This commit is contained in:
Cecilie 2025-09-30 19:57:28 +05:30 committed by GitHub
commit 39311ec34e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 817 additions and 0 deletions

View File

@ -0,0 +1,107 @@
# Harbor Backup and Restore Scripts (Contrib)
**Warning:** These scripts are provided as-is in the `contrib/backup-restore` directory. They are not officially maintained or supported by the Harbor project. Use them at your own risk and ensure you understand their functionality before running them in a production environment.
These scripts (`harbor-backup` and `harbor-restore`) are provided as a convenience for backing up and restoring your Harbor instance. They aim to back up the following components:
* Harbor Database (PostgreSQL)
* Container Registry Data
* Chart Museum Data (if enabled)
* Redis Data (if enabled)
* Secret Keys
* Harbor Configuration (`harbor.yml`)
### Features
Compared to the scripts the harbor project used to have in their repo this set of scripts is more robust in its error handling and also offers features
for not packing the backup into a tarball. This makes it easy to rsync the whole backup directory to a secondary/standby node and restore there.
rsync is used extensively by the script. by leaving the files in the backup directory between runs the downtime for backup is greatly reduced at the
expense of disk space usage.
Supports logging of status messages directly to syslog
## Prerequisites
* **Docker:** These scripts rely on the `docker` command-line interface to interact with Harbor's containers. Ensure Docker is installed and accessible on the machine where you run these scripts.
* **Sufficient Permissions:** You'll need appropriate permissions (e.g., `sudo` or being in the `docker` group) to run Docker commands and perform file system operations.
* **Stopped Harbor Instance:** You must stop your Harbor instance completely before running the `harbor-backup` or `harbor-restore` script to avoid data inconsistencies.
## Usage
### Backup (`harbor-backup`)
1. **Download the Scripts:** Place the `harbor-backup` script in a location accessible from your Harbor instance. Within the Harbor repository, this would typically be under `contrib/backup-restore/`.
2. **Make it Executable:**
```bash
chmod +x harbor-backup
```
3. **Run the Backup Script:**
```bash
./harbor-backup [OPTIONS]
```
3. **Stop Harbor:** Ensure your Harbor instance is completely stopped before proceeding with the backup.
4. **Options:**
* `--docker-cmd <command>`: Specify the Docker command to use (default: `docker`).
* `--db-image <image>`: Specify the Harbor database image to use for the temporary backup container (default: auto-detected). It's generally recommended to let it auto-detect.
* `--db-path <path>`: Harbor DB data path (default: `/data/database`). Adjust if your deployment uses a different path.
* `--registry-path <path>`: Registry data path (default: `/data/registry`). Adjust if your deployment uses a different path.
* `--chart-museum-path <path>`: Chart Museum data path (default: `/data/chart_storage`). Adjust if your deployment uses a different path.
* `--redis-path <path>`: Redis data path (default: `/data/redis`). Adjust if your deployment uses a different path.
* `--secret-path <path>`: Secret data path (default: `/data/secret`). Adjust if your deployment uses a different path.
* `--config-path <path>`: Harbor configuration file path (default: `/etc/harbor/harbor.yml`). Adjust if your deployment uses a different path.
* `--backup-dir <path>`: Directory where the backup will be stored (default: `harbor_backup`).
* `--no-archive`: Do not create a `tar.gz` archive of the backup directory. The backup will remain as a directory structure in `$BACKUP_DIR/harbor`.
* `--use-syslog`: Use syslog for logging output.
* `--log-level <level>`: Set the logging level (default: `INFO`, options: `DEBUG`, `INFO`, `NOTICE`, `WARNING`, `ERROR`, `CRITICAL`, `ALERT`, `EMERGENCY`).
* `--help`: Display this help message.
5. **Backup Location:** By default, the backup will be created in a directory named `harbor_backup` in the current working directory. If the `--no-archive` option is not used, the final backup will be a compressed tarball named `harbor_backup.tar.gz` within the `harbor_backup` directory.
### Restore (`harbor-restore`)
1. **Download the Scripts:** Place the `harbor-restore` script in a location accessible from your Harbor instance. Within the Harbor repository, this would typically be under `contrib/backup-restore/`.
2. **Make it Executable:**
```bash
chmod +x harbor-restore
```
3. **Stop Harbor:** Ensure your Harbor instance is completely stopped before proceeding with the restore.
4. **Run the Restore Script:**
```bash
./harbor-restore [OPTIONS]
```
5. **Options:** The restore script accepts similar options to the backup script, allowing you to specify the Docker command, database image, data paths, and the backup directory.
* `--backup-dir <path>`: **Crucially**, this should point to the directory containing your Harbor backup (either the `harbor` subdirectory extracted from the tarball or the `harbor_backup` directory if `--no-archive` was used).
* `--no-archive`: Use this option if your backup is already extracted into the `$BACKUP_DIR/harbor` directory. If your backup is a `tar.gz` file, **do not** use this option; the script will attempt to extract it.
*(Other options like `--docker-cmd`, `--db-image`, `--db-path`, `--registry-path`, `--chart-museum-path`, `--redis-path`, `--secret-path`, `--config-path`, `--use-syslog`, and `--log-level` function similarly to the backup script.)*
6. **Restore Process:** The script will:
* Start a temporary database container.
* Extract the backup archive (if not using `--no-archive`).
* Drop and recreate existing Harbor databases.
* Restore the database content from the backed-up SQL files.
* Synchronize the registry, chart museum, Redis, and secret data directories.
* Restore the Harbor configuration file.
* Clean up the temporary database container.
7. **Restart Harbor:** Once the restore script completes successfully, you can restart your Harbor instance.
## Important Notes
* **Backup Consistency:** For a consistent backup, it's recommended to stop your Harbor instance or at least ensure minimal write activity during the backup process.
* **Database Image Tag:** In production environments, it's advisable to use a specific tag for the `--db-image` option in both the backup and restore scripts to ensure consistency.
* **Custom Deployments:** If you have a highly customized Harbor deployment with data stored in non-default locations, you **must** use the appropriate command-line options to point the scripts to the correct paths.
* **Testing:** Always test the backup and restore process in a non-production environment before relying on it for critical data.
* **Unsupported:** Remember that these scripts are provided in the `contrib/backup-restore/` directory. They may not be actively maintained, and you might encounter issues. Contributions and improvements from the community are welcome.
## Contributing
If you find issues or have improvements to these scripts, feel free to submit pull requests to the Harbor project in the `contrib/backup-restore/` directory.

