summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_internal.go22
-rw-r--r--libpod/container_internal_linux.go5
-rw-r--r--libpod/container_log_linux.go33
-rw-r--r--libpod/info.go2
-rw-r--r--libpod/kube.go15
-rw-r--r--libpod/network/cni/cni_types.go2
-rw-r--r--libpod/network/cni/run.go6
-rw-r--r--libpod/networking_slirp4netns.go39
-rw-r--r--libpod/options.go2
-rw-r--r--libpod/runtime.go6
-rw-r--r--libpod/runtime_ctr.go2
11 files changed, 101 insertions, 33 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 994ffeec7..b9805faa3 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -457,10 +457,12 @@ func (c *Container) setupStorage(ctx context.Context) error {
options.StorageOpt[split2[0]] = split2[1]
}
}
- if c.restoreFromCheckpoint && !c.config.Privileged {
- // If restoring from a checkpoint, the root file-system
- // needs to be mounted with the same SELinux labels as
- // it was mounted previously.
+ if c.restoreFromCheckpoint && c.config.ProcessLabel != "" && c.config.MountLabel != "" {
+ // If restoring from a checkpoint, the root file-system needs
+ // to be mounted with the same SELinux labels as it was mounted
+ // previously. But only if both labels have been set. For
+ // privileged containers or '--ipc host' only ProcessLabel will
+ // be set and so we will skip it for cases like that.
if options.Flags == nil {
options.Flags = make(map[string]interface{})
}
@@ -1511,8 +1513,8 @@ func (c *Container) mountStorage() (_ string, deferredErr error) {
mountPoint := c.config.Rootfs
// Check if overlay has to be created on top of Rootfs
if c.config.RootfsOverlay {
- overlayDest := c.runtime.store.GraphRoot()
- contentDir, err := overlay.GenerateStructure(c.runtime.store.GraphRoot(), c.ID(), "rootfs", c.RootUID(), c.RootGID())
+ overlayDest := c.runtime.RunRoot()
+ contentDir, err := overlay.GenerateStructure(overlayDest, c.ID(), "rootfs", c.RootUID(), c.RootGID())
if err != nil {
return "", errors.Wrapf(err, "rootfs-overlay: failed to create TempDir in the %s directory", overlayDest)
}
@@ -1737,11 +1739,11 @@ func (c *Container) cleanupStorage() error {
// umount rootfs overlay if it was created
if c.config.RootfsOverlay {
- overlayBasePath := filepath.Dir(c.config.StaticDir)
- overlayBasePath = filepath.Join(overlayBasePath, "rootfs")
+ overlayBasePath := filepath.Dir(c.state.Mountpoint)
if err := overlay.Unmount(overlayBasePath); err != nil {
- // If the container can't remove content report the error
- logrus.Errorf("Failed to cleanup overlay mounts for %s: %v", c.ID(), err)
+ if cleanupErr != nil {
+ logrus.Errorf("Failed to cleanup overlay mounts for %s: %v", c.ID(), err)
+ }
cleanupErr = err
}
}
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 27cc318b4..d3151f7e0 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -322,7 +322,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
return nil, err
}
- g := generate.Generator{Config: c.config.Spec}
+ g := generate.NewFromSpec(c.config.Spec)
// If network namespace was requested, add it now
if c.config.CreateNetNS {
@@ -1219,7 +1219,8 @@ func (c *Container) importCheckpoint(input string) error {
}
// Make sure the newly created config.json exists on disk
- g := generate.Generator{Config: c.config.Spec}
+ g := generate.NewFromSpec(c.config.Spec)
+
if err := c.saveSpec(g.Config); err != nil {
return errors.Wrap(err, "saving imported container specification for restore failed")
}
diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go
index 562169ce2..4029d0af7 100644
--- a/libpod/container_log_linux.go
+++ b/libpod/container_log_linux.go
@@ -121,7 +121,24 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
}()
tailQueue := []*logs.LogLine{} // needed for options.Tail
- doTail := options.Tail > 0
+ doTail := options.Tail >= 0
+ doTailFunc := func() {
+ // Flush *once* we hit the end of the journal.
+ startIndex := int64(len(tailQueue))
+ outputLines := int64(0)
+ for startIndex > 0 && outputLines < options.Tail {
+ startIndex--
+ for startIndex > 0 && tailQueue[startIndex].Partial() {
+ startIndex--
+ }
+ outputLines++
+ }
+ for i := startIndex; i < int64(len(tailQueue)); i++ {
+ logChannel <- tailQueue[i]
+ }
+ tailQueue = nil
+ doTail = false
+ }
lastReadCursor := ""
for {
select {
@@ -152,16 +169,7 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
// Hit the end of the journal (so far?).
if cursor == lastReadCursor {
if doTail {
- // Flush *once* we hit the end of the journal.
- startIndex := int64(len(tailQueue)-1) - options.Tail
- if startIndex < 0 {
- startIndex = 0
- }
- for i := startIndex; i < int64(len(tailQueue)); i++ {
- logChannel <- tailQueue[i]
- }
- tailQueue = nil
- doTail = false
+ doTailFunc()
}
// Unless we follow, quit.
if !options.Follow {
@@ -194,6 +202,9 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
return
}
if status == events.Exited {
+ if doTail {
+ doTailFunc()
+ }
return
}
continue
diff --git a/libpod/info.go b/libpod/info.go
index a2fd18491..8d0b19f23 100644
--- a/libpod/info.go
+++ b/libpod/info.go
@@ -332,7 +332,7 @@ func readKernelVersion() (string, error) {
return "", err
}
f := bytes.Fields(buf)
- if len(f) < 2 {
+ if len(f) < 3 {
return string(bytes.TrimSpace(buf)), nil
}
return string(f[2]), nil
diff --git a/libpod/kube.go b/libpod/kube.go
index 02ac8ed98..ad5acea78 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -11,6 +11,7 @@ import (
"strings"
"time"
+ "github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/env"
@@ -468,11 +469,23 @@ func containerToV1Container(ctx context.Context, c *Container) (v1.Container, []
kubeContainer.Name = removeUnderscores(c.Name())
_, image := c.Image()
+
+ // The infra container may have been created with an overlay root FS
+ // instead of an infra image. If so, set the imageto the default K8s
+ // pause one and make sure it's in the storage by pulling it down if
+ // missing.
+ if image == "" && c.IsInfra() {
+ image = config.DefaultInfraImage
+ if _, err := c.runtime.libimageRuntime.Pull(ctx, image, config.PullPolicyMissing, nil); err != nil {
+ return kubeContainer, nil, nil, nil, err
+ }
+ }
+
kubeContainer.Image = image
kubeContainer.Stdin = c.Stdin()
img, _, err := c.runtime.libimageRuntime.LookupImage(image, nil)
if err != nil {
- return kubeContainer, kubeVolumes, nil, annotations, err
+ return kubeContainer, kubeVolumes, nil, annotations, fmt.Errorf("looking up image %q of container %q: %w", image, c.ID(), err)
}
imgData, err := img.Inspect(ctx, nil)
if err != nil {
diff --git a/libpod/network/cni/cni_types.go b/libpod/network/cni/cni_types.go
index 87beceff3..c70cb92b6 100644
--- a/libpod/network/cni/cni_types.go
+++ b/libpod/network/cni/cni_types.go
@@ -176,7 +176,7 @@ func newIPAMLocalHostRange(subnet types.IPNet, leaseRange *types.LeaseRange, gw
Subnet: subnet.String(),
}
- // an user provided a range, we add it here
+ // a user provided a range, we add it here
if leaseRange != nil {
if leaseRange.StartIP != nil {
hostRange.RangeStart = leaseRange.StartIP.String()
diff --git a/libpod/network/cni/run.go b/libpod/network/cni/run.go
index bd873f89b..99b2adce5 100644
--- a/libpod/network/cni/run.go
+++ b/libpod/network/cni/run.go
@@ -196,10 +196,8 @@ func getRuntimeConfig(netns, conName, conID, networkName string, ports []cniPort
IfName: opts.InterfaceName,
Args: [][2]string{
{"IgnoreUnknown", "1"},
- // FIXME: Should we set the K8S args?
- //{"K8S_POD_NAMESPACE", conName},
- //{"K8S_POD_INFRA_CONTAINER_ID", conID},
- // K8S_POD_NAME is used by dnsname to get the container name
+ // Do not set the K8S env vars, see https://github.com/containers/podman/issues/12083.
+ // Only K8S_POD_NAME is used by dnsname to get the container name.
{"K8S_POD_NAME", conName},
},
CapabilityArgs: map[string]interface{}{},
diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go
index ffd53ec2b..56e8eca99 100644
--- a/libpod/networking_slirp4netns.go
+++ b/libpod/networking_slirp4netns.go
@@ -16,6 +16,7 @@ import (
"syscall"
"time"
+ "github.com/containernetworking/plugins/pkg/ns"
"github.com/containers/podman/v3/pkg/errorhandling"
"github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/podman/v3/pkg/rootlessport"
@@ -58,6 +59,8 @@ type slirp4netnsNetworkOptions struct {
outboundAddr6 string
}
+const ipv6ConfDefaultAcceptDadSysctl = "/proc/sys/net/ipv6/conf/default/accept_dad"
+
func checkSlirpFlags(path string) (*slirpFeatures, error) {
cmd := exec.Command(path, "--help")
out, err := cmd.CombinedOutput()
@@ -297,6 +300,39 @@ func (r *Runtime) setupSlirp4netns(ctr *Container) error {
}
cmd.Stdout = logFile
cmd.Stderr = logFile
+
+ var slirpReadyChan (chan struct{})
+
+ if netOptions.enableIPv6 {
+ slirpReadyChan = make(chan struct{})
+ defer close(slirpReadyChan)
+ go func() {
+ err := ns.WithNetNSPath(netnsPath, func(_ ns.NetNS) error {
+ // Duplicate Address Detection slows the ipv6 setup down for 1-2 seconds.
+ // Since slirp4netns is run it is own namespace and not directly routed
+ // we can skip this to make the ipv6 address immediately available.
+ // We change the default to make sure the slirp tap interface gets the
+ // correct value assigned so DAD is disabled for it
+ // Also make sure to change this value back to the original after slirp4netns
+ // is ready in case users rely on this sysctl.
+ orgValue, err := ioutil.ReadFile(ipv6ConfDefaultAcceptDadSysctl)
+ if err != nil {
+ return err
+ }
+ err = ioutil.WriteFile(ipv6ConfDefaultAcceptDadSysctl, []byte("0"), 0644)
+ if err != nil {
+ return err
+ }
+ // wait for slirp to finish setup
+ <-slirpReadyChan
+ return ioutil.WriteFile(ipv6ConfDefaultAcceptDadSysctl, orgValue, 0644)
+ })
+ if err != nil {
+ logrus.Warnf("failed to set net.ipv6.conf.default.accept_dad sysctl: %v", err)
+ }
+ }()
+ }
+
if err := cmd.Start(); err != nil {
return errors.Wrapf(err, "failed to start slirp4netns process")
}
@@ -310,6 +346,9 @@ func (r *Runtime) setupSlirp4netns(ctr *Container) error {
if err := waitForSync(syncR, cmd, logFile, 1*time.Second); err != nil {
return err
}
+ if slirpReadyChan != nil {
+ slirpReadyChan <- struct{}{}
+ }
// Set a default slirp subnet. Parsing a string with the net helper is easier than building the struct myself
_, ctr.slirp4netnsSubnet, _ = net.ParseCIDR(defaultSlirp4netnsSubnet)
diff --git a/libpod/options.go b/libpod/options.go
index 9762de67e..135b2f363 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -969,7 +969,7 @@ func WithUserNSFrom(nsCtr *Container) CtrCreateOption {
if err := JSONDeepCopy(nsCtr.IDMappings(), &ctr.config.IDMappings); err != nil {
return err
}
- g := generate.Generator{Config: ctr.config.Spec}
+ g := generate.NewFromSpec(ctr.config.Spec)
g.ClearLinuxUIDMappings()
for _, uidmap := range nsCtr.config.IDMappings.UIDMap {
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 855f3a9f9..950ac65eb 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -543,7 +543,11 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
return err
}
if became {
- utils.MovePauseProcessToScope(pausePid)
+ // Check if the pause process was created. If it was created, then
+ // move it to its own systemd scope.
+ if _, err = os.Stat(pausePid); err == nil {
+ utils.MovePauseProcessToScope(pausePid)
+ }
os.Exit(ret)
}
}
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 2256ba57c..0a7db33f1 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -389,7 +389,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
if ctr.restoreFromCheckpoint {
// Remove information about bind mount
// for new container from imported checkpoint
- g := generate.Generator{Config: ctr.config.Spec}
+ g := generate.NewFromSpec(ctr.config.Spec)
g.RemoveMount("/dev/shm")
ctr.config.ShmDir = ""
g.RemoveMount("/etc/resolv.conf")