pixie-lab 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/.github/workflows/cicd.yaml +132 -0
  2. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/CHANGELOG.md +56 -0
  3. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/PKG-INFO +1 -1
  4. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/docs/src/deployment.md +25 -0
  5. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pyproject.toml +1 -1
  6. pixie_lab-0.3.0/src/pixie/catalog/__init__.py +49 -0
  7. pixie_lab-0.3.0/src/pixie/catalog/_live_env.py +128 -0
  8. pixie_lab-0.3.0/src/pixie/catalog/catalog.toml +81 -0
  9. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/events/_kinds.py +20 -0
  10. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/tui/_app.py +5 -3
  11. pixie_lab-0.3.0/src/pixie/web/_overlays.py +225 -0
  12. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_settings_store.py +23 -0
  13. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/catalog.html +2 -0
  14. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/dashboard.html +36 -29
  15. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/layout.html +6 -0
  16. pixie_lab-0.3.0/src/pixie/web/_templates/live_env.html +169 -0
  17. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/machine_detail.html +62 -96
  18. pixie_lab-0.3.0/src/pixie/web/_templates/overlays.html +248 -0
  19. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/settings.html +0 -58
  20. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/main.py +359 -44
  21. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/conftest.py +6 -0
  22. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/integration/conftest.py +7 -0
  23. pixie_lab-0.3.0/tests/test_catalog_seed.py +118 -0
  24. pixie_lab-0.3.0/tests/test_live_env_fetch.py +203 -0
  25. pixie_lab-0.3.0/tests/test_overlays_ui.py +255 -0
  26. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_settings.py +4 -4
  27. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_ui_pages.py +1 -2
  28. pixie_lab-0.2.0/src/pixie/catalog/__init__.py +0 -25
  29. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/.dockerignore +0 -0
  30. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/.github/workflows/docs.yml +0 -0
  31. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/.gitignore +0 -0
  32. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/Containerfile +0 -0
  33. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/LICENSE +0 -0
  34. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/Makefile +0 -0
  35. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/PLAN.md +0 -0
  36. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/README.md +0 -0
  37. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/configs/netboot-pc.toml +0 -0
  38. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/configs/test-pxe-flash-always.toml +0 -0
  39. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/configs/test-pxe-flash.toml +0 -0
  40. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/configs/test-pxe-inventory.toml +0 -0
  41. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/configs/test-pxe-nbdboot.toml +0 -0
  42. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/configs/test-pxe-tui.toml +0 -0
  43. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/configs/test-pxe.toml +0 -0
  44. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/configs/usbboot-pc.toml +0 -0
  45. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/scripts/live_build.py +0 -0
  46. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/scripts/pixie_ipxe_build.py +0 -0
  47. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/scripts/pixie_wheel_stage.py +0 -0
  48. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/scripts/pxe_flash_stage.py +0 -0
  49. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/scripts/pxe_inventory_stage.py +0 -0
  50. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/scripts/pxe_prepare.py +0 -0
  51. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/scripts/pxe_run_chain_test.py +0 -0
  52. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/scripts/usb_iso_build.py +0 -0
  53. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/tasks/netboot-pc.yaml +0 -0
  54. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/tasks/test-pxe-flash-always.yaml +0 -0
  55. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/tasks/test-pxe-flash.yaml +0 -0
  56. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/tasks/test-pxe-inventory.yaml +0 -0
  57. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/tasks/test-pxe-nbdboot.yaml +0 -0
  58. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/tasks/test-pxe-tui.yaml +0 -0
  59. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/tasks/test-pxe.yaml +0 -0
  60. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/cijoe/tasks/usbboot-pc.yaml +0 -0
  61. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/docs/audit.md +0 -0
  62. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/docs/src/boot-modes.md +0 -0
  63. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/docs/src/conf.py +0 -0
  64. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/docs/src/hardware-quirks.md +0 -0
  65. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/docs/src/index.md +0 -0
  66. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/docs/src/quickstart.md +0 -0
  67. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/docs/tooling/README.md +0 -0
  68. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/docs/tooling/pyproject.toml +0 -0
  69. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/docs/tooling/src/pixie_docs/__init__.py +0 -0
  70. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/docs/tooling/src/pixie_docs/cli.py +0 -0
  71. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/README.md +0 -0
  72. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/auxiliary/cloudinit-metadata.meta +0 -0
  73. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/auxiliary/ipxe-embed.ipxe +0 -0
  74. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/auxiliary/ipxe-local-general.h +0 -0
  75. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/auto/config +0 -0
  76. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/archives/backports.list.binary +0 -0
  77. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/archives/backports.list.chroot +0 -0
  78. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/bootloaders/grub-efi/splash.png +0 -0
  79. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/bootloaders/syslinux/splash.png +0 -0
  80. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/hooks/normal/0500-pixie-install.hook.chroot +0 -0
  81. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/hooks/normal/0500-pixie-skip-bootloader-menu.hook.binary +0 -0
  82. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/hooks/normal/0600-pixie-r8125-dkms.hook.chroot +0 -0
  83. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/hooks/normal/0700-pixie-clock-from-http.hook.chroot +0 -0
  84. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/hooks/normal/0800-pixie-ssh-live.hook.chroot +0 -0
  85. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/hooks/normal/0900-pixie-enable-services.hook.chroot +0 -0
  86. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/hooks/normal/0980-pixie-apt-validate.hook.chroot +0 -0
  87. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/etc/issue +0 -0
  88. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/etc/modprobe.d/zz-pixie-blacklist-nouveau.conf +0 -0
  89. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/etc/motd +0 -0
  90. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/etc/profile.d/pixie-version.sh +0 -0
  91. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/getty@.service.d/zzz-pixie-autologin-root.conf +0 -0
  92. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/pixie-banner-early.service +0 -0
  93. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/pixie-banner-late.service +0 -0
  94. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/pixie-banner-mid.service +0 -0
  95. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/pixie-clock-from-http.service +0 -0
  96. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/pixie-images-discover.service +0 -0
  97. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/pixie-on-tty1.service +0 -0
  98. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/pixie-usb-grow.service +0 -0
  99. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/var-lib-pixie-images.mount +0 -0
  100. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/etc/udev/rules.d/70-pixie-realtek-2g5-offloads.rules +0 -0
  101. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/usr/lib/systemd/system-generators/pixie-skip-usb-only-units-on-netboot +0 -0
  102. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/usr/local/sbin/pixie-boot-banner +0 -0
  103. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/usr/local/sbin/pixie-clock-from-http +0 -0
  104. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/usr/local/sbin/pixie-images-discover +0 -0
  105. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/usr/local/sbin/pixie-on-tty1 +0 -0
  106. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/usr/local/sbin/pixie-trace +0 -0
  107. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/includes.chroot/usr/local/sbin/pixie-usb-grow +0 -0
  108. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/package-lists/pixie-base.list.chroot +0 -0
  109. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/package-lists/pixie-flash.list.chroot +0 -0
  110. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/preferences/backports.pref.binary +0 -0
  111. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/pixie-media/live-build/config/preferences/backports.pref.chroot +0 -0
  112. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/__init__.py +0 -0
  113. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/_partition.py +0 -0
  114. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/_util.py +0 -0
  115. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/catalog/_fetcher.py +0 -0
  116. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/catalog/_routes.py +0 -0
  117. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/catalog/_schema.py +0 -0
  118. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/catalog/_store.py +0 -0
  119. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/deploy/__init__.py +0 -0
  120. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/deploy/_main.py +0 -0
  121. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/deploy/_templates.py +0 -0
  122. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/disks.py +0 -0
  123. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/events/__init__.py +0 -0
  124. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/events/_log.py +0 -0
  125. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/events/_routes.py +0 -0
  126. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/exports/__init__.py +0 -0
  127. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/exports/_routes.py +0 -0
  128. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/exports/_store.py +0 -0
  129. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/exports/_supervisor.py +0 -0
  130. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/flash.py +0 -0
  131. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/images.py +0 -0
  132. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/machines/__init__.py +0 -0
  133. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/machines/_routes.py +0 -0
  134. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/machines/_store.py +0 -0
  135. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/oras.py +0 -0
  136. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/pivot/__init__.py +0 -0
  137. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/pivot/nbdboot +0 -0
  138. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/pxe/__init__.py +0 -0
  139. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/pxe/_renderer.py +0 -0
  140. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/pxe/_routes.py +0 -0
  141. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/tftp/__init__.py +0 -0
  142. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/tftp/_supervisor.py +0 -0
  143. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/tui/__init__.py +0 -0
  144. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/tui_catalog.py +0 -0
  145. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/__init__.py +0 -0
  146. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_auth.py +0 -0
  147. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_bind_preview.py +0 -0
  148. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_inventory.py +0 -0
  149. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_static/.gitkeep +0 -0
  150. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_static/bootstrap-icons.min.css +0 -0
  151. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_static/bootstrap.min.css +0 -0
  152. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_static/fonts/bootstrap-icons.woff +0 -0
  153. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_static/fonts/bootstrap-icons.woff2 +0 -0
  154. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_static/htmx.min.js +0 -0
  155. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_static/pixie-favicon.png +0 -0
  156. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_static/sse.js +0 -0
  157. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_table_state.py +0 -0
  158. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/_partials/page_description.html +0 -0
  159. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/_partials/recent_events.html +0 -0
  160. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/_partials/table_helpers.html +0 -0
  161. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/catalog_detail.html +0 -0
  162. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/events.html +0 -0
  163. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/ipxe/bootstrap.j2 +0 -0
  164. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/ipxe/exit.j2 +0 -0
  165. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/ipxe/nbdboot.j2 +0 -0
  166. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/ipxe/pixie-live-env.j2 +0 -0
  167. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/ipxe/unavailable.j2 +0 -0
  168. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/login.html +0 -0
  169. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/src/pixie/web/_templates/machines.html +0 -0
  170. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/__init__.py +0 -0
  171. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/integration/__init__.py +0 -0
  172. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/integration/test_catalog_fetch.py +0 -0
  173. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/integration/test_deploy.py +0 -0
  174. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/integration/test_exports.py +0 -0
  175. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/integration/test_inventory.py +0 -0
  176. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/integration/test_pxe.py +0 -0
  177. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/integration/test_tftp.py +0 -0
  178. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_auth.py +0 -0
  179. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_catalog_api.py +0 -0
  180. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_deploy_unit.py +0 -0
  181. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_event_kinds.py +0 -0
  182. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_events_unit.py +0 -0
  183. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_exports_unit.py +0 -0
  184. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_fetch_progress.py +0 -0
  185. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_healthz.py +0 -0
  186. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_machines_unit.py +0 -0
  187. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_pivot.py +0 -0
  188. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_pxe_plan_json.py +0 -0
  189. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_schema.py +0 -0
  190. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_web_bind_preview.py +0 -0
  191. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/tests/test_web_inventory.py +0 -0
  192. {pixie_lab-0.2.0 → pixie_lab-0.3.0}/uv.lock +0 -0
