From b9c37c7c927e20a9a0640dca217bb45b887f43d8 Mon Sep 17 00:00:00 2001 From: Maxwell <144507225+maxwell-can-not-fly@users.noreply.github.com> Date: Mon, 29 Apr 2024 22:54:57 +0800 Subject: [PATCH] pull command support multiples platforms Signed-off-by: Maxwell <144507225+maxwell-can-not-fly@users.noreply.github.com> --- Makefile | 3 ++ build/kubefile/parser/image_engine_test.go | 5 +++ cmd/sealer/cmd/image/pull.go | 49 +++++++++++++++++++--- pkg/imageengine/buildah/tag.go | 11 +++++ pkg/imageengine/interface.go | 2 + 5 files changed, 64 insertions(+), 6 deletions(-) mode change 100644 => 100755 Makefile diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 index 399df64f453..b6e016e506f --- a/Makefile +++ b/Makefile @@ -53,6 +53,9 @@ linux-arm64: clean build-in-docker: docker run --rm -v ${PWD}:/usr/src/sealer -w /usr/src/sealer registry.cn-qingdao.aliyuncs.com/sealer-io/sealer-build:v1 make linux +podman-build: + sudo podman run --rm -v $(shell pwd):/usr/src/sealer -w /usr/src/sealer registry.cn-qingdao.aliyuncs.com/sealer-io/sealer-build:v1 make linux + ## clean: Remove all files that are created by building. .PHONY: clean clean: diff --git a/build/kubefile/parser/image_engine_test.go b/build/kubefile/parser/image_engine_test.go index d93e41649d1..0bc432bbd6d 100644 --- a/build/kubefile/parser/image_engine_test.go +++ b/build/kubefile/parser/image_engine_test.go @@ -108,6 +108,11 @@ func (testImageEngine) Tag(opts *options.TagOptions) error { panic("implement me") } +func (testImageEngine) Untag(name string) error { + //TODO implement me + panic("implement me") +} + func (testImageEngine) CreateWorkingContainer(opts *options.BuildRootfsOptions) (string, error) { //TODO implement me panic("implement me") diff --git a/cmd/sealer/cmd/image/pull.go b/cmd/sealer/cmd/image/pull.go index 235dc5f9dd3..0c7e6b5e3f5 100644 --- a/cmd/sealer/cmd/image/pull.go +++ b/cmd/sealer/cmd/image/pull.go @@ -27,11 +27,14 @@ import ( var pullOpts *options.PullOptions +var pullPlatforms []string + var longNewPullCmdDescription = `` var exampleForPullCmd = ` sealer pull docker.io/sealerio/kubernetes:v1-22-15-sealerio-2 sealer pull docker.io/sealerio/kubernetes:v1-22-15-sealerio-2 --platform linux/amd64 + sealer pull docker.io/sealerio/kubernetes:v1-22-15-sealerio-2 --platform linux/amd64,linux/arm64 ` // NewPullCmd pullCmd represents the pull command @@ -48,17 +51,51 @@ func NewPullCmd() *cobra.Command { return err } pullOpts.Image = args[0] - imageID, err := engine.Pull(pullOpts) - if err != nil { - return fmt.Errorf("failed to pull image: %s: %v", pullOpts.Image, err) + + if len(pullPlatforms) == 0 { + pullPlatforms = []string{parse.DefaultPlatform()} + } + + if len(pullPlatforms) == 1 { + pullOpts.Platform = pullPlatforms[0] + imageID, err := engine.Pull(pullOpts) + if err != nil { + return fmt.Errorf("failed to pull image: %s: %w", pullOpts.Image, err) + } + + logrus.Infof("successful pull %s with the image ID: %s", pullOpts.Image, imageID) + return err } - logrus.Infof("successful pull %s with the image ID: %s", pullOpts.Image, imageID) - return err + imageIDList := make([]string, 0) + for _, p := range pullPlatforms { + pullOpts.Platform = p + imageID, err := engine.Pull(pullOpts) + if err != nil { + return fmt.Errorf("failed to pull image: %s for %s: %w", pullOpts.Image, p, err) + } + imageIDList = append(imageIDList, imageID) + + if err := engine.Untag(args[0]); err != nil { + return fmt.Errorf("failed to pull image: %s for %s: untag: %w", pullOpts.Image, p, err) + } + } + + if _, err := engine.CreateManifest(args[0], &options.ManifestCreateOpts{}); err != nil { + return fmt.Errorf("failed to pull image: %s: create image list: %w", pullOpts.Image, err) + } + + if err := engine.AddToManifest(args[0], imageIDList, &options.ManifestAddOpts{All: true}); err != nil { + return fmt.Errorf("failed to pull image: %s: fill image list: %w", pullOpts.Image, err) + } + + return nil }, } + pullOpts = &options.PullOptions{} - pullCmd.Flags().StringVar(&pullOpts.Platform, "platform", parse.DefaultPlatform(), "prefer OS/ARCH instead of the current operating system and architecture for choosing images") + pullCmd.Flags().StringSliceVar(&pullPlatforms, "platform", []string{parse.DefaultPlatform()}, "prefer OS/ARCH instead of the current"+ + " operating system and architecture for choosing images, use a comma spereated list to pull muiltple platforms") pullCmd.Flags().StringVar(&pullOpts.PullPolicy, "policy", "always", "missing, always, ifnewer or never.") pullCmd.Flags().BoolVarP(&pullOpts.Quiet, "quiet", "q", false, "don't output progress information when pulling images") pullCmd.Flags().BoolVar(&pullOpts.SkipTLSVerify, "skip-tls-verify", false, "default is requiring HTTPS and verify certificates when accessing the registry.") diff --git a/pkg/imageengine/buildah/tag.go b/pkg/imageengine/buildah/tag.go index cf98dc4fcda..af13ec95c7e 100644 --- a/pkg/imageengine/buildah/tag.go +++ b/pkg/imageengine/buildah/tag.go @@ -46,3 +46,14 @@ func (engine *Engine) Tag(opts *options.TagOptions) error { return nil } + +func (engine *Engine) Untag(name string) error { + + lookupOptions := &libimage.LookupImageOptions{ManifestList: true} + existImage, _, err := engine.ImageRuntime().LookupImage(name, lookupOptions) + if err != nil { + return fmt.Errorf("failed to lookup image: %v", err) + } + + return existImage.Untag(name) +} diff --git a/pkg/imageengine/interface.go b/pkg/imageengine/interface.go index eb04ae9311e..aca6b5982f7 100644 --- a/pkg/imageengine/interface.go +++ b/pkg/imageengine/interface.go @@ -57,6 +57,8 @@ type Interface interface { Tag(opts *options.TagOptions) error + Untag(name string) error + Inspect(opts *options.InspectOptions) (*v1.ImageSpec, error) LookupManifest(name string) (*libimage.ManifestList, error)