Skip to content

Add incremental backup and restore#1

Open
Chyenne8 wants to merge 32 commits into
masterfrom
incremental-backup-restore
Open

Add incremental backup and restore#1
Chyenne8 wants to merge 32 commits into
masterfrom
incremental-backup-restore

Conversation

@Chyenne8

Copy link
Copy Markdown
Owner

Summary

Implements full incremental backup/restore capability using GNU tar's --listed-incremental mechanism. Reduces backup time and storage for large Pulp deployments by only backing up changed files.

Backup Features

Add --incremental CLI parameter:

foremanctl backup /backups --incremental /backups/foreman-backup-TIMESTAMP

Implementation:

  • Modified tar commands to use --listed-incremental with .snar snapshot files
  • .config.snar tracks foremanctl state changes
  • .pulp.snar tracks Pulp content changes
  • Replaced community.general.archive with raw tar for --listed-incremental support
  • Copy .snar files from previous backup before tar runs
  • Validate previous backup exists and contains .snar files
  • Enhanced error messages suggest alternative backups when .snar missing
  • Metadata records: is_incremental, base_backup_dir, base_backup_timestamp

Error handling automation:

  • Scans parent directory for backups with .snar support
  • Lists available alternatives with type and timestamp
  • Provides ready-to-use command with suggested backup

Restore Features

Auto-detect incremental backups from metadata:

  • Parse metadata.yml to identify backup type
  • Display full vs incremental in validation output

Backup chain validation:

  • Verify base backup directory exists
  • Confirm base backup metadata matches expected timestamp
  • Check if base backup already restored via .last_restore_timestamp
  • Fail with clear instructions if chain incomplete

Add --chain for automatic chain restore:

foremanctl restore /backups/foreman-backup-TIMESTAMP --chain

Chain restore automation:

  • Recursively walks metadata to build full dependency chain
  • Restores backups in chronological order (full -> inc1 -> inc2)
  • Databases restored only from full backup
  • Incrementals apply file changes using --listed-incremental=/dev/null
  • Eliminates manual multi-step restore process

Handle .snar files during restore:

  • Detect .snar presence to identify incremental archives
  • Use tar --listed-incremental=/dev/null for extraction
  • Fall back to unarchive module for full backups

Usage Examples

Create full backup (generates .snar files):

foremanctl backup /backups

Create incremental backup:

foremanctl backup /backups --incremental /backups/foreman-backup-20260629T120000

Restore with auto-chain (recommended):

foremanctl restore /backups/foreman-backup-20260701T080000 --chain

Manual chain restore:

foremanctl restore /backups/foreman-backup-20260629T120000
foremanctl restore /backups/foreman-backup-20260630T080000 --force
foremanctl restore /backups/foreman-backup-20260701T080000 --force

Validate incremental backup:

foremanctl restore /backups/foreman-backup-TIMESTAMP --validate

Testing

Backup:

  • ✅ Full backup creates .config.snar and .pulp.snar files
  • ✅ Incremental backup significantly smaller than full
  • ✅ Error with suggestions when .snar files missing
  • ✅ Metadata correctly tracks incremental status

Restore:

  • ✅ Incremental detected from metadata
  • ✅ Chain validation prevents incomplete restores
  • --chain automatically handles dependencies
  • ✅ Clear errors for missing base backups

Files Modified

Backup:

  • src/playbooks/backup/metadata.obsah.yaml
  • src/roles/backup/tasks/main.yaml
  • src/roles/backup/tasks/pulp_content.yaml
  • src/roles/backup/tasks/metadata.yaml
  • docs/user/backup.md

Restore:

  • src/playbooks/restore/metadata.obsah.yaml
  • src/roles/restore/tasks/validate.yaml
  • src/roles/restore/tasks/main.yaml
  • src/roles/restore/tasks/restore_pulp_content.yaml
  • src/roles/restore/tasks/restore_foremanctl_state.yaml
  • src/roles/restore/tasks/restore_databases.yaml
  • src/roles/restore/tasks/restore_chain.yaml (new)
  • src/roles/restore/tasks/restore_chain_walk.yaml (new)
  • src/roles/restore/tasks/restore_single.yaml (new)
  • docs/user/restore.md

