mirror of
https://github.com/linuxkit/linuxkit.git
synced 2026-04-11 05:45:43 +00:00
To enable this bump github.com/Azure/go-ansiterm and github.com/docker/docker to their latest version which have switched to lower case. This in turn requires bumping golang.org/x/sys since github.com/docker/docker/pkg/term now uses `unix.IoctlGetTermios`. I picked the revision from docker/docker's vendor.conf. Signed-off-by: Ian Campbell <ijc@docker.com>
246 lines
6.7 KiB
Go
246 lines
6.7 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strconv"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
//Version 12 relates to Fusion 8 and WS 12
|
|
//virtualHW.version = "12"
|
|
|
|
const vmxHW string = `config.version = "8"
|
|
virtualHW.version = "12"
|
|
vmci0.present = "TRUE"
|
|
floppy0.present = "FALSE"
|
|
displayName = "%s"
|
|
numvcpus = "%d"
|
|
memsize = "%d"
|
|
scsi0.present = "TRUE"
|
|
scsi0.sharedBus = "none"
|
|
scsi0.virtualDev = "lsilogic"
|
|
`
|
|
|
|
const vmxDisk string = `
|
|
scsi0:0.present = "TRUE"
|
|
scsi0:0.fileName = "%s"
|
|
scsi0:0.deviceType = "scsi-hardDisk"
|
|
`
|
|
|
|
const vmxDiskPersistent string = `scsi0:1.present = "TRUE"
|
|
scsi0:1.fileName = "%s"
|
|
scsi0:1.deviceType = "scsi-hardDisk"
|
|
`
|
|
|
|
const vmxCdrom string = `ide1:0.present = "TRUE"
|
|
ide1:0.fileName = "%s"
|
|
ide1:0.deviceType = "cdrom-image"
|
|
`
|
|
|
|
const vmxPCI string = `pciBridge0.present = "TRUE"
|
|
pciBridge4.present = "TRUE"
|
|
pciBridge4.virtualDev = "pcieRootPort"
|
|
pciBridge4.functions = "8"
|
|
pciBridge5.present = "TRUE"
|
|
pciBridge5.virtualDev = "pcieRootPort"
|
|
pciBridge5.functions = "8"
|
|
pciBridge6.present = "TRUE"
|
|
pciBridge6.virtualDev = "pcieRootPort"
|
|
pciBridge6.functions = "8"
|
|
pciBridge7.present = "TRUE"
|
|
pciBridge7.virtualDev = "pcieRootPort"
|
|
pciBridge7.functions = "8"
|
|
ethernet0.pciSlotNumber = "32"
|
|
ethernet0.present = "TRUE"
|
|
ethernet0.virtualDev = "e1000"
|
|
ethernet0.networkName = "Inside"
|
|
ethernet0.generatedAddressOffset = "0"
|
|
guestOS = "other3xlinux-64"
|
|
`
|
|
|
|
func runVMware(args []string) {
|
|
invoked := filepath.Base(os.Args[0])
|
|
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")
|
|
flags.PrintDefaults()
|
|
}
|
|
cpus := flags.Int("cpus", 1, "Number of CPUs")
|
|
mem := flags.Int("mem", 1024, "Amount of memory in MB")
|
|
var disks Disks
|
|
flags.Var(&disks, "disk", "Disk config. [file=]path[,size=1G]")
|
|
state := flags.String("state", "", "Path to directory to keep VM state in")
|
|
|
|
if err := flags.Parse(args); err != nil {
|
|
log.Fatal("Unable to parse args")
|
|
}
|
|
remArgs := flags.Args()
|
|
|
|
if len(remArgs) == 0 {
|
|
fmt.Println("Please specify the prefix to the image to boot")
|
|
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
|
|
|
|
switch runtime.GOOS {
|
|
case "windows":
|
|
vmrunPath = "C:\\Program\\ files\\VMware Workstation\\vmrun.exe"
|
|
vmDiskManagerPath = "C:\\Program\\ files\\VMware Workstation\\vmware-vdiskmanager.exe"
|
|
vmrunArgs = []string{"-T", "ws", "start"}
|
|
case "darwin":
|
|
vmrunPath = "/Applications/VMware Fusion.app/Contents/Library/vmrun"
|
|
vmDiskManagerPath = "/Applications/VMware Fusion.app/Contents/Library/vmware-vdiskmanager"
|
|
vmrunArgs = []string{"-T", "fusion", "start"}
|
|
default:
|
|
vmrunPath = "vmrun"
|
|
vmDiskManagerPath = "vmware-vdiskmanager"
|
|
fullVMrunPath, err := exec.LookPath(vmrunPath)
|
|
if err != nil {
|
|
// Kept as separate error as people may manually change their environment vars
|
|
log.Fatalf("Unable to find %s within the $PATH", vmrunPath)
|
|
}
|
|
vmrunPath = fullVMrunPath
|
|
vmrunArgs = []string{"-T", "ws", "start"}
|
|
}
|
|
|
|
// Check vmrunPath exists before attempting to execute
|
|
if _, err := os.Stat(vmrunPath); os.IsNotExist(err) {
|
|
log.Fatalf("ERROR VMware executables can not be found, ensure software is installed")
|
|
}
|
|
|
|
for i, d := range disks {
|
|
id := ""
|
|
if i != 0 {
|
|
id = strconv.Itoa(i)
|
|
}
|
|
if d.Size != 0 && d.Path == "" {
|
|
d.Path = filepath.Join(*state, "disk"+id+".vmdk")
|
|
}
|
|
if d.Format != "" && d.Format != "vmdk" {
|
|
log.Fatalf("only vmdk supported for VMware driver")
|
|
}
|
|
if d.Path == "" {
|
|
log.Fatalf("disk specified with no size or name")
|
|
}
|
|
disks[i] = d
|
|
}
|
|
|
|
for _, d := range disks {
|
|
// 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(d.Path); err != nil {
|
|
if os.IsPermission(err) {
|
|
log.Fatalf("Unable to read file [%s], please check permissions", d.Path)
|
|
} else if os.IsNotExist(err) {
|
|
log.Infof("Creating new VMware disk [%s]", d.Path)
|
|
vmDiskCmd := exec.Command(vmDiskManagerPath, "-c", "-s", fmt.Sprintf("%dMB", d.Size), "-a", "lsilogic", "-t", "0", d.Path)
|
|
if err = vmDiskCmd.Run(); err != nil {
|
|
log.Fatalf("Error creating disk [%s]: %v", d.Path, err)
|
|
}
|
|
} else {
|
|
log.Fatalf("Unable to read file [%s]: %v", d.Path, err)
|
|
}
|
|
} else {
|
|
log.Infof("Using existing disk [%s]", d.Path)
|
|
}
|
|
}
|
|
|
|
if len(disks) > 1 {
|
|
log.Fatalf("VMware driver currently only supports a single disk")
|
|
}
|
|
|
|
disk := ""
|
|
if len(disks) == 1 {
|
|
disk = disks[0].Path
|
|
}
|
|
|
|
// Build the contents of the VMWare .vmx file
|
|
vmx := buildVMX(*cpus, *mem, disk, prefix)
|
|
if vmx == "" {
|
|
log.Fatalf("VMware .vmx file could not be generated, please confirm inputs")
|
|
}
|
|
|
|
// Create the .vmx file
|
|
vmxPath := filepath.Join(*state, "linuxkit.vmx")
|
|
err := ioutil.WriteFile(vmxPath, []byte(vmx), 0644)
|
|
if err != nil {
|
|
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: %v", err)
|
|
}
|
|
|
|
// check there is output to push to logging
|
|
if len(out) > 0 {
|
|
log.Info(out)
|
|
}
|
|
}
|
|
|
|
func buildVMX(cpus int, mem int, persistentDisk string, prefix string) string {
|
|
// CD-ROM can be added for use in a further release
|
|
cdromPath := ""
|
|
|
|
var returnString string
|
|
|
|
returnString += fmt.Sprintf(vmxHW, prefix, cpus, mem)
|
|
|
|
if cdromPath != "" {
|
|
returnString += fmt.Sprintf(vmxCdrom, cdromPath)
|
|
}
|
|
|
|
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)
|
|
}
|
|
if os.IsNotExist(err) {
|
|
log.Fatalf("File [%s] does not exist in current directory", vmdkPath)
|
|
}
|
|
} else {
|
|
returnString += fmt.Sprintf(vmxDisk, vmdkPath)
|
|
}
|
|
// 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)
|
|
}
|
|
|
|
returnString += vmxPCI
|
|
return returnString
|
|
}
|