Mini Shell
# coding=utf-8
#
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT
import os
from typing import Optional, Dict, AnyStr, Union, List
class NotSupported(Exception):
"""
Custom error to handle compatibility issues
"""
pass
def get_proc_info_as_list_of_dicts(
file_content: AnyStr
) -> List[Optional[Dict[AnyStr, AnyStr]]]:
"""
Parses the response of /proc files
Since this file has a possibility to include multiple
objects info, we need to parse all of them in the separate dicts
:file_content: /proc file content. Example:
processor : 0
vendor_id : AuthenticAMD
processor : 1
vendor_id : AuthenticAMD_1
return: list of dicts with each node
"""
result = []
for info_object in file_content.split("\n\n"):
temp_dict = {}
if not info_object:
continue
for info_attr in info_object.split("\n"):
values = info_attr.split(":")
if len(values) == 2:
temp_dict[values[0].strip()] = values[1].strip()
result.append(temp_dict)
return result
def convert_string_kb_to_mb_value(value: str) -> float:
"""
Helper to get numeric value of string record and convert it to mb
:value: metric value from /proc file. Example: '512 KB'
return: converted value. Example: 0.5
"""
return float(value.split()[0]) / 1024
def get_cpu_metrics() -> List[Optional[Dict[AnyStr,
Union[AnyStr, float, int]]]]:
"""
Prepare list of dicts with required cpu metrics
The base of this method was taken from rhn_client_tools
(src/up2date_client/hardware.py)
Each CPU will be represented with a dict
{
"model": "foo",
"cache_mb": 100,
"frequency_mhz": 100,
"id": 0
}
return: list of dicts with cpu metrics
"""
result_list = []
uname = os.uname().machine
# We can't read the /proc/cpuinfo file or arch isn't compatible
if not os.access("/proc/cpuinfo", os.R_OK):
raise OSError("File for cpuinfo is restricted!")
if uname not in ["x86_64", "i386"]:
raise NotSupported(f"Machine arch {uname} isn't compatible!")
with open("/proc/cpuinfo", "r", encoding="utf-8") as f:
proc_cpuinfo = f.read()
cpu_list = get_proc_info_as_list_of_dicts(proc_cpuinfo)
for cpu in cpu_list:
cpu_dict = {
"id": int(cpu.get('processor', "0")),
# Idea of set a default value from machine arch
# was taken from rhn-client-tools hw getter
"model": cpu.get('model name', uname),
"cache_mb": convert_string_kb_to_mb_value(cpu.get('cache size', "0 KB")),
"frequency_mhz": float(cpu.get('cpu MHz', "0"))
}
result_list.append(cpu_dict)
return result_list
def get_memory_metrics() -> Dict[AnyStr, float]:
"""
Prepare dict of memory metrics
Dict will be represented as:
{
"ram_mb": 8.5
"swap_mb": 2.04
}
"""
if not os.access("/proc/meminfo", os.R_OK):
raise OSError("File for meminfo is restricted!")
with open("/proc/meminfo", "r", encoding="utf-8") as f:
proc_meminfo = f.read()
# meminfo return only one info object
mem_dict = get_proc_info_as_list_of_dicts(proc_meminfo)[0]
# All mem_dict values are represented as string. Example:
# 1000 KB
# We need to split them, convert to int and divide on 1024
# Thus, we will get MB representation of metric
result = {
"ram_mb": convert_string_kb_to_mb_value(mem_dict.get("MemTotal", "0 KB")),
"swap_mb": convert_string_kb_to_mb_value(mem_dict.get("SwapTotal", "0 KB")),
}
return result
Zerion Mini Shell 1.0