File cmpi-provider-register.py of Package cmpi-provider-register.4944
#!/usr/bin/env python
#*******************************************************************************
# Copyright (C) 2008 Novell, Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# - Neither the name of Novell, Inc. nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL Novell, Inc. OR THE CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
#*****************************************************************************/
from pywbem.mof_compiler import MOFCompiler, MOFWBEMConnection, MOFParseError
from optparse import OptionParser
import os
import errno
import sys
from subprocess import call, PIPE, STDOUT, Popen
from getpass import getpass
import pywbem
sfcb_init_script = '/usr/sbin/rcsblim-sfcb'
pegasus_init_script = '/etc/init.d/tog-pegasus'
pegasus_cimserver_exe = '/usr/sbin/cimserver'
pegasus_unix_socket = '/var/run/tog-pegasus/cimxml.socket'
scx_home = '/opt/microsoft/scx'
scx_init_script = '/etc/init.d/scx-cimd'
scx_cimserver_exe = scx_home + '/bin/scxcimserver'
scx_unix_socket = '/var' + scx_home + '/tmp/cim.socket'
scx_provider_dir = scx_home + '/lib/providers'
scx_ext_dir = '/opt/microsoft/scx/lib/providers/ext'
if os.path.isdir('/usr/lib64/cmpi'):
cmpi_dir = '/usr/lib64/cmpi'
elif os.path.isdir('/usr/lib/cmpi'):
cmpi_dir = '/usr/lib/cmpi'
else:
cmpi_dir = None
sfcb_regs = []
peg_regs = []
g_verbose = False
g_restart = True
g_last_output = ''
class Error(Exception):
pass
class SimpleHandle(object):
def __init__(self):
self.default_namespace = 'root/cimv2'
class InstStoringConn(pywbem.WBEMConnection):
def __init__(self, *args, **kwargs):
self.instances = {}
pywbem.WBEMConnection.__init__(self, *args, **kwargs)
def CreateInstance(self, *args, **kwargs):
inst = len(args) > 0 and args[0] or kwargs['NewInstance']
try:
self.instances[self.default_namespace].append(inst)
except KeyError:
self.instances[self.default_namespace] = [inst]
return pywbem.WBEMConnection.CreateInstance(self, *args, **kwargs)
class SimpleCompiler(MOFCompiler):
def __init__(self):
self.first_file = True
self.handle = MOFWBEMConnection()
self.handle = SimpleHandle()
MOFCompiler.__init__(self, self.handle)
def compile_file(self, filename, ns):
if self.first_file:
self.first_file = False
self.rval = []
MOFCompiler.compile_file(self, filename, ns)
return self.rval
self.rval.append((ns, filename))
def process_sfcb(mof, stage, remove=False):
mofcomp = SimpleCompiler()
files = []
files = mofcomp.compile_file(mof, None)
for file_ in files:
dest = stage + '/mofs/' + file_[0]
src = file_[1]
if not remove:
if not os.path.exists(dest):
os.makedirs(dest)
dest+= '/' + os.path.basename(src)
if remove:
try:
os.unlink(dest)
except OSError, e:
if e.errno != errno.ENOENT:
raise
else:
if os.path.islink(dest):
if not os.path.exists(os.readlink(dest)):
os.unlink(dest)
try:
os.symlink(src, dest)
except OSError, e:
if e.errno != errno.EEXIST:
raise
if os.readlink(dest) != src:
print 'Warning: %s already exists' % dest
for src in sfcb_regs:
dest = stage + '/regs/' + os.path.basename(src)
if remove:
try:
os.unlink(dest)
except OSError, e:
if e.errno != errno.ENOENT:
raise
else:
if os.path.islink(dest):
if not os.path.exists(os.readlink(dest)):
os.unlink(dest)
try:
os.symlink(src, dest)
except OSError, e:
if e.errno != errno.EEXIST:
raise
if os.readlink(dest) != src:
print 'Warning: %s already exists' % dest
if g_restart:
sfcb_running = False
if run([sfcb_init_script, 'status']) == 0:
sfcb_running = True
run([sfcb_init_script, 'stop'])
try:
run_check(['sfcbrepos','-f'])
finally:
if sfcb_running:
run([sfcb_init_script, 'start'])
def run_check(command, *args, **kwargs):
if g_verbose:
po = Popen(command, *args, **kwargs)
output = ''
else:
po = Popen(command, stdout=PIPE, stderr=STDOUT, *args, **kwargs)
output = po.communicate()[0]
rc = po.wait()
if rc != 0:
if isinstance(command, list):
command = ' '.join(command)
err = Error("Error running '%s', returned %s" %(command, rc))
err.last_output = output
raise err
return rc
def run(command, *args, **kwargs):
global g_last_output
if g_verbose:
return call(command, *args, **kwargs)
po = Popen(command, stdout=PIPE, stderr=STDOUT, *args, **kwargs)
output = po.communicate()[0]
rc = po.wait()
if rc != 0:
g_last_output = output
return rc
def process_pegasus(mof, mofcomp, init_script, cimserver_exe, remove=False,
provider_dir=None, env=None):
""" Handle Pegasus
Arguments:
mofs -- list of MOF files
mofcomp -- instance of MOFCompiler
init_script -- Init script for Pegasus
cimserver_exe -- Full path to cimserver executable
remove -- True if we're uninstalling providers / removing schema
"""
peg_running = True
if (run([init_script, 'status']) != 0):
peg_running = False
run_check([cimserver_exe,
'enableIndicationService=false',
'enableHttpsConnection=false',
'enableHttpConnection=false'], env=env)
try:
mofcomp.compile_file(mof, 'root/cimv2')
for reg in peg_regs:
mofcomp.compile_file(reg, 'root/PG_InterOp')
if remove:
mofcomp.rollback(verbose=g_verbose)
finally:
if not peg_running:
run_check([cimserver_exe, '-s'], env=env)
if provider_dir:
try:
insts = mofcomp.handle.instances['root/PG_InterOp']
except KeyError:
insts = []
providers = [inst['Location'] for inst in insts
if inst.classname.lower() == 'pg_providermodule']
providers = list(set(providers))
for reg in peg_regs:
dest = provider_dir + '/' + os.path.basename(reg)
if not dest.endswith('.mof'):
dest += '.mof'
if not remove:
if not os.path.exists(dest):
try:
os.symlink(reg, dest)
except OSError, e:
print e
else:
if os.path.islink(dest):
try:
os.unlink(dest)
except OSError, e:
print e
for provider in providers:
libname = 'lib' + provider + '.so'
src = cmpi_dir + '/' + libname
dest = provider_dir + '/' + libname
if not remove:
if os.path.exists(src) and not os.path.exists(dest):
try:
os.symlink(src, dest)
except OSError, e:
print e
# don't remove, in case the provider is shared with other
# packages (like pyCmpiProvider)
#
#else:
# if os.path.islink(dest):
# try:
# os.unlink(dest)
# except OSError, e:
# print e
def sfcb_installed():
return os.path.exists(sfcb_init_script)
def pegasus_installed():
return os.path.exists(pegasus_init_script) and \
os.path.exists(pegasus_cimserver_exe)
def scx_installed():
return os.path.exists(scx_init_script) and \
os.path.exists(scx_cimserver_exe)
if __name__ == '__main__':
usage = 'usage: %prog [options] -d <Data Dir>'
oparser = OptionParser(usage=usage)
oparser.add_option('-s', '--search', dest='search',
help='Search path to find missing schema elements. This option can be present multiple times.',
metavar='Path', action='append')
oparser.add_option('-n', '--namespace', dest='ns',
help='Specify the namespace', metavar='Namespace',
default='root/cimv2')
oparser.add_option('-u', '--url', dest='url',
help='URL to the CIM Server', metavar='URL')
oparser.add_option('-d', '--dir', dest='dir',
help='Directory containing MOF and registration files',
metavar='Dir')
oparser.add_option('-v', '--verbose',
action='store_true', dest='verbose', default=False,
help='Print more messages to stdout')
oparser.add_option('-r', '--remove',
action='store_true', dest='remove', default=False,
help='Remove elements found in MOF, instead of create them')
oparser.add_option('-x', '--no-restart',
action='store_true', dest='no_restart', default=False,
help="Don't run 'sfcbrepos', don't restart sfcbd")
oparser.add_option('-l', '--username',
dest='username', metavar='Username',
help='Specify the username')
oparser.add_option('-p', '--password',
dest='password', metavar='Password',
help='Specify the password')
oparser.add_option('-g', '--stage',
dest='stage', metavar='SFCB stage',
help='Specify the SFCB stage directory',
default='/var/lib/sfcb/stage')
(options, args) = oparser.parse_args()
try:
if options.dir is None:
oparser.error('No directory given')
options.dir = os.path.abspath(options.dir)
if not os.path.isdir(options.dir):
print 'Error: %s is not a directory' % options.dir
sys.exit(1)
moffile = options.dir + '/deploy.mof'
if not os.path.exists(moffile):
print 'Error: missing file:', moffile
sys.exit(1)
elems = os.listdir(options.dir)
for elem in elems:
if elem.endswith('.sfcb.reg'):
sfcb_regs.append(options.dir + '/' + elem)
elif elem.endswith('.peg.reg'):
peg_regs.append(options.dir + '/' + elem)
g_verbose = options.verbose
g_restart = not options.no_restart
do_sfcb = sfcb_installed() and sfcb_regs
do_pegasus = pegasus_installed() and peg_regs
do_scx = scx_installed() and peg_regs
do_scx = do_scx and (options.url == ':scx:' or not options.url)
do_pegasus = do_pegasus and (options.url == ':tog-pegasus:' or
not options.url)
if do_sfcb:
process_sfcb(moffile, options.stage, options.remove)
search = options.search
if args:
oparser.error('Extra arguments given')
pegs = []
if not pegasus_installed() and options.url == ':tog-pegasus:':
print 'Error: tog-pegasus is not installed'
sys.exit(1)
if not scx_installed() and options.url == ':scx:':
print 'Error: SCX is not installed'
sys.exit(1)
if do_pegasus:
pegs.append({'url':pegasus_unix_socket,
'exe':pegasus_cimserver_exe,
'init':pegasus_init_script,
'provider_dir':None,
'env':None,
})
if do_scx:
env = os.environ.copy()
ldp = '%(h)s/lib:%(h)s/lib/providers:%(h)s/lib/providers/ext' % \
{'h':scx_home}
if 'LD_LIBRARY_PATH' in env and env['LD_LIBRARY_PATH']:
ldp+= ':' + env['LD_LIBRARY_PATH']
env['LD_LIBRARY_PATH'] = ldp
pegs.append({'url':scx_unix_socket,
'exe':scx_cimserver_exe,
'init':scx_init_script,
'provider_dir':scx_ext_dir,
'env':env,
})
if not pegs and options.url:
pegs = [{'url':options.url,
'exe':None,
'init':None,
}]
passwd = options.password
if options.username and not passwd:
passwd = getpass('Enter password for %s: ' % options.username)
if options.username:
creds = (options.username, passwd)
else:
creds = None
if search is None:
search = ['/usr/share/mof/cim-current']
search.append(os.path.abspath(options.dir))
# if removing, we'll be verbose later when we actually remove stuff.
# We don't want MOFCompiler to be verbose, as that would be confusing.
verbose = options.verbose and not options.remove
for peg in pegs:
if options.remove:
conn = pywbem.WBEMConnection(peg['url'], creds)
conn = MOFWBEMConnection(conn=conn)
else:
conn = InstStoringConn(peg['url'], creds)
#conn.debug = True
conn.default_namespace = options.ns
mofcomp = MOFCompiler(handle=conn, search_paths=search, verbose=verbose)
try:
process_pegasus(moffile, mofcomp, peg['init'], peg['exe'],
remove=options.remove, provider_dir=peg['provider_dir'],
env=peg['env'])
except MOFParseError, pe:
sys.exit(1)
except pywbem.CIMError, ce:
sys.exit(1)
except Error, e:
print str(e)
if hasattr(e, 'last_output'):
print e.last_output
sys.exit(1)