Full Code of diglos/pi-gen for AI

ethraspbian2.0 b0452ca68627 cached
123 files
183.9 KB
60.9k tokens
1 requests
Download .txt
Showing preview only (212K chars total). Download the full file or copy to clipboard to get everything.
Repository: diglos/pi-gen
Branch: ethraspbian2.0
Commit: b0452ca68627
Files: 123
Total size: 183.9 KB

Directory structure:
gitextract_zctbo7w5/

├── .dockerignore
├── .gitignore
├── Dockerfile
├── LICENSE
├── README.md
├── build-docker.sh
├── build.sh
├── depends
├── docker-compose.yml
├── export-image/
│   ├── 00-allow-rerun/
│   │   └── 00-run.sh
│   ├── 01-set-sources/
│   │   └── 01-run.sh
│   ├── 02-network/
│   │   ├── 01-run.sh
│   │   └── files/
│   │       └── resolv.conf
│   ├── 03-set-partuuid/
│   │   └── 00-run.sh
│   ├── 04-finalise/
│   │   └── 01-run.sh
│   └── prerun.sh
├── export-noobs/
│   ├── 00-release/
│   │   ├── 00-run.sh
│   │   └── files/
│   │       ├── os.json
│   │       ├── partition_setup.sh
│   │       ├── partitions.json
│   │       └── release_notes.txt
│   └── prerun.sh
├── scripts/
│   ├── common
│   ├── dependencies_check
│   └── remove-comments.sed
├── stage0/
│   ├── 00-configure-apt/
│   │   ├── 00-run.sh
│   │   └── files/
│   │       ├── 51cache
│   │       ├── raspberrypi.gpg.key
│   │       ├── raspi.list
│   │       └── sources.list
│   ├── 01-locale/
│   │   ├── 00-debconf
│   │   └── 00-packages
│   ├── 02-firmware/
│   │   └── 01-packages
│   ├── files/
│   │   └── raspberrypi.gpg
│   └── prerun.sh
├── stage1/
│   ├── 00-boot-files/
│   │   ├── 00-run.sh
│   │   └── files/
│   │       ├── cmdline.txt
│   │       └── config.txt
│   ├── 01-sys-tweaks/
│   │   ├── 00-patches/
│   │   │   ├── 01-bashrc.diff
│   │   │   └── series
│   │   ├── 00-run.sh
│   │   └── files/
│   │       ├── fstab
│   │       └── noclear.conf
│   ├── 02-net-tweaks/
│   │   ├── 00-packages
│   │   ├── 00-patches/
│   │   │   ├── 01-hosts.diff
│   │   │   └── series
│   │   ├── 00-run.sh
│   │   └── files/
│   │       ├── hostname
│   │       └── interfaces
│   ├── 03-install-packages/
│   │   └── 00-packages
│   └── prerun.sh
├── stage2/
│   ├── 00-copies-and-fills/
│   │   ├── 01-packages
│   │   └── 02-run.sh
│   ├── 01-sys-tweaks/
│   │   ├── 00-debconf
│   │   ├── 00-packages
│   │   ├── 00-packages-nr
│   │   ├── 00-patches/
│   │   │   ├── 01-useradd.diff
│   │   │   ├── 02-swap.diff
│   │   │   ├── 04-inputrc.diff
│   │   │   ├── 05-path.diff
│   │   │   ├── 07-resize-init.diff
│   │   │   └── series
│   │   ├── 01-run.sh
│   │   └── files/
│   │       ├── 50raspi
│   │       ├── 90-qemu.rules
│   │       ├── console-setup
│   │       ├── rc.local
│   │       ├── resize2fs_once
│   │       └── ttyoutput.conf
│   ├── 02-net-tweaks/
│   │   ├── 00-packages
│   │   ├── 01-run.sh
│   │   └── files/
│   │       ├── wait.conf
│   │       └── wpa_supplicant.conf
│   ├── 03-accept-mathematica-eula/
│   │   └── 00-debconf
│   ├── 03-set-timezone/
│   │   └── 02-run.sh
│   ├── 04-ethereum/
│   │   ├── 00-packages
│   │   ├── 01-run.sh
│   │   └── files/
│   │       ├── armbian-ramlog
│   │       ├── armbian-zram-config.service
│   │       ├── dphys-swapfile
│   │       ├── ethonarm-rpi4-ubuntu64bit-install.sh
│   │       ├── ethonarm-rpi4-ubuntu64bit-setup.sh
│   │       ├── ethonarm.list
│   │       ├── grafana/
│   │       │   ├── prometheus
│   │       │   ├── prometheus-node-exporter
│   │       │   └── prometheus.yml
│   │       ├── grafana-eth2-onyx/
│   │       │   ├── prometheus
│   │       │   ├── prometheus-node-exporter
│   │       │   └── prometheus.yml
│   │       ├── init_resize.sh
│   │       ├── rc.local.eth1
│   │       ├── rc.local.eth2
│   │       ├── rc.local.eth2.medalla
│   │       ├── rc.local.eth2.onyx
│   │       ├── zram-default/
│   │       │   └── armbian-zram-config
│   │       └── zram-lib/
│   │           └── armbian-zram-config
│   ├── EXPORT_IMAGE
│   ├── EXPORT_NOOBS
│   └── prerun.sh
├── stage3/
│   ├── 00-install-packages/
│   │   ├── 00-debconf
│   │   ├── 00-packages
│   │   ├── 00-packages-nr
│   │   └── 01-run.sh
│   ├── 01-tweaks/
│   │   └── 00-run.sh
│   └── prerun.sh
├── stage4/
│   ├── 00-install-packages/
│   │   ├── 00-debconf
│   │   ├── 00-packages
│   │   ├── 00-packages-nr
│   │   ├── 01-packages
│   │   └── 02-packages
│   ├── 01-console-autologin/
│   │   └── 00-run.sh
│   ├── 02-extras/
│   │   └── 00-run.sh
│   ├── 03-magpi/
│   │   ├── 00-run.sh
│   │   └── files/
│   │       └── .gitignore
│   ├── 04-enable-xcompmgr/
│   │   └── 00-run.sh
│   ├── EXPORT_IMAGE
│   ├── EXPORT_NOOBS
│   └── prerun.sh
└── stage5/
    ├── 00-install-extras/
    │   └── 00-packages
    ├── 00-install-libreoffice/
    │   └── 00-packages
    ├── EXPORT_IMAGE
    ├── EXPORT_NOOBS
    └── prerun.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
output/
work/
deploy/
apt-cacher-ng/
.git/objects/*


================================================
FILE: .gitignore
================================================
deploy/*
work/*
config
postrun.sh
SKIP
SKIP_IMAGES
.pc
*-pc
apt-cacher-ng/


================================================
FILE: Dockerfile
================================================
FROM debian:buster

ENV DEBIAN_FRONTEND noninteractive

RUN apt-get -y update && \
    apt-get -y install \
        git vim parted \
        quilt coreutils qemu-user-static debootstrap zerofree zip dosfstools \
        bsdtar libcap2-bin rsync grep udev xz-utils curl xxd file kmod\
    && rm -rf /var/lib/apt/lists/*

COPY . /pi-gen/

VOLUME [ "/pi-gen/work", "/pi-gen/deploy"]


================================================
FILE: LICENSE
================================================
Copyright (c) 2015 Raspberry Pi (Trading) Ltd.

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: README.md
================================================
DISCLAIMER: This is a legacy repository. Please move to our new one:

https://github.com/diglos/ethereumonarm

Ethereum on ARM for Raspberry Pi 4 is a custom Linux image for the device that runs Ethereum clients as a boot service and automatically turns the Raspberry Pi 4 into a full Ethereum 1.0 node or a Ethereum 2.0 node. The image includes other components of the Ethereum ecosystem such as Status.im, Raiden, IPFS, Swarm and Vipnode.

For running a full Ethereum node on NanoPC-T4 or RockPro64 ARM64 devices, please see the Ethereum on ARM64 project

https://github.com/diglos/userpatches

**TL;DR:** **Flash your Raspberry Pi 4, plug in an ethernet cable, connect the SSD disk and power up the device to turn the Raspberry Pi 4 into a full Ethereum 1.0 node or an Ethereum 2.0 node (beacon chain / validator)**

Some background first. As you know, we’ve been running into some memory issues \[1\] with the Raspberry Pi 4 image as Raspbian OS is still on 32bits \[2\] (at least the userland). While we prefer to stick with the official OS we came to the conclusion that, in order to solve these issues, we need to migrate to a native 64 bits OS

Besides, Eth 2.0 clients don’t support 32 bits binaries so using Raspbian would exclude the Raspberry Pi 4 from running an Eth 2.0 node (and the possibility of staking).

So, after several tests we are now releasing 2 different images based on Ubuntu 20.04 64bit \[3\]: Eth 1.0 and Eth 2.0 editions.

Basically, both are the same image and include the same features of the Raspbian based images. But they are setup for running Eth 1.0 or Eth 2.0 software by default

**Images take care of all the necessary steps**, from setting up the environment and formatting the SSD disk to installing and running the Ethereum software as well as starting the blockchain synchronization.

# Main features

* Based on Ubuntu 20.04 64bit
* Automatic USB disk partitioning and formatting
* Adds swap memory (ZRAM kernel module + a swap file) based on Armbian work \[7\]
* Changes the hostname to something like “ethnode-e2a3e6fe” based on MAC hash
* Runs software as a systemd service and starts syncing the Blockchain
* Includes an APT repository for installing and upgrading Ethereum software
* Includes a monitoring dashboard based on Grafana / Prometheus

# Software included

Both images include the same packages, the only difference between them is that Eth 1.0 runs Geth by default and Eth 2.0 runs Prysm beacon chain by default.

**Ethereum 1.0 clients**

* Geth \[8\]: 1.9.13 (official binary)
* Parity \[9\]: 2.7.2 (cross compiled)
* Nethermind \[10\]: 1.8.28 (cross compiled)
* Hyperledger Besu \[11\]: 1.4.4 (compiled)

**Ethereum 2.0 clients**

* Prysm \[12\]: 1.0.0-alpha6 (official binary)
* Lighthouse \[13\]: 0.1.1 (compiled)

**Ethereum framework**

* Swarm \[14\]: 0.5.7 (official binary)
* Raiden Network \[15\]: 0.200.0\~rc1 (official binary)
* IPFS \[16\]: 0.5.0 (official binary)
* Statusd \[17\]: 0.52.3 (compiled)
* Vipnode \[18\]: 2.3.3 (official binary)

# INSTALLATION GUIDE AND USAGE

# Recommended hardware and setup

* Raspberry 4 (model B) - 4GB
* MicroSD Card (16 GB Class 10 minimun)
* SSD USB 3.0 disk (see storage section)
* Power supply
* Ethernet cable
* 30303 Port forwarding (Eth 1.0) and 13000 port forwarding (Eth 2.0) \[4\]
* A case with heatsink and fan (Optional but strongly recommended)
* USB keyboard, Monitor and HDMI cable (micro-HDMI) (Optional)

# Storage

You will need and SSD to run the Ethereum clients (without an SSD drive there’s absolutely no chance of syncing the Ethereum blockchain). There are 2 options:

* Use a USB portable SSD disk such as the Samsung T5 Portable SSD.
* Use a USB 3.0 External Hard Drive Case with a SSD Disk. In our case we used a Inateck 2.5 Hard Drive Enclosure FE2011. Make sure to buy a case with an UAS compliant chip, particularly, one of these: JMicron (JMS567 or JMS578) or ASMedia (ASM1153E).

In both cases, avoid getting low quality SSD disks as it is a key component of you node and it can drastically affect the performance (and sync times)

Keep in mind that you need to plug the disk to an USB 3.0 port (blue)

# Image download & installation

**1.- Download Eth 1.0 or Eth 2.0 images:**

[ubuntu-20.04-preinstalled-server-arm64+raspi-eth1.img.zip](https://ethraspbian.com/downloads/ubuntu-20.04-preinstalled-server-arm64+raspi-eth1.img.zip)

sha256 7fa9370d13857dd6abcc8fde637c7a9a7e3a66b307d5c28b0c0d29a09c73c55c 

[ubuntu-20.04-preinstalled-server-arm64+raspi-eth2.img.zip](https://ethraspbian.com/downloads/ubuntu-20.04-preinstalled-server-arm64+raspi-eth2.img.zip)

sha256 74c0c15b708720e5ae5cac324f1afded6316537fb17166109326755232cd316e

**2.- Flash the image**

Insert the microSD in your Desktop / Laptop and download the file (Eth 1.0, for instance):

    wget https://ethraspbian.com/downloads/ubuntu-20.04-preinstalled-server-arm64+raspi-eth1.img.zip

Note: If you are not comfortable with command line or if you are running Windows, you can use Etcher ([https://etcher.io](https://etcher.io/))

Open a terminal and check your MicroSD device name running:

    sudo fdisk -l

You should see a device named mmcblk0 or sdd. Unzip and flash the image:

    unzip https://ethraspbian.com/downloads/ubuntu-20.04-preinstalled-server-arm64+raspi-eth1.img.zip
    sudo dd bs=1M if=ubuntu-20.04-preinstalled-server-arm64+raspi-eth1.img of=/dev/mmcblk0 && sync

**3.- Insert de MicroSD into the Raspberry Pi 4. Connect an Ethernet cable and attach the USB SSD disk** (make sure you are using a blue port).

**4.- Power on the device**

The Ubuntu OS will boot up in less than one minute but **you will need to wait approximately 10 minutes** in order to allow the script to perform the necessary tasks to turn the device into an Ethereum node and reboot the Raspberry.

Depending on the image, you will be running:

* Eth 1.0: Geth as the default client syncing the blockchain
* Eth 2.0: Prysm as default client syncing the beacon chain (Topaz testnet)

**5.- Log in**

You can log in through SSH or using the console (if you have a monitor and keyboard attached)

    User: ethereum
    Password: ethereum

You will be prompted to change the password on first login, so you will need to login twice.

**6.- Open 30303 port for Geth and 13000 if you are running Prysm beacon chain.** If you don’t know how to do this, google “port forwarding” followed by your router model.

**7.- Getting console output**

You can see what’s happening in the background by typing:

    sudo tail -f /var/log/syslog

Congratulations. You are now running a full Ethereum node on your Raspberry Pi 4.

# Syncing the Blockchain

Now you need to wait for the blockchain to be synced. In the case of Eth 1.0 This will take a few days depending on several factors but you can expect up to about 5-7 days.

If you are running the Eth 2.0 Topaz tesnet you can expect 1-2 days of Beacon chain synchronization time. Remember that you will need to setup the validator later in order to start the staking process (see “How to run the Eth 2.0 validator” section below).

# Monitoring dashboards

For this first release, we included 3 monitoring dashboards based on Prometheus \[5\] / Grafana \[6\] in order to monitor the node and clients’ data (Geth and Besu). You can access through your web browser:

    URL: http://your_raspberrypi_IP:3000
    User: admin
    Password: ethereum

# Switching clients

All clients run as a systemd service. This is important because in case of some problem arises the system will respawn the process automatically.

Geth and Prysm beacon chain run by default (depending on what you are synchronizing, Eth 1.0 or Eth 2.0) so, if you want to switch to other clients (from Geth to Nethermind, for instance), you need to stop and disable Geth first, and enable and start the other client:

    sudo systemctl stop geth && sudo systemctl disable geth

Commands to enable and start each Eth 1.0 client:

    sudo systemctl enable besu && sudo systemctl start besu
    sudo systemctl enable nethermind && sudo systemctl start nethermind
    sudo systemctl enable parity && sudo systemctl start parity

Eth 2.0:

    sudo systemctl stop prysm-beacon && sudo systemctl disable prysm-beacon
    sudo systemctl start lighthouse-beacon && sudo systemctl enable lighthouse-beacon

# Changing parameters

Clients’ config files are located in the /etc/ethereum/ directory. You can edit these files and restart the systemd service in order for the changes to take effect. The only exception is Nethermind which, additionally, has a mainnet config file located here:

    /etc/nethermind/configs/mainnet.cfg

Blockchain clients’ data is stored on the ethereum home account as follows (note the dot before the directory name):

Eth 1.0

    /home/ethereum/.geth
    /home/ethereum/.parity
    /home/ethereum/.besu
    /home/ethereum/.nethermind

Eth2.0

    /home/ethereum/.eth2
    /home/ethereum/.eth2validators
    /home/ethereum/.lighthouse
    Hyperledger Besu and Nethermind

# Nethermind and Hyperledger Besu

These 2 great Eth 1.0 clients have become a great alternative to Geth and Parity. The more diversity in the network, the better, so you may give them a try and contribute to the network health.

Both need further testing so feel free to play with them and report back your feedback.

# How to run the Eth 2.0 validator (staking)

Once the Topaz testnet beacon chain is synchronized you can run a validator in the same device. You will need to follow the steps described here:

[https://prylabs.net/participate](https://prylabs.net/participate)

The first time, you need to create manually an account by running the “validator” binary and setup a password. Once you completed this step you can add the password to /etc/ethereum/prysm-validator.conf and start the validator as a systemd service

# Feeback appreciated

We put a lot of work trying to setup the Raspberry Pi 4 as a full Ethereum node as we know the massive user base of this device may have a very positive impact in the network.

Please, take into account that this is the first image based on Ubuntu 20.04 so there may be some bugs. If so, open an issue on Github or reach us on twitter ([https://twitter.com/EthereumOnARM](https://twitter.com/EthereumOnARM)).


================================================
FILE: build-docker.sh
================================================
#!/bin/bash -e

BUILD_OPTS="$*"

DOCKER="docker"
set +e
if ! $DOCKER ps >/dev/null 2>&1; then
	DOCKER="sudo docker"
fi
if ! $DOCKER ps >/dev/null; then
	echo "error connecting to docker:"
	$DOCKER ps
	exit 1
fi
set -e

if [ -f config ]; then
	# shellcheck disable=SC1091
	source config
fi

while getopts "c:" flag
do
	case "$flag" in
		c)
			# shellcheck disable=SC1090
			source "$OPTARG"
			;;
		*)
			;;
	esac
done

CONTAINER_NAME=${CONTAINER_NAME:-pigen_work}
CONTINUE=${CONTINUE:-0}
PRESERVE_CONTAINER=${PRESERVE_CONTAINER:-0}

if [ -z "${IMG_NAME}" ]; then
	echo "IMG_NAME not set in 'config'" 1>&2
	echo 1>&2
exit 1
fi

CONTAINER_EXISTS=$($DOCKER ps -a --filter name="$CONTAINER_NAME" -q)
CONTAINER_RUNNING=$($DOCKER ps --filter name="$CONTAINER_NAME" -q)
if [ "$CONTAINER_RUNNING" != "" ]; then
	echo "The build is already running in container $CONTAINER_NAME. Aborting."
	exit 1
fi
if [ "$CONTAINER_EXISTS" != "" ] && [ "$CONTINUE" != "1" ]; then
	echo "Container $CONTAINER_NAME already exists and you did not specify CONTINUE=1. Aborting."
	echo "You can delete the existing container like this:"
	echo "  $DOCKER rm -v $CONTAINER_NAME"
	exit 1
fi

$DOCKER build -t pi-gen .
if [ "$CONTAINER_EXISTS" != "" ]; then
	trap 'echo "got CTRL+C... please wait 5s"; $DOCKER stop -t 5 ${CONTAINER_NAME}_cont' SIGINT SIGTERM
	time $DOCKER run --rm --privileged \
		--volumes-from="${CONTAINER_NAME}" --name "${CONTAINER_NAME}_cont" \
		pi-gen \
		bash -e -o pipefail -c "dpkg-reconfigure qemu-user-static &&
	cd /pi-gen; ./build.sh ${BUILD_OPTS} ;
	rsync -av work/*/build.log deploy/" &
	wait "$!"
else
	trap 'echo "got CTRL+C... please wait 5s"; $DOCKER stop -t 5 ${CONTAINER_NAME}' SIGINT SIGTERM
	time $DOCKER run --name "${CONTAINER_NAME}" --privileged \
		pi-gen \
		bash -e -o pipefail -c "dpkg-reconfigure qemu-user-static &&
	cd /pi-gen; ./build.sh ${BUILD_OPTS} &&
	rsync -av work/*/build.log deploy/" &
	wait "$!"
fi
echo "copying results from deploy/"
$DOCKER cp "${CONTAINER_NAME}":/pi-gen/deploy .
ls -lah deploy

# cleanup
if [ "$PRESERVE_CONTAINER" != "1" ]; then
	$DOCKER rm -v "$CONTAINER_NAME"
fi

echo "Done! Your image(s) should be in deploy/"


================================================
FILE: build.sh
================================================
#!/bin/bash -e
# shellcheck disable=SC2119
run_sub_stage()
{
	log "Begin ${SUB_STAGE_DIR}"
	pushd "${SUB_STAGE_DIR}" > /dev/null
	for i in {00..99}; do
		if [ -f "${i}-debconf" ]; then
			log "Begin ${SUB_STAGE_DIR}/${i}-debconf"
			on_chroot << EOF
debconf-set-selections <<SELEOF
$(cat "${i}-debconf")
SELEOF
EOF

		log "End ${SUB_STAGE_DIR}/${i}-debconf"
		fi
		if [ -f "${i}-packages-nr" ]; then
			log "Begin ${SUB_STAGE_DIR}/${i}-packages-nr"
			PACKAGES="$(sed -f "${SCRIPT_DIR}/remove-comments.sed" < "${i}-packages-nr")"
			if [ -n "$PACKAGES" ]; then
				on_chroot << EOF
apt-get install --no-install-recommends -y $PACKAGES
EOF
			fi
			log "End ${SUB_STAGE_DIR}/${i}-packages-nr"
		fi
		if [ -f "${i}-packages" ]; then
			log "Begin ${SUB_STAGE_DIR}/${i}-packages"
			PACKAGES="$(sed -f "${SCRIPT_DIR}/remove-comments.sed" < "${i}-packages")"
			if [ -n "$PACKAGES" ]; then
				on_chroot << EOF
apt-get install -y $PACKAGES
EOF
			fi
			log "End ${SUB_STAGE_DIR}/${i}-packages"
		fi
		if [ -d "${i}-patches" ]; then
			log "Begin ${SUB_STAGE_DIR}/${i}-patches"
			pushd "${STAGE_WORK_DIR}" > /dev/null
			if [ "${CLEAN}" = "1" ]; then
				rm -rf .pc
				rm -rf ./*-pc
			fi
			QUILT_PATCHES="${SUB_STAGE_DIR}/${i}-patches"
			SUB_STAGE_QUILT_PATCH_DIR="$(basename "$SUB_STAGE_DIR")-pc"
			mkdir -p "$SUB_STAGE_QUILT_PATCH_DIR"
			ln -snf "$SUB_STAGE_QUILT_PATCH_DIR" .pc
			quilt upgrade
			if [ -e "${SUB_STAGE_DIR}/${i}-patches/EDIT" ]; then
				echo "Dropping into bash to edit patches..."
				bash
			fi
			RC=0
			quilt push -a || RC=$?
			case "$RC" in
				0|2)
					;;
				*)
					false
					;;
			esac
			popd > /dev/null
			log "End ${SUB_STAGE_DIR}/${i}-patches"
		fi
		if [ -x ${i}-run.sh ]; then
			log "Begin ${SUB_STAGE_DIR}/${i}-run.sh"
			./${i}-run.sh
			log "End ${SUB_STAGE_DIR}/${i}-run.sh"
		fi
		if [ -f ${i}-run-chroot.sh ]; then
			log "Begin ${SUB_STAGE_DIR}/${i}-run-chroot.sh"
			on_chroot < ${i}-run-chroot.sh
			log "End ${SUB_STAGE_DIR}/${i}-run-chroot.sh"
		fi
	done
	popd > /dev/null
	log "End ${SUB_STAGE_DIR}"
}


run_stage(){
	log "Begin ${STAGE_DIR}"
	STAGE="$(basename "${STAGE_DIR}")"
	pushd "${STAGE_DIR}" > /dev/null
	unmount "${WORK_DIR}/${STAGE}"
	STAGE_WORK_DIR="${WORK_DIR}/${STAGE}"
	ROOTFS_DIR="${STAGE_WORK_DIR}"/rootfs
	if [ ! -f SKIP_IMAGES ]; then
		if [ -f "${STAGE_DIR}/EXPORT_IMAGE" ]; then
			EXPORT_DIRS="${EXPORT_DIRS} ${STAGE_DIR}"
		fi
	fi
	if [ ! -f SKIP ]; then
		if [ "${CLEAN}" = "1" ]; then
			if [ -d "${ROOTFS_DIR}" ]; then
				rm -rf "${ROOTFS_DIR}"
			fi
		fi
		if [ -x prerun.sh ]; then
			log "Begin ${STAGE_DIR}/prerun.sh"
			./prerun.sh
			log "End ${STAGE_DIR}/prerun.sh"
		fi
		for SUB_STAGE_DIR in "${STAGE_DIR}"/*; do
			if [ -d "${SUB_STAGE_DIR}" ] &&
			   [ ! -f "${SUB_STAGE_DIR}/SKIP" ]; then
				run_sub_stage
			fi
		done
	fi
	unmount "${WORK_DIR}/${STAGE}"
	PREV_STAGE="${STAGE}"
	PREV_STAGE_DIR="${STAGE_DIR}"
	PREV_ROOTFS_DIR="${ROOTFS_DIR}"
	popd > /dev/null
	log "End ${STAGE_DIR}"
}

if [ "$(id -u)" != "0" ]; then
	echo "Please run as root" 1>&2
	exit 1
fi


if [ -f config ]; then
	# shellcheck disable=SC1091
	source config
fi

while getopts "c:" flag
do
	case "$flag" in
		c)
			EXTRA_CONFIG="$OPTARG"
			# shellcheck disable=SC1090
			source "$EXTRA_CONFIG"
			;;
		*)
			;;
	esac
done

export PI_GEN=${PI_GEN:-pi-gen}
export PI_GEN_REPO=${PI_GEN_REPO:-https://github.com/RPi-Distro/pi-gen}

if [ -z "${IMG_NAME}" ]; then
	echo "IMG_NAME not set" 1>&2
	exit 1
fi

export USE_QEMU="${USE_QEMU:-0}"
export IMG_DATE="${IMG_DATE:-"$(date +%Y-%m-%d)"}"
export IMG_FILENAME="${IMG_FILENAME:-"${IMG_DATE}-${IMG_NAME}"}"
export ZIP_FILENAME="${ZIP_FILENAME:-"image_${IMG_DATE}-${IMG_NAME}"}"

BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
export SCRIPT_DIR="${BASE_DIR}/scripts"
export WORK_DIR="${WORK_DIR:-"${BASE_DIR}/work/${IMG_DATE}-${IMG_NAME}"}"
export DEPLOY_DIR=${DEPLOY_DIR:-"${BASE_DIR}/deploy"}
export DEPLOY_ZIP="${DEPLOY_ZIP:-1}"
export LOG_FILE="${WORK_DIR}/build.log"

export FIRST_USER_NAME=${FIRST_USER_NAME:-pi}
export FIRST_USER_PASS=${FIRST_USER_PASS:-raspberry}
export WPA_ESSID
export WPA_PASSWORD
export WPA_COUNTRY
export ENABLE_SSH="${ENABLE_SSH:-0}"

export BASE_DIR

export CLEAN
export IMG_NAME
export APT_PROXY

export STAGE
export STAGE_DIR
export STAGE_WORK_DIR
export PREV_STAGE
export PREV_STAGE_DIR
export ROOTFS_DIR
export PREV_ROOTFS_DIR
export IMG_SUFFIX
export NOOBS_NAME
export NOOBS_DESCRIPTION
export EXPORT_DIR
export EXPORT_ROOTFS_DIR

export QUILT_PATCHES
export QUILT_NO_DIFF_INDEX=1
export QUILT_NO_DIFF_TIMESTAMPS=1
export QUILT_REFRESH_ARGS="-p ab"

# shellcheck source=scripts/common
source "${SCRIPT_DIR}/common"
# shellcheck source=scripts/dependencies_check
source "${SCRIPT_DIR}/dependencies_check"

dependencies_check "${BASE_DIR}/depends"

#check username is valid
if [[ ! "$FIRST_USER_NAME" =~ ^[a-z][-a-z0-9_]*$ ]]; then
	echo "Invalid FIRST_USER_NAME: $FIRST_USER_NAME"
	exit 1
fi

if [[ -n "${APT_PROXY}" ]] && ! curl --silent "${APT_PROXY}" >/dev/null ; then
	echo "Could not reach APT_PROXY server: ${APT_PROXY}"
	exit 1
fi

mkdir -p "${WORK_DIR}"
log "Begin ${BASE_DIR}"

STAGE_LIST=${STAGE_LIST:-${BASE_DIR}/stage*}

for STAGE_DIR in $STAGE_LIST; do
	STAGE_DIR=$(realpath "${STAGE_DIR}")
	run_stage
done

CLEAN=1
for EXPORT_DIR in ${EXPORT_DIRS}; do
	STAGE_DIR=${BASE_DIR}/export-image
	# shellcheck source=/dev/null
	source "${EXPORT_DIR}/EXPORT_IMAGE"
	EXPORT_ROOTFS_DIR=${WORK_DIR}/$(basename "${EXPORT_DIR}")/rootfs
	run_stage
	if [ "${USE_QEMU}" != "1" ]; then
		if [ -e "${EXPORT_DIR}/EXPORT_NOOBS" ]; then
			# shellcheck source=/dev/null
			source "${EXPORT_DIR}/EXPORT_NOOBS"
			STAGE_DIR="${BASE_DIR}/export-noobs"
			run_stage
		fi
	fi
done

if [ -x postrun.sh ]; then
	log "Begin postrun.sh"
	cd "${BASE_DIR}"
	./postrun.sh
	log "End postrun.sh"
fi

log "End ${BASE_DIR}"


================================================
FILE: depends
================================================
quilt
parted
realpath:coreutils
qemu-arm-static:qemu-user-static
debootstrap
zerofree
zip
mkdosfs:dosfstools
capsh:libcap2-bin
bsdtar
grep
rsync
xz:xz-utils
curl
xxd
file
git
lsmod:kmod


================================================
FILE: docker-compose.yml
================================================
version: '2'

services:
  apt-cacher-ng:
    restart: unless-stopped
    image: sameersbn/apt-cacher-ng:latest
    ports:
    - "3142:3142"
    volumes:
    - ./apt-cacher-ng:/var/cache/apt-cacher-ng


================================================
FILE: export-image/00-allow-rerun/00-run.sh
================================================
#!/bin/bash -e

if [ ! -x "${ROOTFS_DIR}/usr/bin/qemu-arm-static" ]; then
	cp /usr/bin/qemu-arm-static "${ROOTFS_DIR}/usr/bin/"
fi

if [ -e "${ROOTFS_DIR}/etc/ld.so.preload" ]; then
	mv "${ROOTFS_DIR}/etc/ld.so.preload" "${ROOTFS_DIR}/etc/ld.so.preload.disabled"
fi


================================================
FILE: export-image/01-set-sources/01-run.sh
================================================
#!/bin/bash -e

on_chroot << EOF
apt-get update
apt-get -y dist-upgrade
apt-get clean
EOF


================================================
FILE: export-image/02-network/01-run.sh
================================================
#!/bin/bash -e

install -m 644 files/resolv.conf "${ROOTFS_DIR}/etc/"


================================================
FILE: export-image/02-network/files/resolv.conf
================================================
nameserver 8.8.8.8


================================================
FILE: export-image/03-set-partuuid/00-run.sh
================================================
#!/bin/bash -e

IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"

IMGID="$(dd if="${IMG_FILE}" skip=440 bs=1 count=4 2>/dev/null | xxd -e | cut -f 2 -d' ')"

BOOT_PARTUUID="${IMGID}-01"
ROOT_PARTUUID="${IMGID}-02"

sed -i "s/BOOTDEV/PARTUUID=${BOOT_PARTUUID}/" "${ROOTFS_DIR}/etc/fstab"
sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${ROOTFS_DIR}/etc/fstab"

sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${ROOTFS_DIR}/boot/cmdline.txt"


================================================
FILE: export-image/04-finalise/01-run.sh
================================================
#!/bin/bash -e

IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
INFO_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.info"

on_chroot << EOF
/etc/init.d/fake-hwclock stop
hardlink -t /usr/share/doc
EOF

if [ -d "${ROOTFS_DIR}/home/${FIRST_USER_NAME}/.config" ]; then
	chmod 700 "${ROOTFS_DIR}/home/${FIRST_USER_NAME}/.config"
fi

rm -f "${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache"
rm -f "${ROOTFS_DIR}/usr/bin/qemu-arm-static"

if [ "${USE_QEMU}" != "1" ]; then
	if [ -e "${ROOTFS_DIR}/etc/ld.so.preload.disabled" ]; then
		mv "${ROOTFS_DIR}/etc/ld.so.preload.disabled" "${ROOTFS_DIR}/etc/ld.so.preload"
	fi
fi

rm -f "${ROOTFS_DIR}/etc/network/interfaces.dpkg-old"

rm -f "${ROOTFS_DIR}/etc/apt/sources.list~"
rm -f "${ROOTFS_DIR}/etc/apt/trusted.gpg~"

rm -f "${ROOTFS_DIR}/etc/passwd-"
rm -f "${ROOTFS_DIR}/etc/group-"
rm -f "${ROOTFS_DIR}/etc/shadow-"
rm -f "${ROOTFS_DIR}/etc/gshadow-"
rm -f "${ROOTFS_DIR}/etc/subuid-"
rm -f "${ROOTFS_DIR}/etc/subgid-"

rm -f "${ROOTFS_DIR}"/var/cache/debconf/*-old
rm -f "${ROOTFS_DIR}"/var/lib/dpkg/*-old

rm -f "${ROOTFS_DIR}"/usr/share/icons/*/icon-theme.cache

