Rename "manager" to "conductor"

This rename to "conductor" more clearly communicates that this service
has a many-to-many relationship. One or more service instances
coordinate between each other to conduct actions on a set of nodes,
using guarded locks to prevent conflicting simultaneous actions on any
given node. The old name "manager" suggested a more one-to-many relationship,
which is not the design pattern which we use here.

Rename ironic/manager to ironic/conductor
Rename ironic.manager.manager.ManagerService
    to ironic.conductor.manager.ConductorManager
Rename ironic-manager to ironic-conductor
Update docs too

Change-Id: I3191be72a44bdaf14c763ce7519a7ae9066b2bc5
This commit is contained in:
Devananda van der Veen 2013-06-22 12:10:21 -07:00
parent 216fac0b2f
commit 8eb63c2078
23 changed files with 76 additions and 75 deletions

View File

@ -11,12 +11,12 @@ An Ironic deployment will be composed of the following components:
- A RESTful `API service`_, by which operators and other services may interact - A RESTful `API service`_, by which operators and other services may interact
with the managed bare metal servers. with the managed bare metal servers.
- A `Manager service`_, which does the bulk of the work. Functionality is - A `Conductor service`_, which does the bulk of the work. Functionality is
exposed via the `API service`_. The Manager and API services communicate via exposed via the `API service`_. The Conductor and API services communicate via
RPC. RPC.
- A Database and `DB API`_ for storing the state of the Manager and Drivers. - A Database and `DB API`_ for storing the state of the Conductor and Drivers.
- One or more Deployment Agents, which provide local control over the - One or more Deployment Agents, which provide local control over the
hardware which is not available remotely to the Manager. A ramdisk should be hardware which is not available remotely to the Conductor. A ramdisk should be
built which contains one of these agents, eg. with `diskimage-builder`_. built which contains one of these agents, eg. with `diskimage-builder`_.
This ramdisk can be booted on-demand. This ramdisk can be booted on-demand.
@ -26,18 +26,18 @@ Drivers
======= =======
The internal driver API provides a consistent interface between the The internal driver API provides a consistent interface between the
Manager service and the driver implementations. There are two types of drivers: Conductor service and the driver implementations. There are two types of drivers:
- `ControlDrivers`_ manage the hardware, performing functions such as power - `ControlDrivers`_ manage the hardware, performing functions such as power
on/off, toggle boot device, etc. on/off, toggle boot device, etc.
- `DeployDrivers`_ handle the task of booting a temporary ramdisk, formatting - `DeployDrivers`_ handle the task of booting a temporary ramdisk, formatting
drives, and putting a persistent image onto the hardware. drives, and putting a persistent image onto the hardware.
- Driver implementations are loaded and instantiated via entrypoints when the - Driver implementations are loaded and instantiated via entrypoints when the
`Manager service`_ starts. Each Node record stored in the database indicates `Conductor service`_ starts. Each Node record stored in the database indicates
which drivers should manage it. When a task is started on that node, which drivers should manage it. When a task is started on that node,
information about the node and task is passed to the corresponding driver. information about the node and task is passed to the corresponding driver.
In this way, heterogeneous hardware deployments can be managed by a single In this way, heterogeneous hardware deployments can be managed by a single
Manager service. Conductor service.
In addition to the two types of drivers, there are three categories of driver In addition to the two types of drivers, there are three categories of driver
functionality: core, standardized, and vendor: functionality: core, standardized, and vendor:
@ -76,7 +76,7 @@ deployment using virtual machines), an `SSHPowerDriver`_ is also supplied.
.. _API service: /api/ironic.api.controllers.v1.html .. _API service: /api/ironic.api.controllers.v1.html
.. _Manager service: /api/ironic.manager.manager.html .. _Conductor service: /api/ironic.conductor.manager.html
.. _DB API: /api/ironic.db.api.html .. _DB API: /api/ironic.db.api.html
.. _ControlDrivers: /api/ironic.drivers.base.html#ironic.drivers.base.ControlDriver .. _ControlDrivers: /api/ironic.drivers.base.html#ironic.drivers.base.ControlDriver
.. _DeployDrivers: /api/ironic.drivers.base.html#ironic.drivers.base.DeployDriver .. _DeployDrivers: /api/ironic.drivers.base.html#ironic.drivers.base.DeployDriver

View File

