Modules development¶
Basics¶
Langage¶
A module can be implemented in any programing langage : shell scripts, python, perl, C, ...
Rules¶
The rules are passed to the modules through environment variables. Advanced langages can use complex serialized variable values like JSON or XML.
Parameters¶
A module must support only one mandatory argument. Its' values can be either
-
check parameter
Verify the rules are applied on the node or service.
-
fixable parameter
Verify the module can apply the rules on the service or node.
-
fix parameter
Apply the rules on the node or service
Return code¶
A module must return one of those three possible values
-
return code 0
Compliance checks or fixes passed.
-
return code 1
Compliance checks or fixes failed.
-
return code 2
Compliance checks or fixes are not applicable. For example when no rules are made available to the module.
Location¶
Modules are installed in <OSVCVAR>/compliance
.
File naming conventions¶
A module can be either a file or a directory tree. The top-level file or directory name must comply to the naming convention:
[S][0-9]+[-]modname
If the module top-level object is a directory, the file tree under it must be either:
[S][0-9]+[-]modname/main
or:
[S][0-9]+[-]modname/scripts/main
Compliance Objects¶
OpenSVC distributes a collection of compliance objects, implemented as executable python classes, to ease module development. They implement common checks and fixes. The skeletons presented below make use of these objects.
Objects take complex serialized rules as input, and the collector implements forms to easily create those rules.
The calling modules have to specify to the object 2 informations:
- The called action : fix, fixable or check
- The variable name prefix the object must care about. The object will search the environment for variables matching this prefix.
Module skeleton¶
Shell script¶
#!/bin/bash
PATH_SCRIPT="$(cd $(/usr/bin/dirname $(type -p -- $0 || echo $0));pwd)"
PATH_LIB=$PATH_SCRIPT/com.opensvc
PREFIX=OSVC_COMP_FOO
typeset -i r=0
case $1 in
check)
$PATH_LIB/files.py ${PREFIX}_FILES check
[ $? -eq 1 ] && r=1
$PATH_LIB/packages.py ${PREFIX}_PKG check
[ $? -eq 1 ] && r=1
exit $r
;;
fix)
$PATH_LIB/files.py ${PREFIX}_FILES check
[ $? -eq 1 ] && exit 1
$PATH_LIB/packages.py ${PREFIX}_PKG check
[ $? -eq 1 ] && exit 1
;;
fixable)
exit 2
;;
esac
Python script¶
#!/usr/bin/env python
import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), 'com.opensvc'))
from comp import *
import files
import packages
syntax = """syntax: %s check|fixable|fix"""%sys.argv[0]
if len(sys.argv) != 2:
print >>sys.stderr, "wrong number of arguments"
print >>sys.stderr, syntax
sys.exit(RET_ERR)
objs = []
try:
o = packages.CompPackages(prefix='OSVC_COMP_BDC_DHCPD_PACKAGE')
objs.append(o)
except NotApplicable:
pass
try:
o = files.CompFiles(prefix='OSVC_COMP_BDC_DHCPD_FILE')
objs.append(o)
except NotApplicable:
pass
def check():
r = 0
for o in objs:
r |= o.check()
return r
def fixable():
return RET_NA
def fix():
r = 0
for o in objs:
r |= o.fix()
return r
try:
if sys.argv[1] == 'check':
RET = check()
elif sys.argv[1] == 'fix':
RET = fix()
elif sys.argv[1] == 'fixable':
RET = fixable()
else:
print >>sys.stderr, "unsupported argument '%s'"%sys.argv[1]
print >>sys.stderr, syntax
RET = RET_ERR
except NotApplicable:
sys.exit(RET_NA)
except:
import traceback
traceback.print_exc()
sys.exit(RET_ERR)
sys.exit(RET)