mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 09:01:31 +00:00
Util helpers for image/AMI importer
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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")
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
Reference in New Issue
Block a user