diff --git a/.github/renovate.json b/.github/renovate.json index 99ece2c2..60772718 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -4,6 +4,7 @@ "group:allNonMajor" ], "baseBranches": [ + "main", "release/v3.0", "release/v4.0", "release/v5.0" diff --git a/.github/scripts/branch-tags.sh b/.github/scripts/branch-tags.sh new file mode 100644 index 00000000..8456894c --- /dev/null +++ b/.github/scripts/branch-tags.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# Exit immediately if a command exits with a non-zero status +set -e + +# Function to get the previous tag +getPreviousTag() { + local tagPrefix="$1" + # List all tags and filter ones that start with tagPrefix, sort by creation date + git tag --sort=-creatordate | grep "^${tagPrefix}" | head -n 1 +} + +# Determine if we're in a GitHub Actions environment +if [ -n "$GITHUB_REF" ] && [ -n "$GITHUB_SHA" ]; then + # Use GHA environment variables + ref="$GITHUB_REF" + commitSha="${GITHUB_SHA:0:7}" +else + # Fallback to local Git repo + if [ ! -d ".git" ]; then + echo "This script must be run from the root of a Git repository or GitHub Actions." + exit 1 + fi + ref=$(git symbolic-ref HEAD) + commitSha=$(git rev-parse --short HEAD) +fi + +branchTag="" +branchStaticTag="" +prevTag="" + +if [ "$ref" == "refs/heads/main" ]; then + branchTag="head" + branchStaticTag="main-${commitSha}" + prevTag=$(getPreviousTag "main-") +elif [[ "$ref" == refs/heads/release/* ]]; then + version="${ref#refs/heads/release/}" # Extract "vX.0" + branchTag="${version}-head" + branchStaticTag="${version}-head-${commitSha}" + prevTag=$(getPreviousTag "${version}-head-") +else + echo "Unsupported branch pattern. Expected 'main' or 'release/*'." + exit 1 +fi + +# Output the results +echo "branch_tag=${branchTag}" +echo "branch_static_tag=${branchStaticTag}" +echo "prev_static_tag=${prevTag}" \ No newline at end of file diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b7d11f72..97ce3f70 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -7,6 +7,7 @@ on: workflow_call: push: branches: + - main - release/v5.0 - release/v4.0 - release/v3.0 @@ -28,12 +29,11 @@ jobs: build: strategy: matrix: - os : [ - ubuntu-latest - # org-rancher-arm64-containers - ] + arch: + - x64 + - arm64 name : CI - runs-on : ${{ matrix.os }} + runs-on : runs-on,image=ubuntu22-full-${{ matrix.arch }},runner=4cpu-linux-${{ matrix.arch }},run-id=${{ github.run_id }} outputs: k3sversions: ${{ steps.support.outputs.k3sversions }} steps: @@ -49,7 +49,7 @@ jobs: - name: Upload artifact uses: actions/upload-artifact@v4 with: - name: bro-build-artifacts-${{ matrix.os }} + name: bro-build-artifacts-${{ matrix.arch }} path: ./dist/artifacts test: @@ -57,13 +57,12 @@ jobs: needs : [ build ] - runs-on : ${{ matrix.os }} + runs-on : runs-on,image=ubuntu22-full-${{ matrix.arch }},runner=4cpu-linux-${{ matrix.arch }},run-id=${{ github.run_id }} strategy: matrix: - os : [ - ubuntu-latest - # org-rancher-arm64-containers, - ] + arch: + - x64 + - arm64 K3S_VERSION : ${{ fromJSON(needs.build.outputs.k3sversions) }} steps: - name : Checkout repository @@ -71,7 +70,7 @@ jobs: - name : Fetch build artifacts uses: actions/download-artifact@v4 with: - name: bro-build-artifacts-${{ matrix.os }} + name: bro-build-artifacts-${{ matrix.arch }} path: ./dist/artifacts/ - name : Debug run : ls -R ./dist/artifacts @@ -79,9 +78,13 @@ jobs: uses: docker/setup-buildx-action@v3 - name : Load backup-restore-operator image run : docker image load -i ./dist/artifacts/backup-restore-operator.img - - name : Setup up K3d + - name: Install go + uses: actions/setup-go@v5 + with: + go-version: 1.22 + - name : Install k3d run : ./.github/workflows/scripts/install-k3d.sh - - name : Setup up mc + - name : Install minio client run : ./.github/workflows/scripts/install-mc.sh - name : Setup k3d cluster run : CLUSTER_NAME=backup-restore K3S_VERSION=${{ matrix.K3S_VERSION }} ./.github/workflows/scripts/setup-cluster.sh diff --git a/.github/workflows/head-builds.yaml b/.github/workflows/head-builds.yaml new file mode 100644 index 00000000..62e089f6 --- /dev/null +++ b/.github/workflows/head-builds.yaml @@ -0,0 +1,81 @@ +name : Branch head Prerelease Images + +on: + push: + branches: + - main + - release/v[0-9]+.0 + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + REGISTRY: docker.io + REPO : rancher + +permissions: + contents: write + +jobs: + prebuild-env: + name: Prebuild needed Env vars + runs-on : runs-on,image=ubuntu22-full-x64,runner=4cpu-linux-x64,run-id=${{ github.run_id }} + steps: + - name: Check out the repository to the runner + uses: actions/checkout@v4 + - name: Set Branch Tag and Other Variables + id: set-vars + run: bash ./.github/scripts/branch-tags.sh >> $GITHUB_OUTPUT + outputs: + branch_tag: ${{ steps.set-vars.outputs.branch_tag }} + branch_static_tag: ${{ steps.set-vars.outputs.branch_static_tag }} + prev_tag: ${{ steps.set-vars.outputs.prev_tag }} + push: + needs : [ + prebuild-env, + ] + permissions: + contents : read + id-token: write + name : Build and push BRO images + runs-on : runs-on,image=ubuntu22-full-x64,runner=4cpu-linux-x64,run-id=${{ github.run_id }} + steps: + - name : "Read vault secrets" + uses : rancher-eio/read-vault-secrets@main + if: ${{ github.repository_owner == 'rancher' }} + with: + secrets: | + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials username | DOCKER_USERNAME ; + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials password | DOCKER_PASSWORD + - name : Checkout repository + uses: actions/checkout@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ env.DOCKER_USERNAME || vars.REPO }} + password: ${{ env.DOCKER_PASSWORD || secrets.DOCKER_PW }} + - name: Build and push BRO image + env: + FULL_IMAGE_URL: "${{ env.REGISTRY }}/${{ vars.REPO || env.REPO || github.repository_owner }}/backup-restore-operator" + uses: docker/build-push-action@v6 + with: + context: . + file: ./package/Dockerfile + build-args: | + TAG=${{ needs.prebuild-env.outputs.branch_static_tag }} + push: true + tags: ${{ env.FULL_IMAGE_URL }}:${{ needs.prebuild-env.outputs.branch_static_tag }} + platforms: linux/amd64,linux/arm64 + - name: Update rolling tag to new static tag + env: + FULL_IMAGE_URL: ${{ env.REGISTRY }}/${{ vars.REPO || env.REPO || github.repository_owner }}/backup-restore-operator + run: | + VERSION="1.2.0" + curl -LO "https://github.com/oras-project/oras/releases/download/v${VERSION}/oras_${VERSION}_linux_amd64.tar.gz" + mkdir -p oras-install/ + tar -zxf oras_${VERSION}_*.tar.gz -C oras-install/ + oras-install/oras copy ${{ env.FULL_IMAGE_URL }}:${{ needs.prebuild-env.outputs.branch_static_tag }} ${{ env.FULL_IMAGE_URL }}:${{ needs.prebuild-env.outputs.branch_tag }} \ No newline at end of file diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index bb185b12..c6124815 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -49,7 +49,7 @@ jobs: contents : read id-token: write name : Build and push BRO images - runs-on : ubuntu-latest + runs-on : runs-on,image=ubuntu22-full-x64,runner=4cpu-linux-x64,run-id=${{ github.run_id }} steps: - name : "Read vault secrets" uses : rancher-eio/read-vault-secrets@main @@ -67,15 +67,11 @@ jobs: registry: ${{ env.REGISTRY }} username: ${{ env.DOCKER_USERNAME }} password: ${{ env.DOCKER_PASSWORD }} - # setup tag name - - if: ${{ startsWith(github.ref, 'refs/tags/') }} - run: | - echo TAG_NAME=$(echo $GITHUB_REF | sed -e "s|refs/tags/||") >> $GITHUB_ENV - name: Build and push BRO image uses: docker/build-push-action@v6 with: context: . file: ./package/Dockerfile push: true - tags: ${{ env.REGISTRY }}/${{ env.REPO }}/backup-restore-operator:${{ env.TAG_NAME }} + tags: ${{ env.REGISTRY }}/${{ env.REPO }}/backup-restore-operator:${{ github.ref_name }} platforms: linux/amd64,linux/arm64 \ No newline at end of file diff --git a/README.md b/README.md index fca3f617..de5a6778 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,45 @@ # Backup and Restore Operator -### Latest release +## Latest release [![Latest](https://img.shields.io/badge/dynamic/yaml?label=backup-restore-operator&query=%24.entries%5B%27rancher-backup%27%5D%5B0%5D.appVersion&url=https%3A%2F%2Fcharts.rancher.io%2Findex.yaml)](https://github.com/rancher/backup-restore-operator/releases/latest) -### Description +## Description -* This operator provides ability to backup and restore Kubernetes applications (metadata) running on any cluster. It accepts a list of resources that need to be backed up for a particular application. It then gathers these resources by querying the Kubernetes API server, packages all the resources to create a tarball file and pushes it to the configured backup storage location. Since it gathers resources by querying the API server, it can back up applications from any type of Kubernetes cluster. -* The operator preserves the ownerReferences on all resources, hence maintaining dependencies between objects. -* It also provides encryption support, to encrypt user specified resources before saving them in the backup file. It uses the same encryption configuration that is used to enable [Kubernetes Encryption at Rest](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/). Follow the steps in [this section](https://ranchermanager.docs.rancher.com/reference-guides/backup-restore-configuration/backup-configuration#encryption) to configure this. +The Backup and Restore Operator provides the ability to back up and restore the Rancher application running on any Kubernetes cluster. + +### Use Cases +- Performing a backup before upgrading Rancher and restoring after a failed upgrade. +- Restoring your *Rancher application* to a new cluster in a disaster recovery scenario. +- Migrating your *Rancher application* between Kubernetes distributions of the same version. +- (Optional) Storing and restoring backups using [Kubernetes Encryption at Rest](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/). +What the Backup Restore Operator is not: +- A downstream cluster snapshot tool, +- A replacement for Etcd cluster backups, +- Configured to back up user-created resources on the Rancher cluster. ### Branches and Releases +This is the current branch strategy for `rancher/backup-restore-operator`, it may change in the future. + +| Branch | Tag | Rancher | +|----------------|----------|------------------------| +| `main` | `head` | `main` branch (`head`) | +| `release/v5.0` | `v5.x.x` | `v2.9.x` | +| `release/v4.0` | `v4.x.x` | `v2.8.x` | +| `release/v3.0` | `v3.x.x` | `v2.7.x` | -* the tag `v4.x.x` is cut from the `release/v4.0` branch for Rancher v2.8.x line -* the tag `v3.x.x` is cut from the `release/v3.0` branch for Rancher v2.7.x line -* the tag `v2.x.x` is cut from the `release/v2.0` branch for Rancher v2.6.x line ---- -### Quickstart +## Quickstart + +You will need to install the `backup-restore-operator`, from the [Cluster Explorer UI](https://ranchermanager.docs.rancher.com/pages-for-subheaders/backup-restore-and-disaster-recovery). +Within the App catalog look for the `Rancher Backups` application chart. -If Rancher v2.5+ is installed, you can install the `backup-restore-operator`, from the [Cluster Explorer UI](https://ranchermanager.docs.rancher.com/pages-for-subheaders/backup-restore-and-disaster-recovery). -Otherwise, you can install the charts via `helm repo` by executing the commands below. +However, when performing a Rancher migration you will not have the UI installed. +So, you will need to install the charts via `helm repo` by executing the commands below. -First, add our charts repository. +First, add the `rancher-charts` charts repository. ```bash helm repo add rancher-charts https://charts.rancher.io @@ -59,6 +75,15 @@ kubectl delete namespace cattle-resources-system ---- +## More Info + +The default chart is built for the use case of backing up and restoring the Rancher application. +However, under the hood the Backup Restore Operator is a rather flexible extension for backup and restore of Kubernetes resources. + +* This operator provides the ability to backup and restore Kubernetes applications (metadata) running on any cluster. It accepts a list of resources that need to be backed up for the application. It then gathers these resources by querying the Kubernetes API server, packages all the resources to create a tarball file, and pushes it to the configured backup storage location. Since it gathers resources by querying the API server, it can back up applications from any type of Kubernetes cluster. +* The operator preserves the `ownerReferences` on all resources, hence maintaining dependencies between objects. +* It also provides encryption support, to encrypt user specified resources before saving them in the backup file. It uses the same encryption configuration that is used to enable [Kubernetes Encryption at Rest](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/). Follow the steps in [this section](https://ranchermanager.docs.rancher.com/reference-guides/backup-restore-configuration/backup-configuration#encryption) to configure this. + ### CRDs It installs the following cluster-scoped CRDs: diff --git a/package/Dockerfile b/package/Dockerfile index 2c378e77..d3d382a6 100644 --- a/package/Dockerfile +++ b/package/Dockerfile @@ -1,4 +1,9 @@ FROM registry.suse.com/bci/golang:1.22 AS builder + +ARG TAG='' +ARG REPO='' +ENV TAG=$TAG REPO=$REPO + WORKDIR /usr/src/app COPY go.mod go.sum ./ RUN go mod download diff --git a/scripts/version b/scripts/version index 80192a4b..30d71144 100755 --- a/scripts/version +++ b/scripts/version @@ -6,7 +6,7 @@ if [ -n "$(git status --porcelain --untracked-files=no)" ]; then fi COMMIT=$(git rev-parse --short HEAD) -GIT_TAG=${DRONE_TAG:-$(git tag -l --contains HEAD | head -n 1)} +GIT_TAG=$(git tag -l --contains HEAD | head -n 1) if [[ -z "$DIRTY" && -n "$GIT_TAG" ]]; then VERSION=$GIT_TAG