osdict: Add toplevel OSDB as API entry point

Makes code more readable, and lazy loading simpler.
This commit is contained in:
Cole Robinson 2015-04-04 12:04:11 -04:00
parent f644b0997d
commit bd9ab2d5b5
7 changed files with 187 additions and 176 deletions

View File

@ -124,13 +124,13 @@ class TestMisc(unittest.TestCase):
"\n".join([("%s version=%s" % tup) for tup in failures]))
def test_libosinfo_aliases_ro(self):
from virtinst import osdict
aliases = getattr(osdict, "_aliases")
from virtinst import OSDB
aliases = getattr(OSDB, "_aliases")
if len(aliases) != 40:
raise AssertionError(_("osdict._aliases changed size. It "
raise AssertionError(_("OSDB._aliases changed size. It "
"should never be extended, since it is only for back "
"compat with pre-libosinfo osdict."))
"compat with pre-libosinfo osdict.py"))
class TestURI(unittest.TestCase):

View File

@ -813,7 +813,7 @@ class vmmCreate(vmmGObjectUI):
STABLE_OS_SUPPORT or
None)
types = virtinst.osdict.list_os(list_types=True)
types = virtinst.OSDB.list_os(list_types=True)
if not filtervars:
# Kind of a hack, just show linux + windows by default since
# that's all 98% of people care about
@ -821,9 +821,9 @@ class vmmCreate(vmmGObjectUI):
else:
supportl = []
for t in types:
l = virtinst.osdict.list_os(typename=t.name,
only_supported=True,
filtervars=filtervars)
l = virtinst.OSDB.list_os(typename=t.name,
only_supported=True,
filtervars=filtervars)
if l:
supportl.append(t.name)
@ -852,9 +852,9 @@ class vmmCreate(vmmGObjectUI):
None)
preferred = self.config.preferred_distros
variants = virtinst.osdict.list_os(typename=_type,
variants = virtinst.OSDB.list_os(typename=_type,
sortpref=preferred)
supportl = virtinst.osdict.list_os(typename=_type,
supportl = virtinst.OSDB.list_os(typename=_type,
sortpref=preferred,
only_supported=True,
filtervars=filtervars)
@ -1653,7 +1653,10 @@ class vmmCreate(vmmGObjectUI):
self.addstorage.check_path_search(
self, self.conn, path)
res = virtinst.osdict.get_recommended_resources(variant, self.guest)
res = None
osobj = virtinst.OSDB.lookup_os(variant)
if osobj:
res = osobj.get_recommended_resources(self.guest)
# Change the default values suggested to the user.
ram_size = DEFAULT_MEM
@ -2014,7 +2017,7 @@ class vmmCreate(vmmGObjectUI):
distro_type = None
distro_var = None
if variant:
osclass = virtinst.osdict.lookup_os(variant)
osclass = virtinst.OSDB.lookup_os(variant)
distro_type = osclass.typename
distro_var = osclass.name

View File

@ -37,6 +37,7 @@ stable_defaults = _cliconfig.stable_defaults
from . import util
from virtinst import support
from virtinst.uri import URISplit
from virtinst.osdict import OSDB
from virtinst.osxml import OSXML
from virtinst.domainfeatures import DomainFeatures

View File

@ -25,11 +25,11 @@ import tempfile
import urlgrabber
from . import osdict
from . import urlfetcher
from . import util
from .devicedisk import VirtualDisk
from .installer import Installer
from .osdict import OSDB
from .storage import StoragePool, StorageVolume
@ -502,7 +502,7 @@ class DistroInstaller(Installer):
logging.debug("Can't detect distro for media on "
"remote connection.")
else:
distro = osdict.lookup_os_by_media(self.location)
distro = OSDB.lookup_os_by_media(self.location)
except:
logging.debug("Error attempting to detect distro.", exc_info=True)

View File

@ -26,9 +26,9 @@ import libvirt
from virtcli import cliconfig
from . import osdict
from . import util
from . import support
from .osdict import OSDB
from .clock import Clock
from .cpu import CPU
from .device import VirtualDevice
@ -211,9 +211,9 @@ class Guest(XMLBuilder):
###############################
def _set_os_object(self, variant):
obj = osdict.lookup_os(variant)
obj = OSDB.lookup_os(variant)
if not obj:
obj = osdict.lookup_os("generic")
obj = OSDB.lookup_os("generic")
self.__os_object = obj
def _get_os_object(self):
if not self.__os_object:
@ -226,7 +226,7 @@ class Guest(XMLBuilder):
def _set_os_variant(self, val):
if val:
val = val.lower()
if osdict.lookup_os(val) is None:
if OSDB.lookup_os(val) is None:
raise ValueError(
_("Distro '%s' does not exist in our dictionary") % val)

View File

@ -25,53 +25,9 @@ import re
from gi.repository import Libosinfo as libosinfo
# This is only for back compatibility with pre-libosinfo support.
# This should never change.
_aliases = {
"altlinux" : "altlinux1.0",
"debianetch" : "debian4",
"debianlenny" : "debian5",
"debiansqueeze" : "debian6",
"debianwheezy" : "debian7",
"freebsd10" : "freebsd10.0",
"freebsd6" : "freebsd6.0",
"freebsd7" : "freebsd7.0",
"freebsd8" : "freebsd8.0",
"freebsd9" : "freebsd9.0",
"mandriva2009" : "mandriva2009.0",
"mandriva2010" : "mandriva2010.0",
"mbs1" : "mbs1.0",
"msdos" : "msdos6.22",
"openbsd4" : "openbsd4.2",
"opensolaris" : "opensolaris2009.06",
"opensuse11" : "opensuse11.4",
"opensuse12" : "opensuse12.3",
"rhel4" : "rhel4.0",
"rhel5" : "rhel5.0",
"rhel6" : "rhel6.0",
"rhel7" : "rhel7.0",
"ubuntuhardy" : "ubuntu8.04",
"ubuntuintrepid" : "ubuntu8.10",
"ubuntujaunty" : "ubuntu9.04",
"ubuntukarmic" : "ubuntu9.10",
"ubuntulucid" : "ubuntu10.04",
"ubuntumaverick" : "ubuntu10.10",
"ubuntunatty" : "ubuntu11.04",
"ubuntuoneiric" : "ubuntu11.10",
"ubuntuprecise" : "ubuntu12.04",
"ubuntuquantal" : "ubuntu12.10",
"ubunturaring" : "ubuntu13.04",
"ubuntusaucy" : "ubuntu13.10",
"vista" : "winvista",
"winxp64" : "winxp",
"linux" : "generic",
"windows" : "winxp",
"solaris" : "solaris10",
"virtio26": "fedora10",
}
_allvariants = {}
###################
# Sorting helpers #
###################
def _remove_older_point_releases(distro_list):
ret = distro_list[:]
@ -161,18 +117,154 @@ def _sort(tosort, sortpref=None, limit_point_releases=False):
return retlist
class _OsVariantType(object):
class _OSDB(object):
"""
Entry point for the public API
"""
def __init__(self):
self.__os_loader = None
self.__all_variants = None
def __init__(self, name, label, urldistro, sortby):
self.name = name
self.label = label
self.urldistro = urldistro
self.sortby = sortby
# This is only for back compatibility with pre-libosinfo support.
# This should never change.
_aliases = {
"altlinux" : "altlinux1.0",
"debianetch" : "debian4",
"debianlenny" : "debian5",
"debiansqueeze" : "debian6",
"debianwheezy" : "debian7",
"freebsd10" : "freebsd10.0",
"freebsd6" : "freebsd6.0",
"freebsd7" : "freebsd7.0",
"freebsd8" : "freebsd8.0",
"freebsd9" : "freebsd9.0",
"mandriva2009" : "mandriva2009.0",
"mandriva2010" : "mandriva2010.0",
"mbs1" : "mbs1.0",
"msdos" : "msdos6.22",
"openbsd4" : "openbsd4.2",
"opensolaris" : "opensolaris2009.06",
"opensuse11" : "opensuse11.4",
"opensuse12" : "opensuse12.3",
"rhel4" : "rhel4.0",
"rhel5" : "rhel5.0",
"rhel6" : "rhel6.0",
"rhel7" : "rhel7.0",
"ubuntuhardy" : "ubuntu8.04",
"ubuntuintrepid" : "ubuntu8.10",
"ubuntujaunty" : "ubuntu9.04",
"ubuntukarmic" : "ubuntu9.10",
"ubuntulucid" : "ubuntu10.04",
"ubuntumaverick" : "ubuntu10.10",
"ubuntunatty" : "ubuntu11.04",
"ubuntuoneiric" : "ubuntu11.10",
"ubuntuprecise" : "ubuntu12.04",
"ubuntuquantal" : "ubuntu12.10",
"ubunturaring" : "ubuntu13.04",
"ubuntusaucy" : "ubuntu13.10",
"vista" : "winvista",
"winxp64" : "winxp",
def is_type(self):
return self.__class__ == _OsVariantType
"linux" : "generic",
"windows" : "winxp",
"solaris" : "solaris10",
"virtio26": "fedora10",
}
#################
# Internal APIs #
#################
def _make_default_variants(self):
ret = {}
# Back compat 'types'
for name, label in [
("linux", "Linux"),
("windows", "Windows"),
("solaris", "Solaris"),
("unix", "UNIX"),
("other", "Other")]:
ret[name] = _OsVariantType(name, label, None, None)
# Generic variant
v = _OsVariant(None)
ret[v.name] = v
return ret
@property
def _os_loader(self):
if not self.__os_loader:
loader = libosinfo.Loader()
loader.process_default_path()
self.__os_loader = loader
return self.__os_loader
@property
def _all_variants(self):
if not self.__all_variants:
loader = self._os_loader
allvariants = self._make_default_variants()
db = loader.get_db()
oslist = db.get_os_list()
for os in range(oslist.get_length()):
osi = _OsVariant(oslist.get_nth(os))
allvariants[osi.name] = osi
self.__all_variants = allvariants
return self.__all_variants
###############
# Public APIs #
###############
def lookup_os(self, key):
key = self._aliases.get(key) or key
ret = self._all_variants.get(key)
if ret is None or ret.is_type():
return None
return ret
def lookup_os_by_media(self, location):
media = libosinfo.Media.create_from_location(location, None)
ret = self._os_loader.get_db().guess_os_from_media(media)
if ret and len(ret) > 0 and ret[0]:
return ret[0].get_short_id()
return None
def list_os(self, list_types=False, typename=None,
filtervars=None, only_supported=False,
**kwargs):
sortmap = {}
filtervars = filtervars or []
for key, osinfo in self._all_variants.items():
is_type = osinfo.is_type()
if list_types and not is_type:
continue
if not list_types and is_type:
continue
if typename and typename != osinfo.typename:
continue
if filtervars:
filtervars = [self.lookup_os(x).name for x in filtervars]
if osinfo.name not in filtervars:
continue
if only_supported and not osinfo.supported:
continue
sortmap[key] = osinfo
kwargs["limit_point_releases"] = only_supported
return _sort(sortmap, **kwargs)
#####################
# OsVariant classes #
#####################
def _is_os_related_to(o, related_os_list):
if o.get_short_id() in related_os_list:
return True
@ -186,6 +278,17 @@ def _is_os_related_to(o, related_os_list):
return False
class _OsVariantType(object):
def __init__(self, name, label, urldistro, sortby):
self.name = name
self.label = label
self.urldistro = urldistro
self.sortby = sortby
def is_type(self):
return self.__class__ == _OsVariantType
class _OsVariant(_OsVariantType):
def __init__(self, o):
self._os = o
@ -486,100 +589,4 @@ class _OsVariant(_OsVariantType):
return ret
def _add_type(name, label, urldistro=None, sortby=None):
t = _OsVariantType(name, label, urldistro, sortby)
_allvariants[name] = t
def _add_generic_variant():
v = _OsVariant(None)
_allvariants[v.name] = v
_add_type("linux", "Linux")
_add_type("windows", "Windows")
_add_type("solaris", "Solaris")
_add_type("unix", "UNIX")
_add_type("other", "Other")
_add_generic_variant()
_os_data_loaded = False
_os_loader = None
def _get_os_loader():
global _os_loader
if _os_loader:
return _os_loader
_os_loader = libosinfo.Loader()
_os_loader.process_default_path()
return _os_loader
def _load_os_data():
global _os_data_loaded
if _os_data_loaded:
return
loader = _get_os_loader()
db = loader.get_db()
oslist = db.get_os_list()
for os in range(oslist.get_length()):
osi = _OsVariant(oslist.get_nth(os))
_allvariants[osi.name] = osi
_os_data_loaded = True
def lookup_os(key):
_load_os_data()
key = _aliases.get(key) or key
ret = _allvariants.get(key)
if ret is None or ret.is_type():
return None
return ret
def list_os(list_types=False, typename=None,
filtervars=None, only_supported=False,
**kwargs):
_load_os_data()
sortmap = {}
filtervars = filtervars or []
for key, osinfo in _allvariants.items():
is_type = osinfo.is_type()
if list_types and not is_type:
continue
if not list_types and is_type:
continue
if typename and typename != osinfo.typename:
continue
if filtervars:
filtervars = [lookup_os(x).name for x in filtervars]
if osinfo.name not in filtervars:
continue
if only_supported and not osinfo.supported:
continue
sortmap[key] = osinfo
kwargs["limit_point_releases"] = only_supported
return _sort(sortmap, **kwargs)
def get_recommended_resources(variant, guest):
_load_os_data()
v = _allvariants.get(variant)
if v is None:
return None
return v.get_recommended_resources(guest)
def lookup_os_by_media(location):
loader = _get_os_loader()
media = libosinfo.Media.create_from_location(location, None)
ret = loader.get_db().guess_os_from_media(media)
if ret and len(ret) > 0 and ret[0]:
return ret[0].get_short_id()
return None
OSDB = _OSDB()

View File

@ -32,7 +32,7 @@ import urlparse
import urlgrabber.grabber as grabber
from . import osdict
from .osdict import OSDB
#########################################################################
@ -326,7 +326,7 @@ def getDistroStore(guest, fetcher):
urldistro = None
if guest.os_variant:
urldistro = osdict.lookup_os(guest.os_variant).urldistro
urldistro = OSDB.lookup_os(guest.os_variant).urldistro
dist = _distroFromTreeinfo(fetcher, arch, _type)
if dist:
@ -447,7 +447,7 @@ class Distro(object):
self.name))
def _check_osvariant_valid(self, os_variant):
return osdict.lookup_os(os_variant) is not None
return OSDB.lookup_os(os_variant) is not None
def get_osdict_info(self):
"""
@ -667,7 +667,7 @@ class FedoraDistro(RedHatDistro):
Search osdict list, find newest fedora version listed
"""
ret = None
for osinfo in osdict.list_os(typename="linux"):
for osinfo in OSDB.list_os(typename="linux"):
if osinfo.name.startswith("fedora") and "unknown" not in osinfo.name:
# First fedora* occurrence should be the newest
ret = osinfo.name
@ -866,7 +866,7 @@ class SuseDistro(Distro):
def _detect_osdict_from_url(self):
root = "opensuse"
oses = [n for n in osdict.list_os() if n.name.startswith(root)]
oses = [n for n in OSDB.list_os() if n.name.startswith(root)]
for osobj in oses:
codename = osobj.name[len(root):]
@ -941,7 +941,7 @@ class DebianDistro(Distro):
def _detect_osdict_from_url(self):
root = self.name.lower()
oses = [n for n in osdict.list_os() if n.name.startswith(root)]
oses = [n for n in OSDB.list_os() if n.name.startswith(root)]
if self._url_prefix == "daily":
return oses[0].name