rm -f "${ROOTFS_DIR}/var/lib/dbus/machine-id"

true > "${ROOTFS_DIR}/etc/machine-id"

ln -nsf /proc/mounts "${ROOTFS_DIR}/etc/mtab"

find "${ROOTFS_DIR}/var/log/" -type f -exec cp /dev/null {} \;

rm -f "${ROOTFS_DIR}/root/.vnc/private.key"
rm -f "${ROOTFS_DIR}/etc/vnc/updateid"

update_issue "$(basename "${EXPORT_DIR}")"
install -m 644 "${ROOTFS_DIR}/etc/rpi-issue" "${ROOTFS_DIR}/boot/issue.txt"

cp "$ROOTFS_DIR/etc/rpi-issue" "$INFO_FILE"


{
	if [ -f "$ROOTFS_DIR/usr/share/doc/raspberrypi-kernel/changelog.Debian.gz" ]; then
		firmware=$(zgrep "firmware as of" \
			"$ROOTFS_DIR/usr/share/doc/raspberrypi-kernel/changelog.Debian.gz" | \
			head -n1 | sed  -n 's|.* \([^ ]*\)$|\1|p')
		printf "\nFirmware: https://github.com/raspberrypi/firmware/tree/%s\n" "$firmware"

		kernel="$(curl -s -L "https://github.com/raspberrypi/firmware/raw/$firmware/extra/git_hash")"
		printf "Kernel: https://github.com/raspberrypi/linux/tree/%s\n" "$kernel"

		uname="$(curl -s -L "https://github.com/raspberrypi/firmware/raw/$firmware/extra/uname_string7")"
		printf "Uname string: %s\n" "$uname"
	fi

	printf "\nPackages:\n"
	dpkg -l --root "$ROOTFS_DIR"
} >> "$INFO_FILE"

ROOT_DEV="$(mount | grep "${ROOTFS_DIR} " | cut -f1 -d' ')"

unmount "${ROOTFS_DIR}"
zerofree "${ROOT_DEV}"

unmount_image "${IMG_FILE}"

mkdir -p "${DEPLOY_DIR}"

rm -f "${DEPLOY_DIR}/${ZIP_FILENAME}${IMG_SUFFIX}.zip"
rm -f "${DEPLOY_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"

if [ "${DEPLOY_ZIP}" == "1" ]; then
	pushd "${STAGE_WORK_DIR}" > /dev/null
	zip "${DEPLOY_DIR}/${ZIP_FILENAME}${IMG_SUFFIX}.zip" \
		"$(basename "${IMG_FILE}")"
	popd > /dev/null
else
	cp "$IMG_FILE" "$DEPLOY_DIR"
fi

cp "$INFO_FILE" "$DEPLOY_DIR"


================================================
FILE: export-image/prerun.sh
================================================
#!/bin/bash -e

IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"

unmount_image "${IMG_FILE}"

rm -f "${IMG_FILE}"

rm -rf "${ROOTFS_DIR}"
mkdir -p "${ROOTFS_DIR}"

BOOT_SIZE="$((256 * 1024 * 1024))"
TOTAL_SIZE=$(du --apparent-size -s "${EXPORT_ROOTFS_DIR}" --exclude var/cache/apt/archives --block-size=1 | cut -f 1)

ROUND_SIZE="$((4 * 1024 * 1024))"
ROUNDED_ROOT_SECTOR=$(((BOOT_SIZE + ROUND_SIZE) / ROUND_SIZE * ROUND_SIZE / 512 + 8192))
IMG_SIZE=$(((BOOT_SIZE + TOTAL_SIZE + (800 * 1024 * 1024) + ROUND_SIZE - 1) / ROUND_SIZE * ROUND_SIZE))

truncate -s "${IMG_SIZE}" "${IMG_FILE}"
fdisk -H 255 -S 63 "${IMG_FILE}" <<EOF
o
n


8192
+$((BOOT_SIZE / 512))
p
t
c
n


${ROUNDED_ROOT_SECTOR}


p
w
EOF

PARTED_OUT=$(parted -sm "${IMG_FILE}" unit b print)
BOOT_OFFSET=$(echo "$PARTED_OUT" | grep -e '^1:' | cut -d':' -f 2 | tr -d B)
BOOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^1:' | cut -d':' -f 4 | tr -d B)

ROOT_OFFSET=$(echo "$PARTED_OUT" | grep -e '^2:' | cut -d':' -f 2 | tr -d B)
ROOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^2:' | cut -d':' -f 4 | tr -d B)

BOOT_DEV=$(losetup --show -f -o "${BOOT_OFFSET}" --sizelimit "${BOOT_LENGTH}" "${IMG_FILE}")
ROOT_DEV=$(losetup --show -f -o "${ROOT_OFFSET}" --sizelimit "${ROOT_LENGTH}" "${IMG_FILE}")
echo "/boot: offset $BOOT_OFFSET, length $BOOT_LENGTH"
echo "/:     offset $ROOT_OFFSET, length $ROOT_LENGTH"

ROOT_FEATURES="^huge_file"
for FEATURE in metadata_csum 64bit; do
	if grep -q "$FEATURE" /etc/mke2fs.conf; then
	    ROOT_FEATURES="^$FEATURE,$ROOT_FEATURES"
	fi
done
mkdosfs -I -n boot -F 32 -v "$BOOT_DEV" > /dev/null
mkfs.ext4 -L rootfs -O "$ROOT_FEATURES" "$ROOT_DEV" > /dev/null

mount -v "$ROOT_DEV" "${ROOTFS_DIR}" -t ext4
mkdir -p "${ROOTFS_DIR}/boot"
mount -v "$BOOT_DEV" "${ROOTFS_DIR}/boot" -t vfat

rsync -aHAXx --exclude /var/cache/apt/archives --exclude /boot "${EXPORT_ROOTFS_DIR}/" "${ROOTFS_DIR}/"
rsync -rtx "${EXPORT_ROOTFS_DIR}/boot/" "${ROOTFS_DIR}/boot/"


================================================
FILE: export-noobs/00-release/00-run.sh
================================================
#!/bin/bash -e

NOOBS_DIR="${STAGE_WORK_DIR}/${IMG_DATE}-${IMG_NAME}${IMG_SUFFIX}"

install -v -m 744	files/partition_setup.sh	"${NOOBS_DIR}/"
install -v		files/partitions.json		"${NOOBS_DIR}/"
install -v		files/os.json			"${NOOBS_DIR}/"
install -v		files/OS.png			"${NOOBS_DIR}/"
install -v		files/release_notes.txt		"${NOOBS_DIR}/"

tar -v -c -C		files/marketing			-f "${NOOBS_DIR}/marketing.tar" .

BOOT_SHASUM="$(sha256sum "${NOOBS_DIR}/boot.tar.xz" | cut -f1 -d' ')"
ROOT_SHASUM="$(sha256sum "${NOOBS_DIR}/root.tar.xz" | cut -f1 -d' ')"

BOOT_SIZE="$(xz --robot -l "${NOOBS_DIR}/boot.tar.xz"  | grep totals | cut -f 5)"
ROOT_SIZE="$(xz --robot -l "${NOOBS_DIR}/root.tar.xz"  | grep totals | cut -f 5)"

BOOT_SIZE="$(( BOOT_SIZE / 1024 / 1024 + 1))"
ROOT_SIZE="$(( ROOT_SIZE / 1024 / 1024 + 1))"

BOOT_NOM="256"
ROOT_NOM="$(( ROOT_SIZE + 400 ))"

mv "${NOOBS_DIR}/OS.png" "${NOOBS_DIR}/${NOOBS_NAME// /_}.png"

sed "${NOOBS_DIR}/partitions.json" -i -e "s|BOOT_SHASUM|${BOOT_SHASUM}|"
sed "${NOOBS_DIR}/partitions.json" -i -e "s|ROOT_SHASUM|${ROOT_SHASUM}|"

sed "${NOOBS_DIR}/partitions.json" -i -e "s|BOOT_SIZE|${BOOT_SIZE}|"
sed "${NOOBS_DIR}/partitions.json" -i -e "s|ROOT_SIZE|${ROOT_SIZE}|"

sed "${NOOBS_DIR}/partitions.json" -i -e "s|BOOT_NOM|${BOOT_NOM}|"
sed "${NOOBS_DIR}/partitions.json" -i -e "s|ROOT_NOM|${ROOT_NOM}|"

sed "${NOOBS_DIR}/os.json" -i -e "s|UNRELEASED|${IMG_DATE}|"
sed "${NOOBS_DIR}/os.json" -i -e "s|NOOBS_NAME|${NOOBS_NAME}|"
sed "${NOOBS_DIR}/os.json" -i -e "s|NOOBS_DESCRIPTION|${NOOBS_DESCRIPTION}|"

sed "${NOOBS_DIR}/release_notes.txt" -i -e "s|UNRELEASED|${IMG_DATE}|"

cp -a "${NOOBS_DIR}" "${DEPLOY_DIR}/"


================================================
FILE: export-noobs/00-release/files/os.json
================================================
{
    "description": "NOOBS_DESCRIPTION",
    "feature_level": 35120124,
    "kernel": "4.19",
    "name": "NOOBS_NAME",
    "password": "raspberry",
    "release_date": "UNRELEASED",
    "supported_hex_revisions": "2,3,4,5,6,7,8,9,d,e,f,10,11,12,14,19,1040,1041,0092,0093,2082",
    "supported_models": [
        "Pi Model",
        "Pi 2",
        "Pi Zero",
        "Pi 3",
        "Pi Compute Module 3",
        "Pi 4"
    ],
    "url": "http://www.raspbian.org/",
    "username": "pi",
    "version": "buster"
}


================================================
FILE: export-noobs/00-release/files/partition_setup.sh
================================================
#!/bin/sh
#supports_backup in PINN

set -ex

# shellcheck disable=SC2154
if [ -z "$part1" ] || [ -z "$part2" ]; then
  printf "Error: missing environment variable part1 or part2\n" 1>&2
  exit 1
fi

mkdir -p /tmp/1 /tmp/2

mount "$part1" /tmp/1
mount "$part2" /tmp/2

sed /tmp/1/cmdline.txt -i -e "s|root=[^ ]*|root=${part2}|"
sed /tmp/2/etc/fstab -i -e "s|^[^#].* / |${part2}  / |"
sed /tmp/2/etc/fstab -i -e "s|^[^#].* /boot |${part1}  /boot |"

# shellcheck disable=SC2154
if [ -z "$restore" ]; then
  if [ -f /mnt/ssh ]; then
    cp /mnt/ssh /tmp/1/
  fi

  if [ -f /mnt/ssh.txt ]; then
    cp /mnt/ssh.txt /tmp/1/
  fi

  if [ -f /settings/wpa_supplicant.conf ]; then
    cp /settings/wpa_supplicant.conf /tmp/1/
  fi

  if ! grep -q resize /proc/cmdline; then
    if ! grep -q splash /tmp/1/cmdline.txt; then
      sed -i "s| quiet||g" /tmp/1/cmdline.txt
    fi
    sed -i 's| init=/usr/lib/raspi-config/init_resize.sh||' /tmp/1/cmdline.txt
  else
    sed -i '1 s|.*|& sdhci.debug_quirks2=4|' /tmp/1/cmdline.txt
  fi
fi

umount /tmp/1
umount /tmp/2


================================================
FILE: export-noobs/00-release/files/partitions.json
================================================
{
    "partitions": [
        {
            "filesystem_type": "FAT",
            "label": "boot",
            "mkfs_options": "-F 32",
            "partition_size_nominal": BOOT_NOM,
            "uncompressed_tarball_size": BOOT_SIZE,
            "want_maximised": false,
            "sha256sum": "BOOT_SHASUM"
        },
        {
            "filesystem_type": "ext4",
            "label": "root",
            "mkfs_options": "-O ^huge_file",
            "partition_size_nominal": ROOT_NOM,
            "uncompressed_tarball_size": ROOT_SIZE,
            "want_maximised": true,
            "sha256sum": "ROOT_SHASUM"
        }
    ]
}


================================================
FILE: export-noobs/00-release/files/release_notes.txt
================================================
UNRELEASED:
  *
2019-06-20:
  * Based on Debian Buster
  * Support for Raspberry Pi 4 hardware
  * FKMS OpenGL desktop graphics driver and xcompmgr compositing window manager used when running on Raspberry Pi 4
  * Screen Configuration application added for use with FKMS driver
  * Raspberry Pi 4 video output options added to Raspberry Pi Configuration
  * Uses new PiXflat UI theme for GTK and Openbox
  * CPU activity gauge plugin no longer shown on taskbar by default
  * CPU temperature gauge plugin added (not shown by default)
  * USB ejecter and Bluetooth taskbar icons hidden when not appropriate
  * Version 74.0.3729.157 of Chromium web browser included
  * Version 32.0.0.207 of Flash player included
  * IDLE Python IDE removed
  * Wolfram Mathematica removed temporarily due to incompatibility with Buster
  * Display of package sizes removed from Recommended Software
  * Appearance Settings modified to support independent settings for two monitors
  * Oracle Java 7 and 8 replaced with OpenJDK 11
  * Miscellaneous small bug fixes
  * On-board 5GHz WiFi blocked by rfkill by default
    The block is removed when taking one of the following actions:
    - Selecting a locale in the first run wizard
    - Setting the WiFi country in the Raspberry Pi Configuration tool or the Network Settings applet
    - Setting the WiFi country in raspi-config
    - Providing a wpa_supplicant.conf file through the boot partition
    - Running 'rfkill unblock wifi'
  * Boot partition size set to 256M
  * Linux kernel 4.19.50
  * Raspberry Pi firmware 88ca9081f5e51cdedd16d5dbc85ed12a25123201
2019-04-08:
  * Chromium browser updated to version 72
  * VLC media player updated to version 3.0.6
  * RealVNC Server updated to version 6.4.0
  * Flash player updated to version 32.0.0.156
  * Performance improvements to SDL library
  * Performance improvements to pixman library
  * Option to set display underscan added to startup wizard
  * Mounted external drives now displayed on desktop by default
  * Network plugin modified for improved compatibility with wpa_passphrase
  * SD Card Copier tweaks to reduce copy failures
  * Various minor bug fixes and appearance tweaks
  * Added ethtool
  * Added rng-tools
  * Add PINN restore support
  * Linux kernel 4.14.98
  * Raspberry Pi firmware f8939644f7bd3065068787f1f92b3f3c79cf3de9
2018-11-13:
  * Two versions of image created - "base" image has no optional software packages included; "full" image has all optional packages
    - Removed from "base" image - LibreOffice, Thonny, Scratch, Scratch 2, Sonic Pi, Minecraft, Python Games, SmartSim, SenseHAT Emulator
    - Added to "full" image - Mathematica, BlueJ, Greenfoot, Node-RED, Claws Mail, VNC Viewer
  * Python Games and SmartSim added to Recommended Software
  * VLC media player with VideoCore hardware acceleration included in image
  * Version 3.0.5 of Thonny included
  * Modifications to LXDE components to enable local configuration to override global configuration correctly
  * Modifications to Appearance Settings to support above configuration changes
  * Modifications to various initial config defaults and relevant package to support above configuration changes
  * Selecting default option in Appearance Settings now deletes relevant local configuration files
  * PiX theme modified so that all changes made in Appearance Settings are in override files rather than in theme files
  * Design of scrollbar buttons changed
  * Image Viewer moved into Graphics category on main menu
  * Recommended Software now installs LibreOffice language support files if needed, and suggests reboot if needed
  * Latest version of Pepper Flash plugin included
  * Chromium h264ify plugin permissions set correctly by default
  * Corrections to various MIME types so that files open in sensible default applications
  * Set default timezone to 'Europe/London'
  * Linux kernel 4.14.79
  * Raspberry Pi firmware 12e0bf86e08d6067372bc0a45d7e8a10d3113210
2018-10-09:
  * Raspberry Pi 3A+ support
  * In startup wizard, assign keyboard to country as per Debian installer recommendations
  * In startup wizard, add option to use US keyboard in preference to country-specific option
  * In startup wizard, show IP address on first page
  * In startup wizard, check for existing wifi network connection and show it if there is one
  * In startup wizard, install language support packages for LibreOffice and other applications
  * In startup wizard, improve operation with keyboard only and no mouse
  * Password change in Raspberry Pi Configuration and startup wizard now works properly if passwords contain shell characters
  * Battery indicator plugin modified to cope with Pi-top hardware monitor crashing
  * Networking plugin hides wifi password characters by default
  * In Scratch 2 GPIO plugin, set pin from dropdown list rather than free text
  * In Scratch 2 SenseHAT plugin, swap x and y axis values for LED array
  * Include latest Adobe Flash player (31.0.0.108)
  * Include latest RealVNC Server (6.3.1)
  * Include libav-tools
  * Include ssh-import-id
  * Removed Mathematica
  * Merge in latest third-party code for Bluetooth ALSA interface
  * Add ability to prevent software update changing configuration files, by creating ~/.config/.lock file
  * Various other small bug fixes, tweaks and changes to text
  * Make dhcpcd work with 3G devices
  * Add hw acceleration to ffmpeg
  * Improved WiFi-BT coexistence parameters
  * Run fake-hwclock before systemd-fsck-root
  * Raspberry Pi PoE HAT support
  * Linux kernel 4.14.71
  * Raspberry Pi firmware 5b49caa17e91d0e64024380119ad739bb201c674
2018-06-27:
  * New first-boot configuration wizard added
  * Recommended Software installer added
  * Bluej, Greenfoot, NodeRED, Claws Mail, VNC Viewer removed from image - can now be installed from Recommended Applications
  * Qpdfview PDF viewer installed instead of Xpdf
  * Version 65.0 of Chromium browser included, with latest Flash player
  * Volume up / down keys now change by 5% increments and affect currently-selected output device rather than internal device only
  * Network plugin now remembers previously-entered WiFi network passwords when prompting for reconnection
  * Serial port and serial console can now be switched separately in Raspberry Pi Configuration
  * Lxkeymap keyboard language setting application removed - replaced with dialog within Raspberry Pi Configuration
  * Wifi country and keyboard language setting dialogs in Raspberry Pi Configuration now callable from other applications
  * New version of Piboto font included to render with correct weight under some rogue applications
  * Reconnection to Bluetooth audio devices on reboot improved
  * Disable click-to-rename behaviour in file manager if single-click selection enabled
  * Appearance Settings dialog makes config changes to some Qt files to match selected theme
  * MIME file type associations improved
  * Multiple desktop management options removed from mouse middle-click menu
  * Menu shortcuts to Raspberry Pi website amended
  * Python 2 IDLE menu link removed
  * Sample Magpi PDF installed in /home/pi/MagPi
  * Various minor tweaks, bug fixes and appearance changes
  * Bluetooth updates
    - Firmware with Bluetooth 4.2 features
    - SCO profile suppot added via bthelper.service
  * Linux kernel 4.14.50+
  * Raspberry Pi firmware 748fb17992426bb29d99224b93cb962fefbdc833
2018-04-18:
  * Fixed race between wifi-country.service and raspberrypi-net-mods.service
  * Linux kernel 4.14.34+
  * Raspberry Pi firmware 5db8e4e1c63178e200d6fbea23ed4a9bf4656658
2018-03-13:
  * Raspberry Pi 3 B+ support
  * WiFi is disabled until wireless regulatory domain is set (Pi 3 B+ only)
    - The domain can be done through 'Raspberry Pi Configuration' (rc_gui),
      'raspi-config' or by setting 'country=' to an appropriate ISO 3166
      alpha2 country code in /etc/wpa_supplicant/wpa_supplicant.conf.
  * Default wireless regulatory domain is now unset
  * Added support to desktop for different screen sizes and resolutions,
    including multiple preset options in Appearance Settings and pixel doubling
    option in Raspberry Pi Configuration
  * Version 2.1.16 of Thonny included
  * Version 29.0.0.113 of Adobe PepperFlash player included
  * Version 1.2.post1 of Pygame Zero included
  * Bluetooth plugin now supports connection to Bluetooth LE HID devices
  * Network plugin now indicates 5G-compatible APs
  * Latest changes to Bluez ALSA service merged
    - service now started on CLI boot as well as GUI boot
  * Latest changes to dhcpcd networking plugin merged
  * Improved support for running on pi-top devices
  * Small design changes to PiX theme and icons
  * Bug fix - hide spurious window resize handles
  * Bug fix - Scratch 2 remote GPIO state block now works correctly
  * Updated WiFi Firmware
    - brcmfmac43455-sdio 7.45.154
    - brcmfmac43430-sdio 7.45.98.38
  * New packages:
    - policykit-1
    - obconf
    - python-buttonshim python3-buttonshim
    - python-unicornhathd  python3-unicornhathd
    - python-pantilthat python3-pantilthat
  * Linux kernel 4.9.80+
  * Raspberry Pi firmware 3347884c7df574bbabeff6dca63caf686e629699
2017-11-29:
  * Added battery monitor plugin for taskbar - works on x86 images or first-generation Pi-Top
  * Added cutdown mode to PCManFM file manager to reduce complexity
  * Added ability to rename files in PCManFM by clicking name when selected
  * Bug fix in Bluetooth ALSA module to reduce truncation of audio at end of playback
  * Various small tweaks, bug fixes and theme modifications
  * New kernel and firmware
2017-09-07:
  * Disable predictable network interface names for Ethernet devices
  * Bug fix for keyboard settings dialog in Raspberry Pi Configuration
  * Bug fix for crash on some videos and animations in Chromium
  * Bug fix for taskbar crash when running RealVNC server
  * Bug fix for reloading projects with extensions in Scratch 2
  * Bug fix for MAC address problem in Bluetooth
  * Simple mode and new icons in Thonny
  * New Japanese translations in Raspberry Pi Configuration
  * Install fonts-droid-fallback for international fonts
2017-08-16:
  * Based on Raspbian Stretch (Debian version 9)
  * Version 60 of Chromium browser included
  * Version 3.0.1 of Sonic Pi included
  * Version 6.1.1 of RealVNC included
  * Version 0.17.4 of NodeRED included
  * Bluetooth audio routed via ALSA rather than Pulseaudio
  * SenseHAT extension added to Scratch 2
  * Various desktop applications modified to prompt for sudo password if needed
  * lxinput control options for mouse speed simplified
  * lxpanel plugins moved into separate packages
  * Wireless firmware for Pi 3 and Pi 0W modified to address Broadpwn exploit
  * Latest kernel and firmware
  * Various small tweaks, bug fixes and theme modifications
2017-07-05:
  * New kernel and firmware
  * Filesystem created without the metadata_csum feature
2017-06-21:
  * Scratch 2 application included
  * Thonny Python IDE included
  * New icons with thinner outlines
  * Volume control more linear in behaviour
  * Updated Flash player
  * Updated RealVNC server and viewer
  * Various tweaks and bugfixes
  * New kernel and firmware
2017-04-10:
  * Wolfram Mathematica updated to version 11.0.1
  * Adobe Flash Player updated to version 25.0.0.127
  * Use PARTUUID to support USB boot
2017-03-02:
  * Updated kernel and firmware (final Pi Zero W support)
  * Wolfram Mathematica updated to version 11
  * NOOBS installs now checks for presence of 'ssh' file on the NOOBS partition.
2017-02-16:
  * Chromium browser updated to version 56
  * Adobe Flash Player updated to version 24.0.0.221
  * RealVNC Server and Viewer updated to version 6.0.2 (RealVNC Connect)
  * Sonic Pi updated to version 2.11
  * Node-RED updated to version 0.15.3
  * Scratch updated to version 120117
  * Detection of SSH enabled with default password moved into PAM
  * Updated desktop GL driver to support use of fake KMS option
  * Raspberry Pi Configuration and raspi-config allow setting of fixed HDMI resolution
  * raspi-config allows enabling of serial hardware independent of serial terminal
  * Updates to kernel and firmware
  * Various minor bug fixes and usability and appearance tweaks
2017-01-11:
  * Re-release of the 2016-11-25 image with a FAT32-formatted boot partition
2016-11-25:
  * SSH disabled by default; can be enabled by creating a file with name "ssh" in boot partition
  * Prompt for password change at boot when SSH enabled with default password unchanged
  * Adobe Flash Player included
  * Updates to hardware video acceleration in Chromium browser
  * Greeter now uses background image from last set in Appearance Settings rather than pi user
  * Updated version of Scratch
  * Rastrack option removed from raspi-config and Raspberry Pi Configuration
  * Ability to disable graphical boot splash screen added to raspi-config and Raspberry Pi Configuration
  * Appearance Settings dialog made tabbed to work better on small screens
  * Raspberry Pi Configuration now requires current password to change password
  * Various small bug fixes
  * Updated firmware and kernel
