Beispiel #1
0
    def _register_pack_db(self, pack_name, pack_dir):
        content = get_pack_metadata(pack_dir=pack_dir)

        # The rules for the pack ref are as follows:
        # 1. If ref attribute is available, we used that
        # 2. If pack_name is available we use that (this only applies to packs
        # 2hich are in sub-directories)
        # 2. If attribute is not available, but pack name is and pack name meets the valid name
        # criteria, we use that
        content['ref'] = get_pack_ref_from_metadata(
            metadata=content, pack_directory_name=pack_name)

        # Include a list of pack files
        pack_file_list = get_file_list(directory=pack_dir,
                                       exclude_patterns=EXCLUDE_FILE_PATTERNS)
        content['files'] = pack_file_list

        pack_api = PackAPI(**content)
        pack_api.validate()
        pack_db = PackAPI.to_model(pack_api)

        try:
            pack_db.id = Pack.get_by_ref(content['ref']).id
        except StackStormDBObjectNotFoundError:
            LOG.debug('Pack %s not found. Creating new one.', pack_name)

        pack_db = Pack.add_or_update(pack_db)
        LOG.debug('Pack %s registered.' % (pack_name))
        return pack_db
Beispiel #2
0
def verify_pack_version(pack_dir):
    """
    Verify that the pack works with the currently running StackStorm version.
    """
    pack_metadata = get_pack_metadata(pack_dir=pack_dir)
    pack_name = pack_metadata.get('name', None)
    required_stackstorm_version = pack_metadata.get('stackstorm_version', None)
    supported_python_versions = pack_metadata.get('python_versions', None)

    # If stackstorm_version attribute is specified, verify that the pack works with currently
    # running version of StackStorm
    if required_stackstorm_version:
        if not complex_semver_match(CURRENT_STACKSTORM_VERSION, required_stackstorm_version):
            msg = ('Pack "%s" requires StackStorm "%s", but current version is "%s". '
                   'You can override this restriction by providing the "force" flag, but '
                   'the pack is not guaranteed to work.' %
                   (pack_name, required_stackstorm_version, CURRENT_STACKSTORM_VERSION))
            raise ValueError(msg)

    if supported_python_versions:
        if set(supported_python_versions) == set(['2']) and not six.PY2:
            msg = ('Pack "%s" requires Python 2.x, but current Python version is "%s". '
                   'You can override this restriction by providing the "force" flag, but '
                   'the pack is not guaranteed to work.' % (pack_name, CURRENT_PYTHON_VERSION))
            raise ValueError(msg)
        elif set(supported_python_versions) == set(['3']) and not six.PY3:
            msg = ('Pack "%s" requires Python 3.x, but current Python version is "%s". '
                   'You can override this restriction by providing the "force" flag, but '
                   'the pack is not guaranteed to work.' % (pack_name, CURRENT_PYTHON_VERSION))
            raise ValueError(msg)
        else:
            # Pack support Python 2.x and 3.x so no check is needed
            pass

    return True
Beispiel #3
0
    def _register_pack_db(self, pack_name, pack_dir):
        content = get_pack_metadata(pack_dir=pack_dir)

        # The rules for the pack ref are as follows:
        # 1. If ref attribute is available, we used that
        # 2. If pack_name is available we use that (this only applies to packs
        # 2hich are in sub-directories)
        # 2. If attribute is not available, but pack name is and pack name meets the valid name
        # criteria, we use that
        content['ref'] = get_pack_ref_from_metadata(metadata=content,
                                                    pack_directory_name=pack_name)

        # Include a list of pack files
        pack_file_list = get_file_list(directory=pack_dir, exclude_patterns=EXCLUDE_FILE_PATTERNS)
        content['files'] = pack_file_list

        pack_api = PackAPI(**content)
        pack_api.validate()
        pack_db = PackAPI.to_model(pack_api)

        try:
            pack_db.id = Pack.get_by_ref(content['ref']).id
        except StackStormDBObjectNotFoundError:
            LOG.debug('Pack %s not found. Creating new one.', pack_name)

        pack_db = Pack.add_or_update(pack_db)
        LOG.debug('Pack %s registered.' % (pack_name))
        return pack_db
