def from_location(name, base_url='', version='', url='', path=None): """Monkey-patching from_location untill a client with fix for #1503593 If path is supplied search for name file in the path, otherwise if url is supplied - open that url and finally search murano repository for the package. """ if path: pkg_name = os.path.join(path, name) file_name = None for f in [pkg_name, pkg_name + '.zip']: if os.path.exists(f): file_name = f if file_name: return Package.from_file(file_name) LOG.error("Couldn't find file for package {0}, tried {1}".format( name, [pkg_name, pkg_name + '.zip'])) if url: return Package.from_file(url) return Package.from_file( muranoclient_utils.to_url(name, base_url=base_url, version=version, path='apps/', extension='.zip'))
def _ensure_images(name, package, request, step_data=None): try: glance_client = glance.glanceclient(request, version='1') except Exception: glance_client = None base_url = packages_consts.MURANO_REPO_URL image_specs = package.images() if not glance_client and len(image_specs): # NOTE(kzaitsev): no glance_client. Probably v1 client # is not available. Add warning, to let user know that # we were unable to load images automagically # since v2 does not have copy_from download_urls = [] for image_spec in image_specs: download_url = muranoclient_utils.to_url( image_spec.get("Url", image_spec['Name']), base_url=base_url, path='images/', ) download_urls.append(download_url) msg = _("Couldn't initialise glance v1 client, " "therefore could not download images for " "'{0}' package. You may need to download them " "manually from these locations: {1}").format( name, ' '.join(download_urls)) messages.error(request, msg) LOG.error(msg) return try: imgs = muranoclient_utils.ensure_images(glance_client=glance_client, image_specs=package.images(), base_url=base_url) for img in imgs: msg = _("Trying to add {0} image to glance. " "Image will be ready for deployment after " "successful upload").format(img['name'], ) messages.warning(request, msg) log_msg = _("Trying to add {0}, {1} image to " "glance. Image will be ready for " "deployment after successful upload")\ .format(img['name'], img['id'],) LOG.info(log_msg) if step_data: step_data['images'].append(img) except Exception as e: msg = _("Error {0} occurred while installing " "images for {1}").format(e, name) messages.error(request, msg) LOG.exception(msg)
def do_bundle_save(mc, args): """Save a bundle. This will download a bundle of packages with all dependencies to specified path. If path doesn't exist it will be created. """ bundle = args.filename base_url = args.murano_repo_url if args.path: if not os.path.exists(args.path): os.makedirs(args.path) dst = args.path else: dst = os.getcwd() total_reqs = collections.OrderedDict() if os.path.isfile(bundle): _file = bundle else: print( "Bundle file '{0}' does not exist, attempting to download".format( bundle)) _file = utils.to_url( bundle, base_url=base_url, path='bundles/', extension='.bundle', ) try: bundle_file = utils.Bundle.from_file(_file) except Exception as e: msg = "Failed to create bundle for {0}, reason: {1}".format(bundle, e) raise exceptions.CommandError(msg) for package in bundle_file.packages(base_url=base_url): requirements = package.requirements(base_url=base_url) total_reqs.update(requirements) no_images = getattr(args, 'no_images', False) _handle_save_packages(total_reqs, dst, base_url, no_images) try: bundle_file.save(dst, binary=False) print("Bundle file {0} has been successfully saved".format(bundle)) except Exception as e: print("Error {0} occurred while saving bundle {1}".format(e, bundle))
def do_bundle_save(mc, args): """Save a bundle. This will download a bundle of packages with all dependencies to specified path. If path doesn't exist it will be created. """ bundle = args.filename base_url = args.murano_repo_url if args.path: if not os.path.exists(args.path): os.makedirs(args.path) dst = args.path else: dst = os.getcwd() total_reqs = collections.OrderedDict() if os.path.isfile(bundle): _file = bundle else: print("Bundle file '{0}' does not exist, attempting to download" .format(bundle)) _file = utils.to_url( bundle, base_url=base_url, path='bundles/', extension='.bundle', ) try: bundle_file = utils.Bundle.from_file(_file) except Exception as e: msg = "Failed to create bundle for {0}, reason: {1}".format(bundle, e) raise exceptions.CommandError(msg) for package in bundle_file.packages(base_url=base_url): requirements = package.requirements(base_url=base_url) total_reqs.update(requirements) no_images = getattr(args, 'no_images', False) _handle_save_packages(total_reqs, dst, base_url, no_images) try: bundle_file.save(dst, binary=False) print("Bundle file {0} has been successfully saved".format(bundle)) except Exception as e: print("Error {0} occurred while saving bundle {1}".format(e, bundle))
def do_package_save(mc, args): """Save a package. This will download package(s) with all dependencies to specified path. If path doesn't exist it will be created. """ base_url = args.murano_repo_url if args.path: if not os.path.exists(args.path): os.makedirs(args.path) dst = args.path else: dst = os.getcwd() version = args.package_version if version and len(args.filename) >= 2: print("Requested to save more than one package, " "ignoring version.") version = '' total_reqs = collections.OrderedDict() for package in args.package: _file = utils.to_url( package, version=version, base_url=base_url, extension='.zip', path='apps/', ) try: pkg = utils.Package.from_file(_file) except Exception as e: print("Failed to create package for '{0}', reason: {1}".format( package, e)) continue total_reqs.update(pkg.requirements(base_url=base_url)) no_images = getattr(args, 'no_images', False) _handle_save_packages(total_reqs, dst, base_url, no_images)
def process_step(self, form): @catalog_views.update_latest_apps def _update_latest_apps(request, app_id): LOG.info("Adding {0} application to the" " latest apps list".format(app_id)) step_data = self.get_form_step_data(form) if self.steps.current == "upload": import_type = form.cleaned_data["import_type"] data = {} f = None base_url = packages_consts.MURANO_REPO_URL if import_type == "upload": pkg = form.cleaned_data["package"] f = pkg.file elif import_type == "by_url": f = form.cleaned_data["url"] elif import_type == "by_name": name = form.cleaned_data["repo_name"] version = form.cleaned_data["repo_version"] f = muranoclient_utils.to_url(name, version=version, path="/apps/", extension=".zip", base_url=base_url) try: package = muranoclient_utils.Package.from_file(f) name = package.manifest["FullName"] except Exception as e: msg = _("Package creation failed" "Reason: {0}").format(e) LOG.exception(msg) messages.error(self.request, msg) raise exceptions.Http302(reverse("horizon:murano:packages:index")) def _ensure_images(name, package): try: imgs = muranoclient_utils.ensure_images( glance_client=glance_client, image_specs=package.images(), base_url=base_url ) for img in imgs: msg = _("Added {0}, {1} image to glance").format(img["name"], img["id"]) messages.success(self.request, msg) LOG.info(msg) except Exception as e: msg = _("Error {0} occurred while installing " "images for {1}").format(e, name) messages.error(self.request, msg) LOG.exception(msg) reqs = package.requirements(base_url=base_url) glance_client = glance.glanceclient(self.request, version="1") original_package = reqs.pop(name) step_data["dependencies"] = [] for dep_name, dep_package in reqs.iteritems(): _ensure_images(dep_name, dep_package) try: files = {dep_name: dep_package.file()} package = api.muranoclient(self.request).packages.create(data, files) messages.success(self.request, _("Package {0} uploaded").format(dep_name)) _update_latest_apps(request=self.request, app_id=package.id) step_data["dependencies"].append(package) except exc.HTTPConflict: msg = _("Package {0} already registered.").format(dep_name) messages.warning(self.request, msg) LOG.exception(msg) except Exception as e: msg = _("Error {0} occurred while " "installing package {1}").format(e, dep_name) messages.error(self.request, msg) LOG.exception(msg) continue # add main packages images _ensure_images(name, original_package) # import main package itself try: files = {name: original_package.file()} package = api.muranoclient(self.request).packages.create(data, files) messages.success(self.request, _("Package {0} uploaded").format(name)) _update_latest_apps(request=self.request, app_id=package.id) step_data["package"] = package except exc.HTTPConflict: msg = _("Package with specified name already exists") LOG.exception(msg) exceptions.handle(self.request, msg, redirect=reverse("horizon:murano:packages:index")) except exc.HTTPInternalServerError as e: self._handle_exception(e) except exc.HTTPException as e: reason = muranodashboard_utils.parse_api_error(getattr(e, "details", "")) if not reason: raise LOG.exception(reason) exceptions.handle(self.request, reason, redirect=reverse("horizon:murano:packages:index")) except Exception as original_e: self._handle_exception(original_e) return step_data
def process_step(self, form): @catalog_views.update_latest_apps def _update_latest_apps(request, app_id): LOG.info('Adding {0} application to the' ' latest apps list'.format(app_id)) step_data = self.get_form_step_data(form) if self.steps.current == 'upload': import_type = form.cleaned_data['import_type'] data = {} f = None base_url = packages_consts.MURANO_REPO_URL if import_type == 'upload': pkg = form.cleaned_data['package'] f = pkg.file elif import_type == 'by_url': f = form.cleaned_data['url'] elif import_type == 'by_name': name = form.cleaned_data['repo_name'] version = form.cleaned_data['repo_version'] f = muranoclient_utils.to_url( name, version=version, path='/apps/', extension='.zip', base_url=base_url, ) try: package = muranoclient_utils.Package.from_file(f) name = package.manifest['FullName'] except Exception as e: msg = _("Package creation failed" "Reason: {0}").format(e) LOG.exception(msg) messages.error(self.request, msg) raise exceptions.Http302( reverse('horizon:murano:packages:index')) def _ensure_images(name, package): try: imgs = muranoclient_utils.ensure_images( glance_client=glance_client, image_specs=package.images(), base_url=base_url) for img in imgs: msg = _("Added {0}, {1} image to glance").format( img['name'], img['id'], ) messages.success(self.request, msg) LOG.info(msg) except Exception as e: msg = _("Error {0} occurred while installing " "images for {1}").format(e, name) messages.error(self.request, msg) LOG.exception(msg) reqs = package.requirements(base_url=base_url) glance_client = glance.glanceclient(self.request, version='1') original_package = reqs.pop(name) step_data['dependencies'] = [] for dep_name, dep_package in reqs.iteritems(): _ensure_images(dep_name, dep_package) try: files = {dep_name: dep_package.file()} package = api.muranoclient(self.request).packages.create( data, files) messages.success( self.request, _('Package {0} uploaded').format(dep_name)) _update_latest_apps(request=self.request, app_id=package.id) step_data['dependencies'].append(package) except exc.HTTPConflict: msg = _("Package {0} already registered.").format(dep_name) messages.warning(self.request, msg) LOG.exception(msg) except Exception as e: msg = _("Error {0} occurred while " "installing package {1}").format(e, dep_name) messages.error(self.request, msg) LOG.exception(msg) continue # add main packages images _ensure_images(name, original_package) # import main package itself try: files = {name: original_package.file()} package = api.muranoclient(self.request).packages.create( data, files) messages.success(self.request, _('Package {0} uploaded').format(name)) _update_latest_apps(request=self.request, app_id=package.id) step_data['package'] = package except exc.HTTPConflict: msg = _("Package with specified name already exists") LOG.exception(msg) exceptions.handle( self.request, msg, redirect=reverse('horizon:murano:packages:index')) except exc.HTTPInternalServerError as e: self._handle_exception(e) except exc.HTTPException as e: reason = muranodashboard_utils.parse_api_error( getattr(e, 'details', '')) if not reason: raise LOG.exception(reason) exceptions.handle( self.request, reason, redirect=reverse('horizon:murano:packages:index')) except Exception as original_e: self._handle_exception(original_e) return step_data
def do_package_import(mc, args): """Import a package. `FILE` can be either a path to a zip file, url or a FQPN. You can use `--` to separate `FILE`s from other arguments. Categories have to be separated with a space and have to be already present in murano. """ data = {"is_public": args.is_public} version = args.package_version if version and len(args.filename) >= 2: print("Requested to import more than one package, " "ignoring version.") version = '' if args.categories: data["categories"] = args.categories total_reqs = {} for filename in args.filename: if os.path.isfile(filename): _file = filename else: print("Package file '{0}' does not exist, attempting to download" "".format(filename)) _file = utils.to_url( filename, version=version, base_url=args.murano_repo_url, extension='.zip', path='apps/', ) try: package = utils.Package.from_file(_file) except Exception as e: print("Failed to create package for '{0}', reason: {1}".format( filename, e)) continue total_reqs.update(package.requirements(base_url=args.murano_repo_url)) imported_list = [] for name, package in six.iteritems(total_reqs): image_specs = package.images() if image_specs: print("Inspecting required images") try: imgs = utils.ensure_images( glance_client=mc.glance_client, image_specs=image_specs, base_url=args.murano_repo_url, is_package_public=args.is_public) for img in imgs: print("Added {0}, {1} image".format( img['name'], img['id'])) except Exception as e: print("Error {0} occurred while installing " "images for {1}".format(e, name)) try: imported_package = _handle_package_exists( mc, data, package, args.exists_action) if imported_package: imported_list.append(imported_package) except Exception as e: print("Error {0} occurred while installing package {1}".format( e, name)) if imported_list: _print_package_list(imported_list)
def do_bundle_import(mc, args): """Import a bundle. `FILE` can be either a path to a zip file, URL, or name from repo. If `FILE` is a local file, treat names of packages in a bundle as file names, relative to location of the bundle file. Requirements are first searched in the same directory. """ total_reqs = {} for filename in args.filename: local_path = None if os.path.isfile(filename): _file = filename local_path = os.path.dirname(os.path.abspath(filename)) else: print( "Bundle file '{0}' does not exist, attempting to download" "".format(filename)) _file = utils.to_url( filename, base_url=args.murano_repo_url, path='bundles/', extension='.bundle', ) try: bundle_file = utils.Bundle.from_file(_file) except Exception as e: print("Failed to create bundle for '{0}', reason: {1}".format( filename, e)) continue data = {"is_public": args.is_public} for package in bundle_file.packages(base_url=args.murano_repo_url, path=local_path): requirements = package.requirements( base_url=args.murano_repo_url, path=local_path, ) total_reqs.update(requirements) imported_list = [] for name, dep_package in six.iteritems(total_reqs): image_specs = dep_package.images() if image_specs: print("Inspecting required images") try: imgs = utils.ensure_images(glance_client=mc.glance_client, image_specs=image_specs, base_url=args.murano_repo_url, local_path=local_path, is_package_public=args.is_public) for img in imgs: print("Added {0}, {1} image".format( img['name'], img['id'])) except Exception as e: print("Error {0} occurred while installing " "images for {1}".format(e, name)) try: imported_package = _handle_package_exists(mc, data, dep_package, args.exists_action) if imported_package: imported_list.append(imported_package) except exceptions.CommandError: raise except Exception as e: print("Error {0} occurred while " "installing package {1}".format(e, name)) if imported_list: _print_package_list(imported_list)
def process_step(self, form): @catalog_views.update_latest_apps def _update_latest_apps(request, app_id): LOG.info('Adding {0} application to the' ' latest apps list'.format(app_id)) step_data = self.get_form_step_data(form) if self.steps.current == 'upload': import_type = form.cleaned_data['import_type'] data = {} f = None base_url = packages_consts.MURANO_REPO_URL if import_type == 'by_url': f = form.cleaned_data['url'] elif import_type == 'by_name': f = muranoclient_utils.to_url( form.cleaned_data['name'], path='/bundles/', base_url=base_url, extension='.bundle', ) try: bundle = muranoclient_utils.Bundle.from_file(f) except Exception as e: msg = _("Bundle creation failed" "Reason: {0}").format(e) LOG.exception(msg) messages.error(self.request, msg) raise exceptions.Http302( reverse('horizon:murano:packages:index')) glance_client = glance.glanceclient(self.request, version='1') for package_spec in bundle.package_specs(): try: package = muranoclient_utils.Package.from_location( package_spec['Name'], version=package_spec.get('Version'), url=package_spec.get('Url'), base_url=base_url, path=None, ) except Exception as e: msg = _("Error {0} occurred while parsing package {1}")\ .format(e, package_spec.get('Name')) messages.error(self.request, msg) LOG.exception(msg) continue reqs = package.requirements(base_url=base_url) for dep_name, dep_package in reqs.iteritems(): try: imgs = muranoclient_utils.ensure_images( glance_client=glance_client, image_specs=dep_package.images(), base_url=base_url) for img in imgs: msg = _("Added {0}, {1} image to glance").format( img['name'], img['id'], ) messages.success(self.request, msg) LOG.info(msg) except Exception as e: msg = _("Error {0} occurred while installing " "images for {1}").format(e, dep_name) messages.error(self.request, msg) LOG.exception(msg) try: files = {dep_name: dep_package.file()} package = api.muranoclient( self.request).packages.create(data, files) messages.success( self.request, _('Package {0} uploaded').format(dep_name)) _update_latest_apps(request=self.request, app_id=package.id) except exc.HTTPConflict: msg = _("Package {0} already registered.").format( dep_name) messages.warning(self.request, msg) LOG.exception(msg) except exc.HTTPException as e: reason = muranodashboard_utils.parse_api_error( getattr(e, 'details', '')) if not reason: raise msg = _("Package {0} upload failed. {1}").format( dep_name, reason) messages.warning(self.request, msg) LOG.exception(msg) except Exception as e: msg = _("Importing package {0} failed. " "Reason: {1}").format(dep_name, e) messages.warning(self.request, msg) LOG.exception(msg) continue return step_data
def do_package_import(mc, args): """Import a package. `FILE` can be either a path to a zip file, url or a FQPN. You can use `--` to separate `FILE`s from other arguments. Categories have to be separated with a space and have to be already present in murano. """ data = {"is_public": args.is_public} exception_occurred = False version = args.package_version if version and len(args.filename) >= 2: print("Requested to import more than one package, " "ignoring version.") version = '' if args.categories: data["categories"] = args.categories total_reqs = collections.OrderedDict() main_packages_names = [] for filename in args.filename: if os.path.isfile(filename) or os.path.isdir(filename): _file = filename else: print("Package file '{0}' does not exist, attempting to download" "".format(filename)) _file = utils.to_url( filename, version=version, base_url=args.murano_repo_url, extension='.zip', path='apps/', ) try: package = utils.Package.from_file(_file) except Exception as e: print("Failed to create package for '{0}', reason: {1}".format( filename, e)) exception_occurred = True continue total_reqs.update(package.requirements(base_url=args.murano_repo_url)) main_packages_names.append(package.manifest['FullName']) imported_list = [] dep_exists_action = args.dep_exists_action if dep_exists_action == '': dep_exists_action = args.exists_action for name, package in six.iteritems(total_reqs): image_specs = package.images() if image_specs: print("Inspecting required images") try: imgs = utils.ensure_images(glance_client=mc.glance_client, image_specs=image_specs, base_url=args.murano_repo_url, is_package_public=args.is_public) for img in imgs: print("Added {0}, {1} image".format( img['name'], img['id'])) except Exception as e: print("Error {0} occurred while installing " "images for {1}".format(e, name)) exception_occurred = True if name in main_packages_names: exists_action = args.exists_action else: exists_action = dep_exists_action try: imported_package = _handle_package_exists(mc, data, package, exists_action) if imported_package: imported_list.append(imported_package) except Exception as e: print("Error {0} occurred while installing package {1}".format( e, name)) exception_occurred = True if imported_list: _print_package_list(imported_list) if exception_occurred: # NOTE(jose-phillips) Leave a Warning to users in case some packages # can be uploaded successfully. if imported_list: print("Warning: there were some errors during the operation.") sys.exit(1) else: sys.exit(1)
def take_action(self, parsed_args): LOG.debug("take_action({0})".format(parsed_args)) client = self.app.client_manager.application_catalog total_reqs = collections.OrderedDict() for filename in parsed_args.filename: local_path = None if os.path.isfile(filename): _file = filename local_path = os.path.dirname(os.path.abspath(filename)) else: print("Bundle file '{0}' does not exist, attempting " "to download".format(filename)) _file = murano_utils.to_url( filename, base_url=parsed_args.murano_repo_url, path='bundles/', extension='.bundle', ) try: bundle_file = murano_utils.Bundle.from_file(_file) except Exception as e: print("Failed to create bundle for '{0}', reason: {1}".format( filename, e)) continue data = {"is_public": parsed_args.is_public} for package in bundle_file.packages( base_url=parsed_args.murano_repo_url, path=local_path): requirements = package.requirements( base_url=parsed_args.murano_repo_url, path=local_path, ) total_reqs.update(requirements) imported_list = [] for name, dep_package in total_reqs.items(): image_specs = dep_package.images() if image_specs: print("Inspecting required images") try: imgs = parsed_args.ensure_images( glance_client=client.glance_client, image_specs=image_specs, base_url=parsed_args.murano_repo_url, local_path=local_path, is_package_public=parsed_args.is_public) for img in imgs: print("Added {0}, {1} image".format( img['name'], img['id'])) except Exception as e: print("Error {0} occurred while installing " "images for {1}".format(e, name)) try: imported_package = _handle_package_exists( client, data, dep_package, parsed_args.exists_action) if imported_package: imported_list.append(imported_package) except exceptions.CommandError: raise except Exception as e: print("Error {0} occurred while " "installing package {1}".format(e, name)) columns = ('id', 'name', 'fully_qualified_name', 'author', 'active', 'is public', 'type', 'version') column_headers = [c.capitalize() for c in columns] return ( column_headers, list(utils.get_item_properties( s, columns, ) for s in imported_list) )
def process_step(self, form): @catalog_views.update_latest_apps def _update_latest_apps(request, app_id): LOG.info('Adding {0} application to the' ' latest apps list'.format(app_id)) step_data = self.get_form_step_data(form) if self.steps.current == 'upload': import_type = form.cleaned_data['import_type'] data = {} f = None base_url = packages_consts.MURANO_REPO_URL if import_type == 'upload': pkg = form.cleaned_data['package'] f = pkg.file elif import_type == 'by_url': f = form.cleaned_data['url'] elif import_type == 'by_name': name = form.cleaned_data['repo_name'] version = form.cleaned_data['repo_version'] f = muranoclient_utils.to_url( name, version=version, path='apps/', extension='.zip', base_url=base_url, ) try: package = muranoclient_utils.Package.from_file(f) name = package.manifest['FullName'] except Exception as e: if '(404)' in e.message: msg = _("Package creation failed." "Reason: Can't find Package name from repository.") else: msg = _("Package creation failed." "Reason: {0}").format(e) LOG.exception(msg) messages.error(self.request, msg) raise exceptions.Http302( reverse('horizon:murano:packages:index')) def _ensure_images(name, package): try: imgs = muranoclient_utils.ensure_images( glance_client=glance_client, image_specs=package.images(), base_url=base_url) for img in imgs: msg = _("Trying to add {0} image to glance. " "Image will be ready for deployment after " "successful upload").format(img['name'],) messages.warning(self.request, msg) log_msg = _("Trying to add {0}, {1} image to " "glance. Image will be ready for " "deployment after successful upload")\ .format(img['name'], img['id'],) LOG.info(log_msg) step_data['images'].append(img) except Exception as e: msg = _("Error {0} occurred while installing " "images for {1}").format(e, name) messages.error(self.request, msg) LOG.exception(msg) reqs = package.requirements(base_url=base_url) glance_client = glance.glanceclient(self.request, version='1') original_package = reqs.pop(name) step_data['dependencies'] = [] step_data['images'] = [] for dep_name, dep_package in six.iteritems(reqs): _ensure_images(dep_name, dep_package) try: files = {dep_name: dep_package.file()} package = api.muranoclient(self.request).packages.create( data, files) messages.success( self.request, _('Package {0} uploaded').format(dep_name) ) _update_latest_apps( request=self.request, app_id=package.id) step_data['dependencies'].append(package) except exc.HTTPConflict: msg = _("Package {0} already registered.").format( dep_name) messages.warning(self.request, msg) LOG.exception(msg) except Exception as e: msg = _("Error {0} occurred while " "installing package {1}").format(e, dep_name) messages.error(self.request, msg) LOG.exception(msg) continue # add main packages images _ensure_images(name, original_package) # import main package itself try: files = {name: original_package.file()} package = api.muranoclient(self.request).packages.create( data, files) messages.success(self.request, _('Package {0} uploaded').format(name)) _update_latest_apps(request=self.request, app_id=package.id) step_data['package'] = package except exc.HTTPConflict: msg = _("Package with specified name already exists") LOG.exception(msg) exceptions.handle( self.request, msg, redirect=reverse('horizon:murano:packages:index')) except exc.HTTPInternalServerError as e: self._handle_exception(e) except exc.HTTPException as e: reason = muranodashboard_utils.parse_api_error( getattr(e, 'details', '')) if not reason: raise LOG.exception(reason) exceptions.handle( self.request, reason, redirect=reverse('horizon:murano:packages:index')) except Exception as original_e: self._handle_exception(original_e) return step_data
def process_step(self, form): @catalog_views.update_latest_apps def _update_latest_apps(request, app_id): LOG.info("Adding {0} application to the" " latest apps list".format(app_id)) step_data = self.get_form_step_data(form) if self.steps.current == "upload": import_type = form.cleaned_data["import_type"] data = {} f = None base_url = packages_consts.MURANO_REPO_URL if import_type == "by_url": f = form.cleaned_data["url"] elif import_type == "by_name": f = muranoclient_utils.to_url( form.cleaned_data["name"], path="/bundles/", base_url=base_url, extension=".bundle" ) try: bundle = muranoclient_utils.Bundle.from_file(f) except Exception as e: msg = _("Bundle creation failed" "Reason: {0}").format(e) LOG.exception(msg) messages.error(self.request, msg) raise exceptions.Http302(reverse("horizon:murano:packages:index")) glance_client = glance.glanceclient(self.request, version="1") for package_spec in bundle.package_specs(): try: package = muranoclient_utils.Package.from_location( package_spec["Name"], version=package_spec.get("Version"), url=package_spec.get("Url"), base_url=base_url, path=None, ) except Exception as e: msg = _("Error {0} occurred while parsing package {1}").format(e, package_spec.get("Name")) messages.error(self.request, msg) LOG.exception(msg) continue reqs = package.requirements(base_url=base_url) for dep_name, dep_package in reqs.iteritems(): try: imgs = muranoclient_utils.ensure_images( glance_client=glance_client, image_specs=dep_package.images(), base_url=base_url ) for img in imgs: msg = _("Added {0}, {1} image to glance").format(img["name"], img["id"]) messages.success(self.request, msg) LOG.info(msg) except Exception as e: msg = _("Error {0} occurred while installing " "images for {1}").format(e, dep_name) messages.error(self.request, msg) LOG.exception(msg) try: files = {dep_name: dep_package.file()} package = api.muranoclient(self.request).packages.create(data, files) messages.success(self.request, _("Package {0} uploaded").format(dep_name)) _update_latest_apps(request=self.request, app_id=package.id) except exc.HTTPConflict: msg = _("Package {0} already registered.").format(dep_name) messages.warning(self.request, msg) LOG.exception(msg) except exc.HTTPException as e: reason = muranodashboard_utils.parse_api_error(getattr(e, "details", "")) if not reason: raise msg = _("Package {0} upload failed. {1}").format(dep_name, reason) messages.warning(self.request, msg) LOG.exception(msg) except Exception as e: msg = _("Importing package {0} failed. " "Reason: {1}").format(dep_name, e) messages.warning(self.request, msg) LOG.exception(msg) continue return step_data
def process_step(self, form): @catalog_views.update_latest_apps def _update_latest_apps(request, app_id): LOG.info('Adding {0} application to the' ' latest apps list'.format(app_id)) step_data = self.get_form_step_data(form) if self.steps.current == 'upload': import_type = form.cleaned_data['import_type'] data = {} f = None base_url = packages_consts.MURANO_REPO_URL if import_type == 'by_url': f = form.cleaned_data['url'] elif import_type == 'by_name': f = muranoclient_utils.to_url( form.cleaned_data['name'], path='bundles/', base_url=base_url, extension='.bundle', ) try: bundle = muranoclient_utils.Bundle.from_file(f) except Exception as e: if '(404)' in e.message: msg = _("Bundle creation failed." "Reason: Can't find Bundle name from repository.") else: msg = _("Bundle creation failed." "Reason: {0}").format(e) LOG.exception(msg) messages.error(self.request, msg) raise exceptions.Http302( reverse('horizon:murano:packages:index')) glance_client = glance.glanceclient(self.request, version='1') for package_spec in bundle.package_specs(): try: package = muranoclient_utils.Package.from_location( package_spec['Name'], version=package_spec.get('Version'), url=package_spec.get('Url'), base_url=base_url, path=None, ) except Exception as e: msg = _("Error {0} occurred while parsing package {1}")\ .format(e, package_spec.get('Name')) messages.error(self.request, msg) LOG.exception(msg) continue reqs = package.requirements(base_url=base_url) for dep_name, dep_package in six.iteritems(reqs): try: imgs = muranoclient_utils.ensure_images( glance_client=glance_client, image_specs=dep_package.images(), base_url=base_url) for img in imgs: msg = _("Trying to add {0} image to glance. " "Image will be ready for deployment after" " successful upload").format(img['name'],) messages.warning(self.request, msg) log_msg = _("Trying to add {0}, {1} image to " "glance. Image will be ready for " "deployment after successful upload")\ .format(img['name'], img['id'],) LOG.info(log_msg) except Exception as e: msg = _("Error {0} occurred while installing " "images for {1}").format(e, dep_name) messages.error(self.request, msg) LOG.exception(msg) try: files = {dep_name: dep_package.file()} package = api.muranoclient( self.request).packages.create(data, files) messages.success( self.request, _('Package {0} uploaded').format(dep_name) ) _update_latest_apps( request=self.request, app_id=package.id) except exc.HTTPConflict: msg = _("Package {0} already registered.").format( dep_name) messages.warning(self.request, msg) LOG.exception(msg) except exc.HTTPException as e: reason = muranodashboard_utils.parse_api_error( getattr(e, 'details', '')) if not reason: raise msg = _("Package {0} upload failed. {1}").format( dep_name, reason) messages.warning(self.request, msg) LOG.exception(msg) except Exception as e: msg = _("Importing package {0} failed. " "Reason: {1}").format(dep_name, e) messages.warning(self.request, msg) LOG.exception(msg) continue return step_data
def ensure_images(glance_client, image_specs, base_url, local_path=None): """Monkey-patching from_location untill a client with fix for #1503593 Ensure that images from image_specs are available in glance. If not attempts: instructs glance to download the images and sets murano-specific metadata for it. """ def _image_valid(image, keys): for key in keys: if key not in image: LOG.warning("Image specification invalid: " "No {0} key in image ".format(key)) return False return True keys = [ 'Name', 'DiskFormat', 'ContainerFormat', ] installed_images = [] for image_spec in image_specs: if not _image_valid(image_spec, keys): continue filters = { 'name': image_spec["Name"], 'disk_format': image_spec["DiskFormat"], 'container_format': image_spec["ContainerFormat"], } images = glance_client.images.list(filters=filters) try: img = images.next().to_dict() except StopIteration: img = None update_metadata = False if img: LOG.info("Found desired image {0}, id {1}".format( img['name'], img['id'])) # check for murano meta-data if 'murano_image_info' in img.get('properties', {}): LOG.info("Image {0} already has murano meta-data".format( image_spec['Name'])) else: update_metadata = True else: LOG.info("Desired image {0} not found attempting " "to download".format(image_spec['Name'])) update_metadata = True img_file = None if local_path: img_file = os.path.join(local_path, image_spec['Name']) if img_file and not os.path.exists(img_file): LOG.error("Image file {0} does not exist.".format(img_file)) if img_file and os.path.exists(img_file): img = glance_client.images.create( name=image_spec['Name'], container_format=image_spec['ContainerFormat'], disk_format=image_spec['DiskFormat'], data=open(img_file, 'rb'), ) img = img.to_dict() else: download_url = muranoclient_utils.to_url( image_spec.get("Url", image_spec['Name']), base_url=base_url, path='images/', ) LOG.info("Instructing glance to download image {0}".format( image_spec['Name'])) img = glance_client.images.create( name=image_spec["Name"], container_format=image_spec['ContainerFormat'], disk_format=image_spec['DiskFormat'], copy_from=download_url) img = img.to_dict() installed_images.append(img) if update_metadata and 'Meta' in image_spec: LOG.info("Updating image {0} metadata".format( image_spec['Name'])) murano_image_info = jsonutils.dumps(image_spec['Meta']) glance_client.images.update( img['id'], properties={'murano_image_info': murano_image_info}) return installed_images
def process_step(self, form): @catalog_views.update_latest_apps def _update_latest_apps(request, app_id): LOG.info('Adding {0} application to the' ' latest apps list'.format(app_id)) step_data = self.get_form_step_data(form) if self.steps.current == 'upload': import_type = form.cleaned_data['import_type'] data = {} f = None base_url = packages_consts.MURANO_REPO_URL if import_type == 'upload': pkg = form.cleaned_data['package'] f = pkg.file elif import_type == 'by_url': f = form.cleaned_data['url'] elif import_type == 'by_name': name = form.cleaned_data['repo_name'] version = form.cleaned_data['repo_version'] f = muranoclient_utils.to_url( name, version=version, path='/apps/', extension='.zip', base_url=base_url, ) try: package = muranoclient_utils.Package.from_file(f) name = package.manifest['FullName'] except Exception as e: msg = _("Package creation failed" "Reason: {0}").format(e) LOG.exception(msg) messages.error(self.request, msg) raise exceptions.Http302( reverse('horizon:murano:packages:index')) reqs = package.requirements(base_url=base_url) glance_client = glance.glanceclient(self.request, version='1') original_package = reqs.pop(name) step_data['dependencies'] = [] for dep_name, dep_package in reqs.iteritems(): try: imgs = muranoclient_utils.ensure_images( glance_client=glance_client, image_specs=dep_package.images(), base_url=base_url) for img in imgs: msg = _("Added {0}, {1} image to glance").format( img['name'], img['id'], ) messages.success(self.request, msg) LOG.info(msg) except Exception as e: msg = _("Error {0} occurred while installing " "images for {1}").format(e, dep_name) messages.error(self.request, msg) LOG.exception(msg) try: files = {dep_name: dep_package.file()} package = api.muranoclient(self.request).packages.create( data, files) messages.success( self.request, _('Package {0} uploaded').format(dep_name) ) _update_latest_apps( request=self.request, app_id=package.id) step_data['dependencies'].append(package) except exc.HTTPConflict: msg = _("Package {0} already registered.").format( dep_name) messages.warning(self.request, msg) LOG.exception(msg) except Exception as e: msg = _("Error {0} occurred while " "installing package {1}").format(e, dep_name) messages.error(self.request, msg) LOG.exception(msg) continue # install main package images try: imgs = muranoclient_utils.ensure_images( glance_client=glance_client, image_specs=original_package.images(), base_url=base_url) for img in imgs: msg = _("Added {0}, {1} image to glance").format( img['name'], img['id'], ) messages.success(self.request, msg) LOG.info(msg) except Exception as e: msg = _("Error {0} occurred while installing " "images for {1}").format(e, name) messages.error(self.request, msg) LOG.exception(msg) # install main package images try: files = {name: original_package.file()} package = api.muranoclient(self.request).packages.create( data, files) messages.success(self.request, _('Package {0} uploaded').format(name)) _update_latest_apps(request=self.request, app_id=package.id) step_data['package'] = package except exc.HTTPConflict: msg = _("Package with specified name already exists") LOG.exception(msg) exceptions.handle( self.request, msg, redirect=reverse('horizon:murano:packages:index')) except Exception as e: msg = _("Uploading package failed. {0}").format(e.message) LOG.exception(msg) exceptions.handle( self.request, msg, redirect=reverse('horizon:murano:packages:index')) return step_data
def do_package_import(mc, args): """Import a package. `FILE` can be either a path to a zip file, url or a FQPN. You can use `--` to separate `FILE`s from other arguments. Categories have to be separated with a space and have to be already present in murano. """ data = {"is_public": args.is_public} exception_occurred = False version = args.package_version if version and len(args.filename) >= 2: print("Requested to import more than one package, " "ignoring version.") version = '' if args.categories: data["categories"] = args.categories total_reqs = collections.OrderedDict() main_packages_names = [] for filename in args.filename: if os.path.isfile(filename) or os.path.isdir(filename): _file = filename else: print("Package file '{0}' does not exist, attempting to download" "".format(filename)) _file = utils.to_url( filename, version=version, base_url=args.murano_repo_url, extension='.zip', path='apps/', ) try: package = utils.Package.from_file(_file) except Exception as e: print("Failed to create package for '{0}', reason: {1}".format( filename, e)) exception_occurred = True continue total_reqs.update(package.requirements(base_url=args.murano_repo_url)) main_packages_names.append(package.manifest['FullName']) imported_list = [] dep_exists_action = args.dep_exists_action if dep_exists_action == '': dep_exists_action = args.exists_action for name, package in total_reqs.items(): image_specs = package.images() if image_specs: print("Inspecting required images") try: imgs = utils.ensure_images( glance_client=mc.glance_client, image_specs=image_specs, base_url=args.murano_repo_url, is_package_public=args.is_public) for img in imgs: print("Added {0}, {1} image".format( img['name'], img['id'])) except Exception as e: print("Error {0} occurred while installing " "images for {1}".format(e, name)) exception_occurred = True if name in main_packages_names: exists_action = args.exists_action else: exists_action = dep_exists_action try: imported_package = _handle_package_exists( mc, data, package, exists_action) if imported_package: imported_list.append(imported_package) except Exception as e: print("Error {0} occurred while installing package {1}".format( e, name)) exception_occurred = True if imported_list: _print_package_list(imported_list) if exception_occurred: # NOTE(jose-phillips) Leave a Warning to users in case some packages # can be uploaded successfully. if imported_list: print("Warning: there were some errors during the operation.") sys.exit(1) else: sys.exit(1)
def do_package_import(mc, args): """Import a package. `FILE` can be either a path to a zip file, url or a FQPN. You can use `--` to separate `FILE`s from other arguments. Categories have to be separated with a space and have to be already present in murano. """ data = {"is_public": args.is_public} version = args.package_version if version and len(args.filename) >= 2: print("Requested to import more than one package, " "ignoring version.") version = '' if args.categories: data["categories"] = args.categories total_reqs = {} for filename in args.filename: if os.path.isfile(filename): _file = filename else: print( "Package file '{0}' does not exist, attempting to download" "".format(filename)) _file = utils.to_url( filename, version=version, base_url=args.murano_repo_url, extension='.zip', path='apps/', ) try: package = utils.Package.from_file(_file) except Exception as e: print("Failed to create package for '{0}', reason: {1}".format( filename, e)) continue total_reqs.update(package.requirements(base_url=args.murano_repo_url)) imported_list = [] for name, package in six.iteritems(total_reqs): image_specs = package.images() if image_specs: print("Inspecting required images") try: imgs = utils.ensure_images(glance_client=mc.glance_client, image_specs=image_specs, base_url=args.murano_repo_url, is_package_public=args.is_public) for img in imgs: print("Added {0}, {1} image".format( img['name'], img['id'])) except Exception as e: print("Error {0} occurred while installing " "images for {1}".format(e, name)) try: imported_package = _handle_package_exists(mc, data, package, args.exists_action) if imported_package: imported_list.append(imported_package) except Exception as e: print("Error {0} occurred while installing package {1}".format( e, name)) if imported_list: _print_package_list(imported_list)
def do_bundle_import(mc, args): """Import a bundle. `FILE` can be either a path to a zip file, URL, or name from repo. If `FILE` is a local file, treat names of packages in a bundle as file names, relative to location of the bundle file. Requirements are first searched in the same directory. """ total_reqs = collections.OrderedDict() for filename in args.filename: local_path = None if os.path.isfile(filename): _file = filename local_path = os.path.dirname(os.path.abspath(filename)) else: print("Bundle file '{0}' does not exist, attempting to download" "".format(filename)) _file = utils.to_url( filename, base_url=args.murano_repo_url, path='bundles/', extension='.bundle', ) try: bundle_file = utils.Bundle.from_file(_file) except Exception as e: print("Failed to create bundle for '{0}', reason: {1}".format( filename, e)) continue data = {"is_public": args.is_public} for package in bundle_file.packages( base_url=args.murano_repo_url, path=local_path): requirements = package.requirements( base_url=args.murano_repo_url, path=local_path, ) total_reqs.update(requirements) imported_list = [] for name, dep_package in total_reqs.items(): image_specs = dep_package.images() if image_specs: print("Inspecting required images") try: imgs = utils.ensure_images( glance_client=mc.glance_client, image_specs=image_specs, base_url=args.murano_repo_url, local_path=local_path, is_package_public=args.is_public) for img in imgs: print("Added {0}, {1} image".format( img['name'], img['id'])) except Exception as e: print("Error {0} occurred while installing " "images for {1}".format(e, name)) try: imported_package = _handle_package_exists( mc, data, dep_package, args.exists_action) if imported_package: imported_list.append(imported_package) except exceptions.CommandError: raise except Exception as e: print("Error {0} occurred while " "installing package {1}".format(e, name)) if imported_list: _print_package_list(imported_list)
def take_action(self, parsed_args): LOG.debug("take_action({0})".format(parsed_args)) client = self.app.client_manager.application_catalog data = {"is_public": parsed_args.is_public} version = parsed_args.package_version if version and len(parsed_args.filename) >= 2: print("Requested to import more than one package, " "ignoring version.") version = '' if parsed_args.categories: data["categories"] = parsed_args.categories total_reqs = collections.OrderedDict() main_packages_names = [] for filename in parsed_args.filename: if os.path.isfile(filename) or os.path.isdir(filename): _file = filename else: print("Package file '{0}' does not exist, attempting to " "download".format(filename)) _file = murano_utils.to_url( filename, version=version, base_url=parsed_args.murano_repo_url, extension='.zip', path='apps/', ) try: package = murano_utils.Package.from_file(_file) except Exception as e: print("Failed to create package for '{0}', reason: {1}".format( filename, e)) continue total_reqs.update( package.requirements(base_url=parsed_args.murano_repo_url)) main_packages_names.append(package.manifest['FullName']) imported_list = [] dep_exists_action = parsed_args.dep_exists_action if dep_exists_action == '': dep_exists_action = parsed_args.exists_action for name, package in six.iteritems(total_reqs): image_specs = package.images() if image_specs: print("Inspecting required images") try: imgs = murano_utils.ensure_images( glance_client=client.glance_client, image_specs=image_specs, base_url=parsed_args.murano_repo_url, is_package_public=parsed_args.is_public) for img in imgs: print("Added {0}, {1} image".format( img['name'], img['id'])) except Exception as e: print("Error {0} occurred while installing " "images for {1}".format(e, name)) if name in main_packages_names: exists_action = parsed_args.exists_action else: exists_action = dep_exists_action try: imported_package = _handle_package_exists( client, data, package, exists_action) if imported_package: imported_list.append(imported_package) except Exception as e: print("Error {0} occurred while installing package {1}".format( e, name)) columns = ('id', 'name', 'fully_qualified_name', 'author', 'active', 'is public', 'type', 'version') column_headers = [c.capitalize() for c in columns] return ( column_headers, list(utils.get_item_properties( s, columns, ) for s in imported_list) )