Federico Simoncelli has uploaded a new change for review.
Change subject: vm: discover volume path from xml definition
......................................................................
vm: discover volume path from xml definition
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 generated an issue during live migration between different
vdsm versions:
libvirtError: invalid argument: invalid path ... not assigned to
domain
In this patch:
- revert to the previous path for virtual machine images
- inspect libvirt xml during live migration and vdsm restart to
identify if it is necessary to update the path cached in the
drive object (provided by prepareImage)
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1059482
Change-Id: I322f1f879fbd5b6415789f3b307e8741d846d694
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/storage/blockSD.py
M vdsm/storage/fileSD.py
M vdsm/storage/hsm.py
M vdsm/storage/sd.py
M vdsm/vm.py
5 files changed, 25 insertions(+), 8 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/02/24202/1
diff --git a/vdsm/storage/blockSD.py b/vdsm/storage/blockSD.py
index 5179c5a..9d76c2c 100644
--- a/vdsm/storage/blockSD.py
+++ b/vdsm/storage/blockSD.py
@@ -1052,9 +1052,8 @@
vols, rems = self.getAllVolumesImages()
return rems
- def linkBCImage(self, imgPath, imgUUID):
- dst = os.path.join(self.mountpoint, self.sdUUID, sd.DOMAIN_IMAGES,
- imgUUID)
+ def linkBCImage(self, imgUUID, imgPath):
+ dst = sd.StorageDomain.linkBCImage(self, imgUUID, imgPath)
try:
os.symlink(imgPath, dst)
except OSError as e:
diff --git a/vdsm/storage/fileSD.py b/vdsm/storage/fileSD.py
index 180a43f..50caa09 100644
--- a/vdsm/storage/fileSD.py
+++ b/vdsm/storage/fileSD.py
@@ -421,10 +421,6 @@
return dict((k, sd.ImgsPar(tuple(v['imgs']), v['parent']))
for k, v in volumes.iteritems())
- def linkBCImage(self, imgPath, imgUUID):
- return os.path.join(self.mountpoint, self.sdUUID, sd.DOMAIN_IMAGES,
- imgUUID)
-
def createImageLinks(self, srcImgPath, imgUUID):
"""
qcow chain is build by reading each qcow header and reading the path
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index 53c9dd0..384d43f 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -3220,7 +3220,7 @@
imgVolumes = sd.getVolsOfImage(allVols, imgUUID).keys()
imgPath = dom.activateVolumes(imgUUID, imgVolumes)
if spUUID and spUUID != sd.BLANK_UUID:
- runImgPath = dom.linkBCImage(imgPath, imgUUID)
+ runImgPath = dom.linkBCImage(imgUUID, imgPath)
else:
runImgPath = imgPath
diff --git a/vdsm/storage/sd.py b/vdsm/storage/sd.py
index c9738e0..38ec5af 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 linkBCImage(self, imgUUID, imgPath):
+ return image.Image(self._getRepoPath()) \
+ .getImageDir(self.sdUUID, imgUUID)
+
def getIsoDomainImagesDir(self):
"""
Get 'images' directory from Iso domain
diff --git a/vdsm/vm.py b/vdsm/vm.py
index aae8bd6..78161d1 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -4962,6 +4962,16 @@
self.log.debug('Looking for drive with attributes %s', deviceDict)
for d in self._devices[DISK_DEVICES]:
+ # When we analyze a disk device that was already discovered in
+ # the past (generally as soon as the VM is created) we should
+ # verify that the cached path is the one used in libvirt.
+ # We already hit few times the problem that after a live
+ # migration the paths were not in sync anymore (BZ#1059482).
+ if (hasattr(d, 'alias') and d.alias == alias
+ and d.path != devPath):
+ self.log.warning('updating drive %s path from %s to %s',
+ d.alias, d.path, devPath)
+ d.path = devPath
if d.path == devPath:
d.name = name
d.type = devType
@@ -4975,6 +4985,13 @@
# Update vm's conf with address for known disk devices
knownDev = False
for dev in self.conf['devices']:
+ # See comment in previous loop. This part is used to update
+ # the vm configuration as well.
+ if ('alias' in dev and dev['alias'] == alias
+ and dev['path'] != devPath):
+ self.log.warning('updating drive %s config path from %s '
+ 'to %s', dev['alias'], d.path, devPath)
+ dev['path'] = devPath
if dev['type'] == DISK_DEVICES and dev['path'] == devPath:
dev['name'] = name
dev['address'] = address
--
To view, visit http://gerrit.ovirt.org/24202
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I322f1f879fbd5b6415789f3b307e8741d846d694
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
Dan Kenigsberg has posted comments on this change.
Change subject: New before_device_create/before_nic_hotplug hook: privatevlan
......................................................................
Patch Set 5: Code-Review-1
--
To view, visit http://gerrit.ovirt.org/24195
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: comment
Gerrit-Change-Id: Idda6f193c0095241bc1540a0241d49426c000fb3
Gerrit-PatchSet: 5
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Michael Samuel <mik(a)miknet.net>
Gerrit-Reviewer: Antoni Segura Puimedon <asegurap(a)redhat.com>
Gerrit-Reviewer: Assaf Muller <amuller(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Michael Samuel <mik(a)miknet.net>
Gerrit-Reviewer: oVirt Jenkins CI Server
Gerrit-HasComments: No
On Mon, Feb 17, 2014 at 06:19:53PM +0000, Jenkins ci oVirt Server wrote:
> Project: http://jenkins.ovirt.org/job/vdsm_create_rpms/label=centos6/
> Build: http://jenkins.ovirt.org/job/vdsm_create_rpms/label=centos6/1107/
> Build Number: 1107
> Build Status: Still Failing
> Triggered By: Started by Naginator
>
> -------------------------------------
> Changes Since Last Success:
> -------------------------------------
> Changes for Build #1100
> [Antoni S. Puimedon] netinfo: optimize ipaddr retrieval
>
> [Antoni S. Puimedon] net_scale: avoid netinfo instantiation for removal check
These failures seems to be due to a recent change in pep8 :-(
Could you fix the code, or mask the failure?
/usr/bin/pep8 --version
1.4.5
/usr/bin/pep8 --exclude="config.py,constants.py" --filename '*.py,*.py.in' \
client lib/vdsm/*.py lib/vdsm/*.py.in tests vds_bootstrap vdsm-tool vdsm/*.py vdsm/*.py.in vdsm/netconf vdsm/sos/vdsm.py.in vdsm/storage vdsm/vdsm vdsm_api vdsm_hooks vdsm_reg
lib/vdsm/netlink.py:158:9: E123 closing bracket does not match indentation of opening bracket's line
make[3]: *** [check-local] Error 1
Yaniv Bronhaim has uploaded a new change for review.
Change subject: Passing "$*" to shell func with quotation marks passes all vars in one
......................................................................
Passing "$*" to shell func with quotation marks passes all vars in one
Instead of passing the variables as passed to test_conflicting_conf
to the specific test func
Change-Id: Iee8d5f3e9c01bd879a1e41159fa798eefd2c51ca
Signed-off-by: Yaniv Bronhaim <ybronhei(a)redhat.com>
---
M lib/vdsm/tool/libvirt_configure.sh.in
1 file changed, 1 insertion(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/80/24580/1
diff --git a/lib/vdsm/tool/libvirt_configure.sh.in b/lib/vdsm/tool/libvirt_configure.sh.in
index 89f1534..49e0e1e 100755
--- a/lib/vdsm/tool/libvirt_configure.sh.in
+++ b/lib/vdsm/tool/libvirt_configure.sh.in
@@ -52,7 +52,7 @@
}
test_conflicting_conf() {
- test_ssl_conflict_conf "$*"
+ test_ssl_conflict_conf $*
# add here additional conf checks
}
--
To view, visit http://gerrit.ovirt.org/24580
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iee8d5f3e9c01bd879a1e41159fa798eefd2c51ca
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Yaniv Bronhaim <ybronhei(a)redhat.com>
Liron Ar has uploaded a new change for review.
Change subject: introducing downloadImageFromStream
......................................................................
introducing downloadImageFromStream
This patch introduces the downloadImageFromStream verb in vdsm which
allows to upload using streaming content to vdsm images.
XML-RPC spec doesn't support streaming, as we don't want to use HTTP
server in addition to the current XML-RPC server (to not use another
port) we will threat some requests as http requests instead of xml-rpc
requests.
General upload information:
---------------------------------------------------------------
PUT requests arriving to the server with content type of
application/octet-stream to default paths that we use
today for request handling ('/', '/RPC2') will be threated as
upload requests.
The PUT stream upload request inspected headers are:
-- Mandatory headers:
*content-length
-- Mandatory custom headers:
*X-Storage-Pool-Id : mandatory for succesfull execution
*X-Storage-Domain-Id: mandatory for succesfull execution
*X-Image-Id: mandatory for succesfull execution
*X-Volume-Id: mandatory for succesfull execution
-- Optional custom headers;
*X-Buffer-Size: optional, indicates the passed buffer
The server will return answers with the following codes:
200 - request completed, the response body will contain the execution
results, the returned content type is 'application/json'
500 - internal error
406 - missing content-length header
in case that a task was created, its id will be passed in the response
using the custom header 'X-Task-Id' for polling by the engine.
Implementation details
--------------------------------------------------------------
Currently for any spm task (besides delete image) the operation is
performed through a spm task.
We need to have a task to indicate that "there's something" going on -
for example, if we had no task during the upload the spm could be
stopped and be started on other host which might be hazardous.
For having a task we can do two different things -
1. schedule a task to perform the whole download process, that means that
the request thread will be blocked, the read from the stream and writes
to the destination image will be done through the task and then the
request thread will be released and response would be sent.
2. schedule a "dummy" task with "blank" function that will just be used to
indicate that there's an downloadFromStream execution going on while the
request thread will be used for executing the actual download.
Option 2 is implemented with this patch.
needed:
*socket timeout inspection
*tests?
Change-Id: I768b84799ed9fb2769c6d4240519d036f8988b99
Signed-off-by: Liron Aravot <laravot(a)redhat.com>
---
M vdsm/API.py
M vdsm/BindingXMLRPC.py
M vdsm/storage/hsm.py
M vdsm/storage/imageSharing.py
4 files changed, 153 insertions(+), 3 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/81/23281/1
diff --git a/vdsm/API.py b/vdsm/API.py
index e7a550c..37802e1 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -838,6 +838,10 @@
return self._irs.downloadImage(
methodArgs, self._spUUID, self._sdUUID, self._UUID, volUUID)
+ def downloadFromStream(self, methodArgs, volUUID=None):
+ return self._irs.downloadImageFromStream(
+ methodArgs, self._spUUID, self._sdUUID, self._UUID, volUUID)
+
class LVMVolumeGroup(APIBase):
ctorArgs = ['lvmvolumegroupID']
diff --git a/vdsm/BindingXMLRPC.py b/vdsm/BindingXMLRPC.py
index a340ae7..8b7d9fa 100644
--- a/vdsm/BindingXMLRPC.py
+++ b/vdsm/BindingXMLRPC.py
@@ -25,11 +25,14 @@
import logging
import libvirt
import threading
+import cgi
+import json
from vdsm import constants
from vdsm import utils
from vdsm.define import doneCode, errCode
from vdsm.netinfo import getRouteDeviceTo
+from storage.threadLocal import vars
import API
from vdsm.exception import VdsmException
try:
@@ -128,10 +131,91 @@
else:
basehandler = SimpleXMLRPCServer.SimpleXMLRPCRequestHandler
- class LoggingHandler(LoggingMixIn, basehandler):
+ class RequestHandler(LoggingMixIn, basehandler):
+
+ log = logging.getLogger("BindingXMLRPC.RequestHandler")
+ CUSTOM_HEADER_POOL = 'X-Storage-Pool-Id'
+ CUSTOM_HEADER_DOMAIN = 'X-Storage-Domain-Id'
+ CUSTOM_HEADER_IMAGE = 'X-Image-Id'
+ CUSTOM_HEADER_VOLUME = 'X-Volume-Id'
+ CUSTOM_HEADER_BUFFER = 'X-Buffer-Size'
+ CUSTOM_HEADER_TASK_ID = 'X-Task-Id'
+ HEADER_CONTENT_LENGTH = 'content-length'
+ HEADER_CONTENT_TYPE = 'content-type'
+ RESPONSE_LENGTH_REQUIRED_ = 411
+ RESPONSE_NOT_ACCEPTABLE = 406
+ RESPONSE_REQUEST_SUCCEEDED = 200
+ RESPONSE_INTERNAL_ERROR = 500
+
def setup(self):
threadLocal.client = self.client_address[0]
return basehandler.setup(self)
+
+ def addTaskIdHeaderIfPresent(self):
+ if hasattr(vars, 'task'):
+ self.send_header(self.CUSTOM_HEADER_TASK_ID,
+ vars.task.getID())
+
+ def do_PUT(self):
+ ctype, pt = cgi.parse_header(self.headers.getheader(self.
+ HEADER_CONTENT_TYPE))
+ try:
+ if ctype == 'application/octet-stream':
+ contentLength = self.headers. \
+ getheader(self.HEADER_CONTENT_LENGTH)
+ if not contentLength:
+ self.send_response(411)
+ self.finish()
+ return
+
+ # NEED TO DECIDE ABOUT THOSE
+ #self.rfile._sock.settimeout(5)
+ #self.rfile._sock.set_socket_read_timeout
+ spUUID = self.headers. \
+ getheader(self.CUSTOM_HEADER_POOL)
+ sdUUID = self.headers. \
+ getheader(self.CUSTOM_HEADER_DOMAIN)
+ imgUUID = self.headers. \
+ getheader(self.CUSTOM_HEADER_IMAGE)
+ volUUID = self.headers. \
+ getheader(self.CUSTOM_HEADER_VOLUME)
+ bufferSize = self.headers. \
+ getheader(self.CUSTOM_HEADER_BUFFER)
+ contentLength = self.headers. \
+ getheader(self.HEADER_CONTENT_LENGTH)
+
+ methodArgs = {'method': 'stream',
+ 'fileObj': self.rfile,
+ 'Content-Length': contentLength,
+ 'Buffer-Size': bufferSize}
+ image = API.Image(imgUUID, spUUID, sdUUID)
+ response = image.downloadFromStream(methodArgs,
+ volUUID)
+ json_response = json.dumps(response)
+ self.send_response(200)
+ self.send_header(self.HEADER_CONTENT_TYPE,
+ 'application/json')
+ self.send_header(self.HEADER_CONTENT_LENGTH,
+ len(json_response))
+ self.addTaskIdHeaderIfPresent()
+ self.end_headers()
+ self.wfile.write(json_response)
+ self.finish()
+ else:
+ self.send_response(406)
+ self.finish()
+ # shouldn't happen
+ except Exception:
+ self.log.error("execution exception",
+ exc_info=True)
+ try:
+ self.send_response(500)
+ self.addTaskIdHeaderIfPresent()
+ self.end_headers()
+ self.finish()
+ except Exception:
+ self.log.error("failed to return response",
+ exc_info=True)
def parse_request(self):
r = (SecureXMLRPCServer.SecureXMLRPCRequestHandler.
@@ -145,11 +229,11 @@
server_address,
keyfile=KEYFILE, certfile=CERTFILE, ca_certs=CACERT,
timeout=self.serverRespTimeout,
- requestHandler=LoggingHandler)
+ requestHandler=RequestHandler)
else:
server = utils.SimpleThreadedXMLRPCServer(
server_address,
- requestHandler=LoggingHandler, logRequests=True)
+ requestHandler=RequestHandler, logRequests=True)
utils.closeOnExec(server.socket.fileno())
server.lastClientTime = 0
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index 31a6e1c..42b54ce 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -1674,6 +1674,18 @@
self._spmSchedule(spUUID, "downloadImage", pool.downloadImage,
methodArgs, sdUUID, imgUUID, volUUID)
+ @public
+ def downloadImageFromStream(self, methodArgs, spUUID, sdUUID, imgUUID,
+ volUUID=None):
+ """
+ Download an image from a stream synchronously.
+ """
+ sdCache.produce(sdUUID)
+ pool = self.getPool(spUUID)
+ self._spmSchedule(spUUID, "downloadImageFromStream %s" %
+ imgUUID, lambda: True)
+ pool.downloadImage(methodArgs, sdUUID, imgUUID, volUUID)
+
@deprecated
@public
def moveMultipleImages(self, spUUID, srcDomUUID, dstDomUUID, imgDict,
diff --git a/vdsm/storage/imageSharing.py b/vdsm/storage/imageSharing.py
index 26f299a..fa2080d 100644
--- a/vdsm/storage/imageSharing.py
+++ b/vdsm/storage/imageSharing.py
@@ -20,6 +20,9 @@
import logging
import curlImgWrap
+import storage_exception as se
+from vdsm import constants
+from vdsm import utils
log = logging.getLogger("Storage.ImageSharing")
@@ -46,6 +49,20 @@
return size
+def streamGetSize(methodArgs):
+ size = None
+ if 'Content-Length' in methodArgs:
+ size = int(methodArgs['Content-Length'])
+ return size
+
+
+def streamGetBufferSize(methodArgs):
+ size = None
+ if 'X-Buffer-Size' in methodArgs:
+ size = int(methodArgs['X-Buffer-Size'])
+ return size
+
+
def httpDownloadImage(dstImgPath, methodArgs):
curlImgWrap.download(methodArgs.get('url'), dstImgPath,
methodArgs.get("headers", {}))
@@ -56,8 +73,41 @@
methodArgs.get("headers", {}))
+def streamDownloadImage(dstImgPath, methodArgs):
+ bytes_left = streamGetSize(methodArgs)
+ buffer_size = streamGetBufferSize(methodArgs)
+ stream = methodArgs.get('fileObj')
+
+ BS = constants.MEGAB
+ count = bytes_left / BS
+ cmd = [constants.EXT_DD, "of=%s" % dstImgPath, "bs=%s" %
+ constants.MEGAB, "count=%d" % count]
+ p = utils.execCmd(cmd, sudo=False, sync=False)
+
+ default_read_size = buffer_size
+ if default_read_size is None:
+ default_read_size = BS
+
+ while bytes_left > 0:
+ i = min(default_read_size, bytes_left)
+ data = stream.read(i)
+ if not data:
+ break
+ p.stdin.write(data)
+ p.stdin.flush()
+ bytes_left = bytes_left - i
+
+ p.stdin.close()
+ p.wait()
+ if p.returncode != 0:
+ log.error("streamDownloadImage failed",
+ p.returncode, p.stderr.read(1000))
+ raise se.MiscFileWriteException()
+
+
_METHOD_IMPLEMENTATIONS = {
'http': (httpGetSize, httpDownloadImage, httpUploadImage),
+ 'stream': (streamGetSize, streamDownloadImage, None),
}
--
To view, visit http://gerrit.ovirt.org/23281
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I768b84799ed9fb2769c6d4240519d036f8988b99
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Liron Ar <laravot(a)redhat.com>
Nir Soffer has posted comments on this change.
Change subject: test: jsonRpcTests not stable
......................................................................
Patch Set 1:
(3 comments)
http://gerrit.ovirt.org/#/c/24575/1//COMMIT_MSG
Commit Message:
Line 6:
Line 7: test: jsonRpcTests not stable
Line 8:
Line 9: settimeout should be run before connect but during tests close method
Line 10: closes the socket id for the process but the connection is still opened
Do you mean "socket fd"?
Do you mean "the connection is still opened."?
Line 11: if another process shares this socket id so from time to time the socket
Line 12: is reused and error 'Bad file descriptor' is raised during next test.
Line 13:
Line 14: Change-Id: Icc114b5241dc7db715023524f11c81689847e75f
Line 8:
Line 9: settimeout should be run before connect but during tests close method
Line 10: closes the socket id for the process but the connection is still opened
Line 11: if another process shares this socket id so from time to time the socket
Line 12: is reused and error 'Bad file descriptor' is raised during next test.
Do you mean that we use the file descriptor after it was closed?
Line 13:
Line 14: Change-Id: Icc114b5241dc7db715023524f11c81689847e75f
http://gerrit.ovirt.org/#/c/24575/1/lib/yajsonrpc/asyncoreReactor.py
File lib/yajsonrpc/asyncoreReactor.py:
Line 137: self._chat.push(self._impl.buildMessage(message), self._dispatcher)
Line 138: self._reactor.wakeup()
Line 139:
Line 140: def close(self):
Line 141: self._dispatcher.socket.shutdown(socket.SHUT_RDWR)
How this will solve double close (this seems to be the problem according to the commit message.
This should help in getting data sent through the socket to the other side. Instead of getting a connection reset, you will get EPIPE after your read all the data.
Line 142: self._dispatcher.close()
Line 143:
Line 144:
Line 145: def AsyncoreListener(reactor, address, acceptHandler, sslctx=None):
--
To view, visit http://gerrit.ovirt.org/24575
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: comment
Gerrit-Change-Id: Icc114b5241dc7db715023524f11c81689847e75f
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Piotr Kliczewski <piotr.kliczewski(a)gmail.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Nir Soffer <nsoffer(a)redhat.com>
Gerrit-Reviewer: Saggi Mizrahi <smizrahi(a)redhat.com>
Gerrit-Reviewer: oVirt Jenkins CI Server
Gerrit-HasComments: Yes
Dan Kenigsberg has posted comments on this change.
Change subject: New before_device_create/before_nic_hotplug hook: privatevlan
......................................................................
Patch Set 5:
(5 comments)
Thanks for the fixes, few minor questions remain.
http://gerrit.ovirt.org/#/c/24195/5/vdsm_hooks/privatevlan/README
File vdsm_hooks/privatevlan/README:
Line 27:
Line 28: privatevlan_guest_learn=none
Line 29: This is an optional parameter. It is recommended that you set this
Line 30: to none, or leave unset. DHCP snooping functionality is claimed to
Line 31: be available ("dhcp"), but seems broken with qemu guests. The
Is there a libvirt bug about this? If not, please open one!
Line 32: default setting is "any", which means that if the guest IP isn't
Line 33: provided, the filter is not applied until an outbound IP packet is
Line 34: sent, then the IP is locked in until shutdown or migrate.
Line 35:
Line 46: set for other hooks. Please adjust accordingly.
Line 47:
Line 48: NOTE:
Line 49: the filter will be applied only after restart of libvirtd on the host system.
Line 50: # service libvirtd restart
I am sorry, but Toni has misled you. On el6 one must NOT call `service libvirtd restart` since it is NOT redirected to upstart.
Line 51:
Line 52: to see libvirt filters use:
Line 53: # ebtables -t nat -L
Line 54:
http://gerrit.ovirt.org/#/c/24195/5/vdsm_hooks/privatevlan/before_device_cr…
File vdsm_hooks/privatevlan/before_device_create.py:
Line 24: import sys
Line 25: import hooking
Line 26: import traceback
Line 27:
Line 28: # Name of the predefined nwfilter
This comment did not help me. If you think that the use of LIBVIRT_FILTER is not clear (it's clear to me), find a better name for it.
Line 29: LIBVIRT_FILTER = 'privatevlan-vdsm'
Line 30:
Line 31:
Line 32: def addInterfaceFilter(document, interface, allowed_macs, ipaddresses, learn):
Line 65:
Line 66:
Line 67: def main():
Line 68: allowed_macs = os.environ.get('privatevlan_allowed_macs', None)
Line 69: if allowed_macs is None:
Interpreting the empty string in the same way would make the hook a bit more usable - unless you think that passing the empty string is indeed an error.
Line 70: return
Line 71:
Line 72: iplist = os.environ.get('privatevlan_guest_ip', None)
Line 73: learn = os.environ.get('privatevlan_guest_learn', None)
Line 111:
Line 112: try:
Line 113: main()
Line 114: except Exception:
Line 115: sys.stderr.write('privatevlan: [unexpected error]: %s\n' %
why did you opt not to use hooking.exit_hook()?
Line 116: traceback.format_exc())
--
To view, visit http://gerrit.ovirt.org/24195
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: comment
Gerrit-Change-Id: Idda6f193c0095241bc1540a0241d49426c000fb3
Gerrit-PatchSet: 5
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Michael Samuel <mik(a)miknet.net>
Gerrit-Reviewer: Antoni Segura Puimedon <asegurap(a)redhat.com>
Gerrit-Reviewer: Assaf Muller <amuller(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Michael Samuel <mik(a)miknet.net>
Gerrit-Reviewer: oVirt Jenkins CI Server
Gerrit-HasComments: Yes