1+ """
2+ Add helper code to the default IMachine class.
3+ """
4+
15from __future__ import print_function
26import time
37import sys
711import virtualbox
812from virtualbox import library
913
10- """
11- Add helper code to the default IMachine class.
12- """
13-
1414try :
15- basestring = basestring
16- except :
15+ basestring
16+ except NameError :
1717 basestring = (str , bytes )
1818
19- # Extend and fix IMachine :)
19+
20+ # Extend and fix IMachine :)
2021class IMachine (library .IMachine ):
2122 __doc__ = library .IMachine .__doc__
2223
@@ -29,21 +30,18 @@ def remove(self, delete=True):
2930 Options:
3031 delete - remove all elements of this VM from the system
3132
32- Return the IMedia from unregistered VM
33+ Return the IMedia from unregistered VM
3334 """
3435 if self .state >= library .MachineState .running :
3536 session = virtualbox .Session ()
3637 self .lock_machine (session , library .LockType .shared )
3738 try :
3839 progress = session .console .power_down ()
3940 progress .wait_for_completion (- 1 )
40- except Exception as exc :
41- print ("Error powering off machine %s" % progress ,
42- file = sys .stderr )
43- pass
41+ except Exception :
42+ print ("Error powering off machine" , file = sys .stderr )
4443 session .unlock_machine ()
45- time .sleep (0.5 ) # TODO figure out how to ensure session is
46- # really unlocked...
44+ time .sleep (0.5 ) # TODO figure out how to ensure session is really unlocked...
4745
4846 settings_dir = os .path .dirname (self .settings_file_path )
4947 if delete :
@@ -55,35 +53,40 @@ def remove(self, delete=True):
5553 progress = self .delete_config (media )
5654 progress .wait_for_completion (- 1 )
5755 media = []
58-
59- # if delete - At some point in time virtualbox didn't do a full cleanup
56+
57+ # if delete - At some point in time virtualbox didn't do a full cleanup
6058 # of this dir. Let's double check it has been cleaned up.
6159 if delete and os .path .exists (settings_dir ):
6260 shutil .rmtree (settings_dir )
6361
6462 return media
6563
66- def clone (self , snapshot_name_or_id = None ,
67- mode = library .CloneMode .machine_state ,
68- options = [ library . CloneOptions . link ] , name = None ,
69- uuid = None , groups = [] , basefolder = '' , register = True ):
70- """Clone this Machine
64+ def clone (self , snapshot_name_or_id = None ,
65+ mode = library .CloneMode .machine_state ,
66+ options = None , name = None ,
67+ uuid = None , groups = None , basefolder = '' , register = True ):
68+ """Clone this Machine
7169
72- Options:
70+ Options:
7371 snapshot_name_or_id - value can be either ISnapshot, name, or id
7472 mode - set the CloneMode value
75- options - define the CloneOptions options
73+ options - define the CloneOptions options
7674 name - define a name of the new VM
7775 uuid - set the uuid of the new VM
7876 groups - specify which groups the new VM will exist under
7977 basefolder - specify which folder to set the VM up under
8078 register - register this VM with the server
81-
79+
8280 Note: Default values create a linked clone from the current machine
8381 state
8482
85- Return a IMachine object for the newly cloned vm
83+ Return a IMachine object for the newly cloned vm
8684 """
85+ if options is None :
86+ options = [library .CloneOptions .link ]
87+ if groups is None :
88+ groups = []
89+
8790 vbox = virtualbox .VirtualBox ()
8891
8992 if snapshot_name_or_id is not None :
@@ -93,7 +96,7 @@ def clone(self, snapshot_name_or_id=None,
9396 snapshot = snapshot_name_or_id
9497 vm = snapshot .machine
9598 else :
96- # linked clone can only be created from a snapshot...
99+ # linked clone can only be created from a snapshot...
97100 # try grabbing the current_snapshot
98101 if library .CloneOptions .link in options :
99102 vm = self .current_snapshot .machine
@@ -103,27 +106,29 @@ def clone(self, snapshot_name_or_id=None,
103106 if name is None :
104107 name = "%s Clone" % vm .name
105108
106- # Build the settings file
109+ # Build the settings file
107110 create_flags = ''
108111 if uuid is not None :
109112 create_flags = "UUID=%s" % uuid
110113 primary_group = ''
111114 if groups :
112115 primary_group = groups [0 ]
113-
116+
114117 # Make sure this settings file does not already exist
115118 test_name = name
119+ settings_file = ''
116120 for i in range (1 , 1000 ):
117121 settings_file = vbox .compose_machine_filename (test_name ,
118- primary_group , create_flags , basefolder )
122+ primary_group ,
123+ create_flags ,
124+ basefolder )
119125 if not os .path .exists (os .path .dirname (settings_file )):
120126 break
121127 test_name = "%s (%s)" % (name , i )
122128 name = test_name
123129
124130 # Create the new machine and clone it!
125- vm_clone = vbox .create_machine (settings_file , name , groups , '' ,
126- create_flags )
131+ vm_clone = vbox .create_machine (settings_file , name , groups , '' , create_flags )
127132 progress = vm .clone_to (vm_clone , mode , options )
128133 progress .wait_for_completion (- 1 )
129134
@@ -133,17 +138,17 @@ def clone(self, snapshot_name_or_id=None,
133138
134139 # Add a helper to make locking and building a session simple
135140 def create_session (self , lock_type = library .LockType .shared ,
136- session = None ):
141+ session = None ):
137142 """Lock this machine
138-
143+
139144 Arguments:
140145 lock_type - see IMachine.lock_machine for details
141- session - optionally define a session object to lock this machine
142- against. If not defined, a new ISession object is
146+ session - optionally define a session object to lock this machine
147+ against. If not defined, a new ISession object is
143148 created to lock against
144-
149+
145150 return an ISession object
146- """
151+ """
147152 if session is None :
148153 session = library .ISession ()
149154 # NOTE: The following hack handles the issue of unknown machine state.
@@ -153,26 +158,28 @@ def create_session(self, lock_type=library.LockType.shared,
153158 # virtualbox.library.VBoxErrorVmError: 0x80bb0003 (Failed to \
154159 # get a console object from the direct session (Unknown \
155160 # Status 0x80BB0002))
156- for i in range (10 ):
161+ error = None
162+ for _ in range (10 ):
157163 try :
158164 self .lock_machine (session , lock_type )
159165 except Exception as exc :
166+ error = exc
160167 time .sleep (1 )
161168 continue
162169 else :
163170 break
164171 else :
165- raise Exception ("Failed to create clone - %s" % exc )
172+ if error is not None :
173+ raise Exception ("Failed to create clone - %s" % error )
166174 return session
167175
168- # Simplify the launch_vm_process. Build a ISession if it has not been
169- # defined...
176+ # Simplify the launch_vm_process. Build a ISession if it has not been defined...
170177 def launch_vm_process (self , session = None , type_p = 'gui' , environment = '' ):
171178 if session is None :
172179 local_session = library .ISession ()
173180 else :
174181 local_session = session
175- p = super (IMachine , self ).launch_vm_process (local_session ,
182+ p = super (IMachine , self ).launch_vm_process (local_session ,
176183 type_p , environment )
177184 if session is None :
178185 p .wait_for_completion (- 1 )
@@ -181,7 +188,7 @@ def launch_vm_process(self, session=None, type_p='gui', environment=''):
181188 launch_vm_process .__doc__ = library .IMachine .launch_vm_process .__doc__
182189
183190 # BUG: xidl describes this function as exportTo. The interface seems
184- # to export plain "export" instead...
191+ # to export plain "export" instead...
185192 def export_to (self , appliance , location ):
186193 if not isinstance (appliance , library .IAppliance ):
187194 msg = "appliance can only be an instance of type IAppliance"
@@ -190,12 +197,11 @@ def export_to(self, appliance, location):
190197 raise TypeError ("value is not an instance of basestring" )
191198 # see https://github.com/mjdorma/pyvbox/issues/40
192199 description = self ._call ("exportTo" ,
193- in_p = [appliance , location ])
194- description = library .IVirtualSystemDescription (description )
195- return description
200+ in_p = [appliance , location ])
201+ return library .IVirtualSystemDescription (description )
196202 export_to .__doc__ = library .IMachine .export_to .__doc__
197203
198- #if no snapshot has been supplied, try using the current_snapshot
204+ # If no snapshot has been supplied, try using the current_snapshot
199205 def restore_snapshot (self , snapshot = None ):
200206 if snapshot is None :
201207 if self .current_snapshot :
0 commit comments