Compare commits

..

53 Commits

Author SHA1 Message Date
Anton Livaja b3af1c89b8
Merge remote-tracking branch 'origin/ryansquared/add-tmux' 2025-06-30 12:50:11 -07:00
Ryan Heywood fc2dc900cc
Makefile: add system-vm target and GUI=true option 2025-06-25 17:21:46 -04:00
Ryan Heywood a372b606d0
host/etc/profile: specify TERM=linux-16color when TERM like linux 2025-06-25 03:02:02 -04:00
Ryan Heywood d31c5f60ad
host: add tmux, drop into tmux by default on console 2025-06-24 23:27:46 -04:00
Ryan Heywood 75acac32a9
Release 2025.05.0 2025-05-15 00:33:15 -04:00
Anton Livaja bdc971a931
Merge remote-tracking branch 'origin/ryansquared/add-guestctl' 2025-05-14 19:12:21 -07:00
Anton Livaja da8e9b915b
Merge remote-tracking branch 'origin/ryansquared/update-hashes' 2025-05-14 19:11:53 -07:00
Ryan Heywood d7a0b6c5e5
Containerfile: add guestctl to host 2025-05-12 17:09:13 -04:00
Ryan Heywood 30fa06a5fb
update hashes, fix hash updater 2025-05-07 22:58:07 -04:00
Ryan Heywood 82c0d8e55a
Merge remote-tracking branch 'origin/iommu-net' 2025-05-01 17:33:19 -04:00
Anton Livaja 890e715e86
fix: remove unnecessary echo 2025-05-01 14:17:33 -07:00
Ryan Heywood 133a7c9b5b
Merge remote-tracking branch 'origin/iommu-net' 2025-05-01 16:45:27 -04:00
Anton Livaja 8722409004
fix: remove git hooks 2025-05-01 13:41:25 -07:00
Lance Vick 73ab8eae21
Merge branch 'main' into iommu-net 2025-05-01 13:21:18 -07:00
Anton Livaja 72efb86b6f
fix: rename from repros to airgap-guest 2025-05-01 10:51:19 -07:00
Anton Livaja 723ba49cd3
fix: add missint cmd 2025-05-01 09:16:11 -07:00
Anton Livaja c608ad5ccd
feat: add hot plugging for usb devices 2025-04-30 18:48:15 -07:00
Lance Vick 06010bea59
fix: add shell command to supported command list 2025-04-30 18:00:40 -07:00
Lance Vick d1229c0f45
feat: add netvm shell for raw shel access 2025-04-30 17:56:00 -07:00
Lance Vick 24a254a914
fix: overhaul socket buffer handling for far higher stability and blocking boot 2025-04-30 17:30:18 -07:00
Lance Vick bb2f87d471
fix: netvm start edge case handling 2025-04-30 00:24:52 -07:00
Lance Vick b980eb3a97
feat: add dhcpcd to netvm 2025-04-29 19:37:15 -07:00
Lance Vick 22469ca0b9
feat: block netvm start until qemu responds to pings 2025-04-29 19:36:58 -07:00
Lance Vick 3985d8ac19
feat: netvm start now auto-attaches network pci devices 2025-04-28 17:30:42 -07:00
Lance Vick ea07569187
feat: netvm push/pull support, fixed run, and lots of cleanup 2025-04-27 17:45:25 -07:00
Lance Vick 18fa25b87e
feat: initial qemu-ga based netvm command to control guest 2025-04-24 23:10:49 -07:00
Lance Vick b64d76b60d
wip 2025-04-15 13:07:41 -07:00
Ryan Heywood f967c2db49
Merge remote-tracking branch 'origin/pull/43/head' 2025-03-27 14:43:35 -04:00
Anton Livaja a11d544723
Merge branch 'release/2025.02.0' 2025-02-28 17:22:00 -05:00
Anton Livaja 03621ded78
release: add signature 2025-02-28 17:21:17 -05:00
Lance Vick e66f69ac46
release: 2025.02.0 2025-02-28 04:46:23 -08:00
Lance Vick dca180550e
maint: update to latest stagex 2025-02-28 04:26:59 -08:00
Anton Livaja a5b695c2af
remove whitespace 2025-02-17 04:29:17 -05:00
Anton Livaja c350dec98f
fix logging by adding /var/log 2025-02-17 04:27:45 -05:00
Anton Livaja acc7d0c416
fix syslogd 2025-02-17 03:41:47 -05:00
Anton Livaja bd15a10d23
change kernel log level to 7 2025-02-17 03:41:36 -05:00
Ryan Heywood 9f93bebd6a
Merge branch 'anton/fix-containerfile' 2025-02-17 02:59:37 -05:00
Anton Livaja 7f5d3a6275
remove duplicate import and fix as casing 2025-02-17 02:54:38 -05:00
Ryan Heywood 89ada7e795
Merge branch 'anton/set-kernel-log-level' 2025-02-17 02:19:11 -05:00
Anton Livaja 4fa6761729
set kernel log level to 3 2025-02-17 00:36:38 -05:00
Anton Livaja a224d4114e
Merge branch 'lance/set-xdg-runtime' 2025-02-11 02:14:33 -05:00
Lance Vick 5897a2fa5d
fix: set xdg_runtime_dir required by keyfork 2025-02-10 23:01:02 -08:00
Anton Livaja 06de2117dc
Merge branch 'lance/sqlite3' 2025-02-11 01:27:34 -05:00
Lance Vick 15926d8ec3
fix: add sqlite3 to fix sq 2025-02-10 22:11:29 -08:00
Anton Livaja f23195d573
Merge branch 'lance/efi-kvm-boot' 2025-02-10 23:45:31 -05:00
Anton Livaja 08f367edc6
Merge branch 'lance/add-sdtool' 2025-02-10 23:42:33 -05:00
Lance Vick 110f64cf54
feat: optional boot with kvm or efi 2025-02-10 16:31:14 -08:00
Lance Vick ba16f1ea50
feat: add sdtool to image 2025-02-10 16:29:32 -08:00
Lance Vick aa5b04e8a0
Merge remote-tracking branch 'origin/anton/fix-gpg-key-id' 2025-02-09 22:28:51 -08:00
Anton Livaja 238ca2ce41
fix readme with make reproduce command 2025-02-10 00:37:48 -05:00
Anton Livaja dad6fe859b
fix pgp key fetching and indentation 2025-02-10 00:37:23 -05:00
Anton Livaja 5612c59b9a
Merge branch 'lance/stagex-updates' 2025-02-10 00:27:34 -05:00
Lance Vick e2a8d2b8cb
feat: stagex updates w/ canokey smartcard emulation 2025-02-09 20:17:44 -08:00
51 changed files with 1269 additions and 214 deletions

View File

