參考這個網頁去安裝
http://docs.openstack.org/diablo/openstack-compute/install/content/index.html
Management Network (RFC1918 IP Range, not publicly routable): This network is utilized for all inter-server communications within the cloud infrastructure. Recommended size: 255 IPs (CIDR /24)
Public Network (Publicly routable IP range): This network is utilized for providing Public IP accessibility to the API endpoints within the cloud infrastructure. Minimum size: 8 IPs (CIDR /29)
VM Network (RFC1918 IP Range, not publicly routable): This network is utilized for providing primary IP addresses to the cloud instances. Recommended size: 1024 IPs (CIDR /22)
Floating IP network (Publicly routable IP Range): This network is utilized for providing Public IP accessibility to selected cloud instances. Minimum size: 16 IPs (CIDR /28)
Diablo Release 中新增加了 Keystone 及 horizon, 但剛 Release 時整合做的沒有很好, 老是會有一些怪怪的問題, 目前這篇的安裝寫的還滿清楚的, 也把一些問題解決了, 下面是我的安裝紀錄, 基本上都和網頁上的差不多, 在安裝之前, 請一定要修改一下 apt-get repository 的設定, 用原來 Ubuntu 提供的 package 可能會永遠裝不起來, 版號也會不相同
wistor@wistor-dev-6:~$ sudo apt-get install python-software-properties
wistor@wistor-dev-6:~$ sudo add-apt-repository -y ppa:managedit/openstack
wistor@wistor-dev-6:~$ sudo apt-get update
wistor@wistor-dev-6:~$ sudo apt-get install -y managedit-openstack-pin
Keystone Installation
wistor@wistor-dev-6:~$ sudo apt-get install keystone
wistor@wistor-dev-6:~$ sudo apt-get install curl
wistor@wistor-dev-6:~$ sudo rm /var/lib/keystone/keystone.db
# 中間會請你輸入 administrator 的密碼, 請記起來
wistor@wistor-dev-6:~$ sudo apt-get install python-mysqldb mysql-server
都安裝好之後, 開始設定 mysql
# 之後這個 database 可能會需要讓其他機器存取, 所以要把 binding ip 改掉
wistor@wistor-dev-6:~$ sudo sed -i 's/127.0.0.1/0.0.0.0/g' /etc/mysql/my.cnf
wistor@wistor-dev-6:~$ cat /etc/mysql/my.cnf | grep 0.0.0.0
bind-address = 0.0.0.0
wistor@wistor-dev-6:~$ sudo service mysql restart
mysql start/running, process 23775
wistor@wistor-dev-6:~$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 35
Server version: 5.1.58-1ubuntu1 (Ubuntu)
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
# 製造一個 keyston 的 database
mysql> CREATE DATABASE keystone;
Query OK, 1 row affected (0.00 sec)
# 讓 keystone 可以自由存取這個 database, 並且設定一組密碼
mysql> GRANT ALL ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.00 sec)
mysql> quit
Bye
接下來設定 keystone
# 把設定改一下
wistor@wistor-dev-6:~$ sudo nano /etc/keystone/keystone.conf
wistor@wistor-dev-6:~$ sudo cat /etc/keystone/keystone.conf | grep -A 10 backend
[sudo] password for wistor:
# Which backend store should Keystone use by default.
# Default: 'sqlite'
# Available choices are 'sqlite' [future will include LDAP, PAM, etc]
# 這裡看起來怪怪的, 已經改用了 mysql , 但他仍然是設定 sqlite, 先不要理它
default_store = sqlite
--
[keystone.backends.sqlalchemy]
# SQLAlchemy connection string for the reference implementation registry
# server. Any valid SQLAlchemy connection string is fine.
# See: http://bit.ly/ideIpI
# sql_connection = sqlite:////var/lib/keystone/keystone.db
# 這行才是重點, 其中要記得你剛剛在 mysql 內替 keystone 設定的密碼
sql_connection = mysql://keystone:password@172.16.123.6/keystone
backend_entities = ['UserRoleAssociation', 'Endpoints', 'Role', 'Tenant',
'User', 'Credentials', 'EndpointTemplates', 'Token',
'Service']
# 設定都設好之後, 記得把 configuration 的權限設定好
wistor@wistor-dev-6:~$ sudo chown keystone /etc/keystone/keystone.conf
wistor@wistor-dev-6:~$ sudo chmod 0640 /etc/keystone/keystone.conf
wistor@wistor-dev-6:~$ ll
total 16
drwxr-xr-x 2 root root 4096 2012-02-23 15:55 ./
drwxr-xr-x 105 root root 4096 2012-02-23 15:56 ../
-rw-r----- 1 keystone root 2741 2012-02-23 16:11 keystone.conf
-rw-r--r-- 1 root root 913 2012-01-05 20:31 logging.cnf
wistor@wistor-dev-6:~$ sudo service keystone restart
keystone start/running, process 23893
接下來我們要把一些 tenant/user/role/token/service 都加進去
wistor@wistor-dev-6:~$ sudo keystone-manage tenant add openstackDemo
SUCCESS: Tenant openstackDemo created.
wistor@wistor-dev-6:~$ sudo keystone-manage tenant add adminTenant
SUCCESS: Tenant adminTenant created.
wistor@wistor-dev-6:~$ sudo keystone-manage user add adminUser password
SUCCESS: User adminUser created.
wistor@wistor-dev-6:~$ sudo keystone-manage user add demoUser password
SUCCESS: User demoUser created.
wistor@wistor-dev-6:~$ sudo keystone-manage token add 11121314151617181920 adminUser adminTenant 2015-02-05T00:0
SUCCESS: Token 11121314151617181920 created.
wistor@wistor-dev-6:~$ sudo keystone-manage role add Admin
SUCCESS: Role Admin created successfully.
wistor@wistor-dev-6:~$ sudo keystone-manage role add Member
SUCCESS: Role Member created successfully.
wistor@wistor-dev-6:~$ sudo keystone-manage role grant Admin adminUser
SUCCESS: Granted Admin the adminUser role on None.
wistor@wistor-dev-6:~$ sudo keystone-manage role grant Member demoUser
SUCCESS: Granted Member the demoUser role on None.
wistor@wistor-dev-6:~$ sudo keystone-manage role grant Admin adminUser openstackDemo
SUCCESS: Granted Admin the adminUser role on openstackDemo.
wistor@wistor-dev-6:~$ udo keystone-manage role grant Admin adminUser adminTenant
The program 'udo' is currently not installed. You can install it by typing:
sudo apt-get install udo
wistor@wistor-dev-6:~$ sudo keystone-manage role grant Admin adminUser adminTenant
SUCCESS: Granted Admin the adminUser role on adminTenant.
wistor@wistor-dev-6:~$ sudo keystone-manage role grant Member demoUser openstackDemo
SUCCESS: Granted Member the demoUser role on openstackDemo.
wistor@wistor-dev-6:~$ sudo keystone-manage service add nova compute "Nova Compute Service"
SUCCESS: Service nova created successfully.
wistor@wistor-dev-6:~$ sudo keystone-manage service add glance image "Glance Image Service"
SUCCESS: Service glance created successfully.
wistor@wistor-dev-6:~$ sudo keystone-manage service add keystone identity "Keystone Identity Service"
wistor@wistor-dev-6:~$ sudo keystone-manage endpointTemplates add RegionOne nova http://172.16.123.6:8774/v1.1/%tenant_id% http://172.16.123.6:8774/v1.1/%tenant_id% http://172.16.123.6:8774/v1.1/%tenant_id% 1 1
SUCCESS: Created EndpointTemplates for nova pointing to http://172.16.123.6:8774/v1.1/%tenant_id%.
wistor@wistor-dev-6:~$ sudo keystone-manage endpointTemplates add RegionOne glance http://172.16.123.6:9292/v1 http://172.16.123.6:9292/v1 http://172.16.123.6:9292/v1 1 1
SUCCESS: Created EndpointTemplates for glance pointing to http://172.16.123.6:9292/v1.
wistor@wistor-dev-6:~$ sudo keystone-manage endpointTemplates add RegionOne keystone http://172.16.123.6:5000/v2.0 http://172.16.123.6:35357/v2.0 http://172.16.123.6:5000/v2.0 1 1
SUCCESS: Created EndpointTemplates for keystone pointing to http://172.16.123.6:5000/v2.0.
wistor@wistor-dev-6:~$ sudo keystone-manage credentials add adminUser EC2 'password' adminTenant
SUCCESS: Credentials adminUser created.
wistor@wistor-dev-6:~$ sudo keystone-manage credentials add demoUser EC2 'password' openstackDemo
SUCCESS: Credentials demoUser created.
都加好之後, 我們看一下設定有沒有正確
wistor@wistor-dev-6:~$ keystone-manage --version
keystone-manage 2011.3.1
wistor@wistor-dev-6:~$ sudo keystone-manage tenant list
id name enabled
-------------------------------------------------------------------------------
1 openstackDemo 1
2 adminTenant 1
wistor@wistor-dev-6:~$ sudo keystone-manage user list
id name enabled tenant
-------------------------------------------------------------------------------
1 adminUser 1 None
2 demoUser 1 None
wistor@wistor-dev-6:~$ sudo keystone-manage role list
id name
-------------------------------------------------------------------------------
1 Admin
2 Member
wistor@wistor-dev-6:~$ sudo keystone-manage service list
id name type
-------------------------------------------------------------------------------
1 nova compute
2 glance image
3 keystone identity
wistor@wistor-dev-6:~$ sudo keystone-manage endpointTemplates list
All EndpointTemplates
service region Public URL
-------------------------------------------------------------------------------
nova RegionOne http://172.16.123.6:8774/v1.1/%tenant_id%
glance RegionOne http://172.16.123.6:9292/v1
keystone RegionOne http://172.16.123.6:5000/v2.0
wistor@wistor-dev-6:~$ sudo keystone-manage token list
token user expiration tenant
-------------------------------------------------------------------------------
11121314151617181920 1 2015-02-05 00:00:00 2
利用 curl 測試一下
wistor@wistor-dev-6:~$ curl -d '{"auth": {"tenantName": "adminTenant", "passwordCredentials":{"username": "adminUser", "password": "password"}}}' -H "Content-type: application/json" http://172.16.123.6:35357/v2.0/tokens | python -mjson.tool
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1044 100 932 100 112 15248 1832 --:--:-- --:--:-- --:--:-- 15533
{
"access": {
"serviceCatalog": [
{
"endpoints": [
{
"adminURL": "http://172.16.123.6:8774/v1.1/2",
"internalURL": "http://172.16.123.6:8774/v1.1/2",
"publicURL": "http://172.16.123.6:8774/v1.1/2",
"region": "RegionOne"
}
],
"name": "nova",
"type": "compute"
},
{
"endpoints": [
{
"adminURL": "http://172.16.123.6:9292/v1",
"internalURL": "http://172.16.123.6:9292/v1",
"publicURL": "http://172.16.123.6:9292/v1",
"region": "RegionOne"
}
],
"name": "glance",
"type": "image"
},
{
"endpoints": [
{
"adminURL": "http://172.16.123.6:35357/v2.0",
"internalURL": "http://172.16.123.6:5000/v2.0",
"publicURL": "http://172.16.123.6:5000/v2.0",
"region": "RegionOne"
}
],
"name": "keystone",
"type": "identity"
}
],
"token": {
"expires": "2015-02-05T00:00:00",
"id": "11121314151617181920",
"tenant": {
"id": "2",
"name": "adminTenant"
}
},
"user": {
"id": "1",
"name": "adminUser",
"roles": [
{
"id": "1",
"name": "Admin",
"tenantId": "2"
},
{
"id": "1",
"name": "Admin"
}
]
}
}
}
wistor@wistor-dev-6:~$ curl -d '{"auth": {"tenantName": "openstackDemo", "passwordCredentials":{"username": "adminUser", "password": "password"}}}' -H "Content-type: application/json" http://172.16.123.6:35357/v2.0/tokens | python -mjson.tool
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1076 100 962 100 114 15747 1866 --:--:-- --:--:-- --:--:-- 16033
{
"access": {
"serviceCatalog": [
{
"endpoints": [
{
"adminURL": "http://172.16.123.6:8774/v1.1/1",
"internalURL": "http://172.16.123.6:8774/v1.1/1",
"publicURL": "http://172.16.123.6:8774/v1.1/1",
"region": "RegionOne"
}
],
"name": "nova",
"type": "compute"
},
{
"endpoints": [
{
"adminURL": "http://172.16.123.6:9292/v1",
"internalURL": "http://172.16.123.6:9292/v1",
"publicURL": "http://172.16.123.6:9292/v1",
"region": "RegionOne"
}
],
"name": "glance",
"type": "image"
},
{
"endpoints": [
{
"adminURL": "http://172.16.123.6:35357/v2.0",
"internalURL": "http://172.16.123.6:5000/v2.0",
"publicURL": "http://172.16.123.6:5000/v2.0",
"region": "RegionOne"
}
],
"name": "keystone",
"type": "identity"
}
],
"token": {
"expires": "2012-02-24T17:16:43.557972",
"id": "89abab7f-c9ef-47fa-baf3-5bce1bc64037",
"tenant": {
"id": "1",
"name": "openstackDemo"
}
},
"user": {
"id": "1",
"name": "adminUser",
"roles": [
{
"id": "1",
"name": "Admin",
"tenantId": "1"
},
{
"id": "1",
"name": "Admin"
}
]
}
}
}
Glance Installation
安裝 Glance 的 package
wistor@wistor-dev-6:~$ sudo apt-get install glance
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
glance
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/25.6 kB of archives.
After this operation, 229 kB of additional disk space will be used.
Selecting previously deselected package glance.
(Reading database ... 89936 files and directories currently installed.)
Unpacking glance (from .../glance_2011.3.1~20120117~1549-0mit1~22.gbp5e7c88_all.deb) ...
Processing triggers for ureadahead ...
Setting up glance (2011.3.1~20120117~1549-0mit1~22.gbp5e7c88) ...
Adding system user `glance' (UID 108) ...
Adding new user `glance' (UID 108) with group `glance' ...
Not creating home directory `/var/lib/glance'.
glance-api start/running, process 1299
glance-registry start/running, process 1323
wistor@wistor-dev-6:~$ glance --version
glance 2011.3.1-dev
設定一下 glance, 預設一樣是 sqlite, 改成 mysql
wistor@wistor-dev-6:~$
sudo rm /var/lib/glance/glance.sqlite
wistor@wistor-dev-6:~$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 45
Server version: 5.1.58-1ubuntu1 (Ubuntu)
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CREATE DATABASE glance;
Query OK, 1 row affected (0.00 sec)
mysql> GRANT ALL ON glance.* TO 'glance'@'%' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.00 sec)
mysql> quit
Bye
再來設定 glance 三個設定檔, 要修改的有 pipeline 及 token id, database 也要改成 mysql
wistor@wistor-dev-6:~$ sudo nano /etc/glance/glance-registry.conf
wistor@wistor-dev-6:~$ sudo less /etc/glance/glance-registry.conf | grep -A 10 pipe
[pipeline:glance-registry]
# pipeline = context registryapp
# NOTE: use the following pipeline for keystone
############## 修改這個 #####################
pipeline = authtoken auth-context registryapp
wistor@wistor-dev-6:~$ sudo less /etc/glance/glance-registry.conf | grep -A 20 filter:authtoken
[filter:authtoken]
paste.filter_factory = keystone.middleware.auth_token:filter_factory
service_protocol = http
service_host = 127.0.0.1
service_port = 5000
auth_host = 127.0.0.1
auth_port = 35357
auth_protocol = http
auth_uri = http://127.0.0.1:5000/
############## 修改這個 #####################
admin_token = 11121314151617181920
[filter:auth-context]
############## 修改這個 #####################
context_class = glance.registry.context.RequestContext
paste.filter_factory = keystone.middleware.glance_auth_token:filter_factory
wistor@wistor-dev-6:~$ sudo less /etc/glance/glance-registry.conf | grep sql
# See: http://www.sqlalchemy.org/docs/05/reference/sqlalchemy/connections.html#sqlalchemy.create_engine
# sql_connection = sqlite:////var/lib/glance/glance.sqlite
############## 修改這個 #####################
sql_connection = mysql://glance:password@172.16.123.6/glance
sql_idle_timeout = 3600
wistor@wistor-dev-6:~$ sudo nano /etc/glance/glance-api.conf
wistor@wistor-dev-6:~$ sudo less /etc/glance/glance-api.conf | grep -A 10 pipe
[pipeline:glance-api]
# pipeline = versionnegotiation context apiv1app
# NOTE: use the following pipeline for keystone
# pipeline = versionnegotiation authtoken auth-context apiv1app
# To enable Image Cache Management API replace pipeline with below:
# pipeline = versionnegotiation context imagecache apiv1app
# NOTE: use the following pipeline for keystone auth (with caching)
# pipeline = versionnegotiation authtoken auth-context imagecache apiv1app
############## 修改這個 #####################
# 注意: auth-context 這個 tag 要和最後定義的一樣, 網頁上是改成 keystone-shim, 和預設的不一樣
pipeline = versionnegotiation authtoken auth-context apiv1app
wistor@wistor-dev-6:~$ sudo less /etc/glance/glance-api.conf | grep -A 20 filter:authtoken
[filter:authtoken]
paste.filter_factory = keystone.middleware.auth_token:filter_factory
service_protocol = http
service_host = 127.0.0.1
service_port = 5000
auth_host = 127.0.0.1
auth_port = 35357
auth_protocol = http
auth_uri = http://127.0.0.1:5000/
############## 修改這個 #####################
admin_token = 11121314151617181920
[filter:auth-context]
############## 修改這個 #####################
context_class = glance.registry.context.RequestContext
paste.filter_factory = keystone.middleware.glance_auth_token:filter_factory
wistor@wistor-dev-6:~$ sudo nano /etc/glance/glance-scrubber.conf
wistor@wistor-dev-6:~$ sudo less /etc/glance/glance-scrubber.conf | grep -A 10 SQLAlchemy
# SQLAlchemy connection string for the reference implementation
# registry server. Any valid SQLAlchemy connection string is fine.
# See: http://www.sqlalchemy.org/docs/05/reference/sqlalchemy/connections.html#sqlalchemy.create_engine
############## 修改這個 #####################
# sql_connection = sqlite:////var/lib/glance/glance.sqlite
sql_connection = mysql://glance:password@172.16.123.6/glance
wistor@wistor-dev-6:~$ sudo restart glance-registry
glance-registry start/running, process 3874
wistor@wistor-dev-6:~$ sudo restart glance-api
glance-api start/running, process 3878
wistor@wistor-dev-6:~$
設定一些環境變數
wistor@wistor-dev-6:~$ mkdir ~/creds
wistor@wistor-dev-6:~$ sudo nano ~/creds/openrc
wistor@wistor-dev-6:~$ cat ~/creds/openrc
export NOVA_USERNAME=adminUser
export NOVA_PROJECT_ID=openstackDemo
export NOVA_PASSWORD=password
export NOVA_API_KEY=${NOVA_PASSWORD}
export NOVA_URL=http://172.16.123.6:5000/v2.0/
export NOVA_VERSION=1.1
export NOVA_REGION_NAME=RegionOne
export OS_AUTH_USER=${NOVA_USERNAME}
export OS_AUTH_KEY=${NOVA_PASSWORD}
export OS_AUTH_TENANT=${NOVA_PROJECT_ID}
export OS_AUTH_URL=${NOVA_URL}
export OS_AUTH_STRATEGY=keystone
wistor@wistor-dev-6:~$ source ~/creds/openrc
wistor@wistor-dev-6:~$ echo ${OS_AUTH_USER}
adminUser
接下來就是驗証的時間, 我們先和 keystone 拿一個可用的 token , 然後用這個 token 進入 glance 去看它有沒有 image
wistor@wistor-dev-6:~$ curl -d '{"auth": {"tenantName": "openstackDemo", "passwordCredentials":{"username": "adminUser", "password": "password"}}}' -H "Content-type: application/json" http://172.16.123.6:35357/v2.0/tokens | python -mjson.tool
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1069 100 955 100 114 15158 1809 --:--:-- --:--:-- --:--:-- 15403
{
"access": {
"serviceCatalog": [
{
"endpoints": [
{
"adminURL": "http://172.16.123.6:8774/v1.1/1",
"internalURL": "http://172.16.123.6:8774/v1.1/1",
"publicURL": "http://172.16.123.6:8774/v1.1/1",
"region": "RegionOne"
}
],
"name": "nova",
"type": "compute"
},
{
"endpoints": [
{
"adminURL": "http://172.16.123.6:9292/v1",
"internalURL": "http://172.16.123.6:9292/v1",
"publicURL": "http://172.16.123.6:9292/v1",
"region": "RegionOne"
}
],
"name": "glance",
"type": "image"
},
{
"endpoints": [
{
"adminURL": "http://172.16.123.6:35357/v2.0",
"internalURL": "http://172.16.123.6:5000/v2.0",
"publicURL": "http://172.16.123.6:5000/v2.0",
"region": "RegionOne"
}
],
"name": "keystone",
"type": "identity"
}
}
],
"token": {
"expires": "2012-03-01T15:20:10",
"id": "ff7984c9-9226-46b4-beb9-029710f69b0d",
"tenant": {
"id": "1",
"name": "openstackDemo"
}
},
"user": {
"id": "1",
"name": "adminUser",
"roles": [
{
"id": "1",
"name": "Admin",
"tenantId": "1"
},
{
"id": "1",
"name": "Admin"
}
]
}
}
}
# 用我們拿到的 token id
wistor@wistor-dev-6:~$ glance details -A ff7984c9-9226-46b4-beb9-029710f69b0d
# 因為沒有 image, 所以沒有資訊
# 但如果 glance 或是 keystone 沒有設定好的話, 你可能會看到以下訊息
wistor@wistor-dev-6:~$ sudo glance details -A ff7984c9-9226-46b4-beb9-029710f69b0d
Failed to show details. Got error:
Internal Server error: Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/eventlet/wsgi.py", line 336, in handle_one_response
result = self.application(self.environ, start_response)
File "/usr/lib/python2.7/dist-packages/webob/dec.py", line 147, in __call__
resp = self.call_func(req, *args, **self.kwargs)
File "/usr/lib/python2.7/dist-packages/webob/dec.py", line 208, in call_func
return self.func(req, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/glance/common/wsgi.py", line 113, in __call__
response = req.get_response(self.application)
File "/usr/lib/python2.7/dist-packages/webob/request.py", line 1053, in get_response
application, catch_exc_info=False)
File "/usr/lib/python2.7/dist-packages/webob/request.py", line 1022, in call_application
app_iter = application(self.environ, start_response)
File "/usr/lib/python2.7/dist-packages/webob/dec.py", line 147, in __call__
resp = self.call_func(req, *args, **self.kwargs)
File "/usr/lib/python2.7/dist-packages/webob/dec.py", line 208, in call_func
return self.func(req, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/glance/common/wsgi.py", line 110, in __call__
response = self.process_request(req)
File "/usr/lib/python2.7/dist-packages/glance/common/context.py", line 104, in process_request
raise exception.NotAuthorized()
NotAuthorized: None
Nova Installation
- You need an LVM volume group called "nova-volumes" to provide persistent storage to guest VMs. Either create this during the installation or leave some free space to create it prior to installing nova services.
- 192.168.100.0/24 as the fixed range for our guest VMs, connected to the host via br100.
先設定一下網路
wistor@wistor-dev-6:~$ cat /etc/network/interfaces
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 172.16.123.6
netmask 255.255.0.0
gateway 172.16.1.254
# Bridge network interface for VM networks
auto br100
iface br100 inet static
address 192.168.100.1
netmask 255.255.255.0
bridge_stp off
bridge_fd 0
wistor@wistor-dev-6:~$ sudo apt-get install bridge-utils
wistor@wistor-dev-6:~$ sudo brctl addbr br100
wistor@wistor-dev-6:~$ sudo /etc/init.d/networking restart
設定一下 mysql
wistor@wistor-dev-6:~$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 54
Server version: 5.1.58-1ubuntu1 (Ubuntu)
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CREATE DATABASE nova;
Query OK, 1 row affected (0.00 sec)
mysql> GRANT ALL ON nova.* TO 'nova'@'%' IDENTIFIED BY
-> 'password';
Query OK, 0 rows affected (0.00 sec)
mysql> quit
其中我們沒有裝 nova-objectstore, 因為要使用 glance
wistor@wistor-dev-6:~$ sudo apt-get install rabbitmq-server
wistor@wistor-dev-6:~$ sudo apt-get install nova-compute nova-volume nova-vncproxy nova-api nova-ajax-console-proxy nova-doc nova-scheduler nova-network
wistor@wistor-dev-6:~$ sudo apt-get install -y unzip
wistor@wistor-dev-6:~$ sudo apt-get install -y euca2ools
nova 可以設定的東西很多, 這個指令可以看到所有的說明
nova-api --help
首先先設定 nova.conf
wistor@wistor-dev-6:~$ sudo cat /etc/nova/nova.conf
[sudo] password for wistor:
# DATABASE
--sql_connection=mysql://nova:password@172.16.123.6/nova
# LOGS/STATE
--verbose
--dhcpbridge_flagfile=/etc/nova/nova.conf
--dhcpbridge=/usr/bin/nova-dhcpbridge
--logdir=/var/log/nova
--state_path=/var/lib/nova
--lock_path=/var/lock/nova
# RABBITMQ
--rabbit_password=guest
--rabbit_port=5672
--rabbit_host=172.16.123.6
# SCHEDULER
--scheduler_driver=nova.scheduler.simple.SimpleScheduler
# NETWORK
--network_manager=nova.network.manager.FlatDHCPManager
--fixed_range=192.168.100.0/24
# 這行經查証後沒有用
--flat_network_dhcp_start=192.168.100.2
--public_interface=eth0
--flat_interface=eth0
--flat_network_bridge=br100
# GLANCE
--image_service=nova.image.glance.GlanceImageService
--glance_api_servers=172.16.123.6:9292
# COMPUTE
--compute_manager=nova.compute.manager.ComputeManager
--libvirt_type=qemu
# VNCPROXY
--vncproxy_url=http://172.16.123.6:6080
--vncproxy_wwwroot=/var/lib/nova/noVNC
# MISC
--use_deprecated_auth=false
--allow_admin_api=true
--enable_zone_routing=true
# KEYSTONE
--keystone_ec2_url=http://172.16.123.6:5000/v2.0/ec2tokens
再來設定 api-paste.ini, 把 authentication 的部份都換成 keystone
wistor@wistor-dev-6:~$ sudo cat /etc/nova/api-paste.ini
#######
# EC2 #
#######
[composite:ec2]
use = egg:Paste#urlmap
/: ec2versions
/services/Cloud: ec2cloud
/services/Admin: ec2admin
/latest: ec2metadata
/2007-01-19: ec2metadata
/2007-03-01: ec2metadata
/2007-08-29: ec2metadata
/2007-10-10: ec2metadata
/2007-12-15: ec2metadata
/2008-02-01: ec2metadata
/2008-09-01: ec2metadata
/2009-04-04: ec2metadata
/1.0: ec2metadata
[pipeline:ec2cloud]
# pipeline = logrequest ec2noauth cloudrequest authorizer ec2executor
# NOTE(vish): use the following pipeline for deprecated auth
# pipeline = logrequest authenticate cloudrequest authorizer ec2executor
############## 修改這個 #####################
pipeline = logrequest totoken authtoken keystonecontext cloudrequest authorizer ec2executor
[pipeline:ec2admin]
# pipeline = logrequest ec2noauth adminrequest authorizer ec2executor
# NOTE(vish): use the following pipeline for deprecated auth
# pipeline = logrequest authenticate adminrequest authorizer ec2executor
pipeline = logrequest totoken authtoken keystonecontext adminrequest authorizer ec2executor
[pipeline:ec2metadata]
pipeline = logrequest ec2md
[pipeline:ec2versions]
pipeline = logrequest ec2ver
[filter:logrequest]
paste.filter_factory = nova.api.ec2:RequestLogging.factory
[filter:ec2lockout]
paste.filter_factory = nova.api.ec2:Lockout.factory
############## 修改這個 #####################
[filter:totoken]
paste.filter_factory = keystone.middleware.ec2_token:EC2Token.factory
[filter:ec2noauth]
paste.filter_factory = nova.api.ec2:NoAuth.factory
[filter:authenticate]
paste.filter_factory = nova.api.ec2:Authenticate.factory
[filter:cloudrequest]
controller = nova.api.ec2.cloud.CloudController
paste.filter_factory = nova.api.ec2:Requestify.factory
[filter:adminrequest]
controller = nova.api.ec2.admin.AdminController
paste.filter_factory = nova.api.ec2:Requestify.factory
[filter:authorizer]
paste.filter_factory = nova.api.ec2:Authorizer.factory
[app:ec2executor]
paste.app_factory = nova.api.ec2:Executor.factory
[app:ec2ver]
paste.app_factory = nova.api.ec2:Versions.factory
[app:ec2md]
paste.app_factory = nova.api.ec2.metadatarequesthandler:MetadataRequestHandler.factory
#############
# Openstack #
#############
[composite:osapi]
use = egg:Paste#urlmap
/: osversions
/v1.0: openstackapi10
/v1.1: openstackapi11
[pipeline:openstackapi10]
# pipeline = faultwrap noauth ratelimit osapiapp10
# NOTE(vish): use the following pipeline for deprecated auth
# pipeline = faultwrap auth ratelimit osapiapp10
############## 修改這個 #####################
pipeline = faultwrap authtoken keystonecontext ratelimit osapiapp10
[pipeline:openstackapi11]
# pipeline = faultwrap noauth ratelimit extensions osapiapp11
# NOTE(vish): use the following pipeline for deprecated auth
# pipeline = faultwrap auth ratelimit extensions osapiapp11
############## 修改這個 #####################
pipeline = faultwrap authtoken keystonecontext ratelimit extensions osapiapp11
[filter:faultwrap]
paste.filter_factory = nova.api.openstack:FaultWrapper.factory
[filter:auth]
paste.filter_factory = nova.api.openstack.auth:AuthMiddleware.factory
[filter:noauth]
paste.filter_factory = nova.api.openstack.auth:NoAuthMiddleware.factory
[filter:ratelimit]
paste.filter_factory = nova.api.openstack.limits:RateLimitingMiddleware.factory
[filter:extensions]
paste.filter_factory = nova.api.openstack.extensions:ExtensionMiddleware.factory
[app:osapiapp10]
paste.app_factory = nova.api.openstack:APIRouterV10.factory
[app:osapiapp11]
paste.app_factory = nova.api.openstack:APIRouterV11.factory
[pipeline:osversions]
pipeline = faultwrap osversionapp
[app:osversionapp]
paste.app_factory = nova.api.openstack.versions:Versions.factory
##########
# Shared #
##########
############## 修改這個 #####################
[filter:keystonecontext]
paste.filter_factory = keystone.middleware.nova_keystone_context:NovaKeystoneContext.factory
############## 修改這個 #####################
[filter:authtoken]
paste.filter_factory = keystone.middleware.auth_token:filter_factory
service_protocol = http
service_host = 172.16.123.6
service_port = 5000
auth_host = 172.16.123.6
auth_port = 35357
auth_protocol = http
auth_uri = http://172.16.123.6:5000/v2.0/
admin_token = 11121314151617181920
設定好了之後, 稍微再確認一下設定檔的權限, 把資料庫建起來, 然後就重啟 nova,
nova 的 restart script 有問題, 所以最好先 stop 再 start , 不然會遇到無法 restart 的狀況
如果有遇到無法啟動的狀況可以看看 /var/log/nova/ 裡面的 log
wistor@wistor-dev-6:~$ sudo groupadd nova
groupadd: group 'nova' already exists
wistor@wistor-dev-6:~$ sudo usermod -g nova nova
usermod: no changes
wistor@wistor-dev-6:~$ sudo chown -R root:nova /etc/nova
wistor@wistor-dev-6:~$ sudo chmod 640 /etc/nova/nova.conf
wistor@wistor-dev-6:~$ sudo nova-manage db sync
sudo stop nova-api
sudo stop nova-compute
sudo stop nova-network
sudo stop nova-scheduler
sudo stop nova-vncproxy
sudo stop libvirt-bin
sudo /etc/init.d/rabbitmq-server stop
sudo start nova-api
sudo start nova-compute
sudo start nova-network
sudo start nova-scheduler
sudo start nova-vncproxy
sudo start libvirt-bin
sudo /etc/init.d/rabbitmq-server start
wistor@wistor-dev-6:~$ sudo nova-manage network create private --multi_host=T --fixed_range_v4=192.168.100.0/24 --num_networks=1 --network_size=256
wistor@wistor-dev-6:~$ sudo nova-manage service list
Binary Host Zone Status State Updated_At
nova-vncproxy wistor-dev-6 nova enabled :-) 2012-02-29 09:35:16
nova-compute wistor-dev-6 nova enabled :-) 2012-02-29 09:35:17
nova-scheduler wistor-dev-6 nova enabled :-) 2012-02-29 09:35:16
nova-network wistor-dev-6 nova enabled :-) 2012-02-29 09:35:16
wistor@wistor-dev-6:~$ sudo nova-manage version list
2011.3.1 (2011.3.1-LOCALBRANCH:LOCALREVISION)
# 因為 user/project 都和 keystone 取代了, 所以暫時是空的
wistor@wistor-dev-6:~/creds$ sudo nova-manage project list
wistor@wistor-dev-6:~/creds$ sudo nova-manage user list
Image Upload
按照網頁先上傳一個最簡單的 image
wistor@wistor-dev-6:~$ mkdir stackimages
wistor@wistor-dev-6:~$ wget -c http://images.ansolabs.com/tty.tgz -O stackimages/tty.tgz
--2012-02-29 17:46:34-- http://images.ansolabs.com/tty.tgz
Resolving images.ansolabs.com... 173.203.89.94
Connecting to images.ansolabs.com|173.203.89.94|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 23717804 (23M) [text/plain]
Saving to: `stackimages/tty.tgz'
100%[==============================================================================>] 23,717,804 3.51M/s in 8.4s
2012-02-29 17:46:44 (2.68 MB/s) - `stackimages/tty.tgz' saved [23717804/23717804]
wistor@wistor-dev-6:~$ sudo tar -zxf stackimages/tty.tgz -C stackimages
wistor@wistor-dev-6:~$ cd stackimages/
wistor@wistor-dev-6:~/stackimages$ ls
aki-tty ami-tty ari-tty tty.tgz
wistor@wistor-dev-6:~/stackimages$ ll
total 23184
drwxrwxr-x 5 wistor wistor 4096 2012-02-29 17:46 ./
drwxr-xr-x 14 wistor wistor 4096 2012-02-29 17:46 ../
drwxr-xr-x 2 501 staff 4096 2011-01-12 08:49 aki-tty/
drwxr-xr-x 2 501 staff 4096 2011-02-04 09:48 ami-tty/
drwxr-xr-x 2 501 staff 4096 2011-01-12 08:49 ari-tty/
-rw-rw-r-- 1 wistor wistor 23717804 2011-02-04 09:48 tty.tgz
# 先和 keystone 要一個 token
wistor@wistor-dev-6:~$ curl -d '{"auth":{"passwordCredentials":{"username": "adminUser", "password": "password"}}}' -H "Content-type: application/json" http://172.16.123.6:35357/v2.0/tokens | python -mjson.tool
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 275 100 193 100 82 4122 1751 --:--:-- --:--:-- --:--:-- 4195
{
"access": {
"token": {
"expires": "2012-03-01T17:47:59.207984",
"id": "4bf447ea-0a05-494e-b145-a46a0a7bea42"
},
"user": {
"id": "1",
"name": "adminUser",
"roles": [
{
"id": "1",
"name": "Admin"
}
]
}
}
}
# 利用這個 token 來塞進 image
wistor@wistor-dev-6:~$ sudo glance add -A 4bf447ea-0a05-494e-b145-a46a0a7bea42 name="tty-kernel" is_public=true container_format=aki disk_format=aki < stackimages/aki-tty/image
Added new image with ID: 1
wistor@wistor-dev-6:~$ sudo glance add -A 4bf447ea-0a05-494e-b145-a46a0a7bea42 name="tty-ramdisk" is_public=true container_format=ari disk_format=ari < stackimages/ari-tty/image
Added new image with ID: 2
# kernel id 及 ramdisk id 要看前兩個指令傳回的訊息
wistor@wistor-dev-6:~$ sudo glance add -A 4bf447ea-0a05-494e-b145-a46a0a7bea42 name="tty" is_public=true container_format=ami disk_format=ami kernel_id=1 ramdisk_id=2 < stackimages/ami-tty/image
Added new image with ID: 3
# 塞進去後看一下結果
wistor@wistor-dev-6:~$ glance -A ff7984c9-9226-46b4-beb9-029710f69b0d index ID Name Disk Format Container Format Size
---------------- ------------------------------ -------------------- -------------------- --------------
3 tty ami ami 25165824
2 tty-ramdisk ari ari 5882349
1 tty-kernel aki aki 4404752
# 事實上我們可以發現這些 image 是存放在 /var/lib/glance/images, 未來如果有和 swift 整合, 應該會換地方
wistor@wistor-dev-6:~$ ll /var/lib/glance/images
total 34636
drwxr-xr-x 2 glance glance 4096 2012-02-29 17:50 ./
drwxr-xr-x 4 glance glance 4096 2012-02-29 15:12 ../
-rw-rw-r-- 1 glance glance 4404752 2012-02-29 17:50 1
-rw-rw-r-- 1 glance glance 5882349 2012-02-29 17:50 2
-rw-rw-r-- 1 glance glance 25165824 2012-02-29 17:50 3
Horizon Installation
其實我有些看不懂為什麼還要裝 git, 可能是因為 Horizon 還在開發中吧~ 所以過程中可能會用 git 抓一些 source 回來
wistor@wistor-dev-6:~$ sudo apt-get install git-core
[sudo] password for wistor:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
git-core
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 1,384 B of archives.
After this operation, 28.7 kB of additional disk space will be used.
Get:1 http://us.archive.ubuntu.com/ubuntu/ oneiric/main git-core all 1:1.7.5.4-1 [1,384 B]
Fetched 1,384 B in 0s (2,152 B/s)
Selecting previously deselected package git-core.
(Reading database ... 97954 files and directories currently installed.)
Unpacking git-core (from .../git-core_1%3a1.7.5.4-1_all.deb) ...
Setting up git-core (1:1.7.5.4-1) ...
wistor@wistor-dev-6:~$ sudo apt-get install -y libapache2-mod-wsgi
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
libapache2-mod-wsgi
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/133 kB of archives.
After this operation, 426 kB of additional disk space will be used.
Selecting previously deselected package libapache2-mod-wsgi.
(Reading database ... 97860 files and directories currently installed.)
Unpacking libapache2-mod-wsgi (from .../libapache2-mod-wsgi_3.3-2ubuntu3_amd64.deb) ...
Setting up libapache2-mod-wsgi (3.3-2ubuntu3) ...
* Restarting web server apache2
apache2: Could not reliably determine the server's fully qualified domain name, using 172.16.123.6 for ServerName
apache2: Could not reliably determine the server's fully qualified domain name, using 172.16.123.6 for ServerName
...done.
wistor@wistor-dev-6:~$ sudo apt-get install -y openstack-dashboard openstackx python-sqlite
Setting up openstack-dashboard (2011.3+20120121~1341-0mit1~21.gbp510894) ...
INFO:root:Running in debug mode without debug_toolbar.
INFO:root:Running in debug mode without debug_toolbar.
DEBUG:django.db.backends:(0.000)
SELECT name FROM sqlite_master
WHERE type='table' AND NOT name='sqlite_sequence'
ORDER BY name; args=()
Creating tables ...
Creating table django_content_type
DEBUG:django.db.backends:(0.088) CREATE TABLE "django_content_type" (
"id" integer NOT NULL PRIMARY KEY,
"name" varchar(100) NOT NULL,
"app_label" varchar(100) NOT NULL,
"model" varchar(100) NOT NULL,
UNIQUE ("app_label", "model")
)
;; args=()
Creating table django_session
DEBUG:django.db.backends:(0.067) CREATE TABLE "django_session" (
"session_key" varchar(40) NOT NULL PRIMARY KEY,
"session_data" text NOT NULL,
"expire_date" datetime NOT NULL
)
;; args=()
Creating table mailer_message
DEBUG:django.db.backends:(0.048) CREATE TABLE "mailer_message" (
"id" integer NOT NULL PRIMARY KEY,
"message_data" text NOT NULL,
"when_added" datetime NOT NULL,
"priority" varchar(1) NOT NULL
Creating table mailer_dontsendentry
DEBUG:django.db.backends:(0.077) CREATE TABLE "mailer_dontsendentry" (
"id" integer NOT NULL PRIMARY KEY,
"to_address" varchar(75) NOT NULL,
"when_added" datetime NOT NULL
)
;; args=()
Creating table mailer_messagelog
DEBUG:django.db.backends:(0.047) CREATE TABLE "mailer_messagelog" (
"id" integer NOT NULL PRIMARY KEY,
"message_data" text NOT NULL,
"when_added" datetime NOT NULL,
"priority" varchar(1) NOT NULL,
"when_attempted" datetime NOT NULL,
"result" varchar(1) NOT NULL,
"log_message" text NOT NULL
)
;; args=()
DEBUG:django.db.backends:(0.000) SELECT "django_content_type"."id", "django_content_type"."name", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE "django_content_type"."app_label" = contenttypes ORDER BY "django_content_type"."name" ASC; args=('contenttypes',)
DEBUG:django.db.backends:(0.000) SELECT "django_content_type"."id", "django_content_type"."name", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."model" = contenttype AND "django_content_type"."app_label" = contenttypes ); args=('contenttype', 'contenttypes')
DEBUG:django.db.backends:(0.000) INSERT INTO "django_content_type" ("name", "app_label", "model") VALUES (content type, contenttypes, contenttype); args=(u'content type', 'contenttypes', 'contenttype')
DEBUG:django.db.backends:(0.000) SELECT "django_content_type"."id", "django_content_type"."name", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE "django_content_type"."app_label" = sessions ORDER BY "django_content_type"."name" ASC; args=('sessions',)
DEBUG:django.db.backends:(0.000) SELECT "django_content_type"."id", "django_content_type"."name", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."model" = session AND "django_content_type"."app_label" = sessions ); args=('session', 'sessions')
DEBUG:django.db.backends:(0.000) INSERT INTO "django_content_type" ("name", "app_label", "model") VALUES (session, sessions, session); args=(u'session', 'sessions', 'session')
DEBUG:django.db.backends:(0.000) SELECT "django_content_type"."id", "django_content_type"."name", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE "django_content_type"."app_label" = messages ORDER BY "django_content_type"."name" ASC; args=('messages',)
DEBUG:django.db.backends:(0.000) SELECT "django_content_type"."id", "django_content_type"."name", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE "django_content_type"."app_label" = staticfiles ORDER BY "django_content_type"."name" ASC; args=('staticfiles',)
DEBUG:django.db.backends:(0.000) SELECT "django_content_type"."id", "django_content_type"."name", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE "django_content_type"."app_label" = django_openstack ORDER BY "django_content_type"."name" ASC; args=('django_openstack',)
DEBUG:django.db.backends:(0.000) SELECT "django_content_type"."id", "django_content_type"."name", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE "django_content_type"."app_label" = mailer ORDER BY "django_content_type"."name" ASC; args=('mailer',)
DEBUG:django.db.backends:(0.000) SELECT "django_content_type"."id", "django_content_type"."name", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."model" = message AND "django_content_type"."app_label" = mailer ); args=('message', 'mailer')
DEBUG:django.db.backends:(0.000) INSERT INTO "django_content_type" ("name", "app_label", "model") VALUES (message, mailer, message); args=(u'message', 'mailer', 'message')
DEBUG:django.db.backends:(0.000) SELECT "django_content_type"."id", "django_content_type"."name", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."model" = dontsendentry AND "django_content_type"."app_label" = mailer ); args=('dontsendentry', 'mailer')
DEBUG:django.db.backends:(0.000) INSERT INTO "django_content_type" ("name", "app_label", "model") VALUES (don't send entry, mailer, dontsendentry); args=(u"don't send entry", 'mailer', 'dontsendentry')
DEBUG:django.db.backends:(0.000) SELECT "django_content_type"."id", "django_content_type"."name", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."model" = messagelog AND "django_content_type"."app_label" = mailer ); args=('messagelog', 'mailer')
DEBUG:django.db.backends:(0.000) INSERT INTO "django_content_type" ("name", "app_label", "model") VALUES (message log, mailer, messagelog); args=(u'message log', 'mailer', 'messagelog')
Installing custom SQL ...
Installing indexes ...
DEBUG:django.db.backends:(0.057) CREATE INDEX "django_session_c25c2c28" ON "django_session" ("expire_date");; args=()
No fixtures found.
* Reloading web server config apache2
apache2: Could not reliably determine the server's fully qualified domain name, using 172.16.123.6 for ServerName
...done.
Setting up libsqlite0 (2.8.17-6.1ubuntu1) ...
Setting up openstackx (0.2+20120117~1437-0mit1~25.gbp53fd61) ...
Setting up python-sqlite (1.0.1-8) ...
Processing triggers for libc-bin ...
ldconfig deferred processing now taking place
Processing triggers for python-support ...
接下來設定 mysql, 新增 database
wistor@wistor-dev-6:~$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 175
Server version: 5.1.58-1ubuntu1 (Ubuntu)
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CREATE DATABASE dash;
Query OK, 1 row affected (0.00 sec)
mysql> GRANT ALL ON dash.* TO 'dash'@'%' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.00 sec)
然後修改 /etc/openstack-dashboard/local_settings.py, 經過觀察,
發現修改過設定最後會同步到 /usr/share/openstack-dashboard/local/local_settings.py
root@wistor-dev-6:/# find . | grep local_settings
./etc/openstack-dashboard/local_settings.py
./usr/share/openstack-dashboard/local/local_settings.py
./usr/share/openstack-dashboard/local/local_settings.pyc
./usr/share/openstack-dashboard/local/local_settings.py.example
wistor@wistor-dev-6:~$ sudo less /etc/openstack-dashboard/local_settings.py | grep -A 10 DATABASE
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': '/var/lib/openstack-dashboard/dashboard_openstack.sqlite',
# },
# }
# 修改這個 database 設定, 變成 mysql
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'dash',
'USER': 'dash',
'PASSWORD': 'password',
'HOST': 'localhost',
'default-character-set': 'utf8'
},
}
wistor@wistor-dev-6:~$ sudo /etc/init.d/apache2 restart
wistor@wistor-dev-6:~$ sudo restart nova-api
接下來只要直接連到 http://172.16.123.6 就會看到畫面, 帳號密碼是之前在 keystone 設定的 adminUser/password 及 demoUser/password