{"id":584,"date":"2025-12-31T18:42:25","date_gmt":"2026-01-01T02:42:25","guid":{"rendered":"https:\/\/blog.canutethegreat.com\/?p=584"},"modified":"2026-11-08T01:32:04","modified_gmt":"2026-11-08T09:32:04","slug":"horcrux-dev-log-2-my-own-forgejo-a-gentoo-iso-builder-and-an-iso-that-never-quite-booted","status":"publish","type":"post","link":"https:\/\/blog.canutethegreat.com\/index.php\/2025\/12\/31\/horcrux-dev-log-2-my-own-forgejo-a-gentoo-iso-builder-and-an-iso-that-never-quite-booted\/","title":{"rendered":"Horcrux dev log 2: my own Forgejo, a Gentoo ISO builder, and an ISO that never quite booted"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><em>Part 2 in the Horcrux dev log series.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Backdated, written in November 2026 from the repo history. <a href=\"https:\/\/blog.canutethegreat.com\/index.php\/2025\/10\/13\/horcrux-dev-log-1-the-first-week-lots-of-code-and-no-tests-that-ran\/\">Part 1<\/a> was the first week in October.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nothing happened in the repo for two months after the October burst. Then on December 12 there were three commits: &#8220;Major platform enhancements and infrastructure cleanup&#8221;, &#8220;storage, ha, and clustering improvements&#8221; and &#8220;added forgejo workflows&#8221;. The last one matters because I&#8217;d decided to host the code on my own Forgejo and run CI on my own runners.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It didn&#8217;t work. Between December 12 and 31 Forgejo recorded nine workflow runs for Horcrux, all of them skipped. The workflows were copied from GitHub Actions and asked for <code>ubuntu-latest<\/code>, which none of my runners had. A job with no matching runner is skipped, not failed, so nothing showed up red. I&#8217;ll come back to that in part 3.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The big commit<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">On the 19th: &#8220;Refactor Web UI into modular pages and add Gentoo build system&#8221;, 129 files, 47,358 insertions. The UI had been a few enormous page files. Now it&#8217;s modules for audit, auth, backup, dashboard, HA, Kubernetes, metrics, monitoring, storage and system. The same commit added a Gentoo\/Catalyst ISO build system.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On the 29th there was a batch of NAS features (SMB and NFS among them) and a CLI output cleanup.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The ISO commits<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The last commits of the year are all about booting. Five of them:<\/p>\n\n\n\n<pre tabindex=\"0\" class=\"wp-block-code\"><code>c01076e4 Fix ISO build to include kernel and bootloader\n  \"The ISO builder was creating incomplete ISOs missing critical boot components.\"\nb5531304 Improve ISO build with initramfs library support and robustness\n385e3e3b Add serial console support to ISO boot configuration\n  \"Enables boot output visibility when testing in QEMU\"\n(Dec 31) Fix ISO boot with kernel modules and proper init system\n(Dec 31) Fix library copying for horcrux binaries in ISO<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So the first version of the builder made ISOs with no kernel and no bootloader. Each commit fixes whatever the last one exposed: kernel and GRUB, then initramfs libraries, then a serial console so I could watch QEMU, then modules and an init system, then the shared libraries for the Horcrux binaries. I can&#8217;t find a commit where it reaches a login prompt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">State<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The codebase got bigger. As far as I can tell, the ISO script still didn&#8217;t produce a bootable image, and none of the nine CI runs executed. After December 31 the repo is silent until September 24, 2026.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Design decisions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The installer is a Gentoo ISO because Horcrux is Gentoo first. For me that comes down to freedom to choose: USE flags are the main reason, and compiling for specific hardware is the second. I&#8217;ve used Gentoo since 2006. The image is built with Gentoo&#8217;s Catalyst.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The other change in December was hosting. The code and CI moved from GitHub to my own Forgejo, which is now the primary. GitHub likes to block things, so I&#8217;d rather not depend on it. The repos are still mirrored there. The copied workflows asked for a runner label that mine didn&#8217;t have, which is why every run was skipped.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Other parts: <a href=\"https:\/\/blog.canutethegreat.com\/index.php\/2025\/10\/13\/horcrux-dev-log-1-the-first-week-lots-of-code-and-no-tests-that-ran\/\">Part 1<\/a>. The series continues with <a href=\"https:\/\/blog.canutethegreat.com\/index.php\/2026\/11\/07\/horcrux-dev-log-ha-live-migration-three-old-laptops\/\">the latest Horcrux dev log post<\/a>.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>December 2025: Horcrux moves to my own Forgejo, gets a Gentoo\/Catalyst ISO build system, and the year ends with me still fixing boot problems.<\/p>\n","protected":false},"author":1,"featured_media":608,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22,26],"tags":[364,164,361,365,291],"class_list":["post-584","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-linux","category-software-engineering","tag-forgejo","tag-gentoo","tag-horcrux-dev-log","tag-iso","tag-rust"],"_links":{"self":[{"href":"https:\/\/blog.canutethegreat.com\/index.php\/wp-json\/wp\/v2\/posts\/584","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.canutethegreat.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.canutethegreat.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.canutethegreat.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.canutethegreat.com\/index.php\/wp-json\/wp\/v2\/comments?post=584"}],"version-history":[{"count":5,"href":"https:\/\/blog.canutethegreat.com\/index.php\/wp-json\/wp\/v2\/posts\/584\/revisions"}],"predecessor-version":[{"id":648,"href":"https:\/\/blog.canutethegreat.com\/index.php\/wp-json\/wp\/v2\/posts\/584\/revisions\/648"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.canutethegreat.com\/index.php\/wp-json\/wp\/v2\/media\/608"}],"wp:attachment":[{"href":"https:\/\/blog.canutethegreat.com\/index.php\/wp-json\/wp\/v2\/media?parent=584"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.canutethegreat.com\/index.php\/wp-json\/wp\/v2\/categories?post=584"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.canutethegreat.com\/index.php\/wp-json\/wp\/v2\/tags?post=584"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}