@ -1,56 +1,79 @@
FROM stagex/alsa-lib:sx2024.09.0@sha256:a41b481187f76c1e9ed4e237977f4892c1507a3b8f8f6736ff3fdd5144bd2afb AS alsa-lib FROM stagex/user-alsa-lib@sha256:eeaee84f8012865bb33d68287bccfddc6fd04e9082687b8c31008dd07b8e07b8 AS user-alsa-lib
FROM stagex/bash:sx2024.09.0@sha256:cb58f55d268fbe7ef629cda86e3a8af893066e4af7f26ef54748b6ad47bdaa66 AS bash FROM stagex/core-bash@sha256:ae47fcd4247bef0ca4af762a76cb8871a5c868472cab67eed829a55364a8f1fa AS core-bash
FROM stagex/bc:sx2024.09.0@sha256:039cc5ac357a17d6374445fe4eed1dac15cc72f615bd9657c17e2c3904d42b62 AS bc FROM stagex/core-bc@sha256:03e1c729223e9d45f087660f65034b4f6fac91aefb94fb7ccbc85d1ab7e88c1d AS core-bc
FROM stagex/busybox:sx2024.09.0@sha256:d34bfa56566aa72d605d6cbdc154de8330cf426cfea1bc4ba8013abcac594395 AS busybox FROM stagex/core-busybox@sha256:cac5d773db1c69b832d022c469ccf5f52daf223b91166e6866d42d6983a3b374 AS core-busybox
FROM stagex/ccid:sx2024.09.0@sha256:3225dc4a6a1af5f828854157a6b16eb09a0b0f7ebe9d9ee34030afe3966afad1 AS ccid FROM stagex/user-ccid@sha256:313259fb6b059179ff69f4189c57d98b8d468ebf17f14c6f431d7001c8801e1c AS user-ccid
FROM stagex/cpio:sx2024.09.0@sha256:abccb58edb5f1f31b3b9c8b61cffa10cd56de3307e337335927b8df4d9112d24 AS cpio FROM stagex/user-cpio@sha256:2695e1b42f93ec3ea0545e270f0fda4adca3cb48d0526da01954efae1bce95c4 AS user-cpio
FROM stagex/curl:sx2024.09.0@sha256:8e5705a77a76c92d058e016184dabd0c4fa2f6117021cc5ff55df35f654cb158 AS curl FROM stagex/core-curl@sha256:63a5963a4e7852b5482824953d18ea73c7d192fed654eb1236f8b97a6f67cbcc AS core-curl
FROM stagex/dtc:sx2024.09.0@sha256:57f8aaa94059c43081b32fccb473ebd2c0cf16878dcf0e24e0e56c910467e93a AS dtc FROM stagex/user-dtc@sha256:3877063ca1068d48e0b92fcdf5083b707e009e96a6db4bd3536924c9f440cb08 AS user-dtc
FROM stagex/eudev:sx2024.09.0@sha256:7da7aed7ea7eb73bda86e206e765bdc8e6367c2c2ae535ccd68c7c1b0a936611 AS eudev FROM stagex/user-eudev@sha256:709f6f949e93a3a91770b7323fd87eec52714677e4bed88954cadd60506cbce3 AS user-eudev
FROM stagex/flashtools:sx2024.09.0@sha256:4e61cc6f0af9aa6116bb93f048c20d00026d75c27dc52b7e8604f0e340c55b80 AS flashtools FROM stagex/user-flashtools@sha256:f3524d889e9476acbe268b289a3e43f5766da9d3d999009b0bb8e6bddcd9dc5c AS user-flashtools
FROM stagex/gcc:sx2024.09.0@sha256:439bf36289ef036a934129d69dd6b4c196427e4f8e28bc1a3de5b9aab6e062f0 AS gcc FROM stagex/core-gcc@sha256:125bd6306e7f37e57d377d5a189c0e499388aff42b22cc79acee6097357c617f AS core-gcc
FROM stagex/glib:sx2024.09.0@sha256:d280c18f8b52ce21a26924b0cb1bfb69ea6508b57db73efe22401572e71dbe84 AS glib FROM stagex/user-glib@sha256:41fb9409b0bea2421feaee788c88efcf2778f2008634dde00b50f2b6afd2ed11 AS user-glib
FROM stagex/gpg:sx2024.09.0@sha256:f63555b39740db63b34c06894a4a9d5e125d04f5d51e799909d06c490e8ecd42 AS gpg FROM stagex/core-gmp@sha256:4387f9389ef656ef2305719ac1dbcc3d92631deb816da4c7101c0bdc75e57564 AS core-gmp
FROM stagex/grub:sx2024.09.0@sha256:a14c60f152c759185e5702e910053cb5c0d9eee11f43d8d5d40a84123aece9fd AS grub FROM stagex/user-gpg@sha256:92946bb4143ecbd53999cd520fbcb958aecacbac7a85bd58a758be1b57086a9c AS user-gpg
FROM stagex/ipxe:sx2024.09.0@sha256:5791d9b42c7e9099a0180c4fe6cc4b8e9afc9e6b9ec392099c65c53b71db7908 AS ipxe FROM stagex/user-grub@sha256:f3c9ff298c02ee3349496c3b5520079bbd115af0a347525410ba6a34170d4b4c AS user-grub
FROM stagex/jq:sx2024.09.0@sha256:3e8b44aa54481bdd46406e9d3a63862f4216f81530a1898b3c144e1c38847a82 AS jq FROM stagex/user-icepick@sha256:9d2e986a081fa7724dca2397dcd9b17fd2f6221d9c06d44f574625cb36038634 AS user-icepick
FROM stagex/jq:sx2024.09.0@sha256:3e8b44aa54481bdd46406e9d3a63862f4216f81530a1898b3c144e1c38847a82 AS jq FROM stagex/user-ipxe@sha256:b98dea039f0a14a614f035d848d9cfa8b9ad472e6dc24b2e3099f2f8ae209abe AS user-ipxe
FROM stagex/keyfork:sx2024.09.0@sha256:2288c1d769a0c3c535835019ad4919cc45b094492b5aa959a0eaf1e883a96214 AS keyfork FROM stagex/user-jq@sha256:ced6213c21b570dde1077ef49966b64cbf83890859eff83f33c82620520b563e AS user-jq
FROM stagex/libaio:sx2024.09.0@sha256:c8d6dd6f3e6fbda73ac0620b2bc4b4cfe6fa504bf7a17eee3bb56e286c394b8b AS libaio FROM stagex/user-keyfork@sha256:2075687c9a060f5eee89b6a4b5eecec6727afe3d241648b42be225170df0f8e0 AS user-keyfork
FROM stagex/libassuan:sx2024.09.0@sha256:1f31e888ab3f02634009d1a38acca9f25deb827432eb91392e21fd75128a44aa AS libassuan FROM stagex/user-libaio@sha256:3e21cfd5dc07a7300546e4896a81628741c23c4728a68d36e0bb3d8a096f7742 AS user-libaio
FROM stagex/libffi:sx2024.09.0@sha256:ab647ebf8464e00cde623f86f716e7f50ce82c30eafde813b7977d917ff7143a AS libffi FROM stagex/user-libassuan@sha256:dea35799659be7b85e523312c55621007b1918ff3590631155ecf2c699ca470f AS user-libassuan
FROM stagex/libgcrypt:sx2024.09.0@sha256:49c84a586969ff625b3304dcf8905a98db0da36fb8704e3d7a0771d271509b68 AS libgcrypt FROM stagex/core-libffi@sha256:9acd18e59ca11fa727670725e69a976d96f85a00704dea6ad07870bff2bd4e8b AS core-libffi
FROM stagex/libgpg-error:sx2024.09.0@sha256:11c17c1ac41f36c85e538bd34a0095a9f17e116f61c38d560350c02a6929e55a AS libgpg-error FROM stagex/user-libgcrypt@sha256:384f0e703afad6f8885ec77fb814ef182a08600a2032183d231fee5c048a7d2d AS user-libgcrypt
FROM stagex/libksba:sx2024.09.0@sha256:2913b382fdb76f02f9d78ee162066e04953ba782b8f722145111617a842f40a3 AS libksba FROM stagex/user-libgpg-error@sha256:6d7c09e3a7d055a6722910439c533f2babc8eda24b636bf4dfb2b29a3ed6327a AS user-libgpg-error
FROM stagex/libqrencode:sx2024.09.0@sha256:8c0f523bdf8d315e7b67cadd584e23d22a316dd1973232d49603e127717e4d1a AS libqrencode FROM stagex/user-libksba@sha256:c165fb5b7949473cb00b0fe59add90663346b33c6c682309ca0fcccdcf78d569 AS user-libksba
FROM stagex/libseccomp:sx2024.09.0@sha256:f48d783989da9d509cc6b4c12ec34e14074ffc1ab7a4f2d1e322c417d967e12f AS libseccomp FROM stagex/user-libqrencode@sha256:e99d9a71dffb399dbe3af8c16c473f10368c3fb787d72623bdc42c7fa770a33a AS user-libqrencode
FROM stagex/libslirp:sx2024.09.0@sha256:9dfb87e4a0adba80b862ce6b96112d96f509ffbca25bb71c60ba5bb5693b481d AS libslirp FROM stagex/user-libseccomp@sha256:7a397b5261c24aa745fe9158499e0db1ba21df415354bbbe77c90a6a3fd4c517 AS user-libseccomp
FROM stagex/libtpms:sx2024.09.0@sha256:d909a55137d0bf4a76331c2bf0358ee192d6c93ad77a5099af09ce1bcca2a6cd AS libtpms FROM stagex/user-libslirp@sha256:e72ebf587c366e1d0a9a42c74216dd2b9f560d52df3eb8148a2e31821415b082 AS user-libslirp
FROM stagex/libusb:sx2024.09.0@sha256:6c0dcf2b9519b1a41066ad71d3b597e9dae84fb73e5d031a3bdd2eb40f78ef94 AS libusb FROM stagex/user-libtpms@sha256:3fde6f85f3ce637b3d7b98e4fc74c2c57d31adf9c9ca068b3826eb7ebf16f5ba AS user-libtpms
FROM stagex/libzstd:sx2024.09.0@sha256:a055f8cd6e11b0b8836b2e5e1d755f672edbd344a4f4b5aba94919a6511be4c3 AS libzstd FROM stagex/core-libunwind@sha256:4f3ead61255c1e58e7dc43a33043f297f8730ec88e068a4460e5fff09e503781 AS core-libunwind
FROM stagex/linux-airgap:sx2024.09.0@sha256:efb98b59ab37a7e33db423eda7a49bb7273b087838fda8098ce6736a0860fc73 AS linux-airgap FROM stagex/user-libusb@sha256:53d499555164f12d9e87118a6d44e1d07f0b1cc9081a29eb66975662be818a00 AS user-libusb
FROM stagex/lzo:sx2024.09.0@sha256:09c60840e3e3e5835ec027c21283febc9f8cf53ab887576fbe9c38dbdbdfd571 AS lzo FROM stagex/user-libzbar@sha256:8b4ec291f772a10f372c538180f889a46837f2dd97756d1949c5c86111241fa9 AS user-libzbar
FROM stagex/mtools:sx2024.09.0@sha256:c83f7aebce9076903dbf1082aac981d3c0950d9e8952a900e5e072e2a811cda7 AS mtools FROM stagex/core-libzstd@sha256:35ae8f0433cf1472f8fb25e74dc631723e9f458ca3e9544976beb724690adea8 AS core-libzstd
FROM stagex/musl:sx2024.09.0@sha256:ad351b875f26294562d21740a3ee51c23609f15e6f9f0310e0994179c4231e1d AS musl FROM stagex/user-lzo@sha256:9d141a7686fbb027366df80d4f254fb13f4c4524ba4d5cff6ea176b0b4c36cd5 AS user-lzo
FROM stagex/npth:sx2024.09.0@sha256:21d50ec1421fe75af4bea240d76022ddb8c114fd2805bfeb06fb938e5a58fc0d AS npth FROM stagex/user-mtools@sha256:023169be123693e326d2fd97739fe0efa19638ce616cbcc52476e6f14f0a83cc AS user-mtools
FROM stagex/numactl:sx2024.09.0@sha256:39e667b966a443f42e1c7a8c944203945bd1808ce759df1706bb3b93b0b674c2 AS numactl FROM stagex/core-musl@sha256:d5f86324920cfc7fc34f0163502784b73161543ba0a312030a3ddff3ef8ab2f8 AS core-musl
FROM stagex/openpgp-card-tools:sx2024.09.0@sha256:56d4696d111b309e536f1b70980db7098cd7823005432e4130432cb2f625cf9f AS openpgp-card-tools FROM stagex/user-nettle@sha256:249bec1a4273f6461b39ef849d1d8b4ec2d4a3693930f9147cee6c37eef0794a AS user-nettle
FROM stagex/opensc:sx2024.09.0@sha256:5117a9d39d3b77655b29bf661d9e04eea2001a5b033b2fd6b4297048330ff6e7 AS opensc FROM stagex/user-npth@sha256:6ac9a90ca714ba01911c1f617553a5b23b96e9e37ec4a21e5ba132c4886a70e9 AS user-npth
FROM stagex/openssl:sx2024.09.0@sha256:2c1a9d8fcc6f52cb11a206f380b17d74c1079f04cbb08071a4176648b4df52c1 AS openssl FROM stagex/user-numactl@sha256:4046b643293cf9e82f1d29e92c61f0b12210b65987711ddd7c6813f27f3c1bfd AS user-numactl
FROM stagex/pcsc-lite:sx2024.09.0@sha256:4fe37671197ac768637e95f7395ae1a18412b3f42359d0c0aa9f4e7f684aef4e AS pcsc-lite FROM stagex/user-openpgp-card-tools@sha256:369c13ba0a772b1aef31321c0ebbb2a6fcd512491ace003e48c6f18f258905cc AS user-openpgp-card-tools
FROM stagex/pcsc-tools:sx2024.09.0@sha256:05046ca5d41a09163eda26785563fd98f0cb1179030c3f4ee3243997a907bb96 AS pcsc-tools FROM stagex/user-opensc@sha256:f8a1b5d07b6b594b964b63a2572fd10b44e79c3699efb97dfefc2f1dde054a6c AS user-opensc
FROM stagex/qemu:sx2024.09.0@sha256:c9b099bc7d810a581e0e0f68061dd525d7efdb5334d119b4253249a459bd907e AS qemu FROM stagex/core-openssl@sha256:8670a22fb76965f31bda1b61cd75ae39a96e1008deffe289a5d94ee4337b1cb2 AS core-openssl
FROM stagex/seabios:sx2024.09.0@sha256:f4e535fb1bfc2c7ae1756cdaa2404b1572f6ad195ceabba90d87ed0599fd97d7 AS seabios FROM stagex/user-pcsc-lite@sha256:0f06c2e73fabc6f9484bb39362d4084a45ffe88c862764813a62a75840b10cfc AS user-pcsc-lite
FROM stagex/sops:sx2024.09.0@sha256:c742fb1f0c5a4f9d9bc9afc37ba686b247d2b17d55d179409d33736b43c9aaa5 AS sops FROM stagex/user-pcsc-tools@sha256:366867b9c29664264224db7651b710cd70761b67c41ce9c27b9d2829e18b5a30 AS user-pcsc-tools
FROM stagex/swtpm:sx2024.09.0@sha256:c47fb2c4d8690936b4adef832a3f354231bb5a04206bf2fb565218034ce27792 AS swtpm FROM stagex/user-qemu@sha256:45b6d58b55a4c7d616da985d29482f2892540d815a90ed175e53b1c1b172497e AS user-qemu
FROM stagex/syslinux:sx2024.09.0@sha256:a41388558d7f6d9a29847ee2ff5507ab3100bfe9032ef3b99a3d783ad60ed390 AS syslinux FROM stagex/user-canokey-qemu@sha256:3f949f099194d2b721914d9d308c699818f83833b07db1d2e504ee16bfdfa348 AS user-canokey-qemu
FROM stagex/tpm2-tools:sx2024.09.0@sha256:c2fc693ec68a9d097151e5b3dd5b923f0dcc35fd4e0624b91ade3bf21367162c AS tpm2-tools FROM stagex/user-sdtool@sha256:f4be5c2fe87fa3dd8742f91be5a368b6833ceb7156d33192e5339869629aa06a AS user-sdtool
FROM stagex/tpm2-tss:sx2024.09.0@sha256:a8bf8c0973e1b5ba62ce5034a6230684ebe5a142da275d09e81fa2f2f9c87411 AS tpm2-tss FROM stagex/user-seabios@sha256:4adf4c3f70a6c69cb1c925a832363547cfb73ef5a7d75ff65885624916aace90 AS user-seabios
FROM stagex/util-linux:sx2024.09.0@sha256:7e3f3c1e748f5c216503e69b9f8f2e9f8084ec675fb29b23f3a6f0ed3b20c54a AS util-linux FROM stagex/user-sops@sha256:72b09ff439f422889af815f19a223b48b3b3fd0701d312a413069cbabcad7a12 AS user-sops
FROM stagex/xorriso:sx2024.09.0@sha256:2205a8f53d4fc569880c311061daa085f40c62b2fd94d556e72bd31b4df9e63a AS xorriso FROM stagex/core-zlib@sha256:b35b643642153b1620093cfe2963f5fa8e4d194fb2344a5786da5717018976c2 AS core-zlib
FROM stagex/xz:sx2024.09.0@sha256:b57c5e6144117bc0124855e9538e60c302cc7bf53fafb53e2eef3434015366f1 AS xz FROM stagex/user-sequoia-sq@sha256:b7197adb937e3ee0fc8e8edc041acb836da9b2958cbe4bb3b1797b73b50205f7 AS user-sequoia-sq
FROM stagex/yq:sx2024.09.0@sha256:bd6882f0f3ea664e9de6cf732cef2fa2781fc2852f5e6502a6aea1e63eb9708b AS yq FROM stagex/user-sequoia-sq-wot@sha256:7e914c221d65a4cda9683591082e9f5c70d8d31d6a415c1b98e75f4d89f985c5 AS user-sequoia-sq-wot
FROM stagex/zlib:sx2024.09.0@sha256:96b4100550760026065dac57148d99e20a03d17e5ee20d6b32cbacd61125dbb6 AS zlib FROM stagex/core-sqlite3@sha256:3c9318b8fae8471113a229f12cb8956cf8b0119177997ba69c4ead5e97efcdf4 AS core-sqlite3
FROM stagex/user-swtpm@sha256:fc72e5089c08476cfbfd863daf80b3ea86016c27f5c5cf8d497baf9aa0d23a78 AS user-swtpm
FROM stagex/user-syslinux@sha256:6a92128218d68d25d6e10a534776473d805923a318cccb303555f730c7b7410e AS user-syslinux
FROM stagex/user-tpm2-tools@sha256:f25049635ae36e17281c651e0fd6d949abc407185c1013887a0d4feab09ababf AS user-tpm2-tools
FROM stagex/user-tpm2-tss@sha256:58f4d393d6b51746a464ad4eb4a13867c8323c175e0798de9d27be171a088cfa AS user-tpm2-tss
FROM stagex/user-util-linux@sha256:ec5ec2dfd1803dc897a9c0589f12e7ccff3058be4048af3076ff33069f993dd8 AS user-util-linux
FROM stagex/user-xorriso@sha256:6649dab95928e8eeb0199f7bd27852e6fa2682949f3c8f2b7a03978a5ff15b10 AS user-xorriso
FROM stagex/core-xz@sha256:75b657032c8a47eabc3805bae944302c3eeab524e853d6d209285d4347cba0c7 AS core-xz
FROM stagex/user-yq@sha256:ce99f60d83a85fc6db249c141b39af68335bd45b066f2586d39fe111725c6730 AS user-yq
FROM stagex/user-edk2@sha256:db24be51d35117d264dccfc44f0ca331f59d738083170cd9bb86b49a5c06abff AS user-edk2
FROM stagex/core-ca-certificates@sha256:d6fca6c0080e8e5360cd85fc1c4bd3eab71ce626f40602e38488bfd61fd3e89d AS core-ca-certificates
FROM stagex/user-linux-guest-net@sha256:994b6fe49dd4331b32b0854055bff31b06db5eabdeafb32b2c0d55465b7ccf45 AS user-linux-guest-net
FROM stagex/user-linux-airgap@sha256:4f163e5f1f09f87d8f0fcf060193345f0b4dd8dbff2a2b2aec1cd4c254a628ca AS user-linux-airgap
FROM stagex/user-libimobiledevice-glue@sha256:3ce674285cbc04b694b7e400703868fcaac65401f2f2ca2aa2b720b3e0efee3c AS user-libimobiledevice-glue
FROM stagex/user-libimobiledevice@sha256:fcda68bdc397213fa76bd893472a304b093522aaac28e36f458275b93bb1af34 AS user-libimobiledevice
FROM stagex/user-libplist@sha256:2d776cb4eca3689a8bd6ac755a23f492850bf6c7b0c72e3525db6135e4d6e0bc AS user-libplist
FROM stagex/user-libusbmuxd@sha256:1e97f0a2ede0ee5fac9b056d0395e12b77c9f0bf550f9d0c20734ce0617eb51f AS user-libusbmuxd
FROM stagex/user-usbmuxd@sha256:90f687d2368328b76141badc382a21873a5b44d4ddccf851c017caf1e78af418 AS user-usbmuxd
FROM stagex/user-socat@sha256:990a70ae13462d8ba0a925fe959dd83070cbecdb3f91ff145caca5232171f3b8 AS user-socat
FROM stagex/user-dhcpcd@sha256:60bd86d9e2fcb6341c1efaeda5d786b63ff92e9d0c729cd8f634a20ff54ee71e AS user-dhcpcd
FROM stagex/user-guestctl@sha256:95ad9e34a003c7d1d01f5d427b5f79d2430f6e6634debde8e54f9a6f08749704 AS user-guestctl
FROM stagex/core-ncurses@sha256:6602a073bf9a408d1ed7c20ccc98fca974cd307fb8d1da6381fbca684a08169c AS core-ncurses
FROM stagex/user-libevent@sha256:1ba6f006f49cc327a5da84caeb0de7088da844f8021c5902fe387cd379732aec AS user-libevent
FROM stagex/user-tmux@sha256:57b63a27169a333edb073f1c6646a37ec6a9eee02ffdbc494a52bd6d670fc576 AS user-tmux
FROM scratch AS base FROM scratch AS base
ARG VERSION development ARG VERSION development
@ -58,73 +81,179 @@ ARG GIT_TIMESTAMP null
ARG GIT_AUTHOR null ARG GIT_AUTHOR null
ARG GIT_REF null ARG GIT_REF null
ARG GIT_PUBKEY null ARG GIT_PUBKEY null
COPY --from=busybox . / COPY --from=core-busybox . /
COPY --from=musl . / COPY --from=core-musl . /
COPY --from=xorriso . / COPY --from=core-xz . /
COPY --from=cpio . / COPY --from=user-xorriso . /
COPY --from=mtools . / COPY --from=user-cpio . /
COPY --from=xz . / COPY --from=user-mtools . /
COPY --from=grub . / COPY --from=user-grub . /
FROM base as dev FROM base AS dev
COPY --from=gcc . / COPY --from=core-gcc . /
COPY --from=glib . / COPY --from=core-zlib . /
COPY --from=alsa-lib . / COPY --from=user-glib . /
COPY --from=lzo . / COPY --from=user-alsa-lib . /
COPY --from=dtc . / COPY --from=user-lzo . /
COPY --from=zlib . / COPY --from=user-dtc . /
COPY --from=numactl . / COPY --from=user-numactl . /
COPY --from=libaio . / COPY --from=user-libaio . /
COPY --from=libseccomp . / COPY --from=user-libseccomp . /
COPY --from=libffi . / COPY --from=core-libffi . /
COPY --from=libzstd . / COPY --from=core-libzstd . /
COPY --from=libslirp . / COPY --from=user-libslirp . /
COPY --from=seabios . / COPY --from=user-seabios . /
COPY --from=ipxe . / COPY --from=user-ipxe . /
COPY --from=qemu . / COPY --from=user-qemu . /
COPY --from=swtpm . / COPY --from=user-canokey-qemu . /
COPY --from=openssl . / COPY --from=user-swtpm . /
COPY --from=curl . / COPY --from=core-openssl . /
COPY --from=libtpms . / COPY --from=core-curl . /
COPY --from=tpm2-tss . / COPY --from=user-libtpms . /
COPY --from=tpm2-tools . / COPY --from=user-tpm2-tss . /
COPY --from=user-tpm2-tools . /
COPY --from=user-edk2 . /
FROM base AS build-guest
COPY --from=user-linux-guest-net /bzImage iso/boot/vmlinuz
COPY --from=core-busybox . initramfs
COPY --from=user-eudev . initramfs
COPY --from=core-musl . initramfs
COPY --from=core-zlib . initramfs
COPY --from=core-openssl . initramfs
COPY --from=core-ca-certificates . initramfs
COPY --from=user-linux-guest-net . initramfs
COPY --from=user-linux-airgap . initramfs
COPY --from=user-libimobiledevice-glue . initramfs
COPY --from=user-libimobiledevice . initramfs
COPY --from=user-libplist . initramfs
COPY --from=user-libusb . initramfs
COPY --from=user-libusbmuxd . initramfs
COPY --from=core-gcc /usr/lib/. initramfs/usr/lib/
COPY --from=user-usbmuxd . initramfs
COPY --from=user-glib . initramfs
COPY --from=user-numactl . initramfs
COPY --from=user-dhcpcd . initramfs
COPY --from=user-qemu /usr/bin/qemu-ga initramfs/usr/bin/
COPY --from=core-curl . initramfs
COPY src/guest/rootfs/ initramfs
RUN <<-EOF
set -eux
cd initramfs
mkdir -p home/git
chmod 755 home
chown -R 1000:1000 home/git
find . -exec touch -hcd "@0" "{}" +
find . -print0 \
| sort -z \
| cpio \
--null \
--create \
--verbose \
--reproducible \
--format=newc \
| gzip --best \
> ../iso/boot/initramfs
EOF
COPY src/guest/config/syslinux.cfg iso/boot/syslinux/
COPY --from=user-syslinux \
/usr/share/syslinux/isohdpfx.bin \
/usr/share/syslinux/isolinux.bin \
/usr/share/syslinux/ldlinux.c32 \
/usr/share/syslinux/libutil.c32 \
/usr/share/syslinux/libcom32.c32 \
/usr/share/syslinux/mboot.c32 \
iso/boot/syslinux/
ENV SOURCE_DATE_EPOCH=1
RUN <<-EOF
set -eux
find iso -exec touch -hcd "@0" "{}" +
xorrisofs \
-output guest.img \
-full-iso9660-filenames \
-joliet \
-rational-rock \
-sysid LINUX \
-volid "airgap-guest" \
-isohybrid-mbr iso/boot/syslinux/isohdpfx.bin \
-eltorito-boot boot/syslinux/isolinux.bin \
-eltorito-catalog boot/syslinux/boot.cat \
-no-emul-boot \
-boot-load-size 4 \
-boot-info-table \
-no-emul-boot \
-isohybrid-gpt-basdat \
-follow-links \
iso/
EOF
FROM base AS build FROM base AS build
COPY --from=user-linux-airgap /bzImage iso/boot/vmlinuz
## Kernel COPY --from=build-guest /guest.img initramfs/
COPY --from=linux-airgap /bzImage iso/boot/vmlinuz COPY --from=core-busybox . initramfs
COPY --from=user-eudev . initramfs
## Initramfs COPY --from=core-musl . initramfs
COPY --from=busybox . initramfs COPY --from=core-zlib . initramfs
COPY --from=eudev . initramfs COPY --from=user-npth . initramfs
COPY --from=musl . initramfs COPY --from=user-libksba . initramfs
COPY --from=zlib . initramfs COPY --from=user-libgpg-error . initramfs
COPY --from=npth . initramfs COPY --from=user-libassuan . initramfs
COPY --from=libksba . initramfs COPY --from=user-libgcrypt . initramfs
COPY --from=libgpg-error . initramfs COPY --from=core-bash . initramfs
COPY --from=libassuan . initramfs COPY --from=user-gpg . initramfs
COPY --from=libgcrypt . initramfs COPY --from=user-jq . initramfs
COPY --from=keyfork . initramfs COPY --from=user-yq . initramfs
COPY --from=bash . initramfs COPY --from=core-bc . initramfs
COPY --from=gpg . initramfs COPY --from=user-flashtools . initramfs
COPY --from=jq . initramfs COPY --from=core-curl . initramfs
COPY --from=yq . initramfs COPY --from=user-tpm2-tools . initramfs
COPY --from=bc . initramfs COPY --from=user-tpm2-tss . initramfs
COPY --from=flashtools . initramfs COPY --from=core-openssl . initramfs
COPY --from=curl . initramfs COPY --from=user-libusb . initramfs
COPY --from=tpm2-tools . initramfs COPY --from=user-ccid . initramfs
COPY --from=tpm2-tss . initramfs COPY --from=user-pcsc-lite . initramfs
COPY --from=openssl . initramfs COPY --from=user-pcsc-tools . initramfs
COPY --from=libusb . initramfs COPY --from=user-libqrencode . initramfs
COPY --from=ccid . initramfs COPY --from=core-gmp . initramfs
COPY --from=pcsc-lite . initramfs COPY --from=core-libunwind . initramfs
COPY --from=pcsc-tools . initramfs COPY --from=user-nettle . initramfs
COPY --from=openpgp-card-tools . initramfs COPY --from=user-opensc . initramfs
COPY --from=libqrencode . initramfs COPY --from=user-util-linux . initramfs
COPY --from=opensc . initramfs COPY --from=user-sops . initramfs
COPY --from=util-linux . initramfs COPY --from=core-gcc /usr/lib/. initramfs/usr/lib/
COPY --from=sops . initramfs COPY --from=core-sqlite3 . initramfs
COPY rootfs/ initramfs COPY --from=user-sdtool . initramfs
RUN chmod +x initramfs/usr/bin/sdtool
COPY --from=user-openpgp-card-tools . initramfs
COPY --from=user-sequoia-sq . initramfs
COPY --from=user-sequoia-sq-wot . initramfs
COPY --from=user-libslirp . initramfs
COPY --from=user-seabios . initramfs
COPY --from=user-ipxe . initramfs
COPY --from=user-glib . initramfs
COPY --from=user-numactl . initramfs
COPY --from=core-libzstd . initramfs
COPY --from=user-alsa-lib . initramfs
COPY --from=user-lzo . initramfs
COPY --from=user-dtc . initramfs
COPY --from=user-libaio . initramfs
COPY --from=user-libseccomp . initramfs
COPY --from=core-libffi . initramfs
COPY --from=core-libzstd . initramfs
COPY --from=user-libslirp . initramfs
COPY --from=user-seabios . initramfs
COPY --from=user-canokey-qemu . initramfs
COPY --from=user-qemu . initramfs
COPY --from=user-socat . initramfs
COPY --from=user-libzbar . initramfs
COPY --from=user-keyfork . initramfs
COPY --from=user-icepick . initramfs
COPY --from=user-guestctl . initramfs
COPY --from=user-libevent . initramfs
COPY --from=core-ncurses . initramfs
COPY --from=user-tmux . initramfs
COPY src/host/rootfs/ initramfs
COPY <<-EOF initramfs/etc/environment COPY <<-EOF initramfs/etc/environment
export VERSION="$VERSION" export VERSION="$VERSION"
export GIT_TIMESTAMP="$GIT_TIMESTAMP" export GIT_TIMESTAMP="$GIT_TIMESTAMP"
@ -149,8 +278,8 @@ RUN <<-EOF
EOF EOF
## Grub (EFI Boot) ## Grub (EFI Boot)
COPY config/grub.cfg iso/boot/grub/grub.cfg COPY src/host/config/grub.cfg iso/boot/grub/grub.cfg
COPY config/grub_early.cfg grub_early.cfg COPY src/host/config/grub_early.cfg grub_early.cfg
RUN <<-EOF RUN <<-EOF
set -eux set -eux
mkdir -p efi/boot mkdir -p efi/boot
@ -182,8 +311,8 @@ RUN <<-EOF
EOF EOF
## Syslinux (BIOS Boot) ## Syslinux (BIOS Boot)
COPY config/syslinux.cfg iso/boot/syslinux/ COPY src/host/config/syslinux.cfg iso/boot/syslinux/
COPY --from=syslinux \ COPY --from=user-syslinux \
/usr/share/syslinux/isohdpfx.bin \ /usr/share/syslinux/isohdpfx.bin \
/usr/share/syslinux/isolinux.bin \ /usr/share/syslinux/isolinux.bin \
/usr/share/syslinux/ldlinux.c32 \ /usr/share/syslinux/ldlinux.c32 \
@ -192,8 +321,6 @@ COPY --from=syslinux \
/usr/share/syslinux/mboot.c32 \ /usr/share/syslinux/mboot.c32 \
iso/boot/syslinux/ iso/boot/syslinux/
## Build Hybrid EFI/BIOS ISO
FROM build AS install
ENV SOURCE_DATE_EPOCH=1 ENV SOURCE_DATE_EPOCH=1
RUN <<-EOF RUN <<-EOF
set -eux set -eux
@ -232,5 +359,5 @@ RUN <<-EOF
EOF EOF
FROM scratch AS package FROM scratch AS package
COPY --from=install /sdcard.img / COPY --from=build /sdcard.img /
COPY --from=install /airgap.iso / COPY --from=build /airgap.iso /

