pixie-lab 0.4.3__tar.gz → 0.4.4__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 (199) hide show
  1. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/CHANGELOG.md +11 -0
  2. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/PKG-INFO +14 -7
  3. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/README.md +13 -6
  4. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/docs/src/deployment.md +35 -29
  5. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/docs/src/hardware-quirks.md +7 -7
  6. pixie_lab-0.4.4/docs/src/quickstart.md +85 -0
  7. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pyproject.toml +1 -1
  8. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/events/_kinds.py +9 -1
  9. pixie_lab-0.4.4/src/pixie/web/_templates/live_env.html +197 -0
  10. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/main.py +135 -3
  11. pixie_lab-0.4.4/tests/test_live_env_setup.py +119 -0
  12. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/uv.lock +1 -1
  13. pixie_lab-0.4.3/docs/src/quickstart.md +0 -97
  14. pixie_lab-0.4.3/src/pixie/web/_templates/live_env.html +0 -122
  15. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/.dockerignore +0 -0
  16. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/.github/workflows/cicd.yaml +0 -0
  17. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/.github/workflows/docs.yml +0 -0
  18. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/.gitignore +0 -0
  19. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/Containerfile +0 -0
  20. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/LICENSE +0 -0
  21. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/Makefile +0 -0
  22. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/PLAN.md +0 -0
  23. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/configs/live-env-image.toml +0 -0
  24. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/configs/test-pxe-live-env-modes.toml +0 -0
  25. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/configs/test-pxe-nbdboot.toml +0 -0
  26. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/configs/test-pxe.toml +0 -0
  27. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/configs/test-usb-ventoy.toml +0 -0
  28. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/configs/usbboot-pc.toml +0 -0
  29. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/scripts/live_env_image.py +0 -0
  30. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/scripts/live_env_transform.sh +0 -0
  31. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/scripts/pixie_ipxe_build.py +0 -0
  32. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/scripts/pixie_wheel_stage.py +0 -0
  33. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/scripts/pxe_prepare.py +0 -0
  34. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/scripts/pxe_run_chain_test.py +0 -0
  35. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/scripts/usb_iso_build.py +0 -0
  36. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/scripts/usb_iso_verify.py +0 -0
  37. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/scripts/usb_ventoy_guest_start.py +0 -0
  38. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/scripts/usb_ventoy_stage.py +0 -0
  39. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/tasks/live-env-image.yaml +0 -0
  40. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/tasks/test-pxe-live-env-modes.yaml +0 -0
  41. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/tasks/test-pxe-nbdboot.yaml +0 -0
  42. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/tasks/test-pxe.yaml +0 -0
  43. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/tasks/test-usb-ventoy.yaml +0 -0
  44. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/cijoe/tasks/usbboot-pc.yaml +0 -0
  45. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/docs/audit.md +0 -0
  46. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/docs/src/boot-modes.md +0 -0
  47. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/docs/src/conf.py +0 -0
  48. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/docs/src/index.md +0 -0
  49. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/docs/tooling/README.md +0 -0
  50. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/docs/tooling/pyproject.toml +0 -0
  51. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/docs/tooling/src/pixie_docs/__init__.py +0 -0
  52. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/docs/tooling/src/pixie_docs/cli.py +0 -0
  53. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/README.md +0 -0
  54. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/auxiliary/cloudinit-metadata.meta +0 -0
  55. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/auxiliary/ipxe-embed.ipxe +0 -0
  56. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/auxiliary/ipxe-local-general.h +0 -0
  57. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/auto/config +0 -0
  58. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/archives/backports.list.binary +0 -0
  59. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/archives/backports.list.chroot +0 -0
  60. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/bootloaders/grub-efi/splash.png +0 -0
  61. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/bootloaders/syslinux/splash.png +0 -0
  62. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/hooks/normal/0500-pixie-install.hook.chroot +0 -0
  63. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/hooks/normal/0500-pixie-skip-bootloader-menu.hook.binary +0 -0
  64. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/hooks/normal/0600-pixie-r8125-dkms.hook.chroot +0 -0
  65. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/hooks/normal/0700-pixie-clock-from-http.hook.chroot +0 -0
  66. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/hooks/normal/0800-pixie-ssh-live.hook.chroot +0 -0
  67. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/hooks/normal/0900-pixie-enable-services.hook.chroot +0 -0
  68. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/hooks/normal/0980-pixie-apt-validate.hook.chroot +0 -0
  69. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/etc/initramfs-tools/conf.d/pixie-modules-most +0 -0
  70. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/etc/issue +0 -0
  71. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/etc/modprobe.d/zz-pixie-blacklist-nouveau.conf +0 -0
  72. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/etc/motd +0 -0
  73. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/etc/profile.d/pixie-version.sh +0 -0
  74. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/getty@.service.d/zzz-pixie-autologin-root.conf +0 -0
  75. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/pixie-banner-early.service +0 -0
  76. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/pixie-banner-late.service +0 -0
  77. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/pixie-banner-mid.service +0 -0
  78. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/pixie-clock-from-http.service +0 -0
  79. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/pixie-images-discover.service +0 -0
  80. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/pixie-on-tty1.service +0 -0
  81. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/pixie-usb-grow.service +0 -0
  82. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/etc/systemd/system/var-lib-pixie-images.mount +0 -0
  83. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/etc/udev/rules.d/70-pixie-realtek-2g5-offloads.rules +0 -0
  84. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/usr/lib/systemd/system-generators/pixie-skip-usb-only-units-on-netboot +0 -0
  85. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/usr/local/sbin/pixie-boot-banner +0 -0
  86. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/usr/local/sbin/pixie-clock-from-http +0 -0
  87. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/usr/local/sbin/pixie-images-discover +0 -0
  88. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/usr/local/sbin/pixie-on-tty1 +0 -0
  89. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/usr/local/sbin/pixie-trace +0 -0
  90. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/includes.chroot/usr/local/sbin/pixie-usb-grow +0 -0
  91. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/package-lists/pixie-base.list.chroot +0 -0
  92. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/package-lists/pixie-flash.list.chroot +0 -0
  93. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/preferences/backports.pref.binary +0 -0
  94. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/pixie-media/live-build/config/preferences/backports.pref.chroot +0 -0
  95. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/__init__.py +0 -0
  96. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/_partition.py +0 -0
  97. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/_util.py +0 -0
  98. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/catalog/__init__.py +0 -0
  99. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/catalog/_fetcher.py +0 -0
  100. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/catalog/_routes.py +0 -0
  101. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/catalog/_schema.py +0 -0
  102. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/catalog/_store.py +0 -0
  103. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/catalog/catalog.toml +0 -0
  104. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/deploy/__init__.py +0 -0
  105. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/deploy/_main.py +0 -0
  106. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/deploy/_templates.py +0 -0
  107. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/disks.py +0 -0
  108. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/events/__init__.py +0 -0
  109. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/events/_log.py +0 -0
  110. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/events/_routes.py +0 -0
  111. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/exports/__init__.py +0 -0
  112. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/exports/_routes.py +0 -0
  113. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/exports/_store.py +0 -0
  114. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/exports/_supervisor.py +0 -0
  115. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/flash.py +0 -0
  116. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/images.py +0 -0
  117. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/machines/__init__.py +0 -0
  118. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/machines/_routes.py +0 -0
  119. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/machines/_store.py +0 -0
  120. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/oras.py +0 -0
  121. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/oras_pull.py +0 -0
  122. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/pivot/__init__.py +0 -0
  123. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/pivot/nbdboot +0 -0
  124. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/pxe/__init__.py +0 -0
  125. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/pxe/_renderer.py +0 -0
  126. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/pxe/_routes.py +0 -0
  127. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/tftp/__init__.py +0 -0
  128. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/tftp/_supervisor.py +0 -0
  129. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/tui/__init__.py +0 -0
  130. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/tui/_app.py +0 -0
  131. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/tui_catalog.py +0 -0
  132. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/__init__.py +0 -0
  133. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_auth.py +0 -0
  134. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_bind_preview.py +0 -0
  135. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_fsutil.py +0 -0
  136. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_images.py +0 -0
  137. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_inventory.py +0 -0
  138. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_overlay_bind.py +0 -0
  139. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_overlays.py +0 -0
  140. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_settings_store.py +0 -0
  141. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_static/.gitkeep +0 -0
  142. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_static/bootstrap-icons.min.css +0 -0
  143. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_static/bootstrap.min.css +0 -0
  144. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_static/fonts/bootstrap-icons.woff +0 -0
  145. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_static/fonts/bootstrap-icons.woff2 +0 -0
  146. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_static/htmx.min.js +0 -0
  147. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_static/pixie-favicon.png +0 -0
  148. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_static/sse.js +0 -0
  149. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_table_state.py +0 -0
  150. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/_partials/page_description.html +0 -0
  151. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/_partials/recent_events.html +0 -0
  152. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/_partials/table_helpers.html +0 -0
  153. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/catalog.html +0 -0
  154. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/catalog_detail.html +0 -0
  155. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/dashboard.html +0 -0
  156. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/events.html +0 -0
  157. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/image_detail.html +0 -0
  158. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/images.html +0 -0
  159. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/ipxe/bootstrap.j2 +0 -0
  160. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/ipxe/exit.j2 +0 -0
  161. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/ipxe/nbdboot.j2 +0 -0
  162. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/ipxe/unavailable.j2 +0 -0
  163. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/layout.html +0 -0
  164. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/login.html +0 -0
  165. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/machine_detail.html +0 -0
  166. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/machines.html +0 -0
  167. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/overlays.html +0 -0
  168. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/src/pixie/web/_templates/settings.html +0 -0
  169. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/__init__.py +0 -0
  170. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/conftest.py +0 -0
  171. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/integration/__init__.py +0 -0
  172. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/integration/conftest.py +0 -0
  173. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/integration/test_catalog_fetch.py +0 -0
  174. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/integration/test_deploy.py +0 -0
  175. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/integration/test_exports.py +0 -0
  176. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/integration/test_inventory.py +0 -0
  177. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/integration/test_pxe.py +0 -0
  178. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/integration/test_tftp.py +0 -0
  179. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_auth.py +0 -0
  180. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_catalog_api.py +0 -0
  181. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_catalog_seed.py +0 -0
  182. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_deploy_unit.py +0 -0
  183. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_event_kinds.py +0 -0
  184. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_events_unit.py +0 -0
  185. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_exports_unit.py +0 -0
  186. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_fetch_progress.py +0 -0
  187. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_healthz.py +0 -0
  188. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_images_ui.py +0 -0
  189. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_machines_unit.py +0 -0
  190. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_oras_pull.py +0 -0
  191. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_overlays_ui.py +0 -0
  192. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_partition_select.py +0 -0
  193. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_pivot.py +0 -0
  194. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_pxe_plan_json.py +0 -0
  195. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_schema.py +0 -0
  196. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_settings.py +0 -0
  197. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_ui_pages.py +0 -0
  198. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_web_bind_preview.py +0 -0
  199. {pixie_lab-0.4.3 → pixie_lab-0.4.4}/tests/test_web_inventory.py +0 -0
