diff options
-rw-r--r-- | cmd/podman/login.go | 42 | ||||
-rw-r--r-- | cmd/podman/main.go | 3 | ||||
-rw-r--r-- | cmd/podman/shared/container.go | 14 | ||||
-rw-r--r-- | cmd/podman/shared/funcs.go | 4 | ||||
-rw-r--r-- | libpod/image/parts.go | 12 | ||||
-rw-r--r-- | libpod/lock/lock.go | 3 | ||||
-rw-r--r-- | libpod/lock/shm/shm_lock.go | 4 | ||||
-rw-r--r-- | libpod/lock/shm/shm_lock_test.go | 8 | ||||
-rw-r--r-- | libpod/lock/shm_lock_manager_linux.go | 8 |
9 files changed, 68 insertions, 30 deletions
diff --git a/cmd/podman/login.go b/cmd/podman/login.go index 4452651f8..fc7b39ed8 100644 --- a/cmd/podman/login.go +++ b/cmd/podman/login.go @@ -62,12 +62,18 @@ func loginCmd(c *cli.Context) error { return errors.Errorf("too many arguments, login takes only 1 argument") } if len(args) == 0 { - return errors.Errorf("registry must be given") + return errors.Errorf("please specify a registry to login to") } server := registryFromFullName(scrubServer(args[0])) authfile := getAuthFile(c.String("authfile")) sc := common.GetSystemContext("", authfile, false) + if c.IsSet("tls-verify") { + sc.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!c.BoolT("tls-verify")) + } + if c.String("cert-dir") != "" { + sc.DockerCertPath = c.String("cert-dir") + } if c.IsSet("get-login") { user, err := config.GetUserLoggedIn(sc, server) @@ -87,39 +93,25 @@ func loginCmd(c *cli.Context) error { // username of user logged in to server (if one exists) userFromAuthFile, passFromAuthFile, err := config.GetAuthentication(sc, server) if err != nil { - return errors.Wrapf(err, "error getting logged-in user") + return errors.Wrapf(err, "error reading auth file") } ctx := getContext() - - var ( - username string - password string - ) - - if userFromAuthFile != "" { - username = userFromAuthFile - password = passFromAuthFile + // If no username and no password is specified, try to use existing ones. + if c.String("username") == "" && c.String("password") == "" { fmt.Println("Authenticating with existing credentials...") - if err := docker.CheckAuth(ctx, sc, username, password, server); err == nil { + if err := docker.CheckAuth(ctx, sc, userFromAuthFile, passFromAuthFile, server); err == nil { fmt.Println("Existing credentials are valid. Already logged in to", server) return nil } fmt.Println("Existing credentials are invalid, please enter valid username and password") } - username, password, err = getUserAndPass(c.String("username"), c.String("password"), userFromAuthFile) + username, password, err := getUserAndPass(c.String("username"), c.String("password"), userFromAuthFile) if err != nil { return errors.Wrapf(err, "error getting username and password") } - if c.IsSet("tls-verify") { - sc.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!c.BoolT("tls-verify")) - } - if c.String("cert-dir") != "" { - sc.DockerCertPath = c.String("cert-dir") - } - if err = docker.CheckAuth(ctx, sc, username, password, server); err == nil { // Write the new credentials to the authfile if err = config.SetAuthentication(sc, server, username, password); err != nil { @@ -131,14 +123,15 @@ func loginCmd(c *cli.Context) error { fmt.Println("Login Succeeded!") return nil case docker.ErrUnauthorizedForCredentials: - return errors.Errorf("error logging into %q: invalid username/password\n", server) + return errors.Errorf("error logging into %q: invalid username/password", server) default: return errors.Wrapf(err, "error authenticating creds for %q", server) } } // getUserAndPass gets the username and password from STDIN if not given -// using the -u and -p flags +// using the -u and -p flags. If the username prompt is left empty, the +// displayed userFromAuthFile will be used instead. func getUserAndPass(username, password, userFromAuthFile string) (string, string, error) { var err error reader := bufio.NewReader(os.Stdin) @@ -152,7 +145,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 the user just hit enter, use the displayed user from the + // the authentication file. This allows to do a lazy + // `$ podman login -p $NEW_PASSWORD` without specifying the + // user. if strings.TrimSpace(username) == "" { username = userFromAuthFile } diff --git a/cmd/podman/main.go b/cmd/podman/main.go index 7ef22a93b..43804ee35 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -161,6 +161,9 @@ func main() { logrus.Info("running as rootless") } + // Be sure we can create directories with 0755 mode. + syscall.Umask(0022) + if logLevel == "debug" { debug = true diff --git a/cmd/podman/shared/container.go b/cmd/podman/shared/container.go index 30beb4a49..6c7d8eb52 100644 --- a/cmd/podman/shared/container.go +++ b/cmd/podman/shared/container.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/google/shlex" "io" "os" "path/filepath" @@ -640,6 +641,14 @@ func GetRunlabel(label string, runlabelImage string, ctx context.Context, runtim // GenerateRunlabelCommand generates the command that will eventually be execucted by podman func GenerateRunlabelCommand(runLabel, imageName, name string, opts map[string]string, extraArgs []string) ([]string, []string, error) { + // If no name is provided, we use the image's basename instead + if name == "" { + baseName, err := image.GetImageBaseName(imageName) + if err != nil { + return nil, nil, err + } + name = baseName + } // The user provided extra arguments that need to be tacked onto the label's command if len(extraArgs) > 0 { runLabel = fmt.Sprintf("%s %s", runLabel, strings.Join(extraArgs, " ")) @@ -665,7 +674,10 @@ func GenerateRunlabelCommand(runLabel, imageName, name string, opts map[string]s return "" } newS := os.Expand(strings.Join(cmd, " "), envmapper) - cmd = strings.Split(newS, " ") + cmd, err = shlex.Split(newS) + if err != nil { + return nil, nil, err + } return cmd, env, nil } diff --git a/cmd/podman/shared/funcs.go b/cmd/podman/shared/funcs.go index 8770b8ec0..70d041fd2 100644 --- a/cmd/podman/shared/funcs.go +++ b/cmd/podman/shared/funcs.go @@ -65,6 +65,8 @@ func GenerateCommand(command, imageName, name string) ([]string, error) { switch arg { case "IMAGE": newArg = imageName + case "$IMAGE": + newArg = imageName case "IMAGE=IMAGE": newArg = fmt.Sprintf("IMAGE=%s", imageName) case "IMAGE=$IMAGE": @@ -75,6 +77,8 @@ func GenerateCommand(command, imageName, name string) ([]string, error) { newArg = fmt.Sprintf("NAME=%s", name) case "NAME=$NAME": newArg = fmt.Sprintf("NAME=%s", name) + case "$NAME": + newArg = name default: newArg = arg } diff --git a/libpod/image/parts.go b/libpod/image/parts.go index 1509005e5..9adf26fb9 100644 --- a/libpod/image/parts.go +++ b/libpod/image/parts.go @@ -22,6 +22,18 @@ func isRegistry(name string) bool { return strings.ContainsAny(name, ".:") || name == "localhost" } +// GetImageBaseName uses decompose and string splits to obtain the base +// name of an image. Doing this here because it beats changing the +// imageParts struct names to be exported as well. +func GetImageBaseName(input string) (string, error) { + decomposedImage, err := decompose(input) + if err != nil { + return "", err + } + splitImageName := strings.Split(decomposedImage.name, "/") + return splitImageName[len(splitImageName)-1], nil +} + // decompose breaks an input name into an imageParts description func decompose(input string) (imageParts, error) { var ( diff --git a/libpod/lock/lock.go b/libpod/lock/lock.go index 73c1fdcf7..1f94171fe 100644 --- a/libpod/lock/lock.go +++ b/libpod/lock/lock.go @@ -43,6 +43,9 @@ type Locker interface { // encounters a fatal error. // All errors must be handled internally, as they are not returned. For // the most part, panicking should be appropriate. + // Some lock implementations may require that Lock() and Unlock() occur + // within the same goroutine (SHM locking, for example). The usual Go + // Lock()/defer Unlock() pattern will still work fine in these cases. Lock() // Unlock unlocks the lock. // All errors must be handled internally, as they are not returned. For diff --git a/libpod/lock/shm/shm_lock.go b/libpod/lock/shm/shm_lock.go index be5e5148f..87d28e5c1 100644 --- a/libpod/lock/shm/shm_lock.go +++ b/libpod/lock/shm/shm_lock.go @@ -36,7 +36,7 @@ type SHMLocks struct { // nolint // size used by the underlying implementation. func CreateSHMLock(path string, numLocks uint32) (*SHMLocks, error) { if numLocks == 0 { - return nil, errors.Wrapf(syscall.EINVAL, "number of locks must greater than 0 0") + return nil, errors.Wrapf(syscall.EINVAL, "number of locks must be greater than 0") } locks := new(SHMLocks) @@ -65,7 +65,7 @@ func CreateSHMLock(path string, numLocks uint32) (*SHMLocks, error) { // segment was created with. func OpenSHMLock(path string, numLocks uint32) (*SHMLocks, error) { if numLocks == 0 { - return nil, errors.Wrapf(syscall.EINVAL, "number of locks must greater than 0") + return nil, errors.Wrapf(syscall.EINVAL, "number of locks must be greater than 0") } locks := new(SHMLocks) diff --git a/libpod/lock/shm/shm_lock_test.go b/libpod/lock/shm/shm_lock_test.go index 0f3a96cca..594eb5d8e 100644 --- a/libpod/lock/shm/shm_lock_test.go +++ b/libpod/lock/shm/shm_lock_test.go @@ -256,13 +256,13 @@ func TestLockSemaphoreActuallyLocks(t *testing.T) { // Ensures that runtime.LockOSThread() is doing its job func TestLockAndUnlockTwoSemaphore(t *testing.T) { runLockTest(t, func(t *testing.T, locks *SHMLocks) { - err := locks.LockSemaphore(0) + err := locks.LockSemaphore(5) assert.NoError(t, err) - err = locks.LockSemaphore(1) + err = locks.LockSemaphore(6) assert.NoError(t, err) - err = locks.UnlockSemaphore(1) + err = locks.UnlockSemaphore(6) assert.NoError(t, err) // Now yield scheduling @@ -272,7 +272,7 @@ func TestLockAndUnlockTwoSemaphore(t *testing.T) { // And unlock the last semaphore // If we are in a different OS thread, this should fail. // However, runtime.UnlockOSThread() should guarantee we are not - err = locks.UnlockSemaphore(0) + err = locks.UnlockSemaphore(5) assert.NoError(t, err) }) } diff --git a/libpod/lock/shm_lock_manager_linux.go b/libpod/lock/shm_lock_manager_linux.go index 3e8f4f3d2..94dfd7dd7 100644 --- a/libpod/lock/shm_lock_manager_linux.go +++ b/libpod/lock/shm_lock_manager_linux.go @@ -3,7 +3,10 @@ package lock import ( + "syscall" + "github.com/containers/libpod/libpod/lock/shm" + "github.com/pkg/errors" ) // SHMLockManager manages shared memory locks. @@ -60,6 +63,11 @@ func (m *SHMLockManager) RetrieveLock(id uint32) (Locker, error) { lock.lockID = id lock.manager = m + if id >= m.locks.GetMaxLocks() { + return nil, errors.Wrapf(syscall.EINVAL, "lock ID %d is too large - max lock size is %d", + id, m.locks.GetMaxLocks()-1) + } + return lock, nil } |