Module src.NodeRescaler.lxd_node_resource_manager
Expand source code
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022 Universidade da Coruña
# Authors:
# - Jonatan Enes [main](jonatan.enes@udc.es)
# - Roberto R. Expósito
# - Juan Touriño
#
# This file is part of the ServerlessContainers framework, from
# now on referred to as ServerlessContainers.
#
# ServerlessContainers is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 3
# of the License, or (at your option) any later version.
#
# ServerlessContainers is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with ServerlessContainers. If not, see <http://www.gnu.org/licenses/>.
import os
import urllib3
import pylxd
from pylxd import Client
from pylxd.exceptions import NotFound
# Getters
from src.NodeRescaler.node_resource_manager import get_node_cpus
from src.NodeRescaler.node_resource_manager import get_node_mem
from src.NodeRescaler.node_resource_manager import get_node_disks as cgroups_get_node_disks
from src.NodeRescaler.node_resource_manager import get_node_networks as cgroups_get_node_networks
# Setters
from src.NodeRescaler.node_resource_manager import set_node_cpus
from src.NodeRescaler.node_resource_manager import set_node_mem
from src.NodeRescaler.node_resource_manager import set_node_disk
from src.NodeRescaler.node_resource_manager import set_node_net
urllib3.disable_warnings()
DICT_CPU_LABEL = "cpu"
DICT_MEM_LABEL = "mem"
DICT_DISK_LABEL = "disk"
DICT_NET_LABEL = "net"
class LXDContainerManager:
def read_keys(self):
# TODO Improve key handling
self.LXD_CRT = '/${LXD_KEY_PATH}/${LXD_KEY_NAME}.crt'
self.LXD_KEY = '/${LXD_KEY_PATH}/${LXD_KEY_NAME}.key'
self.LXD_ENDPOINT = 'https://localhost:8443'
def __init__(self):
self.read_keys()
# TODO Deal with error if key does not exist
self.client = Client(
endpoint=os.path.expandvars(self.LXD_ENDPOINT),
cert=(os.path.expandvars(self.LXD_CRT),
os.path.expandvars(self.LXD_KEY)),
verify=False)
def get_node_disks(self, container):
devices = container.devices
if not devices:
return True, []
else:
return cgroups_get_node_disks(container.name, devices)
def get_node_networks(self, container):
networks = container.state().network
if not networks:
return True, []
else:
network_host_interfaces = list()
for net in networks.keys():
if net == "lo":
continue # Skip the internal loopback interface
network_host_interfaces.append(
{"container_interface": net, "host_interface": networks[net]["host_name"]})
return cgroups_get_node_networks(network_host_interfaces)
def set_node_resources(self, node_name, resources):
if resources is None:
# No resources to set
return False, {}
else:
try:
container = self.client.containers.get(node_name)
if container.status == "Running":
node_dict = dict()
(cpu_success, mem_success, disk_success, net_success) = (True, True, True, True)
if DICT_CPU_LABEL in resources:
cpu_success, cpu_resources = set_node_cpus(node_name, resources[DICT_CPU_LABEL])
node_dict[DICT_CPU_LABEL] = cpu_resources
if DICT_MEM_LABEL in resources:
mem_success, mem_resources = set_node_mem(node_name, resources[DICT_MEM_LABEL])
node_dict[DICT_MEM_LABEL] = mem_resources
if DICT_DISK_LABEL in resources:
disk_success, disk_resource = set_node_disk(node_name, resources[DICT_DISK_LABEL])
node_dict[DICT_DISK_LABEL] = disk_resource
# disks_changed = list()
# for disk in resources[DICT_DISK_LABEL]:
# disk_success, disk_resource = set_node_disk(node_name, disk)
# disks_changed.append(disk_resource)
# node_dict[DICT_DISK_LABEL] = disks_changed
if DICT_NET_LABEL in resources:
net_success, net_resource = set_node_net(resources[DICT_NET_LABEL])
node_dict[DICT_NET_LABEL] = net_resource
# networks_changed = list()
# for net in resources[DICT_NET_LABEL]:
# net_success, net_resource = set_node_net(net)
# networks_changed.append(net_resource)
# node_dict[DICT_NET_LABEL] = networks_changed
global_success = cpu_success and mem_success and disk_success and net_success
return global_success, node_dict
else:
# If container not running, skip
return False, {}
except pylxd.exceptions.NotFound:
# If node not found, pass
return False, {}
def get_node_resources_by_name(self, container_name):
container = self.client.containers.get(container_name)
return self.get_node_resources(container)
def get_node_resources(self, container):
try:
node_name = container.name
if container.status == "Running":
node_dict = dict()
cpu_success, cpu_resources = get_node_cpus(node_name)
node_dict[DICT_CPU_LABEL] = cpu_resources
mem_success, mem_resources = get_node_mem(node_name)
node_dict[DICT_MEM_LABEL] = mem_resources
# disk_success, disk_resources = self.get_node_disks(container) # LXD Dependent
# if type(disk_resources) == list and len(disk_resources) > 0:
# node_dict[DICT_DISK_LABEL] = disk_resources[0]
# elif disk_resources:
# node_dict[DICT_DISK_LABEL] = disk_resources
# else:
# node_dict[DICT_DISK_LABEL] = []
# # TODO support multiple disks
#
# net_success, net_resources = self.get_node_networks(container) # LXD Dependent
# if net_resources:
# node_dict[DICT_NET_LABEL] = net_resources[0]
# else:
# node_dict[DICT_NET_LABEL] = []
# # TODO support multiple networks
return node_dict
else:
# If container not running, skip
pass
except pylxd.exceptions.NotFound:
# If node not found, pass
pass
def get_all_nodes(self):
containers = self.client.containers.all()
containers_dict = dict()
# client.authenticate('bogus')
for c in containers:
if c.status == "Running":
containers_dict[c.name] = self.get_node_resources(c)
return containers_dict
Classes
class LXDContainerManager
-
Expand source code
class LXDContainerManager: def read_keys(self): # TODO Improve key handling self.LXD_CRT = '/${LXD_KEY_PATH}/${LXD_KEY_NAME}.crt' self.LXD_KEY = '/${LXD_KEY_PATH}/${LXD_KEY_NAME}.key' self.LXD_ENDPOINT = 'https://localhost:8443' def __init__(self): self.read_keys() # TODO Deal with error if key does not exist self.client = Client( endpoint=os.path.expandvars(self.LXD_ENDPOINT), cert=(os.path.expandvars(self.LXD_CRT), os.path.expandvars(self.LXD_KEY)), verify=False) def get_node_disks(self, container): devices = container.devices if not devices: return True, [] else: return cgroups_get_node_disks(container.name, devices) def get_node_networks(self, container): networks = container.state().network if not networks: return True, [] else: network_host_interfaces = list() for net in networks.keys(): if net == "lo": continue # Skip the internal loopback interface network_host_interfaces.append( {"container_interface": net, "host_interface": networks[net]["host_name"]}) return cgroups_get_node_networks(network_host_interfaces) def set_node_resources(self, node_name, resources): if resources is None: # No resources to set return False, {} else: try: container = self.client.containers.get(node_name) if container.status == "Running": node_dict = dict() (cpu_success, mem_success, disk_success, net_success) = (True, True, True, True) if DICT_CPU_LABEL in resources: cpu_success, cpu_resources = set_node_cpus(node_name, resources[DICT_CPU_LABEL]) node_dict[DICT_CPU_LABEL] = cpu_resources if DICT_MEM_LABEL in resources: mem_success, mem_resources = set_node_mem(node_name, resources[DICT_MEM_LABEL]) node_dict[DICT_MEM_LABEL] = mem_resources if DICT_DISK_LABEL in resources: disk_success, disk_resource = set_node_disk(node_name, resources[DICT_DISK_LABEL]) node_dict[DICT_DISK_LABEL] = disk_resource # disks_changed = list() # for disk in resources[DICT_DISK_LABEL]: # disk_success, disk_resource = set_node_disk(node_name, disk) # disks_changed.append(disk_resource) # node_dict[DICT_DISK_LABEL] = disks_changed if DICT_NET_LABEL in resources: net_success, net_resource = set_node_net(resources[DICT_NET_LABEL]) node_dict[DICT_NET_LABEL] = net_resource # networks_changed = list() # for net in resources[DICT_NET_LABEL]: # net_success, net_resource = set_node_net(net) # networks_changed.append(net_resource) # node_dict[DICT_NET_LABEL] = networks_changed global_success = cpu_success and mem_success and disk_success and net_success return global_success, node_dict else: # If container not running, skip return False, {} except pylxd.exceptions.NotFound: # If node not found, pass return False, {} def get_node_resources_by_name(self, container_name): container = self.client.containers.get(container_name) return self.get_node_resources(container) def get_node_resources(self, container): try: node_name = container.name if container.status == "Running": node_dict = dict() cpu_success, cpu_resources = get_node_cpus(node_name) node_dict[DICT_CPU_LABEL] = cpu_resources mem_success, mem_resources = get_node_mem(node_name) node_dict[DICT_MEM_LABEL] = mem_resources # disk_success, disk_resources = self.get_node_disks(container) # LXD Dependent # if type(disk_resources) == list and len(disk_resources) > 0: # node_dict[DICT_DISK_LABEL] = disk_resources[0] # elif disk_resources: # node_dict[DICT_DISK_LABEL] = disk_resources # else: # node_dict[DICT_DISK_LABEL] = [] # # TODO support multiple disks # # net_success, net_resources = self.get_node_networks(container) # LXD Dependent # if net_resources: # node_dict[DICT_NET_LABEL] = net_resources[0] # else: # node_dict[DICT_NET_LABEL] = [] # # TODO support multiple networks return node_dict else: # If container not running, skip pass except pylxd.exceptions.NotFound: # If node not found, pass pass def get_all_nodes(self): containers = self.client.containers.all() containers_dict = dict() # client.authenticate('bogus') for c in containers: if c.status == "Running": containers_dict[c.name] = self.get_node_resources(c) return containers_dict
Methods
def get_all_nodes(self)
-
Expand source code
def get_all_nodes(self): containers = self.client.containers.all() containers_dict = dict() # client.authenticate('bogus') for c in containers: if c.status == "Running": containers_dict[c.name] = self.get_node_resources(c) return containers_dict
def get_node_disks(self, container)
-
Expand source code
def get_node_disks(self, container): devices = container.devices if not devices: return True, [] else: return cgroups_get_node_disks(container.name, devices)
def get_node_networks(self, container)
-
Expand source code
def get_node_networks(self, container): networks = container.state().network if not networks: return True, [] else: network_host_interfaces = list() for net in networks.keys(): if net == "lo": continue # Skip the internal loopback interface network_host_interfaces.append( {"container_interface": net, "host_interface": networks[net]["host_name"]}) return cgroups_get_node_networks(network_host_interfaces)
def get_node_resources(self, container)
-
Expand source code
def get_node_resources(self, container): try: node_name = container.name if container.status == "Running": node_dict = dict() cpu_success, cpu_resources = get_node_cpus(node_name) node_dict[DICT_CPU_LABEL] = cpu_resources mem_success, mem_resources = get_node_mem(node_name) node_dict[DICT_MEM_LABEL] = mem_resources # disk_success, disk_resources = self.get_node_disks(container) # LXD Dependent # if type(disk_resources) == list and len(disk_resources) > 0: # node_dict[DICT_DISK_LABEL] = disk_resources[0] # elif disk_resources: # node_dict[DICT_DISK_LABEL] = disk_resources # else: # node_dict[DICT_DISK_LABEL] = [] # # TODO support multiple disks # # net_success, net_resources = self.get_node_networks(container) # LXD Dependent # if net_resources: # node_dict[DICT_NET_LABEL] = net_resources[0] # else: # node_dict[DICT_NET_LABEL] = [] # # TODO support multiple networks return node_dict else: # If container not running, skip pass except pylxd.exceptions.NotFound: # If node not found, pass pass
def get_node_resources_by_name(self, container_name)
-
Expand source code
def get_node_resources_by_name(self, container_name): container = self.client.containers.get(container_name) return self.get_node_resources(container)
def read_keys(self)
-
Expand source code
def read_keys(self): # TODO Improve key handling self.LXD_CRT = '/${LXD_KEY_PATH}/${LXD_KEY_NAME}.crt' self.LXD_KEY = '/${LXD_KEY_PATH}/${LXD_KEY_NAME}.key' self.LXD_ENDPOINT = 'https://localhost:8443'
def set_node_resources(self, node_name, resources)
-
Expand source code
def set_node_resources(self, node_name, resources): if resources is None: # No resources to set return False, {} else: try: container = self.client.containers.get(node_name) if container.status == "Running": node_dict = dict() (cpu_success, mem_success, disk_success, net_success) = (True, True, True, True) if DICT_CPU_LABEL in resources: cpu_success, cpu_resources = set_node_cpus(node_name, resources[DICT_CPU_LABEL]) node_dict[DICT_CPU_LABEL] = cpu_resources if DICT_MEM_LABEL in resources: mem_success, mem_resources = set_node_mem(node_name, resources[DICT_MEM_LABEL]) node_dict[DICT_MEM_LABEL] = mem_resources if DICT_DISK_LABEL in resources: disk_success, disk_resource = set_node_disk(node_name, resources[DICT_DISK_LABEL]) node_dict[DICT_DISK_LABEL] = disk_resource # disks_changed = list() # for disk in resources[DICT_DISK_LABEL]: # disk_success, disk_resource = set_node_disk(node_name, disk) # disks_changed.append(disk_resource) # node_dict[DICT_DISK_LABEL] = disks_changed if DICT_NET_LABEL in resources: net_success, net_resource = set_node_net(resources[DICT_NET_LABEL]) node_dict[DICT_NET_LABEL] = net_resource # networks_changed = list() # for net in resources[DICT_NET_LABEL]: # net_success, net_resource = set_node_net(net) # networks_changed.append(net_resource) # node_dict[DICT_NET_LABEL] = networks_changed global_success = cpu_success and mem_success and disk_success and net_success return global_success, node_dict else: # If container not running, skip return False, {} except pylxd.exceptions.NotFound: # If node not found, pass return False, {}