User:Jlo/Replacing Debian Jessie with Alpine remotely

From Alpine Linux
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

I want to "upgrade" 200 remote Debian Jessie embedded boxes to AlpineLinux in run-from-ram mode. I have already successfully and happily validated the second stage as this is a minor variation around the "setup-ownbox" script I have added to a standard PXE apkovl. Those box are remotely sshable via openVPN. We need to keep network settings as is because some boxes have ad-hoc network config is restricted zones.

Stage 0

we need to prepare or a cache with reduced set of package or maybe some local repo with all needed packages needed for first stage and use that repo with no-cache option...

How_to_make_a_custom_ISO_image_with_mkimage

sh mkimage.sh --tag 3.6.2 --outdir ~/iso --arch x86_64 --repository http://my.own.repo/alpine/v3.6/main --profile jessie
profile_jessie() {
	profile_standard
	title="AL debian"
	desc="Packages included.
		Suitable for Local install script."
	apks="$apks openvpn wpa_supplicant wireless-tools"
	#apks="$apks linux-firmware"
}

==> alpine-jessie-3.6.2-x86_64.iso

Stage 1

prepare-jessie-for-alpine

#!/bin/sh
# this must be fully automatic
export DEBIAN_FRONTEND=noninteractive
apt-get -y install rsync extlinux
# /boot is a separate partition
rm -fr /boot/boot
ln -sf . /boot/boot
# let's get system file from our install server
cd /tmp
wget http://my.server.home/alpine/alpine-jessie-3.6.2-x86_64.iso
wget http://my.server.home/alpine/debian.apkovl.tar.gz
mount -o loop /tmp/alpine-jessie-3.6.2-x86_64.iso /mnt
rsync -a /mnt/ /boot/
sync 
umount /mnt
# prepare the config overlay
rm -fr /tmp/apkovl
mkdir /tmp/apkovl
tar xzf /tmp/debian.apkovl.tar.gz -C /tmp/apkovl
# keep current active network connection(s) and identity
cp /etc/hostname /tmp/apkovl/etc/
cp /etc/network/interfaces  /tmp/apkovl/etc/network/
cp -r /etc/openvpn /tmp/apkovl/etc/
cp -r /etc/ssh /tmp/apkovl/etc/
cd /tmp/apkovl
# be sure active VPN connections are preserved
mkdir -p /tmp/apkovl/etc/init.d
for v in /tmp/apkovl/etc/openvpn/*.conf ; do
  vn=$(basename $v|cut -d. -f1)
  ln -fs openvpn /tmp/apkovl/etc/init.d/openvpn.$vn
  ln -fs /etc/init.d/openvpn.$vn /tmp/apkovl/etc/runlevels/default/openvpn.$vn
done
# config done ; commit
tar czf /boot/$(hostname).apkovl.tar.gz .
# now the booltoader ; this will kill the active grub...
cat > /boot/extlinux.conf << EOF
timeout 20
prompt 1
default hardened
label hardened
    kernel /boot/vmlinuz-hardened
    initrd /boot/initramfs-hardened
    append alpine_dev=sda1:ext2 modloop=modloop-hardened modules=loop,cramfs,sd-mod,usb-storage,ext2 quiet
EOF
dd if=/usr/lib/syslinux/mbr/mbr.bin of=/dev/sda
extlinux -i /boot
# done
sync
reboot

usage:

~:# prepare-jessie-for-alpine

Stage 2

not tested yet in this procedure but used successfully (a small variant) to prepare new AL boxes.

setup-albox-from-debian

#!/bin/sh
BEGIN=$(date +%s)
name=$1
D=sda
echo "Manufacturing box named *${name}*..." 
rc-service modloop stop
umount /media/${D}* || (echo "Unable to unmount ${D}. Aborting..." ; exit 1)
### Partition the SSD $D
# f2fs want partition of type ext2 in parted
parted -a cylinder -s /dev/${D} -- \
 mklabel msdos                \
 mkpart primary fat32 0%  1%  \
 mkpart primary ext2  1%  2%  \
 mkpart primary ext2  2%  7%  \
 mkpart extended      7% 100% \
 mkpart logical ext2  7%  9%  \
 mkpart logical ext2  9% 15%  \
 mkpart logical ext2 15% 20%  \
 mkpart logical ext2 21% 22%  \
 mkpart logical ext2 22% 23%  \
 mkpart logical ext2 23% 24%  \
 mkpart logical ext2 24% 25%  \
 mkpart logical ext2 25% 26%  \
 mkpart logical ext2 26% 27%  \
 mkpart logical ext2 27% 28%  \
 mkpart logical ext2 28% 29%  \
 mkpart logical ext2 29% 30%  \
 set 1 boot on                \
 || exit 1
### prepare boot partition
mkfs.vfat /dev/${D}1 || exit 1
mkdir -p /media/${D}1
setup-bootable /media/${B} /dev/${D}1 || exit 1
mount -t vfat /dev/${D}1 /media/${D}1 || exit 1
### format partition to hold apkovl and apk/cache; it must be of ext? type
mkfs.ext4 -F -q /dev/${D}2 || exit 1
mkdir -p /media/${D}2
mount -t ext4 /dev/${D}2 /media/${D}2 || exit 1
### format remaining partitions with f2fs
for i in $(seq 3 16);do
  [ $i -eq 4 ] && continue
  mkfs.f2fs -q /dev/${D}$i || exit 1
  mkdir -p /media/${D}$i
  mount -t f2fs /dev/${D}$i /media/${D}$i || exit 1
done
### copy apkovl and apk/cache and stuff
rsync -azur --numeric-ids root@my.server.home:sda* /media/ || exit 1
### prepare new apkovl
rm -fr /tmp/template
mkdir -p /tmp/template
tar xzf /media/${S}2/$(hostname).apkovl.tar.gz -C /tmp/template || exit 1
rm /media/${D}2/$(hostname).apkovl.tar.gz
cd /tmp/template
rm -f etc/ssh/ssh_host_*
for f in $(grep -r $(hostname) etc 2> /dev/null | cut -d: -f1|sort -u);do sed -i -e s/$(hostname)/${name}/g $f;done
for f in $(grep -r ${S} etc 2> /dev/null | cut -d: -f1|sort -u);do sed -i -e s/${S}/${D}/g $f;done
echo "/dev/sdb2 /media/sdb2 ext4 ro,relatime,errors=continue,user_xattr,acl 0 2" > etc/fstab
# remaining partitions are for own stuff
# partition 4 is the extended one 
# (we maybe could just skip 3 and directly jump to extended for own stuff to simplify install script)
echo "/dev/sda3 /media/sda3 f2fs defaults,ro 0 2" >> etc/fstab
for i in $(seq 5 16);do echo "/dev/sda$i /media/sda$i f2fs defaults 0 2" >> etc/fstab;done
# partition 2 will hold apkovl and apk/cache
rm etc/apk/cache
ln -s /media/${D}2/cache etc/apk/cache
ln -s /etc/init.d/local etc/runlevels/default/local
tar czf /media/${D}2/${name}.apkovl.tar.gz . || exit 1
### done
sync
umount /media/${D}*
END=$(date +%s)
DURATION=$(($END-$BEGIN))
echo "Manufacture process took $DURATION seconds to complete." 
logger "Manufacture process took $DURATION seconds to complete." 
reboot

Usage:

~:# setup-albox-from-debian mynewbox