Clan-app: generate hw spec via ssh

This commit is contained in:
Johannes Kirschbauer
2024-08-14 16:16:51 +02:00
parent 6709d47ae5
commit c86b14d34d
8 changed files with 148 additions and 29 deletions

View File

@@ -3,6 +3,7 @@ import { callApi, SuccessData } from "../api";
import { Menu } from "./Menu";
import { activeURI } from "../App";
import toast from "solid-toast";
import { useNavigate } from "@solidjs/router";
type MachineDetails = SuccessData<"list_inventory_machines">["data"][string];
@@ -16,7 +17,7 @@ export const MachineListItem = (props: MachineListItemProps) => {
const { name, info, nixOnly } = props;
const [deploying, setDeploying] = createSignal<boolean>(false);
const navigate = useNavigate();
return (
<li>
<div class="card card-side m-2 bg-base-200">
@@ -63,11 +64,11 @@ export const MachineListItem = (props: MachineListItemProps) => {
<ul class="menu z-[1] w-52 rounded-box bg-base-100 p-2 shadow">
<li>
<a
// onClick={() => {
// setRoute("machines/edit");
// }}
onClick={() => {
navigate("/machines/" + name);
}}
>
Edit
Details
</a>
</li>
<li

View File

@@ -3,10 +3,15 @@ import { Header } from "./header";
import { Sidebar } from "../Sidebar";
import { activeURI, clanList } from "../App";
import { RouteSectionProps } from "@solidjs/router";
import { Toaster } from "solid-toast";
export const Layout: Component<RouteSectionProps> = (props) => {
createEffect(() => {
console.log("Layout props", props.location);
});
return (
<div class="h-screen bg-gradient-to-b from-white to-base-100 p-4">
<Toaster position="top-right" />
<div class="drawer lg:drawer-open ">
<input
id="toplevel-drawer"

View File

@@ -1,6 +1,110 @@
import { callApi } from "@/src/api";
import { activeURI } from "@/src/App";
import { useParams } from "@solidjs/router";
import { createQuery } from "@tanstack/solid-query";
import { createSignal, Show } from "solid-js";
import toast from "solid-toast";
export const MachineDetails = () => {
const params = useParams();
return <div>Machine Details: {params.id}</div>;
const query = createQuery(() => ({
queryKey: [activeURI(), "machine", params.id],
queryFn: async () => {
const curr = activeURI();
if (curr) {
const result = await callApi("get_inventory_machine_details", {
flake_url: curr,
machine_name: params.id,
});
if (result.status === "error") throw new Error("Failed to fetch data");
return result.data;
}
},
}));
const [sshKey, setSshKey] = createSignal<string>();
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">
<label class="justify-self-end font-light">Name</label>
<span>{data().machine.name}</span>
<span class="justify-self-end font-light">description</span>
<span>{data().machine.description}</span>
<span class="justify-self-end font-light">targetHost</span>
<span>{data().machine.deploy.targetHost}</span>
<div class="join col-span-2 justify-self-center">
<button
class="btn join-item btn-sm"
onClick={async () => {
const response = await callApi("open_file", {
file_request: {
title: "Select SSH Key",
mode: "open_file",
initial_folder: "~/.ssh",
},
});
if (response.status === "success" && response.data) {
setSshKey(response.data[0]);
}
}}
>
<span>{sshKey() || "Default ssh key"}</span>
</button>
<button
disabled={!sshKey()}
class="btn btn-accent join-item btn-sm"
onClick={() => setSshKey(undefined)}
>
<span class="material-icons">close</span>
</button>
</div>
<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"
onClick={async () => {
const curr_uri = activeURI();
if (!curr_uri) {
return;
}
if (!query.data?.machine.deploy.targetHost) {
return;
}
const lt = toast.loading("Generating HW spec ...");
const response = await callApi(
"generate_machine_hardware_info",
{
machine_name: params.id,
clan_dir: curr_uri,
hostname: query.data.machine.deploy.targetHost,
},
);
toast.dismiss(lt);
if (response.status === "success") {
toast.success("HW specification processed successfully");
}
if (response.status === "error") {
toast.error(
"Failed to generate. " + response.errors[0].message,
);
}
query.refetch();
}}
>
Generate HW Spec
</button>
</div>
</div>
)}
</Show>
</div>
);
};

View File

@@ -2,6 +2,7 @@ import { callApi, OperationArgs } from "@/src/api";
import { activeURI } from "@/src/App";
import { TextInput } from "@/src/components/TextInput";
import { createForm, required, reset } from "@modular-forms/solid";
import { useNavigate } from "@solidjs/router";
import { createQuery, useQueryClient } from "@tanstack/solid-query";
import { Match, Switch } from "solid-js";
import toast from "solid-toast";
@@ -9,6 +10,7 @@ import toast from "solid-toast";
type CreateMachineForm = OperationArgs<"create_machine">;
export function CreateMachine() {
const navigate = useNavigate();
const [formStore, { Form, Field }] = createForm<CreateMachineForm>({
initialValues: {
flake: {
@@ -49,7 +51,7 @@ export function CreateMachine() {
queryClient.invalidateQueries({
queryKey: [activeURI(), "list_machines"],
});
// setRoute("machines");
navigate("/machines");
} else {
toast.error(
`Error: ${response.errors[0].message}. Machine ${values.machine.name} could not be created`,