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): ...@@ -58,6 +58,7 @@ class Scheduler(SpecField):
fields = {"policy": spec(unicode, True), fields = {"policy": spec(unicode, True),
"priority": spec(unicode, False), "priority": spec(unicode, False),
"enabled": spec(unicode, False),
} }
def __init__(self): def __init__(self):
...@@ -78,6 +79,10 @@ class Scheduler(SpecField): ...@@ -78,6 +79,10 @@ class Scheduler(SpecField):
logger.warning("scheduler priority forced as 0 " + logger.warning("scheduler priority forced as 0 " +
"for non default policies") "for non default policies")
self.priority = "0" 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 return True
...@@ -142,7 +147,7 @@ class PerfWrapper(SpecField): ...@@ -142,7 +147,7 @@ class PerfWrapper(SpecField):
ret = super(PerfWrapper, self).load(data) ret = super(PerfWrapper, self).load(data)
if not ret: if not ret:
return 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", logger.error("Invalid value for perfwrapper enabled: %s",
self.enabled) self.enabled)
return False return False
...@@ -253,7 +258,9 @@ class IsolatorList(SpecField): ...@@ -253,7 +258,9 @@ class IsolatorList(SpecField):
setattr(self, name.lstrip("argo/"), v) setattr(self, name.lstrip("argo/"), v)
for k in self.types: for k in self.types:
if self.types[k].required: 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 return True
...@@ -294,3 +301,25 @@ class ImageManifest(SpecField): ...@@ -294,3 +301,25 @@ class ImageManifest(SpecField):
with open(filename, 'r') as f: with open(filename, 'r') as f:
data = json.load(f) data = json.load(f)
return super(ImageManifest, self).load(data) 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): ...@@ -88,7 +88,7 @@ class ApplicationManager(object):
phase_contexts = dict() phase_contexts = dict()
phase_context_keys = ['set', 'aggregation', 'computetime', 'totaltime'] phase_context_keys = ['set', 'aggregation', 'computetime', 'totaltime']
if container.power['policy']: if container.power['policy']:
ids = container.resources['cpus'] ids = container.resources.cpus
for id in ids: for id in ids:
phase_contexts[id] = dict.fromkeys(phase_context_keys) phase_contexts[id] = dict.fromkeys(phase_context_keys)
phase_contexts[id]['set'] = False phase_contexts[id]['set'] = False
......
This diff is collapsed.
...@@ -126,7 +126,7 @@ class Controller(object): ...@@ -126,7 +126,7 @@ class Controller(object):
def run_policy_container(self, container, application): def run_policy_container(self, container, application):
"""Run policies on a container.""" """Run policies on a container."""
ids = container.resources['cpus'] ids = container.resources.cpus
pcs = application.phase_contexts pcs = application.phase_contexts
# Run policy only if all phase contexts have been received # Run policy only if all phase contexts have been received
if not filter(lambda i: not pcs[i]['set'], ids): if not filter(lambda i: not pcs[i]['set'], ids):
......
from __future__ import print_function from __future__ import print_function
from applications import ApplicationManager from applications import ApplicationManager
from containers import ContainerManager from containers import ContainerManager, NodeOSRuntime
from controller import Controller, PowerActuator from controller import Controller, PowerActuator
from powerpolicy import PowerPolicyManager from powerpolicy import PowerPolicyManager
from functools import partial from functools import partial
...@@ -85,6 +85,7 @@ class Daemon(object): ...@@ -85,6 +85,7 @@ class Daemon(object):
self.upstream_rpc_server.sendmsg(RPC_MSG['getpower'](**update), self.upstream_rpc_server.sendmsg(RPC_MSG['getpower'](**update),
client) client)
elif msg.type == 'run': elif msg.type == 'run':
logger.info("asked to run a command in a container: %r", msg)
container_uuid = msg.container_uuid container_uuid = msg.container_uuid
params = {'manifest': msg.manifest, params = {'manifest': msg.manifest,
'file': msg.path, 'file': msg.path,
...@@ -98,7 +99,7 @@ class Daemon(object): ...@@ -98,7 +99,7 @@ class Daemon(object):
if len(container.processes) == 1: if len(container.processes) == 1:
if container.power['policy']: if container.power['policy']:
container.power['manager'] = PowerPolicyManager( container.power['manager'] = PowerPolicyManager(
container.resources['cpus'], container.resources.cpus,
container.power['policy'], container.power['policy'],
float(container.power['damper']), float(container.power['damper']),
float(container.power['slowdown'])) float(container.power['slowdown']))
...@@ -296,12 +297,14 @@ class Daemon(object): ...@@ -296,12 +297,14 @@ class Daemon(object):
# create managers # create managers
self.resource_manager = ResourceManager(hwloc=self.config.hwloc) self.resource_manager = ResourceManager(hwloc=self.config.hwloc)
container_runtime = \
NodeOSRuntime(self.config.argo_nodeos_config)
self.container_manager = ContainerManager( self.container_manager = ContainerManager(
self.resource_manager, container_runtime,
perfwrapper=self.config.argo_perf_wrapper, self.resource_manager,
linuxperf=self.config.perf, perfwrapper=self.config.argo_perf_wrapper,
argo_nodeos_config=self.config.argo_nodeos_config, linuxperf=self.config.perf,
pmpi_lib=self.config.pmpi_lib, pmpi_lib=self.config.pmpi_lib,
) )
self.application_manager = ApplicationManager() self.application_manager = ApplicationManager()
self.sensor_manager = SensorManager() self.sensor_manager = SensorManager()
......
"""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