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,193 @@ 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+ request := vboxwebsrv.IMachineattachDevice {
166+ This : sm .managedObjectId ,
167+ Name : sc .Name ,
168+ ControllerPort : pn ,
169+ Device : 0 ,
170+ Type_ : & medium .DeviceType ,
171+ Medium : medium .managedObjectId ,
172+ }
173+
174+ _ , err = m .virtualbox .IMachineattachDevice (& request )
175+ if err != nil {
176+ return err
177+ }
178+
179+ if err := sm .SaveSettings (); err != nil {
180+ return err
181+ }
182+
183+ return nil
184+ }
185+
186+ func (m * Machine ) DetachDevice (medium * Medium ) error {
187+
188+ session , err := m .virtualbox .GetSession ()
189+ if err != nil {
190+ return err
191+ }
192+ // defer session.Release()
193+
194+ if err := m .Lock (session , vboxwebsrv .LockTypeShared ); err != nil {
195+ return err
196+ }
197+ defer m .Unlock (session )
198+
199+ sm , err := session .GetMachine ()
200+ if err != nil {
201+ return err
202+ }
203+ defer sm .Release ()
204+
205+ mediumAttachments , err := m .GetMediumAttachments ()
206+ if err != nil {
207+ return err
208+ }
209+
210+ var request * vboxwebsrv.IMachinedetachDevice
211+ for _ , ma := range mediumAttachments {
212+ am := & Medium {virtualbox : m .virtualbox , managedObjectId : ma .Medium }
213+ defer am .Release ()
214+ amID , err := am .GetID ()
215+ if err != nil {
216+ return err
217+ }
218+
219+ if amID != medium .ID {
220+ continue
221+ }
222+ request = & vboxwebsrv.IMachinedetachDevice {
223+ This : sm .managedObjectId ,
224+ Name : ma .Controller ,
225+ ControllerPort : ma .Port ,
226+ Device : 0 ,
227+ }
228+ }
229+ if request == nil {
230+ return errors .New ("couldn't find attached medium" )
231+ }
232+
233+ _ , err = m .virtualbox .IMachinedetachDevice (request )
234+ if err != nil {
235+ return err
236+ }
237+
238+ if err := sm .SaveSettings (); err != nil {
239+ return err
240+ }
241+
242+ return nil
243+ }
244+
245+ func (m * Machine ) Unlock (session * Session ) error {
246+ if err := session .UnlockMachine (); err != nil {
247+ return err
248+ }
249+ return nil
250+ }
251+
252+ func (m * Machine ) Lock (session * Session , lockType vboxwebsrv.LockType ) error {
253+ if err := session .LockMachine (m , lockType ); err != nil {
254+ return err
255+ }
256+ return nil
257+ }
258+
259+ func (m * Machine ) GetID () (string , error ) {
260+ request := vboxwebsrv.IMachinegetId {This : m .managedObjectId }
261+
262+ response , err := m .virtualbox .IMachinegetId (& request )
263+ if err != nil {
264+ return "" , err // TODO: Wrap the error
265+ }
266+
267+ // TODO: See if we need to do anything with the response
268+ return response .Returnval , nil
269+ }
270+
271+ func (m * Machine ) GetName () (string , error ) {
272+ request := vboxwebsrv.IMachinegetName {This : m .managedObjectId }
273+
274+ response , err := m .virtualbox .IMachinegetName (& request )
275+ if err != nil {
276+ return "" , err // TODO: Wrap the error
277+ }
278+
279+ // TODO: See if we need to do anything with the response
280+ return response .Returnval , nil
281+ }
282+
283+ func (m * Machine ) Release () error {
284+ return m .virtualbox .Release (m .managedObjectId )
285+ }
286+
287+ func (m * Machine ) Refresh () error {
288+ if mr , err := m .virtualbox .FindMachine (m .ID ); err != nil {
289+ return err
290+ } else {
291+ m .managedObjectId = mr .managedObjectId
292+ }
293+ return nil
294+ }
0 commit comments