Add a Workshop stack with an InvenTree parts inventory - #512
Open
ChrisonSimtian wants to merge 3 commits into
Open
Add a Workshop stack with an InvenTree parts inventory#512ChrisonSimtian wants to merge 3 commits into
ChrisonSimtian wants to merge 3 commits into
Conversation
The validator deserialised a shape with YamlDotNet's object graph, which hands every scalar back as a string, and then re-typed each one by its text so the schema's integer/boolean constraints would evaluate. That re-typing could not see quoting, so `osVersion: "24.04"` was reported as a number and rejected against `string, integer` — a value the author had explicitly quoted and that ShapeLoader already reads as a string. Nothing hit it until now because every OS version in the lab was an integer (Debian 13). Ubuntu 24.04 is the first that is not, and widening the schema to accept a number would have been the wrong fix: 24.10 round-trips through a double as 24.1, silently requesting a different Ubuntu. Parse through the representation model instead, which preserves scalar style, and re-type only PLAIN scalars.
There is no record of what parts are on hand, so every build starts by guessing — re-ordering an ESP32 that is already in a drawer, or discovering mid-build that the one reed switch went into something else. It surfaced writing the garage-door BOM (SmartHome#48), where the honest instruction was "list everything, we will work out stock later", because there was nothing to check against. InvenTree over Part-DB and Homebox on one argument: it is the only one where a BOM and the stock are the same system, which is exactly the question being asked. CT 8000 on hpe-01 — always-on, and the node with disk to spare. Its own stack, in-tree. Every other stack runs something; this is record-keeping about the lab's physical parts and it serves every other stack's builds. Filing it under SmartHome because the first BOM happened to be a garage door would be an accident of chronology. ADR-0008 keeps cross-cutting stacks in-tree, and there are no blobs or separate audience here to pay the 2-PR tax for. The provisioner exists because ct/inventree.sh leaves an instance nobody can use: site_url points at the CT's DHCP address, and there is no superuser at all — `invoke superuser` is Django's interactive createsuperuser, so converge cannot call it. Both are closed through config keys InvenTree already reads, letting its own startup hook create the account (which skips an existing username, so a restart is not a reset).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #508.
Problem
There was no record of what parts are on hand, so every build started by guessing — re-ordering an ESP32 that is already in a drawer, or discovering mid-build that the one reed switch went into something else. It surfaced writing SmartHome#48, where the honest instruction was "list everything, we will work out stock later", because there was nothing to check against.
Outcome
Workshop — a new in-tree stack — running InvenTree on CT 8000 (
hpe-01, Ubuntu 24.04, 2 cores / 2 GB / 16 GB), at http://inventory.homelab.chrison.internal. Deployed, converged idempotently, and answering BOM-vs-stock over its API.InvenTree over Part-DB and Homebox on one argument: it is the only one of the three where a BOM and the stock are the same system, which is exactly the question being asked.
Its own stack, in-tree. Every other stack runs something — Core is the lifeline, Monitoring watches the lab, Media serves it, SmartHome automates the house, DevOps builds it. This is record-keeping about the lab's physical parts and serves every other stack's builds; filing it under SmartHome because the first BOM happened to be a garage door would be an accident of chronology. ADR-0008 keeps cross-cutting stacks in-tree, and there are no blobs or separate audience here to pay the 2-PR tax for.
What is in here
stacks/Workshop/— the stack (CTID block 8000–8099, skipping 7xxx because CT 7000shopdemois unmanaged) and theinventreemember, with a pinned reservation carryinginventory.homelab.chrison.internal.InvenTreeProvisioner—ct/inventree.shleaves an instance nobody can use:site_urlpoints at the DHCP address, and there is no superuser (invoke superuseris Django's interactivecreatesuperuser, so converge cannot call it). Both are closed through config keys InvenTree already reads, letting its own startup hook create the account — which skips an existing username, so a restart is not a reset.osVersion: "24.04"was rejected as a number. Widening the schema would have been the wrong fix —24.10round-trips through a double as24.1, silently requesting a different Ubuntu.INVENTREE_ADMIN_PASSWORDinsecrets.env.template+ Bitwarden SM. 13 new tests; 386/386 pass; 30/30 shapes valid.Verified live
CREATE→APPLIED→0 applied, 1 no-changeon re-run.admincreated; the Bitwarden password authenticates against the API and mints a token — end-to-end proof the no-trailing-newline handling is right.ds1813-nfs-volume-1, keep 7d/4w/3m. A proof run producedvzdump-lxc-8000-…tar.zst(695 MiB).Two things found on the way, filed separately
invoke updatefailed and an identical re-run succeeded (TransactionManagementErrorbehind aPRAGMA foreign_key_check). SQLite plus the services the postinstall had already started is the likely cause; documented in the stack README so aCREATE FAILEDhere does not trigger a needless rebuild.umaskbefore the redirect — a umask only applies when the redirect creates the file. Now an explicitchmod 600, with a test. Caught because the marker hashes the recipe, so the fix re-converged instead of no-opping.🤖 Generated with Claude Code