split list machines into show machine command
This commit is contained in:
@@ -5,6 +5,7 @@ from .create import register_create_parser
|
|||||||
from .delete import register_delete_parser
|
from .delete import register_delete_parser
|
||||||
from .install import register_install_parser
|
from .install import register_install_parser
|
||||||
from .list import register_list_parser
|
from .list import register_list_parser
|
||||||
|
from .show import register_show_parser
|
||||||
from .update import register_update_parser
|
from .update import register_update_parser
|
||||||
|
|
||||||
|
|
||||||
@@ -62,6 +63,17 @@ Examples:
|
|||||||
)
|
)
|
||||||
register_list_parser(list_parser)
|
register_list_parser(list_parser)
|
||||||
|
|
||||||
|
show_parser = subparser.add_parser(
|
||||||
|
"show",
|
||||||
|
help="Show a machine",
|
||||||
|
epilog=(
|
||||||
|
"""
|
||||||
|
This subcommand shows the details of a machine managed by this clan like icon, description, etc
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
)
|
||||||
|
register_show_parser(show_parser)
|
||||||
|
|
||||||
install_parser = subparser.add_parser(
|
install_parser = subparser.add_parser(
|
||||||
"install",
|
"install",
|
||||||
help="Install a machine",
|
help="Install a machine",
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import dataclasses
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -12,24 +11,15 @@ from ..nix import nix_config, nix_eval
|
|||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass
|
|
||||||
class MachineInfo:
|
|
||||||
machine_name: str
|
|
||||||
machine_description: str | None
|
|
||||||
machine_icon: str | None
|
|
||||||
|
|
||||||
|
|
||||||
@API.register
|
@API.register
|
||||||
def list_machines(flake_url: str | Path, debug: bool) -> dict[str, MachineInfo]:
|
def list_machines(flake_url: str | Path, debug: bool) -> list[str]:
|
||||||
config = nix_config()
|
config = nix_config()
|
||||||
system = config["system"]
|
system = config["system"]
|
||||||
cmd = nix_eval(
|
cmd = nix_eval(
|
||||||
[
|
[
|
||||||
f"{flake_url}#clanInternals.machines.{system}",
|
f"{flake_url}#clanInternals.machines.{system}",
|
||||||
"--apply",
|
"--apply",
|
||||||
"""builtins.mapAttrs (name: attrs: {
|
"builtins.attrNames",
|
||||||
inherit (attrs.config.clanCore) machineDescription machineIcon machineName;
|
|
||||||
})""",
|
|
||||||
"--json",
|
"--json",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -37,27 +27,13 @@ def list_machines(flake_url: str | Path, debug: bool) -> dict[str, MachineInfo]:
|
|||||||
proc = run_no_stdout(cmd)
|
proc = run_no_stdout(cmd)
|
||||||
|
|
||||||
res = proc.stdout.strip()
|
res = proc.stdout.strip()
|
||||||
machines_dict = json.loads(res)
|
return json.loads(res)
|
||||||
|
|
||||||
return {
|
|
||||||
k: MachineInfo(
|
|
||||||
machine_name=v.get("machineName"),
|
|
||||||
machine_description=v.get("machineDescription", None),
|
|
||||||
machine_icon=v.get("machineIcon", None),
|
|
||||||
)
|
|
||||||
for k, v in machines_dict.items()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def list_command(args: argparse.Namespace) -> None:
|
def list_command(args: argparse.Namespace) -> None:
|
||||||
flake_path = Path(args.flake).resolve()
|
flake_path = Path(args.flake).resolve()
|
||||||
print("Listing all machines:\n")
|
for name in list_machines(flake_path, args.debug):
|
||||||
print("Source: ", flake_path)
|
print(name)
|
||||||
print("-" * 40)
|
|
||||||
for name, machine in list_machines(flake_path, args.debug).items():
|
|
||||||
description = machine.machine_description or "[no description]"
|
|
||||||
print(f"{name}\n: {description}\n")
|
|
||||||
print("-" * 40)
|
|
||||||
|
|
||||||
|
|
||||||
def register_list_parser(parser: argparse.ArgumentParser) -> None:
|
def register_list_parser(parser: argparse.ArgumentParser) -> None:
|
||||||
|
|||||||
58
pkgs/clan-cli/clan_cli/machines/show.py
Normal file
58
pkgs/clan-cli/clan_cli/machines/show.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import argparse
|
||||||
|
import dataclasses
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from clan_cli.api import API
|
||||||
|
|
||||||
|
from ..cmd import run_no_stdout
|
||||||
|
from ..nix import nix_config, nix_eval
|
||||||
|
from .types import machine_name_type
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class MachineInfo:
|
||||||
|
machine_name: str
|
||||||
|
machine_description: str | None
|
||||||
|
machine_icon: str | None
|
||||||
|
|
||||||
|
|
||||||
|
@API.register
|
||||||
|
def show_machine(flake_url: str | Path, machine_name: str, debug: bool) -> MachineInfo:
|
||||||
|
config = nix_config()
|
||||||
|
system = config["system"]
|
||||||
|
cmd = nix_eval(
|
||||||
|
[
|
||||||
|
f"{flake_url}#clanInternals.machines.{system}.{machine_name}",
|
||||||
|
"--apply",
|
||||||
|
"machine: { inherit (machine.config.clanCore) machineDescription machineIcon machineName; }",
|
||||||
|
"--json",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
proc = run_no_stdout(cmd)
|
||||||
|
res = proc.stdout.strip()
|
||||||
|
machine = json.loads(res)
|
||||||
|
|
||||||
|
return MachineInfo(
|
||||||
|
machine_name=machine.get("machineName"),
|
||||||
|
machine_description=machine.get("machineDescription", None),
|
||||||
|
machine_icon=machine.get("machineIcon", None),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def show_command(args: argparse.Namespace) -> None:
|
||||||
|
flake_path = Path(args.flake).resolve()
|
||||||
|
machine = show_machine(flake_path, args.machine, args.debug)
|
||||||
|
print(f"Name: {machine.machine_name}")
|
||||||
|
print(f"Description: {machine.machine_description or ''}")
|
||||||
|
print(f"Icon: {machine.machine_icon or ''}")
|
||||||
|
|
||||||
|
|
||||||
|
def register_show_parser(parser: argparse.ArgumentParser) -> None:
|
||||||
|
parser.set_defaults(func=show_command)
|
||||||
|
parser.add_argument(
|
||||||
|
"machine", help="the name of the machine", type=machine_name_type
|
||||||
|
)
|
||||||
@@ -176,7 +176,7 @@ def register_machines_parser(parser: argparse.ArgumentParser) -> None:
|
|||||||
"remove-secret", help="remove a group's access to a secret"
|
"remove-secret", help="remove a group's access to a secret"
|
||||||
)
|
)
|
||||||
remove_secret_parser.add_argument(
|
remove_secret_parser.add_argument(
|
||||||
"machine", help="the name of the group", type=machine_name_type
|
"machine", help="the name of the machine", type=machine_name_type
|
||||||
)
|
)
|
||||||
remove_secret_parser.add_argument(
|
remove_secret_parser.add_argument(
|
||||||
"secret", help="the name of the secret", type=secret_name_type
|
"secret", help="the name of the secret", type=secret_name_type
|
||||||
|
|||||||
@@ -21,6 +21,13 @@ def test_machine_subcommands(
|
|||||||
assert "vm1" in out.out
|
assert "vm1" in out.out
|
||||||
assert "vm2" in out.out
|
assert "vm2" in out.out
|
||||||
|
|
||||||
|
capsys.readouterr()
|
||||||
|
cli.run(["machines", "show", "--flake", str(test_flake_with_core.path), "machine1"])
|
||||||
|
out = capsys.readouterr()
|
||||||
|
assert "machine1" in out.out
|
||||||
|
assert "Description" in out.out
|
||||||
|
print(out)
|
||||||
|
|
||||||
cli.run(
|
cli.run(
|
||||||
["machines", "delete", "--flake", str(test_flake_with_core.path), "machine1"]
|
["machines", "delete", "--flake", str(test_flake_with_core.path), "machine1"]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { OperationResponse, pyApi } from "./message";
|
|||||||
export const makeCountContext = () => {
|
export const makeCountContext = () => {
|
||||||
const [machines, setMachines] = createSignal<
|
const [machines, setMachines] = createSignal<
|
||||||
OperationResponse<"list_machines">
|
OperationResponse<"list_machines">
|
||||||
>({});
|
>([]);
|
||||||
const [loading, setLoading] = createSignal(false);
|
const [loading, setLoading] = createSignal(false);
|
||||||
|
|
||||||
pyApi.list_machines.receive((machines) => {
|
pyApi.list_machines.receive((machines) => {
|
||||||
@@ -41,7 +41,7 @@ export const CountContext = createContext<CountContextType>([
|
|||||||
loading: () => false,
|
loading: () => false,
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
machines: () => ({}),
|
machines: () => ([]),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import { route } from "@/src/App";
|
|||||||
export const MachineListView: Component = () => {
|
export const MachineListView: Component = () => {
|
||||||
const [{ machines, loading }, { getMachines }] = useCountContext();
|
const [{ machines, loading }, { getMachines }] = useCountContext();
|
||||||
|
|
||||||
const list = () => Object.values(machines());
|
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
if (route() === "machines") getMachines();
|
if (route() === "machines") getMachines();
|
||||||
});
|
});
|
||||||
@@ -34,12 +32,12 @@ export const MachineListView: Component = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Match>
|
</Match>
|
||||||
<Match when={!loading() && Object.entries(machines()).length === 0}>
|
<Match when={!loading() && machines().length === 0}>
|
||||||
No machines found
|
No machines found
|
||||||
</Match>
|
</Match>
|
||||||
<Match when={!loading()}>
|
<Match when={!loading()}>
|
||||||
<ul>
|
<ul>
|
||||||
<For each={list()}>
|
<For each={machines()}>
|
||||||
{(entry) => (
|
{(entry) => (
|
||||||
<li>
|
<li>
|
||||||
<div class="card card-side m-2 bg-base-100 shadow-lg">
|
<div class="card card-side m-2 bg-base-100 shadow-lg">
|
||||||
@@ -50,7 +48,8 @@ export const MachineListView: Component = () => {
|
|||||||
</figure>
|
</figure>
|
||||||
<div class="card-body flex-row justify-between">
|
<div class="card-body flex-row justify-between">
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<h2 class="card-title">{entry.machine_name}</h2>
|
<h2 class="card-title">{entry}</h2>
|
||||||
|
{/*
|
||||||
<p
|
<p
|
||||||
classList={{
|
classList={{
|
||||||
"text-gray-400": !entry.machine_description,
|
"text-gray-400": !entry.machine_description,
|
||||||
@@ -59,6 +58,7 @@ export const MachineListView: Component = () => {
|
|||||||
>
|
>
|
||||||
{entry.machine_description || "No description"}
|
{entry.machine_description || "No description"}
|
||||||
</p>
|
</p>
|
||||||
|
*/}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button class="btn btn-ghost">
|
<button class="btn btn-ghost">
|
||||||
|
|||||||
Reference in New Issue
Block a user