def load_from_file(archive_path, target_dir=None, drop_dir=False): if not os.path.isfile(archive_path): raise e.PackageLoadError('Unable to find package file') created = False if not target_dir: target_dir = tempfile.mkdtemp() created = True elif not os.path.exists(target_dir): os.mkdir(target_dir) created = True else: if os.listdir(target_dir): raise e.PackageLoadError('Target directory is not empty') try: if not zipfile.is_zipfile(archive_path): raise e.PackageFormatError("Uploaded file {0} is not a " "zip archive".format(archive_path)) package = zipfile.ZipFile(archive_path) package.extractall(path=target_dir) yield load_from_dir(target_dir) except ValueError as err: raise e.PackageLoadError("Couldn't load package from file: " "{0}".format(err)) finally: if drop_dir: if created: shutil.rmtree(target_dir) else: for f in os.listdir(target_dir): os.unlink(os.path.join(target_dir, f))
def load_from_dir(source_directory, filename='manifest.yaml'): if not os.path.isdir(source_directory) or not os.path.exists( source_directory): raise e.PackageLoadError('Invalid package directory') full_path = path.secure_join(source_directory, filename) if not os.path.isfile(full_path): raise e.PackageLoadError('Unable to find package manifest') try: with open(full_path) as stream: content = yaml.safe_load(stream) except Exception as ex: trace = sys.exc_info()[2] utils.reraise( e.PackageLoadError, e.PackageLoadError("Unable to load due to '{0}'".format(ex)), trace) else: format_spec = str(content.get('Format') or 'MuranoPL/1.0') if format_spec[0].isdigit(): format_spec = 'MuranoPL/' + format_spec plugin_loader = get_plugin_loader() handler = plugin_loader.get_package_handler(format_spec) if handler is None: raise e.PackageFormatError( 'Unsupported format {0}'.format(format_spec)) return handler(source_directory, content)
def _translate_class(self): template_file = os.path.join(self._source_directory, 'template.yaml') shutil.copy(template_file, self.get_resource(self.full_name)) if not os.path.isfile(template_file): raise exceptions.PackageClassLoadError( self.full_name, 'File with class definition not found') with open(template_file) as stream: hot = yaml.safe_load(stream) if 'resources' not in hot: raise exceptions.PackageFormatError('Not a HOT template') translated = { 'Name': self.full_name, 'Extends': 'io.murano.Application' } hot_envs_path = os.path.join(self._source_directory, RESOURCES_DIR_NAME, HOT_ENV_DIR_NAME) # if using hot environments, doing parameter validation with contracts # will overwrite the parameters in the hot environment. # don't validate parameters if hot environments exist. validate_hot_parameters = (not os.path.isdir(hot_envs_path) or not os.listdir(hot_envs_path)) parameters = HotPackage._build_properties(hot, validate_hot_parameters) parameters.update(HotPackage._translate_outputs(hot)) translated['Properties'] = parameters files = HotPackage._translate_files(self._source_directory) translated.update(HotPackage._generate_workflow(hot, files)) self._translated_class = yaml.dump(translated, Dumper=Dumper)
def load_from_dir(source_directory, filename='manifest.yaml', preload=False, loader=yaql_yaml_loader.YaqlYamlLoader): formats = { '1.0': murano.packages.versions.mpl_v1, 'MuranoPL/1.0': murano.packages.versions.mpl_v1, 'Heat.HOT/1.0': murano.packages.versions.hot_v1 } if not os.path.isdir(source_directory) or not os.path.exists( source_directory): raise e.PackageLoadError('Invalid package directory') full_path = os.path.join(source_directory, filename) if not os.path.isfile(full_path): raise e.PackageLoadError('Unable to find package manifest') try: with open(full_path) as stream: content = yaml.safe_load(stream) except Exception as ex: trace = sys.exc_info()[2] raise e.PackageLoadError("Unable to load due to '{0}'".format( str(ex))), None, trace if content: p_format = str(content.get('Format')) if not p_format or p_format not in formats: raise e.PackageFormatError('Unknown or missing format version') package = formats[p_format].create(source_directory, content, loader) formats[p_format].load(package, content) if preload: package.validate() return package
def load_from_file(archive_path, target_dir=None, drop_dir=False, loader=yaql_yaml_loader.YaqlYamlLoader): if not os.path.isfile(archive_path): raise e.PackageLoadError('Unable to find package file') created = False if not target_dir: target_dir = tempfile.mkdtemp() created = True elif not os.path.exists(target_dir): os.mkdir(target_dir) created = True else: if os.listdir(target_dir): raise e.PackageLoadError('Target directory is not empty') try: if not zipfile.is_zipfile(archive_path): raise e.PackageFormatError("Uploading file should be a " "zip' archive") package = zipfile.ZipFile(archive_path) package.extractall(path=target_dir) return load_from_dir(target_dir, preload=True, loader=loader) finally: if drop_dir: if created: shutil.rmtree(target_dir) else: for f in os.listdir(target_dir): os.unlink(os.path.join(target_dir, f))
def _check_full_name(full_name): error = exceptions.PackageFormatError('Invalid FullName ' + full_name) if re.match(r'^[\w\.]+$', full_name): if full_name.startswith('.') or full_name.endswith('.'): raise error if '..' in full_name: raise error else: raise error
def load_from_dir(source_directory, filename='manifest.yaml'): formats = { 'MuranoPL': { ('1.0.0', '1.0.0'): murano.packages.mpl_package.MuranoPlPackage, }, 'Heat.HOT': { ('1.0.0', '1.0.0'): murano.packages.hot_package.HotPackage } } if not os.path.isdir(source_directory) or not os.path.exists( source_directory): raise e.PackageLoadError('Invalid package directory') full_path = os.path.join(source_directory, filename) if not os.path.isfile(full_path): raise e.PackageLoadError('Unable to find package manifest') try: with open(full_path) as stream: content = yaml.safe_load(stream) except Exception as ex: trace = sys.exc_info()[2] raise e.PackageLoadError("Unable to load due to '{0}'".format( str(ex))), None, trace if content: p_format_spec = str(content.get('Format') or 'MuranoPL/1.0') if p_format_spec[0] in string.digits: p_format_spec = 'MuranoPL/' + p_format_spec parts = p_format_spec.split('/', 1) if parts[0] not in formats: raise e.PackageFormatError('Unknown or missing format version') format_set = formats[parts[0]] version = semantic_version.Version('0.0.0') if len(parts) > 1: version = semantic_version.Version.coerce(parts[1]) for key, value in format_set.iteritems(): min_version = semantic_version.Version(key[0]) max_version = semantic_version.Version(key[1]) if min_version <= version <= max_version: return value(source_directory, content, parts[0], version) raise e.PackageFormatError('Unsupported {0} format version {1}'.format( parts[0], version))
def test_package_format_error(self): messages = ['', 'test_message'] for message in messages: error = exceptions.PackageFormatError(message=message) expected = 'Incorrect package format' if message: expected += ': {0}'.format(message) if six.PY2: self.assertEqual(expected, error.message) elif six.PY34: self.assertEqual(expected, error.args[0])
def __init__(self, source_directory, manifest, package_format, runtime_version): super(PackageBase, self).__init__(source_directory, package_format, runtime_version) self._full_name = manifest.get('FullName') if not self._full_name: raise exceptions.PackageFormatError('FullName is not specified') self._check_full_name(self._full_name) self._version = semantic_version.Version.coerce( str(manifest.get('Version', '0.0.0'))) self._package_type = manifest.get('Type') if self._package_type not in package.PackageType.ALL: raise exceptions.PackageFormatError( 'Invalid package Type {0}'.format(self._package_type)) self._display_name = manifest.get('Name', self._full_name) self._description = manifest.get('Description') self._author = manifest.get('Author') self._supplier = manifest.get('Supplier') or {} self._logo = manifest.get('Logo') self._tags = manifest.get('Tags') self._logo_cache = None self._supplier_logo_cache = None
def load(package, yaml_content): package._full_name = yaml_content.get('FullName') if not package._full_name: raise murano.packages.exceptions.PackageFormatError( 'FullName not specified') _check_full_name(package._full_name) package._package_type = yaml_content.get('Type') if not package._package_type or package._package_type not in \ murano.packages.application_package.PackageTypes.ALL: raise e.PackageFormatError('Invalid Package Type') package._display_name = yaml_content.get('Name', package._full_name) package._description = yaml_content.get('Description') package._author = yaml_content.get('Author') package._supplier = yaml_content.get('Supplier') or {} package._logo = yaml_content.get('Logo') package._tags = yaml_content.get('Tags')
def _translate_class(self): csar_file = os.path.join(self._source_directory, 'csar.zip') shutil.copy(csar_file, self.get_resource(self.full_name)) if not os.path.isfile(csar_file): raise exceptions.PackageClassLoadError( self.full_name, 'File with class definition not found') csar_obj = csar.CSAR(csar_file) try: csar_obj.validate() except csar_exception.ValidationError as ve: raise exceptions.PackageFormatError('Not a CSAR archive: ' + str(ve)) translated = { 'Name': self.full_name, 'Extends': 'io.murano.Application' } csar_envs_path = os.path.join(self._source_directory, CSAR_RESOURCES_DIR_NAME, CSAR_ENV_DIR_NAME) validate_csar_parameters = (not os.path.isdir(csar_envs_path) or not os.listdir(csar_envs_path)) tosca = csar_obj.get_main_template_yaml() parameters = CSARPackage._build_properties(tosca, validate_csar_parameters) parameters.update(CSARPackage._translate_outputs(tosca)) translated['Properties'] = parameters hot = yaml.load( self._translate('tosca', csar_obj.csar, parameters, True)) files = CSARPackage._translate_files(self._source_directory) template_file = os.path.join(self._source_directory, CSAR_RESOURCES_DIR_NAME, 'template.yaml') with open(template_file, 'w') as outfile: outfile.write(yaml.safe_dump(hot)) translated.update(CSARPackage._generate_workflow(hot, files)) self._translated_class = yaml.dump(translated, Dumper=Dumper, default_style='"')
def _translate_class(self): template_file = path.secure_join(self._source_directory, 'template.yaml') if not os.path.isfile(template_file): raise exceptions.PackageClassLoadError( self.full_name, 'File with class definition not found') shutil.copy(template_file, self.get_resource(self.full_name)) with open(template_file) as stream: hot = yaml.safe_load(stream) if 'resources' not in hot: raise exceptions.PackageFormatError('Not a HOT template') translated = { 'Name': self.full_name, 'Extends': 'io.murano.Application' } hot_envs_path = path.secure_join(self._source_directory, RESOURCES_DIR_NAME, HOT_ENV_DIR_NAME) # if using hot environments, doing parameter validation with contracts # will overwrite the parameters in the hot environment. # don't validate parameters if hot environments exist. validate_hot_parameters = (not os.path.isdir(hot_envs_path) or not os.listdir(hot_envs_path)) parameters = HotPackage._build_properties(hot, validate_hot_parameters) parameters.update(HotPackage._translate_outputs(hot)) translated['Properties'] = parameters files = HotPackage._translate_files(self._source_directory) translated.update(HotPackage._generate_workflow(hot, files)) # use default_style with double quote mark because by default PyYAML # doesn't put any quote marks ans as a result strings with e.g. dashes # may be interpreted as YAQL expressions upon load self._translated_class = yaml.dump(translated, Dumper=Dumper, default_style='"')