Jason Michael dot com

You don't owe me anything.

Virtual Home

| Comments

I bought a Dell Precision Workstation with dual xeon’s and added 64 gigs of RAM. I intend to turn it into a VM host using KVM (it’s running CentOS 7.x). I’m struggling with this because it seems every thing I try, I find issues I have to trouble shoot, and spending all day troubleshooting and not building is a real pain.

Automation

I created a ‘build a VM’ script, containing the following:

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
# /setup/deploy_vm.bash

source /setup/lib.bash

if [ $# -eq 0 ]; then
    echo "No arguments supplied!"
    echo "REQUIRED: 1 = instid [example: centos-git], 2 = insthost [example: centos-git]"
    exit 1
fi

instid="$1"
insthost="$2"
tzone="US/Central"
domain="atomic.org"
discsize="20G"
memsize="2048"

normallog "grab centos 7 cloud image"

cd /var/lib/libvirt/boot

if [ -f "CentOS-7-x86_64-GenericCloud.qcow2" ]; then
    errorlog "qcow file exists, Skipping"
else
    detaillog "qcow file does not exist.  Download it"
    wget http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2
fi

normallog "setup directories"

D=/var/lib/libvirt/images
VM=$instid
mkdir -vp $D/$VM

normallog "setup metadata"

cd $D/$VM

rm -f meta-data
touch meta-data

echo "instance-id: $instid" >> meta-data
echo "local-hostname: $insthost" >> meta-data

normallog "current meta-data:"

cat meta-data

normallog "setup user-data"

if [ -f ~/.ssh/id_$insthost ]; then
    errorlog "~/.ssh/id_$insthost exists.  Skipping"
else
    ssh-keygen -t ed25519 -C "VM Login ssh key foo" -f ~/.ssh/id_$insthost -P ""
fi

tmpkey=$(cat ~/.ssh/id_$insthost.pub)

cd $D/$VM

rm -f user-data
touch user-data

cat > user-data << ENDOFFILE
#cloud-config

# Hostname management
preserve_hostname: False
hostname: $insthost
fqdn: $insthost.$domain

# Users
users:
    - default
    - name: jason
      groups: ['wheel']
      shell: /bin/bash
      sudo: ALL=(ALL) NOPASSWD:ALL
      ssh-authorized-keys:
        - $tmpkey

# Configure where output will go
output:
  all: ">> /var/log/cloud-init.log"

# configure interaction with ssh server
ssh_genkeytypes: ['ed25519', 'rsa']

# Install my public ssh key to the first user-defined user configured
# in cloud.cfg in the template (which is centos for CentOS cloud images)
ssh_authorized_keys:
  - $tmpkey

# set timezone for VM
timezone: $tzone

# Remove cloud-init
runcmd:
  - systemctl stop network && systemctl start network
  - yum -y remove cloud-init
ENDOFFILE

cat user-data

normallog "Copy cloud image"
cd $D/$VM
cp /var/lib/libvirt/boot/CentOS-7-x86_64-GenericCloud.qcow2 $VM.qcow2

normallog "Create $discsize disc image"
cd $D/$VM
export LIBGUESTFS_BACKEND=direct
qemu-img create -f qcow2 -o preallocation=metadata $VM.new.image $discsize
virt-resize --quiet --expand /dev/sda1 $VM.qcow2 $VM.new.image
cd $D/$VM
mv $VM.new.image $VM.qcow2

normallog "Creating cloud-init iso"

mkisofs -o $VM-cidata.iso -V cidata -J -r user-data meta-data

normallog "Create a pool"

virsh pool-create-as --name $VM --type dir --target $D/$VM

normallog "Install VM"

cd $D/$VM
virt-install --import --name $VM \
--memory $memsize --vcpus 1 --cpu host \
--disk $VM.qcow2,format=qcow2,bus=virtio \
--disk $VM-cidata.iso,device=cdrom \
--network bridge=virbr0,model=virtio \
--os-type=linux \
--os-variant=centos7.0 \
--graphics spice \
--noautoconsole

normallog "Cleanup"

cd $D/$VM
virsh change-media $VM hda --eject --config
rm meta-data user-data centos7-vm1-cidata.iso

normallog "Get IP Address"

virsh net-dhcp-leases default

Test

I tested the script a few times: