Clan-app: connection check & show remote devices

This commit is contained in:
Johannes Kirschbauer
2024-08-16 12:18:21 +02:00
parent 76ca85ac73
commit cabdbe5ecd
5 changed files with 174 additions and 8 deletions

View File

@@ -11,7 +11,7 @@ export const BlockDevicesView: Component = () => {
} = createQuery(() => ({
queryKey: ["block_devices"],
queryFn: async () => {
const result = await callApi("show_block_devices", {});
const result = await callApi("show_block_devices", { options: {} });
if (result.status === "error") throw new Error("Failed to fetch data");
return result.data;

View File

@@ -45,7 +45,7 @@ export const Flash = () => {
/* ==== WIFI NETWORK ==== */
const [wifiNetworks, setWifiNetworks] = createSignal<Wifi[]>([]);
const [passwordVisibility, setPasswordVisibility] = createSignal<boolean[]>(
[],
[]
);
createEffect(() => {
@@ -67,7 +67,7 @@ export const Flash = () => {
const updatedNetworks = wifiNetworks().filter((_, i) => i !== index);
setWifiNetworks(updatedNetworks);
const updatedVisibility = passwordVisibility().filter(
(_, i) => i !== index,
(_, i) => i !== index
);
setPasswordVisibility(updatedVisibility);
setValue(formStore, "wifi", updatedNetworks);
@@ -83,7 +83,9 @@ export const Flash = () => {
const deviceQuery = createQuery(() => ({
queryKey: ["block_devices"],
queryFn: async () => {
const result = await callApi("show_block_devices", { options: {} });
const result = await callApi("show_block_devices", {
options: {},
});
if (result.status === "error") throw new Error("Failed to fetch data");
return result.data;
},

View File

@@ -1,14 +1,25 @@
import { callApi } from "@/src/api";
import { activeURI } from "@/src/App";
import { SelectInput } from "@/src/components/SelectInput";
import { createForm } from "@modular-forms/solid";
import { useParams } from "@solidjs/router";
import { createQuery } from "@tanstack/solid-query";
import { createSignal, Show } from "solid-js";
import { createSignal, For, Show } from "solid-js";
import toast from "solid-toast";
type InstallForm = {
disk: string;
};
export const MachineDetails = () => {
const params = useParams();
const query = createQuery(() => ({
queryKey: [activeURI(), "machine", params.id],
queryKey: [
activeURI(),
"machine",
params.id,
"get_inventory_machine_details",
],
queryFn: async () => {
const curr = activeURI();
if (curr) {
@@ -24,12 +35,66 @@ export const MachineDetails = () => {
const [sshKey, setSshKey] = createSignal<string>();
const [formStore, { Form, Field }] = createForm<InstallForm>({});
const handleSubmit = async (values: InstallForm) => {
return null;
};
const targetHost = () => query?.data?.machine.deploy.targetHost;
const remoteDiskQuery = createQuery(() => ({
queryKey: [activeURI(), "machine", targetHost(), "show_block_devices"],
queryFn: async () => {
const curr = activeURI();
if (curr) {
const result = await callApi("show_block_devices", {
options: {
hostname: targetHost(),
keyfile: sshKey(),
},
});
if (result.status === "error") throw new Error("Failed to fetch data");
return result.data;
}
},
}));
const onlineStatusQuery = createQuery(() => ({
queryKey: [activeURI(), "machine", targetHost(), "check_machine_online"],
queryFn: async () => {
const curr = activeURI();
if (curr) {
const result = await callApi("check_machine_online", {
flake_url: curr,
machine_name: params.id,
opts: {
keyfile: sshKey(),
},
});
if (result.status === "error") throw new Error("Failed to fetch data");
return result.data;
}
},
refetchInterval: 5000,
}));
return (
<div>
{query.isLoading && <span class="loading loading-bars" />}
<Show when={!query.isLoading && query.data}>
{(data) => (
<div class="grid grid-cols-2 gap-2 text-lg">
<Show when={onlineStatusQuery.isFetching} fallback={<span></span>}>
<span class="loading loading-bars loading-sm justify-self-end"></span>
</Show>
<span
class="badge badge-outline text-lg"
classList={{
"badge-primary": onlineStatusQuery.data === "Online",
}}
>
{onlineStatusQuery.data}
</span>
<label class="justify-self-end font-light">Name</label>
<span>{data().machine.name}</span>
<span class="justify-self-end font-light">description</span>
@@ -65,6 +130,7 @@ export const MachineDetails = () => {
<span class="justify-self-end font-light">has hw spec</span>
<span>{data().has_hw_specs ? "Yes" : "Not yet"}</span>
<div class="col-span-2 justify-self-center">
<button
class="btn btn-primary join-item btn-sm"
@@ -102,6 +168,52 @@ export const MachineDetails = () => {
Generate HW Spec
</button>
</div>
<button
class="btn self-end"
onClick={() => remoteDiskQuery.refetch()}
>
Refresh remote disks
</button>
<Form onSubmit={handleSubmit} class="w-full">
<Field name="disk">
{(field, props) => (
<SelectInput
formStore={formStore}
selectProps={props}
label="Remote Disk to use"
value={String(field.value)}
error={field.error}
required
options={
<Show when={remoteDiskQuery.data}>
{(disks) => (
<>
<option disabled>
Select the boot disk of the remote machine
</option>
<For each={disks().blockdevices}>
{(dev) => (
<option value={dev.name}>
{dev.name}
{" -- "}
{dev.size}
{"bytes @"}
{
query.data?.machine.deploy.targetHost?.split(
"@",
)?.[1]
}
</option>
)}
</For>
</>
)}
</Show>
}
/>
)}
</Field>
</Form>
</div>
)}
</Show>