summaryrefslogtreecommitdiff
path: root/pkg/domain/infra
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/domain/infra')
-rw-r--r--pkg/domain/infra/abi/containers.go9
-rw-r--r--pkg/domain/infra/abi/containers_runlabel.go37
-rw-r--r--pkg/domain/infra/abi/generate.go8
-rw-r--r--pkg/domain/infra/abi/images.go24
-rw-r--r--pkg/domain/infra/abi/manifest.go20
-rw-r--r--pkg/domain/infra/abi/network.go4
-rw-r--r--pkg/domain/infra/abi/play.go12
-rw-r--r--pkg/domain/infra/abi/system.go11
-rw-r--r--pkg/domain/infra/tunnel/containers.go94
-rw-r--r--pkg/domain/infra/tunnel/generate.go3
-rw-r--r--pkg/domain/infra/tunnel/images.go23
-rw-r--r--pkg/domain/infra/tunnel/network.go2
12 files changed, 175 insertions, 72 deletions
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 3fee5d394..21618f555 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -174,6 +174,12 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
return err
}
}
+ if c.AutoRemove() {
+ // Issue #7384: if the container is configured for
+ // auto-removal, it might already have been removed at
+ // this point.
+ return nil
+ }
return c.Cleanup(ctx)
})
if err != nil {
@@ -792,6 +798,9 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
}
func (ic *ContainerEngine) ContainerList(ctx context.Context, options entities.ContainerListOptions) ([]entities.ListContainer, error) {
+ if options.Latest {
+ options.Last = 1
+ }
return ps.GetContainerLists(ic.Libpod, options)
}
diff --git a/pkg/domain/infra/abi/containers_runlabel.go b/pkg/domain/infra/abi/containers_runlabel.go
index ab2316d47..30a5a55b8 100644
--- a/pkg/domain/infra/abi/containers_runlabel.go
+++ b/pkg/domain/infra/abi/containers_runlabel.go
@@ -7,12 +7,10 @@ import (
"path/filepath"
"strings"
- "github.com/containers/image/v5/types"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/image"
"github.com/containers/podman/v2/pkg/domain/entities"
envLib "github.com/containers/podman/v2/pkg/env"
- "github.com/containers/podman/v2/pkg/util"
"github.com/containers/podman/v2/utils"
"github.com/google/shlex"
"github.com/pkg/errors"
@@ -36,6 +34,11 @@ func (ic *ContainerEngine) ContainerRunlabel(ctx context.Context, label string,
return err
}
+ if options.Display {
+ fmt.Printf("command: %s\n", strings.Join(append([]string{os.Args[0]}, cmd[1:]...), " "))
+ return nil
+ }
+
stdErr := os.Stderr
stdOut := os.Stdout
stdIn := os.Stdin
@@ -84,29 +87,17 @@ func (ic *ContainerEngine) runlabelImage(ctx context.Context, label string, imag
// Fallthrough and pull!
}
- // Parse credentials if specified.
- var credentials *types.DockerAuthConfig
- if options.Credentials != "" {
- credentials, err = util.ParseRegistryCreds(options.Credentials)
- if err != nil {
- return nil, err
- }
- }
-
- // Suppress pull progress bars if requested.
- pullOutput := os.Stdout
- if options.Quiet {
- pullOutput = nil // c/image/copy takes care of the rest
+ pullOptions := entities.ImagePullOptions{
+ Quiet: options.Quiet,
+ CertDir: options.CertDir,
+ SkipTLSVerify: options.SkipTLSVerify,
+ SignaturePolicy: options.SignaturePolicy,
+ Authfile: options.Authfile,
}
-
- // Pull the image.
- dockerRegistryOptions := image.DockerRegistryOptions{
- DockerCertPath: options.CertDir,
- DockerInsecureSkipTLSVerify: options.SkipTLSVerify,
- DockerRegistryCreds: credentials,
+ if _, err := pull(ctx, ic.Libpod.ImageRuntime(), imageRef, pullOptions, &label); err != nil {
+ return nil, err
}
-
- return ic.Libpod.ImageRuntime().New(ctx, imageRef, options.SignaturePolicy, options.Authfile, pullOutput, &dockerRegistryOptions, image.SigningOptions{}, &label, util.PullImageMissing)
+ return ic.Libpod.ImageRuntime().NewFromLocal(imageRef)
}
// generateRunlabelCommand generates the to-be-executed command as a string
diff --git a/pkg/domain/infra/abi/generate.go b/pkg/domain/infra/abi/generate.go
index 0b73ddd7e..79bf2291e 100644
--- a/pkg/domain/infra/abi/generate.go
+++ b/pkg/domain/infra/abi/generate.go
@@ -19,11 +19,11 @@ func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string,
ctr, ctrErr := ic.Libpod.LookupContainer(nameOrID)
if ctrErr == nil {
// Generate the unit for the container.
- s, err := generate.ContainerUnit(ctr, options)
+ name, content, err := generate.ContainerUnit(ctr, options)
if err != nil {
return nil, err
}
- return &entities.GenerateSystemdReport{Output: s}, nil
+ return &entities.GenerateSystemdReport{Units: map[string]string{name: content}}, nil
}
// If it's not a container, we either have a pod or garbage.
@@ -34,11 +34,11 @@ func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string,
}
// Generate the units for the pod and all its containers.
- s, err := generate.PodUnits(pod, options)
+ units, err := generate.PodUnits(pod, options)
if err != nil {
return nil, err
}
- return &entities.GenerateSystemdReport{Output: s}, nil
+ return &entities.GenerateSystemdReport{Units: units}, nil
}
func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrID string, options entities.GenerateKubeOptions) (*entities.GenerateKubeReport, error) {
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 6b94ca9c0..23aef9573 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -14,7 +14,6 @@ import (
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/docker"
- dockerarchive "github.com/containers/image/v5/docker/archive"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/signature"
@@ -215,7 +214,7 @@ func ToDomainHistoryLayer(layer *libpodImage.History) entities.ImageHistoryLayer
return l
}
-func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entities.ImagePullOptions) (*entities.ImagePullReport, error) {
+func pull(ctx context.Context, runtime *image.Runtime, rawImage string, options entities.ImagePullOptions, label *string) (*entities.ImagePullReport, error) {
var writer io.Writer
if !options.Quiet {
writer = os.Stderr
@@ -230,15 +229,6 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entiti
}
}
- // Special-case for docker-archive which allows multiple tags.
- if imageRef.Transport().Name() == dockerarchive.Transport.Name() {
- newImage, err := ir.Libpod.ImageRuntime().LoadFromArchiveReference(ctx, imageRef, options.SignaturePolicy, writer)
- if err != nil {
- return nil, err
- }
- return &entities.ImagePullReport{Images: []string{newImage[0].ID()}}, nil
- }
-
var registryCreds *types.DockerAuthConfig
if len(options.Username) > 0 && len(options.Password) > 0 {
registryCreds = &types.DockerAuthConfig{
@@ -256,7 +246,7 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entiti
}
if !options.AllTags {
- newImage, err := ir.Libpod.ImageRuntime().New(ctx, rawImage, options.SignaturePolicy, options.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, nil, util.PullImageAlways)
+ newImage, err := runtime.New(ctx, rawImage, options.SignaturePolicy, options.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, label, util.PullImageAlways)
if err != nil {
return nil, err
}
@@ -290,7 +280,7 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entiti
foundIDs := []string{}
for _, tag := range tags {
name := rawImage + ":" + tag
- newImage, err := ir.Libpod.ImageRuntime().New(ctx, name, options.SignaturePolicy, options.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, nil, util.PullImageAlways)
+ newImage, err := runtime.New(ctx, name, options.SignaturePolicy, options.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, nil, util.PullImageAlways)
if err != nil {
logrus.Errorf("error pulling image %q", name)
continue
@@ -304,6 +294,10 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entiti
return &entities.ImagePullReport{Images: foundIDs}, nil
}
+func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entities.ImagePullOptions) (*entities.ImagePullReport, error) {
+ return pull(ctx, ir.Libpod.ImageRuntime(), rawImage, options, nil)
+}
+
func (ir *ImageEngine) Inspect(ctx context.Context, namesOrIDs []string, opts entities.InspectOptions) ([]*entities.ImageInspectReport, []error, error) {
reports := []*entities.ImageInspectReport{}
errs := []error{}
@@ -481,6 +475,10 @@ func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOpti
}
func (ir *ImageEngine) Save(ctx context.Context, nameOrID string, tags []string, options entities.ImageSaveOptions) error {
+ if options.MultiImageArchive {
+ nameOrIDs := append([]string{nameOrID}, tags...)
+ return ir.Libpod.ImageRuntime().SaveImages(ctx, nameOrIDs, options.Format, options.Output, options.Quiet)
+ }
newImage, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrID)
if err != nil {
return err
diff --git a/pkg/domain/infra/abi/manifest.go b/pkg/domain/infra/abi/manifest.go
index 6f3c6b902..55f73bf65 100644
--- a/pkg/domain/infra/abi/manifest.go
+++ b/pkg/domain/infra/abi/manifest.go
@@ -102,7 +102,24 @@ func (ir *ImageEngine) ManifestAdd(ctx context.Context, opts entities.ManifestAd
}
manifestAddOpts.Annotation = annotations
}
- listID, err := listImage.AddManifest(*ir.Libpod.SystemContext(), manifestAddOpts)
+
+ // Set the system context.
+ sys := ir.Libpod.SystemContext()
+ if sys != nil {
+ sys = &types.SystemContext{}
+ }
+ sys.AuthFilePath = opts.Authfile
+ sys.DockerInsecureSkipTLSVerify = opts.SkipTLSVerify
+ sys.DockerCertPath = opts.CertDir
+
+ if opts.Username != "" && opts.Password != "" {
+ sys.DockerAuthConfig = &types.DockerAuthConfig{
+ Username: opts.Username,
+ Password: opts.Password,
+ }
+ }
+
+ listID, err := listImage.AddManifest(*sys, manifestAddOpts)
if err != nil {
return listID, err
}
@@ -191,6 +208,7 @@ func (ir *ImageEngine) ManifestPush(ctx context.Context, names []string, opts en
}
sys.AuthFilePath = opts.Authfile
sys.DockerInsecureSkipTLSVerify = opts.SkipTLSVerify
+ sys.DockerCertPath = opts.CertDir
if opts.Username != "" && opts.Password != "" {
sys.DockerAuthConfig = &types.DockerAuthConfig{
diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go
index c06714cbb..807e4b272 100644
--- a/pkg/domain/infra/abi/network.go
+++ b/pkg/domain/infra/abi/network.go
@@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
+ "os"
"path/filepath"
"strings"
@@ -216,6 +217,9 @@ func createBridge(r *libpod.Runtime, name string, options entities.NetworkCreate
if err != nil {
return "", err
}
+ if err := os.MkdirAll(network.GetCNIConfDir(runtimeConfig), 0755); err != nil {
+ return "", err
+ }
cniPathName := filepath.Join(network.GetCNIConfDir(runtimeConfig), fmt.Sprintf("%s.conflist", name))
err = ioutil.WriteFile(cniPathName, b, 0644)
return cniPathName, err
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index 31ad51672..6dfb52c63 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -132,7 +132,11 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
libpod.WithInfraContainer(),
libpod.WithPodName(podName),
}
- // TODO for now we just used the default kernel namespaces; we need to add/subtract this from yaml
+ // TODO we only configure Process namespace. We also need to account for Host{IPC,Network,PID}
+ // which is not currently possible with pod create
+ if podYAML.Spec.ShareProcessNamespace != nil && *podYAML.Spec.ShareProcessNamespace {
+ podOptions = append(podOptions, libpod.WithPodPID())
+ }
hostname := podYAML.Spec.Hostname
if hostname == "" {
@@ -556,6 +560,7 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container
containerConfig.Env = envs
for _, volume := range containerYAML.VolumeMounts {
+ var readonly string
hostPath, exists := volumes[volume.Name]
if !exists {
return nil, errors.Errorf("Volume mount %s specified for container but not configured in volumes", volume.Name)
@@ -563,7 +568,10 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container
if err := parse.ValidateVolumeCtrDir(volume.MountPath); err != nil {
return nil, errors.Wrapf(err, "error in parsing MountPath")
}
- containerConfig.Volumes = append(containerConfig.Volumes, fmt.Sprintf("%s:%s", hostPath, volume.MountPath))
+ if volume.ReadOnly {
+ readonly = ":ro"
+ }
+ containerConfig.Volumes = append(containerConfig.Volumes, fmt.Sprintf("%s:%s%s", hostPath, volume.MountPath, readonly))
}
return &containerConfig, nil
}
diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go
index ff1052d86..914a7681d 100644
--- a/pkg/domain/infra/abi/system.go
+++ b/pkg/domain/infra/abi/system.go
@@ -313,6 +313,7 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System
}
dfVolumes := make([]*entities.SystemDfVolumeReport, 0, len(vols))
+ var reclaimableSize int64
for _, v := range vols {
var consInUse int
volSize, err := sizeOfPath(v.MountPoint())
@@ -323,15 +324,19 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System
if err != nil {
return nil, err
}
+ if len(inUse) == 0 {
+ reclaimableSize += volSize
+ }
for _, viu := range inUse {
if util.StringInSlice(viu, runningContainers) {
consInUse++
}
}
report := entities.SystemDfVolumeReport{
- VolumeName: v.Name(),
- Links: consInUse,
- Size: volSize,
+ VolumeName: v.Name(),
+ Links: consInUse,
+ Size: volSize,
+ ReclaimableSize: reclaimableSize,
}
dfVolumes = append(dfVolumes, &report)
}
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index cc919561f..35550b9be 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -8,15 +8,18 @@ import (
"os"
"strconv"
"strings"
+ "sync"
"time"
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/podman/v2/libpod/define"
+ "github.com/containers/podman/v2/libpod/events"
"github.com/containers/podman/v2/pkg/api/handlers"
"github.com/containers/podman/v2/pkg/bindings"
"github.com/containers/podman/v2/pkg/bindings/containers"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/errorhandling"
"github.com/containers/podman/v2/pkg/specgen"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -507,33 +510,90 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
for _, w := range con.Warnings {
fmt.Fprintf(os.Stderr, "%s\n", w)
}
+
report := entities.ContainerRunReport{Id: con.ID}
- // Attach
- if !opts.Detach {
- err = startAndAttach(ic, con.ID, &opts.DetachKeys, opts.InputStream, opts.OutputStream, opts.ErrorStream)
- if err == nil {
- exitCode, err := containers.Wait(ic.ClientCxt, con.ID, nil)
- if err == nil {
- report.ExitCode = int(exitCode)
- }
+
+ if opts.Detach {
+ // Detach and return early
+ err := containers.Start(ic.ClientCxt, con.ID, nil)
+ if err != nil {
+ report.ExitCode = define.ExitCode(err)
}
- } else {
- err = containers.Start(ic.ClientCxt, con.ID, nil)
+ return &report, err
}
- if err != nil {
+
+ // Attach
+ if err := startAndAttach(ic, con.ID, &opts.DetachKeys, opts.InputStream, opts.OutputStream, opts.ErrorStream); err != nil {
report.ExitCode = define.ExitCode(err)
+ if opts.Rm {
+ if rmErr := containers.Remove(ic.ClientCxt, con.ID, bindings.PFalse, bindings.PTrue); rmErr != nil {
+ logrus.Debugf("unable to remove container %s after failing to start and attach to it", con.ID)
+ }
+ }
+ return &report, err
}
+
if opts.Rm {
- if err := containers.Remove(ic.ClientCxt, con.ID, bindings.PFalse, bindings.PTrue); err != nil {
- if errors.Cause(err) == define.ErrNoSuchCtr ||
- errors.Cause(err) == define.ErrCtrRemoved {
- logrus.Warnf("Container %s does not exist: %v", con.ID, err)
- } else {
- logrus.Errorf("Error removing container %s: %v", con.ID, err)
+ // Defer the removal, so we can return early if needed and
+ // de-spaghetti the code.
+ defer func() {
+ if err := containers.Remove(ic.ClientCxt, con.ID, bindings.PFalse, bindings.PTrue); err != nil {
+ if errorhandling.Contains(err, define.ErrNoSuchCtr) ||
+ errorhandling.Contains(err, define.ErrCtrRemoved) {
+ logrus.Warnf("Container %s does not exist: %v", con.ID, err)
+ } else {
+ logrus.Errorf("Error removing container %s: %v", con.ID, err)
+ }
}
+ }()
+ }
+
+ // Wait
+ exitCode, waitErr := containers.Wait(ic.ClientCxt, con.ID, nil)
+ if waitErr == nil {
+ report.ExitCode = int(exitCode)
+ return &report, nil
+ }
+
+ // Determine why the wait failed. If the container doesn't exist,
+ // consult the events.
+ if !errorhandling.Contains(waitErr, define.ErrNoSuchCtr) {
+ return &report, waitErr
+ }
+
+ // Events
+ eventsChannel := make(chan *events.Event)
+ eventOptions := entities.EventsOptions{
+ EventChan: eventsChannel,
+ Filter: []string{
+ "type=container",
+ fmt.Sprintf("container=%s", con.ID),
+ fmt.Sprintf("event=%s", events.Exited),
+ },
+ }
+
+ var lastEvent *events.Event
+ var mutex sync.Mutex
+ mutex.Lock()
+ // Read the events.
+ go func() {
+ for e := range eventsChannel {
+ lastEvent = e
}
+ mutex.Unlock()
+ }()
+
+ eventsErr := ic.Events(ctx, eventOptions)
+
+ // Wait for all events to be read
+ mutex.Lock()
+ if eventsErr != nil || lastEvent == nil {
+ logrus.Errorf("Cannot get exit code: %v", err)
+ report.ExitCode = define.ExecErrorCodeNotFound
+ return &report, nil // compat with local client
}
+ report.ExitCode = lastEvent.ContainerExitCode
return &report, err
}
diff --git a/pkg/domain/infra/tunnel/generate.go b/pkg/domain/infra/tunnel/generate.go
index c7d5cd9e2..966f707b1 100644
--- a/pkg/domain/infra/tunnel/generate.go
+++ b/pkg/domain/infra/tunnel/generate.go
@@ -5,11 +5,10 @@ import (
"github.com/containers/podman/v2/pkg/bindings/generate"
"github.com/containers/podman/v2/pkg/domain/entities"
- "github.com/pkg/errors"
)
func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string, options entities.GenerateSystemdOptions) (*entities.GenerateSystemdReport, error) {
- return nil, errors.New("not implemented for tunnel")
+ return generate.Systemd(ic.ClientCxt, nameOrID, options)
}
func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrID string, options entities.GenerateKubeOptions) (*entities.GenerateKubeReport, error) {
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index b255c5da4..185cc2f9a 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -251,12 +251,23 @@ func (ir *ImageEngine) Save(ctx context.Context, nameOrID string, tags []string,
return err
}
- exErr := images.Export(ir.ClientCxt, nameOrID, f, &options.Format, &options.Compress)
- if err := f.Close(); err != nil {
- return err
- }
- if exErr != nil {
- return exErr
+ if options.MultiImageArchive {
+ exErr := images.MultiExport(ir.ClientCxt, append([]string{nameOrID}, tags...), f, &options.Format, &options.Compress)
+ if err := f.Close(); err != nil {
+ return err
+ }
+ if exErr != nil {
+ return exErr
+ }
+ } else {
+ // FIXME: tags are entirely ignored here but shouldn't.
+ exErr := images.Export(ir.ClientCxt, nameOrID, f, &options.Format, &options.Compress)
+ if err := f.Close(); err != nil {
+ return err
+ }
+ if exErr != nil {
+ return exErr
+ }
}
if options.Format != "oci-dir" && options.Format != "docker-dir" {
diff --git a/pkg/domain/infra/tunnel/network.go b/pkg/domain/infra/tunnel/network.go
index 2b197cac0..074425087 100644
--- a/pkg/domain/infra/tunnel/network.go
+++ b/pkg/domain/infra/tunnel/network.go
@@ -8,7 +8,7 @@ import (
)
func (ic *ContainerEngine) NetworkList(ctx context.Context, options entities.NetworkListOptions) ([]*entities.NetworkListReport, error) {
- return network.List(ic.ClientCxt)
+ return network.List(ic.ClientCxt, options)
}
func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []string, options entities.NetworkInspectOptions) ([]entities.NetworkInspectReport, error) {