[
  {
    "path": ".dockerignore",
    "content": "output/\nwork/\ndeploy/\napt-cacher-ng/\n.git/objects/*\n"
  },
  {
    "path": ".gitignore",
    "content": "deploy/*\nwork/*\nconfig\npostrun.sh\nSKIP\nSKIP_IMAGES\n.pc\n*-pc\napt-cacher-ng/\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM debian:buster\n\nENV DEBIAN_FRONTEND noninteractive\n\nRUN apt-get -y update && \\\n    apt-get -y install \\\n        git vim parted \\\n        quilt coreutils qemu-user-static debootstrap zerofree zip dosfstools \\\n        bsdtar libcap2-bin rsync grep udev xz-utils curl xxd file kmod\\\n    && rm -rf /var/lib/apt/lists/*\n\nCOPY . /pi-gen/\n\nVOLUME [ \"/pi-gen/work\", \"/pi-gen/deploy\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2015 Raspberry Pi (Trading) Ltd.\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n\n2. 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.\n\n3. 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.\n\nTHIS 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.\n"
  },
  {
    "path": "README.md",
    "content": "DISCLAIMER: This is a legacy repository. Please move to our new one:\n\nhttps://github.com/diglos/ethereumonarm\n\nEthereum 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.\n\nFor running a full Ethereum node on NanoPC-T4 or RockPro64 ARM64 devices, please see the Ethereum on ARM64 project\n\nhttps://github.com/diglos/userpatches\n\n**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)**\n\nSome 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\n\nBesides, 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).\n\nSo, 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.\n\nBasically, 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\n\n**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.\n\n# Main features\n\n* Based on Ubuntu 20.04 64bit\n* Automatic USB disk partitioning and formatting\n* Adds swap memory (ZRAM kernel module + a swap file) based on Armbian work \\[7\\]\n* Changes the hostname to something like “ethnode-e2a3e6fe” based on MAC hash\n* Runs software as a systemd service and starts syncing the Blockchain\n* Includes an APT repository for installing and upgrading Ethereum software\n* Includes a monitoring dashboard based on Grafana / Prometheus\n\n# Software included\n\nBoth 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.\n\n**Ethereum 1.0 clients**\n\n* Geth \\[8\\]: 1.9.13 (official binary)\n* Parity \\[9\\]: 2.7.2 (cross compiled)\n* Nethermind \\[10\\]: 1.8.28 (cross compiled)\n* Hyperledger Besu \\[11\\]: 1.4.4 (compiled)\n\n**Ethereum 2.0 clients**\n\n* Prysm \\[12\\]: 1.0.0-alpha6 (official binary)\n* Lighthouse \\[13\\]: 0.1.1 (compiled)\n\n**Ethereum framework**\n\n* Swarm \\[14\\]: 0.5.7 (official binary)\n* Raiden Network \\[15\\]: 0.200.0\\~rc1 (official binary)\n* IPFS \\[16\\]: 0.5.0 (official binary)\n* Statusd \\[17\\]: 0.52.3 (compiled)\n* Vipnode \\[18\\]: 2.3.3 (official binary)\n\n# INSTALLATION GUIDE AND USAGE\n\n# Recommended hardware and setup\n\n* Raspberry 4 (model B) - 4GB\n* MicroSD Card (16 GB Class 10 minimun)\n* SSD USB 3.0 disk (see storage section)\n* Power supply\n* Ethernet cable\n* 30303 Port forwarding (Eth 1.0) and 13000 port forwarding (Eth 2.0) \\[4\\]\n* A case with heatsink and fan (Optional but strongly recommended)\n* USB keyboard, Monitor and HDMI cable (micro-HDMI) (Optional)\n\n# Storage\n\nYou 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:\n\n* Use a USB portable SSD disk such as the Samsung T5 Portable SSD.\n* 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).\n\nIn 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)\n\nKeep in mind that you need to plug the disk to an USB 3.0 port (blue)\n\n# Image download & installation\n\n**1.- Download Eth 1.0 or Eth 2.0 images:**\n\n[ubuntu-20.04-preinstalled-server-arm64+raspi-eth1.img.zip](https://ethraspbian.com/downloads/ubuntu-20.04-preinstalled-server-arm64+raspi-eth1.img.zip)\n\nsha256 7fa9370d13857dd6abcc8fde637c7a9a7e3a66b307d5c28b0c0d29a09c73c55c \n\n[ubuntu-20.04-preinstalled-server-arm64+raspi-eth2.img.zip](https://ethraspbian.com/downloads/ubuntu-20.04-preinstalled-server-arm64+raspi-eth2.img.zip)\n\nsha256 74c0c15b708720e5ae5cac324f1afded6316537fb17166109326755232cd316e\n\n**2.- Flash the image**\n\nInsert the microSD in your Desktop / Laptop and download the file (Eth 1.0, for instance):\n\n    wget https://ethraspbian.com/downloads/ubuntu-20.04-preinstalled-server-arm64+raspi-eth1.img.zip\n\nNote: If you are not comfortable with command line or if you are running Windows, you can use Etcher ([https://etcher.io](https://etcher.io/))\n\nOpen a terminal and check your MicroSD device name running:\n\n    sudo fdisk -l\n\nYou should see a device named mmcblk0 or sdd. Unzip and flash the image:\n\n    unzip https://ethraspbian.com/downloads/ubuntu-20.04-preinstalled-server-arm64+raspi-eth1.img.zip\n    sudo dd bs=1M if=ubuntu-20.04-preinstalled-server-arm64+raspi-eth1.img of=/dev/mmcblk0 && sync\n\n**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).\n\n**4.- Power on the device**\n\nThe 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.\n\nDepending on the image, you will be running:\n\n* Eth 1.0: Geth as the default client syncing the blockchain\n* Eth 2.0: Prysm as default client syncing the beacon chain (Topaz testnet)\n\n**5.- Log in**\n\nYou can log in through SSH or using the console (if you have a monitor and keyboard attached)\n\n    User: ethereum\n    Password: ethereum\n\nYou will be prompted to change the password on first login, so you will need to login twice.\n\n**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.\n\n**7.- Getting console output**\n\nYou can see what’s happening in the background by typing:\n\n    sudo tail -f /var/log/syslog\n\nCongratulations. You are now running a full Ethereum node on your Raspberry Pi 4.\n\n# Syncing the Blockchain\n\nNow 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.\n\nIf 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).\n\n# Monitoring dashboards\n\nFor 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:\n\n    URL: http://your_raspberrypi_IP:3000\n    User: admin\n    Password: ethereum\n\n# Switching clients\n\nAll clients run as a systemd service. This is important because in case of some problem arises the system will respawn the process automatically.\n\nGeth 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:\n\n    sudo systemctl stop geth && sudo systemctl disable geth\n\nCommands to enable and start each Eth 1.0 client:\n\n    sudo systemctl enable besu && sudo systemctl start besu\n    sudo systemctl enable nethermind && sudo systemctl start nethermind\n    sudo systemctl enable parity && sudo systemctl start parity\n\nEth 2.0:\n\n    sudo systemctl stop prysm-beacon && sudo systemctl disable prysm-beacon\n    sudo systemctl start lighthouse-beacon && sudo systemctl enable lighthouse-beacon\n\n# Changing parameters\n\nClients’ 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:\n\n    /etc/nethermind/configs/mainnet.cfg\n\nBlockchain clients’ data is stored on the ethereum home account as follows (note the dot before the directory name):\n\nEth 1.0\n\n    /home/ethereum/.geth\n    /home/ethereum/.parity\n    /home/ethereum/.besu\n    /home/ethereum/.nethermind\n\nEth2.0\n\n    /home/ethereum/.eth2\n    /home/ethereum/.eth2validators\n    /home/ethereum/.lighthouse\n    Hyperledger Besu and Nethermind\n\n# Nethermind and Hyperledger Besu\n\nThese 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.\n\nBoth need further testing so feel free to play with them and report back your feedback.\n\n# How to run the Eth 2.0 validator (staking)\n\nOnce 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:\n\n[https://prylabs.net/participate](https://prylabs.net/participate)\n\nThe 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\n\n# Feeback appreciated\n\nWe 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.\n\nPlease, 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)).\n"
  },
  {
    "path": "build-docker.sh",
    "content": "#!/bin/bash -e\n\nBUILD_OPTS=\"$*\"\n\nDOCKER=\"docker\"\nset +e\nif ! $DOCKER ps >/dev/null 2>&1; then\n\tDOCKER=\"sudo docker\"\nfi\nif ! $DOCKER ps >/dev/null; then\n\techo \"error connecting to docker:\"\n\t$DOCKER ps\n\texit 1\nfi\nset -e\n\nif [ -f config ]; then\n\t# shellcheck disable=SC1091\n\tsource config\nfi\n\nwhile getopts \"c:\" flag\ndo\n\tcase \"$flag\" in\n\t\tc)\n\t\t\t# shellcheck disable=SC1090\n\t\t\tsource \"$OPTARG\"\n\t\t\t;;\n\t\t*)\n\t\t\t;;\n\tesac\ndone\n\nCONTAINER_NAME=${CONTAINER_NAME:-pigen_work}\nCONTINUE=${CONTINUE:-0}\nPRESERVE_CONTAINER=${PRESERVE_CONTAINER:-0}\n\nif [ -z \"${IMG_NAME}\" ]; then\n\techo \"IMG_NAME not set in 'config'\" 1>&2\n\techo 1>&2\nexit 1\nfi\n\nCONTAINER_EXISTS=$($DOCKER ps -a --filter name=\"$CONTAINER_NAME\" -q)\nCONTAINER_RUNNING=$($DOCKER ps --filter name=\"$CONTAINER_NAME\" -q)\nif [ \"$CONTAINER_RUNNING\" != \"\" ]; then\n\techo \"The build is already running in container $CONTAINER_NAME. Aborting.\"\n\texit 1\nfi\nif [ \"$CONTAINER_EXISTS\" != \"\" ] && [ \"$CONTINUE\" != \"1\" ]; then\n\techo \"Container $CONTAINER_NAME already exists and you did not specify CONTINUE=1. Aborting.\"\n\techo \"You can delete the existing container like this:\"\n\techo \"  $DOCKER rm -v $CONTAINER_NAME\"\n\texit 1\nfi\n\n$DOCKER build -t pi-gen .\nif [ \"$CONTAINER_EXISTS\" != \"\" ]; then\n\ttrap 'echo \"got CTRL+C... please wait 5s\"; $DOCKER stop -t 5 ${CONTAINER_NAME}_cont' SIGINT SIGTERM\n\ttime $DOCKER run --rm --privileged \\\n\t\t--volumes-from=\"${CONTAINER_NAME}\" --name \"${CONTAINER_NAME}_cont\" \\\n\t\tpi-gen \\\n\t\tbash -e -o pipefail -c \"dpkg-reconfigure qemu-user-static &&\n\tcd /pi-gen; ./build.sh ${BUILD_OPTS} ;\n\trsync -av work/*/build.log deploy/\" &\n\twait \"$!\"\nelse\n\ttrap 'echo \"got CTRL+C... please wait 5s\"; $DOCKER stop -t 5 ${CONTAINER_NAME}' SIGINT SIGTERM\n\ttime $DOCKER run --name \"${CONTAINER_NAME}\" --privileged \\\n\t\tpi-gen \\\n\t\tbash -e -o pipefail -c \"dpkg-reconfigure qemu-user-static &&\n\tcd /pi-gen; ./build.sh ${BUILD_OPTS} &&\n\trsync -av work/*/build.log deploy/\" &\n\twait \"$!\"\nfi\necho \"copying results from deploy/\"\n$DOCKER cp \"${CONTAINER_NAME}\":/pi-gen/deploy .\nls -lah deploy\n\n# cleanup\nif [ \"$PRESERVE_CONTAINER\" != \"1\" ]; then\n\t$DOCKER rm -v \"$CONTAINER_NAME\"\nfi\n\necho \"Done! Your image(s) should be in deploy/\"\n"
  },
  {
    "path": "build.sh",
    "content": "#!/bin/bash -e\n# shellcheck disable=SC2119\nrun_sub_stage()\n{\n\tlog \"Begin ${SUB_STAGE_DIR}\"\n\tpushd \"${SUB_STAGE_DIR}\" > /dev/null\n\tfor i in {00..99}; do\n\t\tif [ -f \"${i}-debconf\" ]; then\n\t\t\tlog \"Begin ${SUB_STAGE_DIR}/${i}-debconf\"\n\t\t\ton_chroot << EOF\ndebconf-set-selections <<SELEOF\n$(cat \"${i}-debconf\")\nSELEOF\nEOF\n\n\t\tlog \"End ${SUB_STAGE_DIR}/${i}-debconf\"\n\t\tfi\n\t\tif [ -f \"${i}-packages-nr\" ]; then\n\t\t\tlog \"Begin ${SUB_STAGE_DIR}/${i}-packages-nr\"\n\t\t\tPACKAGES=\"$(sed -f \"${SCRIPT_DIR}/remove-comments.sed\" < \"${i}-packages-nr\")\"\n\t\t\tif [ -n \"$PACKAGES\" ]; then\n\t\t\t\ton_chroot << EOF\napt-get install --no-install-recommends -y $PACKAGES\nEOF\n\t\t\tfi\n\t\t\tlog \"End ${SUB_STAGE_DIR}/${i}-packages-nr\"\n\t\tfi\n\t\tif [ -f \"${i}-packages\" ]; then\n\t\t\tlog \"Begin ${SUB_STAGE_DIR}/${i}-packages\"\n\t\t\tPACKAGES=\"$(sed -f \"${SCRIPT_DIR}/remove-comments.sed\" < \"${i}-packages\")\"\n\t\t\tif [ -n \"$PACKAGES\" ]; then\n\t\t\t\ton_chroot << EOF\napt-get install -y $PACKAGES\nEOF\n\t\t\tfi\n\t\t\tlog \"End ${SUB_STAGE_DIR}/${i}-packages\"\n\t\tfi\n\t\tif [ -d \"${i}-patches\" ]; then\n\t\t\tlog \"Begin ${SUB_STAGE_DIR}/${i}-patches\"\n\t\t\tpushd \"${STAGE_WORK_DIR}\" > /dev/null\n\t\t\tif [ \"${CLEAN}\" = \"1\" ]; then\n\t\t\t\trm -rf .pc\n\t\t\t\trm -rf ./*-pc\n\t\t\tfi\n\t\t\tQUILT_PATCHES=\"${SUB_STAGE_DIR}/${i}-patches\"\n\t\t\tSUB_STAGE_QUILT_PATCH_DIR=\"$(basename \"$SUB_STAGE_DIR\")-pc\"\n\t\t\tmkdir -p \"$SUB_STAGE_QUILT_PATCH_DIR\"\n\t\t\tln -snf \"$SUB_STAGE_QUILT_PATCH_DIR\" .pc\n\t\t\tquilt upgrade\n\t\t\tif [ -e \"${SUB_STAGE_DIR}/${i}-patches/EDIT\" ]; then\n\t\t\t\techo \"Dropping into bash to edit patches...\"\n\t\t\t\tbash\n\t\t\tfi\n\t\t\tRC=0\n\t\t\tquilt push -a || RC=$?\n\t\t\tcase \"$RC\" in\n\t\t\t\t0|2)\n\t\t\t\t\t;;\n\t\t\t\t*)\n\t\t\t\t\tfalse\n\t\t\t\t\t;;\n\t\t\tesac\n\t\t\tpopd > /dev/null\n\t\t\tlog \"End ${SUB_STAGE_DIR}/${i}-patches\"\n\t\tfi\n\t\tif [ -x ${i}-run.sh ]; then\n\t\t\tlog \"Begin ${SUB_STAGE_DIR}/${i}-run.sh\"\n\t\t\t./${i}-run.sh\n\t\t\tlog \"End ${SUB_STAGE_DIR}/${i}-run.sh\"\n\t\tfi\n\t\tif [ -f ${i}-run-chroot.sh ]; then\n\t\t\tlog \"Begin ${SUB_STAGE_DIR}/${i}-run-chroot.sh\"\n\t\t\ton_chroot < ${i}-run-chroot.sh\n\t\t\tlog \"End ${SUB_STAGE_DIR}/${i}-run-chroot.sh\"\n\t\tfi\n\tdone\n\tpopd > /dev/null\n\tlog \"End ${SUB_STAGE_DIR}\"\n}\n\n\nrun_stage(){\n\tlog \"Begin ${STAGE_DIR}\"\n\tSTAGE=\"$(basename \"${STAGE_DIR}\")\"\n\tpushd \"${STAGE_DIR}\" > /dev/null\n\tunmount \"${WORK_DIR}/${STAGE}\"\n\tSTAGE_WORK_DIR=\"${WORK_DIR}/${STAGE}\"\n\tROOTFS_DIR=\"${STAGE_WORK_DIR}\"/rootfs\n\tif [ ! -f SKIP_IMAGES ]; then\n\t\tif [ -f \"${STAGE_DIR}/EXPORT_IMAGE\" ]; then\n\t\t\tEXPORT_DIRS=\"${EXPORT_DIRS} ${STAGE_DIR}\"\n\t\tfi\n\tfi\n\tif [ ! -f SKIP ]; then\n\t\tif [ \"${CLEAN}\" = \"1\" ]; then\n\t\t\tif [ -d \"${ROOTFS_DIR}\" ]; then\n\t\t\t\trm -rf \"${ROOTFS_DIR}\"\n\t\t\tfi\n\t\tfi\n\t\tif [ -x prerun.sh ]; then\n\t\t\tlog \"Begin ${STAGE_DIR}/prerun.sh\"\n\t\t\t./prerun.sh\n\t\t\tlog \"End ${STAGE_DIR}/prerun.sh\"\n\t\tfi\n\t\tfor SUB_STAGE_DIR in \"${STAGE_DIR}\"/*; do\n\t\t\tif [ -d \"${SUB_STAGE_DIR}\" ] &&\n\t\t\t   [ ! -f \"${SUB_STAGE_DIR}/SKIP\" ]; then\n\t\t\t\trun_sub_stage\n\t\t\tfi\n\t\tdone\n\tfi\n\tunmount \"${WORK_DIR}/${STAGE}\"\n\tPREV_STAGE=\"${STAGE}\"\n\tPREV_STAGE_DIR=\"${STAGE_DIR}\"\n\tPREV_ROOTFS_DIR=\"${ROOTFS_DIR}\"\n\tpopd > /dev/null\n\tlog \"End ${STAGE_DIR}\"\n}\n\nif [ \"$(id -u)\" != \"0\" ]; then\n\techo \"Please run as root\" 1>&2\n\texit 1\nfi\n\n\nif [ -f config ]; then\n\t# shellcheck disable=SC1091\n\tsource config\nfi\n\nwhile getopts \"c:\" flag\ndo\n\tcase \"$flag\" in\n\t\tc)\n\t\t\tEXTRA_CONFIG=\"$OPTARG\"\n\t\t\t# shellcheck disable=SC1090\n\t\t\tsource \"$EXTRA_CONFIG\"\n\t\t\t;;\n\t\t*)\n\t\t\t;;\n\tesac\ndone\n\nexport PI_GEN=${PI_GEN:-pi-gen}\nexport PI_GEN_REPO=${PI_GEN_REPO:-https://github.com/RPi-Distro/pi-gen}\n\nif [ -z \"${IMG_NAME}\" ]; then\n\techo \"IMG_NAME not set\" 1>&2\n\texit 1\nfi\n\nexport USE_QEMU=\"${USE_QEMU:-0}\"\nexport IMG_DATE=\"${IMG_DATE:-\"$(date +%Y-%m-%d)\"}\"\nexport IMG_FILENAME=\"${IMG_FILENAME:-\"${IMG_DATE}-${IMG_NAME}\"}\"\nexport ZIP_FILENAME=\"${ZIP_FILENAME:-\"image_${IMG_DATE}-${IMG_NAME}\"}\"\n\nBASE_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nexport SCRIPT_DIR=\"${BASE_DIR}/scripts\"\nexport WORK_DIR=\"${WORK_DIR:-\"${BASE_DIR}/work/${IMG_DATE}-${IMG_NAME}\"}\"\nexport DEPLOY_DIR=${DEPLOY_DIR:-\"${BASE_DIR}/deploy\"}\nexport DEPLOY_ZIP=\"${DEPLOY_ZIP:-1}\"\nexport LOG_FILE=\"${WORK_DIR}/build.log\"\n\nexport FIRST_USER_NAME=${FIRST_USER_NAME:-pi}\nexport FIRST_USER_PASS=${FIRST_USER_PASS:-raspberry}\nexport WPA_ESSID\nexport WPA_PASSWORD\nexport WPA_COUNTRY\nexport ENABLE_SSH=\"${ENABLE_SSH:-0}\"\n\nexport BASE_DIR\n\nexport CLEAN\nexport IMG_NAME\nexport APT_PROXY\n\nexport STAGE\nexport STAGE_DIR\nexport STAGE_WORK_DIR\nexport PREV_STAGE\nexport PREV_STAGE_DIR\nexport ROOTFS_DIR\nexport PREV_ROOTFS_DIR\nexport IMG_SUFFIX\nexport NOOBS_NAME\nexport NOOBS_DESCRIPTION\nexport EXPORT_DIR\nexport EXPORT_ROOTFS_DIR\n\nexport QUILT_PATCHES\nexport QUILT_NO_DIFF_INDEX=1\nexport QUILT_NO_DIFF_TIMESTAMPS=1\nexport QUILT_REFRESH_ARGS=\"-p ab\"\n\n# shellcheck source=scripts/common\nsource \"${SCRIPT_DIR}/common\"\n# shellcheck source=scripts/dependencies_check\nsource \"${SCRIPT_DIR}/dependencies_check\"\n\ndependencies_check \"${BASE_DIR}/depends\"\n\n#check username is valid\nif [[ ! \"$FIRST_USER_NAME\" =~ ^[a-z][-a-z0-9_]*$ ]]; then\n\techo \"Invalid FIRST_USER_NAME: $FIRST_USER_NAME\"\n\texit 1\nfi\n\nif [[ -n \"${APT_PROXY}\" ]] && ! curl --silent \"${APT_PROXY}\" >/dev/null ; then\n\techo \"Could not reach APT_PROXY server: ${APT_PROXY}\"\n\texit 1\nfi\n\nmkdir -p \"${WORK_DIR}\"\nlog \"Begin ${BASE_DIR}\"\n\nSTAGE_LIST=${STAGE_LIST:-${BASE_DIR}/stage*}\n\nfor STAGE_DIR in $STAGE_LIST; do\n\tSTAGE_DIR=$(realpath \"${STAGE_DIR}\")\n\trun_stage\ndone\n\nCLEAN=1\nfor EXPORT_DIR in ${EXPORT_DIRS}; do\n\tSTAGE_DIR=${BASE_DIR}/export-image\n\t# shellcheck source=/dev/null\n\tsource \"${EXPORT_DIR}/EXPORT_IMAGE\"\n\tEXPORT_ROOTFS_DIR=${WORK_DIR}/$(basename \"${EXPORT_DIR}\")/rootfs\n\trun_stage\n\tif [ \"${USE_QEMU}\" != \"1\" ]; then\n\t\tif [ -e \"${EXPORT_DIR}/EXPORT_NOOBS\" ]; then\n\t\t\t# shellcheck source=/dev/null\n\t\t\tsource \"${EXPORT_DIR}/EXPORT_NOOBS\"\n\t\t\tSTAGE_DIR=\"${BASE_DIR}/export-noobs\"\n\t\t\trun_stage\n\t\tfi\n\tfi\ndone\n\nif [ -x postrun.sh ]; then\n\tlog \"Begin postrun.sh\"\n\tcd \"${BASE_DIR}\"\n\t./postrun.sh\n\tlog \"End postrun.sh\"\nfi\n\nlog \"End ${BASE_DIR}\"\n"
  },
  {
    "path": "depends",
    "content": "quilt\nparted\nrealpath:coreutils\nqemu-arm-static:qemu-user-static\ndebootstrap\nzerofree\nzip\nmkdosfs:dosfstools\ncapsh:libcap2-bin\nbsdtar\ngrep\nrsync\nxz:xz-utils\ncurl\nxxd\nfile\ngit\nlsmod:kmod\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "version: '2'\n\nservices:\n  apt-cacher-ng:\n    restart: unless-stopped\n    image: sameersbn/apt-cacher-ng:latest\n    ports:\n    - \"3142:3142\"\n    volumes:\n    - ./apt-cacher-ng:/var/cache/apt-cacher-ng\n"
  },
  {
    "path": "export-image/00-allow-rerun/00-run.sh",
    "content": "#!/bin/bash -e\n\nif [ ! -x \"${ROOTFS_DIR}/usr/bin/qemu-arm-static\" ]; then\n\tcp /usr/bin/qemu-arm-static \"${ROOTFS_DIR}/usr/bin/\"\nfi\n\nif [ -e \"${ROOTFS_DIR}/etc/ld.so.preload\" ]; then\n\tmv \"${ROOTFS_DIR}/etc/ld.so.preload\" \"${ROOTFS_DIR}/etc/ld.so.preload.disabled\"\nfi\n"
  },
  {
    "path": "export-image/01-set-sources/01-run.sh",
    "content": "#!/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",
    "content": "#!/bin/bash -e\n\ninstall -m 644 files/resolv.conf \"${ROOTFS_DIR}/etc/\"\n"
  },
  {
    "path": "export-image/02-network/files/resolv.conf",
    "content": "nameserver 8.8.8.8\n"
  },
  {
    "path": "export-image/03-set-partuuid/00-run.sh",
    "content": "#!/bin/bash -e\n\nIMG_FILE=\"${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img\"\n\nIMGID=\"$(dd if=\"${IMG_FILE}\" skip=440 bs=1 count=4 2>/dev/null | xxd -e | cut -f 2 -d' ')\"\n\nBOOT_PARTUUID=\"${IMGID}-01\"\nROOT_PARTUUID=\"${IMGID}-02\"\n\nsed -i \"s/BOOTDEV/PARTUUID=${BOOT_PARTUUID}/\" \"${ROOTFS_DIR}/etc/fstab\"\nsed -i \"s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/\" \"${ROOTFS_DIR}/etc/fstab\"\n\nsed -i \"s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/\" \"${ROOTFS_DIR}/boot/cmdline.txt\"\n"
  },
  {
    "path": "export-image/04-finalise/01-run.sh",
    "content": "#!/bin/bash -e\n\nIMG_FILE=\"${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img\"\nINFO_FILE=\"${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.info\"\n\non_chroot << EOF\n/etc/init.d/fake-hwclock stop\nhardlink -t /usr/share/doc\nEOF\n\nif [ -d \"${ROOTFS_DIR}/home/${FIRST_USER_NAME}/.config\" ]; then\n\tchmod 700 \"${ROOTFS_DIR}/home/${FIRST_USER_NAME}/.config\"\nfi\n\nrm -f \"${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache\"\nrm -f \"${ROOTFS_DIR}/usr/bin/qemu-arm-static\"\n\nif [ \"${USE_QEMU}\" != \"1\" ]; then\n\tif [ -e \"${ROOTFS_DIR}/etc/ld.so.preload.disabled\" ]; then\n\t\tmv \"${ROOTFS_DIR}/etc/ld.so.preload.disabled\" \"${ROOTFS_DIR}/etc/ld.so.preload\"\n\tfi\nfi\n\nrm -f \"${ROOTFS_DIR}/etc/network/interfaces.dpkg-old\"\n\nrm -f \"${ROOTFS_DIR}/etc/apt/sources.list~\"\nrm -f \"${ROOTFS_DIR}/etc/apt/trusted.gpg~\"\n\nrm -f \"${ROOTFS_DIR}/etc/passwd-\"\nrm -f \"${ROOTFS_DIR}/etc/group-\"\nrm -f \"${ROOTFS_DIR}/etc/shadow-\"\nrm -f \"${ROOTFS_DIR}/etc/gshadow-\"\nrm -f \"${ROOTFS_DIR}/etc/subuid-\"\nrm -f \"${ROOTFS_DIR}/etc/subgid-\"\n\nrm -f \"${ROOTFS_DIR}\"/var/cache/debconf/*-old\nrm -f \"${ROOTFS_DIR}\"/var/lib/dpkg/*-old\n\nrm -f \"${ROOTFS_DIR}\"/usr/share/icons/*/icon-theme.cache\n\nrm -f \"${ROOTFS_DIR}/var/lib/dbus/machine-id\"\n\ntrue > \"${ROOTFS_DIR}/etc/machine-id\"\n\nln -nsf /proc/mounts \"${ROOTFS_DIR}/etc/mtab\"\n\nfind \"${ROOTFS_DIR}/var/log/\" -type f -exec cp /dev/null {} \\;\n\nrm -f \"${ROOTFS_DIR}/root/.vnc/private.key\"\nrm -f \"${ROOTFS_DIR}/etc/vnc/updateid\"\n\nupdate_issue \"$(basename \"${EXPORT_DIR}\")\"\ninstall -m 644 \"${ROOTFS_DIR}/etc/rpi-issue\" \"${ROOTFS_DIR}/boot/issue.txt\"\n\ncp \"$ROOTFS_DIR/etc/rpi-issue\" \"$INFO_FILE\"\n\n\n{\n\tif [ -f \"$ROOTFS_DIR/usr/share/doc/raspberrypi-kernel/changelog.Debian.gz\" ]; then\n\t\tfirmware=$(zgrep \"firmware as of\" \\\n\t\t\t\"$ROOTFS_DIR/usr/share/doc/raspberrypi-kernel/changelog.Debian.gz\" | \\\n\t\t\thead -n1 | sed  -n 's|.* \\([^ ]*\\)$|\\1|p')\n\t\tprintf \"\\nFirmware: https://github.com/raspberrypi/firmware/tree/%s\\n\" \"$firmware\"\n\n\t\tkernel=\"$(curl -s -L \"https://github.com/raspberrypi/firmware/raw/$firmware/extra/git_hash\")\"\n\t\tprintf \"Kernel: https://github.com/raspberrypi/linux/tree/%s\\n\" \"$kernel\"\n\n\t\tuname=\"$(curl -s -L \"https://github.com/raspberrypi/firmware/raw/$firmware/extra/uname_string7\")\"\n\t\tprintf \"Uname string: %s\\n\" \"$uname\"\n\tfi\n\n\tprintf \"\\nPackages:\\n\"\n\tdpkg -l --root \"$ROOTFS_DIR\"\n} >> \"$INFO_FILE\"\n\nROOT_DEV=\"$(mount | grep \"${ROOTFS_DIR} \" | cut -f1 -d' ')\"\n\nunmount \"${ROOTFS_DIR}\"\nzerofree \"${ROOT_DEV}\"\n\nunmount_image \"${IMG_FILE}\"\n\nmkdir -p \"${DEPLOY_DIR}\"\n\nrm -f \"${DEPLOY_DIR}/${ZIP_FILENAME}${IMG_SUFFIX}.zip\"\nrm -f \"${DEPLOY_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img\"\n\nif [ \"${DEPLOY_ZIP}\" == \"1\" ]; then\n\tpushd \"${STAGE_WORK_DIR}\" > /dev/null\n\tzip \"${DEPLOY_DIR}/${ZIP_FILENAME}${IMG_SUFFIX}.zip\" \\\n\t\t\"$(basename \"${IMG_FILE}\")\"\n\tpopd > /dev/null\nelse\n\tcp \"$IMG_FILE\" \"$DEPLOY_DIR\"\nfi\n\ncp \"$INFO_FILE\" \"$DEPLOY_DIR\"\n"
  },
  {
    "path": "export-image/prerun.sh",
    "content": "#!/bin/bash -e\n\nIMG_FILE=\"${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img\"\n\nunmount_image \"${IMG_FILE}\"\n\nrm -f \"${IMG_FILE}\"\n\nrm -rf \"${ROOTFS_DIR}\"\nmkdir -p \"${ROOTFS_DIR}\"\n\nBOOT_SIZE=\"$((256 * 1024 * 1024))\"\nTOTAL_SIZE=$(du --apparent-size -s \"${EXPORT_ROOTFS_DIR}\" --exclude var/cache/apt/archives --block-size=1 | cut -f 1)\n\nROUND_SIZE=\"$((4 * 1024 * 1024))\"\nROUNDED_ROOT_SECTOR=$(((BOOT_SIZE + ROUND_SIZE) / ROUND_SIZE * ROUND_SIZE / 512 + 8192))\nIMG_SIZE=$(((BOOT_SIZE + TOTAL_SIZE + (800 * 1024 * 1024) + ROUND_SIZE - 1) / ROUND_SIZE * ROUND_SIZE))\n\ntruncate -s \"${IMG_SIZE}\" \"${IMG_FILE}\"\nfdisk -H 255 -S 63 \"${IMG_FILE}\" <<EOF\no\nn\n\n\n8192\n+$((BOOT_SIZE / 512))\np\nt\nc\nn\n\n\n${ROUNDED_ROOT_SECTOR}\n\n\np\nw\nEOF\n\nPARTED_OUT=$(parted -sm \"${IMG_FILE}\" unit b print)\nBOOT_OFFSET=$(echo \"$PARTED_OUT\" | grep -e '^1:' | cut -d':' -f 2 | tr -d B)\nBOOT_LENGTH=$(echo \"$PARTED_OUT\" | grep -e '^1:' | cut -d':' -f 4 | tr -d B)\n\nROOT_OFFSET=$(echo \"$PARTED_OUT\" | grep -e '^2:' | cut -d':' -f 2 | tr -d B)\nROOT_LENGTH=$(echo \"$PARTED_OUT\" | grep -e '^2:' | cut -d':' -f 4 | tr -d B)\n\nBOOT_DEV=$(losetup --show -f -o \"${BOOT_OFFSET}\" --sizelimit \"${BOOT_LENGTH}\" \"${IMG_FILE}\")\nROOT_DEV=$(losetup --show -f -o \"${ROOT_OFFSET}\" --sizelimit \"${ROOT_LENGTH}\" \"${IMG_FILE}\")\necho \"/boot: offset $BOOT_OFFSET, length $BOOT_LENGTH\"\necho \"/:     offset $ROOT_OFFSET, length $ROOT_LENGTH\"\n\nROOT_FEATURES=\"^huge_file\"\nfor FEATURE in metadata_csum 64bit; do\n\tif grep -q \"$FEATURE\" /etc/mke2fs.conf; then\n\t    ROOT_FEATURES=\"^$FEATURE,$ROOT_FEATURES\"\n\tfi\ndone\nmkdosfs -I -n boot -F 32 -v \"$BOOT_DEV\" > /dev/null\nmkfs.ext4 -L rootfs -O \"$ROOT_FEATURES\" \"$ROOT_DEV\" > /dev/null\n\nmount -v \"$ROOT_DEV\" \"${ROOTFS_DIR}\" -t ext4\nmkdir -p \"${ROOTFS_DIR}/boot\"\nmount -v \"$BOOT_DEV\" \"${ROOTFS_DIR}/boot\" -t vfat\n\nrsync -aHAXx --exclude /var/cache/apt/archives --exclude /boot \"${EXPORT_ROOTFS_DIR}/\" \"${ROOTFS_DIR}/\"\nrsync -rtx \"${EXPORT_ROOTFS_DIR}/boot/\" \"${ROOTFS_DIR}/boot/\"\n"
  },
  {
    "path": "export-noobs/00-release/00-run.sh",
    "content": "#!/bin/bash -e\n\nNOOBS_DIR=\"${STAGE_WORK_DIR}/${IMG_DATE}-${IMG_NAME}${IMG_SUFFIX}\"\n\ninstall -v -m 744\tfiles/partition_setup.sh\t\"${NOOBS_DIR}/\"\ninstall -v\t\tfiles/partitions.json\t\t\"${NOOBS_DIR}/\"\ninstall -v\t\tfiles/os.json\t\t\t\"${NOOBS_DIR}/\"\ninstall -v\t\tfiles/OS.png\t\t\t\"${NOOBS_DIR}/\"\ninstall -v\t\tfiles/release_notes.txt\t\t\"${NOOBS_DIR}/\"\n\ntar -v -c -C\t\tfiles/marketing\t\t\t-f \"${NOOBS_DIR}/marketing.tar\" .\n\nBOOT_SHASUM=\"$(sha256sum \"${NOOBS_DIR}/boot.tar.xz\" | cut -f1 -d' ')\"\nROOT_SHASUM=\"$(sha256sum \"${NOOBS_DIR}/root.tar.xz\" | cut -f1 -d' ')\"\n\nBOOT_SIZE=\"$(xz --robot -l \"${NOOBS_DIR}/boot.tar.xz\"  | grep totals | cut -f 5)\"\nROOT_SIZE=\"$(xz --robot -l \"${NOOBS_DIR}/root.tar.xz\"  | grep totals | cut -f 5)\"\n\nBOOT_SIZE=\"$(( BOOT_SIZE / 1024 / 1024 + 1))\"\nROOT_SIZE=\"$(( ROOT_SIZE / 1024 / 1024 + 1))\"\n\nBOOT_NOM=\"256\"\nROOT_NOM=\"$(( ROOT_SIZE + 400 ))\"\n\nmv \"${NOOBS_DIR}/OS.png\" \"${NOOBS_DIR}/${NOOBS_NAME// /_}.png\"\n\nsed \"${NOOBS_DIR}/partitions.json\" -i -e \"s|BOOT_SHASUM|${BOOT_SHASUM}|\"\nsed \"${NOOBS_DIR}/partitions.json\" -i -e \"s|ROOT_SHASUM|${ROOT_SHASUM}|\"\n\nsed \"${NOOBS_DIR}/partitions.json\" -i -e \"s|BOOT_SIZE|${BOOT_SIZE}|\"\nsed \"${NOOBS_DIR}/partitions.json\" -i -e \"s|ROOT_SIZE|${ROOT_SIZE}|\"\n\nsed \"${NOOBS_DIR}/partitions.json\" -i -e \"s|BOOT_NOM|${BOOT_NOM}|\"\nsed \"${NOOBS_DIR}/partitions.json\" -i -e \"s|ROOT_NOM|${ROOT_NOM}|\"\n\nsed \"${NOOBS_DIR}/os.json\" -i -e \"s|UNRELEASED|${IMG_DATE}|\"\nsed \"${NOOBS_DIR}/os.json\" -i -e \"s|NOOBS_NAME|${NOOBS_NAME}|\"\nsed \"${NOOBS_DIR}/os.json\" -i -e \"s|NOOBS_DESCRIPTION|${NOOBS_DESCRIPTION}|\"\n\nsed \"${NOOBS_DIR}/release_notes.txt\" -i -e \"s|UNRELEASED|${IMG_DATE}|\"\n\ncp -a \"${NOOBS_DIR}\" \"${DEPLOY_DIR}/\"\n"
  },
  {
    "path": "export-noobs/00-release/files/os.json",
    "content": "{\n    \"description\": \"NOOBS_DESCRIPTION\",\n    \"feature_level\": 35120124,\n    \"kernel\": \"4.19\",\n    \"name\": \"NOOBS_NAME\",\n    \"password\": \"raspberry\",\n    \"release_date\": \"UNRELEASED\",\n    \"supported_hex_revisions\": \"2,3,4,5,6,7,8,9,d,e,f,10,11,12,14,19,1040,1041,0092,0093,2082\",\n    \"supported_models\": [\n        \"Pi Model\",\n        \"Pi 2\",\n        \"Pi Zero\",\n        \"Pi 3\",\n        \"Pi Compute Module 3\",\n        \"Pi 4\"\n    ],\n    \"url\": \"http://www.raspbian.org/\",\n    \"username\": \"pi\",\n    \"version\": \"buster\"\n}\n"
  },
  {
    "path": "export-noobs/00-release/files/partition_setup.sh",
    "content": "#!/bin/sh\n#supports_backup in PINN\n\nset -ex\n\n# shellcheck disable=SC2154\nif [ -z \"$part1\" ] || [ -z \"$part2\" ]; then\n  printf \"Error: missing environment variable part1 or part2\\n\" 1>&2\n  exit 1\nfi\n\nmkdir -p /tmp/1 /tmp/2\n\nmount \"$part1\" /tmp/1\nmount \"$part2\" /tmp/2\n\nsed /tmp/1/cmdline.txt -i -e \"s|root=[^ ]*|root=${part2}|\"\nsed /tmp/2/etc/fstab -i -e \"s|^[^#].* / |${part2}  / |\"\nsed /tmp/2/etc/fstab -i -e \"s|^[^#].* /boot |${part1}  /boot |\"\n\n# shellcheck disable=SC2154\nif [ -z \"$restore\" ]; then\n  if [ -f /mnt/ssh ]; then\n    cp /mnt/ssh /tmp/1/\n  fi\n\n  if [ -f /mnt/ssh.txt ]; then\n    cp /mnt/ssh.txt /tmp/1/\n  fi\n\n  if [ -f /settings/wpa_supplicant.conf ]; then\n    cp /settings/wpa_supplicant.conf /tmp/1/\n  fi\n\n  if ! grep -q resize /proc/cmdline; then\n    if ! grep -q splash /tmp/1/cmdline.txt; then\n      sed -i \"s| quiet||g\" /tmp/1/cmdline.txt\n    fi\n    sed -i 's| init=/usr/lib/raspi-config/init_resize.sh||' /tmp/1/cmdline.txt\n  else\n    sed -i '1 s|.*|& sdhci.debug_quirks2=4|' /tmp/1/cmdline.txt\n  fi\nfi\n\numount /tmp/1\numount /tmp/2\n"
  },
  {
    "path": "export-noobs/00-release/files/partitions.json",
    "content": "{\n    \"partitions\": [\n        {\n            \"filesystem_type\": \"FAT\",\n            \"label\": \"boot\",\n            \"mkfs_options\": \"-F 32\",\n            \"partition_size_nominal\": BOOT_NOM,\n            \"uncompressed_tarball_size\": BOOT_SIZE,\n            \"want_maximised\": false,\n            \"sha256sum\": \"BOOT_SHASUM\"\n        },\n        {\n            \"filesystem_type\": \"ext4\",\n            \"label\": \"root\",\n            \"mkfs_options\": \"-O ^huge_file\",\n            \"partition_size_nominal\": ROOT_NOM,\n            \"uncompressed_tarball_size\": ROOT_SIZE,\n            \"want_maximised\": true,\n            \"sha256sum\": \"ROOT_SHASUM\"\n        }\n    ]\n}\n"
  },
  {
    "path": "export-noobs/00-release/files/release_notes.txt",
    "content": "UNRELEASED:\n  *\n2019-06-20:\n  * Based on Debian Buster\n  * Support for Raspberry Pi 4 hardware\n  * FKMS OpenGL desktop graphics driver and xcompmgr compositing window manager used when running on Raspberry Pi 4\n  * Screen Configuration application added for use with FKMS driver\n  * Raspberry Pi 4 video output options added to Raspberry Pi Configuration\n  * Uses new PiXflat UI theme for GTK and Openbox\n  * CPU activity gauge plugin no longer shown on taskbar by default\n  * CPU temperature gauge plugin added (not shown by default)\n  * USB ejecter and Bluetooth taskbar icons hidden when not appropriate\n  * Version 74.0.3729.157 of Chromium web browser included\n  * Version 32.0.0.207 of Flash player included\n  * IDLE Python IDE removed\n  * Wolfram Mathematica removed temporarily due to incompatibility with Buster\n  * Display of package sizes removed from Recommended Software\n  * Appearance Settings modified to support independent settings for two monitors\n  * Oracle Java 7 and 8 replaced with OpenJDK 11\n  * Miscellaneous small bug fixes\n  * On-board 5GHz WiFi blocked by rfkill by default\n    The block is removed when taking one of the following actions:\n    - Selecting a locale in the first run wizard\n    - Setting the WiFi country in the Raspberry Pi Configuration tool or the Network Settings applet\n    - Setting the WiFi country in raspi-config\n    - Providing a wpa_supplicant.conf file through the boot partition\n    - Running 'rfkill unblock wifi'\n  * Boot partition size set to 256M\n  * Linux kernel 4.19.50\n  * Raspberry Pi firmware 88ca9081f5e51cdedd16d5dbc85ed12a25123201\n2019-04-08:\n  * Chromium browser updated to version 72\n  * VLC media player updated to version 3.0.6\n  * RealVNC Server updated to version 6.4.0\n  * Flash player updated to version 32.0.0.156\n  * Performance improvements to SDL library\n  * Performance improvements to pixman library\n  * Option to set display underscan added to startup wizard\n  * Mounted external drives now displayed on desktop by default\n  * Network plugin modified for improved compatibility with wpa_passphrase\n  * SD Card Copier tweaks to reduce copy failures\n  * Various minor bug fixes and appearance tweaks\n  * Added ethtool\n  * Added rng-tools\n  * Add PINN restore support\n  * Linux kernel 4.14.98\n  * Raspberry Pi firmware f8939644f7bd3065068787f1f92b3f3c79cf3de9\n2018-11-13:\n  * Two versions of image created - \"base\" image has no optional software packages included; \"full\" image has all optional packages\n    - Removed from \"base\" image - LibreOffice, Thonny, Scratch, Scratch 2, Sonic Pi, Minecraft, Python Games, SmartSim, SenseHAT Emulator\n    - Added to \"full\" image - Mathematica, BlueJ, Greenfoot, Node-RED, Claws Mail, VNC Viewer\n  * Python Games and SmartSim added to Recommended Software\n  * VLC media player with VideoCore hardware acceleration included in image\n  * Version 3.0.5 of Thonny included\n  * Modifications to LXDE components to enable local configuration to override global configuration correctly\n  * Modifications to Appearance Settings to support above configuration changes\n  * Modifications to various initial config defaults and relevant package to support above configuration changes\n  * Selecting default option in Appearance Settings now deletes relevant local configuration files\n  * PiX theme modified so that all changes made in Appearance Settings are in override files rather than in theme files\n  * Design of scrollbar buttons changed\n  * Image Viewer moved into Graphics category on main menu\n  * Recommended Software now installs LibreOffice language support files if needed, and suggests reboot if needed\n  * Latest version of Pepper Flash plugin included\n  * Chromium h264ify plugin permissions set correctly by default\n  * Corrections to various MIME types so that files open in sensible default applications\n  * Set default timezone to 'Europe/London'\n  * Linux kernel 4.14.79\n  * Raspberry Pi firmware 12e0bf86e08d6067372bc0a45d7e8a10d3113210\n2018-10-09:\n  * Raspberry Pi 3A+ support\n  * In startup wizard, assign keyboard to country as per Debian installer recommendations\n  * In startup wizard, add option to use US keyboard in preference to country-specific option\n  * In startup wizard, show IP address on first page\n  * In startup wizard, check for existing wifi network connection and show it if there is one\n  * In startup wizard, install language support packages for LibreOffice and other applications\n  * In startup wizard, improve operation with keyboard only and no mouse\n  * Password change in Raspberry Pi Configuration and startup wizard now works properly if passwords contain shell characters\n  * Battery indicator plugin modified to cope with Pi-top hardware monitor crashing\n  * Networking plugin hides wifi password characters by default\n  * In Scratch 2 GPIO plugin, set pin from dropdown list rather than free text\n  * In Scratch 2 SenseHAT plugin, swap x and y axis values for LED array\n  * Include latest Adobe Flash player (31.0.0.108)\n  * Include latest RealVNC Server (6.3.1)\n  * Include libav-tools\n  * Include ssh-import-id\n  * Removed Mathematica\n  * Merge in latest third-party code for Bluetooth ALSA interface\n  * Add ability to prevent software update changing configuration files, by creating ~/.config/.lock file\n  * Various other small bug fixes, tweaks and changes to text\n  * Make dhcpcd work with 3G devices\n  * Add hw acceleration to ffmpeg\n  * Improved WiFi-BT coexistence parameters\n  * Run fake-hwclock before systemd-fsck-root\n  * Raspberry Pi PoE HAT support\n  * Linux kernel 4.14.71\n  * Raspberry Pi firmware 5b49caa17e91d0e64024380119ad739bb201c674\n2018-06-27:\n  * New first-boot configuration wizard added\n  * Recommended Software installer added\n  * Bluej, Greenfoot, NodeRED, Claws Mail, VNC Viewer removed from image - can now be installed from Recommended Applications\n  * Qpdfview PDF viewer installed instead of Xpdf\n  * Version 65.0 of Chromium browser included, with latest Flash player\n  * Volume up / down keys now change by 5% increments and affect currently-selected output device rather than internal device only\n  * Network plugin now remembers previously-entered WiFi network passwords when prompting for reconnection\n  * Serial port and serial console can now be switched separately in Raspberry Pi Configuration\n  * Lxkeymap keyboard language setting application removed - replaced with dialog within Raspberry Pi Configuration\n  * Wifi country and keyboard language setting dialogs in Raspberry Pi Configuration now callable from other applications\n  * New version of Piboto font included to render with correct weight under some rogue applications\n  * Reconnection to Bluetooth audio devices on reboot improved\n  * Disable click-to-rename behaviour in file manager if single-click selection enabled\n  * Appearance Settings dialog makes config changes to some Qt files to match selected theme\n  * MIME file type associations improved\n  * Multiple desktop management options removed from mouse middle-click menu\n  * Menu shortcuts to Raspberry Pi website amended\n  * Python 2 IDLE menu link removed\n  * Sample Magpi PDF installed in /home/pi/MagPi\n  * Various minor tweaks, bug fixes and appearance changes\n  * Bluetooth updates\n    - Firmware with Bluetooth 4.2 features\n    - SCO profile suppot added via bthelper.service\n  * Linux kernel 4.14.50+\n  * Raspberry Pi firmware 748fb17992426bb29d99224b93cb962fefbdc833\n2018-04-18:\n  * Fixed race between wifi-country.service and raspberrypi-net-mods.service\n  * Linux kernel 4.14.34+\n  * Raspberry Pi firmware 5db8e4e1c63178e200d6fbea23ed4a9bf4656658\n2018-03-13:\n  * Raspberry Pi 3 B+ support\n  * WiFi is disabled until wireless regulatory domain is set (Pi 3 B+ only)\n    - The domain can be done through 'Raspberry Pi Configuration' (rc_gui),\n      'raspi-config' or by setting 'country=' to an appropriate ISO 3166\n      alpha2 country code in /etc/wpa_supplicant/wpa_supplicant.conf.\n  * Default wireless regulatory domain is now unset\n  * Added support to desktop for different screen sizes and resolutions,\n    including multiple preset options in Appearance Settings and pixel doubling\n    option in Raspberry Pi Configuration\n  * Version 2.1.16 of Thonny included\n  * Version 29.0.0.113 of Adobe PepperFlash player included\n  * Version 1.2.post1 of Pygame Zero included\n  * Bluetooth plugin now supports connection to Bluetooth LE HID devices\n  * Network plugin now indicates 5G-compatible APs\n  * Latest changes to Bluez ALSA service merged\n    - service now started on CLI boot as well as GUI boot\n  * Latest changes to dhcpcd networking plugin merged\n  * Improved support for running on pi-top devices\n  * Small design changes to PiX theme and icons\n  * Bug fix - hide spurious window resize handles\n  * Bug fix - Scratch 2 remote GPIO state block now works correctly\n  * Updated WiFi Firmware\n    - brcmfmac43455-sdio 7.45.154\n    - brcmfmac43430-sdio 7.45.98.38\n  * New packages:\n    - policykit-1\n    - obconf\n    - python-buttonshim python3-buttonshim\n    - python-unicornhathd  python3-unicornhathd\n    - python-pantilthat python3-pantilthat\n  * Linux kernel 4.9.80+\n  * Raspberry Pi firmware 3347884c7df574bbabeff6dca63caf686e629699\n2017-11-29:\n  * Added battery monitor plugin for taskbar - works on x86 images or first-generation Pi-Top\n  * Added cutdown mode to PCManFM file manager to reduce complexity\n  * Added ability to rename files in PCManFM by clicking name when selected\n  * Bug fix in Bluetooth ALSA module to reduce truncation of audio at end of playback\n  * Various small tweaks, bug fixes and theme modifications\n  * New kernel and firmware\n2017-09-07:\n  * Disable predictable network interface names for Ethernet devices\n  * Bug fix for keyboard settings dialog in Raspberry Pi Configuration\n  * Bug fix for crash on some videos and animations in Chromium\n  * Bug fix for taskbar crash when running RealVNC server\n  * Bug fix for reloading projects with extensions in Scratch 2\n  * Bug fix for MAC address problem in Bluetooth\n  * Simple mode and new icons in Thonny\n  * New Japanese translations in Raspberry Pi Configuration\n  * Install fonts-droid-fallback for international fonts\n2017-08-16:\n  * Based on Raspbian Stretch (Debian version 9)\n  * Version 60 of Chromium browser included\n  * Version 3.0.1 of Sonic Pi included\n  * Version 6.1.1 of RealVNC included\n  * Version 0.17.4 of NodeRED included\n  * Bluetooth audio routed via ALSA rather than Pulseaudio\n  * SenseHAT extension added to Scratch 2\n  * Various desktop applications modified to prompt for sudo password if needed\n  * lxinput control options for mouse speed simplified\n  * lxpanel plugins moved into separate packages\n  * Wireless firmware for Pi 3 and Pi 0W modified to address Broadpwn exploit\n  * Latest kernel and firmware\n  * Various small tweaks, bug fixes and theme modifications\n2017-07-05:\n  * New kernel and firmware\n  * Filesystem created without the metadata_csum feature\n2017-06-21:\n  * Scratch 2 application included\n  * Thonny Python IDE included\n  * New icons with thinner outlines\n  * Volume control more linear in behaviour\n  * Updated Flash player\n  * Updated RealVNC server and viewer\n  * Various tweaks and bugfixes\n  * New kernel and firmware\n2017-04-10:\n  * Wolfram Mathematica updated to version 11.0.1\n  * Adobe Flash Player updated to version 25.0.0.127\n  * Use PARTUUID to support USB boot\n2017-03-02:\n  * Updated kernel and firmware (final Pi Zero W support)\n  * Wolfram Mathematica updated to version 11\n  * NOOBS installs now checks for presence of 'ssh' file on the NOOBS partition.\n2017-02-16:\n  * Chromium browser updated to version 56\n  * Adobe Flash Player updated to version 24.0.0.221\n  * RealVNC Server and Viewer updated to version 6.0.2 (RealVNC Connect)\n  * Sonic Pi updated to version 2.11\n  * Node-RED updated to version 0.15.3\n  * Scratch updated to version 120117\n  * Detection of SSH enabled with default password moved into PAM\n  * Updated desktop GL driver to support use of fake KMS option\n  * Raspberry Pi Configuration and raspi-config allow setting of fixed HDMI resolution\n  * raspi-config allows enabling of serial hardware independent of serial terminal\n  * Updates to kernel and firmware\n  * Various minor bug fixes and usability and appearance tweaks\n2017-01-11:\n  * Re-release of the 2016-11-25 image with a FAT32-formatted boot partition\n2016-11-25:\n  * SSH disabled by default; can be enabled by creating a file with name \"ssh\" in boot partition\n  * Prompt for password change at boot when SSH enabled with default password unchanged\n  * Adobe Flash Player included\n  * Updates to hardware video acceleration in Chromium browser\n  * Greeter now uses background image from last set in Appearance Settings rather than pi user\n  * Updated version of Scratch\n  * Rastrack option removed from raspi-config and Raspberry Pi Configuration\n  * Ability to disable graphical boot splash screen added to raspi-config and Raspberry Pi Configuration\n  * Appearance Settings dialog made tabbed to work better on small screens\n  * Raspberry Pi Configuration now requires current password to change password\n  * Various small bug fixes\n  * Updated firmware and kernel\n2016-09-23:\n  * New PIXEL desktop environment - new icon set, window design, desktop images, splash screen and greeter\n  * Chromium web browser included\n  * Infinality font rendering patches included\n  * RealVNC server and viewer included\n  * SenseHAT emulator included\n  * Rfkill entries added to Wifi and Bluetooth panel plugins\n  * Updates to various standard applications, including Scratch and NodeRED\n  * Various bug fixes, tweaks and translation updates\n  * Updated firmware and kernel (https://github.com/raspberrypi/firmware/commit/ad8608c08b122b2c228dba0ff5070d6e9519faf5)\n2016-05-27:\n  * Fixed crash of lxpanel when D-bus not accessible\n  * Fixed permissions for D-bus Bluetooth access\n  * Removed sudo from shutdown options\n  * Appearance of tooltips updated in theme\n  * Fixed ejecter plugin grabbing focus\n  * raspi-config command line and GUI apps tidied; unnecessary reboots removed\n  * More error detection in piclone; copying of volume names and IDs added\n  * Updated translation files\n2016-05-10:\n  * New version of Scratch, which no longer requires sudo\n  * New version of BlueJ\n  * New version of NodeRED\n  * New version of pypy\n  * pigpio included\n  * geany editor included\n  * SD Card Copier added (can be used to duplicate or back up the Pi)\n  * Bluetooth plugin added to taskbar\n  * Volume control on taskbar now compatible with Bluetooth devices\n  * New shutdown helper application\n  * Mouse double-click speed setting added to mouse and keyboard preference application\n  * Option to enable / disable 1-wire interface and remote access to pigpio added to Raspberry Pi config application\n  * File system automatically expanded on first boot\n  * Empty Wastebasket option added to right-click menu \n  * Ctrl-Alt-T can be used to open a terminal window\n  * Various small bug fixes and appearance tweaks \n  * Updated firmware and kernel (https://github.com/raspberrypi/firmware/commit/cc6d7bf8b4c03a2a660ff9fdf4083fc165620866)\n2016-03-18:\n  * updated firmware and kernel (https://github.com/raspberrypi/firmware/commit/951799bbcd795ddf27769d14acf4813fdcbe53dc)\n  * use serial0 in cmdline.txt\n  * wpa_supplicant.conf country default to GB (allows use of channels 12 and 13)\n2016-02-26:\n  * Support added for Pi 3, including Wifi and Bluetooth\n  * Option to set wifi country code added to raspi-config\n2016-02-09:\n  * dtb that uses mmc sdcard driver (fixes problems experienced with certain SD cards)\n2016-02-03:\n  * new version of Sonic Pi (2.9)\n  * new version of Scratch (15/1/16)\n  * new version of Node-Red (2.5)\n  * new version of Wolfram (10.3)\n  * optional experimental GL desktop driver (can be enabled using advanced options in command-line raspi-config)\n  * new version of Java (1.8.0_65)\n  * new version of WiringPi\n  * raspi-gpio included\n  * ping no longer requires sudo (except NOOBS installs)\n  * support for more USB audio devices in lxpanel\n  * bug fix for creation of new menus in Alacarte\n  * various changes to raspi-config and GUI to tidy up board support and fix bugs, and updated translations\n  * small tweaks to theme to support GL driver\n2015-11-21:\n  * Included IBM Node-RED IoT application\n  * Included graphical package manager\n  * Included accelerated pixman library\n  * Updated Epiphany browser to improve video compatibility\n  * Updated Scratch with performance improvements and bug fixes\n  * Updated Raspberry Pi configuration to allow boot to pause while\n    network is established\n  * Various minor bug fixes\n2015-09-25:\n  * Based on Debian Jessie\n  * Upgraded applications - Epiphany browser, Scratch and Sonic Pi\n  * Included applications - LibreOffice, Claws Mail, Greenfoot, BlueJ\n  * Included utilities - Alacarte menu editor, Lxkeymap, scrot, tree, pip\n  * New GUI-based Raspberry Pi Configuration application\n  * GPIO control now possible without need for sudo\n  * Web link to Magpi magazine included\n  * New taskbar plugin to eject mounted USB drives\n  * Default boot is now to GUI not desktop\n  * Look and feel now based on GTK+3 default theme\n  * Print screen key launches scrot to produce screenshot\n  * Common keyboards autodetected by GUI and drivers loaded accordingly\n  * Numerous small tweaks and bugfixes\n2015-05-05:\n  * Updated UI changes\n  * Updated firmware\n  * Install raspberrypi-net-mods\n  * Install avahi-daemon\n  * Add user pi to new i2c and spi groups\n  * Modified udev rules for i2c and spi devices\n2015-02-16:\n  * Newer firmware with various fixes\n  * New Sonic Pi release\n  * Pi2 compatible RPi.GPIO\n  * Updated Wolfram Mathematica\n2015-01-31:\n  * Support for Pi2\n  * Newer firmware\n  * New Sonic Pi release\n  * Updated Scratch\n  * New Wolfram Mathematica release\n  * Updated Epiphany\n2014-12-24:\n  * Fix regression with omission of python-pygame\n2014-12-22:\n  * New firmware with variosu fixes and improvements\n  * New UI configuration for lxde\n  * Various package updates\n  * python3-pygame preinstalled\n  * 'nuscratch', scratch running on the Cog StackVM\n  * Misc other changes\n2014-09-09:\n  * New firmware with various fixes and improvements\n  * Minecraft Pi pre-installed\n  * Sonic Pi upgraded to 2.0\n  * Include Epiphany browser work from Collabora\n  * Switch to Java 8 from Java 7\n  * Updated Mathematica\n  * Misc minor configuration changes\n2014-06-20:\n  * New firmware with various fixes, and kernel bugfix\n2014-06-02:\n  * Many, many firmware updates with major USB improvements\n  * pyserial installed by default\n  * picamera installed by default\n2014-01-07:\n  * Firmware updated\n  * Some space saved on the root filesystem\n2013-12-20:\n  * Firmware updated, includes V4L2 fixes\n  * Update omxplayer\n2013-12-18:\n  * Firmware updated and now using kernel 3.10. Many, many improvements\n  * fbturbo XOrg driver is now included and enabled by default. Thanks to \n    ssvb https://github.com/ssvb/xf86-video-fbturbo\n  * Update Scratch image with further bug fixes\n  * Include Wolfram Mathematica\n  * Update to PyPy 2.2\n  * Update omxplayer\n  * Include v4l-utils for use with experimental V4L2 Raspberry Pi camera driver\n  * Update squeak-vm to fix issues with loading JPEGs\n2013-09-25:\n  * Update Scratch image for further performance improvements\n  * Include Oracle JDK\n  * At least a 4GiB SD card is now required (see above)\n  * Include PyPy 2.1\n  * Include base piface packages\n  * Update raspi-config to include bugfix for inheriting language settings\n    from NOOBS\n2013-09-10:\n  * Updated to current top of tree firmware\n  * Update squeak-vm, including fastblit optimised for the Raspbery Pi \n  * Include Sonic Pi and a fixed jackd2 package\n  * Support boot to Scratch\n  * Inherit keyboard and language settings from NOOBS\n"
  },
  {
    "path": "export-noobs/prerun.sh",
    "content": "#!/bin/bash -e\n\nIMG_FILE=\"${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img\"\nNOOBS_DIR=\"${STAGE_WORK_DIR}/${IMG_DATE}-${IMG_NAME}${IMG_SUFFIX}\"\nunmount_image \"${IMG_FILE}\"\n\nmkdir -p \"${STAGE_WORK_DIR}\"\ncp \"${WORK_DIR}/export-image/${IMG_FILENAME}${IMG_SUFFIX}.img\" \"${STAGE_WORK_DIR}/\"\n\nrm -rf \"${NOOBS_DIR}\"\n\nPARTED_OUT=$(parted -sm \"${IMG_FILE}\" unit b print)\nBOOT_OFFSET=$(echo \"$PARTED_OUT\" | grep -e '^1:' | cut -d':' -f 2 | tr -d B)\nBOOT_LENGTH=$(echo \"$PARTED_OUT\" | grep -e '^1:' | cut -d':' -f 4 | tr -d B)\n\nROOT_OFFSET=$(echo \"$PARTED_OUT\" | grep -e '^2:' | cut -d':' -f 2 | tr -d B)\nROOT_LENGTH=$(echo \"$PARTED_OUT\" | grep -e '^2:' | cut -d':' -f 4 | tr -d B)\n\nBOOT_DEV=$(losetup --show -f -o \"${BOOT_OFFSET}\" --sizelimit \"${BOOT_LENGTH}\" \"${IMG_FILE}\")\nROOT_DEV=$(losetup --show -f -o \"${ROOT_OFFSET}\" --sizelimit \"${ROOT_LENGTH}\" \"${IMG_FILE}\")\necho \"/boot: offset $BOOT_OFFSET, length $BOOT_LENGTH\"\necho \"/:     offset $ROOT_OFFSET, length $ROOT_LENGTH\"\n\nmkdir -p \"${STAGE_WORK_DIR}/rootfs\"\nmkdir -p \"${NOOBS_DIR}\"\n\nmount \"$ROOT_DEV\" \"${STAGE_WORK_DIR}/rootfs\"\nmount \"$BOOT_DEV\" \"${STAGE_WORK_DIR}/rootfs/boot\"\n\nln -sv \"/lib/systemd/system/apply_noobs_os_config.service\" \"$ROOTFS_DIR/etc/systemd/system/multi-user.target.wants/apply_noobs_os_config.service\"\n\nbsdtar --numeric-owner --format gnutar -C \"${STAGE_WORK_DIR}/rootfs/boot\" -cpf - . | xz -T0 > \"${NOOBS_DIR}/boot.tar.xz\"\numount \"${STAGE_WORK_DIR}/rootfs/boot\"\nbsdtar --numeric-owner --format gnutar -C \"${STAGE_WORK_DIR}/rootfs\" --one-file-system -cpf - . | xz -T0 > \"${NOOBS_DIR}/root.tar.xz\"\n\nunmount_image \"${IMG_FILE}\"\n"
  },
  {
    "path": "scripts/common",
    "content": "log (){\n\tdate +\"[%T] $*\" | tee -a \"${LOG_FILE}\"\n}\nexport -f log\n\nbootstrap(){\n\tlocal BOOTSTRAP_CMD=debootstrap\n\tlocal BOOTSTRAP_ARGS=()\n\n\texport http_proxy=${APT_PROXY}\n\n\tif [ \"$(dpkg --print-architecture)\" !=  \"armhf\" ] && [ \"$(dpkg --print-architecture)\" !=  \"aarch64\" ]; then\n\t\tBOOTSTRAP_CMD=qemu-debootstrap\n\tfi\n\n\tBOOTSTRAP_ARGS+=(--arch armhf)\n\tBOOTSTRAP_ARGS+=(--components \"main,contrib,non-free\")\n\tBOOTSTRAP_ARGS+=(--keyring \"${STAGE_DIR}/files/raspberrypi.gpg\")\n\tBOOTSTRAP_ARGS+=(\"$@\")\n\n\tsetarch linux32 capsh --drop=cap_setfcap -- \"${BOOTSTRAP_CMD}\" \"${BOOTSTRAP_ARGS[@]}\" || true\n\n\tif [ -d \"$2/debootstrap\" ]; then\n\t\trmdir \"$2/debootstrap\"\n\tfi\n}\nexport -f bootstrap\n\ncopy_previous(){\n\tif [ ! -d \"${PREV_ROOTFS_DIR}\" ]; then\n\t\techo \"Previous stage rootfs not found\"\n\t\tfalse\n\tfi\n\tmkdir -p \"${ROOTFS_DIR}\"\n\trsync -aHAXx --exclude var/cache/apt/archives \"${PREV_ROOTFS_DIR}/\" \"${ROOTFS_DIR}/\"\n}\nexport -f copy_previous\n\nunmount(){\n\tif [ -z \"$1\" ]; then\n\t\tDIR=$PWD\n\telse\n\t\tDIR=$1\n\tfi\n\n\twhile mount | grep -q \"$DIR\"; do\n\t\tlocal LOCS\n\t\tLOCS=$(mount | grep \"$DIR\" | cut -f 3 -d ' ' | sort -r)\n\t\tfor loc in $LOCS; do\n\t\t\tumount \"$loc\"\n\t\tdone\n\tdone\n}\nexport -f unmount\n\nunmount_image(){\n\tsync\n\tsleep 1\n\tlocal LOOP_DEVICES\n\tLOOP_DEVICES=$(losetup --list | grep \"$(basename \"${1}\")\" | cut -f1 -d' ')\n\tfor LOOP_DEV in ${LOOP_DEVICES}; do\n\t\tif [ -n \"${LOOP_DEV}\" ]; then\n\t\t\tlocal MOUNTED_DIR\n\t\t\tMOUNTED_DIR=$(mount | grep \"$(basename \"${LOOP_DEV}\")\" | head -n 1 | cut -f 3 -d ' ')\n\t\t\tif [ -n \"${MOUNTED_DIR}\" ] && [ \"${MOUNTED_DIR}\" != \"/\" ]; then\n\t\t\t\tunmount \"$(dirname \"${MOUNTED_DIR}\")\"\n\t\t\tfi\n\t\t\tsleep 1\n\t\t\tlosetup -d \"${LOOP_DEV}\"\n\t\tfi\n\tdone\n}\nexport -f unmount_image\n\non_chroot() {\n\tif ! mount | grep -q \"$(realpath \"${ROOTFS_DIR}\"/proc)\"; then\n\t\tmount -t proc proc \"${ROOTFS_DIR}/proc\"\n\tfi\n\n\tif ! mount | grep -q \"$(realpath \"${ROOTFS_DIR}\"/dev)\"; then\n\t\tmount --bind /dev \"${ROOTFS_DIR}/dev\"\n\tfi\n\t\n\tif ! mount | grep -q \"$(realpath \"${ROOTFS_DIR}\"/dev/pts)\"; then\n\t\tmount --bind /dev/pts \"${ROOTFS_DIR}/dev/pts\"\n\tfi\n\n\tif ! mount | grep -q \"$(realpath \"${ROOTFS_DIR}\"/sys)\"; then\n\t\tmount --bind /sys \"${ROOTFS_DIR}/sys\"\n\tfi\n\n\tsetarch linux32 capsh --drop=cap_setfcap \"--chroot=${ROOTFS_DIR}/\" -- -e \"$@\"\n}\nexport -f on_chroot\n\nupdate_issue() {\n\tlocal GIT_HASH\n\tGIT_HASH=$(git rev-parse HEAD)\n\techo -e \"Raspberry Pi reference ${IMG_DATE}\\nGenerated using ${PI_GEN}, ${PI_GEN_REPO}, ${GIT_HASH}, ${1}\" > \"${ROOTFS_DIR}/etc/rpi-issue\"\n}\nexport -f update_issue\n\n"
  },
  {
    "path": "scripts/dependencies_check",
    "content": "# dependencies_check\n# $@\tDependency files to check\n#\n# Each dependency is in the form of a tool to test for, optionally followed by\n# a : and the name of a package if the package on a Debian-ish system is not\n# named for the tool (i.e., qemu-user-static).\ndependencies_check()\n{\n\tlocal depfile deps missing\n\n\tfor depfile in \"$@\"; do\n\t\tif [[ -e \"$depfile\" ]]; then\n\t\t\tdeps=\"$(sed -f \"${SCRIPT_DIR}/remove-comments.sed\" < \"${BASE_DIR}/depends\")\"\n\n\t\tfi\n\t\tfor dep in $deps; do\n\t\t\tif ! hash \"${dep%:*}\" 2>/dev/null; then\n\t\t\t\tmissing=\"${missing:+$missing }${dep#*:}\"\n\t\t\tfi\n\t\tdone\n\tdone\n\n\tif [[ \"$missing\" ]]; then\n\t\techo \"Required dependencies not installed\"\n\t\techo\n\t\techo \"This can be resolved on Debian/Raspbian systems by installing:\"\n\t\techo \"$missing\"\n\t\tfalse\n\tfi\n\n\n\tif ! grep -q \"/proc/sys/fs/binfmt_misc\" /proc/mounts; then\n\t\techo \"Module binfmt_misc not loaded in host\"\n\t\techo \"Please run:\"\n\t\techo \"  sudo modprobe binfmt_misc\"\n\t\texit 1\n\tfi\n}\n"
  },
  {
    "path": "scripts/remove-comments.sed",
    "content": "# Deletes comments and collapses whitespace in ##-packages files\n\n# Append (N)ext line to buffer\n# if (!)not ($)buffer is EOF, (b)ranch to (:)label loop\n:loop\nN\n$ !b loop\n\n# Buffer is \"line1\\nline2\\n...lineN\", del comments and collapse whitespace\ns/#[^\\n]*//g\ns/[[:space:]]\\{1,\\}/ /g\n"
  },
  {
    "path": "stage0/00-configure-apt/00-run.sh",
    "content": "#!/bin/bash -e\n\ninstall -m 644 files/sources.list \"${ROOTFS_DIR}/etc/apt/\"\ninstall -m 644 files/raspi.list \"${ROOTFS_DIR}/etc/apt/sources.list.d/\"\n\nif [ -n \"$APT_PROXY\" ]; then\n\tinstall -m 644 files/51cache \"${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache\"\n\tsed \"${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache\" -i -e \"s|APT_PROXY|${APT_PROXY}|\"\nelse\n\trm -f \"${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache\"\nfi\n\non_chroot apt-key add - < files/raspberrypi.gpg.key\non_chroot << EOF\napt-get update\napt-get dist-upgrade -y\nEOF\n"
  },
  {
    "path": "stage0/00-configure-apt/files/51cache",
    "content": "Acquire::http { Proxy \"APT_PROXY\"; };\n"
  },
  {
    "path": "stage0/00-configure-apt/files/raspberrypi.gpg.key",
    "content": "-----BEGIN PGP PUBLIC KEY BLOCK-----\nVersion: GnuPG v1.4.12 (GNU/Linux)\n\nmQENBE/d7o8BCACrwqQacGJfn3tnMzGui6mv2lLxYbsOuy/+U4rqMmGEuo3h9m92\n30E2EtypsoWczkBretzLUCFv+VUOxaA6sV9+puTqYGhhQZFuKUWcG7orf7QbZRuu\nTxsEUepW5lg7MExmAu1JJzqM0kMQX8fVyWVDkjchZ/is4q3BPOUCJbUJOsE+kK/6\n8kW6nWdhwSAjfDh06bA5wvoXNjYoDdnSZyVdcYCPEJXEg5jfF/+nmiFKMZBraHwn\neQsepr7rBXxNcEvDlSOPal11fg90KXpy7Umre1UcAZYJdQeWcHu7X5uoJx/MG5J8\nic6CwYmDaShIFa92f8qmFcna05+lppk76fsnABEBAAG0IFJhc3BiZXJyeSBQaSBB\ncmNoaXZlIFNpZ25pbmcgS2V5iQE4BBMBAgAiBQJP3e6PAhsDBgsJCAcDAgYVCAIJ\nCgsEFgIDAQIeAQIXgAAKCRCCsSmSf6MwPk6vB/9pePB3IukU9WC9Bammh3mpQTvL\nOifbkzHkmAYxzjfK6D2I8pT0xMxy949+ThzJ7uL60p6T/32ED9DR3LHIMXZvKtuc\nmQnSiNDX03E2p7lIP/htoxW2hDP2n8cdlNdt0M9IjaWBppsbO7IrDppG2B1aRLni\nuD7v8bHRL2mKTtIDLX42Enl8aLAkJYgNWpZyPkDyOqamjijarIWjGEPCkaURF7g4\nd44HvYhpbLMOrz1m6N5Bzoa5+nq3lmifeiWKxioFXU+Hy5bhtAM6ljVb59hbD2ra\nX4+3LXC9oox2flmQnyqwoyfZqVgSQa0B41qEQo8t1bz6Q1Ti7fbMLThmbRHiuQEN\nBE/d7o8BCADNlVtBZU63fm79SjHh5AEKFs0C3kwa0mOhp9oas/haDggmhiXdzeD3\n49JWz9ZTx+vlTq0s+I+nIR1a+q+GL+hxYt4HhxoA6vlDMegVfvZKzqTX9Nr2VqQa\nS4Kz3W5ULv81tw3WowK6i0L7pqDmvDqgm73mMbbxfHD0SyTt8+fk7qX6Ag2pZ4a9\nZdJGxvASkh0McGpbYJhk1WYD+eh4fqH3IaeJi6xtNoRdc5YXuzILnp+KaJyPE5CR\nqUY5JibOD3qR7zDjP0ueP93jLqmoKltCdN5+yYEExtSwz5lXniiYOJp8LWFCgv5h\nm8aYXkcJS1xVV9Ltno23YvX5edw9QY4hABEBAAGJAR8EGAECAAkFAk/d7o8CGwwA\nCgkQgrEpkn+jMD5Figf/dIC1qtDMTbu5IsI5uZPX63xydaExQNYf98cq5H2fWF6O\nyVR7ERzA2w33hI0yZQrqO6pU9SRnHRxCFvGv6y+mXXXMRcmjZG7GiD6tQWeN/3wb\nEbAn5cg6CJ/Lk/BI4iRRfBX07LbYULCohlGkwBOkRo10T+Ld4vCCnBftCh5x2OtZ\nTOWRULxP36y2PLGVNF+q9pho98qx+RIxvpofQM/842ZycjPJvzgVQsW4LT91KYAE\n4TVf6JjwUM6HZDoiNcX6d7zOhNfQihXTsniZZ6rky287htsWVDNkqOi5T3oTxWUo\nm++/7s3K3L0zWopdhMVcgg6Nt9gcjzqN1c0gy55L/g==\n=mNSj\n-----END PGP PUBLIC KEY BLOCK-----\n"
  },
  {
    "path": "stage0/00-configure-apt/files/raspi.list",
    "content": "deb http://archive.raspberrypi.org/debian/ buster main\n# Uncomment line below then 'apt-get update' to enable 'apt-get source'\n#deb-src http://archive.raspberrypi.org/debian/ buster main\n"
  },
  {
    "path": "stage0/00-configure-apt/files/sources.list",
    "content": "deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi\n# Uncomment line below then 'apt-get update' to enable 'apt-get source'\n#deb-src http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi\n"
  },
  {
    "path": "stage0/01-locale/00-debconf",
    "content": "# 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, 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\nlocales\tlocales/locales_to_be_generated\tmultiselect\ten_GB.UTF-8 UTF-8\n# Default locale for the system environment:\n# Choices: None, C.UTF-8, en_GB.UTF-8\nlocales\tlocales/default_environment_locale\tselect\ten_GB.UTF-8\n"
  },
  {
    "path": "stage0/01-locale/00-packages",
    "content": "locales\n"
  },
  {
    "path": "stage0/02-firmware/01-packages",
    "content": "raspberrypi-bootloader\nraspberrypi-kernel\n"
  },
  {
    "path": "stage0/prerun.sh",
    "content": "#!/bin/bash -e\n\nif [ ! -d \"${ROOTFS_DIR}\" ]; then\n\tbootstrap buster \"${ROOTFS_DIR}\" http://raspbian.raspberrypi.org/raspbian/\nfi\n"
  },
  {
    "path": "stage1/00-boot-files/00-run.sh",
    "content": "#!/bin/bash -e\n\ninstall -m 644 files/cmdline.txt \"${ROOTFS_DIR}/boot/\"\ninstall -m 644 files/config.txt \"${ROOTFS_DIR}/boot/\"\n"
  },
  {
    "path": "stage1/00-boot-files/files/cmdline.txt",
    "content": "dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait\n"
  },
  {
    "path": "stage1/00-boot-files/files/config.txt",
    "content": "# For more options and information see\n# http://rpf.io/configtxt\n# Some settings may impact device functionality. See link above for details\n\n# uncomment if you get no picture on HDMI for a default \"safe\" mode\n#hdmi_safe=1\n\n# uncomment this if your display has a black border of unused pixels visible\n# and your display can output without overscan\n#disable_overscan=1\n\n# uncomment the following to adjust overscan. Use positive numbers if console\n# goes off screen, and negative if there is too much border\n#overscan_left=16\n#overscan_right=16\n#overscan_top=16\n#overscan_bottom=16\n\n# uncomment to force a console size. By default it will be display's size minus\n# overscan.\n#framebuffer_width=1280\n#framebuffer_height=720\n\n# uncomment if hdmi display is not detected and composite is being output\n#hdmi_force_hotplug=1\n\n# uncomment to force a specific HDMI mode (this will force VGA)\n#hdmi_group=1\n#hdmi_mode=1\n\n# uncomment to force a HDMI mode rather than DVI. This can make audio work in\n# DMT (computer monitor) modes\n#hdmi_drive=2\n\n# uncomment to increase signal to HDMI, if you have interference, blanking, or\n# no display\n#config_hdmi_boost=4\n\n# uncomment for composite PAL\n#sdtv_mode=2\n\n#uncomment to overclock the arm. 700 MHz is the default.\n#arm_freq=800\n\n# Uncomment some or all of these to enable the optional hardware interfaces\n#dtparam=i2c_arm=on\n#dtparam=i2s=on\n#dtparam=spi=on\n\n# Uncomment this to enable the lirc-rpi module\n#dtoverlay=lirc-rpi\n\n# Additional overlays and parameters are documented /boot/overlays/README\n\n# Enable audio (loads snd_bcm2835)\ndtparam=audio=on\n\n[pi4]\n# Enable DRM VC4 V3D driver on top of the dispmanx display stack\ndtoverlay=vc4-fkms-v3d\nmax_framebuffers=2\n\n[all]\n#dtoverlay=vc4-fkms-v3d\n"
  },
  {
    "path": "stage1/01-sys-tweaks/00-patches/01-bashrc.diff",
    "content": "--- a/rootfs/etc/skel/.bashrc\n+++ b/rootfs/etc/skel/.bashrc\n@@ -43,7 +43,7 @@\n # uncomment for a colored prompt, if the terminal has the capability; turned\n # off by default to not distract the user: the focus in a terminal window\n # should be on the output of commands, not on the prompt\n-#force_color_prompt=yes\n+force_color_prompt=yes\n \n if [ -n \"$force_color_prompt\" ]; then\n     if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then\n@@ -57,7 +57,7 @@\n fi\n \n if [ \"$color_prompt\" = yes ]; then\n-    PS1='${debian_chroot:+($debian_chroot)}\\[\\033[01;32m\\]\\u@\\h\\[\\033[00m\\]:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$ '\n+    PS1='${debian_chroot:+($debian_chroot)}\\[\\033[01;32m\\]\\u@\\h\\[\\033[00m\\]:\\[\\033[01;34m\\]\\w \\$\\[\\033[00m\\] '\n else\n     PS1='${debian_chroot:+($debian_chroot)}\\u@\\h:\\w\\$ '\n fi\n@@ -79,9 +79,9 @@\n     #alias dir='dir --color=auto'\n     #alias vdir='vdir --color=auto'\n \n-    #alias grep='grep --color=auto'\n-    #alias fgrep='fgrep --color=auto'\n-    #alias egrep='egrep --color=auto'\n+    alias grep='grep --color=auto'\n+    alias fgrep='fgrep --color=auto'\n+    alias egrep='egrep --color=auto'\n fi\n \n # colored GCC warnings and errors\n"
  },
  {
    "path": "stage1/01-sys-tweaks/00-patches/series",
    "content": "01-bashrc.diff\n"
  },
  {
    "path": "stage1/01-sys-tweaks/00-run.sh",
    "content": "#!/bin/bash -e\n\ninstall -d \"${ROOTFS_DIR}/etc/systemd/system/getty@tty1.service.d\"\ninstall -m 644 files/noclear.conf \"${ROOTFS_DIR}/etc/systemd/system/getty@tty1.service.d/noclear.conf\"\ninstall -v -m 644 files/fstab \"${ROOTFS_DIR}/etc/fstab\"\n\non_chroot << EOF\nif ! id -u ${FIRST_USER_NAME} >/dev/null 2>&1; then\n\tadduser --disabled-password --gecos \"\" ${FIRST_USER_NAME}\nfi\necho \"${FIRST_USER_NAME}:${FIRST_USER_PASS}\" | chpasswd\necho \"root:root\" | chpasswd\nEOF\n\n\n"
  },
  {
    "path": "stage1/01-sys-tweaks/files/fstab",
    "content": "proc            /proc           proc    defaults          0       0\nBOOTDEV  /boot           vfat    defaults          0       2\nROOTDEV  /               ext4    defaults,noatime  0       1\n"
  },
  {
    "path": "stage1/01-sys-tweaks/files/noclear.conf",
    "content": "[Service]\nTTYVTDisallocate=no\n"
  },
  {
    "path": "stage1/02-net-tweaks/00-packages",
    "content": "netbase\n"
  },
  {
    "path": "stage1/02-net-tweaks/00-patches/01-hosts.diff",
    "content": "Index: jessie-stage1/rootfs/etc/hosts\n===================================================================\n--- jessie-stage1.orig/rootfs/etc/hosts\n+++ jessie-stage1/rootfs/etc/hosts\n@@ -3,3 +3,4 @@\n ff02::1\t\tip6-allnodes\n ff02::2\t\tip6-allrouters\n \n+127.0.1.1\traspberrypi\n"
  },
  {
    "path": "stage1/02-net-tweaks/00-patches/series",
    "content": "01-hosts.diff\n"
  },
  {
    "path": "stage1/02-net-tweaks/00-run.sh",
    "content": "#!/bin/bash -e\n\ninstall -m 644 files/hostname \"${ROOTFS_DIR}/etc/hostname\"\n\nln -sf /dev/null \"${ROOTFS_DIR}/etc/systemd/network/99-default.link\"\n"
  },
  {
    "path": "stage1/02-net-tweaks/files/hostname",
    "content": "raspberrypi\n"
  },
  {
    "path": "stage1/02-net-tweaks/files/interfaces",
    "content": "auto lo\n\niface lo inet loopback\niface eth0 inet dhcp\n"
  },
  {
    "path": "stage1/03-install-packages/00-packages",
    "content": "libraspberrypi-bin libraspberrypi0 raspi-config\n"
  },
  {
    "path": "stage1/prerun.sh",
    "content": "#!/bin/bash -e\n\nif [ ! -d \"${ROOTFS_DIR}\" ]; then\n\tcopy_previous\nfi\n"
  },
  {
    "path": "stage2/00-copies-and-fills/01-packages",
    "content": "raspi-copies-and-fills\n"
  },
  {
    "path": "stage2/00-copies-and-fills/02-run.sh",
    "content": "#!/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",
    "content": "# Encoding to use on the console:\n# 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\nconsole-setup   console-setup/charmap47 select  UTF-8\n# Character set to support:\n# 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\nconsole-setup   console-setup/codeset47 select  Guess optimal character set\n# Font for the console:\n# Choices: Fixed, Goha, GohaClassic, Terminus, TerminusBold, TerminusBoldVGA, VGA, Do not change the boot/kernel font, Let the system select a suitable font\nconsole-setup   console-setup/fontface47        select  Do not change the boot/kernel font\n# Key to function as AltGr:\n# 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\nkeyboard-configuration\tkeyboard-configuration/altgr\tselect\tThe default for the keyboard layout\n# Keyboard model:\n# 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\nkeyboard-configuration\tkeyboard-configuration/model\tselect\tGeneric 105-key (Intl) PC\n# Keymap to use:\n# 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\nkeyboard-configuration\tkeyboard-configuration/xkb-keymap\tselect\tgb\n# Compose key:\n# Choices: No compose key, Right Alt (AltGr), Right Control, Right Logo key, Menu key, Left Logo key, Caps Lock\nkeyboard-configuration\tkeyboard-configuration/compose\tselect\tNo compose key\n# Use Control+Alt+Backspace to terminate the X server?\nkeyboard-configuration\tkeyboard-configuration/ctrl_alt_bksp\tboolean\ttrue\n# Keyboard layout:\n# 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\nkeyboard-configuration  keyboard-configuration/variant  select  English (UK)\n"
  },
  {
    "path": "stage2/01-sys-tweaks/00-packages",
    "content": "ssh less fbset sudo psmisc strace ed ncdu crda\nconsole-setup keyboard-configuration debconf-utils parted unzip\nbuild-essential manpages-dev python bash-completion gdb pkg-config\npython-rpi.gpio v4l-utils\navahi-daemon\nlua5.1\nluajit\nhardlink ca-certificates curl\nfake-hwclock nfs-common usbutils\nlibraspberrypi-dev libraspberrypi-doc libfreetype6-dev\ndosfstools\ndphys-swapfile\nraspberrypi-sys-mods\npi-bluetooth\napt-listchanges\nusb-modeswitch\napt-transport-https\nlibpam-chksshpwd\nrpi-update\nlibmtp-runtime\nrsync\nhtop\nman-db\npolicykit-1\nssh-import-id\nrng-tools\nethtool\n"
  },
  {
    "path": "stage2/01-sys-tweaks/00-packages-nr",
    "content": "cifs-utils\n"
  },
  {
    "path": "stage2/01-sys-tweaks/00-patches/01-useradd.diff",
    "content": "Index: jessie-stage2/rootfs/etc/default/useradd\n===================================================================\n--- jessie-stage2.orig/rootfs/etc/default/useradd\n+++ jessie-stage2/rootfs/etc/default/useradd\n@@ -5,7 +5,7 @@\n # Similar to DHSELL in adduser. However, we use \"sh\" here because\n # useradd is a low level utility and should be as general\n # as possible\n-SHELL=/bin/sh\n+SHELL=/bin/bash\n #\n # The default group for users\n # 100=users on Debian systems\n@@ -29,7 +29,7 @@ SHELL=/bin/sh\n # The SKEL variable specifies the directory containing \"skeletal\" user\n # files; in other words, files such as a sample .profile that will be\n # copied to the new user's home directory when it is created.\n-# SKEL=/etc/skel\n+SKEL=/etc/skel\n #\n # Defines whether the mail spool should be created while\n # creating the account\n"
  },
  {
    "path": "stage2/01-sys-tweaks/00-patches/02-swap.diff",
    "content": "Index: jessie-stage2/rootfs/etc/dphys-swapfile\n===================================================================\n--- jessie-stage2.orig/rootfs/etc/dphys-swapfile\n+++ jessie-stage2/rootfs/etc/dphys-swapfile\n@@ -13,7 +13,7 @@\n \n # set size to absolute value, leaving empty (default) then uses computed value\n #   you most likely don't want this, unless you have an special disk situation\n-#CONF_SWAPSIZE=\n+CONF_SWAPSIZE=100\n \n # set size to computed value, this times RAM size, dynamically adapts,\n #   guarantees that there is enough swap without wasting disk space on excess\n"
  },
  {
    "path": "stage2/01-sys-tweaks/00-patches/04-inputrc.diff",
    "content": "Index: jessie-stage2/rootfs/etc/inputrc\n===================================================================\n--- jessie-stage2.orig/rootfs/etc/inputrc\n+++ jessie-stage2/rootfs/etc/inputrc\n@@ -65,3 +65,7 @@ $endif\n # \"\\e[F\": end-of-line\n \n $endif\n+\n+# mappings for up and down arrows search history\n+# \"\\e[B\": history-search-forward\n+# \"\\e[A\": history-search-backward\n"
  },
  {
    "path": "stage2/01-sys-tweaks/00-patches/05-path.diff",
    "content": "Index: jessie-stage2/rootfs/etc/login.defs\n===================================================================\n--- jessie-stage2.orig/rootfs/etc/login.defs\n+++ jessie-stage2/rootfs/etc/login.defs\n@@ -100,7 +100,7 @@ HUSHLOGIN_FILE\t.hushlogin\n #\n # (they are minimal, add the rest in the shell startup files)\n ENV_SUPATH\tPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\n-ENV_PATH\tPATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games\n+ENV_PATH        PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games\n \n #\n # Terminal permissions\nIndex: jessie-stage2/rootfs/etc/profile\n===================================================================\n--- jessie-stage2.orig/rootfs/etc/profile\n+++ jessie-stage2/rootfs/etc/profile\n@@ -4,7 +4,7 @@\n if [ \"`id -u`\" -eq 0 ]; then\n   PATH=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"\n else\n-  PATH=\"/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games\"\n+  PATH=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games\"\n fi\n export PATH\n \n"
  },
  {
    "path": "stage2/01-sys-tweaks/00-patches/07-resize-init.diff",
    "content": "--- a/rootfs/boot/cmdline.txt\n+++ b/rootfs/boot/cmdline.txt\n@@ -1 +1 @@\n-dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait\n+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\n"
  },
  {
    "path": "stage2/01-sys-tweaks/00-patches/series",
    "content": "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",
    "content": "#!/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/systemd/system/rc-local.service.d\"\ninstall -m 644 files/ttyoutput.conf\t\"${ROOTFS_DIR}/etc/systemd/system/rc-local.service.d/\"\n\ninstall -m 644 files/50raspi\t\t\"${ROOTFS_DIR}/etc/apt/apt.conf.d/\"\n\ninstall -m 644 files/console-setup   \t\"${ROOTFS_DIR}/etc/default/\"\n\ninstall -m 755 files/rc.local\t\t\"${ROOTFS_DIR}/etc/\"\n\non_chroot << EOF\nsystemctl disable hwclock.sh\nsystemctl disable nfs-common\nsystemctl disable rpcbind\nif [ \"${ENABLE_SSH}\" == \"1\" ]; then\n\tsystemctl enable ssh\nelse\n\tsystemctl disable ssh\nfi\nsystemctl enable regenerate_ssh_host_keys\nEOF\n\nif [ \"${USE_QEMU}\" = \"1\" ]; then\n\techo \"enter QEMU mode\"\n\tinstall -m 644 files/90-qemu.rules \"${ROOTFS_DIR}/etc/udev/rules.d/\"\n\ton_chroot << EOF\nsystemctl disable resize2fs_once\nEOF\n\techo \"leaving QEMU mode\"\nelse\n\ton_chroot << EOF\nsystemctl enable resize2fs_once\nEOF\nfi\n\non_chroot <<EOF\nfor GRP in input spi i2c gpio; do\n\tgroupadd -f -r \"\\$GRP\"\ndone\nfor GRP in adm dialout cdrom audio users sudo video games plugdev input gpio spi i2c netdev; do\n  adduser $FIRST_USER_NAME \\$GRP\ndone\nEOF\n\non_chroot << EOF\nsetupcon --force --save-only -v\nEOF\n\non_chroot << EOF\nusermod --pass='*' root\nEOF\n\nrm -f \"${ROOTFS_DIR}/etc/ssh/\"ssh_host_*_key*\n"
  },
  {
    "path": "stage2/01-sys-tweaks/files/50raspi",
    "content": "# never use pdiffs. Current implementation is very slow on low-powered devices\nAcquire::PDiffs \"0\";\n\n# download up to 5 pdiffs:\n#Acquire::PDiffs::FileLimit \"5\";\n"
  },
  {
    "path": "stage2/01-sys-tweaks/files/90-qemu.rules",
    "content": "KERNEL==\"sda\", SYMLINK+=\"mmcblk0\"\nKERNEL==\"sda?\", SYMLINK+=\"mmcblk0p%n\"\nKERNEL==\"sda2\", SYMLINK+=\"root\"\n"
  },
  {
    "path": "stage2/01-sys-tweaks/files/console-setup",
    "content": "# CONFIGURATION FILE FOR SETUPCON\n\n# Consult the console-setup(5) manual page.\n\nACTIVE_CONSOLES=\"/dev/tty[1-6]\"\n\nCHARMAP=\"UTF-8\"\n\nCODESET=\"guess\"\nFONTFACE=\"\"\nFONTSIZE=\"\"\n\nVIDEOMODE=\n\n# The following is an example how to use a braille font\n# FONT='lat9w-08.psf.gz brl-8x8.psf'\n"
  },
  {
    "path": "stage2/01-sys-tweaks/files/rc.local",
    "content": "#!/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 will \"exit 0\" on success or any other\n# value on error.\n#\n# In order to enable or disable this script just change the execution\n# bits.\n#\n# By default this script does nothing.\n\n# Print the IP address\n_IP=$(hostname -I) || true\nif [ \"$_IP\" ]; then\n  printf \"My IP address is %s\\n\" \"$_IP\"\nfi\n\nexit 0\n"
  },
  {
    "path": "stage2/01-sys-tweaks/files/resize2fs_once",
    "content": "#!/bin/sh\n### BEGIN INIT INFO\n# Provides:          resize2fs_once\n# Required-Start:\n# Required-Stop:\n# Default-Start: 3\n# Default-Stop:\n# Short-Description: Resize the root filesystem to fill partition\n# Description:\n### END INIT INFO\n. /lib/lsb/init-functions\ncase \"$1\" in\n  start)\n    log_daemon_msg \"Starting resize2fs_once\"\n    ROOT_DEV=$(findmnt / -o source -n) &&\n    resize2fs $ROOT_DEV &&\n    update-rc.d resize2fs_once remove &&\n    rm /etc/init.d/resize2fs_once &&\n    log_end_msg $?\n    ;;\n  *)\n    echo \"Usage: $0 start\" >&2\n    exit 3\n    ;;\nesac\n"
  },
  {
    "path": "stage2/01-sys-tweaks/files/ttyoutput.conf",
    "content": "[Service]\nStandardOutput=tty\n"
  },
  {
    "path": "stage2/02-net-tweaks/00-packages",
    "content": "wpasupplicant wireless-tools firmware-atheros firmware-brcm80211 firmware-libertas firmware-misc-nonfree firmware-realtek\nraspberrypi-net-mods\ndhcpcd5\nnet-tools\n"
  },
  {
    "path": "stage2/02-net-tweaks/01-run.sh",
    "content": "#!/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\t\"${ROOTFS_DIR}/etc/systemd/system/dhcpcd.service.d/\"\n\ninstall -v -d\t\t\t\t\t\"${ROOTFS_DIR}/etc/wpa_supplicant\"\ninstall -v -m 600 files/wpa_supplicant.conf\t\"${ROOTFS_DIR}/etc/wpa_supplicant/\"\n\nif [ -v WPA_COUNTRY ]; then\n\techo \"country=${WPA_COUNTRY}\" >> \"${ROOTFS_DIR}/etc/wpa_supplicant/wpa_supplicant.conf\"\nfi\n\nif [ -v WPA_ESSID ] && [ -v WPA_PASSWORD ]; then\non_chroot <<EOF\nwpa_passphrase \"${WPA_ESSID}\" \"${WPA_PASSWORD}\" >> \"/etc/wpa_supplicant/wpa_supplicant.conf\"\nEOF\nfi\n\n# Disable wifi on 5GHz models\nmkdir -p \"${ROOTFS_DIR}/var/lib/systemd/rfkill/\"\necho 1 > \"${ROOTFS_DIR}/var/lib/systemd/rfkill/platform-3f300000.mmc:wlan\"\necho 1 > \"${ROOTFS_DIR}/var/lib/systemd/rfkill/platform-fe300000.mmc:wlan\"\n"
  },
  {
    "path": "stage2/02-net-tweaks/files/wait.conf",
    "content": "[Service]\nExecStart=\nExecStart=/usr/lib/dhcpcd5/dhcpcd -q -w\n"
  },
  {
    "path": "stage2/02-net-tweaks/files/wpa_supplicant.conf",
    "content": "ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev\nupdate_config=1\n"
  },
  {
    "path": "stage2/03-accept-mathematica-eula/00-debconf",
    "content": "# Do you accept the Wolfram - Raspberry Pi® Bundle License Agreement?\nwolfram-engine  shared/accepted-wolfram-eula    boolean true\n"
  },
  {
    "path": "stage2/03-set-timezone/02-run.sh",
    "content": "#!/bin/bash -e\n\necho \"Europe/London\" > \"${ROOTFS_DIR}/etc/timezone\"\nrm \"${ROOTFS_DIR}/etc/localtime\"\n\non_chroot << EOF\ndpkg-reconfigure -f noninteractive tzdata\nEOF\n"
  },
  {
    "path": "stage2/04-ethereum/00-packages",
    "content": "vim screen jq dirmngr\n"
  },
  {
    "path": "stage2/04-ethereum/01-run.sh",
    "content": "#!/bin/bash -e\n\ninstall -m 644 files/ethonarm.list\t\t\t    ${ROOTFS_DIR}/etc/apt/sources.list.d/ \ninstall -m 755 files/init_resize.sh\t\t\t    ${ROOTFS_DIR}/usr/lib/raspi-config\t\ninstall -m 644 files/dphys-swapfile\t\t\t    ${ROOTFS_DIR}/etc/\ninstall -m 644 files/zram-default/armbian-zram-config\t    ${ROOTFS_DIR}/etc/default\ninstall -D -m 755 files/zram-lib/armbian-zram-config\t    ${ROOTFS_DIR}/usr/lib/armbian/armbian-zram-config\ninstall -m 644 files/armbian-ramlog\t\t\t    ${ROOTFS_DIR}/etc/default\ninstall -m 644 files/armbian-zram-config.service\t    ${ROOTFS_DIR}/etc/systemd/system/\n\ncat <<EOF >> ${ROOTFS_DIR}/etc/bash.bashrc\nalias update-ethereum='\nsudo apt-get update\nsudo apt-get install geth nethermind swarm ipfs parity raiden status.im-node vipnode'\nEOF\n\non_chroot <<EOF\n# Add EthRaspbian APT key\napt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8A584409D327B0A5\n# Install Ethereum packages\napt-get update && apt-get install geth\napt-get install swarm parity nethermind ipfs raiden status.im-node vipnode\n# Force password change on Ethereum account\n#chage -d 0 ethereum\n# enable zram-service\nsystemctl enable armbian-zram-config\nEOF\n\n"
  },
  {
    "path": "stage2/04-ethereum/files/armbian-ramlog",
    "content": "# configuration values for the armbian-ram-logging service\n#\n# enable the armbian-ram-logging service?\nENABLED=true\n#\n# size of the tmpfs mount -- please keep in mind to adjust /etc/default/armbian-zram-config too when increasing\nSIZE=50M\n#\n# use rsync instead of cp -r\n# requires rsync installed, may provide better performance\n# due to copying only new and changed files\nUSE_RSYNC=true\n"
  },
  {
    "path": "stage2/04-ethereum/files/armbian-zram-config.service",
    "content": "# Armbian ZRAM configuration service\n# Create 1 + number of cores compressed block devices\n# This service may block the boot process for up to 30 sec\n[Unit]\nDescription=Armbian ZRAM config\nDefaultDependencies=no\nAfter=local-fs.target\nBefore=armbian-ramlog.target\nConflicts=shutdown.target\n[Service]\nType=oneshot\nExecStart=/usr/lib/armbian/armbian-zram-config start\nExecStop=/usr/lib/armbian/armbian-zram-config stop\nRemainAfterExit=yes\nTimeoutStartSec=30sec\n[Install]\nWantedBy=sysinit.target\n"
  },
  {
    "path": "stage2/04-ethereum/files/dphys-swapfile",
    "content": "# /etc/dphys-swapfile - user settings for dphys-swapfile package\n# author Neil Franklin, last modification 2010.05.05\n# copyright ETH Zuerich Physics Departement\n#   use under either modified/non-advertising BSD or GPL license\n\n# this file is sourced with . so full normal sh syntax applies\n\n# the default settings are added as commented out CONF_*=* lines\n\n\n# where we want the swapfile to be, this is the default\n#CONF_SWAPFILE=/var/swap\n\n# set size to absolute value, leaving empty (default) then uses computed value\n#   you most likely don't want this, unless you have an special disk situation\nCONF_MAXSWAP=6144\nCONF_SWAPSIZE=6144\nCONF_SWAPFILE=/home/ethereum/swapfile\n# set size to computed value, this times RAM size, dynamically adapts,\n#   guarantees that there is enough swap without wasting disk space on excess\n#CONF_SWAPFACTOR=2\n\n# restrict size (computed and absolute!) to maximally this limit\n#   can be set to empty for no limit, but beware of filled partitions!\n#   this is/was a (outdated?) 32bit kernel limit (in MBytes), do not overrun it\n#   but is also sensible on 64bit to prevent filling /var or even / partition\n#CONF_MAXSWAP=2048\n"
  },
  {
    "path": "stage2/04-ethereum/files/ethonarm-rpi4-ubuntu64bit-install.sh",
    "content": "#!/bin/bash\n#\n# Copyright (c) Ethereum on ARM\n#\n# This file is licensed under the terms of the GNU General Public\n# License version 2. This program is licensed \"as is\" without any\n# warranty of any kind, whether express or implied.\n#\n# https://github.com/diglos/pi-gen\n#\n# This script turns James Chambers Ubuntu 64bit image for Raspberry Pi 4 into a full Ethereum node\n# You need to install a Raspbian image and run the script \"ethonarm-rpi4-ubuntu64bit-setup.sh\" before running this script\n#\n# More information about the image here:\n#\n# https://jamesachambers.com/raspberry-pi-4-ubuntu-server-desktop-18-04-3-image-unofficial/\n# https://github.com/TheRemote/Ubuntu-Server-raspi4-unofficial\n#\n\n# Modify hostname (ethnode-$MAC-HASH-CHUNK)\necho Changing hostname\nMAC_HASH=`cat /sys/class/net/eth0/address | sha256sum | awk '{print substr($0,0,9)}'`\necho ethnode-$MAC_HASH > /etc/hostname\nsed -i \"s/127.0.1.1.*/127.0.1.1\\tethnode-$MAC_HASH/g\" /etc/hosts\n\n# Mount /home and add entry to fstab\necho Mounting /home\nmount /dev/sda1 /home\necho '/dev/sda1 /home ext4 defaults 0 2' >> /etc/fstab\n\n# Create Ethereum account\necho \"Creating ethereum  user\"\nif ! id -u ethereum >/dev/null 2>&1; then\n        adduser --disabled-password --gecos \"\" ethereum\nfi\n\necho \"ethereum:ethereum\" | chpasswd\nfor GRP in sudo netdev audio video dialout plugdev bluetooth; do\n\tadduser ethereum $GRP\ndone\n\n# Force password change on first login for security reasons\nchage -d 0 ethereum\n\n\n# Create some swap memory in the USB device for avoiding memory issues.\necho \"Creating swap memory and activating Zram\"\nif stat  /dev/sda > /dev/null 2>&1;\nthen\n\tmkdir -p /home/ethereum/swap\n\tdd if=/dev/zero of=/home/ethereum/swap/swapfile bs=16k count=256k\n\tchmod 600 /home/ethereum/swap/swapfile\n\tmkswap /home/ethereum/swap/swapfile\n\tswapon /home/ethereum/swap/swapfile\n\techo \"/home/ethereum/swap/swapfile none swap sw 0 0\" >> /etc/fstab\nelse\n\techo no swap created\nfi\n\nmkdir -p /usr/lib/armbian\n# Enable Zram (based on ARMBIAN script)\ncat << EOF | tee /etc/default/armbian-zram-config >/dev/null\n# configuration values for the armbian-zram-config service\n#\n# enable the armbian-zram-config service\nENABLED=true\nZRAM_PERCENTAGE=25\nEOF\n\n# Enable Zram (ARMBIAN script)\ncat << 'EOF' | tee /usr/lib/armbian/armbian-zram-config >/dev/null\n#!/bin/bash\n#\n# Copyright (c) Authors: http://www.armbian.com/authors\n#\n# This file is licensed under the terms of the GNU General Public\n# License version 2. This program is licensed \"as is\" without any\n# warranty of any kind, whether express or implied.\n\n# Functions:\n#\n# activate_zram_swap\n# activate_ramlog_partition\n# activate_compressed_tmp\n\n\n# Read in basic OS image information\n#. /etc/armbian-release\n# and script configuration\n#. /usr/lib/armbian/armbian-common\n\n# It's possible to override ZRAM_PERCENTAGE, ZRAM_MAX_DEVICES, SWAP_ALGORITHM,\n# RAMLOG_ALGORITHM and TMP_ALGORITHM here:\n[ -f /etc/default/armbian-zram-config ] && . /etc/default/armbian-zram-config\n\nactivate_zram_swap() {\n\t# Do not interfere with already present config-zram package\n\tdpkg -l | grep -q 'zram-config' && exit 0\n\n\t[[ \"$ENABLED\" != \"true\" ]] && exit 0\n\n\t# Load zram module with n instances for swap: one per CPU core, $ZRAM_MAX_DEVICES\n\t# defines the maximum, on modern kernels we overwrite this with 1 and rely on\n\t# max_comp_streams being set to count of CPU cores or $ZRAM_MAX_DEVICES\n\tuname -r | grep -q '^3.' && zram_max_devs=${ZRAM_MAX_DEVICES:=4} || zram_max_devs=1\n\tcpu_cores=$(grep -c '^processor' /proc/cpuinfo | sed 's/^0$/1/')\n\t[[ ${cpu_cores} -gt ${zram_max_devs} ]] && zram_devices=${zram_max_devs} || zram_devices=${cpu_cores}\n\tmodule_args=\"$(modinfo zram | awk -F\" \" '/num_devices/ {print $2}' | cut -f1 -d:)\"\n\t[[ -n ${module_args} ]] && modprobe zram ${module_args}=$(( ${zram_devices} + 2 )) || return\n\n\t# Expose 50% of real memory as swap space by default\n\tzram_percent=${ZRAM_PERCENTAGE:=50}\n\tmem_info=$(LC_ALL=C free -w 2>/dev/null | grep \"^Mem\" || LC_ALL=C free | grep \"^Mem\")\n\tmemory_total=$(awk '{printf(\"%d\",$2*1024)}' <<<${mem_info})\n\tmem_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${zram_percent} / 100 ))\n\n\t# Limit memory available to zram to 50% by default\n\tmem_limit_percent=${MEM_LIMIT_PERCENTAGE:=50}\n\tmem_limit_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${mem_limit_percent} / 100 ))\n\n\tswap_algo=${SWAP_ALGORITHM:=lzo}\n\tfor (( i=1; i<=zram_devices; i++ )); do\n\t\t[[ -f /sys/block/zram${i}/comp_algorithm ]] && echo ${swap_algo} >/sys/block/zram${i}/comp_algorithm 2>/dev/null\n\t\tif [ \"X${ZRAM_BACKING_DEV}\" != \"X\" ]; then\n\t\t\techo ${ZRAM_BACKING_DEV} >/sys/block/zram${i}/backing_dev\n\t\tfi\n\t\techo -n ${ZRAM_MAX_DEVICES:=4} > /sys/block/zram${i}/max_comp_streams\n\t\techo -n ${mem_per_zram_device} > /sys/block/zram${i}/disksize\n\t\techo -n ${mem_limit_per_zram_device} > /sys/block/zram${i}/mem_limit\n\t\tmkswap /dev/zram${i}\n\t\tswapon -p 5 /dev/zram${i}\n\tdone\n\n\t# Swapping to HDDs is stupid so switch to settings made for flash memory and zram/zswap\n\techo 0 > /proc/sys/vm/page-cluster\n\n\techo -e \"\\n### Activated ${zram_devices} ${swap_algo} zram swap devices with $(( ${mem_per_zram_device} / 1048576 )) MB each\\n\" >>${Log}\n} # activate_zram_swap\n\nactivate_ramlog_partition() {\n\t# /dev/zram0 will be used as a compressed /var/log partition in RAM if\n\t# ENABLED=true in /etc/default/armbian-ramlog is set\n\tENABLED=$(awk -F\"=\" '/^ENABLED/ {print $2}' /etc/default/armbian-ramlog)\n\t[[ \"$ENABLED\" != \"true\" ]] && return\n\t\n\t# read size also from /etc/default/armbian-ramlog\n\tramlogsize=$(awk -F\"=\" '/^SIZE/ {print $2}' /etc/default/armbian-ramlog)\n\tdisksize=$(sed -e 's/M$/*1048576/' -e 's/K$/*1024/' <<<${ramlogsize:=50M} | bc)\n\n\t# choose RAMLOG_ALGORITHM if defined in /etc/default/armbian-zram-config\n\t# otherwise try to choose most efficient compression scheme available.\n\t# See https://patchwork.kernel.org/patch/9918897/\n\tif [ \"X${RAMLOG_ALGORITHM}\" = \"X\" ]; then\n\t\tfor algo in lz4 lz4hc quicklz zlib brotli zstd ; do\n\t\t\techo ${algo} >/sys/block/zram0/comp_algorithm 2>/dev/null\n\t\tdone\n\telse\n\t\techo ${RAMLOG_ALGORITHM} >/sys/block/zram0/comp_algorithm 2>/dev/null\n\tfi\n\techo -n ${disksize} > /sys/block/zram0/disksize\n\n\t# if it fails, select $swap_algo. Workaround for some older kernels\n\tif [[ $? == 1 ]]; then\n\t\techo ${swap_algo} > /sys/block/zram0/comp_algorithm 2>/dev/null\n\t\techo -n ${disksize} > /sys/block/zram0/disksize\n\tfi\n\n\tmkfs.ext4 -O ^has_journal -s 1024 -L log2ram /dev/zram0\n\talgo=$(sed 's/.*\\[\\([^]]*\\)\\].*/\\1/g' </sys/block/zram0/comp_algorithm)\n\techo -e \"### Activated Armbian ramlog partition with ${algo} compression\" >>${Log}\n} # activate_ramlog_partition\n\nactivate_compressed_tmp() {\n\t# create /tmp not as tmpfs but zram compressed if no fstab entry exists\n\tgrep -q '^tmpfs /tmp' /etc/mtab && return\n\n\ttmp_device=$(( ${zram_devices} + 1 ))\n\tif [[ -f /sys/block/zram${tmp_device}/comp_algorithm ]]; then\n\t\tif [ \"X${TMP_ALGORITHM}\" = \"X\" ]; then\n\t\t\techo ${swap_algo} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null\n\t\telse\n\t\t\techo ${TMP_ALGORITHM} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null\n\t\tfi\n\tfi\n\techo -n $(( ${memory_total} / 2 )) > /sys/block/zram${tmp_device}/disksize\n\tmkfs.ext4 -O ^has_journal -s 1024 -L tmp /dev/zram${tmp_device}\n\tmount -o nosuid,discard /dev/zram${tmp_device} /tmp\n\tchmod 777 /tmp\n\talgo=$(sed 's/.*\\[\\([^]]*\\)\\].*/\\1/g' </sys/block/zram${tmp_device}/comp_algorithm)\n} # activate_compressed_tmp\n\ncase $1 in\n\t*start*)\n\t\tactivate_zram_swap\n\t\tactivate_ramlog_partition\n\t\tactivate_compressed_tmp\n\t\t;;\nesac\nEOF\n\ncat << 'EOF' | tee /etc/systemd/system/armbian-zram-config.service >/dev/null\n# Armbian ZRAM configuration service\n# Create 1 + number of cores compressed block devices\n# This service may block the boot process for up to 30 sec\n\n[Unit]\nDescription=Armbian ZRAM config\nDefaultDependencies=no\nAfter=local-fs.target\nBefore=armbian-ramlog.target\nConflicts=shutdown.target\n\n[Service]\nType=oneshot\nExecStart=/usr/lib/armbian/armbian-zram-config start\nExecStop=/usr/lib/armbian/armbian-zram-config stop\nRemainAfterExit=yes\nTimeoutStartSec=30sec\n\n[Install]\nWantedBy=sysinit.target\nEOF\n\ncat << 'EOF' | tee /etc/default/armbian-ramlog >/dev/null\n# configuration values for the armbian-ram-logging service\n#\n# enable the armbian-ram-logging service?\nENABLED=true\n#\n# size of the tmpfs mount -- please keep in mind to adjust /etc/default/armbian-zram-config too when increasing\nSIZE=50M\n#\n# use rsync instead of cp -r\n# requires rsync installed, may provide better performance\n# due to copying only new and changed files\nUSE_RSYNC=true\nEOF\n\nchmod +x /usr/lib/armbian/armbian-zram-config\nsystemctl enable armbian-zram-config\n\n# Swap and Zram tweaks\n# Page allocation error workout\necho \"vm.min_free_kbytes=65536\" >> /etc/sysctl.conf\n# Modify swappiness parameter\necho \"vm.swappiness=100\" >> /etc/sysctl.conf\n\n# Ethereum software installation\n# Add APT EthRaspbian repository\necho \"Adding Ethereum repositories\"\napt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8A584409D327B0A5\nadd-apt-repository -n \"deb http://apt.ethraspbian.com bionic main\"\nadd-apt-repository -n \"deb http://apt.ethraspbian.com bionic-security main\"\nadd-apt-repository \"deb http://apt.ethraspbian.com bionic-upgrades main\"\n\n# Install Ethereum packages\necho Installing Ethereum packages\napt-get install geth\napt-get install parity swarm parity ipfs raiden status.im-node vipnode prysm-beacon prysm-validator lighthouse\n\n# Set Geth cache to 512\necho 'ARGS=\"--lightserv 25 --lightpeers 25 --maxpeers 128 --cache 512\"' > /etc/ethereum/geth.conf\n\necho \"Done. Please, reboot the systems for changes to take effect\"\n\nexit 0\n"
  },
  {
    "path": "stage2/04-ethereum/files/ethonarm-rpi4-ubuntu64bit-setup.sh",
    "content": "#!/bin/bash\n#\n# Copyright (c) Ethereum on ARM\n#\n# This file is licensed under the terms of the GNU General Public\n# License version 2. This program is licensed \"as is\" without any\n# warranty of any kind, whether express or implied.\n#\n# https://github.com/diglos/pi-gen\n\n# Update kernel and firmware\napt-get update && apt-get dist-upgrade -y\nrpi-update <<EOF\ny\nEOF\nrpi-eeprom-update -a\n\n# Format USB SSD and mount it as /home\necho Formatting USB disk. Please be patient\nif stat  /dev/sda > /dev/null 2>&1;\nthen\n        echo Formatting USB Drive...\n        fdisk /dev/sda <<EOF\nd\nn\np\n1\n\n\nw\nEOF\nmkfs.ext4 -F /dev/sda1\nelse\n        echo no SDD detected\nfi\n\necho Done!, please flash James Chambers Ubuntu server image on this MicroSD card\n\nexit 0\n"
  },
  {
    "path": "stage2/04-ethereum/files/ethonarm.list",
    "content": "deb http://apt.ethraspbian.com buster main\ndeb http://apt.ethraspbian.com buster-security main\ndeb http://apt.ethraspbian.com buster-upgrades main\n"
  },
  {
    "path": "stage2/04-ethereum/files/grafana/prometheus",
    "content": "# Set the command-line arguments to pass to the server.\nARGS=\"--storage.tsdb.path=\"/home/prometheus/metrics2/\"\"\n\n# Prometheus supports the following options:\n#  --config.file=\"/etc/prometheus/prometheus.yml\"\n#                             Prometheus configuration file path.\n#  --web.listen-address=\"0.0.0.0:9090\"\n#                             Address to listen on for UI, API, and telemetry.\n#  --web.read-timeout=5m      Maximum duration before timing out read of the\n#                             request, and closing idle connections.\n#  --web.max-connections=512  Maximum number of simultaneous connections.\n#  --web.external-url=<URL>   The URL under which Prometheus is externally\n#                             reachable (for example, if Prometheus is served\n#                             via a reverse proxy). Used for generating\n#                             relative and absolute links back to Prometheus\n#                             itself. If the URL has a path portion, it will\n#                             be used to prefix all HTTP endpoints served by\n#                             Prometheus. If omitted, relevant URL components\n#                             will be derived automatically.\n#  --web.route-prefix=<path>  Prefix for the internal routes of web endpoints.\n#                             Defaults to path of --web.external-url.\n#  --web.local-assets=\"/usr/share/prometheus/web/\"\n#                             Path to static asset/templates directory.\n#  --web.user-assets=<path>   Path to static asset directory, available at\n#                             /user.\n#  --web.enable-lifecycle     Enable shutdown and reload via HTTP request.\n#  --web.enable-admin-api     Enables API endpoints for admin control actions.\n#  --web.console.templates=\"/etc/prometheus/consoles\"\n#                             Path to the console template directory,\n#                             available at /consoles.\n#  --web.console.libraries=\"/etc/prometheus/console_libraries\"\n#                             Path to the console library directory.\n#   --storage.tsdb.path=\"/home/prometheus/metrics2/\"\n#                             Base path for metrics storage.\n#  --storage.tsdb.min-block-duration=2h\n#                             Minimum duration of a data block before being\n#                             persisted.\n#  --storage.tsdb.max-block-duration=<duration>\n#                             Maximum duration compacted blocks may span.\n#                             (Defaults to 10% of the retention period)\n#  --storage.tsdb.retention=15d\n#                             How long to retain samples in the storage.\n#  --storage.tsdb.use-lockfile\n#                             Create a lockfile in data directory.\n#  --alertmanager.notification-queue-capacity=10000\n#                             The capacity of the queue for pending alert\n#                             manager notifications.\n#  --alertmanager.timeout=10s\n#                             Timeout for sending alerts to Alertmanager.\n#  --query.lookback-delta=5m  The delta difference allowed for retrieving\n#                             metrics during expression evaluations.\n#  --query.timeout=2m         Maximum time a query may take before being\n#                             aborted.\n#  --query.max-concurrency=20\n#                             Maximum number of queries executed concurrently.\n#  --log.level=info           Only log messages with the given severity or\n#                             above. One of: [debug, info, warn, error]\n"
  },
  {
    "path": "stage2/04-ethereum/files/grafana/prometheus-node-exporter",
    "content": "# Set the command-line arguments to pass to the server.\n# Due to shell scaping, to pass backslashes for regexes, you need to double\n# them (\\\\d for \\d). If running under systemd, you need to double them again\n# (\\\\\\\\d to mean \\d), and escape newlines too.\nARGS=\"--collector.textfile.directory=\"/home/prometheus/node-exporter\"\n\n# Prometheus-node-exporter supports the following options:\n#\n#  --collector.diskstats.ignored-devices=\"^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\\\\d+n\\\\d+p)\\\\d+$\"\n#                            Regexp of devices to ignore for diskstats.\n#  --collector.filesystem.ignored-mount-points=\"^/(dev|proc|run|sys|mnt|media|var/lib/docker)($|/)\"\n#                            Regexp of mount points to ignore for filesystem\n#                            collector.\n#  --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)$\"\n#                            Regexp of filesystem types to ignore for\n#                            filesystem collector.\n#  --collector.netdev.ignored-devices=\"^lo$\"\n#                            Regexp of net devices to ignore for netdev\n#                            collector.\n#  --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))$\"\n#                            Regexp of fields to return for netstat\n#                            collector.\n#  --collector.ntp.server=\"127.0.0.1\"\n#                            NTP server to use for ntp collector\n#  --collector.ntp.protocol-version=4\n#                            NTP protocol version\n#  --collector.ntp.server-is-local\n#                            Certify that collector.ntp.server address is the\n#                            same local host as this collector.\n#  --collector.ntp.ip-ttl=1  IP TTL to use while sending NTP query\n#  --collector.ntp.max-distance=3.46608s\n#                            Max accumulated distance to the root\n#  --collector.ntp.local-offset-tolerance=1ms\n#                            Offset between local clock and local ntpd time\n#                            to tolerate\n#  --path.procfs=\"/proc\"     procfs mountpoint.\n#  --path.sysfs=\"/sys\"       sysfs mountpoint.\n#  --collector.qdisc.fixtures=\"\"\n#                            test fixtures to use for qdisc collector\n#                            end-to-end testing\n#  --collector.runit.servicedir=\"/etc/service\"\n#                            Path to runit service directory.\n#  --collector.supervisord.url=\"http://localhost:9001/RPC2\"\n#                            XML RPC endpoint.\n#  --collector.systemd.unit-whitelist=\".+\"\n#                            Regexp of systemd units to whitelist. Units must\n#                            both match whitelist and not match blacklist to\n#                            be included.\n#  --collector.systemd.unit-blacklist=\".+(\\\\.device|\\\\.scope|\\\\.slice|\\\\.target)\"\n#                            Regexp of systemd units to blacklist. Units must\n#                            both match whitelist and not match blacklist to\n#                            be included.\n#  --collector.systemd.private\n#                            Establish a private, direct connection to\n#                            systemd without dbus.\n# --collector.textfile.directory=\"/home/prometheus/node-exporter\"\n#                            Directory to read text files with metrics from.\n#  --collector.vmstat.fields=\"^(oom_kill|pgpg|pswp|pg.*fault).*\"\n#                            Regexp of fields to return for vmstat collector.\n#  --collector.wifi.fixtures=\"\"\n#                            test fixtures to use for wifi collector metrics\n#  --collector.arp           Enable the arp collector (default: enabled).\n#  --collector.bcache        Enable the bcache collector (default: enabled).\n#  --collector.bonding       Enable the bonding collector (default: enabled).\n#  --collector.buddyinfo     Enable the buddyinfo collector (default:\n#                            disabled).\n#  --collector.conntrack     Enable the conntrack collector (default:\n#                            enabled).\n#  --collector.cpu           Enable the cpu collector (default: enabled).\n#  --collector.diskstats     Enable the diskstats collector (default:\n#                            enabled).\n#  --collector.drbd          Enable the drbd collector (default: disabled).\n#  --collector.edac          Enable the edac collector (default: enabled).\n#  --collector.entropy       Enable the entropy collector (default: enabled).\n#  --collector.filefd        Enable the filefd collector (default: enabled).\n#  --collector.filesystem    Enable the filesystem collector (default:\n#                            enabled).\n#  --collector.hwmon         Enable the hwmon collector (default: enabled).\n#  --collector.infiniband    Enable the infiniband collector (default:\n#                            enabled).\n#  --collector.interrupts    Enable the interrupts collector (default:\n#                            disabled).\n#  --collector.ipvs          Enable the ipvs collector (default: enabled).\n#  --collector.ksmd          Enable the ksmd collector (default: disabled).\n#  --collector.loadavg       Enable the loadavg collector (default: enabled).\n#  --collector.logind        Enable the logind collector (default: disabled).\n#  --collector.mdadm         Enable the mdadm collector (default: enabled).\n#  --collector.meminfo       Enable the meminfo collector (default: enabled).\n#  --collector.meminfo_numa  Enable the meminfo_numa collector (default:\n#                            disabled).\n#  --collector.mountstats    Enable the mountstats collector (default:\n#                            disabled).\n#  --collector.netdev        Enable the netdev collector (default: enabled).\n#  --collector.netstat       Enable the netstat collector (default: enabled).\n#  --collector.nfs           Enable the nfs collector (default: enabled).\n#  --collector.nfsd          Enable the nfsd collector (default: enabled).\n#  --collector.ntp           Enable the ntp collector (default: disabled).\n#  --collector.qdisc         Enable the qdisc collector (default: disabled).\n#  --collector.runit         Enable the runit collector (default: disabled).\n#  --collector.sockstat      Enable the sockstat collector (default:\n#                            enabled).\n#  --collector.stat          Enable the stat collector (default: enabled).\n#  --collector.supervisord   Enable the supervisord collector (default:\n#                            disabled).\n#  --collector.systemd       Enable the systemd collector (default: enabled).\n#  --collector.tcpstat       Enable the tcpstat collector (default:\n#                            disabled).\n#  --collector.textfile      Enable the textfile collector (default:\n#                            enabled).\n#  --collector.time          Enable the time collector (default: enabled).\n#  --collector.uname         Enable the uname collector (default: enabled).\n#  --collector.vmstat        Enable the vmstat collector (default: enabled).\n#  --collector.wifi          Enable the wifi collector (default: enabled).\n#  --collector.xfs           Enable the xfs collector (default: enabled).\n#  --collector.zfs           Enable the zfs collector (default: enabled).\n#  --collector.timex         Enable the timex collector (default: enabled).\n#  --web.listen-address=\":9100\"\n#                            Address on which to expose metrics and web\n#                            interface.\n#  --web.telemetry-path=\"/metrics\"\n#                            Path under which to expose metrics.\n#  --log.level=\"info\"        Only log messages with the given severity or\n#                            above. Valid levels: [debug, info, warn, error,\n#                            fatal]\n#  --log.format=\"logger:stderr\"\n#                            Set the log target and format. Example:\n#                            \"logger:syslog?appname=bob&local=7\" or\n#                            \"logger:stdout?json=true\"\n"
  },
  {
    "path": "stage2/04-ethereum/files/grafana/prometheus.yml",
    "content": "# Sample config for Prometheus.\n\nglobal:\n  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.\n  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.\n  # scrape_timeout is set to the global default (10s).\n\n  # Attach these labels to any time series or alerts when communicating with\n  # external systems (federation, remote storage, Alertmanager).\n  external_labels:\n      monitor: 'example'\n\n# Alertmanager configuration\nalerting:\n  alertmanagers:\n  - static_configs:\n    - targets: ['localhost:9093']\n\n# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.\nrule_files:\n  # - \"first_rules.yml\"\n  # - \"second_rules.yml\"\n\n# A scrape configuration containing exactly one endpoint to scrape:\n# Here it's Prometheus itself.\nscrape_configs:\n  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.\n  - job_name: 'prometheus'\n\n    # Override the global default and scrape targets from this job every 5 seconds.\n    scrape_interval: 5s\n    scrape_timeout: 5s\n\n    # metrics_path defaults to '/metrics'\n    # scheme defaults to 'http'.\n\n    static_configs:\n      - targets: ['localhost:9090']\n\n  - job_name: node\n    # If prometheus-node-exporter is installed, grab stats about the local\n    # machine by default.\n    static_configs:\n      - targets: ['localhost:9100']\n  - job_name: geth\n    scrape_interval: 15s\n    scrape_timeout: 10s\n    metrics_path: /debug/metrics/prometheus\n    scheme: http\n    static_configs:\n      - targets: ['localhost:6060']\n  - job_name: besu-dev\n    scrape_interval: 15s\n    scrape_timeout: 10s\n    metrics_path: /metrics\n    scheme: http\n    static_configs:\n      - targets: ['localhost:9545']\n  - job_name: 'validator'\n    static_configs:\n      - targets: ['localhost:8081']\n  - job_name: 'beacon node'\n    static_configs:\n      - targets: ['localhost:8080']\n  - job_name: 'lighthouse'\n    static_configs:\n      - targets: ['localhost:5052']\n  - job_name: \"nimbus\"\n    static_configs:\n      - targets: ['127.0.0.1:8008']\n\n"
  },
  {
    "path": "stage2/04-ethereum/files/grafana-eth2-onyx/prometheus",
    "content": "# Set the command-line arguments to pass to the server.\nARGS=\"--storage.tsdb.path=\"/home/prometheus/metrics2/\"\"\n\n# Prometheus supports the following options:\n#  --config.file=\"/etc/prometheus/prometheus.yml\"\n#                             Prometheus configuration file path.\n#  --web.listen-address=\"0.0.0.0:9090\"\n#                             Address to listen on for UI, API, and telemetry.\n#  --web.read-timeout=5m      Maximum duration before timing out read of the\n#                             request, and closing idle connections.\n#  --web.max-connections=512  Maximum number of simultaneous connections.\n#  --web.external-url=<URL>   The URL under which Prometheus is externally\n#                             reachable (for example, if Prometheus is served\n#                             via a reverse proxy). Used for generating\n#                             relative and absolute links back to Prometheus\n#                             itself. If the URL has a path portion, it will\n#                             be used to prefix all HTTP endpoints served by\n#                             Prometheus. If omitted, relevant URL components\n#                             will be derived automatically.\n#  --web.route-prefix=<path>  Prefix for the internal routes of web endpoints.\n#                             Defaults to path of --web.external-url.\n#  --web.local-assets=\"/usr/share/prometheus/web/\"\n#                             Path to static asset/templates directory.\n#  --web.user-assets=<path>   Path to static asset directory, available at\n#                             /user.\n#  --web.enable-lifecycle     Enable shutdown and reload via HTTP request.\n#  --web.enable-admin-api     Enables API endpoints for admin control actions.\n#  --web.console.templates=\"/etc/prometheus/consoles\"\n#                             Path to the console template directory,\n#                             available at /consoles.\n#  --web.console.libraries=\"/etc/prometheus/console_libraries\"\n#                             Path to the console library directory.\n#   --storage.tsdb.path=\"/home/prometheus/metrics2/\"\n#                             Base path for metrics storage.\n#  --storage.tsdb.min-block-duration=2h\n#                             Minimum duration of a data block before being\n#                             persisted.\n#  --storage.tsdb.max-block-duration=<duration>\n#                             Maximum duration compacted blocks may span.\n#                             (Defaults to 10% of the retention period)\n#  --storage.tsdb.retention=15d\n#                             How long to retain samples in the storage.\n#  --storage.tsdb.use-lockfile\n#                             Create a lockfile in data directory.\n#  --alertmanager.notification-queue-capacity=10000\n#                             The capacity of the queue for pending alert\n#                             manager notifications.\n#  --alertmanager.timeout=10s\n#                             Timeout for sending alerts to Alertmanager.\n#  --query.lookback-delta=5m  The delta difference allowed for retrieving\n#                             metrics during expression evaluations.\n#  --query.timeout=2m         Maximum time a query may take before being\n#                             aborted.\n#  --query.max-concurrency=20\n#                             Maximum number of queries executed concurrently.\n#  --log.level=info           Only log messages with the given severity or\n#                             above. One of: [debug, info, warn, error]\n"
  },
  {
    "path": "stage2/04-ethereum/files/grafana-eth2-onyx/prometheus-node-exporter",
    "content": "# Set the command-line arguments to pass to the server.\n# Due to shell scaping, to pass backslashes for regexes, you need to double\n# them (\\\\d for \\d). If running under systemd, you need to double them again\n# (\\\\\\\\d to mean \\d), and escape newlines too.\nARGS=\"--collector.textfile.directory=\"/home/prometheus/node-exporter\"\n\n# Prometheus-node-exporter supports the following options:\n#\n#  --collector.diskstats.ignored-devices=\"^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\\\\d+n\\\\d+p)\\\\d+$\"\n#                            Regexp of devices to ignore for diskstats.\n#  --collector.filesystem.ignored-mount-points=\"^/(dev|proc|run|sys|mnt|media|var/lib/docker)($|/)\"\n#                            Regexp of mount points to ignore for filesystem\n#                            collector.\n#  --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)$\"\n#                            Regexp of filesystem types to ignore for\n#                            filesystem collector.\n#  --collector.netdev.ignored-devices=\"^lo$\"\n#                            Regexp of net devices to ignore for netdev\n#                            collector.\n#  --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))$\"\n#                            Regexp of fields to return for netstat\n#                            collector.\n#  --collector.ntp.server=\"127.0.0.1\"\n#                            NTP server to use for ntp collector\n#  --collector.ntp.protocol-version=4\n#                            NTP protocol version\n#  --collector.ntp.server-is-local\n#                            Certify that collector.ntp.server address is the\n#                            same local host as this collector.\n#  --collector.ntp.ip-ttl=1  IP TTL to use while sending NTP query\n#  --collector.ntp.max-distance=3.46608s\n#                            Max accumulated distance to the root\n#  --collector.ntp.local-offset-tolerance=1ms\n#                            Offset between local clock and local ntpd time\n#                            to tolerate\n#  --path.procfs=\"/proc\"     procfs mountpoint.\n#  --path.sysfs=\"/sys\"       sysfs mountpoint.\n#  --collector.qdisc.fixtures=\"\"\n#                            test fixtures to use for qdisc collector\n#                            end-to-end testing\n#  --collector.runit.servicedir=\"/etc/service\"\n#                            Path to runit service directory.\n#  --collector.supervisord.url=\"http://localhost:9001/RPC2\"\n#                            XML RPC endpoint.\n#  --collector.systemd.unit-whitelist=\".+\"\n#                            Regexp of systemd units to whitelist. Units must\n#                            both match whitelist and not match blacklist to\n#                            be included.\n#  --collector.systemd.unit-blacklist=\".+(\\\\.device|\\\\.scope|\\\\.slice|\\\\.target)\"\n#                            Regexp of systemd units to blacklist. Units must\n#                            both match whitelist and not match blacklist to\n#                            be included.\n#  --collector.systemd.private\n#                            Establish a private, direct connection to\n#                            systemd without dbus.\n# --collector.textfile.directory=\"/home/prometheus/node-exporter\"\n#                            Directory to read text files with metrics from.\n#  --collector.vmstat.fields=\"^(oom_kill|pgpg|pswp|pg.*fault).*\"\n#                            Regexp of fields to return for vmstat collector.\n#  --collector.wifi.fixtures=\"\"\n#                            test fixtures to use for wifi collector metrics\n#  --collector.arp           Enable the arp collector (default: enabled).\n#  --collector.bcache        Enable the bcache collector (default: enabled).\n#  --collector.bonding       Enable the bonding collector (default: enabled).\n#  --collector.buddyinfo     Enable the buddyinfo collector (default:\n#                            disabled).\n#  --collector.conntrack     Enable the conntrack collector (default:\n#                            enabled).\n#  --collector.cpu           Enable the cpu collector (default: enabled).\n#  --collector.diskstats     Enable the diskstats collector (default:\n#                            enabled).\n#  --collector.drbd          Enable the drbd collector (default: disabled).\n#  --collector.edac          Enable the edac collector (default: enabled).\n#  --collector.entropy       Enable the entropy collector (default: enabled).\n#  --collector.filefd        Enable the filefd collector (default: enabled).\n#  --collector.filesystem    Enable the filesystem collector (default:\n#                            enabled).\n#  --collector.hwmon         Enable the hwmon collector (default: enabled).\n#  --collector.infiniband    Enable the infiniband collector (default:\n#                            enabled).\n#  --collector.interrupts    Enable the interrupts collector (default:\n#                            disabled).\n#  --collector.ipvs          Enable the ipvs collector (default: enabled).\n#  --collector.ksmd          Enable the ksmd collector (default: disabled).\n#  --collector.loadavg       Enable the loadavg collector (default: enabled).\n#  --collector.logind        Enable the logind collector (default: disabled).\n#  --collector.mdadm         Enable the mdadm collector (default: enabled).\n#  --collector.meminfo       Enable the meminfo collector (default: enabled).\n#  --collector.meminfo_numa  Enable the meminfo_numa collector (default:\n#                            disabled).\n#  --collector.mountstats    Enable the mountstats collector (default:\n#                            disabled).\n#  --collector.netdev        Enable the netdev collector (default: enabled).\n#  --collector.netstat       Enable the netstat collector (default: enabled).\n#  --collector.nfs           Enable the nfs collector (default: enabled).\n#  --collector.nfsd          Enable the nfsd collector (default: enabled).\n#  --collector.ntp           Enable the ntp collector (default: disabled).\n#  --collector.qdisc         Enable the qdisc collector (default: disabled).\n#  --collector.runit         Enable the runit collector (default: disabled).\n#  --collector.sockstat      Enable the sockstat collector (default:\n#                            enabled).\n#  --collector.stat          Enable the stat collector (default: enabled).\n#  --collector.supervisord   Enable the supervisord collector (default:\n#                            disabled).\n#  --collector.systemd       Enable the systemd collector (default: enabled).\n#  --collector.tcpstat       Enable the tcpstat collector (default:\n#                            disabled).\n#  --collector.textfile      Enable the textfile collector (default:\n#                            enabled).\n#  --collector.time          Enable the time collector (default: enabled).\n#  --collector.uname         Enable the uname collector (default: enabled).\n#  --collector.vmstat        Enable the vmstat collector (default: enabled).\n#  --collector.wifi          Enable the wifi collector (default: enabled).\n#  --collector.xfs           Enable the xfs collector (default: enabled).\n#  --collector.zfs           Enable the zfs collector (default: enabled).\n#  --collector.timex         Enable the timex collector (default: enabled).\n#  --web.listen-address=\":9100\"\n#                            Address on which to expose metrics and web\n#                            interface.\n#  --web.telemetry-path=\"/metrics\"\n#                            Path under which to expose metrics.\n#  --log.level=\"info\"        Only log messages with the given severity or\n#                            above. Valid levels: [debug, info, warn, error,\n#                            fatal]\n#  --log.format=\"logger:stderr\"\n#                            Set the log target and format. Example:\n#                            \"logger:syslog?appname=bob&local=7\" or\n#                            \"logger:stdout?json=true\"\n"
  },
  {
    "path": "stage2/04-ethereum/files/grafana-eth2-onyx/prometheus.yml",
    "content": "# Sample config for Prometheus.\n\nglobal:\n  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.\n  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.\n  # scrape_timeout is set to the global default (10s).\n\n  # Attach these labels to any time series or alerts when communicating with\n  # external systems (federation, remote storage, Alertmanager).\n  external_labels:\n      monitor: 'example'\n\n# Alertmanager configuration\nalerting:\n  alertmanagers:\n  - static_configs:\n    - targets: ['localhost:9093']\n\n# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.\nrule_files:\n  # - \"first_rules.yml\"\n  # - \"second_rules.yml\"\n\n# A scrape configuration containing exactly one endpoint to scrape:\n# Here it's Prometheus itself.\nscrape_configs:\n  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.\n  - job_name: 'prometheus'\n\n    # Override the global default and scrape targets from this job every 5 seconds.\n    scrape_interval: 5s\n    scrape_timeout: 5s\n\n    # metrics_path defaults to '/metrics'\n    # scheme defaults to 'http'.\n\n    static_configs:\n      - targets: ['localhost:9090']\n\n  - job_name: node\n    # If prometheus-node-exporter is installed, grab stats about the local\n    # machine by default.\n    static_configs:\n      - targets: ['localhost:9100']\n  - job_name: geth\n    scrape_interval: 15s\n    scrape_timeout: 10s\n    metrics_path: /debug/metrics/prometheus\n    scheme: http\n    static_configs:\n      - targets: ['localhost:6060']\n  - job_name: besu-dev\n    scrape_interval: 15s\n    scrape_timeout: 10s\n    metrics_path: /metrics\n    scheme: http\n    static_configs:\n      - targets: ['localhost:9545']\n  - job_name: 'validator'\n    static_configs:\n      - targets: ['localhost:8081']\n  - job_name: 'beacon node'\n    static_configs:\n      - targets: ['localhost:8080']\n"
  },
  {
    "path": "stage2/04-ethereum/files/init_resize.sh",
    "content": "#!/bin/sh\n\nreboot_pi () {\n  umount /boot\n  mount / -o remount,ro\n  sync\n  if [ \"$NOOBS\" = \"1\" ]; then\n    if [ \"$NEW_KERNEL\" = \"1\" ]; then\n      reboot -f \"$BOOT_PART_NUM\"\n    else\n      echo \"$BOOT_PART_NUM\" > \"/sys/module/${BCM_MODULE}/parameters/reboot_part\"\n    fi\n  fi\n  echo b > /proc/sysrq-trigger\n  sleep 5\n  exit 0\n}\n\ncheck_commands () {\n  if ! command -v whiptail > /dev/null; then\n      echo \"whiptail not found\"\n      sleep 5\n      return 1\n  fi\n  for COMMAND in grep cut sed parted fdisk findmnt partprobe; do\n    if ! command -v $COMMAND > /dev/null; then\n      FAIL_REASON=\"$COMMAND not found\"\n      return 1\n    fi\n  done\n  return 0\n}\n\ncheck_noobs () {\n  if [ \"$BOOT_PART_NUM\" = \"1\" ]; then\n    NOOBS=0\n  else\n    NOOBS=1\n  fi\n}\n\nget_variables () {\n  ROOT_PART_DEV=$(findmnt / -o source -n)\n  ROOT_PART_NAME=$(echo \"$ROOT_PART_DEV\" | cut -d \"/\" -f 3)\n  ROOT_DEV_NAME=$(echo /sys/block/*/\"${ROOT_PART_NAME}\" | cut -d \"/\" -f 4)\n  ROOT_DEV=\"/dev/${ROOT_DEV_NAME}\"\n  ROOT_PART_NUM=$(cat \"/sys/block/${ROOT_DEV_NAME}/${ROOT_PART_NAME}/partition\")\n\n  BOOT_PART_DEV=$(findmnt /boot -o source -n)\n  BOOT_PART_NAME=$(echo \"$BOOT_PART_DEV\" | cut -d \"/\" -f 3)\n  BOOT_DEV_NAME=$(echo /sys/block/*/\"${BOOT_PART_NAME}\" | cut -d \"/\" -f 4)\n  BOOT_PART_NUM=$(cat \"/sys/block/${BOOT_DEV_NAME}/${BOOT_PART_NAME}/partition\")\n\n  OLD_DISKID=$(fdisk -l \"$ROOT_DEV\" | sed -n 's/Disk identifier: 0x\\([^ ]*\\)/\\1/p')\n\n  check_noobs\n\n  ROOT_DEV_SIZE=$(cat \"/sys/block/${ROOT_DEV_NAME}/size\")\n  TARGET_END=$((ROOT_DEV_SIZE - 1))\n\n  PARTITION_TABLE=$(parted -m \"$ROOT_DEV\" unit s print | tr -d 's')\n\n  LAST_PART_NUM=$(echo \"$PARTITION_TABLE\" | tail -n 1 | cut -d \":\" -f 1)\n\n  ROOT_PART_LINE=$(echo \"$PARTITION_TABLE\" | grep -e \"^${ROOT_PART_NUM}:\")\n  ROOT_PART_START=$(echo \"$ROOT_PART_LINE\" | cut -d \":\" -f 2)\n  ROOT_PART_END=$(echo \"$ROOT_PART_LINE\" | cut -d \":\" -f 3)\n\n  if [ \"$NOOBS\" = \"1\" ]; then\n    EXT_PART_LINE=$(echo \"$PARTITION_TABLE\" | grep \":::;\" | head -n 1)\n    EXT_PART_NUM=$(echo \"$EXT_PART_LINE\" | cut -d \":\" -f 1)\n    EXT_PART_START=$(echo \"$EXT_PART_LINE\" | cut -d \":\" -f 2)\n    EXT_PART_END=$(echo \"$EXT_PART_LINE\" | cut -d \":\" -f 3)\n  fi\n}\n\nfix_partuuid() {\n  DISKID=\"$(fdisk -l \"$ROOT_DEV\" | sed -n 's/Disk identifier: 0x\\([^ ]*\\)/\\1/p')\"\n\n  sed -i \"s/${OLD_DISKID}/${DISKID}/g\" /etc/fstab\n  sed -i \"s/${OLD_DISKID}/${DISKID}/\" /boot/cmdline.txt\n}\n\ncheck_variables () {\n  if [ \"$NOOBS\" = \"1\" ]; then\n    if [ \"$EXT_PART_NUM\" -gt 4 ] || \\\n       [ \"$EXT_PART_START\" -gt \"$ROOT_PART_START\" ] || \\\n       [ \"$EXT_PART_END\" -lt \"$ROOT_PART_END\" ]; then\n      FAIL_REASON=\"Unsupported extended partition\"\n      return 1\n    fi\n  fi\n\n  if [ \"$BOOT_DEV_NAME\" != \"$ROOT_DEV_NAME\" ]; then\n      FAIL_REASON=\"Boot and root partitions are on different devices\"\n      return 1\n  fi\n\n  if [ \"$ROOT_PART_NUM\" -ne \"$LAST_PART_NUM\" ]; then\n    FAIL_REASON=\"Root partition should be last partition\"\n    return 1\n  fi\n\n  if [ \"$ROOT_PART_END\" -gt \"$TARGET_END\" ]; then\n    FAIL_REASON=\"Root partition runs past the end of device\"\n    return 1\n  fi\n\n  if [ ! -b \"$ROOT_DEV\" ] || [ ! -b \"$ROOT_PART_DEV\" ] || [ ! -b \"$BOOT_PART_DEV\" ] ; then\n    FAIL_REASON=\"Could not determine partitions\"\n    return 1\n  fi\n}\n\ncheck_kernel () {\n  local MAJOR=$(uname -r | cut -f1 -d.)\n  local MINOR=$(uname -r | cut -f2 -d.)\n  if [ \"$MAJOR\" -eq \"4\" ] && [ \"$MINOR\" -lt \"9\" ]; then\n    return 0\n  fi\n  if [ \"$MAJOR\" -lt \"4\" ]; then\n    return 0\n  fi\n  NEW_KERNEL=1\n}\n\nethereum_setup () {\n\n# hack to modify hostname in EthRaspbian\nMAC_HASH=`cat /sys/class/net/eth0/address | sha256sum | awk '{print substr($0,0,9)}'`\necho ethnode-$MAC_HASH > /etc/hostname\nsed -i \"s/127.0.1.1.*/127.0.1.1\\tethnode-$MAC_HASH/g\" /etc/hosts\n\n# Format USB3 SSD and mount it as /home\n\necho Looking for USB drive\nsleep 20\n\nif stat  /dev/sda > /dev/null 2>&1;\nthen\n\techo USB drive found\n\tsleep 2 \n        echo Partitioning and formatting USB Drive...\n        fdisk /dev/sda <<EOF\nd\nn\np\n1\n\n\nw\nEOF\nmkfs.ext4 -F /dev/sda1\necho '/dev/sda1 /home ext4 defaults 0 2' >> /etc/fstab && mount /home\nelse\n        echo no SDD detected\n\tsleep 5\nfi\n\n# Create Ethereum account\necho \"Creating ethereum  user for Geth and Parity\"\nif ! id -u ethereum >/dev/null 2>&1; then\n        adduser --disabled-password --gecos \"\" ethereum\nfi\n\necho \"ethereum:ethereum\" | chpasswd\nfor GRP in sudo netdev audio video dialout plugdev bluetooth; do\n\tadduser ethereum $GRP\ndone\n\n# Force password change on first login\nchage -d 0 ethereum\n\n# Delete pi user\nuserdel -r pi\n\n# Enable 64bit Kernel for fixing memory allocation issues\necho arm_64bit=1 >> /boot/config.txt\n\n# Change swappiness default value to force using Zram\necho \"vm.swappiness=100\" >> /etc/sysctl.conf\n\n}\n\nmain () {\n  get_variables\n\n  if ! check_variables; then\n    return 1\n  fi\n\n  check_kernel\n\n  if [ \"$NOOBS\" = \"1\" ] && [ \"$NEW_KERNEL\" != \"1\" ]; then\n    BCM_MODULE=$(grep -e \"^Hardware\" /proc/cpuinfo | cut -d \":\" -f 2 | tr -d \" \" | tr '[:upper:]' '[:lower:]')\n    if ! modprobe \"$BCM_MODULE\"; then\n      FAIL_REASON=\"Couldn't load BCM module $BCM_MODULE\"\n      return 1\n    fi\n  fi\n\n  if [ \"$ROOT_PART_END\" -eq \"$TARGET_END\" ]; then\n    reboot_pi\n  fi\n\n  if [ \"$NOOBS\" = \"1\" ]; then\n    if ! parted -m \"$ROOT_DEV\" u s resizepart \"$EXT_PART_NUM\" yes \"$TARGET_END\"; then\n      FAIL_REASON=\"Extended partition resize failed\"\n      return 1\n    fi\n  fi\n\n  if ! parted -m \"$ROOT_DEV\" u s resizepart \"$ROOT_PART_NUM\" \"$TARGET_END\"; then\n    FAIL_REASON=\"Root partition resize failed\"\n    return 1\n  fi\n\n  partprobe \"$ROOT_DEV\"\n  fix_partuuid\n  ethereum_setup\n\n  return 0\n}\n\nmount -t proc proc /proc\nmount -t sysfs sys /sys\nmount -t tmpfs tmp /run\nmkdir -p /run/systemd\n\nmount /boot\nmount / -o remount,rw\n\nsed -i 's| init=/usr/lib/raspi-config/init_resize\\.sh||' /boot/cmdline.txt\nsed -i 's| sdhci\\.debug_quirks2=4||' /boot/cmdline.txt\n\nif ! grep -q splash /boot/cmdline.txt; then\n  sed -i \"s/ quiet//g\" /boot/cmdline.txt\nfi\n\nsync\n\necho 1 > /proc/sys/kernel/sysrq\n\nif ! check_commands; then\n  reboot_pi\nfi\n\nif main; then\n  whiptail --infobox \"Resized root filesystem. Rebooting in 5 seconds...\" 20 60\n  sleep 5\nelse\n  sleep 5\n  whiptail --msgbox \"Could not expand filesystem, please try raspi-config or rc_gui.\\n${FAIL_REASON}\" 20 60\nfi\n\nreboot_pi\n"
  },
  {
    "path": "stage2/04-ethereum/files/rc.local.eth1",
    "content": "#!/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 will \"exit 0\" on success or any other\n# value on error.\n#\n# In order to enable or disable this script just change the execution\n# bits.\n#\n# By default this script does nothing.\n# This script turns the Ubuntu 64 bit image into an Ethereum on ARM image\n#\n\nFLAG=\"/root/first-run.flag\"\nif [ ! -f $FLAG ]; then\n   # Modify hostname (ethnode-$MAC-HASH-CHUNK)\n   echo Changing hostname\n   MAC_HASH=`cat /sys/class/net/eth0/address | sha256sum | awk '{print substr($0,0,9)}'`\n   echo ethnode-$MAC_HASH > /etc/hostname\n   sed -i \"s/127.0.0.1.*/127.0.0.1\\tethnode-$MAC_HASH/g\" /etc/hosts\n\n   # Format USB3 SSD and mount it as /home\n\n   echo Looking for USB drive\n\n   if stat  /dev/sda > /dev/null 2>&1;\n     then\n     \techo USB drive found\n        echo Partitioning and formatting USB Drive...\n        fdisk /dev/sda <<EOF\nd\nn\np\n1\n\n\n\nw\nEOF\n\n\tmkfs.ext4 -F /dev/sda1\n\techo '/dev/sda1 /home ext4 defaults 0 2' >> /etc/fstab && mount /home\n   else\n        echo no SDD detected\n   fi\n\n   # Create Ethereum account\n   echo \"Creating ethereum  user for Geth and Parity\"\n   if ! id -u ethereum >/dev/null 2>&1; then\n\tadduser --disabled-password --gecos \"\" ethereum\n   fi\n\n   echo \"ethereum:ethereum\" | chpasswd\n   for GRP in sudo netdev audio video dialout plugdev bluetooth; do\n\tadduser ethereum $GRP\n   done\n\n   # Force password change on first login\n   chage -d 0 ethereum\n\n# Create some swap memory in the USB device for avoiding memory issues.\n  echo \"Creating swap memory and activating Zram\"\n  if stat  /dev/sda > /dev/null 2>&1;\n\tthen\n\t\tmkdir -p /home/ethereum/swap\n\t\tdd if=/dev/zero of=/home/ethereum/swap/swapfile bs=16k count=256k\n\t\tchmod 600 /home/ethereum/swap/swapfile\n\t\tmkswap /home/ethereum/swap/swapfile\n\t\tswapon /home/ethereum/swap/swapfile\n\t\techo \"/home/ethereum/swap/swapfile none swap sw 0 0\" >> /etc/fstab\n\telse\n\t\techo no swap created\n   fi\n\n# Enable Zram (based on ARMBIAN script)\n  mkdir -p /usr/lib/armbian\n\n  cat << EOF | tee /etc/default/armbian-zram-config >/dev/null\n# configuration values for the armbian-zram-config service\n#\n# enable the armbian-zram-config service\nENABLED=true\nZRAM_PERCENTAGE=25\nEOF\n\n  # Enable Zram (ARMBIAN script)\n  cat << 'EOF' | tee /usr/lib/armbian/armbian-zram-config >/dev/null\n#!/bin/bash\n#\n# Copyright (c) Authors: http://www.armbian.com/authors\n#\n# This file is licensed under the terms of the GNU General Public\n# License version 2. This program is licensed \"as is\" without any\n# warranty of any kind, whether express or implied.\n# Functions:\n#\n# activate_zram_swap\n# activate_ramlog_partition\n# activate_compressed_tmp\n# Read in basic OS image information\n#. /etc/armbian-release\n# and script configuration\n#. /usr/lib/armbian/armbian-common\n# It's possible to override ZRAM_PERCENTAGE, ZRAM_MAX_DEVICES, SWAP_ALGORITHM,\n# RAMLOG_ALGORITHM and TMP_ALGORITHM here:\n[ -f /etc/default/armbian-zram-config ] && . /etc/default/armbian-zram-config\nactivate_zram_swap() {\n\t# Do not interfere with already present config-zram package\n\tdpkg -l | grep -q 'zram-config' && exit 0\n\t[[ \"$ENABLED\" != \"true\" ]] && exit 0\n\t# Load zram module with n instances for swap: one per CPU core, $ZRAM_MAX_DEVICES\n\t# defines the maximum, on modern kernels we overwrite this with 1 and rely on\n\t# max_comp_streams being set to count of CPU cores or $ZRAM_MAX_DEVICES\n\tuname -r | grep -q '^3.' && zram_max_devs=${ZRAM_MAX_DEVICES:=4} || zram_max_devs=1\n\tcpu_cores=$(grep -c '^processor' /proc/cpuinfo | sed 's/^0$/1/')\n\t[[ ${cpu_cores} -gt ${zram_max_devs} ]] && zram_devices=${zram_max_devs} || zram_devices=${cpu_cores}\n\tmodule_args=\"$(modinfo zram | awk -F\" \" '/num_devices/ {print $2}' | cut -f1 -d:)\"\n\t[[ -n ${module_args} ]] && modprobe zram ${module_args}=$(( ${zram_devices} + 2 )) || return\n\t# Expose 50% of real memory as swap space by default\n\tzram_percent=${ZRAM_PERCENTAGE:=50}\n\tmem_info=$(LC_ALL=C free -w 2>/dev/null | grep \"^Mem\" || LC_ALL=C free | grep \"^Mem\")\n\tmemory_total=$(awk '{printf(\"%d\",$2*1024)}' <<<${mem_info})\n\tmem_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${zram_percent} / 100 ))\n\t# Limit memory available to zram to 50% by default\n\tmem_limit_percent=${MEM_LIMIT_PERCENTAGE:=50}\n\tmem_limit_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${mem_limit_percent} / 100 ))\n\tswap_algo=${SWAP_ALGORITHM:=lzo}\n\tfor (( i=1; i<=zram_devices; i++ )); do\n\t\t[[ -f /sys/block/zram${i}/comp_algorithm ]] && echo ${swap_algo} >/sys/block/zram${i}/comp_algorithm 2>/dev/null\n\t\tif [ \"X${ZRAM_BACKING_DEV}\" != \"X\" ]; then\n\t\t\techo ${ZRAM_BACKING_DEV} >/sys/block/zram${i}/backing_dev\n\t\tfi\n\t\techo -n ${ZRAM_MAX_DEVICES:=4} > /sys/block/zram${i}/max_comp_streams\n\t\techo -n ${mem_per_zram_device} > /sys/block/zram${i}/disksize\n\t\techo -n ${mem_limit_per_zram_device} > /sys/block/zram${i}/mem_limit\n\t\tmkswap /dev/zram${i}\n\t\tswapon -p 5 /dev/zram${i}\n\tdone\n\t# Swapping to HDDs is stupid so switch to settings made for flash memory and zram/zswap\n\techo 0 > /proc/sys/vm/page-cluster\n\techo -e \"\\n### Activated ${zram_devices} ${swap_algo} zram swap devices with $(( ${mem_per_zram_device} / 1048576 )) MB each\\n\" >>${Log}\n} # activate_zram_swap\nactivate_ramlog_partition() {\n\t# /dev/zram0 will be used as a compressed /var/log partition in RAM if\n\t# ENABLED=true in /etc/default/armbian-ramlog is set\n\tENABLED=$(awk -F\"=\" '/^ENABLED/ {print $2}' /etc/default/armbian-ramlog)\n\t[[ \"$ENABLED\" != \"true\" ]] && return\n\t\n\t# read size also from /etc/default/armbian-ramlog\n\tramlogsize=$(awk -F\"=\" '/^SIZE/ {print $2}' /etc/default/armbian-ramlog)\n\tdisksize=$(sed -e 's/M$/*1048576/' -e 's/K$/*1024/' <<<${ramlogsize:=50M} | bc)\n\t# choose RAMLOG_ALGORITHM if defined in /etc/default/armbian-zram-config\n\t# otherwise try to choose most efficient compression scheme available.\n\t# See https://patchwork.kernel.org/patch/9918897/\n\tif [ \"X${RAMLOG_ALGORITHM}\" = \"X\" ]; then\n\t\tfor algo in lz4 lz4hc quicklz zlib brotli zstd ; do\n\t\t\techo ${algo} >/sys/block/zram0/comp_algorithm 2>/dev/null\n\t\tdone\n\telse\n\t\techo ${RAMLOG_ALGORITHM} >/sys/block/zram0/comp_algorithm 2>/dev/null\n\tfi\n\techo -n ${disksize} > /sys/block/zram0/disksize\n\t# if it fails, select $swap_algo. Workaround for some older kernels\n\tif [[ $? == 1 ]]; then\n\t\techo ${swap_algo} > /sys/block/zram0/comp_algorithm 2>/dev/null\n\t\techo -n ${disksize} > /sys/block/zram0/disksize\n\tfi\n\tmkfs.ext4 -O ^has_journal -s 1024 -L log2ram /dev/zram0\n\talgo=$(sed 's/.*\\[\\([^]]*\\)\\].*/\\1/g' </sys/block/zram0/comp_algorithm)\n\techo -e \"### Activated Armbian ramlog partition with ${algo} compression\" >>${Log}\n} # activate_ramlog_partition\nactivate_compressed_tmp() {\n\t# create /tmp not as tmpfs but zram compressed if no fstab entry exists\n\tgrep -q '^tmpfs /tmp' /etc/mtab && return\n\ttmp_device=$(( ${zram_devices} + 1 ))\n\tif [[ -f /sys/block/zram${tmp_device}/comp_algorithm ]]; then\n\t\tif [ \"X${TMP_ALGORITHM}\" = \"X\" ]; then\n\t\t\techo ${swap_algo} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null\n\t\telse\n\t\t\techo ${TMP_ALGORITHM} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null\n\t\tfi\n\tfi\n\techo -n $(( ${memory_total} / 2 )) > /sys/block/zram${tmp_device}/disksize\n\tmkfs.ext4 -O ^has_journal -s 1024 -L tmp /dev/zram${tmp_device}\n\tmount -o nosuid,discard /dev/zram${tmp_device} /tmp\n\tchmod 777 /tmp\n\talgo=$(sed 's/.*\\[\\([^]]*\\)\\].*/\\1/g' </sys/block/zram${tmp_device}/comp_algorithm)\n} # activate_compressed_tmp\ncase $1 in\n\t*start*)\n\t\tactivate_zram_swap\n\t\tactivate_ramlog_partition\n\t\tactivate_compressed_tmp\n\t\t;;\nesac\nEOF\n\n  cat << 'EOF' | tee /etc/systemd/system/armbian-zram-config.service >/dev/null\n# Armbian ZRAM configuration service\n# Create 1 + number of cores compressed block devices\n# This service may block the boot process for up to 30 sec\n[Unit]\nDescription=Armbian ZRAM config\nDefaultDependencies=no\nAfter=local-fs.target\nBefore=armbian-ramlog.target\nConflicts=shutdown.target\n[Service]\nType=oneshot\nExecStart=/usr/lib/armbian/armbian-zram-config start\nExecStop=/usr/lib/armbian/armbian-zram-config stop\nRemainAfterExit=yes\nTimeoutStartSec=30sec\n[Install]\nWantedBy=sysinit.target\nEOF\n\n  cat << 'EOF' | tee /etc/default/armbian-ramlog >/dev/null\n# configuration values for the armbian-ram-logging service\n#\n# enable the armbian-ram-logging service?\nENABLED=true\n#\n# size of the tmpfs mount -- please keep in mind to adjust /etc/default/armbian-zram-config too when increasing\nSIZE=50M\n#\n# use rsync instead of cp -r\n# requires rsync installed, may provide better performance\n# due to copying only new and changed files\nUSE_RSYNC=true\nEOF\n\n  chmod +x /usr/lib/armbian/armbian-zram-config\n  systemctl enable armbian-zram-config\n\n  # Swap and Zram tweaks\n  # Page allocation error workout\n  echo \"vm.min_free_kbytes=65536\" >> /etc/sysctl.conf\n  # Modify swappiness parameter\n  echo \"vm.swappiness=100\" >> /etc/sysctl.conf\n\n\n  # Ethereum software installation\n  # Add APT EthRaspbian repository\n  sleep 25\n  echo \"Adding Ethereum repositories\"\n  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8A584409D327B0A5\n  add-apt-repository -n \"deb http://apt.ethraspbian.com bionic main\"\n  add-apt-repository -n \"deb http://apt.ethraspbian.com bionic-security main\"\n  add-apt-repository \"deb http://apt.ethraspbian.com bionic-upgrades main\"\n\n  # Install Ethereum packages\n  echo Installing Ethereum packages\n  apt-get -y install geth\n  # Stop Geth until first reboot in order to avoid slowing the install process\n  systemctl stop geth\n  apt-get -y install parity nethermind hyperledger-besu swarm ipfs raiden statusd vipnode prysm-beacon prysm-validator prysm-slasher lighthouse\n\n\n  # Create an alias for package updates\n  cat <<EOF >> /etc/bash.bashrc\nalias update-ethereum='\nsudo apt-get update\nsudo apt-get install geth parity nethermind hyperledger-besu swarm ipfs raiden statusd vipnode prysm-beacon prysm-validator prysm-slasher lighthouse'\nEOF\n   # Install monitoring infrastructure\n   wget -P /tmp https://dl.grafana.com/oss/release/grafana_6.7.3_arm64.deb\n   dpkg -i /tmp/grafana_6.7.3_arm64.deb\n   useradd -m prometheus\n   mkdir -p /home/prometheus/node-exporter/\n   chown -R  prometheus:prometheus /home/prometheus/\n   apt install -y prometheus prometheus-node-exporter\n   chown grafana:grafana /root/tmp/grafana.db\n   cp -a /root/tmp/grafana.db /var/lib/grafana/grafana.db\n   cp -a /root/tmp/{prometheus,prometheus-node-exporter} /etc/default\n   cp -a /root/tmp/prometheus.yml /etc/prometheus/\n   systemctl enable grafana-server\n\n   #the next line creates an empty file so it won't run the next boot\n   touch $FLAG\n   reboot\nelse\n   echo \"Nothing to do\"\nfi\n\nexit 0\n"
  },
  {
    "path": "stage2/04-ethereum/files/rc.local.eth2",
    "content": "#!/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 will \"exit 0\" on success or any other\n# value on error.\n#\n# In order to enable or disable this script just change the execution\n# bits.\n#\n# By default this script does nothing.\n# This script turns the Ubuntu 64 bit image into an Ethereum on ARM image\n#\n\nFLAG=\"/root/first-run.flag\"\nif [ ! -f $FLAG ]; then\n   # Modify hostname (ethnode-$MAC-HASH-CHUNK)\n   echo Changing hostname\n   MAC_HASH=`cat /sys/class/net/eth0/address | sha256sum | awk '{print substr($0,0,9)}'`\n   echo ethnode-$MAC_HASH > /etc/hostname\n   sed -i \"s/127.0.0.1.*/127.0.0.1\\tethnode-$MAC_HASH/g\" /etc/hosts\n\n   # Format USB3 SSD and mount it as /home\n\n   echo Looking for USB drive\n\n   if stat  /dev/sda > /dev/null 2>&1;\n     then\n     \techo USB drive found\n        echo Partitioning and formatting USB Drive...\n        fdisk /dev/sda <<EOF\nd\nn\np\n1\n\n\n\nw\nEOF\n\n\tmkfs.ext4 -F /dev/sda1\n\techo '/dev/sda1 /home ext4 defaults 0 2' >> /etc/fstab && mount /home\n   else\n        echo no SDD detected\n   fi\n\n   # Create Ethereum account\n   echo \"Creating ethereum  user for Geth and Parity\"\n   if ! id -u ethereum >/dev/null 2>&1; then\n\tadduser --disabled-password --gecos \"\" ethereum\n   fi\n\n   echo \"ethereum:ethereum\" | chpasswd\n   for GRP in sudo netdev audio video dialout plugdev bluetooth; do\n\tadduser ethereum $GRP\n   done\n\n   # Force password change on first login\n   chage -d 0 ethereum\n\n# Create some swap memory in the USB device for avoiding memory issues.\n  echo \"Creating swap memory and activating Zram\"\n  if stat  /dev/sda > /dev/null 2>&1;\n\tthen\n\t\tmkdir -p /home/ethereum/swap\n\t\tdd if=/dev/zero of=/home/ethereum/swap/swapfile bs=16k count=256k\n\t\tchmod 600 /home/ethereum/swap/swapfile\n\t\tmkswap /home/ethereum/swap/swapfile\n\t\tswapon /home/ethereum/swap/swapfile\n\t\techo \"/home/ethereum/swap/swapfile none swap sw 0 0\" >> /etc/fstab\n\telse\n\t\techo no swap created\n   fi\n\n# Enable Zram (based on ARMBIAN script)\n  mkdir -p /usr/lib/armbian\n\n  cat << EOF | tee /etc/default/armbian-zram-config >/dev/null\n# configuration values for the armbian-zram-config service\n#\n# enable the armbian-zram-config service\nENABLED=true\nZRAM_PERCENTAGE=25\nEOF\n\n  # Enable Zram (ARMBIAN script)\n  cat << 'EOF' | tee /usr/lib/armbian/armbian-zram-config >/dev/null\n#!/bin/bash\n#\n# Copyright (c) Authors: http://www.armbian.com/authors\n#\n# This file is licensed under the terms of the GNU General Public\n# License version 2. This program is licensed \"as is\" without any\n# warranty of any kind, whether express or implied.\n# Functions:\n#\n# activate_zram_swap\n# activate_ramlog_partition\n# activate_compressed_tmp\n# Read in basic OS image information\n#. /etc/armbian-release\n# and script configuration\n#. /usr/lib/armbian/armbian-common\n# It's possible to override ZRAM_PERCENTAGE, ZRAM_MAX_DEVICES, SWAP_ALGORITHM,\n# RAMLOG_ALGORITHM and TMP_ALGORITHM here:\n[ -f /etc/default/armbian-zram-config ] && . /etc/default/armbian-zram-config\nactivate_zram_swap() {\n\t# Do not interfere with already present config-zram package\n\tdpkg -l | grep -q 'zram-config' && exit 0\n\t[[ \"$ENABLED\" != \"true\" ]] && exit 0\n\t# Load zram module with n instances for swap: one per CPU core, $ZRAM_MAX_DEVICES\n\t# defines the maximum, on modern kernels we overwrite this with 1 and rely on\n\t# max_comp_streams being set to count of CPU cores or $ZRAM_MAX_DEVICES\n\tuname -r | grep -q '^3.' && zram_max_devs=${ZRAM_MAX_DEVICES:=4} || zram_max_devs=1\n\tcpu_cores=$(grep -c '^processor' /proc/cpuinfo | sed 's/^0$/1/')\n\t[[ ${cpu_cores} -gt ${zram_max_devs} ]] && zram_devices=${zram_max_devs} || zram_devices=${cpu_cores}\n\tmodule_args=\"$(modinfo zram | awk -F\" \" '/num_devices/ {print $2}' | cut -f1 -d:)\"\n\t[[ -n ${module_args} ]] && modprobe zram ${module_args}=$(( ${zram_devices} + 2 )) || return\n\t# Expose 50% of real memory as swap space by default\n\tzram_percent=${ZRAM_PERCENTAGE:=50}\n\tmem_info=$(LC_ALL=C free -w 2>/dev/null | grep \"^Mem\" || LC_ALL=C free | grep \"^Mem\")\n\tmemory_total=$(awk '{printf(\"%d\",$2*1024)}' <<<${mem_info})\n\tmem_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${zram_percent} / 100 ))\n\t# Limit memory available to zram to 50% by default\n\tmem_limit_percent=${MEM_LIMIT_PERCENTAGE:=50}\n\tmem_limit_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${mem_limit_percent} / 100 ))\n\tswap_algo=${SWAP_ALGORITHM:=lzo}\n\tfor (( i=1; i<=zram_devices; i++ )); do\n\t\t[[ -f /sys/block/zram${i}/comp_algorithm ]] && echo ${swap_algo} >/sys/block/zram${i}/comp_algorithm 2>/dev/null\n\t\tif [ \"X${ZRAM_BACKING_DEV}\" != \"X\" ]; then\n\t\t\techo ${ZRAM_BACKING_DEV} >/sys/block/zram${i}/backing_dev\n\t\tfi\n\t\techo -n ${ZRAM_MAX_DEVICES:=4} > /sys/block/zram${i}/max_comp_streams\n\t\techo -n ${mem_per_zram_device} > /sys/block/zram${i}/disksize\n\t\techo -n ${mem_limit_per_zram_device} > /sys/block/zram${i}/mem_limit\n\t\tmkswap /dev/zram${i}\n\t\tswapon -p 5 /dev/zram${i}\n\tdone\n\t# Swapping to HDDs is stupid so switch to settings made for flash memory and zram/zswap\n\techo 0 > /proc/sys/vm/page-cluster\n\techo -e \"\\n### Activated ${zram_devices} ${swap_algo} zram swap devices with $(( ${mem_per_zram_device} / 1048576 )) MB each\\n\" >>${Log}\n} # activate_zram_swap\nactivate_ramlog_partition() {\n\t# /dev/zram0 will be used as a compressed /var/log partition in RAM if\n\t# ENABLED=true in /etc/default/armbian-ramlog is set\n\tENABLED=$(awk -F\"=\" '/^ENABLED/ {print $2}' /etc/default/armbian-ramlog)\n\t[[ \"$ENABLED\" != \"true\" ]] && return\n\t\n\t# read size also from /etc/default/armbian-ramlog\n\tramlogsize=$(awk -F\"=\" '/^SIZE/ {print $2}' /etc/default/armbian-ramlog)\n\tdisksize=$(sed -e 's/M$/*1048576/' -e 's/K$/*1024/' <<<${ramlogsize:=50M} | bc)\n\t# choose RAMLOG_ALGORITHM if defined in /etc/default/armbian-zram-config\n\t# otherwise try to choose most efficient compression scheme available.\n\t# See https://patchwork.kernel.org/patch/9918897/\n\tif [ \"X${RAMLOG_ALGORITHM}\" = \"X\" ]; then\n\t\tfor algo in lz4 lz4hc quicklz zlib brotli zstd ; do\n\t\t\techo ${algo} >/sys/block/zram0/comp_algorithm 2>/dev/null\n\t\tdone\n\telse\n\t\techo ${RAMLOG_ALGORITHM} >/sys/block/zram0/comp_algorithm 2>/dev/null\n\tfi\n\techo -n ${disksize} > /sys/block/zram0/disksize\n\t# if it fails, select $swap_algo. Workaround for some older kernels\n\tif [[ $? == 1 ]]; then\n\t\techo ${swap_algo} > /sys/block/zram0/comp_algorithm 2>/dev/null\n\t\techo -n ${disksize} > /sys/block/zram0/disksize\n\tfi\n\tmkfs.ext4 -O ^has_journal -s 1024 -L log2ram /dev/zram0\n\talgo=$(sed 's/.*\\[\\([^]]*\\)\\].*/\\1/g' </sys/block/zram0/comp_algorithm)\n\techo -e \"### Activated Armbian ramlog partition with ${algo} compression\" >>${Log}\n} # activate_ramlog_partition\nactivate_compressed_tmp() {\n\t# create /tmp not as tmpfs but zram compressed if no fstab entry exists\n\tgrep -q '^tmpfs /tmp' /etc/mtab && return\n\ttmp_device=$(( ${zram_devices} + 1 ))\n\tif [[ -f /sys/block/zram${tmp_device}/comp_algorithm ]]; then\n\t\tif [ \"X${TMP_ALGORITHM}\" = \"X\" ]; then\n\t\t\techo ${swap_algo} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null\n\t\telse\n\t\t\techo ${TMP_ALGORITHM} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null\n\t\tfi\n\tfi\n\techo -n $(( ${memory_total} / 2 )) > /sys/block/zram${tmp_device}/disksize\n\tmkfs.ext4 -O ^has_journal -s 1024 -L tmp /dev/zram${tmp_device}\n\tmount -o nosuid,discard /dev/zram${tmp_device} /tmp\n\tchmod 777 /tmp\n\talgo=$(sed 's/.*\\[\\([^]]*\\)\\].*/\\1/g' </sys/block/zram${tmp_device}/comp_algorithm)\n} # activate_compressed_tmp\ncase $1 in\n\t*start*)\n\t\tactivate_zram_swap\n\t\tactivate_ramlog_partition\n\t\tactivate_compressed_tmp\n\t\t;;\nesac\nEOF\n\n  cat << 'EOF' | tee /etc/systemd/system/armbian-zram-config.service >/dev/null\n# Armbian ZRAM configuration service\n# Create 1 + number of cores compressed block devices\n# This service may block the boot process for up to 30 sec\n[Unit]\nDescription=Armbian ZRAM config\nDefaultDependencies=no\nAfter=local-fs.target\nBefore=armbian-ramlog.target\nConflicts=shutdown.target\n[Service]\nType=oneshot\nExecStart=/usr/lib/armbian/armbian-zram-config start\nExecStop=/usr/lib/armbian/armbian-zram-config stop\nRemainAfterExit=yes\nTimeoutStartSec=30sec\n[Install]\nWantedBy=sysinit.target\nEOF\n\n  cat << 'EOF' | tee /etc/default/armbian-ramlog >/dev/null\n# configuration values for the armbian-ram-logging service\n#\n# enable the armbian-ram-logging service?\nENABLED=true\n#\n# size of the tmpfs mount -- please keep in mind to adjust /etc/default/armbian-zram-config too when increasing\nSIZE=50M\n#\n# use rsync instead of cp -r\n# requires rsync installed, may provide better performance\n# due to copying only new and changed files\nUSE_RSYNC=true\nEOF\n\n  chmod +x /usr/lib/armbian/armbian-zram-config\n  systemctl enable armbian-zram-config\n\n  # Swap and Zram tweaks\n  # Page allocation error workout\n  echo \"vm.min_free_kbytes=65536\" >> /etc/sysctl.conf\n  # Modify swappiness parameter\n  echo \"vm.swappiness=100\" >> /etc/sysctl.conf\n\n\n  # Ethereum software installation\n  # Add APT EthRaspbian repository\n  sleep 25\n  echo \"Adding Ethereum repositories\"\n  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8A584409D327B0A5\n  add-apt-repository -n \"deb http://apt.ethraspbian.com bionic main\"\n  add-apt-repository -n \"deb http://apt.ethraspbian.com bionic-security main\"\n  add-apt-repository \"deb http://apt.ethraspbian.com bionic-upgrades main\"\n\n  # Install Ethereum packages\n  echo Installing Ethereum packages\n  apt-get -y install prysm-beacon prysm-validator prysm-slasher lighthouse\n  apt-get -y install geth parity nethermind hyperledger-besu swarm ipfs raiden statusd vipnode\n  # Stop and disable Geth\n  systemctl stop geth\n  systemctl disable geth\n  systemctl disable parity\n  # Enable the beacon chain for next reboot\n  systemctl enable prysm-beacon\n\n  # Create an alias for package updates\n  cat <<EOF >> /etc/bash.bashrc\nalias update-ethereum='\nsudo apt-get update\nsudo apt-get install geth parity nethermind hyperledger-besu swarm ipfs raiden statusd vipnode prysm-beacon prysm-validator prysm-slasher lighthouse'\nEOF\n   # Install monitoring infrastructure\n   wget -P /tmp https://dl.grafana.com/oss/release/grafana_6.7.3_arm64.deb\n   dpkg -i /tmp/grafana_6.7.3_arm64.deb\n   useradd -m prometheus\n   mkdir -p /home/prometheus/node-exporter/\n   chown -R  prometheus:prometheus /home/prometheus/\n   apt install -y prometheus prometheus-node-exporter\n   chown grafana:grafana /root/tmp/grafana.db\n   cp -a /root/tmp/grafana.db /var/lib/grafana/grafana.db\n   cp -a /root/tmp/{prometheus,prometheus-node-exporter} /etc/default\n   cp -a /root/tmp/prometheus.yml /etc/prometheus/\n   systemctl enable grafana-server\n\n   #the next line creates an empty file so it won't run the next boot\n   touch $FLAG\n   reboot\nelse\n   echo \"Nothing to do\"\nfi\n\nexit 0\n"
  },
  {
    "path": "stage2/04-ethereum/files/rc.local.eth2.medalla",
    "content": "#!/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 will \"exit 0\" on success or any other\n# value on error.\n#\n# In order to enable or disable this script just change the execution\n# bits.\n#\n# By default this script does nothing.\n# This script turns the Ubuntu 64 bit image into an Ethereum on ARM image\n#\n\nFLAG=\"/root/first-run.flag\"\nif [ ! -f $FLAG ]; then\n   # Modify hostname (ethnode-$MAC-HASH-CHUNK)\n   echo Changing hostname\n   MAC_HASH=`cat /sys/class/net/eth0/address | sha256sum | awk '{print substr($0,0,9)}'`\n   echo ethnode-$MAC_HASH > /etc/hostname\n   sed -i \"s/127.0.0.1.*/127.0.0.1\\tethnode-$MAC_HASH/g\" /etc/hosts\n\n   # Format USB3 SSD and mount it as /home\n\n   echo Looking for USB drive\n\n   if stat  /dev/sda > /dev/null 2>&1;\n     then\n     \techo USB drive found\n        echo Partitioning and formatting USB Drive...\n        fdisk /dev/sda <<EOF\nd\nn\np\n1\n\n\n\nw\nEOF\n\n\tmkfs.ext4 -F /dev/sda1\n\techo '/dev/sda1 /home ext4 defaults 0 2' >> /etc/fstab && mount /home\n   else\n        echo no SDD detected\n   fi\n\n   # Create Ethereum account\n   echo \"Creating ethereum  user for Geth and Parity\"\n   if ! id -u ethereum >/dev/null 2>&1; then\n\tadduser --disabled-password --gecos \"\" ethereum\n   fi\n\n   echo \"ethereum:ethereum\" | chpasswd\n   for GRP in sudo netdev audio video dialout plugdev bluetooth; do\n\tadduser ethereum $GRP\n   done\n\n   # Force password change on first login\n   chage -d 0 ethereum\n\n# Create some swap memory in the USB device for avoiding memory issues.\n  echo \"Creating swap memory and activating Zram\"\n  if stat  /dev/sda > /dev/null 2>&1;\n\tthen\n\t\tmkdir -p /home/ethereum/swap\n\t\tdd if=/dev/zero of=/home/ethereum/swap/swapfile bs=16k count=256k\n\t\tchmod 600 /home/ethereum/swap/swapfile\n\t\tmkswap /home/ethereum/swap/swapfile\n\t\tswapon /home/ethereum/swap/swapfile\n\t\techo \"/home/ethereum/swap/swapfile none swap sw 0 0\" >> /etc/fstab\n\telse\n\t\techo no swap created\n   fi\n\n# Enable Zram (based on ARMBIAN script)\n  mkdir -p /usr/lib/armbian\n\n  cat << EOF | tee /etc/default/armbian-zram-config >/dev/null\n# configuration values for the armbian-zram-config service\n#\n# enable the armbian-zram-config service\nENABLED=true\nZRAM_PERCENTAGE=25\nEOF\n\n  # Enable Zram (ARMBIAN script)\n  cat << 'EOF' | tee /usr/lib/armbian/armbian-zram-config >/dev/null\n#!/bin/bash\n#\n# Copyright (c) Authors: http://www.armbian.com/authors\n#\n# This file is licensed under the terms of the GNU General Public\n# License version 2. This program is licensed \"as is\" without any\n# warranty of any kind, whether express or implied.\n# Functions:\n#\n# activate_zram_swap\n# activate_ramlog_partition\n# activate_compressed_tmp\n# Read in basic OS image information\n#. /etc/armbian-release\n# and script configuration\n#. /usr/lib/armbian/armbian-common\n# It's possible to override ZRAM_PERCENTAGE, ZRAM_MAX_DEVICES, SWAP_ALGORITHM,\n# RAMLOG_ALGORITHM and TMP_ALGORITHM here:\n[ -f /etc/default/armbian-zram-config ] && . /etc/default/armbian-zram-config\nactivate_zram_swap() {\n\t# Do not interfere with already present config-zram package\n\tdpkg -l | grep -q 'zram-config' && exit 0\n\t[[ \"$ENABLED\" != \"true\" ]] && exit 0\n\t# Load zram module with n instances for swap: one per CPU core, $ZRAM_MAX_DEVICES\n\t# defines the maximum, on modern kernels we overwrite this with 1 and rely on\n\t# max_comp_streams being set to count of CPU cores or $ZRAM_MAX_DEVICES\n\tuname -r | grep -q '^3.' && zram_max_devs=${ZRAM_MAX_DEVICES:=4} || zram_max_devs=1\n\tcpu_cores=$(grep -c '^processor' /proc/cpuinfo | sed 's/^0$/1/')\n\t[[ ${cpu_cores} -gt ${zram_max_devs} ]] && zram_devices=${zram_max_devs} || zram_devices=${cpu_cores}\n\tmodule_args=\"$(modinfo zram | awk -F\" \" '/num_devices/ {print $2}' | cut -f1 -d:)\"\n\t[[ -n ${module_args} ]] && modprobe zram ${module_args}=$(( ${zram_devices} + 2 )) || return\n\t# Expose 50% of real memory as swap space by default\n\tzram_percent=${ZRAM_PERCENTAGE:=50}\n\tmem_info=$(LC_ALL=C free -w 2>/dev/null | grep \"^Mem\" || LC_ALL=C free | grep \"^Mem\")\n\tmemory_total=$(awk '{printf(\"%d\",$2*1024)}' <<<${mem_info})\n\tmem_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${zram_percent} / 100 ))\n\t# Limit memory available to zram to 50% by default\n\tmem_limit_percent=${MEM_LIMIT_PERCENTAGE:=50}\n\tmem_limit_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${mem_limit_percent} / 100 ))\n\tswap_algo=${SWAP_ALGORITHM:=lzo}\n\tfor (( i=1; i<=zram_devices; i++ )); do\n\t\t[[ -f /sys/block/zram${i}/comp_algorithm ]] && echo ${swap_algo} >/sys/block/zram${i}/comp_algorithm 2>/dev/null\n\t\tif [ \"X${ZRAM_BACKING_DEV}\" != \"X\" ]; then\n\t\t\techo ${ZRAM_BACKING_DEV} >/sys/block/zram${i}/backing_dev\n\t\tfi\n\t\techo -n ${ZRAM_MAX_DEVICES:=4} > /sys/block/zram${i}/max_comp_streams\n\t\techo -n ${mem_per_zram_device} > /sys/block/zram${i}/disksize\n\t\techo -n ${mem_limit_per_zram_device} > /sys/block/zram${i}/mem_limit\n\t\tmkswap /dev/zram${i}\n\t\tswapon -p 5 /dev/zram${i}\n\tdone\n\t# Swapping to HDDs is stupid so switch to settings made for flash memory and zram/zswap\n\techo 0 > /proc/sys/vm/page-cluster\n\techo -e \"\\n### Activated ${zram_devices} ${swap_algo} zram swap devices with $(( ${mem_per_zram_device} / 1048576 )) MB each\\n\" >>${Log}\n} # activate_zram_swap\nactivate_ramlog_partition() {\n\t# /dev/zram0 will be used as a compressed /var/log partition in RAM if\n\t# ENABLED=true in /etc/default/armbian-ramlog is set\n\tENABLED=$(awk -F\"=\" '/^ENABLED/ {print $2}' /etc/default/armbian-ramlog)\n\t[[ \"$ENABLED\" != \"true\" ]] && return\n\t\n\t# read size also from /etc/default/armbian-ramlog\n\tramlogsize=$(awk -F\"=\" '/^SIZE/ {print $2}' /etc/default/armbian-ramlog)\n\tdisksize=$(sed -e 's/M$/*1048576/' -e 's/K$/*1024/' <<<${ramlogsize:=50M} | bc)\n\t# choose RAMLOG_ALGORITHM if defined in /etc/default/armbian-zram-config\n\t# otherwise try to choose most efficient compression scheme available.\n\t# See https://patchwork.kernel.org/patch/9918897/\n\tif [ \"X${RAMLOG_ALGORITHM}\" = \"X\" ]; then\n\t\tfor algo in lz4 lz4hc quicklz zlib brotli zstd ; do\n\t\t\techo ${algo} >/sys/block/zram0/comp_algorithm 2>/dev/null\n\t\tdone\n\telse\n\t\techo ${RAMLOG_ALGORITHM} >/sys/block/zram0/comp_algorithm 2>/dev/null\n\tfi\n\techo -n ${disksize} > /sys/block/zram0/disksize\n\t# if it fails, select $swap_algo. Workaround for some older kernels\n\tif [[ $? == 1 ]]; then\n\t\techo ${swap_algo} > /sys/block/zram0/comp_algorithm 2>/dev/null\n\t\techo -n ${disksize} > /sys/block/zram0/disksize\n\tfi\n\tmkfs.ext4 -O ^has_journal -s 1024 -L log2ram /dev/zram0\n\talgo=$(sed 's/.*\\[\\([^]]*\\)\\].*/\\1/g' </sys/block/zram0/comp_algorithm)\n\techo -e \"### Activated Armbian ramlog partition with ${algo} compression\" >>${Log}\n} # activate_ramlog_partition\nactivate_compressed_tmp() {\n\t# create /tmp not as tmpfs but zram compressed if no fstab entry exists\n\tgrep -q '^tmpfs /tmp' /etc/mtab && return\n\ttmp_device=$(( ${zram_devices} + 1 ))\n\tif [[ -f /sys/block/zram${tmp_device}/comp_algorithm ]]; then\n\t\tif [ \"X${TMP_ALGORITHM}\" = \"X\" ]; then\n\t\t\techo ${swap_algo} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null\n\t\telse\n\t\t\techo ${TMP_ALGORITHM} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null\n\t\tfi\n\tfi\n\techo -n $(( ${memory_total} / 2 )) > /sys/block/zram${tmp_device}/disksize\n\tmkfs.ext4 -O ^has_journal -s 1024 -L tmp /dev/zram${tmp_device}\n\tmount -o nosuid,discard /dev/zram${tmp_device} /tmp\n\tchmod 777 /tmp\n\talgo=$(sed 's/.*\\[\\([^]]*\\)\\].*/\\1/g' </sys/block/zram${tmp_device}/comp_algorithm)\n} # activate_compressed_tmp\ncase $1 in\n\t*start*)\n\t\tactivate_zram_swap\n\t\tactivate_ramlog_partition\n\t\tactivate_compressed_tmp\n\t\t;;\nesac\nEOF\n\n  cat << 'EOF' | tee /etc/systemd/system/armbian-zram-config.service >/dev/null\n# Armbian ZRAM configuration service\n# Create 1 + number of cores compressed block devices\n# This service may block the boot process for up to 30 sec\n[Unit]\nDescription=Armbian ZRAM config\nDefaultDependencies=no\nAfter=local-fs.target\nBefore=armbian-ramlog.target\nConflicts=shutdown.target\n[Service]\nType=oneshot\nExecStart=/usr/lib/armbian/armbian-zram-config start\nExecStop=/usr/lib/armbian/armbian-zram-config stop\nRemainAfterExit=yes\nTimeoutStartSec=30sec\n[Install]\nWantedBy=sysinit.target\nEOF\n\n  cat << 'EOF' | tee /etc/default/armbian-ramlog >/dev/null\n# configuration values for the armbian-ram-logging service\n#\n# enable the armbian-ram-logging service?\nENABLED=true\n#\n# size of the tmpfs mount -- please keep in mind to adjust /etc/default/armbian-zram-config too when increasing\nSIZE=50M\n#\n# use rsync instead of cp -r\n# requires rsync installed, may provide better performance\n# due to copying only new and changed files\nUSE_RSYNC=true\nEOF\n\n  chmod +x /usr/lib/armbian/armbian-zram-config\n  systemctl enable armbian-zram-config\n\n  # Swap and Zram tweaks\n  # Page allocation error workout\n  echo \"vm.min_free_kbytes=65536\" >> /etc/sysctl.conf\n  # Modify swappiness parameter\n  echo \"vm.swappiness=100\" >> /etc/sysctl.conf\n\n\n  # Ethereum software installation\n  # Add APT EthRaspbian repository\n  sleep 25\n  echo \"Adding Ethereum repositories\"\n  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8A584409D327B0A5\n  add-apt-repository -n \"deb http://apt.ethraspbian.com bionic main\"\n  add-apt-repository -n \"deb http://apt.ethraspbian.com bionic-security main\"\n  add-apt-repository \"deb http://apt.ethraspbian.com bionic-upgrades main\"\n\n  # Install Ethereum packages\n  echo Installing Ethereum packages\n  apt-get -y install prysm-beacon prysm-validator prysm-slasher lighthouse teku nimbus eth2.0-deposit-cli\n  apt-get -y install geth\n  # Stop Geth\n  systemctl stop geth\n\n  # Modify config params for Medalla\n  echo 'ARGS=\"--goerli --http --metrics --metrics.expensive --pprof --maxpeers 50\"' > /etc/ethereum/geth.conf\n#  echo 'ARGS=\"--http-web3provider http://localhost:8545\"' > /etc/ethereum/prysm-beacon.conf\n\n   # Install monitoring infrastructure\n   apt install -y fontconfig-config fonts-dejavu-core libfontconfig1 libfreetype6\n   wget https://dl.grafana.com/oss/release/grafana_7.0.4_arm64.deb\n   dpkg -i grafana_7.0.4_arm64.deb\n   useradd -m prometheus\n   mkdir -p /home/prometheus/node-exporter/\n   chown -R  prometheus:prometheus /home/prometheus/\n   apt install -y prometheus prometheus-node-exporter\n   chown grafana:grafana /root/tmp/grafana.db\n   cp -a /root/tmp/grafana.db /var/lib/grafana/grafana.db\n   cp -a /root/tmp/{prometheus,prometheus-node-exporter} /etc/default\n   cp -a /root/tmp/prometheus.yml /etc/prometheus/\n   systemctl enable grafana-server\n\n   #the next line creates an empty file so it won't run the next boot\n   touch $FLAG\n   reboot\nelse\n   echo \"Nothing to do\"\nfi\n\nexit 0\n"
  },
  {
    "path": "stage2/04-ethereum/files/rc.local.eth2.onyx",
    "content": "#!/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 will \"exit 0\" on success or any other\n# value on error.\n#\n# In order to enable or disable this script just change the execution\n# bits.\n#\n# By default this script does nothing.\n# This script turns the Ubuntu 64 bit image into an Ethereum on ARM image\n#\n\nFLAG=\"/root/first-run.flag\"\nif [ ! -f $FLAG ]; then\n   # Modify hostname (ethnode-$MAC-HASH-CHUNK)\n   echo Changing hostname\n   MAC_HASH=`cat /sys/class/net/eth0/address | sha256sum | awk '{print substr($0,0,9)}'`\n   echo ethnode-$MAC_HASH > /etc/hostname\n   sed -i \"s/127.0.0.1.*/127.0.0.1\\tethnode-$MAC_HASH/g\" /etc/hosts\n\n   # Format USB3 SSD and mount it as /home\n\n   echo Looking for USB drive\n\n   if stat  /dev/sda > /dev/null 2>&1;\n     then\n     \techo USB drive found\n        echo Partitioning and formatting USB Drive...\n        fdisk /dev/sda <<EOF\nd\nn\np\n1\n\n\n\nw\nEOF\n\n\tmkfs.ext4 -F /dev/sda1\n\techo '/dev/sda1 /home ext4 defaults 0 2' >> /etc/fstab && mount /home\n   else\n        echo no SDD detected\n   fi\n\n   # Create Ethereum account\n   echo \"Creating ethereum  user for Geth and Parity\"\n   if ! id -u ethereum >/dev/null 2>&1; then\n\tadduser --disabled-password --gecos \"\" ethereum\n   fi\n\n   echo \"ethereum:ethereum\" | chpasswd\n   for GRP in sudo netdev audio video dialout plugdev bluetooth; do\n\tadduser ethereum $GRP\n   done\n\n   # Force password change on first login\n   chage -d 0 ethereum\n\n# Create some swap memory in the USB device for avoiding memory issues.\n  echo \"Creating swap memory and activating Zram\"\n  if stat  /dev/sda > /dev/null 2>&1;\n\tthen\n\t\tmkdir -p /home/ethereum/swap\n\t\tdd if=/dev/zero of=/home/ethereum/swap/swapfile bs=16k count=256k\n\t\tchmod 600 /home/ethereum/swap/swapfile\n\t\tmkswap /home/ethereum/swap/swapfile\n\t\tswapon /home/ethereum/swap/swapfile\n\t\techo \"/home/ethereum/swap/swapfile none swap sw 0 0\" >> /etc/fstab\n\telse\n\t\techo no swap created\n   fi\n\n# Enable Zram (based on ARMBIAN script)\n  mkdir -p /usr/lib/armbian\n\n  cat << EOF | tee /etc/default/armbian-zram-config >/dev/null\n# configuration values for the armbian-zram-config service\n#\n# enable the armbian-zram-config service\nENABLED=true\nZRAM_PERCENTAGE=25\nEOF\n\n  # Enable Zram (ARMBIAN script)\n  cat << 'EOF' | tee /usr/lib/armbian/armbian-zram-config >/dev/null\n#!/bin/bash\n#\n# Copyright (c) Authors: http://www.armbian.com/authors\n#\n# This file is licensed under the terms of the GNU General Public\n# License version 2. This program is licensed \"as is\" without any\n# warranty of any kind, whether express or implied.\n# Functions:\n#\n# activate_zram_swap\n# activate_ramlog_partition\n# activate_compressed_tmp\n# Read in basic OS image information\n#. /etc/armbian-release\n# and script configuration\n#. /usr/lib/armbian/armbian-common\n# It's possible to override ZRAM_PERCENTAGE, ZRAM_MAX_DEVICES, SWAP_ALGORITHM,\n# RAMLOG_ALGORITHM and TMP_ALGORITHM here:\n[ -f /etc/default/armbian-zram-config ] && . /etc/default/armbian-zram-config\nactivate_zram_swap() {\n\t# Do not interfere with already present config-zram package\n\tdpkg -l | grep -q 'zram-config' && exit 0\n\t[[ \"$ENABLED\" != \"true\" ]] && exit 0\n\t# Load zram module with n instances for swap: one per CPU core, $ZRAM_MAX_DEVICES\n\t# defines the maximum, on modern kernels we overwrite this with 1 and rely on\n\t# max_comp_streams being set to count of CPU cores or $ZRAM_MAX_DEVICES\n\tuname -r | grep -q '^3.' && zram_max_devs=${ZRAM_MAX_DEVICES:=4} || zram_max_devs=1\n\tcpu_cores=$(grep -c '^processor' /proc/cpuinfo | sed 's/^0$/1/')\n\t[[ ${cpu_cores} -gt ${zram_max_devs} ]] && zram_devices=${zram_max_devs} || zram_devices=${cpu_cores}\n\tmodule_args=\"$(modinfo zram | awk -F\" \" '/num_devices/ {print $2}' | cut -f1 -d:)\"\n\t[[ -n ${module_args} ]] && modprobe zram ${module_args}=$(( ${zram_devices} + 2 )) || return\n\t# Expose 50% of real memory as swap space by default\n\tzram_percent=${ZRAM_PERCENTAGE:=50}\n\tmem_info=$(LC_ALL=C free -w 2>/dev/null | grep \"^Mem\" || LC_ALL=C free | grep \"^Mem\")\n\tmemory_total=$(awk '{printf(\"%d\",$2*1024)}' <<<${mem_info})\n\tmem_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${zram_percent} / 100 ))\n\t# Limit memory available to zram to 50% by default\n\tmem_limit_percent=${MEM_LIMIT_PERCENTAGE:=50}\n\tmem_limit_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${mem_limit_percent} / 100 ))\n\tswap_algo=${SWAP_ALGORITHM:=lzo}\n\tfor (( i=1; i<=zram_devices; i++ )); do\n\t\t[[ -f /sys/block/zram${i}/comp_algorithm ]] && echo ${swap_algo} >/sys/block/zram${i}/comp_algorithm 2>/dev/null\n\t\tif [ \"X${ZRAM_BACKING_DEV}\" != \"X\" ]; then\n\t\t\techo ${ZRAM_BACKING_DEV} >/sys/block/zram${i}/backing_dev\n\t\tfi\n\t\techo -n ${ZRAM_MAX_DEVICES:=4} > /sys/block/zram${i}/max_comp_streams\n\t\techo -n ${mem_per_zram_device} > /sys/block/zram${i}/disksize\n\t\techo -n ${mem_limit_per_zram_device} > /sys/block/zram${i}/mem_limit\n\t\tmkswap /dev/zram${i}\n\t\tswapon -p 5 /dev/zram${i}\n\tdone\n\t# Swapping to HDDs is stupid so switch to settings made for flash memory and zram/zswap\n\techo 0 > /proc/sys/vm/page-cluster\n\techo -e \"\\n### Activated ${zram_devices} ${swap_algo} zram swap devices with $(( ${mem_per_zram_device} / 1048576 )) MB each\\n\" >>${Log}\n} # activate_zram_swap\nactivate_ramlog_partition() {\n\t# /dev/zram0 will be used as a compressed /var/log partition in RAM if\n\t# ENABLED=true in /etc/default/armbian-ramlog is set\n\tENABLED=$(awk -F\"=\" '/^ENABLED/ {print $2}' /etc/default/armbian-ramlog)\n\t[[ \"$ENABLED\" != \"true\" ]] && return\n\t\n\t# read size also from /etc/default/armbian-ramlog\n\tramlogsize=$(awk -F\"=\" '/^SIZE/ {print $2}' /etc/default/armbian-ramlog)\n\tdisksize=$(sed -e 's/M$/*1048576/' -e 's/K$/*1024/' <<<${ramlogsize:=50M} | bc)\n\t# choose RAMLOG_ALGORITHM if defined in /etc/default/armbian-zram-config\n\t# otherwise try to choose most efficient compression scheme available.\n\t# See https://patchwork.kernel.org/patch/9918897/\n\tif [ \"X${RAMLOG_ALGORITHM}\" = \"X\" ]; then\n\t\tfor algo in lz4 lz4hc quicklz zlib brotli zstd ; do\n\t\t\techo ${algo} >/sys/block/zram0/comp_algorithm 2>/dev/null\n\t\tdone\n\telse\n\t\techo ${RAMLOG_ALGORITHM} >/sys/block/zram0/comp_algorithm 2>/dev/null\n\tfi\n\techo -n ${disksize} > /sys/block/zram0/disksize\n\t# if it fails, select $swap_algo. Workaround for some older kernels\n\tif [[ $? == 1 ]]; then\n\t\techo ${swap_algo} > /sys/block/zram0/comp_algorithm 2>/dev/null\n\t\techo -n ${disksize} > /sys/block/zram0/disksize\n\tfi\n\tmkfs.ext4 -O ^has_journal -s 1024 -L log2ram /dev/zram0\n\talgo=$(sed 's/.*\\[\\([^]]*\\)\\].*/\\1/g' </sys/block/zram0/comp_algorithm)\n\techo -e \"### Activated Armbian ramlog partition with ${algo} compression\" >>${Log}\n} # activate_ramlog_partition\nactivate_compressed_tmp() {\n\t# create /tmp not as tmpfs but zram compressed if no fstab entry exists\n\tgrep -q '^tmpfs /tmp' /etc/mtab && return\n\ttmp_device=$(( ${zram_devices} + 1 ))\n\tif [[ -f /sys/block/zram${tmp_device}/comp_algorithm ]]; then\n\t\tif [ \"X${TMP_ALGORITHM}\" = \"X\" ]; then\n\t\t\techo ${swap_algo} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null\n\t\telse\n\t\t\techo ${TMP_ALGORITHM} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null\n\t\tfi\n\tfi\n\techo -n $(( ${memory_total} / 2 )) > /sys/block/zram${tmp_device}/disksize\n\tmkfs.ext4 -O ^has_journal -s 1024 -L tmp /dev/zram${tmp_device}\n\tmount -o nosuid,discard /dev/zram${tmp_device} /tmp\n\tchmod 777 /tmp\n\talgo=$(sed 's/.*\\[\\([^]]*\\)\\].*/\\1/g' </sys/block/zram${tmp_device}/comp_algorithm)\n} # activate_compressed_tmp\ncase $1 in\n\t*start*)\n\t\tactivate_zram_swap\n\t\tactivate_ramlog_partition\n\t\tactivate_compressed_tmp\n\t\t;;\nesac\nEOF\n\n  cat << 'EOF' | tee /etc/systemd/system/armbian-zram-config.service >/dev/null\n# Armbian ZRAM configuration service\n# Create 1 + number of cores compressed block devices\n# This service may block the boot process for up to 30 sec\n[Unit]\nDescription=Armbian ZRAM config\nDefaultDependencies=no\nAfter=local-fs.target\nBefore=armbian-ramlog.target\nConflicts=shutdown.target\n[Service]\nType=oneshot\nExecStart=/usr/lib/armbian/armbian-zram-config start\nExecStop=/usr/lib/armbian/armbian-zram-config stop\nRemainAfterExit=yes\nTimeoutStartSec=30sec\n[Install]\nWantedBy=sysinit.target\nEOF\n\n  cat << 'EOF' | tee /etc/default/armbian-ramlog >/dev/null\n# configuration values for the armbian-ram-logging service\n#\n# enable the armbian-ram-logging service?\nENABLED=true\n#\n# size of the tmpfs mount -- please keep in mind to adjust /etc/default/armbian-zram-config too when increasing\nSIZE=50M\n#\n# use rsync instead of cp -r\n# requires rsync installed, may provide better performance\n# due to copying only new and changed files\nUSE_RSYNC=true\nEOF\n\n  chmod +x /usr/lib/armbian/armbian-zram-config\n  systemctl enable armbian-zram-config\n\n  # Swap and Zram tweaks\n  # Page allocation error workout\n  echo \"vm.min_free_kbytes=65536\" >> /etc/sysctl.conf\n  # Modify swappiness parameter\n  echo \"vm.swappiness=100\" >> /etc/sysctl.conf\n\n\n  # Ethereum software installation\n  # Add APT EthRaspbian repository\n  sleep 25\n  echo \"Adding Ethereum repositories\"\n  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8A584409D327B0A5\n  add-apt-repository -n \"deb http://apt.ethraspbian.com bionic main\"\n  add-apt-repository -n \"deb http://apt.ethraspbian.com bionic-security main\"\n  add-apt-repository \"deb http://apt.ethraspbian.com bionic-upgrades main\"\n\n  # Install Ethereum packages\n  echo Installing Ethereum packages\n  apt-get -y install prysm-beacon prysm-validator prysm-slasher\n  apt-get -y install geth\n  # Stop Geth\n  systemctl stop geth\n  # Enable the beacon chain for next reboot\n  systemctl enable prysm-beacon\n\n  # Modify config params for Onyx\n  echo 'ARGS=\"--goerli --http --metrics --metrics.expensive --pprof --maxpeers 50\"' > /etc/ethereum/geth.conf\n  echo 'ARGS=\"--http-web3provider http://localhost:8545\"' > /etc/ethereum/prysm-beacon.conf\n\n  # Create an alias for package updates\n  cat <<EOF >> /etc/bash.bashrc\nalias update-ethereum='\nsudo apt-get update\nsudo apt-get install geth parity nethermind hyperledger-besu swarm ipfs raiden statusd vipnode prysm-beacon prysm-validator prysm-slasher lighthouse'\nEOF\n   # Install monitoring infrastructure\n   apt install -y fontconfig-config fonts-dejavu-core libfontconfig1 libfreetype6\n   wget https://dl.grafana.com/oss/release/grafana_7.0.4_arm64.deb\n   dpkg -i grafana_7.0.4_arm64.deb\n   useradd -m prometheus\n   mkdir -p /home/prometheus/node-exporter/\n   chown -R  prometheus:prometheus /home/prometheus/\n   apt install -y prometheus prometheus-node-exporter\n   chown grafana:grafana /root/tmp/grafana.db\n   cp -a /root/tmp/grafana.db /var/lib/grafana/grafana.db\n   cp -a /root/tmp/{prometheus,prometheus-node-exporter} /etc/default\n   cp -a /root/tmp/prometheus.yml /etc/prometheus/\n   systemctl enable grafana-server\n\n   #the next line creates an empty file so it won't run the next boot\n   touch $FLAG\n   reboot\nelse\n   echo \"Nothing to do\"\nfi\n\nexit 0\n"
  },
  {
    "path": "stage2/04-ethereum/files/zram-default/armbian-zram-config",
    "content": "# configuration values for the armbian-zram-config service\n#\n# enable the armbian-zram-config service\nENABLED=true\nZRAM_PERCENTAGE=25\n"
  },
  {
    "path": "stage2/04-ethereum/files/zram-lib/armbian-zram-config",
    "content": "#!/bin/bash\n#\n# Copyright (c) Authors: http://www.armbian.com/authors\n#\n# This file is licensed under the terms of the GNU General Public\n# License version 2. This program is licensed \"as is\" without any\n# warranty of any kind, whether express or implied.\n# Functions:\n#\n# activate_zram_swap\n# activate_ramlog_partition\n# activate_compressed_tmp\n# Read in basic OS image information\n#. /etc/armbian-release\n# and script configuration\n#. /usr/lib/armbian/armbian-common\n# It's possible to override ZRAM_PERCENTAGE, ZRAM_MAX_DEVICES, SWAP_ALGORITHM,\n# RAMLOG_ALGORITHM and TMP_ALGORITHM here:\n[ -f /etc/default/armbian-zram-config ] && . /etc/default/armbian-zram-config\nactivate_zram_swap() {\n\t# Do not interfere with already present config-zram package\n\tdpkg -l | grep -q 'zram-config' && exit 0\n\t[[ \"$ENABLED\" != \"true\" ]] && exit 0\n\t# Load zram module with n instances for swap: one per CPU core, $ZRAM_MAX_DEVICES\n\t# defines the maximum, on modern kernels we overwrite this with 1 and rely on\n\t# max_comp_streams being set to count of CPU cores or $ZRAM_MAX_DEVICES\n\tuname -r | grep -q '^3.' && zram_max_devs=${ZRAM_MAX_DEVICES:=4} || zram_max_devs=1\n\tcpu_cores=$(grep -c '^processor' /proc/cpuinfo | sed 's/^0$/1/')\n\t[[ ${cpu_cores} -gt ${zram_max_devs} ]] && zram_devices=${zram_max_devs} || zram_devices=${cpu_cores}\n\tmodule_args=\"$(modinfo zram | awk -F\" \" '/num_devices/ {print $2}' | cut -f1 -d:)\"\n\t[[ -n ${module_args} ]] && modprobe zram ${module_args}=$(( ${zram_devices} + 2 )) || return\n\t# Expose 50% of real memory as swap space by default\n\tzram_percent=${ZRAM_PERCENTAGE:=50}\n\tmem_info=$(LC_ALL=C free -w 2>/dev/null | grep \"^Mem\" || LC_ALL=C free | grep \"^Mem\")\n\tmemory_total=$(awk '{printf(\"%d\",$2*1024)}' <<<${mem_info})\n\tmem_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${zram_percent} / 100 ))\n\t# Limit memory available to zram to 50% by default\n\tmem_limit_percent=${MEM_LIMIT_PERCENTAGE:=50}\n\tmem_limit_per_zram_device=$(( ${memory_total} / ${zram_devices} * ${mem_limit_percent} / 100 ))\n\tswap_algo=${SWAP_ALGORITHM:=lzo}\n\tfor (( i=1; i<=zram_devices; i++ )); do\n\t\t[[ -f /sys/block/zram${i}/comp_algorithm ]] && echo ${swap_algo} >/sys/block/zram${i}/comp_algorithm 2>/dev/null\n\t\tif [ \"X${ZRAM_BACKING_DEV}\" != \"X\" ]; then\n\t\t\techo ${ZRAM_BACKING_DEV} >/sys/block/zram${i}/backing_dev\n\t\tfi\n\t\techo -n ${ZRAM_MAX_DEVICES:=4} > /sys/block/zram${i}/max_comp_streams\n\t\techo -n ${mem_per_zram_device} > /sys/block/zram${i}/disksize\n\t\techo -n ${mem_limit_per_zram_device} > /sys/block/zram${i}/mem_limit\n\t\tmkswap /dev/zram${i}\n\t\tswapon -p 5 /dev/zram${i}\n\tdone\n\t# Swapping to HDDs is stupid so switch to settings made for flash memory and zram/zswap\n\techo 0 > /proc/sys/vm/page-cluster\n\techo -e \"\\n### Activated ${zram_devices} ${swap_algo} zram swap devices with $(( ${mem_per_zram_device} / 1048576 )) MB each\\n\" >>${Log}\n} # activate_zram_swap\nactivate_ramlog_partition() {\n\t# /dev/zram0 will be used as a compressed /var/log partition in RAM if\n\t# ENABLED=true in /etc/default/armbian-ramlog is set\n\tENABLED=$(awk -F\"=\" '/^ENABLED/ {print $2}' /etc/default/armbian-ramlog)\n\t[[ \"$ENABLED\" != \"true\" ]] && return\n\t\n\t# read size also from /etc/default/armbian-ramlog\n\tramlogsize=$(awk -F\"=\" '/^SIZE/ {print $2}' /etc/default/armbian-ramlog)\n\tdisksize=$(sed -e 's/M$/*1048576/' -e 's/K$/*1024/' <<<${ramlogsize:=50M} | bc)\n\t# choose RAMLOG_ALGORITHM if defined in /etc/default/armbian-zram-config\n\t# otherwise try to choose most efficient compression scheme available.\n\t# See https://patchwork.kernel.org/patch/9918897/\n\tif [ \"X${RAMLOG_ALGORITHM}\" = \"X\" ]; then\n\t\tfor algo in lz4 lz4hc quicklz zlib brotli zstd ; do\n\t\t\techo ${algo} >/sys/block/zram0/comp_algorithm 2>/dev/null\n\t\tdone\n\telse\n\t\techo ${RAMLOG_ALGORITHM} >/sys/block/zram0/comp_algorithm 2>/dev/null\n\tfi\n\techo -n ${disksize} > /sys/block/zram0/disksize\n\t# if it fails, select $swap_algo. Workaround for some older kernels\n\tif [[ $? == 1 ]]; then\n\t\techo ${swap_algo} > /sys/block/zram0/comp_algorithm 2>/dev/null\n\t\techo -n ${disksize} > /sys/block/zram0/disksize\n\tfi\n\tmkfs.ext4 -O ^has_journal -s 1024 -L log2ram /dev/zram0\n\talgo=$(sed 's/.*\\[\\([^]]*\\)\\].*/\\1/g' </sys/block/zram0/comp_algorithm)\n\techo -e \"### Activated Armbian ramlog partition with ${algo} compression\" >>${Log}\n} # activate_ramlog_partition\nactivate_compressed_tmp() {\n\t# create /tmp not as tmpfs but zram compressed if no fstab entry exists\n\tgrep -q '^tmpfs /tmp' /etc/mtab && return\n\ttmp_device=$(( ${zram_devices} + 1 ))\n\tif [[ -f /sys/block/zram${tmp_device}/comp_algorithm ]]; then\n\t\tif [ \"X${TMP_ALGORITHM}\" = \"X\" ]; then\n\t\t\techo ${swap_algo} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null\n\t\telse\n\t\t\techo ${TMP_ALGORITHM} >/sys/block/zram${tmp_device}/comp_algorithm 2>/dev/null\n\t\tfi\n\tfi\n\techo -n $(( ${memory_total} / 2 )) > /sys/block/zram${tmp_device}/disksize\n\tmkfs.ext4 -O ^has_journal -s 1024 -L tmp /dev/zram${tmp_device}\n\tmount -o nosuid,discard /dev/zram${tmp_device} /tmp\n\tchmod 777 /tmp\n\talgo=$(sed 's/.*\\[\\([^]]*\\)\\].*/\\1/g' </sys/block/zram${tmp_device}/comp_algorithm)\n} # activate_compressed_tmp\ncase $1 in\n\t*start*)\n\t\tactivate_zram_swap\n\t\tactivate_ramlog_partition\n\t\tactivate_compressed_tmp\n\t\t;;\nesac\n"
  },
  {
    "path": "stage2/EXPORT_IMAGE",
    "content": "IMG_SUFFIX=\"-lite\"\nif [ \"${USE_QEMU}\" = \"1\" ]; then\n\texport IMG_SUFFIX=\"${IMG_SUFFIX}-qemu\"\nfi\n"
  },
  {
    "path": "stage2/EXPORT_NOOBS",
    "content": "NOOBS_NAME=\"Raspbian Lite\"\nNOOBS_DESCRIPTION=\"A port of Debian with no desktop environment\"\n"
  },
  {
    "path": "stage2/prerun.sh",
    "content": "#!/bin/bash -e\n\nif [ ! -d \"${ROOTFS_DIR}\" ]; then\n\tcopy_previous\nfi\n"
  },
  {
    "path": "stage3/00-install-packages/00-debconf",
    "content": "# Adobe Flash Player. Copyright 1996-2015. Adobe Systems Incorporated. All Rights Reserved.\nrpi-chromium-mods\trpi-chromium-mods/adobe\tnote\n"
  },
  {
    "path": "stage3/00-install-packages/00-packages",
    "content": "gstreamer1.0-x gstreamer1.0-omx gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-alsa gstreamer1.0-libav\nqpdfview gtk2-engines alsa-utils\ndesktop-base\ngit\nomxplayer\nraspberrypi-artwork\npolicykit-1\ngvfs\nrfkill\nchromium-browser rpi-chromium-mods\ngldriver-test\nfonts-droid-fallback\nfonts-liberation2\nobconf\narandr\n"
  },
  {
    "path": "stage3/00-install-packages/00-packages-nr",
    "content": "xserver-xorg-video-fbdev xserver-xorg xinit xserver-xorg-video-fbturbo\nepiphany-browser\nlxde lxtask menu-xdg\nzenity xdg-utils\ngvfs-backends gvfs-fuse\nlightdm gnome-themes-standard-data gnome-icon-theme\n"
  },
  {
    "path": "stage3/00-install-packages/01-run.sh",
    "content": "#!/bin/bash -e\n\non_chroot << EOF\nupdate-alternatives --install /usr/bin/x-www-browser \\\n  x-www-browser /usr/bin/chromium-browser 86\nupdate-alternatives --install /usr/bin/gnome-www-browser \\\n  gnome-www-browser /usr/bin/chromium-browser 86\nEOF\n"
  },
  {
    "path": "stage3/01-tweaks/00-run.sh",
    "content": "#!/bin/bash -e\n\nrm -f \"${ROOTFS_DIR}/etc/systemd/system/dhcpcd.service.d/wait.conf\"\n"
  },
  {
    "path": "stage3/prerun.sh",
    "content": "#!/bin/bash -e\n\nif [ ! -d \"${ROOTFS_DIR}\" ]; then\n\tcopy_previous\nfi\n"
  },
  {
    "path": "stage4/00-install-packages/00-debconf",
    "content": "# Enable realtime process priority?\njackd2  jackd/tweak_rt_limits   boolean true\n"
  },
  {
    "path": "stage4/00-install-packages/00-packages",
    "content": "python python3-pygame python-pygame python-tk\npython3 python3-tk python3-thonny\npython3-pgzero\npython-serial python3-serial\npython-picamera python3-picamera\ndebian-reference-en dillo\nraspberrypi-net-mods raspberrypi-ui-mods\npython-pip python3-pip\npython3-numpy\npypy\nalacarte rc-gui sense-hat\ntree\nlibgl1-mesa-dri libgles1 libgles2-mesa xcompmgr\ngeany\npiclone\nwiringpi pigpio python-pigpio python3-pigpio raspi-gpio python-gpiozero python3-gpiozero python3-rpi.gpio\npython-spidev python3-spidev\npython-twython python3-twython\npython-smbus python3-smbus\npython-flask python3-flask\npython-picraft python3-picraft\npprompt\npiwiz\nrp-prefapps\nffmpeg\nvlc\n"
  },
  {
    "path": "stage4/00-install-packages/00-packages-nr",
    "content": "pi-package\nrealvnc-vnc-server\n"
  },
  {
    "path": "stage4/00-install-packages/01-packages",
    "content": "python-automationhat python3-automationhat\npython-blinkt python3-blinkt\npython-cap1xxx python3-cap1xxx\npython-drumhat python3-drumhat\npython-envirophat python3-envirophat\npython-explorerhat python3-explorerhat\npython-fourletterphat python3-fourletterphat\npython-microdotphat python3-microdotphat\npython-mote python3-mote\npython-motephat python3-motephat\npython-phatbeat python3-phatbeat\npython-pianohat python3-pianohat\npython-piglow python3-piglow\npython-rainbowhat python3-rainbowhat\npython-scrollphat python3-scrollphat\npython-scrollphathd python3-scrollphathd\npython-sn3218 python3-sn3218\npython-skywriter python3-skywriter\npython-touchphat python3-touchphat\npython-buttonshim python3-buttonshim\npython-unicornhathd  python3-unicornhathd\npython-pantilthat python3-pantilthat\n"
  },
  {
    "path": "stage4/00-install-packages/02-packages",
    "content": "hunspell-en-gb\nhyphen-en-gb\nwamerican\nwbritish\n"
  },
  {
    "path": "stage4/01-console-autologin/00-run.sh",
    "content": "#!/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",
    "content": "#!/bin/bash -e\n\n#Alacarte fixes\ninstall -v -o 1000 -g 1000 -d \"${ROOTFS_DIR}/home/${FIRST_USER_NAME}/.local\"\ninstall -v -o 1000 -g 1000 -d \"${ROOTFS_DIR}/home/${FIRST_USER_NAME}/.local/share\"\ninstall -v -o 1000 -g 1000 -d \"${ROOTFS_DIR}/home/${FIRST_USER_NAME}/.local/share/applications\"\ninstall -v -o 1000 -g 1000 -d \"${ROOTFS_DIR}/home/${FIRST_USER_NAME}/.local/share/desktop-directories\"\n"
  },
  {
    "path": "stage4/03-magpi/00-run.sh",
    "content": "#!/bin/sh -e\n\nmagpi_regex=\"MagPi[[:digit:]]*.pdf\"\nmagpi_loc=\"https://www.raspberrypi.org/magpi-issues\"\nmagpi_latest=\"$(curl \"$magpi_loc/?C=M;O=D\" -s | grep \"$magpi_regex\" -m 1 -o | head -n 1)\"\n\nif [ ! -f \"files/$magpi_latest\" ]; then\n\tfind files/ -regextype grep -regex \"files/$magpi_regex\" -delete\n\twget \"$magpi_loc/$magpi_latest\" -O \"files/$magpi_latest\"\nfi\n\nfile \"files/$magpi_latest\" | grep -q \"PDF document\"\n\ninstall -v -o 1000 -g 1000 -d \"${ROOTFS_DIR}/home/${FIRST_USER_NAME}/MagPi\"\ninstall -v -o 1000 -g 1000 -m 644 \"files/$magpi_latest\" \"${ROOTFS_DIR}/home/${FIRST_USER_NAME}/MagPi/\"\n"
  },
  {
    "path": "stage4/03-magpi/files/.gitignore",
    "content": "*.pdf\n"
  },
  {
    "path": "stage4/04-enable-xcompmgr/00-run.sh",
    "content": "#!/bin/bash -e\n\non_chroot << EOF\n\traspi-config nonint do_xcompmgr 0\nEOF\n"
  },
  {
    "path": "stage4/EXPORT_IMAGE",
    "content": "IMG_SUFFIX=\"\"\nif [ \"${USE_QEMU}\" = \"1\" ]; then\n\texport IMG_SUFFIX=\"${IMG_SUFFIX}-qemu\"\nfi\n"
  },
  {
    "path": "stage4/EXPORT_NOOBS",
    "content": "NOOBS_NAME=\"Raspbian\"\nNOOBS_DESCRIPTION=\"A port of Debian with the Raspberry Pi Desktop\"\n"
  },
  {
    "path": "stage4/prerun.sh",
    "content": "#!/bin/bash -e\n\nif [ ! -d \"${ROOTFS_DIR}\" ]; then\n\tcopy_previous\nfi\n"
  },
  {
    "path": "stage5/00-install-extras/00-packages",
    "content": "mu-editor\nsonic-pi\nscratch nuscratch scratch2\nsmartsim\n\nminecraft-pi python-minecraftpi\npython-sense-emu sense-emu-tools python-sense-emu-doc\n\nclaws-mail\ngreenfoot-unbundled bluej\nnodered\nrealvnc-vnc-viewer\n\npython-games\n"
  },
  {
    "path": "stage5/00-install-libreoffice/00-packages",
    "content": "libreoffice-pi\nlibreoffice-help-en-gb\nlibreoffice-l10n-en-gb\n"
  },
  {
    "path": "stage5/EXPORT_IMAGE",
    "content": "IMG_SUFFIX=\"-full\"\nif [ \"${USE_QEMU}\" = \"1\" ]; then\n\texport IMG_SUFFIX=\"${IMG_SUFFIX}-qemu\"\nfi\n"
  },
  {
    "path": "stage5/EXPORT_NOOBS",
    "content": "NOOBS_NAME=\"Raspbian Full\"\nNOOBS_DESCRIPTION=\"A port of Debian with desktop and recommended applications\"\n"
  },
  {
    "path": "stage5/prerun.sh",
    "content": "#!/bin/bash -e\n\nif [ ! -d \"${ROOTFS_DIR}\" ]; then\n\tcopy_previous\nfi\n"
  }
]