summaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorTomas Smetana <tsmetana@redhat.com>2013-04-25 15:34:07 +0200
committerTomas Smetana <tsmetana@redhat.com>2013-04-25 15:34:07 +0200
commit9e1db917fa4ac56b56343a796c41f3213f53a2af (patch)
tree9d47a334a3cdad520d764c8b591e543e7ca4b180 /doc
parenta10370b13e73184080146ead6899726f78423c43 (diff)
downloadopenlmi-providers-9e1db917fa4ac56b56343a796c41f3213f53a2af.tar.gz
openlmi-providers-9e1db917fa4ac56b56343a796c41f3213f53a2af.tar.xz
openlmi-providers-9e1db917fa4ac56b56343a796c41f3213f53a2af.zip
Add the provider howto document
Diffstat (limited to 'doc')
-rw-r--r--doc/cim-provider-howto.md1213
1 files changed, 1213 insertions, 0 deletions
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 <jdennis@redhat.com>
+% 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.