450 lines
11 KiB
Bash
450 lines
11 KiB
Bash
#!/usr/bin/env zsh
|
|
# Copyright (c) 2016-2017 Dyne.org Foundation
|
|
# libdevuansdk is maintained by Ivan J. <parazyd@dyne.org>
|
|
#
|
|
# This file is part of libdevuansdk
|
|
#
|
|
# This source code 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 software 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 source code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
## helper functions that make my life easier
|
|
|
|
vars+=(loopdevice)
|
|
|
|
build_image_dist() {
|
|
fn build_image_dist
|
|
req=(arch size parted_type)
|
|
if [[ $parted_type = gpt ]]; then
|
|
req+=(gpt_boot gpt_root)
|
|
elif [[ $parted_type = dos ]]; then
|
|
req+=(parted_root parted_boot)
|
|
fi
|
|
req+=(workdir strapdir image_name)
|
|
ckreq || return 1
|
|
|
|
notice "building complete dist image"
|
|
act "$image_name"
|
|
|
|
bootstrap_complete_base || { zerr; wrapup }
|
|
blend_preinst || { zerr; wrapup }
|
|
image_prepare_raw || { zerr; wrapup }
|
|
image_partition_raw_${parted_type} || { zerr; wrapup }
|
|
build_kernel_${arch} || { zerr; wrapup }
|
|
blend_postinst || { zerr; wrapup }
|
|
rsync_to_raw_image || { zerr; wrapup }
|
|
image_pack_dist || { zerr; wrapup }
|
|
}
|
|
|
|
build_iso_dist() {
|
|
fn build_iso_dist
|
|
req=(workdir strapdir os arch)
|
|
ckreq || return 1
|
|
|
|
notice "building complete iso image"
|
|
|
|
bootstrap_complete_base || { zerr; wrapup }
|
|
blend_preinst || { zerr; wrapup }
|
|
iso_prepare_strap || { zerr; wrapup }
|
|
build_kernel_${arch} || { zerr; wrapup }
|
|
iso_setup_isolinux || { zerr; wrapup }
|
|
iso_write_isolinux_cfg || { zerr; wrapup }
|
|
#[[ $INSTALLER = 1 ]] && iso_setup_installer || zerr
|
|
blend_postinst || { zerr; wrapup }
|
|
fill_apt_cache || { zerr; wrapup }
|
|
iso_squash_strap || { zerr; wrapup }
|
|
iso_xorriso_build || { zerr; wrapup }
|
|
}
|
|
|
|
build_vagrant_dist() {
|
|
fn build_vagrant_dist
|
|
req=(workdir strapdir os arch imageformat)
|
|
ckreq || return 1
|
|
|
|
notice "building complete vagrant image"
|
|
|
|
image_${imageformat}_as_strapdir || { zerr; wrapup }
|
|
bootstrap_complete_base || { zerr; wrapup }
|
|
vm_inject_overrides || { zerr; wrapup }
|
|
blend_preinst || { zerr; wrapup }
|
|
vm_setup_grub || { zerr; wrapup }
|
|
blend_postinst || { zerr; wrapup }
|
|
vm_umount_${imageformat} || { zerr; wrapup }
|
|
vm_vbox_setup || { zerr; wrapup }
|
|
vm_vagrant_package || { zerr; wrapup }
|
|
vm_pack_dist || { zerr; wrapup }
|
|
}
|
|
|
|
getfield() {
|
|
fn getfield $*
|
|
print "$1" | \
|
|
grep "^$2=" | \
|
|
sed -e 's:.*=\(.*\)$:\1:g' | \
|
|
sed -e 's:^"\(.*\)"$:\1:g'
|
|
}
|
|
|
|
add-user() {
|
|
fn add-user $*
|
|
local user="$1"
|
|
local pass="$2"
|
|
req=(strapdir user pass)
|
|
ckreq || return 1
|
|
|
|
notice "adding user $user:$pass"
|
|
|
|
cat <<EOF | sudo tee ${strapdir}/adduser
|
|
#!/bin/sh
|
|
useradd -m ${user}
|
|
echo "${user}:${pass}" | chpasswd
|
|
EOF
|
|
chroot-script adduser || zerr
|
|
}
|
|
|
|
devprocsys() {
|
|
fn devprocsys "$@"
|
|
local watdo="$1"
|
|
local werdo="$2"
|
|
req=(watdo werdo)
|
|
ckreq || return 1
|
|
|
|
if [[ $watdo = mount ]]; then
|
|
sudo mount -o bind /sys $werdo/sys && act "mounted sys" && \
|
|
sudo mount -t proc proc $werdo/proc && act "mounted proc" && \
|
|
sudo mount -o bind /dev $werdo/dev && act "mounted dev" && \
|
|
sudo mount -o bind /dev/pts $werdo/dev/pts && act "mounted devpts" && \
|
|
return 0
|
|
elif [[ $watdo = umount ]]; then
|
|
sudo umount $werdo/dev/pts && act "umounted devpts" && sleep 1
|
|
sudo umount $werdo/dev && act "umounted dev" && sleep 1
|
|
sudo umount $werdo/proc && act "umounted proc" && sleep 1
|
|
sudo umount $werdo/sys && act "umounted sys" && sleep 1
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
wrapup() {
|
|
# a hopefully clean exit
|
|
fn wrapup
|
|
req=(strapdir)
|
|
ckreq || {
|
|
die "something is very wrong"
|
|
die "cleanup yourself, sorry"
|
|
exit 1
|
|
}
|
|
|
|
devprocsys umount $strapdir
|
|
exit 1
|
|
}
|
|
|
|
findloopdev() {
|
|
fn findloopdev
|
|
req=(workdir image_name)
|
|
ckreq || return 1
|
|
|
|
notice "finding a free loopdevice"
|
|
|
|
loopdevice=$(sudo losetup -f --show $workdir/${image_name}.img)
|
|
sudo partx -av $loopdevice || zerr
|
|
|
|
func "loopdevice: $loopdevice"
|
|
silly sleep 2
|
|
}
|
|
|
|
findfreenbd() {
|
|
fn findfreenbd
|
|
|
|
notice "looking for a free /dev/nbd"
|
|
|
|
for i in $(seq 0 8); do
|
|
grep "^/dev/nbd${i}" /proc/mounts >/dev/null || {
|
|
print "/dev/nbd${i}"
|
|
break
|
|
}
|
|
done
|
|
}
|
|
|
|
qemu_install_user() {
|
|
fn qemu_install_user
|
|
req=(qemu_bin strapdir)
|
|
ckreq || return 1
|
|
|
|
notice "installing qemu-user-static"
|
|
sudo cp $qemu_bin $strapdir/usr/bin
|
|
}
|
|
|
|
dpkgdivert() {
|
|
fn dpkgdivert "$@"
|
|
req=(watdo werdo)
|
|
local watdo="$1"
|
|
local werdo="$2"
|
|
ckreq || return 1
|
|
|
|
if [[ $watdo = on ]]; then
|
|
cat <<EOF | sudo tee ${werdo}/dpkgdivert >/dev/null
|
|
#!/bin/sh
|
|
dpkg-divert --add --local \
|
|
--divert /usr/sbin/invoke-rc.d.chroot \
|
|
--rename /usr/sbin/invoke-rc.d
|
|
cp /bin/true /usr/sbin/invoke-rc.d
|
|
echo -e "#!/bin/sh\nexit 101" > /usr/sbin/policy-rc.d
|
|
chmod +x /usr/sbin/policy-rc.d
|
|
EOF
|
|
elif [[ $watdo = off ]]; then
|
|
cat <<EOF | sudo tee ${werdo}/dpkgdivert >/dev/null
|
|
#!/bin/sh
|
|
rm -f /usr/sbin/policy-rc.d
|
|
rm -f /usr/sbin/invoke-rc.d
|
|
dpkg-divert --remove --rename /usr/sbin/invoke-rc.d
|
|
EOF
|
|
fi
|
|
|
|
chroot-script dpkgdivert || zerr
|
|
}
|
|
|
|
enableserv() {
|
|
fn enableserv "$@"
|
|
local service="$1"
|
|
req=(service strapdir)
|
|
ckreq || return 1
|
|
|
|
cat <<EOF | sudo tee -a ${strapdir}/enserv >/dev/null
|
|
#!/bin/sh
|
|
update-rc.d ${service} enable
|
|
EOF
|
|
|
|
notice "enabling $service service"
|
|
chroot-script enserv
|
|
}
|
|
|
|
disableserv() {
|
|
fn disableserv "$@"
|
|
local service="$1"
|
|
req=(service strapdir)
|
|
ckreq || return 1
|
|
|
|
cat <<EOF | sudo tee -a ${strapdir}/disserv >/dev/null
|
|
#!/bin/sh
|
|
update-rc.d ${service} disable
|
|
EOF
|
|
|
|
notice "disabling $service service"
|
|
chroot-script disserv
|
|
}
|
|
|
|
install-custdebs() {
|
|
fn install-custdebs
|
|
req=(R strapdir custom_deb_packages)
|
|
ckreq || return 1
|
|
|
|
sudo mkdir -p $strapdir/debs
|
|
sudo cp $R/extra/custom-packages/*.deb $strapdir/debs/
|
|
|
|
cat <<EOF | sudo tee ${strapdir}/install-debs >/dev/null
|
|
#!/bin/sh
|
|
cd /debs
|
|
for deb in ${custom_deb_packages}; do
|
|
dpkg -i \$deb
|
|
apt-get --yes --force-yes -f install
|
|
done
|
|
cd /
|
|
apt-get autoremove
|
|
rm -rf /debs
|
|
EOF
|
|
chroot-script install-debs
|
|
}
|
|
|
|
chroot-script() {
|
|
fn chroot-script "$@"
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
mkdir -p "$R/log"
|
|
|
|
case "x$1" in
|
|
x-d)
|
|
local script="$2"
|
|
devprocsys mount "$strapdir" || zerr
|
|
dpkgdivert on "$strapdir" || zerr
|
|
|
|
## logging
|
|
sudo sed -i "$strapdir/$script" \
|
|
-e 's@#!/bin/sh@#!/bin/sh\'$'\nset -x ; exec 2>/'$script'.log@'
|
|
|
|
notice "chrooting to execute $script..."
|
|
sudo chmod +x "$strapdir/$script" || zerr
|
|
sudo -E chroot "$strapdir" "/$script" || zerr
|
|
sudo mv -f "$strapdir/${script}.log" "$R/log/"
|
|
|
|
dpkgdivert off "$strapdir" || zerr
|
|
devprocsys umount "$strapdir" || zerr
|
|
;;
|
|
*)
|
|
local script="$1"
|
|
[[ "$APT_CACHE" = 1 ]] && { aptcache on "$strapdir/mnt" || zerr }
|
|
|
|
## logging
|
|
sudo sed -i "$strapdir/$script" \
|
|
-e 's@#!/bin/sh@#!/bin/sh\'$'\nset -x ; exec 2>/'$script'.log@'
|
|
|
|
notice "chrooting to execute $script..."
|
|
sudo chmod +x "$strapdir/$script" || zerr
|
|
sudo -E chroot "$strapdir" "/$script" || zerr
|
|
sudo mv -f "$strapdir/${script}.log" "$R/log/"
|
|
|
|
[[ "$APT_CACHE" = 1 ]] && { aptcache off "$strapdir/mnt" || zerr }
|
|
;;
|
|
esac
|
|
|
|
sudo rm -f $strapdir/$script
|
|
}
|
|
|
|
install_fake_package() {
|
|
fn install_fake_package "$@"
|
|
req=(strapdir pkgname pkgver section)
|
|
local pkgname="$1"
|
|
local pkgver="$2"
|
|
local section="$3"
|
|
ckreq || return 1
|
|
|
|
local _tmp="$strapdir/tmp"
|
|
sudo mkdir -p "$_tmp/$pkgname"
|
|
|
|
cat <<EOF | sudo tee ${_tmp}/${pkgname}/${pkgname}_${pkgver}.control >/dev/null
|
|
Section: ${section}
|
|
Priority: optional
|
|
Homepage: https://devuan.org/
|
|
Standards-Version: 3.9.6
|
|
|
|
Package: ${pkgname}
|
|
Version: ${pkgver}
|
|
Maintainer: Devuan developers <onelove@devuan.org>
|
|
Architecture: all
|
|
Description: (Fake) ${pkgname}
|
|
Dummy package used to meet some dependencies without installing the
|
|
real ${pkgname} package.
|
|
EOF
|
|
|
|
cat <<EOF | sudo tee ${strapdir}/install-fake-package >/dev/null
|
|
#!/bin/sh
|
|
cd /tmp/${pkgname}
|
|
equivs-build ${pkgname}_${pkgver}.control \
|
|
&& dpkg -i ${pkgname}_${pkgver}_all.deb || exit 1
|
|
cd /tmp
|
|
rm -rf ${pkgname}
|
|
EOF
|
|
chroot-script install-fake-package || zerr
|
|
}
|
|
|
|
blend_preinst() {
|
|
fn blend_preinst
|
|
func "not overriden"
|
|
return 0
|
|
}
|
|
|
|
blend_postinst() {
|
|
fn blend_postinst
|
|
func "not overriden"
|
|
return 0
|
|
}
|
|
|
|
aptcache() {
|
|
fn aptcache "$*"
|
|
req=(aptcachedir watdo werdo APT_CACHE)
|
|
local watdo="$1"
|
|
local werdo="$2"
|
|
ckreq || return 1
|
|
|
|
[[ $APT_CACHE = 1 ]] || return 0
|
|
|
|
case "$watdo" in
|
|
on)
|
|
act "mounting local apt cache"
|
|
sudo mount -o bind "$aptcachedir" "$werdo" || zerr
|
|
;;
|
|
off)
|
|
act "umounting local apt cache"
|
|
sudo umount "$werdo" || zerr
|
|
;;
|
|
esac
|
|
}
|
|
|
|
fill_apt_cache() {
|
|
fn fill_apt_cache
|
|
req=(strapdir APT_CACHE)
|
|
ckreq || return 1
|
|
|
|
[[ $APT_CACHE = 1 ]] || return 0
|
|
|
|
notice "filling local apt cache"
|
|
|
|
cat <<EOF | sudo tee ${strapdir}/fill-apt-cache >/dev/null
|
|
#!/bin/sh
|
|
|
|
# NOTE: do we need apt update or does it read the remote(s)?
|
|
apt-get update
|
|
apt-get install dpkg-dev
|
|
|
|
cp -afv /var/cache/apt/archives/*.deb /mnt
|
|
cd /mnt
|
|
dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
|
|
cd -
|
|
|
|
apt-get purge dpkg-dev
|
|
|
|
sed -i -e "@deb file:/mnt@d" /etc/apt/sources.list
|
|
apt-get update
|
|
|
|
EOF
|
|
chroot-script fill-apt-cache || zerr
|
|
}
|
|
|
|
silly() {
|
|
fn silly "$@"
|
|
local arg1="$1"
|
|
local arg2="$2"
|
|
## cheers mailpile!
|
|
funneh=("do not think of purple hippos"
|
|
"increasing entropy & scrambling bits"
|
|
"indexing kittens..."
|
|
"patching bugs..."
|
|
"spinning violently around the y-axis"
|
|
"warming up particle accelerator"
|
|
"this server is powered by a lemon and two electrodes"
|
|
"becoming self-aware"
|
|
"BCC-ing ALL THE SPIES!"
|
|
"all of your config settings & passwords are encrypted with AES256"
|
|
"the most common password is 123456, hopefully yours is different"
|
|
"good things come to those who wait"
|
|
"Make Free Software and be happy"
|
|
"We like volcanos, do you like volcanos?"
|
|
"Crossing out swear words..."
|
|
"Informing David Cameron of suspicious ac^H^H^H ... naaah :)"
|
|
"Abandon all hope, ye who enter here"
|
|
"Compiling bullshit bingo grid..."
|
|
"Estimating chance of asteroid hitting Earth"
|
|
"Applying coupons..."
|
|
"Backing up the entire Internet..."
|
|
"Making you wait for no reason"
|
|
"Doing nothing"
|
|
"Pay no attention to the man behind the curtain"
|
|
"You are great just the way you are"
|
|
"Supplying monkeys with typewriters"
|
|
"Swapping time and space"
|
|
"Self potato"
|
|
"god is porco"
|
|
"A million hamsters are spinning their wheels right now"
|
|
)
|
|
local rnd=$(shuf -i1-$#funneh -n 1)
|
|
act "${funneh[$rnd]}" ; [[ $arg1 = sleep ]] && sleep $arg2
|
|
}
|