View File

@ -1,17 +1,22 @@
VERSION := development VERSION := development
GIT_REF := $(shell git log -1 --format=%H) GIT_REF := $(shell git log -1 --format=%H)
GIT_AUTHOR := $(shell git log -1 --format=%an) GIT_AUTHOR := $(shell git log -1 --format=%an)
GIT_PUBKEY := $(shell git log -1 --format=%GP) GIT_PUBKEY := $(shell git log -1 --format=%GK)
GIT_TIMESTAMP := $(shell git log -1 --format=%cd --date=iso) GIT_TIMESTAMP := $(shell git log -1 --format=%cd --date=iso)
EFI := false
GUI := false
,:=,
export export
## Use env vars from latest release when reproducing ## Use env vars from latest release when reproducing
ifdef REPRODUCE ifdef REPRODUCE
include dist/release.env include dist/release.env
export export
endif endif
## Prevents use of caching when building docker image
ifdef NOCACHE ifdef NOCACHE
NO_CACHE := --no-cache NO_CACHE := --no-cache
endif endif
.DEFAULT_GOAL := .DEFAULT_GOAL :=
@ -47,6 +52,32 @@ out/dev-shell.digest: Containerfile | out
shell: out/dev-shell.digest shell: out/dev-shell.digest
docker run -it $(shell cat $<) /bin/sh docker run -it $(shell cat $<) /bin/sh
.PHONY: system-vm
system-vm:
qemu-system-x86_64 \
-m 4G \
-machine q35,kernel-irqchip=split \
-usb \
-device sdhci-pci \
-device sd-card,drive=external \
-drive id=external,if=none,format=raw,file=out/sdcard.img \
-device usb-storage,drive=usbdrive \
-device intel-iommu,intremap=on \
-netdev user,id=net0 \
-device e1000,netdev=net0 \
-chardev socket,path=out/qga.sock,server=on,wait=off,id=qga0 \
-device virtio-serial \
-device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0 \
$(if $(filter $(EFI),true) ,\
-bios /usr/share/ovmf/OVMF.fd \
-drive id=boot$(,)if=virtio$(,)format=raw$(,)file=out/airgap.iso \
,\
-drive id=usbdrive,if=none,format=raw,file=out/airgap.iso \
-boot order=c \
) \
$(if (,$(wildcard /dev/kvm)),-cpu host --accel kvm,) \
$(if $(filter $(GUI),true),,-nographic)
.PHONY: vm .PHONY: vm
vm: out/dev-shell.digest out/airgap.iso out/sdcard.img vm: out/dev-shell.digest out/airgap.iso out/sdcard.img
docker run -it -v ./out:/out $(shell cat $<) sh -c "\ docker run -it -v ./out:/out $(shell cat $<) sh -c "\
@ -56,8 +87,9 @@ vm: out/dev-shell.digest out/airgap.iso out/sdcard.img
--tpm2 & \ --tpm2 & \
qemu-system-x86_64 \ qemu-system-x86_64 \
-m 4G \ -m 4G \
-machine pc \ -machine q35,kernel-irqchip=split \
-chardev socket,id=chrtpm,path=vtpm-sock \ -chardev socket,id=chrtpm,path=vtpm-sock \
-usb -device canokey,file=/out/canokey-file \
-tpmdev emulator,id=tpm0,chardev=chrtpm \ -tpmdev emulator,id=tpm0,chardev=chrtpm \
-device tpm-tis,tpmdev=tpm0 \ -device tpm-tis,tpmdev=tpm0 \
-usb \ -usb \
@ -65,17 +97,33 @@ vm: out/dev-shell.digest out/airgap.iso out/sdcard.img
-device sd-card,drive=external \ -device sd-card,drive=external \
-drive id=external,if=none,format=raw,file=out/sdcard.img \ -drive id=external,if=none,format=raw,file=out/sdcard.img \
-device usb-storage,drive=usbdrive \ -device usb-storage,drive=usbdrive \
-device intel-iommu,intremap=on \
-netdev user,id=net0 \
-device e1000,netdev=net0 \
-chardev socket,path=out/qga.sock,server=on,wait=off,id=qga0 \
-device virtio-serial \
-device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0 \
$(if $(filter $(EFI),true) ,\
-bios /usr/share/ovmf/OVMF.fd \
-drive id=boot$(,)if=virtio$(,)format=raw$(,)file=out/airgap.iso \
,\
-drive id=usbdrive,if=none,format=raw,file=out/airgap.iso \ -drive id=usbdrive,if=none,format=raw,file=out/airgap.iso \
-boot order=c \ -boot order=c \
) \
$(if (,$(wildcard /dev/kvm)),,-cpu host --accel kvm) \
-nographic; \ -nographic; \
" "
## Signing, Verification, and Release Targets ## Release, Signing, Verification, and Reproduction Targets
.PHONY: clean .PHONY: clean
clean: clean:
rm -rf out rm -rf out
.PHONY: update
update:
python3 src/update.py
.PHONY: release .PHONY: release
release: clean release: clean
$(MAKE) NOCACHE=1 VERSION=$(VERSION) $(MAKE) NOCACHE=1 VERSION=$(VERSION)

