metis/cmd/metis/remote_artifacts.go

95 lines
2.5 KiB
Go

package main
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
)
func orasLogin(registry, username, password string) error {
if strings.TrimSpace(username) == "" || strings.TrimSpace(password) == "" {
return fmt.Errorf("harbor credentials missing")
}
cmd := exec.Command("oras", "login", registry, "-u", username, "-p", password)
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%w: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
func orasPush(ref, imagePath, metadataPath string) error {
dir, args, err := orasPushInvocation(ref, imagePath, metadataPath)
if err != nil {
return err
}
cmd := exec.Command("oras", args...)
cmd.Dir = dir
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%w: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
func orasPushInvocation(ref, imagePath, metadataPath string) (string, []string, error) {
imageDir := filepath.Dir(imagePath)
metadataDir := filepath.Dir(metadataPath)
if imageDir != metadataDir {
return "", nil, fmt.Errorf("oras push requires artifacts in one directory: %s vs %s", imageDir, metadataDir)
}
return imageDir, []string{
"push",
ref,
fmt.Sprintf("%s:application/x-raw-disk-image", filepath.Base(imagePath)),
fmt.Sprintf("%s:application/json", filepath.Base(metadataPath)),
}, nil
}
func orasTag(ref string, tags ...string) error {
args := append([]string{"tag", ref}, tags...)
cmd := exec.Command("oras", args...)
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%w: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
func orasPull(ref, outDir string) error {
cmd := exec.Command("oras", "pull", ref, "-o", outDir)
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("%w: %s", err, strings.TrimSpace(string(out)))
}
return nil
}
func resolvePulledArtifact(dir string) (string, bool, error) {
var rawPath string
var compressedPath string
err := filepath.WalkDir(dir, func(path string, d os.DirEntry, walkErr error) error {
if walkErr != nil {
return walkErr
}
if d.IsDir() {
return nil
}
switch {
case strings.HasSuffix(path, ".img.xz"):
compressedPath = path
case strings.HasSuffix(path, ".img"):
rawPath = path
}
return nil
})
if err != nil {
return "", false, err
}
if compressedPath != "" {
return compressedPath, true, nil
}
if rawPath != "" {
return rawPath, false, nil
}
return "", false, fmt.Errorf("no .img or .img.xz artifact found in %s", dir)
}