diff --git a/demo/README.md b/demo/README.md index 49ae532..983b2d0 100644 --- a/demo/README.md +++ b/demo/README.md @@ -101,6 +101,7 @@ followed by the deployment of the PostgreSQL clusters. |----------|---------|-------------| | `LEGACY=true` | `false` | Use the legacy in-tree Barman Cloud code instead of the Barman Cloud Plugin | | `TRUNK=true` | `false` | Deploy from the `main` branch of both CloudNativePG and the Barman Cloud Plugin | +| `REQUIREMENTS_ONLY=true` | `false` | Deploy only CloudNativePG, cert-manager, and the Barman Cloud Plugin; skip ObjectStores/Clusters. A later plain run automatically detects and skips already-installed requirements | | `DRY_RUN=true` | `false` | Print the generated YAML to stdout without applying it | | `OUTPUT_DIR=` | _(unset)_ | Save the generated YAML to `/.yaml` (one file per region) and apply it | | `DRY_RUN=true OUTPUT_DIR=` | | Save the generated YAML to files only, without applying | diff --git a/demo/funcs_requirements.sh b/demo/funcs_requirements.sh new file mode 100755 index 0000000..211ca3c --- /dev/null +++ b/demo/funcs_requirements.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash +## +## Copyright © contributors to CloudNativePG, established as +## CloudNativePG a Series of LF Projects, LLC. +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## +## SPDX-License-Identifier: Apache-2.0 +## + +# +# Deployment of the CloudNativePG demo requirements: the CNPG operator, +# cert-manager, and the Barman Cloud Plugin. Sourced by demo/setup.sh. +# + +# Check whether a CRD exists in the given cluster context +check_crd_existence() { + local context="$1" + local crd="$2" + kubectl --context "${context}" get crd "${crd}" &>/dev/null +} + +# Deploy CloudNativePG, cert-manager, and the Barman Cloud Plugin into a +# single region, unless they are already installed there. +# Globals used: trunk, CERT_MANAGER_VERSION, CNPG_RELEASE_BRANCH, +# CNPG_VERSION_BARE, BARMAN_CLOUD_PLUGIN_VERSION (set by scripts/common.sh +# and demo/setup.sh). +deploy_cnpg_requirements() { + local region="$1" + local context="$2" + + if check_crd_existence "${context}" clusters.postgresql.cnpg.io; then + echo "ℹ️ CloudNativePG requirements already installed in region '${region}' (context: ${context});" \ + "skipping operator/cert-manager/Barman Cloud Plugin installation." + return + fi + + if [ "${trunk}" -eq 1 ]; then + # Deploy CloudNativePG operator (trunk - main branch) + curl -sSfL \ + https://raw.githubusercontent.com/cloudnative-pg/artifacts/main/manifests/operator-manifest.yaml | \ + kubectl --context "${context}" apply -f - --server-side + else + # Deploy CloudNativePG operator (latest stable release) + kubectl apply --server-side \ + --context "${context}" \ + -f "https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-${CNPG_RELEASE_BRANCH}/releases/cnpg-${CNPG_VERSION_BARE}.yaml" + fi + + # Pin the operator to the control-plane node. The playground taints the + # postgres nodes and reserves infra/app nodes for workloads, so the + # control-plane is the natural home for the operator in this demo. + kubectl --context "${context}" -n cnpg-system \ + patch deployment cnpg-controller-manager \ + --type='merge' \ + --patch='{"spec":{"template":{"spec":{"affinity":{"nodeAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"node-role.kubernetes.io/control-plane","operator":"Exists"}]}]}}},"tolerations":[{"key":"node-role.kubernetes.io/control-plane","operator":"Exists"}]}}}}' + + # Wait for CNPG deployment to complete + kubectl --context "${context}" rollout status deployment \ + -n cnpg-system cnpg-controller-manager + echo "📦 CloudNativePG: $(kubectl --context "${context}" get deployment cnpg-controller-manager \ + -n cnpg-system -o jsonpath='{.spec.template.spec.containers[0].image}')" + + # Deploy cert-manager + kubectl apply --context "${context}" -f \ + "https://github.com/cert-manager/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml" + + # Wait for cert-manager deployment to complete + kubectl rollout --context "${context}" status deployment \ + -n cert-manager + cmctl check api --wait=2m --context "${context}" + echo "📦 cert-manager: $(kubectl --context "${context}" get deployment cert-manager \ + -n cert-manager -o jsonpath='{.spec.template.spec.containers[0].image}')" + + if [ "${trunk}" -eq 1 ]; then + # Deploy Barman Cloud Plugin (trunk) + kubectl apply --context "${context}" -f \ + https://raw.githubusercontent.com/cloudnative-pg/plugin-barman-cloud/refs/heads/main/manifest.yaml + else + # Deploy Barman Cloud Plugin (latest stable) + kubectl apply --context "${context}" -f \ + "https://github.com/cloudnative-pg/plugin-barman-cloud/releases/download/${BARMAN_CLOUD_PLUGIN_VERSION}/manifest.yaml" + fi + + # Wait for Barman Cloud Plugin deployment to complete + kubectl rollout --context "${context}" status deployment \ + -n cnpg-system barman-cloud + echo "📦 Barman Cloud Plugin: $(kubectl --context "${context}" get deployment barman-cloud \ + -n cnpg-system -o jsonpath='{.spec.template.spec.containers[0].image}')" +} diff --git a/demo/setup.sh b/demo/setup.sh index c601d20..43a5419 100755 --- a/demo/setup.sh +++ b/demo/setup.sh @@ -25,10 +25,11 @@ # State synchronization is managed via S3 object storage backed by RustFS. # # Usage: -# ./demo/setup.sh [regions...] # specify regions (auto-detects running clusters if omitted) -# LEGACY=true ./demo/setup.sh # use in-tree Barman backup instead of plugin -# TRUNK=true ./demo/setup.sh # deploy from main branch (CNPG + Barman plugin) -# DEBUG=true ./demo/setup.sh # enable shell trace output (set -x) +# ./demo/setup.sh [regions...] # specify regions (auto-detects running clusters if omitted) +# LEGACY=true ./demo/setup.sh # use in-tree Barman backup instead of plugin +# TRUNK=true ./demo/setup.sh # deploy from main branch (CNPG + Barman plugin) +# REQUIREMENTS_ONLY=true ./demo/setup.sh # deploy CNPG + cert-manager + Barman plugin only +# DEBUG=true ./demo/setup.sh # enable shell trace output (set -x) # # Note: This environment is for learning purposes only and should not be # used in production. @@ -40,6 +41,9 @@ set -eu # Source the common setup script source "$(cd "$(dirname "$0")/.." && pwd)/scripts/common.sh" +# Source the CNPG operator/cert-manager/Barman Cloud Plugin deployment function +source "${REPO_ROOT}/demo/funcs_requirements.sh" + kube_config_path="${KUBE_CONFIG_PATH}" templates_dir="${TEMPLATES_DIR:-${REPO_ROOT}/demo/templates}" legacy_templates_dir="${templates_dir}/legacy" @@ -62,13 +66,6 @@ tmpl_cluster_legacy_params="${CLUSTER_LEGACY_PARAMS_TEMPLATE:-${legacy_templates tmpl_external_cluster_legacy="${EXTERNAL_CLUSTER_LEGACY_TEMPLATE:-${legacy_templates_dir}/external-cluster-legacy.yaml}" tmpl_scheduledbackup_legacy="${SCHEDULEDBACKUP_LEGACY_TEMPLATE:-${legacy_templates_dir}/scheduledbackup-legacy.yaml}" -# Check whether a CRD exists in the given cluster context -check_crd_existence() { - local context="$1" - local crd="$2" - kubectl --context "${context}" get crd "${crd}" &>/dev/null -} - legacy=false if [ "${LEGACY:-}" = "true" ]; then legacy=true @@ -79,6 +76,11 @@ if [ "${TRUNK:-}" = "true" ]; then trunk=1 fi +requirements_only=false +if [ "${REQUIREMENTS_ONLY:-}" = "true" ]; then + requirements_only=true +fi + dry_run=false if [ "${DRY_RUN:-}" = "true" ]; then dry_run=true @@ -265,66 +267,15 @@ for region in "${REGIONS[@]}"; do fi if ! ${dry_run}; then - if check_crd_existence "${CONTEXT_NAME}" clusters.postgresql.cnpg.io; then - echo "❌ CloudNativePG is already deployed in region '${region}' (context: ${CONTEXT_NAME})." - echo " Run './demo/teardown.sh' first if you want to redeploy." - exit 1 - fi + deploy_cnpg_requirements "${region}" "${CONTEXT_NAME}" fi - if ! ${dry_run}; then - if [ "${trunk}" -eq 1 ]; then - # Deploy CloudNativePG operator (trunk - main branch) - curl -sSfL \ - https://raw.githubusercontent.com/cloudnative-pg/artifacts/main/manifests/operator-manifest.yaml | \ - kubectl --context "${CONTEXT_NAME}" apply -f - --server-side - else - # Deploy CloudNativePG operator (latest stable release) - kubectl apply --server-side \ - --context "${CONTEXT_NAME}" \ - -f "https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-${CNPG_RELEASE_BRANCH}/releases/cnpg-${CNPG_VERSION_BARE}.yaml" + # REQUIREMENTS_ONLY stops here, before any cluster-specific resources are generated + if ${requirements_only}; then + if ! ${dry_run}; then + echo "✅ Requirements deployment for '${region}' complete in $(format_duration $((SECONDS - region_start)))." fi - - # Pin the operator to the control-plane node. The playground taints the - # postgres nodes and reserves infra/app nodes for workloads, so the - # control-plane is the natural home for the operator in this demo. - kubectl --context "${CONTEXT_NAME}" -n cnpg-system \ - patch deployment cnpg-controller-manager \ - --type='merge' \ - --patch='{"spec":{"template":{"spec":{"affinity":{"nodeAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"node-role.kubernetes.io/control-plane","operator":"Exists"}]}]}}},"tolerations":[{"key":"node-role.kubernetes.io/control-plane","operator":"Exists"}]}}}}' - - # Wait for CNPG deployment to complete - kubectl --context "${CONTEXT_NAME}" rollout status deployment \ - -n cnpg-system cnpg-controller-manager - echo "📦 CloudNativePG: $(kubectl --context "${CONTEXT_NAME}" get deployment cnpg-controller-manager \ - -n cnpg-system -o jsonpath='{.spec.template.spec.containers[0].image}')" - - # Deploy cert-manager - kubectl apply --context "${CONTEXT_NAME}" -f \ - "https://github.com/cert-manager/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml" - - # Wait for cert-manager deployment to complete - kubectl rollout --context "${CONTEXT_NAME}" status deployment \ - -n cert-manager - cmctl check api --wait=2m --context "${CONTEXT_NAME}" - echo "📦 cert-manager: $(kubectl --context "${CONTEXT_NAME}" get deployment cert-manager \ - -n cert-manager -o jsonpath='{.spec.template.spec.containers[0].image}')" - - if [ "${trunk}" -eq 1 ]; then - # Deploy Barman Cloud Plugin (trunk) - kubectl apply --context "${CONTEXT_NAME}" -f \ - https://raw.githubusercontent.com/cloudnative-pg/plugin-barman-cloud/refs/heads/main/manifest.yaml - else - # Deploy Barman Cloud Plugin (latest stable) - kubectl apply --context "${CONTEXT_NAME}" -f \ - "https://github.com/cloudnative-pg/plugin-barman-cloud/releases/download/${BARMAN_CLOUD_PLUGIN_VERSION}/manifest.yaml" - fi - - # Wait for Barman Cloud Plugin deployment to complete - kubectl rollout --context "${CONTEXT_NAME}" status deployment \ - -n cnpg-system barman-cloud - echo "📦 Barman Cloud Plugin: $(kubectl --context "${CONTEXT_NAME}" get deployment barman-cloud \ - -n cnpg-system -o jsonpath='{.spec.template.spec.containers[0].image}')" + continue fi # Create the Barman ObjectStore CRs for all regions (plugin mode only)