diff options
-rw-r--r-- | docs/source/markdown/containers-mounts.conf.5.md | 16 | ||||
-rw-r--r-- | pkg/api/handlers/compat/images.go | 76 | ||||
-rw-r--r-- | pkg/domain/infra/abi/network.go | 2 |
3 files changed, 38 insertions, 56 deletions
diff --git a/docs/source/markdown/containers-mounts.conf.5.md b/docs/source/markdown/containers-mounts.conf.5.md deleted file mode 100644 index 74492c831..000000000 --- a/docs/source/markdown/containers-mounts.conf.5.md +++ /dev/null @@ -1,16 +0,0 @@ -% containers-mounts.conf(5) - -## NAME -containers-mounts.conf - configuration file for default mounts in containers - -## DESCRIPTION -The mounts.conf file specifies volume mount directories that are automatically mounted inside containers. Container processes can then use this content. Usually these directories are used for passing secrets or credentials required by the package software to access remote package repositories. Note that for security reasons, tools adhering to the mounts.conf are expected to copy the contents instead of bind mounting the paths from the host. - -## FORMAT -The format of the mounts.conf is the volume format `/SRC:/DEST`, one mount per line. For example, a mounts.conf with the line `/usr/share/secrets:/run/secrets` would cause the contents of the `/usr/share/secrets` directory on the host to be mounted on the `/run/secrets` directory inside the container. Setting mountpoints allows containers to use the files of the host, for instance, to use the host's subscription to some enterprise Linux distribution. - -## FILES -Some distributions may provide a `/usr/share/containers/mounts.conf` file to provide default mounts, but users can create a `/etc/containers/mounts.conf`, to specify their own special volumes to mount in the container. When Podman runs in rootless mode, the file `$HOME/.config/containers/mounts.conf` will override the default if it exists. - -## HISTORY -Aug 2018, Originally compiled by Valentin Rothberg <vrothberg@suse.com> diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index 3f4320efa..7b336c470 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -1,7 +1,6 @@ package compat import ( - "context" "encoding/json" "fmt" "io/ioutil" @@ -13,12 +12,12 @@ import ( "github.com/containers/common/libimage" "github.com/containers/common/pkg/config" "github.com/containers/image/v5/manifest" + "github.com/containers/image/v5/pkg/shortnames" "github.com/containers/image/v5/types" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/pkg/api/handlers" "github.com/containers/podman/v3/pkg/api/handlers/utils" "github.com/containers/podman/v3/pkg/auth" - "github.com/containers/podman/v3/pkg/channel" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/domain/infra/abi" "github.com/containers/storage" @@ -210,6 +209,11 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) { }) } +type pullResult struct { + images []*libimage.Image + err error +} + func CreateImageFromImage(w http.ResponseWriter, r *http.Request) { // 200 no error // 404 repo does not exist or no read access @@ -231,6 +235,14 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) { fromImage := mergeNameAndTagOrDigest(query.FromImage, query.Tag) + // without this early check this function would return 200 but reported error via body stream soon after + // it's better to let caller know early via HTTP status code that request cannot be processed + _, err := shortnames.Resolve(runtime.SystemContext(), fromImage) + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrap(err, "failed to resolve image name")) + return + } + authConf, authfile, key, err := auth.GetCredentials(r) if err != nil { utils.Error(w, "failed to retrieve repository credentials", http.StatusBadRequest, errors.Wrapf(err, "failed to parse %q header for %s", key, r.URL.String())) @@ -247,26 +259,14 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) { } pullOptions.Writer = os.Stderr // allows for debugging on the server - stderr := channel.NewWriter(make(chan []byte)) - defer stderr.Close() - progress := make(chan types.ProgressProperties) + pullOptions.Progress = progress - var img string - runCtx, cancel := context.WithCancel(context.Background()) + pullResChan := make(chan pullResult) go func() { - defer cancel() - pulledImages, err := runtime.LibimageRuntime().Pull(runCtx, fromImage, config.PullPolicyAlways, pullOptions) - if err != nil { - stderr.Write([]byte(err.Error() + "\n")) - } else { - if len(pulledImages) == 0 { - utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.New("internal error: no images pulled")) - return - } - img = pulledImages[0].ID() - } + pulledImages, err := runtime.LibimageRuntime().Pull(r.Context(), fromImage, config.PullPolicyAlways, pullOptions) + pullResChan <- pullResult{images: pulledImages, err: err} }() flush := func() { @@ -281,7 +281,6 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) { enc := json.NewEncoder(w) enc.SetEscapeHTML(true) - var failed bool loop: // break out of for/select infinite loop for { @@ -312,32 +311,31 @@ loop: // break out of for/select infinite loop } report.Id = e.Artifact.Digest.Encoded()[0:12] if err := enc.Encode(report); err != nil { - stderr.Write([]byte(err.Error())) - } - flush() - case e := <-stderr.Chan(): - failed = true - report.Error = string(e) - if err := enc.Encode(report); err != nil { logrus.Warnf("Failed to json encode error %q", err.Error()) } flush() - case <-runCtx.Done(): - if !failed { - if utils.IsLibpodRequest(r) { - report.Status = "Pull complete" + case pullRes := <-pullResChan: + err := pullRes.err + pulledImages := pullRes.images + if err != nil { + report.Error = err.Error() + } else { + if len(pulledImages) > 0 { + img := pulledImages[0].ID() + if utils.IsLibpodRequest(r) { + report.Status = "Pull complete" + } else { + report.Status = "Download complete" + } + report.Id = img[0:12] } else { - report.Status = "Download complete" - } - report.Id = img[0:12] - if err := enc.Encode(report); err != nil { - logrus.Warnf("Failed to json encode error %q", err.Error()) + report.Error = "internal error: no images pulled" } - flush() } - break loop // break out of for/select infinite loop - case <-r.Context().Done(): - // Client has closed connection + if err := enc.Encode(report); err != nil { + logrus.Warnf("Failed to json encode error %q", err.Error()) + } + flush() break loop // break out of for/select infinite loop } } diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go index 33ab280e5..7900caaa6 100644 --- a/pkg/domain/infra/abi/network.go +++ b/pkg/domain/infra/abi/network.go @@ -11,7 +11,7 @@ import ( ) func (ic *ContainerEngine) NetworkList(ctx context.Context, options entities.NetworkListOptions) ([]*entities.NetworkListReport, error) { - var reports []*entities.NetworkListReport + reports := make([]*entities.NetworkListReport, 0) config, err := ic.Libpod.GetConfig() if err != nil { |