Stats

  • 15 files changed
  • 550 insertions
  • 24 deletions

evgeni and others added 30 commits June 8, 2026 07:42
Replace hardcoded quay.io image references with an iop_image fixture
that reads container_image and container_tag from each role's defaults,
keeping tests in sync with deployment configuration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds an Ansible lint rule to help ensure any future volume mounts
that are added follow this rule.
Standardize certificate directory from /root/certificates to
/var/lib/foremanctl/certs across IOP roles, variable files, and
documentation for consistency with the default certificate source.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Define a canonical `databases` list in database.yml with feature tags,
replacing scattered conditional enumeration across consumers. A computed
`all_databases` filters by enabled_features, and custom Jinja2 filters
derive postgresql_databases/postgresql_users from it — eliminating static
list duplication and the merge pre_tasks in deploy.yaml.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The development playbooks load src/vars/database.yml which now uses
custom filters (to_postgresql_databases, to_postgresql_users). Without
this path, playbooks run from the development directory fail with
"No filter named" errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The version published in the Hashicorp portal is broken, see
https://redhat.atlassian.net/browse/CS-3411 for details
The default and custom_server certificate vars files defined identical
paths since custom certificates are normalized into the same directory
structure during deployment. Remove the vars file indirection and use a
single certificates.yml for all certificate sources.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Guard CA generation with a stat check so existing CA artifacts are never
overwritten during deploy. Without this, the community.crypto modules
detect parameter mismatches (different subject, passphrase) against a
migrated CA and silently regenerate it, breaking certificate trust.

The CA generation block now only runs when ca.crt does not exist (fresh
install) or when certificates_renew_ca is explicitly set to true. Add
--certificate-renew-ca as a deploy parameter for explicit CA renewal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move foreman-installer certificate normalization into the migrate
subcommand so it runs once during migration rather than on every deploy.
The migrate_foreman_installer role copies certs from /root/ssl-build/
into /var/lib/foremanctl/certs/, persists the CA passphrase to a
dedicated file, and backs up the original directory.

Detect custom server certificates by comparing the internal CA with the
server CA. When they differ, persist certificates_source: custom_server
to prevent subsequent deploys from overwriting the custom server cert.

Remove the installer certificate source since migrated certs use the
default source paths after normalization. Mark certificate path
parameters as IGNORE in the answer file migration since the role handles
cert files directly.

Separate I/O from the migrate_answers module so it only transforms and
returns mapped parameters. The playbook handles writing to stdout,
output files, and the parameters file. Migration is preview-by-default
and requires --apply to perform changes.

Update integration tests to read control-node state files from
OBSAH_STATE rather than hardcoding paths or checking the remote server.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements comprehensive offline backup functionality for Foreman deployments:
- Backs up all databases (foreman, candlepin, pulp, 5 IOP DBs)
- Backs up podman secrets, networks, volumes, quadlet files
- Backs up systemd units and foremanctl state
- Includes metadata with container image digests for restore compatibility
- Preflight checks for running tasks and database integrity (amcheck)
- Automatic service restoration on failure

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements offline backup restore functionality with the following features:

Validation:
- Metadata-driven validation for different flavors
- Verifies backup directory structure and required files
- Validates database dumps and foremanctl state archive exist
- Supports dry-run mode to validate without restoring

Restore Process:
- Stops all Foreman services cleanly
- Restores databases using pg_restore with postgres user
- Fixes database ownership after restore
- Restores Pulp content and encryption keys
- Restores foremanctl state (OAuth keys, passwords, configuration)
- Integrates deploy roles to regenerate configuration
- Verifies services after deployment

Error Handling:
- Rescue block stops services on failure
- Leaves system in safe stopped state for investigation
- Provides clear recovery instructions

Implementation Details:
- Derives expected files from backup metadata instead of hardcoding
- Uses regex append for file list generation
- Removes state tracking variables for simplicity
- No debug messages per codebase patterns
- Explicit PostgreSQL stop to handle systemd dependencies

