util: move generate_name to generatename.py

This commit is contained in:
Cole Robinson 2019-06-07 18:16:53 -04:00
parent 5ed8f2aa5f
commit 6677f677da
8 changed files with 91 additions and 84 deletions

View File

@ -16,7 +16,7 @@ from gi.repository import Gtk
from gi.repository import Pango
import virtinst
from virtinst import util
import virtinst.generatename
from . import uiutil
from .addstorage import vmmAddStorage
@ -1494,7 +1494,7 @@ class vmmCreate(vmmGObjectUI):
basename += "-%s" % _pretty_arch(self._guest.os.arch)
force_num = False
return util.generate_name(basename,
return virtinst.generatename.generate_name(basename,
self.conn.get_backend().lookupByName,
start_num=force_num and 1 or 2, force_num=force_num,
sep=not force_num and "-" or "",

View File

@ -13,6 +13,7 @@ import os
import libvirt
from . import generatename
from . import progress
from . import util
from .guest import Guest
@ -492,7 +493,7 @@ class Cloner(object):
clonebase = newname
clonebase = os.path.join(dirname, clonebase)
return util.generate_name(
return generatename.generate_name(
clonebase,
lambda p: DeviceDisk.path_definitely_exists(self.conn, p),
suffix,
@ -512,7 +513,7 @@ class Cloner(object):
basename = basename.replace(match.group(), "")
basename = basename + "-clone"
return util.generate_name(basename,
return generatename.generate_name(basename,
self.conn.lookupByName,
sep="", start_num=start_num)

77
virtinst/generatename.py Normal file
View File

@ -0,0 +1,77 @@
#
# Copyright 2019 Red Hat, Inc.
#
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
#
import libvirt
def libvirt_collision(collision_cb, val):
"""
Run the passed collision function with val as the only argument:
If libvirtError is raised, return False
If no libvirtError raised, return True
"""
check = False
if val is not None:
try:
if collision_cb(val) is not None:
check = True
except libvirt.libvirtError:
pass
return check
def generate_name(base, collision_cb, suffix="", lib_collision=True,
start_num=1, sep="-", force_num=False, collidelist=None):
"""
Generate a new name from the passed base string, verifying it doesn't
collide with the collision callback.
This can be used to generate disk path names from the parent VM or pool
name. Names generated look like 'base-#suffix', ex:
If foobar, and foobar-1.img already exist, and:
base = "foobar"
suffix = ".img"
output = "foobar-2.img"
:param base: The base string to use for the name (e.g. "my-orig-vm-clone")
:param collision_cb: A callback function to check for collision,
receives the generated name as its only arg
:param lib_collision: If true, the collision_cb is not a boolean function,
and instead throws a libvirt error on failure
:param start_num: The number to start at for generating non colliding names
:param sep: The separator to use between the basename and the
generated number (default is "-")
:param force_num: Force the generated name to always end with a number
:param collidelist: An extra list of names to check for collision
"""
collidelist = collidelist or []
base = str(base)
def collide(n):
if n in collidelist:
return True
if lib_collision:
return libvirt_collision(collision_cb, tryname)
else:
return collision_cb(tryname)
numrange = list(range(start_num, start_num + 100000))
if not force_num:
numrange = [None] + numrange
for i in numrange:
tryname = base
if i is not None:
tryname += ("%s%d" % (sep, i))
tryname += suffix
if not collide(tryname):
return tryname
raise ValueError(_("Name generation range exceeded."))

View File

@ -13,7 +13,7 @@ import libvirt
from virtcli import CLIConfig
from . import util
from . import generatename
from .devices import * # pylint: disable=wildcard-import
from .domain import * # pylint: disable=wildcard-import
from .domcapabilities import DomainCapabilities
@ -131,7 +131,7 @@ class Guest(XMLBuilder):
for ignore in range(256):
uuid = _randomUUID()
if not util.libvirt_collision(conn.lookupByUUID, uuid):
if not generatename.libvirt_collision(conn.lookupByUUID, uuid):
return uuid
logging.error("Failed to generate non-conflicting UUID")

View File

@ -11,7 +11,7 @@ import logging
import libvirt
from . import util
from . import generatename
from .xmlbuilder import XMLBuilder, XMLChildProperty, XMLProperty
@ -147,7 +147,7 @@ class Network(XMLBuilder):
@staticmethod
def find_free_name(conn, basename, **kwargs):
cb = conn.networkLookupByName
return util.generate_name(basename, cb, **kwargs)
return generatename.generate_name(basename, cb, **kwargs)
@staticmethod
def pretty_forward_desc(mode, dev):

View File

@ -6,7 +6,7 @@
import libvirt
from . import util
from . import generatename
from .xmlbuilder import XMLBuilder, XMLChildProperty, XMLProperty
@ -19,7 +19,7 @@ class _SnapshotDisk(XMLBuilder):
class DomainSnapshot(XMLBuilder):
@staticmethod
def find_free_name(vm, collidelist):
return util.generate_name("snapshot", vm.snapshotLookupByName,
return generatename.generate_name("snapshot", vm.snapshotLookupByName,
sep="", start_num=1, force_num=True,
collidelist=collidelist)

View File

@ -10,8 +10,8 @@ import threading
import libvirt
from . import generatename
from . import progress
from . import util
from .xmlbuilder import XMLBuilder, XMLChildProperty, XMLProperty
@ -261,7 +261,7 @@ class StoragePool(_StorageObject):
return False
kwargs["lib_collision"] = False
return util.generate_name(basename, cb, **kwargs)
return generatename.generate_name(basename, cb, **kwargs)
@staticmethod
def ensure_pool_is_running(pool_object, refresh=False):
@ -551,7 +551,7 @@ class StorageVolume(_StorageObject):
in use by another volume. Extra params are passed to generate_name
"""
StoragePool.ensure_pool_is_running(pool_object, refresh=True)
return util.generate_name(basename,
return generatename.generate_name(basename,
pool_object.storageVolLookupByName,
**kwargs)

View File

@ -5,8 +5,6 @@
# See the COPYING file in the top-level directory.
#
import libvirt
def listify(l):
if l is None:
@ -17,75 +15,6 @@ def listify(l):
return l
def libvirt_collision(collision_cb, val):
"""
Run the passed collision function with val as the only argument:
If libvirtError is raised, return False
If no libvirtError raised, return True
"""
check = False
if val is not None:
try:
if collision_cb(val) is not None:
check = True
except libvirt.libvirtError:
pass
return check
def generate_name(base, collision_cb, suffix="", lib_collision=True,
start_num=1, sep="-", force_num=False, collidelist=None):
"""
Generate a new name from the passed base string, verifying it doesn't
collide with the collision callback.
This can be used to generate disk path names from the parent VM or pool
name. Names generated look like 'base-#suffix', ex:
If foobar, and foobar-1.img already exist, and:
base = "foobar"
suffix = ".img"
output = "foobar-2.img"
:param base: The base string to use for the name (e.g. "my-orig-vm-clone")
:param collision_cb: A callback function to check for collision,
receives the generated name as its only arg
:param lib_collision: If true, the collision_cb is not a boolean function,
and instead throws a libvirt error on failure
:param start_num: The number to start at for generating non colliding names
:param sep: The separator to use between the basename and the
generated number (default is "-")
:param force_num: Force the generated name to always end with a number
:param collidelist: An extra list of names to check for collision
"""
collidelist = collidelist or []
base = str(base)
def collide(n):
if n in collidelist:
return True
if lib_collision:
return libvirt_collision(collision_cb, tryname)
else:
return collision_cb(tryname)
numrange = list(range(start_num, start_num + 100000))
if not force_num:
numrange = [None] + numrange
for i in numrange:
tryname = base
if i is not None:
tryname += ("%s%d" % (sep, i))
tryname += suffix
if not collide(tryname):
return tryname
raise ValueError(_("Name generation range exceeded."))
def xml_escape(xml):
"""
Replaces chars ' " < > & with xml safe counterparts