summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/podman/commands.go2
-rw-r--r--cmd/podman/container.go1
-rw-r--r--cmd/podman/cp.go34
-rw-r--r--cmd/podman/create.go6
-rw-r--r--cmd/podman/diff.go7
-rw-r--r--cmd/podman/exec.go28
-rw-r--r--cmd/podman/export.go5
-rw-r--r--cmd/podman/generate_kube.go4
-rw-r--r--cmd/podman/kill.go7
-rw-r--r--cmd/podman/main.go88
-rw-r--r--cmd/podman/mount.go4
-rw-r--r--cmd/podman/play_kube.go21
-rw-r--r--cmd/podman/pod.go47
-rw-r--r--cmd/podman/pod_kill.go2
-rw-r--r--cmd/podman/pod_restart.go14
-rw-r--r--cmd/podman/pod_rm.go13
-rw-r--r--cmd/podman/pod_stop.go14
-rw-r--r--cmd/podman/pod_top.go25
-rw-r--r--cmd/podman/ps.go8
-rw-r--r--cmd/podman/restart.go30
-rw-r--r--cmd/podman/rm.go84
-rw-r--r--cmd/podman/run.go4
-rw-r--r--cmd/podman/run_test.go15
-rw-r--r--cmd/podman/search.go16
-rw-r--r--cmd/podman/shared/create.go76
-rw-r--r--cmd/podman/stop.go2
-rw-r--r--cmd/podman/top.go14
-rw-r--r--cmd/podman/tree.go77
-rw-r--r--cmd/podman/varlink/io.podman.varlink19
29 files changed, 138 insertions, 529 deletions
diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go
index 875b2aec8..baa349e1a 100644
--- a/cmd/podman/commands.go
+++ b/cmd/podman/commands.go
@@ -14,7 +14,6 @@ func getMainCommands() []*cobra.Command {
_attachCommand,
_commitCommand,
_createCommand,
- _diffCommand,
_execCommand,
_generateCommand,
_playCommand,
@@ -58,7 +57,6 @@ func getContainerSubCommands() []*cobra.Command {
_cleanupCommand,
_commitCommand,
_createCommand,
- _diffCommand,
_execCommand,
_exportCommand,
_killCommand,
diff --git a/cmd/podman/container.go b/cmd/podman/container.go
index 2e9cedbaa..743dec32f 100644
--- a/cmd/podman/container.go
+++ b/cmd/podman/container.go
@@ -52,6 +52,7 @@ var (
containerCommands = []*cobra.Command{
_containerExistsCommand,
_contInspectSubCommand,
+ _diffCommand,
_listSubCommand,
_logsCommand,
}
diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go
index 18fb2cb73..a0dd46260 100644
--- a/cmd/podman/cp.go
+++ b/cmd/podman/cp.go
@@ -1,10 +1,8 @@
package main
import (
- "io/ioutil"
"os"
"path/filepath"
- "strconv"
"strings"
"github.com/containers/buildah/pkg/chrootuser"
@@ -12,7 +10,6 @@ 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"
@@ -58,9 +55,6 @@ func cpCmd(c *cliconfig.CpValues) error {
if len(args) != 2 {
return errors.Errorf("you must provide a source path and a destination path")
}
- if os.Geteuid() != 0 {
- rootless.SetSkipStorageSetup(true)
- }
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
if err != nil {
@@ -90,34 +84,6 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin
ctr = destCtr
}
- if os.Geteuid() != 0 {
- s, err := ctr.State()
- if err != nil {
- return err
- }
- var became bool
- var ret int
- if s == libpod.ContainerStateRunning || s == libpod.ContainerStatePaused {
- data, err := ioutil.ReadFile(ctr.Config().ConmonPidFile)
- if err != nil {
- return errors.Wrapf(err, "cannot read conmon PID file %q", ctr.Config().ConmonPidFile)
- }
- conmonPid, err := strconv.Atoi(string(data))
- if err != nil {
- return errors.Wrapf(err, "cannot parse PID %q", data)
- }
- became, ret, err = rootless.JoinDirectUserAndMountNS(uint(conmonPid))
- } else {
- became, ret, err = rootless.BecomeRootInUserNS()
- }
- if err != nil {
- return err
- }
- if became {
- os.Exit(ret)
- }
- }
-
mountPoint, err := ctr.Mount()
if err != nil {
return err
diff --git a/cmd/podman/create.go b/cmd/podman/create.go
index bceb606f6..984323653 100644
--- a/cmd/podman/create.go
+++ b/cmd/podman/create.go
@@ -2,12 +2,10 @@ package main
import (
"fmt"
- "os"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/cmd/podman/shared"
- "github.com/containers/libpod/pkg/rootless"
"github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/spf13/cobra"
@@ -54,10 +52,6 @@ func createCmd(c *cliconfig.CreateValues) error {
return err
}
- if os.Geteuid() != 0 {
- rootless.SetSkipStorageSetup(true)
- }
-
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
diff --git a/cmd/podman/diff.go b/cmd/podman/diff.go
index e77e562d4..7f5a313f8 100644
--- a/cmd/podman/diff.go
+++ b/cmd/podman/diff.go
@@ -4,7 +4,7 @@ import (
"fmt"
"github.com/containers/buildah/pkg/formats"
"github.com/containers/libpod/cmd/podman/cliconfig"
- "github.com/containers/libpod/cmd/podman/libpodruntime"
+ "github.com/containers/libpod/pkg/adapter"
"github.com/containers/storage/pkg/archive"
"github.com/pkg/errors"
"github.com/spf13/cobra"
@@ -86,18 +86,17 @@ func diffCmd(c *cliconfig.DiffValues) error {
return errors.Errorf("container, image, or layer name must be specified: podman diff [options [...]] ID-NAME")
}
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
defer runtime.Shutdown(false)
to := c.InputArgs[0]
- changes, err := runtime.GetDiff("", to)
+ changes, err := runtime.Diff(c, to)
if err != nil {
return errors.Wrapf(err, "could not get changes for %q", to)
}
-
diffOutput := []diffOutputParams{}
outputFormat := c.Format
diff --git a/cmd/podman/exec.go b/cmd/podman/exec.go
index fc1c76e9f..f720a9aff 100644
--- a/cmd/podman/exec.go
+++ b/cmd/podman/exec.go
@@ -10,7 +10,6 @@ import (
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/cmd/podman/shared/parse"
"github.com/containers/libpod/libpod"
- "github.com/containers/libpod/pkg/rootless"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -67,7 +66,6 @@ func execCmd(c *cliconfig.ExecValues) error {
if c.Latest {
argStart = 0
}
- rootless.SetSkipStorageSetup(true)
cmd := args[argStart:]
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
if err != nil {
@@ -107,32 +105,6 @@ func execCmd(c *cliconfig.ExecValues) error {
}
- if os.Geteuid() != 0 {
- var became bool
- var ret int
-
- data, err := ioutil.ReadFile(ctr.Config().ConmonPidFile)
- if err == nil {
- conmonPid, err := strconv.Atoi(string(data))
- if err != nil {
- return errors.Wrapf(err, "cannot parse PID %q", data)
- }
- became, ret, err = rootless.JoinDirectUserAndMountNS(uint(conmonPid))
- } else {
- pid, err := ctr.PID()
- if err != nil {
- return err
- }
- became, ret, err = rootless.JoinNS(uint(pid), c.PreserveFDs)
- }
- if err != nil {
- return err
- }
- if became {
- os.Exit(ret)
- }
- }
-
// ENVIRONMENT VARIABLES
env := map[string]string{}
diff --git a/cmd/podman/export.go b/cmd/podman/export.go
index 92633facd..db031aaf2 100644
--- a/cmd/podman/export.go
+++ b/cmd/podman/export.go
@@ -6,7 +6,6 @@ import (
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/shared/parse"
"github.com/containers/libpod/pkg/adapter"
- "github.com/containers/libpod/pkg/rootless"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -41,10 +40,6 @@ func init() {
// exportCmd saves a container to a tarball on disk
func exportCmd(c *cliconfig.ExportValues) error {
- if os.Geteuid() != 0 {
- rootless.SetSkipStorageSetup(true)
- }
-
runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
diff --git a/cmd/podman/generate_kube.go b/cmd/podman/generate_kube.go
index 42cfba8d8..c58372899 100644
--- a/cmd/podman/generate_kube.go
+++ b/cmd/podman/generate_kube.go
@@ -5,7 +5,6 @@ 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"
podmanVersion "github.com/containers/libpod/version"
"github.com/ghodss/yaml"
"github.com/pkg/errors"
@@ -53,9 +52,6 @@ func generateKubeYAMLCmd(c *cliconfig.GenerateKubeValues) error {
servicePorts []v1.ServicePort
)
- if rootless.IsRootless() {
- return errors.Wrapf(libpod.ErrNotImplemented, "rootless users")
- }
args := c.InputArgs
if len(args) != 1 {
return errors.Errorf("you must provide exactly one container|pod ID or name")
diff --git a/cmd/podman/kill.go b/cmd/podman/kill.go
index 2c1e13eaf..6019fbfec 100644
--- a/cmd/podman/kill.go
+++ b/cmd/podman/kill.go
@@ -4,12 +4,10 @@ import (
"fmt"
"reflect"
- "github.com/containers/libpod/pkg/adapter"
- "github.com/opentracing/opentracing-go"
-
"github.com/containers/libpod/cmd/podman/cliconfig"
- "github.com/containers/libpod/pkg/rootless"
+ "github.com/containers/libpod/pkg/adapter"
"github.com/docker/docker/pkg/signal"
+ "github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -63,7 +61,6 @@ func killCmd(c *cliconfig.KillValues) error {
return err
}
- rootless.SetSkipStorageSetup(true)
runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
diff --git a/cmd/podman/main.go b/cmd/podman/main.go
index 1ea7f74bf..1ba58d1f3 100644
--- a/cmd/podman/main.go
+++ b/cmd/podman/main.go
@@ -3,13 +3,16 @@ package main
import (
"context"
"io"
+ "io/ioutil"
"log/syslog"
"os"
"runtime/pprof"
+ "strconv"
"strings"
"syscall"
"github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/libpod"
_ "github.com/containers/libpod/pkg/hooks/0.1.0"
"github.com/containers/libpod/pkg/rootless"
@@ -36,6 +39,7 @@ var (
// implemented.
var mainCommands = []*cobra.Command{
_buildCommand,
+ _diffCommand,
_eventsCommand,
_exportCommand,
_historyCommand,
@@ -59,36 +63,6 @@ var mainCommands = []*cobra.Command{
systemCommand.Command,
}
-var cmdsNotRequiringRootless = map[*cobra.Command]bool{
- _versionCommand: true,
- _createCommand: true,
- _execCommand: true,
- _cpCommand: true,
- _exportCommand: true,
- //// `info` must be executed in an user namespace.
- //// If this change, please also update libpod.refreshRootless()
- _loginCommand: true,
- _logoutCommand: true,
- _mountCommand: true,
- _killCommand: true,
- _pauseCommand: true,
- _podRmCommand: true,
- _podKillCommand: true,
- _podRestartCommand: true,
- _podStatsCommand: true,
- _podStopCommand: true,
- _podTopCommand: true,
- _restartCommand: true,
- &_psCommand: true,
- _rmCommand: true,
- _runCommand: true,
- _unpauseCommand: true,
- _searchCommand: true,
- _statsCommand: true,
- _stopCommand: true,
- _topCommand: true,
-}
-
var rootCmd = &cobra.Command{
Use: "podman",
Long: "manage pods and images",
@@ -152,18 +126,52 @@ func before(cmd *cobra.Command, args []string) error {
logrus.Errorf(err.Error())
os.Exit(1)
}
- if rootless.IsRootless() {
- notRequireRootless := cmdsNotRequiringRootless[cmd]
- if !notRequireRootless && !strings.HasPrefix(cmd.Use, "help") {
- became, ret, err := rootless.BecomeRootInUserNS()
- if err != nil {
- logrus.Errorf(err.Error())
- os.Exit(1)
- }
- if became {
- os.Exit(ret)
+ if os.Geteuid() != 0 && cmd != _searchCommand && cmd != _versionCommand && !strings.HasPrefix(cmd.Use, "help") {
+ podmanCmd := cliconfig.PodmanCommand{
+ cmd,
+ args,
+ MainGlobalOpts,
+ }
+ runtime, err := libpodruntime.GetRuntime(&podmanCmd)
+ if err != nil {
+ return errors.Wrapf(err, "could not get runtime")
+ }
+ defer runtime.Shutdown(false)
+
+ ctrs, err := runtime.GetRunningContainers()
+ if err != nil {
+ logrus.Errorf(err.Error())
+ os.Exit(1)
+ }
+ var became bool
+ var ret int
+ if len(ctrs) == 0 {
+ became, ret, err = rootless.BecomeRootInUserNS()
+ } else {
+ for _, ctr := range ctrs {
+ data, err := ioutil.ReadFile(ctr.Config().ConmonPidFile)
+ if err != nil {
+ logrus.Errorf(err.Error())
+ os.Exit(1)
+ }
+ conmonPid, err := strconv.Atoi(string(data))
+ if err != nil {
+ logrus.Errorf(err.Error())
+ os.Exit(1)
+ }
+ became, ret, err = rootless.JoinUserAndMountNS(uint(conmonPid))
+ if err == nil {
+ break
+ }
}
}
+ if err != nil {
+ logrus.Errorf(err.Error())
+ os.Exit(1)
+ }
+ if became {
+ os.Exit(ret)
+ }
}
if MainGlobalOpts.Syslog {
diff --git a/cmd/podman/mount.go b/cmd/podman/mount.go
index 138548097..a70684a39 100644
--- a/cmd/podman/mount.go
+++ b/cmd/podman/mount.go
@@ -60,10 +60,6 @@ type jsonMountPoint struct {
}
func mountCmd(c *cliconfig.MountValues) error {
- if os.Geteuid() != 0 {
- rootless.SetSkipStorageSetup(true)
- }
-
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
diff --git a/cmd/podman/play_kube.go b/cmd/podman/play_kube.go
index b468a7a89..cbe961279 100644
--- a/cmd/podman/play_kube.go
+++ b/cmd/podman/play_kube.go
@@ -15,7 +15,6 @@ import (
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/image"
ns "github.com/containers/libpod/pkg/namespaces"
- "github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/spec"
"github.com/containers/storage"
"github.com/cri-o/ocicni/pkg/ocicni"
@@ -73,9 +72,6 @@ func playKubeYAMLCmd(c *cliconfig.KubePlayValues) error {
)
ctx := getContext()
- if rootless.IsRootless() {
- return errors.Wrapf(libpod.ErrNotImplemented, "rootless users")
- }
args := c.InputArgs
if len(args) > 1 {
return errors.New("you can only play one kubernetes file at a time")
@@ -243,6 +239,9 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container
envs map[string]string
)
+ // The default for MemorySwappiness is -1, not 0
+ containerConfig.Resources.MemorySwappiness = -1
+
containerConfig.Runtime = runtime
containerConfig.Image = containerYAML.Image
containerConfig.ImageID = newImage.ID()
@@ -270,7 +269,19 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container
}
}
- containerConfig.Command = containerYAML.Command
+ containerConfig.Command = []string{}
+ if imageData != nil && imageData.Config != nil {
+ containerConfig.Command = append(containerConfig.Command, imageData.Config.Entrypoint...)
+ }
+ if len(containerConfig.Command) != 0 {
+ containerConfig.Command = append(containerConfig.Command, containerYAML.Command...)
+ } else if imageData != nil && imageData.Config != nil {
+ containerConfig.Command = append(containerConfig.Command, imageData.Config.Cmd...)
+ }
+ if imageData != nil && len(containerConfig.Command) == 0 {
+ return nil, errors.Errorf("No command specified in container YAML or as CMD or ENTRYPOINT in this image for %s", containerConfig.Name)
+ }
+
containerConfig.StopSignal = 15
// If the user does not pass in ID mappings, just set to basics
diff --git a/cmd/podman/pod.go b/cmd/podman/pod.go
index 9a9c7a702..2d9bca21d 100644
--- a/cmd/podman/pod.go
+++ b/cmd/podman/pod.go
@@ -1,12 +1,7 @@
package main
import (
- "os"
-
"github.com/containers/libpod/cmd/podman/cliconfig"
- "github.com/containers/libpod/pkg/adapter"
- "github.com/containers/libpod/pkg/rootless"
- "github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -39,48 +34,6 @@ var podSubCommands = []*cobra.Command{
_podUnpauseCommand,
}
-func joinPodNS(runtime *adapter.LocalRuntime, all, latest bool, inputArgs []string) ([]string, bool, bool, error) {
- if rootless.IsRootless() {
- if os.Geteuid() == 0 {
- return []string{rootless.Argument()}, false, false, nil
- } else {
- var err error
- var pods []*adapter.Pod
- if all {
- pods, err = runtime.GetAllPods()
- if err != nil {
- return nil, false, false, errors.Wrapf(err, "unable to get pods")
- }
- } else if latest {
- pod, err := runtime.GetLatestPod()
- if err != nil {
- return nil, false, false, errors.Wrapf(err, "unable to get latest pod")
- }
- pods = append(pods, pod)
- } else {
- for _, i := range inputArgs {
- pod, err := runtime.LookupPod(i)
- if err != nil {
- return nil, false, false, errors.Wrapf(err, "unable to lookup pod %s", i)
- }
- pods = append(pods, pod)
- }
- }
- for _, p := range pods {
- _, ret, err := runtime.JoinOrCreateRootlessPod(p)
- if err != nil {
- return nil, false, false, err
- }
- if ret != 0 {
- os.Exit(ret)
- }
- }
- os.Exit(0)
- }
- }
- return inputArgs, all, latest, nil
-}
-
func init() {
podCommand.AddCommand(podSubCommands...)
podCommand.SetHelpTemplate(HelpTemplate())
diff --git a/cmd/podman/pod_kill.go b/cmd/podman/pod_kill.go
index c538674a4..ebd7db762 100644
--- a/cmd/podman/pod_kill.go
+++ b/cmd/podman/pod_kill.go
@@ -6,7 +6,6 @@ import (
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/pkg/adapter"
- "github.com/containers/libpod/pkg/rootless"
"github.com/docker/docker/pkg/signal"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -49,7 +48,6 @@ func init() {
// podKillCmd kills one or more pods with a signal
func podKillCmd(c *cliconfig.PodKillValues) error {
- rootless.SetSkipStorageSetup(true)
runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
diff --git a/cmd/podman/pod_restart.go b/cmd/podman/pod_restart.go
index 9c8d28424..0765b98db 100644
--- a/cmd/podman/pod_restart.go
+++ b/cmd/podman/pod_restart.go
@@ -2,11 +2,9 @@ package main
import (
"fmt"
- "os"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/pkg/adapter"
- "github.com/containers/libpod/pkg/rootless"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -48,24 +46,12 @@ func init() {
func podRestartCmd(c *cliconfig.PodRestartValues) error {
var lastError error
- if os.Geteuid() != 0 {
- rootless.SetSkipStorageSetup(true)
- }
runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
defer runtime.Shutdown(false)
- if rootless.IsRootless() {
- var err error
-
- c.InputArgs, c.All, c.Latest, err = joinPodNS(runtime, c.All, c.Latest, c.InputArgs)
- if err != nil {
- return err
- }
- }
-
restartIDs, conErrors, restartErrors := runtime.RestartPods(getContext(), c)
for _, p := range restartIDs {
diff --git a/cmd/podman/pod_rm.go b/cmd/podman/pod_rm.go
index 735676f8a..cd9f23fe1 100644
--- a/cmd/podman/pod_rm.go
+++ b/cmd/podman/pod_rm.go
@@ -2,11 +2,9 @@ package main
import (
"fmt"
- "os"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/pkg/adapter"
- "github.com/containers/libpod/pkg/rootless"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -48,23 +46,12 @@ func init() {
// podRmCmd deletes pods
func podRmCmd(c *cliconfig.PodRmValues) error {
- if os.Geteuid() != 0 {
- rootless.SetSkipStorageSetup(true)
- }
runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
defer runtime.Shutdown(false)
- if rootless.IsRootless() {
- var err error
- c.InputArgs, c.All, c.Latest, err = joinPodNS(runtime, c.All, c.Latest, c.InputArgs)
- if err != nil {
- return err
- }
- }
-
podRmIds, podRmErrors := runtime.RemovePods(getContext(), c)
for _, p := range podRmIds {
fmt.Println(p)
diff --git a/cmd/podman/pod_stop.go b/cmd/podman/pod_stop.go
index 754a3a7db..f1b0ac51f 100644
--- a/cmd/podman/pod_stop.go
+++ b/cmd/podman/pod_stop.go
@@ -2,11 +2,9 @@ package main
import (
"fmt"
- "os"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/pkg/adapter"
- "github.com/containers/libpod/pkg/rootless"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -48,24 +46,12 @@ func init() {
}
func podStopCmd(c *cliconfig.PodStopValues) error {
- if os.Geteuid() != 0 {
- rootless.SetSkipStorageSetup(true)
- }
-
runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
defer runtime.Shutdown(false)
- if rootless.IsRootless() {
- var err error
- c.InputArgs, c.All, c.Latest, err = joinPodNS(runtime, c.All, c.Latest, c.InputArgs)
- if err != nil {
- return err
- }
- }
-
podStopIds, podStopErrors := runtime.StopPods(getContext(), c)
for _, p := range podStopIds {
fmt.Println(p)
diff --git a/cmd/podman/pod_top.go b/cmd/podman/pod_top.go
index f65d66df6..0d74dc3d6 100644
--- a/cmd/podman/pod_top.go
+++ b/cmd/podman/pod_top.go
@@ -9,7 +9,6 @@ import (
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/libpod"
- "github.com/containers/libpod/pkg/rootless"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -54,10 +53,6 @@ func podTopCmd(c *cliconfig.PodTopValues) error {
)
args := c.InputArgs
- if os.Geteuid() != 0 {
- rootless.SetSkipStorageSetup(true)
- }
-
if c.ListDescriptors {
descriptors, err := libpod.GetContainerPidInformationDescriptors()
if err != nil {
@@ -83,26 +78,6 @@ func podTopCmd(c *cliconfig.PodTopValues) error {
descriptors = args[1:]
}
- if os.Geteuid() != 0 {
- var pod *adapter.Pod
- var err error
- if c.Latest {
- pod, err = runtime.GetLatestPod()
- } else {
- pod, err = runtime.LookupPod(c.InputArgs[0])
- }
- if err != nil {
- return errors.Wrapf(err, "unable to lookup requested container")
- }
- became, ret, err := runtime.JoinOrCreateRootlessPod(pod)
- if err != nil {
- return err
- }
- if became {
- os.Exit(ret)
- }
- }
-
w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0)
psOutput, err := runtime.PodTop(c, descriptors)
if err != nil {
diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go
index 1f8db2739..759a03b86 100644
--- a/cmd/podman/ps.go
+++ b/cmd/podman/ps.go
@@ -17,7 +17,6 @@ import (
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod"
- "github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/util"
"github.com/cri-o/ocicni/pkg/ocicni"
"github.com/docker/go-units"
@@ -202,13 +201,14 @@ func init() {
}
func psCmd(c *cliconfig.PsValues) error {
- if os.Geteuid() != 0 {
- rootless.SetSkipStorageSetup(true)
- }
if c.Bool("trace") {
span, _ := opentracing.StartSpanFromContext(Ctx, "psCmd")
defer span.Finish()
}
+ // TODO disable when single rootless userns merges
+ if c.Bool("size") && os.Geteuid() != 0 {
+ return errors.New("the --size option is not presently supported without root")
+ }
var watch bool
diff --git a/cmd/podman/restart.go b/cmd/podman/restart.go
index e6a6d8434..1553ab805 100644
--- a/cmd/podman/restart.go
+++ b/cmd/podman/restart.go
@@ -1,13 +1,10 @@
package main
import (
- "os"
-
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod"
- "github.com/containers/libpod/pkg/rootless"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -57,19 +54,6 @@ func restartCmd(c *cliconfig.RestartValues) error {
restartContainers []*libpod.Container
)
- if os.Geteuid() != 0 {
- rootless.SetSkipStorageSetup(true)
- }
- if rootless.IsRootless() {
- // If we are in the re-execed rootless environment,
- // override the arg to deal only with one container.
- if os.Geteuid() == 0 {
- c.All = false
- c.Latest = false
- c.InputArgs = []string{rootless.Argument()}
- }
- }
-
args := c.InputArgs
runOnly := c.Running
all := c.All
@@ -115,20 +99,6 @@ func restartCmd(c *cliconfig.RestartValues) error {
}
}
- if os.Geteuid() != 0 {
- // In rootless mode we can deal with one container at at time.
- for _, c := range restartContainers {
- _, ret, err := joinContainerOrCreateRootlessUserNS(runtime, c)
- if err != nil {
- return err
- }
- if ret != 0 {
- os.Exit(ret)
- }
- }
- os.Exit(0)
- }
-
maxWorkers := shared.Parallelize("restart")
if c.GlobalIsSet("max-workers") {
maxWorkers = c.GlobalFlags.MaxWorks
diff --git a/cmd/podman/rm.go b/cmd/podman/rm.go
index 253771e14..52e281402 100644
--- a/cmd/podman/rm.go
+++ b/cmd/podman/rm.go
@@ -2,16 +2,12 @@ package main
import (
"fmt"
- "io/ioutil"
- "os"
- "strconv"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/image"
- "github.com/containers/libpod/pkg/rootless"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -52,39 +48,11 @@ func init() {
markFlagHiddenForRemoteClient("latest", flags)
}
-func joinContainerOrCreateRootlessUserNS(runtime *libpod.Runtime, ctr *libpod.Container) (bool, int, error) {
- if os.Geteuid() == 0 {
- return false, 0, nil
- }
- s, err := ctr.State()
- if err != nil {
- return false, -1, err
- }
- opts := rootless.Opts{
- Argument: ctr.ID(),
- }
- if s == libpod.ContainerStateRunning || s == libpod.ContainerStatePaused {
- data, err := ioutil.ReadFile(ctr.Config().ConmonPidFile)
- if err != nil {
- return false, -1, errors.Wrapf(err, "cannot read conmon PID file %q", ctr.Config().ConmonPidFile)
- }
- conmonPid, err := strconv.Atoi(string(data))
- if err != nil {
- return false, -1, errors.Wrapf(err, "cannot parse PID %q", data)
- }
- return rootless.JoinDirectUserAndMountNSWithOpts(uint(conmonPid), &opts)
- }
- return rootless.BecomeRootInUserNSWithOpts(&opts)
-}
-
// saveCmd saves the image to either docker-archive or oci
func rmCmd(c *cliconfig.RmValues) error {
var (
deleteFuncs []shared.ParallelWorkerInput
)
- if os.Geteuid() != 0 {
- rootless.SetSkipStorageSetup(true)
- }
ctx := getContext()
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
@@ -93,58 +61,6 @@ func rmCmd(c *cliconfig.RmValues) error {
}
defer runtime.Shutdown(false)
- if rootless.IsRootless() {
- // When running in rootless mode we cannot manage different containers and
- // user namespaces from the same context, so be sure to re-exec once for each
- // container we are dealing with.
- // What we do is to first collect all the containers we want to delete, then
- // we re-exec in each of the container namespaces and from there remove the single
- // container.
- var container *libpod.Container
- if os.Geteuid() == 0 {
- // We are in the namespace, override InputArgs with the single
- // argument that was passed down to us.
- c.All = false
- c.Latest = false
- c.InputArgs = []string{rootless.Argument()}
- } else {
- exitCode = 0
- var containers []*libpod.Container
- if c.All {
- containers, err = runtime.GetContainers()
- } else if c.Latest {
- container, err = runtime.GetLatestContainer()
- if err != nil {
- return errors.Wrapf(err, "unable to get latest pod")
- }
- containers = append(containers, container)
- } else {
- for _, c := range c.InputArgs {
- container, err = runtime.LookupContainer(c)
- if err != nil {
- if errors.Cause(err) == libpod.ErrNoSuchCtr {
- exitCode = 1
- continue
- }
- return err
- }
- containers = append(containers, container)
- }
- }
- // Now we really delete the containers.
- for _, c := range containers {
- _, ret, err := joinContainerOrCreateRootlessUserNS(runtime, c)
- if err != nil {
- return err
- }
- if ret != 0 {
- os.Exit(ret)
- }
- }
- os.Exit(exitCode)
- }
- }
-
failureCnt := 0
delContainers, err := getAllOrLatestContainers(&c.PodmanCommand, runtime, -1, "all")
if err != nil {
diff --git a/cmd/podman/run.go b/cmd/podman/run.go
index 3c26e98c1..4bd469106 100644
--- a/cmd/podman/run.go
+++ b/cmd/podman/run.go
@@ -12,7 +12,6 @@ import (
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod"
- "github.com/containers/libpod/pkg/rootless"
opentracing "github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -57,9 +56,6 @@ func runCmd(c *cliconfig.RunValues) error {
if err := createInit(&c.PodmanCommand); err != nil {
return err
}
- if os.Geteuid() != 0 {
- rootless.SetSkipStorageSetup(true)
- }
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
if err != nil {
diff --git a/cmd/podman/run_test.go b/cmd/podman/run_test.go
index a896f1dc7..0bf9cb4d9 100644
--- a/cmd/podman/run_test.go
+++ b/cmd/podman/run_test.go
@@ -8,6 +8,7 @@ import (
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/pkg/inspect"
cc "github.com/containers/libpod/pkg/spec"
+ "github.com/containers/libpod/pkg/sysinfo"
"github.com/docker/go-units"
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
spec "github.com/opencontainers/runtime-spec/specs-go"
@@ -16,8 +17,9 @@ import (
)
var (
- cmd = []string{"podman", "test", "alpine"}
- CLI *cliconfig.PodmanCommand
+ sysInfo = sysinfo.New(true)
+ cmd = []string{"podman", "test", "alpine"}
+ CLI *cliconfig.PodmanCommand
)
// generates a mocked ImageData structure based on alpine
@@ -100,6 +102,9 @@ func TestPIDsLimit(t *testing.T) {
if runtime.GOOS != "linux" {
t.Skip("seccomp, which is enabled by default, is only supported on Linux")
}
+ if !sysInfo.PidsLimit {
+ t.Skip("running test not supported by the host system")
+ }
args := []string{"--pids-limit", "22"}
a := createCLI(args)
a.InputArgs = args
@@ -119,6 +124,9 @@ func TestBLKIOWeightDevice(t *testing.T) {
if runtime.GOOS != "linux" {
t.Skip("seccomp, which is enabled by default, is only supported on Linux")
}
+ if !sysInfo.BlkioWeightDevice {
+ t.Skip("running test not supported by the host system")
+ }
args := []string{"--blkio-weight-device", "/dev/zero:100"}
a := createCLI(args)
a.InputArgs = args
@@ -137,6 +145,9 @@ func TestMemorySwap(t *testing.T) {
if runtime.GOOS != "linux" {
t.Skip("seccomp, which is enabled by default, is only supported on Linux")
}
+ if !sysInfo.SwapLimit {
+ t.Skip("running test not supported by the host system")
+ }
args := []string{"--memory-swap", "45m", "--memory", "40m"}
a := createCLI(args)
a.InputArgs = args
diff --git a/cmd/podman/search.go b/cmd/podman/search.go
index a10b9d419..e614887fc 100644
--- a/cmd/podman/search.go
+++ b/cmd/podman/search.go
@@ -83,11 +83,25 @@ func searchCmd(c *cliconfig.SearchValues) error {
if len(results) == 0 {
return nil
}
- out := formats.StdoutTemplateArray{Output: searchToGeneric(results), Template: format, Fields: genSearchOutputMap()}
+ out := formats.StdoutTemplateArray{Output: searchToGeneric(results), Template: format, Fields: searchHeaderMap()}
formats.Writer(out).Out()
return nil
}
+// searchHeaderMap returns the headers of a SearchResult.
+func searchHeaderMap() map[string]string {
+ s := new(image.SearchResult)
+ v := reflect.Indirect(reflect.ValueOf(s))
+ values := make(map[string]string, v.NumField())
+
+ for i := 0; i < v.NumField(); i++ {
+ key := v.Type().Field(i).Name
+ value := key
+ values[key] = strings.ToUpper(splitCamelCase(value))
+ }
+ return values
+}
+
func genSearchFormat(format string) string {
if format != "" {
// "\t" from the command line is not being recognized as a tab
diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go
index d927e5bf6..cd82e4f1c 100644
--- a/cmd/podman/shared/create.go
+++ b/cmd/podman/shared/create.go
@@ -5,7 +5,6 @@ import (
"encoding/json"
"fmt"
"io"
- "io/ioutil"
"os"
"path/filepath"
"strconv"
@@ -75,7 +74,8 @@ func CreateContainer(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l
imageName := ""
var data *inspect.ImageData = nil
- if rootfs == "" && !rootless.SkipStorageSetup() {
+ // Set the storage if we are running as euid == 0 and there is no rootfs specified
+ if rootfs == "" && os.Geteuid() == 0 {
var writer io.Writer
if !c.Bool("quiet") {
writer = os.Stderr
@@ -758,71 +758,6 @@ type namespace interface {
Container() string
}
-func joinOrCreateRootlessUserNamespace(createConfig *cc.CreateConfig, runtime *libpod.Runtime) (bool, int, error) {
- if os.Geteuid() == 0 {
- return false, 0, nil
- }
-
- if createConfig.Pod != "" {
- pod, err := runtime.LookupPod(createConfig.Pod)
- if err != nil {
- return false, -1, err
- }
- inspect, err := pod.Inspect()
- for _, ctr := range inspect.Containers {
- prevCtr, err := runtime.LookupContainer(ctr.ID)
- if err != nil {
- return false, -1, err
- }
- s, err := prevCtr.State()
- if err != nil {
- return false, -1, err
- }
- if s != libpod.ContainerStateRunning && s != libpod.ContainerStatePaused {
- continue
- }
- data, err := ioutil.ReadFile(prevCtr.Config().ConmonPidFile)
- if err != nil {
- return false, -1, errors.Wrapf(err, "cannot read conmon PID file %q", prevCtr.Config().ConmonPidFile)
- }
- conmonPid, err := strconv.Atoi(string(data))
- if err != nil {
- return false, -1, errors.Wrapf(err, "cannot parse PID %q", data)
- }
- return rootless.JoinDirectUserAndMountNS(uint(conmonPid))
- }
- }
-
- namespacesStr := []string{string(createConfig.IpcMode), string(createConfig.NetMode), string(createConfig.UsernsMode), string(createConfig.PidMode), string(createConfig.UtsMode)}
- for _, i := range namespacesStr {
- if cc.IsNS(i) {
- return rootless.JoinNSPath(cc.NS(i))
- }
- }
-
- namespaces := []namespace{createConfig.IpcMode, createConfig.NetMode, createConfig.UsernsMode, createConfig.PidMode, createConfig.UtsMode}
- for _, i := range namespaces {
- if i.IsContainer() {
- ctr, err := runtime.LookupContainer(i.Container())
- if err != nil {
- return false, -1, err
- }
- pid, err := ctr.PID()
- if err != nil {
- return false, -1, err
- }
- if pid == 0 {
- if createConfig.Pod != "" {
- continue
- }
- return false, -1, errors.Errorf("dependency container %s is not running", ctr.ID())
- }
- return rootless.JoinNS(uint(pid), 0)
- }
- }
- return rootless.BecomeRootInUserNS()
-}
-
func CreateContainerFromCreateConfig(r *libpod.Runtime, createConfig *cc.CreateConfig, ctx context.Context, pod *libpod.Pod) (*libpod.Container, error) {
runtimeSpec, err := cc.CreateConfigToOCISpec(createConfig)
if err != nil {
@@ -833,13 +768,6 @@ func CreateContainerFromCreateConfig(r *libpod.Runtime, createConfig *cc.CreateC
if err != nil {
return nil, err
}
- became, ret, err := joinOrCreateRootlessUserNamespace(createConfig, r)
- if err != nil {
- return nil, err
- }
- if became {
- os.Exit(ret)
- }
ctr, err := r.NewContainer(ctx, runtimeSpec, options...)
if err != nil {
diff --git a/cmd/podman/stop.go b/cmd/podman/stop.go
index 2a1470ad0..e27be64f6 100644
--- a/cmd/podman/stop.go
+++ b/cmd/podman/stop.go
@@ -7,7 +7,6 @@ import (
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/adapter"
- "github.com/containers/libpod/pkg/rootless"
"github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/spf13/cobra"
@@ -59,7 +58,6 @@ func stopCmd(c *cliconfig.StopValues) error {
defer span.Finish()
}
- rootless.SetSkipStorageSetup(true)
runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
diff --git a/cmd/podman/top.go b/cmd/podman/top.go
index 2512631c1..5d394d2d6 100644
--- a/cmd/podman/top.go
+++ b/cmd/podman/top.go
@@ -9,7 +9,6 @@ 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/pkg/errors"
"github.com/spf13/cobra"
)
@@ -77,7 +76,6 @@ func topCmd(c *cliconfig.TopValues) error {
return errors.Errorf("you must provide the name or id of a running container")
}
- rootless.SetSkipStorageSetup(true)
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
@@ -104,18 +102,6 @@ func topCmd(c *cliconfig.TopValues) error {
if conStat != libpod.ContainerStateRunning {
return errors.Errorf("top can only be used on running containers")
}
-
- pid, err := container.PID()
- if err != nil {
- return err
- }
- became, ret, err := rootless.JoinNS(uint(pid), 0)
- if err != nil {
- return err
- }
- if became {
- os.Exit(ret)
- }
psOutput, err := container.GetContainerPidInformation(descriptors)
if err != nil {
return err
diff --git a/cmd/podman/tree.go b/cmd/podman/tree.go
index c56e35aef..371e88495 100644
--- a/cmd/podman/tree.go
+++ b/cmd/podman/tree.go
@@ -5,9 +5,9 @@ import (
"fmt"
"github.com/containers/libpod/cmd/podman/cliconfig"
- "github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/libpod/image"
- units "github.com/docker/go-units"
+ "github.com/containers/libpod/pkg/adapter"
+ "github.com/docker/go-units"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -41,16 +41,6 @@ func init() {
treeCommand.Flags().BoolVar(&treeCommand.WhatRequires, "whatrequires", false, "Show all child images and layers of the specified image")
}
-// infoImage keep information of Image along with all associated layers
-type infoImage struct {
- // id of image
- id string
- // tags of image
- tags []string
- // layers stores all layers of image.
- layers []image.LayerInfo
-}
-
func treeCmd(c *cliconfig.TreeValues) error {
args := c.InputArgs
if len(args) == 0 {
@@ -60,46 +50,33 @@ func treeCmd(c *cliconfig.TreeValues) error {
return errors.Errorf("you must provide at most 1 argument")
}
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
defer runtime.Shutdown(false)
-
- img, err := runtime.ImageRuntime().NewFromLocal(args[0])
+ imageInfo, layerInfoMap, img, err := runtime.Tree(c)
if err != nil {
return err
}
+ return printTree(imageInfo, layerInfoMap, img, c.WhatRequires)
+}
- // Fetch map of image-layers, which is used for printing output.
- layerInfoMap, err := image.GetLayersMapWithImageInfo(runtime.ImageRuntime())
- if err != nil {
- return errors.Wrapf(err, "error while retriving layers of image %q", img.InputName)
- }
-
- // Create an imageInfo and fill the image and layer info
- imageInfo := &infoImage{
- id: img.ID(),
- tags: img.Names(),
- }
-
+func printTree(imageInfo *image.InfoImage, layerInfoMap map[string]*image.LayerInfo, img *adapter.ContainerImage, whatRequires bool) error {
size, err := img.Size(context.Background())
if err != nil {
- return errors.Wrapf(err, "error while retriving image size")
+ return err
}
- fmt.Printf("Image ID: %s\n", imageInfo.id[:12])
- fmt.Printf("Tags:\t %s\n", imageInfo.tags)
+
+ fmt.Printf("Image ID: %s\n", imageInfo.ID[:12])
+ fmt.Printf("Tags:\t %s\n", imageInfo.Tags)
fmt.Printf("Size:\t %v\n", units.HumanSizeWithPrecision(float64(*size), 4))
fmt.Printf(fmt.Sprintf("Image Layers\n"))
- if !c.WhatRequires {
+ if !whatRequires {
// fill imageInfo with layers associated with image.
// the layers will be filled such that
// (Start)RootLayer->...intermediate Parent Layer(s)-> TopLayer(End)
- err := buildImageHierarchyMap(imageInfo, layerInfoMap, img.TopLayer())
- if err != nil {
- return err
- }
// Build output from imageInfo into buffer
printImageHierarchy(imageInfo)
@@ -108,30 +85,8 @@ func treeCmd(c *cliconfig.TreeValues) error {
// the layers will be filled such that
// (Start)TopLayer->...intermediate Child Layer(s)-> Child TopLayer(End)
// (Forks)... intermediate Child Layer(s) -> Child Top Layer(End)
- err := printImageChildren(layerInfoMap, img.TopLayer(), "", true)
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// Stores hierarchy of images such that all parent layers using which image is built are stored in imageInfo
-// Layers are added such that (Start)RootLayer->...intermediate Parent Layer(s)-> TopLayer(End)
-func buildImageHierarchyMap(imageInfo *infoImage, layerMap map[string]*image.LayerInfo, layerID string) error {
- if layerID == "" {
- return nil
- }
- ll, ok := layerMap[layerID]
- if !ok {
- return fmt.Errorf("lookup error: layerid %s not found", layerID)
+ return printImageChildren(layerInfoMap, img.TopLayer(), "", true)
}
- if err := buildImageHierarchyMap(imageInfo, layerMap, ll.ParentID); err != nil {
- return err
- }
-
- imageInfo.layers = append(imageInfo.layers, *ll)
return nil
}
@@ -175,14 +130,14 @@ func printImageChildren(layerMap map[string]*image.LayerInfo, layerID string, pr
}
// prints the layers info of image
-func printImageHierarchy(imageInfo *infoImage) {
- for count, l := range imageInfo.layers {
+func printImageHierarchy(imageInfo *image.InfoImage) {
+ for count, l := range imageInfo.Layers {
var tags string
intend := middleItem
if len(l.RepoTags) > 0 {
tags = fmt.Sprintf(" Top Layer of: %s", l.RepoTags)
}
- if count == len(imageInfo.layers)-1 {
+ if count == len(imageInfo.Layers)-1 {
intend = lastItem
}
fmt.Printf("%s ID: %s Size: %7v%s\n", intend, l.ID[:12], units.HumanSizeWithPrecision(float64(l.Size), 4), tags)
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 5e996f46b..92fdcd20f 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -68,7 +68,8 @@ type Image (
virtualSize: int,
containers: int,
labels: [string]string,
- isParent: bool
+ isParent: bool,
+ topLayer: string
)
# ImageHistory describes the returned structure from ImageHistory.
@@ -461,6 +462,13 @@ type Event(
type: string
)
+type DiffInfo(
+ # path that is different
+ path: string,
+ # Add, Delete, Modify
+ changeType: string
+)
+
# GetVersion returns version and build information of the podman service
method GetVersion() -> (
version: string,
@@ -1154,6 +1162,15 @@ method LoadImage(name: string, inputFile: string, quiet: bool, deleteFile: bool)
# GetEvents returns known libpod events filtered by the options provided.
method GetEvents(filter: []string, since: string, until: string) -> (events: Event)
+# Diff returns a diff between libpod objects
+method Diff(name: string) -> (diffs: []DiffInfo)
+
+# GetLayersMapWithImageInfo is for the development of Podman and should not be used.
+method GetLayersMapWithImageInfo() -> (layerMap: string)
+
+# BuildImageHierarchyMap is for the development of Podman and should not be used.
+method BuildImageHierarchyMap(name: string) -> (imageInfo: string)
+
# ImageNotFound means the image could not be found by the provided name or ID in local storage.
error ImageNotFound (id: string, reason: string)