Added Docker support (#40)
* Added Docker support - replaced necessity for devicemapper (through kpartx) by using parted and losetup with offsets - added Dockerfile - added dependency for parted and grep - added hints to README.md - common: loop through unmounts, fix shellcheck warnings * stage2: use debconf instead of console-setup patch. Fixes #41
This commit is contained in:
parent
bc8a74858e
commit
667318116a
3
.dockerignore
Normal file
3
.dockerignore
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
output/
|
||||||
|
work/
|
||||||
|
deploy/
|
12
Dockerfile
Normal file
12
Dockerfile
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
FROM debian:jessie
|
||||||
|
|
||||||
|
RUN apt-get -y update && \
|
||||||
|
apt-get -y install \
|
||||||
|
git vim parted \
|
||||||
|
quilt realpath qemu-user-static debootstrap zerofree pxz zip dosfstools \
|
||||||
|
bsdtar libcap2-bin rsync grep \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
COPY . /pi-gen/
|
||||||
|
|
||||||
|
VOLUME [ "/pi-gen/work", "/pi-gen/deploy"]
|
19
README.md
Normal file → Executable file
19
README.md
Normal file → Executable file
|
@ -6,7 +6,7 @@ _Tool used to create the raspberrypi.org Raspbian images_
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
`quilt kpartx realpath qemu-user-static debootstrap zerofree pxz zip dosfstools bsdtar libcap2-bin`
|
`quilt parted realpath qemu-user-static debootstrap zerofree pxz zip dosfstools bsdtar libcap2-bin grep rsync`
|
||||||
|
|
||||||
## Config
|
## Config
|
||||||
|
|
||||||
|
@ -35,10 +35,23 @@ A simple example for building Raspbian:
|
||||||
IMG_NAME='Raspbian'
|
IMG_NAME='Raspbian'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Docker Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
vi config # Edit your config file. See above.
|
||||||
|
./build-docker.sh
|
||||||
|
```
|
||||||
|
If everything goes well, your finished image will be in the `deploy/` folder.
|
||||||
|
You can then remove the build container with `docker rm pigen_work`
|
||||||
|
|
||||||
|
If something breaks along the line, you can edit the corresponding scripts, and
|
||||||
|
continue:
|
||||||
|
```
|
||||||
|
CONTINUE=1 ./build-docker.sh
|
||||||
|
```
|
||||||
|
|
||||||
## Stage Anatomy
|
## Stage Anatomy
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Raspbian Stage Overview
|
### Raspbian Stage Overview
|
||||||
|
|
||||||
The build of Raspbian is divided up into several stages for logical clarity
|
The build of Raspbian is divided up into several stages for logical clarity
|
||||||
|
|
73
build-docker.sh
Executable file
73
build-docker.sh
Executable file
|
@ -0,0 +1,73 @@
|
||||||
|
#!/bin/bash -e
|
||||||
|
DOCKER="docker"
|
||||||
|
set +e
|
||||||
|
$DOCKER ps >/dev/null 2>&1
|
||||||
|
if [ $? != 0 ]; then
|
||||||
|
DOCKER="sudo docker"
|
||||||
|
fi
|
||||||
|
if ! $DOCKER ps >/dev/null; then
|
||||||
|
echo "error connecting to docker:"
|
||||||
|
$DOCKER ps
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
set -e
|
||||||
|
|
||||||
|
config_mount=
|
||||||
|
if [ -f config ]; then
|
||||||
|
config_mount="-v $(pwd)/config:/pi-gen/config:ro"
|
||||||
|
source config
|
||||||
|
fi
|
||||||
|
|
||||||
|
CONTAINER_NAME=${CONTAINER_NAME:-pigen_work}
|
||||||
|
CONTINUE=${CONTINUE:-0}
|
||||||
|
|
||||||
|
if [ "$*" != "" ] || [ -z "${IMG_NAME}" ]; then
|
||||||
|
if [ -z "${IMG_NAME}" ]; then
|
||||||
|
echo "IMG_NAME not set in 'build'" 1>&2
|
||||||
|
echo 1>&2
|
||||||
|
fi
|
||||||
|
cat >&2 <<EOF
|
||||||
|
Usage:
|
||||||
|
build-docker.sh [options]
|
||||||
|
Optional environment arguments: ( =<default> )
|
||||||
|
CONTAINER_NAME=pigen_work set a name for the build container
|
||||||
|
CONTINUE=0 continue from a previously started container
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
CONTAINER_EXISTS=$($DOCKER ps -a --filter name="$CONTAINER_NAME" -q)
|
||||||
|
CONTAINER_RUNNING=$($DOCKER ps --filter name="$CONTAINER_NAME" -q)
|
||||||
|
if [ "$CONTAINER_RUNNING" != "" ]; then
|
||||||
|
echo "The build is already running in container $CONTAINER_NAME. Aborting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ "$CONTAINER_EXISTS" != "" ] && [ "$CONTINUE" != "1" ]; then
|
||||||
|
echo "Container $CONTAINER_NAME already exists and you did not specify CONTINUE=1. Aborting."
|
||||||
|
echo "You can delete the existing container like this:"
|
||||||
|
echo " docker rm $CONTAINER_NAME"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
$DOCKER build -t pi-gen .
|
||||||
|
if [ "$CONTAINER_EXISTS" != "" ]; then
|
||||||
|
trap "echo 'got CTRL+C... please wait 5s';docker stop -t 5 ${CONTAINER_NAME}_cont" SIGINT SIGTERM
|
||||||
|
time $DOCKER run --rm --privileged \
|
||||||
|
--volumes-from="${CONTAINER_NAME}" --name "${CONTAINER_NAME}_cont" \
|
||||||
|
pi-gen \
|
||||||
|
bash -e -o pipefail -c "dpkg-reconfigure qemu-user-static &&
|
||||||
|
cd /pi-gen; ./build.sh;
|
||||||
|
rsync -av work/*/build.log deploy/" &
|
||||||
|
wait
|
||||||
|
else
|
||||||
|
trap "echo 'got CTRL+C... please wait 5s'; docker stop -t 5 ${CONTAINER_NAME}" SIGINT SIGTERM
|
||||||
|
$DOCKER run --name "${CONTAINER_NAME}" --privileged \
|
||||||
|
-v $(pwd)/deploy:/pi-gen/deploy \
|
||||||
|
${config_mount} \
|
||||||
|
pi-gen \
|
||||||
|
bash -e -o pipefail -c "dpkg-reconfigure qemu-user-static &&
|
||||||
|
cd /pi-gen; ./build.sh &&
|
||||||
|
rsync -av work/*/build.log deploy/" &
|
||||||
|
wait
|
||||||
|
fi
|
||||||
|
echo "Done! Your image(s) should be in deploy/"
|
6
depends
6
depends
|
@ -1,8 +1,12 @@
|
||||||
quilt
|
quilt
|
||||||
|
parted
|
||||||
|
realpath
|
||||||
qemu-arm-static:qemu-user-static
|
qemu-arm-static:qemu-user-static
|
||||||
debootstrap
|
debootstrap
|
||||||
kpartx zerofree
|
zerofree
|
||||||
pxz zip
|
pxz zip
|
||||||
mkdosfs:dosfstools
|
mkdosfs:dosfstools
|
||||||
capsh:libcap2-bin
|
capsh:libcap2-bin
|
||||||
bsdtar
|
bsdtar
|
||||||
|
grep
|
||||||
|
rsync
|
|
@ -34,9 +34,21 @@ p
|
||||||
w
|
w
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
LOOP_DEV=`kpartx -asv ${IMG_FILE} | grep -E -o -m1 'loop[[:digit:]]+' | head -n 1`
|
PARTED_OUT=$(parted -s ${IMG_FILE} unit b print)
|
||||||
BOOT_DEV=/dev/mapper/${LOOP_DEV}p1
|
BOOT_OFFSET=$(echo "$PARTED_OUT" | grep -e '^ 1'| xargs echo -n \
|
||||||
ROOT_DEV=/dev/mapper/${LOOP_DEV}p2
|
| cut -d" " -f 2 | tr -d B)
|
||||||
|
BOOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^ 1'| xargs echo -n \
|
||||||
|
| cut -d" " -f 4 | tr -d B)
|
||||||
|
|
||||||
|
ROOT_OFFSET=$(echo "$PARTED_OUT" | grep -e '^ 2'| xargs echo -n \
|
||||||
|
| cut -d" " -f 2 | tr -d B)
|
||||||
|
ROOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^ 2'| xargs echo -n \
|
||||||
|
| cut -d" " -f 4 | tr -d B)
|
||||||
|
|
||||||
|
BOOT_DEV=$(losetup --show -f -o ${BOOT_OFFSET} --sizelimit ${BOOT_LENGTH} ${IMG_FILE})
|
||||||
|
ROOT_DEV=$(losetup --show -f -o ${ROOT_OFFSET} --sizelimit ${ROOT_LENGTH} ${IMG_FILE})
|
||||||
|
echo "/boot: offset $BOOT_OFFSET, length $BOOT_LENGTH"
|
||||||
|
echo "/: offset $ROOT_OFFSET, length $ROOT_LENGTH"
|
||||||
|
|
||||||
mkdosfs -n boot -S 512 -s 16 -v $BOOT_DEV > /dev/null
|
mkdosfs -n boot -S 512 -s 16 -v $BOOT_DEV > /dev/null
|
||||||
mkfs.ext4 -O ^huge_file $ROOT_DEV > /dev/null
|
mkfs.ext4 -O ^huge_file $ROOT_DEV > /dev/null
|
||||||
|
|
|
@ -9,9 +9,21 @@ cp ${WORK_DIR}/export-image/${IMG_DATE}-${IMG_NAME}${IMG_SUFFIX}.img ${STAGE_WOR
|
||||||
|
|
||||||
rm -rf ${STAGE_WORK_DIR}/${IMG_DATE}-${IMG_NAME}${IMG_SUFFIX}
|
rm -rf ${STAGE_WORK_DIR}/${IMG_DATE}-${IMG_NAME}${IMG_SUFFIX}
|
||||||
|
|
||||||
LOOP_DEV=`kpartx -asv ${IMG_FILE} | grep -E -o -m1 'loop[[:digit:]]+' | head -n 1`
|
PARTED_OUT=$(parted -s ${IMG_FILE} unit b print)
|
||||||
BOOT_DEV=/dev/mapper/${LOOP_DEV}p1
|
BOOT_OFFSET=$(echo "$PARTED_OUT" | grep -e '^ 1'| xargs echo -n \
|
||||||
ROOT_DEV=/dev/mapper/${LOOP_DEV}p2
|
| cut -d" " -f 2 | tr -d B)
|
||||||
|
BOOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^ 1'| xargs echo -n \
|
||||||
|
| cut -d" " -f 4 | tr -d B)
|
||||||
|
|
||||||
|
ROOT_OFFSET=$(echo "$PARTED_OUT" | grep -e '^ 2'| xargs echo -n \
|
||||||
|
| cut -d" " -f 2 | tr -d B)
|
||||||
|
ROOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^ 2'| xargs echo -n \
|
||||||
|
| cut -d" " -f 4 | tr -d B)
|
||||||
|
|
||||||
|
BOOT_DEV=$(losetup --show -f -o ${BOOT_OFFSET} --sizelimit ${BOOT_LENGTH} ${IMG_FILE})
|
||||||
|
ROOT_DEV=$(losetup --show -f -o ${ROOT_OFFSET} --sizelimit ${ROOT_LENGTH} ${IMG_FILE})
|
||||||
|
echo "/boot: offset $BOOT_OFFSET, length $BOOT_LENGTH"
|
||||||
|
echo "/: offset $ROOT_OFFSET, length $ROOT_LENGTH"
|
||||||
|
|
||||||
mkdir -p ${STAGE_WORK_DIR}/rootfs
|
mkdir -p ${STAGE_WORK_DIR}/rootfs
|
||||||
mkdir -p ${NOOBS_DIR}
|
mkdir -p ${NOOBS_DIR}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
log (){
|
log (){
|
||||||
date +"[%T] $@" | tee -a ${LOG_FILE}
|
date +"[%T] $@" | tee -a "${LOG_FILE}"
|
||||||
}
|
}
|
||||||
export -f log
|
export -f log
|
||||||
|
|
||||||
bootstrap(){
|
bootstrap(){
|
||||||
local ARCH=$(dpkg --print-architecture)
|
local ARCH
|
||||||
|
ARCH=$(dpkg --print-architecture)
|
||||||
|
|
||||||
export http_proxy=${APT_PROXY}
|
export http_proxy=${APT_PROXY}
|
||||||
|
|
||||||
|
@ -22,12 +23,12 @@ bootstrap(){
|
||||||
export -f bootstrap
|
export -f bootstrap
|
||||||
|
|
||||||
copy_previous(){
|
copy_previous(){
|
||||||
if [ ! -d ${PREV_ROOTFS_DIR} ]; then
|
if [ ! -d "${PREV_ROOTFS_DIR}" ]; then
|
||||||
echo "Previous stage rootfs not found"
|
echo "Previous stage rootfs not found"
|
||||||
false
|
false
|
||||||
fi
|
fi
|
||||||
mkdir -p ${ROOTFS_DIR}
|
mkdir -p "${ROOTFS_DIR}"
|
||||||
rsync -aHAXx ${PREV_ROOTFS_DIR}/ ${ROOTFS_DIR}/
|
rsync -aHAXx "${PREV_ROOTFS_DIR}/" "${ROOTFS_DIR}/"
|
||||||
}
|
}
|
||||||
export -f copy_previous
|
export -f copy_previous
|
||||||
|
|
||||||
|
@ -38,10 +39,11 @@ unmount(){
|
||||||
DIR=$1
|
DIR=$1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while mount | grep -q $DIR; do
|
while mount | grep -q "$DIR"; do
|
||||||
local LOCS=`mount | grep $DIR | cut -f 3 -d ' ' | sort -r`
|
local LOCS
|
||||||
|
LOCS=$(mount | grep "$DIR" | cut -f 3 -d ' ' | sort -r)
|
||||||
for loc in $LOCS; do
|
for loc in $LOCS; do
|
||||||
umount $loc
|
umount "$loc"
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
@ -50,42 +52,47 @@ export -f unmount
|
||||||
unmount_image(){
|
unmount_image(){
|
||||||
sync
|
sync
|
||||||
sleep 1
|
sleep 1
|
||||||
local LOOP_DEV=$(losetup -j ${1} | cut -f1 -d':')
|
local LOOP_DEVICES
|
||||||
if [ -n "${LOOP_DEV}" ]; then
|
LOOP_DEVICES=$(losetup -j "${1}" | cut -f1 -d':')
|
||||||
local MOUNTED_DIR=$(mount | grep $(basename ${LOOP_DEV}) | head -n 1 | cut -f 3 -d ' ')
|
for LOOP_DEV in ${LOOP_DEVICES}; do
|
||||||
if [ -n "${MOUNTED_DIR}" ]; then
|
if [ -n "${LOOP_DEV}" ]; then
|
||||||
unmount $(dirname ${MOUNTED_DIR})
|
local MOUNTED_DIR
|
||||||
|
MOUNTED_DIR=$(mount | grep "$(basename "${LOOP_DEV}")" | head -n 1 | cut -f 3 -d ' ')
|
||||||
|
if [ -n "${MOUNTED_DIR}" ] && [ "${MOUNTED_DIR}" != "/" ]; then
|
||||||
|
unmount "$(dirname "${MOUNTED_DIR}")"
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
losetup -d "${LOOP_DEV}"
|
||||||
fi
|
fi
|
||||||
sleep 1
|
done
|
||||||
kpartx -ds ${LOOP_DEV}
|
|
||||||
losetup -d ${LOOP_DEV}
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
export -f unmount_image
|
export -f unmount_image
|
||||||
|
|
||||||
on_chroot() {
|
on_chroot() {
|
||||||
if ! mount | grep -q `realpath ${ROOTFS_DIR}/proc`; then
|
if ! mount | grep -q "$(realpath "${ROOTFS_DIR}"/proc)"; then
|
||||||
mount -t proc proc ${ROOTFS_DIR}/proc
|
mount -t proc proc "${ROOTFS_DIR}/proc"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! mount | grep -q `realpath ${ROOTFS_DIR}/dev`; then
|
if ! mount | grep -q "$(realpath "${ROOTFS_DIR}"/dev)"; then
|
||||||
mount --bind /dev ${ROOTFS_DIR}/dev
|
mount --bind /dev "${ROOTFS_DIR}/dev"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! mount | grep -q `realpath ${ROOTFS_DIR}/dev/pts`; then
|
if ! mount | grep -q "$(realpath "${ROOTFS_DIR}"/dev/pts)"; then
|
||||||
mount --bind /dev/pts ${ROOTFS_DIR}/dev/pts
|
mount --bind /dev/pts "${ROOTFS_DIR}/dev/pts"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! mount | grep -q `realpath ${ROOTFS_DIR}/sys`; then
|
if ! mount | grep -q "$(realpath "${ROOTFS_DIR}"/sys)"; then
|
||||||
mount --bind /sys ${ROOTFS_DIR}/sys
|
mount --bind /sys "${ROOTFS_DIR}/sys"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
capsh --drop=cap_setfcap --chroot=${ROOTFS_DIR}/ -- "$@"
|
capsh --drop=cap_setfcap "--chroot=${ROOTFS_DIR}/" -- "$@"
|
||||||
}
|
}
|
||||||
export -f on_chroot
|
export -f on_chroot
|
||||||
|
|
||||||
update_issue() {
|
update_issue() {
|
||||||
local GIT_HASH=$(git rev-parse HEAD)
|
local GIT_HASH
|
||||||
echo -e "Raspberry Pi reference ${IMG_DATE}\nGenerated using pi-gen, https://github.com/RPi-Distro/pi-gen, ${GIT_HASH}, ${1}" > ${ROOTFS_DIR}/etc/rpi-issue
|
GIT_HASH=$(git rev-parse HEAD)
|
||||||
|
echo -e "Raspberry Pi reference ${IMG_DATE}\nGenerated using pi-gen, https://github.com/RPi-Distro/pi-gen, ${GIT_HASH}, ${1}" > "${ROOTFS_DIR}/etc/rpi-issue"
|
||||||
}
|
}
|
||||||
export -f update_issue
|
export -f update_issue
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
# Encoding to use on the console:
|
# Encoding to use on the console:
|
||||||
# Choices: ARMSCII-8, CP1251, CP1255, CP1256, GEORGIAN-ACADEMY, GEORGIAN-PS, IBM1133, ISIRI-3342, ISO-8859-1, ISO-8859-10, ISO-8859-11, ISO-8859-13, ISO-8859-14, ISO-8859-15, ISO-8859-16, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, KOI8-R, KOI8-U, TIS-620, UTF-8, VISCII
|
# Choices: ARMSCII-8, CP1251, CP1255, CP1256, GEORGIAN-ACADEMY, GEORGIAN-PS, IBM1133, ISIRI-3342, ISO-8859-1, ISO-8859-10, ISO-8859-11, ISO-8859-13, ISO-8859-14, ISO-8859-15, ISO-8859-16, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, KOI8-R, KOI8-U, TIS-620, UTF-8, VISCII
|
||||||
console-setup console-setup/charmap47 select UTF-8
|
console-setup console-setup/charmap47 select UTF-8
|
||||||
|
# Character set to support:
|
||||||
|
# Choices: . Arabic, # Armenian, # Cyrillic - KOI8-R and KOI8-U, # Cyrillic - non-Slavic languages, # Cyrillic - Slavic languages (also Bosnian and Serbian Latin), . Ethiopic, # Georgian, # Greek, # Hebrew, # Lao, # Latin1 and Latin5 - western Europe and Turkic languages, # Latin2 - central Europe and Romanian, # Latin3 and Latin8 - Chichewa; Esperanto; Irish; Maltese and Welsh, # Latin7 - Lithuanian; Latvian; Maori and Marshallese, . Latin - Vietnamese, # Thai, . Combined - Latin; Slavic Cyrillic; Hebrew; basic Arabic, . Combined - Latin; Slavic Cyrillic; Greek, . Combined - Latin; Slavic and non-Slavic Cyrillic, Guess optimal character set
|
||||||
|
console-setup console-setup/codeset47 select Guess optimal character set
|
||||||
|
# Font for the console:
|
||||||
|
# Choices: Fixed, Goha, GohaClassic, Terminus, TerminusBold, TerminusBoldVGA, VGA, Do not change the boot/kernel font, Let the
|
||||||
|
system select a suitable font
|
||||||
|
console-setup console-setup/fontface47 select Do not change the boot/kernel font
|
||||||
# Geographic area:
|
# Geographic area:
|
||||||
# Choices: Africa, America, Antarctica, Australia, Arctic Ocean, Asia, Atlantic Ocean, Europe, Indian Ocean, Pacific Ocean, System V timezones, US, None of the above
|
# Choices: Africa, America, Antarctica, Australia, Arctic Ocean, Asia, Atlantic Ocean, Europe, Indian Ocean, Pacific Ocean, System V timezones, US, None of the above
|
||||||
tzdata tzdata/Areas select Etc
|
tzdata tzdata/Areas select Etc
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
Index: jessie-stage2/rootfs/etc/default/console-setup
|
|
||||||
===================================================================
|
|
||||||
--- jessie-stage2.orig/rootfs/etc/default/console-setup
|
|
||||||
+++ jessie-stage2/rootfs/etc/default/console-setup
|
|
||||||
@@ -6,9 +6,9 @@ ACTIVE_CONSOLES="/dev/tty[1-6]"
|
|
||||||
|
|
||||||
CHARMAP="UTF-8"
|
|
||||||
|
|
||||||
-CODESET="Lat15"
|
|
||||||
-FONTFACE="Fixed"
|
|
||||||
-FONTSIZE="8x16"
|
|
||||||
+CODESET="guess"
|
|
||||||
+FONTFACE=""
|
|
||||||
+FONTSIZE=""
|
|
||||||
|
|
||||||
VIDEOMODE=
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
01-useradd.diff
|
01-useradd.diff
|
||||||
02-swap.diff
|
02-swap.diff
|
||||||
03-console-setup.diff
|
|
||||||
04-inputrc.diff
|
04-inputrc.diff
|
||||||
05-path.diff
|
05-path.diff
|
||||||
06-rc_local.diff
|
06-rc_local.diff
|
||||||
|
|
Loading…
Reference in New Issue
Block a user