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.
|
||||
|
||||
import os
|
||||
import shlex
|
||||
import psutil
|
||||
import subprocess
|
||||
from subprocess import CalledProcessError
|
||||
from src.log import OgError
|
||||
|
||||
from src.ogRest import ThreadState
|
||||
|
@ -30,20 +30,22 @@ class OgLinuxOperations:
|
|||
|
||||
def shellrun(self, request, ogRest):
|
||||
cmd = request.getrun()
|
||||
is_inline = request.get_inline()
|
||||
|
||||
if not is_inline:
|
||||
raise OgError("Only inline mode is supported on Linux")
|
||||
|
||||
try:
|
||||
result = subprocess.run(cmd,
|
||||
shell=True,
|
||||
stdin=subprocess.DEVNULL,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True)
|
||||
except CalledProcessError as error:
|
||||
if error.stderr:
|
||||
return error.stderr
|
||||
if error.stdout:
|
||||
return error.stdout
|
||||
return "{Non zero exit code and empty output}"
|
||||
return result.stdout
|
||||
ogRest.proc = subprocess.Popen(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
shell=True)
|
||||
(output, error) = ogRest.proc.communicate()
|
||||
except (OSError, subprocess.SubprocessError) as e:
|
||||
raise OgError(f'Error when running "shell run" subprocess: {e}') from e
|
||||
|
||||
output = output.decode('utf-8-sig', errors='replace')
|
||||
return (ogRest.proc.returncode, cmd, output)
|
||||
|
||||
def session(self, request, ogRest):
|
||||
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
|
||||
|
||||
|
||||
OG_SHELL = '/bin/bash'
|
||||
|
||||
class OgLiveOperations:
|
||||
def __init__(self, config):
|
||||
self._url = config['opengnsys']['url']
|
||||
|
@ -381,32 +379,38 @@ class OgLiveOperations:
|
|||
|
||||
def shellrun(self, request, ogRest):
|
||||
cmd = request.getrun()
|
||||
cmds = cmd.split(";|\n\r")
|
||||
is_inline = request.get_inline()
|
||||
|
||||
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):
|
||||
file_path = os.path.join(shell_path, file_name)
|
||||
for file_name in shell_path_files:
|
||||
file_path = os.path.join(shell_path, file_name)
|
||||
|
||||
if cmds[0] == file_name:
|
||||
cmds[0] = file_path
|
||||
restricted_mode = True
|
||||
break
|
||||
if cmds[0] == file_name:
|
||||
cmds[0] = file_path
|
||||
cmd = " ".join(cmds)
|
||||
break
|
||||
else:
|
||||
raise OgError(f'Script {cmds[0]} not found in {shell_path}')
|
||||
|
||||
try:
|
||||
if restricted_mode:
|
||||
ogRest.proc = subprocess.Popen(cmds, stdout=subprocess.PIPE)
|
||||
else:
|
||||
ogRest.proc = subprocess.Popen(cmds,
|
||||
stdout=subprocess.PIPE,
|
||||
shell=True,
|
||||
executable=OG_SHELL)
|
||||
ogRest.proc = subprocess.Popen(
|
||||
cmds,
|
||||
stdout=subprocess.PIPE,
|
||||
shell=is_inline)
|
||||
(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
|
||||
|
||||
if ogRest.proc.returncode != 0:
|
||||
|
@ -416,7 +420,8 @@ class OgLiveOperations:
|
|||
|
||||
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):
|
||||
disk = request.getDisk()
|
||||
|
|
|
@ -97,16 +97,12 @@ class ogThread():
|
|||
ogRest.send_internal_server_error(client, exc=e)
|
||||
return
|
||||
|
||||
if request.getEcho():
|
||||
json_body = jsonBody()
|
||||
json_body.add_element('cmd', cmd)
|
||||
json_body.add_element('out', shellout)
|
||||
json_body.add_element('retcode', retcode)
|
||||
response = restResponse(ogResponses.OK, json_body, seq=client.seq)
|
||||
client.send(response.get())
|
||||
else:
|
||||
response = restResponse(ogResponses.OK, seq=client.seq)
|
||||
client.send(response.get())
|
||||
json_body = jsonBody()
|
||||
json_body.add_element('cmd', cmd)
|
||||
json_body.add_element('out', shellout)
|
||||
json_body.add_element('retcode', retcode)
|
||||
response = restResponse(ogResponses.OK, json_body, seq=client.seq)
|
||||
client.send(response.get())
|
||||
|
||||
ogRest.state = ThreadState.IDLE
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ class restRequest:
|
|||
self.type = None
|
||||
self.profile = None
|
||||
self.id = None
|
||||
self.echo = None
|
||||
self.inline = None
|
||||
self.code = None
|
||||
self.seq = None
|
||||
self.backup = None
|
||||
|
@ -72,7 +72,7 @@ class restRequest:
|
|||
if "run" in json_param:
|
||||
self.run = json_param["run"]
|
||||
try:
|
||||
self.echo = json_param["echo"]
|
||||
self.inline = json_param["inline"]
|
||||
except:
|
||||
pass
|
||||
|
||||
|
@ -160,8 +160,8 @@ class restRequest:
|
|||
def getId(self):
|
||||
return self.id
|
||||
|
||||
def getEcho(self):
|
||||
return self.echo
|
||||
def get_inline(self):
|
||||
return self.inline
|
||||
|
||||
def getCode(self):
|
||||
return self.code
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
# (at your option) any later version.
|
||||
|
||||
import os
|
||||
import locale
|
||||
import ctypes
|
||||
import psutil
|
||||
import subprocess
|
||||
from subprocess import CalledProcessError
|
||||
import multiprocessing as mp
|
||||
from multiprocessing import Process, freeze_support
|
||||
from src.log import OgError
|
||||
|
@ -84,20 +84,27 @@ class OgWindowsOperations:
|
|||
|
||||
def shellrun(self, request, ogRest):
|
||||
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:
|
||||
result = subprocess.run(cmd,
|
||||
shell=True,
|
||||
stdin=subprocess.DEVNULL,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True)
|
||||
except CalledProcessError as error:
|
||||
if error.stderr:
|
||||
return error.stderr
|
||||
if error.stdout:
|
||||
return error.stdout
|
||||
return "{Non zero exit code and empty output}"
|
||||
return (result.returncode, cmd, result.stdout)
|
||||
ogRest.proc = subprocess.Popen(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
shell=True,
|
||||
env=env,
|
||||
)
|
||||
output, error = ogRest.proc.communicate()
|
||||
except (OSError, subprocess.SubprocessError) as e:
|
||||
raise OgError(f'Error when running "shell run" subprocess: {e}') from e
|
||||
|
||||
output = output.decode('utf-8-sig', errors='replace')
|
||||
return (ogRest.proc.returncode, cmd, output)
|
||||
|
||||
def session(self, request, ogRest):
|
||||
raise OgError('Function not implemented')
|
||||
|
|
Loading…
Reference in New Issue