blob: 1aa85eab80fa87b576efa976fc06cbb07ab35d4a [file] [log] [blame]
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +03001# lib/ironic
2# Functions to control the configuration and operation of the **Ironic** service
3
4# Dependencies:
Adam Spiers6a5aa7c2013-10-24 11:27:02 +01005#
6# - ``functions`` file
7# - ``DEST``, ``DATA_DIR``, ``STACK_USER`` must be defined
8# - ``SERVICE_{TENANT_NAME|PASSWORD}`` must be defined
9# - ``SERVICE_HOST``
10# - ``KEYSTONE_TOKEN_FORMAT`` must be defined
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +030011
12# ``stack.sh`` calls the entry points in this order:
13#
Adam Spiers6a5aa7c2013-10-24 11:27:02 +010014# - install_ironic
15# - install_ironicclient
16# - init_ironic
17# - start_ironic
18# - stop_ironic
19# - cleanup_ironic
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +030020
Alexander Gordeev06fb29c2014-01-31 18:02:07 +040021# Save trace and pipefail settings
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +030022XTRACE=$(set +o | grep xtrace)
Alexander Gordeev06fb29c2014-01-31 18:02:07 +040023PIPEFAIL=$(set +o | grep pipefail)
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +030024set +o xtrace
Alexander Gordeev06fb29c2014-01-31 18:02:07 +040025set +o pipefail
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +030026
27# Defaults
28# --------
29
30# Set up default directories
31IRONIC_DIR=$DEST/ironic
Alexander Gordeev06fb29c2014-01-31 18:02:07 +040032IRONIC_DATA_DIR=$DATA_DIR/ironic
33IRONIC_STATE_PATH=/var/lib/ironic
Roman Prykhodchenko43e00662013-10-15 17:03:15 +030034IRONICCLIENT_DIR=$DEST/python-ironicclient
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +030035IRONIC_AUTH_CACHE_DIR=${IRONIC_AUTH_CACHE_DIR:-/var/cache/ironic}
36IRONIC_CONF_DIR=${IRONIC_CONF_DIR:-/etc/ironic}
37IRONIC_CONF_FILE=$IRONIC_CONF_DIR/ironic.conf
38IRONIC_ROOTWRAP_CONF=$IRONIC_CONF_DIR/rootwrap.conf
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +030039IRONIC_POLICY_JSON=$IRONIC_CONF_DIR/policy.json
40
Alexander Gordeev06fb29c2014-01-31 18:02:07 +040041# Set up defaults for functional / integration testing
42IRONIC_SCRIPTS_DIR=${IRONIC_SCRIPTS_DIR:-$TOP_DIR/tools/ironic/scripts}
43IRONIC_TEMPLATES_DIR=${IRONIC_TEMPLATES_DIR:-$TOP_DIR/tools/ironic/templates}
44IRONIC_BAREMETAL_BASIC_OPS=$(trueorfalse False $IRONIC_BAREMETAL_BASIC_OPS)
Roman Prykhodchenkodc97a0e2014-04-08 14:19:58 +030045IRONIC_DRIVERS_WHITELIST=${IRONIC_DRIVERS_WHITELIST:-fake,pxe_ssh}
Alexander Gordeev06fb29c2014-01-31 18:02:07 +040046IRONIC_SSH_USERNAME=${IRONIC_SSH_USERNAME:-`whoami`}
47IRONIC_SSH_KEY_DIR=${IRONIC_SSH_KEY_DIR:-$IRONIC_DATA_DIR/ssh_keys}
48IRONIC_SSH_KEY_FILENAME=${IRONIC_SSH_KEY_FILENAME:-ironic_key}
49IRONIC_KEY_FILE=$IRONIC_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME
50IRONIC_SSH_VIRT_TYPE=${IRONIC_SSH_VIRT_TYPE:-virsh}
51IRONIC_TFTPBOOT_DIR=${IRONIC_TFTPBOOT_DIR:-$IRONIC_DATA_DIR/tftpboot}
52IRONIC_VM_SSH_PORT=${IRONIC_VM_SSH_PORT:-2222}
53IRONIC_VM_SSH_ADDRESS=${IRONIC_VM_SSH_ADDRESS:-$HOST_IP}
54IRONIC_VM_COUNT=${IRONIC_VM_COUNT:-1}
55IRONIC_VM_SPECS_CPU=${IRONIC_VM_SPECS_CPU:-1}
Alexander Gordeev84d0ec52014-03-17 17:58:54 +040056# NOTE(agordeev): both ubuntu and fedora deploy images won't work with 256MB of RAM.
57# System halts and throws kernel panic during initramfs unpacking.
58# Ubuntu needs at least 384MB, but fedora requires 448.
59# So placing 512 here to satisfy both.
60IRONIC_VM_SPECS_RAM=${IRONIC_VM_SPECS_RAM:-512}
Alexander Gordeev06fb29c2014-01-31 18:02:07 +040061IRONIC_VM_SPECS_DISK=${IRONIC_VM_SPECS_DISK:-10}
62IRONIC_VM_EMULATOR=${IRONIC_VM_EMULATOR:-/usr/bin/qemu-system-x86_64}
63IRONIC_VM_NETWORK_BRIDGE=${IRONIC_VM_NETWORK_BRIDGE:-brbm}
64IRONIC_VM_NETWORK_RANGE=${IRONIC_VM_NETWORK_RANGE:-192.0.2.0/24}
65IRONIC_VM_MACS_CSV_FILE=${IRONIC_VM_MACS_CSV_FILE:-$IRONIC_DATA_DIR/ironic_macs.csv}
66IRONIC_AUTHORIZED_KEYS_FILE=${IRONIC_AUTHORIZED_KEYS_FILE:-$HOME/.ssh/authorized_keys}
67
Adam Gandelman8af6fae2014-04-11 17:06:14 -070068# By default, baremetal VMs will console output to file.
69IRONIC_VM_LOG_CONSOLE=${IRONIC_VM_LOG_CONSOLE:-True}
70IRONIC_VM_LOG_DIR=${IRONIC_VM_LOG_DIR:-$IRONIC_DATA_DIR/logs/}
71
Alexander Gordeevf177f722014-03-14 18:44:48 +040072DIB_DIR=${DIB_DIR:-$DEST/diskimage-builder}
73
74# Use DIB to create deploy ramdisk and kernel.
75IRONIC_BUILD_DEPLOY_RAMDISK=`trueorfalse True $IRONIC_BUILD_DEPLOY_RAMDISK`
76# If not use DIB, these files are used as deploy ramdisk/kernel.
77# (The value must be a absolute path)
78IRONIC_DEPLOY_RAMDISK=${IRONIC_DEPLOY_RAMDISK:-}
79IRONIC_DEPLOY_KERNEL=${IRONIC_DEPLOY_KERNEL:-}
80IRONIC_DEPLOY_ELEMENT=${IRONIC_DEPLOY_ELEMENT:-deploy-ironic}
81
82#TODO(agordeev): replace 'ubuntu' with host distro name getting
83IRONIC_DEPLOY_FLAVOR=${IRONIC_DEPLOY_FLAVOR:-ubuntu $IRONIC_DEPLOY_ELEMENT}
84
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +030085# Support entry points installation of console scripts
86IRONIC_BIN_DIR=$(get_python_exec_prefix)
87
88# Ironic connection info. Note the port must be specified.
89IRONIC_SERVICE_PROTOCOL=http
90IRONIC_HOSTPORT=${IRONIC_HOSTPORT:-$SERVICE_HOST:6385}
91
Dean Troyer4237f592014-01-29 16:22:11 -060092# Tell Tempest this project is present
93TEMPEST_SERVICES+=,ironic
94
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +030095
96# Functions
97# ---------
98
Dean Troyer1023ff72014-01-27 14:56:44 -060099# Test if any Ironic services are enabled
100# is_ironic_enabled
101function is_ironic_enabled {
102 [[ ,${ENABLED_SERVICES} =~ ,"ir-" ]] && return 0
103 return 1
104}
105
Roman Prykhodchenko43e00662013-10-15 17:03:15 +0300106# install_ironic() - Collect source and prepare
Ian Wienandaee18c72014-02-21 15:35:08 +1100107function install_ironic {
Roman Prykhodchenko43e00662013-10-15 17:03:15 +0300108 git_clone $IRONIC_REPO $IRONIC_DIR $IRONIC_BRANCH
109 setup_develop $IRONIC_DIR
110}
111
112# install_ironicclient() - Collect sources and prepare
Ian Wienandaee18c72014-02-21 15:35:08 +1100113function install_ironicclient {
Roman Prykhodchenko43e00662013-10-15 17:03:15 +0300114 git_clone $IRONICCLIENT_REPO $IRONICCLIENT_DIR $IRONICCLIENT_BRANCH
115 setup_develop $IRONICCLIENT_DIR
116}
117
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300118# cleanup_ironic() - Remove residual data files, anything left over from previous
119# runs that would need to clean up.
Ian Wienandaee18c72014-02-21 15:35:08 +1100120function cleanup_ironic {
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300121 sudo rm -rf $IRONIC_AUTH_CACHE_DIR
122}
123
124# configure_ironic() - Set config files, create data dirs, etc
Ian Wienandaee18c72014-02-21 15:35:08 +1100125function configure_ironic {
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300126 if [[ ! -d $IRONIC_CONF_DIR ]]; then
127 sudo mkdir -p $IRONIC_CONF_DIR
128 fi
129 sudo chown $STACK_USER $IRONIC_CONF_DIR
130
131 # Copy over ironic configuration file and configure common parameters.
132 cp $IRONIC_DIR/etc/ironic/ironic.conf.sample $IRONIC_CONF_FILE
133 iniset $IRONIC_CONF_FILE DEFAULT debug True
134 inicomment $IRONIC_CONF_FILE DEFAULT log_file
135 iniset $IRONIC_CONF_FILE DEFAULT sql_connection `database_connection_url ironic`
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400136 iniset $IRONIC_CONF_FILE DEFAULT state_path $IRONIC_STATE_PATH
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300137 iniset $IRONIC_CONF_FILE DEFAULT use_syslog $SYSLOG
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300138 # Configure Ironic conductor, if it was enabled.
139 if is_service_enabled ir-cond; then
140 configure_ironic_conductor
141 fi
142
143 # Configure Ironic API, if it was enabled.
144 if is_service_enabled ir-api; then
145 configure_ironic_api
146 fi
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400147
148 if [[ "$IRONIC_BAREMETAL_BASIC_OPS" == "True" ]]; then
149 configure_ironic_auxiliary
150 fi
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300151}
152
153# configure_ironic_api() - Is used by configure_ironic(). Performs
154# API specific configuration.
Ian Wienandaee18c72014-02-21 15:35:08 +1100155function configure_ironic_api {
Roman Prykhodchenkoc48c3122013-10-01 17:19:05 +0300156 iniset $IRONIC_CONF_FILE DEFAULT auth_strategy keystone
157 iniset $IRONIC_CONF_FILE DEFAULT policy_file $IRONIC_POLICY_JSON
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300158 iniset $IRONIC_CONF_FILE keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
159 iniset $IRONIC_CONF_FILE keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
160 iniset $IRONIC_CONF_FILE keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
Jamie Lennoxbd24a8d2013-09-20 16:26:42 +1000161 iniset $IRONIC_CONF_FILE keystone_authtoken cafile $KEYSTONE_SSL_CA
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300162 iniset $IRONIC_CONF_FILE keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/
163 iniset $IRONIC_CONF_FILE keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
164 iniset $IRONIC_CONF_FILE keystone_authtoken admin_user ironic
165 iniset $IRONIC_CONF_FILE keystone_authtoken admin_password $SERVICE_PASSWORD
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300166 iniset_rpc_backend ironic $IRONIC_CONF_FILE DEFAULT
167 iniset $IRONIC_CONF_FILE keystone_authtoken signing_dir $IRONIC_AUTH_CACHE_DIR/api
168
169 cp -p $IRONIC_DIR/etc/ironic/policy.json $IRONIC_POLICY_JSON
170}
171
172# configure_ironic_conductor() - Is used by configure_ironic().
173# Sets conductor specific settings.
Ian Wienandaee18c72014-02-21 15:35:08 +1100174function configure_ironic_conductor {
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300175 cp $IRONIC_DIR/etc/ironic/rootwrap.conf $IRONIC_ROOTWRAP_CONF
Lucas Alvares Gomes279295c2014-01-14 11:37:51 +0000176 cp -r $IRONIC_DIR/etc/ironic/rootwrap.d $IRONIC_CONF_DIR
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300177
Alexander Gordeeva67cb1a2014-03-04 18:38:33 +0400178 iniset $IRONIC_CONF_FILE DEFAULT rootwrap_config $IRONIC_ROOTWRAP_CONF
Roman Prykhodchenkodc97a0e2014-04-08 14:19:58 +0300179 iniset $IRONIC_CONF_FILE DEFAULT drivers_whitelist $IRONIC_DRIVERS_WHITELIST
Adam Gandelmand3011982014-03-24 13:55:34 -0700180 iniset $IRONIC_CONF_FILE conductor api_url http://$HOST_IP:6385
181 iniset $IRONIC_CONF_FILE pxe tftp_server $HOST_IP
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400182 iniset $IRONIC_CONF_FILE pxe tftp_root $IRONIC_TFTPBOOT_DIR
183 iniset $IRONIC_CONF_FILE pxe tftp_master_path $IRONIC_TFTPBOOT_DIR/master_images
Adam Gandelman8af6fae2014-04-11 17:06:14 -0700184 if [[ "$IRONIC_VM_LOG_CONSOLE" == "True" ]] ; then
185 iniset $IRONIC_CONF_FILE pxe pxe_append_params "nofb nomodeset vga=normal console=ttyS0"
186 fi
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300187}
188
189# create_ironic_cache_dir() - Part of the init_ironic() process
Ian Wienandaee18c72014-02-21 15:35:08 +1100190function create_ironic_cache_dir {
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300191 # Create cache dir
192 sudo mkdir -p $IRONIC_AUTH_CACHE_DIR/api
193 sudo chown $STACK_USER $IRONIC_AUTH_CACHE_DIR/api
194 rm -f $IRONIC_AUTH_CACHE_DIR/api/*
195 sudo mkdir -p $IRONIC_AUTH_CACHE_DIR/registry
196 sudo chown $STACK_USER $IRONIC_AUTH_CACHE_DIR/registry
197 rm -f $IRONIC_AUTH_CACHE_DIR/registry/*
198}
199
200# create_ironic_accounts() - Set up common required ironic accounts
201
202# Tenant User Roles
203# ------------------------------------------------------------------
204# service ironic admin # if enabled
Ian Wienandaee18c72014-02-21 15:35:08 +1100205function create_ironic_accounts {
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300206
Steve Martinelli19685422014-01-24 13:02:26 -0600207 SERVICE_TENANT=$(openstack project list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
208 ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300209
210 # Ironic
211 if [[ "$ENABLED_SERVICES" =~ "ir-api" ]]; then
Steve Martinelli19685422014-01-24 13:02:26 -0600212 IRONIC_USER=$(openstack user create \
213 ironic \
214 --password "$SERVICE_PASSWORD" \
215 --project $SERVICE_TENANT \
216 --email ironic@example.com \
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300217 | grep " id " | get_field 2)
Steve Martinelli19685422014-01-24 13:02:26 -0600218 openstack role add \
219 $ADMIN_ROLE \
220 --project $SERVICE_TENANT \
221 --user $IRONIC_USER
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300222 if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
Steve Martinelli19685422014-01-24 13:02:26 -0600223 IRONIC_SERVICE=$(openstack service create \
224 ironic \
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300225 --type=baremetal \
226 --description="Ironic baremetal provisioning service" \
227 | grep " id " | get_field 2)
Steve Martinelli19685422014-01-24 13:02:26 -0600228 openstack endpoint create \
229 $IRONIC_SERVICE \
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300230 --region RegionOne \
Roman Prykhodchenkof5002ef2013-09-24 19:09:26 +0300231 --publicurl "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT" \
232 --adminurl "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT" \
233 --internalurl "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT"
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300234 fi
235 fi
236}
237
238
239# init_ironic() - Initialize databases, etc.
Ian Wienandaee18c72014-02-21 15:35:08 +1100240function init_ironic {
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300241 # (Re)create ironic database
242 recreate_database ironic utf8
243
244 # Migrate ironic database
245 $IRONIC_BIN_DIR/ironic-dbsync
246
247 create_ironic_cache_dir
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300248}
249
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300250# start_ironic() - Start running processes, including screen
Ian Wienandaee18c72014-02-21 15:35:08 +1100251function start_ironic {
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300252 # Start Ironic API server, if enabled.
253 if is_service_enabled ir-api; then
254 start_ironic_api
255 fi
256
257 # Start Ironic conductor, if enabled.
258 if is_service_enabled ir-cond; then
259 start_ironic_conductor
260 fi
261}
262
263# start_ironic_api() - Used by start_ironic().
264# Starts Ironic API server.
Ian Wienandaee18c72014-02-21 15:35:08 +1100265function start_ironic_api {
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300266 screen_it ir-api "cd $IRONIC_DIR; $IRONIC_BIN_DIR/ironic-api --config-file=$IRONIC_CONF_FILE"
267 echo "Waiting for ir-api ($IRONIC_HOSTPORT) to start..."
JUN JIE NAN0aa85342013-09-13 15:47:09 +0800268 if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- http://$IRONIC_HOSTPORT; do sleep 1; done"; then
Sean Dague101b4242013-10-22 08:47:11 -0400269 die $LINENO "ir-api did not start"
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300270 fi
271}
272
273# start_ironic_conductor() - Used by start_ironic().
274# Starts Ironic conductor.
Ian Wienandaee18c72014-02-21 15:35:08 +1100275function start_ironic_conductor {
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300276 screen_it ir-cond "cd $IRONIC_DIR; $IRONIC_BIN_DIR/ironic-conductor --config-file=$IRONIC_CONF_FILE"
277 # TODO(romcheg): Find a way to check whether the conductor has started.
278}
279
280# stop_ironic() - Stop running processes
Ian Wienandaee18c72014-02-21 15:35:08 +1100281function stop_ironic {
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300282 # Kill the Ironic screen windows
283 screen -S $SCREEN_NAME -p ir-api -X kill
284 screen -S $SCREEN_NAME -p ir-cond -X kill
285}
286
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400287function is_ironic {
288 if ( is_service_enabled ir-cond && is_service_enabled ir-api ); then
289 return 0
290 fi
291 return 1
292}
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300293
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400294function configure_ironic_dirs {
295 sudo mkdir -p $IRONIC_DATA_DIR
296 sudo mkdir -p $IRONIC_STATE_PATH
297 sudo mkdir -p $IRONIC_TFTPBOOT_DIR
298 sudo chown -R $STACK_USER $IRONIC_DATA_DIR $IRONIC_STATE_PATH
299 sudo chown -R $STACK_USER:$LIBVIRT_GROUP $IRONIC_TFTPBOOT_DIR
300 if is_ubuntu; then
301 PXEBIN=/usr/lib/syslinux/pxelinux.0
302 elif is_fedora; then
303 PXEBIN=/usr/share/syslinux/pxelinux.0
304 fi
305 if [ ! -f $PXEBIN ]; then
306 die $LINENO "pxelinux.0 (from SYSLINUX) not found."
307 fi
308
309 cp $PXEBIN $IRONIC_TFTPBOOT_DIR
310 mkdir -p $IRONIC_TFTPBOOT_DIR/pxelinux.cfg
311}
312
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400313function create_bridge_and_vms {
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400314 # Call libvirt setup scripts in a new shell to ensure any new group membership
315 sudo su $STACK_USER -c "$IRONIC_SCRIPTS_DIR/setup-network"
Adam Gandelman8af6fae2014-04-11 17:06:14 -0700316 if [[ "$IRONIC_VM_LOG_CONSOLE" == "True" ]] ; then
317 LOG_ARG="$IRONIC_VM_LOG_DIR"
318 else
319 LOG_ARG=""
320 fi
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400321 sudo su $STACK_USER -c "$IRONIC_SCRIPTS_DIR/create-nodes \
322 $IRONIC_VM_SPECS_CPU $IRONIC_VM_SPECS_RAM $IRONIC_VM_SPECS_DISK \
Adam Gandelman8af6fae2014-04-11 17:06:14 -0700323 amd64 $IRONIC_VM_COUNT $IRONIC_VM_NETWORK_BRIDGE $IRONIC_VM_EMULATOR \
324 $LOG_ARG" >> $IRONIC_VM_MACS_CSV_FILE
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400325}
326
327function enroll_vms {
328
329 CHASSIS_ID=$(ironic chassis-create -d "ironic test chassis" | grep " uuid " | get_field 2)
330 IRONIC_NET_ID=$(neutron net-list | grep private | get_field 1)
331 local idx=0
332
333 # work around; need to know what netns neutron uses for private network
334 neutron port-create private
335
336 while read MAC; do
337
338 NODE_ID=$(ironic node-create --chassis_uuid $CHASSIS_ID --driver pxe_ssh \
339 -i ssh_virt_type=$IRONIC_SSH_VIRT_TYPE \
340 -i ssh_address=$IRONIC_VM_SSH_ADDRESS \
341 -i ssh_port=$IRONIC_VM_SSH_PORT \
342 -i ssh_username=$IRONIC_SSH_USERNAME \
343 -i ssh_key_filename=$IRONIC_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME \
344 -p cpus=$IRONIC_VM_SPECS_CPU \
345 -p memory_mb=$IRONIC_VM_SPECS_RAM \
346 -p local_gb=$IRONIC_VM_SPECS_DISK \
347 -p cpu_arch=x86_64 \
348 | grep " uuid " | get_field 2)
349
350 ironic port-create --address $MAC --node_uuid $NODE_ID
351
352 idx=$((idx+1))
353
354 done < $IRONIC_VM_MACS_CSV_FILE
355
356 # create the nova flavor
357 nova flavor-create baremetal auto $IRONIC_VM_SPECS_RAM $IRONIC_VM_SPECS_DISK $IRONIC_VM_SPECS_CPU
Alexander Gordeevf177f722014-03-14 18:44:48 +0400358 nova flavor-key baremetal set "cpu_arch"="x86_64" "baremetal:deploy_kernel_id"="$IRONIC_DEPLOY_KERNEL_ID" "baremetal:deploy_ramdisk_id"="$IRONIC_DEPLOY_RAMDISK_ID"
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400359
360 # intentional sleep to make sure the tag has been set to port
361 sleep 10
362 TAPDEV=$(sudo ip netns exec qdhcp-${IRONIC_NET_ID} ip link list | grep tap | cut -d':' -f2 | cut -b2-)
363 TAG_ID=$(sudo ovs-vsctl show |grep ${TAPDEV} -A1 -m1 | grep tag | cut -d':' -f2 | cut -b2-)
364
365 # make sure veth pair is not existing, otherwise delete its links
366 sudo ip link show ovs-tap1 && sudo ip link delete ovs-tap1
367 sudo ip link show brbm-tap1 && sudo ip link delete brbm-tap1
368 # create veth pair for future interconnection between br-int and brbm
369 sudo ip link add brbm-tap1 type veth peer name ovs-tap1
370 sudo ip link set dev brbm-tap1 up
371 sudo ip link set dev ovs-tap1 up
372
373 sudo ovs-vsctl -- --if-exists del-port ovs-tap1 -- add-port br-int ovs-tap1 tag=$TAG_ID
374 sudo ovs-vsctl -- --if-exists del-port brbm-tap1 -- add-port $IRONIC_VM_NETWORK_BRIDGE brbm-tap1
375}
376
377function configure_tftpd {
378 # enable tftp natting for allowing connections to SERVICE_HOST's tftp server
379 sudo modprobe nf_conntrack_tftp
380 sudo modprobe nf_nat_tftp
381
382 if is_ubuntu; then
383 PXEBIN=/usr/lib/syslinux/pxelinux.0
384 elif is_fedora; then
385 PXEBIN=/usr/share/syslinux/pxelinux.0
386 fi
387 if [ ! -f $PXEBIN ]; then
388 die $LINENO "pxelinux.0 (from SYSLINUX) not found."
389 fi
390
391 # stop tftpd and setup serving via xinetd
392 stop_service tftpd-hpa || true
393 [ -f /etc/init/tftpd-hpa.conf ] && echo "manual" | sudo tee /etc/init/tftpd-hpa.override
394 sudo cp $IRONIC_TEMPLATES_DIR/tftpd-xinetd.template /etc/xinetd.d/tftp
395 sudo sed -e "s|%TFTPBOOT_DIR%|$IRONIC_TFTPBOOT_DIR|g" -i /etc/xinetd.d/tftp
396
397 # setup tftp file mapping to satisfy requests at the root (booting) and
398 # /tftpboot/ sub-dir (as per deploy-ironic elements)
399 echo "r ^([^/]) $IRONIC_TFTPBOOT_DIR/\1" >$IRONIC_TFTPBOOT_DIR/map-file
400 echo "r ^(/tftpboot/) $IRONIC_TFTPBOOT_DIR/\2" >>$IRONIC_TFTPBOOT_DIR/map-file
401
402 chmod -R 0755 $IRONIC_TFTPBOOT_DIR
403 restart_service xinetd
404}
405
406function configure_ironic_ssh_keypair {
407 # Generating ssh key pair for stack user
408 if [[ ! -d $IRONIC_SSH_KEY_DIR ]]; then
409 mkdir -p $IRONIC_SSH_KEY_DIR
410 fi
411 if [[ ! -d $HOME/.ssh ]]; then
412 mkdir -p $HOME/.ssh
413 chmod 700 $HOME/.ssh
414 fi
415 echo -e 'n\n' | ssh-keygen -q -t rsa -P '' -f $IRONIC_KEY_FILE
416 cat $IRONIC_KEY_FILE.pub | tee -a $IRONIC_AUTHORIZED_KEYS_FILE
417}
418
419function ironic_ssh_check {
420 local KEY_FILE=$1
421 local FLOATING_IP=$2
422 local PORT=$3
423 local DEFAULT_INSTANCE_USER=$4
424 local ACTIVE_TIMEOUT=$5
425 if ! timeout $ACTIVE_TIMEOUT sh -c "while ! ssh -p $PORT -o StrictHostKeyChecking=no -i $KEY_FILE ${DEFAULT_INSTANCE_USER}@$FLOATING_IP echo success; do sleep 1; done"; then
426 die $LINENO "server didn't become ssh-able!"
427 fi
428}
429
430function configure_ironic_sshd {
431 # Ensure sshd server accepts connections from localhost only
432
433 SSH_CONFIG=/etc/ssh/sshd_config
434 HOST_PORT=$IRONIC_VM_SSH_ADDRESS:$IRONIC_VM_SSH_PORT
435 if ! sudo grep ListenAddress $SSH_CONFIG | grep $HOST_PORT; then
436 echo "ListenAddress $HOST_PORT" | sudo tee -a $SSH_CONFIG
437 fi
438
439 SSH_SERVICE_NAME=sshd
440 if is_ubuntu; then
441 SSH_SERVICE_NAME=ssh
442 fi
443
444 restart_service $SSH_SERVICE_NAME
445 # to ensure ssh service is up and running
446 sleep 3
447 ironic_ssh_check $IRONIC_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME $IRONIC_VM_SSH_ADDRESS $IRONIC_VM_SSH_PORT $IRONIC_SSH_USERNAME 10
448
449}
450
451function configure_ironic_auxiliary {
452 configure_ironic_dirs
453 configure_ironic_ssh_keypair
454 configure_ironic_sshd
455}
456
Alexander Gordeevf177f722014-03-14 18:44:48 +0400457# build deploy kernel+ramdisk, then upload them to glance
458# this function sets IRONIC_DEPLOY_KERNEL_ID and IRONIC_DEPLOY_RAMDISK_ID
459function upload_baremetal_ironic_deploy {
460 token=$1
461
462 if [ -z "$IRONIC_DEPLOY_KERNEL" -o -z "$IRONIC_DEPLOY_RAMDISK" ]; then
463 IRONIC_DEPLOY_KERNEL_PATH=$TOP_DIR/files/ir-deploy.kernel
464 IRONIC_DEPLOY_RAMDISK_PATH=$TOP_DIR/files/ir-deploy.initramfs
465 else
466 IRONIC_DEPLOY_KERNEL_PATH=$IRONIC_DEPLOY_KERNEL
467 IRONIC_DEPLOY_RAMDISK_PATH=$IRONIC_DEPLOY_RAMDISK
468 fi
469
470 if [ ! -e "$IRONIC_DEPLOY_RAMDISK_PATH" -o ! -e "$IRONIC_DEPLOY_KERNEL_PATH" ]; then
471 # files don't exist, need to build them
472 if [ "$IRONIC_BUILD_DEPLOY_RAMDISK" = "True" ]; then
473 # we can build them only if we're not offline
474 if [ "$OFFLINE" != "True" ]; then
475 $DIB_DIR/bin/ramdisk-image-create $IRONIC_DEPLOY_FLAVOR \
476 -o $TOP_DIR/files/ir-deploy
477 else
478 die $LINENO "Deploy kernel+ramdisk files don't exist and cannot be build in OFFLINE mode"
479 fi
480 else
481 die $LINENO "Deploy kernel+ramdisk files don't exist and their building was disabled explicitly by IRONIC_BUILD_DEPLOY_RAMDISK"
482 fi
483 fi
484
485 # load them into glance
486 IRONIC_DEPLOY_KERNEL_ID=$(glance \
487 --os-auth-token $token \
488 --os-image-url http://$GLANCE_HOSTPORT \
489 image-create \
490 --name $(basename $IRONIC_DEPLOY_KERNEL_PATH) \
491 --is-public True --disk-format=aki \
492 < $IRONIC_DEPLOY_KERNEL_PATH | grep ' id ' | get_field 2)
493 IRONIC_DEPLOY_RAMDISK_ID=$(glance \
494 --os-auth-token $token \
495 --os-image-url http://$GLANCE_HOSTPORT \
496 image-create \
497 --name $(basename $IRONIC_DEPLOY_RAMDISK_PATH) \
498 --is-public True --disk-format=ari \
499 < $IRONIC_DEPLOY_RAMDISK_PATH | grep ' id ' | get_field 2)
500}
501
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400502function prepare_baremetal_basic_ops {
503
504 # install diskimage-builder
Alexander Gordeevf177f722014-03-14 18:44:48 +0400505 git_clone $DIB_REPO $DIB_DIR $DIB_BRANCH
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400506
507 # make sure all needed service were enabled
508 for srv in nova glance key neutron; do
509 if ! is_service_enabled "$srv"; then
510 die $LINENO "$srv should be enabled for ironic tests"
511 fi
512 done
513
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400514 TOKEN=$(keystone token-get | grep ' id ' | get_field 2)
515 die_if_not_set $LINENO TOKEN "Keystone fail to get token"
516
517 echo_summary "Creating and uploading baremetal images for ironic"
518
519 # build and upload separate deploy kernel & ramdisk
Alexander Gordeevf177f722014-03-14 18:44:48 +0400520 upload_baremetal_ironic_deploy $TOKEN
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400521
522 create_bridge_and_vms
523 enroll_vms
524 configure_tftpd
Adam Gandelman5f060e62014-04-08 11:52:05 -0700525
526 # restart nova-compute to ensure its resource tracking is up to
527 # date with newly enrolled nodes
528 stop_nova_compute || true
529 start_nova_compute
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400530}
531
532function cleanup_baremetal_basic_ops {
533 rm -f $IRONIC_VM_MACS_CSV_FILE
534 if [ -f $IRONIC_KEY_FILE ]; then
535 KEY=`cat $IRONIC_KEY_FILE.pub`
536 # remove public key from authorized_keys
537 grep -v "$KEY" $IRONIC_AUTHORIZED_KEYS_FILE > temp && mv temp $IRONIC_AUTHORIZED_KEYS_FILE
538 chmod 0600 $IRONIC_AUTHORIZED_KEYS_FILE
539 fi
540 sudo rm -rf $IRONIC_DATA_DIR $IRONIC_STATE_PATH
541 sudo su $STACK_USER -c "$IRONIC_SCRIPTS_DIR/cleanup-nodes $IRONIC_VM_COUNT $IRONIC_VM_NETWORK_BRIDGE"
542 sudo rm -rf /etc/xinetd.d/tftp /etc/init/tftpd-hpa.override
543 restart_service xinetd
544}
545
546# Restore xtrace + pipefail
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300547$XTRACE
Alexander Gordeev06fb29c2014-01-31 18:02:07 +0400548$PIPEFAIL
Roman Prykhodchenkoce696b62013-08-09 10:40:45 +0300549
Adam Spiers6a5aa7c2013-10-24 11:27:02 +0100550# Tell emacs to use shell-script-mode
551## Local variables:
552## mode: shell-script
553## End: