Browse code

Enable console logging for Ironic baremetal VMs

Logs console output of VMs created for use by Ironic to
$DATA_DIR/ironic/logs. This gives Jenkins something to archive
that will be useful for debugging any deployment ramdisk issue
blocking provisioning.

Change-Id: I7d234a6a13dbe8579f685e46d7712dae497272a5

Adam Gandelman authored on 2014/04/12 09:06:14
Showing 4 changed files
... ...
@@ -65,6 +65,10 @@ IRONIC_VM_NETWORK_RANGE=${IRONIC_VM_NETWORK_RANGE:-192.0.2.0/24}
65 65
 IRONIC_VM_MACS_CSV_FILE=${IRONIC_VM_MACS_CSV_FILE:-$IRONIC_DATA_DIR/ironic_macs.csv}
66 66
 IRONIC_AUTHORIZED_KEYS_FILE=${IRONIC_AUTHORIZED_KEYS_FILE:-$HOME/.ssh/authorized_keys}
67 67
 
68
+# By default, baremetal VMs will console output to file.
69
+IRONIC_VM_LOG_CONSOLE=${IRONIC_VM_LOG_CONSOLE:-True}
70
+IRONIC_VM_LOG_DIR=${IRONIC_VM_LOG_DIR:-$IRONIC_DATA_DIR/logs/}
71
+
68 72
 DIB_DIR=${DIB_DIR:-$DEST/diskimage-builder}
69 73
 
70 74
 # Use DIB to create deploy ramdisk and kernel.
... ...
@@ -177,6 +181,9 @@ function configure_ironic_conductor {
177 177
     iniset $IRONIC_CONF_FILE pxe tftp_server $HOST_IP
178 178
     iniset $IRONIC_CONF_FILE pxe tftp_root $IRONIC_TFTPBOOT_DIR
179 179
     iniset $IRONIC_CONF_FILE pxe tftp_master_path $IRONIC_TFTPBOOT_DIR/master_images
180
+    if [[ "$IRONIC_VM_LOG_CONSOLE" == "True" ]] ; then
181
+        iniset $IRONIC_CONF_FILE pxe pxe_append_params "nofb nomodeset vga=normal console=ttyS0"
182
+    fi
180 183
 }
181 184
 
182 185
 # create_ironic_cache_dir() - Part of the init_ironic() process
... ...
@@ -306,9 +313,15 @@ function configure_ironic_dirs {
306 306
 function create_bridge_and_vms {
307 307
     # Call libvirt setup scripts in a new shell to ensure any new group membership
308 308
     sudo su $STACK_USER -c "$IRONIC_SCRIPTS_DIR/setup-network"
309
+    if [[ "$IRONIC_VM_LOG_CONSOLE" == "True" ]] ; then
310
+        LOG_ARG="$IRONIC_VM_LOG_DIR"
311
+    else
312
+        LOG_ARG=""
313
+    fi
309 314
     sudo su $STACK_USER -c "$IRONIC_SCRIPTS_DIR/create-nodes \
310 315
         $IRONIC_VM_SPECS_CPU $IRONIC_VM_SPECS_RAM $IRONIC_VM_SPECS_DISK \
311
-        amd64 $IRONIC_VM_COUNT $IRONIC_VM_NETWORK_BRIDGE $IRONIC_VM_EMULATOR" >> $IRONIC_VM_MACS_CSV_FILE
316
+        amd64 $IRONIC_VM_COUNT $IRONIC_VM_NETWORK_BRIDGE $IRONIC_VM_EMULATOR \
317
+        $LOG_ARG" >> $IRONIC_VM_MACS_CSV_FILE
312 318
 }
313 319
 
314 320
 function enroll_vms {
... ...
@@ -9,6 +9,25 @@ templatedir = os.path.join(os.path.dirname(os.path.dirname(__file__)),
9 9
                            'templates')
10 10
 
11 11
 
12
+CONSOLE_LOG = """
13
+    <serial type='file'>
14
+      <source path='%(console_log)s'/>
15
+      <target port='0'/>
16
+      <alias name='serial0'/>
17
+    </serial>
18
+    <serial type='pty'>
19
+      <source path='/dev/pts/49'/>
20
+      <target port='1'/>
21
+      <alias name='serial1'/>
22
+    </serial>
23
+    <console type='file'>
24
+      <source path='%(console_log)s'/>
25
+      <target type='serial' port='0'/>
26
+      <alias name='serial0'/>
27
+    </console>
28
+"""
29
+
30
+
12 31
 def main():
13 32
     parser = argparse.ArgumentParser(
14 33
         description="Configure a kvm virtual machine for the seed image.")
... ...
@@ -30,6 +49,8 @@ def main():
30 30
                         help='The libvirt network name to use')
31 31
     parser.add_argument('--libvirt-nic-driver', default='e1000',
32 32
                         help='The libvirt network driver to use')
33
+    parser.add_argument('--console-log',
34
+                        help='File to log console')
33 35
     parser.add_argument('--emulator', default=None,
34 36
                         help='Path to emulator bin for vm template')
35 37
     args = parser.parse_args()
... ...
@@ -44,6 +65,7 @@ def main():
44 44
         'cpus': args.cpus,
45 45
         'bootdev': args.bootdev,
46 46
         'network': args.network,
47
+        'nicdriver': args.libvirt_nic_driver,
47 48
         'emulator': args.emulator,
48 49
     }
