feat: support to download differnt kinds of ext

This commit is contained in:
rick 2025-03-05 06:27:03 +00:00
parent 2f409ca68d
commit f6fa6eb9dd
4 changed files with 83 additions and 67 deletions

View File

@ -17,72 +17,75 @@ limitations under the License.
package cmd package cmd
import ( import (
"fmt" "fmt"
"io" "io"
"path/filepath" "path/filepath"
"runtime" "runtime"
"time" "time"
"github.com/linuxsuren/api-testing/pkg/downloader" "github.com/linuxsuren/api-testing/pkg/downloader"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
type extensionOption struct { type extensionOption struct {
ociDownloader downloader.PlatformAwareOCIDownloader ociDownloader downloader.PlatformAwareOCIDownloader
output string output string
registry string registry string
tag string kind string
os string tag string
arch string os string
timeout time.Duration arch string
imagePrefix string timeout time.Duration
imagePrefix string
} }
func createExtensionCommand(ociDownloader downloader.PlatformAwareOCIDownloader) (c *cobra.Command) { func createExtensionCommand(ociDownloader downloader.PlatformAwareOCIDownloader) (c *cobra.Command) {
opt := &extensionOption{ opt := &extensionOption{
ociDownloader: ociDownloader, ociDownloader: ociDownloader,
} }
c = &cobra.Command{ c = &cobra.Command{
Use: "extension", Use: "extension",
Short: "Download extension binary files", Short: "Download extension binary files",
Long: "Download the store extension files", Long: "Download the store extension files",
Args: cobra.MinimumNArgs(1), Args: cobra.MinimumNArgs(1),
RunE: opt.runE, RunE: opt.runE,
} }
flags := c.Flags() flags := c.Flags()
flags.StringVarP(&opt.output, "output", "", ".", "The target directory") 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.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.registry, "registry", "", "", "The target extension image registry, supported: docker.io, ghcr.io")
flags.StringVarP(&opt.os, "os", "", runtime.GOOS, "The OS") flags.StringVarP(&opt.kind, "kind", "", "store", "The extension kind")
flags.StringVarP(&opt.arch, "arch", "", runtime.GOARCH, "The architecture") flags.StringVarP(&opt.os, "os", "", runtime.GOOS, "The OS")
flags.DurationVarP(&opt.timeout, "timeout", "", time.Minute, "The timeout of downloading") flags.StringVarP(&opt.arch, "arch", "", runtime.GOARCH, "The architecture")
flags.StringVarP(&opt.imagePrefix, "image-prefix", "", "linuxsuren", "The prefix for the image address") flags.DurationVarP(&opt.timeout, "timeout", "", time.Minute, "The timeout of downloading")
return 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) { func (o *extensionOption) runE(cmd *cobra.Command, args []string) (err error) {
o.ociDownloader.WithOS(o.os) o.ociDownloader.WithOS(o.os)
o.ociDownloader.WithArch(o.arch) o.ociDownloader.WithArch(o.arch)
o.ociDownloader.WithRegistry(o.registry) o.ociDownloader.WithRegistry(o.registry)
o.ociDownloader.WithImagePrefix(o.imagePrefix) o.ociDownloader.WithImagePrefix(o.imagePrefix)
o.ociDownloader.WithTimeout(o.timeout) o.ociDownloader.WithTimeout(o.timeout)
o.ociDownloader.WithContext(cmd.Context()) o.ociDownloader.WithKind(o.kind)
o.ociDownloader.WithContext(cmd.Context())
for _, arg := range args { for _, arg := range args {
var reader io.Reader var reader io.Reader
if reader, err = o.ociDownloader.Download(arg, o.tag, ""); err != nil { if reader, err = o.ociDownloader.Download(arg, o.tag, ""); err != nil {
return return
} else if reader == nil { } else if reader == nil {
err = fmt.Errorf("cannot find %s", arg) err = fmt.Errorf("cannot find %s", arg)
return return
} }
extFile := o.ociDownloader.GetTargetFile() extFile := o.ociDownloader.GetTargetFile()
cmd.Println("found target file", extFile) cmd.Println("found target file", extFile)
targetFile := filepath.Base(extFile) targetFile := filepath.Base(extFile)
if err = downloader.WriteTo(reader, o.output, targetFile); err == nil { if err = downloader.WriteTo(reader, o.output, targetFile); err == nil {
cmd.Println("downloaded", targetFile) cmd.Println("downloaded", targetFile)
} }
} }
return return
} }

View File

@ -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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -25,30 +25,32 @@ import (
"strings" "strings"
) )
type storeDownloader struct { type extensionDownloader struct {
OCIDownloader OCIDownloader
os, arch string os, arch string
kind string
extFile string extFile string
imagePrefix string imagePrefix string
} }
func NewStoreDownloader() PlatformAwareOCIDownloader { func NewStoreDownloader() PlatformAwareOCIDownloader {
ociDownloader := &storeDownloader{ ociDownloader := &extensionDownloader{
OCIDownloader: NewDefaultOCIDownloader(), OCIDownloader: NewDefaultOCIDownloader(),
} }
ociDownloader.WithOS(runtime.GOOS) ociDownloader.WithOS(runtime.GOOS)
ociDownloader.WithArch(runtime.GOARCH) ociDownloader.WithArch(runtime.GOARCH)
ociDownloader.WithImagePrefix("linuxsuren") ociDownloader.WithImagePrefix("linuxsuren")
ociDownloader.WithKind("store")
return ociDownloader return ociDownloader
} }
func (d *storeDownloader) Download(name, tag, _ string) (reader io.Reader, err error) { func (d *extensionDownloader) Download(name, tag, _ string) (reader io.Reader, err error) {
name = strings.TrimPrefix(name, "atest-store-") name = strings.TrimPrefix(name, fmt.Sprintf("atest-%s-", d.kind))
d.extFile = fmt.Sprintf("atest-store-%s_%s_%s/atest-store-%s", name, d.os, d.arch, name) 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" { if d.os == "windows" {
d.extFile = fmt.Sprintf("%s.exe", d.extFile) 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) reader, err = d.OCIDownloader.Download(image, tag, d.extFile)
return return
} }
@ -64,21 +66,25 @@ func WriteTo(reader io.Reader, dir, file string) (err error) {
return return
} }
func (d *storeDownloader) GetTargetFile() string { func (d *extensionDownloader) GetTargetFile() string {
return d.extFile return d.extFile
} }
func (d *storeDownloader) WithOS(os string) { func (d *extensionDownloader) WithOS(os string) {
d.os = os d.os = os
} }
func (d *storeDownloader) WithImagePrefix(imagePrefix string) { func (d *extensionDownloader) WithImagePrefix(imagePrefix string) {
d.imagePrefix = imagePrefix d.imagePrefix = imagePrefix
} }
func (d *storeDownloader) WithArch(arch string) { func (d *extensionDownloader) WithArch(arch string) {
d.arch = arch d.arch = arch
if d.arch == "amd64" { if d.arch == "amd64" {
d.arch = "amd64_v1" d.arch = "amd64_v1"
} }
} }
func (d *extensionDownloader) WithKind(kind string) {
d.kind = kind
}

View File

@ -45,6 +45,7 @@ type PlatformAwareOCIDownloader interface {
WithOS(string) WithOS(string)
WithArch(string) WithArch(string)
GetTargetFile() string GetTargetFile() string
WithKind(string)
WithImagePrefix(string) WithImagePrefix(string)
} }

View File

@ -176,6 +176,8 @@ var ErrDownloadNotSupport = errors.New("no support")
type nonDownloader struct{} type nonDownloader struct{}
var _ downloader.PlatformAwareOCIDownloader = &nonDownloader{}
func (n *nonDownloader) WithBasicAuth(username string, password string) { func (n *nonDownloader) WithBasicAuth(username string, password string) {
// Do nothing because this is an empty implementation // 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 // 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) { func (n *nonDownloader) WithImagePrefix(imagePrefix string) {
// Do nothing because this is an empty implementation // Do nothing because this is an empty implementation
} }