OpenStack Advent Calendar 2013 JP 8日目

碧川涼

さて、今日も名前に緑色のつく人を見つけられませんでした。が、よくよく考えたら「碧」っていう字も、青だったり緑だったりするじゃないですか、ってことで、今日はゲーム『NOëL 〜La neige〜』に登場するキャラクターの「碧川涼」さんの誕生日だそうです。お誕生日おめでとうございます。えーと、恋愛シミュレーションゲームだそうです。すみません、残念ながらやったことないので、存じあげておりませんでした。

それと、この碧川涼というキャラクターの声を演じているのは根谷美智子さんなんですが、根谷さんの親友の菅原祥子さんは12月12日が誕生日だそうです。おめでとうございます。

Glance のかわりに Walrus を使ってみる

まず最初に、我らが愛する石川 さんがこんなことをツブやいてまして

これは、やばい、このままだと enforcing されちゃう…(((( ;゚Д゚)))…ってことで、今日は OpenStack Advent Calendar 2013 JP の 8 日目です。

ところで、去年の OpenStack Advent Calendar 2012 JP の僕のエントリーは惨々な結果でした…。今年は反省しちゃんとやりきりたいと思いますが、どうやら僕は OpenStack 界隈では「負け犬」「噛ませ犬」のポジションらしく「今年も惨々な内容でひとつよろしく頼むよキミぃ」とか言われてます…(。´Д⊂)

OpenStack 環境の設定

えー、僕は OpenStack 初心者1なので、いま流行りの RDO? Packstack? を使って構築しました。まぁ、Packstack を用いた構築方法についてはきっと誰かが今回の Advent Calendar で書いてくれるでしょうから、ここでは割愛します。

ちなみに、ここで使う Walrus は先日の Eucalyptus Advent Calendar 2013 のエントリ「Walrus をだけを使ってみる」で作った環境を使います。

まず、glance のサービスを止めます。だって使わないんだもんだもん。止めちゃいますよー。

[root@rdo ~(keystone_admin)]# /etc/init.d/openstack-glance-api stop
Stopping openstack-glance-api:                             [  OK  ]
[root@rdo ~(keystone_admin)]# /etc/init.d/openstack-glance-registry stop
Stopping openstack-glance-registry:                        [  OK  ]
[root@rdo ~(keystone_admin)]# /etc/init.d/openstack-glance-scrubber stop

で、nova が glance じゃなくて Walrus を使うように設定します。

[root@rdo ~(keystone_admin)]# diff -u /etc/nova/nova.conf.glance /etc/nova/nova.conf
--- /etc/nova/nova.conf.glance  2013-12-03 14:46:31.314000061 +0900
+++ /etc/nova/nova.conf 2013-12-03 17:29:31.213000032 +0900
@@ -939,7 +939,7 @@
 # with https:// for ssl-based glance api servers.
 # ([hostname|ip]:port) (list value)
 #glance_api_servers=$glance_host:$glance_port
-glance_api_servers=192.168.32.74:9292
+#glance_api_servers=192.168.32.74:9292

 # Allow to perform insecure SSL (https) requests to glance
 # (boolean value)
@@ -965,16 +965,16 @@

 # hostname or ip for OpenStack to use when accessing the s3
 # api (string value)
-#s3_host=$my_ip
+s3_host=192.168.32.73

 # port used when accessing the s3 api (integer value)
-#s3_port=3333
+s3_port=8773

 # access key to use for s3 server for images (string value)
-#s3_access_key=notchecked
+s3_access_key=AKIAMNYEAUG5ZJBN9KPH

 # secret key to use for s3 server for images (string value)
-#s3_secret_key=notchecked
+s3_secret_key=WlsMz8d6LdZKOmSQo07LmtujRqN6OVKw4NoKe02V

 # whether to use ssl when talking to s3 (boolean value)
 #s3_use_ssl=false
@@ -2595,7 +2595,7 @@
 qpid_reconnect=True
 sql_connection=mysql://nova:db56f39a7e064ccc@192.168.32.74/nova
 qpid_reconnect_timeout=0
-image_service=nova.image.glance.GlanceImageService
+image_service=nova.image.s3.S3ImageService
 logdir=/var/log/nova
 qpid_reconnect_interval_max=0
 qpid_reconnect_limit=0

えーと、ここまで設定して、ふと気付いたんですよ。Walrus のエンドポイントって http://ホスト:8773/services/Walrus っていう形式なんすよねー。えぇ、その値を設定するパラメータって s3_host と s3_port じゃ書ききれないよねぇ…。

で、nova/image/s3.py を書き換えようと思ったんですが、@ishikawa84g さんと @shida1234 さんが「それ、keystone に登録しちゃえばいいんじゃない?」と助け船を出してくれまして、以下のように登録してみました。あ、もちろん keystone service-delete で glance のサービスとエンドポイント情報を削除してから実施してます。

[root@rdo ~(keystone_admin)]# keystone service-create --name walrus --type image --description "Eucalyptus Image Service"
+-------------+----------------------------------+
|   Property  |              Value               |
+-------------+----------------------------------+
| description |     Eucalyptus Image Service     |
|      id     | af7ba823c7ab4f58917af6a0fad81006 |
|     name    |              walrus              |
|     type    |              image               |
+-------------+----------------------------------+

[root@rdo ~(keystone_admin)]# keystone endpoint-create --service af7ba823c7ab4f58917af6a0fad81006 --publicurl http://192.168.32.73:8773/services/Walrus --adminurl http://192.168.32.73:8773/services/Walrus --internalurl http://192.168.32.73:8773/services/Walrus
+-------------+-------------------------------------------+
|   Property  |                   Value                   |
+-------------+-------------------------------------------+
|   adminurl  | http://192.168.32.73:8773/services/Walrus |
|      id     |      fa3de0db20ae4903a429c35beabeed37     |
| internalurl | http://192.168.32.73:8773/services/Walrus |
|  publicurl  | http://192.168.32.73:8773/services/Walrus |
|    region   |                 regionOne                 |
|  service_id |      af7ba823c7ab4f58917af6a0fad81006     |
+-------------+-------------------------------------------+

あ、一応 glance っていうか、Image Store とおしゃべりするであろう nova-api と nova-compute は再起動させます。

[root@rdo ~(keystone_admin)]# /etc/init.d/openstack-nova-api restart
Stopping openstack-nova-api:                               [  OK  ]
Starting openstack-nova-api:                               [  OK  ]
[root@rdo ~(keystone_admin)]# /etc/init.d/openstack-nova-compute restart
Stopping openstack-nova-compute:                           [  OK  ]
Starting openstack-nova-compute:                           [  OK  ]

で、ちゃんと接続できるかなーっと nova image-list (カチャカチャカチャ…ッターン!)

[root@rdo ~(keystone_admin)]# nova image-list
ERROR: The server has either erred or is incapable of performing the requested operation. (HTTP 500) (Request-ID: req-ca8b1ed6-7ff0-4863-a05e-f88598a31469)

あ、あれー?何だろう?と思って nova-api のログを見ると…

2013-12-03 18:30:05.838 25016 TRACE nova.api.openstack   File "/usr/lib/python2.6/site-packages/nova/api/openstack/compute/images.py", line 203, in detail
2013-12-03 18:30:05.838 25016 TRACE nova.api.openstack     **page_params)
2013-12-03 18:30:05.838 25016 TRACE nova.api.openstack   File "/usr/lib/python2.6/site-packages/nova/image/glance.py", line 264, in detail
2013-12-03 18:30:05.838 25016 TRACE nova.api.openstack     for image in images:
2013-12-03 18:30:05.838 25016 TRACE nova.api.openstack   File "/usr/lib/python2.6/site-packages/glanceclient/v1/images.py", line 174, in paginate
2013-12-03 18:30:05.838 25016 TRACE nova.api.openstack     images = self._list(url, "images")
2013-12-03 18:30:05.838 25016 TRACE nova.api.openstack   File "/usr/lib/python2.6/site-packages/glanceclient/common/base.py", line 53, in _list
2013-12-03 18:30:05.838 25016 TRACE nova.api.openstack     resp, body = self.api.json_request('GET', url)
2013-12-03 18:30:05.838 25016 TRACE nova.api.openstack   File "/usr/lib/python2.6/site-packages/glanceclient/common/http.py", line 266, in json_request
2013-12-03 18:30:05.838 25016 TRACE nova.api.openstack     resp, body_iter = self._http_request(url, method, **kwargs)
2013-12-03 18:30:05.838 25016 TRACE nova.api.openstack   File "/usr/lib/python2.6/site-packages/glanceclient/common/http.py", line 235, in _http_request
2013-12-03 18:30:05.838 25016 TRACE nova.api.openstack     raise exc.CommunicationError(message=message)
2013-12-03 18:30:05.838 25016 TRACE nova.api.openstack CommunicationError: Error communicating with http://192.168.32.74:9292 [Errno 111] ECONNREFUSED