@@ -11,6 +11,17 @@ operator-facing summary.
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [0.4.4] - 2026-07-27
15
+
16
+ ### Added
17
+
18
+ **One-click live-env setup.** The Live env page now has a **Set up live
19
+ env** button that fetches the `pixie-live-env` image + its arch-headless
20
+ netboot bundle and selects the image in a single action, with a live
21
+ progress bar -- no more hopping to the Catalog tab, fetching two entries
22
+ by hand, and copying a `content_sha256` onto the Live env page. The
23
+ manual "select by content sha" form remains as an advanced override.
24
+
14
25
  ## [0.4.3] - 2026-07-26
15
26
 
16
27
  ### Removed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pixie-lab
3
- Version: 0.4.3
3
+ Version: 0.4.4
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
@@ -67,13 +67,18 @@ top nav has Machines, Catalog, Events, and Settings.
67
67
  2. Click Fetch on a row to download it. The status pill ticks
68
68
  through downloading -> decompressing -> unpacking with a
69
69
  `bytes / total` counter so you see progress live.
70
- 3. Power-cycle a target with pixie in its DHCP next-server chain.
70
+ 3. For the live-env boot modes (`pixie-inventory` / `pixie-tui` /
71
+ `pixie-flash-*`), Fetch the `pixie-live-env` image + its netboot
72
+ bundle, then set the image's `content_sha256` on the Live env page
73
+ (`/ui/live-env`) or via `PIXIE_LIVE_ENV_IMAGE_SHA`. Those modes
74
+ nbdboot that image; until it's selected they render `unavailable`.
75
+ 4. Power-cycle a target with pixie in its DHCP next-server chain.
71
76
  A first contact shows up on `/ui/machines` with the default