Beispiel #4
0
    def run(self, installed_pack, **kwargs):
        """
        :param installed_pack: Installed pack name with version
        :type: installed_pack: ``string``
        """

        if not installed_pack:
            return False, False

        pack_and_version = installed_pack.split(PACK_VERSION_SEPARATOR)
        pack_name = pack_and_version[0]
        pack_version = pack_and_version[1] if len(pack_and_version) > 1 else None

        # Pack version is not specified. Get pack version from index.json file.
        if not pack_version:
            try:
                _, pack_version = get_repo_url(pack_name, proxy_config=None)
            except Exception:
                print ('No record of the "%s" pack in the index.' % (pack_name))
                return False, False

        # Get installed pack version from local pack metadata file.
        try:
            pack_dir = '/opt/stackstorm/packs/%s/' % (pack_name)
            pack_metadata = get_pack_metadata(pack_dir=pack_dir)
            local_pack_version = pack_metadata.get('version', None)
        except Exception:
            print ('Could not open pack.yaml file at location %s' % (pack_dir))
            return False, False

        if pack_version == local_pack_version:
            return True, True
        else:
            return False, False
Beispiel #5
0
def verify_pack_version(pack_dir):
    """
    Verify that the pack works with the currently running StackStorm version.
    """
    pack_metadata = get_pack_metadata(pack_dir=pack_dir)
    pack_name = pack_metadata.get('name', None)
    required_stackstorm_version = pack_metadata.get('stackstorm_version', None)
    supported_python_versions = pack_metadata.get('python_versions', None)

    # If stackstorm_version attribute is specified, verify that the pack works with currently
    # running version of StackStorm
    if required_stackstorm_version:
        if not complex_semver_match(CURRENT_STACKSTORM_VERSION, required_stackstorm_version):
            msg = ('Pack "%s" requires StackStorm "%s", but current version is "%s". '
                   'You can override this restriction by providing the "force" flag, but '
                   'the pack is not guaranteed to work.' %
                   (pack_name, required_stackstorm_version, CURRENT_STACKSTORM_VERSION))
            raise ValueError(msg)

    if supported_python_versions:
        if set(supported_python_versions) == set(['2']) and not six.PY2:
            msg = ('Pack "%s" requires Python 2.x, but current Python version is "%s". '
                   'You can override this restriction by providing the "force" flag, but '
                   'the pack is not guaranteed to work.' % (pack_name, CURRENT_PYTHON_VERSION))
            raise ValueError(msg)
        elif set(supported_python_versions) == set(['3']) and not six.PY3:
            msg = ('Pack "%s" requires Python 3.x, but current Python version is "%s". '
                   'You can override this restriction by providing the "force" flag, but '
                   'the pack is not guaranteed to work.' % (pack_name, CURRENT_PYTHON_VERSION))
            raise ValueError(msg)
        else:
            # Pack support Python 2.x and 3.x so no check is needed
            pass

    return True
Beispiel #6
0
def get_pack_ref(pack_dir):
    """
    Read pack reference from the metadata file and sanitize it.
    """
    metadata = get_pack_metadata(pack_dir=pack_dir)
    pack_ref = get_pack_ref_from_metadata(metadata=metadata, pack_directory_name=None)
    return pack_ref
Beispiel #7
0
def get_pack_ref(pack_dir):
    """
    Read pack reference from the metadata file and sanitize it.
    """
    metadata = get_pack_metadata(pack_dir=pack_dir)
    pack_ref = get_pack_ref_from_metadata(metadata=metadata,
                                          pack_directory_name=None)
    return pack_ref
def get_pack_version(pack=None):
    pack_path = get_pack_base_path(pack)
    try:
        pack_metadata = get_pack_metadata(pack_dir=pack_path)
        result = pack_metadata.get("version", None)
    except Exception:
        result = None
    finally:
        return result
Beispiel #9
0
def get_warnings(pack=None):
    result = None
    pack_path = get_pack_base_path(pack)
    try:
        pack_metadata = get_pack_metadata(pack_dir=pack_path)
        result = get_pack_warnings(pack_metadata)
    except Exception:
        print("Could not open pack.yaml at location %s" % pack_path)
    finally:
        return result
Beispiel #10
0
def get_dependency_list(pack=None):
    pack_path = get_pack_base_path(pack)

    try:
        pack_metadata = get_pack_metadata(pack_dir=pack_path)
        result = pack_metadata.get("dependencies", None)
    except Exception:
        print("Could not open pack.yaml at location %s" % pack_path)
        result = None
    finally:
        return result
