Пример #1
0
    def execute(self, exit=True):
        """
        Execute the actions necessary to perform a `molecule login` and
        return a tuple.

        :param exit: (Unused) Provided to complete method signature.
        :return: Return a tuple of None, otherwise sys.exit on command failure.
        """
        # get list of running hosts from state
        if self.molecule.state.hosts:
            hosts = [k for k, v in self.molecule.state.hosts.iteritems()]
        else:
            hosts = []

        try:
            # Nowhere to login to if there is no running host.
            if len(hosts) == 0:
                raise base.InvalidHost('There are no running hosts.')

            # Check whether a host was specified.
            if self.command_args.get('host') is None:
                # One running host is perfect. Login to it.
                if len(hosts) == 1:
                    hostname = hosts[0]

                # But too many hosts is trouble as well.
                else:
                    message = ('There are {} running hosts. You can only '
                               'login to one at a time.\n\n'
                               'Available hosts:\n{}'.format(
                                   len(hosts), '\n'.join(sorted(hosts))))
                    raise base.InvalidHost(message)

            else:
                # If the host was specified, try to use it.
                hostname = self.command_args.get('host')
                match = [x for x in hosts if x.startswith(hostname)]
                if len(match) == 0:
                    raise subprocess.CalledProcessError(1, None)
                elif len(match) != 1:
                    # If there are multiple matches, but one of them is an
                    # exact string match, assume this is the one they're
                    # looking for and use it
                    if hostname in match:
                        match = [
                            hostname,
                        ]
                    else:
                        message = ("There are {} hosts that match '{}'. You "
                                   'can only login to one at a time.\n\n'
                                   'Available hosts:\n{}'.format(
                                       len(match), hostname,
                                       '\n'.join(sorted(hosts))))
                        raise base.InvalidHost(message)
                hostname = match[0]

        except subprocess.CalledProcessError:
            msg = "Unknown host '{}'.\n\nAvailable hosts:\n{}"
            LOG.error(
                msg.format(self.command_args.get('host'), '\n'.join(hosts)))
            util.sysexit()
        except base.InvalidHost as e:
            LOG.error(e.message)
            util.sysexit()

        self._get_login(hostname)
        return None, None
Пример #2
0
    def execute(self, exit=True):
        """
        Execute the actions necessary to perform a `molecule login` and
        return a tuple.

        :param exit: (Unused) Provided to complete method signature.
        :return: Return a tuple of None, otherwise sys.exit on command failure.
        """
        # get list of running hosts from state
        if self.molecule.state.hosts:
            hosts = [k for k, v in self.molecule.state.hosts.iteritems()]
        else:
            hosts = []

        try:
            # Nowhere to login to if there is no running host.
            if len(hosts) == 0:
                raise base.InvalidHost("There are no running hosts.")

            # Check whether a host was specified.
            if self.molecule.args['<host>'] is None:

                # One running host is perfect. Login to it.
                if len(hosts) == 1:
                    hostname = hosts[0]

                # But too many hosts is trouble as well.
                else:
                    raise base.InvalidHost(
                        "There are {} running hosts. You can only login to one at a time.\n\n"
                        "Available hosts:\n{}".format(
                            len(hosts), "\n".join(hosts)))

            else:
                # If the host was specified, try to use it.
                hostname = self.molecule.args['<host>']
                match = [x for x in hosts if x.startswith(hostname)]
                if len(match) == 0:
                    raise subprocess.CalledProcessError(1, None)
                elif len(match) != 1:
                    # If there are multiple matches, but one of them is an
                    # exact string match, assume this is the one they're
                    # looking for and use it
                    if hostname in match:
                        match = [hostname, ]
                    else:
                        raise base.InvalidHost(
                            "There are {} hosts that match '{}'. You can only login to one at a time.\n\n"
                            "Available hosts:\n{}".format(
                                len(match), hostname, "\n".join(hosts)))
                hostname = match[0]

            login_cmd = self.molecule.driver.login_cmd(hostname)
            login_args = self.molecule.driver.login_args(hostname)

        except subprocess.CalledProcessError:
            msg = "Unknown host '{}'.\n\nAvailable hosts:\n{}"
            LOG.error(
                msg.format(self.molecule.args['<host>'], "\n".join(hosts)))
            util.sysexit()
        except base.InvalidHost as e:
            LOG.error(e.message)
            util.sysexit()

        lines, columns = os.popen('stty size', 'r').read().split()
        dimensions = (int(lines), int(columns))
        self.molecule._pt = pexpect.spawn(
            '/usr/bin/env ' + login_cmd.format(*login_args),
            dimensions=dimensions)
        signal.signal(signal.SIGWINCH, self._sigwinch_passthrough)
        self.molecule._pt.interact()
        return None, None