@ -7,4 +7,4 @@ List of Installed Commands
.. toctree:: .. toctree::
../api/ironic.cmd.api ../api/ironic.cmd.api
../api/ironic.cmd.dbsync ../api/ironic.cmd.dbsync
../api/ironic.cmd.manager ../api/ironic.cmd.conductor

View File

@ -0,0 +1,10 @@
.. _conductor:
==========================
Ironic's Conductor Service
==========================
.. toctree::
../api/ironic.conductor.manager
../api/ironic.conductor.resource_manager
../api/ironic.conductor.task_manager

View File

@ -1,10 +0,0 @@
.. _manager:
==========================
Ironic's Management Server
==========================
.. toctree::
../api/ironic.manager.manager
../api/ironic.manager.resource_manager
../api/ironic.manager.task_manager

View File

@ -30,9 +30,10 @@ today, that is where you want to look.
.. TODO .. TODO
.. - installation .. - installation
.. - configuration .. - configuration
.. - DB and AMQP
.. - API and Conductor services
.. - integration with other OS services .. - integration with other OS services
.. - single or multiple managers .. - any driver-specific configuration
.. - different drivers
.. - hardware enrollment .. - hardware enrollment
.. - manual vs automatic .. - manual vs automatic
.. - hw plugins .. - hw plugins
@ -70,7 +71,7 @@ Python API Quick Reference
dev/common dev/common
dev/db dev/db
dev/drivers dev/drivers
dev/manager dev/conductor
Indices and tables Indices and tables
================== ==================

View File

@ -19,8 +19,8 @@
from oslo.config import cfg from oslo.config import cfg
from pecan import hooks from pecan import hooks
from ironic.conductor import rpcapi
from ironic.db import api as dbapi from ironic.db import api as dbapi
from ironic.manager import rpcapi
from ironic.openstack.common import context from ironic.openstack.common import context
@ -50,4 +50,4 @@ class ContextHook(hooks.PecanHook):
class RPCHook(hooks.PecanHook): class RPCHook(hooks.PecanHook):
def before(self, state): def before(self, state):
state.request.rpcapi = rpcapi.ManagerAPI() state.request.rpcapi = rpcapi.ConductorAPI()

View File

@ -29,7 +29,7 @@ from oslo.config import cfg
from ironic.openstack.common import service from ironic.openstack.common import service
from ironic.common import service as ironic_service from ironic.common import service as ironic_service
from ironic.manager import manager from ironic.conductor import manager
CONF = cfg.CONF CONF = cfg.CONF
@ -38,6 +38,6 @@ def main():
# Pase config file and command line options, then start logging # Pase config file and command line options, then start logging
ironic_service.prepare_service(sys.argv) ironic_service.prepare_service(sys.argv)
mgr = manager.ManagerService(CONF.host, manager.MANAGER_TOPIC) mgr = manager.ConductorManager(CONF.host, manager.MANAGER_TOPIC)
launcher = service.launch(mgr) launcher = service.launch(mgr)
launcher.wait() launcher.wait()

View File

@ -15,47 +15,47 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
"""Handles all activity related to bare-metal deployments. """Conduct all activity related to bare-metal deployments.
A single instance of :py:class:`ironic.manager.manager.ManagerService` is A single instance of :py:class:`ironic.conductor.manager.ConductorManager` is
created within the *ironic-manager* process, and is responsible for performing created within the *ironic-conductor* process, and is responsible for
all actions on bare metal resources (Chassis, Nodes, and Ports). Commands are performing all actions on bare metal resources (Chassis, Nodes, and Ports).
received via RPC calls. The manager service also performs periodic tasks, eg. Commands are received via RPC calls. The conductor service also performs
to monitor the status of active deployments. periodic tasks, eg. to monitor the status of active deployments.
Drivers are loaded via entrypoints, by the Drivers are loaded via entrypoints, by the
:py:class:`ironic.manager.resource_manager.NodeManager` class. Each driver is :py:class:`ironic.conductor.resource_manager.NodeManager` class. Each driver is
instantiated once and a ref to that singleton is included in each resource instantiated once and a ref to that singleton is included in each resource
manager, depending on the node's configuration. In this way, a single manager, depending on the node's configuration. In this way, a single
ManagerService may use multiple drivers, and manage heterogeneous hardware. ConductorManager may use multiple drivers, and manage heterogeneous hardware.
When multiple :py:class:`ManagerService` are run on different hosts, they are When multiple :py:class:`ConductorManager` are run on different hosts, they are
all active and cooperatively manage all nodes in the deplyment. Nodes are all active and cooperatively manage all nodes in the deplyment. Nodes are
locked by each manager when performing actions which change the state of that locked by each conductor when performing actions which change the state of that
node; these locks are represented by the node; these locks are represented by the
:py:class:`ironic.manager.task_manager.TaskManager` class. :py:class:`ironic.conductor.task_manager.TaskManager` class.
""" """
from ironic.common import service from ironic.common import service
from ironic.conductor import task_manager
from ironic.db import api as dbapi from ironic.db import api as dbapi
from ironic.manager import task_manager
from ironic.openstack.common import log from ironic.openstack.common import log
MANAGER_TOPIC = 'ironic.manager' MANAGER_TOPIC = 'ironic.conductor_manager'
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
class ManagerService(service.PeriodicService): class ConductorManager(service.PeriodicService):
"""Ironic Manager service main class.""" """Ironic Conductor service main class."""
RPC_API_VERSION = '1.0' RPC_API_VERSION = '1.0'
def __init__(self, host, topic): def __init__(self, host, topic):
super(ManagerService, self).__init__(host, topic) super(ConductorManager, self).__init__(host, topic)
def start(self): def start(self):
super(ManagerService, self).start() super(ConductorManager, self).start()
self.dbapi = dbapi.get_instance() self.dbapi = dbapi.get_instance()
def initialize_service_hook(self, service): def initialize_service_hook(self, service):

