summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlvaro Neira Ayuso <aneira@soleta.eu>2019-12-27 13:46:49 +0100
committerAlvaro Neira Ayuso <alvaroneay@gmail.com>2020-01-19 19:50:44 +0100
commite20daf639dd271268b172b42adc0d1b9d2103883 (patch)
treeaa9a27298d6a8b88d2a9d1364c5ab8afe00ea780 /src
parentdfc97ffedb9a356299b593f76ce057f5953a77ab (diff)
Add shell run and output commands
Opengnsys needs a support to execute commands on the machine. This patch adds the support for executing two new commands "shell/run" and "shell/output". The first one, give us the support for executing a command in the machine and keep save in a queue the output. The second one, give us the support for sending the output from the command executed.
Diffstat (limited to 'src')
-rw-r--r--src/HTTPParser.py24
-rw-r--r--src/linux/ogOperations.py5
-rw-r--r--src/ogClient.py4
-rw-r--r--src/ogRest.py54
4 files changed, 72 insertions, 15 deletions
diff --git a/src/HTTPParser.py b/src/HTTPParser.py
index 7c64805..47c2204 100644
--- a/src/HTTPParser.py
+++ b/src/HTTPParser.py
@@ -1,5 +1,6 @@
import email
from io import StringIO
+import json
class HTTPParser:
def __init__(self):
@@ -11,24 +12,32 @@ class HTTPParser:
self.contentLen = None
self.operation = None
self.URI = None
+ self.cmd = None
def parser(self,data):
self.requestLine, self.headersAlone = data.split('\n', 1)
self.headers = email.message_from_file(StringIO(self.headersAlone))
- if 'host' in self.headers.keys():
- self.host = self.headers['host']
+ if 'Host' in self.headers.keys():
+ self.host = self.headers['Host']
- if 'content-type' in self.headers.keys():
- self.contentType = self.headers['content-type']
+ if 'Content-Type' in self.headers.keys():
+ self.contentType = self.headers['Content-Type']
- if 'content-length' in self.headers.keys():
- self.contentLen = int(self.headers['content-length'])
+ if 'Content-Length' in self.headers.keys():
+ self.contentLen = int(self.headers['Content-Length'])
if (not self.requestLine == None or not self.requestLine == ''):
self.operation = self.requestLine.split('/', 1)[0]
self.URI = self.requestLine.split('/', 1)[1]
+ if not self.contentLen == 0:
+ msgs = self.headersAlone.rstrip().split('\n')
+ cmd = msgs[len(msgs) - 1]
+ jsoncmd = json.loads(cmd)
+ if "run" in cmd:
+ self.cmd = jsoncmd["run"]
+
def getHeaderLine(self):
return self.headersAlone
@@ -52,3 +61,6 @@ class HTTPParser:
def getURI(self):
return self.URI
+
+ def getCMD(self):
+ return self.cmd
diff --git a/src/linux/ogOperations.py b/src/linux/ogOperations.py
index e3d69e2..1502f40 100644
--- a/src/linux/ogOperations.py
+++ b/src/linux/ogOperations.py
@@ -14,3 +14,8 @@ def reboot():
subprocess.call('source ' + OG_SCRIPT_PATH + 'etc/preinit/loadenviron.sh; ' + OG_SCRIPT_PATH + 'scripts/reboot', shell=True)
else:
subprocess.call(['/sbin/reboot'])
+
+def execCMD(cmd):
+ cmds = cmd.split(" ")
+ result = subprocess.run(cmds, stdout=subprocess.PIPE)
+ return result.stdout.decode('utf-8')
diff --git a/src/ogClient.py b/src/ogClient.py
index fb87bac..6aceeaa 100644
--- a/src/ogClient.py
+++ b/src/ogClient.py
@@ -18,6 +18,7 @@ class ogClient:
def __init__(self, ip, port):
self.ip = ip
self.port = port
+ self.ogrest = ogRest()
def get_socket(self):
return self.sock
@@ -74,7 +75,6 @@ class ogClient:
self.data = self.data + data
httpparser = HTTPParser()
- ogrest = ogRest()
if not self.trailer:
if self.data.find("\r\n") > 0:
@@ -89,7 +89,7 @@ class ogClient:
if self.trailer and len(self.data) >= self.content_len:
httpparser.parser(self.data)
- ogrest.processOperation(httpparser.getRequestOP(), httpparser.getURI(), self)
+ self.ogrest.processOperation(httpparser.getRequestOP(), httpparser.getURI(), httpparser.getCMD(), self)
# Cleanup state information from request
self.data = ""
diff --git a/src/ogRest.py b/src/ogRest.py
index 85e961a..ac02a4f 100644
--- a/src/ogRest.py
+++ b/src/ogRest.py
@@ -2,6 +2,8 @@ import threading
import platform
import time
from enum import Enum
+import json
+import queue
if platform.system() == 'Linux':
from src.linux import ogOperations
@@ -12,21 +14,44 @@ class ogResponses(Enum):
OK=2
class ogRest():
- def getResponse(self, response):
+ def __init__(self):
+ self.msgqueue = queue.Queue(1000)
+
+ def buildJsonResponse(self, idstr, content):
+ data = { idstr :content }
+ return json.dumps(data)
+
+ def getResponse(self, response, idstr=None, content=None):
+ msg = ''
if response == ogResponses.BAD_REQUEST:
- return 'HTTP/1.0 400 Bad request\r\n\r\n'
- if response == ogResponses.IN_PROGRESS:
- return 'HTTP/1.0 202 Accepted\r\n\r\n'
- if response == ogResponses.OK:
- return 'HTTP/1.0 200 OK\r\n\r\n'
+ msg = 'HTTP/1.0 400 Bad request'
+ elif response == ogResponses.IN_PROGRESS:
+ msg = 'HTTP/1.0 202 Accepted'
+ elif response == ogResponses.OK:
+ msg = 'HTTP/1.0 200 OK'
+ else:
+ return msg
- def processOperation(self, op, URI, client):
+ if not content == None:
+ jsonmsg = self.buildJsonResponse(idstr, content)
+ msg = msg + '\nContent-Type:application/json'
+ msg = msg + '\nContent-Length:' + str(len(jsonmsg))
+ msg = msg + '\n' + jsonmsg
+
+ msg = msg + '\r\n\r\n'
+ return msg
+
+ def processOperation(self, op, URI, cmd, client):
if ("poweroff" in URI):
self.process_poweroff(client)
elif ("reboot" in URI):
self.process_reboot(client)
elif ("probe" in URI):
self.process_probe(client)
+ elif ("shell/run" in URI):
+ self.process_shellrun(client, cmd)
+ elif ("shell/output" in URI):
+ self.process_shellout(client)
else:
client.send(self.getResponse(ogResponses.BAD_REQUEST))
@@ -53,3 +78,18 @@ class ogRest():
def process_probe(self, client):
client.send(self.getResponse(ogResponses.OK))
+
+ def process_shellrun(self, client, cmd):
+ if cmd == None:
+ client.send(self.getResponse(ogResponses.BAD_REQUEST))
+ return
+
+ self.msgqueue.put(ogOperations.execCMD(cmd))
+ client.send(self.getResponse(ogResponses.IN_PROGRESS))
+
+ def process_shellout(self, client):
+ if self.msgqueue.empty():
+ client.send(self.getResponse(ogResponses.IN_PROGRESS, 'out', ''))
+ else:
+ out = self.msgqueue.get()
+ client.send(self.getResponse(ogResponses.IN_PROGRESS, 'out', out))