User:Jlo/Replacing Debian Jessie with Alpine remotely: Difference between revisions

From Alpine Linux
 
(14 intermediate revisions by the same user not shown)
Line 1: Line 1:
== Stage 1 ==
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...


something is wrong about init at reboot time :(
[[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
rsync -avzur my.server.home:debian/boot/* /boot/
# let's get system file from our install server
rsync -avzur my.server.home:debian/apks /boot/
cd /tmp
rsync -avzu my.server.home:debian/debian.apkovl.tar.gz /boot/
wget http://my.server.home/alpine/alpine-jessie-3.6.2-x86_64.iso
rsync -auv my.server.home:debian/.alpine-release /boot/
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 /boot/debian.apkovl.tar.gz -C /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 /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
unlink etc/runlevels/default/local
# 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/debian.apkovl.tar.gz .
# 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 ==
Line 47: Line 86:
not tested yet in this procedure but used successfully (a small variant) to prepare new AL boxes.  
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/sda* || (echo "Unable to umount sda. Aborting..." ; exit 1)
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
  mkdir -p /media/${D}$i/.wd
  chmod 777 /media/${D}$i/.wd
  chmod +t /media/${D}$i/.wd
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
echo "With great power comes great responsibility!" > etc/motd
# partition 2 will hold apkovl and apk/cache
mkdir -p etc/manufacture
date +%s > etc/manufacture/manufactured
date >> etc/manufacture/manufactured
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
### copy installed system to proxy partition
rsync -aur --numeric-ids /media/${D}1 /media/${D}5/ || 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