| 
									
										
										
										
											2022-02-14 17:05:46 +08:00
										 |  |  | //go:build linux
 | 
					
						
							| 
									
										
										
										
											2018-06-29 22:00:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | package buildah | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2022-06-22 18:48:00 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2022-07-06 17:14:06 +08:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2018-06-29 22:00:38 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2025-04-08 03:52:10 +08:00
										 |  |  | 	"maps" | 
					
						
							| 
									
										
										
										
											2018-06-29 22:00:38 +08:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	"path/filepath" | 
					
						
							| 
									
										
										
										
											2025-01-23 22:27:47 +08:00
										 |  |  | 	"slices" | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2024-09-12 02:21:25 +08:00
										 |  |  | 	"sync" | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	"syscall" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/containers/buildah/bind" | 
					
						
							|  |  |  | 	"github.com/containers/buildah/chroot" | 
					
						
							| 
									
										
										
										
											2020-10-31 17:58:59 +08:00
										 |  |  | 	"github.com/containers/buildah/copier" | 
					
						
							| 
									
										
										
										
											2021-02-07 06:49:40 +08:00
										 |  |  | 	"github.com/containers/buildah/define" | 
					
						
							| 
									
										
										
										
											2021-10-18 13:51:51 +08:00
										 |  |  | 	"github.com/containers/buildah/internal" | 
					
						
							| 
									
										
										
										
											2023-10-11 14:44:20 +08:00
										 |  |  | 	"github.com/containers/buildah/internal/tmpdir" | 
					
						
							| 
									
										
										
										
											2023-09-12 20:23:29 +08:00
										 |  |  | 	"github.com/containers/buildah/internal/volumes" | 
					
						
							| 
									
										
										
										
											2024-09-12 02:21:25 +08:00
										 |  |  | 	"github.com/containers/buildah/pkg/binfmt" | 
					
						
							| 
									
										
										
										
											2019-04-29 21:41:18 +08:00
										 |  |  | 	"github.com/containers/buildah/pkg/overlay" | 
					
						
							| 
									
										
										
										
											2021-09-28 19:20:36 +08:00
										 |  |  | 	"github.com/containers/buildah/pkg/parse" | 
					
						
							| 
									
										
										
										
											2023-08-26 03:00:19 +08:00
										 |  |  | 	butil "github.com/containers/buildah/pkg/util" | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	"github.com/containers/buildah/util" | 
					
						
							|  |  |  | 	"github.com/docker/go-units" | 
					
						
							|  |  |  | 	"github.com/opencontainers/runtime-spec/specs-go" | 
					
						
							|  |  |  | 	"github.com/opencontainers/runtime-tools/generate" | 
					
						
							|  |  |  | 	"github.com/sirupsen/logrus" | 
					
						
							| 
									
										
										
										
											2025-08-29 20:55:12 +08:00
										 |  |  | 	"go.podman.io/common/libnetwork/etchosts" | 
					
						
							|  |  |  | 	"go.podman.io/common/libnetwork/pasta" | 
					
						
							|  |  |  | 	"go.podman.io/common/libnetwork/resolvconf" | 
					
						
							|  |  |  | 	"go.podman.io/common/libnetwork/slirp4netns" | 
					
						
							|  |  |  | 	nettypes "go.podman.io/common/libnetwork/types" | 
					
						
							|  |  |  | 	netUtil "go.podman.io/common/libnetwork/util" | 
					
						
							|  |  |  | 	"go.podman.io/common/pkg/capabilities" | 
					
						
							|  |  |  | 	"go.podman.io/common/pkg/chown" | 
					
						
							|  |  |  | 	"go.podman.io/common/pkg/config" | 
					
						
							|  |  |  | 	"go.podman.io/common/pkg/hooks" | 
					
						
							|  |  |  | 	hooksExec "go.podman.io/common/pkg/hooks/exec" | 
					
						
							|  |  |  | 	"go.podman.io/image/v5/types" | 
					
						
							|  |  |  | 	"go.podman.io/storage/pkg/fileutils" | 
					
						
							|  |  |  | 	"go.podman.io/storage/pkg/idtools" | 
					
						
							|  |  |  | 	"go.podman.io/storage/pkg/ioutils" | 
					
						
							|  |  |  | 	"go.podman.io/storage/pkg/lockfile" | 
					
						
							|  |  |  | 	"go.podman.io/storage/pkg/mount" | 
					
						
							|  |  |  | 	"go.podman.io/storage/pkg/stringid" | 
					
						
							|  |  |  | 	"go.podman.io/storage/pkg/unshare" | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	"golang.org/x/sys/unix" | 
					
						
							| 
									
										
										
										
											2024-03-26 09:13:35 +08:00
										 |  |  | 	"tags.cncf.io/container-device-interface/pkg/cdi" | 
					
						
							| 
									
										
										
										
											2024-04-12 22:31:51 +08:00
										 |  |  | 	"tags.cncf.io/container-device-interface/pkg/parser" | 
					
						
							| 
									
										
										
										
											2018-06-29 22:00:38 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-18 03:55:11 +08:00
										 |  |  | // binfmtRegistered makes sure we only try to register binfmt_misc
 | 
					
						
							|  |  |  | // interpreters once, the first time we handle a RUN instruction.
 | 
					
						
							|  |  |  | var binfmtRegistered sync.Once | 
					
						
							| 
									
										
										
										
											2022-06-18 20:04:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-29 22:00:38 +08:00
										 |  |  | func setChildProcess() error { | 
					
						
							|  |  |  | 	if err := unix.Prctl(unix.PR_SET_CHILD_SUBREAPER, uintptr(1), 0, 0, 0); err != nil { | 
					
						
							|  |  |  | 		fmt.Fprintf(os.Stderr, "prctl(PR_SET_CHILD_SUBREAPER, 1): %v\n", err) | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-26 09:13:35 +08:00
										 |  |  | func (b *Builder) cdiSetupDevicesInSpec(deviceSpecs []string, configDir string, spec *specs.Spec) ([]string, error) { | 
					
						
							| 
									
										
										
										
											2024-04-12 22:31:51 +08:00
										 |  |  | 	var configDirs []string | 
					
						
							|  |  |  | 	defConfig, err := config.Default() | 
					
						
							| 
									
										
										
										
											2024-04-11 16:37:50 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2024-04-12 22:31:51 +08:00
										 |  |  | 		return nil, fmt.Errorf("failed to get container config: %w", err) | 
					
						
							| 
									
										
										
										
											2024-04-11 16:37:50 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-04-12 22:31:51 +08:00
										 |  |  | 	// The CDI cache prioritizes entries from directories that are later in
 | 
					
						
							|  |  |  | 	// the list of ones it scans, so start with our general config, then
 | 
					
						
							|  |  |  | 	// append values passed to us through API layers.
 | 
					
						
							|  |  |  | 	configDirs = slices.Clone(defConfig.Engine.CdiSpecDirs.Get()) | 
					
						
							| 
									
										
										
										
											2024-03-26 09:13:35 +08:00
										 |  |  | 	if b.CDIConfigDir != "" { | 
					
						
							|  |  |  | 		configDirs = append(configDirs, b.CDIConfigDir) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if configDir != "" { | 
					
						
							|  |  |  | 		configDirs = append(configDirs, configDir) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-04-12 22:31:51 +08:00
										 |  |  | 	if len(configDirs) == 0 { | 
					
						
							|  |  |  | 		// No directories to scan for CDI configuration means that CDI
 | 
					
						
							|  |  |  | 		// won't have any details for setting up any devices, so we
 | 
					
						
							|  |  |  | 		// don't need to be doing anything here.
 | 
					
						
							|  |  |  | 		return deviceSpecs, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var qualifiedDeviceSpecs, unqualifiedDeviceSpecs []string | 
					
						
							|  |  |  | 	for _, deviceSpec := range deviceSpecs { | 
					
						
							|  |  |  | 		if parser.IsQualifiedName(deviceSpec) { | 
					
						
							|  |  |  | 			qualifiedDeviceSpecs = append(qualifiedDeviceSpecs, deviceSpec) | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			unqualifiedDeviceSpecs = append(unqualifiedDeviceSpecs, deviceSpec) | 
					
						
							| 
									
										
										
										
											2024-03-26 09:13:35 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-04-12 22:31:51 +08:00
										 |  |  | 	if len(qualifiedDeviceSpecs) == 0 { | 
					
						
							|  |  |  | 		// None of the specified devices were in the form that would be
 | 
					
						
							|  |  |  | 		// handled by CDI, so we don't need to do anything here.
 | 
					
						
							|  |  |  | 		return deviceSpecs, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := cdi.Configure(cdi.WithSpecDirs(configDirs...)); err != nil { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("CDI default registry ignored configured directories %v: %w", configDirs, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	leftoverDevices := slices.Clone(deviceSpecs) | 
					
						
							|  |  |  | 	if err := cdi.Refresh(); err != nil { | 
					
						
							|  |  |  | 		logrus.Warnf("CDI default registry refresh: %v", err) | 
					
						
							| 
									
										
										
										
											2024-03-26 09:13:35 +08:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2024-04-12 22:31:51 +08:00
										 |  |  | 		leftoverDevices, err = cdi.InjectDevices(spec, qualifiedDeviceSpecs...) | 
					
						
							| 
									
										
										
										
											2024-03-26 09:13:35 +08:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2024-04-12 22:31:51 +08:00
										 |  |  | 			return nil, fmt.Errorf("CDI device injection (leftover devices: %v): %w", leftoverDevices, err) | 
					
						
							| 
									
										
										
										
											2024-03-26 09:13:35 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	removed := slices.DeleteFunc(slices.Clone(deviceSpecs), func(t string) bool { return slices.Contains(leftoverDevices, t) }) | 
					
						
							| 
									
										
										
										
											2024-04-12 22:31:51 +08:00
										 |  |  | 	logrus.Debugf("CDI taking care of devices %v, leaving devices %v, skipped %v", removed, leftoverDevices, unqualifiedDeviceSpecs) | 
					
						
							|  |  |  | 	return append(leftoverDevices, unqualifiedDeviceSpecs...), nil | 
					
						
							| 
									
										
										
										
											2024-03-26 09:13:35 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Extract the device list so that we can still try to make it work if
 | 
					
						
							|  |  |  | // we're running rootless and can't just mknod() the device nodes.
 | 
					
						
							|  |  |  | func separateDevicesFromRuntimeSpec(g *generate.Generator) define.ContainerDevices { | 
					
						
							|  |  |  | 	var result define.ContainerDevices | 
					
						
							|  |  |  | 	if g.Config != nil && g.Config.Linux != nil { | 
					
						
							|  |  |  | 		for _, device := range g.Config.Linux.Devices { | 
					
						
							|  |  |  | 			var bDevice define.BuildahDevice | 
					
						
							|  |  |  | 			bDevice.Path = device.Path | 
					
						
							|  |  |  | 			switch device.Type { | 
					
						
							|  |  |  | 			case "b": | 
					
						
							|  |  |  | 				bDevice.Type = 'b' | 
					
						
							|  |  |  | 			case "c": | 
					
						
							|  |  |  | 				bDevice.Type = 'c' | 
					
						
							|  |  |  | 			case "u": | 
					
						
							|  |  |  | 				bDevice.Type = 'u' | 
					
						
							|  |  |  | 			case "p": | 
					
						
							|  |  |  | 				bDevice.Type = 'p' | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			bDevice.Major = device.Major | 
					
						
							|  |  |  | 			bDevice.Minor = device.Minor | 
					
						
							|  |  |  | 			if device.FileMode != nil { | 
					
						
							|  |  |  | 				bDevice.FileMode = *device.FileMode | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if device.UID != nil { | 
					
						
							|  |  |  | 				bDevice.Uid = *device.UID | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if device.GID != nil { | 
					
						
							|  |  |  | 				bDevice.Gid = *device.GID | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			bDevice.Source = device.Path | 
					
						
							|  |  |  | 			bDevice.Destination = device.Path | 
					
						
							|  |  |  | 			result = append(result, bDevice) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	g.ClearLinuxDevices() | 
					
						
							|  |  |  | 	return result | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | // Run runs the specified command in the container's root filesystem.
 | 
					
						
							|  |  |  | func (b *Builder) Run(command []string, options RunOptions) error { | 
					
						
							| 
									
										
										
										
											2025-01-09 00:04:42 +08:00
										 |  |  | 	var runArtifacts *runMountArtifacts | 
					
						
							|  |  |  | 	if len(options.ExternalImageMounts) > 0 { | 
					
						
							|  |  |  | 		defer func() { | 
					
						
							|  |  |  | 			if runArtifacts == nil { | 
					
						
							|  |  |  | 				// we didn't add ExternalImageMounts to the
 | 
					
						
							|  |  |  | 				// list of images that we're going to unmount
 | 
					
						
							|  |  |  | 				// yet and make a deferred call that cleans
 | 
					
						
							|  |  |  | 				// them up, but the caller is expecting us to
 | 
					
						
							|  |  |  | 				// unmount these for them because we offered to
 | 
					
						
							|  |  |  | 				for _, image := range options.ExternalImageMounts { | 
					
						
							|  |  |  | 					if _, err := b.store.UnmountImage(image, false); err != nil { | 
					
						
							|  |  |  | 						logrus.Debugf("umounting image %q: %v", image, err) | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-12 02:21:25 +08:00
										 |  |  | 	if os.Getenv("container") != "" { | 
					
						
							|  |  |  | 		os, arch, variant, err := parse.Platform("") | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return fmt.Errorf("reading the current default platform") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		platform := b.OCIv1.Platform | 
					
						
							|  |  |  | 		if os != platform.OS || arch != platform.Architecture || variant != platform.Variant { | 
					
						
							|  |  |  | 			binfmtRegistered.Do(func() { | 
					
						
							|  |  |  | 				if err := binfmt.Register(nil); err != nil { | 
					
						
							|  |  |  | 					logrus.Warnf("registering binfmt_misc interpreters: %v", err) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-11 14:44:20 +08:00
										 |  |  | 	p, err := os.MkdirTemp(tmpdir.GetTempDir(), define.Package) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2020-10-15 17:16:50 +08:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// On some hosts like AH, /tmp is a symlink and we need an
 | 
					
						
							|  |  |  | 	// absolute path.
 | 
					
						
							|  |  |  | 	path, err := filepath.EvalSymlinks(p) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2020-10-15 17:16:50 +08:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	logrus.Debugf("using %q to hold bundle data", path) | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		if err2 := os.RemoveAll(path); err2 != nil { | 
					
						
							| 
									
										
										
										
											2021-05-08 01:38:44 +08:00
										 |  |  | 			options.Logger.Error(err2) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	gp, err := generate.New("linux") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 		return fmt.Errorf("generating new 'linux' runtime spec: %w", err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	g := &gp | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	isolation := options.Isolation | 
					
						
							| 
									
										
										
										
											2021-02-07 06:49:40 +08:00
										 |  |  | 	if isolation == define.IsolationDefault { | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		isolation = b.Isolation | 
					
						
							| 
									
										
										
										
											2021-02-07 06:49:40 +08:00
										 |  |  | 		if isolation == define.IsolationDefault { | 
					
						
							| 
									
										
										
										
											2023-02-21 03:30:28 +08:00
										 |  |  | 			isolation, err = parse.IsolationOption("") | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				logrus.Debugf("got %v while trying to determine default isolation, guessing OCI", err) | 
					
						
							|  |  |  | 				isolation = IsolationOCI | 
					
						
							|  |  |  | 			} else if isolation == IsolationDefault { | 
					
						
							|  |  |  | 				isolation = IsolationOCI | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := checkAndOverrideIsolationOptions(isolation, &options); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-27 23:33:35 +08:00
										 |  |  | 	// hardwire the environment to match docker build to avoid subtle and hard-to-debug differences due to containers.conf
 | 
					
						
							|  |  |  | 	b.configureEnvironment(g, options, []string{"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if b.CommonBuildOpts == nil { | 
					
						
							| 
									
										
										
										
											2022-07-06 17:14:06 +08:00
										 |  |  | 		return fmt.Errorf("invalid format on container you must recreate the container") | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := addCommonOptsToSpec(b.CommonBuildOpts, g); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-07 20:06:12 +08:00
										 |  |  | 	workDir := b.WorkDir() | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	if options.WorkingDir != "" { | 
					
						
							|  |  |  | 		g.SetProcessCwd(options.WorkingDir) | 
					
						
							| 
									
										
										
										
											2022-12-07 20:06:12 +08:00
										 |  |  | 		workDir = options.WorkingDir | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} else if b.WorkDir() != "" { | 
					
						
							|  |  |  | 		g.SetProcessCwd(b.WorkDir()) | 
					
						
							| 
									
										
										
										
											2024-10-25 03:35:45 +08:00
										 |  |  | 		workDir = b.WorkDir() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if workDir == "" { | 
					
						
							|  |  |  | 		workDir = string(os.PathSeparator) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	setupSelinux(g, b.ProcessLabel, b.MountLabel) | 
					
						
							|  |  |  | 	mountPoint, err := b.Mount(b.MountLabel) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 		return fmt.Errorf("mounting container %q: %w", b.ContainerID, err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		if err := b.Unmount(); err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-08 01:38:44 +08:00
										 |  |  | 			options.Logger.Errorf("error unmounting container: %v", err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	g.SetRootPath(mountPoint) | 
					
						
							|  |  |  | 	if len(command) > 0 { | 
					
						
							|  |  |  | 		command = runLookupPath(g, command) | 
					
						
							|  |  |  | 		g.SetProcessArgs(command) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		g.SetProcessArgs(nil) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-26 09:13:35 +08:00
										 |  |  | 	// Combine the working container's set of devices with the ones for just this run.
 | 
					
						
							| 
									
										
										
										
											2025-04-08 03:42:52 +08:00
										 |  |  | 	deviceSpecs := slices.Concat(options.DeviceSpecs, b.DeviceSpecs) | 
					
						
							| 
									
										
										
										
											2024-03-26 09:13:35 +08:00
										 |  |  | 	deviceSpecs, err = b.cdiSetupDevicesInSpec(deviceSpecs, options.CDIConfigDir, g.Config) // makes changes to more than just the device list
 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	devices := separateDevicesFromRuntimeSpec(g) | 
					
						
							|  |  |  | 	for _, deviceSpec := range deviceSpecs { | 
					
						
							|  |  |  | 		device, err := parse.DeviceFromPath(deviceSpec) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return fmt.Errorf("setting up device %q: %w", deviceSpec, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		devices = append(devices, device...) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	devices = append(append(devices, options.Devices...), b.Devices...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Mount devices, if any, and if we're rootless attempt to work around not
 | 
					
						
							|  |  |  | 	// being able to create device nodes by bind-mounting them from the host, like podman does.
 | 
					
						
							| 
									
										
										
										
											2022-05-24 18:23:32 +08:00
										 |  |  | 	if unshare.IsRootless() { | 
					
						
							|  |  |  | 		// We are going to create bind mounts for devices
 | 
					
						
							|  |  |  | 		// but we need to make sure that we don't override
 | 
					
						
							|  |  |  | 		// anything which is already in OCI spec.
 | 
					
						
							| 
									
										
										
										
											2025-04-08 02:59:01 +08:00
										 |  |  | 		mounts := make(map[string]any) | 
					
						
							| 
									
										
										
										
											2022-05-24 18:23:32 +08:00
										 |  |  | 		for _, m := range g.Mounts() { | 
					
						
							|  |  |  | 			mounts[m.Destination] = true | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-06-26 16:40:39 +08:00
										 |  |  | 		newMounts := []specs.Mount{} | 
					
						
							| 
									
										
										
										
											2024-03-26 09:13:35 +08:00
										 |  |  | 		for _, d := range devices { | 
					
						
							| 
									
										
										
										
											2022-05-24 18:23:32 +08:00
										 |  |  | 			// Default permission is read-only.
 | 
					
						
							|  |  |  | 			perm := "ro" | 
					
						
							|  |  |  | 			// Get permission configured for this device but only process `write`
 | 
					
						
							|  |  |  | 			// permission in rootless since `mknod` is not supported anyways.
 | 
					
						
							|  |  |  | 			if strings.Contains(string(d.Rule.Permissions), "w") { | 
					
						
							|  |  |  | 				perm = "rw" | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2023-06-26 16:40:39 +08:00
										 |  |  | 			devMnt := specs.Mount{ | 
					
						
							| 
									
										
										
										
											2022-05-24 18:23:32 +08:00
										 |  |  | 				Destination: d.Destination, | 
					
						
							|  |  |  | 				Type:        parse.TypeBind, | 
					
						
							|  |  |  | 				Source:      d.Source, | 
					
						
							|  |  |  | 				Options:     []string{"slave", "nosuid", "noexec", perm, "rbind"}, | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			// Podman parity: podman skips these two devices hence we do the same.
 | 
					
						
							|  |  |  | 			if d.Path == "/dev/ptmx" || strings.HasPrefix(d.Path, "/dev/tty") { | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			// Device is already in OCI spec do not re-mount.
 | 
					
						
							|  |  |  | 			if _, found := mounts[d.Path]; found { | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			newMounts = append(newMounts, devMnt) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		g.Config.Mounts = append(newMounts, g.Config.Mounts...) | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2024-03-26 09:13:35 +08:00
										 |  |  | 		for _, d := range devices { | 
					
						
							| 
									
										
										
										
											2023-06-26 16:40:39 +08:00
										 |  |  | 			sDev := specs.LinuxDevice{ | 
					
						
							| 
									
										
										
										
											2022-05-24 18:23:32 +08:00
										 |  |  | 				Type:     string(d.Type), | 
					
						
							|  |  |  | 				Path:     d.Path, | 
					
						
							|  |  |  | 				Major:    d.Major, | 
					
						
							|  |  |  | 				Minor:    d.Minor, | 
					
						
							|  |  |  | 				FileMode: &d.FileMode, | 
					
						
							|  |  |  | 				UID:      &d.Uid, | 
					
						
							|  |  |  | 				GID:      &d.Gid, | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			g.AddDevice(sDev) | 
					
						
							|  |  |  | 			g.AddLinuxResourcesDevice(true, string(d.Type), &d.Major, &d.Minor, string(d.Permissions)) | 
					
						
							| 
									
										
										
										
											2019-09-07 03:07:18 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-18 23:47:40 +08:00
										 |  |  | 	setupMaskedPaths(g, b.CommonBuildOpts) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	setupReadOnlyPaths(g) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	setupTerminal(g, options.Terminal, options.TerminalSize) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 	configureNetwork, networkString, err := b.configureNamespaces(g, &options) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-16 06:40:15 +08:00
										 |  |  | 	homeDir, err := b.configureUIDGID(g, mountPoint, options) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-04 19:04:16 +08:00
										 |  |  | 	g.SetProcessNoNewPrivileges(b.CommonBuildOpts.NoNewPrivileges) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	g.SetProcessApparmorProfile(b.CommonBuildOpts.ApparmorProfile) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Now grab the spec from the generator.  Set the generator to nil so that future contributors
 | 
					
						
							|  |  |  | 	// will quickly be able to tell that they're supposed to be modifying the spec directly from here.
 | 
					
						
							|  |  |  | 	spec := g.Config | 
					
						
							|  |  |  | 	g = nil | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Set the seccomp configuration using the specified profile name.  Some syscalls are
 | 
					
						
							|  |  |  | 	// allowed if certain capabilities are to be granted (example: CAP_SYS_CHROOT and chroot),
 | 
					
						
							|  |  |  | 	// so we sorted out the capabilities lists first.
 | 
					
						
							|  |  |  | 	if err = setupSeccomp(spec, b.CommonBuildOpts.SeccompProfilePath); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-23 18:37:57 +08:00
										 |  |  | 	uid, gid := spec.Process.User.UID, spec.Process.User.GID | 
					
						
							|  |  |  | 	if spec.Linux != nil { | 
					
						
							|  |  |  | 		uid, gid, err = util.GetHostIDs(spec.Linux.UIDMappings, spec.Linux.GIDMappings, uid, gid) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-03-23 18:37:57 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	idPair := &idtools.IDPair{UID: int(uid), GID: int(gid)} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 00:50:07 +08:00
										 |  |  | 	mode := os.FileMode(0o755) | 
					
						
							| 
									
										
										
										
											2020-10-31 17:58:59 +08:00
										 |  |  | 	coptions := copier.MkdirOptions{ | 
					
						
							| 
									
										
										
										
											2022-03-23 18:37:57 +08:00
										 |  |  | 		ChownNew: idPair, | 
					
						
							| 
									
										
										
										
											2020-10-31 17:58:59 +08:00
										 |  |  | 		ChmodNew: &mode, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-06 01:46:21 +08:00
										 |  |  | 	if err := copier.Mkdir(mountPoint, filepath.Join(mountPoint, spec.Process.Cwd), coptions); err != nil { | 
					
						
							| 
									
										
										
										
											2020-10-31 17:58:59 +08:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	bindFiles := make(map[string]string) | 
					
						
							|  |  |  | 	volumes := b.Volumes() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-23 18:37:57 +08:00
										 |  |  | 	// Figure out who owns files that will appear to be owned by UID/GID 0 in the container.
 | 
					
						
							|  |  |  | 	rootUID, rootGID, err := util.GetHostRootIDs(spec) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	rootIDPair := &idtools.IDPair{UID: int(rootUID), GID: int(rootGID)} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-15 22:53:39 +08:00
										 |  |  | 	hostsFile := "" | 
					
						
							| 
									
										
										
										
											2024-01-31 23:03:20 +08:00
										 |  |  | 	if !options.NoHosts && !slices.Contains(volumes, config.DefaultHostsFile) && options.ConfigureNetwork != define.NetworkDisabled { | 
					
						
							| 
									
										
										
										
											2024-03-16 01:04:08 +08:00
										 |  |  | 		hostsFile, err = b.createHostsFile(path, rootIDPair) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-03-15 22:53:39 +08:00
										 |  |  | 		bindFiles[config.DefaultHostsFile] = hostsFile | 
					
						
							| 
									
										
										
										
											2024-03-16 01:04:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Only add entries here if we do not have to do setup network,
 | 
					
						
							|  |  |  | 		// if we do we have to do it much later after the network setup.
 | 
					
						
							|  |  |  | 		if !configureNetwork { | 
					
						
							|  |  |  | 			var entries etchosts.HostEntries | 
					
						
							|  |  |  | 			isHost := true | 
					
						
							|  |  |  | 			if spec.Linux != nil { | 
					
						
							|  |  |  | 				for _, ns := range spec.Linux.Namespaces { | 
					
						
							|  |  |  | 					if ns.Type == specs.NetworkNamespace { | 
					
						
							|  |  |  | 						isHost = false | 
					
						
							|  |  |  | 						break | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			// add host entry for local ip when running in host network
 | 
					
						
							|  |  |  | 			if spec.Hostname != "" && isHost { | 
					
						
							|  |  |  | 				ip := netUtil.GetLocalIP() | 
					
						
							|  |  |  | 				if ip != "" { | 
					
						
							|  |  |  | 					entries = append(entries, etchosts.HostEntry{ | 
					
						
							|  |  |  | 						Names: []string{spec.Hostname}, | 
					
						
							|  |  |  | 						IP:    ip, | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2024-09-06 21:10:19 +08:00
										 |  |  | 			err = b.addHostsEntries(hostsFile, mountPoint, entries, nil, "") | 
					
						
							| 
									
										
										
										
											2024-03-16 01:04:08 +08:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-31 23:03:20 +08:00
										 |  |  | 	if !options.NoHostname && !(slices.Contains(volumes, "/etc/hostname")) { | 
					
						
							| 
									
										
										
										
											2024-03-15 22:53:39 +08:00
										 |  |  | 		hostnameFile, err := b.generateHostname(path, spec.Hostname, rootIDPair) | 
					
						
							| 
									
										
										
										
											2023-10-25 07:43:56 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							| 
									
										
										
										
											2022-04-21 15:35:56 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-10-25 07:43:56 +08:00
										 |  |  | 		// Bind /etc/hostname
 | 
					
						
							| 
									
										
										
										
											2024-03-15 22:53:39 +08:00
										 |  |  | 		bindFiles["/etc/hostname"] = hostnameFile | 
					
						
							| 
									
										
										
										
											2022-04-21 15:35:56 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-16 01:04:08 +08:00
										 |  |  | 	resolvFile := "" | 
					
						
							| 
									
										
										
										
											2025-04-01 09:00:31 +08:00
										 |  |  | 	if !slices.Contains(volumes, resolvconf.DefaultResolvConf) && options.ConfigureNetwork != define.NetworkDisabled && (len(b.CommonBuildOpts.DNSServers) != 1 || strings.ToLower(b.CommonBuildOpts.DNSServers[0]) != "none") { | 
					
						
							| 
									
										
										
										
											2024-03-16 01:04:08 +08:00
										 |  |  | 		resolvFile, err = b.createResolvConf(path, rootIDPair) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-05-12 21:42:05 +08:00
										 |  |  | 		bindFiles[resolvconf.DefaultResolvConf] = resolvFile | 
					
						
							| 
									
										
										
										
											2024-03-16 01:04:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Only add entries here if we do not have to do setup network,
 | 
					
						
							|  |  |  | 		// if we do we have to do it much later after the network setup.
 | 
					
						
							|  |  |  | 		if !configureNetwork { | 
					
						
							| 
									
										
										
										
											2024-06-09 17:17:25 +08:00
										 |  |  | 			err = b.addResolvConfEntries(resolvFile, nil, spec, false, true) | 
					
						
							| 
									
										
										
										
											2024-03-16 01:04:08 +08:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-09-06 04:54:40 +08:00
										 |  |  | 	// Empty file, so no need to recreate if it exists
 | 
					
						
							|  |  |  | 	if _, ok := bindFiles["/run/.containerenv"]; !ok { | 
					
						
							|  |  |  | 		containerenvPath := filepath.Join(path, "/run/.containerenv") | 
					
						
							| 
									
										
										
										
											2024-08-16 00:50:07 +08:00
										 |  |  | 		if err = os.MkdirAll(filepath.Dir(containerenvPath), 0o755); err != nil { | 
					
						
							| 
									
										
										
										
											2019-09-06 04:54:40 +08:00
										 |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-11-24 08:07:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		rootless := 0 | 
					
						
							|  |  |  | 		if unshare.IsRootless() { | 
					
						
							|  |  |  | 			rootless = 1 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// Populate the .containerenv with container information
 | 
					
						
							| 
									
										
										
										
											2022-04-05 05:27:24 +08:00
										 |  |  | 		containerenv := fmt.Sprintf(` | 
					
						
							| 
									
										
										
										
											2020-11-24 08:07:50 +08:00
										 |  |  | engine="buildah-%s" | 
					
						
							|  |  |  | name=%q | 
					
						
							|  |  |  | id=%q | 
					
						
							|  |  |  | image=%q | 
					
						
							|  |  |  | imageid=%q | 
					
						
							|  |  |  | rootless=%d | 
					
						
							| 
									
										
										
										
											2021-02-07 06:49:40 +08:00
										 |  |  | `, define.Version, b.Container, b.ContainerID, b.FromImage, b.FromImageID, rootless) | 
					
						
							| 
									
										
										
										
											2020-11-24 08:07:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 00:50:07 +08:00
										 |  |  | 		if err = ioutils.AtomicWriteFile(containerenvPath, []byte(containerenv), 0o755); err != nil { | 
					
						
							| 
									
										
										
										
											2019-09-06 04:54:40 +08:00
										 |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-11-29 09:00:39 +08:00
										 |  |  | 		if err := relabel(containerenvPath, b.MountLabel, false); err != nil { | 
					
						
							| 
									
										
										
										
											2020-10-15 17:16:50 +08:00
										 |  |  | 			return err | 
					
						
							| 
									
										
										
										
											2019-09-06 04:54:40 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		bindFiles["/run/.containerenv"] = containerenvPath | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-05-27 10:47:30 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-22 18:48:00 +08:00
										 |  |  | 	// Setup OCI hooks
 | 
					
						
							|  |  |  | 	_, err = b.setupOCIHooks(spec, (len(options.Mounts) > 0 || len(volumes) > 0)) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-07-06 17:14:06 +08:00
										 |  |  | 		return fmt.Errorf("unable to setup OCI hooks: %w", err) | 
					
						
							| 
									
										
										
										
											2022-06-22 18:48:00 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-27 10:47:30 +08:00
										 |  |  | 	runMountInfo := runMountInfo{ | 
					
						
							| 
									
										
										
										
											2022-12-07 20:06:12 +08:00
										 |  |  | 		WorkDir:          workDir, | 
					
						
							| 
									
										
										
										
											2022-05-27 10:47:30 +08:00
										 |  |  | 		ContextDir:       options.ContextDir, | 
					
						
							|  |  |  | 		Secrets:          options.Secrets, | 
					
						
							|  |  |  | 		SSHSources:       options.SSHSources, | 
					
						
							|  |  |  | 		StageMountPoints: options.StageMountPoints, | 
					
						
							|  |  |  | 		SystemContext:    options.SystemContext, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-09 00:04:42 +08:00
										 |  |  | 	runArtifacts, err = b.setupMounts(mountPoint, spec, path, options.Mounts, bindFiles, volumes, options.CompatBuiltinVolumes, b.CommonBuildOpts.Volumes, options.RunMounts, runMountInfo) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 		return fmt.Errorf("resolving mountpoints for container %q: %w", b.ContainerID, err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-07-26 14:07:23 +08:00
										 |  |  | 	if runArtifacts.SSHAuthSock != "" { | 
					
						
							|  |  |  | 		sshenv := "SSH_AUTH_SOCK=" + runArtifacts.SSHAuthSock | 
					
						
							|  |  |  | 		spec.Process.Env = append(spec.Process.Env, sshenv) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-04-17 06:21:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-18 03:55:11 +08:00
										 |  |  | 	// Create any mount points that we need that aren't already present in
 | 
					
						
							|  |  |  | 	// the rootfs.
 | 
					
						
							|  |  |  | 	createdMountTargets, err := b.createMountTargets(spec) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("ensuring mount targets for container %q: %w", b.ContainerID, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							|  |  |  | 		// Attempt to clean up mount targets for the sake of builds
 | 
					
						
							|  |  |  | 		// that don't commit and rebase at each step, and people using
 | 
					
						
							|  |  |  | 		// `buildah run` more than once, who don't expect empty mount
 | 
					
						
							| 
									
										
										
										
											2025-05-02 22:04:19 +08:00
										 |  |  | 		// points to stick around.  They'll still get filtered out at
 | 
					
						
							|  |  |  | 		// commit-time if another concurrent Run() is keeping something
 | 
					
						
							|  |  |  | 		// busy.
 | 
					
						
							| 
									
										
										
										
											2025-06-18 03:55:11 +08:00
										 |  |  | 		if _, err := copier.ConditionalRemove(mountPoint, mountPoint, copier.ConditionalRemoveOptions{ | 
					
						
							|  |  |  | 			UIDMap: b.store.UIDMap(), | 
					
						
							|  |  |  | 			GIDMap: b.store.GIDMap(), | 
					
						
							|  |  |  | 			Paths:  createdMountTargets, | 
					
						
							|  |  |  | 		}); err != nil { | 
					
						
							|  |  |  | 			options.Logger.Errorf("unable to cleanup run mount targets %v", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 13:51:51 +08:00
										 |  |  | 	// following run was called from `buildah run`
 | 
					
						
							|  |  |  | 	// and some images were mounted for this run
 | 
					
						
							|  |  |  | 	// add them to cleanup artifacts
 | 
					
						
							|  |  |  | 	if len(options.ExternalImageMounts) > 0 { | 
					
						
							|  |  |  | 		runArtifacts.MountedImages = append(runArtifacts.MountedImages, options.ExternalImageMounts...) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-17 06:21:31 +08:00
										 |  |  | 	defer func() { | 
					
						
							| 
									
										
										
										
											2025-06-18 03:55:11 +08:00
										 |  |  | 		if err := b.cleanupRunMounts(runArtifacts); err != nil { | 
					
						
							| 
									
										
										
										
											2021-10-18 13:51:51 +08:00
										 |  |  | 			options.Logger.Errorf("unable to cleanup run mounts %v", err) | 
					
						
							| 
									
										
										
										
											2021-04-17 06:21:31 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-17 01:37:44 +08:00
										 |  |  | 	// Handle mount flags that request that the source locations for "bind" mountpoints be
 | 
					
						
							|  |  |  | 	// relabeled, and filter those flags out of the list of mount options we pass to the
 | 
					
						
							|  |  |  | 	// runtime.
 | 
					
						
							|  |  |  | 	for i := range spec.Mounts { | 
					
						
							|  |  |  | 		switch spec.Mounts[i].Type { | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		case "bind", "rbind": | 
					
						
							|  |  |  | 			// all good, keep going
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		zflag := "" | 
					
						
							|  |  |  | 		for _, opt := range spec.Mounts[i].Options { | 
					
						
							|  |  |  | 			if opt == "z" || opt == "Z" { | 
					
						
							|  |  |  | 				zflag = opt | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if zflag == "" { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		spec.Mounts[i].Options = slices.DeleteFunc(spec.Mounts[i].Options, func(opt string) bool { | 
					
						
							|  |  |  | 			return opt == "z" || opt == "Z" | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 		if err := relabel(spec.Mounts[i].Source, b.MountLabel, zflag == "z"); err != nil { | 
					
						
							|  |  |  | 			return fmt.Errorf("setting file label %q on %q: %w", b.MountLabel, spec.Mounts[i].Source, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	switch isolation { | 
					
						
							| 
									
										
										
										
											2021-02-07 06:49:40 +08:00
										 |  |  | 	case define.IsolationOCI: | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		var moreCreateArgs []string | 
					
						
							|  |  |  | 		if options.NoPivot { | 
					
						
							| 
									
										
										
										
											2022-03-18 05:33:50 +08:00
										 |  |  | 			moreCreateArgs = append(moreCreateArgs, "--no-pivot") | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 		err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, networkString, moreCreateArgs, spec, | 
					
						
							| 
									
										
										
										
											2024-03-16 01:04:08 +08:00
										 |  |  | 			mountPoint, path, define.Package+"-"+filepath.Base(path), b.Container, hostsFile, resolvFile) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	case IsolationChroot: | 
					
						
							| 
									
										
										
										
											2024-12-11 03:58:58 +08:00
										 |  |  | 		err = chroot.RunUsingChroot(spec, path, homeDir, options.Stdin, options.Stdout, options.Stderr, options.NoPivot) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	case IsolationOCIRootless: | 
					
						
							|  |  |  | 		moreCreateArgs := []string{"--no-new-keyring"} | 
					
						
							|  |  |  | 		if options.NoPivot { | 
					
						
							|  |  |  | 			moreCreateArgs = append(moreCreateArgs, "--no-pivot") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 		err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, networkString, moreCreateArgs, spec, | 
					
						
							| 
									
										
										
										
											2024-03-16 01:04:08 +08:00
										 |  |  | 			mountPoint, path, define.Package+"-"+filepath.Base(path), b.Container, hostsFile, resolvFile) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	default: | 
					
						
							| 
									
										
										
										
											2022-07-06 17:14:06 +08:00
										 |  |  | 		err = errors.New("don't know how to run this command") | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-26 16:40:39 +08:00
										 |  |  | func (b *Builder) setupOCIHooks(config *specs.Spec, hasVolumes bool) (map[string][]specs.Hook, error) { | 
					
						
							|  |  |  | 	allHooks := make(map[string][]specs.Hook) | 
					
						
							| 
									
										
										
										
											2022-06-22 18:48:00 +08:00
										 |  |  | 	if len(b.CommonBuildOpts.OCIHooksDir) == 0 { | 
					
						
							|  |  |  | 		if unshare.IsRootless() { | 
					
						
							|  |  |  | 			return nil, nil | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		for _, hDir := range []string{hooks.DefaultDir, hooks.OverrideDir} { | 
					
						
							|  |  |  | 			manager, err := hooks.New(context.Background(), []string{hDir}, []string{}) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							| 
									
										
										
										
											2022-07-27 03:27:30 +08:00
										 |  |  | 				if errors.Is(err, os.ErrNotExist) { | 
					
						
							| 
									
										
										
										
											2022-06-22 18:48:00 +08:00
										 |  |  | 					continue | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				return nil, err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			ociHooks, err := manager.Hooks(config, b.ImageAnnotations, hasVolumes) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return nil, err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if len(ociHooks) > 0 || config.Hooks != nil { | 
					
						
							|  |  |  | 				logrus.Warnf("Implicit hook directories are deprecated; set --hooks-dir=%q explicitly to continue to load ociHooks from this directory", hDir) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2025-04-08 03:52:10 +08:00
										 |  |  | 			maps.Copy(allHooks, ociHooks) | 
					
						
							| 
									
										
										
										
											2022-06-22 18:48:00 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		manager, err := hooks.New(context.Background(), b.CommonBuildOpts.OCIHooksDir, []string{}) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		allHooks, err = manager.Hooks(config, b.ImageAnnotations, hasVolumes) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-27 16:26:02 +08:00
										 |  |  | 	hookErr, err := hooksExec.RuntimeConfigFilter(context.Background(), allHooks["precreate"], config, hooksExec.DefaultPostKillTimeout) //nolint:staticcheck
 | 
					
						
							| 
									
										
										
										
											2022-06-22 18:48:00 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		logrus.Warnf("Container: precreate hook: %v", err) | 
					
						
							|  |  |  | 		if hookErr != nil && hookErr != err { | 
					
						
							|  |  |  | 			logrus.Debugf("container: precreate hook (hook error): %v", hookErr) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return allHooks, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-07 06:49:40 +08:00
										 |  |  | func addCommonOptsToSpec(commonOpts *define.CommonBuildOptions, g *generate.Generator) error { | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	// Resources - CPU
 | 
					
						
							|  |  |  | 	if commonOpts.CPUPeriod != 0 { | 
					
						
							|  |  |  | 		g.SetLinuxResourcesCPUPeriod(commonOpts.CPUPeriod) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if commonOpts.CPUQuota != 0 { | 
					
						
							|  |  |  | 		g.SetLinuxResourcesCPUQuota(commonOpts.CPUQuota) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if commonOpts.CPUShares != 0 { | 
					
						
							|  |  |  | 		g.SetLinuxResourcesCPUShares(commonOpts.CPUShares) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if commonOpts.CPUSetCPUs != "" { | 
					
						
							|  |  |  | 		g.SetLinuxResourcesCPUCpus(commonOpts.CPUSetCPUs) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if commonOpts.CPUSetMems != "" { | 
					
						
							|  |  |  | 		g.SetLinuxResourcesCPUMems(commonOpts.CPUSetMems) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Resources - Memory
 | 
					
						
							|  |  |  | 	if commonOpts.Memory != 0 { | 
					
						
							|  |  |  | 		g.SetLinuxResourcesMemoryLimit(commonOpts.Memory) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if commonOpts.MemorySwap != 0 { | 
					
						
							|  |  |  | 		g.SetLinuxResourcesMemorySwap(commonOpts.MemorySwap) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// cgroup membership
 | 
					
						
							|  |  |  | 	if commonOpts.CgroupParent != "" { | 
					
						
							|  |  |  | 		g.SetLinuxCgroupsPath(commonOpts.CgroupParent) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-08 01:54:18 +08:00
										 |  |  | 	defaultContainerConfig, err := config.Default() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-07-06 17:14:06 +08:00
										 |  |  | 		return fmt.Errorf("failed to get container config: %w", err) | 
					
						
							| 
									
										
										
										
											2020-02-08 01:54:18 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	// Other process resource limits
 | 
					
						
							| 
									
										
										
										
											2023-10-25 20:55:41 +08:00
										 |  |  | 	if err := addRlimits(commonOpts.Ulimit, g, defaultContainerConfig.Containers.DefaultUlimits.Get()); err != nil { | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	logrus.Debugf("Resources: %#v", commonOpts) | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 18:22:31 +08:00
										 |  |  | func setupSlirp4netnsNetwork(config *config.Config, netns, cid string, options, hostnames []string) (func(), *netResult, error) { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 	// we need the TmpDir for the slirp4netns code
 | 
					
						
							| 
									
										
										
										
											2023-06-28 21:20:39 +08:00
										 |  |  | 	if err := os.MkdirAll(config.Engine.TmpDir, 0o751); err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 		return nil, nil, fmt.Errorf("failed to create tempdir: %w", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	res, err := slirp4netns.Setup(&slirp4netns.SetupOptions{ | 
					
						
							| 
									
										
										
										
											2023-06-28 21:20:39 +08:00
										 |  |  | 		Config:       config, | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 		ContainerID:  cid, | 
					
						
							|  |  |  | 		Netns:        netns, | 
					
						
							|  |  |  | 		ExtraOptions: options, | 
					
						
							|  |  |  | 		Pdeathsig:    syscall.SIGKILL, | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 		return nil, nil, err | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 	ip, err := slirp4netns.GetIP(res.Subnet) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 		return nil, nil, fmt.Errorf("get slirp4netns ip: %w", err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 18:22:31 +08:00
										 |  |  | 	dns, err := slirp4netns.GetDNS(res.Subnet) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, nil, fmt.Errorf("get slirp4netns dns ip: %w", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	result := &netResult{ | 
					
						
							|  |  |  | 		entries:           etchosts.HostEntries{{IP: ip.String(), Names: hostnames}}, | 
					
						
							|  |  |  | 		dnsServers:        []string{dns.String()}, | 
					
						
							|  |  |  | 		ipv6:              res.IPv6, | 
					
						
							|  |  |  | 		keepHostResolvers: true, | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 	return func() { | 
					
						
							| 
									
										
										
										
											2025-04-01 14:29:12 +08:00
										 |  |  | 		syscall.Kill(res.Pid, syscall.SIGKILL) //nolint:errcheck
 | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 		var status syscall.WaitStatus | 
					
						
							| 
									
										
										
										
											2025-04-01 14:29:12 +08:00
										 |  |  | 		syscall.Wait4(res.Pid, &status, 0, nil) //nolint:errcheck
 | 
					
						
							| 
									
										
										
										
											2024-03-18 18:22:31 +08:00
										 |  |  | 	}, result, nil | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 18:22:31 +08:00
										 |  |  | func setupPasta(config *config.Config, netns string, options, hostnames []string) (func(), *netResult, error) { | 
					
						
							| 
									
										
										
										
											2024-09-06 21:10:19 +08:00
										 |  |  | 	res, err := pasta.Setup(&pasta.SetupOptions{ | 
					
						
							| 
									
										
										
										
											2023-06-28 21:20:39 +08:00
										 |  |  | 		Config:       config, | 
					
						
							| 
									
										
										
										
											2023-06-23 00:14:50 +08:00
										 |  |  | 		Netns:        netns, | 
					
						
							|  |  |  | 		ExtraOptions: options, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 18:22:31 +08:00
										 |  |  | 	var entries etchosts.HostEntries | 
					
						
							|  |  |  | 	if len(res.IPAddresses) > 0 { | 
					
						
							|  |  |  | 		entries = etchosts.HostEntries{{IP: res.IPAddresses[0].String(), Names: hostnames}} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-06 21:10:19 +08:00
										 |  |  | 	mappedIP := "" | 
					
						
							|  |  |  | 	if len(res.MapGuestAddrIPs) > 0 { | 
					
						
							|  |  |  | 		mappedIP = res.MapGuestAddrIPs[0] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 18:22:31 +08:00
										 |  |  | 	result := &netResult{ | 
					
						
							| 
									
										
										
										
											2024-09-06 21:10:19 +08:00
										 |  |  | 		entries:                           entries, | 
					
						
							|  |  |  | 		dnsServers:                        res.DNSForwardIPs, | 
					
						
							|  |  |  | 		excludeIPs:                        res.IPAddresses, | 
					
						
							|  |  |  | 		ipv6:                              res.IPv6, | 
					
						
							|  |  |  | 		keepHostResolvers:                 true, | 
					
						
							|  |  |  | 		preferredHostContainersInternalIP: mappedIP, | 
					
						
							| 
									
										
										
										
											2023-06-23 00:14:50 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 18:22:31 +08:00
										 |  |  | 	return nil, result, nil | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 18:22:31 +08:00
										 |  |  | func (b *Builder) runConfigureNetwork(pid int, isolation define.Isolation, options RunOptions, network, containerName string, hostnames []string) (func(), *netResult, error) { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 	netns := fmt.Sprintf("/proc/%d/ns/net", pid) | 
					
						
							|  |  |  | 	var configureNetworks []string | 
					
						
							| 
									
										
										
										
											2023-06-28 21:20:39 +08:00
										 |  |  | 	defConfig, err := config.Default() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, nil, fmt.Errorf("failed to get container config: %w", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 	name, networkOpts, hasOpts := strings.Cut(network, ":") | 
					
						
							| 
									
										
										
										
											2023-06-23 00:14:50 +08:00
										 |  |  | 	var netOpts []string | 
					
						
							|  |  |  | 	if hasOpts { | 
					
						
							|  |  |  | 		netOpts = strings.Split(networkOpts, ",") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-06-28 21:20:39 +08:00
										 |  |  | 	if isolation == IsolationOCIRootless && name == "" { | 
					
						
							|  |  |  | 		switch defConfig.Network.DefaultRootlessNetworkCmd { | 
					
						
							|  |  |  | 		case slirp4netns.BinaryName, "": | 
					
						
							|  |  |  | 			name = slirp4netns.BinaryName | 
					
						
							|  |  |  | 		case pasta.BinaryName: | 
					
						
							|  |  |  | 			name = pasta.BinaryName | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			return nil, nil, fmt.Errorf("invalid default_rootless_network_cmd option %q", | 
					
						
							|  |  |  | 				defConfig.Network.DefaultRootlessNetworkCmd) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 	switch { | 
					
						
							| 
									
										
										
										
											2023-06-28 21:20:39 +08:00
										 |  |  | 	case name == slirp4netns.BinaryName: | 
					
						
							| 
									
										
										
										
											2024-03-18 18:22:31 +08:00
										 |  |  | 		return setupSlirp4netnsNetwork(defConfig, netns, containerName, netOpts, hostnames) | 
					
						
							| 
									
										
										
										
											2023-06-23 00:14:50 +08:00
										 |  |  | 	case name == pasta.BinaryName: | 
					
						
							| 
									
										
										
										
											2024-03-18 18:22:31 +08:00
										 |  |  | 		return setupPasta(defConfig, netns, netOpts, hostnames) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 	// Basically default case except we make sure to not split an empty
 | 
					
						
							|  |  |  | 	// name as this would return a slice with one empty string which is
 | 
					
						
							|  |  |  | 	// not a valid network name.
 | 
					
						
							|  |  |  | 	case len(network) > 0: | 
					
						
							|  |  |  | 		// old syntax allow comma separated network names
 | 
					
						
							|  |  |  | 		configureNetworks = strings.Split(network, ",") | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if isolation == IsolationOCIRootless { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 		return nil, nil, errors.New("cannot use networks as rootless") | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-06-23 03:55:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-06 04:36:49 +08:00
										 |  |  | 	if len(configureNetworks) == 0 { | 
					
						
							|  |  |  | 		configureNetworks = []string{b.NetworkInterface.DefaultNetworkName()} | 
					
						
							| 
									
										
										
										
											2021-06-23 03:55:00 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	// Make sure we can access the container's network namespace,
 | 
					
						
							|  |  |  | 	// even after it exits, to successfully tear down the
 | 
					
						
							|  |  |  | 	// interfaces.  Ensure this by opening a handle to the network
 | 
					
						
							|  |  |  | 	// namespace, and using our copy to both configure and
 | 
					
						
							|  |  |  | 	// deconfigure it.
 | 
					
						
							|  |  |  | 	netFD, err := unix.Open(netns, unix.O_RDONLY, 0) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 		return nil, nil, fmt.Errorf("opening network namespace: %w", err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	mynetns := fmt.Sprintf("/proc/%d/fd/%d", unix.Getpid(), netFD) | 
					
						
							| 
									
										
										
										
											2022-01-06 04:36:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	networks := make(map[string]nettypes.PerNetworkOptions, len(configureNetworks)) | 
					
						
							|  |  |  | 	for i, network := range configureNetworks { | 
					
						
							|  |  |  | 		networks[network] = nettypes.PerNetworkOptions{ | 
					
						
							|  |  |  | 			InterfaceName: fmt.Sprintf("eth%d", i), | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-01-06 04:36:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	opts := nettypes.NetworkOptions{ | 
					
						
							|  |  |  | 		ContainerID:   containerName, | 
					
						
							|  |  |  | 		ContainerName: containerName, | 
					
						
							|  |  |  | 		Networks:      networks, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-03-18 18:22:31 +08:00
										 |  |  | 	netStatus, err := b.NetworkInterface.Setup(mynetns, nettypes.SetupOptions{NetworkOptions: opts}) | 
					
						
							| 
									
										
										
										
											2022-01-06 04:36:49 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-04-19 16:55:16 +08:00
										 |  |  | 		return nil, nil, err | 
					
						
							| 
									
										
										
										
											2022-01-06 04:36:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 18:22:31 +08:00
										 |  |  | 	teardown := func() { | 
					
						
							| 
									
										
										
										
											2022-01-06 04:36:49 +08:00
										 |  |  | 		err := b.NetworkInterface.Teardown(mynetns, nettypes.TeardownOptions{NetworkOptions: opts}) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2022-01-06 04:36:49 +08:00
										 |  |  | 			options.Logger.Errorf("failed to cleanup network: %v", err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-01-06 04:36:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 18:22:31 +08:00
										 |  |  | 	return teardown, netStatusToNetResult(netStatus, hostnames), nil | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Create pipes to use for relaying stdio.
 | 
					
						
							|  |  |  | func runMakeStdioPipe(uid, gid int) ([][]int, error) { | 
					
						
							|  |  |  | 	stdioPipe := make([][]int, 3) | 
					
						
							|  |  |  | 	for i := range stdioPipe { | 
					
						
							|  |  |  | 		stdioPipe[i] = make([]int, 2) | 
					
						
							|  |  |  | 		if err := unix.Pipe(stdioPipe[i]); err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 			return nil, fmt.Errorf("creating pipe for container FD %d: %w", i, err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := unix.Fchown(stdioPipe[unix.Stdin][0], uid, gid); err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 		return nil, fmt.Errorf("setting owner of stdin pipe descriptor: %w", err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if err := unix.Fchown(stdioPipe[unix.Stdout][1], uid, gid); err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 		return nil, fmt.Errorf("setting owner of stdout pipe descriptor: %w", err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if err := unix.Fchown(stdioPipe[unix.Stderr][1], uid, gid); err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 		return nil, fmt.Errorf("setting owner of stderr pipe descriptor: %w", err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return stdioPipe, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-07 03:07:02 +08:00
										 |  |  | func setupNamespaces(_ *logrus.Logger, g *generate.Generator, namespaceOptions define.NamespaceOptions, idmapOptions define.IDMappingOptions, policy define.NetworkConfigurationPolicy) (configureNetwork bool, networkString string, configureUTS bool, err error) { | 
					
						
							| 
									
										
										
										
											2022-09-25 20:00:14 +08:00
										 |  |  | 	defaultContainerConfig, err := config.Default() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 		return false, "", false, fmt.Errorf("failed to get container config: %w", err) | 
					
						
							| 
									
										
										
										
											2022-09-25 20:00:14 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	addSysctl := func(prefixes []string) error { | 
					
						
							|  |  |  | 		for _, sysctl := range defaultContainerConfig.Sysctls() { | 
					
						
							|  |  |  | 			splitn := strings.SplitN(sysctl, "=", 2) | 
					
						
							|  |  |  | 			if len(splitn) > 2 { | 
					
						
							|  |  |  | 				return fmt.Errorf("sysctl %q defined in containers.conf must be formatted name=value", sysctl) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			for _, prefix := range prefixes { | 
					
						
							|  |  |  | 				if strings.HasPrefix(splitn[0], prefix) { | 
					
						
							|  |  |  | 					g.AddLinuxSysctl(splitn[0], splitn[1]) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	// Set namespace options in the container configuration.
 | 
					
						
							|  |  |  | 	configureUserns := false | 
					
						
							|  |  |  | 	specifiedNetwork := false | 
					
						
							|  |  |  | 	for _, namespaceOption := range namespaceOptions { | 
					
						
							|  |  |  | 		switch namespaceOption.Name { | 
					
						
							| 
									
										
										
										
											2022-09-25 20:00:14 +08:00
										 |  |  | 		case string(specs.IPCNamespace): | 
					
						
							|  |  |  | 			if !namespaceOption.Host { | 
					
						
							|  |  |  | 				if err := addSysctl([]string{"fs.mqueue"}); err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 					return false, "", false, err | 
					
						
							| 
									
										
										
										
											2022-09-25 20:00:14 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		case string(specs.UserNamespace): | 
					
						
							|  |  |  | 			configureUserns = false | 
					
						
							|  |  |  | 			if !namespaceOption.Host && namespaceOption.Path == "" { | 
					
						
							|  |  |  | 				configureUserns = true | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		case string(specs.NetworkNamespace): | 
					
						
							|  |  |  | 			specifiedNetwork = true | 
					
						
							|  |  |  | 			configureNetwork = false | 
					
						
							|  |  |  | 			if !namespaceOption.Host && (namespaceOption.Path == "" || !filepath.IsAbs(namespaceOption.Path)) { | 
					
						
							|  |  |  | 				if namespaceOption.Path != "" && !filepath.IsAbs(namespaceOption.Path) { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 					networkString = namespaceOption.Path | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 					namespaceOption.Path = "" | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-02-07 06:49:40 +08:00
										 |  |  | 				configureNetwork = (policy != define.NetworkDisabled) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		case string(specs.UTSNamespace): | 
					
						
							|  |  |  | 			configureUTS = false | 
					
						
							| 
									
										
										
										
											2022-09-25 20:00:14 +08:00
										 |  |  | 			if !namespaceOption.Host { | 
					
						
							|  |  |  | 				if namespaceOption.Path == "" { | 
					
						
							|  |  |  | 					configureUTS = true | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if err := addSysctl([]string{"kernel.hostname", "kernel.domainame"}); err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 					return false, "", false, err | 
					
						
							| 
									
										
										
										
											2022-09-25 20:00:14 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if namespaceOption.Host { | 
					
						
							|  |  |  | 			if err := g.RemoveLinuxNamespace(namespaceOption.Name); err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 				return false, "", false, fmt.Errorf("removing %q namespace for run: %w", namespaceOption.Name, err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} else if err := g.AddOrReplaceLinuxNamespace(namespaceOption.Name, namespaceOption.Path); err != nil { | 
					
						
							|  |  |  | 			if namespaceOption.Path == "" { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 				return false, "", false, fmt.Errorf("adding new %q namespace for run: %w", namespaceOption.Name, err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 			return false, "", false, fmt.Errorf("adding %q namespace %q for run: %w", namespaceOption.Name, namespaceOption.Path, err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// If we've got mappings, we're going to have to create a user namespace.
 | 
					
						
							|  |  |  | 	if len(idmapOptions.UIDMap) > 0 || len(idmapOptions.GIDMap) > 0 || configureUserns { | 
					
						
							| 
									
										
										
										
											2019-07-16 22:47:25 +08:00
										 |  |  | 		if err := g.AddOrReplaceLinuxNamespace(string(specs.UserNamespace), ""); err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 			return false, "", false, fmt.Errorf("adding new %q namespace for run: %w", string(specs.UserNamespace), err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		hostUidmap, hostGidmap, err := unshare.GetHostIDMappings("") | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 			return false, "", false, err | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		for _, m := range idmapOptions.UIDMap { | 
					
						
							|  |  |  | 			g.AddLinuxUIDMapping(m.HostID, m.ContainerID, m.Size) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if len(idmapOptions.UIDMap) == 0 { | 
					
						
							|  |  |  | 			for _, m := range hostUidmap { | 
					
						
							|  |  |  | 				g.AddLinuxUIDMapping(m.ContainerID, m.ContainerID, m.Size) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		for _, m := range idmapOptions.GIDMap { | 
					
						
							|  |  |  | 			g.AddLinuxGIDMapping(m.HostID, m.ContainerID, m.Size) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if len(idmapOptions.GIDMap) == 0 { | 
					
						
							|  |  |  | 			for _, m := range hostGidmap { | 
					
						
							|  |  |  | 				g.AddLinuxGIDMapping(m.ContainerID, m.ContainerID, m.Size) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if !specifiedNetwork { | 
					
						
							| 
									
										
										
										
											2019-07-16 22:47:25 +08:00
										 |  |  | 			if err := g.AddOrReplaceLinuxNamespace(string(specs.NetworkNamespace), ""); err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 				return false, "", false, fmt.Errorf("adding new %q namespace for run: %w", string(specs.NetworkNamespace), err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-02-07 06:49:40 +08:00
										 |  |  | 			configureNetwork = (policy != define.NetworkDisabled) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2019-07-16 22:47:25 +08:00
										 |  |  | 		if err := g.RemoveLinuxNamespace(string(specs.UserNamespace)); err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 			return false, "", false, fmt.Errorf("removing %q namespace for run: %w", string(specs.UserNamespace), err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if !specifiedNetwork { | 
					
						
							| 
									
										
										
										
											2019-07-16 22:47:25 +08:00
										 |  |  | 			if err := g.RemoveLinuxNamespace(string(specs.NetworkNamespace)); err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 				return false, "", false, fmt.Errorf("removing %q namespace for run: %w", string(specs.NetworkNamespace), err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-09-25 20:00:14 +08:00
										 |  |  | 	if configureNetwork { | 
					
						
							|  |  |  | 		if err := addSysctl([]string{"net"}); err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 			return false, "", false, err | 
					
						
							| 
									
										
										
										
											2022-09-25 20:00:14 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 	return configureNetwork, networkString, configureUTS, nil | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | func (b *Builder) configureNamespaces(g *generate.Generator, options *RunOptions) (bool, string, error) { | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	defaultNamespaceOptions, err := DefaultNamespaceOptions() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 		return false, "", err | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	namespaceOptions := defaultNamespaceOptions | 
					
						
							|  |  |  | 	namespaceOptions.AddOrReplace(b.NamespaceOptions...) | 
					
						
							|  |  |  | 	namespaceOptions.AddOrReplace(options.NamespaceOptions...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	networkPolicy := options.ConfigureNetwork | 
					
						
							| 
									
										
										
										
											2024-08-16 00:50:07 +08:00
										 |  |  | 	// Nothing was specified explicitly so network policy should be inherited from builder
 | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	if networkPolicy == NetworkDefault { | 
					
						
							|  |  |  | 		networkPolicy = b.ConfigureNetwork | 
					
						
							| 
									
										
										
										
											2021-10-27 17:13:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// If builder policy was NetworkDisabled and
 | 
					
						
							|  |  |  | 		// we want to disable network for this run.
 | 
					
						
							|  |  |  | 		// reset options.ConfigureNetwork to NetworkDisabled
 | 
					
						
							|  |  |  | 		// since it will be treated as source of truth later.
 | 
					
						
							|  |  |  | 		if networkPolicy == NetworkDisabled { | 
					
						
							|  |  |  | 			options.ConfigureNetwork = networkPolicy | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-09-11 20:01:43 +08:00
										 |  |  | 	if networkPolicy == NetworkDisabled { | 
					
						
							|  |  |  | 		namespaceOptions.AddOrReplace(define.NamespaceOptions{{Name: string(specs.NetworkNamespace), Host: false}}...) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 	configureNetwork, networkString, configureUTS, err := setupNamespaces(options.Logger, g, namespaceOptions, b.IDMappingOptions, networkPolicy) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 		return false, "", err | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if configureUTS { | 
					
						
							|  |  |  | 		if options.Hostname != "" { | 
					
						
							|  |  |  | 			g.SetHostname(options.Hostname) | 
					
						
							|  |  |  | 		} else if b.Hostname() != "" { | 
					
						
							|  |  |  | 			g.SetHostname(b.Hostname()) | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2025-01-25 04:41:31 +08:00
										 |  |  | 			hostname := stringid.TruncateID(b.ContainerID) | 
					
						
							|  |  |  | 			defConfig, err := config.Default() | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return false, "", fmt.Errorf("failed to get container config: %w", err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if defConfig.Containers.ContainerNameAsHostName { | 
					
						
							|  |  |  | 				if mapped := mapContainerNameToHostname(b.Container); mapped != "" { | 
					
						
							|  |  |  | 					hostname = mapped | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			g.SetHostname(hostname) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		g.SetHostname("") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	found := false | 
					
						
							|  |  |  | 	spec := g.Config | 
					
						
							|  |  |  | 	for i := range spec.Process.Env { | 
					
						
							|  |  |  | 		if strings.HasPrefix(spec.Process.Env[i], "HOSTNAME=") { | 
					
						
							|  |  |  | 			found = true | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !found { | 
					
						
							|  |  |  | 		spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("HOSTNAME=%s", spec.Hostname)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 21:31:32 +08:00
										 |  |  | 	return configureNetwork, networkString, nil | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-16 16:47:48 +08:00
										 |  |  | func runSetupBoundFiles(bundlePath string, bindFiles map[string]string) (mounts []specs.Mount) { | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	for dest, src := range bindFiles { | 
					
						
							|  |  |  | 		options := []string{"rbind"} | 
					
						
							|  |  |  | 		if strings.HasPrefix(src, bundlePath) { | 
					
						
							|  |  |  | 			options = append(options, bind.NoBindOption) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		mounts = append(mounts, specs.Mount{ | 
					
						
							|  |  |  | 			Source:      src, | 
					
						
							|  |  |  | 			Destination: dest, | 
					
						
							|  |  |  | 			Type:        "bind", | 
					
						
							|  |  |  | 			Options:     options, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-07-16 16:47:48 +08:00
										 |  |  | 	return mounts | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-08 01:54:18 +08:00
										 |  |  | func addRlimits(ulimit []string, g *generate.Generator, defaultUlimits []string) error { | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	var ( | 
					
						
							|  |  |  | 		ul  *units.Ulimit | 
					
						
							|  |  |  | 		err error | 
					
						
							| 
									
										
										
										
											2024-01-18 00:03:06 +08:00
										 |  |  | 		// setup rlimits
 | 
					
						
							|  |  |  | 		nofileSet bool | 
					
						
							|  |  |  | 		nprocSet  bool | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-08 01:54:18 +08:00
										 |  |  | 	ulimit = append(defaultUlimits, ulimit...) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	for _, u := range ulimit { | 
					
						
							| 
									
										
										
										
											2023-08-26 03:00:19 +08:00
										 |  |  | 		if ul, err = butil.ParseUlimit(u); err != nil { | 
					
						
							| 
									
										
										
										
											2022-07-06 17:14:06 +08:00
										 |  |  | 			return fmt.Errorf("ulimit option %q requires name=SOFT:HARD, failed to be parsed: %w", u, err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-18 00:03:06 +08:00
										 |  |  | 		if strings.ToUpper(ul.Name) == "NOFILE" { | 
					
						
							|  |  |  | 			nofileSet = true | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if strings.ToUpper(ul.Name) == "NPROC" { | 
					
						
							|  |  |  | 			nprocSet = true | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		g.AddProcessRlimits("RLIMIT_"+strings.ToUpper(ul.Name), uint64(ul.Hard), uint64(ul.Soft)) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-01-18 00:03:06 +08:00
										 |  |  | 	if !nofileSet { | 
					
						
							| 
									
										
										
										
											2025-04-01 08:45:17 +08:00
										 |  |  | 		lim := define.RLimitDefaultValue | 
					
						
							| 
									
										
										
										
											2024-01-18 00:03:06 +08:00
										 |  |  | 		var rlimit unix.Rlimit | 
					
						
							|  |  |  | 		if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlimit); err == nil { | 
					
						
							| 
									
										
										
										
											2025-04-01 08:45:17 +08:00
										 |  |  | 			if lim < rlimit.Max || unshare.IsRootless() { | 
					
						
							|  |  |  | 				lim = rlimit.Max | 
					
						
							| 
									
										
										
										
											2024-01-18 00:03:06 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			logrus.Warnf("Failed to return RLIMIT_NOFILE ulimit %q", err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-04-01 08:45:17 +08:00
										 |  |  | 		g.AddProcessRlimits("RLIMIT_NOFILE", lim, lim) | 
					
						
							| 
									
										
										
										
											2024-01-18 00:03:06 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if !nprocSet { | 
					
						
							| 
									
										
										
										
											2025-04-01 08:45:17 +08:00
										 |  |  | 		lim := define.RLimitDefaultValue | 
					
						
							| 
									
										
										
										
											2024-01-18 00:03:06 +08:00
										 |  |  | 		var rlimit unix.Rlimit | 
					
						
							|  |  |  | 		if err := unix.Getrlimit(unix.RLIMIT_NPROC, &rlimit); err == nil { | 
					
						
							| 
									
										
										
										
											2025-04-01 08:45:17 +08:00
										 |  |  | 			if lim < rlimit.Max || unshare.IsRootless() { | 
					
						
							|  |  |  | 				lim = rlimit.Max | 
					
						
							| 
									
										
										
										
											2024-01-18 00:03:06 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			logrus.Warnf("Failed to return RLIMIT_NPROC ulimit %q", err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-04-01 08:45:17 +08:00
										 |  |  | 		g.AddProcessRlimits("RLIMIT_NPROC", lim, lim) | 
					
						
							| 
									
										
										
										
											2024-01-18 00:03:06 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-13 01:47:25 +08:00
										 |  |  | func (b *Builder) runSetupVolumeMounts(mountLabel string, volumeMounts []string, optionMounts []specs.Mount, idMaps IDMaps) (mounts []specs.Mount, overlayDirs []string, Err error) { | 
					
						
							| 
									
										
										
										
											2019-05-30 04:34:17 +08:00
										 |  |  | 	// Make sure the overlay directory is clean before running
 | 
					
						
							|  |  |  | 	containerDir, err := b.store.ContainerDirectory(b.ContainerID) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2025-06-13 01:47:25 +08:00
										 |  |  | 		return nil, nil, fmt.Errorf("looking up container directory for %s: %w", b.ContainerID, err) | 
					
						
							| 
									
										
										
										
											2019-05-30 04:34:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if err := overlay.CleanupContent(containerDir); err != nil { | 
					
						
							| 
									
										
										
										
											2025-06-13 01:47:25 +08:00
										 |  |  | 		return nil, nil, fmt.Errorf("cleaning up overlay content for %s: %w", b.ContainerID, err) | 
					
						
							| 
									
										
										
										
											2019-05-30 04:34:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-20 02:17:11 +08:00
										 |  |  | 	parseMount := func(mountType, host, container string, options []string) (specs.Mount, error) { | 
					
						
							| 
									
										
										
										
											2020-11-18 22:50:53 +08:00
										 |  |  | 		var foundrw, foundro, foundz, foundZ, foundO, foundU bool | 
					
						
							| 
									
										
										
										
											2022-01-20 17:15:48 +08:00
										 |  |  | 		var rootProp, upperDir, workDir string | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		for _, opt := range options { | 
					
						
							|  |  |  | 			switch opt { | 
					
						
							|  |  |  | 			case "rw": | 
					
						
							|  |  |  | 				foundrw = true | 
					
						
							|  |  |  | 			case "ro": | 
					
						
							|  |  |  | 				foundro = true | 
					
						
							|  |  |  | 			case "z": | 
					
						
							|  |  |  | 				foundz = true | 
					
						
							|  |  |  | 			case "Z": | 
					
						
							|  |  |  | 				foundZ = true | 
					
						
							| 
									
										
										
										
											2019-04-29 21:41:18 +08:00
										 |  |  | 			case "O": | 
					
						
							|  |  |  | 				foundO = true | 
					
						
							| 
									
										
										
										
											2020-11-18 22:50:53 +08:00
										 |  |  | 			case "U": | 
					
						
							|  |  |  | 				foundU = true | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 			case "private", "rprivate", "slave", "rslave", "shared", "rshared": | 
					
						
							|  |  |  | 				rootProp = opt | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-01-20 17:15:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if strings.HasPrefix(opt, "upperdir") { | 
					
						
							|  |  |  | 				splitOpt := strings.SplitN(opt, "=", 2) | 
					
						
							|  |  |  | 				if len(splitOpt) > 1 { | 
					
						
							|  |  |  | 					upperDir = splitOpt[1] | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if strings.HasPrefix(opt, "workdir") { | 
					
						
							|  |  |  | 				splitOpt := strings.SplitN(opt, "=", 2) | 
					
						
							|  |  |  | 				if len(splitOpt) > 1 { | 
					
						
							|  |  |  | 					workDir = splitOpt[1] | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if !foundrw && !foundro { | 
					
						
							|  |  |  | 			options = append(options, "rw") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if foundz { | 
					
						
							| 
									
										
										
										
											2023-11-29 09:00:39 +08:00
										 |  |  | 			if err := relabel(host, mountLabel, true); err != nil { | 
					
						
							| 
									
										
										
										
											2020-10-15 17:16:50 +08:00
										 |  |  | 				return specs.Mount{}, err | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2025-04-17 01:37:44 +08:00
										 |  |  | 			options = slices.DeleteFunc(options, func(o string) bool { return o == "z" }) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if foundZ { | 
					
						
							| 
									
										
										
										
											2023-11-29 09:00:39 +08:00
										 |  |  | 			if err := relabel(host, mountLabel, false); err != nil { | 
					
						
							| 
									
										
										
										
											2020-10-15 17:16:50 +08:00
										 |  |  | 				return specs.Mount{}, err | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2025-04-17 01:37:44 +08:00
										 |  |  | 			options = slices.DeleteFunc(options, func(o string) bool { return o == "Z" }) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-11-18 22:50:53 +08:00
										 |  |  | 		if foundU { | 
					
						
							| 
									
										
										
										
											2022-05-27 10:47:30 +08:00
										 |  |  | 			if err := chown.ChangeHostPathOwnership(host, true, idMaps.processUID, idMaps.processGID); err != nil { | 
					
						
							| 
									
										
										
										
											2020-11-18 22:50:53 +08:00
										 |  |  | 				return specs.Mount{}, err | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2025-04-17 01:37:44 +08:00
										 |  |  | 			options = slices.DeleteFunc(options, func(o string) bool { return o == "U" }) | 
					
						
							| 
									
										
										
										
											2020-11-18 22:50:53 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-29 21:41:18 +08:00
										 |  |  | 		if foundO { | 
					
						
							| 
									
										
										
										
											2022-01-20 17:15:48 +08:00
										 |  |  | 			if (upperDir != "" && workDir == "") || (workDir != "" && upperDir == "") { | 
					
						
							|  |  |  | 				return specs.Mount{}, errors.New("if specifying upperdir then workdir must be specified or vice versa") | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-13 23:12:32 +08:00
										 |  |  | 			containerDir, err := b.store.ContainerDirectory(b.ContainerID) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return specs.Mount{}, err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-27 10:47:30 +08:00
										 |  |  | 			contentDir, err := overlay.TempDir(containerDir, idMaps.rootUID, idMaps.rootGID) | 
					
						
							| 
									
										
										
										
											2019-12-13 23:12:32 +08:00
										 |  |  | 			if err != nil { | 
					
						
							| 
									
										
										
										
											2022-07-06 17:14:06 +08:00
										 |  |  | 				return specs.Mount{}, fmt.Errorf("failed to create TempDir in the %s directory: %w", containerDir, err) | 
					
						
							| 
									
										
										
										
											2019-12-13 23:12:32 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-27 10:47:30 +08:00
										 |  |  | 			overlayOpts := overlay.Options{ | 
					
						
							|  |  |  | 				RootUID:                idMaps.rootUID, | 
					
						
							|  |  |  | 				RootGID:                idMaps.rootGID, | 
					
						
							| 
									
										
										
										
											2022-01-20 17:15:48 +08:00
										 |  |  | 				UpperDirOptionFragment: upperDir, | 
					
						
							|  |  |  | 				WorkDirOptionFragment:  workDir, | 
					
						
							| 
									
										
										
										
											2024-11-07 06:22:49 +08:00
										 |  |  | 				GraphOpts:              slices.Clone(b.store.GraphOptions()), | 
					
						
							| 
									
										
										
										
											2022-01-20 17:15:48 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			overlayMount, err := overlay.MountWithOptions(contentDir, host, container, &overlayOpts) | 
					
						
							| 
									
										
										
										
											2019-04-29 21:41:18 +08:00
										 |  |  | 			if err == nil { | 
					
						
							| 
									
										
										
										
											2025-06-13 01:47:25 +08:00
										 |  |  | 				overlayDirs = append(overlayDirs, contentDir) | 
					
						
							| 
									
										
										
										
											2019-04-29 21:41:18 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-11-18 22:50:53 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// If chown true, add correct ownership to the overlay temp directories.
 | 
					
						
							| 
									
										
										
										
											2024-11-07 06:22:49 +08:00
										 |  |  | 			if err == nil && foundU { | 
					
						
							| 
									
										
										
										
											2022-05-27 10:47:30 +08:00
										 |  |  | 				if err := chown.ChangeHostPathOwnership(contentDir, true, idMaps.processUID, idMaps.processGID); err != nil { | 
					
						
							| 
									
										
										
										
											2020-11-18 22:50:53 +08:00
										 |  |  | 					return specs.Mount{}, err | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-29 21:41:18 +08:00
										 |  |  | 			return overlayMount, err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		if rootProp == "" { | 
					
						
							|  |  |  | 			options = append(options, "private") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-06-20 02:17:11 +08:00
										 |  |  | 		if mountType != "tmpfs" { | 
					
						
							|  |  |  | 			mountType = "bind" | 
					
						
							|  |  |  | 			options = append(options, "rbind") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		return specs.Mount{ | 
					
						
							|  |  |  | 			Destination: container, | 
					
						
							| 
									
										
										
										
											2019-06-20 02:17:11 +08:00
										 |  |  | 			Type:        mountType, | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 			Source:      host, | 
					
						
							| 
									
										
										
										
											2019-06-20 02:17:11 +08:00
										 |  |  | 			Options:     options, | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		}, nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-04-29 21:41:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	// Bind mount volumes specified for this particular Run() invocation
 | 
					
						
							|  |  |  | 	for _, i := range optionMounts { | 
					
						
							|  |  |  | 		logrus.Debugf("setting up mounted volume at %q", i.Destination) | 
					
						
							| 
									
										
										
										
											2019-06-20 02:17:11 +08:00
										 |  |  | 		mount, err := parseMount(i.Type, i.Source, i.Destination, i.Options) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2025-06-13 01:47:25 +08:00
										 |  |  | 			return nil, nil, err | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		mounts = append(mounts, mount) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Bind mount volumes given by the user when the container was created
 | 
					
						
							|  |  |  | 	for _, i := range volumeMounts { | 
					
						
							|  |  |  | 		var options []string | 
					
						
							| 
									
										
										
										
											2021-10-11 11:26:35 +08:00
										 |  |  | 		spliti := parse.SplitStringWithColonEscape(i) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		if len(spliti) > 2 { | 
					
						
							|  |  |  | 			options = strings.Split(spliti[2], ",") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		options = append(options, "rbind") | 
					
						
							| 
									
										
										
										
											2019-06-20 02:17:11 +08:00
										 |  |  | 		mount, err := parseMount("bind", spliti[0], spliti[1], options) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2025-06-13 01:47:25 +08:00
										 |  |  | 			return nil, nil, err | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		mounts = append(mounts, mount) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-06-13 01:47:25 +08:00
										 |  |  | 	return mounts, overlayDirs, nil | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-18 23:47:40 +08:00
										 |  |  | func setupMaskedPaths(g *generate.Generator, opts *define.CommonBuildOptions) { | 
					
						
							|  |  |  | 	if slices.Contains(opts.Unmasks, "all") { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-03-20 18:44:16 +08:00
										 |  |  | nextMaskedPath: | 
					
						
							| 
									
										
										
										
											2025-03-20 18:38:51 +08:00
										 |  |  | 	for _, mp := range append(config.DefaultMaskedPaths(), opts.Masks...) { | 
					
						
							| 
									
										
										
										
											2025-03-20 18:44:16 +08:00
										 |  |  | 		for _, unmask := range opts.Unmasks { | 
					
						
							|  |  |  | 			match, err := filepath.Match(unmask, mp) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				logrus.Warnf("Invalid unmask pattern %q: %v", unmask, err) | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if match { | 
					
						
							|  |  |  | 				continue nextMaskedPath | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2024-12-18 23:47:40 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		g.AddLinuxMaskedPaths(mp) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func setupReadOnlyPaths(g *generate.Generator) { | 
					
						
							| 
									
										
										
										
											2023-10-28 01:10:18 +08:00
										 |  |  | 	for _, rp := range config.DefaultReadOnlyPaths { | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		g.AddLinuxReadonlyPaths(rp) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func setupCapAdd(g *generate.Generator, caps ...string) error { | 
					
						
							|  |  |  | 	for _, cap := range caps { | 
					
						
							|  |  |  | 		if err := g.AddProcessCapabilityBounding(cap); err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 			return fmt.Errorf("adding %q to the bounding capability set: %w", cap, err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if err := g.AddProcessCapabilityEffective(cap); err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 			return fmt.Errorf("adding %q to the effective capability set: %w", cap, err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if err := g.AddProcessCapabilityPermitted(cap); err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 			return fmt.Errorf("adding %q to the permitted capability set: %w", cap, err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func setupCapDrop(g *generate.Generator, caps ...string) error { | 
					
						
							|  |  |  | 	for _, cap := range caps { | 
					
						
							|  |  |  | 		if err := g.DropProcessCapabilityBounding(cap); err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 			return fmt.Errorf("removing %q from the bounding capability set: %w", cap, err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if err := g.DropProcessCapabilityEffective(cap); err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 			return fmt.Errorf("removing %q from the effective capability set: %w", cap, err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if err := g.DropProcessCapabilityPermitted(cap); err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 			return fmt.Errorf("removing %q from the permitted capability set: %w", cap, err) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-14 20:12:56 +08:00
										 |  |  | func setupCapabilities(g *generate.Generator, defaultCapabilities, adds, drops []string) error { | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	g.ClearProcessCapabilities() | 
					
						
							| 
									
										
										
										
											2020-01-14 20:12:56 +08:00
										 |  |  | 	if err := setupCapAdd(g, defaultCapabilities...); err != nil { | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-14 20:12:56 +08:00
										 |  |  | 	for _, c := range adds { | 
					
						
							|  |  |  | 		if strings.ToLower(c) == "all" { | 
					
						
							| 
									
										
										
										
											2020-02-19 03:50:08 +08:00
										 |  |  | 			adds = capabilities.AllCapabilities() | 
					
						
							| 
									
										
										
										
											2020-01-14 20:12:56 +08:00
										 |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-14 20:12:56 +08:00
										 |  |  | 	for _, c := range drops { | 
					
						
							|  |  |  | 		if strings.ToLower(c) == "all" { | 
					
						
							|  |  |  | 			g.ClearProcessCapabilities() | 
					
						
							|  |  |  | 			return nil | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-14 20:12:56 +08:00
										 |  |  | 	if err := setupCapAdd(g, adds...); err != nil { | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-14 20:12:56 +08:00
										 |  |  | 	return setupCapDrop(g, drops...) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-26 16:40:39 +08:00
										 |  |  | func addOrReplaceMount(mounts []specs.Mount, mount specs.Mount) []specs.Mount { | 
					
						
							| 
									
										
										
										
											2022-05-25 17:51:47 +08:00
										 |  |  | 	for i := range mounts { | 
					
						
							|  |  |  | 		if mounts[i].Destination == mount.Destination { | 
					
						
							|  |  |  | 			mounts[i] = mount | 
					
						
							|  |  |  | 			return mounts | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-05-25 17:51:47 +08:00
										 |  |  | 	return append(mounts, mount) | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | // 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
 | 
					
						
							| 
									
										
										
										
											2023-06-26 16:40:39 +08:00
										 |  |  | func setupSpecialMountSpecChanges(spec *specs.Spec, shmSize string) ([]specs.Mount, error) { | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 	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 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	addCgroup := true | 
					
						
							| 
									
										
										
										
											2023-03-23 21:47:58 +08:00
										 |  |  | 	// mount sys when root and no userns or when a new netns is created
 | 
					
						
							|  |  |  | 	canMountSys := (!isRootless && !isNewUserns) || isNetns | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 	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"}, | 
					
						
							| 
									
										
										
										
											2021-11-04 20:45:40 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 		mounts = addOrReplaceMount(mounts, sysMnt) | 
					
						
							| 
									
										
										
										
											2021-11-04 20:45:40 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 	gid5Available := true | 
					
						
							|  |  |  | 	if isRootless { | 
					
						
							|  |  |  | 		_, gids, err := unshare.GetHostIDMappings("") | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-08-07 03:05:01 +08:00
										 |  |  | 		gid5Available = checkIDsGreaterThan5(gids) | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if gid5Available && len(spec.Linux.GIDMappings) > 0 { | 
					
						
							| 
									
										
										
										
											2024-08-07 03:05:01 +08:00
										 |  |  | 		gid5Available = checkIDsGreaterThan5(spec.Linux.GIDMappings) | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if !gid5Available { | 
					
						
							|  |  |  | 		// If we have no GID mappings, the gid=5 default option would fail, so drop it.
 | 
					
						
							|  |  |  | 		devPts := specs.Mount{ | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 			Destination: "/dev/pts", | 
					
						
							|  |  |  | 			Type:        "devpts", | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 			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, | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 			Type:        "bind", | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 			Source:      proc, | 
					
						
							|  |  |  | 			Options:     []string{bind.NoBindOption, "rbind", "nosuid", "noexec", "nodev"}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		mounts = addOrReplaceMount(mounts, procMount) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-12-02 03:08:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 	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) | 
					
						
							| 
									
										
										
										
											2021-12-02 03:08:25 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// if userns and host ipc bind mount shm
 | 
					
						
							|  |  |  | 	if isUserns && !isIpcns { | 
					
						
							|  |  |  | 		// bind mount /dev/shm when it exists
 | 
					
						
							| 
									
										
										
										
											2024-04-11 16:43:18 +08:00
										 |  |  | 		if err := fileutils.Exists("/dev/shm"); err == nil { | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 			shmMount := specs.Mount{ | 
					
						
							|  |  |  | 				Source:      "/dev/shm", | 
					
						
							|  |  |  | 				Type:        "bind", | 
					
						
							|  |  |  | 				Destination: "/dev/shm", | 
					
						
							|  |  |  | 				Options:     []string{bind.NoBindOption, "rbind", "nosuid", "noexec", "nodev"}, | 
					
						
							| 
									
										
										
										
											2021-12-02 03:08:25 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 			mounts = addOrReplaceMount(mounts, shmMount) | 
					
						
							| 
									
										
										
										
											2021-12-02 03:08:25 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 	} else if shmSize != "" { | 
					
						
							|  |  |  | 		shmMount := specs.Mount{ | 
					
						
							|  |  |  | 			Source:      "shm", | 
					
						
							|  |  |  | 			Destination: "/dev/shm", | 
					
						
							|  |  |  | 			Type:        "tmpfs", | 
					
						
							|  |  |  | 			Options:     []string{"private", "nodev", "noexec", "nosuid", "mode=1777", "size=" + shmSize}, | 
					
						
							| 
									
										
										
										
											2021-12-02 03:08:25 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 		mounts = addOrReplaceMount(mounts, shmMount) | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return mounts, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-07 03:05:01 +08:00
										 |  |  | func checkIDsGreaterThan5(ids []specs.LinuxIDMapping) bool { | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 	for _, r := range ids { | 
					
						
							|  |  |  | 		if r.ContainerID <= 5 && 5 < r.ContainerID+r.Size { | 
					
						
							|  |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-04-04 21:58:18 +08:00
										 |  |  | 	return false | 
					
						
							| 
									
										
										
										
											2019-04-26 03:39:49 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-09 06:38:11 +08:00
										 |  |  | // Returns a Mount to add to the runtime spec's list of mounts, the ID of an
 | 
					
						
							|  |  |  | // image, the path to a mounted filesystem, and the path to an overlay
 | 
					
						
							|  |  |  | // filesystem, and an optional lock, or an error.
 | 
					
						
							| 
									
										
										
										
											2024-12-14 05:55:59 +08:00
										 |  |  | //
 | 
					
						
							|  |  |  | // The caller is expected to, after the command which uses the mount exits,
 | 
					
						
							| 
									
										
										
										
											2025-01-09 06:38:11 +08:00
										 |  |  | // clean up the overlay filesystem (if we returned one), unmount the mounted
 | 
					
						
							|  |  |  | // filesystem (if we provided the path to its mountpoint) and remove its
 | 
					
						
							|  |  |  | // mountpoint, unmount the image (if we mounted one), and release the lock (if
 | 
					
						
							|  |  |  | // we took one).
 | 
					
						
							|  |  |  | func (b *Builder) getCacheMount(tokens []string, sys *types.SystemContext, stageMountPoints map[string]internal.StageMountDetails, idMaps IDMaps, workDir, tmpDir string) (*specs.Mount, string, string, string, *lockfile.LockFile, error) { | 
					
						
							| 
									
										
										
										
											2021-10-07 16:27:17 +08:00
										 |  |  | 	var optionMounts []specs.Mount | 
					
						
							| 
									
										
										
										
											2025-01-09 06:38:11 +08:00
										 |  |  | 	optionMount, mountedImage, intermediateMount, overlayMount, targetLock, err := volumes.GetCacheMount(sys, tokens, b.store, b.MountLabel, stageMountPoints, idMaps.uidmap, idMaps.gidmap, workDir, tmpDir) | 
					
						
							| 
									
										
										
										
											2021-10-07 16:27:17 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2025-01-09 06:38:11 +08:00
										 |  |  | 		return nil, "", "", "", nil, err | 
					
						
							| 
									
										
										
										
											2021-10-07 16:27:17 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-10-19 08:55:01 +08:00
										 |  |  | 	succeeded := false | 
					
						
							|  |  |  | 	defer func() { | 
					
						
							| 
									
										
										
										
											2024-12-14 05:55:59 +08:00
										 |  |  | 		if !succeeded { | 
					
						
							| 
									
										
										
										
											2025-01-09 06:38:11 +08:00
										 |  |  | 			if overlayMount != "" { | 
					
						
							|  |  |  | 				if err := overlay.RemoveTemp(overlayMount); err != nil { | 
					
						
							|  |  |  | 					b.Logger.Debug(err.Error()) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2024-12-14 05:55:59 +08:00
										 |  |  | 			if intermediateMount != "" { | 
					
						
							|  |  |  | 				if err := mount.Unmount(intermediateMount); err != nil { | 
					
						
							|  |  |  | 					b.Logger.Debugf("unmounting %q: %v", intermediateMount, err) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if err := os.Remove(intermediateMount); err != nil { | 
					
						
							|  |  |  | 					b.Logger.Debugf("removing should-be-empty directory %q: %v", intermediateMount, err) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2025-01-09 06:38:11 +08:00
										 |  |  | 			if mountedImage != "" { | 
					
						
							|  |  |  | 				if _, err := b.store.UnmountImage(mountedImage, false); err != nil { | 
					
						
							|  |  |  | 					b.Logger.Debugf("unmounting image %q: %v", mountedImage, err) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2024-12-14 05:55:59 +08:00
										 |  |  | 			if targetLock != nil { | 
					
						
							|  |  |  | 				targetLock.Unlock() | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-10-19 08:55:01 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2024-12-14 05:55:59 +08:00
										 |  |  | 	optionMounts = append(optionMounts, optionMount) | 
					
						
							| 
									
										
										
										
											2025-06-13 01:47:25 +08:00
										 |  |  | 	volumes, overlayDirs, err := b.runSetupVolumeMounts(b.MountLabel, nil, optionMounts, idMaps) | 
					
						
							| 
									
										
										
										
											2021-10-07 16:27:17 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2025-01-09 06:38:11 +08:00
										 |  |  | 		return nil, "", "", "", nil, err | 
					
						
							| 
									
										
										
										
											2021-10-07 16:27:17 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-06-13 01:47:25 +08:00
										 |  |  | 	if len(overlayDirs) != 0 { | 
					
						
							|  |  |  | 		return nil, "", "", "", nil, errors.New("internal error: did not expect a resolved cache mount to use the O flag") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-10-19 08:55:01 +08:00
										 |  |  | 	succeeded = true | 
					
						
							| 
									
										
										
										
											2025-01-09 06:38:11 +08:00
										 |  |  | 	return &volumes[0], mountedImage, intermediateMount, overlayMount, targetLock, nil | 
					
						
							| 
									
										
										
										
											2021-10-07 16:27:17 +08:00
										 |  |  | } |