diff options
Diffstat (limited to 'pkg')
44 files changed, 1863 insertions, 44 deletions
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go index a2f73307b..c395ffc7f 100644 --- a/pkg/adapter/containers.go +++ b/pkg/adapter/containers.go @@ -1213,8 +1213,8 @@ func (r *LocalRuntime) generateSystemdgenContainerInfo(c *cliconfig.GenerateSyst return nil, false, err } - timeout := int(ctr.StopTimeout()) - if c.StopTimeout >= 0 { + timeout := ctr.StopTimeout() + if c.Flags().Changed("timeout") || c.Flags().Changed("time") { timeout = c.StopTimeout } diff --git a/pkg/adapter/containers_remote.go b/pkg/adapter/containers_remote.go index 46db7ebe8..fc8b524d6 100644 --- a/pkg/adapter/containers_remote.go +++ b/pkg/adapter/containers_remote.go @@ -15,11 +15,11 @@ import ( "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/shared" - iopodman "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/logs" envLib "github.com/containers/libpod/pkg/env" + iopodman "github.com/containers/libpod/pkg/varlink" "github.com/containers/libpod/pkg/varlinkapi/virtwriter" "github.com/cri-o/ocicni/pkg/ocicni" "github.com/docker/docker/pkg/term" diff --git a/pkg/adapter/errors.go b/pkg/adapter/errors.go index ede3d4b1a..012d01d39 100644 --- a/pkg/adapter/errors.go +++ b/pkg/adapter/errors.go @@ -3,8 +3,8 @@ package adapter import ( - iopodman "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod/define" + iopodman "github.com/containers/libpod/pkg/varlink" "github.com/pkg/errors" ) diff --git a/pkg/adapter/images_remote.go b/pkg/adapter/images_remote.go index e7b38dccc..2df0ffcde 100644 --- a/pkg/adapter/images_remote.go +++ b/pkg/adapter/images_remote.go @@ -6,8 +6,8 @@ import ( "context" "encoding/json" - iopodman "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/pkg/inspect" + iopodman "github.com/containers/libpod/pkg/varlink" ) // Inspect returns returns an ImageData struct from over a varlink connection diff --git a/pkg/adapter/info_remote.go b/pkg/adapter/info_remote.go index c55d1f6ef..0e8fb06d1 100644 --- a/pkg/adapter/info_remote.go +++ b/pkg/adapter/info_remote.go @@ -4,9 +4,9 @@ package adapter import ( "encoding/json" - "github.com/containers/libpod/libpod/define" - "github.com/containers/libpod/cmd/podman/varlink" + "github.com/containers/libpod/libpod/define" + iopodman "github.com/containers/libpod/pkg/varlink" ) // Info returns information for the host system and its components diff --git a/pkg/adapter/pods_remote.go b/pkg/adapter/pods_remote.go index 6b8f22f15..ebd10a92a 100644 --- a/pkg/adapter/pods_remote.go +++ b/pkg/adapter/pods_remote.go @@ -10,9 +10,9 @@ import ( "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/shared" - iopodman "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" + iopodman "github.com/containers/libpod/pkg/varlink" "github.com/containers/libpod/pkg/varlinkapi" "github.com/pkg/errors" "github.com/sirupsen/logrus" diff --git a/pkg/adapter/reset_remote.go b/pkg/adapter/reset_remote.go index 663fab639..284b54a17 100644 --- a/pkg/adapter/reset_remote.go +++ b/pkg/adapter/reset_remote.go @@ -3,7 +3,7 @@ package adapter import ( - "github.com/containers/libpod/cmd/podman/varlink" + iopodman "github.com/containers/libpod/pkg/varlink" ) // Info returns information for the host system and its components diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go index a616e6c7a..a4ac660ea 100644 --- a/pkg/adapter/runtime_remote.go +++ b/pkg/adapter/runtime_remote.go @@ -22,12 +22,12 @@ import ( "github.com/containers/image/v5/types" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/remoteclientconfig" - iopodman "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/events" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/util" + iopodman "github.com/containers/libpod/pkg/varlink" "github.com/containers/libpod/utils" "github.com/containers/storage/pkg/archive" "github.com/opencontainers/go-digest" diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index 4b24d7d9f..bb54450da 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -303,6 +303,10 @@ func ImagesImport(w http.ResponseWriter, r *http.Request) { utils.WriteResponse(w, http.StatusOK, handlers.LibpodImagesImportReport{ID: importedImage}) } +// ImagesPull is the v2 libpod endpoint for pulling images. Note that the +// mandatory `reference` must be a reference to a registry (i.e., of docker +// transport or be normalized to one). Other transports are rejected as they +// do not make sense in a remote context. func ImagesPull(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) decoder := r.Context().Value("decoder").(*schema.Decoder) @@ -328,10 +332,11 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) { return } // Enforce the docker transport. This is just a precaution as some callers - // might accustomed to using the "transport:reference" notation. Using + // might be accustomed to using the "transport:reference" notation. Using // another than the "docker://" transport does not really make sense for a // remote case. For loading tarballs, the load and import endpoints should // be used. + dockerPrefix := fmt.Sprintf("%s://", docker.Transport.Name()) imageRef, err := alltransports.ParseImageName(query.Reference) if err == nil && imageRef.Transport().Name() != docker.Transport.Name() { utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, @@ -339,7 +344,7 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) { return } else if err != nil { origErr := err - imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s://%s", docker.Transport.Name(), query.Reference)) + imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, query.Reference)) if err != nil { utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, errors.Wrapf(origErr, "reference %q must be a docker reference", query.Reference)) @@ -347,16 +352,19 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) { } } + // Trim the docker-transport prefix. + rawImage := strings.TrimPrefix(query.Reference, dockerPrefix) + // all-tags doesn't work with a tagged reference, so let's check early - namedRef, err := reference.Parse(query.Reference) + namedRef, err := reference.Parse(rawImage) if err != nil { utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, - errors.Wrapf(err, "error parsing reference %q", query.Reference)) + errors.Wrapf(err, "error parsing reference %q", rawImage)) return } if _, isTagged := namedRef.(reference.Tagged); isTagged && query.AllTags { utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, - errors.Errorf("reference %q must not have a tag for all-tags", query.Reference)) + errors.Errorf("reference %q must not have a tag for all-tags", rawImage)) return } diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go index 7e9c2e2c0..e834029b2 100644 --- a/pkg/api/handlers/libpod/pods.go +++ b/pkg/api/handlers/libpod/pods.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/http" + "strings" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" @@ -287,6 +288,48 @@ func PodUnpause(w http.ResponseWriter, r *http.Request) { utils.WriteResponse(w, http.StatusOK, &report) } +func PodTop(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + decoder := r.Context().Value("decoder").(*schema.Decoder) + + query := struct { + PsArgs string `schema:"ps_args"` + }{ + PsArgs: "", + } + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, + errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) + return + } + + name := utils.GetName(r) + pod, err := runtime.LookupPod(name) + if err != nil { + utils.ContainerNotFound(w, name, err) + return + } + + args := []string{} + if query.PsArgs != "" { + args = append(args, query.PsArgs) + } + output, err := pod.GetPodPidInformation(args) + if err != nil { + utils.InternalServerError(w, err) + return + } + + var body = handlers.PodTopOKBody{} + if len(output) > 0 { + body.Titles = strings.Split(output[0], "\t") + for _, line := range output[1:] { + body.Processes = append(body.Processes, strings.Split(line, "\t")) + } + } + utils.WriteJSON(w, http.StatusOK, body) +} + func PodKill(w http.ResponseWriter, r *http.Request) { var ( runtime = r.Context().Value("runtime").(*libpod.Runtime) diff --git a/pkg/api/handlers/swagger.go b/pkg/api/handlers/swagger.go index e6e937729..52763a050 100644 --- a/pkg/api/handlers/swagger.go +++ b/pkg/api/handlers/swagger.go @@ -97,14 +97,23 @@ type swagContainerInspectResponse struct { } // List processes in container -// swagger:response DockerTopResponse -type swagDockerTopResponse struct { +// swagger:response DocsContainerTopResponse +type swagContainerTopResponse struct { // in:body Body struct { ContainerTopOKBody } } +// List processes in pod +// swagger:response DocsPodTopResponse +type swagPodTopResponse struct { + // in:body + Body struct { + PodTopOKBody + } +} + // Inspect container // swagger:response LibpodInspectContainerResponse type swagLibpodInspectContainerResponse struct { diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go index 1ca5db3f9..89a571e67 100644 --- a/pkg/api/handlers/types.go +++ b/pkg/api/handlers/types.go @@ -133,6 +133,23 @@ type ContainerTopOKBody struct { dockerContainer.ContainerTopOKBody } +type PodTopOKBody struct { + dockerContainer.ContainerTopOKBody +} + +// swagger:model PodCreateConfig +type PodCreateConfig struct { + Name string `json:"name"` + CGroupParent string `json:"cgroup-parent"` + Hostname string `json:"hostname"` + Infra bool `json:"infra"` + InfraCommand string `json:"infra-command"` + InfraImage string `json:"infra-image"` + Labels []string `json:"labels"` + Publish []string `json:"publish"` + Share string `json:"share"` +} + type ErrorModel struct { Message string `json:"message"` } diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go index 2656d1d89..08834ff01 100644 --- a/pkg/api/server/register_containers.go +++ b/pkg/api/server/register_containers.go @@ -429,7 +429,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // - application/json // responses: // 200: - // $ref: "#/responses/DockerTopResponse" + // $ref: "#/responses/DocsContainerTopResponse" // 404: // $ref: "#/responses/NoSuchContainer" // 500: @@ -1041,7 +1041,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // - application/json // responses: // 200: - // $ref: "#/responses/DockerTopResponse" + // $ref: "#/responses/DocsContainerTopResponse" // 404: // $ref: "#/responses/NoSuchContainer" // 500: diff --git a/pkg/api/server/register_pods.go b/pkg/api/server/register_pods.go index 5ba2263e8..a49bf1f63 100644 --- a/pkg/api/server/register_pods.go +++ b/pkg/api/server/register_pods.go @@ -263,5 +263,36 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // 500: // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name}/unpause"), s.APIHandler(libpod.PodUnpause)).Methods(http.MethodPost) + // swagger:operation GET /libpod/pods/{name}/top pods topPod + // --- + // summary: List processes + // description: List processes running inside a pod + // produces: + // - application/json + // parameters: + // - in: path + // name: name + // type: string + // required: true + // description: | + // Name of pod to query for processes + // - in: query + // name: stream + // type: boolean + // default: true + // description: Stream the output + // - in: query + // name: ps_args + // type: string + // default: -ef + // description: arguments to pass to ps such as aux. Requires ps(1) to be installed in the container if no ps(1) compatible AIX descriptors are used. + // responses: + // 200: + // $ref: "#/responses/DocsPodTopResponse" + // 404: + // $ref: "#/responses/NoSuchContainer" + // 500: + // $ref: "#/responses/InternalError" + r.Handle(VersionedPath("/libpod/pods/{name}/top"), s.APIHandler(libpod.PodTop)).Methods(http.MethodGet) return nil } diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go index 5e3af7a60..5f5c4443f 100644 --- a/pkg/bindings/images/images.go +++ b/pkg/bindings/images/images.go @@ -8,6 +8,7 @@ import ( "net/url" "strconv" + "github.com/containers/image/v5/types" "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/bindings" "github.com/containers/libpod/pkg/domain/entities" @@ -229,3 +230,41 @@ func Import(ctx context.Context, changes []string, message, reference, u *string } return id.ID, response.Process(&id) } + +// Pull is the binding for libpod's v2 endpoints for pulling images. Note that +// `rawImage` must be a reference to a registry (i.e., of docker transport or be +// normalized to one). Other transports are rejected as they do not make sense +// in a remote context. +func Pull(ctx context.Context, rawImage string, options entities.ImagePullOptions) ([]string, error) { + conn, err := bindings.GetClient(ctx) + if err != nil { + return nil, err + } + params := url.Values{} + params.Set("reference", rawImage) + params.Set("credentials", options.Credentials) + params.Set("overrideArch", options.OverrideArch) + params.Set("overrideOS", options.OverrideOS) + if options.TLSVerify != types.OptionalBoolUndefined { + val := bool(options.TLSVerify == types.OptionalBoolTrue) + params.Set("tlsVerify", strconv.FormatBool(val)) + } + params.Set("allTags", strconv.FormatBool(options.AllTags)) + + response, err := conn.DoRequest(nil, http.MethodPost, "/images/pull", params) + if err != nil { + return nil, err + } + + reports := []handlers.LibpodImagesPullReport{} + if err := response.Process(&reports); err != nil { + return nil, err + } + + pulledImages := []string{} + for _, r := range reports { + pulledImages = append(pulledImages, r.ID) + } + + return pulledImages, nil +} diff --git a/pkg/bindings/pods/pods.go b/pkg/bindings/pods/pods.go index bb0abebc4..ae87c00e9 100644 --- a/pkg/bindings/pods/pods.go +++ b/pkg/bindings/pods/pods.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/bindings" "github.com/containers/libpod/pkg/domain/entities" "github.com/containers/libpod/pkg/specgen" @@ -213,9 +214,38 @@ func Stop(ctx context.Context, nameOrID string, timeout *int) (*entities.PodStop return &report, response.Process(&report) } -func Top() error { - // TODO - return bindings.ErrNotImplemented // nolint:typecheck +// Top gathers statistics about the running processes in a pod. The nameOrID can be a pod name +// or a partial/full ID. The descriptors allow for specifying which data to collect from each process. +func Top(ctx context.Context, nameOrID string, descriptors []string) ([]string, error) { + conn, err := bindings.GetClient(ctx) + if err != nil { + return nil, err + } + params := url.Values{} + + if len(descriptors) > 0 { + // flatten the slice into one string + params.Set("ps_args", strings.Join(descriptors, ",")) + } + response, err := conn.DoRequest(nil, http.MethodGet, "/pods/%s/top", params, nameOrID) + if err != nil { + return nil, err + } + + body := handlers.PodTopOKBody{} + if err = response.Process(&body); err != nil { + return nil, err + } + + // handlers.PodTopOKBody{} returns a slice of slices where each cell in the top table is an item. + // In libpod land, we're just using a slice with cells being split by tabs, which allows for an idiomatic + // usage of the tabwriter. + topOutput := []string{strings.Join(body.Titles, "\t")} + for _, out := range body.Processes { + topOutput = append(topOutput, strings.Join(out, "\t")) + } + + return topOutput, err } // Unpause unpauses all paused containers in a Pod. diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go index 9dd9cb707..a31181958 100644 --- a/pkg/bindings/test/containers_test.go +++ b/pkg/bindings/test/containers_test.go @@ -387,15 +387,15 @@ var _ = Describe("Podman containers ", func() { Expect(err).To(BeNil()) // By name - output, err := containers.Top(bt.conn, name, nil) + _, err = containers.Top(bt.conn, name, nil) Expect(err).To(BeNil()) // By id - output, err = containers.Top(bt.conn, cid, nil) + _, err = containers.Top(bt.conn, cid, nil) Expect(err).To(BeNil()) // With descriptors - output, err = containers.Top(bt.conn, cid, []string{"user,pid,hpid"}) + output, err := containers.Top(bt.conn, cid, []string{"user,pid,hpid"}) Expect(err).To(BeNil()) header := strings.Split(output[0], "\t") for _, d := range []string{"USER", "PID", "HPID"} { diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go index 13b6086c3..dc01a793b 100644 --- a/pkg/bindings/test/images_test.go +++ b/pkg/bindings/test/images_test.go @@ -9,6 +9,7 @@ import ( "github.com/containers/libpod/pkg/bindings" "github.com/containers/libpod/pkg/bindings/containers" "github.com/containers/libpod/pkg/bindings/images" + "github.com/containers/libpod/pkg/domain/entities" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/onsi/gomega/gexec" @@ -353,4 +354,24 @@ var _ = Describe("Podman images", func() { Expect(results).To(ContainElement("docker.io/library/alpine:latest")) }) + // TODO: we really need to extent to pull tests once we have a more sophisticated CI. + It("Image Pull", func() { + rawImage := "docker.io/library/busybox:latest" + + pulledImages, err := images.Pull(bt.conn, rawImage, entities.ImagePullOptions{}) + Expect(err).To(BeNil()) + Expect(len(pulledImages)).To(Equal(1)) + + exists, err := images.Exists(bt.conn, rawImage) + Expect(err).To(BeNil()) + Expect(exists).To(BeTrue()) + + // Make sure the normalization AND the full-transport reference works. + _, err = images.Pull(bt.conn, "docker://"+rawImage, entities.ImagePullOptions{}) + Expect(err).To(BeNil()) + + // The v2 endpoint only supports the docker transport. Let's see if that's really true. + _, err = images.Pull(bt.conn, "bogus-transport:bogus.com/image:reference", entities.ImagePullOptions{}) + Expect(err).To(Not(BeNil())) + }) }) diff --git a/pkg/bindings/test/pods_test.go b/pkg/bindings/test/pods_test.go index 0f786e341..2599ec7ef 100644 --- a/pkg/bindings/test/pods_test.go +++ b/pkg/bindings/test/pods_test.go @@ -2,6 +2,7 @@ package test_bindings import ( "net/http" + "strings" "time" "github.com/containers/libpod/libpod/define" @@ -319,4 +320,33 @@ var _ = Describe("Podman pods", func() { Expect(err).To(BeNil()) Expect(exists).To(BeTrue()) }) + + // Test validates the pod top bindings + It("pod top", func() { + var name string = "podA" + + bt.Podcreate(&name) + _, err := pods.Start(bt.conn, name) + Expect(err).To(BeNil()) + + // By name + _, err = pods.Top(bt.conn, name, nil) + Expect(err).To(BeNil()) + + // With descriptors + output, err := pods.Top(bt.conn, name, []string{"user,pid,hpid"}) + Expect(err).To(BeNil()) + header := strings.Split(output[0], "\t") + for _, d := range []string{"USER", "PID", "HPID"} { + Expect(d).To(BeElementOf(header)) + } + + // With bogus ID + _, err = pods.Top(bt.conn, "IdoNotExist", nil) + Expect(err).ToNot(BeNil()) + + // With bogus descriptors + _, err = pods.Top(bt.conn, name, []string{"Me,Neither"}) + Expect(err).ToNot(BeNil()) + }) }) diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go index 2ab566238..77043b89e 100644 --- a/pkg/domain/entities/engine_container.go +++ b/pkg/domain/entities/engine_container.go @@ -27,6 +27,7 @@ type ContainerEngine interface { PodStop(ctx context.Context, namesOrIds []string, options PodStopOptions) ([]*PodStopReport, error) PodRm(ctx context.Context, namesOrIds []string, options PodRmOptions) ([]*PodRmReport, error) PodUnpause(ctx context.Context, namesOrIds []string, options PodunpauseOptions) ([]*PodUnpauseReport, error) + PodTop(ctx context.Context, options PodTopOptions) (*StringSliceReport, error) VolumeCreate(ctx context.Context, opts VolumeCreateOptions) (*IdOrNameResponse, error) VolumeInspect(ctx context.Context, namesOrIds []string, opts VolumeInspectOptions) ([]*VolumeInspectReport, error) diff --git a/pkg/domain/entities/engine_image.go b/pkg/domain/entities/engine_image.go index d0c860a04..cdb8d7f0d 100644 --- a/pkg/domain/entities/engine_image.go +++ b/pkg/domain/entities/engine_image.go @@ -10,4 +10,5 @@ type ImageEngine interface { History(ctx context.Context, nameOrId string, opts ImageHistoryOptions) (*ImageHistoryReport, error) List(ctx context.Context, opts ImageListOptions) ([]*ImageSummary, error) Prune(ctx context.Context, opts ImagePruneOptions) (*ImagePruneReport, error) + Pull(ctx context.Context, rawImage string, opts ImagePullOptions) (*ImagePullReport, error) } diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go index 20af0356f..8e3f49be3 100644 --- a/pkg/domain/entities/images.go +++ b/pkg/domain/entities/images.go @@ -4,6 +4,7 @@ import ( "net/url" "github.com/containers/image/v5/manifest" + "github.com/containers/image/v5/types" docker "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/opencontainers/go-digest" @@ -117,6 +118,39 @@ type ImageInspectOptions struct { Latest bool `json:",omitempty"` } +// ImagePullOptions are the arguments for pulling images. +type ImagePullOptions struct { + // AllTags can be specified to pull all tags of the spiecifed image. Note + // that this only works if the specified image does not include a tag. + AllTags bool + // Authfile is the path to the authentication file. Ignored for remote + // calls. + Authfile string + // CertDir is the path to certificate directories. Ignored for remote + // calls. + CertDir string + // Credentials for authenticating against the registry in the format + // USERNAME:PASSWORD. + Credentials string + // OverrideArch will overwrite the local architecture for image pulls. + OverrideArch string + // OverrideOS will overwrite the local operating system (OS) for image + // pulls. + OverrideOS string + // Quiet can be specified to suppress pull progress when pulling. Ignored + // for remote calls. + Quiet bool + // SignaturePolicy to use when pulling. Ignored for remote calls. + SignaturePolicy string + // TLSVerify to enable/disable HTTPS and certificate verification. + TLSVerify types.OptionalBool +} + +// ImagePullReport is the response from pulling one or more images. +type ImagePullReport struct { + Images []string +} + type ImageListOptions struct { All bool `json:"all" schema:"all"` Filter []string `json:"Filter,omitempty"` diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go index efda17d65..d92d1bc7a 100644 --- a/pkg/domain/entities/pods.go +++ b/pkg/domain/entities/pods.go @@ -141,3 +141,13 @@ func (p PodCreateOptions) ToPodSpecGen(s *specgen.PodSpecGenerator) { // Cgroup s.CgroupParent = p.CGroupParent } + +type PodTopOptions struct { + // CLI flags. + ListDescriptors bool + Latest bool + + // Options for the API. + Descriptors []string + NameOrID string +} diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 44420c1e1..ef2879246 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -5,11 +5,22 @@ package abi import ( "context" "fmt" + "io" + "os" + "strings" + "github.com/containers/image/v5/docker" + dockerarchive "github.com/containers/image/v5/docker/archive" + "github.com/containers/image/v5/docker/reference" + "github.com/containers/image/v5/transports/alltransports" + "github.com/containers/image/v5/types" + "github.com/containers/libpod/libpod/image" libpodImage "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/domain/entities" + "github.com/containers/libpod/pkg/util" "github.com/containers/storage" "github.com/pkg/errors" + "github.com/sirupsen/logrus" ) func (ir *ImageEngine) Exists(_ context.Context, nameOrId string) (*entities.BoolReport, error) { @@ -134,6 +145,95 @@ func ToDomainHistoryLayer(layer *libpodImage.History) entities.ImageHistoryLayer return l } +func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entities.ImagePullOptions) (*entities.ImagePullReport, error) { + var writer io.Writer + if !options.Quiet { + writer = os.Stderr + } + + dockerPrefix := fmt.Sprintf("%s://", docker.Transport.Name()) + imageRef, err := alltransports.ParseImageName(rawImage) + if err != nil { + imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, rawImage)) + if err != nil { + return nil, errors.Errorf("invalid image reference %q", rawImage) + } + } + + // Special-case for docker-archive which allows multiple tags. + if imageRef.Transport().Name() == dockerarchive.Transport.Name() { + newImage, err := ir.Libpod.ImageRuntime().LoadFromArchiveReference(ctx, imageRef, options.SignaturePolicy, writer) + if err != nil { + return nil, errors.Wrapf(err, "error pulling image %q", rawImage) + } + return &entities.ImagePullReport{Images: []string{newImage[0].ID()}}, nil + } + + var registryCreds *types.DockerAuthConfig + if options.Credentials != "" { + creds, err := util.ParseRegistryCreds(options.Credentials) + if err != nil { + return nil, err + } + registryCreds = creds + } + dockerRegistryOptions := image.DockerRegistryOptions{ + DockerRegistryCreds: registryCreds, + DockerCertPath: options.CertDir, + OSChoice: options.OverrideOS, + ArchitectureChoice: options.OverrideArch, + DockerInsecureSkipTLSVerify: options.TLSVerify, + } + + if !options.AllTags { + newImage, err := ir.Libpod.ImageRuntime().New(ctx, rawImage, options.SignaturePolicy, options.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, nil, util.PullImageAlways) + if err != nil { + return nil, errors.Wrapf(err, "error pulling image %q", rawImage) + } + return &entities.ImagePullReport{Images: []string{newImage.ID()}}, nil + } + + // --all-tags requires the docker transport + if imageRef.Transport().Name() != docker.Transport.Name() { + return nil, errors.New("--all-tags requires docker transport") + } + + // Trim the docker-transport prefix. + rawImage = strings.TrimPrefix(rawImage, docker.Transport.Name()) + + // all-tags doesn't work with a tagged reference, so let's check early + namedRef, err := reference.Parse(rawImage) + if err != nil { + return nil, errors.Wrapf(err, "error parsing %q", rawImage) + } + if _, isTagged := namedRef.(reference.Tagged); isTagged { + return nil, errors.New("--all-tags requires a reference without a tag") + + } + + systemContext := image.GetSystemContext("", options.Authfile, false) + tags, err := docker.GetRepositoryTags(ctx, systemContext, imageRef) + if err != nil { + return nil, errors.Wrapf(err, "error getting repository tags") + } + + var foundIDs []string + for _, tag := range tags { + name := rawImage + ":" + tag + newImage, err := ir.Libpod.ImageRuntime().New(ctx, name, options.SignaturePolicy, options.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, nil, util.PullImageAlways) + if err != nil { + logrus.Errorf("error pulling image %q", name) + continue + } + foundIDs = append(foundIDs, newImage.ID()) + } + + if len(tags) != len(foundIDs) { + return nil, errors.Errorf("error pulling image %q", rawImage) + } + return &entities.ImagePullReport{Images: foundIDs}, nil +} + // func (r *imageRuntime) Delete(ctx context.Context, nameOrId string, opts entities.ImageDeleteOptions) (*entities.ImageDeleteReport, error) { // image, err := r.libpod.ImageEngine().NewFromLocal(nameOrId) // if err != nil { diff --git a/pkg/domain/infra/abi/pods.go b/pkg/domain/infra/abi/pods.go index 619e973cf..8abcc6e4b 100644 --- a/pkg/domain/infra/abi/pods.go +++ b/pkg/domain/infra/abi/pods.go @@ -250,3 +250,25 @@ func (ic *ContainerEngine) PodCreate(ctx context.Context, opts entities.PodCreat } return &entities.PodCreateReport{Id: pod.ID()}, nil } + +func (ic *ContainerEngine) PodTop(ctx context.Context, options entities.PodTopOptions) (*entities.StringSliceReport, error) { + var ( + pod *libpod.Pod + err error + ) + + // Look up the pod. + if options.Latest { + pod, err = ic.Libpod.GetLatestPod() + } else { + pod, err = ic.Libpod.LookupPod(options.NameOrID) + } + if err != nil { + return nil, errors.Wrap(err, "unable to lookup requested container") + } + + // Run Top. + report := &entities.StringSliceReport{} + report.Value, err = pod.GetPodPidInformation(options.Descriptors) + return report, err +} diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index 6a3adc9ee..7638d908a 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -85,3 +85,11 @@ func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOption } return &report, nil } + +func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entities.ImagePullOptions) (*entities.ImagePullReport, error) { + pulledImages, err := images.Pull(ir.ClientCxt, rawImage, options) + if err != nil { + return nil, err + } + return &entities.ImagePullReport{Images: pulledImages}, nil +} diff --git a/pkg/domain/infra/tunnel/pods.go b/pkg/domain/infra/tunnel/pods.go index 4894874e5..9561a9807 100644 --- a/pkg/domain/infra/tunnel/pods.go +++ b/pkg/domain/infra/tunnel/pods.go @@ -6,6 +6,7 @@ import ( "github.com/containers/libpod/pkg/bindings/pods" "github.com/containers/libpod/pkg/domain/entities" "github.com/containers/libpod/pkg/specgen" + "github.com/pkg/errors" ) func (ic *ContainerEngine) PodExists(ctx context.Context, nameOrId string) (*entities.BoolReport, error) { @@ -177,3 +178,18 @@ func (ic *ContainerEngine) PodCreate(ctx context.Context, opts entities.PodCreat opts.ToPodSpecGen(podSpec) return pods.CreatePodFromSpec(ic.ClientCxt, podSpec) } + +func (ic *ContainerEngine) PodTop(ctx context.Context, options entities.PodTopOptions) (*entities.StringSliceReport, error) { + switch { + case options.Latest: + return nil, errors.New("latest is not supported") + case options.NameOrID == "": + return nil, errors.New("NameOrID must be specified") + } + + topOutput, err := pods.Top(ic.ClientCxt, options.NameOrID, options.Descriptors) + if err != nil { + return nil, err + } + return &entities.StringSliceReport{Value: topOutput}, nil +} diff --git a/pkg/systemd/generate/systemdgen.go b/pkg/systemd/generate/systemdgen.go index eb15d4927..73fe52c0e 100644 --- a/pkg/systemd/generate/systemdgen.go +++ b/pkg/systemd/generate/systemdgen.go @@ -31,7 +31,7 @@ type ContainerInfo struct { InfraContainer string // StopTimeout sets the timeout Podman waits before killing the container // during service stop. - StopTimeout int + StopTimeout uint // RestartPolicy of the systemd unit (e.g., no, on-failure, always). RestartPolicy string // PIDFile of the service. Required for forking services. Must point to the diff --git a/pkg/varlink/generate.go b/pkg/varlink/generate.go new file mode 100644 index 000000000..b3f58d4a5 --- /dev/null +++ b/pkg/varlink/generate.go @@ -0,0 +1,3 @@ +package iopodman + +//go:generate go run ../../vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/main.go io.podman.varlink diff --git a/pkg/varlink/io.podman.varlink b/pkg/varlink/io.podman.varlink new file mode 100644 index 000000000..0cb95ef97 --- /dev/null +++ b/pkg/varlink/io.podman.varlink @@ -0,0 +1,1398 @@ +# Podman Service Interface and API description. The master version of this document can be found +# in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in the upstream libpod repository. +interface io.podman + +type Volume ( + name: string, + labels: [string]string, + mountPoint: string, + driver: string, + options: [string]string +) + +type NotImplemented ( + comment: string +) + +type StringResponse ( + message: string +) + +type RemoveImageResponse ( + untagged: []string, + deleted: string +) + +type LogLine ( + device: string, + parseLogType : string, + time: string, + msg: string, + cid: string +) + +# ContainerChanges describes the return struct for ListContainerChanges +type ContainerChanges ( + changed: []string, + added: []string, + deleted: []string +) + +type ImageSaveOptions ( + name: string, + format: string, + output: string, + outputType: string, + moreTags: []string, + quiet: bool, + compress: bool +) + +type VolumeCreateOpts ( + volumeName: string, + driver: string, + labels: [string]string, + options: [string]string +) + +type VolumeRemoveOpts ( + volumes: []string, + all: bool, + force: bool +) + +type Image ( + id: string, + digest: string, + digests: []string, + parentId: string, + repoTags: []string, + repoDigests: []string, + created: string, # as RFC3339 + size: int, + virtualSize: int, + containers: int, + labels: [string]string, + isParent: bool, + topLayer: string, + readOnly: bool, + history: []string +) + +# ImageHistory describes the returned structure from ImageHistory. +type ImageHistory ( + id: string, + created: string, # as RFC3339 + createdBy: string, + tags: []string, + size: int, + comment: string +) + +# Represents a single search result from SearchImages +type ImageSearchResult ( + description: string, + is_official: bool, + is_automated: bool, + registry: string, + name: string, + star_count: int +) + +type ImageSearchFilter ( + is_official: ?bool, + is_automated: ?bool, + star_count: int +) + +type AuthConfig ( + username: string, + password: string +) + +type KubePodService ( + pod: string, + service: string +) + +type Container ( + id: string, + image: string, + imageid: string, + command: []string, + createdat: string, # as RFC3339 + runningfor: string, + status: string, + ports: []ContainerPortMappings, + rootfssize: int, + rwsize: int, + names: string, + labels: [string]string, + mounts: []ContainerMount, + containerrunning: bool, + namespaces: ContainerNameSpace +) + +# ContainerStats is the return struct for the stats of a container +type ContainerStats ( + id: string, + name: string, + cpu: float, + cpu_nano: int, + system_nano: int, + mem_usage: int, + mem_limit: int, + mem_perc: float, + net_input: int, + net_output: int, + block_output: int, + block_input: int, + pids: int +) + +type PsOpts ( + all: bool, + filters: ?[]string, + last: ?int, + latest: ?bool, + noTrunc: ?bool, + pod: ?bool, + quiet: ?bool, + size: ?bool, + sort: ?string, + sync: ?bool +) + +type PsContainer ( + id: string, + image: string, + command: string, + created: string, + ports: string, + names: string, + isInfra: bool, + status: string, + state: string, + pidNum: int, + rootFsSize: int, + rwSize: int, + pod: string, + createdAt: string, + exitedAt: string, + startedAt: string, + labels: [string]string, + nsPid: string, + cgroup: string, + ipc: string, + mnt: string, + net: string, + pidNs: string, + user: string, + uts: string, + mounts: string +) + +# ContainerMount describes the struct for mounts in a container +type ContainerMount ( + destination: string, + type: string, + source: string, + options: []string +) + +# ContainerPortMappings describes the struct for portmappings in an existing container +type ContainerPortMappings ( + host_port: string, + host_ip: string, + protocol: string, + container_port: string +) + +# ContainerNamespace describes the namespace structure for an existing container +type ContainerNameSpace ( + user: string, + uts: string, + pidns: string, + pid: string, + cgroup: string, + net: string, + mnt: string, + ipc: string +) + +# InfoDistribution describes the host's distribution +type InfoDistribution ( + distribution: string, + version: string +) + +# InfoHost describes the host stats portion of PodmanInfo +type InfoHost ( + buildah_version: string, + distribution: InfoDistribution, + mem_free: int, + mem_total: int, + swap_free: int, + swap_total: int, + arch: string, + cpus: int, + hostname: string, + kernel: string, + os: string, + uptime: string, + eventlogger: string +) + +# InfoGraphStatus describes the detailed status of the storage driver +type InfoGraphStatus ( + backing_filesystem: string, + native_overlay_diff: string, + supports_d_type: string +) + +# InfoRegistry describes the host's registry information +type InfoRegistry ( + search: []string, + insecure: []string, + blocked: []string +) + +# InfoStore describes the host's storage informatoin +type InfoStore ( + containers: int, + images: int, + graph_driver_name: string, + graph_driver_options: string, + graph_root: string, + graph_status: InfoGraphStatus, + run_root: string +) + +# InfoPodman provides details on the Podman binary +type InfoPodmanBinary ( + compiler: string, + go_version: string, + podman_version: string, + git_commit: string +) + +# PodmanInfo describes the Podman host and build +type PodmanInfo ( + host: InfoHost, + registries: InfoRegistry, + store: InfoStore, + podman: InfoPodmanBinary +) + +# Sockets describes sockets location for a container +type Sockets( + container_id: string, + io_socket: string, + control_socket: string +) + +# Create is an input structure for creating containers. +# args[0] is the image name or id +# args[1-] are the new commands if changed +type Create ( + args: []string, + addHost: ?[]string, + annotation: ?[]string, + attach: ?[]string, + blkioWeight: ?string, + blkioWeightDevice: ?[]string, + capAdd: ?[]string, + capDrop: ?[]string, + cgroupParent: ?string, + cidFile: ?string, + conmonPidfile: ?string, + command: ?[]string, + cpuPeriod: ?int, + cpuQuota: ?int, + cpuRtPeriod: ?int, + cpuRtRuntime: ?int, + cpuShares: ?int, + cpus: ?float, + cpuSetCpus: ?string, + cpuSetMems: ?string, + detach: ?bool, + detachKeys: ?string, + device: ?[]string, + deviceReadBps: ?[]string, + deviceReadIops: ?[]string, + deviceWriteBps: ?[]string, + deviceWriteIops: ?[]string, + dns: ?[]string, + dnsOpt: ?[]string, + dnsSearch: ?[]string, + dnsServers: ?[]string, + entrypoint: ?string, + env: ?[]string, + envFile: ?[]string, + expose: ?[]string, + gidmap: ?[]string, + groupadd: ?[]string, + healthcheckCommand: ?string, + healthcheckInterval: ?string, + healthcheckRetries: ?int, + healthcheckStartPeriod: ?string, + healthcheckTimeout:?string, + hostname: ?string, + imageVolume: ?string, + init: ?bool, + initPath: ?string, + interactive: ?bool, + ip: ?string, + ipc: ?string, + kernelMemory: ?string, + label: ?[]string, + labelFile: ?[]string, + logDriver: ?string, + logOpt: ?[]string, + macAddress: ?string, + memory: ?string, + memoryReservation: ?string, + memorySwap: ?string, + memorySwappiness: ?int, + name: ?string, + network: ?string, + noHosts: ?bool, + oomKillDisable: ?bool, + oomScoreAdj: ?int, + overrideArch: ?string, + overrideOS: ?string, + pid: ?string, + pidsLimit: ?int, + pod: ?string, + privileged: ?bool, + publish: ?[]string, + publishAll: ?bool, + pull: ?string, + quiet: ?bool, + readonly: ?bool, + readonlytmpfs: ?bool, + restart: ?string, + rm: ?bool, + rootfs: ?bool, + securityOpt: ?[]string, + shmSize: ?string, + stopSignal: ?string, + stopTimeout: ?int, + storageOpt: ?[]string, + subuidname: ?string, + subgidname: ?string, + sysctl: ?[]string, + systemd: ?string, + tmpfs: ?[]string, + tty: ?bool, + uidmap: ?[]string, + ulimit: ?[]string, + user: ?string, + userns: ?string, + uts: ?string, + mount: ?[]string, + volume: ?[]string, + volumesFrom: ?[]string, + workDir: ?string +) + +# BuildOptions are are used to describe describe physical attributes of the build +type BuildOptions ( + addHosts: []string, + cgroupParent: string, + cpuPeriod: int, + cpuQuota: int, + cpuShares: int, + cpusetCpus: string, + cpusetMems: string, + memory: int, + memorySwap: int, + shmSize: string, + ulimit: []string, + volume: []string +) + +# BuildInfo is used to describe user input for building images +type BuildInfo ( + architecture: string, + addCapabilities: []string, + additionalTags: []string, + annotations: []string, + buildArgs: [string]string, + buildOptions: BuildOptions, + cniConfigDir: string, + cniPluginDir: string, + compression: string, + contextDir: string, + defaultsMountFilePath: string, + devices: []string, + dockerfiles: []string, + dropCapabilities: []string, + err: string, + forceRmIntermediateCtrs: bool, + iidfile: string, + label: []string, + layers: bool, + nocache: bool, + os: string, + out: string, + output: string, + outputFormat: string, + pullPolicy: string, + quiet: bool, + remoteIntermediateCtrs: bool, + reportWriter: string, + runtimeArgs: []string, + signBy: string, + squash: bool, + target: string, + transientMounts: []string +) + +# MoreResponse is a struct for when responses from varlink requires longer output +type MoreResponse ( + logs: []string, + id: string +) + +# ListPodContainerInfo is a returned struct for describing containers +# in a pod. +type ListPodContainerInfo ( + name: string, + id: string, + status: string +) + +# PodCreate is an input structure for creating pods. +# It emulates options to podman pod create. The infraCommand and +# infraImage options are currently NotSupported. +type PodCreate ( + name: string, + cgroupParent: string, + labels: [string]string, + share: []string, + infra: bool, + infraCommand: string, + infraImage: string, + publish: []string +) + +# ListPodData is the returned struct for an individual pod +type ListPodData ( + id: string, + name: string, + createdat: string, + cgroup: string, + status: string, + labels: [string]string, + numberofcontainers: string, + containersinfo: []ListPodContainerInfo +) + +type PodContainerErrorData ( + containerid: string, + reason: string +) + +# Runlabel describes the required input for container runlabel +type Runlabel( + image: string, + authfile: string, + display: bool, + name: string, + pull: bool, + label: string, + extraArgs: []string, + opts: [string]string +) + +# Event describes a libpod struct +type Event( + # TODO: make status and type a enum at some point? + # id is the container, volume, pod, image ID + id: string, + # image is the image name where applicable + image: string, + # name is the name of the pod, container, image + name: string, + # status describes the event that happened (i.e. create, remove, ...) + status: string, + # time the event happened + time: string, + # type describes object the event happened with (image, container...) + type: string +) + +type DiffInfo( + # path that is different + path: string, + # Add, Delete, Modify + changeType: string +) + +type ExecOpts( + # container name or id + name: string, + # Create pseudo tty + tty: bool, + # privileged access in container + privileged: bool, + # command to execute in container + cmd: []string, + # user to use in container + user: ?string, + # workdir to run command in container + workdir: ?string, + # slice of keyword=value environment variables + env: ?[]string, + # string of detach keys + detachKeys: ?string +) + +# GetVersion returns version and build information of the podman service +method GetVersion() -> ( + version: string, + go_version: string, + git_commit: string, + built: string, # as RFC3339 + os_arch: string, + remote_api_version: int +) + +# Reset resets Podman back to its initial state. +# Removes all Pods, Containers, Images and Volumes +method Reset() -> () + +# GetInfo returns a [PodmanInfo](#PodmanInfo) struct that describes podman and its host such as storage stats, +# build information of Podman, and system-wide registries. +method GetInfo() -> (info: PodmanInfo) + +# ListContainers returns information about all containers. +# See also [GetContainer](#GetContainer). +method ListContainers() -> (containers: []Container) + +method Ps(opts: PsOpts) -> (containers: []PsContainer) + +method GetContainersByStatus(status: []string) -> (containerS: []Container) + +method Top (nameOrID: string, descriptors: []string) -> (top: []string) + +# HealthCheckRun executes defined container's healthcheck command +# and returns the container's health status. +method HealthCheckRun (nameOrID: string) -> (healthCheckStatus: string) + +# GetContainer returns information about a single container. If a container +# with the given id doesn't exist, a [ContainerNotFound](#ContainerNotFound) +# error will be returned. See also [ListContainers](ListContainers) and +# [InspectContainer](#InspectContainer). +method GetContainer(id: string) -> (container: Container) + +# GetContainersByContext allows you to get a list of container ids depending on all, latest, or a list of +# container names. The definition of latest container means the latest by creation date. In a multi- +# user environment, results might differ from what you expect. +method GetContainersByContext(all: bool, latest: bool, args: []string) -> (containers: []string) + +# CreateContainer creates a new container from an image. It uses a [Create](#Create) type for input. +method CreateContainer(create: Create) -> (container: string) + +# InspectContainer data takes a name or ID of a container returns the inspection +# data in string format. You can then serialize the string into JSON. A [ContainerNotFound](#ContainerNotFound) +# error will be returned if the container cannot be found. See also [InspectImage](#InspectImage). +method InspectContainer(name: string) -> (container: string) + +# ListContainerProcesses takes a name or ID of a container and returns the processes +# running inside the container as array of strings. It will accept an array of string +# arguments that represent ps options. If the container cannot be found, a [ContainerNotFound](#ContainerNotFound) +# error will be returned. +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.ListContainerProcesses '{"name": "135d71b9495f", "opts": []}' +# { +# "container": [ +# " UID PID PPID C STIME TTY TIME CMD", +# " 0 21220 21210 0 09:05 pts/0 00:00:00 /bin/sh", +# " 0 21232 21220 0 09:05 pts/0 00:00:00 top", +# " 0 21284 21220 0 09:05 pts/0 00:00:00 vi /etc/hosts" +# ] +# } +# ~~~ +method ListContainerProcesses(name: string, opts: []string) -> (container: []string) + +# GetContainerLogs takes a name or ID of a container and returns the logs of that container. +# If the container cannot be found, a [ContainerNotFound](#ContainerNotFound) error will be returned. +# The container logs are returned as an array of strings. GetContainerLogs will honor the streaming +# capability of varlink if the client invokes it. +method GetContainerLogs(name: string) -> (container: []string) + +method GetContainersLogs(names: []string, follow: bool, latest: bool, since: string, tail: int, timestamps: bool) -> (log: LogLine) + +# ListContainerChanges takes a name or ID of a container and returns changes between the container and +# its base image. It returns a struct of changed, deleted, and added path names. +method ListContainerChanges(name: string) -> (container: ContainerChanges) + +# ExportContainer creates an image from a container. It takes the name or ID of a container and a +# path representing the target tarfile. If the container cannot be found, a [ContainerNotFound](#ContainerNotFound) +# error will be returned. +# The return value is the written tarfile. +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.ExportContainer '{"name": "flamboyant_payne", "path": "/tmp/payne.tar" }' +# { +# "tarfile": "/tmp/payne.tar" +# } +# ~~~ +method ExportContainer(name: string, path: string) -> (tarfile: string) + +# GetContainerStats takes the name or ID of a container and returns a single ContainerStats structure which +# contains attributes like memory and cpu usage. If the container cannot be found, a +# [ContainerNotFound](#ContainerNotFound) error will be returned. If the container is not running, a [NoContainerRunning](#NoContainerRunning) +# error will be returned +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.GetContainerStats '{"name": "c33e4164f384"}' +# { +# "container": { +# "block_input": 0, +# "block_output": 0, +# "cpu": 2.571123918839990154678e-08, +# "cpu_nano": 49037378, +# "id": "c33e4164f384aa9d979072a63319d66b74fd7a128be71fa68ede24f33ec6cfee", +# "mem_limit": 33080606720, +# "mem_perc": 2.166828456524753747370e-03, +# "mem_usage": 716800, +# "name": "competent_wozniak", +# "net_input": 768, +# "net_output": 5910, +# "pids": 1, +# "system_nano": 10000000 +# } +# } +# ~~~ +method GetContainerStats(name: string) -> (container: ContainerStats) + +# GetContainerStatsWithHistory takes a previous set of container statistics and uses libpod functions +# to calculate the containers statistics based on current and previous measurements. +method GetContainerStatsWithHistory(previousStats: ContainerStats) -> (container: ContainerStats) + +# This method has not be implemented yet. +# method ResizeContainerTty() -> (notimplemented: NotImplemented) + +# StartContainer starts a created or stopped container. It takes the name or ID of container. It returns +# the container ID once started. If the container cannot be found, a [ContainerNotFound](#ContainerNotFound) +# error will be returned. See also [CreateContainer](#CreateContainer). +method StartContainer(name: string) -> (container: string) + +# StopContainer stops a container given a timeout. It takes the name or ID of a container as well as a +# timeout value. The timeout value the time before a forcible stop to the container is applied. It +# returns the container ID once stopped. If the container cannot be found, a [ContainerNotFound](#ContainerNotFound) +# error will be returned instead. See also [KillContainer](KillContainer). +# #### Error +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.StopContainer '{"name": "135d71b9495f", "timeout": 5}' +# { +# "container": "135d71b9495f7c3967f536edad57750bfdb569336cd107d8aabab45565ffcfb6" +# } +# ~~~ +method StopContainer(name: string, timeout: int) -> (container: string) + +# InitContainer initializes the given container. It accepts a container name or +# ID, and will initialize the container matching that ID if possible, and error +# if not. Containers can only be initialized when they are in the Created or +# Exited states. Initialization prepares a container to be started, but does not +# start the container. It is intended to be used to debug a container's state +# prior to starting it. +method InitContainer(name: string) -> (container: string) + +# RestartContainer will restart a running container given a container name or ID and timeout value. The timeout +# value is the time before a forcible stop is used to stop the container. If the container cannot be found by +# name or ID, a [ContainerNotFound](#ContainerNotFound) error will be returned; otherwise, the ID of the +# container will be returned. +method RestartContainer(name: string, timeout: int) -> (container: string) + +# KillContainer takes the name or ID of a container as well as a signal to be applied to the container. Once the +# container has been killed, the container's ID is returned. If the container cannot be found, a +# [ContainerNotFound](#ContainerNotFound) error is returned. See also [StopContainer](StopContainer). +method KillContainer(name: string, signal: int) -> (container: string) + +# This method has not be implemented yet. +# method UpdateContainer() -> (notimplemented: NotImplemented) + +# This method has not be implemented yet. +# method RenameContainer() -> (notimplemented: NotImplemented) + +# PauseContainer takes the name or ID of container and pauses it. If the container cannot be found, +# a [ContainerNotFound](#ContainerNotFound) error will be returned; otherwise the ID of the container is returned. +# See also [UnpauseContainer](#UnpauseContainer). +method PauseContainer(name: string) -> (container: string) + +# UnpauseContainer takes the name or ID of container and unpauses a paused container. If the container cannot be +# found, a [ContainerNotFound](#ContainerNotFound) error will be returned; otherwise the ID of the container is returned. +# See also [PauseContainer](#PauseContainer). +method UnpauseContainer(name: string) -> (container: string) + +# Attach takes the name or ID of a container and sets up the ability to remotely attach to its console. The start +# bool is whether you wish to start the container in question first. +method Attach(name: string, detachKeys: string, start: bool) -> () + +method AttachControl(name: string) -> () + +# GetAttachSockets takes the name or ID of an existing container. It returns file paths for two sockets needed +# to properly communicate with a container. The first is the actual I/O socket that the container uses. The +# second is a "control" socket where things like resizing the TTY events are sent. If the container cannot be +# found, a [ContainerNotFound](#ContainerNotFound) error will be returned. +# #### Example +# ~~~ +# $ varlink call -m unix:/run/io.podman/io.podman.GetAttachSockets '{"name": "b7624e775431219161"}' +# { +# "sockets": { +# "container_id": "b7624e7754312191613245ce1a46844abee60025818fe3c3f3203435623a1eca", +# "control_socket": "/var/lib/containers/storage/overlay-containers/b7624e7754312191613245ce1a46844abee60025818fe3c3f3203435623a1eca/userdata/ctl", +# "io_socket": "/var/run/libpod/socket/b7624e7754312191613245ce1a46844abee60025818fe3c3f3203435623a1eca/attach" +# } +# } +# ~~~ +method GetAttachSockets(name: string) -> (sockets: Sockets) + +# WaitContainer takes the name or ID of a container and waits the given interval in milliseconds until the container +# stops. Upon stopping, the return code of the container is returned. If the container container cannot be found by ID +# or name, a [ContainerNotFound](#ContainerNotFound) error is returned. +method WaitContainer(name: string, interval: int) -> (exitcode: int) + +# RemoveContainer requires the name or ID of a container as well as a boolean that +# indicates whether a container should be forcefully removed (e.g., by stopping it), and a boolean +# indicating whether to remove builtin volumes. Upon successful removal of the +# container, its ID is returned. If the +# container cannot be found by name or ID, a [ContainerNotFound](#ContainerNotFound) error will be returned. +# See also [EvictContainer](EvictContainer). +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.RemoveContainer '{"name": "62f4fd98cb57"}' +# { +# "container": "62f4fd98cb57f529831e8f90610e54bba74bd6f02920ffb485e15376ed365c20" +# } +# ~~~ +method RemoveContainer(name: string, force: bool, removeVolumes: bool) -> (container: string) + +# EvictContainer requires the name or ID of a container as well as a boolean that +# indicates to remove builtin volumes. Upon successful eviction of the container, +# its ID is returned. If the container cannot be found by name or ID, +# a [ContainerNotFound](#ContainerNotFound) error will be returned. +# See also [RemoveContainer](RemoveContainer). +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.EvictContainer '{"name": "62f4fd98cb57"}' +# { +# "container": "62f4fd98cb57f529831e8f90610e54bba74bd6f02920ffb485e15376ed365c20" +# } +# ~~~ +method EvictContainer(name: string, removeVolumes: bool) -> (container: string) + +# DeleteStoppedContainers will delete all containers that are not running. It will return a list the deleted +# container IDs. See also [RemoveContainer](RemoveContainer). +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.DeleteStoppedContainers +# { +# "containers": [ +# "451410b931d00def8aa9b4f8084e4d4a39e5e04ea61f358cf53a5cf95afcdcee", +# "8b60f754a3e01389494a9581ade97d35c2765b6e2f19acd2d3040c82a32d1bc0", +# "cf2e99d4d3cad6073df199ed32bbe64b124f3e1aba6d78821aa8460e70d30084", +# "db901a329587312366e5ecff583d08f0875b4b79294322df67d90fc6eed08fc1" +# ] +# } +# ~~~ +method DeleteStoppedContainers() -> (containers: []string) + +# ListImages returns information about the images that are currently in storage. +# See also [InspectImage](#InspectImage). +method ListImages() -> (images: []Image) + +# ListImagesWithFilters returns information about the images that are currently in storage +# after one or more filters has been applied. +# See also [InspectImage](#InspectImage). +method ListImagesWithFilters(filters: []string) -> (images: []Image) + +# GetImage returns information about a single image in storage. +# If the image caGetImage returns be found, [ImageNotFound](#ImageNotFound) will be returned. +method GetImage(id: string) -> (image: Image) + +# BuildImage takes a [BuildInfo](#BuildInfo) structure and builds an image. At a minimum, you must provide the +# contextDir tarball path, the 'dockerfiles' path, and 'output' option in the BuildInfo structure. The 'output' +# options is the name of the of the resulting build. It will return a [MoreResponse](#MoreResponse) structure +# that contains the build logs and resulting image ID. +# #### Example +# ~~~ +# $ sudo varlink call -m unix:///run/podman/io.podman/io.podman.BuildImage '{"build":{"contextDir":"/tmp/t/context.tar","dockerfiles":["Dockerfile"], "output":"foobar"}}' +# { +# "image": { +# "id": "", +# "logs": [ +# "STEP 1: FROM alpine\n" +# ] +# } +# } +# { +# "image": { +# "id": "", +# "logs": [ +# "STEP 2: COMMIT foobar\n" +# ] +# } +# } +# { +# "image": { +# "id": "", +# "logs": [ +# "b7b28af77ffec6054d13378df4fdf02725830086c7444d9c278af25312aa39b9\n" +# ] +# } +# } +# { +# "image": { +# "id": "b7b28af77ffec6054d13378df4fdf02725830086c7444d9c278af25312aa39b9", +# "logs": [] +# } +# } +# ~~~ +method BuildImage(build: BuildInfo) -> (image: MoreResponse) + +# This function is not implemented yet. +# method CreateImage() -> (notimplemented: NotImplemented) + +# InspectImage takes the name or ID of an image and returns a string representation of data associated with the +#image. You must serialize the string into JSON to use it further. An [ImageNotFound](#ImageNotFound) error will +# be returned if the image cannot be found. +method InspectImage(name: string) -> (image: string) + +# HistoryImage takes the name or ID of an image and returns information about its history and layers. The returned +# history is in the form of an array of ImageHistory structures. If the image cannot be found, an +# [ImageNotFound](#ImageNotFound) error is returned. +method HistoryImage(name: string) -> (history: []ImageHistory) + +# PushImage takes two input arguments: the name or ID of an image, the fully-qualified destination name of the image, +# It will return an [ImageNotFound](#ImageNotFound) error if +# the image cannot be found in local storage; otherwise it will return a [MoreResponse](#MoreResponse) +method PushImage(name: string, tag: string, compress: bool, format: string, removeSignatures: bool, signBy: string) -> (reply: MoreResponse) + +# TagImage takes the name or ID of an image in local storage as well as the desired tag name. If the image cannot +# be found, an [ImageNotFound](#ImageNotFound) error will be returned; otherwise, the ID of the image is returned on success. +method TagImage(name: string, tagged: string) -> (image: string) + +# UntagImage takes the name or ID of an image in local storage as well as the +# tag name to be removed. If the image cannot be found, an +# [ImageNotFound](#ImageNotFound) error will be returned; otherwise, the ID of +# the image is returned on success. +method UntagImage(name: string, tag: string) -> (image: string) + +# RemoveImage takes the name or ID of an image as well as a boolean that determines if containers using that image +# should be deleted. If the image cannot be found, an [ImageNotFound](#ImageNotFound) error will be returned. The +# ID of the removed image is returned when complete. See also [DeleteUnusedImages](DeleteUnusedImages). +# #### Example +# ~~~ +# varlink call -m unix:/run/podman/io.podman/io.podman.RemoveImage '{"name": "registry.fedoraproject.org/fedora", "force": true}' +# { +# "image": "426866d6fa419873f97e5cbd320eeb22778244c1dfffa01c944db3114f55772e" +# } +# ~~~ +method RemoveImage(name: string, force: bool) -> (image: string) + +# RemoveImageWithResponse takes the name or ID of an image as well as a boolean that determines if containers using that image +# should be deleted. If the image cannot be found, an [ImageNotFound](#ImageNotFound) error will be returned. The response is +# in the form of a RemoveImageResponse . +method RemoveImageWithResponse(name: string, force: bool) -> (response: RemoveImageResponse) + +# SearchImages searches available registries for images that contain the +# contents of "query" in their name. If "limit" is given, limits the amount of +# search results per registry. +method SearchImages(query: string, limit: ?int, filter: ImageSearchFilter) -> (results: []ImageSearchResult) + +# DeleteUnusedImages deletes any images not associated with a container. The IDs of the deleted images are returned +# in a string array. +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.DeleteUnusedImages +# { +# "images": [ +# "166ea6588079559c724c15223f52927f514f73dd5c5cf2ae2d143e3b2e6e9b52", +# "da86e6ba6ca197bf6bc5e9d900febd906b133eaa4750e6bed647b0fbe50ed43e", +# "3ef70f7291f47dfe2b82931a993e16f5a44a0e7a68034c3e0e086d77f5829adc", +# "59788edf1f3e78cd0ebe6ce1446e9d10788225db3dedcfd1a59f764bad2b2690" +# ] +# } +# ~~~ +method DeleteUnusedImages() -> (images: []string) + +# Commit, creates an image from an existing container. It requires the name or +# ID of the container as well as the resulting image name. Optionally, you can define an author and message +# to be added to the resulting image. You can also define changes to the resulting image for the following +# attributes: _CMD, ENTRYPOINT, ENV, EXPOSE, LABEL, ONBUILD, STOPSIGNAL, USER, VOLUME, and WORKDIR_. To pause the +# container while it is being committed, pass a _true_ bool for the pause argument. If the container cannot +# be found by the ID or name provided, a (ContainerNotFound)[#ContainerNotFound] error will be returned; otherwise, +# the resulting image's ID will be returned as a string inside a MoreResponse. +method Commit(name: string, image_name: string, changes: []string, author: string, message: string, pause: bool, manifestType: string) -> (reply: MoreResponse) + +# ImportImage imports an image from a source (like tarball) into local storage. The image can have additional +# descriptions added to it using the message and changes options. See also [ExportImage](ExportImage). +method ImportImage(source: string, reference: string, message: string, changes: []string, delete: bool) -> (image: string) + +# ExportImage takes the name or ID of an image and exports it to a destination like a tarball. There is also +# a boolean option to force compression. It also takes in a string array of tags to be able to save multiple +# tags of the same image to a tarball (each tag should be of the form <image>:<tag>). Upon completion, the ID +# of the image is returned. If the image cannot be found in local storage, an [ImageNotFound](#ImageNotFound) +# error will be returned. See also [ImportImage](ImportImage). +method ExportImage(name: string, destination: string, compress: bool, tags: []string) -> (image: string) + +# PullImage pulls an image from a repository to local storage. After a successful pull, the image id and logs +# are returned as a [MoreResponse](#MoreResponse). This connection also will handle a WantsMores request to send +# status as it occurs. +method PullImage(name: string, creds: AuthConfig) -> (reply: MoreResponse) + +# CreatePod creates a new empty pod. It uses a [PodCreate](#PodCreate) type for input. +# On success, the ID of the newly created pod will be returned. +# #### Example +# ~~~ +# $ varlink call unix:/run/podman/io.podman/io.podman.CreatePod '{"create": {"name": "test"}}' +# { +# "pod": "b05dee7bd4ccfee688099fe1588a7a898d6ddd6897de9251d4671c9b0feacb2a" +# } +# +# $ varlink call unix:/run/podman/io.podman/io.podman.CreatePod '{"create": {"infra": true, "share": ["ipc", "net", "uts"]}}' +# { +# "pod": "d7697449a8035f613c1a8891286502aca68fff7d5d49a85279b3bda229af3b28" +# } +# ~~~ +method CreatePod(create: PodCreate) -> (pod: string) + +# ListPods returns a list of pods in no particular order. They are +# returned as an array of ListPodData structs. See also [GetPod](#GetPod). +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.ListPods +# { +# "pods": [ +# { +# "cgroup": "machine.slice", +# "containersinfo": [ +# { +# "id": "00c130a45de0411f109f1a0cfea2e298df71db20fa939de5cab8b2160a36be45", +# "name": "1840835294cf-infra", +# "status": "running" +# }, +# { +# "id": "49a5cce72093a5ca47c6de86f10ad7bb36391e2d89cef765f807e460865a0ec6", +# "name": "upbeat_murdock", +# "status": "running" +# } +# ], +# "createdat": "2018-12-07 13:10:15.014139258 -0600 CST", +# "id": "1840835294cf076a822e4e12ba4152411f131bd869e7f6a4e8b16df9b0ea5c7f", +# "name": "foobar", +# "numberofcontainers": "2", +# "status": "Running" +# }, +# { +# "cgroup": "machine.slice", +# "containersinfo": [ +# { +# "id": "1ca4b7bbba14a75ba00072d4b705c77f3df87db0109afaa44d50cb37c04a477e", +# "name": "784306f655c6-infra", +# "status": "running" +# } +# ], +# "createdat": "2018-12-07 13:09:57.105112457 -0600 CST", +# "id": "784306f655c6200aea321dd430ba685e9b2cc1f7d7528a72f3ff74ffb29485a2", +# "name": "nostalgic_pike", +# "numberofcontainers": "1", +# "status": "Running" +# } +# ] +# } +# ~~~ +method ListPods() -> (pods: []ListPodData) + +# GetPod takes a name or ID of a pod and returns single [ListPodData](#ListPodData) +# structure. A [PodNotFound](#PodNotFound) error will be returned if the pod cannot be found. +# See also [ListPods](ListPods). +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.GetPod '{"name": "foobar"}' +# { +# "pod": { +# "cgroup": "machine.slice", +# "containersinfo": [ +# { +# "id": "00c130a45de0411f109f1a0cfea2e298df71db20fa939de5cab8b2160a36be45", +# "name": "1840835294cf-infra", +# "status": "running" +# }, +# { +# "id": "49a5cce72093a5ca47c6de86f10ad7bb36391e2d89cef765f807e460865a0ec6", +# "name": "upbeat_murdock", +# "status": "running" +# } +# ], +# "createdat": "2018-12-07 13:10:15.014139258 -0600 CST", +# "id": "1840835294cf076a822e4e12ba4152411f131bd869e7f6a4e8b16df9b0ea5c7f", +# "name": "foobar", +# "numberofcontainers": "2", +# "status": "Running" +# } +# } +# ~~~ +method GetPod(name: string) -> (pod: ListPodData) + +# InspectPod takes the name or ID of an image and returns a string representation of data associated with the +# pod. You must serialize the string into JSON to use it further. A [PodNotFound](#PodNotFound) error will +# be returned if the pod cannot be found. +method InspectPod(name: string) -> (pod: string) + +# StartPod starts containers in a pod. It takes the name or ID of pod. If the pod cannot be found, a [PodNotFound](#PodNotFound) +# error will be returned. Containers in a pod are started independently. If there is an error starting one container, the ID of those containers +# will be returned in a list, along with the ID of the pod in a [PodContainerError](#PodContainerError). +# If the pod was started with no errors, the pod ID is returned. +# See also [CreatePod](#CreatePod). +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.StartPod '{"name": "135d71b9495f"}' +# { +# "pod": "135d71b9495f7c3967f536edad57750bfdb569336cd107d8aabab45565ffcfb6", +# } +# ~~~ +method StartPod(name: string) -> (pod: string) + +# StopPod stops containers in a pod. It takes the name or ID of a pod and a timeout. +# If the pod cannot be found, a [PodNotFound](#PodNotFound) error will be returned instead. +# Containers in a pod are stopped independently. If there is an error stopping one container, the ID of those containers +# will be returned in a list, along with the ID of the pod in a [PodContainerError](#PodContainerError). +# If the pod was stopped with no errors, the pod ID is returned. +# See also [KillPod](KillPod). +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.StopPod '{"name": "135d71b9495f"}' +# { +# "pod": "135d71b9495f7c3967f536edad57750bfdb569336cd107d8aabab45565ffcfb6" +# } +# ~~~ +method StopPod(name: string, timeout: int) -> (pod: string) + +# RestartPod will restart containers in a pod given a pod name or ID. Containers in +# the pod that are running will be stopped, then all stopped containers will be run. +# If the pod cannot be found by name or ID, a [PodNotFound](#PodNotFound) error will be returned. +# Containers in a pod are restarted independently. If there is an error restarting one container, the ID of those containers +# will be returned in a list, along with the ID of the pod in a [PodContainerError](#PodContainerError). +# If the pod was restarted with no errors, the pod ID is returned. +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.RestartPod '{"name": "135d71b9495f"}' +# { +# "pod": "135d71b9495f7c3967f536edad57750bfdb569336cd107d8aabab45565ffcfb6" +# } +# ~~~ +method RestartPod(name: string) -> (pod: string) + +# KillPod takes the name or ID of a pod as well as a signal to be applied to the pod. If the pod cannot be found, a +# [PodNotFound](#PodNotFound) error is returned. +# Containers in a pod are killed independently. If there is an error killing one container, the ID of those containers +# will be returned in a list, along with the ID of the pod in a [PodContainerError](#PodContainerError). +# If the pod was killed with no errors, the pod ID is returned. +# See also [StopPod](StopPod). +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.KillPod '{"name": "foobar", "signal": 15}' +# { +# "pod": "1840835294cf076a822e4e12ba4152411f131bd869e7f6a4e8b16df9b0ea5c7f" +# } +# ~~~ +method KillPod(name: string, signal: int) -> (pod: string) + +# PausePod takes the name or ID of a pod and pauses the running containers associated with it. If the pod cannot be found, +# a [PodNotFound](#PodNotFound) error will be returned. +# Containers in a pod are paused independently. If there is an error pausing one container, the ID of those containers +# will be returned in a list, along with the ID of the pod in a [PodContainerError](#PodContainerError). +# If the pod was paused with no errors, the pod ID is returned. +# See also [UnpausePod](#UnpausePod). +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.PausePod '{"name": "foobar"}' +# { +# "pod": "1840835294cf076a822e4e12ba4152411f131bd869e7f6a4e8b16df9b0ea5c7f" +# } +# ~~~ +method PausePod(name: string) -> (pod: string) + +# UnpausePod takes the name or ID of a pod and unpauses the paused containers associated with it. If the pod cannot be +# found, a [PodNotFound](#PodNotFound) error will be returned. +# Containers in a pod are unpaused independently. If there is an error unpausing one container, the ID of those containers +# will be returned in a list, along with the ID of the pod in a [PodContainerError](#PodContainerError). +# If the pod was unpaused with no errors, the pod ID is returned. +# See also [PausePod](#PausePod). +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.UnpausePod '{"name": "foobar"}' +# { +# "pod": "1840835294cf076a822e4e12ba4152411f131bd869e7f6a4e8b16df9b0ea5c7f" +# } +# ~~~ +method UnpausePod(name: string) -> (pod: string) + +# RemovePod takes the name or ID of a pod as well a boolean representing whether a running +# container in the pod can be stopped and removed. If a pod has containers associated with it, and force is not true, +# an error will occur. +# If the pod cannot be found by name or ID, a [PodNotFound](#PodNotFound) error will be returned. +# Containers in a pod are removed independently. If there is an error removing any container, the ID of those containers +# will be returned in a list, along with the ID of the pod in a [PodContainerError](#PodContainerError). +# If the pod was removed with no errors, the pod ID is returned. +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.RemovePod '{"name": "62f4fd98cb57", "force": "true"}' +# { +# "pod": "62f4fd98cb57f529831e8f90610e54bba74bd6f02920ffb485e15376ed365c20" +# } +# ~~~ +method RemovePod(name: string, force: bool) -> (pod: string) + +# This method has not be implemented yet. +# method WaitPod() -> (notimplemented: NotImplemented) + +method TopPod(pod: string, latest: bool, descriptors: []string) -> (stats: []string) + +# GetPodStats takes the name or ID of a pod and returns a pod name and slice of ContainerStats structure which +# contains attributes like memory and cpu usage. If the pod cannot be found, a [PodNotFound](#PodNotFound) +# error will be returned. If the pod has no running containers associated with it, a [NoContainerRunning](#NoContainerRunning) +# error will be returned. +# #### Example +# ~~~ +# $ varlink call unix:/run/podman/io.podman/io.podman.GetPodStats '{"name": "7f62b508b6f12b11d8fe02e"}' +# { +# "containers": [ +# { +# "block_input": 0, +# "block_output": 0, +# "cpu": 2.833470544016107524276e-08, +# "cpu_nano": 54363072, +# "id": "a64b51f805121fe2c5a3dc5112eb61d6ed139e3d1c99110360d08b58d48e4a93", +# "mem_limit": 12276146176, +# "mem_perc": 7.974359265237864966003e-03, +# "mem_usage": 978944, +# "name": "quirky_heisenberg", +# "net_input": 866, +# "net_output": 7388, +# "pids": 1, +# "system_nano": 20000000 +# } +# ], +# "pod": "7f62b508b6f12b11d8fe02e0db4de6b9e43a7d7699b33a4fc0d574f6e82b4ebd" +# } +# ~~~ +method GetPodStats(name: string) -> (pod: string, containers: []ContainerStats) + +# GetPodsByStatus searches for pods whose status is included in statuses +method GetPodsByStatus(statuses: []string) -> (pods: []string) + +# ImageExists talks a full or partial image ID or name and returns an int as to whether +# the image exists in local storage. An int result of 0 means the image does exist in +# local storage; whereas 1 indicates the image does not exists in local storage. +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.ImageExists '{"name": "imageddoesntexist"}' +# { +# "exists": 1 +# } +# ~~~ +method ImageExists(name: string) -> (exists: int) + +# ImageTree returns the image tree for the provided image name or ID +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.ImageTree '{"name": "alpine"}' +# { +# "tree": "Image ID: e7d92cdc71fe\nTags: [docker.io/library/alpine:latest]\nSize: 5.861MB\nImage Layers\nāāā ID: 5216338b40a7 Size: 5.857MB Top Layer of: [docker.io/library/alpine:latest]\n" +# } +# ~~~ +method ImageTree(name: string, whatRequires: bool) -> (tree: string) + +# ContainerExists takes a full or partial container ID or name and returns an int as to +# whether the container exists in local storage. A result of 0 means the container does +# exists; whereas a result of 1 means it could not be found. +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.ContainerExists '{"name": "flamboyant_payne"}'{ +# "exists": 0 +# } +# ~~~ +method ContainerExists(name: string) -> (exists: int) + +# ContainerCheckPoint performs a checkpopint on a container by its name or full/partial container +# ID. On successful checkpoint, the id of the checkpointed container is returned. +method ContainerCheckpoint(name: string, keep: bool, leaveRunning: bool, tcpEstablished: bool) -> (id: string) + +# ContainerRestore restores a container that has been checkpointed. The container to be restored can +# be identified by its name or full/partial container ID. A successful restore will result in the return +# of the container's ID. +method ContainerRestore(name: string, keep: bool, tcpEstablished: bool) -> (id: string) + +# ContainerRunlabel runs executes a command as described by a given container image label. +method ContainerRunlabel(runlabel: Runlabel) -> () + +# ExecContainer executes a command in the given container. +method ExecContainer(opts: ExecOpts) -> () + +# ListContainerMounts gathers all the mounted container mount points and returns them as an array +# of strings +# #### Example +# ~~~ +# $ varlink call unix:/run/podman/io.podman/io.podman.ListContainerMounts +# { +# "mounts": { +# "04e4c255269ed2545e7f8bd1395a75f7949c50c223415c00c1d54bfa20f3b3d9": "/var/lib/containers/storage/overlay/a078925828f57e20467ca31cfca8a849210d21ec7e5757332b72b6924f441c17/merged", +# "1d58c319f9e881a644a5122ff84419dccf6d138f744469281446ab243ef38924": "/var/lib/containers/storage/overlay/948fcf93f8cb932f0f03fd52e3180a58627d547192ffe3b88e0013b98ddcd0d2/merged" +# } +# } +# ~~~ +method ListContainerMounts() -> (mounts: [string]string) + +# MountContainer mounts a container by name or full/partial ID. Upon a successful mount, the destination +# mount is returned as a string. +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.MountContainer '{"name": "jolly_shannon"}'{ +# "path": "/var/lib/containers/storage/overlay/419eeb04e783ea159149ced67d9fcfc15211084d65e894792a96bedfae0470ca/merged" +# } +# ~~~ +method MountContainer(name: string) -> (path: string) + +# UnmountContainer umounts a container by its name or full/partial container ID. +# #### Example +# ~~~ +# $ varlink call -m unix:/run/podman/io.podman/io.podman.UnmountContainer '{"name": "jolly_shannon", "force": false}' +# {} +# ~~~ +method UnmountContainer(name: string, force: bool) -> () + +# ImagesPrune removes all unused images from the local store. Upon successful pruning, +# the IDs of the removed images are returned. +method ImagesPrune(all: bool, filter: []string) -> (pruned: []string) + +# This function is not implemented yet. +# method ListContainerPorts(name: string) -> (notimplemented: NotImplemented) + +# GenerateKube generates a Kubernetes v1 Pod description of a Podman container or pod +# and its containers. The description is in YAML. See also [ReplayKube](ReplayKube). +method GenerateKube(name: string, service: bool) -> (pod: KubePodService) + +# ReplayKube recreates a pod and its containers based on a Kubernetes v1 Pod description (in YAML) +# like that created by GenerateKube. See also [GenerateKube](GenerateKube). +# method ReplayKube() -> (notimplemented: NotImplemented) + +# ContainerConfig returns a container's config in string form. This call is for +# development of Podman only and generally should not be used. +method ContainerConfig(name: string) -> (config: string) + +# ContainerArtifacts returns a container's artifacts in string form. This call is for +# development of Podman only and generally should not be used. +method ContainerArtifacts(name: string, artifactName: string) -> (config: string) + +# ContainerInspectData returns a container's inspect data in string form. This call is for +# development of Podman only and generally should not be used. +method ContainerInspectData(name: string, size: bool) -> (config: string) + +# ContainerStateData returns a container's state config in string form. This call is for +# development of Podman only and generally should not be used. +method ContainerStateData(name: string) -> (config: string) + +# PodStateData returns inspectr level information of a given pod in string form. This call is for +# development of Podman only and generally should not be used. +method PodStateData(name: string) -> (config: string) + +# This call is for the development of Podman only and should not be used. +method CreateFromCC(in: []string) -> (id: string) + +# Spec returns the oci spec for a container. This call is for development of Podman only and generally should not be used. +method Spec(name: string) -> (config: string) + +# Sendfile allows a remote client to send a file to the host +method SendFile(type: string, length: int) -> (file_handle: string) + +# ReceiveFile allows the host to send a remote client a file +method ReceiveFile(path: string, delete: bool) -> (len: int) + +# VolumeCreate creates a volume on a remote host +method VolumeCreate(options: VolumeCreateOpts) -> (volumeName: string) + +# VolumeRemove removes a volume on a remote host +method VolumeRemove(options: VolumeRemoveOpts) -> (successes: []string, failures: [string]string) + +# GetVolumes gets slice of the volumes on a remote host +method GetVolumes(args: []string, all: bool) -> (volumes: []Volume) + +# InspectVolume inspects a single volume. Returns inspect JSON in the form of a +# string. +method InspectVolume(name: string) -> (volume: string) + +# VolumesPrune removes unused volumes on the host +method VolumesPrune() -> (prunedNames: []string, prunedErrors: []string) + +# ImageSave allows you to save an image from the local image storage to a tarball +method ImageSave(options: ImageSaveOptions) -> (reply: MoreResponse) + +# GetPodsByContext allows you to get a list pod ids depending on all, latest, or a list of +# pod names. The definition of latest pod means the latest by creation date. In a multi- +# user environment, results might differ from what you expect. +method GetPodsByContext(all: bool, latest: bool, args: []string) -> (pods: []string) + +# LoadImage allows you to load an image into local storage from a tarball. +method LoadImage(name: string, inputFile: string, quiet: bool, deleteFile: bool) -> (reply: MoreResponse) + +# GetEvents returns known libpod events filtered by the options provided. +method GetEvents(filter: []string, since: string, until: string) -> (events: Event) + +# Diff returns a diff between libpod objects +method Diff(name: string) -> (diffs: []DiffInfo) + +# GetLayersMapWithImageInfo is for the development of Podman and should not be used. +method GetLayersMapWithImageInfo() -> (layerMap: string) + +# BuildImageHierarchyMap is for the development of Podman and should not be used. +method BuildImageHierarchyMap(name: string) -> (imageInfo: string) + +# ImageNotFound means the image could not be found by the provided name or ID in local storage. +error ImageNotFound (id: string, reason: string) + +# ContainerNotFound means the container could not be found by the provided name or ID in local storage. +error ContainerNotFound (id: string, reason: string) + +# NoContainerRunning means none of the containers requested are running in a command that requires a running container. +error NoContainerRunning () + +# PodNotFound means the pod could not be found by the provided name or ID in local storage. +error PodNotFound (name: string, reason: string) + +# VolumeNotFound means the volume could not be found by the name or ID in local storage. +error VolumeNotFound (id: string, reason: string) + +# PodContainerError means a container associated with a pod failed to perform an operation. It contains +# a container ID of the container that failed. +error PodContainerError (podname: string, errors: []PodContainerErrorData) + +# NoContainersInPod means a pod has no containers on which to perform the operation. It contains +# the pod ID. +error NoContainersInPod (name: string) + +# InvalidState indicates that a container or pod was in an improper state for the requested operation +error InvalidState (id: string, reason: string) + +# ErrorOccurred is a generic error for an error that occurs during the execution. The actual error message +# is includes as part of the error's text. +error ErrorOccurred (reason: string) + +# RuntimeErrors generally means a runtime could not be found or gotten. +error RuntimeError (reason: string) + +# The Podman endpoint requires that you use a streaming connection. +error WantsMoreRequired (reason: string) + +# Container is already stopped +error ErrCtrStopped (id: string) + +# This function requires CGroupsV2 to run in rootless mode. +error ErrRequiresCgroupsV2ForRootless(reason: string) diff --git a/pkg/varlinkapi/attach.go b/pkg/varlinkapi/attach.go index 5beca3c6f..94f4d653e 100644 --- a/pkg/varlinkapi/attach.go +++ b/pkg/varlinkapi/attach.go @@ -6,10 +6,10 @@ import ( "bufio" "io" - "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/events" + iopodman "github.com/containers/libpod/pkg/varlink" "github.com/containers/libpod/pkg/varlinkapi/virtwriter" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -28,7 +28,7 @@ func setupStreams(call iopodman.VarlinkCall) (*bufio.Reader, *bufio.Writer, *io. stdoutWriter := virtwriter.NewVirtWriteCloser(writer, virtwriter.ToStdout) // TODO if runc ever starts passing stderr, we can too - //stderrWriter := NewVirtWriteCloser(writer, ToStderr) + // stderrWriter := NewVirtWriteCloser(writer, ToStderr) streams := libpod.AttachStreams{ OutputStream: stdoutWriter, diff --git a/pkg/varlinkapi/config.go b/pkg/varlinkapi/config.go index e75170547..c69dc794a 100644 --- a/pkg/varlinkapi/config.go +++ b/pkg/varlinkapi/config.go @@ -4,8 +4,8 @@ package varlinkapi import ( "github.com/containers/libpod/cmd/podman/cliconfig" - iopodman "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod" + iopodman "github.com/containers/libpod/pkg/varlink" "github.com/spf13/cobra" ) diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go index 55427771c..2d051470f 100644 --- a/pkg/varlinkapi/containers.go +++ b/pkg/varlinkapi/containers.go @@ -15,13 +15,13 @@ import ( "time" "github.com/containers/libpod/cmd/podman/shared" - iopodman "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/logs" "github.com/containers/libpod/pkg/adapter/shortcuts" "github.com/containers/libpod/pkg/cgroups" "github.com/containers/libpod/pkg/rootless" + iopodman "github.com/containers/libpod/pkg/varlink" "github.com/containers/libpod/pkg/varlinkapi/virtwriter" "github.com/containers/storage/pkg/archive" "github.com/pkg/errors" @@ -900,7 +900,7 @@ func (i *LibpodAPI) ExecContainer(call iopodman.VarlinkCall, opts iopodman.ExecO return ecErr.Error } -//HealthCheckRun executes defined container's healthcheck command and returns the container's health status. +// HealthCheckRun executes defined container's healthcheck command and returns the container's health status. func (i *LibpodAPI) HealthCheckRun(call iopodman.VarlinkCall, nameOrID string) error { hcStatus, err := i.Runtime.HealthCheck(nameOrID) if err != nil && hcStatus != libpod.HealthCheckFailure { diff --git a/pkg/varlinkapi/containers_create.go b/pkg/varlinkapi/containers_create.go index 6b23dce5e..bbd4d59f1 100644 --- a/pkg/varlinkapi/containers_create.go +++ b/pkg/varlinkapi/containers_create.go @@ -4,7 +4,7 @@ package varlinkapi import ( "github.com/containers/libpod/cmd/podman/shared" - "github.com/containers/libpod/cmd/podman/varlink" + iopodman "github.com/containers/libpod/pkg/varlink" ) // CreateContainer ... diff --git a/pkg/varlinkapi/events.go b/pkg/varlinkapi/events.go index f9a9d9321..4ae2d1cb2 100644 --- a/pkg/varlinkapi/events.go +++ b/pkg/varlinkapi/events.go @@ -6,8 +6,8 @@ import ( "fmt" "time" - "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod/events" + iopodman "github.com/containers/libpod/pkg/varlink" ) // GetEvents is a remote endpoint to get events from the event log diff --git a/pkg/varlinkapi/generate.go b/pkg/varlinkapi/generate.go index 19010097d..c19c8dede 100644 --- a/pkg/varlinkapi/generate.go +++ b/pkg/varlinkapi/generate.go @@ -6,7 +6,7 @@ import ( "encoding/json" "github.com/containers/libpod/cmd/podman/shared" - iopodman "github.com/containers/libpod/cmd/podman/varlink" + iopodman "github.com/containers/libpod/pkg/varlink" ) // GenerateKube ... diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go index 82587f5c4..c3b4bd9ae 100644 --- a/pkg/varlinkapi/images.go +++ b/pkg/varlinkapi/images.go @@ -21,12 +21,12 @@ import ( "github.com/containers/image/v5/transports/alltransports" "github.com/containers/image/v5/types" "github.com/containers/libpod/cmd/podman/shared" - iopodman "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/channelwriter" "github.com/containers/libpod/pkg/util" + iopodman "github.com/containers/libpod/pkg/varlink" "github.com/containers/libpod/utils" "github.com/containers/storage/pkg/archive" v1 "github.com/opencontainers/image-spec/specs-go/v1" diff --git a/pkg/varlinkapi/mount.go b/pkg/varlinkapi/mount.go index 63ce44291..2450f6fd9 100644 --- a/pkg/varlinkapi/mount.go +++ b/pkg/varlinkapi/mount.go @@ -2,9 +2,7 @@ package varlinkapi -import ( - "github.com/containers/libpod/cmd/podman/varlink" -) +import iopodman "github.com/containers/libpod/pkg/varlink" // ListContainerMounts ... func (i *LibpodAPI) ListContainerMounts(call iopodman.VarlinkCall) error { diff --git a/pkg/varlinkapi/pods.go b/pkg/varlinkapi/pods.go index 2ec45f7a1..79ffb6677 100644 --- a/pkg/varlinkapi/pods.go +++ b/pkg/varlinkapi/pods.go @@ -8,9 +8,9 @@ import ( "syscall" "github.com/containers/libpod/cmd/podman/shared" - "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod" "github.com/containers/libpod/pkg/adapter/shortcuts" + iopodman "github.com/containers/libpod/pkg/varlink" ) // CreatePod ... diff --git a/pkg/varlinkapi/remote_client.go b/pkg/varlinkapi/remote_client.go index dd0613494..a16d11dec 100644 --- a/pkg/varlinkapi/remote_client.go +++ b/pkg/varlinkapi/remote_client.go @@ -3,8 +3,8 @@ package varlinkapi import ( - "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod" + iopodman "github.com/containers/libpod/pkg/varlink" ) // ContainerStatsToLibpodContainerStats converts the varlink containerstats to a libpod diff --git a/pkg/varlinkapi/system.go b/pkg/varlinkapi/system.go index e88d010c5..04fb9f648 100644 --- a/pkg/varlinkapi/system.go +++ b/pkg/varlinkapi/system.go @@ -10,8 +10,8 @@ import ( "time" "github.com/containers/image/v5/pkg/sysregistriesv2" - iopodman "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod/define" + iopodman "github.com/containers/libpod/pkg/varlink" "github.com/sirupsen/logrus" ) diff --git a/pkg/varlinkapi/transfers.go b/pkg/varlinkapi/transfers.go index 31d26c3aa..654da276e 100644 --- a/pkg/varlinkapi/transfers.go +++ b/pkg/varlinkapi/transfers.go @@ -9,7 +9,7 @@ import ( "io/ioutil" "os" - "github.com/containers/libpod/cmd/podman/varlink" + iopodman "github.com/containers/libpod/pkg/varlink" "github.com/sirupsen/logrus" ) diff --git a/pkg/varlinkapi/util.go b/pkg/varlinkapi/util.go index d3a41f7ab..6b196f384 100644 --- a/pkg/varlinkapi/util.go +++ b/pkg/varlinkapi/util.go @@ -10,10 +10,10 @@ import ( "github.com/containers/buildah" "github.com/containers/libpod/cmd/podman/shared" - "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/channelwriter" + iopodman "github.com/containers/libpod/pkg/varlink" "github.com/containers/storage/pkg/archive" ) diff --git a/pkg/varlinkapi/volumes.go b/pkg/varlinkapi/volumes.go index e497cb537..b0c3608c4 100644 --- a/pkg/varlinkapi/volumes.go +++ b/pkg/varlinkapi/volumes.go @@ -6,8 +6,8 @@ import ( "encoding/json" "github.com/containers/libpod/cmd/podman/shared" - iopodman "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod" + iopodman "github.com/containers/libpod/pkg/varlink" ) // VolumeCreate creates a libpod volume based on input from a varlink connection |