Change in vdsm[ovirt-3.5-gluster]: gluster: volume snapshot config list and set verbs.
dnarayan at redhat.com
dnarayan at redhat.com
Thu Apr 16 10:14:09 UTC 2015
Hello Piotr Kliczewski, Dan Kenigsberg,
I'd like you to do a code review. Please visit
https://gerrit.ovirt.org/39921
to review the following change.
Change subject: gluster: volume snapshot config list and set verbs.
......................................................................
gluster: volume snapshot config list and set verbs.
This patch adds new verbs to list and set the
configuration of gluster volume snapshots.
*glusterSnapshotConfigList: get the snapshot configuration.
This verb gives the snapshot configuration for the cluster
and for all the volumes present in it.
Returns:
{'system':{'snap-max-hard-limit': 'hardlimit',
'snap-max-soft-limit': 'softLimit',
'auto-delete': 'enable/disable'},
'volume':{'name' :
{'snap-max-hard-limit: 'hardlimit',
'effective-hard-limit: 'EffectiveHardlimit',
'snap-max-soft-limit': 'softLimit'}
}...
}
*glusterVolumeSnapshotConfigList: Get the snapshot
configuration for a volume. Volume name should be provided
as an argument, configuration for that volume along with
cluster snapshot configuration is listed.
Returns:
{'system':{'snap-max-hard-limit': 'hardlimit',
'snap-max-soft-limit': 'softLimit',
'auto-delete': 'enable/disable'},
'volume':{'name' :
{'snap-max-hard-limit: 'hardlimit',
'effective-hard-limit: 'EffectiveHardlimit',
'snap-max-soft-limit': 'softLimit'}
}
}
*glusterSnapshotConfigSet: Set snapshot configuration
at cluster leval. The possible configurations that can
be set are:
snap-max-hard-limit, snap-max-soft-limit and auto-delete
*glusterVolumeSnapshotConfigSet: Set snapshot configuration
at volume leval. Volume name has to be provided as argument.
And the configurable parameter is snap-max-hard-limit.
Change-Id: Iee32a95cf028cda33f25776c08820c5ed80f1033
Signed-off-by: Darshan N <dnarayan at redhat.com>
Reviewed-on: https://gerrit.ovirt.org/34741
Reviewed-by: Piotr Kliczewski <piotr.kliczewski at gmail.com>
Reviewed-by: Dan Kenigsberg <danken at redhat.com>
---
M client/vdsClientGluster.py
M tests/Makefile.am
A tests/glusterSnapshotConfig.xml
M tests/glusterTestData.py
M tests/gluster_cli_tests.py
M vdsm.spec.in
M vdsm/gluster/api.py
M vdsm/gluster/apiwrapper.py
M vdsm/gluster/cli.py
M vdsm/gluster/exception.py
M vdsm/rpc/vdsmapi-gluster-schema.json
11 files changed, 354 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/21/39921/1
diff --git a/client/vdsClientGluster.py b/client/vdsClientGluster.py
index d86d16d..652526d 100644
--- a/client/vdsClientGluster.py
+++ b/client/vdsClientGluster.py
@@ -613,6 +613,41 @@
pp.pprint(status)
return status['status']['code'], status['status']['message']
+ def do_glusterVolumeSnapshotConfigList(self, args):
+ params = self._eqSplit(args)
+ volumeName = params.get('volumeName', '')
+
+ status = self.s.glusterVolumeSnapshotConfigList(volumeName)
+
+ pp.pprint(status)
+ return status['status']['code'], status['status']['message']
+
+ def do_glusterSnapshotConfigList(self, args):
+ status = self.s.glusterSnapshotConfigList()
+ pp.pprint(status)
+ return status['status']['code'], status['status']['message']
+
+ def do_glusterVolumeSnapshotConfigSet(self, args):
+ params = self._eqSplit(args)
+ volumeName = params.get('volumeName', '')
+ optionName = params.get('optionName', '')
+ optionValue = params.get('optionValue', '')
+
+ status = self.s.glusterVolumeSnapshotConfigSet(volumeName,
+ optionName,
+ optionValue)
+ pp.pprint(status)
+ return status['status']['code'], status['status']['message']
+
+ def do_glusterSnapshotConfigSet(self, args):
+ params = self._eqSplit(args)
+ optionName = params.get('optionName', '')
+ optionValue = params.get('optionValue', '')
+
+ status = self.s.glusterSnapshotConfigSet(optionName, optionValue)
+ pp.pprint(status)
+ return status['status']['code'], status['status']['message']
+
def getGlusterCmdDict(serv):
return \
@@ -1021,6 +1056,18 @@
('volumeName=<volume name>',
'delete all snapshots for given volume'
)),
+ 'glusterVolumeSnapshotConfigList': (
+ serv.do_glusterVolumeSnapshotConfigList,
+ ('volumeName=<volume_name>',
+ 'get gluster volume snapshot configuration'
+ )),
+ 'glusterVolumeSnapshotConfigSet': (
+ serv.do_glusterVolumeSnapshotConfigSet,
+ ('volumeName=<volume_name>'
+ 'optionName=<option_name>'
+ 'optionValue=<option_value>',
+ 'Set gluster snapshot configuration at volume leval'
+ )),
'glusterSnapshotDelete': (
serv.do_glusterSnapshotDelete,
('snapName=<snap_name>',
@@ -1041,5 +1088,16 @@
serv.do_glusterSnapshotRestore,
('snapName=snap_name',
'restore snapshot'
+ )),
+ 'glusterSnapshotConfigList': (
+ serv.do_glusterSnapshotConfigList,
+ ('',
+ 'get gluster volume snapshot configuration'
+ )),
+ 'glusterSnapshotConfigSet': (
+ serv.do_glusterSnapshotConfigSet,
+ ('optionName=<option_name>'
+ 'optionValue=<option_value>',
+ 'Set gluster snapshot configuration at cluster leval'
))
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0395058..69feaf2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -114,6 +114,7 @@
caps_numactl_4_nodes.out \
glob_1c60971a-8647-44ac-ae33-6520887f8843.out \
glusterGeoRepStatus.xml \
+ glusterSnapshotConfig.xml \
glusterSnapshotRestore.xml \
glusterVolumeGeoRepConfigList.xml \
glusterVolumeProfileInfo.xml \
diff --git a/tests/glusterSnapshotConfig.xml b/tests/glusterSnapshotConfig.xml
new file mode 100644
index 0000000..d167fdc
--- /dev/null
+++ b/tests/glusterSnapshotConfig.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<cliOutput>
+ <opRet>0</opRet>
+ <opErrno>0</opErrno>
+ <opErrstr/>
+ <snapConfig>
+ <systemConfig>
+ <hardLimit>255</hardLimit>
+ <softLimit>91%</softLimit>
+ <autoDelete>disable</autoDelete>
+ </systemConfig>
+ <volumeConfig>
+ <volume>
+ <name>snap-vol</name>
+ <hardLimit>256</hardLimit>
+ <effectiveHardLimit>255</effectiveHardLimit>
+ <softLimit>232</softLimit>
+ </volume>
+ <volume>
+ <name>snap-vol2</name>
+ <hardLimit>254</hardLimit>
+ <effectiveHardLimit>254</effectiveHardLimit>
+ <softLimit>231</softLimit>
+ </volume>
+ </volumeConfig>
+ </snapConfig>
+</cliOutput>
diff --git a/tests/glusterTestData.py b/tests/glusterTestData.py
index 165c1c3..ff2b1f0 100644
--- a/tests/glusterTestData.py
+++ b/tests/glusterTestData.py
@@ -1128,3 +1128,23 @@
'volumeName': 'snap-vol2',
'volumeUuid': '8558c40f-1581-414e-89d6-46854376ae3d'
}
+
+GLUSTER_SNAPSHOT_CONFIG_LIST = {
+ 'volume': {
+ 'snap-vol': {
+ 'snap-max-hard-limit': '256',
+ 'snap-max-soft-limit': '232',
+ 'effective-hard-limit': '255'
+ },
+ 'snap-vol2': {
+ 'snap-max-hard-limit': '254',
+ 'snap-max-soft-limit': '231',
+ 'effective-hard-limit': '254'
+ }
+ },
+ 'system': {
+ 'snap-max-hard-limit': '255',
+ 'auto-delete': 'disable',
+ 'snap-max-soft-limit': '91%'
+ }
+}
diff --git a/tests/gluster_cli_tests.py b/tests/gluster_cli_tests.py
index eeb00d9..b08e67b 100644
--- a/tests/gluster_cli_tests.py
+++ b/tests/gluster_cli_tests.py
@@ -1152,3 +1152,10 @@
tree = etree.fromstring(out)
status = gcli._parseRestoredSnapshot(tree)
self.assertEquals(status, glusterTestData.GLUSTER_SNAPSHOT_RESTORE)
+
+ def test_parseSnapshotConfigList(self):
+ with open("glusterSnapshotConfig.xml") as f:
+ out = f.read()
+ tree = etree.fromstring(out)
+ status = gcli._parseSnapshotConfigList(tree)
+ self.assertEquals(status, glusterTestData.GLUSTER_SNAPSHOT_CONFIG_LIST)
diff --git a/vdsm.spec.in b/vdsm.spec.in
index c1737a7..98384e0 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1300,6 +1300,7 @@
%{_datadir}/%{vdsm_name}/tests/glusterGeoRepStatus.xml
%{_datadir}/%{vdsm_name}/tests/glusterVolumeGeoRepConfigList.xml
%{_datadir}/%{vdsm_name}/tests/glusterVolumeProfileInfo.xml
+%{_datadir}/%{vdsm_name}/tests/glusterSnapshotConfig.xml
%{_datadir}/%{vdsm_name}/tests/glusterVolumeProfileInfoNfs.xml
%{_datadir}/%{vdsm_name}/tests/glusterVolumeRebalanceStatus.xml
%{_datadir}/%{vdsm_name}/tests/glusterVolumeRemoveBricksStatus.xml
diff --git a/vdsm/gluster/api.py b/vdsm/gluster/api.py
index 6d7e139..648b2bc 100644
--- a/vdsm/gluster/api.py
+++ b/vdsm/gluster/api.py
@@ -445,6 +445,45 @@
status = self.svdsmProxy.glusterSnapshotRestore(snapName)
return {'snapRestore': status}
+ @exportAsVerb
+ def snapshotConfigList(self, options=None):
+ try:
+ status = self.svdsmProxy.glusterSnapshotConfig()
+ except ge.GlusterSnapshotConfigFailedException as e:
+ raise ge.GlusterSnapshotConfigGetFailedException(rc=e.rc,
+ err=e.err)
+ return {'snapshotConfig': status}
+
+ @exportAsVerb
+ def volumeSnapshotConfigList(self, volumeName, options=None):
+ try:
+ status = self.svdsmProxy.glusterSnapshotConfig(
+ volumeName=volumeName)
+ except ge.GlusterSnapshotConfigFailedException as e:
+ raise ge.GlusterSnapshotConfigGetFailedException(rc=e.rc,
+ err=e.err)
+ return {'snapshotConfig': status}
+
+ @exportAsVerb
+ def volumeSnapshotConfigSet(self, volumeName, optionName, optionValue,
+ options=None):
+ try:
+ self.svdsmProxy.glusterSnapshotConfig(volumeName=volumeName,
+ optionName=optionName,
+ optionValue=optionValue)
+ except ge.GlusterSnapshotConfigFailedException as e:
+ raise ge.GlusterSnapshotConfigSetFailedException(rc=e.rc,
+ err=e.err)
+
+ @exportAsVerb
+ def snapshotConfigSet(self, optionName, optionValue, options=None):
+ try:
+ self.svdsmProxy.glusterSnapshotConfig(optionName=optionName,
+ optionValue=optionValue)
+ except ge.GlusterSnapshotConfigFailedException as e:
+ raise ge.GlusterSnapshotConfigSetFailedException(rc=e.rc,
+ err=e.err)
+
def getGlusterMethods(gluster):
l = []
diff --git a/vdsm/gluster/apiwrapper.py b/vdsm/gluster/apiwrapper.py
index f4177cd..0cdb795 100644
--- a/vdsm/gluster/apiwrapper.py
+++ b/vdsm/gluster/apiwrapper.py
@@ -248,6 +248,13 @@
def snapshotDeleteAll(self, volumeName):
return self._gluster.volumeSnapshotDeleteAll(volumeName)
+ def snapshotConfigSet(self, volumeName, optionName, optionValue):
+ return self._gluster.volumeSnapshotConfigSet(volumeName, optionName,
+ optionValue)
+
+ def snapshotConfigList(self, volumeName):
+ return self._gluster.volumeSnapshotConfigList(volumeName)
+
class GlusterSnapshot(GlusterApiBase):
def __init__(self):
@@ -264,3 +271,9 @@
def restore(self, snapName):
return self._gluster.snapshotRestore(snapName)
+
+ def configList(self):
+ return self._gluster.snapshotConfigList()
+
+ def configSet(self, optionName, optionValue):
+ return self._gluster.snapshotConfigSet(optionName, optionValue)
diff --git a/vdsm/gluster/cli.py b/vdsm/gluster/cli.py
index e60da27..c605fd8 100644
--- a/vdsm/gluster/cli.py
+++ b/vdsm/gluster/cli.py
@@ -1335,3 +1335,55 @@
return _parseRestoredSnapshot(xmltree)
except _etreeExceptions:
raise ge.GlusterXmlErrorException(err=[etree.tostring(xmltree)])
+
+
+def _parseSnapshotConfigList(tree):
+ """
+ returns {'system':{'snap-max-hard-limit': 'hardlimit',
+ 'snap-max-soft-limit': 'softLimit',
+ 'auto-delete': 'enable/disable'},
+ 'volume':{'name' :
+ {'snap-max-hard-limit: 'hardlimit',
+ 'effective-hard-limit: 'EffectiveHardlimit',
+ 'snap-max-soft-limit': 'softLimit'}
+ }
+ }
+ """
+ systemConfig = {}
+ systemConfig['snap-max-hard-limit'] = tree.find(
+ 'snapConfig/systemConfig/hardLimit').text
+ systemConfig['snap-max-soft-limit'] = tree.find(
+ 'snapConfig/systemConfig/softLimit').text
+ systemConfig['auto-delete'] = tree.find(
+ 'snapConfig/systemConfig/autoDelete').text
+
+ volumeConfig = {}
+ for el in tree.findall('snapConfig/volumeConfig/volume'):
+ config = {}
+ volumeName = el.find('name').text
+ config['snap-max-hard-limit'] = el.find('hardLimit').text
+ config['effective-hard-limit'] = el.find('effectiveHardLimit').text
+ config['snap-max-soft-limit'] = el.find('softLimit').text
+ volumeConfig[volumeName] = config
+
+ return {'system': systemConfig, 'volume': volumeConfig}
+
+
+ at makePublic
+def snapshotConfig(volumeName=None, optionName=None, optionValue=None):
+ command = _getGlusterSnapshotCmd() + ["config"]
+ if volumeName:
+ command.append(volumeName)
+ if optionName and optionValue:
+ command += [optionName, optionValue]
+
+ try:
+ xmltree = _execGlusterXml(command)
+ if optionName and optionValue:
+ return
+ except ge.GlusterCmdFailedException as e:
+ raise ge.GlusterSnapshotConfigFailedException(rc=e.rc, err=e.err)
+ try:
+ return _parseSnapshotConfigList(xmltree)
+ except _etreeExceptions:
+ raise ge.GlusterXmlErrorException(err=[etree.tostring(xmltree)])
diff --git a/vdsm/gluster/exception.py b/vdsm/gluster/exception.py
index e7e4533..00727d9 100644
--- a/vdsm/gluster/exception.py
+++ b/vdsm/gluster/exception.py
@@ -575,3 +575,21 @@
class GlusterSnapshotRestoreFailedException(GlusterSnapshotException):
code = 4705
message = "Snapshot restore failed"
+
+
+class GlusterSnapshotConfigFailedException(
+ GlusterSnapshotException):
+ code = 4706
+ message = "Snapshot config failed"
+
+
+class GlusterSnapshotConfigSetFailedException(
+ GlusterSnapshotException):
+ code = 4707
+ message = "Snapshot config set failed"
+
+
+class GlusterSnapshotConfigGetFailedException(
+ GlusterSnapshotException):
+ code = 4708
+ message = "Snapshot config get failed"
diff --git a/vdsm/rpc/vdsmapi-gluster-schema.json b/vdsm/rpc/vdsmapi-gluster-schema.json
index 5143f26..e4c0d14 100644
--- a/vdsm/rpc/vdsmapi-gluster-schema.json
+++ b/vdsm/rpc/vdsmapi-gluster-schema.json
@@ -1724,3 +1724,121 @@
{'command': {'class': 'GlusterSnapshot', 'name': 'restore'},
'data': {'snapName': 'str'},
'returns': 'SnapRestoreDetail'}
+
+##
+#
+# @SystemSnapshotConfig:
+#
+# @snap-max-hard-limit: Snapshot max hard limit
+#
+# @snap-max-soft-limit: Soft limit percentage of snapshot max limit
+#
+# @auto-delete: Auto delete enabled/disabled
+#
+# @Since: 4.17.0
+##
+{'type': 'SystemSnapshotConfig',
+ 'data': {'snap-max-hard-limit': 'str', 'snap-max-soft-limit': 'str',
+ 'auto-delete': 'str'}}
+
+##
+#
+# @VolumeSnapConfig:
+#
+# @snap-max-hard-limit: Snapshot max hard limit
+#
+# @effective-hard-limit: Effective snapshot Hard limit for that volume
+#
+# @snap-max-soft-limit: Snapshot soft limit for that volume
+#
+# @Since: 4.17.0
+##
+{'type': 'VolumeSnapConfig',
+ 'data': {'snap-max-hard-limit': 'str', 'effective-hard-limit': 'str',
+ 'snap-max-soft-limit': 'str'}}
+
+##
+#
+# @VolumeSnapshotConfigMap:
+#
+# A mapping of snapshot config indexed by volume name.
+#
+# @Since: 4.17.0
+##
+{'map': 'VolumeSnapshotConfigMap',
+ 'key': 'str', 'value': 'VolumeSnapConfig'}
+
+##
+# @SnapConfigDetail
+#
+# Snapshot configuration details
+#
+# @system: System level snapshot configuration
+#
+# @volume: Volume specific snapshot configuration
+#
+# Since: 4.17.0
+##
+{'type': 'SnapConfigDetail',
+ 'data': {'system': 'SystemSnapshotConfig',
+ 'volume': 'VolumeSnapshotConfigMap'}}
+
+##
+# @GlusterSnapshot.configList:
+#
+# get the config values of snapshot
+#
+# Returns:
+# current configuration related to system and all volumes
+#
+# Since: 4.17.0
+##
+{'command': {'class': 'GlusterSnapshot', 'name': 'configList'},
+ 'data': {},
+ 'returns': 'SnapConfigDetail'}
+
+##
+# @GlusterVolume.snapshotConfigList:
+#
+# get the config values of snapshot for a volume
+#
+# @volumeName: Gluster volume name
+#
+# Returns:
+# current configuration related a gluster volume
+#
+# Since: 4.17.0
+##
+{'command': {'class': 'GlusterVolume', 'name': 'snapshotConfigList'},
+ 'data': {'volumeName': 'str'},
+ 'returns': 'SnapConfigDetail'}
+
+##
+# @GlusterSnapshot.configSet:
+#
+# set gluster volume snapshot config
+#
+# @optionName: Option name to be set
+#
+# @optionValue: Value of the configration option
+#
+# Since: 4.17.0
+##
+{'command': {'class': 'GlusterSnapshot', 'name': 'configSet'},
+ 'data': {'optionName': 'str', 'optionValue': 'str'}}
+
+##
+# @GlusterVolume.snapshotConfigSet:
+#
+# set gluster volume snapshot config
+#
+# @volumeName: Gluster volume name
+#
+# @optionName: Option name to be set
+#
+# @optionValue: Value of the configration option
+#
+# Since: 4.17.0
+##
+{'command': {'class': 'GlusterVolume', 'name': 'snapshotConfigSet'},
+ 'data': {'volumeName': 'str', 'optionName': 'str', 'optionValue': 'str'}}
--
To view, visit https://gerrit.ovirt.org/39921
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iee32a95cf028cda33f25776c08820c5ed80f1033
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5-gluster
Gerrit-Owner: Darshan N <dnarayan at redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken at redhat.com>
Gerrit-Reviewer: Piotr Kliczewski <piotr.kliczewski at gmail.com>
More information about the vdsm-patches
mailing list