Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
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()
}
Пример #5
0
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
}
Пример #6
0
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
}
Пример #7
0
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()
}