/* * Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. */ package vmwarevsphere import ( "fmt" "strconv" "strings" "github.com/docker/machine/drivers/vmwarevsphere/errors" "github.com/docker/machine/libmachine/log" ) type VcConn struct { driver *Driver } func NewVcConn(driver *Driver) VcConn { return VcConn{driver: driver} } func (conn VcConn) DatastoreLs(path string) (string, error) { args := []string{"datastore.ls"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--ds=%s", conn.driver.Datastore)) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, path) stdout, stderr, err := govcOutErr(args...) if stderr == "" && err == nil { return stdout, nil } return "", errors.NewDatastoreError(conn.driver.Datastore, "ls", stderr) } func (conn VcConn) DatastoreMkdir(dirName string) error { _, err := conn.DatastoreLs(dirName) if err == nil { return nil } log.Infof("Creating directory %s on datastore %s of vCenter %s... ", dirName, conn.driver.Datastore, conn.driver.IP) args := []string{"datastore.mkdir"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--ds=%s", conn.driver.Datastore)) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, dirName) _, stderr, err := govcOutErr(args...) if stderr != "" { return errors.NewDatastoreError(conn.driver.Datastore, "mkdir", stderr) } if err != nil { return err } return nil } func (conn VcConn) DatastoreUpload(localPath, destination string) error { stdout, err := conn.DatastoreLs(destination) if err == nil && strings.Contains(stdout, isoFilename) { log.Infof("boot2docker ISO already uploaded, skipping upload... ") return nil } log.Infof("Uploading %s to %s on datastore %s of vCenter %s... ", localPath, destination, conn.driver.Datastore, conn.driver.IP) dsPath := fmt.Sprintf("%s/%s", destination, isoFilename) args := []string{"datastore.upload"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--ds=%s", conn.driver.Datastore)) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, localPath) args = append(args, dsPath) _, stderr, err := govcOutErr(args...) if stderr == "" && err == nil { return nil } return errors.NewDatastoreError(conn.driver.Datacenter, "upload", stderr) } func (conn VcConn) VMInfo() (string, error) { args := []string{"vm.info"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, conn.driver.MachineName) stdout, stderr, err := govcOutErr(args...) if strings.Contains(stdout, "Name") && stderr == "" && err == nil { return stdout, nil } return "", errors.NewVMError("find", conn.driver.MachineName, "VM not found") } func (conn VcConn) VMCreate(isoPath string) error { log.Infof("Creating virtual machine %s of vCenter %s... ", conn.driver.MachineName, conn.driver.IP) args := []string{"vm.create"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--net=%s", conn.driver.Network)) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, fmt.Sprintf("--ds=%s", conn.driver.Datastore)) args = append(args, fmt.Sprintf("--iso=%s", isoPath)) memory := strconv.Itoa(conn.driver.Memory) args = append(args, fmt.Sprintf("--m=%s", memory)) cpu := strconv.Itoa(conn.driver.CPU) args = append(args, fmt.Sprintf("--c=%s", cpu)) args = append(args, "--disk.controller=pvscsi") args = append(args, "--net.adapter=vmxnet3") args = append(args, "--on=false") if conn.driver.Pool != "" { args = append(args, fmt.Sprintf("--pool=%s", conn.driver.Pool)) } if conn.driver.HostIP != "" { args = append(args, fmt.Sprintf("--host.ip=%s", conn.driver.HostIP)) } args = append(args, conn.driver.MachineName) _, stderr, err := govcOutErr(args...) if stderr == "" && err == nil { return nil } return errors.NewVMError("create", conn.driver.MachineName, stderr) } func (conn VcConn) VMPowerOn() error { log.Infof("Powering on virtual machine %s of vCenter %s... ", conn.driver.MachineName, conn.driver.IP) args := []string{"vm.power"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, "-on") args = append(args, conn.driver.MachineName) _, stderr, err := govcOutErr(args...) if stderr == "" && err == nil { return nil } return errors.NewVMError("power on", conn.driver.MachineName, stderr) } func (conn VcConn) VMPowerOff() error { log.Infof("Powering off virtual machine %s of vCenter %s... ", conn.driver.MachineName, conn.driver.IP) args := []string{"vm.power"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, "-off") args = append(args, conn.driver.MachineName) _, stderr, err := govcOutErr(args...) if stderr == "" && err == nil { return nil } return errors.NewVMError("power on", conn.driver.MachineName, stderr) } func (conn VcConn) VMShutdown() error { log.Infof("Powering off virtual machine %s of vCenter %s... ", conn.driver.MachineName, conn.driver.IP) args := []string{"vm.power"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, "-s") args = append(args, conn.driver.MachineName) _, stderr, err := govcOutErr(args...) if stderr == "" && err == nil { return nil } return errors.NewVMError("power on", conn.driver.MachineName, stderr) } func (conn VcConn) VMDestroy() error { log.Infof("Deleting virtual machine %s of vCenter %s... ", conn.driver.MachineName, conn.driver.IP) args := []string{"vm.destroy"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, conn.driver.MachineName) _, stderr, err := govcOutErr(args...) if stderr == "" && err == nil { return nil } return errors.NewVMError("delete", conn.driver.MachineName, stderr) } func (conn VcConn) VMDiskCreate() error { args := []string{"vm.disk.create"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, fmt.Sprintf("--vm=%s", conn.driver.MachineName)) args = append(args, fmt.Sprintf("--ds=%s", conn.driver.Datastore)) args = append(args, fmt.Sprintf("--name=%s/%s", conn.driver.MachineName, conn.driver.MachineName)) diskSize := strconv.Itoa(conn.driver.DiskSize) args = append(args, fmt.Sprintf("--size=%sMiB", diskSize)) _, stderr, err := govcOutErr(args...) if stderr == "" && err == nil { return nil } return errors.NewVMError("add network", conn.driver.MachineName, stderr) } func (conn VcConn) VMAttachNetwork() error { args := []string{"vm.network.add"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, fmt.Sprintf("--vm=%s", conn.driver.MachineName)) args = append(args, fmt.Sprintf("--net=%s", conn.driver.Network)) _, stderr, err := govcOutErr(args...) if stderr == "" && err == nil { return nil } return errors.NewVMError("add network", conn.driver.MachineName, stderr) } func (conn VcConn) VMFetchIP() (string, error) { args := []string{"vm.ip"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, conn.driver.MachineName) stdout, stderr, err := govcOutErr(args...) if stderr == "" && err == nil { return stdout, nil } return "", errors.NewVMError("fetching IP", conn.driver.MachineName, stderr) } func (conn VcConn) GuestMkdir(guestUser, guestPass, dirName string) error { args := []string{"guest.mkdir"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, fmt.Sprintf("--l=%s:%s", guestUser, guestPass)) args = append(args, fmt.Sprintf("--vm=%s", conn.driver.MachineName)) args = append(args, "-p") args = append(args, dirName) _, stderr, err := govcOutErr(args...) if stderr == "" && err == nil { return nil } return errors.NewGuestError("mkdir", conn.driver.MachineName, stderr) } func (conn VcConn) GuestUpload(guestUser, guestPass, localPath, remotePath string) error { args := []string{"guest.upload"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, fmt.Sprintf("--l=%s:%s", guestUser, guestPass)) args = append(args, fmt.Sprintf("--vm=%s", conn.driver.MachineName)) args = append(args, "-f") args = append(args, localPath) args = append(args, remotePath) _, stderr, err := govcOutErr(args...) if stderr == "" && err == nil { return nil } return errors.NewGuestError("upload", conn.driver.MachineName, stderr) } func (conn VcConn) GuestStart(guestUser, guestPass, remoteBin, remoteArguments string) error { args := []string{"guest.start"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, fmt.Sprintf("--l=%s:%s", guestUser, guestPass)) args = append(args, fmt.Sprintf("--vm=%s", conn.driver.MachineName)) args = append(args, remoteBin) args = append(args, remoteArguments) _, stderr, err := govcOutErr(args...) if stderr == "" && err == nil { return nil } return errors.NewGuestError("start", conn.driver.MachineName, stderr) } func (conn VcConn) GuestDownload(guestUser, guestPass, remotePath, localPath string) error { args := []string{"guest.download"} args = conn.AppendConnectionString(args) args = append(args, fmt.Sprintf("--dc=%s", conn.driver.Datacenter)) args = append(args, fmt.Sprintf("--l=%s:%s", guestUser, guestPass)) args = append(args, fmt.Sprintf("--vm=%s", conn.driver.MachineName)) args = append(args, remotePath) args = append(args, localPath) _, stderr, err := govcOutErr(args...) if stderr == "" && err == nil { return nil } return errors.NewGuestError("download", conn.driver.MachineName, stderr) } func (conn VcConn) AppendConnectionString(args []string) []string { args = append(args, fmt.Sprintf("--u=%s:%s@%s", conn.driver.Username, conn.driver.Password, conn.driver.IP)) args = append(args, "--k=true") return args }