2016-09-23:
  * New PIXEL desktop environment - new icon set, window design, desktop images, splash screen and greeter
  * Chromium web browser included
  * Infinality font rendering patches included
  * RealVNC server and viewer included
  * SenseHAT emulator included
  * Rfkill entries added to Wifi and Bluetooth panel plugins
  * Updates to various standard applications, including Scratch and NodeRED
  * Various bug fixes, tweaks and translation updates
  * Updated firmware and kernel (https://github.com/raspberrypi/firmware/commit/ad8608c08b122b2c228dba0ff5070d6e9519faf5)
2016-05-27:
  * Fixed crash of lxpanel when D-bus not accessible
  * Fixed permissions for D-bus Bluetooth access
  * Removed sudo from shutdown options
  * Appearance of tooltips updated in theme
  * Fixed ejecter plugin grabbing focus
  * raspi-config command line and GUI apps tidied; unnecessary reboots removed
  * More error detection in piclone; copying of volume names and IDs added
  * Updated translation files
2016-05-10:
  * New version of Scratch, which no longer requires sudo
  * New version of BlueJ
  * New version of NodeRED
  * New version of pypy
  * pigpio included
  * geany editor included
  * SD Card Copier added (can be used to duplicate or back up the Pi)
  * Bluetooth plugin added to taskbar
  * Volume control on taskbar now compatible with Bluetooth devices
  * New shutdown helper application
  * Mouse double-click speed setting added to mouse and keyboard preference application
  * Option to enable / disable 1-wire interface and remote access to pigpio added to Raspberry Pi config application
  * File system automatically expanded on first boot
  * Empty Wastebasket option added to right-click menu 
  * Ctrl-Alt-T can be used to open a terminal window
  * Various small bug fixes and appearance tweaks 
  * Updated firmware and kernel (https://github.com/raspberrypi/firmware/commit/cc6d7bf8b4c03a2a660ff9fdf4083fc165620866)
2016-03-18:
  * updated firmware and kernel (https://github.com/raspberrypi/firmware/commit/951799bbcd795ddf27769d14acf4813fdcbe53dc)
  * use serial0 in cmdline.txt
  * wpa_supplicant.conf country default to GB (allows use of channels 12 and 13)
2016-02-26:
  * Support added for Pi 3, including Wifi and Bluetooth
  * Option to set wifi country code added to raspi-config
2016-02-09:
  * dtb that uses mmc sdcard driver (fixes problems experienced with certain SD cards)
2016-02-03:
  * new version of Sonic Pi (2.9)
  * new version of Scratch (15/1/16)
  * new version of Node-Red (2.5)
  * new version of Wolfram (10.3)
  * optional experimental GL desktop driver (can be enabled using advanced options in command-line raspi-config)
  * new version of Java (1.8.0_65)
  * new version of WiringPi
  * raspi-gpio included
  * ping no longer requires sudo (except NOOBS installs)
  * support for more USB audio devices in lxpanel
  * bug fix for creation of new menus in Alacarte
  * various changes to raspi-config and GUI to tidy up board support and fix bugs, and updated translations
  * small tweaks to theme to support GL driver
2015-11-21:
  * Included IBM Node-RED IoT application
  * Included graphical package manager
  * Included accelerated pixman library
  * Updated Epiphany browser to improve video compatibility
  * Updated Scratch with performance improvements and bug fixes
  * Updated Raspberry Pi configuration to allow boot to pause while
    network is established
  * Various minor bug fixes
2015-09-25:
  * Based on Debian Jessie
  * Upgraded applications - Epiphany browser, Scratch and Sonic Pi
  * Included applications - LibreOffice, Claws Mail, Greenfoot, BlueJ
  * Included utilities - Alacarte menu editor, Lxkeymap, scrot, tree, pip
  * New GUI-based Raspberry Pi Configuration application
  * GPIO control now possible without need for sudo
  * Web link to Magpi magazine included
  * New taskbar plugin to eject mounted USB drives
  * Default boot is now to GUI not desktop
  * Look and feel now based on GTK+3 default theme
  * Print screen key launches scrot to produce screenshot
  * Common keyboards autodetected by GUI and drivers loaded accordingly
  * Numerous small tweaks and bugfixes
2015-05-05:
  * Updated UI changes
  * Updated firmware
  * Install raspberrypi-net-mods
  * Install avahi-daemon
  * Add user pi to new i2c and spi groups
  * Modified udev rules for i2c and spi devices
2015-02-16:
  * Newer firmware with various fixes
  * New Sonic Pi release
  * Pi2 compatible RPi.GPIO
  * Updated Wolfram Mathematica
2015-01-31:
  * Support for Pi2
  * Newer firmware
  * New Sonic Pi release
  * Updated Scratch
  * New Wolfram Mathematica release
  * Updated Epiphany
2014-12-24:
  * Fix regression with omission of python-pygame
2014-12-22:
  * New firmware with variosu fixes and improvements
  * New UI configuration for lxde
  * Various package updates
  * python3-pygame preinstalled
  * 'nuscratch', scratch running on the Cog StackVM
  * Misc other changes
2014-09-09:
  * New firmware with various fixes and improvements
  * Minecraft Pi pre-installed
  * Sonic Pi upgraded to 2.0
  * Include Epiphany browser work from Collabora
  * Switch to Java 8 from Java 7
  * Updated Mathematica
  * Misc minor configuration changes
2014-06-20:
  * New firmware with various fixes, and kernel bugfix
2014-06-02:
  * Many, many firmware updates with major USB improvements
  * pyserial installed by default
  * picamera installed by default
2014-01-07:
  * Firmware updated
  * Some space saved on the root filesystem
2013-12-20:
  * Firmware updated, includes V4L2 fixes
  * Update omxplayer
2013-12-18:
  * Firmware updated and now using kernel 3.10. Many, many improvements
  * fbturbo XOrg driver is now included and enabled by default. Thanks to 
    ssvb https://github.com/ssvb/xf86-video-fbturbo
  * Update Scratch image with further bug fixes
  * Include Wolfram Mathematica
  * Update to PyPy 2.2
  * Update omxplayer
  * Include v4l-utils for use with experimental V4L2 Raspberry Pi camera driver
  * Update squeak-vm to fix issues with loading JPEGs
2013-09-25:
  * Update Scratch image for further performance improvements
  * Include Oracle JDK
  * At least a 4GiB SD card is now required (see above)
  * Include PyPy 2.1
  * Include base piface packages
  * Update raspi-config to include bugfix for inheriting language settings
    from NOOBS
2013-09-10:
  * Updated to current top of tree firmware
  * Update squeak-vm, including fastblit optimised for the Raspbery Pi 
  * Include Sonic Pi and a fixed jackd2 package
  * Support boot to Scratch
  * Inherit keyboard and language settings from NOOBS


================================================
FILE: export-noobs/prerun.sh
================================================
#!/bin/bash -e

IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
NOOBS_DIR="${STAGE_WORK_DIR}/${IMG_DATE}-${IMG_NAME}${IMG_SUFFIX}"
unmount_image "${IMG_FILE}"

mkdir -p "${STAGE_WORK_DIR}"
cp "${WORK_DIR}/export-image/${IMG_FILENAME}${IMG_SUFFIX}.img" "${STAGE_WORK_DIR}/"

rm -rf "${NOOBS_DIR}"

PARTED_OUT=$(parted -sm "${IMG_FILE}" unit b print)
BOOT_OFFSET=$(echo "$PARTED_OUT" | grep -e '^1:' | cut -d':' -f 2 | tr -d B)
BOOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^1:' | cut -d':' -f 4 | tr -d B)

ROOT_OFFSET=$(echo "$PARTED_OUT" | grep -e '^2:' | cut -d':' -f 2 | tr -d B)
ROOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^2:' | cut -d':' -f 4 | tr -d B)

BOOT_DEV=$(losetup --show -f -o "${BOOT_OFFSET}" --sizelimit "${BOOT_LENGTH}" "${IMG_FILE}")
ROOT_DEV=$(losetup --show -f -o "${ROOT_OFFSET}" --sizelimit "${ROOT_LENGTH}" "${IMG_FILE}")
echo "/boot: offset $BOOT_OFFSET, length $BOOT_LENGTH"
echo "/:     offset $ROOT_OFFSET, length $ROOT_LENGTH"

mkdir -p "${STAGE_WORK_DIR}/rootfs"
mkdir -p "${NOOBS_DIR}"

mount "$ROOT_DEV" "${STAGE_WORK_DIR}/rootfs"
mount "$BOOT_DEV" "${STAGE_WORK_DIR}/rootfs/boot"

ln -sv "/lib/systemd/system/apply_noobs_os_config.service" "$ROOTFS_DIR/etc/systemd/system/multi-user.target.wants/apply_noobs_os_config.service"

bsdtar --numeric-owner --format gnutar -C "${STAGE_WORK_DIR}/rootfs/boot" -cpf - . | xz -T0 > "${NOOBS_DIR}/boot.tar.xz"
umount "${STAGE_WORK_DIR}/rootfs/boot"
bsdtar --numeric-owner --format gnutar -C "${STAGE_WORK_DIR}/rootfs" --one-file-system -cpf - . | xz -T0 > "${NOOBS_DIR}/root.tar.xz"

unmount_image "${IMG_FILE}"


================================================
FILE: scripts/common
================================================
log (){
	date +"[%T] $*" | tee -a "${LOG_FILE}"
}
export -f log

bootstrap(){
	local BOOTSTRAP_CMD=debootstrap
	local BOOTSTRAP_ARGS=()

	export http_proxy=${APT_PROXY}

	if [ "$(dpkg --print-architecture)" !=  "armhf" ] && [ "$(dpkg --print-architecture)" !=  "aarch64" ]; then
		BOOTSTRAP_CMD=qemu-debootstrap
	fi

	BOOTSTRAP_ARGS+=(--arch armhf)
	BOOTSTRAP_ARGS+=(--components "main,contrib,non-free")
	BOOTSTRAP_ARGS+=(--keyring "${STAGE_DIR}/files/raspberrypi.gpg")
	BOOTSTRAP_ARGS+=("$@")

	setarch linux32 capsh --drop=cap_setfcap -- "${BOOTSTRAP_CMD}" "${BOOTSTRAP_ARGS[@]}" || true

	if [ -d "$2/debootstrap" ]; then
		rmdir "$2/debootstrap"
	fi
}
export -f bootstrap

copy_previous(){
	if [ ! -d "${PREV_ROOTFS_DIR}" ]; then
		echo "Previous stage rootfs not found"
		false
	fi
	mkdir -p "${ROOTFS_DIR}"
	rsync -aHAXx --exclude var/cache/apt/archives "${PREV_ROOTFS_DIR}/" "${ROOTFS_DIR}/"
}
export -f copy_previous

unmount(){
	if [ -z "$1" ]; then
		DIR=$PWD
	else
		DIR=$1
	fi

	while mount | grep -q "$DIR"; do
		local LOCS
		LOCS=$(mount | grep "$DIR" | cut -f 3 -d ' ' | sort -r)
		for loc in $LOCS; do
			umount "$loc"
		done
	done
}
export -f unmount

unmount_image(){
	sync
	sleep 1
	local LOOP_DEVICES
	LOOP_DEVICES=$(losetup --list | grep "$(basename "${1}")" | cut -f1 -d' ')
	for LOOP_DEV in ${LOOP_DEVICES}; do
		if [ -n "${LOOP_DEV}" ]; then
			local MOUNTED_DIR
			MOUNTED_DIR=$(mount | grep "$(basename "${LOOP_DEV}")" | head -n 1 | cut -f 3 -d ' ')
			if [ -n "${MOUNTED_DIR}" ] && [ "${MOUNTED_DIR}" != "/" ]; then
				unmount "$(dirname "${MOUNTED_DIR}")"
			fi
			sleep 1
			losetup -d "${LOOP_DEV}"
		fi
	done
}
export -f unmount_image

on_chroot() {
	if ! mount | grep -q "$(realpath "${ROOTFS_DIR}"/proc)"; then
		mount -t proc proc "${ROOTFS_DIR}/proc"
	fi

	if ! mount | grep -q "$(realpath "${ROOTFS_DIR}"/dev)"; then
		mount --bind /dev "${ROOTFS_DIR}/dev"
	fi
	
	if ! mount | grep -q "$(realpath "${ROOTFS_DIR}"/dev/pts)"; then
		mount --bind /dev/pts "${ROOTFS_DIR}/dev/pts"
	fi

	if ! mount | grep -q "$(realpath "${ROOTFS_DIR}"/sys)"; then
		mount --bind /sys "${ROOTFS_DIR}/sys"
	fi

	setarch linux32 capsh --drop=cap_setfcap "--chroot=${ROOTFS_DIR}/" -- -e "$@"
}
export -f on_chroot

update_issue() {
	local GIT_HASH
	GIT_HASH=$(git rev-parse HEAD)
	echo -e "Raspberry Pi reference ${IMG_DATE}\nGenerated using ${PI_GEN}, ${PI_GEN_REPO}, ${GIT_HASH}, ${1}" > "${ROOTFS_DIR}/etc/rpi-issue"
}
export -f update_issue



================================================
FILE: scripts/dependencies_check
================================================
# dependencies_check
# $@	Dependency files to check
#
# Each dependency is in the form of a tool to test for, optionally followed by
# a : and the name of a package if the package on a Debian-ish system is not
# named for the tool (i.e., qemu-user-static).
dependencies_check()
{
	local depfile deps missing

	for depfile in "$@"; do
		if [[ -e "$depfile" ]]; then
			deps="$(sed -f "${SCRIPT_DIR}/remove-comments.sed" < "${BASE_DIR}/depends")"

		fi
		for dep in $deps; do
			if ! hash "${dep%:*}" 2>/dev/null; then
				missing="${missing:+$missing }${dep#*:}"
			fi
		done
	done

	if [[ "$missing" ]]; then
		echo "Required dependencies not installed"
		echo
		echo "This can be resolved on Debian/Raspbian systems by installing:"
		echo "$missing"
		false
	fi


	if ! grep -q "/proc/sys/fs/binfmt_misc" /proc/mounts; then
		echo "Module binfmt_misc not loaded in host"
		echo "Please run:"
		echo "  sudo modprobe binfmt_misc"
		exit 1
	fi
}


================================================
FILE: scripts/remove-comments.sed
================================================
# Deletes comments and collapses whitespace in ##-packages files

# Append (N)ext line to buffer
# if (!)not ($)buffer is EOF, (b)ranch to (:)label loop
:loop
N
$ !b loop

# Buffer is "line1\nline2\n...lineN", del comments and collapse whitespace
s/#[^\n]*//g
s/[[:space:]]\{1,\}/ /g


================================================
FILE: stage0/00-configure-apt/00-run.sh
================================================
#!/bin/bash -e

install -m 644 files/sources.list "${ROOTFS_DIR}/etc/apt/"
install -m 644 files/raspi.list "${ROOTFS_DIR}/etc/apt/sources.list.d/"

if [ -n "$APT_PROXY" ]; then
	install -m 644 files/51cache "${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache"
	sed "${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache" -i -e "s|APT_PROXY|${APT_PROXY}|"
else
	rm -f "${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache"
fi

on_chroot apt-key add - < files/raspberrypi.gpg.key
on_chroot << EOF
apt-get update
apt-get dist-upgrade -y
EOF


================================================
FILE: stage0/00-configure-apt/files/51cache
================================================
Acquire::http { Proxy "APT_PROXY"; };


================================================
FILE: stage0/00-configure-apt/files/raspberrypi.gpg.key
================================================
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.12 (GNU/Linux)

mQENBE/d7o8BCACrwqQacGJfn3tnMzGui6mv2lLxYbsOuy/+U4rqMmGEuo3h9m92
30E2EtypsoWczkBretzLUCFv+VUOxaA6sV9+puTqYGhhQZFuKUWcG7orf7QbZRuu
TxsEUepW5lg7MExmAu1JJzqM0kMQX8fVyWVDkjchZ/is4q3BPOUCJbUJOsE+kK/6
8kW6nWdhwSAjfDh06bA5wvoXNjYoDdnSZyVdcYCPEJXEg5jfF/+nmiFKMZBraHwn
eQsepr7rBXxNcEvDlSOPal11fg90KXpy7Umre1UcAZYJdQeWcHu7X5uoJx/MG5J8
ic6CwYmDaShIFa92f8qmFcna05+lppk76fsnABEBAAG0IFJhc3BiZXJyeSBQaSBB
cmNoaXZlIFNpZ25pbmcgS2V5iQE4BBMBAgAiBQJP3e6PAhsDBgsJCAcDAgYVCAIJ
CgsEFgIDAQIeAQIXgAAKCRCCsSmSf6MwPk6vB/9pePB3IukU9WC9Bammh3mpQTvL
OifbkzHkmAYxzjfK6D2I8pT0xMxy949+ThzJ7uL60p6T/32ED9DR3LHIMXZvKtuc
mQnSiNDX03E2p7lIP/htoxW2hDP2n8cdlNdt0M9IjaWBppsbO7IrDppG2B1aRLni
uD7v8bHRL2mKTtIDLX42Enl8aLAkJYgNWpZyPkDyOqamjijarIWjGEPCkaURF7g4
d44HvYhpbLMOrz1m6N5Bzoa5+nq3lmifeiWKxioFXU+Hy5bhtAM6ljVb59hbD2ra
X4+3LXC9oox2flmQnyqwoyfZqVgSQa0B41qEQo8t1bz6Q1Ti7fbMLThmbRHiuQEN
BE/d7o8BCADNlVtBZU63fm79SjHh5AEKFs0C3kwa0mOhp9oas/haDggmhiXdzeD3
49JWz9ZTx+vlTq0s+I+nIR1a+q+GL+hxYt4HhxoA6vlDMegVfvZKzqTX9Nr2VqQa
S4Kz3W5ULv81tw3WowK6i0L7pqDmvDqgm73mMbbxfHD0SyTt8+fk7qX6Ag2pZ4a9
ZdJGxvASkh0McGpbYJhk1WYD+eh4fqH3IaeJi6xtNoRdc5YXuzILnp+KaJyPE5CR
qUY5JibOD3qR7zDjP0ueP93jLqmoKltCdN5+yYEExtSwz5lXniiYOJp8LWFCgv5h
m8aYXkcJS1xVV9Ltno23YvX5edw9QY4hABEBAAGJAR8EGAECAAkFAk/d7o8CGwwA
CgkQgrEpkn+jMD5Figf/dIC1qtDMTbu5IsI5uZPX63xydaExQNYf98cq5H2fWF6O
yVR7ERzA2w33hI0yZQrqO6pU9SRnHRxCFvGv6y+mXXXMRcmjZG7GiD6tQWeN/3wb
EbAn5cg6CJ/Lk/BI4iRRfBX07LbYULCohlGkwBOkRo10T+Ld4vCCnBftCh5x2OtZ
TOWRULxP36y2PLGVNF+q9pho98qx+RIxvpofQM/842ZycjPJvzgVQsW4LT91KYAE
4TVf6JjwUM6HZDoiNcX6d7zOhNfQihXTsniZZ6rky287htsWVDNkqOi5T3oTxWUo
m++/7s3K3L0zWopdhMVcgg6Nt9gcjzqN1c0gy55L/g==
=mNSj
-----END PGP PUBLIC KEY BLOCK-----


================================================
FILE: stage0/00-configure-apt/files/raspi.list
================================================
deb http://archive.raspberrypi.org/debian/ buster main
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://archive.raspberrypi.org/debian/ buster main


================================================
FILE: stage0/00-configure-apt/files/sources.list
================================================
deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi


================================================
FILE: stage0/01-locale/00-debconf
================================================
# Locales to be generated:
# Choices: All locales, aa_DJ ISO-8859-1, aa_DJ.UTF-8 UTF-8, aa_ER UTF-8, aa_ER@saaho UTF-8, aa_ET UTF-8, af_ZA ISO-8859-1, af_ZA.UTF-8 UTF-8, ak_GH UTF-8, am_ET UTF-8, an_ES ISO-8859-15, an_ES.UTF-8 UTF-8, anp_IN UTF-8, ar_AE ISO-8859-6, ar_AE.UTF-8 UTF-8, ar_BH ISO-8859-6, ar_BH.UTF-8 UTF-8, ar_DZ ISO-8859-6, ar_DZ.UTF-8 UTF-8, ar_EG ISO-8859-6, ar_EG.UTF-8 UTF-8, ar_IN UTF-8, ar_IQ ISO-8859-6, ar_IQ.UTF-8 UTF-8, ar_JO ISO-8859-6, ar_JO.UTF-8 UTF-8, ar_KW ISO-8859-6, ar_KW.UTF-8 UTF-8, ar_LB ISO-8859-6, ar_LB.UTF-8 UTF-8, ar_LY ISO-8859-6, ar_LY.UTF-8 UTF-8, ar_MA ISO-8859-6, ar_MA.UTF-8 UTF-8, ar_OM ISO-8859-6, ar_OM.UTF-8 UTF-8, ar_QA ISO-8859-6, ar_QA.UTF-8 UTF-8, ar_SA ISO-8859-6, ar_SA.UTF-8 UTF-8, ar_SD ISO-8859-6, ar_SD.UTF-8 UTF-8, ar_SS UTF-8, ar_SY ISO-8859-6, ar_SY.UTF-8 UTF-8, ar_TN ISO-8859-6, ar_TN.UTF-8 UTF-8, ar_YE ISO-8859-6, ar_YE.UTF-8 UTF-8, as_IN UTF-8, ast_ES ISO-8859-15, ast_ES.UTF-8 UTF-8, ayc_PE UTF-8, az_AZ UTF-8, be_BY CP1251, be_BY.UTF-8 UTF-8, be_BY@latin UTF-8, bem_ZM UTF-8, ber_DZ UTF-8, ber_MA UTF-8, bg_BG CP1251, bg_BG.UTF-8 UTF-8, bho_IN UTF-8, bn_BD UTF-8, bn_IN UTF-8, bo_CN UTF-8, bo_IN UTF-8, br_FR ISO-8859-1, br_FR.UTF-8 UTF-8, br_FR@euro ISO-8859-15, brx_IN UTF-8, bs_BA ISO-8859-2, bs_BA.UTF-8 UTF-8, byn_ER UTF-8, ca_AD ISO-8859-15, ca_AD.UTF-8 UTF-8, ca_ES ISO-8859-1, ca_ES.UTF-8 UTF-8, ca_ES.UTF-8@valencia UTF-8, ca_ES@euro ISO-8859-15, ca_ES@valencia ISO-8859-15, ca_FR ISO-8859-15, ca_FR.UTF-8 UTF-8, ca_IT ISO-8859-15, ca_IT.UTF-8 UTF-8, cmn_TW UTF-8, crh_UA UTF-8, cs_CZ ISO-8859-2, cs_CZ.UTF-8 UTF-8, csb_PL UTF-8, cv_RU UTF-8, cy_GB ISO-8859-14, cy_GB.UTF-8 UTF-8, da_DK ISO-8859-1, da_DK.UTF-8 UTF-8, de_AT ISO-8859-1, de_AT.UTF-8 UTF-8, de_AT@euro ISO-8859-15, de_BE ISO-8859-1, de_BE.UTF-8 UTF-8, de_BE@euro ISO-8859-15, de_CH ISO-8859-1, de_CH.UTF-8 UTF-8, de_DE ISO-8859-1, de_DE.UTF-8 UTF-8, de_DE@euro ISO-8859-15, de_LI.UTF-8 UTF-8, de_LU ISO-8859-1, de_LU.UTF-8 UTF-8, de_LU@euro ISO-8859-15, doi_IN UTF-8, dv_MV UTF-8, dz_BT UTF-8, el_CY ISO-8859-7, el_CY.UTF-8 UTF-8, el_GR ISO-8859-7, el_GR.UTF-8 UTF-8, en_AG UTF-8, en_AU ISO-8859-1, en_AU.UTF-8 UTF-8, en_BW ISO-8859-1, en_BW.UTF-8 UTF-8, en_CA ISO-8859-1, en_CA.UTF-8 UTF-8, en_DK ISO-8859-1, en_DK.ISO-8859-15 ISO-8859-15, en_DK.UTF-8 UTF-8, en_GB ISO-8859-1, en_GB.ISO-8859-15 ISO-8859-15, en_GB.UTF-8 UTF-8, en_HK ISO-8859-1, en_HK.UTF-8 UTF-8, en_IE ISO-8859-1, en_IE.UTF-8 UTF-8, en_IE@euro ISO-8859-15, en_IN UTF-8, en_NG UTF-8, en_NZ ISO-8859-1, en_NZ.UTF-8 UTF-8, en_PH ISO-8859-1, en_PH.UTF-8 UTF-8, en_SG ISO-8859-1, en_SG.UTF-8 UTF-8, en_US ISO-8859-1, en_US.ISO-8859-15 ISO-8859-15, en_US.UTF-8 UTF-8, en_ZA ISO-8859-1, en_ZA.UTF-8 UTF-8, en_ZM UTF-8, en_ZW ISO-8859-1, en_ZW.UTF-8 UTF-8, eo ISO-8859-3, eo.UTF-8 UTF-8, es_AR ISO-8859-1, es_AR.UTF-8 UTF-8, es_BO ISO-8859-1, es_BO.UTF-8 UTF-8, es_CL ISO-8859-1, es_CL.UTF-8 UTF-8, es_CO ISO-8859-1, es_CO.UTF-8 UTF-8, es_CR ISO-8859-1, es_CR.UTF-8 UTF-8, es_CU UTF-8, es_DO ISO-8859-1, es_DO.UTF-8 UTF-8, es_EC ISO-8859-1, es_EC.UTF-8 UTF-8, es_ES ISO-8859-1, es_ES.UTF-8 UTF-8, es_ES@euro ISO-8859-15, es_GT ISO-8859-1, es_GT.UTF-8 UTF-8, es_HN ISO-8859-1, es_HN.UTF-8 UTF-8, es_MX ISO-8859-1, es_MX.UTF-8 UTF-8, es_NI ISO-8859-1, es_NI.UTF-8 UTF-8, es_PA ISO-8859-1, es_PA.UTF-8 UTF-8, es_PE ISO-8859-1, es_PE.UTF-8 UTF-8, es_PR ISO-8859-1, es_PR.UTF-8 UTF-8, es_PY ISO-8859-1, es_PY.UTF-8 UTF-8, es_SV ISO-8859-1, es_SV.UTF-8 UTF-8, es_US ISO-8859-1, es_US.UTF-8 UTF-8, es_UY ISO-8859-1, es_UY.UTF-8 UTF-8, es_VE ISO-8859-1, es_VE.UTF-8 UTF-8, et_EE ISO-8859-1, et_EE.ISO-8859-15 ISO-8859-15, et_EE.UTF-8 UTF-8, eu_ES ISO-8859-1, eu_ES.UTF-8 UTF-8, eu_ES@euro ISO-8859-15, eu_FR ISO-8859-1, eu_FR.UTF-8 UTF-8, eu_FR@euro ISO-8859-15, fa_IR UTF-8, ff_SN UTF-8, fi_FI ISO-8859-1, fi_FI.UTF-8 UTF-8, fi_FI@euro ISO-8859-15, fil_PH UTF-8, fo_FO ISO-8859-1, fo_FO.UTF-8 UTF-8, fr_BE ISO-8859-1, fr_BE.UTF-8 UTF-8, fr_BE@euro ISO-8859-15, fr_CA ISO-8859-1, fr_CA.UTF-8 UTF-8, fr_CH ISO-8859-1, fr_CH.UTF-8 UTF-8, fr_FR ISO-8859-1, fr_FR.UTF-8 UTF-8, fr_FR@euro ISO-8859-15, fr_LU ISO-8859-1, fr_LU.UTF-8 UTF-8, fr_LU@euro ISO-8859-15, fur_IT UTF-8, fy_DE UTF-8, fy_NL UTF-8, ga_IE ISO-8859-1, ga_IE.UTF-8 UTF-8, ga_IE@euro ISO-8859-15, gd_GB ISO-8859-15, gd_GB.UTF-8 UTF-8, gez_ER UTF-8, gez_ER@abegede UTF-8, gez_ET UTF-8, gez_ET@abegede UTF-8, gl_ES ISO-8859-1, gl_ES.UTF-8 UTF-8, gl_ES@euro ISO-8859-15, gu_IN UTF-8, gv_GB ISO-8859-1, gv_GB.UTF-8 UTF-8, ha_NG UTF-8, hak_TW UTF-8, he_IL ISO-8859-8, he_IL.UTF-8 UTF-8, hi_IN UTF-8, hne_IN UTF-8, hr_HR ISO-8859-2, hr_HR.UTF-8 UTF-8, hsb_DE ISO-8859-2, hsb_DE.UTF-8 UTF-8, ht_HT UTF-8, hu_HU ISO-8859-2, hu_HU.UTF-8 UTF-8, hy_AM UTF-8, hy_AM.ARMSCII-8 ARMSCII-8, ia_FR UTF-8, id_ID ISO-8859-1, id_ID.UTF-8 UTF-8, ig_NG UTF-8, ik_CA UTF-8, is_IS ISO-8859-1, is_IS.UTF-8 UTF-8, it_CH ISO-8859-1, it_CH.UTF-8 UTF-8, it_IT ISO-8859-1, it_IT.UTF-8 UTF-8, it_IT@euro ISO-8859-15, iu_CA UTF-8, iw_IL ISO-8859-8, iw_IL.UTF-8 UTF-8, ja_JP.EUC-JP EUC-JP, ja_JP.UTF-8 UTF-8, ka_GE GEORGIAN-PS, ka_GE.UTF-8 UTF-8, kk_KZ PT154, kk_KZ RK1048, kk_KZ.UTF-8 UTF-8, kl_GL ISO-8859-1, kl_GL.UTF-8 UTF-8, km_KH UTF-8, kn_IN UTF-8, ko_KR.EUC-KR EUC-KR, ko_KR.UTF-8 UTF-8, kok_IN UTF-8, ks_IN UTF-8, ks_IN@devanagari UTF-8, ku_TR ISO-8859-9, ku_TR.UTF-8 UTF-8, kw_GB ISO-8859-1, kw_GB.UTF-8 UTF-8, ky_KG UTF-8, lb_LU UTF-8, lg_UG ISO-8859-10, lg_UG.UTF-8 UTF-8, li_BE UTF-8, li_NL UTF-8, lij_IT UTF-8, lo_LA UTF-8, lt_LT ISO-8859-13, lt_LT.UTF-8 UTF-8, lv_LV ISO-8859-13, lv_LV.UTF-8 UTF-8, lzh_TW UTF-8, mag_IN UTF-8, mai_IN UTF-8, mg_MG ISO-8859-15, mg_MG.UTF-8 UTF-8, mhr_RU UTF-8, mi_NZ ISO-8859-13, mi_NZ.UTF-8 UTF-8, mk_MK ISO-8859-5, mk_MK.UTF-8 UTF-8, ml_IN UTF-8, mn_MN UTF-8, mni_IN UTF-8, mr_IN UTF-8, ms_MY ISO-8859-1, ms_MY.UTF-8 UTF-8, mt_MT ISO-8859-3, mt_MT.UTF-8 UTF-8, my_MM UTF-8, nan_TW UTF-8, nan_TW@latin UTF-8, nb_NO ISO-8859-1, nb_NO.UTF-8 UTF-8, nds_DE UTF-8, nds_NL UTF-8, ne_NP UTF-8, nhn_MX UTF-8, niu_NU UTF-8, niu_NZ UTF-8, nl_AW UTF-8, nl_BE ISO-8859-1, nl_BE.UTF-8 UTF-8, nl_BE@euro ISO-8859-15, nl_NL ISO-8859-1, nl_NL.UTF-8 UTF-8, nl_NL@euro ISO-8859-15, nn_NO ISO-8859-1, nn_NO.UTF-8 UTF-8, nr_ZA UTF-8, nso_ZA UTF-8, oc_FR ISO-8859-1, oc_FR.UTF-8 UTF-8, om_ET UTF-8, om_KE ISO-8859-1, om_KE.UTF-8 UTF-8, or_IN UTF-8, os_RU UTF-8, pa_IN UTF-8, pa_PK UTF-8, pap_AN UTF-8, pap_AW UTF-8, pap_CW UTF-8, pl_PL ISO-8859-2, pl_PL.UTF-8 UTF-8, ps_AF UTF-8, pt_BR ISO-8859-1, pt_BR.UTF-8 UTF-8, pt_PT ISO-8859-1, pt_PT.UTF-8 UTF-8, pt_PT@euro ISO-8859-15, quz_PE UTF-8, ro_RO ISO-8859-2, ro_RO.UTF-8 UTF-8, ru_RU ISO-8859-5, ru_RU.CP1251 CP1251, ru_RU.KOI8-R KOI8-R, ru_RU.UTF-8 UTF-8, ru_UA KOI8-U, ru_UA.UTF-8 UTF-8, rw_RW UTF-8, sa_IN UTF-8, sat_IN UTF-8, sc_IT UTF-8, sd_IN UTF-8, sd_IN@devanagari UTF-8, se_NO UTF-8, shs_CA UTF-8, si_LK UTF-8, sid_ET UTF-8, sk_SK ISO-8859-2, sk_SK.UTF-8 UTF-8, sl_SI ISO-8859-2, sl_SI.UTF-8 UTF-8, so_DJ ISO-8859-1, so_DJ.UTF-8 UTF-8, so_ET UTF-8, so_KE ISO-8859-1, so_KE.UTF-8 UTF-8, so_SO ISO-8859-1, so_SO.UTF-8 UTF-8, sq_AL ISO-8859-1, sq_AL.UTF-8 UTF-8, sq_MK UTF-8, sr_ME UTF-8, sr_RS UTF-8, sr_RS@latin UTF-8, ss_ZA UTF-8, st_ZA ISO-8859-1, st_ZA.UTF-8 UTF-8, sv_FI ISO-8859-1, sv_FI.UTF-8 UTF-8, sv_FI@euro ISO-8859-15, sv_SE ISO-8859-1, sv_SE.ISO-8859-15 ISO-8859-15, sv_SE.UTF-8 UTF-8, sw_KE UTF-8, sw_TZ UTF-8, szl_PL UTF-8, ta_IN UTF-8, ta_LK UTF-8, te_IN UTF-8, tg_TJ KOI8-T, tg_TJ.UTF-8 UTF-8, th_TH TIS-620, th_TH.UTF-8 UTF-8, the_NP UTF-8, ti_ER UTF-8, ti_ET UTF-8, tig_ER UTF-8, tk_TM UTF-8, tl_PH ISO-8859-1, tl_PH.UTF-8 UTF-8, tn_ZA UTF-8, tr_CY ISO-8859-9, tr_CY.UTF-8 UTF-8, tr_TR ISO-8859-9, tr_TR.UTF-8 UTF-8, ts_ZA UTF-8, tt_RU UTF-8, tt_RU@iqtelif UTF-8, ug_CN UTF-8, uk_UA KOI8-U, uk_UA.UTF-8 UTF-8, unm_US UTF-8, ur_IN UTF-8, ur_PK UTF-8, uz_UZ ISO-8859-1, uz_UZ.UTF-8 UTF-8, uz_UZ@cyrillic UTF-8, ve_ZA UTF-8, vi_VN UTF-8, wa_BE ISO-8859-1, wa_BE.UTF-8 UTF-8, wa_BE@euro ISO-8859-15, wae_CH UTF-8, wal_ET UTF-8, wo_SN UTF-8, xh_ZA ISO-8859-1, xh_ZA.UTF-8 UTF-8, yi_US CP1255, yi_US.UTF-8 UTF-8, yo_NG UTF-8, yue_HK UTF-8, zh_CN GB2312, zh_CN.GB18030 GB18030, zh_CN.GBK GBK, zh_CN.UTF-8 UTF-8, zh_HK BIG5-HKSCS, zh_HK.UTF-8 UTF-8, zh_SG GB2312, zh_SG.GBK GBK, zh_SG.UTF-8 UTF-8, zh_TW BIG5, zh_TW.EUC-TW EUC-TW, zh_TW.UTF-8 UTF-8, zu_ZA ISO-8859-1, zu_ZA.UTF-8 UTF-8
locales	locales/locales_to_be_generated	multiselect	en_GB.UTF-8 UTF-8
# Default locale for the system environment:
# Choices: None, C.UTF-8, en_GB.UTF-8
locales	locales/default_environment_locale	select	en_GB.UTF-8


================================================
FILE: stage0/01-locale/00-packages
================================================
locales


================================================
FILE: stage0/02-firmware/01-packages
================================================
raspberrypi-bootloader
raspberrypi-kernel


================================================
FILE: stage0/prerun.sh
================================================
#!/bin/bash -e

if [ ! -d "${ROOTFS_DIR}" ]; then
	bootstrap buster "${ROOTFS_DIR}" http://raspbian.raspberrypi.org/raspbian/
fi


================================================
FILE: stage1/00-boot-files/00-run.sh
================================================
#!/bin/bash -e

install -m 644 files/cmdline.txt "${ROOTFS_DIR}/boot/"
install -m 644 files/config.txt "${ROOTFS_DIR}/boot/"


================================================
FILE: stage1/00-boot-files/files/cmdline.txt
================================================
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait


================================================
FILE: stage1/00-boot-files/files/config.txt
================================================
# For more options and information see
# http://rpf.io/configtxt
# Some settings may impact device functionality. See link above for details

# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1

# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan
#disable_overscan=1

# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
#overscan_left=16
#overscan_right=16
#overscan_top=16
#overscan_bottom=16

# uncomment to force a console size. By default it will be display's size minus
# overscan.
#framebuffer_width=1280
#framebuffer_height=720

# uncomment if hdmi display is not detected and composite is being output
#hdmi_force_hotplug=1

# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1
#hdmi_mode=1

# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
#hdmi_drive=2

# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display
#config_hdmi_boost=4

# uncomment for composite PAL
#sdtv_mode=2

#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800

# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on

# Uncomment this to enable the lirc-rpi module
#dtoverlay=lirc-rpi

# Additional overlays and parameters are documented /boot/overlays/README

# Enable audio (loads snd_bcm2835)
dtparam=audio=on

[pi4]
# Enable DRM VC4 V3D driver on top of the dispmanx display stack
dtoverlay=vc4-fkms-v3d
max_framebuffers=2

[all]
#dtoverlay=vc4-fkms-v3d


================================================
FILE: stage1/01-sys-tweaks/00-patches/01-bashrc.diff
================================================
--- a/rootfs/etc/skel/.bashrc
+++ b/rootfs/etc/skel/.bashrc
@@ -43,7 +43,7 @@
 # uncomment for a colored prompt, if the terminal has the capability; turned
 # off by default to not distract the user: the focus in a terminal window
 # should be on the output of commands, not on the prompt
-#force_color_prompt=yes
+force_color_prompt=yes
 
 if [ -n "$force_color_prompt" ]; then
     if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
@@ -57,7 +57,7 @@
 fi
 
 if [ "$color_prompt" = yes ]; then
-    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
+    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w \$\[\033[00m\] '
 else
     PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
 fi
@@ -79,9 +79,9 @@
     #alias dir='dir --color=auto'
     #alias vdir='vdir --color=auto'
 
-    #alias grep='grep --color=auto'
-    #alias fgrep='fgrep --color=auto'
-    #alias egrep='egrep --color=auto'
+    alias grep='grep --color=auto'
+    alias fgrep='fgrep --color=auto'
+    alias egrep='egrep --color=auto'
 fi
 
 # colored GCC warnings and errors


================================================
FILE: stage1/01-sys-tweaks/00-patches/series
================================================
01-bashrc.diff


================================================
FILE: stage1/01-sys-tweaks/00-run.sh
================================================
#!/bin/bash -e

install -d "${ROOTFS_DIR}/etc/systemd/system/getty@tty1.service.d"
install -m 644 files/noclear.conf "${ROOTFS_DIR}/etc/systemd/system/getty@tty1.service.d/noclear.conf"
install -v -m 644 files/fstab "${ROOTFS_DIR}/etc/fstab"

on_chroot << EOF
if ! id -u ${FIRST_USER_NAME} >/dev/null 2>&1; then
	adduser --disabled-password --gecos "" ${FIRST_USER_NAME}
fi
echo "${FIRST_USER_NAME}:${FIRST_USER_PASS}" | chpasswd
echo "root:root" | chpasswd
EOF




================================================
FILE: stage1/01-sys-tweaks/files/fstab
================================================
proc            /proc           proc    defaults          0       0
BOOTDEV  /boot           vfat    defaults          0       2
ROOTDEV  /               ext4    defaults,noatime  0       1


================================================
FILE: stage1/01-sys-tweaks/files/noclear.conf
================================================
[Service]
TTYVTDisallocate=no


================================================
FILE: stage1/02-net-tweaks/00-packages
================================================
netbase


================================================
FILE: stage1/02-net-tweaks/00-patches/01-hosts.diff
================================================
Index: jessie-stage1/rootfs/etc/hosts
===================================================================
--- jessie-stage1.orig/rootfs/etc/hosts
+++ jessie-stage1/rootfs/etc/hosts
@@ -3,3 +3,4 @@
 ff02::1		ip6-allnodes
 ff02::2		ip6-allrouters
 
+127.0.1.1	raspberrypi


================================================
FILE: stage1/02-net-tweaks/00-patches/series
================================================
01-hosts.diff


================================================
FILE: stage1/02-net-tweaks/00-run.sh
================================================
#!/bin/bash -e

install -m 644 files/hostname "${ROOTFS_DIR}/etc/hostname"

ln -sf /dev/null "${ROOTFS_DIR}/etc/systemd/network/99-default.link"


================================================
FILE: stage1/02-net-tweaks/files/hostname
================================================
raspberrypi


================================================
FILE: stage1/02-net-tweaks/files/interfaces
================================================
auto lo

iface lo inet loopback
iface eth0 inet dhcp


================================================
FILE: stage1/03-install-packages/00-packages
================================================
libraspberrypi-bin libraspberrypi0 raspi-config


================================================
FILE: stage1/prerun.sh
================================================
#!/bin/bash -e

if [ ! -d "${ROOTFS_DIR}" ]; then
	copy_previous
fi


================================================
FILE: stage2/00-copies-and-fills/01-packages
================================================
raspi-copies-and-fills


================================================
FILE: stage2/00-copies-and-fills/02-run.sh
================================================
#!/bin/bash -e

mv "${ROOTFS_DIR}/etc/ld.so.preload" "${ROOTFS_DIR}/etc/ld.so.preload.disabled"


================================================
FILE: stage2/01-sys-tweaks/00-debconf
================================================
# Encoding to use on the console:
# Choices: ARMSCII-8, CP1251, CP1255, CP1256, GEORGIAN-ACADEMY, GEORGIAN-PS, IBM1133, ISIRI-3342, ISO-8859-1, ISO-8859-10, ISO-8859-11, ISO-8859-13, ISO-8859-14, ISO-8859-15, ISO-8859-16, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, KOI8-R, KOI8-U, TIS-620, UTF-8, VISCII
console-setup   console-setup/charmap47 select  UTF-8
# Character set to support:
# Choices: . Arabic, # Armenian, # Cyrillic - KOI8-R and KOI8-U, # Cyrillic - non-Slavic languages, # Cyrillic - Slavic languages (also Bosnian and Serbian Latin), . Ethiopic, # Georgian, # Greek, # Hebrew, # Lao, # Latin1 and Latin5 - western Europe and Turkic languages, # Latin2 - central Europe and Romanian, # Latin3 and Latin8 - Chichewa; Esperanto; Irish; Maltese and Welsh, # Latin7 - Lithuanian; Latvian; Maori and Marshallese, . Latin - Vietnamese, # Thai, . Combined - Latin; Slavic Cyrillic; Hebrew; basic Arabic, . Combined - Latin; Slavic Cyrillic; Greek, . Combined - Latin; Slavic and non-Slavic Cyrillic, Guess optimal character set
console-setup   console-setup/codeset47 select  Guess optimal character set
# Font for the console:
# Choices: Fixed, Goha, GohaClassic, Terminus, TerminusBold, TerminusBoldVGA, VGA, Do not change the boot/kernel font, Let the system select a suitable font
console-setup   console-setup/fontface47        select  Do not change the boot/kernel font
# Key to function as AltGr:
# Choices: The default for the keyboard layout, No AltGr key, Right Alt (AltGr), Right Control, Right Logo key, Menu key, Left Alt, Left Logo key, Keypad Enter key, Both Logo keys, Both Alt keys
keyboard-configuration	keyboard-configuration/altgr	select	The default for the keyboard layout
# Keyboard model:
# Choices: A4Tech KB-21, A4Tech KBS-8, A4Tech Wireless Desktop RFKB-23, Acer AirKey V, Acer C300, Acer Ferrari 4000, Acer Laptop, Advance Scorpius KI, Amiga, Apple, Apple Aluminium Keyboard (ANSI), Apple Aluminium Keyboard (ISO), Apple Aluminium Keyboard (JIS), Apple Laptop, Asus Laptop, Atari TT, Azona RF2300 wireless Internet Keyboard, BTC 5090, BTC 5113RF Multimedia, BTC 5126T, BTC 6301URF, BTC 9000, BTC 9000A, BTC 9001AH, BTC 9019U, BTC 9116U Mini Wireless Internet and Gaming, BenQ X-Touch, BenQ X-Touch 730, BenQ X-Touch 800, Brother Internet Keyboard, Cherry B.UNLIMITED, Cherry Blue Line CyBo@rd, Cherry Blue Line CyBo@rd (alternate option), Cherry CyBo@rd USB-Hub, Cherry CyMotion Expert, Cherry CyMotion Master Linux, Cherry CyMotion Master XPress, Chicony Internet Keyboard, Chicony KB-9885, Chicony KU-0108, Chicony KU-0420, Classmate PC, Compaq Easy Access Keyboard, Compaq Internet Keyboard (13 keys), Compaq Internet Keyboard (18 keys), Compaq Internet Keyboard (7 keys), Compaq iPaq Keyboard, Creative Desktop Wireless 7000, DTK2000, Dell, Dell 101-key PC, Dell Laptop/notebook Inspiron 6xxx/8xxx, Dell Laptop/notebook Precision M series, Dell Latitude series laptop, Dell Precision M65, Dell SK-8125, Dell SK-8135, Dell USB Multimedia Keyboard, Dexxa Wireless Desktop Keyboard, Diamond 9801 / 9802 series, Ennyah DKB-1008, Everex STEPnote, FL90, Fujitsu-Siemens Computers AMILO laptop, Generic 101-key PC, Generic 102-key (Intl) PC, Generic 104-key PC, Generic 105-key (Intl) PC, Genius Comfy KB-12e, Genius Comfy KB-16M / Genius MM Keyboard KWD-910, Genius Comfy KB-21e-Scroll, Genius KB-19e NB, Genius KKB-2050HS, Gyration, HTC Dream, Happy Hacking Keyboard, Happy Hacking Keyboard for Mac, Hewlett-Packard Internet Keyboard, Hewlett-Packard Mini 110 Notebook, Hewlett-Packard Omnibook 500 FA, Hewlett-Packard Omnibook 5xx, Hewlett-Packard Omnibook 6000/6100, Hewlett-Packard Omnibook XE3 GC, Hewlett-Packard Omnibook XE3 GF, Hewlett-Packard Omnibook XT1000, Hewlett-Packard Pavilion ZT11xx, Hewlett-Packard Pavilion dv5, Hewlett-Packard SK-250x Multimedia Keyboard, Hewlett-Packard nx9020, Honeywell Euroboard, Htc Dream phone, IBM Rapid Access, IBM Rapid Access II, IBM Space Saver, IBM ThinkPad 560Z/600/600E/A22E, IBM ThinkPad R60/T60/R61/T61, IBM ThinkPad Z60m/Z60t/Z61m/Z61t, Keytronic FlexPro, Kinesis, Laptop/notebook Compaq (eg. Armada) Laptop Keyboard, Laptop/notebook Compaq (eg. Presario) Internet Keyboard, Laptop/notebook eMachines m68xx, Logitech Access Keyboard, Logitech Cordless Desktop, Logitech Cordless Desktop (alternate option), Logitech Cordless Desktop EX110, Logitech Cordless Desktop LX-300, Logitech Cordless Desktop Navigator, Logitech Cordless Desktop Optical, Logitech Cordless Desktop Pro (alternate option 2), Logitech Cordless Desktop iTouch, Logitech Cordless Freedom/Desktop Navigator, Logitech G15 extra keys via G15daemon, Logitech Generic Keyboard, Logitech Internet 350 Keyboard, Logitech Internet Keyboard, Logitech Internet Navigator Keyboard, Logitech Media Elite Keyboard, Logitech Ultra-X Cordless Media Desktop Keyboard, Logitech Ultra-X Keyboard, Logitech diNovo Edge Keyboard, Logitech diNovo Keyboard, Logitech iTouch, Logitech iTouch Cordless Keyboard (model Y-RB6), Logitech iTouch Internet Navigator Keyboard SE, Logitech iTouch Internet Navigator Keyboard SE (USB), MacBook/MacBook Pro, MacBook/MacBook Pro (Intl), Macintosh, Macintosh Old, Memorex MX1998, Memorex MX2500 EZ-Access Keyboard, Memorex MX2750, Microsoft Comfort Curve Keyboard 2000, Microsoft Internet Keyboard, Microsoft Internet Keyboard Pro\, Swedish, Microsoft Natural, Microsoft Natural Keyboard Elite, Microsoft Natural Keyboard Pro / Microsoft Internet Keyboard Pro, Microsoft Natural Keyboard Pro OEM, Microsoft Natural Keyboard Pro USB / Microsoft Internet Keyboard Pro, Microsoft Natural Wireless Ergonomic Keyboard 4000, Microsoft Natural Wireless Ergonomic Keyboard 7000, Microsoft Office Keyboard, Microsoft Wireless Multimedia Keyboard 1.0A, Northgate OmniKey 101, OLPC, Ortek MCK-800 MM/Internet keyboard, PC-98xx Series, Propeller Voyager (KTEZ-1000), QTronix Scorpius 98N+, SILVERCREST Multimedia Wireless Keyboard, SK-1300, SK-2500, SK-6200, SK-7100, SVEN Ergonomic 2500, SVEN Slim 303, Samsung SDM 4500P, Samsung SDM 4510P, Sanwa Supply SKB-KG3, Sun Type 4, Sun Type 5, Sun Type 6 (Japanese layout), Sun Type 6 USB (Japanese layout), Sun Type 6 USB (Unix layout), Sun Type 6/7 USB, Sun Type 6/7 USB (European layout), Sun Type 7 USB, Sun Type 7 USB (European layout), Sun Type 7 USB (Japanese layout) / Japanese 106-key, Sun Type 7 USB (Unix layout), Super Power Multimedia Keyboard, Symplon PaceBook (tablet PC), Targa Visionary 811, Toshiba Satellite S3000, Trust Direct Access Keyboard, Trust Slimline, Trust Wireless Keyboard Classic, TypeMatrix EZ-Reach 2020, TypeMatrix EZ-Reach 2030 PS2, TypeMatrix EZ-Reach 2030 USB, TypeMatrix EZ-Reach 2030 USB (102/105:EU mode), TypeMatrix EZ-Reach 2030 USB (106:JP mode), Unitek KB-1925, ViewSonic KU-306 Internet Keyboard, Winbook Model XP5, Yahoo! Internet Keyboard
keyboard-configuration	keyboard-configuration/model	select	Generic 105-key (Intl) PC
# Keymap to use:
# Choices: American English, Albanian, Arabic, Asturian, Bangladesh, Belarusian, Bengali, Belgian, Bosnian, Brazilian, British English, Bulgarian, Bulgarian (phonetic layout), Burmese, Canadian French, Canadian Multilingual, Catalan, Chinese, Croatian, Czech, Danish, Dutch, Dvorak, Dzongkha, Esperanto, Estonian, Ethiopian, Finnish, French, Georgian, German, Greek, Gujarati, Gurmukhi, Hebrew, Hindi, Hungarian, Icelandic, Irish, Italian, Japanese, Kannada, Kazakh, Khmer, Kirghiz, Korean, Kurdish (F layout), Kurdish (Q layout), Lao, Latin American, Latvian, Lithuanian, Macedonian, Malayalam, Nepali, Northern Sami, Norwegian, Persian, Philippines, Polish, Portuguese, Punjabi, Romanian, Russian, Serbian (Cyrillic), Sindhi, Sinhala, Slovak, Slovenian, Spanish, Swedish, Swiss French, Swiss German, Tajik, Tamil, Telugu, Thai, Tibetan, Turkish (F layout), Turkish (Q layout), Ukrainian, Uyghur, Vietnamese
keyboard-configuration	keyboard-configuration/xkb-keymap	select	gb
# Compose key:
# Choices: No compose key, Right Alt (AltGr), Right Control, Right Logo key, Menu key, Left Logo key, Caps Lock
keyboard-configuration	keyboard-configuration/compose	select	No compose key
# Use Control+Alt+Backspace to terminate the X server?
keyboard-configuration	keyboard-configuration/ctrl_alt_bksp	boolean	true
# Keyboard layout:
# Choices: English (UK), English (UK) - English (UK\, Colemak), English (UK) - English (UK\, Dvorak with UK punctuation), English (UK) - English (UK\, Dvorak), English (UK) - English (UK\, Macintosh international), English (UK) - English (UK\, Macintosh), English (UK) - English (UK\, extended WinKeys), English (UK) - English (UK\, international with dead keys), Other
keyboard-configuration  keyboard-configuration/variant  select  English (UK)


================================================
FILE: stage2/01-sys-tweaks/00-packages
================================================
ssh less fbset sudo psmisc strace ed ncdu crda
console-setup keyboard-configuration debconf-utils parted unzip
build-essential manpages-dev python bash-completion gdb pkg-config
python-rpi.gpio v4l-utils
avahi-daemon
lua5.1
luajit
hardlink ca-certificates curl
fake-hwclock nfs-common usbutils
libraspberrypi-dev libraspberrypi-doc libfreetype6-dev
dosfstools
dphys-swapfile
raspberrypi-sys-mods
pi-bluetooth
apt-listchanges
usb-modeswitch
apt-transport-https
libpam-chksshpwd
rpi-update
libmtp-runtime
rsync
htop
man-db
policykit-1
ssh-import-id
rng-tools
ethtool


================================================
FILE: stage2/01-sys-tweaks/00-packages-nr
================================================
cifs-utils


================================================
FILE: stage2/01-sys-tweaks/00-patches/01-useradd.diff
================================================
Index: jessie-stage2/rootfs/etc/default/useradd
===================================================================
--- jessie-stage2.orig/rootfs/etc/default/useradd
+++ jessie-stage2/rootfs/etc/default/useradd
@@ -5,7 +5,7 @@
 # Similar to DHSELL in adduser. However, we use "sh" here because
 # useradd is a low level utility and should be as general
 # as possible
-SHELL=/bin/sh
+SHELL=/bin/bash
 #
 # The default group for users
 # 100=users on Debian systems
@@ -29,7 +29,7 @@ SHELL=/bin/sh
 # The SKEL variable specifies the directory containing "skeletal" user
 # files; in other words, files such as a sample .profile that will be
 # copied to the new user's home directory when it is created.
-# SKEL=/etc/skel
+SKEL=/etc/skel
 #
 # Defines whether the mail spool should be created while
 # creating the account


================================================
FILE: stage2/01-sys-tweaks/00-patches/02-swap.diff
================================================
Index: jessie-stage2/rootfs/etc/dphys-swapfile
===================================================================
--- jessie-stage2.orig/rootfs/etc/dphys-swapfile
+++ jessie-stage2/rootfs/etc/dphys-swapfile
@@ -13,7 +13,7 @@
 
 # set size to absolute value, leaving empty (default) then uses computed value
 #   you most likely don't want this, unless you have an special disk situation
-#CONF_SWAPSIZE=
+CONF_SWAPSIZE=100
 
 # set size to computed value, this times RAM size, dynamically adapts,
 #   guarantees that there is enough swap without wasting disk space on excess


================================================
FILE: stage2/01-sys-tweaks/00-patches/04-inputrc.diff
================================================
Index: jessie-stage2/rootfs/etc/inputrc
===================================================================
--- jessie-stage2.orig/rootfs/etc/inputrc
+++ jessie-stage2/rootfs/etc/inputrc
@@ -65,3 +65,7 @@ $endif
 # "\e[F": end-of-line
 
 $endif
+
+# mappings for up and down arrows search history
+# "\e[B": history-search-forward
+# "\e[A": history-search-backward


================================================
FILE: stage2/01-sys-tweaks/00-patches/05-path.diff
================================================
Index: jessie-stage2/rootfs/etc/login.defs
===================================================================
--- jessie-stage2.orig/rootfs/etc/login.defs
+++ jessie-stage2/rootfs/etc/login.defs
@@ -100,7 +100,7 @@ HUSHLOGIN_FILE	.hushlogin
 #
 # (they are minimal, add the rest in the shell startup files)
 ENV_SUPATH	PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
-ENV_PATH	PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
+ENV_PATH        PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
 
 #
 # Terminal permissions
Index: jessie-stage2/rootfs/etc/profile
===================================================================
--- jessie-stage2.orig/rootfs/etc/profile
+++ jessie-stage2/rootfs/etc/profile
@@ -4,7 +4,7 @@
 if [ "`id -u`" -eq 0 ]; then
   PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 else
-  PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
+  PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games"
 fi
 export PATH
 


================================================
FILE: stage2/01-sys-tweaks/00-patches/07-resize-init.diff
================================================
--- a/rootfs/boot/cmdline.txt
+++ b/rootfs/boot/cmdline.txt
@@ -1 +1 @@
-dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
+dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet init=/usr/lib/raspi-config/init_resize.sh


================================================
FILE: stage2/01-sys-tweaks/00-patches/series
================================================
01-useradd.diff
02-swap.diff
04-inputrc.diff
05-path.diff
07-resize-init.diff


================================================
FILE: stage2/01-sys-tweaks/01-run.sh
================================================
#!/bin/bash -e

install -m 755 files/resize2fs_once	"${ROOTFS_DIR}/etc/init.d/"

install -d				"${ROOTFS_DIR}/etc/systemd/system/rc-local.service.d"
install -m 644 files/ttyoutput.conf	"${ROOTFS_DIR}/etc/systemd/system/rc-local.service.d/"

install -m 644 files/50raspi		"${ROOTFS_DIR}/etc/apt/apt.conf.d/"

install -m 644 files/console-setup   	"${ROOTFS_DIR}/etc/default/"

install -m 755 files/rc.local		"${ROOTFS_DIR}/etc/"

on_chroot << EOF
systemctl disable hwclock.sh
systemctl disable nfs-common
systemctl disable rpcbind
if [ "${ENABLE_SSH}" == "1" ]; then
	systemctl enable ssh
else
	systemctl disable ssh
fi
systemctl enable regenerate_ssh_host_keys
EOF

if [ "${USE_QEMU}" = "1" ]; then
	echo "enter QEMU mode"
	install -m 644 files/90-qemu.rules "${ROOTFS_DIR}/etc/udev/rules.d/"
	on_chroot << EOF
systemctl disable resize2fs_once
EOF
	echo "leaving QEMU mode"
else
	on_chroot << EOF
systemctl enable resize2fs_once
EOF
fi

on_chroot <<EOF
for GRP in input spi i2c gpio; do
	groupadd -f -r "\$GRP"
done
for GRP in adm dialout cdrom audio users sudo video games plugdev input gpio spi i2c netdev; do
  adduser $FIRST_USER_NAME \$GRP
done
EOF

on_chroot << EOF
setupcon --force --save-only -v
EOF

on_chroot << EOF
usermod --pass='*' root
EOF

rm -f "${ROOTFS_DIR}/etc/ssh/"ssh_host_*_key*


================================================
FILE: stage2/01-sys-tweaks/files/50raspi
================================================
# never use pdiffs. Current implementation is very slow on low-powered devices
Acquire::PDiffs "0";

# download up to 5 pdiffs:
#Acquire::PDiffs::FileLimit "5";


================================================
FILE: stage2/01-sys-tweaks/files/90-qemu.rules
================================================
KERNEL=="sda", SYMLINK+="mmcblk0"
KERNEL=="sda?", SYMLINK+="mmcblk0p%n"
KERNEL=="sda2", SYMLINK+="root"


================================================
FILE: stage2/01-sys-tweaks/files/console-setup
================================================
# CONFIGURATION FILE FOR SETUPCON

# Consult the console-setup(5) manual page.

ACTIVE_CONSOLES="/dev/tty[1-6]"

CHARMAP="UTF-8"

CODESET="guess"
FONTFACE=""
FONTSIZE=""

VIDEOMODE=

# The following is an example how to use a braille font
# FONT='lat9w-08.psf.gz brl-8x8.psf'


================================================
FILE: stage2/01-sys-tweaks/files/rc.local
================================================
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

exit 0


================================================
FILE: stage2/01-sys-tweaks/files/resize2fs_once
================================================
#!/bin/sh
### BEGIN INIT INFO
# Provides:          resize2fs_once
# Required-Start:
# Required-Stop:
# Default-Start: 3
# Default-Stop:
# Short-Description: Resize the root filesystem to fill partition
# Description:
### END INIT INFO
. /lib/lsb/init-functions
case "$1" in
  start)
    log_daemon_msg "Starting resize2fs_once"
    ROOT_DEV=$(findmnt / -o source -n) &&
    resize2fs $ROOT_DEV &&
    update-rc.d resize2fs_once remove &&
    rm /etc/init.d/resize2fs_once &&
    log_end_msg $?
    ;;
  *)
    echo "Usage: $0 start" >&2
    exit 3
    ;;
esac


================================================
FILE: stage2/01-sys-tweaks/files/ttyoutput.conf
================================================
[Service]
StandardOutput=tty


================================================
FILE: stage2/02-net-tweaks/00-packages
================================================
wpasupplicant wireless-tools firmware-atheros firmware-brcm80211 firmware-libertas firmware-misc-nonfree firmware-realtek
raspberrypi-net-mods
dhcpcd5
net-tools


================================================
FILE: stage2/02-net-tweaks/01-run.sh
================================================
#!/bin/bash -e

install -v -d					"${ROOTFS_DIR}/etc/systemd/system/dhcpcd.service.d"
install -v -m 644 files/wait.conf		"${ROOTFS_DIR}/etc/systemd/system/dhcpcd.service.d/"

install -v -d					"${ROOTFS_DIR}/etc/wpa_supplicant"
install -v -m 600 files/wpa_supplicant.conf	"${ROOTFS_DIR}/etc/wpa_supplicant/"

if [ -v WPA_COUNTRY ]; then
	echo "country=${WPA_COUNTRY}" >> "${ROOTFS_DIR}/etc/wpa_supplicant/wpa_supplicant.conf"
fi

if [ -v WPA_ESSID ] && [ -v WPA_PASSWORD ]; then
on_chroot <<EOF
wpa_passphrase "${WPA_ESSID}" "${WPA_PASSWORD}" >> "/etc/wpa_supplicant/wpa_supplicant.conf"
EOF
fi

# Disable wifi on 5GHz models
mkdir -p "${ROOTFS_DIR}/var/lib/systemd/rfkill/"
echo 1 > "${ROOTFS_DIR}/var/lib/systemd/rfkill/platform-3f300000.mmc:wlan"
echo 1 > "${ROOTFS_DIR}/var/lib/systemd/rfkill/platform-fe300000.mmc:wlan"


================================================
FILE: stage2/02-net-tweaks/files/wait.conf
================================================
[Service]
ExecStart=
ExecStart=/usr/lib/dhcpcd5/dhcpcd -q -w


================================================
FILE: stage2/02-net-tweaks/files/wpa_supplicant.conf
================================================
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1


================================================
FILE: stage2/03-accept-mathematica-eula/00-debconf
================================================
# Do you accept the Wolfram - Raspberry Pi® Bundle License Agreement?
wolfram-engine  shared/accepted-wolfram-eula    boolean true


================================================
FILE: stage2/03-set-timezone/02-run.sh
================================================
#!/bin/bash -e

echo "Europe/London" > "${ROOTFS_DIR}/etc/timezone"
rm "${ROOTFS_DIR}/etc/localtime"

on_chroot << EOF
dpkg-reconfigure -f noninteractive tzdata
EOF


================================================
FILE: stage2/04-ethereum/00-packages
================================================
vim screen jq dirmngr


================================================
FILE: stage2/04-ethereum/01-run.sh
================================================
#!/bin/bash -e

install -m 644 files/ethonarm.list			    ${ROOTFS_DIR}/etc/apt/sources.list.d/ 
install -m 755 files/init_resize.sh			    ${ROOTFS_DIR}/usr/lib/raspi-config	
install -m 644 files/dphys-swapfile			    ${ROOTFS_DIR}/etc/
install -m 644 files/zram-default/armbian-zram-config	    ${ROOTFS_DIR}/etc/default
install -D -m 755 files/zram-lib/armbian-zram-config	    ${ROOTFS_DIR}/usr/lib/armbian/armbian-zram-config
install -m 644 files/armbian-ramlog			    ${ROOTFS_DIR}/etc/default
install -m 644 files/armbian-zram-config.service	    ${ROOTFS_DIR}/etc/systemd/system/

cat <<EOF >> ${ROOTFS_DIR}/etc/bash.bashrc
alias update-ethereum='
sudo apt-get update
sudo apt-get install geth nethermind swarm ipfs parity raiden status.im-node vipnode'
EOF

on_chroot <<EOF
# Add EthRaspbian APT key
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8A584409D327B0A5
# Install Ethereum packages
apt-get update && apt-get install geth
apt-get install swarm parity nethermind ipfs raiden status.im-node vipnode
# Force password change on Ethereum account
#chage -d 0 ethereum
# enable zram-service
systemctl enable armbian-zram-config
EOF



================================================
FILE: stage2/04-ethereum/files/armbian-ramlog
================================================
# configuration values for the armbian-ram-logging service
#
# enable the armbian-ram-logging service?
ENABLED=true
#
# size of the tmpfs mount -- please keep in mind to adjust /etc/default/armbian-zram-config too when increasing
SIZE=50M
#
# use rsync instead of cp -r
# requires rsync installed, may provide better performance
# due to copying only new and changed files
USE_RSYNC=true


================================================
FILE: stage2/04-ethereum/files/armbian-zram-config.service
================================================
# Armbian ZRAM configuration service
# Create 1 + number of cores compressed block devices
# This service may block the boot process for up to 30 sec
[Unit]
Description=Armbian ZRAM config
DefaultDependencies=no
After=local-fs.target
Before=armbian-ramlog.target
Conflicts=shutdown.target
[Service]
Type=oneshot
ExecStart=/usr/lib/armbian/armbian-zram-config start
ExecStop=/usr/lib/armbian/armbian-zram-config stop
RemainAfterExit=yes
TimeoutStartSec=30sec
[Install]
WantedBy=sysinit.target


================================================
FILE: stage2/04-ethereum/files/dphys-swapfile
================================================
# /etc/dphys-swapfile - user settings for dphys-swapfile package
# author Neil Franklin, last modification 2010.05.05
# copyright ETH Zuerich Physics Departement
#   use under either modified/non-advertising BSD or GPL license

# this file is sourced with . so full normal sh syntax applies

# the default settings are added as commented out CONF_*=* lines


# where we want the swapfile to be, this is the default
#CONF_SWAPFILE=/var/swap

# set size to absolute value, leaving empty (default) then uses computed value
#   you most likely don't want this, unless you have an special disk situation
CONF_MAXSWAP=6144
CONF_SWAPSIZE=6144
CONF_SWAPFILE=/home/ethereum/swapfile
# set size to computed value, this times RAM size, dynamically adapts,
#   guarantees that there is enough swap without wasting disk space on excess
#CONF_SWAPFACTOR=2

# restrict size (computed and absolute!) to maximally this limit
#   can be set to empty for no limit, but beware of filled partitions!
#   this is/was a (outdated?) 32bit kernel limit (in MBytes), do not overrun it
#   but is also sensible on 64bit to prevent filling /var or even / partition
#CONF_MAXSWAP=2048


================================================
FILE: stage2/04-ethereum/files/ethonarm-rpi4-ubuntu64bit-install.sh
================================================
#!/bin/bash
#
# Copyright (c) Ethereum on ARM
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
#
# https://github.com/diglos/pi-gen
#
# This script turns James Chambers Ubuntu 64bit image for Raspberry Pi 4 into a full Ethereum node
# You need to install a Raspbian image and run the script "ethonarm-rpi4-ubuntu64bit-setup.sh" before running this script
#
# More information about the image here:
#
# https://jamesachambers.com/raspberry-pi-4-ubuntu-server-desktop-18-04-3-image-unofficial/
# https://github.com/TheRemote/Ubuntu-Server-raspi4-unofficial
#

# Modify hostname (ethnode-$MAC-HASH-CHUNK)
echo Changing hostname
MAC_HASH=`cat /sys/class/net/eth0/address | sha256sum | awk '{print substr($0,0,9)}'`
echo ethnode-$MAC_HASH > /etc/hostname
sed -i "s/127.0.1.1.*/127.0.1.1\tethnode-$MAC_HASH/g" /etc/hosts

# Mount /home and add entry to fstab
echo Mounting /home
mount /dev/sda1 /home
echo '/dev/sda1 /home ext4 defaults 0 2' >> /etc/fstab

# Create Ethereum account
echo "Creating ethereum  user"
if ! id -u ethereum >/dev/null 2>&1; then
        adduser --disabled-password --gecos "" ethereum
fi

echo "ethereum:ethereum" | chpasswd
for GRP in sudo netdev audio video dialout plugdev bluetooth; do
	adduser ethereum $GRP
done

# Force password change on first login for security reasons
chage -d 0 ethereum


# Create some swap memory in the USB device for avoiding memory issues.
echo "Creating swap memory and activating Zram"
if stat  /dev/sda > /dev/null 2>&1;
then
	mkdir -p /home/ethereum/swap
	dd if=/dev/zero of=/home/ethereum/swap/swapfile bs=16k count=256k
	chmod 600 /home/ethereum/swap/swapfile
	mkswap /home/ethereum/swap/swapfile
	swapon /home/ethereum/swap/swapfile
	echo "/home/ethereum/swap/swapfile none swap sw 0 0" >> /etc/fstab
else
	echo no swap created
fi

mkdir -p /usr/lib/armbian
# Enable Zram (based on ARMBIAN script)
cat << EOF | tee /etc/default/armbian-zram-config >/dev/null
# configuration values for the armbian-zram-config service
#
# enable the armbian-zram-config service
ENABLED=true
ZRAM_PERCENTAGE=25
EOF

# Enable Zram (ARMBIAN script)
cat << 'EOF' | tee /usr/lib/armbian/armbian-zram-config >/dev/null
#!/bin/bash
#
# Copyright (c) Authors: http://www.armbian.com/authors
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.

# Functions:
#
# activate_zram_swap
# activate_ramlog_partition
# activate_compressed_tmp


# Read in basic OS image information
#. /etc/armbian-release
# and script configuration
#. /usr/lib/armbian/armbian-common

# It's possible to override ZRAM_PERCENTAGE, ZRAM_MAX_DEVICES, SWAP_ALGORITHM,
# RAMLOG_ALGORITHM and TMP_ALGORITHM here:
[ -f /etc/default/armbian-zram-config ] && . /etc/default/armbian-zram-config

activate_zram_swap() {
	# Do not interfere with already present config-zram package
	dpkg -l | grep -q 'zram-config' && exit 0

	[[ "$ENABLED" != "true" ]] && exit 0

	# Load zram module with n instances for swap: one per CPU core, $ZRAM_MAX_DEVICES
	# defines the maximum, on modern kernels we overwrite this with 1 and rely on
	# max_comp_streams being set to count of CPU cores or $ZRAM_MAX_DEVICES
	uname -r | grep -q '^3.' && zram_max_devs=${ZRAM_MAX_DEVICES:=4} || zram_max_devs=1
	cpu_cores=$(grep -c '^processor' /proc/cpuinfo | sed 's/^0$/1/')
	[[ ${cpu_cores} -gt ${zram_max_devs} ]] && zram_devices=${zram_max_devs} || zram_devices=${cpu_cores}
	module_args="$(modinfo zram | awk -F" " '/num_devices/ {print $2}' | cut -f1 -d:)"
	[[ -n ${module_args} ]] && modprobe zram ${module_args}=$(( ${zram_devices} + 2 )) || return

	# Expose 50% of real memory as swap space by default
	zram_percent=${ZRAM_PERCENTAGE:=50}
	mem_info=$(LC_ALL=C free -w 2>/dev/null | grep "^Mem" || LC_ALL=C free | grep "^Mem")
	memory_total=$(awk '{printf("%d",$2*1024)}' <<<${mem_info})
	mem_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${zram_percent} / 100 ))

	# Limit memory available to zram to 50% by default
	mem_limit_percent=${MEM_LIMIT_PERCENTAGE:=50}
	mem_limit_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${mem_limit_percent} / 100 ))

	swap_algo=${SWAP_ALGORITHM:=lzo}
	for (( i=1; i<=zram_devices; i++ )); do
		[[ -f /sys/block/zram${i}/comp_algorithm ]] && echo ${swap_algo} >/sys/block/zram${i}/comp_algorithm 2>/dev/null
		if [ "X${ZRAM_BACKING_DEV}" != "X" ]; then
			echo ${ZRAM_BACKING_DEV} >/sys/block/zram${i}/backing_dev
		fi
		echo -n ${ZRAM_MAX_DEVICES:=4} > /sys/block/zram${i}/max_comp_streams
		echo -n ${mem_per_zram_device} > /sys/block/zram${i}/disksize
		echo -n ${mem_limit_per_zram_device} > /sys/block/zram${i}/mem_limit
		mkswap /dev/zram${i}
		swapon -p 5 /dev/zram${i}
	done

	# Swapping to HDDs is stupid so switch to settings made for flash memory and zram/zswap
	echo 0 > /proc/sys/vm/page-cluster

	echo -e "\n### Activated ${zram_devices} ${swap_algo} zram swap devices with $(( ${mem_per_zram_device} / 1048576 )) MB each\n" >>${Log}
} # activate_zram_swap

