예제 #1
0
파일: sockio.py 프로젝트: AVD087/mist.io
class ShellNamespace(CustomNamespace):
    def init(self):
        super(ShellNamespace, self).init()
        self.channel = None
        self.ssh_info = {}
        self.provider = ''

    def on_shell_open(self, data):
        if self.ssh_info:
            self.disconnect()
        self.ssh_info = {
            'backend_id': data['backend_id'],
            'machine_id': data['machine_id'],
            'host': data['host'],
            'columns': data['cols'],
            'rows': data['rows'],
        }
        log.info("opened shell")
        self.provider = data.get('provider', '')
        self.shell = Shell(data['host'])
        try:
            key_id, ssh_user = self.shell.autoconfigure(
                self.user, data['backend_id'], data['machine_id']
            )
        except Exception as exc:
            if self.provider == 'docker':
                self.shell = Shell(data['host'], provider=data.get('provider', ''))
                key_id, ssh_user = self.shell.autoconfigure(
                    self.user, data['backend_id'], data['machine_id']
                )
            else:
                log.info(str(exc))
                if isinstance(exc, MachineUnauthorizedError):
                    err = 'Permission denied (publickey).'
                else:
                    err = str(exc)
                self.ssh_info['error'] = err
                self.emit_shell_data(err)
                self.disconnect()
                return
        self.ssh_info.update(key_id=key_id, ssh_user=ssh_user)
        self.channel = self.shell.invoke_shell('xterm', data['cols'], data['rows'])
        self.spawn(self.get_ssh_data)

    def on_shell_data(self, data):
        self.channel.send(data.encode('utf-8', 'ignore'))

    def on_shell_resize(self, columns, rows):
        log.info("Resizing shell to %d * %d", columns, rows)
        try:
            self.channel.resize_pty(columns, rows)
        except:
            pass

    def get_ssh_data(self):
        try:
            if self.provider == 'docker':
                try:
                    self.channel.send('\n')
                except:
                    pass
            while True:
                wait_read(self.channel.fileno())
                try:
                    data = self.channel.recv(1024).decode('utf-8', 'ignore')
                except TypeError:
                    data = self.channel.recv().decode('utf-8', 'ignore')

                if not len(data):
                    return
                self.emit_shell_data(data)
        finally:
            self.channel.close()

    def emit_shell_data(self, data):
        self.emit('shell_data', data)

    def disconnect(self, silent=False):
        if self.channel:
            self.channel.close()
        super(ShellNamespace, self).disconnect(silent=silent)
예제 #2
0
class ShellNamespace(CustomNamespace):
    def init(self):
        super(ShellNamespace, self).init()
        self.channel = None
        self.ssh_info = {}
        self.provider = ''

    def on_shell_open(self, data):
        if self.ssh_info:
            self.disconnect()
        self.ssh_info = {
            'backend_id': data['backend_id'],
            'machine_id': data['machine_id'],
            'host': data['host'],
            'columns': data['cols'],
            'rows': data['rows'],
        }
        log.info("opened shell")
        self.provider = data.get('provider', '')
        self.shell = Shell(data['host'])
        try:
            key_id, ssh_user = self.shell.autoconfigure(
                self.user, data['backend_id'], data['machine_id'])
        except Exception as exc:
            if self.provider == 'docker':
                self.shell = Shell(data['host'],
                                   provider=data.get('provider', ''))
                key_id, ssh_user = self.shell.autoconfigure(
                    self.user, data['backend_id'], data['machine_id'])
            else:
                log.info(str(exc))
                if isinstance(exc, MachineUnauthorizedError):
                    err = 'Permission denied (publickey).'
                else:
                    err = str(exc)
                self.ssh_info['error'] = err
                self.emit_shell_data(err)
                self.disconnect()
                return
        self.ssh_info.update(key_id=key_id, ssh_user=ssh_user)
        self.channel = self.shell.invoke_shell('xterm', data['cols'],
                                               data['rows'])
        self.spawn(self.get_ssh_data)

    def on_shell_data(self, data):
        self.channel.send(data.encode('utf-8', 'ignore'))

    def on_shell_resize(self, columns, rows):
        log.info("Resizing shell to %d * %d", columns, rows)
        try:
            self.channel.resize_pty(columns, rows)
        except:
            pass

    def get_ssh_data(self):
        try:
            if self.provider == 'docker':
                try:
                    self.channel.send('\n')
                except:
                    pass
            while True:
                wait_read(self.channel.fileno())
                try:
                    data = self.channel.recv(1024).decode('utf-8', 'ignore')
                except TypeError:
                    data = self.channel.recv().decode('utf-8', 'ignore')

                if not len(data):
                    return
                self.emit_shell_data(data)
        finally:
            self.channel.close()

    def emit_shell_data(self, data):
        self.emit('shell_data', data)

    def disconnect(self, silent=False):
        if self.channel:
            self.channel.close()
        super(ShellNamespace, self).disconnect(silent=silent)