19
19
Provides vendor passthru methods for SeaMicro specific functionality.
22
24
from oslo.config import cfg
23
25
from oslo.utils import importutils
26
from six.moves.urllib import parse as urlparse
25
28
from ironic.common import boot_devices
26
29
from ironic.common import exception
30
33
from ironic.common import states
31
34
from ironic.conductor import task_manager
32
35
from ironic.drivers import base
36
from ironic.drivers.modules import console_utils
33
37
from ironic.openstack.common import log as logging
34
38
from ironic.openstack.common import loopingcall
101
108
:param node: An Ironic node object.
102
109
:returns: SeaMicro driver info.
103
110
:raises: MissingParameterValue if any required parameters are missing.
111
:raises: InvalidParameterValue if required parameter are invalid.
106
114
info = node.driver_info or {}
107
115
missing_info = [key for key in REQUIRED_PROPERTIES if not info.get(key)]
109
117
raise exception.MissingParameterValue(_(
110
"SeaMicro driver requires the following to be set: %s.")
118
"SeaMicro driver requires the following parameters to be set in"
119
" node's driver_info: %s.") % missing_info)
113
121
api_endpoint = info.get('seamicro_api_endpoint')
114
122
username = info.get('seamicro_username')
115
123
password = info.get('seamicro_password')
116
124
server_id = info.get('seamicro_server_id')
117
125
api_version = info.get('seamicro_api_version', "2")
126
port = info.get('seamicro_terminal_port')
132
raise exception.InvalidParameterValue(_(
133
"SeaMicro terminal port is not an integer."))
135
r = re.compile(r"(^[0-9]+)/([0-9]+$)")
136
if not r.match(server_id):
137
raise exception.InvalidParameterValue(_(
138
"Invalid 'seamicro_server_id' parameter in node's "
139
"driver_info. Expected format of 'seamicro_server_id' "
142
url = urlparse.urlparse(api_endpoint)
143
if (not (url.scheme == "http") or not url.netloc):
144
raise exception.InvalidParameterValue(_(
145
"Invalid 'seamicro_api_endpoint' parameter in node's "
119
148
res = {'username': username,
120
149
'password': password,
121
150
'api_endpoint': api_endpoint,
122
151
'server_id': server_id,
123
152
'api_version': api_version,
364
def get_telnet_port(driver_info):
365
"""Get SeaMicro telnet port to listen."""
366
server_id = int(driver_info['server_id'].split("/")[0])
367
return PORT_BASE + (10 * server_id)
333
370
class Power(base.PowerInterface):
334
371
"""SeaMicro Power Interface.
415
452
return COMMON_PROPERTIES
417
454
def validate(self, task, **kwargs):
418
method = kwargs['method']
419
if method not in VENDOR_PASSTHRU_METHODS:
420
raise exception.InvalidParameterValue(_(
421
"Unsupported method (%s) passed to SeaMicro driver.")
423
455
_parse_driver_info(task.node)
425
def vendor_passthru(self, task, **kwargs):
426
"""Dispatch vendor specific method calls."""
427
method = kwargs['method']
428
if method in VENDOR_PASSTHRU_METHODS:
429
return getattr(self, "_" + method)(task, **kwargs)
431
def _set_node_vlan_id(self, task, **kwargs):
457
@base.passthru(['POST'])
458
def set_node_vlan_id(self, task, **kwargs):
432
459
"""Sets a untagged vlan id for NIC 0 of node.
434
461
@kwargs vlan_id: id of untagged vlan for NIC 0 of node
456
483
node.properties = properties
459
def _attach_volume(self, task, **kwargs):
460
"""Attach volume from SeaMicro storage pools for ironic to node.
461
If kwargs['volume_id'] not given, Create volume in SeaMicro
462
storage pool and attach to node.
486
@base.passthru(['POST'])
487
def attach_volume(self, task, **kwargs):
488
"""Attach a volume to a node.
490
Attach volume from SeaMicro storage pools for ironic to node.
491
If kwargs['volume_id'] not given, Create volume in SeaMicro
492
storage pool and attach to node.
464
494
@kwargs volume_id: id of pre-provisioned volume that is to be attached
465
495
as root volume of node
582
612
raise NotImplementedError()
615
class ShellinaboxConsole(base.ConsoleInterface):
616
"""A ConsoleInterface that uses telnet and shellinabox."""
618
def get_properties(self):
619
d = COMMON_PROPERTIES.copy()
620
d.update(CONSOLE_PROPERTIES)
623
def validate(self, task):
624
"""Validate the Node console info.
626
:param task: a task from TaskManager.
627
:raises: MissingParameterValue if required seamicro parameters are
629
:raises: InvalidParameterValue if required parameter are invalid.
631
driver_info = _parse_driver_info(task.node)
632
if not driver_info['port']:
633
raise exception.MissingParameterValue(_(
634
"Missing 'seamicro_terminal_port' parameter in node's "
637
def start_console(self, task):
638
"""Start a remote console for the node.
640
:param task: a task from TaskManager
641
:raises: MissingParameterValue if required seamicro parameters are
643
:raises: ConsoleError if the directory for the PID file cannot be
645
:raises: ConsoleSubprocessFailed when invoking the subprocess failed
646
:raises: InvalidParameterValue if required parameter are invalid.
649
driver_info = _parse_driver_info(task.node)
650
telnet_port = get_telnet_port(driver_info)
651
chassis_ip = urlparse.urlparse(driver_info['api_endpoint']).netloc
653
seamicro_cmd = ("/:%(uid)s:%(gid)s:HOME:telnet %(chassis)s %(port)s"
654
% {'uid': os.getuid(),
656
'chassis': chassis_ip,
657
'port': telnet_port})
659
console_utils.start_shellinabox_console(driver_info['uuid'],
663
def stop_console(self, task):
664
"""Stop the remote console session for the node.
666
:param task: a task from TaskManager
667
:raises: MissingParameterValue if required seamicro parameters are
669
:raises: ConsoleError if unable to stop the console
670
:raises: InvalidParameterValue if required parameter are invalid.
673
driver_info = _parse_driver_info(task.node)
674
console_utils.stop_shellinabox_console(driver_info['uuid'])
676
def get_console(self, task):
677
"""Get the type and connection information about the console.
679
:raises: MissingParameterValue if required seamicro parameters are
681
:raises: InvalidParameterValue if required parameter are invalid.
684
driver_info = _parse_driver_info(task.node)
685
url = console_utils.get_shellinabox_console_url(driver_info['port'])
686
return {'type': 'shellinabox', 'url': url}