72
77
  `ipxe-exit` boot mode. Open the row to bind a mode + image.
73
- 4. `pixie-inventory` prompts the live env to POST an inventory
78
+ 5. `pixie-inventory` prompts the live env to POST an inventory
74
79
  blob; the target's disks + NICs + memory show up on the
75
80
  machine detail page.
76
- 5. Flash modes (`pixie-flash-once`, `pixie-flash-always`) require
81
+ 6. Flash modes (`pixie-flash-once`, `pixie-flash-always`) require
77
82
  a target disk serial that came in on the inventory. The
78
83
  binding form disables Save until that prerequisite is met.
79
84
 
@@ -85,9 +90,11 @@ event log, settings, NBD-export records, and persistent-overlay
85
90
  records. `blobs/<sha>/blob` holds fetched disk images.
86
91
  `artifacts/<sha>/{vmlinuz,initrd,manifest.json}` holds unpacked
87
92
  netboot bundles. `overlays/<mac>/<image_sha>/<profile>.qcow2` holds
88
- per-machine writable overlays for the `nbdboot` boot mode.
89
- `live-env/` holds the pixie live env kernel + initrd + squashfs the
90
- netboot-pc bake produced.
93
+ per-machine writable overlays for the `nbdboot` boot mode. The live env
94
+ (`pixie-inventory` / `pixie-tui` / `pixie-flash-*`) is the fetched
95
+ `pixie-live-env` disk image, selected by `PIXIE_LIVE_ENV_IMAGE_SHA` /
96
+ the Live env page and nbdbooted like any other image, so it lives in
97
+ `blobs/` + `artifacts/` too - there is no separate live-env directory.
91
98
 
92
99
  Both admin password and display timezone / strftime pattern have
93
100
  env-var overrides plus DB overrides via `/ui/settings`; env wins
@@ -39,13 +39,18 @@ top nav has Machines, Catalog, Events, and Settings.
39
39
  2. Click Fetch on a row to download it. The status pill ticks
40
40
  through downloading -> decompressing -> unpacking with a
41
41
  `bytes / total` counter so you see progress live.
42
- 3. Power-cycle a target with pixie in its DHCP next-server chain.
42
+ 3. For the live-env boot modes (`pixie-inventory` / `pixie-tui` /
43
+ `pixie-flash-*`), Fetch the `pixie-live-env` image + its netboot
44
+ bundle, then set the image's `content_sha256` on the Live env page
45
+ (`/ui/live-env`) or via `PIXIE_LIVE_ENV_IMAGE_SHA`. Those modes
46
+ nbdboot that image; until it's selected they render `unavailable`.
47
+ 4. Power-cycle a target with pixie in its DHCP next-server chain.
43
48
  A first contact shows up on `/ui/machines` with the default
44
49
  `ipxe-exit` boot mode. Open the row to bind a mode + image.
45
- 4. `pixie-inventory` prompts the live env to POST an inventory
50
+ 5. `pixie-inventory` prompts the live env to POST an inventory
46
51
  blob; the target's disks + NICs + memory show up on the
