Fixed ignore_output for run_command

This commit is contained in:
Josiah Baldwin
2026-02-18 15:28:50 -08:00
parent 5975e145a7
commit 6290bc7298

View File

@@ -1501,7 +1501,7 @@ class Session(object):
if (f"node//{nid}" == id): if (f"node//{nid}" == id):
return nid return nid
result = None result = {n: {"complete": False, "result": [], "command": command} for n in nodeids}
console_result = {n: {"complete": False, "result": [], "command": command} for n in nodeids} console_result = {n: {"complete": False, "result": [], "command": command} for n in nodeids}
reply_result = {n: {"complete": False, "result": [], "command": command} for n in nodeids} reply_result = {n: {"complete": False, "result": [], "command": command} for n in nodeids}
async def _console(): async def _console():
@@ -1536,23 +1536,25 @@ class Session(object):
async def __(command, tg, tasks): async def __(command, tg, tasks):
nonlocal result nonlocal result
responseid = self._generate_response_id("run_command") responseid = self._generate_response_id("run_command")
if not ignore_output: if not ignore_output:
reply_task = tg.create_task(asyncio.wait_for(_reply(responseid), timeout=timeout)) reply_task = tg.create_task(asyncio.wait_for(_reply(responseid), timeout=timeout))
# We still need to parse the console results because it sends them without namespace, this will likely break older versions of meshcentral
console_task = tg.create_task(asyncio.wait_for(_console(), timeout=timeout)) console_task = tg.create_task(asyncio.wait_for(_console(), timeout=timeout))
data = await self._send_command(command, "run_command", timeout=timeout, responseid=responseid) data = await self._send_command(command, "run_command", timeout=timeout, responseid=responseid)
if data.get("type", None) != "runcommands" and data.get("result", "ok").lower() != "ok": if data.get("type", None) != "runcommands" and data.get("result", "ok").lower() != "ok":
raise exceptions.ServerError(data["result"]) raise exceptions.ServerError(data["result"])
elif data.get("type", None) != "runcommands" and data.get("result", "ok").lower() == "ok": elif data.get("type", None) != "runcommands" and data.get("result", "ok").lower() == "ok":
reply_task.cancel()
result = console_result
expect_response = False expect_response = False
if not ignore_output: if not ignore_output:
reply_task.cancel()
result = console_result
userid = (await self.user_info())["_id"] userid = (await self.user_info())["_id"]
for n in nodeids: for n in nodeids:
device_info = await self.device_info(n, timeout=timeout) device_info = await self.device_info(n, timeout=timeout)
try: try:
permissions = device_info.mesh.links.get(userid, {}).get("rights",constants.DeviceRights.norights)\ permissions = device_info.mesh.links.get(userid, {}).get("rights",constants.DeviceRights.norights)
# This should work for device rights, but it only seems to work for mesh rights. Not sure why, but I can't get the events to show up when the user only has individual device rights # This should work for device rights, but it only seems to work for mesh rights. Not sure why, but I can't get the events to show up when the user only has individual device rights
# |device_info.get("links", {}).get(userid, {}).get("rights", constants.DeviceRights.norights) # |device_info.get("links", {}).get(userid, {}).get("rights", constants.DeviceRights.norights)
# If we don't have agentconsole rights, we won't be able te read the output, so fill in blanks on this node # If we don't have agentconsole rights, we won't be able te read the output, so fill in blanks on this node
@@ -1566,19 +1568,20 @@ class Session(object):
tasks.append(console_task) tasks.append(console_task)
else: else:
console_task.cancel() console_task.cancel()
elif data.get("type", None) == "runcommands" and not ignore_output: elif data.get("type", None) == "runcommands":
result = reply_result
console_task.cancel() console_task.cancel()
if not ignore_output:
result = reply_result
tasks.append(reply_task) tasks.append(reply_task)
else: else:
if not ignore_output: # if not ignore_output:
console_task.cancel() console_task.cancel()
reply_task.cancel() reply_task.cancel()
raise exceptions.ServerError(f"Unrecognized response: {data}") raise exceptions.ServerError(f"Unrecognized response: {data}")
tasks = [] tasks = []
async with asyncio.TaskGroup() as tg: async with asyncio.TaskGroup() as tg:
tasks.append(tg.create_task(__({ "action": 'runcommands', "nodeids": nodeids, "type": (2 if powershell else 0), "cmds": command, "runAsUser": runAsUser, "reply": not ignore_output}, tg, tasks))) tasks.append(tg.create_task(__({ "action": 'runcommands', "nodeids": nodeids, "type": (2 if powershell else 0), "cmds": command, "runAsUser": runAsUser, "reply": True}, tg, tasks)))
return {n: v | {"result": "".join(v["result"])} for n,v in result.items()} return {n: v | {"result": "".join(v["result"])} for n,v in result.items()}