diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container.go | 2 | ||||
-rw-r--r-- | libpod/container_api.go | 5 | ||||
-rw-r--r-- | libpod/image/pull.go | 9 | ||||
-rw-r--r-- | libpod/oci.go | 22 | ||||
-rw-r--r-- | libpod/runtime.go | 32 |
5 files changed, 45 insertions, 25 deletions
diff --git a/libpod/container.go b/libpod/container.go index e748cb84d..f68a3535e 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -36,6 +36,8 @@ const ( ContainerStateStopped ContainerStatus = iota // ContainerStatePaused indicates that the container has been paused ContainerStatePaused ContainerStatus = iota + // WaitTimeout is the wait timeout before checking for container exit + WaitTimeout = time.Second / time.Millisecond ) // CgroupfsDefaultCgroupParent is the cgroup parent for CGroupFS in libpod diff --git a/libpod/container_api.go b/libpod/container_api.go index 86e2370ea..437699bae 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -592,12 +592,11 @@ func (c *Container) Inspect(size bool) (*inspect.ContainerInspectData, error) { } // Wait blocks on a container to exit and returns its exit code -func (c *Container) Wait() (int32, error) { +func (c *Container) Wait(waitTimeout time.Duration) (int32, error) { if !c.valid { return -1, ErrCtrRemoved } - - err := wait.PollImmediateInfinite(100*time.Millisecond, + err := wait.PollImmediateInfinite(waitTimeout*time.Millisecond, func() (bool, error) { stopped, err := c.isStopped() if err != nil { diff --git a/libpod/image/pull.go b/libpod/image/pull.go index ce3e8e73e..9eac2b988 100644 --- a/libpod/image/pull.go +++ b/libpod/image/pull.go @@ -20,6 +20,7 @@ import ( "github.com/containers/image/types" "github.com/containers/libpod/pkg/registries" "github.com/containers/libpod/pkg/util" + multierror "github.com/hashicorp/go-multierror" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -234,6 +235,7 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa return nil, err } var images []string + var pullErrors *multierror.Error for _, imageInfo := range goal.refPairs { copyOptions := getCopyOptions(sc, writer, dockerOptions, nil, signingOptions, "", nil) if imageInfo.srcRef.Transport().Name() == DockerTransport { @@ -254,6 +256,7 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa io.WriteString(writer, fmt.Sprintf("Trying to pull %s...", imageInfo.image)) } if err = cp.Image(ctx, policyContext, imageInfo.dstRef, imageInfo.srcRef, copyOptions); err != nil { + pullErrors = multierror.Append(pullErrors, err) logrus.Debugf("Error pulling image ref %s: %v", imageInfo.srcRef.StringWithinTransport(), err) if writer != nil { io.WriteString(writer, "Failed\n") @@ -273,10 +276,12 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa } // If the image passed in was fully-qualified, we will have 1 refpair. Bc the image is fq'd, we dont need to yap about registries. if !goal.usedSearchRegistries { + if pullErrors != nil && len(pullErrors.Errors) > 0 { // this should always be true + return nil, errors.Wrap(pullErrors.Errors[0], "unable to pull image") + } return nil, errors.Errorf("unable to pull image, or you do not have pull access") } - return nil, errors.Errorf("unable to find image on registries defined in %s, or you do not have pull access", registryPath) - + return nil, pullErrors } return images, nil } diff --git a/libpod/oci.go b/libpod/oci.go index e1c0d1261..3838394cb 100644 --- a/libpod/oci.go +++ b/libpod/oci.go @@ -66,6 +66,7 @@ type OCIRuntime struct { socketsDir string logSizeMax int64 noPivot bool + reservePorts bool } // syncInfo is used to return data from monitor process to daemon @@ -75,7 +76,7 @@ type syncInfo struct { } // Make a new OCI runtime with provided options -func newOCIRuntime(name string, path string, conmonPath string, conmonEnv []string, cgroupManager string, tmpDir string, logSizeMax int64, noPivotRoot bool) (*OCIRuntime, error) { +func newOCIRuntime(name string, path string, conmonPath string, conmonEnv []string, cgroupManager string, tmpDir string, logSizeMax int64, noPivotRoot bool, reservePorts bool) (*OCIRuntime, error) { runtime := new(OCIRuntime) runtime.name = name runtime.path = path @@ -85,6 +86,7 @@ func newOCIRuntime(name string, path string, conmonPath string, conmonEnv []stri runtime.tmpDir = tmpDir runtime.logSizeMax = logSizeMax runtime.noPivot = noPivotRoot + runtime.reservePorts = reservePorts runtime.exitsDir = filepath.Join(runtime.tmpDir, "exits") runtime.socketsDir = filepath.Join(runtime.tmpDir, "socket") @@ -311,15 +313,17 @@ func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string) (er cmd.Env = append(cmd.Env, fmt.Sprintf("_OCI_STARTPIPE=%d", 4)) cmd.Env = append(cmd.Env, fmt.Sprintf("XDG_RUNTIME_DIR=%s", runtimeDir)) - ports, err := bindPorts(ctr.config.PortMappings) - if err != nil { - return err - } + if r.reservePorts { + ports, err := bindPorts(ctr.config.PortMappings) + if err != nil { + return err + } - // Leak the port we bound in the conmon process. These fd's won't be used - // by the container and conmon will keep the ports busy so that another - // process cannot use them. - cmd.ExtraFiles = append(cmd.ExtraFiles, ports...) + // Leak the port we bound in the conmon process. These fd's won't be used + // by the container and conmon will keep the ports busy so that another + // process cannot use them. + cmd.ExtraFiles = append(cmd.ExtraFiles, ports...) + } if rootless.IsRootless() { ctr.rootlessSlirpSyncR, ctr.rootlessSlirpSyncW, err = os.Pipe() diff --git a/libpod/runtime.go b/libpod/runtime.go index 63b8c971e..736169932 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -164,6 +164,14 @@ type RuntimeConfig struct { InfraImage string `toml:"infra_image"` // InfraCommand is the command run to start up a pod infra container InfraCommand string `toml:"infra_command"` + // EnablePortReservation determines whether libpod will reserve ports on + // the host when they are forwarded to containers. + // When enabled, when ports are forwarded to containers, they are + // held open by conmon as long as the container is running, ensuring + // that they cannot be reused by other programs on the host. + // However, this can cause significant memory usage if a container has + // many ports forwarded to it. Disabling this can save memory. + EnablePortReservation bool `toml:"enable_port_reservation"` } var ( @@ -190,16 +198,17 @@ var ( ConmonEnvVars: []string{ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", }, - CgroupManager: SystemdCgroupsManager, - HooksDir: hooks.DefaultDir, - StaticDir: filepath.Join(storage.DefaultStoreOptions.GraphRoot, "libpod"), - TmpDir: "", - MaxLogSize: -1, - NoPivotRoot: false, - CNIConfigDir: "/etc/cni/net.d/", - CNIPluginDir: []string{"/usr/libexec/cni", "/usr/lib/cni", "/opt/cni/bin"}, - InfraCommand: DefaultInfraCommand, - InfraImage: DefaultInfraImage, + CgroupManager: SystemdCgroupsManager, + HooksDir: hooks.DefaultDir, + StaticDir: filepath.Join(storage.DefaultStoreOptions.GraphRoot, "libpod"), + TmpDir: "", + MaxLogSize: -1, + NoPivotRoot: false, + CNIConfigDir: "/etc/cni/net.d/", + CNIPluginDir: []string{"/usr/libexec/cni", "/usr/lib/cni", "/opt/cni/bin"}, + InfraCommand: DefaultInfraCommand, + InfraImage: DefaultInfraImage, + EnablePortReservation: true, } ) @@ -467,7 +476,8 @@ func makeRuntime(runtime *Runtime) (err error) { ociRuntime, err := newOCIRuntime("runc", runtime.ociRuntimePath, runtime.conmonPath, runtime.config.ConmonEnvVars, runtime.config.CgroupManager, runtime.config.TmpDir, - runtime.config.MaxLogSize, runtime.config.NoPivotRoot) + runtime.config.MaxLogSize, runtime.config.NoPivotRoot, + runtime.config.EnablePortReservation) if err != nil { return err } |