mirror of
https://github.com/xcat2/confluent.git
synced 2024-11-25 19:10:10 +00:00
Confluent server side enclosure reseat
This provides ability to request reseat of nodes, and redirects it to the enclosure manager.
This commit is contained in:
parent
c86d9f3e33
commit
52673a990b
@ -185,6 +185,11 @@ def _init_core():
|
||||
'handler': 'ssh',
|
||||
}),
|
||||
},
|
||||
'_enclosure': {
|
||||
'reseat_bay': PluginRoute(
|
||||
{'pluginattrs': ['hardwaremanagement.method'],
|
||||
'default': 'ipmi'}),
|
||||
},
|
||||
'shell': {
|
||||
# another special case similar to console
|
||||
'sessions': PluginCollection({
|
||||
@ -250,6 +255,7 @@ def _init_core():
|
||||
'pluginattrs': ['hardwaremanagement.method'],
|
||||
'default': 'ipmi',
|
||||
}),
|
||||
'reseat': PluginRoute({'handler': 'enclosure'}),
|
||||
},
|
||||
'sensors': {
|
||||
'hardware': {
|
||||
|
@ -364,6 +364,9 @@ class ChildCollection(LinkRelation):
|
||||
def get_input_message(path, operation, inputdata, nodes=None, multinode=False):
|
||||
if path[0] == 'power' and path[1] == 'state' and operation != 'retrieve':
|
||||
return InputPowerMessage(path, nodes, inputdata)
|
||||
elif (path in (['power', 'reseat'], ['_enclosure', 'reseat_bay']) and
|
||||
operation != 'retrieve'):
|
||||
return InputReseatMessage(path, nodes, inputdata)
|
||||
elif path == ['attributes', 'expression']:
|
||||
return InputExpression(path, inputdata, nodes)
|
||||
elif path[0] in ('attributes', 'users') and operation != 'retrieve':
|
||||
@ -624,7 +627,7 @@ class ConfluentInputMessage(ConfluentMessage):
|
||||
if self.keyname not in datum:
|
||||
raise exc.InvalidArgumentException(
|
||||
'missing {0} argument'.format(self.keyname))
|
||||
elif datum[self.keyname] not in self.valid_values:
|
||||
elif not self.is_valid_key(datum[self.keyname]):
|
||||
raise exc.InvalidArgumentException(
|
||||
datum[self.keyname] + ' is not one of ' +
|
||||
','.join(self.valid_values))
|
||||
@ -634,13 +637,15 @@ class ConfluentInputMessage(ConfluentMessage):
|
||||
if self.keyname not in datum:
|
||||
raise exc.InvalidArgumentException(
|
||||
'missing {0} argument'.format(self.keyname))
|
||||
elif datum[self.keyname] not in self.valid_values:
|
||||
elif not self.is_valid_key(datum[self.keyname]):
|
||||
raise exc.InvalidArgumentException(datum[self.keyname] +
|
||||
' is not one of ' +
|
||||
','.join(self.valid_values))
|
||||
for node in nodes:
|
||||
self.inputbynode[node] = datum[self.keyname]
|
||||
|
||||
def is_valid_key(self, key):
|
||||
return key in self.valid_values
|
||||
|
||||
class InputIdentifyMessage(ConfluentInputMessage):
|
||||
valid_values = set([
|
||||
@ -664,6 +669,16 @@ class InputPowerMessage(ConfluentInputMessage):
|
||||
def powerstate(self, node):
|
||||
return self.inputbynode[node]
|
||||
|
||||
class InputReseatMessage(ConfluentInputMessage):
|
||||
valid_values = set([
|
||||
'reseat',
|
||||
])
|
||||
|
||||
keyname = 'reseat'
|
||||
|
||||
def is_valid_key(self, key):
|
||||
return key in self.valid_values or isinstance(key, int)
|
||||
|
||||
|
||||
class InputBMCReset(ConfluentInputMessage):
|
||||
valid_values = set([
|
||||
@ -875,6 +890,13 @@ class IdentifyState(ConfluentChoiceMessage):
|
||||
keyname = 'identify'
|
||||
|
||||
|
||||
class ReseatResult(ConfluentChoiceMessage):
|
||||
valid_values = set([
|
||||
'success',
|
||||
])
|
||||
keyname = 'reseat'
|
||||
|
||||
|
||||
class PowerState(ConfluentChoiceMessage):
|
||||
valid_values = set([
|
||||
'on',
|
||||
|
@ -0,0 +1,26 @@
|
||||
# Copyright 2017 Lenovo
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import confluent.core as core
|
||||
|
||||
def update(nodes, element, configmanager, inputdata):
|
||||
emebs = configmanager.get_node_attributes(
|
||||
nodes, (u'enclosure.manager', u'enclosure.bay'))
|
||||
for node in nodes:
|
||||
em = emebs[node]['enclosure.manager']['value']
|
||||
eb = emebs[node]['enclosure.bay']['value']
|
||||
for rsp in core.handle_path(
|
||||
'/nodes/{0}/_enclosure/reseat_bay'.format(em),
|
||||
'update', configmanager,
|
||||
inputdata={'reseat': int(eb)}):
|
||||
yield rsp
|
@ -432,6 +432,8 @@ class IpmiHandler(object):
|
||||
raise Exception(self.error)
|
||||
if self.element == ['power', 'state']:
|
||||
self.power()
|
||||
elif self.element == ['_enclosure', 'reseat_bay']:
|
||||
self.reseat_bay()
|
||||
elif self.element == ['boot', 'nextdevice']:
|
||||
self.bootdevice()
|
||||
elif self.element == ['health', 'hardware']:
|
||||
@ -820,6 +822,11 @@ class IpmiHandler(object):
|
||||
else:
|
||||
raise exc.InvalidArgumentException('health is read-only')
|
||||
|
||||
def reseat_bay(self):
|
||||
bay = self.inputdata.inputbynode[self.node]
|
||||
self.ipmicmd.reseat_bay(bay)
|
||||
self.output.put(msg.ReseatResult(self.node, 'success'))
|
||||
|
||||
def bootdevice(self):
|
||||
if 'read' == self.op:
|
||||
bootdev = self.ipmicmd.get_bootdev()
|
||||
|
Loading…
Reference in New Issue
Block a user