Skip to content

Commit b14d3eb

Browse files
author
Luca Bruno
authored
Merge pull request #288 from kinvolk/dongsu/machines-dbus-methods
machine1: add methods ListMachines, ListImages, GetMachineAddresses
2 parents eee3db3 + c211bab commit b14d3eb

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed

machine1/dbus.go

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,25 @@ type Conn struct {
3737
object dbus.BusObject
3838
}
3939

40+
// MachineStatus is a set of necessary info for each machine
41+
type MachineStatus struct {
42+
Name string // The primary machine name as string
43+
Class string // The machine class as string
44+
Service string // The machine service as string
45+
JobPath dbus.ObjectPath // The job object path
46+
}
47+
48+
// ImageStatus is a set of necessary info for each machine image
49+
type ImageStatus struct {
50+
Name string // The primary image name as string
51+
ImageType string // The image type as string
52+
Readonly bool // whether it's readonly or not
53+
CreateTime uint64 // time when it's created
54+
ModifyTime uint64 // time when it's modified
55+
DiskUsage uint64 // used disk space
56+
JobPath dbus.ObjectPath // The job object path
57+
}
58+
4059
// New() establishes a connection to the system bus and authenticates.
4160
func New() (*Conn, error) {
4261
c := new(Conn)
@@ -106,6 +125,11 @@ func (c *Conn) GetMachineByPID(pid uint) (dbus.ObjectPath, error) {
106125
return c.getPath("GetMachineByPID", pid)
107126
}
108127

128+
// GetMachineAddresses gets a list of IP addresses
129+
func (c *Conn) GetMachineAddresses(name string) (dbus.ObjectPath, error) {
130+
return c.getPath("GetMachineAddresses", name)
131+
}
132+
109133
// DescribeMachine gets the properties of a machine
110134
func (c *Conn) DescribeMachine(name string) (machineProps map[string]interface{}, err error) {
111135
var dbusProps map[string]dbus.Variant
@@ -139,3 +163,103 @@ func (c *Conn) TerminateMachine(name string) error {
139163
func (c *Conn) RegisterMachine(name string, id []byte, service string, class string, pid int, root_directory string) error {
140164
return c.object.Call(dbusInterface+".RegisterMachine", 0, name, id, service, class, uint32(pid), root_directory).Err
141165
}
166+
167+
func machineFromInterfaces(machine []interface{}) (*MachineStatus, error) {
168+
if len(machine) < 4 {
169+
return nil, fmt.Errorf("invalid number of machine fields: %d", len(machine))
170+
}
171+
name, ok := machine[0].(string)
172+
if !ok {
173+
return nil, fmt.Errorf("failed to typecast machine field 0 to string")
174+
}
175+
class, ok := machine[1].(string)
176+
if !ok {
177+
return nil, fmt.Errorf("failed to typecast class field 1 to string")
178+
}
179+
service, ok := machine[2].(string)
180+
if !ok {
181+
return nil, fmt.Errorf("failed to typecast service field 2 to string")
182+
}
183+
jobpath, ok := machine[3].(dbus.ObjectPath)
184+
if !ok {
185+
return nil, fmt.Errorf("failed to typecast jobpath field 3 to ObjectPath")
186+
}
187+
188+
ret := MachineStatus{Name: name, Class: class, Service: service, JobPath: jobpath}
189+
return &ret, nil
190+
}
191+
192+
// ListMachines returns an array of all currently running machines.
193+
func (c *Conn) ListMachines() ([]MachineStatus, error) {
194+
result := make([][]interface{}, 0)
195+
if err := c.object.Call(dbusInterface+".ListMachines", 0).Store(&result); err != nil {
196+
return nil, err
197+
}
198+
199+
machs := []MachineStatus{}
200+
for _, i := range result {
201+
machine, err := machineFromInterfaces(i)
202+
if err != nil {
203+
return nil, err
204+
}
205+
machs = append(machs, *machine)
206+
}
207+
208+
return machs, nil
209+
}
210+
211+
func imageFromInterfaces(image []interface{}) (*ImageStatus, error) {
212+
if len(image) < 7 {
213+
return nil, fmt.Errorf("invalid number of image fields: %d", len(image))
214+
}
215+
name, ok := image[0].(string)
216+
if !ok {
217+
return nil, fmt.Errorf("failed to typecast image field 0 to string")
218+
}
219+
imagetype, ok := image[1].(string)
220+
if !ok {
221+
return nil, fmt.Errorf("failed to typecast imagetype field 1 to string")
222+
}
223+
readonly, ok := image[2].(bool)
224+
if !ok {
225+
return nil, fmt.Errorf("failed to typecast readonly field 2 to bool")
226+
}
227+
createtime, ok := image[3].(uint64)
228+
if !ok {
229+
return nil, fmt.Errorf("failed to typecast createtime field 3 to uint64")
230+
}
231+
modifytime, ok := image[4].(uint64)
232+
if !ok {
233+
return nil, fmt.Errorf("failed to typecast modifytime field 4 to uint64")
234+
}
235+
diskusage, ok := image[5].(uint64)
236+
if !ok {
237+
return nil, fmt.Errorf("failed to typecast diskusage field 5 to uint64")
238+
}
239+
jobpath, ok := image[6].(dbus.ObjectPath)
240+
if !ok {
241+
return nil, fmt.Errorf("failed to typecast jobpath field 6 to ObjectPath")
242+
}
243+
244+
ret := ImageStatus{Name: name, ImageType: imagetype, Readonly: readonly, CreateTime: createtime, ModifyTime: modifytime, DiskUsage: diskusage, JobPath: jobpath}
245+
return &ret, nil
246+
}
247+
248+
// ListImages returns an array of all currently available images.
249+
func (c *Conn) ListImages() ([]ImageStatus, error) {
250+
result := make([][]interface{}, 0)
251+
if err := c.object.Call(dbusInterface+".ListImages", 0).Store(&result); err != nil {
252+
return nil, err
253+
}
254+
255+
images := []ImageStatus{}
256+
for _, i := range result {
257+
image, err := imageFromInterfaces(i)
258+
if err != nil {
259+
return nil, err
260+
}
261+
images = append(images, *image)
262+
}
263+
264+
return images, nil
265+
}

machine1/dbus_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ package machine1
1919
import (
2020
"fmt"
2121
"math/rand"
22+
"os"
2223
"os/exec"
24+
"path/filepath"
2325
"testing"
2426
"time"
2527

@@ -80,6 +82,16 @@ func TestMachine(t *testing.T) {
8082
t.Fatalf("did not find machine named %s", machineName)
8183
}
8284

85+
listMachines, getErr := conn.ListMachines()
86+
if getErr != nil {
87+
t.Fatal(getErr)
88+
}
89+
90+
// listMachines includes also `.host`, so by default the length should be greater than 1
91+
if len(listMachines) <= 1 {
92+
t.Fatalf("did not find any machine")
93+
}
94+
8395
tErr := conn.TerminateMachine(machineName)
8496
if tErr != nil {
8597
t.Fatal(tErr)
@@ -102,3 +114,31 @@ func generateRandomLabel(n int) string {
102114
}
103115
return string(s)
104116
}
117+
118+
func TestImages(t *testing.T) {
119+
imageName := machinePrefix + generateRandomLabel(8)
120+
imagePath := filepath.Join("/var/lib/machines", imageName)
121+
122+
if _, err := os.Create(imagePath); err != nil {
123+
t.Fatal(err)
124+
}
125+
defer os.Remove(imagePath)
126+
127+
if err := os.Truncate(imagePath, 500*1024*1024); err != nil {
128+
t.Fatal(err)
129+
}
130+
131+
conn, newErr := New()
132+
if newErr != nil {
133+
t.Fatal(newErr)
134+
}
135+
136+
listImages, listErr := conn.ListImages()
137+
if listErr != nil {
138+
t.Fatal(listErr)
139+
}
140+
141+
if len(listImages) < 1 {
142+
t.Fatalf("did not find any image")
143+
}
144+
}

0 commit comments

Comments
 (0)