Compare commits
1 Commits
c51b1c7bca
...
feat-add-h
| Author | SHA1 | Date | |
|---|---|---|---|
| 5a25eca929 |
@@ -4,16 +4,35 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
paths:
|
|
||||||
- "src/**"
|
|
||||||
- "Dockerfile"
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
DOCKER_REGISTRY: gitea.t000-n.de
|
DOCKER_REGISTRY: gitea.t000-n.de
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
check-changes:
|
||||||
|
name: Check changes
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
changes: ${{ steps.filter.outputs.code }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
|
- name: Get changed files
|
||||||
|
id: filter
|
||||||
|
uses: dorny/paths-filter@v3
|
||||||
|
with:
|
||||||
|
filters: |
|
||||||
|
code:
|
||||||
|
- 'src/**'
|
||||||
|
- 'Dockerfile'
|
||||||
|
- 'gitea/workflows/**'
|
||||||
|
|
||||||
build_and_push:
|
build_and_push:
|
||||||
name: Build and push
|
name: Build and push
|
||||||
|
needs:
|
||||||
|
- check-changes
|
||||||
|
if: ${{ needs.check-changes.outputs.changes != '0' }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
arch:
|
arch:
|
||||||
@@ -23,9 +42,9 @@ jobs:
|
|||||||
- ubuntu-latest
|
- ubuntu-latest
|
||||||
- linux_${{ matrix.arch }}
|
- linux_${{ matrix.arch }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
- uses: actions/checkout@v5
|
||||||
- uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
|
- uses: docker/setup-buildx-action@v3
|
||||||
- uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
- uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.DOCKER_REGISTRY }}
|
registry: ${{ env.DOCKER_REGISTRY }}
|
||||||
username: ${{ secrets.REGISTRY_USER }}
|
username: ${{ secrets.REGISTRY_USER }}
|
||||||
@@ -34,7 +53,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}' | tr '[:upper:]' '[:lower:]') >> $GITHUB_OUTPUT
|
echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}' | tr '[:upper:]' '[:lower:]') >> $GITHUB_OUTPUT
|
||||||
echo REPO_VERSION=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT
|
echo REPO_VERSION=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT
|
||||||
- uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
|
- uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
@@ -53,10 +72,10 @@ jobs:
|
|||||||
outputs:
|
outputs:
|
||||||
tag: ${{ steps.tag.outputs.new-tag }}
|
tag: ${{ steps.tag.outputs.new-tag }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
- uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment@41b7e04221df8a033bec841d40a097b76e5f67ff # 0.1.29
|
- uses: https://gitea.t000-n.de/t.behrendt/conventional-semantic-git-tag-increment@0.0.2
|
||||||
id: tag
|
id: tag
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITEA_TOKEN }}
|
token: ${{ secrets.GITEA_TOKEN }}
|
||||||
@@ -74,12 +93,12 @@ jobs:
|
|||||||
- create_tag
|
- create_tag
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
- uses: actions/checkout@v5
|
||||||
- id: meta
|
- id: meta
|
||||||
run: |
|
run: |
|
||||||
echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}' | tr '[:upper:]' '[:lower:]') >> $GITHUB_OUTPUT
|
echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}' | tr '[:upper:]' '[:lower:]') >> $GITHUB_OUTPUT
|
||||||
echo REPO_VERSION=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT
|
echo REPO_VERSION=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT
|
||||||
- uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
- uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.DOCKER_REGISTRY }}
|
registry: ${{ env.DOCKER_REGISTRY }}
|
||||||
username: ${{ secrets.REGISTRY_USER }}
|
username: ${{ secrets.REGISTRY_USER }}
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ jobs:
|
|||||||
- ubuntu-latest
|
- ubuntu-latest
|
||||||
- linux_amd64
|
- linux_amd64
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
- uses: actions/checkout@v5
|
||||||
- uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
|
- uses: docker/setup-buildx-action@v3
|
||||||
- name: Build image
|
- name: Build image
|
||||||
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
@@ -27,7 +27,7 @@ jobs:
|
|||||||
name: Check syntax
|
name: Check syntax
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
- uses: actions/checkout@v5
|
||||||
- name: Check syntax
|
- name: Check syntax
|
||||||
run: |
|
run: |
|
||||||
bash -n src/backup.sh
|
bash -n src/backup.sh
|
||||||
|
|||||||
14
Dockerfile
14
Dockerfile
@@ -1,15 +1,15 @@
|
|||||||
FROM docker.io/library/alpine:3.23.3@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 AS base
|
FROM alpine:3.22
|
||||||
|
|
||||||
# Add edge repository for postgresql18-client
|
|
||||||
RUN echo '@edge http://dl-cdn.alpinelinux.org/alpine/edge/main' >> /etc/apk/repositories
|
|
||||||
|
|
||||||
RUN apk update && apk add --no-cache \
|
RUN apk update && apk add --no-cache \
|
||||||
bash \
|
bash \
|
||||||
curl \
|
curl \
|
||||||
restic \
|
restic \
|
||||||
jq \
|
postgresql-client \
|
||||||
postgresql18-client@edge \
|
jq
|
||||||
libpq@edge
|
|
||||||
|
RUN curl -O https://dl.min.io/client/mc/release/linux-amd64/mc \
|
||||||
|
&& chmod +x mc \
|
||||||
|
&& mv mc /usr/local/bin/
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
|||||||
133
README.md
133
README.md
@@ -11,7 +11,7 @@ BackupSidecar is configured through environment variables. Below is a breakdown
|
|||||||
These variables apply to both backup and restore operations.
|
These variables apply to both backup and restore operations.
|
||||||
|
|
||||||
- **`OPERATION_MODE`** _(optional)_ - Defines the operation type (`backup` or `restore`). Defaults to `backup`.
|
- **`OPERATION_MODE`** _(optional)_ - Defines the operation type (`backup` or `restore`). Defaults to `backup`.
|
||||||
- **`BACKUP_MODE`** _(optional)_ - Defines the backup type (`directory` or `postgres`). Defaults to `directory`.
|
- **`BACKUP_MODE`** _(optional)_ - Defines the backup type (`directory`, `postgres`, or `s3`). Defaults to `directory`.
|
||||||
- **`RESTIC_PASSWORD`** _(required)_ - The encryption password for Restic.
|
- **`RESTIC_PASSWORD`** _(required)_ - The encryption password for Restic.
|
||||||
- **`RESTIC_REPOSITORY`** _(required)_ - The URI of the Restic repository (e.g., `rest:http://your-rest-server:8000/backup`).
|
- **`RESTIC_REPOSITORY`** _(required)_ - The URI of the Restic repository (e.g., `rest:http://your-rest-server:8000/backup`).
|
||||||
- **`RESTIC_REST_USERNAME`** _(optional)_ - The username for REST server authentication.
|
- **`RESTIC_REST_USERNAME`** _(optional)_ - The username for REST server authentication.
|
||||||
@@ -55,6 +55,22 @@ For `postgres` mode, the following database-related variables are required:
|
|||||||
- **`RESTORE_SNAPSHOT_ID`** _(optional)_ - The specific snapshot ID to restore (defaults to `latest`).
|
- **`RESTORE_SNAPSHOT_ID`** _(optional)_ - The specific snapshot ID to restore (defaults to `latest`).
|
||||||
- **`PSQL_ARGS`** _(optional)_ - Additional flags for `psql` (e.g., `--single-transaction`).
|
- **`PSQL_ARGS`** _(optional)_ - Additional flags for `psql` (e.g., `--single-transaction`).
|
||||||
|
|
||||||
|
### S3 Operations
|
||||||
|
|
||||||
|
For `s3` mode, the following S3-related variables are required:
|
||||||
|
|
||||||
|
**Common Variables:**
|
||||||
|
|
||||||
|
- **`S3_BUCKET`** _(required)_ - The name of the S3 bucket to backup/restore.
|
||||||
|
- **`S3_ENDPOINT`** _(required)_ - The S3 endpoint URL (e.g., `http://minio:9000` for MinIO).
|
||||||
|
- **`MINIO_ACCESS_KEY`** _(required)_ - The MinIO access key for S3 authentication.
|
||||||
|
- **`MINIO_SECRET_KEY`** _(required)_ - The MinIO secret key for S3 authentication.
|
||||||
|
- **`S3_PREFIX`** _(optional)_ - Optional path prefix within the bucket to backup/restore.
|
||||||
|
|
||||||
|
**Restore-Specific Variables:**
|
||||||
|
|
||||||
|
- **`RESTORE_SNAPSHOT_ID`** _(optional)_ - The specific snapshot ID to restore (defaults to `latest`).
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
Ensure the following commands are available in the container:
|
Ensure the following commands are available in the container:
|
||||||
@@ -64,6 +80,7 @@ Ensure the following commands are available in the container:
|
|||||||
- `jq`
|
- `jq`
|
||||||
- `pg_dump` _(only required for PostgreSQL backup operations)_
|
- `pg_dump` _(only required for PostgreSQL backup operations)_
|
||||||
- `psql` _(only required for PostgreSQL restore operations)_
|
- `psql` _(only required for PostgreSQL restore operations)_
|
||||||
|
- `mc` _(only required for S3 operations)_
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@@ -236,6 +253,120 @@ spec:
|
|||||||
value: "Database Restore Notification"
|
value: "Database Restore Notification"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Example Kubernetes Job manifest for running BackupSidecar to backup an S3 bucket:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: backupsidecar-s3-backup
|
||||||
|
namespace: authentik
|
||||||
|
spec:
|
||||||
|
backoffLimit: 3
|
||||||
|
activeDeadlineSeconds: 600
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
restartPolicy: OnFailure
|
||||||
|
containers:
|
||||||
|
- name: backupsidecar
|
||||||
|
image: backupsidecar:latest
|
||||||
|
env:
|
||||||
|
- name: OPERATION_MODE
|
||||||
|
value: "backup"
|
||||||
|
- name: BACKUP_MODE
|
||||||
|
value: "s3"
|
||||||
|
- name: S3_BUCKET
|
||||||
|
value: "my-bucket"
|
||||||
|
- name: S3_ENDPOINT
|
||||||
|
value: "http://minio:9000"
|
||||||
|
- name: S3_PREFIX
|
||||||
|
value: "data" # optional
|
||||||
|
- name: MINIO_ACCESS_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: minio-secret
|
||||||
|
key: access_key
|
||||||
|
- name: MINIO_SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: minio-secret
|
||||||
|
key: secret_key
|
||||||
|
- name: RESTIC_REPOSITORY
|
||||||
|
value: "rest:http://rest-server:8000/backup"
|
||||||
|
- name: RESTIC_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backupsidecar-secret
|
||||||
|
key: restic_password
|
||||||
|
- name: GOTIFYHOST
|
||||||
|
value: "http://gotify.example.com"
|
||||||
|
- name: GOTIFYTOKEN
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backupsidecar-secret
|
||||||
|
key: gotify_token
|
||||||
|
- name: GOTIFYTOPIC
|
||||||
|
value: "S3 Backup Notification"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example Kubernetes Job manifest for running BackupSidecar to restore an S3 bucket:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: backupsidecar-s3-restore
|
||||||
|
namespace: authentik
|
||||||
|
spec:
|
||||||
|
backoffLimit: 3
|
||||||
|
activeDeadlineSeconds: 600
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
restartPolicy: OnFailure
|
||||||
|
containers:
|
||||||
|
- name: backupsidecar
|
||||||
|
image: backupsidecar:latest
|
||||||
|
env:
|
||||||
|
- name: OPERATION_MODE
|
||||||
|
value: "restore"
|
||||||
|
- name: BACKUP_MODE
|
||||||
|
value: "s3"
|
||||||
|
- name: S3_BUCKET
|
||||||
|
value: "my-bucket"
|
||||||
|
- name: S3_ENDPOINT
|
||||||
|
value: "http://minio:9000"
|
||||||
|
- name: S3_PREFIX
|
||||||
|
value: "data" # optional
|
||||||
|
- name: RESTORE_SNAPSHOT_ID
|
||||||
|
value: "abc123def456" # optional, defaults to latest
|
||||||
|
- name: MINIO_ACCESS_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: minio-secret
|
||||||
|
key: access_key
|
||||||
|
- name: MINIO_SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: minio-secret
|
||||||
|
key: secret_key
|
||||||
|
- name: RESTIC_REPOSITORY
|
||||||
|
value: "rest:http://rest-server:8000/backup"
|
||||||
|
- name: RESTIC_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backupsidecar-secret
|
||||||
|
key: restic_password
|
||||||
|
- name: GOTIFYHOST
|
||||||
|
value: "http://gotify.example.com"
|
||||||
|
- name: GOTIFYTOKEN
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: backupsidecar-secret
|
||||||
|
key: gotify_token
|
||||||
|
- name: GOTIFYTOPIC
|
||||||
|
value: "S3 Restore Notification"
|
||||||
|
```
|
||||||
|
|
||||||
## Notifications
|
## Notifications
|
||||||
|
|
||||||
The script can send success or failure notifications via Gotify when enabled. To enable notifications, set `ENABLE_GOTIFY=true` and provide the required Gotify configuration variables (`GOTIFYHOST`, `GOTIFYTOKEN`, `GOTIFYTOPIC`). When notifications are disabled, backup status messages are still logged to the console.
|
The script can send success or failure notifications via Gotify when enabled. To enable notifications, set `ENABLE_GOTIFY=true` and provide the required Gotify configuration variables (`GOTIFYHOST`, `GOTIFYTOKEN`, `GOTIFYTOPIC`). When notifications are disabled, backup status messages are still logged to the console.
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
|
||||||
"extends": [
|
|
||||||
"local>t.behrendt/renovate-configs:common",
|
|
||||||
"local>t.behrendt/renovate-configs:action"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
105
src/backup.sh
105
src/backup.sh
@@ -24,7 +24,7 @@ OPERATION_MODE="${OPERATION_MODE:-backup}"
|
|||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Determine backup mode from the environment only.
|
# Determine backup mode from the environment only.
|
||||||
# Valid values: "directory" or "postgres".
|
# Valid values: "directory", "postgres", or "s3".
|
||||||
# Default to "directory" if not provided.
|
# Default to "directory" if not provided.
|
||||||
#######################################
|
#######################################
|
||||||
BACKUP_MODE="${BACKUP_MODE:-directory}"
|
BACKUP_MODE="${BACKUP_MODE:-directory}"
|
||||||
@@ -39,6 +39,8 @@ if [ "$BACKUP_MODE" = "postgres" ]; then
|
|||||||
elif [ "$OPERATION_MODE" = "restore" ]; then
|
elif [ "$OPERATION_MODE" = "restore" ]; then
|
||||||
REQUIRED_CMDS+=(psql)
|
REQUIRED_CMDS+=(psql)
|
||||||
fi
|
fi
|
||||||
|
elif [ "$BACKUP_MODE" = "s3" ]; then
|
||||||
|
REQUIRED_CMDS+=(mc)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for cmd in "${REQUIRED_CMDS[@]}"; do
|
for cmd in "${REQUIRED_CMDS[@]}"; do
|
||||||
@@ -107,8 +109,16 @@ case "$BACKUP_MODE" in
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
s3)
|
||||||
|
: "${S3_BUCKET:?Environment variable S3_BUCKET is not set (required for S3 mode)}"
|
||||||
|
: "${S3_ENDPOINT:?Environment variable S3_ENDPOINT is not set (required for S3 mode)}"
|
||||||
|
: "${MINIO_ACCESS_KEY:?Environment variable MINIO_ACCESS_KEY is not set (required for S3 mode)}"
|
||||||
|
: "${MINIO_SECRET_KEY:?Environment variable MINIO_SECRET_KEY is not set (required for S3 mode)}"
|
||||||
|
# Optional: S3 path prefix
|
||||||
|
: "${S3_PREFIX:=}"
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Error: Unknown backup mode '$BACKUP_MODE'. Valid modes are 'directory' and 'postgres'." >&2
|
echo "Error: Unknown backup mode '$BACKUP_MODE'. Valid modes are 'directory', 'postgres', and 's3'." >&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -287,6 +297,91 @@ restore_postgres() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Backup an S3 bucket.
|
||||||
|
# Syncs the S3 bucket to a temporary directory and then backs it up.
|
||||||
|
#######################################
|
||||||
|
backup_s3() {
|
||||||
|
log "Starting S3 backup for bucket '${S3_BUCKET}' at endpoint '${S3_ENDPOINT}'"
|
||||||
|
|
||||||
|
# Create a temporary directory for the S3 sync.
|
||||||
|
TEMP_BACKUP_DIR=$(mktemp -d)
|
||||||
|
log "Created temporary directory: ${TEMP_BACKUP_DIR}"
|
||||||
|
|
||||||
|
# Configure MinIO Client alias
|
||||||
|
local alias_name="backupsidecar"
|
||||||
|
if ! mc alias set "${alias_name}" "${S3_ENDPOINT}" "${MINIO_ACCESS_KEY}" "${MINIO_SECRET_KEY}"; then
|
||||||
|
local msg="Failed to configure MinIO client alias"
|
||||||
|
log "$msg"
|
||||||
|
send_notification "$msg"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build S3 path
|
||||||
|
local s3_path="${alias_name}/${S3_BUCKET}"
|
||||||
|
if [ -n "${S3_PREFIX}" ]; then
|
||||||
|
s3_path="${s3_path}/${S3_PREFIX}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Syncing S3 bucket from ${s3_path} to ${TEMP_BACKUP_DIR}..."
|
||||||
|
if mc mirror "${s3_path}" "${TEMP_BACKUP_DIR}" --remove; then
|
||||||
|
log "S3 sync completed successfully."
|
||||||
|
else
|
||||||
|
local exit_code=$?
|
||||||
|
local msg="S3 sync failed with error code ${exit_code}"
|
||||||
|
log "$msg"
|
||||||
|
send_notification "$msg"
|
||||||
|
exit "$exit_code"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Back up the directory containing the S3 content.
|
||||||
|
run_restic_backup "${TEMP_BACKUP_DIR}"
|
||||||
|
}
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Restore an S3 bucket.
|
||||||
|
# Restores the S3 content from the backup and syncs it back to S3.
|
||||||
|
#######################################
|
||||||
|
restore_s3() {
|
||||||
|
local snapshot_id="${RESTORE_SNAPSHOT_ID:-latest}"
|
||||||
|
log "Starting S3 restore for bucket '${S3_BUCKET}' at endpoint '${S3_ENDPOINT}'"
|
||||||
|
|
||||||
|
# Create a temporary directory for the restore.
|
||||||
|
TEMP_RESTORE_DIR=$(mktemp -d)
|
||||||
|
log "Created temporary directory: ${TEMP_RESTORE_DIR}"
|
||||||
|
|
||||||
|
# Restore the backup to the temporary directory
|
||||||
|
run_restic_restore "${TEMP_RESTORE_DIR}" "${snapshot_id}"
|
||||||
|
|
||||||
|
# Configure MinIO Client alias
|
||||||
|
local alias_name="backupsidecar"
|
||||||
|
if ! mc alias set "${alias_name}" "${S3_ENDPOINT}" "${MINIO_ACCESS_KEY}" "${MINIO_SECRET_KEY}"; then
|
||||||
|
local msg="Failed to configure MinIO client alias"
|
||||||
|
log "$msg"
|
||||||
|
send_notification "$msg"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build S3 path
|
||||||
|
local s3_path="${alias_name}/${S3_BUCKET}"
|
||||||
|
if [ -n "${S3_PREFIX}" ]; then
|
||||||
|
s3_path="${s3_path}/${S3_PREFIX}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Syncing restored content from ${TEMP_RESTORE_DIR} to ${s3_path}..."
|
||||||
|
if mc mirror "${TEMP_RESTORE_DIR}" "${s3_path}" --remove; then
|
||||||
|
local msg="S3 restore completed successfully"
|
||||||
|
log "$msg"
|
||||||
|
send_notification "$msg"
|
||||||
|
else
|
||||||
|
local exit_code=$?
|
||||||
|
local msg="S3 restore failed with error code ${exit_code}"
|
||||||
|
log "$msg"
|
||||||
|
send_notification "$msg"
|
||||||
|
exit "$exit_code"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Cleanup temporary resources.
|
# Cleanup temporary resources.
|
||||||
#######################################
|
#######################################
|
||||||
@@ -315,6 +410,9 @@ main() {
|
|||||||
postgres)
|
postgres)
|
||||||
backup_postgres
|
backup_postgres
|
||||||
;;
|
;;
|
||||||
|
s3)
|
||||||
|
backup_s3
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
restore)
|
restore)
|
||||||
@@ -325,6 +423,9 @@ main() {
|
|||||||
postgres)
|
postgres)
|
||||||
restore_postgres
|
restore_postgres
|
||||||
;;
|
;;
|
||||||
|
s3)
|
||||||
|
restore_s3
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
Reference in New Issue
Block a user