diff --git a/pkgs/clan-app/ui/src/workflows/InstallMachine/InstallMachine.tsx b/pkgs/clan-app/ui/src/workflows/InstallMachine/InstallMachine.tsx index e673c817e..9b2a0ca0a 100644 --- a/pkgs/clan-app/ui/src/workflows/InstallMachine/InstallMachine.tsx +++ b/pkgs/clan-app/ui/src/workflows/InstallMachine/InstallMachine.tsx @@ -53,6 +53,7 @@ export interface InstallStoreType { install: { targetHost: string; port?: string; + password?: string; machineName: string; mainDisk: string; // ...TODO Vars diff --git a/pkgs/clan-app/ui/src/workflows/InstallMachine/steps/installSteps.tsx b/pkgs/clan-app/ui/src/workflows/InstallMachine/steps/installSteps.tsx index 98dd5fda8..91cf750f9 100644 --- a/pkgs/clan-app/ui/src/workflows/InstallMachine/steps/installSteps.tsx +++ b/pkgs/clan-app/ui/src/workflows/InstallMachine/steps/installSteps.tsx @@ -54,6 +54,7 @@ const ConfigureAdressSchema = v.object({ v.transform((val) => (val === "" ? undefined : val)), ), ), + password: v.optional(v.string()), }); type ConfigureAdressForm = v.InferInput; @@ -84,6 +85,7 @@ const ConfigureAddress = () => { ...s, targetHost: values.targetHost, port: values.port, + password: values.password, })); // Here you would typically trigger the ISO creation process @@ -98,12 +100,14 @@ const ConfigureAddress = () => { const portValue = getValue(formStore, "port"); const port = portValue ? parseInt(portValue, 10) : undefined; + const password = getValue(formStore, "password") || undefined; setLoading(true); const call = client.fetch("check_machine_ssh_login", { remote: { address, ...(port && { port }), + password: password, ssh_options: { StrictHostKeyChecking: "no", UserKnownHostsFile: "/dev/null", @@ -163,6 +167,24 @@ const ConfigureAddress = () => { /> )} + + {(field, props) => ( + + )} + } @@ -224,6 +246,7 @@ const CheckHardware = () => { target_host: { address: store.install.targetHost, ...(port && { port }), + password: store.install.password, ssh_options: { StrictHostKeyChecking: "no", UserKnownHostsFile: "/dev/null", @@ -650,6 +673,7 @@ const InstallSummary = () => { target_host: { address: store.install.targetHost, ...(port && { port }), + password: store.install.password, ssh_options: { StrictHostKeyChecking: "no", UserKnownHostsFile: "/dev/null", diff --git a/pkgs/clan-cli/clan_lib/machines/hardware.py b/pkgs/clan-cli/clan_lib/machines/hardware.py index 057e2ef50..76fe3cc32 100644 --- a/pkgs/clan-cli/clan_lib/machines/hardware.py +++ b/pkgs/clan-cli/clan_lib/machines/hardware.py @@ -1,5 +1,6 @@ import json import logging +import os from dataclasses import dataclass from enum import Enum from pathlib import Path @@ -91,6 +92,15 @@ def run_machine_hardware_info( str(opts.backend.config_path(machine)), ] + environ = os.environ.copy() + if target_host.password: + cmd += [ + "--env-password", + "--ssh-option", + "IdentitiesOnly=yes", + ] + environ["SSHPASS"] = target_host.password + if target_host.private_key: cmd += ["--ssh-option", f"IdentityFile={target_host.private_key}"] @@ -113,7 +123,9 @@ def run_machine_hardware_info( run( cmd, - RunOpts(log=Log.BOTH, prefix=machine.name, needs_user_terminal=True), + RunOpts( + log=Log.BOTH, prefix=machine.name, needs_user_terminal=True, env=environ + ), ) print(f"Successfully generated: {hw_file}") diff --git a/pkgs/clan-cli/clan_lib/machines/install.py b/pkgs/clan-cli/clan_lib/machines/install.py index 231e13337..8d5146615 100644 --- a/pkgs/clan-cli/clan_lib/machines/install.py +++ b/pkgs/clan-cli/clan_lib/machines/install.py @@ -122,9 +122,6 @@ def run_machine_install(opts: InstallOptions, target_host: Remote) -> None: phases=["partitioning"], ) - if target_host.password: - os.environ["SSHPASS"] = target_host.password - cmd = [ "nixos-anywhere", "--flake", @@ -161,12 +158,14 @@ def run_machine_install(opts: InstallOptions, target_host: Remote) -> None: ], ) + environ = os.environ.copy() if target_host.password: cmd += [ "--env-password", "--ssh-option", "IdentitiesOnly=yes", ] + environ["SSHPASS"] = target_host.password # Always set a nixos-anywhere private key to prevent failures when running # 'clan install --phases kexec' followed by 'clan install --phases disko,install,reboot'. @@ -226,7 +225,12 @@ def run_machine_install(opts: InstallOptions, target_host: Remote) -> None: notify_install_step(notification) run( [*cmd, "--phases", phase], - RunOpts(log=Log.BOTH, prefix=machine.name, needs_user_terminal=True), + RunOpts( + log=Log.BOTH, + prefix=machine.name, + needs_user_terminal=True, + env=environ, + ), ) if opts.phases: