Remote conversion of 64-bit CentOS 6.5 to 64-bit Ubuntu 14.04

For 32-bit source to 64-bit see my older post.

Old install was using software RAID-1, but did not have LVM. Small 200MB /boot partition, 8GB swap and rest as one root partition. We're redoing it completely so what it used to be doesn't really matter. All existing data on root will be lost.

# Mark /dev/sda as failed
mdadm /dev/md0 --fail /dev/sda1
mdadm /dev/md1 --fail /dev/sda2
mdadm /dev/md2 --fail /dev/sda3

# Drop /dev/sda from RAID-1
mdadm /dev/md0 --remove /dev/sda1
mdadm /dev/md1 --remove /dev/sda2
mdadm /dev/md2 --remove /dev/sda3

# /dev/sda is now free and we can start setting up new install on it
# Install parted if not already there
yum -y install parted

# This is old server and small 250GB disks so we don't use EFI partitions
# 4GB boot, 32GB swap, rest as root - with mdraid of course
parted -s -a optimal /dev/sda \
       mklabel msdos \
       mkpart primary 4MiB 4GiB \
       set 1 raid on \
       set 1 boot on \
       mkpart primary 4GiB 36GiB \
       set 2 raid on \
       mkpart primary 36GiB 100% \
       set 3 raid on \
# Create mdraid in degraded mode
echo y|mdadm --create /dev/md101 --force --assume-clean --level=1  --raid-devices=2 \
             --homehost foobar --name=foobar_rp_boot --bitmap=internal \
             missing /dev/sda1
echo y|mdadm --create /dev/md102 --force --assume-clean --level=10 --raid-devices=2 \
             --homehost foobar --name=foobar_rp_swap --bitmap=internal \
             missing /dev/sda2
echo y|mdadm --create /dev/md103 --force --assume-clean --level=10 --raid-devices=2 \
             --homehost foobar --name=foobar_rp_root --bitmap=internal \
             missing /dev/sda3
# Create filesystems
mkfs.ext4 -L"foobar_boot" /dev/md101
mkswap -f -L"foobar_swap" /dev/md102
mkfs.ext4 -L"foobar_root" /dev/md103
# Next we get to debootstrap part to actually install something

# Mount new root + boot filesystems and prepare for debootstrap process
mkdir -p /newsys
mount /dev/md103 /newsys
mkdir -p /newsys/boot
mount /dev/md101 /newsys/boot

# Download and install Ubuntu keyring and debootstrap in case we're not running Ubuntu yet
mkdir -p /tmp/debootstrap
cd /tmp/debootstrap
# Check md5sum - cfa87364720b96e5ca15ef7b2cb4c948
md5sum ubuntu-keyring_2011.11.21.1.tar.gz
# If it matches unpack
tar xzf ubuntu-keyring_2011.11.21.1.tar.gz
# Check md5sum - 040f3afe15b2b6dd953df6eb2091562f
md5sum debootstrap_1.0.66_all.deb
# Unpack and install
ar -x debootstrap_1.0.66_all.deb
tar xzf data.tar.gz -C /

# Many packages required won't work if installad as part of debootstrap so we don't do so
debootstrap --keyring=/tmp/debootstrap/ubuntu-keyring-2011.11.21.1/keyrings/ubuntu-archive-keyring.gpg \
            --include=dosfstools --arch=amd64 trusty /newsys
# Mount proc, sysfs and dev required for next steps
mount -t proc   proc /newsys/proc
mount -t sysfs  sys  /newsys/sys
mount -o bind   /dev /newsys/dev
mount -t devpts pts  /newsys/dev/pts

# We need mtab, but copying /proc/mounts will cause problems so hack a bit..
cat /etc/mtab | grep /newsys | sed -e's|/newsys|/|g' -e's|//|/|g' > /newsys/etc/mtab
# chroot to new install to continue
LANG= chroot /newsys /bin/bash

# Create missing mdraid device links
mkdir -p /dev/md
ln -s /dev/md101 /dev/md/foobar_rp_boot
ln -s /dev/md102 /dev/md/foobar_rp_swap
ln -s /dev/md103 /dev/md/foobar_rp_root

