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()})
|
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:
|
// 500:
|
||||||
// $ref: "#/responses/InternalError"
|
// $ref: "#/responses/InternalError"
|
||||||
r.HandleFunc(VersionedPath("/libpod/containers/{name}/restore"), s.APIHandler(libpod.Restore)).Methods(http.MethodPost)
|
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 /containers/{name}/changes libpod libpodChangesContainer
|
||||||
// swagger:operation GET /libpod/containers/{name}/changes compat changesContainer
|
// 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(VersionedPath("/containers/{name}/changes"), s.APIHandler(compat.Changes))
|
||||||
r.HandleFunc("/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))
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/containers/libpod/pkg/api/handlers"
|
"github.com/containers/libpod/pkg/api/handlers"
|
||||||
"github.com/containers/libpod/pkg/bindings"
|
"github.com/containers/libpod/pkg/bindings"
|
||||||
"github.com/containers/libpod/pkg/domain/entities"
|
"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.
|
// 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)
|
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())
|
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
|
RmErr error
|
||||||
RmiErr 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)
|
ContainerExec(ctx context.Context, nameOrId string, options ExecOptions) (int, error)
|
||||||
ContainerExists(ctx context.Context, nameOrId string) (*BoolReport, error)
|
ContainerExists(ctx context.Context, nameOrId string) (*BoolReport, error)
|
||||||
ContainerExport(ctx context.Context, nameOrId string, options ContainerExportOptions) 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)
|
ContainerInspect(ctx context.Context, namesOrIds []string, options InspectOptions) ([]*ContainerInspectReport, error)
|
||||||
ContainerKill(ctx context.Context, namesOrIds []string, options KillOptions) ([]*KillReport, error)
|
ContainerKill(ctx context.Context, namesOrIds []string, options KillOptions) ([]*KillReport, error)
|
||||||
ContainerList(ctx context.Context, options ContainerListOptions) ([]ListContainer, 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
|
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) {
|
func (ic *ContainerEngine) ContainerCleanup(ctx context.Context, namesOrIds []string, options entities.ContainerCleanupOptions) ([]*entities.ContainerCleanupReport, error) {
|
||||||
return nil, errors.New("not implemented")
|
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