Commit fb396383 authored by Swann Perarnau's avatar Swann Perarnau

Merge branch 'refactor-container-management' into 'master'

Code refactoring in Container management

See merge request !54
parents 08badd4f e15360e4
Pipeline #5096 passed with stages
in 5 minutes and 51 seconds
......@@ -58,6 +58,7 @@ class Scheduler(SpecField):
fields = {"policy": spec(unicode, True),
"priority": spec(unicode, False),
"enabled": spec(unicode, False),
}
def __init__(self):
......@@ -78,6 +79,10 @@ class Scheduler(SpecField):
logger.warning("scheduler priority forced as 0 " +
"for non default policies")
self.priority = "0"
if getattr(self, "enabled", "1") not in ["0", "False", "1", "True"]:
logger.error("Invalid value for scheduler enabled: %s",
self.enabled)
return False
return True
......@@ -142,7 +147,7 @@ class PerfWrapper(SpecField):
ret = super(PerfWrapper, self).load(data)
if not ret:
return ret
if self.enabled not in ["0", "False", "1", "True"]:
if getattr(self, "enabled", "1") not in ["0", "False", "1", "True"]:
logger.error("Invalid value for perfwrapper enabled: %s",
self.enabled)
return False
......@@ -253,7 +258,9 @@ class IsolatorList(SpecField):
setattr(self, name.lstrip("argo/"), v)
for k in self.types:
if self.types[k].required:
assert name.lstrip("argo/") in self.__dict__
if not hasattr(self, k.lstrip("argo/")):
logger.error("Missing mandatory isolator: %s", k)
return False
return True
......@@ -294,3 +301,25 @@ class ImageManifest(SpecField):
with open(filename, 'r') as f:
data = json.load(f)
return super(ImageManifest, self).load(data)
def load_dict(self, data):
"""Load a manifest in dictionary form."""
return super(ImageManifest, self).load(data)
def is_feature_enabled(self, feature, true_values=["1", "True"]):
"""Check if a specific feature is enabled.
Since the enabled field itself is optional, we return true if an
isolator is present in a manifest or the enabled field is not true."""
typename = "argo/{}".format(feature)
assert typename in IsolatorList.types, \
"{} in not a valid feature".format(feature)
logger.debug(repr(self))
if hasattr(self.app.isolators, feature):
isolator = getattr(self.app.isolators, feature)
if hasattr(isolator, 'enabled'):
if isolator.enabled not in true_values:
return False
return True
else:
return False
......@@ -88,7 +88,7 @@ class ApplicationManager(object):
phase_contexts = dict()
phase_context_keys = ['set', 'aggregation', 'computetime', 'totaltime']
if container.power['policy']:
ids = container.resources['cpus']
ids = container.resources.cpus
for id in ids:
phase_contexts[id] = dict.fromkeys(phase_context_keys)
phase_contexts[id]['set'] = False
......
This diff is collapsed.
......@@ -126,7 +126,7 @@ class Controller(object):
def run_policy_container(self, container, application):
"""Run policies on a container."""
ids = container.resources['cpus']
ids = container.resources.cpus
pcs = application.phase_contexts
# Run policy only if all phase contexts have been received
if not filter(lambda i: not pcs[i]['set'], ids):
......
from __future__ import print_function
from applications import ApplicationManager
from containers import ContainerManager
from containers import ContainerManager, NodeOSRuntime
from controller import Controller, PowerActuator
from powerpolicy import PowerPolicyManager
from functools import partial
......@@ -85,6 +85,7 @@ class Daemon(object):
self.upstream_rpc_server.sendmsg(RPC_MSG['getpower'](**update),
client)
elif msg.type == 'run':
logger.info("asked to run a command in a container: %r", msg)
container_uuid = msg.container_uuid
params = {'manifest': msg.manifest,
'file': msg.path,
......@@ -98,7 +99,7 @@ class Daemon(object):
if len(container.processes) == 1:
if container.power['policy']:
container.power['manager'] = PowerPolicyManager(
container.resources['cpus'],
container.resources.cpus,
container.power['policy'],
float(container.power['damper']),
float(container.power['slowdown']))
......@@ -296,11 +297,13 @@ class Daemon(object):
# create managers
self.resource_manager = ResourceManager(hwloc=self.config.hwloc)
container_runtime = \
NodeOSRuntime(self.config.argo_nodeos_config)
self.container_manager = ContainerManager(
container_runtime,
self.resource_manager,
perfwrapper=self.config.argo_perf_wrapper,
linuxperf=self.config.perf,
argo_nodeos_config=self.config.argo_nodeos_config,
pmpi_lib=self.config.pmpi_lib,
)
self.application_manager = ApplicationManager()
......
"""Tests for the ACI Manifest module."""
import nrm
import nrm.aci
import pytest
import json
@pytest.fixture
def manifest_base_data():
data = '''{
"acKind": "ImageManifest",
"acVersion": "0.6.0",
"name": "test",
"app": {
"isolators": [
{
"name": "argo/container",
"value": {
"cpus": "1",
"mems": "1"
}
}
]
}
}'''
return json.loads(data)
def test_manifest_disabled_perfwrapper(manifest_base_data):
"""Ensure we can check if a feature is disabled."""
manifest = nrm.aci.ImageManifest()
isolator_text = '''{
"name": "argo/perfwrapper",
"value": {
"enabled": "0"
}
}'''
isolator = json.loads(isolator_text)
data = manifest_base_data
data["app"]["isolators"].append(isolator)
assert manifest.load_dict(data)
assert not manifest.is_feature_enabled("perfwrapper")
def test_enabled_feature(manifest_base_data):
"""Ensure we can check if a feature is enabled without enabled in it."""
manifest = nrm.aci.ImageManifest()
isolator_text = '''{
"name": "argo/perfwrapper",
"value": {}
}'''
isolator = json.loads(isolator_text)
data = manifest_base_data
data["app"]["isolators"].append(isolator)
assert manifest.load_dict(data)
assert manifest.is_feature_enabled("perfwrapper")
def test_missing_disabled(manifest_base_data):
"""Ensure that a missing feature doesn't appear enabled."""
manifest = nrm.aci.ImageManifest()
assert manifest.load_dict(manifest_base_data)
assert not manifest.is_feature_enabled("perfwrapper")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment