diff options
Diffstat (limited to 'cmd/podman')
-rw-r--r-- | cmd/podman/cliconfig/create.go | 1 | ||||
-rw-r--r-- | cmd/podman/container.go | 1 | ||||
-rw-r--r-- | cmd/podman/cp.go | 71 | ||||
-rw-r--r-- | cmd/podman/main_local.go | 44 | ||||
-rw-r--r-- | cmd/podman/shared/container.go | 5 | ||||
-rw-r--r-- | cmd/podman/shared/create.go | 7 |
6 files changed, 85 insertions, 44 deletions
diff --git a/cmd/podman/cliconfig/create.go b/cmd/podman/cliconfig/create.go index 49ab3d827..5fb2eed10 100644 --- a/cmd/podman/cliconfig/create.go +++ b/cmd/podman/cliconfig/create.go @@ -24,4 +24,5 @@ type BuildValues struct { type CpValues struct { PodmanCommand Extract bool + Pause bool } diff --git a/cmd/podman/container.go b/cmd/podman/container.go index 530175a55..839ae3a0e 100644 --- a/cmd/podman/container.go +++ b/cmd/podman/container.go @@ -54,6 +54,7 @@ var ( _checkpointCommand, _containerExistsCommand, _contInspectSubCommand, + _cpCommand, _diffCommand, _exportCommand, _createCommand, diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go index 8240cc193..907bde4b9 100644 --- a/cmd/podman/cp.go +++ b/cmd/podman/cp.go @@ -13,10 +13,12 @@ import ( "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/containers/storage" "github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/chrootarchive" "github.com/containers/storage/pkg/idtools" + securejoin "github.com/cyphar/filepath-securejoin" digest "github.com/opencontainers/go-digest" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" @@ -49,6 +51,7 @@ func init() { cpCommand.Command = _cpCommand flags := cpCommand.Flags() flags.BoolVar(&cpCommand.Extract, "extract", false, "Extract the tar file into the destination directory.") + flags.BoolVar(&cpCommand.Pause, "pause", true, "Pause the container while copying") cpCommand.SetHelpTemplate(HelpTemplate()) cpCommand.SetUsageTemplate(UsageTemplate()) rootCmd.AddCommand(cpCommand.Command) @@ -66,11 +69,10 @@ func cpCmd(c *cliconfig.CpValues) error { } defer runtime.Shutdown(false) - extract := c.Flag("extract").Changed - return copyBetweenHostAndContainer(runtime, args[0], args[1], extract) + return copyBetweenHostAndContainer(runtime, args[0], args[1], c.Extract, c.Pause) } -func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest string, extract bool) error { +func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest string, extract bool, pause bool) error { srcCtr, srcPath := parsePath(runtime, src) destCtr, destPath := parsePath(runtime, dest) @@ -93,6 +95,38 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin return err } defer ctr.Unmount(false) + + // We can't pause rootless containers. + if pause && rootless.IsRootless() { + state, err := ctr.State() + if err != nil { + return err + } + if state == libpod.ContainerStateRunning { + return errors.Errorf("cannot copy into running rootless container with pause set - pass --pause=false to force copying") + } + } + + if pause && !rootless.IsRootless() { + if err := ctr.Pause(); err != nil { + // An invalid state error is fine. + // The container isn't running or is already paused. + // TODO: We can potentially start the container while + // the copy is running, which still allows a race where + // malicious code could mess with the symlink. + if errors.Cause(err) != libpod.ErrCtrStateInvalid { + return err + } + } else if err == nil { + // Only add the defer if we actually paused + defer func() { + if err := ctr.Unpause(); err != nil { + logrus.Errorf("Error unpausing container after copying: %v", err) + } + }() + } + } + user, err := getUser(mountPoint, ctr.User()) if err != nil { return err @@ -112,19 +146,38 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin var glob []string if isFromHostToCtr { if filepath.IsAbs(destPath) { - destPath = filepath.Join(mountPoint, destPath) - + cleanedPath, err := securejoin.SecureJoin(mountPoint, destPath) + if err != nil { + return err + } + destPath = cleanedPath } else { - if err = idtools.MkdirAllAndChownNew(filepath.Join(mountPoint, ctr.WorkingDir()), 0755, hostOwner); err != nil { + ctrWorkDir, err := securejoin.SecureJoin(mountPoint, ctr.WorkingDir()) + if err != nil { + return err + } + if err = idtools.MkdirAllAndChownNew(ctrWorkDir, 0755, hostOwner); err != nil { return errors.Wrapf(err, "error creating directory %q", destPath) } - destPath = filepath.Join(mountPoint, ctr.WorkingDir(), destPath) + cleanedPath, err := securejoin.SecureJoin(mountPoint, filepath.Join(ctr.WorkingDir(), destPath)) + if err != nil { + return err + } + destPath = cleanedPath } } else { if filepath.IsAbs(srcPath) { - srcPath = filepath.Join(mountPoint, srcPath) + cleanedPath, err := securejoin.SecureJoin(mountPoint, srcPath) + if err != nil { + return err + } + srcPath = cleanedPath } else { - srcPath = filepath.Join(mountPoint, ctr.WorkingDir(), srcPath) + cleanedPath, err := securejoin.SecureJoin(mountPoint, filepath.Join(ctr.WorkingDir(), srcPath)) + if err != nil { + return err + } + srcPath = cleanedPath } } glob, err = filepath.Glob(srcPath) diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go index 5af05a11e..b4f21bd0c 100644 --- a/cmd/podman/main_local.go +++ b/cmd/podman/main_local.go @@ -4,11 +4,9 @@ package main import ( "context" - "io/ioutil" "log/syslog" "os" "runtime/pprof" - "strconv" "strings" "syscall" @@ -120,18 +118,10 @@ func setupRootless(cmd *cobra.Command, args []string) error { 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 := os.Stat(pausePidPath); err == nil { + became, ret, err := rootless.TryJoinFromFilePaths("", false, []string{pausePidPath}) 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("cannot join pause process. You may need to remove %s and stop all containers", pausePidPath) logrus.Errorf("you can use `system migrate` to recreate the pause process") logrus.Errorf(err.Error()) os.Exit(1) @@ -154,28 +144,13 @@ func setupRootless(cmd *cobra.Command, args []string) error { logrus.Errorf(err.Error()) os.Exit(1) } - var became bool - var ret int - if len(ctrs) == 0 { - 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()) - continue - } - conmonPid, err := strconv.Atoi(string(data)) - if err != nil { - logrus.Errorf(err.Error()) - continue - } - became, ret, err = rootless.JoinUserAndMountNS(uint(conmonPid), pausePidPath) - if err == nil { - break - } - } + + paths := []string{} + for _, ctr := range ctrs { + paths = append(paths, ctr.Config().ConmonPidFile) } + + became, ret, err := rootless.TryJoinFromFilePaths(pausePidPath, true, paths) if err != nil { logrus.Errorf(err.Error()) os.Exit(1) @@ -185,6 +160,7 @@ func setupRootless(cmd *cobra.Command, args []string) error { } return nil } + func setRLimits() error { rlimits := new(syscall.Rlimit) rlimits.Cur = 1048576 diff --git a/cmd/podman/shared/container.go b/cmd/podman/shared/container.go index fe447d10d..55cc529e0 100644 --- a/cmd/podman/shared/container.go +++ b/cmd/podman/shared/container.go @@ -631,6 +631,10 @@ func GetCtrInspectInfo(config *libpod.ContainerConfig, ctrInspectData *inspect.C memKernel, memReservation, memSwap, memSwappiness, memDisableOOMKiller := getMemoryInfo(spec) pidsLimit := getPidsInfo(spec) cgroup := getCgroup(spec) + logConfig := inspect.LogConfig{ + config.LogDriver, + make(map[string]string), + } data := &inspect.ContainerData{ ctrInspectData, @@ -681,6 +685,7 @@ func GetCtrInspectInfo(config *libpod.ContainerConfig, ctrInspectData *inspect.C Ulimits: createArtifact.Resources.Ulimit, SecurityOpt: createArtifact.SecurityOpts, Tmpfs: createArtifact.Tmpfs, + LogConfig: &logConfig, }, &inspect.CtrConfig{ Hostname: spec.Hostname, diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go index 3c9b17804..7cf230605 100644 --- a/cmd/podman/shared/create.go +++ b/cmd/podman/shared/create.go @@ -603,6 +603,11 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. memorySwappiness := c.Int64("memory-swappiness") + logDriver := libpod.KubernetesLogging + if c.Changed("log-driver") { + logDriver = c.String("log-driver") + } + config := &cc.CreateConfig{ Annotations: annotations, BuiltinImgVolumes: ImageVolumes, @@ -635,7 +640,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. IPAddress: c.String("ip"), Labels: labels, //LinkLocalIP: c.StringSlice("link-local-ip"), // Not implemented yet - LogDriver: c.String("log-driver"), + LogDriver: logDriver, LogDriverOpt: c.StringSlice("log-opt"), MacAddress: c.String("mac-address"), Name: c.String("name"), |