Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions pkg/metadata/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func main() {
log.SetLevel(log.DebugLevel)
}

providers := []string{"aws", "gcp", "hetzner", "openstack", "scaleway", "vultr", "digitalocean", "packet", "metaldata", "cdrom"}
providers := []string{"aws", "gcp", "hetzner", "openstack", "scaleway", "vultr", "digitalocean", "packet", "metaldata", "vmware", "cdrom"}
args := flag.Args()
if len(args) > 0 {
providers = args
Expand All @@ -103,8 +103,10 @@ func main() {
netProviders = append(netProviders, NewDigitalOcean())
case p == "metaldata":
netProviders = append(netProviders, NewMetalData())
case p == "vmware":
cdromProviders = append(cdromProviders, NewVMware())
case p == "cdrom":
cdromProviders = ListCDROMs()
cdromProviders = append(cdromProviders, ListCDROMs()...)
case strings.HasPrefix(p, "file="):
fileProviders = append(fileProviders, fileProvider(p[5:]))
default:
Expand Down
131 changes: 131 additions & 0 deletions pkg/metadata/provider_vmware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package main

import (
"bytes"
"compress/gzip"
"encoding/base64"
"fmt"
"io/ioutil"
"os/exec"
"path"
"strings"

"github.com/vmware/vmw-guestinfo/rpcvmx"
"github.com/vmware/vmw-guestinfo/vmcheck"
log "github.com/sirupsen/logrus"
)

const (
guestMetaData = "guestinfo.metadata"
guestUserData = "guestinfo.userdata"
)

// ProviderVMware is the type implementing the Provider interface for VMware
type ProviderVMware struct {}

// NewVMware returns a new ProviderVMware
func NewVMware() *ProviderVMware {
return &ProviderVMware{}
}

func (p *ProviderVMware) String() string {
return "VMWARE"
}

// Probe checks if we are running on VMware
func (p *ProviderVMware) Probe() bool {
isVM, err := vmcheck.IsVirtualWorld()
if err != nil {
log.Fatalf("Error: %s", err)
return false
}

if !isVM {
log.Fatalf("ERROR: not in a virtual world.")
return false
}

b, err := p.vmwareGet(guestUserData)
return (err == nil) && len(b) > 0 && string(b) != " " && string(b) != "---"
}

// Extract gets both the hostname and generic userdata
func (p *ProviderVMware) Extract() ([]byte, error) {
// Get host name. This must not fail
metaData, err := p.vmwareGet(guestMetaData)
if err != nil {
return nil, err
}

err = ioutil.WriteFile(path.Join(ConfigPath, "metadata"), metaData, 0644)
if err != nil {
return nil, fmt.Errorf("VMWare: Failed to write metadata: %s", err)
}

// Generic userdata
userData, err := p.vmwareGet(guestUserData)
if err != nil {
log.Printf("VMware: Failed to get user-data: %s", err)
// This is not an error
return nil, nil
}

return userData, nil
}

// vmwareGet gets and extracts the guest data
func (p *ProviderVMware) vmwareGet(name string) ([]byte, error) {
config := rpcvmx.NewConfig()

// get the guest info value
sout, err := config.String(name, "")
if err != nil {
eErr := err.(*exec.ExitError)
log.Debugf("Getting guest info %s failed: error %s", name, string(eErr.Stderr))
return nil, err
}

// get the guest info encryption
senc, err := config.String(name+".encoding", "")
if err != nil {
eErr := err.(*exec.ExitError)
log.Debugf("Getting guest info %s.encoding failed: error %s", name, string(eErr.Stderr))
return nil, err
}

out := []byte(sout)
enc := []byte(senc)

switch strings.TrimSuffix(string(enc), "\n") {
case " ":
return bytes.TrimSuffix(out, []byte("\n")), nil
case "base64":
r := base64.NewDecoder(base64.StdEncoding, bytes.NewBuffer(out))

dst, err := ioutil.ReadAll(r)
if err != nil {
log.Debugf("Decoding base64 of '%s' failed %v", name, err)
return nil, err
}

return dst, nil
case "gzip+base64":
r := base64.NewDecoder(base64.StdEncoding, bytes.NewBuffer(out))

zr, err := gzip.NewReader(r)
if err != nil {
log.Debugf("New gzip reader from '%s' failed %v", name, err)
return nil, err
}

dst, err := ioutil.ReadAll(zr)
if err != nil {
log.Debugf("Read '%s' failed %v", name, err)
return nil, err
}

return dst, nil
default:
return nil, fmt.Errorf("Unknown encoding %s", string(enc))
}
}