mirror of
https://github.com/containers/podman.git
synced 2026-03-28 03:22:18 -04:00
Merge pull request #25130 from Luap99/vendor
vendor latest c/{buildah,common,image,storage}
This commit is contained in:
22
go.mod
22
go.mod
@@ -13,15 +13,15 @@ require (
|
||||
github.com/checkpoint-restore/checkpointctl v1.3.0
|
||||
github.com/checkpoint-restore/go-criu/v7 v7.2.0
|
||||
github.com/containernetworking/plugins v1.5.1
|
||||
github.com/containers/buildah v1.38.1-0.20241119213149-52437ef15d33
|
||||
github.com/containers/common v0.61.1-0.20250120135258-06628cb958e9
|
||||
github.com/containers/buildah v1.38.1-0.20250125114111-92015b7f4301
|
||||
github.com/containers/common v0.61.1-0.20250124131345-fa339b6b6eda
|
||||
github.com/containers/conmon v2.0.20+incompatible
|
||||
github.com/containers/gvisor-tap-vsock v0.8.2
|
||||
github.com/containers/image/v5 v5.33.2-0.20250122201336-16f7e1e0e1fd
|
||||
github.com/containers/image/v5 v5.33.2-0.20250122233652-b5c6aff95ca7
|
||||
github.com/containers/libhvee v0.9.0
|
||||
github.com/containers/ocicrypt v1.2.1
|
||||
github.com/containers/psgo v1.9.0
|
||||
github.com/containers/storage v1.56.2-0.20250121150636-c2cdd500e4ef
|
||||
github.com/containers/storage v1.56.2-0.20250123125217-80d3c0e77d29
|
||||
github.com/containers/winquit v1.1.0
|
||||
github.com/coreos/go-systemd/v22 v22.5.1-0.20231103132048-7d375ecc2b09
|
||||
github.com/crc-org/crc/v2 v2.45.0
|
||||
@@ -29,7 +29,7 @@ require (
|
||||
github.com/cyphar/filepath-securejoin v0.3.6
|
||||
github.com/digitalocean/go-qemu v0.0.0-20230711162256-2e3d0186973e
|
||||
github.com/docker/distribution v2.8.3+incompatible
|
||||
github.com/docker/docker v27.5.0+incompatible
|
||||
github.com/docker/docker v27.5.1+incompatible
|
||||
github.com/docker/go-connections v0.5.0
|
||||
github.com/docker/go-plugins-helpers v0.0.0-20240701071450-45e2431495c8
|
||||
github.com/docker/go-units v0.5.0
|
||||
@@ -69,7 +69,7 @@ require (
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/vbauerster/mpb/v8 v8.9.1
|
||||
github.com/vishvananda/netlink v1.3.0
|
||||
github.com/vishvananda/netlink v1.3.1-0.20240922070040-084abd93d350
|
||||
go.etcd.io/bbolt v1.3.11
|
||||
golang.org/x/crypto v0.32.0
|
||||
golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329
|
||||
@@ -99,15 +99,15 @@ require (
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/containerd/cgroups/v3 v3.0.3 // indirect
|
||||
github.com/containerd/errdefs v0.3.0 // indirect
|
||||
github.com/containerd/errdefs v1.0.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/containerd/platforms v1.0.0-rc.1 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.2.3 // indirect
|
||||
github.com/containernetworking/cni v1.2.3 // indirect
|
||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
|
||||
github.com/containers/luksy v0.0.0-20241007190014-e2530d691420 // indirect
|
||||
github.com/containers/luksy v0.0.0-20250106202729-a3a812db5b72 // indirect
|
||||
github.com/coreos/go-oidc/v3 v3.12.0 // indirect
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f // indirect
|
||||
@@ -171,7 +171,7 @@ require (
|
||||
github.com/miekg/pkcs11 v1.1.1 // indirect
|
||||
github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/moby/buildkit v0.17.1 // indirect
|
||||
github.com/moby/buildkit v0.19.0 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/patternmatcher v0.6.0 // indirect
|
||||
github.com/moby/sys/mountinfo v0.7.2 // indirect
|
||||
@@ -216,7 +216,7 @@ require (
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.mongodb.org/mongo-driver v1.14.0 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect
|
||||
go.opentelemetry.io/otel v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.31.0 // indirect
|
||||
|
||||
60
go.sum
60
go.sum
@@ -3,8 +3,8 @@ dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774 h1:SCbEWT58NSt7d2mcFdvxC9uyrdcTfvBbPLThhkDmXzg=
|
||||
github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774/go.mod h1:6/0dYRLLXyJjbkIPeeGyoJ/eKOSI0eU6eTlCBYibgd0=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
@@ -60,14 +60,14 @@ github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQ
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0=
|
||||
github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0=
|
||||
github.com/containerd/errdefs v0.3.0 h1:FSZgGOeK4yuT/+DnF07/Olde/q4KBoMsaamhXxIMDp4=
|
||||
github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
|
||||
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
|
||||
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
|
||||
github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
|
||||
github.com/containerd/platforms v1.0.0-rc.1 h1:83KIq4yy1erSRgOVHNk1HYdPvzdJ5CnsWaRoJX4C41E=
|
||||
github.com/containerd/platforms v1.0.0-rc.1/go.mod h1:J71L7B+aiM5SdIEqmd9wp6THLVRzJGXfNuWCZCllLA4=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU=
|
||||
github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
|
||||
@@ -76,28 +76,28 @@ github.com/containernetworking/cni v1.2.3 h1:hhOcjNVUQTnzdRJ6alC5XF+wd9mfGIUaj8F
|
||||
github.com/containernetworking/cni v1.2.3/go.mod h1:DuLgF+aPd3DzcTQTtp/Nvl1Kim23oFKdm2okJzBQA5M=
|
||||
github.com/containernetworking/plugins v1.5.1 h1:T5ji+LPYjjgW0QM+KyrigZbLsZ8jaX+E5J/EcKOE4gQ=
|
||||
github.com/containernetworking/plugins v1.5.1/go.mod h1:MIQfgMayGuHYs0XdNudf31cLLAC+i242hNm6KuDGqCM=
|
||||
github.com/containers/buildah v1.38.1-0.20241119213149-52437ef15d33 h1:Ih6KuyByK7ZGGzkS0M5rVBPLWIyeDvdL5klhsKBo8vA=
|
||||
github.com/containers/buildah v1.38.1-0.20241119213149-52437ef15d33/go.mod h1:RxIuKhwTpRl3ma4d4BF6QzSSeg9zNNvo/xhYJOKeDQs=
|
||||
github.com/containers/common v0.61.1-0.20250120135258-06628cb958e9 h1:aiup0MIiAi2Xnv15vApAPqgy4/49ZGkYOpevDgGHfxg=
|
||||
github.com/containers/common v0.61.1-0.20250120135258-06628cb958e9/go.mod h1:1S+/XhAEOwMGePCUqoYYh1iZo9fU1IpuIwVzCCIdBVU=
|
||||
github.com/containers/buildah v1.38.1-0.20250125114111-92015b7f4301 h1:eqHczpfbWOjyvQAkuCmzsZPds657cPXxXniXLcKFHdQ=
|
||||
github.com/containers/buildah v1.38.1-0.20250125114111-92015b7f4301/go.mod h1:UOhJzUS2A0uyZR/TygObcg2Og+nJ02pwMfVhIQBRIN8=
|
||||
github.com/containers/common v0.61.1-0.20250124131345-fa339b6b6eda h1:ltztaW234A8UvR3xz0hY4eD8ABo3B6gd3kGKVHPqGuE=
|
||||
github.com/containers/common v0.61.1-0.20250124131345-fa339b6b6eda/go.mod h1:mWhwkYaWR5bXeOwq3ruzdmH9gaT2pex00C6pd4VXuvM=
|
||||
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
|
||||
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
|
||||
github.com/containers/gvisor-tap-vsock v0.8.2 h1:uQMBCCHlIIj62fPjbvgm6AL5EzsP6TP5eviByOJEsOg=
|
||||
github.com/containers/gvisor-tap-vsock v0.8.2/go.mod h1:EMRe2o63ddq2zxcP0hTysmxCf/5JlaNEg8/gpzP0ox4=
|
||||
github.com/containers/image/v5 v5.33.2-0.20250122201336-16f7e1e0e1fd h1:+3Rikfp8UWWAVihJwK8x4zrfwAA3R/uwdtsX33QyeSA=
|
||||
github.com/containers/image/v5 v5.33.2-0.20250122201336-16f7e1e0e1fd/go.mod h1:wTYNEK3AOQnVlBaQLmq7AmXXWqDvRizeZlT8fE/kaA4=
|
||||
github.com/containers/image/v5 v5.33.2-0.20250122233652-b5c6aff95ca7 h1:dTKluTTlijEdQmTZPK1wTX39qXb4F93/GPHhq+vlC3U=
|
||||
github.com/containers/image/v5 v5.33.2-0.20250122233652-b5c6aff95ca7/go.mod h1:NyH4/AlLW8cvPgtwbCMzz71dr9SOh8/WP9ua5c9Akc8=
|
||||
github.com/containers/libhvee v0.9.0 h1:5UxJMka1lDfxTeITA25Pd8QVVttJAG43eQS1Getw1tc=
|
||||
github.com/containers/libhvee v0.9.0/go.mod h1:p44VJd8jMIx3SRN1eM6PxfCEwXQE0lJ0dQppCAlzjPQ=
|
||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
|
||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
|
||||
github.com/containers/luksy v0.0.0-20241007190014-e2530d691420 h1:57rxgU2wdI3lZMDZtao09WjCWmxBKOxI/Sj37IpCV50=
|
||||
github.com/containers/luksy v0.0.0-20241007190014-e2530d691420/go.mod h1:MYzFCudLgMcXgFl7XuFjUowNDTBqL09BfEgMf7QHtO4=
|
||||
github.com/containers/luksy v0.0.0-20250106202729-a3a812db5b72 h1:hdBIFaml6hO+Bal8CdQSQPTF305gwsJfubs4NoOV53A=
|
||||
github.com/containers/luksy v0.0.0-20250106202729-a3a812db5b72/go.mod h1:UpMgEjd9XelIA/iK+qD3hWIrZY/M3eaepn+gm5U8OYE=
|
||||
github.com/containers/ocicrypt v1.2.1 h1:0qIOTT9DoYwcKmxSt8QJt+VzMY18onl9jUXsxpVhSmM=
|
||||
github.com/containers/ocicrypt v1.2.1/go.mod h1:aD0AAqfMp0MtwqWgHM1bUwe1anx0VazI108CRrSKINQ=
|
||||
github.com/containers/psgo v1.9.0 h1:eJ74jzSaCHnWt26OlKZROSyUyRcGDf+gYBdXnxrMW4g=
|
||||
github.com/containers/psgo v1.9.0/go.mod h1:0YoluUm43Mz2UnBIh1P+6V6NWcbpTL5uRtXyOcH0B5A=
|
||||
github.com/containers/storage v1.56.2-0.20250121150636-c2cdd500e4ef h1:mzC7dl6SRdqyMd22kLuljhJTdoqqd4gW8m4LTNetBCo=
|
||||
github.com/containers/storage v1.56.2-0.20250121150636-c2cdd500e4ef/go.mod h1:KbGwnyB0b3cwwiPuAiB9XqSYfsEhRb/ALIPgfqpmLLA=
|
||||
github.com/containers/storage v1.56.2-0.20250123125217-80d3c0e77d29 h1:3L1QCfh72xytLizQeswDaKcB5ajq54DuFRcAy/C3P3c=
|
||||
github.com/containers/storage v1.56.2-0.20250123125217-80d3c0e77d29/go.mod h1:i/Hb4lu7YgFr9G0K6BMjqW0BLJO1sFsnWQwj2UoWCUM=
|
||||
github.com/containers/winquit v1.1.0 h1:jArun04BNDQvt2W0Y78kh9TazN2EIEMG5Im6/JY7+pE=
|
||||
github.com/containers/winquit v1.1.0/go.mod h1:PsPeZlnbkmGGIToMPHF1zhWjBUkd8aHjMOr/vFcPxw8=
|
||||
github.com/coreos/go-oidc/v3 v3.12.0 h1:sJk+8G2qq94rDI6ehZ71Bol3oUHy63qNYmkiSjrc/Jo=
|
||||
@@ -133,8 +133,8 @@ github.com/docker/cli v27.5.1+incompatible h1:JB9cieUT9YNiMITtIsguaN55PLOHhBSz3L
|
||||
github.com/docker/cli v27.5.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v27.5.0+incompatible h1:um++2NcQtGRTz5eEgO6aJimo6/JxrTXC941hd05JO6U=
|
||||
github.com/docker/docker v27.5.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v27.5.1+incompatible h1:4PYU5dnBYqRQi0294d1FBECqT9ECWeQAIfE8q4YnPY8=
|
||||
github.com/docker/docker v27.5.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
|
||||
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
@@ -356,8 +356,8 @@ github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPn
|
||||
github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/buildkit v0.17.1 h1:VWj6eIdk7u6acHPn2CiA+tdq0/mQoBEk9ckweRzWmPw=
|
||||
github.com/moby/buildkit v0.17.1/go.mod h1:ru8NFyDHD8HbuKaLXJIjK9nr3x6FZR+IWjtF07S+wdM=
|
||||
github.com/moby/buildkit v0.19.0 h1:w9G1p7sArvCGNkpWstAqJfRQTXBKukMyMK1bsah1HNo=
|
||||
github.com/moby/buildkit v0.19.0/go.mod h1:WiHBFTgWV8eB1AmPxIWsAlKjUACAwm3X/14xOV4VWew=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
|
||||
@@ -517,8 +517,8 @@ github.com/vbatts/tar-split v0.11.7 h1:ixZ93pO/GmvaZw4Vq9OwmfZK/kc2zKdPfu0B+gYqs
|
||||
github.com/vbatts/tar-split v0.11.7/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=
|
||||
github.com/vbauerster/mpb/v8 v8.9.1 h1:LH5R3lXPfE2e3lIGxN7WNWv3Hl5nWO6LRi2B0L0ERHw=
|
||||
github.com/vbauerster/mpb/v8 v8.9.1/go.mod h1:4XMvznPh8nfe2NpnDo1QTPvW9MVkUhbG90mPWvmOzcQ=
|
||||
github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk=
|
||||
github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
|
||||
github.com/vishvananda/netlink v1.3.1-0.20240922070040-084abd93d350 h1:w5OI+kArIBVksl8UGn6ARQshtPCQvDsbuA9NQie3GIg=
|
||||
github.com/vishvananda/netlink v1.3.1-0.20240922070040-084abd93d350/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
|
||||
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
|
||||
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
@@ -549,14 +549,14 @@ go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd
|
||||
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM=
|
||||
go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
|
||||
go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 h1:lUsI2TYsQw2r1IASwoROaCnjdj2cvC2+Jbxvk6nHnWU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0/go.mod h1:2HpZxxQurfGxJlJDblybejHB6RX6pmExPNe517hREw4=
|
||||
go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
|
||||
go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
|
||||
go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
|
||||
@@ -565,8 +565,8 @@ go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4Jjx
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||
go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
|
||||
go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
|
||||
go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94=
|
||||
go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
|
||||
@@ -271,6 +271,11 @@ skip_if_remote "different error messages between podman & podman-remote" \
|
||||
"bud with .dockerignore #2" \
|
||||
"bud with .dockerignore #4"
|
||||
|
||||
# 2025-01-27: https://github.com/containers/podman/issues/25138
|
||||
skip_if_remote "FIXME #25138: mount cache not working one remote" \
|
||||
"bud --layers with --mount type bind should burst cache if content is changed" \
|
||||
"bud --layers with --mount type bind should burst and multiple mounts cache if content is changed"
|
||||
|
||||
# END tests which are skipped due to actual podman or podman-remote bugs.
|
||||
###############################################################################
|
||||
# BEGIN temporary workarounds that must be reevaluated periodically
|
||||
|
||||
8
vendor/github.com/containerd/platforms/.golangci.yml
generated
vendored
8
vendor/github.com/containerd/platforms/.golangci.yml
generated
vendored
@@ -1,6 +1,6 @@
|
||||
linters:
|
||||
enable:
|
||||
- exportloopref # Checks for pointers to enclosing loop variables
|
||||
- copyloopvar
|
||||
- gofmt
|
||||
- goimports
|
||||
- gosec
|
||||
@@ -12,14 +12,16 @@ linters:
|
||||
- tenv # Detects using os.Setenv instead of t.Setenv since Go 1.17
|
||||
- unconvert
|
||||
- unused
|
||||
- vet
|
||||
- govet
|
||||
- dupword # Checks for duplicate words in the source code
|
||||
disable:
|
||||
- errcheck
|
||||
|
||||
run:
|
||||
timeout: 5m
|
||||
skip-dirs:
|
||||
|
||||
issues:
|
||||
exclude-dirs:
|
||||
- api
|
||||
- cluster
|
||||
- design
|
||||
|
||||
57
vendor/github.com/containerd/platforms/compare.go
generated
vendored
57
vendor/github.com/containerd/platforms/compare.go
generated
vendored
@@ -31,6 +31,34 @@ type MatchComparer interface {
|
||||
Less(specs.Platform, specs.Platform) bool
|
||||
}
|
||||
|
||||
type platformVersions struct {
|
||||
major []int
|
||||
minor []int
|
||||
}
|
||||
|
||||
var arm64variantToVersion = map[string]platformVersions{
|
||||
"v8": {[]int{8}, []int{0}},
|
||||
"v8.0": {[]int{8}, []int{0}},
|
||||
"v8.1": {[]int{8}, []int{1}},
|
||||
"v8.2": {[]int{8}, []int{2}},
|
||||
"v8.3": {[]int{8}, []int{3}},
|
||||
"v8.4": {[]int{8}, []int{4}},
|
||||
"v8.5": {[]int{8}, []int{5}},
|
||||
"v8.6": {[]int{8}, []int{6}},
|
||||
"v8.7": {[]int{8}, []int{7}},
|
||||
"v8.8": {[]int{8}, []int{8}},
|
||||
"v8.9": {[]int{8}, []int{9}},
|
||||
"v9": {[]int{9, 8}, []int{0, 5}},
|
||||
"v9.0": {[]int{9, 8}, []int{0, 5}},
|
||||
"v9.1": {[]int{9, 8}, []int{1, 6}},
|
||||
"v9.2": {[]int{9, 8}, []int{2, 7}},
|
||||
"v9.3": {[]int{9, 8}, []int{3, 8}},
|
||||
"v9.4": {[]int{9, 8}, []int{4, 9}},
|
||||
"v9.5": {[]int{9, 8}, []int{5, 9}},
|
||||
"v9.6": {[]int{9, 8}, []int{6, 9}},
|
||||
"v9.7": {[]int{9, 8}, []int{7, 9}},
|
||||
}
|
||||
|
||||
// platformVector returns an (ordered) vector of appropriate specs.Platform
|
||||
// objects to try matching for the given platform object (see platforms.Only).
|
||||
func platformVector(platform specs.Platform) []specs.Platform {
|
||||
@@ -72,6 +100,33 @@ func platformVector(platform specs.Platform) []specs.Platform {
|
||||
if variant == "" {
|
||||
variant = "v8"
|
||||
}
|
||||
|
||||
vector = []specs.Platform{} // Reset vector, the first variant will be added in loop.
|
||||
arm64Versions, ok := arm64variantToVersion[variant]
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
for i, major := range arm64Versions.major {
|
||||
for minor := arm64Versions.minor[i]; minor >= 0; minor-- {
|
||||
arm64Variant := "v" + strconv.Itoa(major) + "." + strconv.Itoa(minor)
|
||||
if minor == 0 {
|
||||
arm64Variant = "v" + strconv.Itoa(major)
|
||||
}
|
||||
vector = append(vector, specs.Platform{
|
||||
Architecture: "arm64",
|
||||
OS: platform.OS,
|
||||
OSVersion: platform.OSVersion,
|
||||
OSFeatures: platform.OSFeatures,
|
||||
Variant: arm64Variant,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// All arm64/v8.x and arm64/v9.x are compatible with arm/v8 (32-bits) and below.
|
||||
// There's no arm64 v9 variant, so it's normalized to v8.
|
||||
if strings.HasPrefix(variant, "v8") || strings.HasPrefix(variant, "v9") {
|
||||
variant = "v8"
|
||||
}
|
||||
vector = append(vector, platformVector(specs.Platform{
|
||||
Architecture: "arm",
|
||||
OS: platform.OS,
|
||||
@@ -87,6 +142,8 @@ func platformVector(platform specs.Platform) []specs.Platform {
|
||||
// Only returns a match comparer for a single platform
|
||||
// using default resolution logic for the platform.
|
||||
//
|
||||
// For arm64/v9.x, will also match arm64/v9.{0..x-1} and arm64/v8.{0..x+5}
|
||||
// For arm64/v8.x, will also match arm64/v8.{0..x-1}
|
||||
// For arm/v8, will also match arm/v7, arm/v6 and arm/v5
|
||||
// For arm/v7, will also match arm/v6 and arm/v5
|
||||
// For arm/v6, will also match arm/v5
|
||||
|
||||
4
vendor/github.com/containerd/platforms/database.go
generated
vendored
4
vendor/github.com/containerd/platforms/database.go
generated
vendored
@@ -87,8 +87,10 @@ func normalizeArch(arch, variant string) (string, string) {
|
||||
case "aarch64", "arm64":
|
||||
arch = "arm64"
|
||||
switch variant {
|
||||
case "8", "v8":
|
||||
case "8", "v8", "v8.0":
|
||||
variant = ""
|
||||
case "9", "9.0", "v9.0":
|
||||
variant = "v9"
|
||||
}
|
||||
case "armhf":
|
||||
arch = "arm"
|
||||
|
||||
76
vendor/github.com/containerd/platforms/defaults_windows.go
generated
vendored
76
vendor/github.com/containerd/platforms/defaults_windows.go
generated
vendored
@@ -19,8 +19,6 @@ package platforms
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"golang.org/x/sys/windows"
|
||||
@@ -38,80 +36,6 @@ func DefaultSpec() specs.Platform {
|
||||
}
|
||||
}
|
||||
|
||||
type windowsmatcher struct {
|
||||
specs.Platform
|
||||
osVersionPrefix string
|
||||
defaultMatcher Matcher
|
||||
}
|
||||
|
||||
// Match matches platform with the same windows major, minor
|
||||
// and build version.
|
||||
func (m windowsmatcher) Match(p specs.Platform) bool {
|
||||
match := m.defaultMatcher.Match(p)
|
||||
|
||||
if match && m.OS == "windows" {
|
||||
// HPC containers do not have OS version filled
|
||||
if m.OSVersion == "" || p.OSVersion == "" {
|
||||
return true
|
||||
}
|
||||
|
||||
hostOsVersion := getOSVersion(m.osVersionPrefix)
|
||||
ctrOsVersion := getOSVersion(p.OSVersion)
|
||||
return checkHostAndContainerCompat(hostOsVersion, ctrOsVersion)
|
||||
}
|
||||
|
||||
return match
|
||||
}
|
||||
|
||||
func getOSVersion(osVersionPrefix string) osVersion {
|
||||
parts := strings.Split(osVersionPrefix, ".")
|
||||
if len(parts) < 3 {
|
||||
return osVersion{}
|
||||
}
|
||||
|
||||
majorVersion, _ := strconv.Atoi(parts[0])
|
||||
minorVersion, _ := strconv.Atoi(parts[1])
|
||||
buildNumber, _ := strconv.Atoi(parts[2])
|
||||
|
||||
return osVersion{
|
||||
MajorVersion: uint8(majorVersion),
|
||||
MinorVersion: uint8(minorVersion),
|
||||
Build: uint16(buildNumber),
|
||||
}
|
||||
}
|
||||
|
||||
// Less sorts matched platforms in front of other platforms.
|
||||
// For matched platforms, it puts platforms with larger revision
|
||||
// number in front.
|
||||
func (m windowsmatcher) Less(p1, p2 specs.Platform) bool {
|
||||
m1, m2 := m.Match(p1), m.Match(p2)
|
||||
if m1 && m2 {
|
||||
r1, r2 := revision(p1.OSVersion), revision(p2.OSVersion)
|
||||
return r1 > r2
|
||||
}
|
||||
return m1 && !m2
|
||||
}
|
||||
|
||||
func revision(v string) int {
|
||||
parts := strings.Split(v, ".")
|
||||
if len(parts) < 4 {
|
||||
return 0
|
||||
}
|
||||
r, err := strconv.Atoi(parts[3])
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func prefix(v string) string {
|
||||
parts := strings.Split(v, ".")
|
||||
if len(parts) < 4 {
|
||||
return v
|
||||
}
|
||||
return strings.Join(parts[0:3], ".")
|
||||
}
|
||||
|
||||
// Default returns the current platform's default platform specification.
|
||||
func Default() MatchComparer {
|
||||
return Only(DefaultSpec())
|
||||
|
||||
@@ -16,9 +16,16 @@
|
||||
|
||||
package platforms
|
||||
|
||||
// osVersion is a wrapper for Windows version information
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// windowsOSVersion is a wrapper for Windows version information
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx
|
||||
type osVersion struct {
|
||||
type windowsOSVersion struct {
|
||||
Version uint32
|
||||
MajorVersion uint8
|
||||
MinorVersion uint8
|
||||
@@ -55,7 +62,7 @@ var compatLTSCReleases = []uint16{
|
||||
// Every release after WS 2022 will support the previous ltsc
|
||||
// container image. Stable ABI is in preview mode for windows 11 client.
|
||||
// Refer: https://learn.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/version-compatibility?tabs=windows-server-2022%2Cwindows-10#windows-server-host-os-compatibility
|
||||
func checkHostAndContainerCompat(host, ctr osVersion) bool {
|
||||
func checkWindowsHostAndContainerCompat(host, ctr windowsOSVersion) bool {
|
||||
// check major minor versions of host and guest
|
||||
if host.MajorVersion != ctr.MajorVersion ||
|
||||
host.MinorVersion != ctr.MinorVersion {
|
||||
@@ -76,3 +83,74 @@ func checkHostAndContainerCompat(host, ctr osVersion) bool {
|
||||
}
|
||||
return ctr.Build >= supportedLtscRelease && ctr.Build <= host.Build
|
||||
}
|
||||
|
||||
func getWindowsOSVersion(osVersionPrefix string) windowsOSVersion {
|
||||
if strings.Count(osVersionPrefix, ".") < 2 {
|
||||
return windowsOSVersion{}
|
||||
}
|
||||
|
||||
major, extra, _ := strings.Cut(osVersionPrefix, ".")
|
||||
minor, extra, _ := strings.Cut(extra, ".")
|
||||
build, _, _ := strings.Cut(extra, ".")
|
||||
|
||||
majorVersion, err := strconv.ParseUint(major, 10, 8)
|
||||
if err != nil {
|
||||
return windowsOSVersion{}
|
||||
}
|
||||
|
||||
minorVersion, err := strconv.ParseUint(minor, 10, 8)
|
||||
if err != nil {
|
||||
return windowsOSVersion{}
|
||||
}
|
||||
buildNumber, err := strconv.ParseUint(build, 10, 16)
|
||||
if err != nil {
|
||||
return windowsOSVersion{}
|
||||
}
|
||||
|
||||
return windowsOSVersion{
|
||||
MajorVersion: uint8(majorVersion),
|
||||
MinorVersion: uint8(minorVersion),
|
||||
Build: uint16(buildNumber),
|
||||
}
|
||||
}
|
||||
|
||||
func winRevision(v string) int {
|
||||
parts := strings.Split(v, ".")
|
||||
if len(parts) < 4 {
|
||||
return 0
|
||||
}
|
||||
r, err := strconv.Atoi(parts[3])
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
type windowsVersionMatcher struct {
|
||||
windowsOSVersion
|
||||
}
|
||||
|
||||
func (m windowsVersionMatcher) Match(v string) bool {
|
||||
if m.isEmpty() || v == "" {
|
||||
return true
|
||||
}
|
||||
osv := getWindowsOSVersion(v)
|
||||
return checkWindowsHostAndContainerCompat(m.windowsOSVersion, osv)
|
||||
}
|
||||
|
||||
func (m windowsVersionMatcher) isEmpty() bool {
|
||||
return m.MajorVersion == 0 && m.MinorVersion == 0 && m.Build == 0
|
||||
}
|
||||
|
||||
type windowsMatchComparer struct {
|
||||
Matcher
|
||||
}
|
||||
|
||||
func (c *windowsMatchComparer) Less(p1, p2 specs.Platform) bool {
|
||||
m1, m2 := c.Match(p1), c.Match(p2)
|
||||
if m1 && m2 {
|
||||
r1, r2 := winRevision(p1.OSVersion), winRevision(p2.OSVersion)
|
||||
return r1 > r2
|
||||
}
|
||||
return m1 && !m2
|
||||
}
|
||||
39
vendor/github.com/containerd/platforms/platforms.go
generated
vendored
39
vendor/github.com/containerd/platforms/platforms.go
generated
vendored
@@ -121,7 +121,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
specifierRe = regexp.MustCompile(`^[A-Za-z0-9_-]+$`)
|
||||
specifierRe = regexp.MustCompile(`^[A-Za-z0-9_.-]+$`)
|
||||
osAndVersionRe = regexp.MustCompile(`^([A-Za-z0-9_-]+)(?:\(([A-Za-z0-9_.-]*)\))?$`)
|
||||
)
|
||||
|
||||
@@ -144,18 +144,51 @@ type Matcher interface {
|
||||
//
|
||||
// Applications should opt to use `Match` over directly parsing specifiers.
|
||||
func NewMatcher(platform specs.Platform) Matcher {
|
||||
return newDefaultMatcher(platform)
|
||||
m := &matcher{
|
||||
Platform: Normalize(platform),
|
||||
}
|
||||
|
||||
if platform.OS == "windows" {
|
||||
m.osvM = &windowsVersionMatcher{
|
||||
windowsOSVersion: getWindowsOSVersion(platform.OSVersion),
|
||||
}
|
||||
// In prior versions, on windows, the returned matcher implements a
|
||||
// MatchComprarer interface.
|
||||
// This preserves that behavior for backwards compatibility.
|
||||
//
|
||||
// TODO: This isn't actually used in this package, except for a test case,
|
||||
// which may have been an unintended side of some refactor.
|
||||
// It was likely intended to be used in `Ordered` but it is not since
|
||||
// `Less` that is implemented here ends up getting masked due to wrapping.
|
||||
if runtime.GOOS == "windows" {
|
||||
return &windowsMatchComparer{m}
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
type osVerMatcher interface {
|
||||
Match(string) bool
|
||||
}
|
||||
|
||||
type matcher struct {
|
||||
specs.Platform
|
||||
osvM osVerMatcher
|
||||
}
|
||||
|
||||
func (m *matcher) Match(platform specs.Platform) bool {
|
||||
normalized := Normalize(platform)
|
||||
return m.OS == normalized.OS &&
|
||||
m.Architecture == normalized.Architecture &&
|
||||
m.Variant == normalized.Variant
|
||||
m.Variant == normalized.Variant &&
|
||||
m.matchOSVersion(platform)
|
||||
}
|
||||
|
||||
func (m *matcher) matchOSVersion(platform specs.Platform) bool {
|
||||
if m.osvM != nil {
|
||||
return m.osvM.Match(platform.OSVersion)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *matcher) String() string {
|
||||
|
||||
30
vendor/github.com/containerd/platforms/platforms_other.go
generated
vendored
30
vendor/github.com/containerd/platforms/platforms_other.go
generated
vendored
@@ -1,30 +0,0 @@
|
||||
//go:build !windows
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package platforms
|
||||
|
||||
import (
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// NewMatcher returns the default Matcher for containerd
|
||||
func newDefaultMatcher(platform specs.Platform) Matcher {
|
||||
return &matcher{
|
||||
Platform: Normalize(platform),
|
||||
}
|
||||
}
|
||||
34
vendor/github.com/containerd/platforms/platforms_windows.go
generated
vendored
34
vendor/github.com/containerd/platforms/platforms_windows.go
generated
vendored
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package platforms
|
||||
|
||||
import (
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// NewMatcher returns a Windows matcher that will match on osVersionPrefix if
|
||||
// the platform is Windows otherwise use the default matcher
|
||||
func newDefaultMatcher(platform specs.Platform) Matcher {
|
||||
prefix := prefix(platform.OSVersion)
|
||||
return windowsmatcher{
|
||||
Platform: platform,
|
||||
osVersionPrefix: prefix,
|
||||
defaultMatcher: &matcher{
|
||||
Platform: Normalize(platform),
|
||||
},
|
||||
}
|
||||
}
|
||||
51
vendor/github.com/containers/buildah/.cirrus.yml
generated
vendored
51
vendor/github.com/containers/buildah/.cirrus.yml
generated
vendored
@@ -9,6 +9,7 @@ env:
|
||||
DEST_BRANCH: "main"
|
||||
GOPATH: "/var/tmp/go"
|
||||
GOSRC: "${GOPATH}/src/github.com/containers/buildah"
|
||||
GOCACHE: "/tmp/go-build"
|
||||
# Overrides default location (/tmp/cirrus) for repo clone
|
||||
CIRRUS_WORKING_DIR: "${GOSRC}"
|
||||
# Shell used to execute all script commands
|
||||
@@ -32,7 +33,7 @@ env:
|
||||
DEBIAN_NAME: "debian-13"
|
||||
|
||||
# Image identifiers
|
||||
IMAGE_SUFFIX: "c20241107t210000z-f41f40d13"
|
||||
IMAGE_SUFFIX: "c20250107t132430z-f41f40d13"
|
||||
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
|
||||
PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}"
|
||||
DEBIAN_CACHE_IMAGE_NAME: "debian-${IMAGE_SUFFIX}"
|
||||
@@ -56,7 +57,7 @@ gce_instance: &standardvm
|
||||
image_project: "${IMAGE_PROJECT}"
|
||||
zone: "us-central1-c" # Required by Cirrus for the time being
|
||||
cpu: 2
|
||||
memory: "4Gb"
|
||||
memory: "4G"
|
||||
disk: 200 # Gigabytes, do not set less than 200 per obscure GCE docs re: I/O performance
|
||||
image_name: "${FEDORA_CACHE_IMAGE_NAME}"
|
||||
|
||||
@@ -69,7 +70,7 @@ meta_task:
|
||||
container:
|
||||
image: "quay.io/libpod/imgts:latest"
|
||||
cpu: 1
|
||||
memory: 1
|
||||
memory: "1G"
|
||||
|
||||
env:
|
||||
# Space-separated list of images used by this repository state
|
||||
@@ -93,10 +94,11 @@ smoke_task:
|
||||
name: "Smoke Test"
|
||||
|
||||
gce_instance:
|
||||
memory: "12Gb"
|
||||
memory: "12G"
|
||||
cpu: 4
|
||||
|
||||
# Don't bother running on branches (including cron), or for tags.
|
||||
only_if: $CIRRUS_PR != ''
|
||||
skip: $CIRRUS_PR == ''
|
||||
|
||||
timeout_in: 30m
|
||||
|
||||
@@ -135,15 +137,17 @@ vendor_task:
|
||||
# Confirm cross-compile ALL architectures on a Mac OS-X VM.
|
||||
cross_build_task:
|
||||
name: "Cross Compile"
|
||||
gce_instance:
|
||||
cpu: 8
|
||||
memory: "24G"
|
||||
alias: cross_build
|
||||
only_if: >-
|
||||
$CIRRUS_CHANGE_TITLE !=~ '.*CI:DOCS.*'
|
||||
skip: >-
|
||||
$CIRRUS_CHANGE_TITLE =~ '.*CI:DOCS.*'
|
||||
env:
|
||||
HOME: /root
|
||||
script:
|
||||
- go version
|
||||
- make cross CGO_ENABLED=0
|
||||
|
||||
- make -j cross CGO_ENABLED=0
|
||||
binary_artifacts:
|
||||
path: ./bin/*
|
||||
|
||||
@@ -151,13 +155,12 @@ cross_build_task:
|
||||
unit_task:
|
||||
name: 'Unit tests w/ $STORAGE_DRIVER'
|
||||
alias: unit
|
||||
only_if: ¬_build_docs >-
|
||||
$CIRRUS_CHANGE_TITLE !=~ '.*CI:DOCS.*' &&
|
||||
$CIRRUS_CHANGE_TITLE !=~ '.*CI:BUILD.*'
|
||||
depends_on: &smoke_vendor_cross
|
||||
skip: ¬_build_docs >-
|
||||
$CIRRUS_CHANGE_TITLE =~ '.*CI:DOCS.*' ||
|
||||
$CIRRUS_CHANGE_TITLE =~ '.*CI:BUILD.*'
|
||||
depends_on: &smoke_vendor
|
||||
- smoke
|
||||
- vendor
|
||||
- cross_build
|
||||
|
||||
timeout_in: 90m
|
||||
|
||||
@@ -168,18 +171,14 @@ unit_task:
|
||||
STORAGE_DRIVER: 'overlay'
|
||||
|
||||
setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}'
|
||||
build_script: '${SCRIPT_BASE}/build.sh |& ${_TIMESTAMP}'
|
||||
unit_test_script: '${SCRIPT_BASE}/test.sh unit |& ${_TIMESTAMP}'
|
||||
|
||||
binary_artifacts:
|
||||
path: ./bin/*
|
||||
|
||||
|
||||
conformance_task:
|
||||
name: 'Debian Conformance w/ $STORAGE_DRIVER'
|
||||
alias: conformance
|
||||
only_if: *not_build_docs
|
||||
depends_on: *smoke_vendor_cross
|
||||
skip: *not_build_docs
|
||||
depends_on: *smoke_vendor
|
||||
|
||||
gce_instance:
|
||||
image_name: "${DEBIAN_CACHE_IMAGE_NAME}"
|
||||
@@ -200,8 +199,8 @@ conformance_task:
|
||||
integration_task:
|
||||
name: "Integration $DISTRO_NV w/ $STORAGE_DRIVER"
|
||||
alias: integration
|
||||
only_if: *not_build_docs
|
||||
depends_on: *smoke_vendor_cross
|
||||
skip: *not_build_docs
|
||||
depends_on: *smoke_vendor
|
||||
|
||||
matrix:
|
||||
# VFS
|
||||
@@ -257,8 +256,8 @@ integration_task:
|
||||
integration_rootless_task:
|
||||
name: "Integration rootless $DISTRO_NV w/ $STORAGE_DRIVER"
|
||||
alias: integration_rootless
|
||||
only_if: *not_build_docs
|
||||
depends_on: *smoke_vendor_cross
|
||||
skip: *not_build_docs
|
||||
depends_on: *smoke_vendor
|
||||
|
||||
matrix:
|
||||
# Running rootless tests on overlay
|
||||
@@ -297,8 +296,8 @@ integration_rootless_task:
|
||||
in_podman_task:
|
||||
name: "Containerized Integration"
|
||||
alias: in_podman
|
||||
only_if: *not_build_docs
|
||||
depends_on: *smoke_vendor_cross
|
||||
skip: *not_build_docs
|
||||
depends_on: *smoke_vendor
|
||||
|
||||
env:
|
||||
# This is key, cause the scripts to re-execute themselves inside a container.
|
||||
|
||||
22
vendor/github.com/containers/buildah/.packit.yaml
generated
vendored
22
vendor/github.com/containers/buildah/.packit.yaml
generated
vendored
@@ -12,8 +12,6 @@ packages:
|
||||
buildah-centos:
|
||||
pkg_tool: centpkg
|
||||
specfile_path: rpm/buildah.spec
|
||||
buildah-rhel:
|
||||
specfile_path: rpm/buildah.spec
|
||||
buildah-eln:
|
||||
specfile_path: rpm/buildah.spec
|
||||
|
||||
@@ -28,14 +26,8 @@ jobs:
|
||||
failure_comment:
|
||||
message: "Ephemeral COPR build failed. @containers/packit-build please check."
|
||||
targets:
|
||||
- fedora-development-x86_64
|
||||
- fedora-development-aarch64
|
||||
- fedora-latest-x86_64
|
||||
- fedora-latest-aarch64
|
||||
- fedora-latest-stable-x86_64
|
||||
- fedora-latest-stable-aarch64
|
||||
- fedora-40-x86_64
|
||||
- fedora-40-aarch64
|
||||
- fedora-all-x86_64
|
||||
- fedora-all-aarch64
|
||||
enable_net: true
|
||||
|
||||
- job: copr_build
|
||||
@@ -62,16 +54,6 @@ jobs:
|
||||
- centos-stream-10-aarch64
|
||||
enable_net: true
|
||||
|
||||
# Disabled until there is go 1.22 in epel-9
|
||||
# - job: copr_build
|
||||
# trigger: pull_request
|
||||
# packages: [buildah-rhel]
|
||||
# notifications: *copr_build_failure_notification
|
||||
# targets:
|
||||
# - epel-9-x86_64
|
||||
# - epel-9-aarch64
|
||||
# enable_net: true
|
||||
|
||||
# Run on commit to main branch
|
||||
- job: copr_build
|
||||
trigger: commit
|
||||
|
||||
2
vendor/github.com/containers/buildah/CHANGELOG.md
generated
vendored
2
vendor/github.com/containers/buildah/CHANGELOG.md
generated
vendored
@@ -123,7 +123,7 @@
|
||||
Add PrependedLinkedLayers/AppendedLinkedLayers to CommitOptions
|
||||
integration tests: teach starthttpd() about TLS and pid files
|
||||
|
||||
## vv1.37.0 (2024-07-26)
|
||||
## v1.37.0 (2024-07-26)
|
||||
|
||||
Bump c/storage, c/image, c/common for v1.37.0
|
||||
"build with basename resolving user arg" tests: correct ARG use
|
||||
|
||||
18
vendor/github.com/containers/buildah/Makefile
generated
vendored
18
vendor/github.com/containers/buildah/Makefile
generated
vendored
@@ -38,7 +38,12 @@ CNI_COMMIT := $(shell sed -n 's;^$(COMMENT) github.com/containernetworking/cni \
|
||||
|
||||
EXTRA_LDFLAGS ?=
|
||||
BUILDAH_LDFLAGS := $(GO_LDFLAGS) '-X main.GitCommit=$(GIT_COMMIT) -X main.buildInfo=$(SOURCE_DATE_EPOCH) -X main.cniVersion=$(CNI_COMMIT) $(EXTRA_LDFLAGS)'
|
||||
SOURCES=*.go imagebuildah/*.go bind/*.go chroot/*.go copier/*.go define/*.go docker/*.go internal/config/*.go internal/mkcw/*.go internal/mkcw/types/*.go internal/parse/*.go internal/sbom/*.go internal/source/*.go internal/tmpdir/*.go internal/*.go internal/util/*.go internal/volumes/*.go manifests/*.go pkg/binfmt/*.go pkg/blobcache/*.go pkg/chrootuser/*.go pkg/cli/*.go pkg/completion/*.go pkg/formats/*.go pkg/jail/*.go pkg/overlay/*.go pkg/parse/*.go pkg/rusage/*.go pkg/sshagent/*.go pkg/umask/*.go pkg/util/*.go pkg/volumes/*.go util/*.go
|
||||
|
||||
# This isn't what we actually build; it's a superset, used for target
|
||||
# dependencies. Basically: all *.go and *.c files, except *_test.go,
|
||||
# and except anything in a dot subdirectory. If any of these files is
|
||||
# newer than our target (bin/buildah), a rebuild is triggered.
|
||||
SOURCES=$(shell find . -path './.*' -prune -o \( \( -name '*.go' -o -name '*.c' \) -a ! -name '*_test.go' \) -print)
|
||||
|
||||
LINTFLAGS ?=
|
||||
|
||||
@@ -68,7 +73,7 @@ static:
|
||||
mkdir -p ./bin
|
||||
cp -rfp ./result/bin/* ./bin/
|
||||
|
||||
bin/buildah: $(SOURCES) cmd/buildah/*.go internal/mkcw/embed/entrypoint_amd64.gz
|
||||
bin/buildah: $(SOURCES) internal/mkcw/embed/entrypoint_amd64.gz
|
||||
$(GO_BUILD) $(BUILDAH_LDFLAGS) $(GO_GCFLAGS) "$(GOGCFLAGS)" -o $@ $(BUILDFLAGS) ./cmd/buildah
|
||||
test -z "${SELINUXOPT}" || chcon --verbose -t $(SELINUXTYPE) $@
|
||||
|
||||
@@ -94,17 +99,17 @@ FREEBSD_CROSS_TARGETS := $(filter bin/buildah.freebsd.%,$(ALL_CROSS_TARGETS))
|
||||
.PHONY: cross
|
||||
cross: $(LINUX_CROSS_TARGETS) $(DARWIN_CROSS_TARGETS) $(WINDOWS_CROSS_TARGETS) $(FREEBSD_CROSS_TARGETS)
|
||||
|
||||
bin/buildah.%:
|
||||
bin/buildah.%: $(SOURCES)
|
||||
mkdir -p ./bin
|
||||
GOOS=$(word 2,$(subst ., ,$@)) GOARCH=$(word 3,$(subst ., ,$@)) $(GO_BUILD) $(BUILDAH_LDFLAGS) -o $@ -tags "containers_image_openpgp" ./cmd/buildah
|
||||
|
||||
bin/imgtype: $(SOURCES) tests/imgtype/imgtype.go
|
||||
bin/imgtype: $(SOURCES)
|
||||
$(GO_BUILD) $(BUILDAH_LDFLAGS) -o $@ $(BUILDFLAGS) ./tests/imgtype/imgtype.go
|
||||
|
||||
bin/copy: $(SOURCES) tests/copy/copy.go
|
||||
bin/copy: $(SOURCES)
|
||||
$(GO_BUILD) $(BUILDAH_LDFLAGS) -o $@ $(BUILDFLAGS) ./tests/copy/copy.go
|
||||
|
||||
bin/tutorial: $(SOURCES) tests/tutorial/tutorial.go
|
||||
bin/tutorial: $(SOURCES)
|
||||
$(GO_BUILD) $(BUILDAH_LDFLAGS) -o $@ $(BUILDFLAGS) ./tests/tutorial/tutorial.go
|
||||
|
||||
bin/inet: tests/inet/inet.go
|
||||
@@ -127,7 +132,6 @@ validate: install.tools
|
||||
./tests/validate/whitespace.sh
|
||||
./hack/xref-helpmsgs-manpages
|
||||
./tests/validate/pr-should-include-tests
|
||||
./hack/makefile_sources
|
||||
|
||||
.PHONY: install.tools
|
||||
install.tools:
|
||||
|
||||
7
vendor/github.com/containers/buildah/add.go
generated
vendored
7
vendor/github.com/containers/buildah/add.go
generated
vendored
@@ -495,8 +495,8 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
|
||||
wg.Add(1)
|
||||
if sourceIsGit(src) {
|
||||
go func() {
|
||||
var cloneDir string
|
||||
cloneDir, _, getErr = define.TempDirForURL(tmpdir.GetTempDir(), "", src)
|
||||
var cloneDir, subdir string
|
||||
cloneDir, subdir, getErr = define.TempDirForURL(tmpdir.GetTempDir(), "", src)
|
||||
getOptions := copier.GetOptions{
|
||||
UIDMap: srcUIDMap,
|
||||
GIDMap: srcGIDMap,
|
||||
@@ -511,7 +511,8 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption
|
||||
StripStickyBit: options.StripStickyBit,
|
||||
}
|
||||
writer := io.WriteCloser(pipeWriter)
|
||||
getErr = copier.Get(cloneDir, cloneDir, getOptions, []string{"."}, writer)
|
||||
repositoryDir := filepath.Join(cloneDir, subdir)
|
||||
getErr = copier.Get(repositoryDir, repositoryDir, getOptions, []string{"."}, writer)
|
||||
pipeWriter.Close()
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
2
vendor/github.com/containers/buildah/bind/mount.go
generated
vendored
2
vendor/github.com/containers/buildah/bind/mount.go
generated
vendored
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"syscall"
|
||||
|
||||
"github.com/containers/buildah/util"
|
||||
@@ -14,7 +15,6 @@ import (
|
||||
"github.com/containers/storage/pkg/mount"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/slices"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
|
||||
3
vendor/github.com/containers/buildah/bind/util.go
generated
vendored
3
vendor/github.com/containers/buildah/bind/util.go
generated
vendored
@@ -1,8 +1,9 @@
|
||||
package bind
|
||||
|
||||
import (
|
||||
"slices"
|
||||
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
2
vendor/github.com/containers/buildah/changelog.txt
generated
vendored
2
vendor/github.com/containers/buildah/changelog.txt
generated
vendored
@@ -118,7 +118,7 @@
|
||||
* Add PrependedLinkedLayers/AppendedLinkedLayers to CommitOptions
|
||||
* integration tests: teach starthttpd() about TLS and pid files
|
||||
|
||||
- Changelog for vv1.37.0 (2024-07-26)
|
||||
- Changelog for v1.37.0 (2024-07-26)
|
||||
* Bump c/storage, c/image, c/common for v1.37.0
|
||||
* "build with basename resolving user arg" tests: correct ARG use
|
||||
* bud-multiple-platform-no-run test: correct ARG use
|
||||
|
||||
14
vendor/github.com/containers/buildah/chroot/run_common.go
generated
vendored
14
vendor/github.com/containers/buildah/chroot/run_common.go
generated
vendored
@@ -48,12 +48,13 @@ func init() {
|
||||
type runUsingChrootExecSubprocOptions struct {
|
||||
Spec *specs.Spec
|
||||
BundlePath string
|
||||
NoPivot bool
|
||||
}
|
||||
|
||||
// RunUsingChroot runs a chrooted process, using some of the settings from the
|
||||
// passed-in spec, and using the specified bundlePath to hold temporary files,
|
||||
// directories, and mountpoints.
|
||||
func RunUsingChroot(spec *specs.Spec, bundlePath, homeDir string, stdin io.Reader, stdout, stderr io.Writer) (err error) {
|
||||
func RunUsingChroot(spec *specs.Spec, bundlePath, homeDir string, stdin io.Reader, stdout, stderr io.Writer, noPivot bool) (err error) {
|
||||
var confwg sync.WaitGroup
|
||||
var homeFound bool
|
||||
for _, env := range spec.Process.Env {
|
||||
@@ -97,6 +98,7 @@ func RunUsingChroot(spec *specs.Spec, bundlePath, homeDir string, stdin io.Reade
|
||||
config, conferr := json.Marshal(runUsingChrootSubprocOptions{
|
||||
Spec: spec,
|
||||
BundlePath: bundlePath,
|
||||
NoPivot: noPivot,
|
||||
})
|
||||
if conferr != nil {
|
||||
return fmt.Errorf("encoding configuration for %q: %w", runUsingChrootCommand, conferr)
|
||||
@@ -196,6 +198,7 @@ func runUsingChrootMain() {
|
||||
fmt.Fprintf(os.Stderr, "invalid options spec in runUsingChrootMain\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
noPivot := options.NoPivot
|
||||
|
||||
// Prepare to shuttle stdio back and forth.
|
||||
rootUID32, rootGID32, err := util.GetHostRootIDs(options.Spec)
|
||||
@@ -442,7 +445,7 @@ func runUsingChrootMain() {
|
||||
}()
|
||||
|
||||
// Set up mounts and namespaces, and run the parent subprocess.
|
||||
status, err := runUsingChroot(options.Spec, options.BundlePath, ctty, stdin, stdout, stderr, closeOnceRunning)
|
||||
status, err := runUsingChroot(options.Spec, options.BundlePath, ctty, stdin, stdout, stderr, noPivot, closeOnceRunning)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error running subprocess: %v\n", err)
|
||||
os.Exit(1)
|
||||
@@ -463,7 +466,7 @@ func runUsingChrootMain() {
|
||||
// runUsingChroot, still in the grandparent process, sets up various bind
|
||||
// mounts and then runs the parent process in its own user namespace with the
|
||||
// necessary ID mappings.
|
||||
func runUsingChroot(spec *specs.Spec, bundlePath string, ctty *os.File, stdin io.Reader, stdout, stderr io.Writer, closeOnceRunning []*os.File) (wstatus unix.WaitStatus, err error) {
|
||||
func runUsingChroot(spec *specs.Spec, bundlePath string, ctty *os.File, stdin io.Reader, stdout, stderr io.Writer, noPivot bool, closeOnceRunning []*os.File) (wstatus unix.WaitStatus, err error) {
|
||||
var confwg sync.WaitGroup
|
||||
|
||||
// Create a new mount namespace for ourselves and bind mount everything to a new location.
|
||||
@@ -496,6 +499,7 @@ func runUsingChroot(spec *specs.Spec, bundlePath string, ctty *os.File, stdin io
|
||||
config, conferr := json.Marshal(runUsingChrootExecSubprocOptions{
|
||||
Spec: spec,
|
||||
BundlePath: bundlePath,
|
||||
NoPivot: noPivot,
|
||||
})
|
||||
if conferr != nil {
|
||||
fmt.Fprintf(os.Stderr, "error re-encoding configuration for %q\n", runUsingChrootExecCommand)
|
||||
@@ -619,8 +623,10 @@ func runUsingChrootExecMain() {
|
||||
// Try to chroot into the root. Do this before we potentially
|
||||
// block the syscall via the seccomp profile. Allow the
|
||||
// platform to override this - on FreeBSD, we use a simple
|
||||
// jail to set the hostname in the container
|
||||
// jail to set the hostname in the container, and on Linux
|
||||
// we attempt to pivot_root.
|
||||
if err := createPlatformContainer(options); err != nil {
|
||||
logrus.Debugf("createPlatformContainer: %v", err)
|
||||
var oldst, newst unix.Stat_t
|
||||
if err := unix.Stat(options.Spec.Root.Path, &oldst); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error stat()ing intended root directory %q: %v\n", options.Spec.Root.Path, err)
|
||||
|
||||
1
vendor/github.com/containers/buildah/chroot/run_freebsd.go
generated
vendored
1
vendor/github.com/containers/buildah/chroot/run_freebsd.go
generated
vendored
@@ -41,6 +41,7 @@ var (
|
||||
type runUsingChrootSubprocOptions struct {
|
||||
Spec *specs.Spec
|
||||
BundlePath string
|
||||
NoPivot bool
|
||||
}
|
||||
|
||||
func setPlatformUnshareOptions(spec *specs.Spec, cmd *unshare.Cmd) error {
|
||||
|
||||
54
vendor/github.com/containers/buildah/chroot/run_linux.go
generated
vendored
54
vendor/github.com/containers/buildah/chroot/run_linux.go
generated
vendored
@@ -47,6 +47,7 @@ var (
|
||||
type runUsingChrootSubprocOptions struct {
|
||||
Spec *specs.Spec
|
||||
BundlePath string
|
||||
NoPivot bool
|
||||
UIDMappings []syscall.SysProcIDMap
|
||||
GIDMappings []syscall.SysProcIDMap
|
||||
}
|
||||
@@ -224,8 +225,57 @@ func makeRlimit(limit specs.POSIXRlimit) unix.Rlimit {
|
||||
return unix.Rlimit{Cur: limit.Soft, Max: limit.Hard}
|
||||
}
|
||||
|
||||
func createPlatformContainer(_ runUsingChrootExecSubprocOptions) error {
|
||||
return errors.New("unsupported createPlatformContainer")
|
||||
func createPlatformContainer(options runUsingChrootExecSubprocOptions) error {
|
||||
if options.NoPivot {
|
||||
return errors.New("not using pivot_root()")
|
||||
}
|
||||
// borrowing a technique from runc, who credit the LXC maintainers for this
|
||||
// open descriptors for the old and new root directories so that we can use fchdir()
|
||||
oldRootFd, err := unix.Open("/", unix.O_DIRECTORY, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("opening host root directory: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if err := unix.Close(oldRootFd); err != nil {
|
||||
logrus.Warnf("closing host root directory: %v", err)
|
||||
}
|
||||
}()
|
||||
newRootFd, err := unix.Open(options.Spec.Root.Path, unix.O_DIRECTORY, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("opening container root directory: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if err := unix.Close(newRootFd); err != nil {
|
||||
logrus.Warnf("closing container root directory: %v", err)
|
||||
}
|
||||
}()
|
||||
// change to the new root directory
|
||||
if err := unix.Fchdir(newRootFd); err != nil {
|
||||
return fmt.Errorf("changing to container root directory: %w", err)
|
||||
}
|
||||
// this makes the current directory the root directory. not actually
|
||||
// sure what happens to the other one
|
||||
if err := unix.PivotRoot(".", "."); err != nil {
|
||||
return fmt.Errorf("pivot_root: %w", err)
|
||||
}
|
||||
// go back and clean up the old one
|
||||
if err := unix.Fchdir(oldRootFd); err != nil {
|
||||
return fmt.Errorf("changing to host root directory: %w", err)
|
||||
}
|
||||
// make sure we only unmount things under this tree
|
||||
if err := unix.Mount(".", ".", "bind", unix.MS_BIND|unix.MS_SLAVE|unix.MS_REC, ""); err != nil {
|
||||
return fmt.Errorf("tweaking mount flags on host root directory before unmounting from mount namespace: %w", err)
|
||||
}
|
||||
// detach this (unnamed?) old directory
|
||||
if err := unix.Unmount(".", unix.MNT_DETACH); err != nil {
|
||||
return fmt.Errorf("unmounting host root directory in mount namespace: %w", err)
|
||||
}
|
||||
// go back to a named root directory
|
||||
if err := unix.Fchdir(newRootFd); err != nil {
|
||||
return fmt.Errorf("changing to container root directory at last: %w", err)
|
||||
}
|
||||
logrus.Debugf("pivot_root()ed into %q", options.Spec.Root.Path)
|
||||
return nil
|
||||
}
|
||||
|
||||
func mountFlagsForFSFlags(fsFlags uintptr) uintptr {
|
||||
|
||||
2
vendor/github.com/containers/buildah/commit.go
generated
vendored
2
vendor/github.com/containers/buildah/commit.go
generated
vendored
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"maps"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -26,7 +27,6 @@ import (
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/maps"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
4
vendor/github.com/containers/buildah/config.go
generated
vendored
4
vendor/github.com/containers/buildah/config.go
generated
vendored
@@ -4,8 +4,10 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"maps"
|
||||
"os"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -19,8 +21,6 @@ import (
|
||||
"github.com/containers/storage/pkg/stringid"
|
||||
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/maps"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
// unmarshalConvertedConfig obtains the config blob of img valid for the wantedManifestMIMEType format
|
||||
|
||||
33
vendor/github.com/containers/buildah/copier/copier.go
generated
vendored
33
vendor/github.com/containers/buildah/copier/copier.go
generated
vendored
@@ -35,6 +35,8 @@ const (
|
||||
cISUID = 0o4000 // Set uid, from archive/tar
|
||||
cISGID = 0o2000 // Set gid, from archive/tar
|
||||
cISVTX = 0o1000 // Save text (sticky bit), from archive/tar
|
||||
// xattrs in the PAXRecords map are namespaced with this prefix
|
||||
xattrPAXRecordNamespace = "SCHILY.xattr."
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -711,7 +713,7 @@ func copierWithSubprocess(bulkReader io.Reader, bulkWriter io.Writer, req reques
|
||||
return nil, fmt.Errorf("%v: %w", step, err)
|
||||
}
|
||||
if err = encoder.Encode(req); err != nil {
|
||||
return killAndReturn(err, "error encoding request for copier subprocess")
|
||||
return killAndReturn(err, "error encoding work request for copier subprocess")
|
||||
}
|
||||
if err = decoder.Decode(&resp); err != nil {
|
||||
if errors.Is(err, io.EOF) && errorBuffer.Len() > 0 {
|
||||
@@ -720,7 +722,7 @@ func copierWithSubprocess(bulkReader io.Reader, bulkWriter io.Writer, req reques
|
||||
return killAndReturn(err, "error decoding response from copier subprocess")
|
||||
}
|
||||
if err = encoder.Encode(&request{Request: requestQuit}); err != nil {
|
||||
return killAndReturn(err, "error encoding request for copier subprocess")
|
||||
return killAndReturn(err, "error encoding quit request for copier subprocess")
|
||||
}
|
||||
stdinWrite.Close()
|
||||
stdinWrite = nil
|
||||
@@ -1427,6 +1429,23 @@ func handleRename(rename map[string]string, name string) string {
|
||||
return name
|
||||
}
|
||||
|
||||
// mapWithPrefixedKeysWithoutKeyPrefix returns a map containing every element
|
||||
// of m that had p as a prefix in its (string) key, with that prefix stripped
|
||||
// from its key. items are shallow-copied using assignment. if m is nil, the
|
||||
// returned map will be nil, otherwise it will at least have been allocated
|
||||
func mapWithPrefixedKeysWithoutKeyPrefix[K any](m map[string]K, p string) map[string]K {
|
||||
if m == nil {
|
||||
return m
|
||||
}
|
||||
cloned := make(map[string]K, len(m))
|
||||
for k, v := range m {
|
||||
if strings.HasPrefix(k, p) {
|
||||
cloned[strings.TrimPrefix(k, p)] = v
|
||||
}
|
||||
}
|
||||
return cloned
|
||||
}
|
||||
|
||||
func copierHandlerGetOne(srcfi os.FileInfo, symlinkTarget, name, contentPath string, options GetOptions, tw *tar.Writer, hardlinkChecker *hardlinkChecker, idMappings *idtools.IDMappings) error {
|
||||
// build the header using the name provided
|
||||
hdr, err := tar.FileInfoHeader(srcfi, symlinkTarget)
|
||||
@@ -1455,8 +1474,13 @@ func copierHandlerGetOne(srcfi os.FileInfo, symlinkTarget, name, contentPath str
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting extended attributes for %q: %w", contentPath, err)
|
||||
}
|
||||
if len(xattrs) > 0 && hdr.PAXRecords == nil {
|
||||
hdr.PAXRecords = make(map[string]string, len(xattrs))
|
||||
}
|
||||
}
|
||||
for k, v := range xattrs {
|
||||
hdr.PAXRecords[xattrPAXRecordNamespace+k] = v
|
||||
}
|
||||
hdr.Xattrs = xattrs // nolint:staticcheck
|
||||
if hdr.Typeflag == tar.TypeReg {
|
||||
// if it's an archive and we're extracting archives, read the
|
||||
// file and spool out its contents in-line. (if we just
|
||||
@@ -1959,7 +1983,8 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM
|
||||
}
|
||||
// set xattrs, including some that might have been reset by chown()
|
||||
if !req.PutOptions.StripXattrs {
|
||||
if err = Lsetxattrs(path, hdr.Xattrs); err != nil { // nolint:staticcheck
|
||||
xattrs := mapWithPrefixedKeysWithoutKeyPrefix(hdr.PAXRecords, xattrPAXRecordNamespace)
|
||||
if err = Lsetxattrs(path, xattrs); err != nil { // nolint:staticcheck
|
||||
if !req.PutOptions.IgnoreXattrErrors {
|
||||
return fmt.Errorf("copier: put: error setting extended attributes on %q: %w", path, err)
|
||||
}
|
||||
|
||||
4
vendor/github.com/containers/buildah/define/build.go
generated
vendored
4
vendor/github.com/containers/buildah/define/build.go
generated
vendored
@@ -62,6 +62,8 @@ type CommonBuildOptions struct {
|
||||
// LabelOpts is a slice of the fields of an SELinux context, given in "field:pair" format, or "disable".
|
||||
// Recognized field names are "role", "type", and "level".
|
||||
LabelOpts []string
|
||||
// Paths to mask
|
||||
Masks []string
|
||||
// MemorySwap limits the amount of memory and swap together.
|
||||
MemorySwap int64
|
||||
// NoHostname tells the builder not to create /etc/hostname content when running
|
||||
@@ -109,6 +111,8 @@ type CommonBuildOptions struct {
|
||||
SSHSources []string
|
||||
// OCIHooksDir is the location of OCI hooks for the build containers
|
||||
OCIHooksDir []string
|
||||
// Paths to unmask
|
||||
Unmasks []string
|
||||
}
|
||||
|
||||
// BuildOptions can be used to alter how an image is built.
|
||||
|
||||
40
vendor/github.com/containers/buildah/define/types.go
generated
vendored
40
vendor/github.com/containers/buildah/define/types.go
generated
vendored
@@ -169,13 +169,13 @@ type SBOMScanOptions struct {
|
||||
MergeStrategy SBOMMergeStrategy // how to merge the outputs of multiple scans
|
||||
}
|
||||
|
||||
// TempDirForURL checks if the passed-in string looks like a URL or -. If it is,
|
||||
// TempDirForURL creates a temporary directory, arranges for its contents to be
|
||||
// the contents of that URL, and returns the temporary directory's path, along
|
||||
// with the name of a subdirectory which should be used as the build context
|
||||
// (which may be empty or "."). Removal of the temporary directory is the
|
||||
// responsibility of the caller. If the string doesn't look like a URL,
|
||||
// TempDirForURL returns empty strings and a nil error code.
|
||||
// TempDirForURL checks if the passed-in string looks like a URL or "-". If it
|
||||
// is, TempDirForURL creates a temporary directory, arranges for its contents
|
||||
// to be the contents of that URL, and returns the temporary directory's path,
|
||||
// along with the relative name of a subdirectory which should be used as the
|
||||
// build context (which may be empty or "."). Removal of the temporary
|
||||
// directory is the responsibility of the caller. If the string doesn't look
|
||||
// like a URL or "-", TempDirForURL returns empty strings and a nil error code.
|
||||
func TempDirForURL(dir, prefix, url string) (name string, subdir string, err error) {
|
||||
if !strings.HasPrefix(url, "http://") &&
|
||||
!strings.HasPrefix(url, "https://") &&
|
||||
@@ -188,19 +188,24 @@ func TempDirForURL(dir, prefix, url string) (name string, subdir string, err err
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("creating temporary directory for %q: %w", url, err)
|
||||
}
|
||||
downloadDir := filepath.Join(name, "download")
|
||||
if err = os.MkdirAll(downloadDir, 0o700); err != nil {
|
||||
return "", "", fmt.Errorf("creating directory %q for %q: %w", downloadDir, url, err)
|
||||
}
|
||||
urlParsed, err := urlpkg.Parse(url)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("parsing url %q: %w", url, err)
|
||||
}
|
||||
if strings.HasPrefix(url, "git://") || strings.HasSuffix(urlParsed.Path, ".git") {
|
||||
combinedOutput, gitSubDir, err := cloneToDirectory(url, name)
|
||||
combinedOutput, gitSubDir, err := cloneToDirectory(url, downloadDir)
|
||||
if err != nil {
|
||||
if err2 := os.RemoveAll(name); err2 != nil {
|
||||
logrus.Debugf("error removing temporary directory %q: %v", name, err2)
|
||||
}
|
||||
return "", "", fmt.Errorf("cloning %q to %q:\n%s: %w", url, name, string(combinedOutput), err)
|
||||
}
|
||||
return name, gitSubDir, nil
|
||||
logrus.Debugf("Build context is at %q", filepath.Join(downloadDir, gitSubDir))
|
||||
return name, filepath.Join(filepath.Base(downloadDir), gitSubDir), nil
|
||||
}
|
||||
if strings.HasPrefix(url, "github.com/") {
|
||||
ghurl := url
|
||||
@@ -209,28 +214,29 @@ func TempDirForURL(dir, prefix, url string) (name string, subdir string, err err
|
||||
subdir = path.Base(ghurl) + "-master"
|
||||
}
|
||||
if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {
|
||||
err = downloadToDirectory(url, name)
|
||||
err = downloadToDirectory(url, downloadDir)
|
||||
if err != nil {
|
||||
if err2 := os.RemoveAll(name); err2 != nil {
|
||||
logrus.Debugf("error removing temporary directory %q: %v", name, err2)
|
||||
}
|
||||
return "", subdir, err
|
||||
return "", "", err
|
||||
}
|
||||
return name, subdir, nil
|
||||
logrus.Debugf("Build context is at %q", filepath.Join(downloadDir, subdir))
|
||||
return name, filepath.Join(filepath.Base(downloadDir), subdir), nil
|
||||
}
|
||||
if url == "-" {
|
||||
err = stdinToDirectory(name)
|
||||
err = stdinToDirectory(downloadDir)
|
||||
if err != nil {
|
||||
if err2 := os.RemoveAll(name); err2 != nil {
|
||||
logrus.Debugf("error removing temporary directory %q: %v", name, err2)
|
||||
}
|
||||
return "", subdir, err
|
||||
return "", "", err
|
||||
}
|
||||
logrus.Debugf("Build context is at %q", name)
|
||||
return name, subdir, nil
|
||||
logrus.Debugf("Build context is at %q", filepath.Join(downloadDir, subdir))
|
||||
return name, filepath.Join(filepath.Base(downloadDir), subdir), nil
|
||||
}
|
||||
logrus.Debugf("don't know how to retrieve %q", url)
|
||||
if err2 := os.Remove(name); err2 != nil {
|
||||
if err2 := os.RemoveAll(name); err2 != nil {
|
||||
logrus.Debugf("error removing temporary directory %q: %v", name, err2)
|
||||
}
|
||||
return "", "", errors.New("unreachable code reached")
|
||||
|
||||
4
vendor/github.com/containers/buildah/image.go
generated
vendored
4
vendor/github.com/containers/buildah/image.go
generated
vendored
@@ -8,8 +8,10 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"maps"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -33,8 +35,6 @@ import (
|
||||
specs "github.com/opencontainers/image-spec/specs-go"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/maps"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
4
vendor/github.com/containers/buildah/imagebuildah/build.go
generated
vendored
4
vendor/github.com/containers/buildah/imagebuildah/build.go
generated
vendored
@@ -7,11 +7,13 @@ import (
|
||||
"fmt"
|
||||
gotypes "go/types"
|
||||
"io"
|
||||
"maps"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -38,8 +40,6 @@ import (
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/openshift/imagebuilder"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/maps"
|
||||
"golang.org/x/exp/slices"
|
||||
"golang.org/x/sync/semaphore"
|
||||
)
|
||||
|
||||
|
||||
5
vendor/github.com/containers/buildah/imagebuildah/executor.go
generated
vendored
5
vendor/github.com/containers/buildah/imagebuildah/executor.go
generated
vendored
@@ -6,7 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -35,7 +35,6 @@ import (
|
||||
"github.com/openshift/imagebuilder"
|
||||
"github.com/openshift/imagebuilder/dockerfile/parser"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/slices"
|
||||
"golang.org/x/sync/semaphore"
|
||||
)
|
||||
|
||||
@@ -1015,7 +1014,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
|
||||
for k := range b.unusedArgs {
|
||||
unusedList = append(unusedList, k)
|
||||
}
|
||||
sort.Strings(unusedList)
|
||||
slices.Sort(unusedList)
|
||||
fmt.Fprintf(b.out, "[Warning] one or more build args were not consumed: %v\n", unusedList)
|
||||
}
|
||||
|
||||
|
||||
166
vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
generated
vendored
166
vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
generated
vendored
@@ -9,7 +9,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -44,7 +44,6 @@ import (
|
||||
"github.com/openshift/imagebuilder/dockerfile/command"
|
||||
"github.com/openshift/imagebuilder/dockerfile/parser"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
// StageExecutor bundles up what we need to know when executing one stage of a
|
||||
@@ -639,7 +638,12 @@ func (s *StageExecutor) runStageMountPoints(mountList []string) (map[string]inte
|
||||
// to `mountPoint` replaced from additional
|
||||
// build-context. Reason: Parser will use this
|
||||
// `from` to refer from stageMountPoints map later.
|
||||
stageMountPoints[from] = internal.StageMountDetails{IsStage: false, DidExecute: true, MountPoint: mountPoint}
|
||||
stageMountPoints[from] = internal.StageMountDetails{
|
||||
IsAdditionalBuildContext: true,
|
||||
IsImage: true,
|
||||
DidExecute: true,
|
||||
MountPoint: mountPoint,
|
||||
}
|
||||
break
|
||||
}
|
||||
// Most likely this points to path on filesystem
|
||||
@@ -671,7 +675,11 @@ func (s *StageExecutor) runStageMountPoints(mountList []string) (map[string]inte
|
||||
mountPoint = additionalBuildContext.DownloadedCache
|
||||
}
|
||||
}
|
||||
stageMountPoints[from] = internal.StageMountDetails{IsStage: true, DidExecute: true, MountPoint: mountPoint}
|
||||
stageMountPoints[from] = internal.StageMountDetails{
|
||||
IsAdditionalBuildContext: true,
|
||||
DidExecute: true,
|
||||
MountPoint: mountPoint,
|
||||
}
|
||||
break
|
||||
}
|
||||
// If the source's name corresponds to the
|
||||
@@ -683,7 +691,11 @@ func (s *StageExecutor) runStageMountPoints(mountList []string) (map[string]inte
|
||||
// If the source's name is a stage, return a
|
||||
// pointer to its rootfs.
|
||||
if otherStage, ok := s.executor.stages[from]; ok && otherStage.index < s.index {
|
||||
stageMountPoints[from] = internal.StageMountDetails{IsStage: true, DidExecute: otherStage.didExecute, MountPoint: otherStage.mountPoint}
|
||||
stageMountPoints[from] = internal.StageMountDetails{
|
||||
IsStage: true,
|
||||
DidExecute: otherStage.didExecute,
|
||||
MountPoint: otherStage.mountPoint,
|
||||
}
|
||||
break
|
||||
} else {
|
||||
// Treat the source's name as the name of an image.
|
||||
@@ -691,7 +703,11 @@ func (s *StageExecutor) runStageMountPoints(mountList []string) (map[string]inte
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s from=%s: no stage or image found with that name", flag, from)
|
||||
}
|
||||
stageMountPoints[from] = internal.StageMountDetails{IsStage: false, DidExecute: true, MountPoint: mountPoint}
|
||||
stageMountPoints[from] = internal.StageMountDetails{
|
||||
IsImage: true,
|
||||
DidExecute: true,
|
||||
MountPoint: mountPoint,
|
||||
}
|
||||
break
|
||||
}
|
||||
default:
|
||||
@@ -1263,7 +1279,11 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
|
||||
// No base image means there's nothing to put in a
|
||||
// layer, so don't create one.
|
||||
emptyLayer := (s.builder.FromImageID == "")
|
||||
if imgID, ref, err = s.commit(ctx, s.getCreatedBy(nil, ""), emptyLayer, s.output, s.executor.squash || s.executor.confidentialWorkload.Convert, lastStage); err != nil {
|
||||
createdBy, err := s.getCreatedBy(nil, "")
|
||||
if err != nil {
|
||||
return "", nil, false, fmt.Errorf("unable to get createdBy for the node: %w", err)
|
||||
}
|
||||
if imgID, ref, err = s.commit(ctx, createdBy, emptyLayer, s.output, s.executor.squash || s.executor.confidentialWorkload.Convert, lastStage); err != nil {
|
||||
return "", nil, false, fmt.Errorf("committing base container: %w", err)
|
||||
}
|
||||
} else {
|
||||
@@ -1410,7 +1430,11 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
|
||||
if s.executor.timestamp != nil {
|
||||
timestamp = *s.executor.timestamp
|
||||
}
|
||||
s.builder.AddPrependedEmptyLayer(×tamp, s.getCreatedBy(node, addedContentSummary), "", "")
|
||||
createdBy, err := s.getCreatedBy(node, addedContentSummary)
|
||||
if err != nil {
|
||||
return "", nil, false, fmt.Errorf("unable to get createdBy for the node: %w", err)
|
||||
}
|
||||
s.builder.AddPrependedEmptyLayer(×tamp, createdBy, "", "")
|
||||
continue
|
||||
}
|
||||
// This is the last instruction for this stage,
|
||||
@@ -1420,7 +1444,11 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
|
||||
// stage.
|
||||
if lastStage || imageIsUsedLater {
|
||||
logCommit(s.output, i)
|
||||
imgID, ref, err = s.commit(ctx, s.getCreatedBy(node, addedContentSummary), false, s.output, s.executor.squash, lastStage && lastInstruction)
|
||||
createdBy, err := s.getCreatedBy(node, addedContentSummary)
|
||||
if err != nil {
|
||||
return "", nil, false, fmt.Errorf("unable to get createdBy for the node: %w", err)
|
||||
}
|
||||
imgID, ref, err = s.commit(ctx, createdBy, false, s.output, s.executor.squash, lastStage && lastInstruction)
|
||||
if err != nil {
|
||||
return "", nil, false, fmt.Errorf("committing container for step %+v: %w", *step, err)
|
||||
}
|
||||
@@ -1474,7 +1502,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
|
||||
return "", nil, false, err
|
||||
}
|
||||
for _, mountPoint := range stageMountPoints {
|
||||
if mountPoint.DidExecute {
|
||||
if mountPoint.DidExecute && mountPoint.IsStage {
|
||||
avoidLookingCache = true
|
||||
}
|
||||
}
|
||||
@@ -1641,6 +1669,10 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
|
||||
// We're not going to find any more cache hits, so we
|
||||
// can stop looking for them.
|
||||
checkForLayers = false
|
||||
createdBy, err := s.getCreatedBy(node, addedContentSummary)
|
||||
if err != nil {
|
||||
return "", nil, false, fmt.Errorf("unable to get createdBy for the node: %w", err)
|
||||
}
|
||||
// Create a new image, maybe with a new layer, with the
|
||||
// name for this stage if it's the last instruction.
|
||||
logCommit(s.output, i)
|
||||
@@ -1648,7 +1680,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
|
||||
// because at this point we want to save history for
|
||||
// layers even if its a squashed build so that they
|
||||
// can be part of the build cache.
|
||||
imgID, ref, err = s.commit(ctx, s.getCreatedBy(node, addedContentSummary), !s.stepRequiresLayer(step), commitName, false, lastStage && lastInstruction)
|
||||
imgID, ref, err = s.commit(ctx, createdBy, !s.stepRequiresLayer(step), commitName, false, lastStage && lastInstruction)
|
||||
if err != nil {
|
||||
return "", nil, false, fmt.Errorf("committing container for step %+v: %w", *step, err)
|
||||
}
|
||||
@@ -1679,12 +1711,16 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
|
||||
|
||||
if lastInstruction && lastStage {
|
||||
if s.executor.squash || s.executor.confidentialWorkload.Convert || len(s.executor.sbomScanOptions) != 0 {
|
||||
createdBy, err := s.getCreatedBy(node, addedContentSummary)
|
||||
if err != nil {
|
||||
return "", nil, false, fmt.Errorf("unable to get createdBy for the node: %w", err)
|
||||
}
|
||||
// If this is the last instruction of the last stage,
|
||||
// create a squashed or confidential workload
|
||||
// version of the image if that's what we're after,
|
||||
// or a normal one if we need to scan the image while
|
||||
// committing it.
|
||||
imgID, ref, err = s.commit(ctx, s.getCreatedBy(node, addedContentSummary), !s.stepRequiresLayer(step), commitName, s.executor.squash || s.executor.confidentialWorkload.Convert, lastStage && lastInstruction)
|
||||
imgID, ref, err = s.commit(ctx, createdBy, !s.stepRequiresLayer(step), commitName, s.executor.squash || s.executor.confidentialWorkload.Convert, lastStage && lastInstruction)
|
||||
if err != nil {
|
||||
return "", nil, false, fmt.Errorf("committing final squash step %+v: %w", *step, err)
|
||||
}
|
||||
@@ -1776,54 +1812,58 @@ func historyEntriesEqual(base, derived v1.History) bool {
|
||||
// that we're comparing.
|
||||
// Used to verify whether a cache of the intermediate image exists and whether
|
||||
// to run the build again.
|
||||
func (s *StageExecutor) historyAndDiffIDsMatch(baseHistory []v1.History, baseDiffIDs []digest.Digest, child *parser.Node, history []v1.History, diffIDs []digest.Digest, addedContentSummary string, buildAddsLayer bool) bool {
|
||||
func (s *StageExecutor) historyAndDiffIDsMatch(baseHistory []v1.History, baseDiffIDs []digest.Digest, child *parser.Node, history []v1.History, diffIDs []digest.Digest, addedContentSummary string, buildAddsLayer bool) (bool, error) {
|
||||
// our history should be as long as the base's, plus one entry for what
|
||||
// we're doing
|
||||
if len(history) != len(baseHistory)+1 {
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
// check that each entry in the base history corresponds to an entry in
|
||||
// our history, and count how many of them add a layer diff
|
||||
expectedDiffIDs := 0
|
||||
for i := range baseHistory {
|
||||
if !historyEntriesEqual(baseHistory[i], history[i]) {
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
if !baseHistory[i].EmptyLayer {
|
||||
expectedDiffIDs++
|
||||
}
|
||||
}
|
||||
if len(baseDiffIDs) != expectedDiffIDs {
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
if buildAddsLayer {
|
||||
// we're adding a layer, so we should have exactly one more
|
||||
// layer than the base image
|
||||
if len(diffIDs) != expectedDiffIDs+1 {
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
} else {
|
||||
// we're not adding a layer, so we should have exactly the same
|
||||
// layers as the base image
|
||||
if len(diffIDs) != expectedDiffIDs {
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
// compare the diffs for the layers that we should have in common
|
||||
for i := range baseDiffIDs {
|
||||
if diffIDs[i] != baseDiffIDs[i] {
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return history[len(baseHistory)].CreatedBy == s.getCreatedBy(child, addedContentSummary)
|
||||
createdBy, err := s.getCreatedBy(child, addedContentSummary)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("unable to get createdBy for the node: %w", err)
|
||||
}
|
||||
return history[len(baseHistory)].CreatedBy == createdBy, nil
|
||||
}
|
||||
|
||||
// getCreatedBy returns the command the image at node will be created by. If
|
||||
// the passed-in CompositeDigester is not nil, it is assumed to have the digest
|
||||
// information for the content if the node is ADD or COPY.
|
||||
func (s *StageExecutor) getCreatedBy(node *parser.Node, addedContentSummary string) string {
|
||||
func (s *StageExecutor) getCreatedBy(node *parser.Node, addedContentSummary string) (string, error) {
|
||||
if node == nil {
|
||||
return "/bin/sh"
|
||||
return "/bin/sh", nil
|
||||
}
|
||||
switch strings.ToUpper(node.Value) {
|
||||
case "ARG":
|
||||
@@ -1833,15 +1873,72 @@ func (s *StageExecutor) getCreatedBy(node *parser.Node, addedContentSummary stri
|
||||
}
|
||||
}
|
||||
buildArgs := s.getBuildArgsKey()
|
||||
return "/bin/sh -c #(nop) ARG " + buildArgs
|
||||
return "/bin/sh -c #(nop) ARG " + buildArgs, nil
|
||||
case "RUN":
|
||||
shArg := ""
|
||||
buildArgs := s.getBuildArgsResolvedForRun()
|
||||
appendCheckSum := ""
|
||||
for _, flag := range node.Flags {
|
||||
var err error
|
||||
mountOptionSource := ""
|
||||
mountOptionFrom := ""
|
||||
mountCheckSum := ""
|
||||
if strings.HasPrefix(flag, "--mount=") {
|
||||
mountInfo := getFromAndSourceKeysFromMountFlag(flag)
|
||||
if mountInfo.Type != "bind" {
|
||||
continue
|
||||
}
|
||||
mountOptionSource = mountInfo.Source
|
||||
mountOptionFrom = mountInfo.From
|
||||
// If source is not specified then default is '.'
|
||||
if mountOptionSource == "" {
|
||||
mountOptionSource = "."
|
||||
}
|
||||
}
|
||||
// Source specificed is part of stage, image or additional-build-context.
|
||||
if mountOptionFrom != "" {
|
||||
// If this is not a stage then get digest of image or additional build context
|
||||
if _, ok := s.executor.stages[mountOptionFrom]; !ok {
|
||||
if builder, ok := s.executor.containerMap[mountOptionFrom]; ok {
|
||||
// Found valid image, get image digest.
|
||||
mountCheckSum = builder.FromImageDigest
|
||||
} else {
|
||||
if s.executor.additionalBuildContexts[mountOptionFrom].IsImage {
|
||||
if builder, ok := s.executor.containerMap[s.executor.additionalBuildContexts[mountOptionFrom].Value]; ok {
|
||||
// Found valid image, get image digest.
|
||||
mountCheckSum = builder.FromImageDigest
|
||||
}
|
||||
} else {
|
||||
// Found additional build context, get directory sha.
|
||||
basePath := s.executor.additionalBuildContexts[mountOptionFrom].Value
|
||||
if s.executor.additionalBuildContexts[mountOptionFrom].IsURL {
|
||||
basePath = s.executor.additionalBuildContexts[mountOptionFrom].DownloadedCache
|
||||
}
|
||||
mountCheckSum, err = generatePathChecksum(filepath.Join(basePath, mountOptionSource))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("generating checksum for directory %q in %q: %w", mountOptionSource, basePath, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if mountOptionSource != "" {
|
||||
mountCheckSum, err = generatePathChecksum(filepath.Join(s.executor.contextDir, mountOptionSource))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("generating checksum for directory %q in %q: %w", mountOptionSource, s.executor.contextDir, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if mountCheckSum != "" {
|
||||
// add a separator to appendCheckSum
|
||||
appendCheckSum += ":" + mountCheckSum
|
||||
}
|
||||
}
|
||||
if len(node.Original) > 4 {
|
||||
shArg = node.Original[4:]
|
||||
}
|
||||
if buildArgs != "" {
|
||||
return "|" + strconv.Itoa(len(strings.Split(buildArgs, " "))) + " " + buildArgs + " /bin/sh -c " + shArg
|
||||
return "|" + strconv.Itoa(len(strings.Split(buildArgs, " "))) + " " + buildArgs + " /bin/sh -c " + shArg + appendCheckSum, nil
|
||||
}
|
||||
result := "/bin/sh -c " + shArg
|
||||
if len(node.Heredocs) > 0 {
|
||||
@@ -1850,15 +1947,15 @@ func (s *StageExecutor) getCreatedBy(node *parser.Node, addedContentSummary stri
|
||||
result = result + "\n" + heredocContent
|
||||
}
|
||||
}
|
||||
return result
|
||||
return result + appendCheckSum, nil
|
||||
case "ADD", "COPY":
|
||||
destination := node
|
||||
for destination.Next != nil {
|
||||
destination = destination.Next
|
||||
}
|
||||
return "/bin/sh -c #(nop) " + strings.ToUpper(node.Value) + " " + addedContentSummary + " in " + destination.Value + " "
|
||||
return "/bin/sh -c #(nop) " + strings.ToUpper(node.Value) + " " + addedContentSummary + " in " + destination.Value + " ", nil
|
||||
default:
|
||||
return "/bin/sh -c #(nop) " + node.Original
|
||||
return "/bin/sh -c #(nop) " + node.Original, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1914,7 +2011,7 @@ func (s *StageExecutor) getBuildArgsResolvedForRun() string {
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Strings(envs)
|
||||
slices.Sort(envs)
|
||||
return strings.Join(envs, " ")
|
||||
}
|
||||
|
||||
@@ -1927,7 +2024,7 @@ func (s *StageExecutor) getBuildArgsKey() string {
|
||||
args = append(args, key)
|
||||
}
|
||||
}
|
||||
sort.Strings(args)
|
||||
slices.Sort(args)
|
||||
return strings.Join(args, " ")
|
||||
}
|
||||
|
||||
@@ -2007,7 +2104,10 @@ func (s *StageExecutor) generateCacheKey(ctx context.Context, currNode *parser.N
|
||||
fmt.Fprintln(hash, diffIDs[i].String())
|
||||
}
|
||||
}
|
||||
createdBy := s.getCreatedBy(currNode, addedContentDigest)
|
||||
createdBy, err := s.getCreatedBy(currNode, addedContentDigest)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
fmt.Fprintf(hash, "%t", buildAddsLayer)
|
||||
fmt.Fprintln(hash, createdBy)
|
||||
fmt.Fprintln(hash, manifestType)
|
||||
@@ -2187,7 +2287,11 @@ func (s *StageExecutor) intermediateImageExists(ctx context.Context, currNode *p
|
||||
continue
|
||||
}
|
||||
// children + currNode is the point of the Dockerfile we are currently at.
|
||||
if s.historyAndDiffIDsMatch(baseHistory, baseDiffIDs, currNode, history, diffIDs, addedContentDigest, buildAddsLayer) {
|
||||
foundMatch, err := s.historyAndDiffIDsMatch(baseHistory, baseDiffIDs, currNode, history, diffIDs, addedContentDigest, buildAddsLayer)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if foundMatch {
|
||||
return image.ID, nil
|
||||
}
|
||||
}
|
||||
|
||||
89
vendor/github.com/containers/buildah/imagebuildah/util.go
generated
vendored
89
vendor/github.com/containers/buildah/imagebuildah/util.go
generated
vendored
@@ -1,9 +1,98 @@
|
||||
package imagebuildah
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/buildah"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
type mountInfo struct {
|
||||
Type string
|
||||
Source string
|
||||
From string
|
||||
}
|
||||
|
||||
// Consumes mount flag in format of `--mount=type=bind,src=/path,from=image` and
|
||||
// return mountInfo with values, otherwise values are empty if keys are not present in the option.
|
||||
func getFromAndSourceKeysFromMountFlag(mount string) mountInfo {
|
||||
tokens := strings.Split(strings.TrimPrefix(mount, "--mount="), ",")
|
||||
source := ""
|
||||
from := ""
|
||||
mountType := ""
|
||||
for _, option := range tokens {
|
||||
if optionSplit := strings.Split(option, "="); len(optionSplit) == 2 {
|
||||
if optionSplit[0] == "src" || optionSplit[0] == "source" {
|
||||
source = optionSplit[1]
|
||||
}
|
||||
if optionSplit[0] == "from" {
|
||||
from = optionSplit[1]
|
||||
}
|
||||
if optionSplit[0] == "type" {
|
||||
mountType = optionSplit[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return mountInfo{Source: source, From: from, Type: mountType}
|
||||
}
|
||||
|
||||
// generatePathChecksum generates the SHA-256 checksum for a file or a directory.
|
||||
func generatePathChecksum(sourcePath string) (string, error) {
|
||||
digester := digest.SHA256.Digester()
|
||||
tarWriter := tar.NewWriter(digester.Hash())
|
||||
|
||||
err := filepath.Walk(sourcePath, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var linkTarget string
|
||||
if info.Mode()&os.ModeSymlink != 0 {
|
||||
// If the file is a symlink, get the target
|
||||
linkTarget, err = os.Readlink(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
header, err := tar.FileInfoHeader(info, linkTarget)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
relPath, err := filepath.Rel(sourcePath, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
header.Name = filepath.ToSlash(relPath)
|
||||
|
||||
if err := tarWriter.WriteHeader(header); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !info.Mode().IsRegular() {
|
||||
return nil
|
||||
}
|
||||
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = io.Copy(tarWriter, file)
|
||||
return err
|
||||
})
|
||||
tarWriter.Close()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return digester.Digest().String(), nil
|
||||
}
|
||||
|
||||
// InitReexec is a wrapper for buildah.InitReexec(). It should be called at
|
||||
// the start of main(), and if it returns true, main() should return
|
||||
// successfully immediately.
|
||||
|
||||
BIN
vendor/github.com/containers/buildah/internal/mkcw/embed/entrypoint_amd64.gz
generated
vendored
BIN
vendor/github.com/containers/buildah/internal/mkcw/embed/entrypoint_amd64.gz
generated
vendored
Binary file not shown.
39
vendor/github.com/containers/buildah/internal/open/open.go
generated
vendored
Normal file
39
vendor/github.com/containers/buildah/internal/open/open.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
package open
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// InChroot opens the file at `path` after chrooting to `root` and then
|
||||
// changing its working directory to `wd`. Both `wd` and `path` are evaluated
|
||||
// in the chroot.
|
||||
// Returns a file handle, an Errno value if there was an error and the
|
||||
// underlying error was a standard library error code, and a non-empty error if
|
||||
// one was detected.
|
||||
func InChroot(root, wd, path string, mode int, perm uint32) (fd int, errno syscall.Errno, err error) {
|
||||
requests := requests{
|
||||
Root: root,
|
||||
Wd: wd,
|
||||
Open: []request{
|
||||
{
|
||||
Path: path,
|
||||
Mode: mode,
|
||||
Perms: perm,
|
||||
},
|
||||
},
|
||||
}
|
||||
results := inChroot(requests)
|
||||
if len(results.Open) != 1 {
|
||||
return -1, 0, fmt.Errorf("got %d results back instead of 1", len(results.Open))
|
||||
}
|
||||
if results.Open[0].Err != "" {
|
||||
if results.Open[0].Errno != 0 {
|
||||
err = fmt.Errorf("%s: %w", results.Open[0].Err, results.Open[0].Errno)
|
||||
} else {
|
||||
err = errors.New(results.Open[0].Err)
|
||||
}
|
||||
}
|
||||
return int(results.Open[0].Fd), results.Open[0].Errno, err
|
||||
}
|
||||
88
vendor/github.com/containers/buildah/internal/open/open_linux.go
generated
vendored
Normal file
88
vendor/github.com/containers/buildah/internal/open/open_linux.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
package open
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/storage/pkg/reexec"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
bindFdToPathCommand = "buildah-bind-fd-to-path"
|
||||
)
|
||||
|
||||
func init() {
|
||||
reexec.Register(bindFdToPathCommand, bindFdToPathMain)
|
||||
}
|
||||
|
||||
// BindFdToPath creates a bind mount from the open file (which is actually a
|
||||
// directory) to the specified location. If it succeeds, the caller will need
|
||||
// to unmount the targetPath when it's finished using it. Regardless, it
|
||||
// closes the passed-in descriptor.
|
||||
func BindFdToPath(fd uintptr, targetPath string) error {
|
||||
f := os.NewFile(fd, "passed-in directory descriptor")
|
||||
defer func() {
|
||||
if err := f.Close(); err != nil {
|
||||
logrus.Debugf("closing descriptor %d after attempting to bind to %q: %v", fd, targetPath, err)
|
||||
}
|
||||
}()
|
||||
pipeReader, pipeWriter, err := os.Pipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd := reexec.Command(bindFdToPathCommand)
|
||||
cmd.Stdin = pipeReader
|
||||
var stdout bytes.Buffer
|
||||
var stderr bytes.Buffer
|
||||
cmd.Stdout, cmd.Stderr = &stdout, &stderr
|
||||
cmd.ExtraFiles = append(cmd.ExtraFiles, f)
|
||||
|
||||
err = cmd.Start()
|
||||
pipeReader.Close()
|
||||
if err != nil {
|
||||
pipeWriter.Close()
|
||||
return fmt.Errorf("starting child: %w", err)
|
||||
}
|
||||
|
||||
encoder := json.NewEncoder(pipeWriter)
|
||||
if err := encoder.Encode(&targetPath); err != nil {
|
||||
return fmt.Errorf("sending target path to child: %w", err)
|
||||
}
|
||||
pipeWriter.Close()
|
||||
err = cmd.Wait()
|
||||
trimmedOutput := strings.TrimSpace(stdout.String()) + strings.TrimSpace(stderr.String())
|
||||
if err != nil {
|
||||
if len(trimmedOutput) > 0 {
|
||||
err = fmt.Errorf("%s: %w", trimmedOutput, err)
|
||||
}
|
||||
} else {
|
||||
if len(trimmedOutput) > 0 {
|
||||
err = errors.New(trimmedOutput)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func bindFdToPathMain() {
|
||||
var targetPath string
|
||||
decoder := json.NewDecoder(os.Stdin)
|
||||
if err := decoder.Decode(&targetPath); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error decoding target path")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := unix.Fchdir(3); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "fchdir(): %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := unix.Mount(".", targetPath, "bind", unix.MS_BIND, ""); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "bind-mounting passed-in directory to %q: %v", targetPath, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
28
vendor/github.com/containers/buildah/internal/open/open_types.go
generated
vendored
Normal file
28
vendor/github.com/containers/buildah/internal/open/open_types.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
package open
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type request struct {
|
||||
Path string
|
||||
Mode int
|
||||
Perms uint32
|
||||
}
|
||||
|
||||
type requests struct {
|
||||
Root string
|
||||
Wd string
|
||||
Open []request
|
||||
}
|
||||
|
||||
type result struct {
|
||||
Fd uintptr // as returned by open()
|
||||
Err string // if err was not `nil`, err.Error()
|
||||
Errno syscall.Errno // if err was not `nil` and included a syscall.Errno, its value
|
||||
}
|
||||
|
||||
type results struct {
|
||||
Err string
|
||||
Open []result
|
||||
}
|
||||
168
vendor/github.com/containers/buildah/internal/open/open_unix.go
generated
vendored
Normal file
168
vendor/github.com/containers/buildah/internal/open/open_unix.go
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
//go:build linux || freebsd || darwin
|
||||
|
||||
package open
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/containers/storage/pkg/reexec"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
inChrootCommand = "buildah-open-in-chroot"
|
||||
)
|
||||
|
||||
func init() {
|
||||
reexec.Register(inChrootCommand, inChrootMain)
|
||||
}
|
||||
|
||||
func inChroot(requests requests) results {
|
||||
sock, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0)
|
||||
if err != nil {
|
||||
return results{Err: fmt.Errorf("creating socket pair: %w", err).Error()}
|
||||
}
|
||||
parentSock := sock[0]
|
||||
childSock := sock[1]
|
||||
parentEnd := os.NewFile(uintptr(parentSock), "parent end of socket pair")
|
||||
childEnd := os.NewFile(uintptr(childSock), "child end of socket pair")
|
||||
cmd := reexec.Command(inChrootCommand)
|
||||
cmd.ExtraFiles = append(cmd.ExtraFiles, childEnd)
|
||||
err = cmd.Start()
|
||||
childEnd.Close()
|
||||
defer parentEnd.Close()
|
||||
if err != nil {
|
||||
return results{Err: err.Error()}
|
||||
}
|
||||
encoder := json.NewEncoder(parentEnd)
|
||||
if err := encoder.Encode(&requests); err != nil {
|
||||
return results{Err: fmt.Errorf("sending request down socket: %w", err).Error()}
|
||||
}
|
||||
if err := unix.Shutdown(parentSock, unix.SHUT_WR); err != nil {
|
||||
return results{Err: fmt.Errorf("finishing sending request down socket: %w", err).Error()}
|
||||
}
|
||||
b := make([]byte, 65536)
|
||||
oob := make([]byte, 65536)
|
||||
n, oobn, _, _, err := unix.Recvmsg(parentSock, b, oob, 0)
|
||||
if err != nil {
|
||||
return results{Err: fmt.Errorf("receiving message: %w", err).Error()}
|
||||
}
|
||||
if err := unix.Shutdown(parentSock, unix.SHUT_RD); err != nil {
|
||||
return results{Err: fmt.Errorf("finishing socket: %w", err).Error()}
|
||||
}
|
||||
if n > len(b) {
|
||||
return results{Err: fmt.Errorf("too much regular data: %d > %d", n, len(b)).Error()}
|
||||
}
|
||||
if oobn > len(oob) {
|
||||
return results{Err: fmt.Errorf("too much OOB data: %d > %d", oobn, len(oob)).Error()}
|
||||
}
|
||||
scms, err := unix.ParseSocketControlMessage(oob[:oobn])
|
||||
if err != nil {
|
||||
return results{Err: fmt.Errorf("parsing control message: %w", err).Error()}
|
||||
}
|
||||
var receivedFds []int
|
||||
for i := range scms {
|
||||
fds, err := unix.ParseUnixRights(&scms[i])
|
||||
if err != nil {
|
||||
return results{Err: fmt.Errorf("parsing rights message %d: %w", i, err).Error()}
|
||||
}
|
||||
receivedFds = append(receivedFds, fds...)
|
||||
}
|
||||
decoder := json.NewDecoder(bytes.NewReader(b[:n]))
|
||||
var result results
|
||||
if err := decoder.Decode(&result); err != nil {
|
||||
return results{Err: fmt.Errorf("decoding results: %w", err).Error()}
|
||||
}
|
||||
j := 0
|
||||
for i := range result.Open {
|
||||
if result.Open[i].Err == "" {
|
||||
if j >= len(receivedFds) {
|
||||
for _, fd := range receivedFds {
|
||||
unix.Close(fd)
|
||||
}
|
||||
return results{Err: fmt.Errorf("didn't receive enough FDs").Error()}
|
||||
}
|
||||
result.Open[i].Fd = uintptr(receivedFds[j])
|
||||
j++
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func inChrootMain() {
|
||||
var theseRequests requests
|
||||
var theseResults results
|
||||
sockFd := 3
|
||||
sock := os.NewFile(uintptr(sockFd), "socket connection to parent process")
|
||||
defer sock.Close()
|
||||
encoder := json.NewEncoder(sock)
|
||||
decoder := json.NewDecoder(sock)
|
||||
if err := decoder.Decode(&theseRequests); err != nil {
|
||||
if err := encoder.Encode(results{Err: fmt.Errorf("decoding request: %w", err).Error()}); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if theseRequests.Root != "" {
|
||||
if err := os.Chdir(theseRequests.Root); err != nil {
|
||||
if err := encoder.Encode(results{Err: fmt.Errorf("changing to %q: %w", theseRequests.Root, err).Error()}); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := unix.Chroot(theseRequests.Root); err != nil {
|
||||
if err := encoder.Encode(results{Err: fmt.Errorf("chrooting to %q: %w", theseRequests.Root, err).Error()}); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := os.Chdir("/"); err != nil {
|
||||
if err := encoder.Encode(results{Err: fmt.Errorf("changing to new root: %w", err).Error()}); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if theseRequests.Wd != "" {
|
||||
if err := os.Chdir(theseRequests.Wd); err != nil {
|
||||
if err := encoder.Encode(results{Err: fmt.Errorf("changing to %q in chroot: %w", theseRequests.Wd, err).Error()}); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
var fds []int
|
||||
for _, request := range theseRequests.Open {
|
||||
fd, err := unix.Open(request.Path, request.Mode, request.Perms)
|
||||
thisResult := result{Fd: uintptr(fd)}
|
||||
if err == nil {
|
||||
fds = append(fds, fd)
|
||||
} else {
|
||||
var errno syscall.Errno
|
||||
thisResult.Err = err.Error()
|
||||
if errors.As(err, &errno) {
|
||||
thisResult.Errno = errno
|
||||
}
|
||||
}
|
||||
theseResults.Open = append(theseResults.Open, thisResult)
|
||||
}
|
||||
rights := unix.UnixRights(fds...)
|
||||
inband, err := json.Marshal(&theseResults)
|
||||
if err != nil {
|
||||
if err := encoder.Encode(results{Err: fmt.Errorf("sending response: %w", err).Error()}); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := unix.Sendmsg(sockFd, inband, rights, nil, 0); err != nil {
|
||||
if err := encoder.Encode(results{Err: fmt.Errorf("sending response: %w", err).Error()}); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
7
vendor/github.com/containers/buildah/internal/open/open_unsupported.go
generated
vendored
Normal file
7
vendor/github.com/containers/buildah/internal/open/open_unsupported.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
//go:build !linux && !freebsd && !darwin
|
||||
|
||||
package open
|
||||
|
||||
func inChroot(requests requests) results {
|
||||
return results{Err: "open-in-chroot not available on this platform"}
|
||||
}
|
||||
8
vendor/github.com/containers/buildah/internal/types.go
generated
vendored
8
vendor/github.com/containers/buildah/internal/types.go
generated
vendored
@@ -12,7 +12,9 @@ const (
|
||||
// StageExecutor has ability to mount stages/images in current context and
|
||||
// automatically clean them up.
|
||||
type StageMountDetails struct {
|
||||
DidExecute bool // tells if the stage which is being mounted was freshly executed or was part of older cache
|
||||
IsStage bool // true if the mountpoint is a temporary directory or a stage's rootfs, false if it's an image
|
||||
MountPoint string // mountpoint of the stage or image's root directory
|
||||
DidExecute bool // true if this is a freshly-executed stage, or an image, possibly from a non-local cache
|
||||
IsStage bool // true if the mountpoint is a stage's rootfs
|
||||
IsImage bool // true if the mountpoint is an image's rootfs
|
||||
IsAdditionalBuildContext bool // true if the mountpoint is an additional build context
|
||||
MountPoint string // mountpoint of the stage or image's root directory or path of the additional build context
|
||||
}
|
||||
|
||||
102
vendor/github.com/containers/buildah/internal/volumes/bind_linux.go
generated
vendored
Normal file
102
vendor/github.com/containers/buildah/internal/volumes/bind_linux.go
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
package volumes
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/containers/buildah/internal/open"
|
||||
"github.com/containers/storage/pkg/mount"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// bindFromChroot opens "path" inside of "root" using a chrooted subprocess
|
||||
// that returns a descriptor, then creates a uniquely-named temporary directory
|
||||
// or file under "tmp" and bind-mounts the opened descriptor to it, returning
|
||||
// the path of the temporary file or directory. The caller is responsible for
|
||||
// unmounting and removing the temporary.
|
||||
func bindFromChroot(root, path, tmp string) (string, error) {
|
||||
fd, _, err := open.InChroot(root, "", path, unix.O_DIRECTORY|unix.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
if !errors.Is(err, unix.ENOTDIR) {
|
||||
return "", fmt.Errorf("opening directory %q under %q: %w", path, root, err)
|
||||
}
|
||||
fd, _, err = open.InChroot(root, "", path, unix.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("opening non-directory %q under %q: %w", path, root, err)
|
||||
}
|
||||
}
|
||||
defer func() {
|
||||
if err := unix.Close(fd); err != nil {
|
||||
logrus.Debugf("closing %q under %q: %v", path, root, err)
|
||||
}
|
||||
}()
|
||||
|
||||
succeeded := false
|
||||
var dest string
|
||||
var destF *os.File
|
||||
defer func() {
|
||||
if !succeeded {
|
||||
if destF != nil {
|
||||
if err := destF.Close(); err != nil {
|
||||
logrus.Debugf("closing bind target %q: %v", dest, err)
|
||||
}
|
||||
}
|
||||
if dest != "" {
|
||||
if err := os.Remove(dest); err != nil {
|
||||
logrus.Debugf("removing bind target %q: %v", dest, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
var st unix.Stat_t
|
||||
if err = unix.Fstat(fd, &st); err != nil {
|
||||
return "", fmt.Errorf("checking if %q under %q was a directory: %w", path, root, err)
|
||||
}
|
||||
|
||||
if st.Mode&unix.S_IFDIR == unix.S_IFDIR {
|
||||
if dest, err = os.MkdirTemp(tmp, "bind"); err != nil {
|
||||
return "", fmt.Errorf("creating a bind target directory: %w", err)
|
||||
}
|
||||
} else {
|
||||
if destF, err = os.CreateTemp(tmp, "bind"); err != nil {
|
||||
return "", fmt.Errorf("creating a bind target non-directory: %w", err)
|
||||
}
|
||||
if err := destF.Close(); err != nil {
|
||||
logrus.Debugf("closing bind target %q: %v", dest, err)
|
||||
}
|
||||
dest = destF.Name()
|
||||
}
|
||||
defer func() {
|
||||
if !succeeded {
|
||||
if err := os.Remove(dest); err != nil {
|
||||
logrus.Debugf("removing bind target %q: %v", dest, err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if err := unix.Mount(fmt.Sprintf("/proc/self/fd/%d", fd), dest, "bind", unix.MS_BIND, ""); err != nil {
|
||||
return "", fmt.Errorf("bind-mounting passed-in descriptor to %q: %w", dest, err)
|
||||
}
|
||||
defer func() {
|
||||
if !succeeded {
|
||||
if err := mount.Unmount(dest); err != nil {
|
||||
logrus.Debugf("unmounting bound target %q: %v", dest, err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
var st2 unix.Stat_t
|
||||
if err = unix.Stat(dest, &st2); err != nil {
|
||||
return "", fmt.Errorf("looking up device/inode of newly-bind-mounted %q: %w", dest, err)
|
||||
}
|
||||
|
||||
if st2.Dev != st.Dev || st2.Ino != st.Ino {
|
||||
return "", fmt.Errorf("device/inode weren't what we expected after bind mounting: %w", err)
|
||||
}
|
||||
|
||||
succeeded = true
|
||||
return dest, nil
|
||||
}
|
||||
15
vendor/github.com/containers/buildah/internal/volumes/bind_notlinux.go
generated
vendored
Normal file
15
vendor/github.com/containers/buildah/internal/volumes/bind_notlinux.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
//go:build !linux
|
||||
|
||||
package volumes
|
||||
|
||||
import "errors"
|
||||
|
||||
// bindFromChroot would open "path" inside of "root" using a chrooted
|
||||
// subprocess that returns a descriptor, then would create a uniquely-named
|
||||
// temporary directory or file under "tmp" and bind-mount the opened descriptor
|
||||
// to it, returning the path of the temporary file or directory. The caller
|
||||
// would be responsible for unmounting and removing the temporary. For now,
|
||||
// this just returns an error because it is not implemented for this platform.
|
||||
func bindFromChroot(root, path, tmp string) (string, error) {
|
||||
return "", errors.New("not available on this system")
|
||||
}
|
||||
664
vendor/github.com/containers/buildah/internal/volumes/volumes.go
generated
vendored
664
vendor/github.com/containers/buildah/internal/volumes/volumes.go
generated
vendored
File diff suppressed because it is too large
Load Diff
4
vendor/github.com/containers/buildah/new.go
generated
vendored
4
vendor/github.com/containers/buildah/new.go
generated
vendored
@@ -4,7 +4,9 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"math/rand"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/buildah/define"
|
||||
@@ -21,8 +23,6 @@ import (
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/openshift/imagebuilder"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/maps"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
2
vendor/github.com/containers/buildah/pkg/cli/build.go
generated
vendored
2
vendor/github.com/containers/buildah/pkg/cli/build.go
generated
vendored
@@ -12,6 +12,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -24,7 +25,6 @@ import (
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
type BuildOptions struct {
|
||||
|
||||
66
vendor/github.com/containers/buildah/pkg/overlay/overlay.go
generated
vendored
66
vendor/github.com/containers/buildah/pkg/overlay/overlay.go
generated
vendored
@@ -10,15 +10,14 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/containers/storage/pkg/mount"
|
||||
"github.com/containers/storage/pkg/system"
|
||||
"github.com/containers/storage/pkg/unshare"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Options type holds various configuration options for overlay
|
||||
// MountWithOptions accepts following type so it is easier to specify
|
||||
// more verbose configuration for overlay mount.
|
||||
// Options for MountWithOptions().
|
||||
type Options struct {
|
||||
// The Upper directory is normally writable layer in an overlay mount.
|
||||
// Note!! : Following API does not handles escaping or validates correctness of the values
|
||||
@@ -40,17 +39,26 @@ type Options struct {
|
||||
// TODO: Should we address above comment and handle escaping of metacharacters like
|
||||
// `comma`, `backslash` ,`colon` and any other special characters
|
||||
WorkDirOptionFragment string
|
||||
// Graph options relayed from podman, will be responsible for choosing mount program
|
||||
// Graph options being used by the caller, will be searched when choosing mount program
|
||||
GraphOpts []string
|
||||
// Mark if following overlay is read only
|
||||
ReadOnly bool
|
||||
// RootUID is not used yet but keeping it here for legacy reasons.
|
||||
// Deprecated: RootUID is not used
|
||||
RootUID int
|
||||
// RootGID is not used yet but keeping it here for legacy reasons.
|
||||
// Deprecated: RootGID is not used
|
||||
RootGID int
|
||||
// Force overlay mounting and return a bind mount, rather than
|
||||
// attempting to optimize by having the runtime actually mount and
|
||||
// manage the overlay filesystem.
|
||||
ForceMount bool
|
||||
// MountLabel is a label to force for the overlay filesystem.
|
||||
MountLabel string
|
||||
}
|
||||
|
||||
// TempDir generates an overlay Temp directory in the container content
|
||||
// TempDir generates a uniquely-named directory under ${containerDir}/overlay
|
||||
// which can be used as a parent directory for the upper and working
|
||||
// directories for an overlay mount, creates "upper" and "work" directories
|
||||
// beneath it, and then returns the path of the new directory.
|
||||
func TempDir(containerDir string, rootUID, rootGID int) (string, error) {
|
||||
contentDir := filepath.Join(containerDir, "overlay")
|
||||
if err := idtools.MkdirAllAs(contentDir, 0o700, rootUID, rootGID); err != nil {
|
||||
@@ -62,7 +70,7 @@ func TempDir(containerDir string, rootUID, rootGID int) (string, error) {
|
||||
return "", fmt.Errorf("failed to create the overlay tmpdir in %s directory: %w", contentDir, err)
|
||||
}
|
||||
|
||||
return generateOverlayStructure(contentDir, rootUID, rootGID)
|
||||
return contentDir, generateOverlayStructure(contentDir, rootUID, rootGID)
|
||||
}
|
||||
|
||||
// GenerateStructure generates an overlay directory structure for container content
|
||||
@@ -72,25 +80,24 @@ func GenerateStructure(containerDir, containerID, name string, rootUID, rootGID
|
||||
return "", fmt.Errorf("failed to create the overlay %s directory: %w", contentDir, err)
|
||||
}
|
||||
|
||||
return generateOverlayStructure(contentDir, rootUID, rootGID)
|
||||
return contentDir, generateOverlayStructure(contentDir, rootUID, rootGID)
|
||||
}
|
||||
|
||||
// generateOverlayStructure generates upper, work and merge directory structure for overlay directory
|
||||
func generateOverlayStructure(containerDir string, rootUID, rootGID int) (string, error) {
|
||||
// generateOverlayStructure generates upper, work and merge directories under the specified directory
|
||||
func generateOverlayStructure(containerDir string, rootUID, rootGID int) error {
|
||||
upperDir := filepath.Join(containerDir, "upper")
|
||||
workDir := filepath.Join(containerDir, "work")
|
||||
if err := idtools.MkdirAllAs(upperDir, 0o700, rootUID, rootGID); err != nil {
|
||||
return "", fmt.Errorf("failed to create the overlay %s directory: %w", upperDir, err)
|
||||
return fmt.Errorf("creating overlay upper directory %s: %w", upperDir, err)
|
||||
}
|
||||
if err := idtools.MkdirAllAs(workDir, 0o700, rootUID, rootGID); err != nil {
|
||||
return "", fmt.Errorf("failed to create the overlay %s directory: %w", workDir, err)
|
||||
return fmt.Errorf("creating overlay work directory %s: %w", workDir, err)
|
||||
}
|
||||
mergeDir := filepath.Join(containerDir, "merge")
|
||||
if err := idtools.MkdirAllAs(mergeDir, 0o700, rootUID, rootGID); err != nil {
|
||||
return "", fmt.Errorf("failed to create the overlay %s directory: %w", mergeDir, err)
|
||||
return fmt.Errorf("creating overlay merge directory %s: %w", mergeDir, err)
|
||||
}
|
||||
|
||||
return containerDir, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// Mount creates a subdir of the contentDir based on the source directory
|
||||
@@ -133,8 +140,8 @@ func findMountProgram(graphOptions []string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// mountWithMountProgram mount an overlay at mergeDir using the specified mount program
|
||||
// and overlay options.
|
||||
// mountWithMountProgram mounts an overlay at mergeDir using the specified
|
||||
// mount program and overlay options.
|
||||
func mountWithMountProgram(mountProgram, overlayOptions, mergeDir string) error {
|
||||
cmd := exec.Command(mountProgram, "-o", overlayOptions, mergeDir)
|
||||
|
||||
@@ -144,13 +151,20 @@ func mountWithMountProgram(mountProgram, overlayOptions, mergeDir string) error
|
||||
return nil
|
||||
}
|
||||
|
||||
// mountNatively mounts an overlay at mergeDir using the kernel's mount()
|
||||
// system call.
|
||||
func mountNatively(overlayOptions, mergeDir string) error {
|
||||
return mount.Mount("overlay", mergeDir, "overlay", overlayOptions)
|
||||
}
|
||||
|
||||
// Convert ":" to "\:", the path which will be overlay mounted need to be escaped
|
||||
func escapeColon(source string) string {
|
||||
return strings.ReplaceAll(source, ":", "\\:")
|
||||
}
|
||||
|
||||
// RemoveTemp removes temporary mountpoint and all content from its parent
|
||||
// directory
|
||||
// RemoveTemp unmounts a filesystem mounted at ${contentDir}/merge, and then
|
||||
// removes ${contentDir}, which is typically a path returned by TempDir(),
|
||||
// along with any contents it might still have.
|
||||
func RemoveTemp(contentDir string) error {
|
||||
if err := Unmount(contentDir); err != nil {
|
||||
return err
|
||||
@@ -159,7 +173,9 @@ func RemoveTemp(contentDir string) error {
|
||||
return os.RemoveAll(contentDir)
|
||||
}
|
||||
|
||||
// Unmount the overlay mountpoint
|
||||
// Unmount the overlay mountpoint at ${contentDir}/merge, where ${contentDir}
|
||||
// is typically a path returned by TempDir(). The mountpoint itself is left
|
||||
// unmodified.
|
||||
func Unmount(contentDir string) error {
|
||||
mergeDir := filepath.Join(contentDir, "merge")
|
||||
|
||||
@@ -185,6 +201,8 @@ func Unmount(contentDir string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// recreate removes a directory tree and then recreates the top of that tree
|
||||
// with the same mode and ownership.
|
||||
func recreate(contentDir string) error {
|
||||
st, err := system.Stat(contentDir)
|
||||
if err != nil {
|
||||
@@ -215,8 +233,10 @@ func CleanupMount(contentDir string) (Err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CleanupContent removes all temporary mountpoint and all content from
|
||||
// directory
|
||||
// CleanupContent removes every temporary mountpoint created under
|
||||
// ${containerDir}/overlay as a result of however many calls to TempDir(),
|
||||
// roughly equivalent to calling RemoveTemp() for each of the directories whose
|
||||
// paths it returned, and then removes ${containerDir} itself.
|
||||
func CleanupContent(containerDir string) (Err error) {
|
||||
contentDir := filepath.Join(containerDir, "overlay")
|
||||
|
||||
|
||||
10
vendor/github.com/containers/buildah/pkg/overlay/overlay_freebsd.go
generated
vendored
10
vendor/github.com/containers/buildah/pkg/overlay/overlay_freebsd.go
generated
vendored
@@ -12,11 +12,11 @@ import (
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
// MountWithOptions creates a subdir of the contentDir based on the source directory
|
||||
// from the source system. It then mounts up the source directory on to the
|
||||
// generated mount point and returns the mount point to the caller.
|
||||
// But allows api to set custom workdir, upperdir and other overlay options
|
||||
// Following API is being used by podman at the moment
|
||||
// MountWithOptions returns a specs.Mount which makes the contents of ${source}
|
||||
// visible at ${dest} in the container.
|
||||
// Options allows the caller to configure whether or not the mount should be
|
||||
// read-only.
|
||||
// This API is used by podman.
|
||||
func MountWithOptions(contentDir, source, dest string, opts *Options) (mount specs.Mount, Err error) {
|
||||
if opts == nil {
|
||||
opts = &Options{}
|
||||
|
||||
40
vendor/github.com/containers/buildah/pkg/overlay/overlay_linux.go
generated
vendored
40
vendor/github.com/containers/buildah/pkg/overlay/overlay_linux.go
generated
vendored
@@ -9,13 +9,18 @@ import (
|
||||
|
||||
"github.com/containers/storage/pkg/unshare"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
)
|
||||
|
||||
// MountWithOptions creates a subdir of the contentDir based on the source directory
|
||||
// from the source system. It then mounts up the source directory on to the
|
||||
// generated mount point and returns the mount point to the caller.
|
||||
// But allows api to set custom workdir, upperdir and other overlay options
|
||||
// Following API is being used by podman at the moment
|
||||
// MountWithOptions creates ${contentDir}/merge, where ${contentDir} was
|
||||
// presumably created and returned by a call to TempDir(), and either mounts a
|
||||
// filesystem there and returns a mounts.Spec which bind-mounts the mountpoint
|
||||
// to ${dest}, or returns a mounts.Spec which mounts a filesystem at ${dest}.
|
||||
// Options allows the caller to configure a custom workdir and upperdir,
|
||||
// indicate whether or not the overlay should be read-only, and provide the
|
||||
// graph driver options that we'll search to determine whether or not we should
|
||||
// be using a mount helper (i.e., fuse-overlayfs).
|
||||
// This API is used by podman.
|
||||
func MountWithOptions(contentDir, source, dest string, opts *Options) (mount specs.Mount, Err error) {
|
||||
if opts == nil {
|
||||
opts = &Options{}
|
||||
@@ -25,7 +30,7 @@ func MountWithOptions(contentDir, source, dest string, opts *Options) (mount spe
|
||||
// Create overlay mount options for rw/ro.
|
||||
var overlayOptions string
|
||||
if opts.ReadOnly {
|
||||
// Read-only overlay mounts require two lower layer.
|
||||
// Read-only overlay mounts require two lower layers.
|
||||
lowerTwo := filepath.Join(contentDir, "lower")
|
||||
if err := os.Mkdir(lowerTwo, 0o755); err != nil {
|
||||
return mount, err
|
||||
@@ -38,7 +43,13 @@ func MountWithOptions(contentDir, source, dest string, opts *Options) (mount spe
|
||||
|
||||
if opts.WorkDirOptionFragment != "" && opts.UpperDirOptionFragment != "" {
|
||||
workDir = opts.WorkDirOptionFragment
|
||||
if !filepath.IsAbs(workDir) {
|
||||
workDir = filepath.Join(contentDir, workDir)
|
||||
}
|
||||
upperDir = opts.UpperDirOptionFragment
|
||||
if !filepath.IsAbs(upperDir) {
|
||||
upperDir = filepath.Join(contentDir, upperDir)
|
||||
}
|
||||
}
|
||||
|
||||
st, err := os.Stat(source)
|
||||
@@ -55,6 +66,9 @@ func MountWithOptions(contentDir, source, dest string, opts *Options) (mount spe
|
||||
}
|
||||
overlayOptions = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s,private", escapeColon(source), upperDir, workDir)
|
||||
}
|
||||
if opts.MountLabel != "" {
|
||||
overlayOptions = overlayOptions + "," + label.FormatMountLabel("", opts.MountLabel)
|
||||
}
|
||||
|
||||
mountProgram := findMountProgram(opts.GraphOpts)
|
||||
if mountProgram != "" {
|
||||
@@ -70,7 +84,7 @@ func MountWithOptions(contentDir, source, dest string, opts *Options) (mount spe
|
||||
}
|
||||
|
||||
if unshare.IsRootless() {
|
||||
/* If a mount_program is not specified, fallback to try mounting native overlay. */
|
||||
// If a mount_program is not specified, fallback to try mounting native overlay.
|
||||
overlayOptions = fmt.Sprintf("%s,userxattr", overlayOptions)
|
||||
}
|
||||
|
||||
@@ -79,5 +93,17 @@ func MountWithOptions(contentDir, source, dest string, opts *Options) (mount spe
|
||||
mount.Type = "overlay"
|
||||
mount.Options = strings.Split(overlayOptions, ",")
|
||||
|
||||
if opts.ForceMount {
|
||||
if err := mountNatively(overlayOptions, mergeDir); err != nil {
|
||||
return mount, err
|
||||
}
|
||||
|
||||
mount.Source = mergeDir
|
||||
mount.Destination = dest
|
||||
mount.Type = "bind"
|
||||
mount.Options = []string{"bind", "slave"}
|
||||
return mount, nil
|
||||
}
|
||||
|
||||
return mount, nil
|
||||
}
|
||||
|
||||
12
vendor/github.com/containers/buildah/pkg/parse/parse.go
generated
vendored
12
vendor/github.com/containers/buildah/pkg/parse/parse.go
generated
vendored
@@ -249,6 +249,18 @@ func parseSecurityOpts(securityOpts []string, commonOpts *define.CommonBuildOpti
|
||||
commonOpts.ApparmorProfile = con[1]
|
||||
case "seccomp":
|
||||
commonOpts.SeccompProfilePath = con[1]
|
||||
case "mask":
|
||||
commonOpts.Masks = append(commonOpts.Masks, strings.Split(con[1], ":")...)
|
||||
case "unmask":
|
||||
unmasks := strings.Split(con[1], ":")
|
||||
for _, unmask := range unmasks {
|
||||
matches, _ := filepath.Glob(unmask)
|
||||
if len(matches) > 0 {
|
||||
commonOpts.Unmasks = append(commonOpts.Unmasks, matches...)
|
||||
continue
|
||||
}
|
||||
commonOpts.Unmasks = append(commonOpts.Unmasks, unmask)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("invalid --security-opt 2: %q", opt)
|
||||
}
|
||||
|
||||
18
vendor/github.com/containers/buildah/run.go
generated
vendored
18
vendor/github.com/containers/buildah/run.go
generated
vendored
@@ -159,9 +159,9 @@ type RunOptions struct {
|
||||
RunMounts []string
|
||||
// Map of stages and container mountpoint if any from stage executor
|
||||
StageMountPoints map[string]internal.StageMountDetails
|
||||
// External Image mounts to be cleaned up.
|
||||
// Buildah run --mount could mount image before RUN calls, RUN could cleanup
|
||||
// them up as well
|
||||
// IDs of mounted images to be unmounted before returning
|
||||
// Deprecated: before 1.39, these images would not be consistently
|
||||
// unmounted if Run() returned an error
|
||||
ExternalImageMounts []string
|
||||
// System context of current build
|
||||
SystemContext *types.SystemContext
|
||||
@@ -180,18 +180,22 @@ type RunOptions struct {
|
||||
|
||||
// RunMountArtifacts are the artifacts created when using a run mount.
|
||||
type runMountArtifacts struct {
|
||||
// RunMountTargets are the run mount targets inside the container
|
||||
// RunMountTargets are the run mount targets inside the container which should be removed
|
||||
RunMountTargets []string
|
||||
// RunOverlayDirs are overlay directories which will need to be cleaned up using overlay.RemoveTemp()
|
||||
RunOverlayDirs []string
|
||||
// TmpFiles are artifacts that need to be removed outside the container
|
||||
TmpFiles []string
|
||||
// Any external images which were mounted inside container
|
||||
// Any images which were mounted, which should be unmounted
|
||||
MountedImages []string
|
||||
// Agents are the ssh agents started
|
||||
// Agents are the ssh agents started, which should have their Shutdown() methods called
|
||||
Agents []*sshagent.AgentServer
|
||||
// SSHAuthSock is the path to the ssh auth sock inside the container
|
||||
SSHAuthSock string
|
||||
// TargetLocks to be unlocked if there are any.
|
||||
// Lock files, which should have their Unlock() methods called
|
||||
TargetLocks []*lockfile.LockFile
|
||||
// Intermediate mount points, which should be Unmount()ed and Removed()d
|
||||
IntermediateMounts []string
|
||||
}
|
||||
|
||||
// RunMountInfo are the available run mounts for this run
|
||||
|
||||
212
vendor/github.com/containers/buildah/run_common.go
generated
vendored
212
vendor/github.com/containers/buildah/run_common.go
generated
vendored
@@ -15,6 +15,7 @@ import (
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -27,7 +28,6 @@ import (
|
||||
"github.com/containers/buildah/define"
|
||||
"github.com/containers/buildah/internal"
|
||||
"github.com/containers/buildah/internal/tmpdir"
|
||||
internalUtil "github.com/containers/buildah/internal/util"
|
||||
"github.com/containers/buildah/internal/volumes"
|
||||
"github.com/containers/buildah/pkg/overlay"
|
||||
"github.com/containers/buildah/pkg/sshagent"
|
||||
@@ -40,21 +40,19 @@ import (
|
||||
"github.com/containers/common/pkg/config"
|
||||
"github.com/containers/common/pkg/subscriptions"
|
||||
"github.com/containers/image/v5/types"
|
||||
imageTypes "github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/fileutils"
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/containers/storage/pkg/ioutils"
|
||||
"github.com/containers/storage/pkg/lockfile"
|
||||
"github.com/containers/storage/pkg/mount"
|
||||
"github.com/containers/storage/pkg/reexec"
|
||||
"github.com/containers/storage/pkg/unshare"
|
||||
storageTypes "github.com/containers/storage/types"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/runtime-tools/generate"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/slices"
|
||||
"golang.org/x/sys/unix"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
@@ -1311,7 +1309,9 @@ func init() {
|
||||
reexec.Register(runUsingRuntimeCommand, runUsingRuntimeMain)
|
||||
}
|
||||
|
||||
// If this succeeds, the caller must call cleanupMounts().
|
||||
// If this succeeds, after the command which uses the spec finishes running,
|
||||
// the caller must call b.cleanupRunMounts() on the returned runMountArtifacts
|
||||
// structure.
|
||||
func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath string, optionMounts []specs.Mount, bindFiles map[string]string, builtinVolumes []string, compatBuiltinVolumes types.OptionalBool, volumeMounts []string, runFileMounts []string, runMountInfo runMountInfo) (*runMountArtifacts, error) {
|
||||
// Start building a new list of mounts.
|
||||
var mounts []specs.Mount
|
||||
@@ -1370,14 +1370,16 @@ func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath st
|
||||
processGID: int(processGID),
|
||||
}
|
||||
// Get the list of mounts that are just for this Run() call.
|
||||
runMounts, mountArtifacts, err := b.runSetupRunMounts(mountPoint, runFileMounts, runMountInfo, idMaps)
|
||||
runMounts, mountArtifacts, err := b.runSetupRunMounts(mountPoint, bundlePath, runFileMounts, runMountInfo, idMaps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
succeeded := false
|
||||
defer func() {
|
||||
if !succeeded {
|
||||
volumes.UnlockLockArray(mountArtifacts.TargetLocks)
|
||||
if err := b.cleanupRunMounts(mountPoint, mountArtifacts); err != nil {
|
||||
b.Logger.Debugf("cleaning up run mounts: %v", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
// Add temporary copies of the contents of volume locations at the
|
||||
@@ -1532,28 +1534,61 @@ func checkIfMountDestinationPreExists(root string, dest string) (bool, error) {
|
||||
|
||||
// runSetupRunMounts sets up mounts that exist only in this RUN, not in subsequent runs
|
||||
//
|
||||
// If this function succeeds, the caller must unlock runMountArtifacts.TargetLocks (when??)
|
||||
func (b *Builder) runSetupRunMounts(mountPoint string, mounts []string, sources runMountInfo, idMaps IDMaps) ([]specs.Mount, *runMountArtifacts, error) {
|
||||
mountTargets := make([]string, 0, 10)
|
||||
// If this function succeeds, the caller must free the returned
|
||||
// runMountArtifacts by calling b.cleanupRunMounts() after the command being
|
||||
// executed with those mounts has finished.
|
||||
func (b *Builder) runSetupRunMounts(mountPoint, bundlePath string, mounts []string, sources runMountInfo, idMaps IDMaps) ([]specs.Mount, *runMountArtifacts, error) {
|
||||
mountTargets := make([]string, 0, len(mounts))
|
||||
tmpFiles := make([]string, 0, len(mounts))
|
||||
mountImages := make([]string, 0, 10)
|
||||
mountImages := make([]string, 0, len(mounts))
|
||||
intermediateMounts := make([]string, 0, len(mounts))
|
||||
finalMounts := make([]specs.Mount, 0, len(mounts))
|
||||
agents := make([]*sshagent.AgentServer, 0, len(mounts))
|
||||
sshCount := 0
|
||||
defaultSSHSock := ""
|
||||
targetLocks := []*lockfile.LockFile{}
|
||||
var overlayDirs []string
|
||||
succeeded := false
|
||||
defer func() {
|
||||
if !succeeded {
|
||||
for _, agent := range agents {
|
||||
servePath := agent.ServePath()
|
||||
if err := agent.Shutdown(); err != nil {
|
||||
b.Logger.Errorf("shutting down SSH agent at %q: %v", servePath, err)
|
||||
}
|
||||
}
|
||||
for _, overlayDir := range overlayDirs {
|
||||
if err := overlay.RemoveTemp(overlayDir); err != nil {
|
||||
b.Logger.Error(err.Error())
|
||||
}
|
||||
}
|
||||
for _, intermediateMount := range intermediateMounts {
|
||||
if err := mount.Unmount(intermediateMount); err != nil {
|
||||
b.Logger.Errorf("unmounting %q: %v", intermediateMount, err)
|
||||
}
|
||||
if err := os.Remove(intermediateMount); err != nil {
|
||||
b.Logger.Errorf("removing should-be-empty directory %q: %v", intermediateMount, err)
|
||||
}
|
||||
}
|
||||
for _, mountImage := range mountImages {
|
||||
if _, err := b.store.UnmountImage(mountImage, false); err != nil {
|
||||
b.Logger.Error(err.Error())
|
||||
}
|
||||
}
|
||||
for _, tmpFile := range tmpFiles {
|
||||
if err := os.Remove(tmpFile); err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
b.Logger.Error(err.Error())
|
||||
}
|
||||
}
|
||||
volumes.UnlockLockArray(targetLocks)
|
||||
}
|
||||
}()
|
||||
for _, mount := range mounts {
|
||||
var mountSpec *specs.Mount
|
||||
var err error
|
||||
var envFile, image string
|
||||
var envFile, image, bundleMountsDir, overlayDir, intermediateMount string
|
||||
var agent *sshagent.AgentServer
|
||||
var tl *lockfile.LockFile
|
||||
|
||||
tokens := strings.Split(mount, ",")
|
||||
|
||||
// If `type` is not set default to TypeBind
|
||||
@@ -1581,29 +1616,37 @@ func (b *Builder) runSetupRunMounts(mountPoint string, mounts []string, sources
|
||||
}
|
||||
}
|
||||
case "ssh":
|
||||
mountSpec, agent, err = b.getSSHMount(tokens, sshCount, sources.SSHSources, idMaps)
|
||||
mountSpec, agent, err = b.getSSHMount(tokens, len(agents), sources.SSHSources, idMaps)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if mountSpec != nil {
|
||||
finalMounts = append(finalMounts, *mountSpec)
|
||||
agents = append(agents, agent)
|
||||
if sshCount == 0 {
|
||||
if len(agents) == 0 {
|
||||
defaultSSHSock = mountSpec.Destination
|
||||
}
|
||||
// Count is needed as the default destination of the ssh sock inside the container is /run/buildkit/ssh_agent.{i}
|
||||
sshCount++
|
||||
agents = append(agents, agent)
|
||||
}
|
||||
case define.TypeBind:
|
||||
mountSpec, image, err = b.getBindMount(tokens, sources.SystemContext, sources.ContextDir, sources.StageMountPoints, idMaps, sources.WorkDir)
|
||||
if bundleMountsDir == "" {
|
||||
if bundleMountsDir, err = os.MkdirTemp(bundlePath, "mounts"); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
mountSpec, image, intermediateMount, overlayDir, err = b.getBindMount(tokens, sources.SystemContext, sources.ContextDir, sources.StageMountPoints, idMaps, sources.WorkDir, bundleMountsDir)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
finalMounts = append(finalMounts, *mountSpec)
|
||||
// only perform cleanup if image was mounted ignore everything else
|
||||
if image != "" {
|
||||
mountImages = append(mountImages, image)
|
||||
}
|
||||
if intermediateMount != "" {
|
||||
intermediateMounts = append(intermediateMounts, intermediateMount)
|
||||
}
|
||||
if overlayDir != "" {
|
||||
overlayDirs = append(overlayDirs, overlayDir)
|
||||
}
|
||||
finalMounts = append(finalMounts, *mountSpec)
|
||||
case "tmpfs":
|
||||
mountSpec, err = b.getTmpfsMount(tokens, idMaps, sources.WorkDir)
|
||||
if err != nil {
|
||||
@@ -1611,14 +1654,28 @@ func (b *Builder) runSetupRunMounts(mountPoint string, mounts []string, sources
|
||||
}
|
||||
finalMounts = append(finalMounts, *mountSpec)
|
||||
case "cache":
|
||||
mountSpec, tl, err = b.getCacheMount(tokens, sources.StageMountPoints, idMaps, sources.WorkDir)
|
||||
if bundleMountsDir == "" {
|
||||
if bundleMountsDir, err = os.MkdirTemp(bundlePath, "mounts"); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
mountSpec, image, intermediateMount, overlayDir, tl, err = b.getCacheMount(tokens, sources.SystemContext, sources.StageMountPoints, idMaps, sources.WorkDir, bundleMountsDir)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
finalMounts = append(finalMounts, *mountSpec)
|
||||
if image != "" {
|
||||
mountImages = append(mountImages, image)
|
||||
}
|
||||
if intermediateMount != "" {
|
||||
intermediateMounts = append(intermediateMounts, intermediateMount)
|
||||
}
|
||||
if overlayDir != "" {
|
||||
overlayDirs = append(overlayDirs, overlayDir)
|
||||
}
|
||||
if tl != nil {
|
||||
targetLocks = append(targetLocks, tl)
|
||||
}
|
||||
finalMounts = append(finalMounts, *mountSpec)
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("invalid mount type %q", mountType)
|
||||
}
|
||||
@@ -1638,31 +1695,57 @@ func (b *Builder) runSetupRunMounts(mountPoint string, mounts []string, sources
|
||||
}
|
||||
succeeded = true
|
||||
artifacts := &runMountArtifacts{
|
||||
RunMountTargets: mountTargets,
|
||||
TmpFiles: tmpFiles,
|
||||
Agents: agents,
|
||||
MountedImages: mountImages,
|
||||
SSHAuthSock: defaultSSHSock,
|
||||
TargetLocks: targetLocks,
|
||||
RunMountTargets: mountTargets,
|
||||
RunOverlayDirs: overlayDirs,
|
||||
TmpFiles: tmpFiles,
|
||||
Agents: agents,
|
||||
MountedImages: mountImages,
|
||||
SSHAuthSock: defaultSSHSock,
|
||||
TargetLocks: targetLocks,
|
||||
IntermediateMounts: intermediateMounts,
|
||||
}
|
||||
return finalMounts, artifacts, nil
|
||||
}
|
||||
|
||||
func (b *Builder) getBindMount(tokens []string, context *imageTypes.SystemContext, contextDir string, stageMountPoints map[string]internal.StageMountDetails, idMaps IDMaps, workDir string) (*specs.Mount, string, error) {
|
||||
func (b *Builder) getBindMount(tokens []string, sys *types.SystemContext, contextDir string, stageMountPoints map[string]internal.StageMountDetails, idMaps IDMaps, workDir, tmpDir string) (*specs.Mount, string, string, string, error) {
|
||||
if contextDir == "" {
|
||||
return nil, "", errors.New("Context Directory for current run invocation is not configured")
|
||||
return nil, "", "", "", errors.New("context directory for current run invocation is not configured")
|
||||
}
|
||||
var optionMounts []specs.Mount
|
||||
mount, image, err := volumes.GetBindMount(context, tokens, contextDir, b.store, b.MountLabel, stageMountPoints, workDir)
|
||||
optionMount, image, intermediateMount, overlayMount, err := volumes.GetBindMount(sys, tokens, contextDir, b.store, b.MountLabel, stageMountPoints, workDir, tmpDir)
|
||||
if err != nil {
|
||||
return nil, image, err
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
optionMounts = append(optionMounts, mount)
|
||||
succeeded := false
|
||||
defer func() {
|
||||
if !succeeded {
|
||||
if overlayMount != "" {
|
||||
if err := overlay.RemoveTemp(overlayMount); err != nil {
|
||||
b.Logger.Debug(err.Error())
|
||||
}
|
||||
}
|
||||
if intermediateMount != "" {
|
||||
if err := mount.Unmount(intermediateMount); err != nil {
|
||||
b.Logger.Debugf("unmounting %q: %v", intermediateMount, err)
|
||||
}
|
||||
if err := os.Remove(intermediateMount); err != nil {
|
||||
b.Logger.Debugf("removing should-be-empty directory %q: %v", intermediateMount, err)
|
||||
}
|
||||
}
|
||||
if image != "" {
|
||||
if _, err := b.store.UnmountImage(image, false); err != nil {
|
||||
b.Logger.Debugf("unmounting image %q: %v", image, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
optionMounts = append(optionMounts, optionMount)
|
||||
volumes, err := b.runSetupVolumeMounts(b.MountLabel, nil, optionMounts, idMaps)
|
||||
if err != nil {
|
||||
return nil, image, err
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
return &volumes[0], image, nil
|
||||
succeeded = true
|
||||
return &volumes[0], image, intermediateMount, overlayMount, nil
|
||||
}
|
||||
|
||||
func (b *Builder) getTmpfsMount(tokens []string, idMaps IDMaps, workDir string) (*specs.Mount, error) {
|
||||
@@ -1939,52 +2022,53 @@ func (b *Builder) cleanupTempVolumes() {
|
||||
}
|
||||
|
||||
// cleanupRunMounts cleans up run mounts so they only appear in this run.
|
||||
func (b *Builder) cleanupRunMounts(context *imageTypes.SystemContext, mountpoint string, artifacts *runMountArtifacts) error {
|
||||
func (b *Builder) cleanupRunMounts(mountpoint string, artifacts *runMountArtifacts) error {
|
||||
for _, agent := range artifacts.Agents {
|
||||
err := agent.Shutdown()
|
||||
if err != nil {
|
||||
servePath := agent.ServePath()
|
||||
if err := agent.Shutdown(); err != nil {
|
||||
return fmt.Errorf("shutting down SSH agent at %q: %v", servePath, err)
|
||||
}
|
||||
}
|
||||
// clean up any overlays we mounted
|
||||
for _, overlayDirectory := range artifacts.RunOverlayDirs {
|
||||
if err := overlay.RemoveTemp(overlayDirectory); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup any mounted images for this run
|
||||
// unmount anything that needs unmounting
|
||||
for _, intermediateMount := range artifacts.IntermediateMounts {
|
||||
if err := mount.Unmount(intermediateMount); err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
return fmt.Errorf("unmounting %q: %w", intermediateMount, err)
|
||||
}
|
||||
if err := os.Remove(intermediateMount); err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
return fmt.Errorf("removing should-be-empty directory %q: %w", intermediateMount, err)
|
||||
}
|
||||
}
|
||||
// unmount any images we mounted for this run
|
||||
for _, image := range artifacts.MountedImages {
|
||||
if image != "" {
|
||||
// if flow hits here some image was mounted for this run
|
||||
i, err := internalUtil.LookupImage(context, b.store, image)
|
||||
if err == nil {
|
||||
// silently try to unmount and do nothing
|
||||
// if image is being used by something else
|
||||
_ = i.Unmount(false)
|
||||
}
|
||||
if errors.Is(err, storageTypes.ErrImageUnknown) {
|
||||
// Ignore only if ErrImageUnknown
|
||||
// Reason: Image is already unmounted do nothing
|
||||
continue
|
||||
}
|
||||
return err
|
||||
if _, err := b.store.UnmountImage(image, false); err != nil {
|
||||
logrus.Debugf("umounting image %q: %v", image, err)
|
||||
}
|
||||
}
|
||||
// remove mount targets that were created for this run
|
||||
opts := copier.RemoveOptions{
|
||||
All: true,
|
||||
}
|
||||
for _, path := range artifacts.RunMountTargets {
|
||||
err := copier.Remove(mountpoint, path, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
if err := copier.Remove(mountpoint, path, opts); err != nil {
|
||||
return fmt.Errorf("removing mount target %q %q: %w", mountpoint, path, err)
|
||||
}
|
||||
}
|
||||
var prevErr error
|
||||
for _, path := range artifacts.TmpFiles {
|
||||
err := os.Remove(path)
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
if err := os.Remove(path); err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
if prevErr != nil {
|
||||
logrus.Error(prevErr)
|
||||
}
|
||||
prevErr = err
|
||||
prevErr = fmt.Errorf("removing temporary file: %w", err)
|
||||
}
|
||||
}
|
||||
// unlock if any locked files from this RUN statement
|
||||
// unlock locks we took, most likely for cache mounts
|
||||
volumes.UnlockLockArray(artifacts.TargetLocks)
|
||||
return prevErr
|
||||
}
|
||||
@@ -1999,8 +2083,8 @@ func setPdeathsig(cmd *exec.Cmd) {
|
||||
cmd.SysProcAttr.Pdeathsig = syscall.SIGKILL
|
||||
}
|
||||
|
||||
func relabel(path, mountLabel string, recurse bool) error {
|
||||
if err := label.Relabel(path, mountLabel, recurse); err != nil {
|
||||
func relabel(path, mountLabel string, shared bool) error {
|
||||
if err := label.Relabel(path, mountLabel, shared); err != nil {
|
||||
if !errors.Is(err, syscall.ENOTSUP) {
|
||||
return err
|
||||
}
|
||||
|
||||
40
vendor/github.com/containers/buildah/run_freebsd.go
generated
vendored
40
vendor/github.com/containers/buildah/run_freebsd.go
generated
vendored
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
@@ -26,15 +27,14 @@ import (
|
||||
nettypes "github.com/containers/common/libnetwork/types"
|
||||
netUtil "github.com/containers/common/libnetwork/util"
|
||||
"github.com/containers/common/pkg/config"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/containers/storage/pkg/lockfile"
|
||||
"github.com/containers/storage/pkg/stringid"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/runtime-tools/generate"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/slices"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@@ -73,6 +73,24 @@ func setChildProcess() error {
|
||||
}
|
||||
|
||||
func (b *Builder) Run(command []string, options RunOptions) error {
|
||||
var runArtifacts *runMountArtifacts
|
||||
if len(options.ExternalImageMounts) > 0 {
|
||||
defer func() {
|
||||
if runArtifacts == nil {
|
||||
// we didn't add ExternalImageMounts to the
|
||||
// list of images that we're going to unmount
|
||||
// yet and make a deferred call that cleans
|
||||
// them up, but the caller is expecting us to
|
||||
// unmount these for them because we offered to
|
||||
for _, image := range options.ExternalImageMounts {
|
||||
if _, err := b.store.UnmountImage(image, false); err != nil {
|
||||
logrus.Debugf("umounting image %q: %v", image, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
p, err := os.MkdirTemp(tmpdir.GetTempDir(), define.Package)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -263,7 +281,7 @@ func (b *Builder) Run(command []string, options RunOptions) error {
|
||||
SystemContext: options.SystemContext,
|
||||
}
|
||||
|
||||
runArtifacts, err := b.setupMounts(mountPoint, spec, path, options.Mounts, bindFiles, volumes, options.CompatBuiltinVolumes, b.CommonBuildOpts.Volumes, options.RunMounts, runMountInfo)
|
||||
runArtifacts, err = b.setupMounts(mountPoint, spec, path, options.Mounts, bindFiles, volumes, options.CompatBuiltinVolumes, b.CommonBuildOpts.Volumes, options.RunMounts, runMountInfo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving mountpoints for container %q: %w", b.ContainerID, err)
|
||||
}
|
||||
@@ -280,7 +298,7 @@ func (b *Builder) Run(command []string, options RunOptions) error {
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := b.cleanupRunMounts(options.SystemContext, mountPoint, runArtifacts); err != nil {
|
||||
if err := b.cleanupRunMounts(mountPoint, runArtifacts); err != nil {
|
||||
options.Logger.Errorf("unable to cleanup run mounts %v", err)
|
||||
}
|
||||
}()
|
||||
@@ -328,7 +346,7 @@ func (b *Builder) Run(command []string, options RunOptions) error {
|
||||
}
|
||||
err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, networkString, moreCreateArgs, spec, mountPoint, path, containerName, b.Container, hostsFile, resolvFile)
|
||||
case IsolationChroot:
|
||||
err = chroot.RunUsingChroot(spec, path, homeDir, options.Stdin, options.Stdout, options.Stderr)
|
||||
err = chroot.RunUsingChroot(spec, path, homeDir, options.Stdin, options.Stdout, options.Stderr, options.NoPivot)
|
||||
default:
|
||||
err = errors.New("don't know how to run this command")
|
||||
}
|
||||
@@ -351,13 +369,17 @@ func addCommonOptsToSpec(commonOpts *define.CommonBuildOptions, g *generate.Gene
|
||||
|
||||
// setupSpecialMountSpecChanges creates special mounts for depending
|
||||
// on the namespaces - nothing yet for freebsd
|
||||
func setupSpecialMountSpecChanges(spec *spec.Spec, shmSize string) ([]specs.Mount, error) {
|
||||
func setupSpecialMountSpecChanges(spec *specs.Spec, shmSize string) ([]specs.Mount, error) {
|
||||
return spec.Mounts, nil
|
||||
}
|
||||
|
||||
// If this function succeeds and returns a non-nil *lockfile.LockFile, the caller must unlock it (when??).
|
||||
func (b *Builder) getCacheMount(tokens []string, stageMountPoints map[string]internal.StageMountDetails, idMaps IDMaps, workDir string) (*spec.Mount, *lockfile.LockFile, error) {
|
||||
return nil, nil, errors.New("cache mounts not supported on freebsd")
|
||||
// If this succeeded, the caller would be expected to, after the command which
|
||||
// uses the mount exits, clean up the overlay filesystem (if we returned one),
|
||||
// unmount the mounted filesystem (if we provided the path to its mountpoint)
|
||||
// and remove its mountpoint, unmount the image (if we mounted one), and
|
||||
// release the lock (if we took one).
|
||||
func (b *Builder) getCacheMount(tokens []string, sys *types.SystemContext, stageMountPoints map[string]internal.StageMountDetails, idMaps IDMaps, workDir, tmpDir string) (*specs.Mount, string, string, string, *lockfile.LockFile, error) {
|
||||
return nil, "", "", "", nil, errors.New("cache mounts not supported on freebsd")
|
||||
}
|
||||
|
||||
func (b *Builder) runSetupVolumeMounts(mountLabel string, volumeMounts []string, optionMounts []specs.Mount, idMaps IDMaps) (mounts []specs.Mount, Err error) {
|
||||
|
||||
90
vendor/github.com/containers/buildah/run_linux.go
generated
vendored
90
vendor/github.com/containers/buildah/run_linux.go
generated
vendored
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
@@ -35,17 +36,18 @@ import (
|
||||
"github.com/containers/common/pkg/config"
|
||||
"github.com/containers/common/pkg/hooks"
|
||||
hooksExec "github.com/containers/common/pkg/hooks/exec"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage/pkg/fileutils"
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/containers/storage/pkg/ioutils"
|
||||
"github.com/containers/storage/pkg/lockfile"
|
||||
"github.com/containers/storage/pkg/mount"
|
||||
"github.com/containers/storage/pkg/stringid"
|
||||
"github.com/containers/storage/pkg/unshare"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/runtime-tools/generate"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/slices"
|
||||
"golang.org/x/sys/unix"
|
||||
"tags.cncf.io/container-device-interface/pkg/cdi"
|
||||
"tags.cncf.io/container-device-interface/pkg/parser"
|
||||
@@ -165,6 +167,24 @@ func separateDevicesFromRuntimeSpec(g *generate.Generator) define.ContainerDevic
|
||||
|
||||
// Run runs the specified command in the container's root filesystem.
|
||||
func (b *Builder) Run(command []string, options RunOptions) error {
|
||||
var runArtifacts *runMountArtifacts
|
||||
if len(options.ExternalImageMounts) > 0 {
|
||||
defer func() {
|
||||
if runArtifacts == nil {
|
||||
// we didn't add ExternalImageMounts to the
|
||||
// list of images that we're going to unmount
|
||||
// yet and make a deferred call that cleans
|
||||
// them up, but the caller is expecting us to
|
||||
// unmount these for them because we offered to
|
||||
for _, image := range options.ExternalImageMounts {
|
||||
if _, err := b.store.UnmountImage(image, false); err != nil {
|
||||
logrus.Debugf("umounting image %q: %v", image, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
if os.Getenv("container") != "" {
|
||||
os, arch, variant, err := parse.Platform("")
|
||||
if err != nil {
|
||||
@@ -328,7 +348,7 @@ func (b *Builder) Run(command []string, options RunOptions) error {
|
||||
}
|
||||
}
|
||||
|
||||
setupMaskedPaths(g)
|
||||
setupMaskedPaths(g, b.CommonBuildOpts)
|
||||
setupReadOnlyPaths(g)
|
||||
|
||||
setupTerminal(g, options.Terminal, options.TerminalSize)
|
||||
@@ -498,7 +518,7 @@ rootless=%d
|
||||
SystemContext: options.SystemContext,
|
||||
}
|
||||
|
||||
runArtifacts, err := b.setupMounts(mountPoint, spec, path, options.Mounts, bindFiles, volumes, options.CompatBuiltinVolumes, b.CommonBuildOpts.Volumes, options.RunMounts, runMountInfo)
|
||||
runArtifacts, err = b.setupMounts(mountPoint, spec, path, options.Mounts, bindFiles, volumes, options.CompatBuiltinVolumes, b.CommonBuildOpts.Volumes, options.RunMounts, runMountInfo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving mountpoints for container %q: %w", b.ContainerID, err)
|
||||
}
|
||||
@@ -515,7 +535,7 @@ rootless=%d
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := b.cleanupRunMounts(options.SystemContext, mountPoint, runArtifacts); err != nil {
|
||||
if err := b.cleanupRunMounts(mountPoint, runArtifacts); err != nil {
|
||||
options.Logger.Errorf("unable to cleanup run mounts %v", err)
|
||||
}
|
||||
}()
|
||||
@@ -531,7 +551,7 @@ rootless=%d
|
||||
err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, networkString, moreCreateArgs, spec,
|
||||
mountPoint, path, define.Package+"-"+filepath.Base(path), b.Container, hostsFile, resolvFile)
|
||||
case IsolationChroot:
|
||||
err = chroot.RunUsingChroot(spec, path, homeDir, options.Stdin, options.Stdout, options.Stderr)
|
||||
err = chroot.RunUsingChroot(spec, path, homeDir, options.Stdin, options.Stdout, options.Stderr, options.NoPivot)
|
||||
case IsolationOCIRootless:
|
||||
moreCreateArgs := []string{"--no-new-keyring"}
|
||||
if options.NoPivot {
|
||||
@@ -1141,7 +1161,7 @@ func (b *Builder) runSetupVolumeMounts(mountLabel string, volumeMounts []string,
|
||||
RootGID: idMaps.rootGID,
|
||||
UpperDirOptionFragment: upperDir,
|
||||
WorkDirOptionFragment: workDir,
|
||||
GraphOpts: b.store.GraphOptions(),
|
||||
GraphOpts: slices.Clone(b.store.GraphOptions()),
|
||||
}
|
||||
|
||||
overlayMount, err := overlay.MountWithOptions(contentDir, host, container, &overlayOpts)
|
||||
@@ -1150,7 +1170,7 @@ func (b *Builder) runSetupVolumeMounts(mountLabel string, volumeMounts []string,
|
||||
}
|
||||
|
||||
// If chown true, add correct ownership to the overlay temp directories.
|
||||
if foundU {
|
||||
if err == nil && foundU {
|
||||
if err := chown.ChangeHostPathOwnership(contentDir, true, idMaps.processUID, idMaps.processGID); err != nil {
|
||||
return specs.Mount{}, err
|
||||
}
|
||||
@@ -1199,8 +1219,14 @@ func (b *Builder) runSetupVolumeMounts(mountLabel string, volumeMounts []string,
|
||||
return mounts, nil
|
||||
}
|
||||
|
||||
func setupMaskedPaths(g *generate.Generator) {
|
||||
for _, mp := range config.DefaultMaskedPaths {
|
||||
func setupMaskedPaths(g *generate.Generator, opts *define.CommonBuildOptions) {
|
||||
if slices.Contains(opts.Unmasks, "all") {
|
||||
return
|
||||
}
|
||||
for _, mp := range append(config.DefaultMaskedPaths, opts.Masks...) {
|
||||
if slices.Contains(opts.Unmasks, mp) {
|
||||
continue
|
||||
}
|
||||
g.AddLinuxMaskedPaths(mp)
|
||||
}
|
||||
}
|
||||
@@ -1402,24 +1428,52 @@ func checkIDsGreaterThan5(ids []specs.LinuxIDMapping) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// If this function succeeds and returns a non-nil *lockfile.LockFile, the caller must unlock it (when??).
|
||||
func (b *Builder) getCacheMount(tokens []string, stageMountPoints map[string]internal.StageMountDetails, idMaps IDMaps, workDir string) (*specs.Mount, *lockfile.LockFile, error) {
|
||||
// Returns a Mount to add to the runtime spec's list of mounts, the ID of an
|
||||
// image, the path to a mounted filesystem, and the path to an overlay
|
||||
// filesystem, and an optional lock, or an error.
|
||||
//
|
||||
// The caller is expected to, after the command which uses the mount exits,
|
||||
// clean up the overlay filesystem (if we returned one), unmount the mounted
|
||||
// filesystem (if we provided the path to its mountpoint) and remove its
|
||||
// mountpoint, unmount the image (if we mounted one), and release the lock (if
|
||||
// we took one).
|
||||
func (b *Builder) getCacheMount(tokens []string, sys *types.SystemContext, stageMountPoints map[string]internal.StageMountDetails, idMaps IDMaps, workDir, tmpDir string) (*specs.Mount, string, string, string, *lockfile.LockFile, error) {
|
||||
var optionMounts []specs.Mount
|
||||
mount, targetLock, err := volumes.GetCacheMount(tokens, b.store, b.MountLabel, stageMountPoints, workDir)
|
||||
optionMount, mountedImage, intermediateMount, overlayMount, targetLock, err := volumes.GetCacheMount(sys, tokens, b.store, b.MountLabel, stageMountPoints, idMaps.uidmap, idMaps.gidmap, workDir, tmpDir)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, "", "", "", nil, err
|
||||
}
|
||||
succeeded := false
|
||||
defer func() {
|
||||
if !succeeded && targetLock != nil {
|
||||
targetLock.Unlock()
|
||||
if !succeeded {
|
||||
if overlayMount != "" {
|
||||
if err := overlay.RemoveTemp(overlayMount); err != nil {
|
||||
b.Logger.Debug(err.Error())
|
||||
}
|
||||
}
|
||||
if intermediateMount != "" {
|
||||
if err := mount.Unmount(intermediateMount); err != nil {
|
||||
b.Logger.Debugf("unmounting %q: %v", intermediateMount, err)
|
||||
}
|
||||
if err := os.Remove(intermediateMount); err != nil {
|
||||
b.Logger.Debugf("removing should-be-empty directory %q: %v", intermediateMount, err)
|
||||
}
|
||||
}
|
||||
if mountedImage != "" {
|
||||
if _, err := b.store.UnmountImage(mountedImage, false); err != nil {
|
||||
b.Logger.Debugf("unmounting image %q: %v", mountedImage, err)
|
||||
}
|
||||
}
|
||||
if targetLock != nil {
|
||||
targetLock.Unlock()
|
||||
}
|
||||
}
|
||||
}()
|
||||
optionMounts = append(optionMounts, mount)
|
||||
optionMounts = append(optionMounts, optionMount)
|
||||
volumes, err := b.runSetupVolumeMounts(b.MountLabel, nil, optionMounts, idMaps)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, "", "", "", nil, err
|
||||
}
|
||||
succeeded = true
|
||||
return &volumes[0], targetLock, nil
|
||||
return &volumes[0], mountedImage, intermediateMount, overlayMount, targetLock, nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/containers/buildah/scan.go
generated
vendored
2
vendor/github.com/containers/buildah/scan.go
generated
vendored
@@ -6,6 +6,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/buildah/define"
|
||||
@@ -13,7 +14,6 @@ import (
|
||||
"github.com/mattn/go-shellwords"
|
||||
rspec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
func stringSliceReplaceAll(slice []string, replacements map[string]string, important []string) (built []string, replacedAnImportantValue bool) {
|
||||
|
||||
4
vendor/github.com/containers/buildah/util/util.go
generated
vendored
4
vendor/github.com/containers/buildah/util/util.go
generated
vendored
@@ -7,6 +7,7 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"syscall"
|
||||
@@ -24,7 +25,6 @@ import (
|
||||
"github.com/opencontainers/go-digest"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -42,7 +42,7 @@ var RegistryDefaultPathPrefix = map[string]string{
|
||||
"docker.io": "library",
|
||||
}
|
||||
|
||||
// StringInSlice is deprecated, use golang.org/x/exp/slices.Contains
|
||||
// StringInSlice is deprecated, use slices.Contains
|
||||
func StringInSlice(s string, slice []string) bool {
|
||||
return slices.Contains(slice, s)
|
||||
}
|
||||
|
||||
2
vendor/github.com/containers/storage/pkg/chrootarchive/archive.go
generated
vendored
2
vendor/github.com/containers/storage/pkg/chrootarchive/archive.go
generated
vendored
@@ -47,7 +47,7 @@ func Untar(tarArchive io.Reader, dest string, options *archive.TarOptions) error
|
||||
// This should be used to prevent a potential attacker from manipulating `dest`
|
||||
// such that it would provide access to files outside of `dest` through things
|
||||
// like symlinks. Normally `ResolveSymlinksInScope` would handle this, however
|
||||
// sanitizing symlinks in this manner is inherrently racey:
|
||||
// sanitizing symlinks in this manner is inherently racey:
|
||||
// ref: CVE-2018-15664
|
||||
func UntarWithRoot(tarArchive io.Reader, dest string, options *archive.TarOptions, root string) error {
|
||||
return untarHandler(tarArchive, dest, options, true, root)
|
||||
|
||||
4
vendor/github.com/containers/storage/pkg/ioutils/writers.go
generated
vendored
4
vendor/github.com/containers/storage/pkg/ioutils/writers.go
generated
vendored
@@ -36,9 +36,9 @@ func (r *writeCloserWrapper) Close() error {
|
||||
}
|
||||
|
||||
// NewWriteCloserWrapper returns a new io.WriteCloser.
|
||||
func NewWriteCloserWrapper(r io.Writer, closer func() error) io.WriteCloser {
|
||||
func NewWriteCloserWrapper(w io.Writer, closer func() error) io.WriteCloser {
|
||||
return &writeCloserWrapper{
|
||||
Writer: r,
|
||||
Writer: w,
|
||||
closer: closer,
|
||||
}
|
||||
}
|
||||
|
||||
15
vendor/github.com/moby/buildkit/frontend/dockerfile/parser/directives.go
generated
vendored
15
vendor/github.com/moby/buildkit/frontend/dockerfile/parser/directives.go
generated
vendored
@@ -112,10 +112,15 @@ func (d *DirectiveParser) ParseAll(data []byte) ([]*Directive, error) {
|
||||
// This allows for a flexible range of input formats, and appropriate syntax
|
||||
// selection.
|
||||
func DetectSyntax(dt []byte) (string, string, []Range, bool) {
|
||||
return ParseDirective(keySyntax, dt)
|
||||
return parseDirective(keySyntax, dt, true)
|
||||
}
|
||||
|
||||
func ParseDirective(key string, dt []byte) (string, string, []Range, bool) {
|
||||
return parseDirective(key, dt, false)
|
||||
}
|
||||
|
||||
func parseDirective(key string, dt []byte, anyFormat bool) (string, string, []Range, bool) {
|
||||
dt = discardBOM(dt)
|
||||
dt, hadShebang, err := discardShebang(dt)
|
||||
if err != nil {
|
||||
return "", "", nil, false
|
||||
@@ -131,6 +136,10 @@ func ParseDirective(key string, dt []byte) (string, string, []Range, bool) {
|
||||
return syntax, cmdline, loc, true
|
||||
}
|
||||
|
||||
if !anyFormat {
|
||||
return "", "", nil, false
|
||||
}
|
||||
|
||||
// use directive with different comment prefix, and search for //key=
|
||||
directiveParser = DirectiveParser{line: line}
|
||||
directiveParser.setComment("//")
|
||||
@@ -171,3 +180,7 @@ func discardShebang(dt []byte) ([]byte, bool, error) {
|
||||
}
|
||||
return dt, false, nil
|
||||
}
|
||||
|
||||
func discardBOM(dt []byte) []byte {
|
||||
return bytes.TrimPrefix(dt, []byte{0xEF, 0xBB, 0xBF})
|
||||
}
|
||||
|
||||
4
vendor/github.com/moby/buildkit/frontend/dockerfile/parser/parser.go
generated
vendored
4
vendor/github.com/moby/buildkit/frontend/dockerfile/parser/parser.go
generated
vendored
@@ -291,7 +291,7 @@ func Parse(rwc io.Reader) (*Result, error) {
|
||||
bytesRead := scanner.Bytes()
|
||||
if currentLine == 0 {
|
||||
// First line, strip the byte-order-marker if present
|
||||
bytesRead = bytes.TrimPrefix(bytesRead, utf8bom)
|
||||
bytesRead = discardBOM(bytesRead)
|
||||
}
|
||||
if isComment(bytesRead) {
|
||||
comment := strings.TrimSpace(string(bytesRead[1:]))
|
||||
@@ -522,8 +522,6 @@ func isEmptyContinuationLine(line []byte) bool {
|
||||
return len(trimLeadingWhitespace(trimNewline(line))) == 0
|
||||
}
|
||||
|
||||
var utf8bom = []byte{0xEF, 0xBB, 0xBF}
|
||||
|
||||
func trimContinuationCharacter(line []byte, d *directives) ([]byte, bool) {
|
||||
if d.lineContinuationRegex.Match(line) {
|
||||
line = d.lineContinuationRegex.ReplaceAll(line, []byte("$1"))
|
||||
|
||||
1
vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_unix.go
generated
vendored
1
vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_unix.go
generated
vendored
@@ -1,5 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package shell
|
||||
|
||||
|
||||
2
vendor/github.com/moby/buildkit/util/stack/stack.pb.go
generated
vendored
2
vendor/github.com/moby/buildkit/util/stack/stack.pb.go
generated
vendored
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.35.1
|
||||
// protoc-gen-go v1.35.2
|
||||
// protoc v3.11.4
|
||||
// source: github.com/moby/buildkit/util/stack/stack.proto
|
||||
|
||||
|
||||
15
vendor/github.com/vishvananda/netlink/addr_linux.go
generated
vendored
15
vendor/github.com/vishvananda/netlink/addr_linux.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
@@ -169,6 +170,9 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
|
||||
// AddrList gets a list of IP addresses in the system.
|
||||
// Equivalent to: `ip addr show`.
|
||||
// The list can be filtered by link and ip family.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func AddrList(link Link, family int) ([]Addr, error) {
|
||||
return pkgHandle.AddrList(link, family)
|
||||
}
|
||||
@@ -176,14 +180,17 @@ func AddrList(link Link, family int) ([]Addr, error) {
|
||||
// AddrList gets a list of IP addresses in the system.
|
||||
// Equivalent to: `ip addr show`.
|
||||
// The list can be filtered by link and ip family.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETADDR, unix.NLM_F_DUMP)
|
||||
msg := nl.NewIfAddrmsg(family)
|
||||
req.AddData(msg)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWADDR)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWADDR)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
|
||||
indexFilter := 0
|
||||
@@ -212,7 +219,7 @@ func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
|
||||
res = append(res, addr)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
return res, executeErr
|
||||
}
|
||||
|
||||
func parseAddr(m []byte) (addr Addr, family int, err error) {
|
||||
|
||||
15
vendor/github.com/vishvananda/netlink/bridge_linux.go
generated
vendored
15
vendor/github.com/vishvananda/netlink/bridge_linux.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
@@ -9,21 +10,27 @@ import (
|
||||
|
||||
// BridgeVlanList gets a map of device id to bridge vlan infos.
|
||||
// Equivalent to: `bridge vlan show`
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
|
||||
return pkgHandle.BridgeVlanList()
|
||||
}
|
||||
|
||||
// BridgeVlanList gets a map of device id to bridge vlan infos.
|
||||
// Equivalent to: `bridge vlan show`
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP)
|
||||
msg := nl.NewIfInfomsg(unix.AF_BRIDGE)
|
||||
req.AddData(msg)
|
||||
req.AddData(nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(uint32(nl.RTEXT_FILTER_BRVLAN))))
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
ret := make(map[int32][]*nl.BridgeVlanInfo)
|
||||
for _, m := range msgs {
|
||||
@@ -51,7 +58,7 @@ func (h *Handle) BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
return ret, executeErr
|
||||
}
|
||||
|
||||
// BridgeVlanAdd adds a new vlan filter entry
|
||||
|
||||
16
vendor/github.com/vishvananda/netlink/chain_linux.go
generated
vendored
16
vendor/github.com/vishvananda/netlink/chain_linux.go
generated
vendored
@@ -1,6 +1,8 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@@ -56,6 +58,9 @@ func (h *Handle) chainModify(cmd, flags int, link Link, chain Chain) error {
|
||||
// ChainList gets a list of chains in the system.
|
||||
// Equivalent to: `tc chain list`.
|
||||
// The list can be filtered by link.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func ChainList(link Link, parent uint32) ([]Chain, error) {
|
||||
return pkgHandle.ChainList(link, parent)
|
||||
}
|
||||
@@ -63,6 +68,9 @@ func ChainList(link Link, parent uint32) ([]Chain, error) {
|
||||
// ChainList gets a list of chains in the system.
|
||||
// Equivalent to: `tc chain list`.
|
||||
// The list can be filtered by link.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) ChainList(link Link, parent uint32) ([]Chain, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETCHAIN, unix.NLM_F_DUMP)
|
||||
index := int32(0)
|
||||
@@ -78,9 +86,9 @@ func (h *Handle) ChainList(link Link, parent uint32) ([]Chain, error) {
|
||||
}
|
||||
req.AddData(msg)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWCHAIN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWCHAIN)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
|
||||
var res []Chain
|
||||
@@ -108,5 +116,5 @@ func (h *Handle) ChainList(link Link, parent uint32) ([]Chain, error) {
|
||||
res = append(res, chain)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
return res, executeErr
|
||||
}
|
||||
|
||||
14
vendor/github.com/vishvananda/netlink/class_linux.go
generated
vendored
14
vendor/github.com/vishvananda/netlink/class_linux.go
generated
vendored
@@ -201,14 +201,20 @@ func classPayload(req *nl.NetlinkRequest, class Class) error {
|
||||
|
||||
// ClassList gets a list of classes in the system.
|
||||
// Equivalent to: `tc class show`.
|
||||
//
|
||||
// Generally returns nothing if link and parent are not specified.
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func ClassList(link Link, parent uint32) ([]Class, error) {
|
||||
return pkgHandle.ClassList(link, parent)
|
||||
}
|
||||
|
||||
// ClassList gets a list of classes in the system.
|
||||
// Equivalent to: `tc class show`.
|
||||
//
|
||||
// Generally returns nothing if link and parent are not specified.
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETTCLASS, unix.NLM_F_DUMP)
|
||||
msg := &nl.TcMsg{
|
||||
@@ -222,9 +228,9 @@ func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
|
||||
}
|
||||
req.AddData(msg)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTCLASS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTCLASS)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
|
||||
var res []Class
|
||||
@@ -295,7 +301,7 @@ func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
|
||||
res = append(res, class)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
return res, executeErr
|
||||
}
|
||||
|
||||
func parseHtbClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, error) {
|
||||
|
||||
32
vendor/github.com/vishvananda/netlink/conntrack_linux.go
generated
vendored
32
vendor/github.com/vishvananda/netlink/conntrack_linux.go
generated
vendored
@@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
@@ -44,6 +45,9 @@ type InetFamily uint8
|
||||
|
||||
// ConntrackTableList returns the flow list of a table of a specific family
|
||||
// conntrack -L [table] [options] List conntrack or expectation table
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func ConntrackTableList(table ConntrackTableType, family InetFamily) ([]*ConntrackFlow, error) {
|
||||
return pkgHandle.ConntrackTableList(table, family)
|
||||
}
|
||||
@@ -70,7 +74,7 @@ func ConntrackUpdate(table ConntrackTableType, family InetFamily, flow *Conntrac
|
||||
// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter
|
||||
// conntrack -D [table] parameters Delete conntrack or expectation
|
||||
//
|
||||
// Deprecated: use [ConntrackDeleteFilter] instead.
|
||||
// Deprecated: use [ConntrackDeleteFilters] instead.
|
||||
func ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter CustomConntrackFilter) (uint, error) {
|
||||
return pkgHandle.ConntrackDeleteFilters(table, family, filter)
|
||||
}
|
||||
@@ -83,10 +87,13 @@ func ConntrackDeleteFilters(table ConntrackTableType, family InetFamily, filters
|
||||
|
||||
// ConntrackTableList returns the flow list of a table of a specific family using the netlink handle passed
|
||||
// conntrack -L [table] [options] List conntrack or expectation table
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) ConntrackTableList(table ConntrackTableType, family InetFamily) ([]*ConntrackFlow, error) {
|
||||
res, err := h.dumpConntrackTable(table, family)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
res, executeErr := h.dumpConntrackTable(table, family)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
|
||||
// Deserialize all the flows
|
||||
@@ -95,7 +102,7 @@ func (h *Handle) ConntrackTableList(table ConntrackTableType, family InetFamily)
|
||||
result = append(result, parseRawData(dataRaw))
|
||||
}
|
||||
|
||||
return result, nil
|
||||
return result, executeErr
|
||||
}
|
||||
|
||||
// ConntrackTableFlush flushes all the flows of a specified table using the netlink handle passed
|
||||
@@ -158,6 +165,7 @@ func (h *Handle) ConntrackDeleteFilters(table ConntrackTableType, family InetFam
|
||||
}
|
||||
|
||||
var matched uint
|
||||
var errMsgs []string
|
||||
for _, dataRaw := range res {
|
||||
flow := parseRawData(dataRaw)
|
||||
for _, filter := range filters {
|
||||
@@ -165,14 +173,18 @@ func (h *Handle) ConntrackDeleteFilters(table ConntrackTableType, family InetFam
|
||||
req2 := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK)
|
||||
// skip the first 4 byte that are the netfilter header, the newConntrackRequest is adding it already
|
||||
req2.AddRawData(dataRaw[4:])
|
||||
req2.Execute(unix.NETLINK_NETFILTER, 0)
|
||||
matched++
|
||||
// flow is already deleted, no need to match on other filters and continue to the next flow.
|
||||
break
|
||||
if _, err = req2.Execute(unix.NETLINK_NETFILTER, 0); err == nil {
|
||||
matched++
|
||||
// flow is already deleted, no need to match on other filters and continue to the next flow.
|
||||
break
|
||||
}
|
||||
errMsgs = append(errMsgs, fmt.Sprintf("failed to delete conntrack flow '%s': %s", flow.String(), err.Error()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(errMsgs) > 0 {
|
||||
return matched, fmt.Errorf(strings.Join(errMsgs, "; "))
|
||||
}
|
||||
return matched, nil
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/vishvananda/netlink/conntrack_unspecified.go
generated
vendored
2
vendor/github.com/vishvananda/netlink/conntrack_unspecified.go
generated
vendored
@@ -33,7 +33,7 @@ func ConntrackTableFlush(table ConntrackTableType) error {
|
||||
// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter
|
||||
// conntrack -D [table] parameters Delete conntrack or expectation
|
||||
//
|
||||
// Deprecated: use [ConntrackDeleteFilter] instead.
|
||||
// Deprecated: use [ConntrackDeleteFilters] instead.
|
||||
func ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter *ConntrackFilter) (uint, error) {
|
||||
return 0, ErrNotImplemented
|
||||
}
|
||||
|
||||
40
vendor/github.com/vishvananda/netlink/devlink_linux.go
generated
vendored
40
vendor/github.com/vishvananda/netlink/devlink_linux.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
@@ -466,6 +467,8 @@ func (h *Handle) getEswitchAttrs(family *GenlFamily, dev *DevlinkDevice) {
|
||||
|
||||
// DevLinkGetDeviceList provides a pointer to devlink devices and nil error,
|
||||
// otherwise returns an error code.
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) DevLinkGetDeviceList() ([]*DevlinkDevice, error) {
|
||||
f, err := h.GenlFamilyGet(nl.GENL_DEVLINK_NAME)
|
||||
if err != nil {
|
||||
@@ -478,9 +481,9 @@ func (h *Handle) DevLinkGetDeviceList() ([]*DevlinkDevice, error) {
|
||||
req := h.newNetlinkRequest(int(f.ID),
|
||||
unix.NLM_F_REQUEST|unix.NLM_F_ACK|unix.NLM_F_DUMP)
|
||||
req.AddData(msg)
|
||||
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
devices, err := parseDevLinkDeviceList(msgs)
|
||||
if err != nil {
|
||||
@@ -489,11 +492,14 @@ func (h *Handle) DevLinkGetDeviceList() ([]*DevlinkDevice, error) {
|
||||
for _, d := range devices {
|
||||
h.getEswitchAttrs(f, d)
|
||||
}
|
||||
return devices, nil
|
||||
return devices, executeErr
|
||||
}
|
||||
|
||||
// DevLinkGetDeviceList provides a pointer to devlink devices and nil error,
|
||||
// otherwise returns an error code.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func DevLinkGetDeviceList() ([]*DevlinkDevice, error) {
|
||||
return pkgHandle.DevLinkGetDeviceList()
|
||||
}
|
||||
@@ -646,6 +652,8 @@ func parseDevLinkAllPortList(msgs [][]byte) ([]*DevlinkPort, error) {
|
||||
|
||||
// DevLinkGetPortList provides a pointer to devlink ports and nil error,
|
||||
// otherwise returns an error code.
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) DevLinkGetAllPortList() ([]*DevlinkPort, error) {
|
||||
f, err := h.GenlFamilyGet(nl.GENL_DEVLINK_NAME)
|
||||
if err != nil {
|
||||
@@ -658,19 +666,21 @@ func (h *Handle) DevLinkGetAllPortList() ([]*DevlinkPort, error) {
|
||||
req := h.newNetlinkRequest(int(f.ID),
|
||||
unix.NLM_F_REQUEST|unix.NLM_F_ACK|unix.NLM_F_DUMP)
|
||||
req.AddData(msg)
|
||||
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
ports, err := parseDevLinkAllPortList(msgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ports, nil
|
||||
return ports, executeErr
|
||||
}
|
||||
|
||||
// DevLinkGetPortList provides a pointer to devlink ports and nil error,
|
||||
// otherwise returns an error code.
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func DevLinkGetAllPortList() ([]*DevlinkPort, error) {
|
||||
return pkgHandle.DevLinkGetAllPortList()
|
||||
}
|
||||
@@ -738,15 +748,18 @@ func (h *Handle) DevlinkGetDeviceResources(bus string, device string) (*DevlinkR
|
||||
|
||||
// DevlinkGetDeviceParams returns parameters for devlink device
|
||||
// Equivalent to: `devlink dev param show <bus>/<device>`
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) DevlinkGetDeviceParams(bus string, device string) ([]*DevlinkParam, error) {
|
||||
_, req, err := h.createCmdReq(nl.DEVLINK_CMD_PARAM_GET, bus, device)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Flags |= unix.NLM_F_DUMP
|
||||
respmsg, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
respmsg, executeErr := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
var params []*DevlinkParam
|
||||
for _, m := range respmsg {
|
||||
@@ -761,11 +774,14 @@ func (h *Handle) DevlinkGetDeviceParams(bus string, device string) ([]*DevlinkPa
|
||||
params = append(params, p)
|
||||
}
|
||||
|
||||
return params, nil
|
||||
return params, executeErr
|
||||
}
|
||||
|
||||
// DevlinkGetDeviceParams returns parameters for devlink device
|
||||
// Equivalent to: `devlink dev param show <bus>/<device>`
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func DevlinkGetDeviceParams(bus string, device string) ([]*DevlinkParam, error) {
|
||||
return pkgHandle.DevlinkGetDeviceParams(bus, device)
|
||||
}
|
||||
|
||||
22
vendor/github.com/vishvananda/netlink/filter_linux.go
generated
vendored
22
vendor/github.com/vishvananda/netlink/filter_linux.go
generated
vendored
@@ -405,14 +405,20 @@ func (h *Handle) filterModify(filter Filter, proto, flags int) error {
|
||||
|
||||
// FilterList gets a list of filters in the system.
|
||||
// Equivalent to: `tc filter show`.
|
||||
//
|
||||
// Generally returns nothing if link and parent are not specified.
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func FilterList(link Link, parent uint32) ([]Filter, error) {
|
||||
return pkgHandle.FilterList(link, parent)
|
||||
}
|
||||
|
||||
// FilterList gets a list of filters in the system.
|
||||
// Equivalent to: `tc filter show`.
|
||||
//
|
||||
// Generally returns nothing if link and parent are not specified.
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETTFILTER, unix.NLM_F_DUMP)
|
||||
msg := &nl.TcMsg{
|
||||
@@ -426,9 +432,9 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
|
||||
}
|
||||
req.AddData(msg)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTFILTER)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTFILTER)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
|
||||
var res []Filter
|
||||
@@ -516,7 +522,7 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
return res, executeErr
|
||||
}
|
||||
|
||||
func toTcGen(attrs *ActionAttrs, tcgen *nl.TcGen) {
|
||||
@@ -920,9 +926,11 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
|
||||
actionnStatistic = (*ActionStatistic)(s)
|
||||
}
|
||||
}
|
||||
action.Attrs().Statistics = actionnStatistic
|
||||
action.Attrs().Timestamp = actionTimestamp
|
||||
actions = append(actions, action)
|
||||
if action != nil {
|
||||
action.Attrs().Statistics = actionnStatistic
|
||||
action.Attrs().Timestamp = actionTimestamp
|
||||
actions = append(actions, action)
|
||||
}
|
||||
}
|
||||
return actions, nil
|
||||
}
|
||||
|
||||
15
vendor/github.com/vishvananda/netlink/fou.go
generated
vendored
15
vendor/github.com/vishvananda/netlink/fou.go
generated
vendored
@@ -1,16 +1,7 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrAttrHeaderTruncated is returned when a netlink attribute's header is
|
||||
// truncated.
|
||||
ErrAttrHeaderTruncated = errors.New("attribute header truncated")
|
||||
// ErrAttrBodyTruncated is returned when a netlink attribute's body is
|
||||
// truncated.
|
||||
ErrAttrBodyTruncated = errors.New("attribute body truncated")
|
||||
"net"
|
||||
)
|
||||
|
||||
type Fou struct {
|
||||
@@ -18,4 +9,8 @@ type Fou struct {
|
||||
Port int
|
||||
Protocol int
|
||||
EncapType int
|
||||
Local net.IP
|
||||
Peer net.IP
|
||||
PeerPort int
|
||||
IfIndex int
|
||||
}
|
||||
|
||||
66
vendor/github.com/vishvananda/netlink/fou_linux.go
generated
vendored
66
vendor/github.com/vishvananda/netlink/fou_linux.go
generated
vendored
@@ -1,3 +1,4 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package netlink
|
||||
@@ -5,6 +6,8 @@ package netlink
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"log"
|
||||
"net"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"golang.org/x/sys/unix"
|
||||
@@ -29,6 +32,12 @@ const (
|
||||
FOU_ATTR_IPPROTO
|
||||
FOU_ATTR_TYPE
|
||||
FOU_ATTR_REMCSUM_NOPARTIAL
|
||||
FOU_ATTR_LOCAL_V4
|
||||
FOU_ATTR_LOCAL_V6
|
||||
FOU_ATTR_PEER_V4
|
||||
FOU_ATTR_PEER_V6
|
||||
FOU_ATTR_PEER_PORT
|
||||
FOU_ATTR_IFINDEX
|
||||
FOU_ATTR_MAX = FOU_ATTR_REMCSUM_NOPARTIAL
|
||||
)
|
||||
|
||||
@@ -128,10 +137,14 @@ func (h *Handle) FouDel(f Fou) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func FouList(fam int) ([]Fou, error) {
|
||||
return pkgHandle.FouList(fam)
|
||||
}
|
||||
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) FouList(fam int) ([]Fou, error) {
|
||||
fam_id, err := FouFamilyId()
|
||||
if err != nil {
|
||||
@@ -150,9 +163,9 @@ func (h *Handle) FouList(fam int) ([]Fou, error) {
|
||||
|
||||
req.AddRawData(raw)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if executeErr != nil && !errors.Is(err, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
|
||||
fous := make([]Fou, 0, len(msgs))
|
||||
@@ -165,45 +178,32 @@ func (h *Handle) FouList(fam int) ([]Fou, error) {
|
||||
fous = append(fous, f)
|
||||
}
|
||||
|
||||
return fous, nil
|
||||
return fous, executeErr
|
||||
}
|
||||
|
||||
func deserializeFouMsg(msg []byte) (Fou, error) {
|
||||
// we'll skip to byte 4 to first attribute
|
||||
msg = msg[3:]
|
||||
var shift int
|
||||
fou := Fou{}
|
||||
|
||||
for {
|
||||
// attribute header is at least 16 bits
|
||||
if len(msg) < 4 {
|
||||
return fou, ErrAttrHeaderTruncated
|
||||
}
|
||||
|
||||
lgt := int(binary.BigEndian.Uint16(msg[0:2]))
|
||||
if len(msg) < lgt+4 {
|
||||
return fou, ErrAttrBodyTruncated
|
||||
}
|
||||
attr := binary.BigEndian.Uint16(msg[2:4])
|
||||
|
||||
shift = lgt + 3
|
||||
switch attr {
|
||||
for attr := range nl.ParseAttributes(msg[4:]) {
|
||||
switch attr.Type {
|
||||
case FOU_ATTR_AF:
|
||||
fou.Family = int(msg[5])
|
||||
fou.Family = int(attr.Value[0])
|
||||
case FOU_ATTR_PORT:
|
||||
fou.Port = int(binary.BigEndian.Uint16(msg[5:7]))
|
||||
// port is 2 bytes
|
||||
shift = lgt + 2
|
||||
fou.Port = int(networkOrder.Uint16(attr.Value))
|
||||
case FOU_ATTR_IPPROTO:
|
||||
fou.Protocol = int(msg[5])
|
||||
fou.Protocol = int(attr.Value[0])
|
||||
case FOU_ATTR_TYPE:
|
||||
fou.EncapType = int(msg[5])
|
||||
}
|
||||
|
||||
msg = msg[shift:]
|
||||
|
||||
if len(msg) < 4 {
|
||||
break
|
||||
fou.EncapType = int(attr.Value[0])
|
||||
case FOU_ATTR_LOCAL_V4, FOU_ATTR_LOCAL_V6:
|
||||
fou.Local = net.IP(attr.Value)
|
||||
case FOU_ATTR_PEER_V4, FOU_ATTR_PEER_V6:
|
||||
fou.Peer = net.IP(attr.Value)
|
||||
case FOU_ATTR_PEER_PORT:
|
||||
fou.PeerPort = int(networkOrder.Uint16(attr.Value))
|
||||
case FOU_ATTR_IFINDEX:
|
||||
fou.IfIndex = int(native.Uint16(attr.Value))
|
||||
default:
|
||||
log.Printf("unknown fou attribute from kernel: %+v %v", attr, attr.Type&nl.NLA_TYPE_MASK)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1
vendor/github.com/vishvananda/netlink/fou_unspecified.go
generated
vendored
1
vendor/github.com/vishvananda/netlink/fou_unspecified.go
generated
vendored
@@ -1,3 +1,4 @@
|
||||
//go:build !linux
|
||||
// +build !linux
|
||||
|
||||
package netlink
|
||||
|
||||
13
vendor/github.com/vishvananda/netlink/genetlink_linux.go
generated
vendored
13
vendor/github.com/vishvananda/netlink/genetlink_linux.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"syscall"
|
||||
|
||||
@@ -126,6 +127,8 @@ func parseFamilies(msgs [][]byte) ([]*GenlFamily, error) {
|
||||
return families, nil
|
||||
}
|
||||
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) GenlFamilyList() ([]*GenlFamily, error) {
|
||||
msg := &nl.Genlmsg{
|
||||
Command: nl.GENL_CTRL_CMD_GETFAMILY,
|
||||
@@ -133,13 +136,19 @@ func (h *Handle) GenlFamilyList() ([]*GenlFamily, error) {
|
||||
}
|
||||
req := h.newNetlinkRequest(nl.GENL_ID_CTRL, unix.NLM_F_DUMP)
|
||||
req.AddData(msg)
|
||||
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
families, err := parseFamilies(msgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parseFamilies(msgs)
|
||||
return families, executeErr
|
||||
}
|
||||
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func GenlFamilyList() ([]*GenlFamily, error) {
|
||||
return pkgHandle.GenlFamilyList()
|
||||
}
|
||||
|
||||
13
vendor/github.com/vishvananda/netlink/gtp_linux.go
generated
vendored
13
vendor/github.com/vishvananda/netlink/gtp_linux.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
@@ -74,6 +75,8 @@ func parsePDP(msgs [][]byte) ([]*PDP, error) {
|
||||
return pdps, nil
|
||||
}
|
||||
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) GTPPDPList() ([]*PDP, error) {
|
||||
f, err := h.GenlFamilyGet(nl.GENL_GTP_NAME)
|
||||
if err != nil {
|
||||
@@ -85,13 +88,19 @@ func (h *Handle) GTPPDPList() ([]*PDP, error) {
|
||||
}
|
||||
req := h.newNetlinkRequest(int(f.ID), unix.NLM_F_DUMP)
|
||||
req.AddData(msg)
|
||||
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if executeErr != nil && !errors.Is(err, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
pdps, err := parsePDP(msgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parsePDP(msgs)
|
||||
return pdps, executeErr
|
||||
}
|
||||
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func GTPPDPList() ([]*PDP, error) {
|
||||
return pkgHandle.GTPPDPList()
|
||||
}
|
||||
|
||||
53
vendor/github.com/vishvananda/netlink/link_linux.go
generated
vendored
53
vendor/github.com/vishvananda/netlink/link_linux.go
generated
vendored
@@ -3,6 +3,7 @@ package netlink
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
@@ -1807,20 +1808,20 @@ func (h *Handle) LinkDel(link Link) error {
|
||||
}
|
||||
|
||||
func (h *Handle) linkByNameDump(name string) (Link, error) {
|
||||
links, err := h.LinkList()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
links, executeErr := h.LinkList()
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
|
||||
for _, link := range links {
|
||||
if link.Attrs().Name == name {
|
||||
return link, nil
|
||||
return link, executeErr
|
||||
}
|
||||
|
||||
// support finding interfaces also via altnames
|
||||
for _, altName := range link.Attrs().AltNames {
|
||||
if altName == name {
|
||||
return link, nil
|
||||
return link, executeErr
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1828,25 +1829,33 @@ func (h *Handle) linkByNameDump(name string) (Link, error) {
|
||||
}
|
||||
|
||||
func (h *Handle) linkByAliasDump(alias string) (Link, error) {
|
||||
links, err := h.LinkList()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
links, executeErr := h.LinkList()
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
|
||||
for _, link := range links {
|
||||
if link.Attrs().Alias == alias {
|
||||
return link, nil
|
||||
return link, executeErr
|
||||
}
|
||||
}
|
||||
return nil, LinkNotFoundError{fmt.Errorf("Link alias %s not found", alias)}
|
||||
}
|
||||
|
||||
// LinkByName finds a link by name and returns a pointer to the object.
|
||||
//
|
||||
// If the kernel doesn't support IFLA_IFNAME, this method will fall back to
|
||||
// filtering a dump of all link names. In this case, if the returned error is
|
||||
// [ErrDumpInterrupted] the result may be missing or outdated.
|
||||
func LinkByName(name string) (Link, error) {
|
||||
return pkgHandle.LinkByName(name)
|
||||
}
|
||||
|
||||
// LinkByName finds a link by name and returns a pointer to the object.
|
||||
//
|
||||
// If the kernel doesn't support IFLA_IFNAME, this method will fall back to
|
||||
// filtering a dump of all link names. In this case, if the returned error is
|
||||
// [ErrDumpInterrupted] the result may be missing or outdated.
|
||||
func (h *Handle) LinkByName(name string) (Link, error) {
|
||||
if h.lookupByDump {
|
||||
return h.linkByNameDump(name)
|
||||
@@ -1879,12 +1888,20 @@ func (h *Handle) LinkByName(name string) (Link, error) {
|
||||
|
||||
// LinkByAlias finds a link by its alias and returns a pointer to the object.
|
||||
// If there are multiple links with the alias it returns the first one
|
||||
//
|
||||
// If the kernel doesn't support IFLA_IFALIAS, this method will fall back to
|
||||
// filtering a dump of all link names. In this case, if the returned error is
|
||||
// [ErrDumpInterrupted] the result may be missing or outdated.
|
||||
func LinkByAlias(alias string) (Link, error) {
|
||||
return pkgHandle.LinkByAlias(alias)
|
||||
}
|
||||
|
||||
// LinkByAlias finds a link by its alias and returns a pointer to the object.
|
||||
// If there are multiple links with the alias it returns the first one
|
||||
//
|
||||
// If the kernel doesn't support IFLA_IFALIAS, this method will fall back to
|
||||
// filtering a dump of all link names. In this case, if the returned error is
|
||||
// [ErrDumpInterrupted] the result may be missing or outdated.
|
||||
func (h *Handle) LinkByAlias(alias string) (Link, error) {
|
||||
if h.lookupByDump {
|
||||
return h.linkByAliasDump(alias)
|
||||
@@ -2321,6 +2338,9 @@ func LinkList() ([]Link, error) {
|
||||
|
||||
// LinkList gets a list of link devices.
|
||||
// Equivalent to: `ip link show`
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) LinkList() ([]Link, error) {
|
||||
// NOTE(vish): This duplicates functionality in net/iface_linux.go, but we need
|
||||
// to get the message ourselves to parse link type.
|
||||
@@ -2331,9 +2351,9 @@ func (h *Handle) LinkList() ([]Link, error) {
|
||||
attr := nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(nl.RTEXT_FILTER_VF))
|
||||
req.AddData(attr)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
|
||||
var res []Link
|
||||
@@ -2345,7 +2365,7 @@ func (h *Handle) LinkList() ([]Link, error) {
|
||||
res = append(res, link)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
return res, executeErr
|
||||
}
|
||||
|
||||
// LinkUpdate is used to pass information back from LinkSubscribe()
|
||||
@@ -2381,6 +2401,10 @@ type LinkSubscribeOptions struct {
|
||||
// LinkSubscribeWithOptions work like LinkSubscribe but enable to
|
||||
// provide additional options to modify the behavior. Currently, the
|
||||
// namespace can be provided as well as an error callback.
|
||||
//
|
||||
// When options.ListExisting is true, options.ErrorCallback may be
|
||||
// called with [ErrDumpInterrupted] to indicate that results from
|
||||
// the initial dump of links may be inconsistent or incomplete.
|
||||
func LinkSubscribeWithOptions(ch chan<- LinkUpdate, done <-chan struct{}, options LinkSubscribeOptions) error {
|
||||
if options.Namespace == nil {
|
||||
none := netns.None()
|
||||
@@ -2440,6 +2464,9 @@ func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-c
|
||||
continue
|
||||
}
|
||||
for _, m := range msgs {
|
||||
if m.Header.Flags&unix.NLM_F_DUMP_INTR != 0 && cberr != nil {
|
||||
cberr(ErrDumpInterrupted)
|
||||
}
|
||||
if m.Header.Type == unix.NLMSG_DONE {
|
||||
continue
|
||||
}
|
||||
|
||||
34
vendor/github.com/vishvananda/netlink/neigh_linux.go
generated
vendored
34
vendor/github.com/vishvananda/netlink/neigh_linux.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"syscall"
|
||||
@@ -206,6 +207,9 @@ func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
|
||||
// NeighList returns a list of IP-MAC mappings in the system (ARP table).
|
||||
// Equivalent to: `ip neighbor show`.
|
||||
// The list can be filtered by link and ip family.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func NeighList(linkIndex, family int) ([]Neigh, error) {
|
||||
return pkgHandle.NeighList(linkIndex, family)
|
||||
}
|
||||
@@ -213,6 +217,9 @@ func NeighList(linkIndex, family int) ([]Neigh, error) {
|
||||
// NeighProxyList returns a list of neighbor proxies in the system.
|
||||
// Equivalent to: `ip neighbor show proxy`.
|
||||
// The list can be filtered by link and ip family.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func NeighProxyList(linkIndex, family int) ([]Neigh, error) {
|
||||
return pkgHandle.NeighProxyList(linkIndex, family)
|
||||
}
|
||||
@@ -220,6 +227,9 @@ func NeighProxyList(linkIndex, family int) ([]Neigh, error) {
|
||||
// NeighList returns a list of IP-MAC mappings in the system (ARP table).
|
||||
// Equivalent to: `ip neighbor show`.
|
||||
// The list can be filtered by link and ip family.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) NeighList(linkIndex, family int) ([]Neigh, error) {
|
||||
return h.NeighListExecute(Ndmsg{
|
||||
Family: uint8(family),
|
||||
@@ -230,6 +240,9 @@ func (h *Handle) NeighList(linkIndex, family int) ([]Neigh, error) {
|
||||
// NeighProxyList returns a list of neighbor proxies in the system.
|
||||
// Equivalent to: `ip neighbor show proxy`.
|
||||
// The list can be filtered by link, ip family.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) {
|
||||
return h.NeighListExecute(Ndmsg{
|
||||
Family: uint8(family),
|
||||
@@ -239,18 +252,24 @@ func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) {
|
||||
}
|
||||
|
||||
// NeighListExecute returns a list of neighbour entries filtered by link, ip family, flag and state.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func NeighListExecute(msg Ndmsg) ([]Neigh, error) {
|
||||
return pkgHandle.NeighListExecute(msg)
|
||||
}
|
||||
|
||||
// NeighListExecute returns a list of neighbour entries filtered by link, ip family, flag and state.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) NeighListExecute(msg Ndmsg) ([]Neigh, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETNEIGH, unix.NLM_F_DUMP)
|
||||
req.AddData(&msg)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWNEIGH)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWNEIGH)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
|
||||
var res []Neigh
|
||||
@@ -281,7 +300,7 @@ func (h *Handle) NeighListExecute(msg Ndmsg) ([]Neigh, error) {
|
||||
res = append(res, *neigh)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
return res, executeErr
|
||||
}
|
||||
|
||||
func NeighDeserialize(m []byte) (*Neigh, error) {
|
||||
@@ -364,6 +383,10 @@ type NeighSubscribeOptions struct {
|
||||
// NeighSubscribeWithOptions work like NeighSubscribe but enable to
|
||||
// provide additional options to modify the behavior. Currently, the
|
||||
// namespace can be provided as well as an error callback.
|
||||
//
|
||||
// When options.ListExisting is true, options.ErrorCallback may be
|
||||
// called with [ErrDumpInterrupted] to indicate that results from
|
||||
// the initial dump of links may be inconsistent or incomplete.
|
||||
func NeighSubscribeWithOptions(ch chan<- NeighUpdate, done <-chan struct{}, options NeighSubscribeOptions) error {
|
||||
if options.Namespace == nil {
|
||||
none := netns.None()
|
||||
@@ -428,6 +451,9 @@ func neighSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- NeighUpdate, done <
|
||||
continue
|
||||
}
|
||||
for _, m := range msgs {
|
||||
if m.Header.Flags&unix.NLM_F_DUMP_INTR != 0 && cberr != nil {
|
||||
cberr(ErrDumpInterrupted)
|
||||
}
|
||||
if m.Header.Type == unix.NLMSG_DONE {
|
||||
if listExisting {
|
||||
// This will be called after handling AF_UNSPEC
|
||||
|
||||
3
vendor/github.com/vishvananda/netlink/netlink_linux.go
generated
vendored
3
vendor/github.com/vishvananda/netlink/netlink_linux.go
generated
vendored
@@ -9,3 +9,6 @@ const (
|
||||
FAMILY_V6 = nl.FAMILY_V6
|
||||
FAMILY_MPLS = nl.FAMILY_MPLS
|
||||
)
|
||||
|
||||
// ErrDumpInterrupted is an alias for [nl.ErrDumpInterrupted].
|
||||
var ErrDumpInterrupted = nl.ErrDumpInterrupted
|
||||
|
||||
108
vendor/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
108
vendor/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
@@ -4,6 +4,7 @@ package nl
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/vishvananda/netns"
|
||||
@@ -43,6 +45,26 @@ var SocketTimeoutTv = unix.Timeval{Sec: 60, Usec: 0}
|
||||
// ErrorMessageReporting is the default error message reporting configuration for the new netlink sockets
|
||||
var EnableErrorMessageReporting bool = false
|
||||
|
||||
// ErrDumpInterrupted is an instance of errDumpInterrupted, used to report that
|
||||
// a netlink function has set the NLM_F_DUMP_INTR flag in a response message,
|
||||
// indicating that the results may be incomplete or inconsistent.
|
||||
var ErrDumpInterrupted = errDumpInterrupted{}
|
||||
|
||||
// errDumpInterrupted is an error type, used to report that NLM_F_DUMP_INTR was
|
||||
// set in a netlink response.
|
||||
type errDumpInterrupted struct{}
|
||||
|
||||
func (errDumpInterrupted) Error() string {
|
||||
return "results may be incomplete or inconsistent"
|
||||
}
|
||||
|
||||
// Before errDumpInterrupted was introduced, EINTR was returned when a netlink
|
||||
// response had NLM_F_DUMP_INTR. Retain backward compatibility with code that
|
||||
// may be checking for EINTR using Is.
|
||||
func (e errDumpInterrupted) Is(target error) bool {
|
||||
return target == unix.EINTR
|
||||
}
|
||||
|
||||
// GetIPFamily returns the family type of a net.IP.
|
||||
func GetIPFamily(ip net.IP) int {
|
||||
if len(ip) <= net.IPv4len {
|
||||
@@ -492,22 +514,26 @@ func (req *NetlinkRequest) AddRawData(data []byte) {
|
||||
// Execute the request against the given sockType.
|
||||
// Returns a list of netlink messages in serialized format, optionally filtered
|
||||
// by resType.
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, error) {
|
||||
var res [][]byte
|
||||
err := req.ExecuteIter(sockType, resType, func(msg []byte) bool {
|
||||
res = append(res, msg)
|
||||
return true
|
||||
})
|
||||
if err != nil {
|
||||
if err != nil && !errors.Is(err, ErrDumpInterrupted) {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
return res, err
|
||||
}
|
||||
|
||||
// ExecuteIter executes the request against the given sockType.
|
||||
// Calls the provided callback func once for each netlink message.
|
||||
// If the callback returns false, it is not called again, but
|
||||
// the remaining messages are consumed/discarded.
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
//
|
||||
// Thread safety: ExecuteIter holds a lock on the socket until
|
||||
// it finishes iteration so the callback must not call back into
|
||||
@@ -559,6 +585,8 @@ func (req *NetlinkRequest) ExecuteIter(sockType int, resType uint16, f func(msg
|
||||
return err
|
||||
}
|
||||
|
||||
dumpIntr := false
|
||||
|
||||
done:
|
||||
for {
|
||||
msgs, from, err := s.Receive()
|
||||
@@ -580,7 +608,7 @@ done:
|
||||
}
|
||||
|
||||
if m.Header.Flags&unix.NLM_F_DUMP_INTR != 0 {
|
||||
return syscall.Errno(unix.EINTR)
|
||||
dumpIntr = true
|
||||
}
|
||||
|
||||
if m.Header.Type == unix.NLMSG_DONE || m.Header.Type == unix.NLMSG_ERROR {
|
||||
@@ -634,6 +662,9 @@ done:
|
||||
}
|
||||
}
|
||||
}
|
||||
if dumpIntr {
|
||||
return ErrDumpInterrupted
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -656,9 +687,11 @@ func NewNetlinkRequest(proto, flags int) *NetlinkRequest {
|
||||
}
|
||||
|
||||
type NetlinkSocket struct {
|
||||
fd int32
|
||||
file *os.File
|
||||
lsa unix.SockaddrNetlink
|
||||
fd int32
|
||||
file *os.File
|
||||
lsa unix.SockaddrNetlink
|
||||
sendTimeout int64 // Access using atomic.Load/StoreInt64
|
||||
receiveTimeout int64 // Access using atomic.Load/StoreInt64
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
@@ -802,8 +835,44 @@ func (s *NetlinkSocket) GetFd() int {
|
||||
return int(s.fd)
|
||||
}
|
||||
|
||||
func (s *NetlinkSocket) GetTimeouts() (send, receive time.Duration) {
|
||||
return time.Duration(atomic.LoadInt64(&s.sendTimeout)),
|
||||
time.Duration(atomic.LoadInt64(&s.receiveTimeout))
|
||||
}
|
||||
|
||||
func (s *NetlinkSocket) Send(request *NetlinkRequest) error {
|
||||
return unix.Sendto(int(s.fd), request.Serialize(), 0, &s.lsa)
|
||||
rawConn, err := s.file.SyscallConn()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var (
|
||||
deadline time.Time
|
||||
innerErr error
|
||||
)
|
||||
sendTimeout := atomic.LoadInt64(&s.sendTimeout)
|
||||
if sendTimeout != 0 {
|
||||
deadline = time.Now().Add(time.Duration(sendTimeout))
|
||||
}
|
||||
if err := s.file.SetWriteDeadline(deadline); err != nil {
|
||||
return err
|
||||
}
|
||||
serializedReq := request.Serialize()
|
||||
err = rawConn.Write(func(fd uintptr) (done bool) {
|
||||
innerErr = unix.Sendto(int(s.fd), serializedReq, 0, &s.lsa)
|
||||
return innerErr != unix.EWOULDBLOCK
|
||||
})
|
||||
if innerErr != nil {
|
||||
return innerErr
|
||||
}
|
||||
if err != nil {
|
||||
// The timeout was previously implemented using SO_SNDTIMEO on a blocking
|
||||
// socket. So, continue to return EAGAIN when the timeout is reached.
|
||||
if errors.Is(err, os.ErrDeadlineExceeded) {
|
||||
return unix.EAGAIN
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, *unix.SockaddrNetlink, error) {
|
||||
@@ -812,20 +881,33 @@ func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, *unix.SockaddrNetli
|
||||
return nil, nil, err
|
||||
}
|
||||
var (
|
||||
deadline time.Time
|
||||
fromAddr *unix.SockaddrNetlink
|
||||
rb [RECEIVE_BUFFER_SIZE]byte
|
||||
nr int
|
||||
from unix.Sockaddr
|
||||
innerErr error
|
||||
)
|
||||
receiveTimeout := atomic.LoadInt64(&s.receiveTimeout)
|
||||
if receiveTimeout != 0 {
|
||||
deadline = time.Now().Add(time.Duration(receiveTimeout))
|
||||
}
|
||||
if err := s.file.SetReadDeadline(deadline); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
err = rawConn.Read(func(fd uintptr) (done bool) {
|
||||
nr, from, innerErr = unix.Recvfrom(int(fd), rb[:], 0)
|
||||
return innerErr != unix.EWOULDBLOCK
|
||||
})
|
||||
if innerErr != nil {
|
||||
err = innerErr
|
||||
return nil, nil, innerErr
|
||||
}
|
||||
if err != nil {
|
||||
// The timeout was previously implemented using SO_RCVTIMEO on a blocking
|
||||
// socket. So, continue to return EAGAIN when the timeout is reached.
|
||||
if errors.Is(err, os.ErrDeadlineExceeded) {
|
||||
return nil, nil, unix.EAGAIN
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
fromAddr, ok := from.(*unix.SockaddrNetlink)
|
||||
@@ -847,16 +929,14 @@ func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, *unix.SockaddrNetli
|
||||
|
||||
// SetSendTimeout allows to set a send timeout on the socket
|
||||
func (s *NetlinkSocket) SetSendTimeout(timeout *unix.Timeval) error {
|
||||
// Set a send timeout of SOCKET_SEND_TIMEOUT, this will allow the Send to periodically unblock and avoid that a routine
|
||||
// remains stuck on a send on a closed fd
|
||||
return unix.SetsockoptTimeval(int(s.fd), unix.SOL_SOCKET, unix.SO_SNDTIMEO, timeout)
|
||||
atomic.StoreInt64(&s.sendTimeout, timeout.Nano())
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetReceiveTimeout allows to set a receive timeout on the socket
|
||||
func (s *NetlinkSocket) SetReceiveTimeout(timeout *unix.Timeval) error {
|
||||
// Set a read timeout of SOCKET_READ_TIMEOUT, this will allow the Read to periodically unblock and avoid that a routine
|
||||
// remains stuck on a recvmsg on a closed fd
|
||||
return unix.SetsockoptTimeval(int(s.fd), unix.SOL_SOCKET, unix.SO_RCVTIMEO, timeout)
|
||||
atomic.StoreInt64(&s.receiveTimeout, timeout.Nano())
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetReceiveBufferSize allows to set a receive buffer size on the socket
|
||||
|
||||
13
vendor/github.com/vishvananda/netlink/protinfo_linux.go
generated
vendored
13
vendor/github.com/vishvananda/netlink/protinfo_linux.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"syscall"
|
||||
|
||||
@@ -8,10 +9,14 @@ import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func LinkGetProtinfo(link Link) (Protinfo, error) {
|
||||
return pkgHandle.LinkGetProtinfo(link)
|
||||
}
|
||||
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
||||
base := link.Attrs()
|
||||
h.ensureIndex(base)
|
||||
@@ -19,9 +24,9 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP)
|
||||
msg := nl.NewIfInfomsg(unix.AF_BRIDGE)
|
||||
req.AddData(msg)
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
||||
if err != nil {
|
||||
return pi, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, 0)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return pi, executeErr
|
||||
}
|
||||
|
||||
for _, m := range msgs {
|
||||
@@ -43,7 +48,7 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
||||
}
|
||||
pi = parseProtinfo(infos)
|
||||
|
||||
return pi, nil
|
||||
return pi, executeErr
|
||||
}
|
||||
}
|
||||
return pi, fmt.Errorf("Device with index %d not found", base.Index)
|
||||
|
||||
15
vendor/github.com/vishvananda/netlink/qdisc_linux.go
generated
vendored
15
vendor/github.com/vishvananda/netlink/qdisc_linux.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
@@ -338,6 +339,9 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
|
||||
// QdiscList gets a list of qdiscs in the system.
|
||||
// Equivalent to: `tc qdisc show`.
|
||||
// The list can be filtered by link.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func QdiscList(link Link) ([]Qdisc, error) {
|
||||
return pkgHandle.QdiscList(link)
|
||||
}
|
||||
@@ -345,6 +349,9 @@ func QdiscList(link Link) ([]Qdisc, error) {
|
||||
// QdiscList gets a list of qdiscs in the system.
|
||||
// Equivalent to: `tc qdisc show`.
|
||||
// The list can be filtered by link.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETQDISC, unix.NLM_F_DUMP)
|
||||
index := int32(0)
|
||||
@@ -359,9 +366,9 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
||||
}
|
||||
req.AddData(msg)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWQDISC)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWQDISC)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
|
||||
var res []Qdisc
|
||||
@@ -497,7 +504,7 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
||||
res = append(res, qdisc)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
return res, executeErr
|
||||
}
|
||||
|
||||
func parsePfifoFastData(qdisc Qdisc, value []byte) error {
|
||||
|
||||
24
vendor/github.com/vishvananda/netlink/rdma_link_linux.go
generated
vendored
24
vendor/github.com/vishvananda/netlink/rdma_link_linux.go
generated
vendored
@@ -3,6 +3,7 @@ package netlink
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
@@ -85,19 +86,25 @@ func execRdmaSetLink(req *nl.NetlinkRequest) error {
|
||||
|
||||
// RdmaLinkList gets a list of RDMA link devices.
|
||||
// Equivalent to: `rdma dev show`
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func RdmaLinkList() ([]*RdmaLink, error) {
|
||||
return pkgHandle.RdmaLinkList()
|
||||
}
|
||||
|
||||
// RdmaLinkList gets a list of RDMA link devices.
|
||||
// Equivalent to: `rdma dev show`
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) RdmaLinkList() ([]*RdmaLink, error) {
|
||||
proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_GET)
|
||||
req := h.newNetlinkRequest(proto, unix.NLM_F_ACK|unix.NLM_F_DUMP)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_RDMA, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_RDMA, 0)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
|
||||
var res []*RdmaLink
|
||||
@@ -109,17 +116,23 @@ func (h *Handle) RdmaLinkList() ([]*RdmaLink, error) {
|
||||
res = append(res, link)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
return res, executeErr
|
||||
}
|
||||
|
||||
// RdmaLinkByName finds a link by name and returns a pointer to the object if
|
||||
// found and nil error, otherwise returns error code.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], the result may be missing or
|
||||
// outdated and the caller should retry.
|
||||
func RdmaLinkByName(name string) (*RdmaLink, error) {
|
||||
return pkgHandle.RdmaLinkByName(name)
|
||||
}
|
||||
|
||||
// RdmaLinkByName finds a link by name and returns a pointer to the object if
|
||||
// found and nil error, otherwise returns error code.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], the result may be missing or
|
||||
// outdated and the caller should retry.
|
||||
func (h *Handle) RdmaLinkByName(name string) (*RdmaLink, error) {
|
||||
links, err := h.RdmaLinkList()
|
||||
if err != nil {
|
||||
@@ -288,6 +301,8 @@ func RdmaLinkDel(name string) error {
|
||||
}
|
||||
|
||||
// RdmaLinkDel deletes an rdma link.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], the caller should retry.
|
||||
func (h *Handle) RdmaLinkDel(name string) error {
|
||||
link, err := h.RdmaLinkByName(name)
|
||||
if err != nil {
|
||||
@@ -307,6 +322,7 @@ func (h *Handle) RdmaLinkDel(name string) error {
|
||||
|
||||
// RdmaLinkAdd adds an rdma link for the specified type to the network device.
|
||||
// Similar to: rdma link add NAME type TYPE netdev NETDEV
|
||||
//
|
||||
// NAME - specifies the new name of the rdma link to add
|
||||
// TYPE - specifies which rdma type to use. Link types:
|
||||
// rxe - Soft RoCE driver
|
||||
|
||||
30
vendor/github.com/vishvananda/netlink/route_linux.go
generated
vendored
30
vendor/github.com/vishvananda/netlink/route_linux.go
generated
vendored
@@ -3,6 +3,7 @@ package netlink
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
@@ -1163,6 +1164,9 @@ func (h *Handle) prepareRouteReq(route *Route, req *nl.NetlinkRequest, msg *nl.R
|
||||
// RouteList gets a list of routes in the system.
|
||||
// Equivalent to: `ip route show`.
|
||||
// The list can be filtered by link and ip family.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func RouteList(link Link, family int) ([]Route, error) {
|
||||
return pkgHandle.RouteList(link, family)
|
||||
}
|
||||
@@ -1170,6 +1174,9 @@ func RouteList(link Link, family int) ([]Route, error) {
|
||||
// RouteList gets a list of routes in the system.
|
||||
// Equivalent to: `ip route show`.
|
||||
// The list can be filtered by link and ip family.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) RouteList(link Link, family int) ([]Route, error) {
|
||||
routeFilter := &Route{}
|
||||
if link != nil {
|
||||
@@ -1188,6 +1195,9 @@ func RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, e
|
||||
|
||||
// RouteListFiltered gets a list of routes in the system filtered with specified rules.
|
||||
// All rules must be defined in RouteFilter struct
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) {
|
||||
var res []Route
|
||||
err := h.RouteListFilteredIter(family, filter, filterMask, func(route Route) (cont bool) {
|
||||
@@ -1202,17 +1212,22 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64)
|
||||
|
||||
// RouteListFilteredIter passes each route that matches the filter to the given iterator func. Iteration continues
|
||||
// until all routes are loaded or the func returns false.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func RouteListFilteredIter(family int, filter *Route, filterMask uint64, f func(Route) (cont bool)) error {
|
||||
return pkgHandle.RouteListFilteredIter(family, filter, filterMask, f)
|
||||
}
|
||||
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) RouteListFilteredIter(family int, filter *Route, filterMask uint64, f func(Route) (cont bool)) error {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETROUTE, unix.NLM_F_DUMP)
|
||||
rtmsg := &nl.RtMsg{}
|
||||
rtmsg.Family = uint8(family)
|
||||
|
||||
var parseErr error
|
||||
err := h.routeHandleIter(filter, req, rtmsg, func(m []byte) bool {
|
||||
executeErr := h.routeHandleIter(filter, req, rtmsg, func(m []byte) bool {
|
||||
msg := nl.DeserializeRtMsg(m)
|
||||
if family != FAMILY_ALL && msg.Family != uint8(family) {
|
||||
// Ignore routes not matching requested family
|
||||
@@ -1270,13 +1285,13 @@ func (h *Handle) RouteListFilteredIter(family int, filter *Route, filterMask uin
|
||||
}
|
||||
return f(route)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return executeErr
|
||||
}
|
||||
if parseErr != nil {
|
||||
return parseErr
|
||||
}
|
||||
return nil
|
||||
return executeErr
|
||||
}
|
||||
|
||||
// deserializeRoute decodes a binary netlink message into a Route struct
|
||||
@@ -1684,6 +1699,10 @@ type RouteSubscribeOptions struct {
|
||||
// RouteSubscribeWithOptions work like RouteSubscribe but enable to
|
||||
// provide additional options to modify the behavior. Currently, the
|
||||
// namespace can be provided as well as an error callback.
|
||||
//
|
||||
// When options.ListExisting is true, options.ErrorCallback may be
|
||||
// called with [ErrDumpInterrupted] to indicate that results from
|
||||
// the initial dump of links may be inconsistent or incomplete.
|
||||
func RouteSubscribeWithOptions(ch chan<- RouteUpdate, done <-chan struct{}, options RouteSubscribeOptions) error {
|
||||
if options.Namespace == nil {
|
||||
none := netns.None()
|
||||
@@ -1743,6 +1762,9 @@ func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <
|
||||
continue
|
||||
}
|
||||
for _, m := range msgs {
|
||||
if m.Header.Flags&unix.NLM_F_DUMP_INTR != 0 && cberr != nil {
|
||||
cberr(ErrDumpInterrupted)
|
||||
}
|
||||
if m.Header.Type == unix.NLMSG_DONE {
|
||||
continue
|
||||
}
|
||||
|
||||
21
vendor/github.com/vishvananda/netlink/rule_linux.go
generated
vendored
21
vendor/github.com/vishvananda/netlink/rule_linux.go
generated
vendored
@@ -2,6 +2,7 @@ package netlink
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
@@ -183,12 +184,18 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
|
||||
|
||||
// RuleList lists rules in the system.
|
||||
// Equivalent to: ip rule list
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func RuleList(family int) ([]Rule, error) {
|
||||
return pkgHandle.RuleList(family)
|
||||
}
|
||||
|
||||
// RuleList lists rules in the system.
|
||||
// Equivalent to: ip rule list
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) RuleList(family int) ([]Rule, error) {
|
||||
return h.RuleListFiltered(family, nil, 0)
|
||||
}
|
||||
@@ -196,20 +203,26 @@ func (h *Handle) RuleList(family int) ([]Rule, error) {
|
||||
// RuleListFiltered gets a list of rules in the system filtered by the
|
||||
// specified rule template `filter`.
|
||||
// Equivalent to: ip rule list
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func RuleListFiltered(family int, filter *Rule, filterMask uint64) ([]Rule, error) {
|
||||
return pkgHandle.RuleListFiltered(family, filter, filterMask)
|
||||
}
|
||||
|
||||
// RuleListFiltered lists rules in the system.
|
||||
// Equivalent to: ip rule list
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) RuleListFiltered(family int, filter *Rule, filterMask uint64) ([]Rule, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETRULE, unix.NLM_F_DUMP|unix.NLM_F_REQUEST)
|
||||
msg := nl.NewIfInfomsg(family)
|
||||
req.AddData(msg)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWRULE)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWRULE)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
|
||||
var res = make([]Rule, 0)
|
||||
@@ -306,7 +319,7 @@ func (h *Handle) RuleListFiltered(family int, filter *Rule, filterMask uint64) (
|
||||
res = append(res, *rule)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
return res, executeErr
|
||||
}
|
||||
|
||||
func (pr *RulePortRange) toRtAttrData() []byte {
|
||||
|
||||
109
vendor/github.com/vishvananda/netlink/socket_linux.go
generated
vendored
109
vendor/github.com/vishvananda/netlink/socket_linux.go
generated
vendored
@@ -157,6 +157,9 @@ func (u *UnixSocket) deserialize(b []byte) error {
|
||||
}
|
||||
|
||||
// SocketGet returns the Socket identified by its local and remote addresses.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], the search for a result may
|
||||
// be incomplete and the caller should retry.
|
||||
func (h *Handle) SocketGet(local, remote net.Addr) (*Socket, error) {
|
||||
var protocol uint8
|
||||
var localIP, remoteIP net.IP
|
||||
@@ -232,6 +235,9 @@ func (h *Handle) SocketGet(local, remote net.Addr) (*Socket, error) {
|
||||
}
|
||||
|
||||
// SocketGet returns the Socket identified by its local and remote addresses.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], the search for a result may
|
||||
// be incomplete and the caller should retry.
|
||||
func SocketGet(local, remote net.Addr) (*Socket, error) {
|
||||
return pkgHandle.SocketGet(local, remote)
|
||||
}
|
||||
@@ -283,6 +289,9 @@ func SocketDestroy(local, remote net.Addr) error {
|
||||
}
|
||||
|
||||
// SocketDiagTCPInfo requests INET_DIAG_INFO for TCP protocol for specified family type and return with extension TCP info.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) SocketDiagTCPInfo(family uint8) ([]*InetDiagTCPInfoResp, error) {
|
||||
// Construct the request
|
||||
req := h.newNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP)
|
||||
@@ -295,9 +304,9 @@ func (h *Handle) SocketDiagTCPInfo(family uint8) ([]*InetDiagTCPInfoResp, error)
|
||||
|
||||
// Do the query and parse the result
|
||||
var result []*InetDiagTCPInfoResp
|
||||
var err error
|
||||
err = req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
|
||||
executeErr := req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
|
||||
sockInfo := &Socket{}
|
||||
var err error
|
||||
if err = sockInfo.deserialize(msg); err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -315,18 +324,24 @@ func (h *Handle) SocketDiagTCPInfo(family uint8) ([]*InetDiagTCPInfoResp, error)
|
||||
return true
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
return result, nil
|
||||
return result, executeErr
|
||||
}
|
||||
|
||||
// SocketDiagTCPInfo requests INET_DIAG_INFO for TCP protocol for specified family type and return with extension TCP info.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func SocketDiagTCPInfo(family uint8) ([]*InetDiagTCPInfoResp, error) {
|
||||
return pkgHandle.SocketDiagTCPInfo(family)
|
||||
}
|
||||
|
||||
// SocketDiagTCP requests INET_DIAG_INFO for TCP protocol for specified family type and return related socket.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) SocketDiagTCP(family uint8) ([]*Socket, error) {
|
||||
// Construct the request
|
||||
req := h.newNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP)
|
||||
@@ -339,27 +354,32 @@ func (h *Handle) SocketDiagTCP(family uint8) ([]*Socket, error) {
|
||||
|
||||
// Do the query and parse the result
|
||||
var result []*Socket
|
||||
var err error
|
||||
err = req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
|
||||
executeErr := req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
|
||||
sockInfo := &Socket{}
|
||||
if err = sockInfo.deserialize(msg); err != nil {
|
||||
if err := sockInfo.deserialize(msg); err != nil {
|
||||
return false
|
||||
}
|
||||
result = append(result, sockInfo)
|
||||
return true
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
return result, nil
|
||||
return result, executeErr
|
||||
}
|
||||
|
||||
// SocketDiagTCP requests INET_DIAG_INFO for TCP protocol for specified family type and return related socket.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func SocketDiagTCP(family uint8) ([]*Socket, error) {
|
||||
return pkgHandle.SocketDiagTCP(family)
|
||||
}
|
||||
|
||||
// SocketDiagUDPInfo requests INET_DIAG_INFO for UDP protocol for specified family type and return with extension info.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) SocketDiagUDPInfo(family uint8) ([]*InetDiagUDPInfoResp, error) {
|
||||
// Construct the request
|
||||
var extensions uint8
|
||||
@@ -377,14 +397,14 @@ func (h *Handle) SocketDiagUDPInfo(family uint8) ([]*InetDiagUDPInfoResp, error)
|
||||
|
||||
// Do the query and parse the result
|
||||
var result []*InetDiagUDPInfoResp
|
||||
var err error
|
||||
err = req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
|
||||
executeErr := req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
|
||||
sockInfo := &Socket{}
|
||||
if err = sockInfo.deserialize(msg); err != nil {
|
||||
if err := sockInfo.deserialize(msg); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
var attrs []syscall.NetlinkRouteAttr
|
||||
var err error
|
||||
if attrs, err = nl.ParseRouteAttr(msg[sizeofSocket:]); err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -397,18 +417,24 @@ func (h *Handle) SocketDiagUDPInfo(family uint8) ([]*InetDiagUDPInfoResp, error)
|
||||
result = append(result, res)
|
||||
return true
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
return result, nil
|
||||
return result, executeErr
|
||||
}
|
||||
|
||||
// SocketDiagUDPInfo requests INET_DIAG_INFO for UDP protocol for specified family type and return with extension info.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func SocketDiagUDPInfo(family uint8) ([]*InetDiagUDPInfoResp, error) {
|
||||
return pkgHandle.SocketDiagUDPInfo(family)
|
||||
}
|
||||
|
||||
// SocketDiagUDP requests INET_DIAG_INFO for UDP protocol for specified family type and return related socket.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) SocketDiagUDP(family uint8) ([]*Socket, error) {
|
||||
// Construct the request
|
||||
req := h.newNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP)
|
||||
@@ -421,27 +447,32 @@ func (h *Handle) SocketDiagUDP(family uint8) ([]*Socket, error) {
|
||||
|
||||
// Do the query and parse the result
|
||||
var result []*Socket
|
||||
var err error
|
||||
err = req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
|
||||
executeErr := req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
|
||||
sockInfo := &Socket{}
|
||||
if err = sockInfo.deserialize(msg); err != nil {
|
||||
if err := sockInfo.deserialize(msg); err != nil {
|
||||
return false
|
||||
}
|
||||
result = append(result, sockInfo)
|
||||
return true
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
return result, nil
|
||||
return result, executeErr
|
||||
}
|
||||
|
||||
// SocketDiagUDP requests INET_DIAG_INFO for UDP protocol for specified family type and return related socket.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func SocketDiagUDP(family uint8) ([]*Socket, error) {
|
||||
return pkgHandle.SocketDiagUDP(family)
|
||||
}
|
||||
|
||||
// UnixSocketDiagInfo requests UNIX_DIAG_INFO for unix sockets and return with extension info.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) UnixSocketDiagInfo() ([]*UnixDiagInfoResp, error) {
|
||||
// Construct the request
|
||||
var extensions uint8
|
||||
@@ -456,10 +487,9 @@ func (h *Handle) UnixSocketDiagInfo() ([]*UnixDiagInfoResp, error) {
|
||||
})
|
||||
|
||||
var result []*UnixDiagInfoResp
|
||||
var err error
|
||||
err = req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
|
||||
executeErr := req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
|
||||
sockInfo := &UnixSocket{}
|
||||
if err = sockInfo.deserialize(msg); err != nil {
|
||||
if err := sockInfo.deserialize(msg); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -469,6 +499,7 @@ func (h *Handle) UnixSocketDiagInfo() ([]*UnixDiagInfoResp, error) {
|
||||
}
|
||||
|
||||
var attrs []syscall.NetlinkRouteAttr
|
||||
var err error
|
||||
if attrs, err = nl.ParseRouteAttr(msg[sizeofSocket:]); err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -480,18 +511,24 @@ func (h *Handle) UnixSocketDiagInfo() ([]*UnixDiagInfoResp, error) {
|
||||
result = append(result, res)
|
||||
return true
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
return result, nil
|
||||
return result, executeErr
|
||||
}
|
||||
|
||||
// UnixSocketDiagInfo requests UNIX_DIAG_INFO for unix sockets and return with extension info.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func UnixSocketDiagInfo() ([]*UnixDiagInfoResp, error) {
|
||||
return pkgHandle.UnixSocketDiagInfo()
|
||||
}
|
||||
|
||||
// UnixSocketDiag requests UNIX_DIAG_INFO for unix sockets.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) UnixSocketDiag() ([]*UnixSocket, error) {
|
||||
// Construct the request
|
||||
req := h.newNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP)
|
||||
@@ -501,10 +538,9 @@ func (h *Handle) UnixSocketDiag() ([]*UnixSocket, error) {
|
||||
})
|
||||
|
||||
var result []*UnixSocket
|
||||
var err error
|
||||
err = req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
|
||||
executeErr := req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
|
||||
sockInfo := &UnixSocket{}
|
||||
if err = sockInfo.deserialize(msg); err != nil {
|
||||
if err := sockInfo.deserialize(msg); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -514,13 +550,16 @@ func (h *Handle) UnixSocketDiag() ([]*UnixSocket, error) {
|
||||
}
|
||||
return true
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
return result, nil
|
||||
return result, executeErr
|
||||
}
|
||||
|
||||
// UnixSocketDiag requests UNIX_DIAG_INFO for unix sockets.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func UnixSocketDiag() ([]*UnixSocket, error) {
|
||||
return pkgHandle.UnixSocketDiag()
|
||||
}
|
||||
|
||||
18
vendor/github.com/vishvananda/netlink/socket_xdp_linux.go
generated
vendored
18
vendor/github.com/vishvananda/netlink/socket_xdp_linux.go
generated
vendored
@@ -52,8 +52,10 @@ func (s *XDPSocket) deserialize(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// XDPSocketGet returns the XDP socket identified by its inode number and/or
|
||||
// SocketXDPGetInfo returns the XDP socket identified by its inode number and/or
|
||||
// socket cookie. Specify the cookie as SOCK_ANY_COOKIE if
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], the caller should retry.
|
||||
func SocketXDPGetInfo(ino uint32, cookie uint64) (*XDPDiagInfoResp, error) {
|
||||
// We have a problem here: dumping AF_XDP sockets currently does not support
|
||||
// filtering. We thus need to dump all XSKs and then only filter afterwards
|
||||
@@ -85,6 +87,9 @@ func SocketXDPGetInfo(ino uint32, cookie uint64) (*XDPDiagInfoResp, error) {
|
||||
}
|
||||
|
||||
// SocketDiagXDP requests XDP_DIAG_INFO for XDP family sockets.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func SocketDiagXDP() ([]*XDPDiagInfoResp, error) {
|
||||
var result []*XDPDiagInfoResp
|
||||
err := socketDiagXDPExecutor(func(m syscall.NetlinkMessage) error {
|
||||
@@ -105,10 +110,10 @@ func SocketDiagXDP() ([]*XDPDiagInfoResp, error) {
|
||||
result = append(result, res)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
if err != nil && !errors.Is(err, ErrDumpInterrupted) {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
return result, err
|
||||
}
|
||||
|
||||
// socketDiagXDPExecutor requests XDP_DIAG_INFO for XDP family sockets.
|
||||
@@ -128,6 +133,7 @@ func socketDiagXDPExecutor(receiver func(syscall.NetlinkMessage) error) error {
|
||||
return err
|
||||
}
|
||||
|
||||
dumpIntr := false
|
||||
loop:
|
||||
for {
|
||||
msgs, from, err := s.Receive()
|
||||
@@ -142,6 +148,9 @@ loop:
|
||||
}
|
||||
|
||||
for _, m := range msgs {
|
||||
if m.Header.Flags&unix.NLM_F_DUMP_INTR != 0 {
|
||||
dumpIntr = true
|
||||
}
|
||||
switch m.Header.Type {
|
||||
case unix.NLMSG_DONE:
|
||||
break loop
|
||||
@@ -154,6 +163,9 @@ loop:
|
||||
}
|
||||
}
|
||||
}
|
||||
if dumpIntr {
|
||||
return ErrDumpInterrupted
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
60
vendor/github.com/vishvananda/netlink/vdpa_linux.go
generated
vendored
60
vendor/github.com/vishvananda/netlink/vdpa_linux.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"syscall"
|
||||
@@ -118,6 +119,9 @@ func VDPADelDev(name string) error {
|
||||
|
||||
// VDPAGetDevList returns list of VDPA devices
|
||||
// Equivalent to: `vdpa dev show`
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func VDPAGetDevList() ([]*VDPADev, error) {
|
||||
return pkgHandle.VDPAGetDevList()
|
||||
}
|
||||
@@ -130,6 +134,9 @@ func VDPAGetDevByName(name string) (*VDPADev, error) {
|
||||
|
||||
// VDPAGetDevConfigList returns list of VDPA devices configurations
|
||||
// Equivalent to: `vdpa dev config show`
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func VDPAGetDevConfigList() ([]*VDPADevConfig, error) {
|
||||
return pkgHandle.VDPAGetDevConfigList()
|
||||
}
|
||||
@@ -148,6 +155,9 @@ func VDPAGetDevVStats(name string, queueIndex uint32) (*VDPADevVStats, error) {
|
||||
|
||||
// VDPAGetMGMTDevList returns list of mgmt devices
|
||||
// Equivalent to: `vdpa mgmtdev show`
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func VDPAGetMGMTDevList() ([]*VDPAMGMTDev, error) {
|
||||
return pkgHandle.VDPAGetMGMTDevList()
|
||||
}
|
||||
@@ -261,9 +271,9 @@ func (h *Handle) vdpaRequest(command uint8, extraFlags int, attrs []*nl.RtAttr)
|
||||
req.AddData(a)
|
||||
}
|
||||
|
||||
resp, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
resp, executeErr := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
messages := make([]vdpaNetlinkMessage, 0, len(resp))
|
||||
for _, m := range resp {
|
||||
@@ -273,10 +283,13 @@ func (h *Handle) vdpaRequest(command uint8, extraFlags int, attrs []*nl.RtAttr)
|
||||
}
|
||||
messages = append(messages, attrs)
|
||||
}
|
||||
return messages, nil
|
||||
return messages, executeErr
|
||||
}
|
||||
|
||||
// dump all devices if dev is nil
|
||||
//
|
||||
// If dev is nil and the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) vdpaDevGet(dev *string) ([]*VDPADev, error) {
|
||||
var extraFlags int
|
||||
var attrs []*nl.RtAttr
|
||||
@@ -285,9 +298,9 @@ func (h *Handle) vdpaDevGet(dev *string) ([]*VDPADev, error) {
|
||||
} else {
|
||||
extraFlags = extraFlags | unix.NLM_F_DUMP
|
||||
}
|
||||
messages, err := h.vdpaRequest(nl.VDPA_CMD_DEV_GET, extraFlags, attrs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
messages, executeErr := h.vdpaRequest(nl.VDPA_CMD_DEV_GET, extraFlags, attrs)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
devs := make([]*VDPADev, 0, len(messages))
|
||||
for _, m := range messages {
|
||||
@@ -295,10 +308,13 @@ func (h *Handle) vdpaDevGet(dev *string) ([]*VDPADev, error) {
|
||||
d.parseAttributes(m)
|
||||
devs = append(devs, d)
|
||||
}
|
||||
return devs, nil
|
||||
return devs, executeErr
|
||||
}
|
||||
|
||||
// dump all devices if dev is nil
|
||||
//
|
||||
// If dev is nil, and the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) vdpaDevConfigGet(dev *string) ([]*VDPADevConfig, error) {
|
||||
var extraFlags int
|
||||
var attrs []*nl.RtAttr
|
||||
@@ -307,9 +323,9 @@ func (h *Handle) vdpaDevConfigGet(dev *string) ([]*VDPADevConfig, error) {
|
||||
} else {
|
||||
extraFlags = extraFlags | unix.NLM_F_DUMP
|
||||
}
|
||||
messages, err := h.vdpaRequest(nl.VDPA_CMD_DEV_CONFIG_GET, extraFlags, attrs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
messages, executeErr := h.vdpaRequest(nl.VDPA_CMD_DEV_CONFIG_GET, extraFlags, attrs)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
cfgs := make([]*VDPADevConfig, 0, len(messages))
|
||||
for _, m := range messages {
|
||||
@@ -317,10 +333,13 @@ func (h *Handle) vdpaDevConfigGet(dev *string) ([]*VDPADevConfig, error) {
|
||||
cfg.parseAttributes(m)
|
||||
cfgs = append(cfgs, cfg)
|
||||
}
|
||||
return cfgs, nil
|
||||
return cfgs, executeErr
|
||||
}
|
||||
|
||||
// dump all devices if dev is nil
|
||||
//
|
||||
// If dev is nil and the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) vdpaMGMTDevGet(bus, dev *string) ([]*VDPAMGMTDev, error) {
|
||||
var extraFlags int
|
||||
var attrs []*nl.RtAttr
|
||||
@@ -336,9 +355,9 @@ func (h *Handle) vdpaMGMTDevGet(bus, dev *string) ([]*VDPAMGMTDev, error) {
|
||||
} else {
|
||||
extraFlags = extraFlags | unix.NLM_F_DUMP
|
||||
}
|
||||
messages, err := h.vdpaRequest(nl.VDPA_CMD_MGMTDEV_GET, extraFlags, attrs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
messages, executeErr := h.vdpaRequest(nl.VDPA_CMD_MGMTDEV_GET, extraFlags, attrs)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
cfgs := make([]*VDPAMGMTDev, 0, len(messages))
|
||||
for _, m := range messages {
|
||||
@@ -346,7 +365,7 @@ func (h *Handle) vdpaMGMTDevGet(bus, dev *string) ([]*VDPAMGMTDev, error) {
|
||||
cfg.parseAttributes(m)
|
||||
cfgs = append(cfgs, cfg)
|
||||
}
|
||||
return cfgs, nil
|
||||
return cfgs, executeErr
|
||||
}
|
||||
|
||||
// VDPANewDev adds new VDPA device
|
||||
@@ -385,6 +404,9 @@ func (h *Handle) VDPADelDev(name string) error {
|
||||
|
||||
// VDPAGetDevList returns list of VDPA devices
|
||||
// Equivalent to: `vdpa dev show`
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) VDPAGetDevList() ([]*VDPADev, error) {
|
||||
return h.vdpaDevGet(nil)
|
||||
}
|
||||
@@ -404,6 +426,9 @@ func (h *Handle) VDPAGetDevByName(name string) (*VDPADev, error) {
|
||||
|
||||
// VDPAGetDevConfigList returns list of VDPA devices configurations
|
||||
// Equivalent to: `vdpa dev config show`
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) VDPAGetDevConfigList() ([]*VDPADevConfig, error) {
|
||||
return h.vdpaDevConfigGet(nil)
|
||||
}
|
||||
@@ -441,6 +466,9 @@ func (h *Handle) VDPAGetDevVStats(name string, queueIndex uint32) (*VDPADevVStat
|
||||
|
||||
// VDPAGetMGMTDevList returns list of mgmt devices
|
||||
// Equivalent to: `vdpa mgmtdev show`
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) VDPAGetMGMTDevList() ([]*VDPAMGMTDev, error) {
|
||||
return h.vdpaMGMTDevGet(nil, nil)
|
||||
}
|
||||
|
||||
15
vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go
generated
vendored
15
vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
@@ -215,6 +216,9 @@ func (h *Handle) XfrmPolicyDel(policy *XfrmPolicy) error {
|
||||
// XfrmPolicyList gets a list of xfrm policies in the system.
|
||||
// Equivalent to: `ip xfrm policy show`.
|
||||
// The list can be filtered by ip family.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func XfrmPolicyList(family int) ([]XfrmPolicy, error) {
|
||||
return pkgHandle.XfrmPolicyList(family)
|
||||
}
|
||||
@@ -222,15 +226,18 @@ func XfrmPolicyList(family int) ([]XfrmPolicy, error) {
|
||||
// XfrmPolicyList gets a list of xfrm policies in the system.
|
||||
// Equivalent to: `ip xfrm policy show`.
|
||||
// The list can be filtered by ip family.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) XfrmPolicyList(family int) ([]XfrmPolicy, error) {
|
||||
req := h.newNetlinkRequest(nl.XFRM_MSG_GETPOLICY, unix.NLM_F_DUMP)
|
||||
|
||||
msg := nl.NewIfInfomsg(family)
|
||||
req.AddData(msg)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_XFRM, nl.XFRM_MSG_NEWPOLICY)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_XFRM, nl.XFRM_MSG_NEWPOLICY)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
|
||||
var res []XfrmPolicy
|
||||
@@ -243,7 +250,7 @@ func (h *Handle) XfrmPolicyList(family int) ([]XfrmPolicy, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
return res, executeErr
|
||||
}
|
||||
|
||||
// XfrmPolicyGet gets a the policy described by the index or selector, if found.
|
||||
|
||||
15
vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
generated
vendored
15
vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
@@ -382,6 +383,9 @@ func (h *Handle) XfrmStateDel(state *XfrmState) error {
|
||||
// XfrmStateList gets a list of xfrm states in the system.
|
||||
// Equivalent to: `ip [-4|-6] xfrm state show`.
|
||||
// The list can be filtered by ip family.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func XfrmStateList(family int) ([]XfrmState, error) {
|
||||
return pkgHandle.XfrmStateList(family)
|
||||
}
|
||||
@@ -389,12 +393,15 @@ func XfrmStateList(family int) ([]XfrmState, error) {
|
||||
// XfrmStateList gets a list of xfrm states in the system.
|
||||
// Equivalent to: `ip xfrm state show`.
|
||||
// The list can be filtered by ip family.
|
||||
//
|
||||
// If the returned error is [ErrDumpInterrupted], results may be inconsistent
|
||||
// or incomplete.
|
||||
func (h *Handle) XfrmStateList(family int) ([]XfrmState, error) {
|
||||
req := h.newNetlinkRequest(nl.XFRM_MSG_GETSA, unix.NLM_F_DUMP)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_XFRM, nl.XFRM_MSG_NEWSA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
msgs, executeErr := req.Execute(unix.NETLINK_XFRM, nl.XFRM_MSG_NEWSA)
|
||||
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
|
||||
return nil, executeErr
|
||||
}
|
||||
|
||||
var res []XfrmState
|
||||
@@ -407,7 +414,7 @@ func (h *Handle) XfrmStateList(family int) ([]XfrmState, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
return res, executeErr
|
||||
}
|
||||
|
||||
// XfrmStateGet gets the xfrm state described by the ID, if found.
|
||||
|
||||
7
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go
generated
vendored
7
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go
generated
vendored
@@ -18,13 +18,6 @@ const (
|
||||
WriteErrorKey = attribute.Key("http.write_error") // if an error occurred while writing a reply, the string of the error (io.EOF is not recorded)
|
||||
)
|
||||
|
||||
// Client HTTP metrics.
|
||||
const (
|
||||
clientRequestSize = "http.client.request.size" // Outgoing request bytes total
|
||||
clientResponseSize = "http.client.response.size" // Outgoing response bytes total
|
||||
clientDuration = "http.client.duration" // Outgoing end to end duration, milliseconds
|
||||
)
|
||||
|
||||
// Filter is a predicate used to determine whether a given http.request should
|
||||
// be traced. A Filter must return true if the request should be traced.
|
||||
type Filter func(*http.Request) bool
|
||||
|
||||
26
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go
generated
vendored
26
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go
generated
vendored
@@ -81,12 +81,6 @@ func (h *middleware) configure(c *config) {
|
||||
h.semconv = semconv.NewHTTPServer(c.Meter)
|
||||
}
|
||||
|
||||
func handleErr(err error) {
|
||||
if err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
}
|
||||
|
||||
// serveHTTP sets up tracing and calls the given next http.Handler with the span
|
||||
// context injected into the request context.
|
||||
func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http.Handler) {
|
||||
@@ -190,14 +184,18 @@ func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http
|
||||
// Use floating point division here for higher precision (instead of Millisecond method).
|
||||
elapsedTime := float64(time.Since(requestStartTime)) / float64(time.Millisecond)
|
||||
|
||||
h.semconv.RecordMetrics(ctx, semconv.MetricData{
|
||||
ServerName: h.server,
|
||||
Req: r,
|
||||
StatusCode: statusCode,
|
||||
AdditionalAttributes: labeler.Get(),
|
||||
RequestSize: bw.BytesRead(),
|
||||
ResponseSize: bytesWritten,
|
||||
ElapsedTime: elapsedTime,
|
||||
h.semconv.RecordMetrics(ctx, semconv.ServerMetricData{
|
||||
ServerName: h.server,
|
||||
ResponseSize: bytesWritten,
|
||||
MetricAttributes: semconv.MetricAttributes{
|
||||
Req: r,
|
||||
StatusCode: statusCode,
|
||||
AdditionalAttributes: labeler.Get(),
|
||||
},
|
||||
MetricData: semconv.MetricData{
|
||||
RequestSize: bw.BytesRead(),
|
||||
ElapsedTime: elapsedTime,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,9 @@ func (w *RespWriterWrapper) Write(p []byte) (int, error) {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
|
||||
w.writeHeader(http.StatusOK)
|
||||
if !w.wroteHeader {
|
||||
w.writeHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
n, err := w.ResponseWriter.Write(p)
|
||||
n1 := int64(n)
|
||||
@@ -80,7 +82,12 @@ func (w *RespWriterWrapper) writeHeader(statusCode int) {
|
||||
|
||||
// Flush implements [http.Flusher].
|
||||
func (w *RespWriterWrapper) Flush() {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
|
||||
if !w.wroteHeader {
|
||||
w.writeHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
if f, ok := w.ResponseWriter.(http.Flusher); ok {
|
||||
f.Flush()
|
||||
|
||||
@@ -83,18 +83,26 @@ func (s HTTPServer) Status(code int) (codes.Code, string) {
|
||||
return codes.Unset, ""
|
||||
}
|
||||
|
||||
type MetricData struct {
|
||||
ServerName string
|
||||
type ServerMetricData struct {
|
||||
ServerName string
|
||||
ResponseSize int64
|
||||
|
||||
MetricData
|
||||
MetricAttributes
|
||||
}
|
||||
|
||||
type MetricAttributes struct {
|
||||
Req *http.Request
|
||||
StatusCode int
|
||||
AdditionalAttributes []attribute.KeyValue
|
||||
|
||||
RequestSize int64
|
||||
ResponseSize int64
|
||||
ElapsedTime float64
|
||||
}
|
||||
|
||||
func (s HTTPServer) RecordMetrics(ctx context.Context, md MetricData) {
|
||||
type MetricData struct {
|
||||
RequestSize int64
|
||||
ElapsedTime float64
|
||||
}
|
||||
|
||||
func (s HTTPServer) RecordMetrics(ctx context.Context, md ServerMetricData) {
|
||||
if s.requestBytesCounter == nil || s.responseBytesCounter == nil || s.serverLatencyMeasure == nil {
|
||||
// This will happen if an HTTPServer{} is used insted of NewHTTPServer.
|
||||
return
|
||||
@@ -102,7 +110,7 @@ func (s HTTPServer) RecordMetrics(ctx context.Context, md MetricData) {
|
||||
|
||||
attributes := oldHTTPServer{}.MetricAttributes(md.ServerName, md.Req, md.StatusCode, md.AdditionalAttributes)
|
||||
o := metric.WithAttributeSet(attribute.NewSet(attributes...))
|
||||
addOpts := []metric.AddOption{o} // Allocate vararg slice once.
|
||||
addOpts := []metric.AddOption{o}
|
||||
s.requestBytesCounter.Add(ctx, md.RequestSize, addOpts...)
|
||||
s.responseBytesCounter.Add(ctx, md.ResponseSize, addOpts...)
|
||||
s.serverLatencyMeasure.Record(ctx, md.ElapsedTime, o)
|
||||
@@ -122,11 +130,20 @@ func NewHTTPServer(meter metric.Meter) HTTPServer {
|
||||
|
||||
type HTTPClient struct {
|
||||
duplicate bool
|
||||
|
||||
// old metrics
|
||||
requestBytesCounter metric.Int64Counter
|
||||
responseBytesCounter metric.Int64Counter
|
||||
latencyMeasure metric.Float64Histogram
|
||||
}
|
||||
|
||||
func NewHTTPClient() HTTPClient {
|
||||
func NewHTTPClient(meter metric.Meter) HTTPClient {
|
||||
env := strings.ToLower(os.Getenv("OTEL_SEMCONV_STABILITY_OPT_IN"))
|
||||
return HTTPClient{duplicate: env == "http/dup"}
|
||||
client := HTTPClient{
|
||||
duplicate: env == "http/dup",
|
||||
}
|
||||
client.requestBytesCounter, client.responseBytesCounter, client.latencyMeasure = oldHTTPClient{}.createMeasures(meter)
|
||||
return client
|
||||
}
|
||||
|
||||
// RequestTraceAttrs returns attributes for an HTTP request made by a client.
|
||||
@@ -163,3 +180,48 @@ func (c HTTPClient) ErrorType(err error) attribute.KeyValue {
|
||||
|
||||
return attribute.KeyValue{}
|
||||
}
|
||||
|
||||
type MetricOpts struct {
|
||||
measurement metric.MeasurementOption
|
||||
addOptions metric.AddOption
|
||||
}
|
||||
|
||||
func (o MetricOpts) MeasurementOption() metric.MeasurementOption {
|
||||
return o.measurement
|
||||
}
|
||||
|
||||
func (o MetricOpts) AddOptions() metric.AddOption {
|
||||
return o.addOptions
|
||||
}
|
||||
|
||||
func (c HTTPClient) MetricOptions(ma MetricAttributes) MetricOpts {
|
||||
attributes := oldHTTPClient{}.MetricAttributes(ma.Req, ma.StatusCode, ma.AdditionalAttributes)
|
||||
// TODO: Duplicate Metrics
|
||||
set := metric.WithAttributeSet(attribute.NewSet(attributes...))
|
||||
return MetricOpts{
|
||||
measurement: set,
|
||||
addOptions: set,
|
||||
}
|
||||
}
|
||||
|
||||
func (s HTTPClient) RecordMetrics(ctx context.Context, md MetricData, opts MetricOpts) {
|
||||
if s.requestBytesCounter == nil || s.latencyMeasure == nil {
|
||||
// This will happen if an HTTPClient{} is used insted of NewHTTPClient().
|
||||
return
|
||||
}
|
||||
|
||||
s.requestBytesCounter.Add(ctx, md.RequestSize, opts.AddOptions())
|
||||
s.latencyMeasure.Record(ctx, md.ElapsedTime, opts.MeasurementOption())
|
||||
|
||||
// TODO: Duplicate Metrics
|
||||
}
|
||||
|
||||
func (s HTTPClient) RecordResponseSize(ctx context.Context, responseData int64, opts metric.AddOption) {
|
||||
if s.responseBytesCounter == nil {
|
||||
// This will happen if an HTTPClient{} is used insted of NewHTTPClient().
|
||||
return
|
||||
}
|
||||
|
||||
s.responseBytesCounter.Add(ctx, responseData, opts)
|
||||
// TODO: Duplicate Metrics
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ func (o oldHTTPServer) MetricAttributes(server string, req *http.Request, status
|
||||
|
||||
attributes := slices.Grow(additionalAttributes, n)
|
||||
attributes = append(attributes,
|
||||
o.methodMetric(req.Method),
|
||||
standardizeHTTPMethodMetric(req.Method),
|
||||
o.scheme(req.TLS != nil),
|
||||
semconv.NetHostName(host))
|
||||
|
||||
@@ -164,16 +164,6 @@ func (o oldHTTPServer) MetricAttributes(server string, req *http.Request, status
|
||||
return attributes
|
||||
}
|
||||
|
||||
func (o oldHTTPServer) methodMetric(method string) attribute.KeyValue {
|
||||
method = strings.ToUpper(method)
|
||||
switch method {
|
||||
case http.MethodConnect, http.MethodDelete, http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodPatch, http.MethodPost, http.MethodPut, http.MethodTrace:
|
||||
default:
|
||||
method = "_OTHER"
|
||||
}
|
||||
return semconv.HTTPMethod(method)
|
||||
}
|
||||
|
||||
func (o oldHTTPServer) scheme(https bool) attribute.KeyValue { // nolint:revive
|
||||
if https {
|
||||
return semconv.HTTPSchemeHTTPS
|
||||
@@ -190,3 +180,95 @@ func (o oldHTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue
|
||||
func (o oldHTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue {
|
||||
return semconvutil.HTTPClientResponse(resp)
|
||||
}
|
||||
|
||||
func (o oldHTTPClient) MetricAttributes(req *http.Request, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue {
|
||||
/* The following semantic conventions are returned if present:
|
||||
http.method string
|
||||
http.status_code int
|
||||
net.peer.name string
|
||||
net.peer.port int
|
||||
*/
|
||||
|
||||
n := 2 // method, peer name.
|
||||
var h string
|
||||
if req.URL != nil {
|
||||
h = req.URL.Host
|
||||
}
|
||||
var requestHost string
|
||||
var requestPort int
|
||||
for _, hostport := range []string{h, req.Header.Get("Host")} {
|
||||
requestHost, requestPort = splitHostPort(hostport)
|
||||
if requestHost != "" || requestPort > 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
port := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", requestPort)
|
||||
if port > 0 {
|
||||
n++
|
||||
}
|
||||
|
||||
if statusCode > 0 {
|
||||
n++
|
||||
}
|
||||
|
||||
attributes := slices.Grow(additionalAttributes, n)
|
||||
attributes = append(attributes,
|
||||
standardizeHTTPMethodMetric(req.Method),
|
||||
semconv.NetPeerName(requestHost),
|
||||
)
|
||||
|
||||
if port > 0 {
|
||||
attributes = append(attributes, semconv.NetPeerPort(port))
|
||||
}
|
||||
|
||||
if statusCode > 0 {
|
||||
attributes = append(attributes, semconv.HTTPStatusCode(statusCode))
|
||||
}
|
||||
return attributes
|
||||
}
|
||||
|
||||
// Client HTTP metrics.
|
||||
const (
|
||||
clientRequestSize = "http.client.request.size" // Incoming request bytes total
|
||||
clientResponseSize = "http.client.response.size" // Incoming response bytes total
|
||||
clientDuration = "http.client.duration" // Incoming end to end duration, milliseconds
|
||||
)
|
||||
|
||||
func (o oldHTTPClient) createMeasures(meter metric.Meter) (metric.Int64Counter, metric.Int64Counter, metric.Float64Histogram) {
|
||||
if meter == nil {
|
||||
return noop.Int64Counter{}, noop.Int64Counter{}, noop.Float64Histogram{}
|
||||
}
|
||||
requestBytesCounter, err := meter.Int64Counter(
|
||||
clientRequestSize,
|
||||
metric.WithUnit("By"),
|
||||
metric.WithDescription("Measures the size of HTTP request messages."),
|
||||
)
|
||||
handleErr(err)
|
||||
|
||||
responseBytesCounter, err := meter.Int64Counter(
|
||||
clientResponseSize,
|
||||
metric.WithUnit("By"),
|
||||
metric.WithDescription("Measures the size of HTTP response messages."),
|
||||
)
|
||||
handleErr(err)
|
||||
|
||||
latencyMeasure, err := meter.Float64Histogram(
|
||||
clientDuration,
|
||||
metric.WithUnit("ms"),
|
||||
metric.WithDescription("Measures the duration of outbound HTTP requests."),
|
||||
)
|
||||
handleErr(err)
|
||||
|
||||
return requestBytesCounter, responseBytesCounter, latencyMeasure
|
||||
}
|
||||
|
||||
func standardizeHTTPMethodMetric(method string) attribute.KeyValue {
|
||||
method = strings.ToUpper(method)
|
||||
switch method {
|
||||
case http.MethodConnect, http.MethodDelete, http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodPatch, http.MethodPost, http.MethodPut, http.MethodTrace:
|
||||
default:
|
||||
method = "_OTHER"
|
||||
}
|
||||
return semconv.HTTPMethod(method)
|
||||
}
|
||||
|
||||
58
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go
generated
vendored
58
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go
generated
vendored
@@ -13,11 +13,9 @@ import (
|
||||
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
@@ -29,7 +27,6 @@ type Transport struct {
|
||||
rt http.RoundTripper
|
||||
|
||||
tracer trace.Tracer
|
||||
meter metric.Meter
|
||||
propagators propagation.TextMapPropagator
|
||||
spanStartOptions []trace.SpanStartOption
|
||||
filters []Filter
|
||||
@@ -37,10 +34,7 @@ type Transport struct {
|
||||
clientTrace func(context.Context) *httptrace.ClientTrace
|
||||
metricAttributesFn func(*http.Request) []attribute.KeyValue
|
||||
|
||||
semconv semconv.HTTPClient
|
||||
requestBytesCounter metric.Int64Counter
|
||||
responseBytesCounter metric.Int64Counter
|
||||
latencyMeasure metric.Float64Histogram
|
||||
semconv semconv.HTTPClient
|
||||
}
|
||||
|
||||
var _ http.RoundTripper = &Transport{}
|
||||
@@ -57,8 +51,7 @@ func NewTransport(base http.RoundTripper, opts ...Option) *Transport {
|
||||
}
|
||||
|
||||
t := Transport{
|
||||
rt: base,
|
||||
semconv: semconv.NewHTTPClient(),
|
||||
rt: base,
|
||||
}
|
||||
|
||||
defaultOpts := []Option{
|
||||
@@ -68,46 +61,21 @@ func NewTransport(base http.RoundTripper, opts ...Option) *Transport {
|
||||
|
||||
c := newConfig(append(defaultOpts, opts...)...)
|
||||
t.applyConfig(c)
|
||||
t.createMeasures()
|
||||
|
||||
return &t
|
||||
}
|
||||
|
||||
func (t *Transport) applyConfig(c *config) {
|
||||
t.tracer = c.Tracer
|
||||
t.meter = c.Meter
|
||||
t.propagators = c.Propagators
|
||||
t.spanStartOptions = c.SpanStartOptions
|
||||
t.filters = c.Filters
|
||||
t.spanNameFormatter = c.SpanNameFormatter
|
||||
t.clientTrace = c.ClientTrace
|
||||
t.semconv = semconv.NewHTTPClient(c.Meter)
|
||||
t.metricAttributesFn = c.MetricAttributesFn
|
||||
}
|
||||
|
||||
func (t *Transport) createMeasures() {
|
||||
var err error
|
||||
t.requestBytesCounter, err = t.meter.Int64Counter(
|
||||
clientRequestSize,
|
||||
metric.WithUnit("By"),
|
||||
metric.WithDescription("Measures the size of HTTP request messages."),
|
||||
)
|
||||
handleErr(err)
|
||||
|
||||
t.responseBytesCounter, err = t.meter.Int64Counter(
|
||||
clientResponseSize,
|
||||
metric.WithUnit("By"),
|
||||
metric.WithDescription("Measures the size of HTTP response messages."),
|
||||
)
|
||||
handleErr(err)
|
||||
|
||||
t.latencyMeasure, err = t.meter.Float64Histogram(
|
||||
clientDuration,
|
||||
metric.WithUnit("ms"),
|
||||
metric.WithDescription("Measures the duration of outbound HTTP requests."),
|
||||
)
|
||||
handleErr(err)
|
||||
}
|
||||
|
||||
func defaultTransportFormatter(_ string, r *http.Request) string {
|
||||
return "HTTP " + r.Method
|
||||
}
|
||||
@@ -177,16 +145,15 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||
}
|
||||
|
||||
// metrics
|
||||
metricAttrs := append(append(labeler.Get(), semconvutil.HTTPClientRequestMetrics(r)...), t.metricAttributesFromRequest(r)...)
|
||||
if res.StatusCode > 0 {
|
||||
metricAttrs = append(metricAttrs, semconv.HTTPStatusCode(res.StatusCode))
|
||||
}
|
||||
o := metric.WithAttributeSet(attribute.NewSet(metricAttrs...))
|
||||
metricOpts := t.semconv.MetricOptions(semconv.MetricAttributes{
|
||||
Req: r,
|
||||
StatusCode: res.StatusCode,
|
||||
AdditionalAttributes: append(labeler.Get(), t.metricAttributesFromRequest(r)...),
|
||||
})
|
||||
|
||||
t.requestBytesCounter.Add(ctx, bw.BytesRead(), o)
|
||||
// For handling response bytes we leverage a callback when the client reads the http response
|
||||
readRecordFunc := func(n int64) {
|
||||
t.responseBytesCounter.Add(ctx, n, o)
|
||||
t.semconv.RecordResponseSize(ctx, n, metricOpts.AddOptions())
|
||||
}
|
||||
|
||||
// traces
|
||||
@@ -198,9 +165,12 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||
// Use floating point division here for higher precision (instead of Millisecond method).
|
||||
elapsedTime := float64(time.Since(requestStartTime)) / float64(time.Millisecond)
|
||||
|
||||
t.latencyMeasure.Record(ctx, elapsedTime, o)
|
||||
t.semconv.RecordMetrics(ctx, semconv.MetricData{
|
||||
RequestSize: bw.BytesRead(),
|
||||
ElapsedTime: elapsedTime,
|
||||
}, metricOpts)
|
||||
|
||||
return res, err
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (t *Transport) metricAttributesFromRequest(r *http.Request) []attribute.KeyValue {
|
||||
|
||||
2
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go
generated
vendored
2
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go
generated
vendored
@@ -5,7 +5,7 @@ package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http
|
||||
|
||||
// Version is the current release version of the otelhttp instrumentation.
|
||||
func Version() string {
|
||||
return "0.54.0"
|
||||
return "0.56.0"
|
||||
// This string is updated by the pre_release.sh script during release
|
||||
}
|
||||
|
||||
|
||||
151
vendor/golang.org/x/exp/slices/slices.go
generated
vendored
151
vendor/golang.org/x/exp/slices/slices.go
generated
vendored
@@ -1,151 +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.
|
||||
|
||||
// Package slices defines various functions useful with slices of any type.
|
||||
package slices
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"slices"
|
||||
)
|
||||
|
||||
// TODO(adonovan): when https://go.dev/issue/32816 is accepted, all of
|
||||
// these functions should be annotated (provisionally with "//go:fix
|
||||
// inline") so that tools can safely and automatically replace calls
|
||||
// to exp/slices with calls to std slices by inlining them.
|
||||
|
||||
// Equal reports whether two slices are equal: the same length and all
|
||||
// elements equal. If the lengths are different, Equal returns false.
|
||||
// Otherwise, the elements are compared in increasing index order, and the
|
||||
// comparison stops at the first unequal pair.
|
||||
// Floating point NaNs are not considered equal.
|
||||
func Equal[S ~[]E, E comparable](s1, s2 S) bool {
|
||||
return slices.Equal(s1, s2)
|
||||
}
|
||||
|
||||
// EqualFunc reports whether two slices are equal using an equality
|
||||
// function on each pair of elements. If the lengths are different,
|
||||
// EqualFunc returns false. Otherwise, the elements are compared in
|
||||
// increasing index order, and the comparison stops at the first index
|
||||
// for which eq returns false.
|
||||
func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool {
|
||||
return slices.EqualFunc(s1, s2, eq)
|
||||
}
|
||||
|
||||
// Compare compares the elements of s1 and s2, using [cmp.Compare] on each pair
|
||||
// of elements. The elements are compared sequentially, starting at index 0,
|
||||
// until one element is not equal to the other.
|
||||
// The result of comparing the first non-matching elements is returned.
|
||||
// If both slices are equal until one of them ends, the shorter slice is
|
||||
// considered less than the longer one.
|
||||
// The result is 0 if s1 == s2, -1 if s1 < s2, and +1 if s1 > s2.
|
||||
func Compare[S ~[]E, E cmp.Ordered](s1, s2 S) int {
|
||||
return slices.Compare(s1, s2)
|
||||
}
|
||||
|
||||
// CompareFunc is like [Compare] but uses a custom comparison function on each
|
||||
// pair of elements.
|
||||
// The result is the first non-zero result of cmp; if cmp always
|
||||
// returns 0 the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2),
|
||||
// and +1 if len(s1) > len(s2).
|
||||
func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int {
|
||||
return slices.CompareFunc(s1, s2, cmp)
|
||||
}
|
||||
|
||||
// Index returns the index of the first occurrence of v in s,
|
||||
// or -1 if not present.
|
||||
func Index[S ~[]E, E comparable](s S, v E) int {
|
||||
return slices.Index(s, v)
|
||||
}
|
||||
|
||||
// IndexFunc returns the first index i satisfying f(s[i]),
|
||||
// or -1 if none do.
|
||||
func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int {
|
||||
return slices.IndexFunc(s, f)
|
||||
}
|
||||
|
||||
// Contains reports whether v is present in s.
|
||||
func Contains[S ~[]E, E comparable](s S, v E) bool {
|
||||
return slices.Contains(s, v)
|
||||
}
|
||||
|
||||
// ContainsFunc reports whether at least one
|
||||
// element e of s satisfies f(e).
|
||||
func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool {
|
||||
return slices.ContainsFunc(s, f)
|
||||
}
|
||||
|
||||
// Insert inserts the values v... into s at index i,
|
||||
// returning the modified slice.
|
||||
// The elements at s[i:] are shifted up to make room.
|
||||
// In the returned slice r, r[i] == v[0],
|
||||
// and r[i+len(v)] == value originally at r[i].
|
||||
// Insert panics if i is out of range.
|
||||
// This function is O(len(s) + len(v)).
|
||||
func Insert[S ~[]E, E any](s S, i int, v ...E) S {
|
||||
return slices.Insert(s, i, v...)
|
||||
}
|
||||
|
||||
// Delete removes the elements s[i:j] from s, returning the modified slice.
|
||||
// Delete panics if j > len(s) or s[i:j] is not a valid slice of s.
|
||||
// Delete is O(len(s)-i), so if many items must be deleted, it is better to
|
||||
// make a single call deleting them all together than to delete one at a time.
|
||||
// Delete zeroes the elements s[len(s)-(j-i):len(s)].
|
||||
func Delete[S ~[]E, E any](s S, i, j int) S {
|
||||
return slices.Delete(s, i, j)
|
||||
}
|
||||
|
||||
// DeleteFunc removes any elements from s for which del returns true,
|
||||
// returning the modified slice.
|
||||
// DeleteFunc zeroes the elements between the new length and the original length.
|
||||
func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S {
|
||||
return slices.DeleteFunc(s, del)
|
||||
}
|
||||
|
||||
// Replace replaces the elements s[i:j] by the given v, and returns the
|
||||
// modified slice. Replace panics if s[i:j] is not a valid slice of s.
|
||||
// When len(v) < (j-i), Replace zeroes the elements between the new length and the original length.
|
||||
func Replace[S ~[]E, E any](s S, i, j int, v ...E) S {
|
||||
return slices.Replace(s, i, j, v...)
|
||||
}
|
||||
|
||||
// Clone returns a copy of the slice.
|
||||
// The elements are copied using assignment, so this is a shallow clone.
|
||||
func Clone[S ~[]E, E any](s S) S {
|
||||
return slices.Clone(s)
|
||||
}
|
||||
|
||||
// Compact replaces consecutive runs of equal elements with a single copy.
|
||||
// This is like the uniq command found on Unix.
|
||||
// Compact modifies the contents of the slice s and returns the modified slice,
|
||||
// which may have a smaller length.
|
||||
// Compact zeroes the elements between the new length and the original length.
|
||||
func Compact[S ~[]E, E comparable](s S) S {
|
||||
return slices.Compact(s)
|
||||
}
|
||||
|
||||
// CompactFunc is like [Compact] but uses an equality function to compare elements.
|
||||
// For runs of elements that compare equal, CompactFunc keeps the first one.
|
||||
// CompactFunc zeroes the elements between the new length and the original length.
|
||||
func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S {
|
||||
return slices.CompactFunc(s, eq)
|
||||
}
|
||||
|
||||
// Grow increases the slice's capacity, if necessary, to guarantee space for
|
||||
// another n elements. After Grow(n), at least n elements can be appended
|
||||
// to the slice without another allocation. If n is negative or too large to
|
||||
// allocate the memory, Grow panics.
|
||||
func Grow[S ~[]E, E any](s S, n int) S {
|
||||
return slices.Grow(s, n)
|
||||
}
|
||||
|
||||
// Clip removes unused capacity from the slice, returning s[:len(s):len(s)].
|
||||
func Clip[S ~[]E, E any](s S) S {
|
||||
return slices.Clip(s)
|
||||
}
|
||||
|
||||
// Reverse reverses the elements of the slice in place.
|
||||
func Reverse[S ~[]E, E any](s S) {
|
||||
slices.Reverse(s)
|
||||
}
|
||||
96
vendor/golang.org/x/exp/slices/sort.go
generated
vendored
96
vendor/golang.org/x/exp/slices/sort.go
generated
vendored
@@ -1,96 +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.
|
||||
|
||||
package slices
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"slices"
|
||||
)
|
||||
|
||||
// TODO(adonovan): add a "//go:fix inline" annotation to each function
|
||||
// in this file; see https://go.dev/issue/32816.
|
||||
|
||||
// Sort sorts a slice of any ordered type in ascending order.
|
||||
// When sorting floating-point numbers, NaNs are ordered before other values.
|
||||
func Sort[S ~[]E, E cmp.Ordered](x S) {
|
||||
slices.Sort(x)
|
||||
}
|
||||
|
||||
// SortFunc sorts the slice x in ascending order as determined by the cmp
|
||||
// function. This sort is not guaranteed to be stable.
|
||||
// cmp(a, b) should return a negative number when a < b, a positive number when
|
||||
// a > b and zero when a == b or when a is not comparable to b in the sense
|
||||
// of the formal definition of Strict Weak Ordering.
|
||||
//
|
||||
// SortFunc requires that cmp is a strict weak ordering.
|
||||
// See https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings.
|
||||
// To indicate 'uncomparable', return 0 from the function.
|
||||
func SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
|
||||
slices.SortFunc(x, cmp)
|
||||
}
|
||||
|
||||
// SortStableFunc sorts the slice x while keeping the original order of equal
|
||||
// elements, using cmp to compare elements in the same way as [SortFunc].
|
||||
func SortStableFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
|
||||
slices.SortStableFunc(x, cmp)
|
||||
}
|
||||
|
||||
// IsSorted reports whether x is sorted in ascending order.
|
||||
func IsSorted[S ~[]E, E cmp.Ordered](x S) bool {
|
||||
return slices.IsSorted(x)
|
||||
}
|
||||
|
||||
// IsSortedFunc reports whether x is sorted in ascending order, with cmp as the
|
||||
// comparison function as defined by [SortFunc].
|
||||
func IsSortedFunc[S ~[]E, E any](x S, cmp func(a, b E) int) bool {
|
||||
return slices.IsSortedFunc(x, cmp)
|
||||
}
|
||||
|
||||
// Min returns the minimal value in x. It panics if x is empty.
|
||||
// For floating-point numbers, Min propagates NaNs (any NaN value in x
|
||||
// forces the output to be NaN).
|
||||
func Min[S ~[]E, E cmp.Ordered](x S) E {
|
||||
return slices.Min(x)
|
||||
}
|
||||
|
||||
// MinFunc returns the minimal value in x, using cmp to compare elements.
|
||||
// It panics if x is empty. If there is more than one minimal element
|
||||
// according to the cmp function, MinFunc returns the first one.
|
||||
func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
|
||||
return slices.MinFunc(x, cmp)
|
||||
}
|
||||
|
||||
// Max returns the maximal value in x. It panics if x is empty.
|
||||
// For floating-point E, Max propagates NaNs (any NaN value in x
|
||||
// forces the output to be NaN).
|
||||
func Max[S ~[]E, E cmp.Ordered](x S) E {
|
||||
return slices.Max(x)
|
||||
}
|
||||
|
||||
// MaxFunc returns the maximal value in x, using cmp to compare elements.
|
||||
// It panics if x is empty. If there is more than one maximal element
|
||||
// according to the cmp function, MaxFunc returns the first one.
|
||||
func MaxFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
|
||||
return slices.MaxFunc(x, cmp)
|
||||
}
|
||||
|
||||
// BinarySearch searches for target in a sorted slice and returns the position
|
||||
// where target is found, or the position where target would appear in the
|
||||
// sort order; it also returns a bool saying whether the target is really found
|
||||
// in the slice. The slice must be sorted in increasing order.
|
||||
func BinarySearch[S ~[]E, E cmp.Ordered](x S, target E) (int, bool) {
|
||||
return slices.BinarySearch(x, target)
|
||||
}
|
||||
|
||||
// BinarySearchFunc works like [BinarySearch], but uses a custom comparison
|
||||
// function. The slice must be sorted in increasing order, where "increasing"
|
||||
// is defined by cmp. cmp should return 0 if the slice element matches
|
||||
// the target, a negative number if the slice element precedes the target,
|
||||
// or a positive number if the slice element follows the target.
|
||||
// cmp must implement the same ordering as the slice, such that if
|
||||
// cmp(a, t) < 0 and cmp(b, t) >= 0, then a must precede b in the slice.
|
||||
func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool) {
|
||||
return slices.BinarySearchFunc(x, target, cmp)
|
||||
}
|
||||
30
vendor/modules.txt
vendored
30
vendor/modules.txt
vendored
@@ -111,7 +111,7 @@ github.com/cloudwego/iasm/x86_64
|
||||
# github.com/containerd/cgroups/v3 v3.0.3
|
||||
## explicit; go 1.18
|
||||
github.com/containerd/cgroups/v3/cgroup1/stats
|
||||
# github.com/containerd/errdefs v0.3.0
|
||||
# github.com/containerd/errdefs v1.0.0
|
||||
## explicit; go 1.20
|
||||
github.com/containerd/errdefs
|
||||
# github.com/containerd/errdefs/pkg v0.3.0
|
||||
@@ -122,7 +122,7 @@ github.com/containerd/errdefs/pkg/internal/types
|
||||
# github.com/containerd/log v0.1.0
|
||||
## explicit; go 1.20
|
||||
github.com/containerd/log
|
||||
# github.com/containerd/platforms v0.2.1
|
||||
# github.com/containerd/platforms v1.0.0-rc.1
|
||||
## explicit; go 1.20
|
||||
github.com/containerd/platforms
|
||||
# github.com/containerd/stargz-snapshotter/estargz v0.16.3
|
||||
@@ -147,8 +147,8 @@ github.com/containernetworking/cni/pkg/version
|
||||
# github.com/containernetworking/plugins v1.5.1
|
||||
## explicit; go 1.20
|
||||
github.com/containernetworking/plugins/pkg/ns
|
||||
# github.com/containers/buildah v1.38.1-0.20241119213149-52437ef15d33
|
||||
## explicit; go 1.22.6
|
||||
# github.com/containers/buildah v1.38.1-0.20250125114111-92015b7f4301
|
||||
## explicit; go 1.22.8
|
||||
github.com/containers/buildah
|
||||
github.com/containers/buildah/bind
|
||||
github.com/containers/buildah/chroot
|
||||
@@ -160,6 +160,7 @@ github.com/containers/buildah/internal
|
||||
github.com/containers/buildah/internal/config
|
||||
github.com/containers/buildah/internal/mkcw
|
||||
github.com/containers/buildah/internal/mkcw/types
|
||||
github.com/containers/buildah/internal/open
|
||||
github.com/containers/buildah/internal/parse
|
||||
github.com/containers/buildah/internal/sbom
|
||||
github.com/containers/buildah/internal/tmpdir
|
||||
@@ -178,8 +179,8 @@ github.com/containers/buildah/pkg/sshagent
|
||||
github.com/containers/buildah/pkg/util
|
||||
github.com/containers/buildah/pkg/volumes
|
||||
github.com/containers/buildah/util
|
||||
# github.com/containers/common v0.61.1-0.20250120135258-06628cb958e9
|
||||
## explicit; go 1.22.6
|
||||
# github.com/containers/common v0.61.1-0.20250124131345-fa339b6b6eda
|
||||
## explicit; go 1.22.8
|
||||
github.com/containers/common/internal
|
||||
github.com/containers/common/internal/attributedstring
|
||||
github.com/containers/common/libimage
|
||||
@@ -251,7 +252,7 @@ github.com/containers/conmon/runner/config
|
||||
# github.com/containers/gvisor-tap-vsock v0.8.2
|
||||
## explicit; go 1.22.0
|
||||
github.com/containers/gvisor-tap-vsock/pkg/types
|
||||
# github.com/containers/image/v5 v5.33.2-0.20250122201336-16f7e1e0e1fd
|
||||
# github.com/containers/image/v5 v5.33.2-0.20250122233652-b5c6aff95ca7
|
||||
## explicit; go 1.22.8
|
||||
github.com/containers/image/v5/copy
|
||||
github.com/containers/image/v5/directory
|
||||
@@ -333,7 +334,7 @@ github.com/containers/libhvee/pkg/wmiext
|
||||
# github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01
|
||||
## explicit
|
||||
github.com/containers/libtrust
|
||||
# github.com/containers/luksy v0.0.0-20241007190014-e2530d691420
|
||||
# github.com/containers/luksy v0.0.0-20250106202729-a3a812db5b72
|
||||
## explicit; go 1.20
|
||||
github.com/containers/luksy
|
||||
# github.com/containers/ocicrypt v1.2.1
|
||||
@@ -363,7 +364,7 @@ github.com/containers/psgo/internal/dev
|
||||
github.com/containers/psgo/internal/host
|
||||
github.com/containers/psgo/internal/proc
|
||||
github.com/containers/psgo/internal/process
|
||||
# github.com/containers/storage v1.56.2-0.20250121150636-c2cdd500e4ef
|
||||
# github.com/containers/storage v1.56.2-0.20250123125217-80d3c0e77d29
|
||||
## explicit; go 1.22.0
|
||||
github.com/containers/storage
|
||||
github.com/containers/storage/drivers
|
||||
@@ -471,7 +472,7 @@ github.com/distribution/reference
|
||||
## explicit
|
||||
github.com/docker/distribution/registry/api/errcode
|
||||
github.com/docker/distribution/registry/api/v2
|
||||
# github.com/docker/docker v27.5.0+incompatible
|
||||
# github.com/docker/docker v27.5.1+incompatible
|
||||
## explicit
|
||||
github.com/docker/docker/api
|
||||
github.com/docker/docker/api/types
|
||||
@@ -808,7 +809,7 @@ github.com/mistifyio/go-zfs/v3
|
||||
# github.com/mitchellh/mapstructure v1.5.0
|
||||
## explicit; go 1.14
|
||||
github.com/mitchellh/mapstructure
|
||||
# github.com/moby/buildkit v0.17.1
|
||||
# github.com/moby/buildkit v0.19.0
|
||||
## explicit; go 1.22.0
|
||||
github.com/moby/buildkit/frontend/dockerfile/command
|
||||
github.com/moby/buildkit/frontend/dockerfile/parser
|
||||
@@ -1115,7 +1116,7 @@ github.com/vbauerster/mpb/v8
|
||||
github.com/vbauerster/mpb/v8/cwriter
|
||||
github.com/vbauerster/mpb/v8/decor
|
||||
github.com/vbauerster/mpb/v8/internal
|
||||
# github.com/vishvananda/netlink v1.3.0
|
||||
# github.com/vishvananda/netlink v1.3.1-0.20240922070040-084abd93d350
|
||||
## explicit; go 1.12
|
||||
github.com/vishvananda/netlink
|
||||
github.com/vishvananda/netlink/nl
|
||||
@@ -1144,8 +1145,8 @@ go.opencensus.io/internal
|
||||
go.opencensus.io/trace
|
||||
go.opencensus.io/trace/internal
|
||||
go.opencensus.io/trace/tracestate
|
||||
# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0
|
||||
## explicit; go 1.21
|
||||
# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0
|
||||
## explicit; go 1.22
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv
|
||||
@@ -1212,7 +1213,6 @@ golang.org/x/crypto/xts
|
||||
# golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329
|
||||
## explicit; go 1.22.0
|
||||
golang.org/x/exp/maps
|
||||
golang.org/x/exp/slices
|
||||
# golang.org/x/mod v0.22.0
|
||||
## explicit; go 1.22.0
|
||||
golang.org/x/mod/semver
|
||||
|
||||
Reference in New Issue
Block a user