Commit 37d581b8 authored by Nikos Skalkotos's avatar Nikos Skalkotos

Support private images

Support images that can only be deployed by the user that registers
the image to cyclades
parent fd9af948
......@@ -143,9 +143,9 @@ class BundleVolume(object):
# Copy the Secondary GPT Header
table = GPTPartitionTable(self.disk.device.path)
dd('if=%s' % self.disk.device.path, 'of=%s' % image,
'bs=%d' % self.disk.device.sectorSize, 'conv=notrunc',
'seek=%d' % table.primary.last_usable_lba,
'skip=%d' % table.primary.last_usable_lba)
'bs=%d' % self.disk.device.sectorSize, 'conv=notrunc',
'seek=%d' % table.primary.last_usable_lba,
'skip=%d' % table.primary.last_usable_lba)
# Create the Extended boot records (EBRs) in the image
extended = self.disk.getExtendedPartition()
......
......@@ -185,8 +185,10 @@ def register_image(session):
d = session["dialog"]
dev = session['device']
is_public = False
if "account" not in session:
d.msgbox("You need to provide your ~okeanos login username before you "
d.msgbox("You need to provide your ~okeanos credentians before you "
"can register an images to cyclades",
width=SMALL_WIDTH)
return False
......@@ -206,6 +208,15 @@ def register_image(session):
if len(name) == 0:
d.msgbox("Registration name cannot be empty", width=SMALL_WIDTH)
continue
ret = d.yesno("Make the image public?\\nA public image is accessible"
"by every user of the service.", defaultno=1,
width=WIDTH)
if ret not in (0, 1):
continue
is_public = True if ret == 0 else False
break
metadata = {}
......@@ -214,15 +225,17 @@ def register_image(session):
for key in session['task_metadata']:
metadata[key] = 'yes'
img_type = "public" if is_public else "private"
gauge = GaugeOutput(d, "Image Registration", "Registering image...")
try:
out = dev.out
out.add(gauge)
try:
out.output("Registering image with Cyclades...")
out.output("Registering %s image with Cyclades..." % img_type)
try:
kamaki = Kamaki(session['account'], out)
kamaki.register(name, session['pithos_uri'], metadata)
kamaki.register(name, session['pithos_uri'], metadata,
is_public)
out.success('done')
except ClientError as e:
d.msgbox("Error in pithos+ client: %s" % e.message)
......@@ -232,8 +245,8 @@ def register_image(session):
finally:
gauge.cleanup()
d.msgbox("Image `%s' was successfully registered with Cyclades as `%s'" %
(session['upload'], name), width=SMALL_WIDTH)
d.msgbox("%s image `%s' was successfully registered with Cyclades as `%s'"
% (img_type.title(), session['upload'], name), width=SMALL_WIDTH)
return True
......@@ -286,7 +299,7 @@ def kamaki_menu(session):
else:
del session['account']
d.msgbox("The token you provided is not valid!",
width=SMALL_WIDTH)
width=SMALL_WIDTH)
elif choice == "Upload":
if upload_image(session):
default_item = "Register"
......
......@@ -103,12 +103,12 @@ class WizardRadioListPage(WizardPage):
choices = []
for i in range(len(self.choices)):
default = 1 if i == self.default else 0
default = 1 if self.choices[i][0] == self.default else 0
choices.append((self.choices[i][0], self.choices[i][1], default))
while True:
(code, answer) = \
d.radiolist(self.message, width=PAGE_WIDTH,
d.radiolist(self.message, height=10, width=PAGE_WIDTH,
ok_label="Next", cancel="Back", choices=choices,
title="(%d/%d) %s" % (index + 1, total, self.title)
)
......@@ -116,11 +116,8 @@ class WizardRadioListPage(WizardPage):
if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
return self.PREV
for i in range(len(choices)):
if self.choices[i] == answer:
self.default = i
w[name] = i
break
w[self.name] = answer
self.default = answer
return self.NEXT
......@@ -190,11 +187,15 @@ def wizard(session):
name = WizardInputPage("ImageName", "Please provide a name for the image:",
title="Image Name", init=session['device'].distro)
descr = WizardInputPage("ImageDescription",
"Please provide a description for the image:",
title="Image Description",
init=session['metadata']['DESCRIPTION'] if
'DESCRIPTION' in session['metadata'] else '')
descr = WizardInputPage(
"ImageDescription", "Please provide a description for the image:",
title="Image Description", init=session['metadata']['DESCRIPTION'] if
'DESCRIPTION' in session['metadata'] else '')
registration = WizardRadioListPage(
"ImageRegistration", "Please provide a registration type:",
[("Private", "Image is accessible only by this user"),
("Public", "Everyone can create VMs from this image")],
title="Registration Type", default="Private")
def validate_account(token):
if len(token) == 0:
......@@ -204,15 +205,14 @@ def wizard(session):
account = Kamaki.get_account(token)
if account is None:
session['dialog'].msgbox("The token you provided in not valid!",
width=PAGE_WIDTH)
width=PAGE_WIDTH)
raise WizardInvalidData
return account
account = WizardInputPage("account",
"Please provide your ~okeanos authentication token:",
title="~okeanos account token", init=init_token,
validate=validate_account)
account = WizardInputPage(
"account", "Please provide your ~okeanos authentication token:",
title="~okeanos account", init=init_token, validate=validate_account)
msg = "All necessary information has been gathered. Confirm and Proceed."
proceed = WizardYesNoPage(msg, title="Confirmation")
......@@ -221,6 +221,7 @@ def wizard(session):
w.add_page(name)
w.add_page(descr)
w.add_page(registration)
w.add_page(account)
w.add_page(proceed)
......@@ -296,8 +297,11 @@ def create_image(session):
out.success('done')
out.output()
out.output('Registering image with ~okeanos ...', False)
kamaki.register(wizard['ImageName'], pithos_file, metadata)
is_public = True if w['ImageRegistration'] == "Public" else False
out.output('Registering %s image with ~okeanos ...' %
w['ImageRegistration'].lower(), False)
kamaki.register(wizard['ImageName'], pithos_file, metadata,
is_public)
out.success('done')
out.output()
......@@ -306,8 +310,9 @@ def create_image(session):
finally:
out.remove(with_progress)
msg = "The image was successfully uploaded and registered with " \
"~okeanos. Would you like to keep a local copy of the image?"
msg = "The %s image was successfully uploaded and registered with " \
"~okeanos. Would you like to keep a local copy of the image?" \
% w['ImageRegistration'].lower()
if not d.yesno(msg, width=PAGE_WIDTH):
extract_image(session)
......
......@@ -77,8 +77,9 @@ class Kamaki(object):
config = Config()
pithos_url = config.get('store', 'url')
self.pithos_client = PithosClient(pithos_url,
self.account['auth_token'], self.account['uuid'], self.CONTAINER)
self.pithos_client = PithosClient(
pithos_url, self.account['auth_token'], self.account['uuid'],
self.CONTAINER)
image_url = config.get('image', 'url')
self.image_client = ImageClient(image_url, self.account['auth_token'])
......@@ -103,15 +104,15 @@ class Kamaki(object):
return "pithos://%s/%s/%s" % (self.account['uuid'], self.CONTAINER,
path)
def register(self, name, location, metadata):
def register(self, name, location, metadata, public=False):
"""Register an image to ~okeanos"""
# Convert all metadata to strings
str_metadata = {}
for (key, value) in metadata.iteritems():
str_metadata[str(key)] = str(value)
params = {'is_public': 'true', 'disk_format': 'diskdump'}
is_public = 'true' if public else 'false'
params = {'is_public': is_public, 'disk_format': 'diskdump'}
self.image_client.register(name, location, params, str_metadata)
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
......@@ -118,6 +118,10 @@ def parse_options(input_args):
parser.add_option("--no-shrink", dest="shrink", default=True,
help="don't shrink any partition", action="store_false")
parser.add_option("--public", dest="public", default=False,
help="register image to cyclades as public",
action="store_true")
parser.add_option("--tmpdir", dest="tmp", type="string", default=None,
help="create large temporary image files under DIR",
metavar="DIR")
......@@ -135,7 +139,8 @@ def parse_options(input_args):
raise FatalError("You also need to set -u when -r option is set")
if options.upload and options.token is None:
raise FatalError("Image uploading cannot be performed. "
raise FatalError(
"Image uploading cannot be performed. "
"No authentication token is specified. Use -t to set a token")
if options.tmp is not None and not os.path.isdir(options.tmp):
......@@ -270,7 +275,8 @@ def image_creator():
out.output("Uploading image to pithos:")
kamaki = Kamaki(account, out)
with open(snapshot, 'rb') as f:
uploaded_obj = kamaki.upload(f, size, options.upload,
uploaded_obj = kamaki.upload(
f, size, options.upload,
"(1/4) Calculating block hashes",
"(2/4) Uploading missing blocks")
......@@ -289,8 +295,11 @@ def image_creator():
out.output()
if options.register:
out.output('Registering image with ~okeanos ...', False)
kamaki.register(options.register, uploaded_obj, metadata)
img_type = 'public' if options.public else 'private'
out.output('Registering %s image with ~okeanos ...' % img_type,
False)
kamaki.register(options.register, uploaded_obj, metadata,
options.public)
out.success('done')
out.output()
except ClientError as e:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment