summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--cmd/podman/build.go4
-rw-r--r--cmd/podman/common.go78
-rw-r--r--cmd/podman/create.go1
-rw-r--r--cmd/podman/pod_create.go12
-rw-r--r--cmd/podman/run.go1
-rw-r--r--libpod/image/image.go5
-rw-r--r--pkg/api/handlers/exec.go25
-rw-r--r--pkg/api/handlers/generic/images.go45
-rw-r--r--pkg/api/handlers/libpod/images.go52
-rw-r--r--pkg/api/handlers/swagger.go21
-rw-r--r--pkg/api/handlers/types.go15
-rw-r--r--pkg/api/server/register_exec.go329
-rw-r--r--pkg/api/server/register_images.go77
-rw-r--r--pkg/api/server/server.go1
-rw-r--r--pkg/api/server/swagger.go9
-rw-r--r--pkg/api/tags.yaml4
-rw-r--r--pkg/bindings/errors.go3
-rw-r--r--pkg/bindings/test/images_test.go35
19 files changed, 622 insertions, 97 deletions
diff --git a/Makefile b/Makefile
index 6713b8bae..1e5aa4d77 100644
--- a/Makefile
+++ b/Makefile
@@ -596,7 +596,7 @@ validate.completions: completions/bash/podman
if [ -x /bin/zsh ]; then /bin/zsh completions/zsh/_podman; fi
.PHONY: validate
-validate: lint gofmt .gitvalidation validate.completions man-page-check
+validate: gofmt lint .gitvalidation validate.completions man-page-check
.PHONY: build-all-new-commits
build-all-new-commits:
diff --git a/cmd/podman/build.go b/cmd/podman/build.go
index 885f2ac51..1fcb98a0e 100644
--- a/cmd/podman/build.go
+++ b/cmd/podman/build.go
@@ -234,10 +234,6 @@ func buildCmd(c *cliconfig.BuildValues) error {
return errors.Wrapf(err, "error determining path to file %q", containerfiles[i])
}
contextDir = filepath.Dir(absFile)
- containerfiles[i], err = filepath.Rel(contextDir, absFile)
- if err != nil {
- return errors.Wrapf(err, "error determining path to file %q", containerfiles[i])
- }
break
}
}
diff --git a/cmd/podman/common.go b/cmd/podman/common.go
index 46feae90d..7610edbc0 100644
--- a/cmd/podman/common.go
+++ b/cmd/podman/common.go
@@ -16,6 +16,7 @@ import (
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
"github.com/spf13/cobra"
+ "github.com/spf13/pflag"
)
var (
@@ -116,14 +117,49 @@ func getDefaultNetwork() string {
return "bridge"
}
-func getCreateFlags(c *cliconfig.PodmanCommand) {
-
- createFlags := c.Flags()
-
- createFlags.StringSlice(
+func getNetFlags() *pflag.FlagSet {
+ netFlags := pflag.FlagSet{}
+ netFlags.StringSlice(
"add-host", []string{},
"Add a custom host-to-IP mapping (host:ip) (default [])",
)
+ netFlags.StringSlice(
+ "dns", []string{},
+ "Set custom DNS servers",
+ )
+ netFlags.StringSlice(
+ "dns-opt", []string{},
+ "Set custom DNS options",
+ )
+ netFlags.StringSlice(
+ "dns-search", []string{},
+ "Set custom DNS search domains",
+ )
+ netFlags.String(
+ "ip", "",
+ "Specify a static IPv4 address for the container",
+ )
+ netFlags.String(
+ "mac-address", "",
+ "Container MAC address (e.g. 92:d0:c6:0a:29:33)",
+ )
+ netFlags.String(
+ "network", getDefaultNetwork(),
+ "Connect a container to a network",
+ )
+ netFlags.StringSliceP(
+ "publish", "p", []string{},
+ "Publish a container's port, or a range of ports, to the host (default [])",
+ )
+ netFlags.Bool(
+ "no-hosts", false,
+ "Do not create /etc/hosts within the container, instead use the version from the image",
+ )
+ return &netFlags
+}
+
+func getCreateFlags(c *cliconfig.PodmanCommand) {
+ createFlags := c.Flags()
createFlags.StringSlice(
"annotation", []string{},
"Add annotations to container (key:value) (default [])",
@@ -236,18 +272,6 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"device-write-iops", []string{},
"Limit write rate (IO per second) to a device (e.g. --device-write-iops=/dev/sda:1000)",
)
- createFlags.StringSlice(
- "dns", []string{},
- "Set custom DNS servers",
- )
- createFlags.StringSlice(
- "dns-opt", []string{},
- "Set custom DNS options",
- )
- createFlags.StringSlice(
- "dns-search", []string{},
- "Set custom DNS search domains",
- )
createFlags.String(
"entrypoint", "",
"Overwrite the default ENTRYPOINT of the image",
@@ -324,10 +348,6 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"Keep STDIN open even if not attached",
)
createFlags.String(
- "ip", "",
- "Specify a static IPv4 address for the container",
- )
- createFlags.String(
"ipc", "",
"IPC namespace to use",
)
@@ -351,10 +371,6 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"log-opt", []string{},
"Logging driver options (default [])",
)
- createFlags.String(
- "mac-address", "",
- "Container MAC address (e.g. 92:d0:c6:0a:29:33)",
- )
createFlags.StringP(
"memory", "m", "",
"Memory limit "+sizeWithUnitFormat,
@@ -375,14 +391,6 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"name", "",
"Assign a name to the container",
)
- createFlags.String(
- "network", getDefaultNetwork(),
- "Connect a container to a network",
- )
- createFlags.Bool(
- "no-hosts", false,
- "Do not create /etc/hosts within the container, instead use the version from the image",
- )
createFlags.Bool(
"oom-kill-disable", false,
"Disable OOM Killer",
@@ -417,10 +425,6 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"privileged", false,
"Give extended privileges to container",
)
- createFlags.StringSliceP(
- "publish", "p", []string{},
- "Publish a container's port, or a range of ports, to the host (default [])",
- )
createFlags.BoolP(
"publish-all", "P", false,
"Publish all exposed ports to random ports on the host interface",
diff --git a/cmd/podman/create.go b/cmd/podman/create.go
index 01cad9765..73d62bddb 100644
--- a/cmd/podman/create.go
+++ b/cmd/podman/create.go
@@ -41,6 +41,7 @@ func init() {
getCreateFlags(&createCommand.PodmanCommand)
flags := createCommand.Flags()
+ flags.AddFlagSet(getNetFlags())
flags.SetInterspersed(false)
flags.SetNormalizeFunc(aliasFlags)
}
diff --git a/cmd/podman/pod_create.go b/cmd/podman/pod_create.go
index ad3c00aa8..cee6476ea 100644
--- a/cmd/podman/pod_create.go
+++ b/cmd/podman/pod_create.go
@@ -44,6 +44,18 @@ func init() {
podCreateCommand.SetUsageTemplate(UsageTemplate())
flags := podCreateCommand.Flags()
flags.SetInterspersed(false)
+ // When we are ready to add the network options to the create commmand, we need to uncomment
+ // the following
+
+ //flags.AddFlagSet(getNetFlags())
+
+ // Once this is uncommented, then the publish option below needs to be removed because it
+ // conflicts with the publish in getNetFlags. Upon removal, the c.Publish will not work
+ // anymore and needs to be cleaned up. I suggest starting with removing the Publish attribute
+ // from PodCreateValues structure. Running make should then expose all areas that need to be
+ // addressed. To get the value of publish (and other flags in getNetFlags, use the syntax:
+ // c.<type>("<flag_name") or c.Bool("publish")
+ // Remember to do this safely by checking len, etc.
flags.StringVar(&podCreateCommand.CgroupParent, "cgroup-parent", "", "Set parent cgroup for the pod")
flags.BoolVar(&podCreateCommand.Infra, "infra", true, "Create an infra container associated with the pod to share namespaces with")
diff --git a/cmd/podman/run.go b/cmd/podman/run.go
index caa594682..219f057c3 100644
--- a/cmd/podman/run.go
+++ b/cmd/podman/run.go
@@ -38,6 +38,7 @@ func init() {
flags.SetInterspersed(false)
flags.SetNormalizeFunc(aliasFlags)
flags.Bool("sig-proxy", true, "Proxy received signals to the process")
+ flags.AddFlagSet(getNetFlags())
getCreateFlags(&runCommand.PodmanCommand)
markFlagHiddenForRemoteClient("authfile", flags)
}
diff --git a/libpod/image/image.go b/libpod/image/image.go
index 355249b12..ba1080a71 100644
--- a/libpod/image/image.go
+++ b/libpod/image/image.go
@@ -709,11 +709,12 @@ func (i *Image) Size(ctx context.Context) (*uint64, error) {
}
i.image = localImage
}
- if sum, err := i.imageruntime.store.ImageSize(i.ID()); err == nil && sum >= 0 {
+ sum, err := i.imageruntime.store.ImageSize(i.ID())
+ if err == nil && sum >= 0 {
usum := uint64(sum)
return &usum, nil
}
- return nil, errors.Errorf("unable to determine size")
+ return nil, errors.Wrap(err, "unable to determine size")
}
// toImageRef returns an Image Reference type from an image
diff --git a/pkg/api/handlers/exec.go b/pkg/api/handlers/exec.go
new file mode 100644
index 000000000..8a7b2ae26
--- /dev/null
+++ b/pkg/api/handlers/exec.go
@@ -0,0 +1,25 @@
+package handlers
+
+import (
+ "net/http"
+
+ "github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/pkg/api/handlers/utils"
+)
+
+func CreateExec(w http.ResponseWriter, r *http.Request) {
+ utils.Error(w, "function not implemented", http.StatusInternalServerError, define.ErrNotImplemented)
+}
+
+func StartExec(w http.ResponseWriter, r *http.Request) {
+ utils.Error(w, "function not implemented", http.StatusInternalServerError, define.ErrNotImplemented)
+}
+
+func ResizeExec(w http.ResponseWriter, r *http.Request) {
+ utils.Error(w, "function not implemented", http.StatusInternalServerError, define.ErrNotImplemented)
+
+}
+
+func InspectExec(w http.ResponseWriter, r *http.Request) {
+ utils.Error(w, "function not implemented", http.StatusInternalServerError, define.ErrNotImplemented)
+}
diff --git a/pkg/api/handlers/generic/images.go b/pkg/api/handlers/generic/images.go
index 20dd84456..c65db7575 100644
--- a/pkg/api/handlers/generic/images.go
+++ b/pkg/api/handlers/generic/images.go
@@ -3,6 +3,7 @@ package generic
import (
"encoding/json"
"fmt"
+ "io"
"io/ioutil"
"net/http"
"os"
@@ -315,3 +316,47 @@ func GetImages(w http.ResponseWriter, r *http.Request) {
}
utils.WriteResponse(w, http.StatusOK, summaries)
}
+
+func LoadImages(w http.ResponseWriter, r *http.Request) {
+ // TODO this is basically wrong
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+
+ query := struct {
+ Changes map[string]string `json:"changes"`
+ Message string `json:"message"`
+ Quiet bool `json:"quiet"`
+ }{
+ // This is where you can override the golang default value for one of fields
+ }
+
+ if err := decoder.Decode(&query, r.URL.Query()); err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()))
+ return
+ }
+
+ var (
+ err error
+ writer io.Writer
+ )
+ f, err := ioutil.TempFile("", "api_load.tar")
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to create tempfile"))
+ return
+ }
+ if err := handlers.SaveFromBody(f, r); err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to write temporary file"))
+ return
+ }
+ id, err := runtime.LoadImage(r.Context(), "", f.Name(), writer, "")
+ //id, err := runtime.Import(r.Context())
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to load image"))
+ return
+ }
+ utils.WriteResponse(w, http.StatusOK, struct {
+ Stream string `json:"stream"`
+ }{
+ Stream: fmt.Sprintf("Loaded image: %s\n", id),
+ })
+}
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 202ed5eaa..6c926c45b 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -2,7 +2,6 @@ package libpod
import (
"fmt"
- "io"
"io/ioutil"
"net/http"
"os"
@@ -176,46 +175,17 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, rdr)
}
-func ImportImage(w http.ResponseWriter, r *http.Request) {
- // TODO this is basically wrong
- decoder := r.Context().Value("decoder").(*schema.Decoder)
- runtime := r.Context().Value("runtime").(*libpod.Runtime)
-
- query := struct {
- Changes map[string]string `json:"changes"`
- Message string `json:"message"`
- Quiet bool `json:"quiet"`
- }{
- // This is where you can override the golang default value for one of fields
- }
+func ImagesLoad(w http.ResponseWriter, r *http.Request) {
+ //TODO ...
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.New("/libpod/images/load is not yet implemented"))
+}
- if err := decoder.Decode(&query, r.URL.Query()); err != nil {
- utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()))
- return
- }
+func ImagesImport(w http.ResponseWriter, r *http.Request) {
+ //TODO ...
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.New("/libpod/images/import is not yet implemented"))
+}
- var (
- err error
- writer io.Writer
- )
- f, err := ioutil.TempFile("", "api_load.tar")
- if err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to create tempfile"))
- return
- }
- if err := handlers.SaveFromBody(f, r); err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to write temporary file"))
- return
- }
- id, err := runtime.LoadImage(r.Context(), "", f.Name(), writer, "")
- //id, err := runtime.Import(r.Context())
- if err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to load image"))
- return
- }
- utils.WriteResponse(w, http.StatusOK, struct {
- Stream string `json:"stream"`
- }{
- Stream: fmt.Sprintf("Loaded image: %s\n", id),
- })
+func ImagesPull(w http.ResponseWriter, r *http.Request) {
+ //TODO ...
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.New("/libpod/images/pull is not yet implemented"))
}
diff --git a/pkg/api/handlers/swagger.go b/pkg/api/handlers/swagger.go
index faae98798..bc75777aa 100644
--- a/pkg/api/handlers/swagger.go
+++ b/pkg/api/handlers/swagger.go
@@ -26,6 +26,27 @@ type swagImageInspect struct {
}
}
+// Load response
+// swagger:response DocsLibpodImagesLoadResponse
+type swagLibpodImagesLoadResponse struct {
+ // in:body
+ Body []LibpodImagesLoadReport
+}
+
+// Import response
+// swagger:response DocsLibpodImagesImportResponse
+type swagLibpodImagesImportResponse struct {
+ // in:body
+ Body LibpodImagesImportReport
+}
+
+// Pull response
+// swagger:response DocsLibpodImagesPullResponse
+type swagLibpodImagesPullResponse struct {
+ // in:body
+ Body LibpodImagesPullReport
+}
+
// Delete response
// swagger:response DocsImageDeleteResponse
type swagImageDeleteResponse struct {
diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go
index 34b428852..6169adb18 100644
--- a/pkg/api/handlers/types.go
+++ b/pkg/api/handlers/types.go
@@ -49,6 +49,21 @@ type LibpodContainersPruneReport struct {
PruneError string `json:"error"`
}
+type LibpodImagesLoadReport struct {
+ ID string `json:"id"`
+ RepoTags []string `json:"repoTags"`
+}
+
+type LibpodImagesImportReport struct {
+ ID string `json:"id"`
+ RepoTags []string `json:"repoTags"`
+}
+
+type LibpodImagesPullReport struct {
+ ID string `json:"id"`
+ RepoTags []string `json:"repoTags"`
+}
+
type Info struct {
docker.Info
BuildahVersion string
diff --git a/pkg/api/server/register_exec.go b/pkg/api/server/register_exec.go
new file mode 100644
index 000000000..dbf04dc19
--- /dev/null
+++ b/pkg/api/server/register_exec.go
@@ -0,0 +1,329 @@
+package server
+
+import (
+ "net/http"
+
+ "github.com/containers/libpod/pkg/api/handlers"
+ "github.com/gorilla/mux"
+)
+
+func (s *APIServer) registerExecHandlers(r *mux.Router) error {
+ // swagger:operation POST /containers/{name}/create compat createExec
+ // ---
+ // tags:
+ // - exec (compat)
+ // summary: Create an exec instance
+ // description: Run a command inside a running container.
+ // parameters:
+ // - in: path
+ // name: name
+ // type: string
+ // required: true
+ // description: name of container
+ // - in: body
+ // name: control
+ // description: Attributes for create
+ // schema:
+ // type: object
+ // properties:
+ // AttachStdin:
+ // type: boolean
+ // description: Attach to stdin of the exec command
+ // AttachStdout:
+ // type: boolean
+ // description: Attach to stdout of the exec command
+ // AttachStderr:
+ // type: boolean
+ // description: Attach to stderr of the exec command
+ // DetachKeys:
+ // type: string
+ // description: |
+ // "Override the key sequence for detaching a container. Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _."
+ // Tty:
+ // type: boolean
+ // description: Allocate a pseudo-TTY
+ // Env:
+ // type: array
+ // description: A list of environment variables in the form ["VAR=value", ...]
+ // items:
+ // type: string
+ // Cmd:
+ // type: array
+ // description: Command to run, as a string or array of strings.
+ // items:
+ // type: string
+ // Privileged:
+ // type: boolean
+ // default: false
+ // description: Runs the exec process with extended privileges
+ // User:
+ // type: string
+ // description: |
+ // "The user, and optionally, group to run the exec process inside the container. Format is one of: user, user:group, uid, or uid:gid."
+ // WorkingDir:
+ // type: string
+ // description: The working directory for the exec process inside the container.
+ // produces:
+ // - application/json
+ // responses:
+ // 201:
+ // description: no error
+ // 404:
+ // $ref: "#/responses/NoSuchContainer"
+ // 409:
+ // description: container is paused
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.Handle(VersionedPath("/containers/{name}/create"), APIHandler(s.Context, handlers.CreateExec)).Methods(http.MethodPost)
+ // swagger:operation POST /exec/{id}/start compat startExec
+ // ---
+ // tags:
+ // - exec (compat)
+ // summary: Start an exec instance
+ // description: Starts a previously set up exec instance. If detach is true, this endpoint returns immediately after starting the command. Otherwise, it sets up an interactive session with the command.
+ // parameters:
+ // - in: path
+ // name: id
+ // type: string
+ // required: true
+ // description: Exec instance ID
+ // - in: body
+ // name: control
+ // description: Attributes for start
+ // schema:
+ // type: object
+ // properties:
+ // Detach:
+ // type: boolean
+ // description: Detach from the command
+ // Tty:
+ // type: boolean
+ // description: Allocate a pseudo-TTY
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // description: no error
+ // 404:
+ // $ref: "#/responses/NoSuchExecInstance"
+ // 409:
+ // description: container is stopped or paused
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.Handle(VersionedPath("/exec/{id}/start"), APIHandler(s.Context, handlers.StartExec)).Methods(http.MethodPost)
+ // swagger:operation POST /exec/{id}/resize compat resizeExec
+ // ---
+ // tags:
+ // - exec (compat)
+ // summary: Resize an exec instance
+ // description: |
+ // Resize the TTY session used by an exec instance. This endpoint only works if tty was specified as part of creating and starting the exec instance.
+ // parameters:
+ // - in: path
+ // name: id
+ // type: string
+ // required: true
+ // description: Exec instance ID
+ // - in: query
+ // name: h
+ // type: integer
+ // description: Height of the TTY session in characters
+ // - in: query
+ // name: w
+ // type: integer
+ // description: Width of the TTY session in characters
+ // produces:
+ // - application/json
+ // responses:
+ // 201:
+ // description: no error
+ // 404:
+ // $ref: "#/responses/NoSuchExecInstance"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.Handle(VersionedPath("/exec/{id}/resize"), APIHandler(s.Context, handlers.ResizeExec)).Methods(http.MethodPost)
+ // swagger:operation GET /exec/{id}/inspect compat inspectExec
+ // ---
+ // tags:
+ // - exec (compat)
+ // summary: Inspect an exec instance
+ // description: Return low-level information about an exec instance.
+ // parameters:
+ // - in: path
+ // name: id
+ // type: string
+ // required: true
+ // description: Exec instance ID
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // description: no error
+ // 404:
+ // $ref: "#/responses/NoSuchExecInstance"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.Handle(VersionedPath("/exec/{id}/json"), APIHandler(s.Context, handlers.InspectExec)).Methods(http.MethodGet)
+
+ /*
+ libpod api follows
+ */
+
+ // swagger:operation POST /libpod/containers/{name}/create libpod libpodCreateExec
+ // ---
+ // tags:
+ // - exec
+ // summary: Create an exec instance
+ // description: Run a command inside a running container.
+ // parameters:
+ // - in: path
+ // name: name
+ // type: string
+ // required: true
+ // description: name of container
+ // - in: body
+ // name: control
+ // description: Attributes for create
+ // schema:
+ // type: object
+ // properties:
+ // AttachStdin:
+ // type: boolean
+ // description: Attach to stdin of the exec command
+ // AttachStdout:
+ // type: boolean
+ // description: Attach to stdout of the exec command
+ // AttachStderr:
+ // type: boolean
+ // description: Attach to stderr of the exec command
+ // DetachKeys:
+ // type: string
+ // description: |
+ // "Override the key sequence for detaching a container. Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _."
+ // Tty:
+ // type: boolean
+ // description: Allocate a pseudo-TTY
+ // Env:
+ // type: array
+ // description: A list of environment variables in the form ["VAR=value", ...]
+ // items:
+ // type: string
+ // Cmd:
+ // type: array
+ // description: Command to run, as a string or array of strings.
+ // items:
+ // type: string
+ // Privileged:
+ // type: boolean
+ // default: false
+ // description: Runs the exec process with extended privileges
+ // User:
+ // type: string
+ // description: |
+ // "The user, and optionally, group to run the exec process inside the container. Format is one of: user, user:group, uid, or uid:gid."
+ // WorkingDir:
+ // type: string
+ // description: The working directory for the exec process inside the container.
+ // produces:
+ // - application/json
+ // responses:
+ // 201:
+ // description: no error
+ // 404:
+ // $ref: "#/responses/NoSuchContainer"
+ // 409:
+ // description: container is paused
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.Handle(VersionedPath("/libpod/containers/{name}/create"), APIHandler(s.Context, handlers.CreateExec)).Methods(http.MethodPost)
+ // swagger:operation POST /libpod/exec/{id}/start libpod libpodStartExec
+ // ---
+ // tags:
+ // - exec
+ // summary: Start an exec instance
+ // description: Starts a previously set up exec instance. If detach is true, this endpoint returns immediately after starting the command. Otherwise, it sets up an interactive session with the command.
+ // parameters:
+ // - in: path
+ // name: id
+ // type: string
+ // required: true
+ // description: Exec instance ID
+ // - in: body
+ // name: control
+ // description: Attributes for start
+ // schema:
+ // type: object
+ // properties:
+ // Detach:
+ // type: boolean
+ // description: Detach from the command
+ // Tty:
+ // type: boolean
+ // description: Allocate a pseudo-TTY
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // description: no error
+ // 404:
+ // $ref: "#/responses/NoSuchExecInstance"
+ // 409:
+ // description: container is stopped or paused
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.Handle(VersionedPath("/libpod/exec/{id}/start"), APIHandler(s.Context, handlers.StartExec)).Methods(http.MethodPost)
+ // swagger:operation POST /libpod/exec/{id}/resize libpod libpodResizeExec
+ // ---
+ // tags:
+ // - exec
+ // summary: Resize an exec instance
+ // description: |
+ // Resize the TTY session used by an exec instance. This endpoint only works if tty was specified as part of creating and starting the exec instance.
+ // parameters:
+ // - in: path
+ // name: id
+ // type: string
+ // required: true
+ // description: Exec instance ID
+ // - in: query
+ // name: h
+ // type: integer
+ // description: Height of the TTY session in characters
+ // - in: query
+ // name: w
+ // type: integer
+ // description: Width of the TTY session in characters
+ // produces:
+ // - application/json
+ // responses:
+ // 201:
+ // description: no error
+ // 404:
+ // $ref: "#/responses/NoSuchExecInstance"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.Handle(VersionedPath("/libpod/exec/{id}/resize"), APIHandler(s.Context, handlers.ResizeExec)).Methods(http.MethodPost)
+ // swagger:operation GET /libpod/exec/{id}/inspect libpod libpodInspectExec
+ // ---
+ // tags:
+ // - exec
+ // summary: Inspect an exec instance
+ // description: Return low-level information about an exec instance.
+ // parameters:
+ // - in: path
+ // name: id
+ // type: string
+ // required: true
+ // description: Exec instance ID
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // description: no error
+ // 404:
+ // $ref: "#/responses/NoSuchExecInstance"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.Handle(VersionedPath("/libpod/exec/{id}/json"), APIHandler(s.Context, handlers.InspectExec)).Methods(http.MethodGet)
+ return nil
+}
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index 18a90dc3d..2959e604a 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -107,7 +107,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// description: no error
// 500:
// $ref: '#/responses/InternalError'
- r.Handle(VersionedPath("/images/load"), APIHandler(s.Context, libpod.ImportImage)).Methods(http.MethodPost)
+ r.Handle(VersionedPath("/images/load"), APIHandler(s.Context, generic.LoadImages)).Methods(http.MethodPost)
// swagger:operation POST /images/prune compat pruneImages
// ---
// tags:
@@ -631,18 +631,14 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// 500:
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/images/json"), APIHandler(s.Context, libpod.GetImages)).Methods(http.MethodGet)
- // swagger:operation POST /libpod/images/load libpod libpodImportImage
+ // swagger:operation POST /libpod/images/load libpod libpodImagesLoad
// ---
// tags:
// - images
- // summary: Import image
- // description: Load a set of images and tags into a repository.
+ // summary: Load image
+ // description: Load an image (oci-archive or docker-archive) stream.
// parameters:
// - in: query
- // name: quiet
- // type: boolean
- // description: not supported
- // - in: query
// name: change
// description: "Apply the following possible instructions to the created image (default []): CMD | ENTRYPOINT | ENV | EXPOSE | LABEL | STOPSIGNAL | USER | VOLUME | WORKDIR. JSON encoded string"
// type: string
@@ -660,10 +656,71 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// - application/json
// responses:
// 200:
- // description: no error
+ // $ref: "#/response/LibpodImagesLoadResponse"
+ // 500:
+ // $ref: '#/responses/InternalError'
+ r.Handle(VersionedPath("/libpod/images/load"), APIHandler(s.Context, libpod.ImagesLoad)).Methods(http.MethodPost)
+ // swagger:operation POST /libpod/images/import libpod libpodImagesImport
+ // ---
+ // tags:
+ // - images
+ // summary: Import image
+ // description: Import a previosly exported tarball as an image.
+ // parameters:
+ // - in: query
+ // name: change
+ // description: "Apply the following possible instructions to the created image (default []): CMD | ENTRYPOINT | ENV | EXPOSE | LABEL | STOPSIGNAL | USER | VOLUME | WORKDIR. JSON encoded string"
+ // type: string
+ // - in: query
+ // name: message
+ // description: Set commit message for imported image
+ // type: string
+ // - in: query
+ // name: url
+ // description: Specify a URL instead of a tarball
+ // type: bool
+ // - in: body
+ // name: request
+ // description: Tarball of (or URL to) container image
+ // required: true
+ // schema:
+ // type: string
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // $ref: "#/response/LibpodImagesImportResponse"
+ // 500:
+ // $ref: '#/responses/InternalError'
+ r.Handle(VersionedPath("/libpod/images/import"), APIHandler(s.Context, libpod.ImagesImport)).Methods(http.MethodPost)
+ // swagger:operation GET /libpod/images/pull libpod libpodImagesPull
+ // ---
+ // tags:
+ // - images
+ // summary: Import image
+ // description: Import a previosly exported image as a tarball.
+ // parameters:
+ // - in: query
+ // name: reference
+ // description: Mandatory reference to the image (e.g., quay.io/image/name:tag)/
+ // type: string
+ // - in: query
+ // name: credentials
+ // description: username:password for the registry.
+ // type: string
+ // - in: query
+ // name: tls-verify
+ // description: Require TLS verification.
+ // type: bool
+ // default: true
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // $ref: "#/response/LibpodImagesPullResponse"
// 500:
// $ref: '#/responses/InternalError'
- r.Handle(VersionedPath("/libpod/images/load"), APIHandler(s.Context, libpod.ImportImage)).Methods(http.MethodPost)
+ r.Handle(VersionedPath("/libpod/images/pull"), APIHandler(s.Context, libpod.ImagesPull)).Methods(http.MethodPost)
// swagger:operation POST /libpod/images/prune libpod libpodPruneImages
// ---
// tags:
diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go
index d030961cb..7bb0f5481 100644
--- a/pkg/api/server/server.go
+++ b/pkg/api/server/server.go
@@ -105,6 +105,7 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li
server.RegisterAuthHandlers,
server.RegisterContainersHandlers,
server.RegisterDistributionHandlers,
+ server.registerExecHandlers,
server.registerHealthCheckHandlers,
server.registerImagesHandlers,
server.registerInfoHandlers,
diff --git a/pkg/api/server/swagger.go b/pkg/api/server/swagger.go
index 5098390bc..fc409d816 100644
--- a/pkg/api/server/swagger.go
+++ b/pkg/api/server/swagger.go
@@ -23,6 +23,15 @@ type swagErrNoSuchContainer struct {
}
}
+// No such exec instance
+// swagger:response NoSuchExecInstance
+type swagErrNoSuchExecInstance struct {
+ // in:body
+ Body struct {
+ utils.ErrorModel
+ }
+}
+
// No such volume
// swagger:response NoSuchVolume
type swagErrNoSuchVolume struct {
diff --git a/pkg/api/tags.yaml b/pkg/api/tags.yaml
index be70fb3d8..3bf2bb64f 100644
--- a/pkg/api/tags.yaml
+++ b/pkg/api/tags.yaml
@@ -1,6 +1,8 @@
tags:
- name: containers
description: Actions related to containers
+ - name: exec
+ description: Actions related to exec
- name: images
description: Actions related to images
- name: pods
@@ -11,6 +13,8 @@ tags:
description: Actions related to Podman engine
- name: containers (compat)
description: Actions related to containers for the compatibility endpoints
+ - name: exec (compat)
+ description: Actions related to exec for the compatibility endpoints
- name: images (compat)
description: Actions related to images for the compatibility endpoints
- name: system (compat)
diff --git a/pkg/bindings/errors.go b/pkg/bindings/errors.go
index 8bd40f804..1bcaac3f0 100644
--- a/pkg/bindings/errors.go
+++ b/pkg/bindings/errors.go
@@ -3,7 +3,6 @@ package bindings
import (
"encoding/json"
"io/ioutil"
- "net/http"
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/pkg/errors"
@@ -26,7 +25,7 @@ func (a APIResponse) Process(unmarshalInto interface{}) error {
if err != nil {
return errors.Wrap(err, "unable to process API response")
}
- if a.Response.StatusCode == http.StatusOK {
+ if a.IsSuccess() {
if unmarshalInto != nil {
return json.Unmarshal(data, unmarshalInto)
}
diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go
index 227f28d16..f2dc856b2 100644
--- a/pkg/bindings/test/images_test.go
+++ b/pkg/bindings/test/images_test.go
@@ -89,4 +89,39 @@ var _ = Describe("Podman images", func() {
})
+ //Tests to validate the image tag command.
+ It("tag image", func() {
+ // Validates if invalid image name is given a bad response is encountered.
+ err = images.Tag(connText, "dummy", "demo", "alpine")
+ Expect(err).ToNot(BeNil())
+ code, _ := bindings.CheckResponseCode(err)
+ Expect(code).To(BeNumerically("==", 404))
+
+ // Validates if the image is tagged sucessfully.
+ err = images.Tag(connText, "alpine", "demo", "alpine")
+ Expect(err).To(BeNil())
+
+ //Validates if name updates when the image is retagged.
+ _, err := images.GetImage(connText, "alpine:demo", nil)
+ Expect(err).To(BeNil())
+
+ })
+
+ //Test to validate the List images command.
+ It("List image", func() {
+ //Array to hold the list of images returned
+ imageSummary, err := images.List(connText, nil, nil)
+ //There Should be no errors in the response.
+ Expect(err).To(BeNil())
+ //Since in the begin context only one image is created the list context should have only one image
+ Expect(len(imageSummary)).To(Equal(1))
+
+ //To be written create a new image and check list count again
+ //imageSummary, err = images.List(connText, nil, nil)
+
+ //Since in the begin context only one image adding one more image should
+ ///Expect(len(imageSummary)).To(Equal(2)
+
+ })
+
})