Francesco Romani has uploaded a new change for review.
Change subject: mkimage: do not create world-readable image
......................................................................
mkimage: do not create world-readable image
mkimage generates world-readable images by default.
mkimage spawns a genisoimage process through the cpopen package
to do the actual work.
It is of course possible to fix the permissions once the ISO image
is created with a trivial os.chmod() call, but this will leave
open a window opportunity to still exploit the bug.
A more correct and secure way to fix the permissions of the newly
generated image is to setup the umask just before to exec.
The current python-cpopen package lacks a way to set the umask
of the child before to run it, so this patch depends on an enhanced
python-cpopen, temporarily located here:
https://github.com/mojaves/python-cpopen
With this enhanced cpopen, fixing the permissions is trivially made
by passing the correct umask at the ISO image creation.
Change-Id: I893a1310d9988c52cec9f48dfd17dfa1647da4dc
Bug-Url: https://bugzilla.redhat.com/1034172
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
---
M lib/vdsm/utils.py
M vdsm/mkimage.py
2 files changed, 4 insertions(+), 3 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/46/21946/1
diff --git a/lib/vdsm/utils.py b/lib/vdsm/utils.py
index ebd36b8..8173916 100644
--- a/lib/vdsm/utils.py
+++ b/lib/vdsm/utils.py
@@ -501,7 +501,7 @@
def execCmd(command, sudo=False, cwd=None, data=None, raw=False, logErr=True,
printable=None, env=None, sync=True, nice=None, ioclass=None,
ioclassdata=None, setsid=False, execCmdLogger=logging.root,
- deathSignal=0):
+ deathSignal=0, childUmask=None):
"""
Executes an external command, optionally via sudo.
@@ -531,7 +531,7 @@
execCmdLogger.debug("%s (cwd %s)", cmdline, cwd)
p = BetterPopen(command, close_fds=True, cwd=cwd, env=env,
- deathSignal=deathSignal)
+ deathSignal=deathSignal, childUmask=childUmask)
p = AsyncProc(p)
if not sync:
if data is not None:
diff --git a/vdsm/mkimage.py b/vdsm/mkimage.py
index a4716c7..4daefec 100644
--- a/vdsm/mkimage.py
+++ b/vdsm/mkimage.py
@@ -117,7 +117,8 @@
if volumeName is not None:
command.extend(['-V', volumeName])
command.extend([dirname])
- rc, out, err = storage.misc.execCmd(command, raw=True)
+ rc, out, err = storage.misc.execCmd(command, raw=True,
+ childUmask=0o007)
if rc:
raise OSError(errno.EIO, "could not create iso file: "
"code %s, out %s\nerr %s" % (rc, out, err))
--
To view, visit http://gerrit.ovirt.org/21946
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I893a1310d9988c52cec9f48dfd17dfa1647da4dc
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
Peter V. Saveliev has uploaded a new change for review.
Change subject: remove redundant libvirt call
......................................................................
remove redundant libvirt call
Checking UUIDString() adresses the bug #603494, which
is closed ages ago. While it is nice to support really
ancient libvirt versions, it costs us one extra
libvirt call. Given global libvirt driver lock, it
does matter in mass VM creation.
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=603494
Signed-off-by: Peter V. Saveliev <peet(a)redhat.com>
Change-Id: I06a71c2e44332f50b3203a0a8f1bfa799914b684
---
M vdsm/libvirtvm.py
1 file changed, 0 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/54/11054/1
diff --git a/vdsm/libvirtvm.py b/vdsm/libvirtvm.py
index d13dbb0..9376e5c 100644
--- a/vdsm/libvirtvm.py
+++ b/vdsm/libvirtvm.py
@@ -1539,8 +1539,6 @@
self._dom = NotifyingVirDomain(
self._connection.createXML(domxml, flags),
self._timeoutExperienced)
- if self._dom.UUIDString() != self.id:
- raise Exception('libvirt bug 603494')
hooks.after_vm_start(self._dom.XMLDesc(0), self.conf)
if not self._dom:
self.setDownStatus(ERROR, 'failed to start libvirt vm')
--
To view, visit http://gerrit.ovirt.org/11054
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I06a71c2e44332f50b3203a0a8f1bfa799914b684
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Peter V. Saveliev <peet(a)redhat.com>
Greg Padgett has uploaded a new change for review.
Change subject: storage: refactor nfsSD.py for posix storage
......................................................................
storage: refactor nfsSD.py for posix storage
NFS and PosixFs domains are no longer handled the same way, so logic
that differs between them should be appropriately separated into
classes for each connection type. This removes the need to have a
storageType parameter to NfsStorageDomain:_preCreateValidation().
For now, there's no reason to have a PosixFsStorageDomain class for
Posix storage (it would be empty), so just use MountableStorageDomain
until the need for a subclass arises.
Change-Id: Ic5788925f9c11b417aba713c652fc2a92f178830
Signed-off-by: Greg Padgett <gpadgett(a)redhat.com>
---
M Makefile.am
M vdsm.spec.in
M vdsm/storage/Makefile.am
M vdsm/storage/hsm.py
A vdsm/storage/mountableSD.py
M vdsm/storage/nfsSD.py
M vdsm/storage/sdc.py
7 files changed, 148 insertions(+), 114 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/88/9088/1
diff --git a/Makefile.am b/Makefile.am
index bd262af..a96d3f7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -83,6 +83,7 @@
vdsm/storage/lvm.py \
vdsm/storage/misc.py \
vdsm/storage/mount.py \
+ vdsm/storage/mountableSD.py \
vdsm/storage/multipath.py \
vdsm/storage/nfsSD.py \
vdsm/storage/outOfProcess.py \
diff --git a/vdsm.spec.in b/vdsm.spec.in
index c117ee5..d76495c 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -661,6 +661,7 @@
%{_datadir}/%{vdsm_name}/storage/lvm.py*
%{_datadir}/%{vdsm_name}/storage/misc.py*
%{_datadir}/%{vdsm_name}/storage/mount.py*
+%{_datadir}/%{vdsm_name}/storage/mountableSD.py*
%{_datadir}/%{vdsm_name}/storage/multipath.py*
%{_datadir}/%{vdsm_name}/storage/nfsSD.py*
%{_datadir}/%{vdsm_name}/storage/outOfProcess.py*
diff --git a/vdsm/storage/Makefile.am b/vdsm/storage/Makefile.am
index cff09be..cf8f768 100644
--- a/vdsm/storage/Makefile.am
+++ b/vdsm/storage/Makefile.am
@@ -41,6 +41,7 @@
lvm.py \
misc.py \
mount.py \
+ mountableSD.py \
multipath.py \
nfsSD.py \
outOfProcess.py \
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index 259676b..f56c8b0 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -41,8 +41,9 @@
import sp
import sd
import blockSD
-import nfsSD
import localFsSD
+import mountableSD
+import nfsSD
import lvm
import fileUtils
import multipath
@@ -2251,16 +2252,18 @@
#getSharedLock(connectionsResource...)
#getExclusiveLock(sdUUID...)
- if storageType in sd.BLOCK_DOMAIN_TYPES:
- newSD = blockSD.BlockStorageDomain.create(sdUUID, domainName,
- domClass, typeSpecificArg, storageType, domVersion)
- elif storageType in (sd.NFS_DOMAIN, sd.POSIXFS_DOMAIN):
- newSD = nfsSD.NfsStorageDomain.create(sdUUID, domainName, domClass,
- typeSpecificArg, storageType, domVersion)
- elif storageType == sd.LOCALFS_DOMAIN:
- newSD = localFsSD.LocalFsStorageDomain.create(sdUUID, domainName,
- domClass, typeSpecificArg, storageType, domVersion)
- else:
+ sdConstructorMap = {
+ sd.NFS_DOMAIN : nfsSD.NfsStorageDomain,
+ sd.POSIXFS_DOMAIN : mountableSD.MountableStorageDomain,
+ sd.LOCALFS_DOMAIN : localFsSD.LocalFsStorageDomain,
+ }
+ for domType in sd.BLOCK_DOMAIN_TYPES:
+ sdConstructorMap[domType] = blockSD.BlockStorageDomain
+
+ try:
+ newSD = sdConstructorMap[storageType].create(sdUUID, domainName,
+ domClass, typeSpecificArg, storageType, domVersion)
+ except KeyError:
raise se.StorageDomainTypeError(storageType)
sdCache.manuallyAddDomain(newSD)
diff --git a/vdsm/storage/mountableSD.py b/vdsm/storage/mountableSD.py
new file mode 100644
index 0000000..05284ab
--- /dev/null
+++ b/vdsm/storage/mountableSD.py
@@ -0,0 +1,122 @@
+#
+# Copyright 2009-2012 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+import os
+
+import sd
+import fileSD
+import fileUtils
+import storage_exception as se
+import outOfProcess as oop
+import mount
+import misc
+
+
+class MountableStorageDomain(fileSD.FileStorageDomain):
+
+ @classmethod
+ def _preCreateValidation(cls, sdUUID, domPath, typeSpecificArg, version):
+ # Some trivial resource validation
+ sd.validateDomainVersion(version)
+
+ # Make sure the underlying file system is mounted
+ if not mount.isMounted(domPath):
+ raise se.StorageDomainFSNotMounted(domPath)
+
+ fileSD.validateDirAccess(domPath)
+
+ # Make sure there are no remnants of other domain
+ mdpat = os.path.join(domPath, "*", sd.DOMAIN_META_DATA)
+ if len(oop.getProcessPool(sdUUID).glob.glob(mdpat)) > 0:
+ raise se.StorageDomainNotEmpty(typeSpecificArg)
+
+ @classmethod
+ def create(cls, sdUUID, domainName, domClass, remotePath, storageType,
+ version):
+ """
+ Create new storage domain.
+ 'sdUUID' - Storage Domain UUID
+ 'domainName' - storage domain name ("iso" or "data domain name")
+ 'domClass' - Data/Iso
+ 'remotePath' - server:/export_path
+ 'storageType' - NFS_DOMAIN, LOCALFS_DOMAIN, &etc.
+ 'version' - DOMAIN_VERSIONS
+ """
+ cls.log.info("sdUUID=%s domainName=%s remotePath=%s "
+ "domClass=%s", sdUUID, domainName, remotePath, domClass)
+
+ if not misc.isAscii(domainName) and not sd.supportsUnicode(version):
+ raise se.UnicodeArgumentException()
+
+ # Create local path
+ mntPath = fileUtils.transformPath(remotePath)
+
+ mntPoint = os.path.join(cls.storage_repository,
+ sd.DOMAIN_MNT_POINT, mntPath)
+
+ cls._preCreateValidation(sdUUID, mntPoint, remotePath, version)
+
+ domainDir = os.path.join(mntPoint, sdUUID)
+ cls._prepareMetadata(domainDir, sdUUID, domainName, domClass,
+ remotePath, storageType, version)
+
+ # create domain images folder
+ imagesDir = os.path.join(domainDir, sd.DOMAIN_IMAGES)
+ oop.getProcessPool(sdUUID).fileUtils.createdir(imagesDir)
+
+ # create special imageUUID for ISO/Floppy volumes
+ if domClass is sd.ISO_DOMAIN:
+ isoDir = os.path.join(imagesDir, sd.ISO_IMAGE_UUID)
+ oop.getProcessPool(sdUUID).fileUtils.createdir(isoDir)
+
+ fsd = cls(os.path.join(mntPoint, sdUUID))
+ fsd.initSPMlease()
+
+ return fsd
+
+ def selftest(self):
+ """
+ Run internal self test
+ """
+ if not mount.isMounted(self.mountpoint):
+ raise se.StorageDomainFSNotMounted(self.mountpoint)
+
+ # Run general part of selftest
+ fileSD.FileStorageDomain.selftest(self)
+
+ @staticmethod
+ def findDomainPath(sdUUID):
+ for tmpSdUUID, domainPath in fileSD.scanDomains("*"):
+ if tmpSdUUID == sdUUID and mount.isMounted(
+ os.path.join(domainPath, "..")):
+ return domainPath
+
+ raise se.StorageDomainDoesNotExist(sdUUID)
+
+ def getRealPath(self):
+ try:
+ return mount.getMountFromTarget(self.mountpoint).fs_spec
+ except mount.MountError:
+ return ""
+
+
+def findDomain(sdUUID):
+ return MountableStorageDomain(MountableStorageDomain
+ .findDomainPath(sdUUID))
diff --git a/vdsm/storage/nfsSD.py b/vdsm/storage/nfsSD.py
index 3a1c90e..15dd137 100644
--- a/vdsm/storage/nfsSD.py
+++ b/vdsm/storage/nfsSD.py
@@ -1,5 +1,5 @@
#
-# Copyright 2009-2011 Red Hat, Inc.
+# Copyright 2009-2012 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -18,110 +18,16 @@
# Refer to the README and COPYING files for full details of the license
#
-import os
-
-import sd
-import fileSD
-import fileUtils
+import mountableSD
import storage_exception as se
-import outOfProcess as oop
-import mount
-import misc
-class NfsStorageDomain(fileSD.FileStorageDomain):
+class NfsStorageDomain(mountableSD.MountableStorageDomain):
@classmethod
- def _preCreateValidation(cls, sdUUID, domPath, typeSpecificArg,
- storageType, version):
- # Some trivial resource validation
- # TODO Checking storageType==nfs in the nfs class is not clean
- if storageType == sd.NFS_DOMAIN and ":" not in typeSpecificArg:
+ def _preCreateValidation(cls, sdUUID, domPath, typeSpecificArg, version):
+ if ":" not in typeSpecificArg:
raise se.StorageDomainIllegalRemotePath(typeSpecificArg)
- sd.validateDomainVersion(version)
-
- # Make sure the underlying file system is mounted
- if not mount.isMounted(domPath):
- raise se.StorageDomainFSNotMounted(domPath)
-
- fileSD.validateDirAccess(domPath)
-
- # Make sure there are no remnants of other domain
- mdpat = os.path.join(domPath, "*", sd.DOMAIN_META_DATA)
- if len(oop.getProcessPool(sdUUID).glob.glob(mdpat)) > 0:
- raise se.StorageDomainNotEmpty(typeSpecificArg)
-
- @classmethod
- def create(cls, sdUUID, domainName, domClass, remotePath, storageType,
- version):
- """
- Create new storage domain.
- 'sdUUID' - Storage Domain UUID
- 'domainName' - storage domain name ("iso" or "data domain name")
- 'domClass' - Data/Iso
- 'remotePath' - server:/export_path
- 'storageType' - NFS_DOMAIN, LOCALFS_DOMAIN, &etc.
- 'version' - DOMAIN_VERSIONS
- """
- cls.log.info("sdUUID=%s domainName=%s remotePath=%s "
- "domClass=%s", sdUUID, domainName, remotePath, domClass)
-
- if not misc.isAscii(domainName) and not sd.supportsUnicode(version):
- raise se.UnicodeArgumentException()
-
- # Create local path
- mntPath = fileUtils.transformPath(remotePath)
-
- mntPoint = os.path.join(cls.storage_repository,
- sd.DOMAIN_MNT_POINT, mntPath)
-
- cls._preCreateValidation(sdUUID, mntPoint, remotePath, storageType,
- version)
-
- domainDir = os.path.join(mntPoint, sdUUID)
- cls._prepareMetadata(domainDir, sdUUID, domainName, domClass,
- remotePath, storageType, version)
-
- # create domain images folder
- imagesDir = os.path.join(domainDir, sd.DOMAIN_IMAGES)
- oop.getProcessPool(sdUUID).fileUtils.createdir(imagesDir)
-
- # create special imageUUID for ISO/Floppy volumes
- if domClass is sd.ISO_DOMAIN:
- isoDir = os.path.join(imagesDir, sd.ISO_IMAGE_UUID)
- oop.getProcessPool(sdUUID).fileUtils.createdir(isoDir)
-
- fsd = cls(os.path.join(mntPoint, sdUUID))
- fsd.initSPMlease()
-
- return fsd
-
- def selftest(self):
- """
- Run internal self test
- """
- if not mount.isMounted(self.mountpoint):
- raise se.StorageDomainFSNotMounted(self.mountpoint)
-
- # Run general part of selftest
- fileSD.FileStorageDomain.selftest(self)
-
- @staticmethod
- def findDomainPath(sdUUID):
- for tmpSdUUID, domainPath in fileSD.scanDomains("*"):
- if tmpSdUUID == sdUUID and mount.isMounted(
- os.path.join(domainPath, "..")):
- return domainPath
-
- raise se.StorageDomainDoesNotExist(sdUUID)
-
- def getRealPath(self):
- try:
- return mount.getMountFromTarget(self.mountpoint).fs_spec
- except mount.MountError:
- return ""
-
-
-def findDomain(sdUUID):
- return NfsStorageDomain(NfsStorageDomain.findDomainPath(sdUUID))
+ mountableSD.MountableStorageDomain._preCreateValidation(sdUUID,
+ domPath, typeSpecificArg, version)
diff --git a/vdsm/storage/sdc.py b/vdsm/storage/sdc.py
index f2f4534..1064b5e 100644
--- a/vdsm/storage/sdc.py
+++ b/vdsm/storage/sdc.py
@@ -132,7 +132,7 @@
def _findDomain(self, sdUUID):
import blockSD
import localFsSD
- import nfsSD
+ import mountableSD
# The order is somewhat important, it's ordered
# by how quickly get can find the domain. For instance
@@ -140,7 +140,7 @@
# until it times out, this should affect fetching
# of block\local domains. If for any case in the future
# this changes, please update the order.
- for mod in (blockSD, localFsSD, nfsSD):
+ for mod in (blockSD, localFsSD, mountableSD):
try:
return mod.findDomain(sdUUID)
except se.StorageDomainDoesNotExist:
--
To view, visit http://gerrit.ovirt.org/9088
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic5788925f9c11b417aba713c652fc2a92f178830
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Greg Padgett <gpadgett(a)redhat.com>
Vered Volansky has uploaded a new change for review.
Change subject: utils: cleanup - typos, grammar and comments refinment
......................................................................
utils: cleanup - typos, grammar and comments refinment
Change-Id: I04a1c4d444f2604b66b44bb9deac7d780db04aaf
Signed-off-by: Vered Volansky <vvolansk(a)redhat.com>
---
M lib/vdsm/utils.py
1 file changed, 24 insertions(+), 17 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/62/22862/1
diff --git a/lib/vdsm/utils.py b/lib/vdsm/utils.py
index d6c65b2..122da3e 100644
--- a/lib/vdsm/utils.py
+++ b/lib/vdsm/utils.py
@@ -19,7 +19,7 @@
#
"""
-A module containing miscellaneous functions and classes that are user
+A module containing miscellaneous functions and classes that are used
plentifuly around vdsm.
.. attribute:: utils.symbolerror
@@ -56,7 +56,7 @@
from cpopen import CPopen
from . import constants
-# Buffsize is 1K because I tested it on some use cases and 1k was fastets. If
+# Buffsize is 1K because it was tested on some use cases and 1K was fastest. If
# you find this number to be a bottleneck in any way you are welcome to change
# it
BUFFSIZE = 1024
@@ -118,7 +118,7 @@
"""
Try to remove a file.
- If the file doesn't exist is assumed that it was already removed.
+ If the file doesn't exist it's assumed that it was already removed.
"""
try:
os.unlink(fileToRemove)
@@ -135,7 +135,7 @@
"""
Try to remove a directory and all it's contents.
- If the directory doesn't exist is assumed that it was already removed.
+ If the directory doesn't exist it's assumed that it was already removed.
"""
try:
shutil.rmtree(directoryToRemove)
@@ -180,7 +180,7 @@
"""
Parse ``/proc/meminfo`` and return its content as a dictionary.
- For a reason unknown to me, ``/proc/meminfo`` is is sometime
+ For a reason unknown to me, ``/proc/meminfo`` is sometimes
empty when opened. If that happens, the function retries to open it
3 times.
@@ -297,7 +297,7 @@
class AsyncProc(object):
"""
- AsyncProc is a funky class. It warps a standard subprocess.Popen
+ AsyncProc is a funky class. It wraps a standard subprocess.Popen
Object and gives it super powers. Like the power to read from a stream
without the fear of deadlock. It does this by always sampling all
stream while waiting for data. By doing this the other process can freely
@@ -440,7 +440,7 @@
try:
if self._stdin.len > 0 and self._stdin.pos == 0:
# Polling stdin is redundant if there is nothing to write
- # trun on only if data is waiting to be pushed
+ # turn on only if data is waiting to be pushed
self._poller.modify(self._fdin, select.EPOLLOUT)
pollres = NoIntrPoll(self._poller.poll, 1)
@@ -801,12 +801,12 @@
class memoized(object):
- """Decorator that caches a function's return value each time it is called.
+ """
+ Decorator that caches a function's return value each time it is called.
If called later with the same arguments, the cached value is returned, and
not re-evaluated. There is no support for uncachable arguments.
Adaptation from http://wiki.python.org/moin/PythonDecoratorLibrary#Memoize
-
"""
def __init__(self, func):
self.func = func
@@ -914,7 +914,7 @@
:param func: The callable to run.
:param expectedException: The exception you expect to receive when the
function fails.
- :param tries: The number of time to try. None\0,-1 means infinite.
+ :param tries: The number of times to try. None\0,-1 means infinite.
:param timeout: The time you want to spend waiting. This **WILL NOT** stop
the method. It will just not run it if it ended after the
timeout.
@@ -950,10 +950,12 @@
class AsyncProcessOperation(object):
def __init__(self, proc, resultParser=None):
- """Wraps a running process operation.
+ """
+ Wraps a running process operation.
resultParser should be of type callback(rc, out, err) and can return
- anything or throw exceptions."""
+ anything or throw exceptions.
+ """
self._lock = threading.Lock()
self._result = None
@@ -962,17 +964,22 @@
self._proc = proc
def wait(self, timeout=None, cond=None):
- """Waits until the process has exited, the timeout has been reached or
- the condition has been met"""
+ """
+ Waits until the process has exited, the timeout has been reached or
+ the condition has been met
+ """
return self._proc.wait(timeout, cond)
def stop(self):
- """Stops the running operation, effectively sending a kill signal to
- the process"""
+ """
+ Stops the running operation, effectively sending a kill signal to
+ the process
+ """
self._proc.kill()
def result(self):
- """Returns the result in the as a tuple of (result, error).
+ """
+ Returns the result as a tuple of (result, error).
If the operation is still running it will block until it returns.
If no resultParser has been set the default result
--
To view, visit http://gerrit.ovirt.org/22862
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I04a1c4d444f2604b66b44bb9deac7d780db04aaf
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Vered Volansky <vvolansk(a)redhat.com>