View File

@ -57,7 +57,7 @@ make release
### Reproduce an existing release ### Reproduce an existing release
``` ```
make attest make reproduce
``` ```
### Sign an existing release ### Sign an existing release
@ -129,41 +129,6 @@ make vm
make shell make shell
``` ```
## Writing to SD Card ##
1. Flash `airgap.iso` to an SD Card:
* Use `lsblk` to find device name
* `dd if=out/airgap.iso of=/dev/<your_device> bs=4M status=progress conv=fsync`
2. Use the `sdtool` to lock the SD Card:
a. Get deterministically built binary of `sdtool` from StageX:
* `docker pull stagex/sdtool:latest`
b. Extracting binary:
* Run docker container: `docker create -p 4000:80 --name sdtool stagex/sdtool`
* Copy image to tar: `docker export <container_id> -o sdtool.tar`
* Extract binary from tar: `mkdir -p sdtool-dir | tar -xvf sdtool.tar -C sdtool-dir | cp sdtool-dir/usr/bin/sdtool ./sdtool`
* You can verify the container hash:
* To get container hash: `docker inspect --format='{{json .RepoDigests}}' stagex/sdtool`
* Check the [signatures dir](https://codeberg.org/stagex/stagex/src/branch/main/signatures/stagex) in stagex project for latest signed hashes
c. Permanently lock the card:
* `./sdtool /dev/mmcblk permlock`
d. Test that the card can't be written to:
* `dd if=out/airgap.iso of=/dev/sdb bs=1M status=progress conv=fsync`
3. Verify that the hash of `airgap.iso` matches what's flashed on the SD card:
* `head -c $(stat -c '%s' out/airgap.iso) /dev/<your_device> | sha256sum`
* `sha256sum out/airgap.iso`
## Hardware Compatibility ## ## Hardware Compatibility ##
### Tested Models ### Tested Models

BIN
dist/airgap.iso (Stored with Git LFS) vendored

Binary file not shown.

View File

@ -1,16 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEZ1U/vaRrtxq9LgsLjkeh7DWhVR0FAma0fbsACgkQjkeh7DWh
VR0lYBAAsjKcqgoSM73lck4gSga3CWtTfZ/k7azr98HnUw5InTyTwvna2sRGL3jb
Q0pUhrPVQVmjXSyxD/hR/uLuiAfUn2Gyhp1MZS3C7jmFcRsxCJzNbByv/2bUS2+U
5TaCoxmM8SdxTqcBIyYylKzZ4ub0t3bCWUt2uPqdSqslgEReeqbzzE3jpmiUfmHE
daaZhZa3iPEr7vqq00jUGFuSEdxQCQkty0nZHzfGhHwbliiUGyH6/bb+u4v5eGYH
VEyRq0CWFgw5sywpSf3UZjR0fkd0do9z6Li1ggN2GV63I4oT3L1LltcMXtgfMp+B
SA3gz7/mJsMqM6H2ZWqUgJAZw/mZCGStftSnOTKdyEtpzagNNeePa5f4kM1ZuHF6
ehSl1nbnCeCPfedS8+oUm3v8qWiFLXz4tmYvBnfDWaUXIYpNOrvJPtatdinTNRfl
nglyEt6Olc+3vEqkrEl7JFu13Gl92mbuhhelKjM/VDheHBUZ6yrso1aLbyruO+wm
RxL3pQSCNfAnIQpSdkXga5gVvbZDDISBast3qHFuZaZFbo2p24hw0HnLAfyCrxgF
JnN3x2qqRlTzQSrVr4EEXUwUqpt5LlnQ3kDLNVYhXuqTdmyETj1YGnAXkqV/D+Z7
B7hlDdddXI5d0yDoYPAmF9N7XJCasdfutnO/8IfZ/eE989jYybE=
=eruT
-----END PGP SIGNATURE-----

View File

@ -1,16 +1,16 @@
-----BEGIN PGP SIGNATURE----- -----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEiII6deyqeGsP84sUjkAUeKP773IFAma0f0IACgkQjkAUeKP7 iQIzBAABCgAdFiEEiII6deyqeGsP84sUjkAUeKP773IFAmglbi8ACgkQjkAUeKP7
73I33w//SaGbbM9z8SYsWhii1SBnfs6NVQSwdBoO20C4gFdmZkPVDak3QoCAioaC 73I7Rg/+MQ4yDhcnwBBtlN651Kcou5Z7EhAY5S9stg69yfqWL0MacNGRnEmNHYix
GjlEOEDb7SXfWi3n2z72P97dswN6dG1IxQKR1N913IWzUUEXGR0phaC+o0P1/f74 0J39xeYvP/dSsXYWgW04f0w4FS+msuqK9ML3YbB3Ei7GH4c+Bizhoj415chSMOlo
MXrcUDLwwJwZsA/0zMV6gHvONEqwgmfEO4WrEB/Ty7ueoJjsmQ2oauWytlh8CVDR R97Gz2V+SZ83Ph51+ORA4DUZ3/PIoXfv5syTKmcrioUP9XhCou61TCqN4fMGgXpq
3HFwiVoAjRC2d0vKj0eL2n9pNQNEYKb+oJ/gq3sk2L8qPs1vThQguHADvqmi6V3w 5F4awAZRrTtw+67dcEOmSQ7+TbNsMhJIei5Bg8FdPNS2VuMuUGTMrwsL7FBXIg1j
+4tZqviksPXb+sve3VTsKFDbd5AXvcRY4TbPawQ5W7Aa6iK9W/yA10+zXvcHoGrA 2J4tXUhZvLz7x3i0nuVlELfd6w1dDHW77e9rCmifGd4QRN+gqUGoOjp93HgnsUrJ
6iMR94yI9eprBkqoeoxr2MHPk+8d9xXB16hY/h+OCPibkFFfPST9GDFcp0nk1JFH ASY0BKWfHeHcxpT2qtUuKZuBBjtGkGM9YQSUXYvuzhJp9XEZb9GHBMVo1TvX0sZr
b0bbpanBsxwN3IxTAL0a7iD2nxftZHjgiZib1lhdhLg35o9iou1V0fRPwdjepS3o jWyUVSBlcZuOlG5iGMF8D44nJOX4QikPuGLOJxmG2pOiFvh32qsTA50HV6/BEzZr
2TBvKhtNncUW/87ZhxhdkTI/iUvS0iem3KHUQXkM+ziOC5zGf+PYvMCuy2P0oSei s5zm1IgsdF1SDPrxiqRPjZyvZYcF2kZtqxkzXEJzdPwcqCR9VXHo7InU7OrSg1D0
731aVOgxKbpEZHY0pTkuqG7U4+RWZ+KJEnxETcZWoCeY9DW/u2Dx5hukeZJbvmUo T/4wvsz50gsck1UvhEKukBVaWBmyzjHdnUPelOSbiUfn8xSKeL9RGGktV6tF3bUq
111vBoziyocgKvKi5S3ctZaAwm2wNsE0TU/o5u9+Q5ST1wgsKJF+F0laCUQcDPwM M1yBYp8Bpm3TteqGgeaUjJ5xSRGjynJrlFm+6YSJhf4AOVaex/Tysdlkg8ylQZLn
UyM5VznH31pChrlzRiUcsm0lMvDkx+JfTSBPOgzABMAcQ3YuTSk= IrfZXgpmazBLKHtxQKyr4znWqN+DptMt6W7kPCwejQjiN5WH494=
=e+q6 =BFLb
-----END PGP SIGNATURE----- -----END PGP SIGNATURE-----

4
dist/manifest.txt vendored
View File

@ -1,2 +1,2 @@
fe92783ef775ccc5e32baefb26f951b7f37ed26ecbb4601a068e20b31bebadbb airgap.iso cafe1d794f8bb10e652da130e7f3f2f1a13e0ee89f54fdb6385b6fb191a22221 airgap.iso
b714c963bd8b1f3a38295821f0a3521bc64f97c1023c49d22a2e7433385b1a09 release.env eed8667982e86e41f2ebd1331f408e93ac5ef2a574ee23e7635cbb23506aec73 release.env

10
dist/release.env vendored
View File

@ -1,5 +1,5 @@
VERSION=2024.8.1 VERSION=development
GIT_REF=ea623cc147741b0a753ce4ea7aabe512df9a2ef9 GIT_REF=bdc971a931bf9fc51395beb5afd328d8b493a801
GIT_AUTHOR=Lance R. Vick GIT_AUTHOR=Anton Livaja
GIT_PUBKEY=6B61ECD76088748C70590D55E90A401336C8AAA9 GIT_PUBKEY=44A86CFF1FDF0E85
GIT_TIMESTAMP=2024-08-08 00:34:41 -0700 GIT_TIMESTAMP=2025-05-14 19:12:21 -0700

View File

@ -1 +0,0 @@
pinentry-mode loopback

View File

@ -0,0 +1,8 @@
TIMEOUT 2
PROMPT -1
DEFAULT AirgapGuest
LABEL AirgapGuest
MENU LABEL Linux AirgapGuest
KERNEL /boot/vmlinuz
INITRD /boot/initramfs
APPEND init=/init vga=normal console=ttyAMA0,115200 console=tty highres=off console=ttyS0 console=tty0 ro

View File

@ -0,0 +1,47 @@
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:lp
mem:x:8:
kmem:x:9:
wheel:x:10:root
floppy:x:11:root
mail:x:12:mail
news:x:13:news
uucp:x:14:uucp
man:x:15:man
cron:x:16:cron
console:x:17:
audio:x:18:
cdrom:x:19:
dialout:x:20:root
ftp:x:21:
sshd:x:22:
input:x:23:
at:x:25:at
tape:x:26:root
video:x:27:root
netdev:x:28:
readproc:x:30:
squid:x:31:squid
xfs:x:33:xfs
kvm:x:34:kvm
games:x:35:
shadow:x:42:
cdrw:x:80:
www-data:x:82:
usb:x:85:
vpopmail:x:89:
users:x:100:games
ntp:x:123:
nofiles:x:200:
smmsp:x:209:smmsp
locate:x:245:
abuild:x:300:
utmp:x:406:
ping:x:999:
git:x:1000:

View File

@ -0,0 +1,4 @@
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback airgap-guest
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

View File

@ -13,7 +13,7 @@ SYSLOGD_ARGS=""
start() { start() {
printf 'Starting %s: ' "$DAEMON" printf 'Starting %s: ' "$DAEMON"
# shellcheck disable=SC2086 # we need the word splitting # shellcheck disable=SC2086 # we need the word splitting
start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/sbin/$DAEMON" \ start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/bin/$DAEMON" \
-- -n $SYSLOGD_ARGS -- -n $SYSLOGD_ARGS
status=$? status=$?
if [ "$status" -eq 0 ]; then if [ "$status" -eq 0 ]; then

View File

@ -13,7 +13,7 @@ KLOGD_ARGS=""
start() { start() {
printf 'Starting %s: ' "$DAEMON" printf 'Starting %s: ' "$DAEMON"
# shellcheck disable=SC2086 # we need the word splitting # shellcheck disable=SC2086 # we need the word splitting
start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/sbin/$DAEMON" \ start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/bin/$DAEMON" \
-- -n $KLOGD_ARGS -- -n $KLOGD_ARGS
status=$? status=$?
if [ "$status" -eq 0 ]; then if [ "$status" -eq 0 ]; then

View File

@ -0,0 +1,30 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: qemu-ga
# Required-Start: $remote_fs $syslog
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop:
# Short-Description: Start QEMU Guest Agent
### END INIT INFO
case "$1" in
start)
echo "Starting QEMU Guest Agent"
cat /proc/cpuinfo | grep QEMU && qemu-ga &
;;
stop)
echo "Stopping QEMU Guest Agent"
killall qemu-ga
;;
restart)
"$0" stop
"$0" start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
exit 0

View File

@ -0,0 +1,54 @@
# /etc/inittab
# Format for each entry: <id>:<runlevels>:<action>:<process>
#
# id == tty to run on, or empty for /dev/console
# runlevels == ignored
# action == one of sysinit, respawn, askfirst, wait, and once
# process == program to run
# Startup the system
::sysinit:/bin/mount -t devtmpfs devtmpfs /dev
::sysinit:/bin/mkdir -p /proc /run /dev/pts /dev/shm /sys
::sysinit:/bin/mount -t sysfs sysfs /sys
::sysinit:/bin/mount -t devpts devpts /dev/pts
::sysinit:/bin/mount -t cgroup cgroup /sys/fs/cgroup
::sysinit:/bin/mount -t proc proc /proc
::sysinit:/bin/mount -o remount,rw /
::sysinit:/bin/mkdir /var/log
::sysinit:/bin/hostname -F /etc/hostname
null::sysinit:/bin/ln -sf /proc/self/fd /dev/fd
null::sysinit:/bin/ln -sf /proc/self/fd/0 /dev/stdin
null::sysinit:/bin/ln -sf /proc/self/fd/1 /dev/stdout
null::sysinit:/bin/ln -sf /proc/self/fd/2 /dev/stderr
# Stuff to do for the 3-finger salute
::ctrlaltdel:/usr/bin/reboot
# now run any rc scripts
::sysinit:/etc/init.d/rcS
# Spawn shells on serial terminal and default console
::respawn:-/usr/bin/login -f root
ttyS0::respawn:-/usr/bin/login -f root
# Stuff to do before rebooting
::shutdown:/etc/init.d/rcK
::shutdown:/bin/umount -a -r
::sysinit:/bin/hostname -F /etc/hostname
null::sysinit:/bin/ln -sf /proc/self/fd /dev/fd
null::sysinit:/bin/ln -sf /proc/self/fd/0 /dev/stdin
null::sysinit:/bin/ln -sf /proc/self/fd/1 /dev/stdout
null::sysinit:/bin/ln -sf /proc/self/fd/2 /dev/stderr
# now run any rc scripts
::sysinit:/etc/init.d/rcS
# Put a getty on the serial port
ttyS0::respawn:-/usr/bin/login -f root
# Stuff to do for the 3-finger salute
#::ctrlaltdel:/sbin/reboot
# Stuff to do before rebooting
::shutdown:/etc/init.d/rcK
::shutdown:/bin/umount -a -r

View File

@ -0,0 +1,4 @@
root::0:0:root:/root:/bin/sh
sshd:x:22:22:sshd:/dev/null:/sbin/nologin
git::1000:1000::/home/git:/bin/git-shell
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

View File

@ -0,0 +1,5 @@
export EDITOR=/bin/vi
export PATH="/usr/local/bin:/bin:/sbin:/usr/bin:/usr/sbin"
export PS1="[\h \t] \\$ "
export GNUPGHOME=/.gnupg
cd /root

View File

@ -0,0 +1,2 @@
nameserver 1.1.1.1
nameserver 8.8.8.8

View File

@ -1,5 +1,5 @@
set timeout=1 set timeout=1
menuentry "Linux Airgap" { menuentry "Linux Airgap" {
linux /boot/vmlinuz init=/init console=ttyS0 console=tty0 ro linux /boot/vmlinuz init=/init console=ttyS0 console=tty0 ro loglevel=3
initrd /boot/initramfs initrd /boot/initramfs
} }

View File

@ -0,0 +1,55 @@
#!/bin/sh
DAEMON="syslogd"
PIDFILE="/var/run/$DAEMON.pid"
SYSLOGD_ARGS=""
# shellcheck source=/dev/null
[ -r "/etc/default/$DAEMON" ] && . "/etc/default/$DAEMON"
# BusyBox' syslogd does not create a pidfile, so pass "-n" in the command line
# and use "-m" to instruct start-stop-daemon to create one.
start() {
printf 'Starting %s: ' "$DAEMON"
# shellcheck disable=SC2086 # we need the word splitting
start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/bin/$DAEMON" \
-- -n $SYSLOGD_ARGS
status=$?
if [ "$status" -eq 0 ]; then
echo "OK"
else
echo "FAIL"
fi
return "$status"
}
stop() {
printf 'Stopping %s: ' "$DAEMON"
start-stop-daemon -K -q -p "$PIDFILE"
status=$?
if [ "$status" -eq 0 ]; then
rm -f "$PIDFILE"
echo "OK"
else
echo "FAIL"
fi
return "$status"
}
restart() {
stop
sleep 1
start
}
case "$1" in
start|stop|restart)
"$1";;
reload)
# Restart, since there is no true "reload" feature.
restart;;
*)
echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac

View File

@ -0,0 +1,55 @@
#!/bin/sh
DAEMON="klogd"
PIDFILE="/var/run/$DAEMON.pid"
KLOGD_ARGS=""
# shellcheck source=/dev/null
[ -r "/etc/default/$DAEMON" ] && . "/etc/default/$DAEMON"
# BusyBox' klogd does not create a pidfile, so pass "-n" in the command line
# and use "-m" to instruct start-stop-daemon to create one.
start() {
printf 'Starting %s: ' "$DAEMON"
# shellcheck disable=SC2086 # we need the word splitting
start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/bin/$DAEMON" \
-- -n $KLOGD_ARGS
status=$?
if [ "$status" -eq 0 ]; then
echo "OK"
else
echo "FAIL"
fi
return "$status"
}
stop() {
printf 'Stopping %s: ' "$DAEMON"
start-stop-daemon -K -q -p "$PIDFILE"
status=$?
if [ "$status" -eq 0 ]; then
rm -f "$PIDFILE"
echo "OK"
else
echo "FAIL"
fi
return "$status"
}
restart() {
stop
sleep 1
start
}
case "$1" in
start|stop|restart)
"$1";;
reload)
# Restart, since there is no true "reload" feature.
restart;;
*)
echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac

View File

@ -0,0 +1,94 @@
#!/bin/sh
#
# This script is used by busybox and procps-ng.
#
# With procps-ng, the "--system" option of sysctl also enables "--ignore", so
# errors are not reported via syslog. Use the run_logger function to mimic the
# --system behavior, still reporting errors via syslog. Users not interested
# on error reports can add "-e" to SYSCTL_ARGS.
#
# busybox does not have a "--system" option neither reports errors via syslog,
# so the scripting provides a consistent behavior between the implementations.
# Testing the busybox sysctl exit code is fruitless, as at the moment, since
# its exit status is zero even if errors happen. Hopefully this will be fixed
# in a future busybox version.
PROGRAM="sysctl"
SYSCTL_ARGS=""
# shellcheck source=/dev/null
[ -r "/etc/default/$PROGRAM" ] && . "/etc/default/$PROGRAM"
# Files are read from directories in the SYSCTL_SOURCES list, in the given
# order. A file may be used more than once, since there can be multiple
# symlinks to it. No attempt is made to prevent this.
SYSCTL_SOURCES="/etc/sysctl.d/ /usr/local/lib/sysctl.d/ /usr/lib/sysctl.d/ /lib/sysctl.d/ /etc/sysctl.conf"
# If the logger utility is available all messages are sent to syslog, except
# for the final status. The file redirections do the following:
#
# - stdout is redirected to syslog with facility.level "kern.info"
# - stderr is redirected to syslog with facility.level "kern.err"
# - file dscriptor 4 is used to pass the result to the "start" function.
#
run_logger() {
# shellcheck disable=SC2086 # we need the word splitting
find $SYSCTL_SOURCES -maxdepth 1 -name '*.conf' -print0 2> /dev/null | \
xargs -0 -r -n 1 readlink -f | {
prog_status="OK"
while :; do
read -r file || {
echo "$prog_status" >&4
break
}
echo "* Applying $file ..."
/sbin/sysctl -p "$file" $SYSCTL_ARGS || prog_status="FAIL"
done 2>&1 >&3 | /usr/bin/logger -t sysctl -p kern.err
} 3>&1 | /usr/bin/logger -t sysctl -p kern.info
}
# If logger is not available all messages are sent to stdout/stderr.
run_std() {
# shellcheck disable=SC2086 # we need the word splitting
find $SYSCTL_SOURCES -maxdepth 1 -name '*.conf' -print0 2> /dev/null | \
xargs -0 -r -n 1 readlink -f | {
prog_status="OK"
while :; do
read -r file || {
echo "$prog_status" >&4
break
}
echo "* Applying $file ..."
/sbin/sysctl -p "$file" $SYSCTL_ARGS || prog_status="FAIL"
done
}
}
if [ -x /usr/bin/logger ]; then
run_program="run_logger"
else
run_program="run_std"
fi
start() {
printf '%s %s: ' "$1" "$PROGRAM"
status=$("$run_program" 4>&1)
echo "$status"
if [ "$status" = "OK" ]; then
return 0
fi
return 1
}
case "$1" in
start)
start "Running";;
restart|reload)
start "Rerunning";;
stop)
:;;
*)
echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac

View File

@ -0,0 +1,22 @@
#!/bin/sh
case "${1}" in
start)
keymap="$( \
awk -F 'keymap=' '{sub(/ .*$/, "", $2); print $2}' /proc/cmdline \
)"
if [[ ! -z "$keymap" ]]; then
printf 'Loading Keymap %s: ' "${keymap}"
loadkeys "$keymap"
if [ $? -eq 0 ]; then
echo "OK"
else
echo "FAIL"
fi
fi
;;
*)
echo "Usage: ${0} {start}"
exit 1
;;
esac

View File

@ -0,0 +1,24 @@
#!/bin/sh
case "$1" in
start)
printf "Populating %s using udev: " "${udev_root:-/dev}"
[ -e /proc/sys/kernel/hotplug ] && printf '\000\000\000\000' > /proc/sys/kernel/hotplug
/sbin/udevd -d || { echo "FAIL"; exit 1; }
udevadm trigger --type=subsystems --action=add
udevadm trigger --type=devices --action=add
udevadm settle --timeout=30 || echo "udevadm settle failed"
echo "done"
;;
stop)
# Stop execution of events
udevadm control --stop-exec-queue
killall udevd
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
;;
esac
exit 0

View File

@ -0,0 +1,70 @@
#! /bin/sh
#
# Preserve the random seed between reboots. See urandom(4).
#
# Quietly do nothing if /dev/urandom does not exist
[ -c /dev/urandom ] || exit 0
URANDOM_SEED="/var/lib/random-seed"
# shellcheck source=/dev/null
[ -r "/etc/default/urandom" ] && . "/etc/default/urandom"
if pool_bits=$(cat /proc/sys/kernel/random/poolsize 2> /dev/null); then
pool_size=$((pool_bits/8))
else
pool_size=512
fi
init_rng() {
[ -f "$URANDOM_SEED" ] || return 0
printf 'Initializing random number generator: '
dd if="$URANDOM_SEED" bs="$pool_size" of=/dev/urandom count=1 2> /dev/null
status=$?
if [ "$status" -eq 0 ]; then
echo "OK"
else
echo "FAIL"
fi
return "$status"
}
save_random_seed() {
printf 'Saving random seed: '
status=1
if touch "$URANDOM_SEED.new" 2> /dev/null; then
old_umask=$(umask)
umask 077
dd if=/dev/urandom of="$URANDOM_SEED.tmp" bs="$pool_size" count=1 2> /dev/null
cat "$URANDOM_SEED" "$URANDOM_SEED.tmp" 2>/dev/null \
| sha256sum \
| cut -d ' ' -f 1 > "$URANDOM_SEED.new" && \
mv "$URANDOM_SEED.new" "$URANDOM_SEED" && status=0
rm -f "$URANDOM_SEED.tmp"
umask "$old_umask"
if [ "$status" -eq 0 ]; then
echo "OK"
else
echo "FAIL"
fi
else
echo "SKIP (read-only file system detected)"
fi
return "$status"
}
case "$1" in
start|restart|reload)
# Carry a random seed from start-up to start-up
# Load and then save the whole entropy pool
init_rng && save_random_seed;;
stop)
# Carry a random seed from shut-down to start-up
# Save the whole entropy pool
save_random_seed;;
*)
echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac

View File

@ -0,0 +1,30 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: qemu-ga
# Required-Start: $remote_fs $syslog
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop:
# Short-Description: Start QEMU Guest Agent
### END INIT INFO
case "$1" in
start)
echo "Starting QEMU Guest Agent"
cat /proc/cpuinfo | grep QEMU && qemu-ga &
;;
stop)
echo "Stopping QEMU Guest Agent"
killall qemu-ga
;;
restart)
"$0" stop
"$0" start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
exit 0

27
src/host/rootfs/etc/init.d/rcK Executable file
View File

@ -0,0 +1,27 @@
#!/bin/sh
# Stop all init scripts in /etc/init.d
# executing them in reversed numerical order.
#
for i in $(ls -r /etc/init.d/S??*) ;do
# Ignore dangling symlinks (if any).
[ ! -f "$i" ] && continue
case "$i" in
*.sh)
# Source shell script for speed.
(
trap - INT QUIT TSTP
set stop
. $i
)
;;
*)
# No sh extension, so fork subprocess.
$i stop
;;
esac
done

27
src/host/rootfs/etc/init.d/rcS Executable file
View File

@ -0,0 +1,27 @@
#!/bin/sh
# Start all init scripts in /etc/init.d
# executing them in numerical order.
#
for i in /etc/init.d/S??* ;do
# Ignore dangling symlinks (if any).
[ ! -f "$i" ] && continue
case "$i" in
*.sh)
# Source shell script for speed.
(
trap - INT QUIT TSTP
set start
. $i
)
;;
*)
# No sh extension, so fork subprocess.
$i start
;;
esac
done

View File

@ -10,9 +10,11 @@
# Startup the system # Startup the system
::sysinit:/bin/mount -t devtmpfs devtmpfs /dev ::sysinit:/bin/mount -t devtmpfs devtmpfs /dev
::sysinit:/bin/mkdir -p /proc /run /dev/pts /dev/shm /sys ::sysinit:/bin/mkdir -p /proc /run /dev/pts /dev/shm /sys
::sysinit:/bin/mount -t devpts devpts /dev/pts
::sysinit:/bin/mount -t sysfs sysfs /sys ::sysinit:/bin/mount -t sysfs sysfs /sys
::sysinit:/bin/mount -t proc proc /proc ::sysinit:/bin/mount -t proc proc /proc
::sysinit:/bin/mount -o remount,rw / ::sysinit:/bin/mount -o remount,rw /
::sysinit:/bin/mkdir /var/log
null::sysinit:/bin/ln -sf /proc/self/fd /dev/fd null::sysinit:/bin/ln -sf /proc/self/fd /dev/fd
null::sysinit:/bin/ln -sf /proc/self/fd/0 /dev/stdin null::sysinit:/bin/ln -sf /proc/self/fd/0 /dev/stdin
null::sysinit:/bin/ln -sf /proc/self/fd/1 /dev/stdout null::sysinit:/bin/ln -sf /proc/self/fd/1 /dev/stdout
@ -20,8 +22,8 @@ null::sysinit:/bin/ln -sf /proc/self/fd/2 /dev/stderr
# now run any rc scripts # now run any rc scripts
::sysinit:/etc/init.d/rcS ::sysinit:/etc/init.d/rcS
# Put shells on the serial terminal and console # Put a shell on serial and tmux on console
console::respawn:-/bin/bash console::respawn:-/bin/bash -l -c /bin/tmux
ttyS0::respawn:-/bin/bash ttyS0::respawn:-/bin/bash
# Stuff to do for the 3-finger salute # Stuff to do for the 3-finger salute

View File

@ -0,0 +1 @@
i915

View File

@ -1,7 +1,14 @@
case "$TERM" in
linux|linux-*)
export TERM=linux-16color
;;
esac
export EDITOR=/bin/vi export EDITOR=/bin/vi
export SHELL=/bin/bash
export PATH="/usr/local/bin:/bin:/sbin:/usr/bin:/usr/sbin" export PATH="/usr/local/bin:/bin:/sbin:/usr/bin:/usr/sbin"
export PS1="[\h \t] \\$ " export PS1="[\h \t] \\$ "
export GNUPGHOME=/.gnupg export GNUPGHOME=/.gnupg
export XDG_RUNTIME_DIR=/tmp
source /etc/environment source /etc/environment
cd /root cd /root
clear clear

View File

@ -0,0 +1,36 @@
# Zero-based indexing is sure great in programming languages,
# but not so much in terminal multiplexers where that zero is
# all the way on the other side of the keyboard.
set-option -g base-index 1
set-option -g status on
set-option -g status-interval 1
# We should not have more than one session, but it's still possible.
# Therefore...
set-option -g status-left "[#S] "
# Just so we can use `-ag` properly later
set-option -g status-right ""
# The current power battery level
set-option -ag status-right '#(test -d /sys/class/power_supply/BAT0 && printf " [%%s%%%%]" "$(cat /sys/class/power_supply/BAT0/capacity)")'
# Current date and time, in case it's relevant, and has drifted
set-option -ag status-right " [%Y-%m-%d %H:%M:%S]"
# because cyan on black is cool, and pops out
set-option -g status-style "bg=color0 fg=color6"
set-option -g status-position bottom
# we don't have much screen space, let's limit what's displayed
set-window-option -g window-status-bell-style "bold"
set-window-option -g window-status-current-format "#I:#W"
set-window-option -g window-status-format "#I:#W"
# our "focused" window and pane is the brighter one
set-window-option -g window-status-style "fg=color6"
set-window-option -g window-status-current-style "fg=color14"
set-option -g pane-border-style "fg=color6"
set-option -g pane-active-border-style "fg=color14"
set-option -g message-style "fg=color6 bg=color0"

2
src/host/rootfs/init Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
exec /bin/init

View File

@ -0,0 +1,291 @@
#!/bin/bash
set -eu
COMMAND=($@)
LOCKFILE=/var/run/netvm.pid
QGA_SOCK_PATH=/var/run/netvm_qga.sock
QMP_SOCK_PATH=/var/run/netvm_qmp.sock
QGA_SOCK_FDS=false
qga_connect() {
[[ -v "QGA_SOCK_FDS_PID" ]] && return 0
coproc QGA_SOCK_FDS (
exec socat - UNIX-CONNECT:"${QGA_SOCK_PATH}"
) || return 1
QGA_SOCK_IN=${QGA_SOCK_FDS[0]}
QGA_SOCK_OUT=${QGA_SOCK_FDS[1]}
}
qga_execute() {
local cmd args
cmd="$1"
args="${2-}"
GA_RETURN=""
jq \
-ncM \
--arg cmd "$cmd" \
--argjson args "$args" \
'{"execute": $cmd, "arguments": $args}' \
>&$QGA_SOCK_OUT
local LINE
read -t 5 -r -u $QGA_SOCK_IN LINE || return 1
local ERROR=$(jq -r '.error.desc // empty' <<< "$LINE")
if [[ -n "$ERROR" ]]; then
echo "$ERROR" >&2
return 1
fi
GA_RETURN=$(jq -cM .return <<< "$LINE")
}
qga_flush() {
#Docs say this should work, but it just get parse errors
#LC_ALL= LC_CTYPE=en_US.UTF-8 printf '%b' "\uff" >&$QGA_SOCK_OUT
#read -t 5 -r -u $QGA_SOCK_IN LINE
until ! read -t 1 -r -u $QGA_SOCK_IN LINE; do sleep 0.1; done
}
qga() {
local cmd args
cmd="$1"
args="$2"
qga_connect
local id=$((1 + $RANDOM % 10000000))
qga_execute guest-sync "$(jq -ncM --argjson id "$id" '{"id": $id}')";
[[ "$(jq -re . <<< "$GA_RETURN")" = "$id" ]] || (echo "Error: guest-sync mismatch" >&2 && return 1)
unset GA_RETURN
qga_execute "$cmd" "$args"
echo "$GA_RETURN" 2>&1
local RETURN
kill -INT "$QGA_SOCK_FDS_PID" 2>/dev/null
wait "$QGA_SOCK_FDS_PID" || RETURN=$?
if [[ $RETURN != 130 ]]; then
return $RETURN
fi
}
function cmd_shell(){
qemu-system-x86_64 \
-m 512M \
--machine q35 \
-nographic \
-net none \
-cdrom /guest.img \
-boot order=d \
-device qemu-xhci \
-device virtio-serial \
-device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0
}
function cmd_start(){
[ ! -f "${LOCKFILE}" ] || { echo "Error: Netvm already running"; exit 1; }
local net_args=""
while read line; do
[ -n "$line" ] || break
echo "Preparing PCI network device: $line"
bus=$(echo $line | awk '{ print $1 }')
id=$(echo $line | awk '{ print $4 }' | tr ':' ' ')
echo "$id" > /sys/bus/pci/drivers/vfio-pci/new_id 2>&1 || :
net_args="$net_args -device vfio-pci,host=${bus}"
done <<< "$(lspci | grep 0200 )"
if [[ -n "$net_args" ]]; then
echo Y > /sys/module/vfio_iommu_type1/parameters/allow_unsafe_interrupts
fi
printf "Starting netvm...";
qemu-system-x86_64 \
-m 512M \
--machine q35 \
-nographic \
-serial none \
-monitor none \
-net none \
-cdrom /guest.img \
-boot order=d \
-chardev socket,path=${QGA_SOCK_PATH},server=on,wait=off,id=qga0 \
-qmp unix:${QMP_SOCK_PATH},server,nowait \
$net_args \
-device qemu-xhci,id=usb \
-device virtio-serial \
-device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0 \
>/dev/null 2>&1 &!
pid=$!
printf "done\n"
echo "$pid" > "${LOCKFILE}"
printf "QGA Socket starting... "
until [ -S "${QGA_SOCK_PATH}" ]; do sleep 1; done
printf "done\n"
printf "Connecting to QGA socket... "
until qga_connect; do sleep 1; done
printf "done\n"
[ -f "/proc/${pid}/status" ] || {
echo "Error: netvm exited unexpectedly";
rm "${LOCKFILE}"
exit 1;
}
local id;
local spin='-\|/'
local i=0;
while true; do
i=$(( (i+1) %4 ));
printf "\rConnecting to QGA agent... ${spin:$i:1}"
qga_execute guest-ping "{}" > /dev/null || continue && break
sleep 1
done;
printf "\rConnecting to guest agent... done\n"
printf "Flushing buffers..."
qga_flush
printf "done\n"
local i=0;
while true; do
i=$(( (i+1) %4 ));
printf "\rSyncing with guest... ${spin:$i:1}"
id=$((1 + $RANDOM % 10000000))
qga_execute guest-sync "$(jq -ncM --argjson id "$id" '{"id": $id}')" || continue
if [[ "$(jq -re . <<< "$GA_RETURN")" = "$id" ]]; then
printf "\rSyncing with guest... done\n"
break
fi;
sleep 1
done;
echo "NetVM boot complete"
}
function cmd_stop(){
kill $(cat "${LOCKFILE}")
rm "${LOCKFILE}"
}
function cmd_status(){
qga guest-get-host-name "{}" | jq -r '."host-name"'
pid=$(qga guest-exec '{"path": "uptime", "capture-output": true}' | jq -r '.pid')
out=$(qga guest-exec-status "$(jq -n --argjson pid "$pid" '{pid: $pid }')" \
| jq -r '."out-data"' \
| base64 -d \
)
echo $out
}
function cmd_push(){
local source="${COMMAND[1]}"
local dest="${COMMAND[2]}"
fo_request=$(jq -n --arg dest "$dest" '{"path": $dest, "mode": "w" }')
handle=$(qga guest-file-open "$fo_request")
bufb64=$(base64 "$source")
count=$(cat "$source" | wc -c)
fw_request=$(jq -n \
--argjson handle $handle \
--argjson count $count \
--arg bufb64 "$bufb64" \
'{handle: $handle, "buf-b64": $bufb64, count: $count }' \
)
qga guest-file-write "$fw_request"
fh_request=$(jq -n --argjson handle $handle '{handle: $handle}' )
qga guest-file-flush "$fh_request"
qga guest-file-close "$fh_request"
}
function cmd_pull(){
local source="${COMMAND[1]}"
local dest="${COMMAND[2]}"
fo_request=$(jq -n --arg source "$source" '{"path": $source}')
handle=$(qga guest-file-open "$fo_request")
fr_request=$(jq -n \
--argjson handle $handle \
'{handle: $handle, count: 48000000 }' \
)
out=$(qga guest-file-read "$fr_request")
echo $out | jq -r '."buf-b64"' | base64 -d > $dest
}
function cmd_run(){
[ -z "${COMMAND[1]}" ] && { echo "Error: missing command"; exit 1; }
[ -f "${LOCKFILE}" ] || { echo "Error: Netvm is not running"; exit 1; }
[ -S "${QGA_SOCK_PATH}" ] || { echo "Error: Netvm QGA socket is missing"; exit 1; }
local cmd="${COMMAND[1]}"
local args="${COMMAND[@]:2}"
local args_json="[]"
if [[ -n "$args" ]]; then
args_json=$(printf '%s\n' "$args" | jq -R . | jq -s .)
fi
local request
request=$( \
jq -n \
--arg path "$cmd" \
--argjson args "$args_json" \
'{
path: $path,
arg: $args,
"capture-output": true
}' \
)
pid=$(qga guest-exec "$request" | jq -r '.pid')
local exited=false
until [ "$exited" == "true" ]; do \
out=$(qga guest-exec-status "$(jq -n --argjson pid "$pid" '{pid: $pid }')" )
exited=$(echo $out | jq -r '.exited')
if $exited && jq -r 'has("out-data")' >/dev/null < <(echo $out); then
echo "$out" | jq -r '."out-data"' | base64 -d
break
fi
sleep 1
done
}
function cmd_attach() {
local id="${COMMAND[1]}"
IFS=":" read vendorid_hex productid_hex <<< "$id"
vendorid=$(printf "%d\n" "0x$vendorid_hex")
productid=$(printf "%d\n" "0x$productid_hex")
(
echo '{"execute":"qmp_capabilities"}'
echo '{"execute":"device_add","arguments":{"driver":"usb-host","bus":"usb.0","vendorid":'$vendorid',"productid":'$productid'}}'
) | socat - UNIX-CONNECT:/var/run/netvm_qmp.sock
}
cmd_usage() {
cat <<-_EOF
netvm
Control network vm headlessly via QMP protocol
Usage:
netvm start
Start headless network vm in the background
netvm stop
Stop headless network vm
netvm shell
Start interactive network vm in the foreground
netvm status
Get hostname and uptime from running network vm
netvm attach <vendorid:deviceid>
Hot-plug a USB device to network VM
netvm push <local-path> <remote-path>
Push a local file to the network VM
netvm pull <remote-path> <local-path>
Pull a file from the network VM
netvm run "<command>"
Run a command in network vm and get stdout
_EOF
}
case "$1" in
status) shift; cmd_status $@ ;;
start) shift; cmd_start $@ ;;
stop) shift; cmd_stop $@ ;;
shell) shift; cmd_shell $@ ;;
attach) shift; cmd_attach $@ ;;
push) shift; cmd_push $@ ;;
pull) shift; cmd_pull $@ ;;
run) shift; cmd_run $@ ;;
help) shift; cmd_usage $@ ;;
*) cmd_usage $@ ;;
esac

35
src/update.py Executable file
View File

@ -0,0 +1,35 @@
#!/usr/bin/env python3
from requests import Session
from fileinput import FileInput
target = "Containerfile"
source = "https://codeberg.org/stagex/stagex/raw/branch/main/digests/"
stages = ["core","user","bootstrap"]
digests = {}
for stage in stages:
response = Session().get(f"{source}{stage}.txt")
for line in response.iter_lines():
if not line:
continue
(digest, name) = line.decode("utf-8").split(" ")
print(digest, name)
digests[name] = digest
with FileInput(target, inplace=True, backup='.bak') as f:
for line in f:
if line.startswith("FROM stagex/"):
# NOTE: split by '@' in case a tag is not provided
# Matches:
# stagex/tag:version@sha256:hash
# stagex/tag@sha256:hash
# stagex/tag:version
# stagex/tag
name = line.split("/")[1].split(":")[0].split('@')[0]
if name not in digests:
for stage in stages:
if f"{stage}-{name}" in digests:
name = f"{stage}-{name}"
print(f"FROM stagex/{name}@sha256:{digests[name]} AS {name}")
else:
print(line,end='')