├── .github
└── workflows
│ └── docs.yaml
├── .gitignore
├── .gitmodules
├── .nojekyll
├── Containerfile
├── LICENSE
├── Makefile
├── README.md
├── appliance
├── .gitignore
├── Makefile
├── README.md
├── banner
│ ├── ethereum.txt
│ └── swarmos.ans
├── init
│ └── init-banner.sh
├── kiwi
│ ├── .gitignore
│ ├── Makefile
│ ├── README.md
│ ├── config.sh
│ ├── config.xml.j2
│ └── root
│ │ ├── etc
│ │ ├── login.defs
│ │ ├── selinux
│ │ │ └── config
│ │ └── systemd
│ │ │ ├── network
│ │ │ ├── 20-bridge.network
│ │ │ ├── 20-veth.network
│ │ │ └── 99-default.network
│ │ │ └── system
│ │ │ └── podman-bee.service
│ │ └── fastboot
└── mkroot.sh
├── bee
├── bee-init.sh
└── bee.yaml
├── deboot.yaml
├── docs
├── Makefile
├── docs
│ ├── appliance.md
│ ├── booting.md
│ ├── build.md
│ ├── deboot.md
│ ├── debooting.md
│ ├── gotcha.md
│ ├── grub.md
│ ├── index.md
│ ├── initramfs.md
│ ├── inspect.md
│ ├── metal.md
│ ├── overview.md
│ ├── u-boot.md
│ └── uefi.md
├── mkdocs.yml
└── requirements.txt
├── grub.Makefile
├── grub
├── Makefile
├── build-image.sh
├── grub-mkconfig
├── grub.Makefile
├── init-image.sh
├── mount-image.sh
├── test-grub.sh
└── unmount-image.sh
├── initramfs
├── .gitignore
├── Makefile
└── initramfs-tools
│ ├── hooks
│ ├── bee
│ ├── curl
│ ├── dbus
│ ├── iw
│ ├── wifi
│ ├── zz-busybox-initramfs
│ └── zz-dhclient
│ ├── initramfs.conf
│ ├── modules
│ ├── scripts
│ └── init-top
│ │ └── thing
│ └── update-initramfs.conf
├── loader
├── Makefile
├── cp-image.sh
├── grub
│ ├── README.md
│ ├── bootloaderspec.conf.j2
│ └── grub.cfg.j2
├── init-image.sh
├── init-vfat.sh
└── u-boot
│ └── extlinux.conf.j2
├── resources
├── bee.md
├── deboot-notes.md
└── ethswarm.md
├── swarm.hash
├── 628e277bae4fd88272dd751c852c22acaea9c147833ca0efe0d3a388a9aa8f8e
├── a89fdb4ea26157b48aef657b252d16f338be3e052738457546515f71a06a2b0f
├── e305446d58fb09914e3dd85977afc39df27caa41b58391cacb1b4b37497a48a9
└── ebf3182e6919289a088f175628924a28148528061c6a240293b7bb6300525642
└── test.hash
/.github/workflows/docs.yaml:
--------------------------------------------------------------------------------
1 | name: Publish docs via GitHub Pages
2 | on:
3 | push:
4 | branches:
5 | - main
6 |
7 | jobs:
8 | build:
9 | name: Deploy docs
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout main
13 | uses: actions/checkout@v2
14 |
15 | - name: Deploy docs
16 | uses: mhausenblas/mkdocs-deploy-gh-pages@nomaterial
17 | env:
18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
19 | CONFIG_FILE: docs/mkdocs.yml
20 | EXTRA_PACKAGES: build-base
21 | REQUIREMENTS: docs/requirements.txt
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | rootfs/build/*
2 | grub/build/*
3 | build/*
4 | initramfs/swarm-initrd
5 | env.json
6 |
7 | # vim
8 | **.swp
9 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "dracut"]
2 | path = initramfs/dracut
3 | url = https://github.com/awmacpherson/dracut.git
4 | branch = ethswarm
5 |
--------------------------------------------------------------------------------
/.nojekyll:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Containerfile:
--------------------------------------------------------------------------------
1 | FROM registry.fedoraproject.org/fedora
2 | RUN dnf -y install gcc wget iproute dhclient # for installation in initramfs
3 | RUN dnf -y install kernel systemd kmod-devel squashfs-tools # for appliances, initramfs
4 | RUN dnf -y install kiwi-cli python3-jinja2-cli # for appliances
5 | RUN dnf -y install dosfstools grub2-tools shim # for grub installation
6 | RUN dnf -y install python3-xmltodict # for converting between XML and JSON
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | BUILDDIR = $(abspath ./build)
2 |
3 | CONTAINER_OPTS = -v $(realpath .):/deboot -ti --rm --cap-add=SYS_PTRACE
4 | CONTAINER_IMAGE = ghcr.io/debootdevs/fedora
5 | CONTAINER_RELEASE = "sha256:8e9a3947a835eab7047364ec74084fc63f9d016333b4cd9fcd8a8a8ae3afd0fd"
6 | BEE_VERSION ?= 1.18.2
7 |
8 | ARCH = $(shell uname -m)
9 | ifeq ($(ARCH), aarch64)
10 | SHORT_ARCH = AA64
11 | else ifeq ($(ARCH), x86_64)
12 | SHORT_ARCH = X64
13 | else
14 | $(error Sorry, only aarch64 and x86_64 architectures are supported at the moment)
15 | endif
16 |
17 | KVERSION ?= $(shell find $(PREFIX)/lib/modules -mindepth 1 -maxdepth 1 -printf "%f" -quit)
18 | KERNEL ?= $(PREFIX)/boot/vmlinuz-$(KVERSION)
19 | NAME ?= Swarm Linux
20 | KERNEL_LOADER ?= grub
21 |
22 | .PHONY: extlinux grub install install-grub clean initramfs boot-tree
23 |
24 | ### BUILD-ENV ################################################################
25 |
26 | build-env: env.json
27 |
28 | env.json: Containerfile
29 | podman build . -t deboot-build
30 | podman image inspect deboot-build > $@
31 |
32 | #init-env: env.json
33 | # podman run --rm -v ./:/deboot -v $(PREFIX)/boot:/boot:ro -v $(PREFIX)/lib/modules:/lib/modules:ro -ti deboot-build bash
34 |
35 | init-env: env.json
36 | podman run --privileged --rm -v ./:/deboot -v /dev:/dev -ti deboot-build bash
37 |
38 | rm-env:
39 | -podman rmi deboot-build
40 | -rm env.json
41 |
42 | $(BUILDDIR):
43 | mkdir -p $@
44 |
45 | ### SYSROOT ##################################################################
46 |
47 | SYSROOT = $(BUILDDIR)/sysroot
48 |
49 | appliance: $(BUILDDIR)/boot/LiveOS/squashfs.img
50 |
51 | $(SYSROOT)/etc/os-release:
52 | make SYSROOT=$(SYSROOT) --directory appliance kiwi
53 |
54 | $(BUILDDIR)/squashfs.img: $(SYSROOT)/etc/os-release $(BUILDDIR)
55 | mksquashfs $(SYSROOT) $@ -comp zstd -Xcompression-level 19
56 |
57 | $(BUILDDIR)/boot/LiveOS/squashfs.img: $(BUILDDIR)/squashfs.img
58 | mkdir -p $(BUILDDIR)/boot/LiveOS
59 | cp $< $@
60 |
61 | $(BUILDDIR)/kver: $(SYSROOT)/etc/os-release $(BUILDDIR)
62 | find $(SYSROOT)/lib/modules -mindepth 1 -maxdepth 1 -printf "%f" -quit > $@
63 |
64 | ### BOOT-TREE ################################################################
65 |
66 | boot-tree: $(BUILDDIR)/kver $(BUILDDIR)/boot appliance kernel initramfs loader boot-spec dtb
67 | # make BUILDDIR=$(BUILDDIR) KERNEL_LOADER=$(KERNEL_LOADER) --directory loader boot-tree
68 |
69 | $(BUILDDIR)/boot: $(BUILDDIR)
70 | mkdir -p $@
71 |
72 | ### KERNEL ###################################################################
73 |
74 | kernel: $(BUILDDIR)/boot/vmlinuz
75 |
76 | $(BUILDDIR)/boot/vmlinuz: $(SYSROOT)/etc/os-release $(BUILDDIR)/boot
77 | cp $(SYSROOT)/lib/modules/$$(cat $(BUILDDIR)/kver)/vmlinuz $@
78 |
79 | ### INITRAMFS ################################################################
80 |
81 | initramfs: $(BUILDDIR)/boot/initramfs
82 |
83 | $(BUILDDIR)/boot/initramfs: $(BUILDDIR)/swarm-initrd $(BUILDDIR)/boot
84 | cp $< $@
85 |
86 | $(BUILDDIR)/swarm-initrd: $(BUILDDIR)
87 | make BEE_VERSION=$(BEE_VERSION) BUILDDIR=$(BUILDDIR) SYSROOT=$(SYSROOT) --directory ./initramfs swarm-initrd
88 |
89 | ###### loader #######
90 | ######### GRUB #########
91 | ifeq ($(KERNEL_LOADER), grub)
92 | # Assume Fedora-style GRUB with support for Bootloader Spec files
93 | boot-spec: $(BUILDDIR)/boot/loader/entries/swarm.conf $(BUILDDIR)/boot/EFI/fedora/grub.cfg
94 |
95 | # BLS file unused for now
96 |
97 | $(BUILDDIR)/boot/loader/entries/swarm.conf:
98 | mkdir -p $(@D)
99 | jinja2 -D name="$(NAME)" -D kernel=$(KVERSION) -D hash=$(HASH) loader/grub/bootloaderspec.conf.j2 > $@
100 |
101 | $(BUILDDIR)/boot/EFI/fedora/grub.cfg:
102 | mkdir -p $(@D)
103 | jinja2 loader/grub/grub.cfg.j2 deboot.yaml > $@
104 |
105 | dtb: # not sure if this is needed for GRUB boot?
106 |
107 | loader: $(BUILDDIR)/boot/EFI/BOOT/BOOT$(SHORT_ARCH).EFI
108 |
109 | $(BUILDDIR)/boot/EFI/BOOT/BOOT$(SHORT_ARCH).EFI: /boot/efi/EFI $(BUILDDIR)/boot
110 | cp -r $< $(BUILDDIR)/boot
111 |
112 | ######### U-BOOT #########
113 | else ifeq ($(KERNEL_LOADER), u-boot)
114 | boot-spec: $(BUILDDIR)/boot/extlinux/extlinux.conf
115 |
116 | $(BUILDDIR)/boot/extlinux/extlinux.conf:
117 | mkdir -p $(@D)
118 | jinja2 -D name="$(NAME)" -D kernel=$(KVERSION) -D hash=$(HASH) loader/u-boot/extlinux.conf.j2 > $@
119 |
120 | dtb: $(BUILDDIR)/boot/dtb
121 |
122 | $(BUILDDIR)/boot/dtb: $(PREFIX)/boot/dtb
123 | cp -r $$(readlink -f $<) -T $@
124 |
125 | loader:
126 | # U-Boot doesn't need additional loader
127 | else
128 | $(error Please set KERNEL_LOADER to either "grub" or "u-boot")
129 | endif
130 |
131 | ### INSTALL INTO BOOT.IMG ####################################################
132 |
133 | install: $(BUILDDIR)/boot.part boot-tree
134 | $(eval TMP := $(shell mktemp -d))
135 | mount $< $(TMP)
136 | rm -rf $(TMP)/*
137 | cp -r $(BUILDDIR)/boot -T $(TMP)
138 | umount $(TMP)
139 | rmdir $(TMP)
140 |
141 | ifeq ($(KERNEL_LOADER), u-boot)
142 | $(BUILDDIR)/boot.part:
143 | loader/cp-image.sh $(BOOT_DEV) $(BUILDDIR)/boot.img $@
144 | else
145 | # Create loopback device backed on boot.img, devnode for p1, symlink to devnode
146 | $(BUILDDIR)/boot.part: | $(BUILDDIR)/boot.img
147 | loader/init-vfat.sh $@ $|
148 |
149 | # Allocate space and create GPT partition table with 1 partition
150 | $(BUILDDIR)/boot.img: $(BUILDDIR)
151 | loader/init-image.sh $@
152 | endif
153 |
154 | clean:
155 | -rm appliance/kiwi/config.xml
156 | -rm -rf $(BUILDDIR)/*
157 |
158 | ### DOCS #######################################################
159 |
160 | docs:
161 | make --directory mkdocs
162 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DeBoot - express yourself through bootloading
2 |
3 | DeBoot is a project to research and implement techniques for booting OS images from decentralized storage networks, such as [Swarm](https://ethswarm.org) or [IPFS](https://ipfs.tech/).
4 |
5 | ## Documentation
6 |
7 | Read all about the current technique in [the DeBoot documentation pages](https://debootdevs.github.io/deboot/).
8 |
9 | ## The story so far...
10 |
11 | DeBoot reached the following milestones in its development:
12 |
13 | - **2022 Q4: Hackathon Concept**: demonstration of a minimum viable DeBoot technique.
14 | - **2023 Q2: `x86-64` Proof-of-Concept**: DeBoot technique for `x86-64` architecture, on VM and Baremetal. [link](https://hackmd.io/@i79XZRmjR86P6AbhL0jwVQ/BJUaVuaUn)
15 | - **2023 Q3: `aarch64` Support**: DeBoot technique for `aarch64` architecture, on VM and Baremetal. [link](https://hackmd.io/@i79XZRmjR86P6AbhL0jwVQ/H1kV07Ufa)
16 | - **2023 Q4: Security Model Proposal**: an exploration of bootstrapping bare metal host infrastructure, and definition of a trust-oriented security model for provisioning and package management. [link](https://github.com/debootdevs/boot-survey/releases/tag/v1.0)
17 | - **2024 Q1: Enhanced UX**: refinement of the build and boot processes, and creation of [a user guide for the DeBoot technique](https://debootdevs.github.io/deboot/)
18 |
19 | ## Upcoming Projects
20 |
21 | - DeBooting a Microgravity Machine/RPi – for DeSci!
22 | - OCI Container Registry Integration
23 | - Personalizing DeBootable Images
24 |
25 | ## Get involved
26 |
27 | DeBoot project welcomes collaborators. If you are interested in deployment of software from decentralised storage, introduce yourself in [the DeBoot chat on Matrix](https://matrix.to/#/#deboot:matrix.org) or [the DeBoot chat on Telegram](https://t.me/+hd2JXtyitYw0ZWE9).
28 |
--------------------------------------------------------------------------------
/appliance/.gitignore:
--------------------------------------------------------------------------------
1 | kiwi/target
2 |
--------------------------------------------------------------------------------
/appliance/Makefile:
--------------------------------------------------------------------------------
1 | all: build/squashfs.img
2 |
3 | export OS_BANNER = banner/swarmos.ans
4 |
5 | SYSROOT ?= $(BUILDDIR)/sysroot
6 |
7 | kiwi: $(SYSROOT)/etc/os-release
8 |
9 | $(SYSROOT)/etc/os-release:
10 | make SYSROOT=$(SYSROOT) --directory kiwi
11 |
12 | $(BUILDDIR)/squashfs.img: $(SYSROOT)/etc/os-release
13 |
14 | build/squashfs.img:
15 | . ./mkroot.sh && build_root
16 |
17 | test:
18 | . ./mkroot.sh && test_root
19 |
20 | clean:
21 | rm -f build/squashfs.img
22 | -rmdir build
23 |
--------------------------------------------------------------------------------
/appliance/README.md:
--------------------------------------------------------------------------------
1 | # Rootfs builder
2 |
3 | The scripts and templates in this directory can be used to generate a root filesystem or "userspace") in the compressed squashfs format used for a live OS.
4 |
5 | ## KIWI
6 |
7 | KIWI is a system image builder maintained by SUSE. It constructs a root directory tree based on an XML spec file together with some additional customisation scripts. It can then wrap the tree in a variety of system image types.
8 |
9 | ### Users
10 |
11 | By default, generated images have a single user `root` with password `deboot`. Additional users can be specifying more `` elements, following the pattern used for the root user. Passwords should be specified in the hashed form used in the Linux shadow database; see [`crypt(5)`](https://manpages.debian.org/unstable/libcrypt-dev/crypt.5.en.html) for a description of the format. You can generate hashes in this form using the `mkpasswd` or `openssl passwd` command-line programs.
12 |
13 | ## Legacy script
14 |
15 | Builds a simple placeholder rootfs, encoded as a squashfs, and init script that prints a banner then drops to a shell.
16 |
17 | Run me (rootless) in one of these containers: https://github.com/orgs/dracutdevs/packages
18 |
19 | ```sh
20 | podman run --rm -ti --user 0 -v /dev:/dev -v $PATH_TO_REPO:/deboot:z $CONTAINER bash -l
21 | cd /deboot/rootfs
22 | make all test
23 | ```
24 |
--------------------------------------------------------------------------------
/appliance/banner/ethereum.txt:
--------------------------------------------------------------------------------
1 |
2 | @
3 | @@@
4 | @@@@@@@
5 | @@@@@@@@@
6 | @@@@@@@@@@@@@
7 | @@@@@@@@@@@@@@@
8 | @@@@@@@@@@@@@@@@@@@
9 | @@@@@@@@@@@@@@@@@@@@@
10 | ( #@@@@@@@@@@@/
11 | @@@% @@@ &@@@
12 | @@@@@@ @@@@@@
13 | @@@@@@@@@
14 | @@@@@
15 | @@@
16 |
17 | █████ █████
18 | ░░███ ░░███
19 | ██████ ███████ ░███████ ██████ ████████ ██████ █████ █████████████████
20 | ███░░███░░░███░ ░███░░███ ███░░███░░███░░█████░░███░░███ ░███░░███░░███░░███
21 | ░███████ ░███ ░███ ░███ ░███████ ░███ ░░░███████ ░███ ░███ ░███ ░███ ░███
22 | ░███░░░ ░███ ███░███ ░███ ░███░░░ ░███ ░███░░░ ░███ ░███ ░███ ░███ ░███
23 | ░░██████ ░░█████ ████ █████░░██████ █████ ░░██████ ░░█████████████░███ █████
24 | ░░░░░░ ░░░░░ ░░░░ ░░░░░ ░░░░░░ ░░░░░ ░░░░░░ ░░░░░░░░░░░░░ ░░░ ░░░░░
25 |
26 |
--------------------------------------------------------------------------------
/appliance/banner/swarmos.ans:
--------------------------------------------------------------------------------
1 | [107;40m[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
2 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
3 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
4 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
5 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
6 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
7 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;058m,[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
8 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m([38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;094m*[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m,[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
9 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;130m*[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
10 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;130m*[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@
11 | [38;5;m@[38;5;m@[38;5;m@[38;5;m#[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;236m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m/[38;5;m@[38;5;m@
12 | [38;5;m@[38;5;m@[38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;237m,[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@[38;5;m@
13 | [38;5;m@[38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@
14 | [38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.
15 | [38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;236m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.
16 | [38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.
17 | [38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.
18 | [38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;130m*[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.
19 | [38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;130m*[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;058m,[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.
20 | [38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;130m*[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;058m,[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.
21 | [38;5;m@[38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;130m*[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;058m,[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@
22 | [38;5;m@[38;5;m@[38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;130m*[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;058m,[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@[38;5;m@
23 | [38;5;m@[38;5;m@[38;5;m@[38;5;m#[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m/[38;5;m@[38;5;m@
24 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@
25 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;237m,[38;5;166m/[38;5;166m/[38;5;166m/[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;166m/[38;5;166m/[38;5;166m/[38;5;058m,[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
26 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m([38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m,[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
27 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
28 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
29 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
30 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
31 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
32 | [38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;235m.[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@[38;5;m@
33 | [0m
34 |
35 |
36 |
37 | ,adPPYba, 8b db d8 ,adPPYYba, 8b,dPPYba, 88,dPYba,,adPYba,
38 | I8[ "" `8b d88b d8' "" `Y8 88P' "Y8 88P' "88" "8a
39 | `"Y8ba, `8b d8'`8b d8' ,adPPPPP88 88 88 88 88
40 | aa ]8I `8bd8' `8bd8' 88, ,88 88 88 88 88
41 | `"YbbdP"' YP YP `"8bbdP"Y8 88 ,ad8888ba, ad88888ba8
42 | d8"' `"8b d8" "8b
43 | d8' `8b Y8,
44 | 88 88 `Y8aaaaa,
45 | 88 88 `"""""8b,
46 | Y8, ,8P `8b
47 | Y8a. .a8P Y8a a8P
48 | `"Y8888Y"' "Y88888P"
49 |
50 |
--------------------------------------------------------------------------------
/appliance/init/init-banner.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | : > /dev/watchdog
3 |
4 | strstr() {
5 | [ "${1##*"$2"*}" != "$1" ]
6 | }
7 |
8 | export PATH=/usr/sbin:/usr/bin:/sbin:/bin
9 | command -v plymouth > /dev/null 2>&1 && plymouth --quit
10 | exec > /dev/console 2>&1
11 |
12 | export TERM=linux
13 | export PS1='deboot:\w\$ '
14 | stty sane
15 |
16 | cat /etc/motd
17 | echo "Made it to the rootfs!"
18 |
19 | [ -c /dev/watchdog ] && printf 'V' > /dev/watchdog
20 | strstr "$(setsid --help)" "control" && CTTY="-c"
21 | setsid $CTTY sh -i
22 |
23 | : > /dev/watchdog
24 |
25 | sync
26 | poweroff -f
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/appliance/kiwi/.gitignore:
--------------------------------------------------------------------------------
1 | config.xml
2 |
--------------------------------------------------------------------------------
/appliance/kiwi/Makefile:
--------------------------------------------------------------------------------
1 | all: $(SYSROOT)/etc/os-release
2 |
3 | KIWI = kiwi
4 | #KIWI = $(shell which kiwi || which kiwi-ng)
5 |
6 | ifeq ($(KIWI), )
7 | $(error Could not find kiwi. Please set Make variable KIWI to path to kiwi binary.)
8 | endif
9 |
10 | $(SYSROOT)/etc/os-release: config.xml config.sh root
11 | $(KIWI) --profile Live system prepare --description . --root $(SYSROOT) && touch -h $@
12 |
13 | config.xml: config.xml.j2
14 | jinja2 -D arch=$$(uname -m) $< > $@
15 |
16 | clean:
17 | -rm -rf $(SYSROOT)
18 |
--------------------------------------------------------------------------------
/appliance/kiwi/README.md:
--------------------------------------------------------------------------------
1 | # KIWI image building
2 |
3 | ## Requirements
4 |
5 | OpenSUSE:
6 | ```
7 | zypper install python3-kiwi python311-xmltodict
8 | ```
9 |
--------------------------------------------------------------------------------
/appliance/kiwi/config.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #======================================
3 | # Functions...
4 | #--------------------------------------
5 | test -f /.kconfig && . /.kconfig
6 | test -f /.profile && . /.profile
7 |
8 | #======================================
9 | # Greeting...
10 | #--------------------------------------
11 | echo "Configure image: [$kiwi_iname]..."
12 |
13 | #======================================
14 | # Activate services
15 | #--------------------------------------
16 | baseInsertService dbus-broker
17 | baseInsertService systemd-networkd
18 | baseInsertService systemd-resolved
19 | baseInsertService podman-bee
20 |
21 | #======================================
22 | # Setup default target, multi-user
23 | #--------------------------------------
24 | baseSetRunlevel 3
25 |
--------------------------------------------------------------------------------
/appliance/kiwi/config.xml.j2:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Andrew W. Macpherson
6 | mail@awmacpherson.com
7 | Fedora 39 Appliance
8 |
9 |
10 |
11 |
12 |
13 | 1.0.0
14 | dnf
15 | en_US
16 | us
17 | UTC
18 | false
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/appliance/kiwi/root/etc/login.defs:
--------------------------------------------------------------------------------
1 | # *REQUIRED*
2 | # Directory where mailboxes reside, _or_ name of file, relative to the
3 | # home directory. If you _do_ define both, MAIL_DIR takes precedence.
4 | # QMAIL_DIR is for Qmail
5 | #
6 | #QMAIL_DIR Maildir
7 | MAIL_DIR /var/spool/mail
8 | #MAIL_FILE .mail
9 |
10 | # Password aging controls:
11 | #
12 | # PASS_MAX_DAYS Maximum number of days a password may be used.
13 | # PASS_MIN_DAYS Minimum number of days allowed between password changes.
14 | # PASS_MIN_LEN Minimum acceptable password length.
15 | # PASS_WARN_AGE Number of days warning given before a password expires.
16 | #
17 | PASS_MAX_DAYS 99999
18 | PASS_MIN_DAYS 0
19 | PASS_MIN_LEN 5
20 | PASS_WARN_AGE 7
21 |
22 | #
23 | # Min/max values for automatic uid selection in useradd
24 | #
25 | UID_MIN 500
26 | UID_MAX 60000
27 |
28 | #
29 | # Min/max values for automatic gid selection in groupadd
30 | #
31 | GID_MIN 500
32 | GID_MAX 60000
33 |
34 | #
35 | # If defined, this command is run when removing a user.
36 | # It should remove any at/cron/print jobs etc. owned by
37 | # the user to be removed (passed as the first argument).
38 | #
39 | #USERDEL_CMD /usr/sbin/userdel_local
40 |
41 | #
42 | # If useradd should create home directories for users by default
43 | # On RH systems, we do. This option is overridden with the -m flag on
44 | # useradd command line.
45 | #
46 | CREATE_HOME yes
47 |
48 | # The permission mask is initialized to this value. If not specified,
49 | # the permission mask will be initialized to 022.
50 | UMASK 077
51 |
52 | # This enables userdel to remove user groups if no members exist.
53 | #
54 | USERGROUPS_ENAB yes
55 |
56 | # Use MD5 or DES to encrypt password? Red Hat use MD5 by default.
57 | MD5_CRYPT_ENAB yes
58 |
59 | ENCRYPT_METHOD MD5
60 |
--------------------------------------------------------------------------------
/appliance/kiwi/root/etc/selinux/config:
--------------------------------------------------------------------------------
1 |
2 | # This file controls the state of SELinux on the system.
3 | # SELINUX= can take one of these three values:
4 | # enforcing - SELinux security policy is enforced.
5 | # permissive - SELinux prints warnings instead of enforcing.
6 | # disabled - No SELinux policy is loaded.
7 | SELINUX=permissive
8 | # SELINUXTYPE= can take one of these two values:
9 | # targeted - Only targeted network daemons are protected.
10 | # strict - Full SELinux protection.
11 | # mls - Multi Level Security protection.
12 | SELINUXTYPE=targeted
13 | # SETLOCALDEFS= Check local definition changes
14 | SETLOCALDEFS=0
15 |
16 |
17 |
--------------------------------------------------------------------------------
/appliance/kiwi/root/etc/systemd/network/20-bridge.network:
--------------------------------------------------------------------------------
1 | [Match]
2 | Kind=bridge
3 |
4 | [Link]
5 | Unmanaged=yes
6 |
--------------------------------------------------------------------------------
/appliance/kiwi/root/etc/systemd/network/20-veth.network:
--------------------------------------------------------------------------------
1 | [Match]
2 | Kind=veth
3 |
4 | [Link]
5 | Unmanaged=yes
6 |
--------------------------------------------------------------------------------
/appliance/kiwi/root/etc/systemd/network/99-default.network:
--------------------------------------------------------------------------------
1 | [Match]
2 | Name=*
3 |
4 | [Network]
5 | DHCP=yes
6 |
--------------------------------------------------------------------------------
/appliance/kiwi/root/etc/systemd/system/podman-bee.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=EthSwarm bee node
3 | After=network-online.target
4 |
5 | [Service]
6 | ExecStart=podman run -p 1633:1633 -p 1634:1634 -p 1635:1635 \
7 | docker.io/ethersphere/bee:latest start --password=deboot --swap-enable=false --full-node=false
8 | Restart=always
9 | RestartSec=30
10 |
11 | [Install]
12 | WantedBy=multi-user.target
13 |
--------------------------------------------------------------------------------
/appliance/kiwi/root/fastboot:
--------------------------------------------------------------------------------
1 | 1
2 |
--------------------------------------------------------------------------------
/appliance/mkroot.sh:
--------------------------------------------------------------------------------
1 | #/bin/bash
2 |
3 | mkrootbasedir=$(readlink -f ${BASH_SOURCE[0]})
4 | mkrootbasedir=${mkrootbasedir%/*}
5 | debootbasedir=$(readlink -f $mkrootbasedir/..)
6 | dracutbasedir=$debootbasedir/dracut
7 | echo Using dracut installation found in $dracutbasedir.
8 |
9 | # build directory
10 | export BUILDDIR=${BUILDDIR:-${mkrootbasedir}/build}
11 | mkdir -p $BUILDDIR
12 |
13 | build_root() {
14 | # Prepare rootfs
15 | if [ -f $BUILDDIR/squashfs.img ]; then
16 | echo rootfs already found!
17 | exit 1
18 | fi
19 | ROOTFS_TMPDIR=$(mktemp -dt deboot.XXXXX)
20 | (
21 | export initdir=$ROOTFS_TMPDIR/overlay/source/
22 | . "$dracutbasedir"/dracut-init.sh
23 |
24 | (
25 | cd "$initdir" || exit
26 | mkdir -p dev sys proc etc run root usr var/lib
27 | )
28 |
29 | inst_multiple sh shutdown poweroff stty cat ps ln ip dd \
30 | mount dmesg mkdir cp ping grep setsid ls less cat sync \
31 | #findmnt find curl
32 | for _terminfodir in /lib/terminfo /etc/terminfo /usr/share/terminfo; do
33 | if [ -f "${_terminfodir}"/l/linux ]; then
34 | inst_multiple -o "${_terminfodir}"/l/linux
35 | break
36 | fi
37 | done
38 |
39 | inst_simple "${dracutbasedir}/modules.d/99base/dracut-lib.sh" "/lib/dracut-lib.sh"
40 | inst_simple "${dracutbasedir}/modules.d/99base/dracut-dev-lib.sh" "/lib/dracut-dev-lib.sh"
41 | inst_simple "${dracutbasedir}/modules.d/45url-lib/url-lib.sh" "/lib/url-lib.sh"
42 | inst_simple "${dracutbasedir}/modules.d/40network/net-lib.sh" "/lib/net-lib.sh"
43 | inst_binary "${dracutbasedir}/dracut-util" "/usr/bin/dracut-util"
44 | ln -s dracut-util "${initdir}/usr/bin/dracut-getarg"
45 | ln -s dracut-util "${initdir}/usr/bin/dracut-getargs"
46 |
47 | inst ${mkrootbasedir}/init/init-banner.sh /sbin/init
48 | inst_simple /etc/os-release
49 | inst /etc/passwd /etc/passwd
50 | inst /etc/group /etc/group
51 | inst $OS_BANNER /etc/motd
52 |
53 | )
54 |
55 | mksquashfs $ROOTFS_TMPDIR/overlay/source $BUILDDIR/squashfs.img -quiet -comp zstd -Xcompression-level 22
56 | rm -rf $ROOTFS_TMPDIR
57 | }
58 |
59 | test_root() {
60 | QEMU=${dracutbasedir}/test/run-qemu
61 |
62 | ROOTFS_TMPDIR=$(mktemp -dt deboot.XXXXX)
63 |
64 | ${dracutbasedir}/dracut.sh -l -q -m "dmsquash-live qemu" \
65 | -i $BUILDDIR/squashfs.img /squashfs.img \
66 | --no-hostonly --no-hostonly-cmdline \
67 | --force $ROOTFS_TMPDIR/initrd $KVERSION || return 1
68 |
69 | $QEMU -initrd $ROOTFS_TMPDIR/initrd -append "root=live:/squashfs.img console=ttyS0,115200n81"
70 | rm -rf $ROOTFS_TMPDIR
71 | }
72 |
73 |
--------------------------------------------------------------------------------
/bee/bee-init.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | rm /var/lib/bee/password
3 | cp /keys/* /var/lib/bee/keys
4 | chown bee:bee /var/lib/bee/keys/*
5 | cp ./bee.yaml /etc/bee/bee.yaml
6 |
--------------------------------------------------------------------------------
/bee/bee.yaml:
--------------------------------------------------------------------------------
1 | # config: /etc/bee/bee.yaml
2 | data-dir: /var/lib/bee
3 | password-file: ""
4 | blockchain-rpc-endpoint: https://rpc.gnosischain.com
5 |
--------------------------------------------------------------------------------
/deboot.yaml:
--------------------------------------------------------------------------------
1 | name: deboot
2 | date: 2024-02-08
3 | version: 0.2.0
4 | loader: "bzz://a8e4c9406e3882e745566f907e6477d10cdc44ca6d3349563ccb6619bae22ce5"
5 | docs: "https://debootdevs.github.io/deboot/"
6 | source: "https://github.com/debootdevs/deboot/commit/abe1efa3b7f3240d77292e019552b02f95a29f2a"
7 | entries:
8 | - id: "94a6153735b380e5e45f13e657912d7a3f07c0c570d2389d575cfb4d24055ee6"
9 | desc: (network boot) Bee Ultra Light Node (Swarm) v0.1
10 | - id: "b78752606742d738ea3094d089e1ac99f1e3dbfb0e1075f0e36c0db1bf0dbc50"
11 | desc: (network boot) Nimbus Fluffy Node (Ethereum - Portal Network) v0.1
12 | - id: "9f4b2dec0ccdbef4e42923537acaf822f180780338d06628f269a8fe0aa9d7c8"
13 | desc: (network boot) (--shm-size=65536k) DDVTech mistserver Appliance v0.1
14 | - id: "bac60dafc4033e4aae18b1db7bd231428db45698da4244408e79f79bb029d448"
15 | desc: (network boot) (--shm-size=7168m) DDVTech mistserver Appliance v0.2
16 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | DOCSDIR ?= site
2 |
3 | docs: $(DOCSDIR)/index.html
4 |
5 | $(DOCSDIR)/index.html:
6 | mkdocs build --site-dir $<
7 |
--------------------------------------------------------------------------------
/docs/docs/appliance.md:
--------------------------------------------------------------------------------
1 | # Appliances
2 |
3 | We apply the name *appliance* to the userspace images we build. In this context, an appliance is a "single-purpose OS." Of course, there is nothing about the build process that actually forces our images to be "single-purpose."
4 |
5 | ## Building appliances using KIWI-NG
6 |
7 | The DeBoot POC build uses an open-source tool called [KIWI NG](https://osinside.github.io/kiwi/), developed by SUSE, which consumes XML configuration files and scripts to build root directory trees. We then package the tree by bundling it into a [squashfs](https://docs.kernel.org/filesystems/squashfs.html) using standard Linux tool `mksquashfs`.
8 |
9 | To build an appliance using the DeBoot build system, run `make appliance`. The output is a file `./build/squashfs.img` which can be uploaded to Swarm for later DeBooting.
10 |
11 | The configuration directory for this appliance build is located at `./appliance/kiwi/`.
12 |
13 | Edit the file `config.xml.j2` to:
14 |
15 | - customize the repositories and packages installed in the appliance
16 |
17 | - customize the users configured in the appliance. Hashes for passwords can be generated using `openssl passwd -6`. Default password for _root_ account is _deboot_.
18 |
19 | Add files under `root/` for them to be included in the directory tree.
20 |
21 | Edit the file `config.sh` to install `systemd` services
22 |
23 | ## Uploading your appliance to Swarm
24 |
25 | To upload your appliance to Swarm, you'll need to [run a bee node](https://docs.ethswarm.org/docs/bee/working-with-bee/introduction) (light or full), purchase postage stamp batches using BZZ tokens on the Gnosis Chain network, and upload your data using the node. We recommend the use of [swarm-cli](https://github.com/ethersphere/swarm-cli) for Swarm-related operations.
26 |
27 | ### Obtaining BZZ tokens
28 |
29 | At time of writing (2024-01-30), the most stable (i.e. having least price impact) way to obtain BZZ tokens is to purchase them directly from the issuing contract on Ethereum, which has a frontend at https://openbzz.eth.limo/. The BZZ tokens will then need to be bridged to Gnosis Chain (GC) for use with the Swarm network.
30 |
31 | Small amounts of BZZ tokens are also available on [COWSwap](https://swap.cow.fi/).
32 |
33 | ### Purchasing postage stamp batches
34 |
35 | You can purchase [postage stamps](https://docs.ethswarm.org/docs/learn/technology/contracts/postage-stamp) by interacting with the postage stamp contract using any GC client. This functionality is built into Swarm-CLI's `stamp` functions, which uses the GC RPC endpoint associated to your local bee node.
36 |
37 | Stamp batch sizes are specified in terms of the "batch depth." A batch with depth *n* has a theoretical maximum storage capacity of 2n · 4KiB, however due to the way that Swarm storage space is allocated the actual amount of storage you can get in practice [may be much smaller](https://docs.ethswarm.org/docs/learn/technology/contracts/postage-stamp#effective-utilisation-table), especially for small depths. We recommend purchasing stamp batches of depth at least 26, corresponding to about 226GB of storage on average.
38 |
39 | ### Running a bee node
40 |
41 | We recommend running bee using the official [container images](https://hub.docker.com/layers/ethersphere/bee/latest/images/sha256-c3e36ff3633e435f05fea1d81ba788465ae45ec52b1e56358ea45bd7271758a2?context=explore).
42 |
43 | ### Uploading chunks
44 |
45 | Use the `swarm-cli upload --stamp $MYSTAMP` command.
46 |
--------------------------------------------------------------------------------
/docs/docs/booting.md:
--------------------------------------------------------------------------------
1 | # How booting works
2 |
3 | Booting a computer — that is, executing code on a computer starting from a completely uninitialized, powered off state — usually traverses several stages before reaching its stable state of running operating system software.
4 | The job of each boot stage is to retrieve the program to execute in the next stage from wherever it is being stored, load it into memory, and execute it.
5 | Different boot stages are distinguished by their resource footprint, user interface, the types of storage locations from which they can retrieve data, and the executable image formats they are able to load.
6 | Generally, boot stages are designed to be *ephemeral* in the sense that they leave as little as possible behind in memory when the next stage is running.
7 |
8 | ## Some boot sequences
9 |
10 | * UEFI boot flow summary. https://github.com/tianocore/tianocore.github.io/wiki/PI-Boot-Flow
11 | * Rock5b with U-Boot, a recently popular ARM SOC. https://opensource.rock-chips.com/wiki_Boot_option
12 |
13 | ## Booting Linux
14 |
15 | The DeBoot POC is focussed on the task of booting Linux. Linux is usually distributed in a special gzip-compressed ELF executable format called a [b]zImage with the filename `vmlinuz`. There are various programs that can load this format; the most widely used are GRUB (for x86 systems) and U-Boot (for ARM systems). Linux can also be bundled into an EFI executable using the [EFI boot stub](https://docs.kernel.org/admin-guide/efi-stub.html) format to be loaded by UEFI (or [EBBR](https://arm-software.github.io/ebbr/)) firmware.
16 |
17 | ## Userspace
18 |
19 | The final stage of a Linux boot comprises mounting and switching to the OS root filesystem, or *userspace*. In [systemd-based initramfs](https://systemd.io/INITRD_INTERFACE/), the switch uses the `systemctl switch-root` command.
20 |
--------------------------------------------------------------------------------
/docs/docs/build.md:
--------------------------------------------------------------------------------
1 | # Building the DeBoot POC
2 |
3 | These instructions are based on the [deboot repo on github](https://github.com/debootdevs/deboot).
4 |
5 | ## Quickstart
6 |
7 | Requires `podman`, `git`, `make`, `slirp4netns`, `uidmap` (for Debian distributions).
8 |
9 | Clone the repo with the `--recurse-submodules` flag, e.g. with:
10 |
11 | ```sh
12 | git clone https://github.com/debootdevs/deboot.git --recurse-submodules
13 | ```
14 |
15 | Then starting from the repo root, run the following commands:
16 |
17 | ```sh
18 | sudo make init-env
19 | cd /deboot
20 | make BEE_VERSION=$VERSION install
21 | ```
22 |
23 | where `$VERSION` should be set to the latest version of the Swarm bee node as indicated by its git tag e.g. `VERSION=1.18.2`.
24 |
25 | The main build artefacts are:
26 |
27 | ```sh
28 | ./build/boot.img # bootable image which may be flashed to a USB drive
29 | ./build/squashfs.img # compressed userspace which can be uploaded to Swarm and booted
30 | ```
31 |
32 | To boot your constructed image from Swarm, first you must store it to Swarm, retrieve its Swarm hash, add an entry to `./deboot.yaml`, then rebuild `boot.img`.
33 |
34 | Once done, you can move to the next section to start DeBooting.
35 |
36 | To clean after yourself, run:
37 |
38 | ```sh
39 | sudo make clean
40 | ```
41 |
42 | ## Build container
43 |
44 | The DeBoot build is designed to run in a Fedora container using the same set of package repositories as the appliance to be built and booted. The choice of Fedora is convenient, but not necessary: with suitable modifications to package names and paths, one could adjust the build to construct appliances based on their preferred distro.
45 |
46 | To build and enter the build environment, make sure Podman is installed and run
47 |
48 | ```
49 | myhost:~/deboot$ sudo make init-env
50 | ...
51 | buildenv:/$ cd /deboot
52 | ```
53 |
54 | starting from the repo root.
55 |
56 | ### Privileges
57 |
58 | Certain build stages require mounting a filesystem, hence root privileges in the host. That means the build environment must be run as a *privileged* container invoked by the superuser. If that makes you uncomfortable, we recommend running the entire thing in a VM.
59 |
60 | ### Version consistency
61 |
62 | It is important that the initramfs and userspace use the same versions of packages. Crucially, the kernel modules installed in the initramfs and userspace must both exactly match the version of the loaded kernel; otherwise they cannot be loaded.
63 |
64 | To ensure such consistency, the userspace and initramfs must be built using the same package repositories and at the same time as the build container. Unfortunately this means that the DeBoot POC boot image cannot easily
65 |
66 | ## Layout
67 |
68 | The build processes for separate components are separated into different directories.
69 |
70 | ```sh
71 | /appliance/kiwi/ # rootfs builder
72 | /initramfs/ # initramfs build scripts
73 | dracut/ # dracut fork used to build initramfs
74 | /loader/ # configurations for kernel loaders
75 | grub/ # template for grub.cfg, BLS entries
76 | u-boot/ # template for extlinux.conf
77 | # other directories either deprecated or irrelevant to the build
78 | ```
79 |
80 |
--------------------------------------------------------------------------------
/docs/docs/deboot.md:
--------------------------------------------------------------------------------
1 | # How DeBoot works
2 |
3 | The main GitHub repo hosted at https://github.com/debootdevs/deboot is a proof of concept build for a boot sequence that loads a Linux userspace (i.e. root filesystem) from a squashfs hosted on Swarm. The fetcher is an ultralight Bee node (the reference implementation of a Swarm node) inserted into a custom initramfs generated by a fork of the [dracut project](https://github.com/dracutdevs/dracut).
4 |
5 | We chose to put a Bee node in the initramfs, as opposed to some earlier stage such as GRUB, as an expedient: since bee is already designed to run on Linux, the software can run at the initramfs stage without any modification. Conversely, getting the bee into GRUB, for example, would require porting it to use GRUB syscalls instead of Linux one; potentially a substantial task. Putting exotic fetchers in the initramfs is a simple and flexible solution that allows for rapid iteration.
--------------------------------------------------------------------------------
/docs/docs/debooting.md:
--------------------------------------------------------------------------------
1 | # DeBooting
2 |
3 |
4 |
5 | ## Invoking
6 |
7 | ### VM
8 |
9 | The easiest way to test your DeBoot GRUB build is to run the `grub/test-grub.sh` script from the repo root. This launches a QEMU instance with EDK2 UEFI firmware, a virtual drive backed on `boot.img`, and virtual serial console connected to the invoking terminal.
10 |
11 | In principle the same approach could be used to test ARM/U-Boot builds, provided an emulator for the target board is available. However, this is generally a bigger ask than for x86 CPUs, where "generic" models are often sufficient.
12 |
13 | ### Metal
14 |
15 | The other way to test this is to write `boot.img` to a removable USB drive or SD card and boot your target device from it. I use a command like
16 |
17 | ```
18 | sudo dd if=./build/boot.img of=/dev/sdc
19 | ```
20 |
21 | to do this, but you can use whatever tool you usually use to create bootable USB drives.
22 |
23 | ## Using
24 |
25 | If all goes well, the boot should take you to a GRUB menu displaying various options.
26 |
27 | * Most of the menu items attempt to download, mount, and switch into a squashfs hosted on Swarm.
28 | * One menu item has the phrase "local boot" in the description. This option does not use Swarm, or indeed the network, at all: it loads a local copy of the appliance artefact from the removable drive into memory and boots into that.
29 | * The last menu item takes you back to the UEFI firmware configuration utility.
30 |
31 | ### Pitfalls
32 |
33 | Due to various chunk extinction events that have occurred on Swarm network upgrades, not all of the options in the default configuration of the DeBoot GRUB menu are functional.
34 |
35 | If instead of a menu you end up arriving at a GRUB prompt, it means that GRUB couldn't find its own configuration file. You can help it by running the following commands:
36 |
37 | ```sh
38 | grub$> set prefix=${root}/grub2
39 | grub$> normal # Enter "normal" mode, i.e. GRUB boot menu
40 | ```
41 |
42 | Note that the backspace key here functions like the usual behaviour of the delete key. If using QEMU with virtual serial console output, you may experience visual artefacts when using the shell; if the display gets messed up, clear it with the `clear` command.
43 |
44 | If running via `grub/test-grub.sh`, the graphical output is not connected, and so output on the graphical terminal will not be visible. To disable the graphical terminal in initramfs, hit `e` when your target menu item is highlighted and edit the kernel commandline by deleting the expression `console=tty1`.
--------------------------------------------------------------------------------
/docs/docs/gotcha.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/debootdevs/deboot/b4b6986ae14343b469933fb149b4dca758308f95/docs/docs/gotcha.md
--------------------------------------------------------------------------------
/docs/docs/grub.md:
--------------------------------------------------------------------------------
1 | # GRUB
2 |
3 | The GNU Project's GRand Unified Bootloader is an interactive boot manager capable of loading Linux, BSD, and any [multiboot2](https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html)-compliant operating system kernel. It is distributed as an EFI application and as a legacy "BIOS" boot format for non-UEFI systems. Traditionally, GRUB tends to be used on x86 PCs, especially Linux systems. GRUB is extensible and a wide variety of GRUB modules are available, providing extended filesystem support (including ext4 and btrfs), video driviers, and network protocol implementations.
4 |
5 | GRUB has a rather detailed [manual](https://www.gnu.org/software/grub/manual/grub/grub.html), but in our experience it can be difficult to get a handle on basic usage patterns from reading this. The shell scripts used by Linux distros to generate GRUB's main configuration file, `grub.cfg`, are often complex and arcane. This can make it difficult for non-expert users to diagnose and debug boot issues.
6 |
7 | ## Quickstart
8 |
9 | The default behaviour of GRUB is to try to locate and interpret its configuration file `grub.cfg`, written in a GRUB-specific scripting language similar to Bash.
10 |
--------------------------------------------------------------------------------
/docs/docs/index.md:
--------------------------------------------------------------------------------
1 | # Welcome to the DeBoot Project documentation web site!
2 |
3 | DeBoot is a research project that explores ways to load operating system software from decentralised storage backends.
4 |
--------------------------------------------------------------------------------
/docs/docs/initramfs.md:
--------------------------------------------------------------------------------
1 | # Initramfs
2 |
3 | An *initial ram filesystem* or *initramfs* is an initial stage used in the loading of Linux operating systems that offloads the job of fetching and mounting the root filesystem from the kernel to userspace tools.
4 |
5 | ```
6 | # FEATURES
7 |
8 | Loaders: kernel loader, EFI
9 | Fetches: *
10 | Loads: ELF executables
11 | Size: 10-100MB
12 | ```
13 |
14 | As an archive, an initramfs is a concatenated string of cpio archives, some or all of which may be gzip-compressed.
15 | An initramfs can be unpacked using the `cpio` utility, or inspected at a higher level using `lsnitrd`.
16 | The `dracut-cpio` and `skipcpio` utilities are adapted specifically to unpack the cpio archives produced by dracut.
17 |
18 | ## Building the initramfs
19 |
20 | The DeBoot project uses a fork of the [dracut](https://github.com/dracutdevs/dracut) project to generate initial ram filesystems.
21 |
--------------------------------------------------------------------------------
/docs/docs/inspect.md:
--------------------------------------------------------------------------------
1 | # Inspecting a raw disk image
2 |
3 | To adapt a new device or OS to the DeBoot style boot process, it usually helps to inspect how existing OS distributions on that device do it. Apart from reading documentation, it's useful to download an official raw disk image and inspect it. This page discusses some methods to do that.
4 |
5 | ## The raw disk
6 |
7 | Typically, bootable images are distributed as a raw image of a partitioned disk. This can take the form of a "standard" disk which is intended to be stored on a writable medium and used persistently, or a special hybrid ISO 9660 format which can also be written to an optical disk and used as an installer.
8 |
9 | * Two mode boot extension for ISO 9660. https://en.wikipedia.org/wiki/ISO_9660#El_Torito
10 |
11 | Generally, the `fdisk` program is used to inspect the partition tables of raw disk images, showing whether they are in MBR or GPT format and listing the partitions.
12 |
13 | ```
14 | fdisk -l image.img
15 | ```
16 |
17 | Typically, the last partition is the root filesystem and the earlier partitions (and sometimes some code located in the space before the first partition) are used for booting. Sometimes, the first partition is VFAT formatted and has an "EFI" partition code. In this case, UEFI firmware can discover it and launch EFI applications.
18 |
19 | Once you have seen the layout of the disk, it's time to look inside the partitions. You can create devnodes for these partitions with the following command, which will list out the names of the devnodes: typically `/dev/mapper/loop${x}p${y}` where $y$ is the partition number and $x$ is a counter that keeps track of which loopback device you've used to do this.
20 |
21 | ```
22 | kpartx -va image.img
23 | ```
24 |
25 | This command may need to be run as `sudo`. If `kpartx` is not available, its functionality can be replicated with `losetup` and `partx`.
26 |
27 | ## Inside the partitions
28 |
29 | The first step is to mount and inspect the EFI system partition (ESP), if present. This can be used to figure out whether GRUB, U-Boot, or some other system is being used to boot the OS. If the image has an MBR instead of GPT, the first partition might have some other partition code like "Microsoft Basic Data."
30 |
31 | Some tips on identifying the boot system in use:
32 |
33 | * If the ESP is present and has a file with path `/EFI/BOOT/BOOT${ARCH}.EFI`, it can be booted by UEFI firmware.
34 | * If GRUB is present, there is usually a file `grub${arch}.efi` somewhere in the `/EFI` directory. In this case, `grub.cfg` may be located in the ESP or in the second partition.
35 | * EFI applications can sometimes be booted by boot code supporting a strict subset of UEFI, such as U-Boot or the Raspberry Pi bootloader (which implements EBBR).
36 | * For non-GRUB boot sequences on ARM boards, consult the board's documentation for bootloader configuration. Configuration files are often text based and located in the first partition.
37 | * On U-Boot systems, look for a file `extlinux.conf`.
38 | * On RPi, look for `/config.txt` and `/cmdline.txt`.
39 |
--------------------------------------------------------------------------------
/docs/docs/metal.md:
--------------------------------------------------------------------------------
1 | # Metal
2 |
3 | When a computer is first powered on, raw machine code is loaded into the CPU instruction cache from some fixed offset in a non-removable component (e.g. ROM) on the mainboard and executed. This *first-stage bootloader* is typically very small — on the order of a few hundred bytes. Its only job is to initialize a local storage device containing the second stage bootloader and enough of main memory to load it.
4 |
5 | ## Implementations
6 |
7 | Generally, first stage bootloader and platform firmware is closed source software managed and installed by your mainboard manufacturer.
8 |
9 | A well-known open source project with builds for many boards exists in the form of [coreboot](https://www.coreboot.org/). There's also a nascent Rust reimplemenation called [oreboot](https://github.com/oreboot/oreboot).
--------------------------------------------------------------------------------
/docs/docs/overview.md:
--------------------------------------------------------------------------------
1 | # Overview
2 |
3 | * The main GitHub repo hosted at https://github.com/debootdevs/deboot is a proof of concept build for a boot sequence that loads a Linux userspace (i.e. root filesystem) from a squashfs hosted on Swarm.
--------------------------------------------------------------------------------
/docs/docs/u-boot.md:
--------------------------------------------------------------------------------
1 | U-Boot is both a first-stage and second-stage bootloader.
2 |
--------------------------------------------------------------------------------
/docs/docs/uefi.md:
--------------------------------------------------------------------------------
1 | Unified Extensible Firmware Interface is a specification that defines the architecture of the platform firmware used for booting the computer hardware and its interface for interaction with the operating system.
2 |
--------------------------------------------------------------------------------
/docs/mkdocs.yml:
--------------------------------------------------------------------------------
1 | site_name: DeBoot
2 | site_url: https://debootdevs.github.io/deboot/
3 | nav:
4 | - Overview: overview.md
5 | - How booting works: booting.md
6 | - How DeBoot works: deboot.md
7 | - Boot Stages:
8 | - Metal: metal.md
9 | - UEFI: uefi.md
10 | - GRUB: grub.md
11 | - U-Boot: u-boot.md
12 | - Initramfs: initramfs.md
13 | - Using DeBoot:
14 | - Building DeBoot: build.md
15 | - DeBooting: debooting.md
16 | - Appliances: appliance.md
17 | - Gotchas: gotcha.md
18 | - Inspecting boot images: inspect.md
19 | theme: readthedocs
20 |
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | mkdocs
2 |
--------------------------------------------------------------------------------
/grub.Makefile:
--------------------------------------------------------------------------------
1 | BUILDDIR = $(realpath ./grub/build)
2 | MOUNTDIR = $(BUILDDIR)/mnt
3 | # Fedora grub prefix
4 | GRUB_PREFIX = $(MOUNTDIR)/EFI/fedora
5 | #GRUB_PREFIX = $(MOUNTDIR)/boot/grub2
6 | HOST_EFI = /boot/efi
7 | PKG_INSTALL = dnf -y install
8 |
9 | KVERSION = $(shell find /lib/modules -mindepth 1 -maxdepth 1 -printf "%f" -quit)
10 | BEE_VERSION ?= 1.17.2
11 |
12 | ifeq ($(shell findmnt $(MOUNTDIR)),)
13 | $(error No mount found at $(MOUNTDIR), run 'sudo grub/mount-image.sh' first!)
14 | endif
15 |
16 | dracutbasedir = $(realpath ./dracut)
17 |
18 | all: install-grub $(GRUB_PREFIX)/grub.cfg $(MOUNTDIR)/boot/vmlinuz $(MOUNTDIR)/boot/swarm-initrd
19 |
20 | install-grub:
21 | @echo $(KVERSION)
22 | $(PKG_INSTALL) grub2-efi-x64 shim-x64
23 | cp -r $(HOST_EFI)/* $(MOUNTDIR)
24 |
25 | $(GRUB_PREFIX)/grub.cfg: swarm.hash
26 | mkdir -p $(GRUB_PREFIX)
27 | grub/grub-mkconfig > $@
28 |
29 | $(MOUNTDIR)/boot/vmlinuz:
30 | mkdir -p $(MOUNTDIR)/boot
31 | cp /lib/modules/$(KVERSION)/vmlinuz $@
32 |
33 | $(MOUNTDIR)/boot/swarm-initrd: /usr/bin/bee dracut/dracut-util
34 | mkdir -p $(MOUNTDIR)/boot
35 | $(dracutbasedir)/dracut.sh -l \
36 | -a "bzz network-legacy" \
37 | -o iscsi \
38 | --no-hostonly --no-hostonly-cmdline \
39 | -f $@ $(KVERSION)
40 |
41 | dracut/dracut-util: /usr/bin/gcc
42 | sh -c "cd dracut && ./configure"
43 | make enable_documentation=no -C dracut
44 |
45 | install-bee: /usr/bin/bee
46 |
47 | /usr/bin/bee: bee-$(BEE_VERSION).x86_64.rpm
48 | -rpm -i bee-$(BEE_VERSION).x86_64.rpm
49 |
50 | bee-$(BEE_VERSION).x86_64.rpm:
51 | wget -nc https://github.com/ethersphere/bee/releases/download/v$(BEE_VERSION)/bee-$(BEE_VERSION).x86_64.rpm
52 |
--------------------------------------------------------------------------------
/grub/Makefile:
--------------------------------------------------------------------------------
1 | BUILDDIR = $(realpath .)/build
2 | IMGDIR = $(BUILDDIR)/esp
3 | # Fedora grub prefix
4 | GRUB_PREFIX = $(IMGDIR)/EFI/fedora
5 | #GRUB_PREFIX = $(IMGDIR)/boot/grub2
6 | HOST_EFI = /boot/efi
7 |
8 | CONTAINER_OPTS = -v $(realpath ..):/deboot -ti --rm
9 | CONTAINER_NAME = ghcr.io/debootdevs/fedora
10 | CONTAINER_RELEASE = "sha256:8e9a3947a835eab7047364ec74084fc63f9d016333b4cd9fcd8a8a8ae3afd0fd"
11 | CONTAINER_IMAGE = $(CONTAINER_NAME)@$(CONTAINER_RELEASE)
12 |
13 | KVERSION = $(shell find /lib/modules -mindepth 1 -maxdepth 1 -printf "%f" -quit)
14 |
15 | all: $(GRUB_PREFIX)/grub.cfg $(IMGDIR)/boot/vmlinuz $(IMGDIR)/boot/swarm-initrd
16 |
17 | $(GRUB_PREFIX)/grub.cfg: ../swarm.hash $(GRUB_PREFIX)
18 | HASHDIR=../swarm.hash ./grub-mkconfig > $@
19 |
20 | $(GRUB_PREFIX): $(IMGDIR)
21 | mkdir -p $(GRUB_PREFIX)
22 |
23 | $(IMGDIR)/boot/swarm-initrd: $(IMGDIR)/boot ../initramfs/swarm-initrd
24 | cp ../initramfs/swarm-initrd $@
25 |
26 | $(IMGDIR)/boot/vmlinuz: $(IMGDIR)/boot
27 | podman run $(CONTAINER_OPTS) $(CONTAINER_IMAGE) \
28 | make BUILDDIR=/deboot/build \
29 | --directory /deboot/grub --makefile grub.Makefile
30 |
31 | $(IMGDIR)/boot: $(IMGDIR)
32 | mkdir -p $(IMGDIR)/boot
33 |
34 | $(IMGDIR):
35 | mkdir -p $(IMGDIR)
36 |
37 |
--------------------------------------------------------------------------------
/grub/build-image.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if [ $(id -u) != 0 ]; then
4 | echo This script must be run as root or with sudo!
5 | exit 1
6 | fi
7 |
8 | get_sudoer() {
9 | local SUDOER=$(ps -o ruid= -f $PPID | xargs)
10 | local SUDOER_PASSWD=$(getent passwd $SUDOER)
11 | local SUDOER_NAME=${SUDOER_PASSWD%%:*}
12 | local SUDOER_GROUP=$(groups $SUDOER_NAME | awk '{print $3}')
13 | echo $SUDOER_NAME:$SUDOER_GROUP
14 | }
15 |
16 | BUILDDIR=${BUILDDIR:-./build}
17 | BUILDDIR=$(readlink -f $BUILDDIR)
18 | GRUB_IMG=$BUILDDIR/grub.img
19 | GRUB_CFG=$BUILDDIR/grub.cfg
20 | mkdir -p $BUILDDIR
21 |
22 | PLATFORM=x86_64-efi
23 |
24 | GRUB_INSTALLFLAGS="--removable --force --target=$PLATFORM"
25 |
26 | # main thread
27 | fallocate -l 100m $GRUB_IMG
28 | mkfs.vfat -n DEBOOT $GRUB_IMG
29 | DEBOOT_TMPDIR=$(mktemp -dt deboot-efi.XXXXX)
30 | mount $GRUB_IMG $DEBOOT_TMPDIR
31 | grub2-install $GRUB_INSTALLFLAGS \
32 | --boot-directory=$DEBOOT_TMPDIR/boot \
33 | --efi-directory=$DEBOOT_TMPDIR
34 |
35 | # grub.cfg
36 | cp $GRUB_CFG $DEBOOT_TMPDIR/boot/grub2/grub.cfg
37 |
38 | # kernel + initrd
39 |
40 | cp /boot/vmlinuz $DEBOOT_TMPDIR/boot
41 | cp $BUILDDIR/swarm-initrd $DEBOOT_TMPDIR/boot
42 |
43 | umount $DEBOOT_TMPDIR
44 | rmdir $DEBOOT_TMPDIR
45 |
46 | chown $(get_sudoer) $GRUB_IMG
47 |
--------------------------------------------------------------------------------
/grub/grub-mkconfig:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | gen_menuentry() {
4 | local HASH=${1##*/}
5 | local DESC=$(cat $1)
6 | cat << EOF
7 | menuentry "$DESC" --class swarm --class deboot --id "$HASH" {
8 | search.fs_label DEBOOT root
9 | linux /boot/vmlinuz root=live:bzz://$HASH console=ttyS0 panic=1
10 | initrd /boot/swarm-initrd
11 | }
12 |
13 | EOF
14 | }
15 |
16 | HASHDIR=${HASHDIR-./swarm.hash}
17 |
18 | ### BEGIN OUTPUT #############################################################
19 |
20 | for f in $HASHDIR/*; do
21 | gen_menuentry $f
22 | done
23 |
24 | cat << EOF
25 | menuentry "UEFI Firmware setup" {
26 | fwsetup
27 | }
28 | EOF
29 |
30 |
--------------------------------------------------------------------------------
/grub/grub.Makefile:
--------------------------------------------------------------------------------
1 | # The part of the build that runs inside the container
2 | BUILDDIR = $(realpath .)/build
3 | IMGDIR = $(BUILDDIR)/esp
4 |
5 | # Fedora grub prefix
6 | GRUB_PREFIX = $(MOUNTDIR)/EFI/fedora
7 | #GRUB_PREFIX = $(MOUNTDIR)/boot/grub2
8 | HOST_EFI = /boot/efi
9 |
10 | KVERSION = $(shell find /lib/modules -mindepth 1 -maxdepth 1 -printf "%f" -quit)
11 |
12 | all: install-grub $(IMGDIR)/boot/vmlinuz
13 |
14 | install-grub:
15 | cp -r $(HOST_EFI)/* $(IMGDIR)
16 |
17 | $(IMGDIR)/boot/vmlinuz: $(IMGDIR)/boot
18 | @echo $(KVERSION)
19 | cp /lib/modules/$(KVERSION)/vmlinuz $@
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/grub/init-image.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | BUILDDIR=${BUILDDIR:-./build}
3 | BUILDDIR=$(readlink -f $BUILDDIR)
4 | GRUB_IMG=$BUILDDIR/grub.img
5 |
6 | MKFS_VFAT=$(PATH=/sbin:/usr/sbin:$PATH which mkfs.vfat)
7 |
8 | mkdir -p $BUILDDIR/mnt
9 |
10 | # main thread
11 | fallocate -l 100m $GRUB_IMG
12 | $MKFS_VFAT -n DEBOOT $GRUB_IMG
13 |
--------------------------------------------------------------------------------
/grub/mount-image.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if [ $(id -u) != 0 ]; then
4 | echo This script must be run as root or with sudo!
5 | exit 1
6 | fi
7 |
8 | BUILDDIR=${BUILDDIR:-./build}
9 | BUILDDIR=$(readlink -f $BUILDDIR)
10 | GRUB_IMG=$BUILDDIR/grub.img
11 |
12 | # get uid and gid of sudoer
13 | SUDOER_UID=$(ps -o ruid= $PPID | xargs)
14 | SUDOER_GID=$(getent passwd $SUDOER_UID)
15 | SUDOER_GID=${SUDOER_GID#*:*:*:}
16 | SUDOER_GID=${SUDOER_GID%%:*}
17 |
18 | mount -o uid=$SUDOER_UID,gid=$SUDOER_GID $GRUB_IMG $BUILDDIR/mnt
19 |
20 |
--------------------------------------------------------------------------------
/grub/test-grub.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Fedora
3 | BIOS=${BIOS-/usr/share/edk2/ovmf/OVMF_CODE.fd}
4 | # OpenSUSE
5 | #BIOS=${BIOS:-/usr/share/qemu/ovmf-x86_64.bin}
6 | GRUB=${GRUB:-./build/boot.img}
7 | if [ -z $GRUB ]; then
8 | echo "Please set GRUB=/path/to/grub.img."
9 | exit 1
10 | fi
11 |
12 | if [ -z $TEST_SUBNET ]; then
13 | echo "Please set TEST_SUBNET to a subnet with a route to the Internet!"
14 | fi
15 |
16 | mac=52:54:00:12:34:56
17 |
18 | ARCH=$(uname -m)
19 | dnf install -y qemu-system-${ARCH%%_64}
20 |
21 | qemu-system-$(uname -m) -smp 2 -m 2048M -nographic -enable-kvm -no-reboot \
22 | -bios "$BIOS" -drive file="$GRUB" \
23 | -nic user,model=e1000,mac=$mac
24 |
--------------------------------------------------------------------------------
/grub/unmount-image.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if [ $(id -u) != 0 ]; then
4 | echo This script must be run as root or with sudo!
5 | exit 1
6 | fi
7 |
8 | BUILDDIR=${BUILDDIR:-./build}
9 | BUILDDIR=$(readlink -f $BUILDDIR)
10 | GRUB_IMG=$BUILDDIR/grub.img
11 |
12 | LOOPDEV=$(losetup -nO NAME --associated $GRUB_IMG)
13 | umount $BUILDDIR/mnt
14 | losetup -d $LOOPDEV # note that this only marks the device for later destruction
15 |
--------------------------------------------------------------------------------
/initramfs/.gitignore:
--------------------------------------------------------------------------------
1 | bee-*
2 |
--------------------------------------------------------------------------------
/initramfs/Makefile:
--------------------------------------------------------------------------------
1 | KVERSION = $(shell find /lib/modules -mindepth 1 -maxdepth 1 -printf "%f" -quit)
2 | ARCH = $(shell uname -m)
3 |
4 |
5 | ifeq ($(BEE_VERSION),)
6 | $(error Please set BEE_VERSION.)
7 | endif
8 |
9 | dracutbasedir = $(abspath dracut)
10 | BUILDDIR ?= .
11 |
12 | swarm-initrd: $(BUILDDIR)/swarm-initrd
13 |
14 | $(BUILDDIR)/swarm-initrd: /usr/bin/bee $(dracutbasedir)/dracut-util
15 | $(dracutbasedir)/dracut.sh -l \
16 | -a "bzz network-legacy drm" \
17 | -o iscsi \
18 | --no-hostonly --no-hostonly-cmdline \
19 | -f $@ $(KVERSION)
20 |
21 | $(dracutbasedir)/dracut-util: /usr/bin/gcc
22 | sh -c "cd $(dracutbasedir) && ./configure"
23 | make enable_documentation=no --directory $(dracutbasedir)
24 |
25 | # would not be necessary if Swarm RPM repo were kept up to date
26 |
27 | install-bee: /usr/bin/bee
28 |
29 | /usr/bin/bee: bee-$(BEE_VERSION).$(ARCH).rpm
30 | -rpm -i bee-$(BEE_VERSION).$(ARCH).rpm
31 |
32 | bee-$(BEE_VERSION).$(ARCH).rpm:
33 | curl -sSL https://github.com/ethersphere/bee/releases/download/v$(BEE_VERSION)/bee-$(BEE_VERSION).$(ARCH).rpm -o $@
34 |
--------------------------------------------------------------------------------
/initramfs/initramfs-tools/hooks/bee:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | PREREQ=""
3 | prereqs() {
4 | echo "$PREREQ"
5 | }
6 |
7 | case $1 in
8 | prereqs)
9 | prereqs
10 | exit 0
11 | ;;
12 | esac
13 |
14 | # bee
15 |
16 | . /usr/share/initramfs-tools/hook-functions #provides copy_exec
17 | copy_exec /bin/bee /bin/bee
18 |
19 |
--------------------------------------------------------------------------------
/initramfs/initramfs-tools/hooks/curl:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | PREREQ=""
3 | prereqs() {
4 | echo "$PREREQ"
5 | }
6 |
7 | case $1 in
8 | prereqs)
9 | prereqs
10 | exit 0
11 | ;;
12 | esac
13 |
14 | # bee
15 |
16 | . /usr/share/initramfs-tools/hook-functions #provides copy_exec
17 | copy_exec /usr/bin/curl /bin/curl
18 |
19 |
20 |
--------------------------------------------------------------------------------
/initramfs/initramfs-tools/hooks/dbus:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | PREREQ=""
3 | prereqs() {
4 | echo "$PREREQ"
5 | }
6 |
7 | case $1 in
8 | prereqs)
9 | prereqs
10 | exit 0
11 | ;;
12 | esac
13 |
14 | # dbus
15 |
16 | . /usr/share/initramfs-tools/hook-functions #provides copy_exec
17 |
18 | for f in $(ls /usr/bin/dbus*); do copy_exec $f $f; done
19 |
--------------------------------------------------------------------------------
/initramfs/initramfs-tools/hooks/iw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | PREREQ=""
3 | prereqs() {
4 | echo "$PREREQ"
5 | }
6 |
7 | case $1 in
8 | prereqs)
9 | prereqs
10 | exit 0
11 | ;;
12 | esac
13 |
14 | # iw
15 |
16 | . /usr/share/initramfs-tools/hook-functions #provides copy_exec
17 |
18 | for f in $(ls /usr/sbin/iw*); do copy_exec $f $f; done
19 | for f in $(ls /usr/bin/iw*); do copy_exec $f $f; done
20 | copy_exec /usr/libexec/iwd /bin/iwd
21 |
22 |
--------------------------------------------------------------------------------
/initramfs/initramfs-tools/hooks/wifi:
--------------------------------------------------------------------------------
1 | . /usr/share/initramfs-tools/hook-functions #provides copy_exec
2 | manual_add_modules cfg80211 iwlwifi iwlmvm
3 |
--------------------------------------------------------------------------------
/initramfs/initramfs-tools/hooks/zz-busybox-initramfs:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # This hook copies busybox binary into the initramfs directory
4 | # and creates all necessary links to it.
5 | # It should be placed last into the hooks directory, in order to
6 | # not overwrite commands which are provided by other means.
7 |
8 | set -e
9 |
10 | case "${1:-}" in
11 | prereqs) echo ""; exit 0;;
12 | esac
13 |
14 | BB_BIN=/usr/lib/initramfs-tools/bin/busybox
15 |
16 | [ n = "$BUSYBOX" ] && exit 0
17 |
18 | [ -r /usr/share/initramfs-tools/hook-functions ] || exit 0
19 | . /usr/share/initramfs-tools/hook-functions
20 |
21 | if [ -f $DESTDIR/bin/sh ] && cmp -s $DESTDIR/bin/sh $BB_BIN ; then
22 | # initramfs copies busybox into /bin/sh, undo this
23 | rm -f $DESTDIR/bin/sh
24 | fi
25 | rm -f $DESTDIR/bin/busybox # for compatibility with old initramfs
26 | copy_exec $BB_BIN /bin/busybox
27 |
28 | for alias in $($BB_BIN --list-long); do
29 | alias="${alias#/}"
30 | case "$alias" in
31 | # strip leading /usr, we don't use it
32 | usr/*) alias="${alias#usr/}" ;;
33 | */*) ;;
34 | *) alias="bin/$alias" ;; # make it into /bin
35 | esac
36 |
37 | # Busybox is configured to prefer its own applets, so remove
38 | # duplication from klibc.
39 | name="${alias##*/}"
40 | if [ -e "$DESTDIR/$alias" ] && cmp -s "/usr/lib/klibc/bin/$name" "$DESTDIR/$alias"; then
41 | rm -f "$DESTDIR/$alias"
42 | [ "${verbose}" = "y" ] && echo "Preferring busybox $alias over klibc" || true
43 | fi
44 |
45 | [ -e "$DESTDIR/$alias" ] || \
46 | ln "$DESTDIR/bin/busybox" "$DESTDIR/$alias"
47 | done
48 |
49 | # Casper wants to have access to https, let busybox invoke openssl to
50 | # achieve that.
51 | # TODO: maybe have another variable like BUSYBOX_OPENSSL to include
52 | # openssl if wanted? maybe like cloud-initramfs wants it?
53 | if [ "$CASPER_GENERATE_UUID" ]; then
54 | mkdir -p $DESTDIR/etc/ssl/certs $DESTDIR/usr/lib/ssl/
55 | copy_exec /usr/bin/openssl
56 | copy_file config /etc/ssl/openssl.cnf
57 | update-ca-certificates --fresh --etccertsdir $DESTDIR/etc/ssl/certs --hooksdir /no-hooks
58 | # Only use by-hash certs
59 | rm -f $DESTDIR/etc/ssl/certs/ca-certificates.crt
60 | for cert in $DESTDIR/etc/ssl/certs/* ; do
61 | target=$(readlink $cert)
62 | case $target in
63 | /*)
64 | copy_file cert $target
65 | ;;
66 | esac
67 | done
68 | ln -s /etc/ssl/certs $DESTDIR/usr/lib/ssl/certs
69 | ln -s /etc/ssl/openssl.cnf $DESTDIR/usr/lib/ssl/openssl.cnf
70 | fi
71 |
--------------------------------------------------------------------------------
/initramfs/initramfs-tools/hooks/zz-dhclient:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | PREREQ=""
4 |
5 | prereqs()
6 | {
7 | echo "$PREREQ"
8 | }
9 |
10 | case $1 in
11 | prereqs)
12 | prereqs
13 | exit 0
14 | ;;
15 | esac
16 |
17 | if [ ! -x /sbin/dhclient ]; then
18 | exit 0
19 | fi
20 |
21 | . /usr/share/initramfs-tools/scripts/functions
22 | . /usr/share/initramfs-tools/hook-functions
23 |
24 | copy_exec /bin/run-parts
25 | copy_exec /sbin/dhclient
26 | copy_exec /sbin/dhclient-script
27 | cp -a /usr/lib/initramfs-tools/etc/dhcp/ $DESTDIR/etc/dhcp/
28 | mkdir -p $DESTDIR/var/lib/dhcp/
29 |
--------------------------------------------------------------------------------
/initramfs/initramfs-tools/initramfs.conf:
--------------------------------------------------------------------------------
1 | #
2 | # initramfs.conf
3 | # Configuration file for mkinitramfs(8). See initramfs.conf(5).
4 | #
5 | # Note that configuration options from this file can be overridden
6 | # by config files in the /etc/initramfs-tools/conf.d directory.
7 |
8 | #
9 | # MODULES: [ most | netboot | dep | list ]
10 | #
11 | # most - Add most filesystem and all harddrive drivers.
12 | #
13 | # dep - Try and guess which modules to load.
14 | #
15 | # netboot - Add the base modules, network modules, but skip block devices.
16 | #
17 | # list - Only include modules from the 'additional modules' list
18 | #
19 |
20 | MODULES=most
21 |
22 | #
23 | # BUSYBOX: [ y | n | auto ]
24 | #
25 | # Use busybox shell and utilities. If set to n, klibc utilities will be used.
26 | # If set to auto (or unset), busybox will be used if installed and klibc will
27 | # be used otherwise.
28 | #
29 |
30 | BUSYBOX=auto
31 |
32 | #
33 | # COMPCACHE_SIZE: [ "x K" | "x M" | "x G" | "x %" ]
34 | #
35 | # Amount of RAM to use for RAM-based compressed swap space.
36 | #
37 | # An empty value - compcache isn't used, or added to the initramfs at all.
38 | # An integer and K (e.g. 65536 K) - use a number of kilobytes.
39 | # An integer and M (e.g. 256 M) - use a number of megabytes.
40 | # An integer and G (e.g. 1 G) - use a number of gigabytes.
41 | # An integer and % (e.g. 50 %) - use a percentage of the amount of RAM.
42 | #
43 | # You can optionally install the compcache package to configure this setting
44 | # via debconf and have userspace scripts to load and unload compcache.
45 | #
46 |
47 | COMPCACHE_SIZE=""
48 |
49 | #
50 | # COMPRESS: [ gzip | bzip2 | lz4 | lzma | lzop | xz ]
51 | #
52 |
53 | COMPRESS=lz4
54 |
55 | #
56 | # NFS Section of the config.
57 | #
58 |
59 | #
60 | # DEVICE: ...
61 | #
62 | # Specify a specific network interface, like eth0
63 | # Overridden by optional ip= or BOOTIF= bootarg
64 | #
65 |
66 | DEVICE=
67 |
68 | #
69 | # NFSROOT: [ auto | HOST:MOUNT ]
70 | #
71 |
72 | NFSROOT=auto
73 |
74 | #
75 | # RUNSIZE: ...
76 | #
77 | # The size of the /run tmpfs mount point, like 256M or 10%
78 | # Overridden by optional initramfs.runsize= bootarg
79 | #
80 |
81 | RUNSIZE=10%
82 |
--------------------------------------------------------------------------------
/initramfs/initramfs-tools/modules:
--------------------------------------------------------------------------------
1 | # List of modules that you want to include in your initramfs.
2 | # They will be loaded at boot time in the order below.
3 | #
4 | # Syntax: module_name [args ...]
5 | #
6 | # You must run update-initramfs(8) to effect this change.
7 | #
8 | # Examples:
9 | #
10 | # raid1
11 | # sd_mod
12 |
13 | cfg80211
14 | iwlwifi
15 | iwlmvm
16 | cryptd
17 | ghash_clmulni_intel
18 | crypto_simd
19 | aesni_intel
20 | cmac
21 | crct10dif_pclmul
22 | crc32_pclmul
23 | af_alg
24 | algif_hash
25 | algif_skcipher
26 | algif_aead
27 | libdes
28 | des_generic
29 | libarc4
30 | mac80211
31 | pkcs8_key_parser
32 |
--------------------------------------------------------------------------------
/initramfs/initramfs-tools/scripts/init-top/thing:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | echo POOP
3 |
4 |
--------------------------------------------------------------------------------
/initramfs/initramfs-tools/update-initramfs.conf:
--------------------------------------------------------------------------------
1 | #
2 | # Configuration file for update-initramfs(8)
3 | #
4 |
5 | #
6 | # update_initramfs [ yes | all | no ]
7 | #
8 | # Default is yes
9 | # If set to all update-initramfs will update all initramfs
10 | # If set to no disables any update to initramfs beside kernel upgrade
11 |
12 | update_initramfs=yes
13 |
14 | #
15 | # backup_initramfs [ yes | no ]
16 | #
17 | # Default is no
18 | # If set to no leaves no .bak backup files.
19 |
20 | backup_initramfs=no
21 |
--------------------------------------------------------------------------------
/loader/Makefile:
--------------------------------------------------------------------------------
1 | BUILDDIR ?= $(abspath ./build)
2 | SYSROOT = $(BUILDDIR)/sysroot
3 |
4 | CONTAINER_OPTS = -v $(realpath .):/deboot -ti --rm --cap-add=SYS_PTRACE
5 | CONTAINER_IMAGE = ghcr.io/debootdevs/fedora
6 | CONTAINER_RELEASE = "sha256:8e9a3947a835eab7047364ec74084fc63f9d016333b4cd9fcd8a8a8ae3afd0fd"
7 | BEE_VERSION ?= 1.18.2
8 |
9 | ARCH = $(shell uname -m)
10 | ifeq ($(ARCH), aarch64)
11 | SHORT_ARCH = AA64
12 | else ifeq ($(ARCH), x86_64)
13 | SHORT_ARCH = X64
14 | else
15 | $(error Sorry, only aarch64 and x86_64 architectures are supported at the moment)
16 | endif
17 |
18 | KVERSION ?= $(shell find $(SYSROOT)/lib/modules -mindepth 1 -maxdepth 1 -printf "%f" -quit)
19 | ifeq ($(KVERSION), )
20 | $(error No kernel found! Aborting)
21 | endif
22 | KERNEL ?= $(SYSROOT)/lib/modules/$(KVERSION)/vmlinuz
23 | NAME ?= Swarm Linux
24 | KERNEL_LOADER ?= grub
25 |
26 | .PHONY: extlinux grub install install-grub clean initramfs boot-tree
27 |
28 | ### BOOT-TREE ################################################################
29 |
30 | boot-tree: $(BUILDDIR)/boot loader kernel initramfs boot-spec dtb
31 |
32 | $(BUILDDIR)/boot:
33 | mkdir -p $@
34 |
35 | kernel: $(BUILDDIR)/boot/vmlinuz
36 |
37 | $(BUILDDIR)/boot/vmlinuz: $(KERNEL) $(BUILDDIR)/boot
38 | cp $< $@
39 |
40 | initramfs: $(BUILDDIR)/boot/initramfs
41 |
42 | $(BUILDDIR)/boot/initramfs: initramfs/swarm-initrd $(BUILDDIR)/boot
43 | cp initramfs/swarm-initrd $@
44 |
45 | ###### loader #######
46 | ######### GRUB #########
47 | ifeq ($(KERNEL_LOADER), grub)
48 | # Assume Fedora-style GRUB with support for Bootloader Spec files
49 | boot-spec: $(BUILDDIR)/boot/loader/entries/swarm.conf $(BUILDDIR)/boot/grub2/grub.cfg
50 |
51 | $(BUILDDIR)/boot/loader/entries/swarm.conf:
52 | mkdir -p $(@D)
53 | jinja2 -D name="$(NAME)" -D kernel=$(KVERSION) -D hash=$(HASH) loader/grub/bootloaderspec.conf.j2 > $@
54 |
55 | $(BUILDDIR)/boot/grub2/grub.cfg:
56 | mkdir -p $(@D)
57 | grub2-mkconfig -o $@
58 |
59 | dtb: # not sure if this is needed for GRUB boot?
60 |
61 | loader: $(BUILDDIR)/efi/EFI/BOOT/BOOT$(SHORT_ARCH).EFI
62 |
63 | $(BUILDDIR)/efi/EFI/BOOT/BOOT$(SHORT_ARCH).EFI: $(PREFIX)/boot/efi
64 | cp -r $< -T $(BUILDDIR)/efi
65 |
66 | ######### U-BOOT #########
67 | else ifeq ($(KERNEL_LOADER), u-boot)
68 | boot-spec: $(BUILDDIR)/boot/extlinux/extlinux.conf
69 |
70 | $(BUILDDIR)/boot/extlinux/extlinux.conf:
71 | mkdir -p $(@D)
72 | jinja2 -D name="$(NAME)" -D kernel=$(KVERSION) -D hash=$(HASH) loader/u-boot/extlinux.conf.j2 > $@
73 |
74 | dtb: $(BUILDDIR)/boot/dtb
75 |
76 | $(BUILDDIR)/boot/dtb: $(PREFIX)/boot/dtb
77 | cp -r $$(readlink -f $<) -T $@
78 |
79 | loader:
80 | # U-Boot doesn't need additional loader
81 | else
82 | $(error Please set KERNEL_LOADER to either "grub" or "u-boot")
83 | endif
84 |
85 | ### INSTALL ##################################################################
86 |
87 | install: $(BUILDDIR)/boot.part
88 | $(eval TMP := $(shell mktemp -d))
89 | mount $< $(TMP)
90 | rm -rf $(TMP)/*
91 | cp -r $(BUILDDIR)/boot -T $(TMP)
92 | umount $(TMP)
93 | rmdir $(TMP)
94 |
95 | ifeq ($(KERNEL_LOADER), u-boot)
96 | $(BUILDDIR)/boot.part:
97 | loader/cp-image.sh $(BOOT_DEV) $(BUILDDIR)/boot.img $@
98 | else
99 | $(BUILDDIR)/boot.part: | $(BUILDDIR)/boot.img
100 | loader/init-vfat.sh $@ $|
101 |
102 | $(BUILDDIR)/boot.img:
103 | loader/init-image.sh $@
104 | endif
105 |
106 | ### OLD ######################################################################
107 |
108 | $(BUILDDIR)/grub.img: initramfs/swarm-initrd
109 | grub/init-image.sh
110 |
111 | $(BUILDDIR)/esp:
112 | make BUILDDIR=$(BUILDDIR) --directory grub
113 |
114 | initramfs/swarm-initrd:
115 | make BEE_VERSION=$(BEE_VERSION) --directory ./initramfs swarm-initrd
116 |
117 | install-grub:
118 | grub/mount-image.sh
119 | cp -r $(BUILDDIR)/esp -T $(BUILDDIR)/mnt
120 | # grub/unmount-image.sh
121 | umount $(BUILDDIR)/mnt
122 |
123 | test-grub:
124 | podman run --runtime crun -v /dev:/dev $(CONTAINER_OPTS) $(CONTAINER_IMAGE) sh -c 'cd /deboot && grub/test-grub.sh'
125 |
126 | clean:
127 | -rm initramfs/swarm-initrd
128 | -rm -rf $(BUILDDIR)/*
129 |
--------------------------------------------------------------------------------
/loader/cp-image.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SOURCE=${1-/dev/mmcblk0}
4 | BOOT_IMG=$2
5 | BOOT_PART=$3
6 |
7 | dd if=$SOURCE of=$BOOT_IMG
8 |
9 | # find boot partition
10 | LOOP_DEV=$(losetup -f $BOOT_IMG --show)
11 | partx -a $LOOP_DEV
12 | LOOP_PART=${LOOP_DEV}p1
13 | ln -s $LOOP_PART $BOOT_PART
14 |
--------------------------------------------------------------------------------
/loader/grub/README.md:
--------------------------------------------------------------------------------
1 | # GRUB
2 |
3 | ## Using `grub2-mkconfig`
4 |
5 | The `grub2-mkconfig` that ships with your distro tries to read a load of system information from your host system. It tends to find that difficult from inside a container, making it difficult to set up a virtual build environment. (Really what you need is a VM).
6 |
7 | For ease of testing, the DeBoot project also ships its own very simple version of that script `grub-mkconfig` that consumes menu entries from a `HASHDIR`.
8 |
9 | ## BootloaderSpec
10 |
11 | Text configuration files stored in /boot/loader/entries and consumed by (the grub script fragment generated by) `/etc/grub.d/10_linux`, consumed by `grub2-mkconfig`.
12 |
--------------------------------------------------------------------------------
/loader/grub/bootloaderspec.conf.j2:
--------------------------------------------------------------------------------
1 | title {{ name }}
2 | version {{ kernel }}
3 | linux /vmlinuz
4 | initrd /initramfs
5 | options root=live:bzz://{{ hash }} consoleblank=0 systemd.show_status=true crashkernel=auto no_timer_check console=tty1 console=ttyS0,115200n8
6 |
--------------------------------------------------------------------------------
/loader/grub/grub.cfg.j2:
--------------------------------------------------------------------------------
1 | {% for entry in entries %}
2 | menuentry "{{entry.desc}}" --class swarm --class deboot --id {{entry.id}} {
3 | search.fs_label DEBOOT root
4 | echo "Loading kernel..."
5 | linux /vmlinuz root=live:bzz://{{entry.id}} console=ttyS0 console=tty1 panic=1
6 | echo "Loading initramfs..."
7 | initrd /initramfs
8 | }
9 | {% endfor %}
10 |
11 |
12 | menuentry "(local boot) Locally built appliance" --class swarm --class deboot --id 'local' {
13 | search.fs_label DEBOOT root
14 | echo "Loading kernel..."
15 | linux /vmlinuz root=live:LABEL=DEBOOT console=ttyS0 console=tty1 panic=1
16 | echo "Loading initramfs..."
17 | initrd /initramfs
18 | }
19 |
20 | menuentry "UEFI Firmware setup" {
21 | fwsetup
22 | }
23 |
--------------------------------------------------------------------------------
/loader/init-image.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | BOOT_IMG=$1
4 |
5 | # locate mkfs.vfat
6 | #MKFS_VFAT=$(PATH=/sbin:/usr/sbin:$PATH which mkfs.vfat)
7 | #SGDISK=$(PATH=/sbin:/usr/sbin:$PATH which sgdisk)
8 |
9 | # make GPT disk image
10 |
11 | # main thread
12 | # fallocate -l 255m $BOOT_IMG # not supported in WSL
13 | dd if=/dev/zero of=$BOOT_IMG bs=1M count=512
14 | echo -e 'label: gpt\n,511M,U' | sfdisk $BOOT_IMG
15 | #sgdisk --new=1:0:0 -t 1:ef00 $BOOT_IMG
16 |
--------------------------------------------------------------------------------
/loader/init-vfat.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | BOOT_IMG=$(readlink -f $2)
4 | BOOT_VFAT=$1
5 |
6 | set -x
7 |
8 | # locate mkfs.vfat
9 | #MKFS_VFAT=$(PATH=/sbin:/usr/sbin:$PATH which mkfs.vfat)
10 | #SGDISK=$(PATH=/sbin:/usr/sbin:$PATH which sgdisk)
11 |
12 | # make GPT disk image
13 |
14 | # find boot partition
15 | LOOP_DEV=$(losetup -f $BOOT_IMG --show)
16 | partx -a $LOOP_DEV
17 | LOOP_PART=${LOOP_DEV}p1
18 |
19 | # create VFAT fs
20 | mkfs.vfat -n DEBOOT $LOOP_PART
21 |
22 | # symlink it
23 | ( rm $BOOT_VFAT )
24 | ln -s $LOOP_PART $BOOT_VFAT
25 |
--------------------------------------------------------------------------------
/loader/u-boot/extlinux.conf.j2:
--------------------------------------------------------------------------------
1 | label {{ name }}
2 | kernel /vmlinuz
3 | initrd /initramfs
4 | fdtdir /dtb
5 | append root=live:bzz://{{ hash }} consoleblank=0 crashkernel=auto no_timer_check console=tty1 console=ttyS0,115200n systemd.show_status=true
6 |
--------------------------------------------------------------------------------
/resources/bee.md:
--------------------------------------------------------------------------------
1 | # Bee (EthSwarm)
2 |
3 | Minimal configuration:
4 |
5 | ```yaml
6 | # bee.yaml
7 | blockchain-rpc-endpoint: https://rpc.gnosischain.com # or your own node
8 | full-node: true | false
9 | swap-enable: true | false # false for ultra-light node
10 | data-directory: /home/shtuka/.bee
11 | password-file: "" # no password file
12 | # maybe easier to use one if running inside a container
13 | # use podman secret
14 | # postage-stamp-address:
15 | # postage-stamp-start-block: 29470428
16 | ```
17 |
18 | Directory layout;:
19 |
20 | ```sh
21 | ~/.bee/
22 | keys/
23 | swarm.key # keys to GC address
24 | libp2p.key
25 | pss.key
26 | statestore/ # leveldb stuff
27 | localstore/ # only for full node
28 | swapperstore/ # full node ?
29 | ```
30 |
31 | Pro tips:
32 |
33 | - API up: `localhost:1633/health`
34 |
35 | - Peer list: `localhost:1635/peers`
36 |
37 | - State to preserve for recovery or migration:
38 |
39 | - EOA keypair (`$DATADIR/keys/swarm.key`, format is standard [web3 secret store](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition)).
40 | - Database of used postage stamps (could be as simple as first unused).
41 | - Chequebook contract address, if using cheques (state channels).
42 |
43 | Items 2 and 3 are kept in the state db, so essentially this entire db needs to be backed up.
44 |
45 | ## Issues
46 |
47 | RPM package dependencies not compatible with OpenSUSE (depends on `shadow-utils` but this package is called `shadow` on SUSE systems).
48 |
49 | Wrong HTTP version (fails because this is the libp2p port!).
50 |
51 | ```sh
52 | [root@abe6432677a3 /]# curl localhost:1634/health
53 | curl: (1) Received HTTP/0.9 when not allowed
54 | ```
55 |
56 |
57 |
58 | ## Resources
59 |
60 | Repos.
61 |
62 | - Bee node (Go). https://github.com/ethersphere/bee
63 | - Swarm CLI (Typescript). https://github.com/ethersphere/swarm-cli
64 |
65 | Documentation.
66 |
67 | - Node types. https://docs.ethswarm.org/docs/bee/installation/quick-start
68 | - Secrets format. https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition
--------------------------------------------------------------------------------
/resources/deboot-notes.md:
--------------------------------------------------------------------------------
1 | # DeBoot resources
2 |
3 | ## Other projects
4 |
5 | - Dracut https://github.com/dracutdevs/dracut
6 | - LinuxBoot (alternative to UEFI DXE phase) https://www.linuxboot.org/
7 | - coreboot https://www.coreboot.org/
8 |
9 | ## Firmware
10 |
11 | - https://opensourcefirmware.foundation/
12 |
13 | ## UEFI
14 |
15 | Universal extensible firmware interface.
16 |
17 | An EFI executable is a PE format executable that runs in the UEFI environment.
18 |
19 | At boot, UEFI-compliant firmware finds and loads an EFI executable in an EFI system partition (ESP) on a bootable device (configured from the UEFI/BIOS setup screen).
20 |
21 | - EFI system partition https://en.wikipedia.org/wiki/EFI_system_partition
22 | - iPXE firmware (has wifi, HTTP) https://ipxe.org/howto/chainloading
23 | - EDK2 (UEFI development environment) https://github.com/tianocore/edk2
24 | - http://www.rodsbooks.com/efi-bootloaders/index.html
25 |
26 | ## GRUB
27 |
28 | Everyone's favourite EFI bootloader. Watch out for the GRUB Boot Hole!
29 |
30 | - Manual https://www.gnu.org/software/grub/manual/grub/grub.html
31 | - Netboot syntax https://olbat.net/files/misc/netboot.pdf
32 | - Grub wifi driver (nonexistence of) https://unix.stackexchange.com/questions/631368/how-do-i-add-network-driver-to-grub
33 | - Writing GRUB modules https://wiki.osdev.org/Writing_GRUB_Modules
34 |
35 | ## initramfs
36 |
37 | A temporary filesystem that can be loaded into main memory during the boot process (after loading a kernel but before setting up what will become the root filesystem).
38 |
39 | - https://wiki.gentoo.org/wiki/Custom_Initramfsn
40 | - debugging https://wiki.debian.org/InitramfsDebug
41 |
42 | ## Secure boot
43 |
44 | Only boot into EFI executables signed by some authority, usually the device manufacturer and/or Microsoft/Verisign.
45 |
46 | Options for bootstrapping trust are Shim (Fedora) and PreLoader (Linux Foundation). It is also possible to add or remove signing keys.
47 |
48 | - http://www.rodsbooks.com/efi-bootloaders/secureboot.html
49 |
50 | ## PXE
51 |
52 | Preboot execution environment for netboot. Load EFI executable from a DHCP-proxy and TFTP server on a LAN. Can be used to manage boot for a fleet of devices.
53 |
54 | - DNSMASQ (open source PXE/DHCP/TFTP/DNS boot server) https://thekelleys.org.uk/dnsmasq/doc.html
55 | - How to set up a PXE server (DNSMASQ) https://www.tecmint.com/install-pxe-network-boot-server-in-centos-7/amp/
56 | - Raspberry Pi + PXE https://xunnanxu.github.io/2020/11/28/PXE-Boot-Diskless-Raspberry-Pi-4-With-Ubuntu-Ubiquiti-and-Synology-1-DHCP-Setup/
--------------------------------------------------------------------------------
/resources/ethswarm.md:
--------------------------------------------------------------------------------
1 | # Ethswarm
2 |
3 | ## Glossary
4 |
5 | * *Proximity order (PO).* The length of the longest prefix common to two addresses (considered as bit strings). Up to some simple transformations, this can be interpreted as a 2-adic valuation. For example, consider the address as a bitstring prefixed with $0.$, it represents a rational number expanded in binary.
6 |
7 | * *Neighbourhood of depth $d$*. A set of addresses having a common length $d$ prefix. A ball of $2$-adic radius $2^{-d}$ has depth $d$.
8 |
9 | * *DISC reserve size.* The total size of all outstanding (non-expired) postage batches.
10 |
11 | * *Reserve depth.* Rounded up base 2 logarithm of the reserve size. (Note h
12 |
13 | A quote that I don't understand (Book of Swarm, 3.3.4):
14 |
15 | > The base 2 logarithm of the DISC reserve size rounded up to the nearest integer is
16 | > called the reserve depth. The reserve depth is the shallowest PO such that disjoint
17 | > neighbourhoods of this depth are collectively able to accommodate the volume of
18 | > data corresponding to the total number of chunks paid for, assuming that nodes in
19 | > the neighbourhood have a fixed prescribed storage capacity to store their share of the
20 | > reserve.
21 |
22 | Questions.
23 |
24 | 1. How is reserve depth related to the size of a node's reserve? (I think the latter is hardcoded to 16GB while the former is a dynamic quantity depending on usage.)
25 | 2. A ball of depth $d$ has at least one expected chunk in its reserve if the reserve depth is at least $d$?
26 |
27 | * *Storage depth.* From the way people use this, I believe this is the rounded up base 2 logarithm of the number of uploaded chunks on Swarm.
28 |
29 | The presentation in the Book of Swarm is very confusing and appears contradictory to common usage:
30 |
31 | > A node’s storage depth is defined as the shallowest complete bin, i.e., the lowest PO
32 | > that compliant reserves stores all batch bins at. Unless the farthest bin in the node’s
33 | > reserve is complete, the storage depth equals the reserve’s edge PO plus one.
34 |
35 | * *Neighbourhood depth.* The depth of the smallest ball around a node $X$ that contains at least 3 other peers.
36 |
37 | Questions.
38 |
39 | 1. What does it mean if storage depth equals neighbourhood depth? It means that each neighbourhood (containing at least 4 nodes) hosts at least one chunk in expectation. If each node hosts all chunks in its 4-node neighbourhood, then this guarantees an expected replication rate of at least 4.
40 |
41 | * *Batch depth.* Base 2 logarithm of the number of postage stamps in a batch. (1 postage stamp goes on 1 chunk.)
42 |
43 | * *Uniformity depth.* Base 2 logarithm of the number of buckets [of a batch]. Should be higher than storage depth, so that each bucket is always contained entirely within the area of responsibility of a node.
44 |
45 | * *Postage batch* or *batch.* NFT that can be bought from the postage contract, representing the right to upload a particular number of chunks to each bucket.
46 |
47 | * *Batch bin.* Relative to a given node, the set of all chunks of a particular distance and paid for with a particular postage batch.
48 |
49 | * *Reserve.* Of a node $X$. A set of chunks $R$ satisfying the conditions:
50 |
51 | 1. If $c\in R$ and $d(X,c') < d(X,c)$ then $c\in R$.
52 | 2. If $c\in R$, $d(X,c) = d(X,c')$, and the balance remaining on the postage stamp attached to $c'$ exceeds that of $c$, then $c'\in R$.
53 | 3. $R$ is maximal with respect to these conditions and $|R|<\mathrm{SIZE}$.
54 |
55 | * *Reserve capacity.* The maximum size of the reserve, as hardcoded into the bee node. https://github.com/ethersphere/bee/blob/84b6eaad30b2823b61a141f21247e438ef101ac1/pkg/node/node.go#L177C8-L177C8
56 |
57 | * *Proof of density.* Commitment to a reserve sample via the salted BMT hash of its chunks. The proof "contains information regarding the size of the set from which this was sampled." Comment: the sample is constructed by choosing the first $k$ chunks in the order implied by the lexicographic ordering of their salted hashes. Since the image of this hash ought to be uniformly distributed, if there are $M$ chunks in the sample then the $k$th hash should be $k/M$ of the way into the hash codomain (in expectation).
58 |
59 | Questions.
60 |
61 | 1. Where is this defined formally?
62 | 2. Where is it implemented?
63 |
64 | * *Area of responsibility.* The neighbourhood of a node containing all batch bins of its reserve. (Also called *effective* area of responsibility (?)).
65 |
66 | ## Incentive structure
67 |
68 | - https://medium.com/ethereum-swarm/the-a-b-c-of-the-swarm-incentives-c53525fb55d5
69 | - Storage incentives paper is in the discord/research.
70 |
71 | Redistribution game.
72 |
73 | 1. Each round, a neighbourhood is selected using some entropy. This is called the *neighbourhood selection anchor.*
74 | 2. All staked nodes in the selected neighbourhood may submit a "reserve commitment" to the chunks they store. This commitment is twisted by a secret that the node will reveal later.
75 |
76 | ## BZZ/PLUR
77 |
78 | 16 decimals.
79 |
80 | questions
81 | 1. What is the role of dividing storage slots in a postage batch into buckets?
82 | 1a. In BoS \S3.3.1: "The referenced storage slot has the bucket specified and it aligns with
83 | the chunk address stamped." Concretely, what are these two conditions? Can you point me to the location in the bee source code where these are validated?
84 | 1b. The field "storage slot" in the Stamp data structure comprises a bucket index and a storage slot index within the bucket.
85 | https://github.com/ethersphere/bee/blob/master/pkg/postage/stamp.go
86 |
87 | A. The chunk address determines the index of the bucket it should go into. Thus slots in a particular bucket are stored in the same neighbourhood. Slots within a bucket are fungible (at least before being filled), but buckets are not.
88 |
89 | This makes it expensive to fill up a single neighbourhood excessively.
90 |
91 | Addresses:
92 |
93 | - Token tracker (Ethereum). https://etherscan.io/token/0x19062190b1925b5b6689d7073fdfc8c2976ef8cb
94 | - Token contract (Ethereum). https://etherscan.io/address/0x19062190b1925b5b6689d7073fdfc8c2976ef8cb
95 | - Bonding curve (Ethereum). Frontend is Bzzaar. https://etherscan.io/address/0x4F32Ab778e85C4aD0CEad54f8f82F5Ee74d46904
96 | - 1M DAI collateral.
97 | - Check price here using `buyPrice(1)` query (result in cents).
98 | - OpenBZZ exchange (Ethereum). Frontend openbzz.eth.limo. https://etherscan.io/address/0x69Defd0bdcDCA696042Ed75B00c10276c6D32A33
99 | - Token tracker (Gnosis, bridged through Omnibridge). https://gnosisscan.io/token/0xdbf3ea6f5bee45c02255b2c26a16f300502f68da
100 | - Omnibridge (GC). https://gnosisscan.io/address/0xf6a78083ca3e2a662d6dd1703c939c8ace2e268d
101 |
102 | Storage incentives:
103 |
104 | * Redistribution. https://gnosisscan.io/address/0x1F9a1FDe5c6350E949C5E4aa163B4c97011199B4
105 | * Staking. https://gnosisscan.io/address/0x781c6D1f0eaE6F1Da1F604c6cDCcdB8B76428ba7
106 |
107 | General information.
108 |
109 | - Docs. https://docs.ethswarm.org/docs/learn/faq#what-is-plur
110 |
111 | - Tokenomics. https://blog.ethswarm.org/hive/2021/bzz-tokenomics/
112 |
113 | - Circulating supply feed. https://tokenservice.ethswarm.org/circulating_supply
114 |
115 | (Approx. 63M last time I checked.)
116 |
117 | - Token sale. https://coinlist.co/swarm
118 |
119 | - Price feed. https://tokenservice.ethswarm.org/token_price
--------------------------------------------------------------------------------
/swarm.hash/628e277bae4fd88272dd751c852c22acaea9c147833ca0efe0d3a388a9aa8f8e:
--------------------------------------------------------------------------------
1 | Ethereum infrastructure appliance (v0.1)
2 |
--------------------------------------------------------------------------------
/swarm.hash/a89fdb4ea26157b48aef657b252d16f338be3e052738457546515f71a06a2b0f:
--------------------------------------------------------------------------------
1 | Ethereum infrastructure appliance (v0.0)
2 |
--------------------------------------------------------------------------------
/swarm.hash/e305446d58fb09914e3dd85977afc39df27caa41b58391cacb1b4b37497a48a9:
--------------------------------------------------------------------------------
1 | Swarm OS (DeBoot splash-only fake edition).
2 |
--------------------------------------------------------------------------------
/swarm.hash/ebf3182e6919289a088f175628924a28148528061c6a240293b7bb6300525642:
--------------------------------------------------------------------------------
1 | Fedora 37 w/ systemd networking
2 |
--------------------------------------------------------------------------------
/test.hash:
--------------------------------------------------------------------------------
1 | /bzz/ac28eaf69a6415a243d564ea69765ed8ee81faefc8b2e0b775fc54dbc32d8fa9/0/0/0.png
2 |
--------------------------------------------------------------------------------