# Create fstab for our new install
echo "UUID=$(blkid -t LABEL=foobar_root -s UUID -o value) / ext4 defaults,noatime,discard,errors=remount-ro 0 1" >/etc/fstab
echo "UUID=$(blkid -t LABEL=foobar_boot -s UUID -o value) /boot ext4 defaults,noatime,discard,nobootwait,nofail 0 2" >>/etc/fstab
echo "UUID=$(blkid -t LABEL=foobar_swap -s UUID -o value) swap swap defaults,discard 0 2" >>/etc/fstab
# Set hostname
echo "foobar" >/etc/hostname

# Also update hosts file to prevent warnings from sudo etc.
cat<<'__EOF__'>/etc/hosts localhost foobar

::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

# Setup static IP for network
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static

# DNS too
options timeout:2 attempts:2 rotate
# Ugly hack to prevent launching of services while setting up system with apt-get
mkdir -p /tmp/fakestart
ln -s /bin/true /tmp/fakestart/initctl
ln -s /bin/true /tmp/fakestart/invoke-rc.d
ln -s /bin/true /tmp/fakestart/restart
ln -s /bin/true /tmp/fakestart/start
ln -s /bin/true /tmp/fakestart/stop
ln -s /bin/true /tmp/fakestart/start-stop-daemon
ln -s /bin/true /tmp/fakestart/service
export PATH=/tmp/fakestart:$PATH
# Enable full repositories, we need for example dropbear not included in main repos
cat <<'__EOF__'>/etc/apt/sources.list
deb trusty main restricted
deb-src trusty main restricted
deb trusty-updates main restricted
deb-src trusty-updates main restricted
deb trusty universe
deb-src trusty universe
deb trusty-updates universe
deb-src trusty-updates universe
deb trusty multiverse
deb-src trusty multiverse
deb trusty-updates multiverse
deb-src trusty-updates multiverse
deb trusty-backports main restricted universe multiverse
deb-src trusty-backports main restricted universe multiverse
deb trusty-security main restricted
deb-src trusty-security main restricted
deb trusty-security universe
deb-src trusty-security universe
deb trusty-security multiverse
deb-src trusty-security multiverse

# Prevent apt-get from asking silly questions
export DEBIAN_FRONTEND=noninteractive

# Fix DNS resolution issues for good by removing root cause
# This package is stubborn and can't be excluded during deboostrap
apt-get -y remove resolvconf

# Install some more or less mandatory packages
apt-get update
apt-get --no-install-recommends -y install openssh-server mdadm locales gdisk parted nano \
        linux-image-generic grub-pc-bin grub2-common
# Set root password
passwd root

# Allow root over ssh because we're professionals
sed -i.bak -e's/.*PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config
# Zap partitions on /dev/sdb so it doesn't cause issues on next boot
# This will give error because there's active mdraid on sdb, but don't worry
sgdisk -Z /dev/sdb

# Create devicemap for grub (/boot/grub/
mkdir -p /boot/grub
grub-mkdevicemap -nvv

# Install grub boot sector to both disks
# This will prevent old os from booting but otherwise there's 
# risk of bios picking wrong disk to boot from
grub-install --target=i386-pc /dev/sda
grub-install --target=i386-pc /dev/sdb

# Silent boot is nonsense causing nothing but trouble
# This will change kernel parameters to be more verbose, try to allow boot with degraded RAID,
# and also enables on-the-fly compression for swap
# I have feeling that some of these are no longer valid parameters (if they ever were) due
# constant battle between developers breaking things and users trying to find workarounds to 
# those unwanted changes...
sed -i.bak -e's|^GRUB_CMDLINE_LINUX_DEFAULT=.*|GRUB_CMDLINE_LINUX_DEFAULT="verbose bootdegraded=true bootwait=5 zswap.enabled=1 zswap.compressor=lz4"|g' \
           -e's|^GRUB_HIDDEN_|#GRUB_HIDDEN_|g' /etc/default/grub
