summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/login.go14
-rw-r--r--cmd/podman/logout.go12
-rw-r--r--docs/source/markdown/podman-login.1.md7
-rw-r--r--docs/source/markdown/podman-logout.1.md3
-rw-r--r--pkg/api/handlers/generic/images.go50
-rw-r--r--pkg/api/handlers/utils/containers.go2
-rw-r--r--test/e2e/login_logout_test.go52
7 files changed, 98 insertions, 42 deletions
diff --git a/cmd/podman/login.go b/cmd/podman/login.go
index 369e0da16..e5ff273b8 100644
--- a/cmd/podman/login.go
+++ b/cmd/podman/login.go
@@ -12,6 +12,7 @@ import (
"github.com/containers/image/v5/types"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/libpod/image"
+ "github.com/containers/libpod/pkg/registries"
"github.com/docker/docker-credential-helpers/credentials"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -67,10 +68,19 @@ func loginCmd(c *cliconfig.LoginValues) error {
if len(args) > 1 {
return errors.Errorf("too many arguments, login takes only 1 argument")
}
+ var server string
if len(args) == 0 {
- return errors.Errorf("please specify a registry to login to")
+ registriesFromFile, err := registries.GetRegistries()
+ if err != nil || len(registriesFromFile) == 0 {
+ return errors.Errorf("please specify a registry to login to")
+ }
+
+ server = registriesFromFile[0]
+ logrus.Debugf("registry not specified, default to the first registry %q from registries.conf", server)
+
+ } else {
+ server = registryFromFullName(scrubServer(args[0]))
}
- server := registryFromFullName(scrubServer(args[0]))
sc := image.GetSystemContext("", c.Authfile, false)
if c.Flag("tls-verify").Changed {
diff --git a/cmd/podman/logout.go b/cmd/podman/logout.go
index 4a113b1d0..dec6822cf 100644
--- a/cmd/podman/logout.go
+++ b/cmd/podman/logout.go
@@ -8,7 +8,9 @@ import (
"github.com/containers/image/v5/pkg/docker/config"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/shared"
+ "github.com/containers/libpod/pkg/registries"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
@@ -51,10 +53,16 @@ func logoutCmd(c *cliconfig.LogoutValues) error {
if len(args) > 1 {
return errors.Errorf("too many arguments, logout takes at most 1 argument")
}
+ var server string
if len(args) == 0 && !c.All {
- return errors.Errorf("registry must be given")
+ registriesFromFile, err := registries.GetRegistries()
+ if err != nil || len(registriesFromFile) == 0 {
+ return errors.Errorf("no registries found in registries.conf, a registry must be provided")
+ }
+
+ server = registriesFromFile[0]
+ logrus.Debugf("registry not specified, default to the first registry %q from registries.conf", server)
}
- var server string
if len(args) == 1 {
server = scrubServer(args[0])
}
diff --git a/docs/source/markdown/podman-login.1.md b/docs/source/markdown/podman-login.1.md
index 8a84d359d..a69b311eb 100644
--- a/docs/source/markdown/podman-login.1.md
+++ b/docs/source/markdown/podman-login.1.md
@@ -4,11 +4,12 @@
podman\-login - Login to a container registry
## SYNOPSIS
-**podman login** [*options*] *registry*
+**podman login** [*options*] [*registry*]
## DESCRIPTION
**podman login** logs into a specified registry server with the correct username
-and password. **podman login** reads in the username and password from STDIN.
+and password. If the registry is not specified, the first registry under [registries.search]
+from registries.conf will be used. **podman login** reads in the username and password from STDIN.
The username and password can also be set using the **username** and **password** flags.
The path of the authentication file can be specified by the user by setting the **authfile**
flag. The default path used is **${XDG\_RUNTIME\_DIR}/containers/auth.json**.
@@ -17,7 +18,7 @@ flag. The default path used is **${XDG\_RUNTIME\_DIR}/containers/auth.json**.
**podman login [GLOBAL OPTIONS]**
-**podman login [OPTIONS] REGISTRY [GLOBAL OPTIONS]**
+**podman login [OPTIONS] [REGISTRY] [GLOBAL OPTIONS]**
## OPTIONS
diff --git a/docs/source/markdown/podman-logout.1.md b/docs/source/markdown/podman-logout.1.md
index 01dc52ecd..8b9f75760 100644
--- a/docs/source/markdown/podman-logout.1.md
+++ b/docs/source/markdown/podman-logout.1.md
@@ -8,7 +8,8 @@ podman\-logout - Logout of a container registry
## DESCRIPTION
**podman logout** logs out of a specified registry server by deleting the cached credentials
-stored in the **auth.json** file. The path of the authentication file can be overridden by the user by setting the **authfile** flag.
+stored in the **auth.json** file. If the registry is not specified, the first registry under [registries.search]
+from registries.conf will be used. The path of the authentication file can be overridden by the user by setting the **authfile** flag.
The default path used is **${XDG\_RUNTIME\_DIR}/containers/auth.json**.
All the cached credentials can be removed by setting the **all** flag.
diff --git a/pkg/api/handlers/generic/images.go b/pkg/api/handlers/generic/images.go
index c65db7575..afd107207 100644
--- a/pkg/api/handlers/generic/images.go
+++ b/pkg/api/handlers/generic/images.go
@@ -106,14 +106,14 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
query := struct {
- author string
- changes string
- comment string
- container string
+ Author string `schema:"author"`
+ Changes string `schema:"changes"`
+ Comment string `schema:"comment"`
+ Container string `schema:"container"`
//fromSrc string # fromSrc is currently unused
- pause bool
- repo string
- tag string
+ Pause bool `schema:"pause"`
+ Repo string `schema:"repo"`
+ Tag string `schema:"tag"`
}{
// This is where you can override the golang default value for one of fields
}
@@ -145,22 +145,22 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
return
}
- if len(query.tag) > 0 {
- tag = query.tag
+ if len(query.Tag) > 0 {
+ tag = query.Tag
}
- options.Message = query.comment
- options.Author = query.author
- options.Pause = query.pause
- options.Changes = strings.Fields(query.changes)
- ctr, err := runtime.LookupContainer(query.container)
+ options.Message = query.Comment
+ options.Author = query.Author
+ options.Pause = query.Pause
+ options.Changes = strings.Fields(query.Changes)
+ ctr, err := runtime.LookupContainer(query.Container)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusNotFound, err)
return
}
// I know mitr hates this ... but doing for now
- if len(query.repo) > 1 {
- destImage = fmt.Sprintf("%s:%s", query.repo, tag)
+ if len(query.Repo) > 1 {
+ destImage = fmt.Sprintf("%s:%s", query.Repo, tag)
}
commitImage, err := ctr.Commit(r.Context(), destImage, options)
@@ -179,8 +179,8 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
query := struct {
- fromSrc string
- changes []string
+ FromSrc string `schema:"fromSrc"`
+ Changes []string `schema:"changes"`
}{
// This is where you can override the golang default value for one of fields
}
@@ -190,7 +190,7 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
return
}
// fromSrc – Source to import. The value may be a URL from which the image can be retrieved or - to read the image from the request body. This parameter may only be used when importing an image.
- source := query.fromSrc
+ source := query.FromSrc
if source == "-" {
f, err := ioutil.TempFile("", "api_load.tar")
if err != nil {
@@ -202,7 +202,7 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to write temporary file"))
}
}
- iid, err := runtime.Import(r.Context(), source, "", query.changes, "", false)
+ iid, err := runtime.Import(r.Context(), source, "", query.Changes, "", false)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to import tarball"))
return
@@ -238,8 +238,8 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
query := struct {
- fromImage string
- tag string
+ FromImage string `schema:"fromImage"`
+ Tag string `schema:"tag"`
}{
// This is where you can override the golang default value for one of fields
}
@@ -254,9 +254,9 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
repo – Repository name given to an image when it is imported. The repo may include a tag. This parameter may only be used when importing an image.
tag – Tag or digest. If empty when pulling an image, this causes all tags for the given image to be pulled.
*/
- fromImage := query.fromImage
- if len(query.tag) < 1 {
- fromImage = fmt.Sprintf("%s:%s", fromImage, query.tag)
+ fromImage := query.FromImage
+ if len(query.Tag) < 1 {
+ fromImage = fmt.Sprintf("%s:%s", fromImage, query.Tag)
}
// TODO
diff --git a/pkg/api/handlers/utils/containers.go b/pkg/api/handlers/utils/containers.go
index 74485edf2..c9bb9cf09 100644
--- a/pkg/api/handlers/utils/containers.go
+++ b/pkg/api/handlers/utils/containers.go
@@ -15,7 +15,7 @@ import (
func KillContainer(w http.ResponseWriter, r *http.Request) (*libpod.Container, error) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
- decoder := r.Context().Value("decorder").(*schema.Decoder)
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
Signal syscall.Signal `schema:"signal"`
}{
diff --git a/test/e2e/login_logout_test.go b/test/e2e/login_logout_test.go
index 78c9b52d9..42698d270 100644
--- a/test/e2e/login_logout_test.go
+++ b/test/e2e/login_logout_test.go
@@ -19,14 +19,15 @@ import (
var _ = Describe("Podman login and logout", func() {
var (
- tempdir string
- err error
- podmanTest *PodmanTestIntegration
- authPath string
- certPath string
- port int
- server string
- testImg string
+ tempdir string
+ err error
+ podmanTest *PodmanTestIntegration
+ authPath string
+ certPath string
+ port int
+ server string
+ testImg string
+ registriesConfWithSearch []byte
)
BeforeEach(func() {
@@ -64,6 +65,9 @@ var _ = Describe("Podman login and logout", func() {
f.Sync()
port = 4999 + config.GinkgoConfig.ParallelNode
server = strings.Join([]string{"localhost", strconv.Itoa(port)}, ":")
+
+ registriesConfWithSearch = []byte(fmt.Sprintf("[registries.search]\nregistries = ['%s']", server))
+
testImg = strings.Join([]string{server, "test-apline"}, "/")
os.MkdirAll(filepath.Join("/etc/containers/certs.d", server), os.ModePerm)
@@ -113,6 +117,38 @@ var _ = Describe("Podman login and logout", func() {
Expect(session).To(ExitWithError())
})
+ It("podman login and logout without registry parameter", func() {
+ SkipIfRootless()
+
+ registriesConf, err := ioutil.TempFile("", "TestLoginWithoutParameter")
+ Expect(err).To(BeNil())
+ defer registriesConf.Close()
+ defer os.Remove(registriesConf.Name())
+
+ err = ioutil.WriteFile(registriesConf.Name(), []byte(registriesConfWithSearch), os.ModePerm)
+ Expect(err).To(BeNil())
+
+ // Environment is per-process, so this looks very unsafe; actually it seems fine because tests are not
+ // run in parallel unless they opt in by calling t.Parallel(). So don’t do that.
+ oldRCP, hasRCP := os.LookupEnv("REGISTRIES_CONFIG_PATH")
+ defer func() {
+ if hasRCP {
+ os.Setenv("REGISTRIES_CONFIG_PATH", oldRCP)
+ } else {
+ os.Unsetenv("REGISTRIES_CONFIG_PATH")
+ }
+ }()
+ os.Setenv("REGISTRIES_CONFIG_PATH", registriesConf.Name())
+
+ session := podmanTest.Podman([]string{"login", "-u", "podmantest", "-p", "test"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To((Equal(0)))
+
+ session = podmanTest.Podman([]string{"logout"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ })
+
It("podman login and logout with flag --authfile", func() {
SkipIfRootless()
authFile := filepath.Join(podmanTest.TempDir, "auth.json")