Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e0b56c976f | |||
| bbd59f4a44 | |||
| b03a105375 | |||
| 955a4f07b7 | |||
| 7c97c949f6 | |||
| 4d6ec7c7bb | |||
| 2d05b29b82 | |||
| 823cd2949b | |||
| fc737b0fc0 | |||
| d102ca5767 | |||
| 684cd2eb11 | |||
| 4906aeb3f9 | |||
| 8b188bea68 | |||
| 6362bb6cb6 | |||
| 1d4985d87c | |||
| c1319a91a8 |
@@ -125,6 +125,13 @@ something, not only sessions that touch `documentation/` — which is why it is
|
||||
the operator in plain language, and deliberately **not** `CONTEXT.md`.
|
||||
- **The capability map** (`documentation/architecture/00-capability-map.md`), if a capability's
|
||||
status changed — with its new evidence citation.
|
||||
- **`python3 scripts/unproven.py --summary`** — one line per status, and the not-walked total. Run it
|
||||
at the end of any session that shipped, broke or proved something, and **say in the report if a
|
||||
number moved**. It exists because "which claims are unproven?" was answerable only by a person
|
||||
reading a page: a session asked for "the nine grey claims" could not determine which nine and
|
||||
rightly refused to guess (R-326). *Nine was real and answered a different question — it is the
|
||||
count of claims the 2026-08-09 pass DOWNGRADED. Not-walked is 32 of 55.* A status that moves
|
||||
without anyone noticing is how the picture stops being true.
|
||||
- **Confirm your own last push's CI run went green, by run ID.** CI emails on failure, which is a
|
||||
PUSH signal; this is the PULL check that catches a lost, filtered or unread mail. Quote the run id
|
||||
and its conclusion, e.g.
|
||||
|
||||
+222
@@ -15,6 +15,228 @@
|
||||
> would make one of the two audiences stop reading. `STATUS.md` is also a **view of `OPEN-ITEMS.md`**
|
||||
> and holds nothing of its own; this file does hold its own content, namely the standing rulings below.
|
||||
|
||||
## A name must differ from its neighbours on a stem, not on a noun (2026-08-13, R-323)
|
||||
|
||||
The third near-homograph is renamed: the five-word phrase that proves an account owns the box being
|
||||
bound is „**Tulajdonosi jelmondat**". It was „Visszaállító jelszó" — one word from the „Visszaállító
|
||||
kód" retired days earlier, and false besides: **the phrase restores nothing.**
|
||||
|
||||
**The rule this instance yields, and it generalises past this secret.** Both obvious replacements were
|
||||
rejected, and the reasons are the transferable part:
|
||||
|
||||
- **Do not name a secret after the ACT it is used in, when another secret on the same screen is named
|
||||
after the same act.** The other factor on that page is the „**Párosító kód**". „Összekötési jelszó"
|
||||
would have left the two things a customer types in one sitting separated only by *kód*-versus-
|
||||
*jelszó* — **structurally the very trap being removed**. A name that matches the page's verb feels
|
||||
right and is the wrong axis.
|
||||
- **Do not name a secret after a THING that already has a password.** „Fiókjelszó" collides with the
|
||||
dashboard login, i.e. trades one homograph for a worse one.
|
||||
- **Separate on the STEM first, the noun second.** Beállító / Helyreállítási / Párosító / **Tulajdonosi**
|
||||
— four distinct stems; *kód* / *jelmondat* is the second axis, not the first. A pair distinguished
|
||||
only by its noun is what failed twice.
|
||||
|
||||
**Naming is not function, and the pin says so** (`TestSelfBindPassphrase_StillAcceptedAfterTheRename`
|
||||
drives the real handler with human-messy spacing). **Nothing printed was stranded** — no customer
|
||||
document names the phrase; it is delivered out-of-band, so the description in the hint sentence is
|
||||
what identifies it, which is why that sentence was kept and extended rather than trimmed.
|
||||
|
||||
## A guard is worth what its positive control is worth (2026-08-13, R-324)
|
||||
|
||||
The hub's customer copy came under a guard for the first time — every customer e-mail and both binding
|
||||
pages, the sentences a customer reads *before* they have seen any box screen. Nothing had ever looked
|
||||
at them, in either repo.
|
||||
|
||||
**The part worth carrying: the selftest found a defect in the guard itself on its first run.** The
|
||||
plant→convict→remove→pass control convicted its own step-3 case (a phrase inside a comment) because
|
||||
the synthetic source was named `<selftest>` and comment-stripping keys off the `.go` extension. **A
|
||||
guard that had shipped without a control would have been quietly over-broad**, and the first person to
|
||||
write an honest explanatory comment would have been convicted by it.
|
||||
|
||||
**And on sharing a word list across two repos:** the vocabulary lives once, in `scripts/`, the same
|
||||
home both repos already consume gates from. The consumer that could not be edited that evening is
|
||||
**drift-checked rather than duplicated** — the gate reads the other gate's literal and fails on
|
||||
divergence. That is a scaffold with a register row (R-325) to remove it, not a design; **two copies of
|
||||
a word list is the R-299 defect waiting to happen**, and a drift check is the cheapest way to refuse
|
||||
the copy without making a cross-repo edit at the wrong moment.
|
||||
|
||||
## Suppress an alarm on the machine's own declaration, never on an inference — and check for the second door (2026-08-13, R-321)
|
||||
|
||||
A box whose reporting is deliberately switched off announces it (`health.status = "disabled"`) and
|
||||
then goes quiet by design. The hub stored that, rendered it, and **alarmed on it anyway**, because the
|
||||
staleness verdict was computed from report AGE alone.
|
||||
|
||||
**Three things worth carrying:**
|
||||
|
||||
1. **The discriminator must be the box's own last word.** That is what made this a suppression rather
|
||||
than a guess — and the standing rule is right that suppressing on a guess is worse than the false
|
||||
alarm it removes.
|
||||
2. **RECORD the state; do not delete it.** The `blocked` precedent deletes, and `GetState` then
|
||||
returns `""` — which is not `"down"`, so **`CheckBackupDeadlines` would have gone on alarming from
|
||||
a second function.** One fix, two doors; R-195's shape returning through the one nobody looked at.
|
||||
*Ask of any suppression: which OTHER checker reads this state, and what does it see now?*
|
||||
3. **A clock must restart at the event that ends the suppression**, not at the last observation before
|
||||
it began. Timing from the pre-disable report would fire an instant stale/down for a quiet period we
|
||||
requested. Re-entering the new-customer branch gives a first observation instead of a recovery
|
||||
event.
|
||||
|
||||
**The limit is stated in the code, not hidden:** a box re-enabled that then fails to report keeps
|
||||
being suppressed, because the hub's view changes only when a report arrives. **That is why the state
|
||||
is made visible** — an operator who re-enabled a box and still sees `disabled` is being told it has
|
||||
not come back.
|
||||
|
||||
**And a test lesson:** red-proof 2 revealed that scenario A passed on its state assertion alone even
|
||||
with the suppression deleted, because it seeded the customer *already* disabled and the new-customer
|
||||
branch swallows the first observation. **A test that cannot see the alarm it exists to prevent is not
|
||||
a test** — it now observes the machine healthy first.
|
||||
|
||||
## A number everyone repeats is a claim, and claims get checked (2026-08-13, R-326)
|
||||
|
||||
"The nine grey claims" was repeated across sessions and **exists nowhere**. A session asked to report
|
||||
on them could not determine which nine and declined to guess; that refusal was correct and is the
|
||||
finding.
|
||||
|
||||
**Nine is real and answers a different question: it is the count of claims carrying
|
||||
`verdict: downgraded`** — the ones the 2026-08-09 pass *lowered*. The count of unproven claims is
|
||||
**32 of 55** (`walked` 23, `partial` 14, `built` 14, `missing` 4), and of those 32 only **6** cite an
|
||||
evidence document.
|
||||
|
||||
`scripts/unproven.py` makes it a command, wired into the end-of-session checklist. **The generalisable
|
||||
part: a picture built for a person to read is not a picture anyone can check.** The dataset carried the
|
||||
statuses all along; what was missing was one command that answers the question the operator actually
|
||||
asked. Its first run found a stale claim (R-327) — which is the argument for having built it.
|
||||
|
||||
## A fact the boxes send and the hub cannot read is a future false green — and one now has a reader (2026-08-13, R-319)
|
||||
|
||||
**The first of R-264's twenty-one unconsumed facts is read.** The agent emitted `guest_net` on every
|
||||
heartbeat for **twenty-three days** (agent v0.92.0, R-54, 2026-07-21) while the string occurred
|
||||
**nowhere** in `felhom.eu/hub/` — stored as raw text in `report_json`, reaching no check, no alarm and
|
||||
no screen. Hub v0.104.0 models it: `parseGuestNet`/`guestNet` in `web/hosts.go`, rendered as the
|
||||
host-detail **Guest network** card.
|
||||
|
||||
**The rule this instance teaches, and it generalises past guest networking:**
|
||||
|
||||
- **Read the fact that carries the RISK, not the fact that is easiest to render.** Here that is
|
||||
`heals_last_hour`, not `state`. A guest the watchdog keeps repairing is healthy at every instant
|
||||
anyone looks and is nevertheless failing — rendering the state alone gives it a green tick, which is
|
||||
the failed-disk-drawn-as-a-healthy-empty-disk shape wearing different clothes.
|
||||
- **Decode the field that decides the question, not five of the eight.** `heal_succeeded` was added
|
||||
mid-build for exactly this: six FAILED repairs is a guest that is down, six successful ones is a
|
||||
nuisance, and the count alone cannot tell them apart. **R-260 is the standing warning** — a hub
|
||||
decoder three fields short of the agent dropped the one its checker existed to answer.
|
||||
- **Three absences, three sentences.** Agent too old / capable agent silent / guest state not asserted.
|
||||
All render unknown; conflating them is how an operator starts ignoring a card. The state switch is an
|
||||
**allow-list**, so adding a state to the agent can never silently paint it green here.
|
||||
- **REMOVING an allowlist entry is what proves a reader is wired.** An allowlisted tag is *skipped* by
|
||||
`wire_contract_gate.py`. Re-labelling the eight `guest_net` entries would have left the new reader's
|
||||
own fields unchecked while the gate reported coverage. Deleting them moved checked tags **182 → 190**
|
||||
and skipped **88 → 80** — the positive control that the wiring is real, independent of any test.
|
||||
- **A card is not an alarm, and building the card first is deliberate.** No email was added: the
|
||||
incident behind this (a killed `dhclient`, tunnel down 1 h 15 m, nobody told) was a **visibility**
|
||||
failure, and with zero repairs ever recorded on either demo box any alarm threshold would be invented.
|
||||
**The visible count is what will supply the threshold.**
|
||||
|
||||
**Where the twenty stand** (R-264, counts measured from the allowlist rather than estimated):
|
||||
**8 read · 5 deliberately not consumed · 1 redundant · 6 still owed a reader.** The gate grew a **third**
|
||||
entry kind — `not consumed, deliberately` — because an undecided fact and a decided one must not read
|
||||
alike, and *"arguably owed"* had been carried for five days as though it were a decision.
|
||||
|
||||
**Two findings came out of deciding the last one rather than from building anything:**
|
||||
|
||||
- **R-321** — `reporting_disabled` is *redundant* (`health.status = "disabled"` travels beside it, is
|
||||
decoded, and IS rendered), **but `StalenessChecker.Check` is age-only** (`monitor/staleness.go:88+`,
|
||||
sole skip `IsCustomerBlocked`), so a deliberately-silent box still alarms `node_stale` then
|
||||
`node_down`. **Decoding the flag would have felt like progress and left the alarm firing** — the fix
|
||||
belongs in the checker, which already holds the status it needs.
|
||||
- **R-322** — `retrieval_promise_gate.py` has **never scanned the hub**, which composes every customer
|
||||
e-mail, i.e. the copy read *before* any box screen. A hand scan with its own four stems returns zero,
|
||||
so it is a scope gap rather than a live defect — recorded before someone writes the first hub-side
|
||||
retrieval promise assuming the guard has them covered.
|
||||
|
||||
## One secret in two situations keeps its NAME and changes its SENTENCE — and the mail must name the page the machine shows (2026-08-13, R-295 hub half)
|
||||
|
||||
The box side shipped 2026-08-10; the hub half was dropped twice and was the last place „Visszaállító
|
||||
kód" survived — in the **mails**, the one surface a customer reads *before* they see any screen. It is
|
||||
now „**Beállító kód**" everywhere; the ten-word escrow code stays „**Helyreállítási kód**"; no
|
||||
dashboard-code mail names both.
|
||||
|
||||
**The mechanism worth carrying: the mail names a PAGE, and which page depends on state only the hub
|
||||
knows.** `ReissueForReenroll` sent the *reset* mail, directing the customer to „Elfelejtett jelszó" —
|
||||
but a rebuilt box has no password, so the controller computes `reset := s.authEnabled()` → false
|
||||
(`felhom-controller/controller/internal/web/claim.go:279`), renders „**A szerver beállítása**", and
|
||||
serves **no login page at all**. The named route was not on their screen. **The two situations are
|
||||
distinguishable only at the hub, because the hub chose which call site fired** — so the fix is a new
|
||||
`EmailKind` (`reenroll`), not a reworded shared template. A `default` branch falls back to the
|
||||
first-setup mail, which is the safe direction and is pinned so a future reader knows it was chosen.
|
||||
|
||||
**The re-enrol mail deliberately says nothing about apps or backups.** A clean-slate reinstall is
|
||||
precisely where that reassurance could be false; `TestFormatClaimEmail_ReenrollPromisesNothingAboutTheData`
|
||||
guards the CLAIM rather than one phrasing of it.
|
||||
|
||||
**Naming is not function, and the pin says so:** `TestReenrollSplit_ChangesTheMailNotTheSecret` — the
|
||||
generation still advances, the stored bcrypt hash still verifies the emailed code, no plaintext is
|
||||
persisted. Box-side companion: the controller's `TestResetCode_StillAcceptedOnTheSetupPage`.
|
||||
|
||||
## Evidence dies in the INTERMEDIATE revert, not the final one (2026-08-13, R-320)
|
||||
|
||||
Twice in three days, on the same box at the same point, a phase's logs were destroyed by a revert to
|
||||
`virgin` *between* phases (drill 2026-08-12 Phase A→B; R-316 2026-08-13 Part 1→2). Both times the
|
||||
golden-bake runbook's existing *"scp the log OUT first"* was applied to the **final** teardown and not
|
||||
the middle one. Both times the conclusions survived on luck.
|
||||
|
||||
**Standing rule 5** now: evidence comes off at the end of the phase that produced it, before any revert
|
||||
— **the pull is the LAST ACT OF THE PHASE**, not a step to remember later. Four homes:
|
||||
`workspace-CLAUDE.md`, `runbooks/target-selection.md`, `RUNBOOK-rehearsal-v3.md`, `PROMPT-TEMPLATE.md`
|
||||
report item 8. **And the already-gone case is documented rather than improvised:** say so plainly and
|
||||
reproduce the finding independently.
|
||||
|
||||
**A corollary this session hit immediately:** the second incident was recorded in `REPORT.md`, which
|
||||
every session overwrites — writing tonight's report would have **destroyed the record of a destroyed
|
||||
record**. It was preserved to `audits/REPORT-r316-installer-v1.28.0-2026-08-13.md` first. *A durable
|
||||
citation may never point at a file whose contract is to be overwritten.*
|
||||
|
||||
## Material retained is not history recoverable — ask the three questions separately (2026-08-12)
|
||||
|
||||
**"We keep the old key" and "the customer can get their old backups back" are three questions, and
|
||||
collapsing them is how a false belief survived a week.** Ask them one at a time, and answer each with
|
||||
its own evidence:
|
||||
|
||||
**(a) Is the material retained?** **(b) Does it, once unsealed, still open the old store?**
|
||||
**(c) Does the customer have a ROUTE to (b) through the product?**
|
||||
|
||||
Measured 2026-08-12, and the answers were **yes, yes, no** — a shape nobody had predicted. Our records
|
||||
predicted (a) yes and (b) no ("a box we fill and cannot open"); the drill found (b) works and **(c) was
|
||||
the missing one.** `ListSupersededEscrow` had held the right bytes since v0.93.0 with **zero production
|
||||
callers**, so the capability existed and was unreachable. The same afternoon's follow-up shipped a
|
||||
partial (c) — the product now RECOGNISES a correct code for an earlier package — and established that
|
||||
the rest of (c) is new surface, not wiring, because every restore entry point resolves its repository
|
||||
from settings and its password from one file (R-312).
|
||||
|
||||
**The generalisation, which is the part worth keeping:** a stored artifact proves storage, never
|
||||
usability. Between "the bytes are kept" and "the customer is helped" sit an unseal, a consumer and a
|
||||
route, and each has been separately absent in this project. **Before claiming a capability, name which
|
||||
of the three you have evidence for** — and if a comment or a card asserts the third, find the code path
|
||||
that performs it or move the claim.
|
||||
|
||||
## A removal that leaves the package leaves the next install a second-cycle machine (2026-08-13)
|
||||
|
||||
**Stopping is not removing, and the difference does not show up until the cycle after next.** R-300
|
||||
stopped and disabled the resolver we install and left the package in place — deliberately, as the
|
||||
conservative act. Cycle 1 looked fixed and *was* fixed. But the next install asks dpkg "is this
|
||||
installed?", gets yes, records the package as the household's, and the uninstall after that leaves it
|
||||
running: cycle 3 refuses with the message that blames the customer's network. **Measured, three cycles,
|
||||
before anything was changed.**
|
||||
|
||||
**The general shape:** a teardown that leaves an artifact behind does not merely fail to clean up — it
|
||||
*changes what the next run concludes about who owns that artifact*. Ask of any "we left it in place,
|
||||
to be safe": **what will the next install think this is?** If the answer is "ours, misread as theirs",
|
||||
the conservative act has quietly become the destructive one, one cycle downstream.
|
||||
|
||||
**And the corollary that nearly shipped a second defect:** the thing you remove and the thing something
|
||||
else probes for may be in **different packages**. `dnsmasq` ships the unit; `dnsmasq-base` ships the
|
||||
binary the agent stats to decide whether to install. Removing one and not the other satisfies the
|
||||
uninstall and breaks the next install silently (R-317). **Before removing a package, ask what else
|
||||
tests for the files it shares with its siblings.**
|
||||
|
||||
## Two rules earned twice each (2026-08-12)
|
||||
|
||||
**A fact must be recorded at the moment it is a fact, not inferred later from something adjacent.**
|
||||
|
||||
@@ -1,87 +1,353 @@
|
||||
# REPORT — DRILL: the retained key, and the two fixes nobody had watched work (2026-08-12)
|
||||
# REPORT — the third near-homograph, a machine told to be quiet, and a picture you can query (2026-08-13, late)
|
||||
|
||||
**Class:** drill (unattended, destructive on Tier 0) + spike for Phase C's first step
|
||||
**Venues:** `drill-r50` (nested PVE on DooPlex), `demo-felhom` (guest 9201) — both Tier 0.
|
||||
**`demo-hp` was never touched. `peti-felhom` was never contacted. No abandon countdown was started,
|
||||
shortened or triggered.**
|
||||
**Full record:** `documentation/audits/DRILL-retained-key-2026-08-12.md`
|
||||
**Shipped: hub v0.105.0, deployed and verified.** All three parts complete; **nothing dropped**.
|
||||
**`demo-hp` was not touched** — see §8. No controller change, no agent change, no wire change, so no
|
||||
bake and no approval.
|
||||
|
||||
---
|
||||
|
||||
## The answer to the question this drill existed to answer
|
||||
## 1. Part 1 — the enumeration, the name, and the reasoning
|
||||
|
||||
**(a) Is the old key kept? YES** — proven for the first time in the fleet's history.
|
||||
**(b) Does the kept key open the old backups? YES** — three planted files, including a Hungarian
|
||||
accented filename verified as raw bytes, restored **byte-identical** from a store the machine itself
|
||||
could no longer open.
|
||||
**(c) Can the customer get there through the product? NO — and they are told their correct code is
|
||||
wrong.**
|
||||
**Enumerated before editing. Five customer-facing sites, all in the hub:**
|
||||
|
||||
The brief said to be ready for the answer to be no, and our own records predicted retention would be
|
||||
*"a box we fill and cannot open"*. **That was half right, and the wrong half was the one nobody had
|
||||
checked.** The box opens. What does not exist is the door: `ListSupersededEscrow`
|
||||
(`hub/internal/store/store.go:2841`) is the only reader of a retained key and has **zero production
|
||||
callers**; the recovery path selects `FROM host_escrow` — the current row only. Asked with the very
|
||||
code that had just opened the retained row by hand, the product answered *"the recovery code did not
|
||||
open the sealed bundle — nothing was written"*. → **R-304, rank 1**
|
||||
| `file:line` | what it is |
|
||||
|---|---|
|
||||
| `hub/internal/web/selfbind.go:255` | the binding page's lead sentence |
|
||||
| `hub/internal/web/selfbind.go:256` | the failure banner (said „a jelszót" — generic, but naming the secret) |
|
||||
| `hub/internal/web/selfbind.go:261` | the field label — „Visszaállító jelszó" |
|
||||
| `hub/internal/web/selfbind.go:263` | the hint under the field |
|
||||
| `hub/internal/notify/templates.go:331` | the self-bind e-mail, item 2 |
|
||||
|
||||
Consequences: the census answer **stands**; the countdown banner's promise is **true in substance,
|
||||
false in practice**; the capability map's recovery claim **has been moved** with today's evidence.
|
||||
**No halt. The name appears nowhere in `felhom-controller` or `felhom-agent`** — the only hits there
|
||||
are comments and a test asserting the *already-retired* „Visszaállító **kód**" is absent, which is a
|
||||
different secret. Operator surfaces call it *"Retrieval Password"* in English and the installer uses
|
||||
`FELHOM_RETRIEVAL_PASSPHRASE` as a shell identifier; neither is customer copy and neither was touched.
|
||||
|
||||
## What shipped
|
||||
### The name: **„Tulajdonosi jelmondat"**
|
||||
|
||||
**`installer-v1.27.0` published** — tag cut and **both** `--ref`s in `manifests/webpage.yaml` bumped
|
||||
(sidecar line 327, init container line 372). Publication was earned: both faults were watched
|
||||
happening first, from a machine reset to factory state.
|
||||
Checked against the table rather than against a habit. The phrase **proves the account owns the box
|
||||
being bound — it restores nothing, so the old name was simply false.**
|
||||
|
||||
- **R-300 CLOSED** — pre-fix uninstall left dnsmasq `enabled`/`active` on `0.0.0.0:53`; the next byo
|
||||
install refused, exit 1. Fixed path: recorded `not present before Felhom` → `stopping + disabling
|
||||
it` → `:53 FREE` → preflight PASS. The owner's side proven too (record `yes` → left running).
|
||||
- **R-297 CLOSED** — a stale `golden-0.98.3.tar.zst` planted as newest-by-filename; v1.25.0 took it
|
||||
with no comparison and **the box came up on controller 0.98.3** against a vouched 0.213.0 — below
|
||||
the floor and below v0.206.0 where the off-site recovery screen exists. Fixed path re-fetched and
|
||||
sha-verified the vouched golden (landed 0.213.0); an operator-named stale archive was **refused**.
|
||||
**Both of your suggestions are rejected, and the reasons are the argument:**
|
||||
|
||||
## Findings opened — ceiling R-303 → R-310
|
||||
- **„Fiókjelszó" is worse than the trap it fixes.** There *is* an account password — the dashboard
|
||||
login. This name would collide with a **different real secret**, trading one homograph for a worse
|
||||
one.
|
||||
- **„Összekötési jelszó" recreates the trap structurally.** The other factor on this very page and in
|
||||
the same mail is the **„Párosító kód"** (`selfbind.go:258`, `templates.go:330`). Naming this one
|
||||
after the same act would leave the two factors a customer types **in one sitting** separated only by
|
||||
*kód*-versus-*jelszó* — which is precisely the „Visszaállító kód"/„Visszaállító jelszó" shape being
|
||||
removed. It matches the page's verb, and that is exactly the problem.
|
||||
|
||||
| # | Rank | What |
|
||||
**„Tulajdonosi jelmondat" is distinct on BOTH axes:**
|
||||
|
||||
| | stem | noun |
|
||||
|---|---|---|
|
||||
| **R-304** | **1** | Retained key has no product route; the correct old code is reported as wrong |
|
||||
| **R-305** | 2 | The R-300 cleanup fires **once per machine** — the leftover returns on the second reinstall (proven, cycles 2/3) |
|
||||
| **R-308** | 2 | Stored controller `PASSWORD` no longer opens demo-felhom (`Hibás jelszó`) — not the quoting trap |
|
||||
| **R-306** | 3 | `--preflight-only` says *"no state written"* and writes `state.json` — with an ownership answer that can be wrong |
|
||||
| **R-309** | 3 | The day-0 runbook says pushing publishes the installer; false since R-110 (measured: public URL served 1.25.0 while `main` had 1.27.0) |
|
||||
| **R-310** | 4 | Duplicated sentence in the golden refusal; `--uninstall` needs a pty and `--force` does not bypass it |
|
||||
| **R-307** | — | **Operator decision, deadline 2026-08-24** — see below |
|
||||
| „**Beállító** kód" | Beállító | kód |
|
||||
| „**Helyreállítási** kód" | Helyreállítási | kód |
|
||||
| „**Párosító** kód" (the other factor) | Párosító | kód |
|
||||
| „**Tulajdonosi** jelmondat" | **Tulajdonosi** | **jelmondat** |
|
||||
|
||||
## What needs you
|
||||
*If a plainer noun is ever wanted, „Tulajdonosi jelszó" is a one-word change — the **stem** is what
|
||||
carries the separation.*
|
||||
|
||||
**`demo-felhom` carries a live abandon countdown** — started 2026-08-10, **firing 2026-08-24**, for
|
||||
`/home/felhom-repo.orphaned-20260810`. This drill did **not** start it and deliberately did **not**
|
||||
cancel it. The brief's end state asked for no countdown anywhere; satisfying that means choosing:
|
||||
**cancel it** (copy kept indefinitely, storage cost, no data risk) or **let it run** (copy deleted,
|
||||
irreversibly). **Doing nothing selects deletion.** → **R-307**
|
||||
### As shipped, bytes confirmed
|
||||
|
||||
## End state
|
||||
| string | hex |
|
||||
|---|---|
|
||||
| `Tulajdonosi jelmondat` | `54756c616a646f6e6f7369206a656c6d6f6e646174` |
|
||||
| `tulajdonosi jelmondatodat` | `74756c616a646f6e6f7369206a656c6d6f6e6461746f646174` |
|
||||
| `tulajdonosi jelmondatot` | `74756c616a646f6e6f7369206a656c6d6f6e6461746f74` |
|
||||
| `Ez igazolja, hogy a fiók a tiéd` | `457a206967617a6f6c6a612c20686f67792061206669c3b36b2061207469c3a964` |
|
||||
|
||||
- **`demo-felhom`** — up, reporting, healthy, on the vouched pair; `repo_password` restored to the
|
||||
original (`sha c60c8bc737a6b7c6…`), escrow re-sealed and uploaded, off-site repo reachable
|
||||
(`restic snapshots` exit 0). Its recovery code was rotated by the final ceremony and
|
||||
`R_DEMO-FELHOM` updated in place (prior file backed up alongside). Planted data removed; eight
|
||||
secret-bearing files **shredded**.
|
||||
- **`demo-hp`** — untouched, reporting.
|
||||
- **`drill-r50`** — **reverted to snapshot `virgin`, powered off.**
|
||||
- **Hub** — two new retained rows (the P1 and P2 blobs), deliberately kept as the fixture proving the
|
||||
retention works. `drill-r50-0a4f9a` re-used, not duplicated: no new scratch customer.
|
||||
- **Off-site** — only demo-felhom's own repository path touched, `backup` the only mutating verb used.
|
||||
**No prune, no forget, no delete, no rename anywhere.** One snapshot added and deliberately left:
|
||||
`6ea85413`, 66 KiB, tagged `drill-retained-key-20260812` — removable by ID if you want it gone.
|
||||
Mojibake check clean in both files. **Naming only:** the form field is still `name="passphrase"`, and
|
||||
`TestSelfBindPassphrase_StillAcceptedAfterTheRename` drives the real handler with the same messy human
|
||||
spacing (`" Alpha Beta gamma-delta epsilon "`) and asserts the appliance still binds. The whole
|
||||
pre-existing self-bind suite (A, B, C1, C4, D, E, F, mint × 2) stayed green.
|
||||
|
||||
## Honest gaps
|
||||
---
|
||||
|
||||
- **The Phase A logs did not survive** the intermediate revert to `virgin`. Every quotation in the
|
||||
audit is verbatim from the live run, but the raw files are gone. Procedural lesson, recorded.
|
||||
- The planted data reached the store via `restic` directly, not the dashboard button, because of
|
||||
R-308 — so the app-backup→unit→offsite chain went unexercised. Not what this drill measured.
|
||||
- Wall clock **≈ 1 h 13 min** against a 4–5 h envelope. Nothing was dropped; Phase C ran concurrently
|
||||
with Phase B on a different machine.
|
||||
## 2. Does any customer-facing document name the old phrase? **No.**
|
||||
|
||||
Checked: `documentation/pilot/PETI-tester-agreement.md` does not mention the phrase **at all**;
|
||||
`RUNBOOK-onboarding-draft-v4.md` and `RUNBOOK-byo-deployment.md` name it by its **English operator**
|
||||
name ("retrieval passphrase"). The ISO/installer references are shell identifiers.
|
||||
|
||||
**So nothing printed is stranded.** The one honest caveat: the phrase reaches a customer
|
||||
**out-of-band** — `RUNBOOK-byo-deployment.md:11`, *"delivered to the box owner over a secure channel"*
|
||||
— so the only stale copy of the old name is whatever was said in a message or on the telephone. A
|
||||
person holding such a message would see „Tulajdonosi jelmondat" on the page, be told *"az öt szóból
|
||||
álló kifejezés, amelyet a beállításkor kaptál"*, and be holding exactly that: **the description
|
||||
identifies the thing even where the name has moved.** That was the reason for keeping the hint
|
||||
sentence and extending it with *"Ez igazolja, hogy a fiók a tiéd."*
|
||||
|
||||
---
|
||||
|
||||
## 3. Part 1b — the hub guard, and the control that found a bug in itself
|
||||
|
||||
`scripts/hub_copy_gate.py`, registered as gate 9 in `repo_gates.py`. **Two checks, deliberately
|
||||
different:**
|
||||
|
||||
1. **Retired names — banned outright**, across **all 95** hub `.go`/`.html` files, no allowlist. A
|
||||
name a different secret now owns is never correct anywhere. Comments are stripped, because the
|
||||
register rows and the code comments that record these decisions must quote the retired names.
|
||||
2. **Retrieval stems — registered, not banned**, in four declared customer surfaces
|
||||
(`notify/templates.go`, `web/selfbind.go`, `api/handler.go`, `notify/dispatcher.go`). A missing
|
||||
declared surface is a **FAILURE, never a skip**. The allowlist is **empty, and that is a
|
||||
measurement**: the hub makes no retrieval promise today.
|
||||
|
||||
### plant → convict → remove → pass
|
||||
|
||||
```
|
||||
hub-copy gate SELFTEST
|
||||
1. clean tree : 0 conviction(s) OK
|
||||
2. planted „visszaállító jelszavadat”: CONVICTED (isszaállító jelsz) OK
|
||||
3. same phrase inside a comment : not convicted OK
|
||||
4. planting removed : 0 conviction(s) OK
|
||||
hub-copy gate selftest OK — the guard has been watched catching, ignoring and releasing
|
||||
```
|
||||
|
||||
**The control found a defect in its own instrument on the first run.** Step 3 convicted a comment,
|
||||
because the synthetic source was named `<selftest>` and comment-stripping keys off the `.go`
|
||||
extension. **The bug was in the guard, and the control is what found it** — which is the entire
|
||||
argument for insisting a guard be watched working.
|
||||
|
||||
### One list, not two — and the gap is instrumented rather than hidden
|
||||
|
||||
Both lists live in **`scripts/customer_copy_vocab.py`**, the same shared-gate home
|
||||
(`reuse_refs_check.py`, `instructions_gate.py`) that both repos already consume without copying.
|
||||
|
||||
**`retrieval_promise_gate.py` has NOT adopted it**, because the end state forbade touching
|
||||
`felhom-controller` tonight. So rather than ship two copies that drift, **this gate reads the
|
||||
controller gate's `STEMS` and fails if they disagree** — watched failing:
|
||||
|
||||
```
|
||||
DRIFT: the controller gate's STEMS have diverged from customer_copy_vocab.py
|
||||
controller : ['visszaállíthat', 'visszaszerezhet', 'visszahozhat', 'visszanyit']
|
||||
shared : ['visszaállíthat', 'visszaszerezhet', 'visszahozhat']
|
||||
HUB-COPY GATE FAILED: the shared vocabulary is no longer shared.
|
||||
```
|
||||
|
||||
…and green again when restored. An **absent** sibling clone is **INCONCLUSIVE (exit 2), never a pass**
|
||||
— the G-1 lesson. **This is a scaffold, not the destination: R-325** is the few-line felhom-controller
|
||||
change that makes it import the shared list and delete both its literal and this drift check.
|
||||
|
||||
---
|
||||
|
||||
## 4. Part 2 — the four scenarios, the clock, and the red-proofs
|
||||
|
||||
**Re-established at `file:line`, not taken from the prompt.** The chain end to end: controller
|
||||
`cmd/controller/main.go:1253` sets `Health.Status = "disabled"` in the final minimal report → hub
|
||||
`store.go:953-955,968-975` parses `health.status` into `reports.health_status` →
|
||||
`CustomerSummary.HealthStatus` (`store.go:40`) carries it into `GetCustomers()` →
|
||||
`web/rollup.go:25` renders `disabled` → **`monitor/staleness.go` ignored it and measured age alone.**
|
||||
|
||||
**The halt condition did not fire:** the discriminator is the box's **own last word**, present in the
|
||||
data this checker already reads. That is not a guess.
|
||||
|
||||
### It was TWO doors, not one
|
||||
|
||||
Because the state is **recorded** (`StateDisabled`) rather than **deleted** (as the `blocked`
|
||||
precedent does), `CheckBackupDeadlines` can skip it too. A deleted state returns `""` from `GetState`,
|
||||
and `""` is not `"down"` — so that check would have gone on e-mailing `expected_backup_missed` every
|
||||
morning about the same machine. **R-195's shape returning through a second door**, and it is closed
|
||||
with the first. Recording the state also satisfies the visibility requirement: quiet-on-purpose and
|
||||
quiet-by-accident no longer look identical.
|
||||
|
||||
### The re-enablement judgement
|
||||
|
||||
**The clock runs from the report the hub can actually see.** For a box that reports on re-enabling,
|
||||
that report *is* the re-enablement, so the clock starts there — your recommendation, and the mechanism
|
||||
already had this shape. Timing from the last report *before* the switch-off would fire an instant
|
||||
stale/down for a quiet period we asked for: a false alarm produced by fixing false alarms. Leaving
|
||||
`disabled` re-enters the **same branch as a new customer**, so no `node_recovered` fires for an outage
|
||||
that never happened. `downtimeStart` is cleared **on entry**, so a later genuine outage cannot compute
|
||||
its duration from a clock that started before the silence was requested.
|
||||
|
||||
**LIMIT, stated rather than hidden:** a box re-enabled that then **fails to report at all** keeps being
|
||||
suppressed — the hub sees only that final `disabled` report, and its view changes only when a report
|
||||
arrives. It cannot distinguish that from *still switched off*. **This is exactly why the state is made
|
||||
visible:** an operator who re-enabled a box and still sees `disabled` is being told it has not come back.
|
||||
|
||||
### Scenarios
|
||||
|
||||
| | outcome | verified |
|
||||
|---|---|---|
|
||||
| **A** deliberately silent for days | no stale, no down, no e-mail; state visibly `disabled` | `TestStaleness_A` — observed healthy **first**, then switched off, then three passes |
|
||||
| **B** simply stopped reporting | unchanged: stale then down, exactly as today | `TestStaleness_B` — state `down`, events emitted |
|
||||
| **C** re-enabled, reports promptly | clean transition, **no** recovery event | `TestStaleness_C` — zero events, state `ok` |
|
||||
| **D** re-enabled then genuinely quiet | stale and down fire normally, timed from re-enablement | `TestStaleness_D` — state `down`, events emitted |
|
||||
|
||||
Plus `TestStaleness_DisabledIsAlsoSkippedByTheDeadlineCheck` for the second door.
|
||||
|
||||
### Red-proofs — every mutation asserted applied by grep, and reverted after
|
||||
|
||||
| # | Mutation | Asserted applied | Outcome |
|
||||
|---|---|---|---|
|
||||
| **1** *(the one that matters)* | suppression made **unconditional** (`if true \|\| …`) | `staleness.go:132` grep | **RED — B**: *"a genuinely silent machine is `"disabled"`, want `"down"` — a real alarm was swallowed"*. **A genuinely dead machine was seen NOT alarming.** C and D also red |
|
||||
| **2** | suppression **removed** (`if false && …`) | `staleness.go:132` grep | **RED — A**: *"a deliberately-disabled machine emitted `[node_down]` — three days quiet BY REQUEST"*. Today's false alarm, reproduced verbatim |
|
||||
| **3** | state made **sticky** — remembered instead of re-read from the box, so the clock never leaves the pre-disable report | `staleness.go:132` grep | **RED — D**: *"a once-disabled machine was silenced for ever"*. C also red |
|
||||
|
||||
**A weakness in my own tests was found by red-proof 2 and fixed.** Scenario A originally seeded the
|
||||
customer *already* disabled — and the checker's new-customer branch sets the first state without an
|
||||
event, so **the test passed on its state assertion alone even with the suppression deleted.** It now
|
||||
observes the machine healthy first, and the same mutation then fails on the **event**. A test that
|
||||
cannot see the alarm it exists to prevent is not a test.
|
||||
|
||||
---
|
||||
|
||||
## 5. Part 3 — the real counts, and the number that was wrong
|
||||
|
||||
**Yes, a number I have been repeating is wrong.**
|
||||
|
||||
```
|
||||
where felhom stands — 55 claims, verified_on 2026-08-09
|
||||
walked 23
|
||||
partial 14 (6 cite evidence, 8 prose only)
|
||||
built 14 (0 cite evidence, 14 prose only)
|
||||
missing 4 (0 cite evidence, 4 prose only)
|
||||
NOT WALKED: 32 of 55
|
||||
```
|
||||
|
||||
**"Nine" is real, and it answers a different question: it is the count of claims carrying
|
||||
`verdict: downgraded`** — the ones the 2026-08-09 verification pass **lowered**. That is "re-judged",
|
||||
not "unproven". **Yesterday's session was right to refuse to guess**, and this is what it could not
|
||||
have found without counting.
|
||||
|
||||
The sharper cut is the evidence one: **all 23 walked claims cite an evidence document** (`check_stands.py`
|
||||
convicts a `walked` claim without one), while of the **32** that are not walked, **only 6 cite evidence
|
||||
and 26 are prose only**.
|
||||
|
||||
---
|
||||
|
||||
## 6. The command, and its output
|
||||
|
||||
```
|
||||
$ python3 scripts/unproven.py --summary
|
||||
where felhom stands — 55 claims, verified_on 2026-08-09
|
||||
walked 23
|
||||
partial 14 (6 cite evidence, 8 prose only)
|
||||
built 14 (0 cite evidence, 14 prose only)
|
||||
missing 4 (0 cite evidence, 4 prose only)
|
||||
NOT WALKED: 32 of 55
|
||||
```
|
||||
|
||||
Without `--summary` it prints every not-walked claim with its id, band, verdict and whether it cites
|
||||
evidence, grouped `partial → built → missing`. It reads the dataset **only** — opens no evidence,
|
||||
judges nothing, contacts no machine. An unrecognised status prints with a `⚠ status not known to this
|
||||
script` marker rather than being silently dropped.
|
||||
|
||||
**Wired into the end-of-session checklist** in `felhom.eu/CLAUDE.md`, with the instruction to say in
|
||||
the report if a number moved.
|
||||
|
||||
**Its first run found a stale claim** — `claim.code-naming` is still `partial` and its title still
|
||||
describes the defect R-295 and R-323 have now closed twice over. **I did not move it**, because the
|
||||
dataset's own header forbids it: *"A status may not be RAISED here — the MAP changes first and this
|
||||
file follows it."* Filed as **R-327**, with the honest difficulty noted: no customer has typed
|
||||
„Tulajdonosi jelmondat" yet, so `walked` would be an over-claim.
|
||||
|
||||
**The capability map is deliberately NOT restructured** — recorded in R-326 so it does not read as
|
||||
forgotten.
|
||||
|
||||
---
|
||||
|
||||
## 7. Versions, manifest, CI
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Shipped** | **hub v0.105.0** (`gitea.dooplex.hu/admin/felhom-hub:0.105.0`) |
|
||||
| **Unchanged** | controller **0.214.0**, agent **0.129.0**, installer **1.28.0**, golden 0.214.0, floor 0.214.0, MinAgent 0.129.0 |
|
||||
| **Commits** | `b03a105` the work · `bbd59f4` the manifest bump |
|
||||
| **Manifest** | `manifests/hub.yaml:128` → `0.105.0`, GitOps only — **no `kubectl set image`** |
|
||||
| **Deploy** | ArgoCD hard-refresh + sync → **Synced / Healthy**; pod `hub-5ff87b556b-bvtvt` **1/1 Running**; deployment image confirmed `0.105.0` |
|
||||
| **CI, by run ID** | run **336** (`b03a105375`) **success** · run **337** (`bbd59f4a44`) **success** |
|
||||
| **Gates** | `repo_gates.py --fast` — all **9** OK (the new `hub-copy` included), and again in the pre-push hook on both pushes. **No `--no-verify`** |
|
||||
| **Green gate** | `hub/`: build rc=0, vet rc=0, **test rc=0 across 18 packages**, run separately from every commit |
|
||||
|
||||
**Live verification of the running artifact**, ASCII-only patterns against
|
||||
`/usr/local/bin/felhom-hub` in the running pod:
|
||||
|
||||
```
|
||||
Tulajdonosi jelmondat 1 ← the field label
|
||||
tulajdonosi jelmondatodat 2 ← the page lead + the mail
|
||||
jelszavadat 0 ← the retired possessive is GONE
|
||||
```
|
||||
|
||||
The negative control is the point: the old copy is **absent**, not merely accompanied.
|
||||
|
||||
**Method, stated: this proves the deployed artifact carries the new copy — it is not a rendering.**
|
||||
Rendering the binding page requires minting a self-bind token, which mints a capability URL and sends
|
||||
an e-mail against a real customer record; with `demo-hp` being re-deployed tonight I would not do that
|
||||
to any customer row. The *rendering* is covered by `TestSelfBind_ThirdSecretNaming` and
|
||||
`TestSelfBind_FailureBannerUsesTheSameName`, which drive the real handler through `ServeHTTP`.
|
||||
|
||||
**Part 2 has no live observable tonight, and I will not manufacture one.** No machine is in the
|
||||
disabled state, and producing one would mean switching a real box's reporting off — precisely the kind
|
||||
of thing that must not happen to a fleet of two on the evening one of them is being re-deployed. The
|
||||
fix is proven by four scenarios and three red-proofs and is **latent until a box is actually disabled**.
|
||||
|
||||
---
|
||||
|
||||
## 8. `demo-hp` was not touched
|
||||
|
||||
**No `ssh`, no `pct`, no controller call, no agent call, no hub write of any kind** was issued against
|
||||
`demo-hp` or its records this session. Everything done here was in the `felhom.eu` repo, the hub image
|
||||
and the hub deployment.
|
||||
|
||||
Confirmed read-only, via the hub's own hosts page (`GET /hosts`, HTTP 200):
|
||||
|
||||
```
|
||||
demo-hp-bb76ea ONLINE
|
||||
demo-felhom-8363b5 ONLINE
|
||||
drill-r50-0a4f9a DOWN (reverted to `virgin`, powered off — expected)
|
||||
```
|
||||
|
||||
`demo-hp` is **online and reporting normally**, exactly as it was found. **`felhom-agent` and
|
||||
`felhom-controller` are byte-unchanged** — neither repo was written to.
|
||||
|
||||
---
|
||||
|
||||
## 9. Register
|
||||
|
||||
**Ceiling moved R-322 → R-327** (grepped before minting).
|
||||
|
||||
| Row | State |
|
||||
|---|---|
|
||||
| **R-323** third near-homograph → „Tulajdonosi jelmondat" | **CLOSED — shipped** |
|
||||
| **R-324** the hub's customer copy under a guard | **CLOSED — shipped, selftest green** |
|
||||
| **R-325** controller gate should import the shared vocabulary | **READY (S)** — the drift check is the scaffold |
|
||||
| **R-326** "what is unproven" made queryable | **CLOSED — shipped** |
|
||||
| **R-327** the picture still describes a fixed defect | **READY (S)** — map moves first |
|
||||
| **R-321** a disabled machine alarmed as dead | **CLOSED — both doors** |
|
||||
| **R-322** the guard had never scanned the hub | **CLOSED by R-324** |
|
||||
|
||||
---
|
||||
|
||||
## 10. What was dropped, and observations
|
||||
|
||||
**Nothing was dropped.** Part 1, Part 1b, Part 2 and Part 3 are all complete. Part 3 was the
|
||||
designated first drop and was not needed.
|
||||
|
||||
### Observations — noticed, not acted on
|
||||
|
||||
- **I nearly published a false negative about my own deploy.** The first grep of the running binary
|
||||
used accented patterns through `kubectl exec → sh -c` and returned **0 for every string, including
|
||||
ones that are certainly present** — which reads exactly like "the rename did not deploy". The
|
||||
standing rule (*never let an accented pattern gate a conclusion*) is what caught it; the ASCII-only
|
||||
re-run gave the real answer. **The rule earns its place again, in a chain it was not written for** —
|
||||
it was written for `ssh → pct exec`, and `kubectl exec` mangles identically.
|
||||
- **The `blocked` branch does not clear `downtimeStart`.** The new `disabled` branch does. So a
|
||||
customer that is blocked, later unblocked and later still goes down will compute its downtime from a
|
||||
clock that started before the block. Small, pre-existing, and not changed under a row about
|
||||
something else.
|
||||
- **`gofmt -l internal/` lists 22 pre-existing unformatted files** in the hub, none of them touched by
|
||||
this session. Worth one cleanup commit by someone, sometime — it makes `gofmt -l` useless as a
|
||||
check, which is how a real formatting problem would hide.
|
||||
- **The empty allowlist in the new gate is load-bearing and fragile in one direction.** It is empty
|
||||
because the hub genuinely makes no retrieval promise. The moment someone adds one legitimately, they
|
||||
must register it — and the gate's failure message says so, but nobody reads a failure message until
|
||||
they hit it.
|
||||
- **`unproven.py` shows 26 of 32 not-walked claims are prose only.** That is not a defect per claim —
|
||||
a `missing` claim has nothing to cite — but **14 of 14 `built` claims cite no evidence at all**, and
|
||||
"built" is the status that most invites being read as "done". Worth a look when the capability-map
|
||||
session happens.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# STATUS — what works, what's broken, what's next
|
||||
|
||||
**Updated 2026-08-12 (late evening — retained-key drill).**
|
||||
**Updated 2026-08-13 (late — the third name, a machine told to be quiet, and a picture you can query).**
|
||||
|
||||
> **A view, not a source.** `documentation/backlog/OPEN-ITEMS.md` is the authority; this page restates
|
||||
> part of it in plain words, and **nothing may exist only here**. **Items, not paragraphs. One screen.**
|
||||
@@ -8,61 +8,93 @@
|
||||
|
||||
## Waiting on you
|
||||
|
||||
*(The golden-vouch and floor-raise asks that stood here are **done** — the hub reads golden **0.213.0**,
|
||||
floor **0.213.0**, agent **0.128.0**. Checked live, not assumed.)*
|
||||
*Nothing. All three questions that stood here were answered on 12–13 August and have moved to
|
||||
**Decided** below. A decided question left in the deciding list is how a person loses track of what is
|
||||
actually waiting.*
|
||||
|
||||
- **R-307 — a countdown is already running on `demo-felhom`**, started 10 Aug, **firing 24 August**,
|
||||
after which that set-aside off-site copy is deleted for good. Today's drill did not start it and
|
||||
deliberately did not cancel it. Cancel it (copy kept, costs storage) or let it run (copy deleted).
|
||||
**Doing nothing chooses deletion.**
|
||||
- **R-304 — decide what we promise about old backups.** The retention works, but only an operator can
|
||||
use it; the customer is told their correct code is wrong. Either build the door, or stop promising.
|
||||
- **R-303 — one coherence decision**, ranked low: a box can still raise the "we cannot open your new
|
||||
backups" card while counting down to deleting the old ones. The two no longer contradict each other,
|
||||
but the state is odd and the wrong fix would hide a real second fault.
|
||||
## Decided — and what would reopen each
|
||||
|
||||
*A decision with no trigger becomes a permanent silence, so each one names what would make us look
|
||||
again.*
|
||||
|
||||
- **Getting old backups back yourself: NOT BUILT, deliberately.** A customer in that position is a
|
||||
support conversation, and we can do it by hand. **Reopens if:** a real customer actually asks —
|
||||
one request from a person who is not us. *(register: R-312)*
|
||||
- **The unopenable old copy on `demo-felhom`: KEPT, as a test fixture.** Not for sentiment: it is the
|
||||
only state in existence where a set-aside store is present and cannot be opened, which is the case
|
||||
any future handling of lost backups has to face honestly. **Delete it when:** that work ships, or is
|
||||
abandoned. Until then it is a fixture, not an accumulation. *(register: R-313)*
|
||||
- **A machine in two kinds of trouble says both things: LEFT AS IT IS.** Its real-world likelihood is
|
||||
unknown, and hiding one card risks hiding a real second failure. **Reopens if:** it is observed
|
||||
happening outside a constructed test. *(register: R-303)*
|
||||
|
||||
## What works
|
||||
|
||||
Both demo machines are home, healthy and reporting on the approved pair. Off-site is credentialed on
|
||||
`demo-hp` and its repository still opens with the machine's own key. `drill-r50` is blocked, as intended.
|
||||
Both demo machines are home, healthy and reporting on the approved pair — **controller 0.214.0, agent
|
||||
0.129.0**, delivered by the floor rather than by hand. Off-site is credentialed on `demo-hp` and its
|
||||
repository still opens with the machine's own key. `drill-r50` is reverted to `virgin`, powered off.
|
||||
|
||||
**What the fleet actually is, because two summaries have now been misread:** the hub holds **five
|
||||
customer records and three machines**. The machines are `demo-felhom` and `demo-hp` (both ours, both
|
||||
disposable) and `drill-r50` (a nested drill VM on DooPlex, reverted and powered off). **`peti-felhom`
|
||||
is a real machine we have not heard from since 15 July** and has no host record. **`tester-1` is a
|
||||
record with no machine** — created 13 August, no host, no backups, nothing to lose.
|
||||
|
||||
## Shipped
|
||||
|
||||
- **The drive can be re-attached after a reinstall** (R-280). The restore page said *"this is two
|
||||
clicks"* over an empty list; it was zero clicks and needed an internal path no customer could produce.
|
||||
- **The orphan card stops promising** that set-aside off-site copies can be reopened — twice over
|
||||
(R-294, then **R-299**, which was the same claim in the plural, in the *always-visible* half, missed
|
||||
because the guard matched one inflection of a Hungarian verb).
|
||||
- **The countdown banner stops promising retrieval it cannot see is still true** (R-302). The promise
|
||||
is now conditional on the hub still holding the package it held when the customer decided — pinned
|
||||
then, compared now. A sweep found the same claim in five places; a fourth was fixed with it and a
|
||||
fifth deliberately left, because it is true where it renders.
|
||||
- **One name per secret, box side** (R-295): the dashboard code is „Beállító kód" everywhere;
|
||||
„Visszaállító kód" is retired. It collided with the escrow „Helyreállítási kód" and cost a real code.
|
||||
- **Both installer fixes are now PUBLISHED** as `installer-v1.27.0` (R-297 + R-300). Each fault was
|
||||
watched happening first, on a machine reset to factory state: the old installer really did build a
|
||||
machine on a base image from July, and our own uninstall really did block our own next install.
|
||||
- **The removal now genuinely reverses the installation** (R-316, `installer-v1.28.0` published). The
|
||||
second reinstall used to hit our own leftover; it was watched failing on the cycle that actually
|
||||
fails, then watched passing.
|
||||
- **A correct recovery code is no longer called wrong** (R-311, three components). If a customer types
|
||||
the code for an older set of backups, the machine now checks the packages we kept, recognises it, and
|
||||
says so: *your code is correct, it belongs to an earlier package, we kept it, your current backups are
|
||||
fine, write to us*. It deliberately promises no restore, because there is no button yet.
|
||||
- **The drive can be re-attached after a reinstall** (R-280), and **the orphan card and the countdown
|
||||
banner stop promising retrieval they cannot see is still true** (R-294, R-299, R-302).
|
||||
- **One name per secret — now both halves** (R-295). The dashboard code is „Beállító kód" everywhere,
|
||||
on the machine *and* in the hub's emails; „Visszaállító kód" is retired. It collided with the escrow
|
||||
„Helyreállítási kód" and cost a real code.
|
||||
- **The hub can see whether a machine's guest still has working networking** (R-319, first reader built
|
||||
against R-264). A machine quietly repairing its own network over and over is now visible instead of
|
||||
being a green tick; a machine that does not report it is drawn as unknown, never as healthy.
|
||||
- **The third secret has its own name** (R-323, on your ruling). The five-word phrase that proves an
|
||||
account owns the box being linked is „Tulajdonosi jelmondat". It was „Visszaállító jelszó" — one word
|
||||
from the name we retired last week, and false besides: it restores nothing. Five places, all in the
|
||||
hub; no machine touched.
|
||||
- **A machine we tell to be quiet is no longer reported as dead** (R-321). It went stale, then down,
|
||||
then e-mailed you twice about a silence you asked for. It turned out to be two alarms, not one — the
|
||||
morning backup reminder had the same blind spot and is fixed with it.
|
||||
- **The hub's own words are under a guard** (R-324). Every customer e-mail and the linking pages are
|
||||
now checked for a retired name, and the guard has been watched catching one, ignoring an
|
||||
explanation of one, and going quiet again.
|
||||
- **The countdown on `demo-felhom` is cancelled** on your ruling (R-307). Nothing was deleted.
|
||||
|
||||
## Broken, or knowingly incomplete
|
||||
|
||||
- **The tester's machine has no recovery route at all** — see the `PETI` row. Its host record was
|
||||
deleted on 15 July; there is no key, no off-site copy and no local backup. **If that drive fails,
|
||||
everything on it is lost.** First act of the visit: copy the ~3.6 GB off before anything is
|
||||
reinstalled — it is currently the only copy in existence. Whether it stays parked is your call and is
|
||||
deliberately left open.
|
||||
- **Kept backups can be opened — but not by the customer** (R-304). We now know for certain the old key
|
||||
is kept and **does** open the old backups: three planted files came back byte-for-byte from a store the
|
||||
machine itself could no longer read. But nothing in the product reads a kept key, so it takes an
|
||||
operator with a shell. Worse, a customer who types their **correct** old code is told it *"did not open
|
||||
the sealed bundle"*. The keeping is real; the promise that they can use it is not.
|
||||
- **The dnsmasq fix helps a machine once** (R-305). On a machine that never had Felhom it works. On the
|
||||
second reinstall the leftover comes back, because the package is never removed — so the machine looks,
|
||||
to our own installer, as if the household had installed it. Watched happening the same afternoon.
|
||||
- **The hub half of the naming is undone** (R-295 PARTIAL): the emails still use the retired name and
|
||||
send people to a page a rebuilt machine does not show.
|
||||
- **Peti's machine has no recovery route at all** — see the `PETI` row. **This is a real machine
|
||||
belonging to a real person**, not one of ours and not a record: it reported to the hub for four and a
|
||||
half months and has been silent since 15 July, when its host record was deleted. There is no key, no
|
||||
off-site copy and no local backup. **If that drive fails, everything on it is lost.** First act of the
|
||||
visit: copy the ~3.6 GB off before anything is reinstalled — it is currently the only copy in
|
||||
existence. Whether it stays parked is your call and is deliberately left open.
|
||||
- **Kept backups can be opened — but still only by us** (R-304 partly closed, R-312 decided-not-built).
|
||||
Today the honest answer is "your code is right, write to us" — and we can.
|
||||
- **The agent picks dnsmasq by looking at a file another package owns** (R-317). The box installs fine;
|
||||
only LAN name resolution goes missing, and quietly. One line, deliberately not taken tonight.
|
||||
- **The storage page has its own separate reason for showing an empty list** (R-298), untouched.
|
||||
- **Three more facts the machines send still have no reader** (R-264): a staged-but-unapplied agent
|
||||
update, how deep a restore test actually went, and the two backup-integrity timestamps. Five others
|
||||
are now recorded as deliberately unread, which is honest rather than fixed.
|
||||
- **Two thirds of the standing picture is still unproven, and now you can ask** (R-326).
|
||||
`python3 scripts/unproven.py` lists it: of 55 claims, **23 are walked and 32 are not** — and of
|
||||
those 32, only 6 point at an evidence document. **The "nine" I have been repeating was wrong**: nine
|
||||
is how many claims the 9 August review *lowered*, which is a different question.
|
||||
- **The picture still describes one defect we have since fixed twice** (R-327) — the naming claim. Its
|
||||
status may only be raised after the capability map moves first, which is a separate judgement.
|
||||
|
||||
## Working on next
|
||||
|
||||
Your two decisions above (R-307's deadline is the hard one); then R-304's shape; then the hub naming;
|
||||
then the 2026-08-09 batch (R-279 … R-292), still untriaged against everything since.
|
||||
`demo-hp` is yours this evening — **this session did not touch it**. After that: the three remaining
|
||||
R-264 readers, now that one has been built and we know what one costs; R-317 (one line in the agent);
|
||||
R-327 (decide what the naming claim's status should be); then the 2026-08-09 batch (R-279 … R-292),
|
||||
still untriaged against everything since.
|
||||
|
||||
@@ -476,7 +476,14 @@ Report MUST include:
|
||||
6. **Deployed versions** + `docker ps` / agent-service / hub-pod verification output.
|
||||
7. **NOT yet live-validated — awaiting supervised [Bx]:** explicit list (the real
|
||||
put-data → operate → integrity flow).
|
||||
8. **Teardown evidence — all three §13 layers**, if the run provisioned anything: the machine deleted,
|
||||
8. **Evidence copied off BEFORE each revert** — for every phase that ran on a machine, the logs were
|
||||
pulled to the evidence directory **at the end of that phase**, before any revert, snapshot restore
|
||||
or teardown, **including the intermediate ones**. *The intermediate revert is the one that gets
|
||||
forgotten: two sessions lost a phase's logs to a mid-run revert to `virgin` on 2026-08-12 and
|
||||
2026-08-13 — same machine, same point, three days apart (R-320).* **If a phase's evidence is
|
||||
already gone, the report says so plainly and the finding is REPRODUCED independently** — that is the
|
||||
expectation, not an improvisation. A quotation read live and no longer re-readable is named as such.
|
||||
9. **Teardown evidence — all three §13 layers**, if the run provisioned anything: the machine deleted,
|
||||
`pvesm status` before/after with the space returned, and the **hub-side record's disposition named**
|
||||
(deleted / retained-with-reason / gate-blocked-with-the-command). A run that provisioned nothing says
|
||||
so. "Teardown clean" without layer 3 is not a report — it is the `sess-c` failure.
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -450,8 +450,8 @@ whose credentials reach nothing else — and the only mutating verb used was `ba
|
||||
| Phase A — removal leftover | 16:50 → 17:12 | **~22 min** (4 installs, 4 uninstalls, 3 preflights) |
|
||||
| Phase B — stale golden | 17:13 → 17:34 | **~21 min** (2 full provisions) |
|
||||
| Phase C — retained key | 17:14 → 17:23 | **~25 min** (overlapped Phase B; different machine) |
|
||||
| Record, register, publication, teardown | 17:35 → 17:55 | **~20 min** |
|
||||
| **Total** | **16:42 → 17:55** | **≈ 1 h 13 min** |
|
||||
| Record, register, publication, teardown | 17:34 → 17:45 | **~11 min** |
|
||||
| **Total** | **16:42 → 17:45** | **≈ 1 h 03 min** |
|
||||
|
||||
Phase C ran concurrently with Phase B deliberately — different machines, no shared state. The
|
||||
4–5 hour envelope was not needed; nothing was hurried and nothing was dropped for time.
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
# REPORT — The removal that works once, and a status page that says what it is asking for (2026-08-13)
|
||||
|
||||
**Shipped:** `installer-v1.28.0`, published and verified against the live URL.
|
||||
**Register:** R-305 CLOSED (by R-316), **R-316 / R-317 / R-318 opened**; ceiling R-315 → **R-318**.
|
||||
**Venue:** `drill-r50` only. Neither demo box reinstalled. `peti-felhom` not contacted. Nothing deleted.
|
||||
|
||||
---
|
||||
|
||||
## 1. Cycle 3, before and after
|
||||
|
||||
**Before — on the PUBLISHED v1.27.0, from `virgin`, exit 1:**
|
||||
|
||||
```
|
||||
[ERROR] a resolver is already bound to :53 on this host:
|
||||
udp UNCONN 0 0 0.0.0.0:53 … users:(("dnsmasq",pid=7076,fd=4)) …
|
||||
[ERROR] a resolver is already bound to :53 on this host — Felhom needs the guest reachable by name on your LAN.
|
||||
Stop or reconfigure that resolver, OR point your LAN DNS at the guest's address, then re-run.
|
||||
(Felhom does NOT touch DNS services on a host it does not own — this is a refusal, not a change.)
|
||||
THIS LOOKS LIKE OURS. A previous Felhom install leaves the dnsmasq PACKAGE installed and its unit
|
||||
enabled (only our config snippet is removed), and unconstrained it binds 0.0.0.0:53 — which is what
|
||||
this gate is seeing. If this host had no dnsmasq before Felhom, clear it with:
|
||||
systemctl disable --now dnsmasq
|
||||
Then re-run this installer. If dnsmasq is YOURS, leave it and use one of the two routes above.
|
||||
[ERROR] PRE-FLIGHT FAIL (exit 1) — fix the finding above and re-run
|
||||
```
|
||||
|
||||
**After — v1.28.0, three fresh cycles from `virgin`, exit 0:**
|
||||
|
||||
```
|
||||
:53 now: 0
|
||||
CYCLE 3 rc=0
|
||||
[INFO] host DNS (:53): free
|
||||
[OK] pre-flight passed
|
||||
[OK] PRE-FLIGHT PASS (mode=byo) — no state written, no install step executed
|
||||
```
|
||||
|
||||
The three cycles were run on bytes **sha256-identical** to what the live URL now serves
|
||||
(`cca1dedd9b7c152c…`, compared three ways: live URL, tested file, repo main).
|
||||
|
||||
## 2. The mechanism, at `file:line`
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| ownership **recorded** | `felhom-host-install.sh:1718` — preflight, `dpkg-query -W -f='${Status}' dnsmasq \| grep -q "install ok installed"` |
|
||||
| ownership **read** | `:1097` (`_state_get dnsmasq_preexisting`) at uninstall |
|
||||
| state file **deleted** | `:1268` — *after* the read. **The order was already correct.** |
|
||||
| Felhom's dnsmasq snippets removed | `:1162`, in the loop just above the ownership decision |
|
||||
|
||||
**Why cycle 2 concludes "pre-existing": package presence alone.** The preflight asks dpkg one question
|
||||
and nothing else — it does **not** consult the absence of a record, and it cannot, because the record
|
||||
was deleted with the state file. v1.27.0 stopped the unit and left the package, so the answer stayed
|
||||
`yes` and our own package became "the household's" one cycle later.
|
||||
|
||||
**What the first uninstall did and did not remove:** snippets — removed. Unit — stopped + disabled.
|
||||
State file (and with it the record) — removed. **Package — left.** That last one is the whole defect.
|
||||
|
||||
## 3. What v1.28.0 changes
|
||||
|
||||
When the record says we installed it, the uninstall **removes the package** as well as stopping the
|
||||
unit. Order unchanged: read the record → act → delete the state.
|
||||
|
||||
**Two packages are recorded, not one.** `dnsmasq` ships the systemd unit; **`dnsmasq-base` ships
|
||||
`/usr/sbin/dnsmasq`** (`dpkg -S`, measured on the box). Separately installable, so each is recorded at
|
||||
preflight and taken back only if we added it.
|
||||
|
||||
**Guard rails:** ownership **read, never inferred**; the dependency check is an **`apt-get -s purge`
|
||||
simulation** that proceeds only if the removal set is a subset of ours, else stop+disable **naming the
|
||||
blocking package**; never interactive; **never fatal** — a wedged apt is recorded and restated in the
|
||||
closing NOTE; and the success is **re-queried** rather than read off apt's exit code.
|
||||
|
||||
## 4. Scenarios and red-proofs
|
||||
|
||||
| Scenario | Result |
|
||||
|---|---|
|
||||
| **A** three cycles, fixed | install 3 **PASSES**, `:53` free at every uninstall |
|
||||
| **B** resolver pre-dates Felhom | **untouched** — `install ok installed`, unit active, both packages recorded `yes` |
|
||||
| **C** something depends on it | **not purged**; log named `household-dns-thing`; stop+disable; `:53` free; dependent survived |
|
||||
| **D** no ownership record | **untouched**, reason logged, exact command named |
|
||||
|
||||
**Red-proofs — mutation asserted applied before each run:**
|
||||
|
||||
| Mutation | Outcome |
|
||||
|---|---|
|
||||
| remove the purge call | cycle 2 records `yes`; **cycle 3 refuses, exit 1, in those exact words** |
|
||||
| remove the ownership check | **the household's resolver is PURGED** (`unknown ok not-installed`) |
|
||||
| infer ownership when no record | **the guess is taken** — a field box loses its own DNS |
|
||||
|
||||
**One honest note on red-proof B.** Its first run appeared to pass *for the wrong reason*: apt failed
|
||||
with `dpkg was interrupted` (a broken state my own earlier manual package juggling left), so the
|
||||
resolver survived by accident rather than by the guard. I repaired dpkg and re-ran, and it then failed
|
||||
as required. Worth stating twice over: the mutation looked like a passing guard, and **my own fix's
|
||||
apt-failure path was incidentally observed doing exactly what it should** — logging, continuing, naming
|
||||
the command.
|
||||
|
||||
## 5. The machines already in the field
|
||||
|
||||
**Measured, not reasoned.** A field box is one with the package installed and **no record** — scenario
|
||||
D. Its uninstall leaves the resolver running with the reason logged, and its next install refuses with
|
||||
the message quoted in §1.
|
||||
|
||||
**Is there an honest durable marker? No, and none can be invented.** The Felhom `/etc/dnsmasq.d/
|
||||
felhom-*.conf` snippets are deleted by the uninstall's own loop *before* the ownership decision; the
|
||||
state file carrying the record is deleted at `:1268`; nothing under `/etc/felhom*` survives.
|
||||
`/var/log/dpkg.log` does record the install and is a **timestamp** — refused by the standing rule as a
|
||||
heuristic dressed as a fact. → **R-318**
|
||||
|
||||
**The preflight message, judged as a customer would:** it states the finding, keeps its two routes and
|
||||
its written promise not to touch DNS on a host we do not own, and adds the one thing that gets a person
|
||||
moving — *"THIS LOOKS LIKE OURS"* plus one exact command. It hedges correctly (*looks like*). Its
|
||||
weakness is that it asks them *"did this host have dnsmasq before Felhom?"* — precisely the question we
|
||||
can no longer answer for them. **That is a mechanism, not a rule: the command is on the screen at the
|
||||
moment it is needed.**
|
||||
|
||||
## 6. The defect I nearly shipped
|
||||
|
||||
The agent decides whether to install dnsmasq with `os.Stat("/usr/sbin/dnsmasq")`
|
||||
(`felhom-agent/internal/lanresolver/lanresolver.go:105`) — but that path belongs to **`dnsmasq-base`**,
|
||||
while the unit comes from **`dnsmasq`**. Purging only `dnsmasq` would leave the binary, so the next
|
||||
install would skip the apt step and then fail to enable a unit that is gone — **a silent resolver where
|
||||
today there is at least a visible refusal.** That is why ownership is recorded per package.
|
||||
|
||||
It remains reachable where `dnsmasq-base` pre-dated Felhom (we correctly keep it). **Pre-existing, not
|
||||
introduced here**, filed as **R-317**, and the uninstall now says so out loud rather than leaving it to
|
||||
be found from a resolver that never came up. Fixing it is a one-line agent change, deliberately **not**
|
||||
made here to keep this session to one repo.
|
||||
|
||||
## 7. Publication
|
||||
|
||||
`installer-v1.28.0` tagged; **both** `--ref`s in `manifests/webpage.yaml` moved (sidecar 327, init 372);
|
||||
ArgoCD synced to `823cd29`; live deployment carries the new ref.
|
||||
|
||||
```
|
||||
live URL serves: SCRIPT_VERSION="1.28.0" (was 1.27.0)
|
||||
_dnsmasq_purge_owned present in the served file: 3
|
||||
```
|
||||
|
||||
**Pushing publishes nothing here** — `/scripts/` follows the tag. The runbook still says otherwise;
|
||||
**R-309 remains open and is not forgotten**, deliberately out of scope.
|
||||
|
||||
## 8. Teardown — four layers
|
||||
|
||||
| Layer | State |
|
||||
|---|---|
|
||||
| **machine** | `drill-r50`: 0 guests, no `/var/lib/felhom-install`, dnsmasq `not-installed` at the end |
|
||||
| **host** | `drill-r50` **reverted to snapshot `virgin`, powered off**; `qemu.pid` removed. DooPlex was drill host only |
|
||||
| **hub** | `drill-r50-0a4f9a` **RETAINED** — pre-existing since 2026-07-25, re-used not duplicated. **No new host or customer row was created this session.** Nothing deleted |
|
||||
| **off-site** | **Not contacted at all** — no restic, sftp or endpoint call was made. `demo-felhom`: `last_status=ok`, `escrow=escrowed`, **no abandon countdown** |
|
||||
|
||||
Both demo boxes untouched and healthy: controller **0.214.0**, agent **0.129.0**, `Up … (healthy)`.
|
||||
|
||||
## 9. Evidence, and a repeated miss
|
||||
|
||||
Logs at `documentation/audits/evidence-r316-2026-08-13/`: the fixed cycles (`F1`, `F2`, `F3`), all four
|
||||
scenarios (`B`, `C`, `D`), and every red-proof (`RPA*`, `RPB*`, `RPD*`).
|
||||
|
||||
**The Part 1 logs did not survive.** They were on the drill VM's disk and were destroyed by the revert
|
||||
to `virgin` between Part 1 and Part 2 — **the same mistake as Tuesday, in the same place.** The §1
|
||||
quotation is verbatim from the live run as read at the time, and `RPA1/RPA2/RPA3.log` are an
|
||||
independent reproduction of the identical three-cycle failure, retained. Recorded rather than glossed;
|
||||
the fix is procedural and I have now got it wrong twice.
|
||||
|
||||
## 10. Observations — noticed, not acted on
|
||||
|
||||
- **`dnsmasq-base` is flagged "automatically installed and no longer required"** after `dnsmasq` goes.
|
||||
We deliberately do not `autoremove` — that would be a blast radius nobody asked for.
|
||||
- **`apt-get -s purge` exits 0 even when it prints `E: dpkg was interrupted`.** The simulation output is
|
||||
the signal, never the exit code — which is why the guard parses `Remv`/`Purg` lines rather than
|
||||
trusting `$?`. Another entry for the exit-codes-that-lie class.
|
||||
- The drill VM's `pveam` index is stale on `virgin` and needs `pveam update` before listing templates —
|
||||
already recorded yesterday, hit again today in passing.
|
||||
@@ -0,0 +1,393 @@
|
||||
# REPORT — the small debts paid, and one unread fact given a reader (2026-08-13, evening)
|
||||
|
||||
**Shipped: hub v0.104.0, live and verified.** Parts A and B complete; **Part C dropped**, named in §12.
|
||||
No controller change, no agent change, no wire change — **so there was no bake and no approval**, as the
|
||||
task expected.
|
||||
|
||||
---
|
||||
|
||||
## 1. A4 FIRST — what the fleet actually is, and the entry corrected
|
||||
|
||||
**The task's premise for A4 was wrong, and the evidence is not ambiguous.** It asked me to establish
|
||||
the facts and not accept the framing; doing that reverses the conclusion. Two different records have
|
||||
been called "the tester", and only one of them carries the risk.
|
||||
|
||||
**Read from the hub's own store** (`hub.db` + `-wal` + `-shm`, copied together — the WAL rule):
|
||||
|
||||
| | `peti-felhom` | `david` → `tester-1` |
|
||||
|---|---|---|
|
||||
| customer row | created 2026-02-27 | `david` created 2026-08-01, **deleted today 07:55:49**; `tester-1` created **07:56:47** |
|
||||
| host row | `peti-felhom-86d37d`, deleted 2026-07-15 08:56:22 (`host_deletions` id 1) | **never, either name** |
|
||||
| controller reports | **482**, 2026-02-27 → 2026-07-15 08:39:00 | **0** |
|
||||
| host reports | present until deletion | **0** |
|
||||
| escrow rows | none | none |
|
||||
| events | staleness alarms after it went silent | **4 total** — three hub-side `expected_dbdump_missed` false alarms (R-195's subject) and its own deletion |
|
||||
|
||||
**So:**
|
||||
|
||||
- **"The tester" in this project's own vocabulary is Peti** — `documentation/pilot/PETI-tester-agreement.md`
|
||||
says *"Operator: Viktor. Tester: Peti"* — and the machine is **a real 80-core Proxmox server
|
||||
belonging to a real person**, running Felhom as a BYO guest. It reported for four and a half months.
|
||||
`target-selection.md` puts it at **Tier 2 — protected**, *"because there is a real person behind it"*.
|
||||
**The 3.6 GB with no key, no off-site copy and no local backup is REAL, and the entry keeps its rank.**
|
||||
- **`tester-1` is a record with no machine** — no host, no escrow, no report, ever; and `david` before
|
||||
it was the same. **A record with no machine behind it can lose nothing.**
|
||||
|
||||
**Reconciling this with what the operator said** (*"there is no actual tester yet — only a pre-created
|
||||
customer, now renamed"*): both statements are true of different things. The **pilot programme** never
|
||||
began — the agreement was drafted 2026-07-09, the onboarding runbook stopped at P1 — and the
|
||||
pre-created record is `tester-1`. **Meanwhile the hardware and the data have existed the whole time.**
|
||||
Nothing about the risk changed; only the word that names it.
|
||||
|
||||
**The corrected entry, as shipped** (`STATUS.md`, "Broken, or knowingly incomplete"):
|
||||
|
||||
> - **Peti's machine has no recovery route at all** — see the `PETI` row. **This is a real machine
|
||||
> belonging to a real person**, not one of ours and not a record: it reported to the hub for four and a
|
||||
> half months and has been silent since 15 July, when its host record was deleted. There is no key, no
|
||||
> off-site copy and no local backup. **If that drive fails, everything on it is lost.** First act of the
|
||||
> visit: copy the ~3.6 GB off before anything is reinstalled — it is currently the only copy in
|
||||
> existence. Whether it stays parked is your call and is deliberately left open.
|
||||
|
||||
The `PETI` register row carries the full disambiguation with every count measured, and ends
|
||||
*"Wherever a document says 'the tester's machine', read `peti-felhom`."*
|
||||
|
||||
**What the fleet actually is, in one sentence, now on `STATUS.md`:** the hub holds **five customer
|
||||
records and three machines** — `demo-felhom` and `demo-hp` (ours, disposable), `drill-r50` (a nested
|
||||
drill VM, reverted and powered off); `peti-felhom` is a real machine we have not heard from since 15
|
||||
July and has no host record; `tester-1` is a record with no machine.
|
||||
|
||||
---
|
||||
|
||||
## 2. The hub strings as shipped, with bytes confirmed
|
||||
|
||||
Enumerated at `file:line` before editing. All written from explicit bytes and verified as hex — no
|
||||
non-ASCII crossed a shell chain; the mojibake check (`Ã`/`Å`/`â€`) is clean in every touched file.
|
||||
|
||||
| Where | Was | Is | Hex of the shipped name |
|
||||
|---|---|---|---|
|
||||
| `notify/templates.go:216` subject | „Jelszó-visszaállítási kód" | **„Beállító kód a jelszavad visszaállításához"** | `4265c3a16c6cc3ad74c3b3206bc3b364…` |
|
||||
| `notify/templates.go:221` body | „Visszaállító kód: %s" | **„Beállító kód: %s"** | `4265c3a16c6cc3ad74c3b3206bc3b3643a202573` |
|
||||
| `notify/templates.go` **new** `reenroll` | *(did not exist)* | subject **„Új beállító kód — újratelepült a szervered"**, body names **„A szerver beállítása"** | `224120737a6572766572206265c3a16c6cc3ad74c3a1736122` |
|
||||
| `notify/templates.go:72` lockout | „beállító/visszaállító kód próbálkozás" | **„beállító kód próbálkozás"** | `…6265c3a16c6cc3ad74c3b3206bc3b364…` |
|
||||
| `web/templates/customer_unified.html:476` | „Visszaállító kód küldése" | **„Beállító kód küldése"** | `4265c3a16c6cc3ad74c3b3206bc3b364206bc3bc6c64c3a97365` |
|
||||
|
||||
**The page-naming fix, established at `file:line` rather than assumed.** `ReissueForReenroll` sent the
|
||||
**reset** mail (`claim/engine.go:181`), which directs the customer to an „Elfelejtett jelszó" page. A
|
||||
**rebuilt** box has no password, so the controller computes `reset := s.authEnabled()` → false
|
||||
(`felhom-controller/controller/internal/web/claim.go:279`), renders **„A szerver beállítása"**, and
|
||||
serves **no login page at all** — the named route is not on their screen. Only the hub can tell the two
|
||||
situations apart, because the hub chose which call site fired, so the fix is a **new `EmailKind`**, not
|
||||
a reworded shared template. Same secret, same name, different sentence.
|
||||
|
||||
The re-enrol mail deliberately says **nothing** about apps or backups —
|
||||
`TestFormatClaimEmail_ReenrollPromisesNothingAboutTheData` pins it. A clean-slate reinstall is
|
||||
precisely where such a reassurance could be false, and this project has spent four register rows
|
||||
removing promises it could not see were still true.
|
||||
|
||||
**Live-verified** (endpoint-level, the exact URL the operator UI serves; ClusterIP + Basic auth):
|
||||
`GET /customers/demo-felhom` → **„Beállító kód küldése" present, „Visszaállító kód" absent**.
|
||||
|
||||
### Had the claim guard ever scanned the hub? **No — never.**
|
||||
|
||||
`retrieval_promise_gate.py` lives in `felhom-controller/controller/scripts/`; its declared surfaces are
|
||||
that repo's `internal/web/templates` plus **one** Go handler file, added on 2026-08-12 by R-311 on the
|
||||
express ground that the highest-stakes customer copy *"had never been scanned"*. **The same sentence is
|
||||
true one repo over** — the hub composes every customer e-mail, i.e. the copy a customer reads *before*
|
||||
they see any box screen.
|
||||
|
||||
**I scanned it by hand with the gate's own four stems** (`visszaállíthat`, `visszaszerezhet`,
|
||||
`visszahozhat`, `visszanyit`) across every non-test `.go`/`.html` under `hub/internal/`: **zero
|
||||
occurrences.** So nothing was hiding, and my new strings contain no stem and need no registration.
|
||||
**It is a scope gap, not a live defect — filed as R-322 rather than fixed**, because pointing a
|
||||
controller gate at a sibling repo makes a controller gate fail on a felhom.eu edit, and G-1 already
|
||||
taught this project what a cross-repo gate costs. *(A recommendation not followed gets its line: I
|
||||
recommend a hub-side sibling in `repo_gates.py` sharing ONE stem list — two copies of a word list is
|
||||
how the plural got past the singular in R-299.)*
|
||||
|
||||
---
|
||||
|
||||
## 3. The runbook correction, and where else the claim lived
|
||||
|
||||
`runbooks/day0-install.md` §C.1 said *"there is no release tag… pushing `scripts/felhom-host-install.sh`
|
||||
publishes it."* **It has published nothing since R-110 shipped on 2026-08-03.** §C.1 now opens by naming
|
||||
its own former error and states the three acts that actually publish:
|
||||
|
||||
1. bump `SCRIPT_VERSION` and push to `main` — **publishes nothing**;
|
||||
2. cut and push the tag `installer-v<new SCRIPT_VERSION>`;
|
||||
3. move **BOTH** `--ref=installer-v…` pins in `manifests/webpage.yaml` — the git-sync **sidecar** and the
|
||||
**init container** (lines 327 and 372) — commit, sync. **The one-pin trap is named**: the running pod
|
||||
keeps serving until it restarts, and a fresh pod seeded by a stale init container then serves the OLD
|
||||
script with no error anywhere.
|
||||
|
||||
**How to verify from outside**, since a push, a green sync and a correct-looking manifest are each
|
||||
consistent with nothing having been published:
|
||||
|
||||
```
|
||||
curl -fsS https://felhom.eu/scripts/felhom-host-install.sh | grep -m1 '^SCRIPT_VERSION'
|
||||
```
|
||||
|
||||
**Measured while writing it: served `1.28.0`, `main` `1.28.0`, both pins `installer-v1.28.0`** — the
|
||||
three agreeing is the observation; any one alone is not.
|
||||
|
||||
**Copied elsewhere? Yes, once, and it was hunted.**
|
||||
`audits/SPIKE-universal-iso-3-2026-07-31.md:184` says the same thing **and cites `day0-install.md` as
|
||||
its source** — which is how it spread. It was **true on the day it was written**, so the dated finding
|
||||
is kept verbatim and carries a SUPERSEDED note; falsifying a dated record to tidy it is its own defect.
|
||||
Two other hits are correct in context: `hostinstall_gates.py:198` states the consequence of the
|
||||
manifest *losing* its tag, and the 2026-08-12 drill record already names the sentence as false.
|
||||
|
||||
---
|
||||
|
||||
## 4. The evidence rule, as written and where it lives
|
||||
|
||||
> **Evidence is copied off the machine at the end of the phase that produced it — before any revert,
|
||||
> snapshot restore or teardown. Not at the end of the session.**
|
||||
>
|
||||
> **The mechanism, because a rule without one is a wish:** the last act of a phase that ran on a machine
|
||||
> is `scp`/`pct pull` of its logs into the evidence directory on DooPlex — the same act that ends the
|
||||
> phase, not a separate step to remember later.
|
||||
>
|
||||
> **When a session notices the evidence is already gone: say so plainly in the report and REPRODUCE it
|
||||
> independently.** That is the documented expectation, not an improvisation invented under pressure.
|
||||
|
||||
**Four homes**, chosen so a session meets it before the revert rather than after:
|
||||
|
||||
1. `runbooks/workspace-CLAUDE.md` — **standing rule 5**, so it loads in every session, with the
|
||||
two-incident record in the R-96 rationale comment beneath it.
|
||||
2. `runbooks/target-selection.md` — its own section, in the doc you read *before* picking a machine to
|
||||
break. Tier 0 machines are disposable, which is exactly why nothing you need may be left on one.
|
||||
3. `RUNBOOK-rehearsal-v3.md` — in the standing-rules block, flagged as applying to every phase boundary.
|
||||
4. `PROMPT-TEMPLATE.md` — a new **report item 8**, so a session must state that it did this.
|
||||
|
||||
**Provenance, both occurrences verified, not recalled:** 2026-08-12 the retained-key drill lost its
|
||||
Phase A logs to the revert to `virgin` between Phase A and Phase B
|
||||
(`audits/DRILL-retained-key-2026-08-12.md` §11.5); 2026-08-13 R-316 lost its Part 1 logs, **same box,
|
||||
same revert, same point** (§9 — *"the same mistake as Tuesday, in the same place"*). Both times the
|
||||
existing "scp the log OUT first" was applied to the **final** teardown and not the **intermediate** one.
|
||||
Filed as **R-320**.
|
||||
|
||||
**A side effect worth naming:** that second record lived in `REPORT.md`, which this report overwrites —
|
||||
**writing tonight's report would have destroyed the record of a destroyed record.** It was preserved to
|
||||
`audits/REPORT-r316-installer-v1.28.0-2026-08-13.md` first, and both citations now point there.
|
||||
|
||||
---
|
||||
|
||||
## 5. The three rulings, recorded as decided
|
||||
|
||||
**`STATUS.md`'s "Waiting on you" section is now empty**, and says so: *"Nothing. All three questions
|
||||
that stood here were answered on 12–13 August and have moved to Decided below."* A new **Decided**
|
||||
section carries them, and each register row's status field changed from `READY` to `DECIDED`.
|
||||
|
||||
| Ruling | Trigger that reopens it |
|
||||
|---|---|
|
||||
| **R-312 — recovering an old backup stays a phone call.** Not built, deliberately; the operator path genuinely works (the 2026-08-12 drill restored planted files byte-identical by hand) | **A real need appearing — one request from a customer who is not us.** Until then R-304's honest position stands: retention is operator-only, and nothing may promise the customer can do it |
|
||||
| **R-313 — the unopenable set-aside store on `demo-felhom` is KEPT, as a test fixture.** The specific advantage the operator accepted: it is the only state in existence where a set-aside store is present and **cannot be opened** — a case that cannot be manufactured without destroying another key on purpose | **Delete it when the work it is a fixture FOR ships, or is abandoned** — i.e. when R-312 is built, or when R-312's ruling is made permanent. On either event, delete deliberately and record why |
|
||||
| **R-303 — a machine in two kinds of trouble says both things: left as it is.** Real-world likelihood unknown; the tidier fix risks hiding a genuine second failure | **An observation of the combined state occurring OUTSIDE a constructed test.** One sighting on a real machine reopens it |
|
||||
|
||||
---
|
||||
|
||||
## 6. B0 — do the facts arrive, and is this hub-only?
|
||||
|
||||
**Yes, and yes.** Both halves established before any code was written.
|
||||
|
||||
- **On the wire and in the database.** `demo-felhom-8363b5`'s newest `host_reports` row carries
|
||||
`guest_net.checked_at` plus per-guest `vmid/state/mode/ip/has_route/dhclient_alive/checked_at/message`.
|
||||
The agent's wire type (`felhom-agent/internal/hub/report.go:139-160`) additionally declares `healed`,
|
||||
`heal_succeeded`, `last_heal_at`, `heals_last_hour`, `damped` — absent from the live rows only because
|
||||
they are `omitempty` on a box that has never needed a repair.
|
||||
- **Read by nothing.** The string `guest_net` occurred **nowhere** in `felhom.eu/hub/` — no struct, no
|
||||
template, no checker. Stored as raw text inside `report_json`.
|
||||
|
||||
**So no wire change and no agent change were needed: hub-only.** The halt condition did not fire.
|
||||
|
||||
---
|
||||
|
||||
## 7. Reclassification counts — measured, not estimated
|
||||
|
||||
The register row said *twenty-one*; **the gate's allowlist held twenty.** Twenty is what the
|
||||
dispositions account for, exactly:
|
||||
|
||||
| State | Count | Which |
|
||||
|---|---|---|
|
||||
| **Read** (removed from the allowlist) | **8** | `guest_net` + its seven children |
|
||||
| **Deliberately not consumed** (new third kind, with the ruling and its date) | **5** | `mgmt_plane.healed_recently`, `pbs_dr.applied_at`, `config_hash`, `stacks`, `storage.migrated_to` |
|
||||
| **Redundant** (decided on its own merits) | **1** | `reporting_disabled` |
|
||||
| **Still owed a reader** (R-264, open) | **6** | `selfupdate_pending`, `selfupdate_pending_version`, `restore_tests.mount_parity`, `restore_tests.mount_inventory`, `backup.last_db_dump`, `backup.last_integrity_check` |
|
||||
|
||||
**The eight are REMOVED rather than re-labelled, and that is the point:** an allowlisted tag is
|
||||
*skipped* by the gate, so leaving them would have meant the new reader's own fields were never checked
|
||||
for reachability at all.
|
||||
|
||||
**A thing the task told me to re-read from the register, which was not there.** The operator's
|
||||
dispositions were made on 2026-08-12; **R-264 still read `READY — owner Viktor` and all twenty
|
||||
allowlist entries still said "arguably owed"**. A session told to re-read them from the register would
|
||||
have found none. They are written down now, which is the point of writing them down.
|
||||
|
||||
**`reporting_disabled`, decided on its own merits — and the decision found a real defect the flag would
|
||||
not have fixed.** The product does support the state: the controller sends one minimal report carrying
|
||||
`reporting_disabled: true` **and** `health.status: "disabled"` (`cmd/controller/main.go:1246-1260`),
|
||||
then goes quiet by design. The hub **already decodes** `health_status` and **already renders** that
|
||||
customer as `disabled` (`web/rollup.go:25`) — so the flag is a second spelling of a fact already read:
|
||||
**redundant**. But `StalenessChecker.Check` (`monitor/staleness.go:88+`) is **age-only**; its sole skip
|
||||
is `IsCustomerBlocked`. **A deliberately-silent box still goes `node_stale` at 30 minutes and
|
||||
`node_down` at 60** — exactly the false alarm B0 predicted. **Filed as R-321 and deliberately not fixed
|
||||
here:** decoding the flag would have felt like progress and left the alarm firing. The fix belongs in
|
||||
the checker, which already holds the status it needs.
|
||||
|
||||
---
|
||||
|
||||
## 8. The reader as built, and the alarm judgement
|
||||
|
||||
**`hub/internal/web/hosts.go`** — `parseGuestNet` / `guestNet` / `guestNetView`; rendered as a **Guest
|
||||
network** card on the host-detail page, which is where a person looks at a machine.
|
||||
|
||||
**The signal is the repair count, not the state.** A guest the watchdog keeps repairing is healthy at
|
||||
every instant anyone looks and is nevertheless failing; rendering `state` alone would give it a green
|
||||
tick — the exact shape of the failed-disk-drawn-as-a-healthy-empty-disk defect. `heals_last_hour` sits
|
||||
**beside** the state and drives the summary badge.
|
||||
|
||||
**`heal_succeeded` is decoded too, and that was a deliberate addition mid-build.** My first cut carried
|
||||
the count and not the outcome — which is **R-260 exactly**: a hub decoder three fields short of the
|
||||
agent, missing the one that decides the question. Six *failed* repairs is a guest that is down; six
|
||||
successful ones is a nuisance.
|
||||
|
||||
**The four scenarios, and what the card shows for each — all four verified by test, and three of them
|
||||
observed on the live fleet:**
|
||||
|
||||
| | Rendered | Live sighting |
|
||||
|---|---|---|
|
||||
| **A** healthy, no repairs | `healthy` badge, address, route, dhclient, `0` repairs | **`demo-felhom-8363b5`** — 9201 healthy, `192.168.0.149` (dhcp), swept `08:45:33Z`; **`demo-hp-bb76ea`** — 9201 healthy, `192.168.0.118`, swept `08:52:35Z` |
|
||||
| **B** repaired repeatedly | `needs attention`; the **count** rendered as a warn badge with the last repair time; a sentence naming the 1 h 15 m incident | not yet on hardware — neither demo box has needed a repair since the watchdog shipped |
|
||||
| **C** does not report it | **`unknown`, never healthy** — three absences, three different sentences | **`drill-r50-0a4f9a`** — *"A capable agent sent no guest-network stanza"* → `unknown`. **The unknown branch fired on real data, not only in a test** |
|
||||
| **D** malformed | `unknown`, and the page returns **200** | covered by test; the decode error is swallowed on purpose so one box's bad field cannot break the page for the fleet |
|
||||
|
||||
Two extra branches beyond the four: an unrecognised guest `state` renders unknown (the switch is an
|
||||
allow-list, so adding a state to the agent can never silently paint it green), and an **empty guest
|
||||
list with a fresh sweep is NOT silence** — the agent's contract says that means "the watchdog ran and
|
||||
found nothing", which must stay distinguishable from "the watchdog is not wired", the shape the
|
||||
v0.91.0 inert seam hid behind.
|
||||
|
||||
### The alarm judgement: **no email, deliberately**
|
||||
|
||||
I agree with the task's recommendation and did not add one. The reasoning, since it is a judgement:
|
||||
|
||||
- **The incident was a visibility failure, not a paging failure.** Nobody could *see* the condition for
|
||||
1 h 15 m. A card fixes what actually broke.
|
||||
- **A new alarm on a fleet of two demo machines is untested noise**, on a dispatcher whose severity
|
||||
contract is exact-match lowercase and whose customer-message allow-list must move with it — a
|
||||
two-place change that fires against no real population.
|
||||
- **There is no calibrated threshold to alarm on.** Neither demo box has produced a single repair since
|
||||
the watchdog shipped, so any number I picked would be invented. **The visible count is what will
|
||||
supply the threshold** — which is the argument for building the card first and the alarm second.
|
||||
|
||||
**Revisit when a third machine exists, or when a repair count is seen climbing on real hardware.**
|
||||
|
||||
---
|
||||
|
||||
## 9. Red-proofs — every mutation asserted applied before its run
|
||||
|
||||
Five in total: three mandated for B2, two for A2. Each mutation was **confirmed present by grep before
|
||||
the test ran**, and confirmed **absent by grep after restoring**.
|
||||
|
||||
| # | Mutation | Asserted applied | Outcome |
|
||||
|---|---|---|---|
|
||||
| **1** *(the one that matters)* | The unknown branches in the card's badge chain replaced by the healthy badge | `grep -c 'title="MUTATED">healthy'` → **2** | **RED — both C sub-cases.** A silent machine seen rendering as healthy: *"a silent box must SAY it is unknown"* and *"an old agent's silence must be named as an old agent's silence"* |
|
||||
| **2** | `RepairCount: 0` in the decoder — the climbing-repairs signal dropped | `hosts.go:385 RepairCount: 0, … // MUTATED` | **RED — B**: *"a guest repaired 6 times in an hour is reported as fine — the whole point of the card"* |
|
||||
| **3** | `Degraded()` forced `true` — the healthy branch broken | `hosts.go:348 func … { return true /* MUTATED */ }` | **RED — A**: *"a machine that is fine is being alarmed on"* — the guard is reachable in **both** directions |
|
||||
| **4** | `ReissueForReenroll` routed back to `EmailReset` | `grep` → line 195 reads `EmailReset` | **RED — two tests**: the new `TestReenrollSplit_ChangesTheMailNotTheSecret` **and** the pre-existing `TestReissueForReenroll` |
|
||||
| **5** | „Visszaállító kód: %s" restored in the reset mail body | `grep -n` → `templates.go:241` | **RED — `TestFormatClaimEmail_OneNamePerSecret`** |
|
||||
|
||||
**After every restore the suite is green again**, and `grep -c MUTATED` returns **0** in both touched
|
||||
files.
|
||||
|
||||
**A positive control that the reader is WIRED and not merely written**, independent of the tests: the
|
||||
wire-contract gate's checked-tag count rose **182 → 190** and its skipped count fell **88 → 80** as the
|
||||
eight allowlist entries came out. The gate still passes — meaning those eight tags are now genuinely
|
||||
reachable in the hub.
|
||||
|
||||
---
|
||||
|
||||
## 10. Part C — **DROPPED**, and one part of it answered anyway
|
||||
|
||||
**Dropped, as the task's own drop order specifies.** The honest reason is not only time: **the task
|
||||
names "nine claims" that are grey, and I could not identify which nine.** The capability map holds
|
||||
**22** rows marked `IMPLEMENTED`, five `PARTIAL` and four `MISSING`, and nothing in the tree enumerates
|
||||
a set of nine. Picking nine myself and reporting on them would have produced a confident answer to a
|
||||
question nobody asked — the A4 failure mode, one section later.
|
||||
|
||||
**The one I can answer, because the task identified it precisely.** The self-heal claim is the
|
||||
capability-map row *"Box survives an unattended app or guest-network failure… it is noticed, and where
|
||||
safe it is repaired"*, and its best document does **not** argue against it. The 1 h 15 m outage
|
||||
(`audits/INCIDENT-guest-dhclient-killed-2026-07-20.md`) is the row's **origin**, not its evidence: the
|
||||
evidence is a **deliberate replay of that incident the next day** — `kill -9` at 12:43:18, detected on
|
||||
process liveness **57 s** later while the lease was still live, healed at 12:45:18 with the incident's
|
||||
verbatim invocation, and **the tunnel never dropped** (`cloudflared Up 29 hours`). That is a walk, and
|
||||
the outage was prevented rather than merely observed. **The claim does not need to move down.**
|
||||
|
||||
**What I would flag instead:** the row's *guest-network* leg was proven on the box and, until today,
|
||||
**the hub could not see the condition at all** — which is the gap this session closed and which no
|
||||
capability row expressed. My new row states its own status honestly as **IMPLEMENTED, not
|
||||
PROVEN-LIVE**, because **no machine has ever been observed with a climbing repair count on this card.**
|
||||
|
||||
---
|
||||
|
||||
## 11. Versions, commits, deploy, CI
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Shipped** | **hub v0.104.0** (`gitea.dooplex.hu/admin/felhom-hub:0.104.0`, 25 MB) |
|
||||
| **Unchanged** | controller **0.214.0**, agent **0.129.0**, installer **1.28.0**, golden 0.214.0, floor 0.214.0, MinAgent 0.129.0 |
|
||||
| **Commits** | `4d6ec7c` the work · `7c97c94` the manifest bump |
|
||||
| **Manifest** | `manifests/hub.yaml:128` → `felhom-hub:0.104.0`, GitOps only — **no `kubectl set image`** |
|
||||
| **Deploy** | ArgoCD hard-refresh + sync → `Synced / Healthy`; pod `hub-5c4d8d4b49-864dc` **1/1 Running**; deployment image confirmed `0.104.0` |
|
||||
| **CI, confirmed by run ID** | run **334** (`7c97c949f6`) **success** · run **333** (`4d6ec7c7bb`) **success** |
|
||||
| **Gates** | `repo_gates.py --fast` — all **8** OK, and again in the pre-push hook on both pushes. **No `--no-verify`.** |
|
||||
| **Green gate** | `hub/`: build rc=0, vet rc=0, **test rc=0 across 18 packages**. Run separately from every commit |
|
||||
|
||||
**Live validation method — stated, as the fence requires:** endpoint-level. I invoked the exact URLs
|
||||
the operator UI serves (`GET /hosts/<id>`, `GET /customers/<id>`) against the hub's ClusterIP with the
|
||||
operator Basic-auth credential, so no server logic was skipped — only browser rendering.
|
||||
`claude-in-chrome` is not available on DooPlex; a click-through remains the operator's.
|
||||
|
||||
**Files:** `hub/internal/web/hosts.go`, `hub/internal/web/templates/host_detail_body.html`,
|
||||
`hub/internal/claim/engine.go`, `hub/internal/notify/templates.go`, `hub/internal/web/configs.go`,
|
||||
`hub/internal/web/templates/customer_unified.html`, `scripts/wire_contract_gate.py`, plus
|
||||
`hub/internal/web/hosts_guestnet_test.go` (**new**, 7 tests) and `hub/internal/claim/naming_test.go`
|
||||
(**new**, 6 tests). Tests **+13**.
|
||||
|
||||
**Register:** R-319, R-320, R-321, R-322 minted (ceiling was R-318, grepped first). R-264, R-309, R-312,
|
||||
R-313, R-303 and the `PETI` row updated. `STATUS.md` and the capability map updated.
|
||||
|
||||
---
|
||||
|
||||
## 12. What was dropped, and observations
|
||||
|
||||
**Dropped — named plainly, nothing silently shortened:**
|
||||
|
||||
- **Part C in full**, except the self-heal verdict in §10. Reason in §10: the nine were not identifiable,
|
||||
and inventing them would have been worse than the gap.
|
||||
|
||||
**Nothing else was dropped.** Part A is complete (A1–A5), Part B is complete (B0, B1, and the one reader
|
||||
B2 asked for — not four).
|
||||
|
||||
### Observations — noticed, not acted on
|
||||
|
||||
- **A "0 bytes" answer was nearly a wrong verdict, twice in one hour.** `demo-hp`'s host page came back
|
||||
empty from a `kubectl run` curl pod, which reads exactly like "the card does not render". Retrying with
|
||||
a clean pod name returned **HTTP 200** and a correct card. *An empty listing is not evidence of
|
||||
emptiness* — the instrument was the fault, and the rule caught it.
|
||||
- **R-264's count was wrong**: the row says twenty-one facts, the allowlist held twenty. The row is now
|
||||
written against the measured number.
|
||||
- **The wire gate does not detect a stale allowlist entry.** Its sibling `retrieval_promise_gate.py`
|
||||
fails on one; this one silently skips. Had I re-labelled the eight `guest_net` entries instead of
|
||||
deleting them, the gate would have reported a coverage it did not have and said nothing. Worth the
|
||||
same treatment.
|
||||
- **A third secret sits one homograph away from the two that collided.** The hub's self-bind flow calls
|
||||
the **five-word** retrieval passphrase „**visszaállító jelszó**" (`web/selfbind.go:255,261`;
|
||||
`notify/templates.go:285`) — *jelszó*, not *kód*, so it is outside R-295's ruling and I left it alone.
|
||||
But „Visszaállító kód" was just retired for being a near-homograph of „Helyreállítási kód", and this
|
||||
is a near-homograph of the name that was retired. **Three secrets, three names, and two of them still
|
||||
begin with the same word.** A ruling for it is the operator's, not mine.
|
||||
- **`agents.md`-style version drift in project memory**: `instructions_gate` emits 32 version-literal
|
||||
warnings against `MEMORY.md`. Not a failure and not mine to fix tonight, but it is aimed at the next
|
||||
model to edit that file — which is worth someone acting on before it is noise nobody reads.
|
||||
@@ -183,6 +183,14 @@ no first-boot hook at all, so this question now governs **operator-built images
|
||||
`main` on a 30-second period (`documentation/.../day0-install.md:150-152`) — no release tag, no
|
||||
staging copy, no version selector. Pushing the script publishes it.
|
||||
|
||||
> **⚠ SUPERSEDED 2026-08-03, annotated 2026-08-13 (R-110, R-309). True on the day it was written;
|
||||
> false ever since.** `/scripts/` is now served from the tag `installer-v<SCRIPT_VERSION>` and
|
||||
> **pushing publishes nothing** — publication is a tag plus **two** `--ref` pins in
|
||||
> `manifests/webpage.yaml`. The dated finding is kept as written rather than rewritten, because it
|
||||
> is a record of what was true then; **the note is here because this paragraph cited
|
||||
> `day0-install.md` as its source, which is how the wrong sentence spread.** Current procedure and
|
||||
> the outside-verification command: `runbooks/day0-install.md` §C.1.
|
||||
|
||||
3. **Console display does not exist.** `felhom-host-install.sh` does not write `/etc/issue`,
|
||||
`/etc/issue.net` or any MOTD (grep: no match). PVE's own `/etc/issue` banner is what the console
|
||||
shows after install — observed in this session's screendumps as
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=appliance customer=drill-r50 vmid=120
|
||||
|
||||
[STEP] 1/8 pre-flight
|
||||
[INFO] pve-manager/9.2.2/b9984c6d90a4bd80 (running kernel: 7.0.2-6-pve)
|
||||
[INFO] node: drill-pve (auto)
|
||||
[INFO] agent config: /etc/felhom-agent/agent.json
|
||||
[INFO] agent: not installed yet — will be fetched + installed in step 5/8
|
||||
[INFO] local-lvm free: ~75 GiB
|
||||
[WARN] local-lvm free ~75 GiB < hard min 120 GiB
|
||||
[INFO] free RAM: ~6310 MiB
|
||||
[INFO] existing guests on this host: 0 (pct+qm)
|
||||
[INFO] acl storage 'felhom-pbs' not present yet — expected: the PBS-DR tier creates it; the grant is pre-positioned deliberately
|
||||
[INFO] dnsmasq: already installed BEFORE Felhom — recorded; uninstall will not touch it
|
||||
[INFO] dnsmasq-base: already installed BEFORE Felhom — recorded; uninstall will leave it
|
||||
[INFO] hub reachable (https://hub.felhom.eu)
|
||||
[OK] customer 'drill-r50' exists + passphrase valid
|
||||
[INFO] golden (local): local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[INFO] --skip-provision: agent install/config only, no guest will be provisioned
|
||||
[OK] pre-flight passed
|
||||
[STEP] 2/8 Proxmox API token
|
||||
[OK] token minted (secret captured, not logged)
|
||||
[OK] scoped ACL applied (Base@/, Guest@/pool/felhom + /vms/990000..990009, Store@[local local-lvm felhom-pbs])
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
[STEP] 3/8 compute volume grows
|
||||
[INFO] auto-computed from ~75 GiB free (ONE volume since R-165)
|
||||
[INFO] grows: rootfs +0G (->32G), data +46G (->70G, ONE volume)
|
||||
[STEP] 4/8 host enrollment (POST /host-enroll)
|
||||
[OK] host REUSED (idempotent — existing credential)
|
||||
[INFO] host_id: drill-r50-0a4f9a (api_key captured, not logged)
|
||||
[STEP] 4b/8 break-glass credential (root@pam console password → hub vault)
|
||||
[OK] root@pam password set + vaulted to the hub (retrieve via the operator /admin path; never logged here)
|
||||
[WARN] NOTE: the root@pam password just CHANGED — the old one now fails at the PVE web GUI (:8006).
|
||||
[WARN] Retrieve the new one at hub → host page (vaulted recovery credential).
|
||||
[STEP] 5/8 agent install (fetch + verify + install)
|
||||
[OK] apt repos aligned to no-subscription (already aligned; apt-get update OK)
|
||||
[WARN] no git credential in controller.yaml — fetching artifacts ANONYMOUSLY (they are world-readable; sha256 verification unchanged)
|
||||
[INFO] manifest: agent v0.129.0 (sha 53a54f0620afbd6d…), golden v0.214.0
|
||||
[INFO] fetching agent binary v0.129.0 from Gitea …
|
||||
[OK] verified sha256 53a54f0620afbd6d… matches the hub manifest
|
||||
[OK] installed /usr/local/bin/felhom-agent (felhom-agent 0.129.0)
|
||||
[OK] created service user felhom-agent
|
||||
[OK] added felhom-agent to systemd-journal (unprivileged journal read for NAS verify)
|
||||
[OK] installed /usr/local/sbin/felhom-mkfs-guarded (0755, the guarded mkfs path)
|
||||
[OK] installed /usr/local/sbin/felhom-selfupdate-guarded (0755, the guarded A/B binary-swap path)
|
||||
[OK] installed /usr/local/sbin/felhom-pbs-apply (0755, the guarded PBS-DR apply path)
|
||||
[OK] installed /usr/local/sbin/felhom-backup-target-apply (0755, the guarded backup-target path)
|
||||
[OK] installed /etc/sudoers.d/felhom-agent (0440, visudo-validated)
|
||||
[OK] installed /etc/systemd/system/felhom-agent.service + enabled (started in step 6 after config)
|
||||
[OK] installed self-update rollback unit + start-limit drop-in (auto-rollback armed)
|
||||
[OK] installed break-glass layers 1+2 (tmpfiles /run/sshd + agent-independent watchdog timer)
|
||||
[OK] installed OOB felhom-sshd instance + static belt (agent renders config + fills sets once oob.enabled)
|
||||
[STEP] 6/8 agent config + service
|
||||
[WARN] backup target: DEGRADED — no eligible second drive, so the whole-system backup stays on the SYSTEM drive.
|
||||
[WARN] It protects against file corruption but NOT against a disk failure. Attach a second drive and assign it in the dashboard.
|
||||
[INFO] island bridge vmbr9 already present — leaving it
|
||||
[INFO] R-50 island ON: local_api=169.254.253.1:8443 (vmbr9); guest net1=169.254.253.2/30; lan_resolver.host_ip=10.0.2.15
|
||||
[INFO] node=drill-pve local_api=169.254.253.1:8443 tls_fp=C9:1F:AC:10:AE:62…
|
||||
[OK] wrote /etc/felhom-agent/agent.json (0600 felhom-agent)
|
||||
[OK] agent --selftest (read-only) passed
|
||||
[OK] felhom-agent service active (non-root felhom-agent reads the config OK)
|
||||
[STEP] 7/8 golden archive
|
||||
[INFO] local golden digest matches the manifest (3a40379cb00d98c6…) — this IS the vouched artifact
|
||||
[SKIP] using local golden: local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[SKIP] provision (--skip-provision) — agent install/config verified only
|
||||
[STEP] verify (agent only)
|
||||
[INFO] binary: felhom-agent 0.129.0
|
||||
[INFO] runs as: felhom-agent (want felhom-agent)
|
||||
[OK] service active
|
||||
[OK] --selftest=hub OK (a host-report reached the hub)
|
||||
|
||||
[OK] Agent install SUCCESS — felhom-agent 0.129.0 as felhom-agent, host_id=drill-r50-0a4f9a customer=drill-r50
|
||||
@@ -0,0 +1,731 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=uninstall
|
||||
|
||||
[STEP] UNINSTALL — local host teardown
|
||||
[SKIP] guest 120 already absent — skipping guest teardown
|
||||
[STEP] host-level removal
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-agent.service'.
|
||||
Removed '/etc/systemd/system/timers.target.wants/felhom-mgmt-watchdog.timer'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-sshd.service'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-oob-nft.service'.
|
||||
The unit files have no installation config (WantedBy=, RequiredBy=, UpheldBy=,
|
||||
Also=, or Alias= settings in the [Install] section, and DefaultInstance= for
|
||||
template units). This means they are not meant to be enabled or disabled using systemctl.
|
||||
|
||||
Possible reasons for having these kinds of units are:
|
||||
• A unit may be statically enabled by being symlinked from another unit's
|
||||
.wants/, .requires/, or .upholds/ directory.
|
||||
• A unit's purpose may be to act as a helper for some other unit which has
|
||||
a requirement dependency on it.
|
||||
• A unit may be started when needed via activation (socket, path, timer,
|
||||
D-Bus, udev, scripted systemctl call, ...).
|
||||
• In case of template units, the unit is meant to be enabled with some
|
||||
instance name specified.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-shared-parent.service'.
|
||||
Removed '/etc/systemd/system/pve-guests.service.wants/felhom-shared-parent.service'.
|
||||
[INFO] dnsmasq pre-dates Felhom (recorded at install) — leaving it running, restarting only
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] golden vzdump left in place (pass --remove-golden to remove)
|
||||
|
||||
[STEP] kept vs wiped — read before pulling drives or closing the customer out
|
||||
WIPED (this run):
|
||||
- guest 120 (container + its OS/Docker/user-data volumes)
|
||||
- the felhom-agent: binary, unit, sudoers, config (+ its .bak backups), state dir, service user
|
||||
- self-update artifacts: guarded wrapper, A/B slots (.prev/.new.*), rollback unit, start-limit drop-in
|
||||
- break-glass watchdog + OOB artifacts (where present); guest-hook snippet; dnsmasq snippets; the mkfs + pbs-apply wrappers
|
||||
- pveum: the Felhom roles/user/token/scoped ACL; the emptied felhom pool
|
||||
- the install state file
|
||||
KEPT (lives on deliberately — remove/rotate these out-of-band if the customer is leaving):
|
||||
- the enrolled drives + ALL data under /mnt/felhom-drives — unmounted only, NEVER wiped;
|
||||
the drives are physically removable now.
|
||||
- the hub host/customer record + report history (operator UI / DB)
|
||||
- the escrow blob in the hub, if one exists (operator UI)
|
||||
- the hub-vaulted root@pam recovery credential — the box KEEPS the password step 4b set; rotate it if the box leaves Felhom management
|
||||
|
||||
[OK] UNINSTALL complete — removed: guest 120, the felhom-agent (unit/sudoers/binary/state/config+baks/user + selfupdate-artifacts/shared-parent/mkfs-wrapper/pbs-apply-wrapper/hook-snippet/dnsmasq-snippets), the pveum role/user/token/ACL, the felhom pool, and /var/lib/felhom-install/state.json.
|
||||
[INFO] golden vzdump: left in place (--remove-golden to remove).
|
||||
[INFO] NOTE: the 'sudo' package was left INSTALLED (a system package, never ours to remove). dnsmasq is removed only when the install-time record says Felhom installed it; a resolver that pre-dated Felhom is never touched. The host record still exists in the hub — remove it there if desired.
|
||||
@@ -0,0 +1,71 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=appliance customer=drill-r50 vmid=120
|
||||
|
||||
[STEP] 1/8 pre-flight
|
||||
[INFO] pve-manager/9.2.2/b9984c6d90a4bd80 (running kernel: 7.0.2-6-pve)
|
||||
[INFO] node: drill-pve (auto)
|
||||
[INFO] agent config: /etc/felhom-agent/agent.json
|
||||
[INFO] agent: not installed yet — will be fetched + installed in step 5/8
|
||||
[INFO] local-lvm free: ~75 GiB
|
||||
[WARN] local-lvm free ~75 GiB < hard min 120 GiB
|
||||
[INFO] free RAM: ~6243 MiB
|
||||
[INFO] existing guests on this host: 0 (pct+qm)
|
||||
[INFO] acl storage 'felhom-pbs' not present yet — expected: the PBS-DR tier creates it; the grant is pre-positioned deliberately
|
||||
[INFO] dnsmasq: not present before Felhom — recorded; uninstall will remove it again if we install it
|
||||
[INFO] hub reachable (https://hub.felhom.eu)
|
||||
[OK] customer 'drill-r50' exists + passphrase valid
|
||||
[INFO] golden (local): local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[INFO] --skip-provision: agent install/config only, no guest will be provisioned
|
||||
[OK] pre-flight passed
|
||||
[STEP] 2/8 Proxmox API token
|
||||
[OK] token minted (secret captured, not logged)
|
||||
[OK] scoped ACL applied (Base@/, Guest@/pool/felhom + /vms/990000..990009, Store@[local local-lvm felhom-pbs])
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
[STEP] 3/8 compute volume grows
|
||||
[INFO] auto-computed from ~75 GiB free (ONE volume since R-165)
|
||||
[INFO] grows: rootfs +0G (->32G), data +46G (->70G, ONE volume)
|
||||
[STEP] 4/8 host enrollment (POST /host-enroll)
|
||||
[OK] host REUSED (idempotent — existing credential)
|
||||
[INFO] host_id: drill-r50-0a4f9a (api_key captured, not logged)
|
||||
[STEP] 4b/8 break-glass credential (root@pam console password → hub vault)
|
||||
[OK] root@pam password set + vaulted to the hub (retrieve via the operator /admin path; never logged here)
|
||||
[WARN] NOTE: the root@pam password just CHANGED — the old one now fails at the PVE web GUI (:8006).
|
||||
[WARN] Retrieve the new one at hub → host page (vaulted recovery credential).
|
||||
[STEP] 5/8 agent install (fetch + verify + install)
|
||||
[OK] apt repos aligned to no-subscription (already aligned; apt-get update OK)
|
||||
[WARN] no git credential in controller.yaml — fetching artifacts ANONYMOUSLY (they are world-readable; sha256 verification unchanged)
|
||||
[INFO] manifest: agent v0.129.0 (sha 53a54f0620afbd6d…), golden v0.214.0
|
||||
[INFO] fetching agent binary v0.129.0 from Gitea …
|
||||
[OK] verified sha256 53a54f0620afbd6d… matches the hub manifest
|
||||
[OK] installed /usr/local/bin/felhom-agent (felhom-agent 0.129.0)
|
||||
[OK] created service user felhom-agent
|
||||
[OK] added felhom-agent to systemd-journal (unprivileged journal read for NAS verify)
|
||||
[OK] installed /usr/local/sbin/felhom-mkfs-guarded (0755, the guarded mkfs path)
|
||||
[OK] installed /usr/local/sbin/felhom-selfupdate-guarded (0755, the guarded A/B binary-swap path)
|
||||
[OK] installed /usr/local/sbin/felhom-pbs-apply (0755, the guarded PBS-DR apply path)
|
||||
[OK] installed /usr/local/sbin/felhom-backup-target-apply (0755, the guarded backup-target path)
|
||||
[OK] installed /etc/sudoers.d/felhom-agent (0440, visudo-validated)
|
||||
[OK] installed /etc/systemd/system/felhom-agent.service + enabled (started in step 6 after config)
|
||||
[OK] installed self-update rollback unit + start-limit drop-in (auto-rollback armed)
|
||||
[OK] installed break-glass layers 1+2 (tmpfiles /run/sshd + agent-independent watchdog timer)
|
||||
[OK] installed OOB felhom-sshd instance + static belt (agent renders config + fills sets once oob.enabled)
|
||||
[STEP] 6/8 agent config + service
|
||||
[WARN] backup target: DEGRADED — no eligible second drive, so the whole-system backup stays on the SYSTEM drive.
|
||||
[WARN] It protects against file corruption but NOT against a disk failure. Attach a second drive and assign it in the dashboard.
|
||||
[INFO] island bridge vmbr9 already present — leaving it
|
||||
[INFO] R-50 island ON: local_api=169.254.253.1:8443 (vmbr9); guest net1=169.254.253.2/30; lan_resolver.host_ip=10.0.2.15
|
||||
[INFO] node=drill-pve local_api=169.254.253.1:8443 tls_fp=C9:1F:AC:10:AE:62…
|
||||
[OK] wrote /etc/felhom-agent/agent.json (0600 felhom-agent)
|
||||
[OK] agent --selftest (read-only) passed
|
||||
[OK] felhom-agent service active (non-root felhom-agent reads the config OK)
|
||||
[STEP] 7/8 golden archive
|
||||
[INFO] local golden digest matches the manifest (3a40379cb00d98c6…) — this IS the vouched artifact
|
||||
[SKIP] using local golden: local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[SKIP] provision (--skip-provision) — agent install/config verified only
|
||||
[STEP] verify (agent only)
|
||||
[INFO] binary: felhom-agent 0.129.0
|
||||
[INFO] runs as: felhom-agent (want felhom-agent)
|
||||
[OK] service active
|
||||
[OK] --selftest=hub OK (a host-report reached the hub)
|
||||
|
||||
[OK] Agent install SUCCESS — felhom-agent 0.129.0 as felhom-agent, host_id=drill-r50-0a4f9a customer=drill-r50
|
||||
@@ -0,0 +1,776 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=uninstall
|
||||
|
||||
[STEP] UNINSTALL — local host teardown
|
||||
[SKIP] guest 120 already absent — skipping guest teardown
|
||||
[STEP] host-level removal
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-agent.service'.
|
||||
Removed '/etc/systemd/system/timers.target.wants/felhom-mgmt-watchdog.timer'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-sshd.service'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-oob-nft.service'.
|
||||
The unit files have no installation config (WantedBy=, RequiredBy=, UpheldBy=,
|
||||
Also=, or Alias= settings in the [Install] section, and DefaultInstance= for
|
||||
template units). This means they are not meant to be enabled or disabled using systemctl.
|
||||
|
||||
Possible reasons for having these kinds of units are:
|
||||
• A unit may be statically enabled by being symlinked from another unit's
|
||||
.wants/, .requires/, or .upholds/ directory.
|
||||
• A unit's purpose may be to act as a helper for some other unit which has
|
||||
a requirement dependency on it.
|
||||
• A unit may be started when needed via activation (socket, path, timer,
|
||||
D-Bus, udev, scripted systemctl call, ...).
|
||||
• In case of template units, the unit is meant to be enabled with some
|
||||
instance name specified.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-shared-parent.service'.
|
||||
Removed '/etc/systemd/system/pve-guests.service.wants/felhom-shared-parent.service'.
|
||||
[INFO] dnsmasq was installed by Felhom (recorded at install) — stopping + disabling it
|
||||
Synchronizing state of dnsmasq.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
|
||||
Executing: /usr/lib/systemd/systemd-sysv-install disable dnsmasq
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/dnsmasq.service'.
|
||||
[WARN] dnsmasq: NOT purging — something else now depends on it. Removing it would also take out:
|
||||
[WARN] household-dns-thing
|
||||
[WARN] The unit is stopped + disabled, so :53 is free. The package stays, deliberately.
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] golden vzdump left in place (pass --remove-golden to remove)
|
||||
|
||||
[STEP] kept vs wiped — read before pulling drives or closing the customer out
|
||||
WIPED (this run):
|
||||
- guest 120 (container + its OS/Docker/user-data volumes)
|
||||
- the felhom-agent: binary, unit, sudoers, config (+ its .bak backups), state dir, service user
|
||||
- self-update artifacts: guarded wrapper, A/B slots (.prev/.new.*), rollback unit, start-limit drop-in
|
||||
- break-glass watchdog + OOB artifacts (where present); guest-hook snippet; dnsmasq snippets; the mkfs + pbs-apply wrappers
|
||||
- pveum: the Felhom roles/user/token/scoped ACL; the emptied felhom pool
|
||||
- the install state file
|
||||
KEPT (lives on deliberately — remove/rotate these out-of-band if the customer is leaving):
|
||||
- the enrolled drives + ALL data under /mnt/felhom-drives — unmounted only, NEVER wiped;
|
||||
the drives are physically removable now.
|
||||
- the hub host/customer record + report history (operator UI / DB)
|
||||
- the escrow blob in the hub, if one exists (operator UI)
|
||||
- the hub-vaulted root@pam recovery credential — the box KEEPS the password step 4b set; rotate it if the box leaves Felhom management
|
||||
|
||||
[OK] UNINSTALL complete — removed: guest 120, the felhom-agent (unit/sudoers/binary/state/config+baks/user + selfupdate-artifacts/shared-parent/mkfs-wrapper/pbs-apply-wrapper/hook-snippet/dnsmasq-snippets), the pveum role/user/token/ACL, the felhom pool, and /var/lib/felhom-install/state.json.
|
||||
[INFO] golden vzdump: left in place (--remove-golden to remove).
|
||||
[WARN] NOTE: dnsmasq was NOT removed — purge would also remove household-dns-thing — dnsmasq left installed (stopped + disabled). Its unit is stopped + disabled, so :53 is free, but the NEXT install will read the package as pre-existing.
|
||||
[INFO] NOTE: the 'sudo' package was left INSTALLED (a system package, never ours to remove). dnsmasq is removed only when the install-time record says Felhom installed it; a resolver that pre-dated Felhom is never touched. The host record still exists in the hub — remove it there if desired.
|
||||
@@ -0,0 +1,71 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=appliance customer=drill-r50 vmid=120
|
||||
|
||||
[STEP] 1/8 pre-flight
|
||||
[INFO] pve-manager/9.2.2/b9984c6d90a4bd80 (running kernel: 7.0.2-6-pve)
|
||||
[INFO] node: drill-pve (auto)
|
||||
[INFO] agent config: /etc/felhom-agent/agent.json
|
||||
[INFO] agent: not installed yet — will be fetched + installed in step 5/8
|
||||
[INFO] local-lvm free: ~75 GiB
|
||||
[WARN] local-lvm free ~75 GiB < hard min 120 GiB
|
||||
[INFO] free RAM: ~6253 MiB
|
||||
[INFO] existing guests on this host: 0 (pct+qm)
|
||||
[INFO] acl storage 'felhom-pbs' not present yet — expected: the PBS-DR tier creates it; the grant is pre-positioned deliberately
|
||||
[INFO] dnsmasq: not present before Felhom — recorded; uninstall will remove it again if we install it
|
||||
[INFO] hub reachable (https://hub.felhom.eu)
|
||||
[OK] customer 'drill-r50' exists + passphrase valid
|
||||
[INFO] golden (local): local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[INFO] --skip-provision: agent install/config only, no guest will be provisioned
|
||||
[OK] pre-flight passed
|
||||
[STEP] 2/8 Proxmox API token
|
||||
[OK] token minted (secret captured, not logged)
|
||||
[OK] scoped ACL applied (Base@/, Guest@/pool/felhom + /vms/990000..990009, Store@[local local-lvm felhom-pbs])
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
[STEP] 3/8 compute volume grows
|
||||
[INFO] auto-computed from ~75 GiB free (ONE volume since R-165)
|
||||
[INFO] grows: rootfs +0G (->32G), data +46G (->70G, ONE volume)
|
||||
[STEP] 4/8 host enrollment (POST /host-enroll)
|
||||
[OK] host REUSED (idempotent — existing credential)
|
||||
[INFO] host_id: drill-r50-0a4f9a (api_key captured, not logged)
|
||||
[STEP] 4b/8 break-glass credential (root@pam console password → hub vault)
|
||||
[OK] root@pam password set + vaulted to the hub (retrieve via the operator /admin path; never logged here)
|
||||
[WARN] NOTE: the root@pam password just CHANGED — the old one now fails at the PVE web GUI (:8006).
|
||||
[WARN] Retrieve the new one at hub → host page (vaulted recovery credential).
|
||||
[STEP] 5/8 agent install (fetch + verify + install)
|
||||
[OK] apt repos aligned to no-subscription (already aligned; apt-get update OK)
|
||||
[WARN] no git credential in controller.yaml — fetching artifacts ANONYMOUSLY (they are world-readable; sha256 verification unchanged)
|
||||
[INFO] manifest: agent v0.129.0 (sha 53a54f0620afbd6d…), golden v0.214.0
|
||||
[INFO] fetching agent binary v0.129.0 from Gitea …
|
||||
[OK] verified sha256 53a54f0620afbd6d… matches the hub manifest
|
||||
[OK] installed /usr/local/bin/felhom-agent (felhom-agent 0.129.0)
|
||||
[OK] created service user felhom-agent
|
||||
[OK] added felhom-agent to systemd-journal (unprivileged journal read for NAS verify)
|
||||
[OK] installed /usr/local/sbin/felhom-mkfs-guarded (0755, the guarded mkfs path)
|
||||
[OK] installed /usr/local/sbin/felhom-selfupdate-guarded (0755, the guarded A/B binary-swap path)
|
||||
[OK] installed /usr/local/sbin/felhom-pbs-apply (0755, the guarded PBS-DR apply path)
|
||||
[OK] installed /usr/local/sbin/felhom-backup-target-apply (0755, the guarded backup-target path)
|
||||
[OK] installed /etc/sudoers.d/felhom-agent (0440, visudo-validated)
|
||||
[OK] installed /etc/systemd/system/felhom-agent.service + enabled (started in step 6 after config)
|
||||
[OK] installed self-update rollback unit + start-limit drop-in (auto-rollback armed)
|
||||
[OK] installed break-glass layers 1+2 (tmpfiles /run/sshd + agent-independent watchdog timer)
|
||||
[OK] installed OOB felhom-sshd instance + static belt (agent renders config + fills sets once oob.enabled)
|
||||
[STEP] 6/8 agent config + service
|
||||
[WARN] backup target: DEGRADED — no eligible second drive, so the whole-system backup stays on the SYSTEM drive.
|
||||
[WARN] It protects against file corruption but NOT against a disk failure. Attach a second drive and assign it in the dashboard.
|
||||
[INFO] island bridge vmbr9 already present — leaving it
|
||||
[INFO] R-50 island ON: local_api=169.254.253.1:8443 (vmbr9); guest net1=169.254.253.2/30; lan_resolver.host_ip=10.0.2.15
|
||||
[INFO] node=drill-pve local_api=169.254.253.1:8443 tls_fp=C9:1F:AC:10:AE:62…
|
||||
[OK] wrote /etc/felhom-agent/agent.json (0600 felhom-agent)
|
||||
[OK] agent --selftest (read-only) passed
|
||||
[OK] felhom-agent service active (non-root felhom-agent reads the config OK)
|
||||
[STEP] 7/8 golden archive
|
||||
[INFO] local golden digest matches the manifest (3a40379cb00d98c6…) — this IS the vouched artifact
|
||||
[SKIP] using local golden: local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[SKIP] provision (--skip-provision) — agent install/config verified only
|
||||
[STEP] verify (agent only)
|
||||
[INFO] binary: felhom-agent 0.129.0
|
||||
[INFO] runs as: felhom-agent (want felhom-agent)
|
||||
[OK] service active
|
||||
[OK] --selftest=hub OK (a host-report reached the hub)
|
||||
|
||||
[OK] Agent install SUCCESS — felhom-agent 0.129.0 as felhom-agent, host_id=drill-r50-0a4f9a customer=drill-r50
|
||||
@@ -0,0 +1,734 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=uninstall
|
||||
|
||||
[STEP] UNINSTALL — local host teardown
|
||||
[SKIP] guest 120 already absent — skipping guest teardown
|
||||
[STEP] host-level removal
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-agent.service'.
|
||||
Removed '/etc/systemd/system/timers.target.wants/felhom-mgmt-watchdog.timer'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-sshd.service'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-oob-nft.service'.
|
||||
The unit files have no installation config (WantedBy=, RequiredBy=, UpheldBy=,
|
||||
Also=, or Alias= settings in the [Install] section, and DefaultInstance= for
|
||||
template units). This means they are not meant to be enabled or disabled using systemctl.
|
||||
|
||||
Possible reasons for having these kinds of units are:
|
||||
• A unit may be statically enabled by being symlinked from another unit's
|
||||
.wants/, .requires/, or .upholds/ directory.
|
||||
• A unit's purpose may be to act as a helper for some other unit which has
|
||||
a requirement dependency on it.
|
||||
• A unit may be started when needed via activation (socket, path, timer,
|
||||
D-Bus, udev, scripted systemctl call, ...).
|
||||
• In case of template units, the unit is meant to be enabled with some
|
||||
instance name specified.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-shared-parent.service'.
|
||||
Removed '/etc/systemd/system/pve-guests.service.wants/felhom-shared-parent.service'.
|
||||
[WARN] dnsmasq: no ownership record for this box (installed before that was recorded).
|
||||
[WARN] Leaving it RUNNING — we do not stop a resolver we cannot prove we installed.
|
||||
[WARN] If this host had no dnsmasq before Felhom, a reinstall will refuse on the :53
|
||||
[WARN] gate; clear it yourself with: systemctl disable --now dnsmasq
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] golden vzdump left in place (pass --remove-golden to remove)
|
||||
|
||||
[STEP] kept vs wiped — read before pulling drives or closing the customer out
|
||||
WIPED (this run):
|
||||
- guest 120 (container + its OS/Docker/user-data volumes)
|
||||
- the felhom-agent: binary, unit, sudoers, config (+ its .bak backups), state dir, service user
|
||||
- self-update artifacts: guarded wrapper, A/B slots (.prev/.new.*), rollback unit, start-limit drop-in
|
||||
- break-glass watchdog + OOB artifacts (where present); guest-hook snippet; dnsmasq snippets; the mkfs + pbs-apply wrappers
|
||||
- pveum: the Felhom roles/user/token/scoped ACL; the emptied felhom pool
|
||||
- the install state file
|
||||
KEPT (lives on deliberately — remove/rotate these out-of-band if the customer is leaving):
|
||||
- the enrolled drives + ALL data under /mnt/felhom-drives — unmounted only, NEVER wiped;
|
||||
the drives are physically removable now.
|
||||
- the hub host/customer record + report history (operator UI / DB)
|
||||
- the escrow blob in the hub, if one exists (operator UI)
|
||||
- the hub-vaulted root@pam recovery credential — the box KEEPS the password step 4b set; rotate it if the box leaves Felhom management
|
||||
|
||||
[OK] UNINSTALL complete — removed: guest 120, the felhom-agent (unit/sudoers/binary/state/config+baks/user + selfupdate-artifacts/shared-parent/mkfs-wrapper/pbs-apply-wrapper/hook-snippet/dnsmasq-snippets), the pveum role/user/token/ACL, the felhom pool, and /var/lib/felhom-install/state.json.
|
||||
[INFO] golden vzdump: left in place (--remove-golden to remove).
|
||||
[INFO] NOTE: the 'sudo' package was left INSTALLED (a system package, never ours to remove). dnsmasq is removed only when the install-time record says Felhom installed it; a resolver that pre-dated Felhom is never touched. The host record still exists in the hub — remove it there if desired.
|
||||
@@ -0,0 +1,81 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=appliance customer=drill-r50 vmid=120
|
||||
|
||||
[STEP] 1/8 pre-flight
|
||||
[INFO] pve-manager/9.2.2/b9984c6d90a4bd80 (running kernel: 7.0.2-6-pve)
|
||||
[INFO] node: drill-pve (auto)
|
||||
[INFO] agent config: /etc/felhom-agent/agent.json
|
||||
[INFO] agent: not installed yet — will be fetched + installed in step 5/8
|
||||
[INFO] local-lvm free: ~75 GiB
|
||||
[WARN] local-lvm free ~75 GiB < hard min 120 GiB
|
||||
[INFO] free RAM: ~6356 MiB
|
||||
[INFO] existing guests on this host: 0 (pct+qm)
|
||||
[INFO] acl storage 'felhom-pbs' not present yet — expected: the PBS-DR tier creates it; the grant is pre-positioned deliberately
|
||||
[INFO] dnsmasq: not present before Felhom — recorded; uninstall will remove it again if we install it
|
||||
[INFO] hub reachable (https://hub.felhom.eu)
|
||||
[OK] customer 'drill-r50' exists + passphrase valid
|
||||
[INFO] golden: none local — will fetch + verify from Gitea in step 7/8
|
||||
[INFO] --skip-provision: agent install/config only, no guest will be provisioned
|
||||
[OK] pre-flight passed
|
||||
[STEP] 2/8 Proxmox API token
|
||||
[OK] token minted (secret captured, not logged)
|
||||
[OK] scoped ACL applied (Base@/, Guest@/pool/felhom + /vms/990000..990009, Store@[local local-lvm felhom-pbs])
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
[STEP] 3/8 compute volume grows
|
||||
[INFO] auto-computed from ~75 GiB free (ONE volume since R-165)
|
||||
[INFO] grows: rootfs +0G (->32G), data +46G (->70G, ONE volume)
|
||||
[STEP] 4/8 host enrollment (POST /host-enroll)
|
||||
[OK] host REUSED (idempotent — existing credential)
|
||||
[INFO] host_id: drill-r50-0a4f9a (api_key captured, not logged)
|
||||
[STEP] 4b/8 break-glass credential (root@pam console password → hub vault)
|
||||
[OK] root@pam password set + vaulted to the hub (retrieve via the operator /admin path; never logged here)
|
||||
[WARN] NOTE: the root@pam password just CHANGED — the old one now fails at the PVE web GUI (:8006).
|
||||
[WARN] Retrieve the new one at hub → host page (vaulted recovery credential).
|
||||
[STEP] 5/8 agent install (fetch + verify + install)
|
||||
[INFO] disabled pve-enterprise.sources (Enabled: no)
|
||||
[INFO] disabled ceph.sources (Enabled: no)
|
||||
[INFO] added pve-no-subscription.sources (suite=trixie)
|
||||
[OK] apt repos aligned to no-subscription (changed; apt-get update OK)
|
||||
[WARN] no git credential in controller.yaml — fetching artifacts ANONYMOUSLY (they are world-readable; sha256 verification unchanged)
|
||||
[INFO] manifest: agent v0.129.0 (sha 53a54f0620afbd6d…), golden v0.214.0
|
||||
[INFO] fetching agent binary v0.129.0 from Gitea …
|
||||
[OK] verified sha256 53a54f0620afbd6d… matches the hub manifest
|
||||
[OK] installed /usr/local/bin/felhom-agent (felhom-agent 0.129.0)
|
||||
[INFO] installing the 'sudo' package (required for the non-root agent model) …
|
||||
[OK] sudo installed (Sudo version 1.9.16p2)
|
||||
[INFO] installing the 'age' package (escrow ceremony identity-wrap dependency) …
|
||||
[OK] age installed (1.2.1)
|
||||
[OK] created service user felhom-agent
|
||||
[OK] added felhom-agent to systemd-journal (unprivileged journal read for NAS verify)
|
||||
[OK] installed /usr/local/sbin/felhom-mkfs-guarded (0755, the guarded mkfs path)
|
||||
[OK] installed /usr/local/sbin/felhom-selfupdate-guarded (0755, the guarded A/B binary-swap path)
|
||||
[OK] installed /usr/local/sbin/felhom-pbs-apply (0755, the guarded PBS-DR apply path)
|
||||
[OK] installed /usr/local/sbin/felhom-backup-target-apply (0755, the guarded backup-target path)
|
||||
[OK] installed /etc/sudoers.d/felhom-agent (0440, visudo-validated)
|
||||
[OK] installed /etc/systemd/system/felhom-agent.service + enabled (started in step 6 after config)
|
||||
[OK] installed self-update rollback unit + start-limit drop-in (auto-rollback armed)
|
||||
[OK] installed break-glass layers 1+2 (tmpfiles /run/sshd + agent-independent watchdog timer)
|
||||
[OK] installed OOB felhom-sshd instance + static belt (agent renders config + fills sets once oob.enabled)
|
||||
[STEP] 6/8 agent config + service
|
||||
[WARN] backup target: DEGRADED — no eligible second drive, so the whole-system backup stays on the SYSTEM drive.
|
||||
[WARN] It protects against file corruption but NOT against a disk failure. Attach a second drive and assign it in the dashboard.
|
||||
[INFO] creating island bridge vmbr9 (portless, 169.254.253.1/30)
|
||||
[OK] vmbr9 up: 169.254.253.1/30
|
||||
[INFO] R-50 island ON: local_api=169.254.253.1:8443 (vmbr9); guest net1=169.254.253.2/30; lan_resolver.host_ip=10.0.2.15
|
||||
[INFO] node=drill-pve local_api=169.254.253.1:8443 tls_fp=C9:1F:AC:10:AE:62…
|
||||
[OK] wrote /etc/felhom-agent/agent.json (0600 felhom-agent)
|
||||
[OK] agent --selftest (read-only) passed
|
||||
[OK] felhom-agent service active (non-root felhom-agent reads the config OK)
|
||||
[STEP] 7/8 golden archive
|
||||
[WARN] no git credential in controller.yaml — fetching artifacts ANONYMOUSLY (they are world-readable; sha256 verification unchanged)
|
||||
[INFO] fetching golden v0.214.0 from Gitea → /var/lib/vz/dump/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[OK] verified sha256 3a40379cb00d98c6… matches the hub manifest
|
||||
[OK] golden imported + verified: local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[SKIP] provision (--skip-provision) — agent install/config verified only
|
||||
[STEP] verify (agent only)
|
||||
[INFO] binary: felhom-agent 0.129.0
|
||||
[INFO] runs as: felhom-agent (want felhom-agent)
|
||||
[OK] service active
|
||||
[OK] --selftest=hub OK (a host-report reached the hub)
|
||||
|
||||
[OK] Agent install SUCCESS — felhom-agent 0.129.0 as felhom-agent, host_id=drill-r50-0a4f9a customer=drill-r50
|
||||
@@ -0,0 +1,829 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=uninstall
|
||||
|
||||
[STEP] UNINSTALL — local host teardown
|
||||
[SKIP] guest 120 already absent — skipping guest teardown
|
||||
[STEP] host-level removal
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-agent.service'.
|
||||
Removed '/etc/systemd/system/timers.target.wants/felhom-mgmt-watchdog.timer'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-sshd.service'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-oob-nft.service'.
|
||||
The unit files have no installation config (WantedBy=, RequiredBy=, UpheldBy=,
|
||||
Also=, or Alias= settings in the [Install] section, and DefaultInstance= for
|
||||
template units). This means they are not meant to be enabled or disabled using systemctl.
|
||||
|
||||
Possible reasons for having these kinds of units are:
|
||||
• A unit may be statically enabled by being symlinked from another unit's
|
||||
.wants/, .requires/, or .upholds/ directory.
|
||||
• A unit's purpose may be to act as a helper for some other unit which has
|
||||
a requirement dependency on it.
|
||||
• A unit may be started when needed via activation (socket, path, timer,
|
||||
D-Bus, udev, scripted systemctl call, ...).
|
||||
• In case of template units, the unit is meant to be enabled with some
|
||||
instance name specified.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-shared-parent.service'.
|
||||
Removed '/etc/systemd/system/pve-guests.service.wants/felhom-shared-parent.service'.
|
||||
[INFO] dnsmasq was installed by Felhom (recorded at install) — stopping + disabling it
|
||||
Synchronizing state of dnsmasq.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
|
||||
Executing: /usr/lib/systemd/systemd-sysv-install disable dnsmasq
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/dnsmasq.service'.
|
||||
[INFO] dnsmasq: removing the package(s) Felhom installed: dnsmasq dnsmasq-base
|
||||
Reading package lists...
|
||||
Building dependency tree...
|
||||
Reading state information...
|
||||
The following packages will be REMOVED:
|
||||
dnsmasq* dnsmasq-base*
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
locale: Cannot set LC_CTYPE to default locale: No such file or directory
|
||||
locale: Cannot set LC_ALL to default locale: No such file or directory
|
||||
0 upgraded, 0 newly installed, 2 to remove and 115 not upgraded.
|
||||
After this operation, 1303 kB disk space will be freed.
|
||||
(Reading database ...
(Reading database ... 5%
(Reading database ... 10%
(Reading database ... 15%
(Reading database ... 20%
(Reading database ... 25%
(Reading database ... 30%
(Reading database ... 35%
(Reading database ... 40%
(Reading database ... 45%
(Reading database ... 50%
(Reading database ... 55%
(Reading database ... 60%
(Reading database ... 65%
(Reading database ... 70%
(Reading database ... 75%
(Reading database ... 80%
(Reading database ... 85%
(Reading database ... 90%
(Reading database ... 95%
(Reading database ... 100%
(Reading database ... 52716 files and directories currently installed.)
|
||||
Removing dnsmasq (2.91-1+deb13u1) ...
|
||||
Removing dnsmasq-base (2.91-1+deb13u1) ...
|
||||
Processing triggers for dbus (1.16.2-2) ...
|
||||
Processing triggers for man-db (2.13.1-1) ...
|
||||
(Reading database ...
(Reading database ... 5%
(Reading database ... 10%
(Reading database ... 15%
(Reading database ... 20%
(Reading database ... 25%
(Reading database ... 30%
(Reading database ... 35%
(Reading database ... 40%
(Reading database ... 45%
(Reading database ... 50%
(Reading database ... 55%
(Reading database ... 60%
(Reading database ... 65%
(Reading database ... 70%
(Reading database ... 75%
(Reading database ... 80%
(Reading database ... 85%
(Reading database ... 90%
(Reading database ... 95%
(Reading database ... 100%
(Reading database ... 52664 files and directories currently installed.)
|
||||
Purging configuration files for dnsmasq-base (2.91-1+deb13u1) ...
|
||||
Purging configuration files for dnsmasq (2.91-1+deb13u1) ...
|
||||
[OK] dnsmasq removed — the next install starts from a clean slate, as a first install
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] golden vzdump left in place (pass --remove-golden to remove)
|
||||
|
||||
[STEP] kept vs wiped — read before pulling drives or closing the customer out
|
||||
WIPED (this run):
|
||||
- guest 120 (container + its OS/Docker/user-data volumes)
|
||||
- the felhom-agent: binary, unit, sudoers, config (+ its .bak backups), state dir, service user
|
||||
- self-update artifacts: guarded wrapper, A/B slots (.prev/.new.*), rollback unit, start-limit drop-in
|
||||
- break-glass watchdog + OOB artifacts (where present); guest-hook snippet; dnsmasq snippets; the mkfs + pbs-apply wrappers
|
||||
- pveum: the Felhom roles/user/token/scoped ACL; the emptied felhom pool
|
||||
- the install state file
|
||||
KEPT (lives on deliberately — remove/rotate these out-of-band if the customer is leaving):
|
||||
- the enrolled drives + ALL data under /mnt/felhom-drives — unmounted only, NEVER wiped;
|
||||
the drives are physically removable now.
|
||||
- the hub host/customer record + report history (operator UI / DB)
|
||||
- the escrow blob in the hub, if one exists (operator UI)
|
||||
- the hub-vaulted root@pam recovery credential — the box KEEPS the password step 4b set; rotate it if the box leaves Felhom management
|
||||
|
||||
[OK] UNINSTALL complete — removed: guest 120, the felhom-agent (unit/sudoers/binary/state/config+baks/user + selfupdate-artifacts/shared-parent/mkfs-wrapper/pbs-apply-wrapper/hook-snippet/dnsmasq-snippets), the pveum role/user/token/ACL, the felhom pool, and /var/lib/felhom-install/state.json.
|
||||
[INFO] golden vzdump: left in place (--remove-golden to remove).
|
||||
[INFO] NOTE: the 'sudo' package was left INSTALLED (a system package, never ours to remove). dnsmasq is removed only when the install-time record says Felhom installed it; a resolver that pre-dated Felhom is never touched. The host record still exists in the hub — remove it there if desired.
|
||||
@@ -0,0 +1,71 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=appliance customer=drill-r50 vmid=120
|
||||
|
||||
[STEP] 1/8 pre-flight
|
||||
[INFO] pve-manager/9.2.2/b9984c6d90a4bd80 (running kernel: 7.0.2-6-pve)
|
||||
[INFO] node: drill-pve (auto)
|
||||
[INFO] agent config: /etc/felhom-agent/agent.json
|
||||
[INFO] agent: not installed yet — will be fetched + installed in step 5/8
|
||||
[INFO] local-lvm free: ~75 GiB
|
||||
[WARN] local-lvm free ~75 GiB < hard min 120 GiB
|
||||
[INFO] free RAM: ~6220 MiB
|
||||
[INFO] existing guests on this host: 0 (pct+qm)
|
||||
[INFO] acl storage 'felhom-pbs' not present yet — expected: the PBS-DR tier creates it; the grant is pre-positioned deliberately
|
||||
[INFO] dnsmasq: not present before Felhom — recorded; uninstall will remove it again if we install it
|
||||
[INFO] hub reachable (https://hub.felhom.eu)
|
||||
[OK] customer 'drill-r50' exists + passphrase valid
|
||||
[INFO] golden (local): local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[INFO] --skip-provision: agent install/config only, no guest will be provisioned
|
||||
[OK] pre-flight passed
|
||||
[STEP] 2/8 Proxmox API token
|
||||
[OK] token minted (secret captured, not logged)
|
||||
[OK] scoped ACL applied (Base@/, Guest@/pool/felhom + /vms/990000..990009, Store@[local local-lvm felhom-pbs])
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
[STEP] 3/8 compute volume grows
|
||||
[INFO] auto-computed from ~75 GiB free (ONE volume since R-165)
|
||||
[INFO] grows: rootfs +0G (->32G), data +46G (->70G, ONE volume)
|
||||
[STEP] 4/8 host enrollment (POST /host-enroll)
|
||||
[OK] host REUSED (idempotent — existing credential)
|
||||
[INFO] host_id: drill-r50-0a4f9a (api_key captured, not logged)
|
||||
[STEP] 4b/8 break-glass credential (root@pam console password → hub vault)
|
||||
[OK] root@pam password set + vaulted to the hub (retrieve via the operator /admin path; never logged here)
|
||||
[WARN] NOTE: the root@pam password just CHANGED — the old one now fails at the PVE web GUI (:8006).
|
||||
[WARN] Retrieve the new one at hub → host page (vaulted recovery credential).
|
||||
[STEP] 5/8 agent install (fetch + verify + install)
|
||||
[OK] apt repos aligned to no-subscription (already aligned; apt-get update OK)
|
||||
[WARN] no git credential in controller.yaml — fetching artifacts ANONYMOUSLY (they are world-readable; sha256 verification unchanged)
|
||||
[INFO] manifest: agent v0.129.0 (sha 53a54f0620afbd6d…), golden v0.214.0
|
||||
[INFO] fetching agent binary v0.129.0 from Gitea …
|
||||
[OK] verified sha256 53a54f0620afbd6d… matches the hub manifest
|
||||
[OK] installed /usr/local/bin/felhom-agent (felhom-agent 0.129.0)
|
||||
[OK] created service user felhom-agent
|
||||
[OK] added felhom-agent to systemd-journal (unprivileged journal read for NAS verify)
|
||||
[OK] installed /usr/local/sbin/felhom-mkfs-guarded (0755, the guarded mkfs path)
|
||||
[OK] installed /usr/local/sbin/felhom-selfupdate-guarded (0755, the guarded A/B binary-swap path)
|
||||
[OK] installed /usr/local/sbin/felhom-pbs-apply (0755, the guarded PBS-DR apply path)
|
||||
[OK] installed /usr/local/sbin/felhom-backup-target-apply (0755, the guarded backup-target path)
|
||||
[OK] installed /etc/sudoers.d/felhom-agent (0440, visudo-validated)
|
||||
[OK] installed /etc/systemd/system/felhom-agent.service + enabled (started in step 6 after config)
|
||||
[OK] installed self-update rollback unit + start-limit drop-in (auto-rollback armed)
|
||||
[OK] installed break-glass layers 1+2 (tmpfiles /run/sshd + agent-independent watchdog timer)
|
||||
[OK] installed OOB felhom-sshd instance + static belt (agent renders config + fills sets once oob.enabled)
|
||||
[STEP] 6/8 agent config + service
|
||||
[WARN] backup target: DEGRADED — no eligible second drive, so the whole-system backup stays on the SYSTEM drive.
|
||||
[WARN] It protects against file corruption but NOT against a disk failure. Attach a second drive and assign it in the dashboard.
|
||||
[INFO] island bridge vmbr9 already present — leaving it
|
||||
[INFO] R-50 island ON: local_api=169.254.253.1:8443 (vmbr9); guest net1=169.254.253.2/30; lan_resolver.host_ip=10.0.2.15
|
||||
[INFO] node=drill-pve local_api=169.254.253.1:8443 tls_fp=C9:1F:AC:10:AE:62…
|
||||
[OK] wrote /etc/felhom-agent/agent.json (0600 felhom-agent)
|
||||
[OK] agent --selftest (read-only) passed
|
||||
[OK] felhom-agent service active (non-root felhom-agent reads the config OK)
|
||||
[STEP] 7/8 golden archive
|
||||
[INFO] local golden digest matches the manifest (3a40379cb00d98c6…) — this IS the vouched artifact
|
||||
[SKIP] using local golden: local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[SKIP] provision (--skip-provision) — agent install/config verified only
|
||||
[STEP] verify (agent only)
|
||||
[INFO] binary: felhom-agent 0.129.0
|
||||
[INFO] runs as: felhom-agent (want felhom-agent)
|
||||
[OK] service active
|
||||
[OK] --selftest=hub OK (a host-report reached the hub)
|
||||
|
||||
[OK] Agent install SUCCESS — felhom-agent 0.129.0 as felhom-agent, host_id=drill-r50-0a4f9a customer=drill-r50
|
||||
@@ -0,0 +1,829 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=uninstall
|
||||
|
||||
[STEP] UNINSTALL — local host teardown
|
||||
[SKIP] guest 120 already absent — skipping guest teardown
|
||||
[STEP] host-level removal
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-agent.service'.
|
||||
Removed '/etc/systemd/system/timers.target.wants/felhom-mgmt-watchdog.timer'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-sshd.service'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-oob-nft.service'.
|
||||
The unit files have no installation config (WantedBy=, RequiredBy=, UpheldBy=,
|
||||
Also=, or Alias= settings in the [Install] section, and DefaultInstance= for
|
||||
template units). This means they are not meant to be enabled or disabled using systemctl.
|
||||
|
||||
Possible reasons for having these kinds of units are:
|
||||
• A unit may be statically enabled by being symlinked from another unit's
|
||||
.wants/, .requires/, or .upholds/ directory.
|
||||
• A unit's purpose may be to act as a helper for some other unit which has
|
||||
a requirement dependency on it.
|
||||
• A unit may be started when needed via activation (socket, path, timer,
|
||||
D-Bus, udev, scripted systemctl call, ...).
|
||||
• In case of template units, the unit is meant to be enabled with some
|
||||
instance name specified.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-shared-parent.service'.
|
||||
Removed '/etc/systemd/system/pve-guests.service.wants/felhom-shared-parent.service'.
|
||||
[INFO] dnsmasq was installed by Felhom (recorded at install) — stopping + disabling it
|
||||
Synchronizing state of dnsmasq.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
|
||||
Executing: /usr/lib/systemd/systemd-sysv-install disable dnsmasq
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/dnsmasq.service'.
|
||||
[INFO] dnsmasq: removing the package(s) Felhom installed: dnsmasq dnsmasq-base
|
||||
Reading package lists...
|
||||
Building dependency tree...
|
||||
Reading state information...
|
||||
The following packages will be REMOVED:
|
||||
dnsmasq* dnsmasq-base*
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
locale: Cannot set LC_CTYPE to default locale: No such file or directory
|
||||
locale: Cannot set LC_ALL to default locale: No such file or directory
|
||||
0 upgraded, 0 newly installed, 2 to remove and 115 not upgraded.
|
||||
After this operation, 1303 kB disk space will be freed.
|
||||
(Reading database ...
(Reading database ... 5%
(Reading database ... 10%
(Reading database ... 15%
(Reading database ... 20%
(Reading database ... 25%
(Reading database ... 30%
(Reading database ... 35%
(Reading database ... 40%
(Reading database ... 45%
(Reading database ... 50%
(Reading database ... 55%
(Reading database ... 60%
(Reading database ... 65%
(Reading database ... 70%
(Reading database ... 75%
(Reading database ... 80%
(Reading database ... 85%
(Reading database ... 90%
(Reading database ... 95%
(Reading database ... 100%
(Reading database ... 52716 files and directories currently installed.)
|
||||
Removing dnsmasq (2.91-1+deb13u1) ...
|
||||
Removing dnsmasq-base (2.91-1+deb13u1) ...
|
||||
Processing triggers for dbus (1.16.2-2) ...
|
||||
Processing triggers for man-db (2.13.1-1) ...
|
||||
(Reading database ...
(Reading database ... 5%
(Reading database ... 10%
(Reading database ... 15%
(Reading database ... 20%
(Reading database ... 25%
(Reading database ... 30%
(Reading database ... 35%
(Reading database ... 40%
(Reading database ... 45%
(Reading database ... 50%
(Reading database ... 55%
(Reading database ... 60%
(Reading database ... 65%
(Reading database ... 70%
(Reading database ... 75%
(Reading database ... 80%
(Reading database ... 85%
(Reading database ... 90%
(Reading database ... 95%
(Reading database ... 100%
(Reading database ... 52664 files and directories currently installed.)
|
||||
Purging configuration files for dnsmasq-base (2.91-1+deb13u1) ...
|
||||
Purging configuration files for dnsmasq (2.91-1+deb13u1) ...
|
||||
[OK] dnsmasq removed — the next install starts from a clean slate, as a first install
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] golden vzdump left in place (pass --remove-golden to remove)
|
||||
|
||||
[STEP] kept vs wiped — read before pulling drives or closing the customer out
|
||||
WIPED (this run):
|
||||
- guest 120 (container + its OS/Docker/user-data volumes)
|
||||
- the felhom-agent: binary, unit, sudoers, config (+ its .bak backups), state dir, service user
|
||||
- self-update artifacts: guarded wrapper, A/B slots (.prev/.new.*), rollback unit, start-limit drop-in
|
||||
- break-glass watchdog + OOB artifacts (where present); guest-hook snippet; dnsmasq snippets; the mkfs + pbs-apply wrappers
|
||||
- pveum: the Felhom roles/user/token/scoped ACL; the emptied felhom pool
|
||||
- the install state file
|
||||
KEPT (lives on deliberately — remove/rotate these out-of-band if the customer is leaving):
|
||||
- the enrolled drives + ALL data under /mnt/felhom-drives — unmounted only, NEVER wiped;
|
||||
the drives are physically removable now.
|
||||
- the hub host/customer record + report history (operator UI / DB)
|
||||
- the escrow blob in the hub, if one exists (operator UI)
|
||||
- the hub-vaulted root@pam recovery credential — the box KEEPS the password step 4b set; rotate it if the box leaves Felhom management
|
||||
|
||||
[OK] UNINSTALL complete — removed: guest 120, the felhom-agent (unit/sudoers/binary/state/config+baks/user + selfupdate-artifacts/shared-parent/mkfs-wrapper/pbs-apply-wrapper/hook-snippet/dnsmasq-snippets), the pveum role/user/token/ACL, the felhom pool, and /var/lib/felhom-install/state.json.
|
||||
[INFO] golden vzdump: left in place (--remove-golden to remove).
|
||||
[INFO] NOTE: the 'sudo' package was left INSTALLED (a system package, never ours to remove). dnsmasq is removed only when the install-time record says Felhom installed it; a resolver that pre-dated Felhom is never touched. The host record still exists in the hub — remove it there if desired.
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=byo customer=drill-r50 vmid=120
|
||||
|
||||
[STEP] 1/8 pre-flight
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[INFO] pve-manager/9.2.2/b9984c6d90a4bd80 (running kernel: 7.0.2-6-pve)
|
||||
[INFO] node: drill-pve (auto)
|
||||
[INFO] agent config: /etc/felhom-agent/agent.json
|
||||
[INFO] agent: not installed yet — will be fetched + installed in step 5/8
|
||||
[INFO] local-lvm free: ~75 GiB
|
||||
[WARN] local-lvm free ~75 GiB < hard min 120 GiB
|
||||
[INFO] free RAM: ~6245 MiB
|
||||
[INFO] existing guests on this host: 0 (pct+qm)
|
||||
[INFO] archive storage 'local' present
|
||||
[INFO] acl storage 'felhom-pbs' not present yet — expected: the PBS-DR tier creates it; the grant is pre-positioned deliberately
|
||||
[INFO] acl storages all present or pre-positioned: local local-lvm felhom-pbs
|
||||
[INFO] dnsmasq: not present before Felhom — recorded; uninstall will remove it again if we install it
|
||||
[INFO] host DNS (:53): free
|
||||
[INFO] hub reachable (https://hub.felhom.eu)
|
||||
[OK] customer 'drill-r50' exists + passphrase valid
|
||||
[INFO] golden (local): local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
|
||||
[STEP] BYO disclosure — installing Felhom on a host the operator does NOT own will create:
|
||||
pveum: roles FelhomAgentBase/FelhomAgentGuest/FelhomAgentStore + user felhom-agent@pve + token felhom-agent@pve!agent
|
||||
+ scoped ACL grants (Base@/, Guest@/pool/felhom, Store@[local local-lvm felhom-pbs]) + the 'felhom' pool
|
||||
agent: service user felhom-agent + /usr/local/bin/felhom-agent (+ .bak-* backups; A/B slots via the guarded self-update)
|
||||
+ /etc/systemd/system/felhom-agent.service (+ felhom-agent-rollback.service + start-limit drop-in)
|
||||
+ /etc/sudoers.d/felhom-agent + state dir /var/lib/felhom-agent + config /etc/felhom-agent/agent.json (0600)
|
||||
host: /usr/local/sbin/felhom-mkfs-guarded + /usr/local/sbin/felhom-selfupdate-guarded
|
||||
+ /usr/local/sbin/felhom-pbs-apply (PBS-DR apply wrapper — DR capability is baked
|
||||
on every install; ACTIVATION stays a hub flag, off = zero effect on this host)
|
||||
+ felhom-mgmt-watchdog service+timer+script + /etc/tmpfiles.d/felhom-privsep.conf
|
||||
+ guest-hook snippet under /var/lib/vz/snippets/ (agent-installed at runtime)
|
||||
+ the 'sudo' and 'age' packages if absent + install state dir /var/lib/felhom-install
|
||||
wg: an OUTBOUND WireGuard tunnel to the Felhom hub (wg_tunnel.enabled=true — base
|
||||
infrastructure like the cloudflared tunnel; hands-free peer registration; the
|
||||
operator can disable it per-customer hub-side on request)
|
||||
guest: the provisioned Felhom LXC (vmid 120, capped 2 cores / 4096 MiB) + its volumes
|
||||
+ the golden vzdump imported onto storage 'local'
|
||||
update: operator-signed self-update authority: felhom-op-1
|
||||
NOT touched in byo mode: root@pam (no break-glass), host DNS (:53), OOB sshd.
|
||||
|
||||
[INFO] (--preflight-only: acknowledgement prompt skipped — nothing will be mutated)
|
||||
[OK] pre-flight passed
|
||||
|
||||
[OK] PRE-FLIGHT PASS (mode=byo) — no state written, no install step executed
|
||||
@@ -0,0 +1,774 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=appliance customer=drill-r50 vmid=120
|
||||
|
||||
[STEP] 1/8 pre-flight
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[INFO] pve-manager/9.2.2/b9984c6d90a4bd80 (running kernel: 7.0.2-6-pve)
|
||||
[INFO] node: drill-pve (auto)
|
||||
[INFO] agent config: /etc/felhom-agent/agent.json
|
||||
[INFO] agent: not installed yet — will be fetched + installed in step 5/8
|
||||
[INFO] local-lvm free: ~75 GiB
|
||||
[WARN] local-lvm free ~75 GiB < hard min 120 GiB
|
||||
[INFO] free RAM: ~6245 MiB
|
||||
[INFO] existing guests on this host: 0 (pct+qm)
|
||||
[INFO] acl storage 'felhom-pbs' not present yet — expected: the PBS-DR tier creates it; the grant is pre-positioned deliberately
|
||||
[INFO] dnsmasq: not present before Felhom — recorded; uninstall will remove it again if we install it
|
||||
[INFO] hub reachable (https://hub.felhom.eu)
|
||||
[OK] customer 'drill-r50' exists + passphrase valid
|
||||
[INFO] golden (local): local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[INFO] --skip-provision: agent install/config only, no guest will be provisioned
|
||||
[OK] pre-flight passed
|
||||
[STEP] 2/8 Proxmox API token
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[OK] token minted (secret captured, not logged)
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[OK] scoped ACL applied (Base@/, Guest@/pool/felhom + /vms/990000..990009, Store@[local local-lvm felhom-pbs])
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
[STEP] 3/8 compute volume grows
|
||||
[INFO] auto-computed from ~75 GiB free (ONE volume since R-165)
|
||||
[INFO] grows: rootfs +0G (->32G), data +46G (->70G, ONE volume)
|
||||
[STEP] 4/8 host enrollment (POST /host-enroll)
|
||||
[OK] host REUSED (idempotent — existing credential)
|
||||
[INFO] host_id: drill-r50-0a4f9a (api_key captured, not logged)
|
||||
[STEP] 4b/8 break-glass credential (root@pam console password → hub vault)
|
||||
[OK] root@pam password set + vaulted to the hub (retrieve via the operator /admin path; never logged here)
|
||||
[WARN] NOTE: the root@pam password just CHANGED — the old one now fails at the PVE web GUI (:8006).
|
||||
[WARN] Retrieve the new one at hub → host page (vaulted recovery credential).
|
||||
[STEP] 5/8 agent install (fetch + verify + install)
|
||||
[OK] apt repos aligned to no-subscription (already aligned; apt-get update OK)
|
||||
[WARN] no git credential in controller.yaml — fetching artifacts ANONYMOUSLY (they are world-readable; sha256 verification unchanged)
|
||||
[INFO] manifest: agent v0.129.0 (sha 53a54f0620afbd6d…), golden v0.214.0
|
||||
[INFO] fetching agent binary v0.129.0 from Gitea …
|
||||
[OK] verified sha256 53a54f0620afbd6d… matches the hub manifest
|
||||
[OK] installed /usr/local/bin/felhom-agent (felhom-agent 0.129.0)
|
||||
[OK] created service user felhom-agent
|
||||
[OK] added felhom-agent to systemd-journal (unprivileged journal read for NAS verify)
|
||||
[OK] installed /usr/local/sbin/felhom-mkfs-guarded (0755, the guarded mkfs path)
|
||||
[OK] installed /usr/local/sbin/felhom-selfupdate-guarded (0755, the guarded A/B binary-swap path)
|
||||
[OK] installed /usr/local/sbin/felhom-pbs-apply (0755, the guarded PBS-DR apply path)
|
||||
[OK] installed /usr/local/sbin/felhom-backup-target-apply (0755, the guarded backup-target path)
|
||||
[OK] installed /etc/sudoers.d/felhom-agent (0440, visudo-validated)
|
||||
[OK] installed /etc/systemd/system/felhom-agent.service + enabled (started in step 6 after config)
|
||||
[OK] installed self-update rollback unit + start-limit drop-in (auto-rollback armed)
|
||||
[OK] installed break-glass layers 1+2 (tmpfiles /run/sshd + agent-independent watchdog timer)
|
||||
[OK] installed OOB felhom-sshd instance + static belt (agent renders config + fills sets once oob.enabled)
|
||||
[STEP] 6/8 agent config + service
|
||||
[WARN] backup target: DEGRADED — no eligible second drive, so the whole-system backup stays on the SYSTEM drive.
|
||||
[WARN] It protects against file corruption but NOT against a disk failure. Attach a second drive and assign it in the dashboard.
|
||||
[INFO] island bridge vmbr9 already present — leaving it
|
||||
[INFO] R-50 island ON: local_api=169.254.253.1:8443 (vmbr9); guest net1=169.254.253.2/30; lan_resolver.host_ip=10.0.2.15
|
||||
[INFO] node=drill-pve local_api=169.254.253.1:8443 tls_fp=C9:1F:AC:10:AE:62…
|
||||
[OK] wrote /etc/felhom-agent/agent.json (0600 felhom-agent)
|
||||
[OK] agent --selftest (read-only) passed
|
||||
[OK] felhom-agent service active (non-root felhom-agent reads the config OK)
|
||||
[STEP] 7/8 golden archive
|
||||
[INFO] local golden digest matches the manifest (3a40379cb00d98c6…) — this IS the vouched artifact
|
||||
[SKIP] using local golden: local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[SKIP] provision (--skip-provision) — agent install/config verified only
|
||||
[STEP] verify (agent only)
|
||||
[INFO] binary: felhom-agent 0.129.0
|
||||
[INFO] runs as: felhom-agent (want felhom-agent)
|
||||
[OK] service active
|
||||
[OK] --selftest=hub OK (a host-report reached the hub)
|
||||
|
||||
[OK] Agent install SUCCESS — felhom-agent 0.129.0 as felhom-agent, host_id=drill-r50-0a4f9a customer=drill-r50
|
||||
@@ -0,0 +1,772 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=uninstall
|
||||
|
||||
[STEP] UNINSTALL — local host teardown
|
||||
[SKIP] guest 120 already absent — skipping guest teardown
|
||||
[STEP] host-level removal
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-agent.service'.
|
||||
Removed '/etc/systemd/system/timers.target.wants/felhom-mgmt-watchdog.timer'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-sshd.service'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-oob-nft.service'.
|
||||
The unit files have no installation config (WantedBy=, RequiredBy=, UpheldBy=,
|
||||
Also=, or Alias= settings in the [Install] section, and DefaultInstance= for
|
||||
template units). This means they are not meant to be enabled or disabled using systemctl.
|
||||
|
||||
Possible reasons for having these kinds of units are:
|
||||
• A unit may be statically enabled by being symlinked from another unit's
|
||||
.wants/, .requires/, or .upholds/ directory.
|
||||
• A unit's purpose may be to act as a helper for some other unit which has
|
||||
a requirement dependency on it.
|
||||
• A unit may be started when needed via activation (socket, path, timer,
|
||||
D-Bus, udev, scripted systemctl call, ...).
|
||||
• In case of template units, the unit is meant to be enabled with some
|
||||
instance name specified.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-shared-parent.service'.
|
||||
Removed '/etc/systemd/system/pve-guests.service.wants/felhom-shared-parent.service'.
|
||||
[INFO] dnsmasq was installed by Felhom (recorded at install) — stopping + disabling it
|
||||
Synchronizing state of dnsmasq.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
|
||||
Executing: /usr/lib/systemd/systemd-sysv-install disable dnsmasq
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/dnsmasq.service'.
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] golden vzdump left in place (pass --remove-golden to remove)
|
||||
|
||||
[STEP] kept vs wiped — read before pulling drives or closing the customer out
|
||||
WIPED (this run):
|
||||
- guest 120 (container + its OS/Docker/user-data volumes)
|
||||
- the felhom-agent: binary, unit, sudoers, config (+ its .bak backups), state dir, service user
|
||||
- self-update artifacts: guarded wrapper, A/B slots (.prev/.new.*), rollback unit, start-limit drop-in
|
||||
- break-glass watchdog + OOB artifacts (where present); guest-hook snippet; dnsmasq snippets; the mkfs + pbs-apply wrappers
|
||||
- pveum: the Felhom roles/user/token/scoped ACL; the emptied felhom pool
|
||||
- the install state file
|
||||
KEPT (lives on deliberately — remove/rotate these out-of-band if the customer is leaving):
|
||||
- the enrolled drives + ALL data under /mnt/felhom-drives — unmounted only, NEVER wiped;
|
||||
the drives are physically removable now.
|
||||
- the hub host/customer record + report history (operator UI / DB)
|
||||
- the escrow blob in the hub, if one exists (operator UI)
|
||||
- the hub-vaulted root@pam recovery credential — the box KEEPS the password step 4b set; rotate it if the box leaves Felhom management
|
||||
|
||||
[OK] UNINSTALL complete — removed: guest 120, the felhom-agent (unit/sudoers/binary/state/config+baks/user + selfupdate-artifacts/shared-parent/mkfs-wrapper/pbs-apply-wrapper/hook-snippet/dnsmasq-snippets), the pveum role/user/token/ACL, the felhom pool, and /var/lib/felhom-install/state.json.
|
||||
[INFO] golden vzdump: left in place (--remove-golden to remove).
|
||||
[INFO] NOTE: the 'sudo' package was left INSTALLED (a system package, never ours to remove). dnsmasq is removed only when the install-time record says Felhom installed it; a resolver that pre-dated Felhom is never touched. The host record still exists in the hub — remove it there if desired.
|
||||
@@ -0,0 +1,775 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=appliance customer=drill-r50 vmid=120
|
||||
|
||||
[STEP] 1/8 pre-flight
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[INFO] pve-manager/9.2.2/b9984c6d90a4bd80 (running kernel: 7.0.2-6-pve)
|
||||
[INFO] node: drill-pve (auto)
|
||||
[INFO] agent config: /etc/felhom-agent/agent.json
|
||||
[INFO] agent: not installed yet — will be fetched + installed in step 5/8
|
||||
[INFO] local-lvm free: ~75 GiB
|
||||
[WARN] local-lvm free ~75 GiB < hard min 120 GiB
|
||||
[INFO] free RAM: ~6246 MiB
|
||||
[INFO] existing guests on this host: 0 (pct+qm)
|
||||
[INFO] acl storage 'felhom-pbs' not present yet — expected: the PBS-DR tier creates it; the grant is pre-positioned deliberately
|
||||
[INFO] dnsmasq: already installed BEFORE Felhom — recorded; uninstall will not touch it
|
||||
[INFO] dnsmasq-base: already installed BEFORE Felhom — recorded; uninstall will leave it
|
||||
[INFO] hub reachable (https://hub.felhom.eu)
|
||||
[OK] customer 'drill-r50' exists + passphrase valid
|
||||
[INFO] golden (local): local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[INFO] --skip-provision: agent install/config only, no guest will be provisioned
|
||||
[OK] pre-flight passed
|
||||
[STEP] 2/8 Proxmox API token
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[OK] token minted (secret captured, not logged)
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[OK] scoped ACL applied (Base@/, Guest@/pool/felhom + /vms/990000..990009, Store@[local local-lvm felhom-pbs])
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
[STEP] 3/8 compute volume grows
|
||||
[INFO] auto-computed from ~75 GiB free (ONE volume since R-165)
|
||||
[INFO] grows: rootfs +0G (->32G), data +46G (->70G, ONE volume)
|
||||
[STEP] 4/8 host enrollment (POST /host-enroll)
|
||||
[OK] host REUSED (idempotent — existing credential)
|
||||
[INFO] host_id: drill-r50-0a4f9a (api_key captured, not logged)
|
||||
[STEP] 4b/8 break-glass credential (root@pam console password → hub vault)
|
||||
[OK] root@pam password set + vaulted to the hub (retrieve via the operator /admin path; never logged here)
|
||||
[WARN] NOTE: the root@pam password just CHANGED — the old one now fails at the PVE web GUI (:8006).
|
||||
[WARN] Retrieve the new one at hub → host page (vaulted recovery credential).
|
||||
[STEP] 5/8 agent install (fetch + verify + install)
|
||||
[OK] apt repos aligned to no-subscription (already aligned; apt-get update OK)
|
||||
[WARN] no git credential in controller.yaml — fetching artifacts ANONYMOUSLY (they are world-readable; sha256 verification unchanged)
|
||||
[INFO] manifest: agent v0.129.0 (sha 53a54f0620afbd6d…), golden v0.214.0
|
||||
[INFO] fetching agent binary v0.129.0 from Gitea …
|
||||
[OK] verified sha256 53a54f0620afbd6d… matches the hub manifest
|
||||
[OK] installed /usr/local/bin/felhom-agent (felhom-agent 0.129.0)
|
||||
[OK] created service user felhom-agent
|
||||
[OK] added felhom-agent to systemd-journal (unprivileged journal read for NAS verify)
|
||||
[OK] installed /usr/local/sbin/felhom-mkfs-guarded (0755, the guarded mkfs path)
|
||||
[OK] installed /usr/local/sbin/felhom-selfupdate-guarded (0755, the guarded A/B binary-swap path)
|
||||
[OK] installed /usr/local/sbin/felhom-pbs-apply (0755, the guarded PBS-DR apply path)
|
||||
[OK] installed /usr/local/sbin/felhom-backup-target-apply (0755, the guarded backup-target path)
|
||||
[OK] installed /etc/sudoers.d/felhom-agent (0440, visudo-validated)
|
||||
[OK] installed /etc/systemd/system/felhom-agent.service + enabled (started in step 6 after config)
|
||||
[OK] installed self-update rollback unit + start-limit drop-in (auto-rollback armed)
|
||||
[OK] installed break-glass layers 1+2 (tmpfiles /run/sshd + agent-independent watchdog timer)
|
||||
[OK] installed OOB felhom-sshd instance + static belt (agent renders config + fills sets once oob.enabled)
|
||||
[STEP] 6/8 agent config + service
|
||||
[WARN] backup target: DEGRADED — no eligible second drive, so the whole-system backup stays on the SYSTEM drive.
|
||||
[WARN] It protects against file corruption but NOT against a disk failure. Attach a second drive and assign it in the dashboard.
|
||||
[INFO] island bridge vmbr9 already present — leaving it
|
||||
[INFO] R-50 island ON: local_api=169.254.253.1:8443 (vmbr9); guest net1=169.254.253.2/30; lan_resolver.host_ip=10.0.2.15
|
||||
[INFO] node=drill-pve local_api=169.254.253.1:8443 tls_fp=C9:1F:AC:10:AE:62…
|
||||
[OK] wrote /etc/felhom-agent/agent.json (0600 felhom-agent)
|
||||
[OK] agent --selftest (read-only) passed
|
||||
[OK] felhom-agent service active (non-root felhom-agent reads the config OK)
|
||||
[STEP] 7/8 golden archive
|
||||
[INFO] local golden digest matches the manifest (3a40379cb00d98c6…) — this IS the vouched artifact
|
||||
[SKIP] using local golden: local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[SKIP] provision (--skip-provision) — agent install/config verified only
|
||||
[STEP] verify (agent only)
|
||||
[INFO] binary: felhom-agent 0.129.0
|
||||
[INFO] runs as: felhom-agent (want felhom-agent)
|
||||
[OK] service active
|
||||
[OK] --selftest=hub OK (a host-report reached the hub)
|
||||
|
||||
[OK] Agent install SUCCESS — felhom-agent 0.129.0 as felhom-agent, host_id=drill-r50-0a4f9a customer=drill-r50
|
||||
@@ -0,0 +1,731 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=uninstall
|
||||
|
||||
[STEP] UNINSTALL — local host teardown
|
||||
[SKIP] guest 120 already absent — skipping guest teardown
|
||||
[STEP] host-level removal
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-agent.service'.
|
||||
Removed '/etc/systemd/system/timers.target.wants/felhom-mgmt-watchdog.timer'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-sshd.service'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-oob-nft.service'.
|
||||
The unit files have no installation config (WantedBy=, RequiredBy=, UpheldBy=,
|
||||
Also=, or Alias= settings in the [Install] section, and DefaultInstance= for
|
||||
template units). This means they are not meant to be enabled or disabled using systemctl.
|
||||
|
||||
Possible reasons for having these kinds of units are:
|
||||
• A unit may be statically enabled by being symlinked from another unit's
|
||||
.wants/, .requires/, or .upholds/ directory.
|
||||
• A unit's purpose may be to act as a helper for some other unit which has
|
||||
a requirement dependency on it.
|
||||
• A unit may be started when needed via activation (socket, path, timer,
|
||||
D-Bus, udev, scripted systemctl call, ...).
|
||||
• In case of template units, the unit is meant to be enabled with some
|
||||
instance name specified.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-shared-parent.service'.
|
||||
Removed '/etc/systemd/system/pve-guests.service.wants/felhom-shared-parent.service'.
|
||||
[INFO] dnsmasq pre-dates Felhom (recorded at install) — leaving it running, restarting only
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] golden vzdump left in place (pass --remove-golden to remove)
|
||||
|
||||
[STEP] kept vs wiped — read before pulling drives or closing the customer out
|
||||
WIPED (this run):
|
||||
- guest 120 (container + its OS/Docker/user-data volumes)
|
||||
- the felhom-agent: binary, unit, sudoers, config (+ its .bak backups), state dir, service user
|
||||
- self-update artifacts: guarded wrapper, A/B slots (.prev/.new.*), rollback unit, start-limit drop-in
|
||||
- break-glass watchdog + OOB artifacts (where present); guest-hook snippet; dnsmasq snippets; the mkfs + pbs-apply wrappers
|
||||
- pveum: the Felhom roles/user/token/scoped ACL; the emptied felhom pool
|
||||
- the install state file
|
||||
KEPT (lives on deliberately — remove/rotate these out-of-band if the customer is leaving):
|
||||
- the enrolled drives + ALL data under /mnt/felhom-drives — unmounted only, NEVER wiped;
|
||||
the drives are physically removable now.
|
||||
- the hub host/customer record + report history (operator UI / DB)
|
||||
- the escrow blob in the hub, if one exists (operator UI)
|
||||
- the hub-vaulted root@pam recovery credential — the box KEEPS the password step 4b set; rotate it if the box leaves Felhom management
|
||||
|
||||
[OK] UNINSTALL complete — removed: guest 120, the felhom-agent (unit/sudoers/binary/state/config+baks/user + selfupdate-artifacts/shared-parent/mkfs-wrapper/pbs-apply-wrapper/hook-snippet/dnsmasq-snippets), the pveum role/user/token/ACL, the felhom pool, and /var/lib/felhom-install/state.json.
|
||||
[INFO] golden vzdump: left in place (--remove-golden to remove).
|
||||
[INFO] NOTE: the 'sudo' package was left INSTALLED (a system package, never ours to remove). dnsmasq is removed only when the install-time record says Felhom installed it; a resolver that pre-dated Felhom is never touched. The host record still exists in the hub — remove it there if desired.
|
||||
@@ -0,0 +1,47 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=byo customer=drill-r50 vmid=120
|
||||
|
||||
[STEP] 1/8 pre-flight
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[INFO] pve-manager/9.2.2/b9984c6d90a4bd80 (running kernel: 7.0.2-6-pve)
|
||||
[INFO] node: drill-pve (auto)
|
||||
[INFO] agent config: /etc/felhom-agent/agent.json
|
||||
[INFO] agent: not installed yet — will be fetched + installed in step 5/8
|
||||
[INFO] local-lvm free: ~75 GiB
|
||||
[WARN] local-lvm free ~75 GiB < hard min 120 GiB
|
||||
[INFO] free RAM: ~6153 MiB
|
||||
[INFO] existing guests on this host: 0 (pct+qm)
|
||||
[INFO] archive storage 'local' present
|
||||
[INFO] acl storage 'felhom-pbs' not present yet — expected: the PBS-DR tier creates it; the grant is pre-positioned deliberately
|
||||
[INFO] acl storages all present or pre-positioned: local local-lvm felhom-pbs
|
||||
[INFO] dnsmasq: already installed BEFORE Felhom — recorded; uninstall will not touch it
|
||||
[INFO] dnsmasq-base: already installed BEFORE Felhom — recorded; uninstall will leave it
|
||||
[ERROR] a resolver is already bound to :53 on this host:
|
||||
udp UNCONN 0 0 0.0.0.0:53 0.0.0.0:* users:(("dnsmasq",pid=23649,fd=4)) udp UNCONN 0 0 [::]:53 [::]:* users:(("dnsmasq",pid=23649,fd=6)) tcp LISTEN 0 32 0.0.0.0:53 0.0.0.0:* users:(("dnsmasq",pid=23649
|
||||
[ERROR] a resolver is already bound to :53 on this host — Felhom needs the guest reachable by name on your LAN.
|
||||
Stop or reconfigure that resolver, OR point your LAN DNS at the guest's address, then re-run.
|
||||
(Felhom does NOT touch DNS services on a host it does not own — this is a refusal, not a change.)
|
||||
THIS LOOKS LIKE OURS. A previous Felhom install leaves the dnsmasq PACKAGE installed and its unit
|
||||
enabled (only our config snippet is removed), and unconstrained it binds 0.0.0.0:53 — which is what
|
||||
this gate is seeing. If this host had no dnsmasq before Felhom, clear it with:
|
||||
systemctl disable --now dnsmasq
|
||||
Then re-run this installer. If dnsmasq is YOURS, leave it and use one of the two routes above.
|
||||
[ERROR] PRE-FLIGHT FAIL (exit 1) — fix the finding above and re-run
|
||||
@@ -0,0 +1,775 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=appliance customer=drill-r50 vmid=120
|
||||
|
||||
[STEP] 1/8 pre-flight
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[INFO] pve-manager/9.2.2/b9984c6d90a4bd80 (running kernel: 7.0.2-6-pve)
|
||||
[INFO] node: drill-pve (auto)
|
||||
[INFO] agent config: /etc/felhom-agent/agent.json
|
||||
[INFO] agent: not installed yet — will be fetched + installed in step 5/8
|
||||
[INFO] local-lvm free: ~75 GiB
|
||||
[WARN] local-lvm free ~75 GiB < hard min 120 GiB
|
||||
[INFO] free RAM: ~6306 MiB
|
||||
[INFO] existing guests on this host: 0 (pct+qm)
|
||||
[INFO] acl storage 'felhom-pbs' not present yet — expected: the PBS-DR tier creates it; the grant is pre-positioned deliberately
|
||||
[INFO] dnsmasq: already installed BEFORE Felhom — recorded; uninstall will not touch it
|
||||
[INFO] dnsmasq-base: already installed BEFORE Felhom — recorded; uninstall will leave it
|
||||
[INFO] hub reachable (https://hub.felhom.eu)
|
||||
[OK] customer 'drill-r50' exists + passphrase valid
|
||||
[INFO] golden (local): local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[INFO] --skip-provision: agent install/config only, no guest will be provisioned
|
||||
[OK] pre-flight passed
|
||||
[STEP] 2/8 Proxmox API token
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[OK] token minted (secret captured, not logged)
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[OK] scoped ACL applied (Base@/, Guest@/pool/felhom + /vms/990000..990009, Store@[local local-lvm felhom-pbs])
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
[STEP] 3/8 compute volume grows
|
||||
[INFO] auto-computed from ~75 GiB free (ONE volume since R-165)
|
||||
[INFO] grows: rootfs +0G (->32G), data +46G (->70G, ONE volume)
|
||||
[STEP] 4/8 host enrollment (POST /host-enroll)
|
||||
[OK] host REUSED (idempotent — existing credential)
|
||||
[INFO] host_id: drill-r50-0a4f9a (api_key captured, not logged)
|
||||
[STEP] 4b/8 break-glass credential (root@pam console password → hub vault)
|
||||
[OK] root@pam password set + vaulted to the hub (retrieve via the operator /admin path; never logged here)
|
||||
[WARN] NOTE: the root@pam password just CHANGED — the old one now fails at the PVE web GUI (:8006).
|
||||
[WARN] Retrieve the new one at hub → host page (vaulted recovery credential).
|
||||
[STEP] 5/8 agent install (fetch + verify + install)
|
||||
[OK] apt repos aligned to no-subscription (already aligned; apt-get update OK)
|
||||
[WARN] no git credential in controller.yaml — fetching artifacts ANONYMOUSLY (they are world-readable; sha256 verification unchanged)
|
||||
[INFO] manifest: agent v0.129.0 (sha 53a54f0620afbd6d…), golden v0.214.0
|
||||
[INFO] fetching agent binary v0.129.0 from Gitea …
|
||||
[OK] verified sha256 53a54f0620afbd6d… matches the hub manifest
|
||||
[OK] installed /usr/local/bin/felhom-agent (felhom-agent 0.129.0)
|
||||
[OK] created service user felhom-agent
|
||||
[OK] added felhom-agent to systemd-journal (unprivileged journal read for NAS verify)
|
||||
[OK] installed /usr/local/sbin/felhom-mkfs-guarded (0755, the guarded mkfs path)
|
||||
[OK] installed /usr/local/sbin/felhom-selfupdate-guarded (0755, the guarded A/B binary-swap path)
|
||||
[OK] installed /usr/local/sbin/felhom-pbs-apply (0755, the guarded PBS-DR apply path)
|
||||
[OK] installed /usr/local/sbin/felhom-backup-target-apply (0755, the guarded backup-target path)
|
||||
[OK] installed /etc/sudoers.d/felhom-agent (0440, visudo-validated)
|
||||
[OK] installed /etc/systemd/system/felhom-agent.service + enabled (started in step 6 after config)
|
||||
[OK] installed self-update rollback unit + start-limit drop-in (auto-rollback armed)
|
||||
[OK] installed break-glass layers 1+2 (tmpfiles /run/sshd + agent-independent watchdog timer)
|
||||
[OK] installed OOB felhom-sshd instance + static belt (agent renders config + fills sets once oob.enabled)
|
||||
[STEP] 6/8 agent config + service
|
||||
[WARN] backup target: DEGRADED — no eligible second drive, so the whole-system backup stays on the SYSTEM drive.
|
||||
[WARN] It protects against file corruption but NOT against a disk failure. Attach a second drive and assign it in the dashboard.
|
||||
[INFO] island bridge vmbr9 already present — leaving it
|
||||
[INFO] R-50 island ON: local_api=169.254.253.1:8443 (vmbr9); guest net1=169.254.253.2/30; lan_resolver.host_ip=10.0.2.15
|
||||
[INFO] node=drill-pve local_api=169.254.253.1:8443 tls_fp=C9:1F:AC:10:AE:62…
|
||||
[OK] wrote /etc/felhom-agent/agent.json (0600 felhom-agent)
|
||||
[OK] agent --selftest (read-only) passed
|
||||
[OK] felhom-agent service active (non-root felhom-agent reads the config OK)
|
||||
[STEP] 7/8 golden archive
|
||||
[INFO] local golden digest matches the manifest (3a40379cb00d98c6…) — this IS the vouched artifact
|
||||
[SKIP] using local golden: local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[SKIP] provision (--skip-provision) — agent install/config verified only
|
||||
[STEP] verify (agent only)
|
||||
[INFO] binary: felhom-agent 0.129.0
|
||||
[INFO] runs as: felhom-agent (want felhom-agent)
|
||||
[OK] service active
|
||||
[OK] --selftest=hub OK (a host-report reached the hub)
|
||||
|
||||
[OK] Agent install SUCCESS — felhom-agent 0.129.0 as felhom-agent, host_id=drill-r50-0a4f9a customer=drill-r50
|
||||
@@ -0,0 +1,740 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=uninstall
|
||||
|
||||
[STEP] UNINSTALL — local host teardown
|
||||
[SKIP] guest 120 already absent — skipping guest teardown
|
||||
[STEP] host-level removal
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-agent.service'.
|
||||
Removed '/etc/systemd/system/timers.target.wants/felhom-mgmt-watchdog.timer'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-sshd.service'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-oob-nft.service'.
|
||||
The unit files have no installation config (WantedBy=, RequiredBy=, UpheldBy=,
|
||||
Also=, or Alias= settings in the [Install] section, and DefaultInstance= for
|
||||
template units). This means they are not meant to be enabled or disabled using systemctl.
|
||||
|
||||
Possible reasons for having these kinds of units are:
|
||||
• A unit may be statically enabled by being symlinked from another unit's
|
||||
.wants/, .requires/, or .upholds/ directory.
|
||||
• A unit's purpose may be to act as a helper for some other unit which has
|
||||
a requirement dependency on it.
|
||||
• A unit may be started when needed via activation (socket, path, timer,
|
||||
D-Bus, udev, scripted systemctl call, ...).
|
||||
• In case of template units, the unit is meant to be enabled with some
|
||||
instance name specified.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-shared-parent.service'.
|
||||
Removed '/etc/systemd/system/pve-guests.service.wants/felhom-shared-parent.service'.
|
||||
[INFO] MUTATED: ownership check removed
|
||||
[INFO] dnsmasq: removing the package(s) Felhom installed: dnsmasq
|
||||
E: dpkg was interrupted, you must manually run 'dpkg --configure -a' to correct the problem.
|
||||
[WARN] dnsmasq: the package removal FAILED. The unit is stopped + disabled, so :53 is free,
|
||||
[WARN] but a reinstall will read the package as pre-existing. Clear it with:
|
||||
[WARN] apt-get -y purge dnsmasq
|
||||
[WARN] NOTE: dnsmasq-base pre-dates Felhom and is deliberately kept. It owns /usr/sbin/dnsmasq,
|
||||
[WARN] which the agent stats to decide whether to install — so on this host the next install
|
||||
[WARN] may skip the install step and fail to enable the unit (R-317).
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] golden vzdump left in place (pass --remove-golden to remove)
|
||||
|
||||
[STEP] kept vs wiped — read before pulling drives or closing the customer out
|
||||
WIPED (this run):
|
||||
- guest 120 (container + its OS/Docker/user-data volumes)
|
||||
- the felhom-agent: binary, unit, sudoers, config (+ its .bak backups), state dir, service user
|
||||
- self-update artifacts: guarded wrapper, A/B slots (.prev/.new.*), rollback unit, start-limit drop-in
|
||||
- break-glass watchdog + OOB artifacts (where present); guest-hook snippet; dnsmasq snippets; the mkfs + pbs-apply wrappers
|
||||
- pveum: the Felhom roles/user/token/scoped ACL; the emptied felhom pool
|
||||
- the install state file
|
||||
KEPT (lives on deliberately — remove/rotate these out-of-band if the customer is leaving):
|
||||
- the enrolled drives + ALL data under /mnt/felhom-drives — unmounted only, NEVER wiped;
|
||||
the drives are physically removable now.
|
||||
- the hub host/customer record + report history (operator UI / DB)
|
||||
- the escrow blob in the hub, if one exists (operator UI)
|
||||
- the hub-vaulted root@pam recovery credential — the box KEEPS the password step 4b set; rotate it if the box leaves Felhom management
|
||||
|
||||
[OK] UNINSTALL complete — removed: guest 120, the felhom-agent (unit/sudoers/binary/state/config+baks/user + selfupdate-artifacts/shared-parent/mkfs-wrapper/pbs-apply-wrapper/hook-snippet/dnsmasq-snippets), the pveum role/user/token/ACL, the felhom pool, and /var/lib/felhom-install/state.json.
|
||||
[INFO] golden vzdump: left in place (--remove-golden to remove).
|
||||
[WARN] NOTE: dnsmasq was NOT removed — apt-get purge failed — dnsmasq left installed (stopped + disabled). Its unit is stopped + disabled, so :53 is free, but the NEXT install will read the package as pre-existing.
|
||||
[INFO] NOTE: the 'sudo' package was left INSTALLED (a system package, never ours to remove). dnsmasq is removed only when the install-time record says Felhom installed it; a resolver that pre-dated Felhom is never touched. The host record still exists in the hub — remove it there if desired.
|
||||
@@ -0,0 +1,775 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=appliance customer=drill-r50 vmid=120
|
||||
|
||||
[STEP] 1/8 pre-flight
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[INFO] pve-manager/9.2.2/b9984c6d90a4bd80 (running kernel: 7.0.2-6-pve)
|
||||
[INFO] node: drill-pve (auto)
|
||||
[INFO] agent config: /etc/felhom-agent/agent.json
|
||||
[INFO] agent: not installed yet — will be fetched + installed in step 5/8
|
||||
[INFO] local-lvm free: ~75 GiB
|
||||
[WARN] local-lvm free ~75 GiB < hard min 120 GiB
|
||||
[INFO] free RAM: ~6214 MiB
|
||||
[INFO] existing guests on this host: 0 (pct+qm)
|
||||
[INFO] acl storage 'felhom-pbs' not present yet — expected: the PBS-DR tier creates it; the grant is pre-positioned deliberately
|
||||
[INFO] dnsmasq: already installed BEFORE Felhom — recorded; uninstall will not touch it
|
||||
[INFO] dnsmasq-base: already installed BEFORE Felhom — recorded; uninstall will leave it
|
||||
[INFO] hub reachable (https://hub.felhom.eu)
|
||||
[OK] customer 'drill-r50' exists + passphrase valid
|
||||
[INFO] golden (local): local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[INFO] --skip-provision: agent install/config only, no guest will be provisioned
|
||||
[OK] pre-flight passed
|
||||
[STEP] 2/8 Proxmox API token
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[OK] token minted (secret captured, not logged)
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[OK] scoped ACL applied (Base@/, Guest@/pool/felhom + /vms/990000..990009, Store@[local local-lvm felhom-pbs])
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
[STEP] 3/8 compute volume grows
|
||||
[INFO] auto-computed from ~75 GiB free (ONE volume since R-165)
|
||||
[INFO] grows: rootfs +0G (->32G), data +46G (->70G, ONE volume)
|
||||
[STEP] 4/8 host enrollment (POST /host-enroll)
|
||||
[OK] host REUSED (idempotent — existing credential)
|
||||
[INFO] host_id: drill-r50-0a4f9a (api_key captured, not logged)
|
||||
[STEP] 4b/8 break-glass credential (root@pam console password → hub vault)
|
||||
[OK] root@pam password set + vaulted to the hub (retrieve via the operator /admin path; never logged here)
|
||||
[WARN] NOTE: the root@pam password just CHANGED — the old one now fails at the PVE web GUI (:8006).
|
||||
[WARN] Retrieve the new one at hub → host page (vaulted recovery credential).
|
||||
[STEP] 5/8 agent install (fetch + verify + install)
|
||||
[OK] apt repos aligned to no-subscription (already aligned; apt-get update OK)
|
||||
[WARN] no git credential in controller.yaml — fetching artifacts ANONYMOUSLY (they are world-readable; sha256 verification unchanged)
|
||||
[INFO] manifest: agent v0.129.0 (sha 53a54f0620afbd6d…), golden v0.214.0
|
||||
[INFO] fetching agent binary v0.129.0 from Gitea …
|
||||
[OK] verified sha256 53a54f0620afbd6d… matches the hub manifest
|
||||
[OK] installed /usr/local/bin/felhom-agent (felhom-agent 0.129.0)
|
||||
[OK] created service user felhom-agent
|
||||
[OK] added felhom-agent to systemd-journal (unprivileged journal read for NAS verify)
|
||||
[OK] installed /usr/local/sbin/felhom-mkfs-guarded (0755, the guarded mkfs path)
|
||||
[OK] installed /usr/local/sbin/felhom-selfupdate-guarded (0755, the guarded A/B binary-swap path)
|
||||
[OK] installed /usr/local/sbin/felhom-pbs-apply (0755, the guarded PBS-DR apply path)
|
||||
[OK] installed /usr/local/sbin/felhom-backup-target-apply (0755, the guarded backup-target path)
|
||||
[OK] installed /etc/sudoers.d/felhom-agent (0440, visudo-validated)
|
||||
[OK] installed /etc/systemd/system/felhom-agent.service + enabled (started in step 6 after config)
|
||||
[OK] installed self-update rollback unit + start-limit drop-in (auto-rollback armed)
|
||||
[OK] installed break-glass layers 1+2 (tmpfiles /run/sshd + agent-independent watchdog timer)
|
||||
[OK] installed OOB felhom-sshd instance + static belt (agent renders config + fills sets once oob.enabled)
|
||||
[STEP] 6/8 agent config + service
|
||||
[WARN] backup target: DEGRADED — no eligible second drive, so the whole-system backup stays on the SYSTEM drive.
|
||||
[WARN] It protects against file corruption but NOT against a disk failure. Attach a second drive and assign it in the dashboard.
|
||||
[INFO] island bridge vmbr9 already present — leaving it
|
||||
[INFO] R-50 island ON: local_api=169.254.253.1:8443 (vmbr9); guest net1=169.254.253.2/30; lan_resolver.host_ip=10.0.2.15
|
||||
[INFO] node=drill-pve local_api=169.254.253.1:8443 tls_fp=C9:1F:AC:10:AE:62…
|
||||
[OK] wrote /etc/felhom-agent/agent.json (0600 felhom-agent)
|
||||
[OK] agent --selftest (read-only) passed
|
||||
[OK] felhom-agent service active (non-root felhom-agent reads the config OK)
|
||||
[STEP] 7/8 golden archive
|
||||
[INFO] local golden digest matches the manifest (3a40379cb00d98c6…) — this IS the vouched artifact
|
||||
[SKIP] using local golden: local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[SKIP] provision (--skip-provision) — agent install/config verified only
|
||||
[STEP] verify (agent only)
|
||||
[INFO] binary: felhom-agent 0.129.0
|
||||
[INFO] runs as: felhom-agent (want felhom-agent)
|
||||
[OK] service active
|
||||
[OK] --selftest=hub OK (a host-report reached the hub)
|
||||
|
||||
[OK] Agent install SUCCESS — felhom-agent 0.129.0 as felhom-agent, host_id=drill-r50-0a4f9a customer=drill-r50
|
||||
@@ -0,0 +1,790 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=uninstall
|
||||
|
||||
[STEP] UNINSTALL — local host teardown
|
||||
[SKIP] guest 120 already absent — skipping guest teardown
|
||||
[STEP] host-level removal
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-agent.service'.
|
||||
Removed '/etc/systemd/system/timers.target.wants/felhom-mgmt-watchdog.timer'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-sshd.service'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-oob-nft.service'.
|
||||
The unit files have no installation config (WantedBy=, RequiredBy=, UpheldBy=,
|
||||
Also=, or Alias= settings in the [Install] section, and DefaultInstance= for
|
||||
template units). This means they are not meant to be enabled or disabled using systemctl.
|
||||
|
||||
Possible reasons for having these kinds of units are:
|
||||
• A unit may be statically enabled by being symlinked from another unit's
|
||||
.wants/, .requires/, or .upholds/ directory.
|
||||
• A unit's purpose may be to act as a helper for some other unit which has
|
||||
a requirement dependency on it.
|
||||
• A unit may be started when needed via activation (socket, path, timer,
|
||||
D-Bus, udev, scripted systemctl call, ...).
|
||||
• In case of template units, the unit is meant to be enabled with some
|
||||
instance name specified.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-shared-parent.service'.
|
||||
Removed '/etc/systemd/system/pve-guests.service.wants/felhom-shared-parent.service'.
|
||||
[INFO] MUTATED: ownership check removed
|
||||
[INFO] dnsmasq: removing the package(s) Felhom installed: dnsmasq
|
||||
Reading package lists...
|
||||
Building dependency tree...
|
||||
Reading state information...
|
||||
The following package was automatically installed and is no longer required:
|
||||
dnsmasq-base
|
||||
Use 'apt autoremove' to remove it.
|
||||
The following packages will be REMOVED:
|
||||
dnsmasq*
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
locale: Cannot set LC_CTYPE to default locale: No such file or directory
|
||||
locale: Cannot set LC_ALL to default locale: No such file or directory
|
||||
0 upgraded, 0 newly installed, 1 to remove and 115 not upgraded.
|
||||
After this operation, 159 kB disk space will be freed.
|
||||
(Reading database ...
(Reading database ... 5%
(Reading database ... 10%
(Reading database ... 15%
(Reading database ... 20%
(Reading database ... 25%
(Reading database ... 30%
(Reading database ... 35%
(Reading database ... 40%
(Reading database ... 45%
(Reading database ... 50%
(Reading database ... 55%
(Reading database ... 60%
(Reading database ... 65%
(Reading database ... 70%
(Reading database ... 75%
(Reading database ... 80%
(Reading database ... 85%
(Reading database ... 90%
(Reading database ... 95%
(Reading database ... 100%
(Reading database ... 52716 files and directories currently installed.)
|
||||
Removing dnsmasq (2.91-1+deb13u1) ...
|
||||
(Reading database ...
(Reading database ... 5%
(Reading database ... 10%
(Reading database ... 15%
(Reading database ... 20%
(Reading database ... 25%
(Reading database ... 30%
(Reading database ... 35%
(Reading database ... 40%
(Reading database ... 45%
(Reading database ... 50%
(Reading database ... 55%
(Reading database ... 60%
(Reading database ... 65%
(Reading database ... 70%
(Reading database ... 75%
(Reading database ... 80%
(Reading database ... 85%
(Reading database ... 90%
(Reading database ... 95%
(Reading database ... 100%
(Reading database ... 52697 files and directories currently installed.)
|
||||
Purging configuration files for dnsmasq (2.91-1+deb13u1) ...
|
||||
[OK] dnsmasq removed — the next install starts from a clean slate, as a first install
|
||||
[WARN] NOTE: dnsmasq-base pre-dates Felhom and is deliberately kept. It owns /usr/sbin/dnsmasq,
|
||||
[WARN] which the agent stats to decide whether to install — so on this host the next install
|
||||
[WARN] may skip the install step and fail to enable the unit (R-317).
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] golden vzdump left in place (pass --remove-golden to remove)
|
||||
|
||||
[STEP] kept vs wiped — read before pulling drives or closing the customer out
|
||||
WIPED (this run):
|
||||
- guest 120 (container + its OS/Docker/user-data volumes)
|
||||
- the felhom-agent: binary, unit, sudoers, config (+ its .bak backups), state dir, service user
|
||||
- self-update artifacts: guarded wrapper, A/B slots (.prev/.new.*), rollback unit, start-limit drop-in
|
||||
- break-glass watchdog + OOB artifacts (where present); guest-hook snippet; dnsmasq snippets; the mkfs + pbs-apply wrappers
|
||||
- pveum: the Felhom roles/user/token/scoped ACL; the emptied felhom pool
|
||||
- the install state file
|
||||
KEPT (lives on deliberately — remove/rotate these out-of-band if the customer is leaving):
|
||||
- the enrolled drives + ALL data under /mnt/felhom-drives — unmounted only, NEVER wiped;
|
||||
the drives are physically removable now.
|
||||
- the hub host/customer record + report history (operator UI / DB)
|
||||
- the escrow blob in the hub, if one exists (operator UI)
|
||||
- the hub-vaulted root@pam recovery credential — the box KEEPS the password step 4b set; rotate it if the box leaves Felhom management
|
||||
|
||||
[OK] UNINSTALL complete — removed: guest 120, the felhom-agent (unit/sudoers/binary/state/config+baks/user + selfupdate-artifacts/shared-parent/mkfs-wrapper/pbs-apply-wrapper/hook-snippet/dnsmasq-snippets), the pveum role/user/token/ACL, the felhom pool, and /var/lib/felhom-install/state.json.
|
||||
[INFO] golden vzdump: left in place (--remove-golden to remove).
|
||||
[INFO] NOTE: the 'sudo' package was left INSTALLED (a system package, never ours to remove). dnsmasq is removed only when the install-time record says Felhom installed it; a resolver that pre-dated Felhom is never touched. The host record still exists in the hub — remove it there if desired.
|
||||
@@ -0,0 +1,775 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=appliance customer=drill-r50 vmid=120
|
||||
|
||||
[STEP] 1/8 pre-flight
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[INFO] pve-manager/9.2.2/b9984c6d90a4bd80 (running kernel: 7.0.2-6-pve)
|
||||
[INFO] node: drill-pve (auto)
|
||||
[INFO] agent config: /etc/felhom-agent/agent.json
|
||||
[INFO] agent: not installed yet — will be fetched + installed in step 5/8
|
||||
[INFO] local-lvm free: ~75 GiB
|
||||
[WARN] local-lvm free ~75 GiB < hard min 120 GiB
|
||||
[INFO] free RAM: ~6236 MiB
|
||||
[INFO] existing guests on this host: 0 (pct+qm)
|
||||
[INFO] acl storage 'felhom-pbs' not present yet — expected: the PBS-DR tier creates it; the grant is pre-positioned deliberately
|
||||
[INFO] dnsmasq: already installed BEFORE Felhom — recorded; uninstall will not touch it
|
||||
[INFO] dnsmasq-base: already installed BEFORE Felhom — recorded; uninstall will leave it
|
||||
[INFO] hub reachable (https://hub.felhom.eu)
|
||||
[OK] customer 'drill-r50' exists + passphrase valid
|
||||
[INFO] golden (local): local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[INFO] --skip-provision: agent install/config only, no guest will be provisioned
|
||||
[OK] pre-flight passed
|
||||
[STEP] 2/8 Proxmox API token
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[OK] token minted (secret captured, not logged)
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[OK] scoped ACL applied (Base@/, Guest@/pool/felhom + /vms/990000..990009, Store@[local local-lvm felhom-pbs])
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
[STEP] 3/8 compute volume grows
|
||||
[INFO] auto-computed from ~75 GiB free (ONE volume since R-165)
|
||||
[INFO] grows: rootfs +0G (->32G), data +46G (->70G, ONE volume)
|
||||
[STEP] 4/8 host enrollment (POST /host-enroll)
|
||||
[OK] host REUSED (idempotent — existing credential)
|
||||
[INFO] host_id: drill-r50-0a4f9a (api_key captured, not logged)
|
||||
[STEP] 4b/8 break-glass credential (root@pam console password → hub vault)
|
||||
[OK] root@pam password set + vaulted to the hub (retrieve via the operator /admin path; never logged here)
|
||||
[WARN] NOTE: the root@pam password just CHANGED — the old one now fails at the PVE web GUI (:8006).
|
||||
[WARN] Retrieve the new one at hub → host page (vaulted recovery credential).
|
||||
[STEP] 5/8 agent install (fetch + verify + install)
|
||||
[OK] apt repos aligned to no-subscription (already aligned; apt-get update OK)
|
||||
[WARN] no git credential in controller.yaml — fetching artifacts ANONYMOUSLY (they are world-readable; sha256 verification unchanged)
|
||||
[INFO] manifest: agent v0.129.0 (sha 53a54f0620afbd6d…), golden v0.214.0
|
||||
[INFO] fetching agent binary v0.129.0 from Gitea …
|
||||
[OK] verified sha256 53a54f0620afbd6d… matches the hub manifest
|
||||
[OK] installed /usr/local/bin/felhom-agent (felhom-agent 0.129.0)
|
||||
[OK] created service user felhom-agent
|
||||
[OK] added felhom-agent to systemd-journal (unprivileged journal read for NAS verify)
|
||||
[OK] installed /usr/local/sbin/felhom-mkfs-guarded (0755, the guarded mkfs path)
|
||||
[OK] installed /usr/local/sbin/felhom-selfupdate-guarded (0755, the guarded A/B binary-swap path)
|
||||
[OK] installed /usr/local/sbin/felhom-pbs-apply (0755, the guarded PBS-DR apply path)
|
||||
[OK] installed /usr/local/sbin/felhom-backup-target-apply (0755, the guarded backup-target path)
|
||||
[OK] installed /etc/sudoers.d/felhom-agent (0440, visudo-validated)
|
||||
[OK] installed /etc/systemd/system/felhom-agent.service + enabled (started in step 6 after config)
|
||||
[OK] installed self-update rollback unit + start-limit drop-in (auto-rollback armed)
|
||||
[OK] installed break-glass layers 1+2 (tmpfiles /run/sshd + agent-independent watchdog timer)
|
||||
[OK] installed OOB felhom-sshd instance + static belt (agent renders config + fills sets once oob.enabled)
|
||||
[STEP] 6/8 agent config + service
|
||||
[WARN] backup target: DEGRADED — no eligible second drive, so the whole-system backup stays on the SYSTEM drive.
|
||||
[WARN] It protects against file corruption but NOT against a disk failure. Attach a second drive and assign it in the dashboard.
|
||||
[INFO] island bridge vmbr9 already present — leaving it
|
||||
[INFO] R-50 island ON: local_api=169.254.253.1:8443 (vmbr9); guest net1=169.254.253.2/30; lan_resolver.host_ip=10.0.2.15
|
||||
[INFO] node=drill-pve local_api=169.254.253.1:8443 tls_fp=C9:1F:AC:10:AE:62…
|
||||
[OK] wrote /etc/felhom-agent/agent.json (0600 felhom-agent)
|
||||
[OK] agent --selftest (read-only) passed
|
||||
[OK] felhom-agent service active (non-root felhom-agent reads the config OK)
|
||||
[STEP] 7/8 golden archive
|
||||
[INFO] local golden digest matches the manifest (3a40379cb00d98c6…) — this IS the vouched artifact
|
||||
[SKIP] using local golden: local:backup/vzdump-lxc-9100-2026_08_13-07_43_44.tar.zst
|
||||
[SKIP] provision (--skip-provision) — agent install/config verified only
|
||||
[STEP] verify (agent only)
|
||||
[INFO] binary: felhom-agent 0.129.0
|
||||
[INFO] runs as: felhom-agent (want felhom-agent)
|
||||
[OK] service active
|
||||
[OK] --selftest=hub OK (a host-report reached the hub)
|
||||
|
||||
[OK] Agent install SUCCESS — felhom-agent 0.129.0 as felhom-agent, host_id=drill-r50-0a4f9a customer=drill-r50
|
||||
@@ -0,0 +1,828 @@
|
||||
|
||||
[INFO] felhom-host-install v1.28.0 — mode=uninstall
|
||||
|
||||
[STEP] UNINSTALL — local host teardown
|
||||
[SKIP] guest 120 already absent — skipping guest teardown
|
||||
[STEP] host-level removal
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-agent.service'.
|
||||
Removed '/etc/systemd/system/timers.target.wants/felhom-mgmt-watchdog.timer'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-sshd.service'.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-oob-nft.service'.
|
||||
The unit files have no installation config (WantedBy=, RequiredBy=, UpheldBy=,
|
||||
Also=, or Alias= settings in the [Install] section, and DefaultInstance= for
|
||||
template units). This means they are not meant to be enabled or disabled using systemctl.
|
||||
|
||||
Possible reasons for having these kinds of units are:
|
||||
• A unit may be statically enabled by being symlinked from another unit's
|
||||
.wants/, .requires/, or .upholds/ directory.
|
||||
• A unit's purpose may be to act as a helper for some other unit which has
|
||||
a requirement dependency on it.
|
||||
• A unit may be started when needed via activation (socket, path, timer,
|
||||
D-Bus, udev, scripted systemctl call, ...).
|
||||
• In case of template units, the unit is meant to be enabled with some
|
||||
instance name specified.
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/felhom-shared-parent.service'.
|
||||
Removed '/etc/systemd/system/pve-guests.service.wants/felhom-shared-parent.service'.
|
||||
[INFO] dnsmasq was installed by Felhom (recorded at install) — stopping + disabling it
|
||||
Synchronizing state of dnsmasq.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
|
||||
Executing: /usr/lib/systemd/systemd-sysv-install disable dnsmasq
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
Removed '/etc/systemd/system/multi-user.target.wants/dnsmasq.service'.
|
||||
[INFO] dnsmasq: removing the package(s) Felhom installed: dnsmasq
|
||||
Reading package lists...
|
||||
Building dependency tree...
|
||||
Reading state information...
|
||||
The following package was automatically installed and is no longer required:
|
||||
dnsmasq-base
|
||||
Use 'apt autoremove' to remove it.
|
||||
The following packages will be REMOVED:
|
||||
dnsmasq*
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
locale: Cannot set LC_CTYPE to default locale: No such file or directory
|
||||
locale: Cannot set LC_ALL to default locale: No such file or directory
|
||||
0 upgraded, 0 newly installed, 1 to remove and 115 not upgraded.
|
||||
After this operation, 159 kB disk space will be freed.
|
||||
(Reading database ...
(Reading database ... 5%
(Reading database ... 10%
(Reading database ... 15%
(Reading database ... 20%
(Reading database ... 25%
(Reading database ... 30%
(Reading database ... 35%
(Reading database ... 40%
(Reading database ... 45%
(Reading database ... 50%
(Reading database ... 55%
(Reading database ... 60%
(Reading database ... 65%
(Reading database ... 70%
(Reading database ... 75%
(Reading database ... 80%
(Reading database ... 85%
(Reading database ... 90%
(Reading database ... 95%
(Reading database ... 100%
(Reading database ... 52716 files and directories currently installed.)
|
||||
Removing dnsmasq (2.91-1+deb13u1) ...
|
||||
(Reading database ...
(Reading database ... 5%
(Reading database ... 10%
(Reading database ... 15%
(Reading database ... 20%
(Reading database ... 25%
(Reading database ... 30%
(Reading database ... 35%
(Reading database ... 40%
(Reading database ... 45%
(Reading database ... 50%
(Reading database ... 55%
(Reading database ... 60%
(Reading database ... 65%
(Reading database ... 70%
(Reading database ... 75%
(Reading database ... 80%
(Reading database ... 85%
(Reading database ... 90%
(Reading database ... 95%
(Reading database ... 100%
(Reading database ... 52697 files and directories currently installed.)
|
||||
Purging configuration files for dnsmasq (2.91-1+deb13u1) ...
|
||||
[OK] dnsmasq removed — the next install starts from a clean slate, as a first install
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] old broad role FelhomAgent already absent
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "UTF-8",
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").
|
||||
[SKIP] golden vzdump left in place (pass --remove-golden to remove)
|
||||
|
||||
[STEP] kept vs wiped — read before pulling drives or closing the customer out
|
||||
WIPED (this run):
|
||||
- guest 120 (container + its OS/Docker/user-data volumes)
|
||||
- the felhom-agent: binary, unit, sudoers, config (+ its .bak backups), state dir, service user
|
||||
- self-update artifacts: guarded wrapper, A/B slots (.prev/.new.*), rollback unit, start-limit drop-in
|
||||
- break-glass watchdog + OOB artifacts (where present); guest-hook snippet; dnsmasq snippets; the mkfs + pbs-apply wrappers
|
||||
- pveum: the Felhom roles/user/token/scoped ACL; the emptied felhom pool
|
||||
- the install state file
|
||||
KEPT (lives on deliberately — remove/rotate these out-of-band if the customer is leaving):
|
||||
- the enrolled drives + ALL data under /mnt/felhom-drives — unmounted only, NEVER wiped;
|
||||
the drives are physically removable now.
|
||||
- the hub host/customer record + report history (operator UI / DB)
|
||||
- the escrow blob in the hub, if one exists (operator UI)
|
||||
- the hub-vaulted root@pam recovery credential — the box KEEPS the password step 4b set; rotate it if the box leaves Felhom management
|
||||
|
||||
[OK] UNINSTALL complete — removed: guest 120, the felhom-agent (unit/sudoers/binary/state/config+baks/user + selfupdate-artifacts/shared-parent/mkfs-wrapper/pbs-apply-wrapper/hook-snippet/dnsmasq-snippets), the pveum role/user/token/ACL, the felhom pool, and /var/lib/felhom-install/state.json.
|
||||
[INFO] golden vzdump: left in place (--remove-golden to remove).
|
||||
[INFO] NOTE: the 'sudo' package was left INSTALLED (a system package, never ours to remove). dnsmasq is removed only when the install-time record says Felhom installed it; a resolver that pre-dated Felhom is never touched. The host record still exists in the hub — remove it there if desired.
|
||||
File diff suppressed because one or more lines are too long
@@ -26,6 +26,13 @@
|
||||
> **Point of no return:** booting the install-armed stick (the auto-installer needs no confirm).
|
||||
> Recovery unchanged: stock ISO + `felhom-host-install.sh` — and since RESET is the plan, there
|
||||
> is nothing to restore. Demo-felhom.eu is down for the window (~2 h).
|
||||
>
|
||||
> **EVIDENCE RULE — standing rule 5 (R-320), and it applies to every phase boundary below.** The logs
|
||||
> of a phase are copied OFF the machine at the end of **that** phase, before any revert, snapshot
|
||||
> restore or teardown — **including the intermediate ones, which are the ones that get forgotten.**
|
||||
> Two sessions lost a phase's logs exactly this way on 2026-08-12 and 2026-08-13, same machine, same
|
||||
> point. Make the pull the last act of the phase. **If evidence is already gone: say so plainly and
|
||||
> reproduce the finding independently** — do not let a lost log quietly become a softer claim.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -167,9 +167,44 @@ chmod +x felhom-host-install.sh
|
||||
./felhom-host-install.sh -h | head -3 # sanity: must print v1.15.0 (or newer) — DR-tier-by-default ships the full plumbing
|
||||
```
|
||||
|
||||
This URL is the website's git-sync working tree tracking `main` on a 30-second period
|
||||
(`manifests/webpage.yaml`) — it is always the current `main` script. There is no release tag, no
|
||||
staging copy and no version selector; pushing `scripts/felhom-host-install.sh` publishes it.
|
||||
**⚠ THIS PARAGRAPH USED TO SAY THE OPPOSITE OF THE TRUTH, and two sessions were misled by it before
|
||||
it was corrected on 2026-08-13 (R-309, R-110).** The old text read *"it is always the current `main`
|
||||
script … pushing `scripts/felhom-host-install.sh` publishes it."* **Pushing publishes NOTHING, and has
|
||||
not since R-110 shipped on 2026-08-03.** Believing the old sentence is dangerous in **both**
|
||||
directions: it makes an operator think a pushed fix is live when it is not, and think a pushed mistake
|
||||
is live when it is not. (Measured 2026-08-12: this URL served `1.25.0` while `main` held `1.27.0`,
|
||||
three and a half hours after the push.)
|
||||
|
||||
`manifests/webpage.yaml` runs **two** git-syncs against **different refs**: the website tracks `main`,
|
||||
and `/scripts/` is checked out from the tag **`installer-v<SCRIPT_VERSION>`**. So this URL serves the
|
||||
**tagged** installer, not `main`.
|
||||
|
||||
**What actually publishes it — three acts, and the middle one is two lines, not one:**
|
||||
|
||||
1. Bump `SCRIPT_VERSION` in `scripts/felhom-host-install.sh` (the single version source) and push to
|
||||
`main`. *Nothing is published yet.*
|
||||
2. Cut and push the tag `installer-v<new SCRIPT_VERSION>`.
|
||||
3. Move **BOTH** `--ref=installer-v…` pins in `manifests/webpage.yaml` — the git-sync **sidecar** and
|
||||
the **init container** (today lines 327 and 372) — commit, and sync ArgoCD. **Moving one pin is the
|
||||
trap**: the running pod keeps serving until it restarts, and then a fresh pod seeded by the stale
|
||||
init container serves the OLD script with no error anywhere.
|
||||
|
||||
**To roll back:** move the tag back and wait ~30 s. No ArgoCD sync, no deploy — that is the emergency
|
||||
lever; fix forward afterwards. **Do not pin the website to the tag**, or every copy edit becomes a
|
||||
release. `hostinstall_gates.py` gate 6 fails if the manifest stops naming an `installer-v…` tag or if
|
||||
the website stops tracking `main`.
|
||||
|
||||
**How to verify from OUTSIDE that the published version actually changed** — a push, a green sync and a
|
||||
correct-looking manifest are each consistent with nothing having been published, so ask the public URL
|
||||
rather than the repository:
|
||||
|
||||
```bash
|
||||
curl -fsS https://felhom.eu/scripts/felhom-host-install.sh | grep -m1 '^SCRIPT_VERSION'
|
||||
```
|
||||
|
||||
It must print the **new** version. Confirmed by this method on 2026-08-13: served `1.28.0`, `main`
|
||||
`1.28.0`, both manifest pins `installer-v1.28.0` — the three agreeing is the observation, and any one
|
||||
of them alone is not.
|
||||
|
||||
### C.2 Preview (recommended)
|
||||
|
||||
|
||||
@@ -25,6 +25,25 @@ Fences name **acts**, not machines. "Do not destroy demo-hp's `drill-r50` fixtur
|
||||
demo-hp to host a throwaway VM" are unrelated; only the first has ever been meant. Read a per-machine
|
||||
prohibition as covering the act it names and nothing more.
|
||||
|
||||
## Before you revert it — take the evidence off first
|
||||
|
||||
> **A phase's evidence is copied off the machine at the end of THAT phase, before any revert, snapshot
|
||||
> restore or teardown. Not at the end of the session.** (Standing rule 5, R-320.)
|
||||
>
|
||||
> **The intermediate revert is the one that gets forgotten.** Both losses this project has recorded
|
||||
> were the *middle* teardown, never the final one — the Phase A logs of the 2026-08-12 retained-key
|
||||
> drill and the Part 1 logs of the 2026-08-13 R-316 run, both on `drill-r50`, both destroyed by a
|
||||
> revert to `virgin` between phases, three days apart. Both times the conclusions survived only
|
||||
> because the quotations had been read live and an independent reproduction happened to exist. **That
|
||||
> is luck.**
|
||||
>
|
||||
> **The mechanism:** make the pull the last act of the phase, not a step to remember later —
|
||||
> `pct pull` / `scp` into `documentation/audits/evidence-<topic>-<date>/` on DooPlex, then revert.
|
||||
> Tier 0 machines are *disposable*, which is precisely why nothing you need may be left on one.
|
||||
>
|
||||
> **If you notice it is already gone:** say so plainly in the report and **reproduce the finding
|
||||
> independently**. That is the documented expectation, not an improvisation.
|
||||
|
||||
| Tier | Meaning | Machines |
|
||||
|---|---|---|
|
||||
| **0 — disposable. Reach here first.** | Exists to be broken; reinstalling is a routine afternoon, not an incident. **A drill that needs a victim uses one of these.** | `demo-hp` (t740), `demo-felhom` (N100) |
|
||||
|
||||
@@ -56,6 +56,15 @@ roles. **A file being open in the editor is NOT an instruction. If no task is st
|
||||
"working" and "stopped entirely".
|
||||
4. **A recommendation that is not followed gets one line saying why.** Silence reads as agreement and
|
||||
the disagreement is lost.
|
||||
5. **Evidence is copied off the machine at the end of the phase that produced it — before any revert,
|
||||
snapshot restore or teardown. Not at the end of the session.** The intermediate revert is the one
|
||||
that gets forgotten; both losses were the *middle* teardown, never the final one. **The mechanism,
|
||||
because a rule without one is a wish:** the last act of a phase that ran on a machine is `scp`/`pct
|
||||
pull` its logs to the evidence directory on DooPlex — the same act that ends the phase, not a
|
||||
separate step to remember later. **And when a session notices the evidence is already gone: say so
|
||||
plainly in the report and REPRODUCE it independently.** That is the documented expectation, not an
|
||||
improvisation to be invented under pressure — it is what both sessions did, and it is the only
|
||||
reason two sets of conclusions survived.
|
||||
|
||||
<!--
|
||||
R-96 incident record (committed 2026-07-27) — rationale, not directives.
|
||||
@@ -72,6 +81,16 @@ R-96 incident record (committed 2026-07-27) — rationale, not directives.
|
||||
4. Twice in the R-88/R-97 arc a review point was absorbed rather than argued: R-84 was folded into
|
||||
R-82 without a word, and R-97a's operator-only guard was dropped while the claim it was meant to
|
||||
enforce got committed as a comment — which is how a false guarantee shipped and survived a release.
|
||||
5. Twice in three days, on the SAME machine and at the SAME point. 2026-08-12, the retained-key drill:
|
||||
the Phase A logs lived on `drill-r50`'s disk and were destroyed by the revert to `virgin` between
|
||||
Phase A and Phase B (`audits/DRILL-retained-key-2026-08-12.md` §11.5). 2026-08-13, R-316: the Part 1
|
||||
logs, same disk, same revert, between Part 1 and Part 2 (`audits/REPORT-r316-installer-v1.28.0-2026-08-13.md`
|
||||
§9 — "the same mistake as Tuesday, in the same place"; preserved out of `REPORT.md`, which is
|
||||
overwritten every session). Both times the golden-bake runbook's existing "scp the log OUT first"
|
||||
was applied to the FINAL teardown and not the intermediate one. Both times the conclusions survived
|
||||
only because the quotations had been read live and an independent reproduction happened to exist —
|
||||
that is luck, and the second occurrence is what makes it procedural rather than another apology.
|
||||
Filed as R-320.
|
||||
-->
|
||||
|
||||
## Shared conventions
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# Golden bake 0.214.0 — 2026-08-12
|
||||
|
||||
Per `RUNBOOK-manual-build.md` §4.0/§4.1. Drill VM reverted to `virgin` before and after; guest 9100
|
||||
destroyed `--purge`; `/root` residue shredded.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| `GOLDEN_VERSION` | **0.214.0** |
|
||||
| `GOLDEN_SHA256` | **3a40379cb00d98c6f9550815b2b024783f153e9eef9be2b3252253d24d8d2c4d** |
|
||||
| controller baked | `gitea.dooplex.hu/admin/felhom-controller:0.214.0` |
|
||||
| `MinAgent` (CHANGELOG header) | **0.129.0** |
|
||||
| published | 656 392 524 B, `upload OK (HTTP 201)` |
|
||||
|
||||
## Acceptance markers (`grep -F`, quoted loop variable)
|
||||
|
||||
`docker OK (overlay2` 1 · `including mount point rootfs` 1 · `including mount point mp0` 1 ·
|
||||
`upload OK (HTTP 201)` 1 · `FATAL` 0 · `excluding` 0
|
||||
|
||||
## Fetchability — the SERVED bytes
|
||||
|
||||
```
|
||||
downloaded: 656392524 bytes
|
||||
sha256: 3a40379cb00d98c6f9550815b2b024783f153e9eef9be2b3252253d24d8d2c4d
|
||||
```
|
||||
Identical to `GOLDEN_SHA256`.
|
||||
|
||||
## The template index was STALE, and it would have baked the wrong base
|
||||
|
||||
`pveam available` on the freshly reverted `virgin` listed only `debian-13-standard_13.1-2` — the point
|
||||
release our own memory records as 404-ing since 2026-07-15. **`pveam update` first**, and the real
|
||||
current one is `debian-13-standard_13.6-1_amd64.tar.zst`. The runbook says the point release rots; what
|
||||
it does not say is that the VM's cached index rots too, and reading it without refreshing produces a
|
||||
confident answer that is a fortnight out of date.
|
||||
|
||||
## Secret handling
|
||||
|
||||
Token file→file, read inside the VM by a runner script, never on a command line.
|
||||
`systemctl show golden-bake -p Environment -p ExecStart | grep -c -F <token>` = **0**. Leak grep on the
|
||||
committed log = **0**, believable because a planted-token control on a copy grepped **1**. All in-VM
|
||||
artefacts `shred -u`'d.
|
||||
|
||||
## NOT DONE
|
||||
|
||||
The Day-0 vouch — the operator's, and deliberately so. Three fields, each already verified downloadable
|
||||
and selectable: **golden 0.214.0**, **agent 0.129.0**, **min agent 0.129.0**.
|
||||
@@ -0,0 +1,326 @@
|
||||
[golden] build-golden.sh v3.0.0 — baking controller gitea.dooplex.hu/admin/felhom-controller:0.214.0
|
||||
[golden] creating build LXC 9100 (nesting=1,keyctl=1, unprivileged; rootfs 32G + ONE data volume 24G @ /var/lib/felhom, backup=1) …
|
||||
Logical volume "vm-9100-disk-0" created.
|
||||
Logical volume pve/vm-9100-disk-0 changed.
|
||||
Creating filesystem with 8388608 4k blocks and 2097152 inodes
|
||||
Filesystem UUID: a630e58b-5ddd-4312-8535-b83ed18030fb
|
||||
Superblock backups stored on blocks:
|
||||
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
|
||||
4096000, 7962624
|
||||
Logical volume "vm-9100-disk-1" created.
|
||||
Logical volume pve/vm-9100-disk-1 changed.
|
||||
Creating filesystem with 6291456 4k blocks and 1572864 inodes
|
||||
Filesystem UUID: 247da550-80fb-4921-bb4c-0a3517bdbd21
|
||||
Superblock backups stored on blocks:
|
||||
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
|
||||
extracting archive '/var/lib/vz/template/cache/debian-13-standard_13.6-1_amd64.tar.zst'
|
||||
Total bytes read: 553512960 (528MiB, 177MiB/s)
|
||||
Detected container architecture: amd64
|
||||
Creating SSH host key 'ssh_host_ed25519_key' - this may take some time ...
|
||||
done: SHA256:N/+3Phg1PMspcZ0VWshdC1mXbkAYQ2jAsYhavLNrb0Q root@felhom-golden
|
||||
Creating SSH host key 'ssh_host_ecdsa_key' - this may take some time ...
|
||||
done: SHA256:fl1uCYoByd5OGUy7NjwyEHlkIcOvAxk5887imnsM7tc root@felhom-golden
|
||||
Creating SSH host key 'ssh_host_rsa_key' - this may take some time ...
|
||||
done: SHA256:6wNca1Ee5AXkXkQjmROa6sdynmpHikRhw7MuHpxXrk0 root@felhom-golden
|
||||
[golden] starting + installing Docker (official repo, trixie channel) …
|
||||
apt-listchanges: Can't set locale; make sure $LC_* and $LANG are correct!
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = (unset),
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to the standard locale ("C").
|
||||
locale: Cannot set LC_CTYPE to default locale: No such file or directory
|
||||
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
|
||||
locale: Cannot set LC_ALL to default locale: No such file or directory
|
||||
apt-listchanges: Can't set locale; make sure $LC_* and $LANG are correct!
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LANGUAGE = (unset),
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = (unset),
|
||||
LC_NUMERIC = (unset),
|
||||
LC_COLLATE = (unset),
|
||||
LC_TIME = (unset),
|
||||
LC_MESSAGES = (unset),
|
||||
LC_MONETARY = (unset),
|
||||
LC_ADDRESS = (unset),
|
||||
LC_IDENTIFICATION = (unset),
|
||||
LC_MEASUREMENT = (unset),
|
||||
LC_PAPER = (unset),
|
||||
LC_TELEPHONE = (unset),
|
||||
LC_NAME = (unset),
|
||||
LANG = "en_US.UTF-8"
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to the standard locale ("C").
|
||||
locale: Cannot set LC_CTYPE to default locale: No such file or directory
|
||||
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
|
||||
locale: Cannot set LC_ALL to default locale: No such file or directory
|
||||
[golden] baking daemon.json: classic overlay2 driver (containerd-snapshotter OFF) + log rotation …
|
||||
[golden] wiring the single data volume (R-165 variant V-c): /var/lib/felhom/{docker,sys_drive} -> binds …
|
||||
[golden] verifying Docker works in the build guest (storage driver should be overlay2 on the ext4 data volume) …
|
||||
Unable to find image 'hello-world:latest' locally
|
||||
latest: Pulling from library/hello-world
|
||||
4f55086f7dd0: Pulling fs layer
|
||||
4f55086f7dd0: Download complete
|
||||
4f55086f7dd0: Pull complete
|
||||
Digest: sha256:7f4da0fc94bcece205a8c0b6f4d11c8196924654ffe5c4d1aa439b7f632048b2
|
||||
Status: Downloaded newer image for hello-world:latest
|
||||
docker OK (overlay2; data-root /var/lib/docker)
|
||||
/var/lib/docker is a real mount: /dev/mapper/pve-vm--9100--disk--1[/docker] ext4
|
||||
/mnt/sys_drive is a real mount: /dev/mapper/pve-vm--9100--disk--1[/sys_drive] ext4
|
||||
both paths are ONE filesystem: /dev/mapper/pve-vm--9100--disk--1 23317576
|
||||
[golden] baking the in-guest controller image gitea.dooplex.hu/admin/felhom-controller:0.214.0 (no registry cred at deploy) …
|
||||
|
||||
WARNING! Your credentials are stored unencrypted in '/root/.docker/config.json'.
|
||||
Configure a credential helper to remove this warning. See
|
||||
https://docs.docker.com/go/credential-store/
|
||||
|
||||
0.214.0: Pulling from admin/felhom-controller
|
||||
039e6f9f9752: Pulling fs layer
|
||||
0094c3ac0914: Pulling fs layer
|
||||
deca1dac7403: Pulling fs layer
|
||||
11c19a33d1b8: Pulling fs layer
|
||||
742f054a0a3b: Pulling fs layer
|
||||
63bdd1abbb22: Pulling fs layer
|
||||
11c19a33d1b8: Waiting
|
||||
742f054a0a3b: Waiting
|
||||
63bdd1abbb22: Waiting
|
||||
039e6f9f9752: Verifying Checksum
|
||||
039e6f9f9752: Download complete
|
||||
deca1dac7403: Verifying Checksum
|
||||
deca1dac7403: Download complete
|
||||
11c19a33d1b8: Verifying Checksum
|
||||
11c19a33d1b8: Download complete
|
||||
742f054a0a3b: Verifying Checksum
|
||||
742f054a0a3b: Download complete
|
||||
63bdd1abbb22: Verifying Checksum
|
||||
63bdd1abbb22: Download complete
|
||||
0094c3ac0914: Verifying Checksum
|
||||
0094c3ac0914: Download complete
|
||||
039e6f9f9752: Pull complete
|
||||
0094c3ac0914: Pull complete
|
||||
deca1dac7403: Pull complete
|
||||
11c19a33d1b8: Pull complete
|
||||
742f054a0a3b: Pull complete
|
||||
63bdd1abbb22: Pull complete
|
||||
Digest: sha256:d2c0bc7fba3d142e7f9ee9117231fd7ea28630aa71ce2f4a7e2d0ee1fdb85d97
|
||||
Status: Downloaded newer image for gitea.dooplex.hu/admin/felhom-controller:0.214.0
|
||||
gitea.dooplex.hu/admin/felhom-controller:0.214.0
|
||||
[golden] asking the controller which infra images it manages …
|
||||
[golden] baking infra images (4): traefik:v3.6.7 cloudflare/cloudflared:2026.6.0 gtstef/filebrowser:1.3.3-stable gitea.dooplex.hu/admin/felhom-samba:1.1.0 …
|
||||
v3.6.7: Pulling from library/traefik
|
||||
589002ba0eae: Pulling fs layer
|
||||
ef63511ea6cc: Pulling fs layer
|
||||
0738e5cb835e: Pulling fs layer
|
||||
3e6813f70c64: Pulling fs layer
|
||||
3e6813f70c64: Waiting
|
||||
ef63511ea6cc: Verifying Checksum
|
||||
ef63511ea6cc: Download complete
|
||||
589002ba0eae: Verifying Checksum
|
||||
589002ba0eae: Download complete
|
||||
3e6813f70c64: Verifying Checksum
|
||||
3e6813f70c64: Download complete
|
||||
0738e5cb835e: Verifying Checksum
|
||||
0738e5cb835e: Download complete
|
||||
589002ba0eae: Pull complete
|
||||
ef63511ea6cc: Pull complete
|
||||
0738e5cb835e: Pull complete
|
||||
3e6813f70c64: Pull complete
|
||||
Digest: sha256:a9890c898f379c1905ee5b28342f6b408dc863f08db2dab20e46c267d1ff463a
|
||||
Status: Downloaded newer image for traefik:v3.6.7
|
||||
docker.io/library/traefik:v3.6.7
|
||||
2026.6.0: Pulling from cloudflare/cloudflared
|
||||
47de5dd0b812: Pulling fs layer
|
||||
c172f21841df: Pulling fs layer
|
||||
99515e7b4d35: Pulling fs layer
|
||||
99ba982a9142: Pulling fs layer
|
||||
d6b1b89eccac: Pulling fs layer
|
||||
2780920e5dbf: Pulling fs layer
|
||||
7c12895b777b: Pulling fs layer
|
||||
3214acf345c0: Pulling fs layer
|
||||
52630fc75a18: Pulling fs layer
|
||||
dd64bf2dd177: Pulling fs layer
|
||||
b839dfae01f6: Pulling fs layer
|
||||
ebddc55facdc: Pulling fs layer
|
||||
bdfd7f7e5bf6: Pulling fs layer
|
||||
2d4d7adf6272: Pulling fs layer
|
||||
40008157d8d2: Pulling fs layer
|
||||
bd8962e29291: Pulling fs layer
|
||||
cac2ae0193cb: Pulling fs layer
|
||||
74d1dac84ecc: Pulling fs layer
|
||||
99ba982a9142: Waiting
|
||||
d6b1b89eccac: Waiting
|
||||
2780920e5dbf: Waiting
|
||||
7c12895b777b: Waiting
|
||||
3214acf345c0: Waiting
|
||||
52630fc75a18: Waiting
|
||||
dd64bf2dd177: Waiting
|
||||
b839dfae01f6: Waiting
|
||||
ebddc55facdc: Waiting
|
||||
bdfd7f7e5bf6: Waiting
|
||||
2d4d7adf6272: Waiting
|
||||
40008157d8d2: Waiting
|
||||
bd8962e29291: Waiting
|
||||
cac2ae0193cb: Waiting
|
||||
74d1dac84ecc: Waiting
|
||||
99515e7b4d35: Verifying Checksum
|
||||
99515e7b4d35: Download complete
|
||||
c172f21841df: Verifying Checksum
|
||||
c172f21841df: Download complete
|
||||
47de5dd0b812: Verifying Checksum
|
||||
47de5dd0b812: Download complete
|
||||
99ba982a9142: Download complete
|
||||
d6b1b89eccac: Verifying Checksum
|
||||
d6b1b89eccac: Download complete
|
||||
2780920e5dbf: Verifying Checksum
|
||||
2780920e5dbf: Download complete
|
||||
7c12895b777b: Verifying Checksum
|
||||
7c12895b777b: Download complete
|
||||
52630fc75a18: Verifying Checksum
|
||||
52630fc75a18: Download complete
|
||||
3214acf345c0: Verifying Checksum
|
||||
3214acf345c0: Download complete
|
||||
47de5dd0b812: Pull complete
|
||||
dd64bf2dd177: Verifying Checksum
|
||||
dd64bf2dd177: Download complete
|
||||
b839dfae01f6: Verifying Checksum
|
||||
b839dfae01f6: Download complete
|
||||
ebddc55facdc: Verifying Checksum
|
||||
ebddc55facdc: Download complete
|
||||
bdfd7f7e5bf6: Download complete
|
||||
40008157d8d2: Verifying Checksum
|
||||
40008157d8d2: Download complete
|
||||
bd8962e29291: Verifying Checksum
|
||||
bd8962e29291: Download complete
|
||||
2d4d7adf6272: Verifying Checksum
|
||||
2d4d7adf6272: Download complete
|
||||
c172f21841df: Pull complete
|
||||
cac2ae0193cb: Verifying Checksum
|
||||
cac2ae0193cb: Download complete
|
||||
74d1dac84ecc: Verifying Checksum
|
||||
74d1dac84ecc: Download complete
|
||||
99515e7b4d35: Pull complete
|
||||
99ba982a9142: Pull complete
|
||||
d6b1b89eccac: Pull complete
|
||||
2780920e5dbf: Pull complete
|
||||
7c12895b777b: Pull complete
|
||||
3214acf345c0: Pull complete
|
||||
52630fc75a18: Pull complete
|
||||
dd64bf2dd177: Pull complete
|
||||
b839dfae01f6: Pull complete
|
||||
ebddc55facdc: Pull complete
|
||||
bdfd7f7e5bf6: Pull complete
|
||||
2d4d7adf6272: Pull complete
|
||||
40008157d8d2: Pull complete
|
||||
bd8962e29291: Pull complete
|
||||
cac2ae0193cb: Pull complete
|
||||
74d1dac84ecc: Pull complete
|
||||
Digest: sha256:ba461b8aa9c042156dbd39c38657fe7431bafa063220eab8d5330a523863da9f
|
||||
Status: Downloaded newer image for cloudflare/cloudflared:2026.6.0
|
||||
docker.io/cloudflare/cloudflared:2026.6.0
|
||||
1.3.3-stable: Pulling from gtstef/filebrowser
|
||||
6a0ac1617861: Pulling fs layer
|
||||
ef8806083e82: Pulling fs layer
|
||||
b74107c861c7: Pulling fs layer
|
||||
adc935def003: Pulling fs layer
|
||||
4f4fb700ef54: Pulling fs layer
|
||||
18695ccc900a: Pulling fs layer
|
||||
45d119d5c397: Pulling fs layer
|
||||
dac52db4fc51: Pulling fs layer
|
||||
6d598f86b2f2: Pulling fs layer
|
||||
8aa349c8396c: Pulling fs layer
|
||||
dac52db4fc51: Waiting
|
||||
6d598f86b2f2: Waiting
|
||||
8aa349c8396c: Waiting
|
||||
4f4fb700ef54: Waiting
|
||||
adc935def003: Waiting
|
||||
18695ccc900a: Waiting
|
||||
45d119d5c397: Waiting
|
||||
6a0ac1617861: Verifying Checksum
|
||||
6a0ac1617861: Download complete
|
||||
b74107c861c7: Verifying Checksum
|
||||
b74107c861c7: Download complete
|
||||
6a0ac1617861: Pull complete
|
||||
adc935def003: Verifying Checksum
|
||||
adc935def003: Download complete
|
||||
4f4fb700ef54: Verifying Checksum
|
||||
4f4fb700ef54: Download complete
|
||||
45d119d5c397: Verifying Checksum
|
||||
45d119d5c397: Download complete
|
||||
dac52db4fc51: Verifying Checksum
|
||||
dac52db4fc51: Download complete
|
||||
18695ccc900a: Verifying Checksum
|
||||
18695ccc900a: Download complete
|
||||
6d598f86b2f2: Verifying Checksum
|
||||
6d598f86b2f2: Download complete
|
||||
8aa349c8396c: Verifying Checksum
|
||||
8aa349c8396c: Download complete
|
||||
ef8806083e82: Verifying Checksum
|
||||
ef8806083e82: Download complete
|
||||
ef8806083e82: Pull complete
|
||||
b74107c861c7: Pull complete
|
||||
adc935def003: Pull complete
|
||||
4f4fb700ef54: Pull complete
|
||||
18695ccc900a: Pull complete
|
||||
45d119d5c397: Pull complete
|
||||
dac52db4fc51: Pull complete
|
||||
6d598f86b2f2: Pull complete
|
||||
8aa349c8396c: Pull complete
|
||||
Digest: sha256:eb3733681db8757412632c61a99ad656f0d94ed6781bb2ea114b4d70babab78c
|
||||
Status: Downloaded newer image for gtstef/filebrowser:1.3.3-stable
|
||||
docker.io/gtstef/filebrowser:1.3.3-stable
|
||||
1.1.0: Pulling from admin/felhom-samba
|
||||
897d797d2723: Pulling fs layer
|
||||
3051591aa250: Pulling fs layer
|
||||
ce57a3f93416: Pulling fs layer
|
||||
fb94eeec2fe1: Pulling fs layer
|
||||
fb94eeec2fe1: Waiting
|
||||
ce57a3f93416: Verifying Checksum
|
||||
ce57a3f93416: Download complete
|
||||
fb94eeec2fe1: Verifying Checksum
|
||||
fb94eeec2fe1: Download complete
|
||||
897d797d2723: Verifying Checksum
|
||||
897d797d2723: Download complete
|
||||
3051591aa250: Verifying Checksum
|
||||
3051591aa250: Download complete
|
||||
897d797d2723: Pull complete
|
||||
3051591aa250: Pull complete
|
||||
ce57a3f93416: Pull complete
|
||||
fb94eeec2fe1: Pull complete
|
||||
Digest: sha256:1c17c09422bec0366d7cf0e0fcfc1486ba6c90334a0a5d5c851073a9342f8f10
|
||||
Status: Downloaded newer image for gitea.dooplex.hu/admin/felhom-samba:1.1.0
|
||||
gitea.dooplex.hu/admin/felhom-samba:1.1.0
|
||||
[golden] baking the controller-bootstrap unit (deploys the BAKED controller from the config mount) …
|
||||
Created symlink '/etc/systemd/system/multi-user.target.wants/felhom-controller-bootstrap.service' → '/etc/systemd/system/felhom-controller-bootstrap.service'.
|
||||
[golden] baking the controller-bootstrap PATH unit (starts the service on bootstrap-mount hot-plug — B1) …
|
||||
Created symlink '/etc/systemd/system/multi-user.target.wants/felhom-controller-bootstrap.path' → '/etc/systemd/system/felhom-controller-bootstrap.path'.
|
||||
[golden] baking the first-boot SSH host-key regeneration unit (F3) …
|
||||
Created symlink '/etc/systemd/system/multi-user.target.wants/felhom-regen-hostkeys.service' → '/etc/systemd/system/felhom-regen-hostkeys.service'.
|
||||
[golden] identity-clean + minimize …
|
||||
[golden] stop + archive …
|
||||
INFO: including mount point rootfs ('/') in backup
|
||||
INFO: including mount point mp0 ('/var/lib/felhom') in backup
|
||||
INFO: archive file size: 625MB
|
||||
INFO: Finished Backup of VM 9100 (00:00:39)
|
||||
[golden] DONE. golden archive volid: local:backup/vzdump-lxc-9100-2026_08_12-18_52_07.tar.zst (rootfs 32G + ONE data volume 24G @ /var/lib/felhom, all in the archive)
|
||||
[golden] publishing golden (656392524 bytes, sha256 3a40379cb00d98c6…) → https://gitea.dooplex.hu/api/packages/admin/generic/felhom-golden/0.214.0/golden.tar.zst
|
||||
[golden] pre-delete existing: HTTP 404 (404/204 expected)
|
||||
[golden] upload OK (HTTP 201)
|
||||
GOLDEN_VERSION=0.214.0
|
||||
GOLDEN_SHA256=3a40379cb00d98c6f9550815b2b024783f153e9eef9be2b3252253d24d8d2c4d
|
||||
[golden] Record in the hub operator UI (Configs → Day-0 artifacts): golden 0.214.0 / 3a40379cb00d98c6f9550815b2b024783f153e9eef9be2b3252253d24d8d2c4d
|
||||
[golden] (the build guest 9100 is stopped; destroy it with: pct destroy 9100 --purge)
|
||||
@@ -1,3 +1,232 @@
|
||||
## v0.105.0 — the third name, a machine told to be quiet, and a guard for the hub's own words (2026-08-13)
|
||||
|
||||
Hub only. **No controller change, no agent change, no wire change — nothing to bake.** R-323, R-324,
|
||||
R-321, R-326.
|
||||
|
||||
### R-323 — the third near-homograph: „Tulajdonosi jelmondat"
|
||||
|
||||
Three secrets a customer can hold, and they must be tellable apart by a hurried reader:
|
||||
|
||||
| | what it is | name |
|
||||
|---|---|---|
|
||||
| three words | takes control of the dashboard | „Beállító kód" |
|
||||
| ten words | opens the sealed off-site backups | „Helyreállítási kód" |
|
||||
| **five words** | **proves the account owns the box being bound** | **„Tulajdonosi jelmondat"** |
|
||||
|
||||
The five-word phrase was „Visszaállító jelszó" — **one word from the name retired last week for
|
||||
colliding with „Helyreállítási kód"**, and false besides: the phrase restores nothing.
|
||||
|
||||
**Five customer-facing sites, all here**: `web/selfbind.go:255,256,261,263` and
|
||||
`notify/templates.go:331`. Nothing in `felhom-controller` or `felhom-agent` — the only hits there are
|
||||
comments and a test asserting the already-retired „Visszaállító **kód**" is absent.
|
||||
|
||||
**Both obvious names were rejected, with reasons.** „Fiókjelszó" is worse than the trap it fixes:
|
||||
there IS an account password (the dashboard login), so it would collide with a *different* real
|
||||
secret. „Összekötési jelszó" recreates the trap structurally — the other factor on the same page and
|
||||
in the same mail is the **„Párosító kód"**, so naming this one after the same act would leave the two
|
||||
factors a customer types in one sitting separated only by kód-versus-jelszó, which is exactly the
|
||||
shape being removed. „Tulajdonosi jelmondat" is distinct on **both** axes — stem and noun.
|
||||
|
||||
**Naming only.** The form field is still `name="passphrase"`;
|
||||
`TestSelfBindPassphrase_StillAcceptedAfterTheRename` drives the real handler with the same messy human
|
||||
spacing and asserts the appliance still binds.
|
||||
|
||||
### R-324 — the hub's customer copy comes under a guard, for the first time
|
||||
|
||||
`retrieval_promise_gate.py` lives in `felhom-controller` and scans that repo only. It was extended to
|
||||
Go strings on 2026-08-12 because the recovery screen's copy *"had never been scanned"* — and the same
|
||||
sentence was true one repo over, for the surface a customer reads **first**.
|
||||
|
||||
`scripts/hub_copy_gate.py`, registered in `repo_gates.py`:
|
||||
|
||||
- **retired names — banned outright, across all 95 hub files**, no allowlist. Comments stripped.
|
||||
- **retrieval stems — registered, not banned**, in four declared customer surfaces. A missing declared
|
||||
surface is a FAILURE, never a skip. The allowlist is empty, and that is a measurement.
|
||||
|
||||
**The selftest found a defect in its own instrument on the first run**: the synthetic source was named
|
||||
`<selftest>`, comment-stripping keys off the `.go` extension, and the step-3 control convicted a
|
||||
comment. The bug was in the guard; the control is what found it.
|
||||
|
||||
Vocabulary is **not duplicated** — `scripts/customer_copy_vocab.py` is the one list, in the same
|
||||
shared-gate home both repos already consume without copying. The controller gate has not yet adopted
|
||||
it (that would be a felhom-controller change, out of scope tonight), so this gate **reads its `STEMS`
|
||||
and fails on divergence** — watched failing, and green again when restored. R-325 removes the scaffold.
|
||||
|
||||
### R-321 — a machine we told to be quiet is not a machine that died
|
||||
|
||||
Switching a box's reporting off is supported: the controller sends one final report carrying
|
||||
`health.status = "disabled"` and goes quiet by design. The hub stored that, rendered it in the
|
||||
roll-up, and **alarmed on it anyway** — stale at 30 minutes, down at 60, two e-mails about an outage
|
||||
we caused on purpose.
|
||||
|
||||
**It was two doors, not one.** `StalenessChecker.Check` now skips the age transition; and because the
|
||||
state is **recorded** (`StateDisabled`) rather than deleted, `CheckBackupDeadlines` can skip it too —
|
||||
a deleted state returns `""`, which is not `"down"`, so that check would have gone on sending
|
||||
`expected_backup_missed` every morning. R-195's shape returning through a second door.
|
||||
|
||||
The discriminator is the box's own last word, not an inference. `downtimeStart` is cleared on entry.
|
||||
**The re-enablement clock runs from the report the hub can see**, so a box that reports on re-enabling
|
||||
starts its clock there; leaving `disabled` re-enters the new-customer branch, so no `node_recovered`
|
||||
fires for an outage that never happened. **Limit, stated:** a box re-enabled that then fails to report
|
||||
keeps being suppressed — the hub's view changes only when a report arrives, which is exactly why the
|
||||
state is made visible.
|
||||
|
||||
**Three red-proofs, mutations asserted applied.** The one that matters: an unconditional suppression
|
||||
was seen leaving a genuinely dead machine at `"disabled"` instead of `"down"`. A test weakness was
|
||||
found by a red-proof and fixed — scenario A seeded the customer already-disabled, so the new-customer
|
||||
branch swallowed the first observation and it passed on the state assertion alone even with the
|
||||
suppression deleted.
|
||||
|
||||
### R-326 — "what is unproven" becomes a question a machine can answer
|
||||
|
||||
A session asked for *"the nine grey claims"* could not determine which nine and declined to guess.
|
||||
**Nine is real and answers a different question: it is the count of claims the 2026-08-09 pass
|
||||
DOWNGRADED.** The real figures, from `where-felhom-stands.yaml`: **55 claims — walked 23, partial 14,
|
||||
built 14, missing 4; NOT WALKED 32 of 55**, of which only 6 cite evidence and 26 are prose only.
|
||||
|
||||
`scripts/unproven.py` prints them; `--summary` prints the counts. Wired into the end-of-session
|
||||
checklist. Its first run found a stale claim — `claim.code-naming` still describes a defect now fixed
|
||||
twice over (R-327). The capability map is deliberately **not** restructured.
|
||||
|
||||
## v0.104.0 — the hub can see whether a guest's networking works, and one name per secret (2026-08-13, R-319 + R-295 hub half)
|
||||
|
||||
Two things, both hub-only. **No wire change, no agent change, no controller change, nothing to bake.**
|
||||
|
||||
### R-319 — the guest-network watchdog finally has a reader
|
||||
|
||||
The agent has reported `guest_net` on every heartbeat since **v0.92.0** (R-54, 2026-07-21). The string
|
||||
`guest_net` occurred **nowhere** in this repository: the stanza was stored as raw text inside
|
||||
`report_json` and read by nothing — no check, no alarm, no screen. This is the first of R-264's
|
||||
twenty-one unconsumed facts to be given a reader, and it was chosen because it has a live incident
|
||||
behind it: a killed `dhclient` in a guest took a tunnel down for 1 h 15 m with nobody told
|
||||
(`audits/INCIDENT-guest-dhclient-killed-2026-07-20.md`).
|
||||
|
||||
**Established before anything was written.** The facts arrive and are persisted:
|
||||
`demo-felhom-8363b5`'s newest row carries `guest_net.checked_at` plus per-guest
|
||||
`vmid/state/mode/ip/has_route/dhclient_alive/checked_at/message`, and the agent's wire type
|
||||
(`felhom-agent/internal/hub/report.go:139-160`) additionally carries `healed`, `heal_succeeded`,
|
||||
`last_heal_at`, `heals_last_hour`, `damped` — absent from the live rows only because they are
|
||||
`omitempty` on a box that has never needed a repair.
|
||||
|
||||
**THE SIGNAL IS THE REPAIR COUNT, NOT THE STATE.** A guest whose network the watchdog keeps repairing
|
||||
is healthy at every instant anyone looks and is nevertheless failing. Rendering `state` alone would
|
||||
give that machine a green tick — the exact shape of the defect that drew a failed disk as a healthy
|
||||
empty disk. `heals_last_hour` is therefore surfaced *beside* the state, not behind it, and drives the
|
||||
card's summary badge.
|
||||
|
||||
`heal_succeeded` is decoded too, deliberately. **R-260 is this project's standing warning that a
|
||||
decoder three fields short of the agent dropped the one that decided the question the checker
|
||||
existed to answer.** Six failed repairs is a guest that is down; six successful ones is a nuisance.
|
||||
|
||||
**An unknown is never drawn as healthy.** Three absences are kept apart, each with its own sentence,
|
||||
following the companion-flag convention (`hostNetworkView` is the sibling):
|
||||
|
||||
- the agent predates v0.92.0 — absence is expected, and still tells us nothing;
|
||||
- a capable agent sent no stanza — the watchdog is default-on, so this means it was switched off;
|
||||
- a guest whose own `state` is empty or unrecognised — the state switch is an ALLOW-LIST, so adding a
|
||||
state to the agent can never silently paint it green here.
|
||||
|
||||
A malformed stanza degrades to unknown and **must not 500 the page** — one box's bad field cannot
|
||||
break the host page for the rest of the fleet.
|
||||
|
||||
**No alarm was added, and that is a judgement rather than an omission.** The incident behind this was
|
||||
about nobody being able to *see* the condition, not about nobody being paged; and a new alarm on a
|
||||
fleet of two demo machines is untested noise on a dispatcher whose severity contract is exact-match
|
||||
lowercase. Revisit when a third machine exists, or when a repair count is observed climbing on real
|
||||
hardware — the visible count is what will supply that evidence.
|
||||
|
||||
**Red-proofs, each mutation asserted applied by grep before its run and reverted after:**
|
||||
|
||||
1. the unknown branches replaced by the healthy badge → **both** scenario-C sub-cases go red, a silent
|
||||
machine seen rendering as healthy. *(the one that matters)*
|
||||
2. `RepairCount: 0` in the decoder → B goes red on *"a guest repaired 6 times in an hour is reported
|
||||
as fine"*.
|
||||
3. `Degraded()` forced true → A goes red on *"a machine that is fine is being alarmed on"* — the guard
|
||||
is reachable in both directions, not just the alarming one.
|
||||
|
||||
**Positive control that the wiring is real and not merely written:** `wire_contract_gate.py`'s
|
||||
checked-tag count rose **182 → 190** and its skipped count fell **88 → 80**, because the eight
|
||||
`guest_net` allowlist entries were REMOVED. An allowlisted tag is *skipped*, so leaving them would
|
||||
have meant the new reader's own fields were never checked for reachability at all.
|
||||
|
||||
### R-295 hub half — one name per secret, and the mail names the page the machine shows
|
||||
|
||||
The box side shipped 2026-08-10; the hub side was dropped twice and was the last place the retired
|
||||
name survived — in the **mails**, the one surface a customer reads *before* they see any screen.
|
||||
|
||||
- the three-word dashboard code is **„Beállító kód"** everywhere: the mail bodies, the mail subjects,
|
||||
the operator button, and the lockout notice;
|
||||
- the ten-word escrow code stays **„Helyreállítási kód"**, and no dashboard-code mail names it —
|
||||
naming both secrets in one message is how a customer comes to believe they are the same thing;
|
||||
- **„Visszaállító kód" is retired.**
|
||||
|
||||
**New email kind `reenroll`, because the mail must name the page the machine is actually showing.**
|
||||
`ReissueForReenroll` sent the *reset* mail, which directs the customer to an „Elfelejtett jelszó"
|
||||
page — but a rebuilt box has no password, so the controller renders „A szerver beállítása"
|
||||
(`web/claim.go:279`, `reset := s.authEnabled()`) and serves **no login page at all**. The route named
|
||||
was not on their screen. Only the hub can tell the two situations apart, because it is the hub that
|
||||
chose which call site fired. Same secret, same name, different sentence — which is exactly what the
|
||||
ruling asks for. The re-enrol mail deliberately says **nothing** about apps or backups: a clean-slate
|
||||
reinstall is precisely where such a reassurance could be false.
|
||||
|
||||
**This is naming, not function.** No acceptance logic moved.
|
||||
`TestReenrollSplit_ChangesTheMailNotTheSecret` pins it: the generation still advances, the stored
|
||||
bcrypt hash still verifies the emailed code, no plaintext is persisted. On the box side the companion
|
||||
pin is the controller's `TestResetCode_StillAcceptedOnTheSetupPage`.
|
||||
|
||||
**Two red-proofs:** routing re-enrolment back to `EmailReset` reddens both the new pin and the
|
||||
pre-existing `TestReissueForReenroll`; putting „Visszaállító kód" back in the reset body reddens
|
||||
`TestFormatClaimEmail_OneNamePerSecret`.
|
||||
|
||||
**The claim guard has never scanned the hub.** `retrieval_promise_gate.py` lives in
|
||||
`felhom-controller/controller/scripts/` and its declared surfaces are that repo's templates plus one
|
||||
Go handler file. A scan of `felhom.eu/hub/` with the gate's own four stems returns **zero** — so
|
||||
nothing was hiding, and the new strings carry no stem and need no registration. That the gate's scope
|
||||
excludes a customer-facing surface is recorded as R-322 rather than fixed here.
|
||||
|
||||
### Also
|
||||
|
||||
- `wire_contract_gate.py` grows a **third** entry kind — `not consumed, deliberately` — carrying the
|
||||
operator's 2026-08-12 rulings with their date. Five facts move to it; `reporting_disabled` moves to
|
||||
`redundant`. **Those rulings were not in the register before today**, which is why R-264 now records
|
||||
them. Where the twenty stand: **8 read · 5 deliberately unread · 1 redundant · 6 still owed**.
|
||||
- **R-321 filed, not fixed:** the staleness checker is age-only, so a box on which reporting is
|
||||
deliberately switched off still alarms `node_stale` then `node_down`. Decoding `reporting_disabled`
|
||||
would have felt like progress and left the alarm firing; the fix belongs in the checker, which
|
||||
already holds the `health.status = "disabled"` it needs.
|
||||
|
||||
## v0.103.0 — a host can read the packages we kept for it (2026-08-12, R-311)
|
||||
|
||||
**`ListSupersededEscrow` had zero production callers for nineteen days.** It is the only reader of a
|
||||
retained `identity_blob`, and nothing called it — so the retention shipped in v0.93.0 was material the
|
||||
product could not reach. Proven on the fixture 2026-08-12: a recovery code that opens a retained
|
||||
package (unsealed by hand, and it restored planted files byte-identical from a store the box itself
|
||||
could no longer open) was answered by the product as a code that opened nothing.
|
||||
|
||||
**New: `GET /api/v1/hosts/<id>/escrow/retained`** — the retained siblings of the existing
|
||||
`/escrow` row, self-scoped to the asking host exactly as that one is, behind the same §8.3
|
||||
recovery-mode gate, and audited with the same `escrow_blob_served` event BEFORE the bytes leave.
|
||||
|
||||
**What it will not serve.** Rows whose `identity_blob` is NULL — every pre-v0.93.0 row — are withheld
|
||||
and returned as `unopenable_count` instead. They retain the PBS datastore key and not the repository
|
||||
password, so they can never open what the caller is asking about; serving them would have the agent
|
||||
try packages that cannot succeed and would let the recovery screen claim an earlier package is
|
||||
openable on exactly the boxes the original defect hurt. The count is returned because their EXISTENCE
|
||||
is load-bearing and underivable: on such a box a correct old code opens nothing, and the honest reason
|
||||
is a defect of ours rather than the customer's typing.
|
||||
|
||||
**The trade, stated rather than waved through.** The hub still cannot read any of it — sealed bytes in,
|
||||
sealed bytes out, no decrypt path, no recovery code ever held. What widens is VOLUME: a host key that
|
||||
could fetch one opaque package can now fetch N. Bounded by the same self-scope, the same recovery-mode
|
||||
gate, and an explicit `retainedEscrowServeCap` (16) so a long supersession history cannot become an
|
||||
unbounded read.
|
||||
|
||||
Pinned by six tests driven through the real endpoint, with four red-proofs each asserted to have
|
||||
applied: serving the CURRENT row instead (count 2→1), dropping the unopenable guard (count 1→2,
|
||||
unopenable 1→0), dropping self-scope (403→200), and collapsing the route suffix (count 1→0).
|
||||
|
||||
---
|
||||
|
||||
## v0.102.0 — the hub refuses to vouch a version that cannot be installed (2026-08-09, R-273)
|
||||
|
||||
**The guard owed since 2026-08-09 morning.** Agent v0.128.0 had been published as a package and never
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-hub/internal/store"
|
||||
)
|
||||
|
||||
// R-311 (v0.103.0) — GET /hosts/<id>/escrow/retained.
|
||||
//
|
||||
// WHY THESE TESTS EXIST. `ListSupersededEscrow` had zero production callers for nineteen days; the
|
||||
// retention it reads was proven on 2026-08-12 to hold the right material and to open a store the box
|
||||
// itself could not, while the customer was told their (correct) code opened nothing. These tests pin
|
||||
// the endpoint that ends that, and — more importantly — they pin the two things it must NOT do:
|
||||
// serve a package that cannot be opened, and let one host read another's.
|
||||
|
||||
type retainedResp struct {
|
||||
HostID string `json:"host_id"`
|
||||
Count int `json:"count"`
|
||||
UnopenableCount int `json:"unopenable_count"`
|
||||
TruncatedCount int `json:"truncated_count"`
|
||||
Packages []struct {
|
||||
Index int `json:"index"`
|
||||
SupersededAt string `json:"superseded_at"`
|
||||
KeyFingerprint string `json:"key_fingerprint"`
|
||||
IdentityEscrowB64 string `json:"identity_escrow_b64"`
|
||||
} `json:"packages"`
|
||||
}
|
||||
|
||||
func getRetained(t *testing.T, h *Handler, hostID, key string) (int, retainedResp) {
|
||||
t.Helper()
|
||||
rr := do(h, http.MethodGet, "/hosts/"+hostID+"/escrow/retained", key, "")
|
||||
var out retainedResp
|
||||
if rr.Code == http.StatusOK {
|
||||
if err := json.Unmarshal(rr.Body.Bytes(), &out); err != nil {
|
||||
t.Fatalf("decode retained response: %v (body %s)", err, rr.Body.String())
|
||||
}
|
||||
}
|
||||
return rr.Code, out
|
||||
}
|
||||
|
||||
// seedSuperseded drives the REAL supersession path (a PUT sealing a different password demotes the
|
||||
// current row) rather than inserting into host_escrow_superseded directly — so what the test proves
|
||||
// includes the demote wiring, not just this handler's SELECT.
|
||||
func seedSuperseded(t *testing.T, h *Handler, hostID, key string, gens []struct{ sha, identity string }) {
|
||||
t.Helper()
|
||||
for i, g := range gens {
|
||||
if rr := do(h, http.MethodPut, "/hosts/"+hostID+"/escrow", key, escrowBodyWithHash([]byte("k"), g.sha, g.identity)); rr.Code != http.StatusOK {
|
||||
t.Fatalf("seed PUT %d = %d (%s)", i, rr.Code, rr.Body.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// THE ONE THAT MATTERS: a retained package that carries key material is served, and the caller can
|
||||
// tell it apart from the current row.
|
||||
//
|
||||
// RED-PROOF: change the handler's SELECT source from ListSupersededEscrow to GetHostDRBundle (i.e.
|
||||
// serve the CURRENT row) → the served blob becomes "age-gen3" → this FAILS on the body comparison,
|
||||
// which is exactly the confusion the endpoint exists to end.
|
||||
func TestRetainedEscrowGet_ServesRetainedPackages(t *testing.T) {
|
||||
h, st, _ := newTestHandler(t)
|
||||
st.UpsertHost(&store.Host{HostID: "h1", CustomerID: "c1", APIKey: "HKEY"})
|
||||
seedSuperseded(t, h, "h1", "HKEY", []struct{ sha, identity string }{
|
||||
{"SHA_GEN1", "age-gen1"},
|
||||
{"SHA_GEN2", "age-gen2"},
|
||||
{"SHA_GEN3", "age-gen3"}, // current after this
|
||||
})
|
||||
|
||||
code, out := getRetained(t, h, "h1", "HKEY")
|
||||
if code != http.StatusOK {
|
||||
t.Fatalf("GET retained = %d, want 200", code)
|
||||
}
|
||||
if out.Count != 2 || len(out.Packages) != 2 {
|
||||
t.Fatalf("want 2 retained packages, got count=%d len=%d", out.Count, len(out.Packages))
|
||||
}
|
||||
if out.UnopenableCount != 0 {
|
||||
t.Errorf("unopenable_count = %d, want 0 (every seeded row carried an identity blob)", out.UnopenableCount)
|
||||
}
|
||||
// The retained packages must be the SUPERSEDED generations, never the current one. If this ever
|
||||
// serves gen3 the endpoint is answering the wrong question and the customer is misled again.
|
||||
got := map[string]bool{}
|
||||
for _, p := range out.Packages {
|
||||
b, err := base64.StdEncoding.DecodeString(p.IdentityEscrowB64)
|
||||
if err != nil {
|
||||
t.Fatalf("package %d: identity blob is not base64: %v", p.Index, err)
|
||||
}
|
||||
got[string(b)] = true
|
||||
if p.SupersededAt == "" {
|
||||
t.Errorf("package %d has no superseded_at — the screen needs a date to name the package", p.Index)
|
||||
}
|
||||
}
|
||||
if !got["age-gen1"] || !got["age-gen2"] {
|
||||
t.Errorf("served packages = %v, want the two SUPERSEDED generations (age-gen1, age-gen2)", got)
|
||||
}
|
||||
if got["age-gen3"] {
|
||||
t.Error("the CURRENT package was served as retained — that is the wrong-package confusion this endpoint exists to end")
|
||||
}
|
||||
}
|
||||
|
||||
// A retained row with NO identity blob (every pre-v0.93.0 row) must be WITHHELD and COUNTED. Serving
|
||||
// it would have the agent try a package that cannot open anything, and would let the screen claim an
|
||||
// earlier package is recoverable on exactly the boxes hurt by the original defect.
|
||||
//
|
||||
// RED-PROOF: delete the `if len(e.IdentityBlob) == 0 { unopenable++; continue }` guard → the empty
|
||||
// row is served as a package → Count becomes 2 and UnopenableCount 0 → this FAILS twice.
|
||||
func TestRetainedEscrowGet_WithholdsAndCountsUnopenableRows(t *testing.T) {
|
||||
h, st, _ := newTestHandler(t)
|
||||
st.UpsertHost(&store.Host{HostID: "h1", CustomerID: "c1", APIKey: "HKEY"})
|
||||
// gen1 carries NO identity blob — the pre-v0.93.0 shape.
|
||||
seedSuperseded(t, h, "h1", "HKEY", []struct{ sha, identity string }{
|
||||
{"SHA_GEN1", ""},
|
||||
{"SHA_GEN2", "age-gen2"},
|
||||
{"SHA_GEN3", "age-gen3"},
|
||||
})
|
||||
|
||||
code, out := getRetained(t, h, "h1", "HKEY")
|
||||
if code != http.StatusOK {
|
||||
t.Fatalf("GET retained = %d, want 200", code)
|
||||
}
|
||||
if out.Count != 1 {
|
||||
t.Errorf("count = %d, want 1 (only gen2 carries material)", out.Count)
|
||||
}
|
||||
if out.UnopenableCount != 1 {
|
||||
t.Errorf("unopenable_count = %d, want 1 — the caller cannot derive this and needs it to explain "+
|
||||
"why a correct old code opens nothing on such a box", out.UnopenableCount)
|
||||
}
|
||||
for _, p := range out.Packages {
|
||||
if p.IdentityEscrowB64 == "" {
|
||||
t.Error("a package with an empty identity blob was served — it can never open anything")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SELF-SCOPE. The current-row GET has this and a retained read is strictly more material, so the same
|
||||
// asymmetry must hold: a host key reads only its own.
|
||||
//
|
||||
// RED-PROOF: remove the `!isGlobal && authHostID != pathHostID` branch → h2's key reads h1's packages
|
||||
// → this FAILS with 200.
|
||||
func TestRetainedEscrowGet_SelfScoped(t *testing.T) {
|
||||
h, st, _ := newTestHandler(t)
|
||||
st.UpsertHost(&store.Host{HostID: "h1", CustomerID: "c1", APIKey: "HKEY1"})
|
||||
st.UpsertHost(&store.Host{HostID: "h2", CustomerID: "c2", APIKey: "HKEY2"})
|
||||
seedSuperseded(t, h, "h1", "HKEY1", []struct{ sha, identity string }{
|
||||
{"SHA_GEN1", "age-gen1"},
|
||||
{"SHA_GEN2", "age-gen2"},
|
||||
})
|
||||
|
||||
rr := do(h, http.MethodGet, "/hosts/h1/escrow/retained", "HKEY2", "")
|
||||
if rr.Code != http.StatusForbidden {
|
||||
t.Fatalf("h2 reading h1's retained packages = %d, want 403 — a host key must never be a fleet-wide reader", rr.Code)
|
||||
}
|
||||
}
|
||||
|
||||
// A host that has never re-sealed gets a clean, empty answer — not a 404 and not a fault. "No retained
|
||||
// package" is an ordinary situation and must be distinguishable from "something is broken", or the
|
||||
// agent's try-loop cannot tell them apart either.
|
||||
//
|
||||
// RED-PROOF: make the handler 404 on an empty list → this FAILS with 404.
|
||||
func TestRetainedEscrowGet_NoneIsACleanEmptyAnswer(t *testing.T) {
|
||||
h, st, _ := newTestHandler(t)
|
||||
st.UpsertHost(&store.Host{HostID: "h1", CustomerID: "c1", APIKey: "HKEY"})
|
||||
if rr := do(h, http.MethodPut, "/hosts/h1/escrow", "HKEY", escrowBodyWithHash([]byte("k"), "SHA1", "age-1")); rr.Code != http.StatusOK {
|
||||
t.Fatalf("seed PUT = %d", rr.Code)
|
||||
}
|
||||
|
||||
code, out := getRetained(t, h, "h1", "HKEY")
|
||||
if code != http.StatusOK {
|
||||
t.Fatalf("GET retained on a never-superseded host = %d, want 200", code)
|
||||
}
|
||||
if out.Count != 0 || len(out.Packages) != 0 || out.UnopenableCount != 0 {
|
||||
t.Errorf("want an empty answer, got count=%d packages=%d unopenable=%d", out.Count, len(out.Packages), out.UnopenableCount)
|
||||
}
|
||||
}
|
||||
|
||||
// The retained route must not be reachable without a key at all.
|
||||
//
|
||||
// RED-PROOF: drop the checkAuthHost block → this FAILS with 200.
|
||||
func TestRetainedEscrowGet_RequiresAuth(t *testing.T) {
|
||||
h, st, _ := newTestHandler(t)
|
||||
st.UpsertHost(&store.Host{HostID: "h1", CustomerID: "c1", APIKey: "HKEY"})
|
||||
if rr := do(h, http.MethodGet, "/hosts/h1/escrow/retained", "", ""); rr.Code != http.StatusUnauthorized {
|
||||
t.Fatalf("unauthenticated retained GET = %d, want 401", rr.Code)
|
||||
}
|
||||
}
|
||||
|
||||
// ROUTING: /escrow and /escrow/retained must stay two different answers. A prefix "tidy-up" that
|
||||
// collapsed them would route retained reads to the current row — silently the wrong package.
|
||||
//
|
||||
// RED-PROOF: change the retained case's suffix to "/escrow" (so the earlier case wins) → the retained
|
||||
// route returns the CURRENT-row shape, which has no "packages" key → this FAILS.
|
||||
func TestRetainedEscrowGet_IsADistinctRouteFromTheCurrentRow(t *testing.T) {
|
||||
h, st, _ := newTestHandler(t)
|
||||
st.UpsertHost(&store.Host{HostID: "h1", CustomerID: "c1", APIKey: "HKEY"})
|
||||
seedSuperseded(t, h, "h1", "HKEY", []struct{ sha, identity string }{
|
||||
{"SHA_GEN1", "age-gen1"},
|
||||
{"SHA_GEN2", "age-gen2"},
|
||||
})
|
||||
|
||||
cur := do(h, http.MethodGet, "/hosts/h1/escrow", "HKEY", "")
|
||||
var curBody map[string]any
|
||||
if err := json.Unmarshal(cur.Body.Bytes(), &curBody); err != nil {
|
||||
t.Fatalf("decode current-row body: %v", err)
|
||||
}
|
||||
if _, hasPackages := curBody["packages"]; hasPackages {
|
||||
t.Error("the CURRENT-row route grew a packages key — the two routes have been merged")
|
||||
}
|
||||
if _, hasPresent := curBody["present"]; !hasPresent {
|
||||
t.Error("the current-row route lost its present flag")
|
||||
}
|
||||
|
||||
_, ret := getRetained(t, h, "h1", "HKEY")
|
||||
if ret.Count != 1 {
|
||||
t.Fatalf("retained route count = %d, want 1 — it is answering the current row's question", ret.Count)
|
||||
}
|
||||
}
|
||||
@@ -245,6 +245,13 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
case r.Method == http.MethodGet && strings.HasPrefix(path, "/hosts/") && strings.HasSuffix(path, "/escrow"):
|
||||
hostID := strings.TrimSuffix(strings.TrimPrefix(path, "/hosts/"), "/escrow")
|
||||
h.handleHostEscrowGet(w, r, hostID)
|
||||
// R-311 (v0.103.0): the RETAINED siblings of the row above. The two cases cannot collide — one
|
||||
// ends `/escrow`, the other `/escrow/retained` — but do NOT "tidy" them into a single prefix
|
||||
// match: a prefix match would route retained reads to the CURRENT row, which is silently the
|
||||
// wrong package and is exactly the confusion this endpoint exists to end.
|
||||
case r.Method == http.MethodGet && strings.HasPrefix(path, "/hosts/") && strings.HasSuffix(path, "/escrow/retained"):
|
||||
hostID := strings.TrimSuffix(strings.TrimPrefix(path, "/hosts/"), "/escrow/retained")
|
||||
h.handleHostEscrowRetainedGet(w, r, hostID)
|
||||
// G1 break-glass: day-0 vaults the root@pam console credential (self-scoped host key); the
|
||||
// operator retrieves it via the /admin/ path (global key only).
|
||||
case r.Method == http.MethodPut && strings.HasPrefix(path, "/hosts/") && strings.HasSuffix(path, "/recovery-credential"):
|
||||
@@ -1371,6 +1378,158 @@ func (h *Handler) handleHostEscrowGet(w http.ResponseWriter, r *http.Request, pa
|
||||
})
|
||||
}
|
||||
|
||||
// handleHostEscrowRetainedGet serves a host its own RETAINED (superseded) sealed identity packages.
|
||||
//
|
||||
// ── WHY THIS EXISTS (R-311) ─────────────────────────────────────────────────────────────────────
|
||||
//
|
||||
// `ListSupersededEscrow` has been the only reader of a retained identity blob since v0.93.0 and had
|
||||
// ZERO production callers — every call site was a test. The consequence, measured on the fixture
|
||||
// 2026-08-12: a recovery code that demonstrably opens a retained package (proven by hand: unsealed,
|
||||
// and it restored planted files byte-identical from a store the box could no longer open) was
|
||||
// reported to the customer as a code that opened nothing. The screen already hedged that with two
|
||||
// possible causes (R-222/R-226) and said it could not tell them apart. **It could not tell them
|
||||
// apart because nothing ever looked.** This endpoint is what makes looking possible.
|
||||
//
|
||||
// ── WHAT THIS DOES NOT CHANGE ───────────────────────────────────────────────────────────────────
|
||||
//
|
||||
// The hub still cannot read any of it. Sealed bytes in, sealed bytes out; there is no decrypt path
|
||||
// here and the hub has never held a recovery code. What DOES widen is volume: a host key that could
|
||||
// previously fetch one opaque package can now fetch N. The trade is stated rather than waved through
|
||||
// — see the audit — and it is bounded three ways: the same self-scope as the current row, the same
|
||||
// recovery-mode gate, and an explicit cap so a host with a long supersession history cannot turn one
|
||||
// request into an unbounded read.
|
||||
//
|
||||
// Rows whose `identity_blob` is NULL are NOT served and are counted separately. They are the
|
||||
// pre-v0.93.0 rows; they retain the PBS key and not the repository password, so they can never open
|
||||
// anything the caller is asking about. Serving them would make the agent try packages that cannot
|
||||
// succeed and would let the screen claim an earlier package is openable when it is not — the same
|
||||
// false-explanation trap `SupersededPresent` already avoids at store.go. They are counted because
|
||||
// their EXISTENCE is a true and load-bearing fact: on those boxes a correct old code opens nothing,
|
||||
// and the honest reason is a defect of ours, not the customer's typing.
|
||||
const retainedEscrowServeCap = 16
|
||||
|
||||
// RetainedEscrowPackage / RetainedEscrowResponse are the WIRE for GET /hosts/<id>/escrow/retained.
|
||||
//
|
||||
// They are named types rather than a `map[string]any` on purpose: the wire-contract gate resolves a
|
||||
// declared ROOT by TYPE, so an untyped map is a cross-repo contract the gate cannot see. This wire is
|
||||
// declared in `scripts/wire_contract_gate.py` ROOTS — hub → agent — and the agent's mirror is
|
||||
// `felhom-agent/internal/hub.RetainedEscrowResponse`. Change a tag here and the gate fails there,
|
||||
// which is the entire point.
|
||||
type RetainedEscrowPackage struct {
|
||||
// Index is a label WITHIN ONE RESPONSE. Not durable, never persisted, never a lookup key.
|
||||
Index int `json:"index"`
|
||||
// SupersededAt is when this package stopped being the current one. It is the only field here a
|
||||
// customer ever sees — it is how they recognise which recovery code they are holding.
|
||||
SupersededAt string `json:"superseded_at"`
|
||||
KeyFingerprint string `json:"key_fingerprint"`
|
||||
// IdentityEscrowB64 is OPAQUE ciphertext. The hub cannot open it and never could.
|
||||
IdentityEscrowB64 string `json:"identity_escrow_b64"`
|
||||
}
|
||||
|
||||
type RetainedEscrowResponse struct {
|
||||
HostID string `json:"host_id"`
|
||||
Count int `json:"count"`
|
||||
// UnopenableCount is the number of retained rows withheld because they carry no key material
|
||||
// (every pre-v0.93.0 row). Underivable by the caller and load-bearing: on a box with only those,
|
||||
// a perfectly correct old code opens nothing and the reason is a defect of ours.
|
||||
UnopenableCount int `json:"unopenable_count"`
|
||||
TruncatedCount int `json:"truncated_count"`
|
||||
Packages []RetainedEscrowPackage `json:"packages"`
|
||||
}
|
||||
|
||||
func (h *Handler) handleHostEscrowRetainedGet(w http.ResponseWriter, r *http.Request, pathHostID string) {
|
||||
authHostID, _, isGlobal, ok := h.checkAuthHost(r)
|
||||
if !ok {
|
||||
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
if pathHostID == "" {
|
||||
http.Error(w, "Missing host_id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
// SELF-SCOPED, identically to the current-row GET. Without this line any host key is a fleet-wide
|
||||
// reader of every retained package, which is strictly worse than the same hole on one row.
|
||||
if !isGlobal && authHostID != pathHostID {
|
||||
h.logger.Printf("[WARN] retained escrow GET REFUSED: host %s asked for %s's packages (self-scope)", authHostID, pathHostID)
|
||||
http.Error(w, "Forbidden: host_id mismatch", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
host, err := h.store.GetHost(pathHostID)
|
||||
if err != nil {
|
||||
http.Error(w, "Internal error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if host == nil {
|
||||
http.Error(w, "Unknown host_id", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
// The SAME §8.3 gate as the current row. A retained package is not less sensitive than the
|
||||
// current one; if self-service retrieval is ever switched off, it must go dark with it.
|
||||
if !escrowSelfServiceRetrieval && !host.InRecoveryMode(time.Now().UTC()) {
|
||||
h.logger.Printf("[WARN] retained escrow GET REFUSED for %s — self-service retrieval is disabled and recovery mode is not armed", pathHostID)
|
||||
http.Error(w, "Forbidden: host not in recovery mode (operator must arm it)", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
retained, rerr := h.store.ListSupersededEscrow(pathHostID)
|
||||
if rerr != nil {
|
||||
h.logger.Printf("[ERROR] retained escrow GET for %s: %v", pathHostID, rerr)
|
||||
http.Error(w, "Internal error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
packages := make([]RetainedEscrowPackage, 0, len(retained))
|
||||
unopenable := 0
|
||||
for _, e := range retained {
|
||||
if len(e.IdentityBlob) == 0 {
|
||||
unopenable++
|
||||
continue
|
||||
}
|
||||
if len(packages) >= retainedEscrowServeCap {
|
||||
continue
|
||||
}
|
||||
packages = append(packages, RetainedEscrowPackage{
|
||||
Index: len(packages),
|
||||
SupersededAt: e.UpdatedAt,
|
||||
KeyFingerprint: e.KeyFingerprint,
|
||||
IdentityEscrowB64: base64.StdEncoding.EncodeToString(e.IdentityBlob),
|
||||
})
|
||||
}
|
||||
truncated := 0
|
||||
if n := len(retained) - unopenable; n > len(packages) {
|
||||
truncated = n - len(packages)
|
||||
}
|
||||
|
||||
// The audit row is written BEFORE the bytes leave, exactly as the current-row GET does, so a
|
||||
// retrieval cannot be served without its record. Severity matches that path deliberately: this is
|
||||
// a recovery in progress and nothing else, and it must reach the operator by e-mail.
|
||||
if host.CustomerID != "" && len(packages) > 0 {
|
||||
msg := fmt.Sprintf("Retained recovery packages served: host %s retrieved %d retained sealed package(s) (%d unopenable pre-v0.93.0 row(s) withheld). "+
|
||||
"This is the recovery path in use — the packages cannot be opened without the customer's recovery code, which the hub never holds. "+
|
||||
"If no recovery is in progress on that box, investigate.", pathHostID, len(packages), unopenable)
|
||||
details, _ := json.Marshal(map[string]any{
|
||||
"host_id": pathHostID,
|
||||
"served": len(packages),
|
||||
"unopenable": unopenable,
|
||||
"truncated": truncated,
|
||||
"self_scope": !isGlobal,
|
||||
})
|
||||
if _, eerr := h.store.SaveEvent(host.CustomerID, eventEscrowBlobServed, "warning", msg, string(details), "hub"); eerr != nil {
|
||||
h.logger.Printf("[WARN] %s event save FAILED for %s (serving anyway): %v", eventEscrowBlobServed, pathHostID, eerr)
|
||||
} else if h.dispatcher != nil {
|
||||
go h.dispatcher.ProcessEvent(host.CustomerID, eventEscrowBlobServed, "warning", msg, string(details), "hub")
|
||||
}
|
||||
}
|
||||
h.logger.Printf("[WARN] retained escrow SERVED to host %s (%d package(s), %d unopenable withheld, %d over cap, self_scope=%v)",
|
||||
pathHostID, len(packages), unopenable, truncated, !isGlobal)
|
||||
writeJSON(w, http.StatusOK, RetainedEscrowResponse{
|
||||
HostID: pathHostID,
|
||||
Count: len(packages),
|
||||
UnopenableCount: unopenable,
|
||||
TruncatedCount: truncated,
|
||||
Packages: packages,
|
||||
})
|
||||
}
|
||||
|
||||
// maybeEmitRepoKeyChanged raises ONE operator signal per supersession when the sealed offsite repo
|
||||
// password demonstrably changed. Both hashes have been stored since SLICE 3 (host_escrow and, since
|
||||
// v0.60.0, host_escrow_superseded) and NOTHING compared them: demo-felhom's repository password
|
||||
|
||||
@@ -29,8 +29,21 @@ type EmailKind string
|
||||
|
||||
const (
|
||||
EmailClaim EmailKind = "claim" // first setup: "Elindult a Felhom szervered"
|
||||
EmailReset EmailKind = "reset" // forgotten password
|
||||
EmailReset EmailKind = "reset" // forgotten password — the box HAS a password
|
||||
EmailClaimed EmailKind = "claimed" // confirmation after a successful claim (carries no code)
|
||||
// EmailReenroll — the box was wiped and re-enrolled, so the fresh controller has NO password
|
||||
// while the hub-side claim is still set (ReissueForReenroll).
|
||||
//
|
||||
// R-295 (hub half, 2026-08-13): THIS EXISTS BECAUSE THE MAIL MUST NAME THE PAGE THE MACHINE IS
|
||||
// ACTUALLY SHOWING. Both situations deliver the same secret and it keeps the same name — the
|
||||
// three-word „Beállító kód" — but they do NOT show the same screen, and only the hub can tell
|
||||
// them apart, because it is the hub that chose which call site fired. A rebuilt box renders
|
||||
// „A szerver beállítása" (controller `web/claim.go:279`: `reset := s.authEnabled()`, and a fresh
|
||||
// controller has no password), and it serves no login page — so it has no „Elfelejtett jelszó"
|
||||
// link at all. Sending a re-enrolled customer to that page names a route that is not on their
|
||||
// screen. Splitting the KIND rather than the NAME is what the ruling asks for: one secret in two
|
||||
// situations keeps its name, and the sentence around it changes.
|
||||
EmailReenroll EmailKind = "reenroll"
|
||||
)
|
||||
|
||||
// Mailer delivers a claim-arc email. The code is passed through and MUST NOT be persisted or
|
||||
@@ -178,7 +191,8 @@ func (e *Engine) ReissueForReenroll(cc *store.CustomerConfig) (gen int, reissued
|
||||
if cs == nil || !cs.Claimed() {
|
||||
return 0, false, nil // unclaimed → first-provision path; nothing to re-issue
|
||||
}
|
||||
gen, err = e.rotateAndSend(cc, EmailReset)
|
||||
// EmailReenroll, not EmailReset: same secret, same name, different screen — see the constant.
|
||||
gen, err = e.rotateAndSend(cc, EmailReenroll)
|
||||
if err != nil {
|
||||
return gen, true, err // reissued=true so the caller records the attempt even on email failure
|
||||
}
|
||||
|
||||
@@ -166,8 +166,14 @@ func TestReissueForReenroll(t *testing.T) {
|
||||
if !cs.Claimed() {
|
||||
t.Fatal("re-issue must NEVER un-claim (reset rides rotation)")
|
||||
}
|
||||
if len(m.sends) != sendsBefore+1 || !strings.HasPrefix(m.sends[len(m.sends)-1], "reset:") {
|
||||
t.Fatalf("claimed re-enroll must send exactly one RESET email, got %v", m.sends)
|
||||
// R-295 hub half (2026-08-13): this used to assert "reset:". The KIND was split — same
|
||||
// secret, same name („Beállító kód"), different SENTENCE — because a rebuilt box has no
|
||||
// password, so it shows „A szerver beállítása" and serves no login page, and the reset mail
|
||||
// sent the customer to an „Elfelejtett jelszó" page that is not on their screen. The
|
||||
// assertion is deliberately kept STRICT rather than loosened to "either kind": routing a
|
||||
// re-enrolment back down the reset copy is exactly the regression worth failing on.
|
||||
if len(m.sends) != sendsBefore+1 || !strings.HasPrefix(m.sends[len(m.sends)-1], "reenroll:") {
|
||||
t.Fatalf("claimed re-enroll must send exactly one REENROLL email, got %v", m.sends)
|
||||
}
|
||||
})
|
||||
t.Run("unclaimed is a no-op (first-provision path)", func(t *testing.T) {
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
package claim
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-hub/internal/notify"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
// ── R-295, HUB HALF — ONE NAME PER SECRET, AND THE MAIL NAMES THE PAGE THE MACHINE SHOWS ────────
|
||||
//
|
||||
// Two different secrets were both called „Visszaállító kód": the THREE-word code that gives a person
|
||||
// control of the dashboard, and the TEN-word code that opens the sealed off-site backups. They are
|
||||
// near-homographs of each other and of „Helyreállítási kód", and the collision cost a real code. The
|
||||
// box side shipped on 2026-08-10; the hub side was dropped twice and was the last place the retired
|
||||
// name survived — in the mails, which is the one surface a customer reads BEFORE they see any screen.
|
||||
//
|
||||
// The ruling these tests pin:
|
||||
// - the three-word dashboard code is „Beállító kód" everywhere;
|
||||
// - the ten-word escrow code is „Helyreállítási kód";
|
||||
// - „Visszaállító kód" is RETIRED;
|
||||
// - one secret in two situations keeps its NAME and changes its SENTENCE;
|
||||
// - the mail names the page the machine is ACTUALLY SHOWING.
|
||||
//
|
||||
// THIS IS NAMING, NOT FUNCTION — TestReenrollSplit_ChangesTheMailNotTheSecret is the pin that says
|
||||
// so. On the box side the companion pin is the controller's
|
||||
// TestResetCode_StillAcceptedOnTheSetupPage (claim_code_naming_test.go).
|
||||
|
||||
const retiredName = "Visszaállító kód"
|
||||
|
||||
// The three code-bearing mails all name the secret „Beállító kód", and none of them carries the
|
||||
// retired name. The escrow code's name must not appear in a dashboard-code mail either: naming both
|
||||
// secrets in one message is how a customer comes to believe they are the same thing.
|
||||
func TestFormatClaimEmail_OneNamePerSecret(t *testing.T) {
|
||||
for _, kind := range []EmailKind{EmailClaim, EmailReset, EmailReenroll} {
|
||||
subject, body := notify.FormatClaimEmail(string(kind), "c1", "example.hu", "alma-korte-szilva")
|
||||
whole := subject + "\n" + body
|
||||
|
||||
if !strings.Contains(body, "Beállító kód: alma-korte-szilva") {
|
||||
t.Errorf("%s: the secret must be labelled „Beállító kód”; body was:\n%s", kind, body)
|
||||
}
|
||||
if strings.Contains(whole, retiredName) {
|
||||
t.Errorf("%s: the retired name „%s” is back (subject or body)", kind, retiredName)
|
||||
}
|
||||
if strings.Contains(whole, "Helyreállítási kód") {
|
||||
t.Errorf("%s: names the ESCROW code in a dashboard-code mail — that is the collision", kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The two situations that deliver the SAME secret must not name the SAME page, because the machine
|
||||
// does not show the same page. A box that still has a password shows a login screen carrying an
|
||||
// „Elfelejtett jelszó" link; a REBUILT box has no password, renders „A szerver beállítása" and serves
|
||||
// no login page at all (controller web/claim.go:279 — `reset := s.authEnabled()`).
|
||||
//
|
||||
// Sending a re-enrolled customer to „Elfelejtett jelszó" names a route that is not on their screen.
|
||||
// That was the live defect, and this is the test that would have caught it.
|
||||
func TestFormatClaimEmail_NamesThePageTheMachineShows(t *testing.T) {
|
||||
_, resetBody := notify.FormatClaimEmail(string(EmailReset), "c1", "example.hu", "a-b-c")
|
||||
if !strings.Contains(resetBody, `"Elfelejtett jelszó"`) {
|
||||
t.Errorf("the forgot-password mail should name the page that IS on that customer's screen:\n%s", resetBody)
|
||||
}
|
||||
|
||||
_, reBody := notify.FormatClaimEmail(string(EmailReenroll), "c1", "example.hu", "a-b-c")
|
||||
if strings.Contains(reBody, "Elfelejtett jelszó") {
|
||||
t.Errorf("a REBUILT box serves no login page, so it has no „Elfelejtett jelszó” link:\n%s", reBody)
|
||||
}
|
||||
if !strings.Contains(reBody, `"A szerver beállítása"`) {
|
||||
t.Errorf("the re-enrol mail must name the page a rebuilt box actually shows:\n%s", reBody)
|
||||
}
|
||||
}
|
||||
|
||||
// The re-enrol mail must promise nothing about the customer's apps or backups. A clean-slate
|
||||
// reinstall is exactly the situation in which such a reassurance could be false, and this project has
|
||||
// spent four register rows (R-294, R-299, R-302, R-311) removing promises it could not see were still
|
||||
// true. Guarding the CLAIM rather than one phrasing of it: any sentence that says the backups are
|
||||
// unaffected would have to say so with one of these stems.
|
||||
func TestFormatClaimEmail_ReenrollPromisesNothingAboutTheData(t *testing.T) {
|
||||
_, body := notify.FormatClaimEmail(string(EmailReenroll), "c1", "example.hu", "a-b-c")
|
||||
for _, claimWord := range []string{"mentés", "biztonsági", "alkalmazás", "adataid", "visszaállíthat", "visszaszerezhet"} {
|
||||
if strings.Contains(body, claimWord) {
|
||||
t.Errorf("the re-enrol mail must not talk about data or backups (found %q):\n%s", claimWord, body)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// An unrecognised kind falls through to the first-setup mail. That default is SAFE (a rebuilt box
|
||||
// really is in a setup state) and it is deliberately asserted, because it is the failure mode of
|
||||
// adding a kind on the engine side and forgetting the template: nothing panics, nothing errors, and
|
||||
// the wrong-but-harmless mail goes out. Pinning it means a future reader knows it was chosen.
|
||||
func TestFormatClaimEmail_UnknownKindFallsBackToSetup(t *testing.T) {
|
||||
subject, body := notify.FormatClaimEmail("no-such-kind", "c1", "example.hu", "a-b-c")
|
||||
if !strings.Contains(subject, "Elindult a Felhom szervered") {
|
||||
t.Errorf("unknown kind should fall back to the first-setup mail, got subject %q", subject)
|
||||
}
|
||||
if strings.Contains(subject+body, retiredName) {
|
||||
t.Errorf("the fallback carries the retired name")
|
||||
}
|
||||
}
|
||||
|
||||
// THE ACCEPTANCE PIN. Splitting the mail KIND must not touch the secret: ReissueForReenroll still
|
||||
// rotates the generation, still stores a bcrypt hash that verifies the emailed code, and still stores
|
||||
// no plaintext — byte-for-byte the same custody as the reset path it was split out of. A rename that
|
||||
// quietly broke acceptance would be far worse than the collision it fixes.
|
||||
func TestReenrollSplit_ChangesTheMailNotTheSecret(t *testing.T) {
|
||||
e, st, m := newTestEngine(t)
|
||||
cc := cust()
|
||||
if _, err := e.EnsureIssued(cc); err != nil {
|
||||
t.Fatalf("EnsureIssued: %v", err)
|
||||
}
|
||||
if err := e.MarkClaimed(cc); err != nil {
|
||||
t.Fatalf("MarkClaimed: %v", err)
|
||||
}
|
||||
before, err := st.GetClaim(cc.CustomerID)
|
||||
if err != nil {
|
||||
t.Fatalf("GetClaim: %v", err)
|
||||
}
|
||||
|
||||
gen, reissued, err := e.ReissueForReenroll(cc)
|
||||
if err != nil || !reissued {
|
||||
t.Fatalf("ReissueForReenroll: gen=%d reissued=%v err=%v", gen, reissued, err)
|
||||
}
|
||||
|
||||
// It is the re-enrol mail, not the reset mail — the whole point of the split.
|
||||
last := m.sends[len(m.sends)-1]
|
||||
if !strings.HasPrefix(last, string(EmailReenroll)+":") {
|
||||
t.Errorf("a re-enrolled box must get the reenroll mail, got %q", last)
|
||||
}
|
||||
|
||||
// …and the secret behaves exactly as before: generation advanced, the stored hash verifies the
|
||||
// newly emailed code, the previous code no longer verifies, and no plaintext is persisted.
|
||||
after, err := st.GetClaim(cc.CustomerID)
|
||||
if err != nil {
|
||||
t.Fatalf("GetClaim after: %v", err)
|
||||
}
|
||||
if after.Generation != before.Generation+1 {
|
||||
t.Errorf("generation %d → %d, want +1", before.Generation, after.Generation)
|
||||
}
|
||||
if bcrypt.CompareHashAndPassword([]byte(after.CodeHash), []byte(m.lastCode)) != nil {
|
||||
t.Error("the stored hash does not verify the emailed code — acceptance moved")
|
||||
}
|
||||
if strings.Contains(after.CodeHash, m.lastCode) {
|
||||
t.Error("the stored hash contains the plaintext code")
|
||||
}
|
||||
}
|
||||
|
||||
// RequestReset — a customer who still has a password — must keep sending the RESET mail. The split
|
||||
// must not have swept the genuine forgot-password path along with it: that customer IS looking at a
|
||||
// login page, and „Elfelejtett jelszó" is the right thing to name for them.
|
||||
func TestRequestReset_StillSendsTheResetMail(t *testing.T) {
|
||||
e, _, m := newTestEngine(t)
|
||||
cc := cust()
|
||||
if _, err := e.EnsureIssued(cc); err != nil {
|
||||
t.Fatalf("EnsureIssued: %v", err)
|
||||
}
|
||||
if err := e.MarkClaimed(cc); err != nil {
|
||||
t.Fatalf("MarkClaimed: %v", err)
|
||||
}
|
||||
if err := e.RequestReset(cc); err != nil {
|
||||
t.Fatalf("RequestReset: %v", err)
|
||||
}
|
||||
last := m.sends[len(m.sends)-1]
|
||||
if !strings.HasPrefix(last, string(EmailReset)+":") {
|
||||
t.Errorf("a forgot-password request must still send the reset mail, got %q", last)
|
||||
}
|
||||
}
|
||||
@@ -324,6 +324,16 @@ func init() {
|
||||
//
|
||||
// Customers whose nodes are "down" (no report in >1h) are skipped — they
|
||||
// already have staleness events.
|
||||
// stalenessState reads a customer's staleness state, tolerating a nil checker. Named rather than
|
||||
// inlined so the two states this function skips on are visible in one place — a second caller adding
|
||||
// a third state must not have to rediscover that the nil check exists.
|
||||
func stalenessState(staleness *StalenessChecker, customerID string) string {
|
||||
if staleness == nil {
|
||||
return ""
|
||||
}
|
||||
return staleness.GetState(customerID)
|
||||
}
|
||||
|
||||
func CheckBackupDeadlines(s *store.Store, staleness *StalenessChecker, onEvent EventNotifyFunc, logger *log.Logger) {
|
||||
customerIDs, err := s.GetActiveCustomerIDs()
|
||||
if err != nil {
|
||||
@@ -339,8 +349,15 @@ func CheckBackupDeadlines(s *store.Store, staleness *StalenessChecker, onEvent E
|
||||
var backupMissed, dbdumpMissed, skipped, deferred, unbound int
|
||||
|
||||
for _, id := range customerIDs {
|
||||
// Skip nodes that are down — they already have staleness events
|
||||
if staleness != nil && staleness.GetState(id) == "down" {
|
||||
// Skip nodes that are down — they already have staleness events.
|
||||
//
|
||||
// R-321 adds StateDisabled to the same skip, and it is NOT cosmetic. This check is a second
|
||||
// door onto the same false alarm: a box whose reporting we switched off deliberately is not
|
||||
// "down" (the staleness checker suppresses that), so without this it would keep e-mailing
|
||||
// `expected_backup_missed` / `expected_dbdump_missed` every morning about a machine we asked
|
||||
// to be quiet. That is R-195's shape exactly — a skip keyed off the wrong fact missing the
|
||||
// customer it would most obviously cover — which is why both doors are closed together.
|
||||
if st := stalenessState(staleness, id); st == "down" || st == StateDisabled {
|
||||
skipped++
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package monitor
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -13,6 +14,27 @@ import (
|
||||
// to trigger notification dispatch. Keeps monitor decoupled from notify.
|
||||
type EventNotifyFunc func(customerID, eventType, severity, message, detailsJSON, source string)
|
||||
|
||||
// StateDisabled is the state of a customer whose box we DELIBERATELY told to stop reporting.
|
||||
//
|
||||
// R-321. Switching a box's hub reporting off is a supported product state: the controller sends one
|
||||
// final report carrying health.status = "disabled" (felhom-controller
|
||||
// `cmd/controller/main.go:1253`) and then goes quiet BY DESIGN. That status is parsed and persisted
|
||||
// (`store.go:953-955` → `reports.health_status`), reaches this checker on every pass inside
|
||||
// `CustomerSummary.HealthStatus` (`store.go:40`), and the operator roll-up already renders such a
|
||||
// customer as `disabled` (`web/rollup.go:25`).
|
||||
//
|
||||
// This checker ignored it and measured only the AGE of the last report — so a machine we asked to be
|
||||
// quiet went stale at 30 minutes, down at 60, and e-mailed the operator twice about an outage we
|
||||
// caused on purpose. That is the false alarm that teaches people to ignore the channel, and it is a
|
||||
// sibling of R-195, where the guard that should have covered a customer was keyed off the wrong fact.
|
||||
//
|
||||
// It is a STATE here rather than a deletion (the `blocked` branch below deletes) because other
|
||||
// checkers consult GetState: CheckBackupDeadlines skips a customer that is "down", and a DELETED
|
||||
// state returns "" — which is not "down", so a disabled box would have gone on alarming
|
||||
// `expected_backup_missed` from a different function. Exactly the R-195 shape returning through a
|
||||
// second door.
|
||||
const StateDisabled = "disabled"
|
||||
|
||||
// StalenessChecker monitors customer report freshness and generates
|
||||
// node_stale / node_down / node_recovered events on state transitions.
|
||||
type StalenessChecker struct {
|
||||
@@ -94,6 +116,27 @@ func (sc *StalenessChecker) Check() {
|
||||
continue
|
||||
}
|
||||
|
||||
// R-321 — a machine we told to be quiet is not a machine that died.
|
||||
//
|
||||
// The age-based transition is skipped entirely; no stale, no down, no e-mail. The state is
|
||||
// RECORDED rather than deleted so the deliberate silence is visible to anything that asks
|
||||
// (see StateDisabled). `downtimeStart` is cleared on ENTRY so that a later, genuine outage
|
||||
// cannot compute its duration from a clock that started before we asked for the silence.
|
||||
//
|
||||
// The discriminator is the box's OWN last word, not an inference: it said `disabled` on the
|
||||
// way out. LIMIT, stated rather than hidden: if reporting is re-enabled and the box then
|
||||
// fails to report at all, the hub still sees only that final `disabled` report and keeps
|
||||
// suppressing. The hub cannot distinguish that from "still switched off" — its view changes
|
||||
// only when a report arrives. This is why the state is made VISIBLE: an operator who
|
||||
// re-enabled a box and still sees `disabled` is being told it has not come back.
|
||||
if strings.EqualFold(c.HealthStatus, StateDisabled) {
|
||||
if sc.states[c.CustomerID] != StateDisabled {
|
||||
sc.states[c.CustomerID] = StateDisabled
|
||||
delete(sc.downtimeStart, c.CustomerID)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
age := time.Since(c.ReceivedAt)
|
||||
var newState string
|
||||
switch {
|
||||
@@ -106,8 +149,20 @@ func (sc *StalenessChecker) Check() {
|
||||
}
|
||||
|
||||
oldState := sc.states[c.CustomerID]
|
||||
if oldState == "" {
|
||||
// New customer — set state without event
|
||||
if oldState == "" || oldState == StateDisabled {
|
||||
// New customer — set state without event.
|
||||
//
|
||||
// R-321 adds the re-enabled case to the SAME branch, deliberately. A box coming back
|
||||
// from a deliberate silence is a first observation, not a recovery: emitting here would
|
||||
// send `node_recovered` for an outage that never happened — and would do it every time
|
||||
// an operator switched reporting back on.
|
||||
//
|
||||
// THE RE-ENABLEMENT CLOCK, and this is the judgement: it is the age of the report the
|
||||
// hub can actually see. For a box that reports on re-enabling, that report IS the
|
||||
// re-enablement, so the clock starts there and scenario D (re-enabled, then genuinely
|
||||
// quiet) alarms on a normal schedule timed from the moment it came back. Timing from the
|
||||
// last report BEFORE the switch-off would fire an instant stale/down for a quiet period
|
||||
// we asked for — a false alarm produced by fixing false alarms.
|
||||
sc.states[c.CustomerID] = newState
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
package monitor
|
||||
|
||||
// R-321 — A MACHINE WE TOLD TO BE QUIET IS NOT A MACHINE THAT DIED.
|
||||
//
|
||||
// Switching a box's hub reporting off is a supported product state. The controller sends one final
|
||||
// report carrying health.status = "disabled" and then goes quiet BY DESIGN. The hub parses and stores
|
||||
// that status, and the operator roll-up already renders such a customer as `disabled` — but this
|
||||
// checker measured only the AGE of the last report, so the machine went stale at 30 minutes, down at
|
||||
// 60, and e-mailed the operator twice about an outage we caused on purpose.
|
||||
//
|
||||
// The discriminator is the box's OWN last word, not an inference, and it is in the data this checker
|
||||
// already reads (`CustomerSummary.HealthStatus`). Suppressing on a guess would be worse than the
|
||||
// false alarm it removes; suppressing on the machine's own declaration is not a guess.
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"io"
|
||||
"log"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-hub/internal/store"
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
// seedStalenessCustomer creates a store with one customer and one report of the given health status,
|
||||
// backdated by `age`. Reports are inserted through the REAL SaveReport path so the health_status
|
||||
// denormalization is exercised rather than hand-set — a test that writes the column directly cannot
|
||||
// see a decode that never happens, which is the R-260 class.
|
||||
func seedStalenessCustomer(t *testing.T, health string, age time.Duration) (*store.Store, string) {
|
||||
t.Helper()
|
||||
path := filepath.Join(t.TempDir(), "t.db")
|
||||
st, err := store.New(path, log.New(io.Discard, "", 0))
|
||||
if err != nil {
|
||||
t.Fatalf("store.New: %v", err)
|
||||
}
|
||||
t.Cleanup(func() { st.Close() })
|
||||
if err := st.SaveCustomerConfig(&store.CustomerConfig{
|
||||
CustomerID: "c1", APIKey: "ck", RetrievalPassword: "p", Status: "active",
|
||||
}); err != nil {
|
||||
t.Fatalf("SaveCustomerConfig: %v", err)
|
||||
}
|
||||
saveReportAged(t, st, path, health, age)
|
||||
return st, path
|
||||
}
|
||||
|
||||
// saveReportAged saves a controller report with the given health status and then backdates its
|
||||
// received_at. The backdate is a raw UPDATE because there is no production path that writes an old
|
||||
// timestamp — which is exactly why it is confined to this one helper.
|
||||
func saveReportAged(t *testing.T, st *store.Store, path, health string, age time.Duration) {
|
||||
t.Helper()
|
||||
body := `{"customer_id":"c1","health":{"status":"` + health + `"}}`
|
||||
if err := st.SaveReport("c1", []byte(body)); err != nil {
|
||||
t.Fatalf("SaveReport: %v", err)
|
||||
}
|
||||
if age <= 0 {
|
||||
return
|
||||
}
|
||||
// Backdating goes through a SECOND connection to the same file rather than a test-only method on
|
||||
// Store. No production path writes an old received_at, so exposing one would widen the store's
|
||||
// API for a fixture — and this keeps the ageing confined to the one helper that needs it.
|
||||
db, err := sql.Open("sqlite", path)
|
||||
if err != nil {
|
||||
t.Fatalf("open for backdate: %v", err)
|
||||
}
|
||||
defer db.Close()
|
||||
// GetCustomers selects the report with MAX(received_at), not MAX(id) — so backdating only the
|
||||
// row just written would leave an EARLIER, fresher-looking row as the one the checker reads, and
|
||||
// the fixture would quietly test the wrong report. (Found by two scenarios failing on a change
|
||||
// that was correct: the instrument was wrong, not the code.) Every older row is therefore pushed
|
||||
// further back, so the row just written is unambiguously the latest.
|
||||
when := time.Now().UTC().Add(-age)
|
||||
newest := when.Format("2006-01-02 15:04:05")
|
||||
older := when.Add(-time.Hour).Format("2006-01-02 15:04:05")
|
||||
if _, err := db.Exec(
|
||||
`UPDATE reports SET received_at = ? WHERE customer_id = 'c1' AND id < (SELECT MAX(id) FROM reports WHERE customer_id = 'c1')`,
|
||||
older); err != nil {
|
||||
t.Fatalf("age the older rows: %v", err)
|
||||
}
|
||||
if _, err := db.Exec(
|
||||
`UPDATE reports SET received_at = ? WHERE id = (SELECT MAX(id) FROM reports WHERE customer_id = 'c1')`,
|
||||
newest); err != nil {
|
||||
t.Fatalf("backdate: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// newChecker builds a checker with a 30-minute threshold and records every event it emits.
|
||||
func newChecker(t *testing.T, st *store.Store) (*StalenessChecker, *[]string) {
|
||||
t.Helper()
|
||||
var events []string
|
||||
sc := NewStalenessChecker(st, 30*time.Minute, func(cid, et, sev, msg, det, src string) {
|
||||
events = append(events, et)
|
||||
}, log.New(io.Discard, "", 0))
|
||||
return sc, &events
|
||||
}
|
||||
|
||||
// ── A — a machine deliberately silent for days ──────────────────────────────────────────────────
|
||||
//
|
||||
// WRONG OUTCOME GUARDED: stale, then down, then two e-mails — which is what happens today.
|
||||
func TestStaleness_A_DeliberatelySilentDoesNotAlarm(t *testing.T) {
|
||||
// The box is HEALTHY and OBSERVED first, then switched off. Seeding it already-disabled would
|
||||
// make this test pass vacuously: the checker's new-customer branch sets the first state without
|
||||
// an event, so a customer that was never seen healthy can never emit a transition — and the
|
||||
// assertion below would hold even with the suppression deleted. (Confirmed: it did. The
|
||||
// red-proof for this scenario passed on the state assertion alone until this line was added.)
|
||||
st, path := seedStalenessCustomer(t, "ok", 0)
|
||||
sc, events := newChecker(t, st)
|
||||
sc.Check()
|
||||
if sc.GetState("c1") != "ok" {
|
||||
t.Fatalf("setup: the machine should start observed-healthy, got %q", sc.GetState("c1"))
|
||||
}
|
||||
|
||||
// Reporting is switched off. The box says so on the way out, then goes quiet for three days.
|
||||
saveReportAged(t, st, path, "disabled", 72*time.Hour)
|
||||
|
||||
for i := 0; i < 3; i++ { // several passes: a suppression that only holds once is not a suppression
|
||||
sc.Check()
|
||||
}
|
||||
|
||||
if len(*events) != 0 {
|
||||
t.Fatalf("a deliberately-disabled machine emitted %v — three days quiet BY REQUEST", *events)
|
||||
}
|
||||
// The silence must be VISIBLE, not merely un-alarmed: quiet-on-purpose and quiet-by-accident
|
||||
// must not look identical, and an unknown is never drawn as healthy.
|
||||
if got := sc.GetState("c1"); got != StateDisabled {
|
||||
t.Errorf("state = %q, want %q — the deliberate silence is invisible", got, StateDisabled)
|
||||
}
|
||||
}
|
||||
|
||||
// ── B — a machine that simply stopped reporting ─────────────────────────────────────────────────
|
||||
//
|
||||
// WRONG OUTCOME GUARDED: silence mistaken for a deliberate switch-off — THE ALARM THAT MATTERS,
|
||||
// suppressed. This is the one that must never regress.
|
||||
func TestStaleness_B_GenuineSilenceStillAlarms(t *testing.T) {
|
||||
st, path := seedStalenessCustomer(t, "ok", 0)
|
||||
sc, events := newChecker(t, st)
|
||||
sc.Check() // first observation: healthy, no event
|
||||
|
||||
// The same customer now goes quiet for real.
|
||||
saveReportAged(t, st, path, "ok", 3*time.Hour)
|
||||
sc.Check()
|
||||
|
||||
if got := sc.GetState("c1"); got != "down" {
|
||||
t.Fatalf("a genuinely silent machine is %q, want \"down\" — a real alarm was swallowed", got)
|
||||
}
|
||||
if len(*events) == 0 {
|
||||
t.Fatal("a genuinely silent machine emitted NO event — the suppression is over-broad")
|
||||
}
|
||||
}
|
||||
|
||||
// ── C — a disabled machine that is re-enabled and reports promptly ──────────────────────────────
|
||||
//
|
||||
// WRONG OUTCOME GUARDED: a recovery e-mail for an outage that never happened.
|
||||
func TestStaleness_C_ReEnabledReportsCleanlyWithNoRecoveryEvent(t *testing.T) {
|
||||
st, path := seedStalenessCustomer(t, "disabled", 72*time.Hour)
|
||||
sc, events := newChecker(t, st)
|
||||
sc.Check()
|
||||
if sc.GetState("c1") != StateDisabled {
|
||||
t.Fatalf("setup: expected the disabled state, got %q", sc.GetState("c1"))
|
||||
}
|
||||
|
||||
// Reporting is switched back on and the box reports immediately.
|
||||
saveReportAged(t, st, path, "ok", 0)
|
||||
sc.Check()
|
||||
|
||||
if len(*events) != 0 {
|
||||
t.Fatalf("re-enabling emitted %v — there was no outage to recover from", *events)
|
||||
}
|
||||
if got := sc.GetState("c1"); got != "ok" {
|
||||
t.Errorf("state after re-enable = %q, want \"ok\"", got)
|
||||
}
|
||||
}
|
||||
|
||||
// ── D — a disabled machine that is re-enabled and then goes genuinely quiet ─────────────────────
|
||||
//
|
||||
// WRONG OUTCOME GUARDED: permanently silenced because it was once disabled. Also pins THE CLOCK
|
||||
// JUDGEMENT: timing runs from the report the box sent on re-enabling, not from the last report
|
||||
// before the switch-off — otherwise coming back would fire an instant false alarm about a quiet
|
||||
// period we asked for.
|
||||
func TestStaleness_D_ReEnabledThenQuietAlarmsFromReEnablement(t *testing.T) {
|
||||
st, path := seedStalenessCustomer(t, "disabled", 72*time.Hour)
|
||||
sc, events := newChecker(t, st)
|
||||
sc.Check()
|
||||
|
||||
// Re-enabled, reports promptly — the clean first observation.
|
||||
saveReportAged(t, st, path, "ok", 0)
|
||||
sc.Check()
|
||||
if len(*events) != 0 {
|
||||
t.Fatalf("the re-enable itself emitted %v", *events)
|
||||
}
|
||||
|
||||
// …and then goes quiet for real. Timed from THIS report, it is down.
|
||||
saveReportAged(t, st, path, "ok", 3*time.Hour)
|
||||
sc.Check()
|
||||
|
||||
if got := sc.GetState("c1"); got != "down" {
|
||||
t.Fatalf("state = %q, want \"down\" — a once-disabled machine was silenced for ever", got)
|
||||
}
|
||||
if len(*events) == 0 {
|
||||
t.Fatal("no event for a machine that genuinely died after being re-enabled")
|
||||
}
|
||||
}
|
||||
|
||||
// The deadline check is a SECOND DOOR onto the same false alarm: a disabled box is not "down", so
|
||||
// without its own skip it would keep e-mailing expected_backup_missed every morning. R-195's shape,
|
||||
// which is why both doors are closed together.
|
||||
func TestStaleness_DisabledIsAlsoSkippedByTheDeadlineCheck(t *testing.T) {
|
||||
st, _ := seedStalenessCustomer(t, "disabled", 72*time.Hour)
|
||||
if err := st.UpsertHost(&store.Host{HostID: "h1", CustomerID: "c1", APIKey: "k1"}); err != nil {
|
||||
t.Fatalf("UpsertHost: %v", err)
|
||||
}
|
||||
sc, _ := newChecker(t, st)
|
||||
sc.Check()
|
||||
|
||||
var events []string
|
||||
CheckBackupDeadlines(st, sc, func(cid, et, sev, msg, det, src string) {
|
||||
events = append(events, et)
|
||||
}, log.New(io.Discard, "", 0))
|
||||
|
||||
for _, e := range events {
|
||||
if e == "expected_backup_missed" || e == "expected_dbdump_missed" {
|
||||
t.Fatalf("the deadline check alarmed on a deliberately-disabled machine: %v", events)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ Message: %s`, customerID, eventType, severity, now, message)
|
||||
// customerMessages maps event_type → Hungarian customer message.
|
||||
var customerMessages = map[string]string{
|
||||
// Customer-claim arc (v0.50.0)
|
||||
"claim_lockout": "Túl sok hibás beállító/visszaállító kód próbálkozás történt — a beállító oldal 15 percre zárolva lett. Ha nem te próbálkoztál, jelezd az üzemeltetőnek.",
|
||||
"claim_lockout": "Túl sok hibás beállító kód próbálkozás történt — a beállító oldal 15 percre zárolva lett. Ha nem te próbálkoztál, jelezd az üzemeltetőnek.",
|
||||
// Backup events
|
||||
"backup_completed": "A biztonsági mentés sikeresen elkészült.",
|
||||
"backup_failed": "A biztonsági mentés sikertelen! Kérjük, ellenőrizd a rendszert.",
|
||||
@@ -207,18 +207,38 @@ Felhom.eu monitoring`
|
||||
// ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
// FormatClaimEmail returns (subject, textBody) for a claim-arc email. kind is one of
|
||||
// "claim" | "reset" | "claimed" (claim.EmailKind values). The code appears ONLY in the
|
||||
// "claim" | "reset" | "reenroll" | "claimed" (claim.EmailKind values). The code appears ONLY in the
|
||||
// returned body — callers must never log it.
|
||||
//
|
||||
// R-295, HUB HALF (2026-08-13). ONE NAME PER SECRET, and it is „Beállító kód".
|
||||
//
|
||||
// The three-word code that gives a person control of the DASHBOARD is „Beállító kód" everywhere —
|
||||
// in this mail, on the operator button, and on the box's own page, which has said so since the
|
||||
// controller half shipped on 2026-08-10. The TEN-word code that opens the sealed backups is
|
||||
// „Helyreállítási kód" and is a different secret entirely. **„Visszaállító kód" is retired**: it was
|
||||
// a near-homograph of „Helyreállítási kód", the collision cost a real code, and the hub was the last
|
||||
// place it survived — this half was dropped twice before it was finished.
|
||||
//
|
||||
// The rule the three branches below follow: ONE SECRET IN TWO SITUATIONS KEEPS ITS NAME, AND THE
|
||||
// SENTENCE AROUND IT CHANGES. „reset" and „reenroll" carry the identical secret under the identical
|
||||
// name; they differ only in which page the customer will actually be looking at.
|
||||
//
|
||||
// THIS IS NAMING, NOT FUNCTION. No acceptance logic moved: the code is minted, hashed, rotated,
|
||||
// capped and consumed exactly as before, and a reset code is still accepted on the setup page.
|
||||
// Pinned by TestFormatClaimEmail_OneNamePerSecret and, on the box side, by the controller's
|
||||
// claim_code_naming_test.go.
|
||||
func FormatClaimEmail(kind, customerID, domain, code string) (string, string) {
|
||||
dashboardURL := "https://felhom." + domain
|
||||
switch kind {
|
||||
case "reset":
|
||||
subject := "[Felhom] Jelszó-visszaállítási kód"
|
||||
// The box HAS a password: the customer asked for a reset from the login screen, so the
|
||||
// „Elfelejtett jelszó" link IS on their screen and naming it is correct here.
|
||||
subject := "[Felhom] Beállító kód a jelszavad visszaállításához"
|
||||
body := fmt.Sprintf(`Kedves Ügyfél!
|
||||
|
||||
Jelszó-visszaállítást kértél a Felhom vezérlőpultodhoz.
|
||||
|
||||
Visszaállító kód: %s
|
||||
Beállító kód: %s
|
||||
|
||||
A kód 72 óráig érvényes, és egyszer használható fel. Add meg a vezérlőpult
|
||||
"Elfelejtett jelszó" oldalán, majd válassz új jelszót:
|
||||
@@ -227,6 +247,32 @@ A kód 72 óráig érvényes, és egyszer használható fel. Add meg a vezérlő
|
||||
|
||||
Ha nem te kérted, hagyd figyelmen kívül — a jelenlegi jelszavad változatlan.
|
||||
|
||||
Üdvözlettel,
|
||||
Felhom.eu`, code, dashboardURL)
|
||||
return subject, body
|
||||
case "reenroll":
|
||||
// The box was rebuilt and has NO password, so it shows „A szerver beállítása" and serves no
|
||||
// login page — there is no „Elfelejtett jelszó" link to send anyone to. Same secret, same
|
||||
// name, the page the machine is actually showing.
|
||||
//
|
||||
// It deliberately says NOTHING about the apps or the backups. A clean-slate reinstall is
|
||||
// exactly the situation in which such a reassurance could be false, and this project has
|
||||
// spent four register rows removing promises it could not see were still true.
|
||||
subject := "[Felhom] Új beállító kód — újratelepült a szervered"
|
||||
body := fmt.Sprintf(`Kedves Ügyfél!
|
||||
|
||||
A Felhom szervered újratelepült, ezért a vezérlőpultod belépését újra be kell
|
||||
állítani. A korábbi jelszavad már nem érvényes.
|
||||
|
||||
Beállító kód: %s
|
||||
|
||||
A kód 72 óráig érvényes, és egyszer használható fel. Nyisd meg a vezérlőpultot —
|
||||
"A szerver beállítása" oldal fogad —, add meg a kódot, majd válassz új jelszót:
|
||||
|
||||
%s
|
||||
|
||||
Ha nem te telepítetted újra a szervered, vedd fel a kapcsolatot az üzemeltetővel.
|
||||
|
||||
Üdvözlettel,
|
||||
Felhom.eu`, code, dashboardURL)
|
||||
return subject, body
|
||||
@@ -270,6 +316,24 @@ Felhom.eu`, code, dashboardURL)
|
||||
// link (v0.66.0, R-27 slice 1). The link is the ONLY secret here — the passphrase is never in the
|
||||
// mail (the customer already holds it), and the console pairing code is read off the box screen. The
|
||||
// copy tells the customer they will need both factors on the page. Adult tone, no emoji.
|
||||
//
|
||||
// R-323, THE THIRD NAME (2026-08-13). This mail used to call the five-word phrase „visszaállító
|
||||
// jelszó" — one word away from „Visszaállító kód", which had just been retired for colliding with
|
||||
// „Helyreállítási kód". It is „Tulajdonosi jelmondat" now. Two reasons, and the second is the one
|
||||
// that rules out the obvious alternatives:
|
||||
//
|
||||
// 1. THE OLD NAME WAS FALSE. The phrase restores nothing. It proves the account owns the box being
|
||||
// linked — so the name says that.
|
||||
// 2. IT MUST NOT COLLIDE WITH THE OTHER FACTOR ON THE SAME PAGE. Item 1 below is the „Párosító
|
||||
// kód". Naming this one after the same act („Összekötési jelszó") would leave the two factors a
|
||||
// customer types in one sitting distinguished only by kód-versus-jelszó — which is EXACTLY the
|
||||
// „Visszaállító kód" / „Visszaállító jelszó" shape being removed. „Fiókjelszó" is worse still:
|
||||
// there IS an account password (the dashboard login), so it would collide with a different real
|
||||
// secret. „Tulajdonosi jelmondat" is distinct from all three on BOTH axes — the stem
|
||||
// (Tulajdonosi vs Beállító / Helyreállítási / Párosító) and the noun (jelmondat vs kód / jelszó).
|
||||
//
|
||||
// Naming only: no acceptance logic moved, and the same phrase is still accepted. Pinned by
|
||||
// TestSelfBind_ThirdSecretNaming and TestSelfBindPassphrase_StillAcceptedAfterTheRename.
|
||||
func FormatSelfBindEmail(customerID, link string) (string, string) {
|
||||
subject := "[Felhom] Kösd össze a Felhom dobozodat"
|
||||
body := fmt.Sprintf(`Kedves Ügyfél!
|
||||
@@ -282,8 +346,8 @@ tudod te magad összekötni a fiókoddal — nincs szükség bejelentkezésre:
|
||||
A hivatkozás megnyitása után két adatot kell megadnod:
|
||||
|
||||
1. A párosító kódot, amely a doboz képernyőjén (a monitoron) látható.
|
||||
2. A visszaállító jelszavadat (az 5 szóból álló kifejezést), amelyet a
|
||||
beállításkor kaptál.
|
||||
2. A tulajdonosi jelmondatodat (az 5 szóból álló kifejezést), amelyet a
|
||||
beállításkor kaptál. Ez igazolja, hogy a fiók a tiéd.
|
||||
|
||||
A hivatkozás 7 napig érvényes. Biztonsági okból 5 sikertelen próbálkozás után
|
||||
zárolódik — ilyenkor vedd fel a kapcsolatot az ügyfélszolgálattal.
|
||||
|
||||
@@ -75,8 +75,13 @@ func TestCustomerPage_ClaimCardStates(t *testing.T) {
|
||||
if !strings.Contains(html, ">Claimed ") {
|
||||
t.Error("missing the Claimed chip")
|
||||
}
|
||||
if !strings.Contains(html, "Visszaállító kód küldése") {
|
||||
t.Error("claimed state should offer the reset-code button")
|
||||
// R-295: the button says „Beállító kód küldése" — ONE name per secret. It used to read
|
||||
// „Visszaállító kód küldése", a near-homograph of the escrow „Helyreállítási kód".
|
||||
if !strings.Contains(html, "Beállító kód küldése") {
|
||||
t.Error("claimed state should offer the reset-code button, named „Beállító kód küldése”")
|
||||
}
|
||||
if strings.Contains(html, "Visszaállító kód") {
|
||||
t.Error("the retired name „Visszaállító kód” is back on the customer page")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -776,8 +776,9 @@ func (s *Server) handleConfigUpdate(w http.ResponseWriter, r *http.Request, cust
|
||||
}
|
||||
|
||||
// handleClaimResend (v0.50.0, customer-claim arc) rotates the claim/reset code and re-sends it to
|
||||
// the REGISTERED customer address — the operator "Kód újraküldése" / "Visszaállító kód küldése"
|
||||
// button. The old code stops verifying immediately (single active code); the fresh hash reaches
|
||||
// the REGISTERED customer address — the operator "Kód újraküldése" / "Beállító kód küldése"
|
||||
// button (R-295: the button used to read „Visszaállító kód küldése"; that name is retired).
|
||||
// The old code stops verifying immediately (single active code); the fresh hash reaches
|
||||
// the box on its next report ACK (no config bump needed). No plaintext is ever rendered or logged.
|
||||
func (s *Server) handleClaimResend(w http.ResponseWriter, r *http.Request, customerID string) {
|
||||
if s.claimEngine == nil {
|
||||
|
||||
@@ -263,6 +263,175 @@ func (s *Server) hostNetwork(host *store.Host, reportJSON string) hostNetworkVie
|
||||
return v
|
||||
}
|
||||
|
||||
// ── R-319 — the guest-network watchdog gets a reader ────────────────────────────────────────────
|
||||
//
|
||||
// FIRST OF THE R-264 READERS. The agent has reported `guest_net` on every heartbeat since v0.92.0
|
||||
// (R-54, 2026-07-21) and the hub — the component that emails the operator — modelled NONE of it: the
|
||||
// string `guest_net` occurred nowhere in this repository. It was stored as raw text inside
|
||||
// `report_json` and read by nothing.
|
||||
//
|
||||
// WHY THIS ONE FIRST. It has a live incident behind it: a killed `dhclient` in a guest took a tunnel
|
||||
// down for 1 h 15 m with nobody told (`audits/INCIDENT-guest-dhclient-killed-2026-07-20.md`), and the
|
||||
// watchdog built afterwards has been reporting exactly that condition ever since — to a hub that
|
||||
// modelled none of it. R-264 named it "the strongest candidate of the twenty-one".
|
||||
//
|
||||
// WHAT IS ACTUALLY BEING READ, and it is NOT just the current state. The signal is
|
||||
// `heals_last_hour`: a guest whose network the watchdog keeps REPAIRING is healthy at every instant
|
||||
// anyone looks and is nevertheless failing. Rendering only `state` would give that machine a green
|
||||
// tick — which is the exact shape of the defect that drew a failed disk as a healthy empty disk.
|
||||
// RepairCount is therefore surfaced beside the state, not behind it.
|
||||
//
|
||||
// AN UNKNOWN IS NEVER DRAWN AS HEALTHY. Three distinct absences are kept apart, following the
|
||||
// companion-flag convention this project settled in August (`hostNetworkView` above is the sibling):
|
||||
// - AgentTooOld — the agent predates v0.92.0, so absence is EXPECTED but still tells us nothing;
|
||||
// - Reported=false — a new-enough agent sent no stanza (watchdog disabled, or a report that
|
||||
// predates the feature on this box);
|
||||
// - a guest whose `state` is empty or unrecognised → rendered "unknown", never healthy.
|
||||
// A malformed stanza degrades to Reported=false and must never 500 the page.
|
||||
|
||||
// minAgentForGuestNet is the agent release that first reported `guest_net` (v0.92.0, R-54). Below it
|
||||
// the stanza is absent BY CONSTRUCTION, so its absence is unknown-and-expected rather than a finding.
|
||||
const minAgentForGuestNet = "0.92.0"
|
||||
|
||||
// guestNetGuestView is one owned guest's network health as the watchdog last saw it.
|
||||
type guestNetGuestView struct {
|
||||
VMID int
|
||||
State string // healthy | unhealthy | static_fault | unknown ("" → unknown)
|
||||
Mode string // dhcp | static | unknown
|
||||
IP string
|
||||
HasRoute bool
|
||||
DHClientAlive bool
|
||||
// RepairCount is `heals_last_hour` — THE SIGNAL. A machine repairing itself over and over is
|
||||
// telling you something that its current state cannot.
|
||||
RepairCount int
|
||||
LastHealAt string
|
||||
Damped bool
|
||||
Message string
|
||||
// Healed / HealSucceeded are carried DELIBERATELY, and together. R-260 is this project's
|
||||
// warning: the OOB decoder mirrored five of the agent's eight fields, and the three it dropped
|
||||
// included the one that decided the question the checker existed to answer. A repair that FAILED
|
||||
// is a different fact from a repair that worked, and the count alone cannot express it — six
|
||||
// successful repairs is a nuisance, six FAILED ones is a guest that is down right now.
|
||||
Healed bool
|
||||
HealSucceeded bool
|
||||
}
|
||||
|
||||
// HealFailed reports that the watchdog TRIED to repair this guest and did not succeed. Kept separate
|
||||
// from State because the two can disagree: the sweep that failed to heal is not necessarily the sweep
|
||||
// that set the state.
|
||||
func (g guestNetGuestView) HealFailed() bool { return g.Healed && !g.HealSucceeded }
|
||||
|
||||
// Unknown reports whether this guest's state is one the watchdog did not positively assert. An empty
|
||||
// or unrecognised state is drawn as unknown; it is never allowed to fall through to the healthy
|
||||
// branch. Value receiver — a pointer receiver compiles, vets, passes the suite and 500s at render.
|
||||
func (g guestNetGuestView) Unknown() bool {
|
||||
switch g.State {
|
||||
case "healthy", "unhealthy", "static_fault":
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Repairing reports whether the watchdog has had to repair this guest inside the last hour. This is
|
||||
// deliberately independent of State: the whole point is that a REPAIRED guest reads healthy.
|
||||
func (g guestNetGuestView) Repairing() bool { return g.RepairCount > 0 }
|
||||
|
||||
// guestNetView is the Guest network card's whole view-model.
|
||||
type guestNetView struct {
|
||||
// Reported is the ONLY thing that licenses drawing any health at all. False → unknown.
|
||||
Reported bool
|
||||
// AgentTooOld distinguishes "this agent cannot report it" from "a capable agent said nothing".
|
||||
// Both render as unknown; they need different words, and conflating them is how an operator
|
||||
// starts ignoring the card.
|
||||
AgentTooOld bool
|
||||
CheckedAt string
|
||||
Guests []guestNetGuestView
|
||||
// RepairingCount / UnhealthyCount drive the card's summary badge. Counted rather than derived in
|
||||
// the template: template logic that computes a verdict is logic nobody tests.
|
||||
RepairingCount int
|
||||
UnhealthyCount int
|
||||
UnknownCount int
|
||||
// HealFailedCount — repairs ATTEMPTED and not succeeded. Counted separately from
|
||||
// RepairingCount: a failing repair is a harder fact than a frequent one.
|
||||
HealFailedCount int
|
||||
}
|
||||
|
||||
// Degraded is true when any owned guest is unhealthy OR is being repeatedly repaired. The repair leg
|
||||
// is the one that matters: without it a guest the watchdog fixes every ten minutes reports "healthy"
|
||||
// for ever.
|
||||
func (v guestNetView) Degraded() bool {
|
||||
return v.UnhealthyCount > 0 || v.RepairingCount > 0 || v.HealFailedCount > 0
|
||||
}
|
||||
|
||||
// parseGuestNet extracts the `guest_net` stanza. A missing or malformed body yields Reported=false
|
||||
// (unknown), never an error and never a partial claim of health.
|
||||
func parseGuestNet(reportJSON string) guestNetView {
|
||||
v := guestNetView{Guests: []guestNetGuestView{}}
|
||||
if reportJSON == "" {
|
||||
return v
|
||||
}
|
||||
var body struct {
|
||||
GuestNet *struct {
|
||||
CheckedAt string `json:"checked_at"`
|
||||
Guests []struct {
|
||||
VMID int `json:"vmid"`
|
||||
State string `json:"state"`
|
||||
Mode string `json:"mode"`
|
||||
IP string `json:"ip"`
|
||||
HasRoute bool `json:"has_route"`
|
||||
DHClientAlive bool `json:"dhclient_alive"`
|
||||
HealsLastHour int `json:"heals_last_hour"`
|
||||
Healed bool `json:"healed"`
|
||||
HealSucceeded bool `json:"heal_succeeded"`
|
||||
LastHealAt string `json:"last_heal_at"`
|
||||
Damped bool `json:"damped"`
|
||||
Message string `json:"message"`
|
||||
} `json:"guests"`
|
||||
} `json:"guest_net"`
|
||||
}
|
||||
// A decode error is NOT propagated: one box's bad field must not break the page for the rest of
|
||||
// the fleet. It degrades to Reported=false, which renders as unknown — the safe direction.
|
||||
if err := json.Unmarshal([]byte(reportJSON), &body); err != nil || body.GuestNet == nil {
|
||||
return v
|
||||
}
|
||||
v.Reported = true
|
||||
v.CheckedAt = body.GuestNet.CheckedAt
|
||||
for _, g := range body.GuestNet.Guests {
|
||||
gv := guestNetGuestView{
|
||||
VMID: g.VMID, State: g.State, Mode: g.Mode, IP: g.IP,
|
||||
HasRoute: g.HasRoute, DHClientAlive: g.DHClientAlive,
|
||||
RepairCount: g.HealsLastHour, LastHealAt: g.LastHealAt,
|
||||
Damped: g.Damped, Message: g.Message,
|
||||
Healed: g.Healed, HealSucceeded: g.HealSucceeded,
|
||||
}
|
||||
switch {
|
||||
case gv.Unknown():
|
||||
v.UnknownCount++
|
||||
case gv.State == "unhealthy" || gv.State == "static_fault":
|
||||
v.UnhealthyCount++
|
||||
}
|
||||
if gv.Repairing() {
|
||||
v.RepairingCount++
|
||||
}
|
||||
if gv.HealFailed() {
|
||||
v.HealFailedCount++
|
||||
}
|
||||
v.Guests = append(v.Guests, gv)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// guestNet builds the card's view-model, applying the version gate before the report is consulted so
|
||||
// that an old agent's silence is named as such rather than rendered as a finding.
|
||||
func (s *Server) guestNet(host *store.Host, reportJSON string) guestNetView {
|
||||
if host.AgentVersion != "" && semver.Valid(host.AgentVersion) &&
|
||||
semver.Compare(host.AgentVersion, minAgentForGuestNet) < 0 {
|
||||
return guestNetView{Guests: []guestNetGuestView{}, AgentTooOld: true}
|
||||
}
|
||||
return parseGuestNet(reportJSON)
|
||||
}
|
||||
|
||||
// storageTargetView is the rich per-drive row the host-detail Storage Targets table renders:
|
||||
// fill %, role/state, thin-pool, and SMART health/temp/wear. Parsed from the latest report's
|
||||
// storage_targets[] (the full hostStorageTarget wire shape lives in the api package; this view
|
||||
@@ -533,6 +702,9 @@ func (s *Server) hostDetailData(host *store.Host, r *http.Request) map[string]in
|
||||
// v0.85.0 Network — the host's addresses + its WireGuard allocation.
|
||||
network := s.hostNetwork(host, reportJSON)
|
||||
|
||||
// R-319 Guest network — the R-54 watchdog's per-guest verdict AND its repair count.
|
||||
guestNet := s.guestNet(host, reportJSON)
|
||||
|
||||
// v0.84.0 Console access — presence + username + set_at ONLY. GetHostRecoveryMeta cannot carry
|
||||
// the secret (its query does not select the column); the plaintext reaches the operator solely
|
||||
// through POST /hosts/{id}/reveal-recovery-credential.
|
||||
@@ -573,6 +745,7 @@ func (s *Server) hostDetailData(host *store.Host, r *http.Request) map[string]in
|
||||
// v0.84.0 break-glass Console access card. NEVER add a key holding the secret.
|
||||
// v0.85.0 Network card (addresses + WireGuard allocation/confirmation).
|
||||
"Network": network,
|
||||
"GuestNet": guestNet,
|
||||
"RecoveryVaulted": recoveryMeta != nil,
|
||||
"RecoveryUsername": func() string {
|
||||
if recoveryMeta != nil {
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
package web
|
||||
|
||||
// Guest-network card (R-319) — the first R-264 reader.
|
||||
//
|
||||
// THE FIXTURES BELOW ARE THE REAL WIRE. `liveGuestNetJSON` is the `guest_net` stanza copied verbatim
|
||||
// out of `demo-felhom-8363b5`'s newest row in the live hub's `host_reports` table on 2026-08-13
|
||||
// (agent 0.129.0). Testing against a hand-written shape would have proved only that the parser
|
||||
// matches my own idea of the format — and the defect this whole class comes from (R-260) was exactly
|
||||
// a hub-side struct that did not match what the agent actually sends.
|
||||
//
|
||||
// Every test drives ServeHTTP, so a template gate that never renders is visible here. That is the
|
||||
// seam-wiring rule: handler tests prove nothing about reachability, and this project has shipped four
|
||||
// features whose entry point was never wired.
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// The real stanza: one owned guest, healthy, DHCP, no repairs. `heals_last_hour` and friends are
|
||||
// ABSENT because the agent marks them `omitempty` and this box has never needed a repair — which is
|
||||
// itself the shape scenario A has to survive.
|
||||
const liveGuestNetJSON = `{
|
||||
"host": {"cpu_percent": 4.0, "memory_percent": 30.0, "disk_percent": 20.0},
|
||||
"guest_net": {
|
||||
"checked_at": "2026-08-13T08:15:33Z",
|
||||
"guests": [
|
||||
{"vmid": 9201, "state": "healthy", "mode": "dhcp", "ip": "192.168.0.149",
|
||||
"has_route": true, "dhclient_alive": true, "checked_at": "2026-08-13T08:14:30Z",
|
||||
"message": "address, default route and dhclient all present"}
|
||||
]
|
||||
}
|
||||
}`
|
||||
|
||||
// The same box after the watchdog has had to keep fixing it — the R-54 heal fields populated. This is
|
||||
// the shape the incident of 2026-07-20 would have produced had the watchdog existed then.
|
||||
const repairingGuestNetJSON = `{
|
||||
"host": {"cpu_percent": 4.0, "memory_percent": 30.0, "disk_percent": 20.0},
|
||||
"guest_net": {
|
||||
"checked_at": "2026-08-13T08:15:33Z",
|
||||
"guests": [
|
||||
{"vmid": 9201, "state": "healthy", "mode": "dhcp", "ip": "192.168.0.149",
|
||||
"has_route": true, "dhclient_alive": true, "checked_at": "2026-08-13T08:14:30Z",
|
||||
"healed": true, "heal_succeeded": true, "last_heal_at": "2026-08-13T08:09:12Z",
|
||||
"heals_last_hour": 6, "message": "dhclient was absent; restarted"}
|
||||
]
|
||||
}
|
||||
}`
|
||||
|
||||
// A report from a capable agent with NO guest_net stanza at all — the watchdog switched off, or a
|
||||
// report predating the feature on this box.
|
||||
const silentGuestNetJSON = `{"host": {"cpu_percent": 4.0, "memory_percent": 30.0, "disk_percent": 20.0}}`
|
||||
|
||||
// The stanza arrives, but its contents are not what the hub expects: `guests` is an object where an
|
||||
// array belongs, and `heals_last_hour` is a string. This is what a wire drift or a truncated write
|
||||
// looks like from the hub's side.
|
||||
const malformedGuestNetJSON = `{
|
||||
"host": {"cpu_percent": 4.0},
|
||||
"guest_net": {"checked_at": "2026-08-13T08:15:33Z", "guests": {"vmid": "nine-two-oh-one"}}
|
||||
}`
|
||||
|
||||
// ── A — a machine reporting healthy guest networking, no repairs → shown as healthy ─────────────
|
||||
//
|
||||
// WRONG OUTCOME GUARDED: an empty or alarming state on a machine that is fine. A card that cried
|
||||
// unknown on every healthy box would be switched off within a week, and then the B case below would
|
||||
// never be seen either.
|
||||
func TestGuestNet_A_HealthyRendersHealthy(t *testing.T) {
|
||||
s, st, _ := newRevealServer(t)
|
||||
cookie, _ := newRevealSession(t, s)
|
||||
seedNetHost(t, st, "demo-felhom-8363b5", "0.129.0", liveGuestNetJSON, "")
|
||||
|
||||
body := getHostPage(t, s, cookie, "demo-felhom-8363b5")
|
||||
|
||||
if !strings.Contains(body, "Guest network") {
|
||||
t.Fatal("no Guest network card — the reader shows nothing")
|
||||
}
|
||||
if !strings.Contains(body, "192.168.0.149") {
|
||||
t.Error("the guest's address did not reach the page")
|
||||
}
|
||||
if !strings.Contains(body, "badge-ok") {
|
||||
t.Error("a healthy guest must render as healthy, not as an empty or alarming state")
|
||||
}
|
||||
if strings.Contains(body, "needs attention") {
|
||||
t.Error("a machine that is fine is being alarmed on")
|
||||
}
|
||||
// The unknown branches must NOT fire for a box that reported properly.
|
||||
if strings.Contains(body, "does not run the guest-network watchdog") ||
|
||||
strings.Contains(body, "reported no guest-network state") {
|
||||
t.Error("a reporting box rendered one of the unknown sentences")
|
||||
}
|
||||
}
|
||||
|
||||
// ── B — a machine whose watchdog has repaired the guest repeatedly ──────────────────────────────
|
||||
//
|
||||
// WRONG OUTCOME GUARDED: a green tick because the CURRENT state is fine. This is the exact shape of
|
||||
// the failed-disk-drawn-as-a-healthy-empty-disk defect, and it is the reason this card exists at all:
|
||||
// `state` says "healthy" in this fixture, because between repairs it IS.
|
||||
func TestGuestNet_B_RepeatedRepairsAreVisible(t *testing.T) {
|
||||
s, st, _ := newRevealServer(t)
|
||||
cookie, _ := newRevealSession(t, s)
|
||||
seedNetHost(t, st, "demo-felhom-8363b5", "0.129.0", repairingGuestNetJSON, "")
|
||||
|
||||
body := getHostPage(t, s, cookie, "demo-felhom-8363b5")
|
||||
|
||||
if !strings.Contains(body, "needs attention") {
|
||||
t.Fatal("a guest repaired 6 times in an hour is reported as fine — the whole point of the card")
|
||||
}
|
||||
if !strings.Contains(body, "had their networking repaired in the last hour") {
|
||||
t.Error("the climbing-repairs sentence is missing")
|
||||
}
|
||||
if !strings.Contains(body, ">6<") {
|
||||
t.Error("the repair COUNT is not rendered; 'some repairs' is not the signal, the number is")
|
||||
}
|
||||
if !strings.Contains(body, "2026-08-13T08:09:12Z") {
|
||||
t.Error("the last repair time is not offered (it is in the title attribute)")
|
||||
}
|
||||
}
|
||||
|
||||
// ── C — a machine that does not report the fact at all → drawn as unknown, never healthy ────────
|
||||
//
|
||||
// WRONG OUTCOME GUARDED: absence read as good news. THE ONE THAT MATTERS. Two distinct absences are
|
||||
// checked because they need different words: an agent that cannot report it, and a capable agent that
|
||||
// said nothing.
|
||||
func TestGuestNet_C_SilentIsUnknownNotHealthy(t *testing.T) {
|
||||
t.Run("capable agent, no stanza", func(t *testing.T) {
|
||||
s, st, _ := newRevealServer(t)
|
||||
cookie, _ := newRevealSession(t, s)
|
||||
seedNetHost(t, st, "demo-hp-bb76ea", "0.129.0", silentGuestNetJSON, "")
|
||||
|
||||
body := getHostPage(t, s, cookie, "demo-hp-bb76ea")
|
||||
|
||||
if !strings.Contains(body, "reported no guest-network state") {
|
||||
t.Fatal("a silent box must SAY it is unknown")
|
||||
}
|
||||
if strings.Contains(body, "badge-ok") && strings.Contains(body, "Guest network") {
|
||||
assertNoHealthyBadgeInGuestNetCard(t, body)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("agent too old to report it", func(t *testing.T) {
|
||||
s, st, _ := newRevealServer(t)
|
||||
cookie, _ := newRevealSession(t, s)
|
||||
// 0.91.0 predates the R-54 watchdog (v0.92.0): the absence is expected AND still unknown.
|
||||
seedNetHost(t, st, "old-agent-box", "0.91.0", silentGuestNetJSON, "")
|
||||
|
||||
body := getHostPage(t, s, cookie, "old-agent-box")
|
||||
|
||||
if !strings.Contains(body, "does not run the guest-network watchdog") {
|
||||
t.Fatal("an old agent's silence must be named as an old agent's silence")
|
||||
}
|
||||
if !strings.Contains(body, "<strong>unknown</strong>, not healthy") {
|
||||
t.Error("the unknown-is-not-healthy sentence is missing")
|
||||
}
|
||||
assertNoHealthyBadgeInGuestNetCard(t, body)
|
||||
})
|
||||
}
|
||||
|
||||
// ── D — the fact arrives malformed → unknown, and the hub does not 500 ──────────────────────────
|
||||
//
|
||||
// WRONG OUTCOME GUARDED: a page that breaks on one machine's bad field. getHostPage fails the test on
|
||||
// any non-200, so surviving the call IS half the assertion.
|
||||
func TestGuestNet_D_MalformedIsUnknownAndDoesNotBreakThePage(t *testing.T) {
|
||||
s, st, _ := newRevealServer(t)
|
||||
cookie, _ := newRevealSession(t, s)
|
||||
seedNetHost(t, st, "demo-felhom-8363b5", "0.129.0", malformedGuestNetJSON, "")
|
||||
|
||||
body := getHostPage(t, s, cookie, "demo-felhom-8363b5") // 200 or the test dies here
|
||||
|
||||
if !strings.Contains(body, "reported no guest-network state") {
|
||||
t.Fatal("a malformed stanza must degrade to unknown")
|
||||
}
|
||||
assertNoHealthyBadgeInGuestNetCard(t, body)
|
||||
}
|
||||
|
||||
// A guest whose state string is one the watchdog never asserts (a future value, or a truncated field)
|
||||
// is drawn as unknown rather than falling through to the healthy branch. The switch in
|
||||
// guestNetGuestView.Unknown is an ALLOW-LIST for exactly this reason: an unrecognised value defaults
|
||||
// to unknown, and adding a state to the agent cannot silently paint it green here.
|
||||
func TestGuestNet_UnrecognisedStateIsUnknown(t *testing.T) {
|
||||
s, st, _ := newRevealServer(t)
|
||||
cookie, _ := newRevealSession(t, s)
|
||||
seedNetHost(t, st, "demo-felhom-8363b5", "0.129.0", `{
|
||||
"host": {"cpu_percent": 1.0},
|
||||
"guest_net": {"checked_at": "2026-08-13T08:15:33Z",
|
||||
"guests": [{"vmid": 9201, "state": "quantum", "mode": "dhcp", "ip": "10.0.0.5"}]}}`, "")
|
||||
|
||||
body := getHostPage(t, s, cookie, "demo-felhom-8363b5")
|
||||
|
||||
if !strings.Contains(body, "partly unknown") {
|
||||
t.Fatal("an unrecognised guest state must summarise as unknown, not healthy")
|
||||
}
|
||||
}
|
||||
|
||||
// The empty-list case is deliberately NOT the same as silence: the agent's own contract says a stanza
|
||||
// with a fresh checked_at and no guests means "the watchdog ran and found nothing to report", and that
|
||||
// must stay distinguishable from "the watchdog is not wired" — the shape the v0.91.0 inert seam hid
|
||||
// behind.
|
||||
func TestGuestNet_EmptyListIsNotSilence(t *testing.T) {
|
||||
s, st, _ := newRevealServer(t)
|
||||
cookie, _ := newRevealSession(t, s)
|
||||
seedNetHost(t, st, "demo-felhom-8363b5", "0.129.0",
|
||||
`{"host": {"cpu_percent": 1.0}, "guest_net": {"checked_at": "2026-08-13T08:15:33Z"}}`, "")
|
||||
|
||||
body := getHostPage(t, s, cookie, "demo-felhom-8363b5")
|
||||
|
||||
if !strings.Contains(body, "The watchdog ran and has no guest to report") {
|
||||
t.Fatal("an empty guest list must say the watchdog RAN")
|
||||
}
|
||||
if strings.Contains(body, "reported no guest-network state") {
|
||||
t.Error("an empty list was collapsed into silence — the two are different facts")
|
||||
}
|
||||
}
|
||||
|
||||
// assertNoHealthyBadgeInGuestNetCard checks that the Guest network card contains no healthy badge.
|
||||
// It slices the card out of the page rather than searching the whole body, because `badge-ok` occurs
|
||||
// all over a host page (capabilities, storage, WireGuard) and a whole-page search would pass
|
||||
// vacuously — which is the "instrument that can drop results silently" trap.
|
||||
func assertNoHealthyBadgeInGuestNetCard(t *testing.T, body string) {
|
||||
t.Helper()
|
||||
i := strings.Index(body, "Guest network")
|
||||
if i < 0 {
|
||||
t.Fatal("no Guest network card to slice — the assertion would have passed vacuously")
|
||||
}
|
||||
card := body[i:]
|
||||
if j := strings.Index(card, "</section>"); j >= 0 {
|
||||
card = card[:j]
|
||||
} else {
|
||||
t.Fatal("could not find the end of the Guest network card")
|
||||
}
|
||||
if strings.Contains(card, "badge-ok") {
|
||||
t.Errorf("an UNKNOWN guest-network state rendered a healthy badge:\n%s", card)
|
||||
}
|
||||
}
|
||||
|
||||
// A repair that was ATTEMPTED and FAILED is a harder fact than a repair that worked, and the count
|
||||
// alone cannot express it: six successful repairs is a nuisance, six failed ones is a guest that is
|
||||
// down right now. Dropping `heal_succeeded` from the decoder would be R-260 exactly — the OOB decoder
|
||||
// mirrored five of eight fields and the three it dropped included the deciding one.
|
||||
func TestGuestNet_FailedRepairIsDistinctFromFrequentRepair(t *testing.T) {
|
||||
s, st, _ := newRevealServer(t)
|
||||
cookie, _ := newRevealSession(t, s)
|
||||
seedNetHost(t, st, "demo-felhom-8363b5", "0.129.0", `{
|
||||
"host": {"cpu_percent": 1.0},
|
||||
"guest_net": {"checked_at": "2026-08-13T08:15:33Z",
|
||||
"guests": [{"vmid": 9201, "state": "unhealthy", "mode": "dhcp",
|
||||
"has_route": false, "dhclient_alive": false,
|
||||
"healed": true, "heal_succeeded": false, "heals_last_hour": 3,
|
||||
"message": "dhclient restart did not restore the lease"}]}}`, "")
|
||||
|
||||
body := getHostPage(t, s, cookie, "demo-felhom-8363b5")
|
||||
|
||||
if !strings.Contains(body, "repair failed") {
|
||||
t.Fatal("a repair that was attempted and failed is not distinguished from one that worked")
|
||||
}
|
||||
if !strings.Contains(body, "needs attention") {
|
||||
t.Error("a guest whose repair failed must summarise as needing attention")
|
||||
}
|
||||
assertNoHealthyBadgeInGuestNetCard(t, body)
|
||||
}
|
||||
@@ -252,15 +252,15 @@ const bindPageHTML = `<!DOCTYPE html>
|
||||
<div class="card">
|
||||
<h1>Felhom <span>doboz</span> összekötése</h1>
|
||||
{{if eq .State "form"}}
|
||||
<p class="lead">Kösd össze a most telepített Felhom dobozodat a fiókoddal. Add meg a doboz képernyőjén látható párosító kódot és a visszaállító jelszavadat.</p>
|
||||
{{if .Failed}}<div class="banner">A megadott adatok nem megfelelőek. Ellenőrizd a párosító kódot és a jelszót, majd próbáld újra.</div>{{end}}
|
||||
<p class="lead">Kösd össze a most telepített Felhom dobozodat a fiókoddal. Add meg a doboz képernyőjén látható párosító kódot és a tulajdonosi jelmondatodat.</p>
|
||||
{{if .Failed}}<div class="banner">A megadott adatok nem megfelelőek. Ellenőrizd a párosító kódot és a tulajdonosi jelmondatot, majd próbáld újra.</div>{{end}}
|
||||
<form method="POST" action="/bind/{{.Token}}">
|
||||
<label for="pairing_code">Párosító kód</label>
|
||||
<input class="code" type="text" id="pairing_code" name="pairing_code" autocomplete="off" autocapitalize="characters" spellcheck="false" required autofocus placeholder="ABC-234">
|
||||
<p class="hint">A doboz monitorán jelenik meg, a telepítés után.</p>
|
||||
<label for="passphrase">Visszaállító jelszó</label>
|
||||
<label for="passphrase">Tulajdonosi jelmondat</label>
|
||||
<input type="text" id="passphrase" name="passphrase" autocomplete="off" spellcheck="false" required placeholder="öt szó, kötőjellel vagy szóközzel">
|
||||
<p class="hint">Az öt szóból álló kifejezés, amelyet a beállításkor kaptál.</p>
|
||||
<p class="hint">Az öt szóból álló kifejezés, amelyet a beállításkor kaptál. Ez igazolja, hogy a fiók a tiéd.</p>
|
||||
<button type="submit">Összekötés</button>
|
||||
</form>
|
||||
<p class="note">Biztonsági okból 5 sikertelen próbálkozás után a hivatkozás zárolódik. Ilyenkor vedd fel a kapcsolatot az ügyfélszolgálattal.</p>
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
package web
|
||||
|
||||
// R-323 — THE THIRD NAME. One secret, one name, and none of them a near-homograph of another.
|
||||
//
|
||||
// Three secrets a customer can hold, and they must be tellable apart by a hurried reader:
|
||||
//
|
||||
// three words takes control of the dashboard „Beállító kód"
|
||||
// ten words opens the sealed off-site backups „Helyreállítási kód"
|
||||
// five words proves the account owns the box being bound „Tulajdonosi jelmondat" ← this one
|
||||
//
|
||||
// The five-word phrase used to be „Visszaállító jelszó" — one word away from „Visszaállító kód",
|
||||
// which R-295 had just retired for colliding with „Helyreállítási kód". Found while shipping that
|
||||
// rename and deliberately NOT swept in with it; ruled on separately by the operator 2026-08-13.
|
||||
//
|
||||
// WHY NOT THE OBVIOUS CANDIDATES, since a test is where the reasoning survives:
|
||||
//
|
||||
// „Összekötési jelszó" — the OTHER factor on this very page is the „Párosító kód". Naming this one
|
||||
// after the same act would leave the two factors a customer types in one sitting separated
|
||||
// only by kód-versus-jelszó, which is structurally the „Visszaállító kód"/„Visszaállító
|
||||
// jelszó" trap being removed.
|
||||
// „Fiókjelszó" — there IS an account password (the dashboard login). This would collide
|
||||
// with a DIFFERENT real secret, i.e. trade one homograph for a worse one.
|
||||
//
|
||||
// „Tulajdonosi jelmondat" is distinct on BOTH axes — stem (Tulajdonosi vs Beállító / Helyreállítási
|
||||
// / Párosító) and noun (jelmondat vs kód / jelszó) — and it says what the phrase actually does.
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-hub/internal/notify"
|
||||
"gitea.dooplex.hu/admin/felhom-hub/internal/store"
|
||||
)
|
||||
|
||||
// retiredThirdName is the name this change removes. It is a SUBSTRING check on the stem so that a
|
||||
// possessive or accusative form („visszaállító jelszavadat") cannot slip past a check written
|
||||
// against the nominative — the R-299 lesson, where a guard matched one inflection of a Hungarian
|
||||
// verb and the plural walked straight by.
|
||||
const retiredThirdName = "isszaállító jelsz"
|
||||
|
||||
// The binding page names the secret „Tulajdonosi jelmondat" and nowhere carries the retired name.
|
||||
// Driven through the real handler, so a template that never renders is visible here.
|
||||
func TestSelfBind_ThirdSecretNaming(t *testing.T) {
|
||||
s, st := newTestServer(t)
|
||||
selfBindSetup(t, st, "acme", testCode)
|
||||
token := mintLink(t, st, "acme", selfBindTTL)
|
||||
|
||||
body := bindGET(t, s, token).Body.String()
|
||||
|
||||
if !strings.Contains(body, "Tulajdonosi jelmondat") {
|
||||
t.Errorf("the field label must name the secret „Tulajdonosi jelmondat”:\n%s", body)
|
||||
}
|
||||
if strings.Contains(body, retiredThirdName) {
|
||||
t.Error("the retired name „Visszaállító jelszó” is back on the binding page")
|
||||
}
|
||||
// The two factors on this page must not be near-homographs of each other. The pairing code keeps
|
||||
// its name; what matters is that the SECOND factor no longer differs from it by one noun.
|
||||
if !strings.Contains(body, "Párosító kód") {
|
||||
t.Error("the pairing code lost its name — the two factors must both be named")
|
||||
}
|
||||
// Neither of the OTHER two secrets may be named on this page: a customer who reads „kód" here
|
||||
// twice is the failure this whole arc exists to prevent.
|
||||
for _, other := range []string{"Beállító kód", "Helyreállítási kód"} {
|
||||
if strings.Contains(body, other) {
|
||||
t.Errorf("the binding page names a different secret (%q) — that is the collision", other)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The failure banner must name the secret the same way the label does. A page that asks for a
|
||||
// „Tulajdonosi jelmondat" and then complains about „a jelszó" has two names for one secret again,
|
||||
// which is the defect in miniature.
|
||||
func TestSelfBind_FailureBannerUsesTheSameName(t *testing.T) {
|
||||
s, st := newTestServer(t)
|
||||
selfBindSetup(t, st, "acme", testCode)
|
||||
token := mintLink(t, st, "acme", selfBindTTL)
|
||||
|
||||
rr := bindPOST(t, s, token, testCodeFmt, "wrong wrong wrong wrong wrong")
|
||||
body := rr.Body.String()
|
||||
|
||||
if !strings.Contains(body, "tulajdonosi jelmondat") {
|
||||
t.Errorf("the failure banner does not name the secret the way the label does:\n%s", body)
|
||||
}
|
||||
if strings.Contains(body, retiredThirdName) {
|
||||
t.Error("the retired name is on the failure banner")
|
||||
}
|
||||
}
|
||||
|
||||
// The e-mail that carries the link names it identically. The mail is read BEFORE the page, so a
|
||||
// mismatch here is the customer's first impression of two different secrets.
|
||||
func TestSelfBindEmail_UsesTheSameName(t *testing.T) {
|
||||
subject, body := notify.FormatSelfBindEmail("acme", "https://hub.example/bind/tok")
|
||||
|
||||
if !strings.Contains(body, "tulajdonosi jelmondatodat") {
|
||||
t.Errorf("the self-bind mail does not name the secret „Tulajdonosi jelmondat”:\n%s", body)
|
||||
}
|
||||
if strings.Contains(subject+body, retiredThirdName) {
|
||||
t.Error("the retired name is still in the self-bind mail")
|
||||
}
|
||||
// It must still say what the thing IS — a rename that leaves the customer unable to recognise
|
||||
// what they are holding has fixed a collision and broken the delivery.
|
||||
if !strings.Contains(body, "5 szóból álló kifejezést") {
|
||||
t.Error("the mail no longer says the phrase is five words")
|
||||
}
|
||||
}
|
||||
|
||||
// THE ACCEPTANCE PIN — the whole point of calling this naming rather than function.
|
||||
//
|
||||
// The SAME phrase, typed the same messy way a human types it (odd spacing, mixed case, mixed
|
||||
// separators), still binds the appliance after the rename. If this ever goes red, the rename stopped
|
||||
// being a rename.
|
||||
func TestSelfBindPassphrase_StillAcceptedAfterTheRename(t *testing.T) {
|
||||
s, st := newTestServer(t)
|
||||
id := selfBindSetup(t, st, "acme", testCode)
|
||||
token := mintLink(t, st, "acme", selfBindTTL)
|
||||
|
||||
rr := bindPOST(t, s, token, testCodeFmt, " Alpha Beta gamma-delta epsilon ")
|
||||
|
||||
if rr.Code != http.StatusOK || !strings.Contains(rr.Body.String(), "egy percen belül") {
|
||||
t.Fatalf("the same passphrase stopped being accepted: code=%d body=%q", rr.Code, rr.Body.String())
|
||||
}
|
||||
if a, _ := st.GetAppliance(id); a == nil || a.Status != store.ApplianceBound {
|
||||
t.Fatalf("the appliance did not bind: %+v", a)
|
||||
}
|
||||
// The form field NAME is deliberately still `passphrase`: renaming customer copy must not touch
|
||||
// the wire. A changed field name would be an acceptance change wearing a rename's clothes.
|
||||
body := bindGET(t, s, mintLink(t, st, "acme", selfBindTTL)).Body.String()
|
||||
if !strings.Contains(body, `name="passphrase"`) {
|
||||
t.Error("the form field name changed — that is not a rename, that is a wire change")
|
||||
}
|
||||
}
|
||||
@@ -473,7 +473,7 @@
|
||||
{{if .Claim}}
|
||||
<form method="POST" action="/configs/{{.CustomerID}}/claim-resend" style="margin-top: 0.5rem;">
|
||||
{{.CSRFField}}
|
||||
<button type="submit" class="btn btn-outline btn-sm" data-confirm="Send a fresh code to the registered address? The previous code stops working immediately (the box activates it on its next report, ~15 min).">{{if .Claim.ClaimedAt}}Visszaállító kód küldése{{else}}Kód újraküldése{{end}}</button>
|
||||
<button type="submit" class="btn btn-outline btn-sm" data-confirm="Send a fresh code to the registered address? The previous code stops working immediately (the box activates it on its next report, ~15 min).">{{if .Claim.ClaimedAt}}Beállító kód küldése{{else}}Kód újraküldése{{end}}</button>
|
||||
</form>
|
||||
{{end}}
|
||||
|
||||
|
||||
@@ -317,6 +317,82 @@
|
||||
{{end}}
|
||||
</section>
|
||||
|
||||
<!-- Guest network (R-319): the R-54 watchdog's verdict per owned guest, and — the reason this
|
||||
card exists — HOW OFTEN IT HAD TO REPAIR EACH ONE. A guest the watchdog keeps fixing is
|
||||
healthy every time anyone looks and is nevertheless failing; showing only the state would
|
||||
give it a green tick, which is the failed-disk-drawn-as-a-healthy-empty-disk defect.
|
||||
|
||||
An unknown is NEVER drawn as healthy. Three absences, three sentences: an agent too old to
|
||||
report it, a capable agent that reported nothing, and a guest whose own state the watchdog
|
||||
did not assert. Each branch of this gate has its own render test (the template-gate rule).
|
||||
The agent has sent this on every heartbeat since v0.92.0 and nothing read it until now. -->
|
||||
<section class="card">
|
||||
<h2>Guest network
|
||||
{{if .GuestNet.AgentTooOld}}<span class="badge badge-neutral" title="This agent predates the guest-network watchdog">unknown</span>
|
||||
{{else if not .GuestNet.Reported}}<span class="badge badge-neutral" title="A capable agent sent no guest-network stanza">unknown</span>
|
||||
{{else if .GuestNet.Degraded}}<span class="badge badge-warn" title="A guest is unhealthy, or is being repaired repeatedly">needs attention</span>
|
||||
{{else if .GuestNet.UnknownCount}}<span class="badge badge-neutral" title="The watchdog did not assert a state for every guest">partly unknown</span>
|
||||
{{else if .GuestNet.Guests}}<span class="badge badge-ok" title="Every owned guest has an address, a default route and a live dhclient">healthy</span>
|
||||
{{end}}
|
||||
</h2>
|
||||
|
||||
{{if .GuestNet.AgentTooOld}}
|
||||
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem;">
|
||||
This host's agent (<code>{{.AgentVersion}}</code>) does not run the guest-network watchdog —
|
||||
its guests' networking is <strong>unknown</strong>, not healthy. Needs agent <code>0.92.0</code> or newer.
|
||||
</p>
|
||||
{{else if not .GuestNet.Reported}}
|
||||
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem;">
|
||||
This host reported no guest-network state, so it is <strong>unknown</strong> — not healthy.
|
||||
The watchdog is default-on; a silent capable agent means it was switched off
|
||||
(<code>guest_net.disable</code>), or this report predates it on this box.
|
||||
</p>
|
||||
{{else if .GuestNet.Guests}}
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr><th>Guest</th><th>State</th><th>Address</th><th>Route</th><th>dhclient</th><th>Repairs (1h)</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .GuestNet.Guests}}
|
||||
<tr>
|
||||
<td><code>{{.VMID}}</code></td>
|
||||
<td>
|
||||
{{if .Unknown}}<span class="badge badge-neutral" title="{{.Message}}">unknown</span>
|
||||
{{else if eq .State "healthy"}}<span class="badge badge-ok" title="{{.Message}}">healthy</span>
|
||||
{{else if eq .State "static_fault"}}<span class="badge badge-warn" title="{{.Message}}">static fault</span>
|
||||
{{else}}<span class="badge badge-error" title="{{.Message}}">unhealthy</span>{{end}}
|
||||
{{if .HealFailed}}<span class="badge badge-error" title="The watchdog TRIED to repair this guest and did not succeed">repair failed</span>{{end}}
|
||||
{{if .Damped}}<span class="badge badge-neutral" title="Repairs are rate-limited on this guest">damped</span>{{end}}
|
||||
</td>
|
||||
<td>{{if .IP}}<code>{{.IP}}</code> <span class="text-muted">({{.Mode}})</span>{{else}}<span class="text-muted">—</span>{{end}}</td>
|
||||
<td>{{if .HasRoute}}yes{{else}}<strong>no</strong>{{end}}</td>
|
||||
<td>{{if .DHClientAlive}}yes{{else if eq .Mode "static"}}<span class="text-muted">n/a</span>{{else}}<strong>no</strong>{{end}}</td>
|
||||
<td>
|
||||
{{if .Repairing}}<span class="badge badge-warn" title="The watchdog repaired this guest's network {{.RepairCount}} time(s) in the last hour — last at {{.LastHealAt}}">{{.RepairCount}}</span>
|
||||
{{else}}<span class="text-muted">0</span>{{end}}
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{if .GuestNet.RepairingCount}}
|
||||
<p class="hint" style="font-size: 0.85rem; margin-top: 0.5rem;">
|
||||
<strong>{{.GuestNet.RepairingCount}} guest(s) had their networking repaired in the last hour.</strong>
|
||||
A guest that keeps being repaired reads healthy between repairs and is not. A killed
|
||||
<code>dhclient</code> once took a tunnel down for 1 h 15 m with nobody told; this row is that signal.
|
||||
</p>
|
||||
{{end}}
|
||||
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem; margin-top: 0.5rem;">
|
||||
Last swept {{.GuestNet.CheckedAt}}. One row per owned <em>running</em> guest the watchdog has probed.
|
||||
</p>
|
||||
{{else}}
|
||||
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem;">
|
||||
The watchdog ran and has no guest to report (swept {{.GuestNet.CheckedAt}}). This is
|
||||
distinguishable from silence: the stanza arrived, its guest list is empty.
|
||||
</p>
|
||||
{{end}}
|
||||
</section>
|
||||
|
||||
<!-- DR / Backup -->
|
||||
<section class="card">
|
||||
<h2>DR / Backup</h2>
|
||||
|
||||
+1
-1
@@ -125,7 +125,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: hub
|
||||
image: gitea.dooplex.hu/admin/felhom-hub:0.102.0
|
||||
image: gitea.dooplex.hu/admin/felhom-hub:0.105.0
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
|
||||
@@ -324,7 +324,7 @@ spec:
|
||||
image: registry.k8s.io/git-sync/git-sync:v4.4.0
|
||||
args:
|
||||
- --repo=https://gitea.dooplex.hu/admin/felhom.eu.git
|
||||
- --ref=installer-v1.27.0
|
||||
- --ref=installer-v1.28.0
|
||||
- --root=/git-scripts
|
||||
- --link=current
|
||||
- --period=30s
|
||||
@@ -369,7 +369,7 @@ spec:
|
||||
image: registry.k8s.io/git-sync/git-sync:v4.4.0
|
||||
args:
|
||||
- --repo=https://gitea.dooplex.hu/admin/felhom.eu.git
|
||||
- --ref=installer-v1.27.0
|
||||
- --ref=installer-v1.28.0
|
||||
- --root=/git-scripts
|
||||
- --link=current
|
||||
- --one-time
|
||||
|
||||
@@ -1,3 +1,55 @@
|
||||
## felhom-host-install.sh v1.28.0 — the removal genuinely reverses the installation (2026-08-13, R-316)
|
||||
|
||||
**v1.27.0's fix worked exactly once per machine, and this is the measurement.** Three full cycles on
|
||||
`drill-r50` from `virgin`, on the PUBLISHED v1.27.0, before anything was changed:
|
||||
|
||||
| cycle | recorded | uninstall did | result |
|
||||
|---|---|---|---|
|
||||
| 1 | `no` | stop + disable | `:53` FREE |
|
||||
| 2 | **`yes`** | **left it running** | `0.0.0.0:53` taken |
|
||||
| 3 | — | — | **PRE-FLIGHT FAIL (exit 1)** — *"a resolver is already bound to :53"* |
|
||||
|
||||
**Why cycle 2 says `yes`:** the preflight asks `dpkg-query` whether `dnsmasq` is installed and nothing
|
||||
else — **package presence alone** (not the absence of a record). v1.27.0 stopped the unit and left the
|
||||
package, so the answer stayed yes and our own package became "the household's" one cycle later. **Every
|
||||
box already in the field is at cycle 2**, and a reinstall onto a machine that has had Felhom is cycle 2
|
||||
by definition.
|
||||
|
||||
**Now:** when the install-time record says we installed it, the uninstall **removes the package** as
|
||||
well as stopping the unit — which is what makes the next install a first install again. Order is
|
||||
unchanged and load-bearing: read the record, act, and only then delete the state file that holds it.
|
||||
|
||||
**TWO packages are recorded, not one.** `dnsmasq` ships the systemd unit; **`dnsmasq-base` ships
|
||||
`/usr/sbin/dnsmasq`**. They are separately installable, so each is recorded at preflight and taken back
|
||||
only if we added it.
|
||||
|
||||
**Guard rails, all measured on the box rather than reasoned:**
|
||||
|
||||
- **Ownership is read, never inferred** — no mtimes, no package metadata, no file dates.
|
||||
- **The dependency check is a SIMULATION.** `apt-get -s purge` is asked what it would remove, and the
|
||||
purge proceeds only if the answer is a subset of what we are entitled to remove. Otherwise: stop +
|
||||
disable, and the log names the package that stopped us.
|
||||
- **Never interactive, never fatal.** A wedged apt cannot strand a teardown — the failure is recorded
|
||||
and restated in the closing NOTE, because a half-completed teardown is how cycle 3 refuses.
|
||||
- **The success is asserted, not assumed:** after `apt-get` exits 0 the package is re-queried, because
|
||||
an exit code is not an observation.
|
||||
|
||||
**Scenarios, each watched:** three fixed cycles → **install 3 PASSES**; a household resolver →
|
||||
untouched; a dependent package (`household-dns-thing`) → **not purged, named in the log**, `:53` still
|
||||
freed; no ownership record → untouched, reason logged, exact command named.
|
||||
|
||||
**Red-proofs, mutation asserted applied each time:** remove the purge → **cycle 3 refuses again in
|
||||
those exact words**; remove the ownership check → **a household resolver is purged**; infer ownership
|
||||
when there is no record → **the guess is taken and a field box loses its own DNS**.
|
||||
|
||||
**Known residue, filed as R-317:** where `dnsmasq-base` pre-dated Felhom we correctly keep it, but it
|
||||
owns `/usr/sbin/dnsmasq`, which the agent stats to decide whether to install
|
||||
(`felhom-agent internal/lanresolver/lanresolver.go:105`). On that host shape the next install can skip
|
||||
the apt step and then fail to enable a unit that is gone. The uninstall says so explicitly rather than
|
||||
leaving it to be rediscovered from a silent resolver.
|
||||
|
||||
---
|
||||
|
||||
## PUBLISHED — `installer-v1.27.0` (2026-08-12)
|
||||
|
||||
**v1.26.0 (R-297) and v1.27.0 (R-300) were both written, pushed and deliberately left unpublished
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""customer_copy_vocab — THE ONE list of customer-copy vocabulary, shared by both repos.
|
||||
|
||||
WHY THIS FILE EXISTS AT ALL. Two guards need the same words: the controller's
|
||||
`retrieval_promise_gate.py` (which scans the box's own screens) and this repo's `hub_copy_gate.py`
|
||||
(which scans the hub's e-mails and binding pages). Two copies of a word list is not a theoretical
|
||||
risk here — it is the R-299 defect exactly: a guard asserted one inflection of a Hungarian verb and
|
||||
the plural, one paragraph above, walked straight past it. A second list drifts the same way.
|
||||
|
||||
So the list lives HERE, in `felhom.eu/scripts/`, which is already the established home for gates both
|
||||
repos consume without copying (`reuse_refs_check.py`, `instructions_gate.py` — the controller's own
|
||||
`controller_gates.py` runs them from this directory and FAILS when the sibling clone is absent, which
|
||||
is the fail-CLOSED shape a shared gate needs).
|
||||
|
||||
⚠ ADOPTION IS HALF DONE, AND SAYING SO IS THE POINT. `hub_copy_gate.py` imports this module.
|
||||
`felhom-controller/controller/scripts/retrieval_promise_gate.py` still carries its own `STEMS`
|
||||
literal, because the session that wrote this module was under a hard end-state requirement to leave
|
||||
felhom-controller untouched (its target box was being re-deployed the same evening). Until that gate
|
||||
imports this file, `hub_copy_gate.py` DRIFT-CHECKS it: it reads the controller gate's `STEMS` and
|
||||
fails if the two lists disagree. That gives single-source semantics tonight without a cross-repo
|
||||
edit — but it is a scaffold, not the destination. Register row: R-325.
|
||||
"""
|
||||
|
||||
# ── The retired names ────────────────────────────────────────────────────────────────────────────
|
||||
#
|
||||
# A name here is BANNED from customer-facing copy outright. Unlike the stems below, these are not
|
||||
# claims that might be true in context — they are names for a secret that a different secret now
|
||||
# owns, and a customer meeting one is being told two things have the same name.
|
||||
#
|
||||
# Each entry is a SUBSTRING, deliberately shorn of its leading capital and its ending, so a
|
||||
# possessive or accusative form cannot slip past a check written against the nominative:
|
||||
# „visszaállító jelszavadat" must convict as surely as „Visszaállító jelszó". That is the R-299
|
||||
# lesson applied to nouns instead of verbs.
|
||||
RETIRED_NAMES = {
|
||||
"isszaállító kód": (
|
||||
"R-295 (2026-08-10 box side, 2026-08-13 hub side). The THREE-word code that takes control of "
|
||||
"the dashboard is „Beállító kód”. „Visszaállító kód” was a near-homograph of the escrow "
|
||||
"„Helyreállítási kód” and the collision cost a real code."),
|
||||
"isszaállító jelsz": (
|
||||
"R-323 (2026-08-13). The FIVE-word phrase that proves the account owns the box being bound is "
|
||||
"„Tulajdonosi jelmondat”. „Visszaállító jelszó” was one word from the name retired above, and "
|
||||
"it was false besides — the phrase restores nothing."),
|
||||
}
|
||||
|
||||
# ── The retrieval-promise stems ──────────────────────────────────────────────────────────────────
|
||||
#
|
||||
# These are NOT banned. Each carries the claim "your old backups can be got back", which is sometimes
|
||||
# TRUE and must then be sayable. An occurrence must be REGISTERED with a reason in the consuming
|
||||
# gate's allowlist; an unregistered one fails.
|
||||
#
|
||||
# The docstring of the controller gate is the long version and is worth reading before adding a stem:
|
||||
# five instances of this claim surfaced ONE AT A TIME, and the obvious guard (ban the sentence) was
|
||||
# tried twice and failed twice.
|
||||
RETRIEVAL_STEMS = ["visszaállíthat", "visszaszerezhet", "visszahozhat", "visszanyit"]
|
||||
|
||||
# ── The three secrets, so a reviewer can check a name against the THING ───────────────────────────
|
||||
#
|
||||
# Not consumed by any check — it is here because every argument about these names has had to be
|
||||
# reconstructed from register rows, and the table is the argument.
|
||||
THE_THREE_SECRETS = [
|
||||
("three words", "takes control of the dashboard", "Beállító kód"),
|
||||
("ten words", "opens the sealed off-site backups", "Helyreállítási kód"),
|
||||
("five words", "proves the account owns the box being bound", "Tulajdonosi jelmondat"),
|
||||
]
|
||||
@@ -184,7 +184,7 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_VERSION="1.27.0" # the SINGLE version source (F-1): -h and the run banners follow it.
|
||||
SCRIPT_VERSION="1.28.0" # the SINGLE version source (F-1): -h and the run banners follow it.
|
||||
# The hub used to carry a copy for its Setup tab; R-94 DELETED it
|
||||
# (2026-08-02) because the hub cannot know which version a box runs —
|
||||
# the Setup command fetches this script at run time. scripts/
|
||||
@@ -842,6 +842,92 @@ _uninstall_statement() {
|
||||
# run_uninstall — the full guarded teardown. Every mutation goes through run() so --dry-run prints it
|
||||
# and executes nothing. Ordering is the reverse of install: guest -> agent -> pveum(ACL,token,user,
|
||||
# role) -> golden(opt-in) -> state file. See the TASK spec §7/§8.
|
||||
# _dnsmasq_purge_owned — remove the dnsmasq packages THIS install added, and nothing else (R-316).
|
||||
#
|
||||
# Called only from the `no` branch, i.e. only when the preflight RECORDED that we installed it. There
|
||||
# is no inference here and there must never be: no mtimes, no package metadata, no file dates. That
|
||||
# rule was earned and it is why the record exists at all.
|
||||
#
|
||||
# THE DEPENDENCY GUARD IS A SIMULATION, NOT A GUESS. `apt-get -s purge` is asked what it would do, and
|
||||
# the purge proceeds only if the answer names a subset of the packages we are entitled to remove. If
|
||||
# anything else would be dragged out, we STOP AND DISABLE instead and say which package stopped us —
|
||||
# a silent downgrade to the weaker action would be a warning standing beside a success.
|
||||
#
|
||||
# It can fail and the uninstall still succeeds: a wedged apt must not strand a teardown. Failure is
|
||||
# recorded in _DNSMASQ_PURGE_NOTE and reported in the closing statement, never swallowed.
|
||||
_DNSMASQ_PURGE_NOTE=""
|
||||
_dnsmasq_purge_owned() {
|
||||
local want=("dnsmasq")
|
||||
# dnsmasq-base ships /usr/sbin/dnsmasq and is separately installable — take it back only if we
|
||||
# added it too. Leaving a pre-existing base package is correct; see the WARN below for what that
|
||||
# costs on the next install.
|
||||
if [[ "$(_state_get dnsmasq_base_preexisting)" == "no" ]]; then
|
||||
want+=("dnsmasq-base")
|
||||
fi
|
||||
|
||||
if ! command -v apt-get >/dev/null 2>&1; then
|
||||
_DNSMASQ_PURGE_NOTE="apt-get absent — dnsmasq left installed (stopped + disabled)"
|
||||
log_warn " dnsmasq: apt-get not available — the package stays installed; the unit is stopped + disabled."
|
||||
return 0
|
||||
fi
|
||||
if $DRY_RUN; then
|
||||
log_dry "DEBIAN_FRONTEND=noninteractive apt-get -y purge ${want[*]} (after simulating the blast radius)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# What would come out? Every Remv/Purg line is a package this would remove.
|
||||
local sim removed extra=()
|
||||
sim=$(DEBIAN_FRONTEND=noninteractive apt-get -s purge "${want[@]}" 2>/dev/null) || sim=""
|
||||
if [[ -z "$sim" ]]; then
|
||||
_DNSMASQ_PURGE_NOTE="purge simulation failed — dnsmasq left installed (stopped + disabled)"
|
||||
log_warn " dnsmasq: could not simulate the removal — leaving the package installed (unit stopped + disabled)."
|
||||
log_warn " A reinstall will read it as pre-existing; clear it with: apt-get -y purge ${want[*]}"
|
||||
return 0
|
||||
fi
|
||||
removed=$(printf '%s\n' "$sim" | awk '/^(Remv|Purg) /{print $2}')
|
||||
local p
|
||||
for p in $removed; do
|
||||
case " ${want[*]} " in
|
||||
*" $p "*) ;;
|
||||
*) extra+=("$p") ;;
|
||||
esac
|
||||
done
|
||||
if (( ${#extra[@]} > 0 )); then
|
||||
_DNSMASQ_PURGE_NOTE="purge would also remove ${extra[*]} — dnsmasq left installed (stopped + disabled)"
|
||||
log_warn " dnsmasq: NOT purging — something else now depends on it. Removing it would also take out:"
|
||||
log_warn " ${extra[*]}"
|
||||
log_warn " The unit is stopped + disabled, so :53 is free. The package stays, deliberately."
|
||||
return 0
|
||||
fi
|
||||
|
||||
log_info " dnsmasq: removing the package(s) Felhom installed: ${want[*]}"
|
||||
if run env DEBIAN_FRONTEND=noninteractive apt-get -y purge "${want[@]}"; then
|
||||
# Positive observable: assert it is actually gone rather than trusting apt's exit code.
|
||||
if dpkg-query -W -f='${Status}' dnsmasq 2>/dev/null | grep -q "install ok installed"; then
|
||||
_DNSMASQ_PURGE_NOTE="apt-get reported success but dnsmasq is still installed"
|
||||
log_warn " dnsmasq: apt-get exited 0 but the package is STILL installed — treat as not removed."
|
||||
else
|
||||
log_success " dnsmasq removed — the next install starts from a clean slate, as a first install"
|
||||
fi
|
||||
else
|
||||
_DNSMASQ_PURGE_NOTE="apt-get purge failed — dnsmasq left installed (stopped + disabled)"
|
||||
log_warn " dnsmasq: the package removal FAILED. The unit is stopped + disabled, so :53 is free,"
|
||||
log_warn " but a reinstall will read the package as pre-existing. Clear it with:"
|
||||
log_warn " apt-get -y purge ${want[*]}"
|
||||
fi
|
||||
# R-316: the residual case, stated because it is invisible otherwise. If dnsmasq-base pre-dated us
|
||||
# we correctly leave it — but it owns /usr/sbin/dnsmasq, and the agent decides whether to install
|
||||
# by stat-ing exactly that path (felhom-agent internal/lanresolver/lanresolver.go:105). So on such
|
||||
# a host the next install skips the apt step and then fails to enable a unit that is no longer
|
||||
# there. Filed as R-317; named here so nobody has to rediscover it from a silent resolver.
|
||||
if [[ "$(_state_get dnsmasq_base_preexisting)" == "yes" ]]; then
|
||||
log_warn " NOTE: dnsmasq-base pre-dates Felhom and is deliberately kept. It owns /usr/sbin/dnsmasq,"
|
||||
log_warn " which the agent stats to decide whether to install — so on this host the next install"
|
||||
log_warn " may skip the install step and fail to enable the unit (R-317)."
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
run_uninstall() {
|
||||
log_step "UNINSTALL — local host teardown"
|
||||
|
||||
@@ -1098,8 +1184,22 @@ run_uninstall() {
|
||||
if $_dnsmasq_touched || systemctl is-enabled --quiet dnsmasq 2>/dev/null; then
|
||||
case "$_dnsmasq_owner" in
|
||||
no)
|
||||
# R-316 — STOPPING IS NOT REMOVING, AND THE DIFFERENCE COSTS THE *NEXT* CYCLE.
|
||||
#
|
||||
# R-300 stopped + disabled the unit and left the PACKAGE installed. That frees :53, so
|
||||
# cycle 1 looks fixed — and it is. But the next install's preflight asks dpkg "is
|
||||
# dnsmasq installed?", the answer is still yes, so it records `dnsmasq_preexisting=yes`,
|
||||
# the second uninstall then treats OUR OWN package as the household's and leaves it
|
||||
# running, and the third install refuses again with the message that blames the
|
||||
# customer's network. **Measured on drill-r50 2026-08-13, all three cycles, before this
|
||||
# was written.** Every box already in the field is at cycle 2.
|
||||
#
|
||||
# So: stop first (the port must free even if the package operation fails), then remove
|
||||
# what we added. Order matters — the state file that carries this record is deleted
|
||||
# later in this same function, so the record is read before it can be lost.
|
||||
log_info " dnsmasq was installed by Felhom (recorded at install) — stopping + disabling it"
|
||||
run systemctl disable --now dnsmasq || true
|
||||
_dnsmasq_purge_owned
|
||||
;;
|
||||
yes)
|
||||
log_info " dnsmasq pre-dates Felhom (recorded at install) — leaving it running, restarting only"
|
||||
@@ -1175,7 +1275,14 @@ run_uninstall() {
|
||||
# R-300: the packages are still not PURGED (they are system packages and purging them on a host we
|
||||
# may not own is the wrong blast radius) — but dnsmasq's UNIT is now stopped+disabled when the
|
||||
# install-time record says Felhom installed it, so our own leftover no longer blocks our own reinstall.
|
||||
log_info " NOTE: the 'sudo' and 'dnsmasq' packages were left INSTALLED (system packages, not purged); dnsmasq's unit was stopped+disabled only if Felhom installed it. The host record still exists in the hub — remove it there if desired."
|
||||
# R-316: this line used to say dnsmasq was left installed, and that was the defect in one sentence.
|
||||
# `sudo` genuinely is a system package and stays. dnsmasq is now taken back when the install-time
|
||||
# record says we added it — and when that could not be done, the reason is stated HERE rather than
|
||||
# scrolling past, because a teardown that quietly half-completed is how cycle 3 refuses.
|
||||
if [[ -n "$_DNSMASQ_PURGE_NOTE" ]]; then
|
||||
log_warn " NOTE: dnsmasq was NOT removed — $_DNSMASQ_PURGE_NOTE. Its unit is stopped + disabled, so :53 is free, but the NEXT install will read the package as pre-existing."
|
||||
fi
|
||||
log_info " NOTE: the 'sudo' package was left INSTALLED (a system package, never ours to remove). dnsmasq is removed only when the install-time record says Felhom installed it; a resolver that pre-dated Felhom is never touched. The host record still exists in the hub — remove it there if desired."
|
||||
$DRY_RUN && log_warn " DRY-RUN: nothing above was actually executed."
|
||||
return 0
|
||||
}
|
||||
@@ -1715,12 +1822,24 @@ step_preflight() {
|
||||
# heuristic dressed as a fact, and this project has been bitten by exactly that shape.
|
||||
#
|
||||
# Recorded on EVERY mode, because appliance is where the agent actually installs it.
|
||||
# R-316: TWO packages are recorded, not one, and the second is not pedantry.
|
||||
#
|
||||
# `dnsmasq` ships the systemd unit; **`dnsmasq-base` ships /usr/sbin/dnsmasq**. They are separately
|
||||
# installable, and a host can carry the base package for some unrelated reason. The removal must
|
||||
# take back only what WE added, so what we found has to be recorded package by package — the same
|
||||
# rule as before, applied one level finer.
|
||||
if command -v dpkg-query >/dev/null 2>&1 && dpkg-query -W -f='${Status}' dnsmasq 2>/dev/null | grep -q "install ok installed"; then
|
||||
_state_put dnsmasq_preexisting yes
|
||||
log_info " dnsmasq: already installed BEFORE Felhom — recorded; uninstall will not touch it"
|
||||
else
|
||||
_state_put dnsmasq_preexisting no
|
||||
log_info " dnsmasq: not present before Felhom — recorded; uninstall may stop+disable it if we install it"
|
||||
log_info " dnsmasq: not present before Felhom — recorded; uninstall will remove it again if we install it"
|
||||
fi
|
||||
if command -v dpkg-query >/dev/null 2>&1 && dpkg-query -W -f='${Status}' dnsmasq-base 2>/dev/null | grep -q "install ok installed"; then
|
||||
_state_put dnsmasq_base_preexisting yes
|
||||
log_info " dnsmasq-base: already installed BEFORE Felhom — recorded; uninstall will leave it"
|
||||
else
|
||||
_state_put dnsmasq_base_preexisting no
|
||||
fi
|
||||
|
||||
# Host DNS :53 gate (byo only) — GL-8/F6. In byo the agent's own lan-resolver stays OFF (a config
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""hub_copy_gate — the hub's customer-facing copy comes under a guard (R-324).
|
||||
|
||||
THE SCOPE GAP THIS CLOSES. `retrieval_promise_gate.py` lives in `felhom-controller` and scans that
|
||||
repo only. It was extended to Go string literals on 2026-08-12 (R-311) on the express ground that the
|
||||
recovery screen's messages are Go strings in a handler and "none of it had ever been scanned" — and
|
||||
the identical sentence was true one repo over the whole time. **The hub composes every customer
|
||||
e-mail and renders the binding pages: the first sentences a customer ever reads, before they have
|
||||
seen any box screen.** Nothing looked at them.
|
||||
|
||||
A hand scan on 2026-08-13 returned zero retrieval claims, so this was a SCOPE gap rather than a live
|
||||
defect — which is the moment to close it, before someone writes the first hub-side promise assuming
|
||||
the guard has them covered.
|
||||
|
||||
TWO CHECKS, and the difference is deliberate:
|
||||
|
||||
1. RETIRED NAMES — banned outright, scanned across the WHOLE hub, not just declared surfaces. A
|
||||
name for a secret that a different secret now owns is never correct anywhere, so there is no
|
||||
allowlist and no "unless". Comments are stripped: prose explaining a rename is not the rename
|
||||
coming back, and the register rows that record these decisions quote the retired names by
|
||||
necessity.
|
||||
|
||||
2. RETRIEVAL STEMS — registered, not banned, in the DECLARED customer-facing surfaces. The claim
|
||||
they carry is sometimes true and must stay sayable; what must not happen is a new one appearing
|
||||
where nobody was looking. Same contract as the controller gate: an occurrence is allowlisted
|
||||
WITH A REASON, and a stale allowlist entry is also a failure.
|
||||
|
||||
BOTH lists come from `customer_copy_vocab.py` — see that file for why they are not literals here.
|
||||
|
||||
DRIFT CHECK, and it is load-bearing. The controller gate still owns its own `STEMS` literal (the
|
||||
session that wrote this could not touch felhom-controller). This gate reads that literal and FAILS if
|
||||
it disagrees with the shared list, so the two cannot silently diverge in the meantime. An ABSENT
|
||||
sibling clone is INCONCLUSIVE (exit 2), never a pass — the G-1 lesson: a gate that skips when its
|
||||
sibling is missing runs in neither home.
|
||||
|
||||
Run: python3 scripts/hub_copy_gate.py (from the felhom.eu repo root)
|
||||
python3 scripts/hub_copy_gate.py --selftest (plant → convict → remove → pass)
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from customer_copy_vocab import RETIRED_NAMES, RETRIEVAL_STEMS # noqa: E402
|
||||
|
||||
_HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
_REPO = os.path.dirname(_HERE)
|
||||
_HUB = os.path.join(_REPO, "hub")
|
||||
|
||||
# The hub files that carry HUNGARIAN CUSTOMER-FACING text — the surfaces where a retrieval claim
|
||||
# could be made to a customer. Enumerated by scanning every non-test .go/.html under hub/internal for
|
||||
# accented Hungarian outside comments, then keeping the ones a CUSTOMER (not the operator) reads.
|
||||
#
|
||||
# A declared file that is missing is a FAILURE, never a skip: the controller gate learned that when a
|
||||
# renamed handler would have silently emptied its own scope.
|
||||
CUSTOMER_SURFACES = [
|
||||
os.path.join("hub", "internal", "notify", "templates.go"), # every customer e-mail + event copy
|
||||
os.path.join("hub", "internal", "web", "selfbind.go"), # the binding pages
|
||||
os.path.join("hub", "internal", "api", "handler.go"), # customer-visible event messages
|
||||
os.path.join("hub", "internal", "notify", "dispatcher.go"), # the customer channel's own wording
|
||||
]
|
||||
|
||||
# (file basename, substring that identifies the occurrence) -> why it is allowed.
|
||||
# Empty today, and that is a measurement rather than an oversight: the hub makes no retrieval promise.
|
||||
ALLOWLIST = {}
|
||||
|
||||
GO_COMMENT = re.compile(r"//[^\n]*|/\*.*?\*/", re.S)
|
||||
TPL_COMMENT = re.compile(r"\{\{/\*.*?\*/\}\}", re.S)
|
||||
HTML_COMMENT = re.compile(r"<!--.*?-->", re.S)
|
||||
|
||||
|
||||
def strip_comments(text, path):
|
||||
"""Remove what never reaches a customer.
|
||||
|
||||
Go `//` and `/* */`, Go-template `{{/* */}}`, and — unlike the controller gate — HTML `<!-- -->`
|
||||
too. The controller gate deliberately SCANS HTML comments because its templates ship to a browser
|
||||
where View Source is one keystroke. The hub's Hungarian lives in Go string literals that happen
|
||||
to contain HTML, and its operator templates are not customer copy, so an HTML comment here is a
|
||||
note to the next maintainer. Stated because it is a real difference between the two gates.
|
||||
"""
|
||||
text = TPL_COMMENT.sub("", text)
|
||||
text = HTML_COMMENT.sub("", text)
|
||||
if path.endswith(".go"):
|
||||
text = GO_COMMENT.sub("", text)
|
||||
return text
|
||||
|
||||
|
||||
def _iter_hub_sources():
|
||||
for root, _dirs, files in os.walk(os.path.join(_REPO, "hub", "internal")):
|
||||
for f in sorted(files):
|
||||
if f.endswith("_test.go") or not (f.endswith(".go") or f.endswith(".html")):
|
||||
continue
|
||||
yield os.path.join(root, f)
|
||||
|
||||
|
||||
def scan_retired(extra_text=None):
|
||||
"""Every retired name, everywhere in the hub. Returns a list of convictions."""
|
||||
convictions = []
|
||||
sources = [(p, open(p, encoding="utf-8").read()) for p in _iter_hub_sources()]
|
||||
if extra_text is not None:
|
||||
# The synthetic path MUST end in .go: strip_comments keys comment-stripping off the
|
||||
# extension, so a selftest source named anything else would be scanned WITH its comments —
|
||||
# which is how the first run of this selftest convicted its own step-3 control. The bug was
|
||||
# in the instrument, and the control is what found it.
|
||||
sources.append((os.path.join(_REPO, "hub", "internal", "selftest_planted.go"), extra_text))
|
||||
for path, raw in sources:
|
||||
text = strip_comments(raw, path)
|
||||
for name in RETIRED_NAMES:
|
||||
for m in re.finditer(re.escape(name), text):
|
||||
line = text[: m.start()].count("\n") + 1
|
||||
ctx = " ".join(text[max(0, m.start() - 70): m.end() + 70].split())[:150]
|
||||
convictions.append((os.path.relpath(path, _REPO), line, name, ctx))
|
||||
return convictions
|
||||
|
||||
|
||||
def scan_stems():
|
||||
"""Retrieval stems in the declared customer surfaces. Returns (convictions, seen_keys)."""
|
||||
convictions, seen = [], set()
|
||||
for rel in CUSTOMER_SURFACES:
|
||||
path = os.path.join(_REPO, rel)
|
||||
if not os.path.exists(path):
|
||||
raise SystemExit("hub-copy gate: declared customer surface is MISSING: %s" % rel)
|
||||
name = os.path.basename(path)
|
||||
text = strip_comments(open(path, encoding="utf-8").read(), path)
|
||||
for stem in RETRIEVAL_STEMS:
|
||||
for m in re.finditer(re.escape(stem) + r"[a-záéíóöőúüű]*", text):
|
||||
hit = None
|
||||
for k in (k for k in ALLOWLIST if k[0] == name):
|
||||
for om in re.finditer(re.escape(k[1]), text):
|
||||
if om.start() <= m.start() and m.end() <= om.end():
|
||||
hit = k
|
||||
break
|
||||
if hit:
|
||||
break
|
||||
if hit:
|
||||
seen.add(hit)
|
||||
else:
|
||||
line = text[: m.start()].count("\n") + 1
|
||||
ctx = " ".join(text[max(0, m.start() - 90): m.end() + 90].split())[:170]
|
||||
convictions.append((name, line, m.group(0), ctx))
|
||||
return convictions, seen
|
||||
|
||||
|
||||
def check_drift():
|
||||
"""The controller gate's STEMS must equal the shared list. Returns (status, message).
|
||||
|
||||
status: "ok" | "drift" | "inconclusive"
|
||||
"""
|
||||
sibling = os.path.join(os.path.dirname(_REPO), "felhom-controller",
|
||||
"controller", "scripts", "retrieval_promise_gate.py")
|
||||
if not os.path.exists(sibling):
|
||||
return "inconclusive", ("the felhom-controller clone is absent, so the shared stem list "
|
||||
"could not be compared against the gate that also uses it (%s)" % sibling)
|
||||
text = open(sibling, encoding="utf-8").read()
|
||||
m = re.search(r"^STEMS\s*=\s*\[(.*?)\]", text, re.M | re.S)
|
||||
if not m:
|
||||
return "drift", "could not find a STEMS list in the controller gate — its shape changed"
|
||||
theirs = re.findall(r"[\"']([^\"']+)[\"']", m.group(1))
|
||||
if theirs != RETRIEVAL_STEMS:
|
||||
return "drift", ("the controller gate's STEMS have diverged from customer_copy_vocab.py\n"
|
||||
" controller : %r\n shared : %r" % (theirs, RETRIEVAL_STEMS))
|
||||
return "ok", "controller gate's STEMS match the shared list (%d stem(s))" % len(theirs)
|
||||
|
||||
|
||||
def selftest():
|
||||
"""Plant → convict → remove → pass. A guard never seen catching anything proves nothing."""
|
||||
print("hub-copy gate SELFTEST")
|
||||
baseline = scan_retired()
|
||||
if baseline:
|
||||
print(" FAIL: the tree is not clean before planting — %d conviction(s)" % len(baseline))
|
||||
for c in baseline:
|
||||
print(" %s:%d [%s]" % (c[0], c[1], c[2]))
|
||||
return 1
|
||||
print(" 1. clean tree : 0 conviction(s) OK")
|
||||
|
||||
planted = 'body := "Add meg a visszaállító jelszavadat a folytatáshoz."\n'
|
||||
convicted = scan_retired(extra_text=planted)
|
||||
if len(convicted) != 1 or convicted[0][2] != "isszaállító jelsz":
|
||||
print(" 2. planted retired name : NOT CONVICTED — the guard is inert")
|
||||
print(" got: %r" % (convicted,))
|
||||
return 1
|
||||
print(" 2. planted „visszaállító jelszavadat”: CONVICTED (%s) OK" % convicted[0][2])
|
||||
|
||||
commented = '// the old name was „visszaállító jelszó" and is retired\n'
|
||||
if scan_retired(extra_text=commented):
|
||||
print(" 3. same phrase inside a COMMENT : convicted — comments must not be scanned")
|
||||
return 1
|
||||
print(" 3. same phrase inside a comment : not convicted OK")
|
||||
|
||||
if scan_retired():
|
||||
print(" 4. planting removed : still convicting — the scan is not deterministic")
|
||||
return 1
|
||||
print(" 4. planting removed : 0 conviction(s) OK")
|
||||
print("hub-copy gate selftest OK — the guard has been watched catching, ignoring and releasing")
|
||||
return 0
|
||||
|
||||
|
||||
def main():
|
||||
if "--selftest" in sys.argv:
|
||||
return selftest()
|
||||
|
||||
retired = scan_retired()
|
||||
stems, seen = scan_stems()
|
||||
stale = [k for k in ALLOWLIST if k not in seen]
|
||||
drift_status, drift_msg = check_drift()
|
||||
|
||||
for path, line, name, ctx in retired:
|
||||
print(" %s:%d RETIRED NAME in customer copy (%s):\n …%s…" % (path, line, name, ctx))
|
||||
print(" reason it is retired: %s" % RETIRED_NAMES[name])
|
||||
for name, line, word, ctx in stems:
|
||||
print(" %s:%d unregistered retrieval claim (%s):\n …%s…" % (name, line, word, ctx))
|
||||
for k in stale:
|
||||
print(" STALE ALLOWLIST ENTRY (no longer present): %s :: %r" % (k[0], k[1]))
|
||||
|
||||
n_files = len(list(_iter_hub_sources()))
|
||||
if retired or stems or stale:
|
||||
print("\nHUB-COPY GATE FAILED: %d retired name(s), %d unregistered claim(s), %d stale."
|
||||
% (len(retired), len(stems), len(stale)))
|
||||
print("A retired name is never correct in customer copy — use the current name. If a new")
|
||||
print("retrieval claim is genuinely TRUE where it renders, make it conditional on what the")
|
||||
print("hub can actually see, then register it in ALLOWLIST with the reason.")
|
||||
return 1
|
||||
|
||||
if drift_status == "drift":
|
||||
print(" DRIFT: %s" % drift_msg)
|
||||
print("\nHUB-COPY GATE FAILED: the shared vocabulary is no longer shared.")
|
||||
return 1
|
||||
|
||||
print("hub-copy gate OK — %d hub file(s) scanned for %d retired name(s); %d customer surface(s) "
|
||||
"scanned for %d retrieval stem(s), %d registered claim(s), none unregistered"
|
||||
% (n_files, len(RETIRED_NAMES), len(CUSTOMER_SURFACES), len(RETRIEVAL_STEMS), len(ALLOWLIST)))
|
||||
if drift_status == "inconclusive":
|
||||
print(" ⚠ INCONCLUSIVE (exit 2): %s" % drift_msg)
|
||||
return 2
|
||||
print(" drift: %s" % drift_msg)
|
||||
print(" (BLIND SPOT: this checks the WORDS in the four declared customer surfaces. It cannot")
|
||||
print(" tell whether a true-looking sentence is wired to a predicate that is actually true —")
|
||||
print(" that is what render tests are for. And it does not read the operator's screens.)")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -69,6 +69,9 @@ GATES = [
|
||||
("instructions", os.path.join(SCRIPTS, "instructions_gate.py"), [ROOT], True),
|
||||
("golden-currency", os.path.join(SCRIPTS, "golden_currency_gate.py"), [], True),
|
||||
("wire-contract", os.path.join(SCRIPTS, "wire_contract_gate.py"), [], True),
|
||||
# R-324 — the hub composes every customer e-mail and renders the binding pages, and until
|
||||
# 2026-08-13 no guard in either repo had ever looked at them. Fast: pure file reads.
|
||||
("hub-copy", os.path.join(SCRIPTS, "hub_copy_gate.py"), [], True),
|
||||
]
|
||||
|
||||
VERDICT = {0: "OK", 1: "FAILED", 2: "INCONCLUSIVE"}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""unproven.py — "which claims are not proven?", as a question a machine can answer (R-326).
|
||||
|
||||
WHY THIS EXISTS. The operator asked on 2026-08-04 to see what is built and what is still unproven.
|
||||
The picture was built (`where-felhom-stands.yaml` → `.html`) and it is good — but the QUESTION could
|
||||
only be answered by a person reading it. On 2026-08-13 a session was asked for "the nine grey claims",
|
||||
could not determine which nine, and declined to guess. It was right to decline, and the refusal is
|
||||
the finding this closes.
|
||||
|
||||
WHERE "NINE" CAME FROM, since a wrong number that matches nothing is worse than no number. It is
|
||||
real, and it answers a DIFFERENT question: nine claims carry `verdict: downgraded` — the count the
|
||||
2026-08-09 verification pass LOWERED. The count of claims that are not walked is 32. Both are true;
|
||||
only one of them is "what is unproven".
|
||||
|
||||
This reads the dataset only. It makes no judgement, opens no evidence and contacts no machine — a
|
||||
claim's status is the capability map's business (the map changes first; the dataset follows it), and
|
||||
`check_stands.py` is the gate that keeps the citations honest. This just answers the question.
|
||||
|
||||
Run: python3 scripts/unproven.py # every claim that is not walked
|
||||
python3 scripts/unproven.py --summary # the counts only
|
||||
"""
|
||||
import io
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
DATA = os.path.join(ROOT, "documentation", "architecture", "where-felhom-stands.yaml")
|
||||
|
||||
# The status that means "done end to end on real hardware, with evidence on file". Everything else is
|
||||
# a degree of not-that, which is the whole point of the question.
|
||||
PROVEN = "walked"
|
||||
|
||||
# Widest first, so the output reads as a ladder down from nearly-there to not-started.
|
||||
ORDER = ["partial", "built", "missing"]
|
||||
|
||||
|
||||
def field(entry, name):
|
||||
m = re.search(r"^\s*%s:\s*\"?(.*?)\"?\s*$" % name, entry, re.M)
|
||||
return m.group(1) if m else ""
|
||||
|
||||
|
||||
def load():
|
||||
if not os.path.exists(DATA):
|
||||
sys.exit("unproven: the dataset is missing: %s" % DATA)
|
||||
text = io.open(DATA, encoding="utf-8").read()
|
||||
parts = re.split(r"\n - id: ", text)
|
||||
header, entries = parts[0], parts[1:]
|
||||
if not entries:
|
||||
sys.exit("unproven: no claims parsed from %s — the file's shape changed" % DATA)
|
||||
claims = []
|
||||
for e in entries:
|
||||
claims.append({
|
||||
"id": e.split("\n", 1)[0].strip(),
|
||||
"status": field(e, "status") or "(none)",
|
||||
"title": field(e, "title"),
|
||||
"band": field(e, "band"),
|
||||
"verdict": field(e, "verdict"),
|
||||
"evidence": "evidence:" in e,
|
||||
})
|
||||
return field(header, "verified_on"), claims
|
||||
|
||||
|
||||
def main():
|
||||
verified_on, claims = load()
|
||||
not_walked = [c for c in claims if c["status"] != PROVEN]
|
||||
counts = {}
|
||||
for c in claims:
|
||||
counts[c["status"]] = counts.get(c["status"], 0) + 1
|
||||
|
||||
print("where felhom stands — %d claims, verified_on %s" % (len(claims), verified_on))
|
||||
print(" %-8s %d" % (PROVEN, counts.get(PROVEN, 0)))
|
||||
for s in ORDER:
|
||||
n = counts.get(s, 0)
|
||||
with_ev = sum(1 for c in claims if c["status"] == s and c["evidence"])
|
||||
print(" %-8s %d (%d cite evidence, %d prose only)" % (s, n, with_ev, n - with_ev))
|
||||
for s in sorted(k for k in counts if k not in ORDER + [PROVEN]):
|
||||
print(" %-8s %d ⚠ status not known to this script" % (s, counts[s]))
|
||||
print(" NOT WALKED: %d of %d" % (len(not_walked), len(claims)))
|
||||
|
||||
if "--summary" in sys.argv:
|
||||
return 0
|
||||
|
||||
print()
|
||||
for s in ORDER + sorted(k for k in counts if k not in ORDER + [PROVEN]):
|
||||
rows = [c for c in not_walked if c["status"] == s]
|
||||
if not rows:
|
||||
continue
|
||||
print("%s (%d)" % (s.upper(), len(rows)))
|
||||
for c in sorted(rows, key=lambda c: c["id"]):
|
||||
ev = "evidence" if c["evidence"] else "PROSE ONLY"
|
||||
vd = (" [%s]" % c["verdict"]) if c["verdict"] else ""
|
||||
print(" %-40s %-10s %s%s" % (c["id"], c["band"], ev, vd))
|
||||
print(" %s" % c["title"][:110])
|
||||
print()
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -81,6 +81,12 @@ ROOTS = [
|
||||
"controller", "internal/report", "Report", "hub"),
|
||||
("hub -> controller (report ACK, `escrow` object)",
|
||||
"hub", "internal/store", "EscrowStatus", "controller"),
|
||||
# R-311. Declared the moment the wire was created, because the gate covers only what is DECLARED
|
||||
# and a silent pass is indistinguishable from coverage. The hub response is a named type rather
|
||||
# than a map[string]any precisely so this root can resolve — an untyped map is a cross-repo
|
||||
# contract nothing can check.
|
||||
("hub -> agent (GET /hosts/<id>/escrow/retained)",
|
||||
"hub", "internal/api", "RetainedEscrowResponse", "agent"),
|
||||
]
|
||||
|
||||
# Tag names whose literal string carries no information in a repo-wide search. NOT CHECKED.
|
||||
@@ -97,13 +103,20 @@ GENERIC = {
|
||||
# someone must be able to re-check later, so none of them is bare. A quiet exclusion would be a
|
||||
# dropped field with paperwork, which is worse than the defect.
|
||||
#
|
||||
# TWO KINDS OF ENTRY, and the difference is deliberate:
|
||||
# THREE KINDS OF ENTRY, and the differences are deliberate:
|
||||
# * "redundant" — the hub already decodes something that answers the same question. No consumer
|
||||
# is wanted; the entry is the end of the matter.
|
||||
# * "R-264" — a fact with no consumer that ARGUABLY should have one. The entry does NOT
|
||||
# close the question; it records it against an OPEN register row so that
|
||||
# allowlisting cannot be mistaken for deciding. R-260 is closed by the gate plus
|
||||
# the operator-access fix; the leftover appetite is R-264.
|
||||
# * "not consumed, deliberately" — RULED by the operator, with the date. The question IS closed:
|
||||
# a reader was considered and declined on stated grounds. This kind was added on
|
||||
# 2026-08-13 because "arguably owed" had been carried for five days as though it
|
||||
# were a decision, and an undecided fact and a decided one must not read alike.
|
||||
# THE EMITTER IS DELIBERATELY LEFT ALONE: removing it is a coordinated two-repo
|
||||
# change and it also breaks the byte-identical cross-repo host-report golden. The
|
||||
# honest end here is a recorded decision, not a deletion.
|
||||
#
|
||||
# Keyed by (wire label, dotted emit path).
|
||||
_AH = "agent -> hub (POST /host-report)"
|
||||
@@ -117,6 +130,14 @@ _R264 = (
|
||||
"no consumer today, and one is arguably owed — recorded against R-264 (OPEN) rather than "
|
||||
"decided here. Allowlisting is not deciding.")
|
||||
|
||||
# RULED 2026-08-13 by the operator against R-264: these five were considered for a reader and
|
||||
# declined. The reason each is declined is per-entry below — a bare "not wanted" would be the quiet
|
||||
# exclusion this gate exists to prevent.
|
||||
_NOREADER = (
|
||||
"not consumed, DELIBERATELY — ruled 2026-08-13 (operator, against R-264). A reader was "
|
||||
"considered and declined; the question is closed, not open. The emitter stays (removing it is a "
|
||||
"two-repo change and breaks the host-report golden). ")
|
||||
|
||||
ALLOWLIST = {
|
||||
# ---- redundant: the hub already decodes an equivalent ----
|
||||
(_AH, "host.cpu_temp_c"): _REDUNDANT_HOST_METRICS,
|
||||
@@ -143,33 +164,54 @@ ALLOWLIST = {
|
||||
"redundant: hub-side wgsync reconciles peers from its own state, and the OOB path's own "
|
||||
"wg_handshake_age_s IS now decoded (into HostOOBRow, for the alert text)."),
|
||||
|
||||
# ---- no consumer, and one is arguably owed: R-264, OPEN ----
|
||||
(_AH, "guest_net"): _R264 + " The R-54 guest-network watchdog stanza (whole object).",
|
||||
(_AH, "guest_net.checked_at"): _R264,
|
||||
(_AH, "guest_net.guests.has_route"): _R264,
|
||||
(_AH, "guest_net.guests.dhclient_alive"): _R264,
|
||||
(_AH, "guest_net.guests.heal_succeeded"): _R264,
|
||||
(_AH, "guest_net.guests.heals_last_hour"): _R264,
|
||||
(_AH, "guest_net.guests.last_heal_at"): _R264,
|
||||
(_AH, "guest_net.guests.damped"): _R264,
|
||||
# ---- R-319: guest_net AND ALL SEVEN CHILDREN ARE GONE FROM THIS LIST ----
|
||||
# They are no longer allowlisted because they are no longer unconsumed: the hub models the R-54
|
||||
# watchdog stanza (web/hosts.go parseGuestNet → the host-detail Guest network card), including
|
||||
# heals_last_hour and heal_succeeded. Removing the entries is the POINT — an allowlisted tag is
|
||||
# SKIPPED by this gate, so leaving them here would mean the new reader's fields were never
|
||||
# actually checked for reachability, and the gate would report a coverage it did not have.
|
||||
# The first of R-264's readers; three groups remain owed one.
|
||||
|
||||
# ---- no consumer, and one is arguably owed: R-264, STILL OPEN ----
|
||||
(_AH, "selfupdate_pending"): _R264 + (
|
||||
" NOTE: the agent's own comment beside this field claimed 'the hub reads an absent field as "
|
||||
"pending=false, the correct default'. The hub had no field at all, so it read nothing "
|
||||
"either way. The comment was corrected in the same change as this entry."),
|
||||
(_AH, "selfupdate_pending_version"): _R264,
|
||||
(_AH, "mgmt_plane.healed_recently"): _R264 + (
|
||||
" The hub DOES alarm on mgmt_plane.privsep_healed_at, which is the timestamp beside this "
|
||||
"boolean, so the recurring-clobber signal is not lost — only this flag is."),
|
||||
(_AH, "pbs_dr.applied_at"): _R264,
|
||||
(_AH, "mgmt_plane.healed_recently"): _NOREADER + (
|
||||
"The recurring-clobber signal is NOT lost: the hub already alarms on "
|
||||
"mgmt_plane.privsep_healed_at, the timestamp sitting beside this boolean. A second reader "
|
||||
"for the flag would add a second way to say the same thing and no new fact."),
|
||||
(_AH, "pbs_dr.applied_at"): _NOREADER + (
|
||||
"A tier-applied TIMESTAMP, and the hub already decodes pbs_dr.state — which is the verdict. "
|
||||
"Presence is not success: consuming the timestamp without the state is precisely the "
|
||||
"attempt-read-as-result trap, and with the state it answers nothing further."),
|
||||
(_AH, "restore_tests.mount_parity"): _R264 + (
|
||||
" R-262: the hub's own comment claims this contract is mirrored field-for-field and that a "
|
||||
"key-set test guards drift; it is two fields short and the fixture omits the same two."),
|
||||
(_AH, "restore_tests.mount_inventory"): _R264 + " R-262, as mount_parity.",
|
||||
(_CH, "config_hash"): _R264,
|
||||
(_CH, "reporting_disabled"): _R264,
|
||||
(_CH, "stacks"): _R264 + (
|
||||
" The whole per-stack report object; the hub's app view is built from app_telemetry."),
|
||||
(_CH, "storage.migrated_to"): _R264,
|
||||
(_CH, "config_hash"): _NOREADER + (
|
||||
"A config FINGERPRINT. The hub authors the config and knows its own generation "
|
||||
"(desired_generation, config_version), which is the convergence question it actually asks. "
|
||||
"A hash it did not compute answers a question nobody has posed."),
|
||||
(_CH, "reporting_disabled"): (
|
||||
"redundant: the box sends health.status = \"disabled\" in the SAME minimal report "
|
||||
"(controller cmd/controller/main.go:1254), the hub decodes it into reports.health_status, and "
|
||||
"web/rollup.go:25 renders that customer as 'disabled'. The state IS visible; this flag is a "
|
||||
"second spelling of a fact already read. ⚠ DECIDED ON ITS OWN MERITS 2026-08-13, and the "
|
||||
"decision came with a REAL finding that a second decoded flag would NOT have fixed: "
|
||||
"StalenessChecker.Check (monitor/staleness.go:88+) is age-only — it skips BLOCKED customers "
|
||||
"and nothing else — so a deliberately-silent box still goes stale at 30 min and down at 60. "
|
||||
"Filed as R-321. The fix belongs in the checker, which already has the health status it "
|
||||
"needs; adding a field here would have felt like progress and left the alarm firing."),
|
||||
(_CH, "stacks"): _NOREADER + (
|
||||
"The whole per-stack report object. The hub's app view is built from app_telemetry, which is "
|
||||
"a purpose-built wire with its own table; a second, differently-shaped source for the same "
|
||||
"screen is how two answers to one question get shipped."),
|
||||
(_CH, "storage.migrated_to"): _NOREADER + (
|
||||
"A drive-migration marker: box-local bookkeeping about where data was moved ON that box. The "
|
||||
"hub holds no drive-layout intent to reconcile it against, so it could only be displayed, "
|
||||
"and a fact displayed with nothing to compare it to is decoration."),
|
||||
(_CH, "backup.last_db_dump"): _R264,
|
||||
(_CH, "backup.last_integrity_check"): _R264,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user