docklet/meter/intra/cgroup.py

113 lines
5.0 KiB
Python
Executable File

import subprocess, os
class cgroup_controller:
def read_value(group, uuid, item):
path = cgroup_manager.__default_prefix__ % (group, uuid, item)
if not os.path.exists(path):
raise Exception('read: container "%s" not found!' % uuid)
with open(path, 'r') as file:
value = file.read()
return value.strip()
def write_value(group, uuid, item, value):
path = cgroup_manager.__default_prefix__ % (group, uuid, item)
if not os.path.exists(path):
raise Exception('write: container "%s" not found!' % uuid)
try:
with open(path, 'w') as file:
file.write(str(value))
except:
pass
class cgroup_manager:
__prefix_docker__ = '/sys/fs/cgroup/%s/system.slice/docker-%s.scope/%s'
__prefix_lxc__ = '/sys/fs/cgroup/%s/lxc/%s/%s'
__prefix_lxcinit__ = '/sys/fs/cgroup/%s/init.scope/lxc/%s/%s'
def set_default_memory_limit(limit):
cgroup_manager.__default_memory_limit__ = limit
def set_cgroup_prefix(prefix = __prefix_lxc__):
cgroup_manager.__default_prefix__ = prefix
def auto_detect_prefix():
cgroup_manager.__default_prefix__ = cgroup_manager.__prefix_docker__
if len(cgroup_manager.get_cgroup_containers()) > 0:
return
cgroup_manager.__default_prefix__ = cgroup_manager.__prefix_lxcinit__
if len(cgroup_manager.get_cgroup_containers()) > 0:
return
cgroup_manager.__default_prefix__ = cgroup_manager.__prefix_lxc__
if len(cgroup_manager.get_cgroup_containers()) > 0:
return
# print("[info]", "set cgroup prefix to %s" % cgroup_manager.__default_prefix__)
def get_cgroup_containers():
containers = subprocess.getoutput("find %s -type d 2>/dev/null | awk -F\/ '{print $(NF-1)}'" % (cgroup_manager.__default_prefix__ % ('cpu', '*', '.'))).split()
uuids = []
for item in containers:
if item.startswith('docker-') and item.endswith('.scope') and len(item) > 64:
uuids.append(item[7:-6])
else:
uuids.append(item)
return uuids
def get_container_pid(uuid):
return int(cgroup_controller.read_value('cpu', uuid, 'tasks').split()[0])
def get_container_sample(uuid):
mem_page_sample = int(cgroup_controller.read_value('memory', uuid, 'memory.memsw.usage_in_bytes'))
mem_phys_sample = int(cgroup_controller.read_value('memory', uuid, 'memory.usage_in_bytes'))
cpu_sample = int(cgroup_controller.read_value('cpu', uuid, 'cpuacct.usage'))
pids_sample = int(cgroup_controller.read_value('pids', uuid, 'pids.current'))
container_pid = cgroup_manager.get_container_pid(uuid)
from intra.system import system_manager
real_time = system_manager.get_proc_etime(container_pid)
return {"cpu_sample": cpu_sample, "pids_sample": pids_sample, "mem_page_sample": mem_page_sample, "mem_phys_sample": mem_phys_sample, "pid": container_pid, "real_time": real_time}
def get_container_limit(uuid):
mem_phys_quota = int(cgroup_controller.read_value('memory', uuid, 'memory.limit_in_bytes'))
mem_page_quota = int(cgroup_controller.read_value('memory', uuid, 'memory.memsw.limit_in_bytes'))
cpu_shares = int(cgroup_controller.read_value('cpu', uuid, 'cpu.shares'))
cpu_quota = int(cgroup_controller.read_value('cpu', uuid, 'cpu.cfs_quota_us'))
cpu_quota = cpu_quota if cpu_quota >= 0 else -1
pids_quota = cgroup_controller.read_value('pids', uuid, 'pids.max')
pids_quota = int(pids_quota) if pids_quota != 'max' else -1
return {"cpu_quota": cpu_quota, "cpu_shares": cpu_shares, "mem_phy_quota": mem_phys_quota, "mem_page_quota": mem_page_quota, "pids_quota": pids_quota}
def get_container_oom_status(uuid):
[_x, idle, _y, oom] = cgroup_controller.read_value('memory', uuid, 'memory.oom_control').split()
return (idle == '1', oom == '1')
def set_container_oom_idle(uuid, idle):
cgroup_controller.write_value('memory', uuid, 'memory.oom_control', 1 if idle else 0)
def protect_container_oom(uuid):
cgroup_controller.write_value('memory', uuid, 'memory.oom_control', 1)
data = cgroup_manager.get_container_limit(uuid)
if data["mem_page_quota"] >= 9223372036854771712:
memory_limit_in_bytes = cgroup_manager.__default_memory_limit__ << 30
mem_phy_quota = min(data["mem_phy_quota"], memory_limit_in_bytes)
mem_page_quota = memory_limit_in_bytes
cgroup_controller.write_value('freezer', uuid, 'freezer.state', 'FROZEN')
cgroup_controller.write_value('memory', uuid, 'memory.limit_in_bytes', mem_phy_quota)
cgroup_controller.write_value('memory', uuid, 'memory.limit_in_bytes', mem_phy_quota)
cgroup_controller.write_value('memory', uuid, 'memory.memsw.limit_in_bytes', mem_page_quota)
cgroup_controller.write_value('freezer', uuid, 'freezer.state', 'THAWED')
def set_container_physical_memory_limit(uuid, Mbytes, freeze = False):
if freeze:
cgroup_controller.write_value('freezer', uuid, 'freezer.state', 'FROZEN')
memory_limit = int(max(0, Mbytes)) << 20
cgroup_controller.write_value('memory', uuid, 'memory.limit_in_bytes', memory_limit)
if freeze:
cgroup_controller.write_value('freezer', uuid, 'freezer.state', 'THAWED')
def set_container_cpu_priority_limit(uuid, ceof):
cpu_scaling = min(1024, 10 + int(1024 * ceof))
cgroup_controller.write_value('cpu', uuid, 'cpu.shares', cpu_scaling)