Make rollback a GRUB snapshot reboot
Some checks failed
dev release / build (push) Has been cancelled
Some checks failed
dev release / build (push) Has been cancelled
Updates leads with “Boot a snapshot from GRUB (BOS snapshots)” and links to Snapshots. Snapshots is the list to pick in GRUB, not snapper rollback.
This commit is contained in:
parent
0798fad697
commit
3aad09c9ef
4 changed files with 36 additions and 8 deletions
3
frontend/src/lib/nav.ts
Normal file
3
frontend/src/lib/nav.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
/** Sidebar page switch. Set from +page.svelte; views call it to jump. */
|
||||||
|
export type Navigate = (page: string) => void;
|
||||||
|
export const NAVIGATE_KEY = "bos-settings-navigate";
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
if (!selected) return;
|
if (!selected) return;
|
||||||
if (
|
if (
|
||||||
confirm(
|
confirm(
|
||||||
`Boot into snapshot #${selected}? Snapshots on BOS are booted directly from the GRUB menu (under "BOS snapshots"), not rolled back in place. Reboot now and pick this snapshot there.`,
|
`Reboot to pick snapshot #${selected} in GRUB? BOS boots snapshots from the GRUB “BOS snapshots” submenu. This does not run snapper rollback.`,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
invoke("reboot_system");
|
invoke("reboot_system");
|
||||||
|
|
@ -62,9 +62,10 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ViewScaffold title="Snapshots">
|
<ViewScaffold title="Snapshots">
|
||||||
|
<Hint text="This is how you undo a bad update: reboot and pick the snapshot in GRUB (BOS snapshots)." />
|
||||||
<Group
|
<Group
|
||||||
title="System snapshots"
|
title="What to pick in GRUB"
|
||||||
hint="Created automatically by snap-pac on each pacman transaction. Boot into one from the GRUB menu to recover; delete old ones here."
|
hint="Number, date, and description match the GRUB “BOS snapshots” submenu. Reboot, then choose that entry. This page does not run snapper rollback."
|
||||||
wide
|
wide
|
||||||
>
|
>
|
||||||
<div class="list">
|
<div class="list">
|
||||||
|
|
@ -75,6 +76,11 @@
|
||||||
{:else if snapshots.length === 0}
|
{:else if snapshots.length === 0}
|
||||||
<EmptyState icon={History} title="No snapshots yet" hint="Snapshots are created automatically on every pacman transaction." />
|
<EmptyState icon={History} title="No snapshots yet" hint="Snapshots are created automatically on every pacman transaction." />
|
||||||
{:else}
|
{:else}
|
||||||
|
<div class="row header" aria-hidden="true">
|
||||||
|
<span class="number">#</span>
|
||||||
|
<span class="date">Date</span>
|
||||||
|
<span class="desc">Description</span>
|
||||||
|
</div>
|
||||||
{#each snapshots as snap (snap.number)}
|
{#each snapshots as snap (snap.number)}
|
||||||
<button
|
<button
|
||||||
class="row"
|
class="row"
|
||||||
|
|
@ -91,7 +97,7 @@
|
||||||
|
|
||||||
<div class="btn-row">
|
<div class="btn-row">
|
||||||
<button onclick={refresh}>Refresh</button>
|
<button onclick={refresh}>Refresh</button>
|
||||||
<button disabled={!selected} onclick={bootIntoSelected}>Boot into selected…</button>
|
<button disabled={!selected} onclick={bootIntoSelected}>Reboot to pick in GRUB</button>
|
||||||
<button class="destructive" disabled={!selected} onclick={deleteSelected}>Delete selected</button>
|
<button class="destructive" disabled={!selected} onclick={deleteSelected}>Delete selected</button>
|
||||||
</div>
|
</div>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
@ -121,7 +127,15 @@
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row:hover {
|
.row.header {
|
||||||
|
background: transparent;
|
||||||
|
cursor: default;
|
||||||
|
opacity: 0.55;
|
||||||
|
font-size: var(--font-size-secondary, 12px);
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row:hover:not(.header) {
|
||||||
background-color: color-mix(in srgb, var(--surface), var(--on-surface) 8%);
|
background-color: color-mix(in srgb, var(--surface), var(--on-surface) 8%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from "svelte";
|
import { getContext, onMount } from "svelte";
|
||||||
import { invoke } from "@tauri-apps/api/core";
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
import { runStreamed } from "$lib/streaming";
|
import { runStreamed } from "$lib/streaming";
|
||||||
import ViewScaffold from "$lib/components/ViewScaffold.svelte";
|
import ViewScaffold from "$lib/components/ViewScaffold.svelte";
|
||||||
|
|
@ -7,9 +7,12 @@
|
||||||
import Hint from "$lib/components/Hint.svelte";
|
import Hint from "$lib/components/Hint.svelte";
|
||||||
import EmptyState from "$lib/components/EmptyState.svelte";
|
import EmptyState from "$lib/components/EmptyState.svelte";
|
||||||
import LogView from "$lib/components/LogView.svelte";
|
import LogView from "$lib/components/LogView.svelte";
|
||||||
|
import { NAVIGATE_KEY, type Navigate } from "$lib/nav";
|
||||||
import Download from "@lucide/svelte/icons/download";
|
import Download from "@lucide/svelte/icons/download";
|
||||||
import Cpu from "@lucide/svelte/icons/cpu";
|
import Cpu from "@lucide/svelte/icons/cpu";
|
||||||
|
|
||||||
|
const navigate = getContext<Navigate | undefined>(NAVIGATE_KEY);
|
||||||
|
|
||||||
interface PendingUpdate {
|
interface PendingUpdate {
|
||||||
name: string;
|
name: string;
|
||||||
current: string;
|
current: string;
|
||||||
|
|
@ -156,9 +159,13 @@
|
||||||
|
|
||||||
<Group
|
<Group
|
||||||
title="Rollback"
|
title="Rollback"
|
||||||
hint="BOS pins GRUB to rootflags=subvol=@, so snapper rollback does not change the running root. Boot a snapshot from the GRUB “BOS snapshots” submenu (grub-btrfs), or use the Snapshots page to reboot and pick one there."
|
hint="Boot a snapshot from GRUB (BOS snapshots)."
|
||||||
>
|
>
|
||||||
|
<Hint text="Snapshots lists number, date, and description so you know which GRUB entry to pick. snapper rollback will not change what GRUB boots (rootflags=subvol=@)." />
|
||||||
<Hint text="Bakery also has bakery rollback <pkg> for a single ecosystem binary — that is not a system rollback." />
|
<Hint text="Bakery also has bakery rollback <pkg> for a single ecosystem binary — that is not a system rollback." />
|
||||||
|
<div class="btn-row">
|
||||||
|
<button disabled={!navigate} onclick={() => navigate?.("snapshots")}>Open Snapshots</button>
|
||||||
|
</div>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<LogView lines={log} />
|
<LogView lines={log} />
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,18 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from "svelte";
|
import { onMount, setContext } from "svelte";
|
||||||
import { listen } from "@tauri-apps/api/event";
|
import { listen } from "@tauri-apps/api/event";
|
||||||
import Sidebar from "$lib/components/Sidebar.svelte";
|
import Sidebar from "$lib/components/Sidebar.svelte";
|
||||||
import Placeholder from "$lib/components/Placeholder.svelte";
|
import Placeholder from "$lib/components/Placeholder.svelte";
|
||||||
import { DEFAULT_PAGE } from "$lib/sidebar";
|
import { DEFAULT_PAGE } from "$lib/sidebar";
|
||||||
|
import { NAVIGATE_KEY, type Navigate } from "$lib/nav";
|
||||||
import { initTheme } from "$lib/theme";
|
import { initTheme } from "$lib/theme";
|
||||||
import { VIEWS } from "$lib/views/registry";
|
import { VIEWS } from "$lib/views/registry";
|
||||||
|
|
||||||
let activePage = $state(DEFAULT_PAGE);
|
let activePage = $state(DEFAULT_PAGE);
|
||||||
let ActiveView = $derived(VIEWS[activePage]);
|
let ActiveView = $derived(VIEWS[activePage]);
|
||||||
|
setContext<Navigate>(NAVIGATE_KEY, (page) => {
|
||||||
|
activePage = page;
|
||||||
|
});
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
initTheme();
|
initTheme();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue