mirror of https://git.48k.eu/ogclient
src: add support for direct command execution
Update live shell run mode for the new REST API interface. Evaluate the "inline" field to diferentiate between execution of script in /opt/opengnsys/shell/ and a cmd execution. Remove usage of echo argument of the API REST. Update Windows and Linux mode for direct command execution. Set OutputEncoding environment variable to 'utf-8' in Windows to unify the encoding of stdout for the invoked programs. Decode stdout to utf-8-sig to remove potential BOM. While at this, remove strange legacy ;|\n\r terminator.master v1.3.2-25
parent
a36c4daa23
commit
e4be5c34eb
|
@ -7,9 +7,9 @@
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import shlex
|
||||||
import psutil
|
import psutil
|
||||||
import subprocess
|
import subprocess
|
||||||
from subprocess import CalledProcessError
|
|
||||||
from src.log import OgError
|
from src.log import OgError
|
||||||
|
|
||||||
from src.ogRest import ThreadState
|
from src.ogRest import ThreadState
|
||||||
|
@ -30,20 +30,22 @@ class OgLinuxOperations:
|
||||||
|
|
||||||
def shellrun(self, request, ogRest):
|
def shellrun(self, request, ogRest):
|
||||||
cmd = request.getrun()
|
cmd = request.getrun()
|
||||||
|
is_inline = request.get_inline()
|
||||||
|
|
||||||
|
if not is_inline:
|
||||||
|
raise OgError("Only inline mode is supported on Linux")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(cmd,
|
ogRest.proc = subprocess.Popen(
|
||||||
shell=True,
|
cmd,
|
||||||
stdin=subprocess.DEVNULL,
|
stdout=subprocess.PIPE,
|
||||||
capture_output=True,
|
shell=True)
|
||||||
text=True,
|
(output, error) = ogRest.proc.communicate()
|
||||||
check=True)
|
except (OSError, subprocess.SubprocessError) as e:
|
||||||
except CalledProcessError as error:
|
raise OgError(f'Error when running "shell run" subprocess: {e}') from e
|
||||||
if error.stderr:
|
|
||||||
return error.stderr
|
output = output.decode('utf-8-sig', errors='replace')
|
||||||
if error.stdout:
|
return (ogRest.proc.returncode, cmd, output)
|
||||||
return error.stdout
|
|
||||||
return "{Non zero exit code and empty output}"
|
|
||||||
return result.stdout
|
|
||||||
|
|
||||||
def session(self, request, ogRest):
|
def session(self, request, ogRest):
|
||||||
raise OgError('Function not implemented')
|
raise OgError('Function not implemented')
|
||||||
|
|
|
@ -38,8 +38,6 @@ from src.utils.hw_inventory import get_hardware_inventory, legacy_list_hardware_
|
||||||
from src.log import OgError
|
from src.log import OgError
|
||||||
|
|
||||||
|
|
||||||
OG_SHELL = '/bin/bash'
|
|
||||||
|
|
||||||
class OgLiveOperations:
|
class OgLiveOperations:
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self._url = config['opengnsys']['url']
|
self._url = config['opengnsys']['url']
|
||||||
|
@ -381,32 +379,38 @@ class OgLiveOperations:
|
||||||
|
|
||||||
def shellrun(self, request, ogRest):
|
def shellrun(self, request, ogRest):
|
||||||
cmd = request.getrun()
|
cmd = request.getrun()
|
||||||
cmds = cmd.split(";|\n\r")
|
is_inline = request.get_inline()
|
||||||
|
|
||||||
self._restartBrowser(self._url_log)
|
self._restartBrowser(self._url_log)
|
||||||
|
|
||||||
shell_path = '/opt/opengnsys/shell/'
|
if is_inline:
|
||||||
|
cmds = cmd
|
||||||
|
else:
|
||||||
|
cmds = shlex.split(cmd)
|
||||||
|
shell_path = '/opt/opengnsys/shell/'
|
||||||
|
|
||||||
restricted_mode = False
|
try:
|
||||||
|
shell_path_files = os.listdir(shell_path)
|
||||||
|
except OSError as e:
|
||||||
|
raise OgError(f'Error accessing {shell_path}: {e}') from e
|
||||||
|
|
||||||
for file_name in os.listdir(shell_path):
|
for file_name in shell_path_files:
|
||||||
file_path = os.path.join(shell_path, file_name)
|
file_path = os.path.join(shell_path, file_name)
|
||||||
|
|
||||||
if cmds[0] == file_name:
|
if cmds[0] == file_name:
|
||||||
cmds[0] = file_path
|
cmds[0] = file_path
|
||||||
restricted_mode = True
|
cmd = " ".join(cmds)
|
||||||
break
|
break
|
||||||
|
else:
|
||||||
|
raise OgError(f'Script {cmds[0]} not found in {shell_path}')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if restricted_mode:
|
ogRest.proc = subprocess.Popen(
|
||||||
ogRest.proc = subprocess.Popen(cmds, stdout=subprocess.PIPE)
|
cmds,
|
||||||
else:
|
stdout=subprocess.PIPE,
|
||||||
ogRest.proc = subprocess.Popen(cmds,
|
shell=is_inline)
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
shell=True,
|
|
||||||
executable=OG_SHELL)
|
|
||||||
(output, error) = ogRest.proc.communicate()
|
(output, error) = ogRest.proc.communicate()
|
||||||
except OSError as e:
|
except (OSError, subprocess.SubprocessError) as e:
|
||||||
raise OgError(f'Error when running "shell run" subprocess: {e}') from e
|
raise OgError(f'Error when running "shell run" subprocess: {e}') from e
|
||||||
|
|
||||||
if ogRest.proc.returncode != 0:
|
if ogRest.proc.returncode != 0:
|
||||||
|
@ -416,7 +420,8 @@ class OgLiveOperations:
|
||||||
|
|
||||||
self.refresh(ogRest)
|
self.refresh(ogRest)
|
||||||
|
|
||||||
return (ogRest.proc.returncode, " ".join(cmds), output.decode('utf-8'))
|
output = output.decode('utf-8-sig', errors='replace')
|
||||||
|
return (ogRest.proc.returncode, cmd, output)
|
||||||
|
|
||||||
def session(self, request, ogRest):
|
def session(self, request, ogRest):
|
||||||
disk = request.getDisk()
|
disk = request.getDisk()
|
||||||
|
|
|
@ -97,16 +97,12 @@ class ogThread():
|
||||||
ogRest.send_internal_server_error(client, exc=e)
|
ogRest.send_internal_server_error(client, exc=e)
|
||||||
return
|
return
|
||||||
|
|
||||||
if request.getEcho():
|
json_body = jsonBody()
|
||||||
json_body = jsonBody()
|
json_body.add_element('cmd', cmd)
|
||||||
json_body.add_element('cmd', cmd)
|
json_body.add_element('out', shellout)
|
||||||
json_body.add_element('out', shellout)
|
json_body.add_element('retcode', retcode)
|
||||||
json_body.add_element('retcode', retcode)
|
response = restResponse(ogResponses.OK, json_body, seq=client.seq)
|
||||||
response = restResponse(ogResponses.OK, json_body, seq=client.seq)
|
client.send(response.get())
|
||||||
client.send(response.get())
|
|
||||||
else:
|
|
||||||
response = restResponse(ogResponses.OK, seq=client.seq)
|
|
||||||
client.send(response.get())
|
|
||||||
|
|
||||||
ogRest.state = ThreadState.IDLE
|
ogRest.state = ThreadState.IDLE
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ class restRequest:
|
||||||
self.type = None
|
self.type = None
|
||||||
self.profile = None
|
self.profile = None
|
||||||
self.id = None
|
self.id = None
|
||||||
self.echo = None
|
self.inline = None
|
||||||
self.code = None
|
self.code = None
|
||||||
self.seq = None
|
self.seq = None
|
||||||
self.backup = None
|
self.backup = None
|
||||||
|
@ -72,7 +72,7 @@ class restRequest:
|
||||||
if "run" in json_param:
|
if "run" in json_param:
|
||||||
self.run = json_param["run"]
|
self.run = json_param["run"]
|
||||||
try:
|
try:
|
||||||
self.echo = json_param["echo"]
|
self.inline = json_param["inline"]
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -160,8 +160,8 @@ class restRequest:
|
||||||
def getId(self):
|
def getId(self):
|
||||||
return self.id
|
return self.id
|
||||||
|
|
||||||
def getEcho(self):
|
def get_inline(self):
|
||||||
return self.echo
|
return self.inline
|
||||||
|
|
||||||
def getCode(self):
|
def getCode(self):
|
||||||
return self.code
|
return self.code
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import locale
|
||||||
import ctypes
|
import ctypes
|
||||||
import psutil
|
import psutil
|
||||||
import subprocess
|
import subprocess
|
||||||
from subprocess import CalledProcessError
|
|
||||||
import multiprocessing as mp
|
import multiprocessing as mp
|
||||||
from multiprocessing import Process, freeze_support
|
from multiprocessing import Process, freeze_support
|
||||||
from src.log import OgError
|
from src.log import OgError
|
||||||
|
@ -84,20 +84,27 @@ class OgWindowsOperations:
|
||||||
|
|
||||||
def shellrun(self, request, ogRest):
|
def shellrun(self, request, ogRest):
|
||||||
cmd = request.getrun()
|
cmd = request.getrun()
|
||||||
|
is_inline = request.get_inline()
|
||||||
|
|
||||||
|
if not is_inline:
|
||||||
|
raise OgError("Only inline mode is supported on Windows")
|
||||||
|
|
||||||
|
env = os.environ.copy()
|
||||||
|
env['OutputEncoding'] = 'utf8'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(cmd,
|
ogRest.proc = subprocess.Popen(
|
||||||
shell=True,
|
cmd,
|
||||||
stdin=subprocess.DEVNULL,
|
stdout=subprocess.PIPE,
|
||||||
capture_output=True,
|
shell=True,
|
||||||
text=True,
|
env=env,
|
||||||
check=True)
|
)
|
||||||
except CalledProcessError as error:
|
output, error = ogRest.proc.communicate()
|
||||||
if error.stderr:
|
except (OSError, subprocess.SubprocessError) as e:
|
||||||
return error.stderr
|
raise OgError(f'Error when running "shell run" subprocess: {e}') from e
|
||||||
if error.stdout:
|
|
||||||
return error.stdout
|
output = output.decode('utf-8-sig', errors='replace')
|
||||||
return "{Non zero exit code and empty output}"
|
return (ogRest.proc.returncode, cmd, output)
|
||||||
return (result.returncode, cmd, result.stdout)
|
|
||||||
|
|
||||||
def session(self, request, ogRest):
|
def session(self, request, ogRest):
|
||||||
raise OgError('Function not implemented')
|
raise OgError('Function not implemented')
|
||||||
|
|
Loading…
Reference in New Issue