Exemplo n.º 1
0
def get_python_package_repo(installer: str) -> str:
    """
    Gets the URL to the Tortuga Python package repository.

    :param str installer: the hostname of the installer

    :return str: the URL

    """
    cm = ConfigManager()

    url = cm.getIntWebRootUrl(installer)

    return '{}/python-tortuga/simple/'.format(url)
Exemplo n.º 2
0
def pip_install_requirements(requirements_path):
    """
    Installs packages specified in a requirements.txt file, using the tortuga
    package repo in addition to the standard python repos. This function
    returns nothing, and does nothing if the requirements.txt file is not
    found.

    :param requirements_path: the path to the requirements.txt file

    """
    cm = ConfigManager()

    if not os.path.exists(requirements_path):
        logger.debug('Requirements not found: {}'.format(requirements_path))
        return

    if is_requirements_empty(requirements_path):
        logger.debug('Requirements empty: {}'.format(requirements_path))
        return

    pip_cmd = [
        '{}/pip'.format(cm.getBinDir()),
        'install',
    ]

    installer = cm.getInstaller()
    int_webroot = cm.getIntWebRootUrl(installer)
    installer_repo = '{}/python-tortuga/simple/'.format(int_webroot)

    if cm.is_offline_installation():
        # add tortuga distribution repo
        pip_cmd.append('--index-url')
        pip_cmd.append(installer_repo)

        # add offline dependencies repo
        pip_cmd.append('--extra-index-url')
        pip_cmd.append('{}/offline-deps/python/simple/'.format(int_webroot))
    else:
        pip_cmd.append('--extra-index-url')

        pip_cmd.append(installer_repo)

    pip_cmd.extend(['--trusted-host', installer, '-r', requirements_path])

    logger.debug(' '.join(pip_cmd))
    proc = subprocess.Popen(pip_cmd)
    proc.wait()
    if proc.returncode:
        raise Exception(proc.stderr)
Exemplo n.º 3
0
def pip_install_requirements(requirements_path):
    """
    Installs packages specified in a requirements.txt file, using the kit
    package repo in addition to the standard python repos. This function
    returns nothing, and does nothing if the requirements.txt file is not
    found.

    :param kit_installer:     an instance of KitInstallerBase, which will
                              be searched for a local python package repo
    :param requirements_path: the path to the requirements.txt file

    """
    #
    # In the kit directory:
    #
    #     /opt/tortuga/kits/kit-x.y.z/tortuga_kits/kit_x_y_z
    #
    # if there is a python_packages directory, with a simple subdirectory
    # in it, it is assumed that the simple subdirectory is a PEP 503
    # compliant Python package repository. If found, this directory is
    # added to the list of directories searched for Python packages via
    # pip when installing the requirements.txt file.
    #
    # These directories can easily be created using the py2pi utility.
    #
    cm = ConfigManager()

    if not os.path.exists(requirements_path):
        logger.debug('Requirements not found: {}'.format(requirements_path))
        return

    if is_requirements_empty(requirements_path):
        logger.debug('Requirements empty: {}'.format(requirements_path))
        return

    installer = cm.getInstaller()
    int_webroot = cm.getIntWebRootUrl(installer)
    installer_repo = '{}/python-tortuga/simple/'.format(int_webroot)

    pip_cmd = [
        '{}/pip'.format(cm.getBinDir()), 'install',
        '--extra-index-url', installer_repo,
        '--trusted-host', installer,
        '-r', requirements_path
    ]

    logger.debug(' '.join(pip_cmd))
    subprocess.Popen(pip_cmd).wait()