49 50
 
... ...
@@ -55,22 +77,13 @@ def main():
55 55
         elif os.path.exists("/usr/bin/qemu-kvm"):  # Redhat
56 56
             params['emulator'] = "/usr/bin/qemu-kvm"
57 57
 
58
-    nicparams = {
59
-        'nicdriver': args.libvirt_nic_driver,
60
-        'network': args.network,
61
-    }
62
-
63
-    params['bm_network'] = """
64
-<!-- neutron friendly 'bare metal' network -->
65
-<interface type='network'>
66
-  <source network='%(network)s'/>
67
-  <virtualport type='openvswitch'/>
68
-  <model type='%(nicdriver)s'/>
69
-  <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
70
-</interface>""" % nicparams
71
-
58
+    if args.console_log:
59
+        params['console_log'] = CONSOLE_LOG % {'console_log': args.console_log}
60
+    else:
61
+        params['console_log'] = ''
72 62
     libvirt_template = source_template % params
73 63
     conn = libvirt.open("qemu:///system")
64
+
74 65
     a = conn.defineXML(libvirt_template)
75 66
     print ("Created machine %s with UUID %s" % (args.name, a.UUIDString()))
76 67
 
... ...
@@ -4,7 +4,7 @@
4 4
 
5 5
 # Creates baremetal poseur nodes for ironic testing purposes
6 6
 
7
-set -exu
7
+set -ex
8 8
 
9 9
 # Keep track of the devstack directory
10 10
 TOP_DIR=$(cd $(dirname "$0")/.. && pwd)
... ...
@@ -24,6 +24,7 @@ esac
24 24
 TOTAL=$(($5 - 1))
25 25
 BRIDGE=$6
26 26
 EMULATOR=$7
27
+LOGDIR=$8
27 28
 
28 29
 LIBVIRT_NIC_DRIVER=${LIBVIRT_NIC_DRIVER:-"e1000"}
29 30
 LIBVIRT_STORAGE_POOL=${LIBVIRT_STORAGE_POOL:-"default"}
... ...
@@ -43,6 +44,10 @@ if [ "$pool_state" != "running" ] ; then
43 43
   virsh pool-start $LIBVIRT_STORAGE_POOL >&2
44 44
 fi
45 45
 
46
+if [ -n "$LOGDIR" ] ; then
47
+  mkdir -p "$LOGDIR"
48
+fi
49
+
46 50
 PREALLOC=
47 51
 if [ -f /etc/debian_version ]; then
48 52
     PREALLOC="--prealloc-metadata"
... ...
@@ -51,6 +56,11 @@ fi
51 51
 DOMS=""
52 52
 for idx in $(seq 0 $TOTAL) ; do
53 53
     NAME="baremetal${BRIDGE}_${idx}"
54
+    if [ -n "$LOGDIR" ] ; then
55
+      VM_LOGGING="--console-log $LOGDIR/${NAME}_console.log"
56
+    else
57
+      VM_LOGGING=""
58
+    fi
54 59
     DOMS="$DOMS $NAME"
55 60
     VOL_NAME="baremetal${BRIDGE}-${idx}.qcow2"
56 61
     (virsh list --all | grep -q $NAME) && continue
... ...
@@ -62,7 +72,10 @@ for idx in $(seq 0 $TOTAL) ; do
62 62
     # Pre-touch the VM to set +C, as it can only be set on empty files.
63 63
     sudo touch "$volume_path"
64 64
     sudo chattr +C "$volume_path" || true
65
-    $TOP_DIR/scripts/configure-vm --bootdev network --name $NAME --image "$volume_path" --arch $ARCH --cpus $CPU --memory $MEM --libvirt-nic-driver $LIBVIRT_NIC_DRIVER --emulator $EMULATOR --network $BRIDGE >&2
65
+    $TOP_DIR/scripts/configure-vm \
66
+      --bootdev network --name $NAME --image "$volume_path" \
67
+      --arch $ARCH --cpus $CPU --memory $MEM --libvirt-nic-driver $LIBVIRT_NIC_DRIVER \
68
+      --emulator $EMULATOR --network $BRIDGE $VM_LOGGING >&2
66 69
 done
67 70
 
68 71
 for dom in $DOMS ; do
... ...
@@ -27,14 +27,19 @@
27 27
     <controller type='ide' index='0'>
28 28
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
29 29
     </controller>
30
-    %(network)s
31
-    %(bm_network)s
30
+    <interface type='network'>
31
+      <source network='%(network)s'/>
32
+      <virtualport type='openvswitch'/>
33
+      <model type='%(nicdriver)s'/>
34
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
35
+    </interface>
32 36
     <input type='mouse' bus='ps2'/>
33 37
     <graphics type='vnc' port='-1' autoport='yes'/>
34 38
     <video>
35 39
       <model type='cirrus' vram='9216' heads='1'/>
36 40
       <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
37 41
     </video>
42
+    %(console_log)s
38 43
     <memballoon model='virtio'>
39 44
       <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
40 45
     </memballoon>