diff options
Diffstat (limited to 'pkg/api')
-rw-r--r-- | pkg/api/handlers/compat/containers.go | 7 | ||||
-rw-r--r-- | pkg/api/handlers/compat/images_build.go | 36 | ||||
-rw-r--r-- | pkg/api/handlers/compat/images_push.go | 121 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/copy.go | 12 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/images.go | 1 |
5 files changed, 143 insertions, 34 deletions
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go index d26bb50f4..d3277b815 100644 --- a/pkg/api/handlers/compat/containers.go +++ b/pkg/api/handlers/compat/containers.go @@ -76,7 +76,12 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) { return } if len(report) > 0 && report[0].Err != nil { - utils.InternalServerError(w, report[0].Err) + err = report[0].Err + if errors.Cause(err) == define.ErrNoSuchCtr { + utils.ContainerNotFound(w, name, err) + return + } + utils.InternalServerError(w, err) return } diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index e06f93b89..392f688dd 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -77,6 +77,9 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { Devices string `schema:"devices"` Dockerfile string `schema:"dockerfile"` DropCapabilities string `schema:"dropcaps"` + DNSServers string `schema:"dnsservers"` + DNSOptions string `schema:"dnsoptions"` + DNSSearch string `schema:"dnssearch"` Excludes string `schema:"excludes"` ForceRm bool `schema:"forcerm"` From string `schema:"from"` @@ -160,6 +163,36 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { devices = m } + var dnsservers = []string{} + if _, found := r.URL.Query()["dnsservers"]; found { + var m = []string{} + if err := json.Unmarshal([]byte(query.DNSServers), &m); err != nil { + utils.BadRequest(w, "dnsservers", query.DNSServers, err) + return + } + dnsservers = m + } + + var dnsoptions = []string{} + if _, found := r.URL.Query()["dnsoptions"]; found { + var m = []string{} + if err := json.Unmarshal([]byte(query.DNSOptions), &m); err != nil { + utils.BadRequest(w, "dnsoptions", query.DNSOptions, err) + return + } + dnsoptions = m + } + + var dnssearch = []string{} + if _, found := r.URL.Query()["dnssearch"]; found { + var m = []string{} + if err := json.Unmarshal([]byte(query.DNSSearch), &m); err != nil { + utils.BadRequest(w, "dnssearches", query.DNSSearch, err) + return + } + dnssearch = m + } + var output string if len(query.Tag) > 0 { output = query.Tag[0] @@ -285,6 +318,9 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { CPUQuota: query.CpuQuota, CPUShares: query.CpuShares, CPUSetCPUs: query.CpuSetCpus, + DNSServers: dnsservers, + DNSOptions: dnsoptions, + DNSSearch: dnssearch, HTTPProxy: query.HTTPProxy, Memory: query.Memory, MemorySwap: query.MemSwap, diff --git a/pkg/api/handlers/compat/images_push.go b/pkg/api/handlers/compat/images_push.go index 4f613338f..db02af445 100644 --- a/pkg/api/handlers/compat/images_push.go +++ b/pkg/api/handlers/compat/images_push.go @@ -1,6 +1,8 @@ package compat import ( + "context" + "encoding/json" "fmt" "io/ioutil" "net/http" @@ -10,11 +12,14 @@ import ( "github.com/containers/podman/v3/libpod" "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" + "github.com/docker/docker/pkg/jsonmessage" "github.com/gorilla/schema" "github.com/pkg/errors" + "github.com/sirupsen/logrus" ) // PushImage is the handler for the compat http endpoint for pushing images. @@ -82,6 +87,8 @@ func PushImage(w http.ResponseWriter, r *http.Request) { Password: password, Username: username, DigestFile: digestFile.Name(), + Quiet: true, + Progress: make(chan types.ProgressProperties), } if _, found := r.URL.Query()["tlsVerify"]; found { options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify) @@ -94,31 +101,103 @@ func PushImage(w http.ResponseWriter, r *http.Request) { destination = imageName } - if err := imageEngine.Push(r.Context(), imageName, destination, options); err != nil { - if errors.Cause(err) != storage.ErrImageUnknown { - utils.ImageNotFound(w, imageName, errors.Wrapf(err, "failed to find image %s", imageName)) - return + errorWriter := channel.NewWriter(make(chan []byte)) + defer errorWriter.Close() + + statusWriter := channel.NewWriter(make(chan []byte)) + defer statusWriter.Close() + + runCtx, cancel := context.WithCancel(context.Background()) + var failed bool + + go func() { + defer cancel() + + statusWriter.Write([]byte(fmt.Sprintf("The push refers to repository [%s]", imageName))) + + err := imageEngine.Push(runCtx, imageName, destination, options) + if err != nil { + if errors.Cause(err) != storage.ErrImageUnknown { + errorWriter.Write([]byte("An image does not exist locally with the tag: " + imageName)) + } else { + errorWriter.Write([]byte(err.Error())) + } } + }() - utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "error pushing image %q", imageName)) - return + flush := func() { + if flusher, ok := w.(http.Flusher); ok { + flusher.Flush() + } } - digestBytes, err := ioutil.ReadAll(digestFile) - if err != nil { - utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to read digest tmp file")) - return - } + w.WriteHeader(http.StatusOK) + w.Header().Add("Content-Type", "application/json") + flush() - tag := query.Tag - if tag == "" { - tag = "latest" - } - respData := struct { - Status string `json:"status"` - }{ - Status: fmt.Sprintf("%s: digest: %s size: null", tag, string(digestBytes)), - } + enc := json.NewEncoder(w) + enc.SetEscapeHTML(true) + +loop: // break out of for/select infinite loop + for { + var report jsonmessage.JSONMessage - utils.WriteJSON(w, http.StatusOK, &respData) + select { + case e := <-options.Progress: + switch e.Event { + case types.ProgressEventNewArtifact: + report.Status = "Preparing" + case types.ProgressEventRead: + report.Status = "Pushing" + report.Progress = &jsonmessage.JSONProgress{ + Current: int64(e.Offset), + Total: e.Artifact.Size, + } + case types.ProgressEventSkipped: + report.Status = "Layer already exists" + case types.ProgressEventDone: + report.Status = "Pushed" + } + report.ID = e.Artifact.Digest.Encoded()[0:12] + if err := enc.Encode(report); err != nil { + errorWriter.Write([]byte(err.Error())) + } + flush() + case e := <-statusWriter.Chan(): + report.Status = string(e) + if err := enc.Encode(report); err != nil { + errorWriter.Write([]byte(err.Error())) + } + flush() + case e := <-errorWriter.Chan(): + failed = true + report.Error = &jsonmessage.JSONError{ + Message: string(e), + } + report.ErrorMessage = 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 { + digestBytes, err := ioutil.ReadAll(digestFile) + if err == nil { + tag := query.Tag + if tag == "" { + tag = "latest" + } + report.Status = fmt.Sprintf("%s: digest: %s", tag, string(digestBytes)) + 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 + case <-r.Context().Done(): + // Client has closed connection + break loop // break out of for/select infinite loop + } + } } diff --git a/pkg/api/handlers/libpod/copy.go b/pkg/api/handlers/libpod/copy.go deleted file mode 100644 index 4b345bacc..000000000 --- a/pkg/api/handlers/libpod/copy.go +++ /dev/null @@ -1,12 +0,0 @@ -package libpod - -import ( - "net/http" - - "github.com/containers/podman/v3/pkg/api/handlers/utils" - "github.com/pkg/errors" -) - -func Archive(w http.ResponseWriter, r *http.Request) { - utils.Error(w, "not implemented", http.StatusNotImplemented, errors.New("not implemented")) -} diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index 1a2483784..83fe23621 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -451,6 +451,7 @@ func PushImage(w http.ResponseWriter, r *http.Request) { Password: password, Format: query.Format, All: query.All, + Quiet: true, } if _, found := r.URL.Query()["tlsVerify"]; found { options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify) |