Mini Shell
# 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