summaryrefslogtreecommitdiff
path: root/pkg/domain
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/domain')
-rw-r--r--pkg/domain/entities/containers.go10
-rw-r--r--pkg/domain/entities/engine_container.go4
-rw-r--r--pkg/domain/entities/images.go22
-rw-r--r--pkg/domain/infra/abi/cp.go439
-rw-r--r--pkg/domain/infra/abi/generate.go54
-rw-r--r--pkg/domain/infra/abi/images.go154
-rw-r--r--pkg/domain/infra/abi/images_list.go13
-rw-r--r--pkg/domain/infra/abi/system.go17
-rw-r--r--pkg/domain/infra/tunnel/containers.go4
-rw-r--r--pkg/domain/infra/tunnel/generate.go4
10 files changed, 183 insertions, 538 deletions
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index 3fd7c79f4..39d679eaf 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -403,16 +403,14 @@ type ContainerPortReport struct {
Ports []ocicni.PortMapping
}
-// ContainerCpOptions describes input options for cp
+// ContainerCpOptions describes input options for cp.
type ContainerCpOptions struct {
- Pause bool
+ // Pause the container while copying.
+ Pause bool
+ // Extract the tarfile into the destination directory.
Extract bool
}
-// ContainerCpReport describes the output from a cp operation
-type ContainerCpReport struct {
-}
-
// ContainerStatsOptions describes input options for getting
// stats on containers
type ContainerStatsOptions struct {
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index a4f6c08e9..5ad475133 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -16,7 +16,7 @@ type ContainerEngine interface {
ContainerCheckpoint(ctx context.Context, namesOrIds []string, options CheckpointOptions) ([]*CheckpointReport, error)
ContainerCleanup(ctx context.Context, namesOrIds []string, options ContainerCleanupOptions) ([]*ContainerCleanupReport, error)
ContainerCommit(ctx context.Context, nameOrID string, options CommitOptions) (*CommitReport, error)
- ContainerCp(ctx context.Context, source, dest string, options ContainerCpOptions) (*ContainerCpReport, error)
+ ContainerCp(ctx context.Context, source, dest string, options ContainerCpOptions) error
ContainerCreate(ctx context.Context, s *specgen.SpecGenerator) (*ContainerCreateReport, error)
ContainerDiff(ctx context.Context, nameOrID string, options DiffOptions) (*DiffReport, error)
ContainerExec(ctx context.Context, nameOrID string, options ExecOptions, streams define.AttachStreams) (int, error)
@@ -46,7 +46,7 @@ type ContainerEngine interface {
ContainerWait(ctx context.Context, namesOrIds []string, options WaitOptions) ([]WaitReport, error)
Events(ctx context.Context, opts EventsOptions) error
GenerateSystemd(ctx context.Context, nameOrID string, opts GenerateSystemdOptions) (*GenerateSystemdReport, error)
- GenerateKube(ctx context.Context, nameOrID string, opts GenerateKubeOptions) (*GenerateKubeReport, error)
+ GenerateKube(ctx context.Context, nameOrIDs []string, opts GenerateKubeOptions) (*GenerateKubeReport, error)
SystemPrune(ctx context.Context, options SystemPruneOptions) (*SystemPruneReport, error)
HealthCheckRun(ctx context.Context, nameOrID string, options HealthCheckOptions) (*define.HealthCheckResults, error)
Info(ctx context.Context) (*define.Info, error)
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index ab545d882..81f12bff7 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -51,22 +51,22 @@ func (i *Image) Id() string { // nolint
}
type ImageSummary struct {
- ID string `json:"Id"`
- ParentId string // nolint
- RepoTags []string `json:",omitempty"`
+ ID string `json:"Id"`
+ ParentId string // nolint
+ RepoTags []string
+ RepoDigests []string
Created int64
- Size int64 `json:",omitempty"`
- SharedSize int `json:",omitempty"`
- VirtualSize int64 `json:",omitempty"`
- Labels map[string]string `json:",omitempty"`
- Containers int `json:",omitempty"`
- ReadOnly bool `json:",omitempty"`
- Dangling bool `json:",omitempty"`
+ Size int64
+ SharedSize int
+ VirtualSize int64
+ Labels map[string]string
+ Containers int
+ ReadOnly bool `json:",omitempty"`
+ Dangling bool `json:",omitempty"`
// Podman extensions
Names []string `json:",omitempty"`
Digest string `json:",omitempty"`
- Digests []string `json:",omitempty"`
ConfigDigest string `json:",omitempty"`
History []string `json:",omitempty"`
}
diff --git a/pkg/domain/infra/abi/cp.go b/pkg/domain/infra/abi/cp.go
index 8f4f5d3d7..9409df743 100644
--- a/pkg/domain/infra/abi/cp.go
+++ b/pkg/domain/infra/abi/cp.go
@@ -1,195 +1,70 @@
package abi
import (
- "archive/tar"
"context"
- "fmt"
- "io"
- "os"
- "path/filepath"
"strings"
- "github.com/containers/buildah/pkg/chrootuser"
- "github.com/containers/buildah/util"
"github.com/containers/podman/v2/libpod"
- "github.com/containers/podman/v2/libpod/define"
+ "github.com/containers/podman/v2/pkg/copy"
"github.com/containers/podman/v2/pkg/domain/entities"
- "github.com/containers/storage"
- "github.com/containers/storage/pkg/chrootarchive"
- "github.com/containers/storage/pkg/idtools"
- securejoin "github.com/cyphar/filepath-securejoin"
- "github.com/docker/docker/pkg/archive"
- "github.com/opencontainers/go-digest"
- "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
- "github.com/sirupsen/logrus"
)
-func (ic *ContainerEngine) ContainerCp(ctx context.Context, source, dest string, options entities.ContainerCpOptions) (*entities.ContainerCpReport, error) {
- extract := options.Extract
-
+func (ic *ContainerEngine) ContainerCp(ctx context.Context, source, dest string, options entities.ContainerCpOptions) error {
srcCtr, srcPath := parsePath(ic.Libpod, source)
destCtr, destPath := parsePath(ic.Libpod, dest)
- if (srcCtr == nil && destCtr == nil) || (srcCtr != nil && destCtr != nil) {
- return nil, errors.Errorf("invalid arguments %s, %s you must use just one container", source, dest)
+ if srcCtr != nil && destCtr != nil {
+ return errors.Errorf("invalid arguments %q, %q: you must use just one container", source, dest)
}
-
- if len(srcPath) == 0 || len(destPath) == 0 {
- return nil, errors.Errorf("invalid arguments %s, %s you must specify paths", source, dest)
+ if srcCtr == nil && destCtr == nil {
+ return errors.Errorf("invalid arguments %q, %q: you must specify one container", source, dest)
}
- ctr := srcCtr
- isFromHostToCtr := ctr == nil
- if isFromHostToCtr {
- ctr = destCtr
+ if len(srcPath) == 0 || len(destPath) == 0 {
+ return errors.Errorf("invalid arguments %q, %q: you must specify paths", source, dest)
}
- mountPoint, err := ctr.Mount()
- if err != nil {
- return nil, err
- }
- defer func() {
- if err := ctr.Unmount(false); err != nil {
- logrus.Errorf("unable to umount container '%s': %q", ctr.ID(), err)
+ var sourceItem, destinationItem copy.CopyItem
+ var err error
+ // Copy from the container to the host.
+ if srcCtr != nil {
+ sourceItem, err = copy.CopyItemForContainer(srcCtr, srcPath, options.Pause, true)
+ defer sourceItem.CleanUp()
+ if err != nil {
+ return err
}
- }()
-
- if options.Pause {
- if err := ctr.Pause(); err != nil {
- // An invalid state error is fine.
- // The container isn't running or is already paused.
- // TODO: We can potentially start the container while
- // the copy is running, which still allows a race where
- // malicious code could mess with the symlink.
- if errors.Cause(err) != define.ErrCtrStateInvalid {
- return nil, err
- }
- } else {
- // Only add the defer if we actually paused
- defer func() {
- if err := ctr.Unpause(); err != nil {
- logrus.Errorf("Error unpausing container after copying: %v", err)
- }
- }()
+ } else {
+ sourceItem, err = copy.CopyItemForHost(srcPath, true)
+ if err != nil {
+ return err
}
}
- user, err := getUser(mountPoint, ctr.User())
- if err != nil {
- return nil, err
- }
- idMappingOpts, err := ctr.IDMappings()
- if err != nil {
- return nil, errors.Wrapf(err, "error getting IDMappingOptions")
- }
- destOwner := idtools.IDPair{UID: int(user.UID), GID: int(user.GID)}
- hostUID, hostGID, err := util.GetHostIDs(convertIDMap(idMappingOpts.UIDMap), convertIDMap(idMappingOpts.GIDMap), user.UID, user.GID)
- if err != nil {
- return nil, err
- }
-
- hostOwner := idtools.IDPair{UID: int(hostUID), GID: int(hostGID)}
-
- if isFromHostToCtr {
- if isVol, volDestName, volName := isVolumeDestName(destPath, ctr); isVol { //nolint(gocritic)
- path, err := pathWithVolumeMount(ic.Libpod, volDestName, volName, destPath)
- if err != nil {
- return nil, errors.Wrapf(err, "error getting destination path from volume %s", volDestName)
- }
- destPath = path
- } else if isBindMount, mount := isBindMountDestName(destPath, ctr); isBindMount { //nolint(gocritic)
- path, err := pathWithBindMountSource(mount, destPath)
- if err != nil {
- return nil, errors.Wrapf(err, "error getting destination path from bind mount %s", mount.Destination)
- }
- destPath = path
- } else if filepath.IsAbs(destPath) { //nolint(gocritic)
- cleanedPath, err := securejoin.SecureJoin(mountPoint, destPath)
- if err != nil {
- return nil, err
- }
- destPath = cleanedPath
- } else { //nolint(gocritic)
- ctrWorkDir, err := securejoin.SecureJoin(mountPoint, ctr.WorkingDir())
- if err != nil {
- return nil, err
- }
- if err = idtools.MkdirAllAndChownNew(ctrWorkDir, 0755, hostOwner); err != nil {
- return nil, err
- }
- cleanedPath, err := securejoin.SecureJoin(mountPoint, filepath.Join(ctr.WorkingDir(), destPath))
- if err != nil {
- return nil, err
- }
- destPath = cleanedPath
+ if destCtr != nil {
+ destinationItem, err = copy.CopyItemForContainer(destCtr, destPath, options.Pause, false)
+ defer destinationItem.CleanUp()
+ if err != nil {
+ return err
}
} else {
- destOwner = idtools.IDPair{UID: os.Getuid(), GID: os.Getgid()}
- if isVol, volDestName, volName := isVolumeDestName(srcPath, ctr); isVol { //nolint(gocritic)
- path, err := pathWithVolumeMount(ic.Libpod, volDestName, volName, srcPath)
- if err != nil {
- return nil, errors.Wrapf(err, "error getting source path from volume %s", volDestName)
- }
- srcPath = path
- } else if isBindMount, mount := isBindMountDestName(srcPath, ctr); isBindMount { //nolint(gocritic)
- path, err := pathWithBindMountSource(mount, srcPath)
- if err != nil {
- return nil, errors.Wrapf(err, "error getting source path from bind mount %s", mount.Destination)
- }
- srcPath = path
- } else if filepath.IsAbs(srcPath) { //nolint(gocritic)
- cleanedPath, err := securejoin.SecureJoin(mountPoint, srcPath)
- if err != nil {
- return nil, err
- }
- srcPath = cleanedPath
- } else { //nolint(gocritic)
- cleanedPath, err := securejoin.SecureJoin(mountPoint, filepath.Join(ctr.WorkingDir(), srcPath))
- if err != nil {
- return nil, err
- }
- srcPath = cleanedPath
- }
- }
-
- if !filepath.IsAbs(destPath) {
- dir, err := os.Getwd()
+ destinationItem, err = copy.CopyItemForHost(destPath, false)
+ defer destinationItem.CleanUp()
if err != nil {
- return nil, errors.Wrapf(err, "err getting current working directory")
+ return err
}
- destPath = filepath.Join(dir, destPath)
}
- if source == "-" {
- srcPath = os.Stdin.Name()
- extract = true
- }
- err = containerCopy(srcPath, destPath, source, dest, idMappingOpts, &destOwner, extract, isFromHostToCtr)
- return &entities.ContainerCpReport{}, err
+ // Copy from the host to the container.
+ return copy.Copy(&sourceItem, &destinationItem, options.Extract)
}
-func getUser(mountPoint string, userspec string) (specs.User, error) {
- uid, gid, _, err := chrootuser.GetUser(mountPoint, userspec)
- u := specs.User{
- UID: uid,
- GID: gid,
- Username: userspec,
+func parsePath(runtime *libpod.Runtime, path string) (*libpod.Container, string) {
+ if len(path) == 0 {
+ return nil, ""
}
- if !strings.Contains(userspec, ":") {
- groups, err2 := chrootuser.GetAdditionalGroupsForUser(mountPoint, uint64(u.UID))
- if err2 != nil {
- if errors.Cause(err2) != chrootuser.ErrNoSuchUser && err == nil {
- err = err2
- }
- } else {
- u.AdditionalGids = groups
- }
-
+ if path[0] == '.' || path[0] == '/' { // A path cannot point to a container.
+ return nil, path
}
- return u, err
-}
-
-func parsePath(runtime *libpod.Runtime, path string) (*libpod.Container, string) {
pathArr := strings.SplitN(path, ":", 2)
if len(pathArr) == 2 {
ctr, err := runtime.LookupContainer(pathArr[0])
@@ -199,247 +74,3 @@ func parsePath(runtime *libpod.Runtime, path string) (*libpod.Container, string)
}
return nil, path
}
-
-func evalSymlinks(path string) (string, error) {
- if path == os.Stdin.Name() {
- return path, nil
- }
- return filepath.EvalSymlinks(path)
-}
-
-func getPathInfo(path string) (string, os.FileInfo, error) {
- path, err := evalSymlinks(path)
- if err != nil {
- return "", nil, errors.Wrapf(err, "error evaluating symlinks %q", path)
- }
- srcfi, err := os.Stat(path)
- if err != nil {
- return "", nil, err
- }
- return path, srcfi, nil
-}
-
-func containerCopy(srcPath, destPath, src, dest string, idMappingOpts storage.IDMappingOptions, chownOpts *idtools.IDPair, extract, isFromHostToCtr bool) error {
- srcPath, err := evalSymlinks(srcPath)
- if err != nil {
- return errors.Wrapf(err, "error evaluating symlinks %q", srcPath)
- }
-
- srcPath, srcfi, err := getPathInfo(srcPath)
- if err != nil {
- return err
- }
-
- filename := filepath.Base(destPath)
- if filename == "-" && !isFromHostToCtr {
- err := streamFileToStdout(srcPath, srcfi)
- if err != nil {
- return errors.Wrapf(err, "error streaming source file %s to Stdout", srcPath)
- }
- return nil
- }
-
- destdir := destPath
- if !srcfi.IsDir() {
- destdir = filepath.Dir(destPath)
- }
- _, err = os.Stat(destdir)
- if err != nil && !os.IsNotExist(err) {
- return err
- }
- destDirIsExist := err == nil
- if err = os.MkdirAll(destdir, 0755); err != nil {
- return err
- }
-
- // return functions for copying items
- copyFileWithTar := chrootarchive.CopyFileWithTarAndChown(chownOpts, digest.Canonical.Digester().Hash(), idMappingOpts.UIDMap, idMappingOpts.GIDMap)
- copyWithTar := chrootarchive.CopyWithTarAndChown(chownOpts, digest.Canonical.Digester().Hash(), idMappingOpts.UIDMap, idMappingOpts.GIDMap)
- untarPath := chrootarchive.UntarPathAndChown(chownOpts, digest.Canonical.Digester().Hash(), idMappingOpts.UIDMap, idMappingOpts.GIDMap)
-
- if srcfi.IsDir() {
- logrus.Debugf("copying %q to %q", srcPath+string(os.PathSeparator)+"*", dest+string(os.PathSeparator)+"*")
- if destDirIsExist && !strings.HasSuffix(src, fmt.Sprintf("%s.", string(os.PathSeparator))) {
- srcPathBase := filepath.Base(srcPath)
- if !isFromHostToCtr {
- pathArr := strings.SplitN(src, ":", 2)
- if len(pathArr) != 2 {
- return errors.Errorf("invalid arguments %s, you must specify source path", src)
- }
- if pathArr[1] == "/" {
- // If `srcPath` is the root directory of the container,
- // `srcPath` will be `.../${sha256_ID}/merged/`, so do not join it
- srcPathBase = ""
- }
- }
- destPath = filepath.Join(destPath, srcPathBase)
- }
- if err = copyWithTar(srcPath, destPath); err != nil {
- return errors.Wrapf(err, "error copying %q to %q", srcPath, dest)
- }
- return nil
- }
-
- if extract {
- // We're extracting an archive into the destination directory.
- logrus.Debugf("extracting contents of %q into %q", srcPath, destPath)
- if err = untarPath(srcPath, destPath); err != nil {
- return errors.Wrapf(err, "error extracting %q into %q", srcPath, destPath)
- }
- return nil
- }
-
- destfi, err := os.Stat(destPath)
- if err != nil {
- if !os.IsNotExist(err) || strings.HasSuffix(dest, string(os.PathSeparator)) {
- return err
- }
- }
- if destfi != nil && destfi.IsDir() {
- destPath = filepath.Join(destPath, filepath.Base(srcPath))
- }
-
- // Copy the file, preserving attributes.
- logrus.Debugf("copying %q to %q", srcPath, destPath)
- if err = copyFileWithTar(srcPath, destPath); err != nil {
- return errors.Wrapf(err, "error copying %q to %q", srcPath, destPath)
- }
- return nil
-}
-
-func convertIDMap(idMaps []idtools.IDMap) (convertedIDMap []specs.LinuxIDMapping) {
- for _, idmap := range idMaps {
- tempIDMap := specs.LinuxIDMapping{
- ContainerID: uint32(idmap.ContainerID),
- HostID: uint32(idmap.HostID),
- Size: uint32(idmap.Size),
- }
- convertedIDMap = append(convertedIDMap, tempIDMap)
- }
- return convertedIDMap
-}
-
-func streamFileToStdout(srcPath string, srcfi os.FileInfo) error {
- if srcfi.IsDir() {
- tw := tar.NewWriter(os.Stdout)
- err := filepath.Walk(srcPath, func(path string, info os.FileInfo, err error) error {
- if err != nil || !info.Mode().IsRegular() || path == srcPath {
- return err
- }
- hdr, err := tar.FileInfoHeader(info, "")
- if err != nil {
- return err
- }
-
- if err = tw.WriteHeader(hdr); err != nil {
- return err
- }
- fh, err := os.Open(path)
- if err != nil {
- return err
- }
- defer fh.Close()
-
- _, err = io.Copy(tw, fh)
- return err
- })
- if err != nil {
- return errors.Wrapf(err, "error streaming directory %s to Stdout", srcPath)
- }
- return nil
- }
-
- file, err := os.Open(srcPath)
- if err != nil {
- return err
- }
- defer file.Close()
- if !archive.IsArchivePath(srcPath) {
- tw := tar.NewWriter(os.Stdout)
- hdr, err := tar.FileInfoHeader(srcfi, "")
- if err != nil {
- return err
- }
- err = tw.WriteHeader(hdr)
- if err != nil {
- return err
- }
- _, err = io.Copy(tw, file)
- if err != nil {
- return errors.Wrapf(err, "error streaming archive %s to Stdout", srcPath)
- }
- return nil
- }
-
- _, err = io.Copy(os.Stdout, file)
- if err != nil {
- return errors.Wrapf(err, "error streaming file to Stdout")
- }
- return nil
-}
-
-func isVolumeDestName(path string, ctr *libpod.Container) (bool, string, string) {
- separator := string(os.PathSeparator)
- if filepath.IsAbs(path) {
- path = strings.TrimPrefix(path, separator)
- }
- if path == "" {
- return false, "", ""
- }
- for _, vol := range ctr.Config().NamedVolumes {
- volNamePath := strings.TrimPrefix(vol.Dest, separator)
- if matchVolumePath(path, volNamePath) {
- return true, vol.Dest, vol.Name
- }
- }
- return false, "", ""
-}
-
-// if SRCPATH or DESTPATH is from volume mount's destination -v or --mount type=volume, generates the path with volume mount point
-func pathWithVolumeMount(runtime *libpod.Runtime, volDestName, volName, path string) (string, error) {
- destVolume, err := runtime.GetVolume(volName)
- if err != nil {
- return "", errors.Wrapf(err, "error getting volume destination %s", volName)
- }
- if !filepath.IsAbs(path) {
- path = filepath.Join(string(os.PathSeparator), path)
- }
- path, err = securejoin.SecureJoin(destVolume.MountPoint(), strings.TrimPrefix(path, volDestName))
- return path, err
-}
-
-func isBindMountDestName(path string, ctr *libpod.Container) (bool, specs.Mount) {
- separator := string(os.PathSeparator)
- if filepath.IsAbs(path) {
- path = strings.TrimPrefix(path, string(os.PathSeparator))
- }
- if path == "" {
- return false, specs.Mount{}
- }
- for _, m := range ctr.Config().Spec.Mounts {
- if m.Type != "bind" {
- continue
- }
- mDest := strings.TrimPrefix(m.Destination, separator)
- if matchVolumePath(path, mDest) {
- return true, m
- }
- }
- return false, specs.Mount{}
-}
-
-func matchVolumePath(path, target string) bool {
- pathStr := filepath.Clean(path)
- target = filepath.Clean(target)
- for len(pathStr) > len(target) && strings.Contains(pathStr, string(os.PathSeparator)) {
- pathStr = pathStr[:strings.LastIndex(pathStr, string(os.PathSeparator))]
- }
- return pathStr == target
-}
-
-func pathWithBindMountSource(m specs.Mount, path string) (string, error) {
- if !filepath.IsAbs(path) {
- path = filepath.Join(string(os.PathSeparator), path)
- }
- return securejoin.SecureJoin(m.Source, strings.TrimPrefix(path, m.Destination))
-}
diff --git a/pkg/domain/infra/abi/generate.go b/pkg/domain/infra/abi/generate.go
index 79bf2291e..79f55e2bd 100644
--- a/pkg/domain/infra/abi/generate.go
+++ b/pkg/domain/infra/abi/generate.go
@@ -41,28 +41,48 @@ func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string,
return &entities.GenerateSystemdReport{Units: units}, nil
}
-func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrID string, options entities.GenerateKubeOptions) (*entities.GenerateKubeReport, error) {
+func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string, options entities.GenerateKubeOptions) (*entities.GenerateKubeReport, error) {
var (
- pod *libpod.Pod
+ pods []*libpod.Pod
podYAML *k8sAPI.Pod
err error
- ctr *libpod.Container
+ ctrs []*libpod.Container
servicePorts []k8sAPI.ServicePort
serviceYAML k8sAPI.Service
)
- // Get the container in question.
- ctr, err = ic.Libpod.LookupContainer(nameOrID)
- if err != nil {
- pod, err = ic.Libpod.LookupPod(nameOrID)
+ for _, nameOrID := range nameOrIDs {
+ // Get the container in question
+ ctr, err := ic.Libpod.LookupContainer(nameOrID)
if err != nil {
- return nil, err
+ pod, err := ic.Libpod.LookupPod(nameOrID)
+ if err != nil {
+ return nil, err
+ }
+ pods = append(pods, pod)
+ if len(pods) > 1 {
+ return nil, errors.New("can only generate single pod at a time")
+ }
+ } else {
+ if len(ctr.Dependencies()) > 0 {
+ return nil, errors.Wrapf(define.ErrNotImplemented, "containers with dependencies")
+ }
+ // we cannot deal with ctrs already in a pod
+ if len(ctr.PodID()) > 0 {
+ return nil, errors.Errorf("container %s is associated with pod %s: use generate on the pod itself", ctr.ID(), ctr.PodID())
+ }
+ ctrs = append(ctrs, ctr)
}
- podYAML, servicePorts, err = pod.GenerateForKube()
+ }
+
+ // check our inputs
+ if len(pods) > 0 && len(ctrs) > 0 {
+ return nil, errors.New("cannot generate pods and containers at the same time")
+ }
+
+ if len(pods) == 1 {
+ podYAML, servicePorts, err = pods[0].GenerateForKube()
} else {
- if len(ctr.Dependencies()) > 0 {
- return nil, errors.Wrapf(define.ErrNotImplemented, "containers with dependencies")
- }
- podYAML, err = ctr.GenerateForKube()
+ podYAML, err = libpod.GenerateForKube(ctrs)
}
if err != nil {
return nil, err
@@ -72,7 +92,7 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrID string, op
serviceYAML = libpod.GenerateKubeServiceFromV1Pod(podYAML, servicePorts)
}
- content, err := generateKubeOutput(podYAML, &serviceYAML)
+ content, err := generateKubeOutput(podYAML, &serviceYAML, options.Service)
if err != nil {
return nil, err
}
@@ -80,7 +100,7 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrID string, op
return &entities.GenerateKubeReport{Reader: bytes.NewReader(content)}, nil
}
-func generateKubeOutput(podYAML *k8sAPI.Pod, serviceYAML *k8sAPI.Service) ([]byte, error) {
+func generateKubeOutput(podYAML *k8sAPI.Pod, serviceYAML *k8sAPI.Service, hasService bool) ([]byte, error) {
var (
output []byte
marshalledPod []byte
@@ -93,7 +113,7 @@ func generateKubeOutput(podYAML *k8sAPI.Pod, serviceYAML *k8sAPI.Service) ([]byt
return nil, err
}
- if serviceYAML != nil {
+ if hasService {
marshalledService, err = yaml.Marshal(serviceYAML)
if err != nil {
return nil, err
@@ -114,7 +134,7 @@ func generateKubeOutput(podYAML *k8sAPI.Pod, serviceYAML *k8sAPI.Service) ([]byt
output = append(output, []byte(fmt.Sprintf(header, podmanVersion.Version))...)
output = append(output, marshalledPod...)
- if serviceYAML != nil {
+ if hasService {
output = append(output, []byte("---\n")...)
output = append(output, marshalledService...)
}
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 1b523f06a..57a2bc4cf 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -26,7 +26,6 @@ import (
"github.com/containers/podman/v2/pkg/domain/entities"
domainUtils "github.com/containers/podman/v2/pkg/domain/utils"
"github.com/containers/podman/v2/pkg/rootless"
- "github.com/containers/podman/v2/pkg/trust"
"github.com/containers/podman/v2/pkg/util"
"github.com/containers/storage"
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
@@ -34,9 +33,6 @@ import (
"github.com/sirupsen/logrus"
)
-// SignatureStoreDir defines default directory to store signatures
-const SignatureStoreDir = "/var/lib/containers/sigstore"
-
func (ir *ImageEngine) Exists(_ context.Context, nameOrID string) (*entities.BoolReport, error) {
_, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrID)
if err != nil {
@@ -707,90 +703,79 @@ func (ir *ImageEngine) Sign(ctx context.Context, names []string, options entitie
sc := ir.Libpod.SystemContext()
sc.DockerCertPath = options.CertDir
- systemRegistriesDirPath := trust.RegistriesDirPath(sc)
- registryConfigs, err := trust.LoadAndMergeConfig(systemRegistriesDirPath)
- if err != nil {
- return nil, errors.Wrapf(err, "error reading registry configuration")
- }
-
for _, signimage := range names {
- srcRef, err := alltransports.ParseImageName(signimage)
- if err != nil {
- return nil, errors.Wrapf(err, "error parsing image name")
- }
- rawSource, err := srcRef.NewImageSource(ctx, sc)
- if err != nil {
- return nil, errors.Wrapf(err, "error getting image source")
- }
- err = rawSource.Close()
- if err != nil {
- logrus.Errorf("unable to close new image source %q", err)
- }
- getManifest, _, err := rawSource.GetManifest(ctx, nil)
- if err != nil {
- return nil, errors.Wrapf(err, "error getting getManifest")
- }
- dockerReference := rawSource.Reference().DockerReference()
- if dockerReference == nil {
- return nil, errors.Errorf("cannot determine canonical Docker reference for destination %s", transports.ImageName(rawSource.Reference()))
- }
- var sigStoreDir string
- if options.Directory != "" {
- sigStoreDir = options.Directory
- }
- if sigStoreDir == "" {
- if rootless.IsRootless() {
- sigStoreDir = filepath.Join(filepath.Dir(ir.Libpod.StorageConfig().GraphRoot), "sigstore")
- } else {
- var sigStoreURI string
- registryInfo := trust.HaveMatchRegistry(rawSource.Reference().DockerReference().String(), registryConfigs)
- if registryInfo != nil {
- if sigStoreURI = registryInfo.SigStoreStaging; sigStoreURI == "" {
- sigStoreURI = registryInfo.SigStore
- }
+ err = func() error {
+ srcRef, err := alltransports.ParseImageName(signimage)
+ if err != nil {
+ return errors.Wrapf(err, "error parsing image name")
+ }
+ rawSource, err := srcRef.NewImageSource(ctx, sc)
+ if err != nil {
+ return errors.Wrapf(err, "error getting image source")
+ }
+ defer func() {
+ if err = rawSource.Close(); err != nil {
+ logrus.Errorf("unable to close %s image source %q", srcRef.DockerReference().Name(), err)
}
- if sigStoreURI == "" {
- return nil, errors.Errorf("no signature storage configuration found for %s", rawSource.Reference().DockerReference().String())
-
+ }()
+ getManifest, _, err := rawSource.GetManifest(ctx, nil)
+ if err != nil {
+ return errors.Wrapf(err, "error getting getManifest")
+ }
+ dockerReference := rawSource.Reference().DockerReference()
+ if dockerReference == nil {
+ return errors.Errorf("cannot determine canonical Docker reference for destination %s", transports.ImageName(rawSource.Reference()))
+ }
+ var sigStoreDir string
+ if options.Directory != "" {
+ repo := reference.Path(dockerReference)
+ if path.Clean(repo) != repo { // Coverage: This should not be reachable because /./ and /../ components are not valid in docker references
+ return errors.Errorf("Unexpected path elements in Docker reference %s for signature storage", dockerReference.String())
+ }
+ sigStoreDir = filepath.Join(options.Directory, repo)
+ } else {
+ signatureURL, err := docker.SignatureStorageBaseURL(sc, rawSource.Reference(), true)
+ if err != nil {
+ return err
}
- sigStoreDir, err = localPathFromURI(sigStoreURI)
+ sigStoreDir, err = localPathFromURI(signatureURL)
if err != nil {
- return nil, errors.Wrapf(err, "invalid signature storage %s", sigStoreURI)
+ return err
}
}
- }
- manifestDigest, err := manifest.Digest(getManifest)
- if err != nil {
- return nil, err
- }
- repo := reference.Path(dockerReference)
- if path.Clean(repo) != repo { // Coverage: This should not be reachable because /./ and /../ components are not valid in docker references
- return nil, errors.Errorf("Unexpected path elements in Docker reference %s for signature storage", dockerReference.String())
- }
+ manifestDigest, err := manifest.Digest(getManifest)
+ if err != nil {
+ return err
+ }
- // create signature
- newSig, err := signature.SignDockerManifest(getManifest, dockerReference.String(), mech, options.SignBy)
- if err != nil {
- return nil, errors.Wrapf(err, "error creating new signature")
- }
- // create the signstore file
- signatureDir := fmt.Sprintf("%s@%s=%s", filepath.Join(sigStoreDir, repo), manifestDigest.Algorithm(), manifestDigest.Hex())
- if err := os.MkdirAll(signatureDir, 0751); err != nil {
- // The directory is allowed to exist
- if !os.IsExist(err) {
- logrus.Error(err)
- continue
+ // create signature
+ newSig, err := signature.SignDockerManifest(getManifest, dockerReference.String(), mech, options.SignBy)
+ if err != nil {
+ return errors.Wrapf(err, "error creating new signature")
}
- }
- sigFilename, err := getSigFilename(signatureDir)
- if err != nil {
- logrus.Errorf("error creating sigstore file: %v", err)
- continue
- }
- err = ioutil.WriteFile(filepath.Join(signatureDir, sigFilename), newSig, 0644)
+ // create the signstore file
+ signatureDir := fmt.Sprintf("%s@%s=%s", sigStoreDir, manifestDigest.Algorithm(), manifestDigest.Hex())
+ if err := os.MkdirAll(signatureDir, 0751); err != nil {
+ // The directory is allowed to exist
+ if !os.IsExist(err) {
+ logrus.Error(err)
+ return nil
+ }
+ }
+ sigFilename, err := getSigFilename(signatureDir)
+ if err != nil {
+ logrus.Errorf("error creating sigstore file: %v", err)
+ return nil
+ }
+ err = ioutil.WriteFile(filepath.Join(signatureDir, sigFilename), newSig, 0644)
+ if err != nil {
+ logrus.Errorf("error storing signature for %s", rawSource.Reference().DockerReference().String())
+ return nil
+ }
+ return nil
+ }()
if err != nil {
- logrus.Errorf("error storing signature for %s", rawSource.Reference().DockerReference().String())
- continue
+ return nil, err
}
}
return nil, nil
@@ -815,14 +800,9 @@ func getSigFilename(sigStoreDirPath string) (string, error) {
}
}
-func localPathFromURI(sigStoreDir string) (string, error) {
- url, err := url.Parse(sigStoreDir)
- if err != nil {
- return sigStoreDir, errors.Wrapf(err, "invalid directory %s", sigStoreDir)
- }
+func localPathFromURI(url *url.URL) (string, error) {
if url.Scheme != "file" {
- return sigStoreDir, errors.Errorf("writing to %s is not supported. Use a supported scheme", sigStoreDir)
+ return "", errors.Errorf("writing to %s is not supported. Use a supported scheme", url.String())
}
- sigStoreDir = url.Path
- return sigStoreDir, nil
+ return url.Path, nil
}
diff --git a/pkg/domain/infra/abi/images_list.go b/pkg/domain/infra/abi/images_list.go
index 281b04294..c4b0b7712 100644
--- a/pkg/domain/infra/abi/images_list.go
+++ b/pkg/domain/infra/abi/images_list.go
@@ -35,13 +35,11 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions)
Created: img.Created().Unix(),
Dangling: img.Dangling(),
Digest: string(img.Digest()),
- Digests: digests,
+ RepoDigests: digests,
History: img.NamesHistory(),
Names: img.Names(),
- ParentId: img.Parent,
ReadOnly: img.IsReadOnly(),
SharedSize: 0,
- VirtualSize: img.VirtualSize,
RepoTags: img.Names(), // may include tags and digests
}
e.Labels, err = img.Labels(ctx)
@@ -60,6 +58,15 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions)
return nil, errors.Wrapf(err, "error retrieving size of image %q: you may need to remove the image to resolve the error", img.ID())
}
e.Size = int64(*sz)
+ // This is good enough for now, but has to be
+ // replaced later with correct calculation logic
+ e.VirtualSize = int64(*sz)
+
+ parent, err := img.ParentID(ctx)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error retrieving parent of image %q: you may need to remove the image to resolve the error", img.ID())
+ }
+ e.ParentId = parent
summaries = append(summaries, &e)
}
diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go
index 72fd98ac1..ec2532bea 100644
--- a/pkg/domain/infra/abi/system.go
+++ b/pkg/domain/infra/abi/system.go
@@ -11,6 +11,7 @@ import (
"strings"
"github.com/containers/common/pkg/config"
+ "github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/cgroups"
"github.com/containers/podman/v2/pkg/domain/entities"
@@ -86,7 +87,11 @@ func (ic *ContainerEngine) SetupRootless(_ context.Context, cmd *cobra.Command)
return nil
}
- pausePidPath, err := util.GetRootlessPauseProcessPidPath()
+ tmpDir, err := ic.Libpod.TmpDir()
+ if err != nil {
+ return err
+ }
+ pausePidPath, err := util.GetRootlessPauseProcessPidPathGivenDir(tmpDir)
if err != nil {
return errors.Wrapf(err, "could not get pause process pid file path")
}
@@ -112,7 +117,7 @@ func (ic *ContainerEngine) SetupRootless(_ context.Context, cmd *cobra.Command)
}
became, ret, err = rootless.TryJoinFromFilePaths(pausePidPath, true, paths)
- if err := movePauseProcessToScope(); err != nil {
+ if err := movePauseProcessToScope(ic.Libpod); err != nil {
conf, err := ic.Config(context.Background())
if err != nil {
return err
@@ -133,8 +138,12 @@ func (ic *ContainerEngine) SetupRootless(_ context.Context, cmd *cobra.Command)
return nil
}
-func movePauseProcessToScope() error {
- pausePidPath, err := util.GetRootlessPauseProcessPidPath()
+func movePauseProcessToScope(r *libpod.Runtime) error {
+ tmpDir, err := r.TmpDir()
+ if err != nil {
+ return err
+ }
+ pausePidPath, err := util.GetRootlessPauseProcessPidPathGivenDir(tmpDir)
if err != nil {
return errors.Wrapf(err, "could not get pause process pid file path")
}
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 63677719b..3584668c7 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -731,8 +731,8 @@ func (ic *ContainerEngine) ContainerPort(ctx context.Context, nameOrID string, o
return reports, nil
}
-func (ic *ContainerEngine) ContainerCp(ctx context.Context, source, dest string, options entities.ContainerCpOptions) (*entities.ContainerCpReport, error) {
- return nil, errors.New("not implemented")
+func (ic *ContainerEngine) ContainerCp(ctx context.Context, source, dest string, options entities.ContainerCpOptions) error {
+ return errors.New("not implemented")
}
// Shutdown Libpod engine
diff --git a/pkg/domain/infra/tunnel/generate.go b/pkg/domain/infra/tunnel/generate.go
index 966f707b1..ebbfa143f 100644
--- a/pkg/domain/infra/tunnel/generate.go
+++ b/pkg/domain/infra/tunnel/generate.go
@@ -11,6 +11,6 @@ func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string,
return generate.Systemd(ic.ClientCxt, nameOrID, options)
}
-func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrID string, options entities.GenerateKubeOptions) (*entities.GenerateKubeReport, error) {
- return generate.Kube(ic.ClientCxt, nameOrID, options)
+func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string, options entities.GenerateKubeOptions) (*entities.GenerateKubeReport, error) {
+ return generate.Kube(ic.ClientCxt, nameOrIDs, options)
}