diff options
104 files changed, 676 insertions, 432 deletions
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go index 099fc267e..3720e9608 100644 --- a/cmd/podman/common/completion.go +++ b/cmd/podman/common/completion.go @@ -7,7 +7,9 @@ import ( "reflect" "strconv" "strings" + "unicode" + libimageDefine "github.com/containers/common/libimage/define" "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/image/v5/pkg/sysregistriesv2" @@ -16,6 +18,7 @@ import ( "github.com/containers/podman/v4/libpod/events" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/rootless" + "github.com/containers/podman/v4/pkg/signal" systemdDefine "github.com/containers/podman/v4/pkg/systemd/define" "github.com/containers/podman/v4/pkg/util" "github.com/spf13/cobra" @@ -496,6 +499,11 @@ func AutocompleteImages(cmd *cobra.Command, args []string, toComplete string) ([ return getImages(cmd, toComplete) } +// AutocompleteImageSearchFilters - Autocomplate `search --filter`. +func AutocompleteImageSearchFilters(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return libimageDefine.SearchFilters, cobra.ShellCompDirectiveNoFileComp +} + // AutocompletePodExitPolicy - Autocomplete pod exit policy. func AutocompletePodExitPolicy(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return config.PodExitPolicies, cobra.ShellCompDirectiveNoFileComp @@ -595,7 +603,9 @@ func AutocompleteRunlabelCommand(cmd *cobra.Command, args []string, toComplete s return nil, cobra.ShellCompDirectiveNoFileComp } if len(args) == 0 { - // FIXME: What labels can we recommend here? + // This is unfortunate because the argument order is label followed by image. + // If it would be the other way around we could inspect the first arg and get + // all labels from it to suggest them. return nil, cobra.ShellCompDirectiveNoFileComp } if len(args) == 1 { @@ -800,8 +810,7 @@ func AutocompleteLogDriver(cmd *cobra.Command, args []string, toComplete string) // AutocompleteLogOpt - Autocomplete log-opt options. // -> "path=", "tag=" func AutocompleteLogOpt(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - // FIXME: are these the only one? the man page states these but in the current shell completion they are more options - logOptions := []string{"path=", "tag="} + logOptions := []string{"path=", "tag=", "max-size="} if strings.HasPrefix(toComplete, "path=") { return nil, cobra.ShellCompDirectiveDefault } @@ -840,10 +849,26 @@ func AutocompleteSecurityOption(cmd *cobra.Command, args []string, toComplete st } // AutocompleteStopSignal - Autocomplete stop signal options. -// -> "SIGHUP", "SIGINT", "SIGKILL", "SIGTERM" +// Autocompletes signals both lower or uppercase depending on the user input. func AutocompleteStopSignal(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - // FIXME: add more/different signals? - stopSignals := []string{"SIGHUP", "SIGINT", "SIGKILL", "SIGTERM"} + // convertCase will convert a string to lowercase only if the user input is lowercase + convertCase := func(s string) string { return s } + if len(toComplete) > 0 && unicode.IsLower(rune(toComplete[0])) { + convertCase = strings.ToLower + } + + prefix := "" + // if input starts with "SI" we have to add SIG in front + // since the signal map does not have this prefix but the option + // allows signals with and without SIG prefix + if strings.HasPrefix(toComplete, convertCase("SI")) { + prefix = "SIG" + } + + stopSignals := make([]string, 0, len(signal.SignalMap)) + for sig := range signal.SignalMap { + stopSignals = append(stopSignals, convertCase(prefix+sig)) + } return stopSignals, cobra.ShellCompDirectiveNoFileComp } @@ -1146,7 +1171,7 @@ func getMethodNames(f reflect.Value, prefix string) []formatSuggestion { if kind == reflect.Struct || kind == reflect.Map { suffix = "." } - // From a template users POV it is not importent when the use a struct field or method. + // From a template users POV it is not important when the use a struct field or method. // They only notice the difference when the function requires arguments. // So lets be nice and let the user know that this method requires arguments via the help text. // Note since this is actually a method on a type the first argument is always fix so we should skip it. diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go index 29e138e30..c62ddd6eb 100644 --- a/cmd/podman/containers/create.go +++ b/cmd/podman/containers/create.go @@ -9,6 +9,7 @@ import ( "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/config" + cutil "github.com/containers/common/pkg/util" "github.com/containers/image/v5/transports/alltransports" "github.com/containers/image/v5/types" "github.com/containers/podman/v4/cmd/podman/common" @@ -116,7 +117,7 @@ func create(cmd *cobra.Command, args []string) error { if !cmd.Flags().Changed("pod") { return errors.New("must specify pod value with init-ctr") } - if !util.StringInSlice(initctr, []string{define.AlwaysInitContainer, define.OneShotInitContainer}) { + if !cutil.StringInSlice(initctr, []string{define.AlwaysInitContainer, define.OneShotInitContainer}) { return errors.Errorf("init-ctr value must be '%s' or '%s'", define.AlwaysInitContainer, define.OneShotInitContainer) } cliVals.InitContainerType = initctr diff --git a/cmd/podman/images/mount.go b/cmd/podman/images/mount.go index d5ab3d274..532d96196 100644 --- a/cmd/podman/images/mount.go +++ b/cmd/podman/images/mount.go @@ -7,7 +7,6 @@ import ( "github.com/containers/common/pkg/report" "github.com/containers/podman/v4/cmd/podman/common" "github.com/containers/podman/v4/cmd/podman/registry" - "github.com/containers/podman/v4/cmd/podman/utils" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -71,16 +70,12 @@ func mount(cmd *cobra.Command, args []string) error { return err } - if len(args) > 0 || mountOpts.All { - var errs utils.OutputErrors - for _, r := range reports { - if r.Err == nil { - fmt.Println(r.Path) - continue - } - errs = append(errs, r.Err) + if len(args) == 1 && mountOpts.Format == "" && !mountOpts.All { + if len(reports) != 1 { + return fmt.Errorf("internal error: expected 1 report but got %d", len(reports)) } - return errs.PrintErrors() + fmt.Println(reports[0].Path) + return nil } switch { diff --git a/cmd/podman/images/save.go b/cmd/podman/images/save.go index 3394c2e99..d85d688ee 100644 --- a/cmd/podman/images/save.go +++ b/cmd/podman/images/save.go @@ -6,12 +6,12 @@ import ( "strings" "github.com/containers/common/pkg/completion" + "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/cmd/podman/common" "github.com/containers/podman/v4/cmd/podman/parse" "github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/domain/entities" - "github.com/containers/podman/v4/pkg/util" "github.com/pkg/errors" "github.com/spf13/cobra" "golang.org/x/term" diff --git a/cmd/podman/images/search.go b/cmd/podman/images/search.go index 335ea2b5a..a18f7a11d 100644 --- a/cmd/podman/images/search.go +++ b/cmd/podman/images/search.go @@ -83,8 +83,7 @@ func searchFlags(cmd *cobra.Command) { filterFlagName := "filter" flags.StringSliceVarP(&searchOptions.Filters, filterFlagName, "f", []string{}, "Filter output based on conditions provided (default [])") - // TODO add custom filter function - _ = cmd.RegisterFlagCompletionFunc(filterFlagName, completion.AutocompleteNone) + _ = cmd.RegisterFlagCompletionFunc(filterFlagName, common.AutocompleteImageSearchFilters) formatFlagName := "format" flags.StringVar(&searchOptions.Format, formatFlagName, "", "Change the output format to JSON or a Go template") diff --git a/cmd/podman/images/trust_set.go b/cmd/podman/images/trust_set.go index fff035d12..f4ff0cffc 100644 --- a/cmd/podman/images/trust_set.go +++ b/cmd/podman/images/trust_set.go @@ -5,10 +5,10 @@ import ( "regexp" "github.com/containers/common/pkg/completion" + "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/cmd/podman/common" "github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/pkg/domain/entities" - "github.com/containers/podman/v4/pkg/util" "github.com/pkg/errors" "github.com/spf13/cobra" ) diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go index 62f820790..e2f80bdbc 100644 --- a/cmd/podman/pods/create.go +++ b/cmd/podman/pods/create.go @@ -16,7 +16,6 @@ import ( "github.com/containers/podman/v4/cmd/podman/containers" "github.com/containers/podman/v4/cmd/podman/parse" "github.com/containers/podman/v4/cmd/podman/registry" - "github.com/containers/podman/v4/cmd/podman/validate" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/errorhandling" @@ -36,12 +35,14 @@ var ( You can then start it at any time with the podman pod start <pod_id> command. The pod will be created with the initial state 'created'.` createCommand = &cobra.Command{ - Use: "create [options]", - Args: validate.NoArgs, + Use: "create [options] [NAME]", + Args: cobra.MaximumNArgs(1), Short: "Create a new empty pod", Long: podCreateDescription, RunE: create, ValidArgsFunction: completion.AutocompleteNone, + Example: `podman pod create + podman pod create --label foo=bar mypod`, } ) @@ -115,6 +116,12 @@ func create(cmd *cobra.Command, args []string) error { rawImageName string podName string ) + if len(args) > 0 { + if len(createOptions.Name) > 0 { + return fmt.Errorf("cannot specify --name and NAME at the same time") + } + createOptions.Name = args[0] + } labelFile = infraOptions.LabelFile labels = infraOptions.Label createOptions.Labels, err = parse.GetAllLabels(labelFile, labels) @@ -128,7 +135,7 @@ func create(cmd *cobra.Command, args []string) error { img := imageName if !createOptions.Infra { if cmd.Flag("no-hosts").Changed { - return fmt.Errorf("cannot specify no-hosts without an infra container") + return fmt.Errorf("cannot specify --no-hosts without an infra container") } flags := cmd.Flags() createOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags) @@ -159,7 +166,12 @@ func create(cmd *cobra.Command, args []string) error { if strings.Contains(share, "cgroup") && shareParent { return errors.Wrapf(define.ErrInvalidArg, "cannot define the pod as the cgroup parent at the same time as joining the infra container's cgroupNS") } - createOptions.Share = strings.Split(share, ",") + + if strings.HasPrefix(share, "+") { + createOptions.Share = append(createOptions.Share, strings.Split(specgen.DefaultKernelNamespaces, ",")...) + share = share[1:] + } + createOptions.Share = append(createOptions.Share, strings.Split(share, ",")...) createOptions.ShareParent = &shareParent if cmd.Flag("infra-command").Changed { // Only send content to server side if user changed defaults diff --git a/cmd/podman/pods/ps.go b/cmd/podman/pods/ps.go index 1275e65dc..a89448275 100644 --- a/cmd/podman/pods/ps.go +++ b/cmd/podman/pods/ps.go @@ -24,7 +24,7 @@ var ( // Command: podman pod _ps_ psCmd = &cobra.Command{ - Use: "ps [options]", + Use: "ps [options]", Aliases: []string{"ls", "list"}, Short: "List pods", Long: psDescription, diff --git a/cmd/podman/root.go b/cmd/podman/root.go index 2bd4fa723..1892ff9f7 100644 --- a/cmd/podman/root.go +++ b/cmd/podman/root.go @@ -423,7 +423,7 @@ func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) { // -s is deprecated due to conflict with -s on subcommands storageDriverFlagName := "storage-driver" pFlags.StringVar(&opts.StorageDriver, storageDriverFlagName, "", "Select which storage driver is used to manage storage of images and containers") - _ = cmd.RegisterFlagCompletionFunc(storageDriverFlagName, completion.AutocompleteNone) //TODO: what can we recommend here? + _ = cmd.RegisterFlagCompletionFunc(storageDriverFlagName, completion.AutocompleteNone) tmpdirFlagName := "tmpdir" pFlags.StringVar(&opts.Engine.TmpDir, tmpdirFlagName, "", "Path to the tmp directory for libpod state content.\n\nNote: use the environment variable 'TMPDIR' to change the temporary storage location for container images, '/var/tmp'.\n") diff --git a/cmd/podman/volumes/create.go b/cmd/podman/volumes/create.go index 1668c72de..b47ae16ce 100644 --- a/cmd/podman/volumes/create.go +++ b/cmd/podman/volumes/create.go @@ -17,6 +17,7 @@ var ( createCommand = &cobra.Command{ Use: "create [options] [NAME]", + Args: cobra.MaximumNArgs(1), Short: "Create a new volume", Long: createDescription, RunE: create, @@ -59,9 +60,6 @@ func create(cmd *cobra.Command, args []string) error { var ( err error ) - if len(args) > 1 { - return errors.Errorf("too many arguments, create takes at most 1 argument") - } if len(args) > 0 { createOpts.Name = args[0] } diff --git a/docs/source/markdown/podman-network-create.1.md b/docs/source/markdown/podman-network-create.1.md index 0cdb6fe88..1d89b12e3 100644 --- a/docs/source/markdown/podman-network-create.1.md +++ b/docs/source/markdown/podman-network-create.1.md @@ -4,7 +4,7 @@ podman\-network-create - Create a Podman network ## SYNOPSIS -**podman network create** [*options*] name +**podman network create** [*options*] [*name*] ## DESCRIPTION Create a CNI-network configuration for use with Podman. By default, Podman creates a bridge connection. diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md index fa431b611..cf749efda 100644 --- a/docs/source/markdown/podman-pod-create.1.md +++ b/docs/source/markdown/podman-pod-create.1.md @@ -4,14 +4,24 @@ podman\-pod\-create - Create a new pod ## SYNOPSIS -**podman pod create** [*options*] +**podman pod create** [*options*] [*name*] ## DESCRIPTION Creates an empty pod, or unit of multiple containers, and prepares it to have -containers added to it. The pod id is printed to STDOUT. You can then use -**podman create --pod `<pod_id|pod_name>` ...** to add containers to the pod, and -**podman pod start `<pod_id|pod_name>`** to start the pod. +containers added to it. The pod can be created with a specific name. If a name +is not given a random name is generated. The pod id is printed to STDOUT. You +can then use **podman create --pod `<pod_id|pod_name>` ...** to add containers +to the pod, and **podman pod start `<pod_id|pod_name>`** to start the pod. + +The operator can identify a pod in three ways: +UUID long identifier (“f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778”) +UUID short identifier (“f78375b1c487”) +Name (“jonah”) + +podman generates a UUID for each pod, and if a name is not assigned +to the container with **--name** then a random string name will be generated +for it. The name is useful any place you need to identify a pod. ## OPTIONS @@ -266,16 +276,7 @@ Note: Labeling can be disabled for all containers by setting label=false in the #### **--share**=*namespace* -A comma-separated list of kernel namespaces to share. If none or "" is specified, no namespaces will be shared. The namespaces to choose from are cgroup, ipc, net, pid, uts. - -The operator can identify a pod in three ways: -UUID long identifier (“f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778”) -UUID short identifier (“f78375b1c487”) -Name (“jonah”) - -podman generates a UUID for each pod, and if a name is not assigned -to the container with **--name** then a random string name will be generated -for it. The name is useful any place you need to identify a pod. +A comma-separated list of kernel namespaces to share. If none or "" is specified, no namespaces will be shared. The namespaces to choose from are cgroup, ipc, net, pid, uts. If the option is prefixed with a "+" then the namespace is appended to the default list, otherwise it replaces the default list. Defaults matches Kubernetes default (ipc, net, uts) #### **--share-parent** @@ -549,9 +550,11 @@ that data on the target. ``` $ podman pod create --name test +$ podman pod create mypod + $ podman pod create --infra=false -$ podman pod create --infra-command /top +$ podman pod create --infra-command /top toppod $ podman pod create --publish 8443:443 diff --git a/docs/source/markdown/podman-volume-create.1.md b/docs/source/markdown/podman-volume-create.1.md index 06fadcaa1..31e109791 100644 --- a/docs/source/markdown/podman-volume-create.1.md +++ b/docs/source/markdown/podman-volume-create.1.md @@ -4,7 +4,7 @@ podman\-volume\-create - Create a new volume ## SYNOPSIS -**podman volume create** [*options*] +**podman volume create** [*options*] [*name*] ## DESCRIPTION diff --git a/docs/tutorials/mac_experimental.md b/docs/tutorials/mac_experimental.md index b5b815fe5..1e75d01b8 100644 --- a/docs/tutorials/mac_experimental.md +++ b/docs/tutorials/mac_experimental.md @@ -1,4 +1,4 @@ -# Using podman-machine on MacOS (x86_64 and Apple silicon) +# Using podman-machine on MacOS (Apple silicon and x86_64) ## Setup @@ -12,7 +12,7 @@ require ( github.com/containernetworking/cni v1.1.0 github.com/containernetworking/plugins v1.1.1 github.com/containers/buildah v1.26.1 - github.com/containers/common v0.48.1-0.20220512112240-7536bf6ff9b1 + github.com/containers/common v0.48.1-0.20220523155016-2fd37da97824 github.com/containers/conmon v2.0.20+incompatible github.com/containers/image/v5 v5.21.2-0.20220519193817-1e26896b8059 github.com/containers/ocicrypt v1.1.4-0.20220428134531-566b808bdf6f @@ -340,11 +340,12 @@ github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19 github.com/containers/buildah v1.26.1 h1:D65Vuo+orsI14WWtJhSX6KrpgBBa7+hveVWevzG8p8E= github.com/containers/buildah v1.26.1/go.mod h1:CsWSG8OpJd8v3mlLREJzVAOBgC93DjRNALUVHoi8QsY= github.com/containers/common v0.48.0/go.mod h1:zPLZCfLXfnd1jI0QRsD4By54fP4k1+ifQs+tulIe3o0= -github.com/containers/common v0.48.1-0.20220512112240-7536bf6ff9b1 h1:U+2rYjzRCvI3WRSFf+Rohtu7jRgk/VhJjjFHbU6j0Sk= -github.com/containers/common v0.48.1-0.20220512112240-7536bf6ff9b1/go.mod h1:h8YZVXePE7UViJQ3fPWpYAaeDNYBCzGtL5dA3N8yfT8= +github.com/containers/common v0.48.1-0.20220523155016-2fd37da97824 h1:5gMIUUpIK9DvHrrlj1Tik8GfCh5DEuVqm0JnYHWYUDw= +github.com/containers/common v0.48.1-0.20220523155016-2fd37da97824/go.mod h1:Ru/JjL1CTHzlxghVMhchzcFUwHLvlIeR5/SUMw8VUOI= 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.21.1/go.mod h1:zl35egpcDQa79IEXIuoUe1bW+D1pdxRxYjNlyb3YiXw= +github.com/containers/image/v5 v5.21.2-0.20220511203756-fe4fd4ed8be4/go.mod h1:OsX9sFexyGF0FCNAjfcVFv3IwMqDyLyV/WQY/roLPcE= github.com/containers/image/v5 v5.21.2-0.20220519193817-1e26896b8059 h1:/FzsjrQ2nJtMom9IXEGieORlwUk/NyDuuz5SWcNo324= github.com/containers/image/v5 v5.21.2-0.20220519193817-1e26896b8059/go.mod h1:KntCBNQn3qOuZmQuJ38ORyTozmWXiuo05Vef2S0Sm5M= github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a h1:spAGlqziZjCJL25C6F1zsQY05tfCKE9F5YwtEWWe6hU= diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index d7683cce9..298eb1947 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -36,6 +36,7 @@ import ( "github.com/containers/common/pkg/config" "github.com/containers/common/pkg/subscriptions" "github.com/containers/common/pkg/umask" + cutil "github.com/containers/common/pkg/util" is "github.com/containers/image/v5/storage" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/events" @@ -393,7 +394,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { overrides := c.getUserOverrides() execUser, err := lookup.GetUserGroupInfo(c.state.Mountpoint, c.config.User, overrides) if err != nil { - if util.StringInSlice(c.config.User, c.config.HostUsers) { + if cutil.StringInSlice(c.config.User, c.config.HostUsers) { execUser, err = lookupHostUser(c.config.User) } if err != nil { @@ -2389,7 +2390,7 @@ func (c *Container) generateResolvConf() error { } if len(c.config.DNSSearch) > 0 || len(c.runtime.config.Containers.DNSSearches) > 0 { - if !util.StringInSlice(".", c.config.DNSSearch) { + if !cutil.StringInSlice(".", c.config.DNSSearch) { search = append(search, c.runtime.config.Containers.DNSSearches...) search = append(search, c.config.DNSSearch...) } @@ -3108,7 +3109,7 @@ func (c *Container) getOCICgroupPath() (string, error) { case c.config.NoCgroups: return "", nil case c.config.CgroupsMode == cgroupSplit: - selfCgroup, err := utils.GetOwnCgroup() + selfCgroup, err := utils.GetOwnCgroupDisallowRoot() if err != nil { return "", err } diff --git a/libpod/container_top_linux.go b/libpod/container_top_linux.go index 9b3dbc873..b30e0c732 100644 --- a/libpod/container_top_linux.go +++ b/libpod/container_top_linux.go @@ -96,7 +96,7 @@ func (c *Container) Top(descriptors []string) ([]string, error) { // For more details, please refer to github.com/containers/psgo. func (c *Container) GetContainerPidInformation(descriptors []string) ([]string, error) { pid := strconv.Itoa(c.state.PID) - // TODO: psgo returns a [][]string to give users the ability to apply + // NOTE: psgo returns a [][]string to give users the ability to apply // filters on the data. We need to change the API here // to return a [][]string if we want to make use of // filtering. diff --git a/libpod/events/events.go b/libpod/events/events.go index e83c2efee..a30e0f1ca 100644 --- a/libpod/events/events.go +++ b/libpod/events/events.go @@ -144,8 +144,6 @@ func StringToType(name string) (Type, error) { } // StringToStatus converts a string to an Event Status -// TODO if we add more events, we might consider a go-generator to -// create the switch statement func StringToStatus(name string) (Status, error) { switch name { case Attach.String(): diff --git a/libpod/kube.go b/libpod/kube.go index 5a5fe9d35..20c4612d1 100644 --- a/libpod/kube.go +++ b/libpod/kube.go @@ -14,6 +14,7 @@ import ( "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" + cutil "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/env" v1 "github.com/containers/podman/v4/pkg/k8s.io/api/core/v1" @@ -515,7 +516,7 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod, podDNS.Nameservers = make([]string, 0) } for _, s := range servers { - if !util.StringInSlice(s, podDNS.Nameservers) { // only append if it does not exist + if !cutil.StringInSlice(s, podDNS.Nameservers) { // only append if it does not exist podDNS.Nameservers = append(podDNS.Nameservers, s) } } @@ -526,7 +527,7 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod, podDNS.Searches = make([]string, 0) } for _, d := range domains { - if !util.StringInSlice(d, podDNS.Searches) { // only append if it does not exist + if !cutil.StringInSlice(d, podDNS.Searches) { // only append if it does not exist podDNS.Searches = append(podDNS.Searches, d) } } @@ -543,7 +544,7 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod, podName := removeUnderscores(ctrs[0].Name()) // Check if the pod name and container name will end up conflicting // Append -pod if so - if util.StringInSlice(podName, ctrNames) { + if cutil.StringInSlice(podName, ctrNames) { podName += "-pod" } @@ -824,7 +825,7 @@ func libpodMountsToKubeVolumeMounts(c *Container) ([]v1.VolumeMount, []v1.Volume // generateKubePersistentVolumeClaim converts a ContainerNamedVolume to a Kubernetes PersistentVolumeClaim func generateKubePersistentVolumeClaim(v *ContainerNamedVolume) (v1.VolumeMount, v1.Volume) { - ro := util.StringInSlice("ro", v.Options) + ro := cutil.StringInSlice("ro", v.Options) // To avoid naming conflicts with any host path mounts, add a unique suffix to the volume's name. name := v.Name + "-pvc" @@ -857,7 +858,7 @@ func generateKubeVolumeMount(m specs.Mount) (v1.VolumeMount, v1.Volume, error) { name += "-host" vm.Name = name vm.MountPath = m.Destination - if util.StringInSlice("ro", m.Options) { + if cutil.StringInSlice("ro", m.Options) { vm.ReadOnly = true } @@ -915,7 +916,7 @@ func determineCapAddDropFromCapabilities(defaultCaps, containerCaps []string) *v // Find caps in the defaultCaps but not in the container's // those indicate a dropped cap for _, capability := range defaultCaps { - if !util.StringInSlice(capability, containerCaps) { + if !cutil.StringInSlice(capability, containerCaps) { if _, ok := dedupDrop[capability]; !ok { drop = append(drop, v1.Capability(capability)) dedupDrop[capability] = true @@ -925,7 +926,7 @@ func determineCapAddDropFromCapabilities(defaultCaps, containerCaps []string) *v // Find caps in the container but not in the defaults; those indicate // an added cap for _, capability := range containerCaps { - if !util.StringInSlice(capability, defaultCaps) { + if !cutil.StringInSlice(capability, defaultCaps) { if _, ok := dedupAdd[capability]; !ok { add = append(add, v1.Capability(capability)) dedupAdd[capability] = true diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 0c124cf0b..73e64530e 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -25,13 +25,13 @@ import ( "github.com/containers/common/pkg/config" "github.com/containers/common/pkg/machine" "github.com/containers/common/pkg/netns" + "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/events" "github.com/containers/podman/v4/pkg/errorhandling" "github.com/containers/podman/v4/pkg/namespaces" "github.com/containers/podman/v4/pkg/resolvconf" "github.com/containers/podman/v4/pkg/rootless" - "github.com/containers/podman/v4/pkg/util" "github.com/containers/podman/v4/utils" "github.com/containers/storage/pkg/lockfile" spec "github.com/opencontainers/runtime-spec/specs-go" diff --git a/libpod/options.go b/libpod/options.go index feb89510f..a02c05537 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -12,6 +12,7 @@ import ( nettypes "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/common/pkg/secrets" + cutil "github.com/containers/common/pkg/util" "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/types" "github.com/containers/podman/v4/libpod/define" @@ -605,7 +606,7 @@ func WithSdNotifyMode(mode string) CtrCreateOption { } // verify values - if len(mode) > 0 && !util.StringInSlice(strings.ToLower(mode), SdNotifyModeValues) { + if len(mode) > 0 && !cutil.StringInSlice(strings.ToLower(mode), SdNotifyModeValues) { return errors.Wrapf(define.ErrInvalidArg, "--sdnotify values must be one of %q", strings.Join(SdNotifyModeValues, ", ")) } diff --git a/libpod/pod_top_linux.go b/libpod/pod_top_linux.go index 83a070807..544126dcd 100644 --- a/libpod/pod_top_linux.go +++ b/libpod/pod_top_linux.go @@ -53,7 +53,7 @@ func (p *Pod) GetPodPidInformation(descriptors []string) ([]string, error) { } } - // TODO: psgo returns a [][]string to give users the ability to apply + // NOTE: psgo returns a [][]string to give users the ability to apply // filters on the data. We need to change the API here to return // a [][]string if we want to make use of filtering. opts := psgo.JoinNamespaceOpts{FillMappings: rootless.IsRootless()} diff --git a/libpod/runtime.go b/libpod/runtime.go index 4efa7b8e8..00fa2fe88 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -11,6 +11,7 @@ import ( "regexp" "strconv" "strings" + "sync" "syscall" "time" @@ -87,8 +88,8 @@ type Runtime struct { lockManager lock.Manager // Worker - workerShutdown chan bool - workerChannel chan func() + workerChannel chan func() + workerGroup sync.WaitGroup // syslog describes whenever logrus should log to the syslog as well. // Note that the syslog hook will be enabled early in cmd/podman/syslog_linux.go @@ -823,12 +824,9 @@ func (r *Runtime) Shutdown(force bool) error { return define.ErrRuntimeStopped } - if r.workerShutdown != nil { - // Signal the worker routine to shutdown. The routine will - // process all pending work items and then read from the - // channel; we're blocked until all work items have been - // processed. - r.workerShutdown <- true + if r.workerChannel != nil { + r.workerGroup.Wait() + close(r.workerChannel) } r.valid = false diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index 2eaa77572..bdfc102ba 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -13,6 +13,7 @@ import ( "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/cgroups" "github.com/containers/common/pkg/config" + cutil "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/events" "github.com/containers/podman/v4/libpod/shutdown" @@ -246,7 +247,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai for _, opts := range ctr.config.Networks { if opts.InterfaceName != "" { // check that no name is assigned to more than network - if util.StringInSlice(opts.InterfaceName, usedIfNames) { + if cutil.StringInSlice(opts.InterfaceName, usedIfNames) { return nil, errors.Errorf("network interface name %q is already assigned to another network", opts.InterfaceName) } usedIfNames = append(usedIfNames, opts.InterfaceName) @@ -262,7 +263,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai if opts.InterfaceName == "" { for i < 100000 { ifName := fmt.Sprintf("eth%d", i) - if !util.StringInSlice(ifName, usedIfNames) { + if !cutil.StringInSlice(ifName, usedIfNames) { opts.InterfaceName = ifName usedIfNames = append(usedIfNames, ifName) break diff --git a/libpod/runtime_pod.go b/libpod/runtime_pod.go index dca0ffc8a..ee3d40484 100644 --- a/libpod/runtime_pod.go +++ b/libpod/runtime_pod.go @@ -4,8 +4,8 @@ import ( "context" "time" + "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/libpod/define" - "github.com/containers/podman/v4/pkg/util" "github.com/pkg/errors" ) diff --git a/libpod/runtime_worker.go b/libpod/runtime_worker.go index ca44a27f7..9d41321b2 100644 --- a/libpod/runtime_worker.go +++ b/libpod/runtime_worker.go @@ -1,40 +1,17 @@ package libpod -import ( - "time" -) - func (r *Runtime) startWorker() { - if r.workerChannel == nil { - r.workerChannel = make(chan func(), 1) - r.workerShutdown = make(chan bool) - } + r.workerChannel = make(chan func(), 10) go func() { - for { - // Make sure to read all workers before - // checking if we're about to shutdown. - for len(r.workerChannel) > 0 { - w := <-r.workerChannel - w() - } - - select { - // We'll read from the shutdown channel only when all - // items above have been processed. - // - // (*Runtime).Shutdown() will block until until the - // item is read. - case <-r.workerShutdown: - return - - default: - time.Sleep(100 * time.Millisecond) - } + for w := range r.workerChannel { + w() + r.workerGroup.Done() } }() } func (r *Runtime) queueWork(f func()) { + r.workerGroup.Add(1) go func() { r.workerChannel <- f }() diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index 8c4dea327..76a28fadf 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -460,8 +460,6 @@ func GetImages(w http.ResponseWriter, r *http.Request) { } func LoadImages(w http.ResponseWriter, r *http.Request) { - // TODO this is basically wrong - // TODO ... improve these ^ messages to something useful decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index bcd102901..ba6764e91 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -170,7 +170,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { // convert addcaps formats containerFiles := []string{} - // Tells if query paramemter `dockerfile` is set or not. + // Tells if query parameter `dockerfile` is set or not. dockerFileSet := false if utils.IsLibpodRequest(r) && query.Remote != "" { // The context directory could be a URL. Try to handle that. @@ -674,15 +674,17 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { enc := json.NewEncoder(body) enc.SetEscapeHTML(true) + var stepErrors []string for { - m := struct { + type BuildResponse struct { Stream string `json:"stream,omitempty"` Error *jsonmessage.JSONError `json:"errorDetail,omitempty"` // NOTE: `error` is being deprecated check https://github.com/moby/moby/blob/master/pkg/jsonmessage/jsonmessage.go#L148 ErrorMessage string `json:"error,omitempty"` // deprecate this slowly Aux json.RawMessage `json:"aux,omitempty"` - }{} + } + m := BuildResponse{} select { case e := <-stdout.Chan(): @@ -698,12 +700,27 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { } flush() case e := <-auxout.Chan(): - m.Stream = string(e) - if err := enc.Encode(m); err != nil { - stderr.Write([]byte(err.Error())) + if !query.Quiet { + m.Stream = string(e) + if err := enc.Encode(m); err != nil { + stderr.Write([]byte(err.Error())) + } + flush() + } else { + stepErrors = append(stepErrors, string(e)) } - flush() case e := <-stderr.Chan(): + // Docker-API Compat parity : Build failed so + // output all step errors irrespective of quiet + // flag. + for _, stepError := range stepErrors { + t := BuildResponse{} + t.Stream = stepError + if err := enc.Encode(t); err != nil { + stderr.Write([]byte(err.Error())) + } + flush() + } m.ErrorMessage = string(e) m.Error = &jsonmessage.JSONError{ Message: m.ErrorMessage, diff --git a/pkg/auth/auth.go b/pkg/auth/auth.go index 419225007..3a78436d7 100644 --- a/pkg/auth/auth.go +++ b/pkg/auth/auth.go @@ -245,8 +245,6 @@ func authConfigsToAuthFile(authConfigs map[string]types.DockerAuthConfig) (strin } authFilePath := tmpFile.Name() - // TODO: It would be nice if c/image could dump the map at once. - // // Now use the c/image packages to store the credentials. It's battle // tested, and we make sure to use the same code as the image backend. sys := types.SystemContext{AuthFilePath: authFilePath} diff --git a/pkg/bindings/containers/archive.go b/pkg/bindings/containers/archive.go index 4f4b5a36a..dd489d6f1 100644 --- a/pkg/bindings/containers/archive.go +++ b/pkg/bindings/containers/archive.go @@ -55,8 +55,6 @@ func CopyFromArchive(ctx context.Context, nameOrID string, path string, reader i } // CopyFromArchiveWithOptions copy files into container -// -// FIXME: remove this function and make CopyFromArchive accept the option as the last parameter in podman 4.0 func CopyFromArchiveWithOptions(ctx context.Context, nameOrID string, path string, reader io.Reader, options *CopyOptions) (entities.ContainerCopyFunc, error) { conn, err := bindings.GetClient(ctx) if err != nil { diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go index 8e3b07929..32372019b 100644 --- a/pkg/bindings/images/images.go +++ b/pkg/bindings/images/images.go @@ -280,7 +280,6 @@ func Push(ctx context.Context, source string, destination string, options *PushO if err != nil { return err } - // TODO: have a global system context we can pass around (1st argument) header, err := auth.MakeXRegistryAuthHeader(&imageTypes.SystemContext{AuthFilePath: options.GetAuthfile()}, options.GetUsername(), options.GetPassword()) if err != nil { return err @@ -329,7 +328,6 @@ func Search(ctx context.Context, term string, options *SearchOptions) ([]entitie params.Set("tlsVerify", strconv.FormatBool(!options.GetSkipTLSVerify())) } - // TODO: have a global system context we can pass around (1st argument) header, err := auth.MakeXRegistryAuthHeader(&imageTypes.SystemContext{AuthFilePath: options.GetAuthfile()}, "", "") if err != nil { return nil, err diff --git a/pkg/bindings/images/pull.go b/pkg/bindings/images/pull.go index 20e47179c..de02c62fd 100644 --- a/pkg/bindings/images/pull.go +++ b/pkg/bindings/images/pull.go @@ -42,7 +42,6 @@ func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string, params.Set("tlsVerify", strconv.FormatBool(!options.GetSkipTLSVerify())) } - // TODO: have a global system context we can pass around (1st argument) header, err := auth.MakeXRegistryAuthHeader(&types.SystemContext{AuthFilePath: options.GetAuthfile()}, options.GetUsername(), options.GetPassword()) if err != nil { return nil, err diff --git a/pkg/bindings/images/rm.go b/pkg/bindings/images/rm.go index b80bacf45..eb3eef10c 100644 --- a/pkg/bindings/images/rm.go +++ b/pkg/bindings/images/rm.go @@ -16,9 +16,6 @@ func Remove(ctx context.Context, images []string, options *RemoveOptions) (*enti if options == nil { options = new(RemoveOptions) } - // FIXME - bindings tests are missing for this endpoint. Once the CI is - // re-enabled for bindings, we need to add them. At the time of writing, - // the tests don't compile. var report types.LibpodImagesRemoveReport conn, err := bindings.GetClient(ctx) if err != nil { diff --git a/pkg/bindings/play/play.go b/pkg/bindings/play/play.go index 8058a8514..0261b0250 100644 --- a/pkg/bindings/play/play.go +++ b/pkg/bindings/play/play.go @@ -46,7 +46,6 @@ func KubeWithBody(ctx context.Context, body io.Reader, options *KubeOptions) (*e params.Set("start", strconv.FormatBool(options.GetStart())) } - // TODO: have a global system context we can pass around (1st argument) header, err := auth.MakeXRegistryAuthHeader(&types.SystemContext{AuthFilePath: options.GetAuthfile()}, options.GetUsername(), options.GetPassword()) if err != nil { return nil, err diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go index 7081c5d25..2bb4ceb5b 100644 --- a/pkg/domain/entities/images.go +++ b/pkg/domain/entities/images.go @@ -66,10 +66,9 @@ type ImageSummary struct { Dangling bool `json:",omitempty"` // Podman extensions - Names []string `json:",omitempty"` - Digest string `json:",omitempty"` - ConfigDigest string `json:",omitempty"` - History []string `json:",omitempty"` + Names []string `json:",omitempty"` + Digest string `json:",omitempty"` + History []string `json:",omitempty"` } func (i *ImageSummary) Id() string { // nolint @@ -398,7 +397,6 @@ type ImageUnmountOptions struct { // ImageMountReport describes the response from image mount type ImageMountReport struct { - Err error Id string // nolint Name string Repositories []string diff --git a/pkg/domain/filters/containers.go b/pkg/domain/filters/containers.go index 3e5b9cad9..e2ab8d70c 100644 --- a/pkg/domain/filters/containers.go +++ b/pkg/domain/filters/containers.go @@ -6,6 +6,7 @@ import ( "strings" "time" + cutil "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/util" @@ -257,7 +258,7 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo return false } for _, net := range networks { - if util.StringInSlice(net, inputNetNames) { + if cutil.StringInSlice(net, inputNetNames) { return true } } diff --git a/pkg/domain/filters/pods.go b/pkg/domain/filters/pods.go index e22480006..c2ed359f5 100644 --- a/pkg/domain/filters/pods.go +++ b/pkg/domain/filters/pods.go @@ -4,6 +4,7 @@ import ( "strconv" "strings" + cutil "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/util" @@ -57,7 +58,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti }, nil case "ctr-status": for _, filterValue := range filterValues { - if !util.StringInSlice(filterValue, []string{"created", "running", "paused", "stopped", "exited", "unknown"}) { + if !cutil.StringInSlice(filterValue, []string{"created", "running", "paused", "stopped", "exited", "unknown"}) { return nil, errors.Errorf("%s is not a valid status", filterValue) } } @@ -94,7 +95,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti }, nil case "status": for _, filterValue := range filterValues { - if !util.StringInSlice(filterValue, []string{"stopped", "running", "paused", "exited", "dead", "created", "degraded"}) { + if !cutil.StringInSlice(filterValue, []string{"stopped", "running", "paused", "exited", "dead", "created", "degraded"}) { return nil, errors.Errorf("%s is not a valid pod status", filterValue) } } @@ -150,7 +151,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti return false } for _, net := range networks { - if util.StringInSlice(net, inputNetNames) { + if cutil.StringInSlice(net, inputNetNames) { return true } } diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index c3ec7dd8a..d469fa0ca 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -159,10 +159,6 @@ func (ir *ImageEngine) Mount(ctx context.Context, nameOrIDs []string, opts entit mountReports := []*entities.ImageMountReport{} listMountsOnly := !opts.All && len(nameOrIDs) == 0 for _, i := range images { - // TODO: the .Err fields are not used. This pre-dates the - // libimage migration but should be addressed at some point. - // A quick glimpse at cmd/podman/image/mount.go suggests that - // the errors needed to be handled there as well. var mountPoint string var err error if listMountsOnly { diff --git a/pkg/domain/infra/abi/images_list.go b/pkg/domain/infra/abi/images_list.go index 9a0aaaf3a..8f5591e92 100644 --- a/pkg/domain/infra/abi/images_list.go +++ b/pkg/domain/infra/abi/images_list.go @@ -36,9 +36,7 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) } e := entities.ImageSummary{ - ID: img.ID(), - // TODO: libpod/image didn't set it but libimage should - // ConfigDigest: string(img.ConfigDigest), + ID: img.ID(), Created: img.Created().Unix(), Dangling: isDangling, Digest: string(img.Digest()), diff --git a/pkg/domain/infra/abi/images_test.go b/pkg/domain/infra/abi/images_test.go index 311ab3ed7..3999de457 100644 --- a/pkg/domain/infra/abi/images_test.go +++ b/pkg/domain/infra/abi/images_test.go @@ -16,39 +16,3 @@ func TestToDomainHistoryLayer(t *testing.T) { newLayer := toDomainHistoryLayer(&layer) assert.Equal(t, layer.Size, newLayer.Size) } - -// -// import ( -// "context" -// "testing" -// -// "github.com/stretchr/testify/mock" -// ) -// -// type MockImageRuntime struct { -// mock.Mock -// } -// -// func (m *MockImageRuntime) Delete(ctx context.Context, renderer func() interface{}, name string) error { -// _ = m.Called(ctx, renderer, name) -// return nil -// } -// -// func TestImageSuccess(t *testing.T) { -// actual := func() interface{} { return nil } -// -// m := new(MockImageRuntime) -// m.On( -// "Delete", -// mock.AnythingOfType("*context.emptyCtx"), -// mock.AnythingOfType("func() interface {}"), -// "fedora"). -// Return(nil) -// -// r := DirectImageRuntime{m} -// err := r.Delete(context.TODO(), actual, "fedora") -// if err != nil { -// t.Errorf("should be nil, got: %v", err) -// } -// m.AssertExpectations(t) -// } diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go index 910008fc7..47f7917f4 100644 --- a/pkg/domain/infra/abi/network.go +++ b/pkg/domain/infra/abi/network.go @@ -5,9 +5,9 @@ import ( "github.com/containers/common/libnetwork/types" netutil "github.com/containers/common/libnetwork/util" + "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/domain/entities" - "github.com/containers/podman/v4/pkg/util" "github.com/pkg/errors" ) diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go index 10f3e70b1..2ce190464 100644 --- a/pkg/domain/infra/abi/system.go +++ b/pkg/domain/infra/abi/system.go @@ -10,6 +10,7 @@ import ( "github.com/containers/common/pkg/cgroups" "github.com/containers/common/pkg/config" + cutil "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/domain/entities/reports" @@ -307,7 +308,7 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System reclaimableSize += volSize } for _, viu := range inUse { - if util.StringInSlice(viu, runningContainers) { + if cutil.StringInSlice(viu, runningContainers) { consInUse++ } } diff --git a/pkg/inspect/inspect.go b/pkg/inspect/inspect.go index 767d86daf..15943858f 100644 --- a/pkg/inspect/inspect.go +++ b/pkg/inspect/inspect.go @@ -41,18 +41,3 @@ type RootFS struct { Type string `json:"Type"` Layers []digest.Digest `json:"Layers"` } - -// ImageResult is used for podman images for collection and output. -type ImageResult struct { - Tag string - Repository string - RepoDigests []string - RepoTags []string - ID string - Digest digest.Digest - ConfigDigest digest.Digest - Created time.Time - Size *uint64 - Labels map[string]string - Dangling bool -} diff --git a/pkg/machine/e2e/list_test.go b/pkg/machine/e2e/list_test.go index 0bc867047..1c8c6ac81 100644 --- a/pkg/machine/e2e/list_test.go +++ b/pkg/machine/e2e/list_test.go @@ -3,7 +3,7 @@ package e2e import ( "strings" - "github.com/containers/buildah/util" + "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/cmd/podman/machine" jsoniter "github.com/json-iterator/go" . "github.com/onsi/ginkgo" diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go index 6e36b0886..e3fb3b970 100644 --- a/pkg/machine/qemu/machine.go +++ b/pkg/machine/qemu/machine.go @@ -1545,7 +1545,7 @@ func (v *MachineVM) editCmdLine(flag string, value string) { } } -// RemoveAndCleanMachines removes all machine and cleans up any other files associatied with podman machine +// RemoveAndCleanMachines removes all machine and cleans up any other files associated with podman machine func (p *Provider) RemoveAndCleanMachines() error { var ( vm machine.VM diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go index 0b2874baf..06020aded 100644 --- a/pkg/machine/wsl/machine.go +++ b/pkg/machine/wsl/machine.go @@ -831,16 +831,16 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) ([]error, error) { } if opts.CPUs != nil { - setErrors = append(setErrors, errors.Errorf("changing CPUs not suppored for WSL machines")) + setErrors = append(setErrors, errors.Errorf("changing CPUs not supported for WSL machines")) } if opts.Memory != nil { - setErrors = append(setErrors, errors.Errorf("changing memory not suppored for WSL machines")) + setErrors = append(setErrors, errors.Errorf("changing memory not supported for WSL machines")) } if opts.DiskSize != nil { - setErrors = append(setErrors, errors.Errorf("changing Disk Size not suppored for WSL machines")) + setErrors = append(setErrors, errors.Errorf("changing Disk Size not supported for WSL machines")) } return setErrors, v.writeConfig() @@ -1477,7 +1477,7 @@ func (v *MachineVM) getResources() (resources machine.ResourceConfig) { return } -// RemoveAndCleanMachines removes all machine and cleans up any other files associatied with podman machine +// RemoveAndCleanMachines removes all machine and cleans up any other files associated with podman machine func (p *Provider) RemoveAndCleanMachines() error { var ( vm machine.VM diff --git a/pkg/signal/signal_common.go b/pkg/signal/signal_common.go index 5ea67843a..fe5a76dae 100644 --- a/pkg/signal/signal_common.go +++ b/pkg/signal/signal_common.go @@ -17,7 +17,7 @@ func ParseSignal(rawSignal string) (syscall.Signal, error) { } return syscall.Signal(s), nil } - sig, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")] + sig, ok := SignalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")] if !ok { return -1, fmt.Errorf("invalid signal: %s", rawSignal) } @@ -32,7 +32,7 @@ func ParseSignalNameOrNumber(rawSignal string) (syscall.Signal, error) { if err == nil { return s, nil } - for k, v := range signalMap { + for k, v := range SignalMap { if k == strings.ToUpper(basename) { return v, nil } diff --git a/pkg/signal/signal_linux.go b/pkg/signal/signal_linux.go index 21e09c9fe..a114ea019 100644 --- a/pkg/signal/signal_linux.go +++ b/pkg/signal/signal_linux.go @@ -23,8 +23,8 @@ const ( SIGWINCH = syscall.SIGWINCH // For cross-compilation with Windows ) -// signalMap is a map of Linux signals. -var signalMap = map[string]syscall.Signal{ +// SignalMap is a map of Linux signals. +var SignalMap = map[string]syscall.Signal{ "ABRT": unix.SIGABRT, "ALRM": unix.SIGALRM, "BUS": unix.SIGBUS, @@ -94,8 +94,8 @@ var signalMap = map[string]syscall.Signal{ // CatchAll catches all signals and relays them to the specified channel. func CatchAll(sigc chan os.Signal) { - handledSigs := make([]os.Signal, 0, len(signalMap)) - for _, s := range signalMap { + handledSigs := make([]os.Signal, 0, len(SignalMap)) + for _, s := range SignalMap { handledSigs = append(handledSigs, s) } signal.Notify(sigc, handledSigs...) diff --git a/pkg/signal/signal_linux_mipsx.go b/pkg/signal/signal_linux_mipsx.go index 52b07aaf4..9021a10e7 100644 --- a/pkg/signal/signal_linux_mipsx.go +++ b/pkg/signal/signal_linux_mipsx.go @@ -24,8 +24,8 @@ const ( SIGWINCH = syscall.SIGWINCH ) -// signalMap is a map of Linux signals. -var signalMap = map[string]syscall.Signal{ +// SignalMap is a map of Linux signals. +var SignalMap = map[string]syscall.Signal{ "ABRT": unix.SIGABRT, "ALRM": unix.SIGALRM, "BUS": unix.SIGBUS, @@ -95,8 +95,8 @@ var signalMap = map[string]syscall.Signal{ // CatchAll catches all signals and relays them to the specified channel. func CatchAll(sigc chan os.Signal) { - handledSigs := make([]os.Signal, 0, len(signalMap)) - for _, s := range signalMap { + handledSigs := make([]os.Signal, 0, len(SignalMap)) + for _, s := range SignalMap { handledSigs = append(handledSigs, s) } signal.Notify(sigc, handledSigs...) diff --git a/pkg/signal/signal_unix.go b/pkg/signal/signal_unix.go index c0aa62d21..0f43e21b7 100644 --- a/pkg/signal/signal_unix.go +++ b/pkg/signal/signal_unix.go @@ -16,12 +16,12 @@ const ( SIGWINCH = syscall.SIGWINCH ) -// signalMap is a map of Linux signals. +// SignalMap is a map of Linux signals. // These constants are sourced from the Linux version of golang.org/x/sys/unix // (I don't see much risk of this changing). // This should work as long as Podman only runs containers on Linux, which seems // a safe assumption for now. -var signalMap = map[string]syscall.Signal{ +var SignalMap = map[string]syscall.Signal{ "ABRT": syscall.Signal(0x6), "ALRM": syscall.Signal(0xe), "BUS": syscall.Signal(0x7), diff --git a/pkg/signal/signal_unsupported.go b/pkg/signal/signal_unsupported.go index d8bba7c90..9d0cee317 100644 --- a/pkg/signal/signal_unsupported.go +++ b/pkg/signal/signal_unsupported.go @@ -16,12 +16,12 @@ const ( SIGWINCH = syscall.Signal(0xff) ) -// signalMap is a map of Linux signals. +// SignalMap is a map of Linux signals. // These constants are sourced from the Linux version of golang.org/x/sys/unix // (I don't see much risk of this changing). // This should work as long as Podman only runs containers on Linux, which seems // a safe assumption for now. -var signalMap = map[string]syscall.Signal{ +var SignalMap = map[string]syscall.Signal{ "ABRT": syscall.Signal(0x6), "ALRM": syscall.Signal(0xe), "BUS": syscall.Signal(0x7), diff --git a/pkg/specgen/container_validate.go b/pkg/specgen/container_validate.go index 355fbc368..532a2094f 100644 --- a/pkg/specgen/container_validate.go +++ b/pkg/specgen/container_validate.go @@ -4,9 +4,9 @@ import ( "strconv" "strings" + "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/rootless" - "github.com/containers/podman/v4/pkg/util" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" ) diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index f37d79798..689c740f0 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -16,6 +16,7 @@ import ( "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/parse" "github.com/containers/common/pkg/secrets" + cutil "github.com/containers/common/pkg/util" "github.com/containers/image/v5/manifest" "github.com/containers/podman/v4/libpod/define" ann "github.com/containers/podman/v4/pkg/annotations" @@ -356,7 +357,7 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener // a selinux mount option exists for it for k, v := range opts.Annotations { // Make sure the z/Z option is not already there (from editing the YAML) - if strings.Replace(k, define.BindMountPrefix, "", 1) == volumeSource.Source && !util.StringInSlice("z", options) && !util.StringInSlice("Z", options) { + if strings.Replace(k, define.BindMountPrefix, "", 1) == volumeSource.Source && !cutil.StringInSlice("z", options) && !cutil.StringInSlice("Z", options) { options = append(options, v) } } diff --git a/pkg/specgen/generate/ports.go b/pkg/specgen/generate/ports.go index bec548d3b..4243630e2 100644 --- a/pkg/specgen/generate/ports.go +++ b/pkg/specgen/generate/ports.go @@ -10,9 +10,9 @@ import ( "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v4/utils" + "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/pkg/specgen" "github.com/containers/podman/v4/pkg/specgenutil" - "github.com/containers/podman/v4/pkg/util" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) diff --git a/pkg/specgen/generate/security.go b/pkg/specgen/generate/security.go index ec52164ab..7268ec318 100644 --- a/pkg/specgen/generate/security.go +++ b/pkg/specgen/generate/security.go @@ -7,6 +7,7 @@ import ( "github.com/containers/common/pkg/apparmor" "github.com/containers/common/pkg/capabilities" "github.com/containers/common/pkg/config" + cutil "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/specgen" @@ -120,7 +121,7 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, // capabilities, required to run the container. var capsRequiredRequested []string for key, val := range s.Labels { - if util.StringInSlice(key, capabilities.ContainerImageLabels) { + if cutil.StringInSlice(key, capabilities.ContainerImageLabels) { capsRequiredRequested = strings.Split(val, ",") } } @@ -132,7 +133,7 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, } // Verify all capRequired are in the capList for _, cap := range capsRequired { - if !util.StringInSlice(cap, caplist) { + if !cutil.StringInSlice(cap, caplist) { privCapsRequired = append(privCapsRequired, cap) } } diff --git a/pkg/specgen/generate/validate.go b/pkg/specgen/generate/validate.go index 44c7818e7..a1affef31 100644 --- a/pkg/specgen/generate/validate.go +++ b/pkg/specgen/generate/validate.go @@ -1,6 +1,7 @@ package generate import ( + "io/ioutil" "os" "path/filepath" @@ -166,6 +167,14 @@ func verifyContainerResourcesCgroupV2(s *specgen.SpecGenerator) ([]string, error if err != nil { return warnings, err } + + if own == "/" { + // If running under the root cgroup try to create or reuse a "probe" cgroup to read memory values + own = "podman_probe" + _ = os.MkdirAll(filepath.Join("/sys/fs/cgroup", own), 0o755) + _ = ioutil.WriteFile("/sys/fs/cgroup/cgroup.subtree_control", []byte("+memory"), 0o644) + } + memoryMax := filepath.Join("/sys/fs/cgroup", own, "memory.max") memorySwapMax := filepath.Join("/sys/fs/cgroup", own, "memory.swap.max") _, errMemoryMax := os.Stat(memoryMax) diff --git a/pkg/specgen/namespaces.go b/pkg/specgen/namespaces.go index 7a7ca2706..5a3b94ca4 100644 --- a/pkg/specgen/namespaces.go +++ b/pkg/specgen/namespaces.go @@ -8,6 +8,7 @@ import ( "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/cgroups" + cutil "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/rootless" "github.com/containers/podman/v4/pkg/util" @@ -472,7 +473,7 @@ func ParseNetworkFlag(networks []string) (Namespace, map[string]types.PerNetwork if parts[0] == "" { return toReturn, nil, nil, errors.Wrapf(define.ErrInvalidArg, "network name cannot be empty") } - if util.StringInSlice(parts[0], []string{string(Bridge), string(Slirp), string(FromPod), string(NoNetwork), + if cutil.StringInSlice(parts[0], []string{string(Bridge), string(Slirp), string(FromPod), string(NoNetwork), string(Default), string(Private), string(Path), string(FromContainer), string(Host)}) { return toReturn, nil, nil, errors.Wrapf(define.ErrInvalidArg, "can only set extra network names, selected mode %s conflicts with bridge", parts[0]) } diff --git a/pkg/util/utils.go b/pkg/util/utils.go index a0bf8b50d..ad5db9a1a 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -17,6 +17,7 @@ import ( "github.com/BurntSushi/toml" "github.com/containers/common/pkg/config" + "github.com/containers/common/pkg/util" "github.com/containers/image/v5/types" "github.com/containers/podman/v4/pkg/errorhandling" "github.com/containers/podman/v4/pkg/namespaces" @@ -78,14 +79,9 @@ func ParseRegistryCreds(creds string) (*types.DockerAuthConfig, error) { }, nil } -// StringInSlice determines if a string is in a string slice, returns bool +// StringInSlice is deprecated, use containers/common/pkg/util/StringInSlice func StringInSlice(s string, sl []string) bool { - for _, i := range sl { - if i == s { - return true - } - } - return false + return util.StringInSlice(s, sl) } // StringMatchRegexSlice determines if a given string matches one of the given regexes, returns bool diff --git a/test/apiv2/10-images.at b/test/apiv2/10-images.at index fd04e3f1b..13aaea317 100644 --- a/test/apiv2/10-images.at +++ b/test/apiv2/10-images.at @@ -225,6 +225,18 @@ t POST "images/load" ${TMPD}/test.tar 200 \ t GET libpod/images/quay.io/libpod/alpine:latest/exists 204 t GET libpod/images/quay.io/libpod/busybox:latest/exists 204 +CONTAINERFILE_WITH_ERR_TAR="${TMPD}/containerfile.tar" +cat > $TMPD/containerfile << EOF +FROM quay.io/fedora/fedora +RUN echo 'some error' >&2 +EOF +tar --format=posix -C $TMPD -cvf ${CONTAINERFILE_WITH_ERR_TAR} containerfile &> /dev/null +t POST "build?q=1&dockerfile=containerfile" $CONTAINERFILE_WITH_ERR_TAR 200 +response_output=$(cat "$WORKDIR/curl.result.out") +if [[ ${response_output} == *"some error"* ]];then + _show_ok 0 "compat quiet build" "~ $response_output" "found output from stderr in API" +fi + cleanBuildTest # vim: filetype=sh diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index 3b32b4b82..4081ec45b 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -381,7 +381,7 @@ EXPOSE 2004-2005/tcp`, ALPINE) session := podmanTest.Podman([]string{"run", "-dt", "-p", fmt.Sprintf("%d:%d", port1, port2), ALPINE, "/bin/sh"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - results := SystemExec("iptables", []string{"-t", "nat", "-L"}) + results := SystemExec("iptables", []string{"-t", "nat", "-nvL"}) Expect(results).Should(Exit(0)) Expect(results.OutputToString()).To(ContainSubstring(fmt.Sprintf("%d", port2))) diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go index 64677ba54..d37d8fd1a 100644 --- a/test/e2e/search_test.go +++ b/test/e2e/search_test.go @@ -455,7 +455,6 @@ registries = ['{{.Host}}:{{.Port}}']` }) It("podman search with wildcards", func() { - Skip("FIXME: search on registry.redhat.io is broken (Dec 16 '21)") search := podmanTest.Podman([]string{"search", "registry.redhat.io/*openshift*"}) search.WaitWithDefaultTimeout() Expect(search).Should(Exit(0)) diff --git a/test/system/015-help.bats b/test/system/015-help.bats index 5757d51dc..1356c99a0 100644 --- a/test/system/015-help.bats +++ b/test/system/015-help.bats @@ -34,10 +34,16 @@ function check_help() { # has no ' [options]' is "$usage " " $command_string .*" "Usage string matches command" + # Strip off the leading command string; we no longer need it + usage=$(sed -e "s/^ $command_string \?//" <<<"$usage") + # If usage ends in '[command]', recurse into subcommands - if expr "$usage" : '.*\[command\]$' >/dev/null; then + if expr "$usage" : '\[command\]' >/dev/null; then found[subcommands]=1 - check_help "$@" $cmd + # (except for 'podman help', which is a special case) + if [[ $cmd != "help" ]]; then + check_help "$@" $cmd + fi continue fi @@ -49,10 +55,26 @@ function check_help() { assert "$usage" !~ '[A-Z].*\[option' \ "'options' must precede arguments in usage" + # Strip off '[options]' but remember if we've seen it. + local has_options= + if [[ $usage =~ \[options\] ]]; then + has_options=1 + usage=$(sed -e 's/^\[options\] \?//' <<<"$usage") + fi + + # From this point on, remaining argument descriptions must be UPPER CASE + # e.g., 'podman cmd [options] arg' or 'podman cmd [arg]' are invalid. + assert "$usage" !~ '[a-z]' \ + "$command_string: argument names must be UPPER CASE" + + # It makes no sense to have an optional arg followed by a mandatory one + assert "$usage" !~ '\[.*\] [A-Z]' \ + "$command_string: optional args must be _after_ required ones" + # Cross-check: if usage includes '[options]', there must be a # longer 'Options:' section in the full --help output; vice-versa, # if 'Options:' is in full output, usage line must have '[options]'. - if expr "$usage" : '.*\[option' >/dev/null; then + if [[ $has_options ]]; then if ! expr "$full_help" : ".*Options:" >/dev/null; then die "$command_string: Usage includes '[options]' but has no 'Options:' subsection" fi @@ -95,9 +117,7 @@ function check_help() { fi # If usage has required arguments, try running without them. - # The expression here is 'first capital letter is not in [BRACKETS]'. - # It is intended to handle 'podman foo [options] ARG' but not ' [ARG]'. - if expr "$usage" : '[^A-Z]\+ [A-Z]' >/dev/null; then + if expr "$usage" : '[A-Z]' >/dev/null; then # Exceptions: these commands don't work rootless if is_rootless; then # "pause is not supported for rootless containers" @@ -126,25 +146,15 @@ function check_help() { # the required args, then invoke with one extra. We should get a # usage error. if ! expr "$usage" : ".*\.\.\."; then - # "podman help" can take infinite args, so skip that one - if [ "$cmd" != "help" ]; then - # Get the args part of the command line; this should be - # everything from the first CAPITAL LETTER onward. We - # don't actually care about the letter itself, so just - # make it 'X'. And we don't care about [OPTIONAL] brackets - # either. What we do care about is stuff like 'IMAGE | CTR' - # which is actually one argument; convert to 'IMAGE-or-CTR' - local rhs=$(sed -e 's/^[^A-Z]\+[A-Z]/X/' -e 's/ | /-or-/g' <<<"$usage") - local n_args=$(wc -w <<<"$rhs") - - run_podman '?' "$@" $cmd $(seq --format='x%g' 0 $n_args) - is "$status" 125 \ - "'$usage' indicates a maximum of $n_args args. I invoked it with more, and expected this exit status" - is "$output" "Error:.* \(takes no arguments\|requires exactly $n_args arg\|accepts at most\|too many arguments\|accepts $n_args arg(s), received\|accepts between .* and .* arg(s), received \)" \ - "'$usage' indicates a maximum of $n_args args. I invoked it with more, and expected one of these error messages" + local n_args=$(wc -w <<<"$usage") - found[fixed_args]=1 - fi + run_podman '?' "$@" $cmd $(seq --format='x%g' 0 $n_args) + is "$status" 125 \ + "'$usage' indicates a maximum of $n_args args. I invoked it with more, and expected this exit status" + is "$output" "Error:.* \(takes no arguments\|requires exactly $n_args arg\|accepts at most\|too many arguments\|accepts $n_args arg(s), received\|accepts between .* and .* arg(s), received \)" \ + "'$usage' indicates a maximum of $n_args args. I invoked it with more, and expected one of these error messages" + + found[fixed_args]=1 fi count=$(expr $count + 1) diff --git a/test/system/060-mount.bats b/test/system/060-mount.bats index 7addbd88e..2735d2afd 100644 --- a/test/system/060-mount.bats +++ b/test/system/060-mount.bats @@ -50,6 +50,10 @@ load helpers run_podman image mount $IMAGE mount_path="$output" + # Make sure that `mount -a` prints a table + run_podman image mount -a + is "$output" "$IMAGE .*$mount_path" + test -d $mount_path # Image is custom-built and has a file containing the YMD tag. Check it. @@ -62,8 +66,8 @@ load helpers run_podman image mount is "$output" "$IMAGE *$mount_path" "podman image mount with no args" - # Clean up - run_podman image umount $IMAGE + # Clean up: -f since we mounted it twice + run_podman image umount -f $IMAGE is "$output" "$iid" "podman image umount: image ID of what was umounted" run_podman image umount $IMAGE diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats index 4250f2680..404ad67ec 100644 --- a/test/system/200-pod.bats +++ b/test/system/200-pod.bats @@ -335,8 +335,15 @@ EOF is "$output" ".*Invalid kernel namespace to share: bogus. Options are: cgroup, ipc, net, pid, uts or none" \ "pod test for bogus --share option" run_podman pod create --share ipc --name $pod_name + run_podman pod inspect $pod_name --format "{{.SharedNamespaces}}" + is "$output" "[ipc]" run_podman run --rm --pod $pod_name --hostname foobar $IMAGE hostname is "$output" "foobar" "--hostname should work with non share UTS namespace" + run_podman pod create --share +pid --replace --name $pod_name + run_podman pod inspect $pod_name --format "{{.SharedNamespaces}}" + for ns in uts pid ipc net; do + is "$output" ".*$ns" + done } @test "podman pod create --pod new:$POD --hostname" { @@ -387,20 +394,20 @@ EOF is "$output" "false" "Default network sharing should be false" run_podman pod rm test - run_podman pod create --name test --share ipc --network private + run_podman pod create --share ipc --network private test run_podman pod inspect test --format {{.InfraConfig.HostNetwork}} is "$output" "false" "Private network sharing with only ipc should be false" run_podman pod rm test - run_podman pod create --name test --share net --network private - run_podman pod inspect test --format {{.InfraConfig.HostNetwork}} + local name="$(random_string 10 | tr A-Z a-z)" + run_podman pod create --name $name --share net --network private + run_podman pod inspect $name --format {{.InfraConfig.HostNetwork}} is "$output" "false" "Private network sharing with only net should be false" - run_podman pod rm test - run_podman pod create --name test --share net --network host - run_podman pod inspect test --format {{.InfraConfig.HostNetwork}} + run_podman pod create --share net --network host --replace $name + run_podman pod inspect $name --format {{.InfraConfig.HostNetwork}} is "$output" "true" "Host network sharing with only net should be true" - run_podman pod rm test + run_podman pod rm $name run_podman pod create --name test --share ipc --network host run_podman pod inspect test --format {{.InfraConfig.HostNetwork}} diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats index 567fa89c1..110d425d2 100644 --- a/test/system/250-systemd.bats +++ b/test/system/250-systemd.bats @@ -80,12 +80,6 @@ function service_cleanup() { run_podman logs $cname is "$output" ".*WAITING.*" "running is waiting for signal" - # Exercise `podman auto-update`. - # TODO: this will at least run auto-update code but won't perform an update - # since the image didn't change. We need to improve on that and run - # an image from a local registry instead. - run_podman auto-update - # All good. Stop service, clean up. # Also make sure the service is in the `inactive` state (see #11304). service_cleanup inactive diff --git a/test/system/helpers.bash b/test/system/helpers.bash index 6868f2691..fe9e971fb 100644 --- a/test/system/helpers.bash +++ b/test/system/helpers.bash @@ -397,25 +397,25 @@ function _ensure_pod_state() { for i in {0..5}; do run_podman pod inspect $1 --format "{{.State}}" if [[ $output == "$2" ]]; then - break + return fi sleep 0.5 done - is "$output" "$2" "unexpected pod state" + die "Timed out waiting for pod $1 to enter state $2" } # Wait for the container's (1st arg) running state (2nd arg) function _ensure_container_running() { - for i in {0..5}; do + for i in {0..20}; do run_podman container inspect $1 --format "{{.State.Running}}" if [[ $output == "$2" ]]; then - break + return fi sleep 0.5 done - is "$output" "$2" "unexpected pod state" + die "Timed out waiting for container $1 to enter state running=$2" } ########################### diff --git a/utils/testdata/cgroup.empty b/utils/testdata/cgroup.empty new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/utils/testdata/cgroup.empty diff --git a/utils/testdata/cgroup.other b/utils/testdata/cgroup.other new file mode 100644 index 000000000..239a7cded --- /dev/null +++ b/utils/testdata/cgroup.other @@ -0,0 +1 @@ +0::/other diff --git a/utils/testdata/cgroup.root b/utils/testdata/cgroup.root new file mode 100644 index 000000000..1e027b2a3 --- /dev/null +++ b/utils/testdata/cgroup.root @@ -0,0 +1 @@ +0::/ diff --git a/utils/utils_supported.go b/utils/utils_supported.go index 493ea61ce..c2dcc4631 100644 --- a/utils/utils_supported.go +++ b/utils/utils_supported.go @@ -64,7 +64,7 @@ func RunUnderSystemdScope(pid int, slice string, unitName string) error { return nil } -func getCgroupProcess(procFile string) (string, error) { +func getCgroupProcess(procFile string, allowRoot bool) (string, error) { f, err := os.Open(procFile) if err != nil { return "", err @@ -72,7 +72,7 @@ func getCgroupProcess(procFile string) (string, error) { defer f.Close() scanner := bufio.NewScanner(f) - cgroup := "/" + cgroup := "" for scanner.Scan() { line := scanner.Text() parts := strings.SplitN(line, ":", 3) @@ -87,7 +87,7 @@ func getCgroupProcess(procFile string) (string, error) { cgroup = parts[2] } } - if cgroup == "/" { + if len(cgroup) == 0 || (!allowRoot && cgroup == "/") { return "", errors.Errorf("could not find cgroup mount in %q", procFile) } return cgroup, nil @@ -95,12 +95,16 @@ func getCgroupProcess(procFile string) (string, error) { // GetOwnCgroup returns the cgroup for the current process. func GetOwnCgroup() (string, error) { - return getCgroupProcess("/proc/self/cgroup") + return getCgroupProcess("/proc/self/cgroup", true) +} + +func GetOwnCgroupDisallowRoot() (string, error) { + return getCgroupProcess("/proc/self/cgroup", false) } // GetCgroupProcess returns the cgroup for the specified process process. func GetCgroupProcess(pid int) (string, error) { - return getCgroupProcess(fmt.Sprintf("/proc/%d/cgroup", pid)) + return getCgroupProcess(fmt.Sprintf("/proc/%d/cgroup", pid), true) } // MoveUnderCgroupSubtree moves the PID under a cgroup subtree. diff --git a/utils/utils_test.go b/utils/utils_test.go new file mode 100644 index 000000000..f34dbdd7e --- /dev/null +++ b/utils/utils_test.go @@ -0,0 +1,26 @@ +//go:build linux || darwin +// +build linux darwin + +package utils + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCgroupProcess(t *testing.T) { + val, err := getCgroupProcess("testdata/cgroup.root", true) + assert.Nil(t, err) + assert.Equal(t, "/", val) + + _, err = getCgroupProcess("testdata/cgroup.root", false) + assert.NotNil(t, err) + + val, err = getCgroupProcess("testdata/cgroup.other", true) + assert.Nil(t, err) + assert.Equal(t, "/other", val) + + _, err = getCgroupProcess("testdata/cgroup.empty", true) + assert.NotNil(t, err) +} diff --git a/utils/utils_windows.go b/utils/utils_windows.go index 2c159ab06..1d017f5ae 100644 --- a/utils/utils_windows.go +++ b/utils/utils_windows.go @@ -17,6 +17,10 @@ func GetOwnCgroup() (string, error) { return "", errors.New("not implemented for windows") } +func GetOwnCgroupDisallowRoot() (string, error) { + return "", errors.New("not implemented for windows") +} + func GetCgroupProcess(pid int) (string, error) { return "", errors.New("not implemented for windows") } diff --git a/vendor/github.com/containers/common/libimage/define/search.go b/vendor/github.com/containers/common/libimage/define/search.go new file mode 100644 index 000000000..0abd2ca1c --- /dev/null +++ b/vendor/github.com/containers/common/libimage/define/search.go @@ -0,0 +1,13 @@ +package define + +const ( + // SearchFilterAutomated is the key for filtering images by their automated attribute. + SearchFilterAutomated = "is-automated" + // SearchFilterOfficial is the key for filtering images by their official attribute. + SearchFilterOfficial = "is-official" + // SearchFilterStars is the key for filtering images by stars. + SearchFilterStars = "stars" +) + +// SearchFilters includes all supported search filters. +var SearchFilters = []string{SearchFilterAutomated, SearchFilterOfficial, SearchFilterStars} diff --git a/vendor/github.com/containers/common/libimage/load.go b/vendor/github.com/containers/common/libimage/load.go index c2d066645..89faa4635 100644 --- a/vendor/github.com/containers/common/libimage/load.go +++ b/vendor/github.com/containers/common/libimage/load.go @@ -114,6 +114,11 @@ func (r *Runtime) loadMultiImageDockerArchive(ctx context.Context, ref types.Ima if err != nil { return nil, err } + defer func() { + if err := reader.Close(); err != nil { + logrus.Errorf("Closing reader of docker archive: %v", err) + } + }() refLists, err := reader.List() if err != nil { diff --git a/vendor/github.com/containers/common/libimage/pull.go b/vendor/github.com/containers/common/libimage/pull.go index 4ce8add2f..771756160 100644 --- a/vendor/github.com/containers/common/libimage/pull.go +++ b/vendor/github.com/containers/common/libimage/pull.go @@ -315,6 +315,11 @@ func (r *Runtime) copyFromDockerArchive(ctx context.Context, ref types.ImageRefe if err != nil { return nil, err } + defer func() { + if err := reader.Close(); err != nil { + logrus.Errorf("Closing reader of docker archive: %v", err) + } + }() return r.copyFromDockerArchiveReaderReference(ctx, reader, readerRef, options) } diff --git a/vendor/github.com/containers/common/libimage/search.go b/vendor/github.com/containers/common/libimage/search.go index 33a4776ce..204bcc8c7 100644 --- a/vendor/github.com/containers/common/libimage/search.go +++ b/vendor/github.com/containers/common/libimage/search.go @@ -7,6 +7,7 @@ import ( "strings" "sync" + "github.com/containers/common/libimage/define" registryTransport "github.com/containers/image/v5/docker" "github.com/containers/image/v5/pkg/sysregistriesv2" "github.com/containers/image/v5/transports/alltransports" @@ -81,22 +82,22 @@ func ParseSearchFilter(filter []string) (*SearchFilter, error) { for _, f := range filter { arr := strings.SplitN(f, "=", 2) switch arr[0] { - case "stars": + case define.SearchFilterStars: if len(arr) < 2 { - return nil, errors.Errorf("invalid `stars` filter %q, should be stars=<value>", filter) + return nil, errors.Errorf("invalid filter %q, should be stars=<value>", filter) } stars, err := strconv.Atoi(arr[1]) if err != nil { return nil, errors.Wrapf(err, "incorrect value type for stars filter") } sFilter.Stars = stars - case "is-automated": + case define.SearchFilterAutomated: if len(arr) == 2 && arr[1] == "false" { sFilter.IsAutomated = types.OptionalBoolFalse } else { sFilter.IsAutomated = types.OptionalBoolTrue } - case "is-official": + case define.SearchFilterOfficial: if len(arr) == 2 && arr[1] == "false" { sFilter.IsOfficial = types.OptionalBoolFalse } else { diff --git a/vendor/github.com/containers/common/libnetwork/cni/cni_conversion.go b/vendor/github.com/containers/common/libnetwork/cni/cni_conversion.go index bda7ed7d0..96a2a9a4a 100644 --- a/vendor/github.com/containers/common/libnetwork/cni/cni_conversion.go +++ b/vendor/github.com/containers/common/libnetwork/cni/cni_conversion.go @@ -1,5 +1,5 @@ -//go:build linux -// +build linux +//go:build linux || freebsd +// +build linux freebsd package cni diff --git a/vendor/github.com/containers/common/libnetwork/cni/cni_exec.go b/vendor/github.com/containers/common/libnetwork/cni/cni_exec.go index 6bfa8d63b..79d7ef120 100644 --- a/vendor/github.com/containers/common/libnetwork/cni/cni_exec.go +++ b/vendor/github.com/containers/common/libnetwork/cni/cni_exec.go @@ -16,8 +16,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build linux -// +build linux +//go:build linux || freebsd +// +build linux freebsd package cni diff --git a/vendor/github.com/containers/common/libnetwork/cni/cni_types.go b/vendor/github.com/containers/common/libnetwork/cni/cni_types.go index 25cc173a6..a407a8dea 100644 --- a/vendor/github.com/containers/common/libnetwork/cni/cni_types.go +++ b/vendor/github.com/containers/common/libnetwork/cni/cni_types.go @@ -1,5 +1,5 @@ -//go:build linux -// +build linux +//go:build linux || freebsd +// +build linux freebsd package cni diff --git a/vendor/github.com/containers/common/libnetwork/cni/config.go b/vendor/github.com/containers/common/libnetwork/cni/config.go index f6954db05..c86196c17 100644 --- a/vendor/github.com/containers/common/libnetwork/cni/config.go +++ b/vendor/github.com/containers/common/libnetwork/cni/config.go @@ -1,5 +1,5 @@ -//go:build linux -// +build linux +//go:build linux || freebsd +// +build linux freebsd package cni @@ -12,7 +12,6 @@ import ( pkgutil "github.com/containers/common/pkg/util" "github.com/pkg/errors" "github.com/sirupsen/logrus" - "github.com/vishvananda/netlink" ) // NetworkCreate will take a partial filled Network and fill the @@ -133,14 +132,7 @@ func (n *cniNetwork) NetworkRemove(nameOrID string) error { // Remove the bridge network interface on the host. if network.libpodNet.Driver == types.BridgeNetworkDriver { - link, err := netlink.LinkByName(network.libpodNet.NetworkInterface) - if err == nil { - err = netlink.LinkDel(link) - // only log the error, it is not fatal - if err != nil { - logrus.Infof("Failed to remove network interface %s: %v", network.libpodNet.NetworkInterface, err) - } - } + deleteLink(network.libpodNet.NetworkInterface) } file := network.filename diff --git a/vendor/github.com/containers/common/libnetwork/cni/config_freebsd.go b/vendor/github.com/containers/common/libnetwork/cni/config_freebsd.go new file mode 100644 index 000000000..ff95c0e17 --- /dev/null +++ b/vendor/github.com/containers/common/libnetwork/cni/config_freebsd.go @@ -0,0 +1,17 @@ +//go:build freebsd +// +build freebsd + +package cni + +import ( + "os/exec" + + "github.com/sirupsen/logrus" +) + +func deleteLink(name string) { + if output, err := exec.Command("ifconfig", name, "destroy").CombinedOutput(); err != nil { + // only log the error, it is not fatal + logrus.Infof("Failed to remove network interface %s: %v: %s", name, err, output) + } +} diff --git a/vendor/github.com/containers/common/libnetwork/cni/config_linux.go b/vendor/github.com/containers/common/libnetwork/cni/config_linux.go new file mode 100644 index 000000000..836fd73bf --- /dev/null +++ b/vendor/github.com/containers/common/libnetwork/cni/config_linux.go @@ -0,0 +1,20 @@ +//go:build linux +// +build linux + +package cni + +import ( + "github.com/sirupsen/logrus" + "github.com/vishvananda/netlink" +) + +func deleteLink(name string) { + link, err := netlink.LinkByName(name) + if err == nil { + err = netlink.LinkDel(link) + // only log the error, it is not fatal + if err != nil { + logrus.Infof("Failed to remove network interface %s: %v", name, err) + } + } +} diff --git a/vendor/github.com/containers/common/libnetwork/cni/network.go b/vendor/github.com/containers/common/libnetwork/cni/network.go index 82b9cbd2e..561f309d0 100644 --- a/vendor/github.com/containers/common/libnetwork/cni/network.go +++ b/vendor/github.com/containers/common/libnetwork/cni/network.go @@ -1,5 +1,5 @@ -//go:build linux -// +build linux +//go:build linux || freebsd +// +build linux freebsd package cni diff --git a/vendor/github.com/containers/common/libnetwork/cni/run.go b/vendor/github.com/containers/common/libnetwork/cni/run.go index c5461d74c..35236cf25 100644 --- a/vendor/github.com/containers/common/libnetwork/cni/run.go +++ b/vendor/github.com/containers/common/libnetwork/cni/run.go @@ -1,5 +1,5 @@ -//go:build linux -// +build linux +//go:build linux || freebsd +// +build linux freebsd package cni @@ -12,13 +12,11 @@ import ( "github.com/containernetworking/cni/libcni" cnitypes "github.com/containernetworking/cni/pkg/types" types040 "github.com/containernetworking/cni/pkg/types/040" - "github.com/containernetworking/plugins/pkg/ns" "github.com/containers/common/libnetwork/internal/util" "github.com/containers/common/libnetwork/types" "github.com/hashicorp/go-multierror" "github.com/pkg/errors" "github.com/sirupsen/logrus" - "github.com/vishvananda/netlink" ) // Setup will setup the container network namespace. It returns @@ -36,14 +34,7 @@ func (n *cniNetwork) Setup(namespacePath string, options types.SetupOptions) (ma return nil, err } - // set the loopback adapter up in the container netns - err = ns.WithNetNSPath(namespacePath, func(_ ns.NetNS) error { - link, err := netlink.LinkByName("lo") - if err == nil { - err = netlink.LinkSetUp(link) - } - return err - }) + err = setupLoopback(namespacePath) if err != nil { return nil, errors.Wrapf(err, "failed to set the loopback adapter up") } diff --git a/vendor/github.com/containers/common/libnetwork/cni/run_freebsd.go b/vendor/github.com/containers/common/libnetwork/cni/run_freebsd.go new file mode 100644 index 000000000..c356a864a --- /dev/null +++ b/vendor/github.com/containers/common/libnetwork/cni/run_freebsd.go @@ -0,0 +1,13 @@ +package cni + +import ( + "os/exec" +) + +// FreeBSD vnet adds the lo0 interface automatically - we just need to +// add the default address. Note: this will also add ::1 as a side +// effect. +func setupLoopback(namespacePath string) error { + // The jexec wrapper runs the ifconfig command inside the jail. + return exec.Command("jexec", namespacePath, "ifconfig", "lo0", "inet", "127.0.0.1").Run() +} diff --git a/vendor/github.com/containers/common/libnetwork/cni/run_linux.go b/vendor/github.com/containers/common/libnetwork/cni/run_linux.go new file mode 100644 index 000000000..735e4960e --- /dev/null +++ b/vendor/github.com/containers/common/libnetwork/cni/run_linux.go @@ -0,0 +1,17 @@ +package cni + +import ( + "github.com/containernetworking/plugins/pkg/ns" + "github.com/vishvananda/netlink" +) + +func setupLoopback(namespacePath string) error { + // set the loopback adapter up in the container netns + return ns.WithNetNSPath(namespacePath, func(_ ns.NetNS) error { + link, err := netlink.LinkByName("lo") + if err == nil { + err = netlink.LinkSetUp(link) + } + return err + }) +} diff --git a/vendor/github.com/containers/common/libnetwork/netavark/config.go b/vendor/github.com/containers/common/libnetwork/netavark/config.go index f2c72ab9e..d8843eb2c 100644 --- a/vendor/github.com/containers/common/libnetwork/netavark/config.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/config.go @@ -1,5 +1,5 @@ -//go:build linux -// +build linux +//go:build linux || freebsd +// +build linux freebsd package netavark diff --git a/vendor/github.com/containers/common/libnetwork/netavark/const.go b/vendor/github.com/containers/common/libnetwork/netavark/const.go index 29a7b4f2a..b375acd1b 100644 --- a/vendor/github.com/containers/common/libnetwork/netavark/const.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/const.go @@ -1,5 +1,5 @@ -//go:build linux -// +build linux +//go:build linux || freebsd +// +build linux freebsd package netavark diff --git a/vendor/github.com/containers/common/libnetwork/netavark/exec.go b/vendor/github.com/containers/common/libnetwork/netavark/exec.go index ac87c5438..65dcd5497 100644 --- a/vendor/github.com/containers/common/libnetwork/netavark/exec.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/exec.go @@ -1,5 +1,5 @@ -//go:build linux -// +build linux +//go:build linux || freebsd +// +build linux freebsd package netavark diff --git a/vendor/github.com/containers/common/libnetwork/netavark/ipam.go b/vendor/github.com/containers/common/libnetwork/netavark/ipam.go index 861854351..89820f1d6 100644 --- a/vendor/github.com/containers/common/libnetwork/netavark/ipam.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/ipam.go @@ -1,5 +1,5 @@ -//go:build linux -// +build linux +//go:build linux || freebsd +// +build linux freebsd package netavark diff --git a/vendor/github.com/containers/common/libnetwork/netavark/network.go b/vendor/github.com/containers/common/libnetwork/netavark/network.go index 8e7576a56..0d03cd5e6 100644 --- a/vendor/github.com/containers/common/libnetwork/netavark/network.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/network.go @@ -1,5 +1,5 @@ -//go:build linux -// +build linux +//go:build linux || freebsd +// +build linux freebsd package netavark diff --git a/vendor/github.com/containers/common/libnetwork/netavark/run.go b/vendor/github.com/containers/common/libnetwork/netavark/run.go index c5aa181fd..7f0a84140 100644 --- a/vendor/github.com/containers/common/libnetwork/netavark/run.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/run.go @@ -1,5 +1,5 @@ -//go:build linux -// +build linux +//go:build linux || freebsd +// +build linux freebsd package netavark diff --git a/vendor/github.com/containers/common/libnetwork/network/interface.go b/vendor/github.com/containers/common/libnetwork/network/interface.go index e70f096a4..f41598f77 100644 --- a/vendor/github.com/containers/common/libnetwork/network/interface.go +++ b/vendor/github.com/containers/common/libnetwork/network/interface.go @@ -1,5 +1,5 @@ -//go:build linux -// +build linux +//go:build linux || freebsd +// +build linux freebsd package network @@ -25,14 +25,8 @@ import ( const ( // defaultNetworkBackendFileName is the file name for sentinel file to store the backend defaultNetworkBackendFileName = "defaultNetworkBackend" - // cniConfigDir is the directory where cni configuration is found - cniConfigDir = "/etc/cni/net.d/" // cniConfigDirRootless is the directory in XDG_CONFIG_HOME for cni plugins cniConfigDirRootless = "cni/net.d/" - // netavarkConfigDir is the config directory for the rootful network files - netavarkConfigDir = "/etc/containers/networks" - // netavarkRunDir is the run directory for the rootful temporary network files such as the ipam db - netavarkRunDir = "/run/containers/networks" // netavarkBinary is the name of the netavark binary netavarkBinary = "netavark" diff --git a/vendor/github.com/containers/common/libnetwork/network/interface_freebsd.go b/vendor/github.com/containers/common/libnetwork/network/interface_freebsd.go new file mode 100644 index 000000000..4d60b25c7 --- /dev/null +++ b/vendor/github.com/containers/common/libnetwork/network/interface_freebsd.go @@ -0,0 +1,10 @@ +package network + +const ( + // cniConfigDir is the directory where cni configuration is found + cniConfigDir = "/usr/local/etc/cni/net.d/" + // netavarkConfigDir is the config directory for the rootful network files + netavarkConfigDir = "/usr/local/etc/containers/networks" + // netavarkRunDir is the run directory for the rootful temporary network files such as the ipam db + netavarkRunDir = "/var/run/containers/networks" +) diff --git a/vendor/github.com/containers/common/libnetwork/network/interface_linux.go b/vendor/github.com/containers/common/libnetwork/network/interface_linux.go new file mode 100644 index 000000000..a16194400 --- /dev/null +++ b/vendor/github.com/containers/common/libnetwork/network/interface_linux.go @@ -0,0 +1,10 @@ +package network + +const ( + // cniConfigDir is the directory where cni configuration is found + cniConfigDir = "/etc/cni/net.d/" + // netavarkConfigDir is the config directory for the rootful network files + netavarkConfigDir = "/etc/containers/networks" + // netavarkRunDir is the run directory for the rootful temporary network files such as the ipam db + netavarkRunDir = "/run/containers/networks" +) diff --git a/vendor/github.com/containers/common/pkg/cgroups/cgroups_supported.go b/vendor/github.com/containers/common/pkg/cgroups/cgroups_supported.go index 5c6c199e0..3e7653672 100644 --- a/vendor/github.com/containers/common/pkg/cgroups/cgroups_supported.go +++ b/vendor/github.com/containers/common/pkg/cgroups/cgroups_supported.go @@ -99,7 +99,7 @@ func UserOwnsCurrentSystemdCgroup() (bool, error) { func rmDirRecursively(path string) error { killProcesses := func(signal syscall.Signal) { if signal == unix.SIGKILL { - if err := ioutil.WriteFile(filepath.Join(path, "cgroup.kill"), []byte("1"), 0600); err == nil { + if err := ioutil.WriteFile(filepath.Join(path, "cgroup.kill"), []byte("1"), 0o600); err == nil { return } } diff --git a/vendor/github.com/containers/common/pkg/completion/command.go b/vendor/github.com/containers/common/pkg/completion/command.go new file mode 100644 index 000000000..2deb58757 --- /dev/null +++ b/vendor/github.com/containers/common/pkg/completion/command.go @@ -0,0 +1,96 @@ +package completion + +import ( + "fmt" + "io" + "os" + "strings" + + "github.com/spf13/cobra" +) + +const ( + completionDescription = `Generate shell autocompletions. +Valid arguments are bash, zsh, fish and powershell.` + + bash = "bash" + zsh = "zsh" + fish = "fish" + powershell = "powershell" +) + +var ( + file string + noDesc bool + shells = []string{bash, zsh, fish, powershell} +) + +// AddCompletionCommand adds the completion command to the given command which should be the root command. +// This command can be used the generate the cobra shell completion scripts for bash, zsh, fish and powershell. +func AddCompletionCommand(rootCmd *cobra.Command) { + completionCmd := &cobra.Command{ + Use: fmt.Sprintf("completion [options] {%s}", strings.Join(shells, "|")), + Short: "Generate shell autocompletions", + Long: completionDescription, + ValidArgs: shells, + Args: cobra.ExactValidArgs(1), + RunE: completion, + Example: fmt.Sprintf(`%[1]s completion bash + %[1]s completion zsh -f _%[1]s + %[1]s completion fish --no-desc`, rootCmd.Name()), + // don't show this command to users + Hidden: true, + } + + flags := completionCmd.Flags() + fileFlagName := "file" + flags.StringVarP(&file, fileFlagName, "f", "", "Output the completion to file rather than stdout.") + _ = completionCmd.RegisterFlagCompletionFunc(fileFlagName, AutocompleteDefault) + + flags.BoolVar(&noDesc, "no-desc", false, "Don't include descriptions in the completion output.") + + rootCmd.AddCommand(completionCmd) +} + +func completion(cmd *cobra.Command, args []string) error { + var w io.Writer + + if file != "" { + file, err := os.Create(file) + if err != nil { + return err + } + defer file.Close() + w = file + } else { + w = os.Stdout + } + + var err error + switch args[0] { + case bash: + err = cmd.Root().GenBashCompletionV2(w, !noDesc) + case zsh: + if noDesc { + err = cmd.Root().GenZshCompletionNoDesc(w) + } else { + err = cmd.Root().GenZshCompletion(w) + } + case fish: + err = cmd.Root().GenFishCompletion(w, !noDesc) + case powershell: + if noDesc { + err = cmd.Root().GenPowerShellCompletion(w) + } else { + err = cmd.Root().GenPowerShellCompletionWithDesc(w) + } + } + if err != nil { + return err + } + + _, err = io.WriteString(w, fmt.Sprintf( + "# This file is generated with %q; DO NOT EDIT!\n", cmd.CommandPath(), + )) + return err +} diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go index 25572968f..e3d19ee88 100644 --- a/vendor/github.com/containers/common/pkg/config/config.go +++ b/vendor/github.com/containers/common/pkg/config/config.go @@ -1,6 +1,7 @@ package config import ( + "errors" "fmt" "io/fs" "os" @@ -13,10 +14,10 @@ import ( "github.com/BurntSushi/toml" "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/capabilities" + "github.com/containers/common/pkg/util" "github.com/containers/storage/pkg/unshare" units "github.com/docker/go-units" selinux "github.com/opencontainers/selinux/go-selinux" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -46,6 +47,8 @@ const ( BoltDBStateStore RuntimeStateStore = iota ) +var validImageVolumeModes = []string{"bind", "tmpfs", "ignore"} + // ProxyEnv is a list of Proxy Environment variables var ProxyEnv = []string{ "http_proxy", @@ -77,7 +80,6 @@ type Config struct { // ContainersConfig represents the "containers" TOML config table // containers global options for containers tools type ContainersConfig struct { - // Devices to add to all containers Devices []string `toml:"devices,omitempty"` @@ -294,6 +296,10 @@ type EngineConfig struct { // Building/committing defaults to OCI. ImageDefaultFormat string `toml:"image_default_format,omitempty"` + // ImageVolumeMode Tells container engines how to handle the builtin + // image volumes. Acceptable values are "bind", "tmpfs", and "ignore". + ImageVolumeMode string `toml:"image_volume_mode,omitempty"` + // InfraCommand is the command run to start up a pod infra container. InfraCommand string `toml:"infra_command,omitempty"` @@ -604,14 +610,14 @@ func NewConfig(userConfigPath string) (*Config, error) { // Now, gather the system configs and merge them as needed. configs, err := systemConfigs() if err != nil { - return nil, errors.Wrap(err, "finding config on system") + return nil, fmt.Errorf("finding config on system: %w", err) } for _, path := range configs { // Merge changes in later configs with the previous configs. // Each config file that specified fields, will override the // previous fields. if err = readConfigFromFile(path, config); err != nil { - return nil, errors.Wrapf(err, "reading system config %q", path) + return nil, fmt.Errorf("reading system config %q: %w", path, err) } logrus.Debugf("Merged system config %q", path) logrus.Tracef("%+v", config) @@ -624,7 +630,7 @@ func NewConfig(userConfigPath string) (*Config, error) { // readConfigFromFile reads in container config in the specified // file and then merge changes with the current default. if err = readConfigFromFile(userConfigPath, config); err != nil { - return nil, errors.Wrapf(err, "reading user config %q", userConfigPath) + return nil, fmt.Errorf("reading user config %q: %w", userConfigPath, err) } logrus.Debugf("Merged user config %q", userConfigPath) logrus.Tracef("%+v", config) @@ -650,7 +656,7 @@ func readConfigFromFile(path string, config *Config) error { logrus.Tracef("Reading configuration file %q", path) meta, err := toml.DecodeFile(path, config) if err != nil { - return errors.Wrapf(err, "decode configuration %v", path) + return fmt.Errorf("decode configuration %v: %w", path, err) } keys := meta.Undecoded() if len(keys) > 0 { @@ -704,7 +710,7 @@ func systemConfigs() ([]string, error) { path := os.Getenv("CONTAINERS_CONF") if path != "" { if _, err := os.Stat(path); err != nil { - return nil, errors.Wrap(err, "CONTAINERS_CONF file") + return nil, fmt.Errorf("CONTAINERS_CONF file: %w", err) } return append(configs, path), nil } @@ -779,7 +785,7 @@ func (c *Config) addCAPPrefix() { // Validate is the main entry point for library configuration validation. func (c *Config) Validate() error { if err := c.Containers.Validate(); err != nil { - return errors.Wrap(err, "validating containers config") + return fmt.Errorf("validating containers config: %w", err) } if !c.Containers.EnableLabeling { @@ -787,11 +793,11 @@ func (c *Config) Validate() error { } if err := c.Engine.Validate(); err != nil { - return errors.Wrap(err, "validating engine configs") + return fmt.Errorf("validating engine configs: %w", err) } if err := c.Network.Validate(); err != nil { - return errors.Wrap(err, "validating network configs") + return fmt.Errorf("validating network configs %w", err) } return nil @@ -821,11 +827,14 @@ func (c *EngineConfig) Validate() error { return err } + if err := ValidateImageVolumeMode(c.ImageVolumeMode); err != nil { + return err + } // Check if the pullPolicy from containers.conf is valid // if it is invalid returns the error pullPolicy := strings.ToLower(c.PullPolicy) if _, err := ValidatePullPolicy(pullPolicy); err != nil { - return errors.Wrapf(err, "invalid pull type from containers.conf %q", c.PullPolicy) + return fmt.Errorf("invalid pull type from containers.conf %q: %w", c.PullPolicy, err) } return nil } @@ -851,11 +860,11 @@ func (c *ContainersConfig) Validate() error { } if c.LogSizeMax >= 0 && c.LogSizeMax < OCIBufSize { - return errors.Errorf("log size max should be negative or >= %d", OCIBufSize) + return fmt.Errorf("log size max should be negative or >= %d", OCIBufSize) } if _, err := units.FromHumanSize(c.ShmSize); err != nil { - return errors.Errorf("invalid --shm-size %s, %q", c.ShmSize, err) + return fmt.Errorf("invalid --shm-size %s, %q", c.ShmSize, err) } return nil @@ -869,11 +878,11 @@ func (c *NetworkConfig) Validate() error { if &c.DefaultSubnetPools != &DefaultSubnetPools { for _, pool := range c.DefaultSubnetPools { if pool.Base.IP.To4() == nil { - return errors.Errorf("invalid subnet pool ip %q", pool.Base.IP) + return fmt.Errorf("invalid subnet pool ip %q", pool.Base.IP) } ones, _ := pool.Base.IPNet.Mask.Size() if ones > pool.Size { - return errors.Errorf("invalid subnet pool, size is bigger than subnet %q", &pool.Base.IPNet) + return fmt.Errorf("invalid subnet pool, size is bigger than subnet %q", &pool.Base.IPNet) } if pool.Size > 32 { return errors.New("invalid subnet pool size, must be between 0-32") @@ -891,7 +900,7 @@ func (c *NetworkConfig) Validate() error { } } - return errors.Errorf("invalid cni_plugin_dirs: %s", strings.Join(c.CNIPluginDirs, ",")) + return fmt.Errorf("invalid cni_plugin_dirs: %s", strings.Join(c.CNIPluginDirs, ",")) } // FindConmon iterates over (*Config).ConmonPath and returns the path @@ -928,14 +937,12 @@ func (c *Config) FindConmon() (string, error) { } if foundOutdatedConmon { - return "", errors.Wrapf(ErrConmonOutdated, - "please update to v%d.%d.%d or later", - _conmonMinMajorVersion, _conmonMinMinorVersion, _conmonMinPatchVersion) + return "", fmt.Errorf("please update to v%d.%d.%d or later: %w", + _conmonMinMajorVersion, _conmonMinMinorVersion, _conmonMinPatchVersion, ErrConmonOutdated) } - return "", errors.Wrapf(ErrInvalidArg, - "could not find a working conmon binary (configured options: %v)", - c.Engine.ConmonPath) + return "", fmt.Errorf("could not find a working conmon binary (configured options: %v: %w)", + c.Engine.ConmonPath, ErrInvalidArg) } // GetDefaultEnv returns the environment variables for the container. @@ -992,7 +999,7 @@ func Device(device string) (src, dst, permissions string, err error) { switch len(split) { case 3: if !IsValidDeviceMode(split[2]) { - return "", "", "", errors.Errorf("invalid device mode: %s", split[2]) + return "", "", "", fmt.Errorf("invalid device mode: %s", split[2]) } permissions = split[2] fallthrough @@ -1001,18 +1008,18 @@ func Device(device string) (src, dst, permissions string, err error) { permissions = split[1] } else { if split[1] == "" || split[1][0] != '/' { - return "", "", "", errors.Errorf("invalid device mode: %s", split[1]) + return "", "", "", fmt.Errorf("invalid device mode: %s", split[1]) } dst = split[1] } fallthrough case 1: if !strings.HasPrefix(split[0], "/dev/") { - return "", "", "", errors.Errorf("invalid device mode: %s", split[0]) + return "", "", "", fmt.Errorf("invalid device mode: %s", split[0]) } src = split[0] default: - return "", "", "", errors.Errorf("invalid device specification: %s", device) + return "", "", "", fmt.Errorf("invalid device specification: %s", device) } if dst == "" { @@ -1195,14 +1202,14 @@ func (c *Config) ActiveDestination() (uri, identity string, err error) { case connEnv != "": d, found := c.Engine.ServiceDestinations[connEnv] if !found { - return "", "", errors.Errorf("environment variable CONTAINER_CONNECTION=%q service destination not found", connEnv) + return "", "", fmt.Errorf("environment variable CONTAINER_CONNECTION=%q service destination not found", connEnv) } return d.URI, d.Identity, nil case c.Engine.ActiveService != "": d, found := c.Engine.ServiceDestinations[c.Engine.ActiveService] if !found { - return "", "", errors.Errorf("%q service destination not found", c.Engine.ActiveService) + return "", "", fmt.Errorf("%q service destination not found", c.Engine.ActiveService) } return d.URI, d.Identity, nil case c.Engine.RemoteURI != "": @@ -1232,9 +1239,9 @@ func (c *Config) FindHelperBinary(name string, searchPATH bool) (string, error) } configHint := "To resolve this error, set the helper_binaries_dir key in the `[engine]` section of containers.conf to the directory containing your helper binaries." if len(c.Engine.HelperBinariesDir) == 0 { - return "", errors.Errorf("could not find %q because there are no helper binary directories configured. %s", name, configHint) + return "", fmt.Errorf("could not find %q because there are no helper binary directories configured. %s", name, configHint) } - return "", errors.Errorf("could not find %q in one of %v. %s", name, c.Engine.HelperBinariesDir, configHint) + return "", fmt.Errorf("could not find %q in one of %v. %s", name, c.Engine.HelperBinariesDir, configHint) } // ImageCopyTmpDir default directory to store temporary image files during copy @@ -1253,7 +1260,7 @@ func (c *Config) ImageCopyTmpDir() (string, error) { } } - return "", errors.Errorf("invalid image_copy_tmp_dir value %q (relative paths are not accepted)", c.Engine.ImageCopyTmpDir) + return "", fmt.Errorf("invalid image_copy_tmp_dir value %q (relative paths are not accepted)", c.Engine.ImageCopyTmpDir) } // setupEnv sets the environment variables for the engine @@ -1305,3 +1312,14 @@ func (e eventsLogMaxSize) MarshalText() ([]byte, error) { } return []byte(fmt.Sprintf("%d", e)), nil } + +func ValidateImageVolumeMode(mode string) error { + if mode == "" { + return nil + } + if util.StringInSlice(mode, validImageVolumeModes) { + return nil + } + + return fmt.Errorf("invalid image volume mode %q required value: %s", mode, strings.Join(validImageVolumeModes, ", ")) +} diff --git a/vendor/github.com/containers/common/pkg/config/config_local.go b/vendor/github.com/containers/common/pkg/config/config_local.go index bfb967582..bc8ddc655 100644 --- a/vendor/github.com/containers/common/pkg/config/config_local.go +++ b/vendor/github.com/containers/common/pkg/config/config_local.go @@ -4,6 +4,7 @@ package config import ( + "fmt" "os" "path/filepath" "regexp" @@ -11,7 +12,6 @@ import ( "syscall" units "github.com/docker/go-units" - "github.com/pkg/errors" ) // isDirectory tests whether the given path exists and is a directory. It @@ -44,13 +44,13 @@ func (c *EngineConfig) validatePaths() error { // shift between runs or even parts of the program. - The OCI runtime // uses a different working directory than we do, for example. if c.StaticDir != "" && !filepath.IsAbs(c.StaticDir) { - return errors.Errorf("static directory must be an absolute path - instead got %q", c.StaticDir) + return fmt.Errorf("static directory must be an absolute path - instead got %q", c.StaticDir) } if c.TmpDir != "" && !filepath.IsAbs(c.TmpDir) { - return errors.Errorf("temporary directory must be an absolute path - instead got %q", c.TmpDir) + return fmt.Errorf("temporary directory must be an absolute path - instead got %q", c.TmpDir) } if c.VolumePath != "" && !filepath.IsAbs(c.VolumePath) { - return errors.Errorf("volume path must be an absolute path - instead got %q", c.VolumePath) + return fmt.Errorf("volume path must be an absolute path - instead got %q", c.VolumePath) } return nil } @@ -69,7 +69,7 @@ func (c *ContainersConfig) validateUlimits() error { for _, u := range c.DefaultUlimits { ul, err := units.ParseUlimit(u) if err != nil { - return errors.Wrapf(err, "unrecognized ulimit %s", u) + return fmt.Errorf("unrecognized ulimit %s: %w", u, err) } _, err = ul.GetRlimit() if err != nil { @@ -97,7 +97,7 @@ func (c *ContainersConfig) validateTZ() error { } } - return errors.Errorf( + return fmt.Errorf( "find timezone %s in paths: %s", c.TZ, strings.Join(lookupPaths, ", "), ) @@ -106,7 +106,7 @@ func (c *ContainersConfig) validateTZ() error { func (c *ContainersConfig) validateUmask() error { validUmask := regexp.MustCompile(`^[0-7]{1,4}$`) if !validUmask.MatchString(c.Umask) { - return errors.Errorf("not a valid umask %s", c.Umask) + return fmt.Errorf("not a valid umask %s", c.Umask) } return nil } diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf index a4e755a66..8fd951c4a 100644 --- a/vendor/github.com/containers/common/pkg/config/containers.conf +++ b/vendor/github.com/containers/common/pkg/config/containers.conf @@ -434,6 +434,16 @@ default_sysctls = [ # #image_parallel_copies = 0 +# Tells container engines how to handle the builtin image volumes. +# * bind: An anonymous named volume will be created and mounted +# into the container. +# * tmpfs: The volume is mounted onto the container as a tmpfs, +# which allows users to create content that disappears when +# the container is stopped. +# * ignore: All volumes are just ignored and no action is taken. +# +#image_volume_mode = "" + # Default command to run the infra container # #infra_command = "/pause" diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go index d988d3b1c..f381818f1 100644 --- a/vendor/github.com/containers/common/pkg/config/default.go +++ b/vendor/github.com/containers/common/pkg/config/default.go @@ -2,6 +2,7 @@ package config import ( "bytes" + "errors" "fmt" "net" "os" @@ -19,7 +20,6 @@ import ( "github.com/containers/storage/pkg/unshare" "github.com/containers/storage/types" "github.com/opencontainers/selinux/go-selinux" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -35,7 +35,7 @@ const ( // _conmonVersionFormatErr is used when the expected versio-format of conmon // has changed. - _conmonVersionFormatErr = "conmon version changed format" + _conmonVersionFormatErr = "conmon version changed format: %w" // _defaultGraphRoot points to the default path of the graph root. _defaultGraphRoot = "/var/lib/containers/storage" @@ -43,26 +43,29 @@ const ( // _defaultTransport is a prefix that we apply to an image name to check // docker hub first for the image. _defaultTransport = "docker://" + + // _defaultImageVolumeMode is a mode to handle built-in image volumes. + _defaultImageVolumeMode = "bind" ) var ( - // DefaultInitPath is the default path to the container-init binary + // DefaultInitPath is the default path to the container-init binary. DefaultInitPath = "/usr/libexec/podman/catatonit" - // DefaultInfraImage to use for infra container + // DefaultInfraImage is the default image to run as infrastructure containers in pods. DefaultInfraImage = "" - // DefaultRootlessSHMLockPath is the default path for rootless SHM locks + // DefaultRootlessSHMLockPath is the default path for rootless SHM locks. DefaultRootlessSHMLockPath = "/libpod_rootless_lock" // DefaultDetachKeys is the default keys sequence for detaching a - // container + // container. DefaultDetachKeys = "ctrl-p,ctrl-q" // ErrConmonOutdated indicates the version of conmon found (whether via the configuration or $PATH) - // is out of date for the current podman version + // is out of date for the current podman version. ErrConmonOutdated = errors.New("outdated conmon version") - // ErrInvalidArg indicates that an invalid argument was passed + // ErrInvalidArg indicates that an invalid argument was passed. ErrInvalidArg = errors.New("invalid argument") - // DefaultHooksDirs defines the default hooks directory + // DefaultHooksDirs defines the default hooks directory. DefaultHooksDirs = []string{"/usr/share/containers/oci/hooks.d"} - // DefaultCapabilities for the default_capabilities option in the containers.conf file + // DefaultCapabilities is the default for the default_capabilities option in the containers.conf file. DefaultCapabilities = []string{ "CAP_AUDIT_WRITE", "CAP_CHOWN", @@ -80,7 +83,7 @@ var ( "CAP_SYS_CHROOT", } - // It may seem a bit unconventional, but it is necessary to do so + // Search these locations in which CNIPlugins can be installed. DefaultCNIPluginDirs = []string{ "/usr/local/libexec/cni", "/usr/libexec/cni", @@ -98,7 +101,7 @@ var ( } // additionalHelperBinariesDir is an extra helper binaries directory that // should be set during link-time, if different packagers put their - // helper binary in a different location + // helper binary in a different location. additionalHelperBinariesDir string ) @@ -118,13 +121,13 @@ const ( // InstallPrefix is the prefix where podman will be installed. // It can be overridden at build time. _installPrefix = "/usr" - // CgroupfsCgroupsManager represents cgroupfs native cgroup manager + // CgroupfsCgroupsManager represents cgroupfs native cgroup manager. CgroupfsCgroupsManager = "cgroupfs" // DefaultApparmorProfile specifies the default apparmor profile for the container. DefaultApparmorProfile = apparmor.Profile - // DefaultHostsFile is the default path to the hosts file + // DefaultHostsFile is the default path to the hosts file. DefaultHostsFile = "/etc/hosts" - // SystemdCgroupsManager represents systemd native cgroup manager + // SystemdCgroupsManager represents systemd native cgroup manager. SystemdCgroupsManager = "systemd" // DefaultLogSizeMax is the default value for the maximum log size // allowed for a container. Negative values mean that no limit is imposed. @@ -133,9 +136,9 @@ const ( // before rotation. DefaultEventsLogSizeMax = uint64(1000000) // DefaultPidsLimit is the default value for maximum number of processes - // allowed inside a container + // allowed inside a container. DefaultPidsLimit = 2048 - // DefaultPullPolicy pulls the image if it does not exist locally + // DefaultPullPolicy pulls the image if it does not exist locally. DefaultPullPolicy = "missing" // DefaultSignaturePolicyPath is the default value for the // policy.json file. @@ -146,11 +149,11 @@ const ( // DefaultRootlessSignaturePolicyPath is the location within // XDG_CONFIG_HOME of the rootless policy.json file. DefaultRootlessSignaturePolicyPath = "containers/policy.json" - // DefaultShmSize default value + // DefaultShmSize is the default upper limit on the size of tmpfs mounts. DefaultShmSize = "65536k" - // DefaultUserNSSize default value + // DefaultUserNSSize indicates the default number of UIDs allocated for user namespace within a container. DefaultUserNSSize = 65536 - // OCIBufSize limits maximum LogSizeMax + // OCIBufSize limits maximum LogSizeMax. OCIBufSize = 8192 // SeccompOverridePath if this exists it overrides the default seccomp path. SeccompOverridePath = _etcDir + "/containers/seccomp.json" @@ -158,7 +161,7 @@ const ( SeccompDefaultPath = _installPrefix + "/share/containers/seccomp.json" ) -// DefaultConfig defines the default values from containers.conf +// DefaultConfig defines the default values from containers.conf. func DefaultConfig() (*Config, error) { defaultEngineConfig, err := defaultConfigFromMemory() if err != nil { @@ -294,6 +297,7 @@ func defaultConfigFromMemory() (*EngineConfig, error) { } c.HooksDir = DefaultHooksDirs c.ImageDefaultTransport = _defaultTransport + c.ImageVolumeMode = _defaultImageVolumeMode c.StateType = BoltDBStateStore c.ImageBuildFormat = "oci" @@ -350,7 +354,7 @@ func defaultConfigFromMemory() (*EngineConfig, error) { "/usr/local/bin/krun", }, } - // Needs to be called after populating c.OCIRuntimes + // Needs to be called after populating c.OCIRuntimes. c.OCIRuntime = c.findRuntime() c.ConmonEnvVars = []string{ @@ -411,8 +415,8 @@ func defaultTmpDir() (string, error) { if !os.IsExist(err) { return "", err } else if err := os.Chmod(libpodRuntimeDir, 0o700|os.ModeSticky); err != nil { - // The directory already exist, just set the sticky bit - return "", errors.Wrap(err, "set sticky bit on") + // The directory already exists, so we try to make sure it's private and has the sticky bit set on it. + return "", fmt.Errorf("set sticky bit on: %w", err) } } return filepath.Join(libpodRuntimeDir, "tmp"), nil @@ -435,7 +439,7 @@ func probeConmon(conmonBinary string) error { } major, err := strconv.Atoi(matches[1]) if err != nil { - return errors.Wrap(err, _conmonVersionFormatErr) + return fmt.Errorf(_conmonVersionFormatErr, err) } if major < _conmonMinMajorVersion { return ErrConmonOutdated @@ -446,7 +450,7 @@ func probeConmon(conmonBinary string) error { minor, err := strconv.Atoi(matches[2]) if err != nil { - return errors.Wrap(err, _conmonVersionFormatErr) + return fmt.Errorf(_conmonVersionFormatErr, err) } if minor < _conmonMinMinorVersion { return ErrConmonOutdated @@ -457,7 +461,7 @@ func probeConmon(conmonBinary string) error { patch, err := strconv.Atoi(matches[3]) if err != nil { - return errors.Wrap(err, _conmonVersionFormatErr) + return fmt.Errorf(_conmonVersionFormatErr, err) } if patch < _conmonMinPatchVersion { return ErrConmonOutdated @@ -469,7 +473,7 @@ func probeConmon(conmonBinary string) error { return nil } -// NetNS returns the default network namespace +// NetNS returns the default network namespace. func (c *Config) NetNS() string { return c.Containers.NetNS } @@ -478,7 +482,7 @@ func (c EngineConfig) EventsLogMaxSize() uint64 { return uint64(c.EventsLogFileMaxSize) } -// SecurityOptions returns the default security options +// SecurityOptions returns the default security options. func (c *Config) SecurityOptions() []string { securityOpts := []string{} if c.Containers.SeccompProfile != "" && c.Containers.SeccompProfile != SeccompDefaultPath { @@ -493,82 +497,82 @@ func (c *Config) SecurityOptions() []string { return securityOpts } -// Sysctls returns the default sysctls +// Sysctls returns the default sysctls to set in containers. func (c *Config) Sysctls() []string { return c.Containers.DefaultSysctls } -// Volumes returns the default additional volumes for containersvolumes +// Volumes returns the default set of volumes that should be mounted in containers. func (c *Config) Volumes() []string { return c.Containers.Volumes } -// Devices returns the default additional devices for containers +// Devices returns the default additional devices for containers. func (c *Config) Devices() []string { return c.Containers.Devices } -// DNSServers returns the default DNS servers to add to resolv.conf in containers +// DNSServers returns the default DNS servers to add to resolv.conf in containers. func (c *Config) DNSServers() []string { return c.Containers.DNSServers } -// DNSSerches returns the default DNS searches to add to resolv.conf in containers +// DNSSerches returns the default DNS searches to add to resolv.conf in containers. func (c *Config) DNSSearches() []string { return c.Containers.DNSSearches } -// DNSOptions returns the default DNS options to add to resolv.conf in containers +// DNSOptions returns the default DNS options to add to resolv.conf in containers. func (c *Config) DNSOptions() []string { return c.Containers.DNSOptions } -// Env returns the default additional environment variables to add to containers +// Env returns the default additional environment variables to add to containers. func (c *Config) Env() []string { return c.Containers.Env } -// InitPath returns the default init path to add to containers +// InitPath returns location where init program added to containers when users specify the --init flag. func (c *Config) InitPath() string { return c.Containers.InitPath } -// IPCNS returns the default IPC Namespace configuration to run containers with +// IPCNS returns the default IPC Namespace configuration to run containers with. func (c *Config) IPCNS() string { return c.Containers.IPCNS } -// PIDNS returns the default PID Namespace configuration to run containers with +// PIDNS returns the default PID Namespace configuration to run containers with. func (c *Config) PidNS() string { return c.Containers.PidNS } -// CgroupNS returns the default Cgroup Namespace configuration to run containers with +// CgroupNS returns the default Cgroup Namespace configuration to run containers with. func (c *Config) CgroupNS() string { return c.Containers.CgroupNS } -// Cgroups returns whether to containers with cgroup confinement +// Cgroups returns whether to run containers in their own control groups, as configured by the "cgroups" setting in containers.conf. func (c *Config) Cgroups() string { return c.Containers.Cgroups } -// UTSNS returns the default UTS Namespace configuration to run containers with +// UTSNS returns the default UTS Namespace configuration to run containers with. func (c *Config) UTSNS() string { return c.Containers.UTSNS } -// ShmSize returns the default size for temporary file systems to use in containers +// ShmSize returns the default size for temporary file systems to use in containers. func (c *Config) ShmSize() string { return c.Containers.ShmSize } -// Ulimits returns the default ulimits to use in containers +// Ulimits returns the default ulimits to use in containers. func (c *Config) Ulimits() []string { return c.Containers.DefaultUlimits } -// PidsLimit returns the default maximum number of pids to use in containers +// PidsLimit returns the default maximum number of pids to use in containers. func (c *Config) PidsLimit() int64 { if unshare.IsRootless() { if c.Engine.CgroupManager != SystemdCgroupsManager { @@ -583,12 +587,12 @@ func (c *Config) PidsLimit() int64 { return c.Containers.PidsLimit } -// DetachKeys returns the default detach keys to detach from a container +// DetachKeys returns the default detach keys to detach from a container. func (c *Config) DetachKeys() string { return c.Engine.DetachKeys } -// Tz returns the timezone in the container +// TZ returns the timezone to set in containers. func (c *Config) TZ() string { return c.Containers.TZ } @@ -598,17 +602,17 @@ func (c *Config) Umask() string { } // LogDriver returns the logging driver to be used -// currently k8s-file or journald +// currently k8s-file or journald. func (c *Config) LogDriver() string { return c.Containers.LogDriver } -// MachineEnabled returns if podman is running inside a VM or not +// MachineEnabled returns if podman is running inside a VM or not. func (c *Config) MachineEnabled() bool { return c.Engine.MachineEnabled } -// MachineVolumes returns volumes to mount into the VM +// MachineVolumes returns volumes to mount into the VM. func (c *Config) MachineVolumes() ([]string, error) { return machineVolumes(c.Machine.Volumes) } @@ -619,10 +623,10 @@ func machineVolumes(volumes []string) ([]string, error) { vol := os.ExpandEnv(v) split := strings.Split(vol, ":") if len(split) < 2 || len(split) > 3 { - return nil, errors.Errorf("invalid machine volume %s, 2 or 3 fields required", v) + return nil, fmt.Errorf("invalid machine volume %s, 2 or 3 fields required", v) } if split[0] == "" || split[1] == "" { - return nil, errors.Errorf("invalid machine volume %s, fields must container data", v) + return nil, fmt.Errorf("invalid machine volume %s, fields must container data", v) } translatedVolumes = append(translatedVolumes, vol) } diff --git a/vendor/github.com/containers/common/pkg/config/pull_policy.go b/vendor/github.com/containers/common/pkg/config/pull_policy.go index 8c1f0ec29..c85227fe4 100644 --- a/vendor/github.com/containers/common/pkg/config/pull_policy.go +++ b/vendor/github.com/containers/common/pkg/config/pull_policy.go @@ -2,8 +2,6 @@ package config import ( "fmt" - - "github.com/pkg/errors" ) // PullPolicy determines how and which images are being pulled from a container @@ -63,7 +61,7 @@ func (p PullPolicy) Validate() error { case PullPolicyAlways, PullPolicyMissing, PullPolicyNewer, PullPolicyNever: return nil default: - return errors.Errorf("unsupported pull policy %d", p) + return fmt.Errorf("unsupported pull policy %d", p) } } @@ -85,7 +83,7 @@ func ParsePullPolicy(s string) (PullPolicy, error) { case "never", "Never": return PullPolicyNever, nil default: - return PullPolicyUnsupported, errors.Errorf("unsupported pull policy %q", s) + return PullPolicyUnsupported, fmt.Errorf("unsupported pull policy %q", s) } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 1e5979a24..c0457230b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -109,9 +109,10 @@ github.com/containers/buildah/pkg/rusage github.com/containers/buildah/pkg/sshagent github.com/containers/buildah/pkg/util github.com/containers/buildah/util -# github.com/containers/common v0.48.1-0.20220512112240-7536bf6ff9b1 +# github.com/containers/common v0.48.1-0.20220523155016-2fd37da97824 ## explicit github.com/containers/common/libimage +github.com/containers/common/libimage/define github.com/containers/common/libimage/manifests github.com/containers/common/libnetwork/cni github.com/containers/common/libnetwork/etchosts |