summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/podman/build.go3
-rw-r--r--cmd/podman/cliconfig/config.go18
-rw-r--r--cmd/podman/common.go8
-rw-r--r--cmd/podman/cp.go19
-rw-r--r--cmd/podman/generate_systemd.go1
-rw-r--r--cmd/podman/image.go1
-rw-r--r--cmd/podman/kill.go4
-rw-r--r--cmd/podman/main.go1
-rw-r--r--cmd/podman/main_local.go6
-rw-r--r--cmd/podman/play_kube.go3
-rw-r--r--cmd/podman/pod_kill.go4
-rw-r--r--cmd/podman/ps.go17
-rw-r--r--cmd/podman/rmi.go11
-rw-r--r--cmd/podman/shared/container.go33
-rw-r--r--cmd/podman/shared/create.go9
-rw-r--r--cmd/podman/shared/create_cli.go14
-rw-r--r--cmd/podman/tree.go2
-rw-r--r--cmd/podman/untag.go67
-rw-r--r--cmd/podman/varlink/io.podman.varlink26
-rw-r--r--cmd/service/main.go55
20 files changed, 233 insertions, 69 deletions
diff --git a/cmd/podman/build.go b/cmd/podman/build.go
index fbf85fc97..08d3edaa3 100644
--- a/cmd/podman/build.go
+++ b/cmd/podman/build.go
@@ -375,7 +375,8 @@ func buildCmd(c *cliconfig.BuildValues) error {
},
Target: c.Target,
}
- return runtime.Build(getContext(), c, options, containerfiles)
+ _, _, err = runtime.Build(getContext(), c, options, containerfiles)
+ return err
}
// useLayers returns false if BUILDAH_LAYERS is set to "0" or "false"
diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go
index e81756808..b261599e6 100644
--- a/cmd/podman/cliconfig/config.go
+++ b/cmd/podman/cliconfig/config.go
@@ -163,6 +163,7 @@ type GenerateKubeValues struct {
type GenerateSystemdValues struct {
PodmanCommand
Name bool
+ New bool
Files bool
RestartPolicy string
StopTimeout int
@@ -308,12 +309,13 @@ type HealthCheckValues struct {
type KubePlayValues struct {
PodmanCommand
- Authfile string
- CertDir string
- Creds string
- Quiet bool
- SignaturePolicy string
- TlsVerify bool
+ Authfile string
+ CertDir string
+ Creds string
+ Quiet bool
+ SignaturePolicy string
+ TlsVerify bool
+ SeccompProfileRoot string
}
type PodCreateValues struct {
@@ -680,3 +682,7 @@ type SystemDfValues struct {
Verbose bool
Format string
}
+
+type UntagValues struct {
+ PodmanCommand
+}
diff --git a/cmd/podman/common.go b/cmd/podman/common.go
index 69365201e..dc7590590 100644
--- a/cmd/podman/common.go
+++ b/cmd/podman/common.go
@@ -308,7 +308,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
)
createFlags.String(
"image-volume", cliconfig.DefaultImageVolume,
- "Tells podman how to handle the builtin image volumes. The options are: 'bind', 'tmpfs', or 'ignore'",
+ `Tells podman how to handle the builtin image volumes ("bind"|"tmpfs"|"ignore")`,
)
createFlags.Bool(
"init", false,
@@ -431,7 +431,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
)
createFlags.String(
"pull", "missing",
- `Pull image before creating ("always"|"missing"|"never") (default "missing")`,
+ `Pull image before creating ("always"|"missing"|"never")`,
)
createFlags.BoolP(
"quiet", "q", false,
@@ -447,7 +447,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
)
createFlags.String(
"restart", "",
- "Restart policy to apply when a container exits",
+ `Restart policy to apply when a container exits ("always"|"no"|"on-failure")`,
)
createFlags.Bool(
"rm", false,
@@ -492,7 +492,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
)
createFlags.String(
"systemd", "true",
- `Run container in systemd mode ("true"|"false"|"always" (default "true")`,
+ `Run container in systemd mode ("true"|"false"|"always")`,
)
createFlags.StringArray(
"tmpfs", []string{},
diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go
index 762d70252..ea97752a3 100644
--- a/cmd/podman/cp.go
+++ b/cmd/podman/cp.go
@@ -101,18 +101,7 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin
}
}()
- // We can't pause rootless containers.
- if pause && rootless.IsRootless() {
- state, err := ctr.State()
- if err != nil {
- return err
- }
- if state == define.ContainerStateRunning {
- return errors.Errorf("cannot copy into running rootless container with pause set - pass --pause=false to force copying")
- }
- }
-
- if pause && !rootless.IsRootless() {
+ if pause {
if err := ctr.Pause(); err != nil {
// An invalid state error is fine.
// The container isn't running or is already paused.
@@ -222,7 +211,7 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin
srcPath = os.Stdin.Name()
extract = true
}
- return copy(srcPath, destPath, dest, idMappingOpts, &destOwner, extract, isFromHostToCtr)
+ return copy(srcPath, destPath, src, dest, idMappingOpts, &destOwner, extract, isFromHostToCtr)
}
func getUser(mountPoint string, userspec string) (specs.User, error) {
@@ -276,8 +265,8 @@ func getPathInfo(path string) (string, os.FileInfo, error) {
return path, srcfi, nil
}
-func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, chownOpts *idtools.IDPair, extract, isFromHostToCtr bool) error {
- srcPath, err := evalSymlinks(src)
+func copy(srcPath, destPath, src, dest string, idMappingOpts storage.IDMappingOptions, chownOpts *idtools.IDPair, extract, isFromHostToCtr bool) error {
+ srcPath, err := evalSymlinks(srcPath)
if err != nil {
return errors.Wrapf(err, "error evaluating symlinks %q", srcPath)
}
diff --git a/cmd/podman/generate_systemd.go b/cmd/podman/generate_systemd.go
index aa202a68d..a9775f9cb 100644
--- a/cmd/podman/generate_systemd.go
+++ b/cmd/podman/generate_systemd.go
@@ -45,6 +45,7 @@ func init() {
}
flags.IntVarP(&containerSystemdCommand.StopTimeout, "timeout", "t", -1, "stop timeout override")
flags.StringVar(&containerSystemdCommand.RestartPolicy, "restart-policy", "on-failure", "applicable systemd restart-policy")
+ flags.BoolVarP(&containerSystemdCommand.New, "new", "", false, "create a new container instead of starting an existing one")
}
func generateSystemdCmd(c *cliconfig.GenerateSystemdValues) error {
diff --git a/cmd/podman/image.go b/cmd/podman/image.go
index 66c141686..ce576ff4b 100644
--- a/cmd/podman/image.go
+++ b/cmd/podman/image.go
@@ -74,6 +74,7 @@ var imageSubCommands = []*cobra.Command{
_saveCommand,
_tagCommand,
_treeCommand,
+ _untagCommand,
}
func init() {
diff --git a/cmd/podman/kill.go b/cmd/podman/kill.go
index aba2008ca..a10546ea9 100644
--- a/cmd/podman/kill.go
+++ b/cmd/podman/kill.go
@@ -3,7 +3,7 @@ package main
import (
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/pkg/adapter"
- "github.com/docker/docker/pkg/signal"
+ "github.com/containers/libpod/pkg/util"
"github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/spf13/cobra"
@@ -54,7 +54,7 @@ func killCmd(c *cliconfig.KillValues) error {
// Check if the signalString provided by the user is valid
// Invalid signals will return err
- killSignal, err := signal.ParseSignal(c.Signal)
+ killSignal, err := util.ParseSignal(c.Signal)
if err != nil {
return err
}
diff --git a/cmd/podman/main.go b/cmd/podman/main.go
index 344170ddd..c727eea85 100644
--- a/cmd/podman/main.go
+++ b/cmd/podman/main.go
@@ -68,6 +68,7 @@ var mainCommands = []*cobra.Command{
imageCommand.Command,
_startCommand,
systemCommand.Command,
+ _untagCommand,
}
var rootCmd = &cobra.Command{
diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go
index bc46e4652..e5b87754b 100644
--- a/cmd/podman/main_local.go
+++ b/cmd/podman/main_local.go
@@ -33,7 +33,7 @@ const remote = false
func init() {
cgroupManager := define.SystemdCgroupsManager
- cgroupHelp := "Cgroup manager to use (cgroupfs or systemd)"
+ cgroupHelp := `Cgroup manager to use ("cgroupfs"|"systemd")`
cgroupv2, _ := cgroups.IsCgroup2UnifiedMode()
if rootless.IsRootless() && !cgroupv2 {
cgroupManager = ""
@@ -50,12 +50,12 @@ func init() {
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")
+ rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.EventsBackend, "events-backend", "", `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().StringVar(&MainGlobalOpts.LogLevel, "log-level", "error", "Log messages above specified level: debug, info, warn, error, fatal or panic")
+ 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")
diff --git a/cmd/podman/play_kube.go b/cmd/podman/play_kube.go
index fc9f2d5b6..2028d2ef4 100644
--- a/cmd/podman/play_kube.go
+++ b/cmd/podman/play_kube.go
@@ -28,6 +28,8 @@ var (
},
Example: `podman play kube demo.yml`,
}
+ // https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/
+ defaultSeccompRoot = "/var/lib/kubelet/seccomp"
)
func init() {
@@ -46,6 +48,7 @@ func init() {
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.StringVar(&playKubeCommand.SeccompProfileRoot, "seccomp-profile-root", defaultSeccompRoot, "Directory path for seccomp profiles")
markFlagHidden(flags, "signature-policy")
}
}
diff --git a/cmd/podman/pod_kill.go b/cmd/podman/pod_kill.go
index 064946f72..9f696073d 100644
--- a/cmd/podman/pod_kill.go
+++ b/cmd/podman/pod_kill.go
@@ -6,7 +6,7 @@ import (
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/pkg/adapter"
- "github.com/docker/docker/pkg/signal"
+ "github.com/containers/libpod/pkg/util"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -60,7 +60,7 @@ func podKillCmd(c *cliconfig.PodKillValues) error {
if c.Signal != "" {
// Check if the signalString provided by the user is valid
// Invalid signals will return err
- sysSignal, err := signal.ParseSignal(c.Signal)
+ sysSignal, err := util.ParseSignal(c.Signal)
if err != nil {
return err
}
diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go
index 9fad0ea65..d2c5e19e2 100644
--- a/cmd/podman/ps.go
+++ b/cmd/podman/ps.go
@@ -31,6 +31,7 @@ const (
hsize = "SIZE"
hinfra = "IS INFRA" //nolint
hpod = "POD"
+ hpodname = "POD NAME"
nspid = "PID"
nscgroup = "CGROUPNS"
nsipc = "IPC"
@@ -204,11 +205,15 @@ func checkFlagsPassed(c *cliconfig.PsValues) error {
if c.Last >= 0 && c.Latest {
return errors.Errorf("last and latest are mutually exclusive")
}
- // Quiet conflicts with size, namespace, and format with a Go template
+ // Quiet conflicts with size and namespace and is overridden by a Go
+ // template.
if c.Quiet {
- if c.Size || c.Namespace || (c.Flag("format").Changed &&
- c.Format != formats.JSONString) {
- return errors.Errorf("quiet conflicts with size, namespace, and format with go template")
+ if c.Size || c.Namespace {
+ return errors.Errorf("quiet conflicts with size and namespace")
+ }
+ if c.Flag("format").Changed && c.Format != formats.JSONString {
+ // Quiet is overridden by Go template output.
+ c.Quiet = false
}
}
// Size and namespace conflict with each other
@@ -351,7 +356,7 @@ func psDisplay(c *cliconfig.PsValues, runtime *adapter.LocalRuntime) error {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s", hid, himage, hcommand, hcreated, hstatus, hports, hnames)
// User wants pod info
if opts.Pod {
- fmt.Fprintf(w, "\t%s", hpod)
+ fmt.Fprintf(w, "\t%s\t%s", hpod, hpodname)
}
//User wants size info
if opts.Size {
@@ -370,7 +375,7 @@ func psDisplay(c *cliconfig.PsValues, runtime *adapter.LocalRuntime) error {
fmt.Fprintf(w, "\n%s\t%s\t%s\t%s\t%s\t%s\t%s", container.ID, container.Image, container.Command, container.Created, container.Status, container.Ports, container.Names)
// User wants pod info
if opts.Pod {
- fmt.Fprintf(w, "\t%s", container.Pod)
+ fmt.Fprintf(w, "\t%s\t%s", container.Pod, container.PodName)
}
//User wants size info
if opts.Size {
diff --git a/cmd/podman/rmi.go b/cmd/podman/rmi.go
index 3f621116e..f4ca88ea8 100644
--- a/cmd/podman/rmi.go
+++ b/cmd/podman/rmi.go
@@ -68,7 +68,7 @@ func rmiCmd(c *cliconfig.RmiValues) error {
images := args[:]
removeImage := func(img *adapter.ContainerImage) {
- msg, err := runtime.RemoveImage(ctx, img, c.Force)
+ response, err := runtime.RemoveImage(ctx, img, c.Force)
if err != nil {
if errors.Cause(err) == storage.ErrImageUsedByContainer {
fmt.Printf("A container associated with containers/storage, i.e. via Buildah, CRI-O, etc., may be associated with this image: %-12.12s\n", img.ID())
@@ -83,7 +83,14 @@ func rmiCmd(c *cliconfig.RmiValues) error {
lastError = err
return
}
- fmt.Println(msg)
+ // Iterate if any images tags were deleted
+ for _, i := range response.Untagged {
+ fmt.Printf("Untagged: %s\n", i)
+ }
+ // Make sure an image was deleted (and not just untagged); else print it
+ if len(response.Deleted) > 0 {
+ fmt.Printf("Deleted: %s\n", response.Deleted)
+ }
}
if removeAll {
diff --git a/cmd/podman/shared/container.go b/cmd/podman/shared/container.go
index 4f2002992..5f8df2e10 100644
--- a/cmd/podman/shared/container.go
+++ b/cmd/podman/shared/container.go
@@ -76,6 +76,7 @@ type PsContainerOutput struct {
Pid int
Size *ContainerSize
Pod string
+ PodName string
CreatedAt time.Time
ExitedAt time.Time
StartedAt time.Time
@@ -112,7 +113,7 @@ type ContainerSize struct {
// NewBatchContainer runs a batch process under one lock to get container information and only
// be called in PBatch.
-func NewBatchContainer(ctr *libpod.Container, opts PsOptions) (PsContainerOutput, error) {
+func NewBatchContainer(r *libpod.Runtime, ctr *libpod.Container, opts PsOptions) (PsContainerOutput, error) {
var (
conState define.ContainerStatus
command string
@@ -204,11 +205,11 @@ func NewBatchContainer(ctr *libpod.Container, opts PsOptions) (PsContainerOutput
_, imageName := ctr.Image()
cid := ctr.ID()
- pod := ctr.PodID()
+ podID := ctr.PodID()
if !opts.NoTrunc {
cid = cid[0:cidTruncLength]
- if len(pod) > podTruncLength {
- pod = pod[0:podTruncLength]
+ if len(podID) > podTruncLength {
+ podID = podID[0:podTruncLength]
}
if len(command) > cmdTruncLength {
command = command[0:cmdTruncLength] + "..."
@@ -231,13 +232,29 @@ func NewBatchContainer(ctr *libpod.Container, opts PsOptions) (PsContainerOutput
pso.State = conState
pso.Pid = pid
pso.Size = size
- pso.Pod = pod
pso.ExitedAt = exitedAt
pso.CreatedAt = ctr.CreatedTime()
pso.StartedAt = startedAt
pso.Labels = ctr.Labels()
pso.Mounts = strings.Join(ctr.UserVolumes(), " ")
+ // Add pod name and pod ID if requested by user.
+ // No need to look up the pod if its ID is empty.
+ if opts.Pod && len(podID) > 0 {
+ // The pod name is not in the container definition
+ // so we need to retrieve it using the pod ID.
+ var podName string
+ pod, err := r.LookupPod(podID)
+ if err != nil {
+ logrus.Errorf("unable to lookup pod for container %s", ctr.ID())
+ } else {
+ podName = pod.Name()
+ }
+
+ pso.Pod = podID
+ pso.PodName = podName
+ }
+
if opts.Namespace {
pso.Cgroup = ns.Cgroup
pso.IPC = ns.IPC
@@ -462,13 +479,13 @@ func GetPsContainerOutput(r *libpod.Runtime, opts PsOptions, filters []string, m
outputContainers = []*libpod.Container{latestCtr}
}
- pss := PBatch(outputContainers, maxWorkers, opts)
+ pss := PBatch(r, outputContainers, maxWorkers, opts)
return pss, nil
}
// PBatch performs batch operations on a container in parallel. It spawns the
// number of workers relative to the number of parallel operations desired.
-func PBatch(containers []*libpod.Container, workers int, opts PsOptions) []PsContainerOutput {
+func PBatch(r *libpod.Runtime, containers []*libpod.Container, workers int, opts PsOptions) []PsContainerOutput {
var wg sync.WaitGroup
psResults := []PsContainerOutput{}
@@ -492,7 +509,7 @@ func PBatch(containers []*libpod.Container, workers int, opts PsOptions) []PsCon
j := j
wg.Add(1)
f := func() (PsContainerOutput, error) {
- return NewBatchContainer(j, opts)
+ return NewBatchContainer(r, j, opts)
}
jobs <- workerInput{
parallelFunc: f,
diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go
index bb4e9cd12..58cf56eea 100644
--- a/cmd/podman/shared/create.go
+++ b/cmd/podman/shared/create.go
@@ -24,7 +24,6 @@ import (
"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"
"github.com/docker/go-connections/nat"
"github.com/docker/go-units"
"github.com/opentracing/opentracing-go"
@@ -464,7 +463,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
signalString = c.String("stop-signal")
}
if signalString != "" {
- stopSignal, err = signal.ParseSignal(signalString)
+ stopSignal, err = util.ParseSignal(signalString)
if err != nil {
return nil, err
}
@@ -624,7 +623,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
}
if systemd {
if signalString == "" {
- stopSignal, err = signal.ParseSignal("RTMIN+3")
+ stopSignal, err = util.ParseSignal("RTMIN+3")
if err != nil {
return nil, errors.Wrapf(err, "error parsing systemd signal")
}
@@ -804,6 +803,10 @@ func CreateContainerFromCreateConfig(r *libpod.Runtime, createConfig *cc.CreateC
return nil, err
}
+ // Set the CreateCommand explicitly. Some (future) consumers of libpod
+ // might not want to set it.
+ options = append(options, libpod.WithCreateCommand())
+
ctr, err := r.NewContainer(ctx, runtimeSpec, options...)
if err != nil {
return nil, err
diff --git a/cmd/podman/shared/create_cli.go b/cmd/podman/shared/create_cli.go
index 08a40b206..00b83906d 100644
--- a/cmd/podman/shared/create_cli.go
+++ b/cmd/podman/shared/create_cli.go
@@ -12,11 +12,6 @@ import (
"github.com/sirupsen/logrus"
)
-const (
- // It's not kernel limit, we want this 4M limit to supply a reasonable functional container
- linuxMinMemory = 4194304
-)
-
// GetAllLabels ...
func GetAllLabels(labelFile, inputLabels []string) (map[string]string, error) {
labels := make(map[string]string)
@@ -86,9 +81,6 @@ func verifyContainerResources(config *cc.CreateConfig, update bool) ([]string, e
sysInfo := sysinfo.New(true)
// memory subsystem checks and adjustments
- if config.Resources.Memory != 0 && config.Resources.Memory < linuxMinMemory {
- return warnings, fmt.Errorf("minimum memory limit allowed is 4MB")
- }
if config.Resources.Memory > 0 && !sysInfo.MemoryLimit {
warnings = addWarning(warnings, "Your kernel does not support memory limit capabilities or the cgroup is not mounted. Limitation discarded.")
config.Resources.Memory = 0
@@ -120,9 +112,6 @@ func verifyContainerResources(config *cc.CreateConfig, update bool) ([]string, e
warnings = addWarning(warnings, "Your kernel does not support memory soft limit capabilities or the cgroup is not mounted. Limitation discarded.")
config.Resources.MemoryReservation = 0
}
- if config.Resources.MemoryReservation > 0 && config.Resources.MemoryReservation < linuxMinMemory {
- return warnings, fmt.Errorf("minimum memory reservation allowed is 4MB")
- }
if config.Resources.Memory > 0 && config.Resources.MemoryReservation > 0 && config.Resources.Memory < config.Resources.MemoryReservation {
return warnings, fmt.Errorf("minimum memory limit cannot be less than memory reservation limit, see usage")
}
@@ -130,9 +119,6 @@ func verifyContainerResources(config *cc.CreateConfig, update bool) ([]string, e
warnings = addWarning(warnings, "Your kernel does not support kernel memory limit capabilities or the cgroup is not mounted. Limitation discarded.")
config.Resources.KernelMemory = 0
}
- if config.Resources.KernelMemory > 0 && config.Resources.KernelMemory < linuxMinMemory {
- return warnings, fmt.Errorf("minimum kernel memory limit allowed is 4MB")
- }
if config.Resources.DisableOomKiller && !sysInfo.OomKillDisable {
// only produce warnings if the setting wasn't to *disable* the OOM Kill; no point
// warning the caller if they already wanted the feature to be off
diff --git a/cmd/podman/tree.go b/cmd/podman/tree.go
index cb1b3fc9c..566f96995 100644
--- a/cmd/podman/tree.go
+++ b/cmd/podman/tree.go
@@ -56,7 +56,7 @@ func treeCmd(c *cliconfig.TreeValues) error {
return errors.Wrapf(err, "error creating libpod runtime")
}
defer runtime.DeferredShutdown(false)
- imageInfo, layerInfoMap, img, err := runtime.Tree(c)
+ imageInfo, layerInfoMap, img, err := runtime.Tree(c.InputArgs[0])
if err != nil {
return err
}
diff --git a/cmd/podman/untag.go b/cmd/podman/untag.go
new file mode 100644
index 000000000..9ff62b808
--- /dev/null
+++ b/cmd/podman/untag.go
@@ -0,0 +1,67 @@
+package main
+
+import (
+ "github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/containers/libpod/pkg/adapter"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+ "github.com/spf13/cobra"
+)
+
+var (
+ untagCommand cliconfig.UntagValues
+
+ _untagCommand = &cobra.Command{
+ Use: "untag [flags] IMAGE [NAME...]",
+ Short: "Remove a name from a local image",
+ Long: "Removes one or more names from a locally-stored image.",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ untagCommand.InputArgs = args
+ untagCommand.GlobalFlags = MainGlobalOpts
+ untagCommand.Remote = remoteclient
+ return untag(&untagCommand)
+ },
+ Example: `podman untag 0e3bbc2
+ podman untag imageID:latest otherImageName:latest
+ podman untag httpd myregistryhost:5000/fedora/httpd:v2`,
+ }
+)
+
+func init() {
+ untagCommand.Command = _untagCommand
+ untagCommand.SetHelpTemplate(HelpTemplate())
+ untagCommand.SetUsageTemplate(UsageTemplate())
+}
+
+func untag(c *cliconfig.UntagValues) error {
+ args := c.InputArgs
+
+ if len(args) == 0 {
+ return errors.Errorf("at least one image name needs to be specified")
+ }
+
+ runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
+ if err != nil {
+ return errors.Wrapf(err, "could not create runtime")
+ }
+ defer runtime.DeferredShutdown(false)
+
+ newImage, err := runtime.NewImageFromLocal(args[0])
+ if err != nil {
+ return err
+ }
+
+ tags := args[1:]
+ if len(args) == 1 {
+ // Remove all tags if not explicitly specified
+ tags = newImage.Names()
+ }
+ logrus.Debugf("Tags to be removed: %v", tags)
+
+ for _, tag := range tags {
+ if err := newImage.UntagImage(tag); err != nil {
+ return errors.Wrapf(err, "removing %q from %q", tag, newImage.InputName)
+ }
+ }
+ return nil
+}
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 2251050c3..ac400a467 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -18,6 +18,11 @@ type StringResponse (
message: string
)
+type RemoveImageResponse (
+ untagged: []string,
+ deleted: string
+)
+
type LogLine (
device: string,
parseLogType : string,
@@ -240,6 +245,13 @@ type InfoGraphStatus (
supports_d_type: string
)
+# InfoRegistry describes the host's registry information
+type InfoRegistry (
+ search: []string,
+ insecure: []string,
+ blocked: []string
+)
+
# InfoStore describes the host's storage informatoin
type InfoStore (
containers: int,
@@ -262,8 +274,7 @@ type InfoPodmanBinary (
# PodmanInfo describes the Podman host and build
type PodmanInfo (
host: InfoHost,
- registries: []string,
- insecure_registries: []string,
+ registries: InfoRegistry,
store: InfoStore,
podman: InfoPodmanBinary
)
@@ -855,6 +866,12 @@ method PushImage(name: string, tag: string, compress: bool, format: string, remo
# be found, an [ImageNotFound](#ImageNotFound) error will be returned; otherwise, the ID of the image is returned on success.
method TagImage(name: string, tagged: string) -> (image: string)
+# UntagImage takes the name or ID of an image in local storage as well as the
+# tag name to be removed. If the image cannot be found, an
+# [ImageNotFound](#ImageNotFound) error will be returned; otherwise, the ID of
+# the image is returned on success.
+method UntagImage(name: string, tag: string) -> (image: string)
+
# RemoveImage takes the name or ID of an image as well as a boolean that determines if containers using that image
# should be deleted. If the image cannot be found, an [ImageNotFound](#ImageNotFound) error will be returned. The
# ID of the removed image is returned when complete. See also [DeleteUnusedImages](DeleteUnusedImages).
@@ -867,6 +884,11 @@ method TagImage(name: string, tagged: string) -> (image: string)
# ~~~
method RemoveImage(name: string, force: bool) -> (image: string)
+# RemoveImageWithResponse takes the name or ID of an image as well as a boolean that determines if containers using that image
+# should be deleted. If the image cannot be found, an [ImageNotFound](#ImageNotFound) error will be returned. The reponse is
+# in the form of a RemoveImageResponse .
+method RemoveImageWithResponse(name: string, force: bool) -> (response: RemoveImageResponse)
+
# 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.
diff --git a/cmd/service/main.go b/cmd/service/main.go
new file mode 100644
index 000000000..0290de892
--- /dev/null
+++ b/cmd/service/main.go
@@ -0,0 +1,55 @@
+package main
+
+import (
+ "context"
+ "fmt"
+ "os"
+
+ "github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/containers/libpod/cmd/podman/libpodruntime"
+ api "github.com/containers/libpod/pkg/api/server"
+ "github.com/containers/storage/pkg/reexec"
+ log "github.com/sirupsen/logrus"
+ "github.com/spf13/cobra"
+)
+
+func initConfig() {
+ // we can do more stuff in here.
+}
+
+func main() {
+ if reexec.Init() {
+ // We were invoked with a different argv[0] indicating that we
+ // had a specific job to do as a subprocess, and it's done.
+ return
+ }
+
+ cobra.OnInitialize(initConfig)
+ log.SetLevel(log.DebugLevel)
+
+ config := cliconfig.PodmanCommand{
+ Command: &cobra.Command{},
+ InputArgs: []string{},
+ GlobalFlags: cliconfig.MainFlags{},
+ Remote: false,
+ }
+ // Create a single runtime for http
+ runtime, err := libpodruntime.GetRuntimeDisableFDs(context.Background(), &config)
+ if err != nil {
+ fmt.Printf("error creating libpod runtime: %s", err.Error())
+ os.Exit(1)
+ }
+ defer runtime.DeferredShutdown(false)
+
+ server, err := api.NewServer(runtime)
+ if err != nil {
+ fmt.Println(err.Error())
+ os.Exit(1)
+ }
+
+ err = server.Serve()
+ if err != nil {
+ fmt.Println(err.Error())
+ os.Exit(1)
+ }
+}