Commit 8c80807d authored by Kirill Smelkov's avatar Kirill Smelkov

slapos/recipe/slapconfiguration: Propagate SR defaults to configuration dict

Currently in slapos / slapconfiguration-recipe we have 2 ways to access instance parameters:

    configuration dict,

and

    configuration.<key>

for every valid key in configuration dict.

An SR could also provide default value for a key, e.g. like helloworld
SR does for `name` parameter:

    https://lab.nexedi.com/nexedi/slapos/blob/3c552c05/software/helloworld/instance.cfg.in#L38

and if such parameter is not provided in instance parameters, the
default will be used...

... Though currently it only works for configuration.<key> way of
access: if a default value was provided by SR with

    configuration.key = ...

it will be available via `configuration.key`, but `configuration` dict
will not have `key` entry at all.

This looks non-consistent to me, so imho in addition to propagating

    configuration {} -> configuration.<key>

on parameters receive, we should also propagate

    configuration.<key> -> configuration {} defaults

so that at any time two pictures (configuration {} and set of
configuration.<key>) agree between each other.

NOTE The fix also works for slapconfiguration.serialised case, where we
    obtain parameters as { _ -> json } and json-decode them to python
    dict after receive.

    The reason it works is that we apply defaults after parameters
    decode, so e.g. the following

    # in SR
    configuration.name = John Doe

    # instance parameters
    _ = { "aaa": "bbb" }

    will result in the following `configuration` dict:

    { 'aaa': 'bbb', 'name': 'John Doe' }

/cc @vpelletier, @alain.takoudjou, @rafael, @Tyagov
parent dda79f36
...@@ -108,6 +108,12 @@ class Recipe(object): ...@@ -108,6 +108,12 @@ class Recipe(object):
OPTCRE_match = RawConfigParser.OPTCRE.match OPTCRE_match = RawConfigParser.OPTCRE.match
def __init__(self, buildout, name, options): def __init__(self, buildout, name, options):
# propagate configuration.<key> -> default configuration {}
parameter_default_dict = {}
for key, value in options.iteritems():
if key.startswith('configuration.'):
parameter_default_dict[key[len('configuration.'):]] = value
parameter_dict = self.fetch_parameter_dict(options, parameter_dict = self.fetch_parameter_dict(options,
buildout['buildout']['directory']) buildout['buildout']['directory'])
...@@ -116,6 +122,12 @@ class Recipe(object): ...@@ -116,6 +122,12 @@ class Recipe(object):
# If it is non-dict - we just store it as is; # If it is non-dict - we just store it as is;
# if it is dict - we process it further. # if it is dict - we process it further.
if isinstance(parameter_dict, dict): if isinstance(parameter_dict, dict):
# apply default parameters to parameter_dict
for key, value in parameter_default_dict.iteritems():
if key not in parameter_dict:
parameter_dict[key] = value
# propagate configuration {} -> configuration.<key>
match = self.OPTCRE_match match = self.OPTCRE_match
for key, value in parameter_dict.iteritems(): for key, value in parameter_dict.iteritems():
if match(key) is not None: if match(key) is not None:
......
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