From 4bf973a9f61eae3b02925a42ccfa784baeb917dc Mon Sep 17 00:00:00 2001 From: baude Date: Fri, 22 Feb 2019 11:07:18 -0600 Subject: Enable more podman-remote pod commands enable pod start, stop, and kill subcommands for the remote-client. Signed-off-by: baude --- libpod/adapter/client.go | 47 -- libpod/adapter/containers_remote.go | 50 --- libpod/adapter/images_remote.go | 24 - libpod/adapter/info_remote.go | 56 --- libpod/adapter/pods.go | 54 --- libpod/adapter/pods_remote.go | 98 ----- libpod/adapter/runtime.go | 335 -------------- libpod/adapter/runtime_remote.go | 798 ---------------------------------- libpod/adapter/shortcuts/shortcuts.go | 27 -- libpod/adapter/volumes_remote.go | 33 -- 10 files changed, 1522 deletions(-) delete mode 100644 libpod/adapter/client.go delete mode 100644 libpod/adapter/containers_remote.go delete mode 100644 libpod/adapter/images_remote.go delete mode 100644 libpod/adapter/info_remote.go delete mode 100644 libpod/adapter/pods.go delete mode 100644 libpod/adapter/pods_remote.go delete mode 100644 libpod/adapter/runtime.go delete mode 100644 libpod/adapter/runtime_remote.go delete mode 100644 libpod/adapter/shortcuts/shortcuts.go delete mode 100644 libpod/adapter/volumes_remote.go (limited to 'libpod') diff --git a/libpod/adapter/client.go b/libpod/adapter/client.go deleted file mode 100644 index 6512a5952..000000000 --- a/libpod/adapter/client.go +++ /dev/null @@ -1,47 +0,0 @@ -// +build remoteclient - -package adapter - -import ( - "os" - - "github.com/sirupsen/logrus" - "github.com/varlink/go/varlink" -) - -// DefaultAddress is the default address of the varlink socket -const DefaultAddress = "unix:/run/podman/io.podman" - -// Connect provides a varlink connection -func (r RemoteRuntime) Connect() (*varlink.Connection, error) { - var err error - var connection *varlink.Connection - if bridge := os.Getenv("PODMAN_VARLINK_BRIDGE"); bridge != "" { - logrus.Infof("Connecting with varlink bridge") - logrus.Debugf("%s", bridge) - connection, err = varlink.NewBridge(bridge) - } else { - address := os.Getenv("PODMAN_VARLINK_ADDRESS") - if address == "" { - address = DefaultAddress - } - logrus.Infof("Connecting with varlink address") - logrus.Debugf("%s", address) - connection, err = varlink.NewConnection(address) - } - if err != nil { - return nil, err - } - return connection, nil -} - -// RefreshConnection is used to replace the current r.Conn after things like -// using an upgraded varlink connection -func (r RemoteRuntime) RefreshConnection() error { - newConn, err := r.Connect() - if err != nil { - return err - } - r.Conn = newConn - return nil -} diff --git a/libpod/adapter/containers_remote.go b/libpod/adapter/containers_remote.go deleted file mode 100644 index 9623304e5..000000000 --- a/libpod/adapter/containers_remote.go +++ /dev/null @@ -1,50 +0,0 @@ -// +build remoteclient - -package adapter - -import ( - "encoding/json" - - iopodman "github.com/containers/libpod/cmd/podman/varlink" - "github.com/containers/libpod/libpod" - "github.com/containers/libpod/pkg/inspect" -) - -// Inspect returns an inspect struct from varlink -func (c *Container) Inspect(size bool) (*inspect.ContainerInspectData, error) { - reply, err := iopodman.ContainerInspectData().Call(c.Runtime.Conn, c.ID()) - if err != nil { - return nil, err - } - data := inspect.ContainerInspectData{} - if err := json.Unmarshal([]byte(reply), &data); err != nil { - return nil, err - } - return &data, err -} - -// ID returns the ID of the container -func (c *Container) ID() string { - return c.config.ID -} - -// GetArtifact returns a container's artifacts -func (c *Container) GetArtifact(name string) ([]byte, error) { - var data []byte - reply, err := iopodman.ContainerArtifacts().Call(c.Runtime.Conn, c.ID(), name) - if err != nil { - return nil, err - } - if err := json.Unmarshal([]byte(reply), &data); err != nil { - return nil, err - } - return data, err -} - -// Config returns a container's Config ... same as ctr.Config() -func (c *Container) Config() *libpod.ContainerConfig { - if c.config != nil { - return c.config - } - return c.Runtime.Config(c.ID()) -} diff --git a/libpod/adapter/images_remote.go b/libpod/adapter/images_remote.go deleted file mode 100644 index e7b38dccc..000000000 --- a/libpod/adapter/images_remote.go +++ /dev/null @@ -1,24 +0,0 @@ -// +build remoteclient - -package adapter - -import ( - "context" - "encoding/json" - - iopodman "github.com/containers/libpod/cmd/podman/varlink" - "github.com/containers/libpod/pkg/inspect" -) - -// Inspect returns returns an ImageData struct from over a varlink connection -func (i *ContainerImage) Inspect(ctx context.Context) (*inspect.ImageData, error) { - reply, err := iopodman.InspectImage().Call(i.Runtime.Conn, i.ID()) - if err != nil { - return nil, err - } - data := inspect.ImageData{} - if err := json.Unmarshal([]byte(reply), &data); err != nil { - return nil, err - } - return &data, nil -} diff --git a/libpod/adapter/info_remote.go b/libpod/adapter/info_remote.go deleted file mode 100644 index 3b691ed17..000000000 --- a/libpod/adapter/info_remote.go +++ /dev/null @@ -1,56 +0,0 @@ -// +build remoteclient - -package adapter - -import ( - "encoding/json" - - "github.com/containers/libpod/cmd/podman/varlink" - "github.com/containers/libpod/libpod" -) - -// Info returns information for the host system and its components -func (r RemoteRuntime) Info() ([]libpod.InfoData, error) { - // TODO the varlink implementation for info should be updated to match the output for regular info - var ( - reply []libpod.InfoData - hostInfo map[string]interface{} - store map[string]interface{} - ) - - registries := make(map[string]interface{}) - insecureRegistries := make(map[string]interface{}) - conn, err := r.Connect() - if err != nil { - return nil, err - } - defer conn.Close() - info, err := iopodman.GetInfo().Call(conn) - if err != nil { - return nil, err - } - - // info.host -> map[string]interface{} - h, err := json.Marshal(info.Host) - if err != nil { - return nil, err - } - json.Unmarshal(h, &hostInfo) - - // info.store -> map[string]interface{} - s, err := json.Marshal(info.Store) - if err != nil { - return nil, err - } - json.Unmarshal(s, &store) - - registries["registries"] = info.Registries - insecureRegistries["registries"] = info.Insecure_registries - - // Add everything to the reply - reply = append(reply, libpod.InfoData{Type: "host", Data: hostInfo}) - reply = append(reply, libpod.InfoData{Type: "registries", Data: registries}) - reply = append(reply, libpod.InfoData{Type: "insecure registries", Data: insecureRegistries}) - reply = append(reply, libpod.InfoData{Type: "store", Data: store}) - return reply, nil -} diff --git a/libpod/adapter/pods.go b/libpod/adapter/pods.go deleted file mode 100644 index 9841c20c0..000000000 --- a/libpod/adapter/pods.go +++ /dev/null @@ -1,54 +0,0 @@ -// +build !remoteclient - -package adapter - -import ( - "context" - "github.com/containers/libpod/libpod/adapter/shortcuts" - - "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/libpod" -) - -// Pod ... -type Pod struct { - *libpod.Pod -} - -// RemovePods ... -func (r *LocalRuntime) RemovePods(ctx context.Context, cli *cliconfig.PodRmValues) ([]string, []error) { - var ( - errs []error - podids []string - ) - pods, err := shortcuts.GetPodsByContext(cli.All, cli.Latest, cli.InputArgs, r.Runtime) - if err != nil { - errs = append(errs, err) - return nil, errs - } - - for _, p := range pods { - if err := r.RemovePod(ctx, p, cli.Force, cli.Force); err != nil { - errs = append(errs, err) - } else { - podids = append(podids, p.ID()) - } - } - return podids, errs -} - -// GetLatestPod gets the latest pod and wraps it in an adapter pod -func (r *LocalRuntime) GetLatestPod() (*Pod, error) { - pod := Pod{} - p, err := r.Runtime.GetLatestPod() - pod.Pod = p - return &pod, err -} - -// LookupPod gets a pod by name or id and wraps it in an adapter pod -func (r *LocalRuntime) LookupPod(nameOrID string) (*Pod, error) { - pod := Pod{} - p, err := r.Runtime.LookupPod(nameOrID) - pod.Pod = p - return &pod, err -} diff --git a/libpod/adapter/pods_remote.go b/libpod/adapter/pods_remote.go deleted file mode 100644 index 57c78821f..000000000 --- a/libpod/adapter/pods_remote.go +++ /dev/null @@ -1,98 +0,0 @@ -// +build remoteclient - -package adapter - -import ( - "context" - "encoding/json" - - "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/varlink" - "github.com/containers/libpod/libpod" - "github.com/pkg/errors" - "github.com/ulule/deepcopier" -) - -// Pod ... -type Pod struct { - remotepod -} - -type remotepod struct { - config *libpod.PodConfig - state *libpod.PodInspectState - containers []libpod.PodContainerInfo - Runtime *LocalRuntime -} - -// RemovePods removes one or more based on the cli context. -func (r *LocalRuntime) RemovePods(ctx context.Context, cli *cliconfig.PodRmValues) ([]string, []error) { - var ( - rmErrs []error - rmPods []string - ) - podIDs, err := iopodman.GetPodsByContext().Call(r.Conn, cli.All, cli.Latest, cli.InputArgs) - if err != nil { - rmErrs = append(rmErrs, err) - return nil, rmErrs - } - - for _, p := range podIDs { - reply, err := iopodman.RemovePod().Call(r.Conn, p, cli.Force) - if err != nil { - rmErrs = append(rmErrs, err) - } else { - rmPods = append(rmPods, reply) - } - } - return rmPods, rmErrs -} - -// Inspect looks up a pod by name or id and embeds its data into a remote pod -// object. -func (r *LocalRuntime) Inspect(nameOrID string) (*Pod, error) { - reply, err := iopodman.PodStateData().Call(r.Conn, nameOrID) - if err != nil { - return nil, err - } - data := libpod.PodInspect{} - if err := json.Unmarshal([]byte(reply), &data); err != nil { - return nil, err - } - pod := Pod{} - pod.Runtime = r - pod.config = data.Config - pod.state = data.State - pod.containers = data.Containers - return &pod, nil -} - -// GetLatestPod gets the latest pod and wraps it in an adapter pod -func (r *LocalRuntime) GetLatestPod() (*Pod, error) { - reply, err := iopodman.GetPodsByContext().Call(r.Conn, false, true, nil) - if err != nil { - return nil, err - } - if len(reply) > 0 { - return r.Inspect(reply[0]) - } - return nil, errors.New("no pods exist") -} - -// LookupPod gets a pod by name or ID and wraps it in an adapter pod -func (r *LocalRuntime) LookupPod(nameOrID string) (*Pod, error) { - return r.Inspect(nameOrID) -} - -// Inspect, like libpod pod inspect, returns a libpod.PodInspect object from -// the data of a remotepod data struct -func (p *Pod) Inspect() (*libpod.PodInspect, error) { - config := new(libpod.PodConfig) - deepcopier.Copy(p.remotepod.config).To(config) - inspectData := libpod.PodInspect{ - Config: config, - State: p.remotepod.state, - Containers: p.containers, - } - return &inspectData, nil -} diff --git a/libpod/adapter/runtime.go b/libpod/adapter/runtime.go deleted file mode 100644 index 4f5b98dbb..000000000 --- a/libpod/adapter/runtime.go +++ /dev/null @@ -1,335 +0,0 @@ -// +build !remoteclient - -package adapter - -import ( - "context" - "io" - "io/ioutil" - "os" - "strconv" - - "github.com/containers/buildah" - "github.com/containers/buildah/imagebuildah" - "github.com/containers/buildah/pkg/parse" - "github.com/containers/image/docker/reference" - "github.com/containers/image/types" - "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/libpodruntime" - "github.com/containers/libpod/libpod" - "github.com/containers/libpod/libpod/image" - "github.com/containers/libpod/pkg/rootless" - "github.com/pkg/errors" -) - -// LocalRuntime describes a typical libpod runtime -type LocalRuntime struct { - *libpod.Runtime - Remote bool -} - -// ContainerImage ... -type ContainerImage struct { - *image.Image -} - -// Container ... -type Container struct { - *libpod.Container -} - -// Volume ... -type Volume struct { - *libpod.Volume -} - -// VolumeFilter is for filtering volumes on the client -type VolumeFilter func(*Volume) bool - -// GetRuntime returns a LocalRuntime struct with the actual runtime embedded in it -func GetRuntime(c *cliconfig.PodmanCommand) (*LocalRuntime, error) { - runtime, err := libpodruntime.GetRuntime(c) - if err != nil { - return nil, err - } - return &LocalRuntime{ - Runtime: runtime, - }, nil -} - -// GetImages returns a slice of images in containerimages -func (r *LocalRuntime) GetImages() ([]*ContainerImage, error) { - var containerImages []*ContainerImage - images, err := r.Runtime.ImageRuntime().GetImages() - if err != nil { - return nil, err - } - for _, i := range images { - containerImages = append(containerImages, &ContainerImage{i}) - } - return containerImages, nil - -} - -// NewImageFromLocal returns a containerimage representation of a image from local storage -func (r *LocalRuntime) NewImageFromLocal(name string) (*ContainerImage, error) { - img, err := r.Runtime.ImageRuntime().NewFromLocal(name) - if err != nil { - return nil, err - } - return &ContainerImage{img}, nil -} - -// LoadFromArchiveReference calls into local storage to load an image from an archive -func (r *LocalRuntime) LoadFromArchiveReference(ctx context.Context, srcRef types.ImageReference, signaturePolicyPath string, writer io.Writer) ([]*ContainerImage, error) { - var containerImages []*ContainerImage - imgs, err := r.Runtime.ImageRuntime().LoadFromArchiveReference(ctx, srcRef, signaturePolicyPath, writer) - if err != nil { - return nil, err - } - for _, i := range imgs { - ci := ContainerImage{i} - containerImages = append(containerImages, &ci) - } - return containerImages, nil -} - -// New calls into local storage to look for an image in local storage or to pull it -func (r *LocalRuntime) New(ctx context.Context, name, signaturePolicyPath, authfile string, writer io.Writer, dockeroptions *image.DockerRegistryOptions, signingoptions image.SigningOptions, forcePull bool, label *string) (*ContainerImage, error) { - img, err := r.Runtime.ImageRuntime().New(ctx, name, signaturePolicyPath, authfile, writer, dockeroptions, signingoptions, forcePull, label) - if err != nil { - return nil, err - } - return &ContainerImage{img}, nil -} - -// RemoveImage calls into local storage and removes an image -func (r *LocalRuntime) RemoveImage(ctx context.Context, img *ContainerImage, force bool) (string, error) { - return r.Runtime.RemoveImage(ctx, img.Image, force) -} - -// LookupContainer ... -func (r *LocalRuntime) LookupContainer(idOrName string) (*Container, error) { - ctr, err := r.Runtime.LookupContainer(idOrName) - if err != nil { - return nil, err - } - return &Container{ctr}, nil -} - -// PruneImages is wrapper into PruneImages within the image pkg -func (r *LocalRuntime) PruneImages(all bool) ([]string, error) { - return r.ImageRuntime().PruneImages(all) -} - -// Export is a wrapper to container export to a tarfile -func (r *LocalRuntime) Export(name string, path string) error { - ctr, err := r.Runtime.LookupContainer(name) - if err != nil { - return errors.Wrapf(err, "error looking up container %q", name) - } - if os.Geteuid() != 0 { - state, err := ctr.State() - if err != nil { - return errors.Wrapf(err, "cannot read container state %q", ctr.ID()) - } - if state == libpod.ContainerStateRunning || state == libpod.ContainerStatePaused { - data, err := ioutil.ReadFile(ctr.Config().ConmonPidFile) - if err != nil { - return errors.Wrapf(err, "cannot read conmon PID file %q", ctr.Config().ConmonPidFile) - } - conmonPid, err := strconv.Atoi(string(data)) - if err != nil { - return errors.Wrapf(err, "cannot parse PID %q", data) - } - became, ret, err := rootless.JoinDirectUserAndMountNS(uint(conmonPid)) - if err != nil { - return err - } - if became { - os.Exit(ret) - } - } else { - became, ret, err := rootless.BecomeRootInUserNS() - if err != nil { - return err - } - if became { - os.Exit(ret) - } - } - } - - return ctr.Export(path) -} - -// Import is a wrapper to import a container image -func (r *LocalRuntime) Import(ctx context.Context, source, reference string, changes []string, history string, quiet bool) (string, error) { - return r.Runtime.Import(ctx, source, reference, changes, history, quiet) -} - -// CreateVolume is a wrapper to create volumes -func (r *LocalRuntime) CreateVolume(ctx context.Context, c *cliconfig.VolumeCreateValues, labels, opts map[string]string) (string, error) { - var ( - options []libpod.VolumeCreateOption - volName string - ) - - if len(c.InputArgs) > 0 { - volName = c.InputArgs[0] - options = append(options, libpod.WithVolumeName(volName)) - } - - if c.Flag("driver").Changed { - options = append(options, libpod.WithVolumeDriver(c.Driver)) - } - - if len(labels) != 0 { - options = append(options, libpod.WithVolumeLabels(labels)) - } - - if len(options) != 0 { - options = append(options, libpod.WithVolumeOptions(opts)) - } - newVolume, err := r.NewVolume(ctx, options...) - if err != nil { - return "", err - } - return newVolume.Name(), nil -} - -// RemoveVolumes is a wrapper to remove volumes -func (r *LocalRuntime) RemoveVolumes(ctx context.Context, c *cliconfig.VolumeRmValues) ([]string, error) { - return r.Runtime.RemoveVolumes(ctx, c.InputArgs, c.All, c.Force) -} - -// Push is a wrapper to push an image to a registry -func (r *LocalRuntime) Push(ctx context.Context, srcName, destination, manifestMIMEType, authfile, signaturePolicyPath string, writer io.Writer, forceCompress bool, signingOptions image.SigningOptions, dockerRegistryOptions *image.DockerRegistryOptions, additionalDockerArchiveTags []reference.NamedTagged) error { - newImage, err := r.ImageRuntime().NewFromLocal(srcName) - if err != nil { - return err - } - return newImage.PushImageToHeuristicDestination(ctx, destination, manifestMIMEType, authfile, signaturePolicyPath, writer, forceCompress, signingOptions, dockerRegistryOptions, nil) -} - -// InspectVolumes returns a slice of volumes based on an arg list or --all -func (r *LocalRuntime) InspectVolumes(ctx context.Context, c *cliconfig.VolumeInspectValues) ([]*Volume, error) { - var ( - volumes []*libpod.Volume - err error - ) - - if c.All { - volumes, err = r.GetAllVolumes() - } else { - for _, v := range c.InputArgs { - vol, err := r.GetVolume(v) - if err != nil { - return nil, err - } - volumes = append(volumes, vol) - } - } - if err != nil { - return nil, err - } - return libpodVolumeToVolume(volumes), nil -} - -// Volumes returns a slice of localruntime volumes -func (r *LocalRuntime) Volumes(ctx context.Context) ([]*Volume, error) { - vols, err := r.GetAllVolumes() - if err != nil { - return nil, err - } - return libpodVolumeToVolume(vols), nil -} - -// libpodVolumeToVolume converts a slice of libpod volumes to a slice -// of localruntime volumes (same as libpod) -func libpodVolumeToVolume(volumes []*libpod.Volume) []*Volume { - var vols []*Volume - for _, v := range volumes { - newVol := Volume{ - v, - } - vols = append(vols, &newVol) - } - return vols -} - -// Build is the wrapper to build images -func (r *LocalRuntime) Build(ctx context.Context, c *cliconfig.BuildValues, options imagebuildah.BuildOptions, dockerfiles []string) error { - namespaceOptions, networkPolicy, err := parse.NamespaceOptions(c.PodmanCommand.Command) - if err != nil { - return errors.Wrapf(err, "error parsing namespace-related options") - } - usernsOption, idmappingOptions, err := parse.IDMappingOptions(c.PodmanCommand.Command) - if err != nil { - return errors.Wrapf(err, "error parsing ID mapping options") - } - namespaceOptions.AddOrReplace(usernsOption...) - - systemContext, err := parse.SystemContextFromOptions(c.PodmanCommand.Command) - if err != nil { - return errors.Wrapf(err, "error building system context") - } - - authfile := c.Authfile - if len(c.Authfile) == 0 { - authfile = os.Getenv("REGISTRY_AUTH_FILE") - } - - systemContext.AuthFilePath = authfile - commonOpts, err := parse.CommonBuildOptions(c.PodmanCommand.Command) - if err != nil { - return err - } - - options.NamespaceOptions = namespaceOptions - options.ConfigureNetwork = networkPolicy - options.IDMappingOptions = idmappingOptions - options.CommonBuildOpts = commonOpts - options.SystemContext = systemContext - - if c.Flag("runtime").Changed { - options.Runtime = r.GetOCIRuntimePath() - } - if c.Quiet { - options.ReportWriter = ioutil.Discard - } - - if rootless.IsRootless() { - options.Isolation = buildah.IsolationOCIRootless - } - - return r.Runtime.Build(ctx, options, dockerfiles...) -} - -// PruneVolumes is a wrapper function for libpod PruneVolumes -func (r *LocalRuntime) PruneVolumes(ctx context.Context) ([]string, []error) { - return r.Runtime.PruneVolumes(ctx) -} - -// SaveImage is a wrapper function for saving an image to the local filesystem -func (r *LocalRuntime) SaveImage(ctx context.Context, c *cliconfig.SaveValues) error { - source := c.InputArgs[0] - additionalTags := c.InputArgs[1:] - - newImage, err := r.Runtime.ImageRuntime().NewFromLocal(source) - if err != nil { - return err - } - return newImage.Save(ctx, source, c.Format, c.Output, additionalTags, c.Quiet, c.Compress) -} - -// LoadImage is a wrapper function for libpod PruneVolumes -func (r *LocalRuntime) LoadImage(ctx context.Context, name string, cli *cliconfig.LoadValues) (string, error) { - var ( - writer io.Writer - ) - if !cli.Quiet { - writer = os.Stderr - } - return r.Runtime.LoadImage(ctx, name, cli.Input, writer, cli.SignaturePolicy) -} diff --git a/libpod/adapter/runtime_remote.go b/libpod/adapter/runtime_remote.go deleted file mode 100644 index ca2fad852..000000000 --- a/libpod/adapter/runtime_remote.go +++ /dev/null @@ -1,798 +0,0 @@ -// +build remoteclient - -package adapter - -import ( - "bufio" - "context" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "os" - "strings" - "time" - - "github.com/containers/buildah/imagebuildah" - "github.com/containers/image/docker/reference" - "github.com/containers/image/types" - "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/varlink" - "github.com/containers/libpod/libpod" - "github.com/containers/libpod/libpod/image" - "github.com/containers/libpod/utils" - "github.com/containers/storage/pkg/archive" - "github.com/opencontainers/go-digest" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "github.com/varlink/go/varlink" -) - -// ImageRuntime is wrapper for image runtime -type RemoteImageRuntime struct{} - -// RemoteRuntime describes a wrapper runtime struct -type RemoteRuntime struct { - Conn *varlink.Connection - Remote bool -} - -// LocalRuntime describes a typical libpod runtime -type LocalRuntime struct { - *RemoteRuntime -} - -// GetRuntime returns a LocalRuntime struct with the actual runtime embedded in it -func GetRuntime(c *cliconfig.PodmanCommand) (*LocalRuntime, error) { - runtime := RemoteRuntime{} - conn, err := runtime.Connect() - if err != nil { - return nil, err - } - rr := RemoteRuntime{ - Conn: conn, - Remote: true, - } - foo := LocalRuntime{ - &rr, - } - return &foo, nil -} - -// Shutdown is a bogus wrapper for compat with the libpod runtime -func (r RemoteRuntime) Shutdown(force bool) error { - return nil -} - -// ContainerImage -type ContainerImage struct { - remoteImage -} - -type remoteImage struct { - ID string - Labels map[string]string - RepoTags []string - RepoDigests []string - Parent string - Size int64 - Created time.Time - InputName string - Names []string - Digest digest.Digest - isParent bool - Runtime *LocalRuntime -} - -// Container ... -type Container struct { - remoteContainer -} - -// remoteContainer .... -type remoteContainer struct { - Runtime *LocalRuntime - config *libpod.ContainerConfig - state *libpod.ContainerState -} - -type VolumeFilter func(*Volume) bool - -// Volume is embed for libpod volumes -type Volume struct { - remoteVolume -} - -type remoteVolume struct { - Runtime *LocalRuntime - config *libpod.VolumeConfig -} - -// GetImages returns a slice of containerimages over a varlink connection -func (r *LocalRuntime) GetImages() ([]*ContainerImage, error) { - var newImages []*ContainerImage - images, err := iopodman.ListImages().Call(r.Conn) - if err != nil { - return nil, err - } - for _, i := range images { - name := i.Id - if len(i.RepoTags) > 1 { - name = i.RepoTags[0] - } - newImage, err := imageInListToContainerImage(i, name, r) - if err != nil { - return nil, err - } - newImages = append(newImages, newImage) - } - return newImages, nil -} - -func imageInListToContainerImage(i iopodman.Image, name string, runtime *LocalRuntime) (*ContainerImage, error) { - created, err := time.ParseInLocation(time.RFC3339, i.Created, time.UTC) - if err != nil { - return nil, err - } - ri := remoteImage{ - InputName: name, - ID: i.Id, - Labels: i.Labels, - RepoTags: i.RepoTags, - RepoDigests: i.RepoTags, - Parent: i.ParentId, - Size: i.Size, - Created: created, - Names: i.RepoTags, - isParent: i.IsParent, - Runtime: runtime, - } - return &ContainerImage{ri}, nil -} - -// NewImageFromLocal returns a container image representation of a image over varlink -func (r *LocalRuntime) NewImageFromLocal(name string) (*ContainerImage, error) { - img, err := iopodman.GetImage().Call(r.Conn, name) - if err != nil { - return nil, err - } - return imageInListToContainerImage(img, name, r) - -} - -// LoadFromArchiveReference creates an image from a local archive -func (r *LocalRuntime) LoadFromArchiveReference(ctx context.Context, srcRef types.ImageReference, signaturePolicyPath string, writer io.Writer) ([]*ContainerImage, error) { - var iid string - // TODO We need to find a way to leak certDir, creds, and the tlsverify into this function, normally this would - // come from cli options but we don't want want those in here either. - tlsverify := true - reply, err := iopodman.PullImage().Send(r.Conn, varlink.More, srcRef.DockerReference().String(), "", "", signaturePolicyPath, &tlsverify) - if err != nil { - return nil, err - } - - for { - responses, flags, err := reply() - if err != nil { - return nil, err - } - for _, line := range responses.Logs { - fmt.Print(line) - } - iid = responses.Id - if flags&varlink.Continues == 0 { - break - } - } - - newImage, err := r.NewImageFromLocal(iid) - if err != nil { - return nil, err - } - return []*ContainerImage{newImage}, nil -} - -// New calls into local storage to look for an image in local storage or to pull it -func (r *LocalRuntime) New(ctx context.Context, name, signaturePolicyPath, authfile string, writer io.Writer, dockeroptions *image.DockerRegistryOptions, signingoptions image.SigningOptions, forcePull bool, label *string) (*ContainerImage, error) { - var iid string - if label != nil { - return nil, errors.New("the remote client function does not support checking a remote image for a label") - } - var ( - tlsVerify bool - tlsVerifyPtr *bool - ) - if dockeroptions.DockerInsecureSkipTLSVerify == types.OptionalBoolFalse { - tlsVerify = true - tlsVerifyPtr = &tlsVerify - - } - if dockeroptions.DockerInsecureSkipTLSVerify == types.OptionalBoolTrue { - tlsVerify = false - tlsVerifyPtr = &tlsVerify - } - - reply, err := iopodman.PullImage().Send(r.Conn, varlink.More, name, dockeroptions.DockerCertPath, "", signaturePolicyPath, tlsVerifyPtr) - if err != nil { - return nil, err - } - for { - responses, flags, err := reply() - if err != nil { - return nil, err - } - for _, line := range responses.Logs { - fmt.Print(line) - } - iid = responses.Id - if flags&varlink.Continues == 0 { - break - } - } - newImage, err := r.NewImageFromLocal(iid) - if err != nil { - return nil, err - } - return newImage, nil -} - -// IsParent goes through the layers in the store and checks if i.TopLayer is -// the parent of any other layer in store. Double check that image with that -// layer exists as well. -func (ci *ContainerImage) IsParent() (bool, error) { - return ci.remoteImage.isParent, nil -} - -// ID returns the image ID as a string -func (ci *ContainerImage) ID() string { - return ci.remoteImage.ID -} - -// Names returns a string array of names associated with the image -func (ci *ContainerImage) Names() []string { - return ci.remoteImage.Names -} - -// Created returns the time the image was created -func (ci *ContainerImage) Created() time.Time { - return ci.remoteImage.Created -} - -// Size returns the size of the image -func (ci *ContainerImage) Size(ctx context.Context) (*uint64, error) { - usize := uint64(ci.remoteImage.Size) - return &usize, nil -} - -// Digest returns the image's digest -func (ci *ContainerImage) Digest() digest.Digest { - return ci.remoteImage.Digest -} - -// Labels returns a map of the image's labels -func (ci *ContainerImage) Labels(ctx context.Context) (map[string]string, error) { - return ci.remoteImage.Labels, nil -} - -// Dangling returns a bool if the image is "dangling" -func (ci *ContainerImage) Dangling() bool { - return len(ci.Names()) == 0 -} - -// TagImage ... -func (ci *ContainerImage) TagImage(tag string) error { - _, err := iopodman.TagImage().Call(ci.Runtime.Conn, ci.ID(), tag) - return err -} - -// RemoveImage calls varlink to remove an image -func (r *LocalRuntime) RemoveImage(ctx context.Context, img *ContainerImage, force bool) (string, error) { - return iopodman.RemoveImage().Call(r.Conn, img.InputName, force) -} - -// History returns the history of an image and its layers -func (ci *ContainerImage) History(ctx context.Context) ([]*image.History, error) { - var imageHistories []*image.History - - reply, err := iopodman.HistoryImage().Call(ci.Runtime.Conn, ci.InputName) - if err != nil { - return nil, err - } - for _, h := range reply { - created, err := time.ParseInLocation(time.RFC3339, h.Created, time.UTC) - if err != nil { - return nil, err - } - ih := image.History{ - ID: h.Id, - Created: &created, - CreatedBy: h.CreatedBy, - Size: h.Size, - Comment: h.Comment, - } - imageHistories = append(imageHistories, &ih) - } - return imageHistories, nil -} - -// LookupContainer gets basic information about container over a varlink -// connection and then translates it to a *Container -func (r *LocalRuntime) LookupContainer(idOrName string) (*Container, error) { - state, err := r.ContainerState(idOrName) - if err != nil { - return nil, err - } - config := r.Config(idOrName) - if err != nil { - return nil, err - } - - rc := remoteContainer{ - r, - config, - state, - } - - c := Container{ - rc, - } - return &c, nil -} - -func (r *LocalRuntime) GetLatestContainer() (*Container, error) { - return nil, libpod.ErrNotImplemented -} - -// ContainerState returns the "state" of the container. -func (r *LocalRuntime) ContainerState(name string) (*libpod.ContainerState, error) { //no-lint - reply, err := iopodman.ContainerStateData().Call(r.Conn, name) - if err != nil { - return nil, err - } - data := libpod.ContainerState{} - if err := json.Unmarshal([]byte(reply), &data); err != nil { - return nil, err - } - return &data, err - -} - -// Config returns a container config -func (r *LocalRuntime) Config(name string) *libpod.ContainerConfig { - // TODO the Spec being returned is not populated. Matt and I could not figure out why. Will defer - // further looking into it for after devconf. - // The libpod function for this has no errors so we are kind of in a tough - // spot here. Logging the errors for now. - reply, err := iopodman.ContainerConfig().Call(r.Conn, name) - if err != nil { - logrus.Error("call to container.config failed") - } - data := libpod.ContainerConfig{} - if err := json.Unmarshal([]byte(reply), &data); err != nil { - logrus.Error("failed to unmarshal container inspect data") - } - return &data - -} - -// PruneImages is the wrapper call for a remote-client to prune images -func (r *LocalRuntime) PruneImages(all bool) ([]string, error) { - return iopodman.ImagesPrune().Call(r.Conn, all) -} - -// Export is a wrapper to container export to a tarfile -func (r *LocalRuntime) Export(name string, path string) error { - tempPath, err := iopodman.ExportContainer().Call(r.Conn, name, "") - if err != nil { - return err - } - return r.GetFileFromRemoteHost(tempPath, path, true) -} - -func (r *LocalRuntime) GetFileFromRemoteHost(remoteFilePath, outputPath string, delete bool) error { - outputFile, err := os.Create(outputPath) - if err != nil { - return err - } - defer outputFile.Close() - - writer := bufio.NewWriter(outputFile) - defer writer.Flush() - - reply, err := iopodman.ReceiveFile().Send(r.Conn, varlink.Upgrade, remoteFilePath, delete) - if err != nil { - return err - } - - length, _, err := reply() - if err != nil { - return errors.Wrap(err, "unable to get file length for transfer") - } - - reader := r.Conn.Reader - if _, err := io.CopyN(writer, reader, length); err != nil { - return errors.Wrap(err, "file transer failed") - } - return nil -} - -// Import implements the remote calls required to import a container image to the store -func (r *LocalRuntime) Import(ctx context.Context, source, reference string, changes []string, history string, quiet bool) (string, error) { - // First we send the file to the host - tempFile, err := r.SendFileOverVarlink(source) - if err != nil { - return "", err - } - return iopodman.ImportImage().Call(r.Conn, strings.TrimRight(tempFile, ":"), reference, history, changes, true) -} - -func (r *LocalRuntime) Build(ctx context.Context, c *cliconfig.BuildValues, options imagebuildah.BuildOptions, dockerfiles []string) error { - buildOptions := iopodman.BuildOptions{ - AddHosts: options.CommonBuildOpts.AddHost, - CgroupParent: options.CommonBuildOpts.CgroupParent, - CpuPeriod: int64(options.CommonBuildOpts.CPUPeriod), - CpuQuota: options.CommonBuildOpts.CPUQuota, - CpuShares: int64(options.CommonBuildOpts.CPUShares), - CpusetCpus: options.CommonBuildOpts.CPUSetMems, - CpusetMems: options.CommonBuildOpts.CPUSetMems, - Memory: options.CommonBuildOpts.Memory, - MemorySwap: options.CommonBuildOpts.MemorySwap, - ShmSize: options.CommonBuildOpts.ShmSize, - Ulimit: options.CommonBuildOpts.Ulimit, - Volume: options.CommonBuildOpts.Volumes, - } - - buildinfo := iopodman.BuildInfo{ - AdditionalTags: options.AdditionalTags, - Annotations: options.Annotations, - BuildArgs: options.Args, - BuildOptions: buildOptions, - CniConfigDir: options.CNIConfigDir, - CniPluginDir: options.CNIPluginPath, - Compression: string(options.Compression), - DefaultsMountFilePath: options.DefaultMountsFilePath, - Dockerfiles: dockerfiles, - //Err: string(options.Err), - ForceRmIntermediateCtrs: options.ForceRmIntermediateCtrs, - Iidfile: options.IIDFile, - Label: options.Labels, - Layers: options.Layers, - Nocache: options.NoCache, - //Out: - Output: options.Output, - OutputFormat: options.OutputFormat, - PullPolicy: options.PullPolicy.String(), - Quiet: options.Quiet, - RemoteIntermediateCtrs: options.RemoveIntermediateCtrs, - //ReportWriter: - RuntimeArgs: options.RuntimeArgs, - SignaturePolicyPath: options.SignaturePolicyPath, - Squash: options.Squash, - } - // tar the file - outputFile, err := ioutil.TempFile("", "varlink_tar_send") - if err != nil { - return err - } - defer outputFile.Close() - defer os.Remove(outputFile.Name()) - - // Create the tarball of the context dir to a tempfile - if err := utils.TarToFilesystem(options.ContextDirectory, outputFile); err != nil { - return err - } - // Send the context dir tarball over varlink. - tempFile, err := r.SendFileOverVarlink(outputFile.Name()) - if err != nil { - return err - } - buildinfo.ContextDir = tempFile - - reply, err := iopodman.BuildImage().Send(r.Conn, varlink.More, buildinfo) - if err != nil { - return err - } - - for { - responses, flags, err := reply() - if err != nil { - return err - } - for _, line := range responses.Logs { - fmt.Print(line) - } - if flags&varlink.Continues == 0 { - break - } - } - return err -} - -// SendFileOverVarlink sends a file over varlink in an upgraded connection -func (r *LocalRuntime) SendFileOverVarlink(source string) (string, error) { - fs, err := os.Open(source) - if err != nil { - return "", err - } - - fileInfo, err := fs.Stat() - if err != nil { - return "", err - } - logrus.Debugf("sending %s over varlink connection", source) - reply, err := iopodman.SendFile().Send(r.Conn, varlink.Upgrade, "", int64(fileInfo.Size())) - if err != nil { - return "", err - } - _, _, err = reply() - if err != nil { - return "", err - } - - reader := bufio.NewReader(fs) - _, err = reader.WriteTo(r.Conn.Writer) - if err != nil { - return "", err - } - logrus.Debugf("file transfer complete for %s", source) - r.Conn.Writer.Flush() - - // All was sent, wait for the ACK from the server - tempFile, err := r.Conn.Reader.ReadString(':') - if err != nil { - return "", err - } - - // r.Conn is kaput at this point due to the upgrade - if err := r.RemoteRuntime.RefreshConnection(); err != nil { - return "", err - - } - - return strings.Replace(tempFile, ":", "", -1), nil -} - -// GetAllVolumes retrieves all the volumes -func (r *LocalRuntime) GetAllVolumes() ([]*libpod.Volume, error) { - return nil, libpod.ErrNotImplemented -} - -// RemoveVolume removes a volumes -func (r *LocalRuntime) RemoveVolume(ctx context.Context, v *libpod.Volume, force, prune bool) error { - return libpod.ErrNotImplemented -} - -// GetContainers retrieves all containers from the state -// Filters can be provided which will determine what containers are included in -// the output. Multiple filters are handled by ANDing their output, so only -// containers matching all filters are returned -func (r *LocalRuntime) GetContainers(filters ...libpod.ContainerFilter) ([]*libpod.Container, error) { - return nil, libpod.ErrNotImplemented -} - -// RemoveContainer removes the given container -// If force is specified, the container will be stopped first -// Otherwise, RemoveContainer will return an error if the container is running -func (r *LocalRuntime) RemoveContainer(ctx context.Context, c *libpod.Container, force, volumes bool) error { - return libpod.ErrNotImplemented -} - -// CreateVolume creates a volume over a varlink connection for the remote client -func (r *LocalRuntime) CreateVolume(ctx context.Context, c *cliconfig.VolumeCreateValues, labels, opts map[string]string) (string, error) { - cvOpts := iopodman.VolumeCreateOpts{ - Options: opts, - Labels: labels, - } - if len(c.InputArgs) > 0 { - cvOpts.VolumeName = c.InputArgs[0] - } - - if c.Flag("driver").Changed { - cvOpts.Driver = c.Driver - } - - return iopodman.VolumeCreate().Call(r.Conn, cvOpts) -} - -// RemoveVolumes removes volumes over a varlink connection for the remote client -func (r *LocalRuntime) RemoveVolumes(ctx context.Context, c *cliconfig.VolumeRmValues) ([]string, error) { - rmOpts := iopodman.VolumeRemoveOpts{ - All: c.All, - Force: c.Force, - Volumes: c.InputArgs, - } - return iopodman.VolumeRemove().Call(r.Conn, rmOpts) -} - -func (r *LocalRuntime) Push(ctx context.Context, srcName, destination, manifestMIMEType, authfile, signaturePolicyPath string, writer io.Writer, forceCompress bool, signingOptions image.SigningOptions, dockerRegistryOptions *image.DockerRegistryOptions, additionalDockerArchiveTags []reference.NamedTagged) error { - - var ( - tls *bool - tlsVerify bool - ) - if dockerRegistryOptions.DockerInsecureSkipTLSVerify == types.OptionalBoolTrue { - tlsVerify = false - tls = &tlsVerify - } - if dockerRegistryOptions.DockerInsecureSkipTLSVerify == types.OptionalBoolFalse { - tlsVerify = true - tls = &tlsVerify - } - - reply, err := iopodman.PushImage().Send(r.Conn, varlink.More, srcName, destination, tls, signaturePolicyPath, "", dockerRegistryOptions.DockerCertPath, forceCompress, manifestMIMEType, signingOptions.RemoveSignatures, signingOptions.SignBy) - if err != nil { - return err - } - for { - responses, flags, err := reply() - if err != nil { - return err - } - for _, line := range responses.Logs { - fmt.Print(line) - } - if flags&varlink.Continues == 0 { - break - } - } - - return err -} - -// InspectVolumes returns a slice of volumes based on an arg list or --all -func (r *LocalRuntime) InspectVolumes(ctx context.Context, c *cliconfig.VolumeInspectValues) ([]*Volume, error) { - reply, err := iopodman.GetVolumes().Call(r.Conn, c.InputArgs, c.All) - if err != nil { - return nil, err - } - return varlinkVolumeToVolume(r, reply), nil -} - -//Volumes returns a slice of adapter.volumes based on information about libpod -// volumes over a varlink connection -func (r *LocalRuntime) Volumes(ctx context.Context) ([]*Volume, error) { - reply, err := iopodman.GetVolumes().Call(r.Conn, []string{}, true) - if err != nil { - return nil, err - } - return varlinkVolumeToVolume(r, reply), nil -} - -func varlinkVolumeToVolume(r *LocalRuntime, volumes []iopodman.Volume) []*Volume { - var vols []*Volume - for _, v := range volumes { - volumeConfig := libpod.VolumeConfig{ - Name: v.Name, - Labels: v.Labels, - MountPoint: v.MountPoint, - Driver: v.Driver, - Options: v.Options, - Scope: v.Scope, - } - n := remoteVolume{ - Runtime: r, - config: &volumeConfig, - } - newVol := Volume{ - n, - } - vols = append(vols, &newVol) - } - return vols -} - -// PruneVolumes removes all unused volumes from the remote system -func (r *LocalRuntime) PruneVolumes(ctx context.Context) ([]string, []error) { - var errs []error - prunedNames, prunedErrors, err := iopodman.VolumesPrune().Call(r.Conn) - if err != nil { - return []string{}, []error{err} - } - // We need to transform the string results of the error into actual error types - for _, e := range prunedErrors { - errs = append(errs, errors.New(e)) - } - return prunedNames, errs -} - -// SaveImage is a wrapper function for saving an image to the local filesystem -func (r *LocalRuntime) SaveImage(ctx context.Context, c *cliconfig.SaveValues) error { - source := c.InputArgs[0] - additionalTags := c.InputArgs[1:] - - options := iopodman.ImageSaveOptions{ - Name: source, - Format: c.Format, - Output: c.Output, - MoreTags: additionalTags, - Quiet: c.Quiet, - Compress: c.Compress, - } - reply, err := iopodman.ImageSave().Send(r.Conn, varlink.More, options) - if err != nil { - return err - } - - var fetchfile string - for { - responses, flags, err := reply() - if err != nil { - return err - } - if len(responses.Id) > 0 { - fetchfile = responses.Id - } - for _, line := range responses.Logs { - fmt.Print(line) - } - if flags&varlink.Continues == 0 { - break - } - - } - if err != nil { - return err - } - - outputToDir := false - outfile := c.Output - var outputFile *os.File - // If the result is supposed to be a dir, then we need to put the tarfile - // from the host in a temporary file - if options.Format != "oci-archive" && options.Format != "docker-archive" { - outputToDir = true - outputFile, err = ioutil.TempFile("", "saveimage_tempfile") - if err != nil { - return err - } - outfile = outputFile.Name() - defer outputFile.Close() - defer os.Remove(outputFile.Name()) - } - // We now need to fetch the tarball result back to the more system - if err := r.GetFileFromRemoteHost(fetchfile, outfile, true); err != nil { - return err - } - - // If the result is a tarball, we're done - // If it is a dir, we need to untar the temporary file into the dir - if outputToDir { - if err := utils.UntarToFileSystem(c.Output, outputFile, &archive.TarOptions{}); err != nil { - return err - } - } - return nil -} - -// LoadImage loads a container image from a remote client's filesystem -func (r *LocalRuntime) LoadImage(ctx context.Context, name string, cli *cliconfig.LoadValues) (string, error) { - var names string - remoteTempFile, err := r.SendFileOverVarlink(cli.Input) - if err != nil { - return "", nil - } - more := varlink.More - if cli.Quiet { - more = 0 - } - reply, err := iopodman.LoadImage().Send(r.Conn, uint64(more), name, remoteTempFile, cli.Quiet, true) - if err != nil { - return "", err - } - - for { - responses, flags, err := reply() - if err != nil { - logrus.Error(err) - return "", err - } - for _, line := range responses.Logs { - fmt.Print(line) - } - names = responses.Id - if flags&varlink.Continues == 0 { - break - } - } - return names, nil -} diff --git a/libpod/adapter/shortcuts/shortcuts.go b/libpod/adapter/shortcuts/shortcuts.go deleted file mode 100644 index 0633399ae..000000000 --- a/libpod/adapter/shortcuts/shortcuts.go +++ /dev/null @@ -1,27 +0,0 @@ -package shortcuts - -import "github.com/containers/libpod/libpod" - -// GetPodsByContext gets pods whether all, latest, or a slice of names/ids -func GetPodsByContext(all, latest bool, pods []string, runtime *libpod.Runtime) ([]*libpod.Pod, error) { - var outpods []*libpod.Pod - if all { - return runtime.GetAllPods() - } - if latest { - p, err := runtime.GetLatestPod() - if err != nil { - return nil, err - } - outpods = append(outpods, p) - return outpods, nil - } - for _, p := range pods { - pod, err := runtime.LookupPod(p) - if err != nil { - return nil, err - } - outpods = append(outpods, pod) - } - return outpods, nil -} diff --git a/libpod/adapter/volumes_remote.go b/libpod/adapter/volumes_remote.go deleted file mode 100644 index beacd943a..000000000 --- a/libpod/adapter/volumes_remote.go +++ /dev/null @@ -1,33 +0,0 @@ -// +build remoteclient - -package adapter - -// Name returns the name of the volume -func (v *Volume) Name() string { - return v.config.Name -} - -//Labels returns the labels for a volume -func (v *Volume) Labels() map[string]string { - return v.config.Labels -} - -// Driver returns the driver for the volume -func (v *Volume) Driver() string { - return v.config.Driver -} - -// Options returns the options a volume was created with -func (v *Volume) Options() map[string]string { - return v.config.Options -} - -// MountPath returns the path the volume is mounted to -func (v *Volume) MountPoint() string { - return v.config.MountPoint -} - -// Scope returns the scope for an adapter.volume -func (v *Volume) Scope() string { - return v.config.Scope -} -- cgit v1.2.3-54-g00ecf