Documentation:
- Comprehensive user guide at docs/user/restore.md
- Covers usage, prerequisites, troubleshooting, and best practices
@Chyenne8 Chyenne8 force-pushed the incremental-backup-restore branch from 5ebe24f to 2ecaa0d Compare June 30, 2026 17:47
Implements full incremental backup/restore capability using GNU tar's
--listed-incremental mechanism. Reduces backup time and storage for large
Pulp deployments by only backing up changed files.

Backup features:

Add --incremental CLI parameter:
  foremanctl backup /backups --incremental /backups/foreman-backup-TIMESTAMP

Implementation:
- Modified tar commands to use --listed-incremental with .snar snapshot files
- .config.snar tracks foremanctl state changes
- .pulp.snar tracks Pulp content changes
- Replaced community.general.archive with raw tar for --listed-incremental support
- Copy .snar files from previous backup before tar runs
- Validate previous backup exists and contains .snar files
- Enhanced error messages suggest alternative backups when .snar missing
- Metadata records: is_incremental, base_backup_dir, base_backup_timestamp

Error handling automation:
- Scans parent directory for backups with .snar support
- Lists available alternatives with type and timestamp
- Provides ready-to-use command with suggested backup

Restore features:

Auto-detect incremental backups from metadata:
- Parse metadata.yml to identify backup type
- Display full vs incremental in validation output

Backup chain validation:
- Verify base backup directory exists
- Confirm base backup metadata matches expected timestamp
- Check if base backup already restored via .last_restore_timestamp
- Fail with clear instructions if chain incomplete

Add --restore-chain for automatic chain restore:
  foremanctl restore /backups/foreman-backup-TIMESTAMP --restore-chain

Chain restore automation:
- Recursively walks metadata to build full dependency chain
- Restores backups in chronological order (full -> inc1 -> inc2)
- Databases restored only from full backup
- Incrementals apply file changes using --listed-incremental=/dev/null
- Eliminates manual multi-step restore process

Handle .snar files during restore:
- Detect .snar presence to identify incremental archives
- Use tar --listed-incremental=/dev/null for extraction
- Fall back to unarchive module for full backups

Usage examples:

Create full backup (generates .snar files):
  foremanctl backup /backups

Create incremental backup:
  foremanctl backup /backups --incremental /backups/foreman-backup-20260629T120000

Restore with auto-chain (recommended):
  foremanctl restore /backups/foreman-backup-20260701T080000 --restore-chain

Manual chain restore:
  foremanctl restore /backups/foreman-backup-20260629T120000
  foremanctl restore /backups/foreman-backup-20260630T080000 --force
  foremanctl restore /backups/foreman-backup-20260701T080000 --force

Validate incremental backup:
  foremanctl restore /backups/foreman-backup-TIMESTAMP --validate

Testing:

Backup:
- Full backup creates .config.snar and .pulp.snar files
- Incremental backup significantly smaller than full
- Error with suggestions when .snar files missing
- Metadata correctly tracks incremental status

Restore:
- Incremental detected from metadata
- Chain validation prevents incomplete restores
- --restore-chain automatically handles dependencies
- Clear errors for missing base backups

Files modified:

Backup:
- src/playbooks/backup/metadata.obsah.yaml
- src/roles/backup/tasks/main.yaml
- src/roles/backup/tasks/pulp_content.yaml
- src/roles/backup/tasks/metadata.yaml
- docs/user/backup.md

Restore:
- src/playbooks/restore/metadata.obsah.yaml
- src/roles/restore/tasks/validate.yaml
- src/roles/restore/tasks/main.yaml
- src/roles/restore/tasks/restore_pulp_content.yaml
- src/roles/restore/tasks/restore_foremanctl_state.yaml
- src/roles/restore/tasks/restore_databases.yaml
- src/roles/restore/tasks/restore_chain.yaml (new)
- src/roles/restore/tasks/restore_chain_walk.yaml (new)
- src/roles/restore/tasks/restore_single.yaml (new)
- docs/user/restore.md
@Chyenne8 Chyenne8 force-pushed the incremental-backup-restore branch from 2ecaa0d to bd5f415 Compare June 30, 2026 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants