Compare commits
6 commits
yunohost-b
...
yunohost-s
Author | SHA1 | Date | |
---|---|---|---|
|
5fc15bbd6c | ||
|
ad19a25249 | ||
|
5ddbc1692c | ||
|
bd0f49e4f8 | ||
|
d9ed7ea44f | ||
|
14da13285f |
45 changed files with 188 additions and 1351 deletions
39
.github/workflows/main.yml
vendored
39
.github/workflows/main.yml
vendored
|
@ -1,39 +0,0 @@
|
|||
# This is a basic workflow to help you get started with Actions
|
||||
|
||||
name: Build yunohost rpi image
|
||||
|
||||
# Controls when the workflow will run
|
||||
on:
|
||||
# Triggers the workflow on push or pull request events but only for the "yunohost-buster" branch
|
||||
push:
|
||||
branches: [ "yunohost-bullseye" ]
|
||||
pull_request:
|
||||
branches: [ "yunohost-bullseye" ]
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
# This workflow contains a single job called "build"
|
||||
build:
|
||||
# The type of runner that the job will run on
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
# Runs a set of commands using the runners shell
|
||||
- name: Run a multi-line script
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt-get -y install coreutils quilt parted qemu-user-static debootstrap zerofree zip dosfstools libarchive-tools libcap2-bin grep rsync xz-utils file git curl bc qemu-utils kpartx gpg pigz
|
||||
sudo curl -fsSL https://get.docker.com -o get-docker.sh
|
||||
sudo sh ./get-docker.sh
|
||||
sudo ./build-docker.sh
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Upload deploy directory as artifact
|
||||
path: deploy/
|
|
@ -1,5 +1,4 @@
|
|||
ARG BASE_IMAGE=debian:bullseye
|
||||
FROM ${BASE_IMAGE}
|
||||
FROM debian:buster
|
||||
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
|
||||
|
@ -7,9 +6,8 @@ RUN apt-get -y update && \
|
|||
apt-get -y install --no-install-recommends \
|
||||
git vim parted \
|
||||
quilt coreutils qemu-user-static debootstrap zerofree zip dosfstools \
|
||||
libarchive-tools libcap2-bin rsync grep udev xz-utils curl xxd file kmod bc\
|
||||
binfmt-support ca-certificates qemu-utils kpartx fdisk gpg pigz\
|
||||
procps lsof\
|
||||
bsdtar libcap2-bin rsync grep udev xz-utils curl xxd file kmod bc\
|
||||
binfmt-support ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY . /pi-gen/
|
||||
|
|
190
README.md
190
README.md
|
@ -1,44 +1,25 @@
|
|||
# pi-gen
|
||||
|
||||
Tool used to create Raspberry Pi OS images. (Previously known as Raspbian).
|
||||
_Tool used to create the raspberrypi.org Raspbian images_
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
pi-gen runs on Debian-based operating systems. Currently it is only supported on
|
||||
pi-gen runs on Debian based operating systems. Currently it is only supported on
|
||||
either Debian Buster or Ubuntu Xenial and is known to have issues building on
|
||||
earlier releases of these systems. On other Linux distributions it may be possible
|
||||
to use the Docker build described below.
|
||||
|
||||
To install the required dependencies for `pi-gen` you should run:
|
||||
To install the required dependencies for pi-gen you should run:
|
||||
|
||||
```bash
|
||||
apt-get install coreutils quilt parted qemu-user-static debootstrap zerofree zip \
|
||||
dosfstools libarchive-tools libcap2-bin grep rsync xz-utils file git curl bc \
|
||||
qemu-utils kpartx gpg pigz
|
||||
dosfstools bsdtar libcap2-bin grep rsync xz-utils file git curl bc
|
||||
```
|
||||
|
||||
The file `depends` contains a list of tools needed. The format of this
|
||||
package is `<tool>[:<debian-package>]`.
|
||||
|
||||
## Getting started with building your images
|
||||
|
||||
Getting started is as simple as cloning this repository on your build machine. You
|
||||
can do so with:
|
||||
|
||||
```bash
|
||||
git clone --depth 1 https://github.com/RPI-Distro/pi-gen.git
|
||||
```
|
||||
|
||||
Using `--depth 1` with `git clone` will create a shallow clone, only containing
|
||||
the latest revision of the repository. Do not do this on your development machine.
|
||||
|
||||
Also, be careful to clone the repository to a base path **NOT** containing spaces.
|
||||
This configuration is not supported by debootstrap and will lead to `pi-gen` not
|
||||
running.
|
||||
|
||||
After cloning the repository, you can move to the next step and start configuring
|
||||
your build.
|
||||
|
||||
## Config
|
||||
|
||||
|
@ -55,32 +36,9 @@ The following environment variables are supported:
|
|||
but you should use something else for a customized version. Export files
|
||||
in stages may add suffixes to `IMG_NAME`.
|
||||
|
||||
* `USE_QCOW2` **EXPERIMENTAL** (Default: `0` )
|
||||
* `RELEASE` (Default: buster)
|
||||
|
||||
Instead of using traditional way of building the rootfs of every stage in
|
||||
single subdirectories and copying over the previous one to the next one,
|
||||
qcow2 based virtual disks with backing images are used in every stage.
|
||||
This speeds up the build process and reduces overall space consumption
|
||||
significantly.
|
||||
|
||||
<u>Additional optional parameters regarding qcow2 build:</u>
|
||||
|
||||
* `BASE_QCOW2_SIZE` (Default: 12G)
|
||||
|
||||
Size of the virtual qcow2 disk.
|
||||
Note: it will not actually use that much of space at once but defines the
|
||||
maximum size of the virtual disk. If you change the build process by adding
|
||||
a lot of bigger packages or additional build stages, it can be necessary to
|
||||
increase the value because the virtual disk can run out of space like a normal
|
||||
hard drive would.
|
||||
|
||||
**CAUTION:** Although the qcow2 build mechanism will run fine inside Docker, it can happen
|
||||
that the network block device is not disconnected correctly after the Docker process has
|
||||
ended abnormally. In that case see [Disconnect an image if something went wrong](#Disconnect-an-image-if-something-went-wrong)
|
||||
|
||||
* `RELEASE` (Default: bullseye)
|
||||
|
||||
The release version to build images against. Valid values are jessie, stretch,
|
||||
The release version to build images against. Valid values are jessie, stretch
|
||||
buster, bullseye, and testing.
|
||||
|
||||
* `APT_PROXY` (Default: unset)
|
||||
|
@ -110,34 +68,15 @@ The following environment variables are supported:
|
|||
system for each build stage, amounting to tens of gigabytes in the case of
|
||||
Raspbian.
|
||||
|
||||
**CAUTION**: If your working directory is on an NTFS partition you probably won't be able to build: make sure this is a proper Linux filesystem.
|
||||
**CAUTION**: If your working directory is on an NTFS partition you probably won't be able to build. Make sure this is a proper Linux filesystem.
|
||||
|
||||
* `DEPLOY_DIR` (Default: `"$BASE_DIR/deploy"`)
|
||||
|
||||
Output directory for target system images and NOOBS bundles.
|
||||
|
||||
* `DEPLOY_COMPRESSION` (Default: `zip`)
|
||||
* `DEPLOY_ZIP` (Default: `1`)
|
||||
|
||||
Set to:
|
||||
* `none` to deploy the actual image (`.img`).
|
||||
* `zip` to deploy a zipped image (`.zip`).
|
||||
* `gz` to deploy a gzipped image (`.img.gz`).
|
||||
* `xz` to deploy a xzipped image (`.img.xz`).
|
||||
|
||||
|
||||
* `DEPLOY_ZIP` (Deprecated)
|
||||
|
||||
This option has been deprecated in favor of `DEPLOY_COMPRESSION`.
|
||||
|
||||
If `DEPLOY_ZIP=0` is still present in your config file, the behavior is the
|
||||
same as with `DEPLOY_COMPRESSION=none`.
|
||||
|
||||
* `COMPRESSION_LEVEL` (Default: `6`)
|
||||
|
||||
Compression level to be used when using `zip`, `gz` or `xz` for
|
||||
`DEPLOY_COMPRESSION`. From 0 to 9 (refer to the tool man page for more
|
||||
information on this. Usually 0 is no compression but very fast, up to 9 with
|
||||
the best compression but very slow ).
|
||||
Setting to `0` will deploy the actual image (`.img`) instead of a zipped image (`.zip`).
|
||||
|
||||
* `USE_QEMU` (Default: `"0"`)
|
||||
|
||||
|
@ -177,24 +116,12 @@ The following environment variables are supported:
|
|||
|
||||
* `WPA_ESSID`, `WPA_PASSWORD` and `WPA_COUNTRY` (Default: unset)
|
||||
|
||||
If these are set, they are use to configure `wpa_supplicant.conf`, so that the Raspberry Pi can automatically connect to a wireless network on first boot. If `WPA_ESSID` is set and `WPA_PASSWORD` is unset an unprotected wireless network will be configured. If set, `WPA_PASSWORD` must be between 8 and 63 characters.
|
||||
If these are set, they are use to configure `wpa_supplicant.conf`, so that the Raspberry Pi can automatically connect to a wifi network on first boot. If `WPA_ESSID` is set and `WPA_PASSWORD` is unset an unprotected wifi network will be configured. If set, `WPA_PASSWORD` must be between 8 and 63 characters.
|
||||
|
||||
* `ENABLE_SSH` (Default: `0`)
|
||||
|
||||
Setting to `1` will enable ssh server for remote log in. Note that if you are using a common password such as the defaults there is a high risk of attackers taking over you Raspberry Pi.
|
||||
|
||||
* `PUBKEY_SSH_FIRST_USER` (Default: unset)
|
||||
|
||||
Setting this to a value will make that value the contents of the FIRST_USER_NAME's ~/.ssh/authorized_keys. Obviously the value should
|
||||
therefore be a valid authorized_keys file. Note that this does not
|
||||
automatically enable SSH.
|
||||
|
||||
* `PUBKEY_ONLY_SSH` (Default: `0`)
|
||||
|
||||
* Setting to `1` will disable password authentication for SSH and enable
|
||||
public key authentication. Note that if SSH is not enabled this will take
|
||||
effect when SSH becomes enabled.
|
||||
|
||||
* `STAGE_LIST` (Default: `stage*`)
|
||||
|
||||
If set, then instead of working through the numeric stages in order, this list will be followed. For example setting to `"stage0 stage1 mystage stage2"` will run the contents of `mystage` before stage2. Note that quotes are needed around the list. An absolute or relative path can be given for stages outside the pi-gen directory.
|
||||
|
@ -301,10 +228,6 @@ fix is to ensure `binfmt-support` is installed on the host machine before
|
|||
starting the `./build-docker.sh` script (or using your own docker build
|
||||
solution).
|
||||
|
||||
### Passing arguments to Docker
|
||||
|
||||
When the docker image is run various required command line arguments are provided. For example the system mounts the `/dev` directory to the `/dev` directory within the docker container. If other arguments are required they may be specified in the PIGEN_DOCKER_OPTS environment variable. For example setting `PIGEN_DOCKER_OPTS="--add-host foo:192.168.0.23"` will add '192.168.0.23 foo' to the `/etc/hosts` file in the container. The `--name`
|
||||
and `--privileged` options are already set by the script and should not be redefined.
|
||||
|
||||
## Stage Anatomy
|
||||
|
||||
|
@ -333,7 +256,7 @@ maintenance and allows for more easy customization.
|
|||
|
||||
- **Stage 2** - lite system. This stage produces the Raspbian-Lite image. It
|
||||
installs some optimized memory functions, sets timezone and charmap
|
||||
defaults, installs fake-hwclock and ntp, wireless LAN and bluetooth support,
|
||||
defaults, installs fake-hwclock and ntp, wifi and bluetooth support,
|
||||
dphys-swapfile, and other basics for managing the hardware. It also
|
||||
creates necessary groups and gives the pi user access to sudo and the
|
||||
standard console hardware permission groups.
|
||||
|
@ -397,90 +320,10 @@ follows:
|
|||
* Once you're happy with the image you can remove the SKIP_IMAGES files and
|
||||
export your image to test
|
||||
|
||||
# Regarding Qcow2 image building
|
||||
|
||||
### Get infos about the image in use
|
||||
|
||||
If you issue the two commands shown in the example below in a second command shell while a build
|
||||
is running you can find out, which network block device is currently being used and which qcow2 image
|
||||
is bound to it.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
root@build-machine:~/$ lsblk | grep nbd
|
||||
nbd1 43:32 0 10G 0 disk
|
||||
├─nbd1p1 43:33 0 10G 0 part
|
||||
└─nbd1p1 253:0 0 10G 0 part
|
||||
|
||||
root@build-machine:~/$ ps xa | grep qemu-nbd
|
||||
2392 pts/6 S+ 0:00 grep --color=auto qemu-nbd
|
||||
31294 ? Ssl 0:12 qemu-nbd --discard=unmap -c /dev/nbd1 image-stage4.qcow2
|
||||
```
|
||||
|
||||
Here you can see, that the qcow2 image `image-stage4.qcow2` is currently connected to `/dev/nbd1` with
|
||||
the associated partition map `/dev/mapper/nbd1p1`. Don't worry that `lsblk` shows two entries. It is totally fine, because the device map is accessible via `/dev/mapper/nbd1p1` and also via `/dev/dm-0`. This is all part of the device mapper functionality of the kernel. See `dmsetup` for further information.
|
||||
|
||||
### Mount a qcow2 image
|
||||
|
||||
If you want to examine the content of a a single stage, you can simply mount the qcow2 image found in the `WORK_DIR` directory with the tool `./imagetool.sh`.
|
||||
|
||||
See `./imagetool.sh -h` for further details on how to use it.
|
||||
|
||||
### Disconnect an image if something went wrong
|
||||
|
||||
It can happen, that your build stops in case of an error. Normally `./build.sh` should handle image disconnection appropriately, but in rare cases, especially during a Docker build, this may not work as expected. If that happens, starting a new build will fail and you may have to disconnect the image and/or device yourself.
|
||||
|
||||
A typical message indicating that there are some orphaned device mapper entries is this:
|
||||
|
||||
```
|
||||
Failed to set NBD socket
|
||||
Disconnect client, due to: Unexpected end-of-file before all bytes were read
|
||||
```
|
||||
|
||||
If that happens go through the following steps:
|
||||
|
||||
1. First, check if the image is somehow mounted to a directory entry and umount it as you would any other block device, like i.e. a hard disk or USB stick.
|
||||
|
||||
2. Second, to disconnect an image from `qemu-nbd`, the QEMU Disk Network Block Device Server, issue the following command (be sure to change the device name to the one actually used):
|
||||
|
||||
```bash
|
||||
sudo qemu-nbd -d /dev/nbd1
|
||||
```
|
||||
|
||||
Note: if you use Docker build, normally no active `qemu-nbd` process exists anymore as it will be terminated when the Docker container stops.
|
||||
|
||||
3. To disconnect a device partition map from the network block device, execute:
|
||||
|
||||
```bash
|
||||
sudo kpartx -d /dev/nbd1
|
||||
or
|
||||
sudo ./imagetool.sh --cleanup
|
||||
```
|
||||
|
||||
Note: The `imagetool.sh` command will cleanup any /dev/nbdX that is not connected to a running `qemu-nbd` daemon. Be careful if you use network block devices for other tasks utilizing NBDs on your build machine as well.
|
||||
|
||||
Now you should be able to start a new build without running into troubles again. Most of the time, especially when using Docker build, you will only need no. 3 to get everything up and running again.
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
## `64 Bit Systems`
|
||||
Please note there is currently an issue when compiling with a 64 Bit OS. See
|
||||
https://github.com/RPi-Distro/pi-gen/issues/271
|
||||
|
||||
A 64 bit image can be generated from the `arm64` branch in this repository. Just
|
||||
replace the command from [this section](#getting-started-with-building-your-images)
|
||||
by the one below, and follow the rest of the documentation:
|
||||
```bash
|
||||
git clone --depth 1 --branch arm64 https://github.com/RPI-Distro/pi-gen.git
|
||||
```
|
||||
|
||||
If you want to generate a 64 bits image from a Raspberry Pi running a 32 bits
|
||||
version, you need to add `arm_64bit=1` to your `config.txt` file and reboot your
|
||||
machine. This will restart your machine with a 64 bits kernel. This will only
|
||||
work from a Raspberry Pi with a 64-bit capable processor (i.e. Raspberry Pi Zero
|
||||
2, Raspberry Pi 3 or Raspberry Pi 4).
|
||||
|
||||
Please note there is currently an issue when compiling with a 64 Bit OS. See https://github.com/RPi-Distro/pi-gen/issues/271
|
||||
|
||||
## `binfmt_misc`
|
||||
|
||||
|
@ -489,16 +332,11 @@ possible to make use of `pi-gen` on an x86_64 system, even though it will be run
|
|||
ARM binaries. This requires support from the [`binfmt_misc`](https://en.wikipedia.org/wiki/Binfmt_misc)
|
||||
kernel module.
|
||||
|
||||
You may see one of the following errors:
|
||||
You may see the following error:
|
||||
|
||||
```
|
||||
update-binfmts: warning: Couldn't load the binfmt_misc module.
|
||||
```
|
||||
```
|
||||
W: Failure trying to run: chroot "/pi-gen/work/test/stage0/rootfs" /bin/true
|
||||
and/or
|
||||
chroot: failed to run command '/bin/true': Exec format error
|
||||
```
|
||||
|
||||
To resolve this, ensure that the following files are available (install them if necessary):
|
||||
|
||||
|
@ -508,5 +346,3 @@ To resolve this, ensure that the following files are available (install them if
|
|||
```
|
||||
|
||||
You may also need to load the module by hand - run `modprobe binfmt_misc`.
|
||||
|
||||
If you are using WSL to build you may have to enable the service `sudo update-binfmts --enable`
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/bin/bash -eu
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
BUILD_OPTS="$*"
|
||||
|
@ -48,7 +47,6 @@ fi
|
|||
CONTAINER_NAME=${CONTAINER_NAME:-pigen_work}
|
||||
CONTINUE=${CONTINUE:-0}
|
||||
PRESERVE_CONTAINER=${PRESERVE_CONTAINER:-0}
|
||||
PIGEN_DOCKER_OPTS=${PIGEN_DOCKER_OPTS:-""}
|
||||
|
||||
if [ -z "${IMG_NAME}" ]; then
|
||||
echo "IMG_NAME not set in 'config'" 1>&2
|
||||
|
@ -75,43 +73,29 @@ fi
|
|||
# Modify original build-options to allow config file to be mounted in the docker container
|
||||
BUILD_OPTS="$(echo "${BUILD_OPTS:-}" | sed -E 's@\-c\s?([^ ]+)@-c /config@')"
|
||||
|
||||
${DOCKER} build --build-arg BASE_IMAGE=debian:bullseye -t pi-gen "${DIR}"
|
||||
|
||||
${DOCKER} build -t pi-gen "${DIR}"
|
||||
if [ "${CONTAINER_EXISTS}" != "" ]; then
|
||||
trap 'echo "got CTRL+C... please wait 5s" && ${DOCKER} stop -t 5 ${CONTAINER_NAME}_cont' SIGINT SIGTERM
|
||||
time ${DOCKER} run --rm --privileged \
|
||||
--cap-add=ALL \
|
||||
-v /dev:/dev \
|
||||
-v /lib/modules:/lib/modules \
|
||||
${PIGEN_DOCKER_OPTS} \
|
||||
--volume "${CONFIG_FILE}":/config:ro \
|
||||
-e "GIT_HASH=${GIT_HASH}" \
|
||||
--volumes-from="${CONTAINER_NAME}" --name "${CONTAINER_NAME}_cont" \
|
||||
pi-gen \
|
||||
bash -e -o pipefail -c "dpkg-reconfigure qemu-user-static &&
|
||||
# binfmt_misc is sometimes not mounted with debian bullseye image
|
||||
(mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc || true) &&
|
||||
cd /pi-gen; ./build.sh ${BUILD_OPTS} &&
|
||||
rsync -av work/*/build.log deploy/" &
|
||||
wait "$!"
|
||||
else
|
||||
trap 'echo "got CTRL+C... please wait 5s" && ${DOCKER} stop -t 5 ${CONTAINER_NAME}' SIGINT SIGTERM
|
||||
time ${DOCKER} run --name "${CONTAINER_NAME}" --privileged \
|
||||
--cap-add=ALL \
|
||||
-v /dev:/dev \
|
||||
-v /lib/modules:/lib/modules \
|
||||
${PIGEN_DOCKER_OPTS} \
|
||||
--volume "${CONFIG_FILE}":/config:ro \
|
||||
-e "GIT_HASH=${GIT_HASH}" \
|
||||
pi-gen \
|
||||
bash -e -o pipefail -c "dpkg-reconfigure qemu-user-static &&
|
||||
# binfmt_misc is sometimes not mounted with debian bullseye image
|
||||
(mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc || true) &&
|
||||
cd /pi-gen; ./build.sh ${BUILD_OPTS} &&
|
||||
rsync -av work/*/build.log deploy/" &
|
||||
wait "$!"
|
||||
fi
|
||||
|
||||
echo "copying results from deploy/"
|
||||
${DOCKER} cp "${CONTAINER_NAME}":/pi-gen/deploy .
|
||||
ls -lah deploy
|
||||
|
|
173
build.sh
173
build.sh
|
@ -1,5 +1,4 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
# shellcheck disable=SC2119
|
||||
run_sub_stage()
|
||||
{
|
||||
|
@ -23,11 +22,6 @@ EOF
|
|||
on_chroot << EOF
|
||||
apt-get -o APT::Acquire::Retries=3 install --no-install-recommends -y $PACKAGES
|
||||
EOF
|
||||
if [ "${USE_QCOW2}" = "1" ]; then
|
||||
on_chroot << EOF
|
||||
apt-get clean
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
log "End ${SUB_STAGE_DIR}/${i}-packages-nr"
|
||||
fi
|
||||
|
@ -38,11 +32,6 @@ EOF
|
|||
on_chroot << EOF
|
||||
apt-get -o APT::Acquire::Retries=3 install -y $PACKAGES
|
||||
EOF
|
||||
if [ "${USE_QCOW2}" = "1" ]; then
|
||||
on_chroot << EOF
|
||||
apt-get clean
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
log "End ${SUB_STAGE_DIR}/${i}-packages"
|
||||
fi
|
||||
|
@ -93,30 +82,17 @@ EOF
|
|||
run_stage(){
|
||||
log "Begin ${STAGE_DIR}"
|
||||
STAGE="$(basename "${STAGE_DIR}")"
|
||||
|
||||
pushd "${STAGE_DIR}" > /dev/null
|
||||
|
||||
unmount "${WORK_DIR}/${STAGE}"
|
||||
STAGE_WORK_DIR="${WORK_DIR}/${STAGE}"
|
||||
ROOTFS_DIR="${STAGE_WORK_DIR}"/rootfs
|
||||
|
||||
if [ "${USE_QCOW2}" = "1" ]; then
|
||||
if [ ! -f SKIP ]; then
|
||||
load_qimage
|
||||
fi
|
||||
else
|
||||
# make sure we are not umounting during export-image stage
|
||||
if [ "${USE_QCOW2}" = "0" ] && [ "${NO_PRERUN_QCOW2}" = "0" ]; then
|
||||
unmount "${WORK_DIR}/${STAGE}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f SKIP_IMAGES ]; then
|
||||
if [ -f "${STAGE_DIR}/EXPORT_IMAGE" ]; then
|
||||
EXPORT_DIRS="${EXPORT_DIRS} ${STAGE_DIR}"
|
||||
fi
|
||||
fi
|
||||
if [ ! -f SKIP ]; then
|
||||
if [ "${CLEAN}" = "1" ] && [ "${USE_QCOW2}" = "0" ] ; then
|
||||
if [ "${CLEAN}" = "1" ]; then
|
||||
if [ -d "${ROOTFS_DIR}" ]; then
|
||||
rm -rf "${ROOTFS_DIR}"
|
||||
fi
|
||||
|
@ -127,21 +103,13 @@ run_stage(){
|
|||
log "End ${STAGE_DIR}/prerun.sh"
|
||||
fi
|
||||
for SUB_STAGE_DIR in "${STAGE_DIR}"/*; do
|
||||
if [ -d "${SUB_STAGE_DIR}" ] && [ ! -f "${SUB_STAGE_DIR}/SKIP" ]; then
|
||||
if [ -d "${SUB_STAGE_DIR}" ] &&
|
||||
[ ! -f "${SUB_STAGE_DIR}/SKIP" ]; then
|
||||
run_sub_stage
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "${USE_QCOW2}" = "1" ]; then
|
||||
unload_qimage
|
||||
else
|
||||
# make sure we are not umounting during export-image stage
|
||||
if [ "${USE_QCOW2}" = "0" ] && [ "${NO_PRERUN_QCOW2}" = "0" ]; then
|
||||
unmount "${WORK_DIR}/${STAGE}"
|
||||
fi
|
||||
fi
|
||||
|
||||
PREV_STAGE="${STAGE}"
|
||||
PREV_STAGE_DIR="${STAGE_DIR}"
|
||||
PREV_ROOTFS_DIR="${ROOTFS_DIR}"
|
||||
|
@ -155,14 +123,6 @@ if [ "$(id -u)" != "0" ]; then
|
|||
fi
|
||||
|
||||
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
if [[ $BASE_DIR = *" "* ]]; then
|
||||
echo "There is a space in the base path of pi-gen"
|
||||
echo "This is not a valid setup supported by debootstrap."
|
||||
echo "Please remove the spaces, or move pi-gen directory to a base path without spaces" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export BASE_DIR
|
||||
|
||||
if [ -f config ]; then
|
||||
|
@ -183,15 +143,6 @@ do
|
|||
esac
|
||||
done
|
||||
|
||||
term() {
|
||||
if [ "${USE_QCOW2}" = "1" ]; then
|
||||
log "Unloading image"
|
||||
unload_qimage
|
||||
fi
|
||||
}
|
||||
|
||||
trap term EXIT INT TERM
|
||||
|
||||
export PI_GEN=${PI_GEN:-pi-gen}
|
||||
export PI_GEN_REPO=${PI_GEN_REPO:-https://github.com/RPi-Distro/pi-gen}
|
||||
|
||||
|
@ -203,32 +154,21 @@ fi
|
|||
export USE_QEMU="${USE_QEMU:-0}"
|
||||
export IMG_DATE="${IMG_DATE:-"$(date +%Y-%m-%d)"}"
|
||||
export IMG_FILENAME="${IMG_FILENAME:-"${IMG_DATE}-${IMG_NAME}"}"
|
||||
export ARCHIVE_FILENAME="${ARCHIVE_FILENAME:-"image_${IMG_DATE}-${IMG_NAME}"}"
|
||||
export ZIP_FILENAME="${ZIP_FILENAME:-"image_${IMG_DATE}-${IMG_NAME}"}"
|
||||
|
||||
export SCRIPT_DIR="${BASE_DIR}/scripts"
|
||||
export WORK_DIR="${WORK_DIR:-"${BASE_DIR}/work/${IMG_NAME}"}"
|
||||
export WORK_DIR="${WORK_DIR:-"${BASE_DIR}/work/${IMG_DATE}-${IMG_NAME}"}"
|
||||
export DEPLOY_DIR=${DEPLOY_DIR:-"${BASE_DIR}/deploy"}
|
||||
|
||||
# DEPLOY_ZIP was deprecated in favor of DEPLOY_COMPRESSION
|
||||
# This preserve the old behavior with DEPLOY_ZIP=0 where no archive was created
|
||||
if [ -z "${DEPLOY_COMPRESSION}" ] && [ "${DEPLOY_ZIP:-1}" = "0" ]; then
|
||||
echo "DEPLOY_ZIP has been deprecated in favor of DEPLOY_COMPRESSION"
|
||||
echo "Similar behavior to DEPLOY_ZIP=0 can be obtained with DEPLOY_COMPRESSION=none"
|
||||
echo "Please update your config file"
|
||||
DEPLOY_COMPRESSION=none
|
||||
fi
|
||||
export DEPLOY_COMPRESSION=${DEPLOY_COMPRESSION:-zip}
|
||||
export COMPRESSION_LEVEL=${COMPRESSION_LEVEL:-6}
|
||||
export DEPLOY_ZIP="${DEPLOY_ZIP:-1}"
|
||||
export LOG_FILE="${WORK_DIR}/build.log"
|
||||
|
||||
export TARGET_HOSTNAME=${TARGET_HOSTNAME:-raspberrypi}
|
||||
|
||||
export RELEASE=${RELEASE:-bullseye}
|
||||
export RELEASE=${RELEASE:-buster}
|
||||
export WPA_ESSID
|
||||
export WPA_PASSWORD
|
||||
export WPA_COUNTRY
|
||||
export ENABLE_SSH="${ENABLE_SSH:-0}"
|
||||
export PUBKEY_ONLY_SSH="${PUBKEY_ONLY_SSH:-0}"
|
||||
|
||||
export LOCALE_DEFAULT="${LOCALE_DEFAULT:-en_GB.UTF-8}"
|
||||
|
||||
|
@ -239,8 +179,6 @@ export TIMEZONE_DEFAULT="${TIMEZONE_DEFAULT:-Europe/London}"
|
|||
|
||||
export GIT_HASH=${GIT_HASH:-"$(git rev-parse HEAD)"}
|
||||
|
||||
export PUBKEY_SSH_FIRST_USER
|
||||
|
||||
export CLEAN
|
||||
export IMG_NAME
|
||||
export APT_PROXY
|
||||
|
@ -268,18 +206,6 @@ source "${SCRIPT_DIR}/common"
|
|||
# shellcheck source=scripts/dependencies_check
|
||||
source "${SCRIPT_DIR}/dependencies_check"
|
||||
|
||||
export NO_PRERUN_QCOW2="${NO_PRERUN_QCOW2:-1}"
|
||||
export USE_QCOW2="${USE_QCOW2:-0}"
|
||||
export BASE_QCOW2_SIZE=${BASE_QCOW2_SIZE:-12G}
|
||||
source "${SCRIPT_DIR}/qcow2_handling"
|
||||
if [ "${USE_QCOW2}" = "1" ]; then
|
||||
NO_PRERUN_QCOW2=1
|
||||
else
|
||||
NO_PRERUN_QCOW2=0
|
||||
fi
|
||||
|
||||
export NO_PRERUN_QCOW2="${NO_PRERUN_QCOW2:-1}"
|
||||
|
||||
dependencies_check "${BASE_DIR}/depends"
|
||||
|
||||
if [[ -n "${APT_PROXY}" ]] && ! curl --silent "${APT_PROXY}" >/dev/null ; then
|
||||
|
@ -292,11 +218,6 @@ if [[ -n "${WPA_PASSWORD}" && ${#WPA_PASSWORD} -lt 8 || ${#WPA_PASSWORD} -gt 63
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${PUBKEY_ONLY_SSH}" = "1" && -z "${PUBKEY_SSH_FIRST_USER}" ]]; then
|
||||
echo "Must set 'PUBKEY_SSH_FIRST_USER' to a valid SSH public key if using PUBKEY_ONLY_SSH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "${WORK_DIR}"
|
||||
log "Begin ${BASE_DIR}"
|
||||
|
||||
|
@ -313,98 +234,22 @@ for EXPORT_DIR in ${EXPORT_DIRS}; do
|
|||
# shellcheck source=/dev/null
|
||||
source "${EXPORT_DIR}/EXPORT_IMAGE"
|
||||
EXPORT_ROOTFS_DIR=${WORK_DIR}/$(basename "${EXPORT_DIR}")/rootfs
|
||||
if [ "${USE_QCOW2}" = "1" ]; then
|
||||
USE_QCOW2=0
|
||||
EXPORT_NAME="${IMG_FILENAME}${IMG_SUFFIX}"
|
||||
echo "------------------------------------------------------------------------"
|
||||
echo "Running export stage for ${EXPORT_NAME}"
|
||||
rm -f "${WORK_DIR}/export-image/${EXPORT_NAME}.img" || true
|
||||
rm -f "${WORK_DIR}/export-image/${EXPORT_NAME}.qcow2" || true
|
||||
rm -f "${WORK_DIR}/${EXPORT_NAME}.img" || true
|
||||
rm -f "${WORK_DIR}/${EXPORT_NAME}.qcow2" || true
|
||||
EXPORT_STAGE=$(basename "${EXPORT_DIR}")
|
||||
for s in $STAGE_LIST; do
|
||||
TMP_LIST=${TMP_LIST:+$TMP_LIST }$(basename "${s}")
|
||||
done
|
||||
FIRST_STAGE=${TMP_LIST%% *}
|
||||
FIRST_IMAGE="image-${FIRST_STAGE}.qcow2"
|
||||
|
||||
pushd "${WORK_DIR}" > /dev/null
|
||||
echo "Creating new base "${EXPORT_NAME}.qcow2" from ${FIRST_IMAGE}"
|
||||
cp "./${FIRST_IMAGE}" "${EXPORT_NAME}.qcow2"
|
||||
|
||||
ARR=($TMP_LIST)
|
||||
# rebase stage images to new export base
|
||||
for CURR_STAGE in "${ARR[@]}"; do
|
||||
if [ "${CURR_STAGE}" = "${FIRST_STAGE}" ]; then
|
||||
PREV_IMG="${EXPORT_NAME}"
|
||||
continue
|
||||
fi
|
||||
echo "Rebasing image-${CURR_STAGE}.qcow2 onto ${PREV_IMG}.qcow2"
|
||||
qemu-img rebase -f qcow2 -u -b ${PREV_IMG}.qcow2 image-${CURR_STAGE}.qcow2
|
||||
if [ "${CURR_STAGE}" = "${EXPORT_STAGE}" ]; then
|
||||
break
|
||||
fi
|
||||
PREV_IMG="image-${CURR_STAGE}"
|
||||
done
|
||||
|
||||
# commit current export stage into base export image
|
||||
echo "Committing image-${EXPORT_STAGE}.qcow2 to ${EXPORT_NAME}.qcow2"
|
||||
qemu-img commit -f qcow2 -p -b "${EXPORT_NAME}.qcow2" image-${EXPORT_STAGE}.qcow2
|
||||
|
||||
# rebase stage images back to original first stage for easy re-run
|
||||
for CURR_STAGE in "${ARR[@]}"; do
|
||||
if [ "${CURR_STAGE}" = "${FIRST_STAGE}" ]; then
|
||||
PREV_IMG="image-${CURR_STAGE}"
|
||||
continue
|
||||
fi
|
||||
echo "Rebasing back image-${CURR_STAGE}.qcow2 onto ${PREV_IMG}.qcow2"
|
||||
qemu-img rebase -f qcow2 -u -b ${PREV_IMG}.qcow2 image-${CURR_STAGE}.qcow2
|
||||
if [ "${CURR_STAGE}" = "${EXPORT_STAGE}" ]; then
|
||||
break
|
||||
fi
|
||||
PREV_IMG="image-${CURR_STAGE}"
|
||||
done
|
||||
popd > /dev/null
|
||||
|
||||
mkdir -p "${WORK_DIR}/export-image/rootfs"
|
||||
mv "${WORK_DIR}/${EXPORT_NAME}.qcow2" "${WORK_DIR}/export-image/"
|
||||
echo "Mounting image ${WORK_DIR}/export-image/${EXPORT_NAME}.qcow2 to rootfs ${WORK_DIR}/export-image/rootfs"
|
||||
mount_qimage "${WORK_DIR}/export-image/${EXPORT_NAME}.qcow2" "${WORK_DIR}/export-image/rootfs"
|
||||
|
||||
CLEAN=0
|
||||
run_stage
|
||||
CLEAN=1
|
||||
USE_QCOW2=1
|
||||
|
||||
else
|
||||
run_stage
|
||||
fi
|
||||
if [ "${USE_QEMU}" != "1" ]; then
|
||||
if [ -e "${EXPORT_DIR}/EXPORT_NOOBS" ]; then
|
||||
# shellcheck source=/dev/null
|
||||
source "${EXPORT_DIR}/EXPORT_NOOBS"
|
||||
STAGE_DIR="${BASE_DIR}/export-noobs"
|
||||
if [ "${USE_QCOW2}" = "1" ]; then
|
||||
USE_QCOW2=0
|
||||
run_stage
|
||||
USE_QCOW2=1
|
||||
else
|
||||
run_stage
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -x postrun.sh ]; then
|
||||
if [ -x ${BASE_DIR}/postrun.sh ]; then
|
||||
log "Begin postrun.sh"
|
||||
cd "${BASE_DIR}"
|
||||
./postrun.sh
|
||||
log "End postrun.sh"
|
||||
fi
|
||||
|
||||
if [ "${USE_QCOW2}" = "1" ]; then
|
||||
unload_qimage
|
||||
fi
|
||||
|
||||
log "End ${BASE_DIR}"
|
||||
|
|
4
config
4
config
|
@ -1,6 +1,6 @@
|
|||
IMG_NAME="yunohost"
|
||||
RELEASE="bullseye"
|
||||
USE_QEMU="0"
|
||||
RELEASE="stretch"
|
||||
USE_QEMU="1"
|
||||
LOCALE_DEFAULT="en_US.UTF-8"
|
||||
TARGET_HOSTNAME="yunohost"
|
||||
KEYBOARD_KEYMAP="us"
|
||||
|
|
6
depends
6
depends
|
@ -7,7 +7,7 @@ zerofree
|
|||
zip
|
||||
mkdosfs:dosfstools
|
||||
capsh:libcap2-bin
|
||||
bsdtar:libarchive-tools
|
||||
bsdtar
|
||||
grep
|
||||
rsync
|
||||
xz:xz-utils
|
||||
|
@ -17,7 +17,3 @@ file
|
|||
git
|
||||
lsmod:kmod
|
||||
bc
|
||||
qemu-nbd:qemu-utils
|
||||
kpartx
|
||||
gpg
|
||||
pigz
|
||||
|
|
7
export-image/01-set-sources/01-run.sh
Executable file
7
export-image/01-set-sources/01-run.sh
Executable file
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
on_chroot << EOF
|
||||
apt-get update
|
||||
apt-get -y dist-upgrade
|
||||
apt-get clean
|
||||
EOF
|
|
@ -1 +0,0 @@
|
|||
userconf-pi
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
on_chroot << EOF
|
||||
SUDO_USER="${FIRST_USER_NAME}" rename-user -f -s
|
||||
EOF
|
|
@ -1,9 +0,0 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
rm -f "${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache"
|
||||
find "${ROOTFS_DIR}/var/lib/apt/lists/" -type f -delete
|
||||
on_chroot << EOF
|
||||
apt-get update
|
||||
apt-get -y dist-upgrade
|
||||
apt-get clean
|
||||
EOF
|
13
export-image/03-set-partuuid/00-run.sh
Executable file
13
export-image/03-set-partuuid/00-run.sh
Executable file
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
|
||||
|
||||
IMGID="$(dd if="${IMG_FILE}" skip=440 bs=1 count=4 2>/dev/null | xxd -e | cut -f 2 -d' ')"
|
||||
|
||||
BOOT_PARTUUID="${IMGID}-01"
|
||||
ROOT_PARTUUID="${IMGID}-02"
|
||||
|
||||
sed -i "s/BOOTDEV/PARTUUID=${BOOT_PARTUUID}/" "${ROOTFS_DIR}/etc/fstab"
|
||||
sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${ROOTFS_DIR}/etc/fstab"
|
||||
|
||||
sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${ROOTFS_DIR}/boot/cmdline.txt"
|
|
@ -12,10 +12,7 @@ if hash hardlink 2>/dev/null; then
|
|||
fi
|
||||
EOF
|
||||
|
||||
if [ -d "${ROOTFS_DIR}/home/${FIRST_USER_NAME}/.config" ]; then
|
||||
chmod 700 "${ROOTFS_DIR}/home/${FIRST_USER_NAME}/.config"
|
||||
fi
|
||||
|
||||
rm -f "${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache"
|
||||
rm -f "${ROOTFS_DIR}/usr/bin/qemu-arm-static"
|
||||
|
||||
if [ "${USE_QEMU}" != "1" ]; then
|
||||
|
@ -76,41 +73,25 @@ cp "$ROOTFS_DIR/etc/rpi-issue" "$INFO_FILE"
|
|||
dpkg -l --root "$ROOTFS_DIR"
|
||||
} >> "$INFO_FILE"
|
||||
|
||||
ROOT_DEV="$(mount | grep "${ROOTFS_DIR} " | cut -f1 -d' ')"
|
||||
|
||||
unmount "${ROOTFS_DIR}"
|
||||
zerofree "${ROOT_DEV}"
|
||||
|
||||
unmount_image "${IMG_FILE}"
|
||||
|
||||
mkdir -p "${DEPLOY_DIR}"
|
||||
|
||||
rm -f "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.*"
|
||||
rm -f "${DEPLOY_DIR}/${ZIP_FILENAME}${IMG_SUFFIX}.zip"
|
||||
rm -f "${DEPLOY_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
|
||||
|
||||
mv "$INFO_FILE" "$DEPLOY_DIR/"
|
||||
|
||||
if [ "${USE_QCOW2}" = "0" ] && [ "${NO_PRERUN_QCOW2}" = "0" ]; then
|
||||
ROOT_DEV="$(mount | grep "${ROOTFS_DIR} " | cut -f1 -d' ')"
|
||||
|
||||
unmount "${ROOTFS_DIR}"
|
||||
zerofree "${ROOT_DEV}"
|
||||
|
||||
unmount_image "${IMG_FILE}"
|
||||
if [ "${DEPLOY_ZIP}" == "1" ]; then
|
||||
pushd "${STAGE_WORK_DIR}" > /dev/null
|
||||
zip "${DEPLOY_DIR}/${ZIP_FILENAME}${IMG_SUFFIX}.zip" \
|
||||
"$(basename "${IMG_FILE}")"
|
||||
popd > /dev/null
|
||||
else
|
||||
unload_qimage
|
||||
make_bootable_image "${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.qcow2" "$IMG_FILE"
|
||||
cp "$IMG_FILE" "$DEPLOY_DIR"
|
||||
fi
|
||||
|
||||
case "${DEPLOY_COMPRESSION}" in
|
||||
zip)
|
||||
pushd "${STAGE_WORK_DIR}" > /dev/null
|
||||
zip -"${COMPRESSION_LEVEL}" \
|
||||
"${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.zip" "$(basename "${IMG_FILE}")"
|
||||
popd > /dev/null
|
||||
;;
|
||||
gz)
|
||||
pigz --force -"${COMPRESSION_LEVEL}" "$IMG_FILE" --stdout > \
|
||||
"${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.img.gz"
|
||||
;;
|
||||
xz)
|
||||
xz --compress --force --threads 0 --memlimit-compress=50% -"${COMPRESSION_LEVEL}" \
|
||||
--stdout "$IMG_FILE" > "${DEPLOY_DIR}/${ARCHIVE_FILENAME}${IMG_SUFFIX}.img.xz"
|
||||
;;
|
||||
none | *)
|
||||
cp "$IMG_FILE" "$DEPLOY_DIR/"
|
||||
;;
|
||||
esac
|
||||
cp "$INFO_FILE" "$DEPLOY_DIR"
|
|
@ -1,18 +0,0 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
if [ "${NO_PRERUN_QCOW2}" = "0" ]; then
|
||||
|
||||
IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
|
||||
|
||||
IMGID="$(dd if="${IMG_FILE}" skip=440 bs=1 count=4 2>/dev/null | xxd -e | cut -f 2 -d' ')"
|
||||
|
||||
BOOT_PARTUUID="${IMGID}-01"
|
||||
ROOT_PARTUUID="${IMGID}-02"
|
||||
|
||||
sed -i "s/BOOTDEV/PARTUUID=${BOOT_PARTUUID}/" "${ROOTFS_DIR}/etc/fstab"
|
||||
sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${ROOTFS_DIR}/etc/fstab"
|
||||
|
||||
sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${ROOTFS_DIR}/boot/cmdline.txt"
|
||||
|
||||
fi
|
||||
|
|
@ -1,87 +1,61 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
if [ "${NO_PRERUN_QCOW2}" = "0" ]; then
|
||||
IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
|
||||
IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
|
||||
|
||||
unmount_image "${IMG_FILE}"
|
||||
unmount_image "${IMG_FILE}"
|
||||
|
||||
rm -f "${IMG_FILE}"
|
||||
rm -f "${IMG_FILE}"
|
||||
|
||||
rm -rf "${ROOTFS_DIR}"
|
||||
mkdir -p "${ROOTFS_DIR}"
|
||||
rm -rf "${ROOTFS_DIR}"
|
||||
mkdir -p "${ROOTFS_DIR}"
|
||||
|
||||
BOOT_SIZE="$((256 * 1024 * 1024))"
|
||||
ROOT_SIZE=$(du --apparent-size -s "${EXPORT_ROOTFS_DIR}" --exclude var/cache/apt/archives --exclude boot --block-size=1 | cut -f 1)
|
||||
BOOT_SIZE="$((256 * 1024 * 1024))"
|
||||
ROOT_SIZE=$(du --apparent-size -s "${EXPORT_ROOTFS_DIR}" --exclude var/cache/apt/archives --exclude boot --block-size=1 | cut -f 1)
|
||||
|
||||
# All partition sizes and starts will be aligned to this size
|
||||
ALIGN="$((4 * 1024 * 1024))"
|
||||
# Add this much space to the calculated file size. This allows for
|
||||
# some overhead (since actual space usage is usually rounded up to the
|
||||
# filesystem block size) and gives some free space on the resulting
|
||||
# image.
|
||||
ROOT_MARGIN="$(echo "($ROOT_SIZE * 0.2 + 200 * 1024 * 1024) / 1" | bc)"
|
||||
# All partition sizes and starts will be aligned to this size
|
||||
ALIGN="$((4 * 1024 * 1024))"
|
||||
# Add this much space to the calculated file size. This allows for
|
||||
# some overhead (since actual space usage is usually rounded up to the
|
||||
# filesystem block size) and gives some free space on the resulting
|
||||
# image.
|
||||
ROOT_MARGIN="$(echo "($ROOT_SIZE * 0.2 + 200 * 1024 * 1024) / 1" | bc)"
|
||||
|
||||
BOOT_PART_START=$((ALIGN))
|
||||
BOOT_PART_SIZE=$(((BOOT_SIZE + ALIGN - 1) / ALIGN * ALIGN))
|
||||
ROOT_PART_START=$((BOOT_PART_START + BOOT_PART_SIZE))
|
||||
ROOT_PART_SIZE=$(((ROOT_SIZE + ROOT_MARGIN + ALIGN - 1) / ALIGN * ALIGN))
|
||||
IMG_SIZE=$((BOOT_PART_START + BOOT_PART_SIZE + ROOT_PART_SIZE))
|
||||
BOOT_PART_START=$((ALIGN))
|
||||
BOOT_PART_SIZE=$(((BOOT_SIZE + ALIGN - 1) / ALIGN * ALIGN))
|
||||
ROOT_PART_START=$((BOOT_PART_START + BOOT_PART_SIZE))
|
||||
ROOT_PART_SIZE=$(((ROOT_SIZE + ROOT_MARGIN + ALIGN - 1) / ALIGN * ALIGN))
|
||||
IMG_SIZE=$((BOOT_PART_START + BOOT_PART_SIZE + ROOT_PART_SIZE))
|
||||
|
||||
truncate -s "${IMG_SIZE}" "${IMG_FILE}"
|
||||
truncate -s "${IMG_SIZE}" "${IMG_FILE}"
|
||||
|
||||
parted --script "${IMG_FILE}" mklabel msdos
|
||||
parted --script "${IMG_FILE}" unit B mkpart primary fat32 "${BOOT_PART_START}" "$((BOOT_PART_START + BOOT_PART_SIZE - 1))"
|
||||
parted --script "${IMG_FILE}" unit B mkpart primary ext4 "${ROOT_PART_START}" "$((ROOT_PART_START + ROOT_PART_SIZE - 1))"
|
||||
parted --script "${IMG_FILE}" mklabel msdos
|
||||
parted --script "${IMG_FILE}" unit B mkpart primary fat32 "${BOOT_PART_START}" "$((BOOT_PART_START + BOOT_PART_SIZE - 1))"
|
||||
parted --script "${IMG_FILE}" unit B mkpart primary ext4 "${ROOT_PART_START}" "$((ROOT_PART_START + ROOT_PART_SIZE - 1))"
|
||||
|
||||
PARTED_OUT=$(parted -sm "${IMG_FILE}" unit b print)
|
||||
BOOT_OFFSET=$(echo "$PARTED_OUT" | grep -e '^1:' | cut -d':' -f 2 | tr -d B)
|
||||
BOOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^1:' | cut -d':' -f 4 | tr -d B)
|
||||
PARTED_OUT=$(parted -sm "${IMG_FILE}" unit b print)
|
||||
BOOT_OFFSET=$(echo "$PARTED_OUT" | grep -e '^1:' | cut -d':' -f 2 | tr -d B)
|
||||
BOOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^1:' | cut -d':' -f 4 | tr -d B)
|
||||
|
||||
ROOT_OFFSET=$(echo "$PARTED_OUT" | grep -e '^2:' | cut -d':' -f 2 | tr -d B)
|
||||
ROOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^2:' | cut -d':' -f 4 | tr -d B)
|
||||
ROOT_OFFSET=$(echo "$PARTED_OUT" | grep -e '^2:' | cut -d':' -f 2 | tr -d B)
|
||||
ROOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^2:' | cut -d':' -f 4 | tr -d B)
|
||||
|
||||
echo "Mounting BOOT_DEV..."
|
||||
cnt=0
|
||||
until BOOT_DEV=$(losetup --show -f -o "${BOOT_OFFSET}" --sizelimit "${BOOT_LENGTH}" "${IMG_FILE}"); do
|
||||
if [ $cnt -lt 5 ]; then
|
||||
cnt=$((cnt + 1))
|
||||
echo "Error in losetup for BOOT_DEV. Retrying..."
|
||||
sleep 5
|
||||
else
|
||||
echo "ERROR: losetup for BOOT_DEV failed; exiting"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
BOOT_DEV=$(losetup --show -f -o "${BOOT_OFFSET}" --sizelimit "${BOOT_LENGTH}" "${IMG_FILE}")
|
||||
ROOT_DEV=$(losetup --show -f -o "${ROOT_OFFSET}" --sizelimit "${ROOT_LENGTH}" "${IMG_FILE}")
|
||||
echo "/boot: offset $BOOT_OFFSET, length $BOOT_LENGTH"
|
||||
echo "/: offset $ROOT_OFFSET, length $ROOT_LENGTH"
|
||||
|
||||
echo "Mounting ROOT_DEV..."
|
||||
cnt=0
|
||||
until ROOT_DEV=$(losetup --show -f -o "${ROOT_OFFSET}" --sizelimit "${ROOT_LENGTH}" "${IMG_FILE}"); do
|
||||
if [ $cnt -lt 5 ]; then
|
||||
cnt=$((cnt + 1))
|
||||
echo "Error in losetup for ROOT_DEV. Retrying..."
|
||||
sleep 5
|
||||
else
|
||||
echo "ERROR: losetup for ROOT_DEV failed; exiting"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo "/boot: offset $BOOT_OFFSET, length $BOOT_LENGTH"
|
||||
echo "/: offset $ROOT_OFFSET, length $ROOT_LENGTH"
|
||||
|
||||
ROOT_FEATURES="^huge_file"
|
||||
for FEATURE in metadata_csum 64bit; do
|
||||
ROOT_FEATURES="^huge_file"
|
||||
for FEATURE in metadata_csum 64bit; do
|
||||
if grep -q "$FEATURE" /etc/mke2fs.conf; then
|
||||
ROOT_FEATURES="^$FEATURE,$ROOT_FEATURES"
|
||||
fi
|
||||
done
|
||||
mkdosfs -n boot -F 32 -v "$BOOT_DEV" > /dev/null
|
||||
mkfs.ext4 -L rootfs -O "$ROOT_FEATURES" "$ROOT_DEV" > /dev/null
|
||||
done
|
||||
mkdosfs -n boot -F 32 -v "$BOOT_DEV" > /dev/null
|
||||
mkfs.ext4 -L rootfs -O "$ROOT_FEATURES" "$ROOT_DEV" > /dev/null
|
||||
|
||||
mount -v "$ROOT_DEV" "${ROOTFS_DIR}" -t ext4
|
||||
mkdir -p "${ROOTFS_DIR}/boot"
|
||||
mount -v "$BOOT_DEV" "${ROOTFS_DIR}/boot" -t vfat
|
||||
mount -v "$ROOT_DEV" "${ROOTFS_DIR}" -t ext4
|
||||
mkdir -p "${ROOTFS_DIR}/boot"
|
||||
mount -v "$BOOT_DEV" "${ROOTFS_DIR}/boot" -t vfat
|
||||
|
||||
rsync -aHAXx --exclude /var/cache/apt/archives --exclude /boot "${EXPORT_ROOTFS_DIR}/" "${ROOTFS_DIR}/"
|
||||
rsync -rtx "${EXPORT_ROOTFS_DIR}/boot/" "${ROOTFS_DIR}/boot/"
|
||||
fi
|
||||
rsync -aHAXx --exclude /var/cache/apt/archives --exclude /boot "${EXPORT_ROOTFS_DIR}/" "${ROOTFS_DIR}/"
|
||||
rsync -rtx "${EXPORT_ROOTFS_DIR}/boot/" "${ROOTFS_DIR}/boot/"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
NOOBS_DIR="${STAGE_WORK_DIR}/${IMG_NAME}${IMG_SUFFIX}"
|
||||
NOOBS_DIR="${STAGE_WORK_DIR}/${IMG_DATE}-${IMG_NAME}${IMG_SUFFIX}"
|
||||
|
||||
install -v -m 744 files/partition_setup.sh "${NOOBS_DIR}/"
|
||||
install -v files/partitions.json "${NOOBS_DIR}/"
|
||||
|
@ -20,7 +20,7 @@ BOOT_SIZE="$(( BOOT_SIZE / 1024 / 1024 + 1))"
|
|||
ROOT_SIZE="$(( ROOT_SIZE / 1024 / 1024 + 1))"
|
||||
|
||||
BOOT_NOM="256"
|
||||
ROOT_NOM="$(echo "$ROOT_SIZE" | awk '{printf "%.0f", (($1 + 400) * 1.2) + 0.5 }')"
|
||||
ROOT_NOM="$(( ROOT_SIZE + 400 ))"
|
||||
|
||||
mv "${NOOBS_DIR}/OS.png" "${NOOBS_DIR}/${NOOBS_NAME// /_}.png"
|
||||
|
||||
|
@ -37,12 +37,7 @@ sed "${NOOBS_DIR}/os.json" -i -e "s|UNRELEASED|${IMG_DATE}|"
|
|||
sed "${NOOBS_DIR}/os.json" -i -e "s|NOOBS_NAME|${NOOBS_NAME}|"
|
||||
sed "${NOOBS_DIR}/os.json" -i -e "s|NOOBS_DESCRIPTION|${NOOBS_DESCRIPTION}|"
|
||||
sed "${NOOBS_DIR}/os.json" -i -e "s|RELEASE|${RELEASE}|"
|
||||
sed "${NOOBS_DIR}/os.json" -i -e "s|KERNEL|$(cat "${STAGE_WORK_DIR}/kernel_version")|"
|
||||
|
||||
sed "${NOOBS_DIR}/release_notes.txt" -i -e "s|UNRELEASED|${IMG_DATE}|"
|
||||
|
||||
if [ "${USE_QCOW2}" = "1" ]; then
|
||||
mv "${NOOBS_DIR}" "${DEPLOY_DIR}/"
|
||||
else
|
||||
cp -a "${NOOBS_DIR}" "${DEPLOY_DIR}/"
|
||||
fi
|
||||
cp -a "${NOOBS_DIR}" "${DEPLOY_DIR}/"
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.4 KiB |
|
@ -1,15 +1,18 @@
|
|||
{
|
||||
"description": "NOOBS_DESCRIPTION",
|
||||
"kernel": "KERNEL",
|
||||
"feature_level": 35120124,
|
||||
"kernel": "4.19",
|
||||
"name": "NOOBS_NAME",
|
||||
"password": "raspberry",
|
||||
"release_date": "UNRELEASED",
|
||||
"supported_hex_revisions": "2,3,4,5,6,7,8,9,d,e,f,10,11,12,14,19,1040,1041,0092,0093,2082",
|
||||
"supported_models": [
|
||||
"Pi Zero 2",
|
||||
"Pi Model",
|
||||
"Pi 2",
|
||||
"Pi Zero",
|
||||
"Pi 3",
|
||||
"Pi 4",
|
||||
"Pi Compute Module 3",
|
||||
"Pi Compute Module 4"
|
||||
"Pi 4"
|
||||
],
|
||||
"url": "http://www.raspbian.org/",
|
||||
"username": "pi",
|
||||
|
|
|
@ -1,244 +1,4 @@
|
|||
UNRELEASED:
|
||||
*
|
||||
2022-04-04:
|
||||
* Default "pi” user has been removed; the first-boot wizard enforces the creation of a new user account
|
||||
* rename-user script added to allow existing users to be renamed by temporarily rebooting to cut-down first-boot wizard
|
||||
* Overscan now managed by xrandr under KMS, can be set independently for both monitors, and takes effect on the fly rather than requiring reboot
|
||||
* GTK3 switch control now used in place of paired radio buttons throughout
|
||||
* piwiz - first-boot wizard now runs in a separate session as a different user with different graphics
|
||||
* piwiz - first-boot wizard now has automatic pairing for discoverable Bluetooth mice and keyboards
|
||||
* lxinput - keyboard delay and repeat settings now persist across reboots under mutter
|
||||
* raspi-config / rc_gui - removed pixel doubling option when KMS driver in use
|
||||
* raspi-config - removed composition manager option when legacy driver in use
|
||||
* arandr - restored support for interlaced displays
|
||||
* mutter - implemented more intuitive window and application cycling behaviour
|
||||
* pi-greeter - rebuilt for GTK3
|
||||
* Bug fix - graphical corruption in system tray icons
|
||||
* Bug fix - desktop items vanishing when dragged
|
||||
* Bug fix - terminal windows not focussed correctly when launched
|
||||
* Bug fix - crash after multiple update checks in updater plugin
|
||||
* Bug fix - Raspberry Pi keyboard auto-detect by wizard was broken in previous release
|
||||
* Bug fix - spurious "connected” dialog box shown when reconnecting to Bluetooth LE devices on boot
|
||||
* Support for experimental Wayland backend added - can be enabled as an advanced option in raspi-config
|
||||
* Various small bug fixes and graphical tweaks
|
||||
* Chromium upgraded to version 98.0.4758.106
|
||||
* FFmpeg HW acceleration improved
|
||||
* OpenJDK 17 now defaults to 'client' JVM for ARMv6 compatibility
|
||||
* Raspberry Pi firmware 69277bc713133a54a1d20554d79544da1ae2b6ca
|
||||
* Linux kernel 5.15.30
|
||||
2022-01-28:
|
||||
* Policykit CVE-2021-4034 fix
|
||||
* rc_gui - add combo box to allow resolution to be set for VNC connections
|
||||
* rc_gui - camera interface switch removed
|
||||
* lxpanel - remove appearance settings from preferences dialog; instead add menu option to open general Appearance Settings application
|
||||
* lxpanel - add ellipses to menu items which open dialogs
|
||||
* lxinput - read current mouse acceleration directly from xinput
|
||||
* lxinput - use device IDs rather than names to cope with devices changing when powered-down
|
||||
* lxinput - remove redundant changes to openbox config file
|
||||
* plymouth - set KillMode to mixed to suppress warning message
|
||||
* raspi-config - add option to switch composite video
|
||||
* raspi-config - add option to switch to legacy camera mode
|
||||
* raspi-config - add option to set resolution for headless connections
|
||||
* raspberrypi-ui-mods - disable mutter when VNC server is running and fall back to openbox
|
||||
* pipanel - add command-line option to open on arbitrary tab
|
||||
* lxplug-network - suppress ’scan received’ logging message
|
||||
* raspberrypi-ui-mods - set hover colour for taskbar items based on taskbar colour, not system highlight colour
|
||||
* Legacy camera applications and libraries reinstalled (32-bit only)
|
||||
* Bug fix - lxinput - lxsession config file not being written on first attempt
|
||||
* Bug fix - lxinput - set timer for file write to prevent slider slowing down
|
||||
* Bug fix - lxinput - write values to gsettings as well as xinput and xsettings to take effect within mutter
|
||||
* Bug fix - lxinput - fix failure to parse and write non-English numeric formats
|
||||
* Bug fix - arandr - various fixes to parsing of non-standard EDID blocks to enable model and serial to be correctly extracted
|
||||
* Bug fix - arandr - refresh rate calculated to 3 decimal places for monitors which require it
|
||||
* Bug fix - arandr - enable setting of left and right orientation
|
||||
* Bug fix - arandr - add compatibility with new touchscreen driver
|
||||
* Bug fix - arandr - apply settings correctly to DSI and composite displays
|
||||
* Bug fix - lxplug-magnifier - fix crash when opening preferences without required magnifier package installed
|
||||
* Bug fix - piwiz - launch screen reader install prompt as a new process to prevent audio lockups crashing wizard
|
||||
* Bug fix - lxpanel - not loading some plugins (cpufreq, minimise all windows) due to icon loading code not compatible with GTK+3
|
||||
* Bug fix - gtk+3 - disabled new GDK touch events to enable double-clicks to be detected on touchscreen
|
||||
* Bug fix - xrdp - included backports from bookworm version of xrdp and xorgxrdp to restore window frames with mutter over xrdp connections
|
||||
* Update various translations
|
||||
* udisks2 added to lite image
|
||||
* mkvtoolnix added to lite image
|
||||
* 7z and zip support added to lite image
|
||||
* gnome-keyring added to desktop images
|
||||
* Raspberry Pi firmware c6d56567ff6ef17fd85159770f22abcf2c5953ed
|
||||
* Linux kernel 5.10.92
|
||||
2021-10-30:
|
||||
* Based on Debian version 11 (bullseye)
|
||||
* Desktop components (lxpanel and all plugins, libfm, pcmanfm) now built against GTK+3
|
||||
* Applications (piwiz, pipanel, rc_gui, lxinput) now built against GTK+3
|
||||
* PiXflat GTK+3 theme updated with numerous changes to support the above
|
||||
* GTK+3 : toolbar icon size setting added
|
||||
* GTK+3 : ability to request client-side decoration on windows added
|
||||
* GTK+3 : setting for indent for frame labels in custom style added
|
||||
* mutter window manager used instead of openbox on devices with 2GB or more of RAM
|
||||
* mutter : title bar icon behaviour and appearance modified to match openbox
|
||||
* mutter : additional keyboard shortcuts added
|
||||
* mutter : various performance enhancements
|
||||
* mutter compatibility added to screen magnifier
|
||||
* Numerous changes to Appearance Settings application to support GTK+3 and mutter
|
||||
* Updater plugin added to lxpanel to detect and install software updates
|
||||
* File manager view options simplified to either list or icons, with separate menu option for thumbnails
|
||||
* New file manager toolbar icons
|
||||
* KMS used as default display driver
|
||||
* Modifications to HDMI audio output selection to support the above
|
||||
* xcompmgr enabled when openbox is running under KMS
|
||||
* New default camera subsystem based on libcamera
|
||||
* New camera demo applications (libcamera-still and libcamera-vid) have replaced raspistill and raspivid
|
||||
* Legacy camera subsystem removed from 64-bit RPi OS (still available on 32-bit)
|
||||
* Chromium upgraded to version 92.0.4515.98
|
||||
* VLC media player upgraded to version 3.0.16
|
||||
* Spurious drive removal warning after use of SD card copier removed
|
||||
* Bookshelf application now includes Custom PC magazine
|
||||
* Various translation updates - Italian, Korean, Polish, German, Armenian
|
||||
* Startup wizard now installs Japanese fonts if needed
|
||||
* Progress and information dialog boxes for lxpanel plugins now common to lxpanel, rather than in individual plugins
|
||||
* Icon handling code for lxpanel plugins now common to lxpanel
|
||||
* Package with 4K version of Raspberry Pi wallpaper added to Recommended Software
|
||||
* Python Games and Minecraft removed from Recommended Software - neither is compatible with bullseye
|
||||
* Bluetooth pairing and connection dialogs updated for compatibility with more devices
|
||||
* Bluetooth devices always disconnected before removal to speed up removal process
|
||||
* Bluetooth pairing dialog now only shows devices which offer services which are usable by Pi
|
||||
* Separate Bluetooth unpair dialog removed - unpair now an option for each individual device
|
||||
* Bug fix - mutter : header bar colours not updating when theme is changed
|
||||
* Bug fix - GTK+3 : tooltips being displayed incorrectly at bottom of screen
|
||||
* Bug fix - lxpanel : crash when using keyboard shortcut to enable magnifier when magnifier not installed
|
||||
* Bug fix - lxpanel : lockup in Bluetooth plugin when connecting to certain devices
|
||||
* Bug fix - lxpanel : discoverable mode icon could get out of sync with underlying Bluetooth system state
|
||||
* Bug fix - piwiz : missing cities in timezone list
|
||||
* Bug fix - piwiz : country-specific language packages not being installed
|
||||
* Bug fix - bookshelf : now waits for longer between packets before timing out
|
||||
* Bug fix - accented characters now displayed correctly in localisation dialogs
|
||||
* Raspberry Pi firmware e2bab29767e51c683a312df20014e3277275b8a6
|
||||
* Linux kernel 5.10.63
|
||||
2021-05-07:
|
||||
* Chromium upgraded to version 88.0.4324.187
|
||||
* NuScratch upgraded to version 20210507
|
||||
* Node-RED upgraded to version 1.3.4
|
||||
* pigpio upgraded to version 1.79
|
||||
* Thonny upgraded to version 3.3.6
|
||||
* Icelandic and Italian translations updated for several packages
|
||||
* piclone: Remove hiding of application in other desktops
|
||||
* agnostics: Remove hiding of app in other desktops
|
||||
* rp-bookshelf:
|
||||
- Remove hiding of app in other desktops
|
||||
- GTK+3 version
|
||||
* lxplug-bluetooth:
|
||||
- Fix some memory leaks
|
||||
- Add authorisation dialog required by some BT-LE pairings
|
||||
* alsa-utils: Add custom init files for bcm2835 on Raspberry Pi to set volume correctly
|
||||
* rp-prefapps: Remove hiding of app in other desktops
|
||||
* OpenSSH and OpenSSL speed improvements
|
||||
* Install gpiozero in lite images
|
||||
* Raspberry Pi firmware 518ee7c871aaa9aaa88116953d57e73787ee6e43
|
||||
* Linux kernel 5.10.17
|
||||
2021-03-04:
|
||||
* Thonny upgraded to version 3.3.5
|
||||
* SD Card Copier made compatible with NVMe devices; now built against GTK+3 toolkit
|
||||
* Composite video options removed from Raspberry Pi 4 in Raspberry Pi Configuration
|
||||
* Boot order options in raspi-config adjusted for more flexibility
|
||||
* Recommended Software now built against GTK+3 toolkit
|
||||
* Fix for crash in volume plugin when using keyboard could push value out of range
|
||||
* Fix for focus changing between windows in file manager when using keyboard to navigate directory view
|
||||
* Fix for Raspberry Pi 400 keyboard country not being read correctly in startup wizard
|
||||
* Armenian and Japanese translations added to several packages
|
||||
* Automatically load aes-neon-bs on ARM64 to speed up OpenSSL
|
||||
* Raspberry Pi firmware fcf8d2f7639ad8d0330db9c8db9b71bd33eaaa28
|
||||
* Linux kernel 5.10.17
|
||||
2021-01-11:
|
||||
* Chromium version 86.0.4240.197 included
|
||||
* Screen reader support enabled in Chromium
|
||||
* Adobe have end-of-lifed Flash Player, so it has been removed
|
||||
* Scratch 2 required Flash, so it has been removed
|
||||
* Added Epson printer drivers
|
||||
* Added timeout to hide messages from USB device monitor after 5 seconds
|
||||
* Bug fix - PulseAudio output was in mono
|
||||
* Bug fix - brief audio interruptions at start of playback in VLC
|
||||
* Bug fix - old ALSA output settings being used instead of PulseAudio settings by some applications
|
||||
* Bug fix - crash in PulseAudio volume controller when used on multichannel devices
|
||||
* Bug fix - battery monitor failing to load on x86 platforms
|
||||
* Bug fix - setting of password in startup wizard failed if language was changed
|
||||
* Bug fix - Chromium video playback lockup on small number of devices
|
||||
* Bug fix - Chromium Google Maps 3D view artefacts
|
||||
* Slovak, Italian and Norwegian translations updated
|
||||
* Added Epson printer drivers
|
||||
* Raspberry Pi firmware 70f1581eec2c036b7e9309f1af41c651fb125447
|
||||
* Linux kernel 5.4.83
|
||||
2020-12-02:
|
||||
* PulseAudio now included and running by default
|
||||
* Bluealsa Bluetooth interface removed - Bluetooth audio is now handled by PulseAudio
|
||||
* LXPanel volume control plugin replaced with PulseAudio version
|
||||
* Version 84.0.4147.105 of Chromium web browser included
|
||||
* Version 3.3.0 of Thonny included
|
||||
* Version 32.0.0.453 of Flash player included - note that this will be the final release of Flash, as it is end-of-lifed at the end of 2020
|
||||
* CUPS printer system included, along with system-config-printer CUPS GUI and HP printer drivers
|
||||
* raspi-config menu structure rearranged to match Raspberry Pi Configuration tabs
|
||||
* Control for GPIO-connected fans added to raspi-config and Raspberry Pi Configuration
|
||||
* Control for power / activity LED on Pi 400 and Pi Zero added to raspi-config and Raspberry Pi Configuration
|
||||
* Improved screen reader voice prompts in several applications
|
||||
* Added ctrl-alt-space shortcut to install Orca screen reader at any point
|
||||
* Low voltage warnings added to battery monitor plugin
|
||||
* Magnifier plugin zoom can now be changed with scroll wheel when pointer is over icon
|
||||
* Change to notification popups - now will only close when clicked on directly, not by clicking anywhere
|
||||
* Bookshelf now made compatible with translated versions of books and magazines, and will offer translated versions where available, based on system language setting
|
||||
* Bug fix - crash in CPU temperature plugin when throttling detection fails
|
||||
* Bug fix - if Orca is running, shutdown commands and shutdown dialog will force kill it to prevent it locking up the reboot or shutdown process
|
||||
* Various additional language translations added
|
||||
* Various minor bug fixes and UI tweaks
|
||||
* Raspberry Pi firmware b324aea801f669b6ab18441f970e74a5a7346684
|
||||
* Linux kernel 5.4.79
|
||||
2020-08-20:
|
||||
* raspi-config - added selection of boot device order
|
||||
* raspi-config - added selection of boot EEPROM version
|
||||
* SD Card Copier - copy is now immediately aborted if drives are connected or disconnected while copying
|
||||
* Version 32.0.0.414 of Flash player included
|
||||
* User feedback survey removed from first run of Chromium
|
||||
* Recommended Software - now allows multiple install and reinstall operations without having to close between each one
|
||||
* Bug fix - misleading file browser from panel menu icon selection dialog - icons must now be in icon theme rather than arbitrary files
|
||||
* Bug fix - items in main menu not being translated
|
||||
* Bug fix - raspi-config not detecting audio devices in non-English locales
|
||||
* Bug fix - Bookshelf claiming no disk space in non-English locales
|
||||
* Bug fix - failed installation of both 32 and 64 bit versions of packages by Recommended Software on 64-bit images
|
||||
* Italian translations added (thanks to Emanuele Goldoni and the Italian translation team)
|
||||
* Raspberry Pi firmware ef72c17bcaaeb89093d87bcf71f3228e1b5e1fff
|
||||
* Linux kernel 5.4.51
|
||||
2020-05-27:
|
||||
* Added Bookshelf application
|
||||
* Added Raspberry Pi Diagnostics application
|
||||
* Added magnifier plugin to taskbar - needs magnifier application installed from Recommended Software to enable
|
||||
* Added Magnifier application to Recommended Software
|
||||
* Added marketing questionnaire as initial Chromium tab
|
||||
* Version 0.25 of Scratch 2 included - uses external application to access IMU on SenseHAT
|
||||
* Version 1.0.5 of Scratch 3 included - uses external application to access IMU on SenseHAT
|
||||
* Version 32.0.0.371 of Flash player included
|
||||
* Version 1.0.6 of Node-RED included
|
||||
* Version 6.7.1 of VNC Server included
|
||||
* Version 6.20.113 of VNC Client included
|
||||
* Internal audio outputs enabled as separate ALSA devices
|
||||
* MagPi preinstall removed and replaced with Beginner’s Guide
|
||||
* MagPi weblink removed from main menu
|
||||
* Chromium made default application for PDF files
|
||||
* Common icon loading code for lxpanel plugins used
|
||||
* Italian translations added
|
||||
* Initial move of mouse pointer to menu button disabled
|
||||
* Padding at left of menu button removed
|
||||
* Focus behaviour changed so that focus moves to desktop if no windows are opened - improves reliability of Orca screen reader
|
||||
* Bug fix - focus bug in volume plugin
|
||||
* Bug fix - keyboard repeat interval bug in Mouse & Keyboard Settings
|
||||
* Bug fix - battery detection bug in battery plugin
|
||||
* Bug fix - spurious active areas on taskbar when plugins are hidden
|
||||
* Bug fix - occasional crash in file manager on file selection
|
||||
* Disk ID is now regenerated on first boot
|
||||
* Updated udev rules
|
||||
- Remove unused argon rule
|
||||
- Add vcsm-cma to video group
|
||||
- Add pwm to gpio group
|
||||
* i2cprobe: More flexible I2C/SPI alias mapping
|
||||
* Raspberry Pi firmware 21e1fe3477ffb708a5736ed61a924fd650031136
|
||||
* Linux kernel 4.19.118
|
||||
2020-02-13:
|
||||
* Raspberry Pi Configuration - screen blanking setting disabled if Xscreensaver is installed
|
||||
* Bug fix - switch to turn off VNC server in Raspberry Pi Configuration has no effect
|
||||
* Bug fix - fix %20 characters in file names
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
NOOBS_DIR="${STAGE_WORK_DIR}/${IMG_NAME}${IMG_SUFFIX}"
|
||||
mkdir -p "${STAGE_WORK_DIR}"
|
||||
|
||||
IMG_FILE="${WORK_DIR}/export-image/${IMG_FILENAME}${IMG_SUFFIX}.img"
|
||||
|
||||
IMG_FILE="${STAGE_WORK_DIR}/${IMG_FILENAME}${IMG_SUFFIX}.img"
|
||||
NOOBS_DIR="${STAGE_WORK_DIR}/${IMG_DATE}-${IMG_NAME}${IMG_SUFFIX}"
|
||||
unmount_image "${IMG_FILE}"
|
||||
|
||||
mkdir -p "${STAGE_WORK_DIR}"
|
||||
cp "${WORK_DIR}/export-image/${IMG_FILENAME}${IMG_SUFFIX}.img" "${STAGE_WORK_DIR}/"
|
||||
|
||||
rm -rf "${NOOBS_DIR}"
|
||||
|
||||
PARTED_OUT=$(parted -sm "${IMG_FILE}" unit b print)
|
||||
|
@ -16,32 +16,8 @@ BOOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^1:' | cut -d':' -f 4 | tr -d B)
|
|||
ROOT_OFFSET=$(echo "$PARTED_OUT" | grep -e '^2:' | cut -d':' -f 2 | tr -d B)
|
||||
ROOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^2:' | cut -d':' -f 4 | tr -d B)
|
||||
|
||||
echo "Mounting BOOT_DEV..."
|
||||
cnt=0
|
||||
until BOOT_DEV=$(losetup --show -f -o "${BOOT_OFFSET}" --sizelimit "${BOOT_LENGTH}" "${IMG_FILE}"); do
|
||||
if [ $cnt -lt 5 ]; then
|
||||
cnt=$((cnt + 1))
|
||||
echo "Error in losetup for BOOT_DEV. Retrying..."
|
||||
sleep 5
|
||||
else
|
||||
echo "ERROR: losetup for BOOT_DEV failed; exiting"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Mounting ROOT_DEV..."
|
||||
cnt=0
|
||||
until ROOT_DEV=$(losetup --show -f -o "${ROOT_OFFSET}" --sizelimit "${ROOT_LENGTH}" "${IMG_FILE}"); do
|
||||
if [ $cnt -lt 5 ]; then
|
||||
cnt=$((cnt + 1))
|
||||
echo "Error in losetup for ROOT_DEV. Retrying..."
|
||||
sleep 5
|
||||
else
|
||||
echo "ERROR: losetup for ROOT_DEV failed; exiting"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
BOOT_DEV=$(losetup --show -f -o "${BOOT_OFFSET}" --sizelimit "${BOOT_LENGTH}" "${IMG_FILE}")
|
||||
ROOT_DEV=$(losetup --show -f -o "${ROOT_OFFSET}" --sizelimit "${ROOT_LENGTH}" "${IMG_FILE}")
|
||||
echo "/boot: offset $BOOT_OFFSET, length $BOOT_LENGTH"
|
||||
echo "/: offset $ROOT_OFFSET, length $ROOT_LENGTH"
|
||||
|
||||
|
@ -53,15 +29,8 @@ mount "$BOOT_DEV" "${STAGE_WORK_DIR}/rootfs/boot"
|
|||
|
||||
ln -sv "/lib/systemd/system/apply_noobs_os_config.service" "$ROOTFS_DIR/etc/systemd/system/multi-user.target.wants/apply_noobs_os_config.service"
|
||||
|
||||
KERNEL_VER="$(zgrep -oPm 1 "Linux version \K(.*)$" "${STAGE_WORK_DIR}/rootfs/usr/share/doc/raspberrypi-kernel/changelog.Debian.gz" | cut -f-2 -d.)"
|
||||
echo "$KERNEL_VER" > "${STAGE_WORK_DIR}/kernel_version"
|
||||
|
||||
bsdtar --numeric-owner --format gnutar -C "${STAGE_WORK_DIR}/rootfs/boot" -cpf - . | xz -T0 > "${NOOBS_DIR}/boot.tar.xz"
|
||||
umount "${STAGE_WORK_DIR}/rootfs/boot"
|
||||
bsdtar --numeric-owner --format gnutar -C "${STAGE_WORK_DIR}/rootfs" --one-file-system -cpf - . | xz -T0 > "${NOOBS_DIR}/root.tar.xz"
|
||||
|
||||
if [ "${USE_QCOW2}" = "1" ]; then
|
||||
rm "$ROOTFS_DIR/etc/systemd/system/multi-user.target.wants/apply_noobs_os_config.service"
|
||||
fi
|
||||
|
||||
unmount_image "${IMG_FILE}"
|
||||
|
|
114
imagetool.sh
114
imagetool.sh
|
@ -1,114 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ "$(id -u)" != "0" ]; then
|
||||
echo "Please run as root" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
progname=$(basename $0)
|
||||
|
||||
function usage()
|
||||
{
|
||||
cat << HEREDOC
|
||||
|
||||
Usage:
|
||||
Mount Image : $progname [--mount] [--image-name <path to qcow2 image>] [--mount-point <mount point>]
|
||||
Umount Image: $progname [--umount] [--mount-point <mount point>]
|
||||
Cleanup NBD : $progname [--cleanup]
|
||||
|
||||
arguments:
|
||||
-h, --help show this help message and exit
|
||||
-c, --cleanup cleanup orphaned device mappings
|
||||
-m, --mount mount image
|
||||
-u, --umount umount image
|
||||
-i, --image-name path to qcow2 image
|
||||
-p, --mount-point mount point for image
|
||||
|
||||
This tool will use /dev/nbd1 as default for mounting an image. If you want to use another device, execute like this:
|
||||
NBD_DEV=/dev/nbd2 ./$progname --mount --image-name <your image> --mount-point <your path>
|
||||
|
||||
HEREDOC
|
||||
}
|
||||
|
||||
MOUNT=0
|
||||
UMOUNT=0
|
||||
IMAGE=""
|
||||
MOUNTPOINT=""
|
||||
|
||||
nbd_cleanup() {
|
||||
DEVS="$(lsblk | grep nbd | grep disk | cut -d" " -f1)"
|
||||
if [ ! -z "${DEVS}" ]; then
|
||||
for d in $DEVS; do
|
||||
if [ ! -z "${d}" ]; then
|
||||
QDEV="$(ps xa | grep $d | grep -v grep)"
|
||||
if [ -z "${QDEV}" ]; then
|
||||
kpartx -d /dev/$d && echo "Unconnected device map removed: /dev/$d"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# As long as there is at least one more argument, keep looping
|
||||
while [[ $# -gt 0 ]]; do
|
||||
key="$1"
|
||||
case "$key" in
|
||||
-h|--help)
|
||||
usage
|
||||
exit
|
||||
;;
|
||||
-c|--cleanup)
|
||||
nbd_cleanup
|
||||
;;
|
||||
-m|--mount)
|
||||
MOUNT=1
|
||||
;;
|
||||
-u|--umount)
|
||||
UMOUNT=1
|
||||
;;
|
||||
-i|--image-name)
|
||||
shift
|
||||
IMAGE="$1"
|
||||
;;
|
||||
-p|--mount-point)
|
||||
shift
|
||||
MOUNTPOINT="$1"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option '$key'"
|
||||
usage
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
# Shift after checking all the cases to get the next option
|
||||
shift
|
||||
done
|
||||
|
||||
if [ "${MOUNT}" = "1" ] && [ "${UMOUNT}" = "1" ]; then
|
||||
usage
|
||||
echo "Concurrent mount options not possible."
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ "${MOUNT}" = "1" ] && ([ -z "${IMAGE}" ] || [ -z "${MOUNTPOINT}" ]); then
|
||||
usage
|
||||
echo "Can not mount image. Image path and/or mount point missing."
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ "${UMOUNT}" = "1" ] && [ -z "${MOUNTPOINT}" ]; then
|
||||
usage
|
||||
echo "Can not umount. Mount point parameter missing."
|
||||
exit
|
||||
fi
|
||||
|
||||
export NBD_DEV="${NBD_DEV:-/dev/nbd1}"
|
||||
export MAP_BOOT_DEV=/dev/mapper/nbd1p1
|
||||
export MAP_ROOT_DEV=/dev/mapper/nbd1p2
|
||||
source scripts/qcow2_handling
|
||||
|
||||
if [ "${MOUNT}" = "1" ]; then
|
||||
mount_qimage "${IMAGE}" "${MOUNTPOINT}"
|
||||
elif [ "${UMOUNT}" = "1" ]; then
|
||||
umount_qimage "${MOUNTPOINT}"
|
||||
fi
|
|
@ -9,21 +9,20 @@ bootstrap(){
|
|||
|
||||
export http_proxy=${APT_PROXY}
|
||||
|
||||
BOOTSTRAP_ARGS+=(--arch arm64)
|
||||
BOOTSTRAP_ARGS+=(--include gnupg)
|
||||
if [ "$(dpkg --print-architecture)" != "armhf" ] && [ "$(dpkg --print-architecture)" != "aarch64" ]; then
|
||||
BOOTSTRAP_CMD=qemu-debootstrap
|
||||
fi
|
||||
|
||||
BOOTSTRAP_ARGS+=(--arch armhf)
|
||||
BOOTSTRAP_ARGS+=(--components "main,contrib,non-free")
|
||||
#BOOTSTRAP_ARGS+=(--keyring "${STAGE_DIR}/files/raspberrypi.gpg")
|
||||
BOOTSTRAP_ARGS+=(--exclude=info)
|
||||
BOOTSTRAP_ARGS+=(--include=ca-certificates)
|
||||
BOOTSTRAP_ARGS+=(--keyring "${STAGE_DIR}/files/raspberrypi.gpg")
|
||||
BOOTSTRAP_ARGS+=("$@")
|
||||
printf -v BOOTSTRAP_STR '%q ' "${BOOTSTRAP_ARGS[@]}"
|
||||
|
||||
capsh --drop=cap_setfcap -- -c "'${BOOTSTRAP_CMD}' $BOOTSTRAP_STR" || true
|
||||
setarch linux32 capsh --drop=cap_setfcap -- -c "'${BOOTSTRAP_CMD}' $BOOTSTRAP_STR" || true
|
||||
|
||||
if [ -d "$2/debootstrap" ] && ! rmdir "$2/debootstrap"; then
|
||||
cp "$2/debootstrap/debootstrap.log" "${STAGE_WORK_DIR}"
|
||||
log "bootstrap failed: please check ${STAGE_WORK_DIR}/debootstrap.log"
|
||||
return 1
|
||||
if [ -d "$2/debootstrap" ]; then
|
||||
rmdir "$2/debootstrap"
|
||||
fi
|
||||
}
|
||||
export -f bootstrap
|
||||
|
@ -91,7 +90,7 @@ on_chroot() {
|
|||
mount --bind /sys "${ROOTFS_DIR}/sys"
|
||||
fi
|
||||
|
||||
capsh --drop=cap_setfcap "--chroot=${ROOTFS_DIR}/" -- -e "$@"
|
||||
setarch linux32 capsh --drop=cap_setfcap "--chroot=${ROOTFS_DIR}/" -- -e "$@"
|
||||
}
|
||||
export -f on_chroot
|
||||
|
||||
|
|
|
@ -28,26 +28,11 @@ dependencies_check()
|
|||
false
|
||||
fi
|
||||
|
||||
# If we're building on a native arm platform, we don't need to check for
|
||||
# binfmt_misc or require it to be loaded.
|
||||
|
||||
binfmt_misc_required=1
|
||||
|
||||
case $(uname -m) in
|
||||
aarch64)
|
||||
binfmt_misc_required=0
|
||||
;;
|
||||
arm*)
|
||||
binfmt_misc_required=0
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ "${binfmt_misc_required}" == "1" ]]; then
|
||||
if ! grep -q "/proc/sys/fs/binfmt_misc" /proc/mounts; then
|
||||
echo "Module binfmt_misc not loaded in host"
|
||||
echo "Please run:"
|
||||
echo " sudo modprobe binfmt_misc"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -1,256 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# QCOW2 Routines
|
||||
|
||||
export CURRENT_IMAGE
|
||||
export CURRENT_MOUNTPOINT
|
||||
|
||||
export NBD_DEV
|
||||
export MAP_BOOT_DEV
|
||||
export MAP_ROOT_DEV
|
||||
|
||||
# set in build.sh
|
||||
# should be fairly enough for the beginning
|
||||
# overwrite here by uncommenting following lines
|
||||
# BASE_QCOW2_SIZE=12G
|
||||
|
||||
# find and initialize free block device nodes
|
||||
init_nbd() {
|
||||
modprobe nbd max_part=16
|
||||
if [ -z "${NBD_DEV}" ]; then
|
||||
for x in /sys/class/block/nbd* ; do
|
||||
S=`cat $x/size`
|
||||
if [ "$S" == "0" ] ; then
|
||||
NBD_DEV=/dev/$(basename $x)
|
||||
MAP_BOOT_DEV=/dev/mapper/$(basename $x)p1
|
||||
MAP_ROOT_DEV=/dev/mapper/$(basename $x)p2
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
export -f init_nbd
|
||||
|
||||
# connect image to block device
|
||||
connect_blkdev() {
|
||||
init_nbd
|
||||
qemu-nbd --discard=unmap -c $NBD_DEV "$1"
|
||||
sync
|
||||
kpartx -as $NBD_DEV
|
||||
sync
|
||||
CURRENT_IMAGE="$1"
|
||||
}
|
||||
export -f connect_blkdev
|
||||
|
||||
# disconnect image from block device
|
||||
disconnect_blkdev() {
|
||||
kpartx -d $NBD_DEV
|
||||
qemu-nbd -d $NBD_DEV
|
||||
NBD_DEV=
|
||||
MAP_BOOT_DEV=
|
||||
MAP_ROOT_DEV=
|
||||
CURRENT_IMAGE=
|
||||
}
|
||||
export -f disconnect_blkdev
|
||||
|
||||
# mount qcow2 image: mount_image <image file> <mountpoint>
|
||||
mount_qimage() {
|
||||
connect_blkdev "$1"
|
||||
mount -v -t ext4 $MAP_ROOT_DEV "$2"
|
||||
mkdir -p "${ROOTFS_DIR}/boot"
|
||||
mount -v -t vfat $MAP_BOOT_DEV "$2/boot"
|
||||
CURRENT_MOUNTPOINT="$2"
|
||||
}
|
||||
export -f mount_qimage
|
||||
|
||||
# umount qcow2 image: umount_image <current mountpoint>
|
||||
umount_qimage() {
|
||||
sync
|
||||
#umount "$1/boot"
|
||||
while mount | grep -q "$1"; do
|
||||
local LOCS
|
||||
LOCS=$(mount | grep "$1" | cut -f 3 -d ' ' | sort -r)
|
||||
for loc in $LOCS; do
|
||||
echo "$loc"
|
||||
while mountpoint -q "$loc" && ! umount "$loc"; do
|
||||
sleep 0.1
|
||||
done
|
||||
done
|
||||
done
|
||||
CURRENT_MOUNTPOINT=
|
||||
disconnect_blkdev
|
||||
}
|
||||
export -f umount_qimage
|
||||
|
||||
# create base image / backing image / mount image
|
||||
load_qimage() {
|
||||
if [ -z "${CURRENT_MOUNTPOINT}" ]; then
|
||||
if [ ! -d "${ROOTFS_DIR}" ]; then
|
||||
mkdir -p "${ROOTFS_DIR}";
|
||||
fi
|
||||
|
||||
if [ "${CLEAN}" = "1" ] && [ -f "${WORK_DIR}/image-${STAGE}.qcow2" ]; then
|
||||
rm -f "${WORK_DIR}/image-${STAGE}.qcow2";
|
||||
fi
|
||||
|
||||
if [ ! -f "${WORK_DIR}/image-${STAGE}.qcow2" ]; then
|
||||
pushd ${WORK_DIR} > /dev/null
|
||||
init_nbd
|
||||
if [ -z "${PREV_STAGE}" ]; then
|
||||
echo "Creating base image: image-${STAGE}.qcow2"
|
||||
# -o preallocation=falloc
|
||||
qemu-img create -f qcow2 image-${STAGE}.qcow2 $BASE_QCOW2_SIZE
|
||||
sync
|
||||
qemu-nbd --discard=unmap -c $NBD_DEV image-${STAGE}.qcow2
|
||||
sync
|
||||
sfdisk $NBD_DEV << EOF
|
||||
4MiB,250MiB,c,*
|
||||
254MiB,,83;
|
||||
EOF
|
||||
sync
|
||||
kpartx -as $NBD_DEV
|
||||
mkdosfs -n boot -F 32 -v $MAP_BOOT_DEV
|
||||
mkfs.ext4 -L rootfs -O "^huge_file,^metadata_csum,^64bit" $MAP_ROOT_DEV
|
||||
sync
|
||||
else
|
||||
if [ ! -f "${WORK_DIR}/image-${PREV_STAGE}.qcow2" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
echo "Creating backing image: image-${STAGE}.qcow2 <- ${WORK_DIR}/image-${PREV_STAGE}.qcow2"
|
||||
qemu-img create -f qcow2 \
|
||||
-o backing_file=${WORK_DIR}/image-${PREV_STAGE}.qcow2 \
|
||||
${WORK_DIR}/image-${STAGE}.qcow2
|
||||
sync
|
||||
qemu-nbd --discard=unmap -c $NBD_DEV image-${STAGE}.qcow2
|
||||
sync
|
||||
kpartx -as $NBD_DEV
|
||||
fi
|
||||
|
||||
mount -v -t ext4 $MAP_ROOT_DEV "${ROOTFS_DIR}"
|
||||
mkdir -p "${ROOTFS_DIR}/boot"
|
||||
mount -v -t vfat $MAP_BOOT_DEV "${ROOTFS_DIR}/boot"
|
||||
CURRENT_IMAGE=${WORK_DIR}/image-${STAGE}.qcow2
|
||||
CURRENT_MOUNTPOINT=${ROOTFS_DIR}
|
||||
popd > /dev/null
|
||||
else
|
||||
mount_qimage "${WORK_DIR}/image-${STAGE}.qcow2" "${ROOTFS_DIR}"
|
||||
fi
|
||||
echo "Current image in use: ${CURRENT_IMAGE} (MP: ${CURRENT_MOUNTPOINT})"
|
||||
fi
|
||||
}
|
||||
export -f load_qimage
|
||||
|
||||
# umount current image and refresh mount point env var
|
||||
unload_qimage() {
|
||||
if [ ! -z "${CURRENT_MOUNTPOINT}" ]; then
|
||||
fstrim -v "${CURRENT_MOUNTPOINT}" || true
|
||||
umount_qimage "${CURRENT_MOUNTPOINT}"
|
||||
fi
|
||||
}
|
||||
export -f unload_qimage
|
||||
|
||||
# based on: https://github.com/SirLagz/RaspberryPi-ImgAutoSizer
|
||||
# helper function for make_bootable_image, do not call directly
|
||||
function resize_qcow2() {
|
||||
if [ -z "$CALL_FROM_MBI" ]; then
|
||||
echo "resize_qcow2: cannot be called directly, use make_bootable_image instead"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# ROOT_MARGIN=$((800*1024*1024))
|
||||
ROOT_MARGIN=$((1*1024*1024))
|
||||
PARTED_OUT=`parted -s -m "$NBD_DEV" unit B print`
|
||||
PART_NO=`echo "$PARTED_OUT" | grep ext4 | awk -F: ' { print $1 } '`
|
||||
PART_START=`echo "$PARTED_OUT" | grep ext4 | awk -F: ' { print substr($2,1,length($2)-1) } '`
|
||||
|
||||
e2fsck -y -f $MAP_ROOT_DEV || true
|
||||
|
||||
DATA_SIZE=`resize2fs -P $MAP_ROOT_DEV | awk -F': ' ' { print $2 } '`
|
||||
BLOCK_SIZE=$(dumpe2fs -h $MAP_ROOT_DEV | grep 'Block size' | awk -F': ' ' { print $2 }')
|
||||
BLOCK_SIZE=${BLOCK_SIZE// /}
|
||||
|
||||
let DATA_SIZE=$DATA_SIZE+$ROOT_MARGIN/$BLOCK_SIZE
|
||||
resize2fs -p $MAP_ROOT_DEV $DATA_SIZE
|
||||
sleep 1
|
||||
|
||||
let PART_NEW_SIZE=$DATA_SIZE*$BLOCK_SIZE
|
||||
let PART_NEW_END=$PART_START+$PART_NEW_SIZE
|
||||
ACT1=`parted -s "$NBD_DEV" rm 2`
|
||||
ACT2=`parted -s "$NBD_DEV" unit B mkpart primary $PART_START $PART_NEW_END`
|
||||
NEW_IMG_SIZE=`parted -s -m "$NBD_DEV" unit B print free | tail -1 | awk -F: ' { print substr($2,1,length($2)-1) } '`
|
||||
}
|
||||
export -f resize_qcow2
|
||||
|
||||
# create raw img from qcow2: make_bootable_image <in.qcow2> <out.img>
|
||||
function make_bootable_image() {
|
||||
|
||||
EXPORT_QCOW2="$1"
|
||||
EXPORT_IMAGE="$2"
|
||||
|
||||
echo "Connect block device to source qcow2"
|
||||
connect_blkdev "${EXPORT_QCOW2}"
|
||||
|
||||
echo "Resize fs and partition"
|
||||
CALL_FROM_MBI=1
|
||||
resize_qcow2
|
||||
sync
|
||||
CALL_FROM_MBI=
|
||||
|
||||
echo "Disconnect block device"
|
||||
disconnect_blkdev
|
||||
|
||||
if [ -z "$NEW_IMG_SIZE" ]; then
|
||||
echo "NEW_IMG_SIZE could not be calculated, cannot process image. Exit."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Shrinking qcow2 image"
|
||||
qemu-img resize --shrink "${EXPORT_QCOW2}" $NEW_IMG_SIZE
|
||||
sync
|
||||
|
||||
echo "Convert qcow2 to raw image"
|
||||
qemu-img convert -f qcow2 -O raw "${EXPORT_QCOW2}" "${EXPORT_IMAGE}"
|
||||
sync
|
||||
|
||||
echo "Get PARTUUIDs from image"
|
||||
IMGID="$(blkid -o value -s PTUUID "${EXPORT_IMAGE}")"
|
||||
|
||||
BOOT_PARTUUID="${IMGID}-01"
|
||||
echo "Boot: $BOOT_PARTUUID"
|
||||
ROOT_PARTUUID="${IMGID}-02"
|
||||
echo "Root: $ROOT_PARTUUID"
|
||||
|
||||
echo "Mount image"
|
||||
MOUNTROOT=${WORK_DIR}/tmpimage
|
||||
mkdir -p $MOUNTROOT
|
||||
|
||||
MOUNTPT=$MOUNTROOT
|
||||
PARTITION=2
|
||||
mount "${EXPORT_IMAGE}" "$MOUNTPT" -o loop,offset=$[ `/sbin/sfdisk -d "${EXPORT_IMAGE}" | grep "start=" | head -n $PARTITION | tail -n1 | sed 's/.*start=[ ]*//' | sed 's/,.*//'` * 512 ],sizelimit=$[ `/sbin/sfdisk -d "${EXPORT_IMAGE}" | grep "start=" | head -n $PARTITION | tail -n1 | sed 's/.*size=[ ]*//' | sed 's/,.*//'` * 512 ] || exit 1
|
||||
|
||||
MOUNTPT=$MOUNTROOT/boot
|
||||
PARTITION=1
|
||||
mount "${EXPORT_IMAGE}" "$MOUNTPT" -o loop,offset=$[ `/sbin/sfdisk -d "${EXPORT_IMAGE}" | grep "start=" | head -n $PARTITION | tail -n1 | sed 's/.*start=[ ]*//' | sed 's/,.*//'` * 512 ],sizelimit=$[ `/sbin/sfdisk -d "${EXPORT_IMAGE}" | grep "start=" | head -n $PARTITION | tail -n1 | sed 's/.*size=[ ]*//' | sed 's/,.*//'` * 512 ] || exit 1
|
||||
|
||||
if [ ! -d "${MOUNTROOT}/root" ]; then
|
||||
echo "Image damaged or not mounted. Exit."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Setup PARTUUIDs"
|
||||
if [ ! -z "$BOOT_PARTUUID" ] && [ ! -z "$ROOT_PARTUUID" ]; then
|
||||
echo "Set UUIDs to make it bootable"
|
||||
sed -i "s/BOOTDEV/PARTUUID=${BOOT_PARTUUID}/" "${MOUNTROOT}/etc/fstab"
|
||||
sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${MOUNTROOT}/etc/fstab"
|
||||
sed -i "s/ROOTDEV/PARTUUID=${ROOT_PARTUUID}/" "${MOUNTROOT}/boot/cmdline.txt"
|
||||
fi
|
||||
|
||||
echo "Umount image"
|
||||
sync
|
||||
umount "${MOUNTROOT}/boot" || exit 1
|
||||
umount "${MOUNTROOT}" || exit 1
|
||||
|
||||
echo "Remove qcow2 export image"
|
||||
rm -f "${EXPORT_QCOW2}"
|
||||
}
|
||||
export -f make_bootable_image
|
|
@ -12,9 +12,8 @@ else
|
|||
rm -f "${ROOTFS_DIR}/etc/apt/apt.conf.d/51cache"
|
||||
fi
|
||||
|
||||
cat files/raspberrypi.gpg.key | gpg --dearmor > "${ROOTFS_DIR}/etc/apt/trusted.gpg.d/raspberrypi-archive-stable.gpg"
|
||||
on_chroot apt-key add - < files/raspberrypi.gpg.key
|
||||
on_chroot << EOF
|
||||
dpkg --add-architecture armhf
|
||||
apt-get update
|
||||
apt-get dist-upgrade -y
|
||||
EOF
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
raspberrypi-archive-keyring
|
|
@ -1,7 +1,3 @@
|
|||
deb http://deb.debian.org/debian RELEASE main contrib non-free
|
||||
deb http://security.debian.org/debian-security RELEASE-security main contrib non-free
|
||||
deb http://deb.debian.org/debian RELEASE-updates main contrib non-free
|
||||
# Uncomment deb-src lines below then 'apt-get update' to enable 'apt-get source'
|
||||
#deb-src http://deb.debian.org/debian RELEASE main contrib non-free
|
||||
#deb-src http://security.debian.org/debian-security RELEASE-security main contrib non-free
|
||||
#deb-src http://deb.debian.org/debian RELEASE-updates main contrib non-free
|
||||
deb http://raspbian.raspberrypi.org/raspbian/ RELEASE main contrib non-free rpi
|
||||
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
|
||||
#deb-src http://raspbian.raspberrypi.org/raspbian/ RELEASE main contrib non-free rpi
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
if [ ! -d "${ROOTFS_DIR}" ] || [ "${USE_QCOW2}" = "1" ]; then
|
||||
bootstrap ${RELEASE} "${ROOTFS_DIR}" http://deb.debian.org/debian/
|
||||
if [ ! -d "${ROOTFS_DIR}" ]; then
|
||||
bootstrap ${RELEASE} "${ROOTFS_DIR}" http://raspbian.raspberrypi.org/raspbian/
|
||||
fi
|
||||
|
|
|
@ -1 +1 @@
|
|||
console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 fsck.repair=yes rootwait
|
||||
console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
# uncomment if you get no picture on HDMI for a default "safe" mode
|
||||
#hdmi_safe=1
|
||||
|
||||
# uncomment this if your display has a black border of unused pixels visible
|
||||
# and your display can output without overscan
|
||||
#disable_overscan=1
|
||||
|
||||
# uncomment the following to adjust overscan. Use positive numbers if console
|
||||
# goes off screen, and negative if there is too much border
|
||||
#overscan_left=16
|
||||
|
@ -52,32 +56,10 @@
|
|||
# Enable audio (loads snd_bcm2835)
|
||||
dtparam=audio=on
|
||||
|
||||
# Automatically load overlays for detected cameras
|
||||
camera_auto_detect=1
|
||||
|
||||
# Automatically load overlays for detected DSI displays
|
||||
display_auto_detect=1
|
||||
|
||||
# Enable DRM VC4 V3D driver
|
||||
dtoverlay=vc4-kms-v3d
|
||||
[pi4]
|
||||
# Enable DRM VC4 V3D driver on top of the dispmanx display stack
|
||||
dtoverlay=vc4-fkms-v3d
|
||||
max_framebuffers=2
|
||||
|
||||
# Run in 64-bit mode
|
||||
arm_64bit=1
|
||||
|
||||
# Disable compensation for displays with overscan
|
||||
disable_overscan=1
|
||||
|
||||
[cm4]
|
||||
# Enable host mode on the 2711 built-in XHCI USB controller.
|
||||
# This line should be removed if the legacy DWC2 controller is required
|
||||
# (e.g. for USB device mode) or if USB support is not required.
|
||||
otg_mode=1
|
||||
|
||||
[all]
|
||||
|
||||
[pi4]
|
||||
# Run as fast as firmware / board allows
|
||||
arm_boost=1
|
||||
|
||||
[all]
|
||||
#dtoverlay=vc4-fkms-v3d
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
raspi-config
|
|
@ -1,3 +1,3 @@
|
|||
proc /proc proc defaults 0 0
|
||||
BOOTDEV /boot vfat defaults,flush 0 2
|
||||
BOOTDEV /boot vfat defaults 0 2
|
||||
ROOTDEV / ext4 defaults,noatime 0 1
|
||||
|
|
|
@ -3,6 +3,4 @@
|
|||
echo "${TARGET_HOSTNAME}" > "${ROOTFS_DIR}/etc/hostname"
|
||||
echo "127.0.1.1 ${TARGET_HOSTNAME}" >> "${ROOTFS_DIR}/etc/hosts"
|
||||
|
||||
on_chroot << EOF
|
||||
SUDO_USER="${FIRST_USER_NAME}" raspi-config nonint do_net_names 1
|
||||
EOF
|
||||
ln -sf /dev/null "${ROOTFS_DIR}/etc/systemd/network/99-default.link"
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
libraspberrypi-bin libraspberrypi0
|
||||
systemd-timesyncd
|
||||
libraspberrypi-bin libraspberrypi0 raspi-config
|
||||
|
|
1
stage2/00-copies-and-fills/01-packages
Normal file
1
stage2/00-copies-and-fills/01-packages
Normal file
|
@ -0,0 +1 @@
|
|||
raspi-copies-and-fills
|
6
stage2/00-copies-and-fills/02-run.sh
Executable file
6
stage2/00-copies-and-fills/02-run.sh
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
if [ -f "${ROOTFS_DIR}/etc/ld.so.preload" ]; then
|
||||
mv "${ROOTFS_DIR}/etc/ld.so.preload" "${ROOTFS_DIR}/etc/ld.so.preload.disabled"
|
||||
fi
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
ssh less fbset sudo psmisc strace ed ncdu crda
|
||||
console-setup keyboard-configuration debconf-utils parted
|
||||
build-essential manpages-dev bash-completion gdb pkg-config
|
||||
python-is-python3
|
||||
python3-rpi.gpio v4l-utils
|
||||
python3-gpiozero
|
||||
console-setup keyboard-configuration debconf-utils parted unzip
|
||||
build-essential manpages-dev python bash-completion gdb pkg-config
|
||||
python-rpi.gpio v4l-utils
|
||||
avahi-daemon
|
||||
lua5.1
|
||||
luajit
|
||||
|
@ -28,7 +26,3 @@ rng-tools
|
|||
ethtool
|
||||
ntfs-3g
|
||||
pciutils
|
||||
rpi-eeprom
|
||||
raspinfo
|
||||
udisks2
|
||||
unzip zip p7zip-full
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
cifs-utils
|
||||
libcamera-apps-lite
|
||||
mkvtoolnix
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
--- stage2.orig/rootfs/boot/cmdline.txt
|
||||
+++ stage2/rootfs/boot/cmdline.txt
|
||||
@@ -1 +1 @@
|
||||
-console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 fsck.repair=yes rootwait
|
||||
+console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 fsck.repair=yes rootwait quiet init=/usr/lib/raspi-config/init_resize.sh
|
||||
-console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
|
||||
+console=serial0,115200 console=tty1 root=ROOTDEV rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet init=/usr/lib/raspi-config/init_resize.sh
|
||||
|
|
|
@ -11,18 +11,6 @@ install -m 644 files/console-setup "${ROOTFS_DIR}/etc/default/"
|
|||
|
||||
install -m 755 files/rc.local "${ROOTFS_DIR}/etc/"
|
||||
|
||||
if [ -n "${PUBKEY_SSH_FIRST_USER}" ]; then
|
||||
install -v -m 0700 -o 1000 -g 1000 -d "${ROOTFS_DIR}"/home/"${FIRST_USER_NAME}"/.ssh
|
||||
echo "${PUBKEY_SSH_FIRST_USER}" >"${ROOTFS_DIR}"/home/"${FIRST_USER_NAME}"/.ssh/authorized_keys
|
||||
chown 1000:1000 "${ROOTFS_DIR}"/home/"${FIRST_USER_NAME}"/.ssh/authorized_keys
|
||||
chmod 0600 "${ROOTFS_DIR}"/home/"${FIRST_USER_NAME}"/.ssh/authorized_keys
|
||||
fi
|
||||
|
||||
if [ "${PUBKEY_ONLY_SSH}" = "1" ]; then
|
||||
sed -i -Ee 's/^#?[[:blank:]]*PubkeyAuthentication[[:blank:]]*no[[:blank:]]*$/PubkeyAuthentication yes/
|
||||
s/^#?[[:blank:]]*PasswordAuthentication[[:blank:]]*yes[[:blank:]]*$/PasswordAuthentication no/' "${ROOTFS_DIR}"/etc/ssh/sshd_config
|
||||
fi
|
||||
|
||||
on_chroot << EOF
|
||||
systemctl disable hwclock.sh
|
||||
systemctl disable nfs-common
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
install -v -d "${ROOTFS_DIR}/etc/systemd/system/dhcpcd.service.d"
|
||||
install -v -m 644 files/wait.conf "${ROOTFS_DIR}/etc/systemd/system/dhcpcd.service.d/"
|
||||
|
||||
install -v -d "${ROOTFS_DIR}/etc/wpa_supplicant"
|
||||
install -v -m 600 files/wpa_supplicant.conf "${ROOTFS_DIR}/etc/wpa_supplicant/"
|
||||
|
||||
on_chroot << EOF
|
||||
SUDO_USER="${FIRST_USER_NAME}" raspi-config nonint do_boot_wait 0
|
||||
EOF
|
||||
|
||||
if [ -v WPA_COUNTRY ]; then
|
||||
echo "country=${WPA_COUNTRY}" >> "${ROOTFS_DIR}/etc/wpa_supplicant/wpa_supplicant.conf"
|
||||
fi
|
||||
|
@ -26,12 +25,7 @@ network={
|
|||
EOL
|
||||
fi
|
||||
|
||||
# Disable wifi on 5GHz models if WPA_COUNTRY is not set
|
||||
# Disable wifi on 5GHz models
|
||||
mkdir -p "${ROOTFS_DIR}/var/lib/systemd/rfkill/"
|
||||
if [ -n "$WPA_COUNTRY" ]; then
|
||||
echo 0 > "${ROOTFS_DIR}/var/lib/systemd/rfkill/platform-3f300000.mmcnr:wlan"
|
||||
echo 0 > "${ROOTFS_DIR}/var/lib/systemd/rfkill/platform-fe300000.mmcnr:wlan"
|
||||
else
|
||||
echo 1 > "${ROOTFS_DIR}/var/lib/systemd/rfkill/platform-3f300000.mmcnr:wlan"
|
||||
echo 1 > "${ROOTFS_DIR}/var/lib/systemd/rfkill/platform-fe300000.mmcnr:wlan"
|
||||
fi
|
||||
echo 1 > "${ROOTFS_DIR}/var/lib/systemd/rfkill/platform-3f300000.mmcnr:wlan"
|
||||
echo 1 > "${ROOTFS_DIR}/var/lib/systemd/rfkill/platform-fe300000.mmcnr:wlan"
|
||||
|
|
3
stage2/02-net-tweaks/files/wait.conf
Normal file
3
stage2/02-net-tweaks/files/wait.conf
Normal file
|
@ -0,0 +1,3 @@
|
|||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=/usr/lib/dhcpcd5/dhcpcd -q -w
|
|
@ -15,28 +15,10 @@ rm -f /etc/systemd/network/99-default.link
|
|||
ln -s /dev/null /etc/systemd/network/99-default.link
|
||||
EOF
|
||||
|
||||
# Enable resize2fs for first boot (without having to log-in ssh)
|
||||
on_chroot << EOF
|
||||
systemctl enable resize2fs_once
|
||||
EOF
|
||||
|
||||
# For some reason curl doesnt recognize CA in any cert
|
||||
# and this is fixed by regerating links in /etc/ssl/certs/ ...
|
||||
on_chroot << EOF
|
||||
update-ca-certificates -f -v
|
||||
EOF
|
||||
|
||||
# For some reason curl still doesnt recognize CA in any cert
|
||||
# and this is fixed by adding a ~/.curlrc file ...
|
||||
on_chroot << EOF
|
||||
echo capath=/etc/ssl/certs/ > /root/.curlrc
|
||||
echo cacert=/etc/ssl/certs/ca-certificates.crt >> /root/.curlrc
|
||||
EOF
|
||||
|
||||
# Run the actual install
|
||||
on_chroot << EOF
|
||||
apt-get install insserv resolvconf -y
|
||||
curl https://install.yunohost.org/bullseye | bash -s -- -a
|
||||
curl https://install.yunohost.org/stretch | bash -s -- -a
|
||||
rm -f /etc/ssh/ssh_host_*
|
||||
EOF
|
||||
|
||||
|
@ -46,10 +28,6 @@ sed -i '/PermitRootLogin/c\PermitRootLogin yes' /etc/ssh/sshd_config
|
|||
echo "root:yunohost" | chpasswd
|
||||
EOF
|
||||
|
||||
echo "Removing Raspbian sshd banner"
|
||||
rm -f "${ROOTFS_DIR}/etc/ssh/sshd_config.d/rename_user.conf"
|
||||
rm -f "${ROOTFS_DIR}/usr/share/userconf-pi/sshd_banner"
|
||||
|
||||
install -m 755 files/check_yunohost_is_installed.sh "${ROOTFS_DIR}/etc/profile.d/"
|
||||
|
||||
echo "Cleaning ..."
|
||||
|
@ -64,7 +42,7 @@ EOF
|
|||
# the rootfs/image after that ?
|
||||
while lsof 2>/dev/null | grep -q /root/rpi-image/work/*/export-image/rootfs/dev;
|
||||
do
|
||||
for PID in `ps -ef --forest | grep "qemu-binfmt" | grep -v "grep" | grep "nginx\|nscd\|slapd\|nslcd" | awk '{print $2}'`
|
||||
for PID in `ps -ef --forest | grep "qemu-arm-static" | grep -v "grep" | grep "nginx\|nscd\|slapd\|nslcd" | awk '{print $2}'`
|
||||
do
|
||||
echo "Killing $PID"
|
||||
kill -9 $PID || true
|
||||
|
@ -72,9 +50,9 @@ do
|
|||
done
|
||||
sleep 5
|
||||
done
|
||||
while ps -ef --forest | grep "qemu-binfmt" | grep -v "grep"
|
||||
while ps -ef --forest | grep "qemu-arm-static" | grep -v "grep"
|
||||
do
|
||||
for PID in `ps -ef --forest | grep "qemu-binfmt" | grep -v "grep" | grep "nginx\|nscd\|slapd\|nslcd" | awk '{print $2}'`
|
||||
for PID in `ps -ef --forest | grep "qemu-arm-static" | grep -v "grep" | grep "nginx\|nscd\|slapd\|nslcd" | awk '{print $2}'`
|
||||
do
|
||||
echo "Killing $PID"
|
||||
kill -9 $PID || true
|
||||
|
|
Loading…
Reference in a new issue