Blame internal/boot/vmwaretest/vmware.go

Packit Service 509fd4
// +build integration
Packit Service 509fd4
Packit Service 509fd4
package vmwaretest
Packit Service 509fd4
Packit Service 509fd4
import (
Packit Service 509fd4
	"errors"
Packit Service 509fd4
	"fmt"
Packit Service 509fd4
	"io/ioutil"
Packit Service 509fd4
	"os"
Packit Service 509fd4
	"path/filepath"
Packit Service 509fd4
	"strings"
Packit Service 509fd4
Packit Service 509fd4
	// importing the packages registers these cli commands
Packit Service 509fd4
	"github.com/vmware/govmomi/govc/cli"
Packit Service 509fd4
	_ "github.com/vmware/govmomi/govc/datastore"
Packit Service 509fd4
	_ "github.com/vmware/govmomi/govc/importx"
Packit Service 509fd4
	_ "github.com/vmware/govmomi/govc/vm"
Packit Service 509fd4
	_ "github.com/vmware/govmomi/govc/vm/guest"
Packit Service 509fd4
)
Packit Service 509fd4
Packit Service 509fd4
const WaitTimeout = 6000 // in seconds
Packit Service 509fd4
Packit Service 509fd4
type AuthOptions struct {
Packit Service 509fd4
	Host       string
Packit Service 509fd4
	Username   string
Packit Service 509fd4
	Password   string
Packit Service 509fd4
	Datacenter string
Packit Service 509fd4
	Cluster    string
Packit Service 509fd4
	Network    string
Packit Service 509fd4
	Datastore  string
Packit Service 509fd4
	Folder     string
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func AuthOptionsFromEnv() (*AuthOptions, error) {
Packit Service 509fd4
	host, hostExists := os.LookupEnv("GOVMOMI_URL")
Packit Service 509fd4
	username, userExists := os.LookupEnv("GOVMOMI_USERNAME")
Packit Service 509fd4
	password, pwdExists := os.LookupEnv("GOVMOMI_PASSWORD")
Packit Service 509fd4
	datacenter, dcExists := os.LookupEnv("GOVMOMI_DATACENTER")
Packit Service 509fd4
	cluster, clusterExists := os.LookupEnv("GOVMOMI_CLUSTER")
Packit Service 509fd4
	network, netExists := os.LookupEnv("GOVMOMI_NETWORK")
Packit Service 509fd4
	datastore, dsExists := os.LookupEnv("GOVMOMI_DATASTORE")
Packit Service 509fd4
	folder, folderExists := os.LookupEnv("GOVMOMI_FOLDER")
Packit Service 509fd4
Packit Service 509fd4
	// If only one/two of them are not set, then fail
Packit Service 509fd4
	if !hostExists {
Packit Service 509fd4
		return nil, errors.New("GOVMOMI_URL not set")
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	if !userExists {
Packit Service 509fd4
		return nil, errors.New("GOVMOMI_USERNAME not set")
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	if !pwdExists {
Packit Service 509fd4
		return nil, errors.New("GOVMOMI_PASSWORD not set")
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	if !dcExists {
Packit Service 509fd4
		return nil, errors.New("GOVMOMI_DATACENTER not set")
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	if !clusterExists {
Packit Service 509fd4
		return nil, errors.New("GOVMOMI_CLUSTER not set")
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	if !netExists {
Packit Service 509fd4
		return nil, errors.New("GOVMOMI_NETWORK not set")
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	if !dsExists {
Packit Service 509fd4
		return nil, errors.New("GOVMOMI_DATASTORE not set")
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	if !folderExists {
Packit Service 509fd4
		return nil, errors.New("GOVMOMI_FOLDER not set")
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	return &AuthOptions{
Packit Service 509fd4
		Host:       host,
Packit Service 509fd4
		Username:   username,
Packit Service 509fd4
		Password:   password,
Packit Service 509fd4
		Datacenter: datacenter,
Packit Service 509fd4
		Cluster:    cluster,
Packit Service 509fd4
		Network:    network,
Packit Service 509fd4
		Datastore:  datastore,
Packit Service 509fd4
		Folder:     folder,
Packit Service 509fd4
	}, nil
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func ImportImage(creds *AuthOptions, imagePath, imageName string) error {
Packit Service 509fd4
	args := []string{
Packit Service 509fd4
		"import.vmdk",
Packit Service 509fd4
		fmt.Sprintf("-u=%s:%s@%s", creds.Username, creds.Password, creds.Host),
Packit Service 509fd4
		"-k=true",
Packit Service 509fd4
		fmt.Sprintf("-pool=%s/Resources", creds.Cluster),
Packit Service 509fd4
		fmt.Sprintf("-dc=%s", creds.Datacenter),
Packit Service 509fd4
		fmt.Sprintf("-ds=%s", creds.Datastore),
Packit Service 509fd4
		imagePath,
Packit Service 509fd4
		imageName,
Packit Service 509fd4
	}
Packit Service 509fd4
	retcode := cli.Run(args)
Packit Service 509fd4
Packit Service 509fd4
	if retcode != 0 {
Packit Service 509fd4
		return errors.New("importing vmdk failed")
Packit Service 509fd4
	}
Packit Service 509fd4
	return nil
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func DeleteImage(creds *AuthOptions, directoryName string) error {
Packit Service 509fd4
	retcode := cli.Run([]string{
Packit Service 509fd4
		"datastore.rm",
Packit Service 509fd4
		"-f=true",
Packit Service 509fd4
		fmt.Sprintf("-u=%s:%s@%s", creds.Username, creds.Password, creds.Host),
Packit Service 509fd4
		"-k=true",
Packit Service 509fd4
		fmt.Sprintf("-dc=%s", creds.Datacenter),
Packit Service 509fd4
		fmt.Sprintf("-ds=%s", creds.Datastore),
Packit Service 509fd4
		directoryName + "*", // because vm.create creates another directory with _1 prefix
Packit Service 509fd4
	})
Packit Service 509fd4
Packit Service 509fd4
	if retcode != 0 {
Packit Service 509fd4
		return errors.New("deleting directory failed")
Packit Service 509fd4
	}
Packit Service 509fd4
	return nil
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func runWithStdout(args []string) (string, int) {
Packit Service 509fd4
	oldStdout := os.Stdout
Packit Service 509fd4
	r, w, _ := os.Pipe()
Packit Service 509fd4
	os.Stdout = w
Packit Service 509fd4
Packit Service 509fd4
	retcode := cli.Run(args)
Packit Service 509fd4
Packit Service 509fd4
	w.Close()
Packit Service 509fd4
	out, _ := ioutil.ReadAll(r)
Packit Service 509fd4
	os.Stdout = oldStdout
Packit Service 509fd4
Packit Service 509fd4
	return strings.TrimSpace(string(out)), retcode
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func WithBootedImage(creds *AuthOptions, imagePath, imageName, publicKey string, f func(address string) error) (retErr error) {
Packit Service 509fd4
	vmdkBaseName := filepath.Base(imagePath)
Packit Service 509fd4
Packit Service 509fd4
	args := []string{
Packit Service 509fd4
		"vm.create",
Packit Service 509fd4
		fmt.Sprintf("-u=%s:%s@%s", creds.Username, creds.Password, creds.Host),
Packit Service 509fd4
		"-k=true",
Packit Service 509fd4
		fmt.Sprintf("-pool=%s/Resources", creds.Cluster),
Packit Service 509fd4
		fmt.Sprintf("-dc=%s", creds.Datacenter),
Packit Service 509fd4
		fmt.Sprintf("-ds=%s", creds.Datastore),
Packit Service 509fd4
		fmt.Sprintf("-folder=%s", creds.Folder),
Packit Service 509fd4
		fmt.Sprintf("-net=%s", creds.Network),
Packit Service 509fd4
		"-m=2048", "-g=rhel8_64Guest", "-on=true", "-firmware=bios",
Packit Service 509fd4
		fmt.Sprintf("-disk=%s/%s", imageName, vmdkBaseName),
Packit Service 509fd4
		"--disk.controller=ide",
Packit Service 509fd4
		imageName,
Packit Service 509fd4
	}
Packit Service 509fd4
	retcode := cli.Run(args)
Packit Service 509fd4
	if retcode != 0 {
Packit Service 509fd4
		return errors.New("Creating VM from vmdk failed")
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	defer func() {
Packit Service 509fd4
		args = []string{
Packit Service 509fd4
			"vm.destroy",
Packit Service 509fd4
			fmt.Sprintf("-u=%s:%s@%s", creds.Username, creds.Password, creds.Host),
Packit Service 509fd4
			"-k=true",
Packit Service 509fd4
			imageName,
Packit Service 509fd4
		}
Packit Service 509fd4
		retcode := cli.Run(args)
Packit Service 509fd4
Packit Service 509fd4
		if retcode != 0 {
Packit Service 509fd4
			fmt.Printf("Deleting VM %s failed", imageName)
Packit Service 509fd4
			return
Packit Service 509fd4
		}
Packit Service 509fd4
	}()
Packit Service 509fd4
Packit Service 509fd4
	// note: by default this will wait/block until an IP address is returned
Packit Service 509fd4
	// note: using exec() instead of running the command b/c .Run() returns an int
Packit Service 509fd4
	args = []string{
Packit Service 509fd4
		"vm.ip",
Packit Service 509fd4
		fmt.Sprintf("-u=%s:%s@%s", creds.Username, creds.Password, creds.Host),
Packit Service 509fd4
		"-k=true",
Packit Service 509fd4
		imageName,
Packit Service 509fd4
	}
Packit Service 509fd4
	ipAddress, retcode := runWithStdout(args)
Packit Service 509fd4
Packit Service 509fd4
	if retcode != 0 {
Packit Service 509fd4
		return errors.New("Getting IP address for VM failed")
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	// Disabled b/c of https://github.com/vmware/govmomi/issues/2054
Packit Service 509fd4
	// upload public key on the VM
Packit Service 509fd4
	//args = []string{
Packit Service 509fd4
	//	"guest.mkdir",
Packit Service 509fd4
	//	fmt.Sprintf("-u=%s:%s@%s", creds.Username, creds.Password, creds.Host),
Packit Service 509fd4
	//	"-k=true",
Packit Service 509fd4
	//	fmt.Sprintf("-vm=%s", imageName),
Packit Service 509fd4
	//	"-p", "/root/.ssh",
Packit Service 509fd4
	//}
Packit Service 509fd4
	//retcode = cli.Run(args)
Packit Service 509fd4
	//if retcode != 0 {
Packit Service 509fd4
	//	return errors.New("mkdir /root/.ssh on VM failed")
Packit Service 509fd4
	//}
Packit Service 509fd4
Packit Service 509fd4
	//args = []string{
Packit Service 509fd4
	//	"guest.upload",
Packit Service 509fd4
	//	fmt.Sprintf("-u=%s:%s@%s", creds.Username, creds.Password, creds.Host),
Packit Service 509fd4
	//	"-k=true",
Packit Service 509fd4
	//	fmt.Sprintf("-vm=%s", imageName),
Packit Service 509fd4
	//	"-f=true",
Packit Service 509fd4
	//	publicKey, // this is a file path
Packit Service 509fd4
	//	"/root/.ssh/authorized_keys",
Packit Service 509fd4
	//}
Packit Service 509fd4
	//retcode = cli.Run(args)
Packit Service 509fd4
	//if retcode != 0 {
Packit Service 509fd4
	//	return errors.New("Uploading public key to VM failed")
Packit Service 509fd4
	//}
Packit Service 509fd4
Packit Service 509fd4
	return f(ipAddress)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// hard-coded SSH keys b/c we're having troubles uploading publicKey
Packit Service 509fd4
// to the VM, see https://github.com/vmware/govmomi/issues/2054
Packit Service 509fd4
func WithSSHKeyPair(f func(privateKey, publicKey string) error) error {
Packit Service 509fd4
	public := "/usr/share/tests/osbuild-composer/keyring/id_rsa.pub"
Packit Service 509fd4
	private := "/usr/share/tests/osbuild-composer/keyring/id_rsa"
Packit Service 509fd4
Packit Service 509fd4
	return f(private, public)
Packit Service 509fd4
}