Revision d415dda2
b/image_creator/dialog_menu.py | ||
---|---|---|
615 | 615 |
return True |
616 | 616 |
|
617 | 617 |
|
618 |
def sysprep_params(session): |
|
619 |
|
|
620 |
d = session['dialog'] |
|
621 |
image = session['image'] |
|
622 |
|
|
623 |
available = image.os.sysprep_params |
|
624 |
needed = image.os.needed_sysprep_params() |
|
625 |
|
|
626 |
if len(needed) == 0: |
|
627 |
return True |
|
628 |
|
|
629 |
fields = [] |
|
630 |
for param in needed: |
|
631 |
default = available[param.name] if param.name in available else "" |
|
632 |
fields.append(("%s: " % param.description, default, param.length)) |
|
633 |
|
|
634 |
txt = "Please provide the following system preparation parameters:" |
|
635 |
code, output = d.form(txt, height=13, width=WIDTH, form_height=len(fields), |
|
636 |
fields=fields) |
|
637 |
|
|
638 |
if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): |
|
639 |
return False |
|
640 |
|
|
641 |
sysprep_params = {} |
|
642 |
for i in range(len(fields)): |
|
643 |
if needed[i].validator(output[i]): |
|
644 |
image.os.sysprep_params[needed[i].name] = output[i] |
|
645 |
else: |
|
646 |
d.msgbox("The value you provided for parameter: %s is not valid" % |
|
647 |
name, width=SMALL_WIDTH) |
|
648 |
return False |
|
649 |
|
|
650 |
return True |
|
651 |
|
|
652 |
|
|
618 | 653 |
def sysprep(session): |
619 | 654 |
"""Perform various system preperation tasks on the image""" |
620 | 655 |
d = session['dialog'] |
... | ... | |
677 | 712 |
title="System Preperation", width=SMALL_WIDTH) |
678 | 713 |
continue |
679 | 714 |
|
715 |
if not sysprep_params(session): |
|
716 |
continue |
|
717 |
|
|
680 | 718 |
infobox = InfoBoxOutput(d, "Image Configuration") |
681 | 719 |
try: |
682 | 720 |
image.out.add(infobox) |
b/image_creator/dialog_wizard.py | ||
---|---|---|
208 | 208 |
return self.NEXT |
209 | 209 |
|
210 | 210 |
|
211 |
class WizardFormPage(WizardPage): |
|
212 |
"""Represents a Form in a wizard""" |
|
213 |
|
|
214 |
def __init__(self, name, display_name, text, fields, **kargs): |
|
215 |
super(WizardFormPage, self).__init__(name, display_name, text, **kargs) |
|
216 |
self.fields = fields |
|
217 |
|
|
218 |
def run(self, session, title): |
|
219 |
d = session['dialog'] |
|
220 |
w = session['wizard'] |
|
221 |
|
|
222 |
field_lenght = len(self.fields()) |
|
223 |
form_height = field_lenght if field_lenght < PAGE_HEIGHT - 4 \ |
|
224 |
else PAGET_HEIGHT - 4 |
|
225 |
|
|
226 |
(code, output) = d.form( |
|
227 |
self.text, width=PAGE_WIDTH, height=PAGE_HEIGHT, |
|
228 |
form_height=form_height, ok_label="Next", cancel="Back", |
|
229 |
fields=self.fields(), title=title) |
|
230 |
|
|
231 |
if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): |
|
232 |
return self.PREV |
|
233 |
|
|
234 |
w[self.name] = self.validate(output) |
|
235 |
self.default = output |
|
236 |
self.info = "%s: %s" % (self.display_name, self.display(w[self.name])) |
|
237 |
|
|
238 |
return self.NEXT |
|
239 |
|
|
240 |
|
|
211 | 241 |
class WizardMenuPage(WizardPageWthChoices): |
212 | 242 |
"""Represents a menu dialog with available choices in a wizard""" |
213 | 243 |
|
... | ... | |
250 | 280 |
def start_wizard(session): |
251 | 281 |
"""Run the image creation wizard""" |
252 | 282 |
|
253 |
distro = session['image'].distro |
|
254 |
ostype = session['image'].ostype |
|
283 |
image = session['image'] |
|
284 |
distro = image.distro |
|
285 |
ostype = image.ostype |
|
255 | 286 |
|
287 |
# Create Cloud Wizard Page |
|
256 | 288 |
def cloud_choices(): |
257 | 289 |
choices = [] |
258 | 290 |
for (name, cloud) in Kamaki.get_clouds().items(): |
... | ... | |
279 | 311 |
if edit_cloud(session, cloud): |
280 | 312 |
return cloud |
281 | 313 |
|
282 |
raise WizardInvalidData
|
|
314 |
raise WizardReloadPage
|
|
283 | 315 |
|
284 | 316 |
return cloud |
285 | 317 |
|
... | ... | |
289 | 321 |
choices=cloud_choices, extra_label="Add", extra=cloud_add, |
290 | 322 |
title="Clouds", validate=cloud_validate, fallback=cloud_none_available) |
291 | 323 |
|
324 |
# Create Image Name Wizard Page |
|
292 | 325 |
name = WizardInputPage( |
293 | 326 |
"ImageName", "Image Name", "Please provide a name for the image:", |
294 | 327 |
title="Image Name", default=ostype if distro == "unknown" else distro) |
295 | 328 |
|
329 |
# Create Image Description Wizard Page |
|
296 | 330 |
descr = WizardInputPage( |
297 | 331 |
"ImageDescription", "Image Description", |
298 | 332 |
"Please provide a description for the image:", |
299 | 333 |
title="Image Description", default=session['metadata']['DESCRIPTION'] |
300 | 334 |
if 'DESCRIPTION' in session['metadata'] else '') |
301 | 335 |
|
336 |
# Create Sysprep Params Wizard Page |
|
337 |
needed = image.os.needed_sysprep_params() |
|
338 |
|
|
339 |
def sysprep_params_fields(): |
|
340 |
fields = [] |
|
341 |
available = image.os.sysprep_params |
|
342 |
for param in needed: |
|
343 |
text = param.description |
|
344 |
default = available[param.name] if param.name in available else "" |
|
345 |
fields.append(("%s: " % text, default, param.length)) |
|
346 |
return fields |
|
347 |
|
|
348 |
def sysprep_params_validate(answer): |
|
349 |
params = {} |
|
350 |
for i in range(len(answer)): |
|
351 |
if needed[i].validator(answer): |
|
352 |
params[needed[i].name] = answer[i] |
|
353 |
else: |
|
354 |
session['dialog'].msgbox("Invalid value for parameter `%s'" % |
|
355 |
needed[i].name) |
|
356 |
raise WizardReloadPage |
|
357 |
return params |
|
358 |
|
|
359 |
def sysprep_params_display(params): |
|
360 |
return ",".join(["%s=%s" % (key, val) for key, val in params.items()]) |
|
361 |
|
|
362 |
sysprep_params = WizardFormPage( |
|
363 |
"SysprepParams", "Sysprep Parameters", |
|
364 |
"Prease fill in the following system preparation parameters:", |
|
365 |
title="System Preparation Parameters", fields=sysprep_params_fields, |
|
366 |
display=sysprep_params_display, validate=sysprep_params_validate |
|
367 |
) if len(needed) != 0 else None |
|
368 |
|
|
369 |
# Create Image Registration Wizard Page |
|
302 | 370 |
def registration_choices(): |
303 | 371 |
return [("Private", "Image is accessible only by this user"), |
304 | 372 |
("Public", "Everyone can create VMs from this image")] |
... | ... | |
313 | 381 |
w.add_page(cloud) |
314 | 382 |
w.add_page(name) |
315 | 383 |
w.add_page(descr) |
384 |
if sysprep_params is not None: |
|
385 |
w.add_page(sysprep_params) |
|
316 | 386 |
w.add_page(registration) |
317 | 387 |
|
318 | 388 |
if w.run(): |
... | ... | |
336 | 406 |
out.clear() |
337 | 407 |
|
338 | 408 |
#Sysprep |
409 |
image.os.sysprep_params.update(wizard['SysprepParams']) |
|
339 | 410 |
image.os.do_sysprep() |
340 | 411 |
metadata = image.os.meta |
341 | 412 |
|
b/image_creator/disk.py | ||
---|---|---|
187 | 187 |
self.out.success('done') |
188 | 188 |
return "/dev/mapper/%s" % snapshot |
189 | 189 |
|
190 |
def get_image(self, media): |
|
190 |
def get_image(self, media, **kargs):
|
|
191 | 191 |
"""Returns a newly created Image instance.""" |
192 | 192 |
|
193 |
image = Image(media, self.out) |
|
193 |
image = Image(media, self.out, **kargs)
|
|
194 | 194 |
self._images.append(image) |
195 | 195 |
image.enable() |
196 | 196 |
return image |
b/image_creator/image.py | ||
---|---|---|
45 | 45 |
class Image(object): |
46 | 46 |
"""The instances of this class can create images out of block devices.""" |
47 | 47 |
|
48 |
def __init__(self, device, output, meta={}):
|
|
48 |
def __init__(self, device, output, **kargs):
|
|
49 | 49 |
"""Create a new Image instance""" |
50 | 50 |
|
51 | 51 |
self.device = device |
52 | 52 |
self.out = output |
53 |
self.meta = meta |
|
53 |
|
|
54 |
self.meta = kargs['meta'] if 'meta' in kargs else {} |
|
55 |
self.sysprep_params = \ |
|
56 |
kargs['sysprep_params'] if 'sysprep_params' in kargs else {} |
|
57 |
|
|
54 | 58 |
self.progress_bar = None |
55 | 59 |
self.guestfs_device = None |
56 | 60 |
self.size = 0 |
... | ... | |
117 | 121 |
self.enable() |
118 | 122 |
|
119 | 123 |
cls = os_cls(self.distro, self.ostype) |
120 |
self._os = cls(self) |
|
124 |
self._os = cls(self, sysprep_params=self.sysprep_params)
|
|
121 | 125 |
|
122 | 126 |
self._os.collect_metadata() |
123 | 127 |
|
b/image_creator/main.py | ||
---|---|---|
121 | 121 |
"input media", default=[], action="append", |
122 | 122 |
metavar="SYSPREP") |
123 | 123 |
|
124 |
parser.add_option("--sysprep-param", dest="sysprep_params", default=[], |
|
125 |
help="Add KEY=VALUE system preparation parameter", |
|
126 |
action="append") |
|
127 |
|
|
124 | 128 |
parser.add_option("--no-sysprep", dest="sysprep", default=True, |
125 | 129 |
help="don't perform any system preparation operation", |
126 | 130 |
action="store_false") |
... | ... | |
170 | 174 |
meta[key] = value |
171 | 175 |
options.metadata = meta |
172 | 176 |
|
177 |
sysprep_params = {} |
|
178 |
for p in options.sysprep_params: |
|
179 |
try: |
|
180 |
key, value = p.split('=', 1) |
|
181 |
except ValueError: |
|
182 |
raise FatalError("Sysprep parameter optiont: `%s' is not in " |
|
183 |
"KEY=VALUE format." % p) |
|
184 |
sysprep_params[key] = value |
|
185 |
options.sysprep_params = sysprep_params |
|
186 |
|
|
173 | 187 |
return options |
174 | 188 |
|
175 | 189 |
|
... | ... | |
253 | 267 |
try: |
254 | 268 |
snapshot = disk.snapshot() |
255 | 269 |
|
256 |
image = disk.get_image(snapshot) |
|
270 |
image = disk.get_image(snapshot, sysprep_params=options.sysprep_params)
|
|
257 | 271 |
|
258 | 272 |
for sysprep in options.disabled_syspreps: |
259 | 273 |
image.os.disable_sysprep(image.os.get_sysprep_by_name(sysprep)) |
b/image_creator/os_type/__init__.py | ||
---|---|---|
41 | 41 |
|
42 | 42 |
import textwrap |
43 | 43 |
import re |
44 |
from collections import namedtuple |
|
44 | 45 |
|
45 | 46 |
|
46 | 47 |
def os_cls(distro, osfamily): |
... | ... | |
79 | 80 |
class OSBase(object): |
80 | 81 |
"""Basic operating system class""" |
81 | 82 |
|
82 |
def __init__(self, image): |
|
83 |
SysprepParam = namedtuple('SysprepParam', |
|
84 |
'name description length validator') |
|
85 |
|
|
86 |
def __init__(self, image, **kargs): |
|
83 | 87 |
self.image = image |
84 | 88 |
|
85 | 89 |
self.root = image.root |
86 | 90 |
self.g = image.g |
87 | 91 |
self.out = image.out |
88 | 92 |
|
93 |
self.sysprep_params = \ |
|
94 |
kargs['sysprep_params'] if 'sysprep_params' in kargs else {} |
|
95 |
|
|
89 | 96 |
self.meta = {} |
90 | 97 |
|
91 | 98 |
def collect_metadata(self): |
... | ... | |
102 | 109 |
|
103 | 110 |
self.out.output() |
104 | 111 |
|
112 |
def needed_sysprep_params(self): |
|
113 |
"""Returns a list of needed sysprep parameters. Each element in the |
|
114 |
list is a SysprepParam object. |
|
115 |
""" |
|
116 |
return [] |
|
117 |
|
|
105 | 118 |
def list_syspreps(self): |
106 | 119 |
"""Returns a list of sysprep objects""" |
107 | 120 |
objs = [getattr(self, name) for name in dir(self) |
b/image_creator/os_type/linux.py | ||
---|---|---|
43 | 43 |
|
44 | 44 |
class Linux(Unix): |
45 | 45 |
"""OS class for Linux""" |
46 |
def __init__(self, image): |
|
47 |
super(Linux, self).__init__(image) |
|
46 |
def __init__(self, image, **kargs):
|
|
47 |
super(Linux, self).__init__(image, **kargs)
|
|
48 | 48 |
self._uuid = dict() |
49 | 49 |
self._persistent = re.compile('/dev/[hsv]d[a-z][1-9]*') |
50 | 50 |
|
Also available in: Unified diff