Browse code

Add cinder support

* using the new functional pattern: cinder_XXX functions are in
lib/cinder
* enable with 'c-api,c-sch,c-vol' in ENABLED_SERVICES, n-vol is still the default
* exercises/volumes.sh runs for cinder and n-vol
* move config to /etc/cinder
* change volume_group to stack-volumes; this also renames the backing file
to /opt/stack/data/stack-volumes-backing-file.
* removes osapi_volume from nova.conf enabled_apis
* integrates cinder + keystone
* launches c-sch
* tweaks for multi node
* move enabled_apis substitution to init_cinder

18Jun2010
* restored & rebased
* update setup.py to use setup_develop() in lib/cinder

Change-Id: I1e1aa4387031c56e4fa239eb73bea2af8cef0e38

Dean Troyer authored on 2012/05/03 01:48:15
Showing 11 changed files
... ...
@@ -20,3 +20,9 @@ export RUNNING_TIMEOUT=${RUNNING_TIMEOUT:-$(($BOOT_TIMEOUT + $ACTIVE_TIMEOUT))}
20 20
 
21 21
 # Max time to wait for a vm to terminate
22 22
 export TERMINATE_TIMEOUT=${TERMINATE_TIMEOUT:-30}
23
+
24
+# Max time to wait for a euca-volume command to propogate
25
+export VOLUME_TIMEOUT=${VOLUME_TIMEOUT:-30}
26
+
27
+# Max time to wait for a euca-delete command to propogate
28
+export VOLUME_DELETE_TIMEOUT=${SNAPSHOT_DELETE_TIMEOUT:-60}
... ...
@@ -24,6 +24,9 @@ set -o xtrace
24 24
 # Keep track of the current directory
25 25
 EXERCISE_DIR=$(cd $(dirname "$0") && pwd)
26 26
 TOP_DIR=$(cd $EXERCISE_DIR/..; pwd)
27
+VOLUME_ZONE=cinder
28
+VOLUME_SIZE=1
29
+ATTACH_DEVICE=/dev/vdc
27 30
 
28 31
 # Import common functions
29 32
 source $TOP_DIR/functions
... ...
@@ -33,6 +33,10 @@ source $TOP_DIR/openrc
33 33
 # Import exercise configuration
34 34
 source $TOP_DIR/exerciserc
35 35
 
36
+# If cinder or n-vol are not enabled we exit with exitcode 55 which mean
37
+# exercise is skipped.
38
+is_service_enabled cinder n-vol || exit 55
39
+
36 40
 # Instance type to create
37 41
 DEFAULT_INSTANCE_TYPE=${DEFAULT_INSTANCE_TYPE:-m1.tiny}
38 42
 
39 43
new file mode 100644
... ...
@@ -0,0 +1,2 @@
0
+tgt
1
+lvm2
... ...
@@ -9,6 +9,7 @@
9 9
 # service              nova      admin, [ResellerAdmin (swift only)]
10 10
 # service              quantum   admin        # if enabled
11 11
 # service              swift     admin        # if enabled
12
+# service              cinder    admin        # if enabled
12 13
 # demo                 admin     admin
13 14
 # demo                 demo      Member, anotherrole
14 15
 # invisible_to_admin   demo      Member
... ...
@@ -128,3 +129,13 @@ if [[ "$ENABLED_SERVICES" =~ "tempest" ]]; then
128 128
                                         --email=alt_demo@example.com)
129 129
     keystone user-role-add --user $ALT_DEMO_USER --role $MEMBER_ROLE --tenant_id $ALT_DEMO_TENANT
130 130
 fi
