11package virtualboxclient
22
33import (
4+ "errors"
5+
46 "github.com/appropriate/go-virtualboxclient/vboxwebsrv"
57)
68
79type Machine struct {
810 virtualbox * VirtualBox
911 managedObjectId string
12+ ID string
13+ Name string
1014}
1115
1216func (m * Machine ) GetChipsetType () (* vboxwebsrv.ChipsetType , error ) {
@@ -28,6 +32,18 @@ func (m *Machine) GetMediumAttachments() ([]*vboxwebsrv.IMediumAttachment, error
2832 return nil , err // TODO: Wrap the error
2933 }
3034
35+ ret := response .Returnval
36+ return ret , nil
37+ }
38+
39+ func (m * Machine ) GetMediumAttachmentsOfController (cName string ) ([]* vboxwebsrv.IMediumAttachment , error ) {
40+ request := vboxwebsrv.IMachinegetMediumAttachmentsOfController {This : m .managedObjectId , Name : cName }
41+
42+ response , err := m .virtualbox .IMachinegetMediumAttachmentsOfController (& request )
43+ if err != nil {
44+ return nil , err // TODO: Wrap the error
45+ }
46+
3147 return response .Returnval , nil
3248}
3349
@@ -53,6 +69,29 @@ func (m *Machine) GetSettingsFilePath() (string, error) {
5369 return response .Returnval , nil
5470}
5571
72+ func (m * Machine ) SaveSettings () error {
73+ request := vboxwebsrv.IMachinesaveSettings {This : m .managedObjectId }
74+
75+ _ , err := m .virtualbox .IMachinesaveSettings (& request )
76+ if err != nil {
77+ defer m .DiscardSettings ()
78+ return err // TODO: Wrap the error
79+ }
80+
81+ return nil
82+ }
83+
84+ func (m * Machine ) DiscardSettings () error {
85+ request := vboxwebsrv.IMachinediscardSettings {This : m .managedObjectId }
86+
87+ _ , err := m .virtualbox .IMachinediscardSettings (& request )
88+ if err != nil {
89+ return err // TODO: Wrap the error
90+ }
91+
92+ return nil
93+ }
94+
5695func (m * Machine ) GetStorageControllers () ([]* StorageController , error ) {
5796 request := vboxwebsrv.IMachinegetStorageControllers {This : m .managedObjectId }
5897
@@ -63,8 +102,209 @@ func (m *Machine) GetStorageControllers() ([]*StorageController, error) {
63102
64103 storageControllers := make ([]* StorageController , len (response .Returnval ))
65104 for i , oid := range response .Returnval {
66- storageControllers [i ] = & StorageController {m .virtualbox , oid }
105+ storageControllers [i ] = & StorageController {virtualbox : m .virtualbox , managedObjectId : oid }
67106 }
68107
69108 return storageControllers , nil
70109}
110+
111+ func (m * Machine ) GetStorageController (name string ) (* StorageController , error ) {
112+ if name == "" {
113+ return nil , errors .New ("storage controller name not specified" )
114+ }
115+ scs , err := m .GetStorageControllers ()
116+ if err != nil {
117+ return nil , err
118+ }
119+
120+ for _ , sc := range scs {
121+ scName , err := sc .GetName ()
122+ if err != nil {
123+ return nil , err
124+ }
125+ if scName == name {
126+ sc .Name = scName
127+ return sc , nil
128+ }
129+ }
130+ return nil , errors .New ("storage controller not found" )
131+ }
132+
133+ func (m * Machine ) AttachDevice (medium * Medium ) error {
134+ session , err := m .virtualbox .GetSession ()
135+ if err != nil {
136+ return err
137+ }
138+ // defer session.Release()
139+
140+ if err := m .Lock (session , vboxwebsrv .LockTypeShared ); err != nil {
141+ return err
142+ }
143+ defer m .Unlock (session )
144+
145+ sm , err := session .GetMachine ()
146+ if err != nil {
147+ return err
148+ }
149+ defer sm .Release ()
150+
151+ if m .virtualbox .controllerName == "" {
152+ return errors .New ("missing controllerName" )
153+ }
154+
155+ sc , err := sm .GetStorageController (m .virtualbox .controllerName )
156+ if err != nil {
157+ return err
158+ }
159+
160+ pn , err := sc .GetNextAvailablePort (m )
161+ if err != nil {
162+ return err
163+ }
164+
165+ pc , err := sc .GetPortCount ()
166+ if err != nil {
167+ return err
168+ }
169+
170+ spc := uint32 (pn ) + 1
171+ if spc > pc {
172+ if err := sc .SetPortCount (spc ); err != nil {
173+ return err
174+ }
175+ }
176+
177+ request := vboxwebsrv.IMachineattachDevice {
178+ This : sm .managedObjectId ,
179+ Name : sc .Name ,
180+ ControllerPort : pn ,
181+ Device : 0 ,
182+ Type_ : & medium .DeviceType ,
183+ Medium : medium .managedObjectId ,
184+ }
185+
186+ _ , err = m .virtualbox .IMachineattachDevice (& request )
187+ if err != nil {
188+ return err
189+ }
190+
191+ if err := sm .SaveSettings (); err != nil {
192+ return err
193+ }
194+
195+ if err := m .Unlock (session ); err != nil {
196+ return err
197+ }
198+
199+ return nil
200+ }
201+
202+ func (m * Machine ) DetachDevice (medium * Medium ) error {
203+
204+ session , err := m .virtualbox .GetSession ()
205+ if err != nil {
206+ return err
207+ }
208+ // defer session.Release()
209+
210+ if err := m .Lock (session , vboxwebsrv .LockTypeShared ); err != nil {
211+ return err
212+ }
213+ defer m .Unlock (session )
214+
215+ sm , err := session .GetMachine ()
216+ if err != nil {
217+ return err
218+ }
219+ defer sm .Release ()
220+
221+ mediumAttachments , err := m .GetMediumAttachments ()
222+ if err != nil {
223+ return err
224+ }
225+
226+ var request * vboxwebsrv.IMachinedetachDevice
227+ for _ , ma := range mediumAttachments {
228+ am := & Medium {virtualbox : m .virtualbox , managedObjectId : ma .Medium }
229+ defer am .Release ()
230+ amID , err := am .GetID ()
231+ if err != nil {
232+ return err
233+ }
234+
235+ if amID != medium .ID {
236+ continue
237+ }
238+ request = & vboxwebsrv.IMachinedetachDevice {
239+ This : sm .managedObjectId ,
240+ Name : ma .Controller ,
241+ ControllerPort : ma .Port ,
242+ Device : 0 ,
243+ }
244+ }
245+ if request == nil {
246+ return errors .New ("couldn't find attached medium" )
247+ }
248+
249+ _ , err = m .virtualbox .IMachinedetachDevice (request )
250+ if err != nil {
251+ return err
252+ }
253+
254+ if err := sm .SaveSettings (); err != nil {
255+ return err
256+ }
257+
258+ return nil
259+ }
260+
261+ func (m * Machine ) Unlock (session * Session ) error {
262+ if err := session .UnlockMachine (); err != nil {
263+ return err
264+ }
265+ return nil
266+ }
267+
268+ func (m * Machine ) Lock (session * Session , lockType vboxwebsrv.LockType ) error {
269+ if err := session .LockMachine (m , lockType ); err != nil {
270+ return err
271+ }
272+ return nil
273+ }
274+
275+ func (m * Machine ) GetID () (string , error ) {
276+ request := vboxwebsrv.IMachinegetId {This : m .managedObjectId }
277+
278+ response , err := m .virtualbox .IMachinegetId (& request )
279+ if err != nil {
280+ return "" , err // TODO: Wrap the error
281+ }
282+
283+ // TODO: See if we need to do anything with the response
284+ return response .Returnval , nil
285+ }
286+
287+ func (m * Machine ) GetName () (string , error ) {
288+ request := vboxwebsrv.IMachinegetName {This : m .managedObjectId }
289+
290+ response , err := m .virtualbox .IMachinegetName (& request )
291+ if err != nil {
292+ return "" , err // TODO: Wrap the error
293+ }
294+
295+ // TODO: See if we need to do anything with the response
296+ return response .Returnval , nil
297+ }
298+
299+ func (m * Machine ) Release () error {
300+ return m .virtualbox .Release (m .managedObjectId )
301+ }
302+
303+ func (m * Machine ) Refresh () error {
304+ if mr , err := m .virtualbox .FindMachine (m .ID ); err != nil {
305+ return err
306+ } else {
307+ m .managedObjectId = mr .managedObjectId
308+ }
309+ return nil
310+ }
0 commit comments