Compare commits
7 Commits
nilmrun-1.
...
nilmrun-1.
Author | SHA1 | Date | |
---|---|---|---|
5cd38f1ba9 | |||
d7551bde0b | |||
40fd377a38 | |||
6e7f3ac704 | |||
29adb47a33 | |||
7c605a469a | |||
f5225f88f9 |
@@ -6,9 +6,6 @@ Prerequisites:
|
||||
# Runtime and build environments
|
||||
sudo apt-get install python2.7 python-setuptools
|
||||
|
||||
# Base dependencies
|
||||
sudo apt-get install python-numpy python-scipy
|
||||
|
||||
# Plus nilmdb and its dependencies
|
||||
nilmdb (1.8.2+)
|
||||
|
||||
|
@@ -43,9 +43,8 @@ class LogReceiver(object):
|
||||
|
||||
class Process(object):
|
||||
"""Spawn and manage a subprocess, and capture its output."""
|
||||
def __init__(self, name, argv, tempfile = None):
|
||||
def __init__(self, argv, tempfile = None):
|
||||
self.start_time = None
|
||||
self.name = name
|
||||
|
||||
# Use a pipe for communicating log data
|
||||
(rpipe, wpipe) = os.pipe()
|
||||
@@ -189,7 +188,7 @@ class ProcessManager(object):
|
||||
def __getitem__(self, key):
|
||||
return self.processes[key]
|
||||
|
||||
def run_code(self, procname, code, args):
|
||||
def run_code(self, code, args):
|
||||
"""Evaluate 'code' as if it were placed into a Python file and
|
||||
executed. The arguments, which must be strings, will be
|
||||
accessible in the code as sys.argv[1:]."""
|
||||
@@ -200,13 +199,13 @@ class ProcessManager(object):
|
||||
with os.fdopen(fd, 'w') as f:
|
||||
f.write(code)
|
||||
argv = [ sys.executable, "-B", "-s", "-u", path ] + args
|
||||
pid = self.run_command(procname, argv)
|
||||
pid = self.run_command(argv)
|
||||
self.tmpfiles[pid] = path
|
||||
return pid
|
||||
|
||||
def run_command(self, procname, argv):
|
||||
def run_command(self, argv):
|
||||
"""Execute a command line program"""
|
||||
new = Process(procname, argv)
|
||||
new = Process(argv)
|
||||
self.processes[new.pid] = new
|
||||
return new.pid
|
||||
|
||||
@@ -239,6 +238,7 @@ class ProcessManager(object):
|
||||
|
||||
# Retrieve info for system
|
||||
info["system"]["cpu_percent"] = sum(psutil.cpu_percent(0, percpu=True))
|
||||
info["system"]["cpu_max"] = 100.0 * psutil.NUM_CPUS
|
||||
info["system"]["procs"] = len(psutil.get_pid_list())
|
||||
# psutil > 0.6.0's psutil.virtual_memory() would be better here,
|
||||
# but this should give the same info.
|
||||
|
@@ -5,10 +5,7 @@ import sys
|
||||
import os
|
||||
import socket
|
||||
import simplejson as json
|
||||
import decorator
|
||||
import psutil
|
||||
import traceback
|
||||
import argparse
|
||||
import time
|
||||
|
||||
import nilmdb
|
||||
@@ -67,7 +64,6 @@ class AppProcess(object):
|
||||
"pid": pid,
|
||||
"alive": self.manager[pid].alive,
|
||||
"exitcode": self.manager[pid].exitcode,
|
||||
"name": self.manager[pid].name,
|
||||
"start_time": self.manager[pid].start_time,
|
||||
"log": self.manager[pid].log,
|
||||
}
|
||||
@@ -134,7 +130,7 @@ class AppRun(object):
|
||||
if not isinstance(argv, list):
|
||||
raise cherrypy.HTTPError("400 Bad Request",
|
||||
"argv must be a list of strings")
|
||||
return self.manager.run_command("command", argv)
|
||||
return self.manager.run_command(argv)
|
||||
|
||||
# /run/code
|
||||
@cherrypy.expose
|
||||
@@ -142,16 +138,18 @@ class AppRun(object):
|
||||
@cherrypy.tools.json_out()
|
||||
@exception_to_httperror(nilmrun.processmanager.ProcessError)
|
||||
@cherrypy.tools.CORS_allow(methods = ["POST"])
|
||||
def code(self, code, args):
|
||||
def code(self, code, args = None):
|
||||
"""Execute arbitrary Python code. 'code' is a formatted string.
|
||||
It will be run as if it were written into a Python file and
|
||||
executed. 'args' is a list of strings, and they are passed
|
||||
on the command line as additional arguments (i.e., they end up
|
||||
in sys.argv[1:])"""
|
||||
if args is None:
|
||||
args = []
|
||||
if not isinstance(args, list):
|
||||
raise cherrypy.HTTPError("400 Bad Request",
|
||||
"args must be a list of strings")
|
||||
return self.manager.run_code("usercode", code, args)
|
||||
return self.manager.run_code(code, args)
|
||||
|
||||
class Server(object):
|
||||
def __init__(self, host = '127.0.0.1', port = 8080,
|
||||
|
5
setup.py
5
setup.py
@@ -62,13 +62,9 @@ setup(name='nilmrun',
|
||||
license = "Proprietary",
|
||||
author_email = 'jim@jtan.com',
|
||||
install_requires = [ 'nilmdb >= 1.8.2',
|
||||
'nilmtools >= 1.2.2',
|
||||
'psutil >= 0.3.0',
|
||||
'cherrypy >= 3.2',
|
||||
'decorator',
|
||||
'simplejson',
|
||||
'numpy',
|
||||
'scipy',
|
||||
],
|
||||
packages = [ 'nilmrun',
|
||||
'nilmrun.scripts',
|
||||
@@ -79,7 +75,6 @@ setup(name='nilmrun',
|
||||
entry_points = {
|
||||
'console_scripts': [
|
||||
'nilmrun-server = nilmrun.scripts.nilmrun_server:main',
|
||||
'nilm-trainola = nilmrun.trainola:main',
|
||||
],
|
||||
},
|
||||
zip_safe = False,
|
||||
|
@@ -65,6 +65,7 @@ class TestClient(object):
|
||||
status = client.get("process/status", { "pid": pid })
|
||||
if status["alive"] == False:
|
||||
break
|
||||
time.sleep(0.1)
|
||||
else:
|
||||
raise AssertionError("process " + str(pid) + " didn't die in " +
|
||||
str(timeout) + " seconds: " + repr(status))
|
||||
@@ -145,7 +146,7 @@ class TestClient(object):
|
||||
|
||||
# Verify that status looks OK
|
||||
status = client.get("process/status", { "pid": pid, "clear": True })
|
||||
for x in [ "pid", "alive", "exitcode", "name", "start_time", "log" ]:
|
||||
for x in [ "pid", "alive", "exitcode", "start_time", "log" ]:
|
||||
in_(x, status)
|
||||
in_("dummy 0\ndummy 1\ndummy 2\ndummy 3\n", status["log"])
|
||||
eq_(status["alive"], True)
|
||||
@@ -248,6 +249,7 @@ class TestClient(object):
|
||||
sys.stdout.flush()
|
||||
if status["alive"] == False:
|
||||
break
|
||||
time.sleep(0.1)
|
||||
status = client.post("process/remove", { "pid": pid })
|
||||
os._exit(int(status["exitcode"]))
|
||||
|
||||
@@ -256,7 +258,10 @@ class TestClient(object):
|
||||
eq_(client.get("process/list"), [])
|
||||
|
||||
def do(code, args, kill):
|
||||
if args is not None:
|
||||
pid = client.post("run/code", { "code": code, "args": args } )
|
||||
else:
|
||||
pid = client.post("run/code", { "code": code } )
|
||||
eq_(client.get("process/list"), [pid])
|
||||
if kill:
|
||||
return self.wait_kill(client, pid)
|
||||
@@ -321,6 +326,15 @@ class TestClient(object):
|
||||
eq_(status["log"], "hello\n")
|
||||
ne_(status["exitcode"], 0)
|
||||
|
||||
# default arguments are empty
|
||||
code = textwrap.dedent("""
|
||||
import sys
|
||||
print 'args:', len(sys.argv[1:])
|
||||
""")
|
||||
status = do(code, None, False)
|
||||
eq_(status["log"], "args: 0\n")
|
||||
eq_(status["exitcode"], 0)
|
||||
|
||||
def test_client_08_bad_types(self):
|
||||
client = HTTPClient(baseurl = testurl, post_json = True)
|
||||
|
||||
@@ -332,7 +346,7 @@ class TestClient(object):
|
||||
client.post("run/command", { "argv": "asdf" })
|
||||
in_("must be a list", str(e.exception))
|
||||
|
||||
def test_client_00_info(self):
|
||||
def test_client_09_info(self):
|
||||
client = HTTPClient(baseurl = testurl, post_json = True)
|
||||
|
||||
# start some processes
|
||||
|
Reference in New Issue
Block a user