File: install_devstack.sh

package info (click to toggle)
python-os-xenapi 0.3.4-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 1,012 kB
  • sloc: python: 8,137; sh: 2,154; makefile: 45
file content (390 lines) | stat: -rwxr-xr-x 11,792 bytes parent folder | download
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
#!/bin/bash

# This script is run by install_on_xen_host.sh
#
# It modifies the ubuntu image created by install_on_xen_host.sh
# and previously moodified by prepare_guest_template.sh
#
# This script is responsible for:
# - creates a DomU VM
# - creating run.sh, to run the code on DomU boot
#
# by install_on_xen_host.sh

# Exit on errors
set -o errexit
# Echo commands
set -o xtrace

# This directory
THIS_DIR=$(cd $(dirname "$0") && pwd)
TOP_DIR="$THIS_DIR/../"
SCRIPT_DIR="$TOP_DIR/scripts"
COMM_DIR="$TOP_DIR/common"
CONF_DIR="$TOP_DIR/conf"

# Include onexit commands
. $SCRIPT_DIR/on_exit.sh

# xapi functions
. $COMM_DIR/functions

# Source params
source $CONF_DIR/xenrc

# Defaults for optional arguments
DEVSTACK_SRC=${DEVSTACK_SRC:-"https://github.com/openstack-dev/devstack"}
LOGDIR="/opt/stack/devstack_logs"
DISABLE_JOURNALING="false"

# Number of options passed to this script
REMAINING_OPTIONS="$#"
# Get optional parameters
set +e
while getopts ":d:l:r" flag; do
    REMAINING_OPTIONS=$(expr "$REMAINING_OPTIONS" - 1)
    case "$flag" in
        d)
            DEVSTACK_SRC="$OPTARG"
            REMAINING_OPTIONS=$(expr "$REMAINING_OPTIONS" - 1)
            ;;
        l)
            LOGDIR="$OPTARG"
            REMAINING_OPTIONS=$(expr "$REMAINING_OPTIONS" - 1)
            ;;
        r)
            DISABLE_JOURNALING="true"
            ;;
        \?)
            print_usage_and_die "Invalid option -$OPTARG"
            ;;
    esac
done
set -e

# Make sure that all options processed
if [ "0" != "$REMAINING_OPTIONS" ]; then
    print_usage_and_die "ERROR: some arguments were not recognised!"
fi

#
# Prepare VM for DevStack
#

#
# Configure Networking
#

host_uuid=$(get_current_host_uuid)

MGT_NETWORK=`xe pif-list management=true host-uuid=$host_uuid params=network-uuid minimal=true`
MGT_BRIDGE_OR_NET_NAME=`xe network-list uuid=$MGT_NETWORK params=bridge minimal=true`

setup_network "$VM_BRIDGE_OR_NET_NAME"
setup_network "$MGT_BRIDGE_OR_NET_NAME"
setup_network "$PUB_BRIDGE_OR_NET_NAME"

if parameter_is_specified "FLAT_NETWORK_BRIDGE"; then
    if [ "$(bridge_for "$VM_BRIDGE_OR_NET_NAME")" != "$(bridge_for "$FLAT_NETWORK_BRIDGE")" ]; then
        cat >&2 << EOF
ERROR: FLAT_NETWORK_BRIDGE is specified in localrc file, and either no network
found on XenServer by searching for networks by that value as name-label or
bridge name or the network found does not match the network specified by
VM_BRIDGE_OR_NET_NAME. Please check your localrc file.
EOF
        exit 1
    fi
fi

if ! xenapi_is_listening_on "$MGT_BRIDGE_OR_NET_NAME"; then
    cat >&2 << EOF
ERROR: XenAPI does not have an assigned IP address on the management network.
please review your XenServer network configuration / localrc file.
EOF
    exit 1
fi

HOST_IP=$(xenapi_ip_on "$MGT_BRIDGE_OR_NET_NAME")

# Also, enable ip forwarding in rc.local, since the above trick isn't working
if ! grep -q  "echo 1 >/proc/sys/net/ipv4/ip_forward" /etc/rc.local; then
    echo "echo 1 >/proc/sys/net/ipv4/ip_forward" >> /etc/rc.local