activate_ramlog_partition() {
	# /dev/zram0 will be used as a compressed /var/log partition in RAM if
	# ENABLED=true in /etc/default/armbian-ramlog is set
	ENABLED=$(awk -F"=" '/^ENABLED/ {print $2}' /etc/default/armbian-ramlog)
	[[ "$ENABLED" != "true" ]] && return
	
	# read size also from /etc/default/armbian-ramlog
	ramlogsize=$(awk -F"=" '/^SIZE/ {print $2}' /etc/default/armbian-ramlog)
	disksize=$(sed -e 's/M$/*1048576/' -e 's/K$/*1024/' <<<${ramlogsize:=50M} | bc)

	# choose RAMLOG_ALGORITHM if defined in /etc/default/armbian-zram-config
	# otherwise try to choose most efficient compression scheme available.
	# See https://patchwork.kernel.org/patch/9918897/
	if [ "X${RAMLOG_ALGORITHM}" = "X" ]; then
		for algo in lz4 lz4hc quicklz zlib brotli zstd ; do
			echo ${algo} >/sys/block/zram0/comp_algorithm 2>/dev/null
		done
	else
		echo ${RAMLOG_ALGORITHM} >/sys/block/zram0/comp_algorithm 2>/dev/null
	fi
	echo -n ${disksize} > /sys/block/zram0/disksize

	# if it fails, select $swap_algo. Workaround for some older kernels
	if [[ $? == 1 ]]; then
		echo ${swap_algo} > /sys/block/zram0/comp_algorithm 2>/dev/null
		echo -n ${disksize} > /sys/block/zram0/disksize
	fi

	mkfs.ext4 -O ^has_journal -s 1024 -L log2ram /dev/zram0
	algo=$(sed 's/.*\[\([^]]*\)\].*/\1/g' </sys/block/zram0/comp_algorithm)
	echo -e "### Activated Armbian ramlog partition with ${algo} compression" >>${Log}
} # activate_ramlog_partition

