system: validate installed rollback workflow
This commit is contained in:
@@ -11,9 +11,10 @@ This document defines the current canonical Fruix workflow for:
|
||||
- installing a declarative system onto an image or disk
|
||||
- booting through installer media
|
||||
- rolling forward to a candidate system
|
||||
- rolling back to an earlier declared system
|
||||
- switching an installed system to a staged candidate generation
|
||||
- rolling an installed system back to an earlier recorded generation
|
||||
|
||||
This is the Phase 19.1 operator-facing view of the system model already implemented in earlier phases.
|
||||
This is now the Phase 19 operator-facing view of the system model as validated through explicit installed-system generation switching and rollback.
|
||||
|
||||
## Core model
|
||||
|
||||
@@ -168,6 +169,34 @@ Use this when you want to:
|
||||
- install from an ISO-attached Fruix environment
|
||||
- test the same install model on more realistic VM paths
|
||||
|
||||
### Installed-system generation commands
|
||||
|
||||
Installed Fruix systems now also ship a small in-guest deployment helper at:
|
||||
|
||||
- `/usr/local/bin/fruix`
|
||||
|
||||
Current validated in-guest commands are:
|
||||
|
||||
```sh
|
||||
fruix system status
|
||||
fruix system switch /frx/store/...-fruix-system-...
|
||||
fruix system rollback
|
||||
```
|
||||
|
||||
Current intended usage:
|
||||
|
||||
1. build a candidate closure on the operator side with `./bin/fruix system build`
|
||||
2. ensure that candidate closure is present on the installed target's `/frx/store`
|
||||
3. run `fruix system switch /frx/store/...` on the installed system
|
||||
4. reboot into the staged candidate generation
|
||||
5. if needed, run `fruix system rollback`
|
||||
6. reboot back into the recorded rollback generation
|
||||
|
||||
Important current limitation:
|
||||
|
||||
- `fruix system switch` does **not** yet fetch or copy the candidate closure onto the target for you
|
||||
- it assumes the selected closure is already present in the installed system's `/frx/store`
|
||||
|
||||
## Deployment patterns
|
||||
|
||||
### 1. Build-first workflow
|
||||
@@ -261,7 +290,7 @@ Installed Fruix systems now record an explicit first-generation deployment layou
|
||||
|
||||
- `/var/lib/fruix/system`
|
||||
|
||||
Current validated shape:
|
||||
Initial installed shape:
|
||||
|
||||
```text
|
||||
/var/lib/fruix/system/
|
||||
@@ -275,6 +304,24 @@ Current validated shape:
|
||||
install.scm # present on installed targets
|
||||
```
|
||||
|
||||
After a validated in-place switch, the layout extends to:
|
||||
|
||||
```text
|
||||
/var/lib/fruix/system/
|
||||
current -> generations/2
|
||||
current-generation
|
||||
rollback -> generations/1
|
||||
rollback-generation
|
||||
generations/
|
||||
1/
|
||||
...
|
||||
2/
|
||||
closure -> /frx/store/...-fruix-system-...
|
||||
metadata.scm
|
||||
provenance.scm
|
||||
install.scm # deployment metadata for the switch operation
|
||||
```
|
||||
|
||||
Installed systems also now create explicit GC-root-style deployment links under:
|
||||
|
||||
- `/frx/var/fruix/gcroots`
|
||||
@@ -284,7 +331,9 @@ Current validated shape:
|
||||
```text
|
||||
/frx/var/fruix/gcroots/
|
||||
current-system -> /frx/store/...-fruix-system-...
|
||||
rollback-system -> /frx/store/...-fruix-system-...
|
||||
system-1 -> /frx/store/...-fruix-system-...
|
||||
system-2 -> /frx/store/...-fruix-system-...
|
||||
```
|
||||
|
||||
Important detail:
|
||||
@@ -294,7 +343,9 @@ Important detail:
|
||||
|
||||
## Roll-forward workflow
|
||||
|
||||
The current Fruix roll-forward model is declaration-driven.
|
||||
The current Fruix roll-forward model now has two validated layers.
|
||||
|
||||
### Declaration/deployment roll-forward
|
||||
|
||||
Canonical process:
|
||||
|
||||
@@ -314,47 +365,61 @@ Canonical process:
|
||||
5. boot or install the candidate
|
||||
6. validate the candidate closure in the booted system
|
||||
|
||||
The important property is that the candidate closure appears beside the earlier one in `/frx/store` rather than mutating it in place.
|
||||
### Installed-system generation roll-forward
|
||||
|
||||
When the candidate closure is already present on an installed target:
|
||||
|
||||
1. run `fruix system switch /frx/store/...candidate...`
|
||||
2. confirm the staged state with `fruix system status`
|
||||
3. reboot into the candidate generation
|
||||
4. validate the new active closure after reboot
|
||||
|
||||
The important property is still that the candidate closure appears beside the earlier one in `/frx/store` rather than mutating it in place.
|
||||
|
||||
## Rollback workflow
|
||||
|
||||
The current canonical rollback workflow is also declaration-driven.
|
||||
The current canonical rollback workflow also now has two validated layers.
|
||||
|
||||
Today, rollback means:
|
||||
### Declaration/deployment rollback
|
||||
|
||||
You can still roll back by redeploying the earlier declaration:
|
||||
|
||||
1. retain the earlier declaration that produced the known-good closure
|
||||
2. rebuild or rematerialize that earlier declaration
|
||||
3. redeploy or reboot that earlier artifact again
|
||||
|
||||
Concretely, the usual rollback choices are:
|
||||
Concretely, the usual declaration-level rollback choices are:
|
||||
|
||||
- rebuild the earlier declaration with `fruix system build` and confirm the old closure path reappears
|
||||
- boot the earlier declaration again through `fruix system image`
|
||||
- reinstall the earlier declaration through `fruix system install`, `installer`, or `installer-iso` if the deployment medium itself must change
|
||||
|
||||
This rollback story has already been validated at the closure/image/deployment level:
|
||||
### Installed-system generation rollback
|
||||
|
||||
- side-by-side base-version coexistence in `/frx/store`
|
||||
- roll-forward to a candidate closure
|
||||
- rollback by rebuilding and booting the earlier declaration again
|
||||
- validation on both local QEMU and the approved XCP-ng VM path
|
||||
When an installed target already has both the current and rollback generations recorded:
|
||||
|
||||
1. run `fruix system rollback`
|
||||
2. confirm the staged state with `fruix system status`
|
||||
3. reboot into the rollback generation
|
||||
4. validate the restored active closure after reboot
|
||||
|
||||
This installed-system rollback path is now validated on local `QEMU/UEFI/TCG`.
|
||||
|
||||
### Important scope note
|
||||
|
||||
This is not yet the same thing as a first-class installed-system generation switch command.
|
||||
This is still not yet the same thing as Guix's full `reconfigure`/generation UX.
|
||||
|
||||
Current rollback is:
|
||||
Current installed-system rollback is intentionally modest:
|
||||
|
||||
- **redeploy the earlier declaration again**
|
||||
|
||||
What still remains for later Phase 19 work is making rollback itself operator-driven at the installed-system layer, rather than only declaration/redeploy driven.
|
||||
- it switches between already-recorded generations on the target
|
||||
- it does not yet fetch candidate closures onto the machine for you
|
||||
- it does not yet expose a richer history-management or generation-pruning policy
|
||||
|
||||
Still pending:
|
||||
|
||||
- previous-generation tracking beyond the initial explicit generation-1 layout
|
||||
- an explicit rollback target link distinct from `current`
|
||||
- an operator-facing installed-system rollback workflow
|
||||
- generation switching without full redeploy
|
||||
- operator-facing closure transfer or fetch onto installed systems
|
||||
- multi-generation lifecycle policy beyond the validated `current` and `rollback` pointers
|
||||
- a fuller `reconfigure`-style installed-system UX
|
||||
|
||||
## Provenance and deployment identity
|
||||
|
||||
@@ -375,16 +440,16 @@ Operators should retain metadata from successful candidate and current deploymen
|
||||
|
||||
## Current limitations
|
||||
|
||||
The deployment workflow is now coherent, but it is not yet the final generation-management story.
|
||||
The deployment workflow is now coherent, and Fruix now has a validated installed-system switch/rollback path, but it is still not the final generation-management story.
|
||||
|
||||
Not yet first-class:
|
||||
|
||||
- a dedicated `switch` or `reconfigure` command
|
||||
- an installed-system rollback command that moves between generations in place
|
||||
- multi-generation retention and previous-generation tracking beyond generation 1
|
||||
- generation switching policy independent of full redeploy
|
||||
- host-side closure transfer/fetch onto installed systems as part of `fruix system switch`
|
||||
- a fuller `reconfigure` workflow that builds and stages the new closure from inside the target environment
|
||||
- multi-generation lifecycle policy beyond the validated `current` and `rollback` pointers
|
||||
- generation pruning and retention policy independent of full redeploy
|
||||
|
||||
Those are the next logical steps after the current explicit-generation layout.
|
||||
Those are the next logical steps after the current explicit-generation switch/rollback model.
|
||||
|
||||
## Summary
|
||||
|
||||
@@ -395,6 +460,8 @@ The current canonical Fruix deployment model is:
|
||||
- **materialize** the artifact appropriate to the deployment target
|
||||
- **boot or install** that artifact
|
||||
- **identify deployments by closure path and provenance metadata**
|
||||
- **roll back by rebuilding/redeploying the earlier declaration**, not by mutating the current closure in place
|
||||
- on installed systems, **switch** to a staged candidate with `fruix system switch`
|
||||
- on installed systems, **roll back** to the recorded rollback generation with `fruix system rollback`
|
||||
- still use declaration/redeploy rollback when the target does not already have the desired closure staged locally
|
||||
|
||||
That is the operator-facing workflow Fruix should document and use while installed-system generation switching remains more limited than Guix's mature in-place system-generation workflow.
|
||||
That is the operator-facing workflow Fruix should document and use while its installed-system generation UX remains simpler than Guix's mature in-place system-generation workflow.
|
||||
|
||||
Reference in New Issue
Block a user