Change in vdsm[master]: sd: fix volume path returned by linkBCImage
by Federico Simoncelli
Federico Simoncelli has uploaded a new change for review.
Change subject: sd: fix volume path returned by linkBCImage
......................................................................
sd: fix volume path returned by linkBCImage
In a previous commit (c072945 One shot prepare) we involuntarily
changed the path used for virtual machine images from:
/rhev/data-center/<spUUID>/<sdUUID>/images/<imgUUID>/<volUUID>
to:
/rhev/data-center/mnt/blockSD/<sdUUID>/images/<imgUUID>/<volUUID>
This patch reverts to the previous path in order to minimize the
differences between different versions of vdsm that could lead to
live migration issues, e.g.
libvirtError: invalid argument: invalid path ... not assigned to
domain
Change-Id: Iea497b574d9a9a7e0e9b8e234e2bd9b9d983a60c
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1059482
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/storage/blockSD.py
M vdsm/storage/fileSD.py
M vdsm/storage/sd.py
3 files changed, 8 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/15/24315/1
diff --git a/vdsm/storage/blockSD.py b/vdsm/storage/blockSD.py
index 5179c5a..587e617 100644
--- a/vdsm/storage/blockSD.py
+++ b/vdsm/storage/blockSD.py
@@ -1053,8 +1053,7 @@
return rems
def linkBCImage(self, imgPath, imgUUID):
- dst = os.path.join(self.mountpoint, self.sdUUID, sd.DOMAIN_IMAGES,
- imgUUID)
+ dst = self.getLinkBCImagePath(imgUUID)
try:
os.symlink(imgPath, dst)
except OSError as e:
diff --git a/vdsm/storage/fileSD.py b/vdsm/storage/fileSD.py
index 180a43f..0f52718 100644
--- a/vdsm/storage/fileSD.py
+++ b/vdsm/storage/fileSD.py
@@ -422,8 +422,8 @@
for k, v in volumes.iteritems())
def linkBCImage(self, imgPath, imgUUID):
- return os.path.join(self.mountpoint, self.sdUUID, sd.DOMAIN_IMAGES,
- imgUUID)
+ # Nothing to do here other than returning the path
+ return self.getLinkBCImagePath(imgUUID)
def createImageLinks(self, srcImgPath, imgUUID):
"""
diff --git a/vdsm/storage/sd.py b/vdsm/storage/sd.py
index c9738e0..fd4c9db 100644
--- a/vdsm/storage/sd.py
+++ b/vdsm/storage/sd.py
@@ -25,6 +25,7 @@
from collections import namedtuple
import codecs
+import image
import storage_exception as se
import misc
import resourceFactories
@@ -643,6 +644,10 @@
# If it has a repo we don't have multiple domains. Assume single pool
return os.path.join(self.storage_repository, self.getPools()[0])
+ def getLinkBCImagePath(self, imgUUID):
+ return image.Image(self._getRepoPath()) \
+ .getImageDir(self.sdUUID, imgUUID)
+
def getIsoDomainImagesDir(self):
"""
Get 'images' directory from Iso domain
--
To view, visit http://gerrit.ovirt.org/24315
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iea497b574d9a9a7e0e9b8e234e2bd9b9d983a60c
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
9 years, 10 months
Change in vdsm[master]: vdsm-tool: Add logging and verbosity flags
by dkuznets@redhat.com
Dima Kuznetsov has uploaded a new change for review.
Change subject: vdsm-tool: Add logging and verbosity flags
......................................................................
vdsm-tool: Add logging and verbosity flags
Added -l/--logfile, -v/--verbose flags to vdsm-tool to control the log.
Change-Id: Ia495743f6e869f65843404e4d4c25c146ff14b43
Signed-off-by: Dima Kuznetsov <dkuznets(a)redhat.com>
---
M vdsm-tool/vdsm-tool
1 file changed, 49 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/81/27481/1
diff --git a/vdsm-tool/vdsm-tool b/vdsm-tool/vdsm-tool
index 57968f3..f7c3194 100755
--- a/vdsm-tool/vdsm-tool
+++ b/vdsm-tool/vdsm-tool
@@ -22,6 +22,7 @@
import sys
import imp
import getopt
+import logging
import textwrap
import syslog
import traceback
@@ -129,6 +130,14 @@
print "Valid options:"
print " -h, --help"
+ print "\t\tShow this help menu."
+ print " -l, --logfile <path>"
+ print "\t\tRedirect logging to file."
+ print " -v, --verbose"
+ print "\t\tProvide verbose logs."
+ print " -a, --append"
+ print "\t\tAppend to logfile instead of truncating it",
+ print "(if logging to a file)."
for mod_name, mod_desc in tool_modules:
_usage_module(mod_name, mod_desc)
@@ -137,14 +146,53 @@
sys.exit(exit_code)
+def setup_logging(log_file, verbose, append):
+
+ if verbose:
+ level = logging.INFO
+ else:
+ level = logging.WARNING
+
+ if log_file is not None:
+ handler = logging.FileHandler(log_file, mode=(append and 'a' or 'w'))
+ else:
+ handler = logging.StreamHandler()
+ handler.setFormatter(logging.Formatter(
+ "%(threadName)s::%(levelname)s::%(asctime)s::%(module)s::" +
+ "%(lineno)d::%(name)s::(%(funcName)s) %(message)s"
+ )
+ )
+
+ root_logger = logging.getLogger('')
+ root_logger.setLevel(level)
+ root_logger.addHandler(handler)
+
+
def main():
load_modules()
try:
- opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
+ opts, args = getopt.getopt(sys.argv[1:], "hl:va",
+ ["help", "logfile=", "verbose", "append"])
except getopt.GetoptError:
usage_and_exit(1)
+ log_file = None
+ verbose = False
+ append = False
+
+ for opt in opts:
+ if opt[0] in ('-h', '--help'):
+ usage_and_exit(0)
+ elif opt[0] in ('-l', '--logfile'):
+ log_file = opt[1]
+ elif opt[0] in ('-v', '--verbose'):
+ verbose = True
+ elif opt[0] in ('-a', '--append'):
+ append = True
+
+ setup_logging(log_file, verbose, append)
+
if len(args) < 1:
usage_and_exit(1)
--
To view, visit http://gerrit.ovirt.org/27481
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia495743f6e869f65843404e4d4c25c146ff14b43
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Dima Kuznetsov <dkuznets(a)redhat.com>
9 years, 10 months
Change in vdsm[master]: vdsm-tool: Change upgrade mechanism
by dkuznets@redhat.com
Dima Kuznetsov has uploaded a new change for review.
Change subject: vdsm-tool: Change upgrade mechanism
......................................................................
vdsm-tool: Change upgrade mechanism
The upgrade decorator is a mechanism within vdsm-tool to allow commands
to only run once. It has flags to override, but being a function
decorator, it did not have any direct access to command line arguments
and did access via sys.argv[2:].
There is a patch that will be sent that will add flags to vdsm-tool and
will make break upgrade and its argument parsing. I'm proposing to
change the upgrade from being a decorated function, to a class deriving
from Upgrade with apply() method. This way args can be passed to the
upgrade code (via ctor), and deriving class and extend the argument
parser, this way, we'll also get a nice usage for upgrade commands:
$ vdsm-tool some-upgrade --help
Usage:
vdsm-tool [...]
Options:
[general upgrade options, e.g. --run-again]
[specific upgrade options]
Change-Id: I6e1d28570dedfeff9fe60624b1db72d8cadf136a
Signed-off-by: Dima Kuznetsov <dkuznets(a)redhat.com>
---
M lib/vdsm/tool/unified_persistence.py
M lib/vdsm/tool/upgrade.py
M lib/vdsm/tool/upgrade_300_networks.py
3 files changed, 61 insertions(+), 114 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/93/27193/1
diff --git a/lib/vdsm/tool/unified_persistence.py b/lib/vdsm/tool/unified_persistence.py
index 3d4c8ab..10cdc41 100644
--- a/lib/vdsm/tool/unified_persistence.py
+++ b/lib/vdsm/tool/unified_persistence.py
@@ -23,7 +23,7 @@
from ..netconfpersistence import RunningConfig
from ..netinfo import NetInfo, getIfaceCfg, getDefaultGateway
from . import expose
-from .upgrade import upgrade
+from .upgrade import Upgrade
UPGRADE_NAME = 'upgrade-unified-persistence'
@@ -36,7 +36,6 @@
# bootproto = 'dhcp' if there's a lease on the NIC at the moment of upgrade
-@upgrade(UPGRADE_NAME)
def run():
networks, bondings = _getNetInfo()
logging.debug('%s upgrade persisting networks %s and bondings %s',
@@ -156,6 +155,13 @@
return config.get('vars', 'net_persistence') == 'unified'
+class UpgradeUnifiedPersistence(Upgrade):
+ def run(self):
+ if isNeeded():
+ run()
+ return 0
+
+
@expose(UPGRADE_NAME)
def unified_persistence(*args):
"""
@@ -164,6 +170,4 @@
persistence model is set as unified in /usr/lib64/python2.X/site-packages/
vdsm/config.py
"""
- if isNeeded():
- return run()
- return 0
+ return UpgradeUnifiedPersistence(*args).apply()
diff --git a/lib/vdsm/tool/upgrade.py b/lib/vdsm/tool/upgrade.py
index 2e19701..822a24d 100644
--- a/lib/vdsm/tool/upgrade.py
+++ b/lib/vdsm/tool/upgrade.py
@@ -18,58 +18,31 @@
#
import argparse
-from functools import wraps
import logging
import logging.config
-from logging.handlers import SysLogHandler
import os
-import sys
-from ..constants import (P_VDSM_LOG, P_VDSM_LIB, P_VDSM_CONF, VDSM_USER,
- VDSM_GROUP)
+from ..constants import P_VDSM_LIB
from ..utils import touchFile
-
-sys.path.append("/usr/share/vdsm")
-from storage.fileUtils import chown
class Upgrade(object):
"""
- Code that needs to be run exactly once can use this class as
- a general, simplistic mechanism. Usage:
+ This is a parent class to define upgrades, it defines its own argument
+ parser and allows any subclass extend it, the subclass is to define run()
+ method that will be called if needed upon upgrade.apply().
- with Upgrade('someUpgrade') as upgrade:
- if upgrade.isNeeded():
- runSomeCode()
- upgrade.seal()
-
- Upgrade as a context manager automatically redirects logging
- to the upgrade log. It also supplies the isNeeded and seal methods.
- To call isNeeded and seal automatically use this module's upgrade
- decorator.
+ upgrade.apply() parses the arguments, checks if upgrade should run,
+ and upon successful completion calls upgrade.seal() that marks upgrade as
+ done, to avoid executing it again.
"""
- def __init__(self, upgradeName):
+ def __init__(self, upgradeName, *args):
self._upgradeName = upgradeName
self._upgradeFilePath = os.path.join(P_VDSM_LIB,
'upgrade', self._upgradeName)
- try:
- # First load normal VDSM loggers, then the upgrade logger.
- # This will override VDSM's root logger but will keep the other
- # loggers intact. During an upgrade we add the update handler
- # to all loggers.
- logging.config.fileConfig(P_VDSM_CONF + 'logger.conf',
- disable_existing_loggers=False)
- logging.config.fileConfig(P_VDSM_CONF + 'upgrade.logger.conf',
- disable_existing_loggers=False)
- chown(
- os.path.join(P_VDSM_LOG, 'upgrade.log'),
- VDSM_USER,
- VDSM_GROUP)
- except Exception:
- logging.getLogger('upgrade').addHandler(SysLogHandler('/dev/log'))
- logging.exception("Could not init proper logging")
- finally:
- self.log = logging.getLogger('upgrade')
+ self.log = logging.getLogger('upgrade')
+ self._arg_parser = self._upgrade_argparser()
+ self._args = args
def isNeeded(self):
return not os.path.exists(self._upgradeFilePath)
@@ -86,72 +59,32 @@
self.log.debug("Upgrade %s successfully performed",
self._upgradeName)
- def _attachUpgradeLog(self):
- self._editOtherLoggers(logging.Logger.addHandler)
+ def _upgrade_argparser(self):
+ parser = argparse.ArgumentParser('vdsm-tool %s' % self._upgradeName)
+ parser.add_argument(
+ '--run-again',
+ dest='runAgain',
+ default=False,
+ action='store_true',
+ help='Run the upgrade again, even if it was ran before',
+ )
+ return parser
- def _detachUpgradeLog(self):
- self._editOtherLoggers(logging.Logger.removeHandler)
+ def run(self):
+ pass
- def _editOtherLoggers(self, edit):
- """
- add/remove upgrade handler to/from all non-upgrade loggers
- """
- loggers = dict(logging.Logger.manager.loggerDict.items() +
- [('root', logging.getLogger())])
- for name, logger in loggers.iteritems():
- if name != 'upgrade':
- for handler in logging.getLogger('upgrade').handlers:
- try:
- edit(logger, handler) # Call logger.edit(handler)
- except TypeError:
- pass
-
- def __enter__(self):
- """
- All logging will *also* be output to the upgrade log during
- the scope of this Upgrade.
- """
- self._attachUpgradeLog()
- return self
-
- def __exit__(self, type, value, traceback):
- self._detachUpgradeLog()
-
-
-def _parse_args(upgradeName):
- parser = argparse.ArgumentParser('vdsm-tool %s' % upgradeName)
- parser.add_argument(
- '--run-again',
- dest='runAgain',
- default=False,
- action='store_true',
- help='Run the upgrade again, even if it was ran before',
- )
- return parser.parse_args(sys.argv[2:])
-
-
-def upgrade(upgradeName):
- """
- Used as a decorator for upgrades. Runs the upgrade with an Upgrade
- context manager (documented above). Automatically calls isNeeded and seal
- as needed.
- """
- def decorator(f):
- @wraps(f)
- def wrapper(*args, **kwargs):
- with Upgrade(upgradeName) as upgrade:
- cliArguments = _parse_args(upgradeName)
- if cliArguments.runAgain or upgrade.isNeeded():
- upgrade.log.debug("Running upgrade %s", upgradeName)
- try:
- f(*args, **kwargs)
- except Exception:
- upgrade.log.exception("Failed to run %s",
- upgradeName)
- return 1
- else:
- upgrade.seal()
-
- return 0
- return wrapper
- return decorator
+ def apply(self):
+ res = self._arg_parser.parse_known_args(self._args)
+ self._parsed_ns = res[0]
+ self._parsed_args = res[1]
+ if self.isNeeded() or self._parsed_ns.runAgain:
+ self.log.debug("Running upgrade %s", self._upgradeName)
+ try:
+ self.run()
+ except Exception:
+ self.log.exception("Failed to run %s",
+ self._upgradeName)
+ return 1
+ else:
+ self.seal()
+ return 0
diff --git a/lib/vdsm/tool/upgrade_300_networks.py b/lib/vdsm/tool/upgrade_300_networks.py
index 95d4e17..250b04d 100644
--- a/lib/vdsm/tool/upgrade_300_networks.py
+++ b/lib/vdsm/tool/upgrade_300_networks.py
@@ -24,7 +24,7 @@
from vdsm import netinfo
from vdsm.constants import LEGACY_MANAGEMENT_NETWORKS
from vdsm.tool import expose
-from vdsm.tool.upgrade import upgrade
+from vdsm.tool.upgrade import Upgrade
sys.path.append("/usr/share/vdsm")
from network.configurators import ifcfg
@@ -42,7 +42,6 @@
return not managementNetwork() and managementBridge()
-@upgrade(UPGRADE_NAME)
def run(networks, bridges):
configWriter = ifcfg.ConfigWriter()
@@ -61,6 +60,18 @@
configWriter.removeLibvirtNetwork(network, skipBackup=True)
+class Upgrade300Networks(Upgrade):
+ def __init__(self, networks, bridges, *args):
+ Upgrade.__init__(self, *args)
+ self._networks = networks
+ self._bridges = bridges
+
+ def run(self):
+ if isNeeded(self._networks, self._bridges):
+ run(self._networks, self._bridges)
+ return 0
+
+
@expose(UPGRADE_NAME)
def upgrade_networks(*args):
"""
@@ -73,5 +84,4 @@
networks = netinfo.networks()
bridges = netinfo.bridges()
- if isNeeded(networks, bridges):
- run(networks, bridges)
+ return Upgrade300Networks(networks, bridges, *args).apply()
--
To view, visit http://gerrit.ovirt.org/27193
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6e1d28570dedfeff9fe60624b1db72d8cadf136a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Dima Kuznetsov <dkuznets(a)redhat.com>
9 years, 10 months
Change in vdsm[master]: Adding skiptests for LibvirtModuleConfigureTests
by ybronhei@redhat.com
Yaniv Bronhaim has uploaded a new change for review.
Change subject: Adding skiptests for LibvirtModuleConfigureTests
......................................................................
Adding skiptests for LibvirtModuleConfigureTests
We're getting repeated segmentation fault on jenkins job. Until solving
the issue, keeping branch tests stable.
Change-Id: I95cb5178af8f718dd3f0a1d72e74962a898983a6
Signed-off-by: Yaniv Bronhaim <ybronhei(a)redhat.com>
---
M tests/toolTests.py
1 file changed, 7 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/75/26775/1
diff --git a/tests/toolTests.py b/tests/toolTests.py
index 2fc8c61..86197ac 100644
--- a/tests/toolTests.py
+++ b/tests/toolTests.py
@@ -21,6 +21,7 @@
from vdsm import utils
import monkeypatch
from unittest import TestCase
+from nose.plugins.skip import SkipTest
import tempfile
import os
@@ -160,6 +161,9 @@
self.assertFalse(libvirtConfigure.isconfigured())
def testLibvirtConfigureToSSLTrue(self):
+ # skip test after getting repeated seg fault in jenkins jobs
+ raise SkipTest("Skipping failed test")
+
libvirtConfigure = configurator.LibvirtModuleConfigure(test_env)
self._setConfig('LCONF', 'empty')
self._setConfig('VDSM_CONF_FILE', 'withssl')
@@ -168,6 +172,9 @@
self.assertTrue(libvirtConfigure.isconfigured())
def testLibvirtConfigureToSSLFalse(self):
+ # skip test after getting repeated seg fault in jenkins jobs
+ raise SkipTest("Skipping failed test")
+
libvirtConfigure = configurator.LibvirtModuleConfigure(test_env)
self._setConfig('LCONF', 'empty')
self._setConfig('VDSM_CONF_FILE', 'withnossl')
--
To view, visit http://gerrit.ovirt.org/26775
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I95cb5178af8f718dd3f0a1d72e74962a898983a6
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Yaniv Bronhaim <ybronhei(a)redhat.com>
9 years, 10 months
Change in vdsm[master]: WIP virt: use (c)ElementTree to process XML
by fromani@redhat.com
Francesco Romani has uploaded a new change for review.
Change subject: WIP virt: use (c)ElementTree to process XML
......................................................................
WIP virt: use (c)ElementTree to process XML
this let the virt internal machinery to use (c)ElementTree
instead of minidom. The main driver is performance,
however a nice side effects is the API is a little bit nicer.
This patch is still very much Work In Progress and still
needs quite a lot of polishing and, most likely, to be
split up.
Change-Id: I7874026acf52b869b8329f433d5833530e0d02e0
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
---
M lib/vdsm/compat.py
M tests/vmTests.py
M vdsm/virt/vm.py
M vdsm/virt/xmldom.py
4 files changed, 226 insertions(+), 282 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/56/26856/1
diff --git a/lib/vdsm/compat.py b/lib/vdsm/compat.py
index 26c558e..a59a034 100644
--- a/lib/vdsm/compat.py
+++ b/lib/vdsm/compat.py
@@ -24,3 +24,10 @@
except ImportError: # py3
import pickle
pickle # yep, this is needed twice.
+
+try:
+ import xml.etree.cElementTree as ET
+ ET # make pyflakes happy
+except ImportError: # py3
+ import xml.etree.ElementTree as ET
+ ET # once again, needed twice.
diff --git a/tests/vmTests.py b/tests/vmTests.py
index d655286..20b1007 100644
--- a/tests/vmTests.py
+++ b/tests/vmTests.py
@@ -61,36 +61,43 @@
def assertXML(self, element, expectedXML, path=None):
if path is None:
- converted = element.toprettyxml()
+ converted = ET.tostring(element, encoding='utf-8', method='xml')
else:
- elem = ET.fromstring(element.toprettyxml())
- converted = re.sub(' />', '/>',
- ET.tostring(elem.find("./%s" % path)))
- self.assertEqual(re.sub('\n\s*', ' ', converted).strip(' '),
- re.sub('\n\s*', ' ', expectedXML).strip(' '))
+ converted = ET.tostring(element.find("./%s" % path))
+ self._assertEqualXML(converted, expectedXML)
- def assertXMLNone(self, element, path):
- elem = ET.fromstring(element.toprettyxml())
- converted = elem.find("./%s" % path)
- self.assertEqual(converted, None)
+ def _minimizeXML(self, xml):
+ xml = xml.strip()
+ xml = re.sub('\n\s*', ' ', xml)
+ xml = re.sub(' />', '/>', xml)
+ xml = re.sub('>\s*', '>', xml)
+ return xml
+
+ def _assertEqualXML(self, output, expected):
+ out = self._minimizeXML(output)
+ exp = self._minimizeXML(expected)
+ if out != exp:
+ for i, pair in enumerate(zip(out, exp)):
+ if pair[0] != pair[-1]:
+ caret = '%s^' % ('-' * i)
+ break
+ print out
+ print exp
+ print caret
+ self.assertEqual(out, exp)
def assertBuildCmdLine(self, confToDom):
- oldVdsmRun = constants.P_VDSM_RUN
- constants.P_VDSM_RUN = tempfile.mkdtemp()
- try:
- for conf, expectedXML in confToDom:
+ with namedTemporaryDir() as tmpDir:
+ with MonkeyPatchScope([(constants, 'P_VDSM_RUN', tmpDir + '/')]):
+ for conf, expectedXML in confToDom:
- expectedXML = expectedXML % conf
+ expectedXML = expectedXML % conf
- testVm = vm.Vm(self, conf)
+ testVm = vm.Vm(self, conf)
- output = testVm._buildCmdLine()
+ output = testVm._buildCmdLine()
- self.assertEqual(re.sub('\n\s*', ' ', output.strip(' ')),
- re.sub('\n\s*', ' ', expectedXML.strip(' ')))
- finally:
- shutil.rmtree(constants.P_VDSM_RUN)
- constants.P_VDSM_RUN = oldVdsmRun
+ self._assertEqualXML(output, expectedXML)
def testDomXML(self):
expectedXML = """
@@ -519,10 +526,11 @@
'custom': {'queues': '7'}}
self.conf['custom'] = {'vhost': 'ovirtmgmt:true', 'sndbuf': '0'}
iface = vm.NetworkInterfaceDevice(self.conf, self.log, **dev)
- originalBandwidth = iface.getXML().getElementsByTagName('bandwidth')[0]
+ originalBandwidth = iface.getXML().find('bandwidth')
self.assertXML(originalBandwidth, originalBwidthXML)
- self.assertXML(iface.paramsToBandwidthXML(NEW_OUT, originalBandwidth),
- updatedBwidthXML)
+ updatedBandwidth = iface.paramsToBandwidthXML(
+ NEW_OUT, originalBandwidth)
+ self.assertXML(updatedBandwidth, updatedBwidthXML)
def testControllerXML(self):
devConfs = [
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index a68f101..75924b3 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -484,7 +484,7 @@
ctrl = self.createXmlElem('controller', self.device,
['index', 'model', 'master', 'address'])
if self.device == 'virtio-serial':
- ctrl.setAttrs(index='0', ports='16')
+ xmldom.setattrs(ctrl, index='0', ports='16')
return ctrl
@@ -502,7 +502,7 @@
if 'ram' in self.specParams:
sourceAttrs['ram'] = self.specParams['ram']
- video.appendChildWithArgs('model', type=self.device, **sourceAttrs)
+ xmldom.appendElement(video, 'model', type=self.device, **sourceAttrs)
return video
@@ -514,7 +514,7 @@
Create domxml for sound device
"""
sound = self.createXmlElem('sound', None, ['address'])
- sound.setAttrs(model=self.device)
+ sound.set('model', self.device)
return sound
@@ -588,46 +588,48 @@
</interface>
"""
iface = self.createXmlElem('interface', self.device, ['address'])
- iface.appendChildWithArgs('mac', address=self.macAddr)
- iface.appendChildWithArgs('model', type=self.nicModel)
- iface.appendChildWithArgs('source', bridge=self.network)
+ xmldom.appendElement(iface, 'mac', address=self.macAddr)
+ xmldom.appendElement(iface, 'model', type=self.nicModel)
+ xmldom.appendElement(iface, 'source', bridge=self.network)
if hasattr(self, 'filter'):
- iface.appendChildWithArgs('filterref', filter=self.filter)
+ xmldom.appendElement(iface, 'filterref', filter=self.filter)
if hasattr(self, 'linkActive'):
- iface.appendChildWithArgs('link', state='up'
- if utils.tobool(self.linkActive)
- else 'down')
+ xmldom.appendElement(iface, 'link',
+ state='up'
+ if utils.tobool(self.linkActive)
+ else 'down')
if hasattr(self, 'bootOrder'):
- iface.appendChildWithArgs('boot', order=self.bootOrder)
+ xmldom.appendElement(iface, 'boot', order=self.bootOrder)
if self.driver:
- iface.appendChildWithArgs('driver', **self.driver)
+ xmldom.appendElement(iface, 'driver', self.driver)
if self.sndbufParam:
- tune = iface.appendChildWithArgs('tune')
- tune.appendChildWithArgs('sndbuf', text=self.sndbufParam)
+ tune = xmldom.appendElement(iface, 'tune')
+ xmldom.appendElement(tune, 'sndbuf').text=self.sndbufParam
if hasattr(self, 'specParams'):
if 'inbound' in self.specParams or 'outbound' in self.specParams:
- iface.appendChild(self.paramsToBandwidthXML(self.specParams))
+ iface.append(self.paramsToBandwidthXML(self.specParams))
return iface
def paramsToBandwidthXML(self, specParams, oldBandwidth=None):
"""Returns a valid libvirt xml dom element object."""
bandwidth = self.createXmlElem('bandwidth', None)
- old = {} if oldBandwidth is None else dict(
- (elem.nodeName, elem) for elem in oldBandwidth.childNodes)
+ if oldBandwidth is None:
+ oldBandwidth = xmldom.Element('bandwidth')
for key in ('inbound', 'outbound'):
elem = specParams.get(key)
if elem is None: # Use the old setting if present
- if key in old:
- bandwidth.appendChild(old[key])
+ value = oldBandwidth.find(key)
+ if value is not None:
+ bandwidth.append(value)
elif elem:
# Convert the values to string for adding them to the XML def
attrs = dict((key, str(value)) for key, value in elem.items())
- bandwidth.appendChildWithArgs(key, **attrs)
+ xmldom.appendElement(bandwidth, key, attrs)
return bandwidth
@@ -836,12 +838,13 @@
# when libvirt will support shared leases this will loop over all the
# volumes
for volInfo in self.volumeChain[-1:]:
- lease = xmldom.XMLElement('lease')
- lease.appendChildWithArgs('key', text=volInfo['volumeID'])
- lease.appendChildWithArgs('lockspace',
- text=volInfo['domainID'])
- lease.appendChildWithArgs('target', path=volInfo['leasePath'],
- offset=str(volInfo['leaseOffset']))
+ lease = xmldom.Element('lease')
+ xmldom.appendElement(lease, 'key').text=volInfo['volumeID']
+ xmldom.appendElement(lease, 'lockspace').text=\
+ text=volInfo['domainID']
+ xmldom.appendElement(lease, 'target',
+ path=volInfo['leasePath'],
+ offset=str(volInfo['leaseOffset']))
yield lease
def getXML(self):
@@ -857,42 +860,43 @@
"""
self.device = getattr(self, 'device', 'disk')
- source = xmldom.XMLElement('source')
+ source = xmldom.Element('source')
if self.blockDev:
deviceType = 'block'
- source.setAttrs(dev=self.path)
+ source.set('dev', self.path)
elif self.networkDev:
deviceType = 'network'
- source.setAttrs(protocol=self.volumeInfo['protocol'],
+ xmldom.setattrs(source,
+ protocol=self.volumeInfo['protocol'],
name=self.volumeInfo['path'])
hostAttrs = {'name': self.volumeInfo['volfileServer'],
'port': self.volumeInfo['volPort'],
'transport': self.volumeInfo['volTransport']}
- source.appendChildWithArgs('host', **hostAttrs)
+ xmldom.appendElement(source, 'host', hostAttrs)
else:
deviceType = 'file'
sourceAttrs = {'file': self.path}
if self.device == 'cdrom' or self.device == 'floppy':
sourceAttrs['startupPolicy'] = 'optional'
- source.setAttrs(**sourceAttrs)
+ xmldom.setattrs(source, sourceAttrs)
diskelem = self.createXmlElem('disk', deviceType,
['device', 'address', 'sgio'])
- diskelem.setAttrs(snapshot='no')
- diskelem.appendChild(source)
+ diskelem.set('snapshot', 'no')
+ diskelem.append(source)
targetAttrs = {'dev': self.name}
if self.iface:
targetAttrs['bus'] = self.iface
- diskelem.appendChildWithArgs('target', **targetAttrs)
+ xmldom.appendElement(diskelem, 'target', targetAttrs)
if self.extSharedState == DRIVE_SHARED_TYPE.SHARED:
- diskelem.appendChildWithArgs('shareable')
+ xmldom.appendElement(diskelem, 'shareable')
if hasattr(self, 'readonly') and utils.tobool(self.readonly):
- diskelem.appendChildWithArgs('readonly')
+ xmldom.appendElement(diskelem, 'readonly')
if hasattr(self, 'serial'):
- diskelem.appendChildWithArgs('serial', text=self.serial)
+ xmldom.appendElement(diskelem, 'serial').text=self.serial
if hasattr(self, 'bootOrder'):
- diskelem.appendChildWithArgs('boot', order=self.bootOrder)
+ xmldom.appendElement(diskelem, 'boot', order=self.bootOrder)
if self.device != 'lun' and hasattr(self, 'sgio'):
raise ValueError("sgio attribute can be set only for LUN devices")
@@ -918,19 +922,18 @@
driverAttrs['error_policy'] = 'enospace'
else:
driverAttrs['error_policy'] = 'stop'
- diskelem.appendChildWithArgs('driver', **driverAttrs)
+ xmldom.appendElement(diskelem, 'driver', driverAttrs)
elif self.device == 'floppy':
if (self.path and
not utils.getUserPermissions(constants.QEMU_PROCESS_USER,
self.path)['write']):
- diskelem.appendChildWithArgs('readonly')
+ xmldom.appendElement(diskelem, 'readonly')
if hasattr(self, 'specParams') and 'ioTune' in self.specParams:
self._validateIoTuneParams()
- iotune = xmldom.XMLElement('iotune')
+ iotune = xmldom.appendElement(diskelem, 'iotune')
for key, value in self.specParams['ioTune'].iteritems():
- iotune.appendChildWithArgs(key, text=str(value))
- diskelem.appendChild(iotune)
+ xmldom.appendElement(iotune, key).text=str(value)
return diskelem
@@ -947,9 +950,8 @@
function='0x0'/>
</memballoon>
"""
- m = self.createXmlElem(self.device, None, ['address'])
- m.setAttrs(model=self.specParams['model'])
- return m
+ balloon = self.createXmlElem(self.device, None, ['address'])
+ return xmldom.setattrs(balloon, model=self.specParams['model'])
class WatchdogDevice(VmDevice):
@@ -970,10 +972,10 @@
function='0x0'/>
</watchdog>
"""
- m = self.createXmlElem(self.type, None, ['address'])
- m.setAttrs(model=self.specParams.get('model', 'i6300esb'),
- action=self.specParams.get('action', 'none'))
- return m
+ dev = self.createXmlElem(self.type, None, ['address'])
+ return xmldom.setattrs(dev,
+ model=self.specParams.get('model', 'i6300esb'),
+ action=self.specParams.get('action', 'none'))
class SmartCardDevice(VmDevice):
@@ -991,8 +993,7 @@
sourceAttrs = {'mode': self.specParams['mode']}
if sourceAttrs['mode'] != 'host':
sourceAttrs['type'] = self.specParams['type']
- card.setAttrs(**sourceAttrs)
- return card
+ return xmldom.setattrs(card, sourceAttrs)
class TpmDevice(VmDevice):
@@ -1009,11 +1010,11 @@
</tpm>
"""
tpm = self.createXmlElem(self.device, None)
- tpm.setAttrs(model=self.specParams['model'])
- backend = tpm.appendChildWithArgs('backend',
+ tpm.set('model', self.specParams['model'])
+ backend = xmldom.appendElement(tpm, 'backend',
type=self.specParams['mode'])
- backend.appendChildWithArgs('device',
- path=self.specParams['path'])
+ xmldom.appendElement(backend, 'device',
+ path=self.specParams['path'])
return tpm
@@ -1047,12 +1048,11 @@
if 'period' in self.specParams:
rateAttrs['period'] = self.specParams['period']
- rng.appendChildWithArgs('rate', None, **rateAttrs)
+ xmldom.appendElement(rng, 'rate', rateAttrs)
# <backend... /> element
- rng.appendChildWithArgs('backend',
- caps.RNG_SOURCES[self.specParams['source']],
- model='random')
+ xmldom.appendElement(rng, 'backend', model='random').text=\
+ caps.RNG_SOURCES[self.specParams['source']]
return rng
@@ -1065,12 +1065,12 @@
Create domxml for a console device.
<console type='pty'>
- <target type='virtio' port='0'/>
+ <target type='irtio' port='0'/>
</console>
"""
- m = self.createXmlElem('console', 'pty')
- m.appendChildWithArgs('target', type='virtio', port='0')
- return m
+ console = self.createXmlElem('console', 'pty')
+ xmldom.appendElement(console, 'target', type='virtio', port='0')
+ return console
class MigrationError(Exception):
@@ -2134,14 +2134,15 @@
for devType in self._devices:
for dev in self._devices[devType]:
- deviceXML = dev.getXML().toxml(encoding='utf-8')
+ xmlDev = dev.getXML()
+ deviceXML = dev.toXML()
if getattr(dev, "custom", {}):
deviceXML = hooks.before_device_create(
deviceXML, self.conf, dev.custom)
dev._deviceXML = deviceXML
- domxml._devices.appendChild(xmldom.parse(deviceXML).firstChild)
+ domxml._devices.append(xmlDev)
def _buildCmdLine(self):
domxml = xmldom._DomXML(self.conf, self.log, self.arch)
@@ -2550,24 +2551,22 @@
def setLinkAndNetwork(self, dev, conf, linkValue, networkValue, custom,
specParams=None):
vnicXML = dev.getXML()
- source = vnicXML.getElementsByTagName('source')[0]
- source.setAttribute('bridge', networkValue)
- try:
- link = vnicXML.getElementsByTagName('link')[0]
- except IndexError:
- link = xmldom.XMLElement('link')
- vnicXML.appendChildWithArgs(link)
- link.setAttribute('state', linkValue)
+ source = vnicXML.find('source')
+ source.set('bridge', networkValue)
+ link = vnicXML.find('link')
+ if link is None:
+ link = xmldom.appendElement(vnicXML, 'link')
+ link.set('state', linkValue)
if (specParams and
('inbound' in specParams or 'outbound' in specParams)):
- oldBandwidths = vnicXML.getElementsByTagName('bandwidth')
- oldBandwidth = oldBandwidths[0] if len(oldBandwidths) else None
+ oldBandwidth = vnicXML.find('bandwidth')
newBandwidth = dev.paramsToBandwidthXML(specParams, oldBandwidth)
if oldBandwidth is None:
- vnicXML.appendChild(newBandwidth)
+ vnicXML.append(newBandwidth)
else:
- vnicXML.replaceChild(newBandwidth, oldBandwidth)
- vnicStrXML = vnicXML.toprettyxml(encoding='utf-8')
+ vnicXML.remove(oldBandwidth)
+ vnicXML.append(newBandwidth)
+ vnicStrXML = vnicXML.toXML()
try:
try:
vnicStrXML = hooks.before_update_device(vnicStrXML, self.conf,
@@ -2586,7 +2585,7 @@
# Rollback link and network.
self.log.debug('Rolling back link and net for: %s', dev.alias,
exc_info=True)
- self._dom.updateDeviceFlags(vnicXML.toxml(encoding='utf-8'),
+ self._dom.updateDeviceFlags(vnicXML.toXML(),
libvirt.VIR_DOMAIN_AFFECT_LIVE)
raise
else:
diff --git a/vdsm/virt/xmldom.py b/vdsm/virt/xmldom.py
index ea1387c..e15c2ca 100644
--- a/vdsm/virt/xmldom.py
+++ b/vdsm/virt/xmldom.py
@@ -25,6 +25,7 @@
import xml.dom.minidom
# vdsm imports
+from vdsm.compat import ET
from vdsm import constants
from vdsm import netinfo
from vdsm import utils
@@ -32,6 +33,10 @@
# local imports
# In future those should be imported via ..
import caps
+
+
+Element = ET.Element # FIXME
+appendElement = ET.SubElement
def is_node(xmlNode):
@@ -71,34 +76,6 @@
return self._hash or '0'
-class XMLElement(object):
-
- def __init__(self, tagName, text=None, **attrs):
- self._elem = xml.dom.minidom.Document().createElement(tagName)
- self.setAttrs(**attrs)
- if text is not None:
- self.appendTextNode(text)
-
- def __getattr__(self, name):
- return getattr(self._elem, name)
-
- def setAttrs(self, **attrs):
- for attrName, attrValue in attrs.iteritems():
- self._elem.setAttribute(attrName, attrValue)
-
- def appendTextNode(self, text):
- textNode = xml.dom.minidom.Document().createTextNode(text)
- self._elem.appendChild(textNode)
-
- def appendChild(self, element):
- self._elem.appendChild(element)
-
- def appendChildWithArgs(self, childName, text=None, **attrs):
- child = XMLElement(childName, text, **attrs)
- self._elem.appendChild(child)
- return child
-
-
class _DomXML:
def __init__(self, conf, log, arch):
"""
@@ -123,8 +100,6 @@
self.arch = arch
- self.doc = xml.dom.minidom.Document()
-
if utils.tobool(self.conf.get('kvmEnable', 'true')):
domainType = 'kvm'
else:
@@ -140,29 +115,22 @@
domainAttrs['xmlns:qemu'] = \
'http://libvirt.org/schemas/domain/qemu/1.0'
- self.dom = XMLElement('domain', **domainAttrs)
- self.doc.appendChild(self.dom)
-
- self.dom.appendChildWithArgs('name', text=self.conf['vmName'])
- self.dom.appendChildWithArgs('uuid', text=self.conf['vmId'])
+ self.dom = ET.Element('domain', domainAttrs)
+ appendElement(self.dom, 'name').text=self.conf['vmName']
+ appendElement(self.dom, 'uuid').text=self.conf['vmId']
memSizeKB = str(int(self.conf.get('memSize', '256')) * 1024)
- self.dom.appendChildWithArgs('memory', text=memSizeKB)
- self.dom.appendChildWithArgs('currentMemory', text=memSizeKB)
- vcpu = self.dom.appendChildWithArgs('vcpu', text=self._getMaxVCpus())
- vcpu.setAttrs(**{'current': self._getSmp()})
+ appendElement(self.dom, 'memory').text=memSizeKB
+ appendElement(self.dom, 'currentMemory').text=memSizeKB
+ appendElement(self.dom, 'vcpu', current=self._getSmp()).text=self._getMaxVCpus()
memSizeGuaranteedKB = str(1024 * int(
self.conf.get('memGuaranteedSize', '0')
))
- memtune = XMLElement('memtune')
- self.dom.appendChild(memtune)
+ memtune = appendElement(self.dom, 'memtune')
+ appendElement(memtune, 'min_guarantee').text=memSizeGuaranteedKB
- memtune.appendChildWithArgs('min_guarantee',
- text=memSizeGuaranteedKB)
-
- self._devices = XMLElement('devices')
- self.dom.appendChild(self._devices)
+ self._devices = appendElement(self.dom, 'devices')
def appendClock(self):
"""
@@ -173,15 +141,13 @@
</clock>
"""
- m = XMLElement('clock', offset='variable',
- adjustment=str(self.conf.get('timeOffset', 0)))
- m.appendChildWithArgs('timer', name='rtc', tickpolicy='catchup')
- m.appendChildWithArgs('timer', name='pit', tickpolicy='delay')
-
+ clock = appendElement(self.dom, 'clock',
+ offset='variable',
+ adjustment=str(self.conf.get('timeOffset', 0)))
+ appendElement(clock, 'timer', name='rtc', tickpolicy='catchup')
+ appendElement(clock, 'timer', name='pit', tickpolicy='delay')
if self.arch == caps.Architecture.X86_64:
- m.appendChildWithArgs('timer', name='hpet', present='no')
-
- self.dom.appendChild(m)
+ appendElement(clock, 'timer', name='hpet', present='no')
def appendOs(self):
"""
@@ -197,35 +163,33 @@
</os>
"""
- oselem = XMLElement('os')
- self.dom.appendChild(oselem)
+ os = appendElement(self.dom, 'os')
DEFAULT_MACHINES = {caps.Architecture.X86_64: 'pc',
caps.Architecture.PPC64: 'pseries'}
machine = self.conf.get('emulatedMachine', DEFAULT_MACHINES[self.arch])
- oselem.appendChildWithArgs('type', text='hvm', arch=self.arch,
- machine=machine)
+ appendElement(os, 'type', arch=self.arch, machine=machine).text='hvm'
qemu2libvirtBoot = {'a': 'fd', 'c': 'hd', 'd': 'cdrom', 'n': 'network'}
for c in self.conf.get('boot', ''):
- oselem.appendChildWithArgs('boot', dev=qemu2libvirtBoot[c])
+ appendElement(os, 'boot', dev=qemu2libvirtBoot[c])
if self.conf.get('initrd'):
- oselem.appendChildWithArgs('initrd', text=self.conf['initrd'])
+ appendElement(os, 'initrd').text=self.conf['initrd']
if self.conf.get('kernel'):
- oselem.appendChildWithArgs('kernel', text=self.conf['kernel'])
+ appendElement(os, 'kernel').text=self.conf['kernel']
if self.conf.get('kernelArgs'):
- oselem.appendChildWithArgs('cmdline', text=self.conf['kernelArgs'])
+ appendElement(os, 'cmdline').text=self.conf['kernelArgs']
if self.arch == caps.Architecture.X86_64:
- oselem.appendChildWithArgs('smbios', mode='sysinfo')
+ appendElement(os, 'smbios', mode='sysinfo')
if utils.tobool(self.conf.get('bootMenuEnable', False)):
- oselem.appendChildWithArgs('bootmenu', enable='yes')
+ appendElement(os, 'bootmenu', enable='yes')
def appendSysinfo(self, osname, osversion, serialNumber):
"""
@@ -246,20 +210,15 @@
</sysinfo>
"""
- sysinfoelem = XMLElement('sysinfo', type='smbios')
- self.dom.appendChild(sysinfoelem)
+ sysinfo = appendElement(self.dom, 'sysinfo', type='smbios')
+ syselem = appendElement(sysinfo, 'system')
- syselem = XMLElement('system')
- sysinfoelem.appendChild(syselem)
-
- def appendEntry(k, v):
- syselem.appendChildWithArgs('entry', text=v, name=k)
-
- appendEntry('manufacturer', constants.SMBIOS_MANUFACTURER)
- appendEntry('product', osname)
- appendEntry('version', osversion)
- appendEntry('serial', serialNumber)
- appendEntry('uuid', self.conf['vmId'])
+ appendElement(syselem, 'entry', name='manufacturer').text=\
+ constants.SMBIOS_MANUFACTURER
+ appendElement(syselem, 'entry', name='product').text=osname
+ appendElement(syselem, 'entry', name='version').text=osversion
+ appendElement(syselem, 'entry', name='serial').text=serialNumber
+ appendElement(syselem, 'entry', name='uuid').text=self.conf['vmId']
def appendFeatures(self):
"""
@@ -272,8 +231,8 @@
"""
if utils.tobool(self.conf.get('acpiEnable', 'true')):
- features = self.dom.appendChildWithArgs('features')
- features.appendChildWithArgs('acpi')
+ features = appendElement(self.dom, 'features')
+ appendElement(features, 'acpi')
def appendCpu(self):
"""
@@ -287,20 +246,20 @@
</cpu>
"""
- cpu = XMLElement('cpu')
+ cpu = ET.Element('cpu')
- if self.arch in (caps.Architecture.X86_64):
- cpu.setAttrs(match='exact')
+ if self.arch == caps.Architecture.X86_64:
+ cpu.set('match', 'exact')
features = self.conf.get('cpuType', 'qemu64').split(',')
model = features[0]
if model == 'hostPassthrough':
- cpu.setAttrs(mode='host-passthrough')
+ cpu.set('mode', 'host-passthrough')
elif model == 'hostModel':
- cpu.setAttrs(mode='host-model')
+ cpu.set('mode', 'host-model')
else:
- cpu.appendChildWithArgs('model', text=model)
+ appendElement(cpu, 'model').text=model
# This hack is for backward compatibility as the libvirt
# does not allow 'qemu64' guest on intel hardware
@@ -317,39 +276,39 @@
featureAttrs['policy'] = 'require'
elif feature[0] == '-':
featureAttrs['policy'] = 'disable'
- cpu.appendChildWithArgs('feature', **featureAttrs)
+
+ appendElement(cpu, 'feature', featureAttrs)
if ('smpCoresPerSocket' in self.conf or
'smpThreadsPerCore' in self.conf):
maxVCpus = int(self._getMaxVCpus())
cores = int(self.conf.get('smpCoresPerSocket', '1'))
threads = int(self.conf.get('smpThreadsPerCore', '1'))
- cpu.appendChildWithArgs('topology',
- sockets=str(maxVCpus / cores / threads),
- cores=str(cores), threads=str(threads))
+ appendElement(cpu, 'topology',
+ sockets=str(maxVCpus / cores / threads),
+ cores=str(cores), threads=str(threads))
# CPU-pinning support
# see http://www.ovirt.org/wiki/Features/Design/cpu-pinning
if 'cpuPinning' in self.conf:
- cputune = XMLElement('cputune')
+ cputune = appendElement(self.dom, 'cputune')
cpuPinning = self.conf.get('cpuPinning')
- for cpuPin in cpuPinning.keys():
- cputune.appendChildWithArgs('vcpupin', vcpu=cpuPin,
- cpuset=cpuPinning[cpuPin])
- self.dom.appendChild(cputune)
+ for vcpu, cpuset in cpuPinning.items():
+ appendElement(cputune, 'vcpupin',
+ vcpu=vcpu, cpuset=cpuset)
# Guest numa topology support
# see http://www.ovirt.org/Features/NUMA_and_Virtual_NUMA
if 'guestNumaNodes' in self.conf:
- numa = XMLElement('numa')
+ numa = appendElement(cpu, 'numa')
guestNumaNodes = self.conf.get('guestNumaNodes')
for vmCell in guestNumaNodes:
- numa.appendChildWithArgs('cell',
- cpus=vmCell['cpus'],
- memory=str(vmCell['memory']))
- cpu.appendChild(numa)
+ appendElement(numa, 'cell',
+ cpus=vmCell['cpus'],
+ memory=str(vmCell['memory']))
- self.dom.appendChild(cpu)
+ self.dom.append(cpu)
+
# Guest numatune support
def appendNumaTune(self):
@@ -363,12 +322,11 @@
if 'numaTune' in self.conf:
numaTune = self.conf.get('numaTune')
- if 'nodeset' in numaTune.keys():
+ if 'nodeset' in numaTune:
mode = numaTune.get('mode', 'strict')
- numatune = XMLElement('numatune')
- numatune.appendChildWithArgs('memory', mode=mode,
- nodeset=numaTune['nodeset'])
- self.dom.appendChild(numatune)
+ numatune = appendElement(self.dom, 'numatune')
+ appendElement(numatune, 'memory',
+ mode=mode, nodeset=numaTune['nodeset'])
def _appendAgentDevice(self, path, name):
"""
@@ -377,10 +335,9 @@
<source mode='bind' path='/tmp/socket'/>
</channel>
"""
- channel = XMLElement('channel', type='unix')
- channel.appendChildWithArgs('target', type='virtio', name=name)
- channel.appendChildWithArgs('source', mode='bind', path=path)
- self._devices.appendChild(channel)
+ channel = appendElement(self._devices, 'channel', type='unix')
+ appendElement(channel, 'target', type='virtio', name=name)
+ appendElement(channel, 'source', mode='bind', path=path)
def appendInput(self):
"""
@@ -397,7 +354,7 @@
mouseBus = 'ps2'
inputAttrs = {'type': 'mouse', 'bus': mouseBus}
- self._devices.appendChildWithArgs('input', **inputAttrs)
+ appendElement(self._devices, 'input', inputAttrs)
def appendKeyboardDevice(self):
"""
@@ -409,10 +366,9 @@
<qemu:arg value='keyboard'/>
</qemu:commandline>
"""
- commandLine = XMLElement('qemu:commandline')
- commandLine.appendChildWithArgs('qemu:arg', value='-usbdevice')
- commandLine.appendChildWithArgs('qemu:arg', value='keyboard')
- self.dom.appendChild(commandLine)
+ commandLine = appendElement(self.dom, 'qemu:commandline')
+ appendElement(commandLine, 'qemu:arg', value='-usbdevice')
+ appendElement(commandLine, 'qemu:arg', value='keyboard')
def appendGraphics(self):
"""
@@ -442,43 +398,56 @@
graphicsAttrs['passwd'] = '*****'
graphicsAttrs['passwdValidTo'] = '1970-01-01T00:00:01'
- graphics = XMLElement('graphics', **graphicsAttrs)
+ graphics = appendElement(self._devices, 'graphics', graphicsAttrs)
if 'qxl' in self.conf['display']:
if self.conf.get('spiceSecureChannels'):
for channel in self.conf['spiceSecureChannels'].split(','):
- graphics.appendChildWithArgs('channel', name=channel[1:],
- mode='secure')
+ appendElement(graphics, 'channel',
+ name=channel[1:], mode='secure')
- vmc = XMLElement('channel', type='spicevmc')
- vmc.appendChildWithArgs('target', type='virtio',
- name='com.redhat.spice.0')
- self._devices.appendChild(vmc)
+ vmc = appendElement(self._devices, 'channel', type='spicevmc')
+ appendElement(vmc, 'target',
+ type='virtio', name='com.redhat.spice.0')
if self.conf.get('displayNetwork'):
- graphics.appendChildWithArgs('listen', type='network',
- network=netinfo.LIBVIRT_NET_PREFIX +
- self.conf.get('displayNetwork'))
+ appendElement(graphics, 'listen',
+ type='network',
+ network=netinfo.LIBVIRT_NET_PREFIX +
+ self.conf.get('displayNetwork'))
else:
- graphics.setAttrs(listen='0')
-
- self._devices.appendChild(graphics)
+ graphics.set('listen', '0')
def appendEmulator(self):
- emulatorPath = '/usr/bin/qemu-system-' + self.arch
+ appendElement(self._devices, 'emulator').text=\
+ '/usr/bin/qemu-system-%s' % self.arch
- emulator = XMLElement('emulator', text=emulatorPath)
-
- self._devices.appendChild(emulator)
+ def appendDevice(self, dev):
+ self._devices.append(dev.getXML())
def toxml(self):
- return self.doc.toprettyxml(encoding='utf-8')
+ # FIXME
+ return '<?xml version="1.0" encoding="utf-8"?>' + \
+ tostring(self.dom)
def _getSmp(self):
return self.conf.get('smp', '1')
def _getMaxVCpus(self):
return self.conf.get('maxVCpus', self._getSmp())
+
+
+def tostring(element):
+ return ET.tostring(element, encoding='utf-8', method='xml')
+
+
+def setattrs(element, attrs=None, **kwargs):
+ if attrs is None:
+ attrs = {}
+ attrs.update(kwargs)
+ for attrName, attrValue in attrs.items():
+ element.set(attrName, attrValue)
+ return element
class XMLRepresentable(object):
@@ -488,10 +457,10 @@
Create domxml device element according to passed in params
"""
elemAttrs = {}
- element = XMLElement(elemType)
+ element = ET.Element(elemType)
if deviceType:
- elemAttrs['type'] = deviceType
+ element.set('type', deviceType)
for attrName in attributes:
if not hasattr(self, attrName):
@@ -499,11 +468,10 @@
attr = getattr(self, attrName)
if isinstance(attr, dict):
- element.appendChildWithArgs(attrName, **attr)
+ ET.SubElement(element, attrName, attr)
else:
- elemAttrs[attrName] = attr
+ element.set(attrName, attr)
- element.setAttrs(**elemAttrs)
return element
def getXML(self):
@@ -512,43 +480,5 @@
"""
return self.createXmlElem(self.type, self.device, ['address'])
-
-# A little unrelated hack to make xml.dom.minidom.Document.toprettyxml()
-# not wrap Text node with whitespace.
-# until http://bugs.python.org/issue4147 is accepted
-def __hacked_writexml(self, writer, indent="", addindent="", newl=""):
-
- # copied from xml.dom.minidom.Element.writexml and hacked not to wrap Text
- # nodes with whitespace.
-
- # indent = current indentation
- # addindent = indentation to add to higher levels
- # newl = newline string
- writer.write(indent + "<" + self.tagName)
-
- attrs = self._get_attributes()
- a_names = attrs.keys()
- a_names.sort()
-
- for a_name in a_names:
- writer.write(" %s=\"" % a_name)
- # _write_data(writer, attrs[a_name].value) # replaced
- xml.dom.minidom._write_data(writer, attrs[a_name].value)
- writer.write("\"")
- if self.childNodes:
- # added special handling of Text nodes
- if (len(self.childNodes) == 1 and
- isinstance(self.childNodes[0], xml.dom.minidom.Text)):
- writer.write(">")
- self.childNodes[0].writexml(writer)
- writer.write("</%s>%s" % (self.tagName, newl))
- else:
- writer.write(">%s" % (newl))
- for node in self.childNodes:
- node.writexml(writer, indent + addindent, addindent, newl)
- writer.write("%s</%s>%s" % (indent, self.tagName, newl))
- else:
- writer.write("/>%s" % (newl))
-
-
-xml.dom.minidom.Element.writexml = __hacked_writexml
+ def toXML(self):
+ return tostring(self.getXML())
--
To view, visit http://gerrit.ovirt.org/26856
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7874026acf52b869b8329f433d5833530e0d02e0
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
9 years, 10 months
Change in vdsm[master]: utilsTests: Avoiding returning in the middle of the method
by vvolansk@redhat.com
Vered Volansky has uploaded a new change for review.
Change subject: utilsTests: Avoiding returning in the middle of the method
......................................................................
utilsTests: Avoiding returning in the middle of the method
In RollbackContextTest there are some tests which returns in the first
except. This patch avoids that.
Change-Id: I877f65569f4304bdd4160bb9f84facf261e568e8
Signed-off-by: Vered Volansky <vvolansk(a)redhat.com>
---
M tests/utilsTests.py
1 file changed, 7 insertions(+), 9 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/86/22886/1
diff --git a/tests/utilsTests.py b/tests/utilsTests.py
index bf27f30..7ce15dc 100644
--- a/tests/utilsTests.py
+++ b/tests/utilsTests.py
@@ -334,9 +334,8 @@
rollback.prependDefer(self._callDef)
except Exception:
self.assertEquals(self._called, 2)
- return
-
- self.fail("Exception was not raised")
+ else:
+ self.fail("Exception was not raised")
def testFirstException(self):
"""
@@ -353,11 +352,10 @@
rollback.prependDefer(self._callDef)
except RuntimeError:
self.assertEquals(self._called, 3)
- return
except Exception:
self.fail("Wrong exception was raised")
-
- self.fail("Exception was not raised")
+ else:
+ self.fail("Exception was not raised")
def testKeyErrorException(self):
"""
@@ -368,8 +366,8 @@
with utils.RollbackContext():
{}['aKey']
except KeyError:
- return
+ pass
except Exception:
self.fail("Wrong exception was raised")
-
- self.fail("Exception was not raised")
+ else:
+ self.fail("Exception was not raised")
--
To view, visit http://gerrit.ovirt.org/22886
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I877f65569f4304bdd4160bb9f84facf261e568e8
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Vered Volansky <vvolansk(a)redhat.com>
9 years, 10 months
Change in vdsm[master]: Tests: log actual exceptions in RollbackContext
by vvolansk@redhat.com
Vered Volansky has uploaded a new change for review.
Change subject: Tests: log actual exceptions in RollbackContext
......................................................................
Tests: log actual exceptions in RollbackContext
When a wrong exception is thrown, the alert to this fact now contains
the actual exception that's been raised.
Change-Id: I3e8244f2b6ede47967025eb35e54ee2401fec30b
Signed-off-by: Vered Volansky <vvolansk(a)redhat.com>
---
M tests/utilsTests.py
1 file changed, 6 insertions(+), 6 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/75/28175/1
diff --git a/tests/utilsTests.py b/tests/utilsTests.py
index b799ee9..a7bfd60 100644
--- a/tests/utilsTests.py
+++ b/tests/utilsTests.py
@@ -407,8 +407,8 @@
except RuntimeError:
self.assertEquals(self._called, 3)
return
- except Exception:
- self.fail("Wrong exception was raised")
+ except Exception as e:
+ self.fail("Wrong exception was raised - %s" % e)
self.fail("Exception was not raised")
@@ -422,8 +422,8 @@
{}['aKey']
except KeyError:
pass
- except Exception:
- self.fail("Wrong exception was raised")
+ except Exception as e:
+ self.fail("Wrong exception was raised - %s" % e)
else:
self.fail("Exception was not raised")
@@ -444,8 +444,8 @@
except self.UndoException:
self.fail("Wrong exception was raised - from undo function. \
should have re-raised OriginalException")
- except Exception:
- self.fail("Wrong exception was raised")
+ except Exception as e:
+ self.fail("Wrong exception was raised - %s" % e)
else:
self.fail("Exception was not raised")
--
To view, visit http://gerrit.ovirt.org/28175
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3e8244f2b6ede47967025eb35e54ee2401fec30b
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Vered Volansky <vvolansk(a)redhat.com>
9 years, 10 months
Change in vdsm[master]: vm: add optimizations for hyperv
by fromani@redhat.com
Francesco Romani has uploaded a new change for review.
Change subject: vm: add optimizations for hyperv
......................................................................
vm: add optimizations for hyperv
This patch adds support for hyperv optimizations.
The optimizations are both for stability and for performance.
Engine, or any other client, can enable them by supplying a new
optional parameter 'machineType' in the Vm parameters at
creation time.
As default, the new settings are disabled for backward compatibility.
The parameters are hardcoded and not externally configurable
because they are not supposed to be changed very often, if
changed at all; moreover, this patch already implements
the optimal recommended settings.
Change-Id: I28ea1d5adeda07798255484209e1a1d92c2c2bc5
Bug-Url: https://bugzilla.redhat.com/1083529
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
---
M tests/vmTests.py
M vdsm/virt/vm.py
M vdsm_api/vdsmapi-schema.json
3 files changed, 70 insertions(+), 3 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/19/27619/1
diff --git a/tests/vmTests.py b/tests/vmTests.py
index 1dd75ae..b64f041 100644
--- a/tests/vmTests.py
+++ b/tests/vmTests.py
@@ -264,6 +264,23 @@
domxml.appendFeatures()
self.assertXML(domxml.dom, featuresXML, 'features')
+ def testFeaturesHyperVXML(self):
+ featuresXML = """
+ <features>
+ <acpi/>
+ <hyperv>
+ <relaxed state="on"/>
+ <vapic state="on"/>
+ <spinlocks retries="8191" state="on"/>
+ </hyperv>
+ </features>"""
+ conf = {'machineType': 'hyperv'}
+ conf.update(self.conf)
+ domxml = vm._DomXML(conf, self.log,
+ caps.Architecture.X86_64)
+ domxml.appendFeatures()
+ self.assertXML(domxml.dom, featuresXML, 'features')
+
def testSysinfoXML(self):
sysinfoXML = """
<sysinfo type="smbios">
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index f1c36f8..5f6b557 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -647,11 +647,37 @@
<features>
<acpi/>
<features/>
+
+ for hyperv:
+ <features>
+ <acpi/>
+ <hyperv>
+ <relaxed state='on'/>
+ <vapic state='on'/>
+ <spinlocks state='on' retries='8191'/>
+ </hyperv>
+ <features/>
"""
- if utils.tobool(self.conf.get('acpiEnable', 'true')):
+ if (utils.tobool(self.conf.get('acpiEnable', 'true')) or
+ self.conf.get('machineType') == MachineType.HYPERV):
features = self.dom.appendChildWithArgs('features')
+
+ if utils.tobool(self.conf.get('acpiEnable', 'true')):
features.appendChildWithArgs('acpi')
+
+ if self.conf.get('machineType') == MachineType.HYPERV:
+ hyperv = XMLElement('hyperv')
+ features.appendChild(hyperv)
+
+ hyperv.appendChildWithArgs('relaxed', state='on')
+ # turns off an internal Windows watchdog, and by doing so avoids
+ # some high load BSODs.
+ hyperv.appendChildWithArgs('vapic', state='on')
+ hyperv.appendChildWithArgs(
+ 'spinlocks', state='on', retries='8191')
+ # performance optimization flags, that can improve the performance
+ # by 10% to much more (in extreme cases of resources overcommit).
def appendCpu(self):
"""
@@ -1526,6 +1552,10 @@
pass
+class MachineType:
+ HYPERV = "hyperv"
+
+
class Vm(object):
"""
Used for abstracting communication between various parts of the
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index d134174..86883ff 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -898,6 +898,18 @@
{'enum': 'VmType', 'data': ['kvm']}
##
+# @MachineType:
+#
+# Enumeration of supported machine types, with
+# predefined optimized settings.
+#
+# @hyperv: Machine optimized for hyperv
+#
+# Since: 4.15.0
+##
+{'enum': 'MachineType', 'data': ['hyperv']}
+
+##
# @NetInfoNetworkMap:
#
# A mapping of vdsm Network information indexed by network name.
@@ -3131,6 +3143,9 @@
#
# @kvmEnable: Indicates if KVM hardware acceleration is enabled
#
+# @machineType: #optional Indicates the machine profile for the VM.
+# (new in version 4.15.0)
+#
# @maxVCpus: #optional Maximum number of CPU available for the guest
# It is the upper boundry for hot plug CPU action
#
@@ -3180,7 +3195,8 @@
'display': 'VmDisplayType', 'displayIp': 'str',
'displayPort': 'int', 'displaySecurePort': 'int',
'*emulatedMachine': 'str', '*keyboardLayout': 'str',
- 'kvmEnable': 'bool', '*maxVCpus': 'uint', 'memSize': 'uint',
+ 'kvmEnable': 'bool', '*machineType': 'MachineType',
+ '*maxVCpus': 'uint', 'memSize': 'uint',
'memGuaranteedSize': 'uint', 'nicModel': 'str', 'nice': 'int',
'*pauseCode': 'str', 'pid': 'uint', 'smp': 'uint', '*smpCoresPerSocket': 'uint',
'*smpThreadsPerCore': 'uint', 'status': 'VmStatus',
@@ -3209,6 +3225,9 @@
# @display: The type of display
#
# @kvmEnable: Indicates if KVM hardware acceleration is enabled
+#
+# @machineType: #optional Indicates the machine profile for the VM.
+# (new in version 4.15.0)
#
# @memSize: The amount of memory assigned to the VM in MB
#
@@ -3242,7 +3261,8 @@
{'type': 'VmParameters',
'data': {'acpiEnable': 'bool', '*bootMenuEnable': 'bool',
'*cpuShares': 'str', '*custom': 'StringMap', '*devices': ['VmDevice'],
- 'display': 'VmDisplayType', 'kvmEnable': 'bool', 'memSize': 'uint',
+ 'display': 'VmDisplayType', 'kvmEnable': 'bool',
+ '*machineType': 'MachineType', 'memSize': 'uint',
'nice': 'int', 'smp': 'uint', '*smpCoresPerSocket': 'uint',
'*smpThreadsPerCore': 'uint', 'timeOffset': 'uint',
'transparentHugePages': 'bool', 'vmId': 'UUID', 'vmName': 'str',
--
To view, visit http://gerrit.ovirt.org/27619
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I28ea1d5adeda07798255484209e1a1d92c2c2bc5
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
9 years, 10 months
Change in vdsm[master]: vdsm-upgrade: adds wrapper to ovirt-node-upgrade
by Douglas Schilling Landgraf
Douglas Schilling Landgraf has uploaded a new change for review.
Change subject: vdsm-upgrade: adds wrapper to ovirt-node-upgrade
......................................................................
vdsm-upgrade: adds wrapper to ovirt-node-upgrade
Currently ovirt-node provides ovirt-node-upgrade tool which
should replace vdsm-upgrade. This patch re-write vdsm-upgrade
as wrapper of ovirt-node-upgrade.
Change-Id: I7b997d70a440545497246d1a19d9671b054a56a5
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1079087
Signed-off-by: Douglas Schilling Landgraf <dougsland(a)redhat.com>
---
M vdsm.spec.in
M vdsm_reg/vdsm-upgrade
2 files changed, 54 insertions(+), 153 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/44/28244/1
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 35617ab..9c0e167 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -325,6 +325,7 @@
Requires: %{name} = %{version}-%{release}
Requires: m2crypto
Requires: openssl
+Requires: ovirt-node >= 3.0.4
%description reg
VDSM registration package. Used to register a Linux host to a Virtualization
diff --git a/vdsm_reg/vdsm-upgrade b/vdsm_reg/vdsm-upgrade
index d9bdd31..04967af 100755
--- a/vdsm_reg/vdsm-upgrade
+++ b/vdsm_reg/vdsm-upgrade
@@ -1,184 +1,84 @@
#!/usr/bin/python
+# -*- coding: utf-8 -*-
#
-# Copyright 2008 Red Hat, Inc. and/or its affiliates.
+# Copyright (C) 2008-2014 Red Hat, Inc.
#
# Licensed to you under the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version. See the files README and
# LICENSE_GPL_v2 which accompany this distribution.
#
-
-import errno
-import sys
-import os
import logging
-import logging.config
-from time import strftime
-from config import config
-import deployUtil
-from ovirtnode.install import Install
+import time
-VDSM_REG_CONF_FILE = '/etc/vdsm-reg/vdsm-reg.conf'
-VDSM_CONF_FILE = '/etc/vdsm/vdsm.conf'
-log_filename = '/var/log/vdsm-reg/vds_bootstrap_upgrade.'+strftime("%Y%m%d_%H%M%S")+'.log'
+from vdsm import utils
-try:
- logging.basicConfig(level=logging.DEBUG,
- format='%(asctime)s %(levelname)-8s %(message)s',
- datefmt='%a, %d %b %Y %H:%M:%S',
- filename=log_filename,
- filemode='w')
-except:
- log_filename = '/var/log/vds_bootstrap_upgrade.'+strftime("%Y%m%d_%H%M%S")+'.log'
- logging.basicConfig(level=logging.DEBUG,
- format='%(asctime)s %(levelname)-8s %(message)s',
- datefmt='%a, %d %b %Y %H:%M:%S',
- filename=log_filename,
- filemode='w')
-def setMountPoint(config):
- strFile = config.get('vars', 'upgrade_iso_file')
- strMountPoint = config.get('vars', 'upgrade_mount_point')
+class VdsmService(object):
+ def __init__(self):
+ self.cmd = ['vdsm-tool', '', 'vdsmd']
- try:
- fOK = True
- ret = None
- err = ""
- out = None
+ def start(self):
+ self.cmd[1] = "service-start"
+ return utils.execCmd(self.cmd, sudo=True, raw=True)
- #First look for the upgrade file
- if not os.path.exists(strFile):
- fOK = False
- msg = "<BSTRAP component='setMountPoint' status='FAIL' message='Upgrade file not found'/>"
- logging.error(msg)
- print (msg)
+ def stop(self):
+ self.cmd[1] = "service-stop"
+ return utils.execCmd(self.cmd, sudo=True, raw=True)
- #Now, check if we need to create a mount-point dir.
- if fOK and not os.path.exists(strMountPoint):
- try: os.mkdir(strMountPoint)
- except OSError as err:
- if err.errno != errno.EEXIST:
- fOK = False
+ def status(self):
+ self.cmd[1] = "service-status"
+ return utils.execCmd(self.cmd, sudo=True, raw=True)
- #Now, loop-mount the upgrade iso file.
- if not fOK:
- msg = "<BSTRAP component='setMountPoint' status='FAIL' message='Failed to create mount point: " + deployUtil.escapeXML(str(err)) + "'/>"
- print (msg)
- logging.error(msg)
- else:
- out, err, ret = deployUtil._logExec(["/bin/mount", "-o", "loop", strFile, strMountPoint])
- fOK = (ret != None and ret == 0)
-
- msg = ""
- if fOK:
- msg = "<BSTRAP component='setMountPoint' status='OK' message='Mount succeeded.'/>"
- logging.debug(msg)
- else:
- msg = "<BSTRAP component='setMountPoint' status='FAIL' message='Failed to mount ISO file: " + deployUtil.escapeXML(str(err)) + "'/>"
- logging.error(msg)
- print msg
- except Exception as e:
- fOK = False
- msg = "<BSTRAP component='setMountPoint' status='FAIL' message='setMountPoint exception: " + deployUtil.escapeXML(str(e)) + "'/>"
- logging.error(msg)
- print (msg)
-
- return fOK
-
-def doUpgrade(config):
- fReturn = True
-
- install = Install()
- if install.ovirt_boot_setup(reboot="Y"):
- msg = "<BSTRAP component='doUpgrade' status='OK' message='Upgrade Succeeded. Rebooting'/>"
- print (msg)
- logging.debug(msg)
- else:
- msg = "<BSTRAP component='doUpgrade' status='FAIL' message='Upgrade Failed!'/>"
- print (msg)
- logging.error(msg)
- fReturn = False
-
- return fReturn
-
-def umount(config, shouldReport=True):
- out = None
- err = None
- ret = None
- fReturn = True
-
- strMountPoint = config.get('vars', 'upgrade_mount_point')
-
- if os.path.exists(strMountPoint):
- out, err, ret = deployUtil._logExec(["/bin/umount", strMountPoint])
- fReturn = (ret != None and ret == 0)
-
- if fReturn:
- msg = "<BSTRAP component='umount' status='OK' message='umount Succeeded'/>"
- else:
- msg = "<BSTRAP component='umount' status='FAIL' message=' " + deployUtil.escapeXML(str(err)) + "'/>"
-
- if shouldReport:
- print (msg)
-
- logging.debug(msg)
- return fReturn
def main():
- """Usage: vdsm-upgrade """
- fOK = True
- fMounted = False
+ _log_file = '/var/log/vdsm-reg/vds_bootstrap_upgrade.' + \
+ time.strftime("%Y%m%d_%H%M%S")+'.log'
- # Checking the current status of vdsm
- out, err, ret = deployUtil.setService('vdsmd', 'status')
- if ret == 0:
- # Stop vdsm to avoid communication with Engine before the reboot happens
- out, err, ret = deployUtil.setService('vdsmd', 'stop')
- if ret != 0:
+ logging.basicConfig(
+ level=logging.DEBUG,
+ format='%(asctime)s %(levelname)-8s %(message)s',
+ datefmt='%a, %d %b %Y %H:%M:%S',
+ filename=_log_file,
+ filemode='w'
+ )
+
+ vdsm_service = VdsmService()
+
+ rc, out, err = vdsm_service.status()
+ if rc == 0:
+ rc, out, err = vdsm_service.stop()
+ if rc != 0:
msg = "<BSTRAP component='RHEL_INSTALL' status='FAIL'" \
- " message='Cannot stop vdsm daemon before we" \
- " start the upgrade, please verify!'/>"
+ " message='Cannot stop vdsm daemon before we" \
+ " start the upgrade, please verify!'/>"
else:
msg = "<BSTRAP component='RHEL_INSTALL' status='OK'" \
- " message='vdsm daemon stopped for upgrade process!'/>"
-
+ " message='vdsm daemon stopped for upgrade process!'/>"
else:
msg = "<BSTRAP component='RHEL_INSTALL' status='WARN'" \
- " message='vdsm daemon is already down before we" \
- " stop it for upgrade.'/>"
-
+ " message='vdsm daemon is already down before we" \
+ " stop it for upgrade.'/>"
logging.debug(msg)
print(msg)
- try:
- config.read(VDSM_REG_CONF_FILE)
+ if rc == 0:
+ cmd = [
+ 'ovirt-node-upgrade',
+ '--iso',
+ '/data/updates/ovirt-node-iso-image.iso',
+ '--reboot=1'
+ ]
- #First, quietly try to clean any previous problems.
- umount(config, False)
+ rc, out, err = utils.execCmd(cmd, sudo=True, raw=True)
+ if rc != 0:
+ msg = "<BSTRAP component='RHEV_INSTALL' status='FAIL'/>"
+ else:
+ msg = "<BSTRAP component='RHEV_INSTALL' status='OK'/>"
- #Now: Try mounting
- fOK = setMountPoint(config)
- if fOK:
- fMounted = True
- fOK = doUpgrade(config)
-
- #Finally, is possible umount current upgrade file.
- if fMounted:
- umount(config) #cleanup, may fail in some cases- device busy.
- except:
- fOK = False
-
- if not fOK:
- msg = "<BSTRAP component='RHEV_INSTALL' status='FAIL'/>"
- logging.error("<BSTRAP component='RHEV_INSTALL' status='FAIL'/>")
- else:
- msg = "<BSTRAP component='RHEV_INSTALL' status='OK'/>"
- logging.debug("<BSTRAP component='RHEV_INSTALL' status='OK'/>")
- print (msg)
-
- sys.stdout.flush()
- return fOK
+ logging.debug(msg)
+ print(msg)
+ return rc
if __name__ == "__main__":
- sys.exit(not main())
-
+ main()
--
To view, visit http://gerrit.ovirt.org/28244
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7b997d70a440545497246d1a19d9671b054a56a5
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Douglas Schilling Landgraf <dougsland(a)redhat.com>
9 years, 10 months
Change in vdsm[master]: Bumping compatible cluster and engine version to 3.5
by ybronhei@redhat.com
Yaniv Bronhaim has uploaded a new change for review.
Change subject: Bumping compatible cluster and engine version to 3.5
......................................................................
Bumping compatible cluster and engine version to 3.5
Change-Id: I1eab0652847dd32c11f2612c3b3af1fe689398b6
Signed-off-by: Yaniv Bronhaim <ybronhei(a)redhat.com>
---
M vdsm/dsaversion.py.in
1 file changed, 2 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/78/28078/1
diff --git a/vdsm/dsaversion.py.in b/vdsm/dsaversion.py.in
index 269798a..a4a3637 100644
--- a/vdsm/dsaversion.py.in
+++ b/vdsm/dsaversion.py.in
@@ -33,7 +33,7 @@
'version_name': version_name,
'software_version': software_version,
'software_revision': software_revision,
- 'supportedENGINEs': ['3.0', '3.1', '3.2', '3.3', '3.4'],
+ 'supportedENGINEs': ['3.0', '3.1', '3.2', '3.3', '3.4', '3.5'],
'supportedProtocols': ['2.2', '2.3'],
- 'clusterLevels': ['3.0', '3.1', '3.2', '3.3', '3.4'],
+ 'clusterLevels': ['3.0', '3.1', '3.2', '3.3', '3.4', '3.5'],
}
--
To view, visit http://gerrit.ovirt.org/28078
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1eab0652847dd32c11f2612c3b3af1fe689398b6
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Yaniv Bronhaim <ybronhei(a)redhat.com>
9 years, 10 months