activate_compressed_tmp() {
	# create /tmp not as tmpfs but zram compressed if no fstab entry exists
	grep -q '^tmpfs /tmp' /etc/mtab && return

	tmp_device=$(( ${zram_devices} + 1 ))
	if [[ -f /sys/block/zram${tmp_device}/comp_algorithm ]]; then
		if [ "X${TMP_ALGORITHM}" = "X" ]; then
			echo ${swap_algo} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null
		else
			echo ${TMP_ALGORITHM} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null
		fi
	fi
	echo -n $(( ${memory_total} / 2 )) > /sys/block/zram${tmp_device}/disksize
	mkfs.ext4 -O ^has_journal -s 1024 -L tmp /dev/zram${tmp_device}
	mount -o nosuid,discard /dev/zram${tmp_device} /tmp
	chmod 777 /tmp
	algo=$(sed 's/.*\[\([^]]*\)\].*/\1/g' </sys/block/zram${tmp_device}/comp_algorithm)
} # activate_compressed_tmp

case $1 in
	*start*)
		activate_zram_swap
		activate_ramlog_partition
		activate_compressed_tmp
		;;
esac
EOF

cat << 'EOF' | tee /etc/systemd/system/armbian-zram-config.service >/dev/null
# Armbian ZRAM configuration service
# Create 1 + number of cores compressed block devices
# This service may block the boot process for up to 30 sec

[Unit]
Description=Armbian ZRAM config
DefaultDependencies=no
After=local-fs.target
Before=armbian-ramlog.target
Conflicts=shutdown.target

[Service]
Type=oneshot
ExecStart=/usr/lib/armbian/armbian-zram-config start
ExecStop=/usr/lib/armbian/armbian-zram-config stop
RemainAfterExit=yes
TimeoutStartSec=30sec

[Install]
WantedBy=sysinit.target
EOF

cat << 'EOF' | tee /etc/default/armbian-ramlog >/dev/null
# configuration values for the armbian-ram-logging service
#
# enable the armbian-ram-logging service?
ENABLED=true
#
# size of the tmpfs mount -- please keep in mind to adjust /etc/default/armbian-zram-config too when increasing
SIZE=50M
#
# use rsync instead of cp -r
# requires rsync installed, may provide better performance
# due to copying only new and changed files
USE_RSYNC=true
EOF

chmod +x /usr/lib/armbian/armbian-zram-config
systemctl enable armbian-zram-config

# Swap and Zram tweaks
# Page allocation error workout
echo "vm.min_free_kbytes=65536" >> /etc/sysctl.conf
# Modify swappiness parameter
echo "vm.swappiness=100" >> /etc/sysctl.conf

# Ethereum software installation
# Add APT EthRaspbian repository
echo "Adding Ethereum repositories"
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8A584409D327B0A5
add-apt-repository -n "deb http://apt.ethraspbian.com bionic main"
add-apt-repository -n "deb http://apt.ethraspbian.com bionic-security main"
add-apt-repository "deb http://apt.ethraspbian.com bionic-upgrades main"

# Install Ethereum packages
echo Installing Ethereum packages
apt-get install geth
apt-get install parity swarm parity ipfs raiden status.im-node vipnode prysm-beacon prysm-validator lighthouse

# Set Geth cache to 512
echo 'ARGS="--lightserv 25 --lightpeers 25 --maxpeers 128 --cache 512"' > /etc/ethereum/geth.conf

echo "Done. Please, reboot the systems for changes to take effect"

exit 0


================================================
FILE: stage2/04-ethereum/files/ethonarm-rpi4-ubuntu64bit-setup.sh
================================================
#!/bin/bash
#
# Copyright (c) Ethereum on ARM
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
#
# https://github.com/diglos/pi-gen

# Update kernel and firmware
apt-get update && apt-get dist-upgrade -y
rpi-update <<EOF
y
EOF
rpi-eeprom-update -a

# Format USB SSD and mount it as /home
echo Formatting USB disk. Please be patient
if stat  /dev/sda > /dev/null 2>&1;
then
        echo Formatting USB Drive...
        fdisk /dev/sda <<EOF
d
n
p
1


w
EOF
mkfs.ext4 -F /dev/sda1
else
        echo no SDD detected
fi

echo Done!, please flash James Chambers Ubuntu server image on this MicroSD card

exit 0


================================================
FILE: stage2/04-ethereum/files/ethonarm.list
================================================
deb http://apt.ethraspbian.com buster main
deb http://apt.ethraspbian.com buster-security main
deb http://apt.ethraspbian.com buster-upgrades main


================================================
FILE: stage2/04-ethereum/files/grafana/prometheus
================================================
# Set the command-line arguments to pass to the server.
ARGS="--storage.tsdb.path="/home/prometheus/metrics2/""

# Prometheus supports the following options:
#  --config.file="/etc/prometheus/prometheus.yml"
#                             Prometheus configuration file path.
#  --web.listen-address="0.0.0.0:9090"
#                             Address to listen on for UI, API, and telemetry.
#  --web.read-timeout=5m      Maximum duration before timing out read of the
#                             request, and closing idle connections.
#  --web.max-connections=512  Maximum number of simultaneous connections.
#  --web.external-url=<URL>   The URL under which Prometheus is externally
#                             reachable (for example, if Prometheus is served
#                             via a reverse proxy). Used for generating
#                             relative and absolute links back to Prometheus
#                             itself. If the URL has a path portion, it will
#                             be used to prefix all HTTP endpoints served by
#                             Prometheus. If omitted, relevant URL components
#                             will be derived automatically.
#  --web.route-prefix=<path>  Prefix for the internal routes of web endpoints.
#                             Defaults to path of --web.external-url.
#  --web.local-assets="/usr/share/prometheus/web/"
#                             Path to static asset/templates directory.
#  --web.user-assets=<path>   Path to static asset directory, available at
#                             /user.
#  --web.enable-lifecycle     Enable shutdown and reload via HTTP request.
#  --web.enable-admin-api     Enables API endpoints for admin control actions.
#  --web.console.templates="/etc/prometheus/consoles"
#                             Path to the console template directory,
#                             available at /consoles.
#  --web.console.libraries="/etc/prometheus/console_libraries"
#                             Path to the console library directory.
#   --storage.tsdb.path="/home/prometheus/metrics2/"
#                             Base path for metrics storage.
#  --storage.tsdb.min-block-duration=2h
#                             Minimum duration of a data block before being
#                             persisted.
#  --storage.tsdb.max-block-duration=<duration>
#                             Maximum duration compacted blocks may span.
#                             (Defaults to 10% of the retention period)
#  --storage.tsdb.retention=15d
#                             How long to retain samples in the storage.
#  --storage.tsdb.use-lockfile
#                             Create a lockfile in data directory.
#  --alertmanager.notification-queue-capacity=10000
#                             The capacity of the queue for pending alert
#                             manager notifications.
#  --alertmanager.timeout=10s
#                             Timeout for sending alerts to Alertmanager.
#  --query.lookback-delta=5m  The delta difference allowed for retrieving
#                             metrics during expression evaluations.
#  --query.timeout=2m         Maximum time a query may take before being
#                             aborted.
#  --query.max-concurrency=20
#                             Maximum number of queries executed concurrently.
#  --log.level=info           Only log messages with the given severity or
#                             above. One of: [debug, info, warn, error]


================================================
FILE: stage2/04-ethereum/files/grafana/prometheus-node-exporter
================================================
# Set the command-line arguments to pass to the server.
# Due to shell scaping, to pass backslashes for regexes, you need to double
# them (\\d for \d). If running under systemd, you need to double them again
# (\\\\d to mean \d), and escape newlines too.
ARGS="--collector.textfile.directory="/home/prometheus/node-exporter"

# Prometheus-node-exporter supports the following options:
#
#  --collector.diskstats.ignored-devices="^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\\d+n\\d+p)\\d+$"
#                            Regexp of devices to ignore for diskstats.
#  --collector.filesystem.ignored-mount-points="^/(dev|proc|run|sys|mnt|media|var/lib/docker)($|/)"
#                            Regexp of mount points to ignore for filesystem
#                            collector.
#  --collector.filesystem.ignored-fs-types="^(autofs|binfmt_misc|cgroup|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|mqueue|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|sysfs|tracefs)$"
#                            Regexp of filesystem types to ignore for
#                            filesystem collector.
#  --collector.netdev.ignored-devices="^lo$"
#                            Regexp of net devices to ignore for netdev
#                            collector.
#  --collector.netstat.fields="^(.*_(InErrors|InErrs)|Ip_Forwarding|Ip(6|Ext)_(InOctets|OutOctets)|Icmp6?_(InMsgs|OutMsgs)|TcpExt_(Listen.*|Syncookies.*)|Tcp_(ActiveOpens|PassiveOpens|RetransSegs|CurrEstab)|Udp6?_(InDatagrams|OutDatagrams|NoPorts))$"
#                            Regexp of fields to return for netstat
#                            collector.
#  --collector.ntp.server="127.0.0.1"
#                            NTP server to use for ntp collector
#  --collector.ntp.protocol-version=4
#                            NTP protocol version
#  --collector.ntp.server-is-local
#                            Certify that collector.ntp.server address is the
#                            same local host as this collector.
#  --collector.ntp.ip-ttl=1  IP TTL to use while sending NTP query
#  --collector.ntp.max-distance=3.46608s
#                            Max accumulated distance to the root
#  --collector.ntp.local-offset-tolerance=1ms
#                            Offset between local clock and local ntpd time
#                            to tolerate
#  --path.procfs="/proc"     procfs mountpoint.
#  --path.sysfs="/sys"       sysfs mountpoint.
#  --collector.qdisc.fixtures=""
#                            test fixtures to use for qdisc collector
#                            end-to-end testing
#  --collector.runit.servicedir="/etc/service"
#                            Path to runit service directory.
#  --collector.supervisord.url="http://localhost:9001/RPC2"
#                            XML RPC endpoint.
#  --collector.systemd.unit-whitelist=".+"
#                            Regexp of systemd units to whitelist. Units must
#                            both match whitelist and not match blacklist to
#                            be included.
#  --collector.systemd.unit-blacklist=".+(\\.device|\\.scope|\\.slice|\\.target)"
#                            Regexp of systemd units to blacklist. Units must
#                            both match whitelist and not match blacklist to
#                            be included.
#  --collector.systemd.private
#                            Establish a private, direct connection to
#                            systemd without dbus.
# --collector.textfile.directory="/home/prometheus/node-exporter"
#                            Directory to read text files with metrics from.
#  --collector.vmstat.fields="^(oom_kill|pgpg|pswp|pg.*fault).*"
#                            Regexp of fields to return for vmstat collector.
#  --collector.wifi.fixtures=""
#                            test fixtures to use for wifi collector metrics
#  --collector.arp           Enable the arp collector (default: enabled).
#  --collector.bcache        Enable the bcache collector (default: enabled).
#  --collector.bonding       Enable the bonding collector (default: enabled).
#  --collector.buddyinfo     Enable the buddyinfo collector (default:
#                            disabled).
#  --collector.conntrack     Enable the conntrack collector (default:
#                            enabled).
#  --collector.cpu           Enable the cpu collector (default: enabled).
#  --collector.diskstats     Enable the diskstats collector (default:
#                            enabled).
#  --collector.drbd          Enable the drbd collector (default: disabled).
#  --collector.edac          Enable the edac collector (default: enabled).
#  --collector.entropy       Enable the entropy collector (default: enabled).
#  --collector.filefd        Enable the filefd collector (default: enabled).
#  --collector.filesystem    Enable the filesystem collector (default:
#                            enabled).
#  --collector.hwmon         Enable the hwmon collector (default: enabled).
#  --collector.infiniband    Enable the infiniband collector (default:
#                            enabled).
#  --collector.interrupts    Enable the interrupts collector (default:
#                            disabled).
#  --collector.ipvs          Enable the ipvs collector (default: enabled).
#  --collector.ksmd          Enable the ksmd collector (default: disabled).
#  --collector.loadavg       Enable the loadavg collector (default: enabled).
#  --collector.logind        Enable the logind collector (default: disabled).
#  --collector.mdadm         Enable the mdadm collector (default: enabled).
#  --collector.meminfo       Enable the meminfo collector (default: enabled).
#  --collector.meminfo_numa  Enable the meminfo_numa collector (default:
#                            disabled).
#  --collector.mountstats    Enable the mountstats collector (default:
#                            disabled).
#  --collector.netdev        Enable the netdev collector (default: enabled).
#  --collector.netstat       Enable the netstat collector (default: enabled).
#  --collector.nfs           Enable the nfs collector (default: enabled).
#  --collector.nfsd          Enable the nfsd collector (default: enabled).
#  --collector.ntp           Enable the ntp collector (default: disabled).
#  --collector.qdisc         Enable the qdisc collector (default: disabled).
#  --collector.runit         Enable the runit collector (default: disabled).
#  --collector.sockstat      Enable the sockstat collector (default:
#                            enabled).
#  --collector.stat          Enable the stat collector (default: enabled).
#  --collector.supervisord   Enable the supervisord collector (default:
#                            disabled).
#  --collector.systemd       Enable the systemd collector (default: enabled).
#  --collector.tcpstat       Enable the tcpstat collector (default:
#                            disabled).
#  --collector.textfile      Enable the textfile collector (default:
#                            enabled).
#  --collector.time          Enable the time collector (default: enabled).
#  --collector.uname         Enable the uname collector (default: enabled).
#  --collector.vmstat        Enable the vmstat collector (default: enabled).
#  --collector.wifi          Enable the wifi collector (default: enabled).
#  --collector.xfs           Enable the xfs collector (default: enabled).
#  --collector.zfs           Enable the zfs collector (default: enabled).
#  --collector.timex         Enable the timex collector (default: enabled).
#  --web.listen-address=":9100"
#                            Address on which to expose metrics and web
#                            interface.
#  --web.telemetry-path="/metrics"
#                            Path under which to expose metrics.
#  --log.level="info"        Only log messages with the given severity or
#                            above. Valid levels: [debug, info, warn, error,
#                            fatal]
#  --log.format="logger:stderr"
#                            Set the log target and format. Example:
#                            "logger:syslog?appname=bob&local=7" or
#                            "logger:stdout?json=true"


================================================
FILE: stage2/04-ethereum/files/grafana/prometheus.yml
================================================
# Sample config for Prometheus.

global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
      monitor: 'example'

# Alertmanager configuration
alerting:
  alertmanagers:
  - static_configs:
    - targets: ['localhost:9093']

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'prometheus'

    # Override the global default and scrape targets from this job every 5 seconds.
    scrape_interval: 5s
    scrape_timeout: 5s

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
      - targets: ['localhost:9090']

  - job_name: node
    # If prometheus-node-exporter is installed, grab stats about the local
    # machine by default.
    static_configs:
      - targets: ['localhost:9100']
  - job_name: geth
    scrape_interval: 15s
    scrape_timeout: 10s
    metrics_path: /debug/metrics/prometheus
    scheme: http
    static_configs:
      - targets: ['localhost:6060']
  - job_name: besu-dev
    scrape_interval: 15s
    scrape_timeout: 10s
    metrics_path: /metrics
    scheme: http
    static_configs:
      - targets: ['localhost:9545']
  - job_name: 'validator'
    static_configs:
      - targets: ['localhost:8081']
  - job_name: 'beacon node'
    static_configs:
      - targets: ['localhost:8080']
  - job_name: 'lighthouse'
    static_configs:
      - targets: ['localhost:5052']
  - job_name: "nimbus"
    static_configs:
      - targets: ['127.0.0.1:8008']



================================================
FILE: stage2/04-ethereum/files/grafana-eth2-onyx/prometheus
================================================
# Set the command-line arguments to pass to the server.
ARGS="--storage.tsdb.path="/home/prometheus/metrics2/""

# Prometheus supports the following options:
#  --config.file="/etc/prometheus/prometheus.yml"
#                             Prometheus configuration file path.
#  --web.listen-address="0.0.0.0:9090"
#                             Address to listen on for UI, API, and telemetry.
#  --web.read-timeout=5m      Maximum duration before timing out read of the
#                             request, and closing idle connections.
#  --web.max-connections=512  Maximum number of simultaneous connections.
#  --web.external-url=<URL>   The URL under which Prometheus is externally
#                             reachable (for example, if Prometheus is served
#                             via a reverse proxy). Used for generating
#                             relative and absolute links back to Prometheus
#                             itself. If the URL has a path portion, it will
#                             be used to prefix all HTTP endpoints served by
#                             Prometheus. If omitted, relevant URL components
#                             will be derived automatically.
#  --web.route-prefix=<path>  Prefix for the internal routes of web endpoints.
#                             Defaults to path of --web.external-url.
#  --web.local-assets="/usr/share/prometheus/web/"
#                             Path to static asset/templates directory.
#  --web.user-assets=<path>   Path to static asset directory, available at
#                             /user.
#  --web.enable-lifecycle     Enable shutdown and reload via HTTP request.
#  --web.enable-admin-api     Enables API endpoints for admin control actions.
#  --web.console.templates="/etc/prometheus/consoles"
#                             Path to the console template directory,
#                             available at /consoles.
#  --web.console.libraries="/etc/prometheus/console_libraries"
#                             Path to the console library directory.
#   --storage.tsdb.path="/home/prometheus/metrics2/"
#                             Base path for metrics storage.
#  --storage.tsdb.min-block-duration=2h
#                             Minimum duration of a data block before being
#                             persisted.
#  --storage.tsdb.max-block-duration=<duration>
#                             Maximum duration compacted blocks may span.
#                             (Defaults to 10% of the retention period)
#  --storage.tsdb.retention=15d
#                             How long to retain samples in the storage.
#  --storage.tsdb.use-lockfile
#                             Create a lockfile in data directory.
#  --alertmanager.notification-queue-capacity=10000
#                             The capacity of the queue for pending alert
#                             manager notifications.
#  --alertmanager.timeout=10s
#                             Timeout for sending alerts to Alertmanager.
#  --query.lookback-delta=5m  The delta difference allowed for retrieving
#                             metrics during expression evaluations.
#  --query.timeout=2m         Maximum time a query may take before being
#                             aborted.
#  --query.max-concurrency=20
#                             Maximum number of queries executed concurrently.
#  --log.level=info           Only log messages with the given severity or
#                             above. One of: [debug, info, warn, error]


================================================
FILE: stage2/04-ethereum/files/grafana-eth2-onyx/prometheus-node-exporter
================================================
# Set the command-line arguments to pass to the server.
# Due to shell scaping, to pass backslashes for regexes, you need to double
# them (\\d for \d). If running under systemd, you need to double them again
# (\\\\d to mean \d), and escape newlines too.
ARGS="--collector.textfile.directory="/home/prometheus/node-exporter"

# Prometheus-node-exporter supports the following options:
#
#  --collector.diskstats.ignored-devices="^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\\d+n\\d+p)\\d+$"
#                            Regexp of devices to ignore for diskstats.
#  --collector.filesystem.ignored-mount-points="^/(dev|proc|run|sys|mnt|media|var/lib/docker)($|/)"
#                            Regexp of mount points to ignore for filesystem
#                            collector.
#  --collector.filesystem.ignored-fs-types="^(autofs|binfmt_misc|cgroup|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|mqueue|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|sysfs|tracefs)$"
#                            Regexp of filesystem types to ignore for
#                            filesystem collector.
#  --collector.netdev.ignored-devices="^lo$"
#                            Regexp of net devices to ignore for netdev
#                            collector.
#  --collector.netstat.fields="^(.*_(InErrors|InErrs)|Ip_Forwarding|Ip(6|Ext)_(InOctets|OutOctets)|Icmp6?_(InMsgs|OutMsgs)|TcpExt_(Listen.*|Syncookies.*)|Tcp_(ActiveOpens|PassiveOpens|RetransSegs|CurrEstab)|Udp6?_(InDatagrams|OutDatagrams|NoPorts))$"
#                            Regexp of fields to return for netstat
#                            collector.
#  --collector.ntp.server="127.0.0.1"
#                            NTP server to use for ntp collector
#  --collector.ntp.protocol-version=4
#                            NTP protocol version
#  --collector.ntp.server-is-local
#                            Certify that collector.ntp.server address is the
#                            same local host as this collector.
#  --collector.ntp.ip-ttl=1  IP TTL to use while sending NTP query
#  --collector.ntp.max-distance=3.46608s
#                            Max accumulated distance to the root
#  --collector.ntp.local-offset-tolerance=1ms
#                            Offset between local clock and local ntpd time
#                            to tolerate
#  --path.procfs="/proc"     procfs mountpoint.
#  --path.sysfs="/sys"       sysfs mountpoint.
#  --collector.qdisc.fixtures=""
#                            test fixtures to use for qdisc collector
#                            end-to-end testing
#  --collector.runit.servicedir="/etc/service"
#                            Path to runit service directory.
#  --collector.supervisord.url="http://localhost:9001/RPC2"
#                            XML RPC endpoint.
#  --collector.systemd.unit-whitelist=".+"
#                            Regexp of systemd units to whitelist. Units must
#                            both match whitelist and not match blacklist to
#                            be included.
#  --collector.systemd.unit-blacklist=".+(\\.device|\\.scope|\\.slice|\\.target)"
#                            Regexp of systemd units to blacklist. Units must
#                            both match whitelist and not match blacklist to
#                            be included.
#  --collector.systemd.private
#                            Establish a private, direct connection to
#                            systemd without dbus.
# --collector.textfile.directory="/home/prometheus/node-exporter"
#                            Directory to read text files with metrics from.
#  --collector.vmstat.fields="^(oom_kill|pgpg|pswp|pg.*fault).*"
#                            Regexp of fields to return for vmstat collector.
#  --collector.wifi.fixtures=""
#                            test fixtures to use for wifi collector metrics
#  --collector.arp           Enable the arp collector (default: enabled).
#  --collector.bcache        Enable the bcache collector (default: enabled).
#  --collector.bonding       Enable the bonding collector (default: enabled).
#  --collector.buddyinfo     Enable the buddyinfo collector (default:
#                            disabled).
#  --collector.conntrack     Enable the conntrack collector (default:
#                            enabled).
#  --collector.cpu           Enable the cpu collector (default: enabled).
#  --collector.diskstats     Enable the diskstats collector (default:
#                            enabled).
#  --collector.drbd          Enable the drbd collector (default: disabled).
#  --collector.edac          Enable the edac collector (default: enabled).
#  --collector.entropy       Enable the entropy collector (default: enabled).
#  --collector.filefd        Enable the filefd collector (default: enabled).
#  --collector.filesystem    Enable the filesystem collector (default:
#                            enabled).
#  --collector.hwmon         Enable the hwmon collector (default: enabled).
#  --collector.infiniband    Enable the infiniband collector (default:
#                            enabled).
#  --collector.interrupts    Enable the interrupts collector (default:
#                            disabled).
#  --collector.ipvs          Enable the ipvs collector (default: enabled).
#  --collector.ksmd          Enable the ksmd collector (default: disabled).
#  --collector.loadavg       Enable the loadavg collector (default: enabled).
#  --collector.logind        Enable the logind collector (default: disabled).
#  --collector.mdadm         Enable the mdadm collector (default: enabled).
#  --collector.meminfo       Enable the meminfo collector (default: enabled).
#  --collector.meminfo_numa  Enable the meminfo_numa collector (default:
#                            disabled).
#  --collector.mountstats    Enable the mountstats collector (default:
#                            disabled).
#  --collector.netdev        Enable the netdev collector (default: enabled).
#  --collector.netstat       Enable the netstat collector (default: enabled).
#  --collector.nfs           Enable the nfs collector (default: enabled).
#  --collector.nfsd          Enable the nfsd collector (default: enabled).
#  --collector.ntp           Enable the ntp collector (default: disabled).
#  --collector.qdisc         Enable the qdisc collector (default: disabled).
#  --collector.runit         Enable the runit collector (default: disabled).
#  --collector.sockstat      Enable the sockstat collector (default:
#                            enabled).
#  --collector.stat          Enable the stat collector (default: enabled).
#  --collector.supervisord   Enable the supervisord collector (default:
#                            disabled).
#  --collector.systemd       Enable the systemd collector (default: enabled).
#  --collector.tcpstat       Enable the tcpstat collector (default:
#                            disabled).
#  --collector.textfile      Enable the textfile collector (default:
#                            enabled).
#  --collector.time          Enable the time collector (default: enabled).
#  --collector.uname         Enable the uname collector (default: enabled).
#  --collector.vmstat        Enable the vmstat collector (default: enabled).
#  --collector.wifi          Enable the wifi collector (default: enabled).
#  --collector.xfs           Enable the xfs collector (default: enabled).
#  --collector.zfs           Enable the zfs collector (default: enabled).
#  --collector.timex         Enable the timex collector (default: enabled).
#  --web.listen-address=":9100"
#                            Address on which to expose metrics and web
#                            interface.
#  --web.telemetry-path="/metrics"
#                            Path under which to expose metrics.
#  --log.level="info"        Only log messages with the given severity or
#                            above. Valid levels: [debug, info, warn, error,
#                            fatal]
#  --log.format="logger:stderr"
#                            Set the log target and format. Example:
#                            "logger:syslog?appname=bob&local=7" or
#                            "logger:stdout?json=true"


================================================
FILE: stage2/04-ethereum/files/grafana-eth2-onyx/prometheus.yml
================================================
# Sample config for Prometheus.

global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
      monitor: 'example'

# Alertmanager configuration
alerting:
  alertmanagers:
  - static_configs:
    - targets: ['localhost:9093']

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'prometheus'

    # Override the global default and scrape targets from this job every 5 seconds.
    scrape_interval: 5s
    scrape_timeout: 5s

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
      - targets: ['localhost:9090']

  - job_name: node
    # If prometheus-node-exporter is installed, grab stats about the local
    # machine by default.
    static_configs:
      - targets: ['localhost:9100']
  - job_name: geth
    scrape_interval: 15s
    scrape_timeout: 10s
    metrics_path: /debug/metrics/prometheus
    scheme: http
    static_configs:
      - targets: ['localhost:6060']
  - job_name: besu-dev
    scrape_interval: 15s
    scrape_timeout: 10s
    metrics_path: /metrics
    scheme: http
    static_configs:
      - targets: ['localhost:9545']
  - job_name: 'validator'
    static_configs:
      - targets: ['localhost:8081']
  - job_name: 'beacon node'
    static_configs:
      - targets: ['localhost:8080']


================================================
FILE: stage2/04-ethereum/files/init_resize.sh
================================================
#!/bin/sh

reboot_pi () {
  umount /boot
  mount / -o remount,ro
  sync
  if [ "$NOOBS" = "1" ]; then
    if [ "$NEW_KERNEL" = "1" ]; then
      reboot -f "$BOOT_PART_NUM"
    else
      echo "$BOOT_PART_NUM" > "/sys/module/${BCM_MODULE}/parameters/reboot_part"
    fi
  fi
  echo b > /proc/sysrq-trigger
  sleep 5
  exit 0
}

check_commands () {
  if ! command -v whiptail > /dev/null; then
      echo "whiptail not found"
      sleep 5
      return 1
  fi
  for COMMAND in grep cut sed parted fdisk findmnt partprobe; do
    if ! command -v $COMMAND > /dev/null; then
      FAIL_REASON="$COMMAND not found"
      return 1
    fi
  done
  return 0
}

check_noobs () {
  if [ "$BOOT_PART_NUM" = "1" ]; then
    NOOBS=0
  else
    NOOBS=1
  fi
}

get_variables () {
  ROOT_PART_DEV=$(findmnt / -o source -n)
  ROOT_PART_NAME=$(echo "$ROOT_PART_DEV" | cut -d "/" -f 3)
  ROOT_DEV_NAME=$(echo /sys/block/*/"${ROOT_PART_NAME}" | cut -d "/" -f 4)
  ROOT_DEV="/dev/${ROOT_DEV_NAME}"
  ROOT_PART_NUM=$(cat "/sys/block/${ROOT_DEV_NAME}/${ROOT_PART_NAME}/partition")

  BOOT_PART_DEV=$(findmnt /boot -o source -n)
  BOOT_PART_NAME=$(echo "$BOOT_PART_DEV" | cut -d "/" -f 3)
  BOOT_DEV_NAME=$(echo /sys/block/*/"${BOOT_PART_NAME}" | cut -d "/" -f 4)
  BOOT_PART_NUM=$(cat "/sys/block/${BOOT_DEV_NAME}/${BOOT_PART_NAME}/partition")

  OLD_DISKID=$(fdisk -l "$ROOT_DEV" | sed -n 's/Disk identifier: 0x\([^ ]*\)/\1/p')

  check_noobs

  ROOT_DEV_SIZE=$(cat "/sys/block/${ROOT_DEV_NAME}/size")
  TARGET_END=$((ROOT_DEV_SIZE - 1))

  PARTITION_TABLE=$(parted -m "$ROOT_DEV" unit s print | tr -d 's')

  LAST_PART_NUM=$(echo "$PARTITION_TABLE" | tail -n 1 | cut -d ":" -f 1)

  ROOT_PART_LINE=$(echo "$PARTITION_TABLE" | grep -e "^${ROOT_PART_NUM}:")
  ROOT_PART_START=$(echo "$ROOT_PART_LINE" | cut -d ":" -f 2)
  ROOT_PART_END=$(echo "$ROOT_PART_LINE" | cut -d ":" -f 3)

  if [ "$NOOBS" = "1" ]; then
    EXT_PART_LINE=$(echo "$PARTITION_TABLE" | grep ":::;" | head -n 1)
    EXT_PART_NUM=$(echo "$EXT_PART_LINE" | cut -d ":" -f 1)
    EXT_PART_START=$(echo "$EXT_PART_LINE" | cut -d ":" -f 2)
    EXT_PART_END=$(echo "$EXT_PART_LINE" | cut -d ":" -f 3)
  fi
}

fix_partuuid() {
  DISKID="$(fdisk -l "$ROOT_DEV" | sed -n 's/Disk identifier: 0x\([^ ]*\)/\1/p')"

  sed -i "s/${OLD_DISKID}/${DISKID}/g" /etc/fstab
  sed -i "s/${OLD_DISKID}/${DISKID}/" /boot/cmdline.txt
}

check_variables () {
  if [ "$NOOBS" = "1" ]; then
    if [ "$EXT_PART_NUM" -gt 4 ] || \
       [ "$EXT_PART_START" -gt "$ROOT_PART_START" ] || \
       [ "$EXT_PART_END" -lt "$ROOT_PART_END" ]; then
      FAIL_REASON="Unsupported extended partition"
      return 1
    fi
  fi

  if [ "$BOOT_DEV_NAME" != "$ROOT_DEV_NAME" ]; then
      FAIL_REASON="Boot and root partitions are on different devices"
      return 1
  fi

  if [ "$ROOT_PART_NUM" -ne "$LAST_PART_NUM" ]; then
    FAIL_REASON="Root partition should be last partition"
    return 1
  fi

  if [ "$ROOT_PART_END" -gt "$TARGET_END" ]; then
    FAIL_REASON="Root partition runs past the end of device"
    return 1
  fi

  if [ ! -b "$ROOT_DEV" ] || [ ! -b "$ROOT_PART_DEV" ] || [ ! -b "$BOOT_PART_DEV" ] ; then
    FAIL_REASON="Could not determine partitions"
    return 1
  fi
}

check_kernel () {
  local MAJOR=$(uname -r | cut -f1 -d.)
  local MINOR=$(uname -r | cut -f2 -d.)
  if [ "$MAJOR" -eq "4" ] && [ "$MINOR" -lt "9" ]; then
    return 0
  fi
  if [ "$MAJOR" -lt "4" ]; then
    return 0
  fi
  NEW_KERNEL=1
}

