Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/Skidbladnir

.nornir/uninstall-for-idiots.md

UNINSTALL, for idiots

You installed a program on a server. Now you want it gone, properly, so that when you install it again it starts fresh — but you do not want to lose the little secret file that lets that server download your private code.

That is all this is. Nothing below assumes you know Rust or systemd.


The one sentence

Uninstall throws away all the program's data, and keeps its ssh key.

Every time. There is no extra flag to remember. If you have to pass a flag to get the correct behaviour, somebody built it wrong.


Why both halves matter

Throw the data away. The program keeps things like a warehouse of files, a registry, caches — gigabytes of it. If uninstall leaves that behind, the next install is not a fresh start: it wakes up holding old junk and behaves strangely. You reinstall because you want a clean machine.

Keep the ssh key. The key is a small file that proves to the code server "this machine is allowed to download". The key is registered on the other end. If you delete it, a new install cannot download anything at all, and nobody can fix that except a human who goes and registers a brand-new key on every single repository. That can take hours. So: the key stays.


What went wrong before (real, this happened)

Four programs did this four different ways and all four were wrong.

The two-that-deleted-nothing problem had one cause: the program looked for its data in one place and deleted from a different place. If the two disagree, one of them is lying to you.


The rule that fixes it

One folder. Written down once. The same folder no matter who runs the program.

Not "the user's home folder if a person runs it, some other folder if the system runs it". That kind of cleverness is exactly what caused it. One folder.

/var/lib/dwarves

And that folder is checked the moment you write it down. If you accidentally write somebody's home folder:

/home/rickard        →  REFUSED: it IS account `rickard`'s home directory
/                    →  REFUSED: it is a system directory

it will not let you. You find out immediately, not later when it is eating somebody's files.


What you do (three lines)

If you are wiring up a program, you write:

let root = DataRoot::new("/var/lib/dwarves")?;         // 1. where the data lives
let spec = ServiceSpec::new("dwarves", "…", "…")
    .data_root(&root);
Lifecycle::new(spec).uninstall()?;                     // 2. that is the uninstall

There is no step 3. You do not write any deleting code. You are not allowed to — that is the point.


What it tells you afterwards

If it worked:

✓ uninstall dwarves: unit removed; 7 data item(s) erased under /var/lib/dwarves;
  1 identity item(s) KEPT (ssh key + token survive byte-identical);

If it did nothing:

✗ uninstall dwarves: NOTHING was removed (data root /var/lib/dwarves)
  · data root /var/lib/dwarves does not exist or is unreadable — nothing to erase there

Notice the second one says ✗ and the words NOTHING was removed. It is not allowed to show you a green tick when it did nothing. That was the whole disaster: green tick, 5.3 GB still there.

If you see ✗, the machine is not clean. Read the line under it — it tells you why.


"But I really do want to delete the key too"

Sometimes you are decommissioning a machine for good. Then you say so, explicitly:

UninstallOptions::new().wipe_identity(true)

Before you do, understand what you are buying:

The key is registered on your code server. Deleting it means a future install on this machine cannot download anything until a person generates a new key and registers it on every single repository. Until they finish, that machine is useless.

If that is genuinely what you want, fine. It will never happen by accident — you have to type it.


"Can I delete the user account as well?"

Only together with the above. If you ask to delete the account without asking to delete the key, it refuses and tells you why:

REFUSING to remove the service account: the account OWNS the ssh deploy key, so
deleting it destroys the key as a side effect — the exact holger incident.

Because deleting the account takes its home folder, and its home folder has the key in it. That is how the key got destroyed twice the first time.


"I already have data in the old place"

If the program used to keep its data in your home folder (~/.dwarves, ~/.nornir), that old folder will just sit there forever unless somebody says where it was. So say where it was:

    .legacy_data_root("/home/rickard/.dwarves")

Uninstall then cleans the old place too, by the same rule (data gone, key kept), and tells you it did:

✓ uninstall dwarves: … legacy root /home/rickard/.dwarves swept;

Nothing is quietly moved and nothing is quietly ignored. You are told.


The four things to remember

  1. Uninstall always deletes the data. No flag.
  2. Uninstall always keeps the ssh key (and the token).
  3. One folder, written down once, the same for everybody.
  4. A ✗ means nothing was removed. Believe it, and read the reason.