@@ -17,6 +17,14 @@ name: cicd
17
17
  # version cannot be re-uploaded -- so the job gates on every
18
18
  # prior job (test + integration + build-container + build-wheel
19
19
  # + build-media + every PXE chain test) succeeding first.
20
+ # * ``publish-container``: build + push the appliance image to
21
+ # ghcr.io/<owner>/pixie (``:<version>`` + ``:latest``), v* tags
22
+ # only. Before this the image was smoke-built and thrown away, so
23
+ # the documented ghcr image was never populated by CI.
24
+ # * ``publish-release``: create the GitHub Release for the tag and
25
+ # attach the media ``build-media`` produces -- the netboot-pc
26
+ # live-env bake + the usbboot-pc bootable image + checksums. These
27
+ # used to live only as ephemeral, login-gated workflow artifacts.
20
28
  #
21
29
  # First publish (claiming the pixie-lab name) requires a one-time
22
30
  # PyPI setup: register a Pending Publisher on https://pypi.org
@@ -602,3 +610,127 @@ jobs:
602
610
  # later job is retrying), succeed silently rather than
603
611
  # fail.
604
612
  skip-existing: true
613
+
614
+ publish-container:
615
+ name: Publish container image to ghcr
616
+ # Build + push the appliance image to ghcr.io/<owner>/pixie on a
617
+ # v* tag: ``:<version>`` (the tag minus its leading ``v``) plus
618
+ # ``:latest``. This is the image the compose deploy runs; before
619
+ # this the ``build-container`` job only smoke-built it and threw it
620
+ # away, so ghcr.io/safl/pixie was never populated by CI. Gated on
621
+ # the whole pipeline like publish-pypi -- never ship an image the
622
+ # boot-chain tests did not pass against.
623
+ needs:
624
+ - test
625
+ - integration
626
+ - build-container
627
+ - build-wheel
628
+ - build-media
629
+ - test-pxe
630
+ - test-pxe-nbdboot
631
+ - test-pxe-inventory
632
+ - test-pxe-tui
633
+ - test-pxe-flash
634
+ - test-pxe-flash-always
635
+ runs-on: ubuntu-latest
636
+ if: startsWith(github.ref, 'refs/tags/v')
637
+ permissions:
638
+ contents: read
639
+ packages: write
640
+ steps:
641
+ - uses: actions/checkout@v6
642
+ - name: Log in to ghcr.io
643
+ run: |
644
+ echo "${{ secrets.GITHUB_TOKEN }}" \
645
+ | podman login ghcr.io -u "${{ github.actor }}" --password-stdin
646
+ - name: Build + push image
647
+ run: |
648
+ set -eu
649
+ IMAGE=ghcr.io/${{ github.repository_owner }}/pixie
650
+ VERSION=${GITHUB_REF_NAME#v}
651
+ podman build \
652
+ --build-arg PIXIE_VERSION="$VERSION" \
653
+ -t "$IMAGE:$VERSION" \
654
+ -t "$IMAGE:latest" \
655
+ -f Containerfile .
656
+ podman push "$IMAGE:$VERSION"
657
+ podman push "$IMAGE:latest"
658
+
659
+ publish-release:
660
+ name: Publish GitHub Release (media assets)
661
+ # Attach the media CI already builds -- the netboot-pc live-env
662
+ # bake (vmlinuz + initrd + squashfs) and the usbboot-pc bootable
663
+ # image -- to a GitHub Release on v* tags. Before this they only
664
+ # existed as ephemeral, login-gated workflow artifacts, so an
665
+ # operator had no released live-env or USB image to download. Same
666
+ # full-pipeline gate as the other publish jobs.
667
+ needs:
668
+ - test
669
+ - integration
670
+ - build-container
671
+ - build-wheel
672
+ - build-media
673
+ - test-pxe
674
+ - test-pxe-nbdboot
675
+ - test-pxe-inventory
676
+ - test-pxe-tui
677
+ - test-pxe-flash
678
+ - test-pxe-flash-always
679
+ runs-on: ubuntu-latest
680
+ if: startsWith(github.ref, 'refs/tags/v')
681
+ permissions:
682
+ contents: write
683
+ steps:
684
+ - uses: actions/checkout@v6
685
+ - name: Download media artifacts
686
+ uses: actions/download-artifact@v8
687
+ with:
688
+ # Both build-media matrix legs upload under this shape:
689
+ # ``pixie-netboot-pc-x86_64`` + ``pixie-usbboot-pc-x86_64``.
690
+ # merge-multiple flattens both into one directory.
691
+ pattern: pixie-*-pc-x86_64
692
+ merge-multiple: true
693
+ path: release-assets
694
+ - name: List release assets
695
+ run: ls -la release-assets
696
+ - name: Assemble live-env fetch tarball
697
+ # pixie's in-app "Fetch live-env" pulls ONE tarball that unpacks
698
+ # to vmlinuz + initrd + live.squashfs (see catalog/_live_env.py).
699
+ # Repackage the netboot-pc trio under those stable names so
700
+ # ``.../releases/latest/download/pixie-live-env-x86_64.tar.gz``
701
+ # -- the default PIXIE_LIVE_ENV_SRC -- resolves.
702
+ run: |
703
+ set -eu
704
+ d=$(mktemp -d)
705
+ cp release-assets/pixie-netboot-pc-x86_64-*.vmlinuz "$d/vmlinuz"
706
+ cp release-assets/pixie-netboot-pc-x86_64-*.initrd "$d/initrd"
707
+ cp release-assets/pixie-netboot-pc-x86_64-*.squashfs "$d/live.squashfs"
708
+ tar -C "$d" -czf release-assets/pixie-live-env-x86_64.tar.gz \
709
+ vmlinuz initrd live.squashfs
710
+ ( cd release-assets && sha256sum pixie-live-env-x86_64.tar.gz \
711
+ > pixie-live-env-x86_64.tar.gz.sha256 )
712
+ # Ship the curated catalog (the netboot-capable nosi subset)
713
+ # so DEFAULT_CATALOG_URL (.../releases/latest/download/catalog.toml)
714
+ # resolves and pixie's Import + live-env TUI default work.
715
+ cp src/pixie/catalog/catalog.toml release-assets/catalog.toml
716
+ ls -la release-assets
717
+ - name: Create / update GitHub Release
718
+ uses: softprops/action-gh-release@v2
719
+ with:
720
+ files: release-assets/*
721
+ # Fail loud if the glob matched nothing -- a release with no
722
+ # media is the bug this job exists to prevent.
723
+ fail_on_unmatched_files: true
724
+ generate_release_notes: true
725
+ body: |
726
+ ## Distribution
727
+
728
+ - Container image: `ghcr.io/${{ github.repository_owner }}/pixie:latest` and the matching version tag (this tag without the leading `v`).
729
+ - Python CLI: `uv tool install pixie-lab` (or `pip install pixie-lab`).
730
+
731
+ ## Media assets attached here
732
+
733
+ - `pixie-live-env-x86_64.tar.gz` — the live-env trio packaged for pixie's in-app **Fetch live-env** action (the default `PIXIE_LIVE_ENV_SRC`). Click Fetch live-env on the dashboard and pixie pulls + stages this itself; no manual bake or copy.
734
+ - `pixie-netboot-pc-x86_64-*.{vmlinuz,initrd,squashfs}` — the same live-env (netboot-pc bake) as loose files, if you prefer to stage `PIXIE_LIVE_ENV_DIR` (`data/live-env/`) by hand. Used by the `pixie-flash-once` / `pixie-flash-always` / `pixie-inventory` / `pixie-tui` boot modes.
735
+ - `pixie-usbboot-pc-x86_64-*.iso.gz` — bootable USB / ISO media for the pixie live env.
736
+ - `*.sha256` — checksums for the above.
@@ -11,6 +11,62 @@ operator-facing summary.
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [0.3.0] - 2026-07-23
15
+
16
+ Operator-facing surface + release plumbing. A fleet overlay-management
17
+ page, a tightened inventory view, and a dedicated live-env pane; the
18
+ release now ships the container image + boot media + a curated catalog,
19
+ and pixie can fetch its own live-env.
20
+
21
+ ### Added
22
+
23
+ **Fleet-wide overlay management page.** A new **Overlays** page
24
+ (`/ui/overlays`) lists every persistent nbdboot qcow2 across the fleet
25
+ with disk-used, last-modified, serving port, and a state
26
+ (active / idle / orphaned / missing); per-row Reset and a Prune that
27
+ reclaims only the orphaned + missing ones. The machine-detail Inventory
28
+ view was tightened from stacked stat-cards into one dense summary.
29
+
30
+ **Pixie ships a curated catalog and defaults to it, not nosi's.** A
31
+ fresh (empty) catalog is seeded on first start from a `catalog.toml`
32
+ bundled in the package: a strict subset of the upstream nosi catalog
33
+ restricted to the four netboot-capable images pixie's nbdboot + live-env
34
+ chains actually test and support (debian-13-headless, ubuntu-2404 /
35
+ 2604-headless, fedora-44-headless, each with its netboot bundle). The
36
+ desktop / proxmox / rpios / freebsd variants that have no netboot bundle
37
+ are omitted. The "Import catalog" field and the live-env TUI now default
38
+ to the pixie release copy of this curated catalog rather than the full
39
+ nosi catalog; both remain overridable by URL. Seeding is one-shot,
40
+ never clobbers an operator-populated catalog, and is disabled with
41
+ `PIXIE_SEED_CATALOG=0`.
42
+
43
+ **Pixie can fetch its own live-env, from a dedicated Live-env pane.** A
44
+ new **Live env** page (`/ui/live-env`) is the one place the live env is
45
+ managed: staged-media readiness, a **Fetch live env** action, the fetch
46
+ source, and the extra-kernel-cmdline override. Fetch downloads the
47
+ netboot-pc bake as a single tarball (`PIXIE_LIVE_ENV_SRC`, defaulting to
48
+ the latest GitHub release's `pixie-live-env-x86_64.tar.gz`) and stages
49
+ `vmlinuz` + `initrd` + `live.squashfs` under `PIXIE_LIVE_ENV_DIR`,
50
+ reusing the catalog fetch's curl transport. This replaces the only
51
+ artifact an operator previously had to bake locally
52
+ (`make build VARIANT=netboot-pc`) or hand-copy. The source is overridable
53
+ per deploy (point at a mirror for air-gapped installs). The dashboard
54
+ Live-env card is now status-only and links to the pane; the live-env
55
+ knobs moved off the Settings page. The `publish-release` job assembles
56
+ that tarball so the default source resolves.
57
+
58
+ **Releases now ship the container image and the boot media, not just
59
+ the PyPI package.** Tagging `v*` publishes the appliance image to
60
+ `ghcr.io/safl/pixie` (`:<version>` + `:latest`) and creates a GitHub
61
+ Release with the boot media attached: the netboot-pc live-env bake
62
+ (`vmlinuz` + `initrd` + `squashfs`) that the `pixie-flash-once` /
63
+ `pixie-flash-always` / `pixie-inventory` / `pixie-tui` modes chain
64
+ into, and the `usbboot-pc` bootable `.iso.gz`, each with a `.sha256`.
65
+ Previously a tag published only to PyPI, so the ghcr image that
66
+ `pixie-lab deploy` pins and the live-env media both existed only as
67
+ ephemeral CI artifacts or a local `make build` -- a fresh
68
+ `pixie-lab deploy` pulled an image that was never pushed.
69
+
14
70
  ## [0.2.0] - 2026-07-22
15
71
 
16
72
  First real release after the 0.1.0 skeleton: nbdboot (ephemeral +
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pixie-lab
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Bare-metal netboot appliance: catalog + fetch + NBD + PXE + TFTP + operator TUI in one container
5
5
  Project-URL: Homepage, https://github.com/safl/pixie
6
6
  Project-URL: Repository, https://github.com/safl/pixie
@@ -93,6 +93,20 @@ podman build -t pixie:local -f Containerfile .
93
93
  cd /opt/pixie && podman compose --env-file envvars up -d
94
94
  ```
95
95
 
96
+ ### Stage the live env
97
+
98
+ The `pixie-flash-*`, `pixie-inventory`, and `pixie-tui` boot modes chain
99
+ into pixie's live env (`vmlinuz` + `initrd` + `live.squashfs`). Open the
100
+ **Live env** page in the UI (`/ui/live-env`) and click **Fetch live
101
+ env**: pixie pulls the netboot-pc bake from `PIXIE_LIVE_ENV_SRC`
102
+ (default: the latest pixie GitHub release's
103
+ `pixie-live-env-x86_64.tar.gz`) and stages it under `PIXIE_LIVE_ENV_DIR`
104
+ itself - no manual bake or copy. For an air-gapped install, point
105
+ `PIXIE_LIVE_ENV_SRC` (or the live override on the Live env page) at a
106
+ local mirror of that tarball. You can still build it yourself with
107
+ `make build VARIANT=netboot-pc` and drop the three files into
108
+ `data/live-env/` by hand.
109
+
96
110
  ## Environment variables
97
111
 
98
112
  Pixie reads these at container startup. The compose file passes the
@@ -131,6 +145,17 @@ netboot bundles), `overlays/<mac>/<image_sha>/<profile>.qcow2`
131
145
  `pixie-*` boot modes degrade to an unavailable plan when this dir is
132
146
  missing or incomplete.
133
147
 
148
+ **`PIXIE_LIVE_ENV_SRC`** (default: the latest pixie GitHub release's
149
+ `pixie-live-env-x86_64.tar.gz`) - the tarball the dashboard **Fetch
150
+ live-env** action downloads and stages into `PIXIE_LIVE_ENV_DIR`.
151
+ Accepts `https://` or `oras://`; it must unpack to `vmlinuz` + `initrd`
152
+ + `live.squashfs`. Overridable live on the Live env page.
153
+
154
+ **`PIXIE_SEED_CATALOG`** (default: `1`) - seed a fresh (empty) catalog
155
+ from the bundled curated catalog (the netboot-capable nosi subset) on
156
+ first start. Set to `0` to start with an empty catalog. Runs once and
157
+ never overwrites an operator-populated catalog.
158
+
134
159
  ### NBD supervisor
135
160
 
136
161
  **`PIXIE_NBD_BIND`** (default: `0.0.0.0`) - address nbdkit binds
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pixie-lab"
3
- version = "0.2.0"
3
+ version = "0.3.0"
4
4
  description = "Bare-metal netboot appliance: catalog + fetch + NBD + PXE + TFTP + operator TUI in one container"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -0,0 +1,49 @@
1
+ """Operator-curated image library.
2
+
3
+ Pixie's catalog holds two peer entry shapes: **disk images**
4
+ (``format`` = ``img.gz`` / ``img.zst`` / ``img.xz`` / ``img`` / ...)
5
+ that pixie can flash to a target disk or serve over NBD for nbdboot,
6
+ and **netboot bundles** (``format`` = ``tar.gz``) whose contents pixie
7
+ unpacks into a content-addressed artifacts directory (vmlinuz +
8
+ initrd + manifest.json) so image-native nbdboot has kernel + initrd
9
+ URLs to serve.
10
+
11
+ Disk-image entries can carry a ``netboot_src`` field pointing at the
12
+ sibling bundle by URL; the two are peer catalog entries rather than
13
+ one nested under the other, so a nbdboot-only workflow can fetch a
14
+ bundle standalone and never touch a disk image.
15
+
16
+ There is ONE verb: :func:`pixie.catalog.fetch.fetch`. Downloads +
17
+ sha256s the bytes; if the entry's ``format`` is ``tar.gz``, additionally
18
+ unpacks vmlinuz + initrd + manifest.json into
19
+ ``<state_dir>/artifacts/<content-sha256>/``. Presence on disk IS
20
+ readiness; no ready/pending vocabulary, no auto-fetch, no misses page.
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ from importlib.resources import files
26
+
27
+ # Default "Import catalog" + live-env TUI source. Points at PIXIE's own
28
+ # release copy of the curated catalog (a subset of nosi's, restricted to
29
+ # the netboot-capable images pixie tests + supports), NOT the upstream
30
+ # nosi catalog. Operators can still import the full nosi catalog by URL;
31
+ # this is just the convenience default.
32
+ DEFAULT_CATALOG_URL = "https://github.com/safl/pixie/releases/latest/download/catalog.toml"
33
+
34
+ # The same curated catalog shipped INSIDE the package, used to seed a
35
+ # fresh (empty) catalog on first start so a plain deploy comes up with
36
+ # the known-good set offline -- no network, no release dependency.
37
+ BUNDLED_CATALOG_RESOURCE = "catalog.toml"
38
+
39
+ # Startup seeding is gated on this env (default on). Tests + operators
40
+ # who want an empty catalog set it to ``0``. A one-shot settings marker
41
+ # (below) records that the seed already ran so a later restart never
42
+ # re-seeds after an operator curated the catalog down.
43
+ SEED_CATALOG_ENV = "PIXIE_SEED_CATALOG"
44
+ CATALOG_SEEDED_KEY = "catalog.seeded"
45
+
46
+
47
+ def bundled_catalog_bytes() -> bytes:
48
+ """The curated ``catalog.toml`` shipped inside the package."""
49
+ return (files("pixie.catalog") / BUNDLED_CATALOG_RESOURCE).read_bytes()
@@ -0,0 +1,128 @@
1
+ """Fetch + stage the pixie live-env (the netboot-pc bake).
2
+
3
+ The live env -- ``vmlinuz`` + ``initrd`` + ``live.squashfs`` that the
4
+ ``pixie-flash-*`` / ``pixie-inventory`` / ``pixie-tui`` boot modes chain
5
+ into -- was the one artifact pixie could not retrieve itself: it had to
6
+ be baked locally (``make build VARIANT=netboot-pc``) or hand-copied into
7
+ ``PIXIE_LIVE_ENV_DIR``. This module pulls it from a single tarball
8
+ ``src`` (the same ``https://`` / ``oras://`` schemes the catalog fetch
9
+ speaks) and stages the three files atomically, reusing the catalog
10
+ fetch pipeline's curl download + resume plumbing.
11
+
12
+ Contract with CI's ``publish-release`` job: the tarball carries exactly
13
+ ``vmlinuz`` + ``initrd`` + ``live.squashfs`` at the archive root. Any
14
+ other member is ignored; a missing one is a hard error (better a loud
15
+ "tarball is wrong" than a live env that half-stages and boots into a
16
+ mysterious squashfs-fetch hang).
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import os
22
+ import shutil
23
+ import tarfile
24
+ import tempfile
25
+ from dataclasses import dataclass, field
26
+ from pathlib import Path
27
+
28
+ from pixie._util import CHUNK
29
+ from pixie.catalog._fetcher import (
30
+ FetchError,
31
+ ProgressReporter,
32
+ _resolve_fetch_url,
33
+ _stream_to_tmpfile,
34
+ )
35
+
36
+ # The three files a target's iPXE chain pulls from
37
+ # ``/boot/pixie-live-env/``. Names match what ``pixie-live-env.j2``
38
+ # references (note ``live.squashfs``, not the bake's raw ``*.squashfs``
39
+ # -- the CI tar step renames it).
40
+ LIVE_ENV_FILES: frozenset[str] = frozenset({"vmlinuz", "initrd", "live.squashfs"})
41
+
42
+
43
+ @dataclass
44
+ class LiveEnvResult:
45
+ """Outcome of a successful stage: the src it came from, the sha256
46
+ of the downloaded tarball, its byte size, and the staged file
47
+ sizes."""
48
+
49
+ src: str
50
+ sha256: str
51
+ size: int
52
+ files: dict[str, int] = field(default_factory=dict)
53
+
54
+
55
+ def _unpack_live_env_tar(tar_path: Path, live_env_dir: Path) -> dict[str, int]:
56
+ """Extract the live-env trio from ``tar_path`` into ``live_env_dir``
57
+ atomically. Returns ``{name: size_bytes}``.
58
+
59
+ Hardening mirrors :func:`pixie.catalog._fetcher._unpack_netboot_bundle`:
60
+ only basenames in :data:`LIVE_ENV_FILES` at the archive root are
61
+ accepted; nested paths, parent traversal, and dotfiles are dropped.
62
+ Files land in a staging subdir first, then each is ``os.replace``'d
63
+ onto its final name so a target fetching mid-stage sees the old
64
+ file or the new one, never a half-written squashfs.
65
+ """
66
+ live_env_dir.mkdir(parents=True, exist_ok=True)
67
+ staging = Path(tempfile.mkdtemp(prefix=".staging-", dir=str(live_env_dir)))
68
+ try:
69
+ # ``r:*`` transparently handles .tar / .tar.gz / .tar.xz so the
70
+ # CI side can pick whatever compression without a pixie change.
71
+ with tarfile.open(str(tar_path), mode="r:*") as tar:
72
+ for member in tar.getmembers():
73
+ if not member.isfile():
74
+ continue
75
+ name = os.path.basename(member.name)
76
+ if not name or name.startswith(".") or name != member.name:
77
+ continue
78
+ if name not in LIVE_ENV_FILES:
79
+ continue
80
+ extracted = tar.extractfile(member)
81
+ if extracted is None:
82
+ continue
83
+ with (staging / name).open("wb") as out:
84
+ shutil.copyfileobj(extracted, out, length=CHUNK)
85
+
86
+ missing = LIVE_ENV_FILES - {p.name for p in staging.iterdir()}
87
+ if missing:
88
+ raise FetchError(
89
+ f"live-env tarball {tar_path.name} missing required file(s): {sorted(missing)}"
90
+ )
91
+
92
+ sizes: dict[str, int] = {}
93
+ for name in sorted(LIVE_ENV_FILES):
94
+ final = live_env_dir / name
95
+ os.replace(staging / name, final)
96
+ sizes[name] = final.stat().st_size
97
+ return sizes
98
+ finally:
99
+ shutil.rmtree(staging, ignore_errors=True)
100
+
101
+
102
+ def stage_live_env(
103
+ src: str,
104
+ live_env_dir: Path,
105
+ *,
106
+ progress: ProgressReporter = None,
107
+ ) -> LiveEnvResult:
108
+ """Download the live-env tarball at ``src`` and stage its three
109
+ files into ``live_env_dir``.
110
+
111
+ Reuses the catalog fetch's curl transport (resume + retry + stall
112
+ detection). The tarball lands in ``live_env_dir`` itself so the
113
+ unpack + ``os.replace`` stay on one filesystem. Raises
114
+ :class:`FetchError` on an empty/bad src, an unsupported scheme, a
115
+ download failure, or a tarball missing a required file.
116
+ """
117
+ if not (src or "").strip():
118
+ raise FetchError("no live-env src configured (set PIXIE_LIVE_ENV_SRC)")
119
+ url, headers = _resolve_fetch_url(src.strip())
120
+ live_env_dir.mkdir(parents=True, exist_ok=True)
121
+ tmp_tar, sha256, size = _stream_to_tmpfile(url, headers, live_env_dir, progress)
122
+ try:
123
+ if progress is not None:
124
+ progress({"phase": "unpacking"})
125
+ sizes = _unpack_live_env_tar(tmp_tar, live_env_dir)
126
+ finally:
127
+ tmp_tar.unlink(missing_ok=True)
128
+ return LiveEnvResult(src=src.strip(), sha256=sha256, size=size, files=sizes)
@@ -0,0 +1,81 @@
1
+ version = 1
2
+
3
+ # pixie curated catalog -- a strict SUBSET of the upstream nosi catalog
4
+ # (https://github.com/safl/nosi/releases/latest/download/catalog.toml),
5
+ # restricted to the images that ship a netboot bundle. Those are the
6
+ # only images pixie's nbdboot chain (and the flash / inventory / tui
7
+ # live-env chains that ride the same bundle) actually test + support,
8
+ # so shipping just this subset keeps a fresh pixie's catalog to the
9
+ # known-good set instead of the full nosi menu (desktop / proxmox /
10
+ # rpios / freebsd variants have no netboot bundle and are omitted).
11
+ #
12
+ # Pixie seeds a fresh (empty) catalog from this file on first start and
13
+ # defaults its "Import catalog" + live-env TUI to the pixie release copy
14
+ # of it, rather than the nosi catalog. Override either freely; this is a
15
+ # convenience default, not a lock-in.
16
+ #
17
+ # Refs use the rolling ``:latest`` oras tags so the shipped catalog
18
+ # stays current without re-releasing pixie; the layer digest is still
19
+ # verified at fetch time. Each disk image cross-references its bundle by
20
+ # URL via ``netboot_src`` (pixie's tight form), so the nbdboot renderer
21
+ # resolves the pair without the legacy name-string ``netboot_ref``.
22
+
23
+ [[images]]
24
+ name = "nosi debian-13-headless"
25
+ src = "oras://ghcr.io/safl/nosi/debian-13-headless:latest"
26
+ format = "img.gz"
27
+ arch = "x86_64"
28
+ description = "Debian 13 (trixie) headless. General-purpose headless base with the nosi dev toolset."
29
+ netboot_src = "oras://ghcr.io/safl/nosi/debian-13-headless-netboot:latest"
30
+
31
+ [[images]]
32
+ name = "nosi debian-13-headless netboot bundle"
33
+ src = "oras://ghcr.io/safl/nosi/debian-13-headless-netboot:latest"
34
+ format = "tar.gz"
35
+ arch = "x86_64"
36
+ description = "Netboot bundle for debian-13-headless: vmlinuz + initrd so pixie can nbdboot it over NBD."
37
+
38
+ [[images]]
39
+ name = "nosi ubuntu-2404-headless"
40
+ src = "oras://ghcr.io/safl/nosi/ubuntu-2404-headless:latest"
41
+ format = "img.gz"
42
+ arch = "x86_64"
43
+ description = "Ubuntu 24.04 LTS (noble) headless. Broad driver support for CUDA / ROCm devices and Mellanox NICs / DPUs."
44
+ netboot_src = "oras://ghcr.io/safl/nosi/ubuntu-2404-headless-netboot:latest"
45
+
46
+ [[images]]
47
+ name = "nosi ubuntu-2404-headless netboot bundle"
48
+ src = "oras://ghcr.io/safl/nosi/ubuntu-2404-headless-netboot:latest"
49
+ format = "tar.gz"
50
+ arch = "x86_64"
51
+ description = "Netboot bundle for ubuntu-2404-headless: vmlinuz + initrd so pixie can nbdboot it over NBD."
52
+
53
+ [[images]]
54
+ name = "nosi ubuntu-2604-headless"
55
+ src = "oras://ghcr.io/safl/nosi/ubuntu-2604-headless:latest"
56
+ format = "img.gz"
57
+ arch = "x86_64"
58
+ description = "Ubuntu 26.04 LTS (resolute) headless. A more recent kernel and user-land on Ubuntu LTS."
59
+ netboot_src = "oras://ghcr.io/safl/nosi/ubuntu-2604-headless-netboot:latest"
60
+
61
+ [[images]]
62
+ name = "nosi ubuntu-2604-headless netboot bundle"
63
+ src = "oras://ghcr.io/safl/nosi/ubuntu-2604-headless-netboot:latest"
64
+ format = "tar.gz"
65
+ arch = "x86_64"
66
+ description = "Netboot bundle for ubuntu-2604-headless: vmlinuz + initrd so pixie can nbdboot it over NBD."
67
+
68
+ [[images]]
69
+ name = "nosi fedora-44-headless"
70
+ src = "oras://ghcr.io/safl/nosi/fedora-44-headless:latest"
71
+ format = "img.gz"
72
+ arch = "x86_64"
73
+ description = "Fedora 44 headless. An RHEL-family alternative (dnf, SELinux, EL package universe)."
74
+ netboot_src = "oras://ghcr.io/safl/nosi/fedora-44-headless-netboot:latest"
75
+
76
+ [[images]]
77
+ name = "nosi fedora-44-headless netboot bundle"
78
+ src = "oras://ghcr.io/safl/nosi/fedora-44-headless-netboot:latest"
79
+ format = "tar.gz"
80
+ arch = "x86_64"
81
+ description = "Netboot bundle for fedora-44-headless: vmlinuz + initrd so pixie can nbdboot it over NBD."
@@ -193,6 +193,24 @@ EVENTS_CLEARED = "events.cleared"
193
193
  right after the wipe so the freshly-empty log still records who reset
194
194
  it and when; carries the deleted-row count in ``details``."""
195
195
 
196
+ # ---------- live-env fetch ------------------------------------------
197
+ #
198
+ # The operator "Fetch live-env" action pulls the netboot-pc bake into
199
+ # PIXIE_LIVE_ENV_DIR. No subject (``subject_kind`` = ""): the live env
200
+ # is per-pixie, not per-resource. Dotted ``.done`` / ``.failed`` names
201
+ # mirror the catalog-fetch kinds so ``.failed`` auto-classifies as an
202
+ # error via the ERROR_KINDS ``LIKE '%.failed'`` probe.
203
+
204
+ LIVE_ENV_FETCH_DONE = "live_env.fetch.done"
205
+ """``POST /ui/live-env/fetch`` downloaded + staged vmlinuz + initrd +
206
+ live.squashfs into PIXIE_LIVE_ENV_DIR. Carries the src + content sha in
207
+ ``details``."""
208
+
209
+ LIVE_ENV_FETCH_FAILED = "live_env.fetch.failed"
210
+ """The live-env fetch failed (bad src scheme, download error, or a
211
+ tarball missing a required file). Carries the src + error in
212
+ ``details``."""
213
+
196
214
 
197
215
  # The canonical closed set. Every kind above is registered here; the
198
216
  # ``EventsLog.emit`` call rejects anything not in this frozenset.
@@ -228,6 +246,8 @@ KNOWN_EVENT_KINDS: frozenset[str] = frozenset(
228
246
  AUTH_LOGIN_SUCCEEDED,
229
247
  AUTH_LOGIN_FAILED,
230
248
  EVENTS_CLEARED,
249
+ LIVE_ENV_FETCH_DONE,
250
+ LIVE_ENV_FETCH_FAILED,
231
251
  }
232
252
  )
233
253
 
@@ -328,9 +328,11 @@ def collect_lshw(*, timeout: float = 30.0) -> object | None:
328
328
  # v0.46 stopped publishing a pixie-side catalog.toml mirror and pointed
329
329
  # pixie at the upstream image-builder (``safl/nosi``); the wizard's
330
330
  # ``[d] default`` shortcut tracks the same source so both consumers
331
- # resolve to one catalog. The pixie release no longer ships a
332
- # catalog.toml asset, so the old URL would 404.
333
- _BTY_DEFAULT_CATALOG_URL = "https://github.com/safl/nosi/releases/latest/download/catalog.toml"
331
+ # resolve to one catalog. Points at pixie's curated catalog (the
332
+ # netboot-capable nosi subset) shipped as a pixie release asset, so the
333
+ # live-env wizard defaults to the same known-good set the appliance
334
+ # seeds -- not the full upstream nosi catalog.
335
+ _BTY_DEFAULT_CATALOG_URL = "https://github.com/safl/pixie/releases/latest/download/catalog.toml"
334
336
 
335
337
 
336
338
  # ---------------------------------------------------------------------------