Feat(jobmgr): send START_SCRIPT webhook to mark trace as in_progress ; Fix(windows): prevent CLIXML output on errors by piping to Out-String
ogagent/pipeline/head This commit looks good
Details
ogagent/pipeline/head This commit looks good
Details
parent
d0bde04e92
commit
70f85b1fc7
|
|
@ -1 +1 @@
|
|||
8.5.6
|
||||
8.5.9
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
<item>
|
||||
<widget class="QLabel" name="VersionLabel">
|
||||
<property name="text">
|
||||
<string>Version 0</string>
|
||||
<string>Version 8.5.6</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
from . import modules
|
||||
from .RESTApi import REST, RESTError
|
||||
|
||||
VERSION='0'
|
||||
VERSION='8.5.6'
|
||||
|
||||
__title__ = 'OpenGnsys Agent'
|
||||
__version__ = VERSION
|
||||
|
|
|
|||
|
|
@ -53,6 +53,35 @@ class OpenGnSysWorker(ClientWorker):
|
|||
job_id = self.jobmgr.launch_job (script, True)
|
||||
self.sendServerMessage('script_launched', {'op': 'launched', 'job_id': job_id})
|
||||
|
||||
# Monitor the job in the background and notify the server when done
|
||||
def monitor_job():
|
||||
import time
|
||||
import threading
|
||||
|
||||
job = self.jobmgr.jobs.get(job_id)
|
||||
if not job:
|
||||
return
|
||||
|
||||
p = job.get('p')
|
||||
if not p:
|
||||
return
|
||||
|
||||
p.wait()
|
||||
# Wait for stdout/stderr threads to finish
|
||||
if job.get('t1'): job['t1'].join()
|
||||
if job.get('t2'): job['t2'].join()
|
||||
|
||||
logger.debug(f'Client job {job_id} finished, notifying server.')
|
||||
self.sendServerMessage('script_finished', {
|
||||
'job_id': job_id,
|
||||
'rc': p.returncode,
|
||||
'stderr': job.get('stderr', ''),
|
||||
'stdout': job.get('stdout', '')
|
||||
})
|
||||
|
||||
import threading
|
||||
threading.Thread(target=monitor_job, daemon=True).start()
|
||||
|
||||
def process_terminatescript(self, json_params):
|
||||
job_id = json_params['job_id']
|
||||
logger.debug('Processing terminatescript request, job_id "{}"'.format (job_id))
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ class OpenGnSysWorker(ServerWorker):
|
|||
exec_level = None # Execution level (permitted operations)
|
||||
jobmgr = JobMgr()
|
||||
_registered = False # Whether ogcore has acknowledged our ogagent/started
|
||||
client_jobs = set() # Track active client job IDs for busy status
|
||||
|
||||
def _send_started(self):
|
||||
"""Send ogagent/started to ogcore and mark as registered on success."""
|
||||
|
|
@ -136,11 +137,14 @@ class OpenGnSysWorker(ServerWorker):
|
|||
elem['status'] = 'finished'
|
||||
elem['rc'] = elem['p'].returncode
|
||||
|
||||
stdout = elem.get('stdout', '')
|
||||
stderr = elem.get('stderr', '')
|
||||
der = stdout + ('\n' if stdout and stderr else '') + stderr
|
||||
webhook_body = {
|
||||
"nfn": "RUN_SCRIPT",
|
||||
"nfn": "RESPUESTA_EjecutarScript",
|
||||
"job_id": k,
|
||||
"res": 1 if elem['rc'] == 0 else 0,
|
||||
"der": elem.get('stderr', '')
|
||||
"der": der
|
||||
}
|
||||
logger.info(f"Job {k} finished with return code {elem['rc']}. Sending webhook to ogcore.")
|
||||
try:
|
||||
|
|
@ -150,11 +154,13 @@ class OpenGnSysWorker(ServerWorker):
|
|||
|
||||
if not n % 10:
|
||||
_st_map = {'linux': 'LNX', 'macos': 'OSX', 'windows': 'WIN'}
|
||||
is_busy = any(j['p'].poll() is None for j in self.jobmgr.jobs.values()) or len(self.client_jobs) > 0
|
||||
body = {
|
||||
"iph": self.interface.ip,
|
||||
"timestamp": int(time.time()),
|
||||
"busy": any(j['p'].poll() is None for j in self.jobmgr.jobs.values()),
|
||||
"busy": is_busy,
|
||||
"st": _st_map.get(operations.os_type.lower(), 'UNK'),
|
||||
"loggedin": len(self.user) > 0,
|
||||
}
|
||||
result = self.REST.sendMessage('clients/status/webhook', body)
|
||||
if result is None:
|
||||
|
|
@ -466,6 +472,13 @@ class OpenGnSysWorker(ServerWorker):
|
|||
|
||||
if post_params.get('client', 'false') == 'false':
|
||||
job_id = self.jobmgr.launch_job (script, False)
|
||||
try:
|
||||
self.REST.sendMessage('clients/status/webhook', {
|
||||
"nfn": "START_SCRIPT",
|
||||
"job_id": job_id
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to send START_SCRIPT webhook for job {job_id}: {e}")
|
||||
return {'op': 'launched', 'job_id': job_id}
|
||||
|
||||
else: ## post_params.get('client') is not 'false'
|
||||
|
|
@ -497,8 +510,33 @@ class OpenGnSysWorker(ServerWorker):
|
|||
job_id_path = os.path.join(tempfile.gettempdir(), 'EjecutarScript-jobid')
|
||||
with open (job_id_path, 'w') as fd:
|
||||
fd.write (data['job_id'])
|
||||
self.client_jobs.add(data['job_id'])
|
||||
return True
|
||||
|
||||
def process_client_script_finished(self, data):
|
||||
job_id = data['job_id']
|
||||
rc = data['rc']
|
||||
stdout = data.get('stdout', '')
|
||||
stderr = data.get('stderr', '')
|
||||
der = stdout + ('\n' if stdout and stderr else '') + stderr
|
||||
|
||||
if job_id in self.client_jobs:
|
||||
self.client_jobs.remove(job_id)
|
||||
|
||||
logger.info(f"Client job {job_id} finished with return code {rc}. Sending webhook to ogcore.")
|
||||
webhook_body = {
|
||||
"nfn": "RESPUESTA_EjecutarScript",
|
||||
"job_id": job_id,
|
||||
"res": 1 if rc == 0 else 0,
|
||||
"der": der
|
||||
}
|
||||
try:
|
||||
self.REST.sendMessage('clients/status/webhook', webhook_body)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to send webhook for client job {job_id}: {e}")
|
||||
return True
|
||||
|
||||
|
||||
@execution_level('full')
|
||||
@check_secret
|
||||
def process_terminatescript(self, path, get_params, post_params, server):
|
||||
|
|
|
|||
|
|
@ -151,6 +151,8 @@ def get_etc_path():
|
|||
|
||||
def build_popen_args(script):
|
||||
## turn the script into utf16le, then to b64 again, and feed the blob to powershell
|
||||
## wrap the script to redirect stderr and output as a simple string to avoid CLIXML wrappers in non-interactive errors
|
||||
script = f"& {{ {script} }} 2>&1 | Out-String"
|
||||
u16 = script.encode ('utf-16le') ## utf16
|
||||
b64 = base64.b64encode (u16).decode ('utf-8') ## b64 (which returns bytes, so we need an additional decode(utf8))
|
||||
return ['powershell', '-WindowStyle', 'Hidden', '-EncodedCommand', b64]
|
||||
|
|
|
|||
Loading…
Reference in New Issue