| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | package buildah | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2018-04-12 22:20:36 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2022-07-06 17:14:06 +08:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2018-10-20 02:49:51 +08:00
										 |  |  | 	"math/rand" | 
					
						
							| 
									
										
										
										
											2017-03-24 04:18:40 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-07 06:49:40 +08:00
										 |  |  | 	"github.com/containers/buildah/define" | 
					
						
							| 
									
										
										
										
											2021-04-11 01:44:51 +08:00
										 |  |  | 	"github.com/containers/common/libimage" | 
					
						
							| 
									
										
										
										
											2021-04-30 15:16:03 +08:00
										 |  |  | 	"github.com/containers/common/pkg/config" | 
					
						
							| 
									
										
										
										
											2019-11-01 03:18:10 +08:00
										 |  |  | 	"github.com/containers/image/v5/image" | 
					
						
							| 
									
										
										
										
											2019-10-26 05:19:30 +08:00
										 |  |  | 	"github.com/containers/image/v5/manifest" | 
					
						
							| 
									
										
										
										
											2021-08-03 16:39:06 +08:00
										 |  |  | 	"github.com/containers/image/v5/pkg/shortnames" | 
					
						
							| 
									
										
										
										
											2019-10-26 05:19:30 +08:00
										 |  |  | 	"github.com/containers/image/v5/transports" | 
					
						
							|  |  |  | 	"github.com/containers/image/v5/types" | 
					
						
							| 
									
										
										
										
											2017-05-17 23:53:28 +08:00
										 |  |  | 	"github.com/containers/storage" | 
					
						
							| 
									
										
										
										
											2022-04-01 22:37:45 +08:00
										 |  |  | 	"github.com/containers/storage/pkg/stringid" | 
					
						
							| 
									
										
										
										
											2019-11-01 03:18:10 +08:00
										 |  |  | 	digest "github.com/opencontainers/go-digest" | 
					
						
							| 
									
										
										
										
											2021-08-03 16:39:06 +08:00
										 |  |  | 	v1 "github.com/opencontainers/image-spec/specs-go/v1" | 
					
						
							| 
									
										
										
										
											2017-03-22 04:57:07 +08:00
										 |  |  | 	"github.com/openshift/imagebuilder" | 
					
						
							| 
									
										
										
										
											2017-10-10 03:05:56 +08:00
										 |  |  | 	"github.com/sirupsen/logrus" | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const ( | 
					
						
							| 
									
										
										
										
											2017-02-11 03:45:06 +08:00
										 |  |  | 	// BaseImageFakeName is the "name" of a source image which we interpret
 | 
					
						
							|  |  |  | 	// as "no image".
 | 
					
						
							| 
									
										
										
										
											2017-03-22 04:57:07 +08:00
										 |  |  | 	BaseImageFakeName = imagebuilder.NoBaseImageSpecifier | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 20:04:09 +08:00
										 |  |  | func getImageName(name string, img *storage.Image) string { | 
					
						
							|  |  |  | 	imageName := name | 
					
						
							|  |  |  | 	if len(img.Names) > 0 { | 
					
						
							|  |  |  | 		imageName = img.Names[0] | 
					
						
							|  |  |  | 		// When the image used by the container is a tagged image
 | 
					
						
							|  |  |  | 		// the container name might be set to the original image instead of
 | 
					
						
							| 
									
										
										
										
											2018-10-03 22:05:46 +08:00
										 |  |  | 		// the image given in the "from" command line.
 | 
					
						
							| 
									
										
										
										
											2018-01-18 20:04:09 +08:00
										 |  |  | 		// This loop is supposed to fix this.
 | 
					
						
							|  |  |  | 		for _, n := range img.Names { | 
					
						
							|  |  |  | 			if strings.Contains(n, name) { | 
					
						
							|  |  |  | 				imageName = n | 
					
						
							|  |  |  | 				break | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return imageName | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-29 05:07:58 +08:00
										 |  |  | func imageNamePrefix(imageName string) string { | 
					
						
							|  |  |  | 	prefix := imageName | 
					
						
							| 
									
										
										
										
											2022-04-01 22:37:45 +08:00
										 |  |  | 	if d, err := digest.Parse(imageName); err == nil { | 
					
						
							|  |  |  | 		prefix = d.Encoded() | 
					
						
							|  |  |  | 		if len(prefix) > 12 { | 
					
						
							|  |  |  | 			prefix = prefix[:12] | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if stringid.ValidateID(prefix) == nil { | 
					
						
							|  |  |  | 		prefix = stringid.TruncateID(prefix) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-03 19:01:41 +08:00
										 |  |  | 	s := strings.Split(prefix, ":") | 
					
						
							| 
									
										
										
										
											2017-06-29 05:07:58 +08:00
										 |  |  | 	if len(s) > 0 { | 
					
						
							| 
									
										
										
										
											2020-01-03 19:01:41 +08:00
										 |  |  | 		prefix = s[0] | 
					
						
							| 
									
										
										
										
											2017-06-29 05:07:58 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-03 19:01:41 +08:00
										 |  |  | 	s = strings.Split(prefix, "/") | 
					
						
							| 
									
										
										
										
											2017-06-29 05:07:58 +08:00
										 |  |  | 	if len(s) > 0 { | 
					
						
							| 
									
										
										
										
											2020-01-03 19:01:41 +08:00
										 |  |  | 		prefix = s[len(s)-1] | 
					
						
							| 
									
										
										
										
											2017-06-29 05:07:58 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	s = strings.Split(prefix, "@") | 
					
						
							|  |  |  | 	if len(s) > 0 { | 
					
						
							|  |  |  | 		prefix = s[0] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return prefix | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-07 06:49:40 +08:00
										 |  |  | func newContainerIDMappingOptions(idmapOptions *define.IDMappingOptions) storage.IDMappingOptions { | 
					
						
							| 
									
										
										
										
											2018-03-13 01:53:12 +08:00
										 |  |  | 	var options storage.IDMappingOptions | 
					
						
							|  |  |  | 	if idmapOptions != nil { | 
					
						
							| 
									
										
										
										
											2022-06-20 15:29:56 +08:00
										 |  |  | 		if idmapOptions.AutoUserNs { | 
					
						
							|  |  |  | 			options.AutoUserNs = true | 
					
						
							|  |  |  | 			options.AutoUserNsOpts = idmapOptions.AutoUserNsOpts | 
					
						
							| 
									
										
										
										
											2018-03-13 01:53:12 +08:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2022-06-20 15:29:56 +08:00
										 |  |  | 			options.HostUIDMapping = idmapOptions.HostUIDMapping | 
					
						
							|  |  |  | 			options.HostGIDMapping = idmapOptions.HostGIDMapping | 
					
						
							|  |  |  | 			uidmap, gidmap := convertRuntimeIDMaps(idmapOptions.UIDMap, idmapOptions.GIDMap) | 
					
						
							|  |  |  | 			if len(uidmap) > 0 && len(gidmap) > 0 { | 
					
						
							|  |  |  | 				options.UIDMap = uidmap | 
					
						
							|  |  |  | 				options.GIDMap = gidmap | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				options.HostUIDMapping = true | 
					
						
							|  |  |  | 				options.HostGIDMapping = true | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-03-13 01:53:12 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return options | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-06-02 02:52:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-20 02:49:51 +08:00
										 |  |  | func containerNameExist(name string, containers []storage.Container) bool { | 
					
						
							|  |  |  | 	for _, container := range containers { | 
					
						
							|  |  |  | 		for _, cname := range container.Names { | 
					
						
							|  |  |  | 			if cname == name { | 
					
						
							|  |  |  | 				return true | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func findUnusedContainer(name string, containers []storage.Container) string { | 
					
						
							|  |  |  | 	suffix := 1 | 
					
						
							|  |  |  | 	tmpName := name | 
					
						
							|  |  |  | 	for containerNameExist(tmpName, containers) { | 
					
						
							|  |  |  | 		tmpName = fmt.Sprintf("%s-%d", name, suffix) | 
					
						
							|  |  |  | 		suffix++ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return tmpName | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-02 02:52:16 +08:00
										 |  |  | func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions) (*Builder, error) { | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 	var ( | 
					
						
							|  |  |  | 		ref types.ImageReference | 
					
						
							|  |  |  | 		img *storage.Image | 
					
						
							|  |  |  | 		err error | 
					
						
							|  |  |  | 	) | 
					
						
							| 
									
										
										
										
											2021-04-11 01:44:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-02 02:52:16 +08:00
										 |  |  | 	if options.FromImage == BaseImageFakeName { | 
					
						
							|  |  |  | 		options.FromImage = "" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-06 04:36:49 +08:00
										 |  |  | 	if options.NetworkInterface == nil { | 
					
						
							|  |  |  | 		// create the network interface
 | 
					
						
							|  |  |  | 		// Note: It is important to do this before we pull any images/create containers.
 | 
					
						
							|  |  |  | 		// The default backend detection logic needs an empty store to correctly detect
 | 
					
						
							|  |  |  | 		// that we can use netavark, if the store was not empty it will use CNI to not break existing installs.
 | 
					
						
							|  |  |  | 		options.NetworkInterface, err = getNetworkInterface(store, options.CNIConfigDir, options.CNIPluginPath) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-14 04:03:13 +08:00
										 |  |  | 	systemContext := getSystemContext(store, options.SystemContext, options.SignaturePolicyPath) | 
					
						
							| 
									
										
										
										
											2018-06-02 02:52:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-08 06:27:39 +08:00
										 |  |  | 	if options.FromImage != "" && options.FromImage != BaseImageFakeName { | 
					
						
							| 
									
										
										
										
											2021-04-11 01:44:51 +08:00
										 |  |  | 		imageRuntime, err := libimage.RuntimeFromStore(store, &libimage.RuntimeOptions{SystemContext: systemContext}) | 
					
						
							| 
									
										
										
										
											2018-06-02 02:52:16 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-04-11 01:44:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-30 15:16:03 +08:00
										 |  |  | 		pullPolicy, err := config.ParsePullPolicy(options.PullPolicy.String()) | 
					
						
							| 
									
										
										
										
											2021-04-11 01:44:51 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Note: options.Format does *not* relate to the image we're
 | 
					
						
							|  |  |  | 		// about to pull (see tests/digests.bats).  So we're not
 | 
					
						
							|  |  |  | 		// forcing a MIMEType in the pullOptions below.
 | 
					
						
							|  |  |  | 		pullOptions := libimage.PullOptions{} | 
					
						
							|  |  |  | 		pullOptions.RetryDelay = &options.PullRetryDelay | 
					
						
							|  |  |  | 		pullOptions.OciDecryptConfig = options.OciDecryptConfig | 
					
						
							|  |  |  | 		pullOptions.SignaturePolicyPath = options.SignaturePolicyPath | 
					
						
							|  |  |  | 		pullOptions.Writer = options.ReportWriter | 
					
						
							| 
									
										
										
										
											2022-02-22 21:24:48 +08:00
										 |  |  | 		pullOptions.DestinationLookupReferenceFunc = cacheLookupReferenceFunc(options.BlobDirectory, types.PreserveOriginal) | 
					
						
							| 
									
										
										
										
											2021-04-11 01:44:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		maxRetries := uint(options.MaxPullRetries) | 
					
						
							|  |  |  | 		pullOptions.MaxRetries = &maxRetries | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		pulledImages, err := imageRuntime.Pull(ctx, options.FromImage, pullPolicy, &pullOptions) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if len(pulledImages) > 0 { | 
					
						
							|  |  |  | 			img = pulledImages[0].StorageImage() | 
					
						
							|  |  |  | 			ref, err = pulledImages[0].StorageReference() | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return nil, err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-06-29 05:07:58 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-04-11 01:44:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-01 03:18:10 +08:00
										 |  |  | 	imageSpec := options.FromImage | 
					
						
							| 
									
										
										
										
											2017-06-29 05:07:58 +08:00
										 |  |  | 	imageID := "" | 
					
						
							| 
									
										
										
										
											2019-07-02 05:14:07 +08:00
										 |  |  | 	imageDigest := "" | 
					
						
							| 
									
										
										
										
											2018-06-09 00:55:46 +08:00
										 |  |  | 	topLayer := "" | 
					
						
							| 
									
										
										
										
											2017-06-29 05:07:58 +08:00
										 |  |  | 	if img != nil { | 
					
						
							| 
									
										
										
										
											2019-11-01 03:18:10 +08:00
										 |  |  | 		imageSpec = getImageName(imageNamePrefix(imageSpec), img) | 
					
						
							| 
									
										
										
										
											2017-03-16 05:19:29 +08:00
										 |  |  | 		imageID = img.ID | 
					
						
							| 
									
										
										
										
											2018-06-09 00:55:46 +08:00
										 |  |  | 		topLayer = img.TopLayer | 
					
						
							| 
									
										
										
										
											2017-06-29 05:07:58 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-11-01 03:18:10 +08:00
										 |  |  | 	var src types.Image | 
					
						
							| 
									
										
										
										
											2018-06-12 06:31:04 +08:00
										 |  |  | 	if ref != nil { | 
					
						
							| 
									
										
										
										
											2019-11-01 03:18:10 +08:00
										 |  |  | 		srcSrc, err := ref.NewImageSource(ctx, systemContext) | 
					
						
							| 
									
										
										
										
											2018-06-12 06:31:04 +08:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 			return nil, fmt.Errorf("instantiating image for %q: %w", transports.ImageName(ref), err) | 
					
						
							| 
									
										
										
										
											2018-06-12 06:31:04 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-11-01 03:18:10 +08:00
										 |  |  | 		defer srcSrc.Close() | 
					
						
							|  |  |  | 		manifestBytes, manifestType, err := srcSrc.GetManifest(ctx, nil) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 			return nil, fmt.Errorf("loading image manifest for %q: %w", transports.ImageName(ref), err) | 
					
						
							| 
									
										
										
										
											2019-11-01 03:18:10 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if manifestDigest, err := manifest.Digest(manifestBytes); err == nil { | 
					
						
							|  |  |  | 			imageDigest = manifestDigest.String() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		var instanceDigest *digest.Digest | 
					
						
							|  |  |  | 		if manifest.MIMETypeIsMultiImage(manifestType) { | 
					
						
							|  |  |  | 			list, err := manifest.ListFromBlob(manifestBytes, manifestType) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 				return nil, fmt.Errorf("parsing image manifest for %q as list: %w", transports.ImageName(ref), err) | 
					
						
							| 
									
										
										
										
											2019-07-02 05:14:07 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-11-01 03:18:10 +08:00
										 |  |  | 			instance, err := list.ChooseInstance(systemContext) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 				return nil, fmt.Errorf("finding an appropriate image in manifest list %q: %w", transports.ImageName(ref), err) | 
					
						
							| 
									
										
										
										
											2019-11-01 03:18:10 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			instanceDigest = &instance | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		src, err = image.FromUnparsedImage(ctx, systemContext, image.UnparsedInstance(srcSrc, instanceDigest)) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 			return nil, fmt.Errorf("instantiating image for %q instance %q: %w", transports.ImageName(ref), instanceDigest, err) | 
					
						
							| 
									
										
										
										
											2019-07-02 05:14:07 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-06-12 06:31:04 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-29 05:29:37 +08:00
										 |  |  | 	name := "working-container" | 
					
						
							| 
									
										
										
										
											2021-12-15 06:11:32 +08:00
										 |  |  | 	if options.ContainerSuffix != "" { | 
					
						
							|  |  |  | 		name = options.ContainerSuffix | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-29 05:29:37 +08:00
										 |  |  | 	if options.Container != "" { | 
					
						
							|  |  |  | 		name = options.Container | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2019-11-01 03:18:10 +08:00
										 |  |  | 		if imageSpec != "" { | 
					
						
							|  |  |  | 			name = imageNamePrefix(imageSpec) + "-" + name | 
					
						
							| 
									
										
										
										
											2017-07-29 05:29:37 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-10-20 02:49:51 +08:00
										 |  |  | 	var container *storage.Container | 
					
						
							|  |  |  | 	tmpName := name | 
					
						
							|  |  |  | 	if options.Container == "" { | 
					
						
							|  |  |  | 		containers, err := store.Containers() | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2022-07-06 17:14:06 +08:00
										 |  |  | 			return nil, fmt.Errorf("unable to check for container names: %w", err) | 
					
						
							| 
									
										
										
										
											2018-10-20 02:49:51 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		tmpName = findUnusedContainer(tmpName, containers) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-29 05:07:58 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-22 08:27:25 +08:00
										 |  |  | 	suffixDigitsModulo := 100 | 
					
						
							| 
									
										
										
										
											2019-02-23 10:08:09 +08:00
										 |  |  | 	for { | 
					
						
							| 
									
										
										
										
											2022-01-09 20:29:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		var flags map[string]interface{} | 
					
						
							|  |  |  | 		// check if we have predefined ProcessLabel and MountLabel
 | 
					
						
							|  |  |  | 		// this could be true if this is another stage in a build
 | 
					
						
							|  |  |  | 		if options.ProcessLabel != "" && options.MountLabel != "" { | 
					
						
							|  |  |  | 			flags = map[string]interface{}{ | 
					
						
							|  |  |  | 				"ProcessLabel": options.ProcessLabel, | 
					
						
							|  |  |  | 				"MountLabel":   options.MountLabel, | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-10-20 02:49:51 +08:00
										 |  |  | 		coptions := storage.ContainerOptions{ | 
					
						
							|  |  |  | 			LabelOpts:        options.CommonBuildOpts.LabelOpts, | 
					
						
							|  |  |  | 			IDMappingOptions: newContainerIDMappingOptions(options.IDMappingOptions), | 
					
						
							| 
									
										
										
										
											2022-01-09 20:29:26 +08:00
										 |  |  | 			Flags:            flags, | 
					
						
							| 
									
										
										
										
											2021-02-12 17:31:29 +08:00
										 |  |  | 			Volatile:         true, | 
					
						
							| 
									
										
										
										
											2018-10-20 02:49:51 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		container, err = store.CreateContainer("", []string{tmpName}, imageID, "", "", &coptions) | 
					
						
							|  |  |  | 		if err == nil { | 
					
						
							| 
									
										
										
										
											2018-09-13 02:34:05 +08:00
										 |  |  | 			name = tmpName | 
					
						
							| 
									
										
										
										
											2018-10-20 02:49:51 +08:00
										 |  |  | 			break | 
					
						
							| 
									
										
										
										
											2018-09-13 02:34:05 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-07-06 17:14:06 +08:00
										 |  |  | 		if !errors.Is(err, storage.ErrDuplicateName) || options.Container != "" { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 			return nil, fmt.Errorf("creating container: %w", err) | 
					
						
							| 
									
										
										
										
											2018-10-20 02:49:51 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-04-22 08:27:25 +08:00
										 |  |  | 		tmpName = fmt.Sprintf("%s-%d", name, rand.Int()%suffixDigitsModulo) | 
					
						
							| 
									
										
										
										
											2023-04-22 08:28:36 +08:00
										 |  |  | 		if suffixDigitsModulo < 1_000_000_000 { | 
					
						
							|  |  |  | 			suffixDigitsModulo *= 10 | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-09-13 02:34:05 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 	defer func() { | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2018-10-18 04:58:32 +08:00
										 |  |  | 			if err2 := store.DeleteContainer(container.ID); err2 != nil { | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 				logrus.Errorf("error deleting container %q: %v", container.ID, err2) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-08 07:11:43 +08:00
										 |  |  | 	uidmap, gidmap := convertStorageIDMaps(container.UIDMap, container.GIDMap) | 
					
						
							| 
									
										
										
										
											2018-06-27 04:35:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	defaultNamespaceOptions, err := DefaultNamespaceOptions() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	namespaceOptions := defaultNamespaceOptions | 
					
						
							| 
									
										
										
										
											2018-03-08 07:11:43 +08:00
										 |  |  | 	namespaceOptions.AddOrReplace(options.NamespaceOptions...) | 
					
						
							| 
									
										
										
										
											2017-10-20 05:47:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 	builder := &Builder{ | 
					
						
							| 
									
										
										
										
											2017-11-08 06:44:24 +08:00
										 |  |  | 		store:                 store, | 
					
						
							|  |  |  | 		Type:                  containerType, | 
					
						
							| 
									
										
										
										
											2019-11-01 03:18:10 +08:00
										 |  |  | 		FromImage:             imageSpec, | 
					
						
							| 
									
										
										
										
											2017-11-08 06:44:24 +08:00
										 |  |  | 		FromImageID:           imageID, | 
					
						
							| 
									
										
										
										
											2019-07-02 05:14:07 +08:00
										 |  |  | 		FromImageDigest:       imageDigest, | 
					
						
							| 
									
										
										
										
											2022-12-22 03:51:59 +08:00
										 |  |  | 		GroupAdd:              options.GroupAdd, | 
					
						
							| 
									
										
										
										
											2017-11-08 06:44:24 +08:00
										 |  |  | 		Container:             name, | 
					
						
							|  |  |  | 		ContainerID:           container.ID, | 
					
						
							| 
									
										
										
										
											2023-02-17 04:47:08 +08:00
										 |  |  | 		ImageAnnotations:      map[string]string{}, | 
					
						
							| 
									
										
										
										
											2017-11-08 06:44:24 +08:00
										 |  |  | 		ImageCreatedBy:        "", | 
					
						
							| 
									
										
										
										
											2018-10-20 02:49:51 +08:00
										 |  |  | 		ProcessLabel:          container.ProcessLabel(), | 
					
						
							|  |  |  | 		MountLabel:            container.MountLabel(), | 
					
						
							| 
									
										
										
										
											2017-11-08 06:44:24 +08:00
										 |  |  | 		DefaultMountsFilePath: options.DefaultMountsFilePath, | 
					
						
							| 
									
										
										
										
											2018-05-12 01:00:14 +08:00
										 |  |  | 		Isolation:             options.Isolation, | 
					
						
							| 
									
										
										
										
											2018-03-08 07:11:43 +08:00
										 |  |  | 		NamespaceOptions:      namespaceOptions, | 
					
						
							| 
									
										
										
										
											2018-04-14 06:20:25 +08:00
										 |  |  | 		ConfigureNetwork:      options.ConfigureNetwork, | 
					
						
							|  |  |  | 		CNIPluginPath:         options.CNIPluginPath, | 
					
						
							|  |  |  | 		CNIConfigDir:          options.CNIConfigDir, | 
					
						
							| 
									
										
										
										
											2021-02-07 06:49:40 +08:00
										 |  |  | 		IDMappingOptions: define.IDMappingOptions{ | 
					
						
							| 
									
										
										
										
											2018-03-08 07:11:43 +08:00
										 |  |  | 			HostUIDMapping: len(uidmap) == 0, | 
					
						
							|  |  |  | 			HostGIDMapping: len(uidmap) == 0, | 
					
						
							|  |  |  | 			UIDMap:         uidmap, | 
					
						
							|  |  |  | 			GIDMap:         gidmap, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-01-06 04:36:49 +08:00
										 |  |  | 		Capabilities:     copyStringSlice(options.Capabilities), | 
					
						
							|  |  |  | 		CommonBuildOpts:  options.CommonBuildOpts, | 
					
						
							|  |  |  | 		TopLayer:         topLayer, | 
					
						
							| 
									
										
										
										
											2022-05-04 01:12:01 +08:00
										 |  |  | 		Args:             copyStringStringMap(options.Args), | 
					
						
							| 
									
										
										
										
											2022-01-06 04:36:49 +08:00
										 |  |  | 		Format:           options.Format, | 
					
						
							|  |  |  | 		TempVolumes:      map[string]bool{}, | 
					
						
							|  |  |  | 		Devices:          options.Devices, | 
					
						
							|  |  |  | 		Logger:           options.Logger, | 
					
						
							|  |  |  | 		NetworkInterface: options.NetworkInterface, | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if options.Mount { | 
					
						
							| 
									
										
										
										
											2018-10-20 02:49:51 +08:00
										 |  |  | 		_, err = builder.Mount(container.MountLabel()) | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 			return nil, fmt.Errorf("mounting build container %q: %w", builder.ContainerID, err) | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												bud: teach --platform to take a list
Add a pkg/parse.PlatformsFromOptions() which understands a "variant"
value as an optional third value in an OS/ARCH[/VARIANT] argument value,
which accepts a comma-separated list of them, and which returns a list
of platforms.
Teach "from" and "pull" about the --platform option and add integration
tests for them, warning if --platform was given multiple values.
Add a define.BuildOptions.JobSemaphore which an imagebuildah executor
will use in preference to one that it might allocate for itself.
In main(), allocate a JobSemaphore if the number of jobs is not 0 (which
we treat as "unlimited", and continue to allow executors to do).
In addManifest(), take a lock on the manifest list's image ID so that we
don't overwrite changes that another thread might be making while we're
attempting to make changes to it.  In main(), create an empty list if
the list doesn't already exist before we start down this path, so that
we don't get two threads trying to create that manifest list at the same
time later on.  Two processes could still try to create the same list
twice, but it's an incremental improvement.
Finally, if we've been given multiple platforms to build for, run their
builds concurrently and gather up their results.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
											
										 
											2021-06-22 22:52:49 +08:00
										 |  |  | 	if err := builder.initConfig(ctx, src, systemContext); err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 		return nil, fmt.Errorf("preparing image configuration: %w", err) | 
					
						
							| 
									
										
										
										
											2018-06-12 05:43:21 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-02-17 04:47:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if !options.PreserveBaseImageAnns { | 
					
						
							|  |  |  | 		builder.SetAnnotation(v1.AnnotationBaseImageDigest, imageDigest) | 
					
						
							|  |  |  | 		if !shortnames.IsShortName(imageSpec) { | 
					
						
							|  |  |  | 			// If the base image was specified as a fully-qualified
 | 
					
						
							|  |  |  | 			// image name, let's set it.
 | 
					
						
							|  |  |  | 			builder.SetAnnotation(v1.AnnotationBaseImageName, imageSpec) | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			builder.UnsetAnnotation(v1.AnnotationBaseImageName) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 	err = builder.Save() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-09-18 18:36:08 +08:00
										 |  |  | 		return nil, fmt.Errorf("saving builder state for container %q: %w", builder.ContainerID, err) | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return builder, nil | 
					
						
							|  |  |  | } |