forked from brlbil/linuxkit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprovider_vmware.go
More file actions
125 lines (103 loc) · 2.83 KB
/
provider_vmware.go
File metadata and controls
125 lines (103 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package main
import (
"bytes"
"compress/gzip"
"encoding/base64"
"fmt"
"io/ioutil"
"os/exec"
"path"
"strings"
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 {
cmd string
}
// 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 {
c, err := exec.LookPath("vmware-rpctool")
if err != nil {
return false
}
p.cmd = c
b, err := p.vmwareGet(guestUserData)
return (err == nil) && len(b) > 0 && string(b) != " " && string(b) != "---"
}
// Extract gets both the AWS specific 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) {
cmdArg := func(n string) string {
return fmt.Sprintf("info-get %s", n)
}
// get the gusest info value
out, err := exec.Command(p.cmd, cmdArg(name)).Output()
if err != nil {
eErr := err.(*exec.ExitError)
log.Debugf("Getting guest info %s failed: error %s", cmdArg(name), string(eErr.Stderr))
return nil, err
}
enc, err := exec.Command(p.cmd, cmdArg(name+".encoding")).Output()
if err != nil {
eErr := err.(*exec.ExitError)
log.Debugf("Getting guest info %s.encoding failed: error %s", name, string(eErr.Stderr))
return nil, err
}
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))
}
}