Skip to content

Commit

Permalink
fix: update the simple profile to avoid Container.can_connect (#1927)
Browse files Browse the repository at this point in the history
Using `Container.can_connect` as a guard for Pebble is a poor pattern,
because it introduces a race condition. We recommend that charms use the
"easier to ask forgiveness than permission" pattern by executing the
container calls and catching any errors that occur. This PR updates the
`simple` profile to use that pattern.

There are two other small changes:
* The message in the blocked status was intending to use an f-string,
but was just a regular string, so would have always shown the literal
text "{log_level}" rather than the value of that variable.
* `WaitingStatus` should be used when waiting on an integrated charm,
not the local charm. `MaintenanceStatus` is the correct class to use
when waiting on the local charm.
  • Loading branch information
tonyandrewmeyer authored Oct 10, 2024
1 parent d6f9d13 commit 71a2b6c
Showing 1 changed file with 8 additions and 8 deletions.
16 changes: 8 additions & 8 deletions charmcraft/templates/init-simple/src/charm.py.j2
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,18 @@ class {{ class_name }}(ops.CharmBase):
if log_level in VALID_LOG_LEVELS:
# The config is good, so update the configuration of the workload
container = self.unit.get_container("httpbin")
# Verify that we can connect to the Pebble API in the workload container
if container.can_connect():
# Push an updated layer with the new config
# Push an updated layer with the new config
try:
container.add_layer("httpbin", self._pebble_layer, combine=True)
container.replan()

logger.debug("Log level for gunicorn changed to '%s'", log_level)
self.unit.status = ops.ActiveStatus()
else:
except ops.pebble.ConnectionError:
# We were unable to connect to the Pebble API, so we defer this event
event.defer()
self.unit.status = ops.MaintenanceStatus("waiting for Pebble API")
event.defer()
return

logger.debug("Log level for gunicorn changed to '%s'", log_level)
self.unit.status = ops.ActiveStatus()
else:
# In this case, the config option is bad, so block the charm and notify the operator.
self.unit.status = ops.BlockedStatus(f"invalid log level: '{log_level}'")
Expand Down

0 comments on commit 71a2b6c

Please sign in to comment.