Backup integrator
Platform:
| Channel | Revision | Published | Runs on |
|---|---|---|---|
| latest/edge | 12 | 27 Nov 2025 |
juju deploy backup-integrator --channel edge
charms.backup_integrator.v0.backup
-
- Last updated 17 Sep 2026
- Revision Library version 0.2
Library to manage the relation between backup providers and backup requirers.
Backup provider charms are charms that provide backup services, and
backup requirer charms are charms that have files on the unit that need
to be backed up. This library provides helper classes: BackupProvider
for backup provider charms, and BackupRequirer and
BackupDynamicRequirer for backup requirer charms.
Understanding the Backup Relation
On the requirer side, the backup relation contains five fields in the application databag that describe what to back up and how to perform the backup:
filesetrun-before-backup(optional)run-after-backup(optional)run-before-restore(optional)run-after-restore(optional)
The fileset field is a comma-separated list of files or directories
that the backup provider charm will back up.
The run-before-backup, run-after-backup, run-before-restore, and
run-after-restore fields are optional and point to absolute paths of
executable files on the requirer charm units. These executables can be
scripts such as Bash or Python scripts, provided they include an
appropriate shebang. If any of the fields are not provided, nothing will
be executed before or after the backup or restore process. For
run-before-backup and run-before-restore, if the scripts fail, the
backup or restore operation will be canceled. These scripts can be
useful for performing tasks such as preparing for a backup, automating a
restore, and so on.
The backup relation is designed for machine charms, and all the fields within
the relation, including fileset, run-before-backup, run-after-backup,
run-before-restore, and run-after-restore — point to files on the requirer
unit. To provide the backup relation, the provider charm must have a way to
access and execute those files on the requirer unit to perform the backup.
On the provider side, the backup relation contains no data.
Backup Requirer Charm Using the BackupRequirer Class
For most backup requirer charms, you should use the BackupRequirer
class. To use it, simply initialize the BackupRequirer class with the
appropriate arguments in the charm constructor. The input arguments (
fileset, run_before_backup, run_after_backup,
run_before_restore, run_after_restore) should ideally be hardcoded
rather than dynamically generated. The BackupRequirer will handle all
aspects of the backup relation.
class FooCharm(ops.CharmBase):
def __init__(self, *args: typing.Any):
super().__init__(*args)
src_dir = pathlib.Path(__file__).parent
self._requirer = BackupRequirer(
charm=self,
fileset=["/var/backups/foo"],
run_before_backup=src_dir / "run_before_backup.py",
run_after_backup=src_dir / "run_after_backup.py",
run_after_restore=src_dir / "run_after_restore.py",
)
Backup Requirer Charm Using the BackupDynamicRequirer Class
In some rare cases, the charm does not know the exact backup
specification at build time, for example, when the backup fileset depends on
charm configuration. In that case, you should use the
BackupDynamicRequirer class. To use it, initialize the
BackupDynamicRequirer class in the charm constructor. Unlike the
BackupRequirer class, the backup specification is not provided during
initialization. Instead, you must call
BackupDynamicRequirer.require_backup within an event handler to
provide the information dynamically. You can only call
BackupDynamicRequirer.require_backup on the leader unit. If
BackupDynamicRequirer.require_backup is run on a non-leader unit,
an ops.RelationDataAccessError will be raised.
class BarCharm(ops.CharmBase):
def __init__(self, *args: typing.Any):
super().__init__(*args)
self._requirer = BackupDynamicRequirer(charm=self)
self.framework.observe(
self.on.config_changed,
self._on_config_changed,
)
def _on_config_changed(self, _):
if not self.unit.is_leader():
return
fileset = [
file.strip()
for file in self.config.get("fileset").split(",")
if file.strip()
]
if not fileset:
self.unit.status = ops.WaitingStatus("waiting for fileset config")
return
self._requirer.require_backup(fileset=fileset)
Backup Provider Charm Using the BackupProvider Class
If you are creating a new backup provider charm, you should use the
BackupProvider class, which helps retrieve and validate the backup
specifications provided by backup requirer charms.
import ops
class ProviderCharm(ops.CharmBase):
def __init__(self, *args: typing.Any):
super().__init__(*args)
self._provider = BackupProvider(charm=self)
self.framework.observe(
self._provider.on.backup_required,
self._on_backup_required,
)
def _on_backup_required(self, event):
backup_spec = event.backup_spec
# do something with backup_spec
...
Index
class BackupSpec
BackupSpec describes what and how to back up a charm unit.
Attributes
Methods
BackupSpec. new( cls )
Description
Factory method for creating a new BackupSpec. None
class BackupRequiredEvent
Description
Backup is required from the backup requirer. None
Methods
BackupRequiredEvent. __init__( self , handle , relation , backup_spec: BackupSpec , app , unit )
Description
Initialize a BackupRequiredEvent. None
class BackupProviderEvents
Description
BackupProvider events. None
class BackupProvider
Description
Backup provider helper class. None
Methods
BackupProvider. __init__( self , charm )
Initialize the backup provider.
Arguments
The provider charm instance.
The name of the backup relation.
BackupProvider. get_backup_spec( self , relation )
Retrieve the backup spec for the given relation.
Arguments
The relation to get the backup spec from.
Returns
The backup spec.
class BackupDynamicRequirer
Description
Backup requirer helper class. None
Methods
BackupDynamicRequirer. __init__( self , charm , relation_name: str )
Initialize the backup requirer.
Arguments
The requirer charm instance.
The name of the backup relation.
BackupDynamicRequirer. require_backup( self , fileset , run_before_backup , run_after_backup , run_before_restore , run_after_restore )
Update the backup requirement in the relation data.
Arguments
A list of absolute file or directory paths that need to be backed up.
An optional absolute path to an executable that, if defined, will run before the backup operation. If this command fails, the backup operation will be canceled.
An optional absolute path to an executable that, if defined, will run after the backup operation completes.
An optional absolute path to an executable that, if defined, will run before the restore operation. If this command fails, the restore operation will be canceled.
An optional absolute path to an executable that, if defined, will run after the restore operation completes.
Description
This method must be called on a leader unit, if called on a non-leader unit,
an ops.RelationDataAccessError will be raised.
class BackupRequirer
Description
Backup requirer helper class. None
Methods
BackupRequirer. __init__( self , charm )
Initialize the backup requirer.
Arguments
The requirer charm instance.
A list of absolute file or directory paths that need to be backed up.
An optional absolute path to an executable that, if defined, will run before the backup operation. If this command fails, the backup operation will be canceled.
An optional absolute path to an executable that, if defined, will run after the backup operation completes.
An optional absolute path to an executable that, if defined, will run before the restore operation. If this command fails, the restore operation will be canceled.
An optional absolute path to an executable that, if defined, will run after the restore operation completes.
The name of the backup relation.