From 07e69e41730da3c690c2b8bd8e784392ebb30e1e Mon Sep 17 00:00:00 2001 From: Jakub Ciolek Date: Thu, 17 Aug 2023 17:50:54 +0200 Subject: [PATCH] feat(run): Enable running LLB-built docker images WIP This introduces a `dockerImage` package to run docker images containing a unikernel built with the LLB plugin. The hello world target runs successfully. A new package manager, "docker", has been added. If the target OCI image is missing, this package manager searches for it. There's an ongoing discussion about how to handle image references, especially when an image could be in both local/remote OCI storage and local docker storage. Currently, the process first checks the OCI storage and then Docker. In case of conflicts, the user might need to choose. To-Do: - Fix targets that don't build due to missing dependencies or artifact naming issues. - Provide architecture/platform info via image, as Docker doesn't support non-standard OS like qemu. - Consider support for remote docker registries. - Refactor some interfaces; we could make some of them smaller and avoid the "not implemented" errors. - Explore testing approaches for this functionality. Signed-off-by: Jakub Ciolek --- docker/docker.go | 281 +++++++++++++++++++++++++++++++++++++ docker/docker_manager.go | 177 +++++++++++++++++++++++ docker/docker_options.go | 11 ++ docker/init.go | 16 +++ go.mod | 1 + go.sum | 23 +++ internal/bootstrap/init.go | 2 + packmanager/umbrella.go | 2 +- 8 files changed, 512 insertions(+), 1 deletion(-) create mode 100644 docker/docker.go create mode 100644 docker/docker_manager.go create mode 100644 docker/docker_options.go create mode 100644 docker/init.go diff --git a/docker/docker.go b/docker/docker.go new file mode 100644 index 0000000000..6389a2d54d --- /dev/null +++ b/docker/docker.go @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors. +// Licensed under the BSD-3-Clause License (the "License"). +// You may not use this file except in compliance with the License. +package docker + +import ( + "archive/tar" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "os" + "path/filepath" + + "github.com/docker/docker/api/types" + "github.com/google/go-containerregistry/pkg/name" + "github.com/moby/moby/client" + + "kraftkit.sh/initrd" + "kraftkit.sh/kconfig" + "kraftkit.sh/oci" + "kraftkit.sh/pack" + "kraftkit.sh/unikraft" + "kraftkit.sh/unikraft/arch" + "kraftkit.sh/unikraft/plat" +) + +type DockerImage struct { + ID string + ref name.Reference + + // Embedded attributes which represent target.Target + arch arch.Architecture + plat plat.Platform + kconfig kconfig.KeyValueMap + kernel string + initrd *initrd.InitrdConfig + command []string +} + +// Type implements unikraft.Nameable +func (dockerImage *DockerImage) Type() unikraft.ComponentType { + return unikraft.ComponentTypeApp +} + +// Name implements unikraft.Nameable +func (dockerImage *DockerImage) Name() string { + return dockerImage.ref.Context().Name() +} + +// Version implements unikraft.Nameable +func (dockerImage *DockerImage) Version() string { + return dockerImage.ref.Identifier() +} + +// Metadata implements pack.Package +func (dockerImage *DockerImage) Metadata() any { + return nil +} + +// Push implements pack.Package +func (dockerImage *DockerImage) Push(ctx context.Context, opts ...pack.PushOption) error { + return errors.New("not implemented") +} + +func (dockerImage *DockerImage) Pull(ctx context.Context, opts ...pack.PullOption) error { + targetImageID := dockerImage.ID + + // Setup the pull options + popts, err := pack.NewPullOptions(opts...) + if err != nil { + return err + } + + // Connect to Docker client + dockerClient, err := client.NewClientWithOpts(client.FromEnv) + if err != nil { + return err + } + defer dockerClient.Close() + + // Check if image is in local Docker storage + images, err := dockerClient.ImageList(ctx, types.ImageListOptions{}) + if err != nil { + return err + } + + imageFound := false + for _, img := range images { + if img.ID == targetImageID { + imageFound = true + break + } + } + + if !imageFound { + return errors.New("target image not found in local Docker storage") + } + + if len(popts.Workdir()) > 0 { + // Unpack the image to the provided working directory + reader, err := dockerClient.ImageSave(context.Background(), []string{targetImageID}) + if err != nil { + return err + } + defer reader.Close() + + // Create a unique path to save the image tarball in the temp directory + file, err := os.CreateTemp(os.TempDir(), "docker_image_*.tar") + if err != nil { + return err + } + savePath := file.Name() + defer file.Close() + + // Copy the image data from reader to file + _, err = io.Copy(file, reader) + if err != nil { + return err + } + + if err := unpackTar(savePath, popts.Workdir()); err != nil { + return err + } + + if err := mergeLayersFromManifest(popts.Workdir()); err != nil { + return err + } + + // Set the kernel path + dockerImage.kernel = filepath.Join(popts.Workdir(), oci.WellKnownKernelPath) + } + + return nil +} + +type ImageManifest struct { + Layers []string `json:"Layers"` +} + +func mergeLayersFromManifest(workdir string) error { + // Read manifest.json to get the order of layers + manifestData, err := os.ReadFile(filepath.Join(workdir, "manifest.json")) + if err != nil { + return err + } + + var manifests []ImageManifest + if err := json.Unmarshal(manifestData, &manifests); err != nil { + return err + } + + for _, layerPath := range manifests[0].Layers { + layerTarPath := filepath.Join(workdir, layerPath) + if err := unpackTar(layerTarPath, workdir); err != nil { + return err + } + } + return nil +} + +func unpackTar(src, dest string) error { + tarFile, err := os.Open(src) + if err != nil { + return err + } + defer tarFile.Close() + + tr := tar.NewReader(tarFile) + for { + header, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + return err + } + + targetPath := filepath.Join(dest, header.Name) + switch header.Typeflag { + case tar.TypeDir: + if err := os.MkdirAll(targetPath, header.FileInfo().Mode()); err != nil { + return err + } + case tar.TypeReg: + f, err := os.OpenFile(targetPath, os.O_CREATE|os.O_RDWR, header.FileInfo().Mode()) + if err != nil { + return err + } + if _, err := io.Copy(f, tr); err != nil { + f.Close() + return err + } + f.Close() + } + } + return nil +} + +// Pull implements pack.Package +func (dockerImage *DockerImage) Format() pack.PackageFormat { + return DockerFormat +} + +// Source implements unikraft.component.Component +func (dockerImage *DockerImage) Source() string { + return "" +} + +// Path implements unikraft.component.Component +func (dockerImage *DockerImage) Path() string { + return "" +} + +// KConfigTree implements unikraft.component.Component +func (dockerImage DockerImage) KConfigTree(context.Context, ...*kconfig.KeyValue) (*kconfig.KConfigFile, error) { + return nil, fmt.Errorf("not implemented: docker.dockerImage.KConfigTree") +} + +// KConfig implements unikraft.component.Component +func (dockerImage DockerImage) KConfig() kconfig.KeyValueMap { + return dockerImage.kconfig +} + +// PrintInfo implements unikraft.component.Component +func (dockerImage DockerImage) PrintInfo(context.Context) string { + return "not implemented: docker.dockerImage.PrintInfo" +} + +// Architecture implements unikraft.target.Target +func (dockerImage DockerImage) Architecture() arch.Architecture { + return dockerImage.arch +} + +// Platform implements unikraft.target.Target +func (dockerImage DockerImage) Platform() plat.Platform { + return dockerImage.plat +} + +// Kernel implements unikraft.target.Target +func (dockerImage DockerImage) Kernel() string { + return dockerImage.kernel +} + +// KernelDbg implements unikraft.target.Target +func (dockerImage DockerImage) KernelDbg() string { + return dockerImage.kernel +} + +// Initrd implements unikraft.target.Target +func (dockerImage DockerImage) Initrd() *initrd.InitrdConfig { + return dockerImage.initrd +} + +// Command implements unikraft.target.Target +func (dockerImage DockerImage) Command() []string { + if len(dockerImage.command) == 0 { + return []string{"--"} + } + + return dockerImage.command +} + +// ConfigFilename implements unikraft.target.Target +func (dockerImage DockerImage) ConfigFilename() string { + return "" +} + +// MarshalYAML implements unikraft.target.Target (yaml.Marshaler) +func (dockerImage *DockerImage) MarshalYAML() (interface{}, error) { + if dockerImage == nil { + return nil, nil + } + + return map[string]interface{}{ + "architecture": dockerImage.arch.Name(), + "platform": dockerImage.plat.Name(), + }, nil +} diff --git a/docker/docker_manager.go b/docker/docker_manager.go new file mode 100644 index 0000000000..72e3137d67 --- /dev/null +++ b/docker/docker_manager.go @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors. +// Licensed under the BSD-3-Clause License (the "License"). +// You may not use this file except in compliance with the License. +package docker + +import ( + "context" + "errors" + "fmt" + + "github.com/docker/docker/api/types" + "github.com/moby/moby/client" + + "kraftkit.sh/pack" + "kraftkit.sh/packmanager" + "kraftkit.sh/unikraft/arch" + "kraftkit.sh/unikraft/component" + "kraftkit.sh/unikraft/plat" + "kraftkit.sh/unikraft/target" +) + +type dockerManager struct { + registries []string +} + +const DockerFormat pack.PackageFormat = "docker" + +// NewDockerManager instantiates a new package manager based on local docker images. +func NewDockerManager(ctx context.Context, opts ...any) (packmanager.PackageManager, error) { + manager := dockerManager{} + + for _, mopt := range opts { + opt, ok := mopt.(dockerManagerOption) + if !ok { + return nil, fmt.Errorf("cannot cast docker Manager option") + } + + if err := opt(ctx, &manager); err != nil { + return nil, err + } + } + + return &manager, nil +} + +// Update implements packmanager.PackageManager +func (manager *dockerManager) Update(ctx context.Context) error { + return nil +} + +// Pack implements packmanager.PackageManager +func (manager *dockerManager) Pack(ctx context.Context, entity component.Component, opts ...packmanager.PackOption) ([]pack.Package, error) { + _, ok := entity.(target.Target) + if !ok { + return nil, fmt.Errorf("entity is not Unikraft target") + } + + return nil, fmt.Errorf("not implemented: docker.manager.Pack") +} + +// Unpack implements packmanager.PackageManager +func (manager *dockerManager) Unpack(ctx context.Context, entity pack.Package, opts ...packmanager.UnpackOption) ([]component.Component, error) { + return nil, fmt.Errorf("not implemented: docker.manager.Unpack") +} + +// Catalog implements packmanager.PackageManager +func (manager *dockerManager) Catalog(ctx context.Context, qopts ...packmanager.QueryOption) ([]pack.Package, error) { + // isolate the name of the image + query := packmanager.NewQuery(qopts...) + + // Connect to Docker client + dockerClient, err := client.NewClientWithOpts(client.FromEnv) + if err != nil { + return nil, err + } + defer dockerClient.Close() + + // Check if image is in local Docker storage + images, err := dockerClient.ImageList(ctx, types.ImageListOptions{}) + if err != nil { + return nil, err + } + + for _, i := range images { + for _, t := range i.RepoTags { + if t == query.Name() { + // TODO(jake-ciolek): right now we default to qemu/x86_64 + // figure out what's the best way of passing this in the image. + arch, err := arch.NewArchitectureFromSchema("x86_64") + if err != nil { + return nil, err + } + plat, err := plat.NewPlatformFromOptions(plat.WithName("qemu")) + if err != nil { + return nil, err + } + return []pack.Package{&DockerImage{ + ID: i.ID, + arch: arch, + plat: plat, + }}, nil + } + } + } + + return nil, errors.New("unable to find the requested image in local docker storage") +} + +// SetSources implements packmanager.PackageManager +func (manager *dockerManager) SetSources(_ context.Context, sources ...string) error { + manager.registries = sources + return nil +} + +// AddSource implements packmanager.PackageManager +func (manager *dockerManager) AddSource(ctx context.Context, source string) error { + if manager.registries == nil { + manager.registries = make([]string, 0) + } + + manager.registries = append(manager.registries, source) + + return nil +} + +// RemoveSource implements packmanager.PackageManager +func (manager *dockerManager) RemoveSource(ctx context.Context, source string) error { + for i, needle := range manager.registries { + if needle == source { + ret := make([]string, 0) + ret = append(ret, manager.registries[:i]...) + manager.registries = append(ret, manager.registries[i+1:]...) + break + } + } + + return nil +} + +// IsCompatible implements packmanager.PackageManager +func (manager *dockerManager) IsCompatible(ctx context.Context, source string, qopts ...packmanager.QueryOption) (packmanager.PackageManager, bool, error) { + // Check if an image with given name exists in local docker image storage + + // Connect to Docker client + dockerClient, err := client.NewClientWithOpts(client.FromEnv) + if err != nil { + return nil, false, err + } + defer dockerClient.Close() + + // Check if image is in local Docker storage + images, err := dockerClient.ImageList(ctx, types.ImageListOptions{}) + if err != nil { + return nil, false, err + } + + for _, i := range images { + for _, t := range i.RepoTags { + if t == source { + return manager, true, nil + } + } + } + + return nil, false, nil +} + +// From implements packmanager.PackageManager +func (manager *dockerManager) From(pack.PackageFormat) (packmanager.PackageManager, error) { + return nil, fmt.Errorf("not possible: docker.manager.From") +} + +// Format implements packmanager.PackageManager +func (manager *dockerManager) Format() pack.PackageFormat { + return DockerFormat +} diff --git a/docker/docker_options.go b/docker/docker_options.go new file mode 100644 index 0000000000..5c00b0d096 --- /dev/null +++ b/docker/docker_options.go @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors. +// Licensed under the BSD-3-Clause License (the "License"). +// You may not use this file except in compliance with the License. +package docker + +import ( + "context" +) + +type dockerManagerOption func(context.Context, *dockerManager) error diff --git a/docker/init.go b/docker/init.go new file mode 100644 index 0000000000..6554364dc4 --- /dev/null +++ b/docker/init.go @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors. +// Licensed under the BSD-3-Clause License (the "License"). +// You may not use this file except in compliance with the License. +package docker + +import "kraftkit.sh/packmanager" + +func RegisterPackageManager() func(u *packmanager.UmbrellaManager) error { + return func(u *packmanager.UmbrellaManager) error { + return u.RegisterPackageManager( + DockerFormat, + NewDockerManager, + ) + } +} diff --git a/go.mod b/go.mod index bce95a3a43..d8548e1fae 100644 --- a/go.mod +++ b/go.mod @@ -41,6 +41,7 @@ require ( github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/mapstructure v1.5.0 + github.com/moby/moby v24.0.5+incompatible github.com/muesli/reflow v0.3.0 github.com/muesli/termenv v0.15.2 github.com/onsi/ginkgo/v2 v2.11.0 diff --git a/go.sum b/go.sum index 6a9ac86c31..a56a9cdbc6 100644 --- a/go.sum +++ b/go.sum @@ -75,6 +75,7 @@ github.com/Microsoft/hcsshim v0.10.0-rc.8/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCzt github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= @@ -96,6 +97,7 @@ github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= @@ -105,6 +107,7 @@ github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aymanbagabas/go-osc52 v1.0.3/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= +github.com/aymanbagabas/go-osc52 v1.2.1/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0= @@ -146,6 +149,7 @@ github.com/charmbracelet/lipgloss v0.6.0/go.mod h1:tHh2wr34xcHjC2HCXIlGSG1jaDF0S github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E= github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c= github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= +github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -374,6 +378,7 @@ github.com/erikgeiser/promptkit v0.8.0/go.mod h1:QxyFbCrrj20PyvV5b+ckWPozbgX11s0 github.com/erikh/ping v0.0.0-20141209185752-d731d249e12a h1:xYb+yyQiRJ/j9MeLxAxY7y5zxlKJRsuJrL9aIjvm6ys= github.com/erikh/ping v0.0.0-20141209185752-d731d249e12a/go.mod h1:m0Cg23THf2kNTu+CtJHoq2IjqNQke24ZV8GQlGDfQf4= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= @@ -520,6 +525,7 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -544,9 +550,11 @@ github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/flatbuffers v23.1.21+incompatible h1:bUqzx/MXCDxuS0hRJL2EfjyZL3uQrPbMocUa8zGqsTA= github.com/google/flatbuffers v23.1.21+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -600,16 +608,19 @@ github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.11.1/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= @@ -642,6 +653,7 @@ github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -684,6 +696,7 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kubescape/go-git-url v0.0.25 h1:i7SSSC1+1m/Dg+4LV3erp0YklnWj1Z0cVlRxCT3Zy/0= github.com/kubescape/go-git-url v0.0.25/go.mod h1:IbVT7Wsxlghsa+YxI5KOx4k9VQJaa3z0kTaQz5D3nKM= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= @@ -743,6 +756,9 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +github.com/moby/moby v24.0.5+incompatible h1:uUbydai/Y9J7Ybt+lFI3zBdnsMYXnXE9vEcfZDoEE8Q= +github.com/moby/moby v24.0.5+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= @@ -762,6 +778,7 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho= github.com/muesli/ansi v0.0.0-20221106050444-61f0cd9a192a h1:jlDOeO5TU0pYlbc/y6PFguab5IjANI0Knrpg3u/ton4= @@ -912,6 +929,7 @@ github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= +github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/shirou/gopsutil/v3 v3.23.6 h1:5y46WPI9QBKBbK7EEccUPNXpJpNrvPuTD0O2zHEHT08= @@ -939,6 +957,7 @@ github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2Iqp github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -961,6 +980,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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= @@ -1066,7 +1086,10 @@ go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyK go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/internal/bootstrap/init.go b/internal/bootstrap/init.go index 56335b3afb..814fd867df 100644 --- a/internal/bootstrap/init.go +++ b/internal/bootstrap/init.go @@ -10,6 +10,7 @@ import ( "context" "kraftkit.sh/api" + "kraftkit.sh/docker" "kraftkit.sh/machine/qemu" "kraftkit.sh/manifest" "kraftkit.sh/oci" @@ -44,6 +45,7 @@ func registerPackageManagers(ctx context.Context) error { managerConstructors := []func(u *packmanager.UmbrellaManager) error{ oci.RegisterPackageManager(), manifest.RegisterPackageManager(), + docker.RegisterPackageManager(), } return packmanager.InitUmbrellaManager(ctx, managerConstructors) diff --git a/packmanager/umbrella.go b/packmanager/umbrella.go index 3fd1c0a8c1..ee085c36d3 100644 --- a/packmanager/umbrella.go +++ b/packmanager/umbrella.go @@ -268,7 +268,7 @@ func NewUmbrellaManager(ctx context.Context, constructors []func(*UmbrellaManage log.G(ctx). WithField("format", format). Debugf("could not initialize package manager: %v", err) - continue + return nil, err } if format, ok := u.packageManagers[manager.Format()]; ok {