Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F3153041
fence_amt_ws.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
fence_amt_ws.py
View Options
#!@PYTHON@ -tt
#
# Fence agent for Intel AMT (WS) based on code from the openstack/ironic project:
# https://github.com/openstack/ironic/blob/master/ironic/drivers/modules/amt/power.py
#
# 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
sys
import
atexit
import
logging
sys
.
path
.
append
(
"@FENCEAGENTSLIBDIR@"
)
from
fencing
import
*
from
fencing
import
run_delay
,
fail_usage
,
fail
,
EC_STATUS
from
xml.etree
import
ElementTree
try
:
import
pywsman
except
ImportError
:
pass
POWER_ON
=
'2'
POWER_OFF
=
'8'
POWER_CYCLE
=
'10'
RET_SUCCESS
=
'0'
CIM_PowerManagementService
=
(
'http://schemas.dmtf.org/wbem/wscim/1/'
'cim-schema/2/CIM_PowerManagementService'
)
CIM_ComputerSystem
=
(
'http://schemas.dmtf.org/wbem/wscim/'
'1/cim-schema/2/CIM_ComputerSystem'
)
CIM_AssociatedPowerManagementService
=
(
'http://schemas.dmtf.org/wbem/wscim/'
'1/cim-schema/2/'
'CIM_AssociatedPowerManagementService'
)
CIM_BootConfigSetting
=
(
'http://schemas.dmtf.org/wbem/wscim/'
'1/cim-schema/2/CIM_BootConfigSetting'
)
CIM_BootSourceSetting
=
(
'http://schemas.dmtf.org/wbem/wscim/'
'1/cim-schema/2/CIM_BootSourceSetting'
)
def
xml_find
(
doc
,
namespace
,
item
):
if
doc
is
None
:
return
tree
=
ElementTree
.
fromstring
(
doc
.
root
()
.
string
())
query
=
(
'.//{
%(namespace)s
}
%(item)s
'
%
{
'namespace'
:
namespace
,
'item'
:
item
})
return
tree
.
find
(
query
)
def
_generate_power_action_input
(
action
):
method_input
=
"RequestPowerStateChange_INPUT"
address
=
'http://schemas.xmlsoap.org/ws/2004/08/addressing'
anonymous
=
(
'http://schemas.xmlsoap.org/ws/2004/08/addressing/'
'role/anonymous'
)
wsman
=
'http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd'
namespace
=
CIM_PowerManagementService
doc
=
pywsman
.
XmlDoc
(
method_input
)
root
=
doc
.
root
()
root
.
set_ns
(
namespace
)
root
.
add
(
namespace
,
'PowerState'
,
action
)
child
=
root
.
add
(
namespace
,
'ManagedElement'
,
None
)
child
.
add
(
address
,
'Address'
,
anonymous
)
grand_child
=
child
.
add
(
address
,
'ReferenceParameters'
,
None
)
grand_child
.
add
(
wsman
,
'ResourceURI'
,
CIM_ComputerSystem
)
g_grand_child
=
grand_child
.
add
(
wsman
,
'SelectorSet'
,
None
)
g_g_grand_child
=
g_grand_child
.
add
(
wsman
,
'Selector'
,
'ManagedSystem'
)
g_g_grand_child
.
attr_add
(
wsman
,
'Name'
,
'Name'
)
return
doc
def
get_power_status
(
_
,
options
):
client
=
pywsman
.
Client
(
options
[
"--ip"
],
int
(
options
[
"--ipport"
]),
\
'/wsman'
,
'http'
,
'admin'
,
options
[
"--password"
])
namespace
=
CIM_AssociatedPowerManagementService
client_options
=
pywsman
.
ClientOptions
()
doc
=
client
.
get
(
client_options
,
namespace
)
_SOAP_ENVELOPE
=
'http://www.w3.org/2003/05/soap-envelope'
item
=
'Fault'
fault
=
xml_find
(
doc
,
_SOAP_ENVELOPE
,
item
)
if
fault
is
not
None
:
logging
.
error
(
"Failed to get power state for:
%s
port:
%s
"
,
\
options
[
"--ip"
],
options
[
"--ipport"
])
fail
(
EC_STATUS
)
item
=
"PowerState"
try
:
power_state
=
xml_find
(
doc
,
namespace
,
item
)
.
text
except
AttributeError
:
logging
.
error
(
"Failed to get power state for:
%s
port:
%s
"
,
\
options
[
"--ip"
],
options
[
"--ipport"
])
fail
(
EC_STATUS
)
if
power_state
==
POWER_ON
:
return
"on"
elif
power_state
==
POWER_OFF
:
return
"off"
else
:
fail
(
EC_STATUS
)
def
set_power_status
(
_
,
options
):
client
=
pywsman
.
Client
(
options
[
"--ip"
],
int
(
options
[
"--ipport"
]),
\
'/wsman'
,
'http'
,
'admin'
,
options
[
"--password"
])
method
=
'RequestPowerStateChange'
client_options
=
pywsman
.
ClientOptions
()
client_options
.
add_selector
(
'Name'
,
'Intel(r) AMT Power Management Service'
)
if
options
[
"--action"
]
==
"on"
:
target_state
=
POWER_ON
elif
options
[
"--action"
]
==
"off"
:
target_state
=
POWER_OFF
elif
options
[
"--action"
]
==
"reboot"
:
target_state
=
POWER_CYCLE
if
options
[
"--action"
]
in
[
"on"
,
"off"
,
"reboot"
]
\
and
"--boot-option"
in
options
:
set_boot_order
(
_
,
client
,
options
)
doc
=
_generate_power_action_input
(
target_state
)
client_doc
=
client
.
invoke
(
client_options
,
CIM_PowerManagementService
,
\
method
,
doc
)
item
=
"ReturnValue"
return_value
=
xml_find
(
client_doc
,
CIM_PowerManagementService
,
item
)
.
text
if
return_value
!=
RET_SUCCESS
:
logging
.
error
(
"Failed to set power state:
%s
for:
%s
"
,
\
options
[
"--action"
],
options
[
"--ip"
])
fail
(
EC_STATUS
)
def
set_boot_order
(
_
,
client
,
options
):
method_input
=
"ChangeBootOrder_INPUT"
address
=
'http://schemas.xmlsoap.org/ws/2004/08/addressing'
anonymous
=
(
'http://schemas.xmlsoap.org/ws/2004/08/addressing/'
'role/anonymous'
)
wsman
=
'http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd'
namespace
=
CIM_BootConfigSetting
if
options
[
"--boot-option"
]
==
"pxe"
:
device
=
"Intel(r) AMT: Force PXE Boot"
elif
options
[
"--boot-option"
]
==
"hd"
or
"hdsafe"
:
device
=
"Intel(r) AMT: Force Hard-drive Boot"
elif
options
[
"--boot-option"
]
==
"cd"
:
device
=
"Intel(r) AMT: Force CD/DVD Boot"
elif
options
[
"--boot-option"
]
==
"diag"
:
device
=
"Intel(r) AMT: Force Diagnostic Boot"
else
:
logging
.
error
(
'Boot device:
%s
not supported.'
,
\
options
[
"--boot-option"
])
return
method
=
'ChangeBootOrder'
client_options
=
pywsman
.
ClientOptions
()
client_options
.
add_selector
(
'InstanceID'
,
\
'Intel(r) AMT: Boot Configuration 0'
)
doc
=
pywsman
.
XmlDoc
(
method_input
)
root
=
doc
.
root
()
root
.
set_ns
(
namespace
)
child
=
root
.
add
(
namespace
,
'Source'
,
None
)
child
.
add
(
address
,
'Address'
,
anonymous
)
grand_child
=
child
.
add
(
address
,
'ReferenceParameters'
,
None
)
grand_child
.
add
(
wsman
,
'ResourceURI'
,
CIM_BootSourceSetting
)
g_grand_child
=
grand_child
.
add
(
wsman
,
'SelectorSet'
,
None
)
g_g_grand_child
=
g_grand_child
.
add
(
wsman
,
'Selector'
,
device
)
g_g_grand_child
.
attr_add
(
wsman
,
'Name'
,
'InstanceID'
)
if
options
[
"--boot-option"
]
==
"hdsafe"
:
g_g_grand_child
=
g_grand_child
.
add
(
wsman
,
'Selector'
,
'True'
)
g_g_grand_child
.
attr_add
(
wsman
,
'Name'
,
'UseSafeMode'
)
client_doc
=
client
.
invoke
(
client_options
,
CIM_BootConfigSetting
,
\
method
,
doc
)
item
=
"ReturnValue"
return_value
=
xml_find
(
client_doc
,
CIM_BootConfigSetting
,
item
)
.
text
if
return_value
!=
RET_SUCCESS
:
logging
.
error
(
"Failed to set boot device to:
%s
for:
%s
"
,
\
options
[
"--boot-option"
],
options
[
"--ip"
])
fail
(
EC_STATUS
)
def
reboot_cycle
(
_
,
options
):
status
=
set_power_status
(
_
,
options
)
return
not
bool
(
status
)
def
define_new_opts
():
all_opt
[
"boot_option"
]
=
{
"getopt"
:
"b:"
,
"longopt"
:
"boot-option"
,
"help"
:
"-b, --boot-option=[option] "
"Change the default boot behavior of the
\n
"
" machine."
" (pxe|hd|hdsafe|cd|diag)"
,
"required"
:
"0"
,
"shortdesc"
:
"Change the default boot behavior of the machine."
,
"choices"
:
[
"pxe"
,
"hd"
,
"hdsafe"
,
"cd"
,
"diag"
],
"order"
:
1
}
def
main
():
atexit
.
register
(
atexit_handler
)
device_opt
=
[
"ipaddr"
,
"no_login"
,
"passwd"
,
"boot_option"
,
"no_port"
,
"method"
]
define_new_opts
()
all_opt
[
"ipport"
][
"default"
]
=
"16992"
options
=
check_input
(
device_opt
,
process_input
(
device_opt
))
docs
=
{}
docs
[
"shortdesc"
]
=
"Fence agent for AMT (WS)"
docs
[
"longdesc"
]
=
"fence_amt_ws is an I/O Fencing agent
\
which can be used with Intel AMT (WS). This agent requires
\
the pywsman Python library which is included in OpenWSMAN.
\
(http://openwsman.github.io/)."
docs
[
"vendorurl"
]
=
"http://www.intel.com/"
show_docs
(
options
,
docs
)
run_delay
(
options
)
result
=
fence_action
(
None
,
options
,
set_power_status
,
get_power_status
,
\
None
,
reboot_cycle
)
sys
.
exit
(
result
)
if
__name__
==
"__main__"
:
main
()
File Metadata
Details
Attached
Mime Type
text/x-script.python
Expires
Tue, Feb 25, 8:31 AM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1463297
Default Alt Text
fence_amt_ws.py (8 KB)
Attached To
Mode
rF Fence Agents
Attached
Detach File
Event Timeline
Log In to Comment