Util helpers for image/AMI importer

This commit is contained in:
benduncan
2025-11-05 22:28:05 +11:00
parent d2c2ced79e
commit 69151be3bb
10 changed files with 247 additions and 8 deletions
+4 -2
View File
@@ -127,7 +127,7 @@ func runimagesImportCmd(cmd *cobra.Command, args []string) {
imageStat, err := os.Stat(imageFile)
if err != nil {
fmt.Fprintf(os.Stderr, "File could not be found", err)
fmt.Fprintf(os.Stderr, "File could not be found %s", err)
os.Exit(1)
}
@@ -138,7 +138,7 @@ func runimagesImportCmd(cmd *cobra.Command, args []string) {
imageDir := fmt.Sprintf("%s/images", baseDir)
if !fileExists(imageDir) {
fmt.Fprintf(os.Stderr, "Image directory does not exist. Base path specified correctly?", imageDir)
fmt.Fprintf(os.Stderr, "Image directory does not exist. Base path specified correctly? %s", imageDir)
os.Exit(1)
}
@@ -220,6 +220,8 @@ func runimagesImportCmd(cmd *cobra.Command, args []string) {
os.Exit(1)
}
// Next, validate if the image is raw, tar, gz, xv, etc. We need to upload the raw image
}
func runAdminInit(cmd *cobra.Command, args []string) {
+146
View File
@@ -1,6 +1,7 @@
package utils
import (
"bufio"
"bytes"
"encoding/json"
"encoding/xml"
@@ -8,9 +9,11 @@ import (
"fmt"
"log/slog"
"os"
"os/exec"
"path/filepath"
"reflect"
"strconv"
"strings"
"syscall"
"time"
@@ -340,3 +343,146 @@ func ValidateKeyPairName(name string) error {
return nil
}
// AMI / image extraction utils
func ExtractDiskImageFromFile(imagepath string, tmpdir string) (diskimage string, err error) {
var args []string
var execCmd string
// Confirm file exists
_, err = os.Stat(imagepath)
if err != nil {
return
}
// Extract the filepath
imagefile := filepath.Base(imagepath)
// Provide the full path to the specified file
//imagedir, err := filepath.Abs(filepath.Dir(imagepath))
//if err != nil {
// return
//}
// Already in raw/image formt, confirm the file contains a valid disk image/MBR
if strings.HasSuffix(imagefile, ".raw") || strings.HasSuffix(imagefile, ".img") {
path, err := filepath.Abs(imagepath)
if err != nil {
return path, err
}
// Validate the specified filename is indeed a disk image / MBR
err = validateDiskImagePath(path)
return path, err
} else if strings.HasSuffix(imagefile, ".tar.xz") {
args = []string{
"xfvJ",
imagepath,
"-C",
tmpdir,
}
execCmd = "tar"
} else if strings.HasSuffix(imagefile, ".tar.gz") || strings.HasSuffix(imagefile, ".tgz") {
args = []string{
"xfvz",
imagepath,
"-C",
tmpdir,
}
execCmd = "tar"
} else if strings.HasSuffix(imagefile, ".tar") {
args = []string{
"xfv",
imagepath,
"-C",
tmpdir,
}
execCmd = "tar"
} else if strings.HasSuffix(imagefile, ".xz") {
args = []string{
"-d",
imagepath,
}
execCmd = "xz"
} else {
err = errors.New("unsupported filetype")
return
}
cmd := exec.Command(execCmd, args...)
output, _ := cmd.Output()
diskimage, err = extractDiskImagePath(tmpdir, output)
return
}
func extractDiskImagePath(imagedir string, output []byte) (diskimage string, err error) {
reader := bytes.NewReader(output)
r := bufio.NewReader(reader)
for {
line, err := r.ReadString('\n')
line = strings.Replace(line, "\n", "", 1)
if strings.HasSuffix(line, ".raw") || strings.HasSuffix(line, ".img") {
diskimage := fmt.Sprintf("%s/%s", imagedir, line)
err = validateDiskImagePath(diskimage)
return diskimage, err
}
if err != nil && err.Error() == "EOF" {
break
}
}
return
}
func validateDiskImagePath(diskimage string) (err error) {
args := []string{
diskimage,
}
cmd := exec.Command("file", args...)
output, _ := cmd.Output()
filetype := strings.Split(string(output), ":")
if len(filetype) > 1 {
if strings.Contains(filetype[1], "DOS/MBR boot sector") || strings.Contains(filetype[1], "Linux ") {
return nil
}
}
return errors.New("no valid disk image found")
}
+97 -6
View File
@@ -267,15 +267,15 @@ func TestGenerateErrorPayload(t *testing.T) {
func TestValidateErrorPayload(t *testing.T) {
tests := []struct {
name string
payload string
expectError bool
name string
payload string
expectError bool
expectedCode string
}{
{
name: "Valid error payload",
payload: `{"Code":"ValidationError","Message":null}`,
expectError: true,
name: "Valid error payload",
payload: `{"Code":"ValidationError","Message":null}`,
expectError: true,
expectedCode: "ValidationError",
},
{
@@ -427,3 +427,94 @@ func TestStopProcess(t *testing.T) {
err = StopProcess("nonexistent-process")
assert.Error(t, err, "Should error when stopping non-existent process")
}
// Test file extraction process
func TestExtractDiskImageFromFile(t *testing.T) {
tmpDir, err := os.MkdirTemp("", "hive-utils-test-*")
t.Log("Temp dir:", tmpDir)
assert.NoError(t, err, "Temp dir should be created")
// Sample .xz (fail)
imagePath, err := ExtractDiskImageFromFile("/tmp/file.xz", tmpDir)
assert.Empty(t, imagePath, "Should be blank")
assert.Error(t, err, "Should error")
// Sample incorrect image (fail)
imagePath, err = ExtractDiskImageFromFile("../../tests/ebs.json", tmpDir)
assert.Empty(t, imagePath, "Should be blank")
assert.Error(t, err, "Should error")
assert.ErrorContains(t, err, "unsupported filetype")
// Sample incorrect image (fail)
imagePath, err = ExtractDiskImageFromFile("../../tests/unit-test-disk-image-bad.raw", tmpDir)
assert.NotEmpty(t, imagePath, "Should be blank")
assert.Error(t, err, "Should error")
assert.ErrorContains(t, err, "no valid disk image found")
// Sample raw
imagePath, err = ExtractDiskImageFromFile("../../tests/unit-test-disk-image.raw", tmpDir)
assert.NotEmpty(t, imagePath, "Should not be blank")
assert.Contains(t, imagePath, ".raw")
assert.NoError(t, err, "Should not error")
_, err = exec.LookPath("tar")
if err == nil {
// Sample .tgz
imagePath, err = ExtractDiskImageFromFile("../../tests/unit-test-disk-image2.tgz", tmpDir)
assert.NotEmpty(t, imagePath, "Should not be blank")
assert.Contains(t, imagePath, ".img")
assert.NoError(t, err, "Should not error")
// Sample .tar
imagePath, err = ExtractDiskImageFromFile("../../tests/unit-test-disk-image.tar", tmpDir)
assert.NotEmpty(t, imagePath, "Should not be blank")
assert.Contains(t, imagePath, ".raw")
assert.NoError(t, err, "Should not error")
// Sample .tar.gz
imagePath, err = ExtractDiskImageFromFile("../../tests/unit-test-disk-image.tar.gz", tmpDir)
assert.NotEmpty(t, imagePath, "Should not be blank")
assert.Contains(t, imagePath, ".raw")
assert.NoError(t, err, "Should not error")
// Sample xz
imagePath, err = ExtractDiskImageFromFile("../../tests/unit-test-disk-image.tar.xz", tmpDir)
assert.NotEmpty(t, imagePath, "Should not be blank")
assert.Contains(t, imagePath, ".raw")
assert.NoError(t, err, "Should not error")
// Sample tgz
imagePath, err = ExtractDiskImageFromFile("../../tests/unit-test-disk-image.tgz", tmpDir)
assert.NotEmpty(t, imagePath, "Should not be blank")
assert.Contains(t, imagePath, ".raw")
assert.NoError(t, err, "Should not error")
} else {
t.Skip("tar command not found, skipping archive extraction tests")
}
err = os.RemoveAll(tmpDir)
assert.NoError(t, err, "Could not remove temp dir")
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.