mirror of https://github.com/containers/podman.git
commit
004826653f
|
@ -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()
|
||||
}
|
|
@ -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, "")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue