-
Notifications
You must be signed in to change notification settings - Fork 0
/
qemu-create-os-img
executable file
·204 lines (166 loc) · 6.22 KB
/
qemu-create-os-img
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
#!/usr/bin/env bash
# Required: debootstrap grep chroot qemu-utils(qemu-nbd) mount(umount)
# coreutils(cat rmdir sleep rm) cryptsetup(askpass) kmod(modprobe)
# sudo fdisk e2fsprogs(mkfs.ext4) grub2-common(grub-install)
disk_size="5G"
efi_size="300M"
release="Bionic"
debianrepo="http://ftp.pl.debian.org/debian"
ubunturepo="http://archive.ubuntu.com/ubuntu"
include="less,vim,nano,sudo,openssh-server,acpid"
debianrels="buster,stretch,jessie"
ubunturels="focal,eoan,disco,cosmic,bionic,xenial,trusty"
Help(){
self=${0##*/}
cat <<-EOF
$self - Create a fresh Debian/Ubuntu qemu image
USAGE: $self [-h|--help] [-r <release>] [-n <hostname>] [-i <img file>]
[-s <disk size>] [-e <EFI size>] [<debootstrap>]
-h|--help: Just display this help text
-r/--release <release>: Debian ($debianrels) or
Ubuntu ($ubunturels)
-n/--name <hostname>: Desired hostname
-i/--image <img file>: Image file location (overwritten if existing)
-d/--disksize <disk size>: Size of the virtual disk in MB
-e//-efisize <EFI size>: Size of the EFI System Partition (rest: root)
<debootstrap>: Extra arguments for debootstrap
Default values when options are not supplied:
<release>: $release
<hostname>: <release>
<img file>: <hostname>-<os>-<release>.qcow2
<disk size>: $disk_size
<EFI size>: $efi_size
Authors: Kamil Trzcinski (http://ayufan.eu)
pepa65 <[email protected]> gitlab.com/pepa65/misc
License: GPLv3+
EOF
}
Umount(){
grep -q "$mntdir$1" /proc/mounts && chroot "$mntdir" umount $1
sleep 1
}
Clean(){
if [[ $mntdir ]] && grep -q "$mntdir" /proc/mounts
then
Umount /proc
Umount /sys
Umount /boot/efi
Umount /dev
sudo umount "$mntdir"
sleep 1
fi
[[ $disk ]] && qemu-nbd -d "$disk" && sleep 1
[[ $mntdir ]] && rmdir "$mntdir"
}
Fail(){
Clean
echo
echo "ABORTED: $1"
exit 2
}
mntdir=$(mktemp -d) disk=
trap 'Fail "Ctrl-C received"' INT
args=
while (($#))
do
case $1 in
-h|--help) Help; exit 0 ;;
-r|--release) [[ -z $2 ]] && Help && Fail "option $1 needs argument"
release=$2; shift 2 ;;
-n|--name) [[ -z $2 ]] && Help && Fail "option $1 needs argument"
hostname=$2; shift 2 ;;
-i|--image) [[ -z $2 ]] && Help && Fail "option $1 needs argument"
img_file=$2; shift 2 ;;
-d|--disksize) [[ -z $2 ]] && Help && Fail "option $1 needs argument"
disk_size=$2; shift 2 ;;
-e|--efisize) [[ -z $2 ]] && Help && Fail "option $1 needs argument"
efi_size=$2M; shift 2 ;;
*) args+="$1 "
shift ;;
esac
done
release=${release,,} os=
[[ ,$debianrels, = *,$release,* ]] && os=Debian repo=$debianrepo kern=linux-image-amd64
[[ ,$ubunturels, = *,$release,* ]] && os=Ubuntu repo=$ubunturepo kern=linux-image-generic
[[ $os ]] || Fail "release '$release' not supported"
[[ $hostname ]] || hostname=$release
[[ $img_file ]] || img_file=$hostname-$os-$release.qcow2
pw= pwa=1
while [[ ! $pw = $pwa ]]
do
pw=$(/lib/cryptsetup/askpass "Enter root password for image: ")
pwa=$(/lib/cryptsetup/askpass "Enter the same password again: ")
done
rm -f -- "$img_file" || Fail "insufficient rights to $img_file"
qemu-img create -f qcow2 "$img_file" $disk_size
[[ -f $img_file ]] || Fail "cannot create qemu image $img_file of size $disk_size"
echo "Installing $release into $img_file..."
echo "Looking for nbd device..."
sudo modprobe nbd max_part=16 || Fail "cannot load nbd module into kernel"
for nbd in /dev/nbd*
do sudo qemu-nbd -c "$nbd" "$img_file" 2>/dev/null && disk=$nbd && break
done
[[ $disk ]] || Fail "no nbd device available"
echo "Connected $img_file to $disk"
echo "Partitioning $disk..."
#fdisk_input=$'o\nn\n\n\n\n+'$boot_size$'\nn\n\n\n\n\nw\n'
#sudo fdisk -Lnever "$disk" <<<"$fdisk_input" ||
# Fail "cannot partition $img_file"
gdisk_input=$'n\n1\n\n+'$efi_size$'\nef00\nn\n\n\n\n\nw\ny\n'
sudo gdisk "$disk" <<<"$gdisk_input" ||
Fail "cannot partition $img_file"
echo "Formatting EFI partition..."
sudo mkfs.vfat "${disk}p1" || Fail "cannot create /boot/efi vfat"
echo "Formatting root partition..."
sudo mkfs.ext4 -q "${disk}p2" || Fail "cannot create / ext4"
echo "Mounting root partition..."
sudo mount "${disk}p2" "$mntdir" || Fail "cannot mount /"
echo "Mounting EFI partition..."
sudo mkdir -p "$mntdir/boot/efi"
sudo mount "${disk}p2" "$mntdir/boot/efi" || Fail "cannot mount /boot/efi"
echo "Installing $os $release..."
sudo debootstrap --include=$include $args "$release" "$mntdir" "$repo" ||
Fail "cannot install $os $release onto $disk"
echo "Configuring system..."
cat <<-EOF |sudo tee "$mntdir/etc/fstab"
/dev/sda1 /boot/efi vfat rw,relatime,gid=46,fmask=0077,dmask=0077 0 2
/dev/sda2 / ext4 relatime,errors=remount-ro 0 1
EOF
echo "$hostname" |sudo tee "$mntdir/etc/hostname"
cat <<-EOF |sudo tee "$mntdir/etc/hosts"
127.0.0.1 localhost
127.0.1.1 $hostname
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
EOF
cat <<-EOF |sudo tee "$mntdir/etc/network/interfaces"
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
EOF
sudo mount --bind /dev/ "$mntdir/dev" || Fail "cannot bind /dev"
sudo chroot "$mntdir" mount -t vfat "${disk}p1" /boot/efi ||
Fail "cannot mount /boot/efi"
sudo chroot "$mntdir" mount -t proc proc /proc || Fail "cannot mount /proc"
sudo chroot "$mntdir" mount -t sysfs sysfs /sys || Fail "cannot mount /sys"
LANG=C DEBIAN_FRONTEND=noninteractive sudo chroot "$mntdir" apt-get install -y -q $kern grub-efi ||
Fail "cannot install linux-image and grub packages"
sudo chroot "$mntdir" grub-install "$disk" ||
Fail "cannot install grub bootloader"
sudo chroot "$mntdir" update-grub || Fail "cannot update grub"
sudo sed -i "s|${disk}p1|/dev/sda1|g" "$mntdir/boot/grub/grub.cfg"
sudo sed -i "s|${disk}p2|/dev/sda2|g" "$mntdir/boot/grub/grub.cfg"
sudo chroot "$mntdir" chpasswd <<<"root:$pw"
echo "Finishing grub installation..."
sudo grub-install "$disk" --root-directory="$mntdir" --modules="biosdisk part_msdos" ||
Fail "cannot reinstall grub"
Clean
echo
echo "Installed $os $release from $repo"
echo " on virtual disk file $img_file with hostname $hostname"
[[ $args ]] && echo " with debootstrap extra arguments $args"
echo " disk size is $disk_size and EFI partition size is $efi_size"
echo "SUCCESS!"
exit 0