1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
4
# Copyright 2013 Hewlett-Packard Development Company, L.P.
7
# Licensed under the Apache License, Version 2.0 (the "License"); you may
8
# not use this file except in compliance with the License. You may obtain
9
# a copy of the License at
11
# http://www.apache.org/licenses/LICENSE-2.0
13
# Unless required by applicable law or agreed to in writing, software
14
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16
# License for the specific language governing permissions and limitations
20
Hold the data and drivers for a distinct node within a given context.
22
Each :py:class:`ironic.conductor.resource_manager.NodeManager` instance is a
23
semi-singleton, keyed by the node id. It contains references to all
24
:py:class:`ironic.conductor.task_manager.TaskManager` which called it. When no
25
more TaskManagers reference a given NodeManager, it is automatically destroyed.
27
Do not request a NodeManager directly; instead, you should use a TaskManager to
28
manage the resource in a given context. See the documentation on TaskManager
32
from ironic.openstack.common import lockutils
33
from ironic.openstack.common import log
35
from ironic.common import driver_factory
36
from ironic.common import exception
37
from ironic.db import api as dbapi
39
LOG = log.getLogger(__name__)
41
RESOURCE_MANAGER_SEMAPHORE = "node_resource"
44
class NodeManager(object):
45
"""The data model, state, and drivers to manage a Node."""
49
def __init__(self, id, t, driver_name=None):
50
self._driver_factory = driver_factory.DriverFactory()
54
db = dbapi.get_instance()
55
self.node = db.get_node(id)
56
self.ports = db.get_ports_by_node(id)
58
# Select new driver's name if defined or select already defined in db.
59
driver_name = driver_name or self.node.get('driver')
60
self.driver = self.load_driver(driver_name)
63
@lockutils.synchronized(RESOURCE_MANAGER_SEMAPHORE, 'ironic-')
64
def acquire(cls, id, t, new_driver=None):
65
"""Acquire a NodeManager and associate to a TaskManager."""
66
n = cls._nodes.get(id)
70
n = cls(id, t, new_driver)
75
@lockutils.synchronized(RESOURCE_MANAGER_SEMAPHORE, 'ironic-')
76
def release(cls, id, t):
77
"""Release a NodeManager previously acquired."""
79
n = cls._nodes.get(id)
81
raise exception.IronicException(_(
82
"Release called on node %s for which no lock "
83
"has been acquired.") % id)
88
raise exception.IronicException(_(
89
"Can not release node %s because it was not "
90
"reserved by this tracker.") % id)
92
# Delete the resource when no TaskManager references it.
93
if len(n.task_refs) == 0:
96
def load_driver(self, driver_name):
97
"""Find a driver based on driver_name and return a driver object.
99
:param driver_name: The name of the driver.
100
:returns: A driver object.
101
:raises: DriverNotFound if any driver is not found.
104
driver = self._driver_factory[driver_name]
106
raise exception.DriverNotFound(driver_name=driver_name)