Component Configuration
Configuration of the cobald.daemon
is performed at startup via one of two methods:
a YAML file or Python code.
While the former is more structured and easier to verify, the latter allows for greater freedom.
The configuration file is the only positional argument when launching the cobald.daemon
.
The file extension determines the type of configuration interface to use -
.py
for Python files and .yaml
for YAML files.
$ python3 -m cobald.daemon /etc/cobald/config.yaml
$ python3 -m cobald.daemon /etc/cobald/config.py
The YAML Interface
The top level of a YAML configuration file is a mapping with two sections:
the pipeline
section setting up a pool control pipeline,
and the logging
section setting up the logging facilities.
The logging
section is optional and follows the standard
configuration dictionary schema. [1]
The pipeline
section must contain a sequence of
Controller
s,
Decorator
s
and Pool
s.
Each pipeline
is constructed in reverse order:
the last element should be a Pool
and is constructed first,
then recursively passed to its predecessor for construction.
# pool becomes the target of the controller
pipeline:
- !LinearController
low_utilisation: 0.9
high_utilisation: 1.1
- !CpuPool
interval: 1
Object References
YAML configurations support !!
tag and !
constructor syntax.
These allow to use arbitrary Python objects and registered plugins, respectively.
Both support keyword and positional arguments.
# generic python tag for arbitrary objects
!!python/object:cobald.controller.linear.LinearController {low_utilisation: 0.9}
# constructor tag for registered plugin
!LinearController
low_utilisation: 0.9
Added in version 0.9.3.
Note
The YAML configuration is read using yaml.SafeLoader
to avoid arbitrary code execution.
Objects must be marked as safe for loading,
either as COBalD plugins
or using PyYAML directly.
A legacy format using explicit type references is available, but discouraged.
This uses an invocation mechanism that can use arbitrary callables to construct objects:
each mapping with a __type__
key is invoked with its items as keyword arguments,
and the optional __args__
as positional arguments.
pipeline:
# same as ``package.module.callable(a, b, keyword1="one", keyword2="two")
- __type__: package.module.callable
__args__:
- a
- b
keyword1: one
keyword2: two
Deprecated since version 0.9.3: Use YAML tags and constructors instead.
Python Code Inclusion
Python configuration files are loaded like regular modules.
This allows to define arbitrary types and functions, and directly chain components or configure logging.
At least one pipeline of Controller
s,
Decorator
s
and Pool
s should be instantiated.
from cobald.controller.linear import LinearController
from cobald_demo.cpu_pool import CpuPool
from cobald_demo.draw_line import DrawLineHook
pipeline = LinearController.s(
low_utilisation=0.9, high_allocation=1.1
) >> CpuPool()
As regular modules, Python configurations must explicitly import the components they use. In addition, everything not bound to a name will be garbage collected. This allows configurations to use temporary objects, e.g. reading from files or sockets, but means persistent objects (such as a pipeline) must be bound to a name.