ethereum_setup () {

# hack to modify hostname in EthRaspbian
MAC_HASH=`cat /sys/class/net/eth0/address | sha256sum | awk '{print substr($0,0,9)}'`
echo ethnode-$MAC_HASH > /etc/hostname
sed -i "s/127.0.1.1.*/127.0.1.1\tethnode-$MAC_HASH/g" /etc/hosts

# Format USB3 SSD and mount it as /home

echo Looking for USB drive
sleep 20

if stat  /dev/sda > /dev/null 2>&1;
then
	echo USB drive found
	sleep 2 
        echo Partitioning and formatting USB Drive...
        fdisk /dev/sda <<EOF
d
n
p
1


w
EOF
mkfs.ext4 -F /dev/sda1
echo '/dev/sda1 /home ext4 defaults 0 2' >> /etc/fstab && mount /home
else
        echo no SDD detected
	sleep 5
fi

# Create Ethereum account
echo "Creating ethereum  user for Geth and Parity"
if ! id -u ethereum >/dev/null 2>&1; then
        adduser --disabled-password --gecos "" ethereum
fi

echo "ethereum:ethereum" | chpasswd
for GRP in sudo netdev audio video dialout plugdev bluetooth; do
	adduser ethereum $GRP
done

# Force password change on first login
chage -d 0 ethereum

# Delete pi user
userdel -r pi

# Enable 64bit Kernel for fixing memory allocation issues
echo arm_64bit=1 >> /boot/config.txt

# Change swappiness default value to force using Zram
echo "vm.swappiness=100" >> /etc/sysctl.conf

}

main () {
  get_variables

  if ! check_variables; then
    return 1
  fi

  check_kernel

  if [ "$NOOBS" = "1" ] && [ "$NEW_KERNEL" != "1" ]; then
    BCM_MODULE=$(grep -e "^Hardware" /proc/cpuinfo | cut -d ":" -f 2 | tr -d " " | tr '[:upper:]' '[:lower:]')
    if ! modprobe "$BCM_MODULE"; then
      FAIL_REASON="Couldn't load BCM module $BCM_MODULE"
      return 1
    fi
  fi

  if [ "$ROOT_PART_END" -eq "$TARGET_END" ]; then
    reboot_pi
  fi

  if [ "$NOOBS" = "1" ]; then
    if ! parted -m "$ROOT_DEV" u s resizepart "$EXT_PART_NUM" yes "$TARGET_END"; then
      FAIL_REASON="Extended partition resize failed"
      return 1
    fi
  fi

  if ! parted -m "$ROOT_DEV" u s resizepart "$ROOT_PART_NUM" "$TARGET_END"; then
    FAIL_REASON="Root partition resize failed"
    return 1
  fi

  partprobe "$ROOT_DEV"
  fix_partuuid
  ethereum_setup

  return 0
}

mount -t proc proc /proc
mount -t sysfs sys /sys
mount -t tmpfs tmp /run
mkdir -p /run/systemd

mount /boot
mount / -o remount,rw

sed -i 's| init=/usr/lib/raspi-config/init_resize\.sh||' /boot/cmdline.txt
sed -i 's| sdhci\.debug_quirks2=4||' /boot/cmdline.txt

if ! grep -q splash /boot/cmdline.txt; then
  sed -i "s/ quiet//g" /boot/cmdline.txt
fi

sync

echo 1 > /proc/sys/kernel/sysrq

if ! check_commands; then
  reboot_pi
fi

if main; then
  whiptail --infobox "Resized root filesystem. Rebooting in 5 seconds..." 20 60
  sleep 5
else
  sleep 5
  whiptail --msgbox "Could not expand filesystem, please try raspi-config or rc_gui.\n${FAIL_REASON}" 20 60
fi

reboot_pi


================================================
FILE: stage2/04-ethereum/files/rc.local.eth1
================================================
#!/bin/bash
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# This script turns the Ubuntu 64 bit image into an Ethereum on ARM image
#

FLAG="/root/first-run.flag"
if [ ! -f $FLAG ]; then
   # Modify hostname (ethnode-$MAC-HASH-CHUNK)
   echo Changing hostname
   MAC_HASH=`cat /sys/class/net/eth0/address | sha256sum | awk '{print substr($0,0,9)}'`
   echo ethnode-$MAC_HASH > /etc/hostname
   sed -i "s/127.0.0.1.*/127.0.0.1\tethnode-$MAC_HASH/g" /etc/hosts

   # Format USB3 SSD and mount it as /home

   echo Looking for USB drive

   if stat  /dev/sda > /dev/null 2>&1;
     then
     	echo USB drive found
        echo Partitioning and formatting USB Drive...
        fdisk /dev/sda <<EOF
d
n
p
1



w
EOF

	mkfs.ext4 -F /dev/sda1
	echo '/dev/sda1 /home ext4 defaults 0 2' >> /etc/fstab && mount /home
   else
        echo no SDD detected
   fi

   # Create Ethereum account
   echo "Creating ethereum  user for Geth and Parity"
   if ! id -u ethereum >/dev/null 2>&1; then
	adduser --disabled-password --gecos "" ethereum
   fi

   echo "ethereum:ethereum" | chpasswd
   for GRP in sudo netdev audio video dialout plugdev bluetooth; do
	adduser ethereum $GRP
   done

   # Force password change on first login
   chage -d 0 ethereum

# Create some swap memory in the USB device for avoiding memory issues.
  echo "Creating swap memory and activating Zram"
  if stat  /dev/sda > /dev/null 2>&1;
	then
		mkdir -p /home/ethereum/swap
		dd if=/dev/zero of=/home/ethereum/swap/swapfile bs=16k count=256k
		chmod 600 /home/ethereum/swap/swapfile
		mkswap /home/ethereum/swap/swapfile
		swapon /home/ethereum/swap/swapfile
		echo "/home/ethereum/swap/swapfile none swap sw 0 0" >> /etc/fstab
	else
		echo no swap created
   fi

# Enable Zram (based on ARMBIAN script)
  mkdir -p /usr/lib/armbian

  cat << EOF | tee /etc/default/armbian-zram-config >/dev/null
# configuration values for the armbian-zram-config service
#
# enable the armbian-zram-config service
ENABLED=true
ZRAM_PERCENTAGE=25
EOF

  # Enable Zram (ARMBIAN script)
  cat << 'EOF' | tee /usr/lib/armbian/armbian-zram-config >/dev/null
#!/bin/bash
#
# Copyright (c) Authors: http://www.armbian.com/authors
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# Functions:
#
# activate_zram_swap
# activate_ramlog_partition
# activate_compressed_tmp
# Read in basic OS image information
#. /etc/armbian-release
# and script configuration
#. /usr/lib/armbian/armbian-common
# It's possible to override ZRAM_PERCENTAGE, ZRAM_MAX_DEVICES, SWAP_ALGORITHM,
# RAMLOG_ALGORITHM and TMP_ALGORITHM here:
[ -f /etc/default/armbian-zram-config ] && . /etc/default/armbian-zram-config
activate_zram_swap() {
	# Do not interfere with already present config-zram package
	dpkg -l | grep -q 'zram-config' && exit 0
	[[ "$ENABLED" != "true" ]] && exit 0
	# Load zram module with n instances for swap: one per CPU core, $ZRAM_MAX_DEVICES
	# defines the maximum, on modern kernels we overwrite this with 1 and rely on
	# max_comp_streams being set to count of CPU cores or $ZRAM_MAX_DEVICES
	uname -r | grep -q '^3.' && zram_max_devs=${ZRAM_MAX_DEVICES:=4} || zram_max_devs=1
	cpu_cores=$(grep -c '^processor' /proc/cpuinfo | sed 's/^0$/1/')
	[[ ${cpu_cores} -gt ${zram_max_devs} ]] && zram_devices=${zram_max_devs} || zram_devices=${cpu_cores}
	module_args="$(modinfo zram | awk -F" " '/num_devices/ {print $2}' | cut -f1 -d:)"
	[[ -n ${module_args} ]] && modprobe zram ${module_args}=$(( ${zram_devices} + 2 )) || return
	# Expose 50% of real memory as swap space by default
	zram_percent=${ZRAM_PERCENTAGE:=50}
	mem_info=$(LC_ALL=C free -w 2>/dev/null | grep "^Mem" || LC_ALL=C free | grep "^Mem")
	memory_total=$(awk '{printf("%d",$2*1024)}' <<<${mem_info})
	mem_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${zram_percent} / 100 ))
	# Limit memory available to zram to 50% by default
	mem_limit_percent=${MEM_LIMIT_PERCENTAGE:=50}
	mem_limit_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${mem_limit_percent} / 100 ))
	swap_algo=${SWAP_ALGORITHM:=lzo}
	for (( i=1; i<=zram_devices; i++ )); do
		[[ -f /sys/block/zram${i}/comp_algorithm ]] && echo ${swap_algo} >/sys/block/zram${i}/comp_algorithm 2>/dev/null
		if [ "X${ZRAM_BACKING_DEV}" != "X" ]; then
			echo ${ZRAM_BACKING_DEV} >/sys/block/zram${i}/backing_dev
		fi
		echo -n ${ZRAM_MAX_DEVICES:=4} > /sys/block/zram${i}/max_comp_streams
		echo -n ${mem_per_zram_device} > /sys/block/zram${i}/disksize
		echo -n ${mem_limit_per_zram_device} > /sys/block/zram${i}/mem_limit
		mkswap /dev/zram${i}
		swapon -p 5 /dev/zram${i}
	done
	# Swapping to HDDs is stupid so switch to settings made for flash memory and zram/zswap
	echo 0 > /proc/sys/vm/page-cluster
	echo -e "\n### Activated ${zram_devices} ${swap_algo} zram swap devices with $(( ${mem_per_zram_device} / 1048576 )) MB each\n" >>${Log}
} # activate_zram_swap
activate_ramlog_partition() {
	# /dev/zram0 will be used as a compressed /var/log partition in RAM if
	# ENABLED=true in /etc/default/armbian-ramlog is set
	ENABLED=$(awk -F"=" '/^ENABLED/ {print $2}' /etc/default/armbian-ramlog)
	[[ "$ENABLED" != "true" ]] && return
	
	# read size also from /etc/default/armbian-ramlog
	ramlogsize=$(awk -F"=" '/^SIZE/ {print $2}' /etc/default/armbian-ramlog)
	disksize=$(sed -e 's/M$/*1048576/' -e 's/K$/*1024/' <<<${ramlogsize:=50M} | bc)
	# choose RAMLOG_ALGORITHM if defined in /etc/default/armbian-zram-config
	# otherwise try to choose most efficient compression scheme available.
	# See https://patchwork.kernel.org/patch/9918897/
	if [ "X${RAMLOG_ALGORITHM}" = "X" ]; then
		for algo in lz4 lz4hc quicklz zlib brotli zstd ; do
			echo ${algo} >/sys/block/zram0/comp_algorithm 2>/dev/null
		done
	else
		echo ${RAMLOG_ALGORITHM} >/sys/block/zram0/comp_algorithm 2>/dev/null
	fi
	echo -n ${disksize} > /sys/block/zram0/disksize
	# if it fails, select $swap_algo. Workaround for some older kernels
	if [[ $? == 1 ]]; then
		echo ${swap_algo} > /sys/block/zram0/comp_algorithm 2>/dev/null
		echo -n ${disksize} > /sys/block/zram0/disksize
	fi
	mkfs.ext4 -O ^has_journal -s 1024 -L log2ram /dev/zram0
	algo=$(sed 's/.*\[\([^]]*\)\].*/\1/g' </sys/block/zram0/comp_algorithm)
	echo -e "### Activated Armbian ramlog partition with ${algo} compression" >>${Log}
} # activate_ramlog_partition
activate_compressed_tmp() {
	# create /tmp not as tmpfs but zram compressed if no fstab entry exists
	grep -q '^tmpfs /tmp' /etc/mtab && return
	tmp_device=$(( ${zram_devices} + 1 ))
	if [[ -f /sys/block/zram${tmp_device}/comp_algorithm ]]; then
		if [ "X${TMP_ALGORITHM}" = "X" ]; then
			echo ${swap_algo} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null
		else
			echo ${TMP_ALGORITHM} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null
		fi
	fi
	echo -n $(( ${memory_total} / 2 )) > /sys/block/zram${tmp_device}/disksize
	mkfs.ext4 -O ^has_journal -s 1024 -L tmp /dev/zram${tmp_device}
	mount -o nosuid,discard /dev/zram${tmp_device} /tmp
	chmod 777 /tmp
	algo=$(sed 's/.*\[\([^]]*\)\].*/\1/g' </sys/block/zram${tmp_device}/comp_algorithm)
} # activate_compressed_tmp
case $1 in
	*start*)
		activate_zram_swap
		activate_ramlog_partition
		activate_compressed_tmp
		;;
esac
EOF

  cat << 'EOF' | tee /etc/systemd/system/armbian-zram-config.service >/dev/null
# Armbian ZRAM configuration service
# Create 1 + number of cores compressed block devices
# This service may block the boot process for up to 30 sec
[Unit]
Description=Armbian ZRAM config
DefaultDependencies=no
After=local-fs.target
Before=armbian-ramlog.target
Conflicts=shutdown.target
[Service]
Type=oneshot
ExecStart=/usr/lib/armbian/armbian-zram-config start
ExecStop=/usr/lib/armbian/armbian-zram-config stop
RemainAfterExit=yes
TimeoutStartSec=30sec
[Install]
WantedBy=sysinit.target
EOF

  cat << 'EOF' | tee /etc/default/armbian-ramlog >/dev/null
# configuration values for the armbian-ram-logging service
#
# enable the armbian-ram-logging service?
ENABLED=true
#
# size of the tmpfs mount -- please keep in mind to adjust /etc/default/armbian-zram-config too when increasing
SIZE=50M
#
# use rsync instead of cp -r
# requires rsync installed, may provide better performance
# due to copying only new and changed files
USE_RSYNC=true
EOF

  chmod +x /usr/lib/armbian/armbian-zram-config
  systemctl enable armbian-zram-config

  # Swap and Zram tweaks
  # Page allocation error workout
  echo "vm.min_free_kbytes=65536" >> /etc/sysctl.conf
  # Modify swappiness parameter
  echo "vm.swappiness=100" >> /etc/sysctl.conf


  # Ethereum software installation
  # Add APT EthRaspbian repository
  sleep 25
  echo "Adding Ethereum repositories"
  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8A584409D327B0A5
  add-apt-repository -n "deb http://apt.ethraspbian.com bionic main"
  add-apt-repository -n "deb http://apt.ethraspbian.com bionic-security main"
  add-apt-repository "deb http://apt.ethraspbian.com bionic-upgrades main"

  # Install Ethereum packages
  echo Installing Ethereum packages
  apt-get -y install geth
  # Stop Geth until first reboot in order to avoid slowing the install process
  systemctl stop geth
  apt-get -y install parity nethermind hyperledger-besu swarm ipfs raiden statusd vipnode prysm-beacon prysm-validator prysm-slasher lighthouse


  # Create an alias for package updates
  cat <<EOF >> /etc/bash.bashrc
alias update-ethereum='
sudo apt-get update
sudo apt-get install geth parity nethermind hyperledger-besu swarm ipfs raiden statusd vipnode prysm-beacon prysm-validator prysm-slasher lighthouse'
EOF
   # Install monitoring infrastructure
   wget -P /tmp https://dl.grafana.com/oss/release/grafana_6.7.3_arm64.deb
   dpkg -i /tmp/grafana_6.7.3_arm64.deb
   useradd -m prometheus
   mkdir -p /home/prometheus/node-exporter/
   chown -R  prometheus:prometheus /home/prometheus/
   apt install -y prometheus prometheus-node-exporter
   chown grafana:grafana /root/tmp/grafana.db
   cp -a /root/tmp/grafana.db /var/lib/grafana/grafana.db
   cp -a /root/tmp/{prometheus,prometheus-node-exporter} /etc/default
   cp -a /root/tmp/prometheus.yml /etc/prometheus/
   systemctl enable grafana-server

   #the next line creates an empty file so it won't run the next boot
   touch $FLAG
   reboot
else
   echo "Nothing to do"
fi

exit 0


================================================
FILE: stage2/04-ethereum/files/rc.local.eth2
================================================
#!/bin/bash
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# This script turns the Ubuntu 64 bit image into an Ethereum on ARM image
#

FLAG="/root/first-run.flag"
if [ ! -f $FLAG ]; then
   # Modify hostname (ethnode-$MAC-HASH-CHUNK)
   echo Changing hostname
   MAC_HASH=`cat /sys/class/net/eth0/address | sha256sum | awk '{print substr($0,0,9)}'`
   echo ethnode-$MAC_HASH > /etc/hostname
   sed -i "s/127.0.0.1.*/127.0.0.1\tethnode-$MAC_HASH/g" /etc/hosts

   # Format USB3 SSD and mount it as /home

   echo Looking for USB drive

   if stat  /dev/sda > /dev/null 2>&1;
     then
     	echo USB drive found
        echo Partitioning and formatting USB Drive...
        fdisk /dev/sda <<EOF
d
n
p
1



w
EOF

	mkfs.ext4 -F /dev/sda1
	echo '/dev/sda1 /home ext4 defaults 0 2' >> /etc/fstab && mount /home
   else
        echo no SDD detected
   fi

   # Create Ethereum account
   echo "Creating ethereum  user for Geth and Parity"
   if ! id -u ethereum >/dev/null 2>&1; then
	adduser --disabled-password --gecos "" ethereum
   fi

   echo "ethereum:ethereum" | chpasswd
   for GRP in sudo netdev audio video dialout plugdev bluetooth; do
	adduser ethereum $GRP
   done

   # Force password change on first login
   chage -d 0 ethereum

# Create some swap memory in the USB device for avoiding memory issues.
  echo "Creating swap memory and activating Zram"
  if stat  /dev/sda > /dev/null 2>&1;
	then
		mkdir -p /home/ethereum/swap
		dd if=/dev/zero of=/home/ethereum/swap/swapfile bs=16k count=256k
		chmod 600 /home/ethereum/swap/swapfile
		mkswap /home/ethereum/swap/swapfile
		swapon /home/ethereum/swap/swapfile
		echo "/home/ethereum/swap/swapfile none swap sw 0 0" >> /etc/fstab
	else
		echo no swap created
   fi

# Enable Zram (based on ARMBIAN script)
  mkdir -p /usr/lib/armbian

  cat << EOF | tee /etc/default/armbian-zram-config >/dev/null
# configuration values for the armbian-zram-config service
#
# enable the armbian-zram-config service
ENABLED=true
ZRAM_PERCENTAGE=25
EOF

  # Enable Zram (ARMBIAN script)
  cat << 'EOF' | tee /usr/lib/armbian/armbian-zram-config >/dev/null
#!/bin/bash
#
# Copyright (c) Authors: http://www.armbian.com/authors
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# Functions:
#
# activate_zram_swap
# activate_ramlog_partition
# activate_compressed_tmp
# Read in basic OS image information
#. /etc/armbian-release
# and script configuration
#. /usr/lib/armbian/armbian-common
# It's possible to override ZRAM_PERCENTAGE, ZRAM_MAX_DEVICES, SWAP_ALGORITHM,
# RAMLOG_ALGORITHM and TMP_ALGORITHM here:
[ -f /etc/default/armbian-zram-config ] && . /etc/default/armbian-zram-config
activate_zram_swap() {
	# Do not interfere with already present config-zram package
	dpkg -l | grep -q 'zram-config' && exit 0
	[[ "$ENABLED" != "true" ]] && exit 0
	# Load zram module with n instances for swap: one per CPU core, $ZRAM_MAX_DEVICES
	# defines the maximum, on modern kernels we overwrite this with 1 and rely on
	# max_comp_streams being set to count of CPU cores or $ZRAM_MAX_DEVICES
	uname -r | grep -q '^3.' && zram_max_devs=${ZRAM_MAX_DEVICES:=4} || zram_max_devs=1
	cpu_cores=$(grep -c '^processor' /proc/cpuinfo | sed 's/^0$/1/')
	[[ ${cpu_cores} -gt ${zram_max_devs} ]] && zram_devices=${zram_max_devs} || zram_devices=${cpu_cores}
	module_args="$(modinfo zram | awk -F" " '/num_devices/ {print $2}' | cut -f1 -d:)"
	[[ -n ${module_args} ]] && modprobe zram ${module_args}=$(( ${zram_devices} + 2 )) || return
	# Expose 50% of real memory as swap space by default
	zram_percent=${ZRAM_PERCENTAGE:=50}
	mem_info=$(LC_ALL=C free -w 2>/dev/null | grep "^Mem" || LC_ALL=C free | grep "^Mem")
	memory_total=$(awk '{printf("%d",$2*1024)}' <<<${mem_info})
	mem_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${zram_percent} / 100 ))
	# Limit memory available to zram to 50% by default
	mem_limit_percent=${MEM_LIMIT_PERCENTAGE:=50}
	mem_limit_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${mem_limit_percent} / 100 ))
	swap_algo=${SWAP_ALGORITHM:=lzo}
	for (( i=1; i<=zram_devices; i++ )); do
		[[ -f /sys/block/zram${i}/comp_algorithm ]] && echo ${swap_algo} >/sys/block/zram${i}/comp_algorithm 2>/dev/null
		if [ "X${ZRAM_BACKING_DEV}" != "X" ]; then
			echo ${ZRAM_BACKING_DEV} >/sys/block/zram${i}/backing_dev
		fi
		echo -n ${ZRAM_MAX_DEVICES:=4} > /sys/block/zram${i}/max_comp_streams
		echo -n ${mem_per_zram_device} > /sys/block/zram${i}/disksize
		echo -n ${mem_limit_per_zram_device} > /sys/block/zram${i}/mem_limit
		mkswap /dev/zram${i}
		swapon -p 5 /dev/zram${i}
	done
	# Swapping to HDDs is stupid so switch to settings made for flash memory and zram/zswap
	echo 0 > /proc/sys/vm/page-cluster
	echo -e "\n### Activated ${zram_devices} ${swap_algo} zram swap devices with $(( ${mem_per_zram_device} / 1048576 )) MB each\n" >>${Log}
} # activate_zram_swap
activate_ramlog_partition() {
	# /dev/zram0 will be used as a compressed /var/log partition in RAM if
	# ENABLED=true in /etc/default/armbian-ramlog is set
	ENABLED=$(awk -F"=" '/^ENABLED/ {print $2}' /etc/default/armbian-ramlog)
	[[ "$ENABLED" != "true" ]] && return
	
	# read size also from /etc/default/armbian-ramlog
	ramlogsize=$(awk -F"=" '/^SIZE/ {print $2}' /etc/default/armbian-ramlog)
	disksize=$(sed -e 's/M$/*1048576/' -e 's/K$/*1024/' <<<${ramlogsize:=50M} | bc)
	# choose RAMLOG_ALGORITHM if defined in /etc/default/armbian-zram-config
	# otherwise try to choose most efficient compression scheme available.
	# See https://patchwork.kernel.org/patch/9918897/
	if [ "X${RAMLOG_ALGORITHM}" = "X" ]; then
		for algo in lz4 lz4hc quicklz zlib brotli zstd ; do
			echo ${algo} >/sys/block/zram0/comp_algorithm 2>/dev/null
		done
	else
		echo ${RAMLOG_ALGORITHM} >/sys/block/zram0/comp_algorithm 2>/dev/null
	fi
	echo -n ${disksize} > /sys/block/zram0/disksize
	# if it fails, select $swap_algo. Workaround for some older kernels
	if [[ $? == 1 ]]; then
		echo ${swap_algo} > /sys/block/zram0/comp_algorithm 2>/dev/null
		echo -n ${disksize} > /sys/block/zram0/disksize
	fi
	mkfs.ext4 -O ^has_journal -s 1024 -L log2ram /dev/zram0
	algo=$(sed 's/.*\[\([^]]*\)\].*/\1/g' </sys/block/zram0/comp_algorithm)
	echo -e "### Activated Armbian ramlog partition with ${algo} compression" >>${Log}
} # activate_ramlog_partition
activate_compressed_tmp() {
	# create /tmp not as tmpfs but zram compressed if no fstab entry exists
	grep -q '^tmpfs /tmp' /etc/mtab && return
	tmp_device=$(( ${zram_devices} + 1 ))
	if [[ -f /sys/block/zram${tmp_device}/comp_algorithm ]]; then
		if [ "X${TMP_ALGORITHM}" = "X" ]; then
			echo ${swap_algo} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null
		else
			echo ${TMP_ALGORITHM} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null
		fi
	fi
	echo -n $(( ${memory_total} / 2 )) > /sys/block/zram${tmp_device}/disksize
	mkfs.ext4 -O ^has_journal -s 1024 -L tmp /dev/zram${tmp_device}
	mount -o nosuid,discard /dev/zram${tmp_device} /tmp
	chmod 777 /tmp
	algo=$(sed 's/.*\[\([^]]*\)\].*/\1/g' </sys/block/zram${tmp_device}/comp_algorithm)
} # activate_compressed_tmp
case $1 in
	*start*)
		activate_zram_swap
		activate_ramlog_partition
		activate_compressed_tmp
		;;
esac
EOF

  cat << 'EOF' | tee /etc/systemd/system/armbian-zram-config.service >/dev/null
# Armbian ZRAM configuration service
# Create 1 + number of cores compressed block devices
# This service may block the boot process for up to 30 sec
[Unit]
Description=Armbian ZRAM config
DefaultDependencies=no
After=local-fs.target
Before=armbian-ramlog.target
Conflicts=shutdown.target
[Service]
Type=oneshot
ExecStart=/usr/lib/armbian/armbian-zram-config start
ExecStop=/usr/lib/armbian/armbian-zram-config stop
RemainAfterExit=yes
TimeoutStartSec=30sec
[Install]
WantedBy=sysinit.target
EOF

  cat << 'EOF' | tee /etc/default/armbian-ramlog >/dev/null
# configuration values for the armbian-ram-logging service
#
# enable the armbian-ram-logging service?
ENABLED=true
#
# size of the tmpfs mount -- please keep in mind to adjust /etc/default/armbian-zram-config too when increasing
SIZE=50M
#
# use rsync instead of cp -r
# requires rsync installed, may provide better performance
# due to copying only new and changed files
USE_RSYNC=true
EOF

  chmod +x /usr/lib/armbian/armbian-zram-config
  systemctl enable armbian-zram-config

  # Swap and Zram tweaks
  # Page allocation error workout
  echo "vm.min_free_kbytes=65536" >> /etc/sysctl.conf
  # Modify swappiness parameter
  echo "vm.swappiness=100" >> /etc/sysctl.conf


  # Ethereum software installation
  # Add APT EthRaspbian repository
  sleep 25
  echo "Adding Ethereum repositories"
  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8A584409D327B0A5
  add-apt-repository -n "deb http://apt.ethraspbian.com bionic main"
  add-apt-repository -n "deb http://apt.ethraspbian.com bionic-security main"
  add-apt-repository "deb http://apt.ethraspbian.com bionic-upgrades main"

  # Install Ethereum packages
  echo Installing Ethereum packages
  apt-get -y install prysm-beacon prysm-validator prysm-slasher lighthouse
  apt-get -y install geth parity nethermind hyperledger-besu swarm ipfs raiden statusd vipnode
  # Stop and disable Geth
  systemctl stop geth
  systemctl disable geth
  systemctl disable parity
  # Enable the beacon chain for next reboot
  systemctl enable prysm-beacon

  # Create an alias for package updates
  cat <<EOF >> /etc/bash.bashrc
alias update-ethereum='
sudo apt-get update
sudo apt-get install geth parity nethermind hyperledger-besu swarm ipfs raiden statusd vipnode prysm-beacon prysm-validator prysm-slasher lighthouse'
EOF
   # Install monitoring infrastructure
   wget -P /tmp https://dl.grafana.com/oss/release/grafana_6.7.3_arm64.deb
   dpkg -i /tmp/grafana_6.7.3_arm64.deb
   useradd -m prometheus
   mkdir -p /home/prometheus/node-exporter/
   chown -R  prometheus:prometheus /home/prometheus/
   apt install -y prometheus prometheus-node-exporter
   chown grafana:grafana /root/tmp/grafana.db
   cp -a /root/tmp/grafana.db /var/lib/grafana/grafana.db
   cp -a /root/tmp/{prometheus,prometheus-node-exporter} /etc/default
   cp -a /root/tmp/prometheus.yml /etc/prometheus/
   systemctl enable grafana-server

   #the next line creates an empty file so it won't run the next boot
   touch $FLAG
   reboot
else
   echo "Nothing to do"
fi

exit 0


================================================
FILE: stage2/04-ethereum/files/rc.local.eth2.medalla
================================================
#!/bin/bash
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# This script turns the Ubuntu 64 bit image into an Ethereum on ARM image
#

FLAG="/root/first-run.flag"
if [ ! -f $FLAG ]; then
   # Modify hostname (ethnode-$MAC-HASH-CHUNK)
   echo Changing hostname
   MAC_HASH=`cat /sys/class/net/eth0/address | sha256sum | awk '{print substr($0,0,9)}'`
   echo ethnode-$MAC_HASH > /etc/hostname
   sed -i "s/127.0.0.1.*/127.0.0.1\tethnode-$MAC_HASH/g" /etc/hosts

   # Format USB3 SSD and mount it as /home

   echo Looking for USB drive

   if stat  /dev/sda > /dev/null 2>&1;
     then
     	echo USB drive found
        echo Partitioning and formatting USB Drive...
        fdisk /dev/sda <<EOF
d
n
p
1



w
EOF

	mkfs.ext4 -F /dev/sda1
	echo '/dev/sda1 /home ext4 defaults 0 2' >> /etc/fstab && mount /home
   else
        echo no SDD detected
   fi

   # Create Ethereum account
   echo "Creating ethereum  user for Geth and Parity"
   if ! id -u ethereum >/dev/null 2>&1; then
	adduser --disabled-password --gecos "" ethereum
   fi

   echo "ethereum:ethereum" | chpasswd
   for GRP in sudo netdev audio video dialout plugdev bluetooth; do
	adduser ethereum $GRP
   done

   # Force password change on first login
   chage -d 0 ethereum

# Create some swap memory in the USB device for avoiding memory issues.
  echo "Creating swap memory and activating Zram"
  if stat  /dev/sda > /dev/null 2>&1;
	then
		mkdir -p /home/ethereum/swap
		dd if=/dev/zero of=/home/ethereum/swap/swapfile bs=16k count=256k
		chmod 600 /home/ethereum/swap/swapfile
		mkswap /home/ethereum/swap/swapfile
		swapon /home/ethereum/swap/swapfile
		echo "/home/ethereum/swap/swapfile none swap sw 0 0" >> /etc/fstab
	else
		echo no swap created
   fi

# Enable Zram (based on ARMBIAN script)
  mkdir -p /usr/lib/armbian

  cat << EOF | tee /etc/default/armbian-zram-config >/dev/null
# configuration values for the armbian-zram-config service
#
# enable the armbian-zram-config service
ENABLED=true
ZRAM_PERCENTAGE=25
EOF

  # Enable Zram (ARMBIAN script)
  cat << 'EOF' | tee /usr/lib/armbian/armbian-zram-config >/dev/null
