func LaunchVM(c *VMConfig) (*exec.Cmd, error) { exists, err := vmExists(c.Name) if err != nil { return nil, err } if !exists { err = vmCreate(c) if err != nil { return nil, err } } StoreConfig(c) cmd, err := VBoxHeadless("--startvm", c.Name) if err != nil { return nil, err } conn, err := util.ConnectAndWait("unix", c.sockPath()) if err != nil { return nil, err } go io.Copy(conn, os.Stdin) go io.Copy(os.Stdout, conn) return cmd, nil }
func UploadRPM(r *util.Repo, hypervisor string, image string, config *util.Config, verbose bool) error { file := r.ImagePath(hypervisor, image) vmconfig := &VMConfig{ Image: file, Verbose: verbose, Memory: 64, Networking: "nat", NatRules: []nat.Rule{nat.Rule{GuestPort: "10000", HostPort: "10000"}}, BackingFile: false, } qemu, err := LaunchVM(vmconfig) if err != nil { return err } defer qemu.Process.Kill() conn, err := util.ConnectAndWait("tcp", "localhost:10000") if err != nil { return err } cmd := exec.Command("rpm2cpio", config.RpmBase.Filename()) cmd.Stdout = conn err = cmd.Start() if err != nil { return err } defer cmd.Wait() err = qemu.Wait() conn.Close() return err }
func SetArgs(r *util.Repo, hypervisor, image string, args string) error { file := r.ImagePath(hypervisor, image) cmd := exec.Command("qemu-nbd", file) stdout, err := cmd.StdoutPipe() if err != nil { return err } stderr, err := cmd.StderrPipe() if err != nil { return err } err = cmd.Start() if err != nil { return err } go io.Copy(os.Stdout, stdout) go io.Copy(os.Stderr, stderr) conn, err := util.ConnectAndWait("tcp", "localhost:10809") if err != nil { return err } session := &nbd.NbdSession{ Conn: conn, Handle: 0, } if err := session.Handshake(); err != nil { return err } padding := 512 - (len(args) % 512) data := append([]byte(args), make([]byte, padding)...) if err := session.Write(512, data); err != nil { return err } if err := session.Flush(); err != nil { return err } if err := session.Disconnect(); err != nil { return err } conn.Close() cmd.Wait() return nil }
func UploadFiles(r *util.Repo, hypervisor string, image string, config *util.Config, verbose bool) error { file := r.ImagePath(hypervisor, image) vmconfig := &VMConfig{ Image: file, Verbose: verbose, Memory: 64, Networking: "nat", NatRules: []nat.Rule{nat.Rule{GuestPort: "10000", HostPort: "10000"}}, BackingFile: false, } cmd, err := LaunchVM(vmconfig) if err != nil { return err } defer cmd.Process.Kill() conn, err := util.ConnectAndWait("tcp", "localhost:10000") if err != nil { return err } if _, err = os.Stat(config.Rootfs); !os.IsNotExist(err) { err = filepath.Walk(config.Rootfs, func(src string, info os.FileInfo, _ error) error { if info.IsDir() { return nil } dst := strings.Replace(src, config.Rootfs, "", -1) if verbose { fmt.Println(src + " --> " + dst) } return copyFile(conn, src, dst) }) } for dst, src := range config.Files { err = copyFile(conn, src, dst) if verbose { fmt.Println(src + " --> " + dst) } if err != nil { return err } } cpio.WritePadded(conn, cpio.ToWireFormat("TRAILER!!!", 0, 0)) conn.Close() return cmd.Wait() }
func LaunchVM(c *VMConfig) (*exec.Cmd, error) { if _, err := os.Stat(c.VMXFile); os.IsNotExist(err) { dir := c.InstanceDir err := os.MkdirAll(dir, 0777) if err != nil { fmt.Printf("mkdir failed: %s", dir) return nil, err } cmd := util.CopyFile(c.OriginalVMDK, c.Image) _, err = cmd.Output() if err != nil { fmt.Printf("cp failed: %s", c.OriginalVMDK) return nil, err } err = vmCreateVMXFile(c) if err != nil { fmt.Printf("Create VMXFile failed: %s", c.VMXFile) return nil, err } } StoreConfig(c) cmd, err := vmxRun("-T", "ws", "start", c.VMXFile, "nogui") if err != nil { return nil, err } conn, err := util.ConnectAndWait("unix", c.sockPath()) if err != nil { return nil, err } done := make(chan bool) go io.Copy(conn, os.Stdin) go doRead(done, conn) // Wait until the serial connection is disconnected <-done return cmd, nil }
func UploadRPM(r *util.Repo, hypervisor string, image string, template *core.Template, verbose bool, mem string) error { file := r.ImagePath(hypervisor, image) size, err := util.ParseMemSize(mem) if err != nil { return err } vmconfig := &qemu.VMConfig{ Image: file, Verbose: verbose, Memory: size, Networking: "nat", NatRules: []nat.Rule{nat.Rule{GuestPort: "10000", HostPort: "10000"}}, BackingFile: false, } vm, err := qemu.LaunchVM(vmconfig) if err != nil { return err } defer vm.Process.Kill() conn, err := util.ConnectAndWait("tcp", "localhost:10000") if err != nil { return err } cmd := exec.Command("rpm2cpio", template.RpmBase.Filename()) cmd.Stdout = conn err = cmd.Start() if err != nil { return err } defer cmd.Wait() err = vm.Wait() conn.Close() return err }
func UploadFiles(r *util.Repo, hypervisor string, image string, t *core.Template, verbose bool, mem string) error { file := r.ImagePath(hypervisor, image) size, err := util.ParseMemSize(mem) if err != nil { return err } vmconfig := &qemu.VMConfig{ Image: file, Verbose: verbose, Memory: size, Networking: "nat", NatRules: []nat.Rule{nat.Rule{GuestPort: "10000", HostPort: "10000"}}, BackingFile: false, } cmd, err := qemu.VMCommand(vmconfig) if err != nil { return err } stdout, err := cmd.StdoutPipe() if err != nil { return err } if err := cmd.Start(); err != nil { return err } defer cmd.Process.Kill() scanner := bufio.NewScanner(stdout) for scanner.Scan() { text := scanner.Text() if verbose { fmt.Println(text) } if text == "Waiting for connection from host..." { break } } if verbose { go io.Copy(os.Stdout, stdout) } conn, err := util.ConnectAndWait("tcp", "localhost:10000") if err != nil { return err } rootfsFiles := make(map[string]string) if _, err = os.Stat(t.Rootfs); !os.IsNotExist(err) { err = filepath.Walk(t.Rootfs, func(src string, info os.FileInfo, _ error) error { dst := strings.Replace(src, t.Rootfs, "", 1) if dst != "" { rootfsFiles[dst] = src } return nil }) } fmt.Println("Uploading files...") bar := pb.New(len(rootfsFiles) + len(t.Files)) if !verbose { bar.Start() } for dst, src := range rootfsFiles { err = copyFile(conn, src, dst) if verbose { fmt.Println(src + " --> " + dst) } else { bar.Increment() } if err != nil { return err } } for dst, src := range t.Files { err = copyFile(conn, src, dst) if verbose { fmt.Println(src + " --> " + dst) } else { bar.Increment() } if err != nil { return err } } cpio.WritePadded(conn, cpio.ToWireFormat("TRAILER!!!", 0, 0)) conn.Close() return cmd.Wait() }