diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container_config.go | 2 | ||||
-rw-r--r-- | libpod/container_inspect.go | 4 | ||||
-rw-r--r-- | libpod/container_internal.go | 47 | ||||
-rw-r--r-- | libpod/container_internal_linux.go | 10 | ||||
-rw-r--r-- | libpod/define/info.go | 2 | ||||
-rw-r--r-- | libpod/define/pod_inspect.go | 2 | ||||
-rw-r--r-- | libpod/info.go | 6 | ||||
-rw-r--r-- | libpod/networking_linux.go | 1 | ||||
-rw-r--r-- | libpod/oci_conmon_linux.go | 1 | ||||
-rw-r--r-- | libpod/oci_util.go | 13 | ||||
-rw-r--r-- | libpod/options.go | 3 | ||||
-rw-r--r-- | libpod/pod_api.go | 7 |
12 files changed, 90 insertions, 8 deletions
diff --git a/libpod/container_config.go b/libpod/container_config.go index b80b23c25..a2c989a1a 100644 --- a/libpod/container_config.go +++ b/libpod/container_config.go @@ -107,6 +107,8 @@ type ContainerRootFSConfig struct { // as the container's root. // Conflicts with RootfsImageID. Rootfs string `json:"rootfs,omitempty"` + // RootfsOverlay tells if rootfs has to be mounted as an overlay + RootfsOverlay bool `json:"rootfs_overlay,omitempty"` // ShmDir is the path to be mounted on /dev/shm in container. // If not set manually at creation time, Libpod will create a tmpfs // with the size specified in ShmSize and populate this with the path of diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 2ef4532cd..530160b2d 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -92,7 +92,7 @@ func (c *Container) getContainerInspectData(size bool, driverData *define.Driver } namedVolumes, mounts := c.sortUserVolumes(ctrSpec) - inspectMounts, err := c.getInspectMounts(namedVolumes, c.config.ImageVolumes, mounts) + inspectMounts, err := c.GetInspectMounts(namedVolumes, c.config.ImageVolumes, mounts) if err != nil { return nil, err } @@ -194,7 +194,7 @@ func (c *Container) getContainerInspectData(size bool, driverData *define.Driver // Get inspect-formatted mounts list. // Only includes user-specified mounts. Only includes bind mounts and named // volumes, not tmpfs volumes. -func (c *Container) getInspectMounts(namedVolumes []*ContainerNamedVolume, imageVolumes []*ContainerImageVolume, mounts []spec.Mount) ([]define.InspectMount, error) { +func (c *Container) GetInspectMounts(namedVolumes []*ContainerNamedVolume, imageVolumes []*ContainerImageVolume, mounts []spec.Mount) ([]define.InspectMount, error) { inspectMounts := []define.InspectMount{} // No mounts, return early diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 4d1a25541..1033729ae 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -15,6 +15,7 @@ import ( metadata "github.com/checkpoint-restore/checkpointctl/lib" "github.com/containers/buildah/copier" + "github.com/containers/buildah/pkg/overlay" butil "github.com/containers/buildah/util" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/events" @@ -293,6 +294,15 @@ func (c *Container) handleRestartPolicy(ctx context.Context) (_ bool, retErr err } } + // setup rootlesskit port forwarder again since it dies when conmon exits + // we use rootlesskit port forwarder only as rootless and when bridge network is used + if rootless.IsRootless() && c.config.NetMode.IsBridge() && len(c.config.PortMappings) > 0 { + err := c.runtime.setupRootlessPortMappingViaRLK(c, c.state.NetNS.Path()) + if err != nil { + return false, err + } + } + if c.state.State == define.ContainerStateStopped { // Reinitialize the container if we need to if err := c.reinit(ctx, true); err != nil { @@ -1541,6 +1551,32 @@ func (c *Container) mountStorage() (_ string, deferredErr error) { // We need to mount the container before volumes - to ensure the copyup // works properly. 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()) + if err != nil { + return "", errors.Wrapf(err, "rootfs-overlay: failed to create TempDir in the %s directory", overlayDest) + } + overlayMount, err := overlay.Mount(contentDir, c.config.Rootfs, overlayDest, c.RootUID(), c.RootGID(), c.runtime.store.GraphOptions()) + if err != nil { + return "", errors.Wrapf(err, "rootfs-overlay: creating overlay failed %q", c.config.Rootfs) + } + + // Seems fuse-overlayfs is not present + // fallback to native overlay + if overlayMount.Type == "overlay" { + overlayMount.Options = append(overlayMount.Options, "nodev") + mountOpts := label.FormatMountLabel(strings.Join(overlayMount.Options, ","), c.MountLabel()) + err = mount.Mount("overlay", overlayMount.Source, overlayMount.Type, mountOpts) + if err != nil { + return "", errors.Wrapf(err, "rootfs-overlay: creating overlay failed %q from native overlay", c.config.Rootfs) + } + } + + mountPoint = overlayMount.Source + } + if mountPoint == "" { mountPoint, err = c.mount() if err != nil { @@ -1714,6 +1750,17 @@ func (c *Container) cleanupStorage() error { var cleanupErr error + // umount rootfs overlay if it was created + if c.config.RootfsOverlay { + overlayBasePath := c.runtime.store.GraphRoot() + overlayBasePath = filepath.Join(overlayBasePath, "rootfs") + 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) + cleanupErr = err + } + } + for _, containerMount := range c.config.Mounts { if err := c.unmountSHM(containerMount); err != nil { if cleanupErr != nil { diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 34f84203b..4194a0d93 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -2489,11 +2489,6 @@ func (c *Container) getOCICgroupPath() (string, error) { switch { case c.config.NoCgroups: return "", nil - case (rootless.IsRootless() && (cgroupManager == config.CgroupfsCgroupsManager || !unified)): - if !isRootlessCgroupSet(c.config.CgroupParent) { - return "", nil - } - return c.config.CgroupParent, nil case c.config.CgroupsMode == cgroupSplit: selfCgroup, err := utils.GetOwnCgroup() if err != nil { @@ -2507,6 +2502,11 @@ func (c *Container) getOCICgroupPath() (string, error) { systemdCgroups := fmt.Sprintf("%s:libpod:%s", path.Base(c.config.CgroupParent), c.ID()) logrus.Debugf("Setting CGroups for container %s to %s", c.ID(), systemdCgroups) return systemdCgroups, nil + case (rootless.IsRootless() && (cgroupManager == config.CgroupfsCgroupsManager || !unified)): + if c.config.CgroupParent == "" || !isRootlessCgroupSet(c.config.CgroupParent) { + return "", nil + } + fallthrough case cgroupManager == config.CgroupfsCgroupsManager: cgroupPath := filepath.Join(c.config.CgroupParent, fmt.Sprintf("libpod-%s", c.ID())) logrus.Debugf("Setting CGroup path for container %s to %s", c.ID(), cgroupPath) diff --git a/libpod/define/info.go b/libpod/define/info.go index 73df80087..f4aa0031c 100644 --- a/libpod/define/info.go +++ b/libpod/define/info.go @@ -78,7 +78,9 @@ type IDMappings struct { // for libpod type DistributionInfo struct { Distribution string `json:"distribution"` + Variant string `json:"variant,omitempty"` Version string `json:"version"` + Codename string `json:"codename,omitempty"` } // ConmonInfo describes the conmon executable being used diff --git a/libpod/define/pod_inspect.go b/libpod/define/pod_inspect.go index f91fd198d..b7a6e76b5 100644 --- a/libpod/define/pod_inspect.go +++ b/libpod/define/pod_inspect.go @@ -57,6 +57,8 @@ type InspectPodData struct { CPUQuota int64 `json:"cpu_quota,omitempty"` // CPUSetCPUs contains linux specific CPU data for the pod CPUSetCPUs string `json:"cpuset_cpus,omitempty"` + // Mounts contains volume related information for the pod + Mounts []InspectMount `json:"mounts,omitempty"` } // InspectPodInfraConfig contains the configuration of the pod's infra diff --git a/libpod/info.go b/libpod/info.go index 31ec9cdc1..2eba4bbff 100644 --- a/libpod/info.go +++ b/libpod/info.go @@ -370,9 +370,15 @@ func (r *Runtime) GetHostDistributionInfo() define.DistributionInfo { if strings.HasPrefix(l.Text(), "ID=") { dist.Distribution = strings.TrimPrefix(l.Text(), "ID=") } + if strings.HasPrefix(l.Text(), "VARIANT_ID=") { + dist.Variant = strings.Trim(strings.TrimPrefix(l.Text(), "VARIANT_ID="), "\"") + } if strings.HasPrefix(l.Text(), "VERSION_ID=") { dist.Version = strings.Trim(strings.TrimPrefix(l.Text(), "VERSION_ID="), "\"") } + if strings.HasPrefix(l.Text(), "VERSION_CODENAME=") { + dist.Codename = strings.Trim(strings.TrimPrefix(l.Text(), "VERSION_CODENAME="), "\"") + } } return dist } diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 9aa6cab15..b0d4e0b2d 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -718,6 +718,7 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) error { // set up port forwarder for CNI-in-slirp4netns netnsPath := ctr.state.NetNS.Path() // TODO: support slirp4netns port forwarder as well + // make sure to fix this container.handleRestartPolicy() as well return r.setupRootlessPortMappingViaRLK(ctr, netnsPath) } return nil diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go index c00d83f95..831e89223 100644 --- a/libpod/oci_conmon_linux.go +++ b/libpod/oci_conmon_linux.go @@ -1140,6 +1140,7 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co if err != nil { return err } + filesToClose = append(filesToClose, 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 diff --git a/libpod/oci_util.go b/libpod/oci_util.go index 1cafd5863..f2843b09b 100644 --- a/libpod/oci_util.go +++ b/libpod/oci_util.go @@ -68,6 +68,12 @@ func bindPorts(ports []ocicni.PortMapping) ([]*os.File, error) { return nil, errors.Wrapf(err, "cannot get file for UDP socket") } files = append(files, f) + // close the listener + // note that this does not affect the fd, see the godoc for server.File() + err = server.Close() + if err != nil { + logrus.Warnf("failed to close connection: %v", err) + } case "tcp": var ( @@ -96,6 +102,13 @@ func bindPorts(ports []ocicni.PortMapping) ([]*os.File, error) { return nil, errors.Wrapf(err, "cannot get file for TCP socket") } files = append(files, f) + // close the listener + // note that this does not affect the fd, see the godoc for server.File() + err = server.Close() + if err != nil { + logrus.Warnf("failed to close connection: %v", err) + } + case "sctp": if !notifySCTP { notifySCTP = true diff --git a/libpod/options.go b/libpod/options.go index 4cbd2b5e2..7b0c6641a 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -1337,7 +1337,7 @@ func WithCommand(command []string) CtrCreateOption { // WithRootFS sets the rootfs for the container. // This creates a container from a directory on disk and not an image. -func WithRootFS(rootfs string) CtrCreateOption { +func WithRootFS(rootfs string, overlay bool) CtrCreateOption { return func(ctr *Container) error { if ctr.valid { return define.ErrCtrFinalized @@ -1346,6 +1346,7 @@ func WithRootFS(rootfs string) CtrCreateOption { return err } ctr.config.Rootfs = rootfs + ctr.config.RootfsOverlay = overlay return nil } } diff --git a/libpod/pod_api.go b/libpod/pod_api.go index 5f4d983b9..4e0acf950 100644 --- a/libpod/pod_api.go +++ b/libpod/pod_api.go @@ -582,6 +582,7 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) { // Infra config contains detailed information on the pod's infra // container. var infraConfig *define.InspectPodInfraConfig + var inspectMounts []define.InspectMount if p.state.InfraContainerID != "" { infra, err := p.runtime.GetContainer(p.state.InfraContainerID) if err != nil { @@ -597,6 +598,11 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) { infraConfig.CPUSetCPUs = p.ResourceLim().CPU.Cpus infraConfig.PidNS = p.PidMode() infraConfig.UserNS = p.UserNSMode() + namedVolumes, mounts := infra.sortUserVolumes(infra.Config().Spec) + inspectMounts, err = infra.GetInspectMounts(namedVolumes, infra.config.ImageVolumes, mounts) + if err != nil { + return nil, err + } if len(infra.Config().ContainerNetworkConfig.DNSServer) > 0 { infraConfig.DNSServer = make([]string, 0, len(infra.Config().ContainerNetworkConfig.DNSServer)) @@ -645,6 +651,7 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) { CPUSetCPUs: p.ResourceLim().CPU.Cpus, CPUPeriod: p.CPUPeriod(), CPUQuota: p.CPUQuota(), + Mounts: inspectMounts, } return &inspectData, nil |