Open ca-scribner opened 11 months ago
To implement this, we'd need something like:
# Note: get_layer is no longer decorated with @abstractmethod, so that someone doesn't need to subclass things at all
def get_layer(self) -> List[Layer]:
"""Pebble configuration layer for the container.
Override this method with your own layer configuration.
"""
return []
def _update_layer(self):
"""Updates the Pebble layer for this component, re-planning the services afterward."""
container = self._charm.unit.get_container(self.container_name)
new_layers = self.get_layer()
# For backward compatibility, handle when self.get_layer() returns a single Layer
if not isinstance(new_layers, Iterable):
new_layers = [new_layers]
original_plan = container.get_plan()
for new_layer in new_layers:
container.add_layer(new_layer)
if original_plan.services != container.get_plan():
container.replan()
where we handle the old version of get_layer()
returning a single layer, and loop through the layers then decide at the end of a replan is needed
Sometimes we may run pebble containers that have their own services/environment, etc, set up and do not need us to change anything. Currently, the
PebbleServiceComponent
would not handle this properly as:get_layer()
is an abstract method that must be implementedget_layer()
and the tools that use it (_update_layer()
,get_services_not_active()
), were not written the a null return in mindThe current workaround is to define everything in
get_layer()
, even if you didn't need to change anything.It is not valid to return an empty layer from
get_layer()
because theupdate_layer
code makes the assumption that we wrote everything in a single layer.