image: support zip sources and align class k3s versions
This commit is contained in:
parent
8f0d5389c2
commit
eb77c94db3
@ -24,7 +24,7 @@ classes:
|
||||
os: ubuntu-24.04-raspi
|
||||
image: ${METIS_IMAGE_RPI5_UBUNTU_WORKER}
|
||||
checksum: ${METIS_IMAGE_RPI5_UBUNTU_WORKER_SHA256}
|
||||
k3s_version: v1.31.5+k3s1
|
||||
k3s_version: v1.33.3+k3s1
|
||||
default_labels:
|
||||
hardware: rpi5
|
||||
node-role.kubernetes.io/worker: "true"
|
||||
@ -33,7 +33,7 @@ classes:
|
||||
os: ubuntu-20.04-tegra
|
||||
image: ${METIS_IMAGE_JETSON_UBUNTU_ACCELERATOR}
|
||||
checksum: ${METIS_IMAGE_JETSON_UBUNTU_ACCELERATOR_SHA256}
|
||||
k3s_version: v1.31.5+k3s1
|
||||
k3s_version: v1.33.3+k3s1
|
||||
default_labels:
|
||||
hardware: jetson
|
||||
jetson: "true"
|
||||
@ -43,7 +43,7 @@ classes:
|
||||
os: ubuntu-24.04-raspi
|
||||
image: ${METIS_IMAGE_RPI5_UBUNTU_CONTROL}
|
||||
checksum: ${METIS_IMAGE_RPI5_UBUNTU_CONTROL_SHA256}
|
||||
k3s_version: v1.31.5+k3s1
|
||||
k3s_version: v1.33.3+k3s1
|
||||
default_labels:
|
||||
hardware: rpi5
|
||||
node-role.kubernetes.io/control-plane: "true"
|
||||
@ -54,7 +54,7 @@ classes:
|
||||
os: debian-13
|
||||
image: ${METIS_IMAGE_AMD64_DEBIAN_WORKER}
|
||||
checksum: ${METIS_IMAGE_AMD64_DEBIAN_WORKER_SHA256}
|
||||
k3s_version: v1.31.5+k3s1
|
||||
k3s_version: v1.33.3+k3s1
|
||||
default_labels:
|
||||
hardware: amd64
|
||||
node-role.kubernetes.io/worker: "true"
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
@ -35,6 +36,16 @@ func DownloadAndVerify(url, dest, checksum string) (string, error) {
|
||||
}
|
||||
return dest, nil
|
||||
}
|
||||
if strings.HasSuffix(url, ".zip") {
|
||||
archive := dest + ".zip"
|
||||
if err := ensureVerifiedFile(url, archive, checksum); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := decompressZIP(archive, dest); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return dest, nil
|
||||
}
|
||||
if err := ensureVerifiedFile(url, dest, checksum); err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -107,6 +118,47 @@ func decompressXZ(src, dest string) error {
|
||||
return out.Sync()
|
||||
}
|
||||
|
||||
func decompressZIP(src, dest string) error {
|
||||
reader, err := zip.OpenReader(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
var target *zip.File
|
||||
for _, file := range reader.File {
|
||||
if file.FileInfo().IsDir() {
|
||||
continue
|
||||
}
|
||||
if strings.HasSuffix(strings.ToLower(file.Name), ".img") {
|
||||
target = file
|
||||
break
|
||||
}
|
||||
if target == nil {
|
||||
target = file
|
||||
}
|
||||
}
|
||||
if target == nil {
|
||||
return fmt.Errorf("zip archive %s does not contain a file entry", src)
|
||||
}
|
||||
|
||||
in, err := target.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer in.Close()
|
||||
|
||||
out, err := os.Create(dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
if _, err := io.Copy(out, in); err != nil {
|
||||
return err
|
||||
}
|
||||
return out.Sync()
|
||||
}
|
||||
|
||||
// VerifyChecksum checks sha256 in the form "sha256:<hex>".
|
||||
func VerifyChecksum(path, checksum string) error {
|
||||
if checksum == "" {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"os"
|
||||
@ -107,3 +108,78 @@ func TestDownloadAndVerifyReplacesStaleBadArchiveCache(t *testing.T) {
|
||||
t.Fatalf("unexpected decompressed content: %q", string(data))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDownloadDecompressesZIPFileURLs(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
archive := filepath.Join(dir, "base.zip")
|
||||
if err := writeTestZIP(archive, map[string]string{
|
||||
"nested/base.img": "metis-zip-test",
|
||||
}); err != nil {
|
||||
t.Fatalf("writeTestZIP: %v", err)
|
||||
}
|
||||
dest := filepath.Join(dir, "copy.img")
|
||||
if err := Download("file://"+archive, dest); err != nil {
|
||||
t.Fatalf("Download: %v", err)
|
||||
}
|
||||
data, err := os.ReadFile(dest)
|
||||
if err != nil {
|
||||
t.Fatalf("ReadFile: %v", err)
|
||||
}
|
||||
if string(data) != "metis-zip-test" {
|
||||
t.Fatalf("unexpected decompressed content: %q", string(data))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDownloadAndVerifyUsesArchiveChecksumForZIP(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
archive := filepath.Join(dir, "base.zip")
|
||||
if err := writeTestZIP(archive, map[string]string{
|
||||
"base.img": "metis-zip-test",
|
||||
}); err != nil {
|
||||
t.Fatalf("writeTestZIP: %v", err)
|
||||
}
|
||||
archiveBytes, err := os.ReadFile(archive)
|
||||
if err != nil {
|
||||
t.Fatalf("ReadFile archive: %v", err)
|
||||
}
|
||||
archiveSum := sha256.Sum256(archiveBytes)
|
||||
dest := filepath.Join(dir, "copy.img")
|
||||
localPath, err := DownloadAndVerify("file://"+archive, dest, "sha256:"+hex.EncodeToString(archiveSum[:]))
|
||||
if err != nil {
|
||||
t.Fatalf("DownloadAndVerify: %v", err)
|
||||
}
|
||||
if localPath != dest {
|
||||
t.Fatalf("expected local path %s, got %s", dest, localPath)
|
||||
}
|
||||
data, err := os.ReadFile(dest)
|
||||
if err != nil {
|
||||
t.Fatalf("ReadFile dest: %v", err)
|
||||
}
|
||||
if string(data) != "metis-zip-test" {
|
||||
t.Fatalf("unexpected decompressed content: %q", string(data))
|
||||
}
|
||||
}
|
||||
|
||||
func writeTestZIP(path string, files map[string]string) error {
|
||||
out, err := os.Create(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
zw := zip.NewWriter(out)
|
||||
for name, content := range files {
|
||||
w, err := zw.Create(name)
|
||||
if err != nil {
|
||||
_ = zw.Close()
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write([]byte(content)); err != nil {
|
||||
_ = zw.Close()
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := zw.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return out.Sync()
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user