Repository: vmware/govmomi
Pull request #2214 (2020-12-20 16:41:09)

vcsim: include stderr in log message when volume import fails
Follow up to 1f3fb17 (#2189)

Provide option to use an image other than busybox via env VCSIM_BUSYBOX


Patch:
diff --git a/simulator/container.go b/simulator/container.go
index e1656660..cc4d3d23 100644
--- a/simulator/container.go
+++ b/simulator/container.go
@@ -25,6 +25,7 @@ import (
 	"io"
 	"log"
 	"net/http"
+	"os"
 	"os/exec"
 	"path"
 	"strconv"
@@ -132,7 +133,11 @@ func (c *container) prepareGuestOperation(vm *VirtualMachine, auth types.BaseGue
 
 // createDMI writes BIOS UUID DMI files to a container volume
 func (c *container) createDMI(vm *VirtualMachine, name string) error {
-	cmd := exec.Command("docker", "run", "--rm", "-i", "-v", name+":"+"/"+name, "busybox", "tar", "-C", "/"+name, "-xf", "-")
+	image := os.Getenv("VCSIM_BUSYBOX")
+	if image == "" {
+		image = "busybox"
+	}
+	cmd := exec.Command("docker", "run", "--rm", "-i", "-v", name+":"+"/"+name, image, "tar", "-C", "/"+name, "-xf", "-")
 	stdin, err := cmd.StdinPipe()
 	if err != nil {
 		return err
@@ -167,7 +172,15 @@ func (c *container) createDMI(vm *VirtualMachine, name string) error {
 	_ = tw.Close()
 	_ = stdin.Close()
 
-	return cmd.Wait()
+	err = cmd.Wait()
+	if err != nil {
+		stderr := ""
+		if xerr, ok := err.(*exec.ExitError); ok {
+			stderr = string(xerr.Stderr)
+		}
+		log.Printf("%s %s: %s %s", vm.Name, cmd.Args, err, stderr)
+	}
+	return err
 }
 
 // start runs the container if specified by the RUN.container extraConfig property.
@@ -217,7 +230,6 @@ func (c *container) start(vm *VirtualMachine) {
 	run := append([]string{"docker", "run", "-d", "--name", c.name}, env...)
 
 	if err := c.createDMI(vm, c.name); err != nil {
-		log.Printf("%s: %s", vm.Name, err)
 		return
 	}
 	run = append(run, "-v", fmt.Sprintf("%s:%s:ro", c.name, "/sys/class/dmi/id"))
diff --git a/vsan/client.go b/vsan/client.go
index 36869d2f..91b55337 100644
--- a/vsan/client.go
+++ b/vsan/client.go
@@ -18,7 +18,6 @@ package vsan
 
 import (
 	"context"
-	"errors"
 
 	"github.com/vmware/govmomi/vim25"
 	"github.com/vmware/govmomi/vim25/soap"
@@ -43,27 +42,18 @@ var (
 		Type:  "VsanPerformanceManager",
 		Value: "vsan-performance-manager",
 	}
-	VsanQueryObjectIdentitiesInstance = vimtypes.ManagedObjectReference{
-		Type:  "VsanObjectSystem",
-		Value: "vsan-cluster-object-system",
-	}
-	VsanPropertyCollectorInstance = vimtypes.ManagedObjectReference{
-		Type:  "PropertyCollector",
-		Value: "vsan-property-collector",
-	}
 )
 
 // Client used for accessing vsan health APIs.
 type Client struct {
-	*soap.Client
-
-	Vim25Client *vim25.Client
+	vim25Client   *vim25.Client
+	serviceClient *soap.Client
 }
 
 // NewClient creates a new VsanHealth client
 func NewClient(ctx context.Context, c *vim25.Client) (*Client, error) {
 	sc := c.Client.NewServiceClient(Path, Namespace)
-	return &Client{sc, c}, nil
+	return &Client{c, sc}, nil
 }
 
 // VsanClusterGetConfig calls the Vsan health's VsanClusterGetConfig API.
@@ -73,7 +63,7 @@ func (c *Client) VsanClusterGetConfig(ctx context.Context, cluster vimtypes.Mana
 		Cluster: cluster,
 	}
 
-	res, err := methods.VsanClusterGetConfig(ctx, c, &req)
+	res, err := methods.VsanClusterGetConfig(ctx, c.serviceClient, &req)
 	if err != nil {
 		return nil, err
 	}
@@ -88,13 +78,21 @@ func (c *Client) VsanPerfQueryPerf(ctx context.Context, cluster *vimtypes.Manage
 		QuerySpecs: qSpecs,
 	}
 
-	res, err := methods.VsanPerfQueryPerf(ctx, c, &req)
+	res, err := methods.VsanPerfQueryPerf(ctx, c.serviceClient, &req)
 	if err != nil {
 		return nil, err
 	}
 	return res.Returnval, nil
 }
 
+// Creates the vsan object identities instance. This is to be queried from vsan health.
+var (
+	VsanQueryObjectIdentitiesInstance = vimtypes.ManagedObjectReference{
+		Type:  "VsanObjectSystem",
+		Value: "vsan-cluster-object-system",
+	}
+)
+
 // VsanQueryObjectIdentities return host uuid
 func (c *Client) VsanQueryObjectIdentities(ctx context.Context, cluster vimtypes.ManagedObjectReference) (*vsantypes.VsanObjectIdentityAndHealth, error) {
 	req := vsantypes.VsanQueryObjectIdentities{
@@ -102,49 +100,12 @@ func (c *Client) VsanQueryObjectIdentities(ctx context.Context, cluster vimtypes
 		Cluster: &cluster,
 	}
 
-	res, err := methods.VsanQueryObjectIdentities(ctx, c, &req)
+	res, err := methods.VsanQueryObjectIdentities(ctx, c.serviceClient, &req)
 
 	if err != nil {
 		return nil, err
 	}
 
 	return res.Returnval, nil
-}
-
-// VsanHostGetConfig returns the config of host's vSAN system.
-func (c *Client) VsanHostGetConfig(ctx context.Context, vsanSystem vimtypes.ManagedObjectReference) (*vsantypes.VsanHostConfigInfoEx, error) {
-	req := vimtypes.RetrievePropertiesEx{
-		SpecSet: []vimtypes.PropertyFilterSpec{{
-			ObjectSet: []vimtypes.ObjectSpec{{
-				Obj: vsanSystem}},
-			PropSet: []vimtypes.PropertySpec{{
-				Type:    "HostVsanSystem",
-				PathSet: []string{"config"}}}}},
-		This: VsanPropertyCollectorInstance}
-
-	res, err := methods.RetrievePropertiesEx(ctx, c, &req)
-	if err != nil {
-		return nil, err
-	}
 
-	var property vimtypes.DynamicProperty
-	if res != nil && res.Returnval != nil {
-		for _, obj := range res.Returnval.Objects {
-			for _, prop := range obj.PropSet {
-				if prop.Name == "config" {
-					property = prop
-					break
-				}
-			}
-		}
-	}
-
-	switch cfg := property.Val.(type) {
-	case vimtypes.VsanHostConfigInfo:
-		return &vsantypes.VsanHostConfigInfoEx{VsanHostConfigInfo: cfg}, nil
-	case vsantypes.VsanHostConfigInfoEx:
-		return &cfg, nil
-	default:
-		return nil, errors.New("host vSAN config not found")
-	}
 }


Test patch:
diff --git a/vsan/client_test.go b/vsan/client_test.go
index 47c76e4c..47091441 100644
--- a/vsan/client_test.go
+++ b/vsan/client_test.go
@@ -51,7 +51,7 @@ func TestClient(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	finder := find.NewFinder(vsanHealthClient.Vim25Client, false)
+	finder := find.NewFinder(vsanHealthClient.vim25Client, false)
 	dc, err := finder.Datacenter(ctx, datacenter)
 	if err != nil {
 		t.Fatal(err)
@@ -80,26 +80,6 @@ func TestClient(t *testing.T) {
 	if isFileServiceEnabled {
 		t.Logf("Printing one of the clusterConfig where file service is enabled:\n %+v", pretty.Sprint(clusterConfigToPrint))
 	}
-
-	hosts, _ := finder.HostSystemList(ctx, "*")
-	if err != nil {
-		t.Logf("Error occurred while getting hostSystem %+v", err.Error())
-		t.Fatal(err)
-	}
-
-	for _, host := range hosts {
-		vsanSystem, _ := host.ConfigManager().VsanInternalSystem(ctx)
-		if err != nil {
-			t.Logf("Error occurred: %+v", err.Error())
-			t.Fatal(err)
-		}
-		hostConfig, err := vsanHealthClient.VsanHostGetConfig(ctx, vsanSystem.Reference())
-		if err != nil {
-			t.Logf("Error occurred: %+v", err.Error())
-			t.Fatal(err)
-		}
-		t.Logf("Printing hostConfig:\n %+s", pretty.Sprint(hostConfig))
-	}
 }
 
 func TestVsanQueryObjectIdentities(t *testing.T) {
@@ -125,7 +105,7 @@ func TestVsanQueryObjectIdentities(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	finder := find.NewFinder(vsanHealthClient.Vim25Client, false)
+	finder := find.NewFinder(vsanHealthClient.vim25Client, false)
 	dc, err := finder.Datacenter(ctx, datacenter)
 	if err != nil {
 		t.Fatal(err)