47
52
  machine detail page.
48
- 5. Flash modes (`pixie-flash-once`, `pixie-flash-always`) require
53
+ 6. Flash modes (`pixie-flash-once`, `pixie-flash-always`) require
49
54
  a target disk serial that came in on the inventory. The
50
55
  binding form disables Save until that prerequisite is met.
51
56
 
@@ -57,9 +62,11 @@ event log, settings, NBD-export records, and persistent-overlay
57
62
  records. `blobs/<sha>/blob` holds fetched disk images.
58
63
  `artifacts/<sha>/{vmlinuz,initrd,manifest.json}` holds unpacked
59
64
  netboot bundles. `overlays/<mac>/<image_sha>/<profile>.qcow2` holds
60
- per-machine writable overlays for the `nbdboot` boot mode.
61
- `live-env/` holds the pixie live env kernel + initrd + squashfs the
62
- netboot-pc bake produced.
65
+ per-machine writable overlays for the `nbdboot` boot mode. The live env
66
+ (`pixie-inventory` / `pixie-tui` / `pixie-flash-*`) is the fetched
67
+ `pixie-live-env` disk image, selected by `PIXIE_LIVE_ENV_IMAGE_SHA` /
68
+ the Live env page and nbdbooted like any other image, so it lives in
69
+ `blobs/` + `artifacts/` too - there is no separate live-env directory.
63
70
 
64
71
  Both admin password and display timezone / strftime pattern have
65
72
  env-var overrides plus DB overrides via `/ui/settings`; env wins
@@ -13,8 +13,7 @@ The recommended layout on the deploy host:
13
13
  compose.yml
14
14
  envvars
15
15
  envvars.example
16
- data/ <- persistent state (state.db, blobs, artifacts)
17
- live-env/ <- staged pixie live env (vmlinuz + initrd + squashfs)
16
+ data/ <- persistent state (state.db, blobs, artifacts, overlays)
18
17
  ```
19
18
 
20
19
  `compose.yml` is generated by `pixie-lab init` and shouldn't need
@@ -69,7 +68,7 @@ unattended). Flags choose how far the wipe goes:
69
68
 
70
69
  - `--data` - also delete `data/`: `state.db` (catalog, machines,
71
70
  events, exports, overlays, settings), every fetched blob and unpacked
72
- artifact, all overlay volumes, and the staged `live-env/`.
71
+ artifact, and all overlay volumes.
73
72
  `data/` is a bind mount (`./data:/var/lib/pixie`), not a named
74
73
  volume, so purge unlinks it directly - `podman compose down -v`
75
74
  alone would not touch it.
@@ -93,19 +92,31 @@ podman build -t pixie:local -f Containerfile .
93
92
  cd /opt/pixie && podman compose --env-file envvars up -d
94
93
  ```
95
94
 
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.
95
+ ### Select the live env
96
+
97
+ The `pixie-flash-*`, `pixie-inventory`, and `pixie-tui` boot modes boot
98
+ pixie's live env: the **`pixie-live-env`** disk image (the nosi
99
+ `arch-headless` base with the pixie CLI + `pixie-on-tty1` service
100
+ injected) booted over ephemeral nbdboot, exactly like the `nbdboot`
101
+ mode. Two UI steps set it up:
102
+
103
+ 1. On the **Catalog** page (`/ui/catalog`), Fetch the `pixie-live-env`
104
+ image and its `nosi arch-headless netboot bundle`. Both ship in the
105
+ bundled seed catalog (`PIXIE_SEED_CATALOG`, default on); if your
106
+ catalog is empty, import the release `catalog.toml` first. The image
107
+ is an `img.gz` release asset (its `src` is the latest pixie release's
108
+ `pixie-live-env-x86_64.img.gz`, ~900 MiB); the bundle carries the
109
+ matching kernel + initrd.
110
+ 2. On the **Live env** page (`/ui/live-env`), paste the fetched image's
111
+ `content_sha256` (shown on its catalog row, or in the release's
112
+ `pixie-live-env-x86_64.content-sha256` asset) into **Image content
113
+ sha** and Save. Equivalently, set `PIXIE_LIVE_ENV_IMAGE_SHA` in
114
+ `envvars`.
115
+
116
+ Until an image is selected **and** its bundle + blob are fetched, the
117
+ `pixie-*` boot modes render the readable `unavailable` plan rather than
118
+ booting nothing. For an air-gapped install, mirror the `img.gz` + the
119
+ oras bundle and point the two catalog entries' `src` at your mirror.
109
120
 
110
121
  ## Environment variables
111
122
 
@@ -144,20 +155,15 @@ behaviour. See [](boot-modes.md).
144
155
 
145
156
  **`PIXIE_DATA_DIR`** (default: `/var/lib/pixie`) - state root. Holds
