mirror of
https://github.com/containers/podman.git
synced 2025-12-03 03:39:44 +08:00
vendor in containers/(common,buildah,storage,image)
Changes as of 2022-04-21: - apply-podman-deltas: minor cleanup - buildah-tests.diff: deal with: . buildah #3894 (the registry one), which affected helpers.bash in a way that resulted in conflicts here; and . buildah #3917 (etchosts), which caused offset-only diffs with no conflicts - Reevaluate the bud skip list, and reenable some tests that seems to be passing now under podman: . bud with specified context ... . two tests that require a local registry (which buildah now runs) . bud with --cgroup-parent Signed-off-by: Ed Santiago <santiago@redhat.com> Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
472
vendor/github.com/containers/buildah/run_linux.go
generated
vendored
472
vendor/github.com/containers/buildah/run_linux.go
generated
vendored
@@ -33,10 +33,10 @@ import (
|
||||
"github.com/containers/buildah/pkg/parse"
|
||||
"github.com/containers/buildah/pkg/sshagent"
|
||||
"github.com/containers/buildah/util"
|
||||
"github.com/containers/common/libnetwork/etchosts"
|
||||
"github.com/containers/common/libnetwork/network"
|
||||
nettypes "github.com/containers/common/libnetwork/types"
|
||||
"github.com/containers/common/pkg/capabilities"
|
||||
"github.com/containers/common/pkg/cgroups"
|
||||
"github.com/containers/common/pkg/chown"
|
||||
"github.com/containers/common/pkg/config"
|
||||
"github.com/containers/common/pkg/subscriptions"
|
||||
@@ -222,14 +222,24 @@ func (b *Builder) Run(command []string, options RunOptions) error {
|
||||
}
|
||||
rootIDPair := &idtools.IDPair{UID: int(rootUID), GID: int(rootGID)}
|
||||
|
||||
if !options.NoHosts && !contains(volumes, "/etc/hosts") {
|
||||
hostFile, err := b.generateHosts(path, spec.Hostname, b.CommonBuildOpts.AddHost, rootIDPair)
|
||||
hostFile := ""
|
||||
if !options.NoHosts && !contains(volumes, config.DefaultHostsFile) && options.ConfigureNetwork != define.NetworkDisabled {
|
||||
hostFile, err = b.generateHosts(path, rootIDPair, mountPoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Only bind /etc/hosts if there's a network
|
||||
if options.ConfigureNetwork != define.NetworkDisabled {
|
||||
bindFiles["/etc/hosts"] = hostFile
|
||||
bindFiles[config.DefaultHostsFile] = hostFile
|
||||
}
|
||||
|
||||
// generate /etc/hostname if the user intentionally did not override
|
||||
if !(contains(volumes, "/etc/hostname")) {
|
||||
if _, ok := bindFiles["/etc/hostname"]; !ok {
|
||||
hostFile, err := b.generateHostname(path, spec.Hostname, rootIDPair)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Bind /etc/hostname
|
||||
bindFiles["/etc/hostname"] = hostFile
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,7 +283,7 @@ rootless=%d
|
||||
|
||||
bindFiles["/run/.containerenv"] = containerenvPath
|
||||
}
|
||||
runArtifacts, err := b.setupMounts(options.SystemContext, mountPoint, spec, path, options.Mounts, bindFiles, volumes, b.CommonBuildOpts.Volumes, b.CommonBuildOpts.ShmSize, namespaceOptions, options.Secrets, options.SSHSources, options.RunMounts, options.ContextDir, options.StageMountPoints)
|
||||
runArtifacts, err := b.setupMounts(options.SystemContext, mountPoint, spec, path, options.Mounts, bindFiles, volumes, b.CommonBuildOpts.Volumes, options.Secrets, options.SSHSources, options.RunMounts, options.ContextDir, options.StageMountPoints)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error resolving mountpoints for container %q", b.ContainerID)
|
||||
}
|
||||
@@ -303,7 +313,8 @@ rootless=%d
|
||||
if options.NoPivot {
|
||||
moreCreateArgs = append(moreCreateArgs, "--no-pivot")
|
||||
}
|
||||
err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, configureNetworks, moreCreateArgs, spec, mountPoint, path, define.Package+"-"+filepath.Base(path))
|
||||
err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, configureNetworks, moreCreateArgs, spec,
|
||||
mountPoint, path, define.Package+"-"+filepath.Base(path), b.Container, hostFile)
|
||||
case IsolationChroot:
|
||||
err = chroot.RunUsingChroot(spec, path, homeDir, options.Stdin, options.Stdout, options.Stderr)
|
||||
case IsolationOCIRootless:
|
||||
@@ -311,10 +322,8 @@ rootless=%d
|
||||
if options.NoPivot {
|
||||
moreCreateArgs = append(moreCreateArgs, "--no-pivot")
|
||||
}
|
||||
if err := setupRootlessSpecChanges(spec, path, b.CommonBuildOpts.ShmSize); err != nil {
|
||||
return err
|
||||
}
|
||||
err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, configureNetworks, moreCreateArgs, spec, mountPoint, path, define.Package+"-"+filepath.Base(path))
|
||||
err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, configureNetworks, moreCreateArgs, spec,
|
||||
mountPoint, path, define.Package+"-"+filepath.Base(path), b.Container, hostFile)
|
||||
default:
|
||||
err = errors.Errorf("don't know how to run this command")
|
||||
}
|
||||
@@ -431,7 +440,7 @@ func runSetupBuiltinVolumes(mountLabel, mountPoint, containerDir string, builtin
|
||||
return mounts, nil
|
||||
}
|
||||
|
||||
func (b *Builder) setupMounts(context *imagetypes.SystemContext, mountPoint string, spec *specs.Spec, bundlePath string, optionMounts []specs.Mount, bindFiles map[string]string, builtinVolumes, volumeMounts []string, shmSize string, namespaceOptions define.NamespaceOptions, secrets map[string]define.Secret, sshSources map[string]*sshagent.Source, runFileMounts []string, contextDir string, stageMountPoints map[string]internal.StageMountDetails) (*runMountArtifacts, error) {
|
||||
func (b *Builder) setupMounts(context *imagetypes.SystemContext, mountPoint string, spec *specs.Spec, bundlePath string, optionMounts []specs.Mount, bindFiles map[string]string, builtinVolumes, volumeMounts []string, secrets map[string]define.Secret, sshSources map[string]*sshagent.Source, runFileMounts []string, contextDir string, stageMountPoints map[string]internal.StageMountDetails) (*runMountArtifacts, error) {
|
||||
// Start building a new list of mounts.
|
||||
var mounts []specs.Mount
|
||||
haveMount := func(destination string) bool {
|
||||
@@ -444,79 +453,9 @@ func (b *Builder) setupMounts(context *imagetypes.SystemContext, mountPoint stri
|
||||
return false
|
||||
}
|
||||
|
||||
ipc := namespaceOptions.Find(string(specs.IPCNamespace))
|
||||
hostIPC := ipc == nil || ipc.Host
|
||||
net := namespaceOptions.Find(string(specs.NetworkNamespace))
|
||||
hostNetwork := net == nil || net.Host
|
||||
user := namespaceOptions.Find(string(specs.UserNamespace))
|
||||
hostUser := (user == nil || user.Host) && !unshare.IsRootless()
|
||||
|
||||
// Copy mounts from the generated list.
|
||||
mountCgroups := true
|
||||
specMounts := []specs.Mount{}
|
||||
for _, specMount := range spec.Mounts {
|
||||
// Override some of the mounts from the generated list if we're doing different things with namespaces.
|
||||
if specMount.Destination == "/dev/shm" {
|
||||
specMount.Options = []string{"nosuid", "noexec", "nodev", "mode=1777"}
|
||||
if shmSize != "" {
|
||||
specMount.Options = append(specMount.Options, "size="+shmSize)
|
||||
}
|
||||
if hostIPC && !hostUser {
|
||||
if _, err := os.Stat("/dev/shm"); err != nil && os.IsNotExist(err) {
|
||||
logrus.Debugf("/dev/shm is not present, not binding into container")
|
||||
continue
|
||||
}
|
||||
specMount = specs.Mount{
|
||||
Source: "/dev/shm",
|
||||
Type: "bind",
|
||||
Destination: "/dev/shm",
|
||||
Options: []string{bind.NoBindOption, "rbind", "nosuid", "noexec", "nodev"},
|
||||
}
|
||||
}
|
||||
}
|
||||
if specMount.Destination == "/dev/mqueue" {
|
||||
if hostIPC && !hostUser {
|
||||
if _, err := os.Stat("/dev/mqueue"); err != nil && os.IsNotExist(err) {
|
||||
logrus.Debugf("/dev/mqueue is not present, not binding into container")
|
||||
continue
|
||||
}
|
||||
specMount = specs.Mount{
|
||||
Source: "/dev/mqueue",
|
||||
Type: "bind",
|
||||
Destination: "/dev/mqueue",
|
||||
Options: []string{bind.NoBindOption, "rbind", "nosuid", "noexec", "nodev"},
|
||||
}
|
||||
}
|
||||
}
|
||||
if specMount.Destination == "/sys" {
|
||||
if hostNetwork && !hostUser {
|
||||
mountCgroups = false
|
||||
if _, err := os.Stat("/sys"); err != nil && os.IsNotExist(err) {
|
||||
logrus.Debugf("/sys is not present, not binding into container")
|
||||
continue
|
||||
}
|
||||
specMount = specs.Mount{
|
||||
Source: "/sys",
|
||||
Type: "bind",
|
||||
Destination: "/sys",
|
||||
Options: []string{bind.NoBindOption, "rbind", "nosuid", "noexec", "nodev", "ro"},
|
||||
}
|
||||
}
|
||||
}
|
||||
specMounts = append(specMounts, specMount)
|
||||
}
|
||||
|
||||
// Add a mount for the cgroups filesystem, unless we're already
|
||||
// recursively bind mounting all of /sys, in which case we shouldn't
|
||||
// bother with it.
|
||||
sysfsMount := []specs.Mount{}
|
||||
if mountCgroups {
|
||||
sysfsMount = []specs.Mount{{
|
||||
Destination: "/sys/fs/cgroup",
|
||||
Type: "cgroup",
|
||||
Source: "cgroup",
|
||||
Options: []string{bind.NoBindOption, "nosuid", "noexec", "nodev", "relatime", "ro"},
|
||||
}}
|
||||
specMounts, err := setupSpecialMountSpecChanges(spec, b.CommonBuildOpts.ShmSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get the list of files we need to bind into the container.
|
||||
@@ -568,7 +507,7 @@ func (b *Builder) setupMounts(context *imagetypes.SystemContext, mountPoint stri
|
||||
// everything other than these might have users content
|
||||
mountArtifacts.RunMountTargets = append(append(append(mountArtifacts.RunMountTargets, cleanableDestinationListFromMounts(bindFileMounts)...), cleanableDestinationListFromMounts(subscriptionMounts)...), cleanableDestinationListFromMounts(specMounts)...)
|
||||
|
||||
allMounts := util.SortMounts(append(append(append(append(append(append(volumes, builtins...), runMounts...), subscriptionMounts...), bindFileMounts...), specMounts...), sysfsMount...))
|
||||
allMounts := util.SortMounts(append(append(append(append(append(volumes, builtins...), runMounts...), subscriptionMounts...), bindFileMounts...), specMounts...))
|
||||
// Add them all, in the preferred order, except where they conflict with something that was previously added.
|
||||
for _, mount := range allMounts {
|
||||
if haveMount(mount.Destination) {
|
||||
@@ -705,46 +644,58 @@ func (b *Builder) addResolvConf(rdir string, chownOpts *idtools.IDPair, dnsServe
|
||||
}
|
||||
|
||||
// generateHosts creates a containers hosts file
|
||||
func (b *Builder) generateHosts(rdir, hostname string, addHosts []string, chownOpts *idtools.IDPair) (string, error) {
|
||||
hostPath := "/etc/hosts"
|
||||
stat, err := os.Stat(hostPath)
|
||||
func (b *Builder) generateHosts(rdir string, chownOpts *idtools.IDPair, imageRoot string) (string, error) {
|
||||
conf, err := config.Default()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
hosts := bytes.NewBufferString("# Generated by Buildah\n")
|
||||
orig, err := ioutil.ReadFile(hostPath)
|
||||
path, err := etchosts.GetBaseHostFile(conf.Containers.BaseHostsFile, imageRoot)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
hosts.Write(orig)
|
||||
for _, host := range addHosts {
|
||||
// verify the host format
|
||||
values := strings.SplitN(host, ":", 2)
|
||||
if len(values) != 2 {
|
||||
return "", errors.Errorf("unable to parse host entry %q: incorrect format", host)
|
||||
}
|
||||
if values[0] == "" {
|
||||
return "", errors.Errorf("hostname in host entry %q is empty", host)
|
||||
}
|
||||
if values[1] == "" {
|
||||
return "", errors.Errorf("IP address in host entry %q is empty", host)
|
||||
}
|
||||
hosts.Write([]byte(fmt.Sprintf("%s\t%s\n", values[1], values[0])))
|
||||
}
|
||||
hosts.Write([]byte(fmt.Sprintf("127.0.0.1 %s %s\n", b.Container, hostname)))
|
||||
hosts.Write([]byte(fmt.Sprintf("::1 %s %s\n", b.Container, hostname)))
|
||||
|
||||
if ip := util.LocalIP(); ip != "" {
|
||||
hosts.Write([]byte(fmt.Sprintf("%s %s\n", ip, "host.containers.internal")))
|
||||
targetfile := filepath.Join(rdir, "hosts")
|
||||
if err := etchosts.New(&etchosts.Params{
|
||||
BaseFile: path,
|
||||
ExtraHosts: b.CommonBuildOpts.AddHost,
|
||||
HostContainersInternalIP: etchosts.GetHostContainersInternalIP(conf, nil, nil),
|
||||
TargetFile: targetfile,
|
||||
}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
cfile := filepath.Join(rdir, filepath.Base(hostPath))
|
||||
if err = ioutils.AtomicWriteFile(cfile, hosts.Bytes(), stat.Mode().Perm()); err != nil {
|
||||
return "", errors.Wrapf(err, "error writing /etc/hosts into the container")
|
||||
uid := 0
|
||||
gid := 0
|
||||
if chownOpts != nil {
|
||||
uid = chownOpts.UID
|
||||
gid = chownOpts.GID
|
||||
}
|
||||
uid := int(stat.Sys().(*syscall.Stat_t).Uid)
|
||||
gid := int(stat.Sys().(*syscall.Stat_t).Gid)
|
||||
if err = os.Chown(targetfile, uid, gid); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := label.Relabel(targetfile, b.MountLabel, false); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return targetfile, nil
|
||||
}
|
||||
|
||||
// generateHostname creates a containers /etc/hostname file
|
||||
func (b *Builder) generateHostname(rdir, hostname string, chownOpts *idtools.IDPair) (string, error) {
|
||||
var err error
|
||||
hostnamePath := "/etc/hostname"
|
||||
|
||||
var hostnameBuffer bytes.Buffer
|
||||
hostnameBuffer.Write([]byte(fmt.Sprintf("%s\n", hostname)))
|
||||
|
||||
cfile := filepath.Join(rdir, filepath.Base(hostnamePath))
|
||||
if err = ioutils.AtomicWriteFile(cfile, hostnameBuffer.Bytes(), 0644); err != nil {
|
||||
return "", errors.Wrapf(err, "error writing /etc/hostname into the container")
|
||||
}
|
||||
|
||||
uid := 0
|
||||
gid := 0
|
||||
if chownOpts != nil {
|
||||
uid = chownOpts.UID
|
||||
gid = chownOpts.GID
|
||||
@@ -1179,11 +1130,10 @@ func setupRootlessNetwork(pid int) (teardown func(), err error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *Builder) runConfigureNetwork(pid int, isolation define.Isolation, options RunOptions, configureNetworks []string, containerName string) (teardown func(), err error) {
|
||||
func (b *Builder) runConfigureNetwork(pid int, isolation define.Isolation, options RunOptions, configureNetworks []string, containerName string) (teardown func(), netStatus map[string]nettypes.StatusBlock, err error) {
|
||||
if isolation == IsolationOCIRootless {
|
||||
if ns := options.NamespaceOptions.Find(string(specs.NetworkNamespace)); ns != nil && !ns.Host && ns.Path == "" {
|
||||
return setupRootlessNetwork(pid)
|
||||
}
|
||||
teardown, err = setupRootlessNetwork(pid)
|
||||
return teardown, nil, err
|
||||
}
|
||||
|
||||
if len(configureNetworks) == 0 {
|
||||
@@ -1198,7 +1148,7 @@ func (b *Builder) runConfigureNetwork(pid int, isolation define.Isolation, optio
|
||||
netns := fmt.Sprintf("/proc/%d/ns/net", pid)
|
||||
netFD, err := unix.Open(netns, unix.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error opening network namespace")
|
||||
return nil, nil, errors.Wrapf(err, "error opening network namespace")
|
||||
}
|
||||
mynetns := fmt.Sprintf("/proc/%d/fd/%d", unix.Getpid(), netFD)
|
||||
|
||||
@@ -1214,9 +1164,9 @@ func (b *Builder) runConfigureNetwork(pid int, isolation define.Isolation, optio
|
||||
ContainerName: containerName,
|
||||
Networks: networks,
|
||||
}
|
||||
_, err = b.NetworkInterface.Setup(mynetns, nettypes.SetupOptions{NetworkOptions: opts})
|
||||
netStatus, err = b.NetworkInterface.Setup(mynetns, nettypes.SetupOptions{NetworkOptions: opts})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
teardown = func() {
|
||||
@@ -1226,7 +1176,7 @@ func (b *Builder) runConfigureNetwork(pid int, isolation define.Isolation, optio
|
||||
}
|
||||
}
|
||||
|
||||
return teardown, nil
|
||||
return teardown, netStatus, nil
|
||||
}
|
||||
|
||||
func setNonblock(logger *logrus.Logger, fd int, description string, nonblocking bool) (bool, error) { //nolint:interfacer
|
||||
@@ -2146,100 +2096,146 @@ func (b *Builder) configureEnvironment(g *generate.Generator, options RunOptions
|
||||
}
|
||||
}
|
||||
|
||||
func setupRootlessSpecChanges(spec *specs.Spec, bundleDir string, shmSize string) error {
|
||||
emptyDir := filepath.Join(bundleDir, "empty")
|
||||
if err := os.Mkdir(emptyDir, 0); err != nil {
|
||||
return err
|
||||
func addOrReplaceMount(moutns []specs.Mount, mount specs.Mount) []spec.Mount {
|
||||
for i := range moutns {
|
||||
if moutns[i].Destination == mount.Destination {
|
||||
moutns[i] = mount
|
||||
return moutns
|
||||
}
|
||||
}
|
||||
return append(moutns, mount)
|
||||
}
|
||||
|
||||
// If the container has a network namespace, we can create a fresh /sys mount
|
||||
for _, ns := range spec.Linux.Namespaces {
|
||||
if ns.Type == specs.NetworkNamespace {
|
||||
return nil
|
||||
// setupSpecialMountSpecChanges creates special mounts for depending on the namespaces
|
||||
// logic taken from podman and adapted for buildah
|
||||
// https://github.com/containers/podman/blob/4ba71f955a944790edda6e007e6d074009d437a7/pkg/specgen/generate/oci.go#L178
|
||||
func setupSpecialMountSpecChanges(spec *spec.Spec, shmSize string) ([]specs.Mount, error) {
|
||||
mounts := spec.Mounts
|
||||
isRootless := unshare.IsRootless()
|
||||
isNewUserns := false
|
||||
isNetns := false
|
||||
isPidns := false
|
||||
isIpcns := false
|
||||
|
||||
for _, namespace := range spec.Linux.Namespaces {
|
||||
switch namespace.Type {
|
||||
case specs.NetworkNamespace:
|
||||
isNetns = true
|
||||
case specs.UserNamespace:
|
||||
isNewUserns = true
|
||||
case specs.PIDNamespace:
|
||||
isPidns = true
|
||||
case specs.IPCNamespace:
|
||||
isIpcns = true
|
||||
}
|
||||
}
|
||||
|
||||
// Replace /sys with a read-only bind mount.
|
||||
mounts := []specs.Mount{
|
||||
{
|
||||
Source: "/dev",
|
||||
Destination: "/dev",
|
||||
Type: "tmpfs",
|
||||
Options: []string{"private", "strictatime", "noexec", "nosuid", "mode=755", "size=65536k"},
|
||||
},
|
||||
{
|
||||
Source: "mqueue",
|
||||
Destination: "/dev/mqueue",
|
||||
Type: "mqueue",
|
||||
Options: []string{"private", "nodev", "noexec", "nosuid"},
|
||||
},
|
||||
{
|
||||
Source: "pts",
|
||||
addCgroup := true
|
||||
// mount sys when root and no userns or when both netns and userns are private
|
||||
canMountSys := (!isRootless && !isNewUserns) || (isNetns && isNewUserns)
|
||||
if !canMountSys {
|
||||
addCgroup = false
|
||||
sys := "/sys"
|
||||
sysMnt := specs.Mount{
|
||||
Destination: sys,
|
||||
Type: "bind",
|
||||
Source: sys,
|
||||
Options: []string{bind.NoBindOption, "rprivate", "nosuid", "noexec", "nodev", "ro", "rbind"},
|
||||
}
|
||||
mounts = addOrReplaceMount(mounts, sysMnt)
|
||||
}
|
||||
|
||||
gid5Available := true
|
||||
if isRootless {
|
||||
_, gids, err := unshare.GetHostIDMappings("")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gid5Available = checkIdsGreaterThan5(gids)
|
||||
}
|
||||
if gid5Available && len(spec.Linux.GIDMappings) > 0 {
|
||||
gid5Available = checkIdsGreaterThan5(spec.Linux.GIDMappings)
|
||||
}
|
||||
if !gid5Available {
|
||||
// If we have no GID mappings, the gid=5 default option would fail, so drop it.
|
||||
devPts := specs.Mount{
|
||||
Destination: "/dev/pts",
|
||||
Type: "devpts",
|
||||
Options: []string{"private", "noexec", "nosuid", "newinstance", "ptmxmode=0666", "mode=0620"},
|
||||
},
|
||||
{
|
||||
Source: "devpts",
|
||||
Options: []string{"rprivate", "nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620"},
|
||||
}
|
||||
mounts = addOrReplaceMount(mounts, devPts)
|
||||
}
|
||||
|
||||
isUserns := isNewUserns || isRootless
|
||||
|
||||
if isUserns && !isIpcns {
|
||||
devMqueue := "/dev/mqueue"
|
||||
devMqueueMnt := specs.Mount{
|
||||
Destination: devMqueue,
|
||||
Type: "bind",
|
||||
Source: devMqueue,
|
||||
Options: []string{bind.NoBindOption, "bind", "nosuid", "noexec", "nodev"},
|
||||
}
|
||||
mounts = addOrReplaceMount(mounts, devMqueueMnt)
|
||||
}
|
||||
if isUserns && !isPidns {
|
||||
proc := "/proc"
|
||||
procMount := specs.Mount{
|
||||
Destination: proc,
|
||||
Type: "bind",
|
||||
Source: proc,
|
||||
Options: []string{bind.NoBindOption, "rbind", "nosuid", "noexec", "nodev"},
|
||||
}
|
||||
mounts = addOrReplaceMount(mounts, procMount)
|
||||
}
|
||||
|
||||
if addCgroup {
|
||||
cgroupMnt := specs.Mount{
|
||||
Destination: "/sys/fs/cgroup",
|
||||
Type: "cgroup",
|
||||
Source: "cgroup",
|
||||
Options: []string{"rprivate", "nosuid", "noexec", "nodev", "relatime", "rw"},
|
||||
}
|
||||
mounts = addOrReplaceMount(mounts, cgroupMnt)
|
||||
}
|
||||
|
||||
// if userns and host ipc bind mount shm
|
||||
if isUserns && !isIpcns {
|
||||
// bind mount /dev/shm when it exists
|
||||
if _, err := os.Stat("/dev/shm"); err == nil {
|
||||
shmMount := specs.Mount{
|
||||
Source: "/dev/shm",
|
||||
Type: "bind",
|
||||
Destination: "/dev/shm",
|
||||
Options: []string{bind.NoBindOption, "rbind", "nosuid", "noexec", "nodev"},
|
||||
}
|
||||
mounts = addOrReplaceMount(mounts, shmMount)
|
||||
}
|
||||
} else if shmSize != "" {
|
||||
shmMount := specs.Mount{
|
||||
Source: "shm",
|
||||
Destination: "/dev/shm",
|
||||
Type: "tmpfs",
|
||||
Options: []string{"private", "nodev", "noexec", "nosuid", "mode=1777", fmt.Sprintf("size=%s", shmSize)},
|
||||
},
|
||||
{
|
||||
Source: "/proc",
|
||||
Destination: "/proc",
|
||||
Type: "proc",
|
||||
Options: []string{"private", "nodev", "noexec", "nosuid"},
|
||||
},
|
||||
{
|
||||
Source: "/sys",
|
||||
Destination: "/sys",
|
||||
Type: "bind",
|
||||
Options: []string{bind.NoBindOption, "rbind", "private", "nodev", "noexec", "nosuid", "ro"},
|
||||
},
|
||||
Options: []string{"private", "nodev", "noexec", "nosuid", "mode=1777", "size=" + shmSize},
|
||||
}
|
||||
mounts = addOrReplaceMount(mounts, shmMount)
|
||||
}
|
||||
|
||||
cgroup2, err := cgroups.IsCgroup2UnifiedMode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cgroup2 {
|
||||
hasCgroupNs := false
|
||||
for _, ns := range spec.Linux.Namespaces {
|
||||
if ns.Type == specs.CgroupNamespace {
|
||||
hasCgroupNs = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if hasCgroupNs {
|
||||
mounts = append(mounts, specs.Mount{
|
||||
Destination: "/sys/fs/cgroup",
|
||||
Type: "cgroup",
|
||||
Source: "cgroup",
|
||||
Options: []string{"private", "rw"},
|
||||
})
|
||||
}
|
||||
} else {
|
||||
spec.Linux.Resources = nil
|
||||
// Cover up /sys/fs/cgroup, if it exist in our source for /sys.
|
||||
if _, err := os.Stat("/sys/fs/cgroup"); err == nil {
|
||||
spec.Linux.MaskedPaths = append(spec.Linux.MaskedPaths, "/sys/fs/cgroup")
|
||||
}
|
||||
}
|
||||
// Keep anything that isn't under /dev, /proc, or /sys.
|
||||
for i := range spec.Mounts {
|
||||
if spec.Mounts[i].Destination == "/dev" || strings.HasPrefix(spec.Mounts[i].Destination, "/dev/") ||
|
||||
spec.Mounts[i].Destination == "/proc" || strings.HasPrefix(spec.Mounts[i].Destination, "/proc/") ||
|
||||
spec.Mounts[i].Destination == "/sys" || strings.HasPrefix(spec.Mounts[i].Destination, "/sys/") {
|
||||
continue
|
||||
}
|
||||
mounts = append(mounts, spec.Mounts[i])
|
||||
}
|
||||
spec.Mounts = mounts
|
||||
return nil
|
||||
return mounts, nil
|
||||
}
|
||||
|
||||
func (b *Builder) runUsingRuntimeSubproc(isolation define.Isolation, options RunOptions, configureNetwork bool, configureNetworks, moreCreateArgs []string, spec *specs.Spec, rootPath, bundlePath, containerName string) (err error) {
|
||||
func checkIdsGreaterThan5(ids []spec.LinuxIDMapping) bool {
|
||||
for _, r := range ids {
|
||||
if r.ContainerID <= 5 && 5 < r.ContainerID+r.Size {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *Builder) runUsingRuntimeSubproc(isolation define.Isolation, options RunOptions, configureNetwork bool, configureNetworks,
|
||||
moreCreateArgs []string, spec *specs.Spec, rootPath, bundlePath, containerName, buildContainerName, hostsFile string) (err error) {
|
||||
var confwg sync.WaitGroup
|
||||
config, conferr := json.Marshal(runUsingRuntimeSubprocOptions{
|
||||
Options: options,
|
||||
@@ -2340,7 +2336,7 @@ func (b *Builder) runUsingRuntimeSubproc(isolation define.Isolation, options Run
|
||||
return errors.Wrapf(err, "error parsing pid %s as a number", string(pidValue))
|
||||
}
|
||||
|
||||
teardown, err := b.runConfigureNetwork(pid, isolation, options, configureNetworks, containerName)
|
||||
teardown, netstatus, err := b.runConfigureNetwork(pid, isolation, options, configureNetworks, containerName)
|
||||
if teardown != nil {
|
||||
defer teardown()
|
||||
}
|
||||
@@ -2348,6 +2344,22 @@ func (b *Builder) runUsingRuntimeSubproc(isolation define.Isolation, options Run
|
||||
return err
|
||||
}
|
||||
|
||||
// only add hosts if we manage the hosts file
|
||||
if hostsFile != "" {
|
||||
var entries etchosts.HostEntries
|
||||
if netstatus != nil {
|
||||
entries = etchosts.GetNetworkHostEntries(netstatus, spec.Hostname, buildContainerName)
|
||||
} else {
|
||||
// we have slirp4netns, default to slirp4netns ip since this is not configurable in buildah
|
||||
entries = etchosts.HostEntries{{IP: "10.0.2.100", Names: []string{spec.Hostname, buildContainerName}}}
|
||||
}
|
||||
// make sure to sync this with (b *Builder) generateHosts()
|
||||
err = etchosts.Add(hostsFile, entries)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
logrus.Debug("network namespace successfully setup, send start message to child")
|
||||
_, err = containerStartW.file.Write([]byte{1})
|
||||
if err != nil {
|
||||
@@ -2400,33 +2412,14 @@ func waitForSync(pipeR *os.File) error {
|
||||
func checkAndOverrideIsolationOptions(isolation define.Isolation, options *RunOptions) error {
|
||||
switch isolation {
|
||||
case IsolationOCIRootless:
|
||||
if ns := options.NamespaceOptions.Find(string(specs.IPCNamespace)); ns == nil || ns.Host {
|
||||
logrus.Debugf("Forcing use of an IPC namespace.")
|
||||
}
|
||||
options.NamespaceOptions.AddOrReplace(define.NamespaceOption{Name: string(specs.IPCNamespace)})
|
||||
_, err := exec.LookPath("slirp4netns")
|
||||
hostNetworking := err != nil
|
||||
networkNamespacePath := ""
|
||||
if ns := options.NamespaceOptions.Find(string(specs.NetworkNamespace)); ns != nil {
|
||||
hostNetworking = ns.Host
|
||||
networkNamespacePath = ns.Path
|
||||
if hostNetworking {
|
||||
networkNamespacePath = ""
|
||||
// only change the netns if the caller did not set it
|
||||
if ns := options.NamespaceOptions.Find(string(specs.NetworkNamespace)); ns == nil {
|
||||
if _, err := exec.LookPath("slirp4netns"); err != nil {
|
||||
// if slirp4netns is not installed we have to use the hosts net namespace
|
||||
options.NamespaceOptions.AddOrReplace(define.NamespaceOption{Name: string(specs.NetworkNamespace), Host: true})
|
||||
}
|
||||
}
|
||||
options.NamespaceOptions.AddOrReplace(define.NamespaceOption{
|
||||
Name: string(specs.NetworkNamespace),
|
||||
Host: hostNetworking,
|
||||
Path: networkNamespacePath,
|
||||
})
|
||||
if ns := options.NamespaceOptions.Find(string(specs.PIDNamespace)); ns == nil || ns.Host {
|
||||
logrus.Debugf("Forcing use of a PID namespace.")
|
||||
}
|
||||
options.NamespaceOptions.AddOrReplace(define.NamespaceOption{Name: string(specs.PIDNamespace), Host: false})
|
||||
if ns := options.NamespaceOptions.Find(string(specs.UserNamespace)); ns == nil || ns.Host {
|
||||
logrus.Debugf("Forcing use of a user namespace.")
|
||||
}
|
||||
options.NamespaceOptions.AddOrReplace(define.NamespaceOption{Name: string(specs.UserNamespace)})
|
||||
fallthrough
|
||||
case IsolationOCI:
|
||||
pidns := options.NamespaceOptions.Find(string(specs.PIDNamespace))
|
||||
userns := options.NamespaceOptions.Find(string(specs.UserNamespace))
|
||||
@@ -2447,25 +2440,12 @@ func DefaultNamespaceOptions() (define.NamespaceOptions, error) {
|
||||
options := define.NamespaceOptions{
|
||||
{Name: string(specs.CgroupNamespace), Host: cfg.CgroupNS() == "host"},
|
||||
{Name: string(specs.IPCNamespace), Host: cfg.IPCNS() == "host"},
|
||||
{Name: string(specs.MountNamespace), Host: true},
|
||||
{Name: string(specs.NetworkNamespace), Host: cfg.NetNS() == "host" || cfg.NetNS() == "container"},
|
||||
{Name: string(specs.MountNamespace), Host: false},
|
||||
{Name: string(specs.NetworkNamespace), Host: cfg.NetNS() == "host"},
|
||||
{Name: string(specs.PIDNamespace), Host: cfg.PidNS() == "host"},
|
||||
{Name: string(specs.UserNamespace), Host: true},
|
||||
{Name: string(specs.UserNamespace), Host: cfg.Containers.UserNS == "host"},
|
||||
{Name: string(specs.UTSNamespace), Host: cfg.UTSNS() == "host"},
|
||||
}
|
||||
g, err := generate.New("linux")
|
||||
if err != nil {
|
||||
return options, errors.Wrapf(err, "error generating new 'linux' runtime spec")
|
||||
}
|
||||
spec := g.Config
|
||||
if spec.Linux != nil {
|
||||
for _, ns := range spec.Linux.Namespaces {
|
||||
options.AddOrReplace(define.NamespaceOption{
|
||||
Name: string(ns.Type),
|
||||
Path: ns.Path,
|
||||
})
|
||||
}
|
||||
}
|
||||
return options, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user