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 {