api/machines: move configuration data into subattribute

This helps to make room for 'instance_refs'
And potentially other metadata that we want to compute and expose
This commit is contained in:
Johannes Kirschbauer
2025-09-01 14:42:12 +02:00
parent a06940e981
commit 727d4e70ae
7 changed files with 54 additions and 30 deletions

View File

@@ -3,7 +3,7 @@ import { A } from "@solidjs/router";
import { Accordion } from "@kobalte/core/accordion"; import { Accordion } from "@kobalte/core/accordion";
import Icon from "../Icon/Icon"; import Icon from "../Icon/Icon";
import { Typography } from "@/src/components/Typography/Typography"; import { Typography } from "@/src/components/Typography/Typography";
import { For, Show, useContext } from "solid-js"; import { For, Show } from "solid-js";
import { MachineStatus } from "@/src/components/MachineStatus/MachineStatus"; import { MachineStatus } from "@/src/components/MachineStatus/MachineStatus";
import { buildMachinePath, useClanURI } from "@/src/hooks/clan"; import { buildMachinePath, useClanURI } from "@/src/hooks/clan";
import { useMachineStateQuery } from "@/src/hooks/queries"; import { useMachineStateQuery } from "@/src/hooks/queries";
@@ -136,7 +136,7 @@ export const SidebarBody = (props: SidebarProps) => {
<MachineRoute <MachineRoute
clanURI={clanURI} clanURI={clanURI}
machineID={id} machineID={id}
name={machine.name || id} name={machine.data.name || id}
serviceCount={0} serviceCount={0}
/> />
)} )}

View File

@@ -26,13 +26,19 @@ const mockFetcher: Fetcher = <K extends OperationNames>(
const resultData: Partial<ResultDataMap> = { const resultData: Partial<ResultDataMap> = {
list_machines: { list_machines: {
pandora: { pandora: {
name: "pandora", data: {
name: "pandora",
},
}, },
enceladus: { enceladus: {
name: "enceladus", data: {
name: "enceladus",
},
}, },
dione: { dione: {
name: "dione", data: {
name: "dione",
},
}, },
}, },
}; };

View File

@@ -62,20 +62,28 @@ const mockFetcher: Fetcher = <K extends OperationNames>(
}, },
list_machines: { list_machines: {
jon: { jon: {
name: "jon", data: {
tags: ["all", "nixos", "tag1"], name: "jon",
tags: ["all", "nixos", "tag1"],
},
}, },
sara: { sara: {
name: "sara", data: {
tags: ["all", "darwin", "tag2"], name: "sara",
tags: ["all", "darwin", "tag2"],
},
}, },
kyra: { kyra: {
name: "kyra", data: {
tags: ["all", "darwin", "tag2"], name: "kyra",
tags: ["all", "darwin", "tag2"],
},
}, },
leila: { leila: {
name: "leila", data: {
tags: ["all", "darwin", "tag2"], name: "leila",
tags: ["all", "darwin", "tag2"],
},
}, },
}, },
list_tags: { list_tags: {

View File

@@ -120,7 +120,7 @@ const SelectService = () => {
label: t, label: t,
type: "tag" as const, type: "tag" as const,
members: Object.entries(machinesQuery.data || {}) members: Object.entries(machinesQuery.data || {})
.filter(([_, m]) => m.tags?.includes(t)) .filter(([_, m]) => m.data.tags?.includes(t))
.map(([k]) => k), .map(([k]) => k),
}; };
}); });
@@ -206,7 +206,7 @@ const useOptions = (tagsQuery: TagsQuery, machinesQuery: MachinesQuery) =>
label: tag, label: tag,
value: "t_" + tag, value: "t_" + tag,
members: Object.entries(machines) members: Object.entries(machines)
.filter(([_, v]) => v.tags?.includes(tag)) .filter(([_, v]) => v.data.tags?.includes(tag))
.map(([k]) => k), .map(([k]) => k),
})); }));

View File

@@ -103,7 +103,9 @@ def get_machines_for_update(
machines_to_update = list( machines_to_update = list(
filter( filter(
requires_explicit_update, requires_explicit_update,
instantiate_inventory_to_machines(flake, machines_with_tags).values(), instantiate_inventory_to_machines(
flake, {name: m.data for name, m in machines_with_tags.items()}
).values(),
), ),
) )
# all machines that are in the clan but not included in the update list # all machines that are in the clan but not included in the update list
@@ -128,13 +130,13 @@ def get_machines_for_update(
machines_to_update = [] machines_to_update = []
valid_names = validate_machine_names(explicit_names, flake) valid_names = validate_machine_names(explicit_names, flake)
for name in valid_names: for name in valid_names:
inventory_machine = machines_with_tags.get(name) machine = machines_with_tags.get(name)
if not inventory_machine: if not machine:
msg = "This is an internal bug" msg = "This is an internal bug"
raise ClanError(msg) raise ClanError(msg)
machines_to_update.append( machines_to_update.append(
Machine.from_inventory(name, flake, inventory_machine), Machine.from_inventory(name, flake, machine.data),
) )
return machines_to_update return machines_to_update

View File

@@ -41,28 +41,34 @@ class MachineState(TypedDict):
# add more info later when retrieving remote state # add more info later when retrieving remote state
@dataclass
class MachineResponse:
data: InventoryMachine
# Reference the installed service instances
instance_refs: list[str] = field(default_factory=list)
@API.register @API.register
def list_machines( def list_machines(
flake: Flake, flake: Flake,
opts: ListOptions | None = None, opts: ListOptions | None = None,
) -> dict[str, InventoryMachine]: ) -> dict[str, MachineResponse]:
"""List machines of a clan""" """List machines of a clan"""
inventory_store = InventoryStore(flake=flake) inventory_store = InventoryStore(flake=flake)
inventory = inventory_store.read() inventory = inventory_store.read()
machines = inventory.get("machines", {}) raw_machines = inventory.get("machines", {})
if opts and opts.filter.tags is not None: res: dict[str, MachineResponse] = {}
filtered_machines = {} for machine_name, machine in raw_machines.items():
if opts and opts.filter.tags is not None:
for machine_name, machine in machines.items():
machine_tags = machine.get("tags", []) machine_tags = machine.get("tags", [])
if all(ft in machine_tags for ft in opts.filter.tags): if all(ft in machine_tags for ft in opts.filter.tags):
filtered_machines[machine_name] = machine res[machine_name] = MachineResponse(data=InventoryMachine(**machine))
else:
res[machine_name] = MachineResponse(data=InventoryMachine(**machine))
return filtered_machines return res
return machines
@API.register @API.register

View File

@@ -30,7 +30,9 @@ def list_full_machines(flake: Flake) -> dict[str, Machine]:
"""Like `list_machines`, but returns a full 'machine' instance for each machine.""" """Like `list_machines`, but returns a full 'machine' instance for each machine."""
machines = list_machines(flake) machines = list_machines(flake)
return instantiate_inventory_to_machines(flake, machines) return instantiate_inventory_to_machines(
flake, {name: m.data for name, m in machines.items()}
)
@dataclass @dataclass