summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_api.go14
-rw-r--r--libpod/container_exec.go20
-rw-r--r--libpod/container_inspect.go18
-rw-r--r--libpod/container_internal.go44
-rw-r--r--libpod/container_internal_linux.go23
-rw-r--r--libpod/container_internal_unsupported.go2
-rw-r--r--libpod/container_log.go23
-rw-r--r--libpod/container_log_linux.go16
-rw-r--r--libpod/container_log_unsupported.go4
-rw-r--r--libpod/define/config.go10
-rw-r--r--libpod/define/container_inspect.go57
-rw-r--r--libpod/define/ctr_inspect.go54
-rw-r--r--libpod/define/pod_inspect.go6
-rw-r--r--libpod/events/events_linux.go10
-rw-r--r--libpod/networking_linux.go34
-rw-r--r--libpod/networking_unsupported.go6
-rw-r--r--libpod/oci_conmon_linux.go9
-rw-r--r--libpod/options.go8
-rw-r--r--libpod/pod_api.go41
-rw-r--r--libpod/runtime.go17
-rw-r--r--libpod/runtime_ctr.go22
-rw-r--r--libpod/state_test.go8
-rw-r--r--libpod/storage.go8
-rw-r--r--libpod/util.go19
24 files changed, 269 insertions, 204 deletions
diff --git a/libpod/container_api.go b/libpod/container_api.go
index b37b05ff2..487f75e67 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -29,7 +29,7 @@ import (
// Init requires that all dependency containers be started (e.g. pod infra
// containers). The `recursive` parameter will, if set to true, start these
// dependency containers before initializing this container.
-func (c *Container) Init(ctx context.Context, recursive bool) (err error) {
+func (c *Container) Init(ctx context.Context, recursive bool) error {
span, _ := opentracing.StartSpanFromContext(ctx, "containerInit")
span.SetTag("struct", "container")
defer span.Finish()
@@ -85,7 +85,7 @@ func (c *Container) Init(ctx context.Context, recursive bool) (err error) {
// Start requites that all dependency containers (e.g. pod infra containers) be
// running before being run. The recursive parameter, if set, will start all
// dependencies before starting this container.
-func (c *Container) Start(ctx context.Context, recursive bool) (err error) {
+func (c *Container) Start(ctx context.Context, recursive bool) error {
span, _ := opentracing.StartSpanFromContext(ctx, "containerStart")
span.SetTag("struct", "container")
defer span.Finish()
@@ -112,7 +112,7 @@ func (c *Container) Start(ctx context.Context, recursive bool) (err error) {
// Attach call occurs before Start).
// In overall functionality, it is identical to the Start call, with the added
// side effect that an attach session will also be started.
-func (c *Container) StartAndAttach(ctx context.Context, streams *define.AttachStreams, keys string, resize <-chan remotecommand.TerminalSize, recursive bool) (attachResChan <-chan error, err error) {
+func (c *Container) StartAndAttach(ctx context.Context, streams *define.AttachStreams, keys string, resize <-chan remotecommand.TerminalSize, recursive bool) (<-chan error, error) {
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
@@ -150,7 +150,7 @@ func (c *Container) StartAndAttach(ctx context.Context, streams *define.AttachSt
}
// RestartWithTimeout restarts a running container and takes a given timeout in uint
-func (c *Container) RestartWithTimeout(ctx context.Context, timeout uint) (err error) {
+func (c *Container) RestartWithTimeout(ctx context.Context, timeout uint) error {
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
@@ -160,7 +160,7 @@ func (c *Container) RestartWithTimeout(ctx context.Context, timeout uint) (err e
}
}
- if err = c.checkDependenciesAndHandleError(); err != nil {
+ if err := c.checkDependenciesAndHandleError(); err != nil {
return err
}
@@ -353,7 +353,7 @@ func (c *Container) HTTPAttach(httpCon net.Conn, httpBuf *bufio.ReadWriter, stre
logOpts.WaitGroup.Wait()
close(logChan)
}()
- if err := c.ReadLog(logOpts, logChan); err != nil {
+ if err := c.ReadLog(context.Background(), logOpts, logChan); err != nil {
return err
}
logrus.Debugf("Done reading logs for container %s, %d bytes", c.ID(), logSize)
@@ -760,7 +760,7 @@ func (c *Container) Checkpoint(ctx context.Context, options ContainerCheckpointO
}
// Restore restores a container
-func (c *Container) Restore(ctx context.Context, options ContainerCheckpointOptions) (err error) {
+func (c *Container) Restore(ctx context.Context, options ContainerCheckpointOptions) error {
logrus.Debugf("Trying to restore container %s", c.ID())
if !c.batched {
c.lock.Lock()
diff --git a/libpod/container_exec.go b/libpod/container_exec.go
index 69da6fcfe..bd04ee9b9 100644
--- a/libpod/container_exec.go
+++ b/libpod/container_exec.go
@@ -779,25 +779,25 @@ func (c *Container) execOCILog(sessionID string) string {
}
// create a bundle path and associated files for an exec session
-func (c *Container) createExecBundle(sessionID string) (err error) {
+func (c *Container) createExecBundle(sessionID string) (retErr error) {
bundlePath := c.execBundlePath(sessionID)
- if createErr := os.MkdirAll(bundlePath, execDirPermission); createErr != nil {
- return createErr
+ if err := os.MkdirAll(bundlePath, execDirPermission); err != nil {
+ return err
}
defer func() {
- if err != nil {
- if err2 := os.RemoveAll(bundlePath); err != nil {
- logrus.Warnf("error removing exec bundle after creation caused another error: %v", err2)
+ if retErr != nil {
+ if err := os.RemoveAll(bundlePath); err != nil {
+ logrus.Warnf("error removing exec bundle after creation caused another error: %v", err)
}
}
}()
- if err2 := os.MkdirAll(c.execExitFileDir(sessionID), execDirPermission); err2 != nil {
+ if err := os.MkdirAll(c.execExitFileDir(sessionID), execDirPermission); err != nil {
// The directory is allowed to exist
- if !os.IsExist(err2) {
- err = errors.Wrapf(err2, "error creating OCI runtime exit file path %s", c.execExitFileDir(sessionID))
+ if !os.IsExist(err) {
+ return errors.Wrapf(err, "error creating OCI runtime exit file path %s", c.execExitFileDir(sessionID))
}
}
- return
+ return nil
}
// readExecExitCode reads the exit file for an exec session and returns
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index 03684ddec..cd2e41be2 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -289,6 +289,7 @@ func (c *Container) generateInspectContainerConfig(spec *spec.Spec) *define.Insp
ctrConfig.OpenStdin = c.config.Stdin
ctrConfig.Image = c.config.RootfsImageName
+ ctrConfig.SystemdMode = c.config.Systemd
// Leave empty is not explicitly overwritten by user
if len(c.config.Command) != 0 {
@@ -610,22 +611,11 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
// Port bindings.
// Only populate if we're using CNI to configure the network.
- portBindings := make(map[string][]define.InspectHostPort)
if c.config.CreateNetNS {
- for _, port := range c.config.PortMappings {
- key := fmt.Sprintf("%d/%s", port.ContainerPort, port.Protocol)
- hostPorts := portBindings[key]
- if hostPorts == nil {
- hostPorts = []define.InspectHostPort{}
- }
- hostPorts = append(hostPorts, define.InspectHostPort{
- HostIP: port.HostIP,
- HostPort: fmt.Sprintf("%d", port.HostPort),
- })
- portBindings[key] = hostPorts
- }
+ hostConfig.PortBindings = makeInspectPortBindings(c.config.PortMappings)
+ } else {
+ hostConfig.PortBindings = make(map[string][]define.InspectHostPort)
}
- hostConfig.PortBindings = portBindings
// Cap add and cap drop.
// We need a default set of capabilities to compare against.
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 7a547e565..c44ba5fe6 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -209,7 +209,7 @@ func (c *Container) handleExitFile(exitFile string, fi os.FileInfo) error {
// Handle container restart policy.
// This is called when a container has exited, and was not explicitly stopped by
// an API call to stop the container or pod it is in.
-func (c *Container) handleRestartPolicy(ctx context.Context) (restarted bool, err error) {
+func (c *Container) handleRestartPolicy(ctx context.Context) (_ bool, retErr error) {
// If we did not get a restart policy match, exit immediately.
// Do the same if we're not a policy that restarts.
if !c.state.RestartPolicyMatch ||
@@ -240,7 +240,7 @@ func (c *Container) handleRestartPolicy(ctx context.Context) (restarted bool, er
logrus.Debugf("Restarting container %s due to restart policy %s", c.ID(), c.config.RestartPolicy)
// Need to check if dependencies are alive.
- if err = c.checkDependenciesAndHandleError(); err != nil {
+ if err := c.checkDependenciesAndHandleError(); err != nil {
return false, err
}
@@ -262,9 +262,9 @@ func (c *Container) handleRestartPolicy(ctx context.Context) (restarted bool, er
}
defer func() {
- if err != nil {
- if err2 := c.cleanup(ctx); err2 != nil {
- logrus.Errorf("error cleaning up container %s: %v", c.ID(), err2)
+ if retErr != nil {
+ if err := c.cleanup(ctx); err != nil {
+ logrus.Errorf("error cleaning up container %s: %v", c.ID(), err)
}
}
}()
@@ -767,7 +767,7 @@ func (c *Container) save() error {
// Checks the container is in the right state, then initializes the container in preparation to start the container.
// If recursive is true, each of the containers dependencies will be started.
// Otherwise, this function will return with error if there are dependencies of this container that aren't running.
-func (c *Container) prepareToStart(ctx context.Context, recursive bool) (err error) {
+func (c *Container) prepareToStart(ctx context.Context, recursive bool) (retErr error) {
// Container must be created or stopped to be started
if !c.ensureState(define.ContainerStateConfigured, define.ContainerStateCreated, define.ContainerStateStopped, define.ContainerStateExited) {
return errors.Wrapf(define.ErrCtrStateInvalid, "container %s must be in Created or Stopped state to be started", c.ID())
@@ -784,9 +784,9 @@ func (c *Container) prepareToStart(ctx context.Context, recursive bool) (err err
}
defer func() {
- if err != nil {
- if err2 := c.cleanup(ctx); err2 != nil {
- logrus.Errorf("error cleaning up container %s: %v", c.ID(), err2)
+ if retErr != nil {
+ if err := c.cleanup(ctx); err != nil {
+ logrus.Errorf("error cleaning up container %s: %v", c.ID(), err)
}
}
}()
@@ -1132,7 +1132,7 @@ func (c *Container) reinit(ctx context.Context, retainRetries bool) error {
// Initialize (if necessary) and start a container
// Performs all necessary steps to start a container that is not running
// Does not lock or check validity
-func (c *Container) initAndStart(ctx context.Context) (err error) {
+func (c *Container) initAndStart(ctx context.Context) (retErr error) {
// If we are ContainerStateUnknown, throw an error
if c.state.State == define.ContainerStateUnknown {
return errors.Wrapf(define.ErrCtrStateInvalid, "container %s is in an unknown state", c.ID())
@@ -1150,9 +1150,9 @@ func (c *Container) initAndStart(ctx context.Context) (err error) {
}
defer func() {
- if err != nil {
- if err2 := c.cleanup(ctx); err2 != nil {
- logrus.Errorf("error cleaning up container %s: %v", c.ID(), err2)
+ if retErr != nil {
+ if err := c.cleanup(ctx); err != nil {
+ logrus.Errorf("error cleaning up container %s: %v", c.ID(), err)
}
}
}()
@@ -1321,7 +1321,7 @@ func (c *Container) unpause() error {
}
// Internal, non-locking function to restart a container
-func (c *Container) restartWithTimeout(ctx context.Context, timeout uint) (err error) {
+func (c *Container) restartWithTimeout(ctx context.Context, timeout uint) (retErr error) {
if !c.ensureState(define.ContainerStateConfigured, define.ContainerStateCreated, define.ContainerStateRunning, define.ContainerStateStopped, define.ContainerStateExited) {
return errors.Wrapf(define.ErrCtrStateInvalid, "unable to restart a container in a paused or unknown state")
}
@@ -1358,9 +1358,9 @@ func (c *Container) restartWithTimeout(ctx context.Context, timeout uint) (err e
}
}
defer func() {
- if err != nil {
- if err2 := c.cleanup(ctx); err2 != nil {
- logrus.Errorf("error cleaning up container %s: %v", c.ID(), err2)
+ if retErr != nil {
+ if err := c.cleanup(ctx); err != nil {
+ logrus.Errorf("error cleaning up container %s: %v", c.ID(), err)
}
}
}()
@@ -1682,7 +1682,7 @@ func (c *Container) cleanup(ctx context.Context) error {
// delete deletes the container and runs any configured poststop
// hooks.
-func (c *Container) delete(ctx context.Context) (err error) {
+func (c *Container) delete(ctx context.Context) error {
span, _ := opentracing.StartSpanFromContext(ctx, "delete")
span.SetTag("struct", "container")
defer span.Finish()
@@ -1701,7 +1701,7 @@ func (c *Container) delete(ctx context.Context) (err error) {
// postDeleteHooks runs the poststop hooks (if any) as specified by
// the OCI Runtime Specification (which requires them to run
// post-delete, despite the stage name).
-func (c *Container) postDeleteHooks(ctx context.Context) (err error) {
+func (c *Container) postDeleteHooks(ctx context.Context) error {
span, _ := opentracing.StartSpanFromContext(ctx, "postDeleteHooks")
span.SetTag("struct", "container")
defer span.Finish()
@@ -1824,7 +1824,7 @@ func (c *Container) saveSpec(spec *spec.Spec) error {
}
// Warning: precreate hooks may alter 'config' in place.
-func (c *Container) setupOCIHooks(ctx context.Context, config *spec.Spec) (extensionStageHooks map[string][]spec.Hook, err error) {
+func (c *Container) setupOCIHooks(ctx context.Context, config *spec.Spec) (map[string][]spec.Hook, error) {
allHooks := make(map[string][]spec.Hook)
if c.runtime.config.Engine.HooksDir == nil {
if rootless.IsRootless() {
@@ -1938,7 +1938,7 @@ func (c *Container) checkReadyForRemoval() error {
// writeJSONFile marshalls and writes the given data to a JSON file
// in the bundle path
-func (c *Container) writeJSONFile(v interface{}, file string) (err error) {
+func (c *Container) writeJSONFile(v interface{}, file string) error {
fileJSON, err := json.MarshalIndent(v, "", " ")
if err != nil {
return errors.Wrapf(err, "error writing JSON to %s for container %s", file, c.ID())
@@ -1953,7 +1953,7 @@ func (c *Container) writeJSONFile(v interface{}, file string) (err error) {
// prepareCheckpointExport writes the config and spec to
// JSON files for later export
-func (c *Container) prepareCheckpointExport() (err error) {
+func (c *Container) prepareCheckpointExport() error {
// save live config
if err := c.writeJSONFile(c.Config(), "config.dump"); err != nil {
return err
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index cb70aea62..cfcf9b823 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -244,7 +244,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
// Apply AppArmor checks and load the default profile if needed.
- if !c.config.Privileged {
+ if len(c.config.Spec.Process.ApparmorProfile) > 0 {
updatedProfile, err := apparmor.CheckProfileAndLoadDefault(c.config.Spec.Process.ApparmorProfile)
if err != nil {
return nil, err
@@ -610,7 +610,7 @@ func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr
return nil
}
-func (c *Container) exportCheckpoint(dest string, ignoreRootfs bool) (err error) {
+func (c *Container) exportCheckpoint(dest string, ignoreRootfs bool) error {
if (len(c.config.NamedVolumes) > 0) || (len(c.Dependencies()) > 0) {
return errors.Errorf("Cannot export checkpoints of containers with named volumes or dependencies")
}
@@ -721,7 +721,7 @@ func (c *Container) exportCheckpoint(dest string, ignoreRootfs bool) (err error)
return nil
}
-func (c *Container) checkpointRestoreSupported() (err error) {
+func (c *Container) checkpointRestoreSupported() error {
if !criu.CheckForCriu() {
return errors.Errorf("Checkpoint/Restore requires at least CRIU %d", criu.MinCriuVersion)
}
@@ -731,7 +731,7 @@ func (c *Container) checkpointRestoreSupported() (err error) {
return nil
}
-func (c *Container) checkpointRestoreLabelLog(fileName string) (err error) {
+func (c *Container) checkpointRestoreLabelLog(fileName string) error {
// Create the CRIU log file and label it
dumpLog := filepath.Join(c.bundlePath(), fileName)
@@ -748,7 +748,7 @@ func (c *Container) checkpointRestoreLabelLog(fileName string) (err error) {
return nil
}
-func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointOptions) (err error) {
+func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointOptions) error {
if err := c.checkpointRestoreSupported(); err != nil {
return err
}
@@ -818,7 +818,7 @@ func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointO
return c.save()
}
-func (c *Container) importCheckpoint(input string) (err error) {
+func (c *Container) importCheckpoint(input string) error {
archiveFile, err := os.Open(input)
if err != nil {
return errors.Wrapf(err, "Failed to open checkpoint archive %s for import", input)
@@ -847,8 +847,7 @@ func (c *Container) importCheckpoint(input string) (err error) {
return nil
}
-func (c *Container) restore(ctx context.Context, options ContainerCheckpointOptions) (err error) {
-
+func (c *Container) restore(ctx context.Context, options ContainerCheckpointOptions) (retErr error) {
if err := c.checkpointRestoreSupported(); err != nil {
return err
}
@@ -858,7 +857,7 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
}
if options.TargetFile != "" {
- if err = c.importCheckpoint(options.TargetFile); err != nil {
+ if err := c.importCheckpoint(options.TargetFile); err != nil {
return err
}
}
@@ -944,9 +943,9 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
}
defer func() {
- if err != nil {
- if err2 := c.cleanup(ctx); err2 != nil {
- logrus.Errorf("error cleaning up container %s: %v", c.ID(), err2)
+ if retErr != nil {
+ if err := c.cleanup(ctx); err != nil {
+ logrus.Errorf("error cleaning up container %s: %v", c.ID(), err)
}
}
}()
diff --git a/libpod/container_internal_unsupported.go b/libpod/container_internal_unsupported.go
index a42c1d735..e6d94104c 100644
--- a/libpod/container_internal_unsupported.go
+++ b/libpod/container_internal_unsupported.go
@@ -18,7 +18,7 @@ func (c *Container) unmountSHM(mount string) error {
return define.ErrNotImplemented
}
-func (c *Container) prepare() (err error) {
+func (c *Container) prepare() error {
return define.ErrNotImplemented
}
diff --git a/libpod/container_log.go b/libpod/container_log.go
index 97936c683..80f8e6e50 100644
--- a/libpod/container_log.go
+++ b/libpod/container_log.go
@@ -1,6 +1,7 @@
package libpod
import (
+ "context"
"fmt"
"os"
"time"
@@ -13,9 +14,9 @@ import (
)
// Log is a runtime function that can read one or more container logs.
-func (r *Runtime) Log(containers []*Container, options *logs.LogOptions, logChannel chan *logs.LogLine) error {
+func (r *Runtime) Log(ctx context.Context, containers []*Container, options *logs.LogOptions, logChannel chan *logs.LogLine) error {
for _, ctr := range containers {
- if err := ctr.ReadLog(options, logChannel); err != nil {
+ if err := ctr.ReadLog(ctx, options, logChannel); err != nil {
return err
}
}
@@ -23,25 +24,25 @@ func (r *Runtime) Log(containers []*Container, options *logs.LogOptions, logChan
}
// ReadLog reads a containers log based on the input options and returns loglines over a channel.
-func (c *Container) ReadLog(options *logs.LogOptions, logChannel chan *logs.LogLine) error {
+func (c *Container) ReadLog(ctx context.Context, options *logs.LogOptions, logChannel chan *logs.LogLine) error {
switch c.LogDriver() {
case define.NoLogging:
return errors.Wrapf(define.ErrNoLogs, "this container is using the 'none' log driver, cannot read logs")
case define.JournaldLogging:
// TODO Skip sending logs until journald logs can be read
- return c.readFromJournal(options, logChannel)
+ return c.readFromJournal(ctx, options, logChannel)
case define.JSONLogging:
// TODO provide a separate implementation of this when Conmon
// has support.
fallthrough
case define.KubernetesLogging, "":
- return c.readFromLogFile(options, logChannel)
+ return c.readFromLogFile(ctx, options, logChannel)
default:
return errors.Wrapf(define.ErrInternal, "unrecognized log driver %q, cannot read logs", c.LogDriver())
}
}
-func (c *Container) readFromLogFile(options *logs.LogOptions, logChannel chan *logs.LogLine) error {
+func (c *Container) readFromLogFile(ctx context.Context, options *logs.LogOptions, logChannel chan *logs.LogLine) error {
t, tailLog, err := logs.GetLogFile(c.LogPath(), options)
if err != nil {
// If the log file does not exist, this is not fatal.
@@ -62,8 +63,17 @@ func (c *Container) readFromLogFile(options *logs.LogOptions, logChannel chan *l
}
go func() {
+ defer options.WaitGroup.Done()
+
var partial string
for line := range t.Lines {
+ select {
+ case <-ctx.Done():
+ // the consumer has cancelled
+ return
+ default:
+ // fallthrough
+ }
nll, err := logs.NewLogLine(line.Text)
if err != nil {
logrus.Error(err)
@@ -82,7 +92,6 @@ func (c *Container) readFromLogFile(options *logs.LogOptions, logChannel chan *l
logChannel <- nll
}
}
- options.WaitGroup.Done()
}()
// Check if container is still running or paused
if options.Follow {
diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go
index fad3bf87c..00b2039a9 100644
--- a/libpod/container_log_linux.go
+++ b/libpod/container_log_linux.go
@@ -4,6 +4,7 @@
package libpod
import (
+ "context"
"fmt"
"io"
"math"
@@ -29,7 +30,7 @@ const (
bufLen = 16384
)
-func (c *Container) readFromJournal(options *logs.LogOptions, logChannel chan *logs.LogLine) error {
+func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOptions, logChannel chan *logs.LogLine) error {
var config journal.JournalReaderConfig
if options.Tail < 0 {
config.NumFromTail = math.MaxUint64
@@ -65,13 +66,24 @@ func (c *Container) readFromJournal(options *logs.LogOptions, logChannel chan *l
if options.Follow {
go func() {
+ done := make(chan bool)
+ until := make(chan time.Time)
+ go func() {
+ select {
+ case <-ctx.Done():
+ until <- time.Time{}
+ case <-done:
+ // nothing to do anymore
+ }
+ }()
follower := FollowBuffer{logChannel}
- err := r.Follow(nil, follower)
+ err := r.Follow(until, follower)
if err != nil {
logrus.Debugf(err.Error())
}
r.Close()
options.WaitGroup.Done()
+ done <- true
return
}()
return nil
diff --git a/libpod/container_log_unsupported.go b/libpod/container_log_unsupported.go
index 18882720a..f3b36619e 100644
--- a/libpod/container_log_unsupported.go
+++ b/libpod/container_log_unsupported.go
@@ -3,11 +3,13 @@
package libpod
import (
+ "context"
+
"github.com/containers/libpod/v2/libpod/define"
"github.com/containers/libpod/v2/libpod/logs"
"github.com/pkg/errors"
)
-func (c *Container) readFromJournal(options *logs.LogOptions, logChannel chan *logs.LogLine) error {
+func (c *Container) readFromJournal(_ context.Context, _ *logs.LogOptions, _ chan *logs.LogLine) error {
return errors.Wrapf(define.ErrOSNotSupported, "Journald logging only enabled with systemd on linux")
}
diff --git a/libpod/define/config.go b/libpod/define/config.go
index 900a363d8..64b24d9e2 100644
--- a/libpod/define/config.go
+++ b/libpod/define/config.go
@@ -75,3 +75,13 @@ const JSONLogging = "json-file"
// NoLogging is the string conmon expects when specifying to use no log driver whatsoever
const NoLogging = "none"
+
+// Strings used for --sdnotify option to podman
+const (
+ SdNotifyModeContainer = "container"
+ SdNotifyModeConmon = "conmon"
+ SdNotifyModeIgnore = "ignore"
+)
+
+// DefaultRlimitValue is the value set by default for nofile and nproc
+const RLimitDefaultValue = uint64(1048576)
diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go
index a3cf4304f..7807f9e8b 100644
--- a/libpod/define/container_inspect.go
+++ b/libpod/define/container_inspect.go
@@ -54,6 +54,10 @@ type InspectContainerConfig struct {
// CreateCommand is the full command plus arguments of the process the
// container has been created with.
CreateCommand []string `json:"CreateCommand,omitempty"`
+ // SystemdMode is whether the container is running in systemd mode. In
+ // systemd mode, the container configuration is customized to optimize
+ // running systemd in the container.
+ SystemdMode bool `json:"SystemdMode,omitempty"`
}
// InspectRestartPolicy holds information about the container's restart policy.
@@ -628,3 +632,56 @@ type InspectContainerData struct {
Config *InspectContainerConfig `json:"Config"`
HostConfig *InspectContainerHostConfig `json:"HostConfig"`
}
+
+// InspectExecSession contains information about a given exec session.
+type InspectExecSession struct {
+ // CanRemove is legacy and used purely for compatibility reasons.
+ // Will always be set to true, unless the exec session is running.
+ CanRemove bool `json:"CanRemove"`
+ // ContainerID is the ID of the container this exec session is attached
+ // to.
+ ContainerID string `json:"ContainerID"`
+ // DetachKeys are the detach keys used by the exec session.
+ // If set to "" the default keys are being used.
+ // Will show "<none>" if no detach keys are set.
+ DetachKeys string `json:"DetachKeys"`
+ // ExitCode is the exit code of the exec session. Will be set to 0 if
+ // the exec session has not yet exited.
+ ExitCode int `json:"ExitCode"`
+ // ID is the ID of the exec session.
+ ID string `json:"ID"`
+ // OpenStderr is whether the container's STDERR stream will be attached.
+ // Always set to true if the exec session created a TTY.
+ OpenStderr bool `json:"OpenStderr"`
+ // OpenStdin is whether the container's STDIN stream will be attached
+ // to.
+ OpenStdin bool `json:"OpenStdin"`
+ // OpenStdout is whether the container's STDOUT stream will be attached.
+ // Always set to true if the exec session created a TTY.
+ OpenStdout bool `json:"OpenStdout"`
+ // Running is whether the exec session is running.
+ Running bool `json:"Running"`
+ // Pid is the PID of the exec session's process.
+ // Will be set to 0 if the exec session is not running.
+ Pid int `json:"Pid"`
+ // ProcessConfig contains information about the exec session's process.
+ ProcessConfig *InspectExecProcess `json:"ProcessConfig"`
+}
+
+// InspectExecProcess contains information about the process in a given exec
+// session.
+type InspectExecProcess struct {
+ // Arguments are the arguments to the entrypoint command of the exec
+ // session.
+ Arguments []string `json:"arguments"`
+ // Entrypoint is the entrypoint for the exec session (the command that
+ // will be executed in the container).
+ Entrypoint string `json:"entrypoint"`
+ // Privileged is whether the exec session will be started with elevated
+ // privileges.
+ Privileged bool `json:"privileged"`
+ // Tty is whether the exec session created a terminal.
+ Tty bool `json:"tty"`
+ // User is the user the exec session was started as.
+ User string `json:"user"`
+}
diff --git a/libpod/define/ctr_inspect.go b/libpod/define/ctr_inspect.go
deleted file mode 100644
index b7cd13f82..000000000
--- a/libpod/define/ctr_inspect.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package define
-
-// InspectExecSession contains information about a given exec session.
-type InspectExecSession struct {
- // CanRemove is legacy and used purely for compatibility reasons.
- // Will always be set to true, unless the exec session is running.
- CanRemove bool `json:"CanRemove"`
- // ContainerID is the ID of the container this exec session is attached
- // to.
- ContainerID string `json:"ContainerID"`
- // DetachKeys are the detach keys used by the exec session.
- // If set to "" the default keys are being used.
- // Will show "<none>" if no detach keys are set.
- DetachKeys string `json:"DetachKeys"`
- // ExitCode is the exit code of the exec session. Will be set to 0 if
- // the exec session has not yet exited.
- ExitCode int `json:"ExitCode"`
- // ID is the ID of the exec session.
- ID string `json:"ID"`
- // OpenStderr is whether the container's STDERR stream will be attached.
- // Always set to true if the exec session created a TTY.
- OpenStderr bool `json:"OpenStderr"`
- // OpenStdin is whether the container's STDIN stream will be attached
- // to.
- OpenStdin bool `json:"OpenStdin"`
- // OpenStdout is whether the container's STDOUT stream will be attached.
- // Always set to true if the exec session created a TTY.
- OpenStdout bool `json:"OpenStdout"`
- // Running is whether the exec session is running.
- Running bool `json:"Running"`
- // Pid is the PID of the exec session's process.
- // Will be set to 0 if the exec session is not running.
- Pid int `json:"Pid"`
- // ProcessConfig contains information about the exec session's process.
- ProcessConfig *InspectExecProcess `json:"ProcessConfig"`
-}
-
-// InspectExecProcess contains information about the process in a given exec
-// session.
-type InspectExecProcess struct {
- // Arguments are the arguments to the entrypoint command of the exec
- // session.
- Arguments []string `json:"arguments"`
- // Entrypoint is the entrypoint for the exec session (the command that
- // will be executed in the container).
- Entrypoint string `json:"entrypoint"`
- // Privileged is whether the exec session will be started with elevated
- // privileges.
- Privileged bool `json:"privileged"`
- // Tty is whether the exec session created a terminal.
- Tty bool `json:"tty"`
- // User is the user the exec session was started as.
- User string `json:"user"`
-}
diff --git a/libpod/define/pod_inspect.go b/libpod/define/pod_inspect.go
index 7f06e16fc..634cbb728 100644
--- a/libpod/define/pod_inspect.go
+++ b/libpod/define/pod_inspect.go
@@ -3,8 +3,6 @@ package define
import (
"net"
"time"
-
- "github.com/cri-o/ocicni/pkg/ocicni"
)
// InspectPodData contains detailed information on a pod's configuration and
@@ -60,7 +58,7 @@ type InspectPodData struct {
type InspectPodInfraConfig struct {
// PortBindings are ports that will be forwarded to the infra container
// and then shared with the pod.
- PortBindings []ocicni.PortMapping
+ PortBindings map[string][]InspectHostPort
// HostNetwork is whether the infra container (and thus the whole pod)
// will use the host's network and not create a network namespace.
HostNetwork bool
@@ -89,6 +87,8 @@ type InspectPodInfraConfig struct {
// HostAdd adds a number of hosts to the infra container's resolv.conf
// which will be shared with the rest of the pod.
HostAdd []string
+ // Networks is a list of CNI networks te pod will join.
+ Networks []string
}
// InspectPodContainerInfo contains information on a container in a pod.
diff --git a/libpod/events/events_linux.go b/libpod/events/events_linux.go
index ffb100be8..482d7d6dd 100644
--- a/libpod/events/events_linux.go
+++ b/libpod/events/events_linux.go
@@ -8,20 +8,20 @@ import (
)
// NewEventer creates an eventer based on the eventer type
-func NewEventer(options EventerOptions) (eventer Eventer, err error) {
+func NewEventer(options EventerOptions) (Eventer, error) {
logrus.Debugf("Initializing event backend %s", options.EventerType)
switch strings.ToUpper(options.EventerType) {
case strings.ToUpper(Journald.String()):
- eventer, err = newEventJournalD(options)
+ eventer, err := newEventJournalD(options)
if err != nil {
return nil, errors.Wrapf(err, "eventer creation")
}
+ return eventer, nil
case strings.ToUpper(LogFile.String()):
- eventer = EventLogFile{options}
+ return EventLogFile{options}, nil
case strings.ToUpper(Null.String()):
- eventer = NewNullEventer()
+ return NewNullEventer(), nil
default:
return nil, errors.Errorf("unknown event logger type: %s", strings.ToUpper(options.EventerType))
}
- return eventer, nil
}
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index 7985e17e1..1e79e8732 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -141,18 +141,18 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) ([]*cnitypes.Re
}
// Create and configure a new network namespace for a container
-func (r *Runtime) createNetNS(ctr *Container) (n ns.NetNS, q []*cnitypes.Result, err error) {
+func (r *Runtime) createNetNS(ctr *Container) (n ns.NetNS, q []*cnitypes.Result, retErr error) {
ctrNS, err := netns.NewNS()
if err != nil {
return nil, nil, errors.Wrapf(err, "error creating network namespace for container %s", ctr.ID())
}
defer func() {
- if err != nil {
- if err2 := netns.UnmountNS(ctrNS); err2 != nil {
- logrus.Errorf("Error unmounting partially created network namespace for container %s: %v", ctr.ID(), err2)
+ if retErr != nil {
+ if err := netns.UnmountNS(ctrNS); err != nil {
+ logrus.Errorf("Error unmounting partially created network namespace for container %s: %v", ctr.ID(), err)
}
- if err2 := ctrNS.Close(); err2 != nil {
- logrus.Errorf("Error closing partially created network namespace for container %s: %v", ctr.ID(), err2)
+ if err := ctrNS.Close(); err != nil {
+ logrus.Errorf("Error closing partially created network namespace for container %s: %v", ctr.ID(), err)
}
}
}()
@@ -188,7 +188,7 @@ func checkSlirpFlags(path string) (*slirpFeatures, error) {
}
// Configure the network namespace for a rootless container
-func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) {
+func (r *Runtime) setupRootlessNetNS(ctr *Container) error {
path := r.config.Engine.NetworkCmdPath
if path == "" {
@@ -342,7 +342,7 @@ func waitForSync(syncR *os.File, cmd *exec.Cmd, logFile io.ReadSeeker, timeout t
return nil
}
-func (r *Runtime) setupRootlessPortMapping(ctr *Container, netnsPath string) (err error) {
+func (r *Runtime) setupRootlessPortMapping(ctr *Container, netnsPath string) error {
syncR, syncW, err := os.Pipe()
if err != nil {
return errors.Wrapf(err, "failed to open pipe")
@@ -420,7 +420,7 @@ func (r *Runtime) setupRootlessPortMapping(ctr *Container, netnsPath string) (er
}
// Configure the network namespace using the container process
-func (r *Runtime) setupNetNS(ctr *Container) (err error) {
+func (r *Runtime) setupNetNS(ctr *Container) error {
nsProcess := fmt.Sprintf("/proc/%d/ns/net", ctr.state.PID)
b := make([]byte, 16)
@@ -587,21 +587,7 @@ func getContainerNetIO(ctr *Container) (*netlink.LinkStatistics, error) {
// network.
func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, error) {
settings := new(define.InspectNetworkSettings)
- settings.Ports = make(map[string][]define.InspectHostPort)
- if c.config.PortMappings != nil {
- for _, port := range c.config.PortMappings {
- key := fmt.Sprintf("%d/%s", port.ContainerPort, port.Protocol)
- mapping := settings.Ports[key]
- if mapping == nil {
- mapping = []define.InspectHostPort{}
- }
- mapping = append(mapping, define.InspectHostPort{
- HostIP: port.HostIP,
- HostPort: fmt.Sprintf("%d", port.HostPort),
- })
- settings.Ports[key] = mapping
- }
- }
+ settings.Ports = makeInspectPortBindings(c.config.PortMappings)
// We can't do more if the network is down.
if c.state.NetNS == nil {
diff --git a/libpod/networking_unsupported.go b/libpod/networking_unsupported.go
index d5189709c..69f470ff7 100644
--- a/libpod/networking_unsupported.go
+++ b/libpod/networking_unsupported.go
@@ -4,11 +4,11 @@ package libpod
import "github.com/containers/libpod/v2/libpod/define"
-func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) {
+func (r *Runtime) setupRootlessNetNS(ctr *Container) error {
return define.ErrNotImplemented
}
-func (r *Runtime) setupNetNS(ctr *Container) (err error) {
+func (r *Runtime) setupNetNS(ctr *Container) error {
return define.ErrNotImplemented
}
@@ -16,7 +16,7 @@ func (r *Runtime) teardownNetNS(ctr *Container) error {
return define.ErrNotImplemented
}
-func (r *Runtime) createNetNS(ctr *Container) (err error) {
+func (r *Runtime) createNetNS(ctr *Container) error {
return define.ErrNotImplemented
}
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index e9d5cbaa3..e38646eec 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -190,7 +190,7 @@ func hasCurrentUserMapped(ctr *Container) bool {
}
// CreateContainer creates a container.
-func (r *ConmonOCIRuntime) CreateContainer(ctr *Container, restoreOptions *ContainerCheckpointOptions) (err error) {
+func (r *ConmonOCIRuntime) CreateContainer(ctr *Container, restoreOptions *ContainerCheckpointOptions) error {
if !hasCurrentUserMapped(ctr) {
for _, i := range []string{ctr.state.RunDir, ctr.runtime.config.Engine.TmpDir, ctr.config.StaticDir, ctr.state.Mountpoint, ctr.runtime.config.Engine.VolumePath} {
if err := makeAccessible(i, ctr.RootUID(), ctr.RootGID()); err != nil {
@@ -850,7 +850,7 @@ func (r *ConmonOCIRuntime) getLogTag(ctr *Container) (string, error) {
}
// createOCIContainer generates this container's main conmon instance and prepares it for starting
-func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *ContainerCheckpointOptions) (err error) {
+func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *ContainerCheckpointOptions) error {
var stderrBuf bytes.Buffer
runtimeDir, err := util.GetRuntimeDir()
@@ -1297,8 +1297,9 @@ func (r *ConmonOCIRuntime) moveConmonToCgroupAndSignal(ctr *Container, cmd *exec
return nil
}
-// newPipe creates a unix socket pair for communication
-func newPipe() (parent *os.File, child *os.File, err error) {
+// newPipe creates a unix socket pair for communication.
+// Returns two files - first is parent, second is child.
+func newPipe() (*os.File, *os.File, error) {
fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_SEQPACKET|unix.SOCK_CLOEXEC, 0)
if err != nil {
return nil, nil, err
diff --git a/libpod/options.go b/libpod/options.go
index 3120a35d7..bff3f3c18 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1371,12 +1371,12 @@ func WithHealthCheck(healthCheck *manifest.Schema2HealthConfig) CtrCreateOption
// WithCreateCommand adds the full command plus arguments of the current
// process to the container config.
-func WithCreateCommand() CtrCreateOption {
+func WithCreateCommand(cmd []string) CtrCreateOption {
return func(ctr *Container) error {
if ctr.valid {
return define.ErrCtrFinalized
}
- ctr.config.CreateCommand = os.Args
+ ctr.config.CreateCommand = cmd
return nil
}
}
@@ -1553,12 +1553,12 @@ func WithPodHostname(hostname string) PodCreateOption {
// WithPodCreateCommand adds the full command plus arguments of the current
// process to the pod config.
-func WithPodCreateCommand() PodCreateOption {
+func WithPodCreateCommand(createCmd []string) PodCreateOption {
return func(pod *Pod) error {
if pod.valid {
return define.ErrPodFinalized
}
- pod.config.CreateCommand = os.Args
+ pod.config.CreateCommand = createCmd
return nil
}
}
diff --git a/libpod/pod_api.go b/libpod/pod_api.go
index a02b171e1..f2ef81bec 100644
--- a/libpod/pod_api.go
+++ b/libpod/pod_api.go
@@ -481,6 +481,41 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
}
}
+ // Infra config contains detailed information on the pod's infra
+ // container.
+ var infraConfig *define.InspectPodInfraConfig
+ if p.config.InfraContainer != nil && p.config.InfraContainer.HasInfraContainer {
+ infraConfig = new(define.InspectPodInfraConfig)
+ infraConfig.HostNetwork = p.config.InfraContainer.HostNetwork
+ infraConfig.StaticIP = p.config.InfraContainer.StaticIP
+ infraConfig.StaticMAC = p.config.InfraContainer.StaticMAC
+ infraConfig.NoManageResolvConf = p.config.InfraContainer.UseImageResolvConf
+ infraConfig.NoManageHosts = p.config.InfraContainer.UseImageHosts
+
+ if len(p.config.InfraContainer.DNSServer) > 0 {
+ infraConfig.DNSServer = make([]string, 0, len(p.config.InfraContainer.DNSServer))
+ infraConfig.DNSServer = append(infraConfig.DNSServer, p.config.InfraContainer.DNSServer...)
+ }
+ if len(p.config.InfraContainer.DNSSearch) > 0 {
+ infraConfig.DNSSearch = make([]string, 0, len(p.config.InfraContainer.DNSSearch))
+ infraConfig.DNSSearch = append(infraConfig.DNSSearch, p.config.InfraContainer.DNSSearch...)
+ }
+ if len(p.config.InfraContainer.DNSOption) > 0 {
+ infraConfig.DNSOption = make([]string, 0, len(p.config.InfraContainer.DNSOption))
+ infraConfig.DNSOption = append(infraConfig.DNSOption, p.config.InfraContainer.DNSOption...)
+ }
+ if len(p.config.InfraContainer.HostAdd) > 0 {
+ infraConfig.HostAdd = make([]string, 0, len(p.config.InfraContainer.HostAdd))
+ infraConfig.HostAdd = append(infraConfig.HostAdd, p.config.InfraContainer.HostAdd...)
+ }
+ if len(p.config.InfraContainer.Networks) > 0 {
+ infraConfig.Networks = make([]string, 0, len(p.config.InfraContainer.Networks))
+ infraConfig.Networks = append(infraConfig.Networks, p.config.InfraContainer.Networks...)
+ }
+
+ infraConfig.PortBindings = makeInspectPortBindings(p.config.InfraContainer.PortBindings)
+ }
+
inspectData := define.InspectPodData{
ID: p.ID(),
Name: p.Name(),
@@ -490,12 +525,12 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
State: podState,
Hostname: p.config.Hostname,
Labels: p.Labels(),
- CreateCgroup: false,
+ CreateCgroup: p.config.UsePodCgroup,
CgroupParent: p.CgroupParent(),
CgroupPath: p.state.CgroupPath,
- CreateInfra: false,
+ CreateInfra: infraConfig != nil,
InfraContainerID: p.state.InfraContainerID,
- InfraConfig: nil,
+ InfraConfig: infraConfig,
SharedNamespaces: sharesNS,
NumContainers: uint(len(containers)),
Containers: ctrs,
diff --git a/libpod/runtime.go b/libpod/runtime.go
index bf1e203c1..24370d50e 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -126,7 +126,7 @@ func SetXdgDirs() error {
// NewRuntime creates a new container runtime
// Options can be passed to override the default configuration for the runtime
-func NewRuntime(ctx context.Context, options ...RuntimeOption) (runtime *Runtime, err error) {
+func NewRuntime(ctx context.Context, options ...RuntimeOption) (*Runtime, error) {
conf, err := config.NewConfig("")
if err != nil {
return nil, err
@@ -140,13 +140,13 @@ func NewRuntime(ctx context.Context, options ...RuntimeOption) (runtime *Runtime
// functions can be used to mutate this configuration further.
// An error will be returned if the configuration file at the given path does
// not exist or cannot be loaded
-func NewRuntimeFromConfig(ctx context.Context, userConfig *config.Config, options ...RuntimeOption) (runtime *Runtime, err error) {
+func NewRuntimeFromConfig(ctx context.Context, userConfig *config.Config, options ...RuntimeOption) (*Runtime, error) {
return newRuntimeFromConfig(ctx, userConfig, options...)
}
-func newRuntimeFromConfig(ctx context.Context, conf *config.Config, options ...RuntimeOption) (runtime *Runtime, err error) {
- runtime = new(Runtime)
+func newRuntimeFromConfig(ctx context.Context, conf *config.Config, options ...RuntimeOption) (*Runtime, error) {
+ runtime := new(Runtime)
if conf.Engine.OCIRuntime == "" {
conf.Engine.OCIRuntime = "runc"
@@ -236,7 +236,7 @@ func getLockManager(runtime *Runtime) (lock.Manager, error) {
// Make a new runtime based on the given configuration
// Sets up containers/storage, state store, OCI runtime
-func makeRuntime(ctx context.Context, runtime *Runtime) (err error) {
+func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
// Find a working conmon binary
cPath, err := runtime.config.FindConmon()
if err != nil {
@@ -316,12 +316,11 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (err error) {
return err
}
defer func() {
- if err != nil && store != nil {
+ if retErr != nil && store != nil {
// Don't forcibly shut down
// We could be opening a store in use by another libpod
- _, err2 := store.Shutdown(false)
- if err2 != nil {
- logrus.Errorf("Error removing store for partially-created runtime: %s", err2)
+ if _, err := store.Shutdown(false); err != nil {
+ logrus.Errorf("Error removing store for partially-created runtime: %s", err)
}
}
}()
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index c073aabb5..e2bb696b0 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -34,7 +34,7 @@ type CtrCreateOption func(*Container) error
type ContainerFilter func(*Container) bool
// NewContainer creates a new container from a given OCI config.
-func (r *Runtime) NewContainer(ctx context.Context, rSpec *spec.Spec, options ...CtrCreateOption) (c *Container, err error) {
+func (r *Runtime) NewContainer(ctx context.Context, rSpec *spec.Spec, options ...CtrCreateOption) (*Container, error) {
r.lock.Lock()
defer r.lock.Unlock()
if !r.valid {
@@ -44,7 +44,7 @@ func (r *Runtime) NewContainer(ctx context.Context, rSpec *spec.Spec, options ..
}
// RestoreContainer re-creates a container from an imported checkpoint
-func (r *Runtime) RestoreContainer(ctx context.Context, rSpec *spec.Spec, config *ContainerConfig) (c *Container, err error) {
+func (r *Runtime) RestoreContainer(ctx context.Context, rSpec *spec.Spec, config *ContainerConfig) (*Container, error) {
r.lock.Lock()
defer r.lock.Unlock()
if !r.valid {
@@ -68,7 +68,7 @@ func (r *Runtime) RestoreContainer(ctx context.Context, rSpec *spec.Spec, config
return r.setupContainer(ctx, ctr)
}
-func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConfig) (c *Container, err error) {
+func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConfig) (*Container, error) {
if rSpec == nil {
return nil, errors.Wrapf(define.ErrInvalidArg, "must provide a valid runtime spec to create container")
}
@@ -122,7 +122,7 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf
return ctr, nil
}
-func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ...CtrCreateOption) (c *Container, err error) {
+func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ...CtrCreateOption) (*Container, error) {
span, _ := opentracing.StartSpanFromContext(ctx, "newContainer")
span.SetTag("type", "runtime")
defer span.Finish()
@@ -141,7 +141,7 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ..
return r.setupContainer(ctx, ctr)
}
-func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Container, err error) {
+func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Container, retErr error) {
// Validate the container
if err := ctr.validate(); err != nil {
return nil, err
@@ -157,9 +157,9 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
logrus.Debugf("Allocated lock %d for container %s", ctr.lock.ID(), ctr.ID())
defer func() {
- if err != nil {
- if err2 := ctr.lock.Free(); err2 != nil {
- logrus.Errorf("Error freeing lock for container after creation failed: %v", err2)
+ if retErr != nil {
+ if err := ctr.lock.Free(); err != nil {
+ logrus.Errorf("Error freeing lock for container after creation failed: %v", err)
}
}
}()
@@ -272,9 +272,9 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
return nil, err
}
defer func() {
- if err != nil {
- if err2 := ctr.teardownStorage(); err2 != nil {
- logrus.Errorf("Error removing partially-created container root filesystem: %s", err2)
+ if retErr != nil {
+ if err := ctr.teardownStorage(); err != nil {
+ logrus.Errorf("Error removing partially-created container root filesystem: %s", err)
}
}
}()
diff --git a/libpod/state_test.go b/libpod/state_test.go
index 30ddf5e24..ef4f6f2be 100644
--- a/libpod/state_test.go
+++ b/libpod/state_test.go
@@ -34,13 +34,13 @@ var (
)
// Get an empty BoltDB state for use in tests
-func getEmptyBoltState() (s State, p string, m lock.Manager, err error) {
+func getEmptyBoltState() (_ State, _ string, _ lock.Manager, retErr error) {
tmpDir, err := ioutil.TempDir("", tmpDirPrefix)
if err != nil {
return nil, "", nil, err
}
defer func() {
- if err != nil {
+ if retErr != nil {
os.RemoveAll(tmpDir)
}
}()
@@ -66,13 +66,13 @@ func getEmptyBoltState() (s State, p string, m lock.Manager, err error) {
}
// Get an empty in-memory state for use in tests
-func getEmptyInMemoryState() (s State, p string, m lock.Manager, err error) {
+func getEmptyInMemoryState() (_ State, _ string, _ lock.Manager, retErr error) {
tmpDir, err := ioutil.TempDir("", tmpDirPrefix)
if err != nil {
return nil, "", nil, err
}
defer func() {
- if err != nil {
+ if retErr != nil {
os.RemoveAll(tmpDir)
}
}()
diff --git a/libpod/storage.go b/libpod/storage.go
index be79b3fc0..e497d0daf 100644
--- a/libpod/storage.go
+++ b/libpod/storage.go
@@ -66,7 +66,7 @@ func (metadata *RuntimeContainerMetadata) SetMountLabel(mountLabel string) {
// CreateContainerStorage creates the storage end of things. We already have the container spec created
// TO-DO We should be passing in an Image object in the future.
-func (r *storageService) CreateContainerStorage(ctx context.Context, systemContext *types.SystemContext, imageName, imageID, containerName, containerID string, options storage.ContainerOptions) (cinfo ContainerInfo, err error) {
+func (r *storageService) CreateContainerStorage(ctx context.Context, systemContext *types.SystemContext, imageName, imageID, containerName, containerID string, options storage.ContainerOptions) (_ ContainerInfo, retErr error) {
span, _ := opentracing.StartSpanFromContext(ctx, "createContainerStorage")
span.SetTag("type", "storageService")
defer span.Finish()
@@ -132,9 +132,9 @@ func (r *storageService) CreateContainerStorage(ctx context.Context, systemConte
// If anything fails after this point, we need to delete the incomplete
// container before returning.
defer func() {
- if err != nil {
- if err2 := r.store.DeleteContainer(container.ID); err2 != nil {
- logrus.Infof("%v deleting partially-created container %q", err2, container.ID)
+ if retErr != nil {
+ if err := r.store.DeleteContainer(container.ID); err != nil {
+ logrus.Infof("%v deleting partially-created container %q", err, container.ID)
return
}
diff --git a/libpod/util.go b/libpod/util.go
index 7504295f0..8c2d946ba 100644
--- a/libpod/util.go
+++ b/libpod/util.go
@@ -15,6 +15,7 @@ import (
"github.com/containers/common/pkg/config"
"github.com/containers/libpod/v2/libpod/define"
"github.com/containers/libpod/v2/utils"
+ "github.com/cri-o/ocicni/pkg/ocicni"
"github.com/fsnotify/fsnotify"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
@@ -254,3 +255,21 @@ func makeHTTPAttachHeader(stream byte, length uint32) []byte {
binary.BigEndian.PutUint32(header[4:], length)
return header
}
+
+// Convert OCICNI port bindings into Inspect-formatted port bindings.
+func makeInspectPortBindings(bindings []ocicni.PortMapping) map[string][]define.InspectHostPort {
+ portBindings := make(map[string][]define.InspectHostPort)
+ for _, port := range bindings {
+ key := fmt.Sprintf("%d/%s", port.ContainerPort, port.Protocol)
+ hostPorts := portBindings[key]
+ if hostPorts == nil {
+ hostPorts = []define.InspectHostPort{}
+ }
+ hostPorts = append(hostPorts, define.InspectHostPort{
+ HostIP: port.HostIP,
+ HostPort: fmt.Sprintf("%d", port.HostPort),
+ })
+ portBindings[key] = hostPorts
+ }
+ return portBindings
+}