Merge ~sylvain-pineau/checkbox-ng:fix-1748371 into checkbox-ng:master

Proposed by Sylvain Pineau
Status: Merged
Approved by: Sylvain Pineau
Approved revision: 289c513e8a4e8cf29bd1fe2d5b649c80fc117130
Merged at revision: 7275e5675311b624e5911b374cc187379995f88d
Proposed branch: ~sylvain-pineau/checkbox-ng:fix-1748371
Merge into: checkbox-ng:master
Diff against target: 147 lines (+29/-2)
3 files modified
docs/units/template.rst (+8/-2)
plainbox/impl/session/assistant.py (+3/-0)
plainbox/impl/unit/unit.py (+18/-0)
Reviewer Review Type Date Requested Status
Maciej Kisielewski Approve
Sylvain Pineau (community) Needs Resubmitting
Review via email: mp+337988@code.launchpad.net

Description of the change

New parameter for jinja2 templated jobs (Nota: not only template units), the content of the checkbox config environment section.

Fixes the linked bug, to avoid job description with for example hardcoded <ap_name> where in config we set $AP_NAME.

To post a comment you must log in.
Revision history for this message
Maciej Kisielewski (kissiel) wrote :

I'm going to call for a better solution for the problem.
I really don't like passing the config through provider units.
Runtime configuration should not be a provider's property (logically it isn't). I understand the need for environment info to be present when instantiating templates, but I think we don't need to get providers involved in this dynamic process (providers are fairly static monsters).
What I would advocate doing instead is:
 - pass config to the code that does the instantiation (IDK how many steps in the callstack the config would have to be passed). or,
 - exposing the current config (or current SA instance) through a module interface, I'm doing something similar for the remote functionality, see remote.py: 75-87

review: Needs Fixing
Revision history for this message
Sylvain Pineau (sylvain-pineau) wrote :

New version using a class attribute to store the config rather than passing through provider objects. should be better in term of memory consumption IMHO.

review: Needs Resubmitting
Revision history for this message
Maciej Kisielewski (kissiel) wrote :

