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.makedirs(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(path.secure_join(target_dir, f))
def _load_image(self, file_name, default_name, what_image): full_path = path.secure_join( self._source_directory, file_name or default_name) if not os.path.isfile(full_path) and not file_name: return allowed_ftype = ('png', 'jpeg', 'gif') allowed_size = 500 * 1024 try: if imghdr.what(full_path) not in allowed_ftype: msg = _('{0}: Unsupported Format. Only {1} allowed').format( what_image, ', '.join(allowed_ftype)) raise exceptions.PackageLoadError(msg) fsize = os.stat(full_path).st_size if fsize > allowed_size: msg = _('{0}: Uploaded image size {1} is too large. ' 'Max allowed size is {2}').format( what_image, fsize, allowed_size) raise exceptions.PackageLoadError(msg) with open(full_path, 'rb') as stream: return stream.read() except Exception as ex: trace = sys.exc_info()[2] six.reraise(exceptions.PackageLoadError, exceptions.PackageLoadError( 'Unable to load {0}: {1}'.format(what_image, ex)), trace)
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_ui(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') with open(template_file) as stream: hot = yaml.safe_load(stream) groups = HotPackage._translate_ui_parameters(hot, self.description) forms = [] for i, record in enumerate(groups): forms.append({'group{0}'.format(i): {'fields': record[0]}}) translated = { 'Version': 2, 'Application': HotPackage._generate_application_ui(groups, self.full_name, self.full_name, str(self.version)), 'Forms': forms } # see comment above about default_style return yaml.dump(translated, Dumper=Dumper, default_style='"')
def _get_inputs_outputs(self): entry_point_path = path.secure_join(self.source_directory, RESOURCES_DIR_NAME, self._entry_point) with open(entry_point_path) as blueprint: data = yaml.safe_load(blueprint) return data.get('inputs') or {}, data.get('outputs') or {}
def ui(self): full_path = path.secure_join(self._source_directory, 'UI', self._ui_file) if not os.path.isfile(full_path): return None with open(full_path, 'rb') as stream: return stream.read()
def _build_hot_resources(basedir): result = [] if os.path.isdir(basedir): for root, _, files in os.walk(os.path.abspath(basedir)): for f in files: full_path = path.secure_join(root, f) relative_path = os.path.relpath(full_path, basedir) result.append(relative_path) return result
def get_class(self, name): if name not in self._classes: raise exceptions.PackageClassLoadError( name, 'Class not defined in package ' + self.full_name) def_file = self._classes[name] full_path = path.secure_join(self._source_directory, 'Classes', def_file) if not os.path.isfile(full_path): raise exceptions.PackageClassLoadError( name, 'File with class definition not found') with open(full_path, 'rb') as stream: return stream.read(), full_path
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='"')
def get_resource(self, name): resources_dir = path.secure_join(self._source_directory, 'Resources') if not os.path.exists(resources_dir): os.makedirs(resources_dir) return path.secure_join(resources_dir, name)
def _zip_dir(base, zip_file): for root, _, files in os.walk(base): for f in files: abs_path = path.secure_join(root, f) relative_path = os.path.relpath(abs_path, base) zip_file.write(abs_path, relative_path)
def _get_inputs_outputs(self): entry_point_path = path.secure_join( self.source_directory, RESOURCES_DIR_NAME, self._entry_point) with open(entry_point_path) as blueprint: data = yaml.safe_load(blueprint) return data.get('inputs') or {}, data.get('outputs') or {}
def _translate_files(source_directory): hot_files_path = path.secure_join( source_directory, RESOURCES_DIR_NAME, HOT_FILES_DIR_NAME) return HotPackage._build_hot_resources(hot_files_path)