summaryrefslogtreecommitdiff
path: root/devstack/tools/ironic/scripts/create-node.sh
blob: a2645228244816efd121b8154327e34a42c2e748 (plain)
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
#!/usr/bin/env bash

# **create-nodes**

# Creates baremetal poseur nodes for ironic testing purposes

set -ex

# Make tracing more educational
export PS4='+ ${BASH_SOURCE:-}:${FUNCNAME[0]:-}:L${LINENO:-}:   '

# Keep track of the DevStack directory
TOP_DIR=$(cd $(dirname "$0")/.. && pwd)

while getopts "n:c:i:m:M:d:a:b:e:E:p:o:f:l:L:N:A:D:" arg; do
    case $arg in
        n) NAME=$OPTARG;;
        c) CPU=$OPTARG;;
        i) INTERFACE_COUNT=$OPTARG;;
        M) INTERFACE_MTU=$OPTARG;;
        m) MEM=$(( 1024 * OPTARG ));;
        # Extra G to allow fuzz for partition table : flavor size and registered
        # size need to be different to actual size.
        d) DISK=$(( OPTARG + 1 ));;
        a) ARCH=$OPTARG;;
        b) BRIDGE=$OPTARG;;
        e) EMULATOR=$OPTARG;;
        E) ENGINE=$OPTARG;;
        p) VBMC_PORT=$OPTARG;;
        o) PDU_OUTLET=$OPTARG;;
        f) DISK_FORMAT=$OPTARG;;
        l) LOGDIR=$OPTARG;;
        L) UEFI_LOADER=$OPTARG;;
        N) UEFI_NVRAM=$OPTARG;;
        A) MAC_ADDRESS=$OPTARG;;
        D) NIC_DRIVER=$OPTARG;;
    esac
done

shift $(( $OPTIND - 1 ))

if [ -z "$UEFI_LOADER" ] && [ ! -z "$UEFI_NVRAM" ]; then
    echo "Parameter -N (UEFI NVRAM) cannot be used without -L (UEFI Loader)"
    exit 1
fi

LIBVIRT_NIC_DRIVER=${NIC_DRIVER:-"e1000"}
LIBVIRT_STORAGE_POOL=${LIBVIRT_STORAGE_POOL:-"default"}
LIBVIRT_CONNECT_URI=${LIBVIRT_CONNECT_URI:-"qemu:///system"}

export VIRSH_DEFAULT_CONNECT_URI=$LIBVIRT_CONNECT_URI

if ! virsh pool-list --all | grep -q $LIBVIRT_STORAGE_POOL; then
    virsh pool-define-as --name $LIBVIRT_STORAGE_POOL dir --target /var/lib/libvirt/images >&2
    virsh pool-autostart $LIBVIRT_STORAGE_POOL >&2
    virsh pool-start $LIBVIRT_STORAGE_POOL >&2
fi

pool_state=$(virsh pool-info $LIBVIRT_STORAGE_POOL | grep State | awk '{ print $2 }')
if [ "$pool_state" != "running" ] ; then
    [ ! -d /var/lib/libvirt/images ] && sudo mkdir /var/lib/libvirt/images
    virsh pool-start $LIBVIRT_STORAGE_POOL >&2
fi

if [ -n "$LOGDIR" ] ; then
    mkdir -p "$LOGDIR"
fi

PREALLOC=
if [ -f /etc/debian_version -a "$DISK_FORMAT" == "qcow2" ]; then
    PREALLOC="--prealloc-metadata"
fi

if [ -n "$LOGDIR" ] ; then
    VM_LOGGING="--console-log $LOGDIR/${NAME}_console.log"
else
    VM_LOGGING=""
fi
VOL_NAME="${NAME}.${DISK_FORMAT}"

UEFI_OPTS=""
if [ ! -z "$UEFI_LOADER" ]; then
    UEFI_OPTS="--uefi-loader $UEFI_LOADER"

    if [ ! -z "$UEFI_NVRAM" ]; then
        UEFI_OPTS+=" --uefi-nvram $UEFI_NVRAM"
    fi
fi

# Create bridge and add VM interface to it.
# Additional interface will be added to this bridge and
# it will be plugged to OVS.
# This is needed in order to have interface in OVS even
# when VM is in shutdown state
INTERFACE_COUNT=${INTERFACE_COUNT:-1}

for int in $(seq 1 $INTERFACE_COUNT); do
    tapif=tap-${NAME}i${int}
    ovsif=ovs-${NAME}i${int}
    # NOTE(vsaienko) use veth pair here to ensure that interface
    # exists in OVS even when VM is powered off.
    sudo ip link add dev $tapif type veth peer name $ovsif
    for l in $tapif $ovsif; do
        sudo ip link set dev $l up
        sudo ip link set $l mtu $INTERFACE_MTU
    done
    sudo ovs-vsctl add-port $BRIDGE $ovsif
done

if [ -n "$MAC_ADDRESS" ] ; then
    MAC_ADDRESS="--mac $MAC_ADDRESS"
fi

if ! virsh list --all | grep -q $NAME; then
    virsh vol-list --pool $LIBVIRT_STORAGE_POOL | grep -q $VOL_NAME &&
        virsh vol-delete $VOL_NAME --pool $LIBVIRT_STORAGE_POOL >&2
    virsh vol-create-as $LIBVIRT_STORAGE_POOL ${VOL_NAME} ${DISK}G --format $DISK_FORMAT $PREALLOC >&2
    volume_path=$(virsh vol-path --pool $LIBVIRT_STORAGE_POOL $VOL_NAME)
    # Pre-touch the VM to set +C, as it can only be set on empty files.
    sudo touch "$volume_path"
    sudo chattr +C "$volume_path" || true
    vm_opts=""
    if [[ -n "$EMULATOR" ]]; then
        vm_opts+="--emulator $EMULATOR "
    fi
    $PYTHON $TOP_DIR/scripts/configure-vm.py \
        --bootdev network --name $NAME --image "$volume_path" \
        --arch $ARCH --cpus $CPU --memory $MEM --libvirt-nic-driver $LIBVIRT_NIC_DRIVER \
        --disk-format $DISK_FORMAT $VM_LOGGING --engine $ENGINE $UEFI_OPTS $vm_opts \
        --interface-count $INTERFACE_COUNT $MAC_ADDRESS >&2

    # Createa Virtual BMC for the node if IPMI is used
    if [[ $(type -P vbmc) != "" ]]; then
        sudo vbmc add $NAME --port $VBMC_PORT
        sudo vbmc start $NAME
    fi
fi

# echo mac in format mac1,ovs-node-0i1;mac2,ovs-node-0i2;...;macN,ovs-node0iN
VM_MAC=$(echo -n $(virsh domiflist $NAME |awk '/tap-/{print $5","$3}')|tr ' ' ';' |sed s/tap-/ovs-/g)
echo -n "$VM_MAC $VBMC_PORT $PDU_OUTLET"