Browse code

Basic support of Ironic

Ironic is an OpenStack project than brings a
separate service for baremetal provisioning.
Currently Ironic is in incubation but it needs
to have basic support in devstack to provide
automatic deployment testing.

Change-Id: Ide65a1379fa207a6c8b2c7d9a4f9c874b10fd9ba

Roman Prykhodchenko authored on 2013/08/09 16:40:45
Showing 4 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,222 @@
0
+# lib/ironic
1
+# Functions to control the configuration and operation of the **Ironic** service
2
+
3
+# Dependencies:
4
+# ``functions`` file
5
+# ``DEST``, ``DATA_DIR``, ``STACK_USER`` must be defined
6
+# ``SERVICE_{TENANT_NAME|PASSWORD}`` must be defined
7
+# ``SERVICE_HOST``
8
+# ``KEYSTONE_TOKEN_FORMAT`` must be defined
9
+
10
+# ``stack.sh`` calls the entry points in this order:
11
+#
12
+# install_ironic
13
+# configure_ironic
14
+# init_ironic
15
+# start_ironic
16
+# stop_ironic
17
+# cleanup_ironic
18
+
19
+# Save trace setting
20
+XTRACE=$(set +o | grep xtrace)
21
+set +o xtrace
22
+
23
+
24
+# Defaults
25
+# --------
26
+
27
+# Set up default directories
28
+IRONIC_DIR=$DEST/ironic
29
+IRONIC_AUTH_CACHE_DIR=${IRONIC_AUTH_CACHE_DIR:-/var/cache/ironic}
30
+IRONIC_CONF_DIR=${IRONIC_CONF_DIR:-/etc/ironic}
31
+IRONIC_CONF_FILE=$IRONIC_CONF_DIR/ironic.conf
32
+IRONIC_ROOTWRAP_CONF=$IRONIC_CONF_DIR/rootwrap.conf
33
+IRONIC_ROOTWRAP_FILTERS=$IRONIC_CONF_DIR/rootwrap.d
34
+IRONIC_POLICY_JSON=$IRONIC_CONF_DIR/policy.json
35
+
36
+# Support entry points installation of console scripts
37
+IRONIC_BIN_DIR=$(get_python_exec_prefix)
38
+
39
+# Ironic connection info.  Note the port must be specified.
40
+IRONIC_SERVICE_PROTOCOL=http
41
+IRONIC_HOSTPORT=${IRONIC_HOSTPORT:-$SERVICE_HOST:6385}
42
+
43
+
44
+# Functions
45
+# ---------
46
+
47
+# cleanup_ironic() - Remove residual data files, anything left over from previous
48
+# runs that would need to clean up.
49
+function cleanup_ironic() {
50
+    sudo rm -rf $IRONIC_AUTH_CACHE_DIR
51
+}
52
+
53
+# configure_ironic() - Set config files, create data dirs, etc
54
+function configure_ironic() {
55
+    if [[ ! -d $IRONIC_CONF_DIR ]]; then
56
+        sudo mkdir -p $IRONIC_CONF_DIR
57
+    fi
58
+    sudo chown $STACK_USER $IRONIC_CONF_DIR
59
+
60
+    # Copy over ironic configuration file and configure common parameters.
61
+    cp $IRONIC_DIR/etc/ironic/ironic.conf.sample $IRONIC_CONF_FILE
62
+    iniset $IRONIC_CONF_FILE DEFAULT debug True
63
+    inicomment $IRONIC_CONF_FILE DEFAULT log_file
64
+    iniset $IRONIC_CONF_FILE DEFAULT sql_connection `database_connection_url ironic`
65
+    iniset $IRONIC_CONF_FILE DEFAULT use_syslog $SYSLOG
66
+
67
+    # Configure Ironic conductor, if it was enabled.
68
+    if is_service_enabled ir-cond; then
69
+        configure_ironic_conductor
70
+    fi
71
+
72
+    # Configure Ironic API, if it was enabled.
73
+    if is_service_enabled ir-api; then
74
+        configure_ironic_api
75
+    fi
76
+}
77
+
78
+# configure_ironic_api() - Is used by configure_ironic(). Performs
79
+# API specific configuration.
80
+function configure_ironic_api() {
81
+    iniset $IRONIC_CONF_FILE keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
82
+    iniset $IRONIC_CONF_FILE keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
83
+    iniset $IRONIC_CONF_FILE keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
84
+    iniset $IRONIC_CONF_FILE keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/
85
+    iniset $IRONIC_CONF_FILE keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
86
+    iniset $IRONIC_CONF_FILE keystone_authtoken admin_user ironic
87
+    iniset $IRONIC_CONF_FILE keystone_authtoken admin_password $SERVICE_PASSWORD
88
+    if is_service_enabled qpid; then
89
+        iniset $IRONIC_CONF_FILE DEFAULT notifier_strategy qpid
90
+    elif [ -n "$RABBIT_HOST" ] &&  [ -n "$RABBIT_PASSWORD" ]; then
91
+        iniset $IRONIC_CONF_FILE DEFAULT notifier_strategy rabbit
92
+    fi
93
+    iniset_rpc_backend ironic $IRONIC_CONF_FILE DEFAULT
94
+    iniset $IRONIC_CONF_FILE keystone_authtoken signing_dir $IRONIC_AUTH_CACHE_DIR/api
95
+
96
+    cp -p $IRONIC_DIR/etc/ironic/policy.json $IRONIC_POLICY_JSON
97
+}
98
+
99
+# configure_ironic_conductor() - Is used by configure_ironic().
100
+# Sets conductor specific settings.
101
+function configure_ironic_conductor() {
102
+    cp $IRONIC_DIR/etc/ironic/rootwrap.conf $IRONIC_ROOTWRAP_CONF
103
+    cp -r $IRONIC_DIR/etc/ironic/rootwrap.d $IRONIC_ROOTWRAP_FILTERS
104
+
105
+    iniset $IRONIC_CONF DEFAULT rootwrap_config $IRONIC_ROOTWRAP_CONF
106
+}
107
+
108
+# create_ironic_cache_dir() - Part of the init_ironic() process
109
+function create_ironic_cache_dir() {
110
+    # Create cache dir
111
+    sudo mkdir -p $IRONIC_AUTH_CACHE_DIR/api
112
+    sudo chown $STACK_USER $IRONIC_AUTH_CACHE_DIR/api
113
+    rm -f $IRONIC_AUTH_CACHE_DIR/api/*
114
+    sudo mkdir -p $IRONIC_AUTH_CACHE_DIR/registry
115
+    sudo chown $STACK_USER $IRONIC_AUTH_CACHE_DIR/registry
116
+    rm -f $IRONIC_AUTH_CACHE_DIR/registry/*
117
+}
118
+
119
+# create_ironic_accounts() - Set up common required ironic accounts
120
+
121
+# Tenant               User       Roles
122
+# ------------------------------------------------------------------
123
+# service              ironic     admin        # if enabled
124
+create_ironic_accounts() {
125
+
126
+    SERVICE_TENANT=$(keystone tenant-list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
127
+    ADMIN_ROLE=$(keystone role-list | awk "/ admin / { print \$2 }")
128
+
129
+    # Ironic
130
+    if [[ "$ENABLED_SERVICES" =~ "ir-api" ]]; then
131
+        IRONIC_USER=$(keystone user-create \
132
+            --name=ironic \
133
+            --pass="$SERVICE_PASSWORD" \
134
+            --tenant_id $SERVICE_TENANT \
135
+            --email=ironic@example.com \
136
+            | grep " id " | get_field 2)
137
+        keystone user-role-add \
138
+            --tenant_id $SERVICE_TENANT \
139
+            --user_id $IRONIC_USER \
140
+            --role_id $ADMIN_ROLE
141
+        if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
142
+            IRONIC_SERVICE=$(keystone service-create \
143
+                --name=ironic \
144
+                --type=baremetal \
145
+                --description="Ironic baremetal provisioning service" \
146
+                | grep " id " | get_field 2)
147
+            keystone endpoint-create \
148
+                --region RegionOne \
149
+                --service_id $IRONIC_SERVICE \
150
+                --publicurl "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT/v1/" \
151
+                --adminurl "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT/v1/" \
152
+                --internalurl "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT/v1/"
153
+        fi
154
+    fi
155
+}
156
+
157
+
158
+# init_ironic() - Initialize databases, etc.
159
+function init_ironic() {
160
+    # (Re)create  ironic database
161
+    recreate_database ironic utf8
162
+
163
+    # Migrate ironic database
164
+    $IRONIC_BIN_DIR/ironic-dbsync
165
+
166
+    create_ironic_cache_dir
167
+
168
+    # Create keystone artifacts for Ironic.
169
+    create_ironic_accounts
170
+}
171
+
172
+# install_ironic() - Collect source and prepare
173
+function install_ironic() {
174
+    git_clone $IRONIC_REPO $IRONIC_DIR $IRONIC_BRANCH
175
+    setup_develop $IRONIC_DIR
176
+}
177
+
178
+# start_ironic() - Start running processes, including screen
179
+function start_ironic() {
180
+    # Start Ironic API server, if enabled.
181
+    if is_service_enabled ir-api; then
182
+        start_ironic_api
183
+    fi
184
+
185
+    # Start Ironic conductor, if enabled.
186
+    if is_service_enabled ir-cond; then
187
+        start_ironic_conductor
188
+    fi
189
+}
190
+
191
+# start_ironic_api() - Used by start_ironic().
192
+# Starts Ironic API server.
193
+function start_ironic_api() {
194
+    screen_it ir-api "cd $IRONIC_DIR; $IRONIC_BIN_DIR/ironic-api --config-file=$IRONIC_CONF_FILE"
195
+    echo "Waiting for ir-api ($IRONIC_HOSTPORT) to start..."
196
+    if ! timeout $SERVICE_TIMEOUT sh -c "while ! http_proxy= wget -q -O- http://$IRONIC_HOSTPORT; do sleep 1; done"; then
197
+      die $LINENO "ir-api did not start"
198
+    fi
199
+}
200
+
201
+# start_ironic_conductor() - Used by start_ironic().
202
+# Starts Ironic conductor.
203
+function start_ironic_conductor() {
204
+    screen_it ir-cond "cd $IRONIC_DIR; $IRONIC_BIN_DIR/ironic-conductor --config-file=$IRONIC_CONF_FILE"
205
+    # TODO(romcheg): Find a way to check whether the conductor has started.
206
+}
207
+
208
+# stop_ironic() - Stop running processes
209
+function stop_ironic() {
210
+    # Kill the Ironic screen windows
211
+    screen -S $SCREEN_NAME -p ir-api -X kill
212
+    screen -S $SCREEN_NAME -p ir-cond -X kill
213
+}
214
+
215
+
216
+# Restore xtrace
217
+$XTRACE
218
+
219
+# Local variables:
220
+# mode: shell-script
221
+# End:
... ...
@@ -318,6 +318,7 @@ source $TOP_DIR/lib/heat
318 318
 source $TOP_DIR/lib/neutron
319 319
 source $TOP_DIR/lib/baremetal
320 320
 source $TOP_DIR/lib/ldap
321
+source $TOP_DIR/lib/ironic
321 322
 
322 323
 # Set the destination directories for other OpenStack projects
323 324
 OPENSTACKCLIENT_DIR=$DEST/python-openstackclient
... ...
@@ -778,6 +779,11 @@ if is_service_enabled tls-proxy; then
778 778
     # don't be naive and add to existing line!
779 779
 fi
780 780
 
781
+if is_service_enabled ir-api ir-cond; then
782
+    install_ironic
783
+    configure_ironic
784
+fi
785
+
781 786
 if [[ $TRACK_DEPENDS = True ]]; then
782 787
     $DEST/.venv/bin/pip freeze > $DEST/requires-post-pip
783 788
     if ! diff -Nru $DEST/requires-pre-pip $DEST/requires-post-pip > $DEST/requires.diff; then
... ...
@@ -946,6 +952,15 @@ if is_service_enabled g-reg; then
946 946
     init_glance
947 947
 fi
948 948
 
949
+# Ironic
950
+# ------
951
+
952
+if is_service_enabled ir-api ir-cond; then
953
+    echo_summary "Configuring Ironic"
954
+    init_ironic
955
+fi
956
+
957
+
949 958
 
950 959
 # Neutron
951 960
 # -------
... ...
@@ -1186,6 +1201,12 @@ if is_service_enabled g-api g-reg; then
1186 1186
     start_glance
1187 1187
 fi
1188 1188
 
1189
+# Launch the Ironic services
1190
+if is_service_enabled ir-api ir-cond; then
1191
+    echo_summary "Starting Ironic"
1192
+    start_ironic
1193
+fi
1194
+
1189 1195
 # Create an access key and secret key for nova ec2 register image
1190 1196
 if is_service_enabled key && is_service_enabled swift3 && is_service_enabled nova; then
1191 1197
     NOVA_USER_ID=$(keystone user-list | grep ' nova ' | get_field 1)
... ...
@@ -96,6 +96,10 @@ HEATCLIENT_BRANCH=${HEATCLIENT_BRANCH:-master}
96 96
 HORIZON_REPO=${HORIZON_REPO:-${GIT_BASE}/openstack/horizon.git}
97 97
 HORIZON_BRANCH=${HORIZON_BRANCH:-master}
98 98
 
99
+# baremetal provisionint service
100
+IRONIC_REPO=${IRONIC_REPO:-${GIT_BASE}/openstack/ironic.git}
101
+IRONIC_BRANCH=${IRONIC_BRANCH:-master}
102
+
99 103
 # unified auth system (manages accounts/tokens)
100 104
 KEYSTONE_REPO=${KEYSTONE_REPO:-${GIT_BASE}/openstack/keystone.git}
101 105
 KEYSTONE_BRANCH=${KEYSTONE_BRANCH:-master}
... ...
@@ -33,6 +33,7 @@ source $TOP_DIR/lib/cinder
33 33
 source $TOP_DIR/lib/horizon
34 34
 source $TOP_DIR/lib/swift
35 35
 source $TOP_DIR/lib/neutron
36
+source $TOP_DIR/lib/ironic
36 37
 
37 38
 # Determine what system we are running on.  This provides ``os_VENDOR``,
38 39
 # ``os_RELEASE``, ``os_UPDATE``, ``os_PACKAGE``, ``os_CODENAME``
... ...
@@ -71,6 +72,12 @@ if is_service_enabled s-proxy; then
71 71
     cleanup_swift
72 72
 fi
73 73
 
74
+# Ironic runs daemons
75
+if is_service_enabled ir-api ir-cond; then
76
+    stop_ironic
77
+    cleanup_ironic
78
+fi
79
+
74 80
 # Apache has the WSGI processes
75 81
 if is_service_enabled horizon; then
76 82
     stop_horizon