def _check_cloud(session, name, url, token): """Checks if the provided info for a cloud are valid""" d = session['dialog'] regexp = re.compile(r'^[~@#$:\-\w]+$') if not re.match(regexp, name): d.msgbox("Allowed characters for name: a-zA-Z0-9_~@#$:-", width=WIDTH) return False if len(url) == 0: d.msgbox("URL cannot be empty!", width=WIDTH) return False if len(token) == 0: d.msgbox("Token cannot be empty!", width=WIDTH) return False if Kamaki.create_account(url, token) is None: d.msgbox( "The cloud info you provided is not valid. Please check the " "Authentication URL and the token values again!", width=WIDTH) return False return True
def _check_cloud(session, name, url, token): """Checks if the provided info for a cloud are valid""" d = session['dialog'] regexp = re.compile(r'^[~@#$:\-\w]+$') if not re.match(regexp, name): d.msgbox("Allowed characters for name: a-zA-Z0-9_~@#$:-", width=WIDTH) return False if len(url) == 0: d.msgbox("URL cannot be empty!", width=WIDTH) return False if len(token) == 0: d.msgbox("Token cannot be empty!", width=WIDTH) return False if Kamaki.create_account(url, token) is None: d.msgbox("The cloud info you provided is not valid. Please check the " "Authentication URL and the token values again!", width=WIDTH) return False return True
def image_creator(options, out): """snf-mkimage main function""" if os.geteuid() != 0: raise FatalError("You must run %s as root" % os.path.basename(sys.argv[0])) # Check if the authentication info is valid. The earlier the better if options.token is not None and options.url is not None: try: account = Kamaki.create_account(options.url, options.token) if account is None: raise FatalError("The authentication token and/or URL you " "provided is not valid!") else: kamaki = Kamaki(account, out) except ClientError as e: raise FatalError("Astakos client: %d %s" % (e.status, e.message)) elif options.cloud: avail_clouds = Kamaki.get_clouds() if options.cloud not in avail_clouds.keys(): raise FatalError( "Cloud: `%s' does not exist.\n\nAvailable clouds:\n\n\t%s\n" % (options.cloud, "\n\t".join(avail_clouds.keys()))) try: account = Kamaki.get_account(options.cloud) if account is None: raise FatalError( "Cloud: `%s' exists but is not valid!" % options.cloud) else: kamaki = Kamaki(account, out) except ClientError as e: raise FatalError("Astakos client: %d %s" % (e.status, e.message)) if options.upload and not options.force: if kamaki.object_exists(options.container, options.upload): raise FatalError("Remote storage service object: `%s' exists " "(use --force to overwrite it)." % options.upload) if kamaki.object_exists(options.container, "%s.md5sum" % options.upload): raise FatalError("Remote storage service object: `%s.md5sum' " "exists (use --force to overwrite it)." % options.upload) if options.register and not options.force: if kamaki.object_exists(options.container, "%s.meta" % options.upload): raise FatalError("Remote storage service object `%s.meta' exists " "(use --force to overwrite it)." % options.upload) disk = Disk(options.source, out, options.tmp) # pylint: disable=unused-argument def signal_handler(signum, frame): disk.cleanup() signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) try: # There is no need to snapshot the media if it was created by the Disk # instance as a temporary object. device = disk.file if not options.snapshot else disk.snapshot() image = disk.get_image(device, sysprep_params=options.sysprep_params) if image.is_unsupported() and not options.allow_unsupported: raise FatalError( "The media seems to be unsupported.\n\n" + textwrap.fill("To create an image from an unsupported media, " "you'll need to use the`--allow-unsupported' " "command line option. Using this is highly " "discouraged, since the resulting image will " "not be cleared out of sensitive data and will " "not get customized during the deployment.")) if len(options.host_run) != 0 and not image.mount_local_support: raise FatalError("Running scripts against the guest media is not " "supported for this build of libguestfs.") if len(options.host_run) != 0: for script in options.host_run: if not os.path.isfile(script): raise FatalError("File: `%s' does not exist." % script) if not os.access(script, os.X_OK): raise FatalError("File: `%s' is not executable." % script) for name in options.disabled_syspreps: sysprep = image.os.get_sysprep_by_name(name) if sysprep is not None: image.os.disable_sysprep(sysprep) else: out.warn("Sysprep: `%s' does not exist. Can't disable it." % name) for name in options.enabled_syspreps: sysprep = image.os.get_sysprep_by_name(name) if sysprep is not None: image.os.enable_sysprep(sysprep) else: out.warn("Sysprep: `%s' does not exist. Can't enable it." % name) if image.is_unsupported(): image.meta['EXCLUDE_ALL_TASKS'] = "yes" # Add command line metadata to the collected ones... image.meta.update(options.metadata) if options.print_syspreps: image.os.print_syspreps() out.info() if options.print_sysprep_params: image.os.print_sysprep_params() out.info() if options.print_metadata: image.os.print_metadata() out.info() if options.outfile is None and not options.upload: return 0 if options.virtio is not None and \ hasattr(image.os, 'install_virtio_drivers'): image.os.install_virtio_drivers() if len(options.host_run) != 0: # Export image metadata as environment variables to make them # visible by the scripts for key, value in image.meta.items(): os.environ["SNF_IMAGE_CREATOR_METADATA_%s" % key] = str(value) out.info("Running scripts on the input media:") mpoint = tempfile.mkdtemp() try: image.mount(mpoint) if not image.is_mounted(): raise FatalError("Mounting the media on the host failed.") try: size = len(options.host_run) cnt = 1 for script in options.host_run: script = os.path.abspath(script) out.info(("(%d/%d)" % (cnt, size)).ljust(7), False) out.info("Running `%s'" % script) ret = subprocess.Popen([script], cwd=mpoint).wait() if ret != 0: raise FatalError("Script: `%s' failed (rc=%d)" % (script, ret)) cnt += 1 finally: while not image.umount(): out.warn("Unable to umount the media. Retrying ...") time.sleep(1) out.info() finally: os.rmdir(mpoint) if options.sysprep: image.os.do_sysprep() checksum = image.md5() image_meta = {} for k, v in image.meta.items(): image_meta[str(k)] = str(v) metastring = json.dumps( {'properties': image_meta, 'disk-format': 'diskdump'}, ensure_ascii=False) img_properties = json.dumps(image_meta, ensure_ascii=False) if options.outfile is not None: if os.path.realpath(options.outfile) == '/dev/null': out.warn('Not dumping file to /dev/null') else: image.dump(options.outfile) out.info('Dumping metadata file ...', False) with open('%s.%s' % (options.outfile, 'meta'), 'w') as f: f.write(metastring) out.success('done') out.info('Dumping md5sum file ...', False) with open('%s.%s' % (options.outfile, 'md5sum'), 'w') as f: f.write('%s %s\n' % (checksum, os.path.basename(options.outfile))) out.success('done') out.info('Dumping variant file ...', False) with open('%s.%s' % (options.outfile, 'variant'), 'w') as f: f.write(to_shell(IMG_ID=options.outfile, IMG_FORMAT="diskdump", IMG_PROPERTIES=img_properties)) out.success('done') out.info() try: if options.upload: out.info("Uploading image to the storage service:") with image.raw_device() as raw: with open(raw, 'rb') as f: remote = kamaki.upload( f, image.size, options.upload, options.container, None, "(1/3) Calculating block hashes", "(2/3) Uploading missing blocks") out.info("(3/3) Uploading md5sum file ...", False) md5sumstr = '%s %s\n' % (checksum, os.path.basename(options.upload)) kamaki.upload(StringIO.StringIO(md5sumstr), size=len(md5sumstr), remote_path="%s.%s" % (options.upload, 'md5sum'), container=options.container, content_type="text/plain") out.success('done') out.info() if options.register: img_type = 'public' if options.public else 'private' out.info('Registering %s image with the compute service ...' % img_type, False) result = kamaki.register(options.register, remote, image.meta, options.public) out.success('done') out.info("Uploading metadata file ...", False) metastring = unicode(json.dumps(result, ensure_ascii=False, indent=4)) kamaki.upload(StringIO.StringIO(metastring.encode('utf8')), size=len(metastring), remote_path="%s.%s" % (options.upload, 'meta'), container=options.container, content_type="application/json") out.success('done') if options.public: out.info("Sharing md5sum file ...", False) kamaki.share("%s.md5sum" % options.upload) out.success('done') out.info("Sharing metadata file ...", False) kamaki.share("%s.meta" % options.upload) out.success('done') out.result(json.dumps(result, indent=4, ensure_ascii=False)) out.info() except ClientError as e: raise FatalError("Service client: %d %s" % (e.status, e.message)) finally: out.info('cleaning up ...') disk.cleanup() out.success("snf-image-creator exited without errors") return 0
def image_creator(options, out): """snf-mkimage main function""" if os.geteuid() != 0: raise FatalError("You must run %s as root" % os.path.basename(sys.argv[0])) # Check if the authentication info is valid. The earlier the better if options.token is not None and options.url is not None: try: account = Kamaki.create_account(options.url, options.token) if account is None: raise FatalError("The authentication token and/or URL you " "provided is not valid!") else: kamaki = Kamaki(account, out) except ClientError as e: raise FatalError("Astakos client: %d %s" % (e.status, e.message)) elif options.cloud: avail_clouds = Kamaki.get_clouds() if options.cloud not in avail_clouds.keys(): raise FatalError( "Cloud: `%s' does not exist.\n\nAvailable clouds:\n\n\t%s\n" % (options.cloud, "\n\t".join(avail_clouds.keys()))) try: account = Kamaki.get_account(options.cloud) if account is None: raise FatalError("Cloud: `%s' exists but is not valid!" % options.cloud) else: kamaki = Kamaki(account, out) except ClientError as e: raise FatalError("Astakos client: %d %s" % (e.status, e.message)) if options.upload and not options.force: if kamaki.object_exists(options.container, options.upload): raise FatalError("Remote storage service object: `%s' exists " "(use --force to overwrite it)." % options.upload) if kamaki.object_exists(options.container, "%s.md5sum" % options.upload): raise FatalError("Remote storage service object: `%s.md5sum' " "exists (use --force to overwrite it)." % options.upload) if options.register and not options.force: if kamaki.object_exists(options.container, "%s.meta" % options.upload): raise FatalError("Remote storage service object `%s.meta' exists " "(use --force to overwrite it)." % options.upload) disk = Disk(options.source, out, options.tmp) # pylint: disable=unused-argument def signal_handler(signum, frame): disk.cleanup() signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) try: # There is no need to snapshot the media if it was created by the Disk # instance as a temporary object. device = disk.file if not options.snapshot else disk.snapshot() image = disk.get_image(device, sysprep_params=options.sysprep_params) if image.is_unsupported() and not options.allow_unsupported: raise FatalError( "The media seems to be unsupported.\n\n" + textwrap.fill("To create an image from an unsupported media, " "you'll need to use the`--allow-unsupported' " "command line option. Using this is highly " "discouraged, since the resulting image will " "not be cleared out of sensitive data and will " "not get customized during the deployment.")) if len(options.host_run) != 0 and not image.mount_local_support: raise FatalError("Running scripts against the guest media is not " "supported for this build of libguestfs.") if len(options.host_run) != 0: for script in options.host_run: if not os.path.isfile(script): raise FatalError("File: `%s' does not exist." % script) if not os.access(script, os.X_OK): raise FatalError("File: `%s' is not executable." % script) for name in options.disabled_syspreps: sysprep = image.os.get_sysprep_by_name(name) if sysprep is not None: image.os.disable_sysprep(sysprep) else: out.warn("Sysprep: `%s' does not exist. Can't disable it." % name) for name in options.enabled_syspreps: sysprep = image.os.get_sysprep_by_name(name) if sysprep is not None: image.os.enable_sysprep(sysprep) else: out.warn("Sysprep: `%s' does not exist. Can't enable it." % name) if image.is_unsupported(): image.meta['EXCLUDE_ALL_TASKS'] = "yes" # Add command line metadata to the collected ones... image.meta.update(options.metadata) if options.print_syspreps: image.os.print_syspreps() out.info() if options.print_sysprep_params: image.os.print_sysprep_params() out.info() if options.print_metadata: image.os.print_metadata() out.info() if options.outfile is None and not options.upload: return 0 if options.virtio is not None and \ hasattr(image.os, 'install_virtio_drivers'): image.os.install_virtio_drivers() if len(options.host_run) != 0: # Export image metadata as environment variables to make them # visible by the scripts for key, value in image.meta.items(): os.environ["SNF_IMAGE_CREATOR_METADATA_%s" % key] = str(value) out.info("Running scripts on the input media:") mpoint = tempfile.mkdtemp() try: image.mount(mpoint) if not image.is_mounted(): raise FatalError("Mounting the media on the host failed.") try: size = len(options.host_run) cnt = 1 for script in options.host_run: script = os.path.abspath(script) out.info(("(%d/%d)" % (cnt, size)).ljust(7), False) out.info("Running `%s'" % script) ret = subprocess.Popen([script], cwd=mpoint).wait() if ret != 0: raise FatalError("Script: `%s' failed (rc=%d)" % (script, ret)) cnt += 1 finally: while not image.umount(): out.warn("Unable to umount the media. Retrying ...") time.sleep(1) out.info() finally: os.rmdir(mpoint) if options.sysprep: image.os.do_sysprep() checksum = image.md5() image_meta = {} for k, v in image.meta.items(): image_meta[str(k)] = str(v) metastring = json.dumps( { 'properties': image_meta, 'disk-format': 'diskdump' }, ensure_ascii=False) img_properties = json.dumps(image_meta, ensure_ascii=False) if options.outfile is not None: if os.path.realpath(options.outfile) == '/dev/null': out.warn('Not dumping file to /dev/null') else: image.dump(options.outfile) out.info('Dumping metadata file ...', False) with open('%s.%s' % (options.outfile, 'meta'), 'w') as f: f.write(metastring) out.success('done') out.info('Dumping md5sum file ...', False) with open('%s.%s' % (options.outfile, 'md5sum'), 'w') as f: f.write('%s %s\n' % (checksum, os.path.basename(options.outfile))) out.success('done') out.info('Dumping variant file ...', False) with open('%s.%s' % (options.outfile, 'variant'), 'w') as f: f.write( to_shell(IMG_ID=options.outfile, IMG_FORMAT="diskdump", IMG_PROPERTIES=img_properties)) out.success('done') out.info() try: if options.upload: out.info("Uploading image to the storage service:") with image.raw_device() as raw: with open(raw, 'rb') as f: remote = kamaki.upload( f, image.size, options.upload, options.container, None, "(1/3) Calculating block hashes", "(2/3) Uploading missing blocks") out.info("(3/3) Uploading md5sum file ...", False) md5sumstr = '%s %s\n' % (checksum, os.path.basename(options.upload)) kamaki.upload(StringIO.StringIO(md5sumstr), size=len(md5sumstr), remote_path="%s.%s" % (options.upload, 'md5sum'), container=options.container, content_type="text/plain") out.success('done') out.info() if options.register: img_type = 'public' if options.public else 'private' out.info( 'Registering %s image with the compute service ...' % img_type, False) result = kamaki.register(options.register, remote, image.meta, options.public) out.success('done') out.info("Uploading metadata file ...", False) metastring = unicode( json.dumps(result, ensure_ascii=False, indent=4)) kamaki.upload(StringIO.StringIO(metastring.encode('utf8')), size=len(metastring), remote_path="%s.%s" % (options.upload, 'meta'), container=options.container, content_type="application/json") out.success('done') if options.public: out.info("Sharing md5sum file ...", False) kamaki.share("%s.md5sum" % options.upload) out.success('done') out.info("Sharing metadata file ...", False) kamaki.share("%s.meta" % options.upload) out.success('done') out.result(json.dumps(result, indent=4, ensure_ascii=False)) out.info() except ClientError as e: raise FatalError("Service client: %d %s" % (e.status, e.message)) finally: out.info('cleaning up ...') disk.cleanup() out.success("snf-image-creator exited without errors") return 0