Merge pull request #5803 from baude/v2init

v2podman add container init
This commit is contained in:
OpenShift Merge Robot 2020-04-14 14:34:18 +02:00 committed by GitHub
commit 004826653f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 186 additions and 2 deletions

View File

@ -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()
}

View File

@ -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, "")
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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())
})
})

View File

@ -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
}

View File

@ -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)

View File

@ -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
}

View File

@ -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
}