Commit e4d745a7 authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

Add opcode for running commands remotely



The opcode doesn't pay attention to the build-time flag to enable or
disable restricted commands. In a cluster different nodes could have
different settings.

Node locks are acquired in shared mode by default, but the use of an
exclusive lock can be forced using the “use_locking” parameter.
Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent db2203e0
......@@ -15007,6 +15007,53 @@ class LUTestDelay(NoHooksLU):
self._TestDelay()
 
 
class LURestrictedCommand(NoHooksLU):
"""Logical unit for executing restricted commands.
"""
REQ_BGL = False
def ExpandNames(self):
if self.op.nodes:
self.op.nodes = _GetWantedNodes(self, self.op.nodes)
self.needed_locks = {
locking.LEVEL_NODE: self.op.nodes,
}
self.share_locks = {
locking.LEVEL_NODE: not self.op.use_locking,
}
def CheckPrereq(self):
"""Check prerequisites.
"""
def Exec(self, feedback_fn):
"""Execute restricted command and return output.
"""
owned_nodes = frozenset(self.owned_locks(locking.LEVEL_NODE))
# Check if correct locks are held
assert set(self.op.nodes).issubset(owned_nodes)
rpcres = self.rpc.call_restricted_command(self.op.nodes, self.op.command)
result = []
for node_name in self.op.nodes:
nres = rpcres[node_name]
if nres.fail_msg:
msg = ("Command '%s' on node '%s' failed: %s" %
(self.op.command, node_name, nres.fail_msg))
result.append((False, msg))
else:
result.append((True, nres.payload))
return result
class LUTestJqueue(NoHooksLU):
"""Utility LU to test some aspects of the job queue.
 
......
......@@ -947,6 +947,28 @@ class OpOobCommand(OpCode):
OP_RESULT = _TQueryResult
class OpRestrictedCommand(OpCode):
"""Runs a restricted command on node(s).
"""
OP_PARAMS = [
_PUseLocking,
("nodes", ht.NoDefault, ht.TListOf(ht.TNonEmptyString),
"Nodes on which the command should be run (at least one)"),
("command", ht.NoDefault, ht.TNonEmptyString,
"Command name (no parameters)"),
]
_RESULT_ITEMS = [
ht.Comment("success")(ht.TBool),
ht.Comment("output or error message")(ht.TString),
]
OP_RESULT = \
ht.TListOf(ht.TAnd(ht.TIsLength(len(_RESULT_ITEMS)),
ht.TItems(_RESULT_ITEMS)))
# node opcodes
class OpNodeRemove(OpCode):
......
......@@ -66,6 +66,9 @@ RAPI_OPCODE_EXCLUDE = frozenset([
opcodes.OpNodeAdd,
opcodes.OpNodeRemove,
# Very sensitive in nature
opcodes.OpRestrictedCommand,
# Helper opcodes (e.g. submitted by LUs)
opcodes.OpClusterVerifyConfig,
opcodes.OpClusterVerifyGroup,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment