diff options
Diffstat (limited to 'cmd/podman')
-rw-r--r-- | cmd/podman/attach.go | 2 | ||||
-rw-r--r-- | cmd/podman/build.go | 111 | ||||
-rw-r--r-- | cmd/podman/cleanup.go | 22 | ||||
-rw-r--r-- | cmd/podman/cliconfig/config.go | 6 | ||||
-rw-r--r-- | cmd/podman/commands.go | 2 | ||||
-rw-r--r-- | cmd/podman/containers_prune.go | 13 | ||||
-rw-r--r-- | cmd/podman/create.go | 3 | ||||
-rw-r--r-- | cmd/podman/image.go | 1 | ||||
-rw-r--r-- | cmd/podman/main.go | 1 | ||||
-rw-r--r-- | cmd/podman/rm.go | 5 | ||||
-rw-r--r-- | cmd/podman/run.go | 28 | ||||
-rw-r--r-- | cmd/podman/start.go | 9 | ||||
-rw-r--r-- | cmd/podman/system_prune.go | 2 | ||||
-rw-r--r-- | cmd/podman/varlink/io.podman.varlink | 69 |
14 files changed, 151 insertions, 123 deletions
diff --git a/cmd/podman/attach.go b/cmd/podman/attach.go index c29886825..ed175bdf4 100644 --- a/cmd/podman/attach.go +++ b/cmd/podman/attach.go @@ -74,7 +74,7 @@ func attachCmd(c *cliconfig.AttachValues) error { inputStream = nil } - if err := startAttachCtr(ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, c.SigProxy, false); err != nil { + if err := startAttachCtr(ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, c.SigProxy, false); err != nil && errors.Cause(err) != libpod.ErrDetach { return errors.Wrapf(err, "error attaching to container %s", ctr.ID()) } diff --git a/cmd/podman/build.go b/cmd/podman/build.go index fef93ac47..30a734377 100644 --- a/cmd/podman/build.go +++ b/cmd/podman/build.go @@ -1,7 +1,6 @@ package main import ( - "io/ioutil" "os" "path/filepath" "strings" @@ -9,10 +8,9 @@ import ( "github.com/containers/buildah" "github.com/containers/buildah/imagebuildah" buildahcli "github.com/containers/buildah/pkg/cli" - "github.com/containers/buildah/pkg/parse" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/libpodruntime" - "github.com/containers/libpod/pkg/rootless" + "github.com/containers/libpod/libpod/adapter" + "github.com/docker/go-units" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -76,7 +74,6 @@ func getDockerfiles(files []string) []string { func buildCmd(c *cliconfig.BuildValues) error { // The following was taken directly from containers/buildah/cmd/bud.go // TODO Find a away to vendor more of this in rather than copy from bud - output := "" tags := []string{} if c.Flag("tag").Changed { @@ -86,6 +83,7 @@ func buildCmd(c *cliconfig.BuildValues) error { tags = tags[1:] } } + pullPolicy := imagebuildah.PullNever if c.Pull { pullPolicy = imagebuildah.PullIfMissing @@ -173,16 +171,17 @@ func buildCmd(c *cliconfig.BuildValues) error { dockerfiles = append(dockerfiles, filepath.Join(contextDir, "Dockerfile")) } + runtime, err := adapter.GetRuntime(&c.PodmanCommand) + if err != nil { + return errors.Wrapf(err, "could not get runtime") + } + runtimeFlags := []string{} for _, arg := range c.RuntimeOpts { runtimeFlags = append(runtimeFlags, "--"+arg) } // end from buildah - runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) - if err != nil { - return errors.Wrapf(err, "could not get runtime") - } defer runtime.Shutdown(false) var stdout, stderr, reporter *os.File @@ -201,72 +200,64 @@ func buildCmd(c *cliconfig.BuildValues) error { reporter = f } - systemContext, err := parse.SystemContextFromOptions(c.PodmanCommand.Command) - if err != nil { - return errors.Wrapf(err, "error building system context") - } - systemContext.AuthFilePath = getAuthFile(c.Authfile) - commonOpts, err := parse.CommonBuildOptions(c.PodmanCommand.Command) - if err != nil { - return err + var memoryLimit, memorySwap int64 + if c.Flags().Changed("memory") { + memoryLimit, err = units.RAMInBytes(c.Memory) + if err != nil { + return err + } } - namespaceOptions, networkPolicy, err := parse.NamespaceOptions(c.PodmanCommand.Command) - if err != nil { - return errors.Wrapf(err, "error parsing namespace-related options") - } - usernsOption, idmappingOptions, err := parse.IDMappingOptions(c.PodmanCommand.Command) - if err != nil { - return errors.Wrapf(err, "error parsing ID mapping options") + if c.Flags().Changed("memory-swap") { + memorySwap, err = units.RAMInBytes(c.MemorySwap) + if err != nil { + return err + } } - namespaceOptions.AddOrReplace(usernsOption...) - ociruntime := runtime.GetOCIRuntimePath() - if c.Flag("runtime").Changed { - ociruntime = c.Runtime + buildOpts := buildah.CommonBuildOptions{ + AddHost: c.AddHost, + CgroupParent: c.CgroupParent, + CPUPeriod: c.CPUPeriod, + CPUQuota: c.CPUQuota, + CPUShares: c.CPUShares, + CPUSetCPUs: c.CPUSetCPUs, + CPUSetMems: c.CPUSetMems, + Memory: memoryLimit, + MemorySwap: memorySwap, + ShmSize: c.ShmSize, + Ulimit: c.Ulimit, + Volumes: c.Volume, } + options := imagebuildah.BuildOptions{ - ContextDirectory: contextDir, - PullPolicy: pullPolicy, - Compression: imagebuildah.Gzip, - Quiet: c.Quiet, - SignaturePolicyPath: c.SignaturePolicy, - Args: args, - Output: output, + CommonBuildOpts: &buildOpts, AdditionalTags: tags, - Out: stdout, - Err: stderr, - ReportWriter: reporter, - Runtime: ociruntime, - RuntimeArgs: runtimeFlags, - OutputFormat: format, - SystemContext: systemContext, - NamespaceOptions: namespaceOptions, - ConfigureNetwork: networkPolicy, - CNIPluginPath: c.CNIPlugInPath, + Annotations: c.Annotation, + Args: args, CNIConfigDir: c.CNIConfigDir, - IDMappingOptions: idmappingOptions, - CommonBuildOpts: commonOpts, + CNIPluginPath: c.CNIPlugInPath, + Compression: imagebuildah.Gzip, + ContextDirectory: contextDir, DefaultMountsFilePath: c.GlobalFlags.DefaultMountsFile, + Err: stderr, + ForceRmIntermediateCtrs: c.ForceRm, IIDFile: c.Iidfile, - Squash: c.Squash, Labels: c.Label, - Annotations: c.Annotation, Layers: layers, NoCache: c.NoCache, + Out: stdout, + Output: output, + OutputFormat: format, + PullPolicy: pullPolicy, + Quiet: c.Quiet, RemoveIntermediateCtrs: c.Rm, - ForceRmIntermediateCtrs: c.ForceRm, - } - - if c.Quiet { - options.ReportWriter = ioutil.Discard - } - - if rootless.IsRootless() { - options.Isolation = buildah.IsolationOCIRootless + ReportWriter: reporter, + RuntimeArgs: runtimeFlags, + SignaturePolicyPath: c.SignaturePolicy, + Squash: c.Squash, } - - return runtime.Build(getContext(), options, dockerfiles...) + return runtime.Build(getContext(), c, options, dockerfiles) } // Tail returns a string slice after the first element unless there are diff --git a/cmd/podman/cleanup.go b/cmd/podman/cleanup.go index b1f727d33..e465a30e6 100644 --- a/cmd/podman/cleanup.go +++ b/cmd/podman/cleanup.go @@ -37,6 +37,7 @@ func init() { flags.BoolVarP(&cleanupCommand.All, "all", "a", false, "Cleans up all containers") flags.BoolVarP(&cleanupCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") + flags.BoolVar(&cleanupCommand.Remove, "rm", false, "After cleanup, remove the container entirely") } func cleanupCmd(c *cliconfig.CleanupValues) error { @@ -55,12 +56,25 @@ func cleanupCmd(c *cliconfig.CleanupValues) error { ctx := getContext() for _, ctr := range cleanupContainers { - if err = ctr.Cleanup(ctx); err != nil { - if lastError != nil { - fmt.Fprintln(os.Stderr, lastError) + hadError := false + if c.Remove { + if err := runtime.RemoveContainer(ctx, ctr, false, false); err != nil { + if lastError != nil { + fmt.Fprintln(os.Stderr, lastError) + } + lastError = errors.Wrapf(err, "failed to cleanup and remove container %v", ctr.ID()) + hadError = true } - lastError = errors.Wrapf(err, "failed to cleanup container %v", ctr.ID()) } else { + if err := ctr.Cleanup(ctx); err != nil { + if lastError != nil { + fmt.Fprintln(os.Stderr, lastError) + } + lastError = errors.Wrapf(err, "failed to cleanup container %v", ctr.ID()) + hadError = true + } + } + if !hadError { fmt.Println(ctr.ID()) } } diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go index b925d29ff..f38bcaa62 100644 --- a/cmd/podman/cliconfig/config.go +++ b/cmd/podman/cliconfig/config.go @@ -135,6 +135,11 @@ type PruneImagesValues struct { All bool } +type PruneContainersValues struct { + PodmanCommand + Force bool +} + type ImportValues struct { PodmanCommand Change []string @@ -531,6 +536,7 @@ type CleanupValues struct { PodmanCommand All bool Latest bool + Remove bool } type SystemPruneValues struct { diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go index 90e2ab5cf..baa49d2af 100644 --- a/cmd/podman/commands.go +++ b/cmd/podman/commands.go @@ -10,7 +10,6 @@ import ( func getMainCommands() []*cobra.Command { rootCommands := []*cobra.Command{ _attachCommand, - _buildCommand, _commitCommand, _createCommand, _diffCommand, @@ -54,7 +53,6 @@ func getMainCommands() []*cobra.Command { // Commands that the local client implements func getImageSubCommands() []*cobra.Command { return []*cobra.Command{ - _buildCommand, _loadCommand, _saveCommand, _signCommand, diff --git a/cmd/podman/containers_prune.go b/cmd/podman/containers_prune.go index acc138fe0..bae578e1d 100644 --- a/cmd/podman/containers_prune.go +++ b/cmd/podman/containers_prune.go @@ -13,13 +13,12 @@ import ( ) var ( - pruneContainersCommand cliconfig.ContainersPrune + pruneContainersCommand cliconfig.PruneContainersValues pruneContainersDescription = ` podman container prune Removes all exited containers ` - _pruneContainersCommand = &cobra.Command{ Use: "prune", Short: "Remove all stopped containers", @@ -35,9 +34,11 @@ var ( func init() { pruneContainersCommand.Command = _pruneContainersCommand pruneContainersCommand.SetUsageTemplate(UsageTemplate()) + flags := pruneContainersCommand.Flags() + flags.BoolVarP(&pruneContainersCommand.Force, "force", "f", false, "Force removal of a running container. The default is false") } -func pruneContainers(runtime *adapter.LocalRuntime, ctx context.Context, maxWorkers int, force bool) error { +func pruneContainers(runtime *adapter.LocalRuntime, ctx context.Context, maxWorkers int, force, volumes bool) error { var deleteFuncs []shared.ParallelWorkerInput filter := func(c *libpod.Container) bool { @@ -57,7 +58,7 @@ func pruneContainers(runtime *adapter.LocalRuntime, ctx context.Context, maxWork for _, container := range delContainers { con := container f := func() error { - return runtime.RemoveContainer(ctx, con, force) + return runtime.RemoveContainer(ctx, con, force, volumes) } deleteFuncs = append(deleteFuncs, shared.ParallelWorkerInput{ @@ -70,7 +71,7 @@ func pruneContainers(runtime *adapter.LocalRuntime, ctx context.Context, maxWork return printParallelOutput(deleteErrors, errCount) } -func pruneContainersCmd(c *cliconfig.ContainersPrune) error { +func pruneContainersCmd(c *cliconfig.PruneContainersValues) error { runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "could not get runtime") @@ -83,5 +84,5 @@ func pruneContainersCmd(c *cliconfig.ContainersPrune) error { } logrus.Debugf("Setting maximum workers to %d", maxWorkers) - return pruneContainers(runtime, getContext(), maxWorkers, c.Bool("force")) + return pruneContainers(runtime, getContext(), maxWorkers, c.Bool("force"), c.Bool("volumes")) } diff --git a/cmd/podman/create.go b/cmd/podman/create.go index 1a7f419c0..392163424 100644 --- a/cmd/podman/create.go +++ b/cmd/podman/create.go @@ -646,9 +646,10 @@ func parseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l } var ImageVolumes map[string]struct{} - if data != nil { + if data != nil && c.String("image-volume") != "ignore" { ImageVolumes = data.Config.Volumes } + var imageVolType = map[string]string{ "bind": "", "tmpfs": "", diff --git a/cmd/podman/image.go b/cmd/podman/image.go index edc37b28a..4f9c7cd6a 100644 --- a/cmd/podman/image.go +++ b/cmd/podman/image.go @@ -18,6 +18,7 @@ var ( //imageSubCommands are implemented both in local and remote clients var imageSubCommands = []*cobra.Command{ + _buildCommand, _historyCommand, _imageExistsCommand, _imagesCommand, diff --git a/cmd/podman/main.go b/cmd/podman/main.go index a6f0c500a..f9820c075 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -30,6 +30,7 @@ var ( // Commands that the remote and local client have // implemented. var mainCommands = []*cobra.Command{ + _buildCommand, _exportCommand, _historyCommand, _imagesCommand, diff --git a/cmd/podman/rm.go b/cmd/podman/rm.go index 1e5e9d254..d170e5357 100644 --- a/cmd/podman/rm.go +++ b/cmd/podman/rm.go @@ -39,8 +39,7 @@ func init() { flags.BoolVarP(&rmCommand.All, "all", "a", false, "Remove all containers") flags.BoolVarP(&rmCommand.Force, "force", "f", false, "Force removal of a running container. The default is false") flags.BoolVarP(&rmCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - flags.BoolVarP(&rmCommand.Volumes, "volumes", "v", false, "Remove the volumes associated with the container (Not implemented yet)") - + flags.BoolVarP(&rmCommand.Volumes, "volumes", "v", false, "Remove the volumes associated with the container") } // saveCmd saves the image to either docker-archive or oci @@ -79,7 +78,7 @@ func rmCmd(c *cliconfig.RmValues) error { for _, container := range delContainers { con := container f := func() error { - return runtime.RemoveContainer(ctx, con, c.Force) + return runtime.RemoveContainer(ctx, con, c.Force, c.Volumes) } deleteFuncs = append(deleteFuncs, shared.ParallelWorkerInput{ diff --git a/cmd/podman/run.go b/cmd/podman/run.go index 8649dc190..64f8b6856 100644 --- a/cmd/podman/run.go +++ b/cmd/podman/run.go @@ -118,13 +118,21 @@ func runCmd(c *cliconfig.RunValues) error { } } if err := startAttachCtr(ctr, outputStream, errorStream, inputStream, c.String("detach-keys"), c.Bool("sig-proxy"), true); err != nil { + // We've manually detached from the container + // Do not perform cleanup, or wait for container exit code + // Just exit immediately + if errors.Cause(err) == libpod.ErrDetach { + exitCode = 0 + return nil + } + // This means the command did not exist exitCode = 127 if strings.Index(err.Error(), "permission denied") > -1 { exitCode = 126 } if c.IsSet("rm") { - if deleteError := runtime.RemoveContainer(ctx, ctr, true); deleteError != nil { + if deleteError := runtime.RemoveContainer(ctx, ctr, true, false); deleteError != nil { logrus.Errorf("unable to remove container %s after failing to start and attach to it", ctr.ID()) } } @@ -147,28 +155,12 @@ func runCmd(c *cliconfig.RunValues) error { exitCode = int(ecode) } - if createConfig.Rm { - return runtime.RemoveContainer(ctx, ctr, true) - } - - if err := ctr.Cleanup(ctx); err != nil { - // If the container has been removed already, no need to error on cleanup - // Also, if it was restarted, don't error either - if errors.Cause(err) == libpod.ErrNoSuchCtr || - errors.Cause(err) == libpod.ErrCtrRemoved || - errors.Cause(err) == libpod.ErrCtrStateInvalid { - return nil - } - - return err - } - return nil } // Read a container's exit file func readExitFile(runtimeTmp, ctrID string) (int, error) { - exitFile := filepath.Join(runtimeTmp, "exits", ctrID) + exitFile := filepath.Join(runtimeTmp, "exits", fmt.Sprintf("%s-old", ctrID)) logrus.Debugf("Attempting to read container %s exit code from file %s", ctrID, exitFile) diff --git a/cmd/podman/start.go b/cmd/podman/start.go index 344719fca..3a606d662 100644 --- a/cmd/podman/start.go +++ b/cmd/podman/start.go @@ -108,6 +108,13 @@ func startCmd(c *cliconfig.StartValues) error { // attach to the container and also start it not already running err = startAttachCtr(ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, sigProxy, !ctrRunning) + if errors.Cause(err) == libpod.ErrDetach { + // User manually detached + // Exit cleanly immediately + exitCode = 0 + return nil + } + if ctrRunning { return err } @@ -137,7 +144,7 @@ func startCmd(c *cliconfig.StartValues) error { logrus.Errorf("unable to detect if container %s should be deleted", ctr.ID()) } if createArtifact.Rm { - if rmErr := runtime.RemoveContainer(ctx, ctr, true); rmErr != nil { + if rmErr := runtime.RemoveContainer(ctx, ctr, true, false); rmErr != nil { logrus.Errorf("unable to remove container %s after it failed to start", ctr.ID()) } } diff --git a/cmd/podman/system_prune.go b/cmd/podman/system_prune.go index a88027558..a91d7bf0a 100644 --- a/cmd/podman/system_prune.go +++ b/cmd/podman/system_prune.go @@ -76,7 +76,7 @@ Are you sure you want to continue? [y/N] `, volumeString) ctx := getContext() fmt.Println("Deleted Containers") - lasterr := pruneContainers(runtime, ctx, shared.Parallelize("rm"), false) + lasterr := pruneContainers(runtime, ctx, shared.Parallelize("rm"), false, false) if c.Bool("volumes") { fmt.Println("Deleted Volumes") err := volumePrune(runtime, getContext()) diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index 03ea06dfc..3b7a11fc3 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -311,33 +311,50 @@ type IDMap ( size: int ) +# BuildOptions are are used to describe describe physical attributes of the build +type BuildOptions ( + addHosts: []string, + cgroupParent: string, + cpuPeriod: int, + cpuQuota: int, + cpuShares: int, + cpusetCpus: string, + cpusetMems: string, + memory: int, + memorySwap: int, + shmSize: string, + ulimit: []string, + volume: []string +) + # BuildInfo is used to describe user input for building images type BuildInfo ( - # paths to one or more dockerfiles - dockerfile: []string, - tags: []string, - add_hosts: []string, - cgroup_parent: string, - cpu_period: int, - cpu_quota: int, - cpu_shares: int, - cpuset_cpus: string, - cpuset_mems: string, - memory: string, - memory_swap: string, - security_opts: []string, - shm_size: string, - ulimit: []string, - volume: []string, - squash: bool, - pull: bool, - pull_always: bool, - force_rm: bool, - rm: bool, - label: []string, + additionalTags: []string, annotations: []string, - build_args: [string]string, - image_format: string + buildArgs: [string]string, + buildOptions: BuildOptions, + cniConfigDir: string, + cniPluginDir: string, + compression: string, + contextDir: string, + defaultsMountFilePath: string, + dockerfiles: []string, + err: string, + forceRmIntermediateCtrs: bool, + iidfile: string, + label: []string, + layers: bool, + nocache: bool, + out: string, + output: string, + outputFormat: string, + pullPolicy: string, + quiet: bool, + remoteIntermediateCtrs: bool, + reportWriter: string, + runtimeArgs: []string, + signaturePolicyPath: string, + squash: bool ) # MoreResponse is a struct for when responses from varlink requires longer output @@ -583,7 +600,7 @@ method GetAttachSockets(name: string) -> (sockets: Sockets) # a [ContainerNotFound](#ContainerNotFound) error is returned. method WaitContainer(name: string) -> (exitcode: int) -# RemoveContainer takes requires the name or ID of container as well a boolean representing whether a running +# RemoveContainer takes requires the name or ID of container as well a boolean representing whether a running and a boolean indicating whether to remove builtin volumes # container can be stopped and removed. Upon successful removal of the container, its ID is returned. If the # container cannot be found by name or ID, a [ContainerNotFound](#ContainerNotFound) error will be returned. # #### Example @@ -593,7 +610,7 @@ method WaitContainer(name: string) -> (exitcode: int) # "container": "62f4fd98cb57f529831e8f90610e54bba74bd6f02920ffb485e15376ed365c20" # } # ~~~ -method RemoveContainer(name: string, force: bool) -> (container: string) +method RemoveContainer(name: string, force: bool, removeVolumes: bool) -> (container: string) # DeleteStoppedContainers will delete all containers that are not running. It will return a list the deleted # container IDs. See also [RemoveContainer](RemoveContainer). |