131
+
132
+if [[ "$ENABLED_SERVICES" =~ "cinder" ]]; then
133
+    CINDER_USER=$(get_id keystone user-create --name=cinder \
134
+                                              --pass="$SERVICE_PASSWORD" \
135
+                                              --tenant_id $SERVICE_TENANT \
136
+                                              --email=cinder@example.com)
137
+    keystone user-role-add --tenant_id $SERVICE_TENANT \
138
+                           --user_id $CINDER_USER \
139
+                           --role_id $ADMIN_ROLE
140
+fi
131 141
new file mode 100644
... ...
@@ -0,0 +1,2 @@
0
+lvm2
1
+scsi-target-utils
... ...
@@ -253,6 +253,7 @@ function is_service_enabled() {
253 253
     for service in ${services}; do
254 254
         [[ ,${ENABLED_SERVICES}, =~ ,${service}, ]] && return 0
255 255
         [[ ${service} == "nova" && ${ENABLED_SERVICES} =~ "n-" ]] && return 0
256
+        [[ ${service} == "cinder" && ${ENABLED_SERVICES} =~ "c-" ]] && return 0
256 257
         [[ ${service} == "glance" && ${ENABLED_SERVICES} =~ "g-" ]] && return 0
257 258
         [[ ${service} == "quantum" && ${ENABLED_SERVICES} =~ "q-" ]] && return 0
258 259
     done
259 260
new file mode 100644
... ...
@@ -0,0 +1,154 @@
0
+# lib/cinder
1
+# Install and start Cinder volume service
2
+
3
+# Dependencies:
4
+# - functions
5
+# - KEYSTONE_AUTH_* must be defined
6
+# SERVICE_{TENANT_NAME|PASSWORD} must be defined
7
+
8
+# stack.sh
9
+# ---------
10
+# install_XXX
11
+# configure_XXX
12
+# init_XXX
13
+# start_XXX
14
+# stop_XXX
15
+# cleanup_XXX
16
+
17
+# Print the commands being run so that we can see the command that triggers
18
+# an error.  It is also useful for following along as the install occurs.
19
+set -o xtrace
20
+
21
+
22
+# Defaults
23
+# --------
24
+
25
+# set up default directories
26
+CINDER_DIR=$DEST/cinder
27
+CINDERCLIENT_DIR=$DEST/python-cinderclient
28
+CINDER_CONF_DIR=/etc/cinder
29
+CINDER_CONF=$CINDER_CONF_DIR/cinder.conf
30
+
31
+# Name of the lvm volume group to use/create for iscsi volumes
32
+VOLUME_GROUP=${VOLUME_GROUP:-stack-volumes}
33
+VOLUME_NAME_PREFIX=${VOLUME_NAME_PREFIX:-volume-}
34
+
35
+# cleanup_cinder() - Remove residual data files, anything left over from previous
36
+# runs that a clean run would need to clean up
37
+function cleanup_cinder() {
38
+    # This function intentionally left blank
39
+    :
40
+}
41
+
42
+# configure_cinder() - Set config files, create data dirs, etc
43
+function configure_cinder() {
44
+    setup_develop $CINDER_DIR
45
+    setup_develop $CINDERCLIENT_DIR
46
+
47
+    if [[ ! -d $CINDER_CONF_DIR ]]; then
48
+        sudo mkdir -p $CINDER_CONF_DIR
49
+    fi
50
+    sudo chown `whoami` $CINDER_CONF_DIR
51
+
52
+    cp -p $CINDER_DIR/etc/cinder/policy.json $CINDER_CONF_DIR
53
+
54
+    CINDER_API_PASTE_INI=$CINDER_CONF_DIR/api-paste.ini
55
+    cp $CINDER_DIR/etc/cinder/api-paste.ini $CINDER_API_PASTE_INI
56
+    iniset $CINDER_API_PASTE_INI filter:authtoken auth_host $KEYSTONE_AUTH_HOST
57
+    iniset $CINDER_API_PASTE_INI filter:authtoken auth_port $KEYSTONE_AUTH_PORT
58
+    iniset $CINDER_API_PASTE_INI filter:authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
59
+    iniset $CINDER_API_PASTE_INI filter:authtoken admin_tenant_name $SERVICE_TENANT_NAME
60
+    iniset $CINDER_API_PASTE_INI filter:authtoken admin_user cinder
61
+    iniset $CINDER_API_PASTE_INI filter:authtoken admin_password $SERVICE_PASSWORD
62
+
63
+    cp $CINDER_DIR/etc/cinder/cinder.conf.sample $CINDER_CONF
64
+    iniset $CINDER_CONF DEFAULT auth_strategy keystone
65
+    iniset $CINDER_CONF DEFAULT verbose True
66
+    iniset $CINDER_CONF DEFAULT volume_group $VOLUME_GROUP
67
+    iniset $CINDER_CONF DEFAULT volume_name_template ${VOLUME_NAME_PREFIX}%s
68
+    iniset $CINDER_CONF DEFAULT iscsi_helper tgtadm
69
+    iniset $CINDER_CONF DEFAULT sql_connection $BASE_SQL_CONN/cinder?charset=utf8
70
+    iniset $CINDER_CONF DEFAULT rabbit_host $RABBIT_HOST
71
+    iniset $CINDER_CONF DEFAULT rabbit_password $RABBIT_PASSWORD
72
+    iniset $CINDER_CONF DEFAULT api_paste_config $CINDER_API_PASTE_INI
73
+}
74
+
75
+# init_cinder() - Initialize database and volume group
76
+function init_cinder() {
77
+    # Force nova volumes off
78
+    NOVA_ENABLED_APIS=$(echo $NOVA_ENABLED_APIS | sed "s/osapi_volume,//")
79
+
80
+    if is_service_enabled mysql; then
81
+        # (re)create cinder database
82
+        mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'DROP DATABASE IF EXISTS cinder;'
83
+        mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE cinder;'
84
+
85
+        # (re)create cinder database
86
+        $CINDER_DIR/bin/cinder-manage db sync
87
+    fi
88
+
89
+    if is_service_enabled c-vol; then
90
+        # Configure a default volume group called '`stack-volumes`' for the volume
91
+        # service if it does not yet exist.  If you don't wish to use a file backed
92
+        # volume group, create your own volume group called ``stack-volumes`` before
93
+        # invoking ``stack.sh``.
94
+        #
95
+        # By default, the backing file is 2G in size, and is stored in ``/opt/stack/data``.
96
+
97
+        if ! sudo vgs $VOLUME_GROUP; then
98
+            VOLUME_BACKING_FILE=${VOLUME_BACKING_FILE:-$DATA_DIR/${VOLUME_GROUP}-backing-file}
99
+            VOLUME_BACKING_FILE_SIZE=${VOLUME_BACKING_FILE_SIZE:-2052M}
100
+            # Only create if the file doesn't already exists
101
+            [[ -f $VOLUME_BACKING_FILE ]] || truncate -s $VOLUME_BACKING_FILE_SIZE $VOLUME_BACKING_FILE
102
+            DEV=`sudo losetup -f --show $VOLUME_BACKING_FILE`
103
+            # Only create if the loopback device doesn't contain $VOLUME_GROUP
104
+            if ! sudo vgs $VOLUME_GROUP; then sudo vgcreate $VOLUME_GROUP $DEV; fi
105
+        fi
106
+
107
+        if sudo vgs $VOLUME_GROUP; then
108
+            # Remove iscsi targets
109
+            sudo tgtadm --op show --mode target | grep $VOLUME_NAME_PREFIX | grep Target | cut -f3 -d ' ' | sudo xargs -n1 tgt-admin --delete || true
110
+            # Clean out existing volumes
111
+            for lv in `sudo lvs --noheadings -o lv_name $VOLUME_GROUP`; do
112
+                # VOLUME_NAME_PREFIX prefixes the LVs we want
113
+                if [[ "${lv#$VOLUME_NAME_PREFIX}" != "$lv" ]]; then
114
+                    sudo lvremove -f $VOLUME_GROUP/$lv
115
+                fi
116
+            done
117
+        fi
118
+    fi
119
+}
120
+
121
+# install_cinder() - Collect source and prepare
122
+function install_cinder() {
123
+    git_clone $CINDER_REPO $CINDER_DIR $CINDER_BRANCH
124
+    git_clone $CINDERCLIENT_REPO $CINDERCLIENT_DIR $CINDERCLIENT_BRANCH
125
+}
126
+
127
+# start_cinder() - Start running processes, including screen
128
+function start_cinder() {
129
+    if is_service_enabled c-vol; then
130
+        if [[ "$os_PACKAGE" = "deb" ]]; then
131
+            # tgt in oneiric doesn't restart properly if tgtd isn't running
132
+            # do it in two steps
133
+            sudo stop tgt || true
134
+            sudo start tgt
135
+        else
136
+            # bypass redirection to systemctl during restart
137
+            sudo /sbin/service --skip-redirect tgtd restart
138
+        fi
139
+    fi
140
+
141
+    screen_it c-api "cd $CINDER_DIR && $CINDER_DIR/bin/cinder-api --config-file $CINDER_CONF"
142
+    screen_it c-vol "cd $CINDER_DIR && $CINDER_DIR/bin/cinder-volume --config-file $CINDER_CONF"
143
+    screen_it c-sch "cd $CINDER_DIR && $CINDER_DIR/bin/cinder-scheduler --config-file $CINDER_CONF"
144
+}
145
+
146
+# stop_cinder() - Stop running processes (non-screen)
147
+function stop_cinder() {
148
+    # FIXME(dtroyer): stop only the cinder screen window?
149
+
150
+    if is_service_enabled c-vol; then
151
+        stop_service tgt
152
+    fi
153
+}
... ...
@@ -112,6 +112,13 @@ else
112 112
     NOVA_ROOTWRAP=/usr/bin/nova-rootwrap
113 113
 fi
114 114
 
115
+# ``stack.sh`` keeps function libraries here
116
+# Make sure ``$TOP_DIR/lib`` directory is present
117
+if [ ! -d $TOP_DIR/lib ]; then
118
+    echo "ERROR: missing devstack/lib - did you grab more than just stack.sh?"
119
+    exit 1
120
+fi
121
+
115 122
 # stack.sh keeps the list of ``apt`` and ``pip`` dependencies in external
116 123
 # files, along with config templates and other useful files.  You can find these
117 124
 # in the ``files`` directory (next to this script).  We will reference this
... ...
@@ -130,6 +137,12 @@ if type -p screen >/dev/null && screen -ls | egrep -q "[0-9].stack"; then
130 130
     exit 1
131 131
 fi
132 132
 
133
+# Make sure we only have one volume service enabled.
134
+if is_service_enabled cinder && is_service_enabled n-vol; then
135
+    echo "ERROR: n-vol and cinder must not be enabled at the same time"
136
+    exit 1
137
+fi
138
+
133 139
 # OpenStack is designed to be run as a regular user (Horizon will fail to run
134 140
 # as root, since apache refused to startup serve content from root user).  If
135 141
 # ``stack.sh`` is run as **root**, it automatically creates a **stack** user with
... ...
@@ -201,6 +214,19 @@ fi
201 201
 # prerequisites and initialize ``$DEST``.
202 202
 OFFLINE=`trueorfalse False $OFFLINE`
203 203
 
204
+# Destination path for service data
205
+DATA_DIR=${DATA_DIR:-${DEST}/data}
206
+sudo mkdir -p $DATA_DIR
207
+sudo chown `whoami` $DATA_DIR
208
+
209
+
210
+# Projects
211
+# --------
212
+
213
+# Get project function libraries
214
+source $TOP_DIR/lib/cinder
215
+
216
+
204 217
 # Set the destination directories for openstack projects
205 218
 NOVA_DIR=$DEST/nova
206 219
 HORIZON_DIR=$DEST/horizon
... ...
@@ -234,7 +260,7 @@ M_HOST=${M_HOST:-localhost}
234 234
 M_MAC_RANGE=${M_MAC_RANGE:-FE-EE-DD-00-00-00/24}
235 235
 
236 236
 # Name of the lvm volume group to use/create for iscsi volumes
237
-VOLUME_GROUP=${VOLUME_GROUP:-nova-volumes}
237
+VOLUME_GROUP=${VOLUME_GROUP:-stack-volumes}
238 238
 VOLUME_NAME_PREFIX=${VOLUME_NAME_PREFIX:-volume-}
239 239
 INSTANCE_NAME_PREFIX=${INSTANCE_NAME_PREFIX:-instance-}
240 240
 
... ...
@@ -607,6 +633,10 @@ function get_packages() {
607 607
             if [[ ! $file_to_parse =~ glance ]]; then
608 608
                 file_to_parse="${file_to_parse} glance"
609 609
             fi
610
+        elif [[ $service == c-* ]]; then
611
+            if [[ ! $file_to_parse =~ cinder ]]; then
612
+                file_to_parse="${file_to_parse} cinder"
613
+            fi
610 614
         elif [[ $service == n-* ]]; then
611 615
             if [[ ! $file_to_parse =~ nova ]]; then
612 616
                 file_to_parse="${file_to_parse} nova"
... ...
@@ -704,10 +734,12 @@ if is_service_enabled m-svc; then
704 704
     # melange
705 705
     git_clone $MELANGE_REPO $MELANGE_DIR $MELANGE_BRANCH
706 706
 fi
707
-
708 707
 if is_service_enabled melange; then
709 708
     git_clone $MELANGECLIENT_REPO $MELANGECLIENT_DIR $MELANGECLIENT_BRANCH
710 709
 fi
710
+if is_service_enabled cinder; then
711
+    install_cinder
712
+fi
711 713
 
712 714
 
713 715
 # Initialization
... ...
@@ -743,6 +775,9 @@ fi
743 743
 if is_service_enabled melange; then
744 744
     setup_develop $MELANGECLIENT_DIR
745 745
 fi
746
+if is_service_enabled cinder; then
747
+    configure_cinder
748
+fi
746 749
 
747 750
 # Do this _after_ glance is installed to override the old binary
748 751
 setup_develop $GLANCECLIENT_DIR
... ...
@@ -1643,17 +1678,18 @@ fi
1643 1643
 # Volume Service
1644 1644
 # --------------
1645 1645
 
1646
-if is_service_enabled n-vol; then
1647
-    #
1648
-    # Configure a default volume group called 'nova-volumes' for the nova-volume
1646
+if is_service_enabled cinder; then
1647
+    init_cinder
1648
+elif is_service_enabled n-vol; then
1649
+    # Configure a default volume group called '`stack-volumes`' for the volume
1649 1650
     # service if it does not yet exist.  If you don't wish to use a file backed
1650
-    # volume group, create your own volume group called 'nova-volumes' before
1651
-    # invoking stack.sh.
1651
+    # volume group, create your own volume group called ``stack-volumes`` before
1652
+    # invoking ``stack.sh``.
1652 1653
     #
1653
-    # By default, the backing file is 2G in size, and is stored in /opt/stack.
1654
+    # By default, the backing file is 2G in size, and is stored in ``/opt/stack/data``.
1654 1655
 
1655 1656
     if ! sudo vgs $VOLUME_GROUP; then
1656
-        VOLUME_BACKING_FILE=${VOLUME_BACKING_FILE:-$DEST/nova-volumes-backing-file}
1657
+        VOLUME_BACKING_FILE=${VOLUME_BACKING_FILE:-$DATA_DIR/${VOLUME_GROUP}-backing-file}
1657 1658
         VOLUME_BACKING_FILE_SIZE=${VOLUME_BACKING_FILE_SIZE:-2052M}
1658 1659
         # Only create if the file doesn't already exists
1659 1660
         [[ -f $VOLUME_BACKING_FILE ]] || truncate -s $VOLUME_BACKING_FILE_SIZE $VOLUME_BACKING_FILE
... ...
@@ -1801,6 +1837,10 @@ else
1801 1801
     add_nova_opt "logging_context_format_string=%(asctime)s %(levelname)s %(name)s [%(request_id)s %(user_name)s %(project_name)s] %(instance)s%(message)s"
1802 1802
 fi
1803 1803
 
1804
+# If cinder is enabled, use the cinder volume driver
1805
+if is_service_enabled cinder; then
1806
+    add_nova_opt "volume_api_class=nova.volume.cinder.API"
1807
+fi
1804 1808
 
1805 1809
 # Provide some transition from EXTRA_FLAGS to EXTRA_OPTS
1806 1810
 if [[ -z "$EXTRA_OPTS" && -n "$EXTRA_FLAGS" ]]; then
... ...
@@ -1968,6 +2008,7 @@ fi
1968 1968
 
1969 1969
 # launch the nova-api and wait for it to answer before continuing
1970 1970
 if is_service_enabled n-api; then
1971
+    add_nova_opt "enabled_apis=$NOVA_ENABLED_APIS"
1971 1972
     screen_it n-api "cd $NOVA_DIR && $NOVA_DIR/bin/nova-api"
1972 1973
     echo "Waiting for nova-api to start..."
1973 1974
     if ! timeout $SERVICE_TIMEOUT sh -c "while ! http_proxy= wget -q -O- http://127.0.0.1:8774; do sleep 1; done"; then
... ...
@@ -2003,6 +2044,9 @@ screen_it n-sch "cd $NOVA_DIR && $NOVA_DIR/bin/nova-scheduler"
2003 2003
 screen_it n-novnc "cd $NOVNC_DIR && ./utils/nova-novncproxy --config-file $NOVA_CONF_DIR/$NOVA_CONF --web ."
2004 2004
 screen_it n-xvnc "cd $NOVA_DIR && ./bin/nova-xvpvncproxy --config-file $NOVA_CONF_DIR/$NOVA_CONF"
2005 2005
 screen_it n-cauth "cd $NOVA_DIR && ./bin/nova-consoleauth"
2006
+if is_service_enabled cinder; then
2007
+    start_cinder
2008
+fi
2006 2009
 screen_it horizon "cd $HORIZON_DIR && sudo tail -f /var/log/$APACHE_NAME/horizon_error.log"
2007 2010
 screen_it swift "cd $SWIFT_DIR && $SWIFT_DIR/bin/swift-proxy-server ${SWIFT_CONFIG_DIR}/proxy-server.conf -v"
2008 2011
 
... ...
@@ -9,6 +9,17 @@ RC_DIR=$(cd $(dirname "$BASH_SOURCE") && pwd)
9 9
 # ENABLED_SERVICES="$ENABLED_SERVICES,swift"
10 10
 ENABLED_SERVICES=g-api,g-reg,key,n-api,n-crt,n-obj,n-cpu,n-net,n-vol,n-sch,n-novnc,n-xvnc,n-cauth,horizon,mysql,rabbit
11 11
 
12
+# Set the default Nova APIs to enable
13
+NOVA_ENABLED_APIS=ec2,osapi_compute,osapi_volume,metadata
14
+
15
+# volume service
16
+CINDER_REPO=https://github.com/openstack/cinder
17
+CINDER_BRANCH=master
18
+
19
+# volume client
20
+CINDERCLIENT_REPO=https://github.com/openstack/python-cinderclient
21
+CINDERCLIENT_BRANCH=master
22
+
12 23
 # compute service
13 24
 NOVA_REPO=https://github.com/openstack/nova.git
14 25
 NOVA_BRANCH=master
... ...
@@ -44,7 +44,7 @@ if is_service_enabled horizon; then
44 44
 fi
45 45
 
46 46
 # Get the iSCSI volumes
47
-if is_service_enabled n-vol; then
47
+if is_service_enabled cinder n-vol; then
48 48
     TARGETS=$(sudo tgtadm --op show --mode target)
49 49
     if [[ -n "$TARGETS" ]]; then
50 50
         # FIXME(dtroyer): this could very well require more here to