fi
# Enable ip forwarding at runtime as well
echo 1 > /proc/sys/net/ipv4/ip_forward

HOST_IP=$(xenapi_ip_on "$MGT_BRIDGE_OR_NET_NAME")

#install the previous ubuntu VM

vm_exist=$(xe vm-list name-label="$DEV_STACK_DOMU_NAME" --minimal)
if [ "$vm_exist" != "" ]
then
    echo "Uninstall the previous VM"
    xe vm-uninstall vm="$DEV_STACK_DOMU_NAME" force=true
fi

echo "Install a new ubuntu VM according to previous template"

vm_uuid=$(xe vm-install template="$TNAME" new-name-label="$DEV_STACK_DOMU_NAME")

xe vm-param-set other-config:os-vpx=true uuid="$vm_uuid"

# Install XenServer tools, and other such things
$SCRIPT_DIR/prepare_guest_template.sh "$DEV_STACK_DOMU_NAME"

# Set virtual machine parameters
set_vm_memory "$DEV_STACK_DOMU_NAME" "$VM_MEM_MB"

# Max out VCPU count for better performance
max_vcpus "$DEV_STACK_DOMU_NAME"

# Wipe out all network cards
destroy_all_vifs_of "$DEV_STACK_DOMU_NAME"

# Add only one interface to prepare the guest template
add_interface "$DEV_STACK_DOMU_NAME" "$MGT_BRIDGE_OR_NET_NAME" "0"

# start the VM to run the prepare steps
xe vm-start vm="$DEV_STACK_DOMU_NAME" on=$host_uuid

# Wait for prep script to finish and shutdown system
wait_for_VM_to_halt "$DEV_STACK_DOMU_NAME"

## Setup network cards
# Wipe out all
destroy_all_vifs_of "$DEV_STACK_DOMU_NAME"
# Tenant network
add_interface "$DEV_STACK_DOMU_NAME" "$VM_BRIDGE_OR_NET_NAME" "$VM_DEV_NR"
# Management network
add_interface "$DEV_STACK_DOMU_NAME" "$MGT_BRIDGE_OR_NET_NAME" "$MGT_DEV_NR"
# Public network
add_interface "$DEV_STACK_DOMU_NAME" "$PUB_BRIDGE_OR_NET_NAME" "$PUB_DEV_NR"

#
# persistant the VM's interfaces
#
$SCRIPT_DIR/persist_domU_interfaces.sh "$DEV_STACK_DOMU_NAME"

FLAT_NETWORK_BRIDGE="${FLAT_NETWORK_BRIDGE:-$(bridge_for "$VM_BRIDGE_OR_NET_NAME")}"
append_kernel_cmdline "$DEV_STACK_DOMU_NAME" "flat_network_bridge=${FLAT_NETWORK_BRIDGE}"

# Disable FS journaling. It would reduce disk IO, but may lead to file system
# unstable after long time use
if [ "$DISABLE_JOURNALING" = "true" ]; then
    vm_vbd=$(xe vbd-list vm-name-label=$DEV_STACK_DOMU_NAME --minimal)
    vm_vdi=$(xe vdi-list vbd-uuids=$vm_vbd --minimal)
    dom_zero_uuid=$(xe host-param-get param-name=control-domain-uuid uuid=$host_uuid)
    tmp_vbd=$(xe vbd-create device=autodetect bootable=false mode=RW type=Disk vdi-uuid=$vm_vdi vm-uuid=$dom_zero_uuid)
    xe vbd-plug uuid=$tmp_vbd
    sr_id=$(get_local_sr)
    kpartx -p p -avs  /dev/sm/backend/$sr_id/$vm_vdi
    echo "********Before disable FS journaling********"
    tune2fs -l  /dev/mapper/${vm_vdi}p1 | grep "Filesystem features"
    echo "********Disable FS journaling********"
    tune2fs -O ^has_journal /dev/mapper/${vm_vdi}p1
    echo "********After disable FS journaling********"
    tune2fs -l  /dev/mapper/${vm_vdi}p1 | grep "Filesystem features"
    kpartx -p p -dvs  /dev/sm/backend/$sr_id/$vm_vdi
    xe vbd-unplug uuid=$tmp_vbd timeout=60
    xe vbd-destroy uuid=$tmp_vbd
