Merge pull request 'cli: use nix_shell also in ssh.py' (#25) from zerotier into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/25
This commit is contained in:
Mic92
2023-07-26 06:53:33 +00:00
7 changed files with 130 additions and 110 deletions

View File

@@ -1 +1,2 @@
use nix
# Because we depend on nixpkgs sources, uploading to builders takes a long time
use flake .#clan --builders ''

View File

@@ -1,10 +1,9 @@
import os
CLAN_NIXPKGS = os.environ.get("CLAN_NIXPKGS")
def nix_shell(packages: list[str], cmd: list[str]) -> list[str]:
nixpkgs = os.environ.get("CLAN_NIXPKGS")
# in unittest we will have all binaries provided
if CLAN_NIXPKGS is None:
if nixpkgs is None:
return cmd
return ["nix", "shell", "-f", CLAN_NIXPKGS] + packages + ["-c"] + cmd
return ["nix", "shell", "-f", nixpkgs] + packages + ["-c"] + cmd

View File

@@ -3,6 +3,8 @@ import json
import subprocess
from typing import Optional
from .nix import nix_shell
def ssh(
host: str,
@@ -10,15 +12,10 @@ def ssh(
password: Optional[str] = None,
ssh_args: list[str] = [],
) -> None:
nix_shell_args = []
packages = ["tor", "openssh"]
password_args = []
if password:
nix_shell_args = [
"nix",
"shell",
"nixpkgs#sshpass",
"-c",
]
packages.append("sshpass")
password_args = [
"sshpass",
"-p",
@@ -32,23 +29,22 @@ def ssh(
"StrictHostKeyChecking=no",
f"{user}@{host}",
]
cmd = nix_shell_args + ["torify"] + password_args + _ssh_args
cmd = nix_shell(packages, ["torify"] + password_args + _ssh_args)
subprocess.run(cmd)
def qrcode_scan(pictureFile: str) -> str:
return (
subprocess.run(
[
"nix",
"shell",
"nixpkgs#zbar",
"-c",
"zbarimg",
"--quiet",
"--raw",
pictureFile,
],
nix_shell(
["zbar"],
[
"zbarimg",
"--quiet",
"--raw",
pictureFile,
],
),
stdout=subprocess.PIPE,
check=True,
)

View File

@@ -1,11 +1,11 @@
{ pkgs ? import <nixpkgs> { }
, lib ? pkgs.lib
, python3 ? pkgs.python3
, ruff ? pkgs.ruff
, runCommand ? pkgs.runCommand
, installShellFiles ? pkgs.installShellFiles
, zerotierone ? pkgs.zerotierone
, bubblewrap ? pkgs.bubblewrap
{ pkgs
, lib
, python3
, ruff
, runCommand
, installShellFiles
, zerotierone
, bubblewrap
}:
let
pyproject = builtins.fromTOML (builtins.readFile ./pyproject.toml);

View File

@@ -4,9 +4,11 @@
pyproject = builtins.fromTOML (builtins.readFile ./pyproject.toml);
name = pyproject.project.name;
package = pkgs.callPackage ./default.nix { };
shell = pkgs.callPackage ./shell.nix { };
in
{
packages.${name} = package;
devShells.${name} = shell;
packages.default = package;
checks = package.tests;
};

View File

@@ -1,13 +1,7 @@
{ pkgs ? import <nixpkgs> { }
,
}:
{ pkgs }:
let
lib = pkgs.lib;
python3 = pkgs.python3;
package = import ./default.nix {
inherit lib python3;
};
pythonWithDeps = python3.withPackages (
package = pkgs.callPackage ./default.nix { };
pythonWithDeps = pkgs.python3.withPackages (
ps:
package.propagatedBuildInputs
++ package.devDependencies
@@ -18,39 +12,38 @@ let
checkScript = pkgs.writeScriptBin "check" ''
nix build -f . tests -L "$@"
'';
devShell = pkgs.mkShell {
packages = [
pkgs.ruff
pythonWithDeps
];
# sets up an editable install and add enty points to $PATH
CLAN_NIXPKGS = pkgs.path;
shellHook = ''
tmp_path=$(realpath ./.pythonenv)
repo_root=$(realpath .)
rm -rf $tmp_path
mkdir -p "$tmp_path/${pythonWithDeps.sitePackages}"
${pythonWithDeps.interpreter} -m pip install \
--quiet \
--disable-pip-version-check \
--no-index \
--no-build-isolation \
--prefix "$tmp_path" \
--editable $repo_root
export PATH="$tmp_path/bin:${checkScript}/bin:$PATH"
export PYTHONPATH="$repo_root:$tmp_path/${pythonWithDeps.sitePackages}"
export XDG_DATA_DIRS="$tmp_path/share''${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}"
export fish_complete_path="$tmp_path/share/fish/vendor_completions.d''${fish_complete_path:+:$fish_complete_path}"
mkdir -p \
$tmp_path/share/fish/vendor_completions.d \
$tmp_path/share/bash-completion/completions \
$tmp_path/share/zsh/site-functions
register-python-argcomplete --shell fish clan > $tmp_path/share/fish/vendor_completions.d/clan.fish
register-python-argcomplete --shell bash clan > $tmp_path/share/bash-completion/completions/clan
'';
};
in
devShell
pkgs.mkShell {
packages = [
pkgs.ruff
pythonWithDeps
];
# sets up an editable install and add enty points to $PATH
CLAN_NIXPKGS = pkgs.path;
shellHook = ''
tmp_path=$(realpath ./.pythonenv)
repo_root=$(realpath .)
rm -rf $tmp_path
mkdir -p "$tmp_path/${pythonWithDeps.sitePackages}"
${pythonWithDeps.interpreter} -m pip install \
--quiet \
--disable-pip-version-check \
--no-index \
--no-build-isolation \
--prefix "$tmp_path" \
--editable $repo_root
export PATH="$tmp_path/bin:${checkScript}/bin:$PATH"
export PYTHONPATH="$repo_root:$tmp_path/${pythonWithDeps.sitePackages}"
export XDG_DATA_DIRS="$tmp_path/share''${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}"
export fish_complete_path="$tmp_path/share/fish/vendor_completions.d''${fish_complete_path:+:$fish_complete_path}"
mkdir -p \
$tmp_path/share/fish/vendor_completions.d \
$tmp_path/share/bash-completion/completions \
$tmp_path/share/zsh/site-functions
register-python-argcomplete --shell fish clan > $tmp_path/share/fish/vendor_completions.d/clan.fish
register-python-argcomplete --shell bash clan > $tmp_path/share/bash-completion/completions/clan
'';
}

View File

@@ -1,5 +1,7 @@
import os
import sys
from typing import Union
from contextlib import contextmanager
from typing import Iterator, Union
import pytest
import pytest_subprocess.fake_process
@@ -18,45 +20,72 @@ def test_no_args(
assert captured.err.startswith("usage:")
@contextmanager
def mock_env(**environ: str) -> Iterator[None]:
original_environ = dict(os.environ)
os.environ.update(environ)
try:
yield
finally:
os.environ.clear()
os.environ.update(original_environ)
# using fp fixture from pytest-subprocess
def test_ssh_no_pass(fp: pytest_subprocess.fake_process.FakeProcess) -> None:
host = "somehost"
user = "user"
cmd: list[Union[str, utils.Any]] = [
"torify",
"ssh",
"-o",
"UserKnownHostsFile=/dev/null",
"-o",
"StrictHostKeyChecking=no",
f"{user}@{host}",
fp.any(),
]
fp.register(cmd)
clan_cli.ssh.ssh(
host=host,
user=user,
)
assert fp.call_count(cmd) == 1
with mock_env(CLAN_NIXPKGS="/mocked-nixpkgs"):
host = "somehost"
user = "user"
cmd: list[Union[str, utils.Any]] = [
"nix",
"shell",
"-f",
"/mocked-nixpkgs",
"tor",
"openssh",
"-c",
"torify",
"ssh",
"-o",
"UserKnownHostsFile=/dev/null",
"-o",
"StrictHostKeyChecking=no",
f"{user}@{host}",
fp.any(),
]
fp.register(cmd)
clan_cli.ssh.ssh(
host=host,
user=user,
)
assert fp.call_count(cmd) == 1
def test_ssh_with_pass(fp: pytest_subprocess.fake_process.FakeProcess) -> None:
host = "somehost"
user = "user"
cmd: list[Union[str, utils.Any]] = [
"nix",
"shell",
"nixpkgs#sshpass",
"-c",
fp.any(),
]
fp.register(cmd)
clan_cli.ssh.ssh(
host=host,
user=user,
password="XXX",
)
assert fp.call_count(cmd) == 1
with mock_env(CLAN_NIXPKGS="/mocked-nixpkgs"):
host = "somehost"
user = "user"
cmd: list[Union[str, utils.Any]] = [
"nix",
"shell",
"-f",
"/mocked-nixpkgs",
"tor",
"openssh",
"sshpass",
"-c",
"torify",
"sshpass",
"-p",
fp.any(),
]
fp.register(cmd)
clan_cli.ssh.ssh(
host=host,
user=user,
password="XXX",
)
assert fp.call_count(cmd) == 1
def test_qrcode_scan(fp: pytest_subprocess.fake_process.FakeProcess) -> None: