1
|
#!/bin/bash
|
2
|
# Script managed by Ansible, do not edit
|
3
|
#
|
4
|
# Copyright (C) 2017 Free Software Foundation
|
5
|
# Copyright (C) 2017 Ruben Rodriguez <ruben@fsf.org>
|
6
|
#
|
7
|
# This program is free software; you can redistribute it and/or modify
|
8
|
# it under the terms of the GNU General Public License as published by
|
9
|
# the Free Software Foundation; either version 3 of the License, or
|
10
|
# (at your option) any later version.
|
11
|
#
|
12
|
# This program is distributed in the hope that it will be useful,
|
13
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
# GNU General Public License for more details.
|
16
|
#
|
17
|
# You should have received a copy of the GNU General Public License
|
18
|
# along with this program; if not, write to the Free Software
|
19
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
20
|
#
|
21
|
# https://dsa.debian.org/howto/install-kvm/
|
22
|
# dependencies
|
23
|
# apt install --no-install-recommends libvirt-dev kvm virtinst xfsprogs pwgen
|
24
|
|
25
|
set -e
|
26
|
export LANG=C
|
27
|
export LC_ALL=C
|
28
|
|
29
|
if [ $# -lt 4 ]; then
|
30
|
echo "Usage: $0 hostname.foo.bar disksize(MB) ramsize(MB) cpucount [distro_release_codename]"
|
31
|
echo "Example: $0 www.gnu.org 5000 512 2 flidas"
|
32
|
echo "supported codenames are flidas, belenos and stretch"
|
33
|
exit 1
|
34
|
fi
|
35
|
|
36
|
HOST=$1
|
37
|
HOSTSHORT=$(echo $HOST | sed 's/\..*//')
|
38
|
POOL=rbd
|
39
|
|
40
|
if ! getent hosts $HOST > /dev/null; then
|
41
|
echo "Could not resolve the hostname to an IP. Add it to the DNS first!"
|
42
|
exit 1
|
43
|
fi
|
44
|
|
45
|
IP=$(getent ahosts $HOST |grep ^209.*RAW| sed 's/ .*//')
|
46
|
IP6=$(getent ahosts $HOST |grep ^2001.*RAW| sed 's/ .*//')
|
47
|
NIC=eth0
|
48
|
GATEWAY=209.51.188.1
|
49
|
GATEWAY6=2001:470:142::1
|
50
|
|
51
|
SIZE=$2
|
52
|
RAM=$3
|
53
|
CPUS=$4
|
54
|
|
55
|
RELEASE=flidas
|
56
|
[ 1${5}1 != 11 ] && RELEASE=$5
|
57
|
case $RELEASE in
|
58
|
flidas|belenos)
|
59
|
archive=http://us.archive.trisquel.info/trisquel
|
60
|
linux_pkg=linux-image-virtual
|
61
|
;;
|
62
|
stretch)
|
63
|
archive=http://deb.debian.org/debian/
|
64
|
linux_pkg=linux-image-amd64
|
65
|
;;
|
66
|
*)
|
67
|
echo "$0: error: unknown release"
|
68
|
exit 1
|
69
|
;;
|
70
|
esac
|
71
|
|
72
|
rbd create $HOST --size $SIZE -p $POOL --image-format=2 --image-feature exclusive-lock,object-map,fast-diff,layering
|
73
|
DEVICE=$(rbd-nbd map $HOST)
|
74
|
|
75
|
TARGET=$(mktemp -d)
|
76
|
KEYFILE=/dev/shm/keyfile
|
77
|
pwgen 128 -s -1 | xargs echo -n > $KEYFILE
|
78
|
echo YES | cryptsetup luksFormat -y --cipher aes-xts-plain64 --hash sha256 --use-urandom --key-size 256 $DEVICE --key-file=$KEYFILE
|
79
|
cryptsetup luksOpen $DEVICE $HOST-crypt0 --key-file=$KEYFILE
|
80
|
mkfs.xfs -i size=2048 -s size=4096 -d agcount=4 /dev/mapper/$HOST-crypt0
|
81
|
mount /dev/mapper/$HOST-crypt0 $TARGET -o discard,noatime,nodiratime
|
82
|
|
83
|
if ! [ -d /srv/debootstrap-cache/${RELEASE} ] ; then
|
84
|
mkdir -p /srv/debootstrap-cache/${RELEASE}
|
85
|
eatmydata debootstrap --exclude=resolvconf ${RELEASE} /srv/debootstrap-cache/${RELEASE} $archive
|
86
|
fi
|
87
|
eatmydata cp -a /srv/debootstrap-cache/${RELEASE}/* $TARGET
|
88
|
|
89
|
mknod $TARGET/dev/sda b 8 0
|
90
|
mkdir $TARGET/dev/mapper
|
91
|
cp -av $(readlink -f /dev/mapper/${HOST}-crypt0) $TARGET/dev/mapper/${HOST}-crypt0
|
92
|
cat << EOF > $TARGET/boot/keyscript.sh
|
93
|
#!/bin/sh
|
94
|
echo -n $(cat $KEYFILE)
|
95
|
EOF
|
96
|
chmod 700 $TARGET/boot/keyscript.sh $TARGET/boot/
|
97
|
|
98
|
cat << EOF > /dev/shm/grub.cfg
|
99
|
cryptomount -k /keyfile hd0
|
100
|
linux (crypto0)/vmlinuz root=/dev/mapper/${HOST}-crypt0 ro elevator=noop console=tty0 console=ttyS0,115200 biosdevname=0 net.ifnames=0
|
101
|
initrd (crypto0)/initrd.img
|
102
|
boot
|
103
|
EOF
|
104
|
dd if=/dev/zero of=/dev/shm/memdisk bs=1M count=1
|
105
|
mkfs.ext2 /dev/shm/memdisk
|
106
|
mkdir /dev/shm/memdiskmount || true
|
107
|
mount /dev/shm/memdisk /dev/shm/memdiskmount
|
108
|
cp $KEYFILE /dev/shm/memdiskmount/
|
109
|
umount /dev/shm/memdiskmount
|
110
|
grub-mkimage -v -C xz -c /dev/shm/grub.cfg -O i386-pc -o /var/lib/libvirt/images/grub-$HOST.bin biosdisk ext2 linux xfs normal luks help crypto cryptodisk zfscrypt gcry_sha512 gcry_sha256 echo cat memdisk -m /dev/shm/memdisk
|
111
|
|
112
|
cat << EOF > $TARGET/etc/fstab
|
113
|
# <file system> <mount point> <type> <options> <dump> <pass>
|
114
|
proc /proc proc defaults 0 0
|
115
|
/dev/mapper/${HOST}-crypt0 / xfs noatime,nodiratime,sunit=8192,swidth=8192 0 1
|
116
|
EOF
|
117
|
|
118
|
echo "${HOST}-crypt0 /dev/sda none luks,discard,keyscript=/boot/keyscript.sh" > $TARGET/etc/crypttab
|
119
|
|
120
|
mount -t proc none $TARGET/proc
|
121
|
mount -o bind /dev $TARGET/dev
|
122
|
|
123
|
case $RELEASE in
|
124
|
flidas|belenos)
|
125
|
cat << EOF > $TARGET/etc/apt/sources.list
|
126
|
deb http://us.archive.trisquel.info/trisquel/ ${RELEASE} main
|
127
|
deb http://us.archive.trisquel.info/trisquel/ ${RELEASE}-updates main
|
128
|
deb http://archive.trisquel.info/trisquel ${RELEASE}-security main
|
129
|
EOF
|
130
|
;;
|
131
|
stretch)
|
132
|
cat << EOF > $TARGET/etc/apt/sources.list
|
133
|
deb http://http.us.debian.org/debian ${RELEASE} main
|
134
|
deb http://security.debian.org/ ${RELEASE}/updates main
|
135
|
deb http://http.us.debian.org/debian ${RELEASE}-updates main
|
136
|
EOF
|
137
|
;;
|
138
|
esac
|
139
|
|
140
|
echo "nameserver 209.51.188.16" > $TARGET/etc/resolv.conf
|
141
|
|
142
|
# For disabling upstart during initial setup
|
143
|
cat << EOF > $TARGET/usr/sbin/policy-rc.d
|
144
|
#!/bin/sh
|
145
|
exit 101
|
146
|
EOF
|
147
|
chmod 755 $TARGET/usr/sbin/policy-rc.d
|
148
|
|
149
|
cp /usr/lib/x86_64-linux-gnu/libeatmydata.so $TARGET/usr/lib/x86_64-linux-gnu/libeatmydata.so
|
150
|
DEBIAN_FRONTEND=noninteractive eatmydata chroot $TARGET apt-get update
|
151
|
# busybox-static needed for debian stretch
|
152
|
DEBIAN_FRONTEND=noninteractive eatmydata chroot $TARGET apt-get dist-upgrade --force-yes -y -o Dpkg::Options::="--force-confnew"
|
153
|
DEBIAN_FRONTEND=noninteractive eatmydata chroot $TARGET apt-get install --force-yes -y --no-install-recommends $linux_pkg ssh acpid busybox-static xfsprogs cryptsetup python3-apt python
|
154
|
|
155
|
rm $TARGET/usr/sbin/policy-rc.d
|
156
|
|
157
|
# Set root password
|
158
|
ROOTPW=$(pwgen 12 -s -1)
|
159
|
echo root:$ROOTPW | chroot $TARGET chpasswd
|
160
|
|
161
|
cat << EOF > $TARGET/etc/init/ttykvm.conf
|
162
|
# ttykvm - getty
|
163
|
#
|
164
|
# This service maintains a getty on tty1 from the point the system is
|
165
|
# started until it is shut down again.
|
166
|
|
167
|
start on stopped rc RUNLEVEL=[2345]
|
168
|
|
169
|
stop on runlevel [!2345]
|
170
|
|
171
|
respawn
|
172
|
exec /sbin/getty -8 115200 ttyS0 xterm
|
173
|
EOF
|
174
|
|
175
|
cat << EOF > $TARGET/etc/network/interfaces
|
176
|
# The loopback network interface
|
177
|
auto lo
|
178
|
iface lo inet loopback
|
179
|
|
180
|
# The primary network interface
|
181
|
auto $NIC
|
182
|
iface $NIC inet static
|
183
|
address $IP
|
184
|
gateway $GATEWAY
|
185
|
netmask 255.255.255.0
|
186
|
hostname $HOST
|
187
|
|
188
|
iface eth0 inet6 static
|
189
|
pre-up echo 0 > /proc/sys/net/ipv6/conf/eth0/accept_dad
|
190
|
address $IP6
|
191
|
netmask 48
|
192
|
gateway $GATEWAY6
|
193
|
hostname $HOST
|
194
|
EOF
|
195
|
|
196
|
cat << EOF > $TARGET/etc/resolv.conf
|
197
|
domain fsf.org
|
198
|
search fsf.org
|
199
|
nameserver 209.51.188.16
|
200
|
EOF
|
201
|
|
202
|
echo $HOST > $TARGET/etc/hostname
|
203
|
|
204
|
cat << EOF > $TARGET/etc/hosts
|
205
|
127.0.0.1 localhost
|
206
|
$IP $HOST $HOSTSHORT
|
207
|
|
208
|
::1 localhost ip6-localhost ip6-loopback
|
209
|
fe00::0 ip6-localnet
|
210
|
ff00::0 ip6-mcastprefix
|
211
|
ff02::1 ip6-allnodes
|
212
|
ff02::2 ip6-allrouters
|
213
|
ff02::3 ip6-allhosts
|
214
|
EOF
|
215
|
|
216
|
mkdir $TARGET/root/.ssh
|
217
|
echo 'from="74.94.156.210" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIImP7xYaUTag4/cNyy8W//T4SZyD3bFtjSac3U7t41bh Ansible' > $TARGET/root/.ssh/authorized_keys
|
218
|
|
219
|
rm $TARGET/usr/lib/x86_64-linux-gnu/libeatmydata.so
|
220
|
umount $TARGET/proc
|
221
|
umount $TARGET/dev
|
222
|
umount $TARGET
|
223
|
cryptsetup luksClose /dev/mapper/${HOST}-crypt0
|
224
|
rbd-nbd unmap $DEVICE
|
225
|
|
226
|
cat << EOF > /tmp/disk.xml
|
227
|
<disk type='network' device='disk'>
|
228
|
<driver name='qemu' cache='writeback' discard='unmap' type='raw' />
|
229
|
<auth username='libvirt'>
|
230
|
<secret type='ceph' uuid='dc8e8240-15b4-47ae-896b-6632aec8103e'/>
|
231
|
</auth>
|
232
|
<source protocol='rbd' name='$POOL/$HOST'>
|
233
|
<host name='cephmon1' port='6789'/>
|
234
|
<host name='cephmon2' port='6789'/>
|
235
|
<host name='cephmon3' port='6789'/>
|
236
|
</source>
|
237
|
<target dev='sda' bus='scsi'/>
|
238
|
</disk>
|
239
|
EOF
|
240
|
|
241
|
virt-install --name $HOST --graphics vnc --boot kernel=/var/lib/libvirt/images/grub-$HOST.bin --network type=direct,source=macvtap-bond0,source_mode=bridge,model=virtio --disk none --noautoconsole --controller scsi,model=virtio-scsi --cpu host --vcpus=${CPUS} --memory=$RAM,hugepages=true --cpuset=auto
|
242
|
virsh attach-device $HOST /tmp/disk.xml --persistent
|
243
|
virsh dumpxml $HOST > /tmp/tmp.xml
|
244
|
#sed "1s#># xmlns:qemu=\'http://libvirt.org/schemas/domain/qemu/1.0'>#; s#</domain>#<qemu:commandline><qemu:arg value='-set'/><qemu:arg value='device.scsi0-0-0-0.min_io_size=4194304'/><qemu:arg value='-set'/><qemu:arg value='device.scsi0-0-0-0.opt_io_size=4194304'/></qemu:commandline></domain>#" /tmp/tmp.xml -i
|
245
|
sed "/virtio-scsi/a <driver queues='$CPUS'/>" /tmp/tmp.xml -i
|
246
|
virsh destroy $HOST
|
247
|
# This allows ipv6 to do neighbour discovery https://superuser.com/questions/944678/how-to-configure-macvtap-to-let-it-pass-multicast-packet-correctly
|
248
|
#sed "s_<interface type='direct.*_<interface type='direct' trustGuestRxFilters='yes'>_" -i /tmp/tmp.xml
|
249
|
virsh create /tmp/tmp.xml
|
250
|
|
251
|
echo "
|
252
|
|
253
|
Created new virtual machine $HOST
|
254
|
|
255
|
ROOT PASSWORD : $ROOTPW
|
256
|
LUKS KEY : `cat $KEYFILE`
|
257
|
IP : $IP
|
258
|
RBD IMAGE : $POOL/$HOST
|
259
|
SIZE : $SIZE
|
260
|
RAM SIZE : $RAM
|
261
|
"
|
262
|
|
263
|
rm /tmp/tmp.xml
|
264
|
rm -f $KEYFILE
|
265
|
rm -rf /dev/shm/memdisk* /dev/shm/grub.cfg
|
266
|
|
267
|
exit 0
|