~ubuntu-branches/ubuntu/vivid/ironic/vivid-updates

« back to all changes in this revision

Viewing changes to ironic/conductor/resource_manager.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2014-03-06 13:23:35 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20140306132335-5b49ji56jffxvtn4
Tags: 2014.1~b3-0ubuntu1
* New upstream release:
  - debian/patches/fix-requirements.patch: Dropped no longer needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
 
# coding=utf-8
3
 
 
4
 
# Copyright 2013 Hewlett-Packard Development Company, L.P.
5
 
# All Rights Reserved.
6
 
#
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
10
 
#
11
 
#         http://www.apache.org/licenses/LICENSE-2.0
12
 
#
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
17
 
#    under the License.
18
 
 
19
 
"""
20
 
Hold the data and drivers for a distinct node within a given context.
21
 
 
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.
26
 
 
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
29
 
for an example.
30
 
"""
31
 
 
32
 
from ironic.openstack.common import lockutils
33
 
from ironic.openstack.common import log
34
 
 
35
 
from ironic.common import driver_factory
36
 
from ironic.common import exception
37
 
from ironic.db import api as dbapi
38
 
 
39
 
LOG = log.getLogger(__name__)
40
 
 
41
 
RESOURCE_MANAGER_SEMAPHORE = "node_resource"
42
 
 
43
 
 
44
 
class NodeManager(object):
45
 
    """The data model, state, and drivers to manage a Node."""
46
 
 
47
 
    _nodes = {}
48
 
 
49
 
    def __init__(self, id, t, driver_name=None):
50
 
        self._driver_factory = driver_factory.DriverFactory()
51
 
        self.id = id
52
 
        self.task_refs = [t]
53
 
 
54
 
        db = dbapi.get_instance()
55
 
        self.node = db.get_node(id)
56
 
        self.ports = db.get_ports_by_node(id)
57
 
 
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)
61
 
 
62
 
    @classmethod
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)
67
 
        if n:
68
 
            n.task_refs.append(t)
69
 
        else:
70
 
            n = cls(id, t, new_driver)
71
 
            cls._nodes[id] = n
72
 
        return n
73
 
 
74
 
    @classmethod
75
 
    @lockutils.synchronized(RESOURCE_MANAGER_SEMAPHORE, 'ironic-')
76
 
    def release(cls, id, t):
77
 
        """Release a NodeManager previously acquired."""
78
 
 
79
 
        n = cls._nodes.get(id)
80
 
        if not n:
81
 
            raise exception.IronicException(_(
82
 
                "Release called on node %s for which no lock "
83
 
                "has been acquired.") % id)
84
 
 
85
 
        try:
86
 
            n.task_refs.remove(t)
87
 
        except ValueError:
88
 
            raise exception.IronicException(_(
89
 
                "Can not release node %s because it was not "
90
 
                "reserved by this tracker.") % id)
91
 
 
92
 
        # Delete the resource when no TaskManager references it.
93
 
        if len(n.task_refs) == 0:
94
 
            del(cls._nodes[id])
95
 
 
96
 
    def load_driver(self, driver_name):
97
 
        """Find a driver based on driver_name and return a driver object.
98
 
 
99
 
        :param driver_name: The name of the driver.
100
 
        :returns: A driver object.
101
 
        :raises: DriverNotFound if any driver is not found.
102
 
        """
103
 
        try:
104
 
            driver = self._driver_factory[driver_name]
105
 
        except KeyError:
106
 
            raise exception.DriverNotFound(driver_name=driver_name)
107
 
 
108
 
        return driver.obj