# Workaround for diskfilter write error with GRUB and mdraid
sed -i -e's|^quiet_boot="1"|quiet_boot="0"|g' -e's|^quick_boot="1"|quick_boot="0"|g' /etc/grub.d/10_linux
# More fixes
# Ubuntu initramfs is not able to handle degraded RAID arrays. I'm aware of all sorts
# of "magic" parameters one can set but if you look inside what initramfs scripts do
# they don't even check for those settings or try to do anything smart when there's error.
# What we do below is force arrays online even if some disks are missing. It's far better
# to bring system up in such case and let admin sort it out. Other option is dropping
# to initramfs shell and taking all down for good. Morons...
# As usual one more hack. Not that it should do anything bad because md arrays can't be
# taken down if they already came up ok. If they didn't by time this script is run
# it's game over without this.
cat >/usr/share/initramfs-tools/scripts/init-premount/zzmdraidtryharder <<'__EOF__'
prereqs() {
        echo "$PREREQ"
case "$1" in
                exit 0
. /scripts/functions

sleep 15
echo ""
echo ""
echo "Before fix mdraid status from /proc/mdstat"
cat /proc/mdstat
echo ""
echo "Force-starting arrays with missing or unsynced disks (if any)"
echo ""
mdadm --misc --run /dev/md*
echo ""
echo "After fix mdraid status from /proc/mdstat"
cat /proc/mdstat
echo ""
sleep 5

# Make it executable
chmod a+x /usr/share/initramfs-tools/scripts/init-premount/zzmdraidtryharder

# Rebuild initramdisk so it includes our mdraid fix
update-initramfs -c -k all
# Update grub.cfg

# Exit chroot and reboot
# Prevent apt-get from asking silly questions
export DEBIAN_FRONTEND=noninteractive

# Update distro, install common tools and some extra packages
apt-get update
apt-get -y dist-upgrade
apt-get -y install ubuntu-standard joe wget curl screen python perl mtr traceroute \
                   language-pack-en fail2ban boot-info-script i7z sysstat \
                   build-essential python-software-properties software-properties-common \
                   linux-source linux-headers-generic smartmontools ntp lftp
# Set locale
update-locale LANG=en_US.UTF-8 LANGUAGE=en_US

# Set timezone
cp -f /usr/share/zoneinfo/Europe/Helsinki /etc/localtime
echo "Europe/Helsinki" >/etc/timezone

# Set keyboard layout
sed -i.bak -e's|^XKBLAYOUT=.*|XKBLAYOUT="fi"|g' /etc/default/keyboard
dpkg-reconfigure keyboard-configuration
dpkg-reconfigure console-setup
# Create regular user account, allow sudo, set password
adduser viidakongeorge --shell /bin/bash --disabled-password --gecos viidakongeorge
usermod -a -G sudo viidakongeorge
passwd viidakongeorge
# Always prefer IPv4 over IPv6 due suboptimal IPv6 routing and peering
echo "precedence ::ffff:0:0/96  100" >>/etc/gai.conf
# We still need to add our second disk as part of mirror

# Partitions
parted -s -a optimal /dev/sdb \
       mklabel msdos \
       mkpart primary 4MiB 4GiB \
       set 1 raid on \
       set 1 boot on \
       mkpart primary 4GiB 36GiB \
       set 2 raid on \
       mkpart primary 36GiB 100% \
       set 3 raid on \
# RAID, we can use labels now
mdadm --manage /dev/md/foobar_rp_boot --add /dev/sdb1
mdadm --manage /dev/md/foobar_rp_swap --add /dev/sdb2
mdadm --manage /dev/md/foobar_rp_root --add /dev/sdb3
# Make sure grub is happy with all that has been changed

# Create devicemap for grub (/boot/grub/
mkdir -p /boot/grub
grub-mkdevicemap -nvv

# Install grub boot sector to both disks
grub-install --target=i386-pc /dev/sda
grub-install --target=i386-pc /dev/sdb

# Rebuild initramdisk
update-initramfs -c -k all

# Update grub.cfg

# Reboot to be sure everything works in future as well