diff options
66 files changed, 692 insertions, 289 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index ebe12ab4a..1eb516d84 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -30,7 +30,7 @@ env: PRIOR_UBUNTU_NAME: "ubuntu-2010" # Google-cloud VM Images - IMAGE_SUFFIX: "c6032583541653504" + IMAGE_SUFFIX: "c5348179051806720" FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}" PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}" UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${IMAGE_SUFFIX}" diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 8fd51b5e9..d6f92873e 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/stale@v1 + - uses: actions/stale@v3 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 'A friendly reminder that this issue had no activity for 30 days.' diff --git a/cmd/podman/common/util.go b/cmd/podman/common/util.go index 2a8b2040c..afee55914 100644 --- a/cmd/podman/common/util.go +++ b/cmd/podman/common/util.go @@ -35,6 +35,21 @@ func ReadPodIDFiles(files []string) ([]string, error) { return ids, nil } +// ParseFilters transforms one filter format to another and validates input +func ParseFilters(filter []string) (map[string][]string, error) { + // TODO Remove once filter refactor is finished and url.Values done. + filters := map[string][]string{} + for _, f := range filter { + t := strings.SplitN(f, "=", 2) + filters = make(map[string][]string) + if len(t) < 2 { + return map[string][]string{}, errors.Errorf("filter input must be in the form of filter=value: %s is invalid", f) + } + filters[t[0]] = append(filters[t[0]], t[1]) + } + return filters, nil +} + // createExpose parses user-provided exposed port definitions and converts them // into SpecGen format. // TODO: The SpecGen format should really handle ranges more sanely - we could diff --git a/cmd/podman/containers/prune.go b/cmd/podman/containers/prune.go index 9acf5589b..837d90f70 100644 --- a/cmd/podman/containers/prune.go +++ b/cmd/podman/containers/prune.go @@ -4,16 +4,15 @@ import ( "bufio" "context" "fmt" - "net/url" "os" "strings" "github.com/containers/common/pkg/completion" + "github.com/containers/podman/v3/cmd/podman/common" "github.com/containers/podman/v3/cmd/podman/registry" "github.com/containers/podman/v3/cmd/podman/utils" "github.com/containers/podman/v3/cmd/podman/validate" "github.com/containers/podman/v3/pkg/domain/entities" - "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -50,6 +49,7 @@ func init() { func prune(cmd *cobra.Command, args []string) error { var ( pruneOptions = entities.ContainerPruneOptions{} + err error ) if !force { reader := bufio.NewReader(os.Stdin) @@ -64,14 +64,9 @@ func prune(cmd *cobra.Command, args []string) error { } } - // TODO Remove once filter refactor is finished and url.Values done. - for _, f := range filter { - t := strings.SplitN(f, "=", 2) - pruneOptions.Filters = make(url.Values) - if len(t) < 2 { - return errors.Errorf("filter input must be in the form of filter=value: %s is invalid", f) - } - pruneOptions.Filters.Add(t[0], t[1]) + pruneOptions.Filters, err = common.ParseFilters(filter) + if err != nil { + return err } responses, err := registry.ContainerEngine().ContainerPrune(context.Background(), pruneOptions) diff --git a/cmd/podman/networks/prune.go b/cmd/podman/networks/prune.go index ebba06db5..bcc55f0f4 100644 --- a/cmd/podman/networks/prune.go +++ b/cmd/podman/networks/prune.go @@ -6,6 +6,7 @@ import ( "os" "strings" + "github.com/containers/common/pkg/completion" "github.com/containers/podman/v3/cmd/podman/common" "github.com/containers/podman/v3/cmd/podman/registry" "github.com/containers/podman/v3/cmd/podman/utils" @@ -31,12 +32,14 @@ var ( var ( networkPruneOptions entities.NetworkPruneOptions force bool + filter = []string{} ) -func networkPruneFlags(flags *pflag.FlagSet) { - //TODO: Not implemented but for future reference - //flags.StringSliceVar(&networkPruneOptions.Filters,"filters", []string{}, "provide filter values (e.g. 'until=<timestamp>')") +func networkPruneFlags(cmd *cobra.Command, flags *pflag.FlagSet) { flags.BoolVarP(&force, "force", "f", false, "do not prompt for confirmation") + filterFlagName := "filter" + flags.StringArrayVar(&filter, filterFlagName, []string{}, "Provide filter values (e.g. 'label=<key>=<value>')") + _ = cmd.RegisterFlagCompletionFunc(filterFlagName, completion.AutocompleteNone) } func init() { @@ -46,12 +49,13 @@ func init() { Parent: networkCmd, }) flags := networkPruneCommand.Flags() - networkPruneFlags(flags) + networkPruneFlags(networkPruneCommand, flags) } func networkPrune(cmd *cobra.Command, _ []string) error { var ( errs utils.OutputErrors + err error ) if !force { reader := bufio.NewReader(os.Stdin) @@ -65,6 +69,10 @@ func networkPrune(cmd *cobra.Command, _ []string) error { return nil } } + networkPruneOptions.Filters, err = common.ParseFilters(filter) + if err != nil { + return err + } responses, err := registry.ContainerEngine().NetworkPrune(registry.Context(), networkPruneOptions) if err != nil { setExitCode(err) diff --git a/cmd/podman/networks/reload.go b/cmd/podman/networks/reload.go index 8f2fbf011..035e56a07 100644 --- a/cmd/podman/networks/reload.go +++ b/cmd/podman/networks/reload.go @@ -26,9 +26,6 @@ var ( Example: `podman network reload --latest podman network reload 3c13ef6dd843 podman network reload test1 test2`, - Annotations: map[string]string{ - registry.ParentNSRequired: "", - }, } ) diff --git a/cmd/podman/system/info.go b/cmd/podman/system/info.go index afd5b3a34..44be4ccec 100644 --- a/cmd/podman/system/info.go +++ b/cmd/podman/system/info.go @@ -78,6 +78,8 @@ func info(cmd *cobra.Command, args []string) error { return err } + info.Host.ServiceIsRemote = registry.IsRemote() + switch { case report.IsJSON(inFormat): b, err := json.MarshalIndent(info, "", " ") diff --git a/contrib/systemd/auto-update/podman-auto-update.service b/contrib/systemd/auto-update/podman-auto-update.service index 068dab95b..9376db225 100644 --- a/contrib/systemd/auto-update/podman-auto-update.service +++ b/contrib/systemd/auto-update/podman-auto-update.service @@ -7,6 +7,7 @@ After=network-online.target [Service] Type=oneshot ExecStart=/usr/bin/podman auto-update +ExecStartPost=/usr/bin/podman image prune -f [Install] WantedBy=multi-user.target default.target diff --git a/docs/source/Introduction.rst b/docs/source/Introduction.rst index 3fa86f868..5c8713d27 100644 --- a/docs/source/Introduction.rst +++ b/docs/source/Introduction.rst @@ -2,7 +2,7 @@ Introduction ================================== -Containers_ simplify the consumption of applications with all of their dependencies and default configuration files. Users test drive or deploy a new application with one or two commands instead of following pages of installation instructions. Here's how to find your first `Container Image`_:: +Containers_ simplify the production, distribution, discoverability, and usage of applications with all of their dependencies and default configuration files. Users test drive or deploy a new application with one or two commands instead of following pages of installation instructions. Here's how to find your first `Container Image`_:: podman search busybox diff --git a/docs/source/conf.py b/docs/source/conf.py index 7a180e5ef..8210022f2 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -29,10 +29,7 @@ author = "team" # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = [ - "sphinx_markdown_tables", - "recommonmark" -] +extensions = ["sphinx_markdown_tables", "recommonmark"] # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] @@ -66,26 +63,27 @@ html_css_files = [ # -- Extension configuration ------------------------------------------------- + def convert_markdown_title(app, docname, source): # Process markdown files only docpath = app.env.doc2path(docname) if docpath.endswith(".md"): # Convert pandoc title line into eval_rst block for recommonmark - source[0] = re.sub( - r"^% (.*)", - r"```eval_rst\n.. title:: \g<1>\n```", - source[0]) + source[0] = re.sub(r"^% (.*)", r"```eval_rst\n.. title:: \g<1>\n```", source[0]) def setup(app): app.connect("source-read", convert_markdown_title) app.add_config_value( - "recommonmark_config", { + "recommonmark_config", + { "enable_eval_rst": True, "enable_auto_doc_ref": False, "enable_auto_toc_tree": False, "enable_math": False, "enable_inline_math": False, - }, True) + }, + True, + ) app.add_transform(AutoStructify) diff --git a/docs/source/markdown/podman-network-ls.1.md b/docs/source/markdown/podman-network-ls.1.md index a5c6ff0c0..b7fd13ec6 100644 --- a/docs/source/markdown/podman-network-ls.1.md +++ b/docs/source/markdown/podman-network-ls.1.md @@ -13,7 +13,7 @@ Displays a list of existing podman networks. #### **--filter**, **-f** Filter output based on conditions given. -Multiple filters can be given with multiple uses of the --filter flag. +Multiple filters can be given with multiple uses of the --filter option. Filters with the same key work inclusive with the only exception being `label` which is exclusive. Filters with different keys always work exclusive. diff --git a/docs/source/markdown/podman-network-prune.1.md b/docs/source/markdown/podman-network-prune.1.md index af0a7295d..e18ffaaea 100644 --- a/docs/source/markdown/podman-network-prune.1.md +++ b/docs/source/markdown/podman-network-prune.1.md @@ -16,6 +16,20 @@ the so-called default network which goes by the name of *podman*. Do not prompt for confirmation +#### **--filter** + +Filter output based on conditions given. +Multiple filters can be given with multiple uses of the --filter option. +Filters with the same key work inclusive with the only exception being +`label` which is exclusive. Filters with different keys always work exclusive. + +Valid filters are listed below: + +| **Filter** | **Description** | +| ---------- | ------------------------------------------------------------------------------------- | +| label | [Key] or [Key=Value] Label assigned to a network | +| until | only remove networks created before given timestamp | + ## EXAMPLE Prune networks diff --git a/docs/tutorials/basic_networking.md b/docs/tutorials/basic_networking.md index 51dfa7564..850bf6681 100644 --- a/docs/tutorials/basic_networking.md +++ b/docs/tutorials/basic_networking.md @@ -87,12 +87,16 @@ network, and the one will be created as a bridge network. $ podman network create ``` -When rootless containers are run with a CNI networking configuration, a “side-car” -container for running CNI is also run. Do not remove this container while your rootless -containers are running. if you remove this container (e.g by accident) all attached -containers lose network connectivity. In order to restore the network connectivity -all containers with networks must be restarted. This will automatically recreate -the "side-car" container. For rootfull containers, there is no “side-car” container +When rootless containers are run with a CNI networking configuration, CNI operations +will be executed inside an extra network namespace. To join this namespace, use +`podman unshare --rootless-cni`. Podman version 3.1 and earlier use a special “side-car” +container called rootless-cni-infra. Do not remove this container while your rootless +containers are running. If you remove this container (e.g. by accident), all attached +containers lose network connectivity. In order to restore the network connectivity, all +containers with networks must be restarted. This will automatically recreate the "side-car" +container. When you are using version 3.2 or newer the “side-car” container can be +safely removed. Therefore, it is no longer used. +For rootfull containers, there is no extra namespace or “side-car” container as rootfull users have the permissions to create and modify network interfaces on the host. @@ -12,12 +12,12 @@ require ( github.com/containernetworking/cni v0.8.1 github.com/containernetworking/plugins v0.9.1 github.com/containers/buildah v1.20.2-0.20210504130217-903dc56408ac - github.com/containers/common v0.37.2-0.20210503193405-42134aa138ce + github.com/containers/common v0.38.1-0.20210510140555-24645399a050 github.com/containers/conmon v2.0.20+incompatible github.com/containers/image/v5 v5.12.0 github.com/containers/ocicrypt v1.1.1 github.com/containers/psgo v1.5.2 - github.com/containers/storage v1.30.2 + github.com/containers/storage v1.30.3 github.com/coreos/go-systemd/v22 v22.3.2 github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3 github.com/cri-o/ocicni v0.2.1-0.20210301205850-541cf7c703cf @@ -49,7 +49,7 @@ require ( github.com/opencontainers/runc v1.0.0-rc94 github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 github.com/opencontainers/runtime-tools v0.9.0 - github.com/opencontainers/selinux v1.8.0 + github.com/opencontainers/selinux v1.8.1 github.com/pkg/errors v0.9.1 github.com/pmezard/go-difflib v1.0.0 github.com/rootless-containers/rootlesskit v0.14.2 @@ -197,8 +197,9 @@ github.com/containernetworking/plugins v0.9.1 h1:FD1tADPls2EEi3flPc2OegIY1M9pUa9 github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= github.com/containers/buildah v1.20.2-0.20210504130217-903dc56408ac h1:rPQTF+1lz+F4uTZgfk2pwqGcEEg9mPSWK58UncsqsrA= github.com/containers/buildah v1.20.2-0.20210504130217-903dc56408ac/go.mod h1:0hqcxPCNk/lit/SwBQoXXymCbp2LUa07U0cwrn/T1c0= -github.com/containers/common v0.37.2-0.20210503193405-42134aa138ce h1:e7VNmGqwfUQkw+D5bms262x1HYqxfN9/+t5SoaFnwTk= github.com/containers/common v0.37.2-0.20210503193405-42134aa138ce/go.mod h1:JjU+yvzIGyx8ZsY8nyf7snzs4VSNh1eIaYsqoSKBoRw= +github.com/containers/common v0.38.1-0.20210510140555-24645399a050 h1:o3UdnXpzCmJwto4y+addBH2NXZObuZ0tXA7COZXNMnQ= +github.com/containers/common v0.38.1-0.20210510140555-24645399a050/go.mod h1:64dWQkAgrd2cxVh9eDOxJ/IgPOulVFg6G7WLRDTrAuA= 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.11.1/go.mod h1:HC9lhJ/Nz5v3w/5Co7H431kLlgzlVlOC+auD/er3OqE= @@ -215,8 +216,9 @@ 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.29.0/go.mod h1:u84RU4CCufGeJBNTRNwMB+FoE+AiFeFw4SsMoqAOeCM= github.com/containers/storage v1.30.1/go.mod h1:NDJkiwxnSHD1Is+4DGcyR3SIEYSDOa0xnAW+uGQFx9E= -github.com/containers/storage v1.30.2 h1:qLYh970iu0x53n7A5nlZHO8XjfROfiyizkFyRy62Lpc= github.com/containers/storage v1.30.2/go.mod h1:hK/eetUA5afAZ+ZFZCXIY4eBAIo7XXmfNW476axZfgQ= +github.com/containers/storage v1.30.3 h1:DwX59C66vXwrwIafiMJbZxGIgrrZtQDAZBT/TsCS6mY= +github.com/containers/storage v1.30.3/go.mod h1:167Jo92jpTH5P+qfGblKFCb9kyYZwP2qxtpGczlFAP8= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= @@ -667,8 +669,9 @@ github.com/opencontainers/runtime-tools v0.9.0 h1:FYgwVsKRI/H9hU32MJ/4MLOzXWodKK github.com/opencontainers/runtime-tools v0.9.0/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= -github.com/opencontainers/selinux v1.8.0 h1:+77ba4ar4jsCbL1GLbFL8fFM57w6suPfSS9PDLDY7KM= github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= +github.com/opencontainers/selinux v1.8.1 h1:yvEZh7CsfnJNwKzG9ZeXwbvR05RAZsu5RS/3vA6qFTA= +github.com/opencontainers/selinux v1.8.1/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= github.com/openshift/imagebuilder v1.2.2-0.20210415181909-87f3e48c2656 h1:WaxyNFpmIDu4i6so9r6LVFIbSaXqsj8oitMitt86ae4= github.com/openshift/imagebuilder v1.2.2-0.20210415181909-87f3e48c2656/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo= github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913 h1:TnbXhKzrTOyuvWrjI8W6pcoI9XPbLHFXCdN2dtUw7Rw= diff --git a/hack/bats b/hack/bats new file mode 100755 index 000000000..45b8cf6f2 --- /dev/null +++ b/hack/bats @@ -0,0 +1,109 @@ +#!/bin/bash +# +# bats wrapper - invokes bats, root & rootless, on podman system tests +# + +############################################################################### +# BEGIN usage message + +usage="Usage: $0 [--root] [--rootless] [--filter=filename[:testname]] + +$0 is a wrapper for invoking podman system tests. + + --root Run only as root + --rootless Run only as user (i.e. you) + + --filter=name Run only test files that match 'test/system/*name*', + e.g. '500' or 'net' will match 500-networking.bats. + If ':pattern' is appended, and you have a modern-enough + version of bats installed, runs with '--filter pattern' + which runs only subtests that match 'pattern' + + --help display usage message + +By default, tests ./bin/podman. To test a different podman, do: + + \$ PODMAN=/abs/path/to/podman $0 .... + +To test podman-remote, start your own servers (root and rootless) via: + + /path/to/podman system service --timeout=0 + +...then invoke this script with PODMAN=\$(pwd)/bin/podman-remote + + (You'd think Ed could be bothered to do all that in this script; but then + the flow would be 'sudo start-service; sudo run-bats; sudo stop-service' + and by the time we get to stop-service, the sudo timeout will have lapsed, + and the script will be hanging at the password prompt, and you, who left + your desk for coffee or a walk and expected to come back to completed + root and rootless tests, will be irked because only root tests ran and + now you have to wait for rootless). + +$0 also passes through \$OCI_RUNTIME, should you need to test that. +" + +# END usage message +############################################################################### +# BEGIN initialization and command-line arg checking + +# By default, test the podman in our working directory. +# Some tests cd out of our workdir, so abs path is important +export PODMAN=${PODMAN:-$(pwd)/bin/podman} + +# Because 'make' doesn't do this by default +chcon -t container_runtime_exec_t $PODMAN + +# Directory in which +TESTS=test/system + +REMOTE= +ROOT_ONLY= +ROOTLESS_ONLY= + +declare -a bats_filter=() + +for i;do + value=`expr "$i" : '[^=]*=\(.*\)'` + case "$i" in + -h|--help) echo "$usage"; exit 0;; + --root) ROOT_ONLY=1 ;; + --rootless) ROOTLESS_ONLY=1 ;; + --remote) REMOTE=remote; echo "--remote is TBI"; exit 1;; + */*.bats) TESTS=$i ;; + *) + if [[ $i =~ : ]]; then + tname=${i%:*} # network:localhost -> network + filt=${i#*:} # network:localhost -> localhost + TESTS=$(echo $TESTS/*$tname*.bats) + bats_filter=("--filter" "$filt") + else + TESTS=$(echo $TESTS/*$i*.bats) + fi + ;; + esac +done + +# END initialization and command-line arg checking +############################################################################### + +rc=0 + +# Root +if [ -z "$ROOTLESS_ONLY" ]; then + echo "# bats ${bats_filter[@]} $TESTS" + sudo --preserve-env=PODMAN \ + --preserve-env=PODMAN_TEST_DEBUG \ + --preserve-env=OCI_RUNTIME \ + bats "${bats_filter[@]}" $TESTS + rc=$? +fi + +# Rootless +echo "--------------------------------------------------" +if [ -z "$ROOT_ONLY" ]; then + echo "\$ bats ${bats_filter[@]} $TESTS" + bats "${bats_filter[@]}" $TESTS + rc=$((rc | $?)) +fi + +exit $rc diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go index 4a541b6e7..ec4fa9724 100644 --- a/libpod/container_log_linux.go +++ b/libpod/container_log_linux.go @@ -8,12 +8,12 @@ import ( "fmt" "io" "math" + "strings" "time" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/logs" journal "github.com/coreos/go-systemd/v22/sdjournal" - "github.com/hpcloud/tail/watch" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -89,21 +89,19 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption } }() go func() { - for { - state, err := c.State() - if err != nil { - until <- time.Time{} - logrus.Error(err) - break - } - time.Sleep(watch.POLL_DURATION) - if state != define.ContainerStateRunning && state != define.ContainerStatePaused { - until <- time.Time{} - break - } - } + // FIXME (#10323): we are facing a terrible + // race condition here. At the time the + // container dies and `c.Wait()` has returned, + // we may not have received all journald logs. + // So far there is no other way than waiting + // for a second. Ultimately, `r.Follow` is + // racy and we may have to implement our custom + // logic here. + c.Wait(ctx) + time.Sleep(time.Second) + until <- time.Time{} }() - follower := FollowBuffer{logChannel} + follower := journaldFollowBuffer{logChannel, options.Multi} err := r.Follow(until, follower) if err != nil { logrus.Debugf(err.Error()) @@ -124,7 +122,7 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption // because we are reusing bytes, we need to make // sure the old data doesn't get into the new line bytestr := string(bytes[:ec]) - logLine, err2 := logs.NewLogLine(bytestr) + logLine, err2 := logs.NewJournaldLogLine(bytestr, options.Multi) if err2 != nil { logrus.Error(err2) continue @@ -210,16 +208,18 @@ func formatterMessage(entry *journal.JournalEntry) (string, error) { if !ok { return "", fmt.Errorf("no MESSAGE field present in journal entry") } + msg = strings.TrimSuffix(msg, "\n") return msg, nil } -type FollowBuffer struct { +type journaldFollowBuffer struct { logChannel chan *logs.LogLine + withID bool } -func (f FollowBuffer) Write(p []byte) (int, error) { +func (f journaldFollowBuffer) Write(p []byte) (int, error) { bytestr := string(p) - logLine, err := logs.NewLogLine(bytestr) + logLine, err := logs.NewJournaldLogLine(bytestr, f.withID) if err != nil { return -1, err } diff --git a/libpod/define/errors.go b/libpod/define/errors.go index 64c652eec..81bf5f69c 100644 --- a/libpod/define/errors.go +++ b/libpod/define/errors.go @@ -179,6 +179,9 @@ var ( // ErrNoNetwork indicates that a container has no net namespace, like network=none ErrNoNetwork = errors.New("container has no network namespace") + // ErrNetworkModeInvalid indicates that a container has the wrong network mode for an operation + ErrNetworkModeInvalid = errors.New("invalid network mode") + // ErrSetSecurityAttribute indicates that a request to set a container's security attribute // was not possible. ErrSetSecurityAttribute = fmt.Errorf("%w: unable to assign security attribute", ErrOCIRuntime) diff --git a/libpod/define/info.go b/libpod/define/info.go index 87935be2d..c9d6877c0 100644 --- a/libpod/define/info.go +++ b/libpod/define/info.go @@ -21,31 +21,34 @@ type SecurityInfo struct { SELinuxEnabled bool `json:"selinuxEnabled"` } -//HostInfo describes the libpod host +// HostInfo describes the libpod host type HostInfo struct { - Arch string `json:"arch"` - BuildahVersion string `json:"buildahVersion"` - CgroupManager string `json:"cgroupManager"` - CGroupsVersion string `json:"cgroupVersion"` - Conmon *ConmonInfo `json:"conmon"` - CPUs int `json:"cpus"` - Distribution DistributionInfo `json:"distribution"` - EventLogger string `json:"eventLogger"` - Hostname string `json:"hostname"` - IDMappings IDMappings `json:"idMappings,omitempty"` - Kernel string `json:"kernel"` - MemFree int64 `json:"memFree"` - MemTotal int64 `json:"memTotal"` - OCIRuntime *OCIRuntimeInfo `json:"ociRuntime"` - OS string `json:"os"` - RemoteSocket *RemoteSocket `json:"remoteSocket,omitempty"` - RuntimeInfo map[string]interface{} `json:"runtimeInfo,omitempty"` - Security SecurityInfo `json:"security"` - Slirp4NetNS SlirpInfo `json:"slirp4netns,omitempty"` - SwapFree int64 `json:"swapFree"` - SwapTotal int64 `json:"swapTotal"` - Uptime string `json:"uptime"` - Linkmode string `json:"linkmode"` + Arch string `json:"arch"` + BuildahVersion string `json:"buildahVersion"` + CgroupManager string `json:"cgroupManager"` + CGroupsVersion string `json:"cgroupVersion"` + Conmon *ConmonInfo `json:"conmon"` + CPUs int `json:"cpus"` + Distribution DistributionInfo `json:"distribution"` + EventLogger string `json:"eventLogger"` + Hostname string `json:"hostname"` + IDMappings IDMappings `json:"idMappings,omitempty"` + Kernel string `json:"kernel"` + MemFree int64 `json:"memFree"` + MemTotal int64 `json:"memTotal"` + OCIRuntime *OCIRuntimeInfo `json:"ociRuntime"` + OS string `json:"os"` + // RemoteSocket returns the UNIX domain socket the Podman service is listening on + RemoteSocket *RemoteSocket `json:"remoteSocket,omitempty"` + RuntimeInfo map[string]interface{} `json:"runtimeInfo,omitempty"` + // ServiceIsRemote is true when the podman/libpod service is remote to the client + ServiceIsRemote bool `json:"serviceIsRemote"` + Security SecurityInfo `json:"security"` + Slirp4NetNS SlirpInfo `json:"slirp4netns,omitempty"` + SwapFree int64 `json:"swapFree"` + SwapTotal int64 `json:"swapTotal"` + Uptime string `json:"uptime"` + Linkmode string `json:"linkmode"` } // RemoteSocket describes information about the API socket diff --git a/libpod/logs/log.go b/libpod/logs/log.go index bba52408d..308053b47 100644 --- a/libpod/logs/log.go +++ b/libpod/logs/log.go @@ -206,6 +206,36 @@ func NewLogLine(line string) (*LogLine, error) { return &l, nil } +// NewJournaldLogLine creates a LogLine from the specified line from journald. +// Note that if withID is set, the first item of the message is considerred to +// be the container ID and set as such. +func NewJournaldLogLine(line string, withID bool) (*LogLine, error) { + splitLine := strings.Split(line, " ") + if len(splitLine) < 4 { + return nil, errors.Errorf("'%s' is not a valid container log line", line) + } + logTime, err := time.Parse(LogTimeFormat, splitLine[0]) + if err != nil { + return nil, errors.Wrapf(err, "unable to convert time %s from container log", splitLine[0]) + } + var msg, id string + if withID { + id = splitLine[3] + msg = strings.Join(splitLine[4:], " ") + } else { + msg = strings.Join(splitLine[3:], " ") + // NO ID + } + l := LogLine{ + Time: logTime, + Device: splitLine[1], + ParseLogType: splitLine[2], + Msg: msg, + CID: id, + } + return &l, nil +} + // Partial returns a bool if the log line is a partial log type func (l *LogLine) Partial() bool { return l.ParseLogType == PartialLogType diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 1e763dac5..0e8a4f768 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -23,6 +23,7 @@ import ( "github.com/containers/podman/v3/libpod/events" "github.com/containers/podman/v3/libpod/network" "github.com/containers/podman/v3/pkg/errorhandling" + "github.com/containers/podman/v3/pkg/namespaces" "github.com/containers/podman/v3/pkg/netns" "github.com/containers/podman/v3/pkg/resolvconf" "github.com/containers/podman/v3/pkg/rootless" @@ -758,6 +759,15 @@ func getContainerNetNS(ctr *Container) (string, error) { return "", nil } +// isBridgeNetMode checks if the given network mode is bridge. +// It returns nil when it is set to bridge and an error otherwise. +func isBridgeNetMode(n namespaces.NetworkMode) error { + if !n.IsBridge() { + return errors.Wrapf(define.ErrNetworkModeInvalid, "%q is not supported", n) + } + return nil +} + // Reload only works with containers with a configured network. // It will tear down, and then reconfigure, the network of the container. // This is mainly used when a reload of firewall rules wipes out existing @@ -771,8 +781,8 @@ func (r *Runtime) reloadContainerNetwork(ctr *Container) ([]*cnitypes.Result, er if ctr.state.NetNS == nil { return nil, errors.Wrapf(define.ErrCtrStateInvalid, "container %s network is not configured, refusing to reload", ctr.ID()) } - if rootless.IsRootless() || ctr.config.NetMode.IsSlirp4netns() { - return nil, errors.Wrapf(define.ErrRootless, "network reload only supported for root containers") + if err := isBridgeNetMode(ctr.config.NetMode); err != nil { + return nil, err } logrus.Infof("Going to reload container %s network", ctr.ID()) @@ -1026,8 +1036,8 @@ func (w *logrusDebugWriter) Write(p []byte) (int, error) { // NetworkDisconnect removes a container from the network func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) error { // only the bridge mode supports cni networks - if !c.config.NetMode.IsBridge() { - return errors.Errorf("network mode %q is not supported", c.config.NetMode) + if err := isBridgeNetMode(c.config.NetMode); err != nil { + return err } networks, err := c.networksByNameIndex() @@ -1087,8 +1097,8 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro // ConnectNetwork connects a container to a given network func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) error { // only the bridge mode supports cni networks - if !c.config.NetMode.IsBridge() { - return errors.Errorf("network mode %q is not supported", c.config.NetMode) + if err := isBridgeNetMode(c.config.NetMode); err != nil { + return err } networks, err := c.networksByNameIndex() diff --git a/nix/nixpkgs.json b/nix/nixpkgs.json index 54ddb8978..9b8b8289e 100644 --- a/nix/nixpkgs.json +++ b/nix/nixpkgs.json @@ -1,9 +1,9 @@ { "url": "https://github.com/nixos/nixpkgs", - "rev": "cce26cd83d20356ee96ac9cf1de748e87fcc50b5", - "date": "2021-04-12T22:14:24+02:00", - "path": "/nix/store/0flgsv9kn7q0b2ipqz35lkxq65p5cv83-nixpkgs", - "sha256": "0ji00jz18fvppbi5y98gcalxq2mrsg7dhh9l64yf38jpb5rx3sd4", + "rev": "eb7e1ef185f6c990cda5f71fdc4fb02e76ab06d5", + "date": "2021-05-05T23:16:00+02:00", + "path": "/nix/store/a98lkhjlsqh32ic2kkrv5kkik6jy25wh-nixpkgs", + "sha256": "1ibz204c41g7baqga2iaj11yz9l75cfdylkiqjnk5igm81ivivxg", "fetchSubmodules": false, "deepClone": false, "leaveDotGit": false diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go index 1a833332c..33ab280e5 100644 --- a/pkg/domain/infra/abi/network.go +++ b/pkg/domain/infra/abi/network.go @@ -71,7 +71,9 @@ func (ic *ContainerEngine) NetworkReload(ctx context.Context, names []string, op report := new(entities.NetworkReloadReport) report.Id = ctr.ID() report.Err = ctr.ReloadNetwork() - if options.All && errors.Cause(report.Err) == define.ErrCtrStateInvalid { + // ignore errors for invalid ctr state and network mode when --all is used + if options.All && (errors.Cause(report.Err) == define.ErrCtrStateInvalid || + errors.Cause(report.Err) == define.ErrNetworkModeInvalid) { continue } reports = append(reports, report) diff --git a/pkg/machine/pull.go b/pkg/machine/pull.go index d9f34057f..68bb551dc 100644 --- a/pkg/machine/pull.go +++ b/pkg/machine/pull.go @@ -162,7 +162,11 @@ func Decompress(localPath, uncompressedPath string) error { return err } - if compressionType := archive.DetectCompression(sourceFile); compressionType.Extension() == "tar.xz" { + compressionType := archive.DetectCompression(sourceFile) + if compressionType != archive.Uncompressed { + fmt.Println("Extracting compressed file") + } + if compressionType == archive.Xz { return decompressXZ(localPath, uncompressedFileWriter) } return decompressEverythingElse(localPath, uncompressedFileWriter) @@ -172,7 +176,6 @@ func Decompress(localPath, uncompressedPath string) error { // Maybe extracting then renameing is a good idea here.. // depends on xz: not pre-installed on mac, so it becomes a brew dependency func decompressXZ(src string, output io.Writer) error { - fmt.Println("Extracting compressed file") cmd := exec.Command("xzcat", "-k", src) //cmd := exec.Command("xz", "-d", "-k", "-v", src) stdOut, err := cmd.StdoutPipe() @@ -190,7 +193,6 @@ func decompressXZ(src string, output io.Writer) error { } func decompressEverythingElse(src string, output io.Writer) error { - fmt.Println("Extracting compressed file") f, err := os.Open(src) if err != nil { return err diff --git a/test/e2e/create_staticip_test.go b/test/e2e/create_staticip_test.go index 340ea31f3..2cf552274 100644 --- a/test/e2e/create_staticip_test.go +++ b/test/e2e/create_staticip_test.go @@ -60,8 +60,10 @@ var _ = Describe("Podman create with --ip flag", func() { }) It("Podman create with specified static IP has correct IP", func() { + // NOTE: we force the k8s-file log driver to make sure the + // tests are passing inside a container. ip := GetRandomIPAddress() - result := podmanTest.Podman([]string{"create", "--name", "test", "--ip", ip, ALPINE, "ip", "addr"}) + result := podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--ip", ip, ALPINE, "ip", "addr"}) result.WaitWithDefaultTimeout() // Rootless static ip assignment without network should error if rootless.IsRootless() { @@ -83,10 +85,10 @@ var _ = Describe("Podman create with --ip flag", func() { It("Podman create two containers with the same IP", func() { SkipIfRootless("--ip not supported without network in rootless mode") ip := GetRandomIPAddress() - result := podmanTest.Podman([]string{"create", "--name", "test1", "--ip", ip, ALPINE, "sleep", "999"}) + result := podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test1", "--ip", ip, ALPINE, "sleep", "999"}) result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Equal(0)) - result = podmanTest.Podman([]string{"create", "--name", "test2", "--ip", ip, ALPINE, "ip", "addr"}) + result = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test2", "--ip", ip, ALPINE, "ip", "addr"}) result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Equal(0)) result = podmanTest.Podman([]string{"start", "test1"}) diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go index 1f1786dbe..e4db6b845 100644 --- a/test/e2e/create_test.go +++ b/test/e2e/create_test.go @@ -160,9 +160,12 @@ var _ = Describe("Podman create", func() { if podmanTest.Host.Arch == "ppc64le" { Skip("skip failing test on ppc64le") } + // NOTE: we force the k8s-file log driver to make sure the + // tests are passing inside a container. + mountPath := filepath.Join(podmanTest.TempDir, "secrets") os.Mkdir(mountPath, 0755) - session := podmanTest.Podman([]string{"create", "--name", "test", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) + session := podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"start", "test"}) @@ -173,7 +176,7 @@ var _ = Describe("Podman create", func() { Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring("/create/test rw")) - session = podmanTest.Podman([]string{"create", "--name", "test_ro", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test,ro", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) + session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test_ro", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test,ro", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"start", "test_ro"}) @@ -184,7 +187,7 @@ var _ = Describe("Podman create", func() { Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring("/create/test ro")) - session = podmanTest.Podman([]string{"create", "--name", "test_shared", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test,shared", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) + session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test_shared", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test,shared", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"start", "test_shared"}) @@ -200,7 +203,7 @@ var _ = Describe("Podman create", func() { mountPath = filepath.Join(podmanTest.TempDir, "scratchpad") os.Mkdir(mountPath, 0755) - session = podmanTest.Podman([]string{"create", "--name", "test_tmpfs", "--mount", "type=tmpfs,target=/create/test", ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) + session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test_tmpfs", "--mount", "type=tmpfs,target=/create/test", ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"start", "test_tmpfs"}) diff --git a/test/e2e/info_test.go b/test/e2e/info_test.go index 0b112b312..60136bcc2 100644 --- a/test/e2e/info_test.go +++ b/test/e2e/info_test.go @@ -124,4 +124,15 @@ var _ = Describe("Podman Info", func() { } }) + It("verify ServiceIsRemote", func() { + session := podmanTest.Podman([]string{"info", "--format", "{{.Host.ServiceIsRemote}}"}) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + + if podmanTest.RemoteTest { + Expect(session.OutputToString()).To(ContainSubstring("true")) + } else { + Expect(session.OutputToString()).To(ContainSubstring("false")) + } + }) }) diff --git a/test/e2e/network_connect_disconnect_test.go b/test/e2e/network_connect_disconnect_test.go index 6974c7614..c82aacbe4 100644 --- a/test/e2e/network_connect_disconnect_test.go +++ b/test/e2e/network_connect_disconnect_test.go @@ -66,7 +66,7 @@ var _ = Describe("Podman network connect and disconnect", func() { con := podmanTest.Podman([]string{"network", "disconnect", netName, "test"}) con.WaitWithDefaultTimeout() Expect(con.ExitCode()).ToNot(BeZero()) - Expect(con.ErrorToString()).To(ContainSubstring(`network mode "slirp4netns" is not supported`)) + Expect(con.ErrorToString()).To(ContainSubstring(`"slirp4netns" is not supported: invalid network mode`)) }) It("podman network disconnect", func() { @@ -132,7 +132,7 @@ var _ = Describe("Podman network connect and disconnect", func() { con := podmanTest.Podman([]string{"network", "connect", netName, "test"}) con.WaitWithDefaultTimeout() Expect(con.ExitCode()).ToNot(BeZero()) - Expect(con.ErrorToString()).To(ContainSubstring(`network mode "slirp4netns" is not supported`)) + Expect(con.ErrorToString()).To(ContainSubstring(`"slirp4netns" is not supported: invalid network mode`)) }) It("podman connect on a container that already is connected to the network should error", func() { diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go index ff2e1eb66..6f28d7e19 100644 --- a/test/e2e/network_test.go +++ b/test/e2e/network_test.go @@ -584,6 +584,52 @@ var _ = Describe("Podman network", func() { Expect(nc.ExitCode()).To(Equal(0)) }) + It("podman network prune --filter", func() { + net1 := "macvlan" + stringid.GenerateNonCryptoID() + "net1" + + nc := podmanTest.Podman([]string{"network", "create", net1}) + nc.WaitWithDefaultTimeout() + defer podmanTest.removeCNINetwork(net1) + Expect(nc.ExitCode()).To(Equal(0)) + + list := podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}}"}) + list.WaitWithDefaultTimeout() + Expect(list.ExitCode()).To(BeZero()) + + Expect(StringInSlice(net1, list.OutputToStringArray())).To(BeTrue()) + if !isRootless() { + Expect(StringInSlice("podman", list.OutputToStringArray())).To(BeTrue()) + } + + // -f needed only to skip y/n question + prune := podmanTest.Podman([]string{"network", "prune", "-f", "--filter", "until=50"}) + prune.WaitWithDefaultTimeout() + Expect(prune.ExitCode()).To(BeZero()) + + listAgain := podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}}"}) + listAgain.WaitWithDefaultTimeout() + Expect(listAgain.ExitCode()).To(BeZero()) + + Expect(StringInSlice(net1, listAgain.OutputToStringArray())).To(BeTrue()) + if !isRootless() { + Expect(StringInSlice("podman", list.OutputToStringArray())).To(BeTrue()) + } + + // -f needed only to skip y/n question + prune = podmanTest.Podman([]string{"network", "prune", "-f", "--filter", "until=5000000000000"}) + prune.WaitWithDefaultTimeout() + Expect(prune.ExitCode()).To(BeZero()) + + listAgain = podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}}"}) + listAgain.WaitWithDefaultTimeout() + Expect(listAgain.ExitCode()).To(BeZero()) + + Expect(StringInSlice(net1, listAgain.OutputToStringArray())).To(BeFalse()) + if !isRootless() { + Expect(StringInSlice("podman", list.OutputToStringArray())).To(BeTrue()) + } + }) + It("podman network prune", func() { // Create two networks // Check they are there diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index 4c66e2823..37e837b1d 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -649,11 +649,13 @@ var _ = Describe("Podman run networking", func() { defer podmanTest.removeCNINetwork(netName) name := "nc-server" - run := podmanTest.Podman([]string{"run", "-d", "--name", name, "--net", netName, ALPINE, "nc", "-l", "-p", "8080"}) + run := podmanTest.Podman([]string{"run", "--log-driver", "k8s-file", "-d", "--name", name, "--net", netName, ALPINE, "nc", "-l", "-p", "8080"}) run.WaitWithDefaultTimeout() Expect(run.ExitCode()).To(Equal(0)) - run = podmanTest.Podman([]string{"run", "--rm", "--net", netName, "--uidmap", "0:1:4096", ALPINE, "sh", "-c", fmt.Sprintf("echo podman | nc -w 1 %s.dns.podman 8080", name)}) + // NOTE: we force the k8s-file log driver to make sure the + // tests are passing inside a container. + run = podmanTest.Podman([]string{"run", "--log-driver", "k8s-file", "--rm", "--net", netName, "--uidmap", "0:1:4096", ALPINE, "sh", "-c", fmt.Sprintf("echo podman | nc -w 1 %s.dns.podman 8080", name)}) run.WaitWithDefaultTimeout() Expect(run.ExitCode()).To(Equal(0)) diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 59220cf01..f27ded5d2 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -712,7 +712,7 @@ USER bin`, BB) It("podman run log-opt", func() { log := filepath.Join(podmanTest.TempDir, "/container.log") - session := podmanTest.Podman([]string{"run", "--rm", "--log-opt", fmt.Sprintf("path=%s", log), ALPINE, "ls"}) + session := podmanTest.Podman([]string{"run", "--rm", "--log-driver", "k8s-file", "--log-opt", fmt.Sprintf("path=%s", log), ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) _, err := os.Stat(log) diff --git a/test/e2e/toolbox_test.go b/test/e2e/toolbox_test.go index 986f856bf..16300bebc 100644 --- a/test/e2e/toolbox_test.go +++ b/test/e2e/toolbox_test.go @@ -215,7 +215,7 @@ var _ = Describe("Toolbox-specific testing", func() { useradd := fmt.Sprintf("useradd --home-dir %s --shell %s --uid %s %s", homeDir, shell, uid, username) passwd := fmt.Sprintf("passwd --delete %s", username) - session = podmanTest.Podman([]string{"create", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", + session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", fmt.Sprintf("%s; %s; echo READY; sleep 1000", useradd, passwd)}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -250,7 +250,7 @@ var _ = Describe("Toolbox-specific testing", func() { groupadd := fmt.Sprintf("groupadd --gid %s %s", gid, groupName) - session = podmanTest.Podman([]string{"create", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", + session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", fmt.Sprintf("%s; echo READY; sleep 1000", groupadd)}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -294,7 +294,7 @@ var _ = Describe("Toolbox-specific testing", func() { usermod := fmt.Sprintf("usermod --append --groups wheel --home %s --shell %s --uid %s --gid %s %s", homeDir, shell, uid, gid, username) - session = podmanTest.Podman([]string{"create", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", + session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", fmt.Sprintf("%s; %s; %s; echo READY; sleep 1000", useradd, groupadd, usermod)}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -339,6 +339,7 @@ var _ = Describe("Toolbox-specific testing", func() { // These should be most of the switches that Toolbox uses to create a "toolbox" container // https://github.com/containers/toolbox/blob/master/src/cmd/create.go session = podmanTest.Podman([]string{"create", + "--log-driver", "k8s-file", "--dns", "none", "--hostname", "toolbox", "--ipc", "host", diff --git a/test/system/035-logs.bats b/test/system/035-logs.bats index bac153b8e..3dd88e5eb 100644 --- a/test/system/035-logs.bats +++ b/test/system/035-logs.bats @@ -27,13 +27,22 @@ load helpers run_podman rm $cid } -@test "podman logs - multi" { +function _log_test_multi() { + local driver=$1 + skip_if_remote "logs does not support multiple containers when run remotely" + # Under k8s file, 'podman logs' returns just the facts, Ma'am. + # Under journald, there may be other cruft (e.g. container removals) + local etc= + if [[ $driver =~ journal ]]; then + etc='.*' + fi + # Simple helper to make the container starts, below, easier to read local -a cid doit() { - run_podman run --rm -d --name "$1" $IMAGE sh -c "$2"; + run_podman run --log-driver=$driver --rm -d --name "$1" $IMAGE sh -c "$2"; cid+=($(echo "${output:0:12}")) } @@ -47,24 +56,21 @@ load helpers run_podman logs -f c1 c2 is "$output" \ - "${cid[0]} a -${cid[1]} b -${cid[1]} c + "${cid[0]} a$etc +${cid[1]} b$etc +${cid[1]} c$etc ${cid[0]} d" "Sequential output from logs" } -@test "podman logs over journald" { +@test "podman logs - multi k8s-file" { + _log_test_multi k8s-file +} + +@test "podman logs - multi journald" { # We can't use journald on RHEL as rootless: rhbz#1895105 skip_if_journald_unavailable - msg=$(random_string 20) - - run_podman run --name myctr --log-driver journald $IMAGE echo $msg - - run_podman logs myctr - is "$output" "$msg" "check that log output equals the container output" - - run_podman rm myctr + _log_test_multi journald } # vim: filetype=sh diff --git a/test/system/070-build.bats b/test/system/070-build.bats index a2c8ae588..d2d56c051 100644 --- a/test/system/070-build.bats +++ b/test/system/070-build.bats @@ -393,9 +393,9 @@ Labels.$label_name | $label_value "image tree: third line" is "${lines[3]}" "Image Layers" \ "image tree: fourth line" - is "${lines[4]}" ".* ID: [0-9a-f]\{12\} Size: .* Top Layer of: \[localhost/build_test:latest]" \ + is "${lines[4]}" ".* ID: [0-9a-f]\{12\} Size: .* Top Layer of: \[$IMAGE]" \ "image tree: first layer line" - is "${lines[-1]}" ".* ID: [0-9a-f]\{12\} Size: .* Top Layer of: \[$IMAGE]" \ + is "${lines[-1]}" ".* ID: [0-9a-f]\{12\} Size: .* Top Layer of: \[localhost/build_test:latest]" \ "image tree: last layer line" # FIXME: 'image tree --whatrequires' does not work via remote diff --git a/test/system/130-kill.bats b/test/system/130-kill.bats index 3770eac27..1b02b4976 100644 --- a/test/system/130-kill.bats +++ b/test/system/130-kill.bats @@ -8,7 +8,8 @@ load helpers @test "podman kill - test signal handling in containers" { # Start a container that will handle all signals by emitting 'got: N' local -a signals=(1 2 3 4 5 6 8 10 12 13 14 15 16 20 21 22 23 24 25 26 64) - run_podman run -d $IMAGE sh -c \ + # Force the k8s-file driver until #10323 is fixed. + run_podman run --log-driver=k8s-file -d $IMAGE sh -c \ "for i in ${signals[*]}; do trap \"echo got: \$i\" \$i; done; echo READY; while ! test -e /stop; do sleep 0.05; done; diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats index 654bd5d8a..1cec50827 100644 --- a/test/system/500-networking.bats +++ b/test/system/500-networking.bats @@ -236,7 +236,6 @@ load helpers @test "podman network reload" { skip_if_remote "podman network reload does not have remote support" - skip_if_rootless "podman network reload does not work rootless" random_1=$(random_string 30) HOST_PORT=12345 @@ -246,29 +245,42 @@ load helpers INDEX1=$PODMAN_TMPDIR/hello.txt echo $random_1 > $INDEX1 + # use default network for root + local netname=podman + # for rootless we have to create a custom network since there is no default network + if is_rootless; then + netname=testnet-$(random_string 10) + run_podman network create $netname + is "$output" ".*/cni/net.d/$netname.conflist" "output of 'network create'" + fi + # Bind-mount this file with a different name to a container running httpd run_podman run -d --name myweb -p "$HOST_PORT:80" \ - -v $INDEX1:/var/www/index.txt \ - -w /var/www \ - $IMAGE /bin/busybox-extras httpd -f -p 80 + --network $netname \ + -v $INDEX1:/var/www/index.txt \ + -w /var/www \ + $IMAGE /bin/busybox-extras httpd -f -p 80 cid=$output - run_podman inspect $cid --format "{{.NetworkSettings.IPAddress}}" + run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").IPAddress}}" ip="$output" - run_podman inspect $cid --format "{{.NetworkSettings.MacAddress}}" + run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").MacAddress}}" mac="$output" # Verify http contents: curl from localhost run curl -s $SERVER/index.txt is "$output" "$random_1" "curl 127.0.0.1:/index.txt" - # flush the CNI iptables here - run iptables -t nat -F CNI-HOSTPORT-DNAT + # rootless cannot modify iptables + if ! is_rootless; then + # flush the CNI iptables here + run iptables -t nat -F CNI-HOSTPORT-DNAT - # check that we cannot curl (timeout after 5 sec) - run timeout 5 curl -s $SERVER/index.txt - if [ "$status" -ne 124 ]; then - die "curl did not timeout, status code: $status" + # check that we cannot curl (timeout after 5 sec) + run timeout 5 curl -s $SERVER/index.txt + if [ "$status" -ne 124 ]; then + die "curl did not timeout, status code: $status" + fi fi # reload the network to recreate the iptables rules @@ -276,9 +288,9 @@ load helpers is "$output" "$cid" "Output does not match container ID" # check that we still have the same mac and ip - run_podman inspect $cid --format "{{.NetworkSettings.IPAddress}}" + run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").IPAddress}}" is "$output" "$ip" "IP address changed after podman network reload" - run_podman inspect $cid --format "{{.NetworkSettings.MacAddress}}" + run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").MacAddress}}" is "$output" "$mac" "MAC address changed after podman network reload" # check that we can still curl @@ -296,6 +308,10 @@ load helpers # cleanup the container run_podman rm -f $cid + + if is_rootless; then + run_podman network rm -f $netname + fi } @test "podman rootless cni adds /usr/sbin to PATH" { diff --git a/test/upgrade/test-upgrade.bats b/test/upgrade/test-upgrade.bats index dd827b398..ca478e263 100644 --- a/test/upgrade/test-upgrade.bats +++ b/test/upgrade/test-upgrade.bats @@ -109,6 +109,8 @@ podman \$opts run -d --name myrunningcontainer --label mylabel=$LABEL_RUNNING \ -w /var/www \ $IMAGE /bin/busybox-extras httpd -f -p 80 +podman \$opts pod create --name mypod + echo READY while :;do if [ -e /stop ]; then @@ -136,12 +138,18 @@ EOF # pollute it for use by old-podman. We must keep that pristine # so old-podman is the first to write to it. # + # mount /etc/containers/storage.conf to use the same storage settings as on the host + # mount /dev/shm because the container locks are stored there + # $PODMAN run -d --name podman_parent --pid=host \ --privileged \ --net=host \ --cgroupns=host \ + --pid=host \ + -v /etc/containers/storage.conf:/etc/containers/storage.conf \ -v /dev/fuse:/dev/fuse \ -v /run/crun:/run/crun \ + -v /dev/shm:/dev/shm \ -v $pmroot:$pmroot \ $OLD_PODMAN $pmroot/setup @@ -175,10 +183,11 @@ EOF run_podman ps -a \ --format '{{.Names}}--{{.Status}}--{{.Ports}}--{{.Labels.mylabel}}' \ --sort=names - is "${lines[0]}" "mycreatedcontainer--Created----$LABEL_CREATED" "created" - is "${lines[1]}" "mydonecontainer--Exited (0).*----<no value>" "done" - is "${lines[2]}" "myfailedcontainer--Exited (17) .*----$LABEL_FAILED" "fail" - is "${lines[3]}" "myrunningcontainer--Up .*----$LABEL_RUNNING" "running" + is "${lines[0]}" ".*-infra--Created----<no value>" "infra container" + is "${lines[1]}" "mycreatedcontainer--Created----$LABEL_CREATED" "created" + is "${lines[2]}" "mydonecontainer--Exited (0).*----<no value>" "done" + is "${lines[3]}" "myfailedcontainer--Exited (17) .*----$LABEL_FAILED" "fail" + is "${lines[4]}" "myrunningcontainer--Up .*----$LABEL_RUNNING" "running" # For debugging: dump containers and IDs if [[ -n "$PODMAN_UPGRADE_TEST_DEBUG" ]]; then @@ -206,9 +215,6 @@ failed | exited | 17 @test "logs" { run_podman logs mydonecontainer is "$output" "++$RANDOM_STRING_1++" "podman logs on stopped container" - -# run_podman logs myrunningcontainer -# is "$output" "READY" "podman logs on running container" } @test "exec" { @@ -226,45 +232,36 @@ failed | exited | 17 } @test "pods" { - skip "TBI" + run_podman pod inspect mypod + is "$output" ".*mypod.*" + + run_podman --cgroup-manager=cgroupfs pod start mypod + is "$output" "[0-9a-f]\\{64\\}" "podman pod start" + + run_podman pod ps + is "$output" ".*mypod.*" "podman pod ps shows name" + is "$output" ".*Running.*" "podman pod ps shows running state" + + run_podman pod stop mypod + is "$output" "[0-9a-f]\\{64\\}" "podman pod stop" + + run_podman --cgroup-manager=cgroupfs pod rm mypod + # FIXME: CI runs show this (non fatal) error: + # Error updating pod <ID> conmon cgroup PID limit: open /sys/fs/cgroup/libpod_parent/<ID>/conmon/pids.max: no such file or directory + # Investigate how to fix this (likely a race condition) + # Let's ignore the logrus messages for now + is "$output" ".*[0-9a-f]\\{64\\}" "podman pod rm" } # FIXME: commit? kill? network? pause? restart? top? volumes? What else? @test "start" { - skip "FIXME: this leaves a mount behind: root/overlay/sha/merged" run_podman --cgroup-manager=cgroupfs start -a mydonecontainer is "$output" "++$RANDOM_STRING_1++" "start on already-run container" } @test "rm a stopped container" { - # FIXME FIXME FIXME! - # - # I have no idea what's going on here. For most of my testing in this - # section, the code here was simply 'podman rm myfailedcontainer', and - # it would succeed, but then way down, in 'cleanup' below, the 'rm -f' - # step would fail: - # - # # podman rm -f podman_parent - # error freeing lock for container <sha>: no such file or directory - # ...where <sha> is the ID of the podman_parent container. - # - # I started playing with this section, by adding 'rm mydonecontainer', - # and now it always fails, the same way, but with the container we're - # removing right here: - # - # error freeing lock for container <sha>: no such file or directory - # ...where <sha> is the ID of mydonecontainer. - # - # I don't know. I give up for now, and am skip'ing the whole thing. - # If you want to play with it, try commenting out the 'myfailed' lines, - # or just the 'mydone' ones, or, I don't know. - skip "FIXME: error freeing lock for container <sha>: no such file or dir" - - # For debugging, so we can see what 'error freeing lock' refers to - run_podman ps -a - run_podman rm myfailedcontainer is "$output" "[0-9a-f]\\{64\\}" "podman rm myfailedcontainer" @@ -274,12 +271,6 @@ failed | exited | 17 @test "stop and rm" { - # About a ten-second pause, then: - # Error: timed out waiting for file /tmp/pu.nf747w/tmp/exits/<sha>: internal libpod error - # It doesn't seem to be a socket-length issue: the paths are ~80-88 chars. - # Leaving podman_parent running, and exec'ing into it, it doesn't look - # like the file is being written to the wrong place. - skip "FIXME: this doesn't work: timed out waiting for file tmpdir/exits/sha" run_podman stop myrunningcontainer run_podman rm myrunningcontainer } @@ -304,7 +295,6 @@ failed | exited | 17 run_podman logs podman_parent run_podman rm -f podman_parent - # FIXME: why does this remain mounted? umount $PODMAN_UPGRADE_WORKDIR/root/overlay || true rm -rf $PODMAN_UPGRADE_WORKDIR diff --git a/vendor/github.com/containers/common/libimage/events.go b/vendor/github.com/containers/common/libimage/events.go index bca736c7b..c7733564d 100644 --- a/vendor/github.com/containers/common/libimage/events.go +++ b/vendor/github.com/containers/common/libimage/events.go @@ -1,14 +1,18 @@ package libimage -import "time" +import ( + "time" -// EventType indicates the type of an event. Currrently, there is only one + "github.com/sirupsen/logrus" +) + +// EventType indicates the type of an event. Currently, there is only one // supported type for container image but we may add more (e.g., for manifest // lists) in the future. type EventType int const ( - // EventTypeUnknow is an unitialized EventType. + // EventTypeUnknown is an uninitialized EventType. EventTypeUnknown EventType = iota // EventTypeImagePull represents an image pull. EventTypeImagePull @@ -26,7 +30,7 @@ const ( EventTypeImageUntag // EventTypeImageMount represents an image being mounted. EventTypeImageMount - // EventTypeImageUnmounted represents an image being unmounted. + // EventTypeImageUnmount represents an image being unmounted. EventTypeImageUnmount ) @@ -41,3 +45,18 @@ type Event struct { // Type of the event. Type EventType } + +// writeEvent writes the specified event to the Runtime's event channel. The +// event is discarded if no event channel has been registered (yet). +func (r *Runtime) writeEvent(event *Event) { + select { + case r.eventChannel <- event: + // Done + case <-time.After(2 * time.Second): + // The Runtime's event channel has a buffer of size 100 which + // should be enough even under high load. However, we + // shouldn't block too long in case the buffer runs full (could + // be an honest user error or bug). + logrus.Warnf("Discarding libimage event which was not read within 2 seconds: %v", event) + } +} diff --git a/vendor/github.com/containers/common/libimage/image.go b/vendor/github.com/containers/common/libimage/image.go index 4728565bb..11abfdee7 100644 --- a/vendor/github.com/containers/common/libimage/image.go +++ b/vendor/github.com/containers/common/libimage/image.go @@ -277,6 +277,10 @@ func (i *Image) remove(ctx context.Context, rmMap map[string]*RemoveImageReport, return errors.Errorf("cannot remove read-only image %q", i.ID()) } + if i.runtime.eventChannel != nil { + i.runtime.writeEvent(&Event{ID: i.ID(), Name: referencedBy, Time: time.Now(), Type: EventTypeImageRemove}) + } + // Check if already visisted this image. report, exists := rmMap[i.ID()] if exists { @@ -423,6 +427,9 @@ func (i *Image) Tag(name string) error { } logrus.Debugf("Tagging image %s with %q", i.ID(), ref.String()) + if i.runtime.eventChannel != nil { + i.runtime.writeEvent(&Event{ID: i.ID(), Name: name, Time: time.Now(), Type: EventTypeImageTag}) + } newNames := append(i.Names(), ref.String()) if err := i.runtime.store.SetNames(i.ID(), newNames); err != nil { @@ -454,6 +461,9 @@ func (i *Image) Untag(name string) error { name = ref.String() logrus.Debugf("Untagging %q from image %s", ref.String(), i.ID()) + if i.runtime.eventChannel != nil { + i.runtime.writeEvent(&Event{ID: i.ID(), Name: name, Time: time.Now(), Type: EventTypeImageUntag}) + } removedName := false newNames := []string{} @@ -593,6 +603,10 @@ func (i *Image) RepoDigests() ([]string, error) { // are directly passed down to the containers storage. Returns the fully // evaluated path to the mount point. func (i *Image) Mount(ctx context.Context, mountOptions []string, mountLabel string) (string, error) { + if i.runtime.eventChannel != nil { + i.runtime.writeEvent(&Event{ID: i.ID(), Name: "", Time: time.Now(), Type: EventTypeImageMount}) + } + mountPoint, err := i.runtime.store.MountImage(i.ID(), mountOptions, mountLabel) if err != nil { return "", err @@ -634,6 +648,9 @@ func (i *Image) Mountpoint() (string, error) { // Unmount the image. Use force to ignore the reference counter and forcefully // unmount. func (i *Image) Unmount(force bool) error { + if i.runtime.eventChannel != nil { + i.runtime.writeEvent(&Event{ID: i.ID(), Name: "", Time: time.Now(), Type: EventTypeImageUnmount}) + } logrus.Debugf("Unmounted image %s", i.ID()) _, err := i.runtime.store.UnmountImage(i.ID(), force) return err diff --git a/vendor/github.com/containers/common/libimage/image_tree.go b/vendor/github.com/containers/common/libimage/image_tree.go index 6583a7007..b8b9cb216 100644 --- a/vendor/github.com/containers/common/libimage/image_tree.go +++ b/vendor/github.com/containers/common/libimage/image_tree.go @@ -35,36 +35,45 @@ func (i *Image) Tree(traverseChildren bool) (string, error) { fmt.Fprintf(sb, "No Image Layers") } - tree := gotree.New(sb.String()) - layerTree, err := i.runtime.layerTree() if err != nil { return "", err } - imageNode := layerTree.node(i.TopLayer()) // Traverse the entire tree down to all children. if traverseChildren { + tree := gotree.New(sb.String()) if err := imageTreeTraverseChildren(imageNode, tree); err != nil { return "", err } - } else { - // Walk all layers of the image and assemlbe their data. - for parentNode := imageNode; parentNode != nil; parentNode = parentNode.parent { - if parentNode.layer == nil { - break // we're done - } - var tags string - repoTags, err := parentNode.repoTags() - if err != nil { - return "", err - } - if len(repoTags) > 0 { - tags = fmt.Sprintf(" Top Layer of: %s", repoTags) - } - tree.Add(fmt.Sprintf("ID: %s Size: %7v%s", parentNode.layer.ID[:12], units.HumanSizeWithPrecision(float64(parentNode.layer.UncompressedSize), 4), tags)) + return tree.Print(), nil + } + + // Walk all layers of the image and assemlbe their data. Note that the + // tree is constructed in reverse order to remain backwards compatible + // with Podman. + contents := []string{} + for parentNode := imageNode; parentNode != nil; parentNode = parentNode.parent { + if parentNode.layer == nil { + break // we're done + } + var tags string + repoTags, err := parentNode.repoTags() + if err != nil { + return "", err + } + if len(repoTags) > 0 { + tags = fmt.Sprintf(" Top Layer of: %s", repoTags) } + content := fmt.Sprintf("ID: %s Size: %7v%s", parentNode.layer.ID[:12], units.HumanSizeWithPrecision(float64(parentNode.layer.UncompressedSize), 4), tags) + contents = append(contents, content) + } + contents = append(contents, sb.String()) + + tree := gotree.New(contents[len(contents)-1]) + for i := len(contents) - 2; i >= 0; i-- { + tree.Add(contents[i]) } return tree.Print(), nil @@ -80,14 +89,22 @@ func imageTreeTraverseChildren(node *layerNode, parent gotree.Tree) error { tags = fmt.Sprintf(" Top Layer of: %s", repoTags) } - newNode := parent.Add(fmt.Sprintf("ID: %s Size: %7v%s", node.layer.ID[:12], units.HumanSizeWithPrecision(float64(node.layer.UncompressedSize), 4), tags)) + content := fmt.Sprintf("ID: %s Size: %7v%s", node.layer.ID[:12], units.HumanSizeWithPrecision(float64(node.layer.UncompressedSize), 4), tags) - if len(node.children) <= 1 { - newNode = parent + var newTree gotree.Tree + if node.parent == nil || len(node.parent.children) <= 1 { + // No parent or no siblings, so we can go linear. + parent.Add(content) + newTree = parent + } else { + // Each siblings gets a new tree, so we can branch. + newTree = gotree.New(content) + parent.AddTree(newTree) } + for i := range node.children { child := node.children[i] - if err := imageTreeTraverseChildren(child, newNode); err != nil { + if err := imageTreeTraverseChildren(child, newTree); err != nil { return err } } diff --git a/vendor/github.com/containers/common/libimage/layer_tree.go b/vendor/github.com/containers/common/libimage/layer_tree.go index 7e0940339..4195b43c0 100644 --- a/vendor/github.com/containers/common/libimage/layer_tree.go +++ b/vendor/github.com/containers/common/libimage/layer_tree.go @@ -59,7 +59,7 @@ func (l *layerNode) repoTags() ([]string, error) { return nil, err } for _, tag := range repoTags { - if _, visted := visitedTags[tag]; visted { + if _, visited := visitedTags[tag]; visited { continue } visitedTags[tag] = true diff --git a/vendor/github.com/containers/common/libimage/load.go b/vendor/github.com/containers/common/libimage/load.go index c606aca5b..856813356 100644 --- a/vendor/github.com/containers/common/libimage/load.go +++ b/vendor/github.com/containers/common/libimage/load.go @@ -4,6 +4,7 @@ import ( "context" "errors" "os" + "time" dirTransport "github.com/containers/image/v5/directory" dockerArchiveTransport "github.com/containers/image/v5/docker/archive" @@ -23,6 +24,10 @@ type LoadOptions struct { func (r *Runtime) Load(ctx context.Context, path string, options *LoadOptions) ([]string, error) { logrus.Debugf("Loading image from %q", path) + if r.eventChannel != nil { + r.writeEvent(&Event{ID: "", Name: path, Time: time.Now(), Type: EventTypeImageLoad}) + } + var ( loadedImages []string loadError error diff --git a/vendor/github.com/containers/common/libimage/manifest_list.go b/vendor/github.com/containers/common/libimage/manifest_list.go index 72a2cf55f..f902db5cb 100644 --- a/vendor/github.com/containers/common/libimage/manifest_list.go +++ b/vendor/github.com/containers/common/libimage/manifest_list.go @@ -3,6 +3,7 @@ package libimage import ( "context" "fmt" + "time" "github.com/containers/common/libimage/manifests" imageCopy "github.com/containers/image/v5/copy" @@ -364,6 +365,10 @@ func (m *ManifestList) Push(ctx context.Context, destination string, options *Ma } } + if m.image.runtime.eventChannel != nil { + m.image.runtime.writeEvent(&Event{ID: m.ID(), Name: destination, Time: time.Now(), Type: EventTypeImagePush}) + } + // NOTE: we're using the logic in copier to create a proper // types.SystemContext. This prevents us from having an error prone // code duplicate here. diff --git a/vendor/github.com/containers/common/libimage/pull.go b/vendor/github.com/containers/common/libimage/pull.go index b92a5e15e..f92b4d36c 100644 --- a/vendor/github.com/containers/common/libimage/pull.go +++ b/vendor/github.com/containers/common/libimage/pull.go @@ -5,10 +5,10 @@ import ( "fmt" "io" "strings" + "time" "github.com/containers/common/pkg/config" - dirTransport "github.com/containers/image/v5/directory" - dockerTransport "github.com/containers/image/v5/docker" + registryTransport "github.com/containers/image/v5/docker" dockerArchiveTransport "github.com/containers/image/v5/docker/archive" "github.com/containers/image/v5/docker/reference" ociArchiveTransport "github.com/containers/image/v5/oci/archive" @@ -42,7 +42,7 @@ type PullOptions struct { // policies (e.g., buildah-bud versus podman-build). Making the pull-policy // choice explicit is an attempt to prevent silent regressions. // -// The errror is storage.ErrImageUnknown iff the pull policy is set to "never" +// The error is storage.ErrImageUnknown iff the pull policy is set to "never" // and no local image has been found. This allows for an easier integration // into some users of this package (e.g., Buildah). func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullPolicy, options *PullOptions) ([]*Image, error) { @@ -56,7 +56,7 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP if err != nil { // If the image clearly refers to a local one, we can look it up directly. // In fact, we need to since they are not parseable. - if strings.HasPrefix(name, "sha256:") || (len(name) == 64 && !strings.Contains(name, "/.:@")) { + if strings.HasPrefix(name, "sha256:") || (len(name) == 64 && !strings.ContainsAny(name, "/.:@")) { if pullPolicy == config.PullPolicyAlways { return nil, errors.Errorf("pull policy is always but image has been referred to by ID (%s)", name) } @@ -76,10 +76,14 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP ref = dockerRef } - if options.AllTags && ref.Transport().Name() != dockerTransport.Transport.Name() { + if options.AllTags && ref.Transport().Name() != registryTransport.Transport.Name() { return nil, errors.Errorf("pulling all tags is not supported for %s transport", ref.Transport().Name()) } + if r.eventChannel != nil { + r.writeEvent(&Event{ID: "", Name: name, Time: time.Now(), Type: EventTypeImagePull}) + } + var ( pulledImages []string pullError error @@ -88,29 +92,17 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP // Dispatch the copy operation. switch ref.Transport().Name() { - // DOCKER/REGISTRY - case dockerTransport.Transport.Name(): + // DOCKER REGISTRY + case registryTransport.Transport.Name(): pulledImages, pullError = r.copyFromRegistry(ctx, ref, strings.TrimPrefix(name, "docker://"), pullPolicy, options) // DOCKER ARCHIVE case dockerArchiveTransport.Transport.Name(): pulledImages, pullError = r.copyFromDockerArchive(ctx, ref, &options.CopyOptions) - // OCI - case ociTransport.Transport.Name(): - pulledImages, pullError = r.copyFromDefault(ctx, ref, &options.CopyOptions) - - // OCI ARCHIVE - case ociArchiveTransport.Transport.Name(): - pulledImages, pullError = r.copyFromDefault(ctx, ref, &options.CopyOptions) - - // DIR - case dirTransport.Transport.Name(): - pulledImages, pullError = r.copyFromDefault(ctx, ref, &options.CopyOptions) - - // UNSUPPORTED + // ALL OTHER TRANSPORTS default: - return nil, errors.Errorf("unsupported transport %q for pulling", ref.Transport().Name()) + pulledImages, pullError = r.copyFromDefault(ctx, ref, &options.CopyOptions) } if pullError != nil { @@ -162,7 +154,12 @@ func (r *Runtime) copyFromDefault(ctx context.Context, ref types.ImageReference, imageName = "sha256:" + storageName[1:] } else { storageName = manifest.Annotations["org.opencontainers.image.ref.name"] - imageName = storageName + named, err := NormalizeName(storageName) + if err != nil { + return nil, err + } + imageName = named.String() + storageName = imageName } default: @@ -275,7 +272,7 @@ func (r *Runtime) copyFromRegistry(ctx context.Context, ref types.ImageReference } named := reference.TrimNamed(ref.DockerReference()) - tags, err := dockerTransport.GetRepositoryTags(ctx, &r.systemContext, ref) + tags, err := registryTransport.GetRepositoryTags(ctx, &r.systemContext, ref) if err != nil { return nil, err } @@ -399,7 +396,7 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str for _, candidate := range resolved.PullCandidates { candidateString := candidate.Value.String() logrus.Debugf("Attempting to pull candidate %s for %s", candidateString, imageName) - srcRef, err := dockerTransport.NewReference(candidate.Value) + srcRef, err := registryTransport.NewReference(candidate.Value) if err != nil { return nil, err } diff --git a/vendor/github.com/containers/common/libimage/push.go b/vendor/github.com/containers/common/libimage/push.go index 8ff5d5ffd..f1434b81d 100644 --- a/vendor/github.com/containers/common/libimage/push.go +++ b/vendor/github.com/containers/common/libimage/push.go @@ -2,6 +2,7 @@ package libimage import ( "context" + "time" dockerArchiveTransport "github.com/containers/image/v5/docker/archive" "github.com/containers/image/v5/docker/reference" @@ -61,8 +62,12 @@ func (r *Runtime) Push(ctx context.Context, source, destination string, options destRef = dockerRef } + if r.eventChannel != nil { + r.writeEvent(&Event{ID: image.ID(), Name: destination, Time: time.Now(), Type: EventTypeImagePush}) + } + // Buildah compat: Make sure to tag the destination image if it's a - // Docker archive. This way, we preseve the image name. + // Docker archive. This way, we preserve the image name. if destRef.Transport().Name() == dockerArchiveTransport.Transport.Name() { if named, err := reference.ParseNamed(resolvedSource); err == nil { tagged, isTagged := named.(reference.NamedTagged) diff --git a/vendor/github.com/containers/common/libimage/runtime.go b/vendor/github.com/containers/common/libimage/runtime.go index 4e6bd2cf2..c80e7ec7a 100644 --- a/vendor/github.com/containers/common/libimage/runtime.go +++ b/vendor/github.com/containers/common/libimage/runtime.go @@ -20,6 +20,9 @@ import ( // RuntimeOptions allow for creating a customized Runtime. type RuntimeOptions struct { + // The base system context of the runtime which will be used throughout + // the entire lifespan of the Runtime. Certain options in some + // functions may override specific fields. SystemContext *types.SystemContext } @@ -41,6 +44,8 @@ func setRegistriesConfPath(systemContext *types.SystemContext) { // Runtime is responsible for image management and storing them in a containers // storage. type Runtime struct { + // Use to send events out to users. + eventChannel chan *Event // Underlying storage store. store storage.Store // Global system context. No pointer to simplify copying and modifying @@ -55,6 +60,18 @@ func (r *Runtime) systemContextCopy() *types.SystemContext { return &sys } +// EventChannel creates a buffered channel for events that the Runtime will use +// to write events to. Callers are expected to read from the channel in a +// timely manner. +// Can be called once for a given Runtime. +func (r *Runtime) EventChannel() chan *Event { + if r.eventChannel != nil { + return r.eventChannel + } + r.eventChannel = make(chan *Event, 100) + return r.eventChannel +} + // RuntimeFromStore returns a Runtime for the specified store. func RuntimeFromStore(store storage.Store, options *RuntimeOptions) (*Runtime, error) { if options == nil { @@ -99,6 +116,9 @@ func RuntimeFromStoreOptions(runtimeOptions *RuntimeOptions, storeOptions *stora // is considered to be an error condition. func (r *Runtime) Shutdown(force bool) error { _, err := r.store.Shutdown(force) + if r.eventChannel != nil { + close(r.eventChannel) + } return err } diff --git a/vendor/github.com/containers/common/libimage/save.go b/vendor/github.com/containers/common/libimage/save.go index c03437682..c00c0107e 100644 --- a/vendor/github.com/containers/common/libimage/save.go +++ b/vendor/github.com/containers/common/libimage/save.go @@ -3,6 +3,7 @@ package libimage import ( "context" "strings" + "time" dirTransport "github.com/containers/image/v5/directory" dockerArchiveTransport "github.com/containers/image/v5/docker/archive" @@ -46,7 +47,7 @@ func (r *Runtime) Save(ctx context.Context, names []string, format, path string, // All formats support saving 1. default: if format != "docker-archive" { - return errors.Errorf("unspported format %q for saving multiple images (only docker-archive)", format) + return errors.Errorf("unsupported format %q for saving multiple images (only docker-archive)", format) } if len(options.AdditionalTags) > 0 { return errors.Errorf("cannot save multiple images with multiple tags") @@ -62,7 +63,7 @@ func (r *Runtime) Save(ctx context.Context, names []string, format, path string, return r.saveDockerArchive(ctx, names, path, options) } - return errors.Errorf("unspported format %q for saving images", format) + return errors.Errorf("unsupported format %q for saving images", format) } @@ -74,6 +75,10 @@ func (r *Runtime) saveSingleImage(ctx context.Context, name, format, path string return err } + if r.eventChannel != nil { + r.writeEvent(&Event{ID: image.ID(), Name: path, Time: time.Now(), Type: EventTypeImageSave}) + } + // Unless the image was referenced by ID, use the resolved name as a // tag. var tag string @@ -101,7 +106,7 @@ func (r *Runtime) saveSingleImage(ctx context.Context, name, format, path string options.ManifestMIMEType = manifest.DockerV2Schema2MediaType default: - return errors.Errorf("unspported format %q for saving images", format) + return errors.Errorf("unsupported format %q for saving images", format) } if err != nil { @@ -160,6 +165,9 @@ func (r *Runtime) saveDockerArchive(ctx context.Context, names []string, path st } } localImages[image.ID()] = local + if r.eventChannel != nil { + r.writeEvent(&Event{ID: image.ID(), Name: path, Time: time.Now(), Type: EventTypeImageSave}) + } } writer, err := dockerArchiveTransport.NewWriter(r.systemContextCopy(), path) diff --git a/vendor/github.com/containers/common/libimage/search.go b/vendor/github.com/containers/common/libimage/search.go index b36b6d2a3..4d1b842e7 100644 --- a/vendor/github.com/containers/common/libimage/search.go +++ b/vendor/github.com/containers/common/libimage/search.go @@ -7,7 +7,7 @@ import ( "strings" "sync" - dockerTransport "github.com/containers/image/v5/docker" + registryTransport "github.com/containers/image/v5/docker" "github.com/containers/image/v5/pkg/sysregistriesv2" "github.com/containers/image/v5/transports/alltransports" "github.com/containers/image/v5/types" @@ -193,7 +193,7 @@ func (r *Runtime) searchImageInRegistry(ctx context.Context, term, registry stri return results, nil } - results, err := dockerTransport.SearchRegistry(ctx, sys, registry, term, limit) + results, err := registryTransport.SearchRegistry(ctx, sys, registry, term, limit) if err != nil { return []SearchResult{}, err } @@ -255,7 +255,7 @@ func (r *Runtime) searchImageInRegistry(ctx context.Context, term, registry stri func searchRepositoryTags(ctx context.Context, sys *types.SystemContext, registry, term string, options *SearchOptions) ([]SearchResult, error) { dockerPrefix := "docker://" imageRef, err := alltransports.ParseImageName(fmt.Sprintf("%s/%s", registry, term)) - if err == nil && imageRef.Transport().Name() != dockerTransport.Transport.Name() { + if err == nil && imageRef.Transport().Name() != registryTransport.Transport.Name() { return nil, errors.Errorf("reference %q must be a docker reference", term) } else if err != nil { imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, fmt.Sprintf("%s/%s", registry, term))) @@ -263,7 +263,7 @@ func searchRepositoryTags(ctx context.Context, sys *types.SystemContext, registr return nil, errors.Errorf("reference %q must be a docker reference", term) } } - tags, err := dockerTransport.GetRepositoryTags(ctx, sys, imageRef) + tags, err := registryTransport.GetRepositoryTags(ctx, sys, imageRef) if err != nil { return nil, errors.Errorf("error getting repository tags: %v", err) } @@ -288,18 +288,18 @@ func searchRepositoryTags(ctx context.Context, sys *types.SystemContext, registr return paramsArr, nil } -func (f *SearchFilter) matchesStarFilter(result dockerTransport.SearchResult) bool { +func (f *SearchFilter) matchesStarFilter(result registryTransport.SearchResult) bool { return result.StarCount >= f.Stars } -func (f *SearchFilter) matchesAutomatedFilter(result dockerTransport.SearchResult) bool { +func (f *SearchFilter) matchesAutomatedFilter(result registryTransport.SearchResult) bool { if f.IsAutomated != types.OptionalBoolUndefined { return result.IsAutomated == (f.IsAutomated == types.OptionalBoolTrue) } return true } -func (f *SearchFilter) matchesOfficialFilter(result dockerTransport.SearchResult) bool { +func (f *SearchFilter) matchesOfficialFilter(result registryTransport.SearchResult) bool { if f.IsOfficial != types.OptionalBoolUndefined { return result.IsOfficial == (f.IsOfficial == types.OptionalBoolTrue) } diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go index 371dd3667..ee5957527 100644 --- a/vendor/github.com/containers/common/pkg/config/config.go +++ b/vendor/github.com/containers/common/pkg/config/config.go @@ -232,7 +232,7 @@ type EngineConfig struct { // will fall back to containers/image defaults. ImageParallelCopies uint `toml:"image_parallel_copies,omitempty"` - // ImageDefaultFormat sepecified the manifest Type (oci, v2s2, or v2s1) + // ImageDefaultFormat specified the manifest Type (oci, v2s2, or v2s1) // to use when pulling, pushing, building container images. By default // image pulled and pushed match the format of the source image. // Building/committing defaults to OCI. @@ -425,6 +425,12 @@ type NetworkConfig struct { // to attach pods to. DefaultNetwork string `toml:"default_network,omitempty"` + // DefaultSubnet is the subnet to be used for the default CNI network. + // If a network with the name given in DefaultNetwork is not present + // then a new network using this subnet will be created. + // Must be a valid IPv4 CIDR block. + DefaultSubnet string `toml:"default_subnet,omitempty"` + // NetworkConfigDir is where CNI network configuration files are stored. NetworkConfigDir string `toml:"network_config_dir,omitempty"` } diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf index 00edd5438..f696843f5 100644 --- a/vendor/github.com/containers/common/pkg/config/containers.conf +++ b/vendor/github.com/containers/common/pkg/config/containers.conf @@ -157,7 +157,7 @@ default_sysctls = [ # Logging driver for the container. Available options: k8s-file and journald. # -# log_driver = "k8s-file" +# log_driver = "journald" # Maximum size allowed for the container log file. Negative numbers indicate # that no size limit is imposed. If positive, it must be >= 8192 to match or @@ -243,6 +243,12 @@ default_sysctls = [ # The network name of the default CNI network to attach pods to. # default_network = "podman" +# The default subnet for the default CNI network given in default_network. +# If a network with that name does not exist, a new network using that name and +# this subnet will be created. +# Must be a valid IPv4 CIDR prefix. +#default_subnet = "10.88.0.0/16" + # Path to the directory where CNI configuration files are located. # # network_config_dir = "/etc/cni/net.d/" @@ -254,7 +260,7 @@ default_sysctls = [ # Manifest Type (oci, v2s2, or v2s1) to use when pulling, pushing, building # container images. By default image pulled and pushed match the format of the -# source image. Building/commiting defaults to OCI. +# source image. Building/committing defaults to OCI. # image_default_format = "" # Cgroup management implementation used for the runtime. diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go index 34a360bf5..417776160 100644 --- a/vendor/github.com/containers/common/pkg/config/default.go +++ b/vendor/github.com/containers/common/pkg/config/default.go @@ -102,7 +102,7 @@ const ( // SystemdCgroupsManager represents systemd native cgroup manager SystemdCgroupsManager = "systemd" // DefaultLogDriver is the default type of log files - DefaultLogDriver = "k8s-file" + DefaultLogDriver = "journald" // DefaultLogSizeMax is the default value for the maximum log size // allowed for a container. Negative values mean that no limit is imposed. DefaultLogSizeMax = -1 @@ -114,6 +114,9 @@ const ( // DefaultSignaturePolicyPath is the default value for the // policy.json file. DefaultSignaturePolicyPath = "/etc/containers/policy.json" + // DefaultSubnet is the subnet that will be used for the default CNI + // network. + DefaultSubnet = "10.88.0.0/16" // DefaultRootlessSignaturePolicyPath is the location within // XDG_CONFIG_HOME of the rootless policy.json file. DefaultRootlessSignaturePolicyPath = "containers/policy.json" @@ -204,6 +207,7 @@ func DefaultConfig() (*Config, error) { }, Network: NetworkConfig{ DefaultNetwork: "podman", + DefaultSubnet: DefaultSubnet, NetworkConfigDir: cniConfig, CNIPluginDirs: cniBinDir, }, diff --git a/vendor/github.com/containers/common/pkg/filters/filters.go b/vendor/github.com/containers/common/pkg/filters/filters.go index 53f420db2..e26e056ad 100644 --- a/vendor/github.com/containers/common/pkg/filters/filters.go +++ b/vendor/github.com/containers/common/pkg/filters/filters.go @@ -96,7 +96,7 @@ func PrepareFilters(r *http.Request) (map[string][]string, error) { return filterMap, nil } -// MatchLabelFilters matches labels and returs true if they are valid +// MatchLabelFilters matches labels and returns true if they are valid func MatchLabelFilters(filterValues []string, labels map[string]string) bool { outer: for _, filterValue := range filterValues { diff --git a/vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go b/vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go index 37edc16be..80fcf5458 100644 --- a/vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go +++ b/vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go @@ -33,7 +33,7 @@ type Driver struct { func NewDriver(rootPath string) (*Driver, error) { fileDriver := new(Driver) fileDriver.secretsDataFilePath = filepath.Join(rootPath, secretsDataFile) - // the lockfile functions requre that the rootPath dir is executable + // the lockfile functions require that the rootPath dir is executable if err := os.MkdirAll(rootPath, 0700); err != nil { return nil, err } diff --git a/vendor/github.com/containers/common/pkg/secrets/secrets.go b/vendor/github.com/containers/common/pkg/secrets/secrets.go index 5e0fb3e9d..d27bb7472 100644 --- a/vendor/github.com/containers/common/pkg/secrets/secrets.go +++ b/vendor/github.com/containers/common/pkg/secrets/secrets.go @@ -99,7 +99,7 @@ func NewManager(rootPath string) (*SecretsManager, error) { if !filepath.IsAbs(rootPath) { return nil, errors.Wrapf(errInvalidPath, "path must be absolute: %s", rootPath) } - // the lockfile functions requre that the rootPath dir is executable + // the lockfile functions require that the rootPath dir is executable if err := os.MkdirAll(rootPath, 0700); err != nil { return nil, err } diff --git a/vendor/github.com/containers/common/pkg/secrets/secretsdb.go b/vendor/github.com/containers/common/pkg/secrets/secretsdb.go index 22db97c12..1395d103c 100644 --- a/vendor/github.com/containers/common/pkg/secrets/secretsdb.go +++ b/vendor/github.com/containers/common/pkg/secrets/secretsdb.go @@ -76,7 +76,7 @@ func (s *SecretsManager) getNameAndID(nameOrID string) (name, id string, err err } // ID prefix may have been given, iterate through all IDs. - // ID and partial ID has a max lenth of 25, so we return if its greater than that. + // ID and partial ID has a max length of 25, so we return if its greater than that. if len(nameOrID) > secretIDLength { return "", "", errors.Wrapf(errNoSuchSecret, "no secret with name or id %q", nameOrID) } diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go index af0a1269e..df095f220 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.37.2-dev" +const Version = "0.38.1-dev" diff --git a/vendor/github.com/containers/storage/.cirrus.yml b/vendor/github.com/containers/storage/.cirrus.yml index 836bf659a..96714c2fc 100644 --- a/vendor/github.com/containers/storage/.cirrus.yml +++ b/vendor/github.com/containers/storage/.cirrus.yml @@ -17,15 +17,15 @@ env: #### #### Cache-image names to test with (double-quotes around names are critical) ### - FEDORA_NAME: "fedora-33" - PRIOR_FEDORA_NAME: "fedora-32" - UBUNTU_NAME: "ubuntu-2010" - PRIOR_UBUNTU_NAME: "ubuntu-2004" + FEDORA_NAME: "fedora-34" + PRIOR_FEDORA_NAME: "fedora-33" + UBUNTU_NAME: "ubuntu-2104" + PRIOR_UBUNTU_NAME: "ubuntu-2010" # GCE project where images live IMAGE_PROJECT: "libpod-218412" # VM Image built in containers/automation_images - _BUILT_IMAGE_SUFFIX: "c5744859501821952" + _BUILT_IMAGE_SUFFIX: "c6032583541653504" FEDORA_CACHE_IMAGE_NAME: "fedora-${_BUILT_IMAGE_SUFFIX}" PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${_BUILT_IMAGE_SUFFIX}" UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${_BUILT_IMAGE_SUFFIX}" @@ -112,8 +112,6 @@ ubuntu_testing_task: &ubuntu_testing - env: TEST_DRIVER: "vfs" - env: - TEST_DRIVER: "aufs" - - env: TEST_DRIVER: "overlay" diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION index d1eaa3ba0..b0f33908d 100644 --- a/vendor/github.com/containers/storage/VERSION +++ b/vendor/github.com/containers/storage/VERSION @@ -1 +1 @@ -1.30.2 +1.30.3 diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod index 08a54d60d..bda564681 100644 --- a/vendor/github.com/containers/storage/go.mod +++ b/vendor/github.com/containers/storage/go.mod @@ -16,9 +16,9 @@ require ( github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible github.com/moby/sys/mountinfo v0.4.1 github.com/opencontainers/go-digest v1.0.0 - github.com/opencontainers/runc v1.0.0-rc93 - github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d - github.com/opencontainers/selinux v1.8.0 + github.com/opencontainers/runc v1.0.0-rc94 + github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 + github.com/opencontainers/selinux v1.8.1 github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 @@ -27,6 +27,6 @@ require ( github.com/ulikunitz/xz v0.5.10 github.com/vbatts/tar-split v0.11.1 golang.org/x/net v0.0.0-20201224014010-6772e930b67b - golang.org/x/sys v0.0.0-20210324051608-47abb6519492 + golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 gotest.tools v2.2.0+incompatible ) diff --git a/vendor/github.com/containers/storage/go.sum b/vendor/github.com/containers/storage/go.sum index dc2cbc338..692ddbb84 100644 --- a/vendor/github.com/containers/storage/go.sum +++ b/vendor/github.com/containers/storage/go.sum @@ -82,12 +82,14 @@ github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3k github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= +github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= +github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= @@ -107,6 +109,7 @@ github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= +github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= @@ -164,6 +167,7 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7 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/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.3.1/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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= @@ -205,6 +209,7 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= @@ -233,6 +238,7 @@ github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblf github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -350,8 +356,9 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= @@ -413,18 +420,22 @@ github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5X github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc93 h1:x2UMpOOVf3kQ8arv/EsDGwim8PTNqzL1/EYDr/+scOM= github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= +github.com/opencontainers/runc v1.0.0-rc94 h1:atqAFoBGp+Wkh9HKpYN3g/8NCbMzYG6SJrr+YgwamgM= +github.com/opencontainers/runc v1.0.0-rc94/go.mod h1:z+bZxa/+Tz/FmYVWkhUajJdzFeOqjc5vrqskhVyHGUM= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d h1:pNa8metDkwZjb9g4T8s+krQ+HRgZAkqnXml+wNir/+s= github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= github.com/opencontainers/selinux v1.8.0 h1:+77ba4ar4jsCbL1GLbFL8fFM57w6suPfSS9PDLDY7KM= github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= +github.com/opencontainers/selinux v1.8.1 h1:yvEZh7CsfnJNwKzG9ZeXwbvR05RAZsu5RS/3vA6qFTA= +github.com/opencontainers/selinux v1.8.1/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -687,8 +698,9 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492 h1:Paq34FxTluEPvVyayQqMPgHm+vTOrIifmcYxFBx9TLg= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= +golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/doc.go b/vendor/github.com/opencontainers/selinux/go-selinux/doc.go index 9c9cbd120..0ac7d819e 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/doc.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/doc.go @@ -1,10 +1,6 @@ /* Package selinux provides a high-level interface for interacting with selinux. -This package uses a selinux build tag to enable the selinux functionality. This -allows non-linux and linux users who do not have selinux support to still use -tools that rely on this library. - Usage: import "github.com/opencontainers/selinux/go-selinux" diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go index 439455511..b3d142d8c 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go @@ -25,6 +25,8 @@ var ErrIncompatibleLabel = errors.New("Bad SELinux option z and Z can not be use // the container. A list of options can be passed into this function to alter // the labels. The labels returned will include a random MCS String, that is // guaranteed to be unique. +// If the disabled flag is passed in, the process label will not be set, but the mount label will be set +// to the container_file label with the maximum category. This label is not usable by any confined label. func InitLabels(options []string) (plabel string, mlabel string, retErr error) { if !selinux.GetEnabled() { return "", "", nil @@ -47,7 +49,8 @@ func InitLabels(options []string) (plabel string, mlabel string, retErr error) { } for _, opt := range options { if opt == "disable" { - return "", mountLabel, nil + selinux.ReleaseLabel(mountLabel) + return "", selinux.PrivContainerMountLabel(), nil } if i := strings.Index(opt, ":"); i == -1 { return "", "", errors.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt) diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go index d9119908b..b336ebad3 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go @@ -11,9 +11,10 @@ const ( Permissive = 0 // Disabled constant to indicate SELinux is disabled Disabled = -1 - + // maxCategory is the maximum number of categories used within containers + maxCategory = 1024 // DefaultCategoryRange is the upper bound on the category range - DefaultCategoryRange = uint32(1024) + DefaultCategoryRange = uint32(maxCategory) ) var ( @@ -276,3 +277,8 @@ func DisableSecOpt() []string { func GetDefaultContextWithLevel(user, level, scon string) (string, error) { return getDefaultContextWithLevel(user, level, scon) } + +// PrivContainerMountLabel returns mount label for privileged containers +func PrivContainerMountLabel() string { + return privContainerMountLabel +} diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go index 5bfcc0490..54597398b 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go @@ -892,13 +892,13 @@ func openContextFile() (*os.File, error) { return os.Open(lxcPath) } -var labels = loadLabels() +var labels, privContainerMountLabel = loadLabels() -func loadLabels() map[string]string { +func loadLabels() (map[string]string, string) { labels := make(map[string]string) in, err := openContextFile() if err != nil { - return labels + return labels, "" } defer in.Close() @@ -920,7 +920,10 @@ func loadLabels() map[string]string { } } - return labels + con, _ := NewContext(labels["file"]) + con["level"] = fmt.Sprintf("s0:c%d,c%d", maxCategory-2, maxCategory-1) + reserveLabel(con.get()) + return labels, con.get() } // kvmContainerLabels returns the default processLabel and mountLabel to be used diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go index 70b7b7c85..b7218a0b6 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go @@ -2,6 +2,8 @@ package selinux +const privContainerMountLabel = "" + func setDisabled() { } diff --git a/vendor/modules.txt b/vendor/modules.txt index a494d2fbe..2aa2e39fb 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -90,7 +90,7 @@ github.com/containers/buildah/pkg/overlay github.com/containers/buildah/pkg/parse github.com/containers/buildah/pkg/rusage github.com/containers/buildah/util -# github.com/containers/common v0.37.2-0.20210503193405-42134aa138ce +# github.com/containers/common v0.38.1-0.20210510140555-24645399a050 github.com/containers/common/libimage github.com/containers/common/libimage/manifests github.com/containers/common/pkg/apparmor @@ -191,7 +191,7 @@ github.com/containers/psgo/internal/dev github.com/containers/psgo/internal/host github.com/containers/psgo/internal/proc github.com/containers/psgo/internal/process -# github.com/containers/storage v1.30.2 +# github.com/containers/storage v1.30.3 github.com/containers/storage github.com/containers/storage/drivers github.com/containers/storage/drivers/aufs @@ -513,7 +513,7 @@ github.com/opencontainers/runtime-tools/generate github.com/opencontainers/runtime-tools/generate/seccomp github.com/opencontainers/runtime-tools/specerror github.com/opencontainers/runtime-tools/validate -# github.com/opencontainers/selinux v1.8.0 +# github.com/opencontainers/selinux v1.8.1 github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label github.com/opencontainers/selinux/pkg/pwalk |