User:Jlo/Replacing Debian Jessie with Alpine remotely
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/ cp /mnt/.alpine-release /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 the install media was not already customized for own apps unlink etc/runlevels/default/local # 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