95 lines
2.5 KiB
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)
|
|
}
|