From 10e61edbc7b40fffdfb0404b41c3bd4f61f30a5f Mon Sep 17 00:00:00 2001 From: Tellsanguis Date: Thu, 27 Nov 2025 12:41:39 +0100 Subject: [PATCH] fix(cicd): Execute LINSTOR script in Docker container via SSH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Modifie le script Python pour supporter l'exécution via SSH - Ajoute paramètre --remote-host pour spécifier l'hôte LINSTOR - Installe Python3 dans le container Docker (sans sudo) - Le script s'exécute dans le container et communique avec LINSTOR via SSH - Résout l'erreur 'sudo: command not found' dans les containers Docker --- .forgejo/workflows/deploy.yml | 16 +++++------- scripts/manage_linstor_resources.py | 39 ++++++++++++++++++++--------- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml index 6d71344..01b8361 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/deploy.yml @@ -83,13 +83,11 @@ jobs: fi - name: Setup Python run: | - sudo apt-get update && sudo apt-get install -y python3 + apt-get update && apt-get install -y python3 - name: Prepare LINSTOR resources for pve1 run: | - # Copie le script sur le noeud et exécute avec lecture automatique depuis Terraform - scp scripts/manage_linstor_resources.py root@acemagician:/tmp/ - scp -r terraform root@acemagician:/tmp/ - ssh root@acemagician "python3 /tmp/manage_linstor_resources.py --terraform-dir /tmp/terraform --verbose" + # Exécute le script dans le container, qui utilisera SSH pour communiquer avec LINSTOR + python3 scripts/manage_linstor_resources.py --terraform-dir terraform --remote-host thinkpad --verbose - name: Terraform Apply on pve1 run: | cd terraform/pve1 @@ -127,13 +125,11 @@ jobs: fi - name: Setup Python run: | - sudo apt-get update && sudo apt-get install -y python3 + apt-get update && apt-get install -y python3 - name: Prepare LINSTOR resources for pve2 run: | - # Copie le script sur le noeud et exécute avec lecture automatique depuis Terraform - scp scripts/manage_linstor_resources.py root@elitedesk:/tmp/ - scp -r terraform root@elitedesk:/tmp/ - ssh root@elitedesk "python3 /tmp/manage_linstor_resources.py --terraform-dir /tmp/terraform --verbose" + # Exécute le script dans le container, qui utilisera SSH pour communiquer avec LINSTOR + python3 scripts/manage_linstor_resources.py --terraform-dir terraform --remote-host thinkpad --verbose - name: Terraform Apply on pve2 run: | cd terraform/pve2 diff --git a/scripts/manage_linstor_resources.py b/scripts/manage_linstor_resources.py index 52eb66f..4d71299 100644 --- a/scripts/manage_linstor_resources.py +++ b/scripts/manage_linstor_resources.py @@ -50,17 +50,30 @@ RESOURCE_CONFIG = { class LinstorManager: """Gestionnaire des ressources LINSTOR""" - def __init__(self, verbose=False): + def __init__(self, verbose=False, remote_host=None): self.verbose = verbose + self.remote_host = remote_host # Hôte sur lequel exécuter les commandes LINSTOR via SSH def log(self, message): """Affiche un message de log si le mode verbose est activé""" if self.verbose: print(f"[INFO] {message}") - def run_command(self, command): - """Exécute une commande shell et retourne la sortie""" - self.log(f"Exécution: {' '.join(command)}") + def run_command(self, command, remote_host=None): + """Exécute une commande shell et retourne la sortie + + Args: + command: Liste de commandes à exécuter + remote_host: Si spécifié, exécute la commande via SSH sur cet hôte + """ + if remote_host: + # Construit la commande SSH + ssh_command = ['ssh', f'root@{remote_host}'] + command + self.log(f"Exécution SSH sur {remote_host}: {' '.join(command)}") + command = ssh_command + else: + self.log(f"Exécution locale: {' '.join(command)}") + try: result = subprocess.run( command, @@ -108,7 +121,7 @@ class LinstorManager: def resource_exists(self, resource_name): """Vérifie si une définition de ressource LINSTOR existe""" - output = self.run_command(['linstor', 'resource-definition', 'list', '--machine-readable']) + output = self.run_command(['linstor', 'resource-definition', 'list', '--machine-readable'], self.remote_host) if output is None: return False @@ -125,7 +138,7 @@ class LinstorManager: def get_resource_size(self, resource_name): """Récupère la taille actuelle d'un volume de ressource (en octets)""" - output = self.run_command(['linstor', 'volume-definition', 'list', '--machine-readable']) + output = self.run_command(['linstor', 'volume-definition', 'list', '--machine-readable'], self.remote_host) if output is None: return None @@ -146,7 +159,7 @@ class LinstorManager: def get_resource_nodes(self, resource_name): """Récupère la liste des nœuds où la ressource est déployée""" - output = self.run_command(['linstor', 'resource', 'list', '--machine-readable']) + output = self.run_command(['linstor', 'resource', 'list', '--machine-readable'], self.remote_host) if output is None: return [] @@ -166,7 +179,7 @@ class LinstorManager: def create_resource_definition(self, resource_name): """Crée une définition de ressource LINSTOR""" self.log(f"Création de la définition de ressource '{resource_name}'") - output = self.run_command(['linstor', 'resource-definition', 'create', resource_name]) + output = self.run_command(['linstor', 'resource-definition', 'create', resource_name], self.remote_host) if output is None: return False print(f"✓ Définition de ressource '{resource_name}' créée") @@ -175,7 +188,7 @@ class LinstorManager: def create_volume_definition(self, resource_name, size): """Crée une définition de volume LINSTOR""" self.log(f"Création de la définition de volume pour '{resource_name}' avec taille {size}") - output = self.run_command(['linstor', 'volume-definition', 'create', resource_name, size]) + output = self.run_command(['linstor', 'volume-definition', 'create', resource_name, size], self.remote_host) if output is None: return False print(f"✓ Définition de volume créée pour '{resource_name}' avec taille {size}") @@ -188,7 +201,7 @@ class LinstorManager: 'linstor', 'resource', 'create', node, resource_name, '--storage-pool', storage_pool - ]) + ], self.remote_host) if output is None: return False print(f"✓ Ressource '{resource_name}' créée sur le nœud '{node}'") @@ -200,7 +213,7 @@ class LinstorManager: output = self.run_command([ 'linstor', 'volume-definition', 'set-size', resource_name, '0', new_size - ]) + ], self.remote_host) if output is None: return False print(f"✓ Volume '{resource_name}' redimensionné à {new_size}") @@ -362,11 +375,13 @@ def main(): parser.add_argument('--storage-pool', help='Nom du pool de stockage (ex: pve-storage)') parser.add_argument('--terraform-dir', help='Chemin vers le répertoire Terraform pour lecture automatique de la config') parser.add_argument('--all', action='store_true', help='Traiter toutes les ressources configurées') + parser.add_argument('--remote-host', help='Hôte sur lequel exécuter les commandes LINSTOR via SSH (ex: thinkpad)') parser.add_argument('--verbose', '-v', action='store_true', help='Active la sortie détaillée') args = parser.parse_args() - manager = LinstorManager(verbose=args.verbose) + # Utilise --remote-host si spécifié, sinon utilise le premier noeud trouvé dans la config + manager = LinstorManager(verbose=args.verbose, remote_host=args.remote_host) # Mode 1: Lecture automatique depuis Terraform if args.terraform_dir: