diff options
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/podman/common.go | 8 | ||||
-rw-r--r-- | cmd/podman/create_cli_test.go | 2 | ||||
-rw-r--r-- | cmd/podman/libpodruntime/runtime.go | 54 | ||||
-rw-r--r-- | cmd/podman/login.go | 9 | ||||
-rw-r--r-- | cmd/podman/logout.go | 6 | ||||
-rw-r--r-- | cmd/podman/parse.go | 10 | ||||
-rw-r--r-- | cmd/podman/rm.go | 35 | ||||
-rw-r--r-- | cmd/podman/stats.go | 7 |
8 files changed, 55 insertions, 76 deletions
diff --git a/cmd/podman/common.go b/cmd/podman/common.go index e342659ed..8ae1c9e0f 100644 --- a/cmd/podman/common.go +++ b/cmd/podman/common.go @@ -465,3 +465,11 @@ func getAuthFile(authfile string) string { } return os.Getenv("REGISTRY_AUTH_FILE") } + +// scrubServer removes 'http://' or 'https://' from the front of the +// server/registry string if either is there. This will be mostly used +// for user input from 'podman login' and 'podman logout'. +func scrubServer(server string) string { + server = strings.TrimPrefix(server, "https://") + return strings.TrimPrefix(server, "http://") +} diff --git a/cmd/podman/create_cli_test.go b/cmd/podman/create_cli_test.go index fa128c8e6..9db007ff3 100644 --- a/cmd/podman/create_cli_test.go +++ b/cmd/podman/create_cli_test.go @@ -47,7 +47,7 @@ func TestGetAllLabels(t *testing.T) { } func TestGetAllLabelsBadKeyValue(t *testing.T) { - inLabels := []string{"ONE1", "TWO=2"} + inLabels := []string{"=badValue", "="} fileLabels := []string{} _, err := getAllLabels(fileLabels, inLabels) assert.Error(t, err, assert.AnError) diff --git a/cmd/podman/libpodruntime/runtime.go b/cmd/podman/libpodruntime/runtime.go index a0d497e8e..df422eb81 100644 --- a/cmd/podman/libpodruntime/runtime.go +++ b/cmd/podman/libpodruntime/runtime.go @@ -1,21 +1,16 @@ package libpodruntime import ( - "fmt" - "os" - "path/filepath" - "github.com/containers/libpod/libpod" "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/util" "github.com/containers/storage" - "github.com/pkg/errors" "github.com/urfave/cli" ) // GetRuntime generates a new libpod runtime configured by command line options func GetRuntime(c *cli.Context) (*libpod.Runtime, error) { - storageOpts, err := GetDefaultStoreOptions() + storageOpts, err := util.GetDefaultStoreOptions() if err != nil { return nil, err } @@ -28,7 +23,7 @@ func GetContainerRuntime(c *cli.Context) (*libpod.Runtime, error) { if err != nil { return nil, err } - storageOpts, err := GetDefaultStoreOptions() + storageOpts, err := util.GetDefaultStoreOptions() if err != nil { return nil, err } @@ -37,51 +32,6 @@ func GetContainerRuntime(c *cli.Context) (*libpod.Runtime, error) { return GetRuntimeWithStorageOpts(c, &storageOpts) } -func GetRootlessStorageOpts() (storage.StoreOptions, error) { - var opts storage.StoreOptions - - rootlessRuntime, err := libpod.GetRootlessRuntimeDir() - if err != nil { - return opts, err - } - opts.RunRoot = filepath.Join(rootlessRuntime, "run") - - dataDir := os.Getenv("XDG_DATA_HOME") - if dataDir == "" { - home := os.Getenv("HOME") - if home == "" { - return opts, fmt.Errorf("neither XDG_DATA_HOME nor HOME was set non-empty") - } - // runc doesn't like symlinks in the rootfs path, and at least - // on CoreOS /home is a symlink to /var/home, so resolve any symlink. - resolvedHome, err := filepath.EvalSymlinks(home) - if err != nil { - return opts, errors.Wrapf(err, "cannot resolve %s", home) - } - dataDir = filepath.Join(resolvedHome, ".local", "share") - } - opts.GraphRoot = filepath.Join(dataDir, "containers", "storage") - opts.GraphDriverName = "vfs" - return opts, nil -} - -func GetDefaultStoreOptions() (storage.StoreOptions, error) { - storageOpts := storage.DefaultStoreOptions - if rootless.IsRootless() { - var err error - storageOpts, err = GetRootlessStorageOpts() - if err != nil { - return storageOpts, err - } - - storageConf := filepath.Join(os.Getenv("HOME"), ".config/containers/storage.conf") - if _, err := os.Stat(storageConf); err == nil { - storage.ReloadConfigurationFile(storageConf, &storageOpts) - } - } - return storageOpts, nil -} - // GetRuntime generates a new libpod runtime configured by command line options func GetRuntimeWithStorageOpts(c *cli.Context, storageOpts *storage.StoreOptions) (*libpod.Runtime, error) { options := []libpod.RuntimeOption{} diff --git a/cmd/podman/login.go b/cmd/podman/login.go index 76f0f50ff..aa26d1466 100644 --- a/cmd/podman/login.go +++ b/cmd/podman/login.go @@ -60,10 +60,7 @@ func loginCmd(c *cli.Context) error { if len(args) == 0 { return errors.Errorf("registry must be given") } - var server string - if len(args) == 1 { - server = args[0] - } + server := scrubServer(args[0]) authfile := getAuthFile(c.String("authfile")) sc := common.GetSystemContext("", authfile, false) @@ -113,6 +110,10 @@ func getUserAndPass(username, password, userFromAuthFile string) (string, string if err != nil { return "", "", errors.Wrapf(err, "error reading username") } + // If no username provided, use userFromAuthFile instead. + if strings.TrimSpace(username) == "" { + username = userFromAuthFile + } } if password == "" { fmt.Print("Password: ") diff --git a/cmd/podman/logout.go b/cmd/podman/logout.go index 099464e4f..3cdb606b5 100644 --- a/cmd/podman/logout.go +++ b/cmd/podman/logout.go @@ -44,7 +44,7 @@ func logoutCmd(c *cli.Context) error { } var server string if len(args) == 1 { - server = args[0] + server = scrubServer(args[0]) } authfile := getAuthFile(c.String("authfile")) @@ -54,14 +54,14 @@ func logoutCmd(c *cli.Context) error { if err := config.RemoveAllAuthentication(sc); err != nil { return err } - fmt.Println("Remove login credentials for all registries") + fmt.Println("Removed login credentials for all registries") return nil } err := config.RemoveAuthentication(sc, server) switch err { case nil: - fmt.Printf("Remove login credentials for %s\n", server) + fmt.Printf("Removed login credentials for %s\n", server) return nil case config.ErrNotLoggedIn: return errors.Errorf("Not logged into %s\n", server) diff --git a/cmd/podman/parse.go b/cmd/podman/parse.go index ade592ddf..2e4959656 100644 --- a/cmd/podman/parse.go +++ b/cmd/podman/parse.go @@ -198,6 +198,11 @@ func readKVStrings(env map[string]string, files []string, override []string) err func parseEnv(env map[string]string, line string) error { data := strings.SplitN(line, "=", 2) + // catch invalid variables such as "=" or "=A" + if data[0] == "" { + return errors.Errorf("invalid environment variable: %q", line) + } + // trim the front of a variable, but nothing else name := strings.TrimLeft(data[0], whiteSpaces) if strings.ContainsAny(name, whiteSpaces) { @@ -208,10 +213,7 @@ func parseEnv(env map[string]string, line string) error { env[name] = data[1] } else { // if only a pass-through variable is given, clean it up. - val, exists := os.LookupEnv(name) - if !exists { - return errors.Errorf("environment variable %q does not exist", name) - } + val, _ := os.LookupEnv(name) env[name] = val } return nil diff --git a/cmd/podman/rm.go b/cmd/podman/rm.go index f64eca6f4..38b1546ff 100644 --- a/cmd/podman/rm.go +++ b/cmd/podman/rm.go @@ -3,6 +3,7 @@ package main import ( "fmt" "os" + rt "runtime" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/libpod" @@ -45,6 +46,12 @@ Running containers will not be removed without the -f option. // saveCmd saves the image to either docker-archive or oci func rmCmd(c *cli.Context) error { + var ( + delContainers []*libpod.Container + lastError error + deleteFuncs []workerInput + ) + ctx := getContext() if err := validateFlags(c, rmFlags); err != nil { return err @@ -65,8 +72,6 @@ func rmCmd(c *cli.Context) error { return errors.Errorf("specify one or more containers to remove") } - var delContainers []*libpod.Container - var lastError error if c.Bool("all") { delContainers, err = runtime.GetContainers() if err != nil { @@ -89,16 +94,26 @@ func rmCmd(c *cli.Context) error { delContainers = append(delContainers, container) } } + for _, container := range delContainers { - err = runtime.RemoveContainer(ctx, container, c.Bool("force")) - if err != nil { - if lastError != nil { - fmt.Fprintln(os.Stderr, lastError) - } - lastError = errors.Wrapf(err, "failed to delete container %v", container.ID()) - } else { - fmt.Println(container.ID()) + f := func() error { + return runtime.RemoveContainer(ctx, container, c.Bool("force")) + } + + deleteFuncs = append(deleteFuncs, workerInput{ + containerID: container.ID(), + parallelFunc: f, + }) + } + + deleteErrors := parallelExecuteWorkerPool(rt.NumCPU()*3, deleteFuncs) + for cid, result := range deleteErrors { + if result != nil { + fmt.Println(result.Error()) + lastError = result + continue } + fmt.Println(cid) } return lastError } diff --git a/cmd/podman/stats.go b/cmd/podman/stats.go index dea351e88..f6beac1a8 100644 --- a/cmd/podman/stats.go +++ b/cmd/podman/stats.go @@ -84,8 +84,7 @@ func statsCmd(c *cli.Context) error { if ctr > 1 { return errors.Errorf("--all, --latest and containers cannot be used together") } else if ctr == 0 { - // If user didn't specify, imply --all - all = true + return errors.Errorf("you must specify --all, --latest, or at least one container") } runtime, err := libpodruntime.GetRuntime(c) @@ -126,6 +125,10 @@ func statsCmd(c *cli.Context) error { for _, ctr := range ctrs { initialStats, err := ctr.GetContainerStats(&libpod.ContainerStats{}) if err != nil { + // when doing "all", dont worry about containers that are not running + if c.Bool("all") && errors.Cause(err) == libpod.ErrCtrRemoved || errors.Cause(err) == libpod.ErrNoSuchCtr || errors.Cause(err) == libpod.ErrCtrStateInvalid { + continue + } return err } containerStats[ctr.ID()] = initialStats |