vendor: update c/common

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano
2025-03-20 13:14:42 +01:00
parent 2b0aef554e
commit 88b62d2c27
219 changed files with 15969 additions and 3857 deletions

26
go.mod
View File

@ -12,12 +12,12 @@ require (
github.com/buger/goterm v1.0.4
github.com/checkpoint-restore/checkpointctl v1.3.0
github.com/checkpoint-restore/go-criu/v7 v7.2.0
github.com/containernetworking/plugins v1.5.1
github.com/containernetworking/plugins v1.6.2
github.com/containers/buildah v1.39.2
github.com/containers/common v0.62.2-0.20250311121556-b27979403716
github.com/containers/common v0.62.3-0.20250320113334-33bf9345b5ef
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/gvisor-tap-vsock v0.8.4
github.com/containers/image/v5 v5.34.2-0.20250306154130-12497efe55ac
github.com/containers/image/v5 v5.34.3-0.20250311194052-d84dbab374e7
github.com/containers/libhvee v0.10.0
github.com/containers/ocicrypt v1.2.1
github.com/containers/psgo v1.9.0
@ -53,11 +53,11 @@ require (
github.com/moby/sys/user v0.3.0
github.com/moby/term v0.5.2
github.com/nxadm/tail v1.4.11
github.com/onsi/ginkgo/v2 v2.22.2
github.com/onsi/ginkgo/v2 v2.23.1
github.com/onsi/gomega v1.36.2
github.com/opencontainers/cgroups v0.0.1
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.1
github.com/opencontainers/runc v1.2.6
github.com/opencontainers/runtime-spec v1.2.1
github.com/opencontainers/runtime-tools v0.9.1-0.20241108202711-f7e3563b0271
github.com/opencontainers/selinux v1.11.1
@ -70,7 +70,7 @@ require (
github.com/stretchr/testify v1.10.0
github.com/vbauerster/mpb/v8 v8.9.3
github.com/vishvananda/netlink v1.3.1-0.20250221194427-0af32151e72b
go.etcd.io/bbolt v1.3.11
go.etcd.io/bbolt v1.4.0
golang.org/x/crypto v0.36.0
golang.org/x/net v0.37.0
golang.org/x/sync v0.12.0
@ -81,7 +81,7 @@ require (
gopkg.in/inf.v0 v0.9.1
gopkg.in/yaml.v3 v3.0.1
sigs.k8s.io/yaml v1.4.0
tags.cncf.io/container-device-interface v0.8.1
tags.cncf.io/container-device-interface v1.0.0
)
require (
@ -166,7 +166,7 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mdlayher/socket v0.5.0 // indirect
github.com/mdlayher/socket v0.5.1 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
@ -180,11 +180,12 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/opencontainers/runc v1.2.6 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/sftp v1.13.7 // indirect
github.com/pkg/sftp v1.13.8 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
@ -222,14 +223,15 @@ require (
go.opentelemetry.io/otel/trace v1.32.0 // indirect
golang.org/x/arch v0.8.0 // indirect
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/mod v0.23.0 // indirect
golang.org/x/oauth2 v0.26.0 // indirect
golang.org/x/time v0.9.0 // indirect
golang.org/x/tools v0.29.0 // indirect
golang.org/x/tools v0.30.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
google.golang.org/grpc v1.70.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
tags.cncf.io/container-device-interface/specs-go v0.8.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
tags.cncf.io/container-device-interface/specs-go v1.0.0 // indirect
)

54
go.sum
View File

@ -74,18 +74,18 @@ github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
github.com/containernetworking/cni v1.2.3 h1:hhOcjNVUQTnzdRJ6alC5XF+wd9mfGIUaj8FuJbEslXM=
github.com/containernetworking/cni v1.2.3/go.mod h1:DuLgF+aPd3DzcTQTtp/Nvl1Kim23oFKdm2okJzBQA5M=
github.com/containernetworking/plugins v1.5.1 h1:T5ji+LPYjjgW0QM+KyrigZbLsZ8jaX+E5J/EcKOE4gQ=
github.com/containernetworking/plugins v1.5.1/go.mod h1:MIQfgMayGuHYs0XdNudf31cLLAC+i242hNm6KuDGqCM=
github.com/containernetworking/plugins v1.6.2 h1:pqP8Mq923TLyef5g97XfJ/xpDeVek4yF8A4mzy9Tc4U=
github.com/containernetworking/plugins v1.6.2/go.mod h1:SP5UG3jDO9LtmfbBJdP+nl3A1atOtbj2MBOYsnaxy64=
github.com/containers/buildah v1.39.2 h1:YaFMNnuTr7wKYKQDHkm7yyP9HhWVrNB4DA+DjYUS9k4=
github.com/containers/buildah v1.39.2/go.mod h1:Vb4sDbEq06qQqk29mcGw/1qit8dyukpfL4hwNQ5t+z8=
github.com/containers/common v0.62.2-0.20250311121556-b27979403716 h1:4kwkokczKDAeYELVxxjV5Mpys/sA5TZreq6+cTpzX/M=
github.com/containers/common v0.62.2-0.20250311121556-b27979403716/go.mod h1:Dta+lCx83XAeGHtWwTPz+UwpWMiC0nMZQu4LWm1mTEg=
github.com/containers/common v0.62.3-0.20250320113334-33bf9345b5ef h1:OpMI1mIyrKWPGAYlJY9VVjsCXigtk+3ckYE1SN7JxYA=
github.com/containers/common v0.62.3-0.20250320113334-33bf9345b5ef/go.mod h1:vGmB+0zxqbh5Gd0kOKDlC6sIeoMqso3l4ZKg6+G3YFc=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/gvisor-tap-vsock v0.8.4 h1:z7MqcldnXYGaU6uTaKVl7RFxTmbhNsd2UL0CyM3fdBs=
github.com/containers/gvisor-tap-vsock v0.8.4/go.mod h1:Guh8d/SiuJ9jlnuIyUjcKkFKQ2qpLhNKPGD1jMoIt2Q=
github.com/containers/image/v5 v5.34.2-0.20250306154130-12497efe55ac h1:6MRfoW2H0PBNfL5vsGeD2yCz/y7BoObc8a/drJLTRXE=
github.com/containers/image/v5 v5.34.2-0.20250306154130-12497efe55ac/go.mod h1:Q0vC30+RLFCPdM9Nvm4eaFH5MvWZPkGFPEL1+EzzOHo=
github.com/containers/image/v5 v5.34.3-0.20250311194052-d84dbab374e7 h1:DqNRPDES8oT32Fk2puucIsTnUbPkhKs8Ozo6nuzQjEM=
github.com/containers/image/v5 v5.34.3-0.20250311194052-d84dbab374e7/go.mod h1:hq675fbWkn/bGJwXNXysDu1PQWMOL9P4i2yDvZlSRdA=
github.com/containers/libhvee v0.10.0 h1:7VLv8keWZpHuGmWvyY4c1mVH5V1JYb1G78VC+8AlrM0=
github.com/containers/libhvee v0.10.0/go.mod h1:at0h8lRcK5jCKfQgU/e6Io0Mw12F36zRLjXVOXRoDTM=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
@ -347,8 +347,8 @@ github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBW
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mdlayher/packet v1.1.2 h1:3Up1NG6LZrsgDVn6X4L9Ge/iyRyxFEFD9o6Pr3Q1nQY=
github.com/mdlayher/packet v1.1.2/go.mod h1:GEu1+n9sG5VtiRE4SydOmX5GTwyyYlteZiFU+x0kew4=
github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI=
github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI=
github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos=
github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ=
github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ=
github.com/mdlayher/vsock v1.2.1/go.mod h1:NRfCibel++DgeMD8z/hP+PPTjlNJsdPOmxcnENvE+SE=
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
@ -388,10 +388,12 @@ github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
github.com/onsi/ginkgo/v2 v2.23.1 h1:Ox0cOPv/t8RzKJUfDo9ZKtRvBOJY369sFJnl00CjqwY=
github.com/onsi/ginkgo/v2 v2.23.1/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM=
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
github.com/opencontainers/cgroups v0.0.1 h1:MXjMkkFpKv6kpuirUa4USFBas573sSAY082B4CiHEVA=
github.com/opencontainers/cgroups v0.0.1/go.mod h1:s8lktyhlGUqM7OSRL5P7eAW6Wb+kWPNvt4qvVfzA5vs=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
@ -416,8 +418,8 @@ github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.7 h1:uv+I3nNJvlKZIQGSr8JVQLNHFU9YhhNpvC14Y6KgmSM=
github.com/pkg/sftp v1.13.7/go.mod h1:KMKI0t3T6hfA+lTR/ssZdunHo+uwq7ghoN09/FSu3DY=
github.com/pkg/sftp v1.13.8 h1:Xt7eJ/xqXv7s0VuzFw7JXhZj6Oc1zI6l4GK8KP9sFB0=
github.com/pkg/sftp v1.13.8/go.mod h1:DmvEkvKE2lshEeuo2JMp06yqcx9HVnR7e3zqQl42F3U=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@ -444,6 +446,8 @@ github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWN
github.com/rootless-containers/rootlesskit/v2 v2.3.2 h1:QZk7sKU3+B8UHretEeIg6NSTTpj0o4iHGNhNbJBnHOU=
github.com/rootless-containers/rootlesskit/v2 v2.3.2/go.mod h1:RL7YzL02nA2d8HAzt5d1nZnuiAeudQ4oym+HF/7sk7U=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
github.com/sebdah/goldie/v2 v2.5.5 h1:rx1mwF95RxZ3/83sdS4Yp7t2C5TCokvWP4TBRbAyEWY=
github.com/sebdah/goldie/v2 v2.5.5/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
github.com/seccomp/libseccomp-golang v0.10.0 h1:aA4bp+/Zzi0BnWZ2F1wgNBs5gTpm+na2rWM6M9YjLpY=
@ -546,8 +550,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0=
go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I=
go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk=
go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk=
go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80=
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
@ -580,10 +584,10 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -600,8 +604,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -665,7 +669,6 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
@ -677,7 +680,6 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
@ -709,8 +711,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -751,6 +753,8 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@ -766,7 +770,7 @@ sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
src.elv.sh v0.16.0-rc1.0.20220116211855-fda62502ad7f h1:pjVeIo9Ba6K1Wy+rlwX91zT7A+xGEmxiNRBdN04gDTQ=
src.elv.sh v0.16.0-rc1.0.20220116211855-fda62502ad7f/go.mod h1:kPbhv5+fBeUh85nET3wWhHGUaUQ64nZMJ8FwA5v5Olg=
tags.cncf.io/container-device-interface v0.8.1 h1:c0jN4Mt6781jD67NdPajmZlD1qrqQyov/Xfoab37lj0=
tags.cncf.io/container-device-interface v0.8.1/go.mod h1:Apb7N4VdILW0EVdEMRYXIDVRZfNJZ+kmEUss2kRRQ6Y=
tags.cncf.io/container-device-interface/specs-go v0.8.0 h1:QYGFzGxvYK/ZLMrjhvY0RjpUavIn4KcmRmVP/JjdBTA=
tags.cncf.io/container-device-interface/specs-go v0.8.0/go.mod h1:BhJIkjjPh4qpys+qm4DAYtUyryaTDg9zris+AczXyws=
tags.cncf.io/container-device-interface v1.0.0 h1:fbwPQiWZNpXUb9Os6t6JW52rsOppTFUbeJOpNtN1TmI=
tags.cncf.io/container-device-interface v1.0.0/go.mod h1:mmi2aRGmOjK/6NR3TXjLpEIarOJ9qwgZjQ3nTIRwAaA=
tags.cncf.io/container-device-interface/specs-go v1.0.0 h1:8gLw29hH1ZQP9K1YtAzpvkHCjjyIxHZYzBAvlQ+0vD8=
tags.cncf.io/container-device-interface/specs-go v1.0.0/go.mod h1:u86hoFWqnh3hWz3esofRFKbI261bUlvUfLKGrDhJkgQ=

View File

@ -13,15 +13,14 @@ import (
"strings"
"sync"
runcconfig "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/devices"
"github.com/containers/common/pkg/cgroups"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/systemd"
"github.com/containers/podman/v5/pkg/errorhandling"
"github.com/containers/podman/v5/pkg/rootless"
pmount "github.com/containers/storage/pkg/mount"
runcconfig "github.com/opencontainers/cgroups"
devices "github.com/opencontainers/cgroups/devices/config"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/sirupsen/logrus"

View File

@ -9,10 +9,9 @@ import (
"syscall"
"time"
runccgroup "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/containers/common/pkg/cgroups"
"github.com/containers/podman/v5/libpod/define"
runccgroup "github.com/opencontainers/cgroups"
"golang.org/x/sys/unix"
)

View File

@ -15,7 +15,7 @@ import (
api "github.com/containers/podman/v5/pkg/api/types"
"github.com/containers/storage/pkg/system"
"github.com/docker/docker/api/types/container"
runccgroups "github.com/opencontainers/runc/libcontainer/cgroups"
runccgroups "github.com/opencontainers/cgroups"
"github.com/sirupsen/logrus"
)

View File

@ -13,10 +13,10 @@ The `ns.Do()` method provides **partial** control over network namespaces for yo
```go
err = targetNs.Do(func(hostNs ns.NetNS) error {
linkAttrs := netlink.NewLinkAttrs()
linkAttrs.Name = "dummy0"
dummy := &netlink.Dummy{
LinkAttrs: netlink.LinkAttrs{
Name: "dummy0",
},
LinkAttrs: linkAttrs,
}
return netlink.LinkAdd(dummy)
})

View File

@ -31,6 +31,10 @@ func GetCurrentNS() (NetNS, error) {
// return an unexpected network namespace.
runtime.LockOSThread()
defer runtime.UnlockOSThread()
return getCurrentNSNoLock()
}
func getCurrentNSNoLock() (NetNS, error) {
return GetNS(getCurrentThreadNetNSPath())
}
@ -152,6 +156,54 @@ func GetNS(nspath string) (NetNS, error) {
return &netNS{file: fd}, nil
}
// Returns a new empty NetNS.
// Calling Close() let the kernel garbage collect the network namespace.
func TempNetNS() (NetNS, error) {
var tempNS NetNS
var err error
var wg sync.WaitGroup
wg.Add(1)
// Create the new namespace in a new goroutine so that if we later fail
// to switch the namespace back to the original one, we can safely
// leave the thread locked to die without a risk of the current thread
// left lingering with incorrect namespace.
go func() {
defer wg.Done()
runtime.LockOSThread()
var threadNS NetNS
// save a handle to current network namespace
threadNS, err = getCurrentNSNoLock()
if err != nil {
err = fmt.Errorf("failed to open current namespace: %v", err)
return
}
defer threadNS.Close()
// create the temporary network namespace
err = unix.Unshare(unix.CLONE_NEWNET)
if err != nil {
return
}
// get a handle to the temporary network namespace
tempNS, err = getCurrentNSNoLock()
err2 := threadNS.Set()
if err2 == nil {
// Unlock the current thread only when we successfully switched back
// to the original namespace; otherwise leave the thread locked which
// will force the runtime to scrap the current thread, that is maybe
// not as optimal but at least always safe to do.
runtime.UnlockOSThread()
}
}()
wg.Wait()
return tempNS, err
}
func (ns *netNS) Path() string {
return ns.file.Name()
}
@ -173,7 +225,7 @@ func (ns *netNS) Do(toRun func(NetNS) error) error {
}
containedCall := func(hostNS NetNS) error {
threadNS, err := GetCurrentNS()
threadNS, err := getCurrentNSNoLock()
if err != nil {
return fmt.Errorf("failed to open current netns: %v", err)
}

View File

@ -11,6 +11,7 @@ import (
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/libnetwork/util"
"go.etcd.io/bbolt"
boltErrors "go.etcd.io/bbolt/errors"
)
// IPAM boltdb structure
@ -371,7 +372,7 @@ func (n *netavarkNetwork) removeNetworkIPAMBucket(network *types.Network) error
return db.Update(func(tx *bbolt.Tx) error {
// Ignore ErrBucketNotFound, can happen if the network never allocated any ips,
// i.e. because no container was started.
if err := tx.DeleteBucket([]byte(network.Name)); err != nil && !errors.Is(err, bbolt.ErrBucketNotFound) {
if err := tx.DeleteBucket([]byte(network.Name)); err != nil && !errors.Is(err, boltErrors.ErrBucketNotFound) {
return err
}
return nil

View File

@ -11,10 +11,9 @@ import (
"strconv"
"strings"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
"github.com/opencontainers/runc/libcontainer/cgroups/fs2"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
"github.com/opencontainers/cgroups/fs"
"github.com/opencontainers/cgroups/fs2"
)
type linuxBlkioHandler struct {
@ -26,7 +25,7 @@ func getBlkioHandler() *linuxBlkioHandler {
}
// Apply set the specified constraints
func (c *linuxBlkioHandler) Apply(ctr *CgroupControl, res *configs.Resources) error {
func (c *linuxBlkioHandler) Apply(ctr *CgroupControl, res *cgroups.Resources) error {
if ctr.cgroup2 {
man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path))
if err != nil {

View File

@ -8,9 +8,11 @@ import (
"context"
"errors"
"fmt"
"maps"
"math"
"os"
"path/filepath"
"slices"
"strconv"
"strings"
"sync"
@ -21,11 +23,9 @@ import (
"github.com/containers/storage/pkg/unshare"
systemdDbus "github.com/coreos/go-systemd/v22/dbus"
"github.com/godbus/dbus/v5"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fs2"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
"github.com/opencontainers/cgroups/fs2"
"github.com/sirupsen/logrus"
"golang.org/x/exp/maps"
"golang.org/x/sys/unix"
)
@ -44,7 +44,7 @@ var (
// CgroupControl controls a cgroup hierarchy
type CgroupControl struct {
cgroup2 bool
config *configs.Cgroup
config *cgroups.Cgroup
systemd bool
// List of additional cgroup subsystems joined that
// do not have a custom handler.
@ -58,7 +58,7 @@ type controller struct {
type controllerHandler interface {
Create(*CgroupControl) (bool, error)
Apply(*CgroupControl, *configs.Resources) error
Apply(*CgroupControl, *cgroups.Resources) error
Destroy(*CgroupControl) error
Stat(*CgroupControl, *cgroups.Stats) error
}
@ -297,14 +297,14 @@ func readFileByKeyAsUint64(path, key string) (uint64, error) {
}
// New creates a new cgroup control
func New(path string, resources *configs.Resources) (*CgroupControl, error) {
func New(path string, resources *cgroups.Resources) (*CgroupControl, error) {
cgroup2, err := IsCgroup2UnifiedMode()
if err != nil {
return nil, err
}
control := &CgroupControl{
cgroup2: cgroup2,
config: &configs.Cgroup{
config: &cgroups.Cgroup{
Path: path,
Resources: resources,
},
@ -326,7 +326,7 @@ func New(path string, resources *configs.Resources) (*CgroupControl, error) {
}
// NewSystemd creates a new cgroup control
func NewSystemd(path string, resources *configs.Resources) (*CgroupControl, error) {
func NewSystemd(path string, resources *cgroups.Resources) (*CgroupControl, error) {
cgroup2, err := IsCgroup2UnifiedMode()
if err != nil {
return nil, err
@ -334,7 +334,7 @@ func NewSystemd(path string, resources *configs.Resources) (*CgroupControl, erro
control := &CgroupControl{
cgroup2: cgroup2,
systemd: true,
config: &configs.Cgroup{
config: &cgroups.Cgroup{
Path: path,
Resources: resources,
Rootless: unshare.IsRootless(),
@ -353,7 +353,7 @@ func Load(path string) (*CgroupControl, error) {
control := &CgroupControl{
cgroup2: cgroup2,
systemd: false,
config: &configs.Cgroup{
config: &cgroups.Cgroup{
Path: path,
},
}
@ -485,7 +485,7 @@ func (c *CgroupControl) DeleteByPath(path string) error {
}
// Update updates the cgroups
func (c *CgroupControl) Update(resources *configs.Resources) error {
func (c *CgroupControl) Update(resources *cgroups.Resources) error {
for _, h := range handlers {
if err := h.Apply(c, resources); err != nil {
return err
@ -503,7 +503,7 @@ func (c *CgroupControl) AddPid(pid int) error {
return fs2.CreateCgroupPath(path, c.config)
}
names := maps.Keys(handlers)
names := slices.Collect(maps.Keys(handlers))
for _, c := range c.additionalControllers {
if !c.symlink {

View File

@ -8,10 +8,9 @@ import (
"path/filepath"
"strconv"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
"github.com/opencontainers/runc/libcontainer/cgroups/fs2"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
"github.com/opencontainers/cgroups/fs"
"github.com/opencontainers/cgroups/fs2"
)
type linuxCPUHandler struct {
@ -23,7 +22,7 @@ func getCPUHandler() *linuxCPUHandler {
}
// Apply set the specified constraints
func (c *linuxCPUHandler) Apply(ctr *CgroupControl, res *configs.Resources) error {
func (c *linuxCPUHandler) Apply(ctr *CgroupControl, res *cgroups.Resources) error {
if ctr.cgroup2 {
man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path))
if err != nil {

View File

@ -5,10 +5,9 @@ package cgroups
import (
"path/filepath"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
"github.com/opencontainers/runc/libcontainer/cgroups/fs2"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
"github.com/opencontainers/cgroups/fs"
"github.com/opencontainers/cgroups/fs2"
)
type linuxCpusetHandler struct {
@ -20,7 +19,7 @@ func getCpusetHandler() *linuxCpusetHandler {
}
// Apply set the specified constraints
func (c *linuxCpusetHandler) Apply(ctr *CgroupControl, res *configs.Resources) error {
func (c *linuxCpusetHandler) Apply(ctr *CgroupControl, res *cgroups.Resources) error {
if ctr.cgroup2 {
man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path))
if err != nil {

View File

@ -7,10 +7,9 @@ import (
"path/filepath"
"strconv"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
"github.com/opencontainers/runc/libcontainer/cgroups/fs2"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
"github.com/opencontainers/cgroups/fs"
"github.com/opencontainers/cgroups/fs2"
)
type linuxMemHandler struct {
@ -22,7 +21,7 @@ func getMemoryHandler() *linuxMemHandler {
}
// Apply set the specified constraints
func (c *linuxMemHandler) Apply(ctr *CgroupControl, res *configs.Resources) error {
func (c *linuxMemHandler) Apply(ctr *CgroupControl, res *cgroups.Resources) error {
if ctr.cgroup2 {
man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path))
if err != nil {

View File

@ -5,10 +5,9 @@ package cgroups
import (
"path/filepath"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
"github.com/opencontainers/runc/libcontainer/cgroups/fs2"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
"github.com/opencontainers/cgroups/fs"
"github.com/opencontainers/cgroups/fs2"
)
type linuxPidHandler struct {
@ -20,7 +19,7 @@ func getPidsHandler() *linuxPidHandler {
}
// Apply set the specified constraints
func (c *linuxPidHandler) Apply(ctr *CgroupControl, res *configs.Resources) error {
func (c *linuxPidHandler) Apply(ctr *CgroupControl, res *cgroups.Resources) error {
if ctr.cgroup2 {
man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path))
if err != nil {

View File

@ -14,7 +14,7 @@ import (
systemdDbus "github.com/coreos/go-systemd/v22/dbus"
"github.com/godbus/dbus/v5"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
)
type BlkioDev struct {
@ -22,7 +22,7 @@ type BlkioDev struct {
Bytes uint64
}
func systemdCreate(resources *configs.Resources, path string, c *systemdDbus.Conn) error {
func systemdCreate(resources *cgroups.Resources, path string, c *systemdDbus.Conn) error {
slice, name := filepath.Split(path)
slice = strings.TrimSuffix(slice, "/")
@ -150,7 +150,7 @@ func systemdDestroyConn(path string, c *systemdDbus.Conn) error {
return nil
}
func resourcesToProps(res *configs.Resources, v2 bool) (map[string]uint64, map[string]string, map[string][]byte, map[string]int64, map[string][]BlkioDev, error) {
func resourcesToProps(res *cgroups.Resources, v2 bool) (map[string]uint64, map[string]string, map[string][]byte, map[string]int64, map[string][]BlkioDev, error) {
bMap := make(map[string][]byte)
// this array is not used but will be once more resource limits are added
sMap := make(map[string]string)

View File

@ -14,8 +14,7 @@ import (
"sync"
"github.com/containers/storage/pkg/fileutils"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
@ -122,7 +121,7 @@ func BlkioFiles(cgroupPath string) (wtFile, wtDevFile string) {
}
// SetBlkioThrottle sets the throttle limits for the cgroup
func SetBlkioThrottle(res *configs.Resources, cgroupPath string) error {
func SetBlkioThrottle(res *cgroups.Resources, cgroupPath string) error {
for _, td := range res.BlkioThrottleReadBpsDevice {
if err := WriteFile(cgroupPath, "blkio.throttle.read_bps_device", fmt.Sprintf("%d:%d %d", td.Major, td.Minor, td.Rate)); err != nil {
return err

View File

@ -236,13 +236,12 @@ default_sysctls = [
#
#mounts = []
# Default way to to create a Network namespace for the container
# Options are:
# `private` Create private Network Namespace for the container.
# `host` Share host Network Namespace with the container.
# `none` Containers do not use the network
# Default way to create a NET namespace for the container.
# The option is mapped to the **--network** argument for the podman commands, it accepts the same values as that option.
# For example it can be set to `bridge`, `host`, `none`, `pasta` and more, see the podman-create(1)
# manual for all available options.
#
#netns = "private"
#netns = ""
# Do not modify the `/etc/hosts` file in the container. Podman assumes control
# over the container's `/etc/hosts` file by default; refer to the `--add-host`
@ -381,14 +380,17 @@ default_sysctls = [
#firewall_driver = ""
# The network name of the default network to attach pods to.
# The name of the default network as seen in `podman network ls`. This option only effects the network assignment when
# the bridge network mode is selected, i.e. `--network bridge`. It is the default for rootful containers but not as
# rootless. To change the default network mode use the **netns** option under the `[containers]` table.
#
# Note: This should not be changed while you have any containers using this network.
#
#default_network = "podman"
# The default subnet for the default network given in default_network.
# If a network with that name does not exist, a new network using that name and
# this subnet will be created.
# Must be a valid IPv4 CIDR prefix.
#
# Note: This should not be changed if any containers are currently running on the default network.
#
#default_subnet = "10.88.0.0/16"
@ -897,7 +899,7 @@ default_sysctls = [
# Linux:
# qemu - Open source machine emulator and virtualizer. (Default)
# Windows: there are currently two options:
# wsl - Windows Subsystem for Linux (Default)
# wsl - Windows Subsystem for Linux (Default)
# hyperv - Windows Server Virtualization
# Mac: there are currently two options:
# applehv - Default Apple Hypervisor (Default)

View File

@ -182,13 +182,12 @@ default_sysctls = [
#
#log_tag = ""
# Default way to to create a Network namespace for the container
# Options are:
# `private` Create private Network Namespace for the container.
# `host` Share host Network Namespace with the container.
# `none` Containers do not use the network
# Default way to create a NET namespace for the container.
# The option is mapped to the **--network** argument for the podman commands, it accepts the same values as that option.
# For example it can be set to `bridge`, `host`, `none`, `pasta` and more, see the podman-create(1)
# manual for all available options.
#
#netns = "private"
#netns = ""
# Create /etc/hosts for the container. By default, container engine manage
# /etc/hosts, automatically adding the container's own IP address.
@ -292,14 +291,17 @@ default_sysctls = [
# "/usr/lib/netavark",
#]
# The network name of the default network to attach pods to.
# The name of the default network as seen in `podman network ls`. This option only effects the network assignment when
# the bridge network mode is selected, i.e. `--network bridge`. It is the default for rootful containers but not as
# rootless. To change the default network mode use the **netns** option under the `[containers]` table.
#
# Note: This should not be changed while you have any containers using this network.
#
#default_network = "podman"
# The default subnet for the default network given in default_network.
# If a network with that name does not exist, a new network using that name and
# this subnet will be created.
# Must be a valid IPv4 CIDR prefix.
#
# Note: This should not be changed if any containers are currently running on the default network.
#
#default_subnet = "10.88.0.0/16"

View File

@ -5,14 +5,14 @@ import (
"errors"
"fmt"
"io"
"maps"
"os"
"path/filepath"
"sort"
"slices"
"github.com/containers/common/pkg/secrets/define"
"github.com/containers/storage/pkg/fileutils"
"github.com/containers/storage/pkg/lockfile"
"golang.org/x/exp/maps"
)
// secretsDataFile is the file where secrets data/payload will be stored
@ -53,9 +53,7 @@ func (d *Driver) List() ([]string, error) {
if err != nil {
return nil, err
}
allID := maps.Keys(secretData)
sort.Strings(allID)
return allID, err
return slices.Sorted(maps.Keys(secretData)), nil
}
// Lookup returns the bytes associated with a secret ID

View File

@ -3,8 +3,10 @@ package secrets
import (
"errors"
"fmt"
"maps"
"os"
"path/filepath"
"slices"
"strings"
"time"
@ -14,7 +16,6 @@ import (
"github.com/containers/common/pkg/secrets/shelldriver"
"github.com/containers/storage/pkg/lockfile"
"github.com/containers/storage/pkg/stringid"
"golang.org/x/exp/maps"
)
// maxSecretSize is the max size for secret data - 512kB
@ -290,7 +291,7 @@ func (s *SecretsManager) List() ([]Secret, error) {
if err != nil {
return nil, err
}
return maps.Values(secrets), nil
return slices.Collect(maps.Values(secrets)), nil
}
// LookupSecretData returns secret metadata as well as secret data in bytes.

View File

@ -6,12 +6,14 @@ import (
"errors"
"fmt"
"io"
"maps"
"net"
"net/url"
"os"
"os/user"
"path/filepath"
"regexp"
"slices"
"strings"
"time"
@ -29,7 +31,6 @@ import (
"github.com/skeema/knownhosts"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
"golang.org/x/exp/maps"
)
func golangConnectionCreate(options ConnectionCreateOptions) error {
@ -287,7 +288,7 @@ func ValidateAndConfigure(uri *url.URL, iden string, insecureIsMachineConnection
dedup[fp] = s
}
uniq := maps.Values(dedup)
uniq := slices.Collect(maps.Values(dedup))
authMethods = append(authMethods, ssh.PublicKeysCallback(func() ([]ssh.Signer, error) {
return uniq, nil
}))

View File

@ -9,7 +9,7 @@ import (
"github.com/containers/common/pkg/cgroupv2"
"github.com/containers/storage/pkg/fileutils"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/cgroups"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)

View File

@ -15,7 +15,7 @@ import (
// StringInSlice determines if a string is in a string slice, returns bool.
//
// Deprecated: Use [golang.org/x/exp/slices.Contains] instead.
// Deprecated: Use [slices.Contains] instead.
func StringInSlice(s string, sl []string) bool {
return slices.Contains(sl, s)
}

View File

@ -101,6 +101,9 @@ func NewReference(path string, ref reference.NamedTagged) (types.ImageReference,
// NewIndexReference returns a Docker archive reference for a path and a zero-based source manifest index.
func NewIndexReference(path string, sourceIndex int) (types.ImageReference, error) {
if sourceIndex < 0 {
return nil, fmt.Errorf("invalid call to NewIndexReference with negative index %d", sourceIndex)
}
return newReference(path, nil, sourceIndex, nil, nil)
}

View File

@ -87,10 +87,13 @@ func ParseReference(refString string) (types.ImageReference, error) {
// NewReference returns a docker-daemon reference for either the supplied image ID (config digest) or the supplied reference (which must satisfy !reference.IsNameOnly)
func NewReference(id digest.Digest, ref reference.Named) (types.ImageReference, error) {
if id != "" && ref != nil {
switch {
case id != "" && ref != nil:
return nil, errors.New("docker-daemon: reference must not have an image ID and a reference string specified at the same time")
}
if ref != nil {
case id == "" && ref == nil:
return nil, errors.New("docker-daemon: reference must have at least one of an image ID and a reference string")
case ref != nil:
if reference.IsNameOnly(ref) {
return nil, fmt.Errorf("docker-daemon: reference %s has neither a tag nor a digest", reference.FamiliarString(ref))
}

View File

@ -998,7 +998,12 @@ func (c *dockerClient) getExternalBlob(ctx context.Context, urls []string) (io.R
resp.Body.Close()
continue
}
return resp.Body, getBlobSize(resp), nil
size, err := getBlobSize(resp)
if err != nil {
size = -1
}
return resp.Body, size, nil
}
if remoteErrors == nil {
return nil, 0, nil // fallback to non-external blob
@ -1006,12 +1011,20 @@ func (c *dockerClient) getExternalBlob(ctx context.Context, urls []string) (io.R
return nil, 0, fmt.Errorf("failed fetching external blob from all urls: %w", multierr.Format("", ", ", "", remoteErrors))
}
func getBlobSize(resp *http.Response) int64 {
size, err := strconv.ParseInt(resp.Header.Get("Content-Length"), 10, 64)
if err != nil {
size = -1
func getBlobSize(resp *http.Response) (int64, error) {
hdrs := resp.Header.Values("Content-Length")
if len(hdrs) == 0 {
return -1, errors.New(`Missing "Content-Length" header in response`)
}
return size
hdr := hdrs[0] // Equivalent to resp.Header.Get(…)
size, err := strconv.ParseInt(hdr, 10, 64)
if err != nil { // Gos response reader should already reject such values.
return -1, err
}
if size < 0 { // '-' is not a valid character in Content-Length, so negative values are invalid. Gos response reader should already reject such values.
return -1, fmt.Errorf(`Invalid negative "Content-Length" %q`, hdr)
}
return size, nil
}
// getBlob returns a stream for the specified blob in ref, and the blobs size (or -1 if unknown).
@ -1042,7 +1055,10 @@ func (c *dockerClient) getBlob(ctx context.Context, ref dockerReference, info ty
return nil, 0, fmt.Errorf("fetching blob: %w", err)
}
cache.RecordKnownLocation(ref.Transport(), bicTransportScope(ref), info.Digest, newBICLocationReference(ref))
blobSize := getBlobSize(res)
blobSize, err := getBlobSize(res)
if err != nil {
blobSize = -1
}
reconnectingReader, err := newBodyReader(ctx, c, path, res.Body)
if err != nil {

View File

@ -243,8 +243,12 @@ func (d *dockerImageDestination) blobExists(ctx context.Context, repo reference.
defer res.Body.Close()
switch res.StatusCode {
case http.StatusOK:
size, err := getBlobSize(res)
if err != nil {
return false, -1, fmt.Errorf("determining size of blob %s in %s: %w", digest, repo.Name(), err)
}
logrus.Debugf("... already exists")
return true, getBlobSize(res), nil
return true, size, nil
case http.StatusUnauthorized:
logrus.Debugf("... not authorized")
return false, -1, fmt.Errorf("checking whether a blob %s exists in %s: %w", digest, repo.Name(), registryHTTPResponseToError(res))

View File

@ -52,13 +52,13 @@ func (t ociArchiveTransport) ValidatePolicyConfigurationScope(scope string) erro
return internal.ValidateScope(scope)
}
// ParseReference converts a string, which should not start with the ImageTransport.Name prefix, into an OCI ImageReference.
// ParseReference converts a string, which should not start with the ImageTransport.Name prefix, into an OCI archive ImageReference.
func ParseReference(reference string) (types.ImageReference, error) {
file, image := internal.SplitPathAndImage(reference)
return NewReference(file, image)
}
// NewReference returns an OCI reference for a file and a image.
// NewReference returns an OCI archive reference for a file and an optional image name annotation (if not "").
func NewReference(file, image string) (types.ImageReference, error) {
resolved, err := explicitfilepath.ResolvePathToFullyExplicit(file)
if err != nil {

View File

@ -111,13 +111,13 @@ func newReference(dir, image string, sourceIndex int) (types.ImageReference, err
// NewIndexReference returns an OCI reference for a path and a zero-based source manifest index.
func NewIndexReference(dir string, sourceIndex int) (types.ImageReference, error) {
if sourceIndex < 0 {
return nil, fmt.Errorf("invalid call to NewIndexReference with negative index %d", sourceIndex)
}
return newReference(dir, "", sourceIndex)
}
// NewReference returns an OCI reference for a directory and a image.
//
// We do not expose an API supplying the resolvedDir; we could, but recomputing it
// is generally cheap enough that we prefer being confident about the properties of resolvedDir.
// NewReference returns an OCI reference for a directory and an optional image name annotation (if not "").
func NewReference(dir, image string) (types.ImageReference, error) {
return newReference(dir, image, -1)
}

View File

@ -1,5 +1,10 @@
# CHANGELOG
## v0.5.1
- [Improvement]: revert `go.mod` to Go 1.20 to [resolve an issue around Go
module version upgrades](https://github.com/mdlayher/socket/issues/13).
## v0.5.0
**This is the first release of package socket that only supports Go 1.21+.

View File

@ -1,3 +1,41 @@
## 2.23.1
## 🚨 For users on MacOS 🚨
A long-standing Ginkgo performance issue on MacOS seems to be due to mac's antimalware XProtect. You can follow the instructions [here](https://onsi.github.io/ginkgo/#if-you-are-running-on-macos) to disable it in your terminal. Doing so sped up Ginkgo's own test suite from 1m8s to 47s.
### Fixes
Ginkgo's CLI is now a bit clearer if you pass flags in incorrectly:
- make it clearer that you need to pass a filename to the various profile flags, not an absolute directory [a0e52ff]
- emit an error and exit if the ginkgo invocation includes flags after positional arguments [b799d8d]
This might cause existing CI builds to fail. If so then it's likely that your CI build was misconfigured and should be corrected. Open an issue if you need help.
## 2.23.0
Ginkgo 2.23.0 adds a handful of methods to `GinkgoT()` to make it compatible with the `testing.TB` interface in Go 1.24. `GinkgoT().Context()`, in particular, is a useful shorthand for generating a new context that will clean itself up in a `DeferCleanup()`. This has subtle behavior differences from the golang implementation but should make sense in a Ginkgo... um... context.
### Features
- bump to go 1.24.0 - support new testing.TB methods and add a test to cover testing.TB regressions [37a511b]
### Fixes
- fix edge case where build -o is pointing at an explicit file, not a directory [7556a86]
- Fix binary paths when precompiling multiple suites. [4df06c6]
### Maintenance
- Fix: Correct Markdown list rendering in MIGRATING_TO_V2.md [cbcf39a]
- docs: fix test workflow badge (#1512) [9b261ff]
- Bump golang.org/x/net in /integration/_fixtures/version_mismatch_fixture (#1516) [00f19c8]
- Bump golang.org/x/tools from 0.28.0 to 0.30.0 (#1515) [e98a4df]
- Bump activesupport from 6.0.6.1 to 6.1.7.5 in /docs (#1504) [60cc4e2]
- Bump github-pages from 231 to 232 in /docs (#1447) [fea6f2d]
- Bump rexml from 3.2.8 to 3.3.9 in /docs (#1497) [31d7813]
- Bump webrick from 1.8.1 to 1.9.1 in /docs (#1501) [fc3bbd6]
- Code linting (#1500) [aee0d56]
- change interface{} to any (#1502) [809a710]
## 2.22.2
### Maintenance
@ -630,7 +668,7 @@ Ginkgo also uses this progress reporting infrastructure under the hood when hand
### Features
- `BeforeSuite`, `AfterSuite`, `SynchronizedBeforeSuite`, `SynchronizedAfterSuite`, and `ReportAfterSuite` now support (the relevant subset of) decorators. These can be passed in _after_ the callback functions that are usually passed into these nodes.
As a result the **signature of these methods has changed** and now includes a trailing `args ...interface{}`. For most users simply using the DSL, this change is transparent. However if you were assigning one of these functions to a custom variable (or passing it around) then your code may need to change to reflect the new signature.
As a result the **signature of these methods has changed** and now includes a trailing `args ...any`. For most users simply using the DSL, this change is transparent. However if you were assigning one of these functions to a custom variable (or passing it around) then your code may need to change to reflect the new signature.
### Maintenance
- Modernize the invocation of Ginkgo in github actions [0ffde58]

View File

@ -1,6 +1,6 @@
![Ginkgo](https://onsi.github.io/ginkgo/images/ginkgo.png)
[![test](https://github.com/onsi/ginkgo/workflows/test/badge.svg?branch=master)](https://github.com/onsi/ginkgo/actions?query=workflow%3Atest+branch%3Amaster) | [Ginkgo Docs](https://onsi.github.io/ginkgo/)
[![test](https://github.com/onsi/ginkgo/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/onsi/ginkgo/actions?query=workflow%3Atest+branch%3Amaster) | [Ginkgo Docs](https://onsi.github.io/ginkgo/)
---

View File

@ -83,9 +83,9 @@ func exitIfErrors(errors []error) {
type GinkgoWriterInterface interface {
io.Writer
Print(a ...interface{})
Printf(format string, a ...interface{})
Println(a ...interface{})
Print(a ...any)
Printf(format string, a ...any)
Println(a ...any)
TeeTo(writer io.Writer)
ClearTeeWriters()
@ -243,7 +243,7 @@ for more on how specs are parallelized in Ginkgo.
You can also pass suite-level Label() decorators to RunSpecs. The passed-in labels will apply to all specs in the suite.
*/
func RunSpecs(t GinkgoTestingT, description string, args ...interface{}) bool {
func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
if suiteDidRun {
exitIfErr(types.GinkgoErrors.RerunningSuite())
}
@ -316,7 +316,7 @@ func RunSpecs(t GinkgoTestingT, description string, args ...interface{}) bool {
return passed
}
func extractSuiteConfiguration(args []interface{}) Labels {
func extractSuiteConfiguration(args []any) Labels {
suiteLabels := Labels{}
configErrors := []error{}
for _, arg := range args {
@ -491,14 +491,14 @@ to Describe the behavior of an object or function and, within that Describe, out
You can learn more at https://onsi.github.io/ginkgo/#organizing-specs-with-container-nodes
In addition, container nodes can be decorated with a variety of decorators. You can learn more here: https://onsi.github.io/ginkgo/#decorator-reference
*/
func Describe(text string, args ...interface{}) bool {
func Describe(text string, args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, text, args...))
}
/*
FDescribe focuses specs within the Describe block.
*/
func FDescribe(text string, args ...interface{}) bool {
func FDescribe(text string, args ...any) bool {
args = append(args, internal.Focus)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, text, args...))
}
@ -506,7 +506,7 @@ func FDescribe(text string, args ...interface{}) bool {
/*
PDescribe marks specs within the Describe block as pending.
*/
func PDescribe(text string, args ...interface{}) bool {
func PDescribe(text string, args ...any) bool {
args = append(args, internal.Pending)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, text, args...))
}
@ -522,18 +522,18 @@ var XDescribe = PDescribe
var Context, FContext, PContext, XContext = Describe, FDescribe, PDescribe, XDescribe
/* When is an alias for Describe - it generates the exact same kind of Container node */
func When(text string, args ...interface{}) bool {
func When(text string, args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, "when "+text, args...))
}
/* When is an alias for Describe - it generates the exact same kind of Container node */
func FWhen(text string, args ...interface{}) bool {
func FWhen(text string, args ...any) bool {
args = append(args, internal.Focus)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, "when "+text, args...))
}
/* When is an alias for Describe - it generates the exact same kind of Container node */
func PWhen(text string, args ...interface{}) bool {
func PWhen(text string, args ...any) bool {
args = append(args, internal.Pending)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, "when "+text, args...))
}
@ -550,14 +550,14 @@ You can pass It nodes bare functions (func() {}) or functions that receive a Spe
You can learn more at https://onsi.github.io/ginkgo/#spec-subjects-it
In addition, subject nodes can be decorated with a variety of decorators. You can learn more here: https://onsi.github.io/ginkgo/#decorator-reference
*/
func It(text string, args ...interface{}) bool {
func It(text string, args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, text, args...))
}
/*
FIt allows you to focus an individual It.
*/
func FIt(text string, args ...interface{}) bool {
func FIt(text string, args ...any) bool {
args = append(args, internal.Focus)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, text, args...))
}
@ -565,7 +565,7 @@ func FIt(text string, args ...interface{}) bool {
/*
PIt allows you to mark an individual It as pending.
*/
func PIt(text string, args ...interface{}) bool {
func PIt(text string, args ...any) bool {
args = append(args, internal.Pending)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, text, args...))
}
@ -611,8 +611,8 @@ BeforeSuite can take a func() body, or an interruptible func(SpecContext)/func(c
You cannot nest any other Ginkgo nodes within a BeforeSuite node's closure.
You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite
*/
func BeforeSuite(body interface{}, args ...interface{}) bool {
combinedArgs := []interface{}{body}
func BeforeSuite(body any, args ...any) bool {
combinedArgs := []any{body}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeSuite, "", combinedArgs...))
}
@ -630,8 +630,8 @@ AfterSuite can take a func() body, or an interruptible func(SpecContext)/func(co
You cannot nest any other Ginkgo nodes within an AfterSuite node's closure.
You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite
*/
func AfterSuite(body interface{}, args ...interface{}) bool {
combinedArgs := []interface{}{body}
func AfterSuite(body any, args ...any) bool {
combinedArgs := []any{body}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterSuite, "", combinedArgs...))
}
@ -667,8 +667,8 @@ If either function receives a context.Context/SpecContext it is considered inter
You cannot nest any other Ginkgo nodes within an SynchronizedBeforeSuite node's closure.
You can learn more, and see some examples, here: https://onsi.github.io/ginkgo/#parallel-suite-setup-and-cleanup-synchronizedbeforesuite-and-synchronizedaftersuite
*/
func SynchronizedBeforeSuite(process1Body interface{}, allProcessBody interface{}, args ...interface{}) bool {
combinedArgs := []interface{}{process1Body, allProcessBody}
func SynchronizedBeforeSuite(process1Body any, allProcessBody any, args ...any) bool {
combinedArgs := []any{process1Body, allProcessBody}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeSynchronizedBeforeSuite, "", combinedArgs...))
@ -687,8 +687,8 @@ Note that you can also use DeferCleanup() in SynchronizedBeforeSuite to accompli
You cannot nest any other Ginkgo nodes within an SynchronizedAfterSuite node's closure.
You can learn more, and see some examples, here: https://onsi.github.io/ginkgo/#parallel-suite-setup-and-cleanup-synchronizedbeforesuite-and-synchronizedaftersuite
*/
func SynchronizedAfterSuite(allProcessBody interface{}, process1Body interface{}, args ...interface{}) bool {
combinedArgs := []interface{}{allProcessBody, process1Body}
func SynchronizedAfterSuite(allProcessBody any, process1Body any, args ...any) bool {
combinedArgs := []any{allProcessBody, process1Body}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeSynchronizedAfterSuite, "", combinedArgs...))
@ -703,7 +703,7 @@ BeforeEach can take a func() body, or an interruptible func(SpecContext)/func(co
You cannot nest any other Ginkgo nodes within a BeforeEach node's closure.
You can learn more here: https://onsi.github.io/ginkgo/#extracting-common-setup-beforeeach
*/
func BeforeEach(args ...interface{}) bool {
func BeforeEach(args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeEach, "", args...))
}
@ -716,7 +716,7 @@ JustBeforeEach can take a func() body, or an interruptible func(SpecContext)/fun
You cannot nest any other Ginkgo nodes within a JustBeforeEach node's closure.
You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-creation-and-configuration-justbeforeeach
*/
func JustBeforeEach(args ...interface{}) bool {
func JustBeforeEach(args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeJustBeforeEach, "", args...))
}
@ -731,7 +731,7 @@ AfterEach can take a func() body, or an interruptible func(SpecContext)/func(con
You cannot nest any other Ginkgo nodes within an AfterEach node's closure.
You can learn more here: https://onsi.github.io/ginkgo/#spec-cleanup-aftereach-and-defercleanup
*/
func AfterEach(args ...interface{}) bool {
func AfterEach(args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterEach, "", args...))
}
@ -743,7 +743,7 @@ JustAfterEach can take a func() body, or an interruptible func(SpecContext)/func
You cannot nest any other Ginkgo nodes within a JustAfterEach node's closure.
You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-diagnostics-collection-and-teardown-justaftereach
*/
func JustAfterEach(args ...interface{}) bool {
func JustAfterEach(args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeJustAfterEach, "", args...))
}
@ -758,7 +758,7 @@ You cannot nest any other Ginkgo nodes within a BeforeAll node's closure.
You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#ordered-containers
And you can learn more about BeforeAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall
*/
func BeforeAll(args ...interface{}) bool {
func BeforeAll(args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeAll, "", args...))
}
@ -775,7 +775,7 @@ You cannot nest any other Ginkgo nodes within an AfterAll node's closure.
You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#ordered-containers
And you can learn more about AfterAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall
*/
func AfterAll(args ...interface{}) bool {
func AfterAll(args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterAll, "", args...))
}
@ -818,7 +818,7 @@ When DeferCleanup is called in BeforeSuite, SynchronizedBeforeSuite, AfterSuite,
Note that DeferCleanup does not represent a node but rather dynamically generates the appropriate type of cleanup node based on the context in which it is called. As such you must call DeferCleanup within a Setup or Subject node, and not within a Container node.
You can learn more about DeferCleanup here: https://onsi.github.io/ginkgo/#cleaning-up-our-cleanup-code-defercleanup
*/
func DeferCleanup(args ...interface{}) {
func DeferCleanup(args ...any) {
fail := func(message string, cl types.CodeLocation) {
global.Failer.Fail(message, cl)
}

View File

@ -118,9 +118,9 @@ Use Gomega's gmeasure package instead.
You can learn more here: https://onsi.github.io/ginkgo/#benchmarking-code
*/
type Benchmarker interface {
Time(name string, body func(), info ...interface{}) (elapsedTime time.Duration)
RecordValue(name string, value float64, info ...interface{})
RecordValueWithPrecision(name string, value float64, units string, precision int, info ...interface{})
Time(name string, body func(), info ...any) (elapsedTime time.Duration)
RecordValue(name string, value float64, info ...any)
RecordValueWithPrecision(name string, value float64, units string, precision int, info ...any)
}
/*
@ -129,7 +129,7 @@ Deprecated: Measure() has been removed from Ginkgo 2.0
Use Gomega's gmeasure package instead.
You can learn more here: https://onsi.github.io/ginkgo/#benchmarking-code
*/
func Measure(_ ...interface{}) bool {
func Measure(_ ...any) bool {
deprecationTracker.TrackDeprecation(types.Deprecations.Measure(), types.NewCodeLocation(1))
return true
}

View File

@ -24,15 +24,15 @@ const (
var SingletonFormatter = New(ColorModeTerminal)
func F(format string, args ...interface{}) string {
func F(format string, args ...any) string {
return SingletonFormatter.F(format, args...)
}
func Fi(indentation uint, format string, args ...interface{}) string {
func Fi(indentation uint, format string, args ...any) string {
return SingletonFormatter.Fi(indentation, format, args...)
}
func Fiw(indentation uint, maxWidth uint, format string, args ...interface{}) string {
func Fiw(indentation uint, maxWidth uint, format string, args ...any) string {
return SingletonFormatter.Fiw(indentation, maxWidth, format, args...)
}
@ -115,15 +115,15 @@ func New(colorMode ColorMode) Formatter {
return f
}
func (f Formatter) F(format string, args ...interface{}) string {
func (f Formatter) F(format string, args ...any) string {
return f.Fi(0, format, args...)
}
func (f Formatter) Fi(indentation uint, format string, args ...interface{}) string {
func (f Formatter) Fi(indentation uint, format string, args ...any) string {
return f.Fiw(indentation, 0, format, args...)
}
func (f Formatter) Fiw(indentation uint, maxWidth uint, format string, args ...interface{}) string {
func (f Formatter) Fiw(indentation uint, maxWidth uint, format string, args ...any) string {
out := f.style(format)
if len(args) > 0 {
out = fmt.Sprintf(out, args...)

View File

@ -55,18 +55,22 @@ func buildSpecs(args []string, cliConfig types.CLIConfig, goFlagsConfig types.Go
if suite.State.Is(internal.TestSuiteStateFailedToCompile) {
fmt.Println(suite.CompilationError.Error())
} else {
if len(goFlagsConfig.O) == 0 {
goFlagsConfig.O = path.Join(suite.Path, suite.PackageName+".test")
} else {
var testBinPath string
if len(goFlagsConfig.O) != 0 {
stat, err := os.Stat(goFlagsConfig.O)
if err != nil {
panic(err)
}
if stat.IsDir() {
goFlagsConfig.O += "/" + suite.PackageName + ".test"
testBinPath = goFlagsConfig.O + "/" + suite.PackageName + ".test"
} else {
testBinPath = goFlagsConfig.O
}
}
fmt.Printf("Compiled %s\n", goFlagsConfig.O)
if len(testBinPath) == 0 {
testBinPath = path.Join(suite.Path, suite.PackageName+".test")
}
fmt.Printf("Compiled %s\n", testBinPath)
}
}

View File

@ -12,7 +12,7 @@ func Abort(details AbortDetails) {
panic(details)
}
func AbortGracefullyWith(format string, args ...interface{}) {
func AbortGracefullyWith(format string, args ...any) {
Abort(AbortDetails{
ExitCode: 0,
Error: fmt.Errorf(format, args...),
@ -20,7 +20,7 @@ func AbortGracefullyWith(format string, args ...interface{}) {
})
}
func AbortWith(format string, args ...interface{}) {
func AbortWith(format string, args ...any) {
Abort(AbortDetails{
ExitCode: 1,
Error: fmt.Errorf(format, args...),
@ -28,7 +28,7 @@ func AbortWith(format string, args ...interface{}) {
})
}
func AbortWithUsage(format string, args ...interface{}) {
func AbortWithUsage(format string, args ...any) {
Abort(AbortDetails{
ExitCode: 1,
Error: fmt.Errorf(format, args...),

View File

@ -24,7 +24,11 @@ func (c Command) Run(args []string, additionalArgs []string) {
if err != nil {
AbortWithUsage(err.Error())
}
for _, arg := range args {
if strings.HasPrefix(arg, "-") {
AbortWith("Malformed arguments - make sure all flags appear {{bold}}after{{/}} the Ginkgo subcommand and {{bold}}before{{/}} your list of packages.\n{{gray}}e.g. 'ginkgo run -p my_package' is valid `ginkgo -p run my_package` is not.{{/}}")
}
}
c.Command(args, additionalArgs)
}

View File

@ -68,7 +68,6 @@ func (p Program) RunAndExit(osArgs []string) {
fmt.Fprintln(p.ErrWriter, deprecationTracker.DeprecationsReport())
}
p.Exiter(exitCode)
return
}()
args, additionalArgs := []string{}, []string{}
@ -157,7 +156,6 @@ func (p Program) handleHelpRequestsAndExit(writer io.Writer, args []string) {
p.EmitUsage(writer)
Abort(AbortDetails{ExitCode: 1})
}
return
}
func (p Program) EmitUsage(writer io.Writer) {

View File

@ -89,7 +89,7 @@ func mergeProfileBlock(p *cover.Profile, pb cover.ProfileBlock, startIndex int)
}
i := 0
if sortFunc(i) != true {
if !sortFunc(i) {
i = sort.Search(len(p.Blocks)-startIndex, sortFunc)
}

View File

@ -142,7 +142,7 @@ OUTER_LOOP:
}
if !endTime.IsZero() {
r.suiteConfig.Timeout = endTime.Sub(time.Now())
r.suiteConfig.Timeout = time.Until(endTime)
if r.suiteConfig.Timeout <= 0 {
suites[suiteIdx].State = internal.TestSuiteStateFailedDueToTimeout
opc.StopAndDrain()

View File

@ -1,6 +1,7 @@
package ginkgo
import (
"context"
"testing"
"github.com/onsi/ginkgo/v2/internal/testingtproxy"
@ -48,6 +49,8 @@ The portion of the interface returned by GinkgoT() that maps onto methods in the
*/
type GinkgoTInterface interface {
Cleanup(func())
Chdir(dir string)
Context() context.Context
Setenv(kev, value string)
Error(args ...any)
Errorf(format string, args ...any)

View File

@ -32,7 +32,7 @@ func (f *Failer) GetFailure() types.Failure {
return f.failure
}
func (f *Failer) Panic(location types.CodeLocation, forwardedPanic interface{}) {
func (f *Failer) Panic(location types.CodeLocation, forwardedPanic any) {
f.lock.Lock()
defer f.lock.Unlock()

View File

@ -40,7 +40,7 @@ func (ic InterruptCause) String() string {
}
type InterruptStatus struct {
Channel chan interface{}
Channel chan any
Level InterruptLevel
Cause InterruptCause
}
@ -62,14 +62,14 @@ type InterruptHandlerInterface interface {
}
type InterruptHandler struct {
c chan interface{}
c chan any
lock *sync.Mutex
level InterruptLevel
cause InterruptCause
client parallel_support.Client
stop chan interface{}
stop chan any
signals []os.Signal
requestAbortCheck chan interface{}
requestAbortCheck chan any
}
func NewInterruptHandler(client parallel_support.Client, signals ...os.Signal) *InterruptHandler {
@ -77,10 +77,10 @@ func NewInterruptHandler(client parallel_support.Client, signals ...os.Signal) *
signals = []os.Signal{os.Interrupt, syscall.SIGTERM}
}
handler := &InterruptHandler{
c: make(chan interface{}),
c: make(chan any),
lock: &sync.Mutex{},
stop: make(chan interface{}),
requestAbortCheck: make(chan interface{}),
stop: make(chan any),
requestAbortCheck: make(chan any),
client: client,
signals: signals,
}
@ -98,9 +98,9 @@ func (handler *InterruptHandler) registerForInterrupts() {
signal.Notify(signalChannel, handler.signals...)
// cross-process abort handling
var abortChannel chan interface{}
var abortChannel chan any
if handler.client != nil {
abortChannel = make(chan interface{})
abortChannel = make(chan any)
go func() {
pollTicker := time.NewTicker(ABORT_POLLING_INTERVAL)
for {
@ -125,7 +125,7 @@ func (handler *InterruptHandler) registerForInterrupts() {
}()
}
go func(abortChannel chan interface{}) {
go func(abortChannel chan any) {
var interruptCause InterruptCause
for {
select {
@ -151,7 +151,7 @@ func (handler *InterruptHandler) registerForInterrupts() {
}
if handler.level != oldLevel {
close(handler.c)
handler.c = make(chan interface{})
handler.c = make(chan any)
}
handler.lock.Unlock()
}

View File

@ -84,7 +84,7 @@ const SuppressProgressReporting = suppressProgressReporting(true)
type FlakeAttempts uint
type MustPassRepeatedly uint
type Offset uint
type Done chan<- interface{} // Deprecated Done Channel for asynchronous testing
type Done chan<- any // Deprecated Done Channel for asynchronous testing
type Labels []string
type PollProgressInterval time.Duration
type PollProgressAfter time.Duration
@ -110,9 +110,9 @@ func UnionOfLabels(labels ...Labels) Labels {
return out
}
func PartitionDecorations(args ...interface{}) ([]interface{}, []interface{}) {
decorations := []interface{}{}
remainingArgs := []interface{}{}
func PartitionDecorations(args ...any) ([]any, []any) {
decorations := []any{}
remainingArgs := []any{}
for _, arg := range args {
if isDecoration(arg) {
decorations = append(decorations, arg)
@ -123,7 +123,7 @@ func PartitionDecorations(args ...interface{}) ([]interface{}, []interface{}) {
return decorations, remainingArgs
}
func isDecoration(arg interface{}) bool {
func isDecoration(arg any) bool {
switch t := reflect.TypeOf(arg); {
case t == nil:
return false
@ -168,7 +168,7 @@ func isDecoration(arg interface{}) bool {
}
}
func isSliceOfDecorations(slice interface{}) bool {
func isSliceOfDecorations(slice any) bool {
vSlice := reflect.ValueOf(slice)
if vSlice.Len() == 0 {
return false
@ -184,7 +184,7 @@ func isSliceOfDecorations(slice interface{}) bool {
var contextType = reflect.TypeOf(new(context.Context)).Elem()
var specContextType = reflect.TypeOf(new(SpecContext)).Elem()
func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeType, text string, args ...interface{}) (Node, []error) {
func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeType, text string, args ...any) (Node, []error) {
baseOffset := 2
node := Node{
ID: UniqueNodeID(),
@ -207,7 +207,7 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
args = unrollInterfaceSlice(args)
remainingArgs := []interface{}{}
remainingArgs := []any{}
// First get the CodeLocation up-to-date
for _, arg := range args {
switch v := arg.(type) {
@ -223,7 +223,7 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
labelsSeen := map[string]bool{}
trackedFunctionError := false
args = remainingArgs
remainingArgs = []interface{}{}
remainingArgs = []any{}
// now process the rest of the args
for _, arg := range args {
switch t := reflect.TypeOf(arg); {
@ -451,7 +451,7 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
var doneType = reflect.TypeOf(make(Done))
func extractBodyFunction(deprecationTracker *types.DeprecationTracker, cl types.CodeLocation, arg interface{}) (func(SpecContext), bool) {
func extractBodyFunction(deprecationTracker *types.DeprecationTracker, cl types.CodeLocation, arg any) (func(SpecContext), bool) {
t := reflect.TypeOf(arg)
if t.NumOut() > 0 || t.NumIn() > 1 {
return nil, false
@ -477,7 +477,7 @@ func extractBodyFunction(deprecationTracker *types.DeprecationTracker, cl types.
var byteType = reflect.TypeOf([]byte{})
func extractSynchronizedBeforeSuiteProc1Body(arg interface{}) (func(SpecContext) []byte, bool) {
func extractSynchronizedBeforeSuiteProc1Body(arg any) (func(SpecContext) []byte, bool) {
t := reflect.TypeOf(arg)
v := reflect.ValueOf(arg)
@ -505,7 +505,7 @@ func extractSynchronizedBeforeSuiteProc1Body(arg interface{}) (func(SpecContext)
}, hasContext
}
func extractSynchronizedBeforeSuiteAllProcsBody(arg interface{}) (func(SpecContext, []byte), bool) {
func extractSynchronizedBeforeSuiteAllProcsBody(arg any) (func(SpecContext, []byte), bool) {
t := reflect.TypeOf(arg)
v := reflect.ValueOf(arg)
hasContext, hasByte := false, false
@ -536,11 +536,11 @@ func extractSynchronizedBeforeSuiteAllProcsBody(arg interface{}) (func(SpecConte
var errInterface = reflect.TypeOf((*error)(nil)).Elem()
func NewCleanupNode(deprecationTracker *types.DeprecationTracker, fail func(string, types.CodeLocation), args ...interface{}) (Node, []error) {
func NewCleanupNode(deprecationTracker *types.DeprecationTracker, fail func(string, types.CodeLocation), args ...any) (Node, []error) {
decorations, remainingArgs := PartitionDecorations(args...)
baseOffset := 2
cl := types.NewCodeLocation(baseOffset)
finalArgs := []interface{}{}
finalArgs := []any{}
for _, arg := range decorations {
switch t := reflect.TypeOf(arg); {
case t == reflect.TypeOf(Offset(0)):
@ -920,12 +920,12 @@ func (n Nodes) GetMaxMustPassRepeatedly() int {
return maxMustPassRepeatedly
}
func unrollInterfaceSlice(args interface{}) []interface{} {
func unrollInterfaceSlice(args any) []any {
v := reflect.ValueOf(args)
if v.Kind() != reflect.Slice {
return []interface{}{args}
return []any{args}
}
out := []interface{}{}
out := []any{}
for i := 0; i < v.Len(); i++ {
el := reflect.ValueOf(v.Index(i).Interface())
if el.Kind() == reflect.Slice && el.Type() != reflect.TypeOf(Labels{}) {

View File

@ -69,7 +69,7 @@ type pipePair struct {
writer *os.File
}
func startPipeFactory(pipeChannel chan pipePair, shutdown chan interface{}) {
func startPipeFactory(pipeChannel chan pipePair, shutdown chan any) {
for {
//make the next pipe...
pair := pipePair{}
@ -101,8 +101,8 @@ type genericOutputInterceptor struct {
stderrClone *os.File
pipe pipePair
shutdown chan interface{}
emergencyBailout chan interface{}
shutdown chan any
emergencyBailout chan any
pipeChannel chan pipePair
interceptedContent chan string
@ -139,7 +139,7 @@ func (interceptor *genericOutputInterceptor) ResumeIntercepting() {
interceptor.intercepting = true
if interceptor.stdoutClone == nil {
interceptor.stdoutClone, interceptor.stderrClone = interceptor.implementation.CreateStdoutStderrClones()
interceptor.shutdown = make(chan interface{})
interceptor.shutdown = make(chan any)
go startPipeFactory(interceptor.pipeChannel, interceptor.shutdown)
}
@ -147,13 +147,13 @@ func (interceptor *genericOutputInterceptor) ResumeIntercepting() {
// we get the pipe from our pipe factory. it runs in the background so we can request the next pipe while the spec being intercepted is running
interceptor.pipe = <-interceptor.pipeChannel
interceptor.emergencyBailout = make(chan interface{})
interceptor.emergencyBailout = make(chan any)
//Spin up a goroutine to copy data from the pipe into a buffer, this is how we capture any output the user is emitting
go func() {
buffer := &bytes.Buffer{}
destination := io.MultiWriter(buffer, interceptor.forwardTo)
copyFinished := make(chan interface{})
copyFinished := make(chan any)
reader := interceptor.pipe.reader
go func() {
io.Copy(destination, reader)
@ -224,7 +224,7 @@ func NewOSGlobalReassigningOutputInterceptor() OutputInterceptor {
return &genericOutputInterceptor{
interceptedContent: make(chan string),
pipeChannel: make(chan pipePair),
shutdown: make(chan interface{}),
shutdown: make(chan any),
implementation: &osGlobalReassigningOutputInterceptorImpl{},
}
}

View File

@ -13,7 +13,7 @@ func NewOutputInterceptor() OutputInterceptor {
return &genericOutputInterceptor{
interceptedContent: make(chan string),
pipeChannel: make(chan pipePair),
shutdown: make(chan interface{}),
shutdown: make(chan any),
implementation: &dupSyscallOutputInterceptorImpl{},
}
}

View File

@ -30,7 +30,7 @@ type Server interface {
Close()
Address() string
RegisterAlive(node int, alive func() bool)
GetSuiteDone() chan interface{}
GetSuiteDone() chan any
GetOutputDestination() io.Writer
SetOutputDestination(io.Writer)
}

View File

@ -34,7 +34,7 @@ func (client *httpClient) Close() error {
return nil
}
func (client *httpClient) post(path string, data interface{}) error {
func (client *httpClient) post(path string, data any) error {
var body io.Reader
if data != nil {
encoded, err := json.Marshal(data)
@ -54,7 +54,7 @@ func (client *httpClient) post(path string, data interface{}) error {
return nil
}
func (client *httpClient) poll(path string, data interface{}) error {
func (client *httpClient) poll(path string, data any) error {
for {
resp, err := http.Get(client.serverHost + path)
if err != nil {
@ -153,10 +153,7 @@ func (client *httpClient) PostAbort() error {
func (client *httpClient) ShouldAbort() bool {
err := client.poll("/abort", nil)
if err == ErrorGone {
return true
}
return false
return err == ErrorGone
}
func (client *httpClient) Write(p []byte) (int, error) {

View File

@ -75,7 +75,7 @@ func (server *httpServer) Address() string {
return "http://" + server.listener.Addr().String()
}
func (server *httpServer) GetSuiteDone() chan interface{} {
func (server *httpServer) GetSuiteDone() chan any {
return server.handler.done
}
@ -96,7 +96,7 @@ func (server *httpServer) RegisterAlive(node int, alive func() bool) {
//
// The server will forward all received messages to Ginkgo reporters registered with `RegisterReporters`
func (server *httpServer) decode(writer http.ResponseWriter, request *http.Request, object interface{}) bool {
func (server *httpServer) decode(writer http.ResponseWriter, request *http.Request, object any) bool {
defer request.Body.Close()
if json.NewDecoder(request.Body).Decode(object) != nil {
writer.WriteHeader(http.StatusBadRequest)

View File

@ -35,7 +35,7 @@ func (client *rpcClient) Close() error {
return client.client.Close()
}
func (client *rpcClient) poll(method string, data interface{}) error {
func (client *rpcClient) poll(method string, data any) error {
for {
err := client.client.Call(method, voidSender, data)
if err == nil {

View File

@ -25,7 +25,7 @@ type RPCServer struct {
handler *ServerHandler
}
//Create a new server, automatically selecting a port
// Create a new server, automatically selecting a port
func newRPCServer(parallelTotal int, reporter reporters.Reporter) (*RPCServer, error) {
listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
@ -37,7 +37,7 @@ func newRPCServer(parallelTotal int, reporter reporters.Reporter) (*RPCServer, e
}, nil
}
//Start the server. You don't need to `go s.Start()`, just `s.Start()`
// Start the server. You don't need to `go s.Start()`, just `s.Start()`
func (server *RPCServer) Start() {
rpcServer := rpc.NewServer()
rpcServer.RegisterName("Server", server.handler) //register the handler's methods as the server
@ -48,17 +48,17 @@ func (server *RPCServer) Start() {
go httpServer.Serve(server.listener)
}
//Stop the server
// Stop the server
func (server *RPCServer) Close() {
server.listener.Close()
}
//The address the server can be reached it. Pass this into the `ForwardingReporter`.
// The address the server can be reached it. Pass this into the `ForwardingReporter`.
func (server *RPCServer) Address() string {
return server.listener.Addr().String()
}
func (server *RPCServer) GetSuiteDone() chan interface{} {
func (server *RPCServer) GetSuiteDone() chan any {
return server.handler.done
}

View File

@ -18,7 +18,7 @@ var voidSender Void
// It handles all the business logic to avoid duplication between the two servers
type ServerHandler struct {
done chan interface{}
done chan any
outputDestination io.Writer
reporter reporters.Reporter
alives []func() bool
@ -46,7 +46,7 @@ func newServerHandler(parallelTotal int, reporter reporters.Reporter) *ServerHan
parallelTotal: parallelTotal,
outputDestination: os.Stdout,
done: make(chan interface{}),
done: make(chan any),
}
}

View File

@ -8,7 +8,7 @@ import (
type ReportEntry = types.ReportEntry
func NewReportEntry(name string, cl types.CodeLocation, args ...interface{}) (ReportEntry, error) {
func NewReportEntry(name string, cl types.CodeLocation, args ...any) (ReportEntry, error) {
out := ReportEntry{
Visibility: types.ReportEntryVisibilityAlways,
Name: name,

View File

@ -1,6 +1,7 @@
package testingtproxy
import (
"context"
"fmt"
"io"
"os"
@ -19,9 +20,9 @@ type addReportEntryFunc func(names string, args ...any)
type ginkgoWriterInterface interface {
io.Writer
Print(a ...interface{})
Printf(format string, a ...interface{})
Println(a ...interface{})
Print(a ...any)
Printf(format string, a ...any)
Println(a ...any)
}
type ginkgoRecoverFunc func()
type attachProgressReporterFunc func(func() string) func()
@ -80,11 +81,31 @@ func (t *ginkgoTestingTProxy) Setenv(key, value string) {
}
}
func (t *ginkgoTestingTProxy) Error(args ...interface{}) {
func (t *ginkgoTestingTProxy) Chdir(dir string) {
currentDir, err := os.Getwd()
if err != nil {
t.fail(fmt.Sprintf("Failed to get current directory: %v", err), 1)
}
t.cleanup(os.Chdir, currentDir, internal.Offset(1))
err = os.Chdir(dir)
if err != nil {
t.fail(fmt.Sprintf("Failed to change directory: %v", err), 1)
}
}
func (t *ginkgoTestingTProxy) Context() context.Context {
ctx, cancel := context.WithCancel(context.Background())
t.cleanup(cancel, internal.Offset(1))
return ctx
}
func (t *ginkgoTestingTProxy) Error(args ...any) {
t.fail(fmt.Sprintln(args...), t.offset)
}
func (t *ginkgoTestingTProxy) Errorf(format string, args ...interface{}) {
func (t *ginkgoTestingTProxy) Errorf(format string, args ...any) {
t.fail(fmt.Sprintf(format, args...), t.offset)
}
@ -100,11 +121,11 @@ func (t *ginkgoTestingTProxy) Failed() bool {
return t.report().Failed()
}
func (t *ginkgoTestingTProxy) Fatal(args ...interface{}) {
func (t *ginkgoTestingTProxy) Fatal(args ...any) {
t.fail(fmt.Sprintln(args...), t.offset)
}
func (t *ginkgoTestingTProxy) Fatalf(format string, args ...interface{}) {
func (t *ginkgoTestingTProxy) Fatalf(format string, args ...any) {
t.fail(fmt.Sprintf(format, args...), t.offset)
}
@ -112,11 +133,11 @@ func (t *ginkgoTestingTProxy) Helper() {
types.MarkAsHelper(1)
}
func (t *ginkgoTestingTProxy) Log(args ...interface{}) {
func (t *ginkgoTestingTProxy) Log(args ...any) {
fmt.Fprintln(t.writer, args...)
}
func (t *ginkgoTestingTProxy) Logf(format string, args ...interface{}) {
func (t *ginkgoTestingTProxy) Logf(format string, args ...any) {
t.Log(fmt.Sprintf(format, args...))
}
@ -128,7 +149,7 @@ func (t *ginkgoTestingTProxy) Parallel() {
// No-op
}
func (t *ginkgoTestingTProxy) Skip(args ...interface{}) {
func (t *ginkgoTestingTProxy) Skip(args ...any) {
t.skip(fmt.Sprintln(args...), t.offset)
}
@ -136,7 +157,7 @@ func (t *ginkgoTestingTProxy) SkipNow() {
t.skip("skip", t.offset)
}
func (t *ginkgoTestingTProxy) Skipf(format string, args ...interface{}) {
func (t *ginkgoTestingTProxy) Skipf(format string, args ...any) {
t.skip(fmt.Sprintf(format, args...), t.offset)
}

View File

@ -121,15 +121,15 @@ func (w *Writer) ClearTeeWriters() {
w.teeWriters = []io.Writer{}
}
func (w *Writer) Print(a ...interface{}) {
func (w *Writer) Print(a ...any) {
fmt.Fprint(w, a...)
}
func (w *Writer) Printf(format string, a ...interface{}) {
func (w *Writer) Printf(format string, a ...any) {
fmt.Fprintf(w, format, a...)
}
func (w *Writer) Println(a ...interface{}) {
func (w *Writer) Println(a ...any) {
fmt.Fprintln(w, a...)
}

View File

@ -685,11 +685,11 @@ func (r *DefaultReporter) _emit(s string, block bool, isDelimiter bool) {
}
/* Rendering text */
func (r *DefaultReporter) f(format string, args ...interface{}) string {
func (r *DefaultReporter) f(format string, args ...any) string {
return r.formatter.F(format, args...)
}
func (r *DefaultReporter) fi(indentation uint, format string, args ...interface{}) string {
func (r *DefaultReporter) fi(indentation uint, format string, args ...any) string {
return r.formatter.Fi(indentation, format, args...)
}

View File

@ -60,7 +60,7 @@ AddReportEntry() must be called within a Subject or Setup node - not in a Contai
You can learn more about Report Entries here: https://onsi.github.io/ginkgo/#attaching-data-to-reports
*/
func AddReportEntry(name string, args ...interface{}) {
func AddReportEntry(name string, args ...any) {
cl := types.NewCodeLocation(1)
reportEntry, err := internal.NewReportEntry(name, cl, args...)
if err != nil {
@ -89,7 +89,7 @@ You can learn more about ReportBeforeEach here: https://onsi.github.io/ginkgo/#g
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
*/
func ReportBeforeEach(body any, args ...any) bool {
combinedArgs := []interface{}{body}
combinedArgs := []any{body}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportBeforeEach, "", combinedArgs...))
@ -113,7 +113,7 @@ You can learn more about ReportAfterEach here: https://onsi.github.io/ginkgo/#ge
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
*/
func ReportAfterEach(body any, args ...any) bool {
combinedArgs := []interface{}{body}
combinedArgs := []any{body}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportAfterEach, "", combinedArgs...))
@ -143,7 +143,7 @@ You can learn more about Ginkgo's reporting infrastructure, including generating
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
*/
func ReportBeforeSuite(body any, args ...any) bool {
combinedArgs := []interface{}{body}
combinedArgs := []any{body}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportBeforeSuite, "", combinedArgs...))
}
@ -174,8 +174,8 @@ You can learn more about Ginkgo's reporting infrastructure, including generating
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
*/
func ReportAfterSuite(text string, body any, args ...interface{}) bool {
combinedArgs := []interface{}{body}
func ReportAfterSuite(text string, body any, args ...any) bool {
combinedArgs := []any{body}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportAfterSuite, text, combinedArgs...))
}

View File

@ -23,7 +23,7 @@ You can learn more about generating EntryDescriptions here: https://onsi.github.
*/
type EntryDescription string
func (ed EntryDescription) render(args ...interface{}) string {
func (ed EntryDescription) render(args ...any) string {
return fmt.Sprintf(string(ed), args...)
}
@ -44,7 +44,7 @@ For example:
You can learn more about DescribeTable here: https://onsi.github.io/ginkgo/#table-specs
And can explore some Table patterns here: https://onsi.github.io/ginkgo/#table-specs-patterns
*/
func DescribeTable(description string, args ...interface{}) bool {
func DescribeTable(description string, args ...any) bool {
GinkgoHelper()
generateTable(description, false, args...)
return true
@ -53,7 +53,7 @@ func DescribeTable(description string, args ...interface{}) bool {
/*
You can focus a table with `FDescribeTable`. This is equivalent to `FDescribe`.
*/
func FDescribeTable(description string, args ...interface{}) bool {
func FDescribeTable(description string, args ...any) bool {
GinkgoHelper()
args = append(args, internal.Focus)
generateTable(description, false, args...)
@ -63,7 +63,7 @@ func FDescribeTable(description string, args ...interface{}) bool {
/*
You can mark a table as pending with `PDescribeTable`. This is equivalent to `PDescribe`.
*/
func PDescribeTable(description string, args ...interface{}) bool {
func PDescribeTable(description string, args ...any) bool {
GinkgoHelper()
args = append(args, internal.Pending)
generateTable(description, false, args...)
@ -109,7 +109,7 @@ Note that you **must** place define an It inside the body function.
You can learn more about DescribeTableSubtree here: https://onsi.github.io/ginkgo/#table-specs
And can explore some Table patterns here: https://onsi.github.io/ginkgo/#table-specs-patterns
*/
func DescribeTableSubtree(description string, args ...interface{}) bool {
func DescribeTableSubtree(description string, args ...any) bool {
GinkgoHelper()
generateTable(description, true, args...)
return true
@ -118,7 +118,7 @@ func DescribeTableSubtree(description string, args ...interface{}) bool {
/*
You can focus a table with `FDescribeTableSubtree`. This is equivalent to `FDescribe`.
*/
func FDescribeTableSubtree(description string, args ...interface{}) bool {
func FDescribeTableSubtree(description string, args ...any) bool {
GinkgoHelper()
args = append(args, internal.Focus)
generateTable(description, true, args...)
@ -128,7 +128,7 @@ func FDescribeTableSubtree(description string, args ...interface{}) bool {
/*
You can mark a table as pending with `PDescribeTableSubtree`. This is equivalent to `PDescribe`.
*/
func PDescribeTableSubtree(description string, args ...interface{}) bool {
func PDescribeTableSubtree(description string, args ...any) bool {
GinkgoHelper()
args = append(args, internal.Pending)
generateTable(description, true, args...)
@ -144,9 +144,9 @@ var XDescribeTableSubtree = PDescribeTableSubtree
TableEntry represents an entry in a table test. You generally use the `Entry` constructor.
*/
type TableEntry struct {
description interface{}
decorations []interface{}
parameters []interface{}
description any
decorations []any
parameters []any
codeLocation types.CodeLocation
}
@ -162,7 +162,7 @@ If you want to generate interruptible specs simply write a Table function that a
You can learn more about Entry here: https://onsi.github.io/ginkgo/#table-specs
*/
func Entry(description interface{}, args ...interface{}) TableEntry {
func Entry(description any, args ...any) TableEntry {
GinkgoHelper()
decorations, parameters := internal.PartitionDecorations(args...)
return TableEntry{description: description, decorations: decorations, parameters: parameters, codeLocation: types.NewCodeLocation(0)}
@ -171,7 +171,7 @@ func Entry(description interface{}, args ...interface{}) TableEntry {
/*
You can focus a particular entry with FEntry. This is equivalent to FIt.
*/
func FEntry(description interface{}, args ...interface{}) TableEntry {
func FEntry(description any, args ...any) TableEntry {
GinkgoHelper()
decorations, parameters := internal.PartitionDecorations(args...)
decorations = append(decorations, internal.Focus)
@ -181,7 +181,7 @@ func FEntry(description interface{}, args ...interface{}) TableEntry {
/*
You can mark a particular entry as pending with PEntry. This is equivalent to PIt.
*/
func PEntry(description interface{}, args ...interface{}) TableEntry {
func PEntry(description any, args ...any) TableEntry {
GinkgoHelper()
decorations, parameters := internal.PartitionDecorations(args...)
decorations = append(decorations, internal.Pending)
@ -196,17 +196,17 @@ var XEntry = PEntry
var contextType = reflect.TypeOf(new(context.Context)).Elem()
var specContextType = reflect.TypeOf(new(SpecContext)).Elem()
func generateTable(description string, isSubtree bool, args ...interface{}) {
func generateTable(description string, isSubtree bool, args ...any) {
GinkgoHelper()
cl := types.NewCodeLocation(0)
containerNodeArgs := []interface{}{cl}
containerNodeArgs := []any{cl}
entries := []TableEntry{}
var internalBody interface{}
var internalBody any
var internalBodyType reflect.Type
var tableLevelEntryDescription interface{}
tableLevelEntryDescription = func(args ...interface{}) string {
var tableLevelEntryDescription any
tableLevelEntryDescription = func(args ...any) string {
out := []string{}
for _, arg := range args {
out = append(out, fmt.Sprint(arg))
@ -265,7 +265,7 @@ func generateTable(description string, isSubtree bool, args ...interface{}) {
err = types.GinkgoErrors.InvalidEntryDescription(entry.codeLocation)
}
internalNodeArgs := []interface{}{entry.codeLocation}
internalNodeArgs := []any{entry.codeLocation}
internalNodeArgs = append(internalNodeArgs, entry.decorations...)
hasContext := false
@ -290,7 +290,7 @@ func generateTable(description string, isSubtree bool, args ...interface{}) {
if err != nil {
panic(err)
}
invokeFunction(internalBody, append([]interface{}{c}, entry.parameters...))
invokeFunction(internalBody, append([]any{c}, entry.parameters...))
})
if isSubtree {
exitIfErr(types.GinkgoErrors.ContextsCannotBeUsedInSubtreeTables(cl))
@ -316,7 +316,7 @@ func generateTable(description string, isSubtree bool, args ...interface{}) {
pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, description, containerNodeArgs...))
}
func invokeFunction(function interface{}, parameters []interface{}) []reflect.Value {
func invokeFunction(function any, parameters []any) []reflect.Value {
inValues := make([]reflect.Value, len(parameters))
funcType := reflect.TypeOf(function)
@ -339,7 +339,7 @@ func invokeFunction(function interface{}, parameters []interface{}) []reflect.Va
return reflect.ValueOf(function).Call(inValues)
}
func validateParameters(function interface{}, parameters []interface{}, kind string, cl types.CodeLocation, hasContext bool) error {
func validateParameters(function any, parameters []any, kind string, cl types.CodeLocation, hasContext bool) error {
funcType := reflect.TypeOf(function)
limit := funcType.NumIn()
offset := 0
@ -377,7 +377,7 @@ func validateParameters(function interface{}, parameters []interface{}, kind str
return nil
}
func computeValue(parameter interface{}, t reflect.Type) reflect.Value {
func computeValue(parameter any, t reflect.Type) reflect.Value {
if parameter == nil {
return reflect.Zero(t)
} else {

View File

@ -257,8 +257,12 @@ var FlagSections = GinkgoFlagSections{
{Key: "filter", Style: "{{cyan}}", Heading: "Filtering Tests"},
{Key: "failure", Style: "{{red}}", Heading: "Failure Handling"},
{Key: "output", Style: "{{magenta}}", Heading: "Controlling Output Formatting"},
{Key: "code-and-coverage-analysis", Style: "{{orange}}", Heading: "Code and Coverage Analysis"},
{Key: "performance-analysis", Style: "{{coral}}", Heading: "Performance Analysis"},
{Key: "code-and-coverage-analysis", Style: "{{orange}}", Heading: "Code and Coverage Analysis",
Description: "When generating a cover files, please pass a filename {{bold}}not{{/}} a path. To specify a different directory use {{magenta}}--output-dir{{/}}.",
},
{Key: "performance-analysis", Style: "{{coral}}", Heading: "Performance Analysis",
Description: "When generating profile files, please pass filenames {{bold}}not{{/}} a path. Ginkgo will generate a profile file with the given name in the package's directory. To specify a different directory use {{magenta}}--output-dir{{/}}.",
},
{Key: "debug", Style: "{{blue}}", Heading: "Debugging Tests",
Description: "In addition to these flags, Ginkgo supports a few debugging environment variables. To change the parallel server protocol set {{blue}}GINKGO_PARALLEL_PROTOCOL{{/}} to {{bold}}HTTP{{/}}. To avoid pruning callstacks set {{blue}}GINKGO_PRUNE_STACK{{/}} to {{bold}}FALSE{{/}}."},
{Key: "watch", Style: "{{light-yellow}}", Heading: "Controlling Ginkgo Watch"},
@ -365,7 +369,7 @@ var ReporterConfigFlags = GinkgoFlags{
func BuildTestSuiteFlagSet(suiteConfig *SuiteConfig, reporterConfig *ReporterConfig) (GinkgoFlagSet, error) {
flags := SuiteConfigFlags.CopyAppend(ParallelConfigFlags...).CopyAppend(ReporterConfigFlags...)
flags = flags.WithPrefix("ginkgo")
bindings := map[string]interface{}{
bindings := map[string]any{
"S": suiteConfig,
"R": reporterConfig,
"D": &deprecatedConfig{},
@ -572,7 +576,7 @@ var GoBuildFlags = GinkgoFlags{
// GoRunFlags provides flags for the Ginkgo CLI run, and watch commands that capture go's run-time flags. These are passed to the compiled test binary by the ginkgo CLI
var GoRunFlags = GinkgoFlags{
{KeyPath: "Go.CoverProfile", Name: "coverprofile", UsageArgument: "file", SectionKey: "code-and-coverage-analysis",
Usage: `Write a coverage profile to the file after all tests have passed. Sets -cover.`},
Usage: `Write a coverage profile to the file after all tests have passed. Sets -cover. Must be passed a filename, not a path. Use output-dir to control the location of the output.`},
{KeyPath: "Go.BlockProfile", Name: "blockprofile", UsageArgument: "file", SectionKey: "performance-analysis",
Usage: `Write a goroutine blocking profile to the specified file when all tests are complete. Preserves test binary.`},
{KeyPath: "Go.BlockProfileRate", Name: "blockprofilerate", UsageArgument: "rate", SectionKey: "performance-analysis",
@ -600,6 +604,22 @@ func VetAndInitializeCLIAndGoConfig(cliConfig CLIConfig, goFlagsConfig GoFlagsCo
errors = append(errors, GinkgoErrors.BothRepeatAndUntilItFails())
}
if strings.ContainsRune(goFlagsConfig.CoverProfile, os.PathSeparator) {
errors = append(errors, GinkgoErrors.ExpectFilenameNotPath("--coverprofile", goFlagsConfig.CoverProfile))
}
if strings.ContainsRune(goFlagsConfig.CPUProfile, os.PathSeparator) {
errors = append(errors, GinkgoErrors.ExpectFilenameNotPath("--cpuprofile", goFlagsConfig.CPUProfile))
}
if strings.ContainsRune(goFlagsConfig.MemProfile, os.PathSeparator) {
errors = append(errors, GinkgoErrors.ExpectFilenameNotPath("--memprofile", goFlagsConfig.MemProfile))
}
if strings.ContainsRune(goFlagsConfig.BlockProfile, os.PathSeparator) {
errors = append(errors, GinkgoErrors.ExpectFilenameNotPath("--blockprofile", goFlagsConfig.BlockProfile))
}
if strings.ContainsRune(goFlagsConfig.MutexProfile, os.PathSeparator) {
errors = append(errors, GinkgoErrors.ExpectFilenameNotPath("--mutexprofile", goFlagsConfig.MutexProfile))
}
//initialize the output directory
if cliConfig.OutputDir != "" {
err := os.MkdirAll(cliConfig.OutputDir, 0777)
@ -646,7 +666,7 @@ func GenerateGoTestCompileArgs(goFlagsConfig GoFlagsConfig, packageToBuild strin
args := []string{"test", "-c", packageToBuild}
goArgs, err := GenerateFlagArgs(
GoBuildFlags,
map[string]interface{}{
map[string]any{
"Go": &goFlagsConfig,
},
)
@ -665,7 +685,7 @@ func GenerateGinkgoTestRunArgs(suiteConfig SuiteConfig, reporterConfig ReporterC
flags = flags.CopyAppend(ParallelConfigFlags.WithPrefix("ginkgo")...)
flags = flags.CopyAppend(ReporterConfigFlags.WithPrefix("ginkgo")...)
flags = flags.CopyAppend(GoRunFlags.WithPrefix("test")...)
bindings := map[string]interface{}{
bindings := map[string]any{
"S": &suiteConfig,
"R": &reporterConfig,
"Go": &goFlagsConfig,
@ -677,7 +697,7 @@ func GenerateGinkgoTestRunArgs(suiteConfig SuiteConfig, reporterConfig ReporterC
// GenerateGoTestRunArgs is used by the Ginkgo CLI to generate command line arguments to pass to the compiled non-Ginkgo test binary
func GenerateGoTestRunArgs(goFlagsConfig GoFlagsConfig) ([]string, error) {
flags := GoRunFlags.WithPrefix("test")
bindings := map[string]interface{}{
bindings := map[string]any{
"Go": &goFlagsConfig,
}
@ -699,7 +719,7 @@ func BuildRunCommandFlagSet(suiteConfig *SuiteConfig, reporterConfig *ReporterCo
flags = flags.CopyAppend(GoBuildFlags...)
flags = flags.CopyAppend(GoRunFlags...)
bindings := map[string]interface{}{
bindings := map[string]any{
"S": suiteConfig,
"R": reporterConfig,
"C": cliConfig,
@ -720,7 +740,7 @@ func BuildWatchCommandFlagSet(suiteConfig *SuiteConfig, reporterConfig *Reporter
flags = flags.CopyAppend(GoBuildFlags...)
flags = flags.CopyAppend(GoRunFlags...)
bindings := map[string]interface{}{
bindings := map[string]any{
"S": suiteConfig,
"R": reporterConfig,
"C": cliConfig,
@ -736,7 +756,7 @@ func BuildBuildCommandFlagSet(cliConfig *CLIConfig, goFlagsConfig *GoFlagsConfig
flags := GinkgoCLISharedFlags
flags = flags.CopyAppend(GoBuildFlags...)
bindings := map[string]interface{}{
bindings := map[string]any{
"C": cliConfig,
"Go": goFlagsConfig,
"D": &deprecatedConfig{},
@ -760,7 +780,7 @@ func BuildBuildCommandFlagSet(cliConfig *CLIConfig, goFlagsConfig *GoFlagsConfig
func BuildLabelsCommandFlagSet(cliConfig *CLIConfig) (GinkgoFlagSet, error) {
flags := GinkgoCLISharedFlags.SubsetWithNames("r", "skip-package")
bindings := map[string]interface{}{
bindings := map[string]any{
"C": cliConfig,
}

View File

@ -113,7 +113,7 @@ type DeprecatedSpecFailure struct {
type DeprecatedSpecMeasurement struct {
Name string
Info interface{}
Info any
Order int
Results []float64

View File

@ -88,7 +88,7 @@ body of a {{bold}}Describe{{/}}, {{bold}}Context{{/}}, or {{bold}}When{{/}}.`, n
}
}
func (g ginkgoErrors) CaughtPanicDuringABuildPhase(caughtPanic interface{}, cl CodeLocation) error {
func (g ginkgoErrors) CaughtPanicDuringABuildPhase(caughtPanic any, cl CodeLocation) error {
return GinkgoError{
Heading: "Assertion or Panic detected during tree construction",
Message: formatter.F(
@ -189,7 +189,7 @@ func (g ginkgoErrors) InvalidDeclarationOfFlakeAttemptsAndMustPassRepeatedly(cl
}
}
func (g ginkgoErrors) UnknownDecorator(cl CodeLocation, nodeType NodeType, decorator interface{}) error {
func (g ginkgoErrors) UnknownDecorator(cl CodeLocation, nodeType NodeType, decorator any) error {
return GinkgoError{
Heading: "Unknown Decorator",
Message: formatter.F(`[%s] node was passed an unknown decorator: '%#v'`, nodeType, decorator),
@ -345,7 +345,7 @@ func (g ginkgoErrors) PushingCleanupInCleanupNode(cl CodeLocation) error {
}
/* ReportEntry errors */
func (g ginkgoErrors) TooManyReportEntryValues(cl CodeLocation, arg interface{}) error {
func (g ginkgoErrors) TooManyReportEntryValues(cl CodeLocation, arg any) error {
return GinkgoError{
Heading: "Too Many ReportEntry Values",
Message: formatter.F(`{{bold}}AddGinkgoReport{{/}} can only be given one value. Got unexpected value: %#v`, arg),
@ -539,7 +539,7 @@ func (g ginkgoErrors) SynchronizedBeforeSuiteDisappearedOnProc1() error {
/* Configuration errors */
func (g ginkgoErrors) UnknownTypePassedToRunSpecs(value interface{}) error {
func (g ginkgoErrors) UnknownTypePassedToRunSpecs(value any) error {
return GinkgoError{
Heading: "Unknown Type passed to RunSpecs",
Message: fmt.Sprintf("RunSpecs() accepts labels, and configuration of type types.SuiteConfig and/or types.ReporterConfig.\n You passed in: %v", value),
@ -629,6 +629,13 @@ func (g ginkgoErrors) BothRepeatAndUntilItFails() error {
}
}
func (g ginkgoErrors) ExpectFilenameNotPath(flag string, path string) error {
return GinkgoError{
Heading: fmt.Sprintf("%s expects a filename but was given a path: %s", flag, path),
Message: fmt.Sprintf("%s takes a filename, not a path. Use --output-dir to specify a directory to collect all test outputs.", flag),
}
}
/* Stack-Trace parsing errors */
func (g ginkgoErrors) FailedToParseStackTrace(message string) error {

View File

@ -92,7 +92,7 @@ func (gfs GinkgoFlagSections) Lookup(key string) (GinkgoFlagSection, bool) {
type GinkgoFlagSet struct {
flags GinkgoFlags
bindings interface{}
bindings any
sections GinkgoFlagSections
extraGoFlagsSection GinkgoFlagSection
@ -101,7 +101,7 @@ type GinkgoFlagSet struct {
}
// Call NewGinkgoFlagSet to create GinkgoFlagSet that creates and binds to it's own *flag.FlagSet
func NewGinkgoFlagSet(flags GinkgoFlags, bindings interface{}, sections GinkgoFlagSections) (GinkgoFlagSet, error) {
func NewGinkgoFlagSet(flags GinkgoFlags, bindings any, sections GinkgoFlagSections) (GinkgoFlagSet, error) {
return bindFlagSet(GinkgoFlagSet{
flags: flags,
bindings: bindings,
@ -110,7 +110,7 @@ func NewGinkgoFlagSet(flags GinkgoFlags, bindings interface{}, sections GinkgoFl
}
// Call NewGinkgoFlagSet to create GinkgoFlagSet that extends an existing *flag.FlagSet
func NewAttachedGinkgoFlagSet(flagSet *flag.FlagSet, flags GinkgoFlags, bindings interface{}, sections GinkgoFlagSections, extraGoFlagsSection GinkgoFlagSection) (GinkgoFlagSet, error) {
func NewAttachedGinkgoFlagSet(flagSet *flag.FlagSet, flags GinkgoFlags, bindings any, sections GinkgoFlagSections, extraGoFlagsSection GinkgoFlagSection) (GinkgoFlagSet, error) {
return bindFlagSet(GinkgoFlagSet{
flags: flags,
bindings: bindings,
@ -335,7 +335,7 @@ func (f GinkgoFlagSet) substituteUsage() {
fmt.Fprintln(f.flagSet.Output(), f.Usage())
}
func valueAtKeyPath(root interface{}, keyPath string) (reflect.Value, bool) {
func valueAtKeyPath(root any, keyPath string) (reflect.Value, bool) {
if len(keyPath) == 0 {
return reflect.Value{}, false
}
@ -433,7 +433,7 @@ func (ssv stringSliceVar) Set(s string) error {
}
// given a set of GinkgoFlags and bindings, generate flag arguments suitable to be passed to an application with that set of flags configured.
func GenerateFlagArgs(flags GinkgoFlags, bindings interface{}) ([]string, error) {
func GenerateFlagArgs(flags GinkgoFlags, bindings any) ([]string, error) {
result := []string{}
for _, flag := range flags {
name := flag.ExportAs

View File

@ -343,7 +343,7 @@ func tokenize(input string) func() (*treeNode, error) {
consumeUntil := func(cutset string) (string, int) {
j := i
for ; j < len(runes); j++ {
if strings.IndexRune(cutset, runes[j]) >= 0 {
if strings.ContainsRune(cutset, runes[j]) {
break
}
}

View File

@ -9,18 +9,18 @@ import (
// ReportEntryValue wraps a report entry's value ensuring it can be encoded and decoded safely into reports
// and across the network connection when running in parallel
type ReportEntryValue struct {
raw interface{} //unexported to prevent gob from freaking out about unregistered structs
raw any //unexported to prevent gob from freaking out about unregistered structs
AsJSON string
Representation string
}
func WrapEntryValue(value interface{}) ReportEntryValue {
func WrapEntryValue(value any) ReportEntryValue {
return ReportEntryValue{
raw: value,
}
}
func (rev ReportEntryValue) GetRawValue() interface{} {
func (rev ReportEntryValue) GetRawValue() any {
return rev.raw
}
@ -118,7 +118,7 @@ func (entry ReportEntry) StringRepresentation() string {
// If used from a rehydrated JSON file _or_ in a ReportAfterSuite when running in parallel this will be
// a JSON-decoded {}interface. If you want to reconstitute your original object you can decode the entry.Value.AsJSON
// field yourself.
func (entry ReportEntry) GetRawValue() interface{} {
func (entry ReportEntry) GetRawValue() any {
return entry.Value.GetRawValue()
}

View File

@ -1,3 +1,3 @@
package types
const VERSION = "2.22.2"
const VERSION = "2.23.1"

1
vendor/github.com/opencontainers/cgroups/CODEOWNERS generated vendored Normal file
View File

@ -0,0 +1 @@
* @maintainer1 @maintainer2 @maintainer3

View File

@ -0,0 +1,150 @@
# Contribution Guidelines
Development happens on GitHub.
Issues are used for bugs and actionable items and longer discussions can happen on the [mailing list](#mailing-list).
The content of this repository is licensed under the [Apache License, Version 2.0](LICENSE).
## Code of Conduct
Participation in the Open Container community is governed by [Open Container Code of Conduct][code-of-conduct].
## Meetings
The contributors and maintainers of all OCI projects have monthly meetings at 2:00 PM (USA Pacific) on the first Wednesday of every month.
There is an [iCalendar][rfc5545] format for the meetings [here][meeting.ics].
Everyone is welcome to participate via [UberConference web][UberConference] or audio-only: +1 415 968 0849 (no PIN needed).
An initial agenda will be posted to the [mailing list](#mailing-list) in the week before each meeting, and everyone is welcome to propose additional topics or suggest other agenda alterations there.
Minutes from past meetings are archived [here][minutes].
## Mailing list
You can subscribe and browse the mailing list on [Google Groups][mailing-list].
## IRC
OCI discussion happens on #opencontainers on [Freenode][] ([logs][irc-logs]).
## Git
### Security issues
If you are reporting a security issue, do not create an issue or file a pull
request on GitHub. Instead, disclose the issue responsibly by sending an email
to security@opencontainers.org (which is inhabited only by the maintainers of
the various OCI projects).
### Pull requests are always welcome
We are always thrilled to receive pull requests, and do our best to
process them as fast as possible. Not sure if that typo is worth a pull
request? Do it! We will appreciate it.
If your pull request is not accepted on the first try, don't be
discouraged! If there's a problem with the implementation, hopefully you
received feedback on what to improve.
We're trying very hard to keep the project lean and focused. We don't want it
to do everything for everybody. This means that we might decide against
incorporating a new feature.
### Conventions
Fork the repo and make changes on your fork in a feature branch.
For larger bugs and enhancements, consider filing a leader issue or mailing-list thread for discussion that is independent of the implementation.
Small changes or changes that have been discussed on the [project mailing list](#mailing-list) may be submitted without a leader issue.
If the project has a test suite, submit unit tests for your changes. Take a
look at existing tests for inspiration. Run the full test suite on your branch
before submitting a pull request.
Update the documentation when creating or modifying features. Test
your documentation changes for clarity, concision, and correctness, as
well as a clean documentation build.
Pull requests descriptions should be as clear as possible and include a
reference to all the issues that they address.
Commit messages must start with a capitalized and short summary
written in the imperative, followed by an optional, more detailed
explanatory text which is separated from the summary by an empty line.
Code review comments may be added to your pull request. Discuss, then make the
suggested modifications and push additional commits to your feature branch. Be
sure to post a comment after pushing. The new commits will show up in the pull
request automatically, but the reviewers will not be notified unless you
comment.
Before the pull request is merged, make sure that you squash your commits into
logical units of work using `git rebase -i` and `git push -f`. After every
commit the test suite (if any) should be passing. Include documentation changes
in the same commit so that a revert would remove all traces of the feature or
fix.
Commits that fix or close an issue should include a reference like `Closes #XXX`
or `Fixes #XXX`, which will automatically close the issue when merged.
### Sign your work
The sign-off is a simple line at the end of the explanation for the
patch, which certifies that you wrote it or otherwise have the right to
pass it on as an open-source patch. The rules are pretty simple: if you
can certify the below (from [developercertificate.org][]):
```
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
```
then you just add a line to every git commit message:
Signed-off-by: Joe Smith <joe@gmail.com>
using your real name (sorry, no pseudonyms or anonymous contributions.)
You can add the sign off when creating the git commit via `git commit -s`.
[code-of-conduct]: https://github.com/opencontainers/tob/blob/d2f9d68c1332870e40693fe077d311e0742bc73d/code-of-conduct.md
[developercertificate.org]: http://developercertificate.org/
[Freenode]: https://freenode.net/
[irc-logs]: http://ircbot.wl.linuxfoundation.org/eavesdrop/%23opencontainers/
[mailing-list]: https://groups.google.com/a/opencontainers.org/forum/#!forum/dev
[meeting.ics]: https://github.com/opencontainers/runtime-spec/blob/master/meeting.ics
[minutes]: http://ircbot.wl.linuxfoundation.org/meetings/opencontainers/
[rfc5545]: https://tools.ietf.org/html/rfc5545
[UberConference]: https://www.uberconference.com/opencontainers

63
vendor/github.com/opencontainers/cgroups/GOVERNANCE.md generated vendored Normal file
View File

@ -0,0 +1,63 @@
# Project governance
The [OCI charter][charter] §5.b.viii tasks an OCI Project's maintainers (listed in the repository's MAINTAINERS file and sometimes referred to as "the TDC", [§5.e][charter]) with:
> Creating, maintaining and enforcing governance guidelines for the TDC, approved by the maintainers, and which shall be posted visibly for the TDC.
This section describes generic rules and procedures for fulfilling that mandate.
## Proposing a motion
A maintainer SHOULD propose a motion on the dev@opencontainers.org mailing list (except [security issues](#security-issues)) with another maintainer as a co-sponsor.
## Voting
Voting on a proposed motion SHOULD happen on the dev@opencontainers.org mailing list (except [security issues](#security-issues)) with maintainers posting LGTM or REJECT.
Maintainers MAY also explicitly not vote by posting ABSTAIN (which is useful to revert a previous vote).
Maintainers MAY post multiple times (e.g. as they revise their position based on feedback), but only their final post counts in the tally.
A proposed motion is adopted if two-thirds of votes cast, a quorum having voted, are in favor of the release.
Voting SHOULD remain open for a week to collect feedback from the wider community and allow the maintainers to digest the proposed motion.
Under exceptional conditions (e.g. non-major security fix releases) proposals which reach quorum with unanimous support MAY be adopted earlier.
A maintainer MAY choose to reply with REJECT.
A maintainer posting a REJECT MUST include a list of concerns or links to written documentation for those concerns (e.g. GitHub issues or mailing-list threads).
The maintainers SHOULD try to resolve the concerns and wait for the rejecting maintainer to change their opinion to LGTM.
However, a motion MAY be adopted with REJECTs, as outlined in the previous paragraphs.
## Quorum
A quorum is established when at least two-thirds of maintainers have voted.
For projects that are not specifications, a [motion to release](#release-approval) MAY be adopted if the tally is at least three LGTMs and no REJECTs, even if three votes does not meet the usual two-thirds quorum.
## Amendments
The [project governance](#project-governance) rules and procedures MAY be amended or replaced using the procedures themselves.
The MAINTAINERS of this project governance document is the total set of MAINTAINERS from all Open Containers projects (go-digest, image-spec, image-tools, runC, runtime-spec, runtime-tools, and selinux).
## Subject templates
Maintainers are busy and get lots of email.
To make project proposals recognizable, proposed motions SHOULD use the following subject templates.
### Proposing a motion
> [{project} VOTE]: {motion description} (closes {end of voting window})
For example:
> [runtime-spec VOTE]: Tag 0647920 as 1.0.0-rc (closes 2016-06-03 20:00 UTC)
### Tallying results
After voting closes, a maintainer SHOULD post a tally to the motion thread with a subject template like:
> [{project} {status}]: {motion description} (+{LGTMs} -{REJECTs} #{ABSTAINs})
Where `{status}` is either `adopted` or `rejected`.
For example:
> [runtime-spec adopted]: Tag 0647920 as 1.0.0-rc (+6 -0 #3)
[charter]: https://www.opencontainers.org/about/governance

201
vendor/github.com/opencontainers/cgroups/LICENSE generated vendored Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

8
vendor/github.com/opencontainers/cgroups/MAINTAINERS generated vendored Normal file
View File

@ -0,0 +1,8 @@
Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp> (@AkihiroSuda)
Aleksa Sarai <cyphar@cyphar.com> (@cyphar)
Kir Kolyshkin <kolyshkin@gmail.com> (@kolyshkin)
Mrunal Patel <mpatel@redhat.com> (@mrunalp)
Sebastiaan van Stijn <github@gone.nl> (@thaJeztah)
Odin Ugedal <odin@uged.al> (@odinuge)
Peter Hunt <pehunt@redhat.com> (@haircommander)
Davanum Srinivas <davanum@gmail.com> (@dims)

View File

@ -0,0 +1,92 @@
## Introduction
Dear maintainer. Thank you for investing the time and energy to help
make this project as useful as possible. Maintaining a project is difficult,
sometimes unrewarding work. Sure, you will get to contribute cool
features to the project. But most of your time will be spent reviewing,
cleaning up, documenting, answering questions, justifying design
decisions - while everyone has all the fun! But remember - the quality
of the maintainers work is what distinguishes the good projects from the
great. So please be proud of your work, even the unglamourous parts,
and encourage a culture of appreciation and respect for *every* aspect
of improving the project - not just the hot new features.
This document is a manual for maintainers old and new. It explains what
is expected of maintainers, how they should work, and what tools are
available to them.
This is a living document - if you see something out of date or missing,
speak up!
## What are a maintainer's responsibilities?
It is every maintainer's responsibility to:
* Expose a clear roadmap for improving their component.
* Deliver prompt feedback and decisions on pull requests.
* Be available to anyone with questions, bug reports, criticism etc. on their component.
This includes IRC and GitHub issues and pull requests.
* Make sure their component respects the philosophy, design and roadmap of the project.
## How are decisions made?
This project is an open-source project with an open design philosophy. This
means that the repository is the source of truth for EVERY aspect of the
project, including its philosophy, design, roadmap and APIs. *If it's
part of the project, it's in the repo. It's in the repo, it's part of
the project.*
As a result, all decisions can be expressed as changes to the
repository. An implementation change is a change to the source code. An
API change is a change to the API specification. A philosophy change is
a change to the philosophy manifesto. And so on.
All decisions affecting this project, big and small, follow the same procedure:
1. Discuss a proposal on the [mailing list](CONTRIBUTING.md#mailing-list).
Anyone can do this.
2. Open a pull request.
Anyone can do this.
3. Discuss the pull request.
Anyone can do this.
4. Endorse (`LGTM`) or oppose (`Rejected`) the pull request.
The relevant maintainers do this (see below [Who decides what?](#who-decides-what)).
Changes that affect project management (changing policy, cutting releases, etc.) are [proposed and voted on the mailing list](GOVERNANCE.md).
5. Merge or close the pull request.
The relevant maintainers do this.
### I'm a maintainer, should I make pull requests too?
Yes. Nobody should ever push to master directly. All changes should be
made through a pull request.
## Who decides what?
All decisions are pull requests, and the relevant maintainers make
decisions by accepting or refusing the pull request. Review and acceptance
by anyone is denoted by adding a comment in the pull request: `LGTM`.
However, only currently listed `MAINTAINERS` are counted towards the required
two LGTMs. In addition, if a maintainer has created a pull request, they cannot
count toward the two LGTM rule (to ensure equal amounts of review for every pull
request, no matter who wrote it).
Overall the maintainer system works because of mutual respect.
The maintainers trust one another to act in the best interests of the project.
Sometimes maintainers can disagree and this is part of a healthy project to represent the points of view of various people.
In the case where maintainers cannot find agreement on a specific change, maintainers should use the [governance procedure](GOVERNANCE.md) to attempt to reach a consensus.
### How are maintainers added?
The best maintainers have a vested interest in the project. Maintainers
are first and foremost contributors that have shown they are committed to
the long term success of the project. Contributors wanting to become
maintainers are expected to be deeply involved in contributing code,
pull request review, and triage of issues in the project for more than two months.
Just contributing does not make you a maintainer, it is about building trust with the current maintainers of the project and being a person that they can depend on to act in the best interest of the project.
The final vote to add a new maintainer should be approved by the [governance procedure](GOVERNANCE.md).
### How are maintainers removed?
When a maintainer is unable to perform the [required duties](#what-are-a-maintainers-responsibilities) they can be removed by the [governance procedure](GOVERNANCE.md).
Issues related to a maintainer's performance should be discussed with them among the other maintainers so that they are not surprised by a pull request removing them.

11
vendor/github.com/opencontainers/cgroups/README.md generated vendored Normal file
View File

@ -0,0 +1,11 @@
# OCI Project Template
Useful boilerplate and organizational information for all OCI projects.
* README (this file)
* [The Apache License, Version 2.0](LICENSE)
* [A list of maintainers](MAINTAINERS)
* [Maintainer guidelines](MAINTAINERS_GUIDE.md)
* [Contributor guidelines](CONTRIBUTING.md)
* [Project governance](GOVERNANCE.md)
* [Release procedures](RELEASES.md)

51
vendor/github.com/opencontainers/cgroups/RELEASES.md generated vendored Normal file
View File

@ -0,0 +1,51 @@
# Releases
The release process hopes to encourage early, consistent consensus-building during project development.
The mechanisms used are regular community communication on the mailing list about progress, scheduled meetings for issue resolution and release triage, and regularly paced and communicated releases.
Releases are proposed and adopted or rejected using the usual [project governance](GOVERNANCE.md) rules and procedures.
An anti-pattern that we want to avoid is heavy development or discussions "late cycle" around major releases.
We want to build a community that is involved and communicates consistently through all releases instead of relying on "silent periods" as a judge of stability.
## Parallel releases
A single project MAY consider several motions to release in parallel.
However each motion to release after the initial 0.1.0 MUST be based on a previous release that has already landed.
For example, runtime-spec maintainers may propose a v1.0.0-rc2 on the 1st of the month and a v0.9.1 bugfix on the 2nd of the month.
They may not propose a v1.0.0-rc3 until the v1.0.0-rc2 is accepted (on the 7th if the vote initiated on the 1st passes).
## Specifications
The OCI maintains three categories of projects: specifications, applications, and conformance-testing tools.
However, specification releases have special restrictions in the [OCI charter][charter]:
* They are the target of backwards compatibility (§7.g), and
* They are subject to the OFWa patent grant (§8.d and e).
To avoid unfortunate side effects (onerous backwards compatibity requirements or Member resignations), the following additional procedures apply to specification releases:
### Planning a release
Every OCI specification project SHOULD hold meetings that involve maintainers reviewing pull requests, debating outstanding issues, and planning releases.
This meeting MUST be advertised on the project README and MAY happen on a phone call, video conference, or on IRC.
Maintainers MUST send updates to the dev@opencontainers.org with results of these meetings.
Before the specification reaches v1.0.0, the meetings SHOULD be weekly.
Once a specification has reached v1.0.0, the maintainers may alter the cadence, but a meeting MUST be held within four weeks of the previous meeting.
The release plans, corresponding milestones and estimated due dates MUST be published on GitHub (e.g. https://github.com/opencontainers/runtime-spec/milestones).
GitHub milestones and issues are only used for community organization and all releases MUST follow the [project governance](GOVERNANCE.md) rules and procedures.
### Timelines
Specifications have a variety of different timelines in their lifecycle.
* Pre-v1.0.0 specifications SHOULD release on a monthly cadence to garner feedback.
* Major specification releases MUST release at least three release candidates spaced a minimum of one week apart.
This means a major release like a v1.0.0 or v2.0.0 release will take 1 month at minimum: one week for rc1, one week for rc2, one week for rc3, and one week for the major release itself.
Maintainers SHOULD strive to make zero breaking changes during this cycle of release candidates and SHOULD restart the three-candidate count when a breaking change is introduced.
For example if a breaking change is introduced in v1.0.0-rc2 then the series would end with v1.0.0-rc4 and v1.0.0.
* Minor and patch releases SHOULD be made on an as-needed basis.
[charter]: https://www.opencontainers.org/about/governance

View File

@ -2,8 +2,6 @@ package cgroups
import (
"errors"
"github.com/opencontainers/runc/libcontainer/configs"
)
var (
@ -18,11 +16,11 @@ var (
// DevicesSetV1 and DevicesSetV2 are functions to set devices for
// cgroup v1 and v2, respectively. Unless
// [github.com/opencontainers/runc/libcontainer/cgroups/devices]
// [github.com/opencontainers/cgroups/devices]
// package is imported, it is set to nil, so cgroup managers can't
// manage devices.
DevicesSetV1 func(path string, r *configs.Resources) error
DevicesSetV2 func(path string, r *configs.Resources) error
DevicesSetV1 func(path string, r *Resources) error
DevicesSetV2 func(path string, r *Resources) error
)
type Manager interface {
@ -42,7 +40,7 @@ type Manager interface {
GetStats() (*Stats, error)
// Freeze sets the freezer cgroup to the specified state.
Freeze(state configs.FreezerState) error
Freeze(state FreezerState) error
// Destroy removes cgroup.
Destroy() error
@ -54,7 +52,7 @@ type Manager interface {
// Set sets cgroup resources parameters/limits. If the argument is nil,
// the resources specified during Manager creation (or the previous call
// to Set) are used.
Set(r *configs.Resources) error
Set(r *Resources) error
// GetPaths returns cgroup path(s) to save in a state file in order to
// restore later.
@ -67,10 +65,10 @@ type Manager interface {
GetPaths() map[string]string
// GetCgroups returns the cgroup data as configured.
GetCgroups() (*configs.Cgroup, error)
GetCgroups() (*Cgroup, error)
// GetFreezerState retrieves the current FreezerState of the cgroup.
GetFreezerState() (configs.FreezerState, error)
GetFreezerState() (FreezerState, error)
// Exists returns whether the cgroup path exists or not.
Exists() bool

View File

@ -1,4 +1,4 @@
package configs
package cgroups
type HugepageLimit struct {
// which type of hugepage to limit.

View File

@ -1,8 +1,8 @@
package configs
package cgroups
import (
systemdDbus "github.com/coreos/go-systemd/v22/dbus"
"github.com/opencontainers/runc/libcontainer/devices"
devices "github.com/opencontainers/cgroups/devices/config"
)
type FreezerState string

View File

@ -1,4 +1,4 @@
package configs
package cgroups
// LinuxRdma for Linux cgroup 'rdma' resource management (Linux 4.11)
type LinuxRdma struct {

View File

@ -1,6 +1,6 @@
//go:build !linux
package configs
package cgroups
// Cgroup holds properties of a cgroup on Linux
// TODO Windows: This can ultimately be entirely factored out on Windows as

View File

@ -0,0 +1,174 @@
package config
import (
"fmt"
"os"
"strconv"
)
const (
Wildcard = -1
)
type Device struct {
Rule
// Path to the device.
Path string `json:"path"`
// FileMode permission bits for the device.
FileMode os.FileMode `json:"file_mode"`
// Uid of the device.
Uid uint32 `json:"uid"`
// Gid of the device.
Gid uint32 `json:"gid"`
}
// Permissions is a cgroupv1-style string to represent device access. It
// has to be a string for backward compatibility reasons, hence why it has
// methods to do set operations.
type Permissions string
const (
deviceRead uint = (1 << iota)
deviceWrite
deviceMknod
)
func (p Permissions) toSet() uint {
var set uint
for _, perm := range p {
switch perm {
case 'r':
set |= deviceRead
case 'w':
set |= deviceWrite
case 'm':
set |= deviceMknod
}
}
return set
}
func fromSet(set uint) Permissions {
var perm string
if set&deviceRead == deviceRead {
perm += "r"
}
if set&deviceWrite == deviceWrite {
perm += "w"
}
if set&deviceMknod == deviceMknod {
perm += "m"
}
return Permissions(perm)
}
// Union returns the union of the two sets of Permissions.
func (p Permissions) Union(o Permissions) Permissions {
lhs := p.toSet()
rhs := o.toSet()
return fromSet(lhs | rhs)
}
// Difference returns the set difference of the two sets of Permissions.
// In set notation, A.Difference(B) gives you A\B.
func (p Permissions) Difference(o Permissions) Permissions {
lhs := p.toSet()
rhs := o.toSet()
return fromSet(lhs &^ rhs)
}
// Intersection computes the intersection of the two sets of Permissions.
func (p Permissions) Intersection(o Permissions) Permissions {
lhs := p.toSet()
rhs := o.toSet()
return fromSet(lhs & rhs)
}
// IsEmpty returns whether the set of permissions in a Permissions is
// empty.
func (p Permissions) IsEmpty() bool {
return p == Permissions("")
}
// IsValid returns whether the set of permissions is a subset of valid
// permissions (namely, {r,w,m}).
func (p Permissions) IsValid() bool {
return p == fromSet(p.toSet())
}
type Type rune
const (
WildcardDevice Type = 'a'
BlockDevice Type = 'b'
CharDevice Type = 'c' // or 'u'
FifoDevice Type = 'p'
)
func (t Type) IsValid() bool {
switch t {
case WildcardDevice, BlockDevice, CharDevice, FifoDevice:
return true
default:
return false
}
}
func (t Type) CanMknod() bool {
switch t {
case BlockDevice, CharDevice, FifoDevice:
return true
default:
return false
}
}
func (t Type) CanCgroup() bool {
switch t {
case WildcardDevice, BlockDevice, CharDevice:
return true
default:
return false
}
}
type Rule struct {
// Type of device ('c' for char, 'b' for block). If set to 'a', this rule
// acts as a wildcard and all fields other than Allow are ignored.
Type Type `json:"type"`
// Major is the device's major number.
Major int64 `json:"major"`
// Minor is the device's minor number.
Minor int64 `json:"minor"`
// Permissions is the set of permissions that this rule applies to (in the
// cgroupv1 format -- any combination of "rwm").
Permissions Permissions `json:"permissions"`
// Allow specifies whether this rule is allowed.
Allow bool `json:"allow"`
}
func (d *Rule) CgroupString() string {
var (
major = strconv.FormatInt(d.Major, 10)
minor = strconv.FormatInt(d.Minor, 10)
)
if d.Major == Wildcard {
major = "*"
}
if d.Minor == Wildcard {
minor = "*"
}
return fmt.Sprintf("%c %s:%s %s", d.Type, major, minor, d.Permissions)
}
func (d *Rule) Mkdev() (uint64, error) {
return mkDev(d)
}

View File

@ -0,0 +1,14 @@
package config
import (
"errors"
"golang.org/x/sys/unix"
)
func mkDev(d *Rule) (uint64, error) {
if d.Major == Wildcard || d.Minor == Wildcard {
return 0, errors.New("cannot mkdev() device with wildcards")
}
return unix.Mkdev(uint32(d.Major), uint32(d.Minor)), nil
}

View File

@ -5,12 +5,11 @@ import (
"errors"
"fmt"
"os"
"path"
"path/filepath"
"strconv"
"strings"
"sync"
"github.com/opencontainers/runc/libcontainer/utils"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
@ -147,12 +146,15 @@ func openFile(dir, file string, flags int) (*os.File, error) {
flags |= os.O_TRUNC | os.O_CREATE
mode = 0o600
}
path := path.Join(dir, utils.CleanPath(file))
// NOTE it is important to use filepath.Clean("/"+file) here
// (see https://github.com/opencontainers/runc/issues/4103)!
path := filepath.Join(dir, filepath.Clean("/"+file))
if prepareOpenat2() != nil {
return openFallback(path, flags, mode)
}
relPath := strings.TrimPrefix(path, cgroupfsPrefix)
if len(relPath) == len(path) { // non-standard path, old system?
relPath, ok := strings.CutPrefix(path, cgroupfsPrefix)
if !ok { // Non-standard path, old system?
return openFallback(path, flags, mode)
}
@ -171,10 +173,8 @@ func openFile(dir, file string, flags int) (*os.File, error) {
//
// TODO: if such usage will ever be common, amend this
// to reopen cgroupRootHandle and retry openat2.
fdPath, closer := utils.ProcThreadSelf("fd/" + strconv.Itoa(int(cgroupRootHandle.Fd())))
defer closer()
fdDest, _ := os.Readlink(fdPath)
if fdDest != cgroupfsDir {
fdDest, fdErr := os.Readlink("/proc/thread-self/fd/" + strconv.Itoa(int(cgroupRootHandle.Fd())))
if fdErr == nil && fdDest != cgroupfsDir {
// Wrap the error so it is clear that cgroupRootHandle
// is opened to an unexpected/wrong directory.
err = fmt.Errorf("cgroupRootHandle %d unexpectedly opened to %s != %s: %w",

View File

@ -7,8 +7,7 @@ import (
"strconv"
"strings"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
)
type BlkioGroup struct {
@ -20,11 +19,11 @@ func (s *BlkioGroup) Name() string {
return "blkio"
}
func (s *BlkioGroup) Apply(path string, _ *configs.Resources, pid int) error {
func (s *BlkioGroup) Apply(path string, _ *cgroups.Resources, pid int) error {
return apply(path, pid)
}
func (s *BlkioGroup) Set(path string, r *configs.Resources) error {
func (s *BlkioGroup) Set(path string, r *cgroups.Resources) error {
s.detectWeightFilenames(path)
if r.BlkioWeight != 0 {
if err := cgroups.WriteFile(path, s.weightFilename, strconv.FormatUint(uint64(r.BlkioWeight), 10)); err != nil {

View File

@ -7,9 +7,8 @@ import (
"os"
"strconv"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
"github.com/opencontainers/cgroups/fscommon"
"golang.org/x/sys/unix"
)
@ -19,7 +18,7 @@ func (s *CpuGroup) Name() string {
return "cpu"
}
func (s *CpuGroup) Apply(path string, r *configs.Resources, pid int) error {
func (s *CpuGroup) Apply(path string, r *cgroups.Resources, pid int) error {
if err := os.MkdirAll(path, 0o755); err != nil {
return err
}
@ -34,7 +33,7 @@ func (s *CpuGroup) Apply(path string, r *configs.Resources, pid int) error {
return cgroups.WriteCgroupProc(path, pid)
}
func (s *CpuGroup) SetRtSched(path string, r *configs.Resources) error {
func (s *CpuGroup) SetRtSched(path string, r *cgroups.Resources) error {
var period string
if r.CpuRtPeriod != 0 {
period = strconv.FormatUint(r.CpuRtPeriod, 10)
@ -64,7 +63,7 @@ func (s *CpuGroup) SetRtSched(path string, r *configs.Resources) error {
return nil
}
func (s *CpuGroup) Set(path string, r *configs.Resources) error {
func (s *CpuGroup) Set(path string, r *cgroups.Resources) error {
if r.CpuShares != 0 {
shares := r.CpuShares
if err := cgroups.WriteFile(path, "cpu.shares", strconv.FormatUint(shares, 10)); err != nil {

View File

@ -6,20 +6,12 @@ import (
"strconv"
"strings"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
"github.com/opencontainers/cgroups/fscommon"
)
const (
cgroupCpuacctStat = "cpuacct.stat"
cgroupCpuacctUsageAll = "cpuacct.usage_all"
nanosecondsInSecond = 1000000000
userModeColumn = 1
kernelModeColumn = 2
cuacctUsageAllColumnsNumber = 3
nsInSec = 1000000000
// The value comes from `C.sysconf(C._SC_CLK_TCK)`, and
// on Linux it's a constant which is safe to be hard coded,
@ -34,11 +26,11 @@ func (s *CpuacctGroup) Name() string {
return "cpuacct"
}
func (s *CpuacctGroup) Apply(path string, _ *configs.Resources, pid int) error {
func (s *CpuacctGroup) Apply(path string, _ *cgroups.Resources, pid int) error {
return apply(path, pid)
}
func (s *CpuacctGroup) Set(_ string, _ *configs.Resources) error {
func (s *CpuacctGroup) Set(_ string, _ *cgroups.Resources) error {
return nil
}
@ -81,7 +73,7 @@ func getCpuUsageBreakdown(path string) (uint64, uint64, error) {
const (
userField = "user"
systemField = "system"
file = cgroupCpuacctStat
file = "cpuacct.stat"
)
// Expected format:
@ -103,7 +95,7 @@ func getCpuUsageBreakdown(path string) (uint64, uint64, error) {
return 0, 0, &parseError{Path: path, File: file, Err: err}
}
return (userModeUsage * nanosecondsInSecond) / clockTicks, (kernelModeUsage * nanosecondsInSecond) / clockTicks, nil
return (userModeUsage * nsInSec) / clockTicks, (kernelModeUsage * nsInSec) / clockTicks, nil
}
func getPercpuUsage(path string) ([]uint64, error) {
@ -113,7 +105,6 @@ func getPercpuUsage(path string) ([]uint64, error) {
if err != nil {
return percpuUsage, err
}
// TODO: use strings.SplitN instead.
for _, value := range strings.Fields(data) {
value, err := strconv.ParseUint(value, 10, 64)
if err != nil {
@ -127,7 +118,7 @@ func getPercpuUsage(path string) ([]uint64, error) {
func getPercpuUsageInModes(path string) ([]uint64, []uint64, error) {
usageKernelMode := []uint64{}
usageUserMode := []uint64{}
const file = cgroupCpuacctUsageAll
const file = "cpuacct.usage_all"
fd, err := cgroups.OpenFile(path, file, os.O_RDONLY)
if os.IsNotExist(err) {
@ -141,22 +132,23 @@ func getPercpuUsageInModes(path string) ([]uint64, []uint64, error) {
scanner.Scan() // skipping header line
for scanner.Scan() {
lineFields := strings.SplitN(scanner.Text(), " ", cuacctUsageAllColumnsNumber+1)
if len(lineFields) != cuacctUsageAllColumnsNumber {
// Each line is: cpu user system
fields := strings.SplitN(scanner.Text(), " ", 3)
if len(fields) != 3 {
continue
}
usageInKernelMode, err := strconv.ParseUint(lineFields[kernelModeColumn], 10, 64)
user, err := strconv.ParseUint(fields[1], 10, 64)
if err != nil {
return nil, nil, &parseError{Path: path, File: file, Err: err}
}
usageKernelMode = append(usageKernelMode, usageInKernelMode)
usageUserMode = append(usageUserMode, user)
usageInUserMode, err := strconv.ParseUint(lineFields[userModeColumn], 10, 64)
kernel, err := strconv.ParseUint(fields[2], 10, 64)
if err != nil {
return nil, nil, &parseError{Path: path, File: file, Err: err}
}
usageUserMode = append(usageUserMode, usageInUserMode)
usageKernelMode = append(usageKernelMode, kernel)
}
if err := scanner.Err(); err != nil {
return nil, nil, &parseError{Path: path, File: file, Err: err}

View File

@ -6,32 +6,66 @@ import (
"path/filepath"
"strconv"
"strings"
"sync"
"golang.org/x/sys/unix"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
"github.com/opencontainers/cgroups/fscommon"
)
var (
cpusetLock sync.Mutex
cpusetPrefix = "cpuset."
cpusetFastPath bool
)
func cpusetFile(path string, name string) string {
cpusetLock.Lock()
defer cpusetLock.Unlock()
// Only the v1 cpuset cgroup is allowed to mount with noprefix.
// See kernel source: https://github.com/torvalds/linux/blob/2e1b3cc9d7f790145a80cb705b168f05dab65df2/kernel/cgroup/cgroup-v1.c#L1070
// Cpuset cannot be mounted with and without prefix simultaneously.
// Commonly used in Android environments.
if cpusetFastPath {
return cpusetPrefix + name
}
err := unix.Access(filepath.Join(path, cpusetPrefix+name), unix.F_OK)
if err == nil {
// Use the fast path only if we can access one type of mount for cpuset already
cpusetFastPath = true
} else {
err = unix.Access(filepath.Join(path, name), unix.F_OK)
if err == nil {
cpusetPrefix = ""
cpusetFastPath = true
}
}
return cpusetPrefix + name
}
type CpusetGroup struct{}
func (s *CpusetGroup) Name() string {
return "cpuset"
}
func (s *CpusetGroup) Apply(path string, r *configs.Resources, pid int) error {
func (s *CpusetGroup) Apply(path string, r *cgroups.Resources, pid int) error {
return s.ApplyDir(path, r, pid)
}
func (s *CpusetGroup) Set(path string, r *configs.Resources) error {
func (s *CpusetGroup) Set(path string, r *cgroups.Resources) error {
if r.CpusetCpus != "" {
if err := cgroups.WriteFile(path, "cpuset.cpus", r.CpusetCpus); err != nil {
if err := cgroups.WriteFile(path, cpusetFile(path, "cpus"), r.CpusetCpus); err != nil {
return err
}
}
if r.CpusetMems != "" {
if err := cgroups.WriteFile(path, "cpuset.mems", r.CpusetMems); err != nil {
if err := cgroups.WriteFile(path, cpusetFile(path, "mems"), r.CpusetMems); err != nil {
return err
}
}
@ -49,26 +83,23 @@ func getCpusetStat(path string, file string) ([]uint16, error) {
}
for _, s := range strings.Split(fileContent, ",") {
sp := strings.SplitN(s, "-", 3)
switch len(sp) {
case 3:
return extracted, &parseError{Path: path, File: file, Err: errors.New("extra dash")}
case 2:
min, err := strconv.ParseUint(sp[0], 10, 16)
fromStr, toStr, ok := strings.Cut(s, "-")
if ok {
from, err := strconv.ParseUint(fromStr, 10, 16)
if err != nil {
return extracted, &parseError{Path: path, File: file, Err: err}
}
max, err := strconv.ParseUint(sp[1], 10, 16)
to, err := strconv.ParseUint(toStr, 10, 16)
if err != nil {
return extracted, &parseError{Path: path, File: file, Err: err}
}
if min > max {
return extracted, &parseError{Path: path, File: file, Err: errors.New("invalid values, min > max")}
if from > to {
return extracted, &parseError{Path: path, File: file, Err: errors.New("invalid values, from > to")}
}
for i := min; i <= max; i++ {
for i := from; i <= to; i++ {
extracted = append(extracted, uint16(i))
}
case 1:
} else {
value, err := strconv.ParseUint(s, 10, 16)
if err != nil {
return extracted, &parseError{Path: path, File: file, Err: err}
@ -83,57 +114,57 @@ func getCpusetStat(path string, file string) ([]uint16, error) {
func (s *CpusetGroup) GetStats(path string, stats *cgroups.Stats) error {
var err error
stats.CPUSetStats.CPUs, err = getCpusetStat(path, "cpuset.cpus")
stats.CPUSetStats.CPUs, err = getCpusetStat(path, cpusetFile(path, "cpus"))
if err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
stats.CPUSetStats.CPUExclusive, err = fscommon.GetCgroupParamUint(path, "cpuset.cpu_exclusive")
stats.CPUSetStats.CPUExclusive, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "cpu_exclusive"))
if err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
stats.CPUSetStats.Mems, err = getCpusetStat(path, "cpuset.mems")
stats.CPUSetStats.Mems, err = getCpusetStat(path, cpusetFile(path, "mems"))
if err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
stats.CPUSetStats.MemHardwall, err = fscommon.GetCgroupParamUint(path, "cpuset.mem_hardwall")
stats.CPUSetStats.MemHardwall, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "mem_hardwall"))
if err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
stats.CPUSetStats.MemExclusive, err = fscommon.GetCgroupParamUint(path, "cpuset.mem_exclusive")
stats.CPUSetStats.MemExclusive, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "mem_exclusive"))
if err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
stats.CPUSetStats.MemoryMigrate, err = fscommon.GetCgroupParamUint(path, "cpuset.memory_migrate")
stats.CPUSetStats.MemoryMigrate, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "memory_migrate"))
if err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
stats.CPUSetStats.MemorySpreadPage, err = fscommon.GetCgroupParamUint(path, "cpuset.memory_spread_page")
stats.CPUSetStats.MemorySpreadPage, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "memory_spread_page"))
if err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
stats.CPUSetStats.MemorySpreadSlab, err = fscommon.GetCgroupParamUint(path, "cpuset.memory_spread_slab")
stats.CPUSetStats.MemorySpreadSlab, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "memory_spread_slab"))
if err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
stats.CPUSetStats.MemoryPressure, err = fscommon.GetCgroupParamUint(path, "cpuset.memory_pressure")
stats.CPUSetStats.MemoryPressure, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "memory_pressure"))
if err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
stats.CPUSetStats.SchedLoadBalance, err = fscommon.GetCgroupParamUint(path, "cpuset.sched_load_balance")
stats.CPUSetStats.SchedLoadBalance, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "sched_load_balance"))
if err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
stats.CPUSetStats.SchedRelaxDomainLevel, err = fscommon.GetCgroupParamInt(path, "cpuset.sched_relax_domain_level")
stats.CPUSetStats.SchedRelaxDomainLevel, err = fscommon.GetCgroupParamInt(path, cpusetFile(path, "sched_relax_domain_level"))
if err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
@ -141,7 +172,7 @@ func (s *CpusetGroup) GetStats(path string, stats *cgroups.Stats) error {
return nil
}
func (s *CpusetGroup) ApplyDir(dir string, r *configs.Resources, pid int) error {
func (s *CpusetGroup) ApplyDir(dir string, r *cgroups.Resources, pid int) error {
// This might happen if we have no cpuset cgroup mounted.
// Just do nothing and don't fail.
if dir == "" {
@ -172,10 +203,10 @@ func (s *CpusetGroup) ApplyDir(dir string, r *configs.Resources, pid int) error
}
func getCpusetSubsystemSettings(parent string) (cpus, mems string, err error) {
if cpus, err = cgroups.ReadFile(parent, "cpuset.cpus"); err != nil {
if cpus, err = cgroups.ReadFile(parent, cpusetFile(parent, "cpus")); err != nil {
return
}
if mems, err = cgroups.ReadFile(parent, "cpuset.mems"); err != nil {
if mems, err = cgroups.ReadFile(parent, cpusetFile(parent, "mems")); err != nil {
return
}
return cpus, mems, nil
@ -221,12 +252,12 @@ func cpusetCopyIfNeeded(current, parent string) error {
}
if isEmptyCpuset(currentCpus) {
if err := cgroups.WriteFile(current, "cpuset.cpus", parentCpus); err != nil {
if err := cgroups.WriteFile(current, cpusetFile(current, "cpus"), parentCpus); err != nil {
return err
}
}
if isEmptyCpuset(currentMems) {
if err := cgroups.WriteFile(current, "cpuset.mems", parentMems); err != nil {
if err := cgroups.WriteFile(current, cpusetFile(current, "mems"), parentMems); err != nil {
return err
}
}
@ -237,7 +268,7 @@ func isEmptyCpuset(str string) bool {
return str == "" || str == "\n"
}
func (s *CpusetGroup) ensureCpusAndMems(path string, r *configs.Resources) error {
func (s *CpusetGroup) ensureCpusAndMems(path string, r *cgroups.Resources) error {
if err := s.Set(path, r); err != nil {
return err
}

View File

@ -1,8 +1,7 @@
package fs
import (
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
)
type DevicesGroup struct{}
@ -11,7 +10,7 @@ func (s *DevicesGroup) Name() string {
return "devices"
}
func (s *DevicesGroup) Apply(path string, r *configs.Resources, pid int) error {
func (s *DevicesGroup) Apply(path string, r *cgroups.Resources, pid int) error {
if r.SkipDevices {
return nil
}
@ -24,7 +23,7 @@ func (s *DevicesGroup) Apply(path string, r *configs.Resources, pid int) error {
return apply(path, pid)
}
func (s *DevicesGroup) Set(path string, r *configs.Resources) error {
func (s *DevicesGroup) Set(path string, r *cgroups.Resources) error {
if cgroups.DevicesSetV1 == nil {
if len(r.Devices) == 0 {
return nil

View File

@ -3,7 +3,7 @@ package fs
import (
"fmt"
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
"github.com/opencontainers/cgroups/fscommon"
)
type parseError = fscommon.ParseError

View File

@ -7,8 +7,7 @@ import (
"strings"
"time"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
@ -19,19 +18,19 @@ func (s *FreezerGroup) Name() string {
return "freezer"
}
func (s *FreezerGroup) Apply(path string, _ *configs.Resources, pid int) error {
func (s *FreezerGroup) Apply(path string, _ *cgroups.Resources, pid int) error {
return apply(path, pid)
}
func (s *FreezerGroup) Set(path string, r *configs.Resources) (Err error) {
func (s *FreezerGroup) Set(path string, r *cgroups.Resources) (Err error) {
switch r.Freezer {
case configs.Frozen:
case cgroups.Frozen:
defer func() {
if Err != nil {
// Freezing failed, and it is bad and dangerous
// to leave the cgroup in FROZEN or FREEZING
// state, so (try to) thaw it back.
_ = cgroups.WriteFile(path, "freezer.state", string(configs.Thawed))
_ = cgroups.WriteFile(path, "freezer.state", string(cgroups.Thawed))
}
}()
@ -64,11 +63,11 @@ func (s *FreezerGroup) Set(path string, r *configs.Resources) (Err error) {
// the chances to succeed in freezing
// in case new processes keep appearing
// in the cgroup.
_ = cgroups.WriteFile(path, "freezer.state", string(configs.Thawed))
_ = cgroups.WriteFile(path, "freezer.state", string(cgroups.Thawed))
time.Sleep(10 * time.Millisecond)
}
if err := cgroups.WriteFile(path, "freezer.state", string(configs.Frozen)); err != nil {
if err := cgroups.WriteFile(path, "freezer.state", string(cgroups.Frozen)); err != nil {
return err
}
@ -87,7 +86,7 @@ func (s *FreezerGroup) Set(path string, r *configs.Resources) (Err error) {
switch state {
case "FREEZING":
continue
case string(configs.Frozen):
case string(cgroups.Frozen):
if i > 1 {
logrus.Debugf("frozen after %d retries", i)
}
@ -99,9 +98,9 @@ func (s *FreezerGroup) Set(path string, r *configs.Resources) (Err error) {
}
// Despite our best efforts, it got stuck in FREEZING.
return errors.New("unable to freeze")
case configs.Thawed:
return cgroups.WriteFile(path, "freezer.state", string(configs.Thawed))
case configs.Undefined:
case cgroups.Thawed:
return cgroups.WriteFile(path, "freezer.state", string(cgroups.Thawed))
case cgroups.Undefined:
return nil
default:
return fmt.Errorf("Invalid argument '%s' to freezer.state", string(r.Freezer))
@ -112,7 +111,7 @@ func (s *FreezerGroup) GetStats(path string, stats *cgroups.Stats) error {
return nil
}
func (s *FreezerGroup) GetState(path string) (configs.FreezerState, error) {
func (s *FreezerGroup) GetState(path string) (cgroups.FreezerState, error) {
for {
state, err := cgroups.ReadFile(path, "freezer.state")
if err != nil {
@ -121,11 +120,11 @@ func (s *FreezerGroup) GetState(path string) (configs.FreezerState, error) {
if os.IsNotExist(err) || errors.Is(err, unix.ENODEV) {
err = nil
}
return configs.Undefined, err
return cgroups.Undefined, err
}
switch strings.TrimSpace(state) {
case "THAWED":
return configs.Thawed, nil
return cgroups.Thawed, nil
case "FROZEN":
// Find out whether the cgroup is frozen directly,
// or indirectly via an ancestor.
@ -136,15 +135,15 @@ func (s *FreezerGroup) GetState(path string) (configs.FreezerState, error) {
if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.ENODEV) {
err = nil
}
return configs.Frozen, err
return cgroups.Frozen, err
}
switch self {
case "0\n":
return configs.Thawed, nil
return cgroups.Thawed, nil
case "1\n":
return configs.Frozen, nil
return cgroups.Frozen, nil
default:
return configs.Undefined, fmt.Errorf(`unknown "freezer.self_freezing" state: %q`, self)
return cgroups.Undefined, fmt.Errorf(`unknown "freezer.self_freezing" state: %q`, self)
}
case "FREEZING":
// Make sure we get a stable freezer state, so retry if the cgroup
@ -152,7 +151,7 @@ func (s *FreezerGroup) GetState(path string) (configs.FreezerState, error) {
time.Sleep(1 * time.Millisecond)
continue
default:
return configs.Undefined, fmt.Errorf("unknown freezer.state %q", state)
return cgroups.Undefined, fmt.Errorf("unknown freezer.state %q", state)
}
}
}

View File

@ -8,9 +8,8 @@ import (
"golang.org/x/sys/unix"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
"github.com/opencontainers/cgroups/fscommon"
)
var subsystems = []subsystem{
@ -49,22 +48,22 @@ type subsystem interface {
// Apply creates and joins a cgroup, adding pid into it. Some
// subsystems use resources to pre-configure the cgroup parents
// before creating or joining it.
Apply(path string, r *configs.Resources, pid int) error
Apply(path string, r *cgroups.Resources, pid int) error
// Set sets the cgroup resources.
Set(path string, r *configs.Resources) error
Set(path string, r *cgroups.Resources) error
}
type Manager struct {
mu sync.Mutex
cgroups *configs.Cgroup
cgroups *cgroups.Cgroup
paths map[string]string
}
func NewManager(cg *configs.Cgroup, paths map[string]string) (*Manager, error) {
func NewManager(cg *cgroups.Cgroup, paths map[string]string) (*Manager, error) {
// Some v1 controllers (cpu, cpuset, and devices) expect
// cgroups.Resources to not be nil in Apply.
if cg.Resources == nil {
return nil, errors.New("cgroup v1 manager needs configs.Resources to be set during manager creation")
return nil, errors.New("cgroup v1 manager needs cgroups.Resources to be set during manager creation")
}
if cg.Resources.Unified != nil {
return nil, cgroups.ErrV1NoUnified
@ -168,7 +167,7 @@ func (m *Manager) GetStats() (*cgroups.Stats, error) {
return stats, nil
}
func (m *Manager) Set(r *configs.Resources) error {
func (m *Manager) Set(r *cgroups.Resources) error {
if r == nil {
return nil
}
@ -203,7 +202,7 @@ func (m *Manager) Set(r *configs.Resources) error {
// Freeze toggles the container's freezer cgroup depending on the state
// provided
func (m *Manager) Freeze(state configs.FreezerState) error {
func (m *Manager) Freeze(state cgroups.FreezerState) error {
path := m.Path("freezer")
if path == "" {
return errors.New("cannot toggle freezer: cgroups not configured for container")
@ -233,15 +232,15 @@ func (m *Manager) GetPaths() map[string]string {
return m.paths
}
func (m *Manager) GetCgroups() (*configs.Cgroup, error) {
func (m *Manager) GetCgroups() (*cgroups.Cgroup, error) {
return m.cgroups, nil
}
func (m *Manager) GetFreezerState() (configs.FreezerState, error) {
func (m *Manager) GetFreezerState() (cgroups.FreezerState, error) {
dir := m.Path("freezer")
// If the container doesn't have the freezer cgroup, say it's undefined.
if dir == "" {
return configs.Undefined, nil
return cgroups.Undefined, nil
}
freezer := &FreezerGroup{}
return freezer.GetState(dir)

View File

@ -5,9 +5,8 @@ import (
"os"
"strconv"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
"github.com/opencontainers/cgroups/fscommon"
)
type HugetlbGroup struct{}
@ -16,11 +15,11 @@ func (s *HugetlbGroup) Name() string {
return "hugetlb"
}
func (s *HugetlbGroup) Apply(path string, _ *configs.Resources, pid int) error {
func (s *HugetlbGroup) Apply(path string, _ *cgroups.Resources, pid int) error {
return apply(path, pid)
}
func (s *HugetlbGroup) Set(path string, r *configs.Resources) error {
func (s *HugetlbGroup) Set(path string, r *cgroups.Resources) error {
const suffix = ".limit_in_bytes"
skipRsvd := false

View File

@ -12,9 +12,8 @@ import (
"golang.org/x/sys/unix"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
"github.com/opencontainers/cgroups/fscommon"
)
const (
@ -30,7 +29,7 @@ func (s *MemoryGroup) Name() string {
return "memory"
}
func (s *MemoryGroup) Apply(path string, _ *configs.Resources, pid int) error {
func (s *MemoryGroup) Apply(path string, _ *cgroups.Resources, pid int) error {
return apply(path, pid)
}
@ -66,7 +65,7 @@ func setSwap(path string, val int64) error {
return cgroups.WriteFile(path, cgroupMemorySwapLimit, strconv.FormatInt(val, 10))
}
func setMemoryAndSwap(path string, r *configs.Resources) error {
func setMemoryAndSwap(path string, r *cgroups.Resources) error {
// If the memory update is set to -1 and the swap is not explicitly
// set, we should also set swap to -1, it means unlimited memory.
if r.Memory == -1 && r.MemorySwap == 0 {
@ -108,7 +107,7 @@ func setMemoryAndSwap(path string, r *configs.Resources) error {
return nil
}
func (s *MemoryGroup) Set(path string, r *configs.Resources) error {
func (s *MemoryGroup) Set(path string, r *cgroups.Resources) error {
if err := setMemoryAndSwap(path, r); err != nil {
return err
}

View File

@ -1,8 +1,7 @@
package fs
import (
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
)
type NameGroup struct {
@ -14,7 +13,7 @@ func (s *NameGroup) Name() string {
return s.GroupName
}
func (s *NameGroup) Apply(path string, _ *configs.Resources, pid int) error {
func (s *NameGroup) Apply(path string, _ *cgroups.Resources, pid int) error {
if s.Join {
// Ignore errors if the named cgroup does not exist.
_ = apply(path, pid)
@ -22,7 +21,7 @@ func (s *NameGroup) Apply(path string, _ *configs.Resources, pid int) error {
return nil
}
func (s *NameGroup) Set(_ string, _ *configs.Resources) error {
func (s *NameGroup) Set(_ string, _ *cgroups.Resources) error {
return nil
}

View File

@ -3,8 +3,7 @@ package fs
import (
"strconv"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
)
type NetClsGroup struct{}
@ -13,11 +12,11 @@ func (s *NetClsGroup) Name() string {
return "net_cls"
}
func (s *NetClsGroup) Apply(path string, _ *configs.Resources, pid int) error {
func (s *NetClsGroup) Apply(path string, _ *cgroups.Resources, pid int) error {
return apply(path, pid)
}
func (s *NetClsGroup) Set(path string, r *configs.Resources) error {
func (s *NetClsGroup) Set(path string, r *cgroups.Resources) error {
if r.NetClsClassid != 0 {
if err := cgroups.WriteFile(path, "net_cls.classid", strconv.FormatUint(uint64(r.NetClsClassid), 10)); err != nil {
return err

View File

@ -1,8 +1,7 @@
package fs
import (
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
)
type NetPrioGroup struct{}
@ -11,11 +10,11 @@ func (s *NetPrioGroup) Name() string {
return "net_prio"
}
func (s *NetPrioGroup) Apply(path string, _ *configs.Resources, pid int) error {
func (s *NetPrioGroup) Apply(path string, _ *cgroups.Resources, pid int) error {
return apply(path, pid)
}
func (s *NetPrioGroup) Set(path string, r *configs.Resources) error {
func (s *NetPrioGroup) Set(path string, r *cgroups.Resources) error {
for _, prioMap := range r.NetPrioIfpriomap {
if err := cgroups.WriteFile(path, "net_prio.ifpriomap", prioMap.CgroupString()); err != nil {
return err

View File

@ -8,9 +8,8 @@ import (
"golang.org/x/sys/unix"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/utils"
"github.com/opencontainers/cgroups"
"github.com/opencontainers/cgroups/internal/path"
)
// The absolute path to the root of the cgroup hierarchies.
@ -21,13 +20,13 @@ var (
const defaultCgroupRoot = "/sys/fs/cgroup"
func initPaths(cg *configs.Cgroup) (map[string]string, error) {
func initPaths(cg *cgroups.Cgroup) (map[string]string, error) {
root, err := rootPath()
if err != nil {
return nil, err
}
inner, err := innerPath(cg)
inner, err := path.Inner(cg)
if err != nil {
return nil, err
}
@ -136,22 +135,6 @@ func rootPath() (string, error) {
return cgroupRoot, nil
}
func innerPath(c *configs.Cgroup) (string, error) {
if (c.Name != "" || c.Parent != "") && c.Path != "" {
return "", errors.New("cgroup: either Path or Name and Parent should be used")
}
// XXX: Do not remove CleanPath. Path safety is important! -- cyphar
innerPath := utils.CleanPath(c.Path)
if innerPath == "" {
cgParent := utils.CleanPath(c.Parent)
cgName := utils.CleanPath(c.Name)
innerPath = filepath.Join(cgParent, cgName)
}
return innerPath, nil
}
func subsysPath(root, inner, subsystem string) (string, error) {
// If the cgroup name/path is absolute do not look relative to the cgroup of the init process.
if filepath.IsAbs(inner) {

View File

@ -1,8 +1,7 @@
package fs
import (
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
)
type PerfEventGroup struct{}
@ -11,11 +10,11 @@ func (s *PerfEventGroup) Name() string {
return "perf_event"
}
func (s *PerfEventGroup) Apply(path string, _ *configs.Resources, pid int) error {
func (s *PerfEventGroup) Apply(path string, _ *cgroups.Resources, pid int) error {
return apply(path, pid)
}
func (s *PerfEventGroup) Set(_ string, _ *configs.Resources) error {
func (s *PerfEventGroup) Set(_ string, _ *cgroups.Resources) error {
return nil
}

View File

@ -4,9 +4,8 @@ import (
"math"
"strconv"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/cgroups"
"github.com/opencontainers/cgroups/fscommon"
)
type PidsGroup struct{}
@ -15,11 +14,11 @@ func (s *PidsGroup) Name() string {
return "pids"
}
func (s *PidsGroup) Apply(path string, _ *configs.Resources, pid int) error {
func (s *PidsGroup) Apply(path string, _ *cgroups.Resources, pid int) error {
return apply(path, pid)
}
func (s *PidsGroup) Set(path string, r *configs.Resources) error {
func (s *PidsGroup) Set(path string, r *cgroups.Resources) error {
if r.PidsLimit != 0 {
// "max" is the fallback value.
limit := "max"

Some files were not shown because too many files have changed in this diff Show More