canonical / charmed-kubeflow-chisme

Shared Utilities used across Charmed Kubeflow
Apache License 2.0
1 stars 4 forks source link

Update `PebbleServiceComponent` to allow for empty returns of `get_layer` #74

Open ca-scribner opened 11 months ago

ca-scribner commented 11 months ago

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:

The 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 the update_layer code makes the assumption that we wrote everything in a single layer.

ca-scribner commented 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