1
1
package main
2
2
3
3
import (
4
+ "errors"
4
5
"flag"
5
6
"fmt"
6
7
"log"
8
+ "net"
7
9
"path/filepath"
10
+ "strings"
8
11
"sync"
9
12
13
+ "github.com/appropriate/go-virtualboxclient/vboxwebsrv"
10
14
"github.com/appropriate/go-virtualboxclient/virtualboxclient"
11
15
"github.com/calavera/dkvolume"
12
16
)
@@ -18,9 +22,10 @@ const (
18
22
)
19
23
20
24
var (
21
- socketAddress = filepath .Join ("/run/docker/plugins" , fmt .Sprintf ("%s.sock" , pluginId ))
22
- defaultMountRoot = filepath .Join (dkvolume .DefaultDockerRootDirectory , fmt .Sprintf ("_%s" , pluginId ))
23
- mountRoot = flag .String ("mount-root" , defaultMountRoot , "VirtualBox volumes root mount directory" )
25
+ socketAddress = filepath .Join ("/run/docker/plugins" , fmt .Sprintf ("%s.sock" , pluginId ))
26
+ defaultMountRoot = filepath .Join (dkvolume .DefaultDockerRootDirectory , fmt .Sprintf ("_%s" , pluginId ))
27
+ mountRoot = flag .String ("mount-root" , defaultMountRoot , "VirtualBox volumes root mount directory (on VM)" )
28
+ storageLocationRoot = flag .String ("storage-location-root" , "" , "VirtualBox volumes root storage location directory (on host)" )
24
29
25
30
vboxwebsrvUsername = flag .String ("vboxwebsrv-username" , "" , "Username to connect to vboxwebsrv" )
26
31
vboxwebsrvPassword = flag .String ("vboxwebsrv-password" , "" , "Password to connect to vboxwebsrv" )
@@ -31,6 +36,7 @@ type virtualboxDriver struct {
31
36
sync.Mutex
32
37
33
38
virtualbox * virtualboxclient.VirtualBox
39
+ machine * virtualboxclient.Machine
34
40
volumes map [string ]* virtualboxclient.Medium
35
41
}
36
42
@@ -60,12 +66,25 @@ func (d virtualboxDriver) Create(r dkvolume.Request) dkvolume.Response {
60
66
61
67
func (d virtualboxDriver ) Mount (r dkvolume.Request ) dkvolume.Response {
62
68
fmt .Printf ("Mounting volume %#v\n " , r )
69
+
70
+ scs , err := d .machine .GetStorageControllers ()
71
+ if err != nil {
72
+ return dkvolume.Response {Err : err .Error ()}
73
+ }
74
+
75
+ for _ , sc := range scs {
76
+ fmt .Printf ("%#v\n " , sc )
77
+ }
78
+
63
79
return dkvolume.Response {}
64
80
}
65
81
66
82
func (d virtualboxDriver ) Path (r dkvolume.Request ) dkvolume.Response {
67
- fmt .Printf ("Pathing volume %#v\n " , r )
68
- return dkvolume.Response {}
83
+ mountpoint := d .mountPoint (r .Name )
84
+
85
+ fmt .Printf ("Path %#v => %s\n " , r , mountpoint )
86
+
87
+ return dkvolume.Response {Mountpoint : d .mountPoint (r .Name )}
69
88
}
70
89
71
90
func (d virtualboxDriver ) Remove (r dkvolume.Request ) dkvolume.Response {
@@ -89,13 +108,87 @@ func (d virtualboxDriver) Unmount(r dkvolume.Request) dkvolume.Response {
89
108
}
90
109
91
110
func (d virtualboxDriver ) storageLocation (name string ) string {
92
- return filepath .Join ("/Users/mike/.docker/machine/machines/dev" , fmt .Sprintf ("%s.vmdk" , name ))
111
+ return filepath .Join (* storageLocationRoot , fmt .Sprintf ("%s.vmdk" , name ))
112
+ }
113
+
114
+ func (d virtualboxDriver ) mountPoint (name string ) string {
115
+ return filepath .Join (* mountRoot , name )
116
+ }
117
+
118
+ func (d virtualboxDriver ) findCurrentMachine () (* virtualboxclient.Machine , error ) {
119
+ var (
120
+ sp * virtualboxclient.SystemProperties
121
+ machines []* virtualboxclient.Machine
122
+ chipset * vboxwebsrv.ChipsetType
123
+ maxNetworkAdapters uint32
124
+ na * virtualboxclient.NetworkAdapter
125
+ mac string
126
+ intfMacs []string
127
+ interfaces []net.Interface
128
+ err error
129
+ )
130
+
131
+ interfaces , err = net .Interfaces ()
132
+ if err != nil {
133
+ return nil , err
134
+ }
135
+
136
+ intfMacs = make ([]string , len (interfaces ))
137
+ for i , intf := range interfaces {
138
+ intfMacs [i ] = strings .ToUpper (strings .Replace (intf .HardwareAddr .String (), ":" , "" , - 1 ))
139
+ }
140
+
141
+ sp , err = d .virtualbox .GetSystemProperties ()
142
+ if err != nil {
143
+ return nil , err
144
+ }
145
+
146
+ machines , err = d .virtualbox .GetMachines ()
147
+ if err != nil {
148
+ return nil , err
149
+ }
150
+
151
+ for _ , m := range machines {
152
+ chipset , err = m .GetChipsetType ()
153
+ if err != nil {
154
+ return nil , err
155
+ }
156
+
157
+ maxNetworkAdapters , err = sp .GetMaxNetworkAdapters (chipset )
158
+ if err != nil {
159
+ return nil , err
160
+ }
161
+
162
+ for i := uint32 (0 ); i < maxNetworkAdapters ; i ++ {
163
+ na , err = m .GetNetworkAdapter (i )
164
+ if err != nil {
165
+ return nil , err
166
+ }
167
+
168
+ mac , err = na .GetMACAddress ()
169
+ if err != nil {
170
+ return nil , err
171
+ }
172
+
173
+ for _ , intfMac := range intfMacs {
174
+ if mac == intfMac {
175
+ return m , nil
176
+ }
177
+ }
178
+ }
179
+ }
180
+
181
+ return nil , errors .New ("Unable to find machine" )
93
182
}
94
183
95
184
// TODO: Figure out why Ctrl+C doesn't immediately terminate
96
185
func main () {
97
186
flag .Parse ()
98
187
188
+ if storageLocationRoot == nil || * storageLocationRoot == "" {
189
+ log .Fatal ("Storage location root must be specified with -storage-location-root" )
190
+ }
191
+
99
192
virtualbox := virtualboxclient .New (* vboxwebsrvUsername , * vboxwebsrvPassword , * vboxwebsrvUrl )
100
193
101
194
if err := virtualbox .Logon (); err != nil {
@@ -106,6 +199,13 @@ func main() {
106
199
virtualbox : virtualbox ,
107
200
volumes : map [string ]* virtualboxclient.Medium {},
108
201
}
202
+
203
+ if m , err := d .findCurrentMachine (); err != nil {
204
+ log .Fatal (err )
205
+ } else {
206
+ d .machine = m
207
+ }
208
+
109
209
h := dkvolume .NewHandler (d )
110
210
fmt .Printf ("Listening on %s\n " , socketAddress )
111
211
fmt .Println (h .ServeUnix ("root" , socketAddress ))
0 commit comments