Added remote continuous logging
Signed-off-by: Joppe Blondel <joppe@blondel.nl>
This commit is contained in:
@ -3,13 +3,17 @@
|
||||
import configparser
|
||||
import sys
|
||||
|
||||
def log(*args):
|
||||
print(*args)
|
||||
sys.stdout.flush()
|
||||
|
||||
def print_help():
|
||||
print("Unified FPGA synthesizer frontend\r\n(c) Joppe Blondel - 2022\r\n")
|
||||
print(f"Usage: {sys.argv[0]} [ OPTIONS ] target ...")
|
||||
print("")
|
||||
print("Options:")
|
||||
print(" -h Show this help message")
|
||||
print(" -c <file> Configuration file, defaults to project.cfg")
|
||||
log("Unified FPGA synthesizer frontend\r\n(c) Joppe Blondel - 2022\r\n")
|
||||
log(f"Usage: {sys.argv[0]} [ OPTIONS ] target ...")
|
||||
log("")
|
||||
log("Options:")
|
||||
log(" -h Show this help message")
|
||||
log(" -c <file> Configuration file, defaults to project.cfg")
|
||||
|
||||
if __name__=="__main__":
|
||||
# Parse arguments
|
||||
@ -33,7 +37,7 @@ if __name__=="__main__":
|
||||
targets.append(sys.argv[i])
|
||||
i += 1
|
||||
if nextarg is not None:
|
||||
print("ERROR: expected more arguments")
|
||||
log("ERROR: expected more arguments")
|
||||
exit(1)
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
@ -45,27 +49,27 @@ if __name__=="__main__":
|
||||
|
||||
for target in targets:
|
||||
|
||||
print("Target", target)
|
||||
log("Target", target)
|
||||
|
||||
toolchain = config.get(f'target.{target}', 'toolchain', fallback='NONE')
|
||||
if toolchain=='NONE':
|
||||
print("ERROR: No toolchain specified for target")
|
||||
log("ERROR: No toolchain specified for target")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
exec(f"from remotesyn.toolchains.{toolchain} import do")
|
||||
except ImportError:
|
||||
print(f"ERROR: Unknown toolchain '{toolchain}'")
|
||||
log(f"ERROR: Unknown toolchain '{toolchain}'")
|
||||
exit(1)
|
||||
|
||||
ret = do(config, target, print, subprocesses)
|
||||
ret = do(config, target, log, subprocesses)
|
||||
|
||||
if ret!=0:
|
||||
print("ERROR: toolchain returned with", ret)
|
||||
log("ERROR: toolchain returned with", ret)
|
||||
exit(ret)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\rStopping rbuild")
|
||||
log("\rStopping rbuild")
|
||||
for p in subprocesses:
|
||||
p.kill()
|
||||
exit(0)
|
@ -65,6 +65,7 @@ def recv_file(channel, file):
|
||||
fsize -= 1024
|
||||
|
||||
def recv_dir(channel, dr):
|
||||
print("<<<", dr)
|
||||
cmd(b'ls'+sstr(dr), channel)
|
||||
while True:
|
||||
status = channel.recv(2)
|
||||
@ -79,6 +80,8 @@ def recv_dir(channel, dr):
|
||||
tp = p[0]
|
||||
name = p[1:]
|
||||
if tp=='d':
|
||||
if name.startswith('.'):
|
||||
continue
|
||||
recv_dir(channel, f'{dr}/{name}')
|
||||
else:
|
||||
recv_file(channel, f'{dr}/{name}')
|
||||
@ -171,6 +174,16 @@ if __name__=="__main__":
|
||||
send_file(channel, f)
|
||||
|
||||
cmd(b'do'+sstr(target), channel)
|
||||
status = channel.recv(2)
|
||||
end = -1
|
||||
while end<0:
|
||||
data = channel.recv(8)
|
||||
end = data.find(b'\x00\xff\x00')
|
||||
if end>=0:
|
||||
data = data[0:end]
|
||||
print(str(data, 'utf-8'), end='', flush=True)
|
||||
sys.stdout.flush()
|
||||
|
||||
ret = 0
|
||||
|
||||
# Receive output dir
|
||||
|
@ -14,6 +14,7 @@ import json
|
||||
import threading
|
||||
import socket
|
||||
import shutil
|
||||
import fcntl
|
||||
|
||||
# List of running threads
|
||||
threads = []
|
||||
@ -67,6 +68,23 @@ class FileTransferRF(threading.Thread):
|
||||
self.channel.sendall(fdata)
|
||||
i -= 1024
|
||||
|
||||
class DoLogger(threading.Thread):
|
||||
def __init__(self, channel, p, identifier):
|
||||
threading.Thread.__init__(self)
|
||||
self.channel = channel
|
||||
self.p = p
|
||||
self.identifier = identifier
|
||||
self.running = True
|
||||
def stop(self):
|
||||
self.running = False
|
||||
def run(self):
|
||||
while self.p.poll() is None:
|
||||
d = os.read(self.p.stdout.fileno(), 1024)
|
||||
self.channel.sendall(d)
|
||||
res = self.p.wait()
|
||||
self.channel.sendall(b'\x00\xff\00')
|
||||
self.channel.sendall(struct.pack('>I', res))
|
||||
|
||||
class SSHServer(paramiko.ServerInterface):
|
||||
def __init__(self, authorized):
|
||||
self.event = threading.Event()
|
||||
@ -176,10 +194,15 @@ class SSHServer(paramiko.ServerInterface):
|
||||
print('[]', args)
|
||||
with open(f"{self.identifier}/project.cfg", "w") as f:
|
||||
self.config.write(f)
|
||||
p = subprocess.Popen(f"rbuild -c project.cfg {args}", shell=True, cwd=f'{self.identifier}', stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
p = subprocess.Popen(f"rbuild -c project.cfg {args}", shell=True, cwd=f'{self.identifier}', stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
|
||||
self.subprocesses.append(p)
|
||||
res = p.wait()
|
||||
channel.sendall(struct.pack('>I', res))
|
||||
|
||||
t = DoLogger(channel, p, self.identifier)
|
||||
self.threads.append(t)
|
||||
t.start()
|
||||
|
||||
channel.sendall(b'OK')
|
||||
|
||||
|
||||
return True
|
||||
|
||||
|
Reference in New Issue
Block a user