summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Safranek <jsafrane@redhat.com>2013-05-22 15:39:48 +0200
committerJan Safranek <jsafrane@redhat.com>2013-05-22 16:08:21 +0200
commita97e849eb2278fbebced3779500e4f7e3835c0d7 (patch)
tree09385f15528566fbac7409c1dc500824c116ef33
parent202ca77c8e5efed266ad07ddbd4c5964bc84400e (diff)
downloadopenlmi-providers-a97e849eb2278fbebced3779500e4f7e3835c0d7.tar.gz
openlmi-providers-a97e849eb2278fbebced3779500e4f7e3835c0d7.tar.xz
openlmi-providers-a97e849eb2278fbebced3779500e4f7e3835c0d7.zip
Remove obsolete openlmi-cimmof script, we use pywbem mofcomp.
-rwxr-xr-xopenlmi-cimmof342
1 files changed, 0 insertions, 342 deletions
diff --git a/openlmi-cimmof b/openlmi-cimmof
deleted file mode 100755
index 4f4ccaa..0000000
--- a/openlmi-cimmof
+++ /dev/null
@@ -1,342 +0,0 @@
-#!/usr/bin/env python
-# Copyright (C) 2012-2013 Red Hat, Inc. All rights reserved.
-#
-# This library 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.1 of the License, or (at your option) any later version.
-#
-# This library 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
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-"""
-Allows to modify Pegasus repository with declarations in mof files.
-Pegasus must be running for this script to work. It depends on cimmof
-binary, which is online compilator of MOF files for pegasus.
-
-It works in this way:
- 1. cimmof is called on input mof files
- 2. its output (xml) is then parsed by pywbem functions producing
- CIM objects (instances of ``pywbem.CIMClass`` and
- ``pywbem.CIMInstance``)
- 3. these objects are then used in calls to
- ``{Create,Modify}{Instance,Class}``
-
-*Note* that only Class and Instance declarations are supported.
- - This is due to limitations in pywbem parser.
- - Although this could be avoided by calling wbemexec on generated XML.
-"""
-
-import argparse
-import re
-import logging
-import subprocess
-import sys
-import pywbem
-import xml.dom.minidom as dom
-
-DEFAULT_NAMESPACE = "root/cimv2"
-DEFAULT_CIMMOF = "cimmof"
-
-RE_COMMENT = re.compile(r'\s*<!--.*?-->\s*', re.DOTALL)
-
-logging.basicConfig(level=logging.ERROR,
- format="%(levelname)s - %(message)s")
-LOG = logging.getLogger(__name__)
-
-def die(msg, *args, **kwargs):
- """
- Exit with error printed to stderr.
- """
- LOG.error(msg, *args, **kwargs)
- sys.exit(1)
-
-def xml_cleanup(xml_str):
- """
- Return xml string without comments and whitespaces.
- """
- # remove comments
- without_comments = "".join(RE_COMMENT.split(xml_str))
- # remove whitespaces
- return "".join(l.strip() for l in without_comments.split("\n"))
-
-def get_objects_from_mofs(cimmof, namespace, *mofs):
- """
- Call cimmof binary with mofs as input and obtain class/instance
- declarations in XML.
-
- Return list of pywbem CIM abstractions for each declaration.
- """
- cmd = [cimmof, '--xml', '-n', namespace]
- objects = []
- for mof in mofs:
- process = subprocess.Popen(cmd, stdin=subprocess.PIPE,
- stdout=subprocess.PIPE, stderr=sys.stderr)
- (out, _) = process.communicate(mof.read())
- if len(out.strip()) == 0:
- die("%s returned empty string, is Pegasus running?" % cimmof)
- parsed_dom = dom.parseString(xml_cleanup(out))
- # we cannot use pywbem.parse_cim because it does not support
- # DECLARATION element, but we can parse individual values
- for decl in parsed_dom.getElementsByTagName('VALUE.OBJECT'):
- # pywbem first makes tupletree from dom:
- # (name, attributes, children)
- # and from it generates pywbem CIM abstractions
- (_name, _attrs, obj) = pywbem.tupleparse.parse_value_object(
- pywbem.dom_to_tupletree(decl))
- objects.append(obj)
- return objects
-
-def get_instance_path(conn, namespace, instance, classes):
- """
- Obtains a class declaration from cimom for given instance and builds
- a path from it.
-
- :param conn is a wbem connection
- :param namespace (``str``) is a target namespace of instance
- :param instance (``CIMInstance``) contains class name and is used to get
- values of key properties. Is modified by adding path to it.
- :param classes (``dict``) is a cache of classes obtained from cimom.
- Its items are in form: ``(classname, CIMClass)``.
-
- Return ``CIMInstanceName``.
- """
- if not instance.classname in classes:
- classes[instance.classname] = conn.GetClass(instance.classname,
- IncludeQualifiers=True,
- namespace=namespace)
- cls = classes[instance.classname]
- keys = [p.name for p in cls.properties.values() if "Key" in p.qualifiers]
- path = pywbem.CIMInstanceName(instance.classname, namespace=namespace)
- for key in keys:
- if not key in instance:
- die("instance of %s is missing key property \"%s\"",
- instance.classname, key)
- path[key] = instance[key]
- instance.path = path
- return path
-
-def create_class(conn, cls, namespace, classes, allow_update=False):
- """
- Create class or modify it if already present.
-
- :param classes: (``dict``) a cache of classes obtained from cimom.
- :param allow_update: (``bool``) whether to modify existing class.
- """
- try:
- if not cls.classname in classes:
- classes[cls.classname] = conn.GetClass(cls.classname,
- IncludeQualifiers=True,
- namespace=namespace)
- except pywbem.CIMError as err:
- if err.args[0] != pywbem.CIM_ERR_NOT_FOUND:
- raise
- if cls.classname in classes:
- if not allow_update:
- LOG.error("class %s already exists", cls.classname)
- else:
- conn.ModifyClass(cls, namespace=namespace)
- LOG.info("modified class %s", cls.classname)
- else:
- conn.CreateClass(cls, namespace=namespace)
- LOG.info("created class %s", cls.classname)
-
-def create_instance(conn, inst, namespace, classes, allow_update=False):
- """
- Create instance or modify it if already present.
-
- :param classes: (``dict``) a cache of classes obtained from cimom.
- :param allow_update: (``bool``) whether to modify existing instance.
- """
- path = get_instance_path(conn, namespace, inst, classes)
- present = None
- try:
- present = conn.GetInstance(path)
- except pywbem.CIMError as err:
- if err.args[0] != pywbem.CIM_ERR_NOT_FOUND:
- raise
- if present is not None:
- try:
- if allow_update:
- conn.ModifyInstance(inst)
- LOG.info("modified instance for path %s", path)
- else:
- LOG.error("instance %s already exists", path)
- except pywbem.CIMError as err:
- if err.args[0] == pywbem.CIM_ERR_NOT_SUPPORTED:
- LOG.error("ModifyInstance() is not supported for class %s,"
- " please remove the instance first",
- inst.classname)
- else:
- raise
-
- else:
- conn.CreateInstance(inst)
- LOG.info("created instance for path %s", path)
-
-def reorder_objects(cmd, objects):
- """
- Reorder classes and instances so that dependent objects are handled
- later.
-
- Classes can depend between each other in two ways:
- 1. one inherits from another
- 2. one refers to another (associations)
-
- The first case can be solved by counting number of parents, that are
- also to be removed. Class with highest number will be created as last.
-
- The second one applies only to associations, which can not refer
- to each other. Let's just append them after non-associations.
-
- :param cmd: (``str``) can be "create" or "delete". In latter case the
- result is reversed, so the dependent classes/instances are removed
- as first.
-
- *Note* this does not handle dependencies between instances.
- """
- cls_list = []
- assoc_list = []
- cls_dict = set( c.classname.lower()
- for c in objects if isinstance(c, pywbem.CIMClass))
- # (class name, number of superclasses in cls_dict)
- cls_deps = pywbem.NocaseDict()
- inst_list = []
- for obj in objects:
- if isinstance(obj, pywbem.CIMClass):
- if 'association' in obj.qualifiers:
- assoc_list.append(obj)
- else:
- cls_list.append(obj)
- cls_deps[obj.classname] = 0
- parent = obj.superclass
- while parent in cls_dict:
- cls_deps[obj.classname] += 1
- parent = cls_dict[parent].classname
- else: # no specific reordering of instances
- inst_list.append(obj)
- key_func = lambda c: (cls_deps[c.classname], c.classname)
- cls_list = sorted(cls_list, key=key_func)
- assoc_list = sorted(assoc_list, key=key_func)
-
- result = cls_list + assoc_list + inst_list
- if cmd == "delete":
- result.reverse()
- return result
-
-def push_to_repo(namespace, cmd, objects, allow_update=False):
- """
- Create or delete desired objects in Pegasus repository.
-
- :param cmd: (``string``) is one of { 'create' | 'delete' }
- :param objects: (``list``) is a list of pywbem CIM abstractions
- created from mofs. They will be operated upon.
- """
- if not isinstance(namespace, basestring):
- raise TypeError("namespace must be string")
- if not cmd in ('create', 'delete'):
- raise ValueError('cmd must be either "create" or "delete"')
- classes = pywbem.NocaseDict()
- conn = pywbem.PegasusUDSConnection()
- objects = reorder_objects(cmd, objects)
- for obj in objects:
- try:
- if cmd == "create":
- if isinstance(obj, pywbem.CIMClass):
- create_class(conn, obj, namespace, classes, allow_update)
- elif isinstance(obj, pywbem.CIMInstance):
- create_instance(conn, obj, namespace, classes,
- allow_update)
- else:
- LOG.error("unsupported object for creation: %s",
- obj.__class__.__name__)
-
- else:
- try:
- if isinstance(obj, pywbem.CIMClass):
- conn.DeleteClass(obj.classname, namespace=namespace)
- LOG.info("deleted class %s", obj.classname)
- elif isinstance(obj, pywbem.CIMInstance):
- path = get_instance_path(conn, namespace, obj, classes)
- conn.DeleteInstance(path)
- LOG.info("deleted instance %s", path)
- else:
- LOG.error("unsupported object for deletion: %s",
- obj.__class__.__name__)
- except pywbem.CIMError as err:
- if err.args[0] == pywbem.CIM_ERR_NOT_FOUND:
- LOG.warn("%s not present in repository",
- obj if isinstance(obj, pywbem.CIMClass)
- else path)
- else:
- raise
-
- except pywbem.CIMError as err:
- if err.args[0] in (pywbem.CIM_ERR_INVALID_PARAMETER, ):
- LOG.warn("failed to %s %s: %s", cmd, obj, err)
- else:
- raise
-
-def parse_cmd_line():
- """
- Parse command line and return options.
- """
- parser = argparse.ArgumentParser(
- usage="%(prog)s [options] {create,delete} mof [mof ...]",
- description="Allows to create/delete instances and classes"
- " declared in MOF files. It operates only on Pegasus broker"
- " that needs to be up and running.")
- parser.add_argument('--cimmof', default=DEFAULT_CIMMOF,
- help="Path to cimmof binary to use.")
- #parser.add_argument('--xml', action='store_true', default=False,
- #help="Do not execute any action on cimom, just print the"
- #" xml to stdout.")
- parser.add_argument('-n', '--namespace', default=DEFAULT_NAMESPACE,
- help="Target CIM Repository namespace.")
- parser.add_argument('-v', '--verbose', action='store_true',
- default=False, help="Be more verbosive on output.")
-
- mof_parser = argparse.ArgumentParser(add_help=False)
- mof_parser.add_argument('mof', nargs='+',
- type=argparse.FileType('r'),
- default=sys.stdin,
- help="Mof files containing declarations of classes and instances"
- " to be installed or removed from Pegasus broker.")
-
- command = parser.add_subparsers(title="Operation commands",
- dest="command",
- help="Operation on declarations.")
- create_cmd = command.add_parser('create', parents=[mof_parser],
- help='Create instances and classes listed in mof files.')
- create_cmd.add_argument('-u', '--allow-update',
- action="store_true", default=False,
- help="Allow update of class declaration if it already exists.")
- command.add_parser('delete', parents=[mof_parser],
- help="Delete instances and classes listed in mof files.")
-
- args = parser.parse_args()
- return args
-
-def main():
- """
- The main functionality of script.
- """
- args = parse_cmd_line()
- if args.verbose:
- LOG.setLevel(logging.INFO)
- # parse mofs and build list of pywbem objects
- objs = get_objects_from_mofs(args.cimmof, args.namespace, *args.mof)
- if not objs:
- die("no declarations found!")
- push_to_repo(args.namespace, args.command, objs,
- getattr(args, 'allow_update', False))
-
-if __name__ == '__main__':
- main()
-