From 6d2ea3b7342187b1d5209f1d1efef79427471c80 Mon Sep 17 00:00:00 2001
From: =?utf8?q?Rapha=C3=ABl=20Gertz?= <git@rapsys.eu>
Date: Tue, 21 Jun 2016 14:23:30 +0200
Subject: [PATCH] Initial import

---
 .gitignore             |   4 ++
 config/distcook.conf   |   2 +
 config/imgnames.conf   |   3 +
 config/loop.conf       |   4 ++
 config/luks.conf       |   2 +
 config/mdnames.conf    |   6 ++
 config/mountpoint.conf |   2 +
 config/virtualbox.conf |   2 +
 genimg                 |  62 +++++++++++++++++++
 lib/boot.sh            |  58 ++++++++++++++++++
 lib/device.sh          | 105 ++++++++++++++++++++++++++++++++
 lib/export.sh          | 132 +++++++++++++++++++++++++++++++++++++++++
 lib/free.sh            |  17 ++++++
 lib/mkfs.sh            |  15 +++++
 lib/root.sh            |  14 +++++
 lib/sync.sh            |   8 +++
 16 files changed, 436 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 config/distcook.conf
 create mode 100644 config/imgnames.conf
 create mode 100644 config/loop.conf
 create mode 100644 config/luks.conf
 create mode 100644 config/mdnames.conf
 create mode 100644 config/mountpoint.conf
 create mode 100644 config/virtualbox.conf
 create mode 100755 genimg
 create mode 100644 lib/boot.sh
 create mode 100644 lib/device.sh
 create mode 100644 lib/export.sh
 create mode 100644 lib/free.sh
 create mode 100644 lib/mkfs.sh
 create mode 100644 lib/root.sh
 create mode 100644 lib/sync.sh

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7c13094
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+config/root.conf
+lib/config.sh
+root
+root.conf
diff --git a/config/distcook.conf b/config/distcook.conf
new file mode 100644
index 0000000..f2fefc3
--- /dev/null
+++ b/config/distcook.conf
@@ -0,0 +1,2 @@
+# Set here distcook path
+DISTCOOK='../distcook'
diff --git a/config/imgnames.conf b/config/imgnames.conf
new file mode 100644
index 0000000..728c15b
--- /dev/null
+++ b/config/imgnames.conf
@@ -0,0 +1,3 @@
+# sda img names
+SDA='root/sda.img'
+SDB='root/sdb.img'
diff --git a/config/loop.conf b/config/loop.conf
new file mode 100644
index 0000000..09aa460
--- /dev/null
+++ b/config/loop.conf
@@ -0,0 +1,4 @@
+# Loop A
+LOOPA='/dev/loop0'
+# Loop B
+LOOPB='/dev/loop1'
diff --git a/config/luks.conf b/config/luks.conf
new file mode 100644
index 0000000..b46c774
--- /dev/null
+++ b/config/luks.conf
@@ -0,0 +1,2 @@
+# Luks password (apg -m 32 -x 32 -a 0 -d -n 1)
+LUKSPASSWORD=`apg -m 32 -x 32 -a 0 -d -n 1`
diff --git a/config/mdnames.conf b/config/mdnames.conf
new file mode 100644
index 0000000..d22a708
--- /dev/null
+++ b/config/mdnames.conf
@@ -0,0 +1,6 @@
+# boot md names
+MDBOOT='mdboot'
+# slash md names
+MDSLASH='mdslash'
+# data md names
+MDDATA='mddata'
diff --git a/config/mountpoint.conf b/config/mountpoint.conf
new file mode 100644
index 0000000..d0def73
--- /dev/null
+++ b/config/mountpoint.conf
@@ -0,0 +1,2 @@
+# mount point
+MOUNTPOINT='/media/slash'
diff --git a/config/virtualbox.conf b/config/virtualbox.conf
new file mode 100644
index 0000000..d56e489
--- /dev/null
+++ b/config/virtualbox.conf
@@ -0,0 +1,2 @@
+# VirtualBox hard disk directory
+VBHDDIR='virtualbox'
diff --git a/genimg b/genimg
new file mode 100755
index 0000000..9091ac2
--- /dev/null
+++ b/genimg
@@ -0,0 +1,62 @@
+#! /bin/sh -xe
+
+# Export safe locale
+export LC_ALL=C
+
+# Get distcook path
+. config/distcook.conf
+
+# Copy distcook root config
+cp $DISTCOOK/root.conf config/
+
+# Extract configuration
+echo '#! /bin/sh -e' > lib/config.sh
+cat config/*.conf | perl -pne 'if (/^#/) {undef $_;} else {s/^/export /}' >> lib/config.sh
+
+# Source config
+. lib/config.sh
+
+# Test mapper entries
+if [ -f "/dev/mapper/$SLASHNAME" -o -f "/dev/mapper/$DATANAME" ]; then
+	echo "Mapper name already exists, try to run:"
+	echo "cryptsetup close $SLASHNAME"
+	echo "cryptsetup close $DATANAME"
+	exit 1
+fi
+
+# Test loopa and loopb
+if [ `losetup ${LOOPA} >/dev/null 2>&1; echo $?` -ne 1 -o `losetup ${LOOPB} >/dev/null 2>&1; echo $?` -ne 1 ]; then
+	echo "Loopa or loopb already exists, try to run:"
+	echo "mdadm -S /dev/md/$MDBOOT"
+	echo "mdadm -S /dev/md/$MDSLASH"
+	echo "mdadm -S /dev/md/$MDDATA"
+	echo "losetup -d ${LOOPA}"
+	echo "losetup -d ${LOOPB}"
+	exit 1
+fi
+
+# Create root dir
+if [ ! -d "$PWD/root" ]; then
+	mkdir "$PWD/root"
+fi
+
+# Device creation
+. lib/device.sh
+
+# Fs creation
+. lib/mkfs.sh
+
+# Setup root
+. lib/root.sh
+
+# Sync data
+. lib/sync.sh
+
+# Setup boot
+. lib/boot.sh
+
+# Free resources
+. lib/free.sh
+
+# Export config
+. lib/export.sh
diff --git a/lib/boot.sh b/lib/boot.sh
new file mode 100644
index 0000000..021a384
--- /dev/null
+++ b/lib/boot.sh
@@ -0,0 +1,58 @@
+#! /bin/sh -e
+
+# Bind mount /dev
+mount --bind /dev ${MOUNTPOINT}/dev
+
+# Backup old mtab
+mv ${MOUNTPOINT}/etc/mtab ${MOUNTPOINT}/etc/mtab.orig
+
+# Create new mtab
+#cat /proc/self/mounts | grep -E '^(/dev/m|devtmpfs)' | perl -pne 's%/media(/?)%$1%' | sort | uniq > /media/etc/mtab
+perl -pne "/^(devtmpfs \\/dev|\\/dev\\/(md|dm|mapper))/ || undef \$_; s%${MOUNTPOINT}/?%/%" /proc/self/mounts > ${MOUNTPOINT}/etc/mtab
+
+# Backup old device.map
+mv ${MOUNTPOINT}/boot/grub/device.map ${MOUNTPOINT}/boot/grub/device.map.orig
+
+# Install grub
+for i in $LOOPB $LOOPA; do
+	# Create new device map
+	echo "(hd0)	$i" > ${MOUNTPOINT}/boot/grub/device.map
+
+	# Fix grub
+	#XXX: e2fs_stage1_5 is 20 sectors embedded, but it fail with gpt
+	#XXX: we use install command directly instead of setup (hd0) because it fail with loop
+	cat << EOF | chroot ${MOUNTPOINT} grub --device-map=/boot/grub/device.map
+root (hd0,0)
+install --stage2=/boot/grub/stage2 /grub/stage1 (hd0) /grub/stage2 p /grub/menu.lst
+EOF
+done
+
+# Restore old device.map
+mv -f ${MOUNTPOINT}/boot/grub/device.map.orig ${MOUNTPOINT}/boot/grub/device.map
+
+# Bind mount /proc
+mount --bind /proc ${MOUNTPOINT}/proc
+
+# Bind mount /sys
+mount --bind /sys ${MOUNTPOINT}/sys
+
+# Extract last kernel version
+KVER=`chroot ${MOUNTPOINT} rpm -qa | perl -pne '/kernel-server-latest/||undef $_;s%^kernel-(server)-latest-([^-]+)-(.+)$%\2-\1-\3%'`
+# Regenerate initrd
+#XXX: force non hostonly else it don't store commandline : rd.luks.uuid rd.md.uuid ip=dhcp rd.neednet=1
+DRACUT_SKIP_FORCED_NON_HOSTONLY=1 chroot ${MOUNTPOINT} mkinitrd -f /boot/initrd-${KVER}.img ${KVER}
+
+# Umount dev
+umount ${MOUNTPOINT}/sys
+
+# Umount dev
+umount ${MOUNTPOINT}/proc
+
+# Umount dev
+umount ${MOUNTPOINT}/dev
+
+# Reset mtab
+mv -f ${MOUNTPOINT}/etc/mtab.orig ${MOUNTPOINT}/etc/mtab
+
+# Umount boot
+umount ${MOUNTPOINT}/boot
diff --git a/lib/device.sh b/lib/device.sh
new file mode 100644
index 0000000..1957287
--- /dev/null
+++ b/lib/device.sh
@@ -0,0 +1,105 @@
+#! /bin/sh -e
+
+#  Handle both devices
+for i in ${SDA} ${SDB}; do
+	# Create empty file of 8GB
+	dd if=/dev/zero of=${i} bs=$((8192*1024)) count=1024
+	# Create partition table
+	#XXX: we generate gpt table then fake mbr compat one
+	cat << EOF | fdisk ${i}
+g
+n
+1
+2048
++256M
+t
+29
+n
+2
+526336
++4G
+t
+2
+29
+n
+3
+8914944
++2G
+t
+3
+19
+n
+4
+13109248
+16777182
+t
+4
+29
+x
+A
+1
+M
+r
+d
+n
+p
+1
+2048
++256M
+t
+fd
+n
+p
+2
+526336
++4G
+t
+2
+fd
+n
+p
+3
+8914944
++2G
+t
+3
+82
+n
+p
+13109248
+16777182
+t
+4
+fd
+a
+1
+p
+x
+M
+r
+p
+w
+EOF
+	# Add it with partition scan
+	losetup -f -P ${i}
+done
+
+# Create raids
+mdadm --create /dev/md/${MDBOOT} --level=1 --metadata=0.90 --homehost=${NETHOSTNAME} --name=${MDBOOT} --assume-clean --raid-devices=2 ${LOOPA}p1 ${LOOPB}p1
+mdadm --create /dev/md/${MDSLASH} --level=1 --metadata=default --homehost=${NETHOSTNAME} --name=${MDSLASH} --assume-clean --raid-devices=2 ${LOOPA}p2 ${LOOPB}p2
+mdadm --create /dev/md/${MDDATA} --level=1 --metadata=default --homehost=${NETHOSTNAME} --name=${MDDATA} --assume-clean --raid-devices=2 ${LOOPA}p4 ${LOOPB}p4
+
+# Create slash luks partition
+#XXX: low iter time, should need around 100000 minimum
+echo -n $LUKSPASSWORD | cryptsetup -c aes-xts-plain64 -h sha512 -s 512 --iter-time 2000 --use-urandom --uuid ${LUKSSLASHUUID} -d - --batch-mode luksFormat /dev/md/${MDSLASH} 
+
+# Open luks partition
+echo -n $LUKSPASSWORD | cryptsetup -d - --batch-mode luksOpen /dev/md/${MDSLASH} ${SLASHNAME}
+
+# Create data luks partition
+#XXX: low iter time, should need around 100000 minimum
+echo -n $LUKSPASSWORD | cryptsetup -c aes-xts-plain64 -h sha512 -s 512 --iter-time 2000 --use-urandom --uuid ${LUKSDATAUUID} -d - --batch-mode luksFormat /dev/md/${MDDATA} 
+
+# Open luks partition
+echo -n $LUKSPASSWORD | cryptsetup -d - --batch-mode luksOpen /dev/md/${MDDATA} ${DATANAME}
+
diff --git a/lib/export.sh b/lib/export.sh
new file mode 100644
index 0000000..9e16189
--- /dev/null
+++ b/lib/export.sh
@@ -0,0 +1,132 @@
+#! /bin/sh -e
+
+# Clear config
+cat /dev/null > root.conf
+
+# Append every config parameters
+for i in `cat config/*.conf | perl -pne 'undef $_ if /^#/; s/=.*$//'`; do
+	echo "$i='$(eval echo \$$i)'" | tee -a root.conf
+done
+
+# Virtualbox doc
+cat << EOF > root/virtualbox
+# VirtualBox disk creation commands
+VBoxManage internalcommands createrawvmdk -filename '$VBHDDIR/sda.vmdk' -rawdisk '${PWD}/${SDA}'
+VBoxManage internalcommands createrawvmdk -filename '$VBHDDIR/sdb.vmdk' -rawdisk '${PWD}/${SDB}'
+
+Fix ownership of '${PWD}/${SDA}', '${PWD}/${SDB}', '${VBHDDIR}/sda.vmdk' and '${VBHDDIR}/sdb.vmdk' if you to use these as user
+
+# VirtualBox configuration
+Go in file/preferences.../network/host-only networks" >> root.virtualbox
+Add a new host-only networkd IPv4=${NETGATEWAY4}/IPv4 Mask=255.255.255.0/IPv6=${NETGATEWAY6}/IPv6 Mask=64/DHCP Server=disabled" >> root.virtualbox
+
+# Virtual Machine Configuration
+Create a new virtual machine : Type=Linux/Version=Mageia(${ARCH})/Do not add a virtual hard disk
+Open the settings of the virtual machine
+
+Section Storage
+In controller SATA click on add hard disk, select choose existing disk, sda.vmdk, same with sdb.vmdk
+
+Section Network
+Change 'Attached to' to 'Host-only adapter'
+Under advanced change MAC Address to ${NETMAC}
+EOF
+
+# Dhcpd.conf
+cat << EOF > root/dhcpd.conf
+# No ddns update
+ddns-update-style none;
+
+# Set domain name
+option domain-name "${NETHOSTNAME#*.}";
+
+# Set server name
+option domain-name-servers ${NETDNS/ /, };
+
+# Set least timings
+default-lease-time 600;
+max-lease-time 1050;
+
+# ${NETADDRESS4%.*}.0/${NETADDRESS4#*/} subnet
+subnet ${NETADDRESS4%.*}.0 netmask 255.255.255.0 {
+	# default gateway
+	option routers ${NETGATEWAY4};
+}
+
+host virtualbox {
+	hardware ethernet ${NETMAC};
+	fixed-address ${NETADDRESS4%/*};
+}
+EOF
+
+# Dhcpd6.conf
+cat << EOF > root/dhcpd6.conf
+# No ddns update
+ddns-update-style none;
+
+# Set least timings
+default-lease-time 600;
+max-lease-time 7200;
+
+# Enable RFC 5007 support (same than for DHCPv4)
+allow leasequery;
+
+# vboxnet0 shared network
+shared-network vboxnet0 {
+	# Set domain name
+	option domain-name "${NETHOSTNAME#*.}";
+
+	# Set server name
+#	option dhcp6.name-servers ${NETGATEWAY6};
+
+	# private ${NETADDRESS6%::*}::/${NETADDRESS6#*/} subnet
+	subnet6 ${NETADDRESS6%::*}::/${NETADDRESS6#*/} {
+		# Default range
+		range6 ${NETADDRESS6%::*}::2 ${NETADDRESS6%::*}::ffff:ffff;
+	}
+
+	# shared fe80::/64 subnet
+	subnet6 fe80::/64 {
+	}
+}
+
+host virtualbox {
+	# Client DUID
+	#XXX: only work for ipv4 : hardware ethernet ${NETMAC};
+	#XXX: see journalctl -u dhcpd6.service to get virtualbox machine DUID
+	host-identifier option dhcp6.client-id 00:00:00:00:00:00:00:00:00:00:00:00:00:00;
+	# Set address
+	fixed-address6 ${NETADDRESS6%/*};
+}
+EOF
+
+# Radvd.conf
+cat << EOF > root/radvd.conf
+# Radvd configuration
+interface vboxnet0
+{
+	# Announce at regular interval
+        AdvSendAdvert on;
+	# Start service even if vboxnet0 is missing
+	IgnoreIfMissing on;
+	# Force the configuration of client through dhcpv6
+	AdvManagedFlag on;
+	AdvOtherConfigFlag on;
+
+	prefix ${NETADDRESS6%::*}::/${NETADDRESS6#*/} {
+		# Announce that all address prefix are on-link
+		AdvOnLink on;
+		# Announce that the prefix can be used for autonomous address configuration
+		#XXX: off require a dhcpd6 configuration
+		AdvAutonomous off;
+		# Announce that the interface address is sent instead of network prefix
+		AdvRouterAddr off;
+	};
+
+	prefix ${NETGATEWAY6}/128 {
+		AdvOnLink on;
+		AdvAutonomous off;
+		AdvRouterAddr on;
+	};
+};
+EOF
diff --git a/lib/free.sh b/lib/free.sh
new file mode 100644
index 0000000..a01b368
--- /dev/null
+++ b/lib/free.sh
@@ -0,0 +1,17 @@
+#! /bin/sh -e
+
+# Umount slash
+umount ${MOUNTPOINT}
+
+# Close slash luks partition
+cryptsetup close ${SLASHNAME}
+cryptsetup close ${DATANAME}
+
+# Stop raids
+mdadm --manage /dev/md/${MDBOOT} -S
+mdadm --manage /dev/md/${MDSLASH} -S
+mdadm --manage /dev/md/${MDDATA} -S
+
+# Detach loops
+losetup -d ${LOOPA}
+losetup -d ${LOOPB}
diff --git a/lib/mkfs.sh b/lib/mkfs.sh
new file mode 100644
index 0000000..1ccc671
--- /dev/null
+++ b/lib/mkfs.sh
@@ -0,0 +1,15 @@
+#! /bin/sh -e
+
+# Create /boot on it
+#XXX: it seems it's not possible to boot from ext4 or xfs V5 with grub-legacy anymore
+mkfs.ext3 -L 'boot' -U ${BOOTUUID} /dev/md/${MDBOOT}
+
+# Create swap on it
+mkswap -U ${SWAPAUUID} ${LOOPA}p3
+mkswap -U ${SWAPBUUID} ${LOOPB}p3
+
+# Create filesystem
+mkfs.btrfs -L 'slash' -U ${SLASHUUID} /dev/mapper/${SLASHNAME}
+
+# Create filesystem
+mkfs.btrfs -L 'data' -U ${DATAUUID} /dev/mapper/${DATANAME}
diff --git a/lib/root.sh b/lib/root.sh
new file mode 100644
index 0000000..6f6af1e
--- /dev/null
+++ b/lib/root.sh
@@ -0,0 +1,14 @@
+#! /bin/sh -e
+
+# Make mount point
+mkdir -p ${MOUNTPOINT}
+
+# Mount slash filesystem
+mount /dev/mapper/${SLASHNAME} ${MOUNTPOINT}
+
+# Make boot in mount point
+mkdir -p ${MOUNTPOINT}/boot
+
+# Mount boot filesystem
+mount /dev/md/${MDBOOT} ${MOUNTPOINT}/boot
+
diff --git a/lib/sync.sh b/lib/sync.sh
new file mode 100644
index 0000000..1d1109d
--- /dev/null
+++ b/lib/sync.sh
@@ -0,0 +1,8 @@
+#! /bin/sh -e
+
+# Rsync files (removed P option)
+rsync --delete -aAX $DISTCOOK/root/ ${MOUNTPOINT}/
+
+# Fix by hand /var/log/journal
+#XXX: see warning about copy on write on btrfs filesystem
+chattr +C ${MOUNTPOINT}/var/log/journal
-- 
2.41.3