Browse code

Add Ironic hardware deployment support

Currently devstack create VMs and then deploy Ironic on these VMs.
Sometimes developer may want to deploy on real platform.

A separated file is required to provide the baremetal compute node
information, which includes four fields for each hardware platform,
the ipmi address, the mac address, the ipmi user name and the
password.

Change-Id: I422b43eae6edc95f15b8c40383d0ba7fbcd9b1ff

yunhong jiang authored on 2014/10/08 23:01:02
Showing 2 changed files
... ...
@@ -40,6 +40,18 @@ IRONIC_CONF_FILE=$IRONIC_CONF_DIR/ironic.conf
40 40
 IRONIC_ROOTWRAP_CONF=$IRONIC_CONF_DIR/rootwrap.conf
41 41
 IRONIC_POLICY_JSON=$IRONIC_CONF_DIR/policy.json
42 42
 
43
+# Deploy to hardware platform
44
+IRONIC_HW_NODE_CPU=${IRONIC_HW_NODE_CPU:-1}
45
+IRONIC_HW_NODE_RAM=${IRONIC_HW_NODE_RAM:-512}
46
+IRONIC_HW_NODE_DISK=${IRONIC_HW_NODE_DISK:-10}
47
+IRONIC_HW_EPHEMERAL_DISK=${IRONIC_HW_EPHEMERAL_DISK:-0}
48
+# The file is composed of multiple lines, each line includes four field
49
+# separated by white space: IPMI address, MAC address, IPMI username
50
+# and IPMI password.
51
+# An example:
52
+#   192.168.110.107 00:1e:67:57:50:4c root otc123
53
+IRONIC_IPMIINFO_FILE=${IRONIC_IPMIINFO_FILE:-$IRONIC_DATA_DIR/hardware_info}
54
+
43 55
 # Set up defaults for functional / integration testing
44 56
 IRONIC_SCRIPTS_DIR=${IRONIC_SCRIPTS_DIR:-$TOP_DIR/tools/ironic/scripts}
45 57
 IRONIC_TEMPLATES_DIR=${IRONIC_TEMPLATES_DIR:-$TOP_DIR/tools/ironic/templates}
... ...
@@ -51,6 +63,7 @@ IRONIC_SSH_KEY_FILENAME=${IRONIC_SSH_KEY_FILENAME:-ironic_key}
51 51
 IRONIC_KEY_FILE=$IRONIC_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME
52 52
 IRONIC_SSH_VIRT_TYPE=${IRONIC_SSH_VIRT_TYPE:-virsh}
53 53
 IRONIC_TFTPBOOT_DIR=${IRONIC_TFTPBOOT_DIR:-$IRONIC_DATA_DIR/tftpboot}
54
+IRONIC_TFTPSERVER_IP=${IRONIC_TFTPSERVER_IP:-$HOST_IP}
54 55
 IRONIC_VM_SSH_PORT=${IRONIC_VM_SSH_PORT:-22}
55 56
 IRONIC_VM_SSH_ADDRESS=${IRONIC_VM_SSH_ADDRESS:-$HOST_IP}
56 57
 IRONIC_VM_COUNT=${IRONIC_VM_COUNT:-1}
