読者です 読者をやめる 読者になる 読者になる

grizzlyリリースのnovaが設定ファイル内のroot_helperをハンドリングしてくれないので修正してみた

OpenStack

ちょっと仕事で真面目に取り組むことになったのでgrizzlyをインストールしているんだけど、気になったところをメモしておく。

まぁ普通に使ってれば問題ないんだろうけど、、、それと、現在のmasterはroot_helperオプションをハンドリングしてくれるようなので不要だと思う。

■utils.pyがroot_helperのrootwrapコマンドパスを使ってくれない

novaがroot権限を必要とするコマンドを実行する際に使うラッパーコマンドnova-rootwrapnova.conf内root_helperパラメータで実行時のコマンドラインを指定することができる(今のmasterでは)。

複数バージョンのOpenStackを切り替えて使おうと思うと、root_helperでrootwrapのパスを指定できるのは結構便利なんだけどな。

rootwrapの働き

本家のwikiに詳しく説明されている。
Rootwrap - OpenStack
例えば、novaがiptables-save -cを実行する必要がある場合は、こんな感じで実行する。

nova-rootwrap /etc/nova/rootwrap.conf iptables-save -c
nova.conf内でのroot_helperパラメータ指定の記述は例えばこんな感じ
root_helper = sudo /home/saitou/grizzly/bin/nova-rootwrap /home/saitou/grizzly/nova/etc/nova/rootwrap.conf

これをsudo可能なように以下のように許可してやることにより、novaに対してroot権限を必要とするコマンドの実行権を与えている。

/etc/sudoers.d/nova-rootwrap
saitou ALL=(root) NOPASSWD: /home/saitou/grizzly/bin/nova-rootwrap /home/saitou/grizzly/nova/etc/nova/rootwrap.conf *

しかし、novaのutils.pyのexecute()では、これを取得する部分が以下のように決め打ちになっていて、何を書いても環境変数の$PATHで見つけたnova-rootwrapを使うように記述されています。これはよろしくない。

 200     if run_as_root and os.geteuid() != 0:
 201         cmd = ['sudo', 'nova-rootwrap', CONF.rootwrap_config] + list(cmd)
 202 
 203     cmd = map(str, cmd)

これだとnova-rootwrapは決め打ちでnova.conf内で指定しているrootwrap_configしか持っていってくれません。こまった。

■utils.py用パッチを書いてみた

そこで、こんな感じでnova.conf内で定義したroot_helperの値を参照するように修正してみた。

--- utils.py.org	2013-08-24 18:03:20.286286506 +0900
+++ utils.py	2013-08-24 18:21:43.726288190 +0900
@@ -29,6 +29,7 @@
 import pyclbr
 import random
 import re
+import shlex
 import shutil
 import signal
 import socket
@@ -83,6 +84,9 @@
     cfg.StrOpt('tempdir',
                default=None,
                help='Explicitly specify the temporary working directory'),
+    cfg.StrOpt('root_helper',
+               default='',
+               help='Root helper application.'),
 ]
 CONF = cfg.CONF
 CONF.register_opts(monkey_patch_opts)
@@ -198,7 +202,7 @@
                                         'to utils.execute: %r') % kwargs)
 
     if run_as_root and os.geteuid() != 0:
-        cmd = ['sudo', 'nova-rootwrap', CONF.rootwrap_config] + list(cmd)
+        cmd = shlex.split(CONF.root_helper) + list(cmd)
 
     cmd = map(str, cmd)

とりあえず動いている。
まだnova-apiしか起動させてないんだけどな。先は長いぜ。やれやれだ:)