Exemplo n.º 4
0
def get_puppet_node_yaml(session, nodeName):
    _cm = ConfigManager()

    publicInstallerFQDN = _cm.getInstaller().lower()
    primaryInstallerHostName = publicInstallerFQDN.split('.', 1)[0]

    try:
        dnsZone = GlobalParametersDbHandler().getParameter(
            session, 'DNSZone').value.lower()
    except ParameterNotFound:
        dnsZone = None

    try:
        depot_path = GlobalParametersDbHandler().getParameter(
            session, 'depot').value.lower()

        _cm.setDepotDir(depot_path)
    except ParameterNotFound:
        pass

    bInstaller = primaryInstallerHostName == nodeName.split('.', 1)[0]

    try:
        dbNode = NodesDbHandler().getNode(session, nodeName)
    except NodeNotFound:
        sys.exit(1)

    data = None
    try:
        from tortuga.db.dataRequestsDbHandler import DataRequestsDbHandler
        dbDataRequest = DataRequestsDbHandler().get_by_addHostSession(
            session, dbNode.addHostSession)
        if dbDataRequest:
            data = dbDataRequest.request
    except Exception as e:
        pass

    if dbNode.hardwareprofile.nics:
        privateInstallerFQDN = '%s%s%s' % (primaryInstallerHostName,
                                           get_installer_hostname_suffix(
                                               dbNode.hardwareprofile.nics[0],
                                               enable_interface_aliases=None),
                                           '.%s' %
                                           (dnsZone) if dnsZone else '')
    else:
        privateInstallerFQDN = '%s%s' % (primaryInstallerHostName, '.%s' %
                                         (dnsZone) if dnsZone else '')

    if not bInstaller and dbNode.hardwareprofile.location == 'local':
        # If the hardware profile does not have an associated provisioning
        # NIC, use the public installer FQDN by default. This can happen if
        # the user has added their own "public" nodes to a local hardware
        # profile.

        if not dbNode.hardwareprofile.nics:
            installerHostName = publicInstallerFQDN
        else:
            installerHostName = privateInstallerFQDN
    else:
        # If the specified node is the installer itself or a node
        # accessing the installer through it's public interface, use the
        # public host name.
        installerHostName = publicInstallerFQDN

    puppet_classes = {}

    enabledKits = set()

    if dbNode.softwareprofile:

        for dbComponent in dbNode.softwareprofile.components:

            if not dbComponent.kit.isOs:
                #
                # Load the kit and component installers
                #
                kit_spec = (dbComponent.kit.name, dbComponent.kit.version,
                            dbComponent.kit.iteration)
                kit_installer = get_kit_installer(kit_spec)()
                kit_installer.session = session
                _component = kit_installer.get_component_installer(
                    dbComponent.name)

                #
                # Get the puppet args for the component
                #
                try:
                    puppet_class_args = _component.run_action(
                        'get_puppet_args',
                        dbNode.softwareprofile,
                        dbNode.hardwareprofile,
                        data=data)
                    if puppet_class_args is not None:
                        puppet_classes[_component.puppet_class] = \
                            puppet_class_args
                except Exception:  # noqa pylint: disable=broad-except
                    # suppress exception if unable to get Puppet args
                    puppet_classes[_component.puppet_class] = {}

            else:
                #
                # OS kit component is omitted on installer. The installer
                # is assumed to have a pre-existing OS repository
                # configuration.
                #
                if bInstaller:
                    continue

            enabledKits.add(dbComponent.kit)

    dataDict = {}

    if puppet_classes:
        dataDict['classes'] = puppet_classes

    parametersDict = {}
    dataDict['parameters'] = parametersDict

    # software profile
    if dbNode.softwareprofile:
        parametersDict['swprofilename'] = dbNode.softwareprofile.name

    # hardware profile
    parametersDict['hwprofilename'] = dbNode.hardwareprofile.name

    # installer hostname
    parametersDict['primary_installer_hostname'] = installerHostName

    # Local repos directory
    repodir = os.path.join(_cm.getDepotDir(), 'kits')

    # Build YUM repository entries only if we have kits associated with
    # the software profile.
    if enabledKits:
        repourl = _cm.getIntWebRootUrl(installerHostName) + '/repos' \
            if not bInstaller else 'file://{0}'.format(repodir)

        repo_type = None

        if dbNode.softwareprofile.os.family.name == 'rhel':
            repo_type = 'yum'
        # elif dbNode.softwareprofile.os.family == 'ubuntu':
        #     repo_type = 'apt'

        if repo_type:
            # Only add 'repos' entries for supported operating system
            # families.

            repos_dict = {}

            for kit in enabledKits:
                if kit.isOs:
                    verstr = str(kit.version)
                    arch = kit.components[0].os[0].arch
                else:
                    verstr = '%s-%s' % (kit.version, kit.iteration)
                    arch = 'noarch'

                for dbKitSource in dbNode.softwareprofile.kitsources:
                    if dbKitSource in kit.sources:
                        baseurl = dbKitSource.url
                        break
                else:
                    subpath = '%s/%s/%s' % (kit.name, verstr, arch)

                    if not kit.isOs and not os.path.exists(
                            os.path.join(repodir, subpath,
                                         'repodata/repomd.xml')):
                        continue

                    baseurl = '%s/%s' % (repourl, subpath)

                    # [TODO] temporary workaround for handling RHEL media
                    # path.
                    #
                    # This code is duplicated from tortuga.boot.distro
                    if kit.isOs and \
                       dbNode.softwareprofile.os.name == 'rhel' and \
                       dbNode.softwareprofile.os.family.version != '7':
                        subpath += '/Server'

                if repo_type == 'yum':
                    if dbNode.hardwareprofile.location == 'remote':
                        cost = 1200
                    else:
                        cost = 1000

                    repos_dict['uc-kit-%s' % (kit.name)] = {
                        'type': repo_type,
                        'baseurl': baseurl,
                        'cost': cost,
                    }

            if repos_dict:
                parametersDict['repos'] = repos_dict

    # Enable '3rdparty' repo
    if dbNode.softwareprofile:
        third_party_repo_subpath = '3rdparty/%s/%s/%s' % (
            dbNode.softwareprofile.os.family.name,
            dbNode.softwareprofile.os.family.version,
            dbNode.softwareprofile.os.arch)

        local_repos_path = os.path.join(repodir, third_party_repo_subpath)

        # Check for existence of repository metadata to validate existence
        if enabledKits and os.path.exists(
                os.path.join(local_repos_path, 'repodata', 'repomd.xml')):
            third_party_repo_dict = {
                'tortuga-third-party': {
                    'type': 'yum',
                    'baseurl': os.path.join(repourl, third_party_repo_subpath),
                },
            }

            if 'repos' not in parametersDict:
                parametersDict['repos'] = third_party_repo_dict
            else:
                parametersDict['repos'] = dict(
                    list(parametersDict['repos'].items()) +
                    list(third_party_repo_dict.items()))

    # environment
    dataDict['environment'] = 'production'

    sys.stdout.write(
        yaml.safe_dump(dataDict, default_flow_style=False,
                       explicit_start=True))