summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/podman/attach.go3
-rw-r--r--cmd/podman/cliconfig/defaults.go21
-rw-r--r--cmd/podman/commands.go6
-rw-r--r--cmd/podman/common.go14
-rw-r--r--cmd/podman/container.go3
-rw-r--r--cmd/podman/cp.go43
-rw-r--r--cmd/podman/create.go16
-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.go98
-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.go153
-rw-r--r--cmd/podman/run_test.go18
-rw-r--r--cmd/podman/search.go16
-rw-r--r--cmd/podman/shared/create.go112
-rw-r--r--cmd/podman/shared/intermediate.go465
-rw-r--r--cmd/podman/shared/intermediate_novarlink.go70
-rw-r--r--cmd/podman/shared/intermediate_varlink.go427
-rw-r--r--cmd/podman/sigproxy.go35
-rw-r--r--cmd/podman/start.go5
-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/utils.go196
-rw-r--r--cmd/podman/varlink/io.podman.varlink238
38 files changed, 1278 insertions, 1067 deletions
diff --git a/cmd/podman/attach.go b/cmd/podman/attach.go
index 86e89cfd7..f326f53c3 100644
--- a/cmd/podman/attach.go
+++ b/cmd/podman/attach.go
@@ -6,6 +6,7 @@ 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/adapter"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -78,7 +79,7 @@ func attachCmd(c *cliconfig.AttachValues) error {
}
// If the container is in a pod, also set to recursively start dependencies
- if err := startAttachCtr(ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, c.SigProxy, false, ctr.PodID() != ""); err != nil && errors.Cause(err) != libpod.ErrDetach {
+ if err := adapter.StartAttachCtr(getContext(), ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, c.SigProxy, false, ctr.PodID() != ""); err != nil && errors.Cause(err) != libpod.ErrDetach {
return errors.Wrapf(err, "error attaching to container %s", ctr.ID())
}
diff --git a/cmd/podman/cliconfig/defaults.go b/cmd/podman/cliconfig/defaults.go
new file mode 100644
index 000000000..d5dae0874
--- /dev/null
+++ b/cmd/podman/cliconfig/defaults.go
@@ -0,0 +1,21 @@
+package cliconfig
+
+const (
+ // DefaultSystemD value
+ DefaultSystemD bool = true
+)
+
+var (
+ // DefaultHealthCheckInterval default value
+ DefaultHealthCheckInterval = "30s"
+ // DefaultHealthCheckRetries default value
+ DefaultHealthCheckRetries uint = 3
+ // DefaultHealthCheckStartPeriod default value
+ DefaultHealthCheckStartPeriod = "0s"
+ // DefaultHealthCheckTimeout default value
+ DefaultHealthCheckTimeout = "30s"
+ // DefaultImageVolume default value
+ DefaultImageVolume = "bind"
+ // DefaultShmSize default value
+ DefaultShmSize = "65536k"
+)
diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go
index 875b2aec8..e9afcbc06 100644
--- a/cmd/podman/commands.go
+++ b/cmd/podman/commands.go
@@ -13,8 +13,6 @@ func getMainCommands() []*cobra.Command {
rootCommands := []*cobra.Command{
_attachCommand,
_commitCommand,
- _createCommand,
- _diffCommand,
_execCommand,
_generateCommand,
_playCommand,
@@ -27,7 +25,6 @@ func getMainCommands() []*cobra.Command {
_refreshCommand,
_restartCommand,
_rmCommand,
- _runCommand,
_searchCommand,
_startCommand,
_statsCommand,
@@ -57,8 +54,6 @@ func getContainerSubCommands() []*cobra.Command {
_checkpointCommand,
_cleanupCommand,
_commitCommand,
- _createCommand,
- _diffCommand,
_execCommand,
_exportCommand,
_killCommand,
@@ -70,7 +65,6 @@ func getContainerSubCommands() []*cobra.Command {
_restartCommand,
_restoreCommand,
_rmCommand,
- _runCommand,
_runlabelCommand,
_startCommand,
_statsCommand,
diff --git a/cmd/podman/common.go b/cmd/podman/common.go
index 10fed053e..ba4a3f519 100644
--- a/cmd/podman/common.go
+++ b/cmd/podman/common.go
@@ -294,19 +294,19 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"set a healthcheck command for the container ('none' disables the existing healthcheck)",
)
createFlags.String(
- "healthcheck-interval", "30s",
+ "healthcheck-interval", cliconfig.DefaultHealthCheckInterval,
"set an interval for the healthchecks (a value of disable results in no automatic timer setup)",
)
createFlags.Uint(
- "healthcheck-retries", 3,
+ "healthcheck-retries", cliconfig.DefaultHealthCheckRetries,
"the number of retries allowed before a healthcheck is considered to be unhealthy",
)
createFlags.String(
- "healthcheck-start-period", "0s",
+ "healthcheck-start-period", cliconfig.DefaultHealthCheckStartPeriod,
"the initialization time needed for a container to bootstrap",
)
createFlags.String(
- "healthcheck-timeout", "30s",
+ "healthcheck-timeout", cliconfig.DefaultHealthCheckTimeout,
"the maximum time allowed to complete the healthcheck before an interval is considered failed",
)
createFlags.StringP(
@@ -314,7 +314,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"Set container hostname",
)
createFlags.String(
- "image-volume", "bind",
+ "image-volume", cliconfig.DefaultImageVolume,
"Tells podman how to handle the builtin image volumes. The options are: 'bind', 'tmpfs', or 'ignore'",
)
createFlags.Bool(
@@ -451,7 +451,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"Security Options (default [])",
)
createFlags.String(
- "shm-size", "65536k",
+ "shm-size", cliconfig.DefaultShmSize,
"Size of `/dev/shm`. The format is `<number><unit>`",
)
createFlags.String(
@@ -480,7 +480,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"Sysctl options (default [])",
)
createFlags.Bool(
- "systemd", true,
+ "systemd", cliconfig.DefaultSystemD,
"Run container in systemd mode if the command executable is systemd or init",
)
createFlags.StringSlice(
diff --git a/cmd/podman/container.go b/cmd/podman/container.go
index 2e9cedbaa..d1c42f673 100644
--- a/cmd/podman/container.go
+++ b/cmd/podman/container.go
@@ -52,8 +52,11 @@ var (
containerCommands = []*cobra.Command{
_containerExistsCommand,
_contInspectSubCommand,
+ _diffCommand,
+ _createCommand,
_listSubCommand,
_logsCommand,
+ _runCommand,
}
)
diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go
index 18fb2cb73..7dee37287 100644
--- a/cmd/podman/cp.go
+++ b/cmd/podman/cp.go
@@ -1,10 +1,9 @@
package main
import (
- "io/ioutil"
+ "fmt"
"os"
"path/filepath"
- "strconv"
"strings"
"github.com/containers/buildah/pkg/chrootuser"
@@ -12,7 +11,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 +56,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 +85,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
@@ -241,6 +208,11 @@ func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, ch
if !srcfi.IsDir() && !strings.HasSuffix(dest, string(os.PathSeparator)) {
destdir = filepath.Dir(destPath)
}
+ _, err = os.Stat(destdir)
+ if err != nil && !os.IsNotExist(err) {
+ return errors.Wrapf(err, "error checking directory %q", destdir)
+ }
+ destDirIsExist := (err == nil)
if err = os.MkdirAll(destdir, 0755); err != nil {
return errors.Wrapf(err, "error creating directory %q", destdir)
}
@@ -253,6 +225,9 @@ func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, ch
if srcfi.IsDir() {
logrus.Debugf("copying %q to %q", srcPath+string(os.PathSeparator)+"*", dest+string(os.PathSeparator)+"*")
+ if destDirIsExist && !strings.HasSuffix(src, fmt.Sprintf("%s.", string(os.PathSeparator))) {
+ destPath = filepath.Join(destPath, filepath.Base(srcPath))
+ }
if err = copyWithTar(srcPath, destPath); err != nil {
return errors.Wrapf(err, "error copying %q to %q", srcPath, dest)
}
diff --git a/cmd/podman/create.go b/cmd/podman/create.go
index bceb606f6..1af3920dd 100644
--- a/cmd/podman/create.go
+++ b/cmd/podman/create.go
@@ -2,12 +2,9 @@ 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/containers/libpod/pkg/adapter"
"github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/spf13/cobra"
@@ -54,22 +51,17 @@ func createCmd(c *cliconfig.CreateValues) error {
return err
}
- if os.Geteuid() != 0 {
- rootless.SetSkipStorageSetup(true)
- }
-
- 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)
- ctr, _, err := shared.CreateContainer(getContext(), &c.PodmanCommand, runtime)
+ cid, err := runtime.CreateContainer(getContext(), c)
if err != nil {
return err
}
-
- fmt.Printf("%s\n", ctr.ID())
+ fmt.Printf("%s\n", cid)
return nil
}
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 dd8b61408..b44cf9f0a 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,8 @@ var (
// implemented.
var mainCommands = []*cobra.Command{
_buildCommand,
+ _diffCommand,
+ _createCommand,
_eventsCommand,
_exportCommand,
_historyCommand,
@@ -50,6 +55,7 @@ var mainCommands = []*cobra.Command{
_pullCommand,
_pushCommand,
&_rmiCommand,
+ _runCommand,
_saveCommand,
_stopCommand,
_tagCommand,
@@ -59,36 +65,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",
@@ -118,6 +94,9 @@ func init() {
rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.CniConfigDir, "cni-config-dir", "", "Path of the configuration directory for CNI networks")
rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.DefaultMountsFile, "default-mounts-file", "", "Path to default mounts file")
rootCmd.PersistentFlags().MarkHidden("defaults-mount-file")
+ // 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().IntVar(&MainGlobalOpts.MaxWorks, "max-workers", 0, "The maximum number of workers for parallel operations")
@@ -132,7 +111,10 @@ func init() {
rootCmd.PersistentFlags().BoolVar(&MainGlobalOpts.Syslog, "syslog", false, "Output logging information to syslog as well as the console")
rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.TmpDir, "tmpdir", "", "Path to the tmp directory")
- rootCmd.PersistentFlags().BoolVar(&MainGlobalOpts.Trace, "trace", false, "enable opentracing output")
+ rootCmd.PersistentFlags().BoolVar(&MainGlobalOpts.Trace, "trace", false, "Enable opentracing output")
+ // Override default --help information of `--version` global flag
+ var dummyVersion bool
+ rootCmd.PersistentFlags().BoolVar(&dummyVersion, "version", false, "Version for podman")
rootCmd.AddCommand(mainCommands...)
rootCmd.AddCommand(getMainCommands()...)
@@ -146,18 +128,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..bac5c3c18 100644
--- a/cmd/podman/run.go
+++ b/cmd/podman/run.go
@@ -1,21 +1,10 @@
package main
import (
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "strconv"
- "strings"
-
"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/containers/libpod/pkg/adapter"
opentracing "github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
- "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
@@ -57,147 +46,13 @@ 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)
+ runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
defer runtime.Shutdown(false)
- ctr, createConfig, err := shared.CreateContainer(getContext(), &c.PodmanCommand, runtime)
- if err != nil {
- return err
- }
-
- if logrus.GetLevel() == logrus.DebugLevel {
- cgroupPath, err := ctr.CGroupPath()
- if err == nil {
- logrus.Debugf("container %q has CgroupParent %q", ctr.ID(), cgroupPath)
- }
- }
-
- ctx := getContext()
- // Handle detached start
- if createConfig.Detach {
- // if the container was created as part of a pod, also start its dependencies, if any.
- if err := ctr.Start(ctx, c.IsSet("pod")); err != nil {
- // This means the command did not exist
- exitCode = 127
- if strings.Index(err.Error(), "permission denied") > -1 {
- exitCode = 126
- }
- return err
- }
-
- fmt.Printf("%s\n", ctr.ID())
- exitCode = 0
- return nil
- }
-
- outputStream := os.Stdout
- errorStream := os.Stderr
- inputStream := os.Stdin
-
- // If -i is not set, clear stdin
- if !c.Bool("interactive") {
- inputStream = nil
- }
-
- // If attach is set, clear stdin/stdout/stderr and only attach requested
- if c.IsSet("attach") || c.IsSet("a") {
- outputStream = nil
- errorStream = nil
- if !c.Bool("interactive") {
- inputStream = nil
- }
-
- attachTo := c.StringSlice("attach")
- for _, stream := range attachTo {
- switch strings.ToLower(stream) {
- case "stdout":
- outputStream = os.Stdout
- case "stderr":
- errorStream = os.Stderr
- case "stdin":
- inputStream = os.Stdin
- default:
- return errors.Wrapf(libpod.ErrInvalidArg, "invalid stream %q for --attach - must be one of stdin, stdout, or stderr", stream)
- }
- }
- }
- // if the container was created as part of a pod, also start its dependencies, if any.
- if err := startAttachCtr(ctr, outputStream, errorStream, inputStream, c.String("detach-keys"), c.Bool("sig-proxy"), true, c.IsSet("pod")); 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, false); deleteError != nil {
- logrus.Errorf("unable to remove container %s after failing to start and attach to it", ctr.ID())
- }
- }
- return err
- }
-
- if ecode, err := ctr.Wait(); err != nil {
- if errors.Cause(err) == libpod.ErrNoSuchCtr {
- // The container may have been removed
- // Go looking for an exit file
- rtc, err := runtime.GetConfig()
- if err != nil {
- return err
- }
- ctrExitCode, err := readExitFile(rtc.TmpDir, ctr.ID())
- if err != nil {
- logrus.Errorf("Cannot get exit code: %v", err)
- exitCode = 127
- } else {
- exitCode = ctrExitCode
- }
- }
- } else {
- exitCode = int(ecode)
- }
-
- if c.IsSet("rm") {
- runtime.RemoveContainer(ctx, ctr, false, true)
- }
-
- return nil
-}
-
-// Read a container's exit file
-func readExitFile(runtimeTmp, ctrID string) (int, error) {
- exitFile := filepath.Join(runtimeTmp, "exits", fmt.Sprintf("%s-old", ctrID))
-
- logrus.Debugf("Attempting to read container %s exit code from file %s", ctrID, exitFile)
-
- // Check if it exists
- if _, err := os.Stat(exitFile); err != nil {
- return 0, errors.Wrapf(err, "error getting exit file for container %s", ctrID)
- }
-
- // File exists, read it in and convert to int
- statusStr, err := ioutil.ReadFile(exitFile)
- if err != nil {
- return 0, errors.Wrapf(err, "error reading exit file for container %s", ctrID)
- }
-
- exitCode, err := strconv.Atoi(string(statusStr))
- if err != nil {
- return 0, errors.Wrapf(err, "error parsing exit code for container %s", ctrID)
- }
-
- return exitCode, nil
+ exitCode, err = runtime.Run(getContext(), c, exitCode)
+ return err
}
diff --git a/cmd/podman/run_test.go b/cmd/podman/run_test.go
index a896f1dc7..27b34c323 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
@@ -81,7 +83,8 @@ func getRuntimeSpec(c *cliconfig.PodmanCommand) (*spec.Spec, error) {
createConfig, err := parseCreateOpts(c, runtime, "alpine", generateAlpineImageData())
*/
ctx := getContext()
- createConfig, err := shared.ParseCreateOpts(ctx, c, nil, "alpine", generateAlpineImageData())
+ genericResults := shared.NewIntermediateLayer(c)
+ createConfig, err := shared.ParseCreateOpts(ctx, &genericResults, nil, "alpine", generateAlpineImageData())
if err != nil {
return nil, err
}
@@ -100,6 +103,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 +125,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 +146,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..d694027db 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"
@@ -14,7 +13,6 @@ import (
"time"
"github.com/containers/image/manifest"
- "github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/shared/parse"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/image"
@@ -35,12 +33,7 @@ import (
"github.com/sirupsen/logrus"
)
-// getContext returns a non-nil, empty context
-func getContext() context.Context {
- return context.TODO()
-}
-
-func CreateContainer(ctx context.Context, c *cliconfig.PodmanCommand, runtime *libpod.Runtime) (*libpod.Container, *cc.CreateConfig, error) {
+func CreateContainer(ctx context.Context, c *GenericCLIResults, runtime *libpod.Runtime) (*libpod.Container, *cc.CreateConfig, error) {
var (
healthCheck *manifest.Schema2HealthConfig
err error
@@ -75,7 +68,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
@@ -221,7 +215,7 @@ func parseSecurityOpt(config *cc.CreateConfig, securityOpts []string) error {
return nil
}
-func configureEntrypoint(c *cliconfig.PodmanCommand, data *inspect.ImageData) []string {
+func configureEntrypoint(c *GenericCLIResults, data *inspect.ImageData) []string {
entrypoint := []string{}
if c.IsSet("entrypoint") {
// Force entrypoint to ""
@@ -241,7 +235,7 @@ func configureEntrypoint(c *cliconfig.PodmanCommand, data *inspect.ImageData) []
return entrypoint
}
-func configurePod(c *cliconfig.PodmanCommand, runtime *libpod.Runtime, namespaces map[string]string, podName string) (map[string]string, error) {
+func configurePod(c *GenericCLIResults, runtime *libpod.Runtime, namespaces map[string]string, podName string) (map[string]string, error) {
pod, err := runtime.LookupPod(podName)
if err != nil {
return namespaces, err
@@ -270,7 +264,7 @@ func configurePod(c *cliconfig.PodmanCommand, runtime *libpod.Runtime, namespace
// Parses CLI options related to container creation into a config which can be
// parsed into an OCI runtime spec
-func ParseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *libpod.Runtime, imageName string, data *inspect.ImageData) (*cc.CreateConfig, error) {
+func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.Runtime, imageName string, data *inspect.ImageData) (*cc.CreateConfig, error) {
var (
inputCommand, command []string
memoryLimit, memoryReservation, memorySwap, memoryKernel int64
@@ -353,14 +347,14 @@ func ParseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l
tty := c.Bool("tty")
- if c.Flag("cpu-period").Changed && c.Flag("cpus").Changed {
+ if c.Changed("cpu-period") && c.Changed("cpus") {
return nil, errors.Errorf("--cpu-period and --cpus cannot be set together")
}
- if c.Flag("cpu-quota").Changed && c.Flag("cpus").Changed {
+ if c.Changed("cpu-quota") && c.Changed("cpus") {
return nil, errors.Errorf("--cpu-quota and --cpus cannot be set together")
}
- if c.Bool("no-hosts") && c.Flag("add-host").Changed {
+ if c.Bool("no-hosts") && c.Changed("add-host") {
return nil, errors.Errorf("--no-hosts and --add-host cannot be set together")
}
@@ -379,7 +373,7 @@ func ParseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l
// However, that also involves setting up security opts
// when the pod's namespace is integrated
namespaceNet := c.String("network")
- if c.Flag("net").Changed {
+ if c.Changed("net") {
namespaceNet = c.String("net")
}
namespaces = map[string]string{
@@ -548,7 +542,7 @@ func ParseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l
// WORKING DIRECTORY
workDir := "/"
- if c.IsSet("workdir") || c.IsSet("w") {
+ if c.IsSet("workdir") {
workDir = c.String("workdir")
} else if data != nil && data.Config.WorkingDir != "" {
workDir = data.Config.WorkingDir
@@ -624,14 +618,12 @@ func ParseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l
// This is done because cobra cannot have two aliased flags. So we have to check
// both
network := c.String("network")
- if c.Flag("net").Changed {
+ if c.Changed("net") {
network = c.String("net")
}
- var memorySwappiness int64
- if c.Flags().Lookup("memory-swappiness") != nil {
- memorySwappiness, _ = c.Flags().GetInt64("memory-swappiness")
- }
+ memorySwappiness := c.Int64("memory-swappiness")
+
config := &cc.CreateConfig{
Runtime: runtime,
Annotations: annotations,
@@ -719,7 +711,7 @@ func ParseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l
WorkDir: workDir,
Rootfs: rootfs,
VolumesFrom: c.StringSlice("volumes-from"),
- Syslog: c.GlobalFlags.Syslog,
+ Syslog: c.Bool("syslog"),
}
if c.Bool("init") {
initPath := c.String("init-path")
@@ -758,71 +750,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 +760,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 {
@@ -861,7 +781,7 @@ var defaultEnvVariables = map[string]string{
"TERM": "xterm",
}
-func makeHealthCheckFromCli(c *cliconfig.PodmanCommand) (*manifest.Schema2HealthConfig, error) {
+func makeHealthCheckFromCli(c *GenericCLIResults) (*manifest.Schema2HealthConfig, error) {
inCommand := c.String("healthcheck-command")
inInterval := c.String("healthcheck-interval")
inRetries := c.Uint("healthcheck-retries")
diff --git a/cmd/podman/shared/intermediate.go b/cmd/podman/shared/intermediate.go
new file mode 100644
index 000000000..9afbd68c8
--- /dev/null
+++ b/cmd/podman/shared/intermediate.go
@@ -0,0 +1,465 @@
+package shared
+
+import (
+ "github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/sirupsen/logrus"
+)
+
+/*
+attention
+
+in this file you will see alot of struct duplication. this was done because people wanted a strongly typed
+varlink mechanism. this resulted in us creating this intermediate layer that allows us to take the input
+from the cli and make an intermediate layer which can be transferred as strongly typed structures over a varlink
+interface.
+
+we intentionally avoided heavy use of reflection here because we were concerned about performance impacts to the
+non-varlink intermediate layer generation.
+*/
+
+// GenericCLIResult describes the overall interface for dealing with
+// the create command cli in both local and remote uses
+type GenericCLIResult interface {
+ IsSet() bool
+ Name() string
+ Value() interface{}
+}
+
+// CRStringSlice describes a string slice cli struct
+type CRStringSlice struct {
+ Val []string
+ createResult
+}
+
+// CRString describes a string cli struct
+type CRString struct {
+ Val string
+ createResult
+}
+
+// CRUint64 describes a uint64 cli struct
+type CRUint64 struct {
+ Val uint64
+ createResult
+}
+
+// CRFloat64 describes a float64 cli struct
+type CRFloat64 struct {
+ Val float64
+ createResult
+}
+
+//CRBool describes a bool cli struct
+type CRBool struct {
+ Val bool
+ createResult
+}
+
+// CRInt64 describes an int64 cli struct
+type CRInt64 struct {
+ Val int64
+ createResult
+}
+
+// CRUint describes a uint cli struct
+type CRUint struct {
+ Val uint
+ createResult
+}
+
+// CRInt describes an int cli struct
+type CRInt struct {
+ Val int
+ createResult
+}
+
+// CRStringArray describes a stringarray cli struct
+type CRStringArray struct {
+ Val []string
+ createResult
+}
+
+type createResult struct {
+ Flag string
+ Changed bool
+}
+
+// GenericCLIResults in the intermediate object between the cobra cli
+// and createconfig
+type GenericCLIResults struct {
+ results map[string]GenericCLIResult
+ InputArgs []string
+}
+
+// IsSet returns a bool if the flag was changed
+func (f GenericCLIResults) IsSet(flag string) bool {
+ r := f.findResult(flag)
+ if r == nil {
+ return false
+ }
+ return r.IsSet()
+}
+
+// Value returns the value of the cli flag
+func (f GenericCLIResults) Value(flag string) interface{} {
+ r := f.findResult(flag)
+ if r == nil {
+ return ""
+ }
+ return r.Value()
+}
+
+func (f GenericCLIResults) findResult(flag string) GenericCLIResult {
+ val, ok := f.results[flag]
+ if ok {
+ return val
+ }
+ logrus.Errorf("unable to find flag %s", flag)
+ return nil
+}
+
+// Bool is a wrapper to get a bool value from GenericCLIResults
+func (f GenericCLIResults) Bool(flag string) bool {
+ r := f.findResult(flag)
+ if r == nil {
+ return false
+ }
+ return r.Value().(bool)
+}
+
+// String is a wrapper to get a string value from GenericCLIResults
+func (f GenericCLIResults) String(flag string) string {
+ r := f.findResult(flag)
+ if r == nil {
+ return ""
+ }
+ return r.Value().(string)
+}
+
+// Uint is a wrapper to get an uint value from GenericCLIResults
+func (f GenericCLIResults) Uint(flag string) uint {
+ r := f.findResult(flag)
+ if r == nil {
+ return 0
+ }
+ return r.Value().(uint)
+}
+
+// StringSlice is a wrapper to get a stringslice value from GenericCLIResults
+func (f GenericCLIResults) StringSlice(flag string) []string {
+ r := f.findResult(flag)
+ if r == nil {
+ return []string{}
+ }
+ return r.Value().([]string)
+}
+
+// StringArray is a wrapper to get a stringslice value from GenericCLIResults
+func (f GenericCLIResults) StringArray(flag string) []string {
+ r := f.findResult(flag)
+ if r == nil {
+ return []string{}
+ }
+ return r.Value().([]string)
+}
+
+// Uint64 is a wrapper to get an uint64 value from GenericCLIResults
+func (f GenericCLIResults) Uint64(flag string) uint64 {
+ r := f.findResult(flag)
+ if r == nil {
+ return 0
+ }
+ return r.Value().(uint64)
+}
+
+// Int64 is a wrapper to get an int64 value from GenericCLIResults
+func (f GenericCLIResults) Int64(flag string) int64 {
+ r := f.findResult(flag)
+ if r == nil {
+ return 0
+ }
+ return r.Value().(int64)
+}
+
+// Int is a wrapper to get an int value from GenericCLIResults
+func (f GenericCLIResults) Int(flag string) int {
+ r := f.findResult(flag)
+ if r == nil {
+ return 0
+ }
+ return r.Value().(int)
+}
+
+// Float64 is a wrapper to get an float64 value from GenericCLIResults
+func (f GenericCLIResults) Float64(flag string) float64 {
+ r := f.findResult(flag)
+ if r == nil {
+ return 0
+ }
+ return r.Value().(float64)
+}
+
+// Float64 is a wrapper to get an float64 value from GenericCLIResults
+func (f GenericCLIResults) Changed(flag string) bool {
+ r := f.findResult(flag)
+ if r == nil {
+ return false
+ }
+ return r.IsSet()
+}
+
+// IsSet ...
+func (c CRStringSlice) IsSet() bool { return c.Changed }
+
+// Name ...
+func (c CRStringSlice) Name() string { return c.Flag }
+
+// Value ...
+func (c CRStringSlice) Value() interface{} { return c.Val }
+
+// IsSet ...
+func (c CRString) IsSet() bool { return c.Changed }
+
+// Name ...
+func (c CRString) Name() string { return c.Flag }
+
+// Value ...
+func (c CRString) Value() interface{} { return c.Val }
+
+// IsSet ...
+func (c CRUint64) IsSet() bool { return c.Changed }
+
+// Name ...
+func (c CRUint64) Name() string { return c.Flag }
+
+// Value ...
+func (c CRUint64) Value() interface{} { return c.Val }
+
+// IsSet ...
+func (c CRFloat64) IsSet() bool { return c.Changed }
+
+// Name ...
+func (c CRFloat64) Name() string { return c.Flag }
+
+// Value ...
+func (c CRFloat64) Value() interface{} { return c.Val }
+
+// IsSet ...
+func (c CRBool) IsSet() bool { return c.Changed }
+
+// Name ...
+func (c CRBool) Name() string { return c.Flag }
+
+// Value ...
+func (c CRBool) Value() interface{} { return c.Val }
+
+// IsSet ...
+func (c CRInt64) IsSet() bool { return c.Changed }
+
+// Name ...
+func (c CRInt64) Name() string { return c.Flag }
+
+// Value ...
+func (c CRInt64) Value() interface{} { return c.Val }
+
+// IsSet ...
+func (c CRUint) IsSet() bool { return c.Changed }
+
+// Name ...
+func (c CRUint) Name() string { return c.Flag }
+
+// Value ...
+func (c CRUint) Value() interface{} { return c.Val }
+
+// IsSet ...
+func (c CRInt) IsSet() bool { return c.Changed }
+
+// Name ...
+func (c CRInt) Name() string { return c.Flag }
+
+// Value ...
+func (c CRInt) Value() interface{} { return c.Val }
+
+// IsSet ...
+func (c CRStringArray) IsSet() bool { return c.Changed }
+
+// Name ...
+func (c CRStringArray) Name() string { return c.Flag }
+
+// Value ...
+func (c CRStringArray) Value() interface{} { return c.Val }
+
+func newCreateResult(c *cliconfig.PodmanCommand, flag string) createResult {
+ return createResult{
+ Flag: flag,
+ Changed: c.IsSet(flag),
+ }
+}
+
+func newCRStringSlice(c *cliconfig.PodmanCommand, flag string) CRStringSlice {
+ return CRStringSlice{
+ Val: c.StringSlice(flag),
+ createResult: newCreateResult(c, flag),
+ }
+}
+
+func newCRString(c *cliconfig.PodmanCommand, flag string) CRString {
+ return CRString{
+ Val: c.String(flag),
+ createResult: newCreateResult(c, flag),
+ }
+}
+
+func newCRUint64(c *cliconfig.PodmanCommand, flag string) CRUint64 {
+ return CRUint64{
+ Val: c.Uint64(flag),
+ createResult: newCreateResult(c, flag),
+ }
+}
+
+func newCRFloat64(c *cliconfig.PodmanCommand, flag string) CRFloat64 {
+ return CRFloat64{
+ Val: c.Float64(flag),
+ createResult: newCreateResult(c, flag),
+ }
+}
+
+func newCRBool(c *cliconfig.PodmanCommand, flag string) CRBool {
+ return CRBool{
+ Val: c.Bool(flag),
+ createResult: newCreateResult(c, flag),
+ }
+}
+
+func newCRInt64(c *cliconfig.PodmanCommand, flag string) CRInt64 {
+ return CRInt64{
+ Val: c.Int64(flag),
+ createResult: newCreateResult(c, flag),
+ }
+}
+
+func newCRUint(c *cliconfig.PodmanCommand, flag string) CRUint {
+ return CRUint{
+ Val: c.Uint(flag),
+ createResult: newCreateResult(c, flag),
+ }
+}
+
+func newCRInt(c *cliconfig.PodmanCommand, flag string) CRInt {
+ return CRInt{
+ Val: c.Int(flag),
+ createResult: newCreateResult(c, flag),
+ }
+}
+
+func newCRStringArray(c *cliconfig.PodmanCommand, flag string) CRStringArray {
+ return CRStringArray{
+ Val: c.StringArray(flag),
+ createResult: newCreateResult(c, flag),
+ }
+}
+
+// NewIntermediateLayer creates a GenericCLIResults from a create or run cli-command
+func NewIntermediateLayer(c *cliconfig.PodmanCommand) GenericCLIResults {
+ m := make(map[string]GenericCLIResult)
+
+ m["add-host"] = newCRStringSlice(c, "add-host")
+ m["annotation"] = newCRStringSlice(c, "annotation")
+ m["attach"] = newCRStringSlice(c, "attach")
+ m["blkio-weight"] = newCRString(c, "blkio-weight")
+ m["blkio-weight-device"] = newCRStringSlice(c, "blkio-weight-device")
+ m["cap-add"] = newCRStringSlice(c, "cap-add")
+ m["cap-drop"] = newCRStringSlice(c, "cap-drop")
+ m["cgroup-parent"] = newCRString(c, "cgroup-parent")
+ m["cidfile"] = newCRString(c, "cidfile")
+ m["conmon-pidfile"] = newCRString(c, "conmon-pidfile")
+ m["cpu-period"] = newCRUint64(c, "cpu-period")
+ m["cpu-quota"] = newCRInt64(c, "cpu-quota")
+ m["cpu-rt-period"] = newCRUint64(c, "cpu-rt-period")
+ m["cpu-rt-runtime"] = newCRInt64(c, "cpu-rt-runtime")
+ m["cpu-shares"] = newCRUint64(c, "cpu-shares")
+ m["cpus"] = newCRFloat64(c, "cpus")
+ m["cpuset-cpus"] = newCRString(c, "cpuset-cpus")
+ m["cpuset-mems"] = newCRString(c, "cpuset-mems")
+ m["detach"] = newCRBool(c, "detach")
+ m["detach-keys"] = newCRString(c, "detach-keys")
+ m["device"] = newCRStringSlice(c, "device")
+ m["device-read-bps"] = newCRStringSlice(c, "device-read-bps")
+ m["device-read-iops"] = newCRStringSlice(c, "device-read-iops")
+ m["device-write-bps"] = newCRStringSlice(c, "device-write-bps")
+ m["device-write-iops"] = newCRStringSlice(c, "device-write-iops")
+ m["dns"] = newCRStringSlice(c, "dns")
+ m["dns-opt"] = newCRStringSlice(c, "dns-opt")
+ m["dns-search"] = newCRStringSlice(c, "dns-search")
+ m["entrypoint"] = newCRString(c, "entrypoint")
+ m["env"] = newCRStringArray(c, "env")
+ m["env-file"] = newCRStringSlice(c, "env-file")
+ m["expose"] = newCRStringSlice(c, "expose")
+ m["gidmap"] = newCRStringSlice(c, "gidmap")
+ m["group-add"] = newCRStringSlice(c, "group-add")
+ m["help"] = newCRBool(c, "help")
+ m["healthcheck-command"] = newCRString(c, "healthcheck-command")
+ m["healthcheck-interval"] = newCRString(c, "healthcheck-interval")
+ m["healthcheck-retries"] = newCRUint(c, "healthcheck-retries")
+ m["healthcheck-start-period"] = newCRString(c, "healthcheck-start-period")
+ m["healthcheck-timeout"] = newCRString(c, "healthcheck-timeout")
+ m["hostname"] = newCRString(c, "hostname")
+ m["image-volume"] = newCRString(c, "image-volume")
+ m["init"] = newCRBool(c, "init")
+ m["init-path"] = newCRString(c, "init-path")
+ m["interactive"] = newCRBool(c, "interactive")
+ m["ip"] = newCRString(c, "ip")
+ m["ipc"] = newCRString(c, "ipc")
+ m["kernel-memory"] = newCRString(c, "kernel-memory")
+ m["label"] = newCRStringArray(c, "label")
+ m["label-file"] = newCRStringSlice(c, "label-file")
+ m["log-driver"] = newCRString(c, "log-driver")
+ m["log-opt"] = newCRStringSlice(c, "log-opt")
+ m["mac-address"] = newCRString(c, "mac-address")
+ m["memory"] = newCRString(c, "memory")
+ m["memory-reservation"] = newCRString(c, "memory-reservation")
+ m["memory-swap"] = newCRString(c, "memory-swap")
+ m["memory-swappiness"] = newCRInt64(c, "memory-swappiness")
+ m["name"] = newCRString(c, "name")
+ m["net"] = newCRString(c, "net")
+ m["network"] = newCRString(c, "network")
+ m["no-hosts"] = newCRBool(c, "no-hosts")
+ m["oom-kill-disable"] = newCRBool(c, "oom-kill-disable")
+ m["oom-score-adj"] = newCRInt(c, "oom-score-adj")
+ m["pid"] = newCRString(c, "pid")
+ m["pids-limit"] = newCRInt64(c, "pids-limit")
+ m["pod"] = newCRString(c, "pod")
+ m["privileged"] = newCRBool(c, "privileged")
+ m["publish"] = newCRStringSlice(c, "publish")
+ m["publish-all"] = newCRBool(c, "publish-all")
+ m["quiet"] = newCRBool(c, "quiet")
+ m["read-only"] = newCRBool(c, "read-only")
+ m["restart"] = newCRString(c, "restart")
+ m["rm"] = newCRBool(c, "rm")
+ m["rootfs"] = newCRBool(c, "rootfs")
+ m["security-opt"] = newCRStringArray(c, "security-opt")
+ m["shm-size"] = newCRString(c, "shm-size")
+ m["stop-signal"] = newCRString(c, "stop-signal")
+ m["stop-timeout"] = newCRUint(c, "stop-timeout")
+ m["storage-opt"] = newCRStringSlice(c, "storage-opt")
+ m["subgidname"] = newCRString(c, "subgidname")
+ m["subuidname"] = newCRString(c, "subuidname")
+ m["sysctl"] = newCRStringSlice(c, "sysctl")
+ m["systemd"] = newCRBool(c, "systemd")
+ m["tmpfs"] = newCRStringSlice(c, "tmpfs")
+ m["tty"] = newCRBool(c, "tty")
+ m["uidmap"] = newCRStringSlice(c, "uidmap")
+ m["ulimit"] = newCRStringSlice(c, "ulimit")
+ m["user"] = newCRString(c, "user")
+ m["userns"] = newCRString(c, "userns")
+ m["uts"] = newCRString(c, "uts")
+ m["mount"] = newCRStringArray(c, "mount")
+ m["volume"] = newCRStringArray(c, "volume")
+ m["volumes-from"] = newCRStringSlice(c, "volumes-from")
+ m["workdir"] = newCRString(c, "workdir")
+ // global flag
+ m["trace"] = newCRBool(c, "trace")
+ m["syslog"] = newCRBool(c, "syslog")
+
+ return GenericCLIResults{m, c.InputArgs}
+}
diff --git a/cmd/podman/shared/intermediate_novarlink.go b/cmd/podman/shared/intermediate_novarlink.go
new file mode 100644
index 000000000..26738ce48
--- /dev/null
+++ b/cmd/podman/shared/intermediate_novarlink.go
@@ -0,0 +1,70 @@
+// +build !varlink
+// +build !remoteclient
+
+package shared
+
+/*
+attention
+
+in this file you will see alot of struct duplication. this was done because people wanted a strongly typed
+varlink mechanism. this resulted in us creating this intermediate layer that allows us to take the input
+from the cli and make an intermediate layer which can be transferred as strongly typed structures over a varlink
+interface.
+
+we intentionally avoided heavy use of reflection here because we were concerned about performance impacts to the
+non-varlink intermediate layer generation.
+*/
+
+// ToString wrapper for build without varlink
+func (c CRStringSlice) ToVarlink() interface{} {
+ var v interface{}
+ return v
+}
+
+// ToString wrapper for build without varlink
+func (c CRString) ToVarlink() interface{} {
+ var v interface{}
+ return v
+}
+
+// ToString wrapper for build without varlink
+func (c CRBool) ToVarlink() interface{} {
+ var v interface{}
+ return v
+}
+
+// ToString wrapper for build without varlink
+func (c CRUint64) ToVarlink() interface{} {
+ var v interface{}
+ return v
+}
+
+// ToString wrapper for build without varlink
+func (c CRInt64) ToVarlink() interface{} {
+ var v interface{}
+ return v
+}
+
+// ToString wrapper for build without varlink
+func (c CRFloat64) ToVarlink() interface{} {
+ var v interface{}
+ return v
+}
+
+// ToString wrapper for build without varlink
+func (c CRUint) ToVarlink() interface{} {
+ var v interface{}
+ return v
+}
+
+// ToString wrapper for build without varlink
+func (c CRStringArray) ToVarlink() interface{} {
+ var v interface{}
+ return v
+}
+
+// ToString wrapper for build without varlink
+func (c CRInt) ToVarlink() interface{} {
+ var v interface{}
+ return v
+}
diff --git a/cmd/podman/shared/intermediate_varlink.go b/cmd/podman/shared/intermediate_varlink.go
new file mode 100644
index 000000000..95a0d6287
--- /dev/null
+++ b/cmd/podman/shared/intermediate_varlink.go
@@ -0,0 +1,427 @@
+// +build varlink remoteclient
+
+package shared
+
+import (
+ "fmt"
+ "github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/containers/libpod/cmd/podman/varlink"
+ "github.com/pkg/errors"
+)
+
+// StringSliceToPtr converts a genericcliresult value into a *[]string
+func StringSliceToPtr(g GenericCLIResult) *[]string {
+ if !g.IsSet() {
+ return nil
+ }
+ newT := g.Value().([]string)
+ return &newT
+}
+
+// StringToPtr converts a genericcliresult value into a *string
+func StringToPtr(g GenericCLIResult) *string {
+ if !g.IsSet() {
+ return nil
+ }
+ newT := g.Value().(string)
+ return &newT
+}
+
+// BoolToPtr converts a genericcliresult value into a *bool
+func BoolToPtr(g GenericCLIResult) *bool {
+ if !g.IsSet() {
+ return nil
+ }
+ newT := g.Value().(bool)
+ return &newT
+}
+
+// AnyIntToInt64Ptr converts a genericcliresult value into an *int64
+func AnyIntToInt64Ptr(g GenericCLIResult) *int64 {
+ if !g.IsSet() {
+ return nil
+ }
+ var newT int64
+ switch g.Value().(type) {
+ case int:
+ newT = int64(g.Value().(int))
+ case int64:
+ newT = g.Value().(int64)
+ case uint64:
+ newT = int64(g.Value().(uint64))
+ case uint:
+ newT = int64(g.Value().(uint))
+ default:
+ panic(errors.Errorf("invalid int type"))
+ }
+ return &newT
+}
+
+// Float64ToPtr converts a genericcliresult into a *float64
+func Float64ToPtr(g GenericCLIResult) *float64 {
+ if !g.IsSet() {
+ return nil
+ }
+ newT := g.Value().(float64)
+ return &newT
+}
+
+// MakeVarlink creates a varlink transportable struct from GenericCLIResults
+func (g GenericCLIResults) MakeVarlink() iopodman.Create {
+ v := iopodman.Create{
+ Args: g.InputArgs,
+ AddHost: StringSliceToPtr(g.Find("add-host")),
+ Annotation: StringSliceToPtr(g.Find("annotation")),
+ Attach: StringSliceToPtr(g.Find("attach")),
+ BlkioWeight: StringToPtr(g.Find("blkio-weight")),
+ BlkioWeightDevice: StringSliceToPtr(g.Find("blkio-weight-device")),
+ CapAdd: StringSliceToPtr(g.Find("cap-add")),
+ CapDrop: StringSliceToPtr(g.Find("cap-drop")),
+ CgroupParent: StringToPtr(g.Find("cgroup-parent")),
+ CidFile: StringToPtr(g.Find("cidfile")),
+ ConmonPidfile: StringToPtr(g.Find("conmon-pidfile")),
+ CpuPeriod: AnyIntToInt64Ptr(g.Find("cpu-period")),
+ CpuQuota: AnyIntToInt64Ptr(g.Find("cpu-quota")),
+ CpuRtPeriod: AnyIntToInt64Ptr(g.Find("cpu-rt-period")),
+ CpuRtRuntime: AnyIntToInt64Ptr(g.Find("cpu-rt-runtime")),
+ CpuShares: AnyIntToInt64Ptr(g.Find("cpu-shares")),
+ Cpus: Float64ToPtr(g.Find("cpus")),
+ CpuSetCpus: StringToPtr(g.Find("cpuset-cpus")),
+ CpuSetMems: StringToPtr(g.Find("cpuset-mems")),
+ Detach: BoolToPtr(g.Find("detach")),
+ DetachKeys: StringToPtr(g.Find("detach-keys")),
+ Device: StringSliceToPtr(g.Find("device")),
+ DeviceReadBps: StringSliceToPtr(g.Find("device-read-bps")),
+ DeviceReadIops: StringSliceToPtr(g.Find("device-read-iops")),
+ DeviceWriteBps: StringSliceToPtr(g.Find("device-write-bps")),
+ DeviceWriteIops: StringSliceToPtr(g.Find("device-write-iops")),
+ Dns: StringSliceToPtr(g.Find("dns")),
+ DnsOpt: StringSliceToPtr(g.Find("dns-opt")),
+ DnsSearch: StringSliceToPtr(g.Find("dns-search")),
+ Entrypoint: StringToPtr(g.Find("entrypoint")),
+ Env: StringSliceToPtr(g.Find("env")),
+ EnvFile: StringSliceToPtr(g.Find("env-file")),
+ Expose: StringSliceToPtr(g.Find("expose")),
+ Gidmap: StringSliceToPtr(g.Find("gidmap")),
+ Groupadd: StringSliceToPtr(g.Find("group-add")),
+ HealthcheckCommand: StringToPtr(g.Find("healthcheck-command")),
+ HealthcheckInterval: StringToPtr(g.Find("healthcheck-interval")),
+ HealthcheckRetries: AnyIntToInt64Ptr(g.Find("healthcheck-retries")),
+ HealthcheckStartPeriod: StringToPtr(g.Find("healthcheck-start-period")),
+ HealthcheckTimeout: StringToPtr(g.Find("healthcheck-timeout")),
+ Hostname: StringToPtr(g.Find("hostname")),
+ ImageVolume: StringToPtr(g.Find("image-volume")),
+ Init: BoolToPtr(g.Find("init")),
+ InitPath: StringToPtr(g.Find("init-path")),
+ Interactive: BoolToPtr(g.Find("interactive")),
+ Ip: StringToPtr(g.Find("ip")),
+ Ipc: StringToPtr(g.Find("ipc")),
+ KernelMemory: StringToPtr(g.Find("kernel-memory")),
+ Label: StringSliceToPtr(g.Find("label")),
+ LabelFile: StringSliceToPtr(g.Find("label-file")),
+ LogDriver: StringToPtr(g.Find("log-driver")),
+ LogOpt: StringSliceToPtr(g.Find("log-opt")),
+ MacAddress: StringToPtr(g.Find("mac-address")),
+ Memory: StringToPtr(g.Find("memory")),
+ MemoryReservation: StringToPtr(g.Find("memory-reservation")),
+ MemorySwap: StringToPtr(g.Find("memory-swap")),
+ MemorySwappiness: AnyIntToInt64Ptr(g.Find("memory-swappiness")),
+ Name: StringToPtr(g.Find("name")),
+ Net: StringToPtr(g.Find("net")),
+ Network: StringToPtr(g.Find("network")),
+ OomKillDisable: BoolToPtr(g.Find("oom-kill-disable")),
+ OomScoreAdj: AnyIntToInt64Ptr(g.Find("oom-score-adj")),
+ Pid: StringToPtr(g.Find("pid")),
+ PidsLimit: AnyIntToInt64Ptr(g.Find("pids-limit")),
+ Pod: StringToPtr(g.Find("pod")),
+ Privileged: BoolToPtr(g.Find("privileged")),
+ Publish: StringSliceToPtr(g.Find("publish")),
+ PublishAll: BoolToPtr(g.Find("publish-all")),
+ Quiet: BoolToPtr(g.Find("quiet")),
+ Readonly: BoolToPtr(g.Find("read-only")),
+ Restart: StringToPtr(g.Find("restart")),
+ Rm: BoolToPtr(g.Find("rm")),
+ Rootfs: BoolToPtr(g.Find("rootfs")),
+ SecurityOpt: StringSliceToPtr(g.Find("security-opt")),
+ ShmSize: StringToPtr(g.Find("shm-size")),
+ StopSignal: StringToPtr(g.Find("stop-signal")),
+ StopTimeout: AnyIntToInt64Ptr(g.Find("stop-timeout")),
+ StorageOpt: StringSliceToPtr(g.Find("storage-opt")),
+ Subuidname: StringToPtr(g.Find("subuidname")),
+ Subgidname: StringToPtr(g.Find("subgidname")),
+ Sysctl: StringSliceToPtr(g.Find("sysctl")),
+ Systemd: BoolToPtr(g.Find("systemd")),
+ Tmpfs: StringSliceToPtr(g.Find("tmpfs")),
+ Tty: BoolToPtr(g.Find("tty")),
+ Uidmap: StringSliceToPtr(g.Find("uidmap")),
+ Ulimit: StringSliceToPtr(g.Find("ulimit")),
+ User: StringToPtr(g.Find("user")),
+ Userns: StringToPtr(g.Find("userns")),
+ Uts: StringToPtr(g.Find("uts")),
+ Mount: StringSliceToPtr(g.Find("mount")),
+ Volume: StringSliceToPtr(g.Find("volume")),
+ VolumesFrom: StringSliceToPtr(g.Find("volumes-from")),
+ WorkDir: StringToPtr(g.Find("workdir")),
+ }
+
+ return v
+}
+
+func stringSliceFromVarlink(v *[]string, flagName string, defaultValue *[]string) CRStringSlice {
+ cr := CRStringSlice{}
+ if v == nil {
+ cr.Val = []string{}
+ if defaultValue != nil {
+ cr.Val = *defaultValue
+ }
+ cr.Changed = false
+ } else {
+ cr.Val = *v
+ cr.Changed = true
+ }
+ cr.Flag = flagName
+ return cr
+}
+
+func stringFromVarlink(v *string, flagName string, defaultValue *string) CRString {
+ cr := CRString{}
+ if v == nil {
+ cr.Val = ""
+ if defaultValue != nil {
+ cr.Val = *defaultValue
+ }
+ cr.Changed = false
+ } else {
+ cr.Val = *v
+ cr.Changed = true
+ }
+ cr.Flag = flagName
+ return cr
+}
+
+func boolFromVarlink(v *bool, flagName string, defaultValue bool) CRBool {
+ cr := CRBool{}
+ if v == nil {
+ // In case a cli bool default value is true
+ cr.Val = defaultValue
+ cr.Changed = false
+ } else {
+ fmt.Println(flagName, cr.Val)
+ cr.Val = *v
+ cr.Changed = true
+ }
+ cr.Flag = flagName
+ return cr
+}
+
+func uint64FromVarlink(v *int64, flagName string, defaultValue *uint64) CRUint64 {
+ cr := CRUint64{}
+ if v == nil {
+ cr.Val = 0
+ if defaultValue != nil {
+ cr.Val = *defaultValue
+ }
+ cr.Changed = false
+ } else {
+ cr.Val = uint64(*v)
+ cr.Changed = true
+ }
+ cr.Flag = flagName
+ return cr
+}
+
+func int64FromVarlink(v *int64, flagName string, defaultValue *int64) CRInt64 {
+ cr := CRInt64{}
+ if v == nil {
+ cr.Val = 0
+ if defaultValue != nil {
+ cr.Val = *defaultValue
+ }
+ cr.Changed = false
+ } else {
+ cr.Val = *v
+ cr.Changed = true
+ }
+ cr.Flag = flagName
+ return cr
+}
+
+func float64FromVarlink(v *float64, flagName string, defaultValue *float64) CRFloat64 {
+ cr := CRFloat64{}
+ if v == nil {
+ cr.Val = 0
+ if defaultValue != nil {
+ cr.Val = *defaultValue
+ }
+ cr.Changed = false
+ } else {
+ cr.Val = *v
+ cr.Changed = true
+ }
+ cr.Flag = flagName
+ return cr
+}
+
+func uintFromVarlink(v *int64, flagName string, defaultValue *uint) CRUint {
+ cr := CRUint{}
+ if v == nil {
+ cr.Val = 0
+ if defaultValue != nil {
+ cr.Val = *defaultValue
+ }
+ cr.Changed = false
+ } else {
+ cr.Val = uint(*v)
+ cr.Changed = true
+ }
+ cr.Flag = flagName
+ return cr
+}
+
+func stringArrayFromVarlink(v *[]string, flagName string, defaultValue *[]string) CRStringArray {
+ cr := CRStringArray{}
+ if v == nil {
+ cr.Val = []string{}
+ if defaultValue != nil {
+ cr.Val = *defaultValue
+ }
+ cr.Changed = false
+ } else {
+ cr.Val = *v
+ cr.Changed = true
+ }
+ cr.Flag = flagName
+ return cr
+}
+
+func intFromVarlink(v *int64, flagName string, defaultValue *int) CRInt {
+ cr := CRInt{}
+ if v == nil {
+ if defaultValue != nil {
+ cr.Val = *defaultValue
+ }
+ cr.Val = 0
+ cr.Changed = false
+ } else {
+ cr.Val = int(*v)
+ cr.Changed = true
+ }
+ cr.Flag = flagName
+ return cr
+}
+
+// VarlinkCreateToGeneric creates a GenericCLIResults from the varlink create
+// structure.
+func VarlinkCreateToGeneric(opts iopodman.Create) GenericCLIResults {
+
+ // TODO | WARN
+ // We do not get a default network over varlink. Unlike the other default values for some cli
+ // elements, it seems it gets set to the default anyway.
+
+ m := make(map[string]GenericCLIResult)
+ m["add-host"] = stringSliceFromVarlink(opts.AddHost, "add-host", nil)
+ m["annotation"] = stringSliceFromVarlink(opts.Annotation, "annotation", nil)
+ m["attach"] = stringSliceFromVarlink(opts.Attach, "attach", nil)
+ m["blkio-weight"] = stringFromVarlink(opts.BlkioWeight, "blkio-weight", nil)
+ m["blkio-weight-device"] = stringSliceFromVarlink(opts.BlkioWeightDevice, "blkio-weight-device", nil)
+ m["cap-add"] = stringSliceFromVarlink(opts.CapAdd, "cap-add", nil)
+ m["cap-drop"] = stringSliceFromVarlink(opts.CapDrop, "cap-drop", nil)
+ m["cgroup-parent"] = stringFromVarlink(opts.CgroupParent, "cgroup-parent", nil)
+ m["cidfile"] = stringFromVarlink(opts.CidFile, "cidfile", nil)
+ m["conmon-pidfile"] = stringFromVarlink(opts.ConmonPidfile, "conmon-file", nil)
+ m["cpu-period"] = uint64FromVarlink(opts.CpuPeriod, "cpu-period", nil)
+ m["cpu-quota"] = int64FromVarlink(opts.CpuQuota, "quota", nil)
+ m["cpu-rt-period"] = uint64FromVarlink(opts.CpuRtPeriod, "cpu-rt-period", nil)
+ m["cpu-rt-runtime"] = int64FromVarlink(opts.CpuRtRuntime, "cpu-rt-quota", nil)
+ m["cpu-shares"] = uint64FromVarlink(opts.CpuShares, "cpu-shares", nil)
+ m["cpus"] = float64FromVarlink(opts.Cpus, "cpus", nil)
+ m["cpuset-cpus"] = stringFromVarlink(opts.CpuSetCpus, "cpuset-cpus", nil)
+ m["cpuset-mems"] = stringFromVarlink(opts.CpuSetMems, "cpuset-mems", nil)
+ m["detach"] = boolFromVarlink(opts.Detach, "detach", false)
+ m["detach-keys"] = stringFromVarlink(opts.DetachKeys, "detach-keys", nil)
+ m["device"] = stringSliceFromVarlink(opts.Device, "device", nil)
+ m["device-read-bps"] = stringSliceFromVarlink(opts.DeviceReadBps, "device-read-bps", nil)
+ m["device-read-iops"] = stringSliceFromVarlink(opts.DeviceReadIops, "device-read-iops", nil)
+ m["device-write-bps"] = stringSliceFromVarlink(opts.DeviceWriteBps, "write-device-bps", nil)
+ m["device-write-iops"] = stringSliceFromVarlink(opts.DeviceWriteIops, "write-device-iops", nil)
+ m["dns"] = stringSliceFromVarlink(opts.Dns, "dns", nil)
+ m["dns-opt"] = stringSliceFromVarlink(opts.DnsOpt, "dns-opt", nil)
+ m["dns-search"] = stringSliceFromVarlink(opts.DnsSearch, "dns-search", nil)
+ m["entrypoint"] = stringFromVarlink(opts.Entrypoint, "entrypoint", nil)
+ m["env"] = stringArrayFromVarlink(opts.Env, "env", nil)
+ m["env-file"] = stringSliceFromVarlink(opts.EnvFile, "env-file", nil)
+ m["expose"] = stringSliceFromVarlink(opts.Expose, "expose", nil)
+ m["gidmap"] = stringSliceFromVarlink(opts.Gidmap, "gidmap", nil)
+ m["group-add"] = stringSliceFromVarlink(opts.Groupadd, "group-add", nil)
+ m["healthcheck-command"] = stringFromVarlink(opts.HealthcheckCommand, "healthcheck-command", nil)
+ m["healthcheck-interval"] = stringFromVarlink(opts.HealthcheckInterval, "healthcheck-interval", &cliconfig.DefaultHealthCheckInterval)
+ m["healthcheck-retries"] = uintFromVarlink(opts.HealthcheckRetries, "healthcheck-retries", &cliconfig.DefaultHealthCheckRetries)
+ m["healthcheck-start-period"] = stringFromVarlink(opts.HealthcheckStartPeriod, "healthcheck-start-period", &cliconfig.DefaultHealthCheckStartPeriod)
+ m["healthcheck-timeout"] = stringFromVarlink(opts.HealthcheckTimeout, "healthcheck-timeout", &cliconfig.DefaultHealthCheckTimeout)
+ m["hostname"] = stringFromVarlink(opts.Hostname, "hostname", nil)
+ m["image-volume"] = stringFromVarlink(opts.ImageVolume, "image-volume", &cliconfig.DefaultImageVolume)
+ m["init"] = boolFromVarlink(opts.Init, "init", false)
+ m["init-path"] = stringFromVarlink(opts.InitPath, "init-path", nil)
+ m["interactive"] = boolFromVarlink(opts.Interactive, "interactive", false)
+ m["ip"] = stringFromVarlink(opts.Ip, "ip", nil)
+ m["ipc"] = stringFromVarlink(opts.Ipc, "ipc", nil)
+ m["kernel-memory"] = stringFromVarlink(opts.KernelMemory, "kernel-memory", nil)
+ m["label"] = stringArrayFromVarlink(opts.Label, "label", nil)
+ m["label-file"] = stringSliceFromVarlink(opts.LabelFile, "label-file", nil)
+ m["log-driver"] = stringFromVarlink(opts.LogDriver, "log-driver", nil)
+ m["log-opt"] = stringSliceFromVarlink(opts.LogOpt, "log-opt", nil)
+ m["mac-address"] = stringFromVarlink(opts.MacAddress, "mac-address", nil)
+ m["memory"] = stringFromVarlink(opts.Memory, "memory", nil)
+ m["memory-reservation"] = stringFromVarlink(opts.MemoryReservation, "memory-reservation", nil)
+ m["memory-swap"] = stringFromVarlink(opts.MemorySwap, "memory-swap", nil)
+ m["memory-swappiness"] = int64FromVarlink(opts.MemorySwappiness, "memory-swappiness", nil)
+ m["name"] = stringFromVarlink(opts.Name, "name", nil)
+ m["net"] = stringFromVarlink(opts.Net, "net", nil)
+ m["network"] = stringFromVarlink(opts.Network, "network", nil)
+ m["no-hosts"] = boolFromVarlink(opts.NoHosts, "no-hosts", false)
+ m["oom-kill-disable"] = boolFromVarlink(opts.OomKillDisable, "oon-kill-disable", false)
+ m["oom-score-adj"] = intFromVarlink(opts.OomScoreAdj, "oom-score-adj", nil)
+ m["pid"] = stringFromVarlink(opts.Pid, "pid", nil)
+ m["pids-limit"] = int64FromVarlink(opts.PidsLimit, "pids-limit", nil)
+ m["pod"] = stringFromVarlink(opts.Pod, "pod", nil)
+ m["privileged"] = boolFromVarlink(opts.Privileged, "privileged", false)
+ m["publish"] = stringSliceFromVarlink(opts.Publish, "publish", nil)
+ m["publish-all"] = boolFromVarlink(opts.PublishAll, "publish-all", false)
+ m["quiet"] = boolFromVarlink(opts.Quiet, "quiet", false)
+ m["read-only"] = boolFromVarlink(opts.Readonly, "read-only", false)
+ m["restart"] = stringFromVarlink(opts.Restart, "restart", nil)
+ m["rm"] = boolFromVarlink(opts.Rm, "rm", false)
+ m["rootfs"] = boolFromVarlink(opts.Rootfs, "rootfs", false)
+ m["security-opt"] = stringArrayFromVarlink(opts.SecurityOpt, "security-opt", nil)
+ m["shm-size"] = stringFromVarlink(opts.ShmSize, "shm-size", &cliconfig.DefaultShmSize)
+ m["stop-signal"] = stringFromVarlink(opts.StopSignal, "stop-signal", nil)
+ m["stop-timeout"] = uintFromVarlink(opts.StopTimeout, "stop-timeout", nil)
+ m["storage-opt"] = stringSliceFromVarlink(opts.StorageOpt, "storage-opt", nil)
+ m["subgidname"] = stringFromVarlink(opts.Subgidname, "subgidname", nil)
+ m["subuidname"] = stringFromVarlink(opts.Subuidname, "subuidname", nil)
+ m["sysctl"] = stringSliceFromVarlink(opts.Sysctl, "sysctl", nil)
+ m["systemd"] = boolFromVarlink(opts.Systemd, "systemd", cliconfig.DefaultSystemD)
+ m["tmpfs"] = stringSliceFromVarlink(opts.Tmpfs, "tmpfs", nil)
+ m["tty"] = boolFromVarlink(opts.Tty, "tty", false)
+ m["uidmap"] = stringSliceFromVarlink(opts.Uidmap, "uidmap", nil)
+ m["ulimit"] = stringSliceFromVarlink(opts.Ulimit, "ulimit", nil)
+ m["user"] = stringFromVarlink(opts.User, "user", nil)
+ m["userns"] = stringFromVarlink(opts.Userns, "userns", nil)
+ m["uts"] = stringFromVarlink(opts.Uts, "uts", nil)
+ m["mount"] = stringArrayFromVarlink(opts.Mount, "mount", nil)
+ m["volume"] = stringArrayFromVarlink(opts.Volume, "volume", nil)
+ m["volumes-from"] = stringSliceFromVarlink(opts.VolumesFrom, "volumes-from", nil)
+ m["workdir"] = stringFromVarlink(opts.WorkDir, "workdir", nil)
+
+ gcli := GenericCLIResults{m, opts.Args}
+ return gcli
+}
+
+// Find returns a flag from a GenericCLIResults by name
+func (g GenericCLIResults) Find(name string) GenericCLIResult {
+ result, ok := g.results[name]
+ if ok {
+ return result
+ }
+ panic(errors.Errorf("unable to find generic flag for varlink %s", name))
+}
diff --git a/cmd/podman/sigproxy.go b/cmd/podman/sigproxy.go
deleted file mode 100644
index 16861bad0..000000000
--- a/cmd/podman/sigproxy.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package main
-
-import (
- "os"
- "syscall"
-
- "github.com/containers/libpod/libpod"
- "github.com/docker/docker/pkg/signal"
- "github.com/sirupsen/logrus"
-)
-
-func ProxySignals(ctr *libpod.Container) {
- sigBuffer := make(chan os.Signal, 128)
- signal.CatchAll(sigBuffer)
-
- logrus.Debugf("Enabling signal proxying")
-
- go func() {
- for s := range sigBuffer {
- // Ignore SIGCHLD and SIGPIPE - these are mostly likely
- // intended for the podman command itself.
- if s == signal.SIGCHLD || s == signal.SIGPIPE {
- continue
- }
-
- if err := ctr.Kill(uint(s.(syscall.Signal))); err != nil {
- logrus.Errorf("Error forwarding signal %d to container %s: %v", s, ctr.ID(), err)
- signal.StopCatch(sigBuffer)
- syscall.Kill(syscall.Getpid(), s.(syscall.Signal))
- }
- }
- }()
-
- return
-}
diff --git a/cmd/podman/start.go b/cmd/podman/start.go
index d17a78268..7d97319dd 100644
--- a/cmd/podman/start.go
+++ b/cmd/podman/start.go
@@ -7,6 +7,7 @@ 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/adapter"
opentracing "github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -109,7 +110,7 @@ func startCmd(c *cliconfig.StartValues) error {
// attach to the container and also start it not already running
// If the container is in a pod, also set to recursively start dependencies
- err = startAttachCtr(ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, sigProxy, !ctrRunning, ctr.PodID() != "")
+ err = adapter.StartAttachCtr(ctx, ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, sigProxy, !ctrRunning, ctr.PodID() != "")
if errors.Cause(err) == libpod.ErrDetach {
// User manually detached
// Exit cleanly immediately
@@ -133,7 +134,7 @@ func startCmd(c *cliconfig.StartValues) error {
if err != nil {
return err
}
- ctrExitCode, err := readExitFile(rtc.TmpDir, ctr.ID())
+ ctrExitCode, err := adapter.ReadExitFile(rtc.TmpDir, ctr.ID())
if err != nil {
logrus.Errorf("Cannot get exit code: %v", err)
exitCode = 127
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/utils.go b/cmd/podman/utils.go
index 45d081512..c763940db 100644
--- a/cmd/podman/utils.go
+++ b/cmd/podman/utils.go
@@ -1,205 +1,11 @@
package main
import (
- "context"
"fmt"
- "github.com/spf13/pflag"
- "os"
- gosignal "os/signal"
- "github.com/containers/libpod/cmd/podman/cliconfig"
- "github.com/containers/libpod/libpod"
- "github.com/docker/docker/pkg/signal"
- "github.com/docker/docker/pkg/term"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
- "golang.org/x/crypto/ssh/terminal"
- "k8s.io/client-go/tools/remotecommand"
+ "github.com/spf13/pflag"
)
-type RawTtyFormatter struct {
-}
-
-// Start (if required) and attach to a container
-func startAttachCtr(ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys string, sigProxy bool, startContainer bool, recursive bool) error {
- ctx := context.Background()
- resize := make(chan remotecommand.TerminalSize)
-
- haveTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
-
- // Check if we are attached to a terminal. If we are, generate resize
- // events, and set the terminal to raw mode
- if haveTerminal && ctr.Spec().Process.Terminal {
- logrus.Debugf("Handling terminal attach")
-
- subCtx, cancel := context.WithCancel(ctx)
- defer cancel()
-
- resizeTty(subCtx, resize)
-
- oldTermState, err := term.SaveState(os.Stdin.Fd())
- if err != nil {
- return errors.Wrapf(err, "unable to save terminal state")
- }
-
- logrus.SetFormatter(&RawTtyFormatter{})
- term.SetRawTerminal(os.Stdin.Fd())
-
- defer restoreTerminal(oldTermState)
- }
-
- streams := new(libpod.AttachStreams)
- streams.OutputStream = stdout
- streams.ErrorStream = stderr
- streams.InputStream = stdin
- streams.AttachOutput = true
- streams.AttachError = true
- streams.AttachInput = true
-
- if stdout == nil {
- logrus.Debugf("Not attaching to stdout")
- streams.AttachOutput = false
- }
- if stderr == nil {
- logrus.Debugf("Not attaching to stderr")
- streams.AttachError = false
- }
- if stdin == nil {
- logrus.Debugf("Not attaching to stdin")
- streams.AttachInput = false
- }
-
- if !startContainer {
- if sigProxy {
- ProxySignals(ctr)
- }
-
- return ctr.Attach(streams, detachKeys, resize)
- }
-
- attachChan, err := ctr.StartAndAttach(getContext(), streams, detachKeys, resize, recursive)
- if err != nil {
- return err
- }
-
- if sigProxy {
- ProxySignals(ctr)
- }
-
- if stdout == nil && stderr == nil {
- fmt.Printf("%s\n", ctr.ID())
- }
-
- err = <-attachChan
- if err != nil {
- return errors.Wrapf(err, "error attaching to container %s", ctr.ID())
- }
-
- return nil
-}
-
-// getResize returns a TerminalSize command matching stdin's current
-// size on success, and nil on errors.
-func getResize() *remotecommand.TerminalSize {
- winsize, err := term.GetWinsize(os.Stdin.Fd())
- if err != nil {
- logrus.Warnf("Could not get terminal size %v", err)
- return nil
- }
- return &remotecommand.TerminalSize{
- Width: winsize.Width,
- Height: winsize.Height,
- }
-}
-
-// Helper for prepareAttach - set up a goroutine to generate terminal resize events
-func resizeTty(ctx context.Context, resize chan remotecommand.TerminalSize) {
- sigchan := make(chan os.Signal, 1)
- gosignal.Notify(sigchan, signal.SIGWINCH)
- go func() {
- defer close(resize)
- // Update the terminal size immediately without waiting
- // for a SIGWINCH to get the correct initial size.
- resizeEvent := getResize()
- for {
- if resizeEvent == nil {
- select {
- case <-ctx.Done():
- return
- case <-sigchan:
- resizeEvent = getResize()
- }
- } else {
- select {
- case <-ctx.Done():
- return
- case <-sigchan:
- resizeEvent = getResize()
- case resize <- *resizeEvent:
- resizeEvent = nil
- }
- }
- }
- }()
-}
-
-func restoreTerminal(state *term.State) error {
- logrus.SetFormatter(&logrus.TextFormatter{})
- return term.RestoreTerminal(os.Stdin.Fd(), state)
-}
-
-func (f *RawTtyFormatter) Format(entry *logrus.Entry) ([]byte, error) {
- textFormatter := logrus.TextFormatter{}
- bytes, err := textFormatter.Format(entry)
-
- if err == nil {
- bytes = append(bytes, '\r')
- }
-
- return bytes, err
-}
-
-// For pod commands that have a latest and all flag, getPodsFromContext gets
-// pods the user specifies. If there's an error before getting pods, the pods slice
-// will be empty and error will be not nil. If an error occured after, the pod slice
-// will hold all of the successful pods, and error will hold the last error.
-// The remaining errors will be logged. On success, pods will hold all pods and
-// error will be nil.
-func getPodsFromContext(c *cliconfig.PodmanCommand, r *libpod.Runtime) ([]*libpod.Pod, error) {
- args := c.InputArgs
- var pods []*libpod.Pod
- var lastError error
- var err error
-
- if c.Bool("all") {
- pods, err = r.GetAllPods()
- if err != nil {
- return nil, errors.Wrapf(err, "unable to get running pods")
- }
- }
-
- if c.Bool("latest") {
- pod, err := r.GetLatestPod()
- if err != nil {
- return nil, errors.Wrapf(err, "unable to get latest pod")
- }
- pods = append(pods, pod)
- }
-
- for _, i := range args {
- pod, err := r.LookupPod(i)
- if err != nil {
- if lastError != nil {
- logrus.Errorf("%q", lastError)
- }
- lastError = errors.Wrapf(err, "unable to find pod %s", i)
- continue
- }
- pods = append(pods, pod)
- }
- return pods, lastError
-}
-
//printParallelOutput takes the map of parallel worker results and outputs them
// to stdout
func printParallelOutput(m map[string]error, errCount int) error {
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 5e996f46b..9098a9297 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.
@@ -224,117 +225,104 @@ type Sockets(
control_socket: string
)
-# Create is an input structure for creating containers. It closely resembles the
-# CreateConfig structure in libpod/pkg/spec.
+# Create is an input structure for creating containers.
type Create (
args: []string,
- cap_add: []string,
- cap_drop: []string,
- conmon_pidfile: string,
- cgroup_parent: string,
- command: []string,
- detach: bool,
- devices: []string,
- dns_opt: []string,
- dns_search: []string,
- dns_servers: []string,
- entrypoint: []string,
- env: [string]string,
- exposed_ports: []string,
- gidmap: []string,
- group_add: []string,
- host_add: []string,
- hostname: string,
- image: string,
- image_id: string,
- init: bool,
- init_path: string,
- builtin_imgvolumes: []string,
- id_mappings: IDMappingOptions,
- image_volume_type: string,
- interactive: bool,
- ipc_mode: string,
- labels: [string]string,
- log_driver: string,
- log_driver_opt: []string,
- name: string,
- net_mode: string,
- network: string,
- pid_mode: string,
- pod: string,
- privileged: bool,
- publish: []string,
- publish_all: bool,
- quiet: bool,
- readonly_rootfs: bool,
- resources: CreateResourceConfig,
- rm: bool,
- shm_dir: string,
- stop_signal: int,
- stop_timeout: int,
- subuidmap: string,
- subgidmap: string,
- subuidname: string,
- subgidname: string,
- sys_ctl: [string]string,
- tmpfs: []string,
- tty: bool,
- uidmap: []string,
- userns_mode: string,
- user: string,
- uts_mode: string,
- volumes: []string,
- work_dir: string,
- mount_label: string,
- process_label: string,
- no_new_privs: bool,
- apparmor_profile: string,
- seccomp_profile_path: string,
- security_opts: []string
-)
-
-# CreateResourceConfig is an input structure used to describe host attributes during
-# container creation. It is only valid inside a [Create](#Create) type.
-type CreateResourceConfig (
- blkio_weight: int,
- blkio_weight_device: []string,
- cpu_period: int,
- cpu_quota: int,
- cpu_rt_period: int,
- cpu_rt_runtime: int,
- cpu_shares: int,
- cpus: float,
- cpuset_cpus: string,
- cpuset_mems: string,
- device_read_bps: []string,
- device_read_iops: []string,
- device_write_bps: []string,
- device_write_iops: []string,
- disable_oomkiller: bool,
- kernel_memory: int,
- memory: int,
- memory_reservation: int,
- memory_swap: int,
- memory_swappiness: int,
- oom_score_adj: int,
- pids_limit: int,
- shm_size: int,
- ulimit: []string
-)
-
-# IDMappingOptions is an input structure used to described ids during container creation.
-type IDMappingOptions (
- host_uid_mapping: bool,
- host_gid_mapping: bool,
- uid_map: IDMap,
- gid_map: IDMap
-)
-
-# IDMap is used to describe user name spaces during container creation
-type IDMap (
- container_id: int,
- host_id: int,
- size: int
+ addHost: ?[]string,
+ annotation: ?[]string,
+ attach: ?[]string,
+ blkioWeight: ?string,
+ blkioWeightDevice: ?[]string,
+ capAdd: ?[]string,
+ capDrop: ?[]string,
+ cgroupParent: ?string,
+ cidFile: ?string,
+ conmonPidfile: ?string,
+ command: ?[]string,
+ cpuPeriod: ?int,
+ cpuQuota: ?int,
+ cpuRtPeriod: ?int,
+ cpuRtRuntime: ?int,
+ cpuShares: ?int,
+ cpus: ?float,
+ cpuSetCpus: ?string,
+ cpuSetMems: ?string,
+ detach: ?bool,
+ detachKeys: ?string,
+ device: ?[]string,
+ deviceReadBps: ?[]string,
+ deviceReadIops: ?[]string,
+ deviceWriteBps: ?[]string,
+ deviceWriteIops: ?[]string,
+ dns: ?[]string,
+ dnsOpt: ?[]string,
+ dnsSearch: ?[]string,
+ dnsServers: ?[]string,
+ entrypoint: ?string,
+ env: ?[]string,
+ envFile: ?[]string,
+ expose: ?[]string,
+ gidmap: ?[]string,
+ groupadd: ?[]string,
+ healthcheckCommand: ?string,
+ healthcheckInterval: ?string,
+ healthcheckRetries: ?int,
+ healthcheckStartPeriod: ?string,
+ healthcheckTimeout:?string,
+ hostname: ?string,
+ imageVolume: ?string,
+ init: ?bool,
+ initPath: ?string,
+ interactive: ?bool,
+ ip: ?string,
+ ipc: ?string,
+ kernelMemory: ?string,
+ label: ?[]string,
+ labelFile: ?[]string,
+ logDriver: ?string,
+ logOpt: ?[]string,
+ macAddress: ?string,
+ memory: ?string,
+ memoryReservation: ?string,
+ memorySwap: ?string,
+ memorySwappiness: ?int,
+ name: ?string,
+ net: ?string,
+ network: ?string,
+ noHosts: ?bool,
+ oomKillDisable: ?bool,
+ oomScoreAdj: ?int,
+ pid: ?string,
+ pidsLimit: ?int,
+ pod: ?string,
+ privileged: ?bool,
+ publish: ?[]string,
+ publishAll: ?bool,
+ quiet: ?bool,
+ readonly: ?bool,
+ restart: ?string,
+ rm: ?bool,
+ rootfs: ?bool,
+ securityOpt: ?[]string,
+ shmSize: ?string,
+ stopSignal: ?string,
+ stopTimeout: ?int,
+ storageOpt: ?[]string,
+ subuidname: ?string,
+ subgidname: ?string,
+ sysctl: ?[]string,
+ systemd: ?bool,
+ tmpfs: ?[]string,
+ tty: ?bool,
+ uidmap: ?[]string,
+ ulimit: ?[]string,
+ user: ?string,
+ userns: ?string,
+ uts: ?string,
+ mount: ?[]string,
+ volume: ?[]string,
+ volumesFrom: ?[]string,
+ workDir: ?string
)
# BuildOptions are are used to describe describe physical attributes of the build
@@ -461,6 +449,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,
@@ -490,16 +485,7 @@ method GetContainer(id: string) -> (container: Container)
# user environment, results might differ from what you expect.
method GetContainersByContext(all: bool, latest: bool, args: []string) -> (containers: []string)
-# CreateContainer creates a new container from an image. It uses a [Create](#Create) type for input. The minimum
-# input required for CreateContainer is an image name. If the image name is not found, an [ImageNotFound](#ImageNotFound)
-# error will be returned. Otherwise, the ID of the newly created container will be returned.
-# #### Example
-# ~~~
-# $ varlink call unix:/run/podman/io.podman/io.podman.CreateContainer '{"create": {"image": "alpine"}}'
-# {
-# "container": "8759dafbc0a4dc3bcfb57eeb72e4331eb73c5cc09ab968e65ce45b9ad5c4b6bb"
-# }
-# ~~~
+# CreateContainer creates a new container from an image. It uses a [Create](#Create) type for input.
method CreateContainer(create: Create) -> (container: string)
# InspectContainer data takes a name or ID of a container returns the inspection
@@ -1122,6 +1108,9 @@ method ContainerStateData(name: string) -> (config: string)
# development of Podman only and generally should not be used.
method PodStateData(name: string) -> (config: string)
+# This call is for the development of Podman only and should not be used.
+method CreateFromCC(in: []string) -> (id: string)
+
# Sendfile allows a remote client to send a file to the host
method SendFile(type: string, length: int) -> (file_handle: string)
@@ -1154,6 +1143,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)