@@ -6,6 +6,9 @@ set -eux -o pipefail
66# Restrict the rest of this script to Alpine until it has been tested with other distros
77test -f /etc/alpine-release || exit 0
88
9+ # Nothing to do unless we are running from a ramdisk
10+ [ " $( awk ' $2 == "/" {print $3}' /proc/mounts) " != " tmpfs" ] && exit 0
11+
912# Data directories that should be persisted across reboots
1013DATADIRS=" /etc /home /root /tmp /usr/local /var/lib"
1114
@@ -39,82 +42,78 @@ for DIR in ${DATADIRS}; do
3942done
4043chmod +x /mnt.sh
4144
42- # When running from RAM try to move persistent data to data-volume
43- # FIXME: the test for tmpfs mounts is probably Alpine-specific
44- if [ " $( awk ' $2 == "/" {print $3}' /proc/mounts) " == " tmpfs" ]; then
45- mkdir -p /mnt/data
46- if [ -e /dev/disk/by-label/data-volume ]; then
47- # Find which disk is data volume on
48- DATA_DISK=$( blkid | grep " data-volume" | awk ' {split($0,s,":"); sub(/\d$/, "", s[1]); print s[1]};' )
49- # growpart command may be missing in older VMs
50- if command -v growpart > /dev/null 2>&1 && command -v resize2fs > /dev/null 2>&1 ; then
51- # Automatically expand the data volume filesystem
52- growpart " $DATA_DISK " 1 || true
53- # Only resize when filesystem is in a healthy state
54- if e2fsck -f -p /dev/disk/by-label/data-volume; then
55- resize2fs /dev/disk/by-label/data-volume || true
56- fi
57- fi
58- # Mount data volume
59- mount -t ext4 /dev/disk/by-label/data-volume /mnt/data
60- # Update /etc files that might have changed during this boot
61- cp /etc/network/interfaces /mnt/data/etc/network/
62- cp /etc/resolv.conf /mnt/data/etc/
63- if [ -f /etc/localtime ]; then
64- # Preserve symlink
65- cp -d /etc/localtime /mnt/data/etc/
66- # setup-timezone copies the single zoneinfo file into /etc/zoneinfo and targets the symlink there
67- if [ -d /etc/zoneinfo ]; then
68- rm -rf /mnt/data/etc/zoneinfo
69- cp -r /etc/zoneinfo /mnt/data/etc
70- fi
45+ mkdir -p /mnt/data
46+ if [ -e /dev/disk/by-label/data-volume ]; then
47+ # Find which disk is data volume on
48+ DATA_DISK=$( blkid | grep " data-volume" | awk ' {split($0,s,":"); sub(/\d$/, "", s[1]); print s[1]};' )
49+ # growpart command may be missing in older VMs
50+ if command -v growpart > /dev/null 2>&1 && command -v resize2fs > /dev/null 2>&1 ; then
51+ # Automatically expand the data volume filesystem
52+ growpart " $DATA_DISK " 1 || true
53+ # Only resize when filesystem is in a healthy state
54+ if e2fsck -f -p /dev/disk/by-label/data-volume; then
55+ resize2fs /dev/disk/by-label/data-volume || true
7156 fi
72- if [ -f /etc/timezone ]; then
73- cp /etc/timezone /mnt/data/etc/
57+ fi
58+ # Mount data volume
59+ mount -t ext4 /dev/disk/by-label/data-volume /mnt/data
60+ # Update /etc files that might have changed during this boot
61+ cp /etc/network/interfaces /mnt/data/etc/network/
62+ cp /etc/resolv.conf /mnt/data/etc/
63+ if [ -f /etc/localtime ]; then
64+ # Preserve symlink
65+ cp -d /etc/localtime /mnt/data/etc/
66+ # setup-timezone copies the single zoneinfo file into /etc/zoneinfo and targets the symlink there
67+ if [ -d /etc/zoneinfo ]; then
68+ rm -rf /mnt/data/etc/zoneinfo
69+ cp -r /etc/zoneinfo /mnt/data/etc
7470 fi
75- # TODO there are probably others that should be updated as well
76- else
77- # Find an unpartitioned disk and create data-volume
78- DISKS=$( lsblk --list --noheadings --output name,type | awk ' $2 == "disk" {print $1}' )
79- for DISK in ${DISKS} ; do
80- IN_USE=false
81- # Looking for a disk that is not mounted or partitioned
82- # shellcheck disable=SC2013
83- for PART in $( awk ' /^\/dev\// {gsub("/dev/", ""); print $1}' /proc/mounts) ; do
84- if [ " ${DISK} " == " ${PART} " ] || [ -e /sys/block/" ${DISK} " /" ${PART} " ]; then
85- IN_USE=true
86- break
87- fi
88- done
89- if [ " ${IN_USE} " == " false" ]; then
90- echo ' type=83' | sfdisk --label dos /dev/" ${DISK} "
91- PART=$( lsblk --list /dev/" ${DISK} " --noheadings --output name,type | awk ' $2 == "part" {print $1}' )
92- mkfs.ext4 -L data-volume /dev/" ${PART} "
93- mount -t ext4 /dev/disk/by-label/data-volume /mnt/data
94- # setup apk package cache
95- mkdir -p /mnt/data/apk/cache
96- mkdir -p /etc/apk
97- ln -s /mnt/data/apk/cache /etc/apk/cache
98- # Move all persisted directories to the data volume
99- for DIR in ${DATADIRS} ; do
100- DEST=" /mnt/data$( dirname " ${DIR} " ) "
101- mkdir -p " ${DIR} " " ${DEST} "
102- mv " ${DIR} " " ${DEST} "
103- done
104- # Make sure all data moved to the persistent volume has been committed to disk
105- sync
71+ fi
72+ if [ -f /etc/timezone ]; then
73+ cp /etc/timezone /mnt/data/etc/
74+ fi
75+ # TODO there are probably others that should be updated as well
76+ else
77+ # Find an unpartitioned disk and create data-volume
78+ DISKS=$( lsblk --list --noheadings --output name,type | awk ' $2 == "disk" {print $1}' )
79+ for DISK in ${DISKS} ; do
80+ IN_USE=false
81+ # Looking for a disk that is not mounted or partitioned
82+ # shellcheck disable=SC2013
83+ for PART in $( awk ' /^\/dev\// {gsub("/dev/", ""); print $1}' /proc/mounts) ; do
84+ if [ " ${DISK} " == " ${PART} " ] || [ -e /sys/block/" ${DISK} " /" ${PART} " ]; then
85+ IN_USE=true
10686 break
10787 fi
10888 done
109- fi
110- for DIR in ${DATADIRS} ; do
111- if [ -d /mnt/data" ${DIR} " ]; then
112- mkdir -p " ${DIR} "
113- mount --bind /mnt/data" ${DIR} " " ${DIR} "
89+ if [ " ${IN_USE} " == " false" ]; then
90+ echo ' type=83' | sfdisk --label dos /dev/" ${DISK} "
91+ PART=$( lsblk --list /dev/" ${DISK} " --noheadings --output name,type | awk ' $2 == "part" {print $1}' )
92+ mkfs.ext4 -L data-volume /dev/" ${PART} "
93+ mount -t ext4 /dev/disk/by-label/data-volume /mnt/data
94+ # setup apk package cache
95+ mkdir -p /mnt/data/apk/cache
96+ mkdir -p /etc/apk
97+ ln -s /mnt/data/apk/cache /etc/apk/cache
98+ # Move all persisted directories to the data volume
99+ for DIR in ${DATADIRS} ; do
100+ DEST=" /mnt/data$( dirname " ${DIR} " ) "
101+ mkdir -p " ${DIR} " " ${DEST} "
102+ mv " ${DIR} " " ${DEST} "
103+ done
104+ # Make sure all data moved to the persistent volume has been committed to disk
105+ sync
106+ break
114107 fi
115108 done
116- # Remount submounts on top of the new ${DIR}
117- /mnt.sh
118- # Reinstall packages from /mnt/data/apk/cache into the RAM disk
119- apk fix --no-network
120109fi
110+ for DIR in ${DATADIRS} ; do
111+ if [ -d /mnt/data" ${DIR} " ]; then
112+ mkdir -p " ${DIR} "
113+ mount --bind /mnt/data" ${DIR} " " ${DIR} "
114+ fi
115+ done
116+ # Remount submounts on top of the new ${DIR}
117+ /mnt.sh
118+ # Reinstall packages from /mnt/data/apk/cache into the RAM disk
119+ apk fix --no-network
0 commit comments