(MAINT) test vmpooler #1011
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
name: Install test matrix | |
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: {} | |
jobs: | |
test-install: | |
name: PE ${{ matrix.version }} ${{ matrix.architecture }} on ${{ matrix.image }} | |
runs-on: ubuntu-latest | |
env: | |
BOLT_GEM: true | |
BOLT_DISABLE_ANALYTICS: true | |
LANG: en_US.UTF-8 | |
strategy: | |
fail-fast: false | |
matrix: | |
architecture: [standard-with-dr] | |
version: [2025.6.0] | |
image: [litmusimage/ubuntu:24.04] | |
steps: | |
- name: Checkout Source | |
uses: actions/checkout@v4 | |
- name: Activate Ruby 3.1 | |
uses: ruby/setup-ruby@v1 | |
with: | |
ruby-version: '3.1' | |
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 | |
echo ' StrictHostKeyChecking no' >> $HOME/.ssh/config | |
echo ' UserKnownHostsFile /dev/null' >> $HOME/.ssh/config | |
echo ' ConnectTimeout 30' >> $HOME/.ssh/config | |
echo ' ConnectionAttempts 10' >> $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=docker \ | |
image=${{ matrix.image }} \ | |
architecture=${{ matrix.architecture }} \ | |
--log-level trace | |
echo ::endgroup:: | |
echo ::group::list modules | |
ls -l ./spec/fixtures/modules || true; echo | |
echo ::endgroup:: | |
echo ::group::update every 'ssh:' tag in ./inventory.yaml file to add 'native-ssh: true' under install_test_cluster and indent correctly | |
sed -i -e '/ssh:/a\ native-ssh: true' ./inventory.yaml || true; echo | |
# Also add additional SSH options for container environments | |
sed -i -e '/ssh:/a\ connect-timeout: 30' ./inventory.yaml || true; echo | |
sed -i -e '/ssh:/a\ host-key-check: false' ./inventory.yaml || true; echo | |
# Set root credentials if not already present | |
sed -i -e '/ssh:/a\ user: root' ./inventory.yaml || true; echo | |
sed -i -e '/ssh:/a\ password: root' ./inventory.yaml || true; echo | |
echo ::endgroup:: | |
echo ::group::fix inventory credentials | |
# Backup original inventory | |
cp ./inventory.yaml ./inventory.yaml.backup | |
# Remove any existing SSH user/password entries and add correct ones | |
sed -i '/user:/d' ./inventory.yaml | |
sed -i '/password:/d' ./inventory.yaml | |
sed -i '/host-key-check:/d' ./inventory.yaml | |
sed -i '/connect-timeout:/d' ./inventory.yaml | |
sed -i '/native-ssh:/d' ./inventory.yaml | |
# Add correct SSH configuration after each 'ssh:' line | |
sed -i '/ssh:/a\ user: root' ./inventory.yaml | |
sed -i '/ssh:/a\ password: root' ./inventory.yaml | |
sed -i '/ssh:/a\ host-key-check: false' ./inventory.yaml | |
sed -i '/ssh:/a\ connect-timeout: 30' ./inventory.yaml | |
sed -i '/ssh:/a\ native-ssh: true' ./inventory.yaml | |
echo "=== Updated inventory.yaml ===" | |
cat ./inventory.yaml | |
echo ::endgroup:: | |
echo ::group::list contents of ./inventory.yaml | |
ls -l ./inventory.yaml || true; echo | |
cat ./inventory.yaml || true; echo | |
echo ::endgroup:: | |
echo ::group::list contents of spec/docker/inventory.yaml | |
ls -l ./spec/docker/inventory.yaml || true; echo | |
cat ./spec/docker/inventory.yaml || true; echo | |
echo ::endgroup:: | |
echo ::group::info:request | |
cat request.json || true; echo | |
echo ::endgroup:: | |
- name: Debug container setup | |
run: | | |
echo ::group::debug_container_setup | |
for container in $(docker ps --format "table {{.Names}}" | tail -n +2); do | |
echo "=== Container: $container ===" | |
# Check if SSH service is actually running | |
echo "SSH service status:" | |
docker exec $container systemctl is-active ssh || docker exec $container service ssh status || echo "SSH service check failed" | |
# Check SSH daemon logs | |
echo "SSH daemon logs:" | |
docker exec $container journalctl -u ssh --no-pager -n 10 || docker exec $container tail -10 /var/log/auth.log || echo "No SSH logs found" | |
# Check root password is set | |
echo "Root account status:" | |
docker exec $container passwd -S root || echo "Cannot check root account" | |
# Try to manually set root password | |
echo "Setting root password to 'root':" | |
docker exec $container bash -c 'echo "root:root" | chpasswd' || echo "Failed to set root password" | |
# Check authorized_keys | |
echo "Authorized keys:" | |
docker exec $container cat /root/.ssh/authorized_keys 2>/dev/null || echo "No authorized_keys file" | |
# Check if we can exec into container | |
echo "Test container exec:" | |
docker exec $container whoami || echo "Cannot exec into container" | |
done | |
echo ::endgroup:: | |
- name: Debug SSH connectivity | |
run: | | |
echo ::group::debug_ssh_connectivity | |
# Install sshpass for password authentication | |
sudo apt-get update && sudo apt-get install -y sshpass | |
# Check if containers are running | |
docker ps | |
# Check SSH processes in containers | |
for container in $(docker ps --format "table {{.Names}}" | tail -n +2); do | |
echo "Testing SSH to container: $container" | |
echo "SSH processes in $container:" | |
docker exec $container ps aux | grep sshd || echo "No sshd processes found in $container" | |
# Test SSH connectivity directly with password | |
echo "Testing direct SSH connection to $container:" | |
container_ip=$(docker inspect $container | jq -r '.[0].NetworkSettings.IPAddress') | |
echo "Container IP: $container_ip" | |
# Get the mapped SSH port | |
ssh_port=$(docker port $container 22 | cut -d: -f2) | |
echo "SSH port mapping: localhost:$ssh_port -> $container:22" | |
# Test SSH connection with sshpass and root password | |
echo "Testing SSH with sshpass and root/root:" | |
timeout 10 sshpass -p "root" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 -p $ssh_port root@localhost 'echo "SSH connection successful to '$container'"' || echo "SSH connection failed to $container" | |
# Also check what's actually listening on the SSH port | |
echo "Checking what's listening on port $ssh_port:" | |
netstat -ln | grep ":$ssh_port " || echo "Nothing listening on port $ssh_port" | |
# Check SSH config inside container | |
echo "SSH configuration in $container:" | |
docker exec $container cat /etc/ssh/sshd_config | grep -E "(PasswordAuthentication|PermitRootLogin|PubkeyAuthentication)" || true | |
# Check if root account is set up correctly | |
echo "Root account info in $container:" | |
docker exec $container passwd -S root || true | |
done | |
echo ::endgroup:: | |
- name: Wait for SSH to be ready | |
run: | | |
echo ::group::wait_for_ssh | |
# Wait for SSH to be available on all containers via Bolt | |
for i in {1..12}; do | |
echo "Attempt $i: Testing Bolt SSH connectivity..." | |
# Use inventory settings only (don't override with CLI args) | |
if bundle exec bolt command run 'echo "Bolt SSH test successful"' \ | |
--inventoryfile ./inventory.yaml \ | |
--targets all; then | |
echo "All containers are accessible via Bolt SSH!" | |
break | |
fi | |
if [ $i -eq 12 ]; then | |
echo "Containers failed to become accessible after 12 attempts" | |
echo "Final inventory check:" | |
cat ./inventory.yaml | |
echo "=== Docker container status ===" | |
docker ps | |
exit 1 | |
fi | |
echo "Waiting 10 seconds before retry..." | |
sleep 10 | |
done | |
echo ::endgroup:: | |
- name: Check container SSH configuration | |
run: | | |
echo ::group::container_ssh_config | |
for container in $(docker ps --format "table {{.Names}}" | tail -n +2); do | |
echo "=== SSH config for $container ===" | |
docker exec $container cat /etc/ssh/sshd_config | grep -E "(PasswordAuthentication|PubkeyAuthentication|PermitRootLogin)" || true | |
echo "=== Test password auth ===" | |
ssh_port=$(docker port $container 22 | cut -d: -f2) | |
# Try common passwords | |
for password in "root" "password" "litmus"; do | |
echo "Trying password: $password" | |
timeout 5 sshpass -p "$password" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 -p $ssh_port root@localhost 'echo "Password auth successful with: $password"' && break | |
done || echo "Password authentication failed" | |
done | |
echo ::endgroup:: | |
- name: Install PE on test cluster | |
timeout-minutes: 120 | |
run: | | |
bundle exec bolt plan run peadm_spec::install_test_cluster \ | |
--inventoryfile ./inventory.yaml \ | |
--modulepath spec/fixtures/modules \ | |
architecture=${{ matrix.architecture }} \ | |
version=${{ matrix.version }} \ | |
console_password=${{ secrets.CONSOLE_PASSWORD }} | |
- 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 |