summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrent Baude <bbaude@redhat.com>2020-04-13 16:04:05 -0500
committerBrent Baude <bbaude@redhat.com>2020-04-13 19:51:20 -0500
commitd8d1aa49d27d51f914a0858ab99c57d7dc929926 (patch)
tree715f035f049b161b55932fa9586f24c1876f11a5
parent5cf64aee11063bc8e7ff22f1365b0bf6b3ab0900 (diff)
downloadpodman-d8d1aa49d27d51f914a0858ab99c57d7dc929926.tar.gz
podman-d8d1aa49d27d51f914a0858ab99c57d7dc929926.tar.bz2
podman-d8d1aa49d27d51f914a0858ab99c57d7dc929926.zip
v2podman add container init
add the ability to init a container both local and remote Signed-off-by: Brent Baude <bbaude@redhat.com>
-rw-r--r--cmd/podmanV2/containers/init.go60
-rw-r--r--pkg/api/handlers/libpod/containers.go20
-rw-r--r--pkg/api/server/register_containers.go26
-rw-r--r--pkg/bindings/containers/containers.go19
-rw-r--r--pkg/bindings/test/containers_test.go18
-rw-r--r--pkg/domain/entities/containers.go14
-rw-r--r--pkg/domain/entities/engine_container.go1
-rw-r--r--pkg/domain/infra/abi/containers.go14
-rw-r--r--pkg/domain/infra/tunnel/containers.go16
9 files changed, 186 insertions, 2 deletions
diff --git a/cmd/podmanV2/containers/init.go b/cmd/podmanV2/containers/init.go
new file mode 100644
index 000000000..dd1e1d21b
--- /dev/null
+++ b/cmd/podmanV2/containers/init.go
@@ -0,0 +1,60 @@
+package containers
+
+import (
+ "fmt"
+
+ "github.com/containers/libpod/cmd/podmanV2/parse"
+ "github.com/containers/libpod/cmd/podmanV2/registry"
+ "github.com/containers/libpod/cmd/podmanV2/utils"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/spf13/cobra"
+)
+
+var (
+ initDescription = `Initialize one or more containers, creating the OCI spec and mounts for inspection. Container names or IDs can be used.`
+
+ initCommand = &cobra.Command{
+ Use: "init [flags] CONTAINER [CONTAINER...]",
+ Short: "Initialize one or more containers",
+ Long: initDescription,
+ PreRunE: preRunE,
+ RunE: initContainer,
+ Args: func(cmd *cobra.Command, args []string) error {
+ return parse.CheckAllLatestAndCIDFile(cmd, args, false, false)
+ },
+ Example: `podman init --latest
+ podman init 3c45ef19d893
+ podman init test1`,
+ }
+)
+
+var (
+ initOptions entities.ContainerInitOptions
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: initCommand,
+ })
+ flags := initCommand.Flags()
+ flags.BoolVarP(&initOptions.All, "all", "a", false, "Initialize all containers")
+ flags.BoolVarP(&initOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
+ _ = flags.MarkHidden("latest")
+}
+
+func initContainer(cmd *cobra.Command, args []string) error {
+ var errs utils.OutputErrors
+ report, err := registry.ContainerEngine().ContainerInit(registry.GetContext(), args, initOptions)
+ if err != nil {
+ return err
+ }
+ for _, r := range report {
+ if r.Err == nil {
+ fmt.Println(r.Id)
+ } else {
+ errs = append(errs, r.Err)
+ }
+ }
+ return errs.PrintErrors()
+}
diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go
index 5cbfb11eb..086bef847 100644
--- a/pkg/api/handlers/libpod/containers.go
+++ b/pkg/api/handlers/libpod/containers.go
@@ -285,3 +285,23 @@ func Restore(w http.ResponseWriter, r *http.Request) {
}
utils.WriteResponse(w, http.StatusOK, entities.RestoreReport{Id: ctr.ID()})
}
+
+func InitContainer(w http.ResponseWriter, r *http.Request) {
+ name := utils.GetName(r)
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+ ctr, err := runtime.LookupContainer(name)
+ if err != nil {
+ utils.ContainerNotFound(w, name, err)
+ return
+ }
+ err = ctr.Init(r.Context())
+ if errors.Cause(err) == define.ErrCtrStateInvalid {
+ utils.Error(w, "container already initialized", http.StatusNotModified, err)
+ return
+ }
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+ utils.WriteResponse(w, http.StatusNoContent, "")
+}
diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go
index 150cca872..e39e43bfb 100644
--- a/pkg/api/server/register_containers.go
+++ b/pkg/api/server/register_containers.go
@@ -1377,7 +1377,6 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name}/restore"), s.APIHandler(libpod.Restore)).Methods(http.MethodPost)
-
// swagger:operation GET /containers/{name}/changes libpod libpodChangesContainer
// swagger:operation GET /libpod/containers/{name}/changes compat changesContainer
// ---
@@ -1411,6 +1410,29 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
r.HandleFunc(VersionedPath("/containers/{name}/changes"), s.APIHandler(compat.Changes))
r.HandleFunc("/containers/{name}/changes", s.APIHandler(compat.Changes))
r.HandleFunc(VersionedPath("/libpod/containers/{name}/changes"), s.APIHandler(compat.Changes))
-
+ // swagger:operation POST /libpod/containers/{name}/init libpod libpodInitContainer
+ // ---
+ // tags:
+ // - containers
+ // summary: Initialize a container
+ // description: Performs all tasks necessary for initializing the container but does not start the container.
+ // parameters:
+ // - in: path
+ // name: name
+ // type: string
+ // required: true
+ // description: the name or ID of the container
+ // produces:
+ // - application/json
+ // responses:
+ // 204:
+ // description: no error
+ // 304:
+ // description: container already initialized
+ // 404:
+ // $ref: "#/responses/NoSuchContainer"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.HandleFunc(VersionedPath("/libpod/containers/{name}/init"), s.APIHandler(libpod.InitContainer)).Methods(http.MethodPost)
return nil
}
diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go
index a188d73a0..963f0ec57 100644
--- a/pkg/bindings/containers/containers.go
+++ b/pkg/bindings/containers/containers.go
@@ -12,6 +12,7 @@ import (
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/bindings"
"github.com/containers/libpod/pkg/domain/entities"
+ "github.com/pkg/errors"
)
// List obtains a list of containers in local storage. All parameters to this method are optional.
@@ -316,3 +317,21 @@ func Export(ctx context.Context, nameOrID string, w io.Writer) error {
}
return response.Process(nil)
}
+
+// ContainerInit takes a created container and executes all of the
+// preparations to run the container except it will not start
+// or attach to the container
+func ContainerInit(ctx context.Context, nameOrID string) error {
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return err
+ }
+ response, err := conn.DoRequest(nil, http.MethodPost, "/containers/%s/init", nil, nameOrID)
+ if err != nil {
+ return err
+ }
+ if response.StatusCode == http.StatusNotModified {
+ return errors.Wrapf(define.ErrCtrStateInvalid, "container %s has already been created in runtime", nameOrID)
+ }
+ return response.Process(nil)
+}
diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go
index a8e2fd071..c6501ac9e 100644
--- a/pkg/bindings/test/containers_test.go
+++ b/pkg/bindings/test/containers_test.go
@@ -513,4 +513,22 @@ var _ = Describe("Podman containers ", func() {
Expect(err).To(BeNil())
})
+ It("container init on a bogus container", func() {
+ err := containers.ContainerInit(bt.conn, "doesnotexist")
+ Expect(err).ToNot(BeNil())
+ code, _ := bindings.CheckResponseCode(err)
+ Expect(code).To(BeNumerically("==", http.StatusNotFound))
+ })
+
+ It("container init", func() {
+ s := specgen.NewSpecGenerator(alpine.name)
+ ctr, err := containers.CreateWithSpec(bt.conn, s)
+ Expect(err).To(BeNil())
+ err = containers.ContainerInit(bt.conn, ctr.ID)
+ Expect(err).To(BeNil())
+ // trying to init again should be an error
+ err = containers.ContainerInit(bt.conn, ctr.ID)
+ Expect(err).ToNot(BeNil())
+ })
+
})
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index 51e6cc751..4508f9c2c 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -283,3 +283,17 @@ type ContainerCleanupReport struct {
RmErr error
RmiErr error
}
+
+// ContainerInitOptions describes input options
+// for the container init cli
+type ContainerInitOptions struct {
+ All bool
+ Latest bool
+}
+
+// ContainerInitReport describes the results of a
+// container init
+type ContainerInitReport struct {
+ Err error
+ Id string
+}
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index 7e455b969..d23006a38 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -17,6 +17,7 @@ type ContainerEngine interface {
ContainerExec(ctx context.Context, nameOrId string, options ExecOptions) (int, error)
ContainerExists(ctx context.Context, nameOrId string) (*BoolReport, error)
ContainerExport(ctx context.Context, nameOrId string, options ContainerExportOptions) error
+ ContainerInit(ctx context.Context, namesOrIds []string, options ContainerInitOptions) ([]*ContainerInitReport, error)
ContainerInspect(ctx context.Context, namesOrIds []string, options InspectOptions) ([]*ContainerInspectReport, error)
ContainerKill(ctx context.Context, namesOrIds []string, options KillOptions) ([]*KillReport, error)
ContainerList(ctx context.Context, options ContainerListOptions) ([]ListContainer, error)
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 7f8ec210b..a3a0a8202 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -794,3 +794,17 @@ func (ic *ContainerEngine) ContainerCleanup(ctx context.Context, namesOrIds []st
}
return reports, nil
}
+
+func (ic *ContainerEngine) ContainerInit(ctx context.Context, namesOrIds []string, options entities.ContainerInitOptions) ([]*entities.ContainerInitReport, error) {
+ var reports []*entities.ContainerInitReport
+ ctrs, err := getContainersByContext(options.All, options.Latest, namesOrIds, ic.Libpod)
+ if err != nil {
+ return nil, err
+ }
+ for _, ctr := range ctrs {
+ report := entities.ContainerInitReport{Id: ctr.ID()}
+ report.Err = ctr.Init(ctx)
+ reports = append(reports, &report)
+ }
+ return reports, nil
+}
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 2bc3a1914..1a430e3d0 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -338,3 +338,19 @@ func (ic *ContainerEngine) ContainerDiff(ctx context.Context, nameOrId string, _
func (ic *ContainerEngine) ContainerCleanup(ctx context.Context, namesOrIds []string, options entities.ContainerCleanupOptions) ([]*entities.ContainerCleanupReport, error) {
return nil, errors.New("not implemented")
}
+
+func (ic *ContainerEngine) ContainerInit(ctx context.Context, namesOrIds []string, options entities.ContainerInitOptions) ([]*entities.ContainerInitReport, error) {
+ var reports []*entities.ContainerInitReport
+ ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ for _, ctr := range ctrs {
+ err := containers.ContainerInit(ic.ClientCxt, ctr.ID)
+ reports = append(reports, &entities.ContainerInitReport{
+ Err: err,
+ Id: ctr.ID,
+ })
+ }
+ return reports, nil
+}