Commit 6aef1f9f authored by Swann Perarnau's avatar Swann Perarnau

[refactor] add method to check feature in manifest

The container creation code was starting to repeat the same logic for
testing that a container manifest was enabling a specific feature.

Instead we add a method to the image manifest to check for that.
Also adds tests for that feature.
parent 08badd4f
...@@ -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
...@@ -294,3 +299,23 @@ class ImageManifest(SpecField): ...@@ -294,3 +299,23 @@ 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
...@@ -62,7 +62,7 @@ class ContainerManager(object): ...@@ -62,7 +62,7 @@ class ContainerManager(object):
logger.error("Manifest is invalid") logger.error("Manifest is invalid")
return None return None
if hasattr(manifest.app.isolators, 'scheduler'): if manifest.is_feature_enabled('scheduler'):
sched = manifest.app.isolators.scheduler sched = manifest.app.isolators.scheduler
argv = self.chrt.getwrappedcmd(sched) argv = self.chrt.getwrappedcmd(sched)
else: else:
...@@ -106,33 +106,25 @@ class ContainerManager(object): ...@@ -106,33 +106,25 @@ class ContainerManager(object):
# argo-nodeos-config and not the final command -- that way it would # argo-nodeos-config and not the final command -- that way it would
# be running outside of the container. However, because # be running outside of the container. However, because
# argo-nodeos-config is suid root, perf can't monitor it. # argo-nodeos-config is suid root, perf can't monitor it.
if hasattr(manifest.app.isolators, 'perfwrapper'): if manifest.is_feature_enabled('perfwrapper'):
manifest_perfwrapper = manifest.app.isolators.perfwrapper argv.append(self.perfwrapper)
if hasattr(manifest_perfwrapper, 'enabled'):
if manifest_perfwrapper.enabled in ["1", "True"]: if manifest.is_feature_enabled('power'):
argv.append(self.perfwrapper) pp = manifest.app.isolators.power
if pp.profile in ["1", "True"]:
if hasattr(manifest.app.isolators, 'power'): container_power['profile'] = dict()
if hasattr(manifest.app.isolators.power, 'enabled'): container_power['profile']['start'] = dict()
pp = manifest.app.isolators.power container_power['profile']['end'] = dict()
if pp.enabled in ["1", "True"]: if pp.policy != "NONE":
if pp.profile in ["1", "True"]: container_power['policy'] = pp.policy
container_power['profile'] = dict() container_power['damper'] = pp.damper
container_power['profile']['start'] = dict() container_power['slowdown'] = pp.slowdown
container_power['profile']['end'] = dict()
if pp.policy != "NONE":
container_power['policy'] = pp.policy
container_power['damper'] = pp.damper
container_power['slowdown'] = pp.slowdown
# Compute hardware bindings # Compute hardware bindings
if hasattr(manifest.app.isolators, 'hwbind'): if manifest.is_feature_enabled('hwbind'):
manifest_hwbind = manifest.app.isolators.hwbind hwbindings['enabled'] = True
if hasattr(manifest_hwbind, 'enabled'): hwbindings['distrib'] = sorted(self.hwloc.distrib(
if manifest_hwbind.enabled in ["1", "True"]: ncpus, alloc), key=operator.
hwbindings['enabled'] = True
hwbindings['distrib'] = sorted(self.hwloc.distrib(
ncpus, alloc), key=operator.
attrgetter('cpus')) attrgetter('cpus'))
# build context to execute # build context to execute
......
"""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": []
}
}'''
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"] = [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"] = [isolator]
assert manifest.load_dict(data)
assert 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