1
0
Fork 0

wfvm: Use OpenSSH instead of Paramiko

The Paramiko hack does not stream stdout/stderr and makes debugging or using expect problematic.
This commit is contained in:
Sebastien Bourdeauducq 2020-06-13 18:49:55 +08:00
parent 22a8a5ed92
commit 72d155c047
2 changed files with 21 additions and 53 deletions

View File

@ -55,8 +55,10 @@ win.makeWindowsImage {
}; };
in '' in ''
ln -s ${Anaconda3} ./Anaconda3.exe ln -s ${Anaconda3} ./Anaconda3.exe
win put Anaconda3.exe 'C:\Users\artiq' win-put Anaconda3.exe 'C:\Users\artiq'
win exec 'start /wait "" .\Anaconda3.exe /S /D=%UserProfile%\Anaconda3' echo Running Anaconda installer...
win-exec 'start /wait "" .\Anaconda3.exe /S /D=%UserProfile%\Anaconda3'
echo Anaconda installer finished
''; '';
} }

View File

@ -151,59 +151,25 @@ let
mv c.img $out mv c.img $out
''; '';
# Use Paramiko instead of OpenSSH # Pass empty config file to prevent ssh from failing to create ~/.ssh
# sshOpts = "-F /dev/null -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=\$TMP/known_hosts -o ConnectTimeout=1";
# OpenSSH goes out of it's way to make password logins hard win-exec = pkgs.writeShellScriptBin "win-exec" ''
# and Windows goes out of it's way to make key authentication hard ${pkgs.sshpass}/bin/sshpass -p${users.artiq.password} -- \
# so we're in a pretty tough spot ${pkgs.openssh}/bin/ssh -np 2022 ${sshOpts} \
# artiq@localhost \
# Luckily the usage patterns are quite simple and easy to reimplement with paramiko $1
paramikoClient = pkgs.writeScriptBin "win" '' '';
#!${pkgs.python3.withPackages(ps: [ ps.paramiko ])}/bin/python win-put = pkgs.writeShellScriptBin "win-put" ''
import paramiko echo scp windows $1 -\> $2
import os.path ${pkgs.sshpass}/bin/sshpass -p${users.artiq.password} -- \
import sys ${pkgs.openssh}/bin/scp -P 2022 ${sshOpts} \
$1 artiq@localhost:$2
def w_join(*args):
# Like os.path.join but for windows paths
return "\\".join(args)
if __name__ == '__main__':
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy)
cmd = sys.argv[1]
try:
client.connect(hostname="127.0.0.1", port=2022, username="artiq", password="${users.artiq.password}", timeout=1)
if cmd == "put":
sftp = client.open_sftp()
src = sys.argv[2]
dst = sys.argv[3]
sftp.put(src, w_join(dst, os.path.basename(src)))
elif cmd == "exec":
_, stdout, stderr = client.exec_command(sys.argv[2])
sys.stdout.write(stdout.read().strip().decode())
sys.stdout.flush()
sys.stderr.write(stderr.read().strip().decode())
sys.stderr.flush()
else:
raise ValueError(f"Unhandled command: {cmd}")
except (EOFError, paramiko.ssh_exception.SSHException):
exit(1)
''; '';
finalImage = builtins.foldl' (acc: v: pkgs.runCommandNoCC "${v.name}.img" { finalImage = builtins.foldl' (acc: v: pkgs.runCommandNoCC "${v.name}.img" {
buildInputs = [ buildInputs = [
paramikoClient win-exec
win-put
qemu qemu
] ++ (v.buildInputs or []); ] ++ (v.buildInputs or []);
} (let } (let
@ -234,7 +200,7 @@ let
exit 1 exit 1
fi fi
output=$(win exec 'echo Ran command' || echo "") output=$(win-exec 'echo|set /p="Ran command"' || echo "")
if test "$output" = "Ran command"; then if test "$output" = "Ran command"; then
break break
fi fi
@ -253,7 +219,7 @@ let
# Allow install to "settle" # Allow install to "settle"
sleep 20 sleep 20
win exec 'shutdown /s' win-exec 'shutdown /s'
mv c.img $out mv c.img $out
'')) baseImage installCommands; '')) baseImage installCommands;