... ...
@@ -80,7 +93,7 @@ IRONIC_AGENT_KERNEL_URL=${IRONIC_AGENT_KERNEL_URL:-http://tarballs.openstack.org
80 80
 IRONIC_AGENT_RAMDISK_URL=${IRONIC_AGENT_RAMDISK_URL:-http://tarballs.openstack.org/ironic-python-agent/coreos/files/coreos_production_pxe_image-oem.cpio.gz}
81 81
 
82 82
 # Which deploy driver to use - valid choices right now
83
-# are 'pxe_ssh' and 'agent_ssh'.
83
+# are 'pxe_ssh', 'pxe_ipmitool' and 'agent_ssh'.
84 84
 IRONIC_DEPLOY_DRIVER=${IRONIC_DEPLOY_DRIVER:-pxe_ssh}
85 85
 
86 86
 #TODO(agordeev): replace 'ubuntu' with host distro name getting
... ...
@@ -133,6 +146,11 @@ function is_ironic_enabled {
133 133
     return 1
134 134
 }
135 135
 
136
+function is_ironic_hardware {
137
+    is_ironic_enabled && [[ -n "${IRONIC_DEPLOY_DRIVER##*_ssh}" ]] && return 0
138
+    return 1
139
+}
140
+
136 141
 # install_ironic() - Collect source and prepare
137 142
 function install_ironic {
138 143
     # make sure all needed service were enabled
... ...
@@ -273,7 +291,7 @@ function configure_ironic_conductor {
273 273
     iniset $IRONIC_CONF_FILE DEFAULT rootwrap_config $IRONIC_ROOTWRAP_CONF
274 274
     iniset $IRONIC_CONF_FILE DEFAULT enabled_drivers $IRONIC_ENABLED_DRIVERS
275 275
     iniset $IRONIC_CONF_FILE conductor api_url http://$HOST_IP:6385
276
-    iniset $IRONIC_CONF_FILE pxe tftp_server $HOST_IP
276
+    iniset $IRONIC_CONF_FILE pxe tftp_server $IRONIC_TFTPSERVER_IP
277 277
     iniset $IRONIC_CONF_FILE pxe tftp_root $IRONIC_TFTPBOOT_DIR
278 278
     iniset $IRONIC_CONF_FILE pxe tftp_master_path $IRONIC_TFTPBOOT_DIR/master_images
279 279
     if [[ "$IRONIC_VM_LOG_CONSOLE" == "True" ]] ; then
... ...
@@ -475,7 +493,7 @@ function create_bridge_and_vms {
475 475
     create_ovs_taps
476 476
 }
477 477
 
478
-function enroll_vms {
478
+function enroll_nodes {
479 479
     local chassis_id=$(ironic chassis-create -d "ironic test chassis" | grep " uuid " | get_field 2)
480 480
     local idx=0
481 481
 
... ...
@@ -487,34 +505,65 @@ function enroll_vms {
487 487
         local _IRONIC_DEPLOY_RAMDISK_KEY=deploy_ramdisk
488 488
     fi
489 489
 
490
-    while read MAC; do
491
-
492
-        local node_id=$(ironic node-create --chassis_uuid $chassis_id \
493
-            --driver $IRONIC_DEPLOY_DRIVER \
490
+    if ! is_ironic_hardware; then
491
+        local ironic_node_cpu=$IRONIC_VM_SPECS_CPU
492
+        local ironic_node_ram=$IRONIC_VM_SPECS_RAM
493
+        local ironic_node_disk=$IRONIC_VM_SPECS_DISK
494
+        local ironic_ephemeral_disk=$IRONIC_VM_EPHEMERAL_DISK
495
+        local ironic_hwinfo_file=$IRONIC_VM_MACS_CSV_FILE
496
+        local node_options="\
494 497
             -i $_IRONIC_DEPLOY_KERNEL_KEY=$IRONIC_DEPLOY_KERNEL_ID \
495 498
             -i $_IRONIC_DEPLOY_RAMDISK_KEY=$IRONIC_DEPLOY_RAMDISK_ID \
496 499
             -i ssh_virt_type=$IRONIC_SSH_VIRT_TYPE \
497 500
             -i ssh_address=$IRONIC_VM_SSH_ADDRESS \
498 501
             -i ssh_port=$IRONIC_VM_SSH_PORT \
499 502
             -i ssh_username=$IRONIC_SSH_USERNAME \
500
-            -i ssh_key_filename=$IRONIC_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME \
501
-            -p cpus=$IRONIC_VM_SPECS_CPU \
502
-            -p memory_mb=$IRONIC_VM_SPECS_RAM \
503
-            -p local_gb=$IRONIC_VM_SPECS_DISK \
503
+            -i ssh_key_filename=$IRONIC_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME"
504
+    else
505
+        local ironic_node_cpu=$IRONIC_HW_NODE_CPU
506
+        local ironic_node_ram=$IRONIC_HW_NODE_RAM
507
+        local ironic_node_disk=$IRONIC_HW_NODE_DISK
508
+        local ironic_ephemeral_disk=$IRONIC_HW_EPHEMERAL_DISK
509
+        if [[ -z "${IRONIC_DEPLOY_DRIVER##*_ipmitool}" ]]; then
510
+            local ironic_hwinfo_file=$IRONIC_IPMIINFO_FILE
511
+        fi
512
+    fi
513
+
514
+    while read hardware_info; do
515
+        if ! is_ironic_hardware; then
516
+            local mac_address=$hardware_info
517
+        elif [[ -z "${IRONIC_DEPLOY_DRIVER##*_ipmitool}" ]]; then
518
+            local ipmi_address=$(echo $hardware_info |awk  '{print $1}')
519
+            local mac_address=$(echo $hardware_info |awk '{print $2}')
520
+            local ironic_ipmi_username=$(echo $hardware_info |awk '{print $3}')
521
+            local ironic_ipmi_passwd=$(echo $hardware_info |awk '{print $4}')
522
+            # Currently we require all hardware platform have same CPU/RAM/DISK info
523
+            # in future, this can be enhanced to support different type, and then
524
+            # we create the bare metal flavor with minimum value
525
+            local node_options="-i ipmi_address=$ipmi_address -i ipmi_password=$ironic_ipmi_passwd\
526
+                -i ipmi_username=$ironic_ipmi_username"
527
+        fi
528
+
529
+        local node_id=$(ironic node-create --chassis_uuid $chassis_id \
530
+            --driver $IRONIC_DEPLOY_DRIVER \
531
+            -p cpus=$ironic_node_cpu\
532
+            -p memory_mb=$ironic_node_ram\
533
+            -p local_gb=$ironic_node_disk\
504 534
             -p cpu_arch=x86_64 \
535
+            $node_options \
505 536
             | grep " uuid " | get_field 2)
506 537
 
507
-        ironic port-create --address $MAC --node_uuid $node_id
538
+        ironic port-create --address $mac_address --node_uuid $node_id
508 539
 
509 540
         idx=$((idx+1))
510
-    done < $IRONIC_VM_MACS_CSV_FILE
541
+    done < $ironic_hwinfo_file
511 542
 
512 543
     # create the nova flavor
513 544
     # NOTE(adam_g): Attempting to use an autogenerated UUID for flavor id here uncovered
514 545
     # bug (LP: #1333852) in Trove.  This can be changed to use an auto flavor id when the
515 546
     # bug is fixed in Juno.
516
-    local adjusted_disk=$(($IRONIC_VM_SPECS_DISK - $IRONIC_VM_EPHEMERAL_DISK))
517
-    nova flavor-create --ephemeral $IRONIC_VM_EPHEMERAL_DISK baremetal 551 $IRONIC_VM_SPECS_RAM $adjusted_disk $IRONIC_VM_SPECS_CPU
547
+    local adjusted_disk=$(($ironic_node_disk - $ironic_ephemeral_disk))
548
+    nova flavor-create --ephemeral $ironic_ephemeral_disk baremetal 551 $ironic_node_ram $adjusted_disk $ironic_node_cpu
518 549
 
519 550
     # TODO(lucasagomes): Remove the 'baremetal:deploy_kernel_id'
520 551
     # and 'baremetal:deploy_ramdisk_id' parameters
... ...
@@ -662,11 +711,15 @@ function upload_baremetal_ironic_deploy {
662 662
 
663 663
 function prepare_baremetal_basic_ops {
664 664
     upload_baremetal_ironic_deploy
665
-    create_bridge_and_vms
666
-    enroll_vms
665
+    if ! is_ironic_hardware; then
666
+        create_bridge_and_vms
667
+    fi
668
+    enroll_nodes
667 669
     configure_tftpd
668 670
     configure_iptables
669
-    configure_ironic_auxiliary
671
+    if ! is_ironic_hardware; then
672
+        configure_ironic_auxiliary
673
+    fi
670 674
 }
671 675
 
672 676
 function cleanup_baremetal_basic_ops {
... ...
@@ -523,7 +523,7 @@ function create_neutron_initial_network {
523 523
         die_if_not_set $LINENO PHYSICAL_NETWORK "You must specify the PHYSICAL_NETWORK"
524 524
         die_if_not_set $LINENO PROVIDER_NETWORK_TYPE "You must specifiy the PROVIDER_NETWORK_TYPE"
525 525
         NET_ID=$(neutron net-create $PHYSICAL_NETWORK --tenant_id $TENANT_ID --provider:network_type $PROVIDER_NETWORK_TYPE --provider:physical_network "$PHYSICAL_NETWORK" ${SEGMENTATION_ID:+--provider:segmentation_id $SEGMENTATION_ID} --shared | grep ' id ' | get_field 2)
526
-        SUBNET_ID=$(neutron subnet-create --tenant_id $TENANT_ID --ip_version 4 ${ALLOCATION_POOL:+--allocation-pool $ALLOCATION_POOL} --name $PROVIDER_SUBNET_NAME $NET_ID $FIXED_RANGE | grep ' id ' | get_field 2)
526
+        SUBNET_ID=$(neutron subnet-create --tenant_id $TENANT_ID --ip_version 4 ${ALLOCATION_POOL:+--allocation-pool $ALLOCATION_POOL} --name $PROVIDER_SUBNET_NAME --gateway $NETWORK_GATEWAY $NET_ID $FIXED_RANGE | grep ' id ' | get_field 2)
527 527
         SUBNET_V6_ID=$(neutron subnet-create --tenant_id $TENANT_ID --ip_version 6 --ipv6-address-mode slaac --gateway $V6_NETWORK_GATEWAY --name $PROVIDER_SUBNET_NAME_V6 $NET_ID $FIXED_RANGE_V6 | grep 'id' | get_field 2)
528 528
         sudo ip link set $OVS_PHYSICAL_BRIDGE up
529 529
         sudo ip link set br-int up
... ...
@@ -678,6 +678,13 @@ function start_neutron_agents {
678 678
         sudo ip link set $OVS_PHYSICAL_BRIDGE up
679 679
         sudo ip link set br-int up
680 680
         sudo ip link set $PUBLIC_INTERFACE up
681
+        if is_ironic_hardware; then
682
+            for IP in $(ip addr show dev $PUBLIC_INTERFACE | grep ' inet ' | awk '{print $2}'); do
683
+                sudo ip addr del $IP dev $PUBLIC_INTERFACE
684
+                sudo ip addr add $IP dev $OVS_PHYSICAL_BRIDGE
685
+            done
686
+            sudo route add -net $FIXED_RANGE gw $NETWORK_GATEWAY dev $OVS_PHYSICAL_BRIDGE
687
+        fi
681 688
     fi
682 689
 
683 690
     if is_service_enabled q-vpn; then
... ...
@@ -729,6 +736,14 @@ function stop_neutron {
729 729
 # cleanup_neutron() - Remove residual data files, anything left over from previous
730 730
 # runs that a clean run would need to clean up
731 731
 function cleanup_neutron {
732
+    if [[ is_provider_network && is_ironic_hardware ]]; then
733
+        for IP in $(ip addr show dev $OVS_PHYSICAL_BRIDGE | grep ' inet ' | awk '{print $2}'); do
734
+            sudo ip addr del $IP dev $OVS_PHYSICAL_BRIDGE
735
+            sudo ip addr add $IP dev $PUBLIC_INTERFACE
736
+        done
737
+        sudo route del -net $FIXED_RANGE gw $NETWORK_GATEWAY dev $OVS_PHYSICAL_BRIDGE
738
+    fi
739
+
732 740
     if is_neutron_ovs_base_plugin; then
733 741
         neutron_ovs_base_cleanup
734 742
     fi