Merge ~jslarraz/ubuntu-qa-tools:add-vm-name-resolution into ubuntu-qa-tools:master

Proposed by Jorge Sancho Larraz
Status: Rejected
Rejected by: Jorge Sancho Larraz
Proposed branch: ~jslarraz/ubuntu-qa-tools:add-vm-name-resolution
Merge into: ubuntu-qa-tools:master
Diff against target: 124 lines (+69/-9)
1 file modified
vm-tools/uvt (+69/-9)
Reviewer Review Type Date Requested Status
Ubuntu Bug Control Pending
Review via email: mp+460382@code.launchpad.net

Commit message

uvt: add cmd_ssh and perform address resolution using virsh when possible

Description of the change

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

To post a comment you must log in.
Revision history for this message
Marc Deslauriers (mdeslaur) wrote :

I just ripped out domifaddr support because we wanted to standardize on the same configuration for everyone and domifaddr support was limited and wouldn't allow resolving from the host.

https://git.launchpad.net/ubuntu-qa-tools/commit/vm-tools/uvt?id=43be4941455b466d7be5e263ee6f345be7377277

Perhaps you can add your patch to your snap instead of the main repo?

Revision history for this message
Jorge Sancho Larraz (jslarraz) wrote (last edit ):

Thanks for the info Marc, I'll patch it at build time then

Unmerged commits

9a36ce0... by Jorge Sancho Larraz

uvt: add uvt ssh <vm-name> command

8011732... by Jorge Sancho Larraz

uvt: perform address resolution using virsh when possible

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/vm-tools/uvt b/vm-tools/uvt
2index c7b0143..884b5bf 100755
3--- a/vm-tools/uvt
4+++ b/vm-tools/uvt
5@@ -468,6 +468,58 @@ def cmd_cmd():
6 print("Error: VM '%s' command failed. Aborting." % machine, file=sys.stderr)
7 sys.exit(1)
8
9+def cmd_ssh():
10+ '''Run a command inside a virtual machine'''
11+
12+ usage = "usage: %prog ssh [options] <vm>"
13+
14+ epilog = "\n" + \
15+ "Eg:\n" + \
16+ "$ uvt ssh sec-jammy-amd64\n\n" + \
17+ "This will open an interactive session on the single VM named 'sec-jammy-amd64'\n"
18+
19+ optparse.OptionParser.format_epilog = lambda self, formatter: self.epilog
20+ parser = optparse.OptionParser(usage = usage, epilog = epilog)
21+
22+ parser.add_option("-s", "--start", dest="start", default=False, action='store_true',
23+ help="Start the VM (and shutdown if it wasn't running")
24+
25+ parser.add_option("-t", "--timeout", dest="timeout", default=90, metavar="TIMEOUT",
26+ help="wait TIMEOUT seconds for VM to come up if -s is used (default: %default)")
27+
28+ parser.add_option("-f", "--force-ssh", dest="force_ssh", default=False, action='store_true',
29+ help="force the SSH keys to be taken")
30+
31+ parser.add_option("-r", "--root", dest="root", default=False, action='store_true',
32+ help="login to the VM as root")
33+
34+ parser.add_option("-u", "--user", dest="user", default=None, metavar="USER",
35+ help="login to the VM as user")
36+
37+ parser.add_option("-q", "--quiet", dest="quiet", default=False, action='store_true',
38+ help="only report hostnames and output")
39+
40+ (opt, args) = parser.parse_args()
41+ machine = args[0]
42+
43+ if opt.user is not None and opt.root:
44+ print("Error: may specify only one of --root and --user.\n", file=sys.stderr)
45+ sys.exit(1)
46+
47+ print("----- %s -----" % machine)
48+ if check_vm_exists(machine) == False:
49+ print("Error: VM '%s' does not exist, skipping." % machine, file=sys.stderr)
50+ return
51+
52+ result = vm_run_command(machine, "bash", root=opt.root, start=opt.start,
53+ start_timeout=opt.timeout, force_keys=opt.force_ssh,
54+ quiet=opt.quiet, output=True, interactive=True,
55+ verbose=False, user=opt.user)
56+
57+ if result == False:
58+ print("Error: VM '%s' command failed. Aborting." % machine, file=sys.stderr)
59+ sys.exit(1)
60+
61 def cmd_repo():
62 '''Adds or removes a local repo to a VM'''
63
64@@ -1415,8 +1467,8 @@ def vm_run_command(vm_name, command, root=False, start=False,
65 print("Could not start VM: %s" % vm_name)
66 return False
67
68- dns_name = vm_ping(vm_name)
69- if dns_name == "":
70+ vm_addr = vm_ping(vm_name)
71+ if vm_addr == "":
72 print("Could not ping VM: %s" % vm_name)
73 return False
74
75@@ -1440,7 +1492,7 @@ def vm_run_command(vm_name, command, root=False, start=False,
76 ssh_command += ['-q']
77 ssh_command += ['-o', 'BatchMode=yes']
78
79- ssh_command += [dns_name, command]
80+ ssh_command += [vm_addr, command]
81
82 if interactive:
83 rc, out = runcmd(ssh_command, stderr = None, stdout = None, stdin = None)
84@@ -1519,9 +1571,9 @@ def vm_stop(vm_name):
85 # a shutdown menu.
86
87 # If we can connect using ssh, issue a shutdown command
88- dns_host = vm_ping(vm_name)
89- if dns_host != "" and ssh_connect(dns_host):
90- vm_run_command(dns_host, "shutdown -h now", root=True,
91+ vm_addr = vm_ping(vm_name)
92+ if vm_addr != "" and ssh_connect(vm_addr):
93+ vm_run_command(vm_addr, "shutdown -h now", root=True,
94 force_keys=True, output=False, ignore_rc=True)
95 else:
96 rc, out = runcmd(["virsh", "--connect", uvt_conf["vm_connect"],
97@@ -1563,9 +1615,16 @@ def vm_start_wait(vm_name, timeout=1800, quiet=False, clone_name=None):
98
99 def vm_ping(vm_name):
100 '''Attempts to ping a VM'''
101- rc, out = runcmd(["ping", "-c1", "-w1", vm_name])
102- if rc == 0 and ssh_connect(vm_name) == True:
103- return vm_name
104+
105+ # Try to resolve address first
106+ rc, out = runcmd(["virsh", "--connect", uvt_conf["vm_connect"],
107+ "domifaddr", vm_name])
108+ addr_search = re.search("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", out)
109+ vm_addr = addr_search.group(0) if ((rc == 0) and (addr_search is not None)) else vm_name
110+
111+ rc, out = runcmd(["ping", "-c1", "-w1", vm_addr])
112+ if rc == 0 and ssh_connect(vm_addr) == True:
113+ return vm_addr
114 return ""
115
116 def ssh_connect(host, resolve=True):
117@@ -3608,6 +3667,7 @@ commands = {
118 'update' : cmd_update,
119 'clone' : cmd_clone,
120 'cmd' : cmd_cmd,
121+ 'ssh' : cmd_ssh,
122 'list' : cmd_list,
123 'config' : cmd_config,
124 'dump' : cmd_dump,

Subscribers

People subscribed via source and target branches