Skip to content
Snippets Groups Projects
Commit 7f623b20 authored by Nikos Skalkotos's avatar Nikos Skalkotos
Browse files

Merge Deploy and Customize menu entries

Populate Sysprep entry in "Image Customization Menu". Not fully
working.
parent 755e1885
No related branches found
No related tags found
No related merge requests found
...@@ -46,27 +46,30 @@ from image_creator.output.dialog import InitializationOutput, GaugeOutput ...@@ -46,27 +46,30 @@ from image_creator.output.dialog import InitializationOutput, GaugeOutput
from image_creator.disk import Disk from image_creator.disk import Disk
from image_creator.os_type import os_cls from image_creator.os_type import os_cls
from image_creator.kamaki_wrapper import Kamaki, ClientError from image_creator.kamaki_wrapper import Kamaki, ClientError
from image_creator.help import get_help_file
MSGBOX_WIDTH = 60 MSGBOX_WIDTH = 60
YESNO_WIDTH = 50 YESNO_WIDTH = 50
MENU_WIDTH = 70 MENU_WIDTH = 70
INPUTBOX_WIDTH = 70 INPUTBOX_WIDTH = 70
CHECKBOX_WIDTH = 70
CONFIGURATION_TASKS = {
"FixPartitionTable": CONFIGURATION_TASKS = [
"Enlarge last partition to use all the available space", ("Partition table manipulation", ["FixPartitionTable"],
"FilesystemResizeUnmounted": ["linux", "windows"]),
"Resize file system to use all the available space", ("File system resize",
"AddSwap": "Set up the swap partition and add an entry in fstab", ["FilesystemResizeUnmounted", "FilesystemResizeMounted"],
"DeleteSSHKeys": "Remove ssh keys and in some cases recreate them", ["linux", "windows"]),
"DisableRemoteDesktopConnections": ("Swap partition configuration", ["AddSwap"], ["linux"]),
"Temporary Disable Remote Desktop Connections", ("SSH keys removal", ["DeleteSSHKeys"], ["linux"]),
"40SELinuxAutorelabel": "Force the system to relabel at next boot", ("Temporal RDP disabling", ["DisableRemoteDesktopConnections"], ["windows"]),
"AssignHostname": "Assign Hostname/Computer Name to the instance", ("SELinux relabeling at next boot", ["SELinuxAutorelabel"],
"ChangePassword": "Changes Password for specified users", ["linux"]),
"EnforcePersonality": "Inject files to the instance", ("Hostname/Computer Name assignment", ["AssignHostname"],
"FilesystemResizeMounted": ["windows", "linux"]),
"Resize filesystem to use all the available space"} ("Password change", ["ChangePassword"], ["windows", "linux"]),
("File injection", ["EnforcePersonality"], ["windows", "linux"])
]
class Reset(Exception): class Reset(Exception):
...@@ -234,6 +237,7 @@ def upload_image(session): ...@@ -234,6 +237,7 @@ def upload_image(session):
d.msgbox("Image file `%s' was successfully uploaded to pithos+" % filename, d.msgbox("Image file `%s' was successfully uploaded to pithos+" % filename,
width=MSGBOX_WIDTH) width=MSGBOX_WIDTH)
return True return True
...@@ -429,7 +433,7 @@ def delete_properties(session): ...@@ -429,7 +433,7 @@ def delete_properties(session):
choices.append((key, "%s" % val, 0)) choices.append((key, "%s" % val, 0))
(code, to_delete) = d.checklist("Choose which properties to delete:", (code, to_delete) = d.checklist("Choose which properties to delete:",
choices=choices) choices=choices, width=CHECKBOX_WIDTH)
count = len(to_delete) count = len(to_delete)
# If the user exits with ESC or CANCEL, the returned tag list is empty. # If the user exits with ESC or CANCEL, the returned tag list is empty.
for i in to_delete: for i in to_delete:
...@@ -439,39 +443,127 @@ def delete_properties(session): ...@@ -439,39 +443,127 @@ def delete_properties(session):
d.msgbox("%d image properties were deleted.", width=MSGBOX_WIDTH) d.msgbox("%d image properties were deleted.", width=MSGBOX_WIDTH)
def exclude_task(session): def exclude_tasks(session):
d = session['dialog'] d = session['dialog']
index = 0
displayed_index = 1
choices = [] choices = []
for (key, val) in session['metadata'].items(): mapping = {}
choices.append((key, "%s" % val, 0)) if 'excluded_tasks' not in session:
session['excluded_tasks'] = []
if -1 in session['excluded_tasks']:
if not d.yesno("Image deployment configuration is disabled. "
"Do you wish to enable it?", width=YESNO_WIDTH):
session['excluded_tasks'].remove(-1)
else:
return
for (msg, task, osfamily) in CONFIGURATION_TASKS:
if session['metadata']['OSFAMILY'] in osfamily:
checked = 1 if index in session['excluded_tasks'] else 0
choices.append((str(displayed_index), msg, checked))
mapping[displayed_index] = index
displayed_index += 1
index += 1
(code, to_delete) = d.checklist("Choose which properties to delete:", while 1:
choices=choices) (code, tags) = d.checklist(
count = len(to_delete) "Please choose which configuration tasks you would like to "
# If the user exits with ESC or CANCEL, the returned tag list is empty. "prevent from running during image deployment. "
for i in to_delete: "Press <No Config> to supress any configuration. "
del session['metadata'][i] "Press <Help> for more help on the image deployment configuration "
"tasks.", height=19, list_height=8,
title="Exclude Configuration Tasks", choices=choices,
width=CHECKBOX_WIDTH, help_button=1, extra_button=1,
extra_label="No Config")
if count > 0: if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
d.msgbox("%d image properties were deleted.", width=MSGBOX_WIDTH) break
elif code == d.DIALOG_HELP:
help_file = get_help_file("configuration_tasks")
assert os.path.exists(help_file)
d.textbox(help_file, title="Configuration Tasks",
width=70, height=40)
continue
elif code == d.DIALOG_EXTRA:
session['excluded_tasks'] = [-1]
session['task_metadata'] = ["EXCLUDE_ALL_TASKS"]
break
elif code == d.DIALOG_OK:
session['excluded_tasks'] = []
for tag in tags:
session['excluded_tasks'].append(mapping[int(tag)])
exclude_metadata = []
for task in session['excluded_tasks']:
exclude_metadata.extend(CONFIGURATION_TASKS[task][1])
def deploy_menu(session): session['task_metadata'] = \
map(lambda x: "EXCLUDE_TASK_%s" % x, exclude_metadata)
break
def sysprep(session):
d = session['dialog'] d = session['dialog']
image_os = session['image_os']
syspreps = image_os.list_syspreps()
wrapper = textwrap.TextWrapper()
wrapper.width = 65
sysprep_help = "System Preperation Tasks"
sysprep_help += "\n%s\n\n" % ('=' * len(sysprep_help))
default_item = "View/Modify" while 1:
actions = {"View/Modify": modify_properties, "Delete": delete_properties} choices = []
index = 0
for sysprep in syspreps:
name, descr = image_os.sysprep_info(sysprep)
display_name = name.replace('-', ' ').capitalize()
sysprep_help += "%s\n%s\n%s\n\n" % \
(display_name, '-' * len(display_name),
wrapper.fill(" ".join(descr.split())))
enabled = 1 if sysprep.enabled else 0
choices.append((str(index + 1), display_name, enabled))
index += 1
(code, tags) = d.checklist(
"Please choose which system preperation tasks you would like to "
"run on the image. Press <Help> to see details about the system "
"preperation tasks.",
title="Run system preperation tasks", choices=choices,
width=70, ok_label="Run", help_button=1)
if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
break
if code == d.DIALOG_HELP:
d.scrollbox(sysprep_help, width=70)
continue
def customize_menu(session):
d = session['dialog']
default_item = "Sysprep"
actions = {"Sysprep": sysprep,
"View/Modify": modify_properties,
"Delete": delete_properties,
"Exclude": exclude_tasks}
while 1: while 1:
(code, choice) = d.menu( (code, choice) = d.menu(
"Choose one of the following or press <Back> to exit.", "Choose one of the following or press <Back> to exit.",
width=MENU_WIDTH, width=MENU_WIDTH,
choices=[("View/Modify", "View/Modify image properties"), choices=[("Sysprep", "Run various image preperation tasks"),
("Shrink", "Shrink image"),
("View/Modify", "View/Modify image properties"),
("Delete", "Delete image properties"), ("Delete", "Delete image properties"),
("Exclude", "Exclude configuration tasks from running")], ("Exclude",
cancel="Back", "Exclude various deployment tasks from running")],
default_item=default_item, cancel="Back",
title="Image Deployment Menu") default_item=default_item,
title="Image Customization Menu")
if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
break break
...@@ -484,7 +576,7 @@ def main_menu(session): ...@@ -484,7 +576,7 @@ def main_menu(session):
d = session['dialog'] d = session['dialog']
dev = session['device'] dev = session['device']
d.setBackgroundTitle("OS: %s, Distro: %s" % (dev.ostype, dev.distro)) d.setBackgroundTitle("OS: %s, Distro: %s" % (dev.ostype, dev.distro))
actions = {"Deploy": deploy_menu, actions = {"Customize": customize_menu,
"Register": kamaki_menu, "Register": kamaki_menu,
"Extract": extract_image} "Extract": extract_image}
default_item = "Customize" default_item = "Customize"
...@@ -493,29 +585,23 @@ def main_menu(session): ...@@ -493,29 +585,23 @@ def main_menu(session):
(code, choice) = d.menu( (code, choice) = d.menu(
"Choose one of the following or press <Exit> to exit.", "Choose one of the following or press <Exit> to exit.",
width=MENU_WIDTH, width=MENU_WIDTH,
choices=[("Customize", "Run various image customization tasks"), choices=[("Customize",
("Deploy", "Configure ~okeanos image deployment options"), "Customize image and ~okeanos deployment options"),
("Register", "Register image to ~okeanos"), ("Register", "Register image to ~okeanos"),
("Extract", "Dump image to local file system"), ("Extract", "Dump image to local file system"),
("Reset", "Reset everything and start over again"), ("Reset", "Reset everything and start over again"),
("Help", "Get help for using snf-image-creator")], ("Help", "Get help for using snf-image-creator")],
cancel="Exit", cancel="Exit", menu_height=5, height=13, default_item=default_item,
default_item=default_item,
title="Image Creator for ~okeanos (snf-image-creator version %s)" % title="Image Creator for ~okeanos (snf-image-creator version %s)" %
version) version)
if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
if confirm_exit(d): if confirm_exit(d):
break break
else: elif choice == "Reset":
continue
if choice == "Reset":
if confirm_reset(d): if confirm_reset(d):
d.infobox("Resetting snf-image-creator. Please wait...") d.infobox("Resetting snf-image-creator. Please wait...")
raise Reset raise Reset
else:
continue
elif choice in actions: elif choice in actions:
actions[choice](session) actions[choice](session)
...@@ -542,20 +628,6 @@ def select_file(d, media): ...@@ -542,20 +628,6 @@ def select_file(d, media):
return media return media
def collect_metadata(dev, out):
out.output("Collecting image metadata...")
metadata = dev.meta
dev.mount(readonly=True)
cls = os_cls(dev.distro, dev.ostype)
image_os = cls(dev.root, dev.g, out)
dev.umount()
metadata.update(image_os.meta)
out.success("done")
return metadata
def image_creator(d): def image_creator(d):
basename = os.path.basename(sys.argv[0]) basename = os.path.basename(sys.argv[0])
usage = "Usage: %s [input_media]" % basename usage = "Usage: %s [input_media]" % basename
...@@ -580,7 +652,14 @@ def image_creator(d): ...@@ -580,7 +652,14 @@ def image_creator(d):
snapshot = disk.snapshot() snapshot = disk.snapshot()
dev = disk.get_device(snapshot) dev = disk.get_device(snapshot)
metadata = collect_metadata(dev, out) out.output("Collecting image metadata...")
metadata = dev.meta
dev.mount(readonly=True)
cls = os_cls(dev.distro, dev.ostype)
image_os = cls(dev.root, dev.g, out)
dev.umount()
metadata.update(image_os.meta)
out.success("done")
out.cleanup() out.cleanup()
# Make sure the signal handler does not call out.cleanup again # Make sure the signal handler does not call out.cleanup again
...@@ -593,6 +672,7 @@ def image_creator(d): ...@@ -593,6 +672,7 @@ def image_creator(d):
"disk": disk, "disk": disk,
"snapshot": snapshot, "snapshot": snapshot,
"device": dev, "device": dev,
"image_os": image_os,
"metadata": metadata} "metadata": metadata}
main_menu(session) main_menu(session)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment