summaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/cliconfig/config.go16
-rw-r--r--cmd/podman/common.go4
-rw-r--r--cmd/podman/cp.go5
-rw-r--r--cmd/podman/libpodruntime/runtime.go19
-rw-r--r--cmd/podman/main.go2
-rw-r--r--cmd/podman/main_local.go2
-rw-r--r--cmd/podman/main_remote.go38
-rw-r--r--cmd/podman/main_remote_supported.go57
-rw-r--r--cmd/podman/main_remote_windows.go7
-rw-r--r--cmd/podman/network.go31
-rw-r--r--cmd/podman/network_inspect.go48
-rw-r--r--cmd/podman/network_list.go53
-rw-r--r--cmd/podman/network_rm.go48
-rw-r--r--cmd/podman/pod_create.go3
-rw-r--r--cmd/podman/pod_stats.go13
-rw-r--r--cmd/podman/port.go11
-rw-r--r--cmd/podman/pull.go4
-rw-r--r--cmd/podman/remoteclientconfig/config_linux.go9
-rw-r--r--cmd/podman/restore.go1
-rw-r--r--cmd/podman/shared/container.go8
-rw-r--r--cmd/podman/shared/create.go26
-rw-r--r--cmd/podman/shared/intermediate.go2
-rw-r--r--cmd/podman/shared/intermediate_varlink.go2
-rw-r--r--cmd/podman/sign.go3
-rw-r--r--cmd/podman/stats.go13
-rw-r--r--cmd/podman/system_df.go8
-rw-r--r--cmd/podman/varlink.go2
-rw-r--r--cmd/podman/varlink/io.podman.varlink7
28 files changed, 366 insertions, 76 deletions
diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go
index 37d6d3908..e7ad921da 100644
--- a/cmd/podman/cliconfig/config.go
+++ b/cmd/podman/cliconfig/config.go
@@ -258,6 +258,20 @@ type MountValues struct {
Latest bool
}
+type NetworkListValues struct {
+ PodmanCommand
+ Filter []string
+ Quiet bool
+}
+
+type NetworkRmValues struct {
+ PodmanCommand
+}
+
+type NetworkInspectValues struct {
+ PodmanCommand
+}
+
type PauseValues struct {
PodmanCommand
All bool
@@ -286,6 +300,7 @@ type PodCreateValues struct {
LabelFile []string
Labels []string
Name string
+ Hostname string
PodIDFile string
Publish []string
Share string
@@ -437,6 +452,7 @@ type RestoreValues struct {
Import string
Name string
IgnoreRootfs bool
+ IgnoreStaticIP bool
}
type RmValues struct {
diff --git a/cmd/podman/common.go b/cmd/podman/common.go
index 1e9092bd6..32478bb51 100644
--- a/cmd/podman/common.go
+++ b/cmd/podman/common.go
@@ -388,6 +388,10 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"publish-all", "P", false,
"Publish all exposed ports to random ports on the host interface",
)
+ createFlags.String(
+ "pull", "missing",
+ `Pull image before creating ("always"|"missing"|"never") (default "missing")`,
+ )
createFlags.BoolP(
"quiet", "q", false,
"Suppress output information when pulling images",
diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go
index bee7d2199..ad7253ac0 100644
--- a/cmd/podman/cp.go
+++ b/cmd/podman/cp.go
@@ -140,7 +140,7 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin
if err != nil {
return errors.Wrapf(err, "error getting IDMappingOptions")
}
- containerOwner := idtools.IDPair{UID: int(user.UID), GID: int(user.GID)}
+ destOwner := idtools.IDPair{UID: int(user.UID), GID: int(user.GID)}
hostUID, hostGID, err := util.GetHostIDs(convertIDMap(idMappingOpts.UIDMap), convertIDMap(idMappingOpts.GIDMap), user.UID, user.GID)
if err != nil {
return err
@@ -183,6 +183,7 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin
destPath = cleanedPath
}
} else {
+ destOwner = idtools.IDPair{UID: os.Getuid(), GID: os.Getgid()}
if isVol, volDestName, volName := isVolumeDestName(srcPath, ctr); isVol {
path, err := pathWithVolumeMount(ctr, runtime, volDestName, volName, srcPath)
if err != nil {
@@ -230,7 +231,7 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin
src = os.Stdin.Name()
extract = true
}
- err := copy(src, destPath, dest, idMappingOpts, &containerOwner, extract, isFromHostToCtr)
+ err := copy(src, destPath, dest, idMappingOpts, &destOwner, extract, isFromHostToCtr)
if lastError != nil {
logrus.Error(lastError)
}
diff --git a/cmd/podman/libpodruntime/runtime.go b/cmd/podman/libpodruntime/runtime.go
index ee9e57966..a133549ea 100644
--- a/cmd/podman/libpodruntime/runtime.go
+++ b/cmd/podman/libpodruntime/runtime.go
@@ -15,25 +15,30 @@ import (
// GetRuntimeMigrate gets a libpod runtime that will perform a migration of existing containers
func GetRuntimeMigrate(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
- return getRuntime(ctx, c, false, true, false)
+ return getRuntime(ctx, c, false, true, false, true)
+}
+
+// GetRuntimeDisableFDs gets a libpod runtime that will disable sd notify
+func GetRuntimeDisableFDs(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
+ return getRuntime(ctx, c, false, false, false, false)
}
// GetRuntimeRenumber gets a libpod runtime that will perform a lock renumber
func GetRuntimeRenumber(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
- return getRuntime(ctx, c, true, false, false)
+ return getRuntime(ctx, c, true, false, false, true)
}
// GetRuntime generates a new libpod runtime configured by command line options
func GetRuntime(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
- return getRuntime(ctx, c, false, false, false)
+ return getRuntime(ctx, c, false, false, false, true)
}
// GetRuntimeNoStore generates a new libpod runtime configured by command line options
func GetRuntimeNoStore(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
- return getRuntime(ctx, c, false, false, true)
+ return getRuntime(ctx, c, false, false, true, true)
}
-func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber, migrate, noStore bool) (*libpod.Runtime, error) {
+func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber, migrate, noStore, withFDS bool) (*libpod.Runtime, error) {
options := []libpod.RuntimeOption{}
storageOpts := storage.StoreOptions{}
storageSet := false
@@ -165,6 +170,10 @@ func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber, migra
infraCommand, _ := c.Flags().GetString("infra-command")
options = append(options, libpod.WithDefaultInfraCommand(infraCommand))
}
+
+ if withFDS {
+ options = append(options, libpod.WithEnableSDNotify())
+ }
if c.Flags().Changed("config") {
return libpod.NewRuntimeFromConfig(ctx, c.GlobalFlags.Config, options...)
}
diff --git a/cmd/podman/main.go b/cmd/podman/main.go
index 1b54c9458..dc44a9110 100644
--- a/cmd/podman/main.go
+++ b/cmd/podman/main.go
@@ -101,7 +101,7 @@ func initConfig() {
}
func before(cmd *cobra.Command, args []string) error {
- if err := libpod.SetXdgRuntimeDir(); err != nil {
+ if err := libpod.SetXdgDirs(); err != nil {
logrus.Errorf(err.Error())
os.Exit(1)
}
diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go
index 5c8b2b1ff..587c8260f 100644
--- a/cmd/podman/main_local.go
+++ b/cmd/podman/main_local.go
@@ -1,4 +1,5 @@
// +build !remoteclient
+// +build linux
package main
@@ -122,6 +123,7 @@ func setupRootless(cmd *cobra.Command, args []string) error {
if os.Geteuid() == 0 || cmd == _searchCommand || cmd == _versionCommand || cmd == _mountCommand || cmd == _migrateCommand || strings.HasPrefix(cmd.Use, "help") {
return nil
}
+
podmanCmd := cliconfig.PodmanCommand{
Command: cmd,
InputArgs: args,
diff --git a/cmd/podman/main_remote.go b/cmd/podman/main_remote.go
index ecbb44d5a..a005e925c 100644
--- a/cmd/podman/main_remote.go
+++ b/cmd/podman/main_remote.go
@@ -3,13 +3,8 @@
package main
import (
- "fmt"
- "os"
"os/user"
- "path/filepath"
- "github.com/docker/docker/pkg/homedir"
- "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
@@ -30,39 +25,6 @@ func init() {
rootCmd.PersistentFlags().BoolVar(&MainGlobalOpts.Syslog, "syslog", false, "Output logging information to syslog as well as the console")
}
-func setSyslog() error {
- // Log to file if not using syslog
- homeDir := homedir.Get()
- path := filepath.Join(homeDir, ".config", "containers")
-
- if _, err := os.Stat(path); os.IsNotExist(err) {
- if err := os.MkdirAll(path, 0750); err != nil {
- fmt.Fprintf(os.Stderr, "%v", err)
- return err
- }
- }
-
- // Update path to include file name
- path = filepath.Join(path, "podman.log")
-
- // Create the log file if doesn't exist. And append to it if it already exists.
- file, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0640)
- if err != nil {
- // Cannot open log file. Logging to stderr
- fmt.Fprintf(os.Stderr, "%v", err)
- return err
- } else {
- formatter := new(logrus.TextFormatter)
- formatter.FullTimestamp = true
- logrus.SetFormatter(formatter)
- logrus.SetOutput(file)
- }
-
- // Note this message is only logged if --log-level >= Info!
- logrus.Infof("Logging level set to %s", logrus.GetLevel().String())
- return nil
-}
-
func profileOn(cmd *cobra.Command) error {
return nil
}
diff --git a/cmd/podman/main_remote_supported.go b/cmd/podman/main_remote_supported.go
new file mode 100644
index 000000000..bb567c273
--- /dev/null
+++ b/cmd/podman/main_remote_supported.go
@@ -0,0 +1,57 @@
+// +build remoteclient
+// +build linux darwin
+
+package main
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+
+ "github.com/containers/libpod/pkg/util"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+func setSyslog() error {
+ var err error
+ cfgHomeDir := os.Getenv("XDG_CONFIG_HOME")
+ if cfgHomeDir == "" {
+ if cfgHomeDir, err = util.GetRootlessConfigHomeDir(); err != nil {
+ return err
+ }
+ if err = os.Setenv("XDG_CONFIG_HOME", cfgHomeDir); err != nil {
+ return errors.Wrapf(err, "cannot set XDG_CONFIG_HOME")
+ }
+ }
+ path := filepath.Join(cfgHomeDir, "containers")
+
+ // Log to file if not using syslog
+
+ if _, err := os.Stat(path); os.IsNotExist(err) {
+ if err := os.MkdirAll(path, 0750); err != nil {
+ fmt.Fprintf(os.Stderr, "%v", err)
+ return err
+ }
+ }
+
+ // Update path to include file name
+ path = filepath.Join(path, "podman.log")
+
+ // Create the log file if doesn't exist. And append to it if it already exists.
+ file, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0640)
+ if err != nil {
+ // Cannot open log file. Logging to stderr
+ fmt.Fprintf(os.Stderr, "%v", err)
+ return err
+ } else {
+ formatter := new(logrus.TextFormatter)
+ formatter.FullTimestamp = true
+ logrus.SetFormatter(formatter)
+ logrus.SetOutput(file)
+ }
+
+ // Note this message is only logged if --log-level >= Info!
+ logrus.Infof("Logging level set to %s", logrus.GetLevel().String())
+ return nil
+}
diff --git a/cmd/podman/main_remote_windows.go b/cmd/podman/main_remote_windows.go
new file mode 100644
index 000000000..0ef1370ce
--- /dev/null
+++ b/cmd/podman/main_remote_windows.go
@@ -0,0 +1,7 @@
+// +build remoteclient,windows
+
+package main
+
+func setSyslog() error {
+ return nil
+}
diff --git a/cmd/podman/network.go b/cmd/podman/network.go
new file mode 100644
index 000000000..83a5e71ab
--- /dev/null
+++ b/cmd/podman/network.go
@@ -0,0 +1,31 @@
+//+build !remoteclient
+
+package main
+
+import (
+ "github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/spf13/cobra"
+)
+
+var networkcheckDescription = "Manage networks"
+var networkcheckCommand = cliconfig.PodmanCommand{
+ Command: &cobra.Command{
+ Use: "network",
+ Short: "Manage Networks",
+ Long: networkcheckDescription,
+ RunE: commandRunE(),
+ },
+}
+
+// Commands that are universally implemented
+var networkcheckCommands = []*cobra.Command{
+ _networkinspectCommand,
+ _networklistCommand,
+ _networkrmCommand,
+}
+
+func init() {
+ networkcheckCommand.AddCommand(networkcheckCommands...)
+ networkcheckCommand.SetUsageTemplate(UsageTemplate())
+ rootCmd.AddCommand(networkcheckCommand.Command)
+}
diff --git a/cmd/podman/network_inspect.go b/cmd/podman/network_inspect.go
new file mode 100644
index 000000000..38aaf6ba4
--- /dev/null
+++ b/cmd/podman/network_inspect.go
@@ -0,0 +1,48 @@
+// +build !remoteclient
+
+package main
+
+import (
+ "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"
+)
+
+var (
+ networkinspectCommand cliconfig.NetworkInspectValues
+ networkinspectDescription = `Inspect network`
+ _networkinspectCommand = &cobra.Command{
+ Use: "inspect NETWORK [NETWORK...] [flags] ",
+ Short: "network inspect",
+ Long: networkinspectDescription,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ networkinspectCommand.InputArgs = args
+ networkinspectCommand.GlobalFlags = MainGlobalOpts
+ networkinspectCommand.Remote = remoteclient
+ return networkinspectCmd(&networkinspectCommand)
+ },
+ Example: `podman network inspect podman`,
+ }
+)
+
+func init() {
+ networkinspectCommand.Command = _networkinspectCommand
+ networkinspectCommand.SetHelpTemplate(HelpTemplate())
+ networkinspectCommand.SetUsageTemplate(UsageTemplate())
+}
+
+func networkinspectCmd(c *cliconfig.NetworkInspectValues) error {
+ if rootless.IsRootless() && !remoteclient {
+ return errors.New("network inspect is not supported for rootless mode")
+ }
+ if len(c.InputArgs) < 1 {
+ return errors.Errorf("at least one network name is required")
+ }
+ runtime, err := adapter.GetRuntimeNoStore(getContext(), &c.PodmanCommand)
+ if err != nil {
+ return err
+ }
+ return runtime.NetworkInspect(c)
+}
diff --git a/cmd/podman/network_list.go b/cmd/podman/network_list.go
new file mode 100644
index 000000000..16edf743b
--- /dev/null
+++ b/cmd/podman/network_list.go
@@ -0,0 +1,53 @@
+// +build !remoteclient
+
+package main
+
+import (
+ "errors"
+ "github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/containers/libpod/pkg/adapter"
+ "github.com/containers/libpod/pkg/rootless"
+ "github.com/spf13/cobra"
+)
+
+var (
+ networklistCommand cliconfig.NetworkListValues
+ networklistDescription = `List networks`
+ _networklistCommand = &cobra.Command{
+ Use: "ls",
+ Args: noSubArgs,
+ Short: "network list",
+ Long: networklistDescription,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ networklistCommand.InputArgs = args
+ networklistCommand.GlobalFlags = MainGlobalOpts
+ networklistCommand.Remote = remoteclient
+ return networklistCmd(&networklistCommand)
+ },
+ Example: `podman network list`,
+ }
+)
+
+func init() {
+ networklistCommand.Command = _networklistCommand
+ networklistCommand.SetHelpTemplate(HelpTemplate())
+ networklistCommand.SetUsageTemplate(UsageTemplate())
+ flags := networklistCommand.Flags()
+ // TODO enable filters based on something
+ //flags.StringSliceVarP(&networklistCommand.Filter, "filter", "f", []string{}, "Pause all running containers")
+ flags.BoolVarP(&networklistCommand.Quiet, "quiet", "q", false, "display only names")
+}
+
+func networklistCmd(c *cliconfig.NetworkListValues) error {
+ if rootless.IsRootless() && !remoteclient {
+ return errors.New("network list is not supported for rootless mode")
+ }
+ if len(c.InputArgs) > 0 {
+ return errors.New("network list takes no arguments")
+ }
+ runtime, err := adapter.GetRuntimeNoStore(getContext(), &c.PodmanCommand)
+ if err != nil {
+ return err
+ }
+ return runtime.NetworkList(c)
+}
diff --git a/cmd/podman/network_rm.go b/cmd/podman/network_rm.go
new file mode 100644
index 000000000..50bd48cea
--- /dev/null
+++ b/cmd/podman/network_rm.go
@@ -0,0 +1,48 @@
+// +build !remoteclient
+
+package main
+
+import (
+ "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"
+)
+
+var (
+ networkrmCommand cliconfig.NetworkRmValues
+ networkrmDescription = `Remove networks`
+ _networkrmCommand = &cobra.Command{
+ Use: "rm [flags] NETWORK [NETWORK...]",
+ Short: "network rm",
+ Long: networkrmDescription,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ networkrmCommand.InputArgs = args
+ networkrmCommand.GlobalFlags = MainGlobalOpts
+ networkrmCommand.Remote = remoteclient
+ return networkrmCmd(&networkrmCommand)
+ },
+ Example: `podman network rm podman`,
+ }
+)
+
+func init() {
+ networkrmCommand.Command = _networkrmCommand
+ networkrmCommand.SetHelpTemplate(HelpTemplate())
+ networkrmCommand.SetUsageTemplate(UsageTemplate())
+}
+
+func networkrmCmd(c *cliconfig.NetworkRmValues) error {
+ if rootless.IsRootless() && !remoteclient {
+ return errors.New("network rm is not supported for rootless mode")
+ }
+ if len(c.InputArgs) < 1 {
+ return errors.Errorf("at least one network name is required")
+ }
+ runtime, err := adapter.GetRuntimeNoStore(getContext(), &c.PodmanCommand)
+ if err != nil {
+ return err
+ }
+ return runtime.NetworkRemove(c)
+}
diff --git a/cmd/podman/pod_create.go b/cmd/podman/pod_create.go
index b6154b4db..ad3c00aa8 100644
--- a/cmd/podman/pod_create.go
+++ b/cmd/podman/pod_create.go
@@ -52,6 +52,7 @@ func init() {
flags.StringSliceVar(&podCreateCommand.LabelFile, "label-file", []string{}, "Read in a line delimited file of labels")
flags.StringSliceVarP(&podCreateCommand.Labels, "label", "l", []string{}, "Set metadata on pod (default [])")
flags.StringVarP(&podCreateCommand.Name, "name", "n", "", "Assign a name to the pod")
+ flags.StringVarP(&podCreateCommand.Hostname, "hostname", "", "", "Set a hostname to the pod")
flags.StringVar(&podCreateCommand.PodIDFile, "pod-id-file", "", "Write the pod ID to the file")
flags.StringSliceVarP(&podCreateCommand.Publish, "publish", "p", []string{}, "Publish a container's port, or a range of ports, to the host (default [])")
flags.StringVar(&podCreateCommand.Share, "share", shared.DefaultKernelNamespaces, "A comma delimited list of kernel namespaces the pod will share")
@@ -78,7 +79,7 @@ func podCreateCmd(c *cliconfig.PodCreateValues) error {
if !c.Infra && c.Flag("share").Changed && c.Share != "none" && c.Share != "" {
return errors.Errorf("You cannot share kernel namespaces on the pod level without an infra container")
}
- if c.Flag("pod-id-file").Changed && os.Geteuid() == 0 {
+ if c.Flag("pod-id-file").Changed {
podIdFile, err = util.OpenExclusiveFile(c.PodIDFile)
if err != nil && os.IsExist(err) {
return errors.Errorf("pod id file exists. Ensure another pod is not using it or delete %s", c.PodIDFile)
diff --git a/cmd/podman/pod_stats.go b/cmd/podman/pod_stats.go
index 46cacc026..2f1ebd3ac 100644
--- a/cmd/podman/pod_stats.go
+++ b/cmd/podman/pod_stats.go
@@ -15,6 +15,8 @@ import (
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/adapter"
+ "github.com/containers/libpod/pkg/cgroups"
+ "github.com/containers/libpod/pkg/rootless"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -53,9 +55,14 @@ func init() {
}
func podStatsCmd(c *cliconfig.PodStatsValues) error {
-
- if os.Geteuid() != 0 {
- return errors.New("stats is not supported in rootless mode")
+ if rootless.IsRootless() {
+ unified, err := cgroups.IsCgroup2UnifiedMode()
+ if err != nil {
+ return err
+ }
+ if !unified {
+ return errors.New("stats is not supported in rootless mode without cgroups v2")
+ }
}
format := c.Format
diff --git a/cmd/podman/port.go b/cmd/podman/port.go
index 5753c8e56..4e1f9642c 100644
--- a/cmd/podman/port.go
+++ b/cmd/podman/port.go
@@ -48,8 +48,8 @@ func init() {
func portCmd(c *cliconfig.PortValues) error {
var (
- userProto, containerName string
- userPort int
+ userProto string
+ userPort int
)
args := c.InputArgs
@@ -106,6 +106,7 @@ func portCmd(c *cliconfig.PortValues) error {
if err != nil {
return err
}
+ var found bool
// Iterate mappings
for _, v := range portmappings {
hostIP := v.HostIP
@@ -125,12 +126,14 @@ func portCmd(c *cliconfig.PortValues) error {
if v.ContainerPort == int32(userPort) {
if userProto == "" || userProto == v.Protocol {
fmt.Printf("%s:%d\n", hostIP, v.HostPort)
+ found = true
break
}
- } else {
- return errors.Errorf("No public port '%d' published for %s", userPort, containerName)
}
}
+ if !found && port != "" {
+ return errors.Errorf("failed to find published port '%d'", userPort)
+ }
}
return nil
diff --git a/cmd/podman/pull.go b/cmd/podman/pull.go
index 0eee51e79..53f133929 100644
--- a/cmd/podman/pull.go
+++ b/cmd/podman/pull.go
@@ -150,7 +150,7 @@ func pullCmd(c *cliconfig.PullValues) (retError error) {
// See https://bugzilla.redhat.com/show_bug.cgi?id=1701922 for background
// information.
if !c.Bool("all-tags") {
- newImage, err := runtime.New(getContext(), imgArg, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, true, nil)
+ newImage, err := runtime.New(getContext(), imgArg, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, nil, util.PullImageAlways)
if err != nil {
return errors.Wrapf(err, "error pulling image %q", imgArg)
}
@@ -188,7 +188,7 @@ func pullCmd(c *cliconfig.PullValues) (retError error) {
var foundIDs []string
foundImage := true
for _, name := range names {
- newImage, err := runtime.New(getContext(), name, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, true, nil)
+ newImage, err := runtime.New(getContext(), name, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, nil, util.PullImageAlways)
if err != nil {
logrus.Errorf("error pulling image %q", name)
foundImage = false
diff --git a/cmd/podman/remoteclientconfig/config_linux.go b/cmd/podman/remoteclientconfig/config_linux.go
index b94941381..5d27f19f2 100644
--- a/cmd/podman/remoteclientconfig/config_linux.go
+++ b/cmd/podman/remoteclientconfig/config_linux.go
@@ -1,12 +1,17 @@
package remoteclientconfig
import (
+ "os"
"path/filepath"
"github.com/docker/docker/pkg/homedir"
)
func getConfigFilePath() string {
- homeDir := homedir.Get()
- return filepath.Join(homeDir, ".config", "containers", remoteConfigFileName)
+ path := os.Getenv("XDG_CONFIG_HOME")
+ if path == "" {
+ homeDir := homedir.Get()
+ path = filepath.Join(homeDir, ".config")
+ }
+ return filepath.Join(path, "containers", remoteConfigFileName)
}
diff --git a/cmd/podman/restore.go b/cmd/podman/restore.go
index 3ae141d41..90d0b2dc4 100644
--- a/cmd/podman/restore.go
+++ b/cmd/podman/restore.go
@@ -46,6 +46,7 @@ func init() {
flags.StringVarP(&restoreCommand.Import, "import", "i", "", "Restore from exported checkpoint archive (tar.gz)")
flags.StringVarP(&restoreCommand.Name, "name", "n", "", "Specify new name for container restored from exported checkpoint (only works with --import)")
flags.BoolVar(&restoreCommand.IgnoreRootfs, "ignore-rootfs", false, "Do not apply root file-system changes when importing from exported checkpoint")
+ flags.BoolVar(&restoreCommand.IgnoreStaticIP, "ignore-static-ip", false, "Ignore IP address set via --static-ip")
markFlagHiddenForRemoteClient("latest", flags)
}
diff --git a/cmd/podman/shared/container.go b/cmd/podman/shared/container.go
index 7f53f5ec9..5122d37d1 100644
--- a/cmd/podman/shared/container.go
+++ b/cmd/podman/shared/container.go
@@ -660,7 +660,7 @@ func formatGroup(key string, start, last int32) string {
}
// portsToString converts the ports used to a string of the from "port1, port2"
-// and also groups continuous list of ports in readable format.
+// and also groups a continuous list of ports into a readable format.
func portsToString(ports []ocicni.PortMapping) string {
type portGroup struct {
first int32
@@ -732,7 +732,7 @@ func GetRunlabel(label string, runlabelImage string, ctx context.Context, runtim
registryCreds = creds
}
dockerRegistryOptions.DockerRegistryCreds = registryCreds
- newImage, err = runtime.ImageRuntime().New(ctx, runlabelImage, signaturePolicyPath, authfile, output, &dockerRegistryOptions, image.SigningOptions{}, false, &label)
+ newImage, err = runtime.ImageRuntime().New(ctx, runlabelImage, signaturePolicyPath, authfile, output, &dockerRegistryOptions, image.SigningOptions{}, &label, util.PullImageMissing)
} else {
newImage, err = runtime.ImageRuntime().NewFromLocal(runlabelImage)
}
@@ -750,7 +750,7 @@ func GetRunlabel(label string, runlabelImage string, ctx context.Context, runtim
return runLabel, imageName, err
}
-// GenerateRunlabelCommand generates the command that will eventually be execucted by podman.
+// GenerateRunlabelCommand generates the command that will eventually be execucted by Podman.
func GenerateRunlabelCommand(runLabel, imageName, name string, opts map[string]string, extraArgs []string, globalOpts string) ([]string, []string, error) {
// If no name is provided, we use the image's basename instead.
if name == "" {
@@ -809,7 +809,7 @@ func envSliceToMap(env []string) map[string]string {
return m
}
-// GenerateKube generates kubernetes yaml based on a pod or container
+// GenerateKube generates kubernetes yaml based on a pod or container.
func GenerateKube(name string, service bool, r *libpod.Runtime) (*v1.Pod, *v1.Service, error) {
var (
pod *libpod.Pod
diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go
index 4de68e4bc..094330e24 100644
--- a/cmd/podman/shared/create.go
+++ b/cmd/podman/shared/create.go
@@ -55,7 +55,7 @@ func CreateContainer(ctx context.Context, c *GenericCLIResults, runtime *libpod.
rootfs = c.InputArgs[0]
}
- if c.IsSet("cidfile") && os.Geteuid() == 0 {
+ if c.IsSet("cidfile") {
cidFile, err = util.OpenExclusiveFile(c.String("cidfile"))
if err != nil && os.IsExist(err) {
return nil, nil, errors.Errorf("container id file exists. Ensure another container is not using it or delete %s", c.String("cidfile"))
@@ -70,8 +70,8 @@ func CreateContainer(ctx context.Context, c *GenericCLIResults, runtime *libpod.
imageName := ""
var data *inspect.ImageData = nil
- // Set the storage if we are running as euid == 0 and there is no rootfs specified
- if rootfs == "" && os.Geteuid() == 0 {
+ // Set the storage if there is no rootfs specified
+ if rootfs == "" {
var writer io.Writer
if !c.Bool("quiet") {
writer = os.Stderr
@@ -83,7 +83,13 @@ func CreateContainer(ctx context.Context, c *GenericCLIResults, runtime *libpod.
} else {
return nil, nil, errors.Errorf("error, no input arguments were provided")
}
- newImage, err := runtime.ImageRuntime().New(ctx, name, rtc.SignaturePolicyPath, GetAuthFile(""), writer, nil, image.SigningOptions{}, false, nil)
+
+ pullType, err := util.ValidatePullType(c.String("pull"))
+ if err != nil {
+ return nil, nil, err
+ }
+
+ newImage, err := runtime.ImageRuntime().New(ctx, name, rtc.SignaturePolicyPath, GetAuthFile(c.String("authfile")), writer, nil, image.SigningOptions{}, nil, pullType)
if err != nil {
return nil, nil, err
}
@@ -588,6 +594,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
workDir = data.Config.WorkingDir
}
+ userCommand := []string{}
entrypoint := configureEntrypoint(c, data)
// Build the command
// If we have an entry point, it goes first
@@ -597,9 +604,11 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
if len(inputCommand) > 0 {
// User command overrides data CMD
command = append(command, inputCommand...)
+ userCommand = append(userCommand, inputCommand...)
} else if data != nil && len(data.Config.Cmd) > 0 && !c.IsSet("entrypoint") {
// If not user command, add CMD
command = append(command, data.Config.Cmd...)
+ userCommand = append(userCommand, data.Config.Cmd...)
}
if data != nil && len(command) == 0 {
@@ -624,8 +633,16 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
return nil, errors.Errorf("cannot pass additional search domains when also specifying '.'")
}
+ // Check for explicit dns-search domain of ''
+ if c.Changed("dns-search") && len(c.StringSlice("dns-search")) == 0 {
+ return nil, errors.Errorf("'' is not a valid domain")
+ }
+
// Validate domains are good
for _, dom := range c.StringSlice("dns-search") {
+ if dom == "." {
+ continue
+ }
if _, err := parse.ValidateDomain(dom); err != nil {
return nil, err
}
@@ -680,6 +697,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
Cgroupns: c.String("cgroupns"),
CgroupParent: c.String("cgroup-parent"),
Command: command,
+ UserCommand: userCommand,
Detach: c.Bool("detach"),
Devices: c.StringSlice("device"),
DNSOpt: c.StringSlice("dns-opt"),
diff --git a/cmd/podman/shared/intermediate.go b/cmd/podman/shared/intermediate.go
index 4062ac48a..c6c32f8a9 100644
--- a/cmd/podman/shared/intermediate.go
+++ b/cmd/podman/shared/intermediate.go
@@ -366,6 +366,7 @@ func NewIntermediateLayer(c *cliconfig.PodmanCommand, remote bool) GenericCLIRes
m["add-host"] = newCRStringSlice(c, "add-host")
m["annotation"] = newCRStringSlice(c, "annotation")
m["attach"] = newCRStringSlice(c, "attach")
+ m["authfile"] = newCRString(c, "authfile")
m["blkio-weight"] = newCRString(c, "blkio-weight")
m["blkio-weight-device"] = newCRStringSlice(c, "blkio-weight-device")
m["cap-add"] = newCRStringSlice(c, "cap-add")
@@ -435,6 +436,7 @@ func NewIntermediateLayer(c *cliconfig.PodmanCommand, remote bool) GenericCLIRes
m["privileged"] = newCRBool(c, "privileged")
m["publish"] = newCRStringSlice(c, "publish")
m["publish-all"] = newCRBool(c, "publish-all")
+ m["pull"] = newCRString(c, "pull")
m["quiet"] = newCRBool(c, "quiet")
m["read-only"] = newCRBool(c, "read-only")
m["read-only-tmpfs"] = newCRBool(c, "read-only-tmpfs")
diff --git a/cmd/podman/shared/intermediate_varlink.go b/cmd/podman/shared/intermediate_varlink.go
index 4742d4909..9dbf83950 100644
--- a/cmd/podman/shared/intermediate_varlink.go
+++ b/cmd/podman/shared/intermediate_varlink.go
@@ -137,6 +137,7 @@ func (g GenericCLIResults) MakeVarlink() iopodman.Create {
Privileged: BoolToPtr(g.Find("privileged")),
Publish: StringSliceToPtr(g.Find("publish")),
PublishAll: BoolToPtr(g.Find("publish-all")),
+ Pull: StringToPtr(g.Find("pull")),
Quiet: BoolToPtr(g.Find("quiet")),
Readonly: BoolToPtr(g.Find("read-only")),
Readonlytmpfs: BoolToPtr(g.Find("read-only-tmpfs")),
@@ -393,6 +394,7 @@ func VarlinkCreateToGeneric(opts iopodman.Create) GenericCLIResults {
m["privileged"] = boolFromVarlink(opts.Privileged, "privileged", false)
m["publish"] = stringSliceFromVarlink(opts.Publish, "publish", nil)
m["publish-all"] = boolFromVarlink(opts.PublishAll, "publish-all", false)
+ m["pull"] = stringFromVarlink(opts.Pull, "missing", nil)
m["quiet"] = boolFromVarlink(opts.Quiet, "quiet", false)
m["read-only"] = boolFromVarlink(opts.Readonly, "read-only", false)
m["read-only-tmpfs"] = boolFromVarlink(opts.Readonlytmpfs, "read-only-tmpfs", true)
diff --git a/cmd/podman/sign.go b/cmd/podman/sign.go
index 1333cf441..de289047a 100644
--- a/cmd/podman/sign.go
+++ b/cmd/podman/sign.go
@@ -15,6 +15,7 @@ import (
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/trust"
+ "github.com/containers/libpod/pkg/util"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -113,7 +114,7 @@ func signCmd(c *cliconfig.SignValues) error {
if err != nil {
return err
}
- newImage, err := runtime.ImageRuntime().New(getContext(), signimage, rtc.SignaturePolicyPath, "", os.Stderr, nil, image.SigningOptions{SignBy: signby}, false, nil)
+ newImage, err := runtime.ImageRuntime().New(getContext(), signimage, rtc.SignaturePolicyPath, "", os.Stderr, nil, image.SigningOptions{SignBy: signby}, nil, util.PullImageMissing)
if err != nil {
return errors.Wrapf(err, "error pulling image %s", signimage)
}
diff --git a/cmd/podman/stats.go b/cmd/podman/stats.go
index 3accae1b6..2f696445e 100644
--- a/cmd/podman/stats.go
+++ b/cmd/podman/stats.go
@@ -2,7 +2,6 @@ package main
import (
"fmt"
- "os"
"reflect"
"strings"
"time"
@@ -13,6 +12,8 @@ import (
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/pkg/cgroups"
+ "github.com/containers/libpod/pkg/rootless"
"github.com/docker/go-units"
"github.com/pkg/errors"
"github.com/spf13/cobra"
@@ -66,8 +67,14 @@ func init() {
}
func statsCmd(c *cliconfig.StatsValues) error {
- if os.Geteuid() != 0 {
- return errors.New("stats is not supported for rootless containers")
+ if rootless.IsRootless() {
+ unified, err := cgroups.IsCgroup2UnifiedMode()
+ if err != nil {
+ return err
+ }
+ if !unified {
+ return errors.New("stats is not supported in rootless mode without cgroups v2")
+ }
}
all := c.All
diff --git a/cmd/podman/system_df.go b/cmd/podman/system_df.go
index 6b9824a79..44582a802 100644
--- a/cmd/podman/system_df.go
+++ b/cmd/podman/system_df.go
@@ -460,11 +460,11 @@ func getImageVerboseDiskUsage(ctx context.Context, images []*image.Image, images
}
var repo string
var tag string
- if len(img.Names()) == 0 {
- repo = "<none>"
- tag = "<none>"
+ var repotags []string
+ if len(img.Names()) != 0 {
+ repotags = []string{img.Names()[0]}
}
- repopairs, err := image.ReposToMap([]string{img.Names()[0]})
+ repopairs, err := image.ReposToMap(repotags)
if err != nil {
logrus.Errorf("error finding tag/digest for %s", img.ID())
}
diff --git a/cmd/podman/varlink.go b/cmd/podman/varlink.go
index 92315cd6b..5f89534be 100644
--- a/cmd/podman/varlink.go
+++ b/cmd/podman/varlink.go
@@ -79,7 +79,7 @@ func varlinkCmd(c *cliconfig.VarlinkValues) error {
timeout := time.Duration(c.Timeout) * time.Millisecond
// Create a single runtime for varlink
- runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
+ runtime, err := libpodruntime.GetRuntimeDisableFDs(getContext(), &c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 73f4d1609..08a69275e 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -227,7 +227,8 @@ type InfoHost (
hostname: string,
kernel: string,
os: string,
- uptime: string
+ uptime: string,
+ eventlogger: string
)
# InfoGraphStatus describes the detailed status of the storage driver
@@ -345,6 +346,7 @@ type Create (
privileged: ?bool,
publish: ?[]string,
publishAll: ?bool,
+ pull: ?string,
quiet: ?bool,
readonly: ?bool,
readonlytmpfs: ?bool,
@@ -1275,3 +1277,6 @@ error WantsMoreRequired (reason: string)
# Container is already stopped
error ErrCtrStopped (id: string)
+
+# This function requires CGroupsV2 to run in rootless mode.
+error ErrRequiresCgroupsV2ForRootless(reason: string) \ No newline at end of file