diff --git a/pkg/serviceapi/errors.go b/pkg/serviceapi/errors.go index a0a140427f9..ad50e7ac230 100644 --- a/pkg/serviceapi/errors.go +++ b/pkg/serviceapi/errors.go @@ -14,11 +14,12 @@ func Error(w http.ResponseWriter, apiMessage string, code int, err error) { // Log detailed message of what happened to machine running podman service log.Errorf(err.Error()) - w.(ServiceWriter).WriteJSON(code, struct { - message string - }{ - apiMessage, - }) + w.(ServiceWriter).WriteJSON(code, + struct { + Message string `json:"message"` + }{ + apiMessage, + }) } func noSuchContainerError(w http.ResponseWriter, nameOrId string, err error) { diff --git a/pkg/serviceapi/handler.go b/pkg/serviceapi/handler.go index 16f1e98f82c..41c1b4fa9f2 100644 --- a/pkg/serviceapi/handler.go +++ b/pkg/serviceapi/handler.go @@ -33,6 +33,6 @@ func (w ServiceWriter) WriteJSON(code int, value interface{}) error { w.WriteHeader(code) coder := json.NewEncoder(w) - coder.SetEscapeHTML(false) + coder.SetEscapeHTML(true) return coder.Encode(value) } diff --git a/pkg/serviceapi/handler_images.go b/pkg/serviceapi/handler_images.go index 5c0b3f53df4..527d685c212 100644 --- a/pkg/serviceapi/handler_images.go +++ b/pkg/serviceapi/handler_images.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" "strconv" + "strings" "github.com/containers/libpod/libpod" image2 "github.com/containers/libpod/libpod/image" @@ -32,13 +33,31 @@ func createImage(w http.ResponseWriter, r *http.Request, runtime *libpod.Runtime fromImage := r.Form.Get("fromImage") // TODO // We are eating the output right now because we haven't talked about how to deal with multiple responses yet - _, err := runtime.ImageRuntime().New(ctx, fromImage, "", "", nil, &image2.DockerRegistryOptions{}, image2.SigningOptions{}, nil, util.PullImageAlways) + img, err := runtime.ImageRuntime().New(ctx, fromImage, "", "", nil, &image2.DockerRegistryOptions{}, image2.SigningOptions{}, nil, util.PullImageAlways) if err != nil { Error(w, "Something went wrong.", http.StatusInternalServerError, err) return } + + name := fromImage + tag := "latest" + idx := strings.LastIndexByte(fromImage, ':') + if idx != -1 { + name = fromImage[:idx] + tag = fromImage[idx:] + } // Success - w.(ServiceWriter).WriteJSON(http.StatusOK, "") + w.(ServiceWriter).WriteJSON(http.StatusOK, struct { + Status string `json:"status"` + Error string `json:"error"` + Progress string `json:"progress"` + ProgressDetail map[string]string `json:"progressDetail"` + Id string `json:"id"` + }{ + Status: fmt.Sprintf("Pulling image (%s) from %s", tag, name), + ProgressDetail: map[string]string{}, + Id: img.ID(), + }) } func tagImage(w http.ResponseWriter, r *http.Request, runtime *libpod.Runtime) { @@ -46,7 +65,7 @@ func tagImage(w http.ResponseWriter, r *http.Request, runtime *libpod.Runtime) { name := mux.Vars(r)["name"] newImage, err := runtime.ImageRuntime().NewFromLocal(name) if err != nil { - Error(w, "Something went wrong.", http.StatusNotFound, err) + noSuchImageError(w, name, errors.Wrapf(err, "Failed to find image %s", name)) return } tag := "latest" @@ -70,7 +89,7 @@ func image(w http.ResponseWriter, r *http.Request, runtime *libpod.Runtime) { name := mux.Vars(r)["name"] newImage, err := runtime.ImageRuntime().NewFromLocal(name) if err != nil { - Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(err, "Failed to find image %s", name)) + noSuchImageError(w, name, errors.Wrapf(err, "Failed to find image %s", name)) return } ctx := context.Background() diff --git a/pkg/serviceapi/handler_notfound.go b/pkg/serviceapi/handler_notfound.go index 1b06122344b..b8ff8f25c1e 100644 --- a/pkg/serviceapi/handler_notfound.go +++ b/pkg/serviceapi/handler_notfound.go @@ -1,10 +1,10 @@ package serviceapi import ( - "fmt" "net/http" "github.com/gorilla/mux" + log "github.com/sirupsen/logrus" ) func registerNotFoundHandlers(r *mux.Router) error { @@ -13,7 +13,6 @@ func registerNotFoundHandlers(r *mux.Router) error { } func notFound(w http.ResponseWriter, r *http.Request) { - http.Error(w, - fmt.Sprintf("%d %s for '%s'", http.StatusNotFound, http.StatusText(http.StatusNotFound), r.URL.String()), - http.StatusNotFound) + log.Errorf("%d %s for %s:'%s'", http.StatusNotFound, http.StatusText(http.StatusNotFound), r.Method, r.URL.String()) + http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) } diff --git a/pkg/serviceapi/handler_swarm.go b/pkg/serviceapi/handler_swarm.go index 7039d95e797..f506b1d31cb 100644 --- a/pkg/serviceapi/handler_swarm.go +++ b/pkg/serviceapi/handler_swarm.go @@ -5,18 +5,22 @@ import ( "net/http" "github.com/gorilla/mux" + "github.com/sirupsen/logrus" ) func registerSwarmHandlers(r *mux.Router) error { - r.HandleFunc(unversionedPath("/swarm"), noSwarm) - r.HandleFunc(unversionedPath("/services"), noSwarm) - r.HandleFunc(unversionedPath("/nodes"), noSwarm) - r.HandleFunc(unversionedPath("/tasks"), noSwarm) - r.HandleFunc(unversionedPath("/secrets"), noSwarm) - r.HandleFunc(unversionedPath("/configs"), noSwarm) + r.PathPrefix("/v{version:[0-9.]+}/swarm/").HandlerFunc(noSwarm) + r.PathPrefix("/v{version:[0-9.]+}/services/").HandlerFunc(noSwarm) + r.PathPrefix("/v{version:[0-9.]+}/nodes/").HandlerFunc(noSwarm) + r.PathPrefix("/v{version:[0-9.]+}/tasks/").HandlerFunc(noSwarm) + r.PathPrefix("/v{version:[0-9.]+}/secrets/").HandlerFunc(noSwarm) + r.PathPrefix("/v{version:[0-9.]+}/configs/").HandlerFunc(noSwarm) return nil } +// noSwarm returns http.StatusServiceUnavailable rather than something like http.StatusInternalServerError, +// this allows the client to decide if they still can talk to us func noSwarm(w http.ResponseWriter, r *http.Request) { - Error(w, "node is not part of a swarm", http.StatusServiceUnavailable, errors.New("swarm is not supported by podman")) + logrus.Errorf("%s is not a podman supported service", r.URL.String()) + Error(ServiceWriter{w}, "node is not part of a swarm", http.StatusServiceUnavailable, errors.New("Podman does not support service: "+r.URL.String())) } diff --git a/pkg/serviceapi/handler_version.go b/pkg/serviceapi/handler_version.go index d2a516e415f..34d5569d859 100644 --- a/pkg/serviceapi/handler_version.go +++ b/pkg/serviceapi/handler_version.go @@ -15,6 +15,7 @@ import ( func registerVersionHandlers(r *mux.Router) error { r.Handle(unversionedPath("/version"), serviceHandler(versionHandler)) + r.Handle("/version", serviceHandler(versionHandler)) return nil } @@ -32,22 +33,38 @@ func versionHandler(w http.ResponseWriter, r *http.Request, runtime *libpod.Runt } hostInfo := infoData[0].Data + components := []docker.ComponentVersion{{ + Name: "Engine", + Version: versionInfo.Version, + Details: map[string]string{ + "APIVersion": DefaultApiVersion, + "Arch": goRuntime.GOARCH, + "BuildTime": time.Unix(versionInfo.Built, 0).Format(time.RFC3339), + "Experimental": "true", + "GitCommit": versionInfo.GitCommit, + "GoVersion": versionInfo.GoVersion, + "KernelVersion": hostInfo["kernel"].(string), + "MinAPIVersion": MinimalApiVersion, + "Os": goRuntime.GOOS, + }, + }} + w.(ServiceWriter).WriteJSON(http.StatusOK, Version{docker.Version{ Platform: struct { Name string }{ Name: fmt.Sprintf("%s/%s/%s", goRuntime.GOOS, goRuntime.GOARCH, hostInfo["Distribution"].(map[string]interface{})["distribution"].(string)), }, - Components: nil, - Version: versionInfo.Version, - APIVersion: DefaultApiVersion, - MinAPIVersion: MinimalApiVersion, - GitCommit: versionInfo.GitCommit, - GoVersion: versionInfo.GoVersion, - Os: goRuntime.GOOS, - Arch: goRuntime.GOARCH, - KernelVersion: hostInfo["kernel"].(string), + APIVersion: components[0].Details["APIVersion"], + Arch: components[0].Details["Arch"], + BuildTime: components[0].Details["BuildTime"], + Components: components, Experimental: true, - BuildTime: time.Unix(versionInfo.Built, 0).Format(time.RFC3339), + GitCommit: components[0].Details["GitCommit"], + GoVersion: components[0].Details["GoVersion"], + KernelVersion: components[0].Details["KernelVersion"], + MinAPIVersion: components[0].Details["MinAPIVersion"], + Os: components[0].Details["Os"], + Version: components[0].Version, }}) } diff --git a/pkg/serviceapi/server.go b/pkg/serviceapi/server.go index 3b6de5f638f..60cb4121171 100644 --- a/pkg/serviceapi/server.go +++ b/pkg/serviceapi/server.go @@ -109,5 +109,5 @@ func (s *HttpServer) Close() error { // unversionedPath prepends the version parsing code // any handler may override this default when registering URL(s) func unversionedPath(p string) string { - return "/v{version:[0-9.]*}" + p + return "/v{version:[0-9][0-9.]*}" + p }