84 lines
2.9 KiB
Python
84 lines
2.9 KiB
Python
import paramiko
|
|
import sys
|
|
import time
|
|
|
|
sys.stdout.reconfigure(encoding='utf-8')
|
|
|
|
KEY_FILE = r'C:\Users\Snarf\.ssh\id_ed25519_snarfnet'
|
|
TARGET_IP = '140.44.4.75'
|
|
TARGET_NAME = 'snshpd4lnxswm05'
|
|
|
|
print(f"=== TESTING ROLLING OS UPDATE ON SWARM NODE {TARGET_NAME} ({TARGET_IP}) ===")
|
|
|
|
ssh = paramiko.SSHClient()
|
|
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
ssh.connect(TARGET_IP, username='snarf', key_filename=KEY_FILE, timeout=10)
|
|
|
|
upgrade_cmd = """
|
|
echo "debconf debconf/frontend select Noninteractive" | sudo debconf-set-selections
|
|
echo "linux-base linux-base/removing-running-kernel boolean false" | sudo debconf-set-selections
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
sudo apt-get update -qq
|
|
sudo apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade -y
|
|
sudo apt-get autoremove -y
|
|
"""
|
|
|
|
print("[*] Running apt dist-upgrade...")
|
|
stdin, stdout, stderr = ssh.exec_command(upgrade_cmd)
|
|
exit_code = stdout.channel.recv_exit_status()
|
|
print(f"[*] apt dist-upgrade exit code: {exit_code}")
|
|
|
|
# Check reboot
|
|
stdin, stdout, stderr = ssh.exec_command("test -f /var/run/reboot-required && echo 'yes' || echo 'no'")
|
|
reboot_needed = stdout.read().decode().strip() == 'yes'
|
|
print(f"[*] Reboot required: {reboot_needed}")
|
|
|
|
if reboot_needed:
|
|
print("[*] Gracefully rebooting node...")
|
|
try:
|
|
ssh.exec_command("sudo reboot")
|
|
except Exception:
|
|
pass
|
|
ssh.close()
|
|
|
|
print("[*] Waiting 30s for node to reboot...")
|
|
time.sleep(30)
|
|
|
|
reconnected = False
|
|
for attempt in range(25):
|
|
try:
|
|
ssh = paramiko.SSHClient()
|
|
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
ssh.connect(TARGET_IP, username='snarf', key_filename=KEY_FILE, timeout=6)
|
|
reconnected = True
|
|
print(f"[*] Node reconnected on attempt {attempt+1}!")
|
|
break
|
|
except Exception:
|
|
time.sleep(4)
|
|
|
|
if not reconnected:
|
|
print("[!] ERROR: Node failed to reconnect!")
|
|
sys.exit(1)
|
|
|
|
_, out, _ = ssh.exec_command("sudo systemctl is-active docker")
|
|
print(" Docker service:", out.read().decode().strip())
|
|
_, out, _ = ssh.exec_command("systemctl is-active systemd-timesyncd || systemctl is-active chrony")
|
|
print(" TimeSync:", out.read().decode().strip())
|
|
_, out, _ = ssh.exec_command("systemctl is-active zabbix-agent2")
|
|
print(" ZabbixAgent2:", out.read().decode().strip())
|
|
ssh.close()
|
|
else:
|
|
ssh.close()
|
|
|
|
# Verify on Swarm Leader (140.44.4.73)
|
|
leader_ssh = paramiko.SSHClient()
|
|
leader_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
leader_ssh.connect('140.44.4.73', username='snarf', key_filename=KEY_FILE, timeout=10)
|
|
_, out, _ = leader_ssh.exec_command('sudo docker node ls')
|
|
print("\n=== SWARM NODES FROM LEADER ===")
|
|
print(out.read().decode())
|
|
leader_ssh.close()
|
|
|
|
print(f"[SUCCESS] Swarm node {TARGET_NAME} updated cleanly!")
|
|
|