forked from M-Labs/artiq
artiq_devtool: use CommMgmt instead of shelling out to artiq_coremgmt.
(Which no longer exists.) This also fixes `artiq_devtool hotswap` to work without an `artiq_devtool connect` running in background.
This commit is contained in:
parent
d446a3293e
commit
a39f8d6634
|
@ -0,0 +1,37 @@
|
||||||
|
import sys
|
||||||
|
import socket
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def set_keepalive(sock, after_idle, interval, max_fails):
|
||||||
|
if sys.platform.startswith("linux"):
|
||||||
|
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
||||||
|
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, after_idle)
|
||||||
|
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, interval)
|
||||||
|
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, max_fails)
|
||||||
|
elif sys.platform.startswith("win") or sys.platform.startswith("cygwin"):
|
||||||
|
# setting max_fails is not supported, typically ends up being 5 or 10
|
||||||
|
# depending on Windows version
|
||||||
|
sock.ioctl(socket.SIO_KEEPALIVE_VALS,
|
||||||
|
(1, after_idle*1000, interval*1000))
|
||||||
|
else:
|
||||||
|
logger.warning("TCP keepalive not supported on platform '%s', ignored",
|
||||||
|
sys.platform)
|
||||||
|
|
||||||
|
|
||||||
|
def initialize_connection(host, port, ssh_transport=None):
|
||||||
|
if ssh_transport is None:
|
||||||
|
sock = socket.create_connection((host, port), 5.0)
|
||||||
|
sock.settimeout(None)
|
||||||
|
set_keepalive(sock, 3, 2, 3)
|
||||||
|
logger.debug("connected to %s:%d", host, port)
|
||||||
|
else:
|
||||||
|
sock = ssh_transport.open_channel("direct-tcpip", (host, port),
|
||||||
|
("localhost", 9999), timeout=5.0)
|
||||||
|
ssh_transport.set_keepalive(2)
|
||||||
|
logger.debug("connected to %s:%d via SSH transport to %s:%d",
|
||||||
|
host, port, *ssh_transport.getpeername())
|
||||||
|
return sock
|
|
@ -1,7 +1,5 @@
|
||||||
import struct
|
import struct
|
||||||
import logging
|
import logging
|
||||||
import socket
|
|
||||||
import sys
|
|
||||||
import traceback
|
import traceback
|
||||||
import numpy
|
import numpy
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
@ -9,6 +7,7 @@ from fractions import Fraction
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
from artiq.coredevice import exceptions
|
from artiq.coredevice import exceptions
|
||||||
|
from artiq.coredevice.comm import initialize_connection
|
||||||
from artiq import __version__ as software_version
|
from artiq import __version__ as software_version
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,30 +84,6 @@ class RPCReturnValueError(ValueError):
|
||||||
RPCKeyword = namedtuple('RPCKeyword', ['name', 'value'])
|
RPCKeyword = namedtuple('RPCKeyword', ['name', 'value'])
|
||||||
|
|
||||||
|
|
||||||
def set_keepalive(sock, after_idle, interval, max_fails):
|
|
||||||
if sys.platform.startswith("linux"):
|
|
||||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
|
||||||
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, after_idle)
|
|
||||||
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, interval)
|
|
||||||
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, max_fails)
|
|
||||||
elif sys.platform.startswith("win") or sys.platform.startswith("cygwin"):
|
|
||||||
# setting max_fails is not supported, typically ends up being 5 or 10
|
|
||||||
# depending on Windows version
|
|
||||||
sock.ioctl(socket.SIO_KEEPALIVE_VALS,
|
|
||||||
(1, after_idle*1000, interval*1000))
|
|
||||||
else:
|
|
||||||
logger.warning("TCP keepalive not supported on platform '%s', ignored",
|
|
||||||
sys.platform)
|
|
||||||
|
|
||||||
|
|
||||||
def initialize_connection(host, port):
|
|
||||||
sock = socket.create_connection((host, port), 5.0)
|
|
||||||
sock.settimeout(None)
|
|
||||||
set_keepalive(sock, 3, 2, 3)
|
|
||||||
logger.debug("connected to host %s on port %d", host, port)
|
|
||||||
return sock
|
|
||||||
|
|
||||||
|
|
||||||
class CommKernelDummy:
|
class CommKernelDummy:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
@ -143,10 +118,10 @@ class CommKernel:
|
||||||
self.host = host
|
self.host = host
|
||||||
self.port = port
|
self.port = port
|
||||||
|
|
||||||
def open(self):
|
def open(self, **kwargs):
|
||||||
if hasattr(self, "socket"):
|
if hasattr(self, "socket"):
|
||||||
return
|
return
|
||||||
self.socket = initialize_connection(self.host, self.port)
|
self.socket = initialize_connection(self.host, self.port, **kwargs)
|
||||||
self.socket.sendall(b"ARTIQ coredev\n")
|
self.socket.sendall(b"ARTIQ coredev\n")
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
|
|
|
@ -3,6 +3,8 @@ import logging
|
||||||
import socket
|
import socket
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
|
from artiq.coredevice.comm import initialize_connection
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -44,22 +46,15 @@ class LogLevel(Enum):
|
||||||
TRACE = 5
|
TRACE = 5
|
||||||
|
|
||||||
|
|
||||||
def initialize_connection(host, port):
|
|
||||||
sock = socket.create_connection((host, port), 5.0)
|
|
||||||
sock.settimeout(None)
|
|
||||||
logger.debug("connected to host %s on port %d", host, port)
|
|
||||||
return sock
|
|
||||||
|
|
||||||
|
|
||||||
class CommMgmt:
|
class CommMgmt:
|
||||||
def __init__(self, host, port=1380):
|
def __init__(self, host, port=1380):
|
||||||
self.host = host
|
self.host = host
|
||||||
self.port = port
|
self.port = port
|
||||||
|
|
||||||
def open(self):
|
def open(self, **kwargs):
|
||||||
if hasattr(self, "socket"):
|
if hasattr(self, "socket"):
|
||||||
return
|
return
|
||||||
self.socket = initialize_connection(self.host, self.port)
|
self.socket = initialize_connection(self.host, self.port, **kwargs)
|
||||||
self.socket.sendall(b"ARTIQ management\n")
|
self.socket.sendall(b"ARTIQ management\n")
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
|
|
|
@ -18,6 +18,7 @@ import shlex
|
||||||
|
|
||||||
from artiq.tools import verbosity_args, init_logger
|
from artiq.tools import verbosity_args, init_logger
|
||||||
from artiq.remoting import SSHClient
|
from artiq.remoting import SSHClient
|
||||||
|
from artiq.coredevice.comm_mgmt import CommMgmt
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -264,10 +265,15 @@ def main():
|
||||||
client.run_command(["flterm", serial, "--output-only"])
|
client.run_command(["flterm", serial, "--output-only"])
|
||||||
|
|
||||||
elif action == "hotswap":
|
elif action == "hotswap":
|
||||||
|
lock()
|
||||||
|
|
||||||
logger.info("Hotswapping firmware")
|
logger.info("Hotswapping firmware")
|
||||||
firmware = build_dir(variant, "software", firmware, firmware + ".bin")
|
firmware = build_dir(variant, "software", firmware, firmware + ".bin")
|
||||||
command("artiq_coreboot", "hotswap", firmware,
|
|
||||||
on_failure="Hotswapping failed")
|
mgmt = CommMgmt(device)
|
||||||
|
mgmt.open(ssh_transport=client.get_transport())
|
||||||
|
with open(firmware, "rb") as f:
|
||||||
|
mgmt.hotswap(f.read())
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.error("Unknown action {}".format(action))
|
logger.error("Unknown action {}".format(action))
|
||||||
|
|
Loading…
Reference in New Issue