View File

@ -19,9 +19,9 @@
""" """
Hold the data and drivers for a distinct node within a given context. Hold the data and drivers for a distinct node within a given context.
Each :py:class:`ironic.manager.resource_manager.NodeManager` instance is a Each :py:class:`ironic.conductor.resource_manager.NodeManager` instance is a
semi-singleton, keyed by the node id. It contains references to all semi-singleton, keyed by the node id. It contains references to all
:py:class:`ironic.manager.task_manager.TaskManager` which called it. When no :py:class:`ironic.conductor.task_manager.TaskManager` which called it. When no
more TaskManagers reference a given NodeManager, it is automatically destroyed. more TaskManagers reference a given NodeManager, it is automatically destroyed.
Do not request a NodeManager directly; instead, you should use a TaskManager to Do not request a NodeManager directly; instead, you should use a TaskManager to

View File

@ -16,16 +16,16 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
""" """
Client side of the manager RPC API. Client side of the conductor RPC API.
""" """
import ironic.openstack.common.rpc.proxy import ironic.openstack.common.rpc.proxy
MANAGER_TOPIC = 'ironic.manager' MANAGER_TOPIC = 'ironic.conductor_manager'
class ManagerAPI(ironic.openstack.common.rpc.proxy.RpcProxy): class ConductorAPI(ironic.openstack.common.rpc.proxy.RpcProxy):
"""Client side of the manager RPC API. """Client side of the conductor RPC API.
API version history: API version history:
@ -38,7 +38,7 @@ class ManagerAPI(ironic.openstack.common.rpc.proxy.RpcProxy):
if topic is None: if topic is None:
topic = MANAGER_TOPIC topic = MANAGER_TOPIC
super(ManagerAPI, self).__init__( super(ConductorAPI, self).__init__(
topic=topic, topic=topic,
default_version=self.RPC_API_VERSION) default_version=self.RPC_API_VERSION)

View File

@ -21,7 +21,7 @@ A context manager to peform a series of tasks on a set of resources.
:class:`TaskManager` is a context manager, created on-demand to synchronize :class:`TaskManager` is a context manager, created on-demand to synchronize
locking and simplify operations across a set of locking and simplify operations across a set of
:class:`ironic.manager.resource_manager.NodeManager` instances. Each :class:`ironic.conductor.resource_manager.NodeManager` instances. Each
NodeManager holds the data model for a node, as well as references to the NodeManager holds the data model for a node, as well as references to the
driver singleton appropriate for that node. driver singleton appropriate for that node.
@ -30,13 +30,13 @@ indicated. Multiple shared locks for the same resource may coexist with an
exclusive lock, but only one exclusive lock will be granted across a exclusive lock, but only one exclusive lock will be granted across a
deployment; attempting to allocate another will raise an exception. An deployment; attempting to allocate another will raise an exception. An
exclusive lock is represented in the database to coordinate between exclusive lock is represented in the database to coordinate between
:class:`ironic.manager.manager` instances, even when deployed on :class:`ironic.conductor.manager` instances, even when deployed on
different hosts. different hosts.
:class:`TaskManager` methods, as well as driver methods, may be decorated to :class:`TaskManager` methods, as well as driver methods, may be decorated to
determine whether their invocation requires an exclusive lock. For example:: determine whether their invocation requires an exclusive lock. For example::
from ironic.manager import task_manager from ironic.conductor import task_manager
node_ids = [1, 2, 3] node_ids = [1, 2, 3]
try: try:
@ -66,8 +66,8 @@ import contextlib
from oslo.config import cfg from oslo.config import cfg
from ironic.common import exception from ironic.common import exception
from ironic.conductor import resource_manager
from ironic.db import api as dbapi from ironic.db import api as dbapi
from ironic.manager import resource_manager
CONF = cfg.CONF CONF = cfg.CONF

