full rewrite to add more risc-v
This commit is contained in:
parent
5923111e33
commit
9df4b2cda8
88
README
88
README
@ -1,88 +1,34 @@
|
|||||||
|
|
||||||
parabola-arm-imagebuilder
|
parabola-imagebuilder
|
||||||
=========================
|
=====================
|
||||||
|
|
||||||
|
This is a collection of scripts creating parabola images for use with qemu.
|
||||||
|
|
||||||
image creation
|
image creation
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
this is a collection of scripts creating parabola arm images for use with qemu
|
To create a new virtual machine image, run
|
||||||
with the original goal of building parabola arm packages on these machines.
|
|
||||||
Development focus has since shifted towards creating parabola-arm release
|
|
||||||
tarballs.
|
|
||||||
|
|
||||||
to create a new virtual machine image, run
|
|
||||||
$> sudo ./create.sh
|
$> sudo ./create.sh
|
||||||
|
|
||||||
by default, the creation script will use a ParabolaArm release tarball to
|
The creation is influenced by the following environment variables:
|
||||||
create the virtual machine. Alternatively, to install an archlinuxarm tarball
|
|
||||||
and migrating the installed system to parabola in-place, set the environment
|
|
||||||
variable ARCHBOOTSTRAP to 1:
|
|
||||||
|
|
||||||
$> sudo ARCHBOOTSTRAP=1 ./create.sh
|
ARCH - the target architecture of the image. default: armv7h
|
||||||
|
|
||||||
Optionally, to create a new virtual machine with a packaging environment, set
|
SIZE - the size of the root image. default: 64GiB
|
||||||
the environment variable DEVSETUP to 1:
|
|
||||||
|
|
||||||
$> sudo DEVSETUP=1 ./create.sh
|
MIRROR - the mirror used to pacstrap the image, anything valid in a `Server =`
|
||||||
|
line can go here.
|
||||||
|
default: https://redirector.parabola.nu/\$repo/os/\$arch}
|
||||||
|
|
||||||
The packaging environment setup script makes use of several files and packages
|
The created images are stored in the build/ directory.
|
||||||
present on already setup parabola development machines. if your setup is
|
|
||||||
different, you might have to modify src/stage3.sh accordingly.
|
|
||||||
|
|
||||||
Places the scripts check the host machine for configuration files are:
|
|
||||||
/etc/makepkg.conf - for PACKAGER and GPGKEY
|
|
||||||
~/.gnupg ~/.ssh ~/.gitconfig - copied verbatim to the VM
|
|
||||||
|
|
||||||
The scripts assume that the following programs are available and in $PATH:
|
|
||||||
qemu-img, qemu-system-arm
|
|
||||||
wget
|
|
||||||
parted
|
|
||||||
mkfs.vfat, mkfs.ext4, mkswap
|
|
||||||
bsdtar
|
|
||||||
scp, ssh, ssh-keygen
|
|
||||||
pacman
|
|
||||||
|
|
||||||
The scripts also assume that you like vim :)
|
|
||||||
|
|
||||||
virtual machine start
|
virtual machine start
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
to open a shell into the created machine, run
|
To boot a created virtual machine, run
|
||||||
$> ./start.sh [path to created image]
|
$> sudo ./boot.sh [path to created image]
|
||||||
|
|
||||||
the start.sh script assumes that you want a throwaway session, so it will start
|
The start.sh script assumes that you want a throwaway session, so it will start
|
||||||
the virtual machine in snapshot mode and drop you into an ssh session. Once you
|
the virtual machine in snapshot mode, and changes during the session will be
|
||||||
exit that session, the machine is shutdown and changes made to the image are
|
discarded.
|
||||||
discarded. This behavior can be changed using the following environment
|
|
||||||
variables:
|
|
||||||
|
|
||||||
FOREGROUND : set this to 1 to start a qemu serial connection instead of a ssh
|
|
||||||
session. Useful to capture boot output.
|
|
||||||
|
|
||||||
PERSISTENT : set this to 1 to make persistent changes to the image that are
|
|
||||||
not discarded on shutdown.
|
|
||||||
|
|
||||||
The username and password for the created image is parabola:parabola, or
|
|
||||||
root:parabola respectively. If a packaging environment is setup, the system is
|
|
||||||
configured for passwordless sudo for the parabola user and the package tree and
|
|
||||||
a build chroot are prepared. have fun. also check out the .bashrc of the
|
|
||||||
parabola user in the created virtual machine, for batch build integration based
|
|
||||||
on task-spooler.
|
|
||||||
|
|
||||||
tarball creation
|
|
||||||
----------------
|
|
||||||
|
|
||||||
to create a tarball from the created vm image, run
|
|
||||||
|
|
||||||
$> sudo ./make_tarball.sh [path to created image]
|
|
||||||
|
|
||||||
the tarball creation script assumes to operate on an image *without* packaging
|
|
||||||
environment setup and will not perform additional cleanup operations if used on
|
|
||||||
the wrong image. Things that are cleaned up are:
|
|
||||||
|
|
||||||
/root/.ssh
|
|
||||||
/etc/ssh/ssh_host_*
|
|
||||||
/etc/pacman.d/gnupg
|
|
||||||
/var/log/*
|
|
||||||
/var/cache/*
|
|
||||||
/lost+found
|
|
||||||
|
134
boot.sh
Executable file
134
boot.sh
Executable file
@ -0,0 +1,134 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
##############################################################################
|
||||||
|
# parabola-imagebuilder #
|
||||||
|
# #
|
||||||
|
# Copyright (C) 2017 Andreas Grapentin #
|
||||||
|
# #
|
||||||
|
# This program is free software: you can redistribute it and/or modify #
|
||||||
|
# it under the terms of the GNU General Public License as published by #
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or #
|
||||||
|
# (at your option) any later version. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, #
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||||
|
# GNU General Public License for more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License #
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||||
|
##############################################################################
|
||||||
|
# this is a convenience script to start a created VM
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# common directories
|
||||||
|
startdir="$(pwd)"
|
||||||
|
export TOPBUILDDIR="$startdir"/build
|
||||||
|
export TOPSRCDIR="$startdir"/src
|
||||||
|
mkdir -p "$TOPBUILDDIR"
|
||||||
|
chown "$SUDO_USER" "$TOPBUILDDIR"
|
||||||
|
|
||||||
|
# shellcheck source=src/shared/common.sh
|
||||||
|
. "$TOPSRCDIR"/shared/common.sh
|
||||||
|
|
||||||
|
# sanity checks
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
die -e "$ERROR_INVOCATION" "must be root"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# shellcheck source=src/qemu.sh
|
||||||
|
. "$TOPSRCDIR"/qemu.sh
|
||||||
|
|
||||||
|
check_kernel_arch() {
|
||||||
|
echo -n "checking for kernel name ..."
|
||||||
|
local kernel
|
||||||
|
kernel=$(find "$1" -maxdepth 1 -type f -iname '*vmlinu*' | head -n1)
|
||||||
|
[ -n "$kernel" ] || kernel=no
|
||||||
|
echo "$(basename "$kernel")"
|
||||||
|
|
||||||
|
[ "x$kernel" != "xno" ] || return
|
||||||
|
|
||||||
|
# check if the kernel has an elf header and extract arch
|
||||||
|
|
||||||
|
echo -n "checking for kernel elf header ... "
|
||||||
|
set -o pipefail
|
||||||
|
machine=$(readelf -h "$kernel" 2>/dev/null | grep Machine | awk '{print $2}') || machine=no
|
||||||
|
set +o pipefail
|
||||||
|
echo "$machine"
|
||||||
|
|
||||||
|
[ "x$machine" != "xno" ] && return
|
||||||
|
|
||||||
|
# no elf header? maybe arm?
|
||||||
|
|
||||||
|
echo -n "checking for ARM boot executable ... "
|
||||||
|
local is_arm=no
|
||||||
|
file "$kernel" | grep -q 'ARM boot executable' && is_arm=yes
|
||||||
|
echo "$is_arm"
|
||||||
|
[ "x$is_arm" == "xyes" ] && machine=ARM
|
||||||
|
|
||||||
|
[ "x$machine" != "xno" ] && return
|
||||||
|
|
||||||
|
# no idea, just bail.
|
||||||
|
|
||||||
|
error "unable to extract kernel arch from image"
|
||||||
|
return "$ERROR_MISSING"
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_setargs_arm() {
|
||||||
|
qemu_args=(
|
||||||
|
-snapshot
|
||||||
|
-nographic
|
||||||
|
-machine vexpress-a9
|
||||||
|
-cpu cortex-a9
|
||||||
|
-m 1G
|
||||||
|
-kernel "$1"/vmlinuz-linux-libre
|
||||||
|
-dtb "$1"/dtbs/linux-libre/vexpress-v2p-ca9.dtb
|
||||||
|
-initrd "$1"/initramfs-linux-libre.img
|
||||||
|
--append "console=ttyAMA0 rw root=/dev/mmcblk0p3"
|
||||||
|
-drive if=sd,driver=raw,cache=writeback,file="$2"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_setargs_riscv64() {
|
||||||
|
qemu_args=(
|
||||||
|
-snapshot
|
||||||
|
-nographic
|
||||||
|
-machine virt
|
||||||
|
-m 2G
|
||||||
|
-kernel bbl
|
||||||
|
-append "console=ttyS0 rw root=/dev/vda"
|
||||||
|
-drive file="${3}p3",format=raw,id=hd0
|
||||||
|
-device virtio-blk-device,drive=hd0
|
||||||
|
-object rng-random,filename=/dev/urandom,id=rng0
|
||||||
|
-device virtio-rng-device,rng=rng0
|
||||||
|
-device virtio-net-device,netdev=usernet
|
||||||
|
-netdev user,id=usernet
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
boot_from_image() {
|
||||||
|
[ -f "$1" ] || die "$1: image does not exist"
|
||||||
|
|
||||||
|
local loopdev
|
||||||
|
qemu_img_losetup "$1" || return
|
||||||
|
|
||||||
|
# mount the boot partition
|
||||||
|
mkdir -p "$TOPBUILDDIR"/mnt
|
||||||
|
mount "${loopdev}p1" "$TOPBUILDDIR"/mnt || return
|
||||||
|
trap_add "umount -R $TOPBUILDDIR/mnt" INT TERM EXIT
|
||||||
|
|
||||||
|
local machine
|
||||||
|
check_kernel_arch "$TOPBUILDDIR"/mnt || return
|
||||||
|
|
||||||
|
case "$machine" in
|
||||||
|
RISC-V) arch=riscv64 ;;
|
||||||
|
ARM) arch=arm ;;
|
||||||
|
*) error "unrecognized machine '$machine'"
|
||||||
|
return "$ERROR_UNSPECIFIED" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
qemu_args=()
|
||||||
|
"qemu_setargs_$arch" "$TOPBUILDDIR"/mnt "$1" "$loopdev"
|
||||||
|
QEMU_AUDIO_DRV=none "qemu-system-$arch" "${qemu_args[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
boot_from_image "$1" || die "boot failed"
|
60
create.sh
60
create.sh
@ -1,8 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# parabola-arm-imagebuilder #
|
# parabola-imagebuilder #
|
||||||
# #
|
# #
|
||||||
# Copyright (C) 2017 Andreas Grapentin #
|
# Copyright (C) 2017, 2018 Andreas Grapentin #
|
||||||
# #
|
# #
|
||||||
# This program is free software: you can redistribute it and/or modify #
|
# This program is free software: you can redistribute it and/or modify #
|
||||||
# it under the terms of the GNU General Public License as published by #
|
# it under the terms of the GNU General Public License as published by #
|
||||||
@ -18,48 +18,30 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
set -eu
|
# target options
|
||||||
|
export ARCH="${ARCH:-armv7h}"
|
||||||
die() { echo "$*" 1>&2 ; exit 1; }
|
|
||||||
|
|
||||||
# this script prepares an armv7h parabola image for use with start.sh
|
|
||||||
|
|
||||||
[ $(id -u) -ne 0 ] && die "must be root"
|
|
||||||
[ -z "${SUDO_USER:-}" ] && die "SUDO_USER not set"
|
|
||||||
|
|
||||||
export OUTFILE="${OUTFILE:-armv7h.img}"
|
|
||||||
export SIZE="${SIZE:-64G}"
|
export SIZE="${SIZE:-64G}"
|
||||||
export ARCHTARBALL="${ARCHTARBALL:-ArchLinuxARM-armv7-latest.tar.gz}"
|
export MIRROR="${MIRROR:-https://redirector.parabola.nu/\$repo/os/\$arch}"
|
||||||
export PARABOLATARBALL="${PARABOLATARBALL:-ParabolaARM-armv7-LATEST.tar.gz}"
|
|
||||||
|
|
||||||
export _builddir=build
|
# common directories
|
||||||
mkdir -p "$_builddir"
|
startdir="$(pwd)"
|
||||||
chown $SUDO_USER "$_builddir"
|
export TOPBUILDDIR="$startdir"/build
|
||||||
|
export TOPSRCDIR="$startdir"/src
|
||||||
|
mkdir -p "$TOPBUILDDIR"
|
||||||
|
chown "$SUDO_USER" "$TOPBUILDDIR"
|
||||||
|
|
||||||
export _outfile="$_builddir/$(basename "$OUTFILE")"
|
# shellcheck source=src/shared/common.sh
|
||||||
|
. "$TOPSRCDIR"/shared/common.sh
|
||||||
|
|
||||||
# prepare the empty image
|
# sanity checks
|
||||||
./src/stage0.sh
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
die -e "$ERROR_INVOCATION" "must be root"
|
||||||
if [ -n "${ARCHBOOTSTRAP:-}" ]; then
|
|
||||||
# install a clean archlinux-arm system in the empty image
|
|
||||||
wget -nc http://os.archlinuxarm.org/os/$ARCHTARBALL
|
|
||||||
TARBALL="$ARCHTARBALL" ./src/stage1.sh
|
|
||||||
|
|
||||||
# migrate the installed image to a clean parabola
|
|
||||||
./src/stage2.sh
|
|
||||||
else
|
|
||||||
# install a clean parabola-arm system in the empty image
|
|
||||||
wget -nc https://repo.parabola.nu/iso/arm/LATEST/$PARABOLATARBALL
|
|
||||||
TARBALL="$PARABOLATARBALL" ./src/stage1.sh
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# setup package development environment
|
# shellcheck source=src/qemu.sh
|
||||||
[ -n "${DEVSETUP:-}" ] && ./src/stage3.sh
|
. "$TOPSRCDIR"/qemu.sh
|
||||||
|
|
||||||
# cleanup
|
qemu_make_image "$TOPBUILDDIR/parabola-$ARCH.img" "$SIZE" \
|
||||||
chown $SUDO_USER $_outfile
|
|| die "failed to prepare qemu base image"
|
||||||
mv -v "$_outfile" "$OUTFILE"
|
|
||||||
rm -rf "$_builddir"
|
|
||||||
|
|
||||||
echo "all done :)"
|
msg "all done."
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
##############################################################################
|
|
||||||
# parabola-arm-imagebuilder #
|
|
||||||
# #
|
|
||||||
# Copyright (C) 2017 Andreas Grapentin #
|
|
||||||
# #
|
|
||||||
# This program is free software: you can redistribute it and/or modify #
|
|
||||||
# it under the terms of the GNU General Public License as published by #
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or #
|
|
||||||
# (at your option) any later version. #
|
|
||||||
# #
|
|
||||||
# This program is distributed in the hope that it will be useful, #
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
||||||
# GNU General Public License for more details. #
|
|
||||||
# #
|
|
||||||
# You should have received a copy of the GNU General Public License #
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
die() { echo "$*" 1>&2 ; exit 1; }
|
|
||||||
|
|
||||||
[ $(id -u) -ne 0 ] && die "must be root"
|
|
||||||
|
|
||||||
_builddir=build
|
|
||||||
mkdir -p "$_builddir"
|
|
||||||
|
|
||||||
_imagefile="$_builddir/$(basename "$1")"
|
|
||||||
cp $1 $_imagefile
|
|
||||||
_rootdir="$_builddir"/root-$$
|
|
||||||
|
|
||||||
_loopdev=$(sudo losetup -f --show "$_imagefile")
|
|
||||||
sudo partprobe $_loopdev
|
|
||||||
|
|
||||||
# register a cleanup error handler
|
|
||||||
function cleanup {
|
|
||||||
sudo umount ${_loopdev}p1
|
|
||||||
sudo umount ${_loopdev}p3
|
|
||||||
sudo losetup -d $_loopdev
|
|
||||||
rm -rf "$_rootdir" "$_imagefile"
|
|
||||||
}
|
|
||||||
trap cleanup ERR
|
|
||||||
|
|
||||||
# mount the image
|
|
||||||
mkdir -p "$_rootdir"
|
|
||||||
sudo mount ${_loopdev}p3 "$_rootdir"
|
|
||||||
sudo mount ${_loopdev}p1 "$_rootdir"/boot
|
|
||||||
|
|
||||||
# clean the image
|
|
||||||
rm -fvr \
|
|
||||||
"$_rootdir"/root/.ssh \
|
|
||||||
"$_rootdir"/etc/ssh/ssh_host_* \
|
|
||||||
"$_rootdir"/var/log/* \
|
|
||||||
"$_rootdir"/var/cache/* \
|
|
||||||
"$_rootdir"/lost+found
|
|
||||||
|
|
||||||
# create the tarball
|
|
||||||
tar -czf ParabolaARM-armv7-$(date "+%Y-%m-%d").tar.gz -C "$_rootdir" .
|
|
||||||
|
|
||||||
# cleanup
|
|
||||||
sudo umount ${_loopdev}p1
|
|
||||||
sudo umount ${_loopdev}p3
|
|
||||||
sudo losetup -d $_loopdev
|
|
||||||
rm -rf "$_rootdir" "$_imagefile"
|
|
@ -1,52 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
##############################################################################
|
|
||||||
# parabola-arm-imagebuilder #
|
|
||||||
# #
|
|
||||||
# Copyright (C) 2017 Andreas Grapentin #
|
|
||||||
# #
|
|
||||||
# This program is free software: you can redistribute it and/or modify #
|
|
||||||
# it under the terms of the GNU General Public License as published by #
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or #
|
|
||||||
# (at your option) any later version. #
|
|
||||||
# #
|
|
||||||
# This program is distributed in the hope that it will be useful, #
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
||||||
# GNU General Public License for more details. #
|
|
||||||
# #
|
|
||||||
# You should have received a copy of the GNU General Public License #
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
set -x
|
|
||||||
|
|
||||||
die() { echo "$*" 1>&2 ; exit 1; }
|
|
||||||
|
|
||||||
_tarball=$1
|
|
||||||
|
|
||||||
# parse date from tarball
|
|
||||||
_date=$(echo "${_tarball%.tar.gz}" | rev | cut -d'-' -f1-3 | rev)
|
|
||||||
|
|
||||||
# create checksums
|
|
||||||
sha512sum $_tarball > SHA512SUMS
|
|
||||||
whirlpool-hash $_tarball > WHIRLPOOLSUMS
|
|
||||||
|
|
||||||
# sign tarball and checksum
|
|
||||||
gpg --detach-sign $_tarball
|
|
||||||
gpg --detach-sign SHA512SUMS
|
|
||||||
gpg --detach-sign WHIRLPOOLSUMS
|
|
||||||
|
|
||||||
# upload tarball and checksum
|
|
||||||
_repopath="/srv/repo/main/iso/arm/$_date"
|
|
||||||
ssh repo@repo "mkdir -p $_repopath"
|
|
||||||
scp $_tarball{,.sig} SHA512SUMS{,.sig} WHIRLPOOLSUMS{,.sig} repo@repo:$_repopath/
|
|
||||||
|
|
||||||
# update LATEST symlinks
|
|
||||||
ssh repo@repo "mkdir -p $_repopath/../LATEST"
|
|
||||||
for f in $_tarball{,.sig} SHA512SUMS{,.sig} WHIRLPOOLSUMS{,.sig}; do
|
|
||||||
ssh repo@repo "ln -fs ../$_date/$f $_repopath/../LATEST/$(echo $f | sed "s/$_date/LATEST/g")"
|
|
||||||
done
|
|
||||||
|
|
||||||
# cleanup
|
|
||||||
rm -rf $_tarball.sig SHA512SUMS{,.sig} WHIRLPOOLSUMS{,.sig}
|
|
150
src/qemu.sh
Normal file
150
src/qemu.sh
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
##############################################################################
|
||||||
|
# parabola-arm-imagebuilder #
|
||||||
|
# #
|
||||||
|
# Copyright (C) 2018 Andreas Grapentin #
|
||||||
|
# #
|
||||||
|
# This program is free software: you can redistribute it and/or modify #
|
||||||
|
# it under the terms of the GNU General Public License as published by #
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or #
|
||||||
|
# (at your option) any later version. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, #
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||||
|
# GNU General Public License for more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License #
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
qemu_img_partition_and_mount_for_armv7h() {
|
||||||
|
parted -s "$1" \
|
||||||
|
mklabel gpt \
|
||||||
|
mkpart ESP fat32 1MiB 513MiB \
|
||||||
|
set 1 boot on \
|
||||||
|
mkpart primary linux-swap 513MiB 4609MiB \
|
||||||
|
mkpart primary ext4 4609MiB 100% || return
|
||||||
|
|
||||||
|
check_exe -r mkfs.vfat mkfs.ext4
|
||||||
|
|
||||||
|
mkfs.vfat -F 32 "${1}p1"
|
||||||
|
mkswap "${1}p2"
|
||||||
|
mkfs.ext4 "${1}p3"
|
||||||
|
|
||||||
|
mkdir -p "$2"
|
||||||
|
mount "${1}p3" "$2" || return
|
||||||
|
trap_add "umount -R $2" INT TERM EXIT
|
||||||
|
mkdir -p "$2"/boot
|
||||||
|
mount "${1}p1" "$2"/boot || return
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_img_partition_and_mount_for_riscv64() {
|
||||||
|
parted -s "$1" \
|
||||||
|
mklabel gpt \
|
||||||
|
mkpart primary ext2 1MiB 513MiB \
|
||||||
|
set 1 boot on \
|
||||||
|
mkpart primary linux-swap 513MiB 4609MiB \
|
||||||
|
mkpart primary ext4 4609MiB 100% || return
|
||||||
|
|
||||||
|
check_exe mkfs.ext2 mkfs.ext4
|
||||||
|
|
||||||
|
mkfs.ext2 "${1}p1"
|
||||||
|
mkswap "${1}p2"
|
||||||
|
mkfs.ext4 "${1}p3"
|
||||||
|
|
||||||
|
mkdir -p "$2"
|
||||||
|
mount "${1}p3" "$2" || return
|
||||||
|
trap_add "umount -R $2" INT TERM EXIT
|
||||||
|
mkdir -p "$2"/boot
|
||||||
|
mount "${1}p1" "$2"/boot || return
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_img_losetup() {
|
||||||
|
echo -n "checking for free loop device ... "
|
||||||
|
loopdev=$(losetup -f --show "$1") || loopdev=no
|
||||||
|
echo "$loopdev"
|
||||||
|
|
||||||
|
[ "x$loopdev" == "xno" ] && return "$ERROR_MISSING"
|
||||||
|
|
||||||
|
trap_add "qemu_img_lorelease $loopdev" INT TERM EXIT
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_img_lorelease() {
|
||||||
|
losetup -d "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_setup_user_static() {
|
||||||
|
# borrowed from /usr/bin/librechroot
|
||||||
|
local setarch interpreter
|
||||||
|
case "$ARCH" in
|
||||||
|
armv7h) setarch=armv7l; interpreter=/usr/bin/qemu-arm- ;;
|
||||||
|
*) setarch="$ARCH"; interpreter=/usr/bin/qemu-"$ARCH"- ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if ! setarch "$setarch" /bin/true 2>/dev/null; then
|
||||||
|
# target arch can't execute natively, pacstrap is going to need help by qemu
|
||||||
|
# Make sure that qemu-static is set up with binfmt_misc
|
||||||
|
if [[ -z $(grep -l -F \
|
||||||
|
-e "interpreter $interpreter" \
|
||||||
|
-r -- /proc/sys/fs/binfmt_misc 2>/dev/null \
|
||||||
|
| xargs -r grep -xF 'enabled') ]]
|
||||||
|
then
|
||||||
|
error "unable to continue - need qemu-user-static for $ARCH"
|
||||||
|
return "$ERROR_MISSING"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$1"/usr/bin
|
||||||
|
cp -v "$interpreter"* "$1"/usr/bin || return
|
||||||
|
trap_add "qemu_cleanup_user_static $1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_cleanup_user_static() {
|
||||||
|
rm -f "$1"/usr/bin/qemu-*
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_make_image() {
|
||||||
|
msg "preparing parabola qemu image for $ARCH"
|
||||||
|
|
||||||
|
# skip, if already exists
|
||||||
|
check_file "$1" && return
|
||||||
|
|
||||||
|
check_exe -r parted
|
||||||
|
|
||||||
|
# write to preliminary file
|
||||||
|
local tmpfile="$1.part"
|
||||||
|
rm -f "$tmpfile"
|
||||||
|
|
||||||
|
# create an empty image
|
||||||
|
qemu-img create -f raw "$tmpfile" "$2" || return
|
||||||
|
|
||||||
|
# create a minimal pacman.conf
|
||||||
|
cat > "$TOPBUILDDIR/pacman.conf.$ARCH" << EOF
|
||||||
|
[options]
|
||||||
|
Architecture = $ARCH
|
||||||
|
[libre]
|
||||||
|
Server = $MIRROR
|
||||||
|
[core]
|
||||||
|
Server = $MIRROR
|
||||||
|
[extra]
|
||||||
|
Server = $MIRROR
|
||||||
|
[community]
|
||||||
|
Server = $MIRROR
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# setup the image (in a subshell for trap management)
|
||||||
|
(
|
||||||
|
loopdev=''
|
||||||
|
qemu_img_losetup "$tmpfile" || return
|
||||||
|
|
||||||
|
dd if=/dev/zero of="$loopdev" bs=1M count=8 || return
|
||||||
|
"qemu_img_partition_and_mount_for_$ARCH" "$loopdev" "$TOPBUILDDIR"/mnt || return
|
||||||
|
|
||||||
|
qemu_setup_user_static "$TOPBUILDDIR"/mnt || return
|
||||||
|
|
||||||
|
pacstrap -GMcd -C "$TOPBUILDDIR/pacman.conf.$ARCH" "$TOPBUILDDIR"/mnt || return
|
||||||
|
) || return
|
||||||
|
|
||||||
|
mv "$tmpfile" "$1"
|
||||||
|
}
|
100
src/shared/checks.sh
Normal file
100
src/shared/checks.sh
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
##############################################################################
|
||||||
|
# parabola-imagebuilder #
|
||||||
|
# #
|
||||||
|
# Copyright (C) 2018 Andreas Grapentin #
|
||||||
|
# #
|
||||||
|
# This program is free software: you can redistribute it and/or modify #
|
||||||
|
# it under the terms of the GNU General Public License as published by #
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or #
|
||||||
|
# (at your option) any later version. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, #
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||||
|
# GNU General Public License for more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License #
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
check_exe() {
|
||||||
|
local OPTIND o r=
|
||||||
|
while getopts "r" o; do
|
||||||
|
case "$o" in
|
||||||
|
r) r=yes ;;
|
||||||
|
*) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-r] program ..." ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
|
local v res=0
|
||||||
|
for v in "$@"; do
|
||||||
|
echo -n "checking for $v in \$PATH ... "
|
||||||
|
|
||||||
|
local have_exe=yes
|
||||||
|
type -p "$v" >/dev/null || have_exe=no
|
||||||
|
echo $have_exe
|
||||||
|
|
||||||
|
if [ "x$have_exe" != "xyes" ]; then
|
||||||
|
[ "x$r" == "xyes" ] && die -e "$ERROR_MISSING" "missing $v in \$PATH"
|
||||||
|
res="$ERROR_MISSING"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return "$res"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_file() {
|
||||||
|
local OPTIND o r=
|
||||||
|
while getopts "r" o; do
|
||||||
|
case "$o" in
|
||||||
|
r) r=yes ;;
|
||||||
|
*) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-r] file ..." ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
|
local v res=0
|
||||||
|
for v in "$@"; do
|
||||||
|
echo -n "checking for $v ... "
|
||||||
|
|
||||||
|
local have_file=yes
|
||||||
|
[ -f "$v" ] || have_file=no
|
||||||
|
echo $have_file
|
||||||
|
|
||||||
|
if [ "x$have_file" != "xyes" ]; then
|
||||||
|
[ "x$r" == "xyes" ] && die -e "$ERROR_MISSING" "missing $v in filesystem"
|
||||||
|
res="$ERROR_MISSING"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return "$res"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_gpgkey() {
|
||||||
|
local OPTIND o r=
|
||||||
|
while getopts "r" o; do
|
||||||
|
case "$o" in
|
||||||
|
r) r=yes ;;
|
||||||
|
*) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-r] key" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
|
local v res=0
|
||||||
|
for v in "$@"; do
|
||||||
|
echo -n "checking for key $v ... "
|
||||||
|
|
||||||
|
local have_key=yes
|
||||||
|
sudo -u "$SUDO_USER" gpg --list-keys "$v" &>/dev/null || have_key=no
|
||||||
|
echo $have_key
|
||||||
|
|
||||||
|
if [ "x$have_key" != "xyes" ]; then
|
||||||
|
[ "x$r" == "xyes" ] && die -e "$ERROR_MISSING" "missing $v in keyring"
|
||||||
|
res="$ERROR_MISSING"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return "$res"
|
||||||
|
}
|
68
src/shared/common.sh
Normal file
68
src/shared/common.sh
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
##############################################################################
|
||||||
|
# parabola-imagebuilder #
|
||||||
|
# #
|
||||||
|
# Copyright (C) 2018 Andreas Grapentin #
|
||||||
|
# #
|
||||||
|
# This program is free software: you can redistribute it and/or modify #
|
||||||
|
# it under the terms of the GNU General Public License as published by #
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or #
|
||||||
|
# (at your option) any later version. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, #
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||||
|
# GNU General Public License for more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License #
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# shellcheck source=src/shared/feedback.sh
|
||||||
|
. "$TOPSRCDIR"/shared/feedback.sh
|
||||||
|
# shellcheck source=src/shared/checks.sh
|
||||||
|
. "$TOPSRCDIR"/shared/checks.sh
|
||||||
|
|
||||||
|
retry() {
|
||||||
|
local OPTIND o n=5 s=60
|
||||||
|
while getopts "n:s:" o; do
|
||||||
|
case "$o" in
|
||||||
|
n) n="$OPTARG" ;;
|
||||||
|
s) s="$OPTARG" ;;
|
||||||
|
*) die -e $ERROR_INVOCATION "Usage: ${FUNCNAME[0]} [-n tries] [-s delay] cmd ..." ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
|
for _ in $(seq "$((n - 1))"); do
|
||||||
|
"$@" && return 0
|
||||||
|
sleep "$s"
|
||||||
|
done
|
||||||
|
"$@" || return
|
||||||
|
}
|
||||||
|
|
||||||
|
# appends a command to a trap
|
||||||
|
# source: https://stackoverflow.com/questions/3338030/multiple-bash-traps-for-the-same-signal
|
||||||
|
#
|
||||||
|
# - 1st arg: code to add
|
||||||
|
# - remaining args: names of traps to modify
|
||||||
|
#
|
||||||
|
trap_add() {
|
||||||
|
trap_add_cmd=$1; shift || fatal "${FUNCNAME[0]} usage error"
|
||||||
|
for trap_add_name in "$@"; do
|
||||||
|
trap -- "$(
|
||||||
|
# helper fn to get existing trap command from output
|
||||||
|
# of trap -p
|
||||||
|
extract_trap_cmd() { printf '%s\n' "$3"; }
|
||||||
|
# print the new trap command
|
||||||
|
printf '%s\n' "${trap_add_cmd}"
|
||||||
|
# print existing trap command with newline
|
||||||
|
eval "extract_trap_cmd $(trap -p "${trap_add_name}")"
|
||||||
|
)" "${trap_add_name}" \
|
||||||
|
|| fatal "unable to add to trap ${trap_add_name}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
# set the trace attribute for the above function. this is
|
||||||
|
# required to modify DEBUG or RETURN traps because functions don't
|
||||||
|
# inherit them unless the trace attribute is set
|
||||||
|
declare -f -t trap_add
|
38
src/stage0.sh → src/shared/feedback.sh
Executable file → Normal file
38
src/stage0.sh → src/shared/feedback.sh
Executable file → Normal file
@ -1,8 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# parabola-arm-imagebuilder #
|
# parabola-imagebuilder #
|
||||||
# #
|
# #
|
||||||
# Copyright (C) 2017 Andreas Grapentin #
|
# Copyright (C) 2018 Andreas Grapentin #
|
||||||
# #
|
# #
|
||||||
# This program is free software: you can redistribute it and/or modify #
|
# This program is free software: you can redistribute it and/or modify #
|
||||||
# it under the terms of the GNU General Public License as published by #
|
# it under the terms of the GNU General Public License as published by #
|
||||||
@ -18,8 +18,34 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
set -eu
|
# error codes
|
||||||
|
export ERROR_UNSPECIFIED=1
|
||||||
|
export ERROR_INVOCATION=2
|
||||||
|
export ERROR_MISSING=3
|
||||||
|
export ERROR_BUILDFAIL=4
|
||||||
|
export ERROR_KEYFAIL=5
|
||||||
|
|
||||||
# create an empty qemu image
|
# messaging functions
|
||||||
rm -f $_outfile
|
msg() {
|
||||||
qemu-img create -f raw $_outfile $SIZE
|
echo "$(tput bold)$(tput setf 2)==>$(tput setf 7) $*$(tput sgr0)";
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo "$(tput bold)$(tput setf 4)==> ERROR:$(tput setf 7) $*$(tput sgr0)" 1>&2
|
||||||
|
}
|
||||||
|
|
||||||
|
die() {
|
||||||
|
local OPTIND o e="$ERROR_UNSPECIFIED"
|
||||||
|
while getopts "e:" o; do
|
||||||
|
case "$o" in
|
||||||
|
e) e="$OPTARG" ;;
|
||||||
|
*) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-e status] msg ..." ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
|
error "$@"
|
||||||
|
trap - ERR
|
||||||
|
exit "$e"
|
||||||
|
}
|
||||||
|
trap 'die "unknown error"' ERR
|
@ -1,93 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
##############################################################################
|
|
||||||
# parabola-arm-imagebuilder #
|
|
||||||
# #
|
|
||||||
# Copyright (C) 2017 Andreas Grapentin #
|
|
||||||
# #
|
|
||||||
# This program is free software: you can redistribute it and/or modify #
|
|
||||||
# it under the terms of the GNU General Public License as published by #
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or #
|
|
||||||
# (at your option) any later version. #
|
|
||||||
# #
|
|
||||||
# This program is distributed in the hope that it will be useful, #
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
||||||
# GNU General Public License for more details. #
|
|
||||||
# #
|
|
||||||
# You should have received a copy of the GNU General Public License #
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
_bootdir="$_builddir/boot"
|
|
||||||
_rootdir="$_builddir/root"
|
|
||||||
|
|
||||||
_loopdev=$(losetup -f --show "$_outfile")
|
|
||||||
|
|
||||||
# setup an error exit handler for cleanup
|
|
||||||
function cleanup {
|
|
||||||
echo "exiting due to earlier errors..." >&2
|
|
||||||
for part in p1 p3; do
|
|
||||||
umount $_loopdev$part || true
|
|
||||||
done
|
|
||||||
losetup -d $_loopdev || true
|
|
||||||
rm -rf "$_bootdir" "$_rootdir"
|
|
||||||
rm -f "$_outfile"
|
|
||||||
}
|
|
||||||
trap cleanup ERR
|
|
||||||
|
|
||||||
# the following installation instructions are adapted from
|
|
||||||
# https://archlinuxarm.org/platforms/armv7/arm/versatile-express
|
|
||||||
|
|
||||||
# partition the image
|
|
||||||
dd if=/dev/zero of=$_loopdev bs=1M count=8
|
|
||||||
parted -s $_loopdev \
|
|
||||||
mklabel gpt \
|
|
||||||
mkpart ESP fat32 1MiB 513MiB \
|
|
||||||
set 1 boot on \
|
|
||||||
mkpart primary linux-swap 513MiB 4609MiB \
|
|
||||||
mkpart primary ext4 4609MiB 100%
|
|
||||||
|
|
||||||
# create filesystems
|
|
||||||
mkfs.vfat -F 32 ${_loopdev}p1
|
|
||||||
mkswap ${_loopdev}p2
|
|
||||||
mkfs.ext4 ${_loopdev}p3
|
|
||||||
|
|
||||||
# install the base image
|
|
||||||
mkdir -p "$_bootdir"
|
|
||||||
mkdir -p "$_rootdir"
|
|
||||||
mount ${_loopdev}p1 "$_bootdir"
|
|
||||||
mount ${_loopdev}p3 "$_rootdir"
|
|
||||||
bsdtar -vxpf $TARBALL -C "$_rootdir"
|
|
||||||
sync
|
|
||||||
|
|
||||||
# fill the boot partition and create fstab
|
|
||||||
mv -v "$_rootdir"/boot/* "$_bootdir"
|
|
||||||
cat >> "$_rootdir"/etc/fstab << EOF
|
|
||||||
/dev/mmcblk0p1 /boot vfat defaults 0 0
|
|
||||||
/dev/mmcblk0p2 none swap defaults 0 0
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# create and install root ssh keys for access
|
|
||||||
mkdir -p keys
|
|
||||||
test -f keys/id_rsa || ssh-keygen -N '' -f keys/id_rsa
|
|
||||||
chown $SUDO_USER keys/id_rsa*
|
|
||||||
mkdir -m 700 "$_rootdir"/root/.ssh
|
|
||||||
install -m 600 -o 0 -g 0 keys/id_rsa.pub "$_rootdir"/root/.ssh/authorized_keys
|
|
||||||
|
|
||||||
# create and install ssh host keys
|
|
||||||
for cipher in dsa ecdsa ed25519 rsa; do
|
|
||||||
if [ ! -f keys/ssh_host_${cipher}_key ]; then
|
|
||||||
ssh-keygen -N '' -t ${cipher} -f keys/ssh_host_${cipher}_key
|
|
||||||
fi
|
|
||||||
install -m 600 -o 0 -g 0 keys/ssh_host_${cipher}_key "$_rootdir"/etc/ssh
|
|
||||||
install -m 644 -o 0 -g 0 keys/ssh_host_${cipher}_key.pub "$_rootdir"/etc/ssh
|
|
||||||
done
|
|
||||||
|
|
||||||
# tie up any loose ends
|
|
||||||
for part in p1 p3; do
|
|
||||||
umount $_loopdev$part
|
|
||||||
done
|
|
||||||
losetup -d $_loopdev
|
|
||||||
rm -rf "$_bootdir" "$_rootdir"
|
|
133
src/stage2.sh
133
src/stage2.sh
@ -1,133 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
##############################################################################
|
|
||||||
# parabola-arm-imagebuilder #
|
|
||||||
# #
|
|
||||||
# Copyright (C) 2017 Andreas Grapentin #
|
|
||||||
# #
|
|
||||||
# This program is free software: you can redistribute it and/or modify #
|
|
||||||
# it under the terms of the GNU General Public License as published by #
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or #
|
|
||||||
# (at your option) any later version. #
|
|
||||||
# #
|
|
||||||
# This program is distributed in the hope that it will be useful, #
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
||||||
# GNU General Public License for more details. #
|
|
||||||
# #
|
|
||||||
# You should have received a copy of the GNU General Public License #
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
_scriptfile="$_builddir"/migrate.sh
|
|
||||||
_pidfile="$_builddir"/qemu-$$.pid
|
|
||||||
_bootdir="$_builddir"/boot-$$
|
|
||||||
|
|
||||||
_loopdev=$(sudo losetup -f --show $_outfile)
|
|
||||||
|
|
||||||
# register cleanup handler to stop the started VM
|
|
||||||
function cleanup {
|
|
||||||
test -f "$_pidfile" && (kill -9 $(cat "$_pidfile") || true)
|
|
||||||
rm -f "$_pidfile"
|
|
||||||
umount ${_loopdev}p1
|
|
||||||
losetup -d $_loopdev
|
|
||||||
rm -rf "$_bootdir"
|
|
||||||
rm -f "$_scriptfile"
|
|
||||||
}
|
|
||||||
trap cleanup ERR
|
|
||||||
|
|
||||||
# create the migration script, adapted from
|
|
||||||
# https://wiki.parabola.nu/Migration_from_Arch_ARM
|
|
||||||
cat > "$_scriptfile" << 'EOF'
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
# install the keyrings and mirrorlist
|
|
||||||
sed -i 's/^SigLevel.*/SigLevel = Never/' /etc/pacman.conf
|
|
||||||
pacman --noconfirm -U https://www.parabola.nu/packages/libre/any/parabola-keyring/download/
|
|
||||||
pacman --noconfirm -U https://www.parabola.nu/packages/libre/any/archlinux32-keyring/download/
|
|
||||||
pacman --noconfirm -U https://www.parabola.nu/packages/core/any/archlinux-keyring/download/
|
|
||||||
pacman --noconfirm -U https://www.parabola.nu/packages/libre/any/pacman-mirrorlist/download/
|
|
||||||
pacman --noconfirm -S archlinuxarm-keyring
|
|
||||||
sed -i 's/^SigLevel.*/SigLevel = Required DatabaseOptional/' /etc/pacman.conf
|
|
||||||
|
|
||||||
# update the keyring
|
|
||||||
pacman-key --init
|
|
||||||
pacman-key --populate archlinuxarm archlinux archlinux32 parabola
|
|
||||||
pacman-key --refresh-keys
|
|
||||||
|
|
||||||
# install the mirrorlist
|
|
||||||
[ -f /etc/pacman.d/mirrorlist.pacnew ] && mv /etc/pacman.d/mirrorlist{.pacnew,}
|
|
||||||
|
|
||||||
# enable the [libre] and disable [alarm] in pacman.conf
|
|
||||||
sed -i '/^\[core\]/i \
|
|
||||||
[libre] \
|
|
||||||
Include = /etc/pacman.d/mirrorlist \
|
|
||||||
' /etc/pacman.conf
|
|
||||||
sed -Ei '/^\[alarm\]|\[aur\]/,+2d' /etc/pacman.conf
|
|
||||||
|
|
||||||
# clear the pacman cache. all of it.
|
|
||||||
yes | pacman -Scc
|
|
||||||
|
|
||||||
# fix the architecture in /etc/pacman.conf
|
|
||||||
sed -i 's/^Architecture.*/Architecture = armv7h/' /etc/pacman.conf
|
|
||||||
|
|
||||||
# update the system to parabola
|
|
||||||
pacman --noconfirm -Syy
|
|
||||||
pacman --noconfirm -S pacman
|
|
||||||
mv /etc/pacman.conf{.pacnew,}
|
|
||||||
pacman --noconfirm -Syyuu
|
|
||||||
pacman --noconfirm -S your-freedom
|
|
||||||
yes | pacman -S linux-libre
|
|
||||||
|
|
||||||
# cleanup users
|
|
||||||
userdel -r alarm
|
|
||||||
useradd -mU parabola
|
|
||||||
echo 'parabola:parabola' | chpasswd
|
|
||||||
echo 'root:parabola' | chpasswd
|
|
||||||
|
|
||||||
# cleanup hostname
|
|
||||||
echo "parabola-arm" > /etc/hostname
|
|
||||||
|
|
||||||
# enable UTF-8 locale
|
|
||||||
sed -i 's/#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
|
|
||||||
locale-gen
|
|
||||||
sed -i 's/LANG.*/LANG=en_US.UTF-8/' /etc/locale.conf
|
|
||||||
EOF
|
|
||||||
chmod +x "$_scriptfile"
|
|
||||||
|
|
||||||
# start the VM
|
|
||||||
mkdir -p "$_bootdir"
|
|
||||||
mount ${_loopdev}p1 $_bootdir
|
|
||||||
QEMU_AUDIO_DRV=none qemu-system-arm \
|
|
||||||
-M vexpress-a9 \
|
|
||||||
-m 1G \
|
|
||||||
-dtb "$_bootdir"/dtbs/vexpress-v2p-ca9.dtb \
|
|
||||||
-kernel "$_bootdir"/zImage \
|
|
||||||
--append "root=/dev/mmcblk0p3 rw roottype=ext4 console=ttyAMA0" \
|
|
||||||
-drive if=sd,driver=raw,cache=writeback,file="$_outfile" \
|
|
||||||
-display none \
|
|
||||||
-net user,hostfwd=tcp::2022-:22 \
|
|
||||||
-net nic \
|
|
||||||
-daemonize \
|
|
||||||
-pidfile "$_pidfile"
|
|
||||||
|
|
||||||
# wait for ssh to be up
|
|
||||||
while ! ssh -p 2022 -i keys/id_rsa root@localhost -o StrictHostKeyChecking=no true 2>/dev/null; do
|
|
||||||
echo -n . && sleep 5
|
|
||||||
done && echo
|
|
||||||
|
|
||||||
# copy and execute the migration script
|
|
||||||
scp -P 2022 -i keys/id_rsa "$_scriptfile" root@localhost:
|
|
||||||
ssh -p 2022 -i keys/id_rsa root@localhost "./$(basename "$_scriptfile")"
|
|
||||||
|
|
||||||
# stop the VM
|
|
||||||
ssh -p 2022 -i keys/id_rsa root@localhost "nohup shutdown -h now &>/dev/null & exit"
|
|
||||||
while kill -0 $(cat "$_pidfile") 2> /dev/null; do echo -n . && sleep 5; done && echo
|
|
||||||
|
|
||||||
# cleanup
|
|
||||||
umount ${_loopdev}p1
|
|
||||||
losetup -d $_loopdev
|
|
||||||
rm -rf "$_bootdir" "$_scriptfile" "$_pidfile"
|
|
167
src/stage3.sh
167
src/stage3.sh
@ -1,167 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
##############################################################################
|
|
||||||
# parabola-arm-imagebuilder #
|
|
||||||
# #
|
|
||||||
# Copyright (C) 2017 Andreas Grapentin #
|
|
||||||
# #
|
|
||||||
# This program is free software: you can redistribute it and/or modify #
|
|
||||||
# it under the terms of the GNU General Public License as published by #
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or #
|
|
||||||
# (at your option) any later version. #
|
|
||||||
# #
|
|
||||||
# This program is distributed in the hope that it will be useful, #
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
||||||
# GNU General Public License for more details. #
|
|
||||||
# #
|
|
||||||
# You should have received a copy of the GNU General Public License #
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
_scriptfile="$_builddir"/migrate.sh
|
|
||||||
_pidfile="$_builddir"/qemu-$$.pid
|
|
||||||
_bootdir="$_builddir"/boot-$$
|
|
||||||
|
|
||||||
_loopdev=$(sudo losetup -f --show "$_outfile")
|
|
||||||
|
|
||||||
# register cleanup handler to stop the started VM
|
|
||||||
function cleanup {
|
|
||||||
test -f "$_pidfile" && (kill -9 $(cat "$_pidfile") || true)
|
|
||||||
rm -f "$_pidfile"
|
|
||||||
umount ${_loopdev}p1
|
|
||||||
losetup -d $_loopdev
|
|
||||||
rm -rf "$_bootdir"
|
|
||||||
rm -f "$_scriptfile"
|
|
||||||
}
|
|
||||||
trap cleanup ERR
|
|
||||||
|
|
||||||
# create the package build preparation script, adapted from
|
|
||||||
# https://wiki.parabola.nu/Package_maintainer_guide
|
|
||||||
(source /etc/makepkg.conf && cat > "$_scriptfile" << EOF
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
# setup parabola login keys
|
|
||||||
cat /root/.ssh/authorized_keys >> /home/parabola/.ssh/authorized_keys
|
|
||||||
|
|
||||||
# fix key permissions and ownership
|
|
||||||
chown -R parabola:parabola /home/parabola/{.gnupg,.ssh,.gitconfig}
|
|
||||||
chmod 600 /home/parabola/.ssh/authorized_keys
|
|
||||||
|
|
||||||
# install needed packages
|
|
||||||
pacman --noconfirm -S libretools base-devel vim sudo \
|
|
||||||
rxvt-unicode-terminfo bash-completion htop
|
|
||||||
|
|
||||||
# update configuration
|
|
||||||
sed -i \
|
|
||||||
-e 's_^#PKGDEST.*_PKGDEST="/home/parabola/output/packages"_' \
|
|
||||||
-e 's_^#SRCDEST.*_SRCDEST="/home/parabola/output/sources"_' \
|
|
||||||
-e 's_^#SRCPKGDEST.*_SRCPKGDEST="/home/parabola/output/srcpackages"_' \
|
|
||||||
-e 's_^#LOGDEST.*_LOGDEST="/home/parabola/output/makepkglogs"_' \
|
|
||||||
-e 's_^#PACKAGER.*_PACKAGER="$PACKAGER"_' \
|
|
||||||
-e 's_^#GPGKEY.*_GPGKEY="$GPGKEY"_' \
|
|
||||||
/etc/makepkg.conf
|
|
||||||
|
|
||||||
sed -i \
|
|
||||||
-e 's_^CHROOTDIR.*_CHROOTDIR="/home/parabola/build"_' \
|
|
||||||
-e 's_^CHROOTEXTRAPKG.*_CHROOTEXTRAPKG=(vim)_' \
|
|
||||||
/etc/libretools.d/chroot.conf
|
|
||||||
|
|
||||||
sed -i \
|
|
||||||
-e 's_^HOOKPOSTRELEASE.*_HOOKPOSTRELEASE=""_' \
|
|
||||||
/etc/libretools.conf
|
|
||||||
|
|
||||||
# create directories
|
|
||||||
mkdir -p /home/parabola/output/{packages,sources,srcpackages,makepkglogs}
|
|
||||||
chown -R parabola:parabola /home/parabola/output
|
|
||||||
|
|
||||||
# disable systemd-stdin hack...
|
|
||||||
sed -i '/XXX: SYSTEMD-STDIN HACK/,+9d' /usr/bin/librechroot
|
|
||||||
|
|
||||||
# setup sudo
|
|
||||||
cat > /etc/sudoers.d/parabola << IEOF
|
|
||||||
# grant full permissions to user parabola
|
|
||||||
parabola ALL=(ALL) NOPASSWD: ALL
|
|
||||||
IEOF
|
|
||||||
|
|
||||||
# setup work directories
|
|
||||||
su - parabola -c createworkdir
|
|
||||||
su - parabola -c "sudo librechroot make"
|
|
||||||
|
|
||||||
# setup batch building
|
|
||||||
pacman --noconfirm -S task-spooler
|
|
||||||
|
|
||||||
cat >> /home/parabola/.bashrc << 'IEOF'
|
|
||||||
|
|
||||||
alias sudo='sudo '
|
|
||||||
|
|
||||||
function librespool() {
|
|
||||||
local cmd
|
|
||||||
printf -v cmd '%q ' "\$@"
|
|
||||||
tsp -d script --return --quiet --command "\$cmd" /dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
alias librechroot-spool='librespool sudo /usr/bin/librechroot'
|
|
||||||
alias libremakepkg-spool='librespool sudo /usr/bin/libremakepkg'
|
|
||||||
|
|
||||||
alias qbuild='if tsp | grep " \$(pwd)\\$" >/dev/null; then tspr; fi && tsp echo \$(pwd) && librechroot-spool update && libremakepkg-spool && tsp -d librestage'
|
|
||||||
|
|
||||||
alias tspr='d=\$(tsp | grep " \$(pwd)\\$" | head -n1 | cut -d" " -f1) && for i in \$(seq \$d \$((\$d+3))); do tsp -r \$i; done'
|
|
||||||
alias tspl='watch -n5 tsp'
|
|
||||||
alias tspc='while tsp | grep -q running; do tsp -c; done'
|
|
||||||
|
|
||||||
alias librecommit='if tsp | grep " \$(pwd)\\$" >/dev/null; then tspr; fi && git commit -m "\$(pwd | rev | cut -d"/" -f1-2 | rev): updated to \$(bash -c "source PKGBUILD && echo \\\$pkgver")"'
|
|
||||||
IEOF
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
chmod +x "$_scriptfile"
|
|
||||||
|
|
||||||
# start the VM
|
|
||||||
mkdir -p "$_bootdir"
|
|
||||||
mount ${_loopdev}p1 "$_bootdir"
|
|
||||||
_board="vexpress-a9"
|
|
||||||
_cpu="cortex-a9"
|
|
||||||
_memory="1G"
|
|
||||||
_kernel="$_bootdir"/vmlinuz-linux-libre
|
|
||||||
_dtb="$_bootdir"/dtbs/linux-libre/vexpress-v2p-ca9.dtb
|
|
||||||
_initrd="$_bootdir"/initramfs-linux-libre.img
|
|
||||||
QEMU_AUDIO_DRV=none qemu-system-arm \
|
|
||||||
-M $_board \
|
|
||||||
-cpu $_cpu \
|
|
||||||
-m $_memory \
|
|
||||||
-kernel "$_kernel" \
|
|
||||||
-dtb "$_dtb" \
|
|
||||||
-initrd "$_initrd" \
|
|
||||||
--append "root=/dev/mmcblk0p3 rw roottype=ext4 console=ttyAMA0" \
|
|
||||||
-drive if=sd,driver=raw,cache=writeback,file="$_outfile" \
|
|
||||||
-display none \
|
|
||||||
-net user,hostfwd=tcp::2022-:22 \
|
|
||||||
-net nic \
|
|
||||||
-daemonize \
|
|
||||||
-pidfile "$_pidfile"
|
|
||||||
|
|
||||||
# wait for ssh to be up
|
|
||||||
while ! ssh -p 2022 -i keys/id_rsa root@localhost -o StrictHostKeyChecking=no true 2>/dev/null; do
|
|
||||||
echo -n . && sleep 5
|
|
||||||
done && echo
|
|
||||||
|
|
||||||
# copy the current users keys to the VM
|
|
||||||
scp -rP 2022 -i keys/id_rsa "$(sudo -iu $SUDO_USER pwd)"/.gnupg root@localhost:/home/parabola/
|
|
||||||
scp -rP 2022 -i keys/id_rsa "$(sudo -iu $SUDO_USER pwd)"/.ssh root@localhost:/home/parabola/
|
|
||||||
scp -rP 2022 -i keys/id_rsa "$(sudo -iu $SUDO_USER pwd)"/.gitconfig root@localhost:/home/parabola/
|
|
||||||
|
|
||||||
# copy and execute the migration script
|
|
||||||
scp -P 2022 -i keys/id_rsa "$_scriptfile" root@localhost:
|
|
||||||
ssh -p 2022 -i keys/id_rsa root@localhost "./$(basename "$_scriptfile")"
|
|
||||||
|
|
||||||
# stop the VM
|
|
||||||
ssh -p 2022 -i keys/id_rsa root@localhost "nohup shutdown -h now &>/dev/null & exit"
|
|
||||||
while kill -0 $(cat "$_pidfile") 2> /dev/null; do echo -n . && sleep 5; done && echo
|
|
||||||
|
|
||||||
# cleanup
|
|
||||||
umount ${_loopdev}p1
|
|
||||||
losetup -d $_loopdev
|
|
||||||
rm -rf "$_bootdir" "$_scriptfile" "$_pidfile"
|
|
94
start.sh
94
start.sh
@ -1,94 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
##############################################################################
|
|
||||||
# parabola-arm-imagebuilder #
|
|
||||||
# #
|
|
||||||
# Copyright (C) 2017 Andreas Grapentin #
|
|
||||||
# #
|
|
||||||
# This program is free software: you can redistribute it and/or modify #
|
|
||||||
# it under the terms of the GNU General Public License as published by #
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or #
|
|
||||||
# (at your option) any later version. #
|
|
||||||
# #
|
|
||||||
# This program is distributed in the hope that it will be useful, #
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
||||||
# GNU General Public License for more details. #
|
|
||||||
# #
|
|
||||||
# You should have received a copy of the GNU General Public License #
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
_builddir=build
|
|
||||||
mkdir -p "$_builddir"
|
|
||||||
|
|
||||||
_imagefile=$1
|
|
||||||
_pidfile="$_builddir"/qemu-$$.pid
|
|
||||||
_bootdir="$_builddir"/boot-$$
|
|
||||||
|
|
||||||
_loopdev=$(sudo losetup -f --show "$_imagefile")
|
|
||||||
sudo partprobe $_loopdev
|
|
||||||
touch "$_pidfile"
|
|
||||||
|
|
||||||
# register a cleanup error handler
|
|
||||||
function cleanup {
|
|
||||||
test -f "$_pidfile" && (sudo kill -9 $(cat "$_pidfile") || true)
|
|
||||||
rm -f "$_pidfile"
|
|
||||||
sudo umount ${_loopdev}p1
|
|
||||||
sudo losetup -d $_loopdev
|
|
||||||
rm -rf "$_bootdir"
|
|
||||||
}
|
|
||||||
trap cleanup ERR
|
|
||||||
|
|
||||||
# start the VM
|
|
||||||
mkdir -p "$_bootdir"
|
|
||||||
sudo mount ${_loopdev}p1 "$_bootdir"
|
|
||||||
_board="vexpress-a9"
|
|
||||||
# FIXME: archlinuxarm rust SIGILLs on cortex-a9 cpus, using cortex-a15 for now
|
|
||||||
_cpu="cortex-a15"
|
|
||||||
_memory="1G"
|
|
||||||
_snapshot=""
|
|
||||||
[ -z "${PERSISTENT:-}" ] && _snapshot="-snapshot"
|
|
||||||
_daemonize="-nographic -serial mon:stdio"
|
|
||||||
[ -z "${FOREGROUND:-}" ] && _daemonize="-daemonize -pidfile $_pidfile -net user,hostfwd=tcp::2022-:22 -net nic -display none"
|
|
||||||
if [ -f "$_bootdir"/zImage ]; then
|
|
||||||
_kernel="$_bootdir"/zImage
|
|
||||||
_dtb="$_bootdir"/dtbs/vexpress-v2p-ca9.dtb
|
|
||||||
_initrd="$_bootdir"/initramfs-linux.img
|
|
||||||
else
|
|
||||||
_kernel="$_bootdir"/vmlinuz-linux-libre
|
|
||||||
_dtb="$_bootdir"/dtbs/linux-libre/vexpress-v2p-ca9.dtb
|
|
||||||
_initrd="$_bootdir"/initramfs-linux-libre.img
|
|
||||||
fi
|
|
||||||
QEMU_AUDIO_DRV=none qemu-system-arm \
|
|
||||||
-M $_board \
|
|
||||||
-cpu $_cpu \
|
|
||||||
-m $_memory \
|
|
||||||
-kernel "$_kernel" \
|
|
||||||
-dtb "$_dtb" \
|
|
||||||
-initrd "$_initrd" \
|
|
||||||
--append "root=/dev/mmcblk0p3 rw roottype=ext4 console=ttyAMA0" \
|
|
||||||
-drive if=sd,driver=raw,cache=writeback,file="$_imagefile" \
|
|
||||||
$_daemonize \
|
|
||||||
$_snapshot
|
|
||||||
|
|
||||||
if [ -z "${FOREGROUND:-}" ]; then
|
|
||||||
# wait for ssh to be up
|
|
||||||
_sshopts="-o StrictHostKeyChecking=no -o ConnectTimeout=5"
|
|
||||||
while ! ssh -p 2022 -i keys/id_rsa root@localhost $_sshopts true 2>/dev/null; do
|
|
||||||
echo -n . && sleep 5
|
|
||||||
done && echo
|
|
||||||
|
|
||||||
# open a session
|
|
||||||
ssh -p 2022 -i keys/id_rsa parabola@localhost
|
|
||||||
|
|
||||||
# shutdown the VM
|
|
||||||
ssh -p 2022 -i keys/id_rsa root@localhost "nohup shutdown -h now &>/dev/null & exit"
|
|
||||||
while sudo kill -0 $(cat "$_pidfile") 2> /dev/null; do echo -n . && sleep 5; done && echo
|
|
||||||
fi
|
|
||||||
|
|
||||||
# cleanup
|
|
||||||
sudo umount ${_loopdev}p1
|
|
||||||
sudo losetup -d $_loopdev
|
|
||||||
rm -rf "$_bootdir" "$_pidfile"
|
|
Loading…
Reference in New Issue
Block a user