View File

@ -0,0 +1,375 @@
#!/bin/bash
#
# Harbor Backup Script
#
# Default values
DOCKER_CMD="docker"
HARBOR_DB_IMAGE="$(docker images goharbor/harbor-db --format "{{.Repository}}:{{.Tag}}" | head -1)"
HARBOR_DB_PATH="/data/database"
REGISTRY_DATA_PATH="/data/registry"
CHART_MUSEUM_PATH="/data/chart_storage"
REDIS_DATA_PATH="/data/redis"
SECRET_PATH="/data/secret"
BACKUP_DIR="harbor_backup"
BACKUP_FILE="harbor_backup.tar.gz"
HARBOR_YML="/etc/harbor/harbor.yml"
# Default log level (can be overridden by environment variable)
LOG_LEVEL="INFO"
# Whether to syslog (can be overridden by environment variable)
USE_SYSLOG=false
POSTGRES_UID=999
POSTGRES_GID=999
# Log levels (syslog-compatible)
declare -A LOG_LEVELS=(
[DEBUG]=7
[INFO]=6
[NOTICE]=5
[WARNING]=4
[ERROR]=3
[CRITICAL]=2
[ALERT]=1
[EMERGENCY]=0
)
usage() {
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Backs up a Harbor instance."
echo ""
echo "Options:"
echo " --docker-cmd <command> Docker command (default: docker)"
echo " --db-image <image> Harbor DB image (default: auto-detected)"
echo " --db-path <path> Harbor DB data path (default: /data/database)"
echo " --registry-path <path> Registry data path (default: /data/registry)"
echo " --chart-museum-path <path> Chart Museum data path (default: /data/chart_storage)"
echo " --redis-path <path> Redis data path (default: /data/redis)"
echo " --secret-path <path> Secret data path (default: /data/secret)"
echo " --config-path <path> Harbor configuration file path (default: /etc/harbor/harbor.yml)"
echo " --backup-dir <path> Backup directory (default: harbor_backup)"
echo " --no-archive Do not create a tarball"
echo " --use-syslog Use syslog for logging"
echo " --log-level <level> Log level (default: INFO, options: DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY)"
echo " --help Display this help message"
exit 0
}
# exit immediately if any command fails, an unset variable is used, or a pipe fails
set -euo pipefail
# Parse command-line arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--docker-cmd)
DOCKER_CMD="$2"
shift 2
;;
--db-image)
HARBOR_DB_IMAGE="$2"
shift 2
;;
--db-path)
HARBOR_DB_PATH="$2"
shift 2
;;
--registry-path)
REGISTRY_DATA_PATH="$2"
shift 2
;;
--chart-museum-path)
CHART_MUSEUM_PATH="$2"
shift 2
;;
--redis-path)
REDIS_DATA_PATH="$2"
shift 2
;;
--secret-path)
SECRET_PATH="$2"
shift 2
;;
--config-path)
HARBOR_YML="$2"
shift 2
;;
--backup-dir)
BACKUP_DIR="$2"
shift 2
;;
--no-archive)
NO_ARCHIVE=true
shift
;;
--use-syslog)
USE_SYSLOG=true
shift
;;
--log-level)
LOG_LEVEL="$2"
shift 2
;;
--help)
usage
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
# log() will prepend datetime and log the message to stderr and optionally to syslog
# if the optional log level (defaults to INFO) is equal to higher than
# $LOG_LEVEL
log() {
local level
local message
if [[ $# -eq 1 ]]; then # Check if only one argument is provided
level="INFO" # Default level if not provided
message="$1"
elif [[ $# -eq 2 ]]; then # Check if two arguments are provided
level="$1"
message="$2"
else
echo "Usage: log [LEVEL] MESSAGE" >&2
return 1 # Return error code
fi
# Check if logging level is valid
if [[ ! "${LOG_LEVELS[$level]+_}" ]]; then
echo "Invalid log level: $level" >&2 # Log error to stderr
level="INFO" # Fallback to INFO
fi
# Check minimum log level
if (( ${LOG_LEVELS[$level]} > ${LOG_LEVELS[$LOG_LEVEL]} )); then
return # Don't log if below the threshold
fi
local formatted_message="[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message"
echo "$formatted_message"
if [[ "$USE_SYSLOG" == "true" ]]; then
local syslog_priority="local0.${level,,}" # Convert level to lowercase for syslog
logger -t "harbor-backup" -p "$syslog_priority" "$message"
fi
}
# Launch and wait for database
launch_db() {
if [ -n "$($DOCKER_CMD ps -q)" ]; then
log CRITICAL "There are running containers, please stop and remove before backup"
exit 1
fi
log "Starting database container for backup"
docker run -d --name harbor-db -v "${BACKUP_DIR}":/backup -v "${HARBOR_DB_PATH}":/var/lib/postgresql/data "${HARBOR_DB_IMAGE}" "postgres"
wait_for_db_ready
}
# Wait for database to be ready
wait_for_db_ready() {
TIMEOUT=12
set +e
while [ $TIMEOUT -gt 0 ]; do
docker exec harbor-db pg_isready | grep "accepting connections"
if [ $? -eq 0 ]; then
break
fi
TIMEOUT=$((TIMEOUT - 1))
sleep 5
done
set -e
if [ $TIMEOUT -eq 0 ]; then
log CRITICAL "Harbor DB cannot reach within one minute."
exit 1
fi
}
# Dump databases
dump_database() {
log "Backing up databases"
# Get list of databases
databases=$(docker exec harbor-db psql -t -c "SELECT datname FROM pg_database WHERE datistemplate = false;")
if [[ -z "$databases" ]]; then
log WARNING "No user databases found to backup."
return 0 # Return success if no user databases are found
fi
for db in $databases; do
log "- $db"
dump_file="${BACKUP_DIR}/harbor/db/${db}.sql"
local pg_dump_error=$(${DOCKER_CMD} exec harbor-db bash -c "( pg_dump -U postgres ${db} || echo Exit: \$? >&2 ) 2>&1 > ${dump_file}" )
local pg_dump_status="${pg_dump_error##*$'\n'}"
if [[ "$pg_dump_status" =~ Exit:[[:space:]]*[1-9][0-9]* ]] ; then
log ERROR "Failed to backup database $db: $pg_dump_error"
exit 1
fi
done
}
# Backup registry data
backup_registry() {
log "Backing up registry data"
if ! rsync -a --delete "${REGISTRY_DATA_PATH}/" "${BACKUP_DIR}/harbor/registry/"; then
log ERROR "Failed to backup registry data using rsync"
exit 1
fi
}
# Backup chart museum data
backup_chart_museum() {
if [ -d "${CHART_MUSEUM_PATH}" ]; then
log WARNING "Deprecated feature detected - Backing up chartmuseum data"
if ! rsync -a --delete "${CHART_MUSEUM_PATH}/" "${BACKUP_DIR}/harbor/chart_storage/"; then
log ERROR "Failed to backup chartmuseum data using rsync"
exit 1
fi
fi
}
# Backup redis data
backup_redis() {
if [ -d "${REDIS_DATA_PATH}" ]; then
log "Backing up redis"
if ! rsync -a --delete "${REDIS_DATA_PATH}/" "${BACKUP_DIR}/harbor/redis/"; then
log ERROR "Failed to backup redis data using rsync"
exit 1
fi
else
log "Not backing up redis ${REDIS_DATA_PATH} not found"
fi
}
# Backup secrets
backup_secret() {
# Pre 1.8
OLD_SECRET_PATH=`basename "${SECRET_PATH}"`
if [ -f "${OLD_SECRET_PATH}/secretkey" ]; then
log INFO "Backing up secretkey (pre 1.8)"
if ! cp "${OLD_SECRET_PATH}/secretkey" "${BACKUP_DIR}/harbor/secret/"; then
log ERROR "Failed to backup secretkey"
exit 1
fi
fi
if [ -f "${OLD_SECRET_PATH}/defaultalias" ]; then
log INFO "Backing up defaultalias (pre 1.8)"
if ! cp "${OLD_SECRET_PATH}/defaultalias" "${BACKUP_DIR}/harbor/secret/"; then
log ERROR "Failed to backup defaultalias"
exit 1
fi
fi
# 1.8 and later (Using rsync for directory)
if [ -d "${SECRET_PATH}" ]; then
log INFO "Backing up secrets (1.8+)"
if ! rsync -a --delete "${SECRET_PATH}/" "${BACKUP_DIR}/harbor/secret/"; then
log ERROR "Failed to backup secrets"
exit 1
fi
fi
}
# Backup config
backup_config() {
if [ -f "${HARBOR_YML}" ]; then
log "Backing up configuration file"
cp "${HARBOR_YML}" "${BACKUP_DIR}/harbor/"
else
log "Not backing up configuration file (${HARBOR_YML} not found)"
fi
}
# Clean up database container
clean_db() {
log "Clean up temporary database container for backup"
docker stop harbor-db
docker rm harbor-db
}
# Create tar archive
create_tarball() {
if [ -z "${NO_ARCHIVE}" ]; then
log "Creating tarball ${BACKUP_DIR}/${BACKUP_FILE}"
cd "${BACKUP_DIR}"
tar -czvf --remove-files "${BACKUP_DIR}/${BACKUP_FILE}" harbor
rm -rf harbor
else
log "Not creating tarball"
fi
}
create_backup_dir(){
if [[ -e "${BACKUP_DIR}/harbor/db" ]] ; then
log "Removing existing db backup directory ${BACKUP_DIR}/harbor/db"
rm -rf "${BACKUP_DIR}/harbor/db"
fi
log "Setting correct ownership and permissions"
mkdir -p "${BACKUP_DIR}/harbor/db"
mkdir -p "${BACKUP_DIR}/harbor/registry"
mkdir -p "${BACKUP_DIR}/harbor/chart_storage"
mkdir -p "${BACKUP_DIR}/harbor/redis"
mkdir -p "${BACKUP_DIR}/harbor/secret"
chown "${POSTGRES_UID}:${POSTGRES_GID}" "${BACKUP_DIR}/harbor/db"
chown 0:0 "${BACKUP_DIR}/harbor/secret"
chown 0:0 "${BACKUP_DIR}/harbor/registry"
chown 0:0 "${BACKUP_DIR}/harbor/chart_storage"
chown 0:0 "${BACKUP_DIR}/harbor/redis"
chown 0:0 "${BACKUP_DIR}/harbor"
chmod 700 "${BACKUP_DIR}/harbor/db"
chmod 700 "${BACKUP_DIR}/harbor/secret"
chmod 755 "${BACKUP_DIR}/harbor/registry"
chmod 755 "${BACKUP_DIR}/harbor/chart_storage"
chmod 755 "${BACKUP_DIR}/harbor/redis"
chmod 755 "${BACKUP_DIR}/harbor"
}
#
# main
#
log "Starting backup of harbor"
# Create backup directory
create_backup_dir
# Trap signals for cleanup
trap clean_db EXIT ERR INT TERM
# Launch container for database backup
launch_db
# Dump the databases
dump_database
# Back up registry files
backup_registry
# Back up chartmuseum files
backup_chart_museum
# Back up redis files
backup_redis
# Back up secrets
backup_secret
# Back up configuration files
backup_config
# Create archive (if not disabled)
create_tarball
log "Ending backup of harbor"

View File

@ -0,0 +1,335 @@
#!/bin/bash
#
# Harbor Restore Script
#
# Default values (match the backup script)
DOCKER_CMD="docker"
HARBOR_DB_IMAGE="$(docker images goharbor/harbor-db --format "{{.Repository}}:{{.Tag}}" | head -1)" # Use a specific tag in production
HARBOR_DB_PATH="/data/database"
REGISTRY_DATA_PATH="/data/registry"
CHART_MUSEUM_PATH="/data/chart_storage"
REDIS_DATA_PATH="/data/redis"
SECRET_PATH="/data/secret"
BACKUP_DIR="harbor_backup"
BACKUP_FILE="harbor_backup.tar.gz"
HARBOR_YML="/etc/harbor/harbor.yml"
NO_ARCHIVE="false"
# Default log level
LOG_LEVEL="INFO"
USE_SYSLOG="false"
POSTGRES_UID=999
POSTGRES_GID=999
# Log levels (syslog-compatible)
declare -A LOG_LEVELS=(
[DEBUG]=7
[INFO]=6
[NOTICE]=5
[WARNING]=4
[ERROR]=3
[CRITICAL]=2
[ALERT]=1
[EMERGENCY]=0
)
usage() {
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Restores a Harbor instance."
echo ""
echo "Options:"
echo " --docker-cmd <command> Docker command (default: docker)"
echo " --db-image <image> Harbor DB image (default: auto-detected)"
echo " --db-path <path> Harbor DB data path (default: /data/database)"
echo " --registry-path <path> Registry data path (default: /data/registry)"
echo " --chart-museum-path <path> Chart Museum data path (default: /data/chart_storage)"
echo " --redis-path <path> Redis data path (default: /data/redis)"
echo " --secret-path <path> Secret data path (default: /data/secret)"
echo " --config-path <path> Harbor configuration file path (default: /etc/harbor/harbor.yml)"
echo " --backup-dir <path> Backup directory (default: harbor_backup)"
echo " --no-archive Do not unpack a tarball (source file tree already in place in ${backup_dir}/harbor)"
echo " --use-syslog Use syslog for logging"
echo " --log-level <level> Log level (default: INFO, options: DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY)"
echo " --help Display this help message"
exit 0
}
# exit immediately if any command fails, an unset variable is used, or a pipe fails
set -euo pipefail
# Parse command-line arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--docker-cmd)
DOCKER_CMD="$2"
shift 2
;;
--db-image)
HARBOR_DB_IMAGE="$2"
shift 2
;;
--db-path)
HARBOR_DB_PATH="$2"
shift 2
;;
--registry-path)
REGISTRY_DATA_PATH="$2"
shift 2
;;
--chart-museum-path)
CHART_MUSEUM_PATH="$2"
shift 2
;;
--redis-path)
REDIS_DATA_PATH="$2"
shift 2
;;
--secret-path)
SECRET_PATH="$2"
shift 2
;;
--config-path)
HARBOR_YML="$2"
shift 2
;;
--backup-dir)
BACKUP_DIR="$2"
shift 2
;;
--no-archive)
NO_ARCHIVE="true"
shift
;;
--use-syslog)
USE_SYSLOG="true"
shift
;;
--log-level)
LOG_LEVEL="$2"
shift 2
;;
--help)
usage
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
# log() will prepend datetime and log the message to stderr and optionally to syslog
# if the optional log level (defaults to INFO) is equal to higher than
# $LOG_LEVEL
log() {
local level
local message
if [[ $# -eq 1 ]]; then # Check if only one argument is provided
level="INFO" # Default level if not provided
message="$1"
elif [[ $# -eq 2 ]]; then # Check if two arguments are provided
level="$1"
message="$2"
else
echo "Usage: log [LEVEL] MESSAGE" >&2
return 1 # Return error code
fi
# Check if logging level is valid
if [[ ! "${LOG_LEVELS[$level]+_}" ]]; then
echo "Invalid log level: $level" >&2 # Log error to stderr
level="INFO" # Fallback to INFO
fi
# Check minimum log level
if (( ${LOG_LEVELS[$level]} > ${LOG_LEVELS[$LOG_LEVEL]} )); then
return # Don't log if below the threshold
fi
local formatted_message="[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message"
echo "$formatted_message"
if [[ "$USE_SYSLOG" == "true" ]]; then
local syslog_priority="local0.${level,,}" # Convert level to lowercase for syslog
logger -t "harbor-restore" -p "$syslog_priority" "$message"
fi
}
# Wait for database to be ready
wait_for_db_ready() {
local TIMEOUT=12
set +e
while [ $TIMEOUT -gt 0 ]; do
docker exec harbor-db pg_isready | grep "accepting connections"
if [ $? -eq 0 ]; then
break
fi
TIMEOUT=$(( $TIMEOUT - 1 ))
log "... waiting for database"
sleep 5
done
set -e
if [ $TIMEOUT -eq 0 ]; then
log CRITICAL "Harbor DB cannot reach within one minute."
exit 1
fi
}
# Launch and wait for database
launch_db() {
if [ -n "$($DOCKER_CMD ps -q)" ]; then
log CRITICAL "There are running containers, please stop and remove before backup"
exit 1
fi
log "Starting database container for restore"
docker run -d --name harbor-db -v "${BACKUP_DIR}/harbor/db":/backup -v "${HARBOR_DB_PATH}":/var/lib/postgresql/data "${HARBOR_DB_IMAGE}" "postgres"
wait_for_db_ready
}
# Restore database
restore_database() {
log "Restoring databases"
databases=$(ls "${BACKUP_DIR}/harbor/db"/*.sql | xargs -n1 basename | cut -d '.' -f 1) # Find .sql files
for db in $databases; do
log "- $db"
dump_file="/backup/${db}.sql"
${DOCKER_CMD} exec harbor-db psql -U postgres -d template1 -c "drop database ${db}; exit \$?"
${DOCKER_CMD} exec harbor-db psql -U postgres -d template1 -c "create database ${db}; exit \$?"
${DOCKER_CMD} exec harbor-db sh -c "psql -U postgres -d ${db} > /dev/null < ${dump_file}; exit \$?"
done
}
# Restore registry data
restore_registry() {
if [ -d "${BACKUP_DIR}/harbor/registry" ]; then
log "Restoring registry data"
if ! rsync -a --delete "${BACKUP_DIR}/harbor/registry/" "${REGISTRY_DATA_PATH}/"; then
log ERROR "Failed to restore registry data using rsync"
exit 1
fi
else
log WARNING "No registry data found (${BACKUP_DIR}/harbor/registry/), skipping restore"
fi
}
# Restore chart museum data
restore_chart_museum() {
if [ -d "${BACKUP_DIR}/harbor/chart_storage" ]; then
log WARNING "Deprecated feature detected - Restoring chartmuseum data"
if ! rsync -a --delete "${BACKUP_DIR}/harbor/chart_storage/" "${CHART_MUSEUM_PATH}/"; then
log ERROR "Failed to restore chartmuseum data using rsync"
exit 1
fi
fi
}
# Restore redis data
restore_redis() {
if [ -d "${BACKUP_DIR}/harbor/redis" ]; then
log "Restoring redis"
if ! rsync -a --delete "${BACKUP_DIR}/harbor/redis/" "${REDIS_DATA_PATH}/"; then
log ERROR "Failed to restore redis data using rsync"
exit 1
fi
else
log "No redis backup found, skipping restore."
fi
}
# Restore secrets
restore_secret() {
if [ -d "${BACKUP_DIR}/harbor/secret" ]; then
log "Restoring secrets"
if ! rsync -a --delete "${BACKUP_DIR}/harbor/secret/" "${SECRET_PATH}/"; then
log ERROR "Failed to restore secrets"
exit 1
fi
else
log "No secrets backup found, skipping restore."
fi
}
restore_config() {
if [ -f "${BACKUP_DIR}/harbor/harbor.yml" ]; then
log "Restoring configuration file"
cp "${BACKUP_DIR}/harbor/harbor.yml" "${HARBOR_YML}"
else
log "No configuration backup found, skipping restore."
fi
}
# Clean up database container
clean_db() {
log "Clean up temporary database container for backup"
docker stop harbor-db
docker rm harbor-db
}
extract_tarball() {
if [ ${NO_ARCHIVE} == "false" ]; then
if [ -f "${BACKUP_DIR}/${BACKUP_FILE}" ]; then
cd "${BACKUP_DIR}"
if [ -d harbor ] ; then
log "Removing existing ${BACKUP_DIR}/harbor"
rm -rf harbor
fi
log "Extracting tarball ${BACKUP_DIR}/${BACKUP_FILE}"
tar -xzf "${BACKUP_DIR}/${BACKUP_FILE}"
else
log ERROR "No tarball found, Exiting."
exit 1
fi
else
log "Not extracting tarball"
fi
}
#
# main
#
log "Starting restore of harbor"
# Create backup directory if it doesn't exist (for extracted backups)
if [[ ! -d "$BACKUP_DIR" ]]; then
mkdir -p "$BACKUP_DIR"
fi
# Trap signals for cleanup
trap clean_db EXIT ERR INT TERM
# Launch container for database backup
launch_db
# Extract the tarball (if it exists)
extract_tarball
# Restore the databases
restore_database
# Restore the registry
restore_registry
# Restore the Chart Museum
restore_chart_museum
# Restore Redis
restore_redis
# Restore the secrets
restore_secret
# Restore the configuration
restore_config
log "Ending restore of harbor"