View File

@ -32,8 +32,8 @@ from ironic.common import exception
from ironic.common import paths from ironic.common import paths
from ironic.common import states from ironic.common import states
from ironic.common import utils from ironic.common import utils
from ironic.conductor import task_manager
from ironic.drivers import base from ironic.drivers import base
from ironic.manager import task_manager
from ironic.openstack.common import excutils from ironic.openstack.common import excutils
from ironic.openstack.common import jsonutils as json from ironic.openstack.common import jsonutils as json
from ironic.openstack.common import log as logging from ironic.openstack.common import log as logging

View File

@ -34,8 +34,8 @@ from oslo.config import cfg
from ironic.common import exception from ironic.common import exception
from ironic.common import states from ironic.common import states
from ironic.common import utils from ironic.common import utils
from ironic.conductor import task_manager
from ironic.drivers import base from ironic.drivers import base
from ironic.manager import task_manager
from ironic.openstack.common import jsonutils as json from ironic.openstack.common import jsonutils as json
from ironic.openstack.common import log as logging from ironic.openstack.common import log as logging

View File

@ -21,19 +21,19 @@
import mox import mox
from ironic.common import states from ironic.common import states
from ironic.conductor import manager
from ironic.db import api as dbapi from ironic.db import api as dbapi
from ironic.manager import manager
from ironic.openstack.common import context from ironic.openstack.common import context
from ironic.tests.conductor import utils as mgr_utils
from ironic.tests.db import base from ironic.tests.db import base
from ironic.tests.db import utils from ironic.tests.db import utils
from ironic.tests.manager import utils as mgr_utils
class ManagerTestCase(base.DbTestCase): class ManagerTestCase(base.DbTestCase):
def setUp(self): def setUp(self):
super(ManagerTestCase, self).setUp() super(ManagerTestCase, self).setUp()
self.service = manager.ManagerService('test-host', 'test-topic') self.service = manager.ConductorManager('test-host', 'test-topic')
self.context = context.get_admin_context() self.context = context.get_admin_context()
self.dbapi = dbapi.get_instance() self.dbapi = dbapi.get_instance()
self.driver = mgr_utils.get_mocked_node_manager() self.driver = mgr_utils.get_mocked_node_manager()

View File

