-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreinstall.sh
242 lines (220 loc) · 8.12 KB
/
reinstall.sh
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#!/bin/bash
# https://github.com/p7e4/reinstall
set -e
while getopts "p:k:s:n:" opt; do
case $opt in
p)
PASSWORD=$OPTARG
;;
k)
SSHKEY=$OPTARG
;;
s)
SYSTEM=$OPTARG
;;
n)
hostname=$OPTARG
;;
h | *)
echo "Usage: $(basename $0) [-p password] [-k ssh-key] [-n hostname] -s system"
exit 0
;;
esac
done
if [ -z "$PASSWORD" ] && [ -z "$SSHKEY" ]; then
echo "Error: either -k or -p parameter need to be provided"
exit 1
fi
SYSTEM=$(echo "$SYSTEM" | tr '[:upper:]' '[:lower:]')
if [ "$SYSTEM" != "debian" ] && \
[ "$SYSTEM" != "ubuntu" ] && \
[ "$SYSTEM" != "fedora" ] && \
[ "$SYSTEM" != "rocky" ] && \
[ "$SYSTEM" != "almalinux" ] && \
[ "$SYSTEM" != "centos" ] && \
[ "$SYSTEM" != "archlinux" ]; then
echo "Error: -s parameter must be one of debian, ubuntu, fedora, rocky, almalinux, centos, archlinux"
exit 1
fi
if [ -z "$hostname" ]; then
hostname="vm-$SYSTEM"
fi
if [ -f /etc/default/kexec ]; then
sed -i 's/LOAD_KEXEC=true/LOAD_KEXEC=false/' /etc/default/kexec
fi
apt update && apt install -y qemu-utils jq
country=$(curl -s "https://ipinfo.io/" | jq -r ".country")
echo "server country: $country"
if [ "$country" == "CN" ]; then
if [ "$SYSTEM" == "debian" ]; then
imgUrl="https://mirrors.nju.edu.cn/debian-cdimage/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2"
# deb822 require cloud-init >= 23.4
# debian 12 current: /usr/bin/cloud-init 22.4.2
# apt:
# sources_list: |
# Types: deb deb-src
# URIs: https://mirrors.ustc.edu.cn/debian/
# Suites: bookworm bookworm-updates bookworm-backports
# Components: main
# Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
#
# Types: deb deb-src
# URIs: https://mirrors.ustc.edu.cn/debian-security/
# Suites: bookworm-security
# Components: main
# Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
aptMirror="
apt:
primary:
- arches: [default]
uri: https://mirrors.ustc.edu.cn/debian/
security:
- arches: [default]
uri: https://mirrors.ustc.edu.cn/debian-security/"
elif [ "$SYSTEM" == "ubuntu" ]; then
imgUrl="https://mirrors.nju.edu.cn/ubuntu-cloud-images/noble/current/noble-server-cloudimg-amd64.img"
shaSum="https://mirrors.nju.edu.cn/ubuntu-cloud-images/noble/current/SHA256SUMS"
aptMirror="
apt:
sources_list: |
Types: deb
URIs: https://mirrors.ustc.edu.cn/ubuntu/
Suites: noble noble-updates noble-security noble-backports
Components: main universe restricted multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg"
elif [ "$SYSTEM" == "fedora" ]; then
imgUrl="https://mirrors.nju.edu.cn/fedora/releases/41/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-41-1.4.x86_64.qcow2"
elif [ "$SYSTEM" == "rocky" ]; then
imgUrl="https://mirrors.nju.edu.cn/rocky/9/images/x86_64/Rocky-9-GenericCloud-Base.latest.x86_64.qcow2"
shaSum="https://mirrors.nju.edu.cn/rocky/9/images/x86_64/CHECKSUM"
elif [ "$SYSTEM" == "almalinux" ]; then
imgUrl="https://mirrors.nju.edu.cn/almalinux/9/cloud/x86_64/images/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2"
shaSum="https://mirrors.nju.edu.cn/almalinux/9/cloud/x86_64/images/CHECKSUM"
elif [ "$SYSTEM" == "centos" ]; then
imgUrl="https://mirrors.nju.edu.cn/centos-cloud/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-latest.x86_64.qcow2"
shaSum="https://mirrors.nju.edu.cn/centos-cloud/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-latest.x86_64.qcow2.SHA256SUM"
elif [ "$SYSTEM" == "archlinux" ]; then
imgUrl="https://mirrors.nju.edu.cn/archlinux/images/latest/Arch-Linux-x86_64-cloudimg.qcow2"
shaSum="https://mirrors.nju.edu.cn/archlinux/images/latest/Arch-Linux-x86_64-cloudimg.qcow2.SHA256"
fi
alpineHost="mirrors.nju.edu.cn"
dns="223.5.5.5, 223.6.6.6"
else
if [ "$SYSTEM" == "debian" ]; then
imgUrl="https://cdimage.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2"
elif [ "$SYSTEM" == "ubuntu" ]; then
imgUrl="https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
shaSum="https://cloud-images.ubuntu.com/noble/current/SHA256SUMS"
elif [ "$SYSTEM" == "fedora" ]; then
imgUrl="https://download.fedoraproject.org/pub/fedora/linux/releases/41/Cloud/x86_64/images/Fedora-Cloud-Base-UEFI-UKI-41-1.4.x86_64.qcow2"
elif [ "$SYSTEM" == "rocky" ]; then
imgUrl="https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud-Base.latest.x86_64.qcow2"
shaSum="https://dl.rockylinux.org/pub/rocky/9/images/x86_64/CHECKSUM"
elif [ "$SYSTEM" == "almalinux" ]; then
imgUrl="https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2"
shaSum="https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/CHECKSUM"
elif [ "$SYSTEM" == "centos" ]; then
imgUrl="https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-latest.x86_64.qcow2"
shaSum="https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-latest.x86_64.qcow2.SHA256SUM"
elif [ "$SYSTEM" == "archlinux" ]; then
imgUrl="https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.qcow2"
shaSum="https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.qcow2.SHA256"
fi
alpineHost="dl-cdn.alpinelinux.org"
dns="1.1.1.1, 8.8.8.8"
fi
rm -rf /reinstall
mkdir /reinstall && cd /reinstall
curl -o vmlinuz https://$alpineHost/alpine/latest-stable/releases/x86_64/netboot/vmlinuz-virt
curl -o initrd https://$alpineHost/alpine/latest-stable/releases/x86_64/netboot/initramfs-virt
curl -OA reinstall $imgUrl
imageFile=$(basename $imgUrl)
if [ "$shaSum" ]; then
curl -A reinstall -o SHA256SUMS $shaSum
sha256sum -c SHA256SUMS --ignore-missing 2>&1 | grep OK || (echo "$imageFile sha256 verify faile!" && exit 1)
fi
modprobe nbd
qemu-nbd -c /dev/nbd0 $imageFile
sleep 1
mount $(fdisk -l | grep -E "/dev/nbd0p.*Linux (root|filesystem)" | awk 'END {print $1}') /mnt
if [ "$SSHKEY" ]; then
echo "using ssh key auth, key: $SSHKEY"
sshAuth="
users:
- name: root
ssh_authorized_keys:
- $SSHKEY"
fi
if [ "$PASSWORD" ]; then
echo "using password auth, password: $PASSWORD"
passAuth="
ssh_pwauth: true
chpasswd:
expire: false
users:
- name: root
password: $PASSWORD
type: text
runcmd:
- sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config
- lsb_release -c | grep noble || systemctl restart sshd"
fi
if [ "$SYSTEM" == "fedora" ]; then
cloudFilePath=/mnt/root/etc/cloud/cloud.cfg.d/custom.cfg
else
cloudFilePath=/mnt/etc/cloud/cloud.cfg.d/custom.cfg
fi
cat > $cloudFilePath << EOF
#cloud-config
datasource_list: [None]
hostname: $hostname
timezone: Asia/Shanghai
package_update: true
network:
version: 2
ethernets:
interface:
match:
name: e*
dhcp4: true
dhcp6: false
dhcp4-overrides:
use-dns: no
nameservers:
addresses: [$dns]\
$aptMirror$sshAuth$passAuth
EOF
# systemd-networkd match won't work
if [ "$SYSTEM" == "archlinux" ]; then
sed -i "6,17d" $cloudFilePath
fi
umount /mnt && qemu-nbd -d /dev/nbd0
mkdir tmp && cd tmp
gzip -d < ../initrd | cpio -id
sed -i '/^exec switch_root/i\mv post.start $sysroot/etc/local.d/\nln -s /etc/init.d/local $sysroot/etc/runlevels/default/' init
disk=$(df / | awk 'NR==2 {print $1}')
cat > post.start << EOF
mount / -o remount,size=100%
echo -e "\nhttps://${alpineHost}/alpine/latest-stable/community/" >> /etc/apk/repositories
apk add --no-cache util-linux qemu-img
mount $disk /mnt
cp /mnt/reinstall/$imageFile ./
umount /mnt
qemu-img dd if=$imageFile of=$(echo $disk | sed -E 's/[0-9]+$//') bs=1M
reboot
EOF
chmod +x post.start
find . | cpio -H newc -oF ../initrd
cd .. && rm -rf tmp
cat > /etc/grub.d/40_custom << EOF
#!/bin/sh
exec tail -n +3 \$0
set timeout=3
menuentry "reinstall" {
search -n -f --set=root /reinstall/vmlinuz
linux /reinstall/vmlinuz alpine_repo=https://$alpineHost/alpine/latest-stable/main/ modloop=https://$alpineHost/alpine/latest-stable/releases/x86_64/netboot/modloop-virt
initrd /reinstall/initrd
}
EOF
update-grub && grub-reboot reinstall
echo "reboot to continue"