diff options
Diffstat (limited to 'cmd')
28 files changed, 627 insertions, 172 deletions
diff --git a/cmd/podman/attach.go b/cmd/podman/attach.go index 7d32c57af..6f08cc396 100644 --- a/cmd/podman/attach.go +++ b/cmd/podman/attach.go @@ -2,7 +2,6 @@ package main import ( "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/adapter" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -32,10 +31,7 @@ func init() { attachCommand.SetHelpTemplate(HelpTemplate()) attachCommand.SetUsageTemplate(UsageTemplate()) flags := attachCommand.Flags() - flags.StringVar(&attachCommand.DetachKeys, "detach-keys", define.DefaultDetachKeys, "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`") - // Clear the default, the value specified in the config file should have the - // priority - attachCommand.DetachKeys = "" + flags.StringVar(&attachCommand.DetachKeys, "detach-keys", getDefaultDetachKeys(), "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`") flags.BoolVar(&attachCommand.NoStdin, "no-stdin", false, "Do not attach STDIN. The default is false") flags.BoolVar(&attachCommand.SigProxy, "sig-proxy", true, "Proxy received signals to the process") flags.BoolVarP(&attachCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") diff --git a/cmd/podman/build.go b/cmd/podman/build.go index acd402fdd..04bc56ab0 100644 --- a/cmd/podman/build.go +++ b/cmd/podman/build.go @@ -9,9 +9,9 @@ import ( "github.com/containers/buildah" "github.com/containers/buildah/imagebuildah" buildahcli "github.com/containers/buildah/pkg/cli" - "github.com/containers/image/v5/types" + "github.com/containers/buildah/pkg/parse" + "github.com/containers/common/pkg/config" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/adapter" "github.com/docker/go-units" "github.com/opencontainers/runtime-spec/specs-go" @@ -86,6 +86,7 @@ func initBuild() { fromAndBugFlags, err := buildahcli.GetFromAndBudFlags(&fromAndBudValues, &userNSValues, &namespaceValues) if err != nil { logrus.Errorf("failed to setup podman build flags: %v", err) + os.Exit(1) } flags.AddFlagSet(&budFlags) @@ -267,14 +268,15 @@ func buildCmd(c *cliconfig.BuildValues) error { if err != nil { return err } - if conf != nil && conf.CgroupManager == define.SystemdCgroupsManager { + if conf != nil && conf.Engine.CgroupManager == config.SystemdCgroupsManager { runtimeFlags = append(runtimeFlags, "--systemd-cgroup") } // end from buildah defer runtime.DeferredShutdown(false) - var stdout, stderr, reporter *os.File + var stdin, stdout, stderr, reporter *os.File + stdin = os.Stdin stdout = os.Stdout stderr = os.Stderr reporter = os.Stderr @@ -310,6 +312,17 @@ func buildCmd(c *cliconfig.BuildValues) error { return err } + networkPolicy := buildah.NetworkDefault + for _, ns := range nsValues { + if ns.Name == "none" { + networkPolicy = buildah.NetworkDisabled + break + } else if !filepath.IsAbs(ns.Path) { + networkPolicy = buildah.NetworkEnabled + break + } + } + buildOpts := buildah.CommonBuildOptions{ AddHost: c.AddHost, CgroupParent: c.CgroupParent, @@ -341,21 +354,49 @@ func buildCmd(c *cliconfig.BuildValues) error { layers = false } + compression := imagebuildah.Gzip + if c.DisableCompression { + compression = imagebuildah.Uncompressed + } + + isolation, err := parse.IsolationOption(c.Isolation) + if err != nil { + return errors.Wrapf(err, "error parsing ID mapping options") + } + + usernsOption, idmappingOptions, err := parse.IDMappingOptions(c.PodmanCommand.Command, isolation) + if err != nil { + return errors.Wrapf(err, "error parsing ID mapping options") + } + nsValues = append(nsValues, usernsOption...) + + systemContext, err := parse.SystemContextFromOptions(c.PodmanCommand.Command) + if err != nil { + return errors.Wrapf(err, "error building system context") + } + options := imagebuildah.BuildOptions{ - Architecture: c.Arch, - CommonBuildOpts: &buildOpts, + AddCapabilities: c.CapAdd, AdditionalTags: tags, Annotations: c.Annotation, + Architecture: c.Arch, Args: args, + BlobDirectory: c.BlobCache, CNIConfigDir: c.CNIConfigDir, CNIPluginPath: c.CNIPlugInPath, - Compression: imagebuildah.Gzip, + CommonBuildOpts: &buildOpts, + Compression: compression, + ConfigureNetwork: networkPolicy, ContextDirectory: contextDir, DefaultMountsFilePath: c.GlobalFlags.DefaultMountsFile, + Devices: c.Devices, + DropCapabilities: c.CapDrop, Err: stderr, - In: os.Stdin, ForceRmIntermediateCtrs: c.ForceRm, + IDMappingOptions: idmappingOptions, IIDFile: c.Iidfile, + In: stdin, + Isolation: isolation, Labels: c.Label, Layers: layers, NamespaceOptions: nsValues, @@ -369,13 +410,12 @@ func buildCmd(c *cliconfig.BuildValues) error { RemoveIntermediateCtrs: c.Rm, ReportWriter: reporter, RuntimeArgs: runtimeFlags, + SignBy: c.SignBy, SignaturePolicyPath: c.SignaturePolicy, Squash: c.Squash, - SystemContext: &types.SystemContext{ - OSChoice: c.OverrideOS, - ArchitectureChoice: c.OverrideArch, - }, - Target: c.Target, + SystemContext: systemContext, + Target: c.Target, + TransientMounts: c.Volumes, } _, _, err = runtime.Build(getContext(), c, options, containerfiles) return err diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go index 3428746a9..faf292ea0 100644 --- a/cmd/podman/cliconfig/config.go +++ b/cmd/podman/cliconfig/config.go @@ -2,7 +2,10 @@ package cliconfig import ( "net" + "os" + "github.com/containers/common/pkg/config" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -700,3 +703,14 @@ type SystemDfValues struct { type UntagValues struct { PodmanCommand } + +func GetDefaultConfig() *config.Config { + var err error + conf, err := config.NewConfig("") + conf.CheckCgroupsAndAdjustConfig() + if err != nil { + logrus.Errorf("Error loading container config %v\n", err) + os.Exit(1) + } + return conf +} diff --git a/cmd/podman/cliconfig/defaults.go b/cmd/podman/cliconfig/defaults.go index ce695d153..3082207e0 100644 --- a/cmd/podman/cliconfig/defaults.go +++ b/cmd/podman/cliconfig/defaults.go @@ -11,6 +11,4 @@ var ( DefaultHealthCheckTimeout = "30s" // DefaultImageVolume default value DefaultImageVolume = "bind" - // DefaultShmSize default value - DefaultShmSize = "65536k" ) diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go index dfa04315e..2ee31b643 100644 --- a/cmd/podman/commands.go +++ b/cmd/podman/commands.go @@ -3,6 +3,15 @@ package main import ( + "fmt" + "os" + + "github.com/containers/buildah/pkg/parse" + "github.com/containers/libpod/pkg/apparmor" + "github.com/containers/libpod/pkg/cgroups" + "github.com/containers/libpod/pkg/rootless" + "github.com/containers/libpod/pkg/sysinfo" + "github.com/opencontainers/selinux/go-selinux" "github.com/spf13/cobra" ) @@ -81,3 +90,107 @@ func getSystemSubCommands() []*cobra.Command { return systemCommands } + +func getDefaultSecurityOptions() []string { + securityOpts := []string{} + if defaultContainerConfig.Containers.SeccompProfile != "" && defaultContainerConfig.Containers.SeccompProfile != parse.SeccompDefaultPath { + securityOpts = append(securityOpts, fmt.Sprintf("seccomp=%s", defaultContainerConfig.Containers.SeccompProfile)) + } + if apparmor.IsEnabled() && defaultContainerConfig.Containers.ApparmorProfile != "" { + securityOpts = append(securityOpts, fmt.Sprintf("apparmor=%s", defaultContainerConfig.Containers.ApparmorProfile)) + } + if selinux.GetEnabled() && !defaultContainerConfig.Containers.EnableLabeling { + securityOpts = append(securityOpts, fmt.Sprintf("label=%s", selinux.DisableSecOpt()[0])) + } + return securityOpts +} + +// getDefaultSysctls +func getDefaultSysctls() []string { + return defaultContainerConfig.Containers.DefaultSysctls +} + +func getDefaultVolumes() []string { + return defaultContainerConfig.Containers.Volumes +} + +func getDefaultDevices() []string { + return defaultContainerConfig.Containers.Devices +} + +func getDefaultDNSServers() []string { + return defaultContainerConfig.Containers.DNSServers +} + +func getDefaultDNSSearches() []string { + return defaultContainerConfig.Containers.DNSSearches +} + +func getDefaultDNSOptions() []string { + return defaultContainerConfig.Containers.DNSOptions +} + +func getDefaultEnv() []string { + return defaultContainerConfig.Containers.Env +} + +func getDefaultInitPath() string { + return defaultContainerConfig.Containers.InitPath +} + +func getDefaultIPCNS() string { + return defaultContainerConfig.Containers.IPCNS +} + +func getDefaultPidNS() string { + return defaultContainerConfig.Containers.PidNS +} + +func getDefaultNetNS() string { + if defaultContainerConfig.Containers.NetNS == "private" && rootless.IsRootless() { + return "slirp4netns" + } + return defaultContainerConfig.Containers.NetNS +} + +func getDefaultCgroupNS() string { + return defaultContainerConfig.Containers.CgroupNS +} + +func getDefaultUTSNS() string { + return defaultContainerConfig.Containers.UTSNS +} + +func getDefaultShmSize() string { + return defaultContainerConfig.Containers.ShmSize +} + +func getDefaultUlimits() []string { + return defaultContainerConfig.Containers.DefaultUlimits +} + +func getDefaultUserNS() string { + userns := os.Getenv("PODMAN_USERNS") + if userns != "" { + return userns + } + return defaultContainerConfig.Containers.UserNS +} + +func getDefaultPidsLimit() int64 { + if rootless.IsRootless() { + cgroup2, _ := cgroups.IsCgroup2UnifiedMode() + if cgroup2 { + return defaultContainerConfig.Containers.PidsLimit + } + } + return sysinfo.GetDefaultPidsLimit() +} + +func getDefaultPidsDescription() string { + return "Tune container pids limit (set 0 for unlimited)" +} + +func getDefaultDetachKeys() string { + return defaultContainerConfig.Engine.DetachKeys +} diff --git a/cmd/podman/commands_remoteclient.go b/cmd/podman/commands_remoteclient.go index a278761c1..ef523ffb1 100644 --- a/cmd/podman/commands_remoteclient.go +++ b/cmd/podman/commands_remoteclient.go @@ -47,3 +47,89 @@ func getTrustSubCommands() []*cobra.Command { func getSystemSubCommands() []*cobra.Command { return []*cobra.Command{} } + +func getDefaultSecurityOptions() []string { + return []string{} +} + +// getDefaultSysctls +func getDefaultSysctls() []string { + return []string{} +} + +// getDefaultDevices +func getDefaultDevices() []string { + return []string{} +} + +func getDefaultVolumes() []string { + return []string{} +} + +func getDefaultDNSServers() []string { + return []string{} +} + +func getDefaultDNSSearches() []string { + return []string{} +} + +func getDefaultDNSOptions() []string { + return []string{} +} + +func getDefaultEnv() []string { + return []string{} +} + +func getDefaultInitPath() string { + return "" +} + +func getDefaultIPCNS() string { + return "" +} + +func getDefaultPidNS() string { + return "" +} + +func getDefaultNetNS() string { + return "" +} + +func getDefaultCgroupNS() string { + return "" +} + +func getDefaultUTSNS() string { + return "" +} + +func getDefaultShmSize() string { + return "" +} + +func getDefaultUlimits() []string { + return []string{} +} + +func getDefaultUserNS() string { + return "" +} + +func getDefaultPidsLimit() int64 { + return -1 +} + +func getDefaultPidsDescription() string { + return "Tune container pids limit (set 0 for unlimited, -1 for server defaults)" +} + +func getDefaultShareNetwork() string { + return "" +} + +func getDefaultDetachKeys() string { + return "" +} diff --git a/cmd/podman/common.go b/cmd/podman/common.go index 4eeb09d42..9aa9a63fe 100644 --- a/cmd/podman/common.go +++ b/cmd/podman/common.go @@ -3,15 +3,11 @@ package main import ( "context" "fmt" - "os" "strings" "github.com/containers/buildah" buildahcli "github.com/containers/buildah/pkg/cli" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/libpod/define" - "github.com/containers/libpod/pkg/rootless" - "github.com/containers/libpod/pkg/sysinfo" "github.com/containers/libpod/pkg/util/camelcase" jsoniter "github.com/json-iterator/go" "github.com/pkg/errors" @@ -110,29 +106,22 @@ func getContext() context.Context { return context.TODO() } -func getDefaultNetwork() string { - if rootless.IsRootless() { - return "slirp4netns" - } - return "bridge" -} - func getNetFlags() *pflag.FlagSet { netFlags := pflag.FlagSet{} netFlags.StringSlice( "add-host", []string{}, - "Add a custom host-to-IP mapping (host:ip) (default [])", + "Add a custom host-to-IP mapping (host:ip)", ) netFlags.StringSlice( - "dns", []string{}, + "dns", getDefaultDNSServers(), "Set custom DNS servers", ) netFlags.StringSlice( - "dns-opt", []string{}, + "dns-opt", getDefaultDNSOptions(), "Set custom DNS options", ) netFlags.StringSlice( - "dns-search", []string{}, + "dns-search", getDefaultDNSSearches(), "Set custom DNS search domains", ) netFlags.String( @@ -144,7 +133,7 @@ func getNetFlags() *pflag.FlagSet { "Container MAC address (e.g. 92:d0:c6:0a:29:33)", ) netFlags.String( - "network", getDefaultNetwork(), + "network", getDefaultNetNS(), "Connect a container to a network", ) netFlags.StringSliceP( @@ -162,11 +151,11 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { createFlags := c.Flags() createFlags.StringSlice( "annotation", []string{}, - "Add annotations to container (key:value) (default [])", + "Add annotations to container (key:value)", ) createFlags.StringSliceP( "attach", "a", []string{}, - "Attach to STDIN, STDOUT or STDERR (default [])", + "Attach to STDIN, STDOUT or STDERR", ) createFlags.String( "authfile", buildahcli.GetDefaultAuthFile(), @@ -189,7 +178,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { "Drop capabilities from the container", ) createFlags.String( - "cgroupns", "", + "cgroupns", getDefaultCgroupNS(), "cgroup namespace to use", ) createFlags.String( @@ -244,17 +233,13 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { "detach", "d", false, "Run container in background and print container ID", ) - detachKeys := createFlags.String( - "detach-keys", define.DefaultDetachKeys, + createFlags.String( + "detach-keys", getDefaultDetachKeys(), "Override the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`", ) - // Clear the default, the value specified in the config file should have the - // priority - *detachKeys = "" - createFlags.StringSlice( - "device", []string{}, - "Add a host device to the container (default [])", + "device", getDefaultDevices(), + fmt.Sprintf("Add a host device to the container"), ) createFlags.StringSlice( "device-cgroup-rule", []string{}, @@ -281,7 +266,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { "Overwrite the default ENTRYPOINT of the image", ) createFlags.StringArrayP( - "env", "e", []string{}, + "env", "e", getDefaultEnv(), "Set environment variables in container", ) createFlags.Bool( @@ -293,7 +278,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { ) createFlags.StringSlice( "expose", []string{}, - "Expose a port or a range of ports (default [])", + "Expose a port or a range of ports", ) createFlags.StringSlice( "gidmap", []string{}, @@ -301,7 +286,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { ) createFlags.StringSlice( "group-add", []string{}, - "Add additional groups to join (default [])", + "Add additional groups to join", ) createFlags.Bool( "help", false, "", @@ -343,16 +328,16 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { "Run an init binary inside the container that forwards signals and reaps processes", ) createFlags.String( - "init-path", "", + "init-path", getDefaultInitPath(), // Do not use the Value field for setting the default value to determine user input (i.e., non-empty string) - fmt.Sprintf("Path to the container-init binary (default: %q)", define.DefaultInitPath), + fmt.Sprintf("Path to the container-init binary"), ) createFlags.BoolP( "interactive", "i", false, "Keep STDIN open even if not attached", ) createFlags.String( - "ipc", "", + "ipc", getDefaultIPCNS(), "IPC namespace to use", ) createFlags.String( @@ -361,11 +346,11 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { ) createFlags.StringArrayP( "label", "l", []string{}, - "Set metadata on container (default [])", + "Set metadata on container", ) createFlags.StringSlice( "label-file", []string{}, - "Read in a line delimited file of labels (default [])", + "Read in a line delimited file of labels", ) createFlags.String( "log-driver", "", @@ -373,7 +358,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { ) createFlags.StringSlice( "log-opt", []string{}, - "Logging driver options (default [])", + "Logging driver options", ) createFlags.StringP( "memory", "m", "", @@ -418,12 +403,12 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { ) markFlagHidden(createFlags, "override-os") createFlags.String( - "pid", "", + "pid", getDefaultPidNS(), "PID namespace to use", ) createFlags.Int64( - "pids-limit", sysinfo.GetDefaultPidsLimit(), - "Tune container pids limit (set 0 for unlimited)", + "pids-limit", getDefaultPidsLimit(), + getDefaultPidsDescription(), ) createFlags.String( "pod", "", @@ -466,11 +451,11 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { "The first argument is not an image but the rootfs to the exploded container", ) createFlags.StringArray( - "security-opt", []string{}, - "Security Options (default [])", + "security-opt", getDefaultSecurityOptions(), + fmt.Sprintf("Security Options"), ) createFlags.String( - "shm-size", cliconfig.DefaultShmSize, + "shm-size", getDefaultShmSize(), "Size of /dev/shm "+sizeWithUnitFormat, ) createFlags.String( @@ -478,12 +463,12 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { "Signal to stop a container. Default is SIGTERM", ) createFlags.Uint( - "stop-timeout", define.CtrRemoveTimeout, + "stop-timeout", defaultContainerConfig.Engine.StopTimeout, "Timeout (in seconds) to stop a container. Default is 10", ) createFlags.StringSlice( "storage-opt", []string{}, - "Storage driver options per container (default [])", + "Storage driver options per container", ) createFlags.String( "subgidname", "", @@ -495,8 +480,8 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { ) createFlags.StringSlice( - "sysctl", []string{}, - "Sysctl options (default [])", + "sysctl", getDefaultSysctls(), + "Sysctl options", ) createFlags.String( "systemd", "true", @@ -504,7 +489,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { ) createFlags.StringArray( "tmpfs", []string{}, - "Mount a temporary filesystem (`tmpfs`) into a container (default [])", + "Mount a temporary filesystem (`tmpfs`) into a container", ) createFlags.BoolP( "tty", "t", false, @@ -515,32 +500,32 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { "UID map to use for the user namespace", ) createFlags.StringSlice( - "ulimit", []string{}, - "Ulimit options (default [])", + "ulimit", getDefaultUlimits(), + "Ulimit options", ) createFlags.StringP( "user", "u", "", "Username or UID (format: <name|uid>[:<group|gid>])", ) createFlags.String( - "userns", os.Getenv("PODMAN_USERNS"), + "userns", getDefaultUserNS(), "User namespace to use", ) createFlags.String( - "uts", "", + "uts", getDefaultUTSNS(), "UTS namespace to use", ) createFlags.StringArray( "mount", []string{}, - "Attach a filesystem mount to the container (default [])", + "Attach a filesystem mount to the container", ) createFlags.StringArrayP( - "volume", "v", []string{}, - "Bind mount a volume into the container (default [])", + "volume", "v", getDefaultVolumes(), + "Bind mount a volume into the container", ) createFlags.StringSlice( "volumes-from", []string{}, - "Mount volumes from the specified container(s) (default [])", + "Mount volumes from the specified container(s)", ) createFlags.StringP( "workdir", "w", "", diff --git a/cmd/podman/create.go b/cmd/podman/create.go index 73d62bddb..03eb1b09f 100644 --- a/cmd/podman/create.go +++ b/cmd/podman/create.go @@ -38,7 +38,6 @@ func init() { createCommand.PodmanCommand.Command = _createCommand createCommand.SetHelpTemplate(HelpTemplate()) createCommand.SetUsageTemplate(UsageTemplate()) - getCreateFlags(&createCommand.PodmanCommand) flags := createCommand.Flags() flags.AddFlagSet(getNetFlags()) diff --git a/cmd/podman/exec.go b/cmd/podman/exec.go index 6e5799396..b341ab496 100644 --- a/cmd/podman/exec.go +++ b/cmd/podman/exec.go @@ -2,7 +2,6 @@ package main import ( "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/adapter" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -35,10 +34,7 @@ func init() { execCommand.SetUsageTemplate(UsageTemplate()) flags := execCommand.Flags() flags.SetInterspersed(false) - flags.StringVar(&execCommand.DetachKeys, "detach-keys", define.DefaultDetachKeys, "Select the key sequence for detaching a container. Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _") - // Clear the default, the value specified in the config file should have the - // priority - execCommand.DetachKeys = "" + flags.StringVar(&execCommand.DetachKeys, "detach-keys", getDefaultDetachKeys(), "Select the key sequence for detaching a container. Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _") flags.StringArrayVarP(&execCommand.Env, "env", "e", []string{}, "Set environment variables") flags.StringSliceVar(&execCommand.EnvFile, "env-file", []string{}, "Read in a file of environment variables") flags.BoolVarP(&execCommand.Interactive, "interactive", "i", false, "Keep STDIN open even if not attached") diff --git a/cmd/podman/libpodruntime/runtime.go b/cmd/podman/libpodruntime/runtime.go index e9dc87de1..8dbc4009b 100644 --- a/cmd/podman/libpodruntime/runtime.go +++ b/cmd/podman/libpodruntime/runtime.go @@ -211,8 +211,6 @@ func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, opts *runtimeOp if !opts.withFDS { options = append(options, libpod.WithEnableSDNotify()) } - if c.Flags().Changed("config") { - return libpod.NewRuntimeFromConfig(ctx, c.GlobalFlags.Config, options...) - } + return libpod.NewRuntime(ctx, options...) } diff --git a/cmd/podman/login.go b/cmd/podman/login.go index e09117833..1539e3a79 100644 --- a/cmd/podman/login.go +++ b/cmd/podman/login.go @@ -95,17 +95,19 @@ func loginCmd(c *cliconfig.LoginValues) error { } // username of user logged in to server (if one exists) - userFromAuthFile, passFromAuthFile, err := config.GetAuthentication(sc, server) + authConfig, err := config.GetCredentials(sc, server) // Do not return error if no credentials found in credHelpers, new credentials will be stored by config.SetAuthentication if err != nil && err != credentials.NewErrCredentialsNotFound() { return errors.Wrapf(err, "error reading auth file") } - + if authConfig.IdentityToken != "" { + return errors.Errorf("currently logged in, auth file contains an Identity token") + } if c.Flag("get-login").Changed { - if userFromAuthFile == "" { + if authConfig.Username == "" { return errors.Errorf("not logged into %s", server) } - fmt.Printf("%s\n", userFromAuthFile) + fmt.Printf("%s\n", authConfig.Username) return nil } @@ -129,16 +131,16 @@ func loginCmd(c *cliconfig.LoginValues) error { } // If no username and no password is specified, try to use existing ones. - if c.Username == "" && password == "" && userFromAuthFile != "" && passFromAuthFile != "" { + if c.Username == "" && password == "" && authConfig.Username == "" && authConfig.Password != "" { fmt.Println("Authenticating with existing credentials...") - if err := docker.CheckAuth(ctx, sc, userFromAuthFile, passFromAuthFile, server); err == nil { + if err := docker.CheckAuth(ctx, sc, authConfig.Username, authConfig.Password, server); err == nil { fmt.Println("Existing credentials are valid. Already logged in to", server) return nil } fmt.Println("Existing credentials are invalid, please enter valid username and password") } - username, password, err := getUserAndPass(c.Username, password, userFromAuthFile) + username, password, err := getUserAndPass(c.Username, password, authConfig.Username) if err != nil { return errors.Wrapf(err, "error getting username and password") } diff --git a/cmd/podman/logout.go b/cmd/podman/logout.go index dec6822cf..a541438c3 100644 --- a/cmd/podman/logout.go +++ b/cmd/podman/logout.go @@ -87,12 +87,12 @@ func logoutCmd(c *cliconfig.LogoutValues) error { return nil case config.ErrNotLoggedIn: // username of user logged in to server (if one exists) - userFromAuthFile, passFromAuthFile, err := config.GetAuthentication(sc, server) + authConfig, err := config.GetCredentials(sc, server) if err != nil { return errors.Wrapf(err, "error reading auth file") } - islogin := docker.CheckAuth(getContext(), sc, userFromAuthFile, passFromAuthFile, server) - if userFromAuthFile != "" && passFromAuthFile != "" && islogin == nil { + islogin := docker.CheckAuth(getContext(), sc, authConfig.Username, authConfig.Password, server) + if authConfig.IdentityToken != "" && authConfig.Username != "" && authConfig.Password != "" && islogin == nil { fmt.Printf("Not logged into %s with podman. Existing credentials were established via docker login. Please use docker logout instead.\n", server) return nil } diff --git a/cmd/podman/main.go b/cmd/podman/main.go index a2acbbf53..5134448da 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -6,6 +6,7 @@ import ( "os" "path" + "github.com/containers/common/pkg/config" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" @@ -81,7 +82,10 @@ var rootCmd = &cobra.Command{ SilenceErrors: true, } -var MainGlobalOpts cliconfig.MainFlags +var ( + MainGlobalOpts cliconfig.MainFlags + defaultContainerConfig = getDefaultContainerConfig() +) func initCobra() { cobra.OnInitialize(initConfig) @@ -175,3 +179,12 @@ func main() { CheckForRegistries() os.Exit(exitCode) } + +func getDefaultContainerConfig() *config.Config { + defaultContainerConfig, err := config.Default() + if err != nil { + logrus.Error(err) + os.Exit(1) + } + return defaultContainerConfig +} diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go index 79b5e5af7..b03c7de44 100644 --- a/cmd/podman/main_local.go +++ b/cmd/podman/main_local.go @@ -14,9 +14,9 @@ import ( "strings" "syscall" + "github.com/containers/common/pkg/config" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/libpodruntime" - "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/cgroups" "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/tracing" @@ -32,9 +32,11 @@ import ( const remote = false func init() { - cgroupManager := define.SystemdCgroupsManager + cgroupManager := defaultContainerConfig.Engine.CgroupManager cgroupHelp := `Cgroup manager to use ("cgroupfs"|"systemd")` cgroupv2, _ := cgroups.IsCgroup2UnifiedMode() + + defaultContainerConfig = cliconfig.GetDefaultConfig() if rootless.IsRootless() && !cgroupv2 { cgroupManager = "" cgroupHelp = "Cgroup manager is not supported in rootless mode" @@ -42,25 +44,27 @@ func init() { rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.CGroupManager, "cgroup-manager", cgroupManager, cgroupHelp) // -c is deprecated due to conflict with -c on subcommands rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.CpuProfile, "cpu-profile", "", "Path for the cpu profiling results") - rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.Config, "config", "", "Path of a libpod config file detailing container server configuration options") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.ConmonPath, "conmon", "", "Path of the conmon binary") - rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.NetworkCmdPath, "network-cmd-path", "", "Path to the command for configuring the network") - rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.CniConfigDir, "cni-config-dir", "", "Path of the configuration directory for CNI networks") - rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.DefaultMountsFile, "default-mounts-file", "", "Path to default mounts file") + rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.NetworkCmdPath, "network-cmd-path", defaultContainerConfig.Engine.NetworkCmdPath, "Path to the command for configuring the network") + rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.CniConfigDir, "cni-config-dir", getCNIPluginsDir(), "Path of the configuration directory for CNI networks") + rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.DefaultMountsFile, "default-mounts-file", defaultContainerConfig.Containers.DefaultMountsFile, "Path to default mounts file") + if err := rootCmd.PersistentFlags().MarkHidden("cpu-profile"); err != nil { + logrus.Error("unable to mark default-mounts-file flag as hidden") + } if err := rootCmd.PersistentFlags().MarkHidden("default-mounts-file"); err != nil { logrus.Error("unable to mark default-mounts-file flag as hidden") } - rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.EventsBackend, "events-backend", "", `Events backend to use ("file"|"journald"|"none")`) + rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.EventsBackend, "events-backend", defaultContainerConfig.Engine.EventsLogger, `Events backend to use ("file"|"journald"|"none")`) // Override default --help information of `--help` global flag var dummyHelp bool rootCmd.PersistentFlags().BoolVar(&dummyHelp, "help", false, "Help for podman") - rootCmd.PersistentFlags().StringSliceVar(&MainGlobalOpts.HooksDir, "hooks-dir", []string{}, "Set the OCI hooks directory path (may be set multiple times)") + rootCmd.PersistentFlags().StringSliceVar(&MainGlobalOpts.HooksDir, "hooks-dir", defaultContainerConfig.Engine.HooksDir, "Set the OCI hooks directory path (may be set multiple times)") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.LogLevel, "log-level", "error", `Log messages above specified level ("debug"|"info"|"warn"|"error"|"fatal"|"panic")`) rootCmd.PersistentFlags().IntVar(&MainGlobalOpts.MaxWorks, "max-workers", 0, "The maximum number of workers for parallel operations") if err := rootCmd.PersistentFlags().MarkHidden("max-workers"); err != nil { logrus.Error("unable to mark max-workers flag as hidden") } - rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.Namespace, "namespace", "", "Set the libpod namespace, used to create separate views of the containers and pods on the system") + rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.Namespace, "namespace", defaultContainerConfig.Engine.Namespace, "Set the libpod namespace, used to create separate views of the containers and pods on the system") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.Root, "root", "", "Path to the root directory in which data, including images, is stored") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.Runroot, "runroot", "", "Path to the 'run directory' where all state information is stored") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.Runtime, "runtime", "", "Path to the OCI-compatible binary used to run containers, default is /usr/bin/runc") @@ -179,7 +183,7 @@ func setupRootless(cmd *cobra.Command, args []string) error { if !ownsCgroup { unitName := fmt.Sprintf("podman-%d.scope", os.Getpid()) if err := utils.RunUnderSystemdScope(os.Getpid(), "user.slice", unitName); err != nil { - if conf.CgroupManager == define.SystemdCgroupsManager { + if conf.Engine.CgroupManager == config.SystemdCgroupsManager { logrus.Warnf("Failed to add podman to systemd sandbox cgroup: %v", err) } else { logrus.Debugf("Failed to add podman to systemd sandbox cgroup: %v", err) @@ -223,7 +227,7 @@ func setupRootless(cmd *cobra.Command, args []string) error { if err != nil { return err } - if conf.CgroupManager == define.SystemdCgroupsManager { + if conf.Engine.CgroupManager == config.SystemdCgroupsManager { logrus.Warnf("Failed to add pause process to systemd sandbox cgroup: %v", err) } else { logrus.Debugf("Failed to add pause process to systemd sandbox cgroup: %v", err) @@ -264,3 +268,10 @@ func setUMask() { func checkInput() error { return nil } +func getCNIPluginsDir() string { + if rootless.IsRootless() { + return "" + } + + return defaultContainerConfig.Network.CNIPluginDirs[0] +} diff --git a/cmd/podman/mount.go b/cmd/podman/mount.go index 526a236fd..99e185589 100644 --- a/cmd/podman/mount.go +++ b/cmd/podman/mount.go @@ -68,11 +68,7 @@ func mountCmd(c *cliconfig.MountValues) error { defer runtime.DeferredShutdown(false) if os.Geteuid() != 0 { - rtc, err := runtime.GetConfig() - if err != nil { - return err - } - if driver := rtc.StorageConfig.GraphDriverName; driver != "vfs" { + if driver := runtime.StorageConfig().GraphDriverName; driver != "vfs" { // Do not allow to mount a graphdriver that is not vfs if we are creating the userns as part // of the mount command. return fmt.Errorf("cannot mount using driver %s in rootless mode", driver) diff --git a/cmd/podman/restart.go b/cmd/podman/restart.go index 996a9f7ce..a55f83c67 100644 --- a/cmd/podman/restart.go +++ b/cmd/podman/restart.go @@ -39,9 +39,10 @@ func init() { flags.BoolVarP(&restartCommand.All, "all", "a", false, "Restart all non-running containers") flags.BoolVarP(&restartCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") flags.BoolVar(&restartCommand.Running, "running", false, "Restart only running containers when --all is used") - flags.UintVarP(&restartCommand.Timeout, "timeout", "t", define.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") - flags.UintVar(&restartCommand.Timeout, "time", define.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") + flags.UintVarP(&restartCommand.Timeout, "time", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container") + flags.UintVar(&restartCommand.Timeout, "timeout", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container") + markFlagHidden(flags, "timeout") markFlagHiddenForRemoteClient("latest", flags) } diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go index cec837af6..5fa8d6c0b 100644 --- a/cmd/podman/shared/create.go +++ b/cmd/podman/shared/create.go @@ -99,7 +99,7 @@ func CreateContainer(ctx context.Context, c *GenericCLIResults, runtime *libpod. ArchitectureChoice: overrideArch, } - newImage, err := runtime.ImageRuntime().New(ctx, rawImageName, rtc.SignaturePolicyPath, c.String("authfile"), writer, &dockerRegistryOptions, image.SigningOptions{}, nil, pullType) + newImage, err := runtime.ImageRuntime().New(ctx, rawImageName, rtc.Engine.SignaturePolicyPath, c.String("authfile"), writer, &dockerRegistryOptions, image.SigningOptions{}, nil, pullType) if err != nil { return nil, nil, err } @@ -512,6 +512,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. } // Start with env-host + if c.Bool("env-host") { env = envLib.Join(env, osEnv) } @@ -635,7 +636,6 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. if err != nil { return nil, errors.Wrapf(err, "unable to translate --shm-size") } - // Verify the additional hosts are in correct format for _, host := range c.StringSlice("add-host") { if _, err := parse.ValidateExtraHost(host); err != nil { @@ -643,24 +643,35 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. } } - // Check for . and dns-search domains - if util.StringInSlice(".", c.StringSlice("dns-search")) && len(c.StringSlice("dns-search")) > 1 { - return nil, errors.Errorf("cannot pass additional search domains when also specifying '.'") + var ( + dnsSearches []string + dnsServers []string + dnsOptions []string + ) + if c.Changed("dns-search") { + dnsSearches = c.StringSlice("dns-search") + // Check for explicit dns-search domain of '' + if len(dnsSearches) == 0 { + return nil, errors.Errorf("'' is not a valid domain") + } + // Validate domains are good + for _, dom := range dnsSearches { + if dom == "." { + if len(dnsSearches) > 1 { + return nil, errors.Errorf("cannot pass additional search domains when also specifying '.'") + } + continue + } + if _, err := parse.ValidateDomain(dom); err != nil { + return nil, err + } + } } - - // Check for explicit dns-search domain of '' - if c.Changed("dns-search") && len(c.StringSlice("dns-search")) == 0 { - return nil, errors.Errorf("'' is not a valid domain") + if c.IsSet("dns") { + dnsServers = append(dnsServers, c.StringSlice("dns")...) } - - // Validate domains are good - for _, dom := range c.StringSlice("dns-search") { - if dom == "." { - continue - } - if _, err := parse.ValidateDomain(dom); err != nil { - return nil, err - } + if c.IsSet("dns-opt") { + dnsOptions = c.StringSlice("dns-opt") } var ImageVolumes map[string]struct{} @@ -706,7 +717,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. pidsLimit := c.Int64("pids-limit") if c.String("cgroups") == "disabled" && !c.Changed("pids-limit") { - pidsLimit = 0 + pidsLimit = -1 } pid := &cc.PidConfig{ @@ -736,11 +747,10 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. HostAdd: c.StringSlice("add-host"), Hostname: c.String("hostname"), } - net := &cc.NetworkConfig{ - DNSOpt: c.StringSlice("dns-opt"), - DNSSearch: c.StringSlice("dns-search"), - DNSServers: c.StringSlice("dns"), + DNSOpt: dnsOptions, + DNSSearch: dnsSearches, + DNSServers: dnsServers, HTTPProxy: c.Bool("http-proxy"), MacAddress: c.String("mac-address"), Network: c.String("network"), @@ -751,9 +761,12 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. PortBindings: portBindings, } - sysctl, err := validateSysctl(c.StringSlice("sysctl")) - if err != nil { - return nil, errors.Wrapf(err, "invalid value for sysctl") + sysctl := map[string]string{} + if c.Changed("sysctl") { + sysctl, err = util.ValidateSysctls(c.StringSlice("sysctl")) + if err != nil { + return nil, errors.Wrapf(err, "invalid value for sysctl") + } } secConfig := &cc.SecurityConfig{ @@ -765,8 +778,10 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. Sysctl: sysctl, } - if err := secConfig.SetSecurityOpts(runtime, c.StringArray("security-opt")); err != nil { - return nil, err + if c.Changed("security-opt") { + if err := secConfig.SetSecurityOpts(runtime, c.StringArray("security-opt")); err != nil { + return nil, err + } } // SECCOMP @@ -780,6 +795,19 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. } else { secConfig.SeccompPolicy = policy } + rtc, err := runtime.GetConfig() + if err != nil { + return nil, err + } + volumes := rtc.Containers.Volumes + if c.Changed("volume") { + volumes = append(volumes, c.StringSlice("volume")...) + } + + devices := rtc.Containers.Devices + if c.Changed("device") { + devices = append(devices, c.StringSlice("device")...) + } config := &cc.CreateConfig{ Annotations: annotations, @@ -790,7 +818,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. Command: command, UserCommand: userCommand, Detach: c.Bool("detach"), - Devices: c.StringSlice("device"), + Devices: devices, Entrypoint: entrypoint, Env: env, // ExposedPorts: ports, @@ -845,7 +873,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. Tmpfs: c.StringArray("tmpfs"), Tty: tty, MountsFlag: c.StringArray("mount"), - Volumes: c.StringArray("volume"), + Volumes: volumes, WorkDir: workDir, Rootfs: rootfs, VolumesFrom: c.StringSlice("volumes-from"), diff --git a/cmd/podman/shared/intermediate_varlink.go b/cmd/podman/shared/intermediate_varlink.go index 691c4f92d..d2b048025 100644 --- a/cmd/podman/shared/intermediate_varlink.go +++ b/cmd/podman/shared/intermediate_varlink.go @@ -316,6 +316,7 @@ func intFromVarlink(v *int64, flagName string, defaultValue *int) CRInt { // structure. func VarlinkCreateToGeneric(opts iopodman.Create) GenericCLIResults { + defaultContainerConfig := cliconfig.GetDefaultConfig() // TODO | WARN // We do not get a default network over varlink. Unlike the other default values for some cli // elements, it seems it gets set to the default anyway. @@ -405,7 +406,7 @@ func VarlinkCreateToGeneric(opts iopodman.Create) GenericCLIResults { m["rm"] = boolFromVarlink(opts.Rm, "rm", false) m["rootfs"] = boolFromVarlink(opts.Rootfs, "rootfs", false) m["security-opt"] = stringArrayFromVarlink(opts.SecurityOpt, "security-opt", nil) - m["shm-size"] = stringFromVarlink(opts.ShmSize, "shm-size", &cliconfig.DefaultShmSize) + m["shm-size"] = stringFromVarlink(opts.ShmSize, "shm-size", &defaultContainerConfig.Containers.ShmSize) m["stop-signal"] = stringFromVarlink(opts.StopSignal, "stop-signal", nil) m["stop-timeout"] = uintFromVarlink(opts.StopTimeout, "stop-timeout", nil) m["storage-opt"] = stringSliceFromVarlink(opts.StorageOpt, "storage-opt", nil) diff --git a/cmd/podman/sign.go b/cmd/podman/sign.go index 8ac59b33b..7da3459cf 100644 --- a/cmd/podman/sign.go +++ b/cmd/podman/sign.go @@ -126,19 +126,14 @@ func signCmd(c *cliconfig.SignValues) error { if err != nil { return err } - newImage, err := runtime.ImageRuntime().New(getContext(), signimage, rtc.SignaturePolicyPath, "", os.Stderr, &dockerRegistryOptions, image.SigningOptions{SignBy: signby}, nil, util.PullImageMissing) + newImage, err := runtime.ImageRuntime().New(getContext(), signimage, rtc.Engine.SignaturePolicyPath, "", os.Stderr, &dockerRegistryOptions, image.SigningOptions{SignBy: signby}, nil, util.PullImageMissing) if err != nil { return errors.Wrapf(err, "error pulling image %s", signimage) } if rootless.IsRootless() { if sigStoreDir == "" { - runtimeConfig, err := runtime.GetConfig() - if err != nil { - return err - } - - sigStoreDir = filepath.Join(filepath.Dir(runtimeConfig.StorageConfig.GraphRoot), "sigstore") + sigStoreDir = filepath.Join(filepath.Dir(runtime.StorageConfig().GraphRoot), "sigstore") } } else { registryInfo := trust.HaveMatchRegistry(rawSource.Reference().DockerReference().String(), registryConfigs) diff --git a/cmd/podman/start.go b/cmd/podman/start.go index a070cd18d..ee700032f 100644 --- a/cmd/podman/start.go +++ b/cmd/podman/start.go @@ -35,10 +35,7 @@ func init() { startCommand.SetUsageTemplate(UsageTemplate()) flags := startCommand.Flags() flags.BoolVarP(&startCommand.Attach, "attach", "a", false, "Attach container's STDOUT and STDERR") - // Clear the default, the value specified in the config file should have the - // priority - startCommand.DetachKeys = "" - flags.StringVar(&startCommand.DetachKeys, "detach-keys", define.DefaultDetachKeys, "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`") + flags.StringVar(&startCommand.DetachKeys, "detach-keys", getDefaultDetachKeys(), "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`") flags.BoolVarP(&startCommand.Interactive, "interactive", "i", false, "Keep STDIN open even if not attached") flags.BoolVarP(&startCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") flags.BoolVar(&startCommand.SigProxy, "sig-proxy", false, "Proxy received signals to the process (default true if attaching, false otherwise)") diff --git a/cmd/podman/stop.go b/cmd/podman/stop.go index c62da80df..383a1f61c 100644 --- a/cmd/podman/stop.go +++ b/cmd/podman/stop.go @@ -2,7 +2,6 @@ package main import ( "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/adapter" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" @@ -29,7 +28,7 @@ var ( }, Example: `podman stop ctrID podman stop --latest - podman stop --timeout 2 mywebserver 6e534f14da9d`, + podman stop --time 2 mywebserver 6e534f14da9d`, } ) @@ -42,8 +41,9 @@ func init() { flags.BoolVarP(&stopCommand.Ignore, "ignore", "i", false, "Ignore errors when a specified container is missing") flags.StringArrayVarP(&stopCommand.CIDFiles, "cidfile", "", nil, "Read the container ID from the file") flags.BoolVarP(&stopCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - flags.UintVar(&stopCommand.Timeout, "time", define.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") - flags.UintVarP(&stopCommand.Timeout, "timeout", "t", define.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") + flags.UintVarP(&stopCommand.Timeout, "time", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container") + flags.UintVar(&stopCommand.Timeout, "timeout", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container") + markFlagHidden(flags, "timeout") markFlagHiddenForRemoteClient("latest", flags) markFlagHiddenForRemoteClient("cidfile", flags) markFlagHiddenForRemoteClient("ignore", flags) diff --git a/cmd/podman/unshare.go b/cmd/podman/unshare.go index 31ce441f4..28d17a319 100644 --- a/cmd/podman/unshare.go +++ b/cmd/podman/unshare.go @@ -66,13 +66,8 @@ func unshareCmd(c *cliconfig.PodmanCommand) error { if err != nil { return err } - runtimeConfig, err := runtime.GetConfig() - if err != nil { - return err - } - cmd := exec.Command(c.InputArgs[0], c.InputArgs[1:]...) - cmd.Env = unshareEnv(runtimeConfig.StorageConfig.GraphRoot, runtimeConfig.StorageConfig.RunRoot) + cmd.Env = unshareEnv(runtime.StorageConfig().GraphRoot, runtime.StorageConfig().RunRoot) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index 0ef350fc2..0cb95ef97 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -414,6 +414,8 @@ type BuildOptions ( # BuildInfo is used to describe user input for building images type BuildInfo ( + architecture: string, + addCapabilities: []string, additionalTags: []string, annotations: []string, buildArgs: [string]string, @@ -423,13 +425,16 @@ type BuildInfo ( compression: string, contextDir: string, defaultsMountFilePath: string, + devices: []string, dockerfiles: []string, + dropCapabilities: []string, err: string, forceRmIntermediateCtrs: bool, iidfile: string, label: []string, layers: bool, nocache: bool, + os: string, out: string, output: string, outputFormat: string, @@ -438,7 +443,10 @@ type BuildInfo ( remoteIntermediateCtrs: bool, reportWriter: string, runtimeArgs: []string, - squash: bool + signBy: string, + squash: bool, + target: string, + transientMounts: []string ) # MoreResponse is a struct for when responses from varlink requires longer output diff --git a/cmd/podmanV2/containers/commit.go b/cmd/podmanV2/containers/commit.go new file mode 100644 index 000000000..28eb42f33 --- /dev/null +++ b/cmd/podmanV2/containers/commit.go @@ -0,0 +1,79 @@ +package containers + +import ( + "context" + "fmt" + "io/ioutil" + "os" + "strings" + + "github.com/containers/libpod/cmd/podmanV2/registry" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +var ( + commitDescription = `Create an image from a container's changes. Optionally tag the image created, set the author with the --author flag, set the commit message with the --message flag, and make changes to the instructions with the --change flag.` + + commitCommand = &cobra.Command{ + Use: "commit [flags] CONTAINER [IMAGE]", + Short: "Create new image based on the changed container", + Long: commitDescription, + RunE: commit, + PreRunE: preRunE, + Args: cobra.MinimumNArgs(1), + Example: `podman commit -q --message "committing container to image" reverent_golick image-committed + podman commit -q --author "firstName lastName" reverent_golick image-committed + podman commit -q --pause=false containerID image-committed + podman commit containerID`, + } + + // ChangeCmds is the list of valid Changes commands to passed to the Commit call + ChangeCmds = []string{"CMD", "ENTRYPOINT", "ENV", "EXPOSE", "LABEL", "ONBUILD", "STOPSIGNAL", "USER", "VOLUME", "WORKDIR"} +) + +var ( + commitOptions = entities.CommitOptions{ + ImageName: "", + } + iidFile string +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: commitCommand, + }) + flags := commitCommand.Flags() + flags.StringArrayVarP(&commitOptions.Changes, "change", "c", []string{}, "Apply the following possible instructions to the created image (default []): "+strings.Join(ChangeCmds, " | ")) + flags.StringVarP(&commitOptions.Format, "format", "f", "oci", "`Format` of the image manifest and metadata") + flags.StringVarP(&iidFile, "iidfile", "", "", "`file` to write the image ID to") + flags.StringVarP(&commitOptions.Message, "message", "m", "", "Set commit message for imported image") + flags.StringVarP(&commitOptions.Author, "author", "a", "", "Set the author for the image committed") + flags.BoolVarP(&commitOptions.Pause, "pause", "p", false, "Pause container during commit") + flags.BoolVarP(&commitOptions.Quiet, "quiet", "q", false, "Suppress output") + flags.BoolVar(&commitOptions.IncludeVolumes, "include-volumes", false, "Include container volumes as image volumes") + +} +func commit(cmd *cobra.Command, args []string) error { + container := args[0] + if len(args) > 1 { + commitOptions.ImageName = args[1] + } + if !commitOptions.Quiet { + commitOptions.Writer = os.Stderr + } + + response, err := registry.ContainerEngine().ContainerCommit(context.Background(), container, commitOptions) + if err != nil { + return err + } + if len(iidFile) > 0 { + if err = ioutil.WriteFile(iidFile, []byte(response.Id), 0644); err != nil { + return errors.Wrapf(err, "failed to write image ID to file %q", iidFile) + } + } + fmt.Println(response.Id) + return nil +} diff --git a/cmd/podmanV2/containers/container.go b/cmd/podmanV2/containers/container.go index 6b44f2a3e..b922eea05 100644 --- a/cmd/podmanV2/containers/container.go +++ b/cmd/podmanV2/containers/container.go @@ -1,8 +1,12 @@ package containers import ( + "os" + + "github.com/containers/common/pkg/config" "github.com/containers/libpod/cmd/podmanV2/registry" "github.com/containers/libpod/pkg/domain/entities" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -16,6 +20,8 @@ var ( PersistentPreRunE: preRunE, RunE: registry.SubCommandExists, } + + defaultContainerConfig = getDefaultContainerConfig() ) func init() { @@ -31,3 +37,12 @@ func preRunE(cmd *cobra.Command, args []string) error { _, err := registry.NewContainerEngine(cmd, args) return err } + +func getDefaultContainerConfig() *config.Config { + defaultContainerConfig, err := config.Default() + if err != nil { + logrus.Error(err) + os.Exit(1) + } + return defaultContainerConfig +} diff --git a/cmd/podmanV2/containers/restart.go b/cmd/podmanV2/containers/restart.go index 053891f79..1f1bb11fa 100644 --- a/cmd/podmanV2/containers/restart.go +++ b/cmd/podmanV2/containers/restart.go @@ -46,8 +46,8 @@ func init() { flags.BoolVarP(&restartOptions.All, "all", "a", false, "Restart all non-running containers") flags.BoolVarP(&restartOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") flags.BoolVar(&restartOptions.Running, "running", false, "Restart only running containers when --all is used") - flags.UintVarP(&restartTimeout, "timeout", "t", define.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") - flags.UintVar(&restartTimeout, "time", define.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") + flags.UintVarP(&restartTimeout, "timeout", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container") + flags.UintVar(&restartTimeout, "time", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container") if registry.IsRemote() { _ = flags.MarkHidden("latest") } diff --git a/cmd/podmanV2/containers/stop.go b/cmd/podmanV2/containers/stop.go index 58d47fd52..9a106e8fe 100644 --- a/cmd/podmanV2/containers/stop.go +++ b/cmd/podmanV2/containers/stop.go @@ -7,7 +7,6 @@ import ( "github.com/containers/libpod/cmd/podmanV2/parse" "github.com/containers/libpod/cmd/podmanV2/registry" "github.com/containers/libpod/cmd/podmanV2/utils" - "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/domain/entities" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -47,8 +46,8 @@ func init() { flags.BoolVarP(&stopOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified container is missing") flags.StringArrayVarP(&stopOptions.CIDFiles, "cidfile", "", nil, "Read the container ID from the file") flags.BoolVarP(&stopOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - flags.UintVar(&stopTimeout, "time", define.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") - flags.UintVarP(&stopTimeout, "timeout", "t", define.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") + flags.UintVar(&stopTimeout, "time", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container") + flags.UintVarP(&stopTimeout, "timeout", "t", defaultContainerConfig.Engine.StopTimeout, "Seconds to wait for stop before killing the container") if registry.EngineOptions.EngineMode == entities.ABIMode { _ = flags.MarkHidden("latest") _ = flags.MarkHidden("cidfile") @@ -63,7 +62,7 @@ func stop(cmd *cobra.Command, args []string) error { if cmd.Flag("timeout").Changed && cmd.Flag("time").Changed { return errors.New("the --timeout and --time flags are mutually exclusive") } - stopOptions.Timeout = define.CtrRemoveTimeout + stopOptions.Timeout = defaultContainerConfig.Engine.StopTimeout if cmd.Flag("timeout").Changed || cmd.Flag("time").Changed { stopOptions.Timeout = stopTimeout } diff --git a/cmd/podmanV2/pods/top.go b/cmd/podmanV2/pods/top.go new file mode 100644 index 000000000..5ef282238 --- /dev/null +++ b/cmd/podmanV2/pods/top.go @@ -0,0 +1,90 @@ +package pods + +import ( + "context" + "fmt" + "os" + "strings" + "text/tabwriter" + + "github.com/containers/libpod/cmd/podmanV2/registry" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/containers/psgo" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +var ( + topDescription = fmt.Sprintf(`Specify format descriptors to alter the output. + + You may run "podman pod top -l pid pcpu seccomp" to print the process ID, the CPU percentage and the seccomp mode of each process of the latest pod. + Format Descriptors: + %s`, strings.Join(psgo.ListDescriptors(), ",")) + + topOptions = entities.PodTopOptions{} + + topCommand = &cobra.Command{ + Use: "top [flags] POD [FORMAT-DESCRIPTORS|ARGS]", + Short: "Display the running processes in a pod", + Long: topDescription, + PersistentPreRunE: preRunE, + RunE: top, + Args: cobra.ArbitraryArgs, + Example: `podman pod top podID +podman pod top --latest +podman pod top podID pid seccomp args %C +podman pod top podID -eo user,pid,comm`, + } +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: topCommand, + Parent: podCmd, + }) + + topCommand.SetHelpTemplate(registry.HelpTemplate()) + topCommand.SetUsageTemplate(registry.UsageTemplate()) + + flags := topCommand.Flags() + flags.SetInterspersed(false) + flags.BoolVar(&topOptions.ListDescriptors, "list-descriptors", false, "") + flags.BoolVarP(&topOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") + + _ = flags.MarkHidden("list-descriptors") // meant only for bash completion + if registry.IsRemote() { + _ = flags.MarkHidden("latest") + } +} + +func top(cmd *cobra.Command, args []string) error { + if topOptions.ListDescriptors { + fmt.Println(strings.Join(psgo.ListDescriptors(), "\n")) + return nil + } + + if len(args) < 1 && !topOptions.Latest { + return errors.Errorf("you must provide the name or id of a running pod") + } + + if topOptions.Latest { + topOptions.Descriptors = args + } else { + topOptions.NameOrID = args[0] + topOptions.Descriptors = args[1:] + } + + topResponse, err := registry.ContainerEngine().PodTop(context.Background(), topOptions) + if err != nil { + return err + } + + w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0) + for _, proc := range topResponse.Value { + if _, err := fmt.Fprintln(w, proc); err != nil { + return err + } + } + return w.Flush() +} |