fi

# Add a separate xvdb, if it was requested
if [[ "0" != "$XEN_XVDB_SIZE_GB" ]]; then
    vm=$(xe vm-list name-label="$DEV_STACK_DOMU_NAME" --minimal)

    # Add a new disk
    localsr=$(get_local_sr)
    extra_vdi=$(xe vdi-create \
        name-label=xvdb-added-by-devstack \
        virtual-size="${XEN_XVDB_SIZE_GB}GiB" \
        sr-uuid=$localsr type=user)
    xe vbd-create vm-uuid=$vm vdi-uuid=$extra_vdi device=1
fi

#
# Run DevStack VM
#
xe vm-start vm="$DEV_STACK_DOMU_NAME" on=$host_uuid

# Get hold of the Management IP of OpenStack VM
OS_VM_MANAGEMENT_ADDRESS=$MGT_IP
if [ $OS_VM_MANAGEMENT_ADDRESS == "dhcp" ]; then
    OS_VM_MANAGEMENT_ADDRESS=$(find_ip_by_name $DEV_STACK_DOMU_NAME $MGT_DEV_NR)
fi

# Create an ssh-keypair, and set it up for dom0 user
rm -f /root/dom0key /root/dom0key.pub
ssh-keygen -f /root/dom0key -P "" -C "dom0"
DOMID=$(get_domid "$DEV_STACK_DOMU_NAME")

xenstore-write /local/domain/$DOMID/authorized_keys/$DOMZERO_USER "$(cat /root/dom0key.pub)"
xenstore-chmod -u /local/domain/$DOMID/authorized_keys/$DOMZERO_USER r$DOMID

function run_on_appliance {
    ssh \
        -i /root/dom0key \
        -o UserKnownHostsFile=/dev/null \
        -o StrictHostKeyChecking=no \
        -o BatchMode=yes \
        "$DOMZERO_USER@$OS_VM_MANAGEMENT_ADDRESS" "$@"
}

# Wait until we can log in to the appliance
while ! run_on_appliance true; do
    sleep 1
done

# Remove authenticated_keys updater cronjob
echo "" | run_on_appliance crontab -

# Generate a passwordless ssh key for domzero user
echo "ssh-keygen -f /home/$DOMZERO_USER/.ssh/id_rsa -C $DOMZERO_USER@appliance -N \"\" -q" | run_on_appliance

# Authenticate that user to dom0
run_on_appliance cat /home/$DOMZERO_USER/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys

set +x
echo "################################################################################"
echo ""
echo "VM configuration done!"
echo "################################################################################"


xe vm-shutdown vm="$DEV_STACK_DOMU_NAME"
wait_for_VM_to_halt "$DEV_STACK_DOMU_NAME"
#
# Mount the VDI
#
echo "check vdi mapping"
STAGING_DIR=$($SCRIPT_DIR/manage-vdi open $DEV_STACK_DOMU_NAME 0 1 | grep -o "/tmp/tmp.[[:alnum:]]*")
add_on_exit "$SCRIPT_DIR/manage-vdi close $DEV_STACK_DOMU_NAME 0 1"
# Make sure we have a stage
if [ ! -d $STAGING_DIR/etc ]; then
    echo "ERROR:ct properly set up!"
    exit 1
fi

if [ ! -d "$STAGING_DIR/opt/stack" ]; then
    echo "ERROR: scet"
    exit -1
fi

rm -f $STAGING_DIR/opt/stack/local.conf
pif=$(xe pif-list management=true host-uuid=$host_uuid --minimal)
XENSERVER_IP=$(xe pif-param-get param-name=IP uuid=$pif)


# Create an systemd task for devstack
cat >$STAGING_DIR/etc/systemd/system/devstack.service << EOF
[Unit]
Description=Install OpenStack by DevStack

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/bin/rm -f /opt/stack/runsh.succeeded
ExecStart=/bin/su -c "/opt/stack/run.sh" stack
StandardOutput=tty
StandardError=tty

