Newer
Older
# Copyright (C) 2011-2015 GRNET S.A.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""This module implements the "expert" mode of the dialog-based version of
snf-image-creator.
"""
import os
import textwrap
import StringIO
from image_creator import __version__ as version
from image_creator.util import FatalError, virtio_versions
from image_creator.output.dialog import GaugeOutput, InfoBoxOutput
from image_creator.kamaki_wrapper import Kamaki, ClientError, CONTAINER
from image_creator.help import get_help_file
from image_creator.dialog_util import SMALL_WIDTH, WIDTH, \
update_background_title, confirm_reset, confirm_exit, Reset, \
extract_image, add_cloud, edit_cloud, update_sysprep_param, select_file, \
copy_file, create_form_elements
("Partition table manipulation", ["FixPartitionTable"], lambda x: True),
["FilesystemResizeUnmounted", "FilesystemResizeMounted"], lambda x: True),
("Swap partition configuration", ["AddSwap"], lambda x: x == 'linux'),
("SSH keys removal", ["DeleteSSHKeys"], lambda x: x != 'windows'),
("Temporal RDP disabling", ["DisableRemoteDesktopConnections"],
lambda x: x == "windows"),
("SELinux relabeling at next boot", ["SELinuxAutorelabel"],
lambda x: x == "linux"),
("Hostname/Computer Name assignment", ["AssignHostname"], lambda x: True),
("Password change", ["ChangePassword"], lambda x: True),
("Network configuration", ["ConfigureNetwork"], lambda x: x != 'windows'),
("File injection", ["EnforcePersonality"], lambda x: True)
def __init__(self, session, meta):
self.session = session
self.meta = meta
def __enter__(self):
self.old = {}
for (k, v) in self.meta.items():
self.old[k] = v
def __exit__(self, exc_type, exc_val, exc_tb):
d = self.session['dialog']
altered = {}
added = {}
for (k, v) in self.meta.items():
if k not in self.old:
added[k] = v
elif self.old[k] != v:
altered[k] = v
if not (len(added) or len(altered)):
return
msg = "The last action has changed some image properties:\n\n"
if len(added):
msg += "New image properties:\n"
for (k, v) in added.items():
msg += ' %s: "%s"\n' % (k, v)
msg += "\n"
if len(altered):
msg += "Updated image properties:\n"
for (k, v) in altered.items():
msg += ' %s: "%s" -> "%s"\n' % (k, self.old[k], v)
msg += "\n"
d.msgbox(msg, title="Image Property Changes", width=SMALL_WIDTH)
def upload_image(session):
"""Upload the image to the storage service"""
d.msgbox("You need to select a valid cloud before you can upload "
"images to it", width=SMALL_WIDTH)
if 'uploaded' in session:
_, _, _, container, name = session['uploaded'].split('/')
elif 'OS' in session['image'].meta:
name = "%s.diskdump" % session['image'].meta['OS']
container = CONTAINER
name = ""
container = CONTAINER
fields = [("Remote Name:", name, 60), ("Container:", container, 60)]
(code, output) = d.form("Please provide the following upload info:",
create_form_elements(fields), height=11,
width=WIDTH, form_height=2)
if code in (d.CANCEL, d.ESC):
name, container = output
name = name.strip()
container = container.strip()
if len(name) == 0:
d.msgbox("Remote Name cannot be empty", width=SMALL_WIDTH)
continue
if len(container) == 0:
d.msgbox("Container cannot be empty", width=SMALL_WIDTH)
kamaki = Kamaki(session['account'], None)
overwrite = []
for f in (name, "%s.md5sum" % name, "%s.meta" % name):
if kamaki.object_exists(container, f):
overwrite.append(f)
if len(overwrite) > 0:
if d.yesno("The following storage service object(s) already "
"exist(s):\n%s\nDo you want to overwrite them?" %
"\n".join(overwrite), width=WIDTH, defaultno=1
) != d.OK:
session['checksum'] = image.md5()
with image.raw_device() as raw:
with open(raw, 'rb') as f:
session["uploaded"] = \
kamaki.upload(f, image.size, name, container,
"Calculating block hashes",
"Uploading missing blocks")
out.info("Uploading md5sum file ...")
md5str = "%s %s\n" % (session['checksum'], name)
kamaki.upload(StringIO.StringIO(md5str), size=len(md5str),
remote_path="%s.md5sum" % name,
container=container,
content_type="text/plain")
out.success("done")
except ClientError as e:
d.msgbox(
"Error in storage service client: %s" % e.message,
title="Storage Service Client Error", width=SMALL_WIDTH)
if 'uploaded' in session:
del session['uploaded']
return False
finally:
out.remove(gauge)
finally:
gauge.cleanup()
d.msgbox("Image file `%s' was successfully uploaded" % name,
width=SMALL_WIDTH)
return True
def register_image(session):
Loading
Loading full blame...