1
0
forked from clan/clan-core

clan: add run_no_stdout function suppressing stdout

Add the `run_no_stdout` function suppressing stdout by default.
This keeps the noise down on most commands, while still staying
debuggable.
Stdout will be active when the `--debug` flag is passed to the cli.

Fixes #1443
This commit is contained in:
a-kenji 2024-05-27 21:52:18 +02:00
parent dbaa26ccaa
commit 8a08c00f46
12 changed files with 53 additions and 41 deletions

View File

@ -126,7 +126,6 @@ For more detailed information, visit: https://docs.clan.lol/getting-started/back
parser_flake = subparsers.add_parser( parser_flake = subparsers.add_parser(
"flakes", "flakes",
help="create a clan flake inside the current directory", help="create a clan flake inside the current directory",
description="create a clan flake inside the current directory",
epilog=( epilog=(
""" """
Examples: Examples:
@ -144,7 +143,6 @@ For more detailed information, visit: https://docs.clan.lol/getting-started
parser_config = subparsers.add_parser( parser_config = subparsers.add_parser(
"config", "config",
help="set nixos configuration", help="set nixos configuration",
description="set nixos configuration",
epilog=( epilog=(
""" """
""" """
@ -177,7 +175,6 @@ For more detailed information, visit: https://docs.clan.lol/getting-started/depl
parser_secrets = subparsers.add_parser( parser_secrets = subparsers.add_parser(
"secrets", "secrets",
help="manage secrets", help="manage secrets",
description="manage secrets",
epilog=( epilog=(
""" """
This subcommand provides an interface to secret facts. This subcommand provides an interface to secret facts.
@ -201,7 +198,6 @@ For more detailed information, visit: https://docs.clan.lol/getting-started/secr
parser_facts = subparsers.add_parser( parser_facts = subparsers.add_parser(
"facts", "facts",
help="manage facts", help="manage facts",
description="manage facts",
epilog=( epilog=(
""" """
@ -238,7 +234,6 @@ For more detailed information, visit: https://docs.clan.lol/getting-started/secr
parser_machine = subparsers.add_parser( parser_machine = subparsers.add_parser(
"machines", "machines",
help="manage machines and their configuration", help="manage machines and their configuration",
description="manage machines and their configuration",
epilog=( epilog=(
""" """
This subcommand provides an interface to machines managed by clan. This subcommand provides an interface to machines managed by clan.

View File

@ -140,3 +140,23 @@ def run(
raise ClanCmdError(cmd_out) raise ClanCmdError(cmd_out)
return cmd_out return cmd_out
def run_no_stdout(
cmd: list[str],
*,
env: dict[str, str] | None = None,
cwd: Path = Path.cwd(),
log: Log = Log.STDERR,
check: bool = True,
error_msg: str | None = None,
) -> CmdOut:
"""
Like run, but automatically suppresses stdout, if not in DEBUG log level.
If in DEBUG log level the stdout of commands will be shown.
"""
if logging.getLogger(__name__.split(".")[0]).isEnabledFor(logging.DEBUG):
return run(cmd, env=env, log=log, check=check, error_msg=error_msg)
else:
log = Log.NONE
return run(cmd, env=env, log=log, check=check, error_msg=error_msg)

View File

@ -8,7 +8,7 @@ import sys
from pathlib import Path from pathlib import Path
from typing import Any, get_origin from typing import Any, get_origin
from clan_cli.cmd import run from clan_cli.cmd import run_no_stdout
from clan_cli.dirs import machine_settings_file from clan_cli.dirs import machine_settings_file
from clan_cli.errors import ClanError from clan_cli.errors import ClanError
from clan_cli.git import commit_file from clan_cli.git import commit_file
@ -116,7 +116,7 @@ def options_for_machine(
f"{clan_dir}#nixosConfigurations.{machine_name}.config.clanCore.optionsNix" f"{clan_dir}#nixosConfigurations.{machine_name}.config.clanCore.optionsNix"
) )
cmd = nix_eval(flags=flags) cmd = nix_eval(flags=flags)
proc = run( proc = run_no_stdout(
cmd, cmd,
error_msg=f"Failed to read options for machine {machine_name}", error_msg=f"Failed to read options for machine {machine_name}",
) )
@ -136,7 +136,7 @@ def read_machine_option_value(
f"{clan_dir}#nixosConfigurations.{machine_name}.config.{option}", f"{clan_dir}#nixosConfigurations.{machine_name}.config.{option}",
], ],
) )
proc = run(cmd, error_msg=f"Failed to read option {option}") proc = run_no_stdout(cmd, error_msg=f"Failed to read option {option}")
value = json.loads(proc.stdout) value = json.loads(proc.stdout)
# print the value so that the output can be copied and fed as an input. # print the value so that the output can be copied and fed as an input.

View File

@ -2,7 +2,7 @@ import json
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
from ..cmd import run from ..cmd import run_no_stdout
from ..errors import ClanError from ..errors import ClanError
from ..nix import nix_eval from ..nix import nix_eval
@ -32,7 +32,7 @@ def schema_from_module_file(
""" """
# run the nix expression and parse the output as json # run the nix expression and parse the output as json
cmd = nix_eval(["--expr", nix_expr]) cmd = nix_eval(["--expr", nix_expr])
proc = run(cmd) proc = run_no_stdout(cmd)
return json.loads(proc.stdout) return json.loads(proc.stdout)

View File

@ -2,7 +2,7 @@
import argparse import argparse
from pathlib import Path from pathlib import Path
from ..cmd import CmdOut, run from ..cmd import CmdOut, run_no_stdout
from ..errors import ClanError from ..errors import ClanError
from ..nix import nix_command, nix_shell from ..nix import nix_command, nix_shell
@ -23,28 +23,28 @@ def create_flake(directory: Path, url: str) -> dict[str, CmdOut]:
url, url,
] ]
) )
out = run(command, cwd=directory) out = run_no_stdout(command, cwd=directory)
command = nix_shell(["nixpkgs#git"], ["git", "init"]) command = nix_shell(["nixpkgs#git"], ["git", "init"])
out = run(command, cwd=directory) out = run_no_stdout(command, cwd=directory)
response["git init"] = out response["git init"] = out
command = nix_shell(["nixpkgs#git"], ["git", "add", "."]) command = nix_shell(["nixpkgs#git"], ["git", "add", "."])
out = run(command, cwd=directory) out = run_no_stdout(command, cwd=directory)
response["git add"] = out response["git add"] = out
command = nix_shell(["nixpkgs#git"], ["git", "config", "user.name", "clan-tool"]) command = nix_shell(["nixpkgs#git"], ["git", "config", "user.name", "clan-tool"])
out = run(command, cwd=directory) out = run_no_stdout(command, cwd=directory)
response["git config"] = out response["git config"] = out
command = nix_shell( command = nix_shell(
["nixpkgs#git"], ["git", "config", "user.email", "clan@example.com"] ["nixpkgs#git"], ["git", "config", "user.email", "clan@example.com"]
) )
out = run(command, cwd=directory) out = run_no_stdout(command, cwd=directory)
response["git config"] = out response["git config"] = out
command = ["nix", "flake", "update"] command = ["nix", "flake", "update"]
out = run(command, cwd=directory) out = run_no_stdout(command, cwd=directory)
response["flake update"] = out response["flake update"] = out
return response return response

View File

@ -2,7 +2,7 @@ import argparse
from dataclasses import dataclass from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from ..cmd import run from ..cmd import run_no_stdout
from ..dirs import machine_gcroot from ..dirs import machine_gcroot
from ..errors import ClanError from ..errors import ClanError
from ..machines.list import list_machines from ..machines.list import list_machines
@ -30,7 +30,7 @@ class FlakeConfig:
def run_cmd(cmd: list[str]) -> str: def run_cmd(cmd: list[str]) -> str:
proc = run(cmd) proc = run_no_stdout(cmd)
return proc.stdout.strip() return proc.stdout.strip()

View File

@ -12,7 +12,7 @@ from pathlib import Path
from tempfile import TemporaryDirectory from tempfile import TemporaryDirectory
from typing import Any from typing import Any
from .cmd import Log, run from .cmd import Log, run, run_no_stdout
from .errors import ClanError from .errors import ClanError
from .facts.secret_modules import SecretStoreBase from .facts.secret_modules import SecretStoreBase
from .machines.machines import Machine from .machines.machines import Machine
@ -60,7 +60,7 @@ def get_keymap_and_locale() -> dict[str, str]:
keymap = "en" keymap = "en"
# Execute the `localectl status` command # Execute the `localectl status` command
result = run(["localectl", "status"]) result = run_no_stdout(["localectl", "status"])
if result.returncode == 0: if result.returncode == 0:
output = result.stdout output = result.stdout

View File

@ -4,7 +4,7 @@ from pathlib import Path
from clan_cli.errors import ClanError from clan_cli.errors import ClanError
from clan_cli.nix import nix_shell from clan_cli.nix import nix_shell
from .cmd import Log, run from .cmd import Log, run, run_no_stdout
from .locked_open import locked_open from .locked_open import locked_open
@ -78,7 +78,7 @@ def _commit_file_to_git(
["git", "-C", str(repo_dir), "diff", "--cached", "--exit-code"] ["git", "-C", str(repo_dir), "diff", "--cached", "--exit-code"]
+ [str(file_path) for file_path in file_paths], + [str(file_path) for file_path in file_paths],
) )
result = run(cmd, check=False, cwd=repo_dir) result = run_no_stdout(cmd, check=False, cwd=repo_dir)
# if there is no diff, return # if there is no diff, return
if result.returncode == 0: if result.returncode == 0:
return return
@ -97,6 +97,6 @@ def _commit_file_to_git(
+ [str(file_path) for file_path in file_paths], + [str(file_path) for file_path in file_paths],
) )
run( run_no_stdout(
cmd, error_msg=f"Failed to commit {file_paths} to git repository {repo_dir}" cmd, error_msg=f"Failed to commit {file_paths} to git repository {repo_dir}"
) )

View File

@ -1,7 +1,7 @@
import json import json
from pathlib import Path from pathlib import Path
from ..cmd import run from ..cmd import run_no_stdout
from ..nix import nix_build, nix_config from ..nix import nix_build, nix_config
from .machines import Machine from .machines import Machine
@ -10,7 +10,7 @@ from .machines import Machine
def get_all_machines(flake_dir: Path) -> list[Machine]: def get_all_machines(flake_dir: Path) -> list[Machine]:
config = nix_config() config = nix_config()
system = config["system"] system = config["system"]
json_path = run( json_path = run_no_stdout(
nix_build([f'{flake_dir}#clanInternals.all-machines-json."{system}"']) nix_build([f'{flake_dir}#clanInternals.all-machines-json."{system}"'])
).stdout ).stdout

View File

@ -6,7 +6,7 @@ from pathlib import Path
from clan_cli.api import API from clan_cli.api import API
from ..cmd import Log, run from ..cmd import run_no_stdout
from ..nix import nix_config, nix_eval from ..nix import nix_config, nix_eval
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -34,10 +34,7 @@ def list_machines(flake_url: str | Path, debug: bool) -> dict[str, MachineInfo]:
] ]
) )
if not debug: proc = run_no_stdout(cmd)
proc = run(cmd, log=Log.NONE)
else:
proc = run(cmd)
res = proc.stdout.strip() res = proc.stdout.strip()
machines_dict = json.loads(res) machines_dict = json.loads(res)

View File

@ -10,7 +10,7 @@ from clan_cli.clan_uri import ClanURI, MachineData
from clan_cli.dirs import vm_state_dir from clan_cli.dirs import vm_state_dir
from clan_cli.qemu.qmp import QEMUMonitorProtocol from clan_cli.qemu.qmp import QEMUMonitorProtocol
from ..cmd import run from ..cmd import run_no_stdout
from ..errors import ClanError from ..errors import ClanError
from ..nix import nix_build, nix_config, nix_eval, nix_metadata from ..nix import nix_build, nix_config, nix_eval, nix_metadata
from ..ssh import Host, parse_deployment_address from ..ssh import Host, parse_deployment_address
@ -197,15 +197,15 @@ class Machine:
config_json.flush() config_json.flush()
file_info = json.loads( file_info = json.loads(
run( run_no_stdout(
nix_eval( nix_eval(
[ [
"--impure", "--impure",
"--expr", "--expr",
f'let x = (builtins.fetchTree {{ type = "file"; url = "file://{config_json.name}"; }}); in {{ narHash = x.narHash; path = x.outPath; }}', f'let x = (builtins.fetchTree {{ type = "file"; url = "file://{config_json.name}"; }}); in {{ narHash = x.narHash; path = x.outPath; }}',
] ]
) ),
).stdout.strip() ).stdout.strip(),
) )
args = [] args = []
@ -247,10 +247,10 @@ class Machine:
] ]
if method == "eval": if method == "eval":
output = run(nix_eval(args)).stdout.strip() output = run_no_stdout(nix_eval(args)).stdout.strip()
return output return output
elif method == "build": elif method == "build":
outpath = run(nix_build(args)).stdout.strip() outpath = run_no_stdout(nix_build(args)).stdout.strip()
return Path(outpath) return Path(outpath)
else: else:
raise ValueError(f"Unknown method {method}") raise ValueError(f"Unknown method {method}")

View File

@ -4,7 +4,7 @@ import tempfile
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
from .cmd import run from .cmd import run_no_stdout
from .dirs import nixpkgs_flake, nixpkgs_source from .dirs import nixpkgs_flake, nixpkgs_source
@ -55,12 +55,12 @@ def nix_build(flags: list[str], gcroot: Path | None = None) -> list[str]:
def nix_add_to_gcroots(nix_path: Path, dest: Path) -> None: def nix_add_to_gcroots(nix_path: Path, dest: Path) -> None:
cmd = ["nix-store", "--realise", f"{nix_path}", "--add-root", f"{dest}"] cmd = ["nix-store", "--realise", f"{nix_path}", "--add-root", f"{dest}"]
run(cmd) run_no_stdout(cmd)
def nix_config() -> dict[str, Any]: def nix_config() -> dict[str, Any]:
cmd = nix_command(["show-config", "--json"]) cmd = nix_command(["show-config", "--json"])
proc = run(cmd) proc = run_no_stdout(cmd)
data = json.loads(proc.stdout) data = json.loads(proc.stdout)
config = {} config = {}
for key, value in data.items(): for key, value in data.items():
@ -95,7 +95,7 @@ def nix_eval(flags: list[str]) -> list[str]:
def nix_metadata(flake_url: str | Path) -> dict[str, Any]: def nix_metadata(flake_url: str | Path) -> dict[str, Any]:
cmd = nix_command(["flake", "metadata", "--json", f"{flake_url}"]) cmd = nix_command(["flake", "metadata", "--json", f"{flake_url}"])
proc = run(cmd) proc = run_no_stdout(cmd)
data = json.loads(proc.stdout) data = json.loads(proc.stdout)
return data return data