Revision 74780ad6 image_creator/os_type/windows.py
b/image_creator/os_type/windows.py | ||
---|---|---|
44 | 44 |
import os |
45 | 45 |
import time |
46 | 46 |
import random |
47 |
import subprocess |
|
47 | 48 |
|
48 | 49 |
kvm = get_command('kvm') |
49 | 50 |
|
... | ... | |
51 | 52 |
class Windows(OSBase): |
52 | 53 |
"""OS class for Windows""" |
53 | 54 |
|
54 |
@sysprep(enabled=False) |
|
55 |
def test(self, print_header=True): |
|
56 |
"""test sysprep""" |
|
57 |
pass |
|
55 |
def needed_sysprep_params(self): |
|
56 |
"""Returns a list of needed sysprep parameters. Each element in the |
|
57 |
list is a SysprepParam object. |
|
58 |
""" |
|
59 |
|
|
60 |
password = self.SysprepParam( |
|
61 |
'password', 'Image Administrator Password', 20, lambda x: True) |
|
62 |
|
|
63 |
return [password] |
|
64 |
|
|
65 |
@sysprep(enabled=True) |
|
66 |
def disable_ipv6_privacy_extensions(self, print_header=True): |
|
67 |
"""Disable IPv6 privacy extensions""" |
|
68 |
|
|
69 |
if print_header: |
|
70 |
self.out.output("Disabling IPv6 privacy extensions") |
|
71 |
|
|
72 |
out, err, rc = self._guest_exec( |
|
73 |
'netsh interface ipv6 set global randomizeidentifiers=disabled ' |
|
74 |
'store=persistent') |
|
75 |
|
|
76 |
if rc != 0: |
|
77 |
raise FatalError("Unable to disable IPv6 privacy extensions: %s" % |
|
78 |
err) |
|
79 |
|
|
80 |
@sysprep(enabled=True) |
|
81 |
def microsoft_sysprep(self, print_header=True): |
|
82 |
"""Run the Micorsoft System Preparation Tool on the Image. After this |
|
83 |
runs, no other task may run. |
|
84 |
""" |
|
85 |
|
|
86 |
if print_header: |
|
87 |
self.out.output("Executing sysprep on the image (may take more " |
|
88 |
"than 10 minutes)") |
|
89 |
|
|
90 |
out, err, rc = self._guest_exec(r'C:\windows\system32\sysprep\sysprep ' |
|
91 |
r'/quiet /generalize /oobe /shutdown') |
|
92 |
self.syspreped = True |
|
93 |
if rc != 0: |
|
94 |
raise FatalError("Unable to perform sysprep: %s" % err) |
|
58 | 95 |
|
59 | 96 |
def do_sysprep(self): |
60 | 97 |
"""Prepare system for image creation.""" |
... | ... | |
62 | 99 |
if getattr(self, 'syspreped', False): |
63 | 100 |
raise FatalError("Image is already syspreped!") |
64 | 101 |
|
102 |
txt = "System preparation parameter: `%s' is needed but missing!" |
|
103 |
for param in self.needed_sysprep_params(): |
|
104 |
if param[0] not in self.sysprep_params: |
|
105 |
raise FatalError(txt % param[0]) |
|
106 |
|
|
65 | 107 |
self.mount(readonly=False) |
66 | 108 |
try: |
67 | 109 |
disabled_uac = self._update_uac_remote_setting(1) |
... | ... | |
94 | 136 |
'-netdev', 'type=user,hostfwd=tcp::445-:445,id=netdev0', |
95 | 137 |
'-device', 'virtio-net-pci,mac=%s,netdev=netdev0' % |
96 | 138 |
random_mac(), '-vnc', ':0', _bg=True) |
97 |
time.sleep(30)
|
|
139 |
time.sleep(60)
|
|
98 | 140 |
self.out.success('done') |
141 |
|
|
142 |
tasks = self.list_syspreps() |
|
143 |
enabled = filter(lambda x: x.enabled, tasks) |
|
144 |
|
|
145 |
size = len(enabled) |
|
146 |
|
|
147 |
# Make sure the ms sysprep is the last task to run if it is enabled |
|
148 |
enabled = filter( |
|
149 |
lambda x: x.im_func.func_name != 'microsoft_sysprep', enabled) |
|
150 |
|
|
151 |
ms_sysprep_enabled = False |
|
152 |
if len(enabled) != size: |
|
153 |
enabled.append(self.ms_sysprep) |
|
154 |
ms_sysprep_enabled = True |
|
155 |
|
|
156 |
cnt = 0 |
|
157 |
for task in enabled: |
|
158 |
cnt += 1 |
|
159 |
self.out.output(('(%d/%d)' % (cnt, size)).ljust(7), False) |
|
160 |
task() |
|
161 |
setattr(task.im_func, 'executed', True) |
|
162 |
|
|
163 |
if not ms_sysprep_enabled: |
|
164 |
self._shutdown() |
|
165 |
|
|
99 | 166 |
vm.wait() |
100 | 167 |
finally: |
168 |
if vm.process.alive: |
|
169 |
vm.terminate() |
|
170 |
|
|
101 | 171 |
self.out.output("Relaunching helper VM (may take a while) ...", |
102 | 172 |
False) |
103 | 173 |
self.g.launch() |
... | ... | |
106 | 176 |
if disabled_uac: |
107 | 177 |
self._update_uac_remote_setting(0) |
108 | 178 |
|
109 |
self.syspreped = True |
|
179 |
def _shutdown(self): |
|
180 |
"""Shuts down the windows VM""" |
|
181 |
|
|
182 |
self.out.output("Shutting down windows VM ...", False) |
|
183 |
out, err, rc = self._guest_exec(r'shutdown /s /t 5') |
|
184 |
|
|
185 |
if rc != 0: |
|
186 |
raise FatalError("Unable to perform shutdown: %s" % err) |
|
187 |
|
|
188 |
self.out.success('done') |
|
110 | 189 |
|
111 | 190 |
def _registry_file_path(self, regfile): |
112 | 191 |
"""Retrieves the case sensitive path to a registry file""" |
... | ... | |
205 | 284 |
# Filter out the guest account |
206 | 285 |
return filter(lambda x: x != "Guest", users) |
207 | 286 |
|
287 |
def _guest_exec(self, command): |
|
288 |
user = "Administrator%" + self.sysprep_params['password'] |
|
289 |
addr = 'localhost' |
|
290 |
runas = '--runas=%s' % user |
|
291 |
winexe = subprocess.Popen( |
|
292 |
['winexe', '-U', user, "//%s" % addr, runas, command], |
|
293 |
stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
|
294 |
|
|
295 |
result = winexe.communicate() |
|
296 |
rc = winexe.poll() |
|
297 |
|
|
298 |
return (result[0], result[1], rc) |
|
299 |
|
|
208 | 300 |
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai : |
Also available in: Unified diff