例如:nova-compute调用Instance.save() 方法更改数据库
nova-conductor调用Instance.save() 方法更改数据库
但是我们说过只有nova-conductor能访问数据库为什么呢?
nova/objects/instance.py 中的save方法定义如下。注意这里有个装饰器base.remotable
@base.remotable
def save(self, expected_vm_state=None,
expected_task_state=None, admin_state_reset=False):
"""Save updates to this instance
而nova-computer 不能访问数据库的原因就在这个装饰器中
nova/objects/base.py
def remotable(fn):
@functools.wraps(fn)
def wrapper(self, *args, **kwargs):
if NovaObject.indirection_api:
updates, result = NovaObject.indirection_api.object_action(
ctxt, self, fn.__name__, args, kwargs)
return result
else:
return fn(self, ctxt, *args, **kwargs)
原来能否直接访问数据库要看NovaObject.indirection_api 是否为true
而从nova-computer的入口函数可以看到nova/cmd/compute.py
def main():
config.parse_args(sys.argv)
logging.setup(CONF, 'nova')
priv_context.init(root_helper=shlex.split(utils.get_root_helper()))
utils.monkey_patch()
objects.register_all()
gmr.TextGuruMeditation.setup_autorun(version)
//如果没有定义CONF.conductor.use_local的话,则给objects_base.NovaObject.indirection_api 赋值
if not CONF.conductor.use_local:
cmd_common.block_db_access('nova-compute')
objects_base.NovaObject.indirection_api = \
conductor_rpcapi.ConductorAPI()
else:
LOG.warning(_LW('Conductor local mode is deprecated and will '
'be removed in a subsequent release'))
server = service.Service.create(binary='nova-compute',
topic=CONF.compute_topic,
db_allowed=CONF.conductor.use_local)
所以只有在nova-computer 给objects_base.NovaObject.indirection_api 赋值了。而nova-conductor 没有赋值,所以instance.save() 才可以访问数据库
同理可以知道,如果要让nova-computer 可以访问数据库,则需要CONF.conductor.use_local 为true