diff --git a/mof_compiler b/mof_compiler index 03d31e968..9a302a9ba 100755 --- a/mof_compiler +++ b/mof_compiler @@ -36,7 +36,8 @@ from getpass import getpass from pywbem._cliutils import SmartFormatter from pywbem import WBEMConnection, Error, CIMError, CIM_ERR_NOT_FOUND, \ CIM_ERR_INVALID_SUPERCLASS, CIM_ERR_INVALID_PARAMETER -from pywbem.mof_compiler import MOFWBEMConnection, MOFCompiler +from pywbem.mof_compiler import MOFWBEMConnection, MOFWBEMConnectionRollback, \ + MOFCompiler from pywbem.cim_http import get_default_ca_cert_paths from pywbem import __version__ from pywbem._nocasedict import NocaseDict @@ -402,9 +403,11 @@ Example: if args.remove or args.dry_run: # Write classes/instances to local repo - conn_mof = MOFWBEMConnection(conn=conn) + # The MOFWBEMConnectionRollback connection changes CreateInstance + # to set the path in the NewInstance + conn_mof = MOFWBEMConnectionRollback(conn=conn) else: - # sent classes/instance to conn + # This sends classes/instance to conn conn_mof = MyMOFWBEMConnection(conn=conn) # Make it simple for this script to use these attributes: diff --git a/pywbem/mof_compiler.py b/pywbem/mof_compiler.py index 3bb076d8d..d66814abf 100644 --- a/pywbem/mof_compiler.py +++ b/pywbem/mof_compiler.py @@ -2050,6 +2050,7 @@ def GetClass(self, *args, **kwargs): if self.conn is None: ce = CIMError(CIM_ERR_NOT_FOUND, cname) raise ce + # Otherwise get the class from conn and insert into self.classes cc = self.conn.GetClass(*args, **kwargs) try: self.classes[self.default_namespace][cc.classname] = cc @@ -2094,8 +2095,8 @@ def CreateClass(self, *args, **kwargs): cc = args[0] if args else kwargs['NewClass'] if cc.superclass: try: - _ = self.GetClass(cc.superclass, LocalOnly=True, # noqa: F841 - IncludeQualifiers=False) + self.GetClass(cc.superclass, LocalOnly=True, + IncludeQualifiers=False) except CIMError as ce: if ce.status_code == CIM_ERR_NOT_FOUND: ce.args = (CIM_ERR_INVALID_SUPERCLASS, cc.superclass) @@ -2265,6 +2266,49 @@ def rollback(self, verbose=False): # Issue #990: Also roll back changes to qualifier declarations +class MOFWBEMConnectionRollback(MOFWBEMConnection): + """ + A CIM repository connection to an in-memory repository on top of an + underlying repository, adapts MOFWBEMConnection by modifying + CreateInstance to set CIMInstanceName on each created instance from + the properties in the instance. This is required for rollback + because the rollback uses the instance path to tell the server + delete each instance. + + This class implements the + :class:`~pywbem.BaseRepositoryConnection` interface. + + Raises: + + : The methods of this class may raise any exceptions described for + class :class:`~pywbem.WBEMConnection`. + """ + def CreateInstance(self, *args, **kwargs): + """ + Extend CreateInstance to set instancePath on the instance so that + there is a path to be used in rollback. + + For a description of the parameters, see + :meth:`pywbem.WBEMConnection.CreateInstance`. + """ + + inst = args[0] if args else kwargs['NewInstance'] + + # If the path or keybindings do not exist, create the path from + # the class and instance and set it into NewInstance + if not inst.path or not inst.path.keybindings: + cls = self.GetClass(inst.classname, + LocalOnly=False, + IncludeQualifiers=True) + inst.path = CIMInstanceName.from_instance(cls, inst) + try: + self.instances[self.default_namespace].append(inst) + except KeyError: # default_namespace does not exist. Create it + self.instances[self.default_namespace] = [inst] + + return inst.path + + def _print_logger(msg): """Print the `msg` parameter to stdout.""" print(msg) diff --git a/tests/unittest/pywbem/test.mof b/tests/unittest/pywbem/test.mof index 7346868cf..bdcffc98e 100644 --- a/tests/unittest/pywbem/test.mof +++ b/tests/unittest/pywbem/test.mof @@ -37,17 +37,17 @@ instance of PyWBEM_PersonCollection as $Collection { InstanceID = "PersonCollection"; }; -instance of PyWBEM_MemberOfPersonCollection { +instance of PyWBEM_MemberOfPersonCollection as $MemOf1 { Collection = $Collection; Member = $Alice; }; -instance of PyWBEM_MemberOfPersonCollection { +instance of PyWBEM_MemberOfPersonCollection as $MemOf2 { Collection = $Collection; Member = $Bob; }; -instance of PyWBEM_MemberOfPersonCollection { +instance of PyWBEM_MemberOfPersonCollection as $MemOf3 { Collection = $Collection; Member = $Charlie; }; @@ -160,11 +160,8 @@ instance of PyWBEM_AllTypes { arraySint32 = {0, -9999}; arrayUint64 = {0, 99999}; arraySint64 = {-99999, 0, 99999}; - arrayReal32 = {0, 1.9}; - arrayReal64 = {0, 1.9}; + arrayReal32 = {1.1, 1.9}; + arrayReal64 = {1.2345, 1.9}; arrayString = {"This is a test string", "Second String"}; arrayDateTime = {"19991224120000.000000+360", "19991224120000.000000+360"}; }; - - - diff --git a/tests/unittest/pywbem/test_mof_compiler.py b/tests/unittest/pywbem/test_mof_compiler.py index 793c92be7..427e30b1f 100755 --- a/tests/unittest/pywbem/test_mof_compiler.py +++ b/tests/unittest/pywbem/test_mof_compiler.py @@ -338,6 +338,12 @@ def test_testmof(self): LocalOnly=False, IncludeQualifiers=True) self.assertEqual(ccs.properties['Member'].type, 'reference') + ccs = self.mofcomp.handle.GetClass( + 'PyWBEM_PersonCollection', + LocalOnly=False, IncludeQualifiers=True) + self.assertEqual(ccs.properties['InstanceID'].type, 'string') + self.assertTrue('Key' in ccs.properties['InstanceID'].qualifiers) + # get the instances insts = self.mofcomp.handle.instances[NAME_SPACE]