summaryrefslogtreecommitdiff
path: root/pkg/adapter/runtime.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/adapter/runtime.go')
-rw-r--r--pkg/adapter/runtime.go335
1 files changed, 335 insertions, 0 deletions
diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go
new file mode 100644
index 000000000..4f5b98dbb
--- /dev/null
+++ b/pkg/adapter/runtime.go
@@ -0,0 +1,335 @@
+// +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)
+}