forked from adafruit/Adafruit-Pi-ExternalRoot-Helper
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathadafruit-pi-externalroot-helper
More file actions
executable file
·147 lines (123 loc) · 4.61 KB
/
Copy pathadafruit-pi-externalroot-helper
File metadata and controls
executable file
·147 lines (123 loc) · 4.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env bash
# adafruit-pi-externalroot-helper
#
# Configure a Raspbian system to use an external USB drive as root filesystem.
#
# See README.md for details and sources.
set -e
function print_version() {
echo "Adafruit Pi External Root Helper v0.1.0"
exit 1
}
function print_help() {
echo "Usage: $0 -d [target device]"
echo " -h Print this help"
echo " -v Print version information"
echo " -d [device] Specify path of device to convert to root"
echo
echo "You must specify a device. See:"
echo "https://learn.adafruit.com/external-drive-as-raspberry-pi-root"
exit 1
}
# Display an error message and quit:
function bail() {
FG="1;31m"
BG="40m"
echo -en "[\033[${FG}\033[${BG}error\033[0m] "
echo "$*"
exit 1
}
# Display an info message:
function info() {
task="$1"
shift
FG="1;32m"
BG="40m"
echo -e "[\033[${FG}\033[${BG}${task}\033[0m] $*"
}
if [[ $EUID -ne 0 ]]; then
bail "must be run as root. try: sudo adafruit-pi-externalroot-helper"
fi
# Handle arguments:
args=$(getopt -uo 'hvd:' -- $*)
[ $? != 0 ] && print_help
set -- $args
for i
do
case "$i"
in
-h)
print_help
;;
-v)
print_version
;;
-d)
target_drive="$2"
echo "Target drive = ${2}"
shift
shift
;;
esac
done
if [[ ! -e "$target_drive" ]]; then
bail "Target ${target_drive} must be existing device (use -d /dev/foo to specify)"
fi
info "start" "Will create new ext4 filesystem on ${target_drive}"
info "start" "If there is data on ${target_drive}, it will be lost."
read -p "Really proceed? (y)es / (n)o " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
echo "Quitting."
exit
fi
export target_partition="${target_drive}1"
info "dependencies" "Installing gdisk, rsync, and parted."
# All except gdisk are probably installed, but let's make sure.
apt-get install gdisk rsync parted
info "fs create" "Creating ${target_partition}"
# The alternative here seems to be to pipe a series of commands
# to fdisk(1), similar to how it's done by raspi-config:
# https://github.com/asb/raspi-config/blob/3a5d75340a1f9fe5d7eebfb28fee0e24033f4fd3/raspi-config#L68
# This seemed to work, but I was running into weirdness because
# that doesn't seem to make a GPT, and later on I couldn't get
# partition unique GUID from gdisk. parted(1) is also a nice
# option because it's scriptable and allows partition sizes to
# be specified in percentages.
parted --script "${target_drive}" mklabel gpt
parted --script --align optimal "${target_drive}" mkpart primary ext4 0% 100%
info "fs create" "Creating ext4 filesystem on ${target_partition}"
sleep 5
mkfs -t ext4 -L rootfs "${target_partition}"
info "fs id" "Getting UUID for target partition"
eval `blkid -o export "${target_partition}"`
export target_partition_uuid=$UUID
info "fs id" "Getting Partition unique PARTUUID for target filesystem"
#This value is also part of the blkid info
export partition_unique_partuuid=$PARTUUID
info "fs id" "Target partition UUID: ${target_partition_uuid}"
info "fs id" "Partition unique PARTUUID: ${partition_unique_partuuid}"
info "fs copy" "Mounting ${target_partition} on /mnt"
mount "${target_partition}" /mnt
info "fs copy" "Copying root filesystem to ${target_partition} with rsync"
info "fs copy" "This will take quite a while. Please be patient!"
rsync -ax / /mnt
info "boot config" "Configuring boot from {$target_partition}"
#rootwait is already in the file and is sufficient
cp /boot/cmdline.txt /boot/cmdline.txt.bak
sed -i "s|root=PARTUUID=\S\+ |root=PARTUUID=${partition_unique_partuuid} |g" /boot/cmdline.txt
info "boot config" "Commenting out old root partition in /etc/fstab, adding new one"
# These changes are made on the new drive after copying so that they
# don't have to be undone in order to switch back to booting from the
# SD card.
#comment out old root entry from fstab (this approach respects previous comments)
sed -i -E 's|(^[^\#]*\s\/\s[^\#]*)|#\1|g' /mnt/etc/fstab
#add new root entry
echo "PARTUUID=${partition_unique_partuuid} / ext4 defaults,noatime 0 1" >> /mnt/etc/fstab
info "boot config" "Ok, your system should be ready. You may wish to check:"
info "boot config" " /mnt/etc/fstab"
info "boot config" " /boot/cmdline.txt"
info "boot config" "Your new root drive is currently accessible under /mnt."
info "boot config" "In order to restart with this drive at /, please type:"
info "boot config" "sudo reboot"