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