From 617e8773b3707440613244222bfe7bf1fd937b76 Mon Sep 17 00:00:00 2001 From: YAO Date: Mon, 5 Sep 2022 13:37:09 +0800 Subject: [PATCH] fix sealos will not use local images if there is a newer one remote (#1689) [fix]only support buildah sdk Signed-off-by: yyf1986 <191557539@qq.com> * [fix]only support buildah sdk,delete binary support code Signed-off-by: yyf1986 <191557539@qq.com> Signed-off-by: yyf1986 <191557539@qq.com> Co-authored-by: yyf1986 <191557539@qq.com> --- pkg/image/binary/cluster.go | 112 -------------------- pkg/image/binary/image.go | 159 ---------------------------- pkg/image/binary/registry.go | 51 --------- pkg/image/buildah.go | 13 ++- pkg/image/buildah/registry/pull.go | 3 +- pkg/image/buildah/registry/refer.go | 35 +++++- pkg/image/service.go | 22 ++-- 7 files changed, 53 insertions(+), 342 deletions(-) delete mode 100644 pkg/image/binary/cluster.go delete mode 100644 pkg/image/binary/image.go delete mode 100644 pkg/image/binary/registry.go diff --git a/pkg/image/binary/cluster.go b/pkg/image/binary/cluster.go deleted file mode 100644 index 5a56e19263a..00000000000 --- a/pkg/image/binary/cluster.go +++ /dev/null @@ -1,112 +0,0 @@ -/* -Copyright 2022 cuisongliu@qq.com. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package binary - -import ( - "fmt" - - "github.com/labring/sealos/pkg/utils/exec" - "github.com/labring/sealos/pkg/utils/logger" - - "github.com/pkg/errors" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/util/json" - - "github.com/labring/sealos/pkg/image/types" -) - -type ClusterService struct { -} - -func (s *ClusterService) Create(name string, image string) (*types.ClusterManifest, error) { - if err := s.Delete(name); err != nil { - return nil, err - } - - cmd := fmt.Sprintf("buildah from --pull=never --name %s %s && buildah mount %s ", name, image, name) - if err := exec.Cmd("bash", "-c", cmd); err != nil { - return nil, err - } - return s.Inspect(name) -} - -func (s *ClusterService) Delete(name string) error { - infos, err := s.List() - if err != nil { - return err - } - logger.Debug("current container names is: %v", name) - for _, info := range infos { - if info.Containername == name { - cmd := fmt.Sprintf("buildah unmount %s && buildah rm %s", info.Containername, info.Containername) - if err = exec.Cmd("bash", "-c", cmd); err != nil { - return err - } - } - } - return nil -} - -func (*ClusterService) Inspect(name string) (*types.ClusterManifest, error) { - data := exec.BashEval(fmt.Sprintf("buildah inspect %s", name)) - manifest, err := inspectContainer(data) - if err != nil { - return nil, err - } - return manifest, nil -} - -func (*ClusterService) List() ([]types.ClusterInfo, error) { - data := exec.BashEval("buildah containers --json") - return listContainer(data) -} - -func inspectContainer(data string) (*types.ClusterManifest, error) { - if data != "" { - var outStruct map[string]interface{} - err := json.Unmarshal([]byte(data), &outStruct) - if err != nil { - return nil, errors.Wrap(err, "decode out json from container inspect failed") - } - container, _, _ := unstructured.NestedString(outStruct, "Container") - containerID, _, _ := unstructured.NestedString(outStruct, "ContainerID") - mountPoint, _, _ := unstructured.NestedString(outStruct, "MountPoint") - manifest := &types.ClusterManifest{ - Container: container, - ContainerID: containerID, - MountPoint: mountPoint, - } - return manifest, nil - } - return nil, errors.New("inspect output is empty") -} - -func listContainer(data string) ([]types.ClusterInfo, error) { - if data != "" { - var outStruct []types.ClusterInfo - err := json.Unmarshal([]byte(data), &outStruct) - if err != nil { - return nil, errors.Wrap(err, "decode out json from list container failed") - } - return outStruct, nil - } - return nil, errors.New("containers output is empty") -} - -func NewClusterService() (types.ClusterService, error) { - return &ClusterService{}, nil -} diff --git a/pkg/image/binary/image.go b/pkg/image/binary/image.go deleted file mode 100644 index e286ec968b8..00000000000 --- a/pkg/image/binary/image.go +++ /dev/null @@ -1,159 +0,0 @@ -/* -Copyright 2022 cuisongliu@qq.com. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package binary - -import ( - "context" - "fmt" - "os" - "path" - "path/filepath" - "strings" - - "github.com/labring/sealos/pkg/constants" - "github.com/labring/sealos/pkg/utils/exec" - fileutil "github.com/labring/sealos/pkg/utils/file" - json2 "github.com/labring/sealos/pkg/utils/json" - "github.com/labring/sealos/pkg/utils/logger" - - v1 "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/util/json" - - "github.com/labring/sealos/pkg/buildimage" - "github.com/labring/sealos/pkg/image/types" - "github.com/labring/sealos/pkg/registry" -) - -// ImageService is the default service, which is used for image pull/push -type ImageService struct { -} - -func (d *ImageService) Tag(src, dst string) error { - return exec.Cmd("bash", "-c", fmt.Sprintf("buildah tag %s %s", src, dst)) -} - -func (d *ImageService) Save(imageName, archiveName string) error { - localDir := filepath.Dir(archiveName) - if !fileutil.IsExist(localDir) { - return errors.New("archive dir is not exist") - } - return exec.Cmd("bash", "-c", fmt.Sprintf("buildah push %s %s:%s:%s", imageName, types.DefaultTransport, archiveName, imageName)) -} - -func (d *ImageService) Load(archiveName string) error { - if !fileutil.IsExist(archiveName) { - return errors.New("archive file is not exist") - } - return exec.Cmd("bash", "-c", fmt.Sprintf("buildah pull %s:%s", types.DefaultTransport, archiveName)) -} - -func (d *ImageService) Remove(force bool, images ...string) error { - var forceCMD string - if force { - forceCMD = "-f" - } - cmd := fmt.Sprintf("buildah rmi %s %s", forceCMD, strings.Join(images, " ")) - return exec.Cmd("bash", "-c", cmd) -} - -func (d *ImageService) Inspect(images ...string) (types.ImageListOCIV1, error) { - var imageList types.ImageListOCIV1 - for _, image := range images { - data := exec.BashEval(fmt.Sprintf("buildah inspect %s", image)) - ociImage, err := inspectImage(data) - if err != nil { - return nil, err - } - imageList = append(imageList, *ociImage) - } - - return imageList, nil -} - -func inspectImage(data string) (*v1.Image, error) { - if data != "" { - var outStruct map[string]interface{} - err := json.Unmarshal([]byte(data), &outStruct) - if err != nil { - return nil, errors.Wrap(err, "decode out json from image inspect failed") - } - imageData, _, err := unstructured.NestedFieldCopy(outStruct, "OCIv1") - if err != nil { - return nil, errors.Wrap(err, "decode out json from OCIv1 object failed") - } - img := &v1.Image{} - err = json2.Convert(imageData, img) - if err != nil { - return nil, errors.Wrap(err, "decode OCIv1 to v1.Image failed") - } - return img, nil - } - return nil, errors.New("inspect output is empty") -} - -func (d *ImageService) Build(options *types.BuildOptions, contextDir, imageName string) error { - images, err := buildimage.List(contextDir) - if err != nil { - return err - } - - auths, err := registry.GetAuthInfo() - if err != nil { - return err - } - is := registry.NewImageSaver(context.Background(), options.MaxPullProcs, auths, options.BasicAuth) - platform := strings.Split(options.Platform, "/") - var platformVar v1.Platform - if len(platform) > 2 { - platformVar = v1.Platform{ - Architecture: platform[1], - OS: platform[0], - Variant: platform[2], - } - } else { - platformVar = v1.Platform{ - Architecture: platform[1], - OS: platform[0], - } - } - logger.Info("pull images %v for platform is %s", images, strings.Join([]string{platformVar.OS, platformVar.Architecture}, "/")) - - images, err = is.SaveImages(images, path.Join(contextDir, constants.RegistryDirName), platformVar) - if err != nil { - return errors.Wrap(err, "save images failed in this context") - } - logger.Info("output images %v for platform is %s", images, strings.Join([]string{platformVar.OS, platformVar.Architecture}, "/")) - options.Tag = imageName - cmd := fmt.Sprintf("buildah build %s %s", options.String(), contextDir) - return exec.Cmd("bash", "-c", cmd) -} - -func (d *ImageService) Prune() error { - return exec.Cmd("bash", "-c", "buildah rmi --prune") -} - -func (d *ImageService) ListImages() error { - data, err := exec.RunBashCmd("buildah images") - _, _ = os.Stdout.Write([]byte(data)) - return err -} - -func NewImageService() (types.ImageService, error) { - return &ImageService{}, nil -} diff --git a/pkg/image/binary/registry.go b/pkg/image/binary/registry.go deleted file mode 100644 index 8152797c54f..00000000000 --- a/pkg/image/binary/registry.go +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright 2022 cuisongliu@qq.com. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package binary - -import ( - "fmt" - - "github.com/labring/sealos/pkg/utils/exec" - - "github.com/labring/sealos/pkg/image/types" -) - -type RegistryService struct { -} - -func (*RegistryService) Login(domain, username, passwd string) error { - return exec.Cmd("bash", "-c", fmt.Sprintf("buildah login --tls-verify=false --username %s --password %s %s", username, passwd, domain)) -} -func (*RegistryService) Logout(domain string) error { - return exec.Cmd("bash", "-c", fmt.Sprintf("buildah logout %s", domain)) -} -func (*RegistryService) Pull(images ...string) error { - for _, image := range images { - if err := exec.Cmd("bash", "-c", fmt.Sprintf("buildah pull --tls-verify=false %s", image)); err != nil { - return err - } - } - return nil -} - -func (*RegistryService) Push(image string) error { - return exec.Cmd("bash", "-c", fmt.Sprintf("buildah push --tls-verify=false %s", image)) -} - -func NewRegistryService() (types.RegistryService, error) { - return &RegistryService{}, nil -} diff --git a/pkg/image/buildah.go b/pkg/image/buildah.go index 303ca834011..412c3141dd3 100644 --- a/pkg/image/buildah.go +++ b/pkg/image/buildah.go @@ -19,25 +19,24 @@ package image import ( "github.com/pkg/errors" - "github.com/labring/sealos/pkg/utils/exec" fileutil "github.com/labring/sealos/pkg/utils/file" ) -func initBuildah() (bool, error) { +func initBuildah() error { err := buildahPolicySync() if err != nil { - return false, errors.New("create policy.json failed") + return errors.New("create policy.json failed") } err = buildahStorageSync() if err != nil { - return false, errors.New("create storage config failed") + return errors.New("create storage config failed") } err = buildahRegistrySync() if err != nil { - return false, errors.New("create registry config failed") + return errors.New("create registry config failed") } - _, ok := exec.CheckCmdIsExist("buildah") - return ok, nil + //_, ok := exec.CheckCmdIsExist("buildah") + return nil } func buildahPolicySync() error { diff --git a/pkg/image/buildah/registry/pull.go b/pkg/image/buildah/registry/pull.go index d099a0d306e..42a4cb14997 100644 --- a/pkg/image/buildah/registry/pull.go +++ b/pkg/image/buildah/registry/pull.go @@ -24,6 +24,7 @@ import ( "github.com/containers/buildah" "github.com/containers/buildah/define" + "github.com/containers/buildah/pkg/parse" "github.com/containers/common/pkg/auth" "github.com/pkg/errors" ) @@ -64,7 +65,7 @@ func (*Service) Pull(images ...string) error { return err } - systemContext, _ := getSystemContext(opt.tlsVerify) + systemContext, _ := parse.SystemContextFromOptions(getCmdFlag()) decConfig, err := getDecryptConfig(opt.decryptionKeys) if err != nil { diff --git a/pkg/image/buildah/registry/refer.go b/pkg/image/buildah/registry/refer.go index c215b511d34..85b58f399b1 100644 --- a/pkg/image/buildah/registry/refer.go +++ b/pkg/image/buildah/registry/refer.go @@ -42,6 +42,7 @@ import ( "github.com/containers/storage/pkg/unshare" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" + "github.com/spf13/cobra" ) func getDecryptConfig(decryptionKeys []string) (*encconfig.DecryptConfig, error) { @@ -189,12 +190,12 @@ func newGlobalOptions() *types.GlobalBuildahFlags { } func manifestPush(systemContext *ct.SystemContext, store storage.Store, listImageSpec, destSpec string, opts types.PushOptions) error { - runtime, err := libimage.RuntimeFromStore(store, &libimage.RuntimeOptions{SystemContext: systemContext}) + runtimeFromStore, err := libimage.RuntimeFromStore(store, &libimage.RuntimeOptions{SystemContext: systemContext}) if err != nil { return err } - manifestList, err := runtime.LookupManifestList(listImageSpec) + manifestList, err := runtimeFromStore.LookupManifestList(listImageSpec) if err != nil { return err } @@ -323,3 +324,33 @@ type loginReply struct { getLogin bool tlsVerify bool } + +func getCmdFlag() *cobra.Command { + var opts pullOptions + pullCommand := &cobra.Command{} + + flags := pullCommand.Flags() + flags.SetInterspersed(false) + flags.BoolVarP(&opts.allTags, "all-tags", "a", false, "download all tagged images in the repository") + flags.StringVar(&opts.authfile, "authfile", auth.GetDefaultAuthFile(), "path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") + flags.StringVar(&opts.blobCache, "blob-cache", "", "store copies of pulled image blobs in the specified directory") + flags.StringVar(&opts.certDir, "cert-dir", "", "use certificates at the specified path to access the registry") + flags.StringVar(&opts.creds, "creds", "", "use `[username[:password]]` for accessing the registry") + flags.StringVar(&opts.pullPolicy, "policy", "missing", "missing, always, or never.") + flags.BoolVarP(&opts.removeSignatures, "remove-signatures", "", false, "don't copy signatures when pulling image") + flags.StringVar(&opts.signaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)") + flags.StringSliceVar(&opts.decryptionKeys, "decryption-key", nil, "key needed to decrypt the image") + if err := flags.MarkHidden("signature-policy"); err != nil { + panic(fmt.Sprintf("error marking signature-policy as hidden: %v", err)) + } + flags.BoolVarP(&opts.quiet, "quiet", "q", false, "don't output progress information when pulling images") + flags.String("os", runtime.GOOS, "prefer `OS` instead of the running OS for choosing images") + flags.String("arch", runtime.GOARCH, "prefer `ARCH` instead of the architecture of the machine for choosing images") + flags.StringSlice("platform", []string{parse.DefaultPlatform()}, "prefer OS/ARCH instead of the current operating system and architecture for choosing images") + flags.String("variant", "", "override the `variant` of the specified image") + flags.BoolVar(&opts.tlsVerify, "tls-verify", false, "require HTTPS and verify certificates when accessing the registry. TLS verification cannot be used when talking to an insecure registry.") + if err := flags.MarkHidden("blob-cache"); err != nil { + panic(fmt.Sprintf("error marking blob-cache as hidden: %v", err)) + } + return pullCommand +} diff --git a/pkg/image/service.go b/pkg/image/service.go index 757cbb8009d..1a99ab30ca6 100644 --- a/pkg/image/service.go +++ b/pkg/image/service.go @@ -17,7 +17,6 @@ limitations under the License. package image import ( - "github.com/labring/sealos/pkg/image/binary" buildah_cluster "github.com/labring/sealos/pkg/image/buildah/cluster" buildah_image "github.com/labring/sealos/pkg/image/buildah/image" "github.com/labring/sealos/pkg/image/buildah/registry" @@ -25,22 +24,25 @@ import ( ) func NewClusterService() (types.ClusterService, error) { - if ok, err := initBuildah(); err == nil && ok { - return binary.NewClusterService() + err := initBuildah() + if err == nil { + return buildah_cluster.NewClusterService() } - return buildah_cluster.NewClusterService() + return nil, err } func NewRegistryService() (types.RegistryService, error) { - if ok, err := initBuildah(); err == nil && ok { - return binary.NewRegistryService() + err := initBuildah() + if err == nil { + return registry.NewRegistryService() } - return registry.NewRegistryService() + return nil, err } func NewImageService() (types.ImageService, error) { - if ok, err := initBuildah(); err == nil && ok { - return binary.NewImageService() + err := initBuildah() + if err == nil { + return buildah_image.NewImageService() } - return buildah_image.NewImageService() + return nil, err }