summaryrefslogtreecommitdiff
path: root/pkg/domain/infra/abi
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/domain/infra/abi')
-rw-r--r--pkg/domain/infra/abi/containers.go22
-rw-r--r--pkg/domain/infra/abi/images.go151
-rw-r--r--pkg/domain/infra/abi/pods.go97
-rw-r--r--pkg/domain/infra/abi/system.go4
-rw-r--r--pkg/domain/infra/abi/volumes.go5
5 files changed, 153 insertions, 126 deletions
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 1934533cf..281e448f6 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -16,7 +16,6 @@ import (
"github.com/containers/image/v5/manifest"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
- "github.com/containers/podman/v4/libpod/events"
"github.com/containers/podman/v4/libpod/logs"
"github.com/containers/podman/v4/pkg/checkpoint"
"github.com/containers/podman/v4/pkg/domain/entities"
@@ -939,6 +938,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
}
return reports, errors.Wrapf(err, "unable to start container %s", ctr.ID())
}
+
exitCode = ic.GetContainerExitCode(ctx, ctr)
reports = append(reports, &entities.ContainerStartReport{
Id: ctr.ID(),
@@ -1099,25 +1099,11 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
func (ic *ContainerEngine) GetContainerExitCode(ctx context.Context, ctr *libpod.Container) int {
exitCode, err := ctr.Wait(ctx)
- if err == nil {
- return int(exitCode)
- }
- if errors.Cause(err) != define.ErrNoSuchCtr {
- logrus.Errorf("Could not retrieve exit code: %v", err)
+ if err != nil {
+ logrus.Errorf("Waiting for container %s: %v", ctr.ID(), err)
return define.ExecErrorCodeNotFound
}
- // Make 4 attempt with 0.25s backoff between each for 1 second total
- var event *events.Event
- for i := 0; i < 4; i++ {
- event, err = ic.Libpod.GetLastContainerEvent(ctx, ctr.ID(), events.Exited)
- if err != nil {
- time.Sleep(250 * time.Millisecond)
- continue
- }
- return event.ContainerExitCode
- }
- logrus.Errorf("Could not retrieve exit code from event: %v", err)
- return define.ExecErrorCodeNotFound
+ return int(exitCode)
}
func (ic *ContainerEngine) ContainerLogs(ctx context.Context, containers []string, options entities.ContainerLogsOptions) error {
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index d63de2424..02aa5923d 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -3,6 +3,7 @@ package abi
import (
"context"
"fmt"
+ "io/fs"
"io/ioutil"
"net/url"
"os"
@@ -29,7 +30,6 @@ import (
domainUtils "github.com/containers/podman/v4/pkg/domain/utils"
"github.com/containers/podman/v4/pkg/errorhandling"
"github.com/containers/podman/v4/pkg/rootless"
- "github.com/containers/podman/v4/utils"
"github.com/containers/storage"
dockerRef "github.com/docker/distribution/reference"
"github.com/opencontainers/go-digest"
@@ -350,22 +350,6 @@ func (ir *ImageEngine) Push(ctx context.Context, source string, destination stri
}
return pushError
}
-
-// Transfer moves images between root and rootless storage so the user specified in the scp call can access and use the image modified by root
-func (ir *ImageEngine) Transfer(ctx context.Context, source entities.ImageScpOptions, dest entities.ImageScpOptions, parentFlags []string) error {
- if source.User == "" {
- return errors.Wrapf(define.ErrInvalidArg, "you must define a user when transferring from root to rootless storage")
- }
- podman, err := os.Executable()
- if err != nil {
- return err
- }
- if rootless.IsRootless() && (len(dest.User) == 0 || dest.User == "root") { // if we are rootless and do not have a destination user we can just use sudo
- return transferRootless(source, dest, podman, parentFlags)
- }
- return transferRootful(source, dest, podman, parentFlags)
-}
-
func (ir *ImageEngine) Tag(ctx context.Context, nameOrID string, tags []string, options entities.ImageTagOptions) error {
// Allow tagging manifest list instead of resolving instances from manifest
lookupOptions := &libimage.LookupImageOptions{ManifestList: true}
@@ -694,53 +678,32 @@ func (ir *ImageEngine) Sign(ctx context.Context, names []string, options entitie
return nil, nil
}
-func getSigFilename(sigStoreDirPath string) (string, error) {
- sigFileSuffix := 1
- sigFiles, err := ioutil.ReadDir(sigStoreDirPath)
+func (ir *ImageEngine) Scp(ctx context.Context, src, dst string, parentFlags []string, quiet bool) error {
+ rep, source, dest, flags, err := domainUtils.ExecuteTransfer(src, dst, parentFlags, quiet)
if err != nil {
- return "", err
- }
- sigFilenames := make(map[string]bool)
- for _, file := range sigFiles {
- sigFilenames[file.Name()] = true
+ return err
}
- for {
- sigFilename := "signature-" + strconv.Itoa(sigFileSuffix)
- if _, exists := sigFilenames[sigFilename]; !exists {
- return sigFilename, nil
+ if (rep == nil && err == nil) && (source != nil && dest != nil) { // we need to execute the transfer
+ err := Transfer(ctx, *source, *dest, flags)
+ if err != nil {
+ return err
}
- sigFileSuffix++
- }
-}
-
-func localPathFromURI(url *url.URL) (string, error) {
- if url.Scheme != "file" {
- return "", errors.Errorf("writing to %s is not supported. Use a supported scheme", url.String())
}
- return url.Path, nil
+ return nil
}
-// putSignature creates signature and saves it to the signstore file
-func putSignature(manifestBlob []byte, mech signature.SigningMechanism, sigStoreDir string, instanceDigest digest.Digest, dockerReference dockerRef.Reference, options entities.SignOptions) error {
- newSig, err := signature.SignDockerManifest(manifestBlob, dockerReference.String(), mech, options.SignBy)
- if err != nil {
- return err
- }
- signatureDir := fmt.Sprintf("%s@%s=%s", sigStoreDir, instanceDigest.Algorithm(), instanceDigest.Hex())
- if err := os.MkdirAll(signatureDir, 0751); err != nil {
- // The directory is allowed to exist
- if !os.IsExist(err) {
- return err
- }
+func Transfer(ctx context.Context, source entities.ImageScpOptions, dest entities.ImageScpOptions, parentFlags []string) error {
+ if source.User == "" {
+ return errors.Wrapf(define.ErrInvalidArg, "you must define a user when transferring from root to rootless storage")
}
- sigFilename, err := getSigFilename(signatureDir)
+ podman, err := os.Executable()
if err != nil {
return err
}
- if err = ioutil.WriteFile(filepath.Join(signatureDir, sigFilename), newSig, 0644); err != nil {
- return err
+ if rootless.IsRootless() && (len(dest.User) == 0 || dest.User == "root") { // if we are rootless and do not have a destination user we can just use sudo
+ return transferRootless(source, dest, podman, parentFlags)
}
- return nil
+ return transferRootful(source, dest, podman, parentFlags)
}
// TransferRootless creates new podman processes using exec.Command and sudo, transferring images between the given source and destination users
@@ -763,7 +726,7 @@ func transferRootless(source entities.ImageScpOptions, dest entities.ImageScpOpt
} else {
cmdSave = exec.Command(podman)
}
- cmdSave = utils.CreateSCPCommand(cmdSave, saveCommand)
+ cmdSave = domainUtils.CreateSCPCommand(cmdSave, saveCommand)
logrus.Debugf("Executing save command: %q", cmdSave)
err := cmdSave.Run()
if err != nil {
@@ -776,8 +739,11 @@ func transferRootless(source entities.ImageScpOptions, dest entities.ImageScpOpt
} else {
cmdLoad = exec.Command(podman)
}
- cmdLoad = utils.CreateSCPCommand(cmdLoad, loadCommand)
+ cmdLoad = domainUtils.CreateSCPCommand(cmdLoad, loadCommand)
logrus.Debugf("Executing load command: %q", cmdLoad)
+ if len(dest.Tag) > 0 {
+ return domainUtils.ScpTag(cmdLoad, podman, dest)
+ }
return cmdLoad.Run()
}
@@ -833,11 +799,20 @@ func transferRootful(source entities.ImageScpOptions, dest entities.ImageScpOpti
return err
}
}
- err = execPodman(uSave, saveCommand)
+ _, err = execTransferPodman(uSave, saveCommand, false)
+ if err != nil {
+ return err
+ }
+ out, err := execTransferPodman(uLoad, loadCommand, (len(dest.Tag) > 0))
if err != nil {
return err
}
- return execPodman(uLoad, loadCommand)
+ if out != nil {
+ image := domainUtils.ExtractImage(out)
+ _, err := execTransferPodman(uLoad, []string{podman, "tag", image, dest.Tag}, false)
+ return err
+ }
+ return nil
}
func lookupUser(u string) (*user.User, error) {
@@ -847,10 +822,10 @@ func lookupUser(u string) (*user.User, error) {
return user.Lookup(u)
}
-func execPodman(execUser *user.User, command []string) error {
- cmdLogin, err := utils.LoginUser(execUser.Username)
+func execTransferPodman(execUser *user.User, command []string, needToTag bool) ([]byte, error) {
+ cmdLogin, err := domainUtils.LoginUser(execUser.Username)
if err != nil {
- return err
+ return nil, err
}
defer func() {
@@ -864,11 +839,11 @@ func execPodman(execUser *user.User, command []string) error {
cmd.Stdout = os.Stdout
uid, err := strconv.ParseInt(execUser.Uid, 10, 32)
if err != nil {
- return err
+ return nil, err
}
gid, err := strconv.ParseInt(execUser.Gid, 10, 32)
if err != nil {
- return err
+ return nil, err
}
cmd.SysProcAttr = &syscall.SysProcAttr{
Credential: &syscall.Credential{
@@ -878,5 +853,55 @@ func execPodman(execUser *user.User, command []string) error {
NoSetGroups: false,
},
}
- return cmd.Run()
+ if needToTag {
+ cmd.Stdout = nil
+ return cmd.Output()
+ }
+ return nil, cmd.Run()
+}
+
+func getSigFilename(sigStoreDirPath string) (string, error) {
+ sigFileSuffix := 1
+ sigFiles, err := ioutil.ReadDir(sigStoreDirPath)
+ if err != nil {
+ return "", err
+ }
+ sigFilenames := make(map[string]bool)
+ for _, file := range sigFiles {
+ sigFilenames[file.Name()] = true
+ }
+ for {
+ sigFilename := "signature-" + strconv.Itoa(sigFileSuffix)
+ if _, exists := sigFilenames[sigFilename]; !exists {
+ return sigFilename, nil
+ }
+ sigFileSuffix++
+ }
+}
+
+func localPathFromURI(url *url.URL) (string, error) {
+ if url.Scheme != "file" {
+ return "", errors.Errorf("writing to %s is not supported. Use a supported scheme", url.String())
+ }
+ return url.Path, nil
+}
+
+// putSignature creates signature and saves it to the signstore file
+func putSignature(manifestBlob []byte, mech signature.SigningMechanism, sigStoreDir string, instanceDigest digest.Digest, dockerReference dockerRef.Reference, options entities.SignOptions) error {
+ newSig, err := signature.SignDockerManifest(manifestBlob, dockerReference.String(), mech, options.SignBy)
+ if err != nil {
+ return err
+ }
+ signatureDir := fmt.Sprintf("%s@%s=%s", sigStoreDir, instanceDigest.Algorithm(), instanceDigest.Hex())
+ if err := os.MkdirAll(signatureDir, 0751); err != nil {
+ // The directory is allowed to exist
+ if !errors.Is(err, fs.ErrExist) {
+ return err
+ }
+ }
+ sigFilename, err := getSigFilename(signatureDir)
+ if err != nil {
+ return err
+ }
+ return ioutil.WriteFile(filepath.Join(signatureDir, sigFilename), newSig, 0644)
}
diff --git a/pkg/domain/infra/abi/pods.go b/pkg/domain/infra/abi/pods.go
index 3e9cb7f5e..1dca8c580 100644
--- a/pkg/domain/infra/abi/pods.go
+++ b/pkg/domain/infra/abi/pods.go
@@ -402,6 +402,56 @@ func (ic *ContainerEngine) PodTop(ctx context.Context, options entities.PodTopOp
return report, err
}
+func (ic *ContainerEngine) listPodReportFromPod(p *libpod.Pod) (*entities.ListPodsReport, error) {
+ status, err := p.GetPodStatus()
+ if err != nil {
+ return nil, err
+ }
+ cons, err := p.AllContainers()
+ if err != nil {
+ return nil, err
+ }
+ lpcs := make([]*entities.ListPodContainer, len(cons))
+ for i, c := range cons {
+ state, err := c.State()
+ if err != nil {
+ return nil, err
+ }
+ lpcs[i] = &entities.ListPodContainer{
+ Id: c.ID(),
+ Names: c.Name(),
+ Status: state.String(),
+ }
+ }
+ infraID, err := p.InfraContainerID()
+ if err != nil {
+ return nil, err
+ }
+ networks := []string{}
+ if len(infraID) > 0 {
+ infra, err := p.InfraContainer()
+ if err != nil {
+ return nil, err
+ }
+ networks, err = infra.Networks()
+ if err != nil {
+ return nil, err
+ }
+ }
+ return &entities.ListPodsReport{
+ Cgroup: p.CgroupParent(),
+ Containers: lpcs,
+ Created: p.CreatedTime(),
+ Id: p.ID(),
+ InfraId: infraID,
+ Name: p.Name(),
+ Namespace: p.Namespace(),
+ Networks: networks,
+ Status: status,
+ Labels: p.Labels(),
+ }, nil
+}
+
func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOptions) ([]*entities.ListPodsReport, error) {
var (
err error
@@ -431,53 +481,14 @@ func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOpti
reports := make([]*entities.ListPodsReport, 0, len(pds))
for _, p := range pds {
- var lpcs []*entities.ListPodContainer
- status, err := p.GetPodStatus()
- if err != nil {
- return nil, err
- }
- cons, err := p.AllContainers()
+ r, err := ic.listPodReportFromPod(p)
if err != nil {
- return nil, err
- }
- for _, c := range cons {
- state, err := c.State()
- if err != nil {
- return nil, err
+ if errors.Is(err, define.ErrNoSuchPod) || errors.Is(err, define.ErrNoSuchCtr) {
+ continue
}
- lpcs = append(lpcs, &entities.ListPodContainer{
- Id: c.ID(),
- Names: c.Name(),
- Status: state.String(),
- })
- }
- infraID, err := p.InfraContainerID()
- if err != nil {
return nil, err
}
- networks := []string{}
- if len(infraID) > 0 {
- infra, err := p.InfraContainer()
- if err != nil {
- return nil, err
- }
- networks, err = infra.Networks()
- if err != nil {
- return nil, err
- }
- }
- reports = append(reports, &entities.ListPodsReport{
- Cgroup: p.CgroupParent(),
- Containers: lpcs,
- Created: p.CreatedTime(),
- Id: p.ID(),
- InfraId: infraID,
- Name: p.Name(),
- Namespace: p.Namespace(),
- Networks: networks,
- Status: status,
- Labels: p.Labels(),
- })
+ reports = append(reports, r)
}
return reports, nil
}
diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go
index 6e26026d4..2bd88ed85 100644
--- a/pkg/domain/infra/abi/system.go
+++ b/pkg/domain/infra/abi/system.go
@@ -319,8 +319,8 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System
}
dfVolumes := make([]*entities.SystemDfVolumeReport, 0, len(vols))
- var reclaimableSize uint64
for _, v := range vols {
+ var reclaimableSize uint64
var consInUse int
mountPoint, err := v.MountPoint()
if err != nil {
@@ -341,7 +341,7 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System
return nil, err
}
if len(inUse) == 0 {
- reclaimableSize += volSize
+ reclaimableSize = volSize
}
for _, viu := range inUse {
if cutil.StringInSlice(viu, runningContainers) {
diff --git a/pkg/domain/infra/abi/volumes.go b/pkg/domain/infra/abi/volumes.go
index a9c53c140..1186d8e81 100644
--- a/pkg/domain/infra/abi/volumes.go
+++ b/pkg/domain/infra/abi/volumes.go
@@ -211,3 +211,8 @@ func (ic *ContainerEngine) VolumeUnmount(ctx context.Context, nameOrIDs []string
return reports, nil
}
+
+func (ic *ContainerEngine) VolumeReload(ctx context.Context) (*entities.VolumeReloadReport, error) {
+ report := ic.Libpod.UpdateVolumePlugins(ctx)
+ return &entities.VolumeReloadReport{VolumeReload: *report}, nil
+}