Jorge Sancho Larraz has proposed merging ~jslarraz/ubuntu-qa-tools:add-vm-name-resolution into ubuntu-qa-tools:master.
Commit message: uvt: add cmd_ssh and perform address resolution using virsh when possible Requested reviews: Ubuntu Bug Control (ubuntu-bugcontrol) For more details, see: https://code.launchpad.net/~jslarraz/ubuntu-qa-tools/+git/ubuntu-qa-tools/+merge/460382 When trying to create a snap with uvt I was not able to make address resolution using libnss-libvirt to work. This MR modifies uvt to perform the address resolution internally using `virsh domifaddr` instead of relying on the OS. It will fallback to the old behavior if this resolution does not work. This MR also add a new command called `uvt ssh <vm-name> (pretty much a shortcut for `uvt cmd <vm-name> bash`) that opens an interactive session in the target machine. Both changes together may remove the need of network setup (install libnss-libvirt + config /etc/nsswitch.conf) from the setup step on certain configurations. It will additionally enable us to package uvt as a snap -- Your team Ubuntu Bug Control is requested to review the proposed merge of ~jslarraz/ubuntu-qa-tools:add-vm-name-resolution into ubuntu-qa-tools:master.
diff --git a/vm-tools/uvt b/vm-tools/uvt index c7b0143..884b5bf 100755 --- a/vm-tools/uvt +++ b/vm-tools/uvt @@ -468,6 +468,58 @@ def cmd_cmd(): print("Error: VM '%s' command failed. Aborting." % machine, file=sys.stderr) sys.exit(1) +def cmd_ssh(): + '''Run a command inside a virtual machine''' + + usage = "usage: %prog ssh [options] <vm>" + + epilog = "\n" + \ + "Eg:\n" + \ + "$ uvt ssh sec-jammy-amd64\n\n" + \ + "This will open an interactive session on the single VM named 'sec-jammy-amd64'\n" + + optparse.OptionParser.format_epilog = lambda self, formatter: self.epilog + parser = optparse.OptionParser(usage = usage, epilog = epilog) + + parser.add_option("-s", "--start", dest="start", default=False, action='store_true', + help="Start the VM (and shutdown if it wasn't running") + + parser.add_option("-t", "--timeout", dest="timeout", default=90, metavar="TIMEOUT", + help="wait TIMEOUT seconds for VM to come up if -s is used (default: %default)") + + parser.add_option("-f", "--force-ssh", dest="force_ssh", default=False, action='store_true', + help="force the SSH keys to be taken") + + parser.add_option("-r", "--root", dest="root", default=False, action='store_true', + help="login to the VM as root") + + parser.add_option("-u", "--user", dest="user", default=None, metavar="USER", + help="login to the VM as user") + + parser.add_option("-q", "--quiet", dest="quiet", default=False, action='store_true', + help="only report hostnames and output") + + (opt, args) = parser.parse_args() + machine = args[0] + + if opt.user is not None and opt.root: + print("Error: may specify only one of --root and --user.\n", file=sys.stderr) + sys.exit(1) + + print("----- %s -----" % machine) + if check_vm_exists(machine) == False: + print("Error: VM '%s' does not exist, skipping." % machine, file=sys.stderr) + return + + result = vm_run_command(machine, "bash", root=opt.root, start=opt.start, + start_timeout=opt.timeout, force_keys=opt.force_ssh, + quiet=opt.quiet, output=True, interactive=True, + verbose=False, user=opt.user) + + if result == False: + print("Error: VM '%s' command failed. Aborting." % machine, file=sys.stderr) + sys.exit(1) + def cmd_repo(): '''Adds or removes a local repo to a VM''' @@ -1415,8 +1467,8 @@ def vm_run_command(vm_name, command, root=False, start=False, print("Could not start VM: %s" % vm_name) return False - dns_name = vm_ping(vm_name) - if dns_name == "": + vm_addr = vm_ping(vm_name) + if vm_addr == "": print("Could not ping VM: %s" % vm_name) return False @@ -1440,7 +1492,7 @@ def vm_run_command(vm_name, command, root=False, start=False, ssh_command += ['-q'] ssh_command += ['-o', 'BatchMode=yes'] - ssh_command += [dns_name, command] + ssh_command += [vm_addr, command] if interactive: rc, out = runcmd(ssh_command, stderr = None, stdout = None, stdin = None) @@ -1519,9 +1571,9 @@ def vm_stop(vm_name): # a shutdown menu. # If we can connect using ssh, issue a shutdown command - dns_host = vm_ping(vm_name) - if dns_host != "" and ssh_connect(dns_host): - vm_run_command(dns_host, "shutdown -h now", root=True, + vm_addr = vm_ping(vm_name) + if vm_addr != "" and ssh_connect(vm_addr): + vm_run_command(vm_addr, "shutdown -h now", root=True, force_keys=True, output=False, ignore_rc=True) else: rc, out = runcmd(["virsh", "--connect", uvt_conf["vm_connect"], @@ -1563,9 +1615,16 @@ def vm_start_wait(vm_name, timeout=1800, quiet=False, clone_name=None): def vm_ping(vm_name): '''Attempts to ping a VM''' - rc, out = runcmd(["ping", "-c1", "-w1", vm_name]) - if rc == 0 and ssh_connect(vm_name) == True: - return vm_name + + # Try to resolve address first + rc, out = runcmd(["virsh", "--connect", uvt_conf["vm_connect"], + "domifaddr", vm_name]) + addr_search = re.search("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", out) + vm_addr = addr_search.group(0) if ((rc == 0) and (addr_search is not None)) else vm_name + + rc, out = runcmd(["ping", "-c1", "-w1", vm_addr]) + if rc == 0 and ssh_connect(vm_addr) == True: + return vm_addr return "" def ssh_connect(host, resolve=True): @@ -3608,6 +3667,7 @@ commands = { 'update' : cmd_update, 'clone' : cmd_clone, 'cmd' : cmd_cmd, + 'ssh' : cmd_ssh, 'list' : cmd_list, 'config' : cmd_config, 'dump' : cmd_dump,
_______________________________________________ Mailing list: https://launchpad.net/~ubuntu-bugcontrol Post to : ubuntu-bugcontrol@lists.launchpad.net Unsubscribe : https://launchpad.net/~ubuntu-bugcontrol More help : https://help.launchpad.net/ListHelp