def boot_and_login(self): self.console = remote.boot_to_login_prompt(self.domain, self.console) remote.login(self.domain, self.console) test_directory = remote.path(self.domain, self.console, path=self.test.directory) if not test_directory: abspath = os.path.abspath(self.test.directory) self.logger.error("directory %s not mounted on %s", abspath, self.domain) raise Exception("directory '%s' not mounted on %s" % (abspath, self.domain)) self.logger.info("'cd' to %s", test_directory) self.console.chdir(test_directory)
def boot_and_login(self): self.console = remote.boot_and_login(self.domain, self.console) test_directory = remote.path(self.domain, self.console, path=self.test.directory) if not test_directory: abspath = os.path.abspath(self.test.directory) self.logger.error("directory %s not mounted on %s", abspath, self.domain) raise Exception("directory '%s' not mounted on %s" % (abspath, self.domain)) self.logger.info("'cd' to %s", test_directory) self.console.chdir(test_directory)
def main(): # If SIGUSR1, backtrace all threads; hopefully this is early # enough. faulthandler.register(signal.SIGUSR1) parser = argparse.ArgumentParser( description= "Connect to and run a shell command on a virtual machine domain", epilog= "If no command or file is specified an interactive shell is created. SIGUSR1 will dump all thread stacks" ) parser.add_argument("--timeout", type=argutil.timeout, default=None, help=("maximum runtime for the command" "; -1 for no timeout" " (default: no timeout)")) argutil.add_redirect_argument( parser, "re-direct console output from stdout to %(metavar)s", "--output", "-o", default=sys.stdout, metavar="FILE") parser.add_argument( "--chdir", default=None, action="store", metavar="PATH", help=("first change directory to %(metavar)s on the remote" " domain and update prompt-match logic to expect" " that directory" "; an absolute %(metavar)s is used unmodified" "; a relative %(metavar)s, which is interpreted" " as relative to the current local working directory" ", is converted to an absolute remote path before use" " (default: leave directory unchanged)")) parser.add_argument("--boot", default=None, action="store", type=Boot, choices=[e for e in Boot], help=("force the domain to boot" "; 'cold': power-off any existing domain" "; 'warm': reboot any existing domain" " (default: leave existing domain running)")) parser.add_argument("--shutdown", default=False, action="store_true", help=("on-completion shut down the domain" " (default: leave the domain running)")) parser.add_argument( "--mode", default=None, choices=set(["interactive", "batch"]), help=("enter mode" " (default: if there is no command enter interactive mode)")) parser.add_argument("--host-name", default=None, help="The virtual machine's host name") parser.add_argument("domain", action="store", metavar="DOMAIN", help="virtual machine (domain) to connect to") parser.add_argument( "command", nargs=argparse.REMAINDER, metavar="COMMAND", help= "run shell command non-interactively; WARNING#1: this simply concatenates remaining arguments with spaces; WARNING#2: this does not try to escape arguments before passing them onto the domain's shell" ) logutil.add_arguments(parser) # These three calls go together args = parser.parse_args() logutil.config(args, sys.stderr) logger = logutil.getLogger("kvmsh") # Get things started domain = virsh.Domain(domain_name=args.domain, host_name=args.host_name) # Find a reason to log-in and interact with the console. batch = args.mode == "batch" or args.command interactive = args.mode == "interactive" or (not args.command and args.boot == None and not args.shutdown) # Get the current console, this will be None if the machine is # shutoff. console = domain.console() if args.boot: if args.boot is Boot.cold and console: remote.shutdown(domain, console) console = None console = remote.boot_to_login_prompt(domain, console) elif (interactive or batch) and not console: console = remote.boot_to_login_prompt(domain, console) status = 0 if interactive or batch: remote.login(domain, console) if args.chdir and os.path.isabs(args.chdir): chdir = args.chdir elif args.chdir: chdir = remote.path(domain, console, path=args.chdir) else: chdir = None if chdir: domain.logger.info("'cd' to %s", chdir) console.chdir(chdir) if args.command: console.output(args.output) console.run("") status = console.run(' '.join(args.command), timeout=args.timeout) print() if interactive: print() output = console.output(None) if output: logger.info( "info: option --output disabled as it makes pexpect crash when in interactive mode." ) if args.debug: logger.info( "info: pexpect ignores --debug in interactive mode!") logger.info("Escape character is ^]") # Hack so that the prompt appears console.output(sys.stdout) console.run("") console.output() # Get this terminals properties. columns, rows = os.get_terminal_size() # Normal mode console.stty_sane(term=os.getenv("TERM"), rows=rows, columns=columns) console.interact() if args.shutdown: shutdown_status = remote.shutdown(domain) status = status or shutdown_status sys.exit(status)