diff options
Diffstat (limited to 'cmd/podman')
-rw-r--r-- | cmd/podman/build.go | 3 | ||||
-rw-r--r-- | cmd/podman/common.go | 20 | ||||
-rw-r--r-- | cmd/podman/cp.go | 4 | ||||
-rw-r--r-- | cmd/podman/create.go | 5 | ||||
-rw-r--r-- | cmd/podman/images.go | 2 | ||||
-rw-r--r-- | cmd/podman/libpodruntime/runtime.go | 4 | ||||
-rw-r--r-- | cmd/podman/load.go | 7 | ||||
-rw-r--r-- | cmd/podman/login.go | 41 | ||||
-rw-r--r-- | cmd/podman/logout.go | 14 | ||||
-rw-r--r-- | cmd/podman/main_local.go | 38 | ||||
-rw-r--r-- | cmd/podman/mount.go | 2 | ||||
-rw-r--r-- | cmd/podman/play_kube.go | 24 | ||||
-rw-r--r-- | cmd/podman/pull.go | 21 | ||||
-rw-r--r-- | cmd/podman/push.go | 18 | ||||
-rw-r--r-- | cmd/podman/run.go | 2 | ||||
-rw-r--r-- | cmd/podman/runlabel.go | 18 | ||||
-rw-r--r-- | cmd/podman/search.go | 9 | ||||
-rw-r--r-- | cmd/podman/shared/create.go | 7 | ||||
-rw-r--r-- | cmd/podman/unshare.go | 49 | ||||
-rw-r--r-- | cmd/podman/varlink/io.podman.varlink | 14 |
20 files changed, 203 insertions, 99 deletions
diff --git a/cmd/podman/build.go b/cmd/podman/build.go index 24be9bb46..6e70c6540 100644 --- a/cmd/podman/build.go +++ b/cmd/podman/build.go @@ -43,7 +43,7 @@ var ( return buildCmd(&buildCommand) }, Example: `podman build . - podman build --cert-dir ~/auth --creds=username:password -t imageName -f Dockerfile.simple . + podman build --creds=username:password -t imageName -f Dockerfile.simple . podman build --layers --force-rm --tag imageName .`, } ) @@ -72,6 +72,7 @@ func init() { flags.AddFlagSet(&budFlags) flags.AddFlagSet(&layerFlags) flags.AddFlagSet(&fromAndBugFlags) + flags.MarkHidden("signature-policy") } func getDockerfiles(files []string) []string { diff --git a/cmd/podman/common.go b/cmd/podman/common.go index c0bcaa5c5..054b01247 100644 --- a/cmd/podman/common.go +++ b/cmd/podman/common.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "os" + "path/filepath" "strings" "github.com/containers/buildah" @@ -163,6 +164,10 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { "Attach to STDIN, STDOUT or STDERR (default [])", ) createFlags.String( + "authfile", getAuthFile(""), + "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override", + ) + createFlags.String( "blkio-weight", "", "Block IO weight (relative weight) accepts a weight value between 10 and 1000.", ) @@ -512,7 +517,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { "Username or UID (format: <name|uid>[:<group|gid>])", ) createFlags.String( - "userns", "", + "userns", os.Getenv("PODMAN_USERNS"), "User namespace to use", ) createFlags.String( @@ -553,7 +558,18 @@ func getAuthFile(authfile string) string { if authfile != "" { return authfile } - return os.Getenv("REGISTRY_AUTH_FILE") + if remote { + return "" + } + authfile = os.Getenv("REGISTRY_AUTH_FILE") + if authfile != "" { + return authfile + } + runtimeDir := os.Getenv("XDG_RUNTIME_DIR") + if runtimeDir != "" { + return filepath.Join(runtimeDir, "containers/auth.json") + } + return "" } // scrubServer removes 'http://' or 'https://' from the front of the diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go index 4cb8a8c54..8240cc193 100644 --- a/cmd/podman/cp.go +++ b/cmd/podman/cp.go @@ -272,6 +272,10 @@ func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, ch } return nil } + + if destDirIsExist || strings.HasSuffix(dest, string(os.PathSeparator)) { + destPath = filepath.Join(destPath, filepath.Base(srcPath)) + } // Copy the file, preserving attributes. logrus.Debugf("copying %q to %q", srcPath, destPath) if err = copyFileWithTar(srcPath, destPath); err != nil { diff --git a/cmd/podman/create.go b/cmd/podman/create.go index cb3ba14c5..2351f5860 100644 --- a/cmd/podman/create.go +++ b/cmd/podman/create.go @@ -7,6 +7,7 @@ import ( "github.com/containers/libpod/pkg/adapter" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -72,6 +73,10 @@ func createInit(c *cliconfig.PodmanCommand) error { defer span.Finish() } + if c.IsSet("privileged") && c.IsSet("security-opt") { + logrus.Warn("setting security options with --privileged has no effect") + } + // Docker-compatibility: the "-h" flag for run/create is reserved for // the hostname (see https://github.com/containers/libpod/issues/1367). diff --git a/cmd/podman/images.go b/cmd/podman/images.go index 1c46571c3..3f755efc1 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -362,7 +362,7 @@ func CreateFilterFuncs(ctx context.Context, r *adapter.LocalRuntime, filters []s var filterFuncs []imagefilters.ResultFilter for _, filter := range filters { splitFilter := strings.Split(filter, "=") - if len(splitFilter) != 2 { + if len(splitFilter) < 2 { return nil, errors.Errorf("invalid filter syntax %s", filter) } switch splitFilter[0] { diff --git a/cmd/podman/libpodruntime/runtime.go b/cmd/podman/libpodruntime/runtime.go index b8d77602d..898c81515 100644 --- a/cmd/podman/libpodruntime/runtime.go +++ b/cmd/podman/libpodruntime/runtime.go @@ -5,6 +5,7 @@ import ( "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/namespaces" "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/util" "github.com/containers/storage" @@ -37,11 +38,12 @@ func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber bool, subgidname := c.Flags().Lookup("subgidname") if (uidmapFlag != nil && gidmapFlag != nil && subuidname != nil && subgidname != nil) && (uidmapFlag.Changed || gidmapFlag.Changed || subuidname.Changed || subgidname.Changed) { + userns, _ := c.Flags().GetString("userns") uidmapVal, _ := c.Flags().GetStringSlice("uidmap") gidmapVal, _ := c.Flags().GetStringSlice("gidmap") subuidVal, _ := c.Flags().GetString("subuidname") subgidVal, _ := c.Flags().GetString("subgidname") - mappings, err := util.ParseIDMapping(uidmapVal, gidmapVal, subuidVal, subgidVal) + mappings, err := util.ParseIDMapping(namespaces.UsernsMode(userns), uidmapVal, gidmapVal, subuidVal, subgidVal) if err != nil { return nil, err } diff --git a/cmd/podman/load.go b/cmd/podman/load.go index f3bbed48f..0c41eb792 100644 --- a/cmd/podman/load.go +++ b/cmd/podman/load.go @@ -40,8 +40,11 @@ func init() { flags := loadCommand.Flags() flags.StringVarP(&loadCommand.Input, "input", "i", "", "Read from specified archive file (default: stdin)") flags.BoolVarP(&loadCommand.Quiet, "quiet", "q", false, "Suppress the output") - flags.StringVar(&loadCommand.SignaturePolicy, "signature-policy", "", "Pathname of signature policy file (not usually used)") - + // Disabled flags for the remote client + if !remote { + flags.StringVar(&loadCommand.SignaturePolicy, "signature-policy", "", "Pathname of signature policy file (not usually used)") + flags.MarkHidden("signature-policy") + } } // loadCmd gets the image/file to be loaded from the command line diff --git a/cmd/podman/login.go b/cmd/podman/login.go index 6bf148cca..3a78adadc 100644 --- a/cmd/podman/login.go +++ b/cmd/podman/login.go @@ -32,25 +32,30 @@ var ( return loginCmd(&loginCommand) }, Example: `podman login -u testuser -p testpassword localhost:5000 - podman login --authfile authdir/myauths.json quay.io podman login -u testuser -p testpassword localhost:5000`, } ) func init() { + if !remote { + _loginCommand.Example = fmt.Sprintf("%s\n podman login --authfile authdir/myauths.json quay.io", _loginCommand.Example) + + } loginCommand.Command = _loginCommand loginCommand.SetHelpTemplate(HelpTemplate()) loginCommand.SetUsageTemplate(UsageTemplate()) flags := loginCommand.Flags() - flags.StringVar(&loginCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override") - flags.StringVar(&loginCommand.CertDir, "cert-dir", "", "Pathname of a directory containing TLS certificates and keys used to connect to the registry") flags.BoolVar(&loginCommand.GetLogin, "get-login", true, "Return the current login user for the registry") flags.StringVarP(&loginCommand.Password, "password", "p", "", "Password for registry") - flags.BoolVar(&loginCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") flags.StringVarP(&loginCommand.Username, "username", "u", "", "Username for registry") flags.BoolVar(&loginCommand.StdinPassword, "password-stdin", false, "Take the password from stdin") - + // Disabled flags for the remote client + if !remote { + flags.StringVar(&loginCommand.Authfile, "authfile", getAuthFile(""), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") + flags.StringVar(&loginCommand.CertDir, "cert-dir", "", "Pathname of a directory containing TLS certificates and keys used to connect to the registry") + flags.BoolVar(&loginCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") + } } // loginCmd uses the authentication package to store a user's authenticated credentials @@ -64,9 +69,8 @@ func loginCmd(c *cliconfig.LoginValues) error { return errors.Errorf("please specify a registry to login to") } server := registryFromFullName(scrubServer(args[0])) - authfile := getAuthFile(c.Authfile) - sc := image.GetSystemContext("", authfile, false) + sc := image.GetSystemContext("", c.Authfile, false) if c.Flag("tls-verify").Changed { sc.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!c.TlsVerify) } @@ -74,21 +78,6 @@ func loginCmd(c *cliconfig.LoginValues) error { sc.DockerCertPath = c.CertDir } - if c.Flag("get-login").Changed { - user, err := config.GetUserLoggedIn(sc, server) - - if err != nil { - return errors.Wrapf(err, "unable to check for login user") - } - - if user == "" { - return errors.Errorf("not logged into %s", server) - } - - fmt.Printf("%s\n", user) - return nil - } - // username of user logged in to server (if one exists) userFromAuthFile, passFromAuthFile, err := config.GetAuthentication(sc, server) // Do not return error if no credentials found in credHelpers, new credentials will be stored by config.SetAuthentication @@ -96,6 +85,14 @@ func loginCmd(c *cliconfig.LoginValues) error { return errors.Wrapf(err, "error reading auth file") } + if c.Flag("get-login").Changed { + if userFromAuthFile == "" { + return errors.Errorf("not logged into %s", server) + } + fmt.Printf("%s\n", userFromAuthFile) + return nil + } + ctx := getContext() password := c.Password diff --git a/cmd/podman/logout.go b/cmd/podman/logout.go index ec581a098..5df838bba 100644 --- a/cmd/podman/logout.go +++ b/cmd/podman/logout.go @@ -24,20 +24,23 @@ var ( logoutCommand.Remote = remoteclient return logoutCmd(&logoutCommand) }, - Example: `podman logout docker.io - podman logout --authfile authdir/myauths.json docker.io + Example: `podman logout quay.io podman logout --all`, } ) func init() { + if !remote { + _logoutCommand.Example = fmt.Sprintf("%s\n podman logout --authfile authdir/myauths.json quay.io", _logoutCommand.Example) + + } logoutCommand.Command = _logoutCommand logoutCommand.SetHelpTemplate(HelpTemplate()) logoutCommand.SetUsageTemplate(UsageTemplate()) flags := logoutCommand.Flags() flags.BoolVarP(&logoutCommand.All, "all", "a", false, "Remove the cached credentials for all registries in the auth file") - flags.StringVar(&logoutCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override") - + flags.StringVar(&logoutCommand.Authfile, "authfile", getAuthFile(""), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") + markFlagHiddenForRemoteClient("authfile", flags) } // logoutCmd uses the authentication package to remove the authenticated of a registry @@ -54,9 +57,8 @@ func logoutCmd(c *cliconfig.LogoutValues) error { if len(args) == 1 { server = scrubServer(args[0]) } - authfile := getAuthFile(c.Authfile) - sc := image.GetSystemContext("", authfile, false) + sc := image.GetSystemContext("", c.Authfile, false) if c.All { if err := config.RemoveAllAuthentication(sc); err != nil { diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go index 7452965a2..5af05a11e 100644 --- a/cmd/podman/main_local.go +++ b/cmd/podman/main_local.go @@ -16,6 +16,7 @@ import ( "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/tracing" + "github.com/containers/libpod/pkg/util" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -113,6 +114,35 @@ func setupRootless(cmd *cobra.Command, args []string) error { MainGlobalOpts, remoteclient, } + + pausePidPath, err := util.GetRootlessPauseProcessPidPath() + if err != nil { + return errors.Wrapf(err, "could not get pause process pid file path") + } + + data, err := ioutil.ReadFile(pausePidPath) + if err != nil && !os.IsNotExist(err) { + return errors.Wrapf(err, "cannot read pause process pid file %s", pausePidPath) + } + if err == nil { + pausePid, err := strconv.Atoi(string(data)) + if err != nil { + return errors.Wrapf(err, "cannot parse pause pid file %s", pausePidPath) + } + became, ret, err := rootless.JoinUserAndMountNS(uint(pausePid), "") + if err != nil { + logrus.Errorf("cannot join pause process pid %d. You may need to remove %s and stop all containers", pausePid, pausePidPath) + logrus.Errorf("you can use `system migrate` to recreate the pause process") + logrus.Errorf(err.Error()) + os.Exit(1) + } + if became { + os.Exit(ret) + } + } + + // if there is no pid file, try to join existing containers, and create a pause process. + runtime, err := libpodruntime.GetRuntime(getContext(), &podmanCmd) if err != nil { return errors.Wrapf(err, "could not get runtime") @@ -127,20 +157,20 @@ func setupRootless(cmd *cobra.Command, args []string) error { var became bool var ret int if len(ctrs) == 0 { - became, ret, err = rootless.BecomeRootInUserNS() + became, ret, err = rootless.BecomeRootInUserNS(pausePidPath) } else { for _, ctr := range ctrs { data, err := ioutil.ReadFile(ctr.Config().ConmonPidFile) if err != nil { logrus.Errorf(err.Error()) - os.Exit(1) + continue } conmonPid, err := strconv.Atoi(string(data)) if err != nil { logrus.Errorf(err.Error()) - os.Exit(1) + continue } - became, ret, err = rootless.JoinUserAndMountNS(uint(conmonPid)) + became, ret, err = rootless.JoinUserAndMountNS(uint(conmonPid), pausePidPath) if err == nil { break } diff --git a/cmd/podman/mount.go b/cmd/podman/mount.go index 7c9150d1b..662fb0a28 100644 --- a/cmd/podman/mount.go +++ b/cmd/podman/mount.go @@ -78,7 +78,7 @@ func mountCmd(c *cliconfig.MountValues) error { return fmt.Errorf("cannot mount using driver %s in rootless mode", driver) } - became, ret, err := rootless.BecomeRootInUserNS() + became, ret, err := rootless.BecomeRootInUserNS("") if err != nil { return err } diff --git a/cmd/podman/play_kube.go b/cmd/podman/play_kube.go index e778bafb9..b0f4a44eb 100644 --- a/cmd/podman/play_kube.go +++ b/cmd/podman/play_kube.go @@ -47,22 +47,28 @@ var ( playKubeCommand.Remote = remoteclient return playKubeCmd(&playKubeCommand) }, - Example: `podman play kube demo.yml - podman play kube --cert-dir /mycertsdir --tls-verify=true --quiet myWebPod`, + Example: `podman play kube demo.yml`, } ) func init() { + if !remote { + _playKubeCommand.Example = fmt.Sprintf("%s\n podman play kube --cert-dir /mycertsdir --tls-verify=true --quiet myWebPod", _playKubeCommand.Example) + } playKubeCommand.Command = _playKubeCommand playKubeCommand.SetHelpTemplate(HelpTemplate()) playKubeCommand.SetUsageTemplate(UsageTemplate()) flags := playKubeCommand.Flags() - flags.StringVar(&playKubeCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override") - flags.StringVar(&playKubeCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") flags.StringVar(&playKubeCommand.Creds, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry") flags.BoolVarP(&playKubeCommand.Quiet, "quiet", "q", false, "Suppress output information when pulling images") - flags.StringVar(&playKubeCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") - flags.BoolVar(&playKubeCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") + // Disabled flags for the remote client + if !remote { + flags.StringVar(&playKubeCommand.Authfile, "authfile", getAuthFile(""), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") + flags.StringVar(&playKubeCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") + flags.StringVar(&playKubeCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") + flags.BoolVar(&playKubeCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") + flags.MarkHidden("signature-policy") + } } func playKubeCmd(c *cliconfig.KubePlayValues) error { @@ -217,7 +223,7 @@ func playKubeYAMLCmd(c *cliconfig.KubePlayValues, ctx context.Context, runtime * if err != nil { return pod, err } - createConfig, err := kubeContainerToCreateConfig(ctx, container, runtime, newImage, namespaces, volumes) + createConfig, err := kubeContainerToCreateConfig(ctx, container, runtime, newImage, namespaces, volumes, pod.ID()) if err != nil { return pod, err } @@ -274,7 +280,7 @@ func getPodPorts(containers []v1.Container) []ocicni.PortMapping { } // kubeContainerToCreateConfig takes a v1.Container and returns a createconfig describing a container -func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container, runtime *libpod.Runtime, newImage *image.Image, namespaces map[string]string, volumes map[string]string) (*createconfig.CreateConfig, error) { +func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container, runtime *libpod.Runtime, newImage *image.Image, namespaces map[string]string, volumes map[string]string, podID string) (*createconfig.CreateConfig, error) { var ( containerConfig createconfig.CreateConfig ) @@ -288,6 +294,8 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container containerConfig.Tty = containerYAML.TTY containerConfig.WorkDir = containerYAML.WorkingDir + containerConfig.Pod = podID + imageData, _ := newImage.Inspect(ctx) containerConfig.User = "0" diff --git a/cmd/podman/pull.go b/cmd/podman/pull.go index f6a5beb17..115f437d8 100644 --- a/cmd/podman/pull.go +++ b/cmd/podman/pull.go @@ -36,28 +36,31 @@ var ( return pullCmd(&pullCommand) }, Example: `podman pull imageName - podman pull --cert-dir image/certs --authfile temp-auths/myauths.json docker://docker.io/myrepo/finaltest podman pull fedora:latest`, } ) func init() { + + if !remote { + _pullCommand.Example = fmt.Sprintf("%s\n podman pull --cert-dir image/certs --authfile temp-auths/myauths.json docker://docker.io/myrepo/finaltest", _pullCommand.Example) + + } pullCommand.Command = _pullCommand pullCommand.SetHelpTemplate(HelpTemplate()) pullCommand.SetUsageTemplate(UsageTemplate()) flags := pullCommand.Flags() flags.BoolVar(&pullCommand.AllTags, "all-tags", false, "All tagged images in the repository will be pulled") - flags.StringVar(&pullCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") flags.StringVar(&pullCommand.Creds, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry") flags.BoolVarP(&pullCommand.Quiet, "quiet", "q", false, "Suppress output information when pulling images") - // Disabled flags for the remote client if !remote { - flags.StringVar(&pullCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override") + flags.StringVar(&pullCommand.Authfile, "authfile", getAuthFile(""), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") + flags.StringVar(&pullCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") flags.StringVar(&pullCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") flags.BoolVar(&pullCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") + flags.MarkHidden("signature-policy") } - } // pullCmd gets the data from the command line and calls pullImage @@ -138,8 +141,6 @@ func pullCmd(c *cliconfig.PullValues) (retError error) { return nil } - authfile := getAuthFile(c.String("authfile")) - // FIXME: the default pull consults the registries.conf's search registries // while the all-tags pull does not. This behavior must be fixed in the // future and span across c/buildah, c/image and c/libpod to avoid redundant @@ -148,7 +149,7 @@ func pullCmd(c *cliconfig.PullValues) (retError error) { // See https://bugzilla.redhat.com/show_bug.cgi?id=1701922 for background // information. if !c.Bool("all-tags") { - newImage, err := runtime.New(getContext(), imgArg, c.SignaturePolicy, authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, true, nil) + newImage, err := runtime.New(getContext(), imgArg, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, true, nil) if err != nil { return errors.Wrapf(err, "error pulling image %q", imgArg) } @@ -158,7 +159,7 @@ func pullCmd(c *cliconfig.PullValues) (retError error) { // FIXME: all-tags should use the libpod backend instead of baking its own bread. spec := imgArg - systemContext := image.GetSystemContext("", authfile, false) + systemContext := image.GetSystemContext("", c.Authfile, false) srcRef, err := alltransports.ParseImageName(spec) if err != nil { dockerTransport := "docker://" @@ -186,7 +187,7 @@ func pullCmd(c *cliconfig.PullValues) (retError error) { var foundIDs []string foundImage := true for _, name := range names { - newImage, err := runtime.New(getContext(), name, c.String("signature-policy"), authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, true, nil) + newImage, err := runtime.New(getContext(), name, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, true, nil) if err != nil { logrus.Errorf("error pulling image %q", name) foundImage = false diff --git a/cmd/podman/push.go b/cmd/podman/push.go index ee14b15e2..497820156 100644 --- a/cmd/podman/push.go +++ b/cmd/podman/push.go @@ -35,18 +35,20 @@ var ( return pushCmd(&pushCommand) }, Example: `podman push imageID docker://registry.example.com/repository:tag - podman push imageID oci-archive:/path/to/layout:image:tag - podman push --authfile temp-auths/myauths.json alpine docker://docker.io/myrepo/alpine`, + podman push imageID oci-archive:/path/to/layout:image:tag`, } ) func init() { + if !remote { + _pushCommand.Example = fmt.Sprintf("%s\n podman push --authfile temp-auths/myauths.json alpine docker://docker.io/myrepo/alpine", _pushCommand.Example) + + } + pushCommand.Command = _pushCommand pushCommand.SetHelpTemplate(HelpTemplate()) pushCommand.SetUsageTemplate(UsageTemplate()) flags := pushCommand.Flags() - flags.MarkHidden("signature-policy") - flags.StringVar(&pushCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") flags.StringVar(&pushCommand.Creds, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry") flags.StringVarP(&pushCommand.Format, "format", "f", "", "Manifest type (oci, v2s1, or v2s2) to use when pushing an image using the 'dir:' transport (default is manifest type of source)") flags.BoolVarP(&pushCommand.Quiet, "quiet", "q", false, "Don't output progress information when pushing images") @@ -55,10 +57,12 @@ func init() { // Disabled flags for the remote client if !remote { - flags.StringVar(&pushCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override") + flags.StringVar(&pushCommand.Authfile, "authfile", getAuthFile(""), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") + flags.StringVar(&pushCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") flags.BoolVar(&pushCommand.Compress, "compress", false, "Compress tarball image layers when pushing to a directory using the 'dir' transport. (default is same compression type as source)") flags.StringVar(&pushCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") flags.BoolVar(&pushCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") + flags.MarkHidden("signature-policy") } } @@ -138,7 +142,5 @@ func pushCmd(c *cliconfig.PushValues) error { SignBy: signBy, } - authfile := getAuthFile(c.Authfile) - - return runtime.Push(getContext(), srcName, destName, manifestType, authfile, c.SignaturePolicy, writer, c.Compress, so, &dockerRegistryOptions, nil) + return runtime.Push(getContext(), srcName, destName, manifestType, c.Authfile, c.SignaturePolicy, writer, c.Compress, so, &dockerRegistryOptions, nil) } diff --git a/cmd/podman/run.go b/cmd/podman/run.go index 01b12d282..7d84d716b 100644 --- a/cmd/podman/run.go +++ b/cmd/podman/run.go @@ -36,6 +36,8 @@ func init() { flags.SetInterspersed(false) flags.Bool("sig-proxy", true, "Proxy received signals to the process") getCreateFlags(&runCommand.PodmanCommand) + markFlagHiddenForRemoteClient("authfile", flags) + flags.MarkHidden("signature-policy") } func runCmd(c *cliconfig.RunValues) error { diff --git a/cmd/podman/runlabel.go b/cmd/podman/runlabel.go index e87b88992..59cbc7aa4 100644 --- a/cmd/podman/runlabel.go +++ b/cmd/podman/runlabel.go @@ -45,8 +45,6 @@ func init() { runlabelCommand.SetHelpTemplate(HelpTemplate()) runlabelCommand.SetUsageTemplate(UsageTemplate()) flags := runlabelCommand.Flags() - flags.StringVar(&runlabelCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override") - flags.StringVar(&runlabelCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") flags.StringVar(&runlabelCommand.Creds, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry") flags.BoolVar(&runlabelCommand.Display, "display", false, "Preview the command that the label would run") flags.BoolVar(&runlabelCommand.Replace, "replace", false, "Replace existing container with a new one from the image") @@ -61,10 +59,17 @@ func init() { flags.BoolP("pull", "p", false, "Pull the image if it does not exist locally prior to executing the label contents") flags.BoolVarP(&runlabelCommand.Quiet, "quiet", "q", false, "Suppress output information when installing images") - flags.StringVar(&runlabelCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") - flags.BoolVar(&runlabelCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") + // Disabled flags for the remote client + if !remote { + flags.StringVar(&runlabelCommand.Authfile, "authfile", getAuthFile(""), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") + flags.StringVar(&runlabelCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") + flags.StringVar(&runlabelCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") + flags.BoolVar(&runlabelCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") - flags.MarkDeprecated("pull", "podman will pull if not found in local storage") + flags.MarkDeprecated("pull", "podman will pull if not found in local storage") + flags.MarkHidden("signature-policy") + } + markFlagHiddenForRemoteClient("authfile", flags) } // installCmd gets the data from the command line and calls installImage @@ -137,8 +142,7 @@ func runlabelCmd(c *cliconfig.RunlabelValues) error { dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!c.TlsVerify) } - authfile := getAuthFile(c.Authfile) - runLabel, imageName, err := shared.GetRunlabel(label, runlabelImage, ctx, runtime, true, c.Creds, dockerRegistryOptions, authfile, c.SignaturePolicy, stdOut) + runLabel, imageName, err := shared.GetRunlabel(label, runlabelImage, ctx, runtime, true, c.Creds, dockerRegistryOptions, c.Authfile, c.SignaturePolicy, stdOut) if err != nil { return err } diff --git a/cmd/podman/search.go b/cmd/podman/search.go index b236f3055..ba04002f6 100644 --- a/cmd/podman/search.go +++ b/cmd/podman/search.go @@ -43,12 +43,15 @@ func init() { searchCommand.SetHelpTemplate(HelpTemplate()) searchCommand.SetUsageTemplate(UsageTemplate()) flags := searchCommand.Flags() - flags.StringVar(&searchCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override") flags.StringSliceVarP(&searchCommand.Filter, "filter", "f", []string{}, "Filter output based on conditions provided (default [])") flags.StringVar(&searchCommand.Format, "format", "", "Change the output format to a Go template") flags.IntVar(&searchCommand.Limit, "limit", 0, "Limit the number of results") flags.BoolVar(&searchCommand.NoTrunc, "no-trunc", false, "Do not truncate the output") - flags.BoolVar(&searchCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") + // Disabled flags for the remote client + if !remote { + flags.StringVar(&searchCommand.Authfile, "authfile", getAuthFile(""), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") + flags.BoolVar(&searchCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") + } } func searchCmd(c *cliconfig.SearchValues) error { @@ -70,7 +73,7 @@ func searchCmd(c *cliconfig.SearchValues) error { NoTrunc: c.NoTrunc, Limit: c.Limit, Filter: *filter, - Authfile: getAuthFile(c.Authfile), + Authfile: c.Authfile, } if c.Flag("tls-verify").Changed { searchOptions.InsecureSkipTLSVerify = types.NewOptionalBool(!c.TlsVerify) diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go index d1f704374..3c9b17804 100644 --- a/cmd/podman/shared/create.go +++ b/cmd/podman/shared/create.go @@ -19,6 +19,7 @@ import ( ann "github.com/containers/libpod/pkg/annotations" "github.com/containers/libpod/pkg/inspect" ns "github.com/containers/libpod/pkg/namespaces" + "github.com/containers/libpod/pkg/rootless" cc "github.com/containers/libpod/pkg/spec" "github.com/containers/libpod/pkg/util" "github.com/docker/docker/pkg/signal" @@ -283,7 +284,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. namespaces map[string]string ) - idmappings, err := util.ParseIDMapping(c.StringSlice("uidmap"), c.StringSlice("gidmap"), c.String("subuidname"), c.String("subgidname")) + idmappings, err := util.ParseIDMapping(ns.UsernsMode(c.String("userns")), c.StringSlice("uidmap"), c.StringSlice("gidmap"), c.String("subuidname"), c.String("subgidname")) if err != nil { return nil, err } @@ -451,7 +452,9 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. // USER user := c.String("user") if user == "" { - if data == nil { + if usernsMode.IsKeepID() { + user = fmt.Sprintf("%d:%d", rootless.GetRootlessUID(), rootless.GetRootlessGID()) + } else if data == nil { user = "0" } else { user = data.Config.User diff --git a/cmd/podman/unshare.go b/cmd/podman/unshare.go index 1db647dba..4a4e371db 100644 --- a/cmd/podman/unshare.go +++ b/cmd/podman/unshare.go @@ -3,10 +3,14 @@ package main import ( + "fmt" "os" "os/exec" - "github.com/containers/buildah/pkg/unshare" + "github.com/containers/libpod/cmd/podman/cliconfig" + "github.com/containers/libpod/cmd/podman/libpodruntime" + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/rootless" "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -17,38 +21,61 @@ var ( Use: "unshare [flags] [COMMAND [ARG]]", Short: "Run a command in a modified user namespace", Long: unshareDescription, - RunE: unshareCmd, + RunE: func(cmd *cobra.Command, args []string) error { + unshareCommand.InputArgs = args + unshareCommand.GlobalFlags = MainGlobalOpts + return unshareCmd(&unshareCommand) + }, Example: `podman unshare id podman unshare cat /proc/self/uid_map, podman unshare podman-script.sh`, } + unshareCommand cliconfig.PodmanCommand ) func init() { - _unshareCommand.SetUsageTemplate(UsageTemplate()) + unshareCommand.Command = _unshareCommand + unshareCommand.SetHelpTemplate(HelpTemplate()) + unshareCommand.SetUsageTemplate(UsageTemplate()) flags := _unshareCommand.Flags() flags.SetInterspersed(false) } +func unshareEnv(config *libpod.RuntimeConfig) []string { + return append(os.Environ(), "_CONTAINERS_USERNS_CONFIGURED=done", + fmt.Sprintf("CONTAINERS_GRAPHROOT=%s", config.StorageConfig.GraphRoot), + fmt.Sprintf("CONTAINERS_RUNROOT=%s", config.StorageConfig.RunRoot)) +} + // unshareCmd execs whatever using the ID mappings that we want to use for ourselves -func unshareCmd(c *cobra.Command, args []string) error { - if isRootless := unshare.IsRootless(); !isRootless { +func unshareCmd(c *cliconfig.PodmanCommand) error { + + if isRootless := rootless.IsRootless(); !isRootless { return errors.Errorf("please use unshare with rootless") } // exec the specified command, if there is one - if len(args) < 1 { + if len(c.InputArgs) < 1 { // try to exec the shell, if one's set shell, shellSet := os.LookupEnv("SHELL") if !shellSet { return errors.Errorf("no command specified and no $SHELL specified") } - args = []string{shell} + c.InputArgs = []string{shell} } - cmd := exec.Command(args[0], args[1:]...) - cmd.Env = unshare.RootlessEnv() + + runtime, err := libpodruntime.GetRuntime(getContext(), c) + 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) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr - unshare.ExecRunnable(cmd) - return nil + return cmd.Run() } diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index faaecdb6b..ed7b49c68 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -414,7 +414,6 @@ type BuildInfo ( remoteIntermediateCtrs: bool, reportWriter: string, runtimeArgs: []string, - signaturePolicyPath: string, squash: bool ) @@ -467,13 +466,9 @@ type PodContainerErrorData ( type Runlabel( image: string, authfile: string, - certDir: string, - creds: string, display: bool, name: string, pull: bool, - signaturePolicyPath: string, - tlsVerify: ?bool, label: string, extraArgs: []string, opts: [string]string @@ -759,11 +754,10 @@ method InspectImage(name: string) -> (image: string) # [ImageNotFound](#ImageNotFound) error is returned. method HistoryImage(name: string) -> (history: []ImageHistory) -# PushImage takes three input arguments: the name or ID of an image, the fully-qualified destination name of the image, -# and a boolean as to whether tls-verify should be used (with false disabling TLS, not affecting the default behavior). +# PushImage takes two input arguments: the name or ID of an image, the fully-qualified destination name of the image, # It will return an [ImageNotFound](#ImageNotFound) error if # the image cannot be found in local storage; otherwise it will return a [MoreResponse](#MoreResponse) -method PushImage(name: string, tag: string, tlsverify: ?bool, signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) -> (reply: MoreResponse) +method PushImage(name: string, tag: string, compress: bool, format: string, removeSignatures: bool, signBy: string) -> (reply: MoreResponse) # TagImage takes the name or ID of an image in local storage as well as the desired tag name. If the image cannot # be found, an [ImageNotFound](#ImageNotFound) error will be returned; otherwise, the ID of the image is returned on success. @@ -784,7 +778,7 @@ method RemoveImage(name: string, force: bool) -> (image: string) # SearchImages searches available registries for images that contain the # contents of "query" in their name. If "limit" is given, limits the amount of # search results per registry. -method SearchImages(query: string, limit: ?int, tlsVerify: ?bool, filter: ImageSearchFilter) -> (results: []ImageSearchResult) +method SearchImages(query: string, limit: ?int, filter: ImageSearchFilter) -> (results: []ImageSearchResult) # DeleteUnusedImages deletes any images not associated with a container. The IDs of the deleted images are returned # in a string array. @@ -825,7 +819,7 @@ method ExportImage(name: string, destination: string, compress: bool, tags: []st # PullImage pulls an image from a repository to local storage. After a successful pull, the image id and logs # are returned as a [MoreResponse](#MoreResponse). This connection also will handle a WantsMores request to send # status as it occurs. -method PullImage(name: string, certDir: string, creds: string, signaturePolicy: string, tlsVerify: ?bool) -> (reply: MoreResponse) +method PullImage(name: string) -> (reply: MoreResponse) # CreatePod creates a new empty pod. It uses a [PodCreate](#PodCreate) type for input. # On success, the ID of the newly created pod will be returned. |