Change in vdsm[master]: after_vm_destroy.py: migrate to jsonrpcvdscli
by igoihman@redhat.com
Irit Goihman has uploaded a new change for review.
Change subject: after_vm_destroy.py: migrate to jsonrpcvdscli
......................................................................
after_vm_destroy.py: migrate to jsonrpcvdscli
vdscli is deprecated and replaced by jsonrpcvdscli
Change-Id: I3f3fa6479dde2c4a1298d0ae167d888d9f7e020a
Signed-off-by: Irit Goihman <igoihman(a)redhat.com>
---
M vdsm_hooks/vhostmd/after_vm_destroy.py
1 file changed, 10 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/83/62383/1
diff --git a/vdsm_hooks/vhostmd/after_vm_destroy.py b/vdsm_hooks/vhostmd/after_vm_destroy.py
index e8887bd..7064286 100644
--- a/vdsm_hooks/vhostmd/after_vm_destroy.py
+++ b/vdsm_hooks/vhostmd/after_vm_destroy.py
@@ -1,6 +1,6 @@
#!/usr/bin/python
#
-# Copyright 2011 Red Hat, Inc.
+# Copyright 2011-2016 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
@@ -22,14 +22,20 @@
import os
import subprocess
import hooking
-from vdsm import vdscli
-s = vdscli.connect()
+from vdsm.config import config
+from vdsm import jsonrpcvdscli
-res = s.list(True)
+requestQueues = config.get("addresses", "request_queues")
+requestQueue = requestQueues.split(",")[0]
+server = jsonrpcvdscli.connect(requestQueue=requestQueue)
+
+res = server.list(True)
if res['status']['code'] == 0:
if not [v for v in res['vmList']
if v.get('vmId') != os.environ.get('vmId') and
hooking.tobool(v.get('custom', {}).get('sap_agent', False))]:
subprocess.call(['/usr/bin/sudo', '-n', '/sbin/service', 'vhostmd',
'stop'])
+
+server.close()
--
To view, visit https://gerrit.ovirt.org/62383
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3f3fa6479dde2c4a1298d0ae167d888d9f7e020a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Irit Goihman <igoihman(a)redhat.com>
7 years, 3 months
Change in vdsm[master]: py3: make network/tc_test pass
by Dan Kenigsberg
Dan Kenigsberg has uploaded a new change for review.
Change subject: py3: make network/tc_test pass
......................................................................
py3: make network/tc_test pass
Change-Id: I544446358e611a0507aad7d7df4ab6c57ad5bdf0
Signed-off-by: Dan Kenigsberg <danken(a)redhat.com>
---
M tests/Makefile.am
M tests/network/tc_test.py
2 files changed, 8 insertions(+), 9 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/98/63198/1
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2dce548..7243e50 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -201,7 +201,6 @@
network/ovs_driver_test.py \
network/ovs_info_test.py \
network/ovs_test.py \
- network/tc_test.py \
network/unified_persistence_test.py \
numaUtilsTests.py \
outOfProcessTests.py \
diff --git a/tests/network/tc_test.py b/tests/network/tc_test.py
index 7ac30c0..12bd17e 100644
--- a/tests/network/tc_test.py
+++ b/tests/network/tc_test.py
@@ -25,14 +25,14 @@
import os
import sys
from binascii import unhexlify
-from itertools import izip_longest
from subprocess import Popen, PIPE
from nose.plugins.attrib import attr
import six
+from six.moves import zip_longest
-from hostdevTests import Connection
+from vmfakecon import Connection
from testlib import (VdsmTestCase as TestCaseBase, permutations,
expandPermutations)
from testValidation import ValidateRunningAsRoot, stresstest
@@ -170,8 +170,8 @@
with open(path) as tc_filter_show:
data = tc_filter_show.read()
- for parsed, correct in izip_longest(tc._filters(None, out=data),
- filters):
+ for parsed, correct in zip_longest(tc._filters(None, out=data),
+ filters):
self.assertEqual(parsed, correct)
def test_qdiscs(self):
@@ -220,8 +220,8 @@
'target': 5000.0, 'interval': 150000.0,
'ecn': True}},
)
- for parsed, correct in izip_longest(tc.qdiscs(None, out=data),
- qdiscs):
+ for parsed, correct in zip_longest(tc.qdiscs(None, out=data),
+ qdiscs):
self.assertEqual(parsed, correct)
def test_classes(self):
@@ -265,8 +265,8 @@
'leaf': '5000:', 'hfsc': {'ls': {'m1': 0, 'd': 0,
'm2': reported_ls_5000}}},
)
- for parsed, correct in izip_longest(tc.classes(None, out=data),
- classes):
+ for parsed, correct in zip_longest(tc.classes(None, out=data),
+ classes):
self.assertEqual(parsed, correct)
--
To view, visit https://gerrit.ovirt.org/63198
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I544446358e611a0507aad7d7df4ab6c57ad5bdf0
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Dan Kenigsberg <danken(a)redhat.com>
7 years, 3 months
Change in vdsm[master]: contrib: Simple jsonrpc client
by Nir Soffer
Nir Soffer has uploaded a new change for review.
Change subject: contrib: Simple jsonrpc client
......................................................................
contrib: Simple jsonrpc client
This is a simple jsonrpc client for communicating with the jsonrpc
server from the command line.
Arguments
method one of the mehtods described in json schema
params optionl json object with message parameters
Examples
Calling method without arguements:
# jsonrpc Host.getVMList
{
"jsonrpc": "2.0",
"id": "0e043d83-294a-4d31-b1b6-6dc2f2747494",
"result": [
"b3f6fa00-b315-4ad4-8108-f73da817b5c5"
]
}
Calling method with arguements:
# jsonrpc VM.getStats '{"vmID": "b3f6fa00-b315-4ad4-8108-f73da817b5c5"}'
{
"jsonrpc": "2.0",
"id": "cefd25a3-6250-4123-8a56-d7047899e19e",
"result": [
{
"status": "Down",
"exitMessage": "Admin shut down from the engine",
"vmId": "b3f6fa00-b315-4ad4-8108-f73da817b5c5",
"exitReason": 6,
"timeOffset": "0",
"exitCode": 0
}
]
}
Requires stomp.py library:
https://pypi.python.org/pypi/stomp.py
Change-Id: Ia6273eabf6f3601602659d1e4e748d8025ae8084
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
---
A contrib/jsonrpc
1 file changed, 104 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/81/35181/1
diff --git a/contrib/jsonrpc b/contrib/jsonrpc
new file mode 100755
index 0000000..3080193
--- /dev/null
+++ b/contrib/jsonrpc
@@ -0,0 +1,104 @@
+#!/usr/bin/python
+#
+# Copyright 2014 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
+#
+"""
+jsonrpc-cli - Vdsm jsonrpc client
+"""
+
+import json
+import os
+import signal
+import sys
+import time
+import uuid
+import optparse
+
+import stomp
+
+# Copied from lib/vdsm/vdscli.py
+PKIDIR = '/etc/pki/vdsm'
+KEYFILE = os.path.join(PKIDIR, 'keys/vdsmkey.pem')
+CERTFILE = os.path.join(PKIDIR, 'certs/vdsmcert.pem')
+CACERT = os.path.join(PKIDIR, 'certs/cacert.pem')
+
+PORT = 54321
+DESTINATION = "/queue/_local/vdsm/requests"
+
+
+class Listener(stomp.ConnectionListener):
+
+ def on_error(self, headers, message):
+ print 'Error: %s' % message
+ terminate()
+
+ def on_message(self, headers, message):
+ msg = json.loads(message)
+ print json.dumps(msg, indent=4)
+ terminate()
+
+
+def main(args):
+ parser = option_parser()
+ options, args = parser.parse_args(args)
+ if not args:
+ parser.error("method required")
+
+ msg = {
+ "id": str(uuid.uuid4()),
+ "jsonrpc": "2.0",
+ "method": args[0]
+ }
+
+ if len(args) > 1:
+ msg["params"] = json.loads(args[1])
+
+ conn = stomp.Connection10(
+ host_and_ports=((options.host, PORT),),
+ use_ssl=True,
+ ssl_key_file=KEYFILE,
+ ssl_cert_file=CERTFILE,
+ ssl_ca_certs=CACERT)
+
+ conn.set_listener("", Listener())
+ conn.start()
+ conn.send(body=json.dumps(msg), destination=DESTINATION)
+
+ try:
+ signal.pause()
+ except KeyboardInterrupt:
+ pass
+
+ conn.disconnect()
+
+
+def option_parser():
+ parser = optparse.OptionParser(usage='%prog [options] method [params]')
+ parser.add_option("-a", "--host", dest="host",
+ help="host address (default localhost)")
+ parser.set_defaults(host="localhost")
+ return parser
+
+
+def terminate():
+ os.kill(os.getpid(), signal.SIGINT)
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
--
To view, visit http://gerrit.ovirt.org/35181
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia6273eabf6f3601602659d1e4e748d8025ae8084
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsoffer(a)redhat.com>
7 years, 4 months
Change in vdsm[master]: cleanup: remove persist/unpersist calls for legacy node
by Douglas Schilling Landgraf
Douglas Schilling Landgraf has uploaded a new change for review.
Change subject: cleanup: remove persist/unpersist calls for legacy node
......................................................................
cleanup: remove persist/unpersist calls for legacy node
This patch removes all related to unpersist and persist
calls exclusive for oVirt Node Legacy. oVirt Node Next doesn't
require such approach.
Change-Id: I1cca0cfa0e2254a5a8af6b3591ffe47689410415
Signed-off-by: Douglas Schilling Landgraf <dougsland(a)redhat.com>
---
M lib/vdsm/network/configurators/ifcfg.py
M lib/vdsm/tool/configfile.py
M lib/vdsm/tool/configurators/certificates.py
M lib/vdsm/tool/configurators/libvirt.py
M lib/vdsm/tool/configurators/multipath.py
M lib/vdsm/tool/configurators/passwd.py
M lib/vdsm/tool/register.py
M lib/vdsm/tool/upgrade.py
M lib/vdsm/tool/validate_ovirt_certs.py.in
M lib/vdsm/utils.py
M tests/toolTests.py
M vdsm.spec.in
M vdsm/Makefile.am
D vdsm/ovirt_functions.sh
M vdsm/vdsm-store-net-config.in
M vdsm_hooks/Makefile.am
M vdsm_hooks/fcoe/fcoe_before_network_setup.py
D vdsm_hooks/persist-vdsm-hooks.in
D vdsm_hooks/unpersist-vdsm-hook
19 files changed, 9 insertions(+), 219 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/15/63715/1
diff --git a/lib/vdsm/network/configurators/ifcfg.py b/lib/vdsm/network/configurators/ifcfg.py
index 2302ae1..0555034 100644
--- a/lib/vdsm/network/configurators/ifcfg.py
+++ b/lib/vdsm/network/configurators/ifcfg.py
@@ -55,9 +55,6 @@
from vdsm.network.netinfo.cache import ifaceUsed
from vdsm.network.netlink import waitfor
-if utils.isOvirtNode():
- from ovirt.node.utils import fs as node_fs
-
from . import Configurator, getEthtoolOpts
from ..errors import ConfigNetworkError, ERR_FAILED_IFUP
from ..models import Nic, Bridge
@@ -297,10 +294,7 @@
@staticmethod
def _removeFile(filename):
"""Remove file (directly or using oVirt node's library)"""
- if utils.isOvirtNode():
- node_fs.Config().delete(filename) # unpersists and shreds the file
- else:
- utils.rmFile(filename)
+ utils.rmFile(filename)
logging.debug("Removed file %s", filename)
def createLibvirtNetwork(self, network, bridged=True, iface=None,
@@ -512,10 +506,6 @@
except:
logging.debug('ignoring restorecon error in case '
'SElinux is disabled', exc_info=True)
-
- # make sure that ifcfg files are always persisted by the node
- if self.unifiedPersistence and utils.isOvirtNode():
- node_fs.Config().persist(fileName)
def _createConfFile(self, conf, name, ipv4, ipv6, mtu, nameservers,
**kwargs):
diff --git a/lib/vdsm/tool/configfile.py b/lib/vdsm/tool/configfile.py
index 0c49b19..bad0759 100644
--- a/lib/vdsm/tool/configfile.py
+++ b/lib/vdsm/tool/configfile.py
@@ -175,9 +175,7 @@
if self._entries:
self._writeEntries(f, oldentries)
- utils.unpersist(self._filename)
os.rename(tname, self._filename)
- utils.persist(self._filename)
if self._oldmod != os.stat(self._filename).st_mode:
os.chmod(self._filename, self._oldmod)
diff --git a/lib/vdsm/tool/configurators/certificates.py b/lib/vdsm/tool/configurators/certificates.py
index 0462b4d..edc96b3 100644
--- a/lib/vdsm/tool/configurators/certificates.py
+++ b/lib/vdsm/tool/configurators/certificates.py
@@ -23,10 +23,8 @@
from vdsm.config import config
from . import YES, NO
-from vdsm.tool.validate_ovirt_certs import validate_ovirt_certs
from vdsm.constants import P_VDSM_EXEC, SYSCONF_PATH
from vdsm.commands import execCmd
-from vdsm.utils import isOvirtNode
PKI_DIR = os.path.join(SYSCONF_PATH, 'pki/vdsm')
CA_FILE = os.path.join(PKI_DIR, 'certs/cacert.pem')
@@ -59,8 +57,6 @@
def configure():
_exec_vdsm_gencerts()
- if isOvirtNode():
- validate_ovirt_certs()
def isconfigured():
diff --git a/lib/vdsm/tool/configurators/libvirt.py b/lib/vdsm/tool/configurators/libvirt.py
index 40d4958..94c5da2 100644
--- a/lib/vdsm/tool/configurators/libvirt.py
+++ b/lib/vdsm/tool/configurators/libvirt.py
@@ -27,12 +27,8 @@
from . import InvalidRun, NO, MAYBE
from . certificates import CA_FILE, CERT_FILE, KEY_FILE
from vdsm.tool.configfile import ConfigFile, ParserWrapper
-from vdsm.tool.validate_ovirt_certs import validate_ovirt_certs
from vdsm import utils
from vdsm import constants
-
-if utils.isOvirtNode():
- from ovirt.node.utils.fs import Config as NodeCfg
requires = frozenset(('certificates',))
@@ -45,12 +41,6 @@
def configure():
- if utils.isOvirtNode():
- if not os.path.exists(constants.P_VDSM_CERT):
- raise InvalidRun(
- "vdsm: Missing certificate, vdsm not registered")
- validate_ovirt_certs()
-
# Remove a previous configuration (if present)
removeConf()
@@ -193,14 +183,11 @@
"""
delete a file if it exists.
"""
- if utils.isOvirtNode():
- NodeCfg().delete(content['path'])
- else:
- try:
- os.unlink(content['path'])
- except OSError as e:
- if e.errno != errno.ENOENT:
- raise
+ try:
+ os.unlink(content['path'])
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise
def _removeSection(path):
diff --git a/lib/vdsm/tool/configurators/multipath.py b/lib/vdsm/tool/configurators/multipath.py
index 00ec558..a402cda 100644
--- a/lib/vdsm/tool/configurators/multipath.py
+++ b/lib/vdsm/tool/configurators/multipath.py
@@ -112,7 +112,6 @@
backup = _CONF_FILE + '.' + time.strftime("%Y%m%d%H%M")
shutil.copyfile(_CONF_FILE, backup)
sys.stdout.write("Backup previous multipath.conf to %r\n" % backup)
- utils.persist(backup)
with tempfile.NamedTemporaryFile(
mode="wb",
@@ -125,15 +124,10 @@
if selinux.is_selinux_enabled():
selinux.restorecon(f.name)
os.chmod(f.name, 0o644)
- # On ovirt node multipath.conf is a bind mount and rename will fail
- # if we do not unpersist first, making this non-atomic.
- utils.unpersist(_CONF_FILE)
os.rename(f.name, _CONF_FILE)
except:
os.unlink(f.name)
raise
-
- utils.persist(_CONF_FILE)
# Flush all unused multipath device maps
commands.execCmd([constants.EXT_MULTIPATH, "-F"])
diff --git a/lib/vdsm/tool/configurators/passwd.py b/lib/vdsm/tool/configurators/passwd.py
index 62830df..b75228e 100644
--- a/lib/vdsm/tool/configurators/passwd.py
+++ b/lib/vdsm/tool/configurators/passwd.py
@@ -51,10 +51,6 @@
rc, _, err = commands.execCmd(script, data=libvirt_password())
if rc != 0:
raise RuntimeError("Set password failed: %s" % (err,))
- if utils.isOvirtNode():
- # It seems that all /etc/libvirt folder is persisted in node,
- # but better to persist the db file explicitly
- utils.persist(_LIBVIRT_SASLDB)
def removeConf():
diff --git a/lib/vdsm/tool/register.py b/lib/vdsm/tool/register.py
index d0ae207..ea74bec 100644
--- a/lib/vdsm/tool/register.py
+++ b/lib/vdsm/tool/register.py
@@ -266,18 +266,11 @@
__VDSM_ID = "/etc/vdsm/vdsm.id"
if self.vdsm_uuid and os.path.exists(__VDSM_ID):
- if utils.isOvirtNode():
- from ovirt.node.utils.fs import Config
- Config().unpersist(__VDSM_ID)
os.unlink(__VDSM_ID)
if not os.path.exists(__VDSM_ID):
with open(__VDSM_ID, 'w') as f:
f.write(self.uuid)
-
- if utils.isOvirtNode():
- from ovirt.node.utils.fs import Config
- Config().persist(__VDSM_ID)
self.logger.info("Host UUID: {u}".format(u=self.uuid))
@@ -294,9 +287,6 @@
if not os.path.exists(self.ca_dir):
os.makedirs(self.ca_dir, 0o755)
self._silent_restorecon(self.ca_dir)
- if utils.isOvirtNode():
- from ovirt.node.utils.fs import Config
- Config().persist(self.ca_dir)
res = self._execute_http_request(self.url_CA,
cert_validation=False)
@@ -328,10 +318,6 @@
self.logger.info("Calculated fingerprint: {f}".format(
f=self.fprint))
- if utils.isOvirtNode():
- from ovirt.node.utils.fs import Config
- Config().persist(self.ca_engine)
-
def download_ssh(self):
"""
Download ssh authorized keys and save it in the node
@@ -345,9 +331,6 @@
if not os.path.exists(_auth_keys_dir):
os.makedirs(_auth_keys_dir, 0o700)
self._silent_restorecon(_auth_keys_dir)
- if utils.isOvirtNode():
- from ovirt.node.utils.fs import Config
- Config().persist(_auth_keys_dir)
os.chown(_auth_keys_dir, _uid, _uid)
res = self._execute_http_request(self.url_ssh_key)
@@ -368,9 +351,6 @@
os.chown(_auth_keys, _uid, _uid)
os.unlink(f.name)
- if utils.isOvirtNode():
- from ovirt.node.utils.fs import Config
- Config().persist(_auth_keys)
def execute_registration(self):
"""
diff --git a/lib/vdsm/tool/upgrade.py b/lib/vdsm/tool/upgrade.py
index 4bc904c..291ef13 100644
--- a/lib/vdsm/tool/upgrade.py
+++ b/lib/vdsm/tool/upgrade.py
@@ -46,7 +46,6 @@
except (OSError, IOError):
_get_upgrade_log().exception("Failed to seal upgrade %s", upgrade.name)
else:
- utils.persist(seal_file)
_get_upgrade_log().debug("Upgrade %s successfully performed",
upgrade.name)
diff --git a/lib/vdsm/tool/validate_ovirt_certs.py.in b/lib/vdsm/tool/validate_ovirt_certs.py.in
index 53726d0..1e6a370 100644
--- a/lib/vdsm/tool/validate_ovirt_certs.py.in
+++ b/lib/vdsm/tool/validate_ovirt_certs.py.in
@@ -25,11 +25,6 @@
from . import expose, ExtraArgsError
from ..commands import execCmd
-try:
- from ovirtnode import ovirtfunctions
-except ImportError:
- pass
-
EX_OPENSSL = '@OPENSSL_PATH@'
@@ -60,8 +55,6 @@
if not is_our_cafile(PATH_CACERT):
for f in os.listdir(PATH_CERT):
if is_our_cafile(PATH_CERT + f):
- ovirtfunctions.ovirt_safe_delete_config(PATH_CACERT)
shutil.copy(PATH_CERT + f, PATH_CACERT)
os.chown(PATH_CACERT, uid, gid)
- ovirtfunctions.ovirt_store_config(PATH_CACERT)
break
diff --git a/lib/vdsm/utils.py b/lib/vdsm/utils.py
index 0ff1a3c..5401654 100644
--- a/lib/vdsm/utils.py
+++ b/lib/vdsm/utils.py
@@ -597,12 +597,6 @@
zombiereaper.autoReapPID(self._proc.pid)
-@memoized
-def isOvirtNode():
- return (os.path.exists('/etc/rhev-hypervisor-release') or
- bool(glob.glob('/etc/ovirt-node-*-release')))
-
-
def anyFnmatch(name, patterns):
"""Returns True if any element in the patterns iterable fnmatches name."""
return any(fnmatch(name, pattern) for pattern in patterns)
diff --git a/tests/toolTests.py b/tests/toolTests.py
index e14bb53..ab741e2 100644
--- a/tests/toolTests.py
+++ b/tests/toolTests.py
@@ -334,11 +334,6 @@
libvirt,
'FILES',
FakeFiles
- ),
- (
- utils,
- 'isOvirtNode',
- lambda: False
)
])
diff --git a/vdsm.spec.in b/vdsm.spec.in
index b9ec875..4d5caf1 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -957,9 +957,6 @@
%{_sysconfdir}/libvirt/hooks/qemu
%{_libexecdir}/%{vdsm_name}/curl-img-wrap
%{_libexecdir}/%{vdsm_name}/fc-scan
-%{_libexecdir}/%{vdsm_name}/persist-vdsm-hooks
-%{_libexecdir}/%{vdsm_name}/unpersist-vdsm-hook
-%{_libexecdir}/%{vdsm_name}/ovirt_functions.sh
%{_libexecdir}/%{vdsm_name}/vdsm-gencerts.sh
%{_libexecdir}/%{vdsm_name}/vdsmd_init_common.sh
%{_libexecdir}/%{vdsm_name}/vm_migrate_hook.py*
diff --git a/vdsm/Makefile.am b/vdsm/Makefile.am
index 8b535b6..fd38601 100644
--- a/vdsm/Makefile.am
+++ b/vdsm/Makefile.am
@@ -32,9 +32,6 @@
sitecustomize.py \
$(NULL)
-dist_vdsmexec_SCRIPTS = \
- ovirt_functions.sh
-
nodist_vdsmexec_SCRIPTS = \
vdsm-gencerts.sh \
$(NULL)
diff --git a/vdsm/ovirt_functions.sh b/vdsm/ovirt_functions.sh
deleted file mode 100644
index 12f6864..0000000
--- a/vdsm/ovirt_functions.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-#
-# Copyright 2006-2010 Red Hat, Inc. and/or its affiliates.
-#
-# 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.
-#
-
-isOvirtNode() {
- [ "$(echo /etc/ovirt-node-*-release)" != "/etc/ovirt-node-*-release" ] || \
- [ -f /etc/rhev-hypervisor-release ]
-}
-
-# execute a function if called as a script, e.g.
-# vdsm-bash-functions isOvirtNode
-
-if [ "$(basename -- "$0")" = "vdsm-bash-functions" ]; then
- "$@"
-fi
diff --git a/vdsm/vdsm-store-net-config.in b/vdsm/vdsm-store-net-config.in
index 76822ee..3292f84 100755
--- a/vdsm/vdsm-store-net-config.in
+++ b/vdsm/vdsm-store-net-config.in
@@ -16,33 +16,10 @@
PERSISTENCE=$1
-ifcfg_node_persist() {
- for f in "$NET_CONF_BACK_DIR"/*;
- do
- [ ! -f "$f" ] && continue
- bf=`basename "$f"`
- if [ -f "$NET_CONF_DIR/$bf" ];
- then
- ovirt_store_config "$NET_CONF_DIR/$bf"
- else
- ovirt_safe_delete_config "$NET_CONF_DIR/$bf"
- fi
- rm "$NET_CONF_BACK_DIR/$bf"
- done
-}
-
ifcfg_nonnode_persist() {
# Remove the backed up configuration files thus marking the ones under
# /etc/sysconfig as "safe".
rm -rf "$NET_CONF_BACK_DIR"/*
-}
-
-unified_node_persist() {
- unified_nonnode_persist
-
- # oVirt node ovirt_store_config puts the dir in persistent storage and
- # bind mounts it in the original place. So that's all we really need to do.
- ovirt_store_config "$PERS_CONF_PATH"
}
unified_nonnode_persist() {
@@ -67,21 +44,8 @@
}
-if isOvirtNode
-then
- # for node, persist the changed configuration files
-
- . /usr/libexec/ovirt-functions
-
- if [ "$PERSISTENCE" == "unified" ]; then
- unified_node_persist
- else
- ifcfg_node_persist
- fi
+if [ "$PERSISTENCE" == "unified" ]; then
+ unified_nonnode_persist
else
- if [ "$PERSISTENCE" == "unified" ]; then
- unified_nonnode_persist
- else
- ifcfg_nonnode_persist
- fi
+ ifcfg_nonnode_persist
fi
diff --git a/vdsm_hooks/Makefile.am b/vdsm_hooks/Makefile.am
index 8cbfca1..04728ad 100644
--- a/vdsm_hooks/Makefile.am
+++ b/vdsm_hooks/Makefile.am
@@ -64,18 +64,9 @@
$(NULL)
endif
-dist_vdsmexec_SCRIPTS = \
- unpersist-vdsm-hook
-
-nodist_vdsmexec_SCRIPTS = \
- persist-vdsm-hooks
-
CLEANFILES = \
config.log \
$(nodist_vdsmexec_SCRIPTS)
-
-EXTRA_DIST = \
- persist-vdsm-hooks.in
VDSMHOOKS = \
before_device_create \
diff --git a/vdsm_hooks/fcoe/fcoe_before_network_setup.py b/vdsm_hooks/fcoe/fcoe_before_network_setup.py
index c507c07..e786254 100755
--- a/vdsm_hooks/fcoe/fcoe_before_network_setup.py
+++ b/vdsm_hooks/fcoe/fcoe_before_network_setup.py
@@ -86,7 +86,6 @@
outfile.write(CONFFILE_HEADER + "\n")
for name, value in six.iteritems(config):
outfile.write('%s="%s"\n' % (name, value))
- utils.persist(filename)
def _unconfigure(interface):
@@ -95,7 +94,6 @@
"""
filename = _get_config_name(interface)
if os.path.exists(filename):
- utils.unpersist(filename)
utils.rmFile(filename)
diff --git a/vdsm_hooks/persist-vdsm-hooks.in b/vdsm_hooks/persist-vdsm-hooks.in
deleted file mode 100644
index e7423fb..0000000
--- a/vdsm_hooks/persist-vdsm-hooks.in
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2009-2010 Red Hat, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Description: Persist all VDSM hooks
-#
-
-. @LIBEXECDIR(a)/ovirt_functions.sh
-
-HOOKS_DIR=/usr/libexec/vdsm/hooks
-
-if isOvirtNode
-then
- . /usr/libexec/ovirt-functions
- for hook in "$HOOKS_DIR"/*/*
- do
- if [[ -f "$hook" ]]
- then
- ovirt_store_config "$hook"
- fi
- done
-else
- echo "Host is not RHEV-Hypervisor"
- exit 1
-fi
diff --git a/vdsm_hooks/unpersist-vdsm-hook b/vdsm_hooks/unpersist-vdsm-hook
deleted file mode 100755
index af5af27..0000000
--- a/vdsm_hooks/unpersist-vdsm-hook
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2009-2010 Red Hat, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Description: Unpersist VDSM Hook
-# Input: VDSM Hook file full path
-#
-
-HOOKS_DIR=/usr/libexec/vdsm/hooks
-HOOK_TO_UNPERSIST="$1"
-
-if [[ -z "$HOOK_TO_UNPERSIST" ]]; then
- echo "usage: $0 hook_file"
- exit 1
-fi
-
-if [[ -f /etc/rhev-hypervisor-release ]]
-then
- . /usr/libexec/ovirt-functions
- if [[ "$HOOK_TO_UNPERSIST" =~ ^"$HOOKS_DIR" ]]
- then
- # try to unpersist files only
- if [[ -f "$HOOK_TO_UNPERSIST" ]]
- then
- ovirt_safe_delete_config "$HOOK_TO_UNPERSIST"
- fi
- fi
-else
- echo "Host is not RHEV-Hypervisor"
- exit 1
-fi
--
To view, visit https://gerrit.ovirt.org/63715
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1cca0cfa0e2254a5a8af6b3591ffe47689410415
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Douglas Schilling Landgraf <dougsland(a)redhat.com>
7 years, 4 months
Change in vdsm[master]: spbackends: simplify over-general evaluation
by Dan Kenigsberg
Dan Kenigsberg has uploaded a new change for review.
Change subject: spbackends: simplify over-general evaluation
......................................................................
spbackends: simplify over-general evaluation
The removed code is too clever for the use case of only two values.
Change-Id: I775c4a6003a03c6b65bee3abc8559a88e3eaec01
Signed-off-by: Dan Kenigsberg <danken(a)redhat.com>
---
M vdsm/storage/spbackends.py
1 file changed, 5 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/53/41253/1
diff --git a/vdsm/storage/spbackends.py b/vdsm/storage/spbackends.py
index 953e01e..f6ce02b 100644
--- a/vdsm/storage/spbackends.py
+++ b/vdsm/storage/spbackends.py
@@ -229,8 +229,11 @@
def setSpmStatus(self, lVer=None, spmId=None):
self.invalidateMetadata()
- metaParams = dict(filter(lambda kv: kv[1] is not None,
- ((PMDK_LVER, lVer), (PMDK_SPM_ID, spmId))))
+ metaParams = {}
+ if lVer is not None:
+ metaParams[PMDK_LVER] = lVer
+ if spmId is not None:
+ metaParams[PMDK_SPM_ID] = spmId
self._metadata.update(metaParams)
@unsecured
--
To view, visit https://gerrit.ovirt.org/41253
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I775c4a6003a03c6b65bee3abc8559a88e3eaec01
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Dan Kenigsberg <danken(a)redhat.com>
7 years, 4 months
Change in vdsm[master]: Method not found should return proper code
by Piotr Kliczewski
Piotr Kliczewski has uploaded a new change for review.
Change subject: Method not found should return proper code
......................................................................
Method not found should return proper code
When a method is not found we should return -32601 code.
Change-Id: I9b3e1360303bca7ae3c30846ad46fec1fadac7fb
Signed-off-by: Piotr Kliczewski <piotr.kliczewski(a)gmail.com>
---
M lib/vdsm/rpc/Bridge.py
1 file changed, 1 insertion(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/20/63120/1
diff --git a/lib/vdsm/rpc/Bridge.py b/lib/vdsm/rpc/Bridge.py
index bd180e0..0bd1aaa 100644
--- a/lib/vdsm/rpc/Bridge.py
+++ b/lib/vdsm/rpc/Bridge.py
@@ -110,7 +110,7 @@
try:
className, methodName = method.split('.', 1)
self._schema.get_method(vdsmapi.MethodRep(className, methodName))
- except (KeyError, ValueError):
+ except (vdsmapi.MethodNotFound, ValueError):
raise yajsonrpc.JsonRpcMethodNotFoundError(method)
return partial(self._dynamicMethod, className, methodName)
--
To view, visit https://gerrit.ovirt.org/63120
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I9b3e1360303bca7ae3c30846ad46fec1fadac7fb
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Piotr Kliczewski <piotr.kliczewski(a)gmail.com>
7 years, 4 months
Change in vdsm[master]: spec: bridge-utils are required for tests
by fabiand@redhat.com
Fabian Deutsch has uploaded a new change for review.
Change subject: spec: bridge-utils are required for tests
......................................................................
spec: bridge-utils are required for tests
Change-Id: I115f7e9d01fa74c36ef535f85474ffb16177f429
Signed-off-by: Fabian Deutsch <fabiand(a)fedoraproject.org>
---
M vdsm.spec.in
1 file changed, 1 insertion(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/12/62612/1
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 392b071..c23cde5 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -89,6 +89,7 @@
BuildRequires: rpm-python
BuildRequires: python-blivet
BuildRequires: sanlock-python
+BuildRequires: bridge-utils
%if 0%{?with_openvswitch}
BuildRequires: openvswitch >= 2.0.0
@@ -253,7 +254,6 @@
%endif
Requires: psmisc >= 22.6-15
-Requires: bridge-utils
Requires: sos
Requires: tree
Requires: dosfstools
--
To view, visit https://gerrit.ovirt.org/62612
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I115f7e9d01fa74c36ef535f85474ffb16177f429
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Fabian Deutsch <fabiand(a)redhat.com>
7 years, 4 months
Change in vdsm[master]: sos: replace dumpStorageTable with dump_volume_chains
by igoihman@redhat.com
Irit Goihman has uploaded a new change for review.
Change subject: sos: replace dumpStorageTable with dump_volume_chains
......................................................................
sos: replace dumpStorageTable with dump_volume_chains
dumpStorageTable is old and uses vdscli and has been replaced with
dump_volume_chains which uses jsonrpcvdscli
Change-Id: I73a85e6e720b61da1673af7161a21589ade79831
Signed-off-by: Irit Goihman <igoihman(a)redhat.com>
---
M vdsm/sos/vdsm.py.in
1 file changed, 6 insertions(+), 6 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/28/62628/1
diff --git a/vdsm/sos/vdsm.py.in b/vdsm/sos/vdsm.py.in
index 09ebb78..998c5a1 100644
--- a/vdsm/sos/vdsm.py.in
+++ b/vdsm/sos/vdsm.py.in
@@ -60,6 +60,7 @@
config = _importVdsmPylibModule("vdsm.config").config
jsonrpcvdscli = _importVdsmPylibModule("vdsm.jsonrpcvdscli")
+dump_volume_chains = _importVdsmPylibModule("vdsm.tool.dump_volume_chains")
class vdsm(Plugin, RedHatPlugin):
@@ -151,12 +152,11 @@
self.addObjectAsFile(
cli.getSpmStatus(pool), "getSpmStatus " + pool)
- self.collectExtOutput(
- '/bin/su vdsm -s %s %s/dumpStorageTable.pyc' % (
- '@PYTHON@',
- '@VDSMDIR@',
- )
- )
+ sd_uuid, = cli.getStorageDomainsList()["items"]
+
+ self.addObjectAsFile(
+ dump_volume_chains.dump_chains("dump-volume-chains", sd_uuid),
+ "dump_volume_chains")
def _addVdsmRunDir(self):
"""Add everything under /var/run/vdsm except possibly confidential
--
To view, visit https://gerrit.ovirt.org/62628
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I73a85e6e720b61da1673af7161a21589ade79831
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Irit Goihman <igoihman(a)redhat.com>
7 years, 4 months
Change in vdsm[master]: doc: add basic quickstart for containers
by fromani@redhat.com
Francesco Romani has uploaded a new change for review.
Change subject: doc: add basic quickstart for containers
......................................................................
doc: add basic quickstart for containers
Change-Id: I0fb768ea97dd719cde9bd5e57e1b7cabe4b0f0ae
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
---
M README
1 file changed, 57 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/24/59824/1
diff --git a/README b/README
index 955dfa9..370028e 100644
--- a/README
+++ b/README
@@ -32,6 +32,63 @@
The 'vdsm.spec' file demonstrates how to distribute Vdsm as an RPM
package.
+Containers support
+==================
+
+While Vdsm focus is on managing KVM virtual machines, it could also run
+containers alongside virtual machines using popular formats and runtimes,
+such as rkt and appc images.
+
+Containers are reported as special-purpose VMs to the clients, and responds
+to the Vdsm API invoked on them.
+If a particular container runtime doesn't support an operation, this will
+fail with a standard Vdsm error.
+
+To try this out, you just need to install the 'vdsm-containers subpackage'.
+Make sure to restart *both* supervdsmd and vdsmd once that package is installed.
+You'll also need to have the container runtime you wish to use installed on
+the same host which runs Vdsm. The supported runtimes are:
+
+- rkt (main supported runtime)
+- runc (work in progress)
+- docker (very experimental)
+
+The supported image container formats depend on the container runtime.
+For example, modern rkt could run docker images transparently.
+
+To check if the Vdsm is properly configured to run containers, just do:
+
+# vdsClient -s 0 getVdsCaps | grep containers
+
+ containers = ['rkt']
+
+This means that this Vdsm could also run containers using `rkt`.
+
+Any Engine >= 3.6 could handle containers - they are just VMs from its perspective.
+You just need to set few custom properties. Run this command
+on your Engine host:
+
+# engine-config -s UserDefinedVMProperties='volumeMap=^[a-zA-Z_-]+:[a-zA-Z_-]+$;containerImage=^[a-zA-Z]+(://|)[a-zA-Z]+$;containerType=^(rkt|docker)$' --cver=3.6
+
+replace --cver=3.6 with the version of the Engine you are using.
+Now restart Ovirt Engine, and log in.
+
+You can now run any container. The user defined VM properties define
+the key settings which are not (yet) exposed in the engine UI.
+
+- volumeMap allows you to mount any disk inside the container, should you
+ need any persistence. It is a mapping between disks (e.g. vda)
+ and mountpoint (e.g. data). The mountpoints are just container-dependent labels.
+
+- containerImage is the URL or path of any container image supported by your
+ runtime. E.g. 'docker://redis'
+
+- containerType allows to select the runtime you want to use (e.g. rkt)
+
+Please be aware that many settings are ignored by containers, like all
+the device configurations. Only memory and CPU settings are honoured.
+
+
Getting Help
============
--
To view, visit https://gerrit.ovirt.org/59824
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0fb768ea97dd719cde9bd5e57e1b7cabe4b0f0ae
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
7 years, 4 months
Change in vdsm[master]: tests: containers: add testsuite
by fromani@redhat.com
Francesco Romani has uploaded a new change for review.
Change subject: tests: containers: add testsuite
......................................................................
tests: containers: add testsuite
Change-Id: I27ba3cecbd71b7bbba94992d6bc63ca29333e313
WIP: more tests are being ported
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
---
M configure.ac
M tests/Makefile.am
A tests/containers/Makefile.am
A tests/containers/__init__.py
A tests/containers/cgroups_test.py
A tests/containers/conttestlib.py
A tests/containers/data/bridge_down.xml
A tests/containers/data/bridge_no_source.xml
A tests/containers/data/disk_dev.xml
A tests/containers/data/disk_file_malformed.xml
A tests/containers/data/full_dom.xml
A tests/containers/data/metadata_drive_map.xml
A tests/containers/data/minimal_dom.xml
A tests/containers/data/only_disk.xml
A tests/containers/data/only_mem.xml
A tests/containers/errors_test.py
A tests/containers/fake/bin/docker
A tests/containers/fake/bin/rkt
A tests/containers/fake/bin/systemctl
A tests/containers/fake/bin/systemd-run
A tests/containers/fake/cgroups.tgz
A tests/containers/fs_test.py
A tests/containers/monkey.py
A tests/containers/xmlfile_test.py
24 files changed, 1,083 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/78/60678/1
diff --git a/configure.ac b/configure.ac
index c1dbba5..1087766 100644
--- a/configure.ac
+++ b/configure.ac
@@ -428,6 +428,7 @@
lib/vdsm/virt/containers/runtimes/Makefile
tests/Makefile
tests/common/Makefile
+ tests/containers/Makefile
tests/cpuinfo/Makefile
tests/functional/Makefile
tests/devices/Makefile
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 96c66b7..64e768d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -22,6 +22,7 @@
SUBDIRS = \
common \
+ containers \
cpuinfo \
functional \
devices \
@@ -30,6 +31,8 @@
$(NULL)
common_modules = common/*_test.py
+
+containers_modules = containers/*_test.py
device_modules = \
devices/parsing/complex_vm_tests.py \
@@ -360,6 +363,7 @@
./makecert.sh
run_modules = $(test_modules)
+run_modules += $(containers_modules)
run_modules += $(network_modules)
run_modules += $(device_modules)
run_modules += $(common_modules)
diff --git a/tests/containers/Makefile.am b/tests/containers/Makefile.am
new file mode 100644
index 0000000..afeca74
--- /dev/null
+++ b/tests/containers/Makefile.am
@@ -0,0 +1,31 @@
+#
+# Copyright 2016 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
+#
+
+vdsmcontainerstestsdir = ${vdsmtestsdir}/containers
+
+dist_vdsmcontainerstests_PYTHON = \
+ __init__.py \
+ *_test.py \
+ conttestlib.py \
+ $(NULL)
+
+dist_vdsmcontainerstests_DATA = \
+ $(NULL)
+
diff --git a/tests/containers/__init__.py b/tests/containers/__init__.py
new file mode 100644
index 0000000..44b8a6b
--- /dev/null
+++ b/tests/containers/__init__.py
@@ -0,0 +1,19 @@
+#
+# Copyright 2015-2016 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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
+#
diff --git a/tests/containers/cgroups_test.py b/tests/containers/cgroups_test.py
new file mode 100644
index 0000000..49835d0
--- /dev/null
+++ b/tests/containers/cgroups_test.py
@@ -0,0 +1,69 @@
+#
+# Copyright 2015-2016 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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
+#
+from __future__ import absolute_import
+
+import vdsm.virt.containers.metrics.cgroups
+
+from . import conttestlib
+
+
+class CgroupTests(conttestlib.CgroupTestCase):
+
+ def test_empty_cgroups(self):
+ mon = vdsm.virt.containers.metrics.cgroups.Monitorable(self.pid)
+ self.assertEquals(mon.cgroups, ())
+
+ def test_empty_cpuacct(self):
+ mon = vdsm.virt.containers.metrics.cgroups.Monitorable(self.pid)
+ self.assertIs(mon.cpuacct, None)
+
+ def test_empty_memory(self):
+ mon = vdsm.virt.containers.metrics.cgroups.Monitorable(self.pid)
+ self.assertIs(mon.memory, None)
+
+ def test_empty_blkio(self):
+ mon = vdsm.virt.containers.metrics.cgroups.Monitorable(self.pid)
+ self.assertIs(mon.blkio, None)
+
+ def test_from_pid(self):
+ mon = vdsm.virt.containers.metrics.cgroups.Monitorable.from_pid(
+ self.pid
+ )
+ self.assertTrue(mon.cgroups)
+
+ def test_pid_matches(self):
+ mon = vdsm.virt.containers.metrics.cgroups.Monitorable(self.pid)
+ self.assertEquals(mon.pid, self.pid)
+
+ def test_setup(self):
+ mon = vdsm.virt.containers.metrics.cgroups.Monitorable(self.pid)
+ mon.setup()
+ self.assertTrue(mon.cgroups)
+
+ def test_cgroups_found(self):
+ mon = vdsm.virt.containers.metrics.cgroups.Monitorable(self.pid)
+ mon.setup()
+ for cg in ('memory', 'cpuacct', 'blkio'):
+ self.assertIn(cg, mon.cgroups)
+
+ def test_update_without_setup(self):
+ mon = vdsm.virt.containers.metrics.cgroups.Monitorable(self.pid)
+ mon.update()
+ self.assertEquals(mon.cgroups, ())
diff --git a/tests/containers/conttestlib.py b/tests/containers/conttestlib.py
new file mode 100644
index 0000000..5ad3c4f
--- /dev/null
+++ b/tests/containers/conttestlib.py
@@ -0,0 +1,290 @@
+from __future__ import absolute_import
+#
+# Copyright 2015-2016 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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
+#
+
+from contextlib import contextmanager
+import collections
+import gzip
+import os
+import os.path
+import shutil
+import tarfile
+import tempfile
+import uuid
+import unittest
+
+import vdsm.virt.containers.command
+import vdsm.virt.containers.config
+import vdsm.virt.containers.config.environ
+import vdsm.virt.containers.metrics.cgroups
+import vdsm.virt.containers.runtime
+import vdsm.virt.containers.runtimes
+
+from . import monkey
+
+
+class TestCase(unittest.TestCase):
+
+ def assertNotRaises(self, callableObj=None, *args, **kwargs):
+ # This is required when any exception raised during the call should be
+ # considered as a test failure.
+ context = not_raises(self)
+ if callableObj is None:
+ return context
+ with context:
+ callableObj(*args, **kwargs)
+
+
+@contextmanager
+def not_raises(test_case):
+ try:
+ yield
+ except Exception as e:
+ raise test_case.failureException("Exception raised: %s" % e)
+
+
+class TruePath(object):
+ def cmd(self):
+ return True
+
+
+class NonePath(object):
+ def __init__(self):
+ self.cmd = None
+
+
+TEMPDIR = '/tmp'
+
+
+@contextmanager
+def named_temp_dir(base=TEMPDIR):
+ tmp_dir = tempfile.mkdtemp(dir=base)
+ try:
+ yield tmp_dir
+ finally:
+ shutil.rmtree(tmp_dir)
+
+
+def make_conf(**kwargs):
+ conf = vdsm.virt.containers.config.environ.current()
+ for k, v in list(kwargs.items()):
+ setattr(conf, k, v)
+ return conf
+
+
+@contextmanager
+def global_conf(**kwargs):
+ saved_conf = vdsm.virt.containers.config.environ.current()
+
+ conf = make_conf(**kwargs)
+ vdsm.virt.containers.config.environ.setup(conf)
+ try:
+ yield conf
+ finally:
+ vdsm.virt.containers.config.environ.setup(saved_conf)
+
+
+def fake_executables():
+ paths = ['.', './tests', './fake/bin', './tests/fake/bin']
+ return {
+ 'machinectl': vdsm.virt.containers.command.Path(
+ 'true'
+ ),
+ 'systemctl': vdsm.virt.containers.command.Path(
+ 'systemctl', paths=paths
+ ),
+ 'rkt': vdsm.virt.containers.command.Path(
+ 'rkt', paths=paths
+ ),
+ 'systemd-run': vdsm.virt.containers.command.Path(
+ 'systemd-run', paths=paths
+ ),
+ }
+
+
+class RunnableTestCase(TestCase):
+
+ def setUp(self):
+ self.guid = uuid.uuid4()
+ self.run_dir = tempfile.mkdtemp()
+ self.patch = monkey.Patch([
+ (vdsm.virt.containers.runtimes.rkt.Network, 'DIR', self.run_dir),
+ (vdsm.virt.containers.command, 'executables', fake_executables()),
+ ])
+ self.patch.apply()
+ vdsm.virt.containers.runtime.clear()
+ vdsm.virt.containers.runtime.configure()
+
+ def tearDown(self):
+ self.patch.revert()
+ shutil.rmtree(self.run_dir)
+
+
+@contextmanager
+def move_into(path):
+ oldpath = os.getcwd()
+ try:
+ os.chdir(path)
+ yield
+ finally:
+ os.chdir(oldpath)
+
+
+class CgroupTestCase(TestCase):
+
+ def setUp(self):
+ self.pid = 0
+ testdir = os.path.dirname(os.path.abspath(__file__))
+ self.root = os.path.join(testdir, 'fake')
+
+ self.procfsroot = os.path.join(
+ self.root, vdsm.virt.containers.metrics.cgroups.PROCFS
+ )
+ self.cgroupfsroot = os.path.join(
+ self.root, vdsm.virt.containers.metrics.cgroups.CGROUPFS
+ )
+
+ with move_into(self.root):
+ cgroupsdata = os.path.join(self.root, 'cgroups.tgz')
+ with gzip.GzipFile(cgroupsdata) as gz:
+ tar = tarfile.TarFile(fileobj=gz)
+ tar.extractall()
+
+ self.patch = monkey.Patch([
+ (vdsm.virt.containers.metrics.cgroups,
+ '_PROCBASE', self.procfsroot),
+ (vdsm.virt.containers.metrics.cgroups,
+ '_CGROUPBASE', self.cgroupfsroot),
+ ])
+ self.patch.apply()
+
+ def tearDown(self):
+ self.patch.revert()
+ shutil.rmtree(self.procfsroot)
+ shutil.rmtree(self.cgroupfsroot)
+
+
+class FakeRunnableTestCase(TestCase):
+
+ def setUp(self):
+ def _fake_create(rt, conf, repo, **kwargs):
+ return vdsm.virt.containers.runtimes.fake.Fake(
+ conf,
+ repo,
+ **kwargs
+ )
+
+ self.patch = monkey.Patch([
+ (vdsm.virt.containers.runtime, 'create', _fake_create),
+ ])
+ self.patch.apply()
+ self.dom = vdsm.virt.containers.domain.Domain(
+ minimal_dom_xml(),
+ vdsm.virt.containers.config.environ.current(),
+ FakeRepo()
+ )
+
+ def tearDown(self):
+ self.patch.revert()
+
+
+class FakeRunner(object):
+ def __init__(self):
+ self.stopped = False
+ self.started = False
+ self.setup_done = False
+ self.teardown_done = False
+ self.configured = False
+ self.resynced = False
+ self.uuid = '00000000-0000-0000-0000-000000000000'
+
+ def setup(self, *args, **kwargs):
+ self.setup_done = True
+
+ def teardown(self, *args, **kwargs):
+ self.teardown_done = True
+
+ def start(self, *args, **kwargs):
+ self.started = True
+
+ def resync(self):
+ self.resynced = True
+
+ def stop(self):
+ self.stopped = True
+
+ def configure(self, *args, **kwargs):
+ self.configured = True
+
+
+def minimal_dom_xml(vm_uuid=None):
+ data = _read_dom_xml('minimal_dom.xml')
+ vm_uuid = str(uuid.uuid4()) if vm_uuid is None else vm_uuid
+ return data.format(vm_uuid=vm_uuid)
+
+
+def full_dom_xml(vm_uuid=None):
+ data = _read_dom_xml('full_dom.xml')
+ vm_uuid = str(uuid.uuid4()) if vm_uuid is None else vm_uuid
+ return data.format(vm_uuid=vm_uuid)
+
+
+def only_disk_dom_xml():
+ return _read_dom_xml('only_disk.xml')
+
+
+def only_mem_dom_xml():
+ return _read_dom_xml('only_mem.xml')
+
+
+def disk_dev_dom_xml():
+ return _read_dom_xml('disk_dev.xml')
+
+
+def disk_file_malformed_dom_xml():
+ return _read_dom_xml('disk_file_malformed.xml')
+
+
+def bridge_down_dom_xml():
+ return _read_dom_xml('bridge_down.xml')
+
+
+def bridge_no_source_dom_xml():
+ return _read_dom_xml('bridge_no_source.xml')
+
+
+def metadata_drive_map_dom_xml():
+ return _read_dom_xml('metadata_drive_map.xml')
+
+
+def _read_dom_xml(name):
+ testdir = os.path.dirname(os.path.abspath(__file__))
+ tmpl = os.path.join(testdir, 'data', name)
+ with open(tmpl, 'rt') as src:
+ return src.read()
+
+
+class FakeRepo(vdsm.virt.containers.command.Repo):
+
+ def __init__(self):
+ super(FakeRepo, self).__init__(execs=fake_executables())
+ self._cmds = collections.defaultdict(
+ lambda: vdsm.virt.containers.command.FakeCommand
+ )
diff --git a/tests/containers/data/bridge_down.xml b/tests/containers/data/bridge_down.xml
new file mode 100644
index 0000000..2ef73c7
--- /dev/null
+++ b/tests/containers/data/bridge_down.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<domain type="kvm" xmlns:ovirt="http://ovirt.org/vm/tune/1.0">
+ <name>testVm</name>
+ <uuid>35ef4734-4ed5-4f95-abf8-928e23a76619</uuid>
+ <maxMemory>16384</maxMemory>
+ <metadata>
+ <convirt:container xmlns:convirt="http://github.com/ovirt/containers/1.0">rkt</convirt:container>
+ </metadata>
+ <devices>
+ <emulator>kvm</emulator>
+ <disk type='file' device='disk' snapshot='no'>
+ <driver name='qemu' type='raw' cache='none' error_policy='stop' io='threads'/>
+ <source file='/rhev/data-center/00000001-0001-0001-0001-00000000027f/43db3789-bb16-40bd-a9fc-3cced1b23ea6/images/90bece76-2df6-4a88-bfc8-f6f7461b7b8b/844e5378-6700-45ba-a846-67eba730e24b'>
+ <seclabel model='selinux' labelskip='yes'/>
+ </source>
+ <backingStore/>
+ <target dev='vda' bus='virtio'/>
+ <serial>90bece76-2df6-4a88-bfc8-f6f7461b7b8b</serial>
+ <alias name='virtio-disk0'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
+ </disk>
+ <interface type="bridge">
+ <mac address="00:1a:4a:16:01:5a"/>
+ <model type="virtio"/>
+ <source bridge="ovirtmgmt"/>
+ <filterref filter="vdsm-no-mac-spoofing"/>
+ <link state="down"/>
+ <bandwidth/>
+ </interface>
+ </devices>
+</domain>
diff --git a/tests/containers/data/bridge_no_source.xml b/tests/containers/data/bridge_no_source.xml
new file mode 100644
index 0000000..ed99cae
--- /dev/null
+++ b/tests/containers/data/bridge_no_source.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<domain type="kvm" xmlns:ovirt="http://ovirt.org/vm/tune/1.0">
+ <name>testVm</name>
+ <uuid>35ef4734-4ed5-4f95-abf8-928e23a76619</uuid>
+ <maxMemory>16384</maxMemory>
+ <metadata>
+ <convirt:container xmlns:convirt="http://github.com/ovirt/containers/1.0">rkt</convirt:container>
+ </metadata>
+ <devices>
+ <emulator>kvm</emulator>
+ <disk type='file' device='disk' snapshot='no'>
+ <driver name='qemu' type='raw' cache='none' error_policy='stop' io='threads'/>
+ <source file='/rhev/data-center/00000001-0001-0001-0001-00000000027f/43db3789-bb16-40bd-a9fc-3cced1b23ea6/images/90bece76-2df6-4a88-bfc8-f6f7461b7b8b/844e5378-6700-45ba-a846-67eba730e24b'>
+ <seclabel model='selinux' labelskip='yes'/>
+ </source>
+ <backingStore/>
+ <target dev='vda' bus='virtio'/>
+ <serial>90bece76-2df6-4a88-bfc8-f6f7461b7b8b</serial>
+ <alias name='virtio-disk0'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
+ </disk>
+ <interface type="bridge">
+ <mac address="00:1a:4a:16:01:5a"/>
+ <model type="virtio"/>
+ <filterref filter="vdsm-no-mac-spoofing"/>
+ <link state="up"/>
+ <bandwidth/>
+ </interface>
+ </devices>
+</domain>
diff --git a/tests/containers/data/disk_dev.xml b/tests/containers/data/disk_dev.xml
new file mode 100644
index 0000000..cec0cbc
--- /dev/null
+++ b/tests/containers/data/disk_dev.xml
@@ -0,0 +1,15 @@
+<domain type='kvm' id='2'>
+ <metadata>
+ <convirt:container xmlns:convirt="http://github.com/ovirt/containers/1.0">rkt</convirt:container>
+ </metadata>
+ <devices>
+ <emulator>kvm</emulator>
+ <disk device="disk" snapshot="no" type="block">
+ <source dev="/rhev/data-center/00000001-0001-0001-0001-00000000027f/38fa52fc-f62f-4d83-b89d-956f3d75c518/images/e0482091-853c-4e97-b80f-87f174730688/c36bb9f1-976a-414b-abd5-d72f5d2a94d2"/>
+ <target bus="virtio" dev="vda"/>
+ <serial>e0482091-853c-4e97-b80f-87f174730688</serial>
+ <boot order="1"/>
+ <driver cache="none" error_policy="stop" io="native" name="qemu" type="qcow2"/>
+ </disk>
+ </devices>
+ </domain>
diff --git a/tests/containers/data/disk_file_malformed.xml b/tests/containers/data/disk_file_malformed.xml
new file mode 100644
index 0000000..e15aebf
--- /dev/null
+++ b/tests/containers/data/disk_file_malformed.xml
@@ -0,0 +1,16 @@
+<domain type='kvm' id='2'>
+ <maxMemory slots='16' unit='KiB'>4294967296</maxMemory>
+ <metadata>
+ <convirt:container xmlns:convirt="http://github.com/ovirt/containers/1.0">rkt</convirt:container>
+ </metadata>
+ <devices>
+ <emulator>kvm</emulator>
+ <disk device="disk" snapshot="no" type="file">
+ <source dev="/rhev/data-center/00000001-0001-0001-0001-00000000027f/38fa52fc-f62f-4d83-b89d-956f3d75c518/images/e0482091-853c-4e97-b80f-87f174730688/c36bb9f1-976a-414b-abd5-d72f5d2a94d2"/>
+ <target bus="virtio" dev="vda"/>
+ <serial>e0482091-853c-4e97-b80f-87f174730688</serial>
+ <boot order="1"/>
+ <driver cache="none" error_policy="stop" io="native" name="qemu" type="qcow2"/>
+ </disk>
+ </devices>
+ </domain>
diff --git a/tests/containers/data/full_dom.xml b/tests/containers/data/full_dom.xml
new file mode 100644
index 0000000..901e3ca
--- /dev/null
+++ b/tests/containers/data/full_dom.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<domain type="kvm" xmlns:ovirt="http://ovirt.org/vm/tune/1.0">
+ <name>a_c7_2</name>
+ <uuid>{vm_uuid}</uuid>
+ <memory>4194304</memory>
+ <currentMemory>4194304</currentMemory>
+ <maxMemory slots="16">4294967296</maxMemory>
+ <vcpu current="2">16</vcpu>
+ <metadata>
+ <convirt:container xmlns:convirt="http://github.com/ovirt/containers/1.0">rkt</convirt:container>
+ <ovirt:qos/>
+ </metadata>
+ <devices>
+ <emulator>kvm</emulator>
+ <channel type="unix">
+ <target name="com.redhat.rhevm.vdsm" type="virtio"/>
+ <source mode="bind" path="/var/lib/libvirt/qemu/channels/338175a6-44e7-45d0-8321-2c6f2d5b3d6b.com.redhat.rhevm.vdsm"/>
+ </channel>
+ <channel type="unix">
+ <target name="org.qemu.guest_agent.0" type="virtio"/>
+ <source mode="bind" path="/var/lib/libvirt/qemu/channels/338175a6-44e7-45d0-8321-2c6f2d5b3d6b.org.qemu.guest_agent.0"/>
+ </channel>
+ <input bus="ps2" type="mouse"/>
+ <memballoon model="none"/>
+ <video>
+ <model heads="1" ram="65536" type="qxl" vgamem="16384" vram="32768"/>
+ </video>
+ <graphics autoport="yes" passwd="*****" passwdValidTo="1970-01-01T00:00:01" port="-1" tlsPort="-1" type="spice">
+ <listen network="vdsm-ovirtmgmt" type="network"/>
+ </graphics>
+ <interface type="bridge">
+ <mac address="00:1a:4a:16:01:57"/>
+ <model type="virtio"/>
+ <source bridge="ovirtmgmt"/>
+ <filterref filter="vdsm-no-mac-spoofing"/>
+ <link state="up"/>
+ <bandwidth/>
+ </interface>
+ <disk device="cdrom" snapshot="no" type="file">
+ <source file="/rhev/data-center/00000001-0001-0001-0001-00000000027f/43db3789-bb16-40bd-a9fc-3cced1b23ea6/images/27101aac-10ec-468a-aaf5-694c663b2c33/373d166e-d21a-4ad0-8166-571f49c22d64" startupPolicy="optional"/>
+ <target bus="ide" dev="hdc"/>
+ <readonly/>
+ <serial>522169df-603d-4229-8451-69a4e860554a</serial>
+ <boot order="1"/>
+ </disk>
+ <disk device="disk" snapshot="no" type="file">
+ <source file="/rhev/data-center/00000001-0001-0001-0001-00000000027f/43db3789-bb16-40bd-a9fc-3cced1b23ea6/images/27101aac-10ec-468a-aaf5-694c663b2c33/19bb423f-7db0-4cd1-9fe9-5aa3d4d8c1af"/>
+ <target bus="virtio" dev="vda"/>
+ <serial>27101aac-10ec-468a-aaf5-694c663b2c33</serial>
+ <boot order="2"/>
+ <driver cache="none" error_policy="stop" io="threads" name="qemu" type="raw"/>
+ </disk>
+ <channel type="spicevmc">
+ <target name="com.redhat.spice.0" type="virtio"/>
+ </channel>
+ </devices>
+ <os>
+ <type arch="x86_64" machine="pc-i440fx-rhel7.2.0">hvm</type>
+ <smbios mode="sysinfo"/>
+ </os>
+ <sysinfo type="smbios">
+ <system>
+ <entry name="manufacturer">oVirt</entry>
+ <entry name="product">oVirt Node</entry>
+ <entry name="version">7-2.1511.el7.centos.2.10</entry>
+ <entry name="serial">0A9C980E-6B95-3D34-C5AC-40167EB07D87</entry>
+ <entry name="uuid">338175a6-44e7-45d0-8321-2c6f2d5b3d6b</entry>
+ </system>
+ </sysinfo>
+ <clock adjustment="0" offset="variable">
+ <timer name="rtc" tickpolicy="catchup"/>
+ <timer name="pit" tickpolicy="delay"/>
+ <timer name="hpet" present="no"/>
+ </clock>
+ <features>
+ <acpi/>
+ </features>
+ <cpu match="exact">
+ <model>Opteron_G2</model>
+ <topology cores="1" sockets="16" threads="1"/>
+ <numa>
+ <cell cpus="0,1" memory="4194304"/>
+ </numa>
+ </cpu>
+ <numatune>
+ <memory mode="interleave" nodeset="0"/>
+ </numatune>
+</domain>
diff --git a/tests/containers/data/metadata_drive_map.xml b/tests/containers/data/metadata_drive_map.xml
new file mode 100644
index 0000000..daf194c
--- /dev/null
+++ b/tests/containers/data/metadata_drive_map.xml
@@ -0,0 +1,35 @@
+<domain type='kvm' id='2'>
+ <metadata>
+ <convirt:drivemap xmlns:convirt="http://github.com/ovirt/containers/drivemap/1.0">
+ <volume name="data" drive="vda"/>
+ </convirt:drivemap>
+ <convirt:container xmlns:convirt="http://github.com/ovirt/containers/1.0">rkt</convirt:container>
+ </metadata>
+ <memory>4194304</memory>
+ <currentMemory>4194304</currentMemory>
+ <maxMemory slots="16">4294967296</maxMemory>
+ <vcpu current="2">16</vcpu>
+ <devices>
+ <emulator>kvm</emulator>
+ <disk device="cdrom" snapshot="no" type="file">
+ <source file="/rhev/data-center/00000001-0001-0001-0001-00000000027f/43db3789-bb16-40bd-a9fc-3cced1b23ea6/images/27101aac-10ec-468a-aaf5-694c663b2c33/373d166e-d21a-4ad0-8166-571f49c22d64" startupPolicy="optional"/>
+ <target bus="ide" dev="hdc"/>
+ <readonly/>
+ <serial>522169df-603d-4229-8451-69a4e860554a</serial>
+ <boot order="1"/>
+ </disk>
+ <disk device="disk" snapshot="no" type="block">
+ <source dev="/rhev/data-center/00000001-0001-0001-0001-00000000027f/38fa52fc-f62f-4d83-b89d-956f3d75c518/images/e0482091-853c-4e97-b80f-87f174730688/c36bb9f1-976a-414b-abd5-d72f5d2a94d2"/>
+ <target bus="virtio" dev="vda"/>
+ <serial>e0482091-853c-4e97-b80f-87f174730688</serial>
+ <boot order="2"/>
+ <driver cache="none" error_policy="stop" io="native" name="qemu" type="qcow2"/>
+ </disk>
+ <interface type="bridge">
+ <mac address="00:1a:4a:16:01:57"/>
+ <model type="virtio"/>
+ <source bridge="ovirtmgmt"/>
+ <link state="up"/>
+ </interface>
+ </devices>
+</domain>
diff --git a/tests/containers/data/minimal_dom.xml b/tests/containers/data/minimal_dom.xml
new file mode 100644
index 0000000..cfcb6fa
--- /dev/null
+++ b/tests/containers/data/minimal_dom.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<domain type="kvm" xmlns:ovirt="http://ovirt.org/vm/tune/1.0">
+ <name>testVm</name>
+ <uuid>{vm_uuid}</uuid>
+ <maxMemory>16384</maxMemory>
+ <metadata>
+ <convirt:container xmlns:convirt="http://github.com/ovirt/containers/1.0">rkt</convirt:container>
+ </metadata>
+ <devices>
+ <emulator>rkt</emulator>
+ <disk type='file' device='cdrom' snapshot='no'>
+ <driver name='qemu' type='raw' cache='none' error_policy='stop' io='threads'/>
+ <source file='/rhev/data-center/00000001-0001-0001-0001-00000000027f/43db3789-bb16-40bd-a9fc-3cced1b23ea6/images/90bece76-2df6-4a88-bfc8-f6f7461b7b8b/844e5378-6700-45ba-a846-67eba730e24b'>
+ <seclabel model='selinux' labelskip='yes'/>
+ </source>
+ <backingStore/>
+ <target dev='vda' bus='virtio'/>
+ <serial>90bece76-2df6-4a88-bfc8-f6f7461b7b8b</serial>
+ <alias name='virtio-disk0'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
+ </disk>
+ <interface type="bridge">
+ <mac address="00:1a:4a:16:01:57"/>
+ <model type="virtio"/>
+ <source bridge="ovirtmgmt"/>
+ <link state="up"/>
+ </interface>
+ </devices>
+</domain>
diff --git a/tests/containers/data/only_disk.xml b/tests/containers/data/only_disk.xml
new file mode 100644
index 0000000..dc00f51
--- /dev/null
+++ b/tests/containers/data/only_disk.xml
@@ -0,0 +1,19 @@
+<domain type='kvm' id='2'>
+ <metadata>
+ <convirt:container xmlns:convirt="http://github.com/ovirt/containers/1.0">rkt</convirt:container>
+ </metadata>
+ <devices>
+ <emulator>kvm</emulator>
+ <disk type='file' device='disk' snapshot='no'>
+ <driver name='qemu' type='raw' cache='none' error_policy='stop' io='threads'/>
+ <source file='/random/path/to/disk/image'>
+ <seclabel model='selinux' labelskip='yes'/>
+ </source>
+ <backingStore/>
+ <target dev='vdb' bus='virtio'/>
+ <serial>90bece76-2df6-4a88-bfc8-f6f7461b7b8b</serial>
+ <alias name='virtio-disk1'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
+ </disk>
+ </devices>
+ </domain>
diff --git a/tests/containers/data/only_mem.xml b/tests/containers/data/only_mem.xml
new file mode 100644
index 0000000..ff4190b
--- /dev/null
+++ b/tests/containers/data/only_mem.xml
@@ -0,0 +1,9 @@
+<domain type='kvm' id='2'>
+ <maxMemory slots='16' unit='KiB'>4294967296</maxMemory>
+ <metadata>
+ <convirt:container xmlns:convirt="http://github.com/ovirt/containers/1.0">rkt</convirt:container>
+ </metadata>
+ <devices>
+ <emulator>kvm</emulator>
+ </devices>
+</domain>
diff --git a/tests/containers/errors_test.py b/tests/containers/errors_test.py
new file mode 100644
index 0000000..9b5b159
--- /dev/null
+++ b/tests/containers/errors_test.py
@@ -0,0 +1,34 @@
+from __future__ import absolute_import
+#
+# Copyright 2015-2016 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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 unittest
+
+import libvirt
+
+import vdsm.virt.containers.errors
+
+
+class ErrorsTests(unittest.TestCase):
+
+ def test_throw(self):
+ self.assertRaises(libvirt.libvirtError,
+ vdsm.virt.containers.errors.throw)
diff --git a/tests/containers/fake/bin/docker b/tests/containers/fake/bin/docker
new file mode 100755
index 0000000..6ef02d1
--- /dev/null
+++ b/tests/containers/fake/bin/docker
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+
+import os
+import os.path
+import sys
+
+
+def _main(args):
+ sys.exit(0)
+
+
+if __name__ == "__main__":
+ _main(sys.argv[1:])
diff --git a/tests/containers/fake/bin/rkt b/tests/containers/fake/bin/rkt
new file mode 100755
index 0000000..bc8f566
--- /dev/null
+++ b/tests/containers/fake/bin/rkt
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+
+import os
+import os.path
+import random
+import sys
+import uuid
+
+_ARG = '--uuid-file-save'
+
+def find_path(args):
+ for arg in args:
+ if arg.startswith(_ARG):
+ opt, val = arg.split('=', 1)
+ return val
+ return None
+
+
+def _gc(args):
+ sys.exit(0)
+
+
+def _run(args):
+ try:
+ path = find_path(args)
+ except ValueError:
+ sys.exit(1)
+
+ try:
+ path = path.strip('"')
+ with open(path, 'wt') as fp:
+ fp.write(str(uuid.uuid4()))
+ except IOError as e:
+ sys.exit(2)
+
+
+def _status(rkt_uuid):
+ print(
+"""state=running
+created=2016-06-29 10:10:07.441 +0200 CEST
+started=2016-06-29 10:10:08.548 +0200 CEST
+networks=default:ip4=172.16.28.5
+pid=%i
+exited=false""" % (random.randint(10, 65535)))
+
+
+
+def _main(args):
+ if not args:
+ sys.exit(1)
+
+ if 'gc' in args:
+ _gc(args)
+ elif 'run' in args:
+ _run(args)
+ elif 'status' == args[0]:
+ if len(args) != 2:
+ sys.exit(1)
+ _status(args[1])
+
+
+if __name__ == "__main__":
+ _main(sys.argv[1:])
diff --git a/tests/containers/fake/bin/systemctl b/tests/containers/fake/bin/systemctl
new file mode 100755
index 0000000..f1dee5d
--- /dev/null
+++ b/tests/containers/fake/bin/systemctl
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+import sys
+
+sys.exit(0)
diff --git a/tests/containers/fake/bin/systemd-run b/tests/containers/fake/bin/systemd-run
new file mode 100755
index 0000000..5454dd7
--- /dev/null
+++ b/tests/containers/fake/bin/systemd-run
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+
+import subprocess
+import sys
+
+for idx, arg in enumerate(sys.argv[1:]):
+ if not arg.startswith('--'):
+ break
+
+torun = sys.argv[idx+1:]
+
+subprocess.check_call(torun)
diff --git a/tests/containers/fake/cgroups.tgz b/tests/containers/fake/cgroups.tgz
new file mode 100644
index 0000000..fe3f58f
--- /dev/null
+++ b/tests/containers/fake/cgroups.tgz
Binary files differ
diff --git a/tests/containers/fs_test.py b/tests/containers/fs_test.py
new file mode 100644
index 0000000..e58df27
--- /dev/null
+++ b/tests/containers/fs_test.py
@@ -0,0 +1,75 @@
+#
+# Copyright 2015-2016 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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
+#
+from __future__ import absolute_import
+
+import os
+import tempfile
+import uuid
+
+import vdsm.virt.containers
+import vdsm.virt.containers.fs
+
+from . import conttestlib
+
+
+class ReadFileTests(conttestlib.TestCase):
+
+ def test_read_existing_file(self):
+ content = str(uuid.uuid4())
+ with tempfile.NamedTemporaryFile() as f:
+ f.write(content.encode('ascii'))
+ f.flush()
+ self.assertEqual(content,
+ vdsm.virt.containers.fs.read_file(f.name))
+
+ def test_read_unexisting_file(self):
+ path = '/most/likely/does/not/exist'
+ self.assertRaises(IOError,
+ vdsm.virt.containers.fs.read_file,
+ path)
+
+
+class RMFileTests(conttestlib.TestCase):
+
+ def test_rm_file_once(self):
+ with conttestlib.named_temp_dir() as tmp_dir:
+ path = os.path.join(tmp_dir, "foobar")
+ with open(path, 'wt') as f:
+ f.write('%s\n' % str(uuid.uuid4()))
+ self.assertEquals(os.listdir(tmp_dir), ['foobar'])
+ vdsm.virt.containers.fs.rm_file(path)
+ self.assertEquals(os.listdir(tmp_dir), [])
+
+ def test_rm_file_twice(self):
+ with conttestlib.named_temp_dir() as tmp_dir:
+ path = os.path.join(tmp_dir, "foobar")
+ with open(path, 'wt') as f:
+ f.write('%s\n' % str(uuid.uuid4()))
+ self.assertEquals(os.listdir(tmp_dir), ['foobar'])
+ vdsm.virt.containers.fs.rm_file(path)
+ self.assertEquals(os.listdir(tmp_dir), [])
+ self.assertNotRaises(vdsm.virt.containers.fs.rm_file, path)
+ self.assertEquals(os.listdir(tmp_dir), [])
+
+ def test_rm_file_fails(self):
+ self.assertNotEqual(os.geteuid(), 0)
+ self.assertRaises(OSError,
+ vdsm.virt.containers.fs.rm_file,
+ '/var/log/lastlog')
diff --git a/tests/containers/monkey.py b/tests/containers/monkey.py
new file mode 100644
index 0000000..b71e0825
--- /dev/null
+++ b/tests/containers/monkey.py
@@ -0,0 +1,108 @@
+from __future__ import absolute_import
+#
+# Copyright 2012-2016 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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
+#
+
+from contextlib import contextmanager
+from functools import wraps
+import inspect
+
+
+class Patch(object):
+
+ def __init__(self, what):
+ self.what = what
+ self.old = []
+
+ def apply(self):
+ for module, name, that in self.what:
+ old = getattr(module, name)
+ self.old.append((module, name, old))
+ # The following block is done so that if it is a method we are
+ # patching in, that it will have the same type as the method it
+ # replaced.
+ if inspect.isclass(module):
+ if inspect.isfunction(old):
+ that = staticmethod(that)
+ elif (inspect.ismethod(old) and
+ getattr(old, 'im_self', None) is not None):
+ that = classmethod(that)
+ setattr(module, name, that)
+
+ def revert(self):
+ assert self.old != []
+ while self.old:
+ module, name, that = self.old.pop()
+ # The following block is only necessary for Python2 as it wrongly
+ # sets the function as instancemethod instead of keeping it as
+ # staticmethod.
+ if inspect.isclass(module):
+ if inspect.isfunction(that):
+ that = staticmethod(that)
+
+ setattr(module, name, that)
+
+
+@contextmanager
+def patch_scope(what):
+ patch = Patch(what)
+ patch.apply()
+ try:
+ yield
+ finally:
+ patch.revert()
+
+
+def patch_function(module, name, that):
+ def decorator(f):
+ @wraps(f)
+ def wrapper(*args, **kw):
+ with patch_scope([(module, name, that)]):
+ return f(*args, **kw)
+ return wrapper
+ return decorator
+
+
+def patch_class(module, name, that):
+
+ def setup_decorator(func):
+ @wraps(func)
+ def setup(self, *a, **kw):
+ if not hasattr(self, '__monkeystack__'):
+ self.__monkeystack__ = []
+ patch = Patch([(module, name, that)])
+ self.__monkeystack__.append(patch)
+ patch.apply()
+ return func(self, *a, **kw)
+ return setup
+
+ def teardown_decorator(func):
+ @wraps(func)
+ def teardown(self, *a, **kw):
+ patch = self.__monkeystack__.pop()
+ patch.revert()
+ return func(self, *a, **kw)
+ return teardown
+
+ def wrapper(cls):
+ cls.setUp = setup_decorator(cls.setUp)
+ cls.tearDown = teardown_decorator(cls.tearDown)
+ return cls
+
+ return wrapper
diff --git a/tests/containers/xmlfile_test.py b/tests/containers/xmlfile_test.py
new file mode 100644
index 0000000..8b50652
--- /dev/null
+++ b/tests/containers/xmlfile_test.py
@@ -0,0 +1,87 @@
+#
+# Copyright 2015-2016 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser 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
+#
+from __future__ import absolute_import
+
+import contextlib
+import os
+import uuid
+import xml.etree.ElementTree as ET
+
+import vdsm.virt.containers
+import vdsm.virt.containers.config
+import vdsm.virt.containers.config.environ
+import vdsm.virt.containers.xmlfile
+
+from . import conttestlib
+
+
+class XMLFileTests(conttestlib.TestCase):
+
+ def setUp(self):
+ self.vm_uuid = str(uuid.uuid4())
+
+ @contextlib.contextmanager
+ def test_env(self):
+ with conttestlib.named_temp_dir() as tmp_dir:
+ with conttestlib.global_conf(run_dir=tmp_dir):
+ yield vdsm.virt.containers.xmlfile.XMLFile(
+ self.vm_uuid,
+ vdsm.virt.containers.config.environ.current()
+ )
+
+ def test_fails_without_conf(self):
+ self.assertRaises(vdsm.virt.containers.xmlfile.UnconfiguredXML,
+ vdsm.virt.containers.xmlfile.XMLFile,
+ self.vm_uuid,
+ None)
+
+ def test_path(self):
+ with self.test_env() as xf:
+ self.assertTrue(xf.path.endswith('xml'))
+ self.assertIn(self.vm_uuid, xf.path)
+
+ def test_save(self):
+ root = ET.fromstring(conttestlib.minimal_dom_xml())
+ with self.test_env() as xf:
+ conf = vdsm.virt.containers.config.environ.current()
+ self.assertEquals(os.listdir(conf.run_dir), [])
+ self.assertNotRaises(xf.save, root)
+ self.assertTrue(len(os.listdir(conf.run_dir)), 1)
+
+ def test_load(self):
+ xml_data = conttestlib.minimal_dom_xml()
+ root = ET.fromstring(xml_data)
+ with self.test_env() as xf:
+ xf.save(root)
+ new_root = xf.load()
+ xml_copy = vdsm.virt.containers.xmlfile.XMLFile.encode(new_root)
+ # FIXME: nasty trick to tidy up the XML
+ xml_ref = vdsm.virt.containers.xmlfile.XMLFile.encode(root)
+ self.assertEquals(xml_ref, xml_copy)
+
+ def test_clear(self):
+ xml_data = conttestlib.minimal_dom_xml()
+ root = ET.fromstring(xml_data)
+ with self.test_env() as xf:
+ xf.save(root)
+ conf = vdsm.virt.containers.config.environ.current()
+ self.assertTrue(len(os.listdir(conf.run_dir)), 1)
+ self.assertNotRaises(xf.clear)
+ self.assertEquals(os.listdir(conf.run_dir), [])
--
To view, visit https://gerrit.ovirt.org/60678
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I27ba3cecbd71b7bbba94992d6bc63ca29333e313
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
7 years, 4 months