@ -16,13 +16,13 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
""" """
Unit Tests for :py:class:`ironic.manager.rpcapi.ManagerAPI`. Unit Tests for :py:class:`ironic.conductor.rpcapi.ConductorAPI`.
""" """
from oslo.config import cfg from oslo.config import cfg
from ironic.conductor import rpcapi as conductor_rpcapi
from ironic.db import api as dbapi from ironic.db import api as dbapi
from ironic.manager import rpcapi as manager_rpcapi
from ironic.openstack.common import context from ironic.openstack.common import context
from ironic.openstack.common import jsonutils as json from ironic.openstack.common import jsonutils as json
from ironic.openstack.common import rpc from ironic.openstack.common import rpc
@ -32,10 +32,10 @@ from ironic.tests.db import utils as dbutils
CONF = cfg.CONF CONF = cfg.CONF
class ManagerRpcAPITestCase(base.DbTestCase): class RPCAPITestCase(base.DbTestCase):
def setUp(self): def setUp(self):
super(ManagerRpcAPITestCase, self).setUp() super(RPCAPITestCase, self).setUp()
self.context = context.get_admin_context() self.context = context.get_admin_context()
self.dbapi = dbapi.get_instance() self.dbapi = dbapi.get_instance()
self.fake_node = json.to_primitive(dbutils.get_test_node( self.fake_node = json.to_primitive(dbutils.get_test_node(
@ -47,7 +47,7 @@ class ManagerRpcAPITestCase(base.DbTestCase):
def _test_rpcapi(self, method, rpc_method, **kwargs): def _test_rpcapi(self, method, rpc_method, **kwargs):
ctxt = context.get_admin_context() ctxt = context.get_admin_context()
rpcapi = manager_rpcapi.ManagerAPI(topic='fake-topic') rpcapi = conductor_rpcapi.ConductorAPI(topic='fake-topic')
expected_retval = 'hello world' if method == 'call' else None expected_retval = 'hello world' if method == 'call' else None
expected_version = kwargs.pop('version', rpcapi.RPC_API_VERSION) expected_version = kwargs.pop('version', rpcapi.RPC_API_VERSION)

View File

@ -16,17 +16,17 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
"""Tests for :class:`ironic.manager.task_manager`.""" """Tests for :class:`ironic.conductor.task_manager`."""
from testtools import matchers from testtools import matchers
from ironic.common import exception from ironic.common import exception
from ironic.conductor import task_manager
from ironic.db import api as dbapi from ironic.db import api as dbapi
from ironic.manager import task_manager
from ironic.openstack.common import uuidutils from ironic.openstack.common import uuidutils
from ironic.tests.conductor import utils as mgr_utils
from ironic.tests.db import base from ironic.tests.db import base
from ironic.tests.db import utils from ironic.tests.db import utils
from ironic.tests.manager import utils as mgr_utils
def create_fake_node(i): def create_fake_node(i):

View File

@ -18,9 +18,9 @@
"""Tests for Ironic Manager test utils.""" """Tests for Ironic Manager test utils."""
from ironic.manager import resource_manager from ironic.conductor import resource_manager
from ironic.tests import base from ironic.tests import base
from ironic.tests.manager import utils from ironic.tests.conductor import utils
class UtilsTestCase(base.TestCase): class UtilsTestCase(base.TestCase):

View File

@ -21,7 +21,7 @@
import pkg_resources import pkg_resources
from stevedore import dispatch from stevedore import dispatch
from ironic.manager import resource_manager from ironic.conductor import resource_manager
def get_mockable_extension_manager(driver, namespace): def get_mockable_extension_manager(driver, namespace):

View File

@ -29,13 +29,13 @@ from ironic.openstack.common import jsonutils as json
from ironic.common import exception from ironic.common import exception
from ironic.common import states from ironic.common import states
from ironic.common import utils from ironic.common import utils
from ironic.conductor import task_manager
from ironic.db import api as db_api from ironic.db import api as db_api
from ironic.drivers.modules import ipmi from ironic.drivers.modules import ipmi
from ironic.manager import task_manager
from ironic.tests import base from ironic.tests import base
from ironic.tests.conductor import utils as mgr_utils
from ironic.tests.db import base as db_base from ironic.tests.db import base as db_base
from ironic.tests.db import utils as db_utils from ironic.tests.db import utils as db_utils
from ironic.tests.manager import utils as mgr_utils
CONF = cfg.CONF CONF = cfg.CONF

View File

@ -22,13 +22,13 @@ from ironic.openstack.common import jsonutils as json
from ironic.common import exception from ironic.common import exception
from ironic.common import states from ironic.common import states
from ironic.conductor import task_manager
from ironic.db import api as dbapi from ironic.db import api as dbapi
from ironic.drivers.modules import ssh from ironic.drivers.modules import ssh
from ironic.manager import task_manager
from ironic.tests import base from ironic.tests import base
from ironic.tests.conductor import utils as mgr_utils
from ironic.tests.db import base as db_base from ironic.tests.db import base as db_base
from ironic.tests.db import utils as db_utils from ironic.tests.db import utils as db_utils
from ironic.tests.manager import utils as mgr_utils
INFO_DICT = json.loads(db_utils.ssh_info).get('ssh') INFO_DICT = json.loads(db_utils.ssh_info).get('ssh')

View File

@ -30,7 +30,7 @@ packages =
console_scripts = console_scripts =
ironic-api = ironic.cmd.api:main ironic-api = ironic.cmd.api:main
ironic-dbsync = ironic.cmd.dbsync:main ironic-dbsync = ironic.cmd.dbsync:main
ironic-manager = ironic.cmd.manager:main ironic-conductor = ironic.cmd.conductor:main
ironic-rootwrap = ironic.openstack.common.rootwrap.cmd:main ironic-rootwrap = ironic.openstack.common.rootwrap.cmd:main
ironic.drivers = ironic.drivers =