Compare commits
No commits in common. "master" and "main" have entirely different histories.
|
@ -1,26 +0,0 @@
|
||||||
# suggested build result and log filenames
|
|
||||||
raspi*.bmap
|
|
||||||
raspi*.img
|
|
||||||
raspi*.img.xz
|
|
||||||
raspi*.log
|
|
||||||
raspi*.tar.gz
|
|
||||||
raspi*.sha256
|
|
||||||
raspi_base_bullseye.yaml
|
|
||||||
raspi_1_bullseye.yaml
|
|
||||||
raspi_2_bullseye.yaml
|
|
||||||
raspi_3_bullseye.yaml
|
|
||||||
raspi_4_bullseye.yaml
|
|
||||||
raspi_base_bookworm.yaml
|
|
||||||
raspi_1_bookworm.yaml
|
|
||||||
raspi_2_bookworm.yaml
|
|
||||||
raspi_3_bookworm.yaml
|
|
||||||
raspi_4_bookworm.yaml
|
|
||||||
raspi_base_trixie.yaml
|
|
||||||
raspi_1_trixie.yaml
|
|
||||||
raspi_2_trixie.yaml
|
|
||||||
raspi_3_trixie.yaml
|
|
||||||
raspi_4_trixie.yaml
|
|
||||||
*.log
|
|
||||||
*.img.xz
|
|
||||||
*.img.gz
|
|
||||||
*.img
|
|
28
LICENSE
28
LICENSE
|
@ -1,27 +1,11 @@
|
||||||
Copyright © 2017, Michael Stapelberg and contributors
|
Copyright (c) 2024 Hibbian.
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
* Neither the name of Michael Stapelberg nor the
|
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
names of contributors may be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY Michael Stapelberg ''AS IS'' AND ANY
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
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 Michael Stapelberg 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.
|
|
||||||
|
|
75
Makefile
75
Makefile
|
@ -1,75 +0,0 @@
|
||||||
all: shasums
|
|
||||||
|
|
||||||
# List all the supported and built Pi platforms here. They get expanded
|
|
||||||
# to names like 'raspi_2_buster.yaml' and 'raspi_3_bullseye.img.xz'.
|
|
||||||
BUILD_FAMILIES := 1 2 3 4
|
|
||||||
BUILD_RELEASES := bullseye bookworm trixie
|
|
||||||
|
|
||||||
platforms := $(foreach plat, $(BUILD_FAMILIES),$(foreach rel, $(BUILD_RELEASES), raspi_$(plat)_$(rel)))
|
|
||||||
|
|
||||||
shasums: $(addsuffix .img.sha256,$(platforms)) $(addsuffix .img.xz.sha256,$(platforms))
|
|
||||||
xzimages: $(addsuffix .img.xz,$(platforms))
|
|
||||||
images: $(addsuffix .img,$(platforms))
|
|
||||||
yaml: $(addsuffix .yaml,$(platforms))
|
|
||||||
|
|
||||||
ifeq ($(shell id -u),0)
|
|
||||||
as_root =
|
|
||||||
else ifneq (,$(wildcard /usr/bin/fakemachine))
|
|
||||||
$(warning "This should normally be run as root, but found 'fakemachine', so using that.")
|
|
||||||
as_root = fakemachine -v $(CURDIR) -- env --chdir $(CURDIR)
|
|
||||||
else
|
|
||||||
$(error "This must be run as root")
|
|
||||||
endif
|
|
||||||
|
|
||||||
target_platforms:
|
|
||||||
@echo $(platforms)
|
|
||||||
|
|
||||||
# Generate targets based on all family * release combinations:
|
|
||||||
define dynamic_yaml_target =
|
|
||||||
raspi_$(1)_$(2).yaml: raspi_master.yaml generate-recipe.py
|
|
||||||
raspi_$(1)_$(2).yaml:
|
|
||||||
./generate-recipe.py $(1) $(2)
|
|
||||||
endef
|
|
||||||
$(foreach release,$(BUILD_RELEASES), \
|
|
||||||
$(foreach family,$(BUILD_FAMILIES), \
|
|
||||||
$(eval $(call dynamic_yaml_target,$(family),$(release)))))
|
|
||||||
|
|
||||||
%.img.sha256: %.img
|
|
||||||
echo $@
|
|
||||||
sha256sum $< > $@
|
|
||||||
|
|
||||||
%.img.xz.sha256: %.img.xz
|
|
||||||
echo $@
|
|
||||||
sha256sum $< > $@
|
|
||||||
|
|
||||||
%.img.xz: %.img
|
|
||||||
xz -f -k -z -9 $<
|
|
||||||
|
|
||||||
%.img.bmap: %.img
|
|
||||||
bmaptool create -o $@ $<
|
|
||||||
|
|
||||||
%.img: %.yaml
|
|
||||||
touch $(@:.img=.log)
|
|
||||||
time nice $(as_root) vmdb2 --verbose --rootfs-tarball=$(subst .img,.tar.gz,$@) --output=$@ $(subst .img,.yaml,$@) --log $(subst .img,.log,$@)
|
|
||||||
chmod 0644 $@ $(@,.img=.log)
|
|
||||||
|
|
||||||
_ck_root:
|
|
||||||
[ `whoami` = 'root' ] # Only root can summon vmdb2 ☹
|
|
||||||
|
|
||||||
_clean_yaml:
|
|
||||||
rm -f $(addsuffix .yaml,$(platforms)) raspi_base_bullseye.yaml raspi_base_bookworm.yaml raspi_base_trixie.yaml
|
|
||||||
_clean_images:
|
|
||||||
rm -f $(addsuffix .img,$(platforms))
|
|
||||||
_clean_xzimages:
|
|
||||||
rm -f $(addsuffix .img.xz,$(platforms))
|
|
||||||
_clean_bmaps:
|
|
||||||
rm -f $(addsuffix .img.bmap,$(platforms))
|
|
||||||
_clean_shasums:
|
|
||||||
rm -f $(addsuffix .img.sha256,$(platforms)) $(addsuffix .img.xz.sha256,$(platforms))
|
|
||||||
_clean_logs:
|
|
||||||
rm -f $(addsuffix .log,$(platforms))
|
|
||||||
_clean_tarballs:
|
|
||||||
rm -f $(addsuffix .tar.gz,$(platforms))
|
|
||||||
clean: _clean_xzimages _clean_images _clean_shasums _clean_yaml _clean_tarballs _clean_logs _clean_bmaps
|
|
||||||
|
|
||||||
.PHONY: _ck_root _build_img clean _clean_images _clean_yaml _clean_tarballs _clean_logs
|
|
135
README.md
135
README.md
|
@ -1,134 +1,3 @@
|
||||||
# Raspberry Pi image specs
|
# Raspi-image-spec
|
||||||
|
|
||||||
This repository contains the files with which the images referenced at
|
Image specs for the raspi build.
|
||||||
https://wiki.debian.org/RaspberryPiImages have been built.
|
|
||||||
|
|
||||||
## Option 1: Downloading an image
|
|
||||||
|
|
||||||
See https://wiki.debian.org/RaspberryPiImages for where to obtain the
|
|
||||||
latest pre-built image.
|
|
||||||
|
|
||||||
## Option 2: Building your own image
|
|
||||||
|
|
||||||
If you prefer, you can build a Debian Raspberry Pi image
|
|
||||||
yourself. If you are reading this document online, you should first
|
|
||||||
clone this repository:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
git clone --recursive https://salsa.debian.org/raspi-team/image-specs.git
|
|
||||||
cd image-specs
|
|
||||||
```
|
|
||||||
|
|
||||||
For this you will first need to install the following packages on a
|
|
||||||
Debian Bullseye (11) or higher system:
|
|
||||||
|
|
||||||
* binfmt-support
|
|
||||||
* bmap-tools
|
|
||||||
* debootstrap
|
|
||||||
* dosfstools
|
|
||||||
* fakemachine (optional, only available on amd64)
|
|
||||||
* kpartx
|
|
||||||
* qemu-utils
|
|
||||||
* qemu-user-static
|
|
||||||
* time
|
|
||||||
* vmdb2 (>= 0.17)
|
|
||||||
* python3
|
|
||||||
* zerofree (because of [#1021341](https://bugs.debian.org/1021341))
|
|
||||||
|
|
||||||
To install these (as root):
|
|
||||||
```shell
|
|
||||||
apt install -y vmdb2 dosfstools qemu-utils qemu-user-static debootstrap binfmt-support time kpartx bmap-tools python3 zerofree
|
|
||||||
apt install -y fakemachine
|
|
||||||
```
|
|
||||||
|
|
||||||
If debootstrap still fails with exec format error, try
|
|
||||||
running `dpkg-reconfigure qemu-user-static`. This calls
|
|
||||||
`/var/lib/dpkg/info/qemu-user-static.postinst` which uses binfmt-support
|
|
||||||
to register the executable format with /usr/bin/qemu-$fmt-static
|
|
||||||
|
|
||||||
This repository includes a master YAML recipe (which is basically a
|
|
||||||
configuration file) for all of the generated images, diverting as
|
|
||||||
little as possible in a parametrized way. The master recipe is
|
|
||||||
[raspi_master.yaml](raspi_master.yaml).
|
|
||||||
|
|
||||||
A Makefile is supplied to drive the build of the recipes into images.
|
|
||||||
If `fakemachine` is installed, it can be run as an unprivileged user.
|
|
||||||
Otherwise, because some steps of building the image require root privileges,
|
|
||||||
you'll need to execute `make` as root.
|
|
||||||
|
|
||||||
The argument to `make` is constructed as follows:
|
|
||||||
`raspi_<model>_<release>.<result-type>`
|
|
||||||
|
|
||||||
Whereby <model\> is one of `1`, `2`, `3` or `4`, <release\> is either
|
|
||||||
`bullseye`, `bookworm`, or `trixie`; and <result-type\> is `img` or `yaml`.
|
|
||||||
|
|
||||||
Model `1` should be used for the Raspberry Pi 0, 0w and 1, models A and
|
|
||||||
B. Model `2` for the Raspberry Pi 2 models A and B. Model `3` for all
|
|
||||||
models of the Raspberry Pi 3 and model `4` for all models of the
|
|
||||||
Raspberry Pi 4.
|
|
||||||
So if you want to build the default image for a Raspberry Pi 3B+ with
|
|
||||||
Bullseye, you can just issue:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
make raspi_3_bullseye.img
|
|
||||||
```
|
|
||||||
|
|
||||||
This will first create a `raspi_3_bullseye.yaml` file and then use that
|
|
||||||
*yaml* recipe to build the image with `vmdb2`.
|
|
||||||
|
|
||||||
You can also edit the `yaml` file to customize the built image. If you
|
|
||||||
want to start from the platform-specific recipe, you can issue:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
make raspi_3_bullseye.yaml
|
|
||||||
```
|
|
||||||
The recipe drives [vmdb2](https://vmdb2.liw.fi/), the successor to
|
|
||||||
`vmdebootstrap`. Please refer to [its
|
|
||||||
documentation](https://vmdb2.liw.fi/documentation/) for further details;
|
|
||||||
it is quite an easy format to understand.
|
|
||||||
|
|
||||||
Copy the generated file to a name descriptive enough for you (say,
|
|
||||||
`my_raspi_bullseye.yaml`). Once you have edited the recipe for your
|
|
||||||
specific needs, you can generate the image by issuing the following (as
|
|
||||||
root):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
vmdb2 --rootfs-tarball=my_raspi_bullseye.tar.gz --output \
|
|
||||||
my_raspi_bullseye.img my_raspi_bullseye.yaml --log my_raspi_bullseye.log
|
|
||||||
```
|
|
||||||
|
|
||||||
This is, just follow what is done by the `_build_img` target of the
|
|
||||||
Makefile.
|
|
||||||
|
|
||||||
## Installing the image onto the Raspberry Pi
|
|
||||||
|
|
||||||
Plug an SD card which you would like to entirely overwrite into your SD card reader.
|
|
||||||
|
|
||||||
Assuming your SD card reader provides the device `/dev/mmcblk0`
|
|
||||||
(**Beware** If you choose the wrong device, you might overwrite
|
|
||||||
important parts of your system. Double check it's the correct
|
|
||||||
device!), copy the image onto the SD card:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
bmaptool copy raspi_3_bullseye.img.xz /dev/mmcblk0
|
|
||||||
```
|
|
||||||
|
|
||||||
Alternatively, if you don't have `bmap-tools` installed, you can use
|
|
||||||
`dd` with the compressed image:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
xzcat raspi_3_bullseye.img.xz | dd of=/dev/mmcblk0 bs=64k oflag=dsync status=progress
|
|
||||||
```
|
|
||||||
|
|
||||||
Or with the uncompressed image:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
dd if=raspi_3_bullseye.img of=/dev/mmcblk0 bs=64k oflag=dsync status=progress
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, plug the SD card into the Raspberry Pi, and power it up.
|
|
||||||
|
|
||||||
The image uses the hostname `rpi0w`, `rpi2`, `rpi3`, or `rpi4` depending on the
|
|
||||||
target build. The provided image will allow you to log in with the
|
|
||||||
`root` account with no password set, but only logging in at the
|
|
||||||
physical console (be it serial or by USB keyboard and HDMI monitor).
|
|
|
@ -1,43 +0,0 @@
|
||||||
---
|
|
||||||
stages:
|
|
||||||
# Garbage in is garbage out, so verify our input
|
|
||||||
- check input
|
|
||||||
- build
|
|
||||||
|
|
||||||
variables:
|
|
||||||
DEBIAN_FRONTEND: "noninteractive"
|
|
||||||
# At https://salsa.debian.org/salsa-ci-team/pipeline/container_registry one can see which images are available
|
|
||||||
SALSA_CI_IMAGES: registry.salsa.debian.org/salsa-ci-team/pipeline
|
|
||||||
BASE_CI_IMAGES: ${SALSA_CI_IMAGES}/base
|
|
||||||
|
|
||||||
yamllint:
|
|
||||||
stage: check input
|
|
||||||
image: $BASE_CI_IMAGES:unstable
|
|
||||||
dependencies: []
|
|
||||||
script:
|
|
||||||
- apt-get update && apt-get upgrade -y
|
|
||||||
- apt-get install -y yamllint
|
|
||||||
- yamllint -c debian/yamllint.yml .
|
|
||||||
|
|
||||||
shellcheck:
|
|
||||||
stage: check input
|
|
||||||
image: $BASE_CI_IMAGES:unstable
|
|
||||||
dependencies: []
|
|
||||||
script:
|
|
||||||
- apt-get update && apt-get upgrade -y
|
|
||||||
- apt-get install -y shellcheck
|
|
||||||
- shellcheck -e SC1090,SC1091 -s dash $(find rootfs/etc/initramfs-tools -type f -executable | xargs grep -l '^#!/bin/sh')
|
|
||||||
|
|
||||||
build yamls:
|
|
||||||
stage: build
|
|
||||||
image: $BASE_CI_IMAGES:unstable
|
|
||||||
dependencies: []
|
|
||||||
script:
|
|
||||||
- apt-get update && apt-get upgrade -y
|
|
||||||
- apt-get install -y python3 make git
|
|
||||||
- make yaml
|
|
||||||
- mkdir build
|
|
||||||
- cp raspi*.yaml build/
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- build/
|
|
|
@ -1,6 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
extends: default
|
|
||||||
|
|
||||||
rules:
|
|
||||||
line-length: disable
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,157 +0,0 @@
|
||||||
#!/usr/bin/python3
|
|
||||||
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
# pylint: disable=invalid-name
|
|
||||||
|
|
||||||
### Sanity/usage checks
|
|
||||||
|
|
||||||
if len(sys.argv) != 3:
|
|
||||||
print("E: need 2 arguments", file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
version = sys.argv[1]
|
|
||||||
if version not in ["1", "2", "3", "4"]:
|
|
||||||
print("E: unsupported version %s" % version, file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
suite = sys.argv[2]
|
|
||||||
if suite not in ['bullseye', 'bookworm', 'trixie']:
|
|
||||||
print("E: unsupported suite %s" % suite, file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
target_yaml = 'raspi_%s_%s.yaml' % (version, suite)
|
|
||||||
|
|
||||||
|
|
||||||
### Setting variables based on suite and version starts here
|
|
||||||
|
|
||||||
# Arch, kernel, DTB:
|
|
||||||
if version == '1':
|
|
||||||
arch = 'armel'
|
|
||||||
linux = 'linux-image-rpi'
|
|
||||||
dtb = '/usr/lib/linux-image-*-rpi/bcm*rpi-*.dtb'
|
|
||||||
elif version == '2':
|
|
||||||
arch = 'armhf'
|
|
||||||
linux = 'linux-image-armmp'
|
|
||||||
dtb = '/usr/lib/linux-image-*-armmp/bcm*rpi*.dtb'
|
|
||||||
elif version in ['3', '4']:
|
|
||||||
arch = 'arm64'
|
|
||||||
linux = 'linux-image-arm64'
|
|
||||||
dtb = '/usr/lib/linux-image-*-arm64/broadcom/bcm*rpi*.dtb'
|
|
||||||
|
|
||||||
# Bookworm introduced the 'non-free-firmware' component¹; before that,
|
|
||||||
# raspi-firmware was in 'non-free'
|
|
||||||
#
|
|
||||||
# ¹ https://www.debian.org/vote/2022/vote_003
|
|
||||||
if suite != 'bullseye':
|
|
||||||
firmware_component = 'non-free-firmware'
|
|
||||||
firmware_component_old = 'non-free'
|
|
||||||
else:
|
|
||||||
firmware_component = 'non-free'
|
|
||||||
firmware_component_old = ''
|
|
||||||
|
|
||||||
# wireless firmware:
|
|
||||||
if version != '2':
|
|
||||||
wireless_firmware = 'firmware-brcm80211'
|
|
||||||
else:
|
|
||||||
wireless_firmware = ''
|
|
||||||
|
|
||||||
# bluetooth firmware:
|
|
||||||
if version != '2':
|
|
||||||
bluetooth_firmware = 'bluez-firmware'
|
|
||||||
else:
|
|
||||||
bluetooth_firmware = ''
|
|
||||||
|
|
||||||
# Pi 4 on buster required some backports. Let's keep variables around, ready to
|
|
||||||
# be used whenever we need to pull specific things from backports.
|
|
||||||
backports_enable = False
|
|
||||||
backports_suite = '%s-backports' % suite
|
|
||||||
|
|
||||||
# Serial console:
|
|
||||||
if version in ['1', '2']:
|
|
||||||
serial = 'ttyAMA0,115200'
|
|
||||||
elif version in ['3', '4']:
|
|
||||||
serial = 'ttyS1,115200'
|
|
||||||
|
|
||||||
# CMA fixup:
|
|
||||||
extra_chroot_shell_cmds = []
|
|
||||||
if version == '4':
|
|
||||||
extra_chroot_shell_cmds = [
|
|
||||||
"sed -i 's/cma=64M //' /boot/firmware/cmdline.txt",
|
|
||||||
]
|
|
||||||
|
|
||||||
# Hostname:
|
|
||||||
hostname = 'rpi_%s' % version
|
|
||||||
|
|
||||||
# Nothing yet!
|
|
||||||
extra_root_shell_cmds = []
|
|
||||||
|
|
||||||
|
|
||||||
### The following prepares substitutions based on variables set earlier
|
|
||||||
|
|
||||||
# Enable backports with a reason, or add commented-out entry:
|
|
||||||
if backports_enable:
|
|
||||||
backports_stanza = """
|
|
||||||
%s
|
|
||||||
deb http://deb.debian.org/debian/ %s main %s
|
|
||||||
""" % (backports_enable, backports_suite, firmware_component)
|
|
||||||
else:
|
|
||||||
# ugh
|
|
||||||
backports_stanza = """
|
|
||||||
# Backports are _not_ enabled by default.
|
|
||||||
# Enable them by uncommenting the following line:
|
|
||||||
# deb http://deb.debian.org/debian %s main %s
|
|
||||||
""" % (backports_suite, firmware_component)
|
|
||||||
|
|
||||||
gitcommit = subprocess.getoutput("git show -s --pretty='format:%C(auto)%h (%s, %ad)' --date=short ")
|
|
||||||
buildtime = subprocess.getoutput("date --utc +'%Y-%m-%d %H:%M'")
|
|
||||||
|
|
||||||
### Write results:
|
|
||||||
|
|
||||||
def align_replace(text, pattern, replacement):
|
|
||||||
"""
|
|
||||||
This helper lets us keep the indentation of the matched pattern
|
|
||||||
with the upcoming replacement, across multiple lines. Naive
|
|
||||||
implementation, please make it more pythonic!
|
|
||||||
"""
|
|
||||||
lines = text.splitlines()
|
|
||||||
for i, line in enumerate(lines):
|
|
||||||
m = re.match(r'^(\s+)%s' % pattern, line)
|
|
||||||
if m:
|
|
||||||
indent = m.group(1)
|
|
||||||
del lines[i]
|
|
||||||
for r in replacement:
|
|
||||||
lines.insert(i, '%s%s' % (indent, r))
|
|
||||||
i = i + 1
|
|
||||||
break
|
|
||||||
return '\n'. join(lines) + '\n'
|
|
||||||
|
|
||||||
|
|
||||||
with open('raspi_master.yaml', 'r') as in_file:
|
|
||||||
with open(target_yaml, 'w') as out_file:
|
|
||||||
in_text = in_file.read()
|
|
||||||
out_text = in_text \
|
|
||||||
.replace('__RELEASE__', suite) \
|
|
||||||
.replace('__ARCH__', arch) \
|
|
||||||
.replace('__FIRMWARE_COMPONENT__', firmware_component) \
|
|
||||||
.replace('__FIRMWARE_COMPONENT_OLD__', firmware_component_old) \
|
|
||||||
.replace('__LINUX_IMAGE__', linux) \
|
|
||||||
.replace('__DTB__', dtb) \
|
|
||||||
.replace('__WIRELESS_FIRMWARE__', wireless_firmware) \
|
|
||||||
.replace('__BLUETOOTH_FIRMWARE__', bluetooth_firmware) \
|
|
||||||
.replace('__SERIAL_CONSOLE__', serial) \
|
|
||||||
.replace('__HOST__', hostname) \
|
|
||||||
.replace('__GITCOMMIT__', gitcommit) \
|
|
||||||
.replace('__BUILDTIME__', buildtime)
|
|
||||||
|
|
||||||
out_text = align_replace(out_text, '__EXTRA_ROOT_SHELL_CMDS__', extra_root_shell_cmds)
|
|
||||||
out_text = align_replace(out_text, '__EXTRA_CHROOT_SHELL_CMDS__', extra_chroot_shell_cmds)
|
|
||||||
out_text = align_replace(out_text, '__BACKPORTS__', backports_stanza.splitlines())
|
|
||||||
|
|
||||||
# Try not to keep lines where the placeholder was replaced
|
|
||||||
# with nothing at all (including on a "list item" line):
|
|
||||||
filtered = [x for x in out_text.splitlines()
|
|
||||||
if not re.match(r'^\s+$', x)
|
|
||||||
and not re.match(r'^\s+-\s*$', x)]
|
|
||||||
out_file.write('\n'.join(filtered) + "\n")
|
|
|
@ -1,199 +0,0 @@
|
||||||
---
|
|
||||||
# See https://wiki.debian.org/RaspberryPi3 for known issues and more details.
|
|
||||||
# image.yml based on revision: ff7fdbf (Switch from qemu-debootstrap to debootstrap., 2024-01-01)
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- mkimg: "{{ output }}"
|
|
||||||
size: 2500M
|
|
||||||
|
|
||||||
- mklabel: msdos
|
|
||||||
device: "{{ output }}"
|
|
||||||
|
|
||||||
- mkpart: primary
|
|
||||||
fs-type: 'fat32'
|
|
||||||
device: "{{ output }}"
|
|
||||||
start: 4MiB
|
|
||||||
end: 512MiB
|
|
||||||
tag: tag-firmware
|
|
||||||
|
|
||||||
- mkpart: primary
|
|
||||||
device: "{{ output }}"
|
|
||||||
start: 512MiB
|
|
||||||
end: 100%
|
|
||||||
tag: tag-root
|
|
||||||
|
|
||||||
- kpartx: "{{ output }}"
|
|
||||||
|
|
||||||
- mkfs: vfat
|
|
||||||
partition: tag-firmware
|
|
||||||
label: RASPIFIRM
|
|
||||||
|
|
||||||
- mkfs: ext4
|
|
||||||
partition: tag-root
|
|
||||||
label: RASPIROOT
|
|
||||||
|
|
||||||
- mount: tag-root
|
|
||||||
|
|
||||||
- mount: tag-firmware
|
|
||||||
mount-on: tag-root
|
|
||||||
dirname: '/boot/firmware'
|
|
||||||
|
|
||||||
- unpack-rootfs: tag-root
|
|
||||||
|
|
||||||
- debootstrap: bookworm
|
|
||||||
require_empty_target: false
|
|
||||||
mirror: http://deb.debian.org/debian
|
|
||||||
target: tag-root
|
|
||||||
arch: arm64
|
|
||||||
components:
|
|
||||||
- main
|
|
||||||
- non-free-firmware
|
|
||||||
- non-free
|
|
||||||
unless: rootfs_unpacked
|
|
||||||
|
|
||||||
- create-file: /etc/apt/sources.list
|
|
||||||
contents: |+
|
|
||||||
deb http://deb.debian.org/debian bookworm main non-free-firmware non-free
|
|
||||||
deb http://deb.debian.org/debian bookworm-updates main non-free-firmware non-free
|
|
||||||
deb http://security.debian.org/debian-security bookworm-security main non-free-firmware non-free
|
|
||||||
# Backports are _not_ enabled by default.
|
|
||||||
# Enable them by uncommenting the following line:
|
|
||||||
deb http://deb.debian.org/debian bookworm-backports main non-free-firmware
|
|
||||||
|
|
||||||
- create-file: /etc/apt/preferences.d/hibbian.pref
|
|
||||||
contents: |+
|
|
||||||
Package: *
|
|
||||||
Pin: release o=Hibbian
|
|
||||||
Pin-Priority: 600
|
|
||||||
|
|
||||||
- create-file: /etc/apt/preferences.d/hibbian.pref
|
|
||||||
contents: |+
|
|
||||||
Package: linux-image
|
|
||||||
Pin: release o=Debian Backports
|
|
||||||
Pin-Priority: 500
|
|
||||||
|
|
||||||
- create-file: /etc/apt/sources.list.d/hibbian.list
|
|
||||||
contents: |+
|
|
||||||
deb http://repo.hibbian.org/hibbian bookworm-hibbian-unstable main non-free-firmware non-free
|
|
||||||
|
|
||||||
- copy-file: /etc/apt/trusted.gpg.d/hibbian-archive-keyring.gpg
|
|
||||||
src: etc/apt/trusted.gpg.d/hibbian-archive-keyring.gpg
|
|
||||||
perm: 0755
|
|
||||||
|
|
||||||
- copy-file: /etc/initramfs-tools/hooks/rpi-resizerootfs
|
|
||||||
src: rootfs/etc/initramfs-tools/hooks/rpi-resizerootfs
|
|
||||||
perm: 0755
|
|
||||||
unless: rootfs_unpacked
|
|
||||||
|
|
||||||
- copy-file: /etc/initramfs-tools/scripts/local-bottom/rpi-resizerootfs
|
|
||||||
src: rootfs/etc/initramfs-tools/scripts/local-bottom/rpi-resizerootfs
|
|
||||||
perm: 0755
|
|
||||||
unless: rootfs_unpacked
|
|
||||||
|
|
||||||
- apt: install
|
|
||||||
packages:
|
|
||||||
- ca-certificates
|
|
||||||
- dosfstools
|
|
||||||
- iw
|
|
||||||
- parted
|
|
||||||
- openssh-server
|
|
||||||
- network-manager
|
|
||||||
- systemd-timesyncd
|
|
||||||
- linux-image-arm64
|
|
||||||
- raspi-firmware
|
|
||||||
- firmware-brcm80211
|
|
||||||
- bluez-firmware
|
|
||||||
- base-files
|
|
||||||
- linbpq
|
|
||||||
- sudo
|
|
||||||
- vim-nox
|
|
||||||
- net-tools
|
|
||||||
tag: tag-root
|
|
||||||
|
|
||||||
- cache-rootfs: tag-root
|
|
||||||
unless: rootfs_unpacked
|
|
||||||
|
|
||||||
- shell: |
|
|
||||||
echo "hibbian-$(date +%Y%m%d)" > "${ROOT?}/etc/hostname"
|
|
||||||
|
|
||||||
# Allow root logins locally with no password
|
|
||||||
sed -i 's,root:[^:]*:,root::,' "${ROOT?}/etc/shadow"
|
|
||||||
|
|
||||||
install -m 644 -o root -g root rootfs/etc/fstab "${ROOT?}/etc/fstab"
|
|
||||||
|
|
||||||
install -m 644 -o root -g root rootfs/etc/network/interfaces.d/eth0 "${ROOT?}/etc/network/interfaces.d/eth0"
|
|
||||||
install -m 600 -o root -g root rootfs/etc/network/interfaces.d/wlan0 "${ROOT?}/etc/network/interfaces.d/wlan0"
|
|
||||||
|
|
||||||
install -m 755 -o root -g root rootfs/usr/local/sbin/rpi-set-sysconf "${ROOT?}/usr/local/sbin/rpi-set-sysconf"
|
|
||||||
install -m 644 -o root -g root rootfs/etc/systemd/system/rpi-set-sysconf.service "${ROOT?}/etc/systemd/system/"
|
|
||||||
install -m 644 -o root -g root rootfs/boot/firmware/sysconf.txt "${ROOT?}/boot/firmware/sysconf.txt"
|
|
||||||
mkdir -p "${ROOT?}/etc/systemd/system/basic.target.requires/"
|
|
||||||
ln -s /etc/systemd/system/rpi-set-sysconf.service "${ROOT?}/etc/systemd/system/basic.target.requires/rpi-set-sysconf.service"
|
|
||||||
|
|
||||||
# Resize script is now in the initrd for first boot; no need to ship it.
|
|
||||||
rm -f "${ROOT?}/etc/initramfs-tools/hooks/rpi-resizerootfs"
|
|
||||||
rm -f "${ROOT?}/etc/initramfs-tools/scripts/local-bottom/rpi-resizerootfs"
|
|
||||||
|
|
||||||
install -m 644 -o root -g root rootfs/etc/systemd/system/rpi-reconfigure-raspi-firmware.service "${ROOT?}/etc/systemd/system/"
|
|
||||||
mkdir -p "${ROOT?}/etc/systemd/system/multi-user.target.requires/"
|
|
||||||
ln -s /etc/systemd/system/rpi-reconfigure-raspi-firmware.service "${ROOT?}/etc/systemd/system/multi-user.target.requires/rpi-reconfigure-raspi-firmware.service"
|
|
||||||
|
|
||||||
install -m 644 -o root -g root rootfs/etc/systemd/system/rpi-generate-ssh-host-keys.service "${ROOT?}/etc/systemd/system/"
|
|
||||||
ln -s /etc/systemd/system/rpi-generate-ssh-host-keys.service "${ROOT?}/etc/systemd/system/multi-user.target.requires/rpi-generate-ssh-host-keys.service"
|
|
||||||
rm -f "${ROOT?}"/etc/ssh/ssh_host_*_key*
|
|
||||||
|
|
||||||
root-fs: tag-root
|
|
||||||
|
|
||||||
# Copy the relevant device tree files to the boot partition
|
|
||||||
- chroot: tag-root
|
|
||||||
shell: |
|
|
||||||
install -m 644 -o root -g root /usr/lib/linux-image-*-arm64/broadcom/bcm*rpi*.dtb /boot/firmware/
|
|
||||||
|
|
||||||
# Clean up archive cache (likely not useful) and lists (likely outdated) to
|
|
||||||
# reduce image size by several hundred megabytes.
|
|
||||||
- chroot: tag-root
|
|
||||||
shell: |
|
|
||||||
apt-get clean
|
|
||||||
rm -rf /var/lib/apt/lists
|
|
||||||
|
|
||||||
# Modify the kernel commandline we take from the firmware to boot from
|
|
||||||
# the partition labeled raspiroot instead of forcing it to mmcblk0p2.
|
|
||||||
# Also insert the serial console right before the root= parameter.
|
|
||||||
#
|
|
||||||
# These changes will be overwritten after the hardware is probed
|
|
||||||
# after dpkg reconfigures raspi-firmware (upon first boot), so make
|
|
||||||
# sure we don't lose label-based booting.
|
|
||||||
- chroot: tag-root
|
|
||||||
shell: |
|
|
||||||
sed -i 's/root=/console=ttyS1,115200 root=/' /boot/firmware/cmdline.txt
|
|
||||||
sed -i 's#root=/dev/mmcblk0p2#root=LABEL=RASPIROOT#' /boot/firmware/cmdline.txt
|
|
||||||
sed -i 's/^#ROOTPART=.*/ROOTPART=LABEL=RASPIROOT/' /etc/default/raspi*-firmware
|
|
||||||
|
|
||||||
sed -i 's/cma=64M //' /boot/firmware/cmdline.txt
|
|
||||||
|
|
||||||
# TODO(https://github.com/larswirzenius/vmdb2/issues/24): remove once vmdb
|
|
||||||
# clears /etc/resolv.conf on its own.
|
|
||||||
- shell: |
|
|
||||||
rm "${ROOT?}/etc/resolv.conf"
|
|
||||||
root-fs: tag-root
|
|
||||||
|
|
||||||
# Clear /etc/machine-id and /var/lib/dbus/machine-id, as both should
|
|
||||||
# be auto-generated upon first boot. From the manpage
|
|
||||||
# (machine-id(5)):
|
|
||||||
#
|
|
||||||
# For normal operating system installations, where a custom image is
|
|
||||||
# created for a specific machine, /etc/machine-id should be
|
|
||||||
# populated during installation.
|
|
||||||
#
|
|
||||||
# Note this will also trigger ConditionFirstBoot=yes for systemd.
|
|
||||||
# On Buster, /etc/machine-id should be an emtpy file, not an absent file
|
|
||||||
# On Bullseye, /etc/machine-id should not exist in an image
|
|
||||||
- chroot: tag-root
|
|
||||||
shell: |
|
|
||||||
rm -f /etc/machine-id /var/lib/dbus/machine-id
|
|
||||||
echo "uninitialized" > /etc/machine-id
|
|
||||||
|
|
||||||
# Create /etc/raspi-image-id to know, from what commit the image was built
|
|
||||||
- chroot: tag-root
|
|
||||||
shell: |
|
|
||||||
echo "image based on revision: ff7fdbf (Switch from qemu-debootstrap to debootstrap., 2024-01-01) and built in 2024 with love from Hibby" > "/etc/raspi-image-id"
|
|
|
@ -1,176 +0,0 @@
|
||||||
---
|
|
||||||
# See https://wiki.debian.org/RaspberryPi3 for known issues and more details.
|
|
||||||
# image.yml based on revision: __GITCOMMIT__
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- mkimg: "{{ output }}"
|
|
||||||
size: 2500M
|
|
||||||
|
|
||||||
- mklabel: msdos
|
|
||||||
device: "{{ output }}"
|
|
||||||
|
|
||||||
- mkpart: primary
|
|
||||||
fs-type: 'fat32'
|
|
||||||
device: "{{ output }}"
|
|
||||||
start: 4MiB
|
|
||||||
end: 512MiB
|
|
||||||
tag: tag-firmware
|
|
||||||
|
|
||||||
- mkpart: primary
|
|
||||||
device: "{{ output }}"
|
|
||||||
start: 512MiB
|
|
||||||
end: 100%
|
|
||||||
tag: tag-root
|
|
||||||
|
|
||||||
- kpartx: "{{ output }}"
|
|
||||||
|
|
||||||
- mkfs: vfat
|
|
||||||
partition: tag-firmware
|
|
||||||
label: RASPIFIRM
|
|
||||||
|
|
||||||
- mkfs: ext4
|
|
||||||
partition: tag-root
|
|
||||||
label: RASPIROOT
|
|
||||||
|
|
||||||
- mount: tag-root
|
|
||||||
|
|
||||||
- mount: tag-firmware
|
|
||||||
mount-on: tag-root
|
|
||||||
dirname: '/boot/firmware'
|
|
||||||
|
|
||||||
- unpack-rootfs: tag-root
|
|
||||||
|
|
||||||
- debootstrap: __RELEASE__
|
|
||||||
require_empty_target: false
|
|
||||||
mirror: http://deb.debian.org/debian
|
|
||||||
target: tag-root
|
|
||||||
arch: __ARCH__
|
|
||||||
components:
|
|
||||||
- main
|
|
||||||
- __FIRMWARE_COMPONENT__
|
|
||||||
- __FIRMWARE_COMPONENT_OLD__
|
|
||||||
unless: rootfs_unpacked
|
|
||||||
|
|
||||||
- create-file: /etc/apt/sources.list
|
|
||||||
contents: |+
|
|
||||||
deb http://deb.debian.org/debian __RELEASE__ main __FIRMWARE_COMPONENT__ __FIRMWARE_COMPONENT_OLD__
|
|
||||||
deb http://deb.debian.org/debian __RELEASE__-updates main __FIRMWARE_COMPONENT__ __FIRMWARE_COMPONENT_OLD__
|
|
||||||
deb http://security.debian.org/debian-security __RELEASE__-security main __FIRMWARE_COMPONENT__ __FIRMWARE_COMPONENT_OLD__
|
|
||||||
__BACKPORTS__
|
|
||||||
|
|
||||||
unless: rootfs_unpacked
|
|
||||||
|
|
||||||
- copy-file: /etc/initramfs-tools/hooks/rpi-resizerootfs
|
|
||||||
src: rootfs/etc/initramfs-tools/hooks/rpi-resizerootfs
|
|
||||||
perm: 0755
|
|
||||||
unless: rootfs_unpacked
|
|
||||||
|
|
||||||
- copy-file: /etc/initramfs-tools/scripts/local-bottom/rpi-resizerootfs
|
|
||||||
src: rootfs/etc/initramfs-tools/scripts/local-bottom/rpi-resizerootfs
|
|
||||||
perm: 0755
|
|
||||||
unless: rootfs_unpacked
|
|
||||||
|
|
||||||
- apt: install
|
|
||||||
packages:
|
|
||||||
- ca-certificates
|
|
||||||
- dosfstools
|
|
||||||
- iw
|
|
||||||
- parted
|
|
||||||
- ssh
|
|
||||||
- wpasupplicant
|
|
||||||
- systemd-timesyncd
|
|
||||||
- __LINUX_IMAGE__
|
|
||||||
- raspi-firmware
|
|
||||||
- __WIRELESS_FIRMWARE__
|
|
||||||
- __BLUETOOTH_FIRMWARE__
|
|
||||||
tag: tag-root
|
|
||||||
unless: rootfs_unpacked
|
|
||||||
|
|
||||||
- cache-rootfs: tag-root
|
|
||||||
unless: rootfs_unpacked
|
|
||||||
|
|
||||||
- shell: |
|
|
||||||
echo "__HOST__-$(date +%Y%m%d)" > "${ROOT?}/etc/hostname"
|
|
||||||
|
|
||||||
# Allow root logins locally with no password
|
|
||||||
sed -i 's,root:[^:]*:,root::,' "${ROOT?}/etc/shadow"
|
|
||||||
|
|
||||||
install -m 644 -o root -g root rootfs/etc/fstab "${ROOT?}/etc/fstab"
|
|
||||||
|
|
||||||
install -m 644 -o root -g root rootfs/etc/network/interfaces.d/eth0 "${ROOT?}/etc/network/interfaces.d/eth0"
|
|
||||||
install -m 600 -o root -g root rootfs/etc/network/interfaces.d/wlan0 "${ROOT?}/etc/network/interfaces.d/wlan0"
|
|
||||||
|
|
||||||
install -m 755 -o root -g root rootfs/usr/local/sbin/rpi-set-sysconf "${ROOT?}/usr/local/sbin/rpi-set-sysconf"
|
|
||||||
install -m 644 -o root -g root rootfs/etc/systemd/system/rpi-set-sysconf.service "${ROOT?}/etc/systemd/system/"
|
|
||||||
install -m 644 -o root -g root rootfs/boot/firmware/sysconf.txt "${ROOT?}/boot/firmware/sysconf.txt"
|
|
||||||
mkdir -p "${ROOT?}/etc/systemd/system/basic.target.requires/"
|
|
||||||
ln -s /etc/systemd/system/rpi-set-sysconf.service "${ROOT?}/etc/systemd/system/basic.target.requires/rpi-set-sysconf.service"
|
|
||||||
|
|
||||||
# Resize script is now in the initrd for first boot; no need to ship it.
|
|
||||||
rm -f "${ROOT?}/etc/initramfs-tools/hooks/rpi-resizerootfs"
|
|
||||||
rm -f "${ROOT?}/etc/initramfs-tools/scripts/local-bottom/rpi-resizerootfs"
|
|
||||||
|
|
||||||
install -m 644 -o root -g root rootfs/etc/systemd/system/rpi-reconfigure-raspi-firmware.service "${ROOT?}/etc/systemd/system/"
|
|
||||||
mkdir -p "${ROOT?}/etc/systemd/system/multi-user.target.requires/"
|
|
||||||
ln -s /etc/systemd/system/rpi-reconfigure-raspi-firmware.service "${ROOT?}/etc/systemd/system/multi-user.target.requires/rpi-reconfigure-raspi-firmware.service"
|
|
||||||
|
|
||||||
install -m 644 -o root -g root rootfs/etc/systemd/system/rpi-generate-ssh-host-keys.service "${ROOT?}/etc/systemd/system/"
|
|
||||||
ln -s /etc/systemd/system/rpi-generate-ssh-host-keys.service "${ROOT?}/etc/systemd/system/multi-user.target.requires/rpi-generate-ssh-host-keys.service"
|
|
||||||
rm -f "${ROOT?}"/etc/ssh/ssh_host_*_key*
|
|
||||||
|
|
||||||
__EXTRA_ROOT_SHELL_CMDS__
|
|
||||||
root-fs: tag-root
|
|
||||||
|
|
||||||
# Copy the relevant device tree files to the boot partition
|
|
||||||
- chroot: tag-root
|
|
||||||
shell: |
|
|
||||||
install -m 644 -o root -g root __DTB__ /boot/firmware/
|
|
||||||
|
|
||||||
# Clean up archive cache (likely not useful) and lists (likely outdated) to
|
|
||||||
# reduce image size by several hundred megabytes.
|
|
||||||
- chroot: tag-root
|
|
||||||
shell: |
|
|
||||||
apt-get clean
|
|
||||||
rm -rf /var/lib/apt/lists
|
|
||||||
|
|
||||||
# Modify the kernel commandline we take from the firmware to boot from
|
|
||||||
# the partition labeled raspiroot instead of forcing it to mmcblk0p2.
|
|
||||||
# Also insert the serial console right before the root= parameter.
|
|
||||||
#
|
|
||||||
# These changes will be overwritten after the hardware is probed
|
|
||||||
# after dpkg reconfigures raspi-firmware (upon first boot), so make
|
|
||||||
# sure we don't lose label-based booting.
|
|
||||||
- chroot: tag-root
|
|
||||||
shell: |
|
|
||||||
sed -i 's/root=/console=__SERIAL_CONSOLE__ root=/' /boot/firmware/cmdline.txt
|
|
||||||
sed -i 's#root=/dev/mmcblk0p2#root=LABEL=RASPIROOT#' /boot/firmware/cmdline.txt
|
|
||||||
sed -i 's/^#ROOTPART=.*/ROOTPART=LABEL=RASPIROOT/' /etc/default/raspi*-firmware
|
|
||||||
|
|
||||||
__EXTRA_CHROOT_SHELL_CMDS__
|
|
||||||
|
|
||||||
# TODO(https://github.com/larswirzenius/vmdb2/issues/24): remove once vmdb
|
|
||||||
# clears /etc/resolv.conf on its own.
|
|
||||||
- shell: |
|
|
||||||
rm "${ROOT?}/etc/resolv.conf"
|
|
||||||
root-fs: tag-root
|
|
||||||
|
|
||||||
# Clear /etc/machine-id and /var/lib/dbus/machine-id, as both should
|
|
||||||
# be auto-generated upon first boot. From the manpage
|
|
||||||
# (machine-id(5)):
|
|
||||||
#
|
|
||||||
# For normal operating system installations, where a custom image is
|
|
||||||
# created for a specific machine, /etc/machine-id should be
|
|
||||||
# populated during installation.
|
|
||||||
#
|
|
||||||
# Note this will also trigger ConditionFirstBoot=yes for systemd.
|
|
||||||
# On Buster, /etc/machine-id should be an emtpy file, not an absent file
|
|
||||||
# On Bullseye, /etc/machine-id should not exist in an image
|
|
||||||
- chroot: tag-root
|
|
||||||
shell: |
|
|
||||||
rm -f /etc/machine-id /var/lib/dbus/machine-id
|
|
||||||
echo "uninitialized" > /etc/machine-id
|
|
||||||
|
|
||||||
# Create /etc/raspi-image-id to know, from what commit the image was built
|
|
||||||
- chroot: tag-root
|
|
||||||
shell: |
|
|
||||||
echo "image based on revision: __GITCOMMIT__ and build on __BUILDTIME__ (UTC)" > "/etc/raspi-image-id"
|
|
|
@ -1,35 +0,0 @@
|
||||||
# This file will be automatically evaluated and installed at next boot
|
|
||||||
# time, and regenerated (to avoid leaking passwords and such information).
|
|
||||||
#
|
|
||||||
# To force it to be evaluated immediately, you can run (as root):
|
|
||||||
#
|
|
||||||
# /usr/sbin/rpi-set-sysconf
|
|
||||||
#
|
|
||||||
# You can disable the file evaluation by disabling the rpi-set-sysconf
|
|
||||||
# service in systemd:
|
|
||||||
#
|
|
||||||
# systemctl disable rpi-set-sysconf
|
|
||||||
#
|
|
||||||
# Comments (all portions of a line following a '#' character) are
|
|
||||||
# ignored. This file is read line by line. Valid
|
|
||||||
# configuration lines are of the form 'key=value'. Whitespace around
|
|
||||||
# 'key' and 'value' is ignored. This file will be _regenerated_ every
|
|
||||||
# time it is evaluated.
|
|
||||||
#
|
|
||||||
# We follow the convention to indent with one space comments, and
|
|
||||||
# leave no space to indicate the line is an example that could be
|
|
||||||
# uncommented.
|
|
||||||
|
|
||||||
# root_pw - Set a password for the root user (by default, it allows
|
|
||||||
# for a passwordless login)
|
|
||||||
#root_pw=FooBar
|
|
||||||
|
|
||||||
# root_authorized_key - Set an authorized key for a root ssh login
|
|
||||||
#root_authorized_key=
|
|
||||||
|
|
||||||
# hostname - Set the system hostname.
|
|
||||||
#hostname=rpi
|
|
||||||
|
|
||||||
# We found the following unhandled keys - That means, the
|
|
||||||
# configuration script does not know how to handle them. Please
|
|
||||||
# double-check them!
|
|
|
@ -1,4 +0,0 @@
|
||||||
# The root file system has fs_passno=1 as per fstab(5) for automatic fsck.
|
|
||||||
LABEL=RASPIROOT / ext4 rw 0 1
|
|
||||||
# All other file systems have fs_passno=2 as per fstab(5) for automatic fsck.
|
|
||||||
LABEL=RASPIFIRM /boot/firmware vfat rw 0 2
|
|
|
@ -1,52 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
|
|
||||||
#
|
|
||||||
# List the soft prerequisites here. This is a space separated list of
|
|
||||||
# names, of scripts that are in the same directory as this one, that
|
|
||||||
# must be run before this one can be.
|
|
||||||
#
|
|
||||||
PREREQS=""
|
|
||||||
case $1 in
|
|
||||||
prereqs) echo "$PREREQS"; exit 0;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
. /usr/share/initramfs-tools/hook-functions
|
|
||||||
|
|
||||||
# List ALL the programs we need, because we explicitly call them
|
|
||||||
# Don't *assume* it will be included!
|
|
||||||
# The update-initramfs script will figure out any dependencies
|
|
||||||
# that also need to be included, so lets not do that
|
|
||||||
#
|
|
||||||
# Find the path as used by the package itself; usrmerge may not be used
|
|
||||||
|
|
||||||
# from coreutils
|
|
||||||
copy_exec /usr/bin/realpath
|
|
||||||
copy_exec /usr/bin/tail
|
|
||||||
copy_exec /usr/bin/test
|
|
||||||
|
|
||||||
# from dosfstools
|
|
||||||
copy_exec /sbin/fsck.vfat
|
|
||||||
|
|
||||||
# from e2fsprogs
|
|
||||||
copy_exec /sbin/resize2fs
|
|
||||||
copy_exec /sbin/fsck.ext4
|
|
||||||
|
|
||||||
# from grep
|
|
||||||
copy_exec /bin/grep
|
|
||||||
|
|
||||||
# from logsave
|
|
||||||
copy_exec /sbin/logsave
|
|
||||||
|
|
||||||
# from mount
|
|
||||||
copy_exec /bin/mount
|
|
||||||
copy_exec /bin/umount
|
|
||||||
|
|
||||||
# from parted
|
|
||||||
copy_exec /sbin/parted
|
|
||||||
copy_exec /sbin/partprobe
|
|
||||||
|
|
||||||
# from util-linux
|
|
||||||
copy_exec /bin/lsblk
|
|
||||||
copy_exec /sbin/blkid
|
|
||||||
copy_exec /sbin/fsck
|
|
|
@ -1,59 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
|
|
||||||
#
|
|
||||||
# List the soft prerequisites here. This is a space separated list of
|
|
||||||
# names, of scripts that are in the same directory as this one, that
|
|
||||||
# must be run before this one can be.
|
|
||||||
#
|
|
||||||
PREREQS=""
|
|
||||||
case $1 in
|
|
||||||
prereqs) echo "$PREREQS"; exit 0;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
. /scripts/functions
|
|
||||||
|
|
||||||
# Given the root partition, get the underlying device and partition number
|
|
||||||
rootpart=$(realpath "$ROOT")
|
|
||||||
rootpart_nr=$(blkid -sPART_ENTRY_NUMBER -o value -p "$rootpart")
|
|
||||||
rootdev="/dev/$(lsblk -no pkname "$rootpart")"
|
|
||||||
|
|
||||||
# Parted will detect if the GPT label is messed up and fix it
|
|
||||||
# automatically, we just need to tell it to do so.
|
|
||||||
parted -s "$rootdev" print 2>&1 | grep -z "fix the GPT" && {
|
|
||||||
echo "Fix" | parted ---pretend-input-tty "$rootdev" print
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if there's free space at the end of the device
|
|
||||||
free_space="$(parted -m -s "$rootdev" print free | tail -n1 | grep free)"
|
|
||||||
if test -z "$free_space"; then
|
|
||||||
# Great, we already resized; nothing left to do!
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
log_begin_msg "$0 resizing $ROOT"
|
|
||||||
|
|
||||||
# Unmount for safety; fail if unset or empty (shellcheck SC2154)
|
|
||||||
umount "${rootmnt:?}"
|
|
||||||
|
|
||||||
# Expand the partition size to fill the entire device
|
|
||||||
parted -s "$rootdev" resizepart "$rootpart_nr" 100%
|
|
||||||
|
|
||||||
wait_for_udev 5
|
|
||||||
|
|
||||||
# Now resize the filesystem
|
|
||||||
partprobe "$rootdev"
|
|
||||||
resize2fs "$rootpart"
|
|
||||||
|
|
||||||
# After resizing, (re)check the root partition's filesystem
|
|
||||||
fsck "$rootpart"
|
|
||||||
|
|
||||||
# Remount root
|
|
||||||
# Don't quote ${ROOTFLAGS} as that results in an extra (empty) argument
|
|
||||||
# to 'mount', which in turn causes a boot failure
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
if ! mount -r ${FSTYPE:+-t "${FSTYPE}"} ${ROOTFLAGS} "${ROOT}" "${rootmnt?}"; then
|
|
||||||
panic "Failed to mount ${ROOT} as root file system."
|
|
||||||
fi
|
|
||||||
|
|
||||||
log_end_msg
|
|
|
@ -1,3 +0,0 @@
|
||||||
auto eth0
|
|
||||||
iface eth0 inet dhcp
|
|
||||||
iface eth0 inet6 auto
|
|
|
@ -1,8 +0,0 @@
|
||||||
# To enable wireless networking, uncomment the following lines and -naturally-
|
|
||||||
# replace with your network's details.
|
|
||||||
#
|
|
||||||
# allow-hotplug wlan0
|
|
||||||
# iface wlan0 inet dhcp
|
|
||||||
# iface wlan0 inet6 dhcp
|
|
||||||
# wpa-ssid my-network-ssid
|
|
||||||
# wpa-psk s3kr3t_P4ss
|
|
|
@ -1,10 +0,0 @@
|
||||||
[Unit]
|
|
||||||
Description=generate SSH host keys
|
|
||||||
ConditionPathExistsGlob=!/etc/ssh/ssh_host_*_key
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
ExecStart=/usr/sbin/dpkg-reconfigure -fnoninteractive openssh-server
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
RequiredBy=multi-user.target
|
|
|
@ -1,14 +0,0 @@
|
||||||
[Unit]
|
|
||||||
Description=Reconfigure raspi-firmware to regenerate config.txt matching actual hardware
|
|
||||||
Before=sysinit.target
|
|
||||||
DefaultDependencies=no
|
|
||||||
RequiresMountsFor=/boot/firmware
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
TimeoutSec=infinity
|
|
||||||
ExecStart=/usr/sbin/dpkg-reconfigure raspi-firmware
|
|
||||||
ExecStart=/bin/systemctl --no-reload disable %n
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
RequiredBy=sysinit.target
|
|
|
@ -1,9 +0,0 @@
|
||||||
[Unit]
|
|
||||||
Description=Set up system configuration
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
ExecStart=/usr/local/sbin/rpi-set-sysconf
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
RequiredBy=basic.target
|
|
|
@ -1,157 +0,0 @@
|
||||||
#!/usr/bin/perl
|
|
||||||
use strict;
|
|
||||||
use warnings;
|
|
||||||
use IO::File;
|
|
||||||
use IO::Pipe;
|
|
||||||
use feature 'switch';
|
|
||||||
|
|
||||||
my ($filename, $conf);
|
|
||||||
|
|
||||||
$filename = '/boot/firmware/sysconf.txt';
|
|
||||||
|
|
||||||
logger('info', "Reading the system configuration settings from $filename");
|
|
||||||
$conf = read_conf($filename);
|
|
||||||
|
|
||||||
if (my $pass = delete($conf->{root_pw})) {
|
|
||||||
my $pipe;
|
|
||||||
logger('debug', 'Resetting root password');
|
|
||||||
unless (open($pipe, '|-', '/usr/sbin/chpasswd')) {
|
|
||||||
my $err = $!;
|
|
||||||
logger('error', "Could not run chpasswd: $err");
|
|
||||||
die $err;
|
|
||||||
}
|
|
||||||
$pipe->print("root:$pass");
|
|
||||||
close($pipe);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (my $root_authorized_key = delete($conf->{root_authorized_key})) {
|
|
||||||
my $fh;
|
|
||||||
logger('debug', "Adding key to root's authorized_keys");
|
|
||||||
if(! -d "/root/.ssh") {
|
|
||||||
if(!mkdir("/root/.ssh", 0700)) {
|
|
||||||
my $err = sprintf("Could not create /root/.ssh directory: %s", $!);
|
|
||||||
logger('error', $err);
|
|
||||||
die $err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unless ($fh = IO::File->new('/root/.ssh/authorized_keys', 'w', 0600)) {
|
|
||||||
my $err = $!;
|
|
||||||
logger('error', "Could not write /root/.ssh/authorized_keys: $err");
|
|
||||||
die $err;
|
|
||||||
}
|
|
||||||
$fh->print($root_authorized_key);
|
|
||||||
$fh->close;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (my $name = delete($conf->{hostname})) {
|
|
||||||
my $fh;
|
|
||||||
logger('debug', "Setting hostname to '$name'");
|
|
||||||
unless ($fh = IO::File->new('/etc/hostname', 'w')) {
|
|
||||||
my $err = $!;
|
|
||||||
logger('error', "Could not write hostname '$name': $err");
|
|
||||||
die $err;
|
|
||||||
}
|
|
||||||
$fh->print($name);
|
|
||||||
$fh->close;
|
|
||||||
system('hostname', '--file', '/etc/hostname');
|
|
||||||
}
|
|
||||||
|
|
||||||
rewrite_conf_file($filename, $conf);
|
|
||||||
|
|
||||||
exit 0;
|
|
||||||
|
|
||||||
sub read_conf {
|
|
||||||
my ($file, $conf, $fh);
|
|
||||||
$file = shift;
|
|
||||||
|
|
||||||
$conf = {};
|
|
||||||
unless ($fh = IO::File->new($filename, 'r')) {
|
|
||||||
my $err = $!;
|
|
||||||
logger('error', "Could not read from configuration file '$filename': $err");
|
|
||||||
# Not finding the config file is not fatal: there is just
|
|
||||||
# nothing to configure!
|
|
||||||
return $conf;
|
|
||||||
}
|
|
||||||
while (my $line = $fh->getline) {
|
|
||||||
my ($key, $value);
|
|
||||||
# Allow for comments, and properly ignore them
|
|
||||||
$line =~ s/#.+//;
|
|
||||||
if ( ($key, $value) = ($line =~ m/^\s*([^=]+)\s*=\s*(.*)\s*$/)) {
|
|
||||||
$key = lc($key);
|
|
||||||
if (exists($conf->{$key})) {
|
|
||||||
logger('warn',
|
|
||||||
"Repeated configuration key: $key. " .
|
|
||||||
"Overwriting with new value ($value)");
|
|
||||||
}
|
|
||||||
$conf->{$key} = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$fh->close;
|
|
||||||
|
|
||||||
return $conf;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub logger {
|
|
||||||
my ($prio, $msg) = @_;
|
|
||||||
system('logger', '-p', "daemon.$prio",
|
|
||||||
'-t', 'rpi-set-sysconf', $msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub rewrite_conf_file {
|
|
||||||
my ($filename, $conf) = @_;
|
|
||||||
my $fh;
|
|
||||||
unless ($fh = IO::File->new($filename, 'w')) {
|
|
||||||
my $err = $!;
|
|
||||||
logger('error', "Could not write to configuration file '$filename': $err");
|
|
||||||
die $err;
|
|
||||||
}
|
|
||||||
$fh->print(
|
|
||||||
q(# This file will be automatically evaluated and installed at next boot
|
|
||||||
# time, and regenerated (to avoid leaking passwords and such information).
|
|
||||||
#
|
|
||||||
# To force it to be evaluated immediately, you can run (as root):
|
|
||||||
#
|
|
||||||
# /usr/local/sbin/rpi-set-sysconf
|
|
||||||
#
|
|
||||||
# You can disable the file evaluation by disabling the rpi-set-sysconf
|
|
||||||
# service in systemd:
|
|
||||||
#
|
|
||||||
# systemctl disable rpi-set-sysconf
|
|
||||||
#
|
|
||||||
# Comments (all portions of a line following a '#' character) are
|
|
||||||
# ignored. This file is read line by line. Valid
|
|
||||||
# configuration lines are of the form 'key=value'. Whitespace around
|
|
||||||
# 'key' and 'value' is ignored. This file will be _regenerated_ every
|
|
||||||
# time it is evaluated.
|
|
||||||
#
|
|
||||||
# We follow the convention to indent with one space comments, and
|
|
||||||
# leave no space to indicate the line is an example that could be
|
|
||||||
# uncommented.
|
|
||||||
|
|
||||||
# root_pw - Set a password for the root user (by default, it allows
|
|
||||||
# for a passwordless login)
|
|
||||||
#root_pw=FooBar
|
|
||||||
|
|
||||||
# root_authorized_key - Set an authorized key for a root ssh login
|
|
||||||
#root_authorized_key=
|
|
||||||
|
|
||||||
# hostname - Set the system hostname.
|
|
||||||
#hostname=rpi
|
|
||||||
));
|
|
||||||
|
|
||||||
if (scalar keys %$conf) {
|
|
||||||
logger('warn', 'Unprocessed keys left in $filename: ' .
|
|
||||||
join(', ', sort keys %$conf));
|
|
||||||
$fh->print(
|
|
||||||
q(
|
|
||||||
# We found the following unhandled keys - That means, the
|
|
||||||
# configuration script does not know how to handle them. Please
|
|
||||||
# double-check them!
|
|
||||||
));
|
|
||||||
$fh->print(join('', map {sprintf("%s=%s\n", $_, $conf->{$_})} sort keys %$conf));
|
|
||||||
}
|
|
||||||
$fh->close;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue