diff --git a/bin/confetty b/bin/confetty index 23035fd4..73cdee63 100755 --- a/bin/confetty +++ b/bin/confetty @@ -344,10 +344,25 @@ def exit(code=0): if consoleonly: sys.exit(code) else: - tlvdata.send(session.connection, {'operation': 'stop', 'path': currconsole}) + tlvdata.send(session.connection, {'operation': 'stop', + 'path': currconsole}) inconsole = False def conserver_command(fh, command): + # x - conserver has that as 'show baud', I am inclined to replace that with + # 'request exclusive' + # b - conserver has that as 'broadcast message', I'm tempted to use that + # for break + # r - replay + # p - replay (this is the one I've always used) + # f - force attach read/write + # a - attach read/write + # s - spy mode + # l[n] - send a particular break, tempted to do l0 for compatibility + # o - reopen tty, this should mean reconnect console + # d - down a console... never used this... + # L - toggle logging + # w - who is on console while not command: ready, _, _ = select.select((fh,), (), (), 1) if ready: @@ -355,9 +370,14 @@ def conserver_command(fh, command): if command[0] == '.': print("disconnect]\r") exit() + if command[0] == 'b': + tlvdata.send(session.connection, {'operation': 'break', + 'path': currconsole}) + print("break sent]\r") elif command[0] == '?': print("help]\r") print(". disconnect\r") + print("b break\r") print(" abort command\r") elif command[0] == '\x0d': print("ignored]\r") diff --git a/confluent/consoleserver.py b/confluent/consoleserver.py index 041d0695..9115c2e6 100644 --- a/confluent/consoleserver.py +++ b/confluent/consoleserver.py @@ -80,6 +80,7 @@ class _ConsoleHandler(object): self._console = plugin.handle_path( "/nodes/%s/_console/session" % self.node, "create", self.cfgmgr) + self.send_break = self._console.send_break if self._attribwatcher: self.cfgmgr.remove_watcher(self._attribwatcher) self._attribwatcher = None @@ -288,6 +289,9 @@ class ConsoleSession(object): if recdata: datacallback(recdata) + def send_break(self): + self.conshdl.send_break() + def destroy(self): _handled_consoles[self.ckey].detachuser(self.username) _handled_consoles[self.ckey].unregister_rcpt(self.reghdl) diff --git a/confluent/interface/console.py b/confluent/interface/console.py index 8f013923..538f57db 100644 --- a/confluent/interface/console.py +++ b/confluent/interface/console.py @@ -38,6 +38,11 @@ class Console(object): def wait_for_data(self, timeout=600): raise NotImplementedError("Subclassing required") + def send_break(self): + """This function is how a plugin should implement sending a break to + the remote console""" + pass + def ping(self): """This function is a hint to the console plugin that now would be a nice time to assess health of console connection. Plugins that see diff --git a/confluent/sockapi.py b/confluent/sockapi.py index 52d8aa08..d531b06c 100644 --- a/confluent/sockapi.py +++ b/confluent/sockapi.py @@ -131,6 +131,9 @@ def process_request(connection, request, cfm, authdata, authname): if data['operation'] == 'stop': consession.destroy() return + elif data['operation'] == 'break': + consession.send_break() + continue else: raise Exception("TODO") if not data: diff --git a/plugins/hardwaremanagement/ipmi.py b/plugins/hardwaremanagement/ipmi.py index 26e18487..5dad6416 100644 --- a/plugins/hardwaremanagement/ipmi.py +++ b/plugins/hardwaremanagement/ipmi.py @@ -150,6 +150,9 @@ class IpmiConsole(conapi.Console): def write(self, data): self.solconnection.send_data(data) + def send_break(self): + self.solconnection.send_break() + class IpmiIterator(object): def __init__(self, operator, nodes, element, cfg, inputdata):