あらやだ、この子、Glance 見に行ってんじゃないの…。っていうか、何で nova/image/glance.py が呼ばれてるのさ…。ということでコード nova/api/openstack/compute/images.py を確認すると…

import nova.image.glance
from nova.openstack.common.gettextutils import _
import nova.utils

あぁ…、思いっきり import nova.image.glance してるじゃん…、じゃぁ誰が「image_service=nova.image.s3.S3ImageService」の設定を見てくれるの?

[root@rdo ~(keystone_admin)]# grep -i CONF.image_service -r /usr/lib/python2.6/site-packages/nova/
[root@rdo ~(keystone_admin)]# grep "'image_service'" -r /usr/lib/python2.6/site-packages/nova/
[root@rdo ~(keystone_admin)]#

ちょっと待て、本来なら今頃、OpenStack から Walrus を使ってインスタンスを起動して感無量~人´ω`*)とかやってるはずなのに、何?あれ?誰も nova.conf の image_service を見てないんじゃないの?ちょっと!どーゆーこと?何この無力感…(:.;´;Д;゚;.:)

Advent Calendar のエントリに「Glance のかわりに Walrus を使う(キリッ」とか書いたのに、このままではまた去年と同様に「m9(^Д^)プギャー」ですよ。もうね、どんだけ僕は成功しちゃいけない星のもとに生まれたんすか?

ってことで、足掻いてみます。そりゃーもう必死に足掻いてみます。アラフォー男児が本気で足掻いたら、きっと nova だって「おっぉ、わかったぉ、Glance やめて S3 喋ってみるよ」って折れてくれるはず、nova 懐深い子、きっと僕も包んでくれるはず。

まず、手始めに nova/image/glance.py を呼び出している nova/api/openstack/compute/images.py を見てみます。

class Controller(wsgi.Controller):
    """Base controller for retrieving/displaying images."""

    _view_builder_class = views_images.ViewBuilder

    def __init__(self, image_service=None, **kwargs):
        """Initialize new `ImageController`.

        :param image_service: `nova.image.glance:GlanceImageService`

        """
        super(Controller, self).__init__(**kwargs)
        self._image_service = (image_service or
                               nova.image.glance.get_default_image_service())

うん、あら?、ほう、image_service image_service が None じゃなければ glance.get_default_image_service は呼ばれないのか。そうかそうか、んじゃー、glance.py に get_default_image_service があるってことは、s3.py にもあるのかな?

[root@rdo ~]# grep "def get_default_image_service" -r /usr/lib/python2.6/site-packages/nova/image/s3.py | wc -l
0

うん、無いね、全く無いね、容赦なく無いね。

よし、おいちゃん覚悟した、Pythonian じゃないうえに Python 書けないけど、頑張る。nova/api/openstack/compute/images.py を書き換えるよ。

--- /usr/lib/python2.6/site-packages/nova/api/openstack/compute/images.py.orig  2013-12-07 05:19:23.774000083 +0900
+++ /usr/lib/python2.6/site-packages/nova/api/openstack/compute/images.py       2013-12-07 05:14:58.438000084 +0900
@@ -21,6 +21,7 @@
 from nova.api.openstack import xmlutil
 from nova import exception
 import nova.image.glance
+import nova.image.s3
 from nova.openstack.common.gettextutils import _
 import nova.utils

@@ -96,6 +97,7 @@

         """
         super(Controller, self).__init__(**kwargs)
+        image_service = nova.image.s3.S3ImageService()
         self._image_service = (image_service or
                                nova.image.glance.get_default_image_service())

で、nova-api を再起動して、nova image-list (カチャカチャカチャ…ッターン!)

2013-12-07 05:15:24.699 10379 TRACE nova.api.openstack   File "/usr/lib/python2.6/site-packages/nova/api/openstack/compute/images.py", line 205, in detail
2013-12-07 05:15:24.699 10379 TRACE nova.api.openstack     **page_params)
2013-12-07 05:15:24.699 10379 TRACE nova.api.openstack   File "/usr/lib/python2.6/site-packages/nova/image/s3.py", line 168, in detail
2013-12-07 05:15:24.699 10379 TRACE nova.api.openstack     images = self.service.detail(context, **kwargs)
2013-12-07 05:15:24.699 10379 TRACE nova.api.openstack   File "/usr/lib/python2.6/site-packages/nova/image/glance.py", line 264, in detail
2013-12-07 05:15:24.699 10379 TRACE nova.api.openstack     for image in images:
(中略)
2013-12-07 05:15:24.699 10379 TRACE nova.api.openstack   File "/usr/lib/python2.6/site-packages/glanceclient/common/http.py", line 235, in _http_request
2013-12-07 05:15:24.699 10379 TRACE nova.api.openstack     raise exc.CommunicationError(message=message)
2013-12-07 05:15:24.699 10379 TRACE nova.api.openstack CommunicationError: Error communicating with http://192.168.32.74:9292 [Errno 111] ECONNREFUSED

ば、馬鹿な…。glance を叩きに行ってるだと?

詳しく追うの面倒なので、ざっと確認すると、S3ImageService.detail -> self.service.detail で、んじゃー self.service は何かしら?って言うと、S3ImageService の __init__ で以下の定義がありまして

    def __init__(self, service=None, *args, **kwargs):
        self.cert_rpcapi = nova.cert.rpcapi.CertAPI()
        self.service = service or glance.get_default_image_service()
        self.service.__init__(*args, **kwargs)

service が None のときは glance.get_default_image_service() を呼ぶから、結果 self.service には GlanceImageService が入るというわけでして、











(#゚Д゚)









いやもう駄目じゃん、これ、何があっても glance 呼ばれるじゃん。だって service = S3ImageService やっても循環するだけでしょ?いやいやいや、やってみたよ、無駄だとわかってもやってみたよ、修造よろしくリスペクトな気持ちでやってみたよ、そしたらね、

2013-12-06 16:39:41.592 12145 DEBUG nova.wsgi [-] Loading app ec2 from /etc/nova/api-paste.ini load_app /usr/lib/python2.6/site-packages/nova/wsgi.py:
484
2013-12-06 16:39:41.680 12145 DEBUG nova.image.s3 [-] s3.py serivce is None __init__ /usr/lib/python2.6/site-packages/nova/image/s3.py:91
2013-12-06 16:39:41.681 12145 DEBUG nova.image.s3 [-] s3.py serivce is None __init__ /usr/lib/python2.6/site-packages/nova/image/s3.py:91
(中略)
2013-12-06 16:39:41.728 12145 DEBUG nova.image.s3 [-] s3.py serivce is None __init__ /usr/lib/python2.6/site-packages/nova/image/s3.py:91
2013-12-06 16:39:41.728 12145 DEBUG nova.image.s3 [-] s3.py serivce is None __init__ /usr/lib/python2.6/site-packages/nova/image/s3.py:91
2013-12-06 16:39:41.729 12145 CRITICAL nova [-] 'module' object has no attribute 'tracebacklimit'
2013-12-06 16:39:41.729 12145 TRACE nova Traceback (most recent call last):
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/bin/nova-api", line 10, in <module>
2013-12-06 16:39:41.729 12145 TRACE nova     sys.exit(main())
(中略)
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/lib/python2.6/site-packages/nova/api/ec2/cloud.py", line 226, in __init__
2013-12-06 16:39:41.729 12145 TRACE nova     self.image_service = s3.S3ImageService()
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/lib/python2.6/site-packages/nova/image/s3.py", line 93, in __init__
2013-12-06 16:39:41.729 12145 TRACE nova     self.service = S3ImageService()
(中略)
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/lib/python2.6/site-packages/nova/image/s3.py", line 91, in __init__
2013-12-06 16:39:41.729 12145 TRACE nova     LOG.debug("s3.py serivce is %s", service)
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/lib64/python2.6/logging/__init__.py", line 1305, in debug
2013-12-06 16:39:41.729 12145 TRACE nova     self.logger.debug(msg, *args, **kwargs)
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/lib64/python2.6/logging/__init__.py", line 1044, in debug
2013-12-06 16:39:41.729 12145 TRACE nova     self._log(DEBUG, msg, args, **kwargs)
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/lib64/python2.6/logging/__init__.py", line 1173, in _log
2013-12-06 16:39:41.729 12145 TRACE nova     self.handle(record)
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/lib64/python2.6/logging/__init__.py", line 1183, in handle
2013-12-06 16:39:41.729 12145 TRACE nova     self.callHandlers(record)
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/lib64/python2.6/logging/__init__.py", line 1220, in callHandlers
2013-12-06 16:39:41.729 12145 TRACE nova     hdlr.handle(record)
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/lib64/python2.6/logging/__init__.py", line 679, in handle
2013-12-06 16:39:41.729 12145 TRACE nova     self.emit(record)
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/lib64/python2.6/logging/handlers.py", line 405, in emit
2013-12-06 16:39:41.729 12145 TRACE nova     logging.FileHandler.emit(self, record)
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/lib64/python2.6/logging/__init__.py", line 860, in emit
2013-12-06 16:39:41.729 12145 TRACE nova     StreamHandler.emit(self, record)
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/lib64/python2.6/logging/__init__.py", line 804, in emit
2013-12-06 16:39:41.729 12145 TRACE nova     self.handleError(record)
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/lib64/python2.6/logging/__init__.py", line 733, in handleError
2013-12-06 16:39:41.729 12145 TRACE nova     traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/lib64/python2.6/traceback.py", line 125, in print_exception
2013-12-06 16:39:41.729 12145 TRACE nova     print_tb(tb, limit, file)
2013-12-06 16:39:41.729 12145 TRACE nova   File "/usr/lib64/python2.6/traceback.py", line 57, in print_tb
2013-12-06 16:39:41.729 12145 TRACE nova     if hasattr(sys, 'tracebacklimit'):
2013-12-06 16:39:41.729 12145 TRACE nova AttributeError: 'module' object has no attribute 'tracebacklimit'
2013-12-06 16:39:41.729 12145 TRACE nova

tracebacklimit …そりゃそうだ、だってループしてんだもん、そりゃそうだ。

あーあ、終りましたよ、また今年も失敗で終りですよ。何だよ、タイトルを「Glance のかわりに Walrus を使ってみる」じゃなくて「Glance のバックエンドに Walrus を使ってみる」って書いてたら今頃きっと成功ですよ。もうね、世の OpenStacker が「ぐぐー、やっぱ Glance より Walrus かー、ちきしょー」っていう姿を夢見て走ってみたのに、気付いたら明後日の方向にスロットル全開ですよ。

ちっきしょー、s3.py なんて名前でファイルを置いとくから淡い期待を抱いちゃうじゃん、もうね、s3.py じゃなくて ese3.py とかで置いておいてくれたらいいのに。



クリスマスまであと17日です✌(́◓q◔`)✌


  1. ツールに頼らないと環境を作れないぐらいに初心者です [return]