[IMP] script todo: default erplibre/erplibre login + ~/.ssh/config entry
VMs were created with user "erplibre" but NO password (lock_passwd: true), so the serial console refused every login and only SSH-by-key worked — hence "can't connect". - The todo deploy flow (single VM and infra) now sets a default console password "erplibre" for the "erplibre" user, in addition to the SSH key, so virsh console and password SSH both work. It is shown as "Console/SSH login: erplibre / erplibre" and can be changed at the single-VM prompt. - The console entry now prints the default login and the Ctrl+] hint. - After creating a VM, offer to add it to ~/.ssh/config (Host <name>, HostName <ip>, User erplibre) so "ssh <name>" just works; the infra flow asks once and adds every VM. Existing blocks for the same Host are replaced, the rest of the file is preserved, mode kept 600. Note: VMs created before this change have no console password — delete and redeploy them to get the erplibre/erplibre login. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9876a03ac7
commit
78e7cf55c6
2 changed files with 108 additions and 7 deletions
|
|
@ -954,11 +954,15 @@ class TODO:
|
|||
# sous sudo (HOME=/root) et ne pourrait pas déduire ~ correctement.
|
||||
ssh_key = os.path.expanduser(ssh_key)
|
||||
|
||||
use_password = False
|
||||
if not ssh_key:
|
||||
ans = input(t("No SSH key found. Set a password instead? (Y/n): "))
|
||||
# Défaut oui : tout sauf une réponse négative explicite vaut oui.
|
||||
use_password = not self._is_no(ans)
|
||||
# Mot de passe console (défaut « erplibre ») : permet la connexion par
|
||||
# la console série (virsh console) EN PLUS de la clé SSH. Sans lui, le
|
||||
# compte est verrouillé et la console refuse tout login.
|
||||
password = (
|
||||
input(
|
||||
t("Console password for 'erplibre' (default: erplibre): ")
|
||||
).strip()
|
||||
or "erplibre"
|
||||
)
|
||||
|
||||
force = False
|
||||
if not dry_run:
|
||||
|
|
@ -978,8 +982,8 @@ class TODO:
|
|||
parts += ["--disk-size", disk_size]
|
||||
if ssh_key:
|
||||
parts += ["--ssh-key", ssh_key]
|
||||
if use_password:
|
||||
parts.append("--ask-password")
|
||||
if password:
|
||||
parts += ["--password", password]
|
||||
if force:
|
||||
parts.append("--force")
|
||||
if dry_run:
|
||||
|
|
@ -989,8 +993,14 @@ class TODO:
|
|||
|
||||
cmd = " ".join(shlex.quote(p) for p in parts)
|
||||
print(f"{t('Will execute:')} {cmd}")
|
||||
if password:
|
||||
print(f"🔑 {t('Console/SSH login:')} erplibre / {password}")
|
||||
self.execute.exec_command_live(cmd, source_erplibre=False)
|
||||
|
||||
# Proposer d'enregistrer la VM dans ~/.ssh/config (après le 1er boot).
|
||||
if not dry_run:
|
||||
self._qemu_offer_ssh_config(name, "erplibre")
|
||||
|
||||
def _qemu_download_image(self):
|
||||
script_path = self._qemu_script_path()
|
||||
distro = self._qemu_prompt_distro()
|
||||
|
|
@ -1047,10 +1057,52 @@ class TODO:
|
|||
print(t("VM name is required!"))
|
||||
return
|
||||
print(f"\n💡 {t('To leave the console, press Ctrl+] (then Enter).')}")
|
||||
print(
|
||||
f"👤 {t('Default login (if set at deploy): erplibre / erplibre')}"
|
||||
)
|
||||
cmd = f"sudo virsh console {shlex.quote(name)}"
|
||||
print(f"{t('Will execute:')} {cmd}")
|
||||
self.execute.exec_command_live(cmd, source_erplibre=False)
|
||||
|
||||
def _qemu_offer_ssh_config(self, name, user):
|
||||
"""Propose d'enregistrer la VM dans ~/.ssh/config (bloc Host name)."""
|
||||
if not self._is_yes(input(t("Add this VM to ~/.ssh/config? (y/N): "))):
|
||||
return
|
||||
print(t("Waiting for the VM IP (DHCP lease)..."))
|
||||
ip = self._qemu_vm_ip(name)
|
||||
if not ip:
|
||||
print(t("No IP yet; add it later once the VM has booted."))
|
||||
return
|
||||
self._write_ssh_config_entry(name, user, ip)
|
||||
|
||||
def _write_ssh_config_entry(self, host, user, ip):
|
||||
"""Écrit/remplace un bloc « Host <host> » dans ~/.ssh/config."""
|
||||
cfg = os.path.expanduser("~/.ssh/config")
|
||||
os.makedirs(os.path.dirname(cfg), exist_ok=True)
|
||||
existing = ""
|
||||
if os.path.exists(cfg):
|
||||
with open(cfg, encoding="utf-8") as fh:
|
||||
existing = fh.read()
|
||||
# Retire un ancien bloc du même Host (jusqu'au prochain Host / EOF).
|
||||
pattern = re.compile(
|
||||
rf"(?ms)^[ \t]*Host[ \t]+{re.escape(host)}[ \t]*\n"
|
||||
r"(?:[ \t]+.*\n?)*"
|
||||
)
|
||||
existing = pattern.sub("", existing).rstrip("\n")
|
||||
block = (
|
||||
f"Host {host}\n"
|
||||
f" HostName {ip}\n"
|
||||
f" User {user}\n"
|
||||
# IP DHCP réutilisées entre VM -> on évite l'erreur de clé d'hôte.
|
||||
f" StrictHostKeyChecking no\n"
|
||||
f" UserKnownHostsFile /dev/null\n"
|
||||
)
|
||||
content = (existing + "\n\n" + block) if existing else block
|
||||
with open(cfg, "w", encoding="utf-8") as fh:
|
||||
fh.write(content)
|
||||
os.chmod(cfg, 0o600)
|
||||
print(f"✅ {t('Added to ~/.ssh/config:')} ssh {host}")
|
||||
|
||||
def _qemu_list_domains(self):
|
||||
"""Noms des VM libvirt définies (via virsh)."""
|
||||
try:
|
||||
|
|
@ -1377,6 +1429,10 @@ class TODO:
|
|||
if self._is_yes(ans):
|
||||
install_branch = self._qemu_pick_branch()
|
||||
|
||||
add_ssh_config = self._is_yes(
|
||||
input(t("Add each VM to ~/.ssh/config? (y/N): "))
|
||||
)
|
||||
|
||||
# 5) Confirmation puis déploiement séquentiel.
|
||||
ans = input(f"\n{t('Deploy these VMs now? (y/N): ')}")
|
||||
if not self._is_yes(ans):
|
||||
|
|
@ -1403,6 +1459,9 @@ class TODO:
|
|||
]
|
||||
if ssh_key:
|
||||
parts += ["--ssh-key", ssh_key]
|
||||
# Mot de passe console par défaut « erplibre » (login virsh
|
||||
# console + SSH par mot de passe), en plus de la clé.
|
||||
parts += ["--password", "erplibre"]
|
||||
if install_branch:
|
||||
parts += ["--package", "git"]
|
||||
parts.append("-y")
|
||||
|
|
@ -1410,6 +1469,10 @@ class TODO:
|
|||
print(f"\n▶ {name}: {cmd}")
|
||||
self.execute.exec_command_live(cmd, source_erplibre=False)
|
||||
deployed.append(name)
|
||||
if add_ssh_config:
|
||||
ip = self._qemu_vm_ip(name)
|
||||
if ip:
|
||||
self._write_ssh_config_entry(name, "erplibre", ip)
|
||||
|
||||
# 6) Installation ERPLibre (clone) si demandée.
|
||||
if install_branch:
|
||||
|
|
@ -1418,6 +1481,7 @@ class TODO:
|
|||
self._qemu_install_erplibre_vm(name, ssh_key, install_branch)
|
||||
|
||||
print(f"\n✅ {t('ERPLibre infra deployment done.')}")
|
||||
print(f" {t('Default login:')} erplibre / erplibre")
|
||||
print(f" {t('Manage with:')} sudo virsh list --all")
|
||||
|
||||
def _deploy_clone_erplibre(self):
|
||||
|
|
|
|||
|
|
@ -229,6 +229,43 @@ TRANSLATIONS = {
|
|||
"fr": "Pour quitter la console, appuyez sur Ctrl+] (puis Entrée).",
|
||||
"en": "To leave the console, press Ctrl+] (then Enter).",
|
||||
},
|
||||
"Default login (if set at deploy): erplibre / erplibre": {
|
||||
"fr": "Login par défaut (si défini au déploiement) : "
|
||||
"erplibre / erplibre",
|
||||
"en": "Default login (if set at deploy): erplibre / erplibre",
|
||||
},
|
||||
"Console password for 'erplibre' (default: erplibre): ": {
|
||||
"fr": "Mot de passe console pour « erplibre » (défaut : erplibre) : ",
|
||||
"en": "Console password for 'erplibre' (default: erplibre): ",
|
||||
},
|
||||
"Console/SSH login:": {
|
||||
"fr": "Connexion console/SSH :",
|
||||
"en": "Console/SSH login:",
|
||||
},
|
||||
"Default login:": {
|
||||
"fr": "Login par défaut :",
|
||||
"en": "Default login:",
|
||||
},
|
||||
"Add this VM to ~/.ssh/config? (y/N): ": {
|
||||
"fr": "Ajouter cette VM à ~/.ssh/config ? (o/N) : ",
|
||||
"en": "Add this VM to ~/.ssh/config? (y/N): ",
|
||||
},
|
||||
"Add each VM to ~/.ssh/config? (y/N): ": {
|
||||
"fr": "Ajouter chaque VM à ~/.ssh/config ? (o/N) : ",
|
||||
"en": "Add each VM to ~/.ssh/config? (y/N): ",
|
||||
},
|
||||
"Waiting for the VM IP (DHCP lease)...": {
|
||||
"fr": "Attente de l'IP de la VM (bail DHCP)...",
|
||||
"en": "Waiting for the VM IP (DHCP lease)...",
|
||||
},
|
||||
"No IP yet; add it later once the VM has booted.": {
|
||||
"fr": "Pas encore d'IP ; à ajouter plus tard une fois la VM démarrée.",
|
||||
"en": "No IP yet; add it later once the VM has booted.",
|
||||
},
|
||||
"Added to ~/.ssh/config:": {
|
||||
"fr": "Ajouté à ~/.ssh/config :",
|
||||
"en": "Added to ~/.ssh/config:",
|
||||
},
|
||||
"SSH address input method": {
|
||||
"fr": "Méthode de saisie de l'adresse SSH",
|
||||
"en": "SSH address input method",
|
||||
|
|
|
|||
Loading…
Reference in a new issue