diff --git a/cmd/extension.go b/cmd/extension.go index 6d04e6c..166dcd3 100644 --- a/cmd/extension.go +++ b/cmd/extension.go @@ -17,72 +17,75 @@ limitations under the License. package cmd import ( - "fmt" - "io" - "path/filepath" - "runtime" - "time" + "fmt" + "io" + "path/filepath" + "runtime" + "time" - "github.com/linuxsuren/api-testing/pkg/downloader" - "github.com/spf13/cobra" + "github.com/linuxsuren/api-testing/pkg/downloader" + "github.com/spf13/cobra" ) type extensionOption struct { - ociDownloader downloader.PlatformAwareOCIDownloader - output string - registry string - tag string - os string - arch string - timeout time.Duration - imagePrefix string + ociDownloader downloader.PlatformAwareOCIDownloader + output string + registry string + kind string + tag string + os string + arch string + timeout time.Duration + imagePrefix string } func createExtensionCommand(ociDownloader downloader.PlatformAwareOCIDownloader) (c *cobra.Command) { - opt := &extensionOption{ - ociDownloader: ociDownloader, - } - c = &cobra.Command{ - Use: "extension", - Short: "Download extension binary files", - Long: "Download the store extension files", - Args: cobra.MinimumNArgs(1), - RunE: opt.runE, - } - flags := c.Flags() - flags.StringVarP(&opt.output, "output", "", ".", "The target directory") - flags.StringVarP(&opt.tag, "tag", "", "", "The extension image tag, try to find the latest one if this is empty") - flags.StringVarP(&opt.registry, "registry", "", "", "The target extension image registry, supported: docker.io, ghcr.io") - flags.StringVarP(&opt.os, "os", "", runtime.GOOS, "The OS") - flags.StringVarP(&opt.arch, "arch", "", runtime.GOARCH, "The architecture") - flags.DurationVarP(&opt.timeout, "timeout", "", time.Minute, "The timeout of downloading") - flags.StringVarP(&opt.imagePrefix, "image-prefix", "", "linuxsuren", "The prefix for the image address") - return + opt := &extensionOption{ + ociDownloader: ociDownloader, + } + c = &cobra.Command{ + Use: "extension", + Short: "Download extension binary files", + Long: "Download the store extension files", + Args: cobra.MinimumNArgs(1), + RunE: opt.runE, + } + flags := c.Flags() + flags.StringVarP(&opt.output, "output", "", ".", "The target directory") + flags.StringVarP(&opt.tag, "tag", "", "", "The extension image tag, try to find the latest one if this is empty") + flags.StringVarP(&opt.registry, "registry", "", "", "The target extension image registry, supported: docker.io, ghcr.io") + flags.StringVarP(&opt.kind, "kind", "", "store", "The extension kind") + flags.StringVarP(&opt.os, "os", "", runtime.GOOS, "The OS") + flags.StringVarP(&opt.arch, "arch", "", runtime.GOARCH, "The architecture") + flags.DurationVarP(&opt.timeout, "timeout", "", time.Minute, "The timeout of downloading") + flags.StringVarP(&opt.imagePrefix, "image-prefix", "", "linuxsuren", "The prefix for the image address") + return } func (o *extensionOption) runE(cmd *cobra.Command, args []string) (err error) { - o.ociDownloader.WithOS(o.os) - o.ociDownloader.WithArch(o.arch) - o.ociDownloader.WithRegistry(o.registry) - o.ociDownloader.WithImagePrefix(o.imagePrefix) - o.ociDownloader.WithTimeout(o.timeout) - o.ociDownloader.WithContext(cmd.Context()) + o.ociDownloader.WithOS(o.os) + o.ociDownloader.WithArch(o.arch) + o.ociDownloader.WithRegistry(o.registry) + o.ociDownloader.WithImagePrefix(o.imagePrefix) + o.ociDownloader.WithTimeout(o.timeout) + o.ociDownloader.WithKind(o.kind) + o.ociDownloader.WithContext(cmd.Context()) - for _, arg := range args { - var reader io.Reader - if reader, err = o.ociDownloader.Download(arg, o.tag, ""); err != nil { - return - } else if reader == nil { - err = fmt.Errorf("cannot find %s", arg) - return - } - extFile := o.ociDownloader.GetTargetFile() - cmd.Println("found target file", extFile) + for _, arg := range args { + var reader io.Reader + if reader, err = o.ociDownloader.Download(arg, o.tag, ""); err != nil { + return + } else if reader == nil { + err = fmt.Errorf("cannot find %s", arg) + return + } + extFile := o.ociDownloader.GetTargetFile() + cmd.Println("found target file", extFile) - targetFile := filepath.Base(extFile) - if err = downloader.WriteTo(reader, o.output, targetFile); err == nil { - cmd.Println("downloaded", targetFile) - } - } - return + targetFile := filepath.Base(extFile) + if err = downloader.WriteTo(reader, o.output, targetFile); err == nil { + cmd.Println("downloaded", targetFile) + } + } + return } diff --git a/pkg/downloader/store.go b/pkg/downloader/extension.go similarity index 65% rename from pkg/downloader/store.go rename to pkg/downloader/extension.go index 2d4256e..a696f2e 100644 --- a/pkg/downloader/store.go +++ b/pkg/downloader/extension.go @@ -1,5 +1,5 @@ /* -Copyright 2024 API Testing Authors. +Copyright 2024-2025 API Testing Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,30 +25,32 @@ import ( "strings" ) -type storeDownloader struct { +type extensionDownloader struct { OCIDownloader os, arch string + kind string extFile string imagePrefix string } func NewStoreDownloader() PlatformAwareOCIDownloader { - ociDownloader := &storeDownloader{ + ociDownloader := &extensionDownloader{ OCIDownloader: NewDefaultOCIDownloader(), } ociDownloader.WithOS(runtime.GOOS) ociDownloader.WithArch(runtime.GOARCH) ociDownloader.WithImagePrefix("linuxsuren") + ociDownloader.WithKind("store") return ociDownloader } -func (d *storeDownloader) Download(name, tag, _ string) (reader io.Reader, err error) { - name = strings.TrimPrefix(name, "atest-store-") - d.extFile = fmt.Sprintf("atest-store-%s_%s_%s/atest-store-%s", name, d.os, d.arch, name) +func (d *extensionDownloader) Download(name, tag, _ string) (reader io.Reader, err error) { + name = strings.TrimPrefix(name, fmt.Sprintf("atest-%s-", d.kind)) + d.extFile = fmt.Sprintf("atest-%s-%s_%s_%s/atest-%s-%s", d.kind, name, d.os, d.arch, d.kind, name) if d.os == "windows" { d.extFile = fmt.Sprintf("%s.exe", d.extFile) } - image := fmt.Sprintf("%s/atest-ext-store-%s", d.imagePrefix, name) + image := fmt.Sprintf("%s/atest-ext-%s-%s", d.imagePrefix, d.kind, name) reader, err = d.OCIDownloader.Download(image, tag, d.extFile) return } @@ -64,21 +66,25 @@ func WriteTo(reader io.Reader, dir, file string) (err error) { return } -func (d *storeDownloader) GetTargetFile() string { +func (d *extensionDownloader) GetTargetFile() string { return d.extFile } -func (d *storeDownloader) WithOS(os string) { +func (d *extensionDownloader) WithOS(os string) { d.os = os } -func (d *storeDownloader) WithImagePrefix(imagePrefix string) { +func (d *extensionDownloader) WithImagePrefix(imagePrefix string) { d.imagePrefix = imagePrefix } -func (d *storeDownloader) WithArch(arch string) { +func (d *extensionDownloader) WithArch(arch string) { d.arch = arch if d.arch == "amd64" { d.arch = "amd64_v1" } } + +func (d *extensionDownloader) WithKind(kind string) { + d.kind = kind +} diff --git a/pkg/downloader/oci.go b/pkg/downloader/oci.go index 558c024..487ca70 100644 --- a/pkg/downloader/oci.go +++ b/pkg/downloader/oci.go @@ -45,6 +45,7 @@ type PlatformAwareOCIDownloader interface { WithOS(string) WithArch(string) GetTargetFile() string + WithKind(string) WithImagePrefix(string) } diff --git a/pkg/server/store_ext_manager.go b/pkg/server/store_ext_manager.go index c6148de..516aba0 100644 --- a/pkg/server/store_ext_manager.go +++ b/pkg/server/store_ext_manager.go @@ -176,6 +176,8 @@ var ErrDownloadNotSupport = errors.New("no support") type nonDownloader struct{} +var _ downloader.PlatformAwareOCIDownloader = &nonDownloader{} + func (n *nonDownloader) WithBasicAuth(username string, password string) { // Do nothing because this is an empty implementation } @@ -197,6 +199,10 @@ func (n *nonDownloader) WithRegistry(string) { // Do nothing because this is an empty implementation } +func (n *nonDownloader) WithKind(string) { + // Do nothing because this is an empty implementation +} + func (n *nonDownloader) WithImagePrefix(imagePrefix string) { // Do nothing because this is an empty implementation }