diff options
Diffstat (limited to 'libpod/container_internal_linux.go')
-rw-r--r-- | libpod/container_internal_linux.go | 95 |
1 files changed, 65 insertions, 30 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index afcf51a11..d06c19b8c 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -63,12 +63,12 @@ func (c *Container) unmountSHM(mount string) error { // namespaces func (c *Container) prepare() (err error) { var ( - wg sync.WaitGroup - netNS ns.NetNS - networkStatus []*cnitypes.Result - createNetNSErr, mountStorageErr error - mountPoint string - tmpStateLock sync.Mutex + wg sync.WaitGroup + netNS ns.NetNS + networkStatus []*cnitypes.Result + createNetNSErr, mountStorageErr, rootlessSetupErr error + mountPoint string + tmpStateLock sync.Mutex ) wg.Add(2) @@ -87,6 +87,11 @@ func (c *Container) prepare() (err error) { c.state.NetNS = netNS c.state.NetworkStatus = networkStatus } + + // Setup rootless networking, requires c.state.NetNS to be set + if rootless.IsRootless() { + rootlessSetupErr = c.runtime.setupRootlessNetNS(c) + } } }() // Mount storage if not mounted @@ -132,6 +137,10 @@ func (c *Container) prepare() (err error) { return mountStorageErr } + if rootlessSetupErr != nil { + return rootlessSetupErr + } + // Save the container return c.save() } @@ -185,11 +194,11 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { // If network namespace was requested, add it now if c.config.CreateNetNS { if c.config.PostConfigureNetNS { - if err := g.AddOrReplaceLinuxNamespace(spec.NetworkNamespace, ""); err != nil { + if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), ""); err != nil { return nil, err } } else { - if err := g.AddOrReplaceLinuxNamespace(spec.NetworkNamespace, c.state.NetNS.Path()); err != nil { + if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), c.state.NetNS.Path()); err != nil { return nil, err } } @@ -310,7 +319,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { } } if c.config.PIDNsCtr != "" { - if err := c.addNamespaceContainer(&g, PIDNS, c.config.PIDNsCtr, string(spec.PIDNamespace)); err != nil { + if err := c.addNamespaceContainer(&g, PIDNS, c.config.PIDNsCtr, spec.PIDNamespace); err != nil { return nil, err } } @@ -340,7 +349,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { g.AddAnnotation("org.opencontainers.image.stopSignal", fmt.Sprintf("%d", c.config.StopSignal)) for _, i := range c.config.Spec.Linux.Namespaces { - if string(i.Type) == spec.UTSNamespace { + if i.Type == spec.UTSNamespace { hostname := c.Hostname() g.SetHostname(hostname) g.AddProcessEnv("HOSTNAME", hostname) @@ -466,37 +475,55 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro g.AddMount(tmpfsMnt) } - // rootless containers have no write access to /sys/fs/cgroup, so don't - // add any mount into the container. - if !rootless.IsRootless() { - cgroupPath, err := c.CGroupPath() - if err != nil { - return err - } - sourcePath := filepath.Join("/sys/fs/cgroup/systemd", cgroupPath) + unified, err := cgroups.IsCgroup2UnifiedMode() + if err != nil { + return err + } + g.RemoveMount("/sys/fs/cgroup") + + if unified { + sourcePath := filepath.Join("/sys/fs/cgroup") systemdMnt := spec.Mount{ - Destination: "/sys/fs/cgroup/systemd", + Destination: "/sys/fs/cgroup", Type: "bind", Source: sourcePath, - Options: []string{"bind", "private"}, + Options: []string{"bind", "private", "rw"}, } g.AddMount(systemdMnt) } else { - systemdMnt := spec.Mount{ - Destination: "/sys/fs/cgroup/systemd", - Type: "bind", - Source: "/sys/fs/cgroup/systemd", - Options: []string{"bind", "nodev", "noexec", "nosuid"}, + // rootless containers have no write access to /sys/fs/cgroup, so don't + // add any mount into the container. + if !rootless.IsRootless() { + cgroupPath, err := c.CGroupPath() + if err != nil { + return err + } + sourcePath := filepath.Join("/sys/fs/cgroup", cgroupPath) + + systemdMnt := spec.Mount{ + Destination: "/sys/fs/cgroup", + Type: "bind", + Source: sourcePath, + Options: []string{"bind", "private"}, + } + g.AddMount(systemdMnt) + } else { + systemdMnt := spec.Mount{ + Destination: "/sys/fs/cgroup", + Type: "bind", + Source: "/sys/fs/cgroup", + Options: []string{"bind", "nodev", "noexec", "nosuid"}, + } + g.AddMount(systemdMnt) } - g.AddMount(systemdMnt) } return nil } // Add an existing container's namespace to the spec -func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr string, specNS string) error { +func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr string, specNS spec.LinuxNamespaceType) error { nsCtr, err := c.runtime.state.Container(ctr) if err != nil { return errors.Wrapf(err, "error retrieving dependency %s of container %s from state", ctr, c.ID()) @@ -508,7 +535,7 @@ func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr return err } - if err := g.AddOrReplaceLinuxNamespace(specNS, nsPath); err != nil { + if err := g.AddOrReplaceLinuxNamespace(string(specNS), nsPath); err != nil { return err } @@ -725,6 +752,14 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti return err } + // If a container is restored multiple times from an exported checkpoint with + // the help of '--import --name', the restore will fail if during 'podman run' + // a static container IP was set with '--ip'. The user can tell the restore + // process to ignore the static IP with '--ignore-static-ip' + if options.IgnoreStaticIP { + c.config.StaticIP = nil + } + // Read network configuration from checkpoint // Currently only one interface with one IP is supported. networkStatusFile, err := os.Open(filepath.Join(c.bundlePath(), "network.status")) @@ -734,7 +769,7 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti // TODO: This implicit restoring with or without IP depending on an // unrelated restore parameter (--name) does not seem like the // best solution. - if err == nil && options.Name == "" { + if err == nil && options.Name == "" && !options.IgnoreStaticIP { // The file with the network.status does exist. Let's restore the // container with the same IP address as during checkpointing. defer networkStatusFile.Close() @@ -787,7 +822,7 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti // We want to have the same network namespace as before. if c.config.CreateNetNS { - if err := g.AddOrReplaceLinuxNamespace(spec.NetworkNamespace, c.state.NetNS.Path()); err != nil { + if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), c.state.NetNS.Path()); err != nil { return err } } |