Great stuff, thanks! +1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/docs/units/template.rst b/docs/units/template.rst
index f16e314..5b31010 100644
--- a/docs/units/template.rst
+++ b/docs/units/template.rst
@@ -176,7 +176,13 @@ Plainbox populates the template parameter dictionary with some extra keys to aid
176``__index__``:176``__index__``:
177 If a template unit can result in N content jobs then this variable is equal to how many jobs have been created so far.177 If a template unit can result in N content jobs then this variable is equal to how many jobs have been created so far.
178178
179Following parameters are only available for ``template-engine``: ``jinja2``:
180
179``__system_env__``:181``__system_env__``:
180 When the plainbox encounters a template to render it will populate this variable with the executing shell's enviroment variables as ``os.environ``182 When checkbox encounters a template to render it will populate this variable with the executing shell's enviroment variables as ``os.environ``
183
184``__on_ubuntucore__``:
185 Helper function (boolean) checking if checkbox runs from on ubuntu core
181186
182 Available for ``template-engine``: ``jinja2``187``__checkbox_env__``:
188 Dictionary containing the checkbox config environment section
diff --git a/plainbox/impl/session/assistant.py b/plainbox/impl/session/assistant.py
index db60157..4836c8c 100644
--- a/plainbox/impl/session/assistant.py
+++ b/plainbox/impl/session/assistant.py
@@ -61,6 +61,7 @@ from plainbox.impl.session.restart import detect_restart_strategy
61from plainbox.impl.session.storage import SessionStorageRepository61from plainbox.impl.session.storage import SessionStorageRepository
62from plainbox.impl.transport import OAuthTransport62from plainbox.impl.transport import OAuthTransport
63from plainbox.impl.transport import TransportError63from plainbox.impl.transport import TransportError
64from plainbox.impl.unit.unit import Unit
64from plainbox.vendor import morris65from plainbox.vendor import morris
6566
66_logger = logging.getLogger("plainbox.session.assistant")67_logger = logging.getLogger("plainbox.session.assistant")
@@ -168,6 +169,7 @@ class SessionAssistant:
168 self._api_flags = api_flags169 self._api_flags = api_flags
169 self._repo = SessionStorageRepository()170 self._repo = SessionStorageRepository()
170 self._config = PlainBoxConfig().get()171 self._config = PlainBoxConfig().get()
172 Unit.config = self._config
171 self._execution_ctrl_list = None # None is "default"173 self._execution_ctrl_list = None # None is "default"
172 self._ctrl_setup_list = []174 self._ctrl_setup_list = []
173 # List of providers that were selected. This is buffered until a175 # List of providers that were selected. This is buffered until a
@@ -335,6 +337,7 @@ class SessionAssistant:
335 """337 """
336 UsageExpectation.of(self).enforce()338 UsageExpectation.of(self).enforce()
337 self._config = config339 self._config = config
340 Unit.config = config
338 # NOTE: We expect applications to call this at most once.341 # NOTE: We expect applications to call this at most once.
339 del UsageExpectation.of(self).allowed_calls[342 del UsageExpectation.of(self).allowed_calls[
340 self.use_alternate_configuration]343 self.use_alternate_configuration]
diff --git a/plainbox/impl/unit/unit.py b/plainbox/impl/unit/unit.py
index ec1cd55..cd7b365 100644
--- a/plainbox/impl/unit/unit.py
+++ b/plainbox/impl/unit/unit.py
@@ -36,6 +36,7 @@ from jinja2 import Template
36from plainbox.i18n import gettext as _36from plainbox.i18n import gettext as _
37from plainbox.impl.decorators import cached_property37from plainbox.impl.decorators import cached_property
38from plainbox.impl.decorators import instance_method_lru_cache38from plainbox.impl.decorators import instance_method_lru_cache
39from plainbox.impl.secure.config import Unset
39from plainbox.impl.secure.origin import Origin40from plainbox.impl.secure.origin import Origin
40from plainbox.impl.secure.rfc822 import normalize_rfc822_value41from plainbox.impl.secure.rfc822 import normalize_rfc822_value
41from plainbox.impl.symbol import Symbol42from plainbox.impl.symbol import Symbol
@@ -380,6 +381,8 @@ class Unit(metaclass=UnitType):
380 class.381 class.
381 """382 """
382383
384 config = None
385
383 def __init__(self, data, raw_data=None, origin=None, provider=None,386 def __init__(self, data, raw_data=None, origin=None, provider=None,
384 parameters=None, field_offset_map=None, virtual=False):387 parameters=None, field_offset_map=None, virtual=False):
385 """388 """
@@ -605,6 +608,13 @@ class Unit(metaclass=UnitType):
605 field_offset_map=record.field_offset_map)608 field_offset_map=record.field_offset_map)
606609
607 @instance_method_lru_cache(maxsize=None)610 @instance_method_lru_cache(maxsize=None)
611 def _checkbox_env(self):
612 if self.config is not None and self.config.environment is not Unset:
613 return self.config.environment
614 else:
615 return {}
616
617 @instance_method_lru_cache(maxsize=None)
608 def get_record_value(self, name, default=None):618 def get_record_value(self, name, default=None):
609 """619 """
610 Obtain the normalized value of the specified record attribute620 Obtain the normalized value of the specified record attribute
@@ -628,6 +638,7 @@ class Unit(metaclass=UnitType):
628 # template instantiation we avoid problems with creation of638 # template instantiation we avoid problems with creation of
629 # checkpoints639 # checkpoints
630 tmp_params = self.parameters.copy()640 tmp_params = self.parameters.copy()
641 tmp_params.update({'__checkbox_env__': self._checkbox_env()})
631 tmp_params.update({'__system_env__': os.environ})642 tmp_params.update({'__system_env__': os.environ})
632 tmp_params.update({'__on_ubuntucore__': on_ubuntucore()})643 tmp_params.update({'__on_ubuntucore__': on_ubuntucore()})
633 value = Template(value).render(tmp_params)644 value = Template(value).render(tmp_params)
@@ -640,6 +651,7 @@ class Unit(metaclass=UnitType):
640 elif (value is not None and self.template_engine == 'jinja2'651 elif (value is not None and self.template_engine == 'jinja2'
641 and not self.is_parametric):652 and not self.is_parametric):
642 tmp_params = {653 tmp_params = {
654 '__checkbox_env__': self._checkbox_env(),
643 '__system_env__': os.environ,655 '__system_env__': os.environ,
644 '__on_ubuntucore__': on_ubuntucore()656 '__on_ubuntucore__': on_ubuntucore()
645 }657 }
@@ -669,6 +681,7 @@ class Unit(metaclass=UnitType):
669 if value is not None and self.is_parametric:681 if value is not None and self.is_parametric:
670 if self.template_engine == 'jinja2':682 if self.template_engine == 'jinja2':
671 tmp_params = self.parameters.copy()683 tmp_params = self.parameters.copy()
684 tmp_params.update({'__checkbox_env__': self._checkbox_env()})
672 tmp_params.update({'__system_env__': os.environ})685 tmp_params.update({'__system_env__': os.environ})
673 tmp_params.update({'__on_ubuntucore__': on_ubuntucore()})686 tmp_params.update({'__on_ubuntucore__': on_ubuntucore()})
674 value = Template(value).render(tmp_params)687 value = Template(value).render(tmp_params)
@@ -677,6 +690,7 @@ class Unit(metaclass=UnitType):
677 elif (value is not None and self.template_engine == 'jinja2'690 elif (value is not None and self.template_engine == 'jinja2'
678 and not self.is_parametric):691 and not self.is_parametric):
679 tmp_params = {692 tmp_params = {
693 '__checkbox_env__': self._checkbox_env(),
680 '__system_env__': os.environ,694 '__system_env__': os.environ,
681 '__on_ubuntucore__': on_ubuntucore()695 '__on_ubuntucore__': on_ubuntucore()
682 }696 }
@@ -722,6 +736,7 @@ class Unit(metaclass=UnitType):
722 # of the problem?736 # of the problem?
723 if self.template_engine == 'jinja2':737 if self.template_engine == 'jinja2':
724 tmp_params = self.parameters.copy()738 tmp_params = self.parameters.copy()
739 tmp_params.update({'__checkbox_env__': self._checkbox_env()})
725 tmp_params.update({'__system_env__': os.environ})740 tmp_params.update({'__system_env__': os.environ})
726 tmp_params.update({'__on_ubuntucore__': on_ubuntucore()})741 tmp_params.update({'__on_ubuntucore__': on_ubuntucore()})
727 msgstr = Template(msgstr).render(tmp_params)742 msgstr = Template(msgstr).render(tmp_params)
@@ -730,6 +745,7 @@ class Unit(metaclass=UnitType):
730 msgstr, (), self.parameters)745 msgstr, (), self.parameters)
731 elif self.template_engine == 'jinja2':746 elif self.template_engine == 'jinja2':
732 tmp_params = {747 tmp_params = {
748 '__checkbox_env__': self._checkbox_env(),
733 '__system_env__': os.environ,749 '__system_env__': os.environ,
734 '__on_ubuntucore__': on_ubuntucore()750 '__on_ubuntucore__': on_ubuntucore()
735 }751 }
@@ -744,6 +760,7 @@ class Unit(metaclass=UnitType):
744 if self.is_parametric:760 if self.is_parametric:
745 if self.template_engine == 'jinja2':761 if self.template_engine == 'jinja2':
746 tmp_params = self.parameters.copy()762 tmp_params = self.parameters.copy()
763 tmp_params.update({'__checkbox_env__': self._checkbox_env()})
747 tmp_params.update({'__system_env__': os.environ})764 tmp_params.update({'__system_env__': os.environ})
748 tmp_params.update({'__on_ubuntucore__': on_ubuntucore()})765 tmp_params.update({'__on_ubuntucore__': on_ubuntucore()})
749 msgstr = Template(msgstr).render(tmp_params)766 msgstr = Template(msgstr).render(tmp_params)
@@ -752,6 +769,7 @@ class Unit(metaclass=UnitType):
752 msgstr, (), self.parameters)769 msgstr, (), self.parameters)
753 elif self.template_engine == 'jinja2':770 elif self.template_engine == 'jinja2':
754 tmp_params = {771 tmp_params = {
772 '__checkbox_env__': self._checkbox_env(),
755 '__system_env__': os.environ,773 '__system_env__': os.environ,
756 '__on_ubuntucore__': on_ubuntucore()774 '__on_ubuntucore__': on_ubuntucore()
757 }775 }

Subscribers

People subscribed via source and target branches