[Install]
WantedBy=multi-user.target

EOF

if [ $? -ne 0 ]; then
echo "fatal error, install service failed."
exit 1
fi

# enable this service
rm -f $STAGING_DIR/etc/systemd/system/multi-user.target.wants/devstack.service
ln -s /etc/systemd/system/devstack.service $STAGING_DIR/etc/systemd/system/multi-user.target.wants/devstack.service

# Gracefully cp only if source file/dir exists
function cp_it {
    if [ -e $1 ] || [ -d $1 ]; then
        cp -pRL $1 $2
    fi
}

# Copy over your ssh keys and env if desired
cp_it ~/.ssh $STAGING_DIR/opt/stack/.ssh
cp_it ~/.ssh/id_rsa.pub $STAGING_DIR/opt/stack/.ssh/authorized_keys
cp_it ~/.gitconfig $STAGING_DIR/opt/stack/.gitconfig
cp_it ~/.vimrc $STAGING_DIR/opt/stack/.vimrc
cp_it ~/.bashrc $STAGING_DIR/opt/stack/.bashrc
if [ -d $DEVSTACK_SRC ]; then
  # Local repository for devstack exist, copy it to DomU
  cp_it $DEVSTACK_SRC $STAGING_DIR/opt/stack/
fi

# Journald default is to not persist logs to disk if /var/log/journal is
# not present. Update the configuration to set storage to persistent which
# will create /var/log/journal if necessary and store logs on disk. This
# avoids the situation where test runs can fill the journald ring buffer
# deleting older logs that may be important to the job.
JOURNALD_CFG=$STAGING_DIR/etc/systemd/journald.conf
if [ -f $JOURNALD_CFG ] ; then
    sed -i -e 's/#Storage=auto/Storage=persistent/' $JOURNALD_CFG
fi

# Configure run.sh
DOMU_STACK_DIR=/opt/stack
DOMU_DEV_STACK_DIR=$DOMU_STACK_DIR/devstack
cat <<EOF >$STAGING_DIR/opt/stack/run.sh
#!/bin/bash
set -eux
(
  flock -n 9 || exit 1

  sudo chown -R stack $DOMU_STACK_DIR

  cd $DOMU_STACK_DIR

  [ -e /opt/stack/runsh.succeeded ] && rm /opt/stack/runsh.succeeded
  echo \$\$ >> /opt/stack/run_sh.pid

  if [ ! -d $DOMU_DEV_STACK_DIR ]; then
  echo "Can not find the devstack source code, get it from git."
  git clone $DEVSTACK_SRC $DOMU_DEV_STACK_DIR
  fi

  cp $DOMU_STACK_DIR/local.conf $DOMU_DEV_STACK_DIR/

  cd $DOMU_DEV_STACK_DIR
  ./unstack.sh || true
  ./stack.sh

  # Got to the end - success
  touch /opt/stack/runsh.succeeded

  # Update /etc/issue
  (
      echo "OpenStack VM - Installed by DevStack"
      IPADDR=$(ip -4 address show eth0 | sed -n 's/.*inet \([0-9\.]\+\).*/\1/p')
      echo "  Management IP:   $IPADDR"
      echo -n "  Devstack run:    "
      if [ -e /opt/stack/runsh.succeeded ]; then
          echo "SUCCEEDED"
      else
          echo "FAILED"
      fi
      echo ""
  ) > /opt/stack/issue
  sudo cp /opt/stack/issue /etc/issue

  rm /opt/stack/run_sh.pid
) 9> /opt/stack/.runsh_lock
EOF

chmod 755 $STAGING_DIR/opt/stack/run.sh
if [ ! -f $TOP_DIR/local.conf ]; then
    echo "ERROR: You should prepare a local.conf and put it under $TOP_DIR"
    exit 1
fi

cp_it $TOP_DIR/local.conf $STAGING_DIR/opt/stack/local.conf
cp_it $THIS_DIR/run.sh $STAGING_DIR/opt/stack/run.sh