#!/bin/bash
#
# Copyright (c) Authors: http://www.armbian.com/authors
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# Functions:
#
# activate_zram_swap
# activate_ramlog_partition
# activate_compressed_tmp
# Read in basic OS image information
#. /etc/armbian-release
# and script configuration
#. /usr/lib/armbian/armbian-common
# It's possible to override ZRAM_PERCENTAGE, ZRAM_MAX_DEVICES, SWAP_ALGORITHM,
# RAMLOG_ALGORITHM and TMP_ALGORITHM here:
[ -f /etc/default/armbian-zram-config ] && . /etc/default/armbian-zram-config
activate_zram_swap() {
	# Do not interfere with already present config-zram package
	dpkg -l | grep -q 'zram-config' && exit 0
	[[ "$ENABLED" != "true" ]] && exit 0
	# Load zram module with n instances for swap: one per CPU core, $ZRAM_MAX_DEVICES
	# defines the maximum, on modern kernels we overwrite this with 1 and rely on
	# max_comp_streams being set to count of CPU cores or $ZRAM_MAX_DEVICES
	uname -r | grep -q '^3.' && zram_max_devs=${ZRAM_MAX_DEVICES:=4} || zram_max_devs=1
	cpu_cores=$(grep -c '^processor' /proc/cpuinfo | sed 's/^0$/1/')
	[[ ${cpu_cores} -gt ${zram_max_devs} ]] && zram_devices=${zram_max_devs} || zram_devices=${cpu_cores}
	module_args="$(modinfo zram | awk -F" " '/num_devices/ {print $2}' | cut -f1 -d:)"
	[[ -n ${module_args} ]] && modprobe zram ${module_args}=$(( ${zram_devices} + 2 )) || return
	# Expose 50% of real memory as swap space by default
	zram_percent=${ZRAM_PERCENTAGE:=50}
	mem_info=$(LC_ALL=C free -w 2>/dev/null | grep "^Mem" || LC_ALL=C free | grep "^Mem")
	memory_total=$(awk '{printf("%d",$2*1024)}' <<<${mem_info})
	mem_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${zram_percent} / 100 ))
	# Limit memory available to zram to 50% by default
	mem_limit_percent=${MEM_LIMIT_PERCENTAGE:=50}
	mem_limit_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${mem_limit_percent} / 100 ))
	swap_algo=${SWAP_ALGORITHM:=lzo}
	for (( i=1; i<=zram_devices; i++ )); do
		[[ -f /sys/block/zram${i}/comp_algorithm ]] && echo ${swap_algo} >/sys/block/zram${i}/comp_algorithm 2>/dev/null
		if [ "X${ZRAM_BACKING_DEV}" != "X" ]; then
			echo ${ZRAM_BACKING_DEV} >/sys/block/zram${i}/backing_dev
		fi
		echo -n ${ZRAM_MAX_DEVICES:=4} > /sys/block/zram${i}/max_comp_streams
		echo -n ${mem_per_zram_device} > /sys/block/zram${i}/disksize
		echo -n ${mem_limit_per_zram_device} > /sys/block/zram${i}/mem_limit
		mkswap /dev/zram${i}
		swapon -p 5 /dev/zram${i}
	done
	# Swapping to HDDs is stupid so switch to settings made for flash memory and zram/zswap
	echo 0 > /proc/sys/vm/page-cluster
	echo -e "\n### Activated ${zram_devices} ${swap_algo} zram swap devices with $(( ${mem_per_zram_device} / 1048576 )) MB each\n" >>${Log}
} # activate_zram_swap
activate_ramlog_partition() {
	# /dev/zram0 will be used as a compressed /var/log partition in RAM if
	# ENABLED=true in /etc/default/armbian-ramlog is set
	ENABLED=$(awk -F"=" '/^ENABLED/ {print $2}' /etc/default/armbian-ramlog)
	[[ "$ENABLED" != "true" ]] && return
	
	# read size also from /etc/default/armbian-ramlog
	ramlogsize=$(awk -F"=" '/^SIZE/ {print $2}' /etc/default/armbian-ramlog)
	disksize=$(sed -e 's/M$/*1048576/' -e 's/K$/*1024/' <<<${ramlogsize:=50M} | bc)
	# choose RAMLOG_ALGORITHM if defined in /etc/default/armbian-zram-config
	# otherwise try to choose most efficient compression scheme available.
	# See https://patchwork.kernel.org/patch/9918897/
	if [ "X${RAMLOG_ALGORITHM}" = "X" ]; then
		for algo in lz4 lz4hc quicklz zlib brotli zstd ; do
			echo ${algo} >/sys/block/zram0/comp_algorithm 2>/dev/null
		done
	else
		echo ${RAMLOG_ALGORITHM} >/sys/block/zram0/comp_algorithm 2>/dev/null
	fi
	echo -n ${disksize} > /sys/block/zram0/disksize
	# if it fails, select $swap_algo. Workaround for some older kernels
	if [[ $? == 1 ]]; then
		echo ${swap_algo} > /sys/block/zram0/comp_algorithm 2>/dev/null
		echo -n ${disksize} > /sys/block/zram0/disksize
	fi
	mkfs.ext4 -O ^has_journal -s 1024 -L log2ram /dev/zram0
	algo=$(sed 's/.*\[\([^]]*\)\].*/\1/g' </sys/block/zram0/comp_algorithm)
	echo -e "### Activated Armbian ramlog partition with ${algo} compression" >>${Log}
} # activate_ramlog_partition
activate_compressed_tmp() {
	# create /tmp not as tmpfs but zram compressed if no fstab entry exists
	grep -q '^tmpfs /tmp' /etc/mtab && return
	tmp_device=$(( ${zram_devices} + 1 ))
	if [[ -f /sys/block/zram${tmp_device}/comp_algorithm ]]; then
		if [ "X${TMP_ALGORITHM}" = "X" ]; then
			echo ${swap_algo} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null
		else
			echo ${TMP_ALGORITHM} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null
		fi
	fi
	echo -n $(( ${memory_total} / 2 )) > /sys/block/zram${tmp_device}/disksize
	mkfs.ext4 -O ^has_journal -s 1024 -L tmp /dev/zram${tmp_device}
	mount -o nosuid,discard /dev/zram${tmp_device} /tmp
	chmod 777 /tmp
	algo=$(sed 's/.*\[\([^]]*\)\].*/\1/g' </sys/block/zram${tmp_device}/comp_algorithm)
} # activate_compressed_tmp
case $1 in
	*start*)
		activate_zram_swap
		activate_ramlog_partition
		activate_compressed_tmp
		;;
esac
EOF

  cat << 'EOF' | tee /etc/systemd/system/armbian-zram-config.service >/dev/null
# Armbian ZRAM configuration service
# Create 1 + number of cores compressed block devices
# This service may block the boot process for up to 30 sec
[Unit]
Description=Armbian ZRAM config
DefaultDependencies=no
After=local-fs.target
Before=armbian-ramlog.target
Conflicts=shutdown.target
[Service]
Type=oneshot
ExecStart=/usr/lib/armbian/armbian-zram-config start
ExecStop=/usr/lib/armbian/armbian-zram-config stop
RemainAfterExit=yes
TimeoutStartSec=30sec
[Install]
WantedBy=sysinit.target
EOF

  cat << 'EOF' | tee /etc/default/armbian-ramlog >/dev/null
# configuration values for the armbian-ram-logging service
#
# enable the armbian-ram-logging service?
ENABLED=true
#
# size of the tmpfs mount -- please keep in mind to adjust /etc/default/armbian-zram-config too when increasing
SIZE=50M
#
# use rsync instead of cp -r
# requires rsync installed, may provide better performance
# due to copying only new and changed files
USE_RSYNC=true
EOF

  chmod +x /usr/lib/armbian/armbian-zram-config
  systemctl enable armbian-zram-config

  # Swap and Zram tweaks
  # Page allocation error workout
  echo "vm.min_free_kbytes=65536" >> /etc/sysctl.conf
  # Modify swappiness parameter
  echo "vm.swappiness=100" >> /etc/sysctl.conf


  # Ethereum software installation
  # Add APT EthRaspbian repository
  sleep 25
  echo "Adding Ethereum repositories"
  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8A584409D327B0A5
  add-apt-repository -n "deb http://apt.ethraspbian.com bionic main"
  add-apt-repository -n "deb http://apt.ethraspbian.com bionic-security main"
  add-apt-repository "deb http://apt.ethraspbian.com bionic-upgrades main"

  # Install Ethereum packages
  echo Installing Ethereum packages
  apt-get -y install prysm-beacon prysm-validator prysm-slasher lighthouse teku nimbus eth2.0-deposit-cli
  apt-get -y install geth
  # Stop Geth
  systemctl stop geth

  # Modify config params for Medalla
  echo 'ARGS="--goerli --http --metrics --metrics.expensive --pprof --maxpeers 50"' > /etc/ethereum/geth.conf
#  echo 'ARGS="--http-web3provider http://localhost:8545"' > /etc/ethereum/prysm-beacon.conf

   # Install monitoring infrastructure
   apt install -y fontconfig-config fonts-dejavu-core libfontconfig1 libfreetype6
   wget https://dl.grafana.com/oss/release/grafana_7.0.4_arm64.deb
   dpkg -i grafana_7.0.4_arm64.deb
   useradd -m prometheus
   mkdir -p /home/prometheus/node-exporter/
   chown -R  prometheus:prometheus /home/prometheus/
   apt install -y prometheus prometheus-node-exporter
   chown grafana:grafana /root/tmp/grafana.db
   cp -a /root/tmp/grafana.db /var/lib/grafana/grafana.db
   cp -a /root/tmp/{prometheus,prometheus-node-exporter} /etc/default
   cp -a /root/tmp/prometheus.yml /etc/prometheus/
   systemctl enable grafana-server

   #the next line creates an empty file so it won't run the next boot
   touch $FLAG
   reboot
else
   echo "Nothing to do"
fi

exit 0


================================================
FILE: stage2/04-ethereum/files/rc.local.eth2.onyx
================================================
#!/bin/bash
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# This script turns the Ubuntu 64 bit image into an Ethereum on ARM image
#

FLAG="/root/first-run.flag"
if [ ! -f $FLAG ]; then
   # Modify hostname (ethnode-$MAC-HASH-CHUNK)
   echo Changing hostname
   MAC_HASH=`cat /sys/class/net/eth0/address | sha256sum | awk '{print substr($0,0,9)}'`
   echo ethnode-$MAC_HASH > /etc/hostname
   sed -i "s/127.0.0.1.*/127.0.0.1\tethnode-$MAC_HASH/g" /etc/hosts

   # Format USB3 SSD and mount it as /home

   echo Looking for USB drive

   if stat  /dev/sda > /dev/null 2>&1;
     then
     	echo USB drive found
        echo Partitioning and formatting USB Drive...
        fdisk /dev/sda <<EOF
d
n
p
1



w
EOF

	mkfs.ext4 -F /dev/sda1
	echo '/dev/sda1 /home ext4 defaults 0 2' >> /etc/fstab && mount /home
   else
        echo no SDD detected
   fi

   # Create Ethereum account
   echo "Creating ethereum  user for Geth and Parity"
   if ! id -u ethereum >/dev/null 2>&1; then
	adduser --disabled-password --gecos "" ethereum
   fi

   echo "ethereum:ethereum" | chpasswd
   for GRP in sudo netdev audio video dialout plugdev bluetooth; do
	adduser ethereum $GRP
   done

   # Force password change on first login
   chage -d 0 ethereum

# Create some swap memory in the USB device for avoiding memory issues.
  echo "Creating swap memory and activating Zram"
  if stat  /dev/sda > /dev/null 2>&1;
	then
		mkdir -p /home/ethereum/swap
		dd if=/dev/zero of=/home/ethereum/swap/swapfile bs=16k count=256k
		chmod 600 /home/ethereum/swap/swapfile
		mkswap /home/ethereum/swap/swapfile
		swapon /home/ethereum/swap/swapfile
		echo "/home/ethereum/swap/swapfile none swap sw 0 0" >> /etc/fstab
	else
		echo no swap created
   fi

# Enable Zram (based on ARMBIAN script)
  mkdir -p /usr/lib/armbian

  cat << EOF | tee /etc/default/armbian-zram-config >/dev/null
# configuration values for the armbian-zram-config service
#
# enable the armbian-zram-config service
ENABLED=true
ZRAM_PERCENTAGE=25
EOF

  # Enable Zram (ARMBIAN script)
  cat << 'EOF' | tee /usr/lib/armbian/armbian-zram-config >/dev/null
#!/bin/bash
#
# Copyright (c) Authors: http://www.armbian.com/authors
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# Functions:
#
# activate_zram_swap
# activate_ramlog_partition
# activate_compressed_tmp
# Read in basic OS image information
#. /etc/armbian-release
# and script configuration
#. /usr/lib/armbian/armbian-common
# It's possible to override ZRAM_PERCENTAGE, ZRAM_MAX_DEVICES, SWAP_ALGORITHM,
# RAMLOG_ALGORITHM and TMP_ALGORITHM here:
[ -f /etc/default/armbian-zram-config ] && . /etc/default/armbian-zram-config
activate_zram_swap() {
	# Do not interfere with already present config-zram package
	dpkg -l | grep -q 'zram-config' && exit 0
	[[ "$ENABLED" != "true" ]] && exit 0
	# Load zram module with n instances for swap: one per CPU core, $ZRAM_MAX_DEVICES
	# defines the maximum, on modern kernels we overwrite this with 1 and rely on
	# max_comp_streams being set to count of CPU cores or $ZRAM_MAX_DEVICES
	uname -r | grep -q '^3.' && zram_max_devs=${ZRAM_MAX_DEVICES:=4} || zram_max_devs=1
	cpu_cores=$(grep -c '^processor' /proc/cpuinfo | sed 's/^0$/1/')
	[[ ${cpu_cores} -gt ${zram_max_devs} ]] && zram_devices=${zram_max_devs} || zram_devices=${cpu_cores}
	module_args="$(modinfo zram | awk -F" " '/num_devices/ {print $2}' | cut -f1 -d:)"
	[[ -n ${module_args} ]] && modprobe zram ${module_args}=$(( ${zram_devices} + 2 )) || return
	# Expose 50% of real memory as swap space by default
	zram_percent=${ZRAM_PERCENTAGE:=50}
	mem_info=$(LC_ALL=C free -w 2>/dev/null | grep "^Mem" || LC_ALL=C free | grep "^Mem")
	memory_total=$(awk '{printf("%d",$2*1024)}' <<<${mem_info})
	mem_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${zram_percent} / 100 ))
	# Limit memory available to zram to 50% by default
	mem_limit_percent=${MEM_LIMIT_PERCENTAGE:=50}
	mem_limit_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${mem_limit_percent} / 100 ))
	swap_algo=${SWAP_ALGORITHM:=lzo}
	for (( i=1; i<=zram_devices; i++ )); do
		[[ -f /sys/block/zram${i}/comp_algorithm ]] && echo ${swap_algo} >/sys/block/zram${i}/comp_algorithm 2>/dev/null
		if [ "X${ZRAM_BACKING_DEV}" != "X" ]; then
			echo ${ZRAM_BACKING_DEV} >/sys/block/zram${i}/backing_dev
		fi
		echo -n ${ZRAM_MAX_DEVICES:=4} > /sys/block/zram${i}/max_comp_streams
		echo -n ${mem_per_zram_device} > /sys/block/zram${i}/disksize
		echo -n ${mem_limit_per_zram_device} > /sys/block/zram${i}/mem_limit
		mkswap /dev/zram${i}
		swapon -p 5 /dev/zram${i}
	done
	# Swapping to HDDs is stupid so switch to settings made for flash memory and zram/zswap
	echo 0 > /proc/sys/vm/page-cluster
	echo -e "\n### Activated ${zram_devices} ${swap_algo} zram swap devices with $(( ${mem_per_zram_device} / 1048576 )) MB each\n" >>${Log}
} # activate_zram_swap
activate_ramlog_partition() {
	# /dev/zram0 will be used as a compressed /var/log partition in RAM if
	# ENABLED=true in /etc/default/armbian-ramlog is set
	ENABLED=$(awk -F"=" '/^ENABLED/ {print $2}' /etc/default/armbian-ramlog)
	[[ "$ENABLED" != "true" ]] && return
	
	# read size also from /etc/default/armbian-ramlog
	ramlogsize=$(awk -F"=" '/^SIZE/ {print $2}' /etc/default/armbian-ramlog)
	disksize=$(sed -e 's/M$/*1048576/' -e 's/K$/*1024/' <<<${ramlogsize:=50M} | bc)
	# choose RAMLOG_ALGORITHM if defined in /etc/default/armbian-zram-config
	# otherwise try to choose most efficient compression scheme available.
	# See https://patchwork.kernel.org/patch/9918897/
	if [ "X${RAMLOG_ALGORITHM}" = "X" ]; then
		for algo in lz4 lz4hc quicklz zlib brotli zstd ; do
			echo ${algo} >/sys/block/zram0/comp_algorithm 2>/dev/null
		done
	else
		echo ${RAMLOG_ALGORITHM} >/sys/block/zram0/comp_algorithm 2>/dev/null
	fi
	echo -n ${disksize} > /sys/block/zram0/disksize
	# if it fails, select $swap_algo. Workaround for some older kernels
	if [[ $? == 1 ]]; then
		echo ${swap_algo} > /sys/block/zram0/comp_algorithm 2>/dev/null
		echo -n ${disksize} > /sys/block/zram0/disksize
	fi
	mkfs.ext4 -O ^has_journal -s 1024 -L log2ram /dev/zram0
	algo=$(sed 's/.*\[\([^]]*\)\].*/\1/g' </sys/block/zram0/comp_algorithm)
	echo -e "### Activated Armbian ramlog partition with ${algo} compression" >>${Log}
} # activate_ramlog_partition
activate_compressed_tmp() {
	# create /tmp not as tmpfs but zram compressed if no fstab entry exists
	grep -q '^tmpfs /tmp' /etc/mtab && return
	tmp_device=$(( ${zram_devices} + 1 ))
	if [[ -f /sys/block/zram${tmp_device}/comp_algorithm ]]; then
		if [ "X${TMP_ALGORITHM}" = "X" ]; then
			echo ${swap_algo} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null
		else
			echo ${TMP_ALGORITHM} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null
		fi
	fi
	echo -n $(( ${memory_total} / 2 )) > /sys/block/zram${tmp_device}/disksize
	mkfs.ext4 -O ^has_journal -s 1024 -L tmp /dev/zram${tmp_device}
	mount -o nosuid,discard /dev/zram${tmp_device} /tmp
	chmod 777 /tmp
	algo=$(sed 's/.*\[\([^]]*\)\].*/\1/g' </sys/block/zram${tmp_device}/comp_algorithm)
} # activate_compressed_tmp
case $1 in
	*start*)
		activate_zram_swap
		activate_ramlog_partition
		activate_compressed_tmp
		;;
esac
EOF

  cat << 'EOF' | tee /etc/systemd/system/armbian-zram-config.service >/dev/null
# Armbian ZRAM configuration service
# Create 1 + number of cores compressed block devices
# This service may block the boot process for up to 30 sec
[Unit]
Description=Armbian ZRAM config
DefaultDependencies=no
After=local-fs.target
Before=armbian-ramlog.target
Conflicts=shutdown.target
[Service]
Type=oneshot
ExecStart=/usr/lib/armbian/armbian-zram-config start
ExecStop=/usr/lib/armbian/armbian-zram-config stop
RemainAfterExit=yes
TimeoutStartSec=30sec
[Install]
WantedBy=sysinit.target
EOF

  cat << 'EOF' | tee /etc/default/armbian-ramlog >/dev/null
# configuration values for the armbian-ram-logging service
#
# enable the armbian-ram-logging service?
ENABLED=true
#
# size of the tmpfs mount -- please keep in mind to adjust /etc/default/armbian-zram-config too when increasing
SIZE=50M
#
# use rsync instead of cp -r
# requires rsync installed, may provide better performance
# due to copying only new and changed files
USE_RSYNC=true
EOF

  chmod +x /usr/lib/armbian/armbian-zram-config
  systemctl enable armbian-zram-config

  # Swap and Zram tweaks
  # Page allocation error workout
  echo "vm.min_free_kbytes=65536" >> /etc/sysctl.conf
  # Modify swappiness parameter
  echo "vm.swappiness=100" >> /etc/sysctl.conf


  # Ethereum software installation
  # Add APT EthRaspbian repository
  sleep 25
  echo "Adding Ethereum repositories"
  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8A584409D327B0A5
  add-apt-repository -n "deb http://apt.ethraspbian.com bionic main"
  add-apt-repository -n "deb http://apt.ethraspbian.com bionic-security main"
  add-apt-repository "deb http://apt.ethraspbian.com bionic-upgrades main"

  # Install Ethereum packages
  echo Installing Ethereum packages
  apt-get -y install prysm-beacon prysm-validator prysm-slasher
  apt-get -y install geth
  # Stop Geth
  systemctl stop geth
  # Enable the beacon chain for next reboot
  systemctl enable prysm-beacon

  # Modify config params for Onyx
  echo 'ARGS="--goerli --http --metrics --metrics.expensive --pprof --maxpeers 50"' > /etc/ethereum/geth.conf
  echo 'ARGS="--http-web3provider http://localhost:8545"' > /etc/ethereum/prysm-beacon.conf

  # Create an alias for package updates
  cat <<EOF >> /etc/bash.bashrc
alias update-ethereum='
sudo apt-get update
sudo apt-get install geth parity nethermind hyperledger-besu swarm ipfs raiden statusd vipnode prysm-beacon prysm-validator prysm-slasher lighthouse'
EOF
   # Install monitoring infrastructure
   apt install -y fontconfig-config fonts-dejavu-core libfontconfig1 libfreetype6
   wget https://dl.grafana.com/oss/release/grafana_7.0.4_arm64.deb
   dpkg -i grafana_7.0.4_arm64.deb
   useradd -m prometheus
   mkdir -p /home/prometheus/node-exporter/
   chown -R  prometheus:prometheus /home/prometheus/
   apt install -y prometheus prometheus-node-exporter
   chown grafana:grafana /root/tmp/grafana.db
   cp -a /root/tmp/grafana.db /var/lib/grafana/grafana.db
   cp -a /root/tmp/{prometheus,prometheus-node-exporter} /etc/default
   cp -a /root/tmp/prometheus.yml /etc/prometheus/
   systemctl enable grafana-server

   #the next line creates an empty file so it won't run the next boot
   touch $FLAG
   reboot
else
   echo "Nothing to do"
fi

exit 0


================================================
FILE: stage2/04-ethereum/files/zram-default/armbian-zram-config
================================================
# configuration values for the armbian-zram-config service
#
# enable the armbian-zram-config service
ENABLED=true
ZRAM_PERCENTAGE=25


================================================
FILE: stage2/04-ethereum/files/zram-lib/armbian-zram-config
================================================
#!/bin/bash
#
# Copyright (c) Authors: http://www.armbian.com/authors
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# Functions:
#
# activate_zram_swap
# activate_ramlog_partition
# activate_compressed_tmp
# Read in basic OS image information
#. /etc/armbian-release
# and script configuration
#. /usr/lib/armbian/armbian-common
# It's possible to override ZRAM_PERCENTAGE, ZRAM_MAX_DEVICES, SWAP_ALGORITHM,
# RAMLOG_ALGORITHM and TMP_ALGORITHM here:
[ -f /etc/default/armbian-zram-config ] && . /etc/default/armbian-zram-config
activate_zram_swap() {
	# Do not interfere with already present config-zram package
	dpkg -l | grep -q 'zram-config' && exit 0
	[[ "$ENABLED" != "true" ]] && exit 0
	# Load zram module with n instances for swap: one per CPU core, $ZRAM_MAX_DEVICES
	# defines the maximum, on modern kernels we overwrite this with 1 and rely on
	# max_comp_streams being set to count of CPU cores or $ZRAM_MAX_DEVICES
	uname -r | grep -q '^3.' && zram_max_devs=${ZRAM_MAX_DEVICES:=4} || zram_max_devs=1
	cpu_cores=$(grep -c '^processor' /proc/cpuinfo | sed 's/^0$/1/')
	[[ ${cpu_cores} -gt ${zram_max_devs} ]] && zram_devices=${zram_max_devs} || zram_devices=${cpu_cores}
	module_args="$(modinfo zram | awk -F" " '/num_devices/ {print $2}' | cut -f1 -d:)"
	[[ -n ${module_args} ]] && modprobe zram ${module_args}=$(( ${zram_devices} + 2 )) || return
	# Expose 50% of real memory as swap space by default
	zram_percent=${ZRAM_PERCENTAGE:=50}
	mem_info=$(LC_ALL=C free -w 2>/dev/null | grep "^Mem" || LC_ALL=C free | grep "^Mem")
	memory_total=$(awk '{printf("%d",$2*1024)}' <<<${mem_info})
	mem_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${zram_percent} / 100 ))
	# Limit memory available to zram to 50% by default
	mem_limit_percent=${MEM_LIMIT_PERCENTAGE:=50}
	mem_limit_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${mem_limit_percent} / 100 ))
	swap_algo=${SWAP_ALGORITHM:=lzo}
	for (( i=1; i<=zram_devices; i++ )); do
		[[ -f /sys/block/zram${i}/comp_algorithm ]] && echo ${swap_algo} >/sys/block/zram${i}/comp_algorithm 2>/dev/null
		if [ "X${ZRAM_BACKING_DEV}" != "X" ]; then
			echo ${ZRAM_BACKING_DEV} >/sys/block/zram${i}/backing_dev
		fi
		echo -n ${ZRAM_MAX_DEVICES:=4} > /sys/block/zram${i}/max_comp_streams
		echo -n ${mem_per_zram_device} > /sys/block/zram${i}/disksize
		echo -n ${mem_limit_per_zram_device} > /sys/block/zram${i}/mem_limit
		mkswap /dev/zram${i}
		swapon -p 5 /dev/zram${i}
	done
	# Swapping to HDDs is stupid so switch to settings made for flash memory and zram/zswap
	echo 0 > /proc/sys/vm/page-cluster
	echo -e "\n### Activated ${zram_devices} ${swap_algo} zram swap devices with $(( ${mem_per_zram_device} / 1048576 )) MB each\n" >>${Log}
} # activate_zram_swap
activate_ramlog_partition() {
	# /dev/zram0 will be used as a compressed /var/log partition in RAM if
	# ENABLED=true in /etc/default/armbian-ramlog is set
	ENABLED=$(awk -F"=" '/^ENABLED/ {print $2}' /etc/default/armbian-ramlog)
	[[ "$ENABLED" != "true" ]] && return
	
	# read size also from /etc/default/armbian-ramlog
	ramlogsize=$(awk -F"=" '/^SIZE/ {print $2}' /etc/default/armbian-ramlog)
	disksize=$(sed -e 's/M$/*1048576/' -e 's/K$/*1024/' <<<${ramlogsize:=50M} | bc)
	# choose RAMLOG_ALGORITHM if defined in /etc/default/armbian-zram-config
	# otherwise try to choose most efficient compression scheme available.
	# See https://patchwork.kernel.org/patch/9918897/
	if [ "X${RAMLOG_ALGORITHM}" = "X" ]; then
		for algo in lz4 lz4hc quicklz zlib brotli zstd ; do
			echo ${algo} >/sys/block/zram0/comp_algorithm 2>/dev/null
		done
	else
		echo ${RAMLOG_ALGORITHM} >/sys/block/zram0/comp_algorithm 2>/dev/null
	fi
	echo -n ${disksize} > /sys/block/zram0/disksize
	# if it fails, select $swap_algo. Workaround for some older kernels
	if [[ $? == 1 ]]; then
		echo ${swap_algo} > /sys/block/zram0/comp_algorithm 2>/dev/null
		echo -n ${disksize} > /sys/block/zram0/disksize
	fi
	mkfs.ext4 -O ^has_journal -s 1024 -L log2ram /dev/zram0
	algo=$(sed 's/.*\[\([^]]*\)\].*/\1/g' </sys/block/zram0/comp_algorithm)
	echo -e "### Activated Armbian ramlog partition with ${algo} compression" >>${Log}
} # activate_ramlog_partition
activate_compressed_tmp() {
	# create /tmp not as tmpfs but zram compressed if no fstab entry exists
	grep -q '^tmpfs /tmp' /etc/mtab && return
	tmp_device=$(( ${zram_devices} + 1 ))
	if [[ -f /sys/block/zram${tmp_device}/comp_algorithm ]]; then
		if [ "X${TMP_ALGORITHM}" = "X" ]; then
			echo ${swap_algo} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null
		else
			echo ${TMP_ALGORITHM} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null
		fi
	fi
	echo -n $(( ${memory_total} / 2 )) > /sys/block/zram${tmp_device}/disksize
	mkfs.ext4 -O ^has_journal -s 1024 -L tmp /dev/zram${tmp_device}
	mount -o nosuid,discard /dev/zram${tmp_device} /tmp
	chmod 777 /tmp
	algo=$(sed 's/.*\[\([^]]*\)\].*/\1/g' </sys/block/zram${tmp_device}/comp_algorithm)
} # activate_compressed_tmp
case $1 in
	*start*)
		activate_zram_swap
		activate_ramlog_partition
		activate_compressed_tmp
		;;
esac


================================================
FILE: stage2/EXPORT_IMAGE
================================================
IMG_SUFFIX="-lite"
if [ "${USE_QEMU}" = "1" ]; then
	export IMG_SUFFIX="${IMG_SUFFIX}-qemu"
fi


================================================
FILE: stage2/EXPORT_NOOBS
================================================
NOOBS_NAME="Raspbian Lite"
NOOBS_DESCRIPTION="A port of Debian with no desktop environment"


================================================
FILE: stage2/prerun.sh
================================================
#!/bin/bash -e

if [ ! -d "${ROOTFS_DIR}" ]; then
	copy_previous
fi


================================================
FILE: stage3/00-install-packages/00-debconf
================================================
# Adobe Flash Player. Copyright 1996-2015. Adobe Systems Incorporated. All Rights Reserved.
rpi-chromium-mods	rpi-chromium-mods/adobe	note


================================================
FILE: stage3/00-install-packages/00-packages
================================================
gstreamer1.0-x gstreamer1.0-omx gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-alsa gstreamer1.0-libav
qpdfview gtk2-engines alsa-utils
desktop-base
git
omxplayer
raspberrypi-artwork
policykit-1
gvfs
rfkill
chromium-browser rpi-chromium-mods
gldriver-test
fonts-droid-fallback
fonts-liberation2
obconf
arandr


================================================
FILE: stage3/00-install-packages/00-packages-nr
================================================
xserver-xorg-video-fbdev xserver-xorg xinit xserver-xorg-video-fbturbo
epiphany-browser
lxde lxtask menu-xdg
zenity xdg-utils
gvfs-backends gvfs-fuse
lightdm gnome-themes-standard-data gnome-icon-theme


================================================
FILE: stage3/00-install-packages/01-run.sh
================================================
#!/bin/bash -e

on_chroot << EOF
update-alternatives --install /usr/bin/x-www-browser \
  x-www-browser /usr/bin/chromium-browser 86
update-alternatives --install /usr/bin/gnome-www-browser \
  gnome-www-browser /usr/bin/chromium-browser 86
EOF


================================================
FILE: stage3/01-tweaks/00-run.sh
================================================
#!/bin/bash -e

rm -f "${ROOTFS_DIR}/etc/systemd/system/dhcpcd.service.d/wait.conf"


================================================
FILE: stage3/prerun.sh
================================================
#!/bin/bash -e

if [ ! -d "${ROOTFS_DIR}" ]; then
	copy_previous
fi


================================================
FILE: stage4/00-install-packages/00-debconf
================================================
# Enable realtime process priority?
jackd2  jackd/tweak_rt_limits   boolean true


================================================
FILE: stage4/00-install-packages/00-packages
================================================
python python3-pygame python-pygame python-tk
python3 python3-tk python3-th
Download .txt
gitextract_zctbo7w5/

├── .dockerignore
├── .gitignore
├── Dockerfile
├── LICENSE
├── README.md
├── build-docker.sh
├── build.sh
├── depends
├── docker-compose.yml
├── export-image/
│   ├── 00-allow-rerun/
│   │   └── 00-run.sh
│   ├── 01-set-sources/
│   │   └── 01-run.sh
│   ├── 02-network/
│   │   ├── 01-run.sh
│   │   └── files/
│   │       └── resolv.conf
│   ├── 03-set-partuuid/
│   │   └── 00-run.sh
│   ├── 04-finalise/
│   │   └── 01-run.sh
│   └── prerun.sh
├── export-noobs/
│   ├── 00-release/
│   │   ├── 00-run.sh
│   │   └── files/
│   │       ├── os.json
│   │       ├── partition_setup.sh
│   │       ├── partitions.json
│   │       └── release_notes.txt
│   └── prerun.sh
├── scripts/
│   ├── common
│   ├── dependencies_check
│   └── remove-comments.sed
├── stage0/
│   ├── 00-configure-apt/
│   │   ├── 00-run.sh
│   │   └── files/
│   │       ├── 51cache
│   │       ├── raspberrypi.gpg.key
│   │       ├── raspi.list
│   │       └── sources.list
│   ├── 01-locale/
│   │   ├── 00-debconf
│   │   └── 00-packages
│   ├── 02-firmware/
│   │   └── 01-packages
│   ├── files/
│   │   └── raspberrypi.gpg
│   └── prerun.sh
├── stage1/
│   ├── 00-boot-files/
│   │   ├── 00-run.sh
│   │   └── files/
│   │       ├── cmdline.txt
│   │       └── config.txt
│   ├── 01-sys-tweaks/
│   │   ├── 00-patches/
│   │   │   ├── 01-bashrc.diff
│   │   │   └── series
│   │   ├── 00-run.sh
│   │   └── files/
│   │       ├── fstab
│   │       └── noclear.conf
│   ├── 02-net-tweaks/
│   │   ├── 00-packages
│   │   ├── 00-patches/
│   │   │   ├── 01-hosts.diff
│   │   │   └── series
│   │   ├── 00-run.sh
│   │   └── files/
│   │       ├── hostname
│   │       └── interfaces
│   ├── 03-install-packages/
│   │   └── 00-packages
│   └── prerun.sh
├── stage2/
│   ├── 00-copies-and-fills/
│   │   ├── 01-packages
│   │   └── 02-run.sh
│   ├── 01-sys-tweaks/
│   │   ├── 00-debconf
│   │   ├── 00-packages
│   │   ├── 00-packages-nr
│   │   ├── 00-patches/
│   │   │   ├── 01-useradd.diff
│   │   │   ├── 02-swap.diff
│   │   │   ├── 04-inputrc.diff
│   │   │   ├── 05-path.diff
│   │   │   ├── 07-resize-init.diff
│   │   │   └── series
│   │   ├── 01-run.sh
│   │   └── files/
│   │       ├── 50raspi
│   │       ├── 90-qemu.rules
│   │       ├── console-setup
│   │       ├── rc.local
│   │       ├── resize2fs_once
│   │       └── ttyoutput.conf
│   ├── 02-net-tweaks/
│   │   ├── 00-packages
│   │   ├── 01-run.sh
│   │   └── files/
│   │       ├── wait.conf
│   │       └── wpa_supplicant.conf
│   ├── 03-accept-mathematica-eula/
│   │   └── 00-debconf
│   ├── 03-set-timezone/
│   │   └── 02-run.sh
│   ├── 04-ethereum/
│   │   ├── 00-packages
│   │   ├── 01-run.sh
│   │   └── files/
│   │       ├── armbian-ramlog
│   │       ├── armbian-zram-config.service
│   │       ├── dphys-swapfile
│   │       ├── ethonarm-rpi4-ubuntu64bit-install.sh
│   │       ├── ethonarm-rpi4-ubuntu64bit-setup.sh
│   │       ├── ethonarm.list
│   │       ├── grafana/
│   │       │   ├── prometheus
│   │       │   ├── prometheus-node-exporter
│   │       │   └── prometheus.yml
│   │       ├── grafana-eth2-onyx/
│   │       │   ├── prometheus
│   │       │   ├── prometheus-node-exporter
│   │       │   └── prometheus.yml
│   │       ├── init_resize.sh
│   │       ├── rc.local.eth1
│   │       ├── rc.local.eth2
│   │       ├── rc.local.eth2.medalla
│   │       ├── rc.local.eth2.onyx
│   │       ├── zram-default/
│   │       │   └── armbian-zram-config
│   │       └── zram-lib/
│   │           └── armbian-zram-config
│   ├── EXPORT_IMAGE
│   ├── EXPORT_NOOBS
│   └── prerun.sh
├── stage3/
│   ├── 00-install-packages/
│   │   ├── 00-debconf
│   │   ├── 00-packages
│   │   ├── 00-packages-nr
│   │   └── 01-run.sh
│   ├── 01-tweaks/
│   │   └── 00-run.sh
│   └── prerun.sh
├── stage4/
│   ├── 00-install-packages/
│   │   ├── 00-debconf
│   │   ├── 00-packages
│   │   ├── 00-packages-nr
│   │   ├── 01-packages
│   │   └── 02-packages
│   ├── 01-console-autologin/
│   │   └── 00-run.sh
│   ├── 02-extras/
│   │   └── 00-run.sh
│   ├── 03-magpi/
│   │   ├── 00-run.sh
│   │   └── files/
│   │       └── .gitignore
│   ├── 04-enable-xcompmgr/
│   │   └── 00-run.sh
│   ├── EXPORT_IMAGE
│   ├── EXPORT_NOOBS
│   └── prerun.sh
└── stage5/
    ├── 00-install-extras/
    │   └── 00-packages
    ├── 00-install-libreoffice/
    │   └── 00-packages
    ├── EXPORT_IMAGE
    ├── EXPORT_NOOBS
    └── prerun.sh
Condensed preview — 123 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (204K chars).
[
  {
    "path": ".dockerignore",
    "chars": 52,
    "preview": "output/\nwork/\ndeploy/\napt-cacher-ng/\n.git/objects/*\n"
  },
  {
    "path": ".gitignore",
    "chars": 75,
    "preview": "deploy/*\nwork/*\nconfig\npostrun.sh\nSKIP\nSKIP_IMAGES\n.pc\n*-pc\napt-cacher-ng/\n"
  },
  {
    "path": "Dockerfile",
    "chars": 380,
    "preview": "FROM debian:buster\n\nENV DEBIAN_FRONTEND noninteractive\n\nRUN apt-get -y update && \\\n    apt-get -y install \\\n        git "
  },
  {
    "path": "LICENSE",
    "chars": 1498,
    "preview": "Copyright (c) 2015 Raspberry Pi (Trading) Ltd.\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms,"
  },
  {
    "path": "README.md",
    "chars": 10272,
    "preview": "DISCLAIMER: This is a legacy repository. Please move to our new one:\n\nhttps://github.com/diglos/ethereumonarm\n\nEthereum "
  },
  {
    "path": "build-docker.sh",
    "chars": 2165,
    "preview": "#!/bin/bash -e\n\nBUILD_OPTS=\"$*\"\n\nDOCKER=\"docker\"\nset +e\nif ! $DOCKER ps >/dev/null 2>&1; then\n\tDOCKER=\"sudo docker\"\nfi\ni"
  },
  {
    "path": "build.sh",
    "chars": 5856,
    "preview": "#!/bin/bash -e\n# shellcheck disable=SC2119\nrun_sub_stage()\n{\n\tlog \"Begin ${SUB_STAGE_DIR}\"\n\tpushd \"${SUB_STAGE_DIR}\" > /"
  },
  {
    "path": "depends",
    "chars": 186,
    "preview": "quilt\nparted\nrealpath:coreutils\nqemu-arm-static:qemu-user-static\ndebootstrap\nzerofree\nzip\nmkdosfs:dosfstools\ncapsh:libca"
  },
  {
    "path": "docker-compose.yml",
    "chars": 200,
    "preview": "version: '2'\n\nservices:\n  apt-cacher-ng:\n    restart: unless-stopped\n    image: sameersbn/apt-cacher-ng:latest\n    ports"
  },
  {
    "path": "export-image/00-allow-rerun/00-run.sh",
    "chars": 266,
    "preview": "#!/bin/bash -e\n\nif [ ! -x \"${ROOTFS_DIR}/usr/bin/qemu-arm-static\" ]; then\n\tcp /usr/bin/qemu-arm-static \"${ROOTFS_DIR}/us"
  },
  {
    "path": "export-image/01-set-sources/01-run.sh",
    "chars": 90,
    "preview": "#!/bin/bash -e\n\non_chroot << EOF\napt-get update\napt-get -y dist-upgrade\napt-get clean\nEOF\n"
  },
  {
    "path": "export-image/02-network/01-run.sh",
    "chars": 70,
    "preview": "#!/bin/bash -e\n\ninstall -m 644 files/resolv.conf \"${ROOTFS_DIR}/etc/\"\n"
  },
  {
    "path": "export-image/02-network/files/resolv.conf",
    "chars": 19,
    "preview": "nameserver 8.8.8.8\n"
  },
  {
    "path": "export-image/03-set-partuuid/00-run.sh",
    "chars": 452,
    "preview": "#!/bin/bash -e\n\nIMG_FILE=\"${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img\"\n\nIMGID=\"$(dd if=\"${IMG_FILE}\" skip=440 bs="
  },
  {
    "path": "export-image/04-finalise/01-run.sh",
    "chars": 2813,
    "preview": "#!/bin/bash -e\n\nIMG_FILE=\"${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img\"\nINFO_FILE=\"${STAGE_WORK_DIR}/${IMG_FILENAM"
  },
  {
    "path": "export-image/prerun.sh",
    "chars": 1951,
    "preview": "#!/bin/bash -e\n\nIMG_FILE=\"${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img\"\n\nunmount_image \"${IMG_FILE}\"\n\nrm -f \"${IMG"
  },
  {
    "path": "export-noobs/00-release/00-run.sh",
    "chars": 1648,
    "preview": "#!/bin/bash -e\n\nNOOBS_DIR=\"${STAGE_WORK_DIR}/${IMG_DATE}-${IMG_NAME}${IMG_SUFFIX}\"\n\ninstall -v -m 744\tfiles/partition_se"
  },
  {
    "path": "export-noobs/00-release/files/os.json",
    "chars": 517,
    "preview": "{\n    \"description\": \"NOOBS_DESCRIPTION\",\n    \"feature_level\": 35120124,\n    \"kernel\": \"4.19\",\n    \"name\": \"NOOBS_NAME\","
  },
  {
    "path": "export-noobs/00-release/files/partition_setup.sh",
    "chars": 1055,
    "preview": "#!/bin/sh\n#supports_backup in PINN\n\nset -ex\n\n# shellcheck disable=SC2154\nif [ -z \"$part1\" ] || [ -z \"$part2\" ]; then\n  p"
  },
  {
    "path": "export-noobs/00-release/files/partitions.json",
    "chars": 639,
    "preview": "{\n    \"partitions\": [\n        {\n            \"filesystem_type\": \"FAT\",\n            \"label\": \"boot\",\n            \"mkfs_opt"
  },
  {
    "path": "export-noobs/00-release/files/release_notes.txt",
    "chars": 19770,
    "preview": "UNRELEASED:\n  *\n2019-06-20:\n  * Based on Debian Buster\n  * Support for Raspberry Pi 4 hardware\n  * FKMS OpenGL desktop g"
  },
  {
    "path": "export-noobs/prerun.sh",
    "chars": 1597,
    "preview": "#!/bin/bash -e\n\nIMG_FILE=\"${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img\"\nNOOBS_DIR=\"${STAGE_WORK_DIR}/${IMG_DATE}-$"
  },
  {
    "path": "scripts/common",
    "chars": 2460,
    "preview": "log (){\n\tdate +\"[%T] $*\" | tee -a \"${LOG_FILE}\"\n}\nexport -f log\n\nbootstrap(){\n\tlocal BOOTSTRAP_CMD=debootstrap\n\tlocal BO"
  },
  {
    "path": "scripts/dependencies_check",
    "chars": 945,
    "preview": "# dependencies_check\n# $@\tDependency files to check\n#\n# Each dependency is in the form of a tool to test for, optionally"
  },
  {
    "path": "scripts/remove-comments.sed",
    "chars": 284,
    "preview": "# Deletes comments and collapses whitespace in ##-packages files\n\n# Append (N)ext line to buffer\n# if (!)not ($)buffer i"
  },
  {
    "path": "stage0/00-configure-apt/00-run.sh",
    "chars": 503,
    "preview": "#!/bin/bash -e\n\ninstall -m 644 files/sources.list \"${ROOTFS_DIR}/etc/apt/\"\ninstall -m 644 files/raspi.list \"${ROOTFS_DIR"
  },
  {
    "path": "stage0/00-configure-apt/files/51cache",
    "chars": 38,
    "preview": "Acquire::http { Proxy \"APT_PROXY\"; };\n"
  },
  {
    "path": "stage0/00-configure-apt/files/raspberrypi.gpg.key",
    "chars": 1719,
    "preview": "-----BEGIN PGP PUBLIC KEY BLOCK-----\nVersion: GnuPG v1.4.12 (GNU/Linux)\n\nmQENBE/d7o8BCACrwqQacGJfn3tnMzGui6mv2lLxYbsOuy/"
  },
  {
    "path": "stage0/00-configure-apt/files/raspi.list",
    "chars": 187,
    "preview": "deb http://archive.raspberrypi.org/debian/ buster main\n# Uncomment line below then 'apt-get update' to enable 'apt-get s"
  },
  {
    "path": "stage0/00-configure-apt/files/sources.list",
    "chars": 235,
    "preview": "deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi\n# Uncomment line below then 'apt-get upda"
  },
  {
    "path": "stage0/01-locale/00-debconf",
    "chars": 8525,
    "preview": "# Locales to be generated:\n# Choices: All locales, aa_DJ ISO-8859-1, aa_DJ.UTF-8 UTF-8, aa_ER UTF-8, aa_ER@saaho UTF-8, "
  },
  {
    "path": "stage0/01-locale/00-packages",
    "chars": 8,
    "preview": "locales\n"
  },
  {
    "path": "stage0/02-firmware/01-packages",
    "chars": 42,
    "preview": "raspberrypi-bootloader\nraspberrypi-kernel\n"
  },
  {
    "path": "stage0/prerun.sh",
    "chars": 129,
    "preview": "#!/bin/bash -e\n\nif [ ! -d \"${ROOTFS_DIR}\" ]; then\n\tbootstrap buster \"${ROOTFS_DIR}\" http://raspbian.raspberrypi.org/rasp"
  },
  {
    "path": "stage1/00-boot-files/00-run.sh",
    "chars": 125,
    "preview": "#!/bin/bash -e\n\ninstall -m 644 files/cmdline.txt \"${ROOTFS_DIR}/boot/\"\ninstall -m 644 files/config.txt \"${ROOTFS_DIR}/bo"
  },
  {
    "path": "stage1/00-boot-files/files/cmdline.txt",
    "chars": 129,
    "preview": "dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 elevator=deadline fsck.repair=yes "
  },
  {
    "path": "stage1/00-boot-files/files/config.txt",
    "chars": 1735,
    "preview": "# For more options and information see\n# http://rpf.io/configtxt\n# Some settings may impact device functionality. See li"
  },
  {
    "path": "stage1/01-sys-tweaks/00-patches/01-bashrc.diff",
    "chars": 1152,
    "preview": "--- a/rootfs/etc/skel/.bashrc\n+++ b/rootfs/etc/skel/.bashrc\n@@ -43,7 +43,7 @@\n # uncomment for a colored prompt, if the "
  },
  {
    "path": "stage1/01-sys-tweaks/00-patches/series",
    "chars": 15,
    "preview": "01-bashrc.diff\n"
  },
  {
    "path": "stage1/01-sys-tweaks/00-run.sh",
    "chars": 464,
    "preview": "#!/bin/bash -e\n\ninstall -d \"${ROOTFS_DIR}/etc/systemd/system/getty@tty1.service.d\"\ninstall -m 644 files/noclear.conf \"${"
  },
  {
    "path": "stage1/01-sys-tweaks/files/fstab",
    "chars": 190,
    "preview": "proc            /proc           proc    defaults          0       0\nBOOTDEV  /boot           vfat    defaults          0"
  },
  {
    "path": "stage1/01-sys-tweaks/files/noclear.conf",
    "chars": 30,
    "preview": "[Service]\nTTYVTDisallocate=no\n"
  },
  {
    "path": "stage1/02-net-tweaks/00-packages",
    "chars": 8,
    "preview": "netbase\n"
  },
  {
    "path": "stage1/02-net-tweaks/00-patches/01-hosts.diff",
    "chars": 270,
    "preview": "Index: jessie-stage1/rootfs/etc/hosts\n===================================================================\n--- jessie-sta"
  },
  {
    "path": "stage1/02-net-tweaks/00-patches/series",
    "chars": 14,
    "preview": "01-hosts.diff\n"
  },
  {
    "path": "stage1/02-net-tweaks/00-run.sh",
    "chars": 145,
    "preview": "#!/bin/bash -e\n\ninstall -m 644 files/hostname \"${ROOTFS_DIR}/etc/hostname\"\n\nln -sf /dev/null \"${ROOTFS_DIR}/etc/systemd/"
  },
  {
    "path": "stage1/02-net-tweaks/files/hostname",
    "chars": 12,
    "preview": "raspberrypi\n"
  },
  {
    "path": "stage1/02-net-tweaks/files/interfaces",
    "chars": 53,
    "preview": "auto lo\n\niface lo inet loopback\niface eth0 inet dhcp\n"
  },
  {
    "path": "stage1/03-install-packages/00-packages",
    "chars": 48,
    "preview": "libraspberrypi-bin libraspberrypi0 raspi-config\n"
  },
  {
    "path": "stage1/prerun.sh",
    "chars": 68,
    "preview": "#!/bin/bash -e\n\nif [ ! -d \"${ROOTFS_DIR}\" ]; then\n\tcopy_previous\nfi\n"
  },
  {
    "path": "stage2/00-copies-and-fills/01-packages",
    "chars": 23,
    "preview": "raspi-copies-and-fills\n"
  },
  {
    "path": "stage2/00-copies-and-fills/02-run.sh",
    "chars": 96,
    "preview": "#!/bin/bash -e\n\nmv \"${ROOTFS_DIR}/etc/ld.so.preload\" \"${ROOTFS_DIR}/etc/ld.so.preload.disabled\"\n"
  },
  {
    "path": "stage2/01-sys-tweaks/00-debconf",
    "chars": 8720,
    "preview": "# Encoding to use on the console:\n# Choices: ARMSCII-8, CP1251, CP1255, CP1256, GEORGIAN-ACADEMY, GEORGIAN-PS, IBM1133, "
  },
  {
    "path": "stage2/01-sys-tweaks/00-packages",
    "chars": 565,
    "preview": "ssh less fbset sudo psmisc strace ed ncdu crda\nconsole-setup keyboard-configuration debconf-utils parted unzip\nbuild-ess"
  },
  {
    "path": "stage2/01-sys-tweaks/00-packages-nr",
    "chars": 11,
    "preview": "cifs-utils\n"
  },
  {
    "path": "stage2/01-sys-tweaks/00-patches/01-useradd.diff",
    "chars": 822,
    "preview": "Index: jessie-stage2/rootfs/etc/default/useradd\n===================================================================\n--- "
  },
  {
    "path": "stage2/01-sys-tweaks/00-patches/02-swap.diff",
    "chars": 577,
    "preview": "Index: jessie-stage2/rootfs/etc/dphys-swapfile\n===================================================================\n--- j"
  },
  {
    "path": "stage2/01-sys-tweaks/00-patches/04-inputrc.diff",
    "chars": 366,
    "preview": "Index: jessie-stage2/rootfs/etc/inputrc\n===================================================================\n--- jessie-s"
  },
  {
    "path": "stage2/01-sys-tweaks/00-patches/05-path.diff",
    "chars": 1093,
    "preview": "Index: jessie-stage2/rootfs/etc/login.defs\n===================================================================\n--- jessi"
  },
  {
    "path": "stage2/01-sys-tweaks/00-patches/07-resize-init.diff",
    "chars": 380,
    "preview": "--- a/rootfs/boot/cmdline.txt\n+++ b/rootfs/boot/cmdline.txt\n@@ -1 +1 @@\n-dwc_otg.lpm_enable=0 console=serial0,115200 con"
  },
  {
    "path": "stage2/01-sys-tweaks/00-patches/series",
    "chars": 78,
    "preview": "01-useradd.diff\n02-swap.diff\n04-inputrc.diff\n05-path.diff\n07-resize-init.diff\n"
  },
  {
    "path": "stage2/01-sys-tweaks/01-run.sh",
    "chars": 1301,
    "preview": "#!/bin/bash -e\n\ninstall -m 755 files/resize2fs_once\t\"${ROOTFS_DIR}/etc/init.d/\"\n\ninstall -d\t\t\t\t\"${ROOTFS_DIR}/etc/system"
  },
  {
    "path": "stage2/01-sys-tweaks/files/50raspi",
    "chars": 161,
    "preview": "# never use pdiffs. Current implementation is very slow on low-powered devices\nAcquire::PDiffs \"0\";\n\n# download up to 5 "
  },
  {
    "path": "stage2/01-sys-tweaks/files/90-qemu.rules",
    "chars": 104,
    "preview": "KERNEL==\"sda\", SYMLINK+=\"mmcblk0\"\nKERNEL==\"sda?\", SYMLINK+=\"mmcblk0p%n\"\nKERNEL==\"sda2\", SYMLINK+=\"root\"\n"
  },
  {
    "path": "stage2/01-sys-tweaks/files/console-setup",
    "chars": 276,
    "preview": "# CONFIGURATION FILE FOR SETUPCON\n\n# Consult the console-setup(5) manual page.\n\nACTIVE_CONSOLES=\"/dev/tty[1-6]\"\n\nCHARMAP"
  },
  {
    "path": "stage2/01-sys-tweaks/files/rc.local",
    "chars": 420,
    "preview": "#!/bin/sh -e\n#\n# rc.local\n#\n# This script is executed at the end of each multiuser runlevel.\n# Make sure that the script"
  },
  {
    "path": "stage2/01-sys-tweaks/files/resize2fs_once",
    "chars": 560,
    "preview": "#!/bin/sh\n### BEGIN INIT INFO\n# Provides:          resize2fs_once\n# Required-Start:\n# Required-Stop:\n# Default-Start: 3\n"
  },
  {
    "path": "stage2/01-sys-tweaks/files/ttyoutput.conf",
    "chars": 29,
    "preview": "[Service]\nStandardOutput=tty\n"
  },
  {
    "path": "stage2/02-net-tweaks/00-packages",
    "chars": 161,
    "preview": "wpasupplicant wireless-tools firmware-atheros firmware-brcm80211 firmware-libertas firmware-misc-nonfree firmware-realte"
  },
  {
    "path": "stage2/02-net-tweaks/01-run.sh",
    "chars": 825,
    "preview": "#!/bin/bash -e\n\ninstall -v -d\t\t\t\t\t\"${ROOTFS_DIR}/etc/systemd/system/dhcpcd.service.d\"\ninstall -v -m 644 files/wait.conf\t"
  },
  {
    "path": "stage2/02-net-tweaks/files/wait.conf",
    "chars": 61,
    "preview": "[Service]\nExecStart=\nExecStart=/usr/lib/dhcpcd5/dhcpcd -q -w\n"
  },
  {
    "path": "stage2/02-net-tweaks/files/wpa_supplicant.conf",
    "chars": 72,
    "preview": "ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev\nupdate_config=1\n"
  },
  {
    "path": "stage2/03-accept-mathematica-eula/00-debconf",
    "chars": 131,
    "preview": "# Do you accept the Wolfram - Raspberry Pi® Bundle License Agreement?\nwolfram-engine  shared/accepted-wolfram-eula    bo"
  },
  {
    "path": "stage2/03-set-timezone/02-run.sh",
    "chars": 165,
    "preview": "#!/bin/bash -e\n\necho \"Europe/London\" > \"${ROOTFS_DIR}/etc/timezone\"\nrm \"${ROOTFS_DIR}/etc/localtime\"\n\non_chroot << EOF\nd"
  },
  {
    "path": "stage2/04-ethereum/00-packages",
    "chars": 22,
    "preview": "vim screen jq dirmngr\n"
  },
  {
    "path": "stage2/04-ethereum/01-run.sh",
    "chars": 1147,
    "preview": "#!/bin/bash -e\n\ninstall -m 644 files/ethonarm.list\t\t\t    ${ROOTFS_DIR}/etc/apt/sources.list.d/ \ninstall -m 755 files/ini"
  },
  {
    "path": "stage2/04-ethereum/files/armbian-ramlog",
    "chars": 388,
    "preview": "# configuration values for the armbian-ram-logging service\n#\n# enable the armbian-ram-logging service?\nENABLED=true\n#\n# "
  },
  {
    "path": "stage2/04-ethereum/files/armbian-zram-config.service",
    "chars": 492,
    "preview": "# Armbian ZRAM configuration service\n# Create 1 + number of cores compressed block devices\n# This service may block the "
  },
  {
    "path": "stage2/04-ethereum/files/dphys-swapfile",
    "chars": 1156,
    "preview": "# /etc/dphys-swapfile - user settings for dphys-swapfile package\n# author Neil Franklin, last modification 2010.05.05\n# "
  },
  {
    "path": "stage2/04-ethereum/files/ethonarm-rpi4-ubuntu64bit-install.sh",
    "chars": 9591,
    "preview": "#!/bin/bash\n#\n# Copyright (c) Ethereum on ARM\n#\n# This file is licensed under the terms of the GNU General Public\n# Lice"
  },
  {
    "path": "stage2/04-ethereum/files/ethonarm-rpi4-ubuntu64bit-setup.sh",
    "chars": 742,
    "preview": "#!/bin/bash\n#\n# Copyright (c) Ethereum on ARM\n#\n# This file is licensed under the terms of the GNU General Public\n# Lice"
  },
  {
    "path": "stage2/04-ethereum/files/ethonarm.list",
    "chars": 147,
    "preview": "deb http://apt.ethraspbian.com buster main\ndeb http://apt.ethraspbian.com buster-security main\ndeb http://apt.ethraspbia"
  },
  {
    "path": "stage2/04-ethereum/files/grafana/prometheus",
    "chars": 3517,
    "preview": "# Set the command-line arguments to pass to the server.\nARGS=\"--storage.tsdb.path=\"/home/prometheus/metrics2/\"\"\n\n# Prome"
  },
  {
    "path": "stage2/04-ethereum/files/grafana/prometheus-node-exporter",
    "chars": 8172,
    "preview": "# Set the command-line arguments to pass to the server.\n# Due to shell scaping, to pass backslashes for regexes, you nee"
  },
  {
    "path": "stage2/04-ethereum/files/grafana/prometheus.yml",
    "chars": 2115,
    "preview": "# Sample config for Prometheus.\n\nglobal:\n  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Defau"
  },
  {
    "path": "stage2/04-ethereum/files/grafana-eth2-onyx/prometheus",
    "chars": 3517,
    "preview": "# Set the command-line arguments to pass to the server.\nARGS=\"--storage.tsdb.path=\"/home/prometheus/metrics2/\"\"\n\n# Prome"
  },
  {
    "path": "stage2/04-ethereum/files/grafana-eth2-onyx/prometheus-node-exporter",
    "chars": 8172,
    "preview": "# Set the command-line arguments to pass to the server.\n# Due to shell scaping, to pass backslashes for regexes, you nee"
  },
  {
    "path": "stage2/04-ethereum/files/grafana-eth2-onyx/prometheus.yml",
    "chars": 1952,
    "preview": "# Sample config for Prometheus.\n\nglobal:\n  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Defau"
  },
  {
    "path": "stage2/04-ethereum/files/init_resize.sh",
    "chars": 6225,
    "preview": "#!/bin/sh\n\nreboot_pi () {\n  umount /boot\n  mount / -o remount,ro\n  sync\n  if [ \"$NOOBS\" = \"1\" ]; then\n    if [ \"$NEW_KER"
  },
  {
    "path": "stage2/04-ethereum/files/rc.local.eth1",
    "chars": 10600,
    "preview": "#!/bin/bash\n#\n# rc.local\n#\n# This script is executed at the end of each multiuser runlevel.\n# Make sure that the script "
  },
  {
    "path": "stage2/04-ethereum/files/rc.local.eth2",
    "chars": 10674,
    "preview": "#!/bin/bash\n#\n# rc.local\n#\n# This script is executed at the end of each multiuser runlevel.\n# Make sure that the script "
  },
  {
    "path": "stage2/04-ethereum/files/rc.local.eth2.medalla",
    "chars": 10536,
    "preview": "#!/bin/bash\n#\n# rc.local\n#\n# This script is executed at the end of each multiuser runlevel.\n# Make sure that the script "
  },
  {
    "path": "stage2/04-ethereum/files/rc.local.eth2.onyx",
    "chars": 10836,
    "preview": "#!/bin/bash\n#\n# rc.local\n#\n# This script is executed at the end of each multiuser runlevel.\n# Make sure that the script "
  },
  {
    "path": "stage2/04-ethereum/files/zram-default/armbian-zram-config",
    "chars": 134,
    "preview": "# configuration values for the armbian-zram-config service\n#\n# enable the armbian-zram-config service\nENABLED=true\nZRAM_"
  },
  {
    "path": "stage2/04-ethereum/files/zram-lib/armbian-zram-config",
    "chars": 5191,
    "preview": "#!/bin/bash\n#\n# Copyright (c) Authors: http://www.armbian.com/authors\n#\n# This file is licensed under the terms of the G"
  },
  {
    "path": "stage2/EXPORT_IMAGE",
    "chars": 95,
    "preview": "IMG_SUFFIX=\"-lite\"\nif [ \"${USE_QEMU}\" = \"1\" ]; then\n\texport IMG_SUFFIX=\"${IMG_SUFFIX}-qemu\"\nfi\n"
  },
  {
    "path": "stage2/EXPORT_NOOBS",
    "chars": 92,
    "preview": "NOOBS_NAME=\"Raspbian Lite\"\nNOOBS_DESCRIPTION=\"A port of Debian with no desktop environment\"\n"
  },
  {
    "path": "stage2/prerun.sh",
    "chars": 68,
    "preview": "#!/bin/bash -e\n\nif [ ! -d \"${ROOTFS_DIR}\" ]; then\n\tcopy_previous\nfi\n"
  },
  {
    "path": "stage3/00-install-packages/00-debconf",
    "chars": 139,
    "preview": "# Adobe Flash Player. Copyright 1996-2015. Adobe Systems Incorporated. All Rights Reserved.\nrpi-chromium-mods\trpi-chromi"
  },
  {
    "path": "stage3/00-install-packages/00-packages",
    "chars": 352,
    "preview": "gstreamer1.0-x gstreamer1.0-omx gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1."
  },
  {
    "path": "stage3/00-install-packages/00-packages-nr",
    "chars": 202,
    "preview": "xserver-xorg-video-fbdev xserver-xorg xinit xserver-xorg-video-fbturbo\nepiphany-browser\nlxde lxtask menu-xdg\nzenity xdg-"
  },
  {
    "path": "stage3/00-install-packages/01-run.sh",
    "chars": 245,
    "preview": "#!/bin/bash -e\n\non_chroot << EOF\nupdate-alternatives --install /usr/bin/x-www-browser \\\n  x-www-browser /usr/bin/chromiu"
  },
  {
    "path": "stage3/01-tweaks/00-run.sh",
    "chars": 84,
    "preview": "#!/bin/bash -e\n\nrm -f \"${ROOTFS_DIR}/etc/systemd/system/dhcpcd.service.d/wait.conf\"\n"
  },
  {
    "path": "stage3/prerun.sh",
    "chars": 68,
    "preview": "#!/bin/bash -e\n\nif [ ! -d \"${ROOTFS_DIR}\" ]; then\n\tcopy_previous\nfi\n"
  },
  {
    "path": "stage4/00-install-packages/00-debconf",
    "chars": 81,
    "preview": "# Enable realtime process priority?\njackd2  jackd/tweak_rt_limits   boolean true\n"
  },
  {
    "path": "stage4/00-install-packages/00-packages",
    "chars": 647,
    "preview": "python python3-pygame python-pygame python-tk\npython3 python3-tk python3-thonny\npython3-pgzero\npython-serial python3-ser"
  },
  {
    "path": "stage4/00-install-packages/00-packages-nr",
    "chars": 30,
    "preview": "pi-package\nrealvnc-vnc-server\n"
  },
  {
    "path": "stage4/00-install-packages/01-packages",
    "chars": 779,
    "preview": "python-automationhat python3-automationhat\npython-blinkt python3-blinkt\npython-cap1xxx python3-cap1xxx\npython-drumhat py"
  },
  {
    "path": "stage4/00-install-packages/02-packages",
    "chars": 47,
    "preview": "hunspell-en-gb\nhyphen-en-gb\nwamerican\nwbritish\n"
  },
  {
    "path": "stage4/01-console-autologin/00-run.sh",
    "chars": 110,
    "preview": "#!/bin/bash -e\n\non_chroot << EOF\n\tSUDO_USER=\"${FIRST_USER_NAME}\" raspi-config nonint do_boot_behaviour B4\nEOF\n"
  },
  {
    "path": "stage4/02-extras/00-run.sh",
    "chars": 391,
    "preview": "#!/bin/bash -e\n\n#Alacarte fixes\ninstall -v -o 1000 -g 1000 -d \"${ROOTFS_DIR}/home/${FIRST_USER_NAME}/.local\"\ninstall -v "
  },
  {
    "path": "stage4/03-magpi/00-run.sh",
    "chars": 593,
    "preview": "#!/bin/sh -e\n\nmagpi_regex=\"MagPi[[:digit:]]*.pdf\"\nmagpi_loc=\"https://www.raspberrypi.org/magpi-issues\"\nmagpi_latest=\"$(c"
  },
  {
    "path": "stage4/03-magpi/files/.gitignore",
    "chars": 6,
    "preview": "*.pdf\n"
  },
  {
    "path": "stage4/04-enable-xcompmgr/00-run.sh",
    "chars": 72,
    "preview": "#!/bin/bash -e\n\non_chroot << EOF\n\traspi-config nonint do_xcompmgr 0\nEOF\n"
  },
  {
    "path": "stage4/EXPORT_IMAGE",
    "chars": 90,
    "preview": "IMG_SUFFIX=\"\"\nif [ \"${USE_QEMU}\" = \"1\" ]; then\n\texport IMG_SUFFIX=\"${IMG_SUFFIX}-qemu\"\nfi\n"
  },
  {
    "path": "stage4/EXPORT_NOOBS",
    "chars": 89,
    "preview": "NOOBS_NAME=\"Raspbian\"\nNOOBS_DESCRIPTION=\"A port of Debian with the Raspberry Pi Desktop\"\n"
  },
  {
    "path": "stage4/prerun.sh",
    "chars": 68,
    "preview": "#!/bin/bash -e\n\nif [ ! -d \"${ROOTFS_DIR}\" ]; then\n\tcopy_previous\nfi\n"
  },
  {
    "path": "stage5/00-install-extras/00-packages",
    "chars": 221,
    "preview": "mu-editor\nsonic-pi\nscratch nuscratch scratch2\nsmartsim\n\nminecraft-pi python-minecraftpi\npython-sense-emu sense-emu-tools"
  },
  {
    "path": "stage5/00-install-libreoffice/00-packages",
    "chars": 61,
    "preview": "libreoffice-pi\nlibreoffice-help-en-gb\nlibreoffice-l10n-en-gb\n"
  },
  {
    "path": "stage5/EXPORT_IMAGE",
    "chars": 95,
    "preview": "IMG_SUFFIX=\"-full\"\nif [ \"${USE_QEMU}\" = \"1\" ]; then\n\texport IMG_SUFFIX=\"${IMG_SUFFIX}-qemu\"\nfi\n"
  },
  {
    "path": "stage5/EXPORT_NOOBS",
    "chars": 106,
    "preview": "NOOBS_NAME=\"Raspbian Full\"\nNOOBS_DESCRIPTION=\"A port of Debian with desktop and recommended applications\"\n"
  },
  {
    "path": "stage5/prerun.sh",
    "chars": 68,
    "preview": "#!/bin/bash -e\n\nif [ ! -d \"${ROOTFS_DIR}\" ]; then\n\tcopy_previous\nfi\n"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the diglos/pi-gen GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 123 files (183.9 KB), approximately 60.9k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!