Beispiel #11
0
def verify_pack_version(pack_dir):
    """
    Verify that the pack works with the currently running StackStorm version.
    """
    pack_metadata = get_pack_metadata(pack_dir=pack_dir)
    pack_name = pack_metadata.get('name', None)
    required_stackstorm_version = pack_metadata.get('stackstorm_version', None)

    # If stackstorm_version attribute is speficied, verify that the pack works with currently
    # running version of StackStorm
    if required_stackstorm_version:
        if not complex_semver_match(CURRENT_STACKSTROM_VERSION,
                                    required_stackstorm_version):
            msg = (
                'Pack "%s" requires StackStorm "%s", but current version is "%s". '
                % (pack_name, required_stackstorm_version,
                   CURRENT_STACKSTROM_VERSION),
                'You can override this restriction by providing the "force" flag, but ',
                'the pack is not guaranteed to work.')
            raise ValueError(msg)

    return True
Beispiel #12
0
 def _get_pack_metadata(pack_dir):
     metadata = get_pack_metadata(pack_dir=pack_dir)
     return metadata
Beispiel #13
0
 def _get_pack_metadata(pack_dir):
     metadata = get_pack_metadata(pack_dir=pack_dir)
     return metadata
Beispiel #14
0
def download_pack(pack, abs_repo_base='/opt/stackstorm/packs', verify_ssl=True, force=False,
                  proxy_config=None, force_owner_group=True, force_permissions=True,
                  use_python3=False, logger=LOG):
    """
    Download the pack and move it to /opt/stackstorm/packs.

    :param abs_repo_base: Path where the pack should be installed to.
    :type abs_repo_base: ``str``

    :param pack: Pack name.
    :rtype pack: ``str``

    :param force_owner_group: Set owner group of the pack directory to the value defined in the
                              config.
    :type force_owner_group: ``bool``

    :param force_permissions: True to force 770 permission on all the pack content.
    :type force_permissions: ``bool``

    :param force: Force the installation and ignore / delete the lock file if it already exists.
    :type force: ``bool``

    :param use_python3: True if a python3 binary should be used for this pack.
    :type use_python3: ``bool``

    :return: (pack_url, pack_ref, result)
    :rtype: tuple
    """
    proxy_config = proxy_config or {}

    # Python3 binary check
    python3_binary = cfg.CONF.actionrunner.python3_binary
    if use_python3 and not python3_binary:
        msg = ('Requested to use Python 3, but python3 binary not found on the system or '
               'actionrunner.python3 config option is not configured correctly.')
        raise ValueError(msg)

    try:
        pack_url, pack_version = get_repo_url(pack, proxy_config=proxy_config)
    except Exception as e:
        # Pack not found or similar
        result = [None, pack, (False, six.text_type(e))]
        return result

    result = [pack_url, None, None]

    temp_dir_name = hashlib.md5(pack_url.encode()).hexdigest()
    lock_file = LockFile('/tmp/%s' % (temp_dir_name))
    lock_file_path = lock_file.lock_file

    if force:
        logger.debug('Force mode is enabled, deleting lock file...')

        try:
            os.unlink(lock_file_path)
        except OSError:
            # Lock file doesn't exist or similar
            pass

    with lock_file:
        try:
            user_home = os.path.expanduser('~')
            abs_local_path = os.path.join(user_home, temp_dir_name)

            if pack_url.startswith('file://'):
                # Local pack
                local_pack_directory = os.path.abspath(os.path.join(pack_url.split('file://')[1]))
            else:
                local_pack_directory = None

            # If it's a local pack which is not a git repository, just copy the directory content
            # over
            if local_pack_directory and not os.path.isdir(
                    os.path.join(local_pack_directory, '.git')):
                if not os.path.isdir(local_pack_directory):
                    raise ValueError('Local pack directory "%s" doesn\'t exist' %
                                     (local_pack_directory))

                logger.debug('Detected local pack directory which is not a git repository, just '
                             'copying files over...')

                shutil.copytree(local_pack_directory, abs_local_path)
            else:
                # 1. Clone / download the repo
                clone_repo(temp_dir=abs_local_path, repo_url=pack_url, verify_ssl=verify_ssl,
                           ref=pack_version)

            pack_metadata = get_pack_metadata(pack_dir=abs_local_path)
            pack_ref = get_pack_ref(pack_dir=abs_local_path)
            result[1] = pack_ref

            # 2. Verify that the pack version if compatible with current StackStorm version
            if not force:
                verify_pack_version(pack_metadata=pack_metadata, use_python3=use_python3)

            # 3. Move pack to the final location
            move_result = move_pack(abs_repo_base=abs_repo_base, pack_name=pack_ref,
                                    abs_local_path=abs_local_path,
                                    pack_metadata=pack_metadata,
                                    force_owner_group=force_owner_group,
                                    force_permissions=force_permissions,
                                    logger=logger)
            result[2] = move_result
        finally:
            cleanup_repo(abs_local_path=abs_local_path)

    return tuple(result)