146
157
  `state.db`, `blobs/` (fetched image bytes), `artifacts/` (extracted
147
- netboot bundles), `overlays/<alias>.qcow2`
158
+ netboot bundles), and `overlays/<alias>.qcow2`
148
159
  (globally-named single-writer overlay volumes for nbdboot; see
149
- [](boot-modes.md)),
150
- `live-env/` (staged pixie live env).
151
-
152
- **`PIXIE_LIVE_ENV_DIR`** (default: `$PIXIE_DATA_DIR/live-env`) - the
153
- `pixie-*` boot modes degrade to an unavailable plan when this dir is
154
- missing or incomplete.
155
-
156
- **`PIXIE_LIVE_ENV_SRC`** (default: the latest pixie GitHub release's
157
- `pixie-live-env-x86_64.tar.gz`) - the tarball the dashboard **Fetch
158
- live-env** action downloads and stages into `PIXIE_LIVE_ENV_DIR`.
159
- Accepts `https://` or `oras://`; it must unpack to `vmlinuz` + `initrd`
160
- + `live.squashfs`. Overridable live on the Live env page.
160
+ [](boot-modes.md)).
161
+
162
+ **`PIXIE_LIVE_ENV_IMAGE_SHA`** (default: unset) - the `content_sha256`
163
+ of the fetched `pixie-live-env` disk image the `pixie-inventory` /
164
+ `pixie-tui` / `pixie-flash-*` boot modes nbdboot. When unset, those
165
+ modes render the `unavailable` plan. Overridable live on the Live env
166
+ page (see [Select the live env](#select-the-live-env)).
161
167
 
162
168
  **`PIXIE_SEED_CATALOG`** (default: `1`) - seed a fresh (empty) catalog
163
169
  from the bundled curated catalog (the netboot-capable nosi subset) on
@@ -5,7 +5,7 @@ pixie's live env end-to-end, and the kernel cmdline tokens that
5
5
  unblock them. Set the tokens via the Settings page
6
6
  (`/ui/settings`, "Live-env" card, "Extra kernel cmdline") or via
7
7
  `PIXIE_LIVE_ENV_EXTRA_CMDLINE` in `envvars`. Either path is
8
- appended verbatim to the `pixie-live-env.j2` kernel line, after
8
+ appended verbatim to the live-env kernel line, after
9
9
  `pixie.mac=` + `bty.mac=` so last-token-wins on any conflict.
10
10
 
11
11
  The Settings page persists across restarts (state.db). The
@@ -21,14 +21,14 @@ Symptom pattern from the pixie access log:
21
21
 
22
22
  GET /pxe-bootstrap.ipxe 200
23
23
  GET /pxe/<mac> 200
24
- GET /boot/pixie-live-env/vmlinuz 200
25
- GET /boot/pixie-live-env/initrd 200
26
- # ...silence. No /boot/pixie-live-env/live.squashfs fetch.
24
+ GET /artifacts/<sha>/vmlinuz 200
25
+ GET /artifacts/<sha>/initrd 200
26
+ # ...silence. No NBD connect to the live-env export.
27
27
 
28
28
  iPXE handed the kernel + initrd off to Linux, then Linux couldn't
29
29
  bring up the boot NIC (driver -EIO, DMA fail, ROM-BAR conflict,
30
- etc). live-boot has no interface to run `fetch=` through and the
31
- target hangs silently before any userspace runs.
30
+ etc), so the initrd never connects the live-env image over NBD and
31
+ the target hangs silently before any userspace runs.
32
32
 
33
33
  Get to a serial console (BMC SoL, USB-serial adapter, or physical
34
34
  COM1). If the console shows the kernel initialising, then falling
@@ -67,7 +67,7 @@ workaround kicks in the kernel logs:
67
67
  igb 0000:06:00.0: Intel(R) Gigabit Ethernet Network Connection
68
68
  igb 0000:06:00.0 enp6s0: igb: enp6s0 NIC Link is Up 1000 Mbps Full Duplex
69
69
 
70
- ...and the live-boot initrd fetches the squashfs normally.
70
+ ...and the initrd connects the live-env image over NBD normally.
71
71
 
72
72
  ## Target firmware prerequisites (not cmdline)
73
73
 
@@ -0,0 +1,85 @@
1
+ # Quickstart
2
+
3
+ Bring pixie up, point DHCP at it, and boot a first target.
4
+
5
+ ## Bring pixie up
6
+
7
+ One command. It generates the config, starts the container, and waits
8
+ until pixie answers healthy:
9
+
10
+ ```
11
+ uv tool run pixie-lab deploy /opt/pixie --host-addr <LAN-IP>
12
+ ```
13
+
14
+ `uv tool run` fetches `pixie-lab` into a throwaway environment (nothing
15
+ to install or leave behind). `deploy` writes `compose.yml` + `envvars`
16
+ into `/opt/pixie`, brings the stack up under `network_mode: host` (so
17
+ TFTP + the NBD range + HTTP all reach the LAN), waits on `/healthz`, and
18
+ prints the admin password it generated. The only default you usually
19
+ set is `--host-addr` (otherwise auto-detected); override the rest with
20
+ `--admin-password` / `--image` as needed.
21
+
22
+ Host prerequisite: podman + a compose provider. Then log in at
23
+ `http://<LAN-IP>:8080/`.
24
+
25
+ > Prefer to review the generated files first? `uv tool run pixie-lab
26
+ > init /opt/pixie` writes the same `compose.yml` + `envvars` without
27
+ > starting anything; edit `envvars` (`PIXIE_HOST_ADDR` +
28
+ > `PIXIE_ADMIN_PASSWORD`), then `cd /opt/pixie && podman compose
29
+ > --env-file envvars up -d`.
30
+
31
+ ## Usage
32
+
33
+ pixie is up; the rest is day-to-day operation. Point DHCP at it once,
34
+ then drive everything from the web UI at `http://<LAN-IP>:8080/`.
35
+
36
+ ### Point DHCP at pixie
37
+
38
+ Set your DHCP server to chain PXE targets through pixie's TFTP and
39
+ iPXE bootstrap. See [](deployment.md#dhcp-handoff) for BIOS + UEFI
40
+ dnsmasq recipes.
41
+
42
+ ### Add a catalog entry
43
+
44
+ Open `http://<PIXIE_HOST_ADDR>:8080/ui/catalog` in a browser, log in
45
+ with your admin password, and add a catalog entry with a source URL.
46
+ Hit Fetch. Pixie pulls the bytes to disk (and for `img.gz` / `img.zst`
47
+ inputs, decompresses on the way in). The row flips to `fetched` when
48
+ the pipeline lands.
49
+
50
+ ### Select the live env
51
+
52
+ The `pixie-inventory`, `pixie-tui`, and `pixie-flash-*` boot modes boot
53
+ the `pixie-live-env` disk image (the operator TUI + CLI baked in) over
54
+ nbdboot. On `/ui/catalog`, Fetch the **`pixie-live-env`** image and its
55
+ **`nosi arch-headless netboot bundle`** (both ship in the seed catalog).
56
+ Then open the **Live env** page (`/ui/live-env`) and set **Image content
57
+ sha** to the fetched image's `content_sha256` (shown on its catalog
58
+ row), or set `PIXIE_LIVE_ENV_IMAGE_SHA` in `envvars`. Until an image is
59
+ selected, those boot modes render an `unavailable` plan. See
60
+ [](deployment.md#select-the-live-env) for detail and the air-gapped
61
+ path.
62
+
63
+ ### Bind a machine
64
+
65
+ Once a target has PXEd at least once, it appears on `/ui/machines`.
66
+ Click its MAC to open the machine detail page. Pick a boot mode from
67
+ the card grid, pick an image, and Save. On the target's next PXE,
68
+ pixie serves the plan you bound.
69
+
70
+ See [](boot-modes.md) for what each mode does and how bindings pin a
71
+ machine to an image and, for `nbdboot`, an overlay volume.
72
+
73
+ ## Tear it down
74
+
75
+ One command, the inverse of deploy:
76
+
77
+ ```
78
+ uv tool run pixie-lab purge /opt/pixie --all --yes
79
+ ```
80
+
81
+ `--all` removes the container, its image, and `data/`. Drop `--all` to
82
+ stop + remove the container only, or pick with `--data` / `--images`.
83
+ Without `--yes` it prints the plan and asks first -- the `--data` /
84
+ `--all` deletions are irreversible, and even a plain stop drops every
85
+ live NBD export (any target booted `nbdboot` off pixie loses its root).
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pixie-lab"
3
- version = "0.4.3"
3
+ version = "0.4.4"
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"
@@ -196,7 +196,14 @@ EVENTS_CLEARED = "events.cleared"
196
196
  right after the wipe so the freshly-empty log still records who reset
197
197
  it and when; carries the deleted-row count in ``details``."""
198
198
 
199
- # ---------- live-env fetch ------------------------------------------
199
+ # ---------- live env ------------------------------------------------
200
+
201
+ LIVE_ENV_IMAGE_SELECTED = "live_env.image.selected"
202
+ """The one-click "Set up live env" action fetched the pixie-live-env
203
+ image + its bundle and selected the image (set ``live_env.image_sha``).
204
+ Carries the selected ``image_sha`` in ``details``."""
205
+
206
+
200
207
  # The canonical closed set. Every kind above is registered here; the
201
208
  # ``EventsLog.emit`` call rejects anything not in this frozenset.
202
209
  KNOWN_EVENT_KINDS: frozenset[str] = frozenset(
@@ -230,6 +237,7 @@ KNOWN_EVENT_KINDS: frozenset[str] = frozenset(
230
237
  AUTH_LOGIN_SUCCEEDED,
231
238
  AUTH_LOGIN_FAILED,
232
239
  EVENTS_CLEARED,
240
+ LIVE_ENV_IMAGE_SELECTED,
233
241
  }
234
242
  )
235
243
 
@@ -0,0 +1,197 @@
1
+ {% extends "layout.html" %}
2
+ {% from "_partials/page_description.html" import page_description %}
3
+ {% block title %}Live env - pixie{% endblock %}
4
+
5
+ {% block subnav %}
6
+ <nav class="navbar subnav-strip" aria-label="Section sub-navigation">
7
+ <div class="container">
8
+ <span class="subnav-jumps d-flex align-items-center flex-wrap">
9
+ <a href="#setup">Setup</a>
10
+ <a href="#advanced">Advanced</a>
11
+ <a href="#options">Options</a>
12
+ </span>
13
+ </div>
14
+ </nav>
15
+ {% endblock %}
16
+
17
+ {% block content %}
18
+ {% set ss = live_env_setup_state or {} %}
19
+ {{ page_description('boombox', 'The pixie live env that the pixie-inventory / pixie-tui / pixie-flash-once / pixie-flash-always boot modes boot into: a disk image (the pixie-live-env catalog entry) booted over ephemeral nbdboot. Click Set up live env to fetch it and select it in one step; until then those boot modes render an "unavailable" plan.') }}
20
+
21
+ {% if flash_error %}
22
+ <div class="alert alert-danger py-2">{{ flash_error }}</div>
23
+ {% endif %}
24
+
25
+ {# ---- One-click setup -------------------------------------------- #}
26
+ <div class="card shadow-sm mb-4" id="setup">
27
+ <div class="card-header bg-light d-flex align-items-center gap-2">
28
+ <h2 class="h5 mb-0"><i class="bi bi-boombox me-2"></i>Live env</h2>
29
+ {% if live_env_ready %}
30
+ <span class="badge text-bg-success ms-auto"><i class="bi bi-check-circle me-1"></i>ready</span>
31
+ {% elif ss.state == 'running' %}
32
+ <span class="badge text-bg-info ms-auto"><span class="spinner-border spinner-border-sm me-1" role="status"></span>setting up</span>
33
+ {% else %}
34
+ <span class="badge text-bg-warning ms-auto"><i class="bi bi-exclamation-triangle me-1"></i>not set up</span>
35
+ {% endif %}
36
+ </div>
37
+ <div class="card-body">
38
+ {% if live_env_ready %}
39
+ <p class="small mb-3">
40
+ Image <code>{{ live_env_image_sha.effective[:12] }}</code> is fetched and
41
+ selected; the <code>pixie-inventory</code> / <code>pixie-tui</code> /
42
+ <code>pixie-flash-*</code> modes nbdboot it. Nothing else to do.
43
+ </p>
44
+ {% else %}
45
+ <p class="small mb-3">
46
+ One click fetches the <code>pixie-live-env</code> image (~900&nbsp;MiB) +
47
+ its arch-headless netboot bundle from the catalog, then selects the image.
48
+ No catalog hopping or sha copying. It runs on the server; you can leave
49
+ this page. Re-running when everything is already fetched just re-selects.
50
+ </p>
51
+ {% endif %}
52
+
53
+ {# Progress (polled live while a setup runs). #}
54
+ <div id="setup-progress" class="{% if ss.state != 'running' %}d-none{% endif %} mb-3">
55
+ <div class="d-flex align-items-center gap-2 small mb-1">
56
+ <span class="spinner-border spinner-border-sm" role="status"></span>
57
+ <span id="setup-step">Fetching {{ ss.step or 'live env' }}{% if ss.phase %} ({{ ss.phase }}){% endif %}...</span>
58
+ </div>
59
+ <div class="progress" role="progressbar" style="height: 1.1rem;">
60
+ <div id="setup-bar" class="progress-bar progress-bar-striped progress-bar-animated"
61
+ style="width: {% if ss.total_bytes %}{{ (100 * ss.bytes_downloaded / ss.total_bytes) | round(0, 'floor') }}{% else %}100{% endif %}%"></div>
62
+ </div>
63
+ </div>
64
+ <div id="setup-error" class="alert alert-danger py-2 small {% if ss.state != 'error' %}d-none{% endif %}">
65
+ <i class="bi bi-exclamation-triangle me-1"></i><span id="setup-error-msg">{{ ss.error }}</span>
66
+ </div>
67
+
68
+ <form method="post" action="/ui/live-env/setup" class="m-0">
69
+ <button type="submit" class="btn {% if live_env_ready %}btn-outline-secondary{% else %}btn-primary{% endif %}"
70
+ id="setup-btn" {% if ss.state == 'running' %}disabled{% endif %}>
71
+ {% if ss.state == 'running' %}
72
+ <span class="spinner-border spinner-border-sm me-1" role="status"></span>Setting up...
73
+ {% else %}
74
+ <i class="bi bi-boombox me-1"></i>{% if live_env_ready %}Re-run setup{% else %}Set up live env{% endif %}
75
+ {% endif %}
76
+ </button>
77
+ <span class="text-muted small ms-2">Fetch + select in one step.</span>
78
+ </form>
79
+ </div>
80
+ </div>
81
+
82
+ {# ---- Advanced: select by content sha ---------------------------- #}
83
+ <div class="card shadow-sm mb-4" id="advanced">
84
+ <div class="card-header bg-light fw-semibold">
85
+ <i class="bi bi-sliders me-1"></i>Advanced: select by content sha
86
+ </div>
87
+ <div class="card-body">
88
+ <p class="small text-muted mb-3">
89
+ Manual override of what Set up above does automatically: point the live env
90
+ at a specific fetched image by its <code>content_sha256</code> (from its
91
+ <a href="/ui/catalog">Catalog</a> row). The image plus its netboot bundle
92
+ (via the entry's <code>netboot_src</code>) must both be fetched.
93
+ </p>
94
+ <form method="post" action="/ui/live-env/image/edit" class="row g-3">
95
+ <div class="col-12">
96
+ <label for="live_env_image_sha" class="form-label">
97
+ Image content sha
98
+ <span class="badge text-bg-{% if live_env_image_sha.override %}primary{% else %}secondary{% endif %} ms-1">
99
+ {% if live_env_image_sha.override %}override{% elif live_env_image_sha.effective %}env{% else %}unset{% endif %}
100
+ </span>
101
+ </label>
102
+ <input type="text" id="live_env_image_sha" name="live_env_image_sha"
103
+ class="form-control font-monospace"
104
+ value="{{ live_env_image_sha.override }}"
105
+ placeholder="(unset - live-env modes render the unavailable plan)"
106
+ pattern="[0-9a-fA-F]{64}">
107
+ <div class="form-text">
108
+ Blank falls back to <code>{{ live_env_image_sha.env }}</code> then unset.
109
+ Effective:
110
+ {% if live_env_image_sha.effective %}<code>{{ live_env_image_sha.effective }}</code>{% else %}<em class="text-muted">(none)</em>{% endif %}.
111
+ {% if live_env_image_sha.updated_at %}<br>Last updated: <code>{{ live_env_image_sha.updated_at | fmt_ts }}</code>.{% endif %}
112
+ </div>
113
+ </div>
114
+ <div class="col-12">
115
+ <button type="submit" class="btn btn-outline-secondary"><i class="bi bi-check2 me-1"></i>Save</button>
116
+ <span class="text-muted small ms-2">
117
+ Takes effect on the NEXT <code>GET /pxe/&lt;mac&gt;</code>; a target already mid-boot must be power-cycled.
118
+ </span>
119
+ </div>
120
+ </form>
121
+ </div>
122
+ </div>
123
+
124
+ {# ---- Options (config) ------------------------------------------- #}
125
+ <div class="card shadow-sm mb-4" id="options">
126
+ <div class="card-header bg-light fw-semibold">
127
+ <i class="bi bi-gear me-1"></i>Options
128
+ </div>
129
+ <div class="card-body">
130
+ <form method="post" action="/ui/live-env/cmdline/edit" class="row g-3">
131
+ <div class="col-12">
132
+ <label for="extra_cmdline" class="form-label">
133
+ Extra kernel cmdline
134
+ <span class="badge text-bg-{% if live_env_extra_cmdline.override %}primary{% else %}secondary{% endif %} ms-1">
135
+ {% if live_env_extra_cmdline.override %}override{% elif live_env_extra_cmdline.effective %}env{% else %}default{% endif %}
136
+ </span>
137
+ </label>
138
+ <input type="text" id="extra_cmdline" name="extra_cmdline"
139
+ class="form-control font-monospace"
140
+ value="{{ live_env_extra_cmdline.override }}"
141
+ placeholder="e.g. pci=realloc=on,nocrs"
142
+ list="live-env-cmdline-suggestions">
143
+ <datalist id="live-env-cmdline-suggestions">
144
+ <option value="pci=realloc=on,nocrs">
145
+ </datalist>
146
+ <div class="form-text">
147
+ Tokens appended verbatim to the live-env kernel cmdline
148
+ (after <code>pixie.mac=</code> / <code>bty.mac=</code>, so last-token-wins on any
149
+ conflict). Whitespace-separated; single line. Blank falls back to
150
+ <code>{{ live_env_extra_cmdline.env }}</code> then no append. A machine with its own
151
+ <code>extra_cmdline</code> binding overrides this global. Effective:
152
+ {% if live_env_extra_cmdline.effective %}<code>{{ live_env_extra_cmdline.effective }}</code>{% else %}<em class="text-muted">(none)</em>{% endif %}.
153
+ Known-good values per hardware in
154
+ <a href="https://github.com/safl/pixie/blob/main/docs/src/hardware-quirks.md" target="_blank" rel="noreferrer">docs/hardware-quirks.md</a>.
155
+ {% if live_env_extra_cmdline.updated_at %}<br>Last updated: <code>{{ live_env_extra_cmdline.updated_at | fmt_ts }}</code>.{% endif %}
156
+ </div>
157
+ </div>
158
+ <div class="col-12">
159
+ <button type="submit" class="btn btn-primary"><i class="bi bi-check2 me-1"></i>Save</button>
160
+ <span class="text-muted small ms-2">
161
+ Takes effect on the NEXT <code>GET /pxe/&lt;mac&gt;</code>; a target already mid-boot must be power-cycled.
162
+ </span>
163
+ </div>
164
+ </form>
165
+ </div>
166
+ </div>
167
+
168
+ {# Poll setup progress while a run is in flight; reload when it lands
169
+ so the ready badge + selected sha update. #}
170
+ <script>
171
+ (function () {
172
+ if ("{{ ss.state }}" !== "running") return;
173
+ var box = document.getElementById("setup-progress");
174
+ var step = document.getElementById("setup-step");
175
+ var bar = document.getElementById("setup-bar");
176
+ function poll() {
177
+ fetch("/ui/live-env/setup-state.json", { headers: { "Accept": "application/json" } })
178
+ .then(function (r) { return r.json(); })
179
+ .then(function (s) {
180
+ if (!s || s.state === "running") {
181
+ if (step) step.textContent = "Fetching " + (s.step || "live env") +
182
+ (s.phase ? " (" + s.phase + ")" : "") + "...";
183
+ if (bar && s.total_bytes) {
184
+ bar.style.width = Math.floor(100 * s.bytes_downloaded / s.total_bytes) + "%";
185
+ }
186
+ setTimeout(poll, 1500);
187
+ } else {
188
+ // done or error -> reload to render the final state.
189
+ location.reload();
190
+ }
191
+ })
192
+ .catch(function () { setTimeout(poll, 3000); });
193
+ }
194
+ setTimeout(poll, 1500);
195
+ })();
196
+ </script>
197
+ {% endblock %}