rename Board -> Node
This commit is contained in:
parent
93d2f34680
commit
4bdc66d07a
12
bin/iotronic
12
bin/iotronic
|
@ -7,22 +7,22 @@ BASE=http://$HOST:$PORT/$VERSION
|
|||
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
echo "list - create-board - delete-board - show"
|
||||
echo "list - create-node - delete-node - show"
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
|
||||
list) curl -sS $BASE/boards/ | python -m json.tool
|
||||
list) curl -sS $BASE/nodes/ | python -m json.tool
|
||||
echo "";
|
||||
;;
|
||||
create-board) curl -sS -H "Content-Type: application/json" -X POST $BASE/boards/ -d '{"code":"'"$2"'"}' | python -m json.tool
|
||||
create-node) curl -sS -H "Content-Type: application/json" -X POST $BASE/nodes/ -d '{"code":"'"$2"'"}' | python -m json.tool
|
||||
echo "";
|
||||
;;
|
||||
delete-board) curl -sS -X DELETE $BASE/boards/$2 | python -m json.tool
|
||||
delete-node) curl -sS -X DELETE $BASE/nodes/$2 | python -m json.tool
|
||||
echo "";
|
||||
;;
|
||||
show) curl -sS $BASE/boards/$2 | python -m json.tool
|
||||
show) curl -sS $BASE/nodes/$2 | python -m json.tool
|
||||
echo "";
|
||||
;;
|
||||
*) echo "list - create-board - delete-board - show"
|
||||
*) echo "list - create-node - delete-node - show"
|
||||
esac
|
||||
|
|
|
@ -21,7 +21,7 @@ from pecan import rest
|
|||
from webob import exc
|
||||
from wsme import types as wtypes
|
||||
from iotronic.api.controllers import link
|
||||
from iotronic.api.controllers.v1 import board
|
||||
from iotronic.api.controllers.v1 import node
|
||||
|
||||
|
||||
'''
|
||||
|
@ -29,7 +29,7 @@ from iotronic.api.controllers.v1 import board
|
|||
|
||||
#from iotronic.api.controllers.v1 import chassis
|
||||
#from iotronic.api.controllers.v1 import driver
|
||||
from iotronic.api.controllers.v1 import node
|
||||
|
||||
|
||||
#from iotronic.api.controllers.v1 import port
|
||||
from iotronic.api.controllers.v1 import board
|
||||
|
@ -79,10 +79,7 @@ class V1(base.APIBase):
|
|||
#chassis = [link.Link]
|
||||
"""Links to the chassis resource"""
|
||||
|
||||
#nodes = [link.Link]
|
||||
"""Links to the nodes resource"""
|
||||
|
||||
boards = [link.Link]
|
||||
nodes = [link.Link]
|
||||
"""Links to the nodes resource"""
|
||||
|
||||
#ports = [link.Link]
|
||||
|
@ -96,13 +93,13 @@ class V1(base.APIBase):
|
|||
v1 = V1()
|
||||
v1.id = "v1"
|
||||
|
||||
v1.boards = [link.Link.make_link('self', pecan.request.host_url,
|
||||
'nodes', ''),
|
||||
link.Link.make_link('bookmark',
|
||||
pecan.request.host_url,
|
||||
'nodes', '',
|
||||
bookmark=True)
|
||||
]
|
||||
v1.nodes = [link.Link.make_link('self', pecan.request.host_url,
|
||||
'nodes', ''),
|
||||
link.Link.make_link('bookmark',
|
||||
pecan.request.host_url,
|
||||
'nodes', '',
|
||||
bookmark=True)
|
||||
]
|
||||
|
||||
'''
|
||||
v1.links = [link.Link.make_link('self', pecan.request.host_url,
|
||||
|
@ -124,14 +121,6 @@ class V1(base.APIBase):
|
|||
'chassis', '',
|
||||
bookmark=True)
|
||||
]
|
||||
|
||||
v1.nodes = [link.Link.make_link('self', pecan.request.host_url,
|
||||
'nodes', ''),
|
||||
link.Link.make_link('bookmark',
|
||||
pecan.request.host_url,
|
||||
'nodes', '',
|
||||
bookmark=True)
|
||||
]
|
||||
'''
|
||||
'''
|
||||
v1.ports = [link.Link.make_link('self', pecan.request.host_url,
|
||||
|
@ -155,8 +144,7 @@ class V1(base.APIBase):
|
|||
class Controller(rest.RestController):
|
||||
"""Version 1 API controller root."""
|
||||
|
||||
boards = board.BoardsController()
|
||||
#nodes = node.NodesController()
|
||||
nodes = node.NodesController()
|
||||
#ports = port.PortsController()
|
||||
#chassis = chassis.ChassisController()
|
||||
#drivers = driver.DriversController()
|
||||
|
|
|
@ -12,8 +12,8 @@ import pecan
|
|||
from pecan import rest
|
||||
|
||||
|
||||
class Board(base.APIBase):
|
||||
"""API representation of a board.
|
||||
class Node(base.APIBase):
|
||||
"""API representation of a node.
|
||||
"""
|
||||
|
||||
uuid = types.uuid
|
||||
|
@ -21,45 +21,45 @@ class Board(base.APIBase):
|
|||
status = wsme.wsattr(wtypes.text)
|
||||
|
||||
@staticmethod
|
||||
def _convert_with_links(board, url, expand=True, show_password=True):
|
||||
def _convert_with_links(node, url, expand=True, show_password=True):
|
||||
'''
|
||||
if not expand:
|
||||
except_list = ['instance_uuid', 'maintenance', 'power_state',
|
||||
'provision_state', 'uuid', 'name']
|
||||
board.unset_fields_except(except_list)
|
||||
node.unset_fields_except(except_list)
|
||||
else:
|
||||
if not show_password:
|
||||
board.driver_info = ast.literal_eval(strutils.mask_password(
|
||||
board.driver_info,
|
||||
node.driver_info = ast.literal_eval(strutils.mask_password(
|
||||
node.driver_info,
|
||||
"******"))
|
||||
board.ports = [link.Link.make_link('self', url, 'boards',
|
||||
board.uuid + "/ports"),
|
||||
link.Link.make_link('bookmark', url, 'boards',
|
||||
board.uuid + "/ports",
|
||||
node.ports = [link.Link.make_link('self', url, 'nodes',
|
||||
node.uuid + "/ports"),
|
||||
link.Link.make_link('bookmark', url, 'nodes',
|
||||
node.uuid + "/ports",
|
||||
bookmark=True)
|
||||
]
|
||||
|
||||
board.chassis_id = wtypes.Unset
|
||||
node.chassis_id = wtypes.Unset
|
||||
'''
|
||||
'''
|
||||
board.links = [link.Link.make_link('self', url, 'boards',
|
||||
board.uuid),
|
||||
link.Link.make_link('bookmark', url, 'boards',
|
||||
board.uuid, bookmark=True)
|
||||
node.links = [link.Link.make_link('self', url, 'nodes',
|
||||
node.uuid),
|
||||
link.Link.make_link('bookmark', url, 'nodes',
|
||||
node.uuid, bookmark=True)
|
||||
]
|
||||
'''
|
||||
return board
|
||||
return node
|
||||
|
||||
@classmethod
|
||||
def convert_with_links(cls, rpc_board, expand=True):
|
||||
board = Board(**rpc_board.as_dict())
|
||||
return cls._convert_with_links(board, pecan.request.host_url,
|
||||
def convert_with_links(cls, rpc_node, expand=True):
|
||||
node = Node(**rpc_node.as_dict())
|
||||
return cls._convert_with_links(node, pecan.request.host_url,
|
||||
expand,
|
||||
pecan.request.context.show_password)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.fields = []
|
||||
fields = list(objects.Board.fields)
|
||||
fields = list(objects.Node.fields)
|
||||
for k in fields:
|
||||
# Skip fields we do not expose.
|
||||
if not hasattr(self, k):
|
||||
|
@ -67,27 +67,27 @@ class Board(base.APIBase):
|
|||
self.fields.append(k)
|
||||
setattr(self, k, kwargs.get(k, wtypes.Unset))
|
||||
|
||||
class BoardCollection(collection.Collection):
|
||||
"""API representation of a collection of boards."""
|
||||
class NodeCollection(collection.Collection):
|
||||
"""API representation of a collection of nodes."""
|
||||
|
||||
boards = [Board]
|
||||
"""A list containing boards objects"""
|
||||
nodes = [Node]
|
||||
"""A list containing nodes objects"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self._type = 'boards'
|
||||
self._type = 'nodes'
|
||||
|
||||
@staticmethod
|
||||
def convert_with_links(boards, limit, url=None, expand=False, **kwargs):
|
||||
collection = BoardCollection()
|
||||
collection.boards = [Board.convert_with_links(n, expand) for n in boards]
|
||||
def convert_with_links(nodes, limit, url=None, expand=False, **kwargs):
|
||||
collection = NodeCollection()
|
||||
collection.nodes = [Node.convert_with_links(n, expand) for n in nodes]
|
||||
collection.next = collection.get_next(limit, url=url, **kwargs)
|
||||
return collection
|
||||
|
||||
class BoardsController(rest.RestController):
|
||||
class NodesController(rest.RestController):
|
||||
|
||||
invalid_sort_key_list = ['properties']
|
||||
|
||||
def _get_boards_collection(self, chassis_uuid, instance_uuid, associated,
|
||||
def _get_nodes_collection(self, chassis_uuid, instance_uuid, associated,
|
||||
maintenance, marker, limit, sort_key, sort_dir,
|
||||
expand=False, resource_url=None):
|
||||
'''
|
||||
|
@ -100,7 +100,7 @@ class BoardsController(rest.RestController):
|
|||
|
||||
marker_obj = None
|
||||
if marker:
|
||||
marker_obj = objects.Board.get_by_uuid(pecan.request.context,
|
||||
marker_obj = objects.Node.get_by_uuid(pecan.request.context,
|
||||
marker)
|
||||
|
||||
if sort_key in self.invalid_sort_key_list:
|
||||
|
@ -109,7 +109,7 @@ class BoardsController(rest.RestController):
|
|||
"sorting") % {'key': sort_key})
|
||||
|
||||
if instance_uuid:
|
||||
boards = self._get_boards_by_instance(instance_uuid)
|
||||
nodes = self._get_nodes_by_instance(instance_uuid)
|
||||
else:
|
||||
filters = {}
|
||||
if chassis_uuid:
|
||||
|
@ -119,7 +119,7 @@ class BoardsController(rest.RestController):
|
|||
if maintenance is not None:
|
||||
filters['maintenance'] = maintenance
|
||||
|
||||
boards = objects.Board.list(pecan.request.context, limit, marker_obj,
|
||||
nodes = objects.Node.list(pecan.request.context, limit, marker_obj,
|
||||
sort_key=sort_key, sort_dir=sort_dir,
|
||||
filters=filters)
|
||||
|
||||
|
@ -128,80 +128,80 @@ class BoardsController(rest.RestController):
|
|||
parameters['associated'] = associated
|
||||
if maintenance:
|
||||
parameters['maintenance'] = maintenance
|
||||
return BoardCollection.convert_with_links(boards, limit,
|
||||
return NodeCollection.convert_with_links(nodes, limit,
|
||||
url=resource_url,
|
||||
expand=expand,
|
||||
**parameters)
|
||||
|
||||
@expose.expose(BoardCollection, types.uuid, types.uuid, types.boolean,
|
||||
@expose.expose(NodeCollection, types.uuid, types.uuid, types.boolean,
|
||||
types.boolean, types.uuid, int, wtypes.text, wtypes.text)
|
||||
def get_all(self, chassis_uuid=None, instance_uuid=None, associated=None,
|
||||
maintenance=None, marker=None, limit=None, sort_key='id',
|
||||
sort_dir='asc'):
|
||||
"""Retrieve a list of boards.
|
||||
"""Retrieve a list of nodes.
|
||||
|
||||
:param chassis_uuid: Optional UUID of a chassis, to get only boards for
|
||||
:param chassis_uuid: Optional UUID of a chassis, to get only nodes for
|
||||
that chassis.
|
||||
:param instance_uuid: Optional UUID of an instance, to find the board
|
||||
:param instance_uuid: Optional UUID of an instance, to find the node
|
||||
associated with that instance.
|
||||
:param associated: Optional boolean whether to return a list of
|
||||
associated or unassociated boards. May be combined
|
||||
associated or unassociated nodes. May be combined
|
||||
with other parameters.
|
||||
:param maintenance: Optional boolean value that indicates whether
|
||||
to get boards in maintenance mode ("True"), or not
|
||||
to get nodes in maintenance mode ("True"), or not
|
||||
in maintenance mode ("False").
|
||||
:param marker: pagination marker for large data sets.
|
||||
:param limit: maximum number of resources to return in a single result.
|
||||
:param sort_key: column to sort results by. Default: id.
|
||||
:param sort_dir: direction to sort. "asc" or "desc". Default: asc.
|
||||
"""
|
||||
return self._get_boards_collection(chassis_uuid, instance_uuid,
|
||||
return self._get_nodes_collection(chassis_uuid, instance_uuid,
|
||||
associated, maintenance, marker,
|
||||
limit, sort_key, sort_dir)
|
||||
|
||||
|
||||
|
||||
@expose.expose(Board,types.uuid_or_name)
|
||||
def get(self,board_ident):
|
||||
"""Retrieve information about the given board.
|
||||
@expose.expose(Node,types.uuid_or_name)
|
||||
def get(self,node_ident):
|
||||
"""Retrieve information about the given node.
|
||||
|
||||
:param node_ident: UUID or logical name of a board.
|
||||
:param node_ident: UUID or logical name of a node.
|
||||
"""
|
||||
rpc_board = api_utils.get_rpc_board(board_ident)
|
||||
board = Board(**rpc_board.as_dict())
|
||||
return board
|
||||
rpc_node = api_utils.get_rpc_node(node_ident)
|
||||
node = Node(**rpc_node.as_dict())
|
||||
return node
|
||||
|
||||
@expose.expose(None, types.uuid_or_name, status_code=204)
|
||||
def delete(self, board_ident):
|
||||
"""Delete a board.
|
||||
def delete(self, node_ident):
|
||||
"""Delete a node.
|
||||
|
||||
:param board_ident: UUID or logical name of a board.
|
||||
:param node_ident: UUID or logical name of a node.
|
||||
"""
|
||||
rpc_board = api_utils.get_rpc_board(board_ident)
|
||||
rpc_node = api_utils.get_rpc_node(node_ident)
|
||||
|
||||
try:
|
||||
topic = pecan.request.rpcapi.get_topic_for(rpc_board)
|
||||
topic = pecan.request.rpcapi.get_topic_for(rpc_node)
|
||||
except exception.NoValidHost as e:
|
||||
e.code = 400
|
||||
raise e
|
||||
|
||||
pecan.request.rpcapi.destroy_board(pecan.request.context,
|
||||
rpc_board.uuid, topic)
|
||||
pecan.request.rpcapi.destroy_node(pecan.request.context,
|
||||
rpc_node.uuid, topic)
|
||||
|
||||
@expose.expose(Board, body=Board, status_code=201)
|
||||
def post(self,Board):
|
||||
"""Create a new Board.
|
||||
@expose.expose(Node, body=Node, status_code=201)
|
||||
def post(self,Node):
|
||||
"""Create a new Node.
|
||||
|
||||
:param Board: a Board within the request body.
|
||||
:param Node: a Node within the request body.
|
||||
"""
|
||||
|
||||
if not Board.uuid:
|
||||
Board.uuid = uuidutils.generate_uuid()
|
||||
if not Board.status:
|
||||
Board.status = 'DISCONNECTED'
|
||||
new_Board = objects.Board(pecan.request.context,
|
||||
**Board.as_dict())
|
||||
new_Board.create()
|
||||
#pecan.response.location = link.build_url('Boards', new_Board.uuid)
|
||||
return Board.convert_with_links(new_Board)
|
||||
if not Node.uuid:
|
||||
Node.uuid = uuidutils.generate_uuid()
|
||||
if not Node.status:
|
||||
Node.status = 'DISCONNECTED'
|
||||
new_Node = objects.Node(pecan.request.context,
|
||||
**Node.as_dict())
|
||||
new_Node.create()
|
||||
#pecan.response.location = link.build_url('Nodes', new_Node.uuid)
|
||||
return Node.convert_with_links(new_Node)
|
||||
|
|
@ -337,7 +337,7 @@ class ConductorAPI(object):
|
|||
:raises: InvalidState if the node is in the wrong provision
|
||||
state to perform deletion.
|
||||
"""
|
||||
cctxt = self.client.prepare(topic=topic or self.topic, version='1.9')
|
||||
cctxt = self.client.prepare(topic=topic or self.topic, version='1.0')
|
||||
return cctxt.call(context, 'destroy_node', node_id=node_id)
|
||||
|
||||
def get_console_information(self, context, node_id, topic=None):
|
||||
|
@ -505,6 +505,7 @@ class ConductorAPI(object):
|
|||
cctxt = self.client.prepare(topic=topic or self.topic, version='1.25')
|
||||
return cctxt.call(context, 'destroy_port', port=port)
|
||||
|
||||
'''
|
||||
######################### NEW
|
||||
|
||||
def destroy_board(self, context, board_id, topic=None):
|
||||
|
@ -520,3 +521,4 @@ class ConductorAPI(object):
|
|||
"""
|
||||
cctxt = self.client.prepare(topic=topic or self.topic, version='1.0')
|
||||
return cctxt.call(context, 'destroy_board', board_id=board_id)
|
||||
'''
|
|
@ -19,10 +19,10 @@
|
|||
A context manager to perform a series of tasks on a set of resources.
|
||||
|
||||
:class:`TaskManager` is a context manager, created on-demand to allow
|
||||
synchronized access to a board and its resources.
|
||||
synchronized access to a node and its resources.
|
||||
|
||||
The :class:`TaskManager` will, by default, acquire an exclusive lock on
|
||||
a board for the duration that the TaskManager instance exists. You may
|
||||
a node for the duration that the TaskManager instance exists. You may
|
||||
create a TaskManager instance without locking by passing "shared=True"
|
||||
when creating it, but certain operations on the resources held by such
|
||||
an instance of TaskManager will not be possible. Requiring this exclusive
|
||||
|
@ -38,28 +38,28 @@ different hosts.
|
|||
:class:`TaskManager` methods, as well as driver methods, may be decorated to
|
||||
determine whether their invocation requires an exclusive lock.
|
||||
|
||||
The TaskManager instance exposes certain board resources and properties as
|
||||
The TaskManager instance exposes certain node resources and properties as
|
||||
attributes that you may access:
|
||||
|
||||
task.context
|
||||
The context passed to TaskManager()
|
||||
task.shared
|
||||
False if Board is locked, True if it is not locked. (The
|
||||
False if Node is locked, True if it is not locked. (The
|
||||
'shared' kwarg arg of TaskManager())
|
||||
task.board
|
||||
The Board object
|
||||
task.node
|
||||
The Node object
|
||||
task.ports
|
||||
Ports belonging to the Board
|
||||
Ports belonging to the Node
|
||||
task.driver
|
||||
The Driver for the Board, or the Driver based on the
|
||||
The Driver for the Node, or the Driver based on the
|
||||
'driver_name' kwarg of TaskManager().
|
||||
|
||||
Example usage:
|
||||
|
||||
::
|
||||
|
||||
with task_manager.acquire(context, board_id) as task:
|
||||
task.driver.power.power_on(task.board)
|
||||
with task_manager.acquire(context, node_id) as task:
|
||||
task.driver.power.power_on(task.node)
|
||||
|
||||
If you need to execute task-requiring code in a background thread, the
|
||||
TaskManager instance provides an interface to handle this for you, making
|
||||
|
@ -68,10 +68,10 @@ an exception occurs). Common use of this is within the Manager like so:
|
|||
|
||||
::
|
||||
|
||||
with task_manager.acquire(context, board_id) as task:
|
||||
with task_manager.acquire(context, node_id) as task:
|
||||
<do some work>
|
||||
task.spawn_after(self._spawn_worker,
|
||||
utils.board_power_action, task, new_state)
|
||||
utils.node_power_action, task, new_state)
|
||||
|
||||
All exceptions that occur in the current GreenThread as part of the
|
||||
spawn handling are re-raised. You can specify a hook to execute custom
|
||||
|
@ -86,11 +86,11 @@ raised in the background thread.):
|
|||
if isinstance(e, Exception):
|
||||
...
|
||||
|
||||
with task_manager.acquire(context, board_id) as task:
|
||||
with task_manager.acquire(context, node_id) as task:
|
||||
<do some work>
|
||||
task.set_spawn_error_hook(on_error)
|
||||
task.spawn_after(self._spawn_worker,
|
||||
utils.board_power_action, task, new_state)
|
||||
utils.node_power_action, task, new_state)
|
||||
|
||||
"""
|
||||
|
||||
|
@ -129,18 +129,18 @@ def require_exclusive_lock(f):
|
|||
return wrapper
|
||||
|
||||
|
||||
def acquire(context, board_id, shared=False, driver_name=None):
|
||||
"""Shortcut for acquiring a lock on a Board.
|
||||
def acquire(context, node_id, shared=False, driver_name=None):
|
||||
"""Shortcut for acquiring a lock on a Node.
|
||||
|
||||
:param context: Request context.
|
||||
:param board_id: ID or UUID of board to lock.
|
||||
:param node_id: ID or UUID of node to lock.
|
||||
:param shared: Boolean indicating whether to take a shared or exclusive
|
||||
lock. Default: False.
|
||||
:param driver_name: Name of Driver. Default: None.
|
||||
:returns: An instance of :class:`TaskManager`.
|
||||
|
||||
"""
|
||||
return TaskManager(context, board_id, shared=shared,
|
||||
return TaskManager(context, node_id, shared=shared,
|
||||
driver_name=driver_name)
|
||||
|
||||
|
||||
|
@ -148,27 +148,27 @@ class TaskManager(object):
|
|||
"""Context manager for tasks.
|
||||
|
||||
This class wraps the locking, driver loading, and acquisition
|
||||
of related resources (eg, Board and Ports) when beginning a unit of work.
|
||||
of related resources (eg, Node and Ports) when beginning a unit of work.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, context, board_id, shared=False, driver_name=None):
|
||||
def __init__(self, context, node_id, shared=False, driver_name=None):
|
||||
"""Create a new TaskManager.
|
||||
|
||||
Acquire a lock on a board. The lock can be either shared or
|
||||
Acquire a lock on a node. The lock can be either shared or
|
||||
exclusive. Shared locks may be used for read-only or
|
||||
non-disruptive actions only, and must be considerate to what
|
||||
other threads may be doing on the same board at the same time.
|
||||
other threads may be doing on the same node at the same time.
|
||||
|
||||
:param context: request context
|
||||
:param board_id: ID or UUID of board to lock.
|
||||
:param node_id: ID or UUID of node to lock.
|
||||
:param shared: Boolean indicating whether to take a shared or exclusive
|
||||
lock. Default: False.
|
||||
:param driver_name: The name of the driver to load, if different
|
||||
from the Board's current driver.
|
||||
from the Node's current driver.
|
||||
:raises: DriverNotFound
|
||||
:raises: BoardNotFound
|
||||
:raises: BoardLocked
|
||||
:raises: NodeNotFound
|
||||
:raises: NodeLocked
|
||||
|
||||
"""
|
||||
|
||||
|
@ -176,41 +176,43 @@ class TaskManager(object):
|
|||
self._on_error_method = None
|
||||
|
||||
self.context = context
|
||||
#self.board = None
|
||||
self.board = None
|
||||
#self.node = None
|
||||
self.node = None
|
||||
self.shared = shared
|
||||
|
||||
self.fsm = states.machine.copy()
|
||||
|
||||
# BoardLocked exceptions can be annoying. Let's try to alleviate
|
||||
# NodeLocked exceptions can be annoying. Let's try to alleviate
|
||||
# some of that pain by retrying our lock attempts. The retrying
|
||||
# module expects a wait_fixed value in milliseconds.
|
||||
@retrying.retry(
|
||||
retry_on_exception=lambda e: isinstance(e, exception.BoardLocked),
|
||||
stop_max_attempt_number=CONF.conductor.board_locked_retry_attempts,
|
||||
wait_fixed=CONF.conductor.board_locked_retry_interval * 1000)
|
||||
def reserve_board():
|
||||
LOG.debug("Attempting to reserve board %(board)s",
|
||||
{'board': board_id})
|
||||
self.board = objects.Board.reserve(context, CONF.host, board_id)
|
||||
retry_on_exception=lambda e: isinstance(e, exception.NodeLocked),
|
||||
stop_max_attempt_number=CONF.conductor.node_locked_retry_attempts,
|
||||
wait_fixed=CONF.conductor.node_locked_retry_interval * 1000)
|
||||
def reserve_node():
|
||||
LOG.debug("Attempting to reserve node %(node)s",
|
||||
{'node': node_id})
|
||||
self.node = objects.Node.reserve(context, CONF.host, node_id)
|
||||
|
||||
try:
|
||||
"""
|
||||
if not self.shared:
|
||||
reserve_board()
|
||||
reserve_node()
|
||||
else:
|
||||
self.board = objects.Board.get(context, board_id)
|
||||
#self.ports = objects.Port.list_by_board_id(context, self.board.id)
|
||||
"""
|
||||
self.node = objects.Node.get(context, node_id)
|
||||
#self.ports = objects.Port.list_by_node_id(context, self.node.id)
|
||||
#self.driver = driver_factory.get_driver(driver_name or
|
||||
# self.board.driver)
|
||||
# self.node.driver)
|
||||
|
||||
# NOTE(deva): this handles the Juno-era NOSTATE state
|
||||
# and should be deleted after Kilo is released
|
||||
'''
|
||||
if self.board.provision_state is states.NOSTATE:
|
||||
self.board.provision_state = states.AVAILABLE
|
||||
self.board.save()
|
||||
if self.node.provision_state is states.NOSTATE:
|
||||
self.node.provision_state = states.AVAILABLE
|
||||
self.node.save()
|
||||
|
||||
self.fsm.initialize(self.board.provision_state)
|
||||
self.fsm.initialize(self.node.provision_state)
|
||||
'''
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception():
|
||||
|
@ -248,25 +250,27 @@ class TaskManager(object):
|
|||
self._on_error_kwargs = kwargs
|
||||
|
||||
def release_resources(self):
|
||||
"""Unlock a board and release resources.
|
||||
"""Unlock a node and release resources.
|
||||
|
||||
If an exclusive lock is held, unlock the board. Reset attributes
|
||||
If an exclusive lock is held, unlock the node. Reset attributes
|
||||
to make it clear that this instance of TaskManager should no
|
||||
longer be accessed.
|
||||
"""
|
||||
|
||||
pass #don't need it at the moment
|
||||
"""
|
||||
if not self.shared:
|
||||
try:
|
||||
if self.board:
|
||||
objects.Board.release(self.context, CONF.host, self.board.id)
|
||||
except exception.BoardNotFound:
|
||||
# squelch the exception if the board was deleted
|
||||
if self.node:
|
||||
objects.Node.release(self.context, CONF.host, self.node.id)
|
||||
except exception.NodeNotFound:
|
||||
# squelch the exception if the node was deleted
|
||||
# within the task's context.
|
||||
pass
|
||||
self.board = None
|
||||
self.node = None
|
||||
self.driver = None
|
||||
self.ports = None
|
||||
self.fsm = None
|
||||
"""
|
||||
|
||||
def _thread_release_resources(self, t):
|
||||
"""Thread.link() callback to release resources."""
|
||||
|
@ -282,38 +286,38 @@ class TaskManager(object):
|
|||
:param call_kwargs: optional \**kwargs to pass to the callback method
|
||||
:param err_handler: optional error handler to invoke if the
|
||||
callback fails, eg. because there are no workers available
|
||||
(err_handler should accept arguments board, prev_prov_state, and
|
||||
(err_handler should accept arguments node, prev_prov_state, and
|
||||
prev_target_state)
|
||||
:raises: InvalidState if the event is not allowed by the associated
|
||||
state machine
|
||||
"""
|
||||
# Advance the state model for the given event. Note that this doesn't
|
||||
# alter the board in any way. This may raise InvalidState, if this event
|
||||
# alter the node in any way. This may raise InvalidState, if this event
|
||||
# is not allowed in the current state.
|
||||
self.fsm.process_event(event)
|
||||
|
||||
# stash current states in the error handler if callback is set,
|
||||
# in case we fail to get a worker from the pool
|
||||
if err_handler and callback:
|
||||
self.set_spawn_error_hook(err_handler, self.board,
|
||||
self.board.provision_state,
|
||||
self.board.target_provision_state)
|
||||
self.set_spawn_error_hook(err_handler, self.node,
|
||||
self.node.provision_state,
|
||||
self.node.target_provision_state)
|
||||
|
||||
self.board.provision_state = self.fsm.current_state
|
||||
self.board.target_provision_state = self.fsm.target_state
|
||||
self.node.provision_state = self.fsm.current_state
|
||||
self.node.target_provision_state = self.fsm.target_state
|
||||
|
||||
# set up the async worker
|
||||
if callback:
|
||||
# clear the error if we're going to start work in a callback
|
||||
self.board.last_error = None
|
||||
self.node.last_error = None
|
||||
if call_args is None:
|
||||
call_args = ()
|
||||
if call_kwargs is None:
|
||||
call_kwargs = {}
|
||||
self.spawn_after(callback, *call_args, **call_kwargs)
|
||||
|
||||
# publish the state transition by saving the Board
|
||||
self.board.save()
|
||||
# publish the state transition by saving the Node
|
||||
self.node.save()
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
@ -351,9 +355,9 @@ class TaskManager(object):
|
|||
**self._on_error_kwargs)
|
||||
except Exception:
|
||||
LOG.warning(_LW("Task's on_error hook failed to "
|
||||
"call %(method)s on board %(board)s"),
|
||||
"call %(method)s on node %(node)s"),
|
||||
{'method': self._on_error_method.__name__,
|
||||
'board': self.board.uuid})
|
||||
'node': self.node.uuid})
|
||||
|
||||
if thread is not None:
|
||||
# This means the link() failed for some
|
||||
|
|
|
@ -395,7 +395,7 @@ class Connection(object):
|
|||
"""
|
||||
|
||||
|
||||
|
||||
'''
|
||||
|
||||
###################### NEW #############################
|
||||
|
||||
|
@ -572,3 +572,4 @@ class Connection(object):
|
|||
:raises: BoardAssociated
|
||||
:raises: BoardNotFound
|
||||
"""
|
||||
'''
|
||||
|
|
|
@ -119,9 +119,9 @@ def add_port_filter_by_node(query, value):
|
|||
if strutils.is_int_like(value):
|
||||
return query.filter_by(node_id=value)
|
||||
else:
|
||||
query = query.join(models.Board,
|
||||
models.Port.node_id == models.Board.id)
|
||||
return query.filter(models.Board.uuid == value)
|
||||
query = query.join(models.Node,
|
||||
models.Port.node_id == models.Node.id)
|
||||
return query.filter(models.Node.uuid == value)
|
||||
|
||||
|
||||
def add_node_filter_by_chassis(query, value):
|
||||
|
@ -129,7 +129,7 @@ def add_node_filter_by_chassis(query, value):
|
|||
return query.filter_by(chassis_id=value)
|
||||
else:
|
||||
query = query.join(models.Chassis,
|
||||
models.Board.chassis_id == models.Chassis.id)
|
||||
models.Node.chassis_id == models.Chassis.id)
|
||||
return query.filter(models.Chassis.uuid == value)
|
||||
|
||||
|
||||
|
@ -167,14 +167,16 @@ class Connection(api.Connection):
|
|||
query = query.filter_by(chassis_id=chassis_obj.id)
|
||||
if 'associated' in filters:
|
||||
if filters['associated']:
|
||||
query = query.filter(models.Board.instance_uuid != None)
|
||||
query = query.filter(models.Node.instance_uuid != None)
|
||||
else:
|
||||
query = query.filter(models.Board.instance_uuid == None)
|
||||
query = query.filter(models.Node.instance_uuid == None)
|
||||
"""
|
||||
if 'reserved' in filters:
|
||||
if filters['reserved']:
|
||||
query = query.filter(models.Board.reservation != None)
|
||||
query = query.filter(models.Node.reservation != None)
|
||||
else:
|
||||
query = query.filter(models.Board.reservation == None)
|
||||
query = query.filter(models.Node.reservation == None)
|
||||
"""
|
||||
if 'maintenance' in filters:
|
||||
query = query.filter_by(maintenance=filters['maintenance'])
|
||||
if 'driver' in filters:
|
||||
|
@ -184,12 +186,12 @@ class Connection(api.Connection):
|
|||
if 'provisioned_before' in filters:
|
||||
limit = (timeutils.utcnow() -
|
||||
datetime.timedelta(seconds=filters['provisioned_before']))
|
||||
query = query.filter(models.Board.provision_updated_at < limit)
|
||||
query = query.filter(models.Node.provision_updated_at < limit)
|
||||
if 'inspection_started_before' in filters:
|
||||
limit = ((timeutils.utcnow()) -
|
||||
(datetime.timedelta(
|
||||
seconds=filters['inspection_started_before'])))
|
||||
query = query.filter(models.Board.inspection_started_at < limit)
|
||||
query = query.filter(models.Node.inspection_started_at < limit)
|
||||
|
||||
return query
|
||||
|
||||
|
@ -198,26 +200,26 @@ class Connection(api.Connection):
|
|||
# list-ify columns default values because it is bad form
|
||||
# to include a mutable list in function definitions.
|
||||
if columns is None:
|
||||
columns = [models.Board.id]
|
||||
columns = [models.Node.id]
|
||||
else:
|
||||
columns = [getattr(models.Board, c) for c in columns]
|
||||
columns = [getattr(models.Node, c) for c in columns]
|
||||
|
||||
query = model_query(*columns, base_model=models.Board)
|
||||
query = model_query(*columns, base_model=models.Node)
|
||||
query = self._add_nodes_filters(query, filters)
|
||||
return _paginate_query(models.Board, limit, marker,
|
||||
return _paginate_query(models.Node, limit, marker,
|
||||
sort_key, sort_dir, query)
|
||||
|
||||
def get_node_list(self, filters=None, limit=None, marker=None,
|
||||
sort_key=None, sort_dir=None):
|
||||
query = model_query(models.Board)
|
||||
query = model_query(models.Node)
|
||||
query = self._add_nodes_filters(query, filters)
|
||||
return _paginate_query(models.Board, limit, marker,
|
||||
return _paginate_query(models.Node, limit, marker,
|
||||
sort_key, sort_dir, query)
|
||||
|
||||
def reserve_node(self, tag, node_id):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(models.Board, session=session)
|
||||
query = model_query(models.Node, session=session)
|
||||
query = add_identity_filter(query, node_id)
|
||||
# be optimistic and assume we usually create a reservation
|
||||
count = query.filter_by(reservation=None).update(
|
||||
|
@ -236,7 +238,7 @@ class Connection(api.Connection):
|
|||
def release_node(self, tag, node_id):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(models.Board, session=session)
|
||||
query = model_query(models.Node, session=session)
|
||||
query = add_identity_filter(query, node_id)
|
||||
# be optimistic and assume we usually release a reservation
|
||||
count = query.filter_by(reservation=tag).update(
|
||||
|
@ -262,7 +264,7 @@ class Connection(api.Connection):
|
|||
# TODO(deva): change this to ENROLL
|
||||
values['provision_state'] = states.AVAILABLE
|
||||
|
||||
node = models.Board()
|
||||
node = models.Node()
|
||||
node.update(values)
|
||||
try:
|
||||
node.save()
|
||||
|
@ -277,21 +279,21 @@ class Connection(api.Connection):
|
|||
return node
|
||||
|
||||
def get_node_by_id(self, node_id):
|
||||
query = model_query(models.Board).filter_by(id=node_id)
|
||||
query = model_query(models.Node).filter_by(id=node_id)
|
||||
try:
|
||||
return query.one()
|
||||
except NoResultFound:
|
||||
raise exception.NodeNotFound(node=node_id)
|
||||
|
||||
def get_node_by_uuid(self, node_uuid):
|
||||
query = model_query(models.Board).filter_by(uuid=node_uuid)
|
||||
query = model_query(models.Node).filter_by(uuid=node_uuid)
|
||||
try:
|
||||
return query.one()
|
||||
except NoResultFound:
|
||||
raise exception.NodeNotFound(node=node_uuid)
|
||||
|
||||
def get_node_by_name(self, node_name):
|
||||
query = model_query(models.Board).filter_by(name=node_name)
|
||||
query = model_query(models.Node).filter_by(name=node_name)
|
||||
try:
|
||||
return query.one()
|
||||
except NoResultFound:
|
||||
|
@ -301,7 +303,7 @@ class Connection(api.Connection):
|
|||
if not uuidutils.is_uuid_like(instance):
|
||||
raise exception.InvalidUUID(uuid=instance)
|
||||
|
||||
query = (model_query(models.Board)
|
||||
query = (model_query(models.Node)
|
||||
.filter_by(instance_uuid=instance))
|
||||
|
||||
try:
|
||||
|
@ -312,9 +314,26 @@ class Connection(api.Connection):
|
|||
return result
|
||||
|
||||
def destroy_node(self, node_id):
|
||||
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(models.Board, session=session)
|
||||
query = model_query(models.Node, session=session)
|
||||
query = add_identity_filter(query, node_id)
|
||||
try:
|
||||
node_ref = query.one()
|
||||
except NoResultFound:
|
||||
raise exception.NodeNotFound(node=node_id)
|
||||
|
||||
# Get node ID, if an UUID was supplied. The ID is
|
||||
# required for deleting all ports, attached to the node.
|
||||
if uuidutils.is_uuid_like(node_id):
|
||||
node_id = node_ref['id']
|
||||
|
||||
query.delete()
|
||||
"""
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(models.Node, session=session)
|
||||
query = add_identity_filter(query, node_id)
|
||||
|
||||
try:
|
||||
|
@ -332,11 +351,12 @@ class Connection(api.Connection):
|
|||
#port_query.delete()
|
||||
|
||||
query.delete()
|
||||
"""
|
||||
|
||||
def update_node(self, node_id, values):
|
||||
# NOTE(dtantsur): this can lead to very strange errors
|
||||
if 'uuid' in values:
|
||||
msg = _("Cannot overwrite UUID for an existing Board.")
|
||||
msg = _("Cannot overwrite UUID for an existing Node.")
|
||||
raise exception.InvalidParameterValue(err=msg)
|
||||
|
||||
try:
|
||||
|
@ -356,7 +376,7 @@ class Connection(api.Connection):
|
|||
def _do_update_node(self, node_id, values):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
query = model_query(models.Board, session=session)
|
||||
query = model_query(models.Node, session=session)
|
||||
query = add_identity_filter(query, node_id)
|
||||
try:
|
||||
ref = query.with_lockmode('update').one()
|
||||
|
@ -509,7 +529,7 @@ class Connection(api.Connection):
|
|||
def chassis_not_empty(session):
|
||||
"""Checks whether the chassis does not have nodes."""
|
||||
|
||||
query = model_query(models.Board, session=session)
|
||||
query = model_query(models.Node, session=session)
|
||||
query = add_node_filter_by_chassis(query, chassis_id)
|
||||
|
||||
return query.count() != 0
|
||||
|
@ -579,7 +599,7 @@ class Connection(api.Connection):
|
|||
session = get_session()
|
||||
nodes = []
|
||||
with session.begin():
|
||||
query = (model_query(models.Board, session=session)
|
||||
query = (model_query(models.Node, session=session)
|
||||
.filter_by(reservation=hostname))
|
||||
nodes = [node['uuid'] for node in query]
|
||||
query.update({'reservation': None})
|
||||
|
@ -607,6 +627,7 @@ class Connection(api.Connection):
|
|||
return d2c
|
||||
|
||||
|
||||
"""
|
||||
###################### NEW #############################
|
||||
def _add_boards_filters(self, query, filters):
|
||||
if filters is None:
|
||||
|
@ -819,3 +840,4 @@ class Connection(api.Connection):
|
|||
'''
|
||||
ref.update(values)
|
||||
return ref
|
||||
"""
|
||||
|
|
|
@ -139,8 +139,22 @@ class Conductor(Base):
|
|||
|
||||
|
||||
class Node(Base):
|
||||
"""Represents a bare metal node."""
|
||||
"""Represents a board."""
|
||||
|
||||
__tablename__ = 'nodes'
|
||||
'''
|
||||
__table_args__ = (
|
||||
schema.UniqueConstraint('uuid', name='uniq_nodes0uuid'),
|
||||
schema.UniqueConstraint('instance_uuid',
|
||||
name='uniq_nodes0instance_uuid'),
|
||||
schema.UniqueConstraint('name', name='uniq_nodes0name'),
|
||||
table_args())
|
||||
'''
|
||||
id = Column(Integer, primary_key=True)
|
||||
uuid = Column(String(36))
|
||||
code = Column(String(25))
|
||||
status = Column(String(15), nullable=True)
|
||||
"""
|
||||
__tablename__ = 'nodes'
|
||||
'''
|
||||
__table_args__ = (
|
||||
|
@ -193,7 +207,7 @@ class Node(Base):
|
|||
#inspection_finished_at = Column(DateTime, nullable=True)
|
||||
#inspection_started_at = Column(DateTime, nullable=True)
|
||||
#extra = Column(JSONEncodedDict)
|
||||
|
||||
"""
|
||||
|
||||
class Port(Base):
|
||||
"""Represents a network port of a bare metal node."""
|
||||
|
@ -209,22 +223,3 @@ class Port(Base):
|
|||
node_id = Column(Integer, ForeignKey('nodes.id'), nullable=True)
|
||||
extra = Column(JSONEncodedDict)
|
||||
|
||||
##################### NEW
|
||||
class Board(Base):
|
||||
"""Represents a board."""
|
||||
|
||||
__tablename__ = 'boards'
|
||||
'''
|
||||
__table_args__ = (
|
||||
schema.UniqueConstraint('uuid', name='uniq_nodes0uuid'),
|
||||
schema.UniqueConstraint('instance_uuid',
|
||||
name='uniq_nodes0instance_uuid'),
|
||||
schema.UniqueConstraint('name', name='uniq_nodes0name'),
|
||||
table_args())
|
||||
'''
|
||||
id = Column(Integer, primary_key=True)
|
||||
uuid = Column(String(36))
|
||||
code = Column(String(25))
|
||||
status = Column(String(15), nullable=True)
|
||||
#reservation = Column(String(255), nullable=True)
|
||||
|
||||
|
|
|
@ -14,21 +14,18 @@
|
|||
|
||||
#from iotronic.objects import chassis
|
||||
from iotronic.objects import conductor
|
||||
#from iotronic.objects import node
|
||||
from iotronic.objects import board
|
||||
from iotronic.objects import node
|
||||
#from iotronic.objects import port
|
||||
|
||||
|
||||
#Chassis = chassis.Chassis
|
||||
Conductor = conductor.Conductor
|
||||
Board=board.Board
|
||||
#Node = node.Node
|
||||
Node = node.Node
|
||||
#Port = port.Port
|
||||
|
||||
__all__ = (
|
||||
#Chassis,
|
||||
Conductor,
|
||||
#Node,
|
||||
Board,
|
||||
Node,
|
||||
#Port
|
||||
)
|
||||
|
|
|
@ -22,7 +22,7 @@ from iotronic.objects import base
|
|||
from iotronic.objects import utils as obj_utils
|
||||
|
||||
|
||||
class Board(base.IotronicObject):
|
||||
class Node(base.IotronicObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
|
@ -37,75 +37,75 @@ class Board(base.IotronicObject):
|
|||
}
|
||||
|
||||
@staticmethod
|
||||
def _from_db_object(board, db_board):
|
||||
def _from_db_object(node, db_node):
|
||||
"""Converts a database entity to a formal object."""
|
||||
for field in board.fields:
|
||||
board[field] = db_board[field]
|
||||
board.obj_reset_changes()
|
||||
return board
|
||||
for field in node.fields:
|
||||
node[field] = db_node[field]
|
||||
node.obj_reset_changes()
|
||||
return node
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get(cls, context, board_id):
|
||||
"""Find a board based on its id or uuid and return a Board object.
|
||||
def get(cls, context, node_id):
|
||||
"""Find a node based on its id or uuid and return a Node object.
|
||||
|
||||
:param board_id: the id *or* uuid of a board.
|
||||
:returns: a :class:`Board` object.
|
||||
:param node_id: the id *or* uuid of a node.
|
||||
:returns: a :class:`Node` object.
|
||||
"""
|
||||
if strutils.is_int_like(board_id):
|
||||
return cls.get_by_id(context, board_id)
|
||||
elif uuidutils.is_uuid_like(board_id):
|
||||
return cls.get_by_uuid(context, board_id)
|
||||
if strutils.is_int_like(node_id):
|
||||
return cls.get_by_id(context, node_id)
|
||||
elif uuidutils.is_uuid_like(node_id):
|
||||
return cls.get_by_uuid(context, node_id)
|
||||
else:
|
||||
raise exception.InvalidIdentity(identity=board_id)
|
||||
raise exception.InvalidIdentity(identity=node_id)
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_id(cls, context, board_id):
|
||||
"""Find a board based on its integer id and return a Board object.
|
||||
def get_by_id(cls, context, node_id):
|
||||
"""Find a node based on its integer id and return a Node object.
|
||||
|
||||
:param board_id: the id of a board.
|
||||
:returns: a :class:`Board` object.
|
||||
:param node_id: the id of a node.
|
||||
:returns: a :class:`Node` object.
|
||||
"""
|
||||
db_board = cls.dbapi.get_board_by_id(board_id)
|
||||
board = Board._from_db_object(cls(context), db_board)
|
||||
return board
|
||||
db_node = cls.dbapi.get_node_by_id(node_id)
|
||||
node = Node._from_db_object(cls(context), db_node)
|
||||
return node
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_uuid(cls, context, uuid):
|
||||
"""Find a board based on uuid and return a Board object.
|
||||
"""Find a node based on uuid and return a Node object.
|
||||
|
||||
:param uuid: the uuid of a board.
|
||||
:returns: a :class:`Board` object.
|
||||
:param uuid: the uuid of a node.
|
||||
:returns: a :class:`Node` object.
|
||||
"""
|
||||
db_board = cls.dbapi.get_board_by_uuid(uuid)
|
||||
board = Board._from_db_object(cls(context), db_board)
|
||||
return board
|
||||
db_node = cls.dbapi.get_node_by_uuid(uuid)
|
||||
node = Node._from_db_object(cls(context), db_node)
|
||||
return node
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_code(cls, context, code):
|
||||
"""Find a board based on name and return a Board object.
|
||||
"""Find a node based on name and return a Node object.
|
||||
|
||||
:param name: the logical name of a board.
|
||||
:returns: a :class:`Board` object.
|
||||
:param name: the logical name of a node.
|
||||
:returns: a :class:`Node` object.
|
||||
"""
|
||||
db_board = cls.dbapi.get_board_by_code(code)
|
||||
board = Board._from_db_object(cls(context), db_board)
|
||||
return board
|
||||
db_node = cls.dbapi.get_node_by_code(code)
|
||||
node = Node._from_db_object(cls(context), db_node)
|
||||
return node
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_instance_uuid(cls, context, instance_uuid):
|
||||
"""Find a board based on the instance uuid and return a Board object.
|
||||
"""Find a node based on the instance uuid and return a Node object.
|
||||
|
||||
:param uuid: the uuid of the instance.
|
||||
:returns: a :class:`Board` object.
|
||||
:returns: a :class:`Node` object.
|
||||
"""
|
||||
db_board = cls.dbapi.get_board_by_instance(instance_uuid)
|
||||
board = Board._from_db_object(cls(context), db_board)
|
||||
return board
|
||||
db_node = cls.dbapi.get_node_by_instance(instance_uuid)
|
||||
node = Node._from_db_object(cls(context), db_node)
|
||||
return node
|
||||
|
||||
@base.remotable_classmethod
|
||||
def list(cls, context, limit=None, marker=None, sort_key=None,
|
||||
sort_dir=None, filters=None):
|
||||
"""Return a list of Board objects.
|
||||
"""Return a list of Node objects.
|
||||
|
||||
:param context: Security context.
|
||||
:param limit: maximum number of resources to return in a single result.
|
||||
|
@ -113,101 +113,101 @@ class Board(base.IotronicObject):
|
|||
:param sort_key: column to sort results by.
|
||||
:param sort_dir: direction to sort. "asc" or "desc".
|
||||
:param filters: Filters to apply.
|
||||
:returns: a list of :class:`Board` object.
|
||||
:returns: a list of :class:`Node` object.
|
||||
|
||||
"""
|
||||
db_boards = cls.dbapi.get_board_list(filters=filters, limit=limit,
|
||||
db_nodes = cls.dbapi.get_node_list(filters=filters, limit=limit,
|
||||
marker=marker, sort_key=sort_key,
|
||||
sort_dir=sort_dir)
|
||||
return [Board._from_db_object(cls(context), obj) for obj in db_boards]
|
||||
return [Node._from_db_object(cls(context), obj) for obj in db_nodes]
|
||||
|
||||
@base.remotable_classmethod
|
||||
def reserve(cls, context, tag, board_id):
|
||||
"""Get and reserve a board.
|
||||
def reserve(cls, context, tag, node_id):
|
||||
"""Get and reserve a node.
|
||||
|
||||
To prevent other ManagerServices from manipulating the given
|
||||
Board while a Task is performed, mark it reserved by this host.
|
||||
Node while a Task is performed, mark it reserved by this host.
|
||||
|
||||
:param context: Security context.
|
||||
:param tag: A string uniquely identifying the reservation holder.
|
||||
:param board_id: A board id or uuid.
|
||||
:raises: BoardNotFound if the board is not found.
|
||||
:returns: a :class:`Board` object.
|
||||
:param node_id: A node id or uuid.
|
||||
:raises: NodeNotFound if the node is not found.
|
||||
:returns: a :class:`Node` object.
|
||||
|
||||
"""
|
||||
db_board = cls.dbapi.reserve_board(tag, board_id)
|
||||
board = Board._from_db_object(cls(context), db_board)
|
||||
return board
|
||||
db_node = cls.dbapi.reserve_node(tag, node_id)
|
||||
node = Node._from_db_object(cls(context), db_node)
|
||||
return node
|
||||
|
||||
@base.remotable_classmethod
|
||||
def release(cls, context, tag, board_id):
|
||||
"""Release the reservation on a board.
|
||||
def release(cls, context, tag, node_id):
|
||||
"""Release the reservation on a node.
|
||||
|
||||
:param context: Security context.
|
||||
:param tag: A string uniquely identifying the reservation holder.
|
||||
:param board_id: A board id or uuid.
|
||||
:raises: BoardNotFound if the board is not found.
|
||||
:param node_id: A node id or uuid.
|
||||
:raises: NodeNotFound if the node is not found.
|
||||
|
||||
"""
|
||||
cls.dbapi.release_board(tag, board_id)
|
||||
cls.dbapi.release_node(tag, node_id)
|
||||
|
||||
@base.remotable
|
||||
def create(self, context=None):
|
||||
"""Create a Board record in the DB.
|
||||
"""Create a Node record in the DB.
|
||||
|
||||
Column-wise updates will be made based on the result of
|
||||
self.what_changed(). If target_power_state is provided,
|
||||
it will be checked against the in-database copy of the
|
||||
board before updates are made.
|
||||
node before updates are made.
|
||||
|
||||
:param context: Security context. NOTE: This should only
|
||||
be used internally by the indirection_api.
|
||||
Unfortunately, RPC requires context as the first
|
||||
argument, even though we don't use it.
|
||||
A context should be set when instantiating the
|
||||
object, e.g.: Board(context)
|
||||
object, e.g.: Node(context)
|
||||
|
||||
"""
|
||||
values = self.obj_get_changes()
|
||||
db_board = self.dbapi.create_board(values)
|
||||
self._from_db_object(self, db_board)
|
||||
db_node = self.dbapi.create_node(values)
|
||||
self._from_db_object(self, db_node)
|
||||
|
||||
@base.remotable
|
||||
def destroy(self, context=None):
|
||||
"""Delete the Board from the DB.
|
||||
"""Delete the Node from the DB.
|
||||
|
||||
:param context: Security context. NOTE: This should only
|
||||
be used internally by the indirection_api.
|
||||
Unfortunately, RPC requires context as the first
|
||||
argument, even though we don't use it.
|
||||
A context should be set when instantiating the
|
||||
object, e.g.: Board(context)
|
||||
object, e.g.: Node(context)
|
||||
"""
|
||||
self.dbapi.destroy_board(self.uuid)
|
||||
self.dbapi.destroy_node(self.uuid)
|
||||
self.obj_reset_changes()
|
||||
|
||||
@base.remotable
|
||||
def save(self, context=None):
|
||||
"""Save updates to this Board.
|
||||
"""Save updates to this Node.
|
||||
|
||||
Column-wise updates will be made based on the result of
|
||||
self.what_changed(). If target_power_state is provided,
|
||||
it will be checked against the in-database copy of the
|
||||
board before updates are made.
|
||||
node before updates are made.
|
||||
|
||||
:param context: Security context. NOTE: This should only
|
||||
be used internally by the indirection_api.
|
||||
Unfortunately, RPC requires context as the first
|
||||
argument, even though we don't use it.
|
||||
A context should be set when instantiating the
|
||||
object, e.g.: Board(context)
|
||||
object, e.g.: Node(context)
|
||||
"""
|
||||
updates = self.obj_get_changes()
|
||||
if 'driver' in updates and 'driver_internal_info' not in updates:
|
||||
# Clean driver_internal_info when changes driver
|
||||
self.driver_internal_info = {}
|
||||
updates = self.obj_get_changes()
|
||||
self.dbapi.update_board(self.uuid, updates)
|
||||
self.dbapi.update_node(self.uuid, updates)
|
||||
self.obj_reset_changes()
|
||||
|
||||
@base.remotable
|
||||
|
@ -219,7 +219,7 @@ class Board(base.IotronicObject):
|
|||
Unfortunately, RPC requires context as the first
|
||||
argument, even though we don't use it.
|
||||
A context should be set when instantiating the
|
||||
object, e.g.: Board(context)
|
||||
object, e.g.: Node(context)
|
||||
"""
|
||||
current = self.__class__.get_by_uuid(self._context, self.uuid)
|
||||
for field in self.fields:
|
|
@ -20,13 +20,13 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `iotronic` /*!40100 DEFAULT CHARACTER S
|
|||
USE `iotronic`;
|
||||
|
||||
--
|
||||
-- Table structure for table `boards`
|
||||
-- Table structure for table `nodes`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `boards`;
|
||||
DROP TABLE IF EXISTS `nodes`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `boards` (
|
||||
CREATE TABLE `nodes` (
|
||||
`created_at` datetime DEFAULT NULL,
|
||||
`updated_at` datetime DEFAULT NULL,
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
|
|
Loading…
Reference in New Issue