Revision 74780ad6

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