-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmachine-properties.go
143 lines (123 loc) · 3.43 KB
/
machine-properties.go
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package drivervbox
import (
"fmt"
"regexp"
"strings"
"github.com/kuttiproject/drivercore"
"github.com/kuttiproject/workspace"
)
const (
propIPAddress = "/VirtualBox/GuestInfo/Net/0/V4/IP"
propIPAddress2 = "/VirtualBox/GuestInfo/Net/1/V4/IP"
propIPAddress3 = "/VirtualBox/GuestInfo/Net/2/V4/IP"
propLoggedInUsers = "/VirtualBox/GuestInfo/OS/LoggedInUsers"
propSSHAddress = "/kutti/VMInfo/SSHAddress"
propSavedIPAddress = "/kutti/VMInfo/SavedIPAddress"
)
var (
properrorpattern, _ = regexp.Compile("error: (.*)\n")
proppattern, _ = regexp.Compile("Name: (.*), value: (.*), timestamp: (.*), flags:(.*)\n")
// VBoxManage in VirtualBox 7 changes the output pattern
proppattern2, _ = regexp.Compile("([^\\s]*)\\s*=\\s'(.*)'(.*)\n")
)
// When properties are parsed by parseprop(), certain properties
// can cause an action to be taken. This map contains the names of some
// VirtualBox properties, and correspoding actions.
var propMap = map[string]func(*Machine, string){
propLoggedInUsers: func(vh *Machine, value string) {
vh.status = drivercore.MachineStatusRunning
},
propSavedIPAddress: func(vh *Machine, value string) {
vh.savedipaddress = trimpropend(value)
},
}
func (vh *Machine) getproperty(propname string) (string, bool) {
output, err := workspace.RunWithResults(
vh.driver.vboxmanagepath,
"guestproperty",
"get",
vh.qname(),
propname,
)
// VBoxManage guestproperty gets the hardcoded value "No value set!"
// if the property value cannot be retrieved
if err != nil || output == "No value set!" || output == "No value set!\n" {
return "", false
}
// Output is in the format
// Value: <value>
// So, 7th rune onwards
return output[7:], true
}
func (vh *Machine) setproperty(propname string, value string) error {
_, err := workspace.RunWithResults(
vh.driver.vboxmanagepath,
"guestproperty",
"set",
vh.qname(),
propname,
value,
)
if err != nil {
// TODO: Error consolidation
return fmt.Errorf(
"could not set property %s for host %s: %v",
propname,
vh.name,
err,
)
}
return nil
}
func (vh *Machine) unsetproperty(propname string) error {
_, err := workspace.RunWithResults(
vh.driver.vboxmanagepath,
"guestproperty",
"unset",
vh.qname(),
propname,
)
if err != nil {
return fmt.Errorf(
"could not unset property %s for host %s: %v",
propname,
vh.name,
err,
)
}
return nil
}
func trimpropend(s string) string {
return strings.TrimSpace(s)
}
func (vh *Machine) parseProps(propstr string) {
// There are two possibilities. Either:
// VBoxManage: error: Could not find a registered machine named 'xxx'
// ...
// Or:
// Name: /VirtualBox/GuestInfo/Net/0/V4/IP, value: 10.0.2.15, timestamp: 1568552111298588000, flags:
// ...
// This should not have made it this far. Still,
// belt and suspenders...
errorsfound := properrorpattern.FindAllStringSubmatch(propstr, 1)
if len(errorsfound) != 0 {
// deal with the error with:
// errorsfound[0][1]
vh.status = drivercore.MachineStatusError
vh.errormessage = errorsfound[0][1]
return
}
results := proppattern.FindAllStringSubmatch(propstr, -1)
// In case there are no matches, use the VirtualBox 7 pattern
if results == nil {
results = proppattern2.FindAllStringSubmatch(propstr, -1)
}
for _, record := range results {
// record[1] - Name and record[2] - Value
// Run any configured action for a property
action, ok := propMap[record[1]]
if ok {
action(vh, record[2])
}
}
}