From b0ddcf3420bf74a52c42fbf5239244e83a40ec18 Mon Sep 17 00:00:00 2001 From: Neil Anderson Date: Thu, 27 Jun 2024 09:24:01 +0100 Subject: [PATCH] Adding support for legacy compilers --- .github/workflows/test-upgrade-legacy.yaml | 160 ++++++++++++++++++ functions/oid.pp | 1 + manifests/setup/legacy_compiler_group.pp | 30 ++++ manifests/setup/node_manager.pp | 24 +++ plans/convert_compiler_to_legacy.pp | 58 +++++++ plans/subplans/component_install.pp | 4 + plans/subplans/install.pp | 2 + plans/update_compiler_extensions.pp | 27 +++ plans/upgrade.pp | 21 ++- .../plans/provision_test_cluster.pp | 3 + 10 files changed, 328 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/test-upgrade-legacy.yaml create mode 100644 manifests/setup/legacy_compiler_group.pp create mode 100644 plans/convert_compiler_to_legacy.pp create mode 100644 plans/update_compiler_extensions.pp diff --git a/.github/workflows/test-upgrade-legacy.yaml b/.github/workflows/test-upgrade-legacy.yaml new file mode 100644 index 000000000..974f2524b --- /dev/null +++ b/.github/workflows/test-upgrade-legacy.yaml @@ -0,0 +1,160 @@ +--- +name: "Upgrade PE with one legacy compiler" + +on: + pull_request: + paths: + - ".github/workflows/**/*" + - "spec/**/*" + - "lib/**/*" + - "tasks/**/*" + - "functions/**/*" + - "types/**/*" + - "plans/**/*" + - "hiera/**/*" + - "manifests/**/*" + - "templates/**/*" + - "files/**/*" + - "metadata.json" + - "Rakefile" + - "Gemfile" + - "provision.yaml" + - ".rspec" + - ".rubocop.yml" + - ".puppet-lint.rc" + - ".fixtures.yml" + branches: [main] + workflow_dispatch: + ssh-debugging: + description: "Boolean; whether or not to pause for ssh debugging" + required: true + default: "false" + +jobs: + test-install: + name: "PE ${{ matrix.version }} ${{ matrix.architecture }} on ${{ matrix.image }}" + runs-on: ubuntu-20.04 + env: + BOLT_GEM: true + BOLT_DISABLE_ANALYTICS: true + LANG: "en_US.UTF-8" + strategy: + fail-fast: false + matrix: + architecture: + - "large-with-two-compilers" + image: + - "almalinux-cloud/almalinux-8" + version: + - "2023.6.0" + to_version: + - "2023.7.0" + + steps: + - name: "Start SSH session" + if: ${{ github.event.inputs.ssh-debugging == 'true' }} + uses: luchihoratiu/debug-via-ssh@main + with: + NGROK_AUTH_TOKEN: ${{ secrets.NGROK_AUTH_TOKEN }} + SSH_PASS: ${{ secrets.SSH_PASS }} + + - name: "Checkout Source" + uses: actions/checkout@v2 + + - name: "Activate Ruby 2.7" + uses: ruby/setup-ruby@v1 + with: + ruby-version: "2.7" + bundler-cache: true + + - name: "Print bundle environment" + if: ${{ github.repository_owner == 'puppetlabs' }} + run: | + echo ::group::info:bundler + bundle env + echo ::endgroup:: + + - name: "Provision test cluster" + timeout-minutes: 15 + run: | + echo ::group::prepare + mkdir -p $HOME/.ssh + echo 'Host *' > $HOME/.ssh/config + echo ' ServerAliveInterval 150' >> $HOME/.ssh/config + echo ' ServerAliveCountMax 2' >> $HOME/.ssh/config + bundle exec rake spec_prep + echo ::endgroup:: + + echo ::group::provision + bundle exec bolt plan run peadm_spec::provision_test_cluster \ + --modulepath spec/fixtures/modules \ + provider=provision_service \ + image=${{ matrix.image }} \ + architecture=${{ matrix.architecture }} + echo ::endgroup:: + + echo ::group::info:request + cat request.json || true; echo + echo ::endgroup:: + + echo ::group::info:inventory + sed -e 's/password: .*/password: "[redacted]"/' < spec/fixtures/litmus_inventory.yaml || true + echo ::endgroup:: + + - name: Set up yq + uses: frenck/action-setup-yq@v1 + with: + version: v4.30.5 + + - name: 'Install PE on test cluster' + timeout-minutes: 120 + run: | + bundle exec bolt plan run peadm_spec::install_test_cluster \ + --inventoryfile spec/fixtures/litmus_inventory.yaml \ + --modulepath spec/fixtures/modules \ + architecture="large" \ + version=${{ matrix.version }} + + - name: 'Wait as long as the file ${HOME}/pause file is present' + if: ${{ always() && github.event.inputs.ssh-debugging == 'true' }} + run: | + while [ -f "${HOME}/pause" ] ; do + echo "${HOME}/pause present, sleeping for 60 seconds..." + sleep 60 + done + echo "${HOME}/pause absent, continuing workflow." + + - name: 'Convert one compiler to legacy' + timeout-minutes: 120 + run: | + primary=$(yq '.groups[].targets[] | select(.vars.role == "primary") | .uri' spec/fixtures/litmus_inventory.yaml) + compiler=$(yq '.groups[].targets[] | select(.vars.role == "compiler") | .uri' spec/fixtures/litmus_inventory.yaml | head -n 1) + + bundle exec bolt plan run peadm::convert_compiler_to_legacy \ + --modulepath spec/fixtures/modules \ + primary_host=$primary \ + legacy_hosts=$compiler + + + - name: 'Upgrade PE on test cluster' + timeout-minutes: 120 + run: | + bundle exec bolt plan run peadm_spec::upgrade_test_cluster \ + --inventoryfile spec/fixtures/litmus_inventory.yaml \ + --modulepath spec/fixtures/modules \ + architecture="large" \ + version=${{ matrix.to_version }} + + - name: "Tear down test cluster" + if: ${{ always() }} + continue-on-error: true + run: | + if [ -f spec/fixtures/litmus_inventory.yaml ]; then + echo ::group::tear_down + bundle exec rake 'litmus:tear_down' + echo ::endgroup:: + + echo ::group::info:request + cat request.json || true; echo + echo ::endgroup:: + fi diff --git a/functions/oid.pp b/functions/oid.pp index 2fc735d03..0f03a43cc 100644 --- a/functions/oid.pp +++ b/functions/oid.pp @@ -4,6 +4,7 @@ function peadm::oid ( case $short_name { 'peadm_role': { '1.3.6.1.4.1.34380.1.1.9812' } 'peadm_availability_group': { '1.3.6.1.4.1.34380.1.1.9813' } + 'peadm_legacy_compiler': { '1.3.6.1.4.1.34380.1.1.9814' } 'pp_application': { '1.3.6.1.4.1.34380.1.1.8' } 'pp_cluster': { '1.3.6.1.4.1.34380.1.1.16' } 'pp_role': { '1.3.6.1.4.1.34380.1.1.13' } diff --git a/manifests/setup/legacy_compiler_group.pp b/manifests/setup/legacy_compiler_group.pp new file mode 100644 index 000000000..758fdf271 --- /dev/null +++ b/manifests/setup/legacy_compiler_group.pp @@ -0,0 +1,30 @@ +# @api private +class peadm::setup::legacy_compiler_group ( + String[1] $primary_host +) { + Node_group { + purge_behavior => none, + } + + node_group { 'PE Legacy Compiler': + parent => 'PE Master', + rule => ['and', + ['=', ['trusted', 'extensions', peadm::oid('peadm_legacy_compiler')], 'true'], + ['=', ['trusted', 'extensions', 'pp_auth_role'], 'pe_compiler'], + ], + classes => { + 'pe_repo' => {}, + 'puppet_enterprise::profile::master' => { 'code_manager_auto_configure' => true, 'replication_mode' => 'none' }, + }, + data => { + 'pe_repo' => { 'compile_master_pool_address' => $primary_host }, + }, + variables => { + 'pe_master' => true, + }, + } + + node_group { 'PE Compiler': + rule => ['and', ['=', ['trusted', 'extensions', peadm::oid('peadm_legacy_compiler')], 'false']], + } +} diff --git a/manifests/setup/node_manager.pp b/manifests/setup/node_manager.pp index a514b3572..ca08c099a 100644 --- a/manifests/setup/node_manager.pp +++ b/manifests/setup/node_manager.pp @@ -78,6 +78,12 @@ variables => { 'pe_master' => true }, } + # PE Compiler group comes from default PE and already has the pe compiler role + node_group { 'PE Compiler': + parent => 'PE Master', + rule => ['and', ['=', ['trusted', 'extensions', peadm::oid('peadm_legacy_compiler')], 'false']], + } + # This group should pin the primary, and also map to any pe-postgresql nodes # which are part of the architecture. node_group { 'PE Database': @@ -191,4 +197,22 @@ }, }, } + + node_group { 'PE Legacy Compiler': + parent => 'PE Master', + rule => ['and', + ['=', ['trusted', 'extensions', peadm::oid('peadm_legacy_compiler')], 'true'], + ['=', ['trusted', 'extensions', 'pp_auth_role'], 'pe_compiler'], + ], + classes => { + 'pe_repo' => {}, + 'puppet_enterprise::profile::master' => { 'code_manager_auto_configure' => true, 'replication_mode' => 'none' }, + }, + data => { + 'pe_repo' => { 'compile_master_pool_address' => $primary_host }, + }, + variables => { + 'pe_master' => true, + }, + } } diff --git a/plans/convert_compiler_to_legacy.pp b/plans/convert_compiler_to_legacy.pp new file mode 100644 index 000000000..69be62b3a --- /dev/null +++ b/plans/convert_compiler_to_legacy.pp @@ -0,0 +1,58 @@ +# @api private +plan peadm::convert_compiler_to_legacy ( + Peadm::SingleTargetSpec $primary_host, + TargetSpec $legacy_hosts, + Boolean $remove_pdb = false, +) { + $primary_target = peadm::get_targets($primary_host, 1) + $legacy_targets = peadm::get_targets($legacy_hosts) + + $cluster = run_task('peadm::get_peadm_config', $primary_host).first.value + $error = getvar('cluster.error') + if $error { + fail_plan($error) + } + + $all_targets = peadm::flatten_compact([ + getvar('cluster.params.primary_host'), + getvar('cluster.params.replica_host'), + getvar('cluster.params.primary_postgresql_host'), + getvar('cluster.params.replica_postgresql_host'), + getvar('cluster.params.compiler_hosts'), + ]) + + if $remove_pdb { + run_command('puppet resource service puppet ensure=stopped', $legacy_targets) + run_command('puppet resource service pe-puppetdb ensure=stopped enable=false', $legacy_targets) + } + + apply($primary_target) { + class { 'peadm::setup::node_manager_yaml': + primary_host => $primary_target.peadm::certname(), + } + + class { 'peadm::setup::legacy_compiler_group': + primary_host => $primary_target.peadm::certname(), + } + } + + run_plan('peadm::update_compiler_extensions', compiler_hosts => $legacy_targets, primary_host => $primary_target, legacy => true) + + run_task('peadm::puppet_runonce', $legacy_targets) + run_task('peadm::puppet_runonce', $primary_target) + run_task('peadm::puppet_runonce', $all_targets) + + if $remove_pdb { + run_command('puppet resource package pe-puppetdb ensure=purged', $legacy_targets) + run_command('puppet resource user pe-puppetdb ensure=absent', $legacy_targets) + + run_command('rm -rf /etc/puppetlabs/puppetdb', $legacy_targets) + run_command('rm -rf /var/log/puppetlabs/puppetdb', $legacy_targets) + run_command('rm -rf /opt/puppetlabs/server/data/puppetdb', $legacy_targets) + } + + run_command('systemctl start pe-puppetserver.service', $legacy_targets) + run_command('puppet resource service puppet ensure=running', $legacy_targets) + + return("Converted host ${legacy_targets} to legacy compiler.") +} diff --git a/plans/subplans/component_install.pp b/plans/subplans/component_install.pp index df74079e2..daf116880 100644 --- a/plans/subplans/component_install.pp +++ b/plans/subplans/component_install.pp @@ -22,6 +22,10 @@ peadm::oid('pp_auth_role') => 'pe_compiler', peadm::oid('peadm_availability_group') => $avail_group_letter, } + } elsif $role == 'pe_compiler_legacy' { + $certificate_extensions = { + peadm::oid('peadm_role') => $role, + } } else { $certificate_extensions = { peadm::oid('peadm_role') => $role, diff --git a/plans/subplans/install.pp b/plans/subplans/install.pp index 0ecbd6bf3..ed275a294 100644 --- a/plans/subplans/install.pp +++ b/plans/subplans/install.pp @@ -278,6 +278,7 @@ extension_requests => { peadm::oid('pp_auth_role') => 'pe_compiler', peadm::oid('peadm_availability_group') => 'A', + peadm::oid('peadm_legacy_compiler') => 'false', } ) }, @@ -286,6 +287,7 @@ extension_requests => { peadm::oid('pp_auth_role') => 'pe_compiler', peadm::oid('peadm_availability_group') => 'B', + peadm::oid('peadm_legacy_compiler') => 'false', } ) }, diff --git a/plans/update_compiler_extensions.pp b/plans/update_compiler_extensions.pp new file mode 100644 index 000000000..4ae45930c --- /dev/null +++ b/plans/update_compiler_extensions.pp @@ -0,0 +1,27 @@ +# @api private +plan peadm::update_compiler_extensions ( + TargetSpec $compiler_hosts, + Peadm::SingleTargetSpec $primary_host, + Boolean $legacy = false, +) { + $primary_target = peadm::get_targets($primary_host, 1) + $host_targets = peadm::get_targets($compiler_hosts) + + run_plan('peadm::modify_certificate', $host_targets, + primary_host => $primary_target, + add_extensions => { + peadm::oid('peadm_legacy_compiler') => "${legacy}", + }, + ) + + run_task('peadm::puppet_runonce', $primary_target) + run_task('peadm::puppet_runonce', $host_targets) + + if $legacy { + run_command('systemctl restart pe-puppetserver.service', $host_targets) + } else { + run_command('systemctl restart pe-puppetserver.service pe-puppetdb.service', $host_targets) + } + + return("Added legacy cert with value ${legacy} to compiler hosts ${compiler_hosts}") +} diff --git a/plans/upgrade.pp b/plans/upgrade.pp index 06ac068df..0f48e21d6 100644 --- a/plans/upgrade.pp +++ b/plans/upgrade.pp @@ -167,11 +167,25 @@ == $cert_extensions.dig($primary_target[0].peadm::certname, peadm::oid('peadm_availability_group'))) } + $compiler_m1_nonlegacy_targets = $compiler_targets.filter |$target| { + ($cert_extensions.dig($target.peadm::certname, peadm::oid('peadm_availability_group')) + == $cert_extensions.dig($primary_target[0].peadm::certname, peadm::oid('peadm_availability_group'))) and + ($cert_extensions.dig($target.peadm::certname, peadm::oid('peadm_legacy_compiler')) + == 'false') + } + $compiler_m2_targets = $compiler_targets.filter |$target| { ($cert_extensions.dig($target.peadm::certname, peadm::oid('peadm_availability_group')) == $cert_extensions.dig($replica_target[0].peadm::certname, peadm::oid('peadm_availability_group'))) } + $compiler_m2_nonlegacy_targets = $compiler_targets.filter |$target| { + ($cert_extensions.dig($target.peadm::certname, peadm::oid('peadm_availability_group')) + == $cert_extensions.dig($replica_target[0].peadm::certname, peadm::oid('peadm_availability_group'))) and + ($cert_extensions.dig($target.peadm::certname, peadm::oid('peadm_legacy_compiler')) + == 'false') + } + peadm::plan_step('preparation') || { if $download_mode == 'bolthost' { # Download the PE tarball on the nodes that need it @@ -239,7 +253,7 @@ peadm::plan_step('upgrade-primary') || { # Shut down PuppetDB on CMs that use the PM's PDB PG. Use run_command instead # of run_task(service, ...) so that upgrading from 2018.1 works over PCP. - run_command('systemctl stop pe-puppetdb', $compiler_m1_targets) + run_command('systemctl stop pe-puppetdb', $compiler_m1_nonlegacy_targets) run_task('peadm::pe_install', $primary_postgresql_target, tarball => $upload_tarball_path, @@ -263,6 +277,9 @@ $primary_target, $primary_postgresql_target, ])) + + # Running again to ensure that the primary is fully upgraded + run_task('peadm::puppet_runonce', $primary_target) } peadm::plan_step('upgrade-node-groups') || { @@ -341,7 +358,7 @@ # Shut down PuppetDB on CMs that use the replica's PDB PG. Use run_command # instead of run_task(service, ...) so that upgrading from 2018.1 works # over PCP. - run_command('systemctl stop pe-puppetdb', $compiler_m2_targets) + run_command('systemctl stop pe-puppetdb', $compiler_m2_nonlegacy_targets) run_task('peadm::pe_install', $replica_postgresql_target, tarball => $upload_tarball_path, diff --git a/spec/acceptance/peadm_spec/plans/provision_test_cluster.pp b/spec/acceptance/peadm_spec/plans/provision_test_cluster.pp index a3a18d4ef..8af5be93f 100644 --- a/spec/acceptance/peadm_spec/plans/provision_test_cluster.pp +++ b/spec/acceptance/peadm_spec/plans/provision_test_cluster.pp @@ -14,6 +14,9 @@ 'large': { ['primary', 'compiler'] } + 'large-with-two-compilers': { + ['primary', 'compiler', 'compiler'] + } 'large-with-dr': { ['primary', 'compiler', 'replica', 'compiler'] }