Compare commits

...
6 changed files with 135 additions and 0 deletions

No files matched your search

@@ -1,3 +1,4 @@
export const NIXOS_LIST_GENERATIONS = "nixos:list-generations";
export const NIXOS_SET_GENERATION = "nixos:set-generation";
export const NIXOS_DELETE_GENERATION = "nixos:delete-generation";
export const NIXOS_DELETE_ALL_OLD_GENERATIONS = "nixos:delete-all-old-generations";
@@ -2,6 +2,7 @@ import {
NIXOS_LIST_GENERATIONS,
NIXOS_SET_GENERATION,
NIXOS_DELETE_GENERATION,
NIXOS_DELETE_ALL_OLD_GENERATIONS,
} from "./nixos-channels";
export type NixOSGeneration = {
@@ -23,5 +24,7 @@ export function exposeNixOSContext() {
ipcRenderer.invoke(NIXOS_SET_GENERATION, generationId),
deleteGeneration: (generationId: string) =>
ipcRenderer.invoke(NIXOS_DELETE_GENERATION, generationId),
deleteAllOldGenerations: () =>
ipcRenderer.invoke(NIXOS_DELETE_ALL_OLD_GENERATIONS),
});
}
@@ -4,6 +4,7 @@ import {
NIXOS_LIST_GENERATIONS,
NIXOS_SET_GENERATION,
NIXOS_DELETE_GENERATION,
NIXOS_DELETE_ALL_OLD_GENERATIONS,
} from "./nixos-channels";
import { NixOSGeneration } from "./nixos-context";
@@ -46,6 +47,18 @@ export function addNixOSEventListeners() {
};
}
});
ipcMain.handle(NIXOS_DELETE_ALL_OLD_GENERATIONS, async (_) => {
try {
const result = await deleteAllOldNixOSGeneration();
return result;
} catch (error) {
console.error("Failed to delete all NixOS generations:", error);
return {
success: false,
error: error instanceof Error ? error.message : String(error),
};
}
});
}
async function listNixOSGenerations(): Promise<{
@@ -179,6 +192,48 @@ async function deleteNixOSGeneration(generationId: string): Promise<{
});
}
async function deleteAllOldNixOSGeneration(): Promise<{
success: boolean;
error?: string;
}> {
return new Promise((resolve) => {
const process = spawn("sudo", [
"sh",
"-c",
`nix-collect-garbage --delete-old`,
]);
let stderr = "";
let stdout = "";
process.stdout?.on("data", (data) => {
stdout += data.toString();
});
process.stderr?.on("data", (data) => {
stderr += data.toString();
});
process.on("close", (code) => {
if (code === 0) {
resolve({ success: true });
} else {
resolve({
success: false,
error: stderr || stdout || `Process exited with code ${code}`,
});
}
});
process.on("error", (error) => {
resolve({
success: false,
error: error instanceof Error ? error.message : String(error),
});
});
});
}
function parseNixOSGenerations(output: string): NixOSGeneration[] {
const lines = output.trim().split("\n");
const generations: NixOSGeneration[] = [];
+13
View File
@@ -59,6 +59,19 @@ export async function deleteNixOSGeneration(generationId: string): Promise<{
};
}
}
export async function deleteAllOldNixOSGeneration(): Promise<{
success: boolean;
error?: string;
}> {
try {
return await window.nixos.deleteAllOldGenerations();
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : String(error),
};
}
}
/**
* Check if NixOS context is available
+61
View File
@@ -15,6 +15,7 @@ import {
setNixOSGeneration,
deleteNixOSGeneration,
isNixOSAvailable,
deleteAllOldNixOSGeneration,
} from "@/helpers/nixos_helpers";
import { useUpdateStore } from "@/stores/updateStore";
import { useGithubSourceStore } from "@/stores/githubSourceStore";
@@ -50,6 +51,9 @@ export function ChooseVersionPage() {
const [generationActionLoading, setGenerationActionLoading] = useState<
string | null
>(null);
const [deleteAllActionLoading, setdeleteAllActionLoading] = useState<
boolean | false
>(false);
const { githubSource, setGithubSource } = useGithubSourceStore();
@@ -341,6 +345,37 @@ export function ChooseVersionPage() {
}
};
const handleDeleteAllOldGeneration = async () => {
if (
!confirm(
`Are you sure you want to delete all old generation This will also update the bootloader menu. This action cannot be undone.`,
)
) {
return;
}
setdeleteAllActionLoading(true)
try {
const result = await deleteAllOldNixOSGeneration();
if (result.success) {
// Refresh the generations list
const updatedResult = await listNixOSGenerations();
if (updatedResult.success) {
setNixosGenerations(updatedResult.generations);
}
console.log(
`Successfully deleted all old generations`,
);
} else {
console.error(`Failed to delete generation: ${result.error}`);
setNixosError(result.error || "Failed to delete all old generations");
}
} catch (error) {
console.error("Error deleting generation:", error);
setNixosError(error instanceof Error ? error.message : String(error));
} finally {
setdeleteAllActionLoading(false);
}
};
return (
<Page>
<SectionTitle title="Current Version"></SectionTitle>
@@ -533,8 +568,14 @@ export function ChooseVersionPage() {
</span>
)}
<DeleteAllButton
onDeleteAll={()=> handleDeleteAllOldGeneration()}
isLoading = {deleteAllActionLoading}//DOTO: Set the Variable to true when it ist loading
/>
{nixosGenerations !== undefined && nixosGenerations.length > 0 ? (
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
{nixosGenerations.map((generation) => (
<GenerationButton
key={generation.id}
@@ -623,6 +664,26 @@ function GenerationButton({
);
}
type DeleteAllButtonProps = {
isLoading: boolean;
onDeleteAll:() => void;
};
function DeleteAllButton({
isLoading,
onDeleteAll,
}: DeleteAllButtonProps){
return (
<div className="flex gap-2">
<TouchButton
variant="destructive"
disabled = {isLoading}
onClick={onDeleteAll}>
{isLoading? <LoadingSpinner/>: "Delete All Versions"}
</TouchButton>
</div>
)
}
type UpdateButtonProps = {
time?: Date;
title: string;
+2
View File
@@ -86,6 +86,8 @@ interface NixOSContext {
deleteGeneration: (
generationId: string,
) => Promise<{ success: boolean; error?: string }>;
deleteAllOldGenerations: (
) => Promise<{ success: boolean; error?: string }>;
}
declare interface Window {
themeMode: ThemeModeContext;