summaryrefslogtreecommitdiff
path: root/pkg/domain
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/domain')
-rw-r--r--pkg/domain/entities/containers.go1
-rw-r--r--pkg/domain/entities/generate.go7
-rw-r--r--pkg/domain/entities/images.go17
-rw-r--r--pkg/domain/entities/manifest.go21
-rw-r--r--pkg/domain/entities/system.go7
-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.go93
-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
17 files changed, 208 insertions, 91 deletions
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index c8894300b..16997cdd1 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -282,6 +282,7 @@ type ContainerListOptions struct {
Quiet bool
Size bool
Sort string
+ Storage bool
Sync bool
Watch uint
}
diff --git a/pkg/domain/entities/generate.go b/pkg/domain/entities/generate.go
index a8ad13705..4a0d7537e 100644
--- a/pkg/domain/entities/generate.go
+++ b/pkg/domain/entities/generate.go
@@ -4,8 +4,6 @@ import "io"
// GenerateSystemdOptions control the generation of systemd unit files.
type GenerateSystemdOptions struct {
- // Files - generate files instead of printing to stdout.
- Files bool
// Name - use container/pod name instead of its ID.
Name bool
// New - create a new container instead of starting a new one.
@@ -24,9 +22,8 @@ type GenerateSystemdOptions struct {
// GenerateSystemdReport
type GenerateSystemdReport struct {
- // Output of the generate process. Either the generated files or their
- // entire content.
- Output string
+ // Units of the generate process. key = unit name -> value = unit content
+ Units map[string]string
}
// GenerateKubeOptions control the generation of Kubernetes YAML files.
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index 3a12a4e22..2a8133680 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -271,11 +271,22 @@ type ImageImportReport struct {
Id string //nolint
}
+// ImageSaveOptions provide options for saving images.
type ImageSaveOptions struct {
+ // Compress layers when saving to a directory.
Compress bool
- Format string
- Output string
- Quiet bool
+ // Format of saving the image: oci-archive, oci-dir (directory with oci
+ // manifest type), docker-archive, docker-dir (directory with v2s2
+ // manifest type).
+ Format string
+ // MultiImageArchive denotes if the created archive shall include more
+ // than one image. Additional tags will be interpreted as references
+ // to images which are added to the archive.
+ MultiImageArchive bool
+ // Output - write image to the specified path.
+ Output string
+ // Quiet - suppress output when copying images
+ Quiet bool
}
// ImageTreeOptions provides options for ImageEngine.Tree()
diff --git a/pkg/domain/entities/manifest.go b/pkg/domain/entities/manifest.go
index 853619b19..01180951a 100644
--- a/pkg/domain/entities/manifest.go
+++ b/pkg/domain/entities/manifest.go
@@ -9,14 +9,19 @@ type ManifestCreateOptions struct {
}
type ManifestAddOptions struct {
- All bool `json:"all" schema:"all"`
- Annotation []string `json:"annotation" schema:"annotation"`
- Arch string `json:"arch" schema:"arch"`
- Features []string `json:"features" schema:"features"`
- Images []string `json:"images" schema:"images"`
- OS string `json:"os" schema:"os"`
- OSVersion string `json:"os_version" schema:"os_version"`
- Variant string `json:"variant" schema:"variant"`
+ All bool `json:"all" schema:"all"`
+ Annotation []string `json:"annotation" schema:"annotation"`
+ Arch string `json:"arch" schema:"arch"`
+ Authfile string `json:"-" schema:"-"`
+ CertDir string `json:"-" schema:"-"`
+ Features []string `json:"features" schema:"features"`
+ Images []string `json:"images" schema:"images"`
+ OS string `json:"os" schema:"os"`
+ OSVersion string `json:"os_version" schema:"os_version"`
+ Password string `json:"-" schema:"-"`
+ SkipTLSVerify types.OptionalBool `json:"-" schema:"-"`
+ Username string `json:"-" schema:"-"`
+ Variant string `json:"variant" schema:"variant"`
}
type ManifestAnnotateOptions struct {
diff --git a/pkg/domain/entities/system.go b/pkg/domain/entities/system.go
index af355b0af..bde2b6ef2 100644
--- a/pkg/domain/entities/system.go
+++ b/pkg/domain/entities/system.go
@@ -75,9 +75,10 @@ type SystemDfContainerReport struct {
// SystemDfVolumeReport describes a volume and its size
type SystemDfVolumeReport struct {
- VolumeName string
- Links int
- Size int64
+ VolumeName string
+ Links int
+ Size int64
+ ReclaimableSize int64
}
// SystemResetOptions describes the options for resetting your
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..062b38a70 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -8,11 +8,13 @@ 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"
@@ -507,33 +509,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 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)
+ }
}
+ }()
+ }
+
+ // 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 !strings.Contains(waitErr.Error(), define.ErrNoSuchCtr.Error()) {
+ 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) {