Backup integrator

Weii Wang Publisher

Platform:

Ubuntu
24.04
Channel Revision Published Runs on
latest/edge 12 27 Nov 2025
Ubuntu 24.04
juju deploy backup-integrator --channel edge

charms.backup_integrator.v0.backup

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:

  • fileset
  • run-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
        ...


class BackupSpec

BackupSpec describes what and how to back up a charm unit.

Attributes

fileset
A list of absolute file or directory paths that need to be backed up.
run_before_backup
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.
run_after_backup
An optional absolute path to an executable that, if defined, will run after the backup operation completes.
run_before_restore
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.
run_after_restore
An optional absolute path to an executable that, if defined, will run after the restore operation completes.
model_config
The Pydantic model configuration.

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

charm

The provider charm instance.

relation_name

The name of the backup relation.

BackupProvider. get_backup_spec( self , relation )

Retrieve the backup spec for the given relation.

Arguments

relation

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

charm

The requirer charm instance.

relation_name

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

fileset

A list of absolute file or directory paths that need to be backed up.

run_before_backup

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.

run_after_backup

An optional absolute path to an executable that, if defined, will run after the backup operation completes.

run_before_restore

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.

run_after_restore

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

charm

The requirer charm instance.

fileset

A list of absolute file or directory paths that need to be backed up.

run_before_backup

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.

run_after_backup

An optional absolute path to an executable that, if defined, will run after the backup operation completes.

run_before_restore

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.

run_after_restore

An optional absolute path to an executable that, if defined, will run after the restore operation completes.

relation_name

The name of the backup relation.