aboutsummaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_exec.go7
-rw-r--r--libpod/container_internal_linux.go10
-rw-r--r--libpod/define/errors.go3
-rw-r--r--libpod/define/info.go1
-rw-r--r--libpod/define/pod_inspect.go2
-rw-r--r--libpod/define/version.go10
-rw-r--r--libpod/healthcheck_linux.go5
-rw-r--r--libpod/image/image.go74
-rw-r--r--libpod/image/pull.go3
-rw-r--r--libpod/image/utils.go29
-rw-r--r--libpod/info.go1
-rw-r--r--libpod/kube.go18
-rw-r--r--libpod/oci_attach_linux.go2
-rw-r--r--libpod/oci_conmon_exec_linux.go27
-rw-r--r--libpod/oci_conmon_linux.go31
-rw-r--r--libpod/options.go50
-rw-r--r--libpod/pod.go4
-rw-r--r--libpod/pod_api.go2
-rw-r--r--libpod/rootless_cni_linux.go28
-rw-r--r--libpod/runtime_img.go3
-rw-r--r--libpod/runtime_pod_infra_linux.go34
21 files changed, 243 insertions, 101 deletions
diff --git a/libpod/container_exec.go b/libpod/container_exec.go
index f5f54c7cc..fce26acb0 100644
--- a/libpod/container_exec.go
+++ b/libpod/container_exec.go
@@ -980,11 +980,6 @@ func prepareForExec(c *Container, session *ExecSession) (*ExecOptions, error) {
capList = capabilities.AllCapabilities()
}
- user := c.config.User
- if session.Config.User != "" {
- user = session.Config.User
- }
-
if err := c.createExecBundle(session.ID()); err != nil {
return nil, err
}
@@ -995,7 +990,7 @@ func prepareForExec(c *Container, session *ExecSession) (*ExecOptions, error) {
opts.Env = session.Config.Environment
opts.Terminal = session.Config.Terminal
opts.Cwd = session.Config.WorkDir
- opts.User = user
+ opts.User = session.Config.User
opts.PreserveFDs = session.Config.PreserveFDs
opts.DetachKeys = session.Config.DetachKeys
opts.ExitCommand = session.Config.ExitCommand
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 86a28c176..eba732d2a 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -415,8 +415,9 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
// Look up and add groups the user belongs to, if a group wasn't directly specified
- if !rootless.IsRootless() && !strings.Contains(c.config.User, ":") {
+ if !strings.Contains(c.config.User, ":") {
for _, gid := range execUser.Sgids {
+ // FIXME: We need to add a flag to containers.conf to not add these for HPC Users.
g.AddProcessAdditionalGid(uint32(gid))
}
}
@@ -635,7 +636,7 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
Destination: "/sys/fs/cgroup/systemd",
Type: "bind",
Source: "/sys/fs/cgroup/systemd",
- Options: []string{"bind", "nodev", "nosuid", "rprivate"},
+ Options: []string{"bind", "nodev", "noexec", "nosuid", "rprivate"},
}
g.AddMount(systemdMnt)
g.AddLinuxMaskedPaths("/sys/fs/cgroup/systemd/release_agent")
@@ -1383,6 +1384,11 @@ func (c *Container) generateResolvConf() (string, error) {
return "", err
}
+ // Determine if symlink points to any of the systemd-resolved files
+ if strings.HasPrefix(resolvPath, "/run/systemd/resolve/") {
+ resolvPath = "/run/systemd/resolve/resolv.conf"
+ }
+
contents, err := ioutil.ReadFile(resolvPath)
if err != nil {
return "", errors.Wrapf(err, "unable to read %s", resolvPath)
diff --git a/libpod/define/errors.go b/libpod/define/errors.go
index b3f6483d1..627928ef7 100644
--- a/libpod/define/errors.go
+++ b/libpod/define/errors.go
@@ -162,6 +162,9 @@ var (
// in a pod. This cannot be done as the infra container has all the network information
ErrNetworkOnPodContainer = errors.New("network cannot be configured when it is shared with a pod")
+ // ErrNetworkInUse indicates the requested operation failed because the network was in use
+ ErrNetworkInUse = errors.New("network is being used")
+
// ErrStoreNotInitialized indicates that the container storage was never
// initialized.
ErrStoreNotInitialized = errors.New("the container storage was never initialized")
diff --git a/libpod/define/info.go b/libpod/define/info.go
index 47c53d067..f0e05801c 100644
--- a/libpod/define/info.go
+++ b/libpod/define/info.go
@@ -15,6 +15,7 @@ type Info struct {
type HostInfo struct {
Arch string `json:"arch"`
BuildahVersion string `json:"buildahVersion"`
+ CgroupManager string `json:"cgroupManager"`
CGroupsVersion string `json:"cgroupVersion"`
Conmon *ConmonInfo `json:"conmon"`
CPUs int `json:"cpus"`
diff --git a/libpod/define/pod_inspect.go b/libpod/define/pod_inspect.go
index 60e19fe05..a4115eb92 100644
--- a/libpod/define/pod_inspect.go
+++ b/libpod/define/pod_inspect.go
@@ -89,6 +89,8 @@ type InspectPodInfraConfig struct {
HostAdd []string
// Networks is a list of CNI networks the pod will join.
Networks []string
+ // NetworkOptions are additional options for each network
+ NetworkOptions map[string][]string
}
// InspectPodContainerInfo contains information on a container in a pod.
diff --git a/libpod/define/version.go b/libpod/define/version.go
index daa5cf7b2..d4cdd539d 100644
--- a/libpod/define/version.go
+++ b/libpod/define/version.go
@@ -18,9 +18,9 @@ var (
buildInfo string
)
-// Version is an output struct for varlink
+// Version is an output struct for API
type Version struct {
- APIVersion int64
+ APIVersion string
Version string
GoVersion string
GitCommit string
@@ -29,7 +29,7 @@ type Version struct {
OsArch string
}
-// GetVersion returns a VersionOutput struct for varlink and podman
+// GetVersion returns a VersionOutput struct for API and podman
func GetVersion() (Version, error) {
var err error
var buildTime int64
@@ -42,8 +42,8 @@ func GetVersion() (Version, error) {
}
}
return Version{
- APIVersion: podmanVersion.APIVersion,
- Version: podmanVersion.Version,
+ APIVersion: podmanVersion.APIVersion.String(),
+ Version: podmanVersion.Version.String(),
GoVersion: runtime.Version(),
GitCommit: gitCommit,
BuiltTime: time.Unix(buildTime, 0).Format(time.ANSIC),
diff --git a/libpod/healthcheck_linux.go b/libpod/healthcheck_linux.go
index 08f37d412..b0f1ff35d 100644
--- a/libpod/healthcheck_linux.go
+++ b/libpod/healthcheck_linux.go
@@ -35,9 +35,8 @@ func (c *Container) createTimer() error {
conn.Close()
logrus.Debugf("creating systemd-transient files: %s %s", "systemd-run", cmd)
systemdRun := exec.Command("systemd-run", cmd...)
- _, err = systemdRun.CombinedOutput()
- if err != nil {
- return err
+ if output, err := systemdRun.CombinedOutput(); err != nil {
+ return errors.Errorf("%s", output)
}
return nil
}
diff --git a/libpod/image/image.go b/libpod/image/image.go
index 850a48eae..f5bf47694 100644
--- a/libpod/image/image.go
+++ b/libpod/image/image.go
@@ -410,48 +410,92 @@ func (ir *Runtime) getLocalImage(inputName string) (string, *storage.Image, erro
if inputName == "" {
return "", nil, errors.Errorf("input name is blank")
}
+
// Check if the input name has a transport and if so strip it
dest, err := alltransports.ParseImageName(inputName)
if err == nil && dest.DockerReference() != nil {
inputName = dest.DockerReference().String()
}
- img, err := ir.getImage(stripSha256(inputName))
+ // Early check for fully-qualified images and (short) IDs.
+ img, err := ir.store.Image(stripSha256(inputName))
if err == nil {
- return inputName, img, err
+ return inputName, img, nil
}
- // container-storage wasn't able to find it in its current form
- // check if the input name has a tag, and if not, run it through
- // again
+ // Note that it's crucial to first decompose the image and check if
+ // it's a fully-qualified one or a "short name". The latter requires
+ // some normalization with search registries and the
+ // "localhost/prefix".
decomposedImage, err := decompose(inputName)
if err != nil {
+ // We may have a storage reference. We can't parse it to a
+ // reference before. Otherwise, we'd normalize "alpine" to
+ // "docker.io/library/alpine:latest" which would break the
+ // order in which we should query local images below.
+ if ref, err := is.Transport.ParseStoreReference(ir.store, inputName); err == nil {
+ img, err = is.Transport.GetStoreImage(ir.store, ref)
+ if err == nil {
+ return inputName, img, nil
+ }
+ }
return "", nil, err
}
- // The image has a registry name in it and we made sure we looked for it locally
- // with a tag. It cannot be local.
+ // The specified image is fully qualified, so it doesn't exist in the
+ // storage.
if decomposedImage.hasRegistry {
+ // However ... we may still need to normalize to docker.io:
+ // `docker.io/foo` -> `docker.io/library/foo`
+ if ref, err := is.Transport.ParseStoreReference(ir.store, inputName); err == nil {
+ img, err = is.Transport.GetStoreImage(ir.store, ref)
+ if err == nil {
+ return inputName, img, nil
+ }
+ }
return "", nil, errors.Wrapf(ErrNoSuchImage, imageError)
}
- // if the image is saved with the repository localhost, searching with localhost prepended is necessary
- // We don't need to strip the sha because we have already determined it is not an ID
- ref, err := decomposedImage.referenceWithRegistry(DefaultLocalRegistry)
+
+ // "Short-name image", so let's try out certain prefixes:
+ // 1) DefaultLocalRegistry (i.e., "localhost/)
+ // 2) Unqualified-search registries from registries.conf
+ unqualifiedSearchRegistries, err := registries.GetRegistries()
if err != nil {
return "", nil, err
}
- img, err = ir.getImage(ref.String())
+
+ for _, candidate := range append([]string{DefaultLocalRegistry}, unqualifiedSearchRegistries...) {
+ ref, err := decomposedImage.referenceWithRegistry(candidate)
+ if err != nil {
+ return "", nil, err
+ }
+ img, err := ir.store.Image(ref.String())
+ if err == nil {
+ return ref.String(), img, nil
+ }
+ }
+
+ // Backwards compat: normalize to docker.io as some users may very well
+ // rely on that.
+ ref, err := is.Transport.ParseStoreReference(ir.store, inputName)
if err == nil {
- return inputName, img, err
+ img, err = is.Transport.GetStoreImage(ir.store, ref)
+ if err == nil {
+ return inputName, img, nil
+ }
}
- // grab all the local images
+ // Last resort: look at the repotags of all images and try to find a
+ // match.
images, err := ir.GetImages()
if err != nil {
return "", nil, err
}
- // check the repotags of all images for a match
+ decomposedImage, err = decompose(inputName)
+ if err != nil {
+ return "", nil, err
+ }
repoImage, err := findImageInRepotags(decomposedImage, images)
if err == nil {
return inputName, repoImage, nil
@@ -1284,7 +1328,7 @@ func (ir *Runtime) Import(ctx context.Context, path, reference string, writer io
return nil, errors.Wrapf(err, "error updating image config")
}
- sc := GetSystemContext("", "", false)
+ sc := GetSystemContext(ir.SignaturePolicyPath, "", false)
// if reference not given, get the image digest
if reference == "" {
diff --git a/libpod/image/pull.go b/libpod/image/pull.go
index 94d6af4c2..65acdf427 100644
--- a/libpod/image/pull.go
+++ b/libpod/image/pull.go
@@ -255,6 +255,9 @@ func (ir *Runtime) pullImageFromHeuristicSource(ctx context.Context, inputName s
sc.ArchitectureChoice = dockerOptions.ArchitectureChoice
sc.VariantChoice = dockerOptions.VariantChoice
}
+ if signaturePolicyPath == "" {
+ sc.SignaturePolicyPath = ir.SignaturePolicyPath
+ }
sc.BlobInfoCacheDir = filepath.Join(ir.store.GraphRoot(), "cache")
srcRef, err := alltransports.ParseImageName(inputName)
if err != nil {
diff --git a/libpod/image/utils.go b/libpod/image/utils.go
index b7ea63c66..2538f429b 100644
--- a/libpod/image/utils.go
+++ b/libpod/image/utils.go
@@ -33,7 +33,7 @@ func findImageInRepotags(search imageParts, images []*Image) (*storage.Image, er
continue
}
// account for registry:/somedir/image
- if strings.HasSuffix(dName, searchName) && dSuspiciousTagValueForSearch == searchSuspiciousTagValueForSearch {
+ if strings.HasSuffix(dName, "/"+searchName) && dSuspiciousTagValueForSearch == searchSuspiciousTagValueForSearch {
results = append(results, image.image)
continue
}
@@ -86,33 +86,6 @@ func hasTransport(image string) bool {
return strings.Contains(image, "://")
}
-// ReposToMap parses the specified repotags and returns a map with repositories
-// as keys and the corresponding arrays of tags or digests-as-strings as values.
-func ReposToMap(names []string) (map[string][]string, error) {
- // map format is repo -> []tag-or-digest
- repos := make(map[string][]string)
- for _, name := range names {
- var repository, tag string
- if len(name) > 0 {
- named, err := reference.ParseNormalizedNamed(name)
- if err != nil {
- return nil, err
- }
- repository = named.Name()
- if ref, ok := named.(reference.NamedTagged); ok {
- tag = ref.Tag()
- } else if ref, ok := named.(reference.Canonical); ok {
- tag = ref.Digest().String()
- }
- }
- repos[repository] = append(repos[repository], tag)
- }
- if len(repos) == 0 {
- repos["<none>"] = []string{"<none>"}
- }
- return repos, nil
-}
-
// GetAdditionalTags returns a list of reference.NamedTagged for the
// additional tags given in images
func GetAdditionalTags(images []string) ([]reference.NamedTagged, error) {
diff --git a/libpod/info.go b/libpod/info.go
index 153000b6f..dd7a521c1 100644
--- a/libpod/info.go
+++ b/libpod/info.go
@@ -87,6 +87,7 @@ func (r *Runtime) hostInfo() (*define.HostInfo, error) {
info := define.HostInfo{
Arch: runtime.GOARCH,
BuildahVersion: buildah.Version,
+ CgroupManager: r.config.Engine.CgroupManager,
Linkmode: linkmode.Linkmode(),
CPUs: runtime.NumCPU(),
Distribution: hostDistributionInfo,
diff --git a/libpod/kube.go b/libpod/kube.go
index 9d5cbe68b..f83e99d82 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -77,6 +77,24 @@ func (p *Pod) GenerateForKube() (*v1.Pod, []v1.ServicePort, error) {
}
pod.Spec.HostAliases = extraHost
+ // vendor/k8s.io/api/core/v1/types.go: v1.Container cannot save restartPolicy
+ // so set it at here
+ for _, ctr := range allContainers {
+ if !ctr.IsInfra() {
+ switch ctr.Config().RestartPolicy {
+ case RestartPolicyAlways:
+ pod.Spec.RestartPolicy = v1.RestartPolicyAlways
+ case RestartPolicyOnFailure:
+ pod.Spec.RestartPolicy = v1.RestartPolicyOnFailure
+ case RestartPolicyNo:
+ pod.Spec.RestartPolicy = v1.RestartPolicyNever
+ default: // some pod create from cmdline, such as "", so set it to Never
+ pod.Spec.RestartPolicy = v1.RestartPolicyNever
+ }
+ break
+ }
+ }
+
if p.SharesPID() {
// unfortunately, go doesn't have a nice way to specify a pointer to a bool
b := true
diff --git a/libpod/oci_attach_linux.go b/libpod/oci_attach_linux.go
index 74af449ed..149ee813b 100644
--- a/libpod/oci_attach_linux.go
+++ b/libpod/oci_attach_linux.go
@@ -14,7 +14,7 @@ import (
"github.com/containers/podman/v2/pkg/errorhandling"
"github.com/containers/podman/v2/pkg/kubeutils"
"github.com/containers/podman/v2/utils"
- "github.com/docker/docker/pkg/term"
+ "github.com/moby/term"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
diff --git a/libpod/oci_conmon_exec_linux.go b/libpod/oci_conmon_exec_linux.go
index c18da68fe..8651c1dc5 100644
--- a/libpod/oci_conmon_exec_linux.go
+++ b/libpod/oci_conmon_exec_linux.go
@@ -537,9 +537,6 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp
}
}()
- // Make a channel to pass errors back
- errChan := make(chan error)
-
attachStdout := true
attachStderr := true
attachStdin := true
@@ -580,13 +577,16 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp
hijackWriteErrorAndClose(deferredErr, c.ID(), isTerminal, httpCon, httpBuf)
}()
+ stdoutChan := make(chan error)
+ stdinChan := make(chan error)
+
// Next, STDIN. Avoid entirely if attachStdin unset.
if attachStdin {
go func() {
logrus.Debugf("Beginning STDIN copy")
_, err := utils.CopyDetachable(conn, httpBuf, detachKeys)
logrus.Debugf("STDIN copy completed")
- errChan <- err
+ stdinChan <- err
}()
}
@@ -613,19 +613,24 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp
logrus.Debugf("Performing non-terminal HTTP attach for container %s", c.ID())
err = httpAttachNonTerminalCopy(conn, httpBuf, c.ID(), attachStdin, attachStdout, attachStderr)
}
- errChan <- err
+ stdoutChan <- err
logrus.Debugf("STDOUT/ERR copy completed")
}()
- if cancel != nil {
+ for {
select {
- case err := <-errChan:
- return err
+ case err := <-stdoutChan:
+ if err != nil {
+ return err
+ }
+
+ return nil
+ case err := <-stdinChan:
+ if err != nil {
+ return err
+ }
case <-cancel:
return nil
}
- } else {
- var connErr error = <-errChan
- return connErr
}
}
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 5769e5580..1d4f33794 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -555,9 +555,6 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
return err
}
- // Make a channel to pass errors back
- errChan := make(chan error)
-
attachStdout := true
attachStderr := true
attachStdin := true
@@ -672,6 +669,9 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
logrus.Debugf("Forwarding attach output for container %s", ctr.ID())
+ stdoutChan := make(chan error)
+ stdinChan := make(chan error)
+
// Handle STDOUT/STDERR
go func() {
var err error
@@ -690,7 +690,7 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
logrus.Debugf("Performing non-terminal HTTP attach for container %s", ctr.ID())
err = httpAttachNonTerminalCopy(conn, httpBuf, ctr.ID(), attachStdin, attachStdout, attachStderr)
}
- errChan <- err
+ stdoutChan <- err
logrus.Debugf("STDOUT/ERR copy completed")
}()
// Next, STDIN. Avoid entirely if attachStdin unset.
@@ -698,20 +698,25 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
go func() {
_, err := utils.CopyDetachable(conn, httpBuf, detach)
logrus.Debugf("STDIN copy completed")
- errChan <- err
+ stdinChan <- err
}()
}
- if cancel != nil {
+ for {
select {
- case err := <-errChan:
- return err
+ case err := <-stdoutChan:
+ if err != nil {
+ return err
+ }
+
+ return nil
+ case err := <-stdinChan:
+ if err != nil {
+ return err
+ }
case <-cancel:
return nil
}
- } else {
- var connErr error = <-errChan
- return connErr
}
}
@@ -1330,10 +1335,10 @@ func (r *ConmonOCIRuntime) sharedConmonArgs(ctr *Container, cuuid, bundlePath, p
switch logDriver {
case define.JournaldLogging:
logDriverArg = define.JournaldLogging
- case define.JSONLogging:
- fallthrough
case define.NoLogging:
logDriverArg = define.NoLogging
+ case define.JSONLogging:
+ fallthrough
default: //nolint-stylecheck
// No case here should happen except JSONLogging, but keep this here in case the options are extended
logrus.Errorf("%s logging specified but not supported. Choosing k8s-file logging instead", ctr.LogDriver())
diff --git a/libpod/options.go b/libpod/options.go
index d592124bc..f7190d0e3 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1659,6 +1659,36 @@ func WithUmask(umask string) CtrCreateOption {
// Pod Creation Options
+// WithInfraImage sets the infra image for libpod.
+// An infra image is used for inter-container kernel
+// namespace sharing within a pod. Typically, an infra
+// container is lightweight and is there to reap
+// zombie processes within its pid namespace.
+func WithInfraImage(img string) PodCreateOption {
+ return func(pod *Pod) error {
+ if pod.valid {
+ return define.ErrPodFinalized
+ }
+
+ pod.config.InfraContainer.InfraImage = img
+
+ return nil
+ }
+}
+
+// WithInfraCommand sets the command to
+// run on pause container start up.
+func WithInfraCommand(cmd []string) PodCreateOption {
+ return func(pod *Pod) error {
+ if pod.valid {
+ return define.ErrPodFinalized
+ }
+
+ pod.config.InfraContainer.InfraCommand = cmd
+ return nil
+ }
+}
+
// WithPodName sets the name of the pod.
func WithPodName(name string) PodCreateOption {
return func(pod *Pod) error {
@@ -2173,3 +2203,23 @@ func WithPodInfraExitCommand(exitCmd []string) PodCreateOption {
return nil
}
}
+
+// WithPodSlirp4netns tells the pod to use slirp4netns.
+func WithPodSlirp4netns(networkOptions map[string][]string) PodCreateOption {
+ return func(pod *Pod) error {
+ if pod.valid {
+ return define.ErrPodFinalized
+ }
+
+ if !pod.config.InfraContainer.HasInfraContainer {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod networking as no infra container is being created")
+ }
+ if pod.config.InfraContainer.HostNetwork {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot set both HostNetwork and Slirp4netns")
+ }
+ pod.config.InfraContainer.Slirp4netns = true
+ pod.config.InfraContainer.NetworkOptions = networkOptions
+
+ return nil
+ }
+}
diff --git a/libpod/pod.go b/libpod/pod.go
index 422966b94..a5a0532be 100644
--- a/libpod/pod.go
+++ b/libpod/pod.go
@@ -105,6 +105,10 @@ type InfraContainerConfig struct {
HostAdd []string `json:"hostsAdd,omitempty"`
Networks []string `json:"networks,omitempty"`
ExitCommand []string `json:"exitCommand,omitempty"`
+ InfraImage string `json:"infraImage,omitempty"`
+ InfraCommand []string `json:"infraCommand,omitempty"`
+ Slirp4netns bool `json:"slirp4netns,omitempty"`
+ NetworkOptions map[string][]string `json:"network_options,omitempty"`
}
// ID retrieves the pod's ID
diff --git a/libpod/pod_api.go b/libpod/pod_api.go
index ec4cc08f7..0ae180356 100644
--- a/libpod/pod_api.go
+++ b/libpod/pod_api.go
@@ -584,7 +584,7 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
infraConfig.Networks = make([]string, 0, len(p.config.InfraContainer.Networks))
infraConfig.Networks = append(infraConfig.Networks, p.config.InfraContainer.Networks...)
}
-
+ infraConfig.NetworkOptions = p.config.InfraContainer.NetworkOptions
infraConfig.PortBindings = makeInspectPortBindings(p.config.InfraContainer.PortBindings)
}
diff --git a/libpod/rootless_cni_linux.go b/libpod/rootless_cni_linux.go
index 76dbfdcae..21e43ebd0 100644
--- a/libpod/rootless_cni_linux.go
+++ b/libpod/rootless_cni_linux.go
@@ -13,6 +13,7 @@ import (
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/image"
+ "github.com/containers/podman/v2/pkg/env"
"github.com/containers/podman/v2/pkg/util"
"github.com/containers/storage/pkg/lockfile"
"github.com/hashicorp/go-multierror"
@@ -22,10 +23,9 @@ import (
"github.com/sirupsen/logrus"
)
+// Built from ../contrib/rootless-cni-infra.
var rootlessCNIInfraImage = map[string]string{
- // Built from ../contrib/rootless-cni-infra
- // TODO: move to Podman's official quay
- "amd64": "ghcr.io/akihirosuda/podman-rootless-cni-infra:gd34868a13-amd64",
+ "amd64": "quay.io/libpod/rootless-cni-infra@sha256:304742d5d221211df4ec672807a5842ff11e3729c50bc424ea0cea858f69d7b7", // 3-amd64
}
const (
@@ -255,12 +255,26 @@ func startRootlessCNIInfraContainer(ctx context.Context, r *Runtime) (*Container
Destination: "/etc/cni/net.d",
Type: "bind",
Source: r.config.Network.NetworkConfigDir,
- Options: []string{"ro"},
+ Options: []string{"ro", "bind"},
}
g.AddMount(etcCNINetD)
- // FIXME: how to propagate ProcessArgs and Envs from Dockerfile?
- g.SetProcessArgs([]string{"sleep", "infinity"})
- g.AddProcessEnv("CNI_PATH", "/opt/cni/bin")
+
+ inspectData, err := newImage.Inspect(ctx)
+ if err != nil {
+ return nil, err
+ }
+ imageEnv, err := env.ParseSlice(inspectData.Config.Env)
+ if err != nil {
+ return nil, err
+ }
+ for k, v := range imageEnv {
+ g.AddProcessEnv(k, v)
+ }
+ if len(inspectData.Config.Cmd) == 0 {
+ return nil, errors.Errorf("rootless CNI infra image %q has no command specified", imageName)
+ }
+ g.SetProcessArgs(inspectData.Config.Cmd)
+
var options []CtrCreateOption
options = append(options, WithRootFSFromImage(newImage.ID(), imageName, imageName))
options = append(options, WithCtrNamespace(rootlessCNIInfraContainerNamespace))
diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go
index eb4512f8d..e57890fa2 100644
--- a/libpod/runtime_img.go
+++ b/libpod/runtime_img.go
@@ -174,7 +174,7 @@ func (r *Runtime) Build(ctx context.Context, options imagebuildah.BuildOptions,
}
// Import is called as an intermediary to the image library Import
-func (r *Runtime) Import(ctx context.Context, source string, reference string, changes []string, history string, quiet bool) (string, error) {
+func (r *Runtime) Import(ctx context.Context, source, reference, signaturePolicyPath string, changes []string, history string, quiet bool) (string, error) {
var (
writer io.Writer
err error
@@ -223,6 +223,7 @@ func (r *Runtime) Import(ctx context.Context, source string, reference string, c
source = file
}
+ r.imageRuntime.SignaturePolicyPath = signaturePolicyPath
newImage, err := r.imageRuntime.Import(ctx, source, reference, writer, image.SigningOptions{}, config)
if err != nil {
return "", err
diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go
index b2f21d946..7f58e86d8 100644
--- a/libpod/runtime_pod_infra_linux.go
+++ b/libpod/runtime_pod_infra_linux.go
@@ -36,22 +36,30 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
isRootless := rootless.IsRootless()
- entryCmd := []string{r.config.Engine.InfraCommand}
+ entrypointSet := len(p.config.InfraContainer.InfraCommand) > 0
+ entryPoint := p.config.InfraContainer.InfraCommand
+ entryCmd := []string{}
var options []CtrCreateOption
// I've seen circumstances where config is being passed as nil.
// Let's err on the side of safety and make sure it's safe to use.
if config != nil {
- setEntrypoint := false
// default to entrypoint in image if there is one
- if len(config.Entrypoint) > 0 {
- entryCmd = config.Entrypoint
- setEntrypoint = true
+ if !entrypointSet {
+ if len(config.Entrypoint) > 0 {
+ entrypointSet = true
+ entryPoint = config.Entrypoint
+ entryCmd = config.Entrypoint
+ }
+ } else { // so use the InfraCommand
+ entrypointSet = true
+ entryCmd = entryPoint
}
+
if len(config.Cmd) > 0 {
// We can't use the default pause command, since we're
// sourcing from the image. If we didn't already set an
// entrypoint, set one now.
- if !setEntrypoint {
+ if !entrypointSet {
// Use the Docker default "/bin/sh -c"
// entrypoint, as we're overriding command.
// If an image doesn't want this, it can
@@ -73,8 +81,11 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
// Since user namespace sharing is not implemented, we only need to check if it's rootless
if !p.config.InfraContainer.HostNetwork {
netmode := "bridge"
- if isRootless {
+ if isRootless || p.config.InfraContainer.Slirp4netns {
netmode = "slirp4netns"
+ if len(p.config.InfraContainer.NetworkOptions) != 0 {
+ options = append(options, WithNetworkOptions(p.config.InfraContainer.NetworkOptions))
+ }
}
// PostConfigureNetNS should not be set since user namespace sharing is not implemented
// and rootless networking no longer supports post configuration setup
@@ -136,6 +147,9 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
options = append(options, WithRootFSFromImage(imgID, imgName, rawImageName))
options = append(options, WithName(containerName))
options = append(options, withIsInfra())
+ if entrypointSet {
+ options = append(options, WithEntrypoint(entryPoint))
+ }
if len(p.config.InfraContainer.ConmonPidFile) > 0 {
options = append(options, WithConmonPidFile(p.config.InfraContainer.ConmonPidFile))
}
@@ -151,7 +165,11 @@ func (r *Runtime) createInfraContainer(ctx context.Context, p *Pod) (*Container,
return nil, define.ErrRuntimeStopped
}
- newImage, err := r.ImageRuntime().New(ctx, r.config.Engine.InfraImage, "", "", nil, nil, image.SigningOptions{}, nil, util.PullImageMissing)
+ img := p.config.InfraContainer.InfraImage
+ if img == "" {
+ img = r.config.Engine.InfraImage
+ }
+ newImage, err := r.ImageRuntime().New(ctx, img, "", "", nil, nil, image.SigningOptions{}, nil, util.PullImageMissing)
if err != nil {
return nil, err
}