mirror of https://github.com/containers/podman.git
Merge pull request #22243 from Luap99/rootless-netns
vendor latest c/common to fix rootless-netns issues
This commit is contained in:
commit
8ab4bc9250
10
go.mod
10
go.mod
|
@ -26,7 +26,7 @@ require (
|
||||||
github.com/checkpoint-restore/go-criu/v7 v7.1.0
|
github.com/checkpoint-restore/go-criu/v7 v7.1.0
|
||||||
github.com/containernetworking/plugins v1.4.0
|
github.com/containernetworking/plugins v1.4.0
|
||||||
github.com/containers/buildah v1.35.1-0.20240318192459-e64e6cc09dfd
|
github.com/containers/buildah v1.35.1-0.20240318192459-e64e6cc09dfd
|
||||||
github.com/containers/common v0.58.1-0.20240320163250-bc5f97c39cca
|
github.com/containers/common v0.58.1-0.20240403123718-735c922b53c4
|
||||||
github.com/containers/conmon v2.0.20+incompatible
|
github.com/containers/conmon v2.0.20+incompatible
|
||||||
github.com/containers/gvisor-tap-vsock v0.7.3
|
github.com/containers/gvisor-tap-vsock v0.7.3
|
||||||
github.com/containers/image/v5 v5.30.0
|
github.com/containers/image/v5 v5.30.0
|
||||||
|
@ -64,7 +64,7 @@ require (
|
||||||
github.com/moby/sys/user v0.1.0
|
github.com/moby/sys/user v0.1.0
|
||||||
github.com/moby/term v0.5.0
|
github.com/moby/term v0.5.0
|
||||||
github.com/nxadm/tail v1.4.11
|
github.com/nxadm/tail v1.4.11
|
||||||
github.com/onsi/ginkgo/v2 v2.17.0
|
github.com/onsi/ginkgo/v2 v2.17.1
|
||||||
github.com/onsi/gomega v1.32.0
|
github.com/onsi/gomega v1.32.0
|
||||||
github.com/opencontainers/go-digest v1.0.0
|
github.com/opencontainers/go-digest v1.0.0
|
||||||
github.com/opencontainers/image-spec v1.1.0
|
github.com/opencontainers/image-spec v1.1.0
|
||||||
|
@ -84,7 +84,7 @@ require (
|
||||||
github.com/vishvananda/netlink v1.2.1-beta.2
|
github.com/vishvananda/netlink v1.2.1-beta.2
|
||||||
go.etcd.io/bbolt v1.3.9
|
go.etcd.io/bbolt v1.3.9
|
||||||
golang.org/x/crypto v0.21.0
|
golang.org/x/crypto v0.21.0
|
||||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225
|
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8
|
||||||
golang.org/x/net v0.22.0
|
golang.org/x/net v0.22.0
|
||||||
golang.org/x/sync v0.6.0
|
golang.org/x/sync v0.6.0
|
||||||
golang.org/x/sys v0.18.0
|
golang.org/x/sys v0.18.0
|
||||||
|
@ -227,10 +227,10 @@ require (
|
||||||
go.opentelemetry.io/otel/sdk v1.21.0 // indirect
|
go.opentelemetry.io/otel/sdk v1.21.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.22.0 // indirect
|
go.opentelemetry.io/otel/trace v1.22.0 // indirect
|
||||||
golang.org/x/arch v0.7.0 // indirect
|
golang.org/x/arch v0.7.0 // indirect
|
||||||
golang.org/x/mod v0.15.0 // indirect
|
golang.org/x/mod v0.16.0 // indirect
|
||||||
golang.org/x/oauth2 v0.18.0 // indirect
|
golang.org/x/oauth2 v0.18.0 // indirect
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
golang.org/x/tools v0.18.0 // indirect
|
golang.org/x/tools v0.19.0 // indirect
|
||||||
google.golang.org/appengine v1.6.8 // indirect
|
google.golang.org/appengine v1.6.8 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||||
google.golang.org/grpc v1.62.0 // indirect
|
google.golang.org/grpc v1.62.0 // indirect
|
||||||
|
|
20
go.sum
20
go.sum
|
@ -76,8 +76,8 @@ github.com/containernetworking/plugins v1.4.0 h1:+w22VPYgk7nQHw7KT92lsRmuToHvb7w
|
||||||
github.com/containernetworking/plugins v1.4.0/go.mod h1:UYhcOyjefnrQvKvmmyEKsUA+M9Nfn7tqULPpH0Pkcj0=
|
github.com/containernetworking/plugins v1.4.0/go.mod h1:UYhcOyjefnrQvKvmmyEKsUA+M9Nfn7tqULPpH0Pkcj0=
|
||||||
github.com/containers/buildah v1.35.1-0.20240318192459-e64e6cc09dfd h1:QVUSJsMYYUIQmMi+PU9NYXpbk/lgz0Xx6/naihFHFBQ=
|
github.com/containers/buildah v1.35.1-0.20240318192459-e64e6cc09dfd h1:QVUSJsMYYUIQmMi+PU9NYXpbk/lgz0Xx6/naihFHFBQ=
|
||||||
github.com/containers/buildah v1.35.1-0.20240318192459-e64e6cc09dfd/go.mod h1:kJEmpENlkUrZ39k4jVJC9RxDNH30qxSsfEOar4la8Ec=
|
github.com/containers/buildah v1.35.1-0.20240318192459-e64e6cc09dfd/go.mod h1:kJEmpENlkUrZ39k4jVJC9RxDNH30qxSsfEOar4la8Ec=
|
||||||
github.com/containers/common v0.58.1-0.20240320163250-bc5f97c39cca h1:5hTRZutFijVzUJJAU5oQJTOSbFkN2yJ2INcWlfMFjwk=
|
github.com/containers/common v0.58.1-0.20240403123718-735c922b53c4 h1:lj/tku4jvMnYcDmRIz182mPkI99CDK7Zvh4eN6NhR/k=
|
||||||
github.com/containers/common v0.58.1-0.20240320163250-bc5f97c39cca/go.mod h1:qVUk13f2BftvRSK9rkR7VI9aUPCt+IzOyApQdqqkPyw=
|
github.com/containers/common v0.58.1-0.20240403123718-735c922b53c4/go.mod h1:10Y0+fVkDetxuizCMziHDUBbCUR87tgz82oHGCnhi4g=
|
||||||
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
|
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/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
|
||||||
github.com/containers/gvisor-tap-vsock v0.7.3 h1:yORnf15sP+sLFhxLNLgmB5/lOhldn9dRMHx/tmYtSOQ=
|
github.com/containers/gvisor-tap-vsock v0.7.3 h1:yORnf15sP+sLFhxLNLgmB5/lOhldn9dRMHx/tmYtSOQ=
|
||||||
|
@ -443,8 +443,8 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
||||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||||
github.com/onsi/ginkgo/v2 v2.17.0 h1:kdnunFXpBjbzN56hcJHrXZ8M+LOkenKA7NnBzTNigTI=
|
github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
|
||||||
github.com/onsi/ginkgo/v2 v2.17.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
|
github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||||
|
@ -646,8 +646,8 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf
|
||||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
|
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw=
|
||||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
|
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
@ -656,8 +656,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
|
||||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
@ -777,8 +777,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
|
||||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
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.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
|
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
|
||||||
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
|
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|
|
@ -785,6 +785,12 @@ EOF
|
||||||
|
|
||||||
pasta_iface=$(default_ifname)
|
pasta_iface=$(default_ifname)
|
||||||
|
|
||||||
|
# First let's force a setup error by making pasta be "false".
|
||||||
|
ln -s /usr/bin/false $PODMAN_TMPDIR/pasta
|
||||||
|
CONTAINERS_HELPER_BINARY_DIR="$PODMAN_TMPDIR" run_podman 125 unshare --rootless-netns ip addr
|
||||||
|
assert "$output" =~ "pasta failed with exit code 1"
|
||||||
|
|
||||||
|
# Now this should recover from the previous error and setup the netns correctly.
|
||||||
run_podman unshare --rootless-netns ip addr
|
run_podman unshare --rootless-netns ip addr
|
||||||
is "$output" ".*${pasta_iface}.*"
|
is "$output" ".*${pasta_iface}.*"
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
dockerArchiveTransport "github.com/containers/image/v5/docker/archive"
|
dockerArchiveTransport "github.com/containers/image/v5/docker/archive"
|
||||||
ociArchiveTransport "github.com/containers/image/v5/oci/archive"
|
ociArchiveTransport "github.com/containers/image/v5/oci/archive"
|
||||||
ociTransport "github.com/containers/image/v5/oci/layout"
|
ociTransport "github.com/containers/image/v5/oci/layout"
|
||||||
|
"github.com/containers/image/v5/transports"
|
||||||
"github.com/containers/image/v5/types"
|
"github.com/containers/image/v5/types"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
@ -21,6 +22,30 @@ type LoadOptions struct {
|
||||||
CopyOptions
|
CopyOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// doLoadReference does the heavy lifting for LoadReference() and Load(),
|
||||||
|
// without adding debug messages or handling defaults.
|
||||||
|
func (r *Runtime) doLoadReference(ctx context.Context, ref types.ImageReference, options *LoadOptions) (images []string, transportName string, err error) {
|
||||||
|
transportName = ref.Transport().Name()
|
||||||
|
switch transportName {
|
||||||
|
case dockerArchiveTransport.Transport.Name():
|
||||||
|
images, err = r.loadMultiImageDockerArchive(ctx, ref, &options.CopyOptions)
|
||||||
|
default:
|
||||||
|
images, err = r.copyFromDefault(ctx, ref, &options.CopyOptions)
|
||||||
|
}
|
||||||
|
return images, ref.Transport().Name(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadReference loads one or more images from the specified location.
|
||||||
|
func (r *Runtime) LoadReference(ctx context.Context, ref types.ImageReference, options *LoadOptions) ([]string, error) {
|
||||||
|
logrus.Debugf("Loading image from %q", transports.ImageName(ref))
|
||||||
|
|
||||||
|
if options == nil {
|
||||||
|
options = &LoadOptions{}
|
||||||
|
}
|
||||||
|
images, _, err := r.doLoadReference(ctx, ref, options)
|
||||||
|
return images, err
|
||||||
|
}
|
||||||
|
|
||||||
// Load loads one or more images (depending on the transport) from the
|
// Load loads one or more images (depending on the transport) from the
|
||||||
// specified path. The path may point to an image the following transports:
|
// specified path. The path may point to an image the following transports:
|
||||||
// oci, oci-archive, dir, docker-archive.
|
// oci, oci-archive, dir, docker-archive.
|
||||||
|
@ -41,8 +66,7 @@ func (r *Runtime) Load(ctx context.Context, path string, options *LoadOptions) (
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, ociTransport.Transport.Name(), err
|
return nil, ociTransport.Transport.Name(), err
|
||||||
}
|
}
|
||||||
images, err := r.copyFromDefault(ctx, ref, &options.CopyOptions)
|
return r.doLoadReference(ctx, ref, options)
|
||||||
return images, ociTransport.Transport.Name(), err
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// OCI-ARCHIVE
|
// OCI-ARCHIVE
|
||||||
|
@ -52,8 +76,7 @@ func (r *Runtime) Load(ctx context.Context, path string, options *LoadOptions) (
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, ociArchiveTransport.Transport.Name(), err
|
return nil, ociArchiveTransport.Transport.Name(), err
|
||||||
}
|
}
|
||||||
images, err := r.copyFromDefault(ctx, ref, &options.CopyOptions)
|
return r.doLoadReference(ctx, ref, options)
|
||||||
return images, ociArchiveTransport.Transport.Name(), err
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// DOCKER-ARCHIVE
|
// DOCKER-ARCHIVE
|
||||||
|
@ -63,8 +86,7 @@ func (r *Runtime) Load(ctx context.Context, path string, options *LoadOptions) (
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, dockerArchiveTransport.Transport.Name(), err
|
return nil, dockerArchiveTransport.Transport.Name(), err
|
||||||
}
|
}
|
||||||
images, err := r.loadMultiImageDockerArchive(ctx, ref, &options.CopyOptions)
|
return r.doLoadReference(ctx, ref, options)
|
||||||
return images, dockerArchiveTransport.Transport.Name(), err
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// DIR
|
// DIR
|
||||||
|
@ -74,8 +96,7 @@ func (r *Runtime) Load(ctx context.Context, path string, options *LoadOptions) (
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, dirTransport.Transport.Name(), err
|
return nil, dirTransport.Transport.Name(), err
|
||||||
}
|
}
|
||||||
images, err := r.copyFromDefault(ctx, ref, &options.CopyOptions)
|
return r.doLoadReference(ctx, ref, options)
|
||||||
return images, dirTransport.Transport.Name(), err
|
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
loadedImages, transportName, err := f()
|
loadedImages, transportName, err := f()
|
||||||
|
|
|
@ -314,6 +314,29 @@ type ManifestListAddOptions struct {
|
||||||
Password string
|
Password string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *ManifestList) parseNameToExtantReference(ctx context.Context, name string, manifestList bool, what string) (types.ImageReference, error) {
|
||||||
|
ref, err := alltransports.ParseImageName(name)
|
||||||
|
if err != nil {
|
||||||
|
withDocker := fmt.Sprintf("%s://%s", docker.Transport.Name(), name)
|
||||||
|
ref, err = alltransports.ParseImageName(withDocker)
|
||||||
|
if err == nil {
|
||||||
|
var src types.ImageSource
|
||||||
|
src, err = ref.NewImageSource(ctx, nil)
|
||||||
|
if err == nil {
|
||||||
|
src.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
image, _, lookupErr := m.image.runtime.LookupImage(name, &LookupImageOptions{ManifestList: manifestList})
|
||||||
|
if lookupErr != nil {
|
||||||
|
return nil, fmt.Errorf("locating %s: %q: %w; %q: %w", what, withDocker, err, name, lookupErr)
|
||||||
|
}
|
||||||
|
ref, err = image.storageReference, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ref, err
|
||||||
|
}
|
||||||
|
|
||||||
// Add adds one or more manifests to the manifest list and returns the digest
|
// Add adds one or more manifests to the manifest list and returns the digest
|
||||||
// of the added instance.
|
// of the added instance.
|
||||||
func (m *ManifestList) Add(ctx context.Context, name string, options *ManifestListAddOptions) (digest.Digest, error) {
|
func (m *ManifestList) Add(ctx context.Context, name string, options *ManifestListAddOptions) (digest.Digest, error) {
|
||||||
|
@ -321,14 +344,10 @@ func (m *ManifestList) Add(ctx context.Context, name string, options *ManifestLi
|
||||||
options = &ManifestListAddOptions{}
|
options = &ManifestListAddOptions{}
|
||||||
}
|
}
|
||||||
|
|
||||||
ref, err := alltransports.ParseImageName(name)
|
ref, err := m.parseNameToExtantReference(ctx, name, false, "image to add to manifest list")
|
||||||
if err != nil {
|
|
||||||
withDocker := fmt.Sprintf("%s://%s", docker.Transport.Name(), name)
|
|
||||||
ref, err = alltransports.ParseImageName(withDocker)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Now massage in the copy-related options into the system context.
|
// Now massage in the copy-related options into the system context.
|
||||||
systemContext := m.image.runtime.systemContextCopy()
|
systemContext := m.image.runtime.systemContextCopy()
|
||||||
|
@ -428,17 +447,9 @@ func (m *ManifestList) AddArtifact(ctx context.Context, options *ManifestListAdd
|
||||||
opts.LayerMediaType = &options.LayerType
|
opts.LayerMediaType = &options.LayerType
|
||||||
}
|
}
|
||||||
if options.Subject != "" {
|
if options.Subject != "" {
|
||||||
ref, err := alltransports.ParseImageName(options.Subject)
|
ref, err := m.parseNameToExtantReference(ctx, options.Subject, true, "subject for artifact manifest")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
withDocker := fmt.Sprintf("%s://%s", docker.Transport.Name(), options.Subject)
|
return "", err
|
||||||
ref, err = alltransports.ParseImageName(withDocker)
|
|
||||||
if err != nil {
|
|
||||||
image, _, err := m.image.runtime.LookupImage(options.Subject, &LookupImageOptions{ManifestList: true})
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("locating subject for artifact manifest: %w", err)
|
|
||||||
}
|
|
||||||
ref = image.storageReference
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
opts.SubjectReference = ref
|
opts.SubjectReference = ref
|
||||||
}
|
}
|
||||||
|
@ -541,17 +552,9 @@ func (m *ManifestList) AnnotateInstance(d digest.Digest, options *ManifestListAn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if options.Subject != "" {
|
if options.Subject != "" {
|
||||||
ref, err := alltransports.ParseImageName(options.Subject)
|
ref, err := m.parseNameToExtantReference(ctx, options.Subject, true, "subject for image index")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
withDocker := fmt.Sprintf("%s://%s", docker.Transport.Name(), options.Subject)
|
return err
|
||||||
ref, err = alltransports.ParseImageName(withDocker)
|
|
||||||
if err != nil {
|
|
||||||
image, _, err := m.image.runtime.LookupImage(options.Subject, &LookupImageOptions{ManifestList: true})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("locating subject for image index: %w", err)
|
|
||||||
}
|
|
||||||
ref = image.storageReference
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
src, err := ref.NewImageSource(ctx, &m.image.runtime.systemContext)
|
src, err := ref.NewImageSource(ctx, &m.image.runtime.systemContext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -495,6 +495,14 @@ func prepareAddWithCompression(variants []string) ([]cp.OptionCompressionVariant
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mapToSlice(m map[string]string) []string {
|
||||||
|
slice := make([]string, 0, len(m))
|
||||||
|
for key, value := range m {
|
||||||
|
slice = append(slice, key+"="+value)
|
||||||
|
}
|
||||||
|
return slice
|
||||||
|
}
|
||||||
|
|
||||||
// Add adds information about the specified image to the list, computing the
|
// Add adds information about the specified image to the list, computing the
|
||||||
// image's manifest's digest, retrieving OS and architecture information from
|
// image's manifest's digest, retrieving OS and architecture information from
|
||||||
// the image's configuration, and recording the image's reference so that it
|
// the image's configuration, and recording the image's reference so that it
|
||||||
|
@ -516,6 +524,7 @@ func (l *list) Add(ctx context.Context, sys *types.SystemContext, ref types.Imag
|
||||||
Size int64
|
Size int64
|
||||||
ConfigInfo types.BlobInfo
|
ConfigInfo types.BlobInfo
|
||||||
ArtifactType string
|
ArtifactType string
|
||||||
|
URLs []string
|
||||||
}
|
}
|
||||||
var instanceInfos []instanceInfo
|
var instanceInfos []instanceInfo
|
||||||
var manifestDigest digest.Digest
|
var manifestDigest digest.Digest
|
||||||
|
@ -547,6 +556,8 @@ func (l *list) Add(ctx context.Context, sys *types.SystemContext, ref types.Imag
|
||||||
OSFeatures: append([]string{}, platform.OSFeatures...),
|
OSFeatures: append([]string{}, platform.OSFeatures...),
|
||||||
Size: instance.Size,
|
Size: instance.Size,
|
||||||
ArtifactType: instance.ArtifactType,
|
ArtifactType: instance.ArtifactType,
|
||||||
|
Annotations: mapToSlice(instance.Annotations),
|
||||||
|
URLs: instance.URLs,
|
||||||
}
|
}
|
||||||
instanceInfos = append(instanceInfos, instanceInfo)
|
instanceInfos = append(instanceInfos, instanceInfo)
|
||||||
}
|
}
|
||||||
|
@ -578,6 +589,8 @@ func (l *list) Add(ctx context.Context, sys *types.SystemContext, ref types.Imag
|
||||||
OSFeatures: append([]string{}, platform.OSFeatures...),
|
OSFeatures: append([]string{}, platform.OSFeatures...),
|
||||||
Size: instance.Size,
|
Size: instance.Size,
|
||||||
ArtifactType: instance.ArtifactType,
|
ArtifactType: instance.ArtifactType,
|
||||||
|
Annotations: mapToSlice(instance.Annotations),
|
||||||
|
URLs: instance.URLs,
|
||||||
}
|
}
|
||||||
instanceInfos = append(instanceInfos, instanceInfo)
|
instanceInfos = append(instanceInfos, instanceInfo)
|
||||||
added = true
|
added = true
|
||||||
|
@ -649,6 +662,9 @@ func (l *list) Add(ctx context.Context, sys *types.SystemContext, ref types.Imag
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("adding instance with digest %q: %w", *instanceInfo.instanceDigest, err)
|
return "", fmt.Errorf("adding instance with digest %q: %w", *instanceInfo.instanceDigest, err)
|
||||||
}
|
}
|
||||||
|
if err = l.List.SetURLs(*instanceInfo.instanceDigest, instanceInfo.URLs); err != nil {
|
||||||
|
return "", fmt.Errorf("setting URLs for instance with digest %q: %w", *instanceInfo.instanceDigest, err)
|
||||||
|
}
|
||||||
if _, ok := l.instances[*instanceInfo.instanceDigest]; !ok {
|
if _, ok := l.instances[*instanceInfo.instanceDigest]; !ok {
|
||||||
l.instances[*instanceInfo.instanceDigest] = transports.ImageName(ref)
|
l.instances[*instanceInfo.instanceDigest] = transports.ImageName(ref)
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,6 +240,15 @@ func (r *Runtime) copyFromDefault(ctx context.Context, ref types.ImageReference,
|
||||||
// Figure out a name for the storage destination.
|
// Figure out a name for the storage destination.
|
||||||
var storageName, imageName string
|
var storageName, imageName string
|
||||||
switch ref.Transport().Name() {
|
switch ref.Transport().Name() {
|
||||||
|
case registryTransport.Transport.Name():
|
||||||
|
// Normalize to docker.io if needed (see containers/podman/issues/10998).
|
||||||
|
named, err := reference.ParseNormalizedNamed(strings.TrimLeft(ref.StringWithinTransport(), ":/"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
imageName = named.String()
|
||||||
|
storageName = imageName
|
||||||
|
|
||||||
case dockerDaemonTransport.Transport.Name():
|
case dockerDaemonTransport.Transport.Name():
|
||||||
// Normalize to docker.io if needed (see containers/podman/issues/10998).
|
// Normalize to docker.io if needed (see containers/podman/issues/10998).
|
||||||
named, err := reference.ParseNormalizedNamed(ref.StringWithinTransport())
|
named, err := reference.ParseNormalizedNamed(ref.StringWithinTransport())
|
||||||
|
|
79
vendor/github.com/containers/common/libnetwork/internal/rootlessnetns/netns_linux.go
generated
vendored
79
vendor/github.com/containers/common/libnetwork/internal/rootlessnetns/netns_linux.go
generated
vendored
|
@ -100,19 +100,38 @@ func (n *Netns) getOrCreateNetns() (ns.NetNS, bool, error) {
|
||||||
nsPath := n.getPath(rootlessNetnsDir)
|
nsPath := n.getPath(rootlessNetnsDir)
|
||||||
nsRef, err := ns.GetNS(nsPath)
|
nsRef, err := ns.GetNS(nsPath)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// TODO check if slirp4netns is alive
|
pidPath := n.getPath(rootlessNetNsConnPidFile)
|
||||||
|
pid, err := readPidFile(pidPath)
|
||||||
|
if err == nil {
|
||||||
|
// quick check if pasta/slirp4netns are still running
|
||||||
|
err := unix.Kill(pid, 0)
|
||||||
|
if err == nil {
|
||||||
|
// All good, return the netns.
|
||||||
return nsRef, false, nil
|
return nsRef, false, nil
|
||||||
}
|
}
|
||||||
|
// Print warnings in case things went wrong, we might be able to recover
|
||||||
|
// but maybe not so make sure to leave some hints so we can figure out what went wrong.
|
||||||
|
if errors.Is(err, unix.ESRCH) {
|
||||||
|
logrus.Warn("rootless netns program no longer running, trying to start it again")
|
||||||
|
} else {
|
||||||
|
logrus.Warnf("failed to check if rootless netns program is running: %v, trying to start it again", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logrus.Warnf("failed to read rootless netns program pid: %v", err)
|
||||||
|
}
|
||||||
|
// In case of errors continue and setup the network cmd again.
|
||||||
|
} else {
|
||||||
logrus.Debugf("Creating rootless network namespace at %q", nsPath)
|
logrus.Debugf("Creating rootless network namespace at %q", nsPath)
|
||||||
// We have to create the netns dir again here because it is possible
|
// We have to create the netns dir again here because it is possible
|
||||||
// that cleanup() removed it.
|
// that cleanup() removed it.
|
||||||
if err := os.MkdirAll(n.dir, 0o700); err != nil {
|
if err := os.MkdirAll(n.dir, 0o700); err != nil {
|
||||||
return nil, false, wrapError("", err)
|
return nil, false, wrapError("", err)
|
||||||
}
|
}
|
||||||
netns, err := netns.NewNSAtPath(nsPath)
|
nsRef, err = netns.NewNSAtPath(nsPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, wrapError("create netns", err)
|
return nil, false, wrapError("create netns", err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
switch strings.ToLower(n.config.Network.DefaultRootlessNetworkCmd) {
|
switch strings.ToLower(n.config.Network.DefaultRootlessNetworkCmd) {
|
||||||
case "", slirp4netns.BinaryName:
|
case "", slirp4netns.BinaryName:
|
||||||
err = n.setupSlirp4netns(nsPath)
|
err = n.setupSlirp4netns(nsPath)
|
||||||
|
@ -121,7 +140,17 @@ func (n *Netns) getOrCreateNetns() (ns.NetNS, bool, error) {
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("invalid rootless network command %q", n.config.Network.DefaultRootlessNetworkCmd)
|
err = fmt.Errorf("invalid rootless network command %q", n.config.Network.DefaultRootlessNetworkCmd)
|
||||||
}
|
}
|
||||||
return netns, true, err
|
// If pasta or slirp4netns fail here we need to get rid of the netns again to not leak it,
|
||||||
|
// otherwise the next command thinks the netns was successfully setup.
|
||||||
|
if err != nil {
|
||||||
|
if nerr := netns.UnmountNS(nsPath); nerr != nil {
|
||||||
|
logrus.Error(nerr)
|
||||||
|
}
|
||||||
|
_ = nsRef.Close()
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nsRef, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Netns) cleanup() error {
|
func (n *Netns) cleanup() error {
|
||||||
|
@ -165,11 +194,7 @@ func (n *Netns) setupPasta(nsPath string) error {
|
||||||
|
|
||||||
if systemd.RunsOnSystemd() {
|
if systemd.RunsOnSystemd() {
|
||||||
// Treat these as fatal - if pasta failed to write a PID file something is probably wrong.
|
// Treat these as fatal - if pasta failed to write a PID file something is probably wrong.
|
||||||
pidfile, err := os.ReadFile(pidPath)
|
pid, err := readPidFile(pidPath)
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to open pasta PID file: %w", err)
|
|
||||||
}
|
|
||||||
pid, err := strconv.Atoi(strings.TrimSpace(string(pidfile)))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to decode pasta PID: %w", err)
|
return fmt.Errorf("unable to decode pasta PID: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -245,18 +270,14 @@ func (n *Netns) setupSlirp4netns(nsPath string) error {
|
||||||
|
|
||||||
func (n *Netns) cleanupRootlessNetns() error {
|
func (n *Netns) cleanupRootlessNetns() error {
|
||||||
pidFile := n.getPath(rootlessNetNsConnPidFile)
|
pidFile := n.getPath(rootlessNetNsConnPidFile)
|
||||||
b, err := os.ReadFile(pidFile)
|
pid, err := readPidFile(pidFile)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var i int
|
// kill the slirp/pasta process so we do not leak it
|
||||||
i, err = strconv.Atoi(strings.TrimSpace(string(b)))
|
err = unix.Kill(pid, unix.SIGTERM)
|
||||||
if err == nil {
|
|
||||||
// kill the slirp process so we do not leak it
|
|
||||||
err = unix.Kill(i, unix.SIGTERM)
|
|
||||||
if err == unix.ESRCH {
|
if err == unix.ESRCH {
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,6 +315,13 @@ func (n *Netns) setupMounts() error {
|
||||||
return wrapError("create new mount namespace", err)
|
return wrapError("create new mount namespace", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure we mount private in our mountns to prevent accidentally
|
||||||
|
// overwriting the host mounts in case the default propagation is shared.
|
||||||
|
err = unix.Mount("", "/", "", unix.MS_PRIVATE|unix.MS_REC, "")
|
||||||
|
if err != nil {
|
||||||
|
return wrapError("make tree private in new mount namespace", err)
|
||||||
|
}
|
||||||
|
|
||||||
xdgRuntimeDir, err := homedir.GetRuntimeDir()
|
xdgRuntimeDir, err := homedir.GetRuntimeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not get runtime directory: %w", err)
|
return fmt.Errorf("could not get runtime directory: %w", err)
|
||||||
|
@ -301,7 +329,7 @@ func (n *Netns) setupMounts() error {
|
||||||
newXDGRuntimeDir := n.getPath(xdgRuntimeDir)
|
newXDGRuntimeDir := n.getPath(xdgRuntimeDir)
|
||||||
// 1. Mount the netns into the new run to keep them accessible.
|
// 1. Mount the netns into the new run to keep them accessible.
|
||||||
// Otherwise cni setup will fail because it cannot access the netns files.
|
// Otherwise cni setup will fail because it cannot access the netns files.
|
||||||
err = mountAndMkdirDest(xdgRuntimeDir, newXDGRuntimeDir, none, unix.MS_BIND|unix.MS_SHARED|unix.MS_REC)
|
err = mountAndMkdirDest(xdgRuntimeDir, newXDGRuntimeDir, none, unix.MS_BIND|unix.MS_REC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -556,15 +584,12 @@ func (n *Netns) Run(lock *lockfile.LockFile, toRun func() error) error {
|
||||||
logrus.Errorf("Failed to decrement ref count: %v", err)
|
logrus.Errorf("Failed to decrement ref count: %v", err)
|
||||||
return inErr
|
return inErr
|
||||||
}
|
}
|
||||||
if count == 0 {
|
// runInner() already cleans up the netns when it created a new one on errors
|
||||||
|
// so we only need to do that if there was no error.
|
||||||
|
if inErr == nil && count == 0 {
|
||||||
err = n.cleanup()
|
err = n.cleanup()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = wrapError("cleanup", err)
|
return wrapError("cleanup", err)
|
||||||
if inErr == nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logrus.Errorf("Failed to cleanup rootless netns: %v", err)
|
|
||||||
return inErr
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,3 +624,11 @@ func refCount(dir string, inc int) (int, error) {
|
||||||
|
|
||||||
return currentCount, nil
|
return currentCount, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readPidFile(path string) (int, error) {
|
||||||
|
b, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return strconv.Atoi(strings.TrimSpace(string(b)))
|
||||||
|
}
|
||||||
|
|
|
@ -135,7 +135,11 @@ func NewNetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var netns *rootlessnetns.Netns
|
var netns *rootlessnetns.Netns
|
||||||
if unshare.IsRootless() {
|
// Do not use unshare.IsRootless() here. We only care if we are running re-exec in the userns,
|
||||||
|
// IsRootless() also returns true if we are root in a userns which is not what we care about and
|
||||||
|
// causes issues as this slower more complicated rootless-netns logic should not be used as root.
|
||||||
|
_, useRootlessNetns := os.LookupEnv(unshare.UsernsEnvName)
|
||||||
|
if useRootlessNetns {
|
||||||
netns, err = rootlessnetns.New(conf.NetworkRunDir, rootlessnetns.Netavark, conf.Config)
|
netns, err = rootlessnetns.New(conf.NetworkRunDir, rootlessnetns.Netavark, conf.Config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -147,7 +151,7 @@ func NewNetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) {
|
||||||
networkRunDir: conf.NetworkRunDir,
|
networkRunDir: conf.NetworkRunDir,
|
||||||
netavarkBinary: conf.NetavarkBinary,
|
netavarkBinary: conf.NetavarkBinary,
|
||||||
aardvarkBinary: conf.AardvarkBinary,
|
aardvarkBinary: conf.AardvarkBinary,
|
||||||
networkRootless: unshare.IsRootless(),
|
networkRootless: useRootlessNetns,
|
||||||
ipamDBPath: filepath.Join(conf.NetworkRunDir, "ipam.db"),
|
ipamDBPath: filepath.Join(conf.NetworkRunDir, "ipam.db"),
|
||||||
firewallDriver: conf.Config.Network.FirewallDriver,
|
firewallDriver: conf.Config.Network.FirewallDriver,
|
||||||
defaultNetwork: defaultNetworkName,
|
defaultNetwork: defaultNetworkName,
|
||||||
|
|
|
@ -328,6 +328,11 @@ type EngineConfig struct {
|
||||||
// this slice takes precedence.
|
// this slice takes precedence.
|
||||||
HooksDir attributedstring.Slice `toml:"hooks_dir,omitempty"`
|
HooksDir attributedstring.Slice `toml:"hooks_dir,omitempty"`
|
||||||
|
|
||||||
|
// Location of CDI configuration files. These define mounts devices and
|
||||||
|
// other configs according to the CDI spec. In particular this is used
|
||||||
|
// for GPU passthrough.
|
||||||
|
CdiSpecDirs attributedstring.Slice `toml:"cdi_spec_dirs,omitempty"`
|
||||||
|
|
||||||
// ImageBuildFormat (DEPRECATED) indicates the default image format to
|
// ImageBuildFormat (DEPRECATED) indicates the default image format to
|
||||||
// building container images. Should use ImageDefaultFormat
|
// building container images. Should use ImageDefaultFormat
|
||||||
ImageBuildFormat string `toml:"image_build_format,omitempty"`
|
ImageBuildFormat string `toml:"image_build_format,omitempty"`
|
||||||
|
@ -772,7 +777,7 @@ func (m *MachineConfig) URI() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *EngineConfig) findRuntime() string {
|
func (c *EngineConfig) findRuntime() string {
|
||||||
// Search for crun first followed by runc, kata, runsc
|
// Search for crun first followed by runc, runj, kata, runsc, ocijail
|
||||||
for _, name := range []string{"crun", "runc", "runj", "kata", "runsc", "ocijail"} {
|
for _, name := range []string{"crun", "runc", "runj", "kata", "runsc", "ocijail"} {
|
||||||
for _, v := range c.OCIRuntimes[name] {
|
for _, v := range c.OCIRuntimes[name] {
|
||||||
if _, err := os.Stat(v); err == nil {
|
if _, err := os.Stat(v); err == nil {
|
||||||
|
|
|
@ -544,6 +544,12 @@ default_sysctls = [
|
||||||
# "/usr/share/containers/oci/hooks.d",
|
# "/usr/share/containers/oci/hooks.d",
|
||||||
#]
|
#]
|
||||||
|
|
||||||
|
# Directories to scan for CDI Spec files.
|
||||||
|
#
|
||||||
|
#cdi_spec_dirs = [
|
||||||
|
# "/etc/cdi",
|
||||||
|
#]
|
||||||
|
|
||||||
# Manifest Type (oci, v2s2, or v2s1) to use when pulling, pushing, building
|
# Manifest Type (oci, v2s2, or v2s1) to use when pulling, pushing, building
|
||||||
# container images. By default image pulled and pushed match the format of the
|
# container images. By default image pulled and pushed match the format of the
|
||||||
# source image. Building/committing defaults to OCI.
|
# source image. Building/committing defaults to OCI.
|
||||||
|
|
|
@ -414,6 +414,12 @@ default_sysctls = [
|
||||||
# "/usr/local/share/containers/oci/hooks.d",
|
# "/usr/local/share/containers/oci/hooks.d",
|
||||||
#]
|
#]
|
||||||
|
|
||||||
|
# Directories to scan for CDI Spec files.
|
||||||
|
#
|
||||||
|
#cdi_spec_dirs = [
|
||||||
|
# "/etc/cdi",
|
||||||
|
#]
|
||||||
|
|
||||||
# Manifest Type (oci, v2s2, or v2s1) to use when pulling, pushing, building
|
# Manifest Type (oci, v2s2, or v2s1) to use when pulling, pushing, building
|
||||||
# container images. By default image pulled and pushed match the format of the
|
# container images. By default image pulled and pushed match the format of the
|
||||||
# source image. Building/committing defaults to OCI.
|
# source image. Building/committing defaults to OCI.
|
||||||
|
|
|
@ -74,6 +74,8 @@ var (
|
||||||
ErrInvalidArg = errors.New("invalid argument")
|
ErrInvalidArg = errors.New("invalid argument")
|
||||||
// DefaultHooksDirs defines the default hooks directory.
|
// DefaultHooksDirs defines the default hooks directory.
|
||||||
DefaultHooksDirs = []string{"/usr/share/containers/oci/hooks.d"}
|
DefaultHooksDirs = []string{"/usr/share/containers/oci/hooks.d"}
|
||||||
|
// DefaultCdiSpecDirs defines the default cdi spec directories.
|
||||||
|
DefaultCdiSpecDirs = []string{"/etc/cdi"}
|
||||||
// DefaultCapabilities is the default for the default_capabilities option in the containers.conf file.
|
// DefaultCapabilities is the default for the default_capabilities option in the containers.conf file.
|
||||||
DefaultCapabilities = []string{
|
DefaultCapabilities = []string{
|
||||||
"CAP_CHOWN",
|
"CAP_CHOWN",
|
||||||
|
@ -347,6 +349,7 @@ func defaultEngineConfig() (*EngineConfig, error) {
|
||||||
c.HelperBinariesDir.Set(append([]string{additionalHelperBinariesDir}, c.HelperBinariesDir.Get()...))
|
c.HelperBinariesDir.Set(append([]string{additionalHelperBinariesDir}, c.HelperBinariesDir.Get()...))
|
||||||
}
|
}
|
||||||
c.HooksDir.Set(DefaultHooksDirs)
|
c.HooksDir.Set(DefaultHooksDirs)
|
||||||
|
c.CdiSpecDirs.Set(DefaultCdiSpecDirs)
|
||||||
c.ImageDefaultTransport = _defaultTransport
|
c.ImageDefaultTransport = _defaultTransport
|
||||||
c.ImageVolumeMode = _defaultImageVolumeMode
|
c.ImageVolumeMode = _defaultImageVolumeMode
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PullPolicy determines how and which images are being pulled from a container
|
// PullPolicy determines how and which images are being pulled from a container
|
||||||
|
@ -73,14 +74,14 @@ func (p PullPolicy) Validate() error {
|
||||||
// * "newer" <-> PullPolicyNewer (also "ifnewer")
|
// * "newer" <-> PullPolicyNewer (also "ifnewer")
|
||||||
// * "never" <-> PullPolicyNever
|
// * "never" <-> PullPolicyNever
|
||||||
func ParsePullPolicy(s string) (PullPolicy, error) {
|
func ParsePullPolicy(s string) (PullPolicy, error) {
|
||||||
switch s {
|
switch strings.ToLower(s) {
|
||||||
case "always", "Always":
|
case "always":
|
||||||
return PullPolicyAlways, nil
|
return PullPolicyAlways, nil
|
||||||
case "missing", "Missing", "ifnotpresent", "IfNotPresent", "":
|
case "missing", "ifmissing", "ifnotpresent", "":
|
||||||
return PullPolicyMissing, nil
|
return PullPolicyMissing, nil
|
||||||
case "newer", "Newer", "ifnewer", "IfNewer":
|
case "newer", "ifnewer":
|
||||||
return PullPolicyNewer, nil
|
return PullPolicyNewer, nil
|
||||||
case "never", "Never":
|
case "never":
|
||||||
return PullPolicyNever, nil
|
return PullPolicyNever, nil
|
||||||
default:
|
default:
|
||||||
return PullPolicyUnsupported, fmt.Errorf("unsupported pull policy %q", s)
|
return PullPolicyUnsupported, fmt.Errorf("unsupported pull policy %q", s)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/common/internal"
|
"github.com/containers/common/internal"
|
||||||
"github.com/containers/image/v5/manifest"
|
"github.com/containers/image/v5/manifest"
|
||||||
|
@ -80,10 +81,18 @@ func Create() List {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sliceToMap(s []string) map[string]string {
|
||||||
|
m := make(map[string]string, len(s))
|
||||||
|
for _, spec := range s {
|
||||||
|
key, value, _ := strings.Cut(spec, "=")
|
||||||
|
m[key] = value
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
// AddInstance adds an entry for the specified manifest digest, with assorted
|
// AddInstance adds an entry for the specified manifest digest, with assorted
|
||||||
// additional information specified in parameters, to the list or index.
|
// additional information specified in parameters, to the list or index.
|
||||||
func (l *list) AddInstance(manifestDigest digest.Digest, manifestSize int64, manifestType, osName, architecture, osVersion string, osFeatures []string, variant string, features, annotations []string) error { // nolint:revive
|
func (l *list) AddInstance(manifestDigest digest.Digest, manifestSize int64, manifestType, osName, architecture, osVersion string, osFeatures []string, variant string, features, annotations []string) error { // nolint:revive
|
||||||
// FIXME: the annotations argument is currently ignored
|
|
||||||
if err := l.Remove(manifestDigest); err != nil && !errors.Is(err, os.ErrNotExist) {
|
if err := l.Remove(manifestDigest); err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -120,6 +129,7 @@ func (l *list) AddInstance(manifestDigest digest.Digest, manifestSize int64, man
|
||||||
Size: manifestSize,
|
Size: manifestSize,
|
||||||
Digest: manifestDigest,
|
Digest: manifestDigest,
|
||||||
Platform: ociv1platform,
|
Platform: ociv1platform,
|
||||||
|
Annotations: sliceToMap(annotations),
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -15,21 +15,35 @@ const (
|
||||||
// Note: This function is copied from containers/podman libpod/util.go
|
// Note: This function is copied from containers/podman libpod/util.go
|
||||||
// Please see https://github.com/containers/common/pull/1460
|
// Please see https://github.com/containers/common/pull/1460
|
||||||
func queryPackageVersion(cmdArg ...string) string {
|
func queryPackageVersion(cmdArg ...string) string {
|
||||||
|
_, err := os.Stat(cmdArg[0])
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
output := UnknownPackage
|
output := UnknownPackage
|
||||||
if 1 < len(cmdArg) {
|
if 1 < len(cmdArg) {
|
||||||
cmd := exec.Command(cmdArg[0], cmdArg[1:]...)
|
cmd := exec.Command(cmdArg[0], cmdArg[1:]...)
|
||||||
if outp, err := cmd.Output(); err == nil {
|
if outp, err := cmd.Output(); err == nil {
|
||||||
output = string(outp)
|
output = string(outp)
|
||||||
deb := false
|
|
||||||
if cmdArg[0] == "/usr/bin/dlocate" {
|
if cmdArg[0] == "/usr/bin/dlocate" {
|
||||||
// can return multiple matches
|
// can return multiple matches
|
||||||
l := strings.Split(output, "\n")
|
l := strings.Split(output, "\n")
|
||||||
output = l[0]
|
output = l[0]
|
||||||
deb = true
|
r := strings.Split(output, ": ")
|
||||||
} else if cmdArg[0] == "/usr/bin/dpkg" {
|
regexpFormat := `^..\s` + r[0] + `\s`
|
||||||
deb = true
|
cmd = exec.Command(cmdArg[0], "-P", regexpFormat, "-l")
|
||||||
|
cmd.Env = []string{"COLUMNS=160"} // show entire value
|
||||||
|
// dlocate always returns exit code 1 for list command
|
||||||
|
if outp, _ = cmd.Output(); len(outp) > 0 {
|
||||||
|
lines := strings.Split(string(outp), "\n")
|
||||||
|
if len(lines) > 1 {
|
||||||
|
line := lines[len(lines)-2] // trailing newline
|
||||||
|
f := strings.Fields(line)
|
||||||
|
if len(f) >= 2 {
|
||||||
|
return f[1] + "_" + f[2]
|
||||||
}
|
}
|
||||||
if deb {
|
}
|
||||||
|
}
|
||||||
|
} else if cmdArg[0] == "/usr/bin/dpkg" {
|
||||||
r := strings.Split(output, ": ")
|
r := strings.Split(output, ": ")
|
||||||
queryFormat := `${Package}_${Version}_${Architecture}`
|
queryFormat := `${Package}_${Version}_${Architecture}`
|
||||||
cmd = exec.Command("/usr/bin/dpkg-query", "-f", queryFormat, "-W", r[0])
|
cmd = exec.Command("/usr/bin/dpkg-query", "-f", queryFormat, "-W", r[0])
|
||||||
|
@ -53,22 +67,36 @@ func Package(program string) string { // program is full path
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return UnknownPackage
|
return UnknownPackage
|
||||||
}
|
}
|
||||||
packagers := [][]string{
|
|
||||||
{"/usr/bin/rpm", "-q", "-f"},
|
type Packager struct {
|
||||||
{"/usr/bin/dlocate", "-F"}, // Debian, Ubuntu (quick)
|
Format string
|
||||||
{"/usr/bin/dpkg", "-S"}, // Debian, Ubuntu (slow)
|
Command []string
|
||||||
{"/usr/bin/pacman", "-Qo"}, // Arch
|
}
|
||||||
{"/usr/bin/qfile", "-qv"}, // Gentoo (quick)
|
packagers := []Packager{
|
||||||
{"/usr/bin/equery", "b"}, // Gentoo (slow)
|
{"rpm", []string{"/usr/bin/rpm", "-q", "-f"}},
|
||||||
{"/sbin/apk", "info", "-W"}, // Alpine
|
{"deb", []string{"/usr/bin/dlocate", "-F"}}, // Debian, Ubuntu (quick)
|
||||||
{"/usr/local/sbin/pkg", "which", "-q"}, // FreeBSD
|
{"deb", []string{"/usr/bin/dpkg", "-S"}}, // Debian, Ubuntu (slow)
|
||||||
|
{"pacman", []string{"/usr/bin/pacman", "-Qo"}}, // Arch
|
||||||
|
{"gentoo", []string{"/usr/bin/qfile", "-qv"}}, // Gentoo (quick)
|
||||||
|
{"gentoo", []string{"/usr/bin/equery", "b"}}, // Gentoo (slow)
|
||||||
|
{"apk", []string{"/sbin/apk", "info", "-W"}}, // Alpine
|
||||||
|
{"pkg", []string{"/usr/local/sbin/pkg", "which", "-q"}}, // FreeBSD
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, cmd := range packagers {
|
lastformat := ""
|
||||||
|
for _, packager := range packagers {
|
||||||
|
if packager.Format == lastformat {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cmd := packager.Command
|
||||||
cmd = append(cmd, program)
|
cmd = append(cmd, program)
|
||||||
if out := queryPackageVersion(cmd...); out != UnknownPackage {
|
if out := queryPackageVersion(cmd...); out != UnknownPackage {
|
||||||
|
if out == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
lastformat = packager.Format
|
||||||
}
|
}
|
||||||
return UnknownPackage
|
return UnknownPackage
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
## 2.17.1
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- If the user sets --seed=0, make sure all parallel nodes get the same seed [af0330d]
|
||||||
|
|
||||||
## 2.17.0
|
## 2.17.0
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
|
@ -265,7 +265,7 @@ var FlagSections = GinkgoFlagSections{
|
||||||
// SuiteConfigFlags provides flags for the Ginkgo test process, and CLI
|
// SuiteConfigFlags provides flags for the Ginkgo test process, and CLI
|
||||||
var SuiteConfigFlags = GinkgoFlags{
|
var SuiteConfigFlags = GinkgoFlags{
|
||||||
{KeyPath: "S.RandomSeed", Name: "seed", SectionKey: "order", UsageDefaultValue: "randomly generated by Ginkgo",
|
{KeyPath: "S.RandomSeed", Name: "seed", SectionKey: "order", UsageDefaultValue: "randomly generated by Ginkgo",
|
||||||
Usage: "The seed used to randomize the spec suite."},
|
Usage: "The seed used to randomize the spec suite.", AlwaysExport: true},
|
||||||
{KeyPath: "S.RandomizeAllSpecs", Name: "randomize-all", SectionKey: "order", DeprecatedName: "randomizeAllSpecs", DeprecatedDocLink: "changed-command-line-flags",
|
{KeyPath: "S.RandomizeAllSpecs", Name: "randomize-all", SectionKey: "order", DeprecatedName: "randomizeAllSpecs", DeprecatedDocLink: "changed-command-line-flags",
|
||||||
Usage: "If set, ginkgo will randomize all specs together. By default, ginkgo only randomizes the top level Describe, Context and When containers."},
|
Usage: "If set, ginkgo will randomize all specs together. By default, ginkgo only randomizes the top level Describe, Context and When containers."},
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ type GinkgoFlag struct {
|
||||||
DeprecatedVersion string
|
DeprecatedVersion string
|
||||||
|
|
||||||
ExportAs string
|
ExportAs string
|
||||||
|
AlwaysExport bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type GinkgoFlags []GinkgoFlag
|
type GinkgoFlags []GinkgoFlag
|
||||||
|
@ -431,7 +432,7 @@ func (ssv stringSliceVar) Set(s string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//given a set of GinkgoFlags and bindings, generate flag arguments suitable to be passed to an application with that set of flags configured.
|
// 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 interface{}) ([]string, error) {
|
||||||
result := []string{}
|
result := []string{}
|
||||||
for _, flag := range flags {
|
for _, flag := range flags {
|
||||||
|
@ -451,19 +452,19 @@ func GenerateFlagArgs(flags GinkgoFlags, bindings interface{}) ([]string, error)
|
||||||
iface := value.Interface()
|
iface := value.Interface()
|
||||||
switch value.Type() {
|
switch value.Type() {
|
||||||
case reflect.TypeOf(string("")):
|
case reflect.TypeOf(string("")):
|
||||||
if iface.(string) != "" {
|
if iface.(string) != "" || flag.AlwaysExport {
|
||||||
result = append(result, fmt.Sprintf("--%s=%s", name, iface))
|
result = append(result, fmt.Sprintf("--%s=%s", name, iface))
|
||||||
}
|
}
|
||||||
case reflect.TypeOf(int64(0)):
|
case reflect.TypeOf(int64(0)):
|
||||||
if iface.(int64) != 0 {
|
if iface.(int64) != 0 || flag.AlwaysExport {
|
||||||
result = append(result, fmt.Sprintf("--%s=%d", name, iface))
|
result = append(result, fmt.Sprintf("--%s=%d", name, iface))
|
||||||
}
|
}
|
||||||
case reflect.TypeOf(float64(0)):
|
case reflect.TypeOf(float64(0)):
|
||||||
if iface.(float64) != 0 {
|
if iface.(float64) != 0 || flag.AlwaysExport {
|
||||||
result = append(result, fmt.Sprintf("--%s=%f", name, iface))
|
result = append(result, fmt.Sprintf("--%s=%f", name, iface))
|
||||||
}
|
}
|
||||||
case reflect.TypeOf(int(0)):
|
case reflect.TypeOf(int(0)):
|
||||||
if iface.(int) != 0 {
|
if iface.(int) != 0 || flag.AlwaysExport {
|
||||||
result = append(result, fmt.Sprintf("--%s=%d", name, iface))
|
result = append(result, fmt.Sprintf("--%s=%d", name, iface))
|
||||||
}
|
}
|
||||||
case reflect.TypeOf(bool(true)):
|
case reflect.TypeOf(bool(true)):
|
||||||
|
@ -471,7 +472,7 @@ func GenerateFlagArgs(flags GinkgoFlags, bindings interface{}) ([]string, error)
|
||||||
result = append(result, fmt.Sprintf("--%s", name))
|
result = append(result, fmt.Sprintf("--%s", name))
|
||||||
}
|
}
|
||||||
case reflect.TypeOf(time.Duration(0)):
|
case reflect.TypeOf(time.Duration(0)):
|
||||||
if iface.(time.Duration) != time.Duration(0) {
|
if iface.(time.Duration) != time.Duration(0) || flag.AlwaysExport {
|
||||||
result = append(result, fmt.Sprintf("--%s=%s", name, iface))
|
result = append(result, fmt.Sprintf("--%s=%s", name, iface))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
package types
|
package types
|
||||||
|
|
||||||
const VERSION = "2.17.0"
|
const VERSION = "2.17.1"
|
||||||
|
|
|
@ -47,7 +47,7 @@ import (
|
||||||
func Find(importPath, srcDir string) (filename, path string) {
|
func Find(importPath, srcDir string) (filename, path string) {
|
||||||
cmd := exec.Command("go", "list", "-json", "-export", "--", importPath)
|
cmd := exec.Command("go", "list", "-json", "-export", "--", importPath)
|
||||||
cmd.Dir = srcDir
|
cmd.Dir = srcDir
|
||||||
out, err := cmd.CombinedOutput()
|
out, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", ""
|
return "", ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,13 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/tools/internal/aliases"
|
||||||
"golang.org/x/tools/internal/typeparams"
|
"golang.org/x/tools/internal/typeparams"
|
||||||
|
"golang.org/x/tools/internal/typesinternal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO(adonovan): think about generic aliases.
|
||||||
|
|
||||||
// A Path is an opaque name that identifies a types.Object
|
// A Path is an opaque name that identifies a types.Object
|
||||||
// relative to its package. Conceptually, the name consists of a
|
// relative to its package. Conceptually, the name consists of a
|
||||||
// sequence of destructuring operations applied to the package scope
|
// sequence of destructuring operations applied to the package scope
|
||||||
|
@ -223,7 +227,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
|
||||||
// Reject obviously non-viable cases.
|
// Reject obviously non-viable cases.
|
||||||
switch obj := obj.(type) {
|
switch obj := obj.(type) {
|
||||||
case *types.TypeName:
|
case *types.TypeName:
|
||||||
if _, ok := obj.Type().(*types.TypeParam); !ok {
|
if _, ok := aliases.Unalias(obj.Type()).(*types.TypeParam); !ok {
|
||||||
// With the exception of type parameters, only package-level type names
|
// With the exception of type parameters, only package-level type names
|
||||||
// have a path.
|
// have a path.
|
||||||
return "", fmt.Errorf("no path for %v", obj)
|
return "", fmt.Errorf("no path for %v", obj)
|
||||||
|
@ -310,7 +314,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inspect declared methods of defined types.
|
// Inspect declared methods of defined types.
|
||||||
if T, ok := o.Type().(*types.Named); ok {
|
if T, ok := aliases.Unalias(o.Type()).(*types.Named); ok {
|
||||||
path = append(path, opType)
|
path = append(path, opType)
|
||||||
// The method index here is always with respect
|
// The method index here is always with respect
|
||||||
// to the underlying go/types data structures,
|
// to the underlying go/types data structures,
|
||||||
|
@ -395,13 +399,8 @@ func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) {
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
recvT := meth.Type().(*types.Signature).Recv().Type()
|
_, named := typesinternal.ReceiverNamed(meth.Type().(*types.Signature).Recv())
|
||||||
if ptr, ok := recvT.(*types.Pointer); ok {
|
if named == nil {
|
||||||
recvT = ptr.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
named, ok := recvT.(*types.Named)
|
|
||||||
if !ok {
|
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,6 +443,8 @@ func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) {
|
||||||
// nil, it will be allocated as necessary.
|
// nil, it will be allocated as necessary.
|
||||||
func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]bool) []byte {
|
func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]bool) []byte {
|
||||||
switch T := T.(type) {
|
switch T := T.(type) {
|
||||||
|
case *aliases.Alias:
|
||||||
|
return find(obj, aliases.Unalias(T), path, seen)
|
||||||
case *types.Basic, *types.Named:
|
case *types.Basic, *types.Named:
|
||||||
// Named types belonging to pkg were handled already,
|
// Named types belonging to pkg were handled already,
|
||||||
// so T must belong to another package. No path.
|
// so T must belong to another package. No path.
|
||||||
|
@ -616,6 +617,7 @@ func Object(pkg *types.Package, p Path) (types.Object, error) {
|
||||||
|
|
||||||
// Inv: t != nil, obj == nil
|
// Inv: t != nil, obj == nil
|
||||||
|
|
||||||
|
t = aliases.Unalias(t)
|
||||||
switch code {
|
switch code {
|
||||||
case opElem:
|
case opElem:
|
||||||
hasElem, ok := t.(hasElem) // Pointer, Slice, Array, Chan, Map
|
hasElem, ok := t.(hasElem) // Pointer, Slice, Array, Chan, Map
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright 2024 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package aliases
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go/token"
|
||||||
|
"go/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Package aliases defines backward compatible shims
|
||||||
|
// for the types.Alias type representation added in 1.22.
|
||||||
|
// This defines placeholders for x/tools until 1.26.
|
||||||
|
|
||||||
|
// NewAlias creates a new TypeName in Package pkg that
|
||||||
|
// is an alias for the type rhs.
|
||||||
|
//
|
||||||
|
// When GoVersion>=1.22 and GODEBUG=gotypesalias=1,
|
||||||
|
// the Type() of the return value is a *types.Alias.
|
||||||
|
func NewAlias(pos token.Pos, pkg *types.Package, name string, rhs types.Type) *types.TypeName {
|
||||||
|
if enabled() {
|
||||||
|
tname := types.NewTypeName(pos, pkg, name, nil)
|
||||||
|
newAlias(tname, rhs)
|
||||||
|
return tname
|
||||||
|
}
|
||||||
|
return types.NewTypeName(pos, pkg, name, rhs)
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2024 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !go1.22
|
||||||
|
// +build !go1.22
|
||||||
|
|
||||||
|
package aliases
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Alias is a placeholder for a go/types.Alias for <=1.21.
|
||||||
|
// It will never be created by go/types.
|
||||||
|
type Alias struct{}
|
||||||
|
|
||||||
|
func (*Alias) String() string { panic("unreachable") }
|
||||||
|
|
||||||
|
func (*Alias) Underlying() types.Type { panic("unreachable") }
|
||||||
|
|
||||||
|
func (*Alias) Obj() *types.TypeName { panic("unreachable") }
|
||||||
|
|
||||||
|
// Unalias returns the type t for go <=1.21.
|
||||||
|
func Unalias(t types.Type) types.Type { return t }
|
||||||
|
|
||||||
|
// Always false for go <=1.21. Ignores GODEBUG.
|
||||||
|
func enabled() bool { return false }
|
||||||
|
|
||||||
|
func newAlias(name *types.TypeName, rhs types.Type) *Alias { panic("unreachable") }
|
|
@ -0,0 +1,72 @@
|
||||||
|
// Copyright 2024 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.22
|
||||||
|
// +build go1.22
|
||||||
|
|
||||||
|
package aliases
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go/ast"
|
||||||
|
"go/parser"
|
||||||
|
"go/token"
|
||||||
|
"go/types"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Alias is an alias of types.Alias.
|
||||||
|
type Alias = types.Alias
|
||||||
|
|
||||||
|
// Unalias is a wrapper of types.Unalias.
|
||||||
|
func Unalias(t types.Type) types.Type { return types.Unalias(t) }
|
||||||
|
|
||||||
|
// newAlias is an internal alias around types.NewAlias.
|
||||||
|
// Direct usage is discouraged as the moment.
|
||||||
|
// Try to use NewAlias instead.
|
||||||
|
func newAlias(tname *types.TypeName, rhs types.Type) *Alias {
|
||||||
|
a := types.NewAlias(tname, rhs)
|
||||||
|
// TODO(go.dev/issue/65455): Remove kludgy workaround to set a.actual as a side-effect.
|
||||||
|
Unalias(a)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// enabled returns true when types.Aliases are enabled.
|
||||||
|
func enabled() bool {
|
||||||
|
// Use the gotypesalias value in GODEBUG if set.
|
||||||
|
godebug := os.Getenv("GODEBUG")
|
||||||
|
value := -1 // last set value.
|
||||||
|
for _, f := range strings.Split(godebug, ",") {
|
||||||
|
switch f {
|
||||||
|
case "gotypesalias=1":
|
||||||
|
value = 1
|
||||||
|
case "gotypesalias=0":
|
||||||
|
value = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch value {
|
||||||
|
case 0:
|
||||||
|
return false
|
||||||
|
case 1:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return aliasesDefault()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// aliasesDefault reports if aliases are enabled by default.
|
||||||
|
func aliasesDefault() bool {
|
||||||
|
// Dynamically check if Aliases will be produced from go/types.
|
||||||
|
aliasesDefaultOnce.Do(func() {
|
||||||
|
fset := token.NewFileSet()
|
||||||
|
f, _ := parser.ParseFile(fset, "a.go", "package p; type A = int", 0)
|
||||||
|
pkg, _ := new(types.Config).Check("p", fset, []*ast.File{f}, nil)
|
||||||
|
_, gotypesaliasDefault = pkg.Scope().Lookup("A").Type().(*types.Alias)
|
||||||
|
})
|
||||||
|
return gotypesaliasDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
var gotypesaliasDefault bool
|
||||||
|
var aliasesDefaultOnce sync.Once
|
|
@ -259,13 +259,6 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func deref(typ types.Type) types.Type {
|
|
||||||
if p, _ := typ.(*types.Pointer); p != nil {
|
|
||||||
return p.Elem()
|
|
||||||
}
|
|
||||||
return typ
|
|
||||||
}
|
|
||||||
|
|
||||||
type byPath []*types.Package
|
type byPath []*types.Package
|
||||||
|
|
||||||
func (a byPath) Len() int { return len(a) }
|
func (a byPath) Len() int { return len(a) }
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/tools/go/types/objectpath"
|
"golang.org/x/tools/go/types/objectpath"
|
||||||
|
"golang.org/x/tools/internal/aliases"
|
||||||
"golang.org/x/tools/internal/tokeninternal"
|
"golang.org/x/tools/internal/tokeninternal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -506,13 +507,13 @@ func (p *iexporter) doDecl(obj types.Object) {
|
||||||
case *types.TypeName:
|
case *types.TypeName:
|
||||||
t := obj.Type()
|
t := obj.Type()
|
||||||
|
|
||||||
if tparam, ok := t.(*types.TypeParam); ok {
|
if tparam, ok := aliases.Unalias(t).(*types.TypeParam); ok {
|
||||||
w.tag('P')
|
w.tag('P')
|
||||||
w.pos(obj.Pos())
|
w.pos(obj.Pos())
|
||||||
constraint := tparam.Constraint()
|
constraint := tparam.Constraint()
|
||||||
if p.version >= iexportVersionGo1_18 {
|
if p.version >= iexportVersionGo1_18 {
|
||||||
implicit := false
|
implicit := false
|
||||||
if iface, _ := constraint.(*types.Interface); iface != nil {
|
if iface, _ := aliases.Unalias(constraint).(*types.Interface); iface != nil {
|
||||||
implicit = iface.IsImplicit()
|
implicit = iface.IsImplicit()
|
||||||
}
|
}
|
||||||
w.bool(implicit)
|
w.bool(implicit)
|
||||||
|
@ -738,6 +739,8 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
switch t := t.(type) {
|
switch t := t.(type) {
|
||||||
|
// TODO(adonovan): support types.Alias.
|
||||||
|
|
||||||
case *types.Named:
|
case *types.Named:
|
||||||
if targs := t.TypeArgs(); targs.Len() > 0 {
|
if targs := t.TypeArgs(); targs.Len() > 0 {
|
||||||
w.startType(instanceType)
|
w.startType(instanceType)
|
||||||
|
@ -843,7 +846,7 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
ft := t.EmbeddedType(i)
|
ft := t.EmbeddedType(i)
|
||||||
tPkg := pkg
|
tPkg := pkg
|
||||||
if named, _ := ft.(*types.Named); named != nil {
|
if named, _ := aliases.Unalias(ft).(*types.Named); named != nil {
|
||||||
w.pos(named.Obj().Pos())
|
w.pos(named.Obj().Pos())
|
||||||
} else {
|
} else {
|
||||||
w.pos(token.NoPos)
|
w.pos(token.NoPos)
|
||||||
|
|
|
@ -22,6 +22,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/tools/go/types/objectpath"
|
"golang.org/x/tools/go/types/objectpath"
|
||||||
|
"golang.org/x/tools/internal/aliases"
|
||||||
|
"golang.org/x/tools/internal/typesinternal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type intReader struct {
|
type intReader struct {
|
||||||
|
@ -522,7 +524,7 @@ func canReuse(def *types.Named, rhs types.Type) bool {
|
||||||
if def == nil {
|
if def == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
iface, _ := rhs.(*types.Interface)
|
iface, _ := aliases.Unalias(rhs).(*types.Interface)
|
||||||
if iface == nil {
|
if iface == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -587,14 +589,13 @@ func (r *importReader) obj(name string) {
|
||||||
// If the receiver has any targs, set those as the
|
// If the receiver has any targs, set those as the
|
||||||
// rparams of the method (since those are the
|
// rparams of the method (since those are the
|
||||||
// typeparams being used in the method sig/body).
|
// typeparams being used in the method sig/body).
|
||||||
base := baseType(recv.Type())
|
_, recvNamed := typesinternal.ReceiverNamed(recv)
|
||||||
assert(base != nil)
|
targs := recvNamed.TypeArgs()
|
||||||
targs := base.TypeArgs()
|
|
||||||
var rparams []*types.TypeParam
|
var rparams []*types.TypeParam
|
||||||
if targs.Len() > 0 {
|
if targs.Len() > 0 {
|
||||||
rparams = make([]*types.TypeParam, targs.Len())
|
rparams = make([]*types.TypeParam, targs.Len())
|
||||||
for i := range rparams {
|
for i := range rparams {
|
||||||
rparams[i] = targs.At(i).(*types.TypeParam)
|
rparams[i] = aliases.Unalias(targs.At(i)).(*types.TypeParam)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
msig := r.signature(recv, rparams, nil)
|
msig := r.signature(recv, rparams, nil)
|
||||||
|
@ -624,7 +625,7 @@ func (r *importReader) obj(name string) {
|
||||||
}
|
}
|
||||||
constraint := r.typ()
|
constraint := r.typ()
|
||||||
if implicit {
|
if implicit {
|
||||||
iface, _ := constraint.(*types.Interface)
|
iface, _ := aliases.Unalias(constraint).(*types.Interface)
|
||||||
if iface == nil {
|
if iface == nil {
|
||||||
errorf("non-interface constraint marked implicit")
|
errorf("non-interface constraint marked implicit")
|
||||||
}
|
}
|
||||||
|
@ -831,7 +832,7 @@ func (r *importReader) typ() types.Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
func isInterface(t types.Type) bool {
|
func isInterface(t types.Type) bool {
|
||||||
_, ok := t.(*types.Interface)
|
_, ok := aliases.Unalias(t).(*types.Interface)
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1030,7 +1031,7 @@ func (r *importReader) tparamList() []*types.TypeParam {
|
||||||
for i := range xs {
|
for i := range xs {
|
||||||
// Note: the standard library importer is tolerant of nil types here,
|
// Note: the standard library importer is tolerant of nil types here,
|
||||||
// though would panic in SetTypeParams.
|
// though would panic in SetTypeParams.
|
||||||
xs[i] = r.typ().(*types.TypeParam)
|
xs[i] = aliases.Unalias(r.typ()).(*types.TypeParam)
|
||||||
}
|
}
|
||||||
return xs
|
return xs
|
||||||
}
|
}
|
||||||
|
@ -1077,13 +1078,3 @@ func (r *importReader) byte() byte {
|
||||||
}
|
}
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
func baseType(typ types.Type) *types.Named {
|
|
||||||
// pointer receivers are never types.Named types
|
|
||||||
if p, _ := typ.(*types.Pointer); p != nil {
|
|
||||||
typ = p.Elem()
|
|
||||||
}
|
|
||||||
// receiver base types are always (possibly generic) types.Named types
|
|
||||||
n, _ := typ.(*types.Named)
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
// Copyright 2021 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
//go:build !go1.18
|
|
||||||
// +build !go1.18
|
|
||||||
|
|
||||||
package gcimporter
|
|
||||||
|
|
||||||
import "go/types"
|
|
||||||
|
|
||||||
const iexportVersion = iexportVersionGo1_11
|
|
||||||
|
|
||||||
func additionalPredeclared() []types.Type {
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -2,9 +2,6 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
package gcimporter
|
package gcimporter
|
||||||
|
|
||||||
import "go/types"
|
import "go/types"
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build !(go1.18 && goexperiment.unified)
|
//go:build !goexperiment.unified
|
||||||
// +build !go1.18 !goexperiment.unified
|
// +build !goexperiment.unified
|
||||||
|
|
||||||
package gcimporter
|
package gcimporter
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build go1.18 && goexperiment.unified
|
//go:build goexperiment.unified
|
||||||
// +build go1.18,goexperiment.unified
|
// +build goexperiment.unified
|
||||||
|
|
||||||
package gcimporter
|
package gcimporter
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
// Copyright 2022 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
//go:build !go1.18
|
|
||||||
// +build !go1.18
|
|
||||||
|
|
||||||
package gcimporter
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"go/token"
|
|
||||||
"go/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
|
|
||||||
err = fmt.Errorf("go/tools compiled with a Go version earlier than 1.18 cannot read unified IR export data")
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -4,9 +4,6 @@
|
||||||
|
|
||||||
// Derived from go/internal/gcimporter/ureader.go
|
// Derived from go/internal/gcimporter/ureader.go
|
||||||
|
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
package gcimporter
|
package gcimporter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -16,6 +13,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/tools/internal/aliases"
|
||||||
"golang.org/x/tools/internal/pkgbits"
|
"golang.org/x/tools/internal/pkgbits"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -553,7 +551,7 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
|
||||||
// If the underlying type is an interface, we need to
|
// If the underlying type is an interface, we need to
|
||||||
// duplicate its methods so we can replace the receiver
|
// duplicate its methods so we can replace the receiver
|
||||||
// parameter's type (#49906).
|
// parameter's type (#49906).
|
||||||
if iface, ok := underlying.(*types.Interface); ok && iface.NumExplicitMethods() != 0 {
|
if iface, ok := aliases.Unalias(underlying).(*types.Interface); ok && iface.NumExplicitMethods() != 0 {
|
||||||
methods := make([]*types.Func, iface.NumExplicitMethods())
|
methods := make([]*types.Func, iface.NumExplicitMethods())
|
||||||
for i := range methods {
|
for i := range methods {
|
||||||
fn := iface.ExplicitMethod(i)
|
fn := iface.ExplicitMethod(i)
|
||||||
|
|
|
@ -34,30 +34,16 @@ func GetLines(file *token.File) []int {
|
||||||
lines []int
|
lines []int
|
||||||
_ []struct{}
|
_ []struct{}
|
||||||
}
|
}
|
||||||
type tokenFile118 struct {
|
|
||||||
_ *token.FileSet // deleted in go1.19
|
|
||||||
tokenFile119
|
|
||||||
}
|
|
||||||
|
|
||||||
type uP = unsafe.Pointer
|
if unsafe.Sizeof(*file) != unsafe.Sizeof(tokenFile119{}) {
|
||||||
switch unsafe.Sizeof(*file) {
|
|
||||||
case unsafe.Sizeof(tokenFile118{}):
|
|
||||||
var ptr *tokenFile118
|
|
||||||
*(*uP)(uP(&ptr)) = uP(file)
|
|
||||||
ptr.mu.Lock()
|
|
||||||
defer ptr.mu.Unlock()
|
|
||||||
return ptr.lines
|
|
||||||
|
|
||||||
case unsafe.Sizeof(tokenFile119{}):
|
|
||||||
var ptr *tokenFile119
|
|
||||||
*(*uP)(uP(&ptr)) = uP(file)
|
|
||||||
ptr.mu.Lock()
|
|
||||||
defer ptr.mu.Unlock()
|
|
||||||
return ptr.lines
|
|
||||||
|
|
||||||
default:
|
|
||||||
panic("unexpected token.File size")
|
panic("unexpected token.File size")
|
||||||
}
|
}
|
||||||
|
var ptr *tokenFile119
|
||||||
|
type uP = unsafe.Pointer
|
||||||
|
*(*uP)(uP(&ptr)) = uP(file)
|
||||||
|
ptr.mu.Lock()
|
||||||
|
defer ptr.mu.Unlock()
|
||||||
|
return ptr.lines
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddExistingFiles adds the specified files to the FileSet if they
|
// AddExistingFiles adds the specified files to the FileSet if they
|
||||||
|
|
|
@ -2,20 +2,10 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// Package typeparams contains common utilities for writing tools that interact
|
// Package typeparams contains common utilities for writing tools that
|
||||||
// with generic Go code, as introduced with Go 1.18.
|
// interact with generic Go code, as introduced with Go 1.18. It
|
||||||
//
|
// supplements the standard library APIs. Notably, the StructuralTerms
|
||||||
// Many of the types and functions in this package are proxies for the new APIs
|
// API computes a minimal representation of the structural
|
||||||
// introduced in the standard library with Go 1.18. For example, the
|
|
||||||
// typeparams.Union type is an alias for go/types.Union, and the ForTypeSpec
|
|
||||||
// function returns the value of the go/ast.TypeSpec.TypeParams field. At Go
|
|
||||||
// versions older than 1.18 these helpers are implemented as stubs, allowing
|
|
||||||
// users of this package to write code that handles generic constructs inline,
|
|
||||||
// even if the Go version being used to compile does not support generics.
|
|
||||||
//
|
|
||||||
// Additionally, this package contains common utilities for working with the
|
|
||||||
// new generic constructs, to supplement the standard library APIs. Notably,
|
|
||||||
// the StructuralTerms API computes a minimal representation of the structural
|
|
||||||
// restrictions on a type parameter.
|
// restrictions on a type parameter.
|
||||||
//
|
//
|
||||||
// An external version of these APIs is available in the
|
// An external version of these APIs is available in the
|
||||||
|
@ -27,6 +17,9 @@ import (
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
"go/types"
|
"go/types"
|
||||||
|
|
||||||
|
"golang.org/x/tools/internal/aliases"
|
||||||
|
"golang.org/x/tools/internal/typesinternal"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UnpackIndexExpr extracts data from AST nodes that represent index
|
// UnpackIndexExpr extracts data from AST nodes that represent index
|
||||||
|
@ -72,9 +65,9 @@ func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack toke
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsTypeParam reports whether t is a type parameter.
|
// IsTypeParam reports whether t is a type parameter (or an alias of one).
|
||||||
func IsTypeParam(t types.Type) bool {
|
func IsTypeParam(t types.Type) bool {
|
||||||
_, ok := t.(*types.TypeParam)
|
_, ok := aliases.Unalias(t).(*types.TypeParam)
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,13 +83,8 @@ func OriginMethod(fn *types.Func) *types.Func {
|
||||||
if recv == nil {
|
if recv == nil {
|
||||||
return fn
|
return fn
|
||||||
}
|
}
|
||||||
base := recv.Type()
|
_, named := typesinternal.ReceiverNamed(recv)
|
||||||
p, isPtr := base.(*types.Pointer)
|
if named == nil {
|
||||||
if isPtr {
|
|
||||||
base = p.Elem()
|
|
||||||
}
|
|
||||||
named, isNamed := base.(*types.Named)
|
|
||||||
if !isNamed {
|
|
||||||
// Receiver is a *types.Interface.
|
// Receiver is a *types.Interface.
|
||||||
return fn
|
return fn
|
||||||
}
|
}
|
||||||
|
@ -158,6 +146,9 @@ func OriginMethod(fn *types.Func) *types.Func {
|
||||||
// In this case, GenericAssignableTo reports that instantiations of Container
|
// In this case, GenericAssignableTo reports that instantiations of Container
|
||||||
// are assignable to the corresponding instantiation of Interface.
|
// are assignable to the corresponding instantiation of Interface.
|
||||||
func GenericAssignableTo(ctxt *types.Context, V, T types.Type) bool {
|
func GenericAssignableTo(ctxt *types.Context, V, T types.Type) bool {
|
||||||
|
V = aliases.Unalias(V)
|
||||||
|
T = aliases.Unalias(T)
|
||||||
|
|
||||||
// If V and T are not both named, or do not have matching non-empty type
|
// If V and T are not both named, or do not have matching non-empty type
|
||||||
// parameter lists, fall back on types.AssignableTo.
|
// parameter lists, fall back on types.AssignableTo.
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
package typeparams
|
package typeparams
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"go/types"
|
"go/types"
|
||||||
|
|
||||||
|
"golang.org/x/tools/internal/aliases"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CoreType returns the core type of T or nil if T does not have a core type.
|
// CoreType returns the core type of T or nil if T does not have a core type.
|
||||||
|
@ -109,7 +112,7 @@ func CoreType(T types.Type) types.Type {
|
||||||
// _NormalTerms makes no guarantees about the order of terms, except that it
|
// _NormalTerms makes no guarantees about the order of terms, except that it
|
||||||
// is deterministic.
|
// is deterministic.
|
||||||
func _NormalTerms(typ types.Type) ([]*types.Term, error) {
|
func _NormalTerms(typ types.Type) ([]*types.Term, error) {
|
||||||
switch typ := typ.(type) {
|
switch typ := aliases.Unalias(typ).(type) {
|
||||||
case *types.TypeParam:
|
case *types.TypeParam:
|
||||||
return StructuralTerms(typ)
|
return StructuralTerms(typ)
|
||||||
case *types.Union:
|
case *types.Union:
|
||||||
|
@ -120,3 +123,15 @@ func _NormalTerms(typ types.Type) ([]*types.Term, error) {
|
||||||
return []*types.Term{types.NewTerm(false, typ)}, nil
|
return []*types.Term{types.NewTerm(false, typ)}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MustDeref returns the type of the variable pointed to by t.
|
||||||
|
// It panics if t's core type is not a pointer.
|
||||||
|
//
|
||||||
|
// TODO(adonovan): ideally this would live in typesinternal, but that
|
||||||
|
// creates an import cycle. Move there when we melt this package down.
|
||||||
|
func MustDeref(t types.Type) types.Type {
|
||||||
|
if ptr, ok := CoreType(t).(*types.Pointer); ok {
|
||||||
|
return ptr.Elem()
|
||||||
|
}
|
||||||
|
panic(fmt.Sprintf("%v is not a pointer", t))
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Copyright 2024 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package typesinternal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go/types"
|
||||||
|
|
||||||
|
"golang.org/x/tools/internal/aliases"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ReceiverNamed returns the named type (if any) associated with the
|
||||||
|
// type of recv, which may be of the form N or *N, or aliases thereof.
|
||||||
|
// It also reports whether a Pointer was present.
|
||||||
|
func ReceiverNamed(recv *types.Var) (isPtr bool, named *types.Named) {
|
||||||
|
t := recv.Type()
|
||||||
|
if ptr, ok := aliases.Unalias(t).(*types.Pointer); ok {
|
||||||
|
isPtr = true
|
||||||
|
t = ptr.Elem()
|
||||||
|
}
|
||||||
|
named, _ = aliases.Unalias(t).(*types.Named)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpointer returns T given *T or an alias thereof.
|
||||||
|
// For all other types it is the identity function.
|
||||||
|
// It does not look at underlying types.
|
||||||
|
// The result may be an alias.
|
||||||
|
//
|
||||||
|
// Use this function to strip off the optional pointer on a receiver
|
||||||
|
// in a field or method selection, without losing the named type
|
||||||
|
// (which is needed to compute the method set).
|
||||||
|
//
|
||||||
|
// See also [typeparams.MustDeref], which removes one level of
|
||||||
|
// indirection from the type, regardless of named types (analogous to
|
||||||
|
// a LOAD instruction).
|
||||||
|
func Unpointer(t types.Type) types.Type {
|
||||||
|
if ptr, ok := aliases.Unalias(t).(*types.Pointer); ok {
|
||||||
|
return ptr.Elem()
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
}
|
|
@ -2,9 +2,6 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build go1.18
|
|
||||||
// +build go1.18
|
|
||||||
|
|
||||||
package typesinternal
|
package typesinternal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Copyright 2023 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package versions
|
||||||
|
|
||||||
|
// This file contains predicates for working with file versions to
|
||||||
|
// decide when a tool should consider a language feature enabled.
|
||||||
|
|
||||||
|
// GoVersions that features in x/tools can be gated to.
|
||||||
|
const (
|
||||||
|
Go1_18 = "go1.18"
|
||||||
|
Go1_19 = "go1.19"
|
||||||
|
Go1_20 = "go1.20"
|
||||||
|
Go1_21 = "go1.21"
|
||||||
|
Go1_22 = "go1.22"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Future is an invalid unknown Go version sometime in the future.
|
||||||
|
// Do not use directly with Compare.
|
||||||
|
const Future = ""
|
||||||
|
|
||||||
|
// AtLeast reports whether the file version v comes after a Go release.
|
||||||
|
//
|
||||||
|
// Use this predicate to enable a behavior once a certain Go release
|
||||||
|
// has happened (and stays enabled in the future).
|
||||||
|
func AtLeast(v, release string) bool {
|
||||||
|
if v == Future {
|
||||||
|
return true // an unknown future version is always after y.
|
||||||
|
}
|
||||||
|
return Compare(Lang(v), Lang(release)) >= 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Before reports whether the file version v is strictly before a Go release.
|
||||||
|
//
|
||||||
|
// Use this predicate to disable a behavior once a certain Go release
|
||||||
|
// has happened (and stays enabled in the future).
|
||||||
|
func Before(v, release string) bool {
|
||||||
|
if v == Future {
|
||||||
|
return false // an unknown future version happens after y.
|
||||||
|
}
|
||||||
|
return Compare(Lang(v), Lang(release)) < 0
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2024 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package versions
|
||||||
|
|
||||||
|
// toolchain is maximum version (<1.22) that the go toolchain used
|
||||||
|
// to build the current tool is known to support.
|
||||||
|
//
|
||||||
|
// When a tool is built with >=1.22, the value of toolchain is unused.
|
||||||
|
//
|
||||||
|
// x/tools does not support building with go <1.18. So we take this
|
||||||
|
// as the minimum possible maximum.
|
||||||
|
var toolchain string = Go1_18
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2024 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.19
|
||||||
|
// +build go1.19
|
||||||
|
|
||||||
|
package versions
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if Compare(toolchain, Go1_19) < 0 {
|
||||||
|
toolchain = Go1_19
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2024 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.20
|
||||||
|
// +build go1.20
|
||||||
|
|
||||||
|
package versions
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if Compare(toolchain, Go1_20) < 0 {
|
||||||
|
toolchain = Go1_20
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2024 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.21
|
||||||
|
// +build go1.21
|
||||||
|
|
||||||
|
package versions
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if Compare(toolchain, Go1_21) < 0 {
|
||||||
|
toolchain = Go1_21
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,9 +12,19 @@ import (
|
||||||
"go/types"
|
"go/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FileVersions always reports the a file's Go version as the
|
// FileVersion returns a language version (<=1.21) derived from runtime.Version()
|
||||||
// zero version at this Go version.
|
// or an unknown future version.
|
||||||
func FileVersions(info *types.Info, file *ast.File) string { return "" }
|
func FileVersion(info *types.Info, file *ast.File) string {
|
||||||
|
// In x/tools built with Go <= 1.21, we do not have Info.FileVersions
|
||||||
|
// available. We use a go version derived from the toolchain used to
|
||||||
|
// compile the tool by default.
|
||||||
|
// This will be <= go1.21. We take this as the maximum version that
|
||||||
|
// this tool can support.
|
||||||
|
//
|
||||||
|
// There are no features currently in x/tools that need to tell fine grained
|
||||||
|
// differences for versions <1.22.
|
||||||
|
return toolchain
|
||||||
|
}
|
||||||
|
|
||||||
// InitFileVersions is a noop at this Go version.
|
// InitFileVersions is a noop when compiled with this Go version.
|
||||||
func InitFileVersions(*types.Info) {}
|
func InitFileVersions(*types.Info) {}
|
||||||
|
|
|
@ -12,10 +12,27 @@ import (
|
||||||
"go/types"
|
"go/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FileVersions maps a file to the file's semantic Go version.
|
// FileVersions returns a file's Go version.
|
||||||
// The reported version is the zero version if a version cannot be determined.
|
// The reported version is an unknown Future version if a
|
||||||
func FileVersions(info *types.Info, file *ast.File) string {
|
// version cannot be determined.
|
||||||
return info.FileVersions[file]
|
func FileVersion(info *types.Info, file *ast.File) string {
|
||||||
|
// In tools built with Go >= 1.22, the Go version of a file
|
||||||
|
// follow a cascades of sources:
|
||||||
|
// 1) types.Info.FileVersion, which follows the cascade:
|
||||||
|
// 1.a) file version (ast.File.GoVersion),
|
||||||
|
// 1.b) the package version (types.Config.GoVersion), or
|
||||||
|
// 2) is some unknown Future version.
|
||||||
|
//
|
||||||
|
// File versions require a valid package version to be provided to types
|
||||||
|
// in Config.GoVersion. Config.GoVersion is either from the package's module
|
||||||
|
// or the toolchain (go run). This value should be provided by go/packages
|
||||||
|
// or unitchecker.Config.GoVersion.
|
||||||
|
if v := info.FileVersions[file]; IsValid(v) {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
// Note: we could instead return runtime.Version() [if valid].
|
||||||
|
// This would act as a max version on what a tool can support.
|
||||||
|
return Future
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitFileVersions initializes info to record Go versions for Go files.
|
// InitFileVersions initializes info to record Go versions for Go files.
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
|
|
||||||
package versions
|
package versions
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// Note: If we use build tags to use go/versions when go >=1.22,
|
// Note: If we use build tags to use go/versions when go >=1.22,
|
||||||
// we run into go.dev/issue/53737. Under some operations users would see an
|
// we run into go.dev/issue/53737. Under some operations users would see an
|
||||||
// import of "go/versions" even if they would not compile the file.
|
// import of "go/versions" even if they would not compile the file.
|
||||||
|
@ -45,6 +49,7 @@ func IsValid(x string) bool { return isValid(stripGo(x)) }
|
||||||
// stripGo converts from a "go1.21" version to a "1.21" version.
|
// stripGo converts from a "go1.21" version to a "1.21" version.
|
||||||
// If v does not start with "go", stripGo returns the empty string (a known invalid version).
|
// If v does not start with "go", stripGo returns the empty string (a known invalid version).
|
||||||
func stripGo(v string) string {
|
func stripGo(v string) string {
|
||||||
|
v, _, _ = strings.Cut(v, "-") // strip -bigcorp suffix.
|
||||||
if len(v) < 2 || v[:2] != "go" {
|
if len(v) < 2 || v[:2] != "go" {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,7 @@ github.com/containers/buildah/pkg/sshagent
|
||||||
github.com/containers/buildah/pkg/util
|
github.com/containers/buildah/pkg/util
|
||||||
github.com/containers/buildah/pkg/volumes
|
github.com/containers/buildah/pkg/volumes
|
||||||
github.com/containers/buildah/util
|
github.com/containers/buildah/util
|
||||||
# github.com/containers/common v0.58.1-0.20240320163250-bc5f97c39cca
|
# github.com/containers/common v0.58.1-0.20240403123718-735c922b53c4
|
||||||
## explicit; go 1.20
|
## explicit; go 1.20
|
||||||
github.com/containers/common/internal
|
github.com/containers/common/internal
|
||||||
github.com/containers/common/internal/attributedstring
|
github.com/containers/common/internal/attributedstring
|
||||||
|
@ -836,7 +836,7 @@ github.com/nxadm/tail/winfile
|
||||||
# github.com/oklog/ulid v1.3.1
|
# github.com/oklog/ulid v1.3.1
|
||||||
## explicit
|
## explicit
|
||||||
github.com/oklog/ulid
|
github.com/oklog/ulid
|
||||||
# github.com/onsi/ginkgo/v2 v2.17.0
|
# github.com/onsi/ginkgo/v2 v2.17.1
|
||||||
## explicit; go 1.20
|
## explicit; go 1.20
|
||||||
github.com/onsi/ginkgo/v2
|
github.com/onsi/ginkgo/v2
|
||||||
github.com/onsi/ginkgo/v2/config
|
github.com/onsi/ginkgo/v2/config
|
||||||
|
@ -1179,12 +1179,12 @@ golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
|
||||||
golang.org/x/crypto/ssh/knownhosts
|
golang.org/x/crypto/ssh/knownhosts
|
||||||
golang.org/x/crypto/twofish
|
golang.org/x/crypto/twofish
|
||||||
golang.org/x/crypto/xts
|
golang.org/x/crypto/xts
|
||||||
# golang.org/x/exp v0.0.0-20240222234643-814bf88cf225
|
# golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8
|
||||||
## explicit; go 1.20
|
## explicit; go 1.20
|
||||||
golang.org/x/exp/constraints
|
golang.org/x/exp/constraints
|
||||||
golang.org/x/exp/maps
|
golang.org/x/exp/maps
|
||||||
golang.org/x/exp/slices
|
golang.org/x/exp/slices
|
||||||
# golang.org/x/mod v0.15.0
|
# golang.org/x/mod v0.16.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
golang.org/x/mod/semver
|
golang.org/x/mod/semver
|
||||||
golang.org/x/mod/sumdb/note
|
golang.org/x/mod/sumdb/note
|
||||||
|
@ -1248,8 +1248,8 @@ golang.org/x/text/unicode/norm
|
||||||
# golang.org/x/time v0.3.0
|
# golang.org/x/time v0.3.0
|
||||||
## explicit
|
## explicit
|
||||||
golang.org/x/time/rate
|
golang.org/x/time/rate
|
||||||
# golang.org/x/tools v0.18.0
|
# golang.org/x/tools v0.19.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.19
|
||||||
golang.org/x/tools/cmd/stringer
|
golang.org/x/tools/cmd/stringer
|
||||||
golang.org/x/tools/cover
|
golang.org/x/tools/cover
|
||||||
golang.org/x/tools/go/ast/inspector
|
golang.org/x/tools/go/ast/inspector
|
||||||
|
@ -1257,6 +1257,7 @@ golang.org/x/tools/go/gcexportdata
|
||||||
golang.org/x/tools/go/internal/packagesdriver
|
golang.org/x/tools/go/internal/packagesdriver
|
||||||
golang.org/x/tools/go/packages
|
golang.org/x/tools/go/packages
|
||||||
golang.org/x/tools/go/types/objectpath
|
golang.org/x/tools/go/types/objectpath
|
||||||
|
golang.org/x/tools/internal/aliases
|
||||||
golang.org/x/tools/internal/event
|
golang.org/x/tools/internal/event
|
||||||
golang.org/x/tools/internal/event/core
|
golang.org/x/tools/internal/event/core
|
||||||
golang.org/x/tools/internal/event/keys
|
golang.org/x/tools/internal/event/keys
|
||||||
|
|
Loading…
Reference in New Issue