Antoni Segura Puimedon has uploaded a new change for review.
Change subject: vdsmcli: Add a contrib command line client alternative
......................................................................
vdsmcli: Add a contrib command line client alternative
This command line client is built by hand for the convenience of
developers and requires the click library:
pip install click
It easily supports commands and subcommands. For example:
vdsmcli network
is a command and 'show' and 'add' are its subcommands.
Examples:
toniel602 ~ # vdsmcli network show -k nics -k networks
============================================= Nics
eth6
eth5
eth4
eth3
eth2
eth1
============================================= Networks
foo
or
toniel602 ~ # vdsmcli --verbode --pprint network show -k networks
============================================= Networks
===============
foo
===============
{'addr': '',
'bootproto4': 'none',
'bridged': False,
'gateway': '',
'iface': 'bond42',
'interface': 'bond42',
'ipv6addrs': ['2620:52:0:223c:201:a4ff:feac:8796/64',
'fe80::201:a4ff:feac:8796/64'],
'ipv6gateway': 'fe80:52:0:223c::3fe',
'mtu': '1500',
'netmask': ''}
addition
toniel602 ~ # ./cvdsm.py -v -p network add foo --bridgeless --nic eth4
--nic eth5 --bond bond42
Networks: {u'foo': {'bonding': u'bond42', 'bridged': False}}
Bonds: {u'bond42': {'nics': (u'eth4', u'eth5')}}
Succeeded. Done
One could extend it with a vm command so that it was easy to do:
vdsmcli vm hotplug 34f5f608-91ed-48d1-af31-c3a3d788678e nic --mac 00:11:22:33:44:55 --model virtio
Change-Id: Ie5574b2b34f0b7b2174e9da0c4487f812ff20f5b
Signed-off-by: Antoni S. Puimedon <asegurap(a)redhat.com>
---
A contrib/vdsmcli.py
1 file changed, 113 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/52/28152/1
diff --git a/contrib/vdsmcli.py b/contrib/vdsmcli.py
new file mode 100644
index 0000000..2255201
--- /dev/null
+++ b/contrib/vdsmcli.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python2
+# 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
+#
+"""This is a command line client for vdsm."""
+
+from pprint import pformat
+
+import click
+
+from vdsm import netinfo, vdscli
+
+_NET_DEVICE_TYPES = ('networks', 'bridges', 'vlans', 'bondings', 'nics')
+
+
+class Options(object):
+ def __init__(self, verbose=None, pprint=None):
+ self.verbose = verbose
+ self.pprint = pprint
+
+
+(a)click.group()
+(a)click.option('-v', '--verbose', is_flag=True)
+(a)click.option('-p', '--pprint', is_flag=True)
+(a)click.pass_context
+def cli(ctx, verbose, pprint):
+ ctx.obj = Options(verbose, pprint)
+
+
+(a)cli.group()
+(a)click.pass_obj
+def network(options):
+ """Network actions and information displaying."""
+ pass
+
+
+(a)network.command(help='Configure network')
+(a)click.pass_obj
+(a)click.option('--bridged/--bridgeless', default=True)
+(a)click.option('--vlan', default=None, type=click.INT)
+(a)click.option('--bond', default=None)
+(a)click.option('--bond-opts', default=None)
+(a)click.option('--nic', multiple=True)
+(a)click.argument('name')
+(a)click.argument('extra_attributes', required=False, nargs=-1)
+def add(options, bridged, vlan, bond, bond_opts, nic, name, extra_attributes):
+ conn = vdscli.connect()
+ networks = {name: {'bridged': bridged}}
+ if vlan:
+ networks[name]['vlan'] = vlan
+ if len(nic) == 1:
+ networks[name]['nic'] = nic[0]
+ if bond:
+ networks[name]['bonding'] = bond
+ bonds = {bond: {'nics': nic}}
+ if bond_opts:
+ bonds[bond]['options'] = bond_opts
+ else:
+ bonds = {}
+
+ for key, value in (elem.split('=') for elem in extra_attributes):
+ networks[name][key] = value
+
+ if options.verbose:
+ click.echo('Networks: %s' % (pformat(networks) if options.pprint else
+ networs))
+ click.echo('Bonds: %s' % (pformat(bonds) if options.pprint else bonds))
+ result = conn.setupNetworks(networks, bonds, {'connectivityCheck': False})
+ code = result['status']['code']
+ message = result['status']['message']
+ click.echo('%s. %s' % ('Succeeded' if code == 0 else 'Failed', message))
+
+
+(a)network.command(help='show network and net device information')
+(a)click.pass_obj
+(a)click.option('--kind', '-k', multiple=True, type=click.Choice(
+ _NET_DEVICE_TYPES))
+def show(options, kind):
+ if not kind:
+ kind = ('networks',)
+ conn = vdscli.connect()
+ info = netinfo.NetInfo(conn.getVdsCapabilities()['info'])
+ for k in kind:
+ click.echo('')
+ click.echo('=' * 45, nl=False)
+ click.echo(' ' + k[0].upper() + k[1:])
+ for name, attrs in getattr(info, k).iteritems():
+ if options.verbose:
+ click.echo('=' * 15)
+ click.echo(name)
+ if options.verbose:
+ click.echo('=' * 15)
+ click.echo(pformat(attrs) if options.pprint else attrs)
+ click.echo('')
+
+
+if __name__ == '__main__':
+ cli()
--
To view, visit http://gerrit.ovirt.org/28152
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie5574b2b34f0b7b2174e9da0c4487f812ff20f5b
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Antoni Segura Puimedon <asegurap(a)redhat.com>
Dan Kenigsberg has uploaded a new change for review.
Change subject: faqemu: move hook logic out of vdsm
......................................................................
faqemu: move hook logic out of vdsm
Vdsm-proper has been aware of the faqemu hook. Now that we have an
after_get_caps hook point, this is no longer necessary. This patch move
the faking logic, so that it does not need to be shipped on production
systems and clutter the code.
Change-Id: I46d0079491f707b0abd3fbbe2d47f63697dac9c5
Signed-off-by: Dan Kenigsberg <danken(a)redhat.com>
---
M vdsm.spec.in
M vdsm/caps.py
M vdsm_hooks/faqemu/Makefile.am
A vdsm_hooks/faqemu/after_get_caps.py
4 files changed, 110 insertions(+), 42 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/05/27705/1
diff --git a/vdsm.spec.in b/vdsm.spec.in
index c620174..e6db372 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1464,6 +1464,7 @@
%defattr(-, root, root, -)
%doc COPYING
%{_libexecdir}/%{vdsm_name}/hooks/before_vm_start/10_faqemu
+%{_libexecdir}/%{vdsm_name}/hooks/after_get_caps/10_faqemu
%if 0%{?with_gluster}
%files gluster
diff --git a/vdsm/caps.py b/vdsm/caps.py
index 46094f3..7c1e520 100644
--- a/vdsm/caps.py
+++ b/vdsm/caps.py
@@ -1,5 +1,5 @@
#
-# Copyright 2011 Red Hat, Inc.
+# Copyright 2011-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
@@ -197,7 +197,7 @@
@utils.memoized
-def _getLiveSnapshotSupport(arch, capabilities=None):
+def getLiveSnapshotSupport(arch, capabilities=None):
if capabilities is None:
capabilities = _getCapsXMLStr()
caps = minidom.parseString(capabilities)
@@ -295,7 +295,7 @@
@utils.memoized
-def _getEmulatedMachines(arch, capabilities=None):
+def getEmulatedMachines(arch, capabilities=None):
if capabilities is None:
capabilities = _getCapsXMLStr()
caps = minidom.parseString(capabilities)
@@ -444,13 +444,6 @@
return dict(release=release, version=version, name=osname)
-def getTargetArch():
- if config.getboolean('vars', 'fake_kvm_support'):
- return config.get('vars', 'fake_kvm_architecture')
- else:
- return platform.machine()
-
-
def _getSELinuxEnforceMode():
"""
Returns the SELinux mode as reported by kernel.
@@ -480,13 +473,11 @@
def get():
- targetArch = getTargetArch()
+ targetArch = platform.machine()
caps = {}
- caps['kvmEnabled'] = \
- str(config.getboolean('vars', 'fake_kvm_support') or
- os.path.exists('/dev/kvm')).lower()
+ caps['kvmEnabled'] = str(os.path.exists('/dev/kvm')).lower()
cpuInfo = CpuInfo()
cpuTopology = CpuTopology()
@@ -498,30 +489,9 @@
caps['cpuThreads'] = str(cpuTopology.threads())
caps['cpuSockets'] = str(cpuTopology.sockets())
caps['cpuSpeed'] = cpuInfo.mhz()
- if config.getboolean('vars', 'fake_kvm_support'):
- if targetArch == Architecture.X86_64:
- caps['cpuModel'] = 'Intel(Fake) CPU'
-
- flagList = ['vmx', 'sse2', 'nx']
-
- if targetArch == platform.machine():
- flagList += cpuInfo.flags()
-
- flags = set(flagList)
-
- caps['cpuFlags'] = ','.join(flags) + ',model_486,model_pentium,' \
- 'model_pentium2,model_pentium3,model_pentiumpro,' \
- 'model_qemu32,model_coreduo,model_core2duo,model_n270,' \
- 'model_Conroe,model_Penryn,model_Nehalem,model_Opteron_G1'
- elif targetArch == Architecture.PPC64:
- caps['cpuModel'] = 'POWER 7 (fake)'
- caps['cpuFlags'] = 'powernv,model_POWER7_v2.3'
- else:
- raise RuntimeError('Unsupported architecture: %s' % targetArch)
- else:
- caps['cpuModel'] = cpuInfo.model()
- caps['cpuFlags'] = ','.join(cpuInfo.flags() +
- _getCompatibleCpuModels())
+ caps['cpuModel'] = cpuInfo.model()
+ caps['cpuFlags'] = ','.join(cpuInfo.flags() +
+ _getCompatibleCpuModels())
caps.update(_getVersionInfo())
caps.update(netinfo.get())
@@ -534,7 +504,7 @@
caps['operatingSystem'] = osversion()
caps['uuid'] = utils.getHostUUID()
caps['packages2'] = _getKeyPackages()
- caps['emulatedMachines'] = _getEmulatedMachines(targetArch)
+ caps['emulatedMachines'] = getEmulatedMachines(targetArch)
caps['ISCSIInitiatorName'] = _getIscsiIniName()
caps['HBAInventory'] = storage.hba.HBAInventory()
caps['vmTypes'] = ['kvm']
@@ -550,7 +520,7 @@
caps['selinux'] = _getSELinux()
- liveSnapSupported = _getLiveSnapshotSupport(targetArch)
+ liveSnapSupported = getLiveSnapshotSupport(targetArch)
if liveSnapSupported is not None:
caps['liveSnapshot'] = str(liveSnapSupported).lower()
diff --git a/vdsm_hooks/faqemu/Makefile.am b/vdsm_hooks/faqemu/Makefile.am
index 3e1b0c0..e93c943 100644
--- a/vdsm_hooks/faqemu/Makefile.am
+++ b/vdsm_hooks/faqemu/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2011-2012 Red Hat, Inc.
+# Copyright 2011-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
@@ -24,12 +24,18 @@
config.log
EXTRA_DIST = \
- before_vm_start.py
+ before_vm_start.py \
+ after_get_caps.py \
+ $(NULL)
install-data-local:
$(MKDIR_P) $(DESTDIR)$(vdsmhooksdir)/before_vm_start
+ $(MKDIR_P) $(DESTDIR)$(vdsmhooksdir)/after_get_caps
$(INSTALL_SCRIPT) $(srcdir)/before_vm_start.py \
$(DESTDIR)$(vdsmhooksdir)/before_vm_start/10_faqemu
+ $(INSTALL_SCRIPT) $(srcdir)/after_get_caps.py \
+ $(DESTDIR)$(vdsmhooksdir)/after_get_caps/10_faqemu
uninstall-local:
$(RM) $(DESTDIR)$(vdsmhooksdir)/before_vm_start/10_faqemu
+ $(RM) $(DESTDIR)$(vdsmhooksdir)/after_get_caps/10_faqemu
diff --git a/vdsm_hooks/faqemu/after_get_caps.py b/vdsm_hooks/faqemu/after_get_caps.py
new file mode 100644
index 0000000..a4a008b
--- /dev/null
+++ b/vdsm_hooks/faqemu/after_get_caps.py
@@ -0,0 +1,91 @@
+#!/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
+#
+
+import platform
+import sys
+import traceback
+
+# using vdsm internals in a hook is dangerous and frowned upon,
+# as internal APIs may change without notice.
+# However, faqemu is a bit different, as it is not expected to be ever used in
+# production.
+sys.path.append('/usr/share/vdsm')
+import caps
+import hooking
+from vdsm.config import config
+
+
+def fake_caps(c, target_arch):
+ c['kvmEnabled'] = 'True'
+ cpu_info = caps.CpuInfo()
+ if target_arch == caps.Architecture.X86_64:
+ c['cpuModel'] = 'Intel(Fake) CPU'
+
+ flagList = ['vmx', 'sse2', 'nx']
+
+ if target_arch == platform.machine():
+ flagList += cpu_info.flags()
+
+ flags = set(flagList)
+
+ c['cpuFlags'] = ','.join(flags) + ',model_486,model_pentium,' \
+ 'model_pentium2,model_pentium3,model_pentiumpro,' \
+ 'model_qemu32,model_coreduo,model_core2duo,model_n270,' \
+ 'model_Conroe,model_Penryn,model_Nehalem,model_Opteron_G1'
+ elif target_arch == caps.Architecture.PPC64:
+ c['cpuModel'] = 'POWER 7 (fake)'
+ c['cpuFlags'] = 'powernv,model_POWER7_v2.3'
+ else:
+ raise RuntimeError('Unsupported architecture: %s' % target_arch)
+
+ if target_arch != platform.machine():
+ c['emulatedMachines'] = caps.getEmulatedMachines(target_arch)
+
+ liveSnapSupported = caps.getLiveSnapshotSupport(target_arch)
+ if liveSnapSupported is not None:
+ caps['liveSnapshot'] = str(liveSnapSupported).lower()
+
+ return c
+
+
+def main():
+ if config.getboolean('vars', 'fake_kvm_support'):
+ try:
+ c = hooking.read_json()
+ target_arch = config.get('vars', 'fake_kvm_architecture')
+ c = fake_caps(c, target_arch)
+ hooking.write_json(c)
+ except:
+ hooking.exit_hook('faqemu: %s\n'
+ % traceback.format_exc())
+ sys.exit(2)
+
+
+def test():
+ from pprint import pprint
+ pprint(fake_caps({}, 'ppc64'))
+
+
+if __name__ == '__main__':
+ if '--test' in sys.argv:
+ test()
+ else:
+ main()
--
To view, visit http://gerrit.ovirt.org/27705
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I46d0079491f707b0abd3fbbe2d47f63697dac9c5
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Dan Kenigsberg <danken(a)redhat.com>
Federico Simoncelli has uploaded a new change for review.
Change subject: spbackends: do not set spmRole on forceFreeSpm
......................................................................
spbackends: do not set spmRole on forceFreeSpm
Setting the spmRole to SPM_FREE on forceFreeSpm is harmful. In fact the
release of the spm role (SPM_ACQUIRED) should go through the stopSpm
procedure where the master filesystem is unmounted, etc.
Change-Id: I2bd9a0d9749e49a97a31c535c92dd242eb8f74ec
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/storage/spbackends.py
1 file changed, 0 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/18/27318/1
diff --git a/vdsm/storage/spbackends.py b/vdsm/storage/spbackends.py
index 86714a3..dddb749 100644
--- a/vdsm/storage/spbackends.py
+++ b/vdsm/storage/spbackends.py
@@ -327,7 +327,6 @@
# DO NOT USE, STUPID, HERE ONLY FOR BC
# TODO: SCSI Fence the 'lastOwner'
self.setSpmStatus(LVER_INVALID, SPM_ID_FREE, __securityOverride=True)
- self.pool.spmRole = SPM_FREE
@classmethod
def _getPoolMD(cls, domain):
--
To view, visit http://gerrit.ovirt.org/27318
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I2bd9a0d9749e49a97a31c535c92dd242eb8f74ec
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
Federico Simoncelli has uploaded a new change for review.
Change subject: [wip] sdcache: avoid extra refresh due samplingmethod
......................................................................
[wip] sdcache: avoid extra refresh due samplingmethod
In order to avoid an extra iscsi rescan (symptomatic of samplingmethod)
an additional lock has been introduced to queue the requests when the
storage is flagged as stale.
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=870768
Change-Id: If178a8eaeb94f1dfe9e0957036dde88f6a22829c
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/storage/sdc.py
1 file changed, 25 insertions(+), 26 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/74/9274/1
diff --git a/vdsm/storage/sdc.py b/vdsm/storage/sdc.py
index f2f4534..978e3fa 100644
--- a/vdsm/storage/sdc.py
+++ b/vdsm/storage/sdc.py
@@ -62,32 +62,27 @@
STORAGE_UPDATED = 0
STORAGE_STALE = 1
- STORAGE_REFRESHING = 2
def __init__(self, storage_repo):
- self._syncroot = threading.Condition()
+ self._syncDomain = threading.Condition()
+ self._syncRefresh = threading.Lock()
self.__domainCache = {}
self.__inProgress = set()
self.__staleStatus = self.STORAGE_STALE
self.storage_repo = storage_repo
def invalidateStorage(self):
- with self._syncroot:
- self.__staleStatus = self.STORAGE_STALE
+ self.log.debug("The storages have been invalidated")
+ self.__staleStatus = self.STORAGE_STALE
@misc.samplingmethod
def refreshStorage(self):
- self.__staleStatus = self.STORAGE_REFRESHING
-
+ # We need to set the __staleStatus value at the beginning because we
+ # want to keep track of the future invalidateStorage calls that might
+ # arrive during the rescan procedure.
+ self.__staleStatus = self.STORAGE_UPDATED
multipath.rescan()
lvm.invalidateCache()
-
- # If a new invalidateStorage request came in after the refresh
- # started then we cannot flag the storages as updated (force a
- # new rescan later).
- with self._syncroot:
- if self.__staleStatus == self.STORAGE_REFRESHING:
- self.__staleStatus = self.STORAGE_UPDATED
def produce(self, sdUUID):
domain = DomainProxy(self, sdUUID)
@@ -98,7 +93,7 @@
return domain
def _realProduce(self, sdUUID):
- with self._syncroot:
+ with self._syncDomain:
while True:
domain = self.__domainCache.get(sdUUID)
@@ -109,25 +104,29 @@
self.__inProgress.add(sdUUID)
break
- self._syncroot.wait()
+ self._syncDomain.wait()
try:
- # If multiple calls reach this point and the storage is not
- # updated the refreshStorage() sampling method is called
- # serializing (and eventually grouping) the requests.
- if self.__staleStatus != self.STORAGE_UPDATED:
- self.refreshStorage()
+ # Here we cannot take full advantage of the refreshStorage
+ # samplingmethod since we might be scheduling an unneeded
+ # extra rescan. We need an additional lock (_syncRefresh)
+ # to make sure that __staleStatus is taken in account
+ # (without affecting all the other external refreshStorage
+ # calls as it would be if we move this check there).
+ with self._syncRefresh:
+ if self.__staleStatus != self.STORAGE_UPDATED:
+ self.refreshStorage()
domain = self._findDomain(sdUUID)
- with self._syncroot:
+ with self._syncDomain:
self.__domainCache[sdUUID] = domain
return domain
finally:
- with self._syncroot:
+ with self._syncDomain:
self.__inProgress.remove(sdUUID)
- self._syncroot.notifyAll()
+ self._syncDomain.notifyAll()
def _findDomain(self, sdUUID):
import blockSD
@@ -162,16 +161,16 @@
return uuids
def refresh(self):
- with self._syncroot:
+ with self._syncDomain:
lvm.invalidateCache()
self.__domainCache.clear()
def manuallyAddDomain(self, domain):
- with self._syncroot:
+ with self._syncDomain:
self.__domainCache[domain.sdUUID] = domain
def manuallyRemoveDomain(self, sdUUID):
- with self._syncroot:
+ with self._syncDomain:
try:
del self.__domainCache[sdUUID]
except KeyError:
--
To view, visit http://gerrit.ovirt.org/9274
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If178a8eaeb94f1dfe9e0957036dde88f6a22829c
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>