diff --git a/Dockerfile b/Dockerfile index 8a954c5e160..08dab8e46fe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,9 @@ COPY imagecontent/etc/containers /etc/containers COPY imagecontent/usr/share/containers /usr/share/containers RUN mkdir -p /var/cache/blobs \ /var/lib/shared/overlay-images \ - /var/lib/shared/overlay-layers && \ + /var/lib/shared/overlay-layers \ + /etc/pki/tls/certs /etc/docker/certs.d && \ + chmod g+w /etc/pki/tls/certs /etc/docker/certs.d && \ touch /var/lib/shared/overlay-images/images.lock \ /var/lib/shared/overlay-layers/layers.lock diff --git a/Dockerfile-dev b/Dockerfile-dev index e23f186fd77..db3c8c06d57 100644 --- a/Dockerfile-dev +++ b/Dockerfile-dev @@ -3,7 +3,6 @@ LABEL io.k8s.display-name="OpenShift Origin Builder" \ io.k8s.description="This is a component of OpenShift Origin and is responsible for executing image builds." \ io.openshift.tags="openshift,builder" -# TODO: Add fuse-overlayfs once we build off of RHEL-8 UBI RUN INSTALL_PKGS=" \ bind-utils bsdtar findutils fuse-overlayfs git hostname lsof \ procps-ng runc socat tar tree util-linux wget which \ @@ -15,7 +14,9 @@ COPY imagecontent/etc/containers /etc/containers COPY imagecontent/usr/share/containers /usr/share/containers RUN mkdir -p /var/cache/blobs \ /var/lib/shared/overlay-images \ - /var/lib/shared/overlay-layers && \ + /var/lib/shared/overlay-layers \ + /etc/pki/tls/certs /etc/docker/certs.d && \ + chmod g+w /etc/pki/tls/certs /etc/docker/certs.d && \ touch /var/lib/shared/overlay-images/images.lock \ /var/lib/shared/overlay-layers/layers.lock diff --git a/Dockerfile.rhel7 b/Dockerfile.rhel7 index e26f2cba6ed..8a1bd40eacc 100644 --- a/Dockerfile.rhel7 +++ b/Dockerfile.rhel7 @@ -17,7 +17,9 @@ COPY imagecontent/etc/containers /etc/containers COPY imagecontent/usr/share/containers /usr/share/containers RUN mkdir -p /var/cache/blobs \ /var/lib/shared/overlay-images \ - /var/lib/shared/overlay-layers && \ + /var/lib/shared/overlay-layers \ + /etc/pki/tls/certs /etc/docker/certs.d && \ + chmod g+w /etc/pki/tls/certs /etc/docker/certs.d && \ touch /var/lib/shared/overlay-images/images.lock \ /var/lib/shared/overlay-layers/layers.lock diff --git a/Dockerfile.rhel8 b/Dockerfile.rhel8 index 834ccdd87de..80590d8fdd8 100644 --- a/Dockerfile.rhel8 +++ b/Dockerfile.rhel8 @@ -16,7 +16,9 @@ COPY imagecontent/etc/containers /etc/containers COPY imagecontent/usr/share/containers /usr/share/containers RUN mkdir -p /var/cache/blobs \ /var/lib/shared/overlay-images \ - /var/lib/shared/overlay-layers && \ + /var/lib/shared/overlay-layers \ + /etc/pki/tls/certs /etc/docker/certs.d && \ + chmod g+w /etc/pki/tls/certs /etc/docker/certs.d && \ touch /var/lib/shared/overlay-images/images.lock \ /var/lib/shared/overlay-layers/layers.lock diff --git a/cmd/builder.go b/cmd/builder.go index c7a6859b727..564064eb053 100644 --- a/cmd/builder.go +++ b/cmd/builder.go @@ -11,6 +11,7 @@ import ( kcmdutil "k8s.io/kubectl/pkg/cmd/util" "k8s.io/kubectl/pkg/util/templates" + "github.com/containers/common/pkg/config" "github.com/openshift/builder/pkg/build/builder/cmd" "github.com/openshift/builder/pkg/version" ) @@ -65,31 +66,72 @@ func NewCmdVersion(fullName string, versionInfo k8sversion.Info, buildahVersion // NewCommandS2IBuilder provides a CLI handler for S2I build type func NewCommandS2IBuilder(name string) *cobra.Command { + var isolation, ociRuntime, storageDriver, storageOptions string + + defaultConfig, err := config.DefaultConfig() + kcmdutil.CheckErr(err) + cmd := &cobra.Command{ Use: name, Short: "Run a Source-to-Image build", Long: s2iBuilderLong, Run: func(c *cobra.Command, args []string) { - err := cmd.RunS2IBuild(c.OutOrStderr()) + var err error + if isolation == "" { + isolation, err = builderDefaultIsolation() + kcmdutil.CheckErr(err) + } + if storageDriver == "" { + storageDriver, storageOptions, err = builderDefaultStorage() + kcmdutil.CheckErr(err) + } + err = cmd.RunS2IBuild(c.OutOrStderr(), isolation, ociRuntime, storageDriver, storageOptions) kcmdutil.CheckErr(err) }, } + flags := cmd.Flags() + flags.StringVar(&isolation, "isolation", isolation, "type of process `isolation` to use for RUN instructions") + flags.StringVar(&ociRuntime, "oci-runtime", defaultConfig.Engine.OCIRuntime, "runtime to invoke for OCI isolation") + flags.StringVar(&storageDriver, "storage-driver", storageDriver, "storage driver to use for storing layers, images, and working containers") + flags.StringVar(&storageOptions, "storage-options", storageOptions, "storage options to use when storing layers, images, and working containers") + cmd.AddCommand(NewCmdVersion(name, version.Get(), version.BuildahVersion(), os.Stdout)) return cmd } // NewCommandDockerBuilder provides a CLI handler for Docker build type func NewCommandDockerBuilder(name string) *cobra.Command { + var isolation, ociRuntime, storageDriver, storageOptions string + + defaultConfig, err := config.DefaultConfig() + kcmdutil.CheckErr(err) + cmd := &cobra.Command{ Use: name, Short: "Run a Docker build", Long: dockerBuilderLong, Run: func(c *cobra.Command, args []string) { - err := cmd.RunDockerBuild(c.OutOrStderr()) + var err error + if isolation == "" { + isolation, err = builderDefaultIsolation() + kcmdutil.CheckErr(err) + } + if storageDriver == "" { + storageDriver, storageOptions, err = builderDefaultStorage() + kcmdutil.CheckErr(err) + } + err = cmd.RunDockerBuild(c.OutOrStderr(), isolation, ociRuntime, storageDriver, storageOptions) kcmdutil.CheckErr(err) }, } + + flags := cmd.Flags() + flags.StringVar(&isolation, "isolation", isolation, "type of process `isolation` to use for RUN instructions") + flags.StringVar(&ociRuntime, "oci-runtime", defaultConfig.Engine.OCIRuntime, "runtime to invoke for OCI isolation") + flags.StringVar(&storageDriver, "storage-driver", storageDriver, "storage driver to use for storing layers, images, and working containers") + flags.StringVar(&storageOptions, "storage-options", storageOptions, "storage options to use when storing layers, images, and working containers") + cmd.AddCommand(NewCmdVersion(name, version.Get(), version.BuildahVersion(), os.Stdout)) return cmd } diff --git a/cmd/defaults.go b/cmd/defaults.go new file mode 100644 index 00000000000..9cb715310d3 --- /dev/null +++ b/cmd/defaults.go @@ -0,0 +1,106 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" + + "github.com/containers/storage" + "k8s.io/klog/v2" +) + +// Return "chroot" if we know we're not actually root, "oci" otherwise. +func builderDefaultIsolation() (string, error) { + if inUserNamespace() { + // We probably don't have enough privileges to use a proper + // runtime. + // Lean on the container that we're in being itself + // unprivileged (i.e., having control groups including the + // device cgroup configured for us, being provided with a + // smaller set of devices in /dev, and likely running without a + // few capabilities that we don't need), and reduce the degree + // of isolation that we try to use to what we know we're + // actually allowed to do in an unprivileged container. + return "chroot", nil + } + // Use the proper runtime. + return "oci", nil +} + +// Check that /dev/fuse is usable and we have the fuse-overlayfs helper. +func builderCanUseOverlayFUSE() error { + device, err := os.Open("/dev/fuse") + if err != nil { + return fmt.Errorf("error opening device: %v", err) + } + defer device.Close() + if _, err := os.Stat("/usr/bin/fuse-overlayfs"); err != nil { + return err + } + return nil +} + +// Try various storage setups until we find one that works with the privileges +// that we currently have. +func builderDefaultStorage() (string, string, error) { + for _, candidate := range []struct { + driver, options string + also func() error + }{ + {"overlay", `["mountopt=metacopy=on"]`, nil}, + {"overlay", ``, nil}, + {"overlay", `["mount_program=/usr/bin/fuse-overlayfs","mountopt=metacopy=on"]`, builderCanUseOverlayFUSE}, + {"overlay", `["mount_program=/usr/bin/fuse-overlayfs"]`, builderCanUseOverlayFUSE}, + {"vfs", "", nil}, + } { + var options []string + // Is there an additional test? + if candidate.also != nil { + if why := candidate.also(); why != nil { + klog.V(2).Info(why.Error()) + continue + } + } + // Are there options for this case? + if candidate.options != "" { + err := json.Unmarshal([]byte(candidate.options), &options) + if err != nil { + klog.Errorf("internal error parsing options %q: %v", candidate.options, err) + continue + } + } + // Precreate some things. + if _, err := os.Stat(fmt.Sprintf("/var/lib/shared/%s-layers/layers.lock", candidate.driver)); err == nil { + if _, err := os.Stat(fmt.Sprintf("/var/lib/shared/%s-images/images.lock", candidate.driver)); err == nil { + if _, err := os.Stat(fmt.Sprintf("/var/lib/shared/%s-containers/containers.lock", candidate.driver)); err == nil { + options = append(options, fmt.Sprintf("%s.imagestore=/var/lib/shared", candidate.driver)) + } + } + } + // Clear out the directory we're about to use. + os.RemoveAll("/var/lib/containers/storage/tmp") + os.RemoveAll("/run/containers/storage/tmp") + // Try to initialize storage. + store, err := storage.GetStore(storage.StoreOptions{ + GraphRoot: "/var/lib/containers/storage/tmp", + RunRoot: "/run/containers/storage/tmp", + GraphDriverName: candidate.driver, + GraphDriverOptions: options, + }) + if err != nil { + klog.V(2).Infof("Unable to initialize storage %q with options %v: %v\n", candidate.driver, options, err) + continue + } + // Shut down the storage that we were able to initialize. + _, err = store.Shutdown(true) + // Re-encode the options before returning them. + reencodedOptions, err := json.Marshal(options) + if err != nil { + klog.Errorf("Error re-encoding options %v: %v\n", options, err) + continue + } + klog.Infof("Defaulting to storage driver %q with options %v.\n", candidate.driver, options) + return candidate.driver, string(reencodedOptions), nil + } + return "", "", nil +} diff --git a/cmd/main.go b/cmd/main.go index fff8b55d2e6..ec8022b3f95 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -10,10 +10,12 @@ import ( "syscall" "time" + "github.com/containers/storage" "github.com/containers/storage/pkg/reexec" "github.com/spf13/cobra" "k8s.io/component-base/logs" + kcmdutil "k8s.io/kubectl/pkg/cmd/util" "github.com/openshift/builder/pkg/build/builder" "github.com/openshift/builder/pkg/version" @@ -52,19 +54,37 @@ func main() { fs := s2ifs.NewFileSystem() err := fs.Copy(clusterCASrc, clusterCADst, map[string]string{}) if err != nil { - fmt.Printf("Error setting up cluster CA cert: %v", err) + fmt.Printf("Error setting up cluster CA cert: %v\n", err) os.Exit(1) } runtimeCASrc := fmt.Sprintf("%s/certs.d", builder.ConfigMapCertsMountPath) err = fs.CopyContents(runtimeCASrc, runtimeCertRoot, map[string]string{}) if err != nil { - fmt.Printf("Error setting up service CA cert: %v", err) + fmt.Printf("Error setting up service CA cert: %v\n", err) os.Exit(1) } basename := filepath.Base(os.Args[0]) command := CommandFor(basename) + + flags := command.Flags() + var uidmap, gidmap string + var useNewuidmap, useNewgidmap bool + flags.StringVar(&uidmap, "uidmap", "", "re-exec in a user namespace using the specified UID map") + flags.StringVar(&gidmap, "gidmap", "", "re-exec in a user namespace using the specified GID map") + flags.BoolVar(&useNewuidmap, "use-newuidmap", os.Geteuid() != 0, "use newuidmap to set up UID mappings") + flags.BoolVar(&useNewgidmap, "use-newgidmap", os.Geteuid() != 0, "use newgidmap to set up GID mappings") + wrapped := command.Run + command.Run = func(c *cobra.Command, args []string) { + storeOptions, err := storage.DefaultStoreOptions(false, 0) + kcmdutil.CheckErr(err) + os.MkdirAll(storeOptions.GraphRoot, 0775) + os.MkdirAll(storeOptions.RunRoot, 0775) + maybeReexecUsingUserNamespace(uidmap, useNewuidmap, gidmap, useNewgidmap) + wrapped(c, args) + } + if err := command.Execute(); err != nil { os.Exit(1) } @@ -76,15 +96,15 @@ func CommandFor(basename string) *cobra.Command { var cmd *cobra.Command switch basename { - case "openshift-sti-build": + case "openshift-sti-build", "openshift-sti-build-in-a-user-namespace": cmd = NewCommandS2IBuilder(basename) - case "openshift-docker-build": + case "openshift-docker-build", "openshift-docker-build-in-a-user-namespace": cmd = NewCommandDockerBuilder(basename) - case "openshift-git-clone": + case "openshift-git-clone", "openshift-git-clone-in-a-user-namespace": cmd = NewCommandGitClone(basename) - case "openshift-manage-dockerfile": + case "openshift-manage-dockerfile", "openshift-manage-dockerfile-in-a-user-namespace": cmd = NewCommandManageDockerfile(basename) - case "openshift-extract-image-content": + case "openshift-extract-image-content", "openshift-extract-image-content-in-a-user-namespace": cmd = NewCommandExtractImageContent(basename) default: fmt.Printf("unknown command name: %s\n", basename) diff --git a/cmd/userns.go b/cmd/userns.go new file mode 100644 index 00000000000..4285810db21 --- /dev/null +++ b/cmd/userns.go @@ -0,0 +1,114 @@ +package main + +import ( + "fmt" + "os" + "strconv" + "strings" + "syscall" + + "github.com/containers/storage/pkg/unshare" + specs "github.com/opencontainers/runtime-spec/specs-go" + "github.com/syndtr/gocapability/capability" + "k8s.io/klog/v2" +) + +const usernsMarkerVariable = "BUILDER_USERNS_CONFIGURED" + +func parseIDMappings(uidmap, gidmap string) ([]specs.LinuxIDMapping, []specs.LinuxIDMapping) { + // helper for parsing a string of the form "container:host:size[,container:host:size...]" + parseMapping := func(what, mapSpec string) []specs.LinuxIDMapping { + var mapping []specs.LinuxIDMapping + for _, entry := range strings.Split(mapSpec, ",") { + if entry == "" { + continue + } + triple := strings.Split(entry, ":") + if len(triple) != 3 { + klog.Errorf("Invalid format for %s entry %q\n", what, entry) + return nil + } + containerID, err := strconv.ParseUint(triple[0], 10, 32) + if err != nil { + klog.Errorf("Invalid format for %s entry %q container ID %q: %v\n", what, entry, triple[0], err) + return nil + } + hostID, err := strconv.ParseUint(triple[1], 10, 32) + if err != nil { + klog.Errorf("Invalid format for %s entry %q host ID %q: %v\n", what, entry, triple[1], err) + return nil + } + size, err := strconv.ParseUint(triple[2], 10, 32) + if err != nil { + klog.Errorf("Invalid format for %s entry %q size %q: %v\n", what, entry, triple[2], err) + return nil + } + mapping = append(mapping, specs.LinuxIDMapping{ + ContainerID: uint32(containerID), + HostID: uint32(hostID), + Size: uint32(size), + }) + } + return mapping + } + + // Return what's already in place, or whatever was specified. + UIDs, GIDs, err := unshare.GetHostIDMappings("") + if err != nil { + klog.Fatalf("Error reading current ID mappings: %v\n", err) + } + if os.Geteuid() != 0 { + uid := fmt.Sprintf("%d", os.Geteuid()) + UIDs, GIDs, err = unshare.GetSubIDMappings(uid, uid) + if err != nil { + klog.Fatalf("Error reading ID mappings for %s: %v\n", err) + } + } + if uidMappings := parseMapping("uidmap", uidmap); len(uidMappings) != 0 { + UIDs = uidMappings + } + if gidMappings := parseMapping("gidmap", gidmap); len(gidMappings) != 0 { + GIDs = gidMappings + } + return UIDs, GIDs +} + +func inUserNamespace() bool { + return os.Getenv(usernsMarkerVariable) != "" +} + +func maybeReexecUsingUserNamespace(uidmap string, useNewuidmap bool, gidmap string, useNewgidmap bool) { + // If we've already done all of this, there's no need to do it again. + if inUserNamespace() { + return + } + + // If there's nothing to do, just return. + if uidmap == "" && gidmap == "" && os.Geteuid() == 0 { + if caps, err := capability.NewPid(0); err == nil && caps.Get(capability.EFFECTIVE, capability.CAP_SYS_ADMIN) { + return + } + } + + // Parse our --uidmap and --gidmap flags into ID mappings and re-exec ourselves. + cmd := unshare.Command(append([]string{fmt.Sprintf("%s-in-a-user-namespace", os.Args[0])}, os.Args[1:]...)...) + + // Set up a new user namespace with the ID mappings. + cmd.UnshareFlags = syscall.CLONE_NEWUSER | syscall.CLONE_NEWNS + cmd.UidMappings, cmd.GidMappings = parseIDMappings(uidmap, gidmap) + cmd.UseNewuidmap, cmd.UseNewgidmap = useNewuidmap, useNewgidmap + cmd.GidMappingsEnableSetgroups = true + + // Set markers so that we know we've done all of this already, and set + // HOME so that the child doesn't try to read configuration from + // /root/.config, which it can't if it's another user that's being told + // it's root because it's running in a user namespace, which would + // trigger a permissions error. HOME also needs to be writable. + cmd.Env = append(os.Environ(), usernsMarkerVariable+"=done", "HOME=/var/lib/containers") + + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + unshare.ExecRunnable(cmd, nil) + klog.Fatalf("Internal error: should not have gotten back from ExecRunnable().\n") +} diff --git a/go.mod b/go.mod index aa9fcc58895..32d41ff56ab 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.1.3 github.com/spf13/pflag v1.0.5 + github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 golang.org/x/sys v0.0.0-20210324051608-47abb6519492 k8s.io/api v0.21.1 k8s.io/apimachinery v0.21.1 diff --git a/go.sum b/go.sum index 751985f36b3..ce57cd27770 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,7 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774 h1:SCbEWT58NSt7d2mcFdvxC9uyrdcTfvBbPLThhkDmXzg= github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774/go.mod h1:6/0dYRLLXyJjbkIPeeGyoJ/eKOSI0eU6eTlCBYibgd0= github.com/Azure/azure-sdk-for-go v43.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= @@ -119,9 +120,11 @@ github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1 github.com/checkpoint-restore/go-criu/v4 v4.0.2/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= +github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= github.com/cilium/ebpf v0.0.0-20200507155900-a9f01edf17e3/go.mod h1:XT+cAw5wfvsodedcijoh1l9cf7v1x9FlFB/3VmF/O8s= @@ -230,6 +233,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= @@ -271,7 +275,9 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3 github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484 h1:pEtiCjIXx3RvGjlUJuCNxNOw0MNblyR9Wi+vJGBFh+8= github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -292,6 +298,7 @@ github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/ github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsouza/go-dockerclient v1.7.2 h1:bBEAcqLTkpq205jooP5RVroUKiVEWgGecHyeZc4OFjo= github.com/fsouza/go-dockerclient v1.7.2/go.mod h1:+ugtMCVRwnPfY7d8/baCzZ3uwB0BrG5DB8OzbtxaRz8= @@ -558,6 +565,7 @@ github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc= @@ -622,6 +630,7 @@ github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1: github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/moby/buildkit v0.6.3 h1:2eFVHDz1E9uyMsbquywvjPIZ0yHT58HWCcn0K9qavWM= github.com/moby/buildkit v0.6.3/go.mod h1:JKVImCzxztxvULr5P6ZiBfA/B2P+ZpR6UHxOXQn4KiU= github.com/moby/ipvs v1.0.1/go.mod h1:2pngiyseZbIKXNv7hsKj3O9UEz30c53MT9005gt2hxQ= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= @@ -657,8 +666,10 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= @@ -672,6 +683,7 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.15.2/go.mod h1:Dd6YFfwBW84ETqqtL0CPyPXillHgY6XhQH3uuCCTr/o= +github.com/onsi/ginkgo v1.16.1 h1:foqVmeWDD6yYpK+Yz3fHyNIxFYNxswxqNFjSKe+vI54= github.com/onsi/ginkgo v1.16.1/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -680,6 +692,7 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= +github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug= github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -804,6 +817,7 @@ github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvW github.com/seccomp/libseccomp-golang v0.9.2-0.20200616122406-847368b35ebf h1:b0+ZBD3rohnkQ4q5duD1+RyTXTg9yk+qTOPMSQtapO0= github.com/seccomp/libseccomp-golang v0.9.2-0.20200616122406-847368b35ebf/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -848,6 +862,7 @@ github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h github.com/storageos/go-api v2.2.0+incompatible/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -891,9 +906,11 @@ github.com/vbauerster/mpb/v5 v5.4.0/go.mod h1:fi4wVo7BVQ22QcvFObm+VwliQXlV1eBT8J github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852 h1:cPXZWzzG0NllBLdjWoD1nDfaqu98YMv+OneaKc8sPOA= github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae h1:4hwBBUfQCFe3Cym0ZtKyq7L16eZUtYKs+BaHDN6mAns= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE= @@ -1184,6 +1201,7 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= @@ -1261,6 +1279,7 @@ gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUy gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= @@ -1278,6 +1297,7 @@ gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76 gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= @@ -1294,8 +1314,10 @@ gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/build/builder/cmd/builder.go b/pkg/build/builder/cmd/builder.go index a13f275bfdb..6e0b3adaad1 100644 --- a/pkg/build/builder/cmd/builder.go +++ b/pkg/build/builder/cmd/builder.go @@ -61,7 +61,7 @@ type builderConfig struct { blobCache string } -func newBuilderConfigFromEnvironment(out io.Writer, needsDocker bool) (*builderConfig, error) { +func newBuilderConfigFromEnvironment(out io.Writer, needsDocker bool, isolation, ociRuntime, storageDriver, storageOptions string) (*builderConfig, error) { cfg := &builderConfig{} var err error @@ -108,12 +108,12 @@ func newBuilderConfigFromEnvironment(out io.Writer, needsDocker bool) (*builderC if err != nil { return nil, err } - if driver, ok := os.LookupEnv("BUILD_STORAGE_DRIVER"); ok { - storeOptions.GraphDriverName = driver + if storageDriver != "" { + storeOptions.GraphDriverName = storageDriver } - if storageOptions, ok := os.LookupEnv("BUILD_STORAGE_OPTIONS"); ok { + if storageOptions != "" { if err := json.Unmarshal([]byte(storageOptions), &storeOptions.GraphDriverOptions); err != nil { - log.V(0).Infof("Error parsing BUILD_STORAGE_OPTIONS (%q): %v", storageOptions, err) + log.V(0).Infof("Error parsing storage options (%q): %v", storageOptions, err) return nil, err } } @@ -155,7 +155,7 @@ func newBuilderConfigFromEnvironment(out io.Writer, needsDocker bool) (*builderC imageOptimizationPolicy = buildapiv1.ImageOptimizationSkipLayers } - dockerClient, err := bld.GetDaemonlessClient(systemContext, store, cfg.blobCache, imageOptimizationPolicy) + dockerClient, err := bld.GetDaemonlessClient(systemContext, store, cfg.blobCache, isolation, ociRuntime, imageOptimizationPolicy) if err != nil { return nil, fmt.Errorf("no daemonless store: %v", err) } @@ -363,9 +363,9 @@ func (s2iBuilder) Build(dockerClient bld.DockerClient, sock string, buildsClient return bld.NewS2IBuilder(dockerClient, sock, buildsClient, build, cgLimits).Build() } -func runBuild(out io.Writer, builder builder) error { +func runBuild(out io.Writer, builder builder, isolation, ociRuntime, storageDriver, storageOptions string) error { logVersion() - cfg, err := newBuilderConfigFromEnvironment(out, true) + cfg, err := newBuilderConfigFromEnvironment(out, true, isolation, ociRuntime, storageDriver, storageOptions) if err != nil { return err } @@ -376,7 +376,7 @@ func runBuild(out io.Writer, builder builder) error { } // RunDockerBuild creates a docker builder and runs its build -func RunDockerBuild(out io.Writer) error { +func RunDockerBuild(out io.Writer, isolation, ociRuntime, storageDriver, storageOptions string) error { switch { case log.Is(6): serviceability.InitLogrus("DEBUG") @@ -385,11 +385,11 @@ func RunDockerBuild(out io.Writer) error { case log.Is(0): serviceability.InitLogrus("WARN") } - return runBuild(out, dockerBuilder{}) + return runBuild(out, dockerBuilder{}, isolation, ociRuntime, storageDriver, storageOptions) } // RunS2IBuild creates a S2I builder and runs its build -func RunS2IBuild(out io.Writer) error { +func RunS2IBuild(out io.Writer, isolation, ociRuntime, storageDriver, storageOptions string) error { switch { case log.Is(6): serviceability.InitLogrus("DEBUG") @@ -398,7 +398,7 @@ func RunS2IBuild(out io.Writer) error { case log.Is(0): serviceability.InitLogrus("WARN") } - return runBuild(out, s2iBuilder{}) + return runBuild(out, s2iBuilder{}, isolation, ociRuntime, storageDriver, storageOptions) } // RunGitClone performs a git clone using the build defined in the environment @@ -412,7 +412,7 @@ func RunGitClone(out io.Writer) error { serviceability.InitLogrus("WARN") } logVersion() - cfg, err := newBuilderConfigFromEnvironment(out, false) + cfg, err := newBuilderConfigFromEnvironment(out, false, "", "", "", "") if err != nil { return err } @@ -439,7 +439,7 @@ func RunManageDockerfile(out io.Writer) error { serviceability.InitLogrus("WARN") } logVersion() - cfg, err := newBuilderConfigFromEnvironment(out, false) + cfg, err := newBuilderConfigFromEnvironment(out, false, "", "", "", "") if err != nil { return err } @@ -461,7 +461,7 @@ func RunExtractImageContent(out io.Writer) error { serviceability.InitLogrus("WARN") } logVersion() - cfg, err := newBuilderConfigFromEnvironment(out, true) + cfg, err := newBuilderConfigFromEnvironment(out, true, "", "", "", "") if err != nil { return err } diff --git a/pkg/build/builder/daemonless.go b/pkg/build/builder/daemonless.go index bf5f36c7fbf..41e5adacb13 100644 --- a/pkg/build/builder/daemonless.go +++ b/pkg/build/builder/daemonless.go @@ -242,7 +242,7 @@ func daemonlessProcessLimits() (defaultProcessLimits []string) { return defaultProcessLimits } -func buildDaemonlessImage(sc types.SystemContext, store storage.Store, isolation buildah.Isolation, contextDir string, optimization buildapiv1.ImageOptimizationPolicy, opts *docker.BuildImageOptions, blobCacheDirectory string) error { +func buildDaemonlessImage(sc types.SystemContext, store storage.Store, isolation buildah.Isolation, ociRuntime, contextDir string, optimization buildapiv1.ImageOptimizationPolicy, opts *docker.BuildImageOptions, blobCacheDirectory string) error { log.V(2).Infof("Building...") args := make(map[string]string) @@ -295,6 +295,7 @@ func buildDaemonlessImage(sc types.SystemContext, store storage.Store, isolation ContextDirectory: contextDir, PullPolicy: pullPolicy, Isolation: isolation, + Runtime: ociRuntime, TransientMounts: transientMounts, Args: args, Output: opts.Name, @@ -686,7 +687,7 @@ func inspectDaemonlessImage(sc types.SystemContext, store storage.Store, name st // daemonlessRun mimics the 'docker run --rm' CLI command well enough. It creates and // starts a container and streams its logs. The container is removed after it terminates. -func daemonlessRun(ctx context.Context, store storage.Store, isolation buildah.Isolation, createOpts docker.CreateContainerOptions, attachOpts docker.AttachToContainerOptions, blobCacheDirectory string) error { +func daemonlessRun(ctx context.Context, store storage.Store, isolation buildah.Isolation, ociRuntime string, createOpts docker.CreateContainerOptions, attachOpts docker.AttachToContainerOptions, blobCacheDirectory string) error { if createOpts.Config == nil { return fmt.Errorf("error calling daemonlessRun: expected a Config") } @@ -725,6 +726,7 @@ func daemonlessRun(ctx context.Context, store storage.Store, isolation buildah.I } runOptions := buildah.RunOptions{ Isolation: isolation, + Runtime: ociRuntime, Entrypoint: entrypoint, Cmd: createOpts.Config.Cmd, Stdout: attachOpts.OutputStream, @@ -740,6 +742,7 @@ type DaemonlessClient struct { SystemContext types.SystemContext Store storage.Store Isolation buildah.Isolation + OCIRuntime string BlobCacheDirectory string ImageOptimizationPolicy buildapiv1.ImageOptimizationPolicy builders map[string]*buildah.Builder @@ -747,15 +750,29 @@ type DaemonlessClient struct { // GetDaemonlessClient returns a valid implemenatation of the DockerClient // interface, or an error if the implementation couldn't be created. -func GetDaemonlessClient(systemContext types.SystemContext, store storage.Store, blobCacheDirectory string, imageOptimizationPolicy buildapiv1.ImageOptimizationPolicy) (client DockerClient, err error) { +func GetDaemonlessClient(systemContext types.SystemContext, store storage.Store, blobCacheDirectory string, isolationSpec, ociRuntime string, imageOptimizationPolicy buildapiv1.ImageOptimizationPolicy) (client DockerClient, err error) { if blobCacheDirectory != "" { log.V(0).Infof("Caching blobs under %q.", blobCacheDirectory) } + var isolation buildah.Isolation + switch isolationSpec { + case "", "oci": + isolation = buildah.IsolationOCI + case "rootless": + isolation = buildah.IsolationOCIRootless + case "chroot": + isolation = buildah.IsolationChroot + default: + log.V(0).Infof("Unrecognized isolation type %q.", isolationSpec) + return nil, errors.Errorf("Unrecognized isolation type %q.", isolationSpec) + } + return &DaemonlessClient{ SystemContext: systemContext, Store: store, - Isolation: buildah.IsolationOCI, + Isolation: isolation, + OCIRuntime: ociRuntime, BlobCacheDirectory: blobCacheDirectory, ImageOptimizationPolicy: imageOptimizationPolicy, builders: make(map[string]*buildah.Builder), @@ -763,7 +780,7 @@ func GetDaemonlessClient(systemContext types.SystemContext, store storage.Store, } func (d *DaemonlessClient) BuildImage(opts docker.BuildImageOptions) error { - return buildDaemonlessImage(d.SystemContext, d.Store, d.Isolation, opts.ContextDir, d.ImageOptimizationPolicy, &opts, d.BlobCacheDirectory) + return buildDaemonlessImage(d.SystemContext, d.Store, d.Isolation, d.OCIRuntime, opts.ContextDir, d.ImageOptimizationPolicy, &opts, d.BlobCacheDirectory) } func (d *DaemonlessClient) PushImage(opts docker.PushImageOptions, auth docker.AuthConfiguration) (string, error) { @@ -778,29 +795,6 @@ func (d *DaemonlessClient) RemoveImage(name string) error { return removeDaemonlessImage(d.SystemContext, d.Store, name) } -func (d *DaemonlessClient) CreateContainer(opts docker.CreateContainerOptions) (*docker.Container, error) { - options := buildah.BuilderOptions{ - FromImage: opts.Config.Image, - Container: opts.Name, - BlobDirectory: d.BlobCacheDirectory, - MaxPullRetries: DefaultPushOrPullRetryCount, - PullRetryDelay: DefaultPushOrPullRetryDelay, - } - builder, err := buildah.NewBuilder(opts.Context, d.Store, options) - if err != nil { - return nil, err - } - builder.SetCmd(opts.Config.Cmd) - builder.SetEntrypoint(opts.Config.Entrypoint) - if builder.Container != "" { - d.builders[builder.Container] = builder - } - if builder.ContainerID != "" { - d.builders[builder.ContainerID] = builder - } - return &docker.Container{ID: builder.ContainerID}, nil -} - func (d *DaemonlessClient) RemoveContainer(opts docker.RemoveContainerOptions) error { builder, ok := d.builders[opts.ID] if !ok { diff --git a/pkg/build/builder/daemonless_unsupported.go b/pkg/build/builder/daemonless_unsupported.go index 8199e2a4a93..25ce2d93bc4 100644 --- a/pkg/build/builder/daemonless_unsupported.go +++ b/pkg/build/builder/daemonless_unsupported.go @@ -31,9 +31,6 @@ func (d *DaemonlessClient) PushImage(opts docker.PushImageOptions, auth docker.A func (d *DaemonlessClient) RemoveImage(name string) error { return errors.New("removing images not supported on this platform") } -func (d *DaemonlessClient) CreateContainer(opts docker.CreateContainerOptions) (*docker.Container, error) { - return nil, errors.New("creating containers not supported on this platform") -} func (d *DaemonlessClient) PullImage(opts docker.PullImageOptions, searchPaths []string) error { return errors.New("pulling images not supported on this platform") } diff --git a/pkg/build/builder/dockerutil.go b/pkg/build/builder/dockerutil.go index b2dccd38df2..68819a0caae 100644 --- a/pkg/build/builder/dockerutil.go +++ b/pkg/build/builder/dockerutil.go @@ -31,7 +31,6 @@ type DockerClient interface { BuildImage(opts docker.BuildImageOptions) error PushImage(opts docker.PushImageOptions, auth docker.AuthConfiguration) (string, error) RemoveImage(name string) error - CreateContainer(opts docker.CreateContainerOptions) (*docker.Container, error) PullImage(opts docker.PullImageOptions, authSearchPaths []string) error RemoveContainer(opts docker.RemoveContainerOptions) error InspectImage(name string) (*docker.Image, error) diff --git a/pkg/build/builder/dockerutil_test.go b/pkg/build/builder/dockerutil_test.go index 2ae1c768fdc..5b84880fb7f 100644 --- a/pkg/build/builder/dockerutil_test.go +++ b/pkg/build/builder/dockerutil_test.go @@ -58,9 +58,6 @@ func (d *FakeDocker) RemoveImage(name string) error { } return nil } -func (d *FakeDocker) CreateContainer(opts docker.CreateContainerOptions) (*docker.Container, error) { - return &docker.Container{}, nil -} func (d *FakeDocker) PullImage(opts docker.PullImageOptions, searchPaths []string) error { if d.pullImageFunc != nil { return d.pullImageFunc(opts, searchPaths)