mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-18 17:01:07 +00:00
Merge pull request #1827 from rneugeba/state
Use a "state" directory for linuxkit run state and enable virtio sockets
This commit is contained in:
commit
318cf6841c
5
.gitignore
vendored
5
.gitignore
vendored
@ -6,11 +6,14 @@ Dockerfile.media
|
||||
*.tag
|
||||
*.iso
|
||||
*.vhd
|
||||
*.vmdk
|
||||
*.vmdk.lck
|
||||
*.tar
|
||||
*.gz
|
||||
*.vhdx
|
||||
*.efi
|
||||
*.qcow2
|
||||
*-kernel$
|
||||
*-kernel
|
||||
*-cmdline
|
||||
*-state
|
||||
artifacts/*
|
||||
|
2
Makefile
2
Makefile
@ -74,4 +74,4 @@ ci-pr:
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf bin *.log *-kernel *-cmdline *.img *.iso *.gz *.qcow2 *.vhd *.vmx *.vmdk *.tar
|
||||
rm -rf bin *.log *-kernel *-cmdline *-state *.img *.iso *.gz *.qcow2 *.vhd *.vmx *.vmdk *.tar
|
||||
|
@ -27,31 +27,31 @@ const (
|
||||
|
||||
// Process the run arguments and execute run
|
||||
func runGcp(args []string) {
|
||||
gcpCmd := flag.NewFlagSet("gcp", flag.ExitOnError)
|
||||
flags := flag.NewFlagSet("gcp", flag.ExitOnError)
|
||||
invoked := filepath.Base(os.Args[0])
|
||||
gcpCmd.Usage = func() {
|
||||
flags.Usage = func() {
|
||||
fmt.Printf("USAGE: %s run gcp [options] [name]\n\n", invoked)
|
||||
fmt.Printf("'name' specifies either the name of an already uploaded\n")
|
||||
fmt.Printf("GCP image or the full path to a image file which will be\n")
|
||||
fmt.Printf("uploaded before it is run.\n\n")
|
||||
fmt.Printf("Options:\n\n")
|
||||
gcpCmd.PrintDefaults()
|
||||
flags.PrintDefaults()
|
||||
}
|
||||
zoneFlag := gcpCmd.String("zone", defaultZone, "GCP Zone")
|
||||
machineFlag := gcpCmd.String("machine", defaultMachine, "GCP Machine Type")
|
||||
keysFlag := gcpCmd.String("keys", "", "Path to Service Account JSON key file")
|
||||
projectFlag := gcpCmd.String("project", "", "GCP Project Name")
|
||||
diskSizeFlag := gcpCmd.Int("disk-size", 0, "Size of system disk in GB")
|
||||
skipCleanup := gcpCmd.Bool("skip-cleanup", false, "Don't remove images or VMs")
|
||||
zoneFlag := flags.String("zone", defaultZone, "GCP Zone")
|
||||
machineFlag := flags.String("machine", defaultMachine, "GCP Machine Type")
|
||||
keysFlag := flags.String("keys", "", "Path to Service Account JSON key file")
|
||||
projectFlag := flags.String("project", "", "GCP Project Name")
|
||||
diskSizeFlag := flags.Int("disk-size", 0, "Size of system disk in GB")
|
||||
skipCleanup := flags.Bool("skip-cleanup", false, "Don't remove images or VMs")
|
||||
|
||||
if err := gcpCmd.Parse(args); err != nil {
|
||||
if err := flags.Parse(args); err != nil {
|
||||
log.Fatal("Unable to parse args")
|
||||
}
|
||||
|
||||
remArgs := gcpCmd.Args()
|
||||
remArgs := flags.Args()
|
||||
if len(remArgs) == 0 {
|
||||
fmt.Printf("Please specify the name of the image to boot\n")
|
||||
gcpCmd.Usage()
|
||||
flags.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
name := remArgs[0]
|
||||
|
@ -15,34 +15,42 @@ import (
|
||||
|
||||
// Process the run arguments and execute run
|
||||
func runHyperKit(args []string) {
|
||||
hyperkitCmd := flag.NewFlagSet("hyperkit", flag.ExitOnError)
|
||||
flags := flag.NewFlagSet("hyperkit", flag.ExitOnError)
|
||||
invoked := filepath.Base(os.Args[0])
|
||||
hyperkitCmd.Usage = func() {
|
||||
flags.Usage = func() {
|
||||
fmt.Printf("USAGE: %s run hyperkit [options] prefix\n\n", invoked)
|
||||
fmt.Printf("'prefix' specifies the path to the VM image.\n")
|
||||
fmt.Printf("\n")
|
||||
fmt.Printf("Options:\n")
|
||||
hyperkitCmd.PrintDefaults()
|
||||
flags.PrintDefaults()
|
||||
}
|
||||
hyperkitPath := hyperkitCmd.String("hyperkit", "", "Path to hyperkit binary (if not in default location)")
|
||||
cpus := hyperkitCmd.Int("cpus", 1, "Number of CPUs")
|
||||
mem := hyperkitCmd.Int("mem", 1024, "Amount of memory in MB")
|
||||
diskSz := hyperkitCmd.Int("disk-size", 0, "Size of Disk in MB")
|
||||
disk := hyperkitCmd.String("disk", "", "Path to disk image to used")
|
||||
data := hyperkitCmd.String("data", "", "Metadata to pass to VM (either a path to a file or a string)")
|
||||
ipStr := hyperkitCmd.String("ip", "", "IP address for the VM")
|
||||
hyperkitPath := flags.String("hyperkit", "", "Path to hyperkit binary (if not in default location)")
|
||||
cpus := flags.Int("cpus", 1, "Number of CPUs")
|
||||
mem := flags.Int("mem", 1024, "Amount of memory in MB")
|
||||
diskSz := flags.Int("disk-size", 0, "Size of Disk in MB")
|
||||
disk := flags.String("disk", "", "Path to disk image to used")
|
||||
data := flags.String("data", "", "Metadata to pass to VM (either a path to a file or a string)")
|
||||
ipStr := flags.String("ip", "", "IP address for the VM")
|
||||
state := flags.String("state", "", "Path to directory to keep VM state in")
|
||||
|
||||
if err := hyperkitCmd.Parse(args); err != nil {
|
||||
if err := flags.Parse(args); err != nil {
|
||||
log.Fatal("Unable to parse args")
|
||||
}
|
||||
remArgs := hyperkitCmd.Args()
|
||||
remArgs := flags.Args()
|
||||
if len(remArgs) == 0 {
|
||||
fmt.Println("Please specify the prefix to the image to boot\n")
|
||||
hyperkitCmd.Usage()
|
||||
flags.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
prefix := remArgs[0]
|
||||
|
||||
if *state == "" {
|
||||
*state = prefix + "-state"
|
||||
}
|
||||
if err := os.MkdirAll(*state, 0755); err != nil {
|
||||
log.Fatalf("Could not create state directory: %v", err)
|
||||
}
|
||||
|
||||
isoPath := ""
|
||||
if *data != "" {
|
||||
var d []byte
|
||||
@ -54,9 +62,9 @@ func runHyperKit(args []string) {
|
||||
log.Fatalf("Cannot read user data: %v", err)
|
||||
}
|
||||
}
|
||||
isoPath = prefix + "-data.iso"
|
||||
isoPath = filepath.Join(*state, "data.iso")
|
||||
if err := WriteMetadataISO(isoPath, d); err != nil {
|
||||
log.Fatalf("Cannot write user data ISO: %s", err)
|
||||
log.Fatalf("Cannot write user data ISO: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,10 +92,10 @@ func runHyperKit(args []string) {
|
||||
}
|
||||
|
||||
if *diskSz != 0 && *disk == "" {
|
||||
*disk = prefix + "-disk.img"
|
||||
*disk = filepath.Join(*state, "disk.img")
|
||||
}
|
||||
|
||||
h, err := hyperkit.New(*hyperkitPath, "auto", "")
|
||||
h, err := hyperkit.New(*hyperkitPath, "auto", *state)
|
||||
if err != nil {
|
||||
log.Fatalln("Error creating hyperkit: ", err)
|
||||
}
|
||||
@ -98,6 +106,7 @@ func runHyperKit(args []string) {
|
||||
h.UUID = vmUUID
|
||||
h.DiskImage = *disk
|
||||
h.ISOImage = isoPath
|
||||
h.VSock = true
|
||||
h.CPUs = *cpus
|
||||
h.Memory = *mem
|
||||
h.DiskSize = *diskSz
|
||||
|
@ -40,25 +40,25 @@ func ValidateHTTPURL(url string) {
|
||||
|
||||
// Process the run arguments and execute run
|
||||
func runPacket(args []string) {
|
||||
packetCmd := flag.NewFlagSet("packet", flag.ExitOnError)
|
||||
flags := flag.NewFlagSet("packet", flag.ExitOnError)
|
||||
invoked := filepath.Base(os.Args[0])
|
||||
packetCmd.Usage = func() {
|
||||
flags.Usage = func() {
|
||||
fmt.Printf("USAGE: %s run packet [options] [name]\n\n", invoked)
|
||||
fmt.Printf("Options:\n\n")
|
||||
packetCmd.PrintDefaults()
|
||||
flags.PrintDefaults()
|
||||
}
|
||||
baseURLFlag := packetCmd.String("base-url", "", "Base URL that the kernel and initrd are served from.")
|
||||
zoneFlag := packetCmd.String("zone", packetDefaultZone, "Packet Zone")
|
||||
machineFlag := packetCmd.String("machine", packetDefaultMachine, "Packet Machine Type")
|
||||
apiKeyFlag := packetCmd.String("api-key", "", "Packet API key")
|
||||
projectFlag := packetCmd.String("project-id", "", "Packet Project ID")
|
||||
hostNameFlag := packetCmd.String("hostname", packetDefaultHostname, "Hostname of new instance")
|
||||
nameFlag := packetCmd.String("img-name", "", "Overrides the prefix used to identify the files. Defaults to [name]")
|
||||
if err := packetCmd.Parse(args); err != nil {
|
||||
baseURLFlag := flags.String("base-url", "", "Base URL that the kernel and initrd are served from.")
|
||||
zoneFlag := flags.String("zone", packetDefaultZone, "Packet Zone")
|
||||
machineFlag := flags.String("machine", packetDefaultMachine, "Packet Machine Type")
|
||||
apiKeyFlag := flags.String("api-key", "", "Packet API key")
|
||||
projectFlag := flags.String("project-id", "", "Packet Project ID")
|
||||
hostNameFlag := flags.String("hostname", packetDefaultHostname, "Hostname of new instance")
|
||||
nameFlag := flags.String("img-name", "", "Overrides the prefix used to identify the files. Defaults to [name]")
|
||||
if err := flags.Parse(args); err != nil {
|
||||
log.Fatal("Unable to parse args")
|
||||
}
|
||||
|
||||
remArgs := packetCmd.Args()
|
||||
remArgs := flags.Args()
|
||||
prefix := "packet"
|
||||
if len(remArgs) > 0 {
|
||||
prefix = remArgs[0]
|
||||
|
@ -38,63 +38,63 @@ type QemuConfig struct {
|
||||
|
||||
func runQemu(args []string) {
|
||||
invoked := filepath.Base(os.Args[0])
|
||||
qemuFlags := flag.NewFlagSet("qemu", flag.ExitOnError)
|
||||
qemuFlags.Usage = func() {
|
||||
flags := flag.NewFlagSet("qemu", flag.ExitOnError)
|
||||
flags.Usage = func() {
|
||||
fmt.Printf("USAGE: %s run qemu [options] prefix\n\n", invoked)
|
||||
fmt.Printf("'prefix' specifies the path to the VM image.\n")
|
||||
fmt.Printf("\n")
|
||||
fmt.Printf("Options:\n")
|
||||
qemuFlags.PrintDefaults()
|
||||
flags.PrintDefaults()
|
||||
}
|
||||
|
||||
// Determine Flags
|
||||
qemuGUI := qemuFlags.Bool("gui", false, "Set qemu to use video output instead of stdio")
|
||||
qemuUEFI := qemuFlags.Bool("uefi", false, "Set UEFI boot from 'prefix'-efi.iso")
|
||||
qemuIso := qemuFlags.Bool("iso", false, "Set Legacy BIOS boot from 'prefix'.iso")
|
||||
qemuKernel := qemuFlags.Bool("kernel", true, "Set boot using 'prefix'-kernel/-initrd/-cmdline")
|
||||
enableGUI := flags.Bool("gui", false, "Set qemu to use video output instead of stdio")
|
||||
uefiBoot := flags.Bool("uefi", false, "Set UEFI boot from 'prefix'-efi.iso")
|
||||
isoBoot := flags.Bool("iso", false, "Set Legacy BIOS boot from 'prefix'.iso")
|
||||
kernelBoot := flags.Bool("kernel", true, "Set boot using 'prefix'-kernel/-initrd/-cmdline")
|
||||
|
||||
// Paths and settings for Disks and UEFI firware
|
||||
qemuDiskPath := qemuFlags.String("disk", "", "Path to disk image to use")
|
||||
qemuDiskSize := qemuFlags.String("disk-size", "", "Size of disk to create, only created if it doesn't exist")
|
||||
qemuFWPath := qemuFlags.String("fw", "/usr/share/ovmf/bios.bin", "Path to OVMF firmware for UEFI boot")
|
||||
disk := flags.String("disk", "", "Path to disk image to use")
|
||||
diskSz := flags.String("disk-size", "", "Size of disk to create, only created if it doesn't exist")
|
||||
fw := flags.String("fw", "/usr/share/ovmf/bios.bin", "Path to OVMF firmware for UEFI boot")
|
||||
|
||||
// VM configuration
|
||||
qemuArch := qemuFlags.String("arch", "x86_64", "Type of architecture to use, e.g. x86_64, aarch64")
|
||||
qemuCPUs := qemuFlags.String("cpus", "1", "Number of CPUs")
|
||||
qemuMem := qemuFlags.String("mem", "1024", "Amount of memory in MB")
|
||||
arch := flags.String("arch", "x86_64", "Type of architecture to use, e.g. x86_64, aarch64")
|
||||
cpus := flags.String("cpus", "1", "Number of CPUs")
|
||||
mem := flags.String("mem", "1024", "Amount of memory in MB")
|
||||
|
||||
publishFlags := multipleFlag{}
|
||||
qemuFlags.Var(&publishFlags, "publish", "Publish a vm's port(s) to the host (default [])")
|
||||
flags.Var(&publishFlags, "publish", "Publish a vm's port(s) to the host (default [])")
|
||||
|
||||
if err := qemuFlags.Parse(args); err != nil {
|
||||
if err := flags.Parse(args); err != nil {
|
||||
log.Fatal("Unable to parse args")
|
||||
}
|
||||
remArgs := qemuFlags.Args()
|
||||
remArgs := flags.Args()
|
||||
|
||||
if len(remArgs) == 0 {
|
||||
fmt.Println("Please specify the prefix to the image to boot")
|
||||
qemuFlags.Usage()
|
||||
flags.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
prefix := remArgs[0]
|
||||
|
||||
// Print warning if conflicting UEFI and ISO flags are set
|
||||
if *qemuUEFI && *qemuIso {
|
||||
if *uefiBoot && *isoBoot {
|
||||
log.Warnf("Both -iso and -uefi have been used")
|
||||
}
|
||||
|
||||
config := QemuConfig{
|
||||
Prefix: prefix,
|
||||
ISO: *qemuIso,
|
||||
UEFI: *qemuUEFI,
|
||||
Kernel: *qemuKernel,
|
||||
GUI: *qemuGUI,
|
||||
DiskPath: *qemuDiskPath,
|
||||
DiskSize: *qemuDiskSize,
|
||||
FWPath: *qemuFWPath,
|
||||
Arch: *qemuArch,
|
||||
CPUs: *qemuCPUs,
|
||||
Memory: *qemuMem,
|
||||
ISO: *isoBoot,
|
||||
UEFI: *uefiBoot,
|
||||
Kernel: *kernelBoot,
|
||||
GUI: *enableGUI,
|
||||
DiskPath: *disk,
|
||||
DiskSize: *diskSz,
|
||||
FWPath: *fw,
|
||||
Arch: *arch,
|
||||
CPUs: *cpus,
|
||||
Memory: *mem,
|
||||
PublishedPorts: publishFlags,
|
||||
}
|
||||
|
||||
|
@ -66,44 +66,52 @@ guestOS = "other3xlinux-64"
|
||||
|
||||
func runVMware(args []string) {
|
||||
invoked := filepath.Base(os.Args[0])
|
||||
vmwareArgs := flag.NewFlagSet("vmware", flag.ExitOnError)
|
||||
vmwareArgs.Usage = func() {
|
||||
flags := flag.NewFlagSet("vmware", flag.ExitOnError)
|
||||
flags.Usage = func() {
|
||||
fmt.Printf("USAGE: %s run vmware [options] prefix\n\n", invoked)
|
||||
fmt.Printf("'prefix' specifies the path to the VM image.\n")
|
||||
fmt.Printf("\n")
|
||||
fmt.Printf("Options:\n")
|
||||
vmwareArgs.PrintDefaults()
|
||||
flags.PrintDefaults()
|
||||
}
|
||||
vmwareCPUs := vmwareArgs.Int("cpus", 1, "Number of CPUs")
|
||||
vmwareMem := vmwareArgs.Int("mem", 1024, "Amount of memory in MB")
|
||||
vmwareDisk := vmwareArgs.String("disk", "", "Path to disk image to use")
|
||||
vmwareDiskSize := vmwareArgs.String("disk-size", "", "Size of the disk to create, only created if it doesn't exist")
|
||||
cpus := flags.Int("cpus", 1, "Number of CPUs")
|
||||
mem := flags.Int("mem", 1024, "Amount of memory in MB")
|
||||
disk := flags.String("disk", "", "Path to disk image to use")
|
||||
diskSz := flags.String("disk-size", "", "Size of the disk to create, only created if it doesn't exist")
|
||||
state := flags.String("state", "", "Path to directory to keep VM state in")
|
||||
|
||||
if err := vmwareArgs.Parse(args); err != nil {
|
||||
if err := flags.Parse(args); err != nil {
|
||||
log.Fatal("Unable to parse args")
|
||||
}
|
||||
remArgs := vmwareArgs.Args()
|
||||
remArgs := flags.Args()
|
||||
|
||||
if len(remArgs) == 0 {
|
||||
fmt.Println("Please specify the prefix to the image to boot")
|
||||
vmwareArgs.Usage()
|
||||
flags.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
prefix := remArgs[0]
|
||||
|
||||
if *state == "" {
|
||||
*state = prefix + "-state"
|
||||
}
|
||||
if err := os.MkdirAll(*state, 0755); err != nil {
|
||||
log.Fatalf("Could not create state directory: %v", err)
|
||||
}
|
||||
|
||||
var vmrunPath, vmDiskManagerPath string
|
||||
var vmrunArgs []string
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
vmrunPath = "C:\\Program\\ files\\VMware Workstation\\vmrun.exe"
|
||||
vmDiskManagerPath = "C:\\Program\\ files\\VMware Workstation\\vmware-vdiskmanager.exe"
|
||||
vmrunArgs = []string{"-T", "ws", "start", prefix + ".vmx"}
|
||||
vmrunArgs = []string{"-T", "ws", "start"}
|
||||
}
|
||||
|
||||
if runtime.GOOS == "darwin" {
|
||||
vmrunPath = "/Applications/VMware Fusion.app/Contents/Library/vmrun"
|
||||
vmDiskManagerPath = "/Applications/VMware Fusion.app/Contents/Library/vmware-vdiskmanager"
|
||||
vmrunArgs = []string{"-T", "fusion", "start", prefix + ".vmx"}
|
||||
vmrunArgs = []string{"-T", "fusion", "start"}
|
||||
}
|
||||
|
||||
if runtime.GOOS == "linux" {
|
||||
@ -115,7 +123,7 @@ func runVMware(args []string) {
|
||||
log.Fatalf("Unable to find %s within the $PATH", vmrunPath)
|
||||
}
|
||||
vmrunPath = fullVMrunPath
|
||||
vmrunArgs = []string{"-T", "ws", "start", prefix + ".vmx"}
|
||||
vmrunArgs = []string{"-T", "ws", "start"}
|
||||
}
|
||||
|
||||
// Check vmrunPath exists before attempting to execute
|
||||
@ -123,48 +131,50 @@ func runVMware(args []string) {
|
||||
log.Fatalf("ERROR VMware executables can not be found, ensure software is installed")
|
||||
}
|
||||
|
||||
if *vmwareDisk != "" {
|
||||
if *disk == "" && *diskSz != "" {
|
||||
*disk = filepath.Join(*state, "disk.vmdk")
|
||||
}
|
||||
if *disk != "" {
|
||||
// Check vmDiskManagerPath exist before attempting to execute
|
||||
if _, err := os.Stat(vmDiskManagerPath); os.IsNotExist(err) {
|
||||
log.Fatalf("ERROR VMware Disk Manager executables can not be found, ensure software is installed")
|
||||
}
|
||||
|
||||
// If disk doesn't exist then create one, error if disk is unreadable
|
||||
if _, err := os.Stat(*vmwareDisk); err != nil {
|
||||
if _, err := os.Stat(*disk); err != nil {
|
||||
if os.IsPermission(err) {
|
||||
log.Fatalf("Unable to read file [%s], please check permissions", *vmwareDisk)
|
||||
log.Fatalf("Unable to read file [%s], please check permissions", *disk)
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
log.Infof("Creating new VMware disk [%s]", *vmwareDisk)
|
||||
vmDiskCmd := exec.Command(vmDiskManagerPath, "-c", "-s", *vmwareDiskSize, "-a", "lsilogic", "-t", "0", *vmwareDisk)
|
||||
log.Infof("Creating new VMware disk [%s]", *disk)
|
||||
vmDiskCmd := exec.Command(vmDiskManagerPath, "-c", "-s", *diskSz, "-a", "lsilogic", "-t", "0", *disk)
|
||||
if err = vmDiskCmd.Run(); err != nil {
|
||||
log.Fatalf("Error creating disk [%s]: %s", *vmwareDisk, err.Error())
|
||||
log.Fatalf("Error creating disk [%s]: %v", *disk, err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Infof("Using existing disk [%s]", *vmwareDisk)
|
||||
log.Infof("Using existing disk [%s]", *disk)
|
||||
}
|
||||
}
|
||||
|
||||
// Build the contents of the VMWare .vmx file
|
||||
vmx := buildVMX(*vmwareCPUs, *vmwareMem, *vmwareDisk, prefix)
|
||||
|
||||
vmx := buildVMX(*cpus, *mem, *disk, prefix)
|
||||
if vmx == "" {
|
||||
log.Fatalf("VMware .vmx file could not be generated, please confirm inputs")
|
||||
}
|
||||
|
||||
// Create the .vmx file
|
||||
err := ioutil.WriteFile(prefix+".vmx", []byte(vmx), 0644)
|
||||
|
||||
vmxPath := filepath.Join(*state, "linuxkit.vmx")
|
||||
err := ioutil.WriteFile(vmxPath, []byte(vmx), 0644)
|
||||
if err != nil {
|
||||
log.Fatalf("Error writing .vmx file")
|
||||
log.Fatalf("Error writing .vmx file: %v", err)
|
||||
}
|
||||
vmrunArgs = append(vmrunArgs, vmxPath)
|
||||
|
||||
cmd := exec.Command(vmrunPath, vmrunArgs...)
|
||||
out, err := cmd.Output()
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Error starting vmrun")
|
||||
log.Fatalf("Error starting vmrun: %v", err)
|
||||
}
|
||||
|
||||
// check there is output to push to logging
|
||||
@ -185,7 +195,10 @@ func buildVMX(cpus int, mem int, persistentDisk string, prefix string) string {
|
||||
returnString += fmt.Sprintf(vmxCdrom, cdromPath)
|
||||
}
|
||||
|
||||
vmdkPath := prefix + ".vmdk"
|
||||
vmdkPath, err := filepath.Abs(prefix + ".vmdk")
|
||||
if err != nil {
|
||||
log.Fatalf("Unable get absolute path for boot vmdk: %v", err)
|
||||
}
|
||||
if _, err := os.Stat(vmdkPath); err != nil {
|
||||
if os.IsPermission(err) {
|
||||
log.Fatalf("Unable to read file [%s], please check permissions", vmdkPath)
|
||||
@ -198,6 +211,10 @@ func buildVMX(cpus int, mem int, persistentDisk string, prefix string) string {
|
||||
}
|
||||
// Add persistentDisk to the vmx if it has been specified in the args.
|
||||
if persistentDisk != "" {
|
||||
persistentDisk, err = filepath.Abs(persistentDisk)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable get absolute path for persistent disk: %v", err)
|
||||
}
|
||||
returnString += fmt.Sprintf(vmxDiskPersistent, persistentDisk)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user