User:Jlo/Replacing Debian Jessie with Alpine remotely: Difference between revisions
m (→Stage 2) |
m (→Stage 1) |
||
(15 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
== Stage | 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]] | |||
<pre> | <pre> | ||
sh mkimage.sh --tag 3.6.2 --outdir ~/iso --arch x86_64 --repository http://my.own.repo/alpine/v3.6/main --profile jessie | |||
</pre> | |||
<pre> | |||
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" | |||
} | |||
</pre> | |||
==> '''alpine-jessie-3.6.2-x86_64.iso''' | |||
== Stage 1 == | |||
<u>prepare-jessie-for-alpine</u> <pre> | |||
#!/bin/sh | #!/bin/sh | ||
# this must be fully automatic | |||
export DEBIAN_FRONTEND=noninteractive | export DEBIAN_FRONTEND=noninteractive | ||
apt-get -y install rsync extlinux | apt-get -y install rsync extlinux | ||
# /boot is a separate partition | |||
rm -fr /boot/boot | rm -fr /boot/boot | ||
ln -sf . /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 | rm -fr /tmp/apkovl | ||
mkdir /tmp/apkovl | mkdir /tmp/apkovl | ||
tar xzf / | 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 /etc/network/interfaces /tmp/apkovl/etc/network/ | ||
cp -r /etc/openvpn /tmp/apkovl/etc/ | cp -r /etc/openvpn /tmp/apkovl/etc/ | ||
cp -r /etc/ssh /tmp/apkovl/etc/ | cp -r /etc/ssh /tmp/apkovl/etc/ | ||
cd /tmp/apkovl | cd /tmp/apkovl | ||
# be sure active VPN connections are preserved | |||
mkdir -p /tmp/apkovl/etc/init.d | mkdir -p /tmp/apkovl/etc/init.d | ||
for v in /tmp/apkovl/etc/openvpn/*.conf ; do | for v in /tmp/apkovl/etc/openvpn/*.conf ; do | ||
Line 27: | Line 61: | ||
ln -fs /etc/init.d/openvpn.$vn /tmp/apkovl/etc/runlevels/default/openvpn.$vn | ln -fs /etc/init.d/openvpn.$vn /tmp/apkovl/etc/runlevels/default/openvpn.$vn | ||
done | done | ||
tar czf /boot/ | # config done ; commit | ||
tar czf /boot/$(hostname).apkovl.tar.gz . | |||
# now the booltoader ; this will kill the active grub... | |||
cat > /boot/extlinux.conf << EOF | cat > /boot/extlinux.conf << EOF | ||
timeout 20 | timeout 20 | ||
Line 39: | Line 75: | ||
dd if=/usr/lib/syslinux/mbr/mbr.bin of=/dev/sda | dd if=/usr/lib/syslinux/mbr/mbr.bin of=/dev/sda | ||
extlinux -i /boot | extlinux -i /boot | ||
# done | |||
sync | sync | ||
reboot | reboot | ||
</pre> | </pre> | ||
usage: <pre>~:# prepare-jessie-for-alpine</pre> | |||
== Stage 2 == | == Stage 2 == | ||
not tested yet | not tested yet in this procedure but used successfully (a small variant) to prepare new AL boxes. | ||
<pre> | <u>setup-albox-from-debian</u> <pre> | ||
#!/bin/sh | #!/bin/sh | ||
BEGIN=$(date +%s) | BEGIN=$(date +%s) | ||
Line 54: | Line 93: | ||
echo "Manufacturing box named *${name}*..." | echo "Manufacturing box named *${name}*..." | ||
rc-service modloop stop | rc-service modloop stop | ||
umount /media/ | umount /media/${D}* || (echo "Unable to unmount ${D}. Aborting..." ; exit 1) | ||
### Partition the SSD $D | ### Partition the SSD $D | ||
# f2fs want partition of type ext2 in parted | |||
parted -a cylinder -s /dev/${D} -- \ | parted -a cylinder -s /dev/${D} -- \ | ||
mklabel msdos \ | mklabel msdos \ | ||
Line 91: | Line 131: | ||
mkdir -p /media/${D}$i | mkdir -p /media/${D}$i | ||
mount -t f2fs /dev/${D}$i /media/${D}$i || exit 1 | mount -t f2fs /dev/${D}$i /media/${D}$i || exit 1 | ||
done | done | ||
### copy apkovl and apk/cache and stuff | ### copy apkovl and apk/cache and stuff | ||
Line 107: | Line 144: | ||
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 | 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 | 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 | 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 | 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 | rm etc/apk/cache | ||
ln -s /media/${D}2/cache etc/apk/cache | ln -s /media/${D}2/cache etc/apk/cache | ||
ln -s /etc/init.d/local etc/runlevels/default/local | ln -s /etc/init.d/local etc/runlevels/default/local | ||
tar czf /media/${D}2/${name}.apkovl.tar.gz . || exit 1 | tar czf /media/${D}2/${name}.apkovl.tar.gz . || exit 1 | ||
### done | ### done | ||
sync | sync | ||
Line 128: | Line 163: | ||
reboot | reboot | ||
</pre> | </pre> | ||
Usage: <pre>~:# setup-albox-from-debian mynewbox</pre> |
Latest revision as of 15:04, 8 November 2017
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