summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml24
-rw-r--r--cmd/podman/system/prune.go32
-rwxr-xr-xcontrib/cirrus/runner.sh4
-rwxr-xr-xcontrib/cirrus/setup_environment.sh1
-rw-r--r--docs/source/markdown/podman-build.1.md8
-rw-r--r--go.mod10
-rw-r--r--go.sum19
-rw-r--r--libpod/container_internal_linux.go14
-rw-r--r--libpod/oci_conmon_linux.go5
-rw-r--r--libpod/runtime_img.go18
-rw-r--r--pkg/api/handlers/compat/containers.go22
-rw-r--r--pkg/api/handlers/compat/containers_prune.go17
-rw-r--r--pkg/api/handlers/libpod/containers.go24
-rw-r--r--pkg/api/handlers/libpod/images.go19
-rw-r--r--pkg/api/server/register_images.go9
-rw-r--r--pkg/specgen/generate/security.go36
-rw-r--r--test/apiv2/20-containers.at26
-rw-r--r--test/buildah-bud/README.md82
-rw-r--r--test/buildah-bud/buildah-tests.diff192
-rw-r--r--test/buildah-bud/make-new-buildah-diffs63
-rwxr-xr-xtest/buildah-bud/run-buildah-bud-tests166
-rw-r--r--test/e2e/run_test.go23
-rw-r--r--test/python/docker/compat/test_images.py17
-rw-r--r--test/system/120-load.bats9
-rw-r--r--test/system/200-pod.bats16
-rw-r--r--test/system/220-healthcheck.bats2
-rw-r--r--test/system/410-selinux.bats3
-rw-r--r--test/system/500-networking.bats1
-rw-r--r--vendor/github.com/containers/common/pkg/auth/auth.go4
-rw-r--r--vendor/github.com/containers/common/pkg/capabilities/capabilities.go30
-rw-r--r--vendor/github.com/containers/common/pkg/chown/chown.go57
-rw-r--r--vendor/github.com/containers/common/pkg/chown/chown_unix.go66
-rw-r--r--vendor/github.com/containers/common/pkg/chown/chown_windows.go11
-rw-r--r--vendor/github.com/containers/common/pkg/completion/completion.go14
-rw-r--r--vendor/github.com/containers/common/pkg/config/default.go6
-rw-r--r--vendor/github.com/containers/common/pkg/parse/parse_unix.go7
-rw-r--r--vendor/github.com/containers/common/version/version.go2
-rw-r--r--vendor/github.com/containers/image/v5/copy/copy.go43
-rw-r--r--vendor/github.com/containers/image/v5/pkg/sysregistriesv2/shortnames.go12
-rw-r--r--vendor/github.com/containers/image/v5/storage/storage_image.go3
-rw-r--r--vendor/github.com/containers/image/v5/version/version.go2
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/activation/files_unix.go (renamed from vendor/github.com/coreos/go-systemd/v22/activation/files.go)2
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/activation/files_windows.go21
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go45
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/dbus/methods.go323
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/journal/journal.go179
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go208
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go35
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/sdjournal/journal.go51
-rw-r--r--vendor/github.com/syndtr/gocapability/capability/enum.go45
-rw-r--r--vendor/github.com/syndtr/gocapability/capability/enum_gen.go9
-rw-r--r--vendor/modules.txt10
52 files changed, 1619 insertions, 428 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 9c13f5303..e09db2a81 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -579,6 +579,29 @@ remote_system_test_task:
TEST_FLAVOR: sys
PODBIN_NAME: remote
+buildah_bud_test_task:
+ name: *std_name_fmt
+ alias: buildah_bud_test
+ skip: *tags
+ only_if: *not_docs
+ depends_on:
+ - local_integration_test
+ env:
+ TEST_FLAVOR: bud
+ DISTRO_NV: ${FEDORA_NAME}
+ # Not used here, is used in other tasks
+ VM_IMAGE_NAME: ${FEDORA_CACHE_IMAGE_NAME}
+ CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
+ # ID for re-use of build output
+ _BUILD_CACHE_HANDLE: ${FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
+ PODBIN_NAME: podman
+ gce_instance: *standardvm
+ timeout_in: 45m
+ clone_script: *noop
+ gopath_cache: *ro_gopath_cache
+ setup_script: *setup
+ main_script: *main
+ always: *int_logs_artifacts
rootless_system_test_task:
name: *std_name_fmt
@@ -687,6 +710,7 @@ success_task:
- remote_system_test
- rootless_system_test
- upgrade_test
+ - buildah_bud_test
- meta
container: *smallcontainer
env:
diff --git a/cmd/podman/system/prune.go b/cmd/podman/system/prune.go
index 136c15304..3020a541b 100644
--- a/cmd/podman/system/prune.go
+++ b/cmd/podman/system/prune.go
@@ -55,22 +55,17 @@ func init() {
func prune(cmd *cobra.Command, args []string) error {
var err error
-
// Prompt for confirmation if --force is not set
if !force {
reader := bufio.NewReader(os.Stdin)
volumeString := ""
if pruneOptions.Volume {
volumeString = `
- - all volumes not used by at least one container`
+ - all volumes not used by at least one container`
}
- fmt.Printf(`
-WARNING! This will remove:
- - all stopped containers%s
- - all stopped pods
- - all dangling images
- - all build cache
-Are you sure you want to continue? [y/N] `, volumeString)
+
+ fmt.Printf(createPruneWarningMessage(pruneOptions), volumeString, "Are you sure you want to continue? [y/N] ")
+
answer, err := reader.ReadString('\n')
if err != nil {
return err
@@ -115,3 +110,22 @@ Are you sure you want to continue? [y/N] `, volumeString)
fmt.Printf("Total reclaimed space: %s\n", units.HumanSize((float64)(response.ReclaimedSpace)))
return nil
}
+
+func createPruneWarningMessage(pruneOpts entities.SystemPruneOptions) string {
+ if pruneOpts.All {
+ return `WARNING! This will remove:
+ - all stopped containers
+ - all networks not used by at least one container%s
+ - all images without at least one container associated to them
+ - all build cache
+
+%s`
+ }
+ return `WARNING! This will remove:
+ - all stopped containers
+ - all networks not used by at least one container%s
+ - all dangling images
+ - all dangling build cache
+
+%s`
+}
diff --git a/contrib/cirrus/runner.sh b/contrib/cirrus/runner.sh
index fca9aff93..507d22e13 100755
--- a/contrib/cirrus/runner.sh
+++ b/contrib/cirrus/runner.sh
@@ -74,6 +74,10 @@ function _run_upgrade_test() {
bats test/upgrade |& logformatter
}
+function _run_bud() {
+ ./test/buildah-bud/run-buildah-bud-tests |& logformatter
+}
+
function _run_bindings() {
# shellcheck disable=SC2155
export PATH=$PATH:$GOSRC/hack
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index 64ea3b7b4..fcb1284e7 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -201,6 +201,7 @@ case "$TEST_FLAVOR" in
int) ;&
sys) ;&
upgrade_test) ;&
+ bud) ;&
bindings) ;&
endpoint)
# Use existing host bits when testing is to happen inside a container
diff --git a/docs/source/markdown/podman-build.1.md b/docs/source/markdown/podman-build.1.md
index 24093d414..8fcfe555e 100644
--- a/docs/source/markdown/podman-build.1.md
+++ b/docs/source/markdown/podman-build.1.md
@@ -650,6 +650,10 @@ If --userns-gid-map-group is specified, but --userns-uid-map-user is not
specified, `podman` will assume that the specified group name is also a
suitable user name to use as the default setting for this option.
+**NOTE:** When this option is specified by a rootless user, the specified
+mappings are relative to the rootless usernamespace in the container, rather
+than being relative to the host as it would be when run rootful.
+
#### **--userns-gid-map-group**=*group*
Specifies that a GID mapping which should be used to set ownership, at the
@@ -661,6 +665,10 @@ If --userns-uid-map-user is specified, but --userns-gid-map-group is not
specified, `podman` will assume that the specified user name is also a
suitable group name to use as the default setting for this option.
+**NOTE:** When this option is specified by a rootless user, the specified
+mappings are relative to the rootless usernamespace in the container, rather
+than being relative to the host as it would be when run rootful.
+
#### **--uts**=*how*
Sets the configuration for UTS namespaces when the handling `RUN` instructions.
diff --git a/go.mod b/go.mod
index a19d8dc04..680f9bd9c 100644
--- a/go.mod
+++ b/go.mod
@@ -11,13 +11,13 @@ require (
github.com/containernetworking/cni v0.8.1
github.com/containernetworking/plugins v0.9.1
github.com/containers/buildah v1.19.8
- github.com/containers/common v0.35.0
+ github.com/containers/common v0.35.3
github.com/containers/conmon v2.0.20+incompatible
- github.com/containers/image/v5 v5.10.2
+ github.com/containers/image/v5 v5.10.5
github.com/containers/ocicrypt v1.1.0
github.com/containers/psgo v1.5.2
github.com/containers/storage v1.28.0
- github.com/coreos/go-systemd/v22 v22.1.0
+ github.com/coreos/go-systemd/v22 v22.3.0
github.com/cri-o/ocicni v0.2.1-0.20210301205850-541cf7c703cf
github.com/cyphar/filepath-securejoin v0.2.2
github.com/davecgh/go-spew v1.1.1
@@ -67,8 +67,6 @@ require (
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
- k8s.io/api v0.20.1
+ k8s.io/api v0.20.5
k8s.io/apimachinery v0.20.5
)
-
-replace github.com/syndtr/gocapability => github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
diff --git a/go.sum b/go.sum
index 8e7039504..e7a89e5c3 100644
--- a/go.sum
+++ b/go.sum
@@ -179,13 +179,14 @@ github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRD
github.com/containers/buildah v1.19.8 h1:4TzmetfKPQF5hh6GgMwbAfrD50j+PAcsRiWDnx+gCI8=
github.com/containers/buildah v1.19.8/go.mod h1:VnyHWgNmfR1d89/zJ/F4cbwOzaQS+6sBky46W7dCo3E=
github.com/containers/common v0.33.4/go.mod h1:PhgL71XuC4jJ/1BIqeP7doke3aMFkCP90YBXwDeUr9g=
-github.com/containers/common v0.35.0 h1:1OLZ2v+Tj/CN9BTQkKZ5VOriOiArJedinMMqfJRUI38=
-github.com/containers/common v0.35.0/go.mod h1:gs1th7XFTOvVUl4LDPdQjOfOeNiVRDbQ7CNrZ0wS6F8=
+github.com/containers/common v0.35.3 h1:6tEBSIHlJzpmt35zA1ZcjBqbtUilAHDWaa7buPvaqWY=
+github.com/containers/common v0.35.3/go.mod h1:rMzxgD7nMGw++cEbsp+NZv0UJO4rgXbm7F7IbJPTwIE=
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/image/v5 v5.10.1/go.mod h1:JlRLJZv7elVbtHaaaR6Kz8i6G3k2ttj4t7fubwxD9Hs=
-github.com/containers/image/v5 v5.10.2 h1:STD9GYR9p/X0qTLmBYsyx8dEM7zQW+qZ8KHoL/64fkg=
github.com/containers/image/v5 v5.10.2/go.mod h1:JlRLJZv7elVbtHaaaR6Kz8i6G3k2ttj4t7fubwxD9Hs=
+github.com/containers/image/v5 v5.10.5 h1:VK1UbsZMzjdw5Xqr3Im9h4iOqHWU0naFs+I78kavc7I=
+github.com/containers/image/v5 v5.10.5/go.mod h1:SgIbWEedCNBbn2FI5cH0/jed1Ecy2s8XK5zTxvJTzII=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
@@ -197,7 +198,7 @@ github.com/containers/psgo v1.5.2/go.mod h1:2ubh0SsreMZjSXW1Hif58JrEcFudQyIy9EzP
github.com/containers/storage v1.23.5/go.mod h1:ha26Q6ngehFNhf3AWoXldvAvwI4jFe3ETQAf/CeZPyM=
github.com/containers/storage v1.24.5/go.mod h1:YC+2pY8SkfEAcZkwycxYbpK8EiRbx5soPPwz9dxe4IQ=
github.com/containers/storage v1.24.6/go.mod h1:YC+2pY8SkfEAcZkwycxYbpK8EiRbx5soPPwz9dxe4IQ=
-github.com/containers/storage v1.25.0/go.mod h1:UxTYd5F4mPVqmDRcRL0PBS8+HP74aBn96eahnhEvPtk=
+github.com/containers/storage v1.24.8/go.mod h1:YC+2pY8SkfEAcZkwycxYbpK8EiRbx5soPPwz9dxe4IQ=
github.com/containers/storage v1.28.0 h1:lA/9i9BIjfmIRxCI8GuzasYHmU4IUXVcfZZiDceD0Eg=
github.com/containers/storage v1.28.0/go.mod h1:ixAwO7Bj31cigqPEG7aCz+PYmxkDxbIFdUFioYdxbzI=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
@@ -213,8 +214,9 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
-github.com/coreos/go-systemd/v22 v22.1.0 h1:kq/SbG2BCKLkDKkjQf5OWwKWUKj1lgs3lFI4PxnR5lg=
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
+github.com/coreos/go-systemd/v22 v22.3.0 h1:C8u/Ljj8G8O6rqWJh2J8cDyeEFBMWvXlvJ/ccMyzcqw=
+github.com/coreos/go-systemd/v22 v22.3.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
@@ -747,8 +749,10 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
-github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0TYG7HtkIgExQo+2RdLuwRft63jn2HWj8=
+github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
+github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
+github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
github.com/tchap/go-patricia v2.3.0+incompatible h1:GkY4dP3cEfEASBPPkWd+AmjYxhmDkqO9/zg7R0lSQRs=
github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
@@ -1165,8 +1169,9 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-k8s.io/api v0.20.1 h1:ud1c3W3YNzGd6ABJlbFfKXBKXO+1KdGfcgGGNgFR03E=
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
+k8s.io/api v0.20.5 h1:zsMTffV0Le2EiI0aKvlTHEnXGxk1HiqGRhJcCPiI7JI=
+k8s.io/api v0.20.5/go.mod h1:FQjAceXnVaWDeov2YUWhOb6Yt+5UjErkp6UO3nczO1Y=
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apimachinery v0.20.5 h1:wO/FxMVRn223rAKxnBbwCyuN96bS9MFTIvP0e/V7cps=
k8s.io/apimachinery v0.20.5/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 24319f4b5..94c6c3840 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -1503,16 +1503,24 @@ func (c *Container) makeBindMounts() error {
}
// Make /etc/localtime
- if c.Timezone() != "" {
+ ctrTimezone := c.Timezone()
+ if ctrTimezone != "" {
+ // validate the format of the timezone specified if it's not "local"
+ if ctrTimezone != "local" {
+ _, err = time.LoadLocation(ctrTimezone)
+ if err != nil {
+ return errors.Wrapf(err, "error finding timezone for container %s", c.ID())
+ }
+ }
if _, ok := c.state.BindMounts["/etc/localtime"]; !ok {
var zonePath string
- if c.Timezone() == "local" {
+ if ctrTimezone == "local" {
zonePath, err = filepath.EvalSymlinks("/etc/localtime")
if err != nil {
return errors.Wrapf(err, "error finding local timezone for container %s", c.ID())
}
} else {
- zone := filepath.Join("/usr/share/zoneinfo", c.Timezone())
+ zone := filepath.Join("/usr/share/zoneinfo", ctrTimezone)
zonePath, err = filepath.EvalSymlinks(zone)
if err != nil {
return errors.Wrapf(err, "error setting timezone for container %s", c.ID())
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index ef5f6fb0c..1c7089e5d 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -1268,7 +1268,10 @@ func prepareProcessExec(c *Container, options *ExecOptions, env []string, sessio
return nil, err
}
- allCaps := capabilities.AllCapabilities()
+ allCaps, err := capabilities.BoundingSet()
+ if err != nil {
+ return nil, err
+ }
if options.Privileged {
pspec.Capabilities.Bounding = allCaps
} else {
diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go
index 90b11f8ca..13ac42e7d 100644
--- a/libpod/runtime_img.go
+++ b/libpod/runtime_img.go
@@ -313,15 +313,23 @@ func (r *Runtime) LoadImageFromSingleImageArchive(ctx context.Context, writer io
func() (types.ImageReference, error) {
return layout.NewReference(inputFile, "")
},
+ func() (types.ImageReference, error) {
+ // This item needs to be last to break out of loop and report meaningful error message
+ return nil,
+ errors.New("payload does not match any of the supported image formats (oci-archive, oci-dir, docker-archive, docker-dir)")
+ },
} {
src, err := referenceFn()
- if err == nil && src != nil {
- newImages, err := r.ImageRuntime().LoadFromArchiveReference(ctx, src, signaturePolicy, writer)
- if err == nil {
- return getImageNames(newImages), nil
- }
+ if err != nil {
saveErr = err
+ continue
+ }
+
+ newImages, err := r.ImageRuntime().LoadFromArchiveReference(ctx, src, signaturePolicy, writer)
+ if err == nil {
+ return getImageNames(newImages), nil
}
+ saveErr = err
}
return "", errors.Wrapf(saveErr, "error pulling image")
}
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go
index d3277b815..e7146a5d8 100644
--- a/pkg/api/handlers/compat/containers.go
+++ b/pkg/api/handlers/compat/containers.go
@@ -19,6 +19,7 @@ import (
"github.com/containers/podman/v3/pkg/domain/infra/abi"
"github.com/containers/podman/v3/pkg/ps"
"github.com/containers/podman/v3/pkg/signal"
+ "github.com/containers/podman/v3/pkg/util"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/go-connections/nat"
@@ -92,23 +93,24 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
- All bool `schema:"all"`
- Limit int `schema:"limit"`
- Size bool `schema:"size"`
- Filters map[string][]string `schema:"filters"`
+ All bool `schema:"all"`
+ Limit int `schema:"limit"`
+ Size bool `schema:"size"`
}{
// override any golang type defaults
}
- if err := decoder.Decode(&query, r.URL.Query()); err != nil {
- utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
+ filterMap, err := util.PrepareFilters(r)
+
+ if dErr := decoder.Decode(&query, r.URL.Query()); dErr != nil || err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
- filterFuncs := make([]libpod.ContainerFilter, 0, len(query.Filters))
+ filterFuncs := make([]libpod.ContainerFilter, 0, len(*filterMap))
all := query.All || query.Limit > 0
- if len(query.Filters) > 0 {
- for k, v := range query.Filters {
+ if len((*filterMap)) > 0 {
+ for k, v := range *filterMap {
generatedFunc, err := filters.GenerateContainerFilterFuncs(k, v, runtime)
if err != nil {
utils.InternalServerError(w, err)
@@ -120,7 +122,7 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
// Docker thinks that if status is given as an input, then we should override
// the all setting and always deal with all containers.
- if len(query.Filters["status"]) > 0 {
+ if len((*filterMap)["status"]) > 0 {
all = true
}
if !all {
diff --git a/pkg/api/handlers/compat/containers_prune.go b/pkg/api/handlers/compat/containers_prune.go
index dc4d53af6..e37929d27 100644
--- a/pkg/api/handlers/compat/containers_prune.go
+++ b/pkg/api/handlers/compat/containers_prune.go
@@ -9,23 +9,20 @@ import (
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/domain/entities/reports"
"github.com/containers/podman/v3/pkg/domain/filters"
- "github.com/gorilla/schema"
+ "github.com/containers/podman/v3/pkg/util"
"github.com/pkg/errors"
)
func PruneContainers(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
- decoder := r.Context().Value("decoder").(*schema.Decoder)
-
- query := struct {
- Filters map[string][]string `schema:"filters"`
- }{}
- if err := decoder.Decode(&query, r.URL.Query()); err != nil {
- utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
+ filtersMap, err := util.PrepareFilters(r)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
- filterFuncs := make([]libpod.ContainerFilter, 0, len(query.Filters))
- for k, v := range query.Filters {
+
+ filterFuncs := make([]libpod.ContainerFilter, 0, len(*filtersMap))
+ for k, v := range *filtersMap {
generatedFunc, err := filters.GenerateContainerFilterFuncs(k, v, runtime)
if err != nil {
utils.InternalServerError(w, err)
diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go
index 01b9ec101..77269db8b 100644
--- a/pkg/api/handlers/libpod/containers.go
+++ b/pkg/api/handlers/libpod/containers.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/domain/infra/abi"
+ "github.com/containers/podman/v3/pkg/util"
"github.com/gorilla/schema"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -59,20 +60,21 @@ func ContainerExists(w http.ResponseWriter, r *http.Request) {
func ListContainers(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
- All bool `schema:"all"`
- External bool `schema:"external"`
- Filters map[string][]string `schema:"filters"`
- Last int `schema:"last"` // alias for limit
- Limit int `schema:"limit"`
- Namespace bool `schema:"namespace"`
- Size bool `schema:"size"`
- Sync bool `schema:"sync"`
+ All bool `schema:"all"`
+ External bool `schema:"external"`
+ Last int `schema:"last"` // alias for limit
+ Limit int `schema:"limit"`
+ Namespace bool `schema:"namespace"`
+ Size bool `schema:"size"`
+ Sync bool `schema:"sync"`
}{
// override any golang type defaults
}
- if err := decoder.Decode(&query, r.URL.Query()); err != nil {
- utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
+ filterMap, err := util.PrepareFilters(r)
+
+ if dErr := decoder.Decode(&query, r.URL.Query()); dErr != nil || err != nil {
+ utils.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError,
errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
@@ -94,7 +96,7 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
opts := entities.ContainerListOptions{
All: query.All,
External: query.External,
- Filters: query.Filters,
+ Filters: *filterMap,
Last: limit,
Namespace: query.Namespace,
// Always return Pod, should not be part of the API.
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 83fe23621..1f306a533 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -319,18 +319,6 @@ func ExportImages(w http.ResponseWriter, r *http.Request) {
func ImagesLoad(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
- decoder := r.Context().Value("decoder").(*schema.Decoder)
- query := struct {
- Reference string `schema:"reference"`
- }{
- // Add defaults here once needed.
- }
-
- if err := decoder.Decode(&query, r.URL.Query()); err != nil {
- utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
- errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
- return
- }
tmpfile, err := ioutil.TempFile("", "libpod-images-load.tar")
if err != nil {
@@ -338,14 +326,15 @@ func ImagesLoad(w http.ResponseWriter, r *http.Request) {
return
}
defer os.Remove(tmpfile.Name())
- defer tmpfile.Close()
- if _, err := io.Copy(tmpfile, r.Body); err != nil && err != io.EOF {
+ _, err = io.Copy(tmpfile, r.Body)
+ tmpfile.Close()
+
+ if err != nil && err != io.EOF {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to write archive to temporary file"))
return
}
- tmpfile.Close()
loadedImage, err := runtime.LoadImage(context.Background(), tmpfile.Name(), os.Stderr, "")
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to load image"))
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index 3d86e5d38..423766bd8 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -810,11 +810,14 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// summary: Load image
// description: Load an image (oci-archive or docker-archive) stream.
// parameters:
- // - in: formData
+ // - in: body
// name: upload
- // description: tarball of container image
- // type: file
// required: true
+ // description: tarball of container image
+ // schema:
+ // type: string
+ // consumes:
+ // - application/x-tar
// produces:
// - application/json
// responses:
diff --git a/pkg/specgen/generate/security.go b/pkg/specgen/generate/security.go
index 56aac8bfd..e0e4a47a4 100644
--- a/pkg/specgen/generate/security.go
+++ b/pkg/specgen/generate/security.go
@@ -89,12 +89,28 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator,
// NOTE: Must happen before SECCOMP
if s.Privileged {
g.SetupPrivileged(true)
- caplist = capabilities.AllCapabilities()
+ caplist, err = capabilities.BoundingSet()
+ if err != nil {
+ return err
+ }
} else {
- caplist, err = capabilities.MergeCapabilities(rtc.Containers.DefaultCapabilities, s.CapAdd, s.CapDrop)
+ mergedCaps, err := capabilities.MergeCapabilities(rtc.Containers.DefaultCapabilities, s.CapAdd, s.CapDrop)
+ if err != nil {
+ return err
+ }
+ boundingSet, err := capabilities.BoundingSet()
if err != nil {
return err
}
+ boundingCaps := make(map[string]interface{})
+ for _, b := range boundingSet {
+ boundingCaps[b] = b
+ }
+ for _, c := range mergedCaps {
+ if _, ok := boundingCaps[c]; ok {
+ caplist = append(caplist, c)
+ }
+ }
privCapsRequired := []string{}
@@ -139,10 +155,24 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator,
configSpec.Process.Capabilities.Permitted = caplist
configSpec.Process.Capabilities.Inheritable = caplist
} else {
- userCaps, err := capabilities.MergeCapabilities(nil, s.CapAdd, nil)
+ mergedCaps, err := capabilities.MergeCapabilities(nil, s.CapAdd, nil)
if err != nil {
return errors.Wrapf(err, "capabilities requested by user are not valid: %q", strings.Join(s.CapAdd, ","))
}
+ boundingSet, err := capabilities.BoundingSet()
+ if err != nil {
+ return err
+ }
+ boundingCaps := make(map[string]interface{})
+ for _, b := range boundingSet {
+ boundingCaps[b] = b
+ }
+ var userCaps []string
+ for _, c := range mergedCaps {
+ if _, ok := boundingCaps[c]; ok {
+ userCaps = append(userCaps, c)
+ }
+ }
configSpec.Process.Capabilities.Effective = userCaps
configSpec.Process.Capabilities.Permitted = userCaps
configSpec.Process.Capabilities.Inheritable = userCaps
diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at
index 478717700..9030f0095 100644
--- a/test/apiv2/20-containers.at
+++ b/test/apiv2/20-containers.at
@@ -280,6 +280,32 @@ t GET containers/json 200 \
podman stop bar
+#compat api list containers sanity checks
+t GET containers/json?filters='garb1age}' 500 \
+ .cause="invalid character 'g' looking for beginning of value"
+t GET containers/json?filters='{"label":["testl' 500 \
+ .cause="unexpected end of JSON input"
+
+#libpod api list containers sanity checks
+t GET libpod/containers/json?filters='garb1age}' 500 \
+ .cause="invalid character 'g' looking for beginning of value"
+t GET libpod/containers/json?filters='{"label":["testl' 500 \
+ .cause="unexpected end of JSON input"
+
+# Prune containers - bad filter input
+t POST containers/prune?filters='garb1age}' 500 \
+ .cause="invalid character 'g' looking for beginning of value"
+t POST libpod/containers/prune?filters='garb1age}' 500 \
+ .cause="invalid character 'g' looking for beginning of value"
+
+## Prune containers with illformed label
+t POST containers/prune?filters='{"label":["tes' 500 \
+ .cause="unexpected end of JSON input"
+t POST libpod/containers/prune?filters='{"label":["tes' 500 \
+ .cause="unexpected end of JSON input"
+
+t GET libpod/containers/json?filters='{"label":["testlabel"]}' 200 length=0
+
# Test CPU limit (NanoCPUs)
t POST containers/create Image=$IMAGE HostConfig='{"NanoCpus":500000}' 201 \
.Id~[0-9a-f]\\{64\\}
diff --git a/test/buildah-bud/README.md b/test/buildah-bud/README.md
new file mode 100644
index 000000000..88e4bbc3c
--- /dev/null
+++ b/test/buildah-bud/README.md
@@ -0,0 +1,82 @@
+buildah-bud tests under podman
+==============================
+
+This directory contains tools for running 'buildah bud' tests
+under podman. The key concept of the workflow is:
+
+* Pull buildah @ version specified in go.mod
+* Apply a small set of patches to buildah's tests directory, such that
+ * BATS will use 'podman build' instead of 'buildah bud'; and
+ * some not-applicable-under-podman tests are skipped
+
+It's a teeny bit more complicated than that, but that's really most of
+what you need to know for most purposes. The tests run in podman CI,
+and for the most part are expected to just pass.
+
+Troubleshooting
+---------------
+
+If you're reading this, it's probably because something went wrong.
+At the time of this writing (March 2021, initial commit) it is
+impossible to foresee what typical failures will look like, but
+my prediction is that they will fit one of two categories:
+
+* Failure when vendoring new buildah (e.g., by dependabot)
+* Other failure
+
+Let's examine those in reverse order:
+
+Failure when not vendoring
+--------------------------
+
+Aside from flakes, my only guess here is that you broke 'podman build'.
+If this is the case, it is very likely that you are aware of what you
+did; and if this is the case, your change likely falls into one of
+these two categories:
+
+* "OOPS! I didn't mean to break that". Solution: fix it!
+* "Uh, yeah, this is deliberate, and we choose to be incompatible with buildah". In this case, you'll need to skip or edit the failing test(s); see below.
+
+If neither of those is the case, then I'm sorry, you're on your own.
+When you figure it out, please remember to update these instructions.
+
+
+Failure when vendoring new buildah
+----------------------------------
+
+This is what I predict will be the usual case; and I predict that
+failures will fall into one of two bins:
+
+* failure to apply the patch
+* failure because there are new buildah tests for functionality not in podman
+
+In either case, the process for solving is the same:
+
+* Start with a checked-out podman tree with the failing PR applied
+* run `./test/buildah-bud/run-buildah-bud-tests`
+
+Presumably, something will fail here. Whatever the failure, your next step is:
+
+* `cd test-buildah-v<TAB>` (this is a new directory created by the script)
+
+If the failure was in `git am`, solve it (left as exercise for the reader).
+
+If the failure was in tests run, solve it (either by adding `skip`s to
+failing tests in bud.bats, or less preferably, by making other tweaks
+to the test code).
+
+You now have modified files. THOSE SHOULD ONLY BE test/bud.bats or
+test/helpers.bash! If you changed any other file, that is a sign that
+something is very wrong!
+
+Commit your changes: `git commit --all --amend`
+
+Push those changes to the podman repo: `./make-new-buildah-diffs`
+
+cd back up to the podman repo
+
+As necessary, rerun `run-buildah-bud-tests`. You can use `--no-checkout`
+to run tests immediately, without rerunning the git checkout.
+
+If you're happy with the diffs, `git add` the modified `.diff` file
+and submit it as part of your PR.
diff --git a/test/buildah-bud/buildah-tests.diff b/test/buildah-bud/buildah-tests.diff
new file mode 100644
index 000000000..92adabcac
--- /dev/null
+++ b/test/buildah-bud/buildah-tests.diff
@@ -0,0 +1,192 @@
+From c85882a8f7fb6efbf4d59dfe8340bfbef57ccd48 Mon Sep 17 00:00:00 2001
+From: Ed Santiago <santiago@redhat.com>
+Date: Tue, 9 Feb 2021 17:28:05 -0700
+Subject: [PATCH] tweaks for running buildah tests under podman
+
+Signed-off-by: Ed Santiago <santiago@redhat.com>
+---
+ tests/bud.bats | 26 ++++++++++++++++----------
+ tests/helpers.bash | 28 ++++++++++++++++++++++++----
+ 2 files changed, 40 insertions(+), 14 deletions(-)
+
+diff --git a/tests/bud.bats b/tests/bud.bats
+index 1efc3c58..9a39d594 100644
+--- a/tests/bud.bats
++++ b/tests/bud.bats
+@@ -4,7 +4,7 @@ load helpers
+
+ @test "bud with a path to a Dockerfile (-f) containing a non-directory entry" {
+ run_buildah 125 bud -f ${TESTSDIR}/bud/non-directory-in-path/non-directory/Dockerfile
+- expect_output --substring "non-directory/Dockerfile: not a directory"
++ expect_output --substring "Error: context must be a directory:"
+ }
+
+ @test "bud with --dns* flags" {
+@@ -95,6 +95,7 @@ symlink(subdir)"
+ }
+
+ @test "bud-flags-order-verification" {
++ skip "N/A under podman"
+ run_buildah 125 bud /tmp/tmpdockerfile/ -t blabla
+ check_options_flag_err "-t"
+
+@@ -1324,13 +1325,13 @@ function _test_http() {
+ @test "bud with dir for file but no Dockerfile in dir" {
+ target=alpine-image
+ run_buildah 125 bud --signature-policy ${TESTSDIR}/policy.json -t ${target} -f ${TESTSDIR}/bud/empty-dir ${TESTSDIR}/bud/empty-dir
+- expect_output --substring "no such file or directory"
++ expect_output --substring "Error: context must be a directory:"
+ }
+
+ @test "bud with bad dir Dockerfile" {
+ target=alpine-image
+ run_buildah 125 bud --signature-policy ${TESTSDIR}/policy.json -t ${target} -f ${TESTSDIR}/baddirname ${TESTSDIR}/baddirname
+- expect_output --substring "no such file or directory"
++ expect_output --substring "Error: context must be a directory:"
+ }
+
+ @test "bud with ARG before FROM default value" {
+@@ -1742,7 +1743,9 @@ _EOF
+ run_buildah bud --signature-policy ${TESTSDIR}/policy.json --layers -t test-img-2 --build-arg TEST=foo -f Dockerfile4 ${TESTSDIR}/bud/build-arg
+ run_buildah inspect -f '{{.FromImageID}}' test-img-2
+ argsid="$output"
+- [[ "$argsid" != "$initialid" ]]
++ if [[ "$argsid" == "$initialid" ]]; then
++ die ".FromImageID of test-img-2 ($argsid) == same as test-img, it should be different"
++ fi
+
+ # Set the build-arg via an ENV in the local environment and verify that the cached layers are not used
+ export TEST=bar
+@@ -1795,6 +1798,7 @@ _EOF
+ }
+
+ @test "bud without any arguments should succeed" {
++ skip "does not work under podman"
+ cd ${TESTSDIR}/bud/from-scratch
+ run_buildah bud --signature-policy ${TESTSDIR}/policy.json
+ }
+@@ -1802,7 +1806,7 @@ _EOF
+ @test "bud without any arguments should fail when no Dockerfile exist" {
+ cd $(mktemp -d)
+ run_buildah 125 bud --signature-policy ${TESTSDIR}/policy.json
+- expect_output --substring "no such file or directory"
++ expect_output "Error: no context directory and no Containerfile specified"
+ }
+
+ @test "bud with specified context should fail if directory contains no Dockerfile" {
+@@ -1815,16 +1819,17 @@ _EOF
+ DIR=$(mktemp -d)
+ mkdir -p "$DIR"/Dockerfile
+ run_buildah 125 bud --signature-policy ${TESTSDIR}/policy.json "$DIR"
+- expect_output --substring "is not a file"
++ expect_output --substring "Error: open .*: no such file or directory"
+ }
+
+ @test "bud with specified context should fail if context contains not-existing Dockerfile" {
+ DIR=$(mktemp -d)
+ run_buildah 125 bud --signature-policy ${TESTSDIR}/policy.json "$DIR"/Dockerfile
+- expect_output --substring "no such file or directory"
++ expect_output --substring "context must be a directory"
+ }
+
+ @test "bud with specified context should succeed if context contains existing Dockerfile" {
++ skip "podman requires a directory, not a Dockerfile"
+ DIR=$(mktemp -d)
+ echo "FROM alpine" > "$DIR"/Dockerfile
+ run_buildah 0 bud --signature-policy ${TESTSDIR}/policy.json "$DIR"/Dockerfile
+@@ -1876,7 +1881,7 @@ _EOF
+
+ @test "bud-squash-hardlinks" {
+ _prefetch busybox
+- run_buildah bud --signature-policy ${TESTSDIR}/policy.json --squash ${TESTSDIR}/bud/layers-squash/Dockerfile.hardlinks
++ run_buildah bud --signature-policy ${TESTSDIR}/policy.json --squash -f Dockerfile.hardlinks ${TESTSDIR}/bud/layers-squash
+ }
+
+ @test "bud with additional directory of devices" {
+@@ -2023,6 +2028,7 @@ _EOF
+ }
+
+ @test "bud pull never" {
++ skip "FIXME: podman issue #9573"
+ target=pull
+ run_buildah 125 bud --signature-policy ${TESTSDIR}/policy.json -t ${target} --pull-never ${TESTSDIR}/bud/pull
+ expect_output --substring "pull policy is \"never\" but \""
+@@ -2042,6 +2048,7 @@ _EOF
+ }
+
+ @test "bud with Containerfile should fail with nonexistent authfile" {
++ skip "FIXME: podman issue #9572"
+ target=alpine-image
+ run_buildah 125 bud --authfile /tmp/nonexistent --signature-policy ${TESTSDIR}/policy.json -t ${target} ${TESTSDIR}/bud/containerfile
+ }
+@@ -2169,6 +2176,7 @@ EOM
+ }
+
+ @test "bud with encrypted FROM image" {
++ skip "Too much effort to spin up a local registry"
+ _prefetch busybox
+ mkdir ${TESTDIR}/tmp
+ openssl genrsa -out ${TESTDIR}/tmp/mykey.pem 1024
+@@ -2241,8 +2249,6 @@ EOM
+ _prefetch alpine
+ run_buildah bud --timestamp=0 --quiet --pull=false --signature-policy ${TESTSDIR}/policy.json -t timestamp -f Dockerfile.1 ${TESTSDIR}/bud/cache-stages
+ cid=$output
+- run_buildah inspect --format '{{ .Docker.Created }}' timestamp
+- expect_output --substring "1970-01-01"
+ run_buildah inspect --format '{{ .OCIv1.Created }}' timestamp
+ expect_output --substring "1970-01-01"
+ run_buildah inspect --format '{{ .History }}' timestamp
+diff --git a/tests/helpers.bash b/tests/helpers.bash
+index 5623a0e7..9683360f 100644
+--- a/tests/helpers.bash
++++ b/tests/helpers.bash
+@@ -70,7 +70,7 @@ function _prefetch() {
+ mkdir -p ${_BUILDAH_IMAGE_CACHEDIR}
+ fi
+
+- local _podman_opts="--root ${TESTDIR}/root --storage-driver ${STORAGE_DRIVER}"
++ local _podman_opts="--root ${TESTDIR}/root --runroot ${TESTDIR}/runroot --storage-driver ${STORAGE_DRIVER}"
+
+ for img in "$@"; do
+ echo "# [checking for: $img]" >&2
+@@ -138,15 +138,35 @@ function run_buildah() {
+ --retry) retry=3; shift;; # retry network flakes
+ esac
+
++ local podman_or_buildah=${BUILDAH_BINARY}
++ if [[ $1 == "bud" || $1 == "build-using-dockerfile" ]]; then
++ shift
++ # podman defaults to --layers=true; buildah to --false.
++ # If command line includes explicit --layers, leave it untouched,
++ # but otherwise update command line so podman mimics buildah default.
++ if [[ "$*" =~ --layers || "$*" =~ --squash ]]; then
++ set "build" "--force-rm=false" "$@"
++ else
++ set "build" "--force-rm=false" "--layers=false" "$@"
++ fi
++ podman_or_buildah=${PODMAN_BINARY}
++
++ # podman always exits 125 where buildah exits 1 or 2
++ case $expected_rc in
++ 1|2) expected_rc=125 ;;
++ esac
++ fi
++ local cmd_basename=$(basename ${podman_or_buildah})
++
+ # Remember command args, for possible use in later diagnostic messages
+- MOST_RECENT_BUILDAH_COMMAND="buildah $*"
++ MOST_RECENT_BUILDAH_COMMAND="$cmd_basename $*"
+
+ while [ $retry -gt 0 ]; do
+ retry=$(( retry - 1 ))
+
+ # stdout is only emitted upon error; this echo is to help a debugger
+- echo "\$ $BUILDAH_BINARY $*"
+- run timeout --foreground --kill=10 $BUILDAH_TIMEOUT ${BUILDAH_BINARY} --registries-conf ${TESTSDIR}/registries.conf --root ${TESTDIR}/root --runroot ${TESTDIR}/runroot --storage-driver ${STORAGE_DRIVER} "$@"
++ echo "\$ $cmd_basename $*"
++ run timeout --foreground --kill=10 $BUILDAH_TIMEOUT ${podman_or_buildah} --registries-conf ${TESTSDIR}/registries.conf --root ${TESTDIR}/root --runroot ${TESTDIR}/runroot --storage-driver ${STORAGE_DRIVER} "$@"
+ # without "quotes", multiple lines are glommed together into one
+ if [ -n "$output" ]; then
+ echo "$output"
+--
+2.30.2
diff --git a/test/buildah-bud/make-new-buildah-diffs b/test/buildah-bud/make-new-buildah-diffs
new file mode 100644
index 000000000..1191f4597
--- /dev/null
+++ b/test/buildah-bud/make-new-buildah-diffs
@@ -0,0 +1,63 @@
+#!/bin/bash
+#
+# This script is intended to help developers get buildah-tests-under-podman
+# working again in case of failure.
+#
+ME=$(basename $0)
+
+die() {
+ echo "$ME: $*" >&2
+ exit 1
+}
+
+# Confirm that we're in a test-buildah* subdir of podman
+whereami=$(basename $(pwd))
+if [[ ! $whereami =~ test-buildah-v ]]; then
+ die "Please run me while cd'ed to a test-buildah-vN.M directory"
+fi
+
+# FIXME: check that git repo is buildah
+git remote -v | grep -q [BUILDAHREPO] \
+ || die "This does not look like a buildah repo (git remote -v)"
+
+# We could do the commit automatically, but it's prudent to require human
+# involvement.
+modified=$(git status --untracked=no --porcelain)
+if [[ -n "$modified" ]]; then
+ echo $modified
+ die "Please commit your changes: git commit --amend --all"
+fi
+
+# Remove any 00??-*.patch files
+rm -f 0001-*.patch
+
+# Check count of commits, barf if need to squash
+n_commits=$(git log --pretty=format:%h [BASETAG]..HEAD | wc -l)
+if [[ $n_commits -gt 1 ]]; then
+ die "Please squash your commits"
+fi
+
+# Scope check: make sure the only files changed are under tests/
+changes=$(git diff --name-status [BASETAG]..HEAD | egrep -v '\stests/')
+if [[ -n "$changes" ]]; then
+ echo $changes
+ die "Found modified files other than under 'tests/'"
+fi
+
+###############################################################################
+# All right - things look good. Generate the patch, and copy it into place.
+
+git format-patch [BASETAG]
+
+# Once again, make sure there's exactly one and only one commit
+shopt -s nullglob
+patch2=$(echo 0002-*.patch)
+if [[ -n "$patch2" ]]; then
+ die "Internal error: I thought I checked for squashed commits, but still see $patch2"
+fi
+
+# All looks good. Now write that patch into its proper place in the
+# podman repo. The sed and tac mess strips trailing whitespace and
+# empty lines; we need to do this to pass github CI checks.
+sed -e 's/ \+$//' <0001-*.patch |\
+ tac | sed -e '/./,$!d' | tac >| ../test/buildah-bud/buildah-tests.diff
diff --git a/test/buildah-bud/run-buildah-bud-tests b/test/buildah-bud/run-buildah-bud-tests
new file mode 100755
index 000000000..67c8fdfa4
--- /dev/null
+++ b/test/buildah-bud/run-buildah-bud-tests
@@ -0,0 +1,166 @@
+#!/bin/bash
+
+ME=$(basename $0)
+
+###############################################################################
+# BEGIN user-customizable section
+
+# Buildah main repository; unlikely to change often
+BUILDAH_REPO=github.com/containers/buildah
+
+# Tag name used to identify the base checkout
+BASE_TAG=buildah-bud-in-podman
+
+# END user-customizable section
+###############################################################################
+
+usage="Usage: $ME [--help] [--no-checkout] [--no-test]
+"
+
+# Parse command-line options (used in development only, not in CI)
+do_checkout=y
+do_test=y
+for i; do
+ case "$i" in
+ --no-checkout) do_checkout= ; shift;;
+ --no-test) do_test= ; shift;;
+ -h|--help) echo "$usage"; exit 0;;
+ *) echo "$ME: Unrecognized option '$i'" >&2; exit 1;;
+ esac
+done
+
+# Patches helpers.bash and potentially other files (bud.bats? Dockerfiles?)
+#
+# The patch file is horrible to generate:
+# 1) cd to the checked-out buildah/tests directory
+# 2) make your edits
+# 3) git commit -asm 'blah blah blah'
+# 3a) if checked-out directory already includes earlier patches,
+# you may need to 'git commit --amend' instead
+# 4) git format-patch HEAD^
+# 5) sed -e 's/ \+$//' 0001* >../PATCH-FILE-PATH
+# 6) vim that file, remove trailing empty newlines
+# 7) cd back out of buildah directory, and git-commit this new patch file
+#
+# FIXME: this makes me nervous. The diff will probably need tweaking
+# over time. I don't think we need to version it, because we
+# *have* to be in lockstep with a specific buildah version,
+# so problems should only arise when we re-vendor.
+# But I'm still nervous and can't put my finger on the reason.
+#
+# Complicated invocation needed because we 'cd' down below.
+BUD_TEST_DIR=$(realpath $(dirname ${BASH_SOURCE[0]}))
+PATCHES=${BUD_TEST_DIR}/buildah-tests.diff
+
+# Friendlier relative path to our buildah-tests dir
+BUD_TEST_DIR_REL=$(dirname $(git ls-files --full-name ${BASH_SOURCE[0]}))
+# Path to podman binary; again, do it before we cd
+PODMAN_BINARY=$(pwd)/bin/podman
+REMOTE=
+# If remote, start server & change path
+if [[ "${PODBIN_NAME:-}" = "remote" ]]; then
+ REMOTE=1
+ echo "$ME: remote tests are not working yet" >&2
+ exit 1
+fi
+
+function die() {
+ failhint=
+ echo "$ME: $*" >&2
+ exit 1
+}
+
+# From here on out, any unexpected abort will try to offer helpful hints
+failhint=
+trap 'if [[ $? != 0 ]]; then if [[ -n $failhint ]]; then echo;echo "***************************************";echo $failhint;echo;echo "Please see $BUD_TEST_DIR_REL/README.md for advice";fi;fi' 0
+
+# Find the version of buildah we've vendored in, so we can run the right tests
+buildah_version=$(awk "\$1 == \"$BUILDAH_REPO\" { print \$2 }" <go.mod)
+
+if [[ -z "$buildah_version" ]]; then
+ # This should not happen
+ die "Did not find '$BUILDAH_REPO' in go.mod"
+fi
+
+# From here on out, any error is fatal
+set -e
+
+# Before pulling buildah (while still cd'ed to podman repo), try to determine
+# if this is a PR, and if so if it's a revendoring of buildah. We use this to
+# try to offer a helpful hint on failure.
+is_revendor=
+if [[ -n $CIRRUS_CHANGE_IN_REPO ]]; then
+ if [[ -n $DEST_BRANCH ]]; then
+ head=${CIRRUS_CHANGE_IN_REPO}
+ # Base of this PR.
+ base=$(set -x;git merge-base ${DEST_BRANCH} $head)
+ changes=$(set -x;git diff --name-status $base $head)
+ if [[ -n $changes ]]; then
+ if [[ $changes =~ vendor/$BUILDAH_REPO ]]; then
+ is_revendor=y
+ fi
+ fi
+ fi
+fi
+
+# Pull buildah, including tests
+buildah_dir=test-buildah-$buildah_version
+if [[ -n $do_checkout ]]; then
+ if [[ -d $buildah_dir ]]; then
+ die "Directory already exists: $buildah_dir"
+ fi
+
+ failhint="'git clone' failed - this should never happen!"
+ (set -x;git clone -q --branch $buildah_version https://$BUILDAH_REPO $buildah_dir)
+
+ cd $buildah_dir
+
+ # Give it a recognizable tag; this will be useful if we need to update
+ # the set of patches
+ (set -x;git tag $BASE_TAG)
+
+ # Build buildah
+ failhint="error building buildah. This should never happen."
+ (set -x;make bin/buildah)
+
+ # Apply custom patches. We do this _after_ building, although it shouldn't
+ # matter because these patches should only apply to test scripts.
+ failhint="
+Error applying patch file. This can happen when you vendor in a new buildah."
+ (set -x;git am <$PATCHES)
+
+ failhint=
+ sed -e "s,\[BASETAG\],${BASE_TAG},g" \
+ -e "s,\[BUILDAHREPO\],${BUILDAH_REPO},g" \
+ < ${BUD_TEST_DIR}/make-new-buildah-diffs \
+ > make-new-buildah-diffs
+ chmod 755 make-new-buildah-diffs
+else
+ # Called with --no-checkout
+ test -d $buildah_dir || die "Called with --no-checkout, but $buildah_dir does not exist"
+
+ cd $buildah_dir
+fi
+
+if [[ -n $do_test ]]; then
+ failhint="Error running buildah bud tests under podman."
+ if [[ -n $is_revendor ]]; then
+ failhint+="
+
+It looks like you're vendoring in a new buildah. The likely failure
+here is that there's a new test in bud.bats that uses functionality
+not (yet) in podman build. You will likely need to 'skip' that test.
+"
+ else
+ failhint+="
+
+Is it possible that your PR breaks podman build in some way? Please
+review the test failure and double-check your changes.
+"
+ fi
+
+ (set -x;sudo env TMPDIR=/var/tmp \
+ PODMAN_BINARY=$PODMAN_BINARY \
+ BUILDAH_BINARY=$(pwd)/bin/buildah \
+ bats tests/bud.bats)
+fi
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 4e5106731..bb1f9590d 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -1412,7 +1412,28 @@ USER mail`
})
It("podman run --tz", func() {
- session := podmanTest.Podman([]string{"run", "--tz", "foo", "--rm", ALPINE, "date"})
+ testDir := filepath.Join(podmanTest.RunRoot, "tz-test")
+ err := os.MkdirAll(testDir, 0755)
+ Expect(err).To(BeNil())
+
+ tzFile := filepath.Join(testDir, "tzfile.txt")
+ file, err := os.Create(tzFile)
+ Expect(err).To(BeNil())
+
+ _, err = file.WriteString("Hello")
+ Expect(err).To(BeNil())
+ file.Close()
+
+ badTZFile := fmt.Sprintf("../../../%s", tzFile)
+ session := podmanTest.Podman([]string{"run", "--tz", badTZFile, "--rm", ALPINE, "date"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Not(Equal(0)))
+ Expect(session.ErrorToString()).To(ContainSubstring("error finding timezone for container"))
+
+ err = os.Remove(tzFile)
+ Expect(err).To(BeNil())
+
+ session = podmanTest.Podman([]string{"run", "--tz", "foo", "--rm", ALPINE, "date"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Not(Equal(0)))
diff --git a/test/python/docker/compat/test_images.py b/test/python/docker/compat/test_images.py
index 4a90069a9..571b31881 100644
--- a/test/python/docker/compat/test_images.py
+++ b/test/python/docker/compat/test_images.py
@@ -1,4 +1,5 @@
import collections
+import io
import os
import subprocess
import sys
@@ -6,6 +7,7 @@ import time
import unittest
from docker import DockerClient, errors
+from docker.errors import APIError
from test.python.docker import Podman
from test.python.docker.compat import common, constant
@@ -79,9 +81,7 @@ class TestImages(unittest.TestCase):
self.assertEqual(len(self.client.images.list()), 2)
# List images with filter
- self.assertEqual(
- len(self.client.images.list(filters={"reference": "alpine"})), 1
- )
+ self.assertEqual(len(self.client.images.list(filters={"reference": "alpine"})), 1)
def test_search_image(self):
"""Search for image"""
@@ -149,15 +149,22 @@ class TestImages(unittest.TestCase):
self.assertEqual(len(self.client.images.list()), 2)
+ def test_load_corrupt_image(self):
+ """Import|Load Image failure"""
+ tarball = io.BytesIO("This is a corrupt tarball".encode("utf-8"))
+ with self.assertRaises(APIError):
+ self.client.images.load(tarball)
+
def test_build_image(self):
labels = {"apple": "red", "grape": "green"}
- _ = self.client.images.build(path="test/python/docker/build_labels", labels=labels, tag="labels")
+ _ = self.client.images.build(
+ path="test/python/docker/build_labels", labels=labels, tag="labels"
+ )
image = self.client.images.get("labels")
self.assertEqual(image.labels["apple"], labels["apple"])
self.assertEqual(image.labels["grape"], labels["grape"])
-
if __name__ == "__main__":
# Setup temporary space
unittest.main()
diff --git a/test/system/120-load.bats b/test/system/120-load.bats
index 95113c4a6..d29be462d 100644
--- a/test/system/120-load.bats
+++ b/test/system/120-load.bats
@@ -32,7 +32,7 @@ verify_iid_and_name() {
echo "I am an invalid file and should cause a podman-load error" > $invalid
run_podman 125 load -i $invalid
# podman and podman-remote emit different messages; this is a common string
- is "$output" ".*error pulling image: unable to pull .*" \
+ is "$output" ".*payload does not match any of the supported image formats .*" \
"load -i INVALID fails with expected diagnostic"
}
@@ -137,6 +137,13 @@ verify_iid_and_name() {
"Diagnostic from 'podman load' without redirection or -i"
}
+@test "podman load - redirect corrupt payload" {
+ run_podman 125 load <<< "Danger, Will Robinson!! This is a corrupt tarball!"
+ is "$output" \
+ ".*payload does not match any of the supported image formats .*" \
+ "Diagnostic from 'podman load' unknown/corrupt payload"
+}
+
@test "podman load - multi-image archive" {
img1="quay.io/libpod/testimage:00000000"
img2="quay.io/libpod/testimage:20200902"
diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats
index 51835e4a3..c65449212 100644
--- a/test/system/200-pod.bats
+++ b/test/system/200-pod.bats
@@ -18,10 +18,6 @@ function teardown() {
@test "podman pod top - containers in different PID namespaces" {
- if is_remote && is_rootless; then
- skip "FIXME: pending #7139"
- fi
-
# With infra=false, we don't get a /pause container (we also
# don't pull k8s.gcr.io/pause )
no_infra='--infra=false'
@@ -55,10 +51,6 @@ function teardown() {
@test "podman pod - communicating between pods" {
- if is_remote && is_rootless; then
- skip "FIXME: pending #7139"
- fi
-
podname=pod$(random_string)
run_podman 1 pod exists $podname
run_podman pod create --infra=true --name=$podname
@@ -117,10 +109,6 @@ function teardown() {
}
@test "podman pod - communicating via /dev/shm " {
- if is_remote && is_rootless; then
- skip "FIXME: pending #7139"
- fi
-
podname=pod$(random_string)
run_podman 1 pod exists $podname
run_podman pod create --infra=true --name=$podname
@@ -168,10 +156,6 @@ function random_ip() {
}
@test "podman pod create - hashtag AllTheOptions" {
- if is_remote && is_rootless; then
- skip "FIXME: pending #7139"
- fi
-
mac=$(random_mac)
add_host_ip=$(random_ip)
add_host_n=$(random_string | tr A-Z a-z).$(random_string | tr A-Z a-z).xyz
diff --git a/test/system/220-healthcheck.bats b/test/system/220-healthcheck.bats
index 3405029c1..f929c6770 100644
--- a/test/system/220-healthcheck.bats
+++ b/test/system/220-healthcheck.bats
@@ -25,8 +25,6 @@ function _check_health {
@test "podman healthcheck" {
- skip_if_remote "FIXME: pending #7137"
-
# Create an image with a healthcheck script; said script will
# pass until the file /uh-oh gets created (by us, via exec)
cat >${PODMAN_TMPDIR}/healthcheck <<EOF
diff --git a/test/system/410-selinux.bats b/test/system/410-selinux.bats
index 49743ff33..4a2c7b7a4 100644
--- a/test/system/410-selinux.bats
+++ b/test/system/410-selinux.bats
@@ -61,9 +61,6 @@ function check_label() {
# SELinux not enabled on Ubuntu, so we should never get here
die "WHOA! SELinux enabled, but no /usr/bin/rpm!"
fi
- if [[ "$cs_version" < "2.146" ]]; then
- skip "FIXME: #7939: requires container-selinux-2.146.0 (currently installed: $cs_version)"
- fi
fi
# FIXME FIXME FIXME: delete up to here, leaving just check_label
diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats
index 0d976a6af..4868ad6a0 100644
--- a/test/system/500-networking.bats
+++ b/test/system/500-networking.bats
@@ -97,7 +97,6 @@ load helpers
# "network create" now works rootless, with the help of a special container
@test "podman network create" {
- skip_if_remote "FIXME: pending #7808"
myport=54322
local mynetname=testnet-$(random_string 10)
diff --git a/vendor/github.com/containers/common/pkg/auth/auth.go b/vendor/github.com/containers/common/pkg/auth/auth.go
index 8daaf4c08..88028d9f8 100644
--- a/vendor/github.com/containers/common/pkg/auth/auth.go
+++ b/vendor/github.com/containers/common/pkg/auth/auth.go
@@ -22,9 +22,7 @@ import (
func GetDefaultAuthFile() string {
authfile := os.Getenv("REGISTRY_AUTH_FILE")
if authfile == "" {
- if authfile, ok := os.LookupEnv("DOCKER_CONFIG"); ok {
- logrus.Infof("Using DOCKER_CONFIG environment variable for authfile path %s", authfile)
- }
+ authfile = os.Getenv("DOCKER_CONFIG")
}
return authfile
}
diff --git a/vendor/github.com/containers/common/pkg/capabilities/capabilities.go b/vendor/github.com/containers/common/pkg/capabilities/capabilities.go
index ddfa53be8..78be4d158 100644
--- a/vendor/github.com/containers/common/pkg/capabilities/capabilities.go
+++ b/vendor/github.com/containers/common/pkg/capabilities/capabilities.go
@@ -16,6 +16,9 @@ var (
// Used internally and populated during init().
capabilityList []string
+ // Used internally and populated during init().
+ capsList []capability.Cap
+
// ErrUnknownCapability is thrown when an unknown capability is processed.
ErrUnknownCapability = errors.New("unknown capability")
@@ -28,6 +31,10 @@ var (
// Useful on the CLI for `--cap-add=all` etc.
const All = "ALL"
+func getCapName(c capability.Cap) string {
+ return "CAP_" + strings.ToUpper(c.String())
+}
+
func init() {
last := capability.CAP_LAST_CAP
// hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap
@@ -38,7 +45,8 @@ func init() {
if cap > last {
continue
}
- capabilityList = append(capabilityList, "CAP_"+strings.ToUpper(cap.String()))
+ capsList = append(capsList, cap)
+ capabilityList = append(capabilityList, getCapName(cap))
}
}
@@ -52,6 +60,26 @@ func stringInSlice(s string, sl []string) bool {
return false
}
+// BoundingSet returns the capabilities in the current bounding set
+func BoundingSet() ([]string, error) {
+ currentCaps, err := capability.NewPid2(0)
+ if err != nil {
+ return nil, err
+ }
+ err = currentCaps.Load()
+ if err != nil {
+ return nil, err
+ }
+ var r []string
+ for _, c := range capsList {
+ if !currentCaps.Get(capability.BOUNDING, c) {
+ continue
+ }
+ r = append(r, getCapName(c))
+ }
+ return r, nil
+}
+
// AllCapabilities returns all known capabilities.
func AllCapabilities() []string {
return capabilityList
diff --git a/vendor/github.com/containers/common/pkg/chown/chown.go b/vendor/github.com/containers/common/pkg/chown/chown.go
index fe794304e..fb7d67f33 100644
--- a/vendor/github.com/containers/common/pkg/chown/chown.go
+++ b/vendor/github.com/containers/common/pkg/chown/chown.go
@@ -4,10 +4,8 @@ import (
"os"
"os/user"
"path/filepath"
- "syscall"
"github.com/containers/storage/pkg/homedir"
- "github.com/pkg/errors"
)
// DangerousHostPath validates if a host path is dangerous and should not be modified
@@ -65,58 +63,3 @@ func DangerousHostPath(path string) (bool, error) {
return false, nil
}
-
-// ChangeHostPathOwnership changes the uid and gid ownership of a directory or file within the host.
-// This is used by the volume U flag to change source volumes ownership
-func ChangeHostPathOwnership(path string, recursive bool, uid, gid int) error {
- // Validate if host path can be chowned
- isDangerous, err := DangerousHostPath(path)
- if err != nil {
- return errors.Wrapf(err, "failed to validate if host path is dangerous")
- }
-
- if isDangerous {
- return errors.Errorf("chowning host path %q is not allowed. You can manually `chown -R %d:%d %s`", path, uid, gid, path)
- }
-
- // Chown host path
- if recursive {
- err := filepath.Walk(path, func(filePath string, f os.FileInfo, err error) error {
- if err != nil {
- return err
- }
-
- // Get current ownership
- currentUID := int(f.Sys().(*syscall.Stat_t).Uid)
- currentGID := int(f.Sys().(*syscall.Stat_t).Gid)
-
- if uid != currentUID || gid != currentGID {
- return os.Lchown(filePath, uid, gid)
- }
-
- return nil
- })
-
- if err != nil {
- return errors.Wrapf(err, "failed to chown recursively host path")
- }
- } else {
- // Get host path info
- f, err := os.Lstat(path)
- if err != nil {
- return errors.Wrapf(err, "failed to get host path information")
- }
-
- // Get current ownership
- currentUID := int(f.Sys().(*syscall.Stat_t).Uid)
- currentGID := int(f.Sys().(*syscall.Stat_t).Gid)
-
- if uid != currentUID || gid != currentGID {
- if err := os.Lchown(path, uid, gid); err != nil {
- return errors.Wrapf(err, "failed to chown host path")
- }
- }
- }
-
- return nil
-}
diff --git a/vendor/github.com/containers/common/pkg/chown/chown_unix.go b/vendor/github.com/containers/common/pkg/chown/chown_unix.go
new file mode 100644
index 000000000..82342f6af
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/chown/chown_unix.go
@@ -0,0 +1,66 @@
+// +build !windows
+
+package chown
+
+import (
+ "os"
+ "path/filepath"
+ "syscall"
+
+ "github.com/pkg/errors"
+)
+
+// ChangeHostPathOwnership changes the uid and gid ownership of a directory or file within the host.
+// This is used by the volume U flag to change source volumes ownership
+func ChangeHostPathOwnership(path string, recursive bool, uid, gid int) error {
+ // Validate if host path can be chowned
+ isDangerous, err := DangerousHostPath(path)
+ if err != nil {
+ return errors.Wrapf(err, "failed to validate if host path is dangerous")
+ }
+
+ if isDangerous {
+ return errors.Errorf("chowning host path %q is not allowed. You can manually `chown -R %d:%d %s`", path, uid, gid, path)
+ }
+
+ // Chown host path
+ if recursive {
+ err := filepath.Walk(path, func(filePath string, f os.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+
+ // Get current ownership
+ currentUID := int(f.Sys().(*syscall.Stat_t).Uid)
+ currentGID := int(f.Sys().(*syscall.Stat_t).Gid)
+
+ if uid != currentUID || gid != currentGID {
+ return os.Lchown(filePath, uid, gid)
+ }
+
+ return nil
+ })
+
+ if err != nil {
+ return errors.Wrapf(err, "failed to chown recursively host path")
+ }
+ } else {
+ // Get host path info
+ f, err := os.Lstat(path)
+ if err != nil {
+ return errors.Wrapf(err, "failed to get host path information")
+ }
+
+ // Get current ownership
+ currentUID := int(f.Sys().(*syscall.Stat_t).Uid)
+ currentGID := int(f.Sys().(*syscall.Stat_t).Gid)
+
+ if uid != currentUID || gid != currentGID {
+ if err := os.Lchown(path, uid, gid); err != nil {
+ return errors.Wrapf(err, "failed to chown host path")
+ }
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/containers/common/pkg/chown/chown_windows.go b/vendor/github.com/containers/common/pkg/chown/chown_windows.go
new file mode 100644
index 000000000..ad6039a90
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/chown/chown_windows.go
@@ -0,0 +1,11 @@
+package chown
+
+import (
+ "github.com/pkg/errors"
+)
+
+// ChangeHostPathOwnership changes the uid and gid ownership of a directory or file within the host.
+// This is used by the volume U flag to change source volumes ownership
+func ChangeHostPathOwnership(path string, recursive bool, uid, gid int) error {
+ return errors.Errorf("windows not supported")
+}
diff --git a/vendor/github.com/containers/common/pkg/completion/completion.go b/vendor/github.com/containers/common/pkg/completion/completion.go
index 90fe2f111..c90bf540b 100644
--- a/vendor/github.com/containers/common/pkg/completion/completion.go
+++ b/vendor/github.com/containers/common/pkg/completion/completion.go
@@ -139,3 +139,17 @@ func AutocompleteOS(cmd *cobra.Command, args []string, toComplete string) ([]str
completions := []string{"linux", "windows"}
return completions, cobra.ShellCompDirectiveNoFileComp
}
+
+// AutocompleteJSONFormat - Autocomplete format flag option.
+// -> "json"
+func AutocompleteJSONFormat(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ return []string{"json"}, cobra.ShellCompDirectiveNoFileComp
+}
+
+// AutocompleteOneArg - Autocomplete one random arg
+func AutocompleteOneArg(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ if len(args) == 1 {
+ return nil, cobra.ShellCompDirectiveDefault
+ }
+ return nil, cobra.ShellCompDirectiveNoFileComp
+}
diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go
index 57f64c395..9199a6286 100644
--- a/vendor/github.com/containers/common/pkg/config/default.go
+++ b/vendor/github.com/containers/common/pkg/config/default.go
@@ -11,9 +11,9 @@ import (
"github.com/containers/common/pkg/apparmor"
"github.com/containers/common/pkg/cgroupv2"
- "github.com/containers/storage"
"github.com/containers/storage/pkg/homedir"
"github.com/containers/storage/pkg/unshare"
+ "github.com/containers/storage/types"
"github.com/opencontainers/selinux/go-selinux"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -224,9 +224,9 @@ func defaultConfigFromMemory() (*EngineConfig, error) {
c.EventsLogFilePath = filepath.Join(c.TmpDir, "events", "events.log")
if path, ok := os.LookupEnv("CONTAINERS_STORAGE_CONF"); ok {
- storage.SetDefaultConfigFilePath(path)
+ types.SetDefaultConfigFilePath(path)
}
- storeOpts, err := storage.DefaultStoreOptions(unshare.IsRootless(), unshare.GetRootlessUID())
+ storeOpts, err := types.DefaultStoreOptions(unshare.IsRootless(), unshare.GetRootlessUID())
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/common/pkg/parse/parse_unix.go b/vendor/github.com/containers/common/pkg/parse/parse_unix.go
index 880fbf674..c07471c93 100644
--- a/vendor/github.com/containers/common/pkg/parse/parse_unix.go
+++ b/vendor/github.com/containers/common/pkg/parse/parse_unix.go
@@ -7,13 +7,12 @@ import (
"path/filepath"
"github.com/containers/storage/pkg/unshare"
- "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/devices"
"github.com/pkg/errors"
)
-func DeviceFromPath(device string) ([]configs.Device, error) {
- var devs []configs.Device
+func DeviceFromPath(device string) ([]devices.Device, error) {
+ var devs []devices.Device
src, dst, permissions, err := Device(device)
if err != nil {
return nil, err
@@ -44,7 +43,7 @@ func DeviceFromPath(device string) ([]configs.Device, error) {
}
for _, d := range srcDevices {
d.Path = filepath.Join(dst, filepath.Base(d.Path))
- d.Permissions = configs.DevicePermissions(permissions)
+ d.Permissions = devices.Permissions(permissions)
devs = append(devs, *d)
}
return devs, nil
diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go
index ff95a6522..afe620231 100644
--- a/vendor/github.com/containers/common/version/version.go
+++ b/vendor/github.com/containers/common/version/version.go
@@ -1,4 +1,4 @@
package version
// Version is the version of the build.
-const Version = "0.35.0"
+const Version = "0.35.3"
diff --git a/vendor/github.com/containers/image/v5/copy/copy.go b/vendor/github.com/containers/image/v5/copy/copy.go
index b5c755e18..3a2ee9a8f 100644
--- a/vendor/github.com/containers/image/v5/copy/copy.go
+++ b/vendor/github.com/containers/image/v5/copy/copy.go
@@ -1067,6 +1067,26 @@ type diffIDResult struct {
// copyLayer copies a layer with srcInfo (with known Digest and Annotations and possibly known Size) in src to dest, perhaps (de/re/)compressing it,
// and returns a complete blobInfo of the copied layer, and a value for LayerDiffIDs if diffIDIsNeeded
func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, toEncrypt bool, pool *mpb.Progress) (types.BlobInfo, digest.Digest, error) {
+ // If the srcInfo doesn't contain compression information, try to compute it from the
+ // MediaType, which was either read from a manifest by way of LayerInfos() or constructed
+ // by LayerInfosForCopy(), if it was supplied at all. If we succeed in copying the blob,
+ // the BlobInfo we return will be passed to UpdatedImage() and then to UpdateLayerInfos(),
+ // which uses the compression information to compute the updated MediaType values.
+ // (Sadly UpdatedImage() is documented to not update MediaTypes from
+ // ManifestUpdateOptions.LayerInfos[].MediaType, so we are doing it indirectly.)
+ //
+ // This MIME type → compression mapping belongs in manifest-specific code in our manifest
+ // package (but we should preferably replace/change UpdatedImage instead of productizing
+ // this workaround).
+ if srcInfo.CompressionAlgorithm == nil {
+ switch srcInfo.MediaType {
+ case manifest.DockerV2Schema2LayerMediaType, imgspecv1.MediaTypeImageLayerGzip:
+ srcInfo.CompressionAlgorithm = &compression.Gzip
+ case imgspecv1.MediaTypeImageLayerZstd:
+ srcInfo.CompressionAlgorithm = &compression.Zstd
+ }
+ }
+
cachedDiffID := ic.c.blobInfoCache.UncompressedDigest(srcInfo.Digest) // May be ""
// Diffs are needed if we are encrypting an image or trying to decrypt an image
diffIDIsNeeded := ic.diffIDsAreNeeded && cachedDiffID == "" || toEncrypt || (isOciEncrypted(srcInfo.MediaType) && ic.c.ociDecryptConfig != nil)
@@ -1095,6 +1115,19 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to
Artifact: srcInfo,
}
}
+
+ // If the reused blob has the same digest as the one we asked for, but
+ // the transport didn't/couldn't supply compression info, fill it in based
+ // on what we know from the srcInfos we were given.
+ // If the srcInfos came from LayerInfosForCopy(), then UpdatedImage() will
+ // call UpdateLayerInfos(), which uses this information to compute the
+ // MediaType value for the updated layer infos, and it the transport
+ // didn't pass the information along from its input to its output, then
+ // it can derive the MediaType incorrectly.
+ if blobInfo.Digest == srcInfo.Digest && blobInfo.CompressionAlgorithm == nil {
+ blobInfo.CompressionOperation = srcInfo.CompressionOperation
+ blobInfo.CompressionAlgorithm = srcInfo.CompressionAlgorithm
+ }
return blobInfo, cachedDiffID, nil
}
}
@@ -1349,7 +1382,15 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr
compressionOperation = types.PreserveOriginal
inputInfo = srcInfo
uploadCompressorName = srcCompressorName
- uploadCompressionFormat = nil
+ // Remember if the original blob was compressed, and if so how, so that if
+ // LayerInfosForCopy() returned something that differs from what was in the
+ // source's manifest, and UpdatedImage() needs to call UpdateLayerInfos(),
+ // it will be able to correctly derive the MediaType for the copied blob.
+ if isCompressed {
+ uploadCompressionFormat = &compressionFormat
+ } else {
+ uploadCompressionFormat = nil
+ }
}
// Perform image encryption for valid mediatypes if ociEncryptConfig provided
diff --git a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/shortnames.go b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/shortnames.go
index a9c498d7a..784a616dc 100644
--- a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/shortnames.go
+++ b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/shortnames.go
@@ -34,15 +34,9 @@ func shortNameAliasesConfPath(ctx *types.SystemContext) (string, error) {
}
// Rootless user
- var cacheRoot string
- if xdgCache := os.Getenv("XDG_CACHE_HOME"); xdgCache != "" {
- cacheRoot = xdgCache
- } else {
- configHome, err := homedir.GetConfigHome()
- if err != nil {
- return "", err
- }
- cacheRoot = filepath.Join(configHome, ".cache")
+ cacheRoot, err := homedir.GetCacheHome()
+ if err != nil {
+ return "", err
}
return filepath.Join(cacheRoot, userShortNamesFile), nil
diff --git a/vendor/github.com/containers/image/v5/storage/storage_image.go b/vendor/github.com/containers/image/v5/storage/storage_image.go
index 924d684ae..5340690bc 100644
--- a/vendor/github.com/containers/image/v5/storage/storage_image.go
+++ b/vendor/github.com/containers/image/v5/storage/storage_image.go
@@ -246,8 +246,7 @@ func (s *storageImageSource) LayerInfosForCopy(ctx context.Context, instanceDige
case imgspecv1.MediaTypeImageManifest:
uncompressedLayerType = imgspecv1.MediaTypeImageLayer
case manifest.DockerV2Schema1MediaType, manifest.DockerV2Schema1SignedMediaType, manifest.DockerV2Schema2MediaType:
- // This is actually a compressed type, but there's no uncompressed type defined
- uncompressedLayerType = manifest.DockerV2Schema2LayerMediaType
+ uncompressedLayerType = manifest.DockerV2SchemaLayerMediaTypeUncompressed
}
physicalBlobInfos := []types.BlobInfo{}
diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go
index 4c722505c..fb7230241 100644
--- a/vendor/github.com/containers/image/v5/version/version.go
+++ b/vendor/github.com/containers/image/v5/version/version.go
@@ -8,7 +8,7 @@ const (
// VersionMinor is for functionality in a backwards-compatible manner
VersionMinor = 10
// VersionPatch is for backwards-compatible bug fixes
- VersionPatch = 2
+ VersionPatch = 5
// VersionDev indicates development branch. Releases will be empty string.
VersionDev = ""
diff --git a/vendor/github.com/coreos/go-systemd/v22/activation/files.go b/vendor/github.com/coreos/go-systemd/v22/activation/files_unix.go
index 29dd18def..fc7db98fb 100644
--- a/vendor/github.com/coreos/go-systemd/v22/activation/files.go
+++ b/vendor/github.com/coreos/go-systemd/v22/activation/files_unix.go
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// +build !windows
+
// Package activation implements primitives for systemd socket activation.
package activation
diff --git a/vendor/github.com/coreos/go-systemd/v22/activation/files_windows.go b/vendor/github.com/coreos/go-systemd/v22/activation/files_windows.go
new file mode 100644
index 000000000..d391bf00c
--- /dev/null
+++ b/vendor/github.com/coreos/go-systemd/v22/activation/files_windows.go
@@ -0,0 +1,21 @@
+// Copyright 2015 CoreOS, Inc.
+//
+// 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 activation
+
+import "os"
+
+func Files(unsetEnv bool) []*os.File {
+ return nil
+}
diff --git a/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go b/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go
index 91584a166..e843a4613 100644
--- a/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go
+++ b/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go
@@ -16,6 +16,7 @@
package dbus
import (
+ "context"
"encoding/hex"
"fmt"
"os"
@@ -112,39 +113,63 @@ type Conn struct {
// New establishes a connection to any available bus and authenticates.
// Callers should call Close() when done with the connection.
+// Deprecated: use NewWithContext instead
func New() (*Conn, error) {
- conn, err := NewSystemConnection()
+ return NewWithContext(context.Background())
+}
+
+// NewWithContext same as New with context
+func NewWithContext(ctx context.Context) (*Conn, error) {
+ conn, err := NewSystemConnectionContext(ctx)
if err != nil && os.Geteuid() == 0 {
- return NewSystemdConnection()
+ return NewSystemdConnectionContext(ctx)
}
return conn, err
}
// NewSystemConnection establishes a connection to the system bus and authenticates.
// Callers should call Close() when done with the connection
+// Deprecated: use NewSystemConnectionContext instead
func NewSystemConnection() (*Conn, error) {
+ return NewSystemConnectionContext(context.Background())
+}
+
+// NewSystemConnectionContext same as NewSystemConnection with context
+func NewSystemConnectionContext(ctx context.Context) (*Conn, error) {
return NewConnection(func() (*dbus.Conn, error) {
- return dbusAuthHelloConnection(dbus.SystemBusPrivate)
+ return dbusAuthHelloConnection(ctx, dbus.SystemBusPrivate)
})
}
// NewUserConnection establishes a connection to the session bus and
// authenticates. This can be used to connect to systemd user instances.
// Callers should call Close() when done with the connection.
+// Deprecated: use NewUserConnectionContext instead
func NewUserConnection() (*Conn, error) {
+ return NewUserConnectionContext(context.Background())
+}
+
+// NewUserConnectionContext same as NewUserConnection with context
+func NewUserConnectionContext(ctx context.Context) (*Conn, error) {
return NewConnection(func() (*dbus.Conn, error) {
- return dbusAuthHelloConnection(dbus.SessionBusPrivate)
+ return dbusAuthHelloConnection(ctx, dbus.SessionBusPrivate)
})
}
// NewSystemdConnection establishes a private, direct connection to systemd.
// This can be used for communicating with systemd without a dbus daemon.
// Callers should call Close() when done with the connection.
+// Deprecated: use NewSystemdConnectionContext instead
func NewSystemdConnection() (*Conn, error) {
+ return NewSystemdConnectionContext(context.Background())
+}
+
+// NewSystemdConnectionContext same as NewSystemdConnection with context
+func NewSystemdConnectionContext(ctx context.Context) (*Conn, error) {
return NewConnection(func() (*dbus.Conn, error) {
// We skip Hello when talking directly to systemd.
- return dbusAuthConnection(func(opts ...dbus.ConnOption) (*dbus.Conn, error) {
- return dbus.Dial("unix:path=/run/systemd/private")
+ return dbusAuthConnection(ctx, func(opts ...dbus.ConnOption) (*dbus.Conn, error) {
+ return dbus.Dial("unix:path=/run/systemd/private", opts...)
})
})
}
@@ -201,8 +226,8 @@ func (c *Conn) GetManagerProperty(prop string) (string, error) {
return variant.String(), nil
}
-func dbusAuthConnection(createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) {
- conn, err := createBus()
+func dbusAuthConnection(ctx context.Context, createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) {
+ conn, err := createBus(dbus.WithContext(ctx))
if err != nil {
return nil, err
}
@@ -221,8 +246,8 @@ func dbusAuthConnection(createBus func(opts ...dbus.ConnOption) (*dbus.Conn, err
return conn, nil
}
-func dbusAuthHelloConnection(createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) {
- conn, err := dbusAuthConnection(createBus)
+func dbusAuthHelloConnection(ctx context.Context, createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) {
+ conn, err := dbusAuthConnection(ctx, createBus)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go b/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go
index e38659d7b..01879ba15 100644
--- a/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go
+++ b/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go
@@ -15,6 +15,7 @@
package dbus
import (
+ "context"
"errors"
"fmt"
"path"
@@ -23,6 +24,18 @@ import (
"github.com/godbus/dbus/v5"
)
+// Who can be used to specify which process to kill in the unit via the KillUnitWithTarget API
+type Who string
+
+const (
+ // All sends the signal to all processes in the unit
+ All Who = "all"
+ // Main sends the signal to the main process of the unit
+ Main Who = "main"
+ // Control sends the signal to the control process of the unit
+ Control Who = "control"
+)
+
func (c *Conn) jobComplete(signal *dbus.Signal) {
var id uint32
var job dbus.ObjectPath
@@ -38,14 +51,14 @@ func (c *Conn) jobComplete(signal *dbus.Signal) {
c.jobListener.Unlock()
}
-func (c *Conn) startJob(ch chan<- string, job string, args ...interface{}) (int, error) {
+func (c *Conn) startJob(ctx context.Context, ch chan<- string, job string, args ...interface{}) (int, error) {
if ch != nil {
c.jobListener.Lock()
defer c.jobListener.Unlock()
}
var p dbus.ObjectPath
- err := c.sysobj.Call(job, 0, args...).Store(&p)
+ err := c.sysobj.CallWithContext(ctx, job, 0, args...).Store(&p)
if err != nil {
return 0, err
}
@@ -90,43 +103,85 @@ func (c *Conn) startJob(ch chan<- string, job string, args ...interface{}) (int,
// should not be considered authoritative.
//
// If an error does occur, it will be returned to the user alongside a job ID of 0.
+// Deprecated: use StartUnitContext instead
func (c *Conn) StartUnit(name string, mode string, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.StartUnit", name, mode)
+ return c.StartUnitContext(context.Background(), name, mode, ch)
+}
+
+// StartUnitContext same as StartUnit with context
+func (c *Conn) StartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
+ return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.StartUnit", name, mode)
}
// StopUnit is similar to StartUnit but stops the specified unit rather
// than starting it.
+// Deprecated: use StopUnitContext instead
func (c *Conn) StopUnit(name string, mode string, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.StopUnit", name, mode)
+ return c.StopUnitContext(context.Background(), name, mode, ch)
+}
+
+// StopUnitContext same as StopUnit with context
+func (c *Conn) StopUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
+ return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.StopUnit", name, mode)
}
// ReloadUnit reloads a unit. Reloading is done only if the unit is already running and fails otherwise.
+// Deprecated: use ReloadUnitContext instead
func (c *Conn) ReloadUnit(name string, mode string, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.ReloadUnit", name, mode)
+ return c.ReloadUnitContext(context.Background(), name, mode, ch)
+}
+
+// ReloadUnitContext same as ReloadUnit with context
+func (c *Conn) ReloadUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
+ return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadUnit", name, mode)
}
// RestartUnit restarts a service. If a service is restarted that isn't
// running it will be started.
+// Deprecated: use RestartUnitContext instead
func (c *Conn) RestartUnit(name string, mode string, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.RestartUnit", name, mode)
+ return c.RestartUnitContext(context.Background(), name, mode, ch)
+}
+
+// RestartUnitContext same as RestartUnit with context
+func (c *Conn) RestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
+ return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.RestartUnit", name, mode)
}
// TryRestartUnit is like RestartUnit, except that a service that isn't running
// is not affected by the restart.
+// Deprecated: use TryRestartUnitContext instead
func (c *Conn) TryRestartUnit(name string, mode string, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.TryRestartUnit", name, mode)
+ return c.TryRestartUnitContext(context.Background(), name, mode, ch)
+}
+
+// TryRestartUnitContext same as TryRestartUnit with context
+func (c *Conn) TryRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
+ return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.TryRestartUnit", name, mode)
}
// ReloadOrRestartUnit attempts a reload if the unit supports it and use a restart
// otherwise.
+// Deprecated: use ReloadOrRestartUnitContext instead
func (c *Conn) ReloadOrRestartUnit(name string, mode string, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.ReloadOrRestartUnit", name, mode)
+ return c.ReloadOrRestartUnitContext(context.Background(), name, mode, ch)
+}
+
+// ReloadOrRestartUnitContext same as ReloadOrRestartUnit with context
+func (c *Conn) ReloadOrRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
+ return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadOrRestartUnit", name, mode)
}
// ReloadOrTryRestartUnit attempts a reload if the unit supports it and use a "Try"
// flavored restart otherwise.
+// Deprecated: use ReloadOrTryRestartUnitContext instead
func (c *Conn) ReloadOrTryRestartUnit(name string, mode string, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.ReloadOrTryRestartUnit", name, mode)
+ return c.ReloadOrTryRestartUnitContext(context.Background(), name, mode, ch)
+}
+
+// ReloadOrTryRestartUnitContext same as ReloadOrTryRestartUnit with context
+func (c *Conn) ReloadOrTryRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
+ return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadOrTryRestartUnit", name, mode)
}
// StartTransientUnit() may be used to create and start a transient unit, which
@@ -134,28 +189,57 @@ func (c *Conn) ReloadOrTryRestartUnit(name string, mode string, ch chan<- string
// system is rebooted. name is the unit name including suffix, and must be
// unique. mode is the same as in StartUnit(), properties contains properties
// of the unit.
+// Deprecated: use StartTransientUnitContext instead
func (c *Conn) StartTransientUnit(name string, mode string, properties []Property, ch chan<- string) (int, error) {
- return c.startJob(ch, "org.freedesktop.systemd1.Manager.StartTransientUnit", name, mode, properties, make([]PropertyCollection, 0))
+ return c.StartTransientUnitContext(context.Background(), name, mode, properties, ch)
+}
+
+// StartTransientUnitContext same as StartTransientUnit with context
+func (c *Conn) StartTransientUnitContext(ctx context.Context, name string, mode string, properties []Property, ch chan<- string) (int, error) {
+ return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.StartTransientUnit", name, mode, properties, make([]PropertyCollection, 0))
}
// KillUnit takes the unit name and a UNIX signal number to send. All of the unit's
// processes are killed.
+// Deprecated: use KillUnitContext instead
func (c *Conn) KillUnit(name string, signal int32) {
- c.sysobj.Call("org.freedesktop.systemd1.Manager.KillUnit", 0, name, "all", signal).Store()
+ c.KillUnitContext(context.Background(), name, signal)
+}
+
+// KillUnitContext same as KillUnit with context
+func (c *Conn) KillUnitContext(ctx context.Context, name string, signal int32) {
+ c.KillUnitWithTarget(ctx, name, All, signal)
+}
+
+// KillUnitWithTarget is like KillUnitContext, but allows you to specify which process in the unit to send the signal to
+func (c *Conn) KillUnitWithTarget(ctx context.Context, name string, target Who, signal int32) error {
+ return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.KillUnit", 0, name, string(target), signal).Store()
}
// ResetFailedUnit resets the "failed" state of a specific unit.
+// Deprecated: use ResetFailedUnitContext instead
func (c *Conn) ResetFailedUnit(name string) error {
- return c.sysobj.Call("org.freedesktop.systemd1.Manager.ResetFailedUnit", 0, name).Store()
+ return c.ResetFailedUnitContext(context.Background(), name)
+}
+
+// ResetFailedUnitContext same as ResetFailedUnit with context
+func (c *Conn) ResetFailedUnitContext(ctx context.Context, name string) error {
+ return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ResetFailedUnit", 0, name).Store()
}
// SystemState returns the systemd state. Equivalent to `systemctl is-system-running`.
+// Deprecated: use SystemStateContext instead
func (c *Conn) SystemState() (*Property, error) {
+ return c.SystemStateContext(context.Background())
+}
+
+// SystemStateContext same as SystemState with context
+func (c *Conn) SystemStateContext(ctx context.Context) (*Property, error) {
var err error
var prop dbus.Variant
obj := c.sysconn.Object("org.freedesktop.systemd1", "/org/freedesktop/systemd1")
- err = obj.Call("org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.systemd1.Manager", "SystemState").Store(&prop)
+ err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.systemd1.Manager", "SystemState").Store(&prop)
if err != nil {
return nil, err
}
@@ -164,7 +248,7 @@ func (c *Conn) SystemState() (*Property, error) {
}
// getProperties takes the unit path and returns all of its dbus object properties, for the given dbus interface
-func (c *Conn) getProperties(path dbus.ObjectPath, dbusInterface string) (map[string]interface{}, error) {
+func (c *Conn) getProperties(ctx context.Context, path dbus.ObjectPath, dbusInterface string) (map[string]interface{}, error) {
var err error
var props map[string]dbus.Variant
@@ -173,7 +257,7 @@ func (c *Conn) getProperties(path dbus.ObjectPath, dbusInterface string) (map[st
}
obj := c.sysconn.Object("org.freedesktop.systemd1", path)
- err = obj.Call("org.freedesktop.DBus.Properties.GetAll", 0, dbusInterface).Store(&props)
+ err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.GetAll", 0, dbusInterface).Store(&props)
if err != nil {
return nil, err
}
@@ -187,23 +271,41 @@ func (c *Conn) getProperties(path dbus.ObjectPath, dbusInterface string) (map[st
}
// GetUnitProperties takes the (unescaped) unit name and returns all of its dbus object properties.
+// Deprecated: use GetUnitPropertiesContext instead
func (c *Conn) GetUnitProperties(unit string) (map[string]interface{}, error) {
+ return c.GetUnitPropertiesContext(context.Background(), unit)
+}
+
+// GetUnitPropertiesContext same as GetUnitPropertiesContext with context
+func (c *Conn) GetUnitPropertiesContext(ctx context.Context, unit string) (map[string]interface{}, error) {
path := unitPath(unit)
- return c.getProperties(path, "org.freedesktop.systemd1.Unit")
+ return c.getProperties(ctx, path, "org.freedesktop.systemd1.Unit")
}
// GetUnitPathProperties takes the (escaped) unit path and returns all of its dbus object properties.
+// Deprecated: use GetUnitPathPropertiesContext instead
func (c *Conn) GetUnitPathProperties(path dbus.ObjectPath) (map[string]interface{}, error) {
- return c.getProperties(path, "org.freedesktop.systemd1.Unit")
+ return c.GetUnitPathPropertiesContext(context.Background(), path)
+}
+
+// GetUnitPathPropertiesContext same as GetUnitPathProperties with context
+func (c *Conn) GetUnitPathPropertiesContext(ctx context.Context, path dbus.ObjectPath) (map[string]interface{}, error) {
+ return c.getProperties(ctx, path, "org.freedesktop.systemd1.Unit")
}
// GetAllProperties takes the (unescaped) unit name and returns all of its dbus object properties.
+// Deprecated: use GetAllPropertiesContext instead
func (c *Conn) GetAllProperties(unit string) (map[string]interface{}, error) {
+ return c.GetAllPropertiesContext(context.Background(), unit)
+}
+
+// GetAllPropertiesContext same as GetAllProperties with context
+func (c *Conn) GetAllPropertiesContext(ctx context.Context, unit string) (map[string]interface{}, error) {
path := unitPath(unit)
- return c.getProperties(path, "")
+ return c.getProperties(ctx, path, "")
}
-func (c *Conn) getProperty(unit string, dbusInterface string, propertyName string) (*Property, error) {
+func (c *Conn) getProperty(ctx context.Context, unit string, dbusInterface string, propertyName string) (*Property, error) {
var err error
var prop dbus.Variant
@@ -213,7 +315,7 @@ func (c *Conn) getProperty(unit string, dbusInterface string, propertyName strin
}
obj := c.sysconn.Object("org.freedesktop.systemd1", path)
- err = obj.Call("org.freedesktop.DBus.Properties.Get", 0, dbusInterface, propertyName).Store(&prop)
+ err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, dbusInterface, propertyName).Store(&prop)
if err != nil {
return nil, err
}
@@ -221,21 +323,39 @@ func (c *Conn) getProperty(unit string, dbusInterface string, propertyName strin
return &Property{Name: propertyName, Value: prop}, nil
}
+// Deprecated: use GetUnitPropertyContext instead
func (c *Conn) GetUnitProperty(unit string, propertyName string) (*Property, error) {
- return c.getProperty(unit, "org.freedesktop.systemd1.Unit", propertyName)
+ return c.GetUnitPropertyContext(context.Background(), unit, propertyName)
+}
+
+// GetUnitPropertyContext same as GetUnitProperty with context
+func (c *Conn) GetUnitPropertyContext(ctx context.Context, unit string, propertyName string) (*Property, error) {
+ return c.getProperty(ctx, unit, "org.freedesktop.systemd1.Unit", propertyName)
}
// GetServiceProperty returns property for given service name and property name
+// Deprecated: use GetServicePropertyContext instead
func (c *Conn) GetServiceProperty(service string, propertyName string) (*Property, error) {
- return c.getProperty(service, "org.freedesktop.systemd1.Service", propertyName)
+ return c.GetServicePropertyContext(context.Background(), service, propertyName)
+}
+
+// GetServicePropertyContext same as GetServiceProperty with context
+func (c *Conn) GetServicePropertyContext(ctx context.Context, service string, propertyName string) (*Property, error) {
+ return c.getProperty(ctx, service, "org.freedesktop.systemd1.Service", propertyName)
}
// GetUnitTypeProperties returns the extra properties for a unit, specific to the unit type.
// Valid values for unitType: Service, Socket, Target, Device, Mount, Automount, Snapshot, Timer, Swap, Path, Slice, Scope
// return "dbus.Error: Unknown interface" if the unitType is not the correct type of the unit
+// Deprecated: use GetUnitTypePropertiesContext instead
func (c *Conn) GetUnitTypeProperties(unit string, unitType string) (map[string]interface{}, error) {
+ return c.GetUnitTypePropertiesContext(context.Background(), unit, unitType)
+}
+
+// GetUnitTypePropertiesContext same as GetUnitTypeProperties with context
+func (c *Conn) GetUnitTypePropertiesContext(ctx context.Context, unit string, unitType string) (map[string]interface{}, error) {
path := unitPath(unit)
- return c.getProperties(path, "org.freedesktop.systemd1."+unitType)
+ return c.getProperties(ctx, path, "org.freedesktop.systemd1."+unitType)
}
// SetUnitProperties() may be used to modify certain unit properties at runtime.
@@ -245,12 +365,24 @@ func (c *Conn) GetUnitTypeProperties(unit string, unitType string) (map[string]i
// case the settings only apply until the next reboot. name is the name of the unit
// to modify. properties are the settings to set, encoded as an array of property
// name and value pairs.
+// Deprecated: use SetUnitPropertiesContext instead
func (c *Conn) SetUnitProperties(name string, runtime bool, properties ...Property) error {
- return c.sysobj.Call("org.freedesktop.systemd1.Manager.SetUnitProperties", 0, name, runtime, properties).Store()
+ return c.SetUnitPropertiesContext(context.Background(), name, runtime, properties...)
}
+// SetUnitPropertiesContext same as SetUnitProperties with context
+func (c *Conn) SetUnitPropertiesContext(ctx context.Context, name string, runtime bool, properties ...Property) error {
+ return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.SetUnitProperties", 0, name, runtime, properties).Store()
+}
+
+// Deprecated: use GetUnitTypePropertyContext instead
func (c *Conn) GetUnitTypeProperty(unit string, unitType string, propertyName string) (*Property, error) {
- return c.getProperty(unit, "org.freedesktop.systemd1."+unitType, propertyName)
+ return c.GetUnitTypePropertyContext(context.Background(), unit, unitType, propertyName)
+}
+
+// GetUnitTypePropertyContext same as GetUnitTypeProperty with context
+func (c *Conn) GetUnitTypePropertyContext(ctx context.Context, unit string, unitType string, propertyName string) (*Property, error) {
+ return c.getProperty(ctx, unit, "org.freedesktop.systemd1."+unitType, propertyName)
}
type UnitStatus struct {
@@ -299,22 +431,40 @@ func (c *Conn) listUnitsInternal(f storeFunc) ([]UnitStatus, error) {
// be more unit names loaded than actual units behind them.
// Also note that a unit is only loaded if it is active and/or enabled.
// Units that are both disabled and inactive will thus not be returned.
+// Deprecated: use ListUnitsContext instead
func (c *Conn) ListUnits() ([]UnitStatus, error) {
- return c.listUnitsInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnits", 0).Store)
+ return c.ListUnitsContext(context.Background())
+}
+
+// ListUnitsContext same as ListUnits with context
+func (c *Conn) ListUnitsContext(ctx context.Context) ([]UnitStatus, error) {
+ return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnits", 0).Store)
}
// ListUnitsFiltered returns an array with units filtered by state.
// It takes a list of units' statuses to filter.
+// Deprecated: use ListUnitsFilteredContext instead
func (c *Conn) ListUnitsFiltered(states []string) ([]UnitStatus, error) {
- return c.listUnitsInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitsFiltered", 0, states).Store)
+ return c.ListUnitsFilteredContext(context.Background(), states)
+}
+
+// ListUnitsFilteredContext same as ListUnitsFiltered with context
+func (c *Conn) ListUnitsFilteredContext(ctx context.Context, states []string) ([]UnitStatus, error) {
+ return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitsFiltered", 0, states).Store)
}
// ListUnitsByPatterns returns an array with units.
// It takes a list of units' statuses and names to filter.
// Note that units may be known by multiple names at the same time,
// and hence there might be more unit names loaded than actual units behind them.
+// Deprecated: use ListUnitsByPatternsContext instead
func (c *Conn) ListUnitsByPatterns(states []string, patterns []string) ([]UnitStatus, error) {
- return c.listUnitsInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitsByPatterns", 0, states, patterns).Store)
+ return c.ListUnitsByPatternsContext(context.Background(), states, patterns)
+}
+
+// ListUnitsByPatternsContext same as ListUnitsByPatterns with context
+func (c *Conn) ListUnitsByPatternsContext(ctx context.Context, states []string, patterns []string) ([]UnitStatus, error) {
+ return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitsByPatterns", 0, states, patterns).Store)
}
// ListUnitsByNames returns an array with units. It takes a list of units'
@@ -322,8 +472,14 @@ func (c *Conn) ListUnitsByPatterns(states []string, patterns []string) ([]UnitSt
// method, this method returns statuses even for inactive or non-existing
// units. Input array should contain exact unit names, but not patterns.
// Note: Requires systemd v230 or higher
+// Deprecated: use ListUnitsByNamesContext instead
func (c *Conn) ListUnitsByNames(units []string) ([]UnitStatus, error) {
- return c.listUnitsInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitsByNames", 0, units).Store)
+ return c.ListUnitsByNamesContext(context.Background(), units)
+}
+
+// ListUnitsByNamesContext same as ListUnitsByNames with context
+func (c *Conn) ListUnitsByNamesContext(ctx context.Context, units []string) ([]UnitStatus, error) {
+ return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitsByNames", 0, units).Store)
}
type UnitFile struct {
@@ -358,13 +514,25 @@ func (c *Conn) listUnitFilesInternal(f storeFunc) ([]UnitFile, error) {
}
// ListUnitFiles returns an array of all available units on disk.
+// Deprecated: use ListUnitFilesContext instead
func (c *Conn) ListUnitFiles() ([]UnitFile, error) {
- return c.listUnitFilesInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitFiles", 0).Store)
+ return c.ListUnitFilesContext(context.Background())
+}
+
+// ListUnitFilesContext same as ListUnitFiles with context
+func (c *Conn) ListUnitFilesContext(ctx context.Context) ([]UnitFile, error) {
+ return c.listUnitFilesInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitFiles", 0).Store)
}
// ListUnitFilesByPatterns returns an array of all available units on disk matched the patterns.
+// Deprecated: use ListUnitFilesByPatternsContext instead
func (c *Conn) ListUnitFilesByPatterns(states []string, patterns []string) ([]UnitFile, error) {
- return c.listUnitFilesInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitFilesByPatterns", 0, states, patterns).Store)
+ return c.ListUnitFilesByPatternsContext(context.Background(), states, patterns)
+}
+
+// ListUnitFilesByPatternsContext same as ListUnitFilesByPatterns with context
+func (c *Conn) ListUnitFilesByPatternsContext(ctx context.Context, states []string, patterns []string) ([]UnitFile, error) {
+ return c.listUnitFilesInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitFilesByPatterns", 0, states, patterns).Store)
}
type LinkUnitFileChange EnableUnitFileChange
@@ -383,9 +551,15 @@ type LinkUnitFileChange EnableUnitFileChange
// structures with three strings: the type of the change (one of symlink
// or unlink), the file name of the symlink and the destination of the
// symlink.
+// Deprecated: use LinkUnitFilesContext instead
func (c *Conn) LinkUnitFiles(files []string, runtime bool, force bool) ([]LinkUnitFileChange, error) {
+ return c.LinkUnitFilesContext(context.Background(), files, runtime, force)
+}
+
+// LinkUnitFilesContext same as LinkUnitFiles with context
+func (c *Conn) LinkUnitFilesContext(ctx context.Context, files []string, runtime bool, force bool) ([]LinkUnitFileChange, error) {
result := make([][]interface{}, 0)
- err := c.sysobj.Call("org.freedesktop.systemd1.Manager.LinkUnitFiles", 0, files, runtime, force).Store(&result)
+ err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.LinkUnitFiles", 0, files, runtime, force).Store(&result)
if err != nil {
return nil, err
}
@@ -425,11 +599,17 @@ func (c *Conn) LinkUnitFiles(files []string, runtime bool, force bool) ([]LinkUn
// structures with three strings: the type of the change (one of symlink
// or unlink), the file name of the symlink and the destination of the
// symlink.
+// Deprecated: use EnableUnitFilesContext instead
func (c *Conn) EnableUnitFiles(files []string, runtime bool, force bool) (bool, []EnableUnitFileChange, error) {
+ return c.EnableUnitFilesContext(context.Background(), files, runtime, force)
+}
+
+// EnableUnitFilesContext same as EnableUnitFiles with context
+func (c *Conn) EnableUnitFilesContext(ctx context.Context, files []string, runtime bool, force bool) (bool, []EnableUnitFileChange, error) {
var carries_install_info bool
result := make([][]interface{}, 0)
- err := c.sysobj.Call("org.freedesktop.systemd1.Manager.EnableUnitFiles", 0, files, runtime, force).Store(&carries_install_info, &result)
+ err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.EnableUnitFiles", 0, files, runtime, force).Store(&carries_install_info, &result)
if err != nil {
return false, nil, err
}
@@ -471,9 +651,15 @@ type EnableUnitFileChange struct {
// consists of structures with three strings: the type of the change (one of
// symlink or unlink), the file name of the symlink and the destination of the
// symlink.
+// Deprecated: use DisableUnitFilesContext instead
func (c *Conn) DisableUnitFiles(files []string, runtime bool) ([]DisableUnitFileChange, error) {
+ return c.DisableUnitFilesContext(context.Background(), files, runtime)
+}
+
+// DisableUnitFilesContext same as DisableUnitFiles with context
+func (c *Conn) DisableUnitFilesContext(ctx context.Context, files []string, runtime bool) ([]DisableUnitFileChange, error) {
result := make([][]interface{}, 0)
- err := c.sysobj.Call("org.freedesktop.systemd1.Manager.DisableUnitFiles", 0, files, runtime).Store(&result)
+ err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.DisableUnitFiles", 0, files, runtime).Store(&result)
if err != nil {
return nil, err
}
@@ -512,9 +698,15 @@ type DisableUnitFileChange struct {
// * runtime to specify whether the unit was enabled for runtime
// only (true, /run/systemd/..), or persistently (false, /etc/systemd/..)
// * force flag
+// Deprecated: use MaskUnitFilesContext instead
func (c *Conn) MaskUnitFiles(files []string, runtime bool, force bool) ([]MaskUnitFileChange, error) {
+ return c.MaskUnitFilesContext(context.Background(), files, runtime, force)
+}
+
+// MaskUnitFilesContext same as MaskUnitFiles with context
+func (c *Conn) MaskUnitFilesContext(ctx context.Context, files []string, runtime bool, force bool) ([]MaskUnitFileChange, error) {
result := make([][]interface{}, 0)
- err := c.sysobj.Call("org.freedesktop.systemd1.Manager.MaskUnitFiles", 0, files, runtime, force).Store(&result)
+ err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.MaskUnitFiles", 0, files, runtime, force).Store(&result)
if err != nil {
return nil, err
}
@@ -552,9 +744,15 @@ type MaskUnitFileChange struct {
// the usual unit search paths)
// * runtime to specify whether the unit was enabled for runtime
// only (true, /run/systemd/..), or persistently (false, /etc/systemd/..)
+// Deprecated: use UnmaskUnitFilesContext instead
func (c *Conn) UnmaskUnitFiles(files []string, runtime bool) ([]UnmaskUnitFileChange, error) {
+ return c.UnmaskUnitFilesContext(context.Background(), files, runtime)
+}
+
+// UnmaskUnitFilesContext same as UnmaskUnitFiles with context
+func (c *Conn) UnmaskUnitFilesContext(ctx context.Context, files []string, runtime bool) ([]UnmaskUnitFileChange, error) {
result := make([][]interface{}, 0)
- err := c.sysobj.Call("org.freedesktop.systemd1.Manager.UnmaskUnitFiles", 0, files, runtime).Store(&result)
+ err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.UnmaskUnitFiles", 0, files, runtime).Store(&result)
if err != nil {
return nil, err
}
@@ -586,8 +784,14 @@ type UnmaskUnitFileChange struct {
// Reload instructs systemd to scan for and reload unit files. This is
// equivalent to a 'systemctl daemon-reload'.
+// Deprecated: use ReloadContext instead
func (c *Conn) Reload() error {
- return c.sysobj.Call("org.freedesktop.systemd1.Manager.Reload", 0).Store()
+ return c.ReloadContext(context.Background())
+}
+
+// ReloadContext same as Reload with context
+func (c *Conn) ReloadContext(ctx context.Context) error {
+ return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.Reload", 0).Store()
}
func unitPath(name string) dbus.ObjectPath {
@@ -598,3 +802,48 @@ func unitPath(name string) dbus.ObjectPath {
func unitName(dpath dbus.ObjectPath) string {
return pathBusUnescape(path.Base(string(dpath)))
}
+
+// Currently queued job definition
+type JobStatus struct {
+ Id uint32 // The numeric job id
+ Unit string // The primary unit name for this job
+ JobType string // The job type as string
+ Status string // The job state as string
+ JobPath dbus.ObjectPath // The job object path
+ UnitPath dbus.ObjectPath // The unit object path
+}
+
+// ListJobs returns an array with all currently queued jobs
+// Deprecated: use ListJobsContext instead
+func (c *Conn) ListJobs() ([]JobStatus, error) {
+ return c.ListJobsContext(context.Background())
+}
+
+// ListJobsContext same as ListJobs with context
+func (c *Conn) ListJobsContext(ctx context.Context) ([]JobStatus, error) {
+ return c.listJobsInternal(ctx)
+}
+
+func (c *Conn) listJobsInternal(ctx context.Context) ([]JobStatus, error) {
+ result := make([][]interface{}, 0)
+ if err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListJobs", 0).Store(&result); err != nil {
+ return nil, err
+ }
+
+ resultInterface := make([]interface{}, len(result))
+ for i := range result {
+ resultInterface[i] = result[i]
+ }
+
+ status := make([]JobStatus, len(result))
+ statusInterface := make([]interface{}, len(status))
+ for i := range status {
+ statusInterface[i] = &status[i]
+ }
+
+ if err := dbus.Store(resultInterface, statusInterface...); err != nil {
+ return nil, err
+ }
+
+ return status, nil
+}
diff --git a/vendor/github.com/coreos/go-systemd/v22/journal/journal.go b/vendor/github.com/coreos/go-systemd/v22/journal/journal.go
index a0f4837a0..ac24c7767 100644
--- a/vendor/github.com/coreos/go-systemd/v22/journal/journal.go
+++ b/vendor/github.com/coreos/go-systemd/v22/journal/journal.go
@@ -23,20 +23,7 @@
package journal
import (
- "bytes"
- "encoding/binary"
- "errors"
"fmt"
- "io"
- "io/ioutil"
- "net"
- "os"
- "strconv"
- "strings"
- "sync"
- "sync/atomic"
- "syscall"
- "unsafe"
)
// Priority of a journal message
@@ -53,173 +40,7 @@ const (
PriDebug
)
-var (
- // This can be overridden at build-time:
- // https://github.com/golang/go/wiki/GcToolchainTricks#including-build-information-in-the-executable
- journalSocket = "/run/systemd/journal/socket"
-
- // unixConnPtr atomically holds the local unconnected Unix-domain socket.
- // Concrete safe pointer type: *net.UnixConn
- unixConnPtr unsafe.Pointer
- // onceConn ensures that unixConnPtr is initialized exactly once.
- onceConn sync.Once
-)
-
-func init() {
- onceConn.Do(initConn)
-}
-
-// Enabled checks whether the local systemd journal is available for logging.
-func Enabled() bool {
- onceConn.Do(initConn)
-
- if (*net.UnixConn)(atomic.LoadPointer(&unixConnPtr)) == nil {
- return false
- }
-
- if _, err := net.Dial("unixgram", journalSocket); err != nil {
- return false
- }
-
- return true
-}
-
-// Send a message to the local systemd journal. vars is a map of journald
-// fields to values. Fields must be composed of uppercase letters, numbers,
-// and underscores, but must not start with an underscore. Within these
-// restrictions, any arbitrary field name may be used. Some names have special
-// significance: see the journalctl documentation
-// (http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html)
-// for more details. vars may be nil.
-func Send(message string, priority Priority, vars map[string]string) error {
- conn := (*net.UnixConn)(atomic.LoadPointer(&unixConnPtr))
- if conn == nil {
- return errors.New("could not initialize socket to journald")
- }
-
- socketAddr := &net.UnixAddr{
- Name: journalSocket,
- Net: "unixgram",
- }
-
- data := new(bytes.Buffer)
- appendVariable(data, "PRIORITY", strconv.Itoa(int(priority)))
- appendVariable(data, "MESSAGE", message)
- for k, v := range vars {
- appendVariable(data, k, v)
- }
-
- _, _, err := conn.WriteMsgUnix(data.Bytes(), nil, socketAddr)
- if err == nil {
- return nil
- }
- if !isSocketSpaceError(err) {
- return err
- }
-
- // Large log entry, send it via tempfile and ancillary-fd.
- file, err := tempFd()
- if err != nil {
- return err
- }
- defer file.Close()
- _, err = io.Copy(file, data)
- if err != nil {
- return err
- }
- rights := syscall.UnixRights(int(file.Fd()))
- _, _, err = conn.WriteMsgUnix([]byte{}, rights, socketAddr)
- if err != nil {
- return err
- }
-
- return nil
-}
-
// Print prints a message to the local systemd journal using Send().
func Print(priority Priority, format string, a ...interface{}) error {
return Send(fmt.Sprintf(format, a...), priority, nil)
}
-
-func appendVariable(w io.Writer, name, value string) {
- if err := validVarName(name); err != nil {
- fmt.Fprintf(os.Stderr, "variable name %s contains invalid character, ignoring\n", name)
- }
- if strings.ContainsRune(value, '\n') {
- /* When the value contains a newline, we write:
- * - the variable name, followed by a newline
- * - the size (in 64bit little endian format)
- * - the data, followed by a newline
- */
- fmt.Fprintln(w, name)
- binary.Write(w, binary.LittleEndian, uint64(len(value)))
- fmt.Fprintln(w, value)
- } else {
- /* just write the variable and value all on one line */
- fmt.Fprintf(w, "%s=%s\n", name, value)
- }
-}
-
-// validVarName validates a variable name to make sure journald will accept it.
-// The variable name must be in uppercase and consist only of characters,
-// numbers and underscores, and may not begin with an underscore:
-// https://www.freedesktop.org/software/systemd/man/sd_journal_print.html
-func validVarName(name string) error {
- if name == "" {
- return errors.New("Empty variable name")
- } else if name[0] == '_' {
- return errors.New("Variable name begins with an underscore")
- }
-
- for _, c := range name {
- if !(('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_') {
- return errors.New("Variable name contains invalid characters")
- }
- }
- return nil
-}
-
-// isSocketSpaceError checks whether the error is signaling
-// an "overlarge message" condition.
-func isSocketSpaceError(err error) bool {
- opErr, ok := err.(*net.OpError)
- if !ok || opErr == nil {
- return false
- }
-
- sysErr, ok := opErr.Err.(*os.SyscallError)
- if !ok || sysErr == nil {
- return false
- }
-
- return sysErr.Err == syscall.EMSGSIZE || sysErr.Err == syscall.ENOBUFS
-}
-
-// tempFd creates a temporary, unlinked file under `/dev/shm`.
-func tempFd() (*os.File, error) {
- file, err := ioutil.TempFile("/dev/shm/", "journal.XXXXX")
- if err != nil {
- return nil, err
- }
- err = syscall.Unlink(file.Name())
- if err != nil {
- return nil, err
- }
- return file, nil
-}
-
-// initConn initializes the global `unixConnPtr` socket.
-// It is meant to be called exactly once, at program startup.
-func initConn() {
- autobind, err := net.ResolveUnixAddr("unixgram", "")
- if err != nil {
- return
- }
-
- sock, err := net.ListenUnixgram("unixgram", autobind)
- if err != nil {
- return
- }
-
- atomic.StorePointer(&unixConnPtr, unsafe.Pointer(sock))
-}
diff --git a/vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go b/vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go
new file mode 100644
index 000000000..7233ecfc7
--- /dev/null
+++ b/vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go
@@ -0,0 +1,208 @@
+// Copyright 2015 CoreOS, Inc.
+//
+// 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.
+
+// +build !windows
+
+// Package journal provides write bindings to the local systemd journal.
+// It is implemented in pure Go and connects to the journal directly over its
+// unix socket.
+//
+// To read from the journal, see the "sdjournal" package, which wraps the
+// sd-journal a C API.
+//
+// http://www.freedesktop.org/software/systemd/man/systemd-journald.service.html
+package journal
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net"
+ "os"
+ "strconv"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "syscall"
+ "unsafe"
+)
+
+var (
+ // This can be overridden at build-time:
+ // https://github.com/golang/go/wiki/GcToolchainTricks#including-build-information-in-the-executable
+ journalSocket = "/run/systemd/journal/socket"
+
+ // unixConnPtr atomically holds the local unconnected Unix-domain socket.
+ // Concrete safe pointer type: *net.UnixConn
+ unixConnPtr unsafe.Pointer
+ // onceConn ensures that unixConnPtr is initialized exactly once.
+ onceConn sync.Once
+)
+
+func init() {
+ onceConn.Do(initConn)
+}
+
+// Enabled checks whether the local systemd journal is available for logging.
+func Enabled() bool {
+ onceConn.Do(initConn)
+
+ if (*net.UnixConn)(atomic.LoadPointer(&unixConnPtr)) == nil {
+ return false
+ }
+
+ if _, err := net.Dial("unixgram", journalSocket); err != nil {
+ return false
+ }
+
+ return true
+}
+
+// Send a message to the local systemd journal. vars is a map of journald
+// fields to values. Fields must be composed of uppercase letters, numbers,
+// and underscores, but must not start with an underscore. Within these
+// restrictions, any arbitrary field name may be used. Some names have special
+// significance: see the journalctl documentation
+// (http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html)
+// for more details. vars may be nil.
+func Send(message string, priority Priority, vars map[string]string) error {
+ conn := (*net.UnixConn)(atomic.LoadPointer(&unixConnPtr))
+ if conn == nil {
+ return errors.New("could not initialize socket to journald")
+ }
+
+ socketAddr := &net.UnixAddr{
+ Name: journalSocket,
+ Net: "unixgram",
+ }
+
+ data := new(bytes.Buffer)
+ appendVariable(data, "PRIORITY", strconv.Itoa(int(priority)))
+ appendVariable(data, "MESSAGE", message)
+ for k, v := range vars {
+ appendVariable(data, k, v)
+ }
+
+ _, _, err := conn.WriteMsgUnix(data.Bytes(), nil, socketAddr)
+ if err == nil {
+ return nil
+ }
+ if !isSocketSpaceError(err) {
+ return err
+ }
+
+ // Large log entry, send it via tempfile and ancillary-fd.
+ file, err := tempFd()
+ if err != nil {
+ return err
+ }
+ defer file.Close()
+ _, err = io.Copy(file, data)
+ if err != nil {
+ return err
+ }
+ rights := syscall.UnixRights(int(file.Fd()))
+ _, _, err = conn.WriteMsgUnix([]byte{}, rights, socketAddr)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func appendVariable(w io.Writer, name, value string) {
+ if err := validVarName(name); err != nil {
+ fmt.Fprintf(os.Stderr, "variable name %s contains invalid character, ignoring\n", name)
+ }
+ if strings.ContainsRune(value, '\n') {
+ /* When the value contains a newline, we write:
+ * - the variable name, followed by a newline
+ * - the size (in 64bit little endian format)
+ * - the data, followed by a newline
+ */
+ fmt.Fprintln(w, name)
+ binary.Write(w, binary.LittleEndian, uint64(len(value)))
+ fmt.Fprintln(w, value)
+ } else {
+ /* just write the variable and value all on one line */
+ fmt.Fprintf(w, "%s=%s\n", name, value)
+ }
+}
+
+// validVarName validates a variable name to make sure journald will accept it.
+// The variable name must be in uppercase and consist only of characters,
+// numbers and underscores, and may not begin with an underscore:
+// https://www.freedesktop.org/software/systemd/man/sd_journal_print.html
+func validVarName(name string) error {
+ if name == "" {
+ return errors.New("Empty variable name")
+ } else if name[0] == '_' {
+ return errors.New("Variable name begins with an underscore")
+ }
+
+ for _, c := range name {
+ if !(('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_') {
+ return errors.New("Variable name contains invalid characters")
+ }
+ }
+ return nil
+}
+
+// isSocketSpaceError checks whether the error is signaling
+// an "overlarge message" condition.
+func isSocketSpaceError(err error) bool {
+ opErr, ok := err.(*net.OpError)
+ if !ok || opErr == nil {
+ return false
+ }
+
+ sysErr, ok := opErr.Err.(*os.SyscallError)
+ if !ok || sysErr == nil {
+ return false
+ }
+
+ return sysErr.Err == syscall.EMSGSIZE || sysErr.Err == syscall.ENOBUFS
+}
+
+// tempFd creates a temporary, unlinked file under `/dev/shm`.
+func tempFd() (*os.File, error) {
+ file, err := ioutil.TempFile("/dev/shm/", "journal.XXXXX")
+ if err != nil {
+ return nil, err
+ }
+ err = syscall.Unlink(file.Name())
+ if err != nil {
+ return nil, err
+ }
+ return file, nil
+}
+
+// initConn initializes the global `unixConnPtr` socket.
+// It is meant to be called exactly once, at program startup.
+func initConn() {
+ autobind, err := net.ResolveUnixAddr("unixgram", "")
+ if err != nil {
+ return
+ }
+
+ sock, err := net.ListenUnixgram("unixgram", autobind)
+ if err != nil {
+ return
+ }
+
+ atomic.StorePointer(&unixConnPtr, unsafe.Pointer(sock))
+}
diff --git a/vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go b/vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go
new file mode 100644
index 000000000..677aca68e
--- /dev/null
+++ b/vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go
@@ -0,0 +1,35 @@
+// Copyright 2015 CoreOS, Inc.
+//
+// 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 journal provides write bindings to the local systemd journal.
+// It is implemented in pure Go and connects to the journal directly over its
+// unix socket.
+//
+// To read from the journal, see the "sdjournal" package, which wraps the
+// sd-journal a C API.
+//
+// http://www.freedesktop.org/software/systemd/man/systemd-journald.service.html
+package journal
+
+import (
+ "errors"
+)
+
+func Enabled() bool {
+ return false
+}
+
+func Send(message string, priority Priority, vars map[string]string) error {
+ return errors.New("could not initialize socket to journald")
+}
diff --git a/vendor/github.com/coreos/go-systemd/v22/sdjournal/journal.go b/vendor/github.com/coreos/go-systemd/v22/sdjournal/journal.go
index 7f840def8..344016ebe 100644
--- a/vendor/github.com/coreos/go-systemd/v22/sdjournal/journal.go
+++ b/vendor/github.com/coreos/go-systemd/v22/sdjournal/journal.go
@@ -300,6 +300,24 @@ package sdjournal
// return sd_journal_get_catalog(j, ret);
// }
//
+// int
+// my_sd_id128_get_boot(void *f, sd_id128_t *boot_id)
+// {
+// int(*sd_id128_get_boot)(sd_id128_t *);
+//
+// sd_id128_get_boot = f;
+// return sd_id128_get_boot(boot_id);
+// }
+//
+// char *
+// my_sd_id128_to_string(void *f, sd_id128_t boot_id, char s[SD_ID128_STRING_MAX])
+// {
+// char *(*sd_id128_to_string)(sd_id128_t, char *);
+//
+// sd_id128_to_string = f;
+// return sd_id128_to_string(boot_id, s);
+// }
+//
import "C"
import (
"bytes"
@@ -928,7 +946,7 @@ func (j *Journal) SeekHead() error {
}
// SeekTail may be used to seek to the end of the journal, i.e. the most recent
-// available entry. This call must be followed by a call to Next before any
+// available entry. This call must be followed by a call to Previous before any
// call to Get* will return data about the last element.
func (j *Journal) SeekTail() error {
sd_journal_seek_tail, err := getFunction("sd_journal_seek_tail")
@@ -1118,3 +1136,34 @@ func (j *Journal) GetCatalog() (string, error) {
return catalog, nil
}
+
+// GetBootID get systemd boot id
+func (j *Journal) GetBootID() (string, error) {
+ sd_id128_get_boot, err := getFunction("sd_id128_get_boot")
+ if err != nil {
+ return "", err
+ }
+
+ var boot_id C.sd_id128_t
+ r := C.my_sd_id128_get_boot(sd_id128_get_boot, &boot_id)
+ if r < 0 {
+ return "", fmt.Errorf("failed to get boot id: %s", syscall.Errno(-r).Error())
+ }
+
+ sd_id128_to_string, err := getFunction("sd_id128_to_string")
+ if err != nil {
+ return "", err
+ }
+
+ id128StringMax := C.ulong(C.SD_ID128_STRING_MAX)
+ c := (*C.char)(C.malloc(id128StringMax))
+ defer C.free(unsafe.Pointer(c))
+ C.my_sd_id128_to_string(sd_id128_to_string, boot_id, c)
+
+ bootID := C.GoString(c)
+ if len(bootID) <= 0 {
+ return "", fmt.Errorf("get boot id %s is not valid", bootID)
+ }
+
+ return bootID, nil
+}
diff --git a/vendor/github.com/syndtr/gocapability/capability/enum.go b/vendor/github.com/syndtr/gocapability/capability/enum.go
index 693817317..ad1078531 100644
--- a/vendor/github.com/syndtr/gocapability/capability/enum.go
+++ b/vendor/github.com/syndtr/gocapability/capability/enum.go
@@ -41,7 +41,9 @@ const (
//go:generate go run enumgen/gen.go
type Cap int
-// POSIX-draft defined capabilities.
+// POSIX-draft defined capabilities and Linux extensions.
+//
+// Defined in https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h
const (
// In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this
// overrides the restriction of changing file ownership and group
@@ -187,6 +189,7 @@ const (
// arbitrary SCSI commands
// Allow setting encryption key on loopback filesystem
// Allow setting zone reclaim policy
+ // Allow everything under CAP_BPF and CAP_PERFMON for backward compatibility
CAP_SYS_ADMIN = Cap(21)
// Allow use of reboot()
@@ -211,6 +214,7 @@ const (
// Allow more than 64hz interrupts from the real-time clock
// Override max number of consoles on console allocation
// Override max number of keymaps
+ // Control memory reclaim behavior
CAP_SYS_RESOURCE = Cap(24)
// Allow manipulation of system clock
@@ -256,8 +260,45 @@ const (
// Allow preventing system suspends
CAP_BLOCK_SUSPEND = Cap(36)
- // Allow reading audit messages from the kernel
+ // Allow reading the audit log via multicast netlink socket
CAP_AUDIT_READ = Cap(37)
+
+ // Allow system performance and observability privileged operations
+ // using perf_events, i915_perf and other kernel subsystems
+ CAP_PERFMON = Cap(38)
+
+ // CAP_BPF allows the following BPF operations:
+ // - Creating all types of BPF maps
+ // - Advanced verifier features
+ // - Indirect variable access
+ // - Bounded loops
+ // - BPF to BPF function calls
+ // - Scalar precision tracking
+ // - Larger complexity limits
+ // - Dead code elimination
+ // - And potentially other features
+ // - Loading BPF Type Format (BTF) data
+ // - Retrieve xlated and JITed code of BPF programs
+ // - Use bpf_spin_lock() helper
+ //
+ // CAP_PERFMON relaxes the verifier checks further:
+ // - BPF progs can use of pointer-to-integer conversions
+ // - speculation attack hardening measures are bypassed
+ // - bpf_probe_read to read arbitrary kernel memory is allowed
+ // - bpf_trace_printk to print kernel memory is allowed
+ //
+ // CAP_SYS_ADMIN is required to use bpf_probe_write_user.
+ //
+ // CAP_SYS_ADMIN is required to iterate system wide loaded
+ // programs, maps, links, BTFs and convert their IDs to file descriptors.
+ //
+ // CAP_PERFMON and CAP_BPF are required to load tracing programs.
+ // CAP_NET_ADMIN and CAP_BPF are required to load networking programs.
+ CAP_BPF = Cap(39)
+
+ // Allow checkpoint/restore related operations.
+ // Introduced in kernel 5.9
+ CAP_CHECKPOINT_RESTORE = Cap(40)
)
var (
diff --git a/vendor/github.com/syndtr/gocapability/capability/enum_gen.go b/vendor/github.com/syndtr/gocapability/capability/enum_gen.go
index b9e6d2d5e..2ff9bf4d8 100644
--- a/vendor/github.com/syndtr/gocapability/capability/enum_gen.go
+++ b/vendor/github.com/syndtr/gocapability/capability/enum_gen.go
@@ -80,6 +80,12 @@ func (c Cap) String() string {
return "block_suspend"
case CAP_AUDIT_READ:
return "audit_read"
+ case CAP_PERFMON:
+ return "perfmon"
+ case CAP_BPF:
+ return "bpf"
+ case CAP_CHECKPOINT_RESTORE:
+ return "checkpoint_restore"
}
return "unknown"
}
@@ -125,5 +131,8 @@ func List() []Cap {
CAP_WAKE_ALARM,
CAP_BLOCK_SUSPEND,
CAP_AUDIT_READ,
+ CAP_PERFMON,
+ CAP_BPF,
+ CAP_CHECKPOINT_RESTORE,
}
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 28cf409ee..02c5d7867 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -93,7 +93,7 @@ github.com/containers/buildah/pkg/parse
github.com/containers/buildah/pkg/rusage
github.com/containers/buildah/pkg/supplemented
github.com/containers/buildah/util
-# github.com/containers/common v0.35.0
+# github.com/containers/common v0.35.3
github.com/containers/common/pkg/apparmor
github.com/containers/common/pkg/apparmor/internal/supported
github.com/containers/common/pkg/auth
@@ -115,7 +115,7 @@ github.com/containers/common/pkg/umask
github.com/containers/common/version
# github.com/containers/conmon v2.0.20+incompatible
github.com/containers/conmon/runner/config
-# github.com/containers/image/v5 v5.10.2
+# github.com/containers/image/v5 v5.10.5
github.com/containers/image/v5/copy
github.com/containers/image/v5/directory
github.com/containers/image/v5/directory/explicitfilepath
@@ -233,7 +233,7 @@ github.com/containers/storage/types
github.com/coreos/go-iptables/iptables
# github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e
github.com/coreos/go-systemd/activation
-# github.com/coreos/go-systemd/v22 v22.1.0
+# github.com/coreos/go-systemd/v22 v22.3.0
github.com/coreos/go-systemd/v22/activation
github.com/coreos/go-systemd/v22/daemon
github.com/coreos/go-systemd/v22/dbus
@@ -547,7 +547,7 @@ github.com/stefanberger/go-pkcs11uri
# github.com/stretchr/testify v1.7.0
github.com/stretchr/testify/assert
github.com/stretchr/testify/require
-# github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 => github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
+# github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
github.com/syndtr/gocapability/capability
# github.com/tchap/go-patricia v2.3.0+incompatible
github.com/tchap/go-patricia/patricia
@@ -750,7 +750,7 @@ gopkg.in/tomb.v1
gopkg.in/yaml.v2
# gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
gopkg.in/yaml.v3
-# k8s.io/api v0.20.1
+# k8s.io/api v0.20.5
k8s.io/api/apps/v1
k8s.io/api/core/v1
# k8s.io/apimachinery v0.20.5