Enhancement that gets the hosts installation location from install.inf and also collects the repos provided by zypper. These locations are then presented as potential installation locations when createing a VM. Index: virt-manager-1.2.1/virtManager/create.py =================================================================== --- virt-manager-1.2.1.orig/virtManager/create.py +++ virt-manager-1.2.1/virtManager/create.py @@ -359,7 +359,13 @@ class vmmCreate(vmmGObjectUI): self.widget("install-url-options").set_expanded(False) urlmodel = self.widget("install-url-box").get_model() ksmodel = self.widget("install-ks-box").get_model() - self.populate_media_model(urlmodel, self.config.get_media_urls()) + urllist = self.config.get_media_urls() + (index, inst_repos) = util.getInstallRepos() + for u in urllist: + if u in inst_repos: + inst_repos.remove(u) + media_urllist = urllist + inst_repos + self.populate_media_model(urlmodel, media_urllist) self.populate_media_model(ksmodel, self.config.get_kickstart_urls()) self.set_distro_labels("-", "-", force=True) Index: virt-manager-1.2.1/virtinst/util.py =================================================================== --- virt-manager-1.2.1.orig/virtinst/util.py +++ virt-manager-1.2.1/virtinst/util.py @@ -23,11 +23,14 @@ import os import random import re import stat +import subprocess +from subprocess import Popen, PIPE import libvirt _host_blktap_capable = None +_host_repo_url = None def listify(l): @@ -462,3 +465,96 @@ def register_libvirt_error_handler(): ignore = userdata ignore = err libvirt.registerErrorHandler(f=libvirt_callback, ctx=None) + +def getHostInstallSource(): + global _host_repo_url + if _host_repo_url is not None: + return _host_repo_url + if os.geteuid() != 0: + return None + + if os.path.exists('/var/lib/YaST2/install.inf'): + server_ip = server_name = server_dir = inst_mode = None + f = open('/var/lib/YaST2/install.inf') + lines = f.readlines() + f.close() + # Newer install.inf files use RepoURL. Older versions require parsing more fields + for line in lines: + if line.startswith('RepoURL:'): + repo_url = line[:-1].split('?', 1)[0] + repo_url = repo_url.split(' ') + if repo_url[1]: + if repo_url[1].startswith('ftp:') or repo_url[1].startswith('http:') or repo_url[1].startswith('smb:') or repo_url[1].startswith('nfs:'): + _host_repo_url = repo_url[1] + return repo_url[1] + return None + elif line.startswith('InstMode:'): + inst_mode = line[:-1].split('?', 1)[0] + inst_mode = inst_mode.split(' ') + inst_mode = inst_mode[1] + if inst_mode != 'ftp' and inst_mode != 'http' and inst_mode != 'smb' and inst_mode != 'nfs': + return None + elif line.startswith('ServerIP:'): + server_ip = line[:-1].split('?', 1)[0] + server_ip = server_ip.split(' ') + server_ip = server_ip[1] + elif line.startswith('ServerName:'): + server_name = line[:-1].split('?', 1)[0] + server_name = server_name.split(' ') + server_name = server_name[1] + elif line.startswith('Serverdir:'): + server_dir = line[:-1].split('?', 1)[0] + server_dir = server_dir.split(' ') + server_dir = server_dir[1] + if inst_mode: + repo_url = inst_mode + "://" + if server_name: + repo_url = repo_url + server_name + "/" + if server_dir: + repo_url = repo_url + server_dir + elif server_ip: + repo_url = repo_url + server_ip + "/" + if server_dir: + repo_url = repo_url + server_dir + _host_repo_url = repo_url + return repo_url + return None + +def getInstallRepos(enabled_sources_only = True): + if os.geteuid() != 0: + return (0, []) + dom0_inst_source = getHostInstallSource() + try: + if enabled_sources_only is True: + cmd = ['/usr/bin/zypper', 'lr', '-u', '-E'] + else: + cmd = ['/usr/bin/zypper', 'lr', '-u'] + p = subprocess.Popen(cmd, stdout=PIPE, stderr=PIPE) + stdout, stderr = p.communicate() + zypper_output = stdout + zypper_list = zypper_output.split("\n") + zypper_header = [x.strip(' ') for x in zypper_list[0].split("|")] + uri_index = zypper_header.index("URI") + except: + if dom0_inst_source is None: + dom0_inst_source = [] + return (0, dom0_inst_source) + + index_dom0 = -1 + number_of_sources = 0 + zypper_output = [] + for repo in zypper_list: + repo = [x.strip(' ') for x in repo.split("|")] + if len(repo) >= uri_index: + str = repo[uri_index] + if str.startswith('ftp://') or str.startswith('http://') or str.startswith('nfs://') or str.startswith('smb://'): + zypper_output.append(str) + if dom0_inst_source is not None and str == dom0_inst_source: + index_dom0 = number_of_sources + number_of_sources += 1 + + if index_dom0 == -1 and dom0_inst_source: + index_dom0 = 0 + zypper_output.insert(0, dom0_inst_source) + return (index_dom0, zypper_output) +