forked from public/airgap
Compare commits
100 Commits
stagex-rew
...
main
Author | SHA1 | Date |
---|---|---|
|
75acac32a9 | |
|
bdc971a931 | |
|
da8e9b915b | |
|
d7a0b6c5e5 | |
|
30fa06a5fb | |
|
82c0d8e55a | |
|
890e715e86 | |
|
133a7c9b5b | |
|
8722409004 | |
|
73ab8eae21 | |
|
72efb86b6f | |
|
723ba49cd3 | |
|
c608ad5ccd | |
|
06010bea59 | |
|
d1229c0f45 | |
|
24a254a914 | |
|
bb2f87d471 | |
|
b980eb3a97 | |
|
22469ca0b9 | |
|
3985d8ac19 | |
|
ea07569187 | |
|
18fa25b87e | |
|
b64d76b60d | |
|
f967c2db49 | |
|
a11d544723 | |
|
03621ded78 | |
|
e66f69ac46 | |
|
dca180550e | |
|
a5b695c2af | |
|
c350dec98f | |
|
acc7d0c416 | |
|
bd15a10d23 | |
|
9f93bebd6a | |
|
7f5d3a6275 | |
|
89ada7e795 | |
|
4fa6761729 | |
|
a224d4114e | |
|
5897a2fa5d | |
|
06de2117dc | |
|
15926d8ec3 | |
|
f23195d573 | |
|
08f367edc6 | |
|
110f64cf54 | |
|
ba16f1ea50 | |
|
aa5b04e8a0 | |
|
238ca2ce41 | |
|
dad6fe859b | |
|
5612c59b9a | |
|
e2a8d2b8cb | |
|
13bedb1e73 | |
|
3b039317c9 | |
|
b78da5c22a | |
|
f25615bc97 | |
|
bb76f61615 | |
|
934fb903dd | |
|
575967e5b4 | |
|
8db8dfc2a1 | |
|
e75ac046e0 | |
|
d480d0a809 | |
|
23cf93a8c2 | |
|
1f2abbaee9 | |
|
6fa36e4e74 | |
|
cac8bc947d | |
|
d8dd960dd5 | |
|
8308101a35 | |
|
1f26de8fc1 | |
|
4ad5be07db | |
|
657a3ff611 | |
|
ea623cc147 | |
|
95ccf80fe8 | |
|
5904a22c80 | |
|
485fc58bfb | |
|
e1c677bc06 | |
|
dc8515ea02 | |
|
3cb460b72e | |
|
f1c0f2f8b5 | |
|
1f2ce99275 | |
|
721ffad1f0 | |
|
74bf27bc66 | |
|
44e18ea21b | |
|
a2a3cce64c | |
|
f0270a2862 | |
|
24725ea630 | |
|
96ea9054f9 | |
|
4676d9f889 | |
|
d1707c48f1 | |
|
51ec4ca719 | |
|
f735b7e3af | |
|
c20dedcc35 | |
|
d737fce6ea | |
|
e886bc51fa | |
|
fbdb919b7f | |
|
df223e6deb | |
|
1578b3c76d | |
|
0af9d294a7 | |
|
dc60d53fca | |
|
16479807f1 | |
|
38689b24b2 | |
|
de0a962876 | |
|
7d9f87c976 |
|
@ -1 +1,2 @@
|
|||
dist/*.iso filter=lfs diff=lfs merge=lfs -text
|
||||
dist/airgap.iso filter=lfs diff=lfs merge=lfs -text
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
cache/
|
||||
out/
|
||||
out*/
|
||||
.*
|
||||
|
|
410
Containerfile
410
Containerfile
|
@ -1,69 +1,357 @@
|
|||
FROM stagex/busybox AS busybox
|
||||
FROM stagex/musl AS musl
|
||||
FROM stagex/xorriso AS xorriso
|
||||
FROM stagex/syslinux AS syslinux
|
||||
FROM stagex/cpio AS cpio
|
||||
FROM stagex/linux-airgap AS linux
|
||||
FROM stagex/mtools AS mtools
|
||||
FROM stagex/dosfstools AS dosfstools
|
||||
FROM stagex/user-alsa-lib@sha256:eeaee84f8012865bb33d68287bccfddc6fd04e9082687b8c31008dd07b8e07b8 AS user-alsa-lib
|
||||
FROM stagex/core-bash@sha256:ae47fcd4247bef0ca4af762a76cb8871a5c868472cab67eed829a55364a8f1fa AS core-bash
|
||||
FROM stagex/core-bc@sha256:03e1c729223e9d45f087660f65034b4f6fac91aefb94fb7ccbc85d1ab7e88c1d AS core-bc
|
||||
FROM stagex/core-busybox@sha256:cac5d773db1c69b832d022c469ccf5f52daf223b91166e6866d42d6983a3b374 AS core-busybox
|
||||
FROM stagex/user-ccid@sha256:313259fb6b059179ff69f4189c57d98b8d468ebf17f14c6f431d7001c8801e1c AS user-ccid
|
||||
FROM stagex/user-cpio@sha256:2695e1b42f93ec3ea0545e270f0fda4adca3cb48d0526da01954efae1bce95c4 AS user-cpio
|
||||
FROM stagex/core-curl@sha256:63a5963a4e7852b5482824953d18ea73c7d192fed654eb1236f8b97a6f67cbcc AS core-curl
|
||||
FROM stagex/user-dtc@sha256:3877063ca1068d48e0b92fcdf5083b707e009e96a6db4bd3536924c9f440cb08 AS user-dtc
|
||||
FROM stagex/user-eudev@sha256:709f6f949e93a3a91770b7323fd87eec52714677e4bed88954cadd60506cbce3 AS user-eudev
|
||||
FROM stagex/user-flashtools@sha256:f3524d889e9476acbe268b289a3e43f5766da9d3d999009b0bb8e6bddcd9dc5c AS user-flashtools
|
||||
FROM stagex/core-gcc@sha256:125bd6306e7f37e57d377d5a189c0e499388aff42b22cc79acee6097357c617f AS core-gcc
|
||||
FROM stagex/user-glib@sha256:41fb9409b0bea2421feaee788c88efcf2778f2008634dde00b50f2b6afd2ed11 AS user-glib
|
||||
FROM stagex/core-gmp@sha256:4387f9389ef656ef2305719ac1dbcc3d92631deb816da4c7101c0bdc75e57564 AS core-gmp
|
||||
FROM stagex/user-gpg@sha256:92946bb4143ecbd53999cd520fbcb958aecacbac7a85bd58a758be1b57086a9c AS user-gpg
|
||||
FROM stagex/user-grub@sha256:f3c9ff298c02ee3349496c3b5520079bbd115af0a347525410ba6a34170d4b4c AS user-grub
|
||||
FROM stagex/user-icepick@sha256:9d2e986a081fa7724dca2397dcd9b17fd2f6221d9c06d44f574625cb36038634 AS user-icepick
|
||||
FROM stagex/user-ipxe@sha256:b98dea039f0a14a614f035d848d9cfa8b9ad472e6dc24b2e3099f2f8ae209abe AS user-ipxe
|
||||
FROM stagex/user-jq@sha256:ced6213c21b570dde1077ef49966b64cbf83890859eff83f33c82620520b563e AS user-jq
|
||||
FROM stagex/user-keyfork@sha256:2075687c9a060f5eee89b6a4b5eecec6727afe3d241648b42be225170df0f8e0 AS user-keyfork
|
||||
FROM stagex/user-libaio@sha256:3e21cfd5dc07a7300546e4896a81628741c23c4728a68d36e0bb3d8a096f7742 AS user-libaio
|
||||
FROM stagex/user-libassuan@sha256:dea35799659be7b85e523312c55621007b1918ff3590631155ecf2c699ca470f AS user-libassuan
|
||||
FROM stagex/core-libffi@sha256:9acd18e59ca11fa727670725e69a976d96f85a00704dea6ad07870bff2bd4e8b AS core-libffi
|
||||
FROM stagex/user-libgcrypt@sha256:384f0e703afad6f8885ec77fb814ef182a08600a2032183d231fee5c048a7d2d AS user-libgcrypt
|
||||
FROM stagex/user-libgpg-error@sha256:6d7c09e3a7d055a6722910439c533f2babc8eda24b636bf4dfb2b29a3ed6327a AS user-libgpg-error
|
||||
FROM stagex/user-libksba@sha256:c165fb5b7949473cb00b0fe59add90663346b33c6c682309ca0fcccdcf78d569 AS user-libksba
|
||||
FROM stagex/user-libqrencode@sha256:e99d9a71dffb399dbe3af8c16c473f10368c3fb787d72623bdc42c7fa770a33a AS user-libqrencode
|
||||
FROM stagex/user-libseccomp@sha256:7a397b5261c24aa745fe9158499e0db1ba21df415354bbbe77c90a6a3fd4c517 AS user-libseccomp
|
||||
FROM stagex/user-libslirp@sha256:e72ebf587c366e1d0a9a42c74216dd2b9f560d52df3eb8148a2e31821415b082 AS user-libslirp
|
||||
FROM stagex/user-libtpms@sha256:3fde6f85f3ce637b3d7b98e4fc74c2c57d31adf9c9ca068b3826eb7ebf16f5ba AS user-libtpms
|
||||
FROM stagex/core-libunwind@sha256:4f3ead61255c1e58e7dc43a33043f297f8730ec88e068a4460e5fff09e503781 AS core-libunwind
|
||||
FROM stagex/user-libusb@sha256:53d499555164f12d9e87118a6d44e1d07f0b1cc9081a29eb66975662be818a00 AS user-libusb
|
||||
FROM stagex/user-libzbar@sha256:8b4ec291f772a10f372c538180f889a46837f2dd97756d1949c5c86111241fa9 AS user-libzbar
|
||||
FROM stagex/core-libzstd@sha256:35ae8f0433cf1472f8fb25e74dc631723e9f458ca3e9544976beb724690adea8 AS core-libzstd
|
||||
FROM stagex/user-lzo@sha256:9d141a7686fbb027366df80d4f254fb13f4c4524ba4d5cff6ea176b0b4c36cd5 AS user-lzo
|
||||
FROM stagex/user-mtools@sha256:023169be123693e326d2fd97739fe0efa19638ce616cbcc52476e6f14f0a83cc AS user-mtools
|
||||
FROM stagex/core-musl@sha256:d5f86324920cfc7fc34f0163502784b73161543ba0a312030a3ddff3ef8ab2f8 AS core-musl
|
||||
FROM stagex/user-nettle@sha256:249bec1a4273f6461b39ef849d1d8b4ec2d4a3693930f9147cee6c37eef0794a AS user-nettle
|
||||
FROM stagex/user-npth@sha256:6ac9a90ca714ba01911c1f617553a5b23b96e9e37ec4a21e5ba132c4886a70e9 AS user-npth
|
||||
FROM stagex/user-numactl@sha256:4046b643293cf9e82f1d29e92c61f0b12210b65987711ddd7c6813f27f3c1bfd AS user-numactl
|
||||
FROM stagex/user-openpgp-card-tools@sha256:369c13ba0a772b1aef31321c0ebbb2a6fcd512491ace003e48c6f18f258905cc AS user-openpgp-card-tools
|
||||
FROM stagex/user-opensc@sha256:f8a1b5d07b6b594b964b63a2572fd10b44e79c3699efb97dfefc2f1dde054a6c AS user-opensc
|
||||
FROM stagex/core-openssl@sha256:8670a22fb76965f31bda1b61cd75ae39a96e1008deffe289a5d94ee4337b1cb2 AS core-openssl
|
||||
FROM stagex/user-pcsc-lite@sha256:0f06c2e73fabc6f9484bb39362d4084a45ffe88c862764813a62a75840b10cfc AS user-pcsc-lite
|
||||
FROM stagex/user-pcsc-tools@sha256:366867b9c29664264224db7651b710cd70761b67c41ce9c27b9d2829e18b5a30 AS user-pcsc-tools
|
||||
FROM stagex/user-qemu@sha256:45b6d58b55a4c7d616da985d29482f2892540d815a90ed175e53b1c1b172497e AS user-qemu
|
||||
FROM stagex/user-canokey-qemu@sha256:3f949f099194d2b721914d9d308c699818f83833b07db1d2e504ee16bfdfa348 AS user-canokey-qemu
|
||||
FROM stagex/user-sdtool@sha256:f4be5c2fe87fa3dd8742f91be5a368b6833ceb7156d33192e5339869629aa06a AS user-sdtool
|
||||
FROM stagex/user-seabios@sha256:4adf4c3f70a6c69cb1c925a832363547cfb73ef5a7d75ff65885624916aace90 AS user-seabios
|
||||
FROM stagex/user-sops@sha256:72b09ff439f422889af815f19a223b48b3b3fd0701d312a413069cbabcad7a12 AS user-sops
|
||||
FROM stagex/core-zlib@sha256:b35b643642153b1620093cfe2963f5fa8e4d194fb2344a5786da5717018976c2 AS core-zlib
|
||||
FROM stagex/user-sequoia-sq@sha256:b7197adb937e3ee0fc8e8edc041acb836da9b2958cbe4bb3b1797b73b50205f7 AS user-sequoia-sq
|
||||
FROM stagex/user-sequoia-sq-wot@sha256:7e914c221d65a4cda9683591082e9f5c70d8d31d6a415c1b98e75f4d89f985c5 AS user-sequoia-sq-wot
|
||||
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 scratch AS base
|
||||
COPY --from=busybox . /
|
||||
COPY --from=musl . /
|
||||
COPY --from=xorriso . /
|
||||
COPY --from=cpio . /
|
||||
COPY --from=mtools . /
|
||||
COPY --from=linux . /
|
||||
COPY --from=dosfstools . /
|
||||
COPY --from=syslinux . /
|
||||
ARG VERSION development
|
||||
ARG GIT_TIMESTAMP null
|
||||
ARG GIT_AUTHOR null
|
||||
ARG GIT_REF null
|
||||
ARG GIT_PUBKEY null
|
||||
COPY --from=core-busybox . /
|
||||
COPY --from=core-musl . /
|
||||
COPY --from=core-xz . /
|
||||
COPY --from=user-xorriso . /
|
||||
COPY --from=user-cpio . /
|
||||
COPY --from=user-mtools . /
|
||||
COPY --from=user-grub . /
|
||||
|
||||
FROM base AS build
|
||||
COPY --from=linux /bzImage /iso/boot/bzImage
|
||||
COPY --from=stagex/busybox . initramfs
|
||||
COPY --chmod=0755 <<-EOF initramfs/init
|
||||
#!/bin/sh
|
||||
/bin/sh
|
||||
EOF
|
||||
RUN cd initramfs && find . | cpio -o -H newc | gzip -9 > /iso/boot/init.gz
|
||||
COPY <<-EOF iso/isolinux/isolinux.cfg
|
||||
DEFAULT linux
|
||||
LABEL linux
|
||||
KERNEL boot/bzImage
|
||||
APPEND initrd=boot/init.gz
|
||||
EOF
|
||||
COPY --from=syslinux /usr/share/syslinux/isolinux.bin iso/isolinux/
|
||||
COPY --from=syslinux /usr/share/syslinux/ldlinux.c32 iso/isolinux/
|
||||
FROM base AS dev
|
||||
COPY --from=core-gcc . /
|
||||
COPY --from=core-zlib . /
|
||||
COPY --from=user-glib . /
|
||||
COPY --from=user-alsa-lib . /
|
||||
COPY --from=user-lzo . /
|
||||
COPY --from=user-dtc . /
|
||||
COPY --from=user-numactl . /
|
||||
COPY --from=user-libaio . /
|
||||
COPY --from=user-libseccomp . /
|
||||
COPY --from=core-libffi . /
|
||||
COPY --from=core-libzstd . /
|
||||
COPY --from=user-libslirp . /
|
||||
COPY --from=user-seabios . /
|
||||
COPY --from=user-ipxe . /
|
||||
COPY --from=user-qemu . /
|
||||
COPY --from=user-canokey-qemu . /
|
||||
COPY --from=user-swtpm . /
|
||||
COPY --from=core-openssl . /
|
||||
COPY --from=core-curl . /
|
||||
COPY --from=user-libtpms . /
|
||||
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
|
||||
mkdir -p iso/efi
|
||||
truncate -s $((10796+128+128))k iso/efi/esp.img
|
||||
mkfs.fat -F 16 -f 1 -M 0xF0 -r 112 -R 1 iso/efi/esp.img
|
||||
mmd -i iso/efi/esp.img ::boot
|
||||
mcopy -i iso/efi/esp.img iso/boot/bzImage ::boot/bzImage
|
||||
mcopy -i iso/efi/esp.img iso/boot/init.gz ::boot/init.gz
|
||||
mmd -i iso/efi/esp.img ::syslinux
|
||||
mcopy -i iso/efi/esp.img iso/isolinux/isolinux.cfg ::syslinux/syslinux.cfg
|
||||
mcopy -i iso/efi/esp.img /usr/share/syslinux/efi64/ldlinux.e64 ::syslinux/ldlinux.e64
|
||||
mmd -i iso/efi/esp.img ::efi
|
||||
mmd -i iso/efi/esp.img ::efi/boot
|
||||
mcopy -i iso/efi/esp.img /usr/share/syslinux/efi64/syslinux.efi ::efi/boot/boot64.efi
|
||||
ls -Rlah iso
|
||||
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
|
||||
COPY --from=user-linux-airgap /bzImage iso/boot/vmlinuz
|
||||
COPY --from=build-guest /guest.img initramfs/
|
||||
COPY --from=core-busybox . initramfs
|
||||
COPY --from=user-eudev . initramfs
|
||||
COPY --from=core-musl . initramfs
|
||||
COPY --from=core-zlib . initramfs
|
||||
COPY --from=user-npth . initramfs
|
||||
COPY --from=user-libksba . initramfs
|
||||
COPY --from=user-libgpg-error . initramfs
|
||||
COPY --from=user-libassuan . initramfs
|
||||
COPY --from=user-libgcrypt . initramfs
|
||||
COPY --from=core-bash . initramfs
|
||||
COPY --from=user-gpg . initramfs
|
||||
COPY --from=user-jq . initramfs
|
||||
COPY --from=user-yq . initramfs
|
||||
COPY --from=core-bc . initramfs
|
||||
COPY --from=user-flashtools . initramfs
|
||||
COPY --from=core-curl . initramfs
|
||||
COPY --from=user-tpm2-tools . initramfs
|
||||
COPY --from=user-tpm2-tss . initramfs
|
||||
COPY --from=core-openssl . initramfs
|
||||
COPY --from=user-libusb . initramfs
|
||||
COPY --from=user-ccid . initramfs
|
||||
COPY --from=user-pcsc-lite . initramfs
|
||||
COPY --from=user-pcsc-tools . initramfs
|
||||
COPY --from=user-libqrencode . initramfs
|
||||
COPY --from=core-gmp . initramfs
|
||||
COPY --from=core-libunwind . initramfs
|
||||
COPY --from=user-nettle . initramfs
|
||||
COPY --from=user-opensc . initramfs
|
||||
COPY --from=user-util-linux . initramfs
|
||||
COPY --from=user-sops . initramfs
|
||||
COPY --from=core-gcc /usr/lib/. initramfs/usr/lib/
|
||||
COPY --from=core-sqlite3 . 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 src/host/rootfs/ initramfs
|
||||
COPY <<-EOF initramfs/etc/environment
|
||||
export VERSION="$VERSION"
|
||||
export GIT_TIMESTAMP="$GIT_TIMESTAMP"
|
||||
export GIT_AUTHOR="$GIT_AUTHOR"
|
||||
export GIT_REF="$GIT_REF"
|
||||
export GIT_PUBKEY="$GIT_PUBKEY"
|
||||
EOF
|
||||
RUN <<-EOF
|
||||
set -eux
|
||||
cd initramfs
|
||||
find . -exec touch -hcd "@0" "{}" +
|
||||
find . -print0 \
|
||||
| sort -z \
|
||||
| cpio \
|
||||
--null \
|
||||
--create \
|
||||
--verbose \
|
||||
--reproducible \
|
||||
--format=newc \
|
||||
| gzip --best \
|
||||
> ../iso/boot/initramfs
|
||||
EOF
|
||||
|
||||
## Grub (EFI Boot)
|
||||
COPY src/host/config/grub.cfg iso/boot/grub/grub.cfg
|
||||
COPY src/host/config/grub_early.cfg grub_early.cfg
|
||||
RUN <<-EOF
|
||||
set -eux
|
||||
mkdir -p efi/boot
|
||||
grub-mkimage \
|
||||
--config="grub_early.cfg" \
|
||||
--prefix="/boot/grub" \
|
||||
--output="efi/boot/bootx64.efi" \
|
||||
--format="x86_64-efi" \
|
||||
--compression="xz" \
|
||||
all_video \
|
||||
disk \
|
||||
part_gpt \
|
||||
part_msdos \
|
||||
linux \
|
||||
normal \
|
||||
configfile \
|
||||
search \
|
||||
search_label \
|
||||
efi_gop \
|
||||
fat \
|
||||
iso9660 \
|
||||
gzio \
|
||||
serial \
|
||||
terminal
|
||||
find efi -exec touch -hcd "@0" "{}" +
|
||||
mformat -i iso/boot/grub/efi.img -C -f 1440 -N 0 ::
|
||||
mcopy -i iso/boot/grub/efi.img -ms efi ::
|
||||
touch -md "@0" iso/boot/grub/efi.img
|
||||
EOF
|
||||
|
||||
## Syslinux (BIOS Boot)
|
||||
COPY src/host/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
|
||||
dd if=/dev/zero bs=1M count=10 >> user.img
|
||||
mformat -v user -i user.img -N 0 ::
|
||||
find iso -exec touch -hcd "@0" "{}" +
|
||||
xorrisofs \
|
||||
-output airgap.iso \
|
||||
-full-iso9660-filenames \
|
||||
-joliet \
|
||||
-rational-rock \
|
||||
-sysid LINUX \
|
||||
-volid "airgap" \
|
||||
-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 \
|
||||
-eltorito-alt-boot \
|
||||
-e boot/grub/efi.img \
|
||||
-no-emul-boot \
|
||||
-isohybrid-gpt-basdat \
|
||||
-follow-links \
|
||||
-append_partition 3 0xb user.img \
|
||||
iso/
|
||||
EOF
|
||||
|
||||
## Minimal Autorun SD card image
|
||||
COPY sdcard sdcard
|
||||
RUN <<-EOF
|
||||
set -eux
|
||||
dd if=/dev/zero of=sdcard.img bs=1M count=32
|
||||
mformat -v external -i sdcard.img ::
|
||||
mcopy -i sdcard.img -s sdcard/* ::
|
||||
EOF
|
||||
FROM build AS install
|
||||
RUN xorriso \
|
||||
-as mkisofs \
|
||||
-output airgap.iso \
|
||||
-eltorito-boot isolinux/isolinux.bin \
|
||||
-no-emul-boot \
|
||||
-boot-load-size 4 \
|
||||
-boot-info-table \
|
||||
-eltorito-alt-boot \
|
||||
-eltorito-platform efi \
|
||||
-eltorito-boot efi/esp.img \
|
||||
-no-emul-boot \
|
||||
-eltorito-catalog isolinux/boot.cat \
|
||||
iso
|
||||
#RUN isohybrid airgap.iso
|
||||
|
||||
FROM scratch AS package
|
||||
COPY --from=install /airgap.iso /
|
||||
COPY --from=build /sdcard.img /
|
||||
COPY --from=build /airgap.iso /
|
||||
|
|
157
Makefile
157
Makefile
|
@ -1,21 +1,150 @@
|
|||
VERSION := development
|
||||
GIT_REF := $(shell git log -1 --format=%H)
|
||||
GIT_AUTHOR := $(shell git log -1 --format=%an)
|
||||
GIT_PUBKEY := $(shell git log -1 --format=%GK)
|
||||
GIT_TIMESTAMP := $(shell git log -1 --format=%cd --date=iso)
|
||||
EFI := false
|
||||
,:=,
|
||||
export
|
||||
|
||||
## Use env vars from latest release when reproducing
|
||||
ifdef REPRODUCE
|
||||
include dist/release.env
|
||||
export
|
||||
endif
|
||||
|
||||
## Prevents use of caching when building docker image
|
||||
ifdef NOCACHE
|
||||
NO_CACHE := --no-cache
|
||||
endif
|
||||
|
||||
.DEFAULT_GOAL :=
|
||||
.PHONY: default
|
||||
default: \
|
||||
$(OUT_DIR)/airgap.iso
|
||||
out/release.env \
|
||||
out/manifest.txt \
|
||||
out/airgap.iso
|
||||
|
||||
.PHONY: vm
|
||||
vm:
|
||||
$(call toolchain,$(USER)," \
|
||||
qemu-system-i386 \
|
||||
-M pc \
|
||||
-nographic \
|
||||
-cdrom "$(OUT_DIR)/airgap.iso"; \
|
||||
")
|
||||
## Primary targets
|
||||
|
||||
$(OUT_DIR)/airgap.iso: \
|
||||
$(FETCH_DIR)/buildroot
|
||||
out/airgap.iso: Containerfile $(shell git ls-files rootfs)
|
||||
SOURCE_DATE_EPOCH=1 \
|
||||
docker build \
|
||||
--progress=plain \
|
||||
--output type=oci,tar=false,force-compression=true,name=airgap,dest=airgap \
|
||||
. \
|
||||
-f Containerfile
|
||||
--output type=local,rewrite-timestamp=true,dest=out \
|
||||
--build-arg SOURCE_DATE_EPOCH=1 \
|
||||
--build-arg VERSION="$(VERSION)" \
|
||||
--build-arg GIT_REF="$(GIT_REF)" \
|
||||
--build-arg GIT_AUTHOR="$(GIT_AUTHOR)" \
|
||||
--build-arg GIT_PUBKEY="$(GIT_PUBKEY)" \
|
||||
--build-arg GIT_TIMESTAMP="$(GIT_TIMESTAMP)" \
|
||||
$(NO_CACHE) \
|
||||
-f Containerfile \
|
||||
.
|
||||
|
||||
## Development Targets
|
||||
|
||||
out/dev-shell.digest: Containerfile | out
|
||||
docker build --target dev -f Containerfile -q . > $@
|
||||
|
||||
.PHONY: shell
|
||||
shell: out/dev-shell.digest
|
||||
docker run -it $(shell cat $<) /bin/sh
|
||||
|
||||
.PHONY: vm
|
||||
vm: out/dev-shell.digest out/airgap.iso out/sdcard.img
|
||||
docker run -it -v ./out:/out $(shell cat $<) sh -c "\
|
||||
swtpm socket \
|
||||
--tpmstate dir=. \
|
||||
--ctrl type=unixio,path=vtpm-sock \
|
||||
--tpm2 & \
|
||||
qemu-system-x86_64 \
|
||||
-m 4G \
|
||||
-machine q35,kernel-irqchip=split \
|
||||
-chardev socket,id=chrtpm,path=vtpm-sock \
|
||||
-usb -device canokey,file=/out/canokey-file \
|
||||
-tpmdev emulator,id=tpm0,chardev=chrtpm \
|
||||
-device tpm-tis,tpmdev=tpm0 \
|
||||
-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) \
|
||||
-nographic; \
|
||||
"
|
||||
|
||||
## Release, Signing, Verification, and Reproduction Targets
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf out
|
||||
|
||||
.PHONY: update
|
||||
update:
|
||||
python3 src/update.py
|
||||
|
||||
.PHONY: release
|
||||
release: clean
|
||||
$(MAKE) NOCACHE=1 VERSION=$(VERSION)
|
||||
rm -rf dist/*
|
||||
cp -R out/release.env out/airgap.iso out/manifest.txt dist/
|
||||
|
||||
.PHONY: sign
|
||||
sign:
|
||||
set -e; \
|
||||
git config --get user.signingkey 2>&1 >/dev/null || { \
|
||||
echo "Error: git user.signingkey is not defined"; \
|
||||
exit 1; \
|
||||
}; \
|
||||
fingerprint=$$(\
|
||||
git config --get user.signingkey \
|
||||
| sed 's/.*\([A-Z0-9]\{16\}\).*/\1/g' \
|
||||
); \
|
||||
gpg --armor \
|
||||
--detach-sig \
|
||||
--output dist/manifest.$${fingerprint}.asc \
|
||||
dist/manifest.txt
|
||||
|
||||
.PHONY: verify
|
||||
verify: | dist/manifest.txt
|
||||
set -e; \
|
||||
for file in dist/manifest.*.asc; do \
|
||||
echo "\nVerifying: $${file}\n"; \
|
||||
gpg --verify $${file} dist/manifest.txt; \
|
||||
done;
|
||||
|
||||
.PHONY: reproduce
|
||||
reproduce: clean | out
|
||||
$(MAKE) REPRODUCE=true NOCACHE=1
|
||||
diff -q out/manifest.txt dist/manifest.txt;
|
||||
|
||||
out:
|
||||
mkdir -p $@
|
||||
|
||||
out/release.env: $(shell git ls-files) | out
|
||||
echo 'VERSION=$(VERSION)' > out/release.env
|
||||
echo 'GIT_REF=$(GIT_REF)' >> out/release.env
|
||||
echo 'GIT_AUTHOR=$(GIT_AUTHOR)' >> out/release.env
|
||||
echo 'GIT_PUBKEY=$(GIT_PUBKEY)' >> out/release.env
|
||||
echo 'GIT_TIMESTAMP=$(GIT_TIMESTAMP)' >> out/release.env
|
||||
|
||||
out/manifest.txt: out/airgap.iso out/release.env | out
|
||||
openssl sha256 -r \
|
||||
out/airgap.iso \
|
||||
out/release.env \
|
||||
| sed -e 's/ \*out\// /g' -e 's/ \.\// /g' \
|
||||
> $@
|
||||
|
|
100
README.md
100
README.md
|
@ -1,24 +1,26 @@
|
|||
# AirgapOS #
|
||||
|
||||
<https://github.com/distrust-foundation/airgap>
|
||||
<https://git.distrust.co/public/airgap>
|
||||
|
||||
## About ##
|
||||
|
||||
A live buildroot based Liux distribution designed for managing secrets offline.
|
||||
A full-source-bootstrapped, deterministic, minimal, immutable, and offline,
|
||||
workstation linux distribution designed for creating and managing secrets
|
||||
offline.
|
||||
|
||||
Built for those of us that want to be -really- sure our most important secrets
|
||||
are managed in a clean environment with an "air gap" between us and the
|
||||
internet with high integrity on the supply chain of the firmware and OS used.
|
||||
|
||||
## Uses ##
|
||||
* Generate GPG keychain
|
||||
* Generate PGP keychain
|
||||
* Store/Restore gpg keychain to security token such as a Yubikey or Nitrokey
|
||||
* Signing cryptocurrency transactions
|
||||
* Generate/backup BIP39 universal cryptocurrency wallet seed
|
||||
* Store/Restore BIP39 seed to a hardware wallet such as a Trezor or Ledger
|
||||
|
||||
## Features ##
|
||||
* Determinsitic iso generation for multi-party code->binary verification
|
||||
* Deterministic iso generation for multi-party code->binary verification
|
||||
* Small footprint (< 100MB)
|
||||
* Immutable and Diskless: runs from initramfs
|
||||
* Network support and most drivers removed to minimize exfiltration vectors
|
||||
|
@ -27,37 +29,54 @@ internet with high integrity on the supply chain of the firmware and OS used.
|
|||
|
||||
### Software ###
|
||||
|
||||
* docker 18+
|
||||
* docker 26+
|
||||
|
||||
### Hardware ###
|
||||
|
||||
* Recommended: PC running coreboot-heads
|
||||
* Allows for signed builds, and verification of signed sd card payloads
|
||||
* Ensure any Wifi/Disk/Bluetooth/Audio devices are disabled/removed
|
||||
* Supported remote attestation key (Librem Key, Nitrokey, etc)
|
||||
* Supported GPG smartcard device (Yubikey, Ledger, Trezor, Librem Key, etc)
|
||||
* x86_64 PC or laptop
|
||||
* linuxboot/heads firmware supported and recommended for multi-use machine
|
||||
* Allows for signed builds, and verification of signed sd card payloads
|
||||
* Ensure any Wifi/Disk/Bluetooth/Audio devices are disabled/removed
|
||||
* Blank flash drive
|
||||
* Blank SD card
|
||||
|
||||
## Build ##
|
||||
|
||||
### Update git submodules
|
||||
|
||||
```
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
### Build a new release
|
||||
|
||||
```
|
||||
make release
|
||||
```
|
||||
```
|
||||
make release
|
||||
```
|
||||
|
||||
### Reproduce an existing release
|
||||
|
||||
```
|
||||
make attest
|
||||
```
|
||||
```
|
||||
make reproduce
|
||||
```
|
||||
|
||||
### Sign an existing release
|
||||
|
||||
```
|
||||
make sign
|
||||
```
|
||||
```
|
||||
make sign
|
||||
```
|
||||
|
||||
## Provisioning ##
|
||||
|
||||
1. Write airgap.iso to CD-ROM or SD Card
|
||||
a. `dd if=out/airgap.iso of=/dev/sda bs=1M conv=sync status=progress`
|
||||
b. `cdrecord out/airgap.iso`
|
||||
|
||||
2. Verify media still produces expected hash
|
||||
```
|
||||
sha256sum out/airgap.iso
|
||||
head -c $(stat -c '%s' airgap.iso) /dev/sda | sha256sum
|
||||
```
|
||||
|
||||
## Setup ##
|
||||
|
||||
|
@ -109,3 +128,46 @@ make vm
|
|||
```
|
||||
make shell
|
||||
```
|
||||
|
||||
## Hardware Compatibility ##
|
||||
|
||||
### Tested Models
|
||||
|
||||
* Purism Librem 14
|
||||
|
||||
* HP 13" Intel Celeron - 4GB Memory - 64GB eMMC, HP 14-dq0052dx, SKU: 6499749, UPC: 196548430192, DCS: 6.768.5321, ~USD $179.99
|
||||
|
||||
* Lenovo 14" Flex 5i FHD Touchscreen 2-in-1 Laptop - Intel Core i3-1215U - 8GB Memory - Intel UHD Graphics, SKU: 6571565, ~USD $379.99
|
||||
|
||||
### Disabling Secure Boot
|
||||
|
||||
AirgapOS can't be booted using secure boot. Therefore it has to be disabled. Alternative systems like Heads may be used.
|
||||
|
||||
#### Instructions to Disable Secure Boot in BIOS
|
||||
|
||||
1. Restart your computer
|
||||
|
||||
2. **Enter BIOS/UEFI Setup**:
|
||||
- As your computer starts up, press the appropriate key to enter the BIOS/UEFI setup. Common keys include:
|
||||
- **F2** (Dell, Acer, Lenovo)
|
||||
- **Delete** (ASUS, MSI)
|
||||
- **F10** (HP)
|
||||
- **Esc** (Some systems)
|
||||
- You may see a prompt on the screen indicating which key to press
|
||||
|
||||
3. **Navigate to the Secure Boot Option**:
|
||||
- Once in the BIOS/UEFI setup, use the arrow keys to navigate through the menus. Look for a tab or section labeled **"Boot," "Security,"** or **"Authentication."**
|
||||
- The exact location of the Secure Boot option can vary, so you may need to explore a bit
|
||||
|
||||
4. **Locate Secure Boot**:
|
||||
- Find the **Secure Boot** option within the selected menu. It may be listed as **"Secure Boot Control"** or simply **"Secure Boot."**
|
||||
|
||||
5. **Disable Secure Boot**:
|
||||
- Select the Secure Boot option and change its setting to **Disabled**. This is usually done by pressing **Enter** and then selecting **Disabled** from the options.
|
||||
|
||||
6. **Save Changes and Exit**:
|
||||
- After disabling Secure Boot, navigate to the **Exit** tab or section.
|
||||
- Choose the option to **Save Changes and Exit**. Confirm any prompts that appear to save your changes.
|
||||
|
||||
7. **Reboot Your Computer**:
|
||||
- Your computer will restart. Secure Boot should now be disabled.
|
Binary file not shown.
|
@ -0,0 +1,16 @@
|
|||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCgAdFiEEiII6deyqeGsP84sUjkAUeKP773IFAmglbi8ACgkQjkAUeKP7
|
||||
73I7Rg/+MQ4yDhcnwBBtlN651Kcou5Z7EhAY5S9stg69yfqWL0MacNGRnEmNHYix
|
||||
0J39xeYvP/dSsXYWgW04f0w4FS+msuqK9ML3YbB3Ei7GH4c+Bizhoj415chSMOlo
|
||||
R97Gz2V+SZ83Ph51+ORA4DUZ3/PIoXfv5syTKmcrioUP9XhCou61TCqN4fMGgXpq
|
||||
5F4awAZRrTtw+67dcEOmSQ7+TbNsMhJIei5Bg8FdPNS2VuMuUGTMrwsL7FBXIg1j
|
||||
2J4tXUhZvLz7x3i0nuVlELfd6w1dDHW77e9rCmifGd4QRN+gqUGoOjp93HgnsUrJ
|
||||
ASY0BKWfHeHcxpT2qtUuKZuBBjtGkGM9YQSUXYvuzhJp9XEZb9GHBMVo1TvX0sZr
|
||||
jWyUVSBlcZuOlG5iGMF8D44nJOX4QikPuGLOJxmG2pOiFvh32qsTA50HV6/BEzZr
|
||||
s5zm1IgsdF1SDPrxiqRPjZyvZYcF2kZtqxkzXEJzdPwcqCR9VXHo7InU7OrSg1D0
|
||||
T/4wvsz50gsck1UvhEKukBVaWBmyzjHdnUPelOSbiUfn8xSKeL9RGGktV6tF3bUq
|
||||
M1yBYp8Bpm3TteqGgeaUjJ5xSRGjynJrlFm+6YSJhf4AOVaex/Tysdlkg8ylQZLn
|
||||
IrfZXgpmazBLKHtxQKyr4znWqN+DptMt6W7kPCwejQjiN5WH494=
|
||||
=BFLb
|
||||
-----END PGP SIGNATURE-----
|
|
@ -0,0 +1,2 @@
|
|||
cafe1d794f8bb10e652da130e7f3f2f1a13e0ee89f54fdb6385b6fb191a22221 airgap.iso
|
||||
eed8667982e86e41f2ebd1331f408e93ac5ef2a574ee23e7635cbb23506aec73 release.env
|
|
@ -0,0 +1,5 @@
|
|||
VERSION=development
|
||||
GIT_REF=bdc971a931bf9fc51395beb5afd328d8b493a801
|
||||
GIT_AUTHOR=Anton Livaja
|
||||
GIT_PUBKEY=44A86CFF1FDF0E85
|
||||
GIT_TIMESTAMP=2025-05-14 19:12:21 -0700
|
|
@ -1 +0,0 @@
|
|||
pinentry-mode loopback
|
|
@ -1,12 +0,0 @@
|
|||
KERNEL!="sd[a-z][0-9]", GOTO="sd_cards_auto_mount_end"
|
||||
|
||||
# Global mount options
|
||||
ACTION=="add", ENV{mount_options}="relatime"
|
||||
|
||||
# Filesystem specific options
|
||||
ACTION=="add", IMPORT{program}="/sbin/blkid -o udev -p %N"
|
||||
ACTION=="add", ENV{ID_FS_TYPE}=="vfat|ntfs", ENV{mount_options}="$env{mount_options},utf8,flush,user,umask=0000"
|
||||
ACTION=="add", RUN+="/bin/mkdir -p /media/sd-%k", RUN+="/bin/mount -o $env{mount_options} /dev/%k /media/sd-%k"
|
||||
ACTION=="add", RUN+="/usr/local/bin/autorun /media/sd-%k"
|
||||
ACTION=="remove", RUN+="/bin/umount -l /media/sd-%k", RUN+="/bin/rmdir /media/sd-%k"
|
||||
LABEL="sd_cards_auto_mount_end"
|
|
@ -1,18 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
source /etc/profile
|
||||
|
||||
folder=${1?}
|
||||
|
||||
if [ -f "${folder}/autorun.sh.asc" ]; then
|
||||
echo "" >/dev/console
|
||||
echo "++ Autorun: Found ${folder}/autorun.sh" >/dev/console;
|
||||
gpg --verify "${folder}/autorun.sh.asc" >/dev/null 2>&1 || {
|
||||
echo "!! Autorun: Verification Failed for ${folder}/autorun.sh" \
|
||||
>/dev/console;
|
||||
exit 1;
|
||||
}
|
||||
echo "++ Autorun: Verified ${folder}/autorun.sh" >/dev/console
|
||||
echo "** Autorun: Executing ${folder}/autorun.sh" >/dev/console
|
||||
/bin/bash "${folder}/autorun.sh" >/dev/console
|
||||
fi
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "Autorun.sh executed"
|
|
@ -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
|
|
@ -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:
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,2 @@
|
|||
nameserver 1.1.1.1
|
||||
nameserver 8.8.8.8
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
exec /bin/init
|
|
@ -0,0 +1,5 @@
|
|||
set timeout=1
|
||||
menuentry "Linux Airgap" {
|
||||
linux /boot/vmlinuz init=/init console=ttyS0 console=tty0 ro loglevel=3
|
||||
initrd /boot/initramfs
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
search --no-floppy --set=root --label "airgap"
|
||||
set prefix=($root)/boot/grub
|
|
@ -0,0 +1,8 @@
|
|||
TIMEOUT 2
|
||||
PROMPT -1
|
||||
DEFAULT Airgap
|
||||
LABEL Airgap
|
||||
MENU LABEL Linux Airgap
|
||||
KERNEL /boot/vmlinuz
|
||||
INITRD /boot/initramfs
|
||||
APPEND init=/init console=ttyS0 console=tty0 ro
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/sh
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
/usr/sbin/pcscd -d || { echo "FAIL"; exit 1; }
|
||||
killall pcscd
|
||||
/usr/sbin/pcscd -d || { echo "FAIL"; exit 1; }
|
||||
echo "done"
|
||||
;;
|
||||
stop)
|
||||
# Stop execution of events
|
||||
killall pcscd
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -1,11 +1,5 @@
|
|||
# /etc/inittab
|
||||
#
|
||||
# Copyright (C) 2001 Erik Andersen <andersen@codepoet.org>
|
||||
#
|
||||
# Note: BusyBox init doesn't support runlevels. The runlevels field is
|
||||
# completely ignored by BusyBox init. If you want runlevels, use
|
||||
# sysvinit.
|
||||
#
|
||||
|
||||
# Format for each entry: <id>:<runlevels>:<action>:<process>
|
||||
#
|
||||
# id == tty to run on, or empty for /dev/console
|
||||
|
@ -14,27 +8,26 @@
|
|||
# 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 proc proc /proc
|
||||
::sysinit:/bin/mount -o remount,rw /
|
||||
::sysinit:/bin/mkdir -p /dev/pts /dev/shm
|
||||
::sysinit:/bin/mount -a
|
||||
::sysinit:/sbin/swapon -a
|
||||
::sysinit:/bin/mkdir /var/log
|
||||
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
|
||||
::sysinit:/bin/hostname -F /etc/hostname
|
||||
# now run any rc scripts
|
||||
::sysinit:/etc/init.d/rcS
|
||||
|
||||
# Put a getty on the serial port
|
||||
#console::respawn:/sbin/getty -L console 0 vt100 # GENERIC_SERIAL
|
||||
::respawn:-/bin/bash
|
||||
# Put shells on the serial terminal and console
|
||||
console::respawn:-/bin/bash
|
||||
ttyS0::respawn:-/bin/bash
|
||||
|
||||
# Stuff to do for the 3-finger salute
|
||||
#::ctrlaltdel:/sbin/reboot
|
||||
::ctrlaltdel:/sbin/reboot
|
||||
|
||||
# Stuff to do before rebooting
|
||||
::shutdown:/etc/init.d/rcK
|
||||
::shutdown:/sbin/swapoff -a
|
||||
::shutdown:/bin/umount -a -r
|
|
@ -0,0 +1 @@
|
|||
i915
|
|
@ -2,9 +2,9 @@ export EDITOR=/bin/vi
|
|||
export PATH="/usr/local/bin:/bin:/sbin:/usr/bin:/usr/sbin"
|
||||
export PS1="[\h \t] \\$ "
|
||||
export GNUPGHOME=/.gnupg
|
||||
export XDG_RUNTIME_DIR=/tmp
|
||||
source /etc/environment
|
||||
|
||||
dmesg -n1
|
||||
cd /root
|
||||
clear
|
||||
cat << "EOF"
|
||||
_ _ ___ ____
|
||||
|
@ -19,5 +19,5 @@ echo " - Version: $VERSION"
|
|||
echo " - Date: $GIT_TIMESTAMP"
|
||||
echo " - Committer: $GIT_AUTHOR"
|
||||
echo " - Commit: $GIT_REF"
|
||||
echo " - Key: $GIT_KEY"
|
||||
echo " - Key: $GIT_PUBKEY"
|
||||
echo ""
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
exec /bin/init
|
|
@ -0,0 +1,15 @@
|
|||
KERNEL!="mmcblk[0-9]p[0-9]|sd[a-z][0-9]", GOTO="automount_end"
|
||||
ACTION=="add", PROGRAM!="/sbin/blkid %N", GOTO="automount_end"
|
||||
IMPORT{program}="/sbin/blkid -o udev -p %N"
|
||||
|
||||
ENV{ID_FS_LABEL}!="", ENV{dir_name}="%E{ID_FS_LABEL}"
|
||||
ENV{ID_FS_LABEL}=="", ENV{dir_name}="%k"
|
||||
|
||||
ACTION=="add", IMPORT{program}="/sbin/blkid -o udev -p %N"
|
||||
ACTION=="add", ENV{ID_FS_TYPE}=="vfat", ENV{mount_options}="relatime,utf8,flush,user,umask=0000"
|
||||
ACTION=="add", RUN+="/bin/mkdir -p /media/%E{dir_name}", RUN+="/bin/mount -o $env{mount_options} /dev/%k /media/%E{dir_name}"
|
||||
ACTION=="add", RUN+="/usr/local/bin/autorun /media/%E{dir_name}"
|
||||
|
||||
ACTION=="remove", ENV{dir_name}!="", RUN+="/bin/umount -l /media/%E{dir_name}", RUN+="/bin/rmdir /media/%E{dir_name}"
|
||||
|
||||
LABEL="automount_end"
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
source /etc/profile
|
||||
|
||||
folder=${1?}
|
||||
|
||||
if [ "$folder" == "/media/USER" ] && [ -f "${folder}/autorun.sh" ]; then
|
||||
if touch "${folder}/.write_test" 2>/dev/null; then
|
||||
echo "!! Autorun: Read-only verification failed for /media/USER" >/dev/console
|
||||
exit 1;
|
||||
else
|
||||
echo "" >/dev/console
|
||||
echo "++ Autorun: Found /media/USER/autorun.sh" >/dev/console;
|
||||
echo "** Autorun: Executing /media/USER/autorun.sh" >/dev/console
|
||||
/bin/bash "/media/USER/autorun.sh" >/dev/console
|
||||
fi
|
||||
elif [ -f "${folder}/autorun.sh.asc" ]; then
|
||||
echo "" >/dev/console
|
||||
echo "++ Autorun: Found ${folder}/autorun.sh" >/dev/console;
|
||||
gpg --verify "${folder}/autorun.sh.asc" >/dev/null 2>&1 || {
|
||||
echo "!! Autorun: Verification Failed for ${folder}/autorun.sh" \
|
||||
>/dev/console;
|
||||
exit 1;
|
||||
}
|
||||
echo "++ Autorun: Verified ${folder}/autorun.sh" >/dev/console
|
||||
echo "** Autorun: Executing ${folder}/autorun.sh" >/dev/console
|
||||
/bin/bash "${folder}/autorun.sh" >/dev/console
|
||||
fi
|
|
@ -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
|
|
@ -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='')
|
Loading…
Reference in New Issue