Mini Shell

Direktori : /proc/thread-self/root/opt/alt/python37/lib/python3.7/site-packages/clcommon/
Upload File :
Current File : //proc/thread-self/root/opt/alt/python37/lib/python3.7/site-packages/clcommon/group_info_reader.py

# coding=utf-8
#
# Copyright CloudLinux Zug GmbH 2010-2018 All Rights Reserved
# Licensed under CLOUD LINUX ZUG GMBH LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENCE.TXT
#

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from typing import Dict  # NOQA
import requests
import platform
from time import sleep
from clcommon.utils import is_testing_enabled_repo, get_cl_version
from clcommon.clexception import FormattedException


class GroupInfoReaderError(FormattedException):

    def __init__(self, reason, message=None, details=None):
        if message is None:
            message = (
                'Error occurred during getting remote available groups info. '
                'Try again later. If you have the same problem again - '
                'contact CloudLinux support.'
            )
        super(GroupInfoReaderError, self).__init__(dict(
            message=message,
            context=dict(reason=reason),
            details=details,
        ))


class GroupInfoReader:
    """
    The purpose of this class is to get remote yum info
    about available groups:
    1. alt-php
    2. alt-nodejs
    3. alt-ruby
    4. alt-python
    There we get special url with json which depends on machine features:
    cl version: 6, 7, 6 hybrid
    architecture: x84_64, i386
    enabled testing repositories status: beta, stable
    """
    # TODO: consider about caching during some period of time
    GROUP_INFO = None
    GROUP_URL = None
    BASE = 'https://1.mirror.g.cdn.mycache.org/other/'

    @classmethod
    def group_url(cls):
        # type: () -> str
        """Get url with available groups json"""
        if cls.GROUP_URL is None:
            cls.GROUP_URL = cls._get_group_url()
        return cls.GROUP_URL

    @classmethod
    def _get_group_url(cls):
        # type () -> str
        """
        Final url example: http://1.mirror.g.cdn.mycache.org/other/cl6/package-info.x86_64.stable.json
        for cl6, arch x86_64 and disabled testing: stable
        :return string with result url or None if CL version cannot be identified
        """
        arch = platform.machine()
        arch = 'i386' if arch != 'x86_64' else arch
        repo = 'beta' if is_testing_enabled_repo() else 'stable'
        cl_version = get_cl_version()
        if cl_version is None:
            return None
        # replace cl7h -> cl7, due to using same repo link for 7/7h
        cl_version = cl_version.replace('cl7h', 'cl7')
        suffix = '.'.join(['/package-info', arch, repo, 'json'])
        return cls.BASE + cl_version + suffix

    @classmethod
    def get_available_groups(cls):
        # type: () -> Dict
        """
        Sends request to group url, gets json and converts it to dict
        :return: dict with groups info
        """
        if cls.GROUP_INFO is not None:
            return cls.GROUP_INFO
        url = cls.group_url()
        if url is None:
            raise GroupInfoReaderError(
                'Could not identify CloudLinux version',
                message='Could not identify CloudLinux version (using kernel version). '
                        'Restart your system. If you have the same problem again - '
                        'contact CloudLinux support.'
            )
        # requests.get() with 3 retries
        # Increasing sleep time
        attempts = 3
        for i in range(attempts):
            try:
                cls.GROUP_INFO = requests.get(url).json()
                return cls.GROUP_INFO
            except requests.exceptions.RequestException as e:
                if i + 1 >= attempts:
                    raise GroupInfoReaderError(
                        '{} - link unavailable'.format(url),
                        message='Connection problems. Try again later. '
                                'If you have the same problem again - '
                                'contact CloudLinux support.',
                        details=str(e)
                    )
                sleep(i + 1)

    @classmethod
    def get_group_info(cls, group):
        # type: (str) -> Dict
        """
        Filter dict with all available groups by special group name
        E.g: group = python
        we will get dict like that:
        {'alt-python27': {'version': '2.7.15', 'name': 'alt-python27', 'release': '1.el6'},
        'alt-python33': {'version': '3.3.3', 'name': 'alt-python33', 'release': '1.el6'},
        'alt-python34': {'version': '3.4.4', 'name': 'alt-python34', 'release': '1.el6'}...}
        :param group
        :rtype: dict with info per group
        """
        group_info = {}
        available_groups = cls.get_available_groups()
        for grp in available_groups.get('groups_info', {}):
            if group in grp:
                group_info.update({grp: available_groups['groups_info'][grp]})
        return group_info

Zerion Mini Shell 1.0