示例#1
0
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)
示例#2
0
    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)
示例#3
0
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))
示例#4
0
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
示例#5
0
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))
示例#6
0
 def _load_image(self, file_name, default_name, what_image):
     full_path = os.path.join(self._source_directory, file_name
                              or default_name)
     if not os.path.isfile(full_path) and not file_name:
         return
     try:
         if imghdr.what(full_path) != 'png':
             raise exceptions.PackageLoadError(
                 '{0} is not in PNG format'.format(what_image))
         with open(full_path) as stream:
             return stream.read()
     except Exception as ex:
         trace = sys.exc_info()[2]
         raise exceptions.PackageLoadError('Unable to load {0}: {1}'.format(
             what_image, ex)), None, trace
 def _load_logo(self, validate=False):
     logo_file = self._logo or 'logo.png'
     full_path = os.path.join(self._source_directory, logo_file)
     if not os.path.isfile(full_path) and logo_file == 'logo.png':
         self._logo_cache = None
         return
     try:
         if validate:
             if imghdr.what(full_path) != 'png':
                 raise e.PackageLoadError("Logo is not in PNG format")
         with open(full_path) as stream:
             self._logo_cache = stream.read()
     except Exception as ex:
         trace = sys.exc_info()[2]
         raise e.PackageLoadError("Unable to load logo: " +
                                  str(ex)), None, trace
示例#8
0
    def _get_package_by_definition(self, package_def):
        package_id = package_def.id
        package_name = package_def.fully_qualified_name
        package_directory = os.path.join(self._cache_directory, package_name)

        if os.path.exists(package_directory):
            try:
                return load_utils.load_from_dir(
                    package_directory,
                    preload=True,
                    loader=yaql_yaml_loader.YaqlYamlLoader)
            except pkg_exc.PackageLoadError:
                LOG.exception(
                    _LE('Unable to load package from cache. Clean-up...'))
                shutil.rmtree(package_directory, ignore_errors=True)
        try:
            package_data = self._murano_client_factory().packages.download(
                package_id)
        except muranoclient_exc.HTTPException as e:
            msg = 'Error loading package id {0}: {1}'.format(
                package_id, str(e))
            exc_info = sys.exc_info()
            raise pkg_exc.PackageLoadError(msg), None, exc_info[2]
        package_file = None
        try:
            with tempfile.NamedTemporaryFile(delete=False) as package_file:
                package_file.write(package_data)

            return load_utils.load_from_file(
                package_file.name,
                target_dir=package_directory,
                drop_dir=False,
                loader=yaql_yaml_loader.YaqlYamlLoader)
        except IOError:
            msg = 'Unable to extract package data for %s' % package_id
            exc_info = sys.exc_info()
            raise pkg_exc.PackageLoadError(msg), None, exc_info[2]
        finally:
            try:
                if package_file:
                    os.remove(package_file.name)
            except OSError:
                pass
示例#9
0
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))
示例#10
0
 def load_definition(self, name):
     try:
         package = self._get_package_for(name)
         if package is None:
             raise exceptions.NoPackageForClassFound(name)
         return package.get_class(name)
     # (sjmc7) This is used as a control condition for system classes;
     # do not delete (although I think it needs a better solution)
     except exceptions.NoPackageForClassFound:
         raise
     except Exception as e:
         msg = "Error loading {0}: {1}".format(name, str(e))
         raise pkg_exceptions.PackageLoadError(msg), None, sys.exc_info()[2]
示例#11
0
    def _get_package_by_definition(self, package_def):
        package_id = package_def.id
        package_directory = os.path.join(
            self._cache_directory, package_def.fully_qualified_name,
            getattr(package_def, 'version', '0.0.0'), package_id)

        if os.path.isdir(package_directory):
            try:
                return load_utils.load_from_dir(package_directory)
            except pkg_exc.PackageLoadError:
                LOG.exception(
                    _LE('Unable to load package from cache. Clean-up.'))
                shutil.rmtree(package_directory, ignore_errors=True)

        # the package is not yet in cache, let's try and download it.
        download_lock_path = os.path.join(
            self._cache_directory, '{}_download.lock'.format(package_id))
        download_ipc_lock = m_utils.ExclusiveInterProcessLock(
            path=download_lock_path, sleep_func=eventlet.sleep)

        with download_mem_locks[package_id].write_lock(), download_ipc_lock:

            # NOTE(kzaitsev):
            # in case there were 2 concurrent threads/processes one might have
            # already downloaded this package. Check before trying to download
            if os.path.isdir(package_directory):
                try:
                    return load_utils.load_from_dir(package_directory)
                except pkg_exc.PackageLoadError:
                    LOG.error(
                        _LE('Unable to load package from cache. Clean-up.'))
                    shutil.rmtree(package_directory, ignore_errors=True)

            # attempt the download itself
            try:
                LOG.debug("Attempting to download package {} {}".format(
                    package_def.fully_qualified_name, package_id))
                package_data = self.client.packages.download(package_id)
            except muranoclient_exc.HTTPException as e:
                msg = 'Error loading package id {0}: {1}'.format(
                    package_id, str(e))
                exc_info = sys.exc_info()
                six.reraise(pkg_exc.PackageLoadError,
                            pkg_exc.PackageLoadError(msg), exc_info[2])
            package_file = None
            try:
                with tempfile.NamedTemporaryFile(delete=False) as package_file:
                    package_file.write(package_data)

                with load_utils.load_from_file(package_file.name,
                                               target_dir=package_directory,
                                               drop_dir=False) as app_package:
                    LOG.info(
                        _LI("Successfully downloaded and unpacked package {} {}"
                            ).format(package_def.fully_qualified_name,
                                     package_id))
                    self._downloaded.append(app_package)

                    self.try_cleanup_cache(os.path.split(package_directory)[0],
                                           current_id=package_id)
                    return app_package
            except IOError:
                msg = 'Unable to extract package data for %s' % package_id
                exc_info = sys.exc_info()
                six.reraise(pkg_exc.PackageLoadError,
                            pkg_exc.PackageLoadError(msg), exc_info[2])
            finally:
                try:
                    if package_file:
                        os.remove(package_file.name)
                except OSError:
                    pass