From 9e1db917fa4ac56b56343a796c41f3213f53a2af Mon Sep 17 00:00:00 2001 From: Tomas Smetana Date: Thu, 25 Apr 2013 15:34:07 +0200 Subject: Add the provider howto document --- doc/cim-provider-howto.md | 1213 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1213 insertions(+) create mode 100644 doc/cim-provider-howto.md (limited to 'doc') diff --git a/doc/cim-provider-howto.md b/doc/cim-provider-howto.md new file mode 100644 index 0000000..da7fb0e --- /dev/null +++ b/doc/cim-provider-howto.md @@ -0,0 +1,1213 @@ +% OpenLMI CIM Provider HOWTO +% John Dennis +% 3/30/2013 + +# License # + +This document is licensed under the [Create Commons ShareAlike +license](http://creativecommons.org/licenses/by-sa/3.0/) + +You are free: + +To Share + : To copy, distribute and transmit the work + +To Remix + : To adapt the work + +Use commercially + + : To make commercial use of the work + +Under the following conditions: + +Attribution + + : You must attribute the work in the manner specified by the author + or licensor (but not in any way that suggests that they endorse + you or your use of the work). + +Share Alike + + : If you alter, transform, or build upon this work, you may + distribute the resulting work only under the same or similar + license to this one. + + +# Introduction # + +CIM stands for Common Information Model. CIM is one component of WBEM +(Web-Based Enterprise Management). WBEM is a technology suite allowing +one to remotely enumerate the computing resources in an enterprise, +query their state, modify their configuration and otherwise act upon +those resources. People often use the term CIM when they are actually +discussing WBEM. Technically CIM is only a schema and +specification. The suite of specifications and technologies providing +enterprise computer management based on the CIM model is WBEM. + +CIM is an open standard under the auspices of DMTF ([Distributed +Management Task Force](http://www.dmtf.org/)). WBEM Management tools +based on CIM allow IT administrators to manage diverse computing +resources in a heterogeneous environment. In addtion to CIM DMTF also +manages many of the specifications related to WBEM. + +If you've been asked to write a CIM provider this document will +introduce you to the relevant technologies and guide you through the +development process. + +## WBEM Components ## + +Although technically CIM is only a schema definition the common usage +of the term CIM is often taken to mean the collection of tools and +technologies enabling computer management, i.e. WBEM. Without the +overarching technology ecosystem that WBEM provides CIM would just be +a paper abstraction. Lets briefly explore how these independent +components fit together to form a WBEM management solution. + +A manged system runs a service called the CIMOM, sometimes referred to +as a broker. CIMOM stands for Common Information Model Object +Manager. Typically the CIMOM is connected to the internet so that it +can provide remote administration of the computer. The CIMOM will load +a set of providers. Each provider is a software module dedicated to +managing one type (i.e. class) of resource on the computer, for +example network interfaces. There may be multiple instances of that +resource class. The provider is responsible for managing all instances +of that resource class. The provider in addition to providing +information about a resource instance may optionally allow the +resource instance to be configured or acted upon. It is the CIMOM +which organizes all the providers on the system and grants a CIM +client access to those providers. There are many CIMOM implementations +available. Since all CIMOM's are supposed to follow the collection of +WBEM standards all CIM clients should be able to inter-operate with +each CIMOM. + +A CIM provider can be loaded into different CIMOM implementations if +both the CIMOM and the provider utilize a common programming API. CMPI +(Common Manageability Programming Interface) is the standardized API +all CIMOM's and provider's should be coded to. + +A CIM client is able to connect to a CIMOM and interact with the +resources (i.e. objects) being managed by the CIMOM. It is important +to note *a CIM client does not interact directly with a provider* +running in the CIMOM. Rather the CIMOM will expose to the CIM +client the objects made available to the CIMOM via it's set of loaded +providers. + +Communication between a CIM client and a CIMOM occurs via +standardized protocols. At the time of this writing only one protocol +is in wide use, [CIM Operations over +HTTP](http://www.dmtf.org/standards/wbem). This protocol establishes +HTTP headers and then passes the CIM payload as an XML document to +the CIMOM. Responses from the CIMOM are also encoded in XML. The +definition of the XML documents are defined in [Representation of CIM +in XML](http://www.dmtf.org/standards/wbem). The collection of +standards used by CIM clients and CIMOM brokers are known as WBEM +(Web-Based Enterprise Management). + +In a typical scenario a CIM client will make an authenticated +connection to a CIMOM and ask it to enumerate the set of objects +it's interested in. The CIM client may choose to enumerate all instances +of a specific class or it may utilize a query language to refine the +results. CIM objects are often related to one another via +Associations. Querying via associations is very similar to +performing a join in SQL. + +CIM objects have properties and methods. A property is a piece of data +and a method is a function you can call. A CIM client may examine the +properties of a returned object to determine it's health state, +configuration, status, etc. Configuration is an advanced topic +explained in greater depth in [Resource +Configuration](#resource-configuration). + +A lot of information has been presented in a short time, to help +clarify here is simple break down of how the components fit together. + +1. CIM client makes authenticated connection to a CIMOM. + +2. Using the HTTP protocol an XML document is passed from the CIM + client to the CIMOM. The XML document describes the requested CIM + operation. Formation of the XML document is performed by CIM client + API library routines. + +3. The CIMOM interprets the XML document and calls routines in it's + providers to service the request. + +4. The CIMOM communicates with it's providers using the CMPI C + language API. + +5. The CIMOM coalesces the information supplied by it's providers + and forms an XML document which will then be returned as the HTTP + response to the CIM client. + +6. Library routines in the CIM client parse the XML document and + return the information via a CIM client API. + +# What do I need to know to write a CIM provider? # + +CIM is an extraordinarily complex topic. Without some guidance one can +easily get lost in the wealth of material resulting in spinning your +wheels without making a lot of progress. In this section we try to +summarize some key aspects of CIM and direct you to information that +will help you complete your task while helping you stay clear of +material which is not relevant. + +Material deemed to be critical will be highlighted + +**In a single sentence like this.** + +## CIM Schema, MOF and Profiles ## + +### CIM Schema and MOF Syntax ### + +CIM models real world objects and their relationships. Those objects +are modeled via CIM classes. A CIM class has properties and +methods. The DMTF has defined a set of CIM classes which are meant to +be the building blocks for a CIM model, this is the [CIM +Schema](http://www.dmtf.org/standards/CIM). The CIM Schema is +expressed in the MOF [Managed Object +Format](http://www.dmtf.org/standards/cim) syntax. MOF files are used +to define provider interfaces. + +**You must be fluent in MOF, it is the language of CIM.** + +### Models and Profiles ### + +A model is a collection of schema elements designed to model a +computer system component which is to be managed. It defines the +schema classes used to represent the managed elements and their +relationships. At it's heart a model is pure CIM Schema but schema +alone is not sufficient to explain intended usages nor the rules for +how the schema elements interact. This expository material is +collected into a document called a profile. Profiles follow a +standardized format called the [Management Profile Specification +Template](http://www.dmtf.org/standards/profiles). DMTF has already +defined numerous profiles to cover common computer system elements, +these are collected in the [Management +Profiles](http://www.dmtf.org/standards/profiles) web page. For some +reason the primary CIM page on the DMTF website does not link to the +management profiles. This curious omission might cause you to miss the +critical aspect of CIM profiles. + +**Prior to starting a CIM provider peruse the [Management +Profiles](http://www.dmtf.org/standards/profiles) to determine if one +or more profiles already exist, if so you should implement that model.** + +## Are you creating a model or implementing an existing profile? ## + +If a profile already exists your job is tremendously simplified. The +profile lays out the exact classes you have to implement along with +the rules for how they interact. Chapter 9 of the profile is +especially useful because it illustrates expected use cases with +examples, this can greatly aid your comprehension of the model and +it's profile. If a profile exists it is not necessary to understand +the breath and depth of the CIM Schema, the necessary schema elements +have already been assembled for you. At this point you can move on to +the provider implementation tasks at this point using the profile as a +recipe. + +However if a profile does not yet exist for your provider you must +define one. Unfortunately this is a very challenging task, it demands +an in-depth understanding the CIM Schema as well as a working knowledge +of the existing profiles. You need a familiarity with the existing profiles +in order to understand the design patterns of CIM, otherwise your +provider will not function as expected. + +If you do find yourself in the position of having to author a +model/profile then you should read the [Using the +Schema](http://www2.informatik.hu-berlin.de/~xing/Lib/cim-tutorial/using/index.html) +and [Extending the +Schema](http://www2.informatik.hu-berlin.de/~xing/Lib/cim-tutorial/extend/index.html) +sections in this [tutorial +section](http://www2.informatik.hu-berlin.de/~xing/Lib/cim-tutorial/intro/components.html). It +will provide the conceptual framework for schema design decisions. + + +## CMPI and KonkretCMPI ## + +OpenLMI encourages the use of KonkretCMPI to aid provider +development. + +**You will want to read the** [KonkretCMPI +Documentation](http://konkretcmpi.org/KonkretCMPI.html) **to +understand the basic development process with KonkretCMPI.** + +You might be tempted after reading the KonkretCMPI documentation to +dive and begin writing a provider believing KonkretCMPI given you +all you need to know to complete the task. But the truth is you're not +writing to a KonkretCMPI API, instead you're writing your provider +using the CMPI API. Essentially what KonkretCMPI does is insulate you +from CMPI. KonkretCMPI gives you a layer over CMPI that provides a +nice level of abstraction and other utility support. The other primary +advantage of KonkretCMPI is it automatically generates all the +necessary stub functions needed to comply with CMPI. After KonkretCMPI +runs you need to add your implementation to the function stubs +KonkretCMPI generated for you. Overall this simplifies the development +process. + +However, if you don't have an understanding of CMPI from the outset +you'll likely find what KonkretCMPI generates confusing because it +will seem to exist in a vacuum. You won't necessarily understand how +or why all the code pieces generated by KonkretCMPI fit together. You +might find yourself asking were certain initialization is performed or +in what order, how to manage life cycle, how are errors handled, +etc. All of this is clearly spelled out in the CMPI spec. You'll +probably also discover what KonkretCMPI gives to is incomplete, not +everything you may need to do in your provider is covered by +KonkretCMPI. There is an excellent chance you'll need to call the CMPI +API directly for services not provided by KonkretCMPI. It's best to +think of KonkretCMPI as a CMPI helper, it is not a CMPI replacement +(i.e. wrapper around CMPI). + +**Therefore you should also read the** [CMPI +Specification](https://www2.opengroup.org/ogsys/catalog/C061) + +The CMPI specification is long, here is my suggestion for reading it +to get started. Read chapters 1-5, those chapters lay out the basic +model and groundwork. If you understand those concepts you're in good +shape. The remaining chapters list the function tables and detailed +descriptions of each function in it's respective table. You don't need +to know the details of each function, but it helps to know what is +available. I would suggest perusing the beginning of each of these +remaining chapters just to see what's available in table, you can skip +the per function detail. + +The CMPI specification describes the CMPI API at the raw C level. It +can be very verbose code which is ripe for simplification through +pre-processor macros. Standard macros are defined in +`/usr/include/cmpi/cmpimacs.h`. Most code will use those macros and as +such those macros are the *effective* CMPI API. You should be using +these standard CMPI macros and be familiar with them for those cases +where KonkretCMPI does not provide an alternative. + +**You should be familiar with the contents of `cmpimacs.h`.** + +## Tutorials ## + +At this point you now have enough background information to dive into +the [DMTF CIM +Tutorial](http://www.wbemsolutions.com/tutorials/DMTF/). This tutorial +will help clarify the concepts already presented and round out +material we have glossed over. The tutorial is brief and a bit +superficial, it may or may not satisfy your needs for the +comprehension of CIM. + +**Read the** [DMTF CIM +Tutorial](http://www.wbemsolutions.com/tutorials/DMTF/). + +On the other hand the [Learn +CIM](http://www2.informatik.hu-berlin.de/~xing/Lib/cim-tutorial/start.html) +is much more complete and goes into much more depth. Not everyone will +need the material here but many will find it helpful. A good strategy +is to skim the tutorial making note of the material it covers and then +later when confronted with a gap in your comprehension return to the +tutorial. + +## Tools and Packages ## + +### CIMOM's ### + + * [OpenPegasus](https://collaboration.opengroup.org/pegasus/) + OpenPegasus is an open-source implementation of the DMTF CIM and + WBEM standards. OpenPegasus is written in C++ and is designed to + be portable. It builds and runs on most versions of UNIX, + Linux, OpenVMS, and Microsoft Windows. + + RPM package name: tog-pegasus + + You may find the [OpenPegasus Administrator's Guide](http://cvs.opengroup.org/cgi-bin/viewcvs.cgi/*checkout*/pegasus/doc/Admin_Guide_Release.pdf) + useful for topics concerning installation, configuration, + authentication, etc. of OpenPegasus. + + * [SFCB](http://sourceforge.net/apps/mediawiki/sblim/index.php?title=Sfcb) + Small Footprint CIM Broker. SFCB is a CIM server for + resource-constrained and embedded environments. It is written in C + and designed to be modular and lightweight. + + RPM package name: sblim-sfcb + + +### Development Tools ### + + * [KonkretCMPI](http://konkretcmpi.org/) is used to generate C source code + for providers from a mof specification. + + RPM package name: konkretcmpi + + + * [CMake](http://www.cmake.org/) is the required build tool. Various + aspects of OpenLMI provider development and deployment are + automatically handled via custom CMake macros provided by OpenLMI. + + RPM package name: cmake + + * [PyWBEM](http://sourceforge.net/apps/mediawiki/pywbem/index.php?title=Main_Page) + PyWBEM is a Python library supporting CIM operations over HTTP using + the WBEM CIM-XML protocol. It is easy to use and master. PyWBEM also + provides a Python provider interface suitable for rapid development + of CIM providers. + + RPM package name: pywbem + + * [OpenLMI](https://fedorahosted.org/openlmi/) + OpenLMI maintains numerous development tools to ease the task of + CIM provider development, deployement and WBEM operations. + + RPM package name: openlmi-providers-devel + + +### Client Tools ### + + * [PyWBEM](http://sourceforge.net/apps/mediawiki/pywbem/index.php?title=Main_Page) + can be used for client scripting in Python. + + * [YAWN](http://sourceforge.net/apps/mediawiki/pywbem/index.php?title=YAWN) + Yet Another WBEM Navigator. YAWN runs in the Apache web server, it + is Python based and utilizes Apache's mod-python. It is a CIM + client tool in that it provides a way to browse CIM Schema and + exercise CIM providers from within your local web browser. + + RPM package name: yawn + + * [OpenLMI](https://fedorahosted.org/openlmi/) + OpenLMI maintain several client tools + + RPM package name: openlmi-tools + +# Writing a CIM provider for OpenLMI # + +## OpenLMI Development Conventions ## + +OpenLMI has established a number of development conventions which you will +want to observe. + +* The preferred CIMOM is + [OpenPegasus](https://collaboration.opengroup.org/pegasus/) + +* The preferred source code language for providers is C. + +* [KonkretCMPI](http://konkretcmpi.org/) is used to generate C source code + for providers. + +* [CMake](http://www.cmake.org/) is the build tool. Various aspects of + provider development and deployment are automatically handled via + custom CMake macros provided by OpenLMI. + +* [PyWBEM](http://sourceforge.net/apps/mediawiki/pywbem/index.php?title=Main_Page) + is used for client scripting in Python and implementing providers + when Python is the language of choice. + + +## Set-Up Your Environment ## + +This assumes you are working on a Fedora/RHEL/CentOS RPM based Linux +distribution, although the basic concepts remain the same some package +names and commands may differ slightly for other Linux distributions. + +### Install CIMOM ### + +Install the OpenPegasus package + +~~~~~~ +sudo yum install tog-pegasus +~~~~~~ + +Make sure OpenPegasus is running. **Note:** provider registration only +works when OpenPegasus is running. + +~~~~~~ +sudo systemctl start tog-pegasus.service +~~~~~~ + +If you want the OpenPegasus CIMOM service to automatically start after +a reboot: + +~~~~~~ +sudo systemctl enable tog-pegasus.service +~~~~~~ + +**Tip:** pegasus can easily be controlled via the `cimserver` command, +in fact the systemd service control mechanisms simply calls the +`cimserver` command. During development you may find it easier to +start, stop, and check the status of the OpenPegasus CIMOM service via +`cimserver` rather than by the `systemctl` infrastructure. + +### Install YAWN ### + +YAWN is not a requirement but being able to browse the CIM class +hierarchy and invoke your provider from within your web browser is so +handy most developers will want this. YAWN runs in the Apache web +server therefore you will need to have Apache (e.g. httpd) installed +and running to be able to browse at the following URL http://host/yawn +where host is the host name you've installed YAWN on. + +~~~~~~ +sudo yum install httpd yawn +~~~~~~ + +Then make sure the Apache httpd service is running. + +~~~~~~ +sudo systemctl start httpd.service +~~~~~~ + +Optionally enable Apache httpd to start after booting. + +~~~~~~ +sudo systemctl enable httpd.service +~~~~~~ + +See the section on [OpenPegasus authentication](#openpegasus-authentication) to understand the +username and password prompts required by YAWN when you first connect. + +### Install Client Tools ### + +OpenLMI Tools provides a CIM shell and a few other handy utilities. + +~~~~~~ +sudo yum install openlmi-tools +~~~~~~ + +Various WBEM command line utilities are provided by sblim-wbemcli + +~~~~~~ +sudo yum install sblim-wbemcli +~~~~~~ + +Python libraries which allow you to write simple Python scripts for +WBEM operations are provided by pywbem. + +~~~~~~ +sudo yum install pywbem +~~~~~~ + +## Install Provider Development tools ## + +You will need KonkretCMPI, CMake and tools provided by OpenLMI. + +~~~~~~ +sudo yum install cmake konkretcmpi openlmi-providers-devel +~~~~~~ + +## Begin Provider Development (C Language) ## + +During this discussion we're going to use `XXX` as the name of +your provider, you will need to substitute `XXX` for your provider +name. + +You must use CMake to take advantage of the OpenLMI development +support. It expects the following structure in your development +tree. + +~~~~~~ +CMakeLists.txt +mof/LMI_XXX.mof +~~~~~~ + +CMake will read the contents of CMakeLists.txt and produce a set of +native Makefiles. CMake macros provided by openlmi-providers-devel +will also set things up to invoke konkretcmpi to translate your +LMI_XXX.mof file into a set of C source code files. + +The defaults for CMake do not correspond to the defaults when CMake is +invoked when producing OpenLMI RPM's. The goal here is not so much to +match RPM but rather to produce a build that matches the expected +system conventions and the OpenLMI conventions. + +Since you probably won't be producing an RPM for your provider +initially it's best to make sure CMake is configured to generate +Makefiles that will build using the same conventions for building and +installing as is done in RPM. There are various ways to do this but +one simple technique is to define a shell script which invokes CMake +with the matching RPM configuration, for example: + +~~~~~~ +#!/bin/sh + +/usr/bin/cmake -DCMAKE_VERBOSE_MAKEFILE=ON \ + -DCMAKE_INSTALL_PREFIX:PATH=/usr \ + -DINCLUDE_INSTALL_DIR:PATH=/usr/include \ + -DLIB_INSTALL_DIR:PATH=/usr/lib \ + -DSYSCONF_INSTALL_DIR:PATH=/etc \ + -DSHARE_INSTALL_PREFIX:PATH=/usr/share \ + -DBUILD_SHARED_LIBS:BOOL=ON . + +if [ $? -eq 0 ]; then + make +fi +~~~~~~ + +During development it is useful to turn on debugging symbols and turn +off optimization which complicate debugging using `gdb`. If you add + +~~~~~~ +export CFLAGS='-g -O0' +~~~~~~ + +to the above script before invoking cmake it will add these options to +the Makefile. CMake has other mechanisms for producing debug builds +(i.e. build targets). If you prefer those CMake mechanisms that's fine +too but I found the above to be simple and expedient. + +You will need a valid CMakeLists.txt file that follows the OpenLMI +CMake conventions. Since OpenLMI is under active development the +contents of the example CMakeLists.txt file may evolve or a +CMakeLists.txt template may be included in the future but for the time +being the example CMakeLists.txt represents a viable starting point. + +**Note:** If you aren't familiar with CMake it can be difficult to +figure out how to do a few simple things. For example if your provider +is dependent upon another library how do you get things set up such +that the include files are found and the right libraries are added +when linking? In the following CMakeLists.txt example I've added a +dependency on `glib2` only for the purposes of illustration, if your +provider does not use `glib2` you won't need any of the items in the +CMakeLists.txt file with the string "glib" in it. But you can use +"glib" items as a model for what needs to be added for any dependency +you do have. Also note that `glib2` installs pkgconfig files which +define how to compile and link against `glib2`. Most library packages ship +with pkgconfig files, the `glib2` example assumes pkgconfig files are +available for the dependency, if your dependency does not provide +pkgconfig files you'll have to adjust accordingly. + +~~~~~~ +cmake_minimum_required(VERSION 2.6) +include(OpenLMIMacros) +find_package(CMPI REQUIRED) +find_package(KonkretCMPI REQUIRED) + +find_package(PkgConfig QUIET) +pkg_check_modules(GLIB2 glib-2.0 REQUIRED) + +add_subdirectory(mof) + +set(PROVIDER_NAME XXX) +set(LIBRARY_NAME cmpiLMI_${PROVIDER_NAME}) +set(MOF LMI_XXX.mof) + + +# Add all your .c source files here +set(provider_SRCS + LMI_XXXProvider.c +) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") + +konkretcmpi_generate(${MOF} + CIM_PROVIDERS + CIM_HEADERS +) + +add_library(${LIBRARY_NAME} SHARED + ${provider_SRCS} + ${CIM_PROVIDERS} + ${CIM_HEADERS} +) + +# FIXME - /usr/include/openlmi shouldn't be hardcoded, needed for globals.h +# OpenLMI should provide a pkgconfig file +include_directories(${CMAKE_CURRENT_BINARY_DIR} + ${CMPI_INCLUDE_DIR} + ${GLIB2_INCLUDE_DIRS} + /usr/include/openlmi + ) + +target_link_libraries(${LIBRARY_NAME} + openlmicommon + ${KONKRETCMPI_LIBRARIES} + ${GLIB2_LIBRARIES} + ) + +# Create registration file +cim_registration(${PROVIDER_NAME} ${LIBRARY_NAME} ${MOF} share/openlmi-providers) + +install(TARGETS ${LIBRARY_NAME} DESTINATION lib${LIB_SUFFIX}/cmpi/) +~~~~~~ + +## Perform a Build ## + +Your mof/LMI_XXX.mof file will need to have been populated with +something to start with. At this point you may want to refer to the +[KonkretCMPI Documentation](http://konkretcmpi.org/KonkretCMPI.html) +to understand the basic development process with KonkretCMPI and +follow it's example tutorial. + +### Understanding KonkretCMPI Behavior ### + +The role of KonkretCMPI is to read a MOF file and generate C code +definitions and code stubs necessary to implement your +provider. KonkretCMPI generates 3 distinct sets of files: + +* .h C header files +* .c C implementation files +* .reg CIMOM registration files + +Anytime your mof file changes KonkretCMPI needs to run again to make +sure the generated files are in sync with the mof file contents. +If KonkretCMPI sees that you are missing any of the generated .c files it +will generate the .c files for you. However if KonkretCMPI finds an +existing .c file it will **not overwrite** the .c file. This is because +you will have likely added your custom provider implementation code to +these files and you don't want to lose your work. + +The header files are directly tied to the definitions found in the mof +file. It is essential those definitions be correct and reflect the +current contents of the mof file. Therefore KonkretCMPI **always +overwrites generated .h files**. + +**Tip:** Do not add any custom content to any of the generated .h +files, your content will be lost every time KonkretCMPI runs due to a +mof file change. If you did add any custom content to a generated .h +file you'll have to merge it back in, this is a pain. A better +approach is to put custom header style information in an independent +header file and include it in your .c file. + +**Note:** Because KonkretCMPI will not overwrite an existing .c file +you may need to merge function prototype information back into your .c +file. You typically only need to do this when a CIM method signature +is modified in the mof file or you've added a new CIM method. It's +much easier to merge function prototypes back into your .c file than +it is to move the .c file aside to allow KonkretCMPI to regenerate the +.c file and then subsequently needing to merge all your custom code +back into the newly generated .c file. + +**Tip:** It's easier to do your provider development if your mof file +is complete and exactly as you want it. This way you'll have fewer +issues with KonkretCMPI regenerating files, needing to unregister and +re-register your provider, or wondering why you can't see your updated +mof (because you forget to redo the registration). But sometimes it's +easier to develop your mof incrementally, you'll have to decide which +development strategy better suits your style and situation. + +## Installing and Registering Your Provider ## + +If all has gone well after typing `make` you will have compiled your +.c files and linked them into a provider module. Now you need to +install your provider so your CIMOM can load it. + +In order for your CIMOM to expose your provider it must be registered +with your CIMOM. This requires the following 3 files to have been +installed in the expected location in your file system. + +* provider module (i.e. your provider .so file) +* provider mof file +* provider registration file + +The following command will install these files + +~~~~~~ +sudo make install +~~~~~~ + +**Note:** This is one reason it's critical to invoke CMake with the +overridden defaults otherwise the installation directories will not +default to the system defaults. + +Now that the files are installed you must register your +provider. OpenLMI provides a utility script `openlmi-mof-register` to +simplify this task. **Note:** the `openlmi-mof-register` script is +also used to unregister a provider, more on that in a moment. + +Substitute `XXX` for the name of your provider. + +~~~~~~ +sudo openlmi-mof-register register \ + /usr/share/openlmi-providers/XXX.mof \ + /usr/share/openlmi-providers/XXX.reg +~~~~~~ + +**Note:** OpenPegasus must be running when you register or unregister +a provider. + +**Tip:** During your provider development cycle of edit/build/test you +do not need to re-register your provider if your mof file did not +change. It's sufficient to just install your updated provider .so +(e.g. `sudo make install`) and restart the CIMOM. However if your mof +file changed your CIMOM won't know about the mof changes because one +of the things registration does is import the mof definitions into the +CIMOM. After editing your mof you will need to unregister your old +provider and re-register it again. In summary only after a mof +modification you will need to do the following: + +~~~~~~ +sudo openlmi-mof-register unregister \ + /usr/share/openlmi-providers/XXX.mof \ + /usr/share/openlmi-providers/XXX.reg +sudo make install +sudo openlmi-mof-register register \ + /usr/share/openlmi-providers/XXX.mof \ + /usr/share/openlmi-providers/XXX.reg +~~~~~~ + +## Testing Your Provider ## + +Once your provider is installed and registered you will want to +exercise it. Here are some simple ways you can do that, which one you +choose is up to you, all boil down to invoking a CIM client against +your CIMOM. + +* Use YAWN in your web browser, open a URL +(e.g. `http://localhost/yawn) and navigate to one of your provider +classes. + +* Write a Python script using PyWBEM and run that script. + +* Use the OpenLMI shell + +## Development Debugging Tricks and Techniques ## + +### Starting, Stopping and Controling OpenPegasus ### + +Don't use the `systemctl` service command to stop and start +OpenPegasus, instead use the `cimserver` command, it's much easier, +plus you can specify one time configuration parameters useful for +debugging (see below). + +### Run OpenPegasus In The Foreground ### + +You can insert printf debugging statements in your code but you won't +see them on the console unless you run OpenPegasus in a special +way. Also, you will want to run OpenPegasus in the foreground, not +allow it to fork a daemon process or spawn child processes. Running +OpenPegasus in the following way is much friendlier during the +development cycle. + +~~~~~~ +sudo cimserver daemon=false forceProviderProcesses=false +~~~~~~ + +When run this way you'll see any printf's you've added, they will +appear in your console. When you're done with the current testing +cycle simply control-c and OpenPegasus will exit. A rapid development +cycle might look like this: + +~~~~~~ +# Edit your provider source code +make +sudo make install +sudo cimserver daemon=false forceProviderProcesses=false +# Test via YAWN or a script +~~~~~~ + +### Using the Debugger ### + +It's easy to set a breakpoint in your provider and have `gdb` break +there for you. Of course you'll want to have compiled with -g to turn +debugging symbols on and you'll probably also want to disable +optimization with -O0 so that single stepping in the debugger +follows your source code instead of jumping around. + +Create a .gdbinit file in your local directory. Let's say you want to +break on LMI_foobar + +~~~~~~ +set breakpoint pending on +b LMI_foobar +r daemon=false forceProviderProcesses=false +~~~~~~ + +For security reasons current versions of `gdb` require you to enable +reading the the local .gdbinit file, one solution is to add this to +your `~/.gdbinit` file: + +~~~~~~ +add-auto-load-safe-path . +set auto-load local-gdbinit on +~~~~~~ + +Then run OpenPegasus under `gdb` + +~~~~~~ +sudo gdb /usr/sbin/cimserver +~~~~~~ + +Exercise your provide in your preferred fashion and you should +break. Then debug in `gdb` as you would normally do. + +Of course like most things in life there are multiple ways of doing +things, the above is just one suggestion, you could use gdb to attach +to the running cimserver process or any number of other mechanisms, use +your programming skills and knowledge to find a methodology that works +best for you. + +### Controlling OpenPegasus Behavior ### + +[Advanced startup properties for CIMOM](http://publib.boulder.ibm.com/infocenter/iseries/v6r1m0/topic/rzatl/rzatladvstartup.htm) +provides useful information about available options to control +OpenPegasus behavior. + +### OpenPegasus Logging and Tracing ### + +OpenPegasus has a tracing facility. You can utilize the CMPI logging +commands to record debug and/or informational messages to the +OpenPegasus trace file instead of printf statements. This is a cleaner +solution once your provider more stable and you can dispense with +temporary printf statements. + +The CMPI logging and trace functions are `CMLogMessage` and +`CMTraceMessage` and are defined in `/usr/include/cmpi/cmpimacs.h`, +refer to that file for their usage. + +But more importantly when you're baffled about what OpenPegasus is +doing it can be invaluable to have full logging and trace information +at your disposal to peruse. The trace file is: + +~~~~~~ +/var/lib/Pegasus/cache/trace/cimserver.trc +~~~~~~ + +To ratchet up the verbosity of the trace information you may want to +run OpenPegasus like this: + +~~~~~~ +sudo cimserver daemon=false forceProviderProcesses=false \ + logLevel=TRACE traceLevel=5 traceFacility=File \ + traceComponents=All +~~~~~~ + +Detailed information about OpenPegasus tracing can be found in +[OpenPegasus Tracing User Guide](http://cvs.opengroup.org/cgi-bin/viewcvs.cgi/*checkout*/pegasus/doc/TracingUserGuide.pdf?rev=1.3) + + +### Dumping Method Parameters To the Console ### + +Sometimes it's nice to be able to see the CIM method parameters being +passed to your CIM method by dumping them to the console (of course +you could also run under `gdb` too and break on the +method). KonkretCMPI generates a Args_Print function in the generated +.h file you can call. + +To print method YYY args in konkret: + +In XXX_DispatchMethod() in XXX.h + +Add + +XXX_YYY_Args_Print(&args, stdout); + +*after* XXX_YYY_Args_InitFromArgs (otherwise args won't be initialized.) + +## Provider Development Tips ## + +## MOF Development Issues ## + +### Structures and Array of Structures as CIM Method Parameters ### + +There is no way to pass a complex object in a CIM method call (i.e. a +structure or class). CIM arrays are limited to simple scalar base +types (int, string, etc.). Thus there is no way to pass things like +(key,value) pairs directly. Instead one needs to define an array for +the key names, and an array for the values (of a specific base +type). To find the value of a key look up it's value at the same index +in the as it appears in the key array. The same holds true for any +array of structures, you have to decompose the structure members into +individual arrays and recombine them back together by indexing into +each array using the same index. Don't forget you'll need to declare +the array with the `ArrayType ( "Indexed" )` qualifier in the MOF +file. This is very reminiscent of programming in FORTRAN, ugh! + +## KonkretCMPI Oddities ## + +KonkretCMPI doc uses this example invocation (note KonkretCMPI +invocation is normally done via CMake macros) + +~~~~~~ +konkret -s KC_Widget -m Widget.mof KC_Widget=Widget +~~~~~~ + +But there is no man page describing what the args do in detail and the +-h option is very terse and omits describing the final arg and for a +long it was not clear to me what that arg was doing. The CMake macro +konkretcmpi_generate does not use the same arg list as what is +documented above which is also confusing. Apparently the form used in +the Konkret doc of `KC_Widget=Widget` is an alias mechanism which +modifies the class name as found in the MOF file (lhs) to an alternate +name (rhs) used in the generated C code. The type names, function +names, generated file names etc. will all use the rhs alias, otherwise +they will use the class name as found in the MOF. + +## OpenPegasus Authentication ## + +The [OpenPegasus Administrator's Guide](http://cvs.opengroup.org/cgi-bin/viewcvs.cgi/*checkout*/pegasus/doc/Admin_Guide_Release.pdf) +gives a brief overview of how OpenPegasus handles authentication. But +the following document which is installed along with the tog-pegasus +package on Red Hat systems gives a more comprehensive overview. + +~~~~~~ +/usr/share/doc/tog-pegasus-*/README.RedHat.Security +~~~~~~ + +The short story is root user authentication works for local +connections but is denied for network connections. If you've installed +YAWN then the user authentication prompt issued by YAWN appears to +OpenPegasus as a local user and root will work. However this is quite +insecure and should be avoided. Root authentication is possibly +justified in constrained cases such as during development where the +target machine is on an isolated local network (i.e. virtual +machines used for test and development). + +The preferred mechanism is to use the `pegasus` user account which is +created when tog-pegasus is installed. However there is no password +established for the `pegasus` user during install (this is a security +precaution) and you will need to set the `pegasus` user password +(requires root privileges) + +~~~~~~ +sudo passwd pegasus XXX +~~~~~~ + +where XXX is the `pegasus` password. After this is done you can +authenticate to OpenPegasus with the username `pegasus` and the +password you created. + +# Advanced CIM Topics # + +## Resource Configuration ## + +How one handles configuration of CIM elements is a surprisingly +complex topic and woefully under documented. If you're developing your +own profile you'll need to understand these topics. The best way to +learn about configuration approaches is to study the existing CIM +profiles and see how they are handled in the example profiles. + +One naive approach would be to provide a CIM method to set +configuration parameters on your CIM object. This is a traditional +approach in many programming API's. However the CIM Schema and +existing models often take a different approach utilizing the +following CIM classes and associations. This is probably worth entire +tutorial on it's own. Here is a brief introduction: + +The following classes are used as base classes to contain +configuration parameters. + +* `CIM_SettingData` +* `CIM_Capabilities` + +The following *association* classes are used to form links between +the `SettingData` and `Capability` derived classes. + +* `CIM_ElementSettingData` +* `CIM_ElementCapabilities` +* `CIM_SettingsDefineCapabilities` +* `CIM_SettingsDefineState` + +The way these can be combined is many fold. Naively you may assume you +would have only one `SettingData` instance where the entirety of the +configuration parameters are stored. But in fact you may have many +such instances joined in a web by associations, some indicating +current values, defaults values to be applied next, minimum values, +maximum values, etc. + +#### CIM_SettingData #### + +ChangeableType + : Has the following possible values + + * Not Changeable - Persistent + * Changeable - Transient + * Changeable - Persistent + * Not Changeable - Transient + +CIM_SettingData is linked via CIM_SettingsDefineState and +CIM_SettingsDefineCapabilities associations. + + +#### CIM_ElementSettingData #### + +CIM_ElementSettingData has the following properties: + +IsDefault + : Has the following possible values + + * Unknown + * Is Default + * Is Not Default + +IsCurrent + : Has the following possible values + + * Unknown + * Is Current + * Is Not Current + +IsNext + : Has the following possible values + + * Unknown + * Is Next + * Is Not Next + * Is Next For Single Use + +#### CIM_ElementCapabilities #### + +Characteristics[] + : Has the following possible simultaneous values + + * Default + * Current + +#### CIM_SettingsDefineCapabilities #### + +PropertyPolicy + : Has the following possible values + + * Independent + * Correlated + +ValueRole + : Has the following possible values + + * Default + * Optimal + * Mean + * Supported + +ValueRange + : Has the following possible values + + * Point + * Minimums + * Maximums + * Increments + +### Tying the Configuration Classes Together ### + +If you're looking at a CIM_ElementSettingData association the `IsDefault` +property will tell you if the group of configuration parameters +pointed by the SettingData reference are the default values. Likewise +the `IsCurrent` property tells you if the configuration parameters +pointed by the SettingData reference are current values or not. The +`IsNext` property tells you if the the configuration parameters +pointed by the SettingData reference will be applied the next time +configuration is applied and whether those parameters will permanently +persist. + +The CIM_ElementCapabilities association tells you if the +CIM_Capabilities pointed to by the association for a CIM_ManagedElement +(i.e. an object) are the defaults or the current values. + +The CIM_SettingsDefineCapabilities association tells you how to +interpret the SettingData being pointed to. There may be many +SettingData objects needed to fully specify the configuration. The +`PropertyPolicy` property tells you if you have to correlate the +SettingData values or if you can treat them independently. The +`ValueRole` property tells you what role the pointed to SettingData +plays, i.e. defaults, optimal, average, etc. The `ValueRange` property +tells you if the pointed to SettingData are a single set of values, +just the minimum values, just the maximum values, or represent the +increments each property value can be stepped by. + +In practice what the `ValueRole` property does is force you to have +many SettingData objects to specify the configuration for an +element. Let's say your CIM element has some properties that can only +be specified within a minimum and maximum range. You would then create +a SettingData containing the valid minimums and point to it via a +CIM_SettingsDefineCapabilities association. Likewise you would create +a SettingData containing the valid maximums and point to it via a +CIM_SettingsDefineCapabilities association. To ascertain the valid +range you have to query for CIM_SettingsDefineCapabilities where the +`ValueRange` property is Minimums, query for the Maximums and then +follow the association pointers to each respective Capabilities to form +the min/max range. By the same token a CIM_SettingsDefineCapabilities +whose `ValueRange` property is Point indicates a single set of values +rather than a range. Ultimately you have to find all the +CIM_SettingsDefineCapabilities objects bound to the element you want +to configure and interpret them. + +Are you confused yet? It's very convoluted and the possible +combinations are large. Don't you wish you could just call a method +and set the configuration parameters or query them? The best way to +wrap your head around all this is to study the various profiles +utilizing these classes, especially study the use case examples in +Chapter 9 of the profile, that will help solidify your understanding. + +# FAQ # + +**Q:** How do I make a CIM method a class method as opposed to a instance +method? + +**A:** An instance method is bound to the instance it is called from, in +object oriented languages the instance is often called "self" or +"this". This is the default method binding in CIM. However you can +specify class methods as well which are not bound to an +instance, to do this add the `Static` qualifier to the list of +qualifiers belonging to the method. + +# Vocabulary # + +CIM + + : [Common Information Model](http://www.dmtf.org/standards/cim) is + schema and associated specification which details how to represent + the elements of a computer system in order to manage those + elements. This yeilds a common and portable mechanism by which IT + administrators can manage their computing resources. CIM is + defined by the DMTF. + +CIM Schema + + : The [CIM Schema](http://www.dmtf.org/standards/CIM) is a + collection of predefined CIM classes which forms the building + blocks for modeling in CIM. The CIM Schema is expressed in MOF + (Managed Object Format) syntax. + +CIMOM + + : Common Information Model Object Manager. Sometimes referred to as a + broker the CIMOM is a network connected service running on a + managed computer which grants access to the CIM providers on + the managed computer. A CIM client connects to the CIMOM in + order to manage a specific resource on the managed computer. Those + resource instances are made available to the CIMOM by the + providers loaded by the CIMOM. + +CMPI + + : [Common Manageability Programming + Interface](http://www.opengroup.org/standards/enterprise-management). CMPI + is an open standard defined by the Open Group which defines the + programming API between a CIMOM and a CIM provider. In the + absence of CMPI each CIM provider would need to be coded to + the API of the CIMOM it was loaded into. CMPI allows a CIM + provider to be written once and utilized by different CIMOM + implementations. + +DMTF + + : [Distributed Management Task Force](http://www.dmtf.org/) is an + industry consortium defining open standards for computer system + management. + +KonkretCMPI + + : A tool used to aid development of CIM + providers. [KonkretCMPI](http://konkretcmpi.org/) reads a MOF + specification file and generates a set of C header files, C + program files and provider registration files. The primary purpose + of KonkretCMPI is to insulate a provider author from the CMPI API + by providing all the necessary "glue code" needed to adhere to the + CMPI specification. This allows the programmer to focus on the + particulars of the provider. + +MOF + + : [Managed Object Format](http://www.dmtf.org/standards/CIM) is the + syntax used to describe the CIM Schema. MOF files are used to + define provider interfaces. + +Provider + + : A software module which is loaded by the CIMOM broker running + locally on a managed system which provides information about a + type (i.e. class) of resource, for example network + interfaces. There may be multiple instances of that resource + class. The Provider is responsible for managing all instances + of that resource class. The Provider in addition to providing + information about a resource instance may optionally allow the + resource instance to be configured or acted upon. + +WBEM + + : [Web-Based Enterprise + Management](http://www.dmtf.org/standards/wbem). A collection of + standardized technologies providing unified management of + distributed computing environments based on CIM concepts. -- cgit