pax_global_header00006660000000000000000000000064121147774310014521gustar00rootroot0000000000000052 comment=3c95739d6cd3795f8e4e3dc8781b55cb96fe1463 pacemaker-mgmt-pacemaker-mgmt-2.1.2/000077500000000000000000000000001211477743100173055ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/.hgignore000066400000000000000000000124341211477743100211140ustar00rootroot00000000000000syntax: glob # Autofoo entries *.o *.la *.lo *.pyc .libs .deps *.cache .cvsignore compile configure configure.status configure.lineno depcomp aclocal.m4 libtool ltmain.sh ltconfig libltdl mkinstalldirs install-sh missing py-compile autom4te* libtool.m4 ltdl.m4 libltdl.tar autoconf autoheader automake include/ha_version.h include/hb_config.h include/stamp-h1 ylwrap # BEAM Entries *.beam parser-messages MISC_ERRORS cscope.files cscope.out patches updates logs # OS and Editor Artifacts .DS_Store *.diff *.patch *~ # Entries generated by configure cim/mof/register_providers.sh cim/mof/unregister_providers.sh crm/admin/crm_primitive.py crm/admin/cluster cts/LSBDummy cts/*.py doc/cibadmin.8 doc/startstop fencing/test/STONITHDBasicSanityCheck heartbeat.spec heartbeat/init.d/heartbeat heartbeat/lib/BasicSanityCheck heartbeat/lib/ResourceManager heartbeat/lib/TestHeartbeatComm heartbeat/lib/ha_config heartbeat/lib/ha_propagate heartbeat/lib/hb_addnode heartbeat/lib/hb_delnode heartbeat/lib/hb_setsite heartbeat/lib/hb_setweight heartbeat/lib/hb_standby heartbeat/lib/hb_takeover heartbeat/lib/mach_down heartbeat/lib/req_resource heartbeat/rc.d/ask_resources heartbeat/rc.d/hb_takeover heartbeat/shellfuncs include/ha_config.h include/pils/plugin.h include/stamp-h2 ldirectord/init.d/ldirectord ldirectord/ldirectord lib/plugins/stonith/external/ibmrsa lib/plugins/stonith/external/riloe lib/plugins/stonith/external/ssh lib/plugins/stonith/ribcl.py linux-ha/config.h linux-ha/config.h.in linux-ha/stamp-h1 lrm/test/LRMBasicSanityCheck lrm/test/simple_ops mgmt/client/haclient.py mgmt/client/mgmtcmd.py pkg/InfoFiles/pkginfo pkg/InfoFiles/postinstall pkg/InfoFiles/preinstall port/heartbeat/pkg-deinstall port/heartbeat/pkg-descr port/heartbeat/pkg-install port/heartbeat/pkg-plist port/portMakefile resources/OCF/AudibleAlarm resources/OCF/ClusterMon resources/OCF/Delay resources/OCF/Dummy resources/OCF/eDir88 resources/OCF/Evmsd resources/OCF/Filesystem resources/OCF/ICP resources/OCF/IPaddr resources/OCF/IPaddr2 resources/OCF/IPsrcaddr resources/OCF/LVM resources/OCF/LinuxSCSI resources/OCF/MailTo resources/OCF/Pure-FTPd resources/OCF/Raid1 resources/OCF/ServeRAID resources/OCF/Stateful resources/OCF/SysInfo resources/OCF/VIPArip resources/OCF/WAS resources/OCF/WinPopup resources/OCF/Xen resources/OCF/Xinetd resources/OCF/apache resources/OCF/db2 resources/OCF/drbd resources/OCF/ocf-shellfuncs resources/OCF/oracle resources/OCF/oralsnr resources/OCF/pgsql resources/OCF/pingd resources/OCF/portblock resources/OCF/EvmsSCC resources/OCF/ManageRAID resources/OCF/ManageVE resources/OCF/SAPDatabase resources/OCF/SAPInstance resources/OCF/SendArp resources/OCF/WAS6 resources/OCF/mysql resources/OCF/rsyncd resources/heartbeat/AudibleAlarm resources/heartbeat/Delay resources/heartbeat/Filesystem resources/heartbeat/ICP resources/heartbeat/IPaddr resources/heartbeat/IPaddr2 resources/heartbeat/IPsrcaddr resources/heartbeat/IPv6addr resources/heartbeat/LVM resources/heartbeat/LVSSyncDaemonSwap resources/heartbeat/LinuxSCSI resources/heartbeat/MailTo resources/heartbeat/OCF resources/heartbeat/Raid1 resources/heartbeat/SendArp resources/heartbeat/ServeRAID resources/heartbeat/WAS resources/heartbeat/WinPopup resources/heartbeat/Xinetd resources/heartbeat/apache resources/heartbeat/db2 resources/heartbeat/hto-mapfuncs resources/heartbeat/portblock snmp_subagent/SNMPAgentSanityCheck tools/ccdv tools/haresources2cib.py tsa_plugin/linuxha-adapter tsa_plugin/testrun.sh # Project build targets contrib/ipfail/ipfail contrib/mlock/mlock crm/admin/ccm_tool crm/admin/cibadmin crm/admin/crm_attribute crm/admin/crm_diff crm/admin/crm_failcount crm/admin/crm_master crm/admin/crm_mon crm/admin/crm_resource crm/admin/crm_standby crm/admin/crm_uuid crm/admin/crm_verify crm/admin/crmadmin crm/admin/crm_commands.py crm/admin/crm_sh crm/admin/crm_utils.py crm/admin/iso8601 crm/cib/cib crm/cib/cibmon crm/crm.dtd crm/crmd/atest crm/crmd/crmd crm/crmd/fsa_actions_by_state.png crm/crmd/fsa_inputs.png crm/crmd/fsa_inputs_by_action.png crm/pengine/pengine crm/pengine/ptest crm/tengine/tengine crm/tengine/ttest doc/ChangeLog doc/GettingStarted.txt doc/HardwareGuide.txt doc/Requirements.txt doc/crm_resource.8 doc/faqntips.txt doc/heartbeat_api.txt doc/rsync.txt fencing/stonithd/stonithd fencing/test/apitest heartbeat/findif heartbeat/heartbeat heartbeat/libnet_util/send_arp ldirectord/ldirectord.8 lib/clplumbing/base64_md5_test lib/clplumbing/ipctest lib/clplumbing/ipctransientclient lib/clplumbing/ipctransientserver lib/hbclient/api_test lib/stonith/meatclient lib/stonith/stonith logd/ha_logd logd/ha_logger logd/logtest lrm/admin/lrmadmin lrm/lrmd/lrmd lrm/test/apitest lrm/test/callbacktest lrm/test/plugintest membership/ccm/ccm membership/ccm/ccm_testclient membership/ccm/clmtest membership/quorumd/quorumd membership/quorumd/quorumdtest telecom/apphbd/apphbd telecom/apphbd/apphbtest telecom/recoverymgrd/conf_lex.c telecom/recoverymgrd/conf_yacc.c telecom/recoverymgrd/conf_yacc.h telecom/recoverymgrd/recoverymgrd tools/attrd tools/attrd_updater tools/cl_respawn tools/cl_status tools/pingd tools/dopd tools/drbd-peer-outdater lib/mgmt/pymgmt.py lib/mgmt/pymgmt_wrap.c tsa_plugin/ha_mgmt_client_wrap.c # Misc TAGS .gres.* *.orig .gdb_history # Entries better done as regexp's to avoid matching too broadly syntax: regexp ^config\.* README$ Makefile$ Makefile.in$ pacemaker-mgmt-pacemaker-mgmt-2.1.2/ConfigureMe000077500000000000000000000200051211477743100214330ustar00rootroot00000000000000#!/bin/sh # # ConfigureMe: apply appropriate default local configuration options # # Copyright: 2001 Alan Robertson # License: GNU General Public License (GPL) # Usage() { cat <<-! Usage: $0 {configure|make|install|dist|distcheck|package|flags|bootstrap} [--xxx=yyy] $0 is a wrapper to invoke GNU 'configure' with options that match common conventions associated with this machine (i.e. $CFENV) You may also, if you wish, supply additional 'configure' options in their usual '--xxx=yyy' form. It will also build, make, install or create packages for the build environment. $0 does not know how to create packages for every environment, nor is the information on "common conventions" necessarily correct. Patches to this process are solicited -- especially in these areas. ! if [ -x ./configure ] then echo "Legal configure arguments are:" ./configure --help fi exit 1 } # # The vast majority of cases here have not been tested yet... # If you don't think the treatment of your favorite OS is right, # then submit a patch. Some of these conventions were wild guesses... # # autoconf "--enable-XXX" options generally have their default {yes|no} # set, and perhaps acted upon, in "configure.in". # # But we will also allow many of them to take a "try" setting, # interpreted there as: # "try to act as if 'yes' had been specified, but if this proves # troublesome, then continue as if 'no' had been specified". # By using these from here in "ConfigureMe", this allows the beginner # to make rapid, successful progress (albeit suboptimal) with an # implicit sense of achievement, rather than the demoralisation from # an unnecessarily failed 'yes' specification. # (David Lee, 2005) cmd=$0 pathtotop=`dirname ${cmd}` PACKAGECMD="" ConfigureLinux() { DFLAGS="" if [ -f /etc/UnitedLinux-release -a -s /etc/UnitedLinux-release ] then distro="United Linux" PACKAGECMD="$MAKE_CMD rpm" DFLAGS="--with-ucd-snmp-devel=ucdsnmp --with-group-id=90 --with-ccmuser-id=90" elif [ -f /etc/SuSE-release -a -s /etc/SuSE-release ] then distro="SuSE Linux" PACKAGECMD="$MAKE_CMD rpm" # -fno-unit-at-a-time is replaced by -fno-toplevel-reorder in gcc4.2 # But apparently it shouldn't be required # http://www.gnu.org/software/gcc/gcc-4.2/changes.html #export CFLAGS="$CFLAGS -fno-unit-at-a-time" DFLAGS="--with-group-id=90 --with-ccmuser-id=90" R=`cat /etc/SuSE-release | grep 'VERSION *= *' | sed -e 's%.*= *%%'` case $R in [78].*) DFLAGS="$DFLAGS --mandir=/usr/share/man --disable-snmp-subagent --disable-swig --with-ucd-snmp-devel=ucdsnmp";; esac elif [ -f /etc/redhat-release -a -s /etc/redhat-release ] then distro="RedHat Linux" PACKAGECMD="$MAKE_CMD rpm" DFLAGS="--mandir=/usr/share/man" elif [ -f /etc/conectiva-release -a -s /etc/conectiva-release ] then distro="Conectiva Linux" PACKAGECMD="$MAKE_CMD rpm" DFLAGS="--with-group-id=17 --mandir=/usr/share/man --infodir=/usr/share/info --with-ccmuser-id=17" elif [ -f /etc/debian_version -a -s /etc/debian_version ] then distro="Debian GNU/Linux" PACKAGECMD="$MAKE_CMD deb" DFLAGS="--mandir=/usr/share/man" elif [ -f /etc/gentoo-release -a -s /etc/gentoo-release ] then distro="Gentoo Linux" PACKAGECMD="$MAKE_CMD dist" DFLAGS="--with-group-name=cluster --with-ccmuser-name=cluster --with-group-id=65 --with-ccmuser-id=65" else distro="Generic Linux" fi CFENV="$distro" FLAGS="--prefix=/usr --sysconfdir=/etc --localstatedir=/var $DFLAGS --disable-rpath" } ConfigureAIX() { CFENV="AIX (freeware toolbox)" FLAGS="--disable-ldirectord --prefix /opt/freeware" } ConfigureFreeBSD() { FLAGS="--prefix=/usr/local --sysconfdir=/usr/local/etc --localstatedir=/var --enable-all --with-group-id=90 --with-ccmuser-id=90 --disable-rpath" CFENV="FreeBSD" } ConfigureOpenBSD() { FLAGS="--prefix=/usr/local --sysconfdir=/etc --localstatedir=/var --with-group-id=584 --with-ccmuser-id=584 --disable-rpath --with-group-name=_heartbeat --with-ccmuser-name=_heartbeat --with-ocf-root=/usr/local/lib/ocf/ --enable-fatal-warnings=no" export LDFLAGS="-liconv -L/usr/local/lib/libnet-1.0" export LIBNETCONFIG=/usr/local/bin/libnet-config-1.0 export AUTOCONF_VERSION=2.61 CFENV="OpenBSD" } ConfigureNetBSD() { FLAGS="--disable-ldirectord --prefix=/usr/local --sysconfdir=/usr/local/etc --localstatedir=/var --with-group-id=90 --with-ccmuser-id=90 --disable-rpath" CFENV="NetBSD" } ConfigureGenericBSD() { FLAGS="--disable-ldirectord --prefix=/usr/local --sysconfdir=/usr/local/etc --localstatedir=/var --with-group-id=90 --with-ccmuser-id=90 --disable-rpath" CFENV="Generic BSD" } ConfigureSolaris() { # PKGNAME: see comment in "configure.in" PKGNAME="LXHAhb" FLAGS="--disable-ldirectord --prefix=/opt/$PKGNAME --sysconfdir=/etc/opt/$PKGNAME --localstatedir=/var/opt/$PKGNAME --with-pkgname=$PKGNAME --disable-rpath" CFENV="Solaris" PACKAGECMD="$MAKE_CMD pkg" } ConfigureDarwin() { for dir in / /sw /opt/local; do if [ -d $dir ]; then install_prefix=$dir fi done FLAGS="--prefix=${install_prefix}" FLAGS="$FLAGS --with-initdir=/private/etc/mach_init.d" FLAGS="$FLAGS --localstatedir=${install_prefix}/var" FLAGS="$FLAGS --with-group-name=admin --with-ccmuser-name=daemon" FLAGS="$FLAGS --enable-fatal-warnings=yes" FLAGS="$FLAGS --disable-rpath" export CFENV="Darwin" } ConfigureGenericUNIX() { echo "Configuring for generic UNIX system" FLAGS="--disable-ldirectord --prefix=/usr --sysconfdir=/etc --localstatedir=/var" CFENV="Generic UNIX" } lcase() { # Convert to lower-case in a portable way if [ X"`echo A | dd conv=lcase 2>/dev/null`" = Xa ] then dd conv=lcase 2>/dev/null else tr ['A-Z'] ['a-z'] fi } GetConfigureFLAGS() { if [ "X$MAKE" != "X" ] then MAKE_CMD="$MAKE" elif which gmake > /dev/null then MAKE_CMD="gmake" else MAKE_CMD="make" fi case $CROSSCOMPILE in yes) GetCrossConfigureFlags;; *) GetNativeConfigureFlags;; esac } GetNativeConfigureFlags() { case `uname -s | lcase` in linux) ConfigureLinux;; aix) ConfigureAIX;; freebsd) ConfigureFreeBSD;; openbsd) ConfigureOpenBSD;; netbsd) ConfigureOpenBSD;; *bsd) ConfigureGenericBSD;; sunos) ConfigureSolaris;; darwin) ConfigureDarwin;; *) ConfigureGenericUNIX;; esac } GetCrossConfigureFlags() { case $CC in # Don't force endianness on ARM - it can be either type *arm*) FLAGS="--prefix=/usr/local/arm-linux/arm-linux --sysconfdir=/etc --localstatedir=/var";; *) echo "Error: Unsupported cross-compiler: [$CC]"; exit 1;; esac } Run() { echo "Running $@" "$@" } PackageItUp() { if [ "X$PACKAGECMD" = X ] then echo "Do not know how to build a package for $CFENV" >&2 return 1 else Run $PACKAGECMD fi } do_configure () { # Do autotools bootstrap if needed. # Should only be needed by developers and geeks because any # distributed stable versions (tar.gz etc.) should already have # "configure" etc. set up. if [ ! -x ${pathtotop}/configure ] then Run ${pathtotop}/bootstrap "$@" else Run ${pathtotop}/configure "$@" fi } cmd=`echo $1 | lcase` case $cmd in cross-*) CROSSCOMPILE=yes; cmd=`echo $cmd |cut -c7-`;; *) CROSSCOMPILE=no;; esac GetConfigureFLAGS echo "" echo "Configure flags for $CFENV: $FLAGS" >&2 if [ $# -le 0 ] then Usage fi shift case $cmd in flags) echo $FLAGS $@ ;; cf|conf|configure) do_configure $FLAGS $@ ;; boot|bootstrap) rm -f ${pathtotop}/configure do_configure $FLAGS $@ ;; make|build) do_configure $FLAGS $@ && \ Run $MAKE_CMD;; install) do_configure $FLAGS $@ && \ Run $MAKE_CMD install ;; dist) do_configure $FLAGS $@ && \ Run $MAKE_CMD dist ;; distcheck) do_configure $FLAGS $@ && \ source ./heartbeat/lib/ha_config && \ Run $MAKE_CMD DESTDIR="$PWD/heartbeat-$VERSION/=inst" distcheck ;; pkg|package|rpm|deb|dpkg) do_configure $FLAGS $@ && \ PackageItUp ;; *) Usage ;; esac pacemaker-mgmt-pacemaker-mgmt-2.1.2/Makefile.am000066400000000000000000000071171211477743100213470ustar00rootroot00000000000000# # linux-ha: Linux-HA code # # Copyright (C) 2002 Alan Robertson # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # EXTRA_DIST = bootstrap ConfigureMe README.in libltdl.tar AUTOMAKE_OPTIONS = foreign MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure DRF/config-h.in \ DRF/stamp-h.in libtool.m4 ltdl.m4 libltdl.tar coredir = @HA_COREDIR@ hauser = @HA_CCMUSER@ TARFILE = pacemaker-mgmt.tar.gz LAST_RELEASE = pacemaker-mgmt-1.99.2 if CIM_PROVIDER_BUILD CIM_PROVIDER_DIR = cim endif if TSA_PLUGIN_BUILD TSA_PLUGIN_DIR = tsa_plugin endif if SNMP_SUBAGENT_BUILD SNMP_SUBAGENT_DIR = snmp_subagent endif SUBDIRS = $(LIBLTDL_DIR) replace include lib mgmt $(CIM_PROVIDER_DIR) $(TSA_PLUGIN_DIR) $(SNMP_SUBAGENT_DIR) doc if MGMT_CLIENT_BUILD SUBDIRS += po endif tgz: rm -f $(TARFILE) hg archive -t tgz $(TARFILE) echo Rebuilt $(TARFILE) on `date` changes: printf "$(PACKAGE) ($(VERSION)-1) stable; urgency=medium\n" printf " * Update source tarball to revision: `hg id`\n" printf " * Statistics:\n" printf " Changesets: `hg log -M --template "{desc|firstline|strip}\n" -r $(LAST_RELEASE):tip | wc -l`\n" printf " Diff: " hg diff -r $(LAST_RELEASE):tip | diffstat | tail -n 1 # printf "\n * Testing Notes:\n" # printf "\n + Test hardware:\n" # printf "\n + All testing was performed with STONITH enabled\n" # printf "\n + Pending bugs encountered during testing:\n" printf "\n * Changes since $(LAST_RELEASE)\n" # hg log -M --template " + {desc|firstline|strip}\n" -r $(LAST_RELEASE):tip | grep -v Low: | sort -uf hg log -M --template " + {desc|firstline|strip}\n" -r $(LAST_RELEASE):tip | sort -uf printf "\n -- Gao,Yan `date +"%a, %d %b %Y %T %z"`\n" OBS_PROJECT = pacemaker-mgmt OBS_SERVER = c001n16.suse.de OBS_PREFIX = Development/obs OBS_FILES = .changes $(TARFILE) stable: tgz make changes > .changes scp $(OBS_FILES) $(OBS_SERVER):$(OBS_PREFIX)/server:ha-clustering/$(OBS_PROJECT)/ unstable: tgz make changes > .changes scp $(OBS_FILES) $(OBS_SERVER):$(OBS_PREFIX)/server:ha-clustering:UNSTABLE/$(OBS_PROJECT)/ factory: tgz make changes > .changes ssh $(OBS_SERVER) -- 'cd $(OBS_PREFIX)/server:ha-clustering:Factory/$(OBS_PROJECT) ; /usr/bin/osc up' scp $(OBS_FILES) $(OBS_SERVER):$(OBS_PREFIX)/server:ha-clustering:Factory/$(OBS_PROJECT)/ ssh $(OBS_SERVER) -- "cd $(OBS_PREFIX)/server:ha-clustering:Factory/$(OBS_PROJECT); /usr/bin/osc commit -m \"New $(OBS_PROJECT) snapshot - $(shell $(HG) id)\"" install-exec-local: if MGMT_CLIENT_BUILD -mkdir -p $(DESTDIR)$(bindir) -cd $(DESTDIR)$(libdir)/heartbeat-gui && rm -f haclient.py && ln -s $(datadir)/heartbeat-gui/haclient.py . -cd $(DESTDIR)$(bindir) && rm -f crm_gui && ln -s $(datadir)/heartbeat-gui/haclient.py crm_gui -cd $(DESTDIR)$(bindir) && rm -f hb_gui && ln -s $(datadir)/heartbeat-gui/haclient.py hb_gui endif dist-clean-local: rm -f autoconf automake autoheader maintainer-clean-local: rm -f libltdl.tar pacemaker-mgmt-pacemaker-mgmt-2.1.2/README.in000066400000000000000000000022441211477743100205740ustar00rootroot00000000000000Hi, Welcome to the linux-ha project source tree. There is a little documentation on setting things up for a HA failover system in the doc directory. The following things are among the more interesting docs: GettingStarted.html HardwareGuide.html Requirements.html faqntips.html nice_failback.txt rsync.html For building the system: If you have no idea what to do, then you should probably use the ConfigureMe to configure (and make, install, package, etc.) the software. ConfigureMe makes some educated guesses on how linux-ha ought to be installed by default on the current system type. If you have played with autoconf/automake packages before, then you can use the bootstrap script, or configure, etc. like normal. Due to the way that init directories are handled by heartbeat, make distcheck can be problematic. The following should allow this to run successfully, noting that gmake is often available as make: gmake DESTDIR="$PWD/heartbeat-@VERSION@/=inst" distcheck For more information on the project, see the web site at linux-ha.org. Information on joining mailing lists can be found at http://linux-ha.org/contact/ Enjoy! -- The Linux-Ha development team pacemaker-mgmt-pacemaker-mgmt-2.1.2/acinclude.m4000066400000000000000000000023011211477743100214720ustar00rootroot00000000000000dnl dnl local autoconf/automake macros needed for heartbeat dnl Started by David Lee February 2006 dnl dnl License: GNU General Public License (GPL) dnl AM_CHECK_PYTHON_HEADERS: Find location of python include files. dnl Taken from: dnl http://source.macgimp.org/ dnl which is GPL and is attributed to James Henstridge. dnl dnl AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE]) dnl Imports: dnl $PYTHON dnl Exports: dnl PYTHON_INCLUDES AC_DEFUN([AM_CHECK_PYTHON_HEADERS], [AC_REQUIRE([AM_PATH_PYTHON]) AC_MSG_CHECKING(for headers required to compile python extensions) dnl deduce PYTHON_INCLUDES py_prefix=`$PYTHON -c "import sys; print sys.prefix"` py_exec_prefix=`$PYTHON -c "import sys; print sys.exec_prefix"` PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}" if test "$py_prefix" != "$py_exec_prefix"; then PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}" fi AC_SUBST(PYTHON_INCLUDES) dnl check if the headers exist: save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" AC_TRY_CPP([#include ],dnl [AC_MSG_RESULT(found) $1],dnl [AC_MSG_RESULT(not found) $2]) CPPFLAGS="$save_CPPFLAGS" ]) pacemaker-mgmt-pacemaker-mgmt-2.1.2/bootstrap000077500000000000000000000144471211477743100212620ustar00rootroot00000000000000#!/bin/sh # # License: GNU General Public License (GPL) # Copyright 2001 horms # (heavily mangled by alanr) # # bootstrap: set up the project and get it ready to make # # Basically, we run autoconf, automake and libtool in the # right way to get things set up for this environment. # # We also look and see if those tools are installed, and # tell you where to get them if they're not. # # Our goal is to not require dragging along anything # more than we need. If this doesn't work on your system, # (i.e., your /bin/sh is broken) send us a patch. # # This code loosely based on the corresponding named script in # enlightenment, and also on the sort-of-standard autoconf # bootstrap script. # Run this to generate all the initial makefiles, etc. testProgram() { cmd=$1 if [ -z "$cmd" ]; then return 1; fi arch=`uname -s` # Make sure the which is in an if-block... on some platforms it throws exceptions # # The ERR trap is not executed if the failed command is part # of an until or while loop, part of an if statement, part of a && # or || list. if which $cmd /dev/null 2>&1 then : else return 1 fi # The GNU standard is --version if $cmd --version /dev/null 2>&1 then return 0 fi # Maybe it suppports -V instead if $cmd -V /dev/null 2>&1 then return 0 fi # Nope, the program seems broken return 1 } srcdir=`dirname $0` CONFIG=$srcdir/configure if [ X$srcdir = "X" ] then srcdir=. fi case "$*" in --help) IsHelp=yes;; -?) IsHelp=yes; set -- --help;; *) IsHelp=no;; esac arch=`uname -s` # Disable the errors on FreeBSD until a fix can be found. if [ ! "$arch" = "FreeBSD" ]; then set -e # # All errors are fatal from here on out... # The shell will complain and exit on any "uncaught" error code. # # # And the trap will ensure sure some kind of error message comes out. # trap 'echo ""; echo "$0 exiting due to error (sorry!)." >&2' 0 fi HERE=`pwd` cd $srcdir RC=0 gnu="ftp://ftp.gnu.org/pub/gnu" # Check for Autoconf pkg="autoconf" URL=$gnu/$pkg/ for command in autoconf autoconf213 autoconf253 autoconf259 do if testProgram $command == 1 then : OK $pkg is installed autoconf=$command autoheader=`echo "$autoconf" | sed -e 's/autoconf/autoheader/'` autom4te=`echo "$autoconf" | sed -e 's/autoconf/autmo4te/'` autoreconf=`echo "$autoconf" | sed -e 's/autoconf/autoreconf/'` autoscan=`echo "$autoconf" | sed -e 's/autoconf/autoscan/'` autoupdate=`echo "$autoconf" | sed -e 's/autoconf/autoupdate/'` ifnames=`echo "$autoconf" | sed -e 's/autoconf/ifnames/'` fi done # Check to see if we got a valid command. if $autoconf --version /dev/null 2>&1 then echo "Autoconf package $autoconf found." else RC=$? cat <<-!EOF >&2 You must have $pkg installed to compile the linux-ha package. Download the appropriate package for your system, or get the source tarball at: $URL !EOF fi # Create local copy so that the incremental updates will work. rm -f ./autoconf ln -s `which $autoconf` ./autoconf # Check for automake pkg="automake" URL=$gnu/$pkg/ for command in automake automake14 automake-1.4 automake15 automake-1.5 automake17 automake-1.7 automake19 automake-1.9 do if testProgram $command then : OK $pkg is installed automake=$command aclocal=`echo "$automake" | sed -e 's/automake/aclocal/'` fi done # Check to see if we got a valid command. if $automake --version /dev/null 2>&1 then echo "Automake package $automake found." else RC=$? cat <<-!EOF >&2 You must have $pkg installed to compile the linux-ha package. Download the appropriate package for your system, or get the source tarball at: $URL !EOF fi # Create local copy so that the incremental updates will work. rm -f ./automake ln -s `which $automake` ./automake # Check for Libtool pkg="libtool" for command in libtool libtool14 libtool15 glibtool do URL=$gnu/$pkg/ if testProgram $command then : OK $pkg is installed libtool=$command libtoolize=`echo "$libtool" | sed -e 's/libtool/libtoolize/'` fi done # Check to see if we got a valid command. if $libtool --version /dev/null 2>&1 then echo "Libtool package $libtool found." else RC=$? cat <<-!EOF >&2 You must have $pkg installed to compile the linux-ha package. Download the appropriate package for your system, or get the source tarball at: $URL !EOF fi # Create local copy so that the incremental updates will work. rm -f ./libtool ln -s `which $libtool` ./libtool case $RC in 0) ;; *) exit $RC;; esac case $IsHelp in yes) $CONFIG "$@"; trap '' 0; exit 0;; esac if [ $# -lt 1 ] then cat <<-! Running $CONFIG with no arguments. If you wish to pass any arguments to $CONFIG please specify them on the $0 command line. ! fi oneline() { read x; echo "$x" } LT_version=`$libtool --version | oneline | sed -e 's%^[^0-9]*%%' -e s'% .*%%'` LT_majvers=`echo "$LT_version" | sed -e 's%\..*%%'` LT_minvers=`echo "$LT_version" | sed -e 's%^[^.]*\.%%' ` LT_minnum=`echo "$LT_minvers" | sed -e 's%[^0-9].*%%'` if [ $LT_majvers -lt 1 ] || [ $LT_majvers -eq 1 -a $LT_minnum -lt 4 ] then echo "Minimum version of libtool is 1.4. You have $LT_version installed." exit 1 fi echo $aclocal $ACLOCAL_FLAGS $aclocal $ACLOCAL_FLAGS # Create local copy so that the incremental updates will work. rm -f ./autoheader ln -s `which $autoheader` ./autoheader if echo $autoheader --version < /dev/null > /dev/null 2>&1 $autoheader --version < /dev/null > /dev/null 2>&1 then echo $autoheader $autoheader fi rm -rf libltdl libltdl.tar echo $libtoolize --ltdl --force --copy $libtoolize --ltdl --force --copy echo $aclocal $ACLOCAL_FLAGS $aclocal $ACLOCAL_FLAGS # Emulate the old --ltdl-tar option... # If the libltdl directory is required we will unpack it later tar -cf libltdl.tar libltdl rm -rf libltdl echo $automake --add-missing --include-deps --copy $automake --add-missing --include-deps --copy echo $autoconf $autoconf test -f libtool.m4 || touch libtool.m4 test -f ltdl.m4 || touch ltdl.m4 cd $HERE echo $CONFIG "$@" $CONFIG "$@" echo "Now type 'gmake' to compile the system, noting that" echo "'gmake' is often available as 'make'." echo trap '' 0 pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/000077500000000000000000000000001211477743100200555ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/.cvsignore000066400000000000000000000000711211477743100220530ustar00rootroot00000000000000Makefile.in Makefile .deps .libs *.la *.lo .*.swp *.beam pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/Makefile.am000066400000000000000000000206611211477743100221160ustar00rootroot00000000000000# Linux-HA: CIM Provider # # Author: Jia Ming Pan # Copyright (c) 2005 International Business Machines # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in # Subdirectories SUBDIRS = mof CMPIHEADERS = $(CMPI_HEADER_PATH) INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_builddir)/linux-ha -I$(top_srcdir)/linux-ha \ -I$(top_builddir)/libltdl -I$(top_srcdir)/libltdl \ -I$(CMPI_HEADER_PATH) COMMONLIBS = $(top_builddir)/lib/clplumbing/libplumb.la \ $(top_builddir)/lib/hbclient/libhbclient.la \ $(top_builddir)/membership/ccm/libccmclient.la \ $(top_builddir)/membership/ccm/libclm.la \ $(GLIBLIB) #using pthread, or gthread? #THREADLIB = `pkg-config --libs gthread-2.0` THREADLIB = lpthread cimprovidersdir = $(CMPI_PROVIDER_DIR) noinst_HEADERS = cluster_info.h cmpi_utils.h mof_map.h\ resource_common.h constraint_common.h LRM_DIR = lrm MGMTLIBS = $(top_builddir)/mgmt/daemon/libhbmgmt.la \ $(top_builddir)/lib/mgmt/libhbmgmtcommon.la \ $(top_builddir)/lib/$(LRM_DIR)/liblrm.la cimproviders_LTLIBRARIES = libHAClusterInfo.la \ libHA_ClusterProvider.la \ libHA_ClusterNodeProvider.la \ libHA_ParticipatingNodeProvider.la \ libHA_SoftwareIdentityProvider.la \ libHA_InstalledSoftwareIdentityProvider.la \ libHA_PrimitiveResourceProvider.la \ libHA_ResourceCloneProvider.la \ libHA_MasterSlaveResourceProvider.la \ libHA_ResourceGroupProvider.la \ libHA_SubResourceProvider.la \ libHA_OperationProvider.la \ libHA_OperationOnProvider.la \ libHA_HostedResourceProvider.la \ libHA_LocationConstraintProvider.la \ libHA_ColocationConstraintProvider.la \ libHA_OrderConstraintProvider.la \ libHA_IndicationProvider.la \ libHA_ClusteringServiceProvider.la \ libHA_InstanceAttributesProvider.la \ libHA_AttributesOfResourceProvider.la \ libHA_LocationConstraintRuleProvider.la \ libHA_RuleOfLocationConstraintProvider.la #-------------------------------------------------------------- libHAClusterInfo_la_SOURCES = mgmt_client.c utils.c \ cluster_info.c cmpi_utils.c mof_map.c libHAClusterInfo_la_LIBADD = $(COMMONLIBS) $(MGMTLIBS) #-------------------------------------------------------------- libHA_ClusterProvider_la_SOURCES = cluster_provider.c libHA_ClusterProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_SoftwareIdentityProvider_la_SOURCES = software_identity_provider.c libHA_SoftwareIdentityProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_ClusterNodeProvider_la_SOURCES = cluster_node_provider.c libHA_ClusterNodeProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_PrimitiveResourceProvider_la_SOURCES = resource_common.c primitive_resource_provider.c libHA_PrimitiveResourceProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_ResourceCloneProvider_la_SOURCES = resource_common.c resource_clone_provider.c libHA_ResourceCloneProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_MasterSlaveResourceProvider_la_SOURCES= resource_common.c masterslave_resource_provider.c libHA_MasterSlaveResourceProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_ResourceGroupProvider_la_SOURCES = resource_common.c resource_group_provider.c libHA_ResourceGroupProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_ParticipatingNodeProvider_la_SOURCES = participating_node_provider.c libHA_ParticipatingNodeProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_HostedResourceProvider_la_SOURCES = hosted_resource_provider.c libHA_HostedResourceProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_InstalledSoftwareIdentityProvider_la_SOURCES = installed_software_provider.c libHA_InstalledSoftwareIdentityProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_AttributesOfResourceProvider_la_SOURCES = attrs_of_resource_provider.c libHA_AttributesOfResourceProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_InstanceAttributesProvider_la_SOURCES = instance_attrs_provider.c libHA_InstanceAttributesProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_SubResourceProvider_la_SOURCES = subresource_provider.c libHA_SubResourceProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_OperationProvider_la_SOURCES = operation_provider.c libHA_OperationProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_LocationConstraintProvider_la_SOURCES = constraint_common.c location_constraint_provider.c libHA_LocationConstraintProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_ColocationConstraintProvider_la_SOURCES = constraint_common.c colocation_constraint_provider.c libHA_ColocationConstraintProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_OrderConstraintProvider_la_SOURCES = constraint_common.c order_constraint_provider.c libHA_OrderConstraintProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_IndicationProvider_la_SOURCES = cluster_indication_provider.c libHA_IndicationProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_OperationOnProvider_la_SOURCES = operation_on_provider.c libHA_OperationOnProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_ClusteringServiceProvider_la_SOURCES = clustering_service_provider.c libHA_ClusteringServiceProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_LocationConstraintRuleProvider_la_SOURCES = constraint_common.c constraint_rule_provider.c libHA_LocationConstraintRuleProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- libHA_RuleOfLocationConstraintProvider_la_SOURCES = rule_of_constraint_provider.c libHA_RuleOfLocationConstraintProvider_la_LIBADD = libHAClusterInfo.la #-------------------------------------------------------------- noinst_PROGRAMS = simpletest simpletest_SOURCES = simple_test.c simpletest_LDADD = libHAClusterInfo.la pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/attrs_of_resource_provider.c000066400000000000000000000223721211477743100256710ustar00rootroot00000000000000/* * attributes_of_resource.c: HA_AttributesOfResource Provider * * Author: Jia Ming Pan * Copyright (c) 2006 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include "cluster_info.h" #include "cmpi_utils.h" static const char * PROVIDER_ID = "cim-attrof"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_AttributesOfResource"; static char Left [] = "Resource"; static char Right [] = "InstanceAttributes"; static char LeftClassName [] = "HA_PrimitiveResource"; static char RightClassName [] = "HA_InstanceAttributes"; DeclareInstanceFunctions (AttributesOfResource); DeclareAssociationFunctions(AttributesOfResource); static int resource_has_attr(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIObjectPath * rscop, CMPIObjectPath * attrop, CMPIStatus * rc) { char *rscid, *nvrscid = NULL; rscid = CMGetKeyString(rscop, "Id", rc); nvrscid = CMGetKeyString(attrop, "ResourceId", rc); if ( strncmp(rscid, nvrscid, MAXLEN) == 0 ) { return TRUE; } return FALSE; } /********************************************** * Instance **********************************************/ static CMPIStatus AttributesOfResourceCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus AttributesOfResourceEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "AttributesOf: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_enum_insts(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, resource_has_attr, NULL, FALSE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus AttributesOfResourceEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "AttributesOf: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_enum_insts(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, resource_has_attr, NULL, TRUE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus AttributesOfResourceGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "AttributesOf: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_get_inst(Broker, ClassName, ctx, rslt, cop, Left, Right, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus AttributesOfResourceCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus AttributesOfResourceSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "AttributesOf: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus AttributesOfResourceDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; return rc; } static CMPIStatus AttributesOfResourceExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /**************************************************** * Association ****************************************************/ static CMPIStatus AttributesOfResourceAssociationCleanup(CMPIAssociationMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus AttributesOfResourceAssociators(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * assoc_class, const char * result_class, const char * role, const char * result_role, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "AttributesOf: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_enum_associators(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, assoc_class, result_class, role, result_role, resource_has_attr, NULL, TRUE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus AttributesOfResourceAssociatorNames(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * assoc_class, const char * result_class, const char * role, const char * result_role) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "AttributesOf: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_enum_associators(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, assoc_class, result_class, role, result_role, resource_has_attr, NULL, FALSE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus AttributesOfResourceReferences(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * result_class, const char * role, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "AttributesOf: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if ( assoc_enum_references(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, result_class, role, NULL, NULL, TRUE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus AttributesOfResourceReferenceNames(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * result_class, const char * role) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "AttributesOf: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if ( assoc_enum_references(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, result_class, role, resource_has_attr, NULL, FALSE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } /************************************************************** * MI stub *************************************************************/ DeclareInstanceMI (AttributesOfResource, HA_AttributesOfResourceProvider, Broker); DeclareAssociationMI(AttributesOfResource, HA_AttributesOfResourceProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/cluster_indication_provider.c000066400000000000000000000260051211477743100260200ustar00rootroot00000000000000/* * cluster_indication_provider.c: HA_Indication provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include "cluster_info.h" #include "cmpi_utils.h" struct cmpi_ind_env { char * classname; CMPIBroker * broker; CMPIContext * context; CMPIString * filter; }; enum ind_type { IND_TYPE_CLUSTER = 0, /* cluster-type indicatoin */ IND_TYPE_NODE, /* node-type indication */ IND_TYPE_MEMBERSHIP, /* membership-type indication */ IND_TYPE_RESOURCE, /* resource-type indication */ IND_TYPE_CRM, IND_TYPE_UNKNOWN }; struct cmpi_ind_data { const char * message; /* indication message */ enum ind_type type; /* type */ }; #define PROVIDER_ID "cim-ind" /* #define HB_CLIENT_ID "cmpi_indication" */ #define HB_CLIENT_ID NULL #define IND_NAMESPACE "root/cimv2" #define DEFAULT_TIME_OUT 5 static char G_classname [] = "HA_Indication"; static CMPIBroker * G_broker = NULL; static int ind_enabled = 0; static struct cmpi_ind_env * ind_env = NULL; static pthread_t ind_thread_id = 0; static GMainLoop * G_mainloop = NULL; static int ind_event_handler(const char * event); static int ind_generate_indication (void * data); static void ind_stop_thread(int ano); static int ind_main_loop (void); static void * ind_thread_func(void * param); static int haind_activate(CMPIContext * ctx, CMPIResult * rslt, CMPISelectExp * filter, const char * type, CMPIObjectPath * classpath, CMPIBoolean firstactivation, CMPIStatus * rc); static int haind_deactivate(CMPIContext * ctx, CMPIResult * rslt, CMPISelectExp * filter, const char * type, CMPIObjectPath * classpath, CMPIBoolean lastactivation, CMPIStatus * rc); DeclareIndicationFunctions(Indication); static int ind_generate_indication (void * data) { CMPIInstance * instance = NULL; CMPIObjectPath * op = NULL; CMPIStatus rc; CMPIDateTime * date_time = NULL; struct cmpi_ind_data * ind_data = NULL; char msg[128]; ind_data = (struct cmpi_ind_data *) data; cl_log(LOG_INFO, "%s: status changed, genereate indication.", __FUNCTION__); ASSERT(ind_env); /* create indication instance and set properties */ op = CMNewObjectPath(ind_env->broker, IND_NAMESPACE, ind_env->classname, &rc); instance = CMNewInstance(ind_env->broker, op, &rc); date_time = CMNewDateTime(ind_env->broker, &rc); snprintf(msg, 128, "%s", ind_data->message); CMSetProperty(instance, "Message", msg, CMPI_chars); CMSetProperty(instance, "Time", &date_time, CMPI_dateTime); CMSetProperty(instance, "Type", &ind_data->type, CMPI_uint16); /* deliver indication */ cl_log(LOG_INFO, "%s: deliver indication", __FUNCTION__); CBDeliverIndication(ind_env->broker, ind_env->context, IND_NAMESPACE, instance); return HA_OK; } static int ind_event_handler(const char * event) { struct cmpi_ind_data data ; char msg[256]; if ( event == NULL ) { return HA_FAIL; } cl_log(LOG_INFO, "ind_event_handler: got event: %s", event); snprintf(msg, 256, "Got an indication: %s", event); data.type = IND_TYPE_CRM; data.message = msg; return ind_generate_indication(&data); } static int ind_disconnected_handler(const char * event) { struct cmpi_ind_data data; cl_log(LOG_INFO, "heartbeat disconnected"); data.type = IND_TYPE_CLUSTER; data.message = "Heartbeat disconnected"; ind_generate_indication(&data); ind_stop_thread(11); return HA_OK; } static void ind_stop_thread(int a) { if ( G_mainloop && g_main_is_running(G_mainloop)) { g_main_quit(G_mainloop); } } static void * ind_thread_func(void * param) { /* attach thread */ CBAttachThread(ind_env->broker, ind_env->context); signal(SIGTERM, ind_stop_thread); signal(SIGINT, ind_stop_thread); /* main loop */ ind_main_loop(); /* detach thread */ CBDetachThread(ind_env->broker, ind_env->context); cim_free(ind_env); return NULL; } static int ind_main_loop () { G_mainloop = g_main_new(FALSE); if ( G_mainloop == NULL ) { cl_log(LOG_ERR, "ind_main_loop: couldn't creat mainloop"); return HA_FAIL; } g_main_run(G_mainloop); return HA_OK; } /***************************************************************** * interface ****************************************************************/ static int haind_activate(CMPIContext * ctx, CMPIResult * rslt, CMPISelectExp * filter, const char * type, CMPIObjectPath * classpath, CMPIBoolean firstactivation, CMPIStatus * rc) { pthread_attr_t tattr; PROVIDER_INIT_LOGGER(); if ( (ind_env = (struct cmpi_ind_env *) cim_malloc(sizeof(struct cmpi_ind_env)) ) == NULL ) { cl_log(LOG_ERR, "%s: could not alloc ind_env", __FUNCTION__); return HA_FAIL; } ind_env->broker = G_broker; ind_env->context = ctx; ind_env->filter = CMGetSelExpString(filter, rc); ind_env->classname = G_classname; /* set event hooks, noly one hook for each event currently */ reg_event(EVT_CIB_CHANGED, ind_event_handler); reg_event(EVT_DISCONNECTED, ind_disconnected_handler); pthread_attr_init(&tattr); pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); /* should use broker->xft->newThread(...) ? */ CBPrepareAttachThread(G_broker, ctx); pthread_create(&ind_thread_id, &tattr, ind_thread_func, NULL); return HA_OK; } static int haind_deactivate(CMPIContext * ctx, CMPIResult * rslt, CMPISelectExp * filter, const char * type, CMPIObjectPath * classpath, CMPIBoolean lastactivation, CMPIStatus * rc) { /* destroy the indication thread */ ind_stop_thread(1) ; cim_free (ind_env); return HA_OK; } /************************************************** * Indication Interface *************************************************/ static CMPIStatus IndicationIndicationCleanup(CMPIIndicationMI * mi, CMPIContext * ctx) { PROVIDER_INIT_LOGGER(); CMReturn(CMPI_RC_OK); } static CMPIStatus IndicationAuthorizeFilter(CMPIIndicationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPISelectExp * filter, const char * type, CMPIObjectPath * classPath, const char * owner) { CMPIBoolean authorized = 1; char * filter_str = NULL; CMPIStatus rc; PROVIDER_INIT_LOGGER(); filter_str = CMGetCharPtr( CMGetSelExpString(filter, &rc) ); cl_log(LOG_INFO, "%s: eventype = %s, filter = %s", __FUNCTION__,type, filter_str); CMReturnData(rslt, (CMPIValue *)&authorized, CMPI_boolean); CMReturnDone(rslt); CMReturn(CMPI_RC_OK); } static CMPIStatus IndicationMustPoll(CMPIIndicationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPISelectExp * filter, const char * indType, CMPIObjectPath * classPath) { CMPIStatus rc = {CMPI_RC_ERR_NOT_SUPPORTED, NULL}; CMPIBoolean poll = 0; char * filter_str = NULL; PROVIDER_INIT_LOGGER(); filter_str = CMGetCharPtr( CMGetSelExpString(filter, &rc) ); cl_log(LOG_INFO, "%s: eventype = %s, filter = %s", __FUNCTION__, indType, filter_str); cl_log(LOG_INFO, "%s: does not suppot poll", __FUNCTION__); CMReturnData(rslt, (CMPIValue *)&poll, CMPI_boolean); CMReturnDone(rslt); return rc; } static CMPIStatus IndicationActivateFilter(CMPIIndicationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPISelectExp * filter, const char * type, CMPIObjectPath * classPath, CMPIBoolean firstActivation) { CMPIBoolean activated = 1; CMPIStatus rc; PROVIDER_INIT_LOGGER(); if ( haind_activate(ctx, rslt, filter, type, classPath, firstActivation, &rc) == HA_OK ) { CMReturnData(rslt, (CMPIValue *)&activated, CMPI_boolean); CMReturnDone(rslt); CMReturn(CMPI_RC_OK); } else { CMReturnDone(rslt); CMReturn(CMPI_RC_ERR_FAILED); } } static CMPIStatus IndicationDeActivateFilter(CMPIIndicationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPISelectExp * filter, const char * type, CMPIObjectPath * classPath, CMPIBoolean lastActivation) { CMPIBoolean deactivated = 1; CMPIStatus rc; PROVIDER_INIT_LOGGER(); if ( haind_deactivate(ctx, rslt, filter, type, classPath, lastActivation, &rc) == HA_OK ) { CMReturnData(rslt, (CMPIValue *)&deactivated, CMPI_boolean); CMReturnDone(rslt); CMReturn(CMPI_RC_OK); } else { CMReturnDone(rslt); CMReturn(CMPI_RC_ERR_FAILED); } } static void IndicationEnableIndications(CMPIIndicationMI * mi ) { /* Enable indication generation */ ind_enabled = 1; } static void IndicationDisableIndications(CMPIIndicationMI * mi ) { /* Disable indication generation */ ind_enabled = 0; } /***************************************************** * Indication ****************************************************/ DeclareIndicationMI(Indication, HA_IndicationProvider, G_broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/cluster_info.c000066400000000000000000001346721211477743100227320ustar00rootroot00000000000000 /* * cluster_info.c * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cluster_info.h" #include "mof_map.h" /*FIXME: remove hardcode path */ #define CLIHB "/etc/init.d/heartbeat" #define CONFIG_FILENAME HA_HBCONF_DIR"/ha.cf" #define BACKUP_CONFIG_NAME CONFIG_NAME".bak" #define BACKUP_KEYFILE KEYFILE".bak" #define CONFIG_COMMENT \ "#This file was generated by provider\n\n\n" #define CIM_RSCNAME_TABLE "resource_name_table" #define CIM_RSCTYPE_TABLE "resource_type_table" #define CIM_RSCOPS_TABLE "resource_operations" #define CIM_RSCATTRS_TABLE "resource_attrubtes_table" #define CIM_SUBRSC_NAME_TABLE "subresource_name_table" #define CIM_RESOURCE_TABLE "resource_table" typedef struct FunContext_s { int func_id; /* function name */ const char * cmnd[8]; /* mgmt cmnds */ const char * pattern_exp; int (*handle_func)(MClient*, void*, const struct FunContext_s*, void*); } FunContext; #define MSG_MAX_DEPTH 2 struct msg_pattern_t { char ** keys[MSG_MAX_DEPTH]; /* keys of nodes*/ int len[MSG_MAX_DEPTH]; /* keys length of each node */ char * tag[MSG_MAX_DEPTH]; /* description for each node */ int depth; /* message depth */ }; static int node_return(MClient*, void*, const FunContext*, void*); static int list_return(MClient*, void*, const FunContext*, void*); static int node_update(MClient*, void*, const FunContext*, void*); static struct msg_pattern_t * msg_pattern_parse(const char *pattern); static void msg_pattern_free(void*); static int InsertOption(struct ha_msg*, const char *, const char * option); static int StrIsEmpty(const char * str); static int cib_changed(void); static int cim_rsctype_s2tid(const char * rsctype); static const char* cim_rsctype_tid2s(int rsctype); #define cim_rscname_table_keys() cim_dbkeys(CIM_RSCNAME_TABLE) #define cim_rscname_table_add(rscid) \ cim_dbput(CIM_RSCNAME_TABLE, rscid, "disabled") #define cim_rscname_table_del(rscid) \ cim_dbdel(CIM_RSCNAME_TABLE, rscid) #define cim_rscname_table_get(rscid) \ cim_dbget(CIM_RSCNAME_TABLE, rscid) #define cim_rsctype_table_add(rscid,type) cim_dbput(CIM_RSCTYPE_TABLE, rscid, type) #define cim_rsctype_table_del( rscid) cim_dbdel(CIM_RSCTYPE_TABLE, rscid) #define STR_CONS_ORDER "rsc_order" #define STR_CONS_LOCATION "rsc_location" #define STR_CONS_COLOCATION "rsc_colocation" /* description: return CRM configuration format: MSG_CRM_CONFIG return: MSG_OK transition_idle_timeout symmetric_cluster(True|False) stonith_enabled(True|False) no_quorum_policy(freeze|stop|ignore) default_resource_stickiness have_quorum(True|False) or MSG_FAIL */ #define BEGIN_NODE "{" #define END_NODE "}" #define BEGIN_NODE_CHAR '{' #define END_NODE_CHAR '}' #define BEGIN_KEY "(" #define END_KEY ")" #define BEGIN_KEY_CHAR '(' #define END_KEY_CHAR ')' #define REPEATE "?" #define ANYTIMES "*" #define REPEATE_CHAR '?' #define ANYTIMES_CHAR '*' #define MAXTIMES 999 static const char crm_config [] = BEGIN_NODE "crm_config" BEGIN_KEY "transition_idle_timeout" END_KEY BEGIN_KEY "symmetric_cluster" END_KEY BEGIN_KEY "stonith_enabled" END_KEY BEGIN_KEY "no_quorum_policy" END_KEY BEGIN_KEY "default_resource_stickiness" END_KEY BEGIN_KEY "have_quorum" END_KEY END_NODE; /* format: MSG_HB_CONFIG return: MSG_OK apiauth auto_failback baud debug debugfile deadping deadtime hbversion hopfudge initdead keepalive logfacility logfile msgfmt nice_failback node normalpoll stonith udpport warntime watchdog or MSG_FAIL */ static const char hb_config [] = BEGIN_NODE "hb_config" BEGIN_KEY "apiauth" END_KEY BEGIN_KEY "auto_failback" END_KEY BEGIN_KEY "baud" END_KEY BEGIN_KEY "debug" END_KEY BEGIN_KEY "debugfile" END_KEY BEGIN_KEY "deadping" END_KEY BEGIN_KEY "deadtime" END_KEY BEGIN_KEY "hbversion" END_KEY BEGIN_KEY "hopfudge" END_KEY BEGIN_KEY "initdead" END_KEY BEGIN_KEY "keepalive" END_KEY BEGIN_KEY "logfacility" END_KEY BEGIN_KEY "logfile" END_KEY BEGIN_KEY "msgfmt" END_KEY BEGIN_KEY "nice_failback" END_KEY BEGIN_KEY "node" END_KEY BEGIN_KEY "normalpoll" END_KEY BEGIN_KEY "stonith" END_KEY BEGIN_KEY "updport" END_KEY BEGIN_KEY "warntime" END_KEY BEGIN_KEY "watchdog" END_KEY END_NODE; /* MSG_NODE_CONFIG NODENAME return: MSG_OK uname online(True|False) standbyTrue|False) unclean(True|False) shutdown(True|False) expected_up(True|False) is_dc(True|False) node_ping("ping|member") */ static const char node_info [] = BEGIN_NODE BEGIN_KEY "uname" END_KEY BEGIN_KEY "online" END_KEY BEGIN_KEY "standby" END_KEY BEGIN_KEY "unclean" END_KEY BEGIN_KEY "shutdown" END_KEY BEGIN_KEY "expected_up" END_KEY BEGIN_KEY "is_dc" END_KEY BEGIN_KEY "node_ping" END_KEY END_NODE; /* description: return the operations of a given resource format: MSG_RSC_OPS resource return: MSG_OK id1 name1 interval1 timeout1 id2 name2 interval2 timeout2 ... idn namen intervaln timeoutn or MSG_FAIL */ static const char operations [] = BEGIN_NODE "operations" BEGIN_NODE "op" REPEATE ANYTIMES BEGIN_KEY "id" END_KEY BEGIN_KEY "name" END_KEY BEGIN_KEY "interval" END_KEY BEGIN_KEY "timeout" END_KEY END_NODE END_NODE; static const char attributes []= BEGIN_NODE CIM_MSG_INST_ATTR BEGIN_NODE CIM_MSG_ATTR REPEATE ANYTIMES BEGIN_KEY "id" END_KEY BEGIN_KEY "name" END_KEY BEGIN_KEY "value" END_KEY END_NODE END_NODE; static const char primitive []= BEGIN_NODE "primitive" BEGIN_KEY "id" END_KEY BEGIN_KEY "class" END_KEY BEGIN_KEY "provider" END_KEY BEGIN_KEY "type" END_KEY END_NODE; static const char clone [] = BEGIN_NODE "clone" BEGIN_KEY "id" END_KEY BEGIN_KEY "clone_max" END_KEY BEGIN_KEY "clone_node_max" END_KEY END_NODE; static const char master []= BEGIN_NODE "master_slave" BEGIN_KEY "id" END_KEY BEGIN_KEY "clone_max" END_KEY BEGIN_KEY "clone_node_max" END_KEY BEGIN_KEY "master_max" END_KEY BEGIN_KEY "master_node_max" END_KEY END_NODE; static const char order_constraint [] = BEGIN_NODE "rsc_order" BEGIN_KEY "id" END_KEY BEGIN_KEY "from" END_KEY BEGIN_KEY "type" END_KEY BEGIN_KEY "to" END_KEY END_NODE; static const char co_constraint[] = BEGIN_NODE "rsc_colocation" BEGIN_KEY "id" END_KEY BEGIN_KEY "from" END_KEY BEGIN_KEY "to" END_KEY BEGIN_KEY "score" END_KEY END_NODE; /* rsc_location: MSG_OK id resource score expr_id1 attribute1 operation1 value1 expr_id2 attribute2 operation2 value2 ... expr_idn attributen operationn valuen */ static const char location_constraint[] = BEGIN_NODE "rsc_location" BEGIN_KEY "id" END_KEY BEGIN_KEY "resource" END_KEY BEGIN_KEY "score" END_KEY BEGIN_NODE "rule" REPEATE ANYTIMES /* constraint rule */ BEGIN_KEY "id" END_KEY BEGIN_KEY "attribute" END_KEY BEGIN_KEY "operation" END_KEY BEGIN_KEY "value" END_KEY END_NODE END_NODE; #define A_1(a) {a,NULL} #define A_2(a,b) {a,b,NULL} #define A_3(a,b,c) {a,b,c,NULL} #define A_4(a,b,c,d) {a,b,c,d,NULL} #define A_5(a,b,c,d,e) {a,b,c,d,e,NULL} static const FunContext query_ctx_table [] = { /* cluster */ {GET_CRM_CONFIG,A_1(MSG_CRM_CONFIG), crm_config, node_return}, {GET_HB_CONFIG, A_1(MSG_HB_CONFIG), hb_config, node_return}, {GET_DC, A_1(MSG_DC), "{(dc)}", node_return}, {GET_NODE_INFO, A_1(MSG_NODE_CONFIG),node_info, node_return}, {GET_NODE_LIST, A_1(MSG_ALLNODES), NULL, list_return}, /* resource */ {GET_RSC_OPERATIONS, A_1(MSG_RSC_OPS), operations, node_return}, {GET_RSC_ATTRIBUTES, A_1(MSG_RSC_PARAMS),attributes, node_return}, {GET_RSC_TYPE, A_1(MSG_RSC_TYPE), "{(type)}", node_return}, {GET_PRIMITIVE, A_1(MSG_RSC_ATTRS), primitive, node_return}, {GET_CLONE, A_1(MSG_GET_CLONE), clone, node_return}, {GET_MASTER, A_1(MSG_GET_MASTER), master, node_return}, {GET_SUB_RSC, A_1(MSG_SUB_RSC), NULL, list_return}, {GET_RSC_LIST, A_1(MSG_ALL_RSC), NULL, list_return}, {GET_RSC_HOST, A_1(MSG_RSC_RUNNING_ON), "{(host)}", node_return}, {GET_RSC_STATUS,A_1(MSG_RSC_STATUS), "{(status)}", node_return}, /* metadata */ {GET_RSC_CLASSES, A_1(MSG_RSC_CLASSES), NULL, list_return}, {GET_RSC_TYPES, A_1(MSG_RSC_TYPE), NULL, list_return}, {GET_RSC_PROVIDERS, A_1(MSG_RSC_PROVIDERS), NULL, list_return}, /* constaint */ {GET_ORDER_CONSTRAINT, A_2(MSG_GET_CONSTRAINT, STR_CONS_ORDER), order_constraint, node_return }, {GET_LOCATION_CONSTRAINT, A_2(MSG_GET_CONSTRAINT, STR_CONS_LOCATION), location_constraint, node_return }, {GET_COLOCATION_CONSTRAINT, A_2(MSG_GET_CONSTRAINT,STR_CONS_COLOCATION), co_constraint, node_return }, {GET_ORDER_CONS_LIST, A_2(MSG_GET_CONSTRAINTS, STR_CONS_ORDER), NULL, list_return }, {GET_LOCATION_CONS_LIST, A_2(MSG_GET_CONSTRAINTS, STR_CONS_LOCATION), NULL, list_return }, {GET_COLOCATION_CONS_LIST, A_2(MSG_GET_CONSTRAINTS,STR_CONS_COLOCATION), NULL, list_return } }; /* description: add a new resource format: MSGA_DD_RSC rsc_id rsc_class rsc_type rsc_provider group("" for NONE) advance(""|"clone"|"master") advance_id clone_max clone_node_max master_max master_node_max param_id1 param_name1 param_value1 param_id2 param_name2 param_value2 ... param_idn param_namen param_valuen */ static const char resource[] = BEGIN_NODE BEGIN_KEY "id" END_KEY BEGIN_KEY "class" END_KEY BEGIN_KEY "type" END_KEY BEGIN_KEY "provider" END_KEY BEGIN_KEY "groupid" END_KEY BEGIN_KEY "advance" END_KEY BEGIN_KEY "advance_id" END_KEY BEGIN_KEY "clone_max" END_KEY BEGIN_KEY "clone_node_max" END_KEY BEGIN_KEY "master_max" END_KEY BEGIN_KEY "master_node_max" END_KEY BEGIN_NODE CIM_MSG_ATTR REPEATE BEGIN_KEY "id" END_KEY BEGIN_KEY "name" END_KEY BEGIN_KEY "value" END_KEY END_NODE END_NODE; static const FunContext update_ctx_table [] = { {DEL_OPERATION, A_1(MSG_DEL_RSC_OP), NULL, NULL}, {DEL_ATTRIBUTES, A_1(MSG_DEL_RSC_PARAM),NULL, NULL}, {DEL_RESOURCE, A_1(MSG_DEL_RSC), NULL, NULL}, {CLEANUP_RESOURCE, A_1(MSG_CLEANUP_RSC), NULL, NULL}, {CREATE_RSC_GROUP, A_1(MSG_ADD_GRP),NULL, NULL}, {CREATE_RESOURCE, A_1(MSG_ADD_RSC), resource, node_update}, {DEL_ORDER_CONSTRAINT, A_2(MSG_DEL_CONSTRAINT, STR_CONS_ORDER), NULL, NULL }, {DEL_LOCATION_CONSTRAINT, A_2(MSG_DEL_CONSTRAINT, STR_CONS_LOCATION), NULL, NULL }, {DEL_COLOCATION_CONSTRAINT, A_2(MSG_DEL_CONSTRAINT, STR_CONS_COLOCATION), NULL, NULL }, {UPDATE_CLONE, A_1(MSG_UPDATE_CLONE), clone, node_update}, {UPDATE_MASTER, A_1(MSG_UPDATE_MASTER),master, node_update}, {UPDATE_OPERATIONS, A_1(MSG_UP_RSC_OPS), operations, node_update}, {UPDATE_ATTRIBUTES, A_1(MSG_UP_RSC_PARAMS), attributes, node_update }, {UPDATE_ORDER_CONSTRAINT, A_2(MSG_UP_CONSTRAINT, STR_CONS_ORDER), order_constraint, node_update }, {UPDATE_LOCATION_CONSTRAINT, A_2(MSG_UP_CONSTRAINT, STR_CONS_LOCATION), location_constraint, node_update }, {UPDATE_COLOCATION_CONSTRAINT, A_2(MSG_UP_CONSTRAINT, STR_CONS_COLOCATION), co_constraint, node_update }, }; static const FunContext * find_query_ctx(int func_id) { int i, len; const FunContext * ctx_table; len = sizeof(query_ctx_table)/sizeof(FunContext); ctx_table = query_ctx_table; for (i = 0; i < len; i++){ if (ctx_table[i].func_id == func_id){ return &ctx_table[i]; } } return NULL; } static const FunContext * find_update_ctx(int func_id) { int i, len; const FunContext * ctx_table; len = sizeof(update_ctx_table)/sizeof(FunContext); ctx_table = update_ctx_table; for (i = 0; i < len; i++){ if (ctx_table[i].func_id == func_id){ return &ctx_table[i]; } } return NULL; } struct ha_msg * cim_query_dispatch(int func_id, const char * param, void * out) { const FunContext * ctx; MClient * client; const char * arg; int i = 0; struct ha_msg * msg = NULL; char pathname[MAXLEN]; cim_debug2(LOG_INFO, "cim_query_dispatch: %d, %s", func_id, param? param : ""); /* look for msg from cache first */ snprintf(pathname, MAXLEN, "cache_1_%d_%s", func_id, param?param:"list"); if (!cib_changed() &&(msg = cim_disk2msg(pathname))){ return msg; } /* not found: get msg from client */ if ((ctx = find_query_ctx(func_id)) == NULL ) { cl_log(LOG_ERR, "%s: can't find function %d.", __FUNCTION__, func_id); return NULL; } if ((msg = ha_msg_new(1)) == NULL ) { cl_log(LOG_ERR, "%s: alloc msg failed.", __FUNCTION__); return NULL; } if ( (client = mclient_new()) == NULL ) { cl_log(LOG_ERR, "%s: can't create client", __FUNCTION__); ha_msg_del(msg); return NULL; } while ((arg = ctx->cmnd[i++])){ mclient_cmnd_append(client, arg); } if(param){ mclient_cmnd_append(client, param); } /* execute the command and call callback to process the result */ if( mclient_process(client) == MC_OK && ctx->handle_func ) { if( client->rlen == 0 ) { cl_log(LOG_WARNING, "cim_qeury_dispatch:" "client only return 'ok'"); goto clean_and_return_null; } else if ( ctx->handle_func(client, msg, ctx, out)!= HA_OK) { cl_log(LOG_ERR, "cim_query_dispatch: handle_func failed."); goto clean_and_return_null; } } else { goto clean_and_return_null; } mclient_free(client); /* cache it */ if ( msg ) { snprintf(pathname, MAXLEN, "cache_1_%d_%s", func_id, param?param:"list"); cim_msg2disk(pathname, msg); } return msg; clean_and_return_null: mclient_free(client); ha_msg_del(msg); return NULL; } int cim_update_dispatch(int func_id, const char* param, void* in, void* out) { const FunContext * ctx; MClient * client; const char * arg; int ret = HA_OK; int i = 0; if ((ctx = find_update_ctx(func_id)) == NULL ) { cl_log(LOG_ERR, "cim_update: can't find function %d", func_id); return HA_FAIL; } if ( (client = mclient_new()) == NULL ) { cl_log(LOG_ERR, "%s: can't create client", __FUNCTION__); return HA_FAIL; } while ((arg = ctx->cmnd[i++])){ mclient_cmnd_append(client, arg); } if(param){ mclient_cmnd_append(client, param); } ret = HA_OK; if ( ctx->handle_func ){ ret = ctx->handle_func(client, in, ctx, out); } if ( ret == HA_OK ) { if ( mclient_process(client) != MC_OK ) { cl_log(LOG_ERR, "%s: update failed.", __FUNCTION__); ret = HA_FAIL; } } mclient_free(client); return ret; } static void msg_pattern_free(void * param) { struct msg_pattern_t *pattern = NULL; int i; if ((pattern = (struct msg_pattern_t*)param) == NULL ) { return; } for(i = 0; i < MSG_MAX_DEPTH; i++) { int j; for(j=0; jlen[i]; j++) { if ( pattern->keys[i][j] ) { cim_free(pattern->keys[i][j]); } } if ( pattern->tag[i] ) { cim_free(pattern->tag[i]); } } cim_free(pattern); } static struct msg_pattern_t * msg_pattern_parse(const char *exp) { const char *p, *q; char ch, tmp[128]; int depth = -1; struct msg_pattern_t * pattern; cim_debug2(LOG_INFO, "msg_pattern_parse: pattern_exp: %s", exp); pattern = (struct msg_pattern_t *) cim_malloc(sizeof(struct msg_pattern_t)); if ( pattern == NULL ) { cl_log(LOG_ERR, "%s: alloc msg_pattern failed.", __FUNCTION__); return NULL; } memset(pattern, 0, sizeof(struct msg_pattern_t)); pattern->depth = 0; p = exp; while((ch = *(p++) )) { if ( ch == BEGIN_NODE_CHAR ) { depth++; if ( depth >= MSG_MAX_DEPTH) { cl_log(LOG_ERR, "%s: depth >= %d.", __FUNCTION__, MSG_MAX_DEPTH); msg_pattern_free(pattern); return NULL; } q = p; while( *p != BEGIN_KEY_CHAR && *p != BEGIN_NODE_CHAR && *p != REPEATE_CHAR){ p++; } if ( p != q ) { memcpy(tmp, q, p - q); tmp[p - q] = EOS; cim_debug2(LOG_INFO, "Got tag %d:%s", depth, tmp); pattern->tag[depth] = cim_strdup(tmp); } continue; } if ( ch == REPEATE_CHAR ) { if(*p == ANYTIMES_CHAR){ /* the only case by now */ p++; } } if ( ch == BEGIN_KEY_CHAR) { /* found one pattern*/ q = p; /* its start position */ while(*p != END_KEY_CHAR) { p++; /* its end position */ } memcpy(tmp, q, p - q); tmp[p - q] = EOS; pattern->len[depth] ++; pattern->keys[depth] = cim_realloc(pattern->keys[depth], pattern->len[depth]*sizeof(char*)); pattern->keys[depth][pattern->len[depth]-1] = cim_strdup(tmp); continue; } } pattern->depth = depth; return pattern; } static int list_return(MClient *client, void *data, const FunContext *ctx, void *out) { struct ha_msg *msg; int i; if((msg = (struct ha_msg *)data) == NULL ) { cl_log(LOG_ERR, "%s: msg not alloced.", __FUNCTION__); return HA_FAIL; } for(i=0; i < client->rlen; i++){ char *value = mclient_nth_value(client, i); if(value == NULL ) { cl_log(LOG_ERR, "%s: failed to get at %d.", __FUNCTION__, i); return HA_FAIL; } cim_list_add(msg, value); } return HA_OK; } /* default callback for query_dispatch */ static int node_return(MClient *client, void *data, const FunContext *ctx, void *out) { struct ha_msg *msg; int i, index, len; struct msg_pattern_t * pattern; if ((pattern = msg_pattern_parse(ctx->pattern_exp)) == NULL ) { cl_log(LOG_ERR, "node_return: pattern parse failed."); return HA_FAIL; } index = 0; if((msg = (struct ha_msg *)data) == NULL ) { cl_log(LOG_ERR, "%s: msg not alloced.", __FUNCTION__); return HA_FAIL; } /* parent node */ for(i=0; i < pattern->len[0]; i++){ char *value = mclient_nth_value(client, index ++); if(value == NULL ) { cl_log(LOG_ERR, "%s: get pattern:%d failed.", __FUNCTION__, i); return HA_FAIL; } ha_msg_add(msg, pattern->keys[0][i], value); } if( pattern->tag[0] ) { ha_msg_add(msg, CIM_MSG_TAG, pattern->tag[0]); } /* no child node, done */ if(pattern->len[1] == 0 || pattern->keys[1] == NULL) { goto done; } /* otherwise, create child node and add it to upper node */ len = (client->rlen - index)/pattern->len[1]; for(i=0; i < len; i++){ char * value = NULL; struct ha_msg *child; int j = 0; child = ha_msg_new(pattern->len[1]); for (j=0; j < pattern->len[1]; j++) { value = mclient_nth_value(client, index ++); if(value == NULL ) { ha_msg_del(child); goto done; } ha_msg_add(child, pattern->keys[1][j], value); } if( pattern->tag[1] ) { ha_msg_add(child, CIM_MSG_TAG, pattern->tag[1]); } cim_msg_add_child(msg, cl_get_string(child, "id"), child); } done: msg_pattern_free(pattern); return HA_OK; } /* default callback for update_dispatch */ static int node_update(MClient* client, void* data, const FunContext* ctx, void* out) { int len, i; struct msg_pattern_t * pattern; struct ha_msg *msg = NULL; if ( (msg = (struct ha_msg *)data) == NULL ) { return HA_OK; } if ((pattern = msg_pattern_parse(ctx->pattern_exp)) == NULL ) { DEBUG_LEAVE(); return HA_FAIL; } for(i=0; i < pattern->len[0]; i++){ const char *value; value = cl_get_string(msg, pattern->keys[0][i]); mclient_cmnd_append(client, value? value : ""); } /* no child msg, done */ if(pattern->len[1] == 0 || pattern->keys[1] == NULL) { goto done; } /* otherwise, get child struct and append to client */ len = cim_msg_children_count(msg); for(i=0; i < len; i++){ const char *value = NULL; struct ha_msg *child; int j = 0; child = cim_msg_child_index(msg, i); cl_log(LOG_INFO, "%s: child: %s", __FUNCTION__, msg2string(child)); for (j=0; j < pattern->len[1]; j++) { value = cl_get_string(child, pattern->keys[1][j]); cl_log(LOG_INFO, "%s: %s -- %s", __FUNCTION__, pattern->keys[1][j], value); mclient_cmnd_append(client, value?value : ""); } } done: msg_pattern_free(pattern); return HA_OK; } int cim_get_hb_status () { char ** std_out = NULL; int ret; int status = HB_UNKNOWN; run_shell_cmnd(CLIHB" status", &ret, &std_out, NULL); if ( std_out == NULL || std_out[0] == NULL ) { return HB_UNKNOWN; } if ( strstr ( std_out[0], "running") != NULL ) { status = HB_RUNNING; } else { status = HB_STOPED; } free_2d_zarray(std_out, cim_free); return status; } int cim_change_hb_state (int state) { int status; int rc; const char * cmnd = NULL; switch(state) { case START_HB: cmnd = CLIHB" start"; break; case STOP_HB: cmnd = CLIHB" stop"; break; case RESTART_HB: cmnd = CLIHB" restart"; break; default: cl_log(LOG_ERR, "cim_change_hb_state: unknown opeation"); } /* run it */ rc=system(cmnd); if (rc != 0) { cl_log(LOG_ERR, "%s: system(%s) returned %d", __FUNCTION__, cmnd, rc); } /* verify the status */ status = cim_get_hb_status(); if ( (state == START_HB || state == RESTART_HB) && (status == HB_RUNNING) ) { return HA_OK; } else if( state == STOP_HB && status == HB_STOPED ) { return HA_OK; } return HA_FAIL; } static int InsertOption(struct ha_msg *msg, const char * directive, const char * option) { int i = 0; const struct map_t *map = cim_query_map(HA_CLUSTER); if (map== NULL ) { return HA_FAIL; } for (i=0; ilen; i++) { if ( strncmp(directive, map->entry[i].key, MAXLEN) == 0){ break; } } if (map->entry[i].type == CMPI_charsA) { cl_msg_list_add_string(msg, directive, option); } else { cl_msg_modstring(msg, directive, option); } return HA_OK; } struct ha_msg* cim_get_hacf_config () { FILE * f = NULL; char buf[MAXLEN]; char * cp; char directive[MAXLEN]; size_t dirlength; char option[MAXLEN]; size_t optionlength; struct ha_msg * info = NULL; const char * cfgfile = CONFIG_FILENAME; DEBUG_ENTER(); if ((info = ha_msg_new(16)) == NULL ) { return NULL; } if ((f = fopen(cfgfile, "r")) == NULL ) { cl_log(LOG_ERR, "Failed to open %s", cfgfile); ha_msg_del(info); return NULL; } while (fgets(buf, MAXLEN, f) != NULL) { char * bp = buf; char option_full[MAXLEN] = ""; /* Skip over white space */ bp += strspn(bp, WHITESPACE); /* Zap comments on the line */ if ((cp = strchr(bp, COMMENTCHAR)) != NULL) { *cp = EOS; } /* Strip '\n' and '\r' chars */ if ((cp = strpbrk(bp, CRLF)) != NULL) { *cp = EOS; } /* Ignore blank (and comment) lines */ if (*bp == EOS) { continue; } /* Now we expect a directive name */ dirlength = strcspn(bp, WHITESPACE); strncpy(directive, bp, dirlength); directive[dirlength] = EOS; while (*bp != EOS) { optionlength = strcspn(bp, DELIMS); strncpy(option, bp, optionlength); option[optionlength] = EOS; bp += optionlength; if ( strcmp(option, directive) != 0 ) { if ( strcmp(directive, "node") != 0) { strcat(option_full, option); strcat(option_full, " "); }else{ /* directive is "node" */ InsertOption(info, directive, option); } } /* Skip over Delimiters */ bp += strspn(bp, DELIMS); } if ( strcmp(directive, "node") != 0 ) { option_full[strlen(option_full) - 1] = EOS; InsertOption(info, directive, option_full); } } fclose(f); DEBUG_LEAVE(); return info; } static int StrIsEmpty(const char * str) { char ch; while ( (ch = *(str++) )){ if ( ch ==' ' || ch == '\t'){ continue; } else { return 0; } } return 1; } #define SPACELEN 20 #define FILLSPACE(f, n) do{ \ int i=0; \ for(i=0; i<(n); i++){ \ fprintf(f, " ");\ } \ } while(0); static void write_file_foreach(char *key, struct ha_msg *msg, void *user) { FILE * f = (FILE *) user; int i, len; const struct map_t *map = cim_query_map(HA_CLUSTER); if (map == NULL ) { return; } for (i=0; ilen; i++) { if ( strncmp(key, map->entry[i].key, MAXLEN) == 0){ break; } } if (map->entry[i].type == CMPI_charsA) { len = cl_msg_list_length(msg, key); for (i =0; i < len; i++) { char * value; value = (char*)cl_msg_list_nth_data(msg, key, i); if ( !StrIsEmpty(value) ){ fprintf(f, "%s", (char *)key); FILLSPACE(f, SPACELEN - strlen(key)) fprintf(f, "%s\n", value); } } } else { const char *value = cl_get_string(msg, key); if (value && !StrIsEmpty(value)) { fprintf(f, "%s", (char *)key); FILLSPACE(f, SPACELEN - strlen(key)) fprintf(f, "%s\n", value); } } } int cim_update_hacf(struct ha_msg *info) { FILE * f = NULL; int i; /* backup old file */ if ( rename(CONFIG_NAME, BACKUP_CONFIG_NAME) != 0 ) { cl_log(LOG_WARNING, "Backup ha.cf failed."); } if ( ( f = fopen(CONFIG_NAME, "w") ) == NULL ) { cl_log(LOG_ERR, "Could not open ha.cf"); return HA_FAIL; } cl_log(LOG_INFO, "Begin dump config infomation."); fprintf(f, CONFIG_COMMENT); for(i=0; infields; i++) { write_file_foreach(info->names[i], info, f); } fclose(f); return HA_OK; } struct ha_msg * cim_get_authkeys(void) { FILE * f = NULL; struct stat keyfilestat; int authnum = -1; char buf[MAXLEN]; char key[MAXLEN]; char method[MAXLEN]; int i; int src; struct ha_msg * authinfo; if ( (authinfo = ha_msg_new(2)) == NULL ) { cl_log(LOG_ERR, "Alloc table failed."); return NULL; } if ((f = fopen(KEYFILE, "r")) == NULL) { cl_log(LOG_ERR, "Cannot open keyfile [%s]. Stop." , KEYFILE); ha_msg_del(authinfo); return NULL; } if (fstat(fileno(f), &keyfilestat) < 0 || keyfilestat.st_mode & (S_IROTH | S_IRGRP)) { cl_log(LOG_ERR, "Bad permissions on keyfile" " [%s], 600 recommended.", KEYFILE); fclose(f); ha_msg_del(authinfo); return NULL; } while(fgets(buf, MAXLEN, f) != NULL) { char * bp = buf; bp += strspn(bp, WHITESPACE); if (*bp == COMMENTCHAR || *bp == EOS) { continue; } if (*bp == 'a') { if ((src=sscanf(bp, "auth %d", &authnum)) != 1) { cl_log(LOG_ERR , "Invalid auth line [%s] in " KEYFILE , buf); } /* Parsing of this line now complete */ continue; } key[0] = EOS; if ((src=sscanf(bp, "%d%s%s", &i, method, key)) >= 2) { if ((i < 0) || (i >= MAXAUTH)) { ha_log(LOG_ERR, "Invalid authnum [%d] in " KEYFILE, i); continue; } /* found */ if ( i == authnum ) { break; } } else if (*bp != EOS) { ha_log(LOG_ERR, "Auth line [%s] is invalid." , buf); } } /* add auth method, key to dict */ ha_msg_add(authinfo, "authmethod", method); ha_msg_add(authinfo, "authkey", key); fclose(f); return authinfo; } int cim_update_authkeys(struct ha_msg *msg) { FILE * f; const char *method, *key; /* backup old file */ if ( rename(KEYFILE, BACKUP_KEYFILE) != 0 ) { cl_log(LOG_WARNING, "Backup authkeys failed."); } if ( ( f = fopen(KEYFILE, "w") ) == NULL ) { cl_log(LOG_ERR, "Can not open authkeys."); return HA_FAIL; } /* set mode to 0600 */ if ( chmod(KEYFILE, 0600) != 0 ) { cl_log(LOG_ERR, "Cat not chmod authkeys to 0600."); fclose(f); return HA_FAIL; } /* get new value */ method = cl_get_string(msg, "authmethod"); key = cl_get_string(msg, "authkey"); if (method == NULL || key == NULL ) { cl_log(LOG_ERR, "FATAL: method or key is NULL."); fclose(f); return HA_FAIL; } /* write file */ fprintf(f, CONFIG_COMMENT); fprintf(f, "auth %u\n", 1); fprintf(f, "%u %s %s\n", 1, method, key); fclose(f); return HA_OK; } struct ha_msg * cim_get_software_identity(void) { char ** out = NULL; int ret; DEBUG_ENTER(); run_shell_cmnd(HA_LIBHBDIR"/heartbeat -V", &ret, &out, NULL); if ( out ) { struct ha_msg * msg; char * hbversion; if ( (msg = ha_msg_new(1)) == NULL){ free_2d_zarray(out, cim_free); return NULL; } hbversion = out[0]; if ( hbversion ){ hbversion[strlen(hbversion)-1]=EOS; ha_msg_add(msg, "hbversion", hbversion); DEBUG_LEAVE(); return msg; } else { ha_msg_del(msg); } } DEBUG_LEAVE(); return NULL; } static int cib_changed() { /*FIXME: implementation required */ return 1; } /**************************************************************** * resource list ***************************************************************/ int cim_rsc_is_in_cib(const char *rscid) { char * value; /* struct ha_msg *list=NULL; if ((list = cim_query_dispatch(GET_RSC_LIST, NULL, NULL))){ if ( cim_list_find(list, rscid)) { ha_msg_del(list); cim_debug2(LOG_INFO, "%s: %s is in CIB, " "reason: it's in the CIB resource list.", __FUNCTION__, rscid); return TRUE; } } */ if ((value = cim_rscname_table_get(rscid)) == NULL ) { return TRUE; } else { cim_free(value); return FALSE; } } struct ha_msg* cim_get_all_rsc_list(void) { struct ha_msg *list1 = NULL, *list2; int len2; /* list in CIB */ list1 = cim_query_dispatch(GET_RSC_LIST, NULL, NULL); if (list1 == NULL && (list1 = ha_msg_new(1)) == NULL ) { cl_log(LOG_ERR, "cim_get_all_rsc_list: can't get list1."); return NULL; } /* merge with diabled list */ if ((list2 = cim_rscname_table_keys())) { int i; len2 = cim_list_length(list2); cim_debug2(LOG_INFO, "len2 = %d", len2); for(i=0; i * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef _CLUSTER_INFO_H #define _CLUSTER_INFO_H #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include #include #include #include #include "utils.h" #include "mgmt_client.h" #define TID_UNKNOWN 0x0 #define TID_RES_PRIMITIVE 0x51 #define TID_RES_GROUP 0x52 #define TID_RES_CLONE 0x53 #define TID_RES_MASTER 0x54 #define TID_CONS_ORDER 0x61 #define TID_CONS_LOCATION 0x62 #define TID_CONS_COLOCATION 0x63 #define TID_ARRAY 0x100 #define S_RES_PRIMITIVE "native" #define S_RES_GROUP "group" #define S_RES_CLONE "clone" #define S_RES_MASTER "master" #define S_RES_UNKNOWN "unknown" #define CIM_MSG_LIST "__list__" #define CIM_MSG_TAG "__tag__" #define CIM_MSG_ATTR_ID "id" /* every node-msg should have this */ #define CIM_MSG_INST_ATTR "instance_attributes" #define CIM_MSG_ATTR "attributes" #define HA_CIM_VARDIR "/var/lib/heartbeat/cim" enum { HB_RUNNING = 1, HB_STOPED = 2, HB_UNKNOWN = 3 }; enum { START_HB = 1, STOP_HB = 2, RESTART_HB = 3 }; enum QUERY_CTXIDS { /* cluster */ GET_CRM_CONFIG = 0 , /* get crm config values */ GET_HB_CONFIG , /* get heartbeat config values */ GET_DC , /* get cluster DC */ /* node */ GET_NODE_INFO , /* get node status, etc. */ GET_NODE_LIST , /* get all node names */ /* 4 */ /* resource */ GET_RSC_CLASSES , /* get resource's classes */ GET_RSC_PROVIDERS , /* get resource's providers */ GET_RSC_TYPES , /* get resource's types */ GET_RSC_LIST , /* get all resource names in CIB*/ GET_RSC_TYPE , /* get a resource's type */ GET_RSC_STATUS , /* get a resource's status */ GET_RSC_HOST , /* get the node name which a resource is running on*/ GET_SUB_RSC , /* get the sub resources of a resource*/ GET_PRIMITIVE , /* get a primitive resource */ GET_CLONE , /* get a clone resource */ GET_MASTER , /* get a master-slave resource */ /* 15 */ /* resource attribute */ GET_RSC_OPERATIONS , /* get operations of a resource */ GET_RSC_ATTRIBUTES , /* get attributes of a resource */ /* 17 */ /* constriant */ GET_ORDER_CONS_LIST , /* get all order constraint names*/ GET_LOCATION_CONS_LIST , /* get all location cons names */ GET_COLOCATION_CONS_LIST, /* get all colocation cons names*/ GET_ORDER_CONSTRAINT , /* get an order constraint */ GET_LOCATION_CONSTRAINT , /* get an location cons */ GET_COLOCATION_CONSTRAINT, /* get a colocation cons */ /* 23 */ /* end */ QUERY_CTXID_END /* END of list */ }; enum UPDATE_CTXIDS { /* resource */ DEL_RESOURCE = 0 , /* delete a resource */ DEL_OPERATION , /* delete an operation */ DEL_ATTRIBUTES , /* delete an attribute */ CLEANUP_RESOURCE , UPDATE_MASTER , /* update a master-slave resource */ UPDATE_CLONE , /* update a clone resource */ UPDATE_OPERATIONS , /* update operations */ UPDATE_ATTRIBUTES , /* update attributes */ CREATE_RESOURCE , /* create a resource */ CREATE_RSC_GROUP , /* create a resource group */ /* constraint */ DEL_LOCATION_CONSTRAINT , /* delete a location cons */ DEL_ORDER_CONSTRAINT , /* delete an order cons */ DEL_COLOCATION_CONSTRAINT, /* delete a colocation cons */ UPDATE_LOCATION_CONSTRAINT, /* update loationn constraint */ UPDATE_ORDER_CONSTRAINT , /* update order constraint */ UPDATE_COLOCATION_CONSTRAINT, /* update colocation constraint */ /* end */ UPDATE_CTXID_END /* END of list */ }; struct ha_msg * cim_query_dispatch(int id, const char* param, void* out); int cim_update_dispatch(int id,const char*param, void*data, void*); /* cluster */ struct ha_msg * cim_get_software_identity(void); int cim_get_hb_status (void); int cim_change_hb_state(int state); struct ha_msg * cim_get_hacf_config (void); struct ha_msg * cim_get_authkeys (void); int cim_update_hacf(struct ha_msg *msg); int cim_update_authkeys(struct ha_msg *msg); #define RESOURCE_ENABLED(rscid) (cim_rsc_is_in_cib(rscid)) #define RESOURCE_DISABLED(rscid) (!cim_rsc_is_in_cib(rscid)) /* get a resource's type: TID_RES_PRIMITIVE, etc */ int cim_get_rsctype(const char * rscid); int cim_rsc_is_in_cib(const char *rscid); /* not include sub resources */ struct ha_msg* cim_get_all_rsc_list(void); /* retrive the closure of the list */ struct ha_msg* cim_traverse_allrsc(struct ha_msg* list); /* resource operations */ struct ha_msg * cim_get_rscops(const char *rscid); int cim_add_rscop(const char *rscid, struct ha_msg *op); int cim_del_rscop(const char *rscid, const char *opid); int cim_update_rscop(const char*rscid, const char*, struct ha_msg*); /* resource */ /* submit a resource to CIB */ int cim_rsc_submit(const char *rscid); /* store a resource image on the disk */ int cim_rscdb_store(int type, const char *rscid, struct ha_msg *rsc); /* cleanup a resource image from the disk, as well as its attributes, type ... */ int cim_rscdb_cleanup(int type, const char * rscid); struct ha_msg* cim_find_rsc(int type, const char * rscid); int cim_update_rsc(int type, const char *rscid, struct ha_msg *); int cim_remove_rsc(const char * rscid); /* sub resource */ struct ha_msg * cim_get_subrsc_list(const char *rscid); int cim_add_subrsc(struct ha_msg *rsc, struct ha_msg *subrsc); /* resource attributes */ struct ha_msg * cim_rscattrs_get(const char *rscid); int cim_rscattrs_del(const char *rscid); int cim_update_attrnvpair(const char*, const char*, struct ha_msg*); int cim_remove_attrnvpair(const char* rscid, const char* attrid); #endif /* _CLUSTER_INFO_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/cluster_node_provider.c000066400000000000000000000203641211477743100246260ustar00rootroot00000000000000/* * cluster_node_provider.c: HA_ClusterNode provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include "cmpi_utils.h" #include "cluster_info.h" static const char * PROVIDER_ID = "cim-node"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_ClusterNode"; static CMPIInstance * make_node_instance(CMPIObjectPath * op, char * uname, CMPIStatus * rc); static int node_get_inst(CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties, CMPIStatus * rc); static int node_enum_insts(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, int EnumInst, CMPIStatus * rc); static int cleanup_node(void); DeclareInstanceFunctions(ClusterNode); static CMPIInstance * make_node_instance(CMPIObjectPath * op, char * uname, CMPIStatus * rc) { CMPIInstance * ci = NULL; char caption[MAXLEN]; struct ha_msg *nodeinfo; ci = CMNewInstance(Broker, op, rc); if ( CMIsNullObject(ci) ) { CMSetStatusWithChars(Broker, rc, CMPI_RC_ERR_FAILED, "Create instance failed"); return NULL; } snprintf(caption, MAXLEN, "Node.%s", uname); CMSetProperty(ci, "CreationClassName", ClassName, CMPI_chars); CMSetProperty(ci, "Name", uname, CMPI_chars); CMSetProperty(ci, "Caption", caption, CMPI_chars); nodeinfo = cim_query_dispatch(GET_NODE_INFO, uname, NULL); if(nodeinfo){ cmpi_msg2inst(Broker, ci, HA_CLUSTER_NODE, nodeinfo, rc); ha_msg_del(nodeinfo); } return ci; } static int node_get_inst(CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties, CMPIStatus * rc) { CMPIObjectPath * op = NULL; CMPIString * tmp; char * uname = NULL; CMPIInstance * ci = NULL; tmp = CMGetKey(cop, "Name", rc).value.string; if ( tmp == NULL ) { cl_log(LOG_ERR, "node_get_inst: Failed to get key:Name"); return HA_FAIL; } uname = CMGetCharPtr(tmp); op = CMNewObjectPath(Broker, CMGetCharPtr(CMGetNameSpace(cop, rc)), ClassName, rc); if ( CMIsNullObject(op) ){ cl_log(LOG_ERR, "node_get_inst: Alloc ObjectPath failed."); return HA_FAIL; } ci = make_node_instance(op, uname, rc); if ( CMIsNullObject(ci) ) { return HA_FAIL; } CMReturnInstance(rslt, ci); CMReturnDone(rslt); return HA_OK; } static int node_enum_insts(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, int EnumInst, CMPIStatus * rc) { CMPIObjectPath * op = NULL; int hbstatus; int i = 0, len; struct ha_msg *nodes; char *nspace; if ((hbstatus = cim_get_hb_status()) != HB_RUNNING ) { CMReturnDone(rslt); return HA_OK; } nspace = CMGetCharPtr(CMGetNameSpace(ref, rc)); if ( nspace == NULL ) { return HA_FAIL; } nodes = cim_query_dispatch(GET_NODE_LIST, NULL, NULL); if ( nodes == NULL ) { cl_log(LOG_ERR, "%s: Can not get node list.", __FUNCTION__); CMSetStatusWithChars(Broker, rc, CMPI_RC_ERR_FAILED, "Could not get node list."); return HA_FAIL; } len = cim_list_length(nodes); for (i = 0; i < len; i++) { char *uname; if ((uname = cim_list_index(nodes, i)) == NULL ) { continue; } /* create an object */ op = CMNewObjectPath(Broker, nspace, ClassName, rc); if (op == NULL ){ ha_msg_del(nodes); return HA_FAIL; } if ( EnumInst ) { /* enumerate instances */ CMPIInstance * ci = NULL; if ((ci = make_node_instance(op, uname, rc))==NULL) { rc->rc = CMPI_RC_ERR_FAILED; ha_msg_del(nodes); return HA_FAIL; } CMReturnInstance(rslt, ci); } else { /* enumerate instance names */ CMAddKey(op, "CreationClassName", ClassName, CMPI_chars); CMAddKey(op, "Name", uname, CMPI_chars); CMReturnObjectPath(rslt, op); } } CMReturnDone(rslt); ha_msg_del(nodes); return HA_OK; } static int cleanup_node () { cl_log(LOG_INFO, "%s: clean up", __FUNCTION__); return HA_OK; } /********************************************** * Instance provider functions **********************************************/ static CMPIStatus ClusterNodeCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { cleanup_node(); CMReturn(CMPI_RC_OK); } static CMPIStatus ClusterNodeEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); node_enum_insts(mi, ctx, rslt, ref, FALSE, &rc); return rc; } static CMPIStatus ClusterNodeEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); node_enum_insts(mi, ctx, rslt, ref, TRUE, &rc); return rc; } static CMPIStatus ClusterNodeGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); node_get_inst(ctx, rslt, cop, properties, &rc); return rc; } static CMPIStatus ClusterNodeCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus ClusterNodeSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus ClusterNodeDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus ClusterNodeExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /***************************************************** * install provider ****************************************************/ DeclareInstanceMI(ClusterNode, HA_ClusterNodeProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/cluster_provider.c000066400000000000000000000356001211477743100236200ustar00rootroot00000000000000/* * cluster_provider.c: HA_Cluster provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include "cmpi_utils.h" #include "cluster_info.h" #include "utils.h" static const char * PROVIDER_ID = "cim-hb"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_Cluster"; static char InstName [] = "LinuxHACluster"; static char Caption [] = "LinuxHA Cluster"; /* auth map */ uint32_t auth_valuemap [] = {0, 1, 2}; const char * auth_values [] = {"sha1", "md5", "crc"}; static uint32_t last_requested_state = 5; /* Not Changed */ static CMPIInstance * make_cluster_instance(CMPIObjectPath * op, CMPIStatus * rc); static int cluster_get_inst(CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIStatus * rc); static int cluster_enum_insts(CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties, int enum_inst, CMPIStatus * rc); static int auth_value2map(const char * method); static const char * auth_map2value(uint32_t map); static void config_set_instance(CMPIInstance * ci, CMPIStatus * rc); static void auth_set_instance(CMPIInstance * ci, CMPIStatus * rc); static void crm_set_instance(CMPIInstance * ci, CMPIStatus * rc); /* set instance */ static int cluster_update_inst(CMPIContext* ctx, CMPIResult* rslt, CMPIObjectPath*, CMPIInstance*, CMPIStatus*); static int request_state_change(int state); static int cleanup_cluster(void); DeclareInstanceFunctions(Cluster); static int auth_value2map(const char * method) { int i; for (i = 0; i < sizeof(auth_valuemap)/sizeof(uint32_t); i++) { if ( strcmp(auth_values[i], method) == 0) { return auth_valuemap[i]; } } return -1; } static const char * auth_map2value(uint32_t map) { int i; for (i = 0; i < sizeof(auth_valuemap)/sizeof(uint32_t); i++) { if ( map == auth_valuemap[i] ) { return auth_values[i]; } } return NULL; } static void config_set_instance(CMPIInstance * ci, CMPIStatus * rc) { struct ha_msg * info; DEBUG_ENTER(); /* get cluster config values */ info = cim_get_hacf_config (); if ( info == NULL ) { cl_log(LOG_ERR, "%s:can not get cluster.", __FUNCTION__); return; } cmpi_msg2inst(Broker, ci, HA_CLUSTER, info, rc); DEBUG_LEAVE(); ha_msg_del(info); } static void auth_set_instance(CMPIInstance * ci, CMPIStatus * rc) { int num; char* method; char* key; struct ha_msg *msg; DEBUG_ENTER(); if ( (msg = cim_get_authkeys()) == NULL ){ cl_log(LOG_WARNING, "Can not get auth message"); return; } method = cim_strdup(cl_get_string(msg, "authmethod")); key = cim_strdup(cl_get_string(msg, "authkey")); num = auth_value2map(method); CMSetProperty(ci, "AuthMethod", &num, CMPI_uint32); CMSetProperty(ci, "AuthKey", key, CMPI_chars); DEBUG_LEAVE(); ha_msg_del(msg); } static void crm_set_instance(CMPIInstance * ci, CMPIStatus * rc) { char * it, * sc, * se; char * nq, * rs, * hq; struct ha_msg *msg; if (( msg = cim_query_dispatch(GET_CRM_CONFIG, NULL, NULL)) == NULL ){ return; } it = cim_strdup(cl_get_string(msg, "transition_idle_timeout")); sc = cim_strdup(cl_get_string(msg, "symmetric_cluster")); se = cim_strdup(cl_get_string(msg, "stonith_enabled")); nq = cim_strdup(cl_get_string(msg, "no_quorum_policy")); rs = cim_strdup(cl_get_string(msg, "default_resource_stickiness")); hq = cim_strdup(cl_get_string(msg, "have_quorum")); if (it && sc && se && nq && rs && hq) { CMSetProperty(ci, "TransitionIdleTimeout", it, CMPI_chars); CMSetProperty(ci, "SymmetricCluster", sc, CMPI_chars); CMSetProperty(ci, "StonithEnabled", se, CMPI_chars); CMSetProperty(ci, "NoQuorumPolicy", nq, CMPI_chars); CMSetProperty(ci, "DefaultResourceStickiness", rs, CMPI_chars); CMSetProperty(ci, "HaveQuorum", hq, CMPI_chars); } ha_msg_del(msg); } /* always only one cluster instance */ static CMPIInstance * make_cluster_instance(CMPIObjectPath * op, CMPIStatus * rc) { CMPIInstance *ci = NULL; uint32_t state = 0; struct ha_msg *msg; DEBUG_ENTER(); ci = CMNewInstance(Broker, op, rc); if ( CMIsNullObject(ci) ) { cl_log(LOG_ERR, "%s: couldn't create instance", __FUNCTION__); CMSetStatusWithChars(Broker, rc, CMPI_RC_ERR_FAILED, "Could not create instance."); return NULL; } CMSetProperty(ci, "CreationClassName", ClassName, CMPI_chars); CMSetProperty(ci, "Name", InstName, CMPI_chars); CMSetProperty(ci, "Caption", Caption, CMPI_chars); /* set config properties */ config_set_instance(ci, rc); /* set auth properties */ auth_set_instance(ci, rc); state = 3; /* Disabled */ if( cim_get_hb_status() == HB_RUNNING) { state = 2; /* Enabled */ /* set crm properties */ crm_set_instance(ci, rc); } CMSetProperty(ci, "EnabledState", &state, CMPI_uint32); CMSetProperty(ci, "RequestedState", &last_requested_state, CMPI_uint32); if ( (msg = cim_get_software_identity() )){ char * hv; hv = cim_strdup(cl_get_string(msg, "hbversion")); if (hv) { CMSetProperty(ci, "HBVersion", hv, CMPI_chars); } cim_free(hv); } DEBUG_LEAVE(); return ci; } /* get a cluster instance */ static int cluster_get_inst(CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIStatus * rc) { CMPIObjectPath * op = NULL; CMPIString * cmpi_namespace = NULL; char * namespace = NULL; CMPIInstance * ci = NULL; int ret = 0; cmpi_namespace = CMGetNameSpace(cop, rc); namespace = CMGetCharPtr(cmpi_namespace); op = CMNewObjectPath(Broker, namespace, ClassName, rc); if ( CMIsNullObject(op) ){ ret = HA_FAIL; CMSetStatusWithChars(Broker, rc, CMPI_RC_ERR_FAILED, "Create object path failed"); goto out; } /* make a cluster instance */ ci = make_cluster_instance(op, rc); if ( CMIsNullObject(ci) ) { ret = HA_FAIL; goto out; } /* return the instance */ CMReturnInstance(rslt, ci); CMReturnDone(rslt); ret = HA_OK; out: return ret; } /* enumerate cluster instances or instance names */ static int cluster_enum_insts(CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties, int enum_inst, CMPIStatus * rc) { CMPIInstance * ci = NULL; CMPIObjectPath * op = NULL; CMPIString * cmpi_namespace = NULL; char * namespace = NULL; int ret = 0; cmpi_namespace = CMGetNameSpace(cop, rc); namespace = CMGetCharPtr(cmpi_namespace); op = CMNewObjectPath(Broker, namespace, ClassName, rc); if ( CMIsNullObject(op) ){ CMSetStatusWithChars(Broker, rc, CMPI_RC_ERR_FAILED, "Create object path failed"); ret = HA_FAIL; goto out; } if ( ! enum_inst ) { /* enumerate instance names */ CMAddKey(op, "CreationClassName", ClassName, CMPI_chars); CMAddKey(op, "Name", InstName, CMPI_chars); CMReturnObjectPath(rslt, op); } else { /* enumerate instances */ ci = make_cluster_instance(op, rc); if ( CMIsNullObject(ci) ) { ret = HA_FAIL; goto out; } CMReturnInstance(rslt, ci); } CMReturnDone(rslt); ret = HA_OK; out: return ret; } /* update cluster instance, this will result in modification to the ha.cf and authkeys */ static int cluster_update_inst(CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * op, CMPIInstance * inst, CMPIStatus * rc) { int ret, authnum; const char *authkey, *authmethod; struct ha_msg *cfginfo, *authinfo; /* ha.cf */ if((cfginfo = cim_get_hacf_config()) == NULL ) { /* ha.cf not exist yet */ if ((cfginfo = ha_msg_new(16)) == NULL ) { return HA_FAIL; } } ret = cmpi_inst2msg(inst, HA_CLUSTER, cfginfo, rc); /* update the ha.cf file */ ret = cim_update_hacf(cfginfo); ha_msg_del(cfginfo); /* authkeys */ if ( (authinfo = cim_get_authkeys()) == NULL ) { if ((authinfo = ha_msg_new(2)) == NULL ) { return HA_FAIL; } } authnum = CMGetProperty(inst, "AuthMethod", rc).value.uint32; if ( rc->rc == CMPI_RC_OK ) { authmethod = auth_map2value(authnum); cl_msg_modstring(authinfo, "authmethod", authmethod); } authkey = CMGetPropertyString(inst, "AuthKey", rc); if ( authkey ) { cl_msg_modstring(authinfo, "authkey", authkey); } /* update the authkeys file */ ret = cim_update_authkeys(authinfo); ha_msg_del(authinfo); return HA_OK; } /* clean up */ static int cleanup_cluster () { cl_log(LOG_INFO, "%s: clean up", __FUNCTION__); return HA_OK; } /* use 2: Enabled, 3: Disabled, 10: Reboot for hb start hb stop hb restart */ static int request_state_change(int state) { int action [] = {0, 0, START_HB, STOP_HB, 0, /* 4 */ 0, 0, 0, 0, 0, /* 9 */ 0, RESTART_HB}; last_requested_state = state; cim_change_hb_state(action[state]); return HA_OK; } /********************************************** * Instance Provider Interface **********************************************/ static CMPIStatus ClusterCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { cleanup_cluster(); CMReturn(CMPI_RC_OK); } static CMPIStatus ClusterEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath *ref) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); /* enumerate instance names */ cluster_enum_insts(ctx, rslt, ref, NULL, FALSE, &rc); return rc; } static CMPIStatus ClusterEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath* ref, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); cluster_enum_insts(ctx, rslt, ref, NULL, TRUE, &rc); return rc; } static CMPIStatus ClusterGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); cluster_get_inst(ctx, rslt, cop, &rc); return rc; } static CMPIStatus ClusterCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hacf_config() ) { cl_log(LOG_WARNING, "Only one instance is allowed."); CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_FAILED, "Only one instance is allowed."); } else { cluster_update_inst(ctx, rslt, cop, ci, &rc); CMReturn(CMPI_RC_OK); } return rc; } static CMPIStatus ClusterSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * op, CMPIInstance * inst, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; /* initialize logger */ PROVIDER_INIT_LOGGER(); /* set instance */ cluster_update_inst(ctx, rslt, op, inst, &rc); CMReturn(CMPI_RC_OK); } static CMPIStatus ClusterDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus ClusterExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /************************************************** * Method Provider Interface *************************************************/ static CMPIStatus ClusterInvokeMethod(CMPIMethodMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, const char * method_name, CMPIArgs * in, CMPIArgs * out) { CMPIString * class_name = NULL; CMPIStatus rc = {CMPI_RC_OK, NULL}; int ret; class_name = CMGetClassName(ref, &rc); if(strcasecmp(CMGetCharPtr(class_name), ClassName) == 0 && strcasecmp("RequestStateChange", method_name) == 0 ){ int state; /* we ignore the TimeoutPeriod parameter */ state = CMGetArg(in, "RequestedState", &rc).value.uint32; ret = request_state_change(state); CMAddArg(out, "Job", NULL, CMPI_ref); } CMReturnData(rslt, &ret, CMPI_uint32); CMReturnDone(rslt); CMReturn(CMPI_RC_OK); } static CMPIStatus ClusterMethodCleanup(CMPIMethodMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } /***************************************************** * install interface ****************************************************/ DeclareInstanceMI(Cluster, HA_ClusterProvider, Broker); DeclareMethodMI(Cluster, HA_ClusterProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/clustering_service_provider.c000066400000000000000000000163021211477743100260340ustar00rootroot00000000000000/* * clustering_service_provider.c: HA_ClusteringService provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include "cmpi_utils.h" #include "cluster_info.h" static const char * PROVIDER_ID = "cim_soft"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_ClusteringService"; static char DEFAULT_ID [] = "default_service_id"; DeclareInstanceFunctions(ClusteringService); static CMPIStatus ClusteringServiceCleanup(CMPIInstanceMI* mi, CMPIContext* ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus ClusteringServiceEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref) { CMPIStatus rc = {CMPI_RC_OK, NULL}; char *namespace = NULL; CMPIObjectPath * op = NULL; PROVIDER_INIT_LOGGER(); namespace = CMGetCharPtr(CMGetNameSpace(ref, &rc)); op = CMNewObjectPath(Broker, namespace, ClassName, &rc); if ( CMIsNullObject(op) ){ CMReturn(CMPI_RC_ERR_FAILED); } CMAddKey(op, "Id", DEFAULT_ID, CMPI_chars); CMReturnObjectPath(rslt, op); return rc; } static CMPIStatus ClusteringServiceEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; char *namespace = NULL; CMPIObjectPath *op; CMPIEnumeration *en; PROVIDER_INIT_LOGGER(); namespace = CMGetCharPtr(CMGetNameSpace(ref, &rc)); op = CMNewObjectPath(Broker, namespace, ClassName, &rc); if ( CMIsNullObject(op) ){ CMReturn(CMPI_RC_ERR_FAILED); } en = CBEnumInstanceNames(Broker, ctx, ref, &rc); if ( CMIsNullObject(en) ){ CMReturn(CMPI_RC_ERR_FAILED); } while ( CMHasNext(en, &rc) ){ CMPIData ref_data; CMPIInstance * inst = NULL; ref_data = CMGetNext(en, &rc); if (ref_data.value.ref == NULL) { cl_log(LOG_INFO, "failed to get ref"); CMReturn(CMPI_RC_ERR_FAILED); } inst = CBGetInstance(Broker, ctx, ref_data.value.ref, properties, &rc); if ( CMIsNullObject(inst) ) { return rc; } CMReturnInstance(rslt, inst); } CMReturnDone(rslt); return rc; } static CMPIStatus ClusteringServiceGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIObjectPath *op; CMPIInstance *ci; char *namespace; CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); namespace = CMGetCharPtr(CMGetNameSpace(cop, &rc)); op = CMNewObjectPath(Broker, namespace, ClassName, &rc); if ( CMIsNullObject(op) ){ CMReturn(CMPI_RC_ERR_FAILED); } ci = CMNewInstance(Broker, op, &rc); if ( CMIsNullObject(ci) ) { CMReturn(CMPI_RC_ERR_FAILED); } CMSetProperty(ci, "Id", DEFAULT_ID, CMPI_chars); CMSetProperty(ci, "Caption", DEFAULT_ID, CMPI_chars); CMReturnInstance(rslt, ci); CMReturnDone(rslt); return rc; } static CMPIStatus ClusteringServiceCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus ClusteringServiceSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus ClusteringServiceDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus ClusteringServiceExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /*********************************************** * method ***********************************************/ static CMPIStatus ClusteringServiceInvokeMethod(CMPIMethodMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, const char * method_name, CMPIArgs * in, CMPIArgs * out) { CMPIString * classname = NULL; CMPIStatus rc = {CMPI_RC_OK, NULL}; CMPIObjectPath* rscop = NULL; int ret = 0; PROVIDER_INIT_LOGGER(); classname = CMGetClassName(ref, &rc); if((rscop = CMGetArg(in, "Resource", &rc).value.ref) == NULL ) { cl_log(LOG_ERR, "%s: can't get Resource ObjectPath.", __FUNCTION__); return rc; } if(strcasecmp(CMGetCharPtr(classname), ClassName) == 0 && strcasecmp(METHOD_ADD_RESOURCE, method_name) == 0 ){ char * rscid; rscid = CMGetKeyString(rscop, "Id", &rc); if ( ( ret = cim_rsc_submit(rscid)) == HA_FAIL ) { cl_log(LOG_ERR, "%s: failed to add resource %s.", __FUNCTION__, rscid); rc.rc = CMPI_RC_ERR_FAILED; } } CMReturnData(rslt, &ret, CMPI_uint32); CMReturnDone(rslt); CMReturn(CMPI_RC_OK); } static CMPIStatus ClusteringServiceMethodCleanup(CMPIMethodMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } /***************************************************** * instance MI ****************************************************/ DeclareInstanceMI(ClusteringService, HA_ClusteringServiceProvider, Broker); DeclareMethodMI(ClusteringService, HA_ClusteringServiceProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/cmpi_utils.c000066400000000000000000000476371211477743100224120ustar00rootroot00000000000000/* * assoc_utils.c: Utilities for CMPI Providers * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include "cmpi_utils.h" #include "cluster_info.h" static inline int ClassIsA(const char * source_class, char * name, CMPIBroker * broker, CMPIObjectPath * cop); static CMPIInstance * MakeInstance(CMPIBroker * broker, char * classname, CMPIObjectPath * op, char * left, char * right, CMPIObjectPath * lop, CMPIObjectPath * rop, CMPIStatus * rc); int cmpi_msg2inst(CMPIBroker * broker, CMPIInstance * inst, int mapid, struct ha_msg *msg, CMPIStatus * rc) { int i = 0; const struct map_t *map = NULL; if ( (map = cim_query_map(mapid)) == NULL ) { cl_log(LOG_ERR, "%s: map is NULL.", __FUNCTION__); return HA_FAIL; } for ( i=0; i < map->len; i++) { if(map->entry[i].type == CMPI_chars) { const char *value; value = cl_get_string(msg, map->entry[i].key); if ( value == NULL ) { cl_log(LOG_WARNING, "%s: key %s not found.", __FUNCTION__, map->entry[i].key); continue; } cim_debug2(LOG_INFO, "%s: got %s:%s [CMPI_chars]", map->entry[i].key, value, __FUNCTION__); CMSetProperty(inst,map->entry[i].name, cim_strdup(value),CMPI_chars); } else if ( map->entry[i].type == CMPI_charsA ) { /* set Array */ CMPIArray * array=NULL; int j = 0, len = 0; len = cl_msg_list_length(msg, map->entry[i].key); if (len <= 0) { continue; } array = CMNewArray(broker, len, CMPI_chars, rc); if ( array == NULL ) { DEBUG_LEAVE(); return HA_FAIL; } for ( j = 0; j < len; j++ ) { char *value = NULL; value = (char*)cl_msg_list_nth_data(msg, map->entry[i].key, j); if ( value == NULL ) { continue; } CMSetArrayElementAt(array, j, &value, CMPI_chars); } cim_debug2(LOG_INFO, "%s: got %s [CMPI_charsA]", __FUNCTION__, map->entry[i].key); CMSetProperty(inst, map->entry[i].name, &array, CMPI_charsA); } else if (map->entry[i].type == CMPI_uint32){ /* set CMPI_uint32 */ } } return HA_OK; } int cmpi_inst2msg(CMPIInstance *inst, int mapid, struct ha_msg *msg, CMPIStatus *rc) { int i = 0; const struct map_t *map = cim_query_map(mapid); CMPIData data; DEBUG_ENTER(); if ( map == NULL ) { return HA_FAIL; } for( i =0; i < map->len; i++){ if ( strncmp(map->entry[i].key , "", MAXLEN) == 0 ) { continue; } data = CMGetProperty(inst, map->entry[i].name, rc); if (rc->rc != CMPI_RC_OK){ cl_log(LOG_WARNING, "Property %s missing.", map->entry[i].name); continue; } if ( data.type == CMPI_string) { char * value = CMGetCharPtr(data.value.string); cl_msg_modstring(msg, map->entry[i].key, value); } else if (data.type == CMPI_stringA){ CMPIArray * array = data.value.array; int j, len = CMGetArrayCount(array, rc); cl_msg_remove(msg, map->entry[i].key); for (j=0; jentry[i].key, value); } } else if (data.type == CMPI_uint32){ cl_log(LOG_ERR, "%s: Not support.", __FUNCTION__); } } return HA_OK; } /**************************************** * new association functions ****************************************/ /* is 'name' a 'source_class'? */ static inline int ClassIsA(const char * source_class, char * classname, CMPIBroker * broker, CMPIObjectPath * cop) { CMPIStatus rc; int is_a = 0; if ( strcmp (source_class, classname) == 0){ is_a = 1; }else if (CMClassPathIsA(broker, cop, classname, &rc)){ is_a = 1; } return is_a; } /* make a instance */ static CMPIInstance * MakeInstance(CMPIBroker * broker, char * classname, CMPIObjectPath * op, char * left, char * right, CMPIObjectPath * lop, CMPIObjectPath * rop, CMPIStatus * rc) { CMPIInstance * inst = NULL; if ( (inst = CMNewInstance(broker, op, rc) ) == NULL ) { cl_log(LOG_ERR, "%s:%d: create instance failed for %s", __FUNCTION__, __LINE__, classname); return NULL; } /* set properties */ CMSetProperty(inst, left, (CMPIValue *)&lop, CMPI_ref); CMSetProperty(inst, right, (CMPIValue *)&rop, CMPI_ref); return inst; } /* enumerate instance names */ CMPIArray * cmpi_instance_names(CMPIBroker * broker, char * namespace, char * classname, CMPIContext * ctx, CMPIStatus * rc) { int max_len = 256; CMPIObjectPath * refs[max_len]; CMPIEnumeration * en; CMPIObjectPath * op = NULL; CMPIArray * array; int len = 0, i = 0; DEBUG_ENTER(); /* create ObjectPath for the class */ op = CMNewObjectPath(broker, namespace, classname, rc); RETURN_FAIL_IFNULL_OBJ(op, "ObjectPath"); /* enumerate instance names of the class */ en = CBEnumInstanceNames(broker, ctx, op, rc); if ( CMIsNullObject(en) ){ cl_log(LOG_ERR, "cmpi_instance_names: " "enumerate instance names for %s failed.", classname); return NULL; } len = 0; while(CMHasNext(en, rc)) { CMPIObjectPath * top = CMGetNext(en, rc).value.ref; if ( CMIsNullObject(top) ) { continue; } if ( len == max_len ) { break; } refs[len] = top; len ++; } if ((array = CMNewArray(broker, len, CMPI_ref, rc)) == NULL ) { cl_log(LOG_ERR, "cmpi_instance_names: create array failed"); return NULL; } for (i=0; i * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef _CMPI_UTILS_H #define _CMPI_UTILS_H #include #include #include #include #include "utils.h" #include "mof_map.h" /* for compatibility */ #ifndef CMPIVersion090 #define CMPIConst #undef CMGetCharPtr #define CMGetCharPtr(x) ((char *)(x)->hdl) #define CMIndicationMIStubExtensions(x) #else /* CMPIVersion090 */ #define CMPIConst const #endif /* CMPIVersion090 */ #define CMGetKeyString(op,key,rc) ({ \ CMPIString * s = CMGetKey(op,key,rc).value.string;\ char *v = NULL; \ if ( s == NULL ) { \ cl_log(LOG_ERR, "key %s is missing.", key);\ }else { \ v = CMGetCharPtr(s); \ } \ v; \ }) #define CMGetPropertyString(op,prop,rc) ({ \ CMPIString * s = CMGetProperty(op,prop,rc).value.string;\ char *v = NULL; \ if ( s == NULL ) { \ cl_log(LOG_ERR, "Property %s is missing.", prop);\ }else { \ v = CMGetCharPtr(s); \ } \ v; \ }) int cmpi_msg2inst(CMPIBroker * broker, CMPIInstance * inst, int mapid, struct ha_msg *msg, CMPIStatus * rc); int cmpi_inst2msg(CMPIInstance *inst, int mapid, struct ha_msg *msg, CMPIStatus *rc); /*********************************************************** * assocation functions **********************************************************/ typedef int (* assoc_pred_func_t)(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIObjectPath * left, CMPIObjectPath * right, CMPIStatus * rc); struct assoc_env { GPtrArray * left_op_tbl; GPtrArray * right_op_tbl; int (*done)(struct assoc_env * env); }; /* target_name: which should be enumerated source_op : generate enumeration according to this object path */ typedef CMPIArray * (* assoc_enum_func_t) (CMPIBroker * broker, char * classname, CMPIContext * ctx, char * namespace, char * target_name, char * target_role, CMPIObjectPath * source_op, /*void * user_data,*/ CMPIStatus * rc); CMPIArray * cmpi_instance_names(CMPIBroker * broker, char * namespace, char * classname, CMPIContext * ctx, CMPIStatus *rc); /* get instance */ int assoc_get_inst(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char * left, char * right, CMPIStatus * rc); /* enumerate cop's associators */ int assoc_enum_associators(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char * left, char * right, char * lclass, char * rclass, const char * assoc_class, const char * result_class, const char * role, const char * result_role, assoc_pred_func_t func, assoc_enum_func_t enum_func, int inst, CMPIStatus * rc); /* enum cop's references */ int assoc_enum_references(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char * left, char * right, char * lclass, char * rclass, const char * result_class, const char * role, assoc_pred_func_t func, assoc_enum_func_t enum_func, int inst, CMPIStatus * rc); /* enum association's instances */ int assoc_enum_insts(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char * left, char * right, char * lclass, char * rclass, assoc_pred_func_t func, assoc_enum_func_t enum_func, int inst, CMPIStatus * rc); /* return ret if obj is a NULL CMPI Object */ #define RETURN_IFNULL_OBJ(obj, ret, n) do { \ if ( CMIsNullObject(obj) ) { \ cl_log(LOG_ERR, "%s:%s:%d: CMPI Object: %s is NULL",\ __FUNCTION__, __FILE__, __LINE__, n);\ return ret; \ } \ } while (0) /* return HA_FAIL if obj is a NULL CMPI Object */ #define RETURN_FAIL_IFNULL_OBJ(obj, n) RETURN_IFNULL_OBJ(obj, HA_FAIL, n) #define RETURN_NULL_IFNULL_OBJ(obj, n) RETURN_IFNULL_OBJ(obj, NULL, n) #define DeclareInstanceCleanup(pfx) \ CMPIStatus pfx##Cleanup(CMPIInstanceMI * mi, CMPIContext * ctx) #define DeclareInstanceEnumInstanceNames(pfx) \ CMPIStatus pfx##EnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, \ CMPIResult * rslt, CMPIObjectPath * ref) #define DeclareInstanceEnumInstances(pfx) \ CMPIStatus pfx##EnumInstances(CMPIInstanceMI * mi, CMPIContext* ctx, \ CMPIResult * rslt, CMPIObjectPath * ref, \ char ** properties) #define DeclareInstanceGetInstance(pfx) \ CMPIStatus pfx##GetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, \ CMPIResult * rslt, CMPIObjectPath * cop, \ char ** properties) #define DeclareInstanceCreateInstance(pfx) \ CMPIStatus pfx##CreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, \ CMPIResult * rslt, CMPIObjectPath * cop, \ CMPIInstance * ci) #define DeclareInstanceSetInstance(pfx) \ CMPIStatus pfx##SetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, \ CMPIResult * rslt, CMPIObjectPath * cop, \ CMPIInstance * ci, char ** properties) #define DeclareInstanceDeleteInstance(pfx) \ CMPIStatus pfx##DeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, \ CMPIResult * rslt, CMPIObjectPath * cop) #define DeclareInstanceExecQuery(pfx) \ CMPIStatus pfx##ExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, \ CMPIResult * rslt, CMPIObjectPath * ref, \ char * lang, char * query) #define DeclareInstanceFunctions(pfx) \ static DeclareInstanceCleanup(pfx); \ static DeclareInstanceEnumInstanceNames(pfx); \ static DeclareInstanceEnumInstances(pfx); \ static DeclareInstanceGetInstance(pfx); \ static DeclareInstanceCreateInstance(pfx); \ static DeclareInstanceSetInstance(pfx); \ static DeclareInstanceDeleteInstance(pfx); \ static DeclareInstanceExecQuery(pfx) #define DeclareMethodInvokeMethod(pfx) \ CMPIStatus pfx##InvokeMethod(CMPIMethodMI * mi, CMPIContext * ctx, \ CMPIResult * rslt, CMPIObjectPath * ref, \ const char * method, CMPIArgs * in, CMPIArgs * out) #define DeclareMethodCleanup(pfx) \ CMPIStatus pfx##MethodCleanup(CMPIMethodMI * mi, CMPIContext * ctx) #define DeclareMethodFunctions(pfx) \ static DeclareMethodInvokeMethod(pfx); \ static DeclareMethodCleanup(pfx) #define DeclareAssociationCleanup(pfx) \ CMPIStatus pfx##AssociationCleanup(CMPIAssociationMI * mi, CMPIContext * ctx) #define DeclareAssociationAssociators(pfx) \ CMPIStatus pfx##Associators(CMPIAssociationMI * mi, CMPIContext * ctx, \ CMPIResult * rslt, CMPIObjectPath * op, \ const char * asscClass, const char * resultClass, \ const char * role, const char * resultRole, \ char ** properties) #define DeclareAssociationAssociatorNames(pfx) \ CMPIStatus pfx##AssociatorNames(CMPIAssociationMI * mi, CMPIContext * ctx, \ CMPIResult * rslt, CMPIObjectPath * op, \ const char * asscClass, const char * resultClass, \ const char * role, const char * resultRole) #define DeclareAssociationReferences(pfx) \ CMPIStatus pfx##References(CMPIAssociationMI * mi, \ CMPIContext * ctx, CMPIResult * rslt, \ CMPIObjectPath * op, const char * resultClass, \ const char * role, char ** properties) #define DeclareAssociationReferenceNames(pfx) \ CMPIStatus pfx##ReferenceNames(CMPIAssociationMI * mi, \ CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, \ const char * resultClass, const char * role) #define DeclareAssociationFunctions(pfx) \ static DeclareAssociationCleanup(pfx); \ static DeclareAssociationAssociators(pfx); \ static DeclareAssociationAssociatorNames(pfx); \ static DeclareAssociationReferences(pfx); \ static DeclareAssociationReferenceNames(pfx) #define DeclareIndicationCleanup(pfx) \ CMPIStatus pfx##IndicationCleanup(CMPIIndicationMI * mi, CMPIContext * ctx) #define DeclareIndicationAuthorizeFilter(pfx) \ CMPIStatus pfx##AuthorizeFilter(CMPIIndicationMI * mi, CMPIContext * ctx, \ CMPIResult * rslt, \ CMPISelectExp * filter, const char * type, \ CMPIObjectPath * classPath, const char * owner) #define DeclareIndicationMustPoll(pfx) \ CMPIStatus pfx##MustPoll(CMPIIndicationMI * mi, \ CMPIContext * ctx, CMPIResult * rslt, CMPISelectExp * filter,\ const char * indType, CMPIObjectPath * classPath) #define DeclareIndicationActivateFilter(pfx) \ CMPIStatus pfx##ActivateFilter(CMPIIndicationMI * mi, \ CMPIContext * ctx, CMPIResult * rslt, \ CMPISelectExp * filter, const char * type, \ CMPIObjectPath * classPath, CMPIBoolean firstActivation) #define DeclareIndicationDeActivateFilter(pfx) \ CMPIStatus pfx##DeActivateFilter(CMPIIndicationMI * mi, \ CMPIContext * ctx, CMPIResult * rslt, \ CMPISelectExp * filter, const char * type, \ CMPIObjectPath * classPath, CMPIBoolean lastActivation) #define DeclareIndicationFunctions(pfx) \ static DeclareIndicationCleanup(pfx); \ static DeclareIndicationAuthorizeFilter(pfx); \ static DeclareIndicationMustPoll(pfx); \ static DeclareIndicationActivateFilter(pfx); \ static DeclareIndicationDeActivateFilter(pfx) #define DeclareInstanceMI(pfx, pn, broker) \ static char inst_provider_name [] = "instance"#pn; \ static CMPIInstanceMIFT instMIFT = { \ CMPICurrentVersion, \ CMPICurrentVersion, \ inst_provider_name, \ pfx##Cleanup, \ pfx##EnumInstanceNames, \ pfx##EnumInstances, \ pfx##GetInstance, \ pfx##CreateInstance, \ pfx##SetInstance, \ pfx##DeleteInstance, \ pfx##ExecQuery \ }; \ CMPIInstanceMI * \ pn##_Create_InstanceMI(CMPIBroker * brkr, CMPIContext * ctx); \ CMPIInstanceMI * \ pn##_Create_InstanceMI(CMPIBroker * brkr, CMPIContext * ctx) \ { \ static CMPIInstanceMI mi = { \ NULL, \ &instMIFT \ }; \ broker = brkr; \ return &mi; \ } #define DeclareMethodMI(pfx, pn, broker) \ static char method_provider_name [] = "method"#pn; \ static CMPIMethodMIFT methMIFT = { \ CMPICurrentVersion, \ CMPICurrentVersion, \ method_provider_name, \ pfx##MethodCleanup, \ pfx##InvokeMethod \ }; \ CMPIMethodMI * \ pn##_Create_MethodMI(CMPIBroker * brkr, CMPIContext * ctx); \ CMPIMethodMI * \ pn##_Create_MethodMI(CMPIBroker * brkr, CMPIContext * ctx) { \ static CMPIMethodMI mi = { \ NULL, \ &methMIFT, \ }; \ broker=brkr; \ return &mi; \ } #define DeclareAssociationMI(pfx, pn, broker) \ static char assoc_provider_name [] = "association"#pn; \ static CMPIAssociationMIFT assocMIFT = { \ CMPICurrentVersion, \ CMPICurrentVersion, \ assoc_provider_name, \ pfx##AssociationCleanup, \ pfx##Associators, \ pfx##AssociatorNames, \ pfx##References, \ pfx##ReferenceNames \ }; \ CMPIAssociationMI * \ pn##_Create_AssociationMI(CMPIBroker * brkr, CMPIContext *ctx); \ CMPIAssociationMI * \ pn##_Create_AssociationMI(CMPIBroker * brkr, CMPIContext *ctx) \ { \ static CMPIAssociationMI mi = { \ NULL, \ &assocMIFT \ }; \ broker = brkr; \ return &mi; \ } #define DeclareIndicationMI(pfx, pn, broker) \ static char ind_provider_name [] = "Indication"#pn; \ static CMPIIndicationMIFT indMIFT = { \ CMPICurrentVersion, \ CMPICurrentVersion, \ ind_provider_name, \ pfx##IndicationCleanup, \ pfx##AuthorizeFilter, \ pfx##MustPoll, \ pfx##ActivateFilter, \ pfx##DeActivateFilter, \ CMIndicationMIStubExtensions(pfx) \ }; \ CMPIIndicationMI * \ pn##_Create_IndicationMI(CMPIBroker * brkr, CMPIContext * ctx); \ CMPIIndicationMI * \ pn##_Create_IndicationMI(CMPIBroker * brkr, CMPIContext * ctx) { \ static CMPIIndicationMI mi = { \ NULL, \ &indMIFT, \ }; \ return &mi; \ } #endif /* _CMPI_UTILS_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/colocation_constraint_provider.c000066400000000000000000000123561211477743100265400ustar00rootroot00000000000000/* * colocation_constraint_provider.c: HA_ResourceColocationConstraint provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include "cmpi_utils.h" #include "cluster_info.h" #include "constraint_common.h" static const char * PROVIDER_ID = "cim-colo"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_ColocationConstraint"; DeclareInstanceFunctions(ColocationConstraint); /********************************************** * Instance provider functions **********************************************/ static CMPIStatus ColocationConstraintCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus ColocationConstraintEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref) { CMPIStatus rc; int ret; PROVIDER_INIT_LOGGER(); ret = constraint_enum_insts(Broker, ClassName, ctx, rslt, ref, FALSE, TID_CONS_COLOCATION, &rc); return rc; } static CMPIStatus ColocationConstraintEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char ** properties) { CMPIStatus rc; int ret; PROVIDER_INIT_LOGGER(); ret = constraint_enum_insts(Broker, ClassName, ctx, rslt, ref, TRUE, TID_CONS_COLOCATION, &rc); return rc; } static CMPIStatus ColocationConstraintGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc; int ret; PROVIDER_INIT_LOGGER(); ret = constraing_get_inst(Broker, ClassName, ctx, rslt, cop, properties, TID_CONS_COLOCATION, &rc); return rc; } static CMPIStatus ColocationConstraintCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; int ret; PROVIDER_INIT_LOGGER(); ret = constraint_create_inst(Broker, ClassName, mi, ctx, rslt, cop, ci, TID_CONS_COLOCATION, &rc); return rc; } static CMPIStatus ColocationConstraintSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; int ret; PROVIDER_INIT_LOGGER(); ret = constraint_update_inst(Broker, ClassName, mi, ctx, rslt, cop, ci, properties, TID_CONS_COLOCATION, &rc); return rc; } static CMPIStatus ColocationConstraintDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; int ret; ret = constraint_delete_inst(Broker, ClassName, mi, ctx, rslt, cop, TID_CONS_COLOCATION, &rc); return rc; } static CMPIStatus ColocationConstraintExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /************************************************** * Method Provider functions *************************************************/ static CMPIStatus ColocationConstraintInvokeMethod(CMPIMethodMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, const char * method, CMPIArgs * in, CMPIArgs * out) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus ColocationConstraintMethodCleanup(CMPIMethodMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } /***************************************************** * install provider ****************************************************/ DeclareInstanceMI(ColocationConstraint, HA_ColocationConstraintProvider, Broker); DeclareMethodMI(ColocationConstraint, HA_ColocationConstraintProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/constraint_common.c000066400000000000000000000253161211477743100237640ustar00rootroot00000000000000/* * constraint_common.c: common functions for constraint providers * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include "cluster_info.h" #include "constraint_common.h" #include "cmpi_utils.h" static char SystemName [] = "LinuxHACluster"; static char SystemCrName [] = "HA_Cluster"; static CMPIInstance * make_instance_byid(CMPIBroker * broker, char * classname, CMPIObjectPath * op, char * id, uint32_t type, CMPIStatus * rc); static CMPIInstance * make_instance(CMPIBroker * broker, char * classname, CMPIObjectPath *op, struct ha_msg *cons, int type, CMPIStatus * rc); static CMPIInstance * make_instance(CMPIBroker *broker, char *classname, CMPIObjectPath *op, struct ha_msg* constraint, int type, CMPIStatus *rc) { CMPIInstance * ci = NULL; char *id; char caption[MAXLEN]; DEBUG_ENTER(); ci = CMNewInstance(broker, op, rc); if ( CMIsNullObject(ci) ) { cl_log(LOG_ERR, "%s: can't create instance", __FUNCTION__); CMSetStatusWithChars(broker, rc, CMPI_RC_ERR_FAILED, "Can't get create instance"); goto out; } id = cim_strdup(cl_get_string(constraint, "id")); if ( id == NULL ) { return NULL; } /* setting properties */ CMSetProperty(ci, "Id", id, CMPI_chars); CMSetProperty(ci, "SystemCreationClassName", SystemCrName, CMPI_chars); CMSetProperty(ci, "SystemName", SystemName, CMPI_chars); CMSetProperty(ci, "CreationClassName", classname, CMPI_chars); if ( type == TID_CONS_ORDER ) { cmpi_msg2inst(broker, ci, HA_ORDER_CONSTRAINT, constraint, rc); } else if ( type == TID_CONS_LOCATION ) { cmpi_msg2inst(broker, ci, HA_LOCATION_CONSTRAINT, constraint, rc); } else if ( type == TID_CONS_COLOCATION ) { cmpi_msg2inst(broker, ci, HA_COLOCATION_CONSTRAINT, constraint, rc); } snprintf(caption, MAXLEN, "Constraint.%s", id); CMSetProperty(ci, "Caption", caption, CMPI_chars); cim_free(id); out: DEBUG_LEAVE(); return ci; } static CMPIInstance * make_instance_byid(CMPIBroker * broker, char * classname, CMPIObjectPath * op, char * id, uint32_t type, CMPIStatus * rc) { CMPIInstance * ci; struct ha_msg *constraint; int funcid = 0; DEBUG_ENTER(); switch(type) { case TID_CONS_LOCATION: funcid=GET_LOCATION_CONSTRAINT; break; case TID_CONS_COLOCATION: funcid=GET_COLOCATION_CONSTRAINT; break; case TID_CONS_ORDER: funcid=GET_ORDER_CONSTRAINT; break; default:break; } if ( (constraint= cim_query_dispatch(funcid, id, NULL)) == NULL ) { return NULL; } ci = make_instance(broker, classname, op, constraint, type, rc); ha_msg_del(constraint); DEBUG_LEAVE(); return ci; } int constraing_get_inst(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties, uint32_t type, CMPIStatus * rc) { CMPIInstance* ci = NULL; CMPIObjectPath * op = NULL; char * consid = NULL; DEBUG_ENTER(); /* get the key from the object path */ if (( consid = CMGetKeyString(cop, "Id", rc)) == NULL ) { cl_log(LOG_ERR, "%s: Id is missing.", __FUNCTION__); return HA_FAIL; } /* create a object path */ op = CMNewObjectPath(broker, CMGetCharPtr(CMGetNameSpace(cop, rc)), classname, rc); if ( CMIsNullObject(op) ){ cl_log(LOG_ERR, "%s: Could not create object path.", __FUNCTION__); return HA_FAIL; } /* make an instance */ ci = make_instance_byid(broker, classname, op, consid, type, rc); if ( CMIsNullObject(ci) ) { cl_log(LOG_ERR, "%s: Could not create instance.", __FUNCTION__); return HA_FAIL; } /* add the instance to result */ CMReturnInstance(rslt, ci); CMReturnDone(rslt); return HA_OK; } int constraint_enum_insts(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, int need_inst, uint32_t type, CMPIStatus * rc) { char * namespace = NULL; CMPIObjectPath * op = NULL; int i, funcid = 0, len; struct ha_msg * cons; /* create object path */ namespace = CMGetCharPtr(CMGetNameSpace(ref, rc)); op = CMNewObjectPath(broker, namespace, classname, rc); if ( CMIsNullObject(op) ){ return HA_FAIL; } switch(type){ case TID_CONS_ORDER: funcid = GET_ORDER_CONS_LIST;break; case TID_CONS_LOCATION: funcid = GET_LOCATION_CONS_LIST; break; case TID_CONS_COLOCATION: funcid = GET_COLOCATION_CONS_LIST; break; default: break; } if ( ( cons = cim_query_dispatch(funcid, NULL, NULL) ) == NULL ) { return HA_FAIL; } len = cim_list_length(cons); /* for each constraint */ for ( i = 0; i < len; i++) { char * consid = cim_list_index(cons, i); if ( need_inst ) { /* if need instance, make instance an return it */ CMPIInstance * ci = NULL; ci = make_instance_byid(broker, classname, op, consid, type, rc); if ( CMIsNullObject(ci) ){ cl_log(LOG_WARNING, "%s: can not make instance", __FUNCTION__); return HA_FAIL; } cl_log(LOG_INFO, "%s: return instance", __FUNCTION__); CMReturnInstance(rslt, ci); } else { /* otherwise, just add keys to objectpath and return it */ CMAddKey(op, "Id", consid, CMPI_chars); CMAddKey(op, "SystemName", SystemName, CMPI_chars); CMAddKey(op, "SystemCreationClassName", SystemCrName, CMPI_chars); CMAddKey(op, "CreationClassName", classname, CMPI_chars); /* add object to rslt */ CMReturnObjectPath(rslt, op); } } CMReturnDone(rslt); rc->rc = CMPI_RC_OK; ha_msg_del(cons); return HA_OK; } int constraint_delete_inst(CMPIBroker * broker, char * classname, CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, uint32_t type, CMPIStatus * rc) { const char * key [] = {"Id", "CreationClassName", "SystemName", "SystemCreationClassName"}; int funcid = 0; char * id; DEBUG_ENTER(); if ((id = CMGetKeyString(cop, key[0], rc)) == NULL ) { rc->rc = CMPI_RC_ERR_FAILED; cl_log(LOG_ERR, "del_cons: can't get constraint id."); return HA_FAIL; } switch(type){ case TID_CONS_ORDER: funcid = DEL_ORDER_CONSTRAINT; break; case TID_CONS_LOCATION: funcid = DEL_LOCATION_CONSTRAINT; break; case TID_CONS_COLOCATION: funcid = DEL_COLOCATION_CONSTRAINT; break; default: cl_log(LOG_WARNING, "del_cons: Unknown type"); break; } if ( cim_update_dispatch(funcid, id, NULL, NULL) == HA_OK ) { rc->rc = CMPI_RC_OK; } else { rc->rc = CMPI_RC_ERR_FAILED; cl_log(LOG_ERR, "del_cons: cim_update return error."); } DEBUG_LEAVE(); return HA_OK; } int constraint_update_inst(CMPIBroker * broker, char * classname, CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties, uint32_t type, CMPIStatus * rc) { struct ha_msg * t=NULL; const char * key [] = {"Id", "CreationClassName", "SystemName", "SystemCreationClassName"}; char * id, *crname, *sysname, *syscrname; int ret = HA_FAIL; DEBUG_ENTER(); id = CMGetKeyString(cop, key[0], rc); crname = CMGetKeyString(cop, key[1], rc); sysname = CMGetKeyString(cop, key[2], rc); syscrname = CMGetKeyString(cop, key[3], rc); switch(type){ case TID_CONS_ORDER: t = cim_query_dispatch(GET_ORDER_CONSTRAINT, id, NULL); cmpi_inst2msg(ci, HA_ORDER_CONSTRAINT, t, rc); ret = cim_update_dispatch(UPDATE_ORDER_CONSTRAINT, NULL, t, NULL); break; case TID_CONS_LOCATION: t = cim_query_dispatch(GET_LOCATION_CONSTRAINT, id, NULL); cmpi_inst2msg(ci, HA_LOCATION_CONSTRAINT, t, rc); ret = cim_update_dispatch(UPDATE_LOCATION_CONSTRAINT, NULL, t, NULL); break; case TID_CONS_COLOCATION: t = cim_query_dispatch(GET_COLOCATION_CONSTRAINT, id, NULL); cmpi_inst2msg(ci, HA_COLOCATION_CONSTRAINT, t, rc); ret = cim_update_dispatch(UPDATE_COLOCATION_CONSTRAINT, NULL, t, NULL); break; default: break; } ha_msg_del(t); /* if update OK, return CMPI_RC_OK */ rc->rc = (ret == HA_OK)? CMPI_RC_OK : CMPI_RC_ERR_FAILED; DEBUG_ENTER(); return HA_OK; } int constraint_create_inst(CMPIBroker * broker, char * classname, CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, uint32_t type, CMPIStatus * rc) { struct ha_msg *t; int ret = HA_FAIL; DEBUG_ENTER(); if (( t = ha_msg_new(16)) == NULL ) { rc->rc = CMPI_RC_ERR_FAILED; DEBUG_LEAVE(); return HA_FAIL; } switch(type){ case TID_CONS_ORDER: cmpi_inst2msg(ci, HA_ORDER_CONSTRAINT, t, rc); ret = cim_update_dispatch(UPDATE_ORDER_CONSTRAINT, NULL, t, NULL); break; case TID_CONS_LOCATION: cmpi_inst2msg(ci, HA_LOCATION_CONSTRAINT, t, rc); ret = cim_update_dispatch(UPDATE_LOCATION_CONSTRAINT, NULL, t, NULL); break; case TID_CONS_COLOCATION: cmpi_inst2msg(ci, HA_COLOCATION_CONSTRAINT, t, rc); ret = cim_update_dispatch(UPDATE_COLOCATION_CONSTRAINT, NULL, t, NULL); break; default: break; } rc->rc = (ret==HA_OK)? CMPI_RC_OK : CMPI_RC_ERR_FAILED; ha_msg_del(t); DEBUG_LEAVE(); return ret; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/constraint_common.h000066400000000000000000000041331211477743100237630ustar00rootroot00000000000000/* * constraint_common.h: common functions for constraint providers * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef _CONSTRAINT_COMMON_H #define _CONSTRAINT_COMMON_H int constraing_get_inst(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties, uint32_t type, CMPIStatus * rc); int constraint_enum_insts(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, int need_inst, uint32_t type, CMPIStatus * rc); int delete_constraint(CMPIBroker * broker, char * classname, CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, uint32_t type, CMPIStatus * rc); int constraint_update_inst(CMPIBroker * broker, char * classname, CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties, uint32_t type, CMPIStatus * rc); int constraint_create_inst(CMPIBroker * broker, char * classname, CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, uint32_t type, CMPIStatus * rc); int constraint_delete_inst(CMPIBroker * broker, char * classname, CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, uint32_t type, CMPIStatus * rc); #endif pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/constraint_rule_provider.c000066400000000000000000000236341211477743100253560ustar00rootroot00000000000000/* * constraint_rule_provider.c: HA_LocationConstraintRule provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include "cmpi_utils.h" #include "cluster_info.h" #include "constraint_common.h" #include "utils.h" static const char * PROVIDER_ID = "cim-rule"; static char ClassName [] = "HA_LocationConstraintRule"; static CMPIBroker * Broker = NULL; DeclareInstanceFunctions(LocationConstraintRule); static struct ha_msg * find_constraint_rule(const char * consid, const char *ruleid) { struct ha_msg * constraint; int i, size = 0; struct ha_msg *rule; constraint = cim_query_dispatch(GET_LOCATION_CONSTRAINT, consid, NULL); if ( constraint == NULL ) { return NULL; } size = cim_msg_children_count(constraint); for ( i = 0; i < size; i++ ) { const char *id; rule = cim_msg_child_index(constraint, i); id = cl_get_string(rule, "id"); if ( strncmp(id, ruleid, MAXLEN) == 0 ) { rule = ha_msg_copy(rule); ha_msg_del(constraint); return rule; } } ha_msg_del(constraint); return NULL; } static CMPIInstance * constraint_rule_make_instance(CMPIObjectPath * op, char* consid, const char * ruleid, struct ha_msg *rule, CMPIStatus * rc) { char caption[MAXLEN]; CMPIInstance * ci = NULL; ci = CMNewInstance(Broker, op, rc); if ( CMIsNullObject(ci) ) { cl_log(LOG_ERR, "%s: couldn't create instance", __FUNCTION__); CMSetStatusWithChars(Broker, rc, CMPI_RC_ERR_FAILED, "Could not create instance."); return NULL; } snprintf(caption, MAXLEN, "LocationConstraintRule.%s", ruleid); CMSetProperty(ci, "Caption", caption, CMPI_chars); CMSetProperty(ci, "ConstraintId", consid, CMPI_chars); cmpi_msg2inst(Broker, ci, HA_LOCATION_CONSTRAINT_RULE, rule, rc); return ci; } static int constraint_rule_enum_insts(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, int EnumInst, CMPIStatus * rc) { char *namespace; CMPIObjectPath * op = NULL; int i, j, size = 0, rulecount = 0; char *consid = NULL, *ruleid = NULL; struct ha_msg *list, *constraint, *rule = NULL; namespace = CMGetCharPtr(CMGetNameSpace(ref, rc)); if ( namespace == NULL ) { return HA_FAIL; } list = cim_query_dispatch(GET_LOCATION_CONS_LIST, NULL, NULL); if ( list == NULL ) { goto done; } size = cim_list_length(list); for (i = 0; i < size; i++) { consid = cim_list_index(list, i); constraint = cim_query_dispatch(GET_LOCATION_CONSTRAINT, consid, NULL); if ( constraint == NULL ) { continue; } rulecount = cim_msg_children_count(constraint); for (j = 0; j < rulecount; j++){ ruleid = cim_strdup(cim_msg_child_name(constraint, j)); op = CMNewObjectPath(Broker, namespace, ClassName, rc); if ( EnumInst ) { CMPIInstance * ci = NULL; rule = cim_msg_child_index(constraint, j); ci = constraint_rule_make_instance(op, consid, ruleid, rule, rc); CMReturnInstance(rslt, ci); } else { /* enumerate instance names */ CMAddKey(op, "ConstraintId", consid, CMPI_chars); CMAddKey(op, "Id", ruleid, CMPI_chars); CMReturnObjectPath(rslt, op); } cim_free(ruleid); } ha_msg_del(constraint); } ha_msg_del(list); done: rc->rc = CMPI_RC_OK; CMReturnDone(rslt); return HA_OK; } /********************************************** * Instance provider functions **********************************************/ static CMPIStatus LocationConstraintRuleCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus LocationConstraintRuleEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); constraint_rule_enum_insts(mi, ctx, rslt, ref, FALSE, &rc); return rc; } static CMPIStatus LocationConstraintRuleEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); constraint_rule_enum_insts(mi, ctx, rslt, ref, TRUE, &rc); return rc; } static CMPIStatus LocationConstraintRuleGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIObjectPath * op; CMPIInstance * ci; CMPIStatus rc; char *consid, *id; struct ha_msg * rule; PROVIDER_INIT_LOGGER(); id = CMGetKeyString(cop, "Id", &rc); consid = CMGetKeyString(cop, "ConstraintId", &rc); op = CMNewObjectPath(Broker, CMGetCharPtr(CMGetNameSpace(cop, &rc)), ClassName, &rc); if ( CMIsNullObject(op) ){ cl_log(LOG_WARNING, "%s: can not create object path.", __FUNCTION__); CMReturnDone(rslt); return rc; } if ((rule = find_constraint_rule(consid, id)) == NULL ) { cl_log(LOG_WARNING, "%s: rule %s not found.", __FUNCTION__, id); CMReturnDone(rslt); return rc; } ci = constraint_rule_make_instance(op, consid, id, rule, &rc); if ( CMIsNullObject(ci) ) { CMReturnDone(rslt); return rc; } CMReturnInstance(rslt, ci); CMReturnDone(rslt); CMReturn(CMPI_RC_OK); } static CMPIStatus LocationConstraintRuleCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; char *id, *consid; struct ha_msg * constraint, *rule; int ret; id = CMGetKeyString(cop, "Id", &rc); consid = CMGetKeyString(cop, "ConstraintId", &rc); constraint = cim_query_dispatch(GET_LOCATION_CONSTRAINT, consid, NULL); if (constraint == NULL ) { goto done; } if ( cl_get_struct(constraint, id) != NULL ) { cl_log(LOG_ERR, "%s: rule with id %s already exists.", __FUNCTION__, id); rc.rc = CMPI_RC_ERR_FAILED; goto done; } if ( (rule = ha_msg_new(1)) == NULL ) { cl_log(LOG_ERR, "%s: alloc rule failed.", __FUNCTION__); rc.rc = CMPI_RC_ERR_FAILED; goto done; } if (cmpi_inst2msg(ci, HA_LOCATION_CONSTRAINT_RULE, rule, &rc) != HA_OK ) { rc.rc = CMPI_RC_ERR_FAILED; goto done; } ha_msg_addstruct(constraint, id, rule); ret = cim_update_dispatch(UPDATE_LOCATION_CONSTRAINT, NULL, constraint, NULL); ha_msg_del(constraint); if ( ret != HA_OK ) { rc.rc = CMPI_RC_ERR_FAILED; } done: return rc; } static CMPIStatus LocationConstraintRuleSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; char *id, *consid; struct ha_msg * constraint, *rule; int ret; id = CMGetKeyString(cop, "Id", &rc); consid = CMGetKeyString(cop, "ConstraintId", &rc); constraint = cim_query_dispatch(GET_LOCATION_CONSTRAINT, consid, NULL); if (constraint == NULL ) { goto done; } if ( (rule = ha_msg_new(1)) == NULL ) { cl_log(LOG_ERR, "%s: alloc rule failed.", __FUNCTION__); rc.rc = CMPI_RC_ERR_FAILED; goto done; } if (cmpi_inst2msg(ci, HA_LOCATION_CONSTRAINT_RULE, rule, &rc) != HA_OK ) { rc.rc = CMPI_RC_ERR_FAILED; goto done; } cl_msg_remove(constraint, id); ha_msg_addstruct(constraint, id, rule); ret = cim_update_dispatch(UPDATE_LOCATION_CONSTRAINT, NULL, constraint, NULL); ha_msg_del(constraint); if ( ret != HA_OK ) { rc.rc = CMPI_RC_ERR_FAILED; } done: return rc; } static CMPIStatus LocationConstraintRuleDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; char *id, *consid; struct ha_msg * constraint; int ret; id = CMGetKeyString(cop, "Id", &rc); consid = CMGetKeyString(cop, "ConstraintId", &rc); constraint = cim_query_dispatch(GET_LOCATION_CONSTRAINT, consid, NULL); if (constraint == NULL ) { goto done; } ret = cim_update_dispatch(DEL_LOCATION_CONSTRAINT, consid, NULL,NULL); if ( ret != HA_OK ) { rc.rc = CMPI_RC_ERR_FAILED; goto done; } cl_msg_remove(constraint, id); ret = cim_update_dispatch(UPDATE_LOCATION_CONSTRAINT, NULL, constraint, NULL); ha_msg_del(constraint); if ( ret != HA_OK ) { rc.rc = CMPI_RC_ERR_FAILED; } done: return rc; } static CMPIStatus LocationConstraintRuleExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /***************************************************** * install provider ****************************************************/ DeclareInstanceMI(LocationConstraintRule, HA_LocationConstraintRuleProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/hosted_resource_provider.c000066400000000000000000000224741211477743100253410ustar00rootroot00000000000000/* * hosted_resource_provider.c: HA_HostedResource provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include "cluster_info.h" #include "cmpi_utils.h" static const char * PROVIDER_ID = "cim-hosted-res"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_HostedResource"; static char Left [] = "Antecedent"; static char Right [] = "Dependent"; static char LeftClassName [] = "HA_ClusterNode"; static char RightClassName [] = "HA_PrimitiveResource"; static int node_host_res(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIObjectPath * node_op, CMPIObjectPath * res_op, CMPIStatus * rc); DeclareInstanceFunctions (HostedResource); DeclareAssociationFunctions(HostedResource); /* here resource can be primitive, group, clone and master */ static int node_host_res(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIObjectPath * node_op, CMPIObjectPath * res_op, CMPIStatus * rc) { char * rsc_id; char * uname; int host = FALSE; const char * running_node; struct ha_msg * msg; rsc_id = CMGetKeyString(res_op, "Id", rc); uname = CMGetKeyString(node_op, "Name", rc); /* get running node */ if ((msg = cim_query_dispatch(GET_RSC_HOST, rsc_id, NULL)) == NULL ) { cl_log(LOG_WARNING, "running node of %s is NULL", rsc_id); return FALSE; } running_node = cl_get_string(msg, "host"); /* campare running node with uname */ if ( strncmp(running_node, uname, MAXLEN) == 0 ) { host = TRUE; } ha_msg_del(msg); return host; } /********************************************** * Instance Provider Interface **********************************************/ static CMPIStatus HostedResourceCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus HostedResourceEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext* ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; if (assoc_enum_insts(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, node_host_res, NULL, 0, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus HostedResourceEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; if (assoc_enum_insts(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, node_host_res, NULL, 1, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus HostedResourceGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; if (assoc_get_inst(Broker, ClassName, ctx, rslt, cop, Left, Right, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus HostedResourceCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus HostedResourceSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus HostedResourceDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus HostedResourceExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath *ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /**************************************************** * Association ****************************************************/ static CMPIStatus HostedResourceAssociationCleanup(CMPIAssociationMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus HostedResourceAssociators(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * assoc_class, const char * result_class, const char * role, const char * result_role, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if (assoc_enum_associators(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, assoc_class, result_class, role, result_role, node_host_res, NULL, 1, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus HostedResourceAssociatorNames(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * assoc_class, const char * result_class, const char * role, const char * result_role) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if (assoc_enum_associators(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, assoc_class, result_class, role, result_role, node_host_res, NULL, 0, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus HostedResourceReferences(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * result_class, const char * role, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( assoc_enum_references(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, result_class, role, node_host_res, NULL, 1, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus HostedResourceReferenceNames(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * result_class, const char * role) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( assoc_enum_references(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, result_class, role, node_host_res, NULL, 0, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } /*********************************************** * Install MIs **********************************************/ DeclareInstanceMI(HostedResource, HA_HostedResourceProvider, Broker); DeclareAssociationMI(HostedResource, HA_HostedResourceProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/installed_software_provider.c000066400000000000000000000167561211477743100260430ustar00rootroot00000000000000/* * installed_software_provider.c: * HA_InstalledSoftwareIdentity provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include "cluster_info.h" #include "cmpi_utils.h" static const char * PROVIDER_ID = "cim-ins-sw"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_InstalledSoftwareIdentity"; static char Left [] = "System"; static char Right [] = "InstalledSoftware"; static char LeftClassName [] = "HA_Cluster"; static char RightClassName [] = "HA_SoftwareIdentity"; DeclareInstanceFunctions(InstalledSoftware); DeclareAssociationFunctions(InstalledSoftware); /********************************************** * Instance **********************************************/ static CMPIStatus InstalledSoftwareCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus InstalledSoftwareEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext* ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); assoc_enum_insts(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, NULL, NULL, FALSE, &rc); return rc; } static CMPIStatus InstalledSoftwareEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); assoc_enum_insts(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, NULL, NULL, TRUE, &rc); return rc; } static CMPIStatus InstalledSoftwareGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); assoc_get_inst(Broker, ClassName, ctx, rslt, cop, Left, Right, &rc); return rc; } static CMPIStatus InstalledSoftwareCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus InstalledSoftwareSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus InstalledSoftwareDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus InstalledSoftwareExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /**************************************************** * Association ****************************************************/ static CMPIStatus InstalledSoftwareAssociationCleanup(CMPIAssociationMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus InstalledSoftwareAssociators(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * assoc_class, const char * result_class, const char * role, const char * result_role, char ** properties) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); assoc_enum_associators(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, assoc_class, result_class, role, result_role, NULL, NULL, TRUE, &rc); return rc; } static CMPIStatus InstalledSoftwareAssociatorNames(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * assoc_class, const char * result_class, const char * role, const char * result_role) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); assoc_enum_associators(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, assoc_class, result_class, role, result_role, NULL, NULL, FALSE, &rc); return rc; } static CMPIStatus InstalledSoftwareReferences(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * result_class, const char * role, char ** properties) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); assoc_enum_references(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, result_class, role, NULL, NULL, TRUE, &rc); return rc; } static CMPIStatus InstalledSoftwareReferenceNames(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * result_class, const char * role) { CMPIStatus rc; assoc_enum_references(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, result_class, role, NULL, NULL, FALSE, &rc); return rc; } /************************************************************** * MI stub *************************************************************/ DeclareInstanceMI(InstalledSoftware, HA_InstalledSoftwareIdentityProvider, Broker); DeclareAssociationMI(InstalledSoftware, HA_InstalledSoftwareIdentityProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/instance_attrs_provider.c000066400000000000000000000222351211477743100251600ustar00rootroot00000000000000/* * instance_attr_provider.c: HA_InstanceAttributes provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include "cmpi_utils.h" #include "cluster_info.h" static const char * PROVIDER_ID = "cim-attr"; static char ClassName [] = "HA_InstanceAttributes"; static CMPIBroker * Broker = NULL; DeclareInstanceFunctions(InstanceAttributes); static struct ha_msg * find_instattrs_nvpair(const char * rscid, const char *nvid) { struct ha_msg *instattrss = NULL, *nvpair; if ((instattrss = cim_rscattrs_get(rscid)) == NULL ) { return NULL; } if ((nvpair = cim_msg_find_child(instattrss, nvid))) { nvpair = ha_msg_copy(nvpair); } ha_msg_del(instattrss); return nvpair; } static CMPIInstance * instattrs_make_instance(CMPIObjectPath * op, char* rscid, const char * nvid, struct ha_msg *nvpair, CMPIStatus * rc) { char caption[MAXLEN], id[MAXLEN]; CMPIInstance * ci = NULL; ci = CMNewInstance(Broker, op, rc); if ( CMIsNullObject(ci) ) { cl_log(LOG_ERR, "%s: couldn't create instance", __FUNCTION__); CMSetStatusWithChars(Broker, rc, CMPI_RC_ERR_FAILED, "Could not create instance."); return NULL; } /* set properties */ cmpi_msg2inst(Broker, ci, HA_INSTANCE_ATTRIBUTES, nvpair, rc); cim_debug2(LOG_INFO, "%s: rscid: %s, nvid: %s.", __FUNCTION__, rscid, nvid); snprintf(caption, MAXLEN, "InstanceAttributes.%s-%s", rscid, nvid); strncpy(id, nvid, MAXLEN); CMSetProperty(ci, "Id", id, CMPI_chars); CMSetProperty(ci, "Caption", caption, CMPI_chars); CMSetProperty(ci, "ResourceId", rscid, CMPI_chars); return ci; } static int instattrs_enum_insts(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, int EnumInst, CMPIStatus * rc) { char *namespace; CMPIObjectPath * op = NULL; char *nvid, *rscid; struct ha_msg *msg, *rsclist, *instattrs, *nvpair; int i, j, rsccount, nvcount; namespace = CMGetCharPtr(CMGetNameSpace(ref, rc)); /* all resources, including the sub resources */ if ((msg = cim_get_all_rsc_list())== NULL || (rsclist = cim_traverse_allrsc(msg)) == NULL ) { cl_log(LOG_WARNING, "%s: no resource found.", __FUNCTION__); goto done; } ha_msg_del(msg); /* for each resource */ rsccount = cim_list_length(rsclist); for (i = 0; i < rsccount; i++){ rscid = cim_list_index(rsclist, i); if (!rscid || cim_get_rsctype(rscid) != TID_RES_PRIMITIVE) { continue; } /* get the resource's instance attributes */ if ((instattrs = cim_rscattrs_get(rscid)) == NULL ){ continue; } /* for each nvpair in the attirubtes */ nvcount = cim_msg_children_count(instattrs); for (j = 0; j < nvcount; j++) { const char *const_id; if(( nvpair = cim_msg_child_index(instattrs, j)) == NULL ||(const_id = cl_get_string(nvpair, "id"))== NULL){ continue; } nvid = cim_strdup(const_id); /* create objectpath or instance */ op = CMNewObjectPath(Broker, namespace, ClassName, rc); if ( EnumInst ) { CMPIInstance * ci = NULL; ci = instattrs_make_instance(op, rscid, nvid, nvpair, rc); CMReturnInstance(rslt, ci); } else { /* enumerate instance names */ CMAddKey(op, "ResourceId", rscid, CMPI_chars); CMAddKey(op, "Id", nvid, CMPI_chars); CMReturnObjectPath(rslt, op); } cim_free(nvid); } } done: rc->rc = CMPI_RC_OK; CMReturnDone(rslt); return HA_OK; } /********************************************** * Instance provider functions **********************************************/ static CMPIStatus InstanceAttributesCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus InstanceAttributesEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); instattrs_enum_insts(mi, ctx, rslt, ref, FALSE, &rc); return rc; } static CMPIStatus InstanceAttributesEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); instattrs_enum_insts(mi, ctx, rslt, ref, TRUE, &rc); return rc; } static CMPIStatus InstanceAttributesGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIObjectPath * op; CMPIInstance * ci; CMPIStatus rc; char *rscid, *id, *namespace; struct ha_msg *nvpair = NULL; PROVIDER_INIT_LOGGER(); id = CMGetKeyString(cop, "Id", &rc); rscid = CMGetKeyString(cop, "ResourceId", &rc); /* create objectpath for the instance */ namespace = CMGetCharPtr(CMGetNameSpace(cop, &rc)); op = CMNewObjectPath(Broker, namespace, ClassName, &rc); if ( CMIsNullObject(op) ){ cl_log(LOG_WARNING, "inst_attr: can not create object path."); CMReturnDone(rslt); return rc; } /* get the nvpair */ if ((nvpair = find_instattrs_nvpair(rscid, id)) == NULL ) { cl_log(LOG_ERR, "%s: can't find instattrs for %s", __FUNCTION__, id); CMReturnDone(rslt); rc.rc = CMPI_RC_ERR_FAILED; return rc; } /* make instance */ ci = instattrs_make_instance(op, rscid, id, nvpair, &rc); if ( CMIsNullObject(ci) ) { CMReturnDone(rslt); return rc; } ha_msg_del(nvpair); CMReturnInstance(rslt, ci); CMReturnDone(rslt); CMReturn(CMPI_RC_OK); } static CMPIStatus InstanceAttributesCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; struct ha_msg *nvpair; char *id, *rscid; id = CMGetKeyString(cop, "Id", &rc); rscid = CMGetKeyString(cop, "ResourceId", &rc); /* create an empty operatoin */ if ((nvpair = ha_msg_new(16)) == NULL ) { cl_log(LOG_ERR, "%s: nvpair alloc failed.", __FUNCTION__); rc.rc = CMPI_RC_ERR_FAILED; goto done; } cmpi_inst2msg(ci, HA_INSTANCE_ATTRIBUTES, nvpair, &rc); /* add attr to resource */ if (cim_update_attrnvpair(rscid, id, nvpair) != HA_OK ) { rc.rc = CMPI_RC_ERR_FAILED; ha_msg_del(nvpair); goto done; } ha_msg_del(nvpair); rc.rc = CMPI_RC_OK; done: return rc; } static CMPIStatus InstanceAttributesSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; struct ha_msg *nvpair; char *id, *rscid; int ret; id = CMGetKeyString(cop, "Id", &rc); rscid = CMGetKeyString(cop, "ResourceId", &rc); if ( (nvpair = find_instattrs_nvpair(rscid, id)) == NULL ) { cl_log(LOG_ERR, "%s: failed to get nvpair.", __FUNCTION__); rc.rc = CMPI_RC_ERR_FAILED; goto done; } cmpi_inst2msg(ci, HA_INSTANCE_ATTRIBUTES, nvpair, &rc); cim_debug_msg(nvpair, "%s: nvpair from inputs:", __FUNCTION__); if ( (ret = cim_update_attrnvpair(rscid, id, nvpair)) == HA_OK ) { rc.rc = CMPI_RC_OK; } else { rc.rc = CMPI_RC_ERR_FAILED; } ha_msg_del(nvpair); done: return rc; } static CMPIStatus InstanceAttributesDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; char *id, *rscid; id = CMGetKeyString(cop, "Id", &rc); rscid = CMGetKeyString(cop, "ResourceId", &rc); if ( cim_remove_attrnvpair(rscid, id) == HA_OK ) { rc.rc = CMPI_RC_OK; } else { rc.rc = CMPI_RC_ERR_FAILED; } return rc; } static CMPIStatus InstanceAttributesExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /***************************************************** * install provider ****************************************************/ DeclareInstanceMI(InstanceAttributes, HA_InstanceAttributesProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/location_constraint_provider.c000066400000000000000000000107211211477743100262100ustar00rootroot00000000000000/* * location_constraint_provider.c: HA_ResourceLocationConstraint provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include "cmpi_utils.h" #include "cluster_info.h" #include "constraint_common.h" static const char * PROVIDER_ID = "constraint"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_LocationConstraint"; DeclareInstanceFunctions(LocationConstraint); /********************************************** * Instance provider functions **********************************************/ static CMPIStatus LocationConstraintCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus LocationConstraintEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); constraint_enum_insts(Broker, ClassName, ctx, rslt, ref, FALSE, TID_CONS_LOCATION, &rc); return rc; } static CMPIStatus LocationConstraintEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char ** properties) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); constraint_enum_insts(Broker, ClassName, ctx, rslt, ref, TRUE, TID_CONS_LOCATION, &rc); return rc; } static CMPIStatus LocationConstraintGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); constraing_get_inst(Broker, ClassName, ctx, rslt, cop, properties, TID_CONS_LOCATION, &rc); return rc; } static CMPIStatus LocationConstraintCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); constraint_create_inst(Broker, ClassName, mi, ctx, rslt, cop, ci, TID_CONS_LOCATION, &rc); return rc; } static CMPIStatus LocationConstraintSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; int ret; PROVIDER_INIT_LOGGER(); ret = constraint_update_inst(Broker, ClassName, mi, ctx, rslt, cop, ci, properties, TID_CONS_LOCATION, &rc); return rc; } static CMPIStatus LocationConstraintDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; int ret; ret = constraint_delete_inst(Broker, ClassName, mi, ctx, rslt, cop, TID_CONS_LOCATION, &rc); return rc; } static CMPIStatus LocationConstraintExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /***************************************************** * install provider ****************************************************/ DeclareInstanceMI(LocationConstraint, HA_LocationConstraintProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/masterslave_resource_provider.c000066400000000000000000000126731211477743100264010ustar00rootroot00000000000000/* * masterslave_resource_provider.c: HA_MasterSlaveResource provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include "cmpi_utils.h" #include "cluster_info.h" #include "resource_common.h" static const char * PROVIDER_ID = "cim-res-ms"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_MasterSlaveResource"; DeclareInstanceFunctions(MasterSlaveResource); /********************************************** * Instance provider functions **********************************************/ static CMPIStatus MasterSlaveResourceCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMPIStatus rc; resource_cleanup(Broker, ClassName, mi, ctx, TID_RES_MASTER, &rc); CMReturn(CMPI_RC_OK); } static CMPIStatus MasterSlaveResourceEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); resource_enum_insts(Broker, ClassName, ctx, rslt, ref, FALSE, TID_RES_MASTER, &rc); return rc; } static CMPIStatus MasterSlaveResourceEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char ** properties) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); resource_enum_insts(Broker, ClassName, ctx, rslt, ref, TRUE, TID_RES_MASTER, &rc); return rc; } static CMPIStatus MasterSlaveResourceGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); resource_get_inst(Broker, ClassName, ctx, rslt, cop, properties, TID_RES_MASTER, &rc); return rc; } static CMPIStatus MasterSlaveResourceCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); resource_create_inst(Broker, ClassName, ctx, rslt, cop, ci, TID_RES_MASTER, &rc); return rc; } static CMPIStatus MasterSlaveResourceSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); resource_update_inst(Broker, ClassName, ctx, rslt, cop, ci, properties, TID_RES_MASTER, &rc); return rc; } static CMPIStatus MasterSlaveResourceDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); resource_del_inst(Broker, ClassName, ctx, rslt, cop, &rc); return rc; } static CMPIStatus MasterSlaveResourceExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /************************************************ * method ***********************************************/ static CMPIStatus MasterSlaveResourceInvokeMethod(CMPIMethodMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, const char * method_name, CMPIArgs * in, CMPIArgs * out) { CMPIString * classname = NULL; CMPIStatus rc = {CMPI_RC_OK, NULL}; int ret = 0; PROVIDER_INIT_LOGGER(); classname = CMGetClassName(ref, &rc); if(strcasecmp(CMGetCharPtr(classname), ClassName) == 0 && strcasecmp(METHOD_ADD_RESOURCE, method_name) == 0 ){ ret = resource_add_subrsc(Broker, ClassName, ctx, rslt, ref, TID_RES_GROUP, in, out, &rc); } CMReturnData(rslt, &ret, CMPI_uint32); CMReturnDone(rslt); CMReturn(CMPI_RC_OK); } static CMPIStatus MasterSlaveResourceMethodCleanup(CMPIMethodMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } /***************************************************** * install provider ****************************************************/ DeclareInstanceMI(MasterSlaveResource, HA_MasterSlaveResourceProvider, Broker); DeclareMethodMI(MasterSlaveResource, HA_MasterSlaveResourceProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/mgmt_client.c000066400000000000000000000117521211477743100225310ustar00rootroot00000000000000/* * mgmt_client.c: mgmt library client * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include "mgmt_client.h" #define LIB_INIT_ALL (ENABLE_LRM|ENABLE_CRM) #undef DEBUG_ENTER #undef DEBUG_LEAVE #define DEBUG_ENTER() #define DEBUG_LEAVE() const char * module_name = "cim"; pthread_mutex_t client_mutex = PTHREAD_MUTEX_INITIALIZER; int mgmt_lib_initialize(void) { init_mgmt_lib(module_name, LIB_INIT_ALL); return HA_OK; } void mgmt_lib_finalize(void) { final_mgmt_lib(); return; } MClient * mclient_new (void) { MClient * client; /* lib must be init before every thing, otherwise mgmt_malloc ... will not be set to malloc... */ mgmt_lib_initialize(); client = (MClient *)cim_malloc(sizeof(MClient)); if ( client == NULL ) { cl_log(LOG_ERR, "mclient_new: failed to malloc client."); return NULL; } memset(client, 0, sizeof(MClient)); client->cmnd = NULL; client->rdata = NULL; client->rlen = 0; return client; } MClient * mclient_new_with_cmnd(const char * type, ... ) { MClient * client; va_list ap; if ( ( client = mclient_new()) == NULL ) { cl_log(LOG_ERR, "mclient_new_with_cmnd: can't alloc client."); return NULL; } /* alloc msg */ mclient_cmnd_append(client, type); va_start(ap, type); while (1) { char * arg = va_arg(ap, char *); if ( arg == NULL ) { break; } mclient_cmnd_append(client, arg); } va_end(ap); return client; } void mclient_free(void * c) { MClient * client = (MClient *)c; if ( client == NULL ) { return; } if ( client->rdata ) { mgmt_del_args(client->rdata); } if (client->cmnd ) { mgmt_del_msg(client->cmnd); } cim_free(client); /* cleanup lib */ mgmt_lib_finalize(); } int mclient_cmnd_new(MClient * client, const char * type, ...) { va_list ap; int rc = HA_FAIL; if ( client->cmnd ) { mgmt_del_msg(client->cmnd); client->cmnd = NULL; } /* alloc msg */ mclient_cmnd_append(client, type); va_start(ap, type); while (1) { char * arg = va_arg(ap, char *); if ( arg == NULL ) { break; } mclient_cmnd_append(client, arg); } va_end(ap); return rc; } int mclient_cmnd_append(MClient * client, const char * cmnd) { if (client->cmnd == NULL ) { client->cmnd = mgmt_new_msg(cmnd, NULL); } else { client->cmnd = mgmt_msg_append(client->cmnd, cmnd); } return HA_OK; } int mclient_process(MClient * client) { char * result; int n, rc; char ** args = NULL; pthread_mutex_lock(&client_mutex); result = process_msg(client->cmnd); pthread_mutex_unlock(&client_mutex); if ( result == NULL ) { cl_log(LOG_ERR, "mclient_process: failed to process: %s", client->cmnd); rc = MC_ERROR; goto exit2; } cl_log(LOG_INFO, "%s: cmnd: [%s], result: [%s].", __FUNCTION__, client->cmnd, result); if ( ! mgmt_result_ok(result) ) { cl_log(LOG_WARNING, "mclient_process: client return \'failed\'."); cl_log(LOG_WARNING, "mclient_process: cmnd %s", client->cmnd); cl_log(LOG_WARNING, "mclient_process: %s", result); rc = MC_FAIL; goto exit1; } /* free rdata if not NULL */ if ( client->rdata ) { mgmt_del_args(client->rdata); } client->rlen = 0; client->rdata = NULL; /* parse args */ if ( ( args = mgmt_msg_args(result, &n) ) == NULL ) { cl_log(LOG_ERR, "do_process_cmnd: parse args failed."); rc = MC_ERROR; goto exit1; } client->rlen = n - 1; client->rdata = args; rc = MC_OK; exit1: mgmt_del_msg(result); exit2: return rc; } char * mclient_nth_value(MClient * client, uint32_t index) { if ( client == NULL ||client->rdata == NULL) { cl_log(LOG_ERR, "mclient_nth_value: parameter error."); return NULL; } if ( index >= client->rlen ) { cl_log(LOG_ERR, "mclient_nth_value: index:%d, len:%d.", index, client->rlen); return NULL; } /* cl_log(LOG_INFO, "mclient_nth_value: got value %u:%s", index, client->rdata[index + 1]); */ return client->rdata[index + 1]; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/mgmt_client.h000066400000000000000000000053371211477743100225400ustar00rootroot00000000000000/* * mgmt_client.c: mgmt library client * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef _MGMT_CLIENT_H #define _MGMT_CLIENT_H #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include #include #include #include #include #include #include "utils.h" #define Arg1(a) a, NULL #define Arg2(a,b) a, b, NULL #define Arg3(a,b,c) a, b, c, NULL #define Arg4(a,b,c,d) a, b, c, d, NULL #define Arg5(a,b,c,d,e) a, b, c, d, e, NULL #define Arg6(a,b,c,d,e,f) a, b, c, d, e, f, NULL #define mclient_makeup_param(a,b) \ ({ char param[MAXLEN] = ""; \ strncat(param, a, \ sizeof(param)-strlen(param)-1); \ strncat(param, "\n", \ sizeof(param)-strlen(param)-1); \ strncat(param, b, \ sizeof(param)-strlen(param)-1); \ param; \ }) #define mclient_new_and_process(cmnd, arg...) \ ({ MClient * client = mclient_new_with_cmnd(cmnd, ##arg); \ if ( client ){ \ if ( mclient_process(client) != HA_OK \ || client->rlen == 0){ \ mclient_free(client); \ client = NULL; \ cl_log(LOG_ERR,"mclient_new_and_process"\ ":process error."); \ } \ } \ client; \ }) typedef struct mgmt_client { char * cmnd; /* cmnd */ char ** rdata; /* result */ int rlen; /* result length */ } MClient; #define MC_OK 0 #define MC_FAIL -1 #define MC_ERROR -2 MClient * mclient_new(void); MClient * mclient_new_with_cmnd(const char * type, ...); int mclient_cmnd_new(MClient * client, const char * type, ...); int mclient_cmnd_append(MClient * client, const char * cmnd); int mclient_process(MClient * client); char * mclient_nth_value(MClient * client, uint32_t index); char * mclient_nth_key(MClient * client, uint32_t index); void mclient_free(void * client); int mgmt_lib_initialize(void); void mgmt_lib_finalize(void); #endif pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/mof/000077500000000000000000000000001211477743100206365ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/mof/.cvsignore000066400000000000000000000001471211477743100226400ustar00rootroot00000000000000Makefile.in Makefile .deps .libs *.la *.lo .*.swp *.beam register_providers.sh unregister_providers.sh pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/mof/LinuxHA.fig000066400000000000000000000150071211477743100226400ustar00rootroot00000000000000#FIG 3.2 Portrait Center Metric A4 100.000000 Single -2 1200 2 0 32 #ffffff 6 0 0 0 0 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 10181 1228 13535 1228 13535 2362 10181 2362 10181 1228 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 10181 1228 13535 1228 13535 2362 10181 2362 10181 1228 4 1 0 0 0 16 28.452756 0.0 6 0.0 0.0 11858 1700 LinuxHA_Cluster\001 4 1 0 0 0 16 28.452756 0.0 6 0.0 0.0 11858 2173 from CIM_Cluster\001 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 10181 2362 13535 2362 13535 2551 10181 2551 10181 2362 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 10181 2362 13535 2362 13535 2551 10181 2551 10181 2362 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 10181 2551 13535 2551 13535 2740 10181 2740 10181 2551 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 10181 2551 13535 2551 13535 2740 10181 2740 10181 2551 -6 6 0 0 0 0 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 16606 5480 21755 5480 21755 6614 16606 6614 16606 5480 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 16606 5480 21755 5480 21755 6614 16606 6614 16606 5480 4 1 0 0 0 16 28.452756 0.0 6 0.0 0.0 19181 5952 LinuxHA_SoftwareIdentity\001 4 1 0 0 0 16 28.452756 0.0 6 0.0 0.0 19181 6425 from CIM_SoftwareIdentity\001 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 16606 6614 21755 6614 21755 6803 16606 6803 16606 6614 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 16606 6614 21755 6614 21755 6803 16606 6803 16606 6614 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 16606 6803 21755 6803 21755 6992 16606 6992 16606 6803 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 16606 6803 21755 6803 21755 6992 16606 6992 16606 6803 -6 6 0 0 0 0 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 9425 7653 14338 7653 14338 8787 9425 8787 9425 7653 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 9425 7653 14338 7653 14338 8787 9425 8787 9425 7653 4 1 0 0 0 16 28.452756 0.0 6 0.0 0.0 11881 8125 LinuxHA_ClusterNode\001 4 1 0 0 0 16 28.452756 0.0 6 0.0 0.0 11881 8598 from CIM_ComputerSystem\001 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 9425 8787 14338 8787 14338 8976 9425 8976 9425 8787 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 9425 8787 14338 8787 14338 8976 9425 8976 9425 8787 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 9425 8976 14338 8976 14338 9165 9425 9165 9425 8976 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 9425 8976 14338 8976 14338 9165 9425 9165 9425 8976 -6 6 0 0 0 0 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 4157 10346 9307 10346 9307 11480 4157 11480 4157 10346 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 4157 10346 9307 10346 9307 11480 4157 11480 4157 10346 4 1 0 0 0 16 28.452756 0.0 6 0.0 0.0 6732 10818 LinuxHA_ClusterResource\001 4 1 0 0 0 16 28.452756 0.0 6 0.0 0.0 6732 11291 from CIM_Service\001 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 4157 11480 9307 11480 9307 11669 4157 11669 4157 11480 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 4157 11480 9307 11480 9307 11669 4157 11669 4157 11480 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 4157 11669 9307 11669 9307 11858 4157 11858 4157 11669 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 4157 11669 9307 11669 9307 11858 4157 11858 4157 11669 -6 6 0 0 0 0 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 3002 14451 10490 14451 10490 15113 3002 15113 3002 14451 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 3002 14451 10490 14451 10490 15113 3002 15113 3002 14451 4 1 0 0 0 16 28.452756 0.0 6 0.0 0.0 6746 14924 LinuxHA_ClusterResourceInstanceAttr\001 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 3002 15113 10490 15113 10490 15302 3002 15302 3002 15113 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 3002 15113 10490 15113 10490 15302 3002 15302 3002 15113 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 3002 15302 10490 15302 10490 15491 3002 15491 3002 15302 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 3002 15302 10490 15302 10490 15491 3002 15491 3002 15302 -6 6 0 0 0 0 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 14931 10601 21238 10601 21238 11262 14931 11262 14931 10601 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 14931 10601 21238 10601 21238 11262 14931 11262 14931 10601 4 1 0 0 0 16 28.452756 0.0 6 0.0 0.0 18085 11074 LinuxHA_ClusterResourceGroup\001 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 14931 11262 21238 11262 21238 11451 14931 11451 14931 11262 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 14931 11262 21238 11262 21238 11451 14931 11451 14931 11262 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 14931 11451 21238 11451 21238 11640 14931 11640 14931 11451 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 14931 11451 21238 11451 21238 11640 14931 11640 14931 11451 -6 6 0 0 0 0 2 1 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 4 14931 10932 12119 10932 12119 10913 9307 10913 4 0 0 0 0 12 22.762205 0.0 6 0.0 0.0 12166 10851 LinuxHA_SubResource\001 -6 6 0 0 0 0 2 1 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 18085 11640 18085 13033 21761 13033 21761 10932 21238 10932 4 1 0 0 0 12 22.762205 0.0 6 0.0 0.0 19923 12962 LinuxHA_SubGroup\001 -6 6 0 0 0 0 2 1 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 4 6732 11858 6732 13222 6746 13222 6746 14451 4 1 0 0 0 12 22.762205 0.0 6 0.0 0.0 6739 13151 LinuxHA_ClusterResourceInstance\001 -6 6 0 0 0 0 2 1 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 4 13535 1795 14037 1795 14037 6047 16606 6047 4 0 0 0 0 12 22.762205 0.0 6 0.0 0.0 14084 3850 LinuxHA_InstalledSoftwareIdentity(CIM_InstalledSoftwareIdentity)\001 -6 6 0 0 0 0 2 1 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 4 11858 2740 11858 5196 11881 5196 11881 7653 4 1 0 0 0 12 22.762205 0.0 6 0.0 0.0 11870 5125 LinuxHA_ParticipatingNode(CIM_ParticipatingCS)\001 -6 6 0 0 0 0 2 1 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 3 9425 8220 6732 8220 6732 10346 4 1 0 0 0 12 22.762205 0.0 6 0.0 0.0 8078 8149 LinuxHA_HostedResource(CIM_HostedService)\001 -6 6 0 0 0 0 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 3010 5462 8396 5462 8396 6596 3010 6596 3010 5462 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 3010 5462 8396 5462 8396 6596 3010 6596 3010 5462 4 1 0 0 0 16 28.452756 0.0 6 0.0 0.0 5703 5935 LinuxHA_ClusteringService\001 4 1 0 0 0 16 28.452756 0.0 6 0.0 0.0 5703 6407 from CIM_ClusteringService\001 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 3010 6596 8396 6596 8396 6785 3010 6785 3010 6596 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 3010 6596 8396 6596 8396 6785 3010 6785 3010 6596 2 3 0 1 32 32 0 -1 20 0.000000 0 0 0 0 0 5 3010 6785 8396 6785 8396 6974 3010 6974 3010 6785 2 3 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 5 3010 6785 8396 6785 8396 6974 3010 6974 3010 6785 -6 6 0 0 0 0 2 1 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 3 10181 1795 5703 1795 5703 5462 4 1 0 0 0 12 22.762205 0.0 6 0.0 0.0 7942 1724 LinuxHA_HostedClusterService(CIM_HostedClusterService)\001 -6 6 0 0 0 0 2 1 0 1 0 0 0 0 -1 0.000000 0 0 0 0 0 3 14338 8220 18085 8220 18085 10601 4 1 0 0 0 12 22.762205 0.0 6 0.0 0.0 16211 8149 LinuxHA_HostedResourceGroup\001 -6 pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/mof/LinuxHA.mof000066400000000000000000000432471211477743100226630ustar00rootroot00000000000000/* * LinuxHA.mof : CIM MOF file * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ //------------------------------------------------- // HA_Cluster //------------------------------------------------- [ Provider("cmpi:HA_ClusterProvider") ] class HA_Cluster : CIM_Cluster { [ Description("The heartbeat version")] string HBVersion; //******************************************** // Configuration directives // refer to http://wiki.linux-ha.org/ha_2ecf for details //********************************************* [ Description( "The apiauth directive specifies what users and/or groups" "are allowed to connect to a specific API group name") ] string APIAuth []; string NiceFailBack; [ Description( "Determins whether a resource will automatically fail back to" "its primary node, or remain on whatever the node is serving." "Possible values are: on, off, legacy.") ] string AutoFailBack; [ Description ( "The speed for serial communications" ) ] string BaudRate; [ Description( "Which interfaces Heartbeat sends UDP broadcast traffic on") ] string BroadCastPath; [ Description( "The time Heartbeat will reconnect to the logging daemon if" "the connection between Heartbeat and the logging daemon is " "broken") ] string ConnLogdTime = "60s"; [ Description ( "Making core dump" ) ] string CoreDump; [ Description( "Whether Heartbeat should run the 1.x-style cluster manager " "or the 2.x-style cluster manager that supports more than 2 " "nodes" ) ] string WithCrm; [ Description( "How quickly Heartbeat should decide that a ping node in a " "cluster is dead") ] string DeadPing; [ Description( "How quickly Heartbeat should decide that a node in a " "cluster is dead") ] string DeadTime; [ Description ( "The Level of debugging" ) ] string DebugLevel; [ Description ( "The file Heartbeat will write debug messages to" ) ] string DebugFile; [ Description ( "Declare fiber channel devices as PingNodes to " "Heartbeat" ) ] string Aping; [ Description( "How Heartbeat should compute its current generation number " "for communications") ] string GenMethod = "file"; [ Description( "Controls how many nodes a packet can be forwarded through " "before it is thrown away in the worst case") ] string HOPFudge; [ Description( "The time that it takes to declare a cluster node dead when " "Heartbeat is first started") ] string InitDead; [ Description( "The interval between heartbeat packets") ] string KeepAlive; [ Description( "Which syslog logging facility it should use for logging " "its messages") ] string LogFacility; [ Description( "Configures a log file. All non-debug messages from " "Heartbeat will go into this file" ) ] string LogFile; [ Description("Configure a multicast communication path")] string MultiCastPath; [ Description ( "The format Heartbeat uses in wire, classic or " "netstring" ) ] string MsgFmt = "classic"; [ Description("What machines are in the cluster")] string Node []; [ Description("Declare PingNodes to Heartbeat")] string PingNode []; [ Description("Declare PingNodes to Heartbeat")] string PingGroup []; [ Description( "The realtime directive specifies whether or not Heartbeat " "should try and take advantage of the operating system's " "realtime scheduling features. ") ] string RealTime; [ Description( "specify a program to run and monitor while it runs") ] string Respawn; [ Description ("specifies Heartbeat's realtime priority" ) ] string RTPriority; [ Description ( "configure serial communication path" ) ] string SerialPath; [ Description ( "onfigure Heartbeat's (release 1), STONITH " "configuration" ) ] string Stonith; [ Description ( "onfigure Heartbeat's (release 1), STONITH " "configuration" ) ] string StonithHost; [ Description( "configures Heartbeat to communicate over a UDP " "unicast communications link") ] string UniCastPath; [ Description("specifies port for UDP communication")] string UDPPort; [ Description( "the directive to determine whether heartbeats use logging " "daemon or not" ) ] string UseLogd; [ Description( "how quickly Heartbeat should issue a \"late heartbeat\" " "warning" ) ] string WarnTime; [ Description("configure watchdog device")] string WatchdogTimer; string NormalPoll; string CoreRootDir; string LogBadPack; /* Authentication config */ [ Description("Authentication method"), ValueMap { "0", "1", "2" }, Values { "sha1", "md5", "crc" } ] uint32 AuthMethod; string AuthKey; /* CRM config */ string TransitionIdleTimeout; string SymmetricCluster; string StonithEnabled; string NoQuorumPolicy; string DefaultResourceStickiness; string HaveQuorum; /* methods */ /* RequestStateChange */ }; //---------------------------------------- // HA_SoftwareIdentity //---------------------------------------- [ Provider("cmpi:HA_SoftwareIdentityProvider") ] class HA_SoftwareIdentity : CIM_SoftwareIdentity { [ Override ("InstanceID") ] string InstanceID; [ Override ("MajorVersion") ] uint16 MajorVersion; [ Override ("MinorVersion") ] uint16 MinorVersion; [ Override ("RevisionNumber") ] uint16 RevisionNumber; [ Override ("BuildNumber") ] uint16 BuildNumber; [ Override ("VersionString") ] string VersionString; }; //-------------------------------------------------- // Association: HA_InstallSoftwareIdentity //-------------------------------------------------- [ Association, Provider ( "cmpi:HA_InstalledSoftwareIdentityProvider" ) ] class HA_InstalledSoftwareIdentity : CIM_InstalledSoftwareIdentity { [ Key, Override ( "System" ) ] HA_Cluster REF System; [ Key, Override ( "InstalledSoftware" ) ] HA_SoftwareIdentity REF InstalledSoftware; }; /*===========================================================================*/ //---------------------------------------- // ClusterNode //---------------------------------------- [ Provider ( "cmpi:HA_ClusterNodeProvider" ) ] class HA_ClusterNode : CIM_ComputerSystem { [ Override ( "Name" ), Description ("Node's uname") ] string Name; string OnLine; string Unclean; string Status; string IsDC; string Standby; string Unclean; string Shutdown; string ExpectedUp; string NodePing; }; //------------------------------------------------------------------- // HA_ClusterAbstractResource, Primitive Resource or ReousrceGroup //------------------------------------------------------------------- /* this class inherit from CIM_Service originally */ [ Description ( "Cluster resource class") /* ,Provider("cmpi:HA_ResourceProvider") */ ] class HA_ClusterResource { [ Key, Description("Group id, resource name, etc.") ] string Id; [ Key, Description("ClassName that created the instance.") ] string CreationClassName; [ Key, Description("Always LinuxHACluster.") ] string SystemName = "LinuxHACluster"; [ Key, Description("Always HA_Cluster") ] string SystemCreationClassName = "HA_Cluster"; [ Description ("Status of the resource") ] string ResourceStatus; /* running or not running */ /* DTD1.0/Annotated */ string Description; string IsManaged = "true"; /* true|false */ string OnStopFail; /* ignore|stonith|block */ string RestartType = "ignore"; /* ignore|restart */ string MultipleActive = "stop_start"; /* stop_start|stop_only|block */ string ResourceStickiness = "0"; /* 0|INFINITY|-INFINITY */ string StartPreRep; /* nothing|quorum|fencing */ string Caption; string Enabled = "false"; /* uint32 AddOperation( [IN, Description("Resource to be added") ] HA_Operation REF Operation); */ }; //---------------------------------------- // HA_PrimitiveResource //---------------------------------------- [ Description ( "LinuxHA cluster resource class" ), Provider("cmpi:HA_PrimitiveResourceProvider") ] class HA_PrimitiveResource : HA_ClusterResource { string ResourceClass = "ocf"; string Type; string Provider = "heartbeat"; string HostingNode; /* string InstanceAttributes []; */ }; //------------------------------------------------ // HA_ResourceGroup //------------------------------------------------ [ Provider("cmpi:HA_ResourceGroupProvider") ] class HA_ResourceGroup : HA_ClusterResource { uint32 AddPrimitiveResource( [IN, Description("Resource to be added") ] HA_PrimitiveResource REF Resource); }; //---------------------------------------- // HA_ResrouceClone //---------------------------------------- [ Provider("cmpi:HA_ResourceCloneProvider") ] class HA_ResourceClone : HA_ClusterResource { string Notify; string Ordered; string Interleave; string CloneMax; string CloneNodeMax; uint32 AddResource( [IN, Description("Resource to be added") ] HA_Resource REF Resource); }; //------------------------------------------------ // HA_ResourceMasterSlave //------------------------------------------------ [ Provider("cmpi:HA_MasterSlaveResourceProvider") ] class HA_MasterSlaveResource : HA_ClusterResource { string CloneMax; string CloneNodeMax; string MaxMasters; string MaxNodeMasters; uint32 AddResource( [IN, Description("Resource to be added") ] HA_Resource REF Resource); }; //---------------------------------------- // HA_InstanceAttributes //---------------------------------------- [ Provider("cmpi:HA_InstanceAttributesProvider") ] class HA_InstanceAttributes { [ Key ] string Id; [ Key ] string ResourceId; string Name; string Value; string Caption; }; //---------------------------------------- // Association, HA_AttributesOfResource //---------------------------------------- [ Association, Aggregation, Provider ("cmpi:HA_AttributesOfResourceProvider") ] class HA_AttributesOfResource { [ Key, Aggregate, Description("Resource") ] HA_PrimitiveResource REF Resource; [ Key, Description("InstanceAttributes") ] HA_InstanceAttributes REF InstanceAttributes; }; //---------------------------------------- // HA_Operation //---------------------------------------- [ Provider("cmpi:HA_OperationProvider") ] class HA_Operation { [ Key, Description ("This operation's Id.") ] String Id; [ Key, Description ("The resource that this operation belongs to") ] String ResourceId; [ Description ("The name of the operation") ] string Name = "start|stop|monitor"; /* start|stop|monitor */ string Description; [ Description ("Operation interval, only applies to monitor") ] string Interval = "10s"; [ Description ("The maximum period of time before considering " "the action failed") ] string Timeout; [ Description ("What conditions need to be met before this action " "can be run") ] string PreReq; /* nothing|quorum|fencing */ [ Description ("The action to take if this action fails") ] string OnFail; /* nothing|block|stop|fence */ string Enabled = "true"; string Caption; }; //---------------------------------------- // Association, HA_OperationOnResource //---------------------------------------- [ Association, Aggregation, Provider ("cmpi:HA_OperationOnProvider") ] class HA_OperationOnResource { [ Key, Description("Resource") ] HA_PrimitiveResource REF Resource; [ Key, Description("Operation") ] HA_Operation REF Operation; }; //------------------------------------------------ // HA_ResourceConstraint, Abstract //------------------------------------------------ class HA_ResourceConstraint { [ Key, Description (" Id ") ] string Id; [ Key ] string CreationClassName; [ Key ] string SystemName; [ Key ] string SystemCreationClassName; string Caption; }; //------------------------------------------------ // HA_OrderConstraint //------------------------------------------------ /* rsc_order constraint */ [ Provider ("cmpi:HA_OrderConstraintProvider" ) ] class HA_OrderConstraint : HA_ResourceConstraint { string From; string OrderType; string To; }; //------------------------------------------------ // HA_ColocationConstraint //------------------------------------------------ /* rsc_colocation constraint */ [ Provider ("cmpi:HA_ColocationConstraintProvider" ) ] class HA_ColocationConstraint : HA_ResourceConstraint { string From; string To; string Score; }; //------------------------------------------------ // HA_LocationConstraint //------------------------------------------------ /* rsc_location constraint */ [ Provider ("cmpi:HA_LocationConstraintProvider" ) ] class HA_LocationConstraint: HA_ResourceConstraint { string Resource; string Score; }; [ Provider ("cmpi:HA_LocationConstraintRuleProvider" ) ] class HA_LocationConstraintRule { [ Key ] string Id; [ Key ] string ConstraintId; string Attribute; string Operation; string Value; string Caption; }; [ Association, Aggregation, Provider ("cmpi:HA_RuleOfLocationConstraintProvider" ) ] class HA_RuleOfLocationConstraint { [Key] HA_LocationConstraint REF Constraint; [Key] HA_LocationConstraintRule REF Rule; }; //----------------------------------------------- // Association, HA_SubResource //----------------------------------------------- [ Association, Aggregation, Provider ( "cmpi:HA_SubResourceProvider" ) ] class HA_SubResource { [ Key, Aggregate, Description ( "Resource Group/Clone/Master" ) ] HA_ClusterResource REF Antecedent; [ Key, Description ( "SubResource or SubResourceGroup" ) ] HA_ClusterResource REF Dependent; }; //----------------------------------------- // Association, HA_ParticipatingNode //----------------------------------------- [ Association, Provider("cmpi:HA_ParticipatingNodeProvider") ] class HA_ParticipatingNode : CIM_ParticipatingCS{ [ Override ("Dependent"), Description ("The LinuxHA Cluster.") ] HA_Cluster REF Dependent; [ Override ("Antecedent"), Description ("The LinuxHA Node.") ] HA_ClusterNode REF Antecedent; }; //------------------------------------------- // Assocition, HA_HostedResource //------------------------------------------- [ Association, Provider("cmpi:HA_HostedResourceProvider") ] class HA_HostedResource { [ Key, Description ("The cluster node that host the resource.") ] HA_ClusterNode REF Antecedent; [ Key, Description ("The cluster resource.") ] HA_PrimitiveResource REF Dependent; }; //------------------------------------------- // Indication, HA_Indication //------------------------------------------- [ Indication, Provider ("cmpi:HA_IndicationProvider") ] class HA_Indication : CIM_ProcessIndication { uint16 Type; string Message; datetime Time; }; [ Provider ("cmpi:HA_ClusteringServiceProvider") ] class HA_ClusteringService { [ Key ] string Id; string Caption; uint32 AddResource( [IN, Description ("The resource to be added.")] HA_ClusterResource REF Resource); }; //----------------------------------------- // End of File //----------------------------------------- pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/mof/LinuxHA.reg000066400000000000000000000047461211477743100226600ustar00rootroot00000000000000# Classname Namespace ProviderName ProviderModule ProviderTypes ... # HA Cluster HA_Cluster root/cimv2 HA_ClusterProvider HA_ClusterProvider instance # HA Cluster Node HA_ClusterNode root/cimv2 HA_ClusterNodeProvider HA_ClusterNodeProvider instance #Primitve Resource HA_PrimitiveResource root/cimv2 HA_PrimitiveResourceProvider HA_PrimitiveResourceProvider instance #Resource Group HA_ResourceGroup root/cimv2 HA_ResourceGroupProvider HA_ResourceGroupProvider instance # Resource Clone HA_ResourceClone root/cimv2 HA_ResourceCloneProvider HA_ResourceCloneProvider instance # Master Slave Clone HA_MasterSlaveResource root/cimv2 HA_MasterSlaveResourceProvider HA_MasterSlaveResourceProvider instance # Resource instance #HA_InstanceAttributes root/cimv2 HA_InstanceAttributesProvider HA_InstanceAttributesProvider instance # Software HA_SoftwareIdentity root/cimv2 HA_SoftwareIdentityProvider HA_SoftwareIdentityProvider instance # LocationConstraint HA_LocationConstraint root/cimv2 HA_LocationConstraintProvider HA_LocationConstraintProvider instance # ColocationConstraint HA_ColocationConstraint root/cimv2 HA_ColocationConstraintProvider HA_ColocationConstraintProvider instance # OrderConstraint HA_OrderConstraint root/cimv2 HA_OrderConstraintProvider HA_OrderConstraintProvider instance # Operation HA_Operation root/cimv2 HA_OperationProvider HA_OperationProvider instance # Association, between Cluster and Node HA_ParticipatingNode root/cimv2 HA_ParticipatingNodeProvider HA_ParticipatingNodeProvider instance association # Association, between Resource and Hosting Node HA_HostedResource root/cimv2 HA_HostedResourceProvider HA_HostedResourceProvider instance association # Association, between Cluster and Software HA_InstalledSoftwareIdentity root/cimv2 HA_InstalledSoftwareIdentityProvider HA_InstalledSoftwareIdentityProvider instance association # Association, between Resource and its instance attribute #HA_ResourceInstance root/cimv2 HA_ResourceInstanceProvider HA_ResourceInstanceProvider instance association # Association, between Resource (Group/MasterSlave/Clone) and its sub resource HA_SubResource root/cimv2 HA_SubResourceProvider HA_SubResourceProvider instance association # Association, operation and resource HA_OperationOnResource root/cimv2 HA_OperationOnProvider HA_OperationOnProvider instance association #Indication HA_Indication root/cimv2 HA_IndicationProvider HA_IndicationProvider indication HA_ClusteringService root/cimv2 HA_ClusteringServiceProvider HA_ClusteringServiceProvider instance pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/mof/Makefile.am000066400000000000000000000021131211477743100226670ustar00rootroot00000000000000# Linux-HA: Makefile for register # # Author: Jia Ming Pan # Copyright (c) 2005 International Business Machines # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in mof_DATA = LinuxHA.mof LinuxHA.reg mof_SCRIPTS = register_providers.sh unregister_providers.sh do_register.sh mofdir = @HA_NOARCHDATAHBDIR@/cim DIST_LIST = $(mof_DATA) $(mof_SCRIPTS) EXTRA_DIST = $(DIST_LIST) pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/mof/do_register.sh000066400000000000000000000213231211477743100235010ustar00rootroot00000000000000#!/bin/sh # # Linux-HA: CIM Provider register tool # # Author: Jia Ming Pan # Copyright (c) 2005 International Business Machines # Licensed under the GNU GPL. # # #---------- openwbem functions --------------------------------------- openwbem_config="" openwbem_http_port=5988 openwbem_https_port=5989 openwbem_get_config_pathname() { owcimomd=`which owcimomd` prefix=`dirname $owcimomd` prefix=`dirname $prefix` echo config file: "$prefix/etc/openwbem/openwbem.conf" openwbem_config="$prefix/etc/openwbem/openwbem.conf" } openwbem_get_http_port() { openwbem_get_config_pathname http_port=`grep -e "http_server.http_port.*=" $openwbem_config | sed -e 's/.*=\W*\(\D*\)/\1/'` if [ "X$http_port" != "X" ]; then openwbem_http_port=$http_port fi echo openwbem_http_port: $openwbem_http_port } openwbem_get_https_port() { openwbem_get_config_pathname https_port=`grep -e "http_server.https_port.*=" $openwbem_config | sed -e 's/.*=\W*\(\D*\)/\1/'` if [ "X$https_port" != "X" ]; then openwbem_https_port=$https_port fi echo openwbem_https_port: $openwbem_https_port } openwbem_register () { mof_file=$1 reg_file=$2 ps -C owcimomd > /dev/null 2>&1 if test $? != 0; then echo "owcimomd not running, start it first" exit fi OWMOFC=`which owmofc` if test $? != 0; then echo "owmofc not found, OpenWbem not installed?" fi openwbem_get_http_port $OWMOFC -u "http://localhost:$openwbem_http_port/root/cimv2" $mof_file } openwbem_unregister () { mof_file=$1 reg_file=$2 ps -C owcimomd > /dev/null 2>&1 if test $? != 0; then echo "owcimomd not running, start it first" exit fi OWMOFC=`which owmofc` if test $? != 0; then echo "owmofc not found, OpenWbem not installed?" fi openwbem_get_http_port $OWMOFC -u "http://localhost:$openwbem_http_port/root/cimv2" -r $mof_file } #---------- pegasus functions ---------------------------------------- pegasus_add_module () { mof_file=$1 reg_file=$2 out_file=$REGFILE modules=`cat $reg_file 2> /dev/null | grep -v '^[[:space:]]*#.*' | cut -d ' ' -f 4 | sort | uniq` for module in $modules; do cat >> $out_file < /dev/null | grep -v '^[[:space:]]*#.*' | cut -d ' ' -f 3-4 | sort | uniq` set -- $providers while test x$1 != x do cat >> $out_file <> $out_file << EOF instance of PG_ProviderCapabilities { ProviderModuleName = "$providermodule"; ProviderName = "$providername"; ClassName = "$classname"; ProviderType = { $provider_types }; Namespaces = {"$namespace"}; SupportedProperties = NULL; SupportedMethods = NULL; CapabilityID = "$capid"; }; EOF done # while } pegasus_register () { mof_file=$1 reg_file=$2 if ps -C cimserver > /dev/null 2>&1 then CIMMOF=cimmof state=active else CIMMOF=cimmofl PEGASUSREPOSITORY="/opt/tog-pegasus/repository" CIMMOF="$CIMMOF -R $PEGASUSREPOSITORY" state=inactive fi pegasus_add_module $mof_file $reg_file pegasus_add_provider $mof_file $reg_file pegasus_add_capability $mof_file $reg_file $CIMMOF -n root/cimv2 $mof_file $CIMMOF -n root/PG_Interop $REGFILE } pegasus_unregister () { echo "FixME" exit } #---------- sfcb functions ------------------------------------------- sfcb_transform () { old_file=$1 new_file=$2 cat $old_file | grep -v '^[[:space:]]*#.*' | \ while read classname namespace providername providermodule types do cat >> $new_file < /dev/null 2>&1 if [ $? -eq 0 ]; then echo "sfcbd is running, please stop it first." exit fi } sfcb_register () { mof_file=$1 reg_file=$2 sfcb_running_check new_reg_file=/tmp/`basename $2`.reg sfcb_transform $reg_file $new_reg_file ## register echo register to sfcb ... sfcbstage -r $new_reg_file $mof_file if [ $? -eq 1 ]; then echo failed to register, exit exit fi echo rebuild sfcb repository ... sfcbrepos -f if [ $? -eq 1 ]; then echo failed to rebuild sfcb, exit exit fi rm -rf $new_reg_file } sfcb_unregister () { mof_file=$1 reg_file=$2 sfcb_running_check new_reg_file=/tmp/`basename $2`.reg sfcb_transform $reg_file $new_reg_file ## register echo unregister to sfcb ... sfcbunstage -r $new_reg_file $mof_file if [ $? -eq 1 ]; then echo failed to unregister, exit exit fi echo rebuild sfcb repository ... sfcbrepos -f if [ $? -eq 1 ]; then echo failed to rebuild sfcb, exit exit fi rm -rf $new_reg_file } #========== main ============================================ mof_file="" reg_file="" unregister="no" cimom="" usage () { echo "usage: $0 [-t cimserver] [-u] -r regfile -m mof" echo $'\t'-t cimserver: specify cimserver "[pegasus|openwbem|sfcb]". echo $'\t'-u: Unregister echo $'\t'-r regfile: specify reg file. echo $'\t'-m moffile: specify mof file. exit 0 } args=`getopt hut:r:m: $*` if test $? != 0; then usage fi while [ -n "$1" ]; do case $1 in -h) usage;; -u) unregister="yes" shift;; -t) shift if test "x$cimom" = "x"; then cimom=$1 else echo CIM server already set, ignore [$1] fi shift;; -m) shift if test "x$mof_file" = "x"; then mof_file=$1 else echo MOF file already set, ignore [$1] fi shift;; -r) shift if test "x$reg_file" = "x"; then reg_file=$1 else echo Reg file already set, ignore [$1] fi shift;; --) break;; esac done if test "x$unregister" != "xyes"; then echo registering providers ... else echo unregistering providers ... fi echo CIM Server: $cimom echo mof file : $mof_file echo registration file : $reg_file case $cimom in pegasus) ;; sfcb) ;; openwbem);; *) usage;; esac REG_FUNC=${cimom}_register UNREG_FUNC=${cimom}_unregister if test "x$unregister" != "xyes"; then $REG_FUNC $mof_file $reg_file else $UNREG_FUNC $mof_file $reg_file fi #============== end of file ======================================= pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/mof/register_providers.sh.in000066400000000000000000000005411211477743100255200ustar00rootroot00000000000000#!/bin/sh # # Linux-HA: CIM Provider register tool # # Author: Jia Ming Pan # Copyright (c) 2005 International Business Machines # Licensed under the GNU GPL. # # sh @HA_NOARCHDATAHBDIR@/heartbeat/cim/do_register.sh -t @CIMOM@ \ -r @HA_NOARCHDATAHBDIR@/heartbeat/cim/LinuxHA.reg \ -m @HA_NOARCHDATAHBDIR@/heartbeat/cim/LinuxHA.mof pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/mof/unregister_providers.sh.in000066400000000000000000000005441211477743100260660ustar00rootroot00000000000000#!/bin/sh # # Linux-HA: CIM Provider register tool # # Author: Jia Ming Pan # Copyright (c) 2005 International Business Machines # Licensed under the GNU GPL. # # sh @HA_NOARCHDATAHBDIR@/heartbeat/cim/do_register.sh -u -t @CIMOM@ \ -r @HA_NOARCHDATAHBDIR@/heartbeat/cim/LinuxHA.reg \ -m @HA_NOARCHDATAHBDIR@/heartbeat/cim/LinuxHA.mof pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/mof_map.c000066400000000000000000000145071211477743100216460ustar00rootroot00000000000000/* * mof_map.c: map Class properties to msg attributes * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include "mof_map.h" #define MAPDIM(x) (sizeof(x)/sizeof(map_entry_t)) static const map_entry_t HA_CLUSTER_entry [] = { {KEY_HBVERSION, "HBVersion", CMPI_chars}, {KEY_HOST, "Node", CMPI_charsA}, {KEY_HOPS, "HOPFudge", CMPI_chars}, {KEY_KEEPALIVE, "KeepAlive", CMPI_chars}, {KEY_DEADTIME, "DeadTime", CMPI_chars}, {KEY_DEADPING, "DeadPing", CMPI_chars}, {KEY_WARNTIME, "WarnTime", CMPI_chars}, {KEY_INITDEAD, "InitDead", CMPI_chars}, {KEY_WATCHDOG, "WatchdogTimer", CMPI_chars}, {KEY_BAUDRATE, "BaudRate", CMPI_chars}, {KEY_UDPPORT, "UDPPort", CMPI_chars}, {KEY_FACILITY, "LogFacility", CMPI_chars}, {KEY_LOGFILE, "LogFile", CMPI_chars}, {KEY_DBGFILE, "DebugFile", CMPI_chars}, {KEY_FAILBACK, "NiceFailBack", CMPI_chars}, {KEY_AUTOFAIL, "AutoFailBack", CMPI_chars}, {KEY_STONITH, "Stonith", CMPI_chars}, {KEY_STONITHHOST, "StonithHost", CMPI_chars}, {KEY_CLIENT_CHILD, "Respawn", CMPI_chars}, {KEY_RT_PRIO, "RTPriority", CMPI_chars}, {KEY_GEN_METH, "GenMethod", CMPI_chars}, {KEY_REALTIME, "RealTime", CMPI_chars}, {KEY_DEBUGLEVEL, "DebugLevel", CMPI_chars}, {KEY_NORMALPOLL, "NormalPoll", CMPI_chars}, {KEY_APIPERM, "APIAuth", CMPI_charsA}, {KEY_MSGFMT, "MsgFmt", CMPI_chars}, {KEY_LOGDAEMON, "UseLogd", CMPI_chars}, {KEY_CONNINTVAL, "ConnLogdTime", CMPI_chars}, {KEY_BADPACK, "LogBadPack", CMPI_chars}, {KEY_REGAPPHBD, "NormalPoll", CMPI_chars}, {KEY_COREDUMP, "CoreDump", CMPI_chars}, {KEY_COREROOTDIR, "CoreRootDir", CMPI_chars}, {KEY_REL2, "WithCrm", CMPI_chars}, {"pingnode", "PingNode", CMPI_charsA}, {"pinggroup", "PingGroup", CMPI_charsA} }; static const map_entry_t HA_CLUSTER_NODE_entry [] = { {"uname", "Name", CMPI_chars}, {"online", "OnLine", CMPI_chars}, {"standby", "Standby", CMPI_chars}, {"unclean", "Unclean", CMPI_chars}, {"shutdown", "Shutdown", CMPI_chars}, {"expected_up", "ExpectedUp", CMPI_chars}, {"node_ping", "NodePing", CMPI_chars}, {"is_dc", "IsDC", CMPI_chars}, }; static const map_entry_t HA_PRIMITIVE_RESOURCE_entry [] = { {"id", "Id", CMPI_chars}, {"class", "ResourceClass",CMPI_chars}, {"type", "Type", CMPI_chars}, {"provider", "Provider", CMPI_chars}, {"enabled", "Enabled", CMPI_chars}, }; static const map_entry_t HA_RESOURCE_CLONE_entry [] = { {"id", "Id", CMPI_chars}, {"notify", "Notify", CMPI_chars}, {"ordered", "Ordered", CMPI_chars}, {"interleave", "Interleave", CMPI_chars}, {"clone_max", "CloneMax", CMPI_chars}, {"clone_node_max","CloneNodeMax",CMPI_chars}, {"enabled", "Enabled", CMPI_chars}, }; static const map_entry_t HA_MASTERSLAVE_RESOURCE_entry [] = { {"id", "Id", CMPI_chars}, {"clone_max", "CloneMax", CMPI_chars}, {"clone_node_max", "CloneNodeMax", CMPI_chars}, {"master_max", "MaxMasters", CMPI_chars}, {"master_node_max", "MaxNodeMasters", CMPI_chars}, {"enabled", "Enabled", CMPI_chars}, }; static const map_entry_t HA_RESOURCE_GROUP_entry [] = { {"id", "Id", CMPI_chars}, {"enabled", "Enabled", CMPI_chars}, }; static const map_entry_t HA_OPERATION_entry [] = { {"id", "Id", CMPI_chars}, {"name", "Name", CMPI_chars}, {"interval", "Interval", CMPI_chars}, {"timeout", "Timeout", CMPI_chars} }; static const map_entry_t HA_ORDER_CONSTRAINT_entry [] = { {"id", "Id", CMPI_chars}, {"from", "From", CMPI_chars}, {"type", "OrderType", CMPI_chars}, {"to", "To", CMPI_chars}, }; static const map_entry_t HA_COLOCATION_CONSTRAINT_entry [] = { {"id", "Id", CMPI_chars}, {"from", "From", CMPI_chars}, {"to", "To", CMPI_chars}, {"score", "Score", CMPI_chars} }; static const map_entry_t HA_LOCATION_CONSTRAINT_entry [] = { {"id", "Id", CMPI_chars}, {"score", "Score", CMPI_chars}, {"resource", "Resource", CMPI_chars} }; static const map_entry_t HA_INSTANCE_ATTRIBUTES_entry [] = { {"id", "Id", CMPI_chars}, {"name", "Name", CMPI_chars}, {"value", "Value", CMPI_chars} }; static const map_entry_t HA_LOCATION_CONSTRAINT_RULE_entry [] = { {"id", "Id", CMPI_chars}, {"attribute", "Attribute", CMPI_chars}, {"operation", "Operation", CMPI_chars}, {"value", "Value", CMPI_chars}, }; #define MAKE_ENTRY(id,entry) {id, MAPDIM(entry), entry} static const struct map_t map_table [] = { MAKE_ENTRY(HA_CLUSTER, HA_CLUSTER_entry), MAKE_ENTRY(HA_CLUSTER_NODE, HA_CLUSTER_NODE_entry), MAKE_ENTRY(HA_PRIMITIVE_RESOURCE, HA_PRIMITIVE_RESOURCE_entry), MAKE_ENTRY(HA_RESOURCE_CLONE, HA_RESOURCE_CLONE_entry), MAKE_ENTRY(HA_RESOURCE_GROUP, HA_RESOURCE_GROUP_entry), MAKE_ENTRY(HA_MASTERSLAVE_RESOURCE, HA_MASTERSLAVE_RESOURCE_entry), MAKE_ENTRY(HA_OPERATION, HA_OPERATION_entry), MAKE_ENTRY(HA_ORDER_CONSTRAINT, HA_ORDER_CONSTRAINT_entry), MAKE_ENTRY(HA_COLOCATION_CONSTRAINT, HA_COLOCATION_CONSTRAINT_entry), MAKE_ENTRY(HA_LOCATION_CONSTRAINT, HA_LOCATION_CONSTRAINT_entry), MAKE_ENTRY(HA_INSTANCE_ATTRIBUTES, HA_INSTANCE_ATTRIBUTES_entry), MAKE_ENTRY(HA_LOCATION_CONSTRAINT_RULE, HA_LOCATION_CONSTRAINT_RULE_entry), }; const struct map_t * cim_query_map(int mapid) { int i; for(i = 0; i < sizeof(map_table)/sizeof(struct map_t); i++) { if ( mapid == map_table[i].id) { return &map_table[i]; } } return NULL; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/mof_map.h000066400000000000000000000054621211477743100216530ustar00rootroot00000000000000/* * mof_map.h: map class properties to msg attributes * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef _MOF_MAP_H #define _MOF_MAP_H typedef struct { const char * key; const char * name; int type; } map_entry_t; struct map_t{ int id; int len; const map_entry_t *entry; }; const struct map_t * cim_query_map(int mapid); #define HA_CLUSTER 1 #define HA_CLUSTER_NODE 2 #define HA_PRIMITIVE_RESOURCE 3 #define HA_RESOURCE_CLONE 4 #define HA_MASTERSLAVE_RESOURCE 5 #define HA_OPERATION 6 #define HA_ORDER_CONSTRAINT 7 #define HA_COLOCATION_CONSTRAINT 8 #define HA_LOCATION_CONSTRAINT 9 #define HA_RESOURCE_GROUP 10 #define HA_INSTANCE_ATTRIBUTES 11 #define HA_LOCATION_CONSTRAINT_RULE 12 #define METHOD_ADD_RESOURCE "AddResource" #define METHOD_ADD_PRIMITIVE_RESOURCE "AddPrimitiveResource" #define CLASS_HA_CLUSTER "HA_Cluster" #define CLASS_HA_CLUSTER_NODE "HA_ClusterNode" #define CLASS_HA_CLUSTER_RESOURCE "HA_ClusterResource" #define CLASS_HA_SOFTWARE_IDENTITY "HA_SoftwareIdentity" #define CLASS_HA_INSTALLED_SOFTWARE_IDENTITY "HA_InstalledSoftwareIdentity" #define CLASS_HA_PRIMITIVE_RESOURCE "HA_PrimitiveResource" #define CLASS_HA_RESOURCE_GROUP "HA_ResourceGroup" #define CLASS_HA_RESOURCE_CLONE "HA_ResourceClone" #define CLASS_HA_MSTERSLAVE_RESOURCE "HA_MasterSlaveResource" #define CLASS_HA_INSTANCE_ATTRIBUTES "HA_InstanceAttributes" #define CLASS_HA_ATTRIBUTES_OF_RESOURCE "HA_AttributesOfResource" #define CLASS_HA_OPERATION "HA_Operation" #define CLASS_HA_OPERATION_ON_RESOURCE "HA_OperationOnResource" #define CLASS_HA_RESOURCE_CONSTRAINT "HA_ResourceConstraint" #define CLASS_HA_ORDER_CONSTRAINT "HA_OrderConstraint" #define CLASS_HA_COLOCATION_CONSTRAINT "HA_ColocationConstraint" #define CLASS_HA_LOCATION_CONSTRAINT "HA_LocationConstraint" #define CLASS_HA_SUBRESOURCE "HA_SubResource" #define CLASS_HA_PARTICIPATING_NODE "HA_ParticipatingNode" #define CLASS_HA_HOSTED_RESOURCE "HA_HostedResource" #define CLASS_HA_INDICATION "HA_Indication" #define CLASS_HA_CLUSTERING_SERVICE "HA_ClusteringService" #endif pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/operation_on_provider.c000066400000000000000000000221621211477743100246320ustar00rootroot00000000000000/* * operation_on_provider.c: HA_OperationOn provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include "cluster_info.h" #include "cmpi_utils.h" static const char * PROVIDER_ID = "cim-op-on"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_OperationOnResource"; static char Left [] = "Resource"; static char Right [] = "Operation"; static char LeftClassName [] = "HA_PrimitiveResource"; static char RightClassName [] = "HA_Operation"; DeclareInstanceFunctions (OperationOn); DeclareAssociationFunctions(OperationOn); static int resource_has_op(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIObjectPath * rscop, CMPIObjectPath * opop, CMPIStatus * rc) { char *rscid, *oprscid; rscid = CMGetKeyString(rscop, "Id", rc); oprscid = CMGetKeyString(opop, "ResourceId", rc); if ( rscid == NULL || oprscid == NULL ) { return FALSE; } if ( strncmp(rscid, oprscid, MAXLEN) == 0 ) { return TRUE; } return FALSE; } /********************************************** * Instance **********************************************/ static CMPIStatus OperationOnCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus OperationOnEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "OperationsOn: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_enum_insts(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, resource_has_op, NULL, FALSE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus OperationOnEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "OperationsOn: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_enum_insts(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, resource_has_op, NULL, TRUE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus OperationOnGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "OperationsOn: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_get_inst(Broker, ClassName, ctx, rslt, cop, Left, Right, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus OperationOnCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus OperationOnSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "OperationsOn: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus OperationOnDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; return rc; } static CMPIStatus OperationOnExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /**************************************************** * Association ****************************************************/ static CMPIStatus OperationOnAssociationCleanup(CMPIAssociationMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus OperationOnAssociators(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * assoc_class, const char * result_class, const char * role, const char * result_role, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "OperationsOn: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_enum_associators(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, assoc_class, result_class, role, result_role, resource_has_op, NULL, TRUE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus OperationOnAssociatorNames(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * assoc_class, const char * result_class, const char * role, const char * result_role) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "OperationsOn: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_enum_associators(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, assoc_class, result_class, role, result_role, resource_has_op, NULL, FALSE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus OperationOnReferences(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * result_class, const char * role, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "OperationsOn: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if ( assoc_enum_references(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, result_class, role, NULL, NULL, TRUE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus OperationOnReferenceNames(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * result_class, const char * role) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "OperationsOn: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if ( assoc_enum_references(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, result_class, role, resource_has_op, NULL, FALSE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } /************************************************************** * MI stub *************************************************************/ DeclareInstanceMI (OperationOn, HA_OperationOnProvider, Broker); DeclareAssociationMI(OperationOn, HA_OperationOnProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/operation_provider.c000066400000000000000000000204751211477743100241430ustar00rootroot00000000000000/* * operation_provider.c: HA_Operation provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include "cmpi_utils.h" #include "cluster_info.h" static const char * PROVIDER_ID = "cim-op"; static char ClassName [] = "HA_Operation"; static CMPIBroker * Broker = NULL; DeclareInstanceFunctions(Operation); static struct ha_msg * find_operation(const char * rscid, const char *opid) { struct ha_msg *ops, *operation = NULL; if ((ops = cim_get_rscops(rscid)) == NULL ) { cl_log(LOG_WARNING, "%s: none ops of %s found.", __FUNCTION__, rscid); return NULL; } if ((operation = cim_msg_find_child(ops, opid)) ){ operation = ha_msg_copy(operation); } ha_msg_del(ops); return operation; } static CMPIInstance * operation_make_instance(CMPIObjectPath * op, char* rscid, const char * opid, struct ha_msg *operation, CMPIStatus * rc) { char caption[MAXLEN]; CMPIInstance * ci = NULL; ci = CMNewInstance(Broker, op, rc); if ( CMIsNullObject(ci) ) { cl_log(LOG_ERR, "%s: couldn't create instance", __FUNCTION__); CMSetStatusWithChars(Broker, rc, CMPI_RC_ERR_FAILED, "Could not create instance."); return NULL; } cmpi_msg2inst(Broker, ci, HA_OPERATION, operation, rc); snprintf(caption, MAXLEN, "Operation.%s", opid); CMSetProperty(ci, "Caption", caption, CMPI_chars); CMSetProperty(ci, "ResourceId", rscid, CMPI_chars); return ci; } static int operation_enum_insts(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, int EnumInst, CMPIStatus * rc) { char *namespace; CMPIObjectPath * op = NULL; char *opid, *rscid; struct ha_msg *msg, *rsclist, *ops, *operation; int i, j, rsccount, opcount; DEBUG_ENTER(); namespace = CMGetCharPtr(CMGetNameSpace(ref, rc)); if ( namespace == NULL ) { return HA_FAIL; } if ((msg = cim_get_all_rsc_list())== NULL || (rsclist = cim_traverse_allrsc(msg)) == NULL ) { goto done; } ha_msg_del(msg); rsccount = cim_list_length(rsclist); for (i = 0; i < rsccount; i++){ rscid = cim_list_index(rsclist, i); if (rscid == NULL || (ops = cim_get_rscops(rscid)) == NULL ){ continue; } opcount = cim_msg_children_count(ops); for (j = 0; j < opcount; j++) { const char *const_opid; if(( operation = cim_msg_child_index(ops, j)) == NULL ||(const_opid=cl_get_string(operation, "id"))== NULL){ continue; } opid = cim_strdup(const_opid); op = CMNewObjectPath(Broker, namespace, ClassName, rc); if ( EnumInst ) { CMPIInstance * ci = NULL; ci = operation_make_instance(op, rscid, opid, operation, rc); CMReturnInstance(rslt, ci); } else { /* enumerate instance names */ CMAddKey(op, "ResourceId", rscid, CMPI_chars); CMAddKey(op, "Id", opid, CMPI_chars); CMReturnObjectPath(rslt, op); } cim_free(opid); } } ha_msg_del(rsclist); done: rc->rc = CMPI_RC_OK; CMReturnDone(rslt); DEBUG_LEAVE(); return HA_OK; } /********************************************** * Instance provider functions **********************************************/ static CMPIStatus OperationCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus OperationEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); operation_enum_insts(mi, ctx, rslt, ref, FALSE, &rc); return rc; } static CMPIStatus OperationEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); operation_enum_insts(mi, ctx, rslt, ref, TRUE, &rc); return rc; } static CMPIStatus OperationGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIObjectPath * op; CMPIInstance * ci; CMPIStatus rc; char *rscid, *id; struct ha_msg *operation = NULL; PROVIDER_INIT_LOGGER(); id = CMGetKeyString(cop, "Id", &rc); rscid = CMGetKeyString(cop, "ResourceId", &rc); op = CMNewObjectPath(Broker, CMGetCharPtr(CMGetNameSpace(cop, &rc)), ClassName, &rc); if ( CMIsNullObject(op) ){ cl_log(LOG_WARNING, "inst_attr: can not create object path."); CMReturnDone(rslt); return rc; } operation = find_operation(rscid, id); if ( operation == NULL) { cl_log(LOG_ERR, "%s: can't find operation for %s", __FUNCTION__, id); CMReturnDone(rslt); rc.rc = CMPI_RC_ERR_FAILED; return rc; } ci = operation_make_instance(op, rscid, id, operation, &rc); if ( CMIsNullObject(ci) ) { CMReturnDone(rslt); return rc; } CMReturnInstance(rslt, ci); CMReturnDone(rslt); CMReturn(CMPI_RC_OK); } static CMPIStatus OperationCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; struct ha_msg *operation; char *id, *rscid; id = CMGetKeyString(cop, "Id", &rc); rscid = CMGetKeyString(cop, "ResourceId", &rc); /* create an empty operatoin */ if ((operation = ha_msg_new(16)) == NULL ) { cl_log(LOG_ERR, "%s: operation alloc failed.", __FUNCTION__); rc.rc = CMPI_RC_ERR_FAILED; goto done; } /* fill operation */ cmpi_inst2msg(ci, HA_OPERATION, operation, &rc); /* add op to resource */ if (cim_add_rscop(rscid, operation) != HA_OK ) { rc.rc = CMPI_RC_ERR_FAILED; ha_msg_del(operation); goto done; } ha_msg_del(operation); rc.rc = CMPI_RC_OK; done: return rc; } static CMPIStatus OperationSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; struct ha_msg *operation; char *id, *rscid; id = CMGetKeyString(cop, "Id", &rc); rscid = CMGetKeyString(cop, "ResourceId", &rc); if ((operation = find_operation(rscid, id)) == NULL ) { rc.rc = CMPI_RC_ERR_FAILED; goto done; } cmpi_inst2msg(ci, HA_OPERATION, operation, &rc); cim_update_rscop(rscid, id, operation); rc.rc = CMPI_RC_OK; done: return rc; } static CMPIStatus OperationDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; char *id, *rscid; id = CMGetKeyString(cop, "Id", &rc); rscid = CMGetKeyString(cop, "ResourceId", &rc); if ( cim_del_rscop(rscid, id) == HA_OK ) { rc.rc = CMPI_RC_OK; } else { rc.rc = CMPI_RC_ERR_FAILED; } return rc; } static CMPIStatus OperationExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /***************************************************** * install provider ****************************************************/ DeclareInstanceMI(Operation, HA_OperationProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/order_constraint_provider.c000066400000000000000000000103131211477743100255100ustar00rootroot00000000000000/* * order_constraint_provider.c: HA_ResourceOrderConstraint provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include "cmpi_utils.h" #include "cluster_info.h" #include "constraint_common.h" static const char * PROVIDER_ID = "cim-op"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_OrderConstraint"; DeclareInstanceFunctions(OrderConstraint); static CMPIStatus OrderConstraintCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus OrderConstraintEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); constraint_enum_insts(Broker, ClassName, ctx, rslt, ref, FALSE, TID_CONS_ORDER, &rc); return rc; } static CMPIStatus OrderConstraintEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char ** properties) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); constraint_enum_insts(Broker, ClassName, ctx, rslt, ref, TRUE, TID_CONS_ORDER, &rc); return rc; } static CMPIStatus OrderConstraintGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); constraing_get_inst(Broker, ClassName, ctx, rslt, cop, properties, TID_CONS_ORDER, &rc); return rc; } static CMPIStatus OrderConstraintCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); constraint_create_inst(Broker, ClassName, mi, ctx, rslt, cop, ci, TID_CONS_ORDER, &rc); return rc; } static CMPIStatus OrderConstraintSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); constraint_update_inst(Broker, ClassName, mi, ctx, rslt, cop, ci, properties, TID_CONS_ORDER, &rc); return rc; } static CMPIStatus OrderConstraintDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; constraint_delete_inst(Broker, ClassName, mi, ctx, rslt, cop, TID_CONS_ORDER, &rc); return rc; } static CMPIStatus OrderConstraintExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /***************************************************** * install provider ****************************************************/ DeclareInstanceMI(OrderConstraint, HA_OrderConstraintProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/participating_node_provider.c000066400000000000000000000174771211477743100260160ustar00rootroot00000000000000/* * participating_node_provider.c: HA_ParticipatingNode provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include "cmpi_utils.h" #include "cluster_info.h" #include "cmpi_utils.h" #define PROVIDER_ID "cim-par-node" static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_ParticipatingNode"; static char Left [] = "Dependent"; static char Right [] = "Antecedent"; static char LeftClassName [] = "HA_Cluster"; static char RightClassName [] = "HA_ClusterNode"; DeclareInstanceFunctions (ParticipatingNode); DeclareAssociationFunctions(ParticipatingNode); /********************************************** * Instance Provider Interface **********************************************/ static CMPIStatus ParticipatingNodeCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus ParticipatingNodeEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if (assoc_enum_insts(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, NULL, NULL, 0, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus ParticipatingNodeEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if (assoc_enum_insts(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, NULL, NULL, 1, &rc) != HA_OK ){ return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus ParticipatingNodeGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( assoc_get_inst(Broker, ClassName, ctx, rslt, cop, Left, Right, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus ParticipatingNodeCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus ParticipatingNodeSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus ParticipatingNodeDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus ParticipatingNodeExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /**************************************************** * Association ****************************************************/ static CMPIStatus ParticipatingNodeAssociationCleanup(CMPIAssociationMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus ParticipatingNodeAssociators(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * assoc_class, const char * result_class, const char * role, const char * result_role, char ** properties) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); if (assoc_enum_associators(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, assoc_class, result_class, role, result_role, NULL, NULL, 1, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus ParticipatingNodeAssociatorNames(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * assoc_class, const char * result_class, const char * role, const char * result_role) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); if (assoc_enum_associators(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, assoc_class, result_class, role, result_role, NULL, NULL, 0, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus ParticipatingNodeReferences(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * result_class, const char * role, char ** properties) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); if ( assoc_enum_references(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, result_class, role, NULL, NULL, 1, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus ParticipatingNodeReferenceNames(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * result_class, const char * role) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); if (assoc_enum_references(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, result_class, role, NULL, NULL, 0, &rc) != HA_OK ){ return rc; } CMReturn(CMPI_RC_OK); } /************************************************************** * MI stub *************************************************************/ DeclareInstanceMI (ParticipatingNode, HA_ParticipatingNodeProvider, Broker); DeclareAssociationMI(ParticipatingNode, HA_ParticipatingNodeProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/primitive_resource_provider.c000066400000000000000000000131161211477743100260540ustar00rootroot00000000000000/* * primitive_resource_provider.c: HA_PrimitiveResource provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include "cmpi_utils.h" #include "cluster_info.h" #include "resource_common.h" static const char * PROVIDER_ID = "cim-rsc"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_PrimitiveResource"; static const char * METHOD_ADD_OPERATION = "AddOperation"; DeclareInstanceFunctions(PrimitiveResource); static CMPIStatus PrimitiveResourceCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMPIStatus rc; resource_cleanup(Broker, ClassName, mi, ctx, TID_RES_PRIMITIVE, &rc); CMReturn(CMPI_RC_OK); } static CMPIStatus PrimitiveResourceEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); resource_enum_insts(Broker, ClassName, ctx, rslt, ref, FALSE, TID_RES_PRIMITIVE, &rc); return rc; } static CMPIStatus PrimitiveResourceEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult* rslt, CMPIObjectPath* ref, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); resource_enum_insts(Broker, ClassName, ctx, rslt, ref, TRUE, TID_RES_PRIMITIVE, &rc); return rc; } static CMPIStatus PrimitiveResourceGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult* rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); resource_get_inst(Broker, ClassName, ctx, rslt, cop, properties, TID_RES_PRIMITIVE, &rc); return rc; } static CMPIStatus PrimitiveResourceCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance* ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); resource_create_inst(Broker, ClassName, ctx, rslt, cop, ci, TID_RES_PRIMITIVE, &rc); return rc; } static CMPIStatus PrimitiveResourceSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); resource_update_inst(Broker, ClassName, ctx, rslt, cop, ci, properties, TID_RES_PRIMITIVE, &rc); return rc; } static CMPIStatus PrimitiveResourceDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); resource_del_inst(Broker, ClassName, ctx, rslt, cop, &rc); return rc; } static CMPIStatus PrimitiveResourceExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /*********************************************** * method ***********************************************/ static CMPIStatus PrimitiveResourceInvokeMethod(CMPIMethodMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, const char * method_name, CMPIArgs * in, CMPIArgs * out) { CMPIString * classname = NULL; CMPIStatus rc = {CMPI_RC_OK, NULL}; int ret = 0; classname = CMGetClassName(ref, &rc); if(strcasecmp(CMGetCharPtr(classname), ClassName) == 0 && strcasecmp(METHOD_ADD_OPERATION, method_name) == 0 ){ #if 0 ret = resource_add_operation(Broker, ClassName, ctx, rslt, ref, TID_RES_PRIMITIVE, in, out, &rc); #endif ret = HA_OK; } CMReturnData(rslt, &ret, CMPI_uint32); CMReturnDone(rslt); CMReturn(CMPI_RC_OK); } static CMPIStatus PrimitiveResourceMethodCleanup(CMPIMethodMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } /***************************************************** * instance MI ****************************************************/ DeclareInstanceMI(PrimitiveResource, HA_PrimitiveResourceProvider, Broker); DeclareMethodMI(PrimitiveResource, HA_PrimitiveResourceProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/resource_clone_provider.c000066400000000000000000000126251211477743100251500ustar00rootroot00000000000000/* * resource_clone_provider.c: HA_ResourceClone provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include "utils.h" #include "cmpi_utils.h" #include "cluster_info.h" #include "resource_common.h" static const char * PROVIDER_ID = "cim-clone"; static char ClassName [] = "HA_ResourceClone"; static CMPIBroker * Broker = NULL; DeclareInstanceFunctions(ResourceClone); /********************************************** * Instance provider functions **********************************************/ static CMPIStatus ResourceCloneCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMPIStatus rc; resource_cleanup(Broker, ClassName, mi, ctx, TID_RES_CLONE, &rc); CMReturn(CMPI_RC_OK); } static CMPIStatus ResourceCloneEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); resource_enum_insts(Broker, ClassName, ctx, rslt, ref, FALSE, TID_RES_CLONE, &rc); return rc; } static CMPIStatus ResourceCloneEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char ** properties) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); resource_enum_insts(Broker, ClassName, ctx, rslt, ref, TRUE, TID_RES_CLONE, &rc); return rc; } static CMPIStatus ResourceCloneGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); resource_get_inst(Broker, ClassName, ctx, rslt, cop, properties, TID_RES_CLONE, &rc); return rc; } static CMPIStatus ResourceCloneCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; resource_create_inst(Broker, ClassName, ctx, rslt, cop, ci, TID_RES_CLONE, &rc); return rc; } static CMPIStatus ResourceCloneSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); resource_update_inst(Broker, ClassName, ctx, rslt, cop, ci, properties, TID_RES_CLONE, &rc); return rc; } static CMPIStatus ResourceCloneDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); resource_del_inst(Broker, ClassName, ctx, rslt, cop, &rc); return rc; } static CMPIStatus ResourceCloneExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /************************************************ * method ***********************************************/ static CMPIStatus ResourceCloneInvokeMethod(CMPIMethodMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, const char * method_name, CMPIArgs * in, CMPIArgs * out) { CMPIString * classname = NULL; CMPIStatus rc = {CMPI_RC_OK, NULL}; int ret = 0; PROVIDER_INIT_LOGGER(); DEBUG_ENTER(); classname = CMGetClassName(ref, &rc); if(strcasecmp(CMGetCharPtr(classname), ClassName) == 0 && strcasecmp(METHOD_ADD_RESOURCE, method_name) == 0 ){ ret = resource_add_subrsc(Broker, ClassName, ctx, rslt, ref, TID_RES_CLONE, in, out, &rc); } CMReturnData(rslt, &ret, CMPI_uint32); CMReturnDone(rslt); DEBUG_LEAVE(); CMReturn(CMPI_RC_OK); } static CMPIStatus ResourceCloneMethodCleanup(CMPIMethodMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } /***************************************************** * install provider ****************************************************/ DeclareInstanceMI(ResourceClone, HA_ResourceCloneProvider, Broker); DeclareMethodMI(ResourceClone, HA_ResourceCloneProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/resource_common.c000066400000000000000000000416131211477743100234250ustar00rootroot00000000000000/* * resource_common.c: common functions for resource providers * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include "cluster_info.h" #include "resource_common.h" #include "cmpi_utils.h" static char SystemName [] = "LinuxHACluster"; static char SystemClassName [] = "HA_Cluster"; static char PrimitiveClassName [] = "HA_PrimitiveResource"; static char GroupClassName [] = "HA_ResourceGroup"; static char CloneClassName [] = "HA_ResourceClone"; static char MasterClassName [] = "HA_MasterSlaveResource"; static void primitive_set_instance(CMPIBroker * broker, CMPIInstance * ci, struct ha_msg *, CMPIStatus *); static void group_set_instance(CMPIBroker * broker, CMPIInstance * ci, struct ha_msg *, CMPIStatus *); static void clone_set_instance(CMPIBroker * broker, CMPIInstance * ci, struct ha_msg *, CMPIStatus *); static void master_set_instance(CMPIBroker * broker, CMPIInstance * ci, struct ha_msg *, CMPIStatus *); static CMPIInstance * make_instance(CMPIBroker * broker, char * classname, CMPIObjectPath * op, struct ha_msg *info, uint32_t type, CMPIStatus * rc); static CMPIInstance * make_instance_byid(CMPIBroker * broker, CMPIObjectPath * ref, char * rscid, uint32_t type, CMPIStatus * rc); static CMPIObjectPath * make_objectpath_byid(CMPIBroker * broker, CMPIObjectPath * ref, char * rscid, uint32_t type, CMPIStatus * rc); static void primitive_set_instance(CMPIBroker * broker, CMPIInstance * ci, struct ha_msg *info, CMPIStatus * rc) { const char *const_host= NULL, *id; char * host = NULL; struct ha_msg *msg = NULL; cmpi_msg2inst(broker, ci, HA_PRIMITIVE_RESOURCE, info, rc); id = cl_get_string(info, "id"); if ( RESOURCE_ENABLED(id) ) { msg = cim_query_dispatch(GET_RSC_HOST, id, NULL); } /* get hosting node */ if ( msg && (const_host = cl_get_string(msg, "host")) != NULL ){ host = cim_strdup(const_host); cl_log(LOG_INFO, "Hosting node is %s", host); CMSetProperty(ci, "HostingNode", host, CMPI_chars); } else { /* OpenWBEM will segment fault in HostedResource provider if "HostingNode" not set */ host = cim_strdup ("Unknown"); CMSetProperty(ci, "HostingNode", host, CMPI_chars); } cim_free(host); } static void group_set_instance(CMPIBroker * broker, CMPIInstance * ci, struct ha_msg *info, CMPIStatus * rc) { cmpi_msg2inst(broker, ci, HA_RESOURCE_GROUP, info, rc); } static void clone_set_instance(CMPIBroker * broker, CMPIInstance * ci, struct ha_msg *clone, CMPIStatus * rc) { cmpi_msg2inst(broker, ci, HA_RESOURCE_CLONE, clone, rc); } static void master_set_instance(CMPIBroker * broker, CMPIInstance * ci, struct ha_msg *master, CMPIStatus * rc) { cmpi_msg2inst(broker, ci, HA_MASTERSLAVE_RESOURCE, master, rc); } static CMPIInstance * make_instance(CMPIBroker * broker, char * classname, CMPIObjectPath * op, struct ha_msg* info, uint32_t type, CMPIStatus * rc) { CMPIInstance * ci = NULL; char *id, *status; const char *constid, *conststatus; char caption [MAXLEN]; struct ha_msg *msg; ci = CMNewInstance(broker, op, rc); if ( CMIsNullObject(ci) ) { cl_log(LOG_ERR, "%s: Can't create instance.", __FUNCTION__); CMSetStatusWithChars(broker, rc, CMPI_RC_ERR_FAILED, "Can't get create instance"); return NULL; } constid = cl_get_string(info, "id"); id = cim_strdup(constid); snprintf(caption, MAXLEN, "Resource.%s", id); /* set other key properties inherited from super classes */ CMSetProperty(ci, "SystemCreationClassName", SystemClassName, CMPI_chars); CMSetProperty(ci, "SystemName", SystemName, CMPI_chars); CMSetProperty(ci, "CreationClassName", classname, CMPI_chars); CMSetProperty(ci, "Id", id, CMPI_chars); /* set Caption */ CMSetProperty(ci, "Caption", caption, CMPI_chars); if ((msg = cim_query_dispatch(GET_RSC_STATUS, id, NULL)) ){ if (( conststatus = cl_get_string(msg, "status")) ) { status = cim_strdup(conststatus); CMSetProperty(ci, "ResourceStatus", status, CMPI_chars); cim_free(status); } } ha_msg_del(msg); if (type == TID_RES_PRIMITIVE) { /* attributes2inst(broker, ci, id, info, rc); */ primitive_set_instance(broker, ci, info, rc); } else if ( type == TID_RES_GROUP){ group_set_instance(broker, ci, info, rc); } else if ( type == TID_RES_CLONE){ clone_set_instance(broker, ci, info, rc); } else if ( type == TID_RES_MASTER) { master_set_instance(broker, ci, info, rc); } cim_free(id); return ci; } static CMPIInstance * make_instance_byid(CMPIBroker * broker, CMPIObjectPath * ref, char * rscid, uint32_t type, CMPIStatus * rc) { CMPIInstance * ci = NULL; char * namespace, * classname; CMPIObjectPath * op; struct ha_msg *info = NULL; namespace = CMGetCharPtr(CMGetNameSpace(ref, rc)); switch(type) { case TID_RES_PRIMITIVE: classname = PrimitiveClassName; break; case TID_RES_GROUP: classname = GroupClassName; break; case TID_RES_CLONE: classname = CloneClassName; break; case TID_RES_MASTER: classname = MasterClassName; break; default: return NULL; } if ((info = cim_find_rsc(type, rscid)) == NULL ) { cl_log(LOG_ERR, "%s: failed to get resource", __FUNCTION__); return NULL; } if ( RESOURCE_ENABLED(rscid)) { ha_msg_add(info, "enabled", "true"); } else { ha_msg_add(info, "enabled", "false"); } op = CMNewObjectPath(broker, namespace, classname, rc); if ( CMIsNullObject(op) ) { cl_log(LOG_ERR, "%s: can't create objectpath", __FUNCTION__); return NULL; } ci = make_instance(broker, classname, op, info, type, rc); ha_msg_del(info); CMRelease(op); return ci; } static CMPIObjectPath * make_objectpath_byid(CMPIBroker * broker, CMPIObjectPath * ref, char * rscid, uint32_t type, CMPIStatus * rc) { char *namespace, *classname; CMPIObjectPath * op; DEBUG_ENTER(); if ( rscid == NULL ) { return NULL; } namespace = CMGetCharPtr(CMGetNameSpace(ref, rc)); switch(type) { case TID_RES_PRIMITIVE: classname = PrimitiveClassName; break; case TID_RES_GROUP: classname = GroupClassName; break; case TID_RES_CLONE: classname = CloneClassName; break; case TID_RES_MASTER: classname = MasterClassName; break; default: return NULL; } op = CMNewObjectPath(broker, namespace, classname, rc); if ( CMIsNullObject(op) ) { return NULL; } CMAddKey(op, "Id", rscid, CMPI_chars); CMAddKey(op, "SystemName", SystemName, CMPI_chars); CMAddKey(op, "SystemCreationClassName", SystemClassName, CMPI_chars); CMAddKey(op, "CreationClassName", classname, CMPI_chars); DEBUG_LEAVE(); return op; } int resource_get_inst(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char ** properties, uint32_t type, CMPIStatus * rc) { CMPIInstance * ci = NULL; CMPIData data_name; char * rscid = NULL; uint32_t this_type; if ( cim_get_hb_status() != HB_RUNNING ) { rc->rc = CMPI_RC_ERR_FAILED; cl_log(LOG_WARNING, "Heartbeat not running."); return HA_FAIL; } data_name = CMGetKey(ref, "Id", rc); if ( data_name.value.string == NULL ) { cl_log(LOG_WARNING, "key %s is NULL", "Id"); return HA_FAIL; } rscid = CMGetCharPtr(data_name.value.string); this_type = (type == 0) ? cim_get_rsctype(rscid) : type; ci = make_instance_byid(broker, ref, rscid, this_type, rc); if ( CMIsNullObject(ci) ) { cl_log(LOG_WARNING, "Can not create resource instance."); return HA_FAIL; } CMReturnInstance(rslt, ci); CMReturnDone(rslt); return HA_OK; } /* should return primitives in group for primitive provider? no */ int resource_enum_insts(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, int need_inst, uint32_t type, CMPIStatus * rc) { struct ha_msg* names; int i, len; DEBUG_ENTER(); if ( cim_get_hb_status() != HB_RUNNING ) { rc->rc = CMPI_RC_ERR_FAILED; cl_log(LOG_WARNING, "Heartbeat not running."); return HA_FAIL; } if ( ( names = cim_get_all_rsc_list()) == NULL ) { rc->rc = CMPI_RC_ERR_FAILED; cl_log(LOG_WARNING, "Get resource list failed."); return HA_FAIL; } len = cim_list_length(names); for ( i = 0; i < len; i++) { char *rsc = NULL; if ((rsc = cim_list_index(names, i)) == NULL) { continue; } if ( type != cim_get_rsctype(rsc)){ continue; } /* should we return all sub resource of group/clone/master for the primitive resources enumeration operation? */ if ( need_inst ) { CMPIInstance * ci = NULL; ci = make_instance_byid(broker, ref, rsc, type, rc); if( ci ) { CMReturnInstance(rslt, ci); } } else { CMPIObjectPath * op; op = make_objectpath_byid(broker, ref, rsc, type, rc); if (op) { /* add object to rslt */ CMReturnObjectPath(rslt, op); } } } CMReturnDone(rslt); ha_msg_del(names); DEBUG_LEAVE(); return HA_OK; } int resource_cleanup(CMPIBroker * broker, char * classname, CMPIInstanceMI * mi, CMPIContext * ctx, uint32_t type, CMPIStatus * rc) { return HA_OK; } int resource_del_inst(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, CMPIStatus * rc) { char * rscid; CMPIString * string; int ret = HA_FAIL; if ((string = CMGetKey(ref, "Id", rc).value.string) == NULL ) { cl_log(LOG_WARNING, "Resource id missing."); return HA_FAIL; } rscid = CMGetCharPtr(string); ret = cim_remove_rsc(rscid); rc->rc = (ret==HA_OK)? CMPI_RC_OK : CMPI_RC_ERR_FAILED; return ret; } #if 0 static int resource_update_instattrs(const char *rscid, struct ha_msg * attributes) { int i, len; struct ha_msg * old = cim_get_rscattrs(rscid); /* delete nvpair */ len = (old) ? cim_msg_children_count(old): 0; for (i = 0; i < len; i++) { const char * id = cim_msg_child_name(old, i); if (id && cl_get_struct(attributes, id) == NULL ) { cim_remove_attrnvpair(rscid, id); } } len = cim_msg_children_count(attributes); for (i = 0; i < len; i++) { struct ha_msg * nvpair = cim_msg_child_index(attributes, i); if ( nvpair ) { const char * id = cim_msg_child_name(attributes, i); cim_update_attrnvpair(rscid, id, nvpair); } } return HA_OK; } #endif int resource_update_inst(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties, uint32_t type, CMPIStatus * rc) { struct ha_msg *resource = NULL /*, *attributes = NULL*/; char * rscid; int ret = 0; DEBUG_ENTER(); /* get resource id */ if ((rscid = CMGetKeyString(cop, "Id", rc)) == NULL ) { return HA_FAIL; } /* get original values, and set new values */ resource = cim_find_rsc(type, rscid); if ( type == TID_RES_PRIMITIVE ) { cl_msg_remove(resource, CIM_MSG_ATTR); cmpi_inst2msg(ci, HA_PRIMITIVE_RESOURCE, resource, rc); /* attributes = inst2attributes(cop, ci, rc); */ } else if (type == TID_RES_MASTER) { cmpi_inst2msg(ci, HA_MASTERSLAVE_RESOURCE, resource, rc); } else if (type == TID_RES_CLONE ) { cmpi_inst2msg(ci, HA_RESOURCE_CLONE, resource, rc); } /* update resource */ ret = cim_update_rsc(type, rscid, resource); if ( type != TID_RES_PRIMITIVE) { goto done; } /* update its attributes */ /* ret = resource_update_instattrs(rscid, attributes); ha_msg_del(attributes); */ done: ha_msg_del(resource); rc->rc = (ret==HA_OK) ? CMPI_RC_OK: CMPI_RC_ERR_FAILED; DEBUG_LEAVE(); return ret; } int resource_create_inst(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, uint32_t type, CMPIStatus * rc) { struct ha_msg *resource /*, *attributes*/; int ret = HA_FAIL; char * rscid = NULL; const char * rsctype = NULL; DEBUG_ENTER(); if((resource = ha_msg_new(16)) == NULL ) { return HA_FAIL; } /* get resource id */ if ((rscid = CMGetKeyString(cop, "Id", rc)) == NULL ) { ha_msg_del(resource); return HA_FAIL; } switch(type){ case TID_RES_PRIMITIVE: /* get resource attributes */ /* attributes = inst2attributes(cop, ci, rc); */ ret = cmpi_inst2msg(ci, HA_PRIMITIVE_RESOURCE, resource, rc); rsctype = "native"; break; case TID_RES_CLONE: ret = cmpi_inst2msg(ci, HA_RESOURCE_CLONE, resource, rc); ha_msg_add(resource, "advance", "clone"); rsctype = "clone"; break; case TID_RES_MASTER: ret = cmpi_inst2msg(ci, HA_MASTERSLAVE_RESOURCE, resource, rc); ha_msg_add(resource, "advance", "master"); rsctype = "master"; break; case TID_RES_GROUP: ha_msg_add(resource, "id", rscid); rsctype = "group"; break; } ha_msg_add(resource, "enabled", "false"); ret = cim_rscdb_store(type, rscid, resource); rc->rc = (ret==HA_OK) ? CMPI_RC_OK: CMPI_RC_ERR_FAILED; ha_msg_del(resource); DEBUG_LEAVE(); return ret; } #if 0 /* add a operation to resource */ int resource_add_operation(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, uint32_t type, CMPIArgs *in, CMPIArgs *out, CMPIStatus * rc) { CMPIObjectPath * opop; const char * key[] = {"Id", "SystemName", "SystemCreationClassName"}; char *id, *sysname, *syscrname, *namespace; struct ha_msg *msg; if((opop = CMGetArg(in, "Operation", rc).value.ref) == NULL ) { cl_log(LOG_ERR, "%s: can't get Operation ObjectPath.", __FUNCTION__); return HA_FAIL; } id = CMGetKeyString(opop, key[0], rc); sysname = CMGetKeyString(opop, key[1], rc); syscrname = CMGetKeyString(opop, key[2], rc); namespace = CMGetCharPtr(CMGetNameSpace(opop, rc)); if ((msg = cim_load_operation(sysname, id)) == NULL ) { cl_log(LOG_ERR, "%s: can't find instance for %s:%s:%s:%s.", __FUNCTION__, namespace, id, sysname, syscrname); return HA_FAIL; } cim_add_rscop(sysname, msg); ha_msg_del(msg); return HA_OK; } #endif /* add sub resource to group/clone/master-slave */ int resource_add_subrsc(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, uint32_t type, CMPIArgs *in, CMPIArgs *out, CMPIStatus * rc) { CMPIObjectPath * rscop; char *subrscid, *rscid; struct ha_msg *subrsc, *resource; int ret ; rscid = CMGetKeyString(ref, "Id", rc); resource = cim_find_rsc(type, rscid); if((rscop = CMGetArg(in, "Resource", rc).value.ref) == NULL ) { cl_log(LOG_ERR, "%s: can't get Resource ObjectPath.", __FUNCTION__); return HA_FAIL; } subrscid = CMGetKeyString(rscop, "Id", rc); subrsc = cim_find_rsc(TID_RES_PRIMITIVE, subrscid); if (subrsc == NULL ) { cl_log(LOG_ERR, "%s: resource %s not exist.", __FUNCTION__, subrscid); return HA_FAIL; } ret = cim_add_subrsc(resource, subrsc); ha_msg_del(subrsc); ha_msg_del(resource); rc->rc = (ret == HA_OK) ? CMPI_RC_OK : CMPI_RC_ERR_FAILED; return ret; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/resource_common.h000066400000000000000000000051201211477743100234230ustar00rootroot00000000000000/* * resource_common.h: common functions for resource providers * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef _RESROUCE_COMMON_H #define _RESOURCE_COMMON_H /* get a resource instance */ int resource_get_inst(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char ** properties, uint32_t type, CMPIStatus * rc); /* enumerate instances or instance names */ int resource_enum_insts(CMPIBroker* broker, char* classname, CMPIContext* ctx, CMPIResult * rslt, CMPIObjectPath * ref, int need_inst, uint32_t type, CMPIStatus * rc); /* cleanup provider */ int resource_cleanup(CMPIBroker* broker, char* classname, CMPIInstanceMI* mi, CMPIContext * ctx, uint32_t type, CMPIStatus * rc); /* delete resource */ int resource_del_inst(CMPIBroker* broker, char* classname, CMPIContext* ctx, CMPIResult * rslt, CMPIObjectPath * ref, CMPIStatus * rc); /* update resource */ int resource_update_inst(CMPIBroker* broker, char* classname, CMPIContext* ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties, uint32_t type, CMPIStatus * rc); /* create a resource */ int resource_create_inst(CMPIBroker* broker, char* classname, CMPIContext* ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, uint32_t type, CMPIStatus * rc); #if 0 /* add a operation to resource */ int resource_add_operation(CMPIBroker* broker, char*classname, CMPIContext* ctx, CMPIResult * rslt, CMPIObjectPath * ref, uint32_t type, CMPIArgs *in, CMPIArgs *out, CMPIStatus * rc); #endif /* add sub resource to group/clone/master-slave */ int resource_add_subrsc(CMPIBroker* broker, char* classname, CMPIContext* ctx, CMPIResult * rslt, CMPIObjectPath * ref, uint32_t type, CMPIArgs *in, CMPIArgs *out, CMPIStatus * rc); #endif pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/resource_group_provider.c000066400000000000000000000126371211477743100252070ustar00rootroot00000000000000/* * resource_group_provider.c: HA_ClusterResourceGroup provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include "cmpi_utils.h" #include "cluster_info.h" #include "resource_common.h" static const char * PROVIDER_ID = "cim-res-grp"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_ResourceGroup"; DeclareInstanceFunctions(ResourceGroup); /********************************************** * Instance **********************************************/ static CMPIStatus ResourceGroupCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMPIStatus rc; resource_cleanup(Broker, ClassName, mi, ctx, TID_RES_GROUP, &rc); CMReturn(CMPI_RC_OK); } static CMPIStatus ResourceGroupEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); resource_enum_insts(Broker, ClassName, ctx, rslt, ref, FALSE, TID_RES_GROUP, &rc); return rc; } static CMPIStatus ResourceGroupEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char ** properties) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); resource_enum_insts(Broker, ClassName, ctx, rslt, ref, TRUE, TID_RES_GROUP, &rc); return rc; } static CMPIStatus ResourceGroupGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc; PROVIDER_INIT_LOGGER(); resource_get_inst(Broker, ClassName, ctx, rslt, cop, properties, TID_RES_GROUP, &rc); return rc; } static CMPIStatus ResourceGroupCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); resource_create_inst(Broker, ClassName, ctx, rslt, cop, ci, TID_RES_GROUP, &rc); return rc; } static CMPIStatus ResourceGroupSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; resource_update_inst(Broker, ClassName, ctx, rslt, cop, ci, properties, TID_RES_GROUP, &rc); return rc; } static CMPIStatus ResourceGroupDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); resource_del_inst(Broker, ClassName, ctx, rslt, cop, &rc); return rc; } static CMPIStatus ResourceGroupExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath *ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /************************************************ * method ***********************************************/ static CMPIStatus ResourceGroupInvokeMethod(CMPIMethodMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, const char * method_name, CMPIArgs * in, CMPIArgs * out) { CMPIString * classname = NULL; CMPIStatus rc = {CMPI_RC_OK, NULL}; int ret = 0; classname = CMGetClassName(ref, &rc); if(strcasecmp(CMGetCharPtr(classname), ClassName) == 0 && strcasecmp(METHOD_ADD_PRIMITIVE_RESOURCE, method_name) == 0){ ret = resource_add_subrsc(Broker, ClassName, ctx, rslt, ref, TID_RES_GROUP, in, out, &rc); } CMReturnData(rslt, &ret, CMPI_uint32); CMReturnDone(rslt); CMReturn(CMPI_RC_OK); } static CMPIStatus ResourceGroupMethodCleanup(CMPIMethodMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } /************************************************************** * Entry *************************************************************/ DeclareInstanceMI(ResourceGroup, HA_ResourceGroupProvider, Broker); DeclareMethodMI(ResourceGroup, HA_ResourceGroupProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/rule_of_constraint_provider.c000066400000000000000000000214731211477743100260410ustar00rootroot00000000000000/* * rule_of_constraint_provider.c: HA_RuleOfLocationConstraint provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include "cluster_info.h" #include "cmpi_utils.h" static const char * PROVIDER_ID = "cim-ruleof"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_RuleOfLocationConstraint"; static char Left [] = "Constraint"; static char Right [] = "Rule"; static char LeftClassName [] = "HA_LocationConstraint"; static char RightClassName [] = "HA_LocationConstraintRule"; DeclareInstanceFunctions (RuleOfLocationConstraint); DeclareAssociationFunctions(RuleOfLocationConstraint); static int constraint_has_rule(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIObjectPath * consop, CMPIObjectPath * ruleop,CMPIStatus * rc) { char *id1, *id2; id1 = CMGetKeyString(consop, "Id", rc); id2 = CMGetKeyString(ruleop, "ConstraintId", rc); if ( id1 == NULL || id2 == NULL ) { return FALSE; } if ( strncmp(id1, id2, MAXLEN) == 0 ) { return TRUE; } return FALSE; } /********************************************** * Instance **********************************************/ static CMPIStatus RuleOfLocationConstraintCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus RuleOfLocationConstraintEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "RuleofConstraint: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_enum_insts(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, constraint_has_rule, NULL, FALSE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus RuleOfLocationConstraintEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "RuleofConstraint: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_enum_insts(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, constraint_has_rule, NULL, TRUE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus RuleOfLocationConstraintGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "RuleofConstraint: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_get_inst(Broker, ClassName, ctx, rslt, cop, Left, Right, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus RuleOfLocationConstraintCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus RuleOfLocationConstraintSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "RuleofConstraint: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus RuleOfLocationConstraintDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; return rc; } static CMPIStatus RuleOfLocationConstraintExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /**************************************************** * Association ****************************************************/ static CMPIStatus RuleOfLocationConstraintAssociationCleanup(CMPIAssociationMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus RuleOfLocationConstraintAssociators(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * assoc_class, const char * result_class, const char * role, const char * result_role, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "RuleofConstraint: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_enum_associators(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, assoc_class, result_class, role, result_role, constraint_has_rule, NULL, TRUE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus RuleOfLocationConstraintAssociatorNames(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * assoc_class, const char * result_class, const char * role, const char * result_role) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "RuleofConstraint: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_enum_associators(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, assoc_class, result_class, role, result_role, constraint_has_rule, NULL, FALSE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus RuleOfLocationConstraintReferences(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * result_class, const char * role, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "RuleofConstraint: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if ( assoc_enum_references(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, result_class, role, NULL, NULL, TRUE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus RuleOfLocationConstraintReferenceNames(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * result_class, const char * role) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if ( cim_get_hb_status() != HB_RUNNING ) { cl_log(LOG_ERR, "RuleofConstraint: heartbeat not running"); CMReturn(CMPI_RC_ERR_FAILED); } if ( assoc_enum_references(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, result_class, role, constraint_has_rule, NULL, FALSE, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } /************************************************************** * MI stub *************************************************************/ DeclareInstanceMI (RuleOfLocationConstraint, HA_RuleOfLocationConstraintProvider, Broker); DeclareAssociationMI(RuleOfLocationConstraint, HA_RuleOfLocationConstraintProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/simple_test.c000066400000000000000000000022621211477743100225530ustar00rootroot00000000000000/* * Tests * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include "cluster_info.h" #include #include #include #include "utils.h" #include "cluster_info.h" #include "mgmt_client.h" int main(int argc, char * argv[]) { return 0; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/software_identity_provider.c000066400000000000000000000171761211477743100257120ustar00rootroot00000000000000/* * cmpi_software_identity_provider.c: HA_SoftwareIdentity provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include "cmpi_utils.h" #include "cluster_info.h" static const char * PROVIDER_ID = "cim_soft"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_SoftwareIdentity"; DeclareInstanceFunctions(SoftwareIdentity); static CMPIStatus SoftwareIdentityCleanup(CMPIInstanceMI* mi, CMPIContext* ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus SoftwareIdentityEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref) { CMPIObjectPath * op = NULL; char * namespace = NULL; CMPIStatus rc; char instance_id [] = "LinuxHA:Cluster"; PROVIDER_INIT_LOGGER(); DEBUG_ENTER(); namespace = CMGetCharPtr(CMGetNameSpace(ref, &rc)); op = CMNewObjectPath(Broker, namespace, ClassName, &rc); if ( CMIsNullObject(op) ){ CMReturn(CMPI_RC_ERR_FAILED); } CMAddKey(op, "InstanceID", instance_id, CMPI_chars); CMReturnObjectPath(rslt, op); DEBUG_LEAVE(); CMReturn(CMPI_RC_OK); } static CMPIStatus SoftwareIdentityEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char ** properties) { CMPIObjectPath * op = NULL; CMPIEnumeration * en = NULL; char * namespace = NULL; CMPIStatus rc; PROVIDER_INIT_LOGGER(); DEBUG_ENTER(); namespace = CMGetCharPtr(CMGetNameSpace(ref, &rc)); op = CMNewObjectPath(Broker, namespace, ClassName, &rc); if ( CMIsNullObject(op) ){ CMReturn(CMPI_RC_ERR_FAILED); } en = CBEnumInstanceNames(Broker, ctx, ref, &rc); if ( CMIsNullObject(en) ){ CMReturn(CMPI_RC_ERR_FAILED); } while ( CMHasNext(en, &rc) ){ CMPIData ref_data; CMPIInstance * inst = NULL; ref_data = CMGetNext(en, &rc); if (ref_data.value.ref == NULL) { cl_log(LOG_INFO, "failed to get ref"); CMReturn(CMPI_RC_ERR_FAILED); } inst = CBGetInstance(Broker, ctx, ref_data.value.ref, properties, &rc); if ( CMIsNullObject(inst) ) { return rc; } CMReturnInstance(rslt, inst); } CMReturnDone(rslt); DEBUG_LEAVE(); CMReturn(CMPI_RC_OK); } static CMPIStatus SoftwareIdentityGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMPIInstance * ci = NULL; CMPIObjectPath * op = NULL; CMPIString * key; char * instance_id = NULL; char * namespace = NULL; char * hbversion = NULL; char ** match = NULL; char caption [] = "SoftwareIdentity"; int len = 0; struct ha_msg * info = NULL; PROVIDER_INIT_LOGGER(); DEBUG_ENTER(); key = CMGetKey(cop, "InstanceID", &rc).value.string; if ( CMIsNullObject(key) ) { CMReturn(CMPI_RC_ERR_FAILED); } instance_id = CMGetCharPtr(key); namespace = CMGetCharPtr(CMGetNameSpace(cop, &rc)); op = CMNewObjectPath(Broker, namespace, ClassName, &rc); if ( CMIsNullObject(op) ){ CMReturn(CMPI_RC_ERR_FAILED); } ci = CMNewInstance(Broker, op, &rc); if ( CMIsNullObject(ci) ) { CMReturn(CMPI_RC_ERR_FAILED); } /* get config table */ if ( ( info = cim_get_software_identity () ) == NULL ) { cl_log(LOG_ERR, "can't get software_identity"); CMReturn(CMPI_RC_ERR_FAILED); } /* search KEY_HBVERSION in keys */ hbversion = cim_strdup(cl_get_string(info, "hbversion")); /* set properties */ CMSetProperty(ci, "InstanceID", instance_id, CMPI_chars); CMSetProperty(ci, "VersionString", hbversion, CMPI_chars); CMSetProperty(ci, "Caption", caption, CMPI_chars); /* convert char * to int */ match = split_string(hbversion, &len, "."); if ( match && len == 3 ){ int major = 0, minor = 0, revision = 0; if ( match[0] ) major = atoi(match[0]); if ( match[1] ) minor = atoi(match[1]); if ( match[2] ) revision = atoi(match[2]); CMSetProperty(ci, "MajorVersion", &major, CMPI_uint16); CMSetProperty(ci, "MinorVersion", &minor, CMPI_uint16); CMSetProperty(ci, "RevisionNumber", &revision, CMPI_uint16); free_2d_array(match, len, cim_free); } CMReturnInstance(rslt, ci); CMReturnDone(rslt); cim_free(hbversion); ha_msg_del(info); DEBUG_LEAVE(); CMReturn(CMPI_RC_OK); } static CMPIStatus SoftwareIdentityCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus SoftwareIdentitySetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus SoftwareIdentityDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus SoftwareIdentityExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /***************************************************** * instance MI ****************************************************/ DeclareInstanceMI(SoftwareIdentity, HA_SoftwareIdentityProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/subresource_provider.c000066400000000000000000000326621211477743100245050ustar00rootroot00000000000000/* * sub_resource_provider.c: HA_SubResource provider * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include "cluster_info.h" #include "cmpi_utils.h" static const char * PROVIDER_ID = "cim-sub-res"; static CMPIBroker * Broker = NULL; static char ClassName [] = "HA_SubResource"; static char Left [] = "Antecedent"; static char Right [] = "Dependent"; static char LeftClassName [] = "HA_ClusterResource"; static char RightClassName [] = "HA_ClusterResource"; static char PrimitiveClassName [] = "HA_PrimitiveResource"; static char GroupClassName [] = "HA_ResourceGroup"; static char CloneClassName [] = "HA_ResourceClone"; static char MasterClassName [] = "HA_MasterSlaveResource"; static char UnknownClassName [] = "Unknown"; static CMPIArray * make_subrsc_array(CMPIBroker * broker, char * classname, CMPIContext * ctx, char * namespace, char * target_name, char * target_role, CMPIObjectPath * source_op, CMPIStatus * rc); static CMPIArray * make_resource_array(CMPIBroker * broker, char * classname, CMPIContext * ctx, char * namespace, char * target_name, char * target_role, CMPIObjectPath * source_op, CMPIStatus * rc); static int subresource(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIObjectPath * group_op, CMPIObjectPath * res_op, CMPIStatus * rc); DeclareInstanceFunctions(SubResource); DeclareAssociationFunctions(SubResource); /* make an array with all sub resources of source_op */ static CMPIArray * make_subrsc_array(CMPIBroker * broker, char * classname, CMPIContext * ctx, char * namespace, char * target_name, char * target_role, CMPIObjectPath * source_op, CMPIStatus * rc) { CMPIArray * array; struct ha_msg *sublist; const char * key[] = { "Id", "CreationClassName", "SystemName", "SystemCreationClassName"}; char *id, *crname, *sysname, * syscrname; int i, len; /* get keys */ id = CMGetKeyString(source_op, key[0], rc); crname = CMGetKeyString(source_op, key[1], rc); sysname = CMGetKeyString(source_op, key[2], rc); syscrname = CMGetKeyString(source_op, key[3], rc); if ( strcmp(crname, PrimitiveClassName) == 0 ) { return CMNewArray(broker, 0, CMPI_ref, rc); } if ((sublist = cim_get_subrsc_list(id)) == NULL ) { cl_log(LOG_ERR, "%s: can't find subresource of %s", __FUNCTION__, id); return NULL; } /* create a array to hold the object path */ len = cim_list_length(sublist); array = CMNewArray(broker, len, CMPI_ref, rc); /* for each sub primitive resource */ for ( i = 0; i < len; i++ ) { uint32_t rsctype; CMPIObjectPath * target_op; char * subid; subid = cim_list_index(sublist, i); rsctype = cim_get_rsctype(subid); if (rsctype == TID_RES_PRIMITIVE ) { crname = PrimitiveClassName; } else if ( rsctype == TID_RES_GROUP ) { crname = GroupClassName; } else if ( rsctype == TID_RES_GROUP ) { crname = CloneClassName; } else if ( rsctype == TID_RES_MASTER ) { crname = MasterClassName; } else { crname = UnknownClassName; } /* create object path */ target_op = CMNewObjectPath(broker, namespace, crname, rc); if ( CMIsNullObject(target_op) ) { continue; } /* set keys */ CMAddKey(target_op, "Id", subid, CMPI_chars); CMAddKey(target_op, "SystemName", sysname, CMPI_chars); CMAddKey(target_op, "SystemCreationClassName", syscrname, CMPI_chars); CMAddKey(target_op, "CreationClassName", crname, CMPI_chars); /* add to array */ CMSetArrayElementAt(array, i, &target_op, CMPI_ref); } ha_msg_del(sublist); return array; } static CMPIArray * make_resource_array(CMPIBroker * broker, char * classname, CMPIContext * ctx, char * namespace, char * target_name, char * target_role, CMPIObjectPath * source_op, CMPIStatus * rc) { if ( target_name == NULL ) { cl_log(LOG_ERR, "%s: target name can't be NULL", __FUNCTION__); return NULL; } if ( strcmp(target_role, Left) == 0 ) { /* target is resource group */ return cmpi_instance_names(broker,namespace, target_name, ctx, rc); } else if ( strcmp(target_role, Right) == 0 ) { /* target is primitive */ return make_subrsc_array(broker, classname, ctx, namespace, target_name, target_role, source_op, rc); } /* else */ return NULL; } static int subresource(CMPIBroker * broker, char * classname, CMPIContext * ctx, CMPIObjectPath * group_op, CMPIObjectPath * res_op, CMPIStatus * rc) { char *rscid, *groupid; int i, len; struct ha_msg * sublist; rscid = CMGetKeyString(res_op, "Id", rc); groupid = CMGetKeyString(group_op, "Id", rc); if ( rscid == NULL || groupid == NULL ) { return FALSE; } /* get the this group's sub resources */ if ((sublist = cim_get_subrsc_list(groupid)) == NULL ) { return 0; } /* looking for the rsc */ len = cim_list_length(sublist); for ( i = 0; i < len; i++ ) { char * subid = cim_list_index(sublist, i); if ( strncmp(rscid, subid?subid:"", MAXLEN ) == 0 ) { /* found */ return TRUE; } } ha_msg_del(sublist); return FALSE; } /********************************************** * Instance **********************************************/ static CMPIStatus SubResourceCleanup(CMPIInstanceMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus SubResourceEnumInstanceNames(CMPIInstanceMI * mi, CMPIContext* ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; if (cim_get_hb_status() != HB_RUNNING ) { CMReturn(CMPI_RC_ERR_FAILED); } assoc_enum_insts(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, subresource, make_resource_array, FALSE, &rc); return rc; } static CMPIStatus SubResourceEnumInstances(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; if (cim_get_hb_status() != HB_RUNNING ) { CMReturn(CMPI_RC_ERR_FAILED); } assoc_enum_insts(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, subresource, make_resource_array, TRUE, &rc); return rc; } static CMPIStatus SubResourceGetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; if (cim_get_hb_status() != HB_RUNNING ) { CMReturn(CMPI_RC_ERR_FAILED); } assoc_get_inst(Broker, ClassName, ctx, rslt, cop, Left, Right, &rc); return rc; } static CMPIStatus SubResourceCreateInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus SubResourceSetInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, CMPIInstance * ci, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } static CMPIStatus SubResourceDeleteInstance(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop) { CMPIStatus rc = {CMPI_RC_OK, NULL}; return rc; } static CMPIStatus SubResourceExecQuery(CMPIInstanceMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath *ref, char * lang, char * query) { CMPIStatus rc = {CMPI_RC_OK, NULL}; CMSetStatusWithChars(Broker, &rc, CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED"); return rc; } /**************************************************** * Association ****************************************************/ static CMPIStatus SubResourceAssociationCleanup(CMPIAssociationMI * mi, CMPIContext * ctx) { CMReturn(CMPI_RC_OK); } static CMPIStatus SubResourceAssociators(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * assoc_class, const char * result_class, const char * role, const char * result_role, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if (cim_get_hb_status() != HB_RUNNING ) { CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_enum_associators(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, assoc_class, result_class, role, result_role, subresource, make_resource_array, 1, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus SubResourceAssociatorNames(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * assoc_class, const char * result_class, const char * role, const char * result_role) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if (cim_get_hb_status() != HB_RUNNING ) { CMReturn(CMPI_RC_ERR_FAILED); } if (assoc_enum_associators(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, assoc_class, result_class, role, result_role, subresource, make_resource_array, 0, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus SubResourceReferences(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * result_class, const char * role, char ** properties) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if (cim_get_hb_status() != HB_RUNNING ) { CMReturn(CMPI_RC_ERR_FAILED); } if ( assoc_enum_references(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, result_class, role, subresource, make_resource_array, 1, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } static CMPIStatus SubResourceReferenceNames(CMPIAssociationMI * mi, CMPIContext * ctx, CMPIResult * rslt, CMPIObjectPath * cop, const char * result_class, const char * role) { CMPIStatus rc = {CMPI_RC_OK, NULL}; PROVIDER_INIT_LOGGER(); if (cim_get_hb_status() != HB_RUNNING ) { CMReturn(CMPI_RC_ERR_FAILED); } if ( assoc_enum_references(Broker, ClassName, ctx, rslt, cop, Left, Right, LeftClassName, RightClassName, result_class, role, subresource, make_resource_array, 0, &rc) != HA_OK ) { return rc; } CMReturn(CMPI_RC_OK); } /*************************************** * installed MIs **************************************/ DeclareInstanceMI(SubResource, HA_SubResourceProvider, Broker); DeclareAssociationMI(SubResource, HA_SubResourceProvider, Broker); pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/tests/000077500000000000000000000000001211477743100212175ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/tests/CreateFilter.xml000066400000000000000000000025721211477743100243200ustar00rootroot00000000000000 CIM_UnitaryComputerSystem hadev4 CIM_IndicationFilter Filter01 SELECT * FROM LinuxHA_Indication WQL root/cimv2 pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/tests/CreateHandler.xml000066400000000000000000000022351211477743100244440ustar00rootroot00000000000000 CIM_UnitaryComputerSystem hadev4 CIM_ListenerDestinationCIMXML Handler01 file://linuxha_indication.log pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/tests/CreateSubscription.xml000066400000000000000000000055341211477743100255600ustar00rootroot00000000000000 CIM_UnitaryComputerSystem hadev4 CIM_IndicationFilter Filter01 CIM_UnitaryComputerSystem hadev4 CIM_ListenerDestinationCIMXML Handler01 2 pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/tests/DeleteFilter.xml000066400000000000000000000022731211477743100243150ustar00rootroot00000000000000 CIM_UnitaryComputerSystem hadev4 CIM_IndicationFilter Filter01 pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/tests/DeleteHandler.xml000066400000000000000000000023161211477743100244430ustar00rootroot00000000000000 CIM_UnitaryComputerSystem hadev4 CIM_ListenerDestinationCIMXML Handler01 pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/tests/DeleteSubscription.xml000066400000000000000000000050721211477743100255540ustar00rootroot00000000000000 CIM_IndicationFilter Filter01 CIM_UnitaryComputerSystem hadev4 CIM_ListenerDestinationCIMXML Handler01 CIM_UnitaryComputerSystem hadev4 pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/tests/ResourceTest.sh000077500000000000000000000205261211477743100242120ustar00rootroot00000000000000#!/bin/sh if test $# != 2; then echo "usage: $0 user password." exit 1 fi USER=$1 PASSWD=$2 CIB=/var/lib/heartbeat/crm/cib.xml function wait_cib_updated() { sleep 2 } function resource_query () { crm_resource -Q -r $1 } #create a primitive resource function create_primitive_resource() { TYPE=$1 RSC_ID=$2 echo "creating resource, type: $TYPE, id: $RSC_ID." wbemcli ci http://$USER:$PASSWD@localhost/root/cimv2:HA_PrimitiveResource.Id="$RSC_ID",\ CreationClassName="HA_PrimitiveResource",\ SystemName="LinuxHACluster",\ SystemCreationClassName="HA_LinuxHA" \ ResourceClass="ocf",\ Type="$TYPE",\ Provider="heartbeat",\ Id="$RSC_ID",\ CreationClassName="HA_PrimitiveResource",\ SystemName="LinuxHACluster",\ SystemCreationClassName="HA_LinuxHA" > /dev/null } #create its attributes function create_attribute() { RSC_ID=$1 ATTR_ID=$2 NAME=$3 VALUE=$4 echo "creating attribute for resource: $RSC_ID, id: $ATTR_ID, $NAME=$VALUE." wbemcli ci http://$USER:$PASSWD@localhost/root/cimv2:HA_InstanceAttributes.Id="$ATTR_ID",\ ResourceId="$RSC_ID" \ Id="$ATTR_ID",\ ResourceId="$RSC_ID",\ Name="$NAME",\ Value="$VALUE" > /dev/null } #create its operations function create_operation() { RSC_ID=$1 OP_ID=$2 NAME=$3 INTERVAL=$4 TIMEOUT=$5 echo "creating opertion for resource: $RSC_ID, id: $OP_ID, $NAME,$INTERVAL,$TIMEOUT." wbemcli ci http://$USER:$PASSWD@localhost/root/cimv2:HA_Operation.Id="$OP_ID",\ ResourceId="$RSC_ID" \ Id="$OP_ID",\ ResourceId="$RSC_ID",\ Name="$NAME",\ Interval="$INTERVAL",\ TimeOut="$TIMEOUT" > /dev/null } #add to CIB function cib_add_resource() { RSC_ID=$1 echo "adding resource: $RSC_ID to CIB." wbemcli cm http://$USER:$PASSWD@localhost/root/cimv2:HA_ClusteringService.Id=default_service_id \ AddResource.Resource=http://localhost/root/cimv2:HA_PrimitiveResource.Id="$RSC_ID" > /dev/null } #delete function delete_resource () { CLASSNAME=$1 RSC_ID=$2 echo "deleting resource: $RSC_ID." wbemcli di http://$USER:$PASSWD@localhost/root/cimv2:$CLASSNAME.Id="$RSC_ID",\ CreationClassName="$CLASSNAME",\ SystemName="LinuxHACluster",\ SystemCreationClassName="HA_LinuxHA" } # create a resource group function create_resource_group() { GROUP_ID=$1 echo "creating resource group, id: $GROUP_ID." wbemcli ci http://$USER:$PASSWD@localhost/root/cimv2:HA_ResourceGroup.Id="$GROUP_ID",\ CreationClassName="HA_ResourceGroup",\ SystemName="LinuxHACluster",\ SystemCreationClassName="HA_LinuxHA" \ Id="$GROUP_ID",\ CreationClassName="HA_ResourceGroup",\ SystemName="LinuxHACluster",\ SystemCreationClassName="HA_LinuxHA" > /dev/null } #add resource to group function group_add_resource() { GROUP_ID=$1 RSC_ID=$2 echo "adding resource: $RSC_ID to resource group $GROUP_ID." wbemcli cm http://$USER:$PASSWD@localhost/root/cimv2:HA_ResourceGroup.Id=$GROUP_ID,\ CreationClassName="HA_ResourceGroup",\ SystemName="LinuxHACluster",\ SystemCreationClassName="HA_LinuxHA" \ AddPrimitiveResource.Resource=http://localhost/root/cimv2:HA_PrimitiveResource.Id="$RSC_ID" > /dev/null } function create_location_constraint() { CONS_ID=$1 RSC_ID=$2 NODE=$3 SCORE=$4 echo "creating location_constraint $CONS_ID for id: $RSC_ID, $NODE,$SCORE" wbemcli ci http://$USER:$PASSWD@localhost/root/cimv2:HA_LocationConstraint.Id="$CONS_ID",\ CreationClassName="HA_LocationConstraint",\ SystemName="LinuxHACluster",\ SystemCreationClassName="HA_LinuxHA" \ Id="$CONS_ID",\ CreationClassName="HA_LocationConstraint",\ SystemName="LinuxHACluster",\ SystemCreationClassName="HA_LinuxHA",\ Resource="$RSC_ID",\ Score=$SCORE wbemcli ci http://$USER:$PASSWD@localhost/root/cimv2:HA_LocationConstraintRule.Id="${CONS_ID}_rule",\ ConstraintId="$CONS_ID" \ Id="${CONS_ID}_rule",\ ConstraintId="$CONS_ID",\ Attribute="node",\ Operation="eq",\ Value="$NODE" } function delete_constraint() { CLASSNAME=$1 CONS_ID=$2 echo "deleting constraint: $CONS_ID." wbemcli di http://$USER:$PASSWD@localhost/root/cimv2:$CLASSNAME.Id="$CONS_ID",\ CreationClassName="$CLASSNAME",\ SystemName="LinuxHACluster",\ SystemCreationClassName="HA_LinuxHA" } function create_order_constraint() { CONS_ID=$1 FROM=$2 TO=$3 TYPE=$4 echo "creating order_constraint $CONS_ID, $FROM, $TO, $TYPE" wbemcli ci http://$USER:$PASSWD@localhost/root/cimv2:HA_OrderConstraint.Id="$CONS_ID",\ CreationClassName="HA_OrderConstraint",\ SystemName="LinuxHACluster",\ SystemCreationClassName="HA_LinuxHA" \ Id="$CONS_ID",\ CreationClassName="HA_OrderConstraint",\ SystemName="LinuxHACluster",\ SystemCreationClassName="HA_LinuxHA",\ From="$FROM",\ To="$TO",\ OrderType=$TYPE } function create_colocation_constraint() { CONS_ID=$1 FROM=$2 TO=$3 SCORE=$4 echo "creating colocation_constraint $CONS_ID, $FROM, $TO, $SCORE" wbemcli ci http://$USER:$PASSWD@localhost/root/cimv2:HA_ColocationConstraint.Id="$CONS_ID",\ CreationClassName="HA_ColocationConstraint",\ SystemName="LinuxHACluster",\ SystemCreationClassName="HA_LinuxHA" \ Id="$CONS_ID",\ CreationClassName="HA_ColocationConstraint",\ SystemName="LinuxHACluster",\ SystemCreationClassName="HA_LinuxHA",\ From="$FROM",\ To="$TO",\ Score=$SCORE } ############################################################## # primitive resource ############################################################## echo "---------------------------------------------------" echo "Primitive Resource Creation test" echo "---------------------------------------------------" RESOURCE_ID=test_primitive_resource ATTRIBUTE_ID=${RESOURCE_ID}_ip delete_resource HA_PrimitiveResource $RESOURCE_ID 2>/dev/null create_primitive_resource "IPaddr" "$RESOURCE_ID" create_attribute $RESOURCE_ID $ATTRIBUTE_ID "ip" "127.0.0.111" create_attribute $RESOURCE_ID ${RESOURCE_ID}_nic "nic" "lo" cib_add_resource $RESOURCE_ID create_attribute $RESOURCE_ID ${RESOURCE_ID}_netmask "netmask" "255.255.255.0" create_operation $RESOURCE_ID ${RESOURCE_ID}_monitor "monitor" "10s" "20s" wait_cib_updated resource_query $RESOURCE_ID echo "---------------------------------------------------" echo "Primitive Resource Creation test 2" echo "---------------------------------------------------" RESOURCE_ID2=test_primitive_resource_2 ATTRIBUTE_ID2=${RESOURCE_ID2}_ip delete_resource HA_PrimitiveResource $RESOURCE_ID2 2>/dev/null create_primitive_resource "IPaddr" "$RESOURCE_ID2" create_attribute $RESOURCE_ID2 $ATTRIBUTE_ID2 "ip" "127.0.0.112" cib_add_resource $RESOURCE_ID2 wait_cib_updated resource_query $RESOURCE_ID2 echo "---------------------------------------------------" echo "Location Constraint creation test" echo "---------------------------------------------------" delete_constraint HA_LocationConstraint ${RESOURCE_ID}_location_cons create_location_constraint ${RESOURCE_ID}_location_cons ${RESOURCE_ID} "node1" "1000" wait_cib_updated echo "---------------------------------------------------" echo "Location Constraint creation test" echo "---------------------------------------------------" delete_constraint HA_OrderConstraint test_order_cons create_order_constraint test_order_cons ${RESOURCE_ID} ${RESOURCE_ID2} "after" wait_cib_updated echo "---------------------------------------------------" echo "Colocation Constraint creation test" echo "---------------------------------------------------" delete_constraint HA_ColocationConstraint test_colocation_cons create_colocation_constraint test_colocation_cons ${RESOURCE_ID} ${RESOURCE_ID2} 1000 wait_cib_updated ############################################################# # resource group ############################################################# GROUP_ID=test_resource_group delete_resource HA_ResourceGroup $GROUP_ID 2>/dev/null echo "---------------------------------------------------" echo "Resource Group Creation test" echo "---------------------------------------------------" SUB_RESOURCE_ID=sub_resource_1 SUB_ATTRIBUTE_ID=${SUB_RESOURCE_ID}_ip create_primitive_resource "IPaddr" "$SUB_RESOURCE_ID" create_attribute $SUB_RESOURCE_ID $SUB_ATTRIBUTE_ID "ip" "127.0.0.200" create_resource_group $GROUP_ID group_add_resource $GROUP_ID $SUB_RESOURCE_ID cib_add_resource $GROUP_ID wait_cib_updated resource_query $GROUP_ID echo "---------------------------------------------------" echo "Resource Group Add Resource test" echo "---------------------------------------------------" SUB_RESOURCE_ID2=sub_resource_2 SUB_ATTRIBUTE_ID2=${SUB_RESOURCE_ID2}_ip create_primitive_resource "IPaddr" $SUB_RESOURCE_ID2 create_attribute $SUB_RESOURCE_ID2 $SUB_ATTRIBUTE_ID2 "ip" "127.0.0.201" group_add_resource $GROUP_ID $SUB_RESOURCE_ID2 wait_cib_updated resource_query $GROUP_ID pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/tests/runtest.sh000077500000000000000000000131341211477743100232640ustar00rootroot00000000000000#!/bin/sh # # Linux-HA: CIM Provider tests # # Author: Jia Ming Pan # Copyright (c) 2005 International Business Machines # Licensed under the GNU GPL. # # # set quite to 0 to disable result outputs quite=0 color=1 # loop iteration iteration=$1 if [ X"$iteration" = "X" ]; then iteration=1 fi #set to your username, password, host echo -en "user: " read USERNAME echo -en "password: " read PASSWD HOST=localhost NAMESPACE=root/cimv2 WBEMCLI=`which wbemcli` if test $? != 0; then echo "wbemcli not found, please install sblim-wbemcli" exit 1 fi WBEMCLI="$WBEMCLI -nl" INST_CLASSES="HA_Cluster HA_SoftwareIdentity HA_ClusterNode HA_ResourceGroup HA_ResourceClone HA_PrimitiveResource HA_MasterSlaveResource HA_OrderConstraint HA_LocationConstraint HA_ColocationConstraint HA_InstanceAttributes HA_Operation" ASSOC_CLASSES="HA_ParticipatingNode HA_InstalledSoftwareIdentity HA_SubResource HA_HostedResource HA_AttributesOfResource HA_OperationOnResource" ALL_CLASSES="$INST_CLASSES $ASSOC_CLASSES" function get_assoc_classes_of () { case $1 in HA_Cluster) echo "HA_ParticipatingNode HA_InstalledSoftwareIdentity";; HA_ClusterNode) echo "HA_ParticipatingNode HA_HostedResource";; HA_PrimitiveResource) echo "HA_SubResource HA_HostedResource HA_AttributesOfResource HA_OperationOnResource";; HA_MasterSlaveResource|HA_ResourceClone|HA_ResourceGroup) echo "HA_SubResource";; HA_SoftwareIdentity) echo "HA_InstalledSoftwareIdentity";; *) echo "" esac } if test $color = 1; then HL="\33[1m" #high light RED="\33[31m" GREEN="\33[32m" BLUE="\33[34m" YELLOW="\33[33m" END="\33[0m" fi TMP=`mktemp` success=0 failure=0 empty=0 total=0 function call_empty () { echo -e $'\t'$HL$YELLOW"[ EMPTY ]"$END empty=`expr $empty + 1` } function call_ok () { echo -e $'\t'$HL$GREEN"[ OK ]"$END success=`expr $success + 1` } function call_failed () { echo -e $'\t'$HL$RED"[ FAILED ]"$END cat $TMP failure=`expr $failure + 1` } EMPTY=0 ERROR=1 SUCCESS=2 function check_result () { echo if test $quite = 0; then cat $TMP fi # empty lc=`cat $TMP | wc -l` if [ $lc -eq 0 ]; then call_empty return $EMPTY fi # error grep -e FAILED -e ERR -e "*" -e Exception -e error $TMP >/dev/null 2>&1 if [ $? -eq 0 ]; then call_failed return $ERROR fi # success call_ok return $SUCCESS } ################################################################ function cim_get_instance () { ref=$1 echo -en gi$'\t'$HL"http://$USERNAME:"*PASSWD*"@"$ref$END result=`$WBEMCLI gi http://$USERNAME:$PASSWD@$ref >$TMP 2>&1` check_result return $? } function cim_enum_instances () { op=$1 class=$2 echo -en $op$'\t'$HL$class$END result=`$WBEMCLI $op http://$USERNAME:$PASSWD@$HOST/$NAMESPACE:$class >$TMP 2>&1` check_result return $? } function cim_enum_associators () { op=$1 ref=$2 assoc_class=$3 echo -en $op$'\t'$HL"http://"$USERNAME:"*PASSWD*"@$ref$END -ac $assoc_class result=`$WBEMCLI $op http://$USERNAME:$PASSWD@$ref -ac $assoc_class >$TMP 2>&1` check_result return $? } function cim_enum_references () { op=$1 ref=$2 assoc_class=$3 echo -en $op$'\t'$HL"http://"$USERNAME:"*PASSWD*"@$ref$END -arc $assoc_class result=`$WBEMCLI $op http://$USERNAME:$PASSWD@$ref -arc $assoc_class >$TMP 2>&1` check_result return $? } ### EnumerateInstanceNames, EnuerateInstances, GetInstance. function instance_test () { for class in $ALL_CLASSES; do cim_enum_instances "ein" $class if [ $? -eq $SUCCESS ]; then result=`cat $TMP` for ref in $result; do cim_get_instance "$ref" done fi cim_enum_instances "ei" $class done } function assoc_test () { for inst_class in $INST_CLASSES; do result="" cim_enum_instances "ein" $inst_class if [ $? -eq $SUCCESS ]; then result=`cat $TMP` else continue fi for ref in $result; do assoc_classes=`get_assoc_classes_of $inst_class` for assoc_class in $assoc_classes; do cim_enum_associators ain $ref $assoc_class cim_enum_associators ai $ref $assoc_class cim_enum_references rin $ref $assoc_class cim_enum_references ri $ref $assoc_class done done done } ## Main ################ for i in `seq $iteration`; do instance_test assoc_test done total=`expr $empty + $failure + $success` echo Total: $total, Success: $success, Failure: $failure, Empty: $empty rm -rf $TMP pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/tests/subscription.sh000077500000000000000000000006361211477743100243070ustar00rootroot00000000000000#!/bin/sh TMP=`mktemp` WBEMCAT=`which wbemcat` if test $? != 0; then echo wbemcat not found! exit fi wbemcat CreateFilter.xml > $TMP wbemcat CreateHandler.xml > $TMP wbemcat CreateSubscription.xml > $TMP echo echo Create subscription, echo Press any key to terminate ... read wbemcat DeleteFilter.xml > $TMP wbemcat DeleteSubscription.xml > $TMP wbemcat DeleteHandler.xml > $TMP rm -rf $TMP pacemaker-mgmt-pacemaker-mgmt-2.1.2/cim/utils.c000066400000000000000000000270531211477743100213700ustar00rootroot00000000000000/* * utils.c: utilities * * Author: Jia Ming Pan * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include "cluster_info.h" #include "utils.h" int debug_level = 10; static char * pathname_encode(const char *); int cim_init_logger(const char * entity) { char * inherit_debuglevel; int debug_level = 2; inherit_debuglevel = getenv(HADEBUGVAL); if (inherit_debuglevel != NULL) { debug_level = atoi(inherit_debuglevel); if (debug_level > 2) { debug_level = 2; } } cl_log_set_entity(entity); cl_log_enable_stderr(debug_level?TRUE:FALSE); cl_log_set_facility(HA_LOG_FACILITY); return HA_OK; } int run_shell_cmnd(const char *cmnd, int *ret, char ***out, char ***err) /* err not used currently */ { FILE * fstream = NULL; char buffer [4096]; int cmnd_rc, rc, i; DEBUG_ENTER(); if ( (fstream = popen(cmnd, "r")) == NULL ){ cl_log(LOG_ERR, "run_shell_cmnd: popen error: %s", strerror(errno)); return HA_FAIL; } if ( (*out = cim_malloc(sizeof(char*)) ) == NULL ) { cl_log(LOG_ERR, "run_shell_cmnd: failed malloc."); return HA_FAIL; } (*out)[0] = NULL; i = 0; while (!feof(fstream)) { if ( fgets(buffer, 4096, fstream) != NULL ){ /** add buffer to out **/ *out = cim_realloc(*out, (i+2) * sizeof(char*)); if ( *out == NULL ) { rc = HA_FAIL; goto exit; } (*out)[i] = cim_strdup(buffer); (*out)[i+1] = NULL; }else{ continue; } i++; } rc = HA_OK; exit: if ( (cmnd_rc = pclose(fstream)) == -1 ){ /*** WARNING log ***/ cl_log(LOG_WARNING, "failed to close pipe."); } *ret = cmnd_rc; DEBUG_LEAVE(); return rc; } char ** regex_search(const char * reg, const char * str, int * len) { regex_t regexp; const int maxmatch = 16; regmatch_t pm[16]; int i, ret, nmatch = 0; char **match = NULL; DEBUG_ENTER(); *len = 0; ret = regcomp(®exp, reg, REG_EXTENDED); if ( ret != 0) { cl_log(LOG_ERR, "regex_search: error regcomp regex %s.", reg); return HA_FAIL; } ret = regexec(®exp, str, nmatch, pm, 0); if ( ret == REG_NOMATCH ){ regfree(®exp); cl_log(LOG_ERR, "regex_search: no match."); return NULL; }else if (ret != 0){ cl_log(LOG_ERR, "regex_search: error regexec.\n"); regfree(®exp); return NULL; } for(nmatch=0; pm[nmatch].rm_so != -1 && nmatch < maxmatch; nmatch++); if ( (match = cim_malloc(nmatch*sizeof(char *))) == NULL ) { cl_log(LOG_ERR, "regex_search: alloc_failed."); regfree(®exp); return NULL; } *len = nmatch; for(i = 0; i < maxmatch && i < nmatch; i++){ int str_len = pm[i].rm_eo - pm[i].rm_so; if ((match[i] = cim_malloc(str_len + 1))) { strncpy( match[i], str + pm[i].rm_so, str_len); match[i][str_len] = EOS; } } regfree(®exp); DEBUG_LEAVE(); return match; } void free_2d_zarray(void *zarray, cim_free_t free) { void ** z = (void **)zarray; int i = 0; void * p; while ((p=z[i++])) { free(p); } cim_free(z); } void free_2d_array(void * a, int len, cim_free_t free) { int i; void ** array = (void **)a; for (i=0; iuuid[i]); } return str; } void cim_assert(const char * assertion, int line, const char * file) { cl_log(LOG_ERR, "Assertion \"%s\" failed on line %d in file \"%s\"" , assertion, line, file); exit(1); } char ** split_string(const char* string, int *len, const char *delim) { char **strings = NULL; const char *p; *len = 0; while(*string){ char * token = NULL; /* eat up delim chars */ while (*string && strchr(delim, *string)) { string++; continue; } if(!*string) { break; } /* reach a delim char */ p = string; while ( *p && !strchr(delim, *p) ) { p ++; continue; } /* copy string~(p-1) to token */ token = cim_malloc(p-string+1); if ( token == NULL ) { return strings; } memcpy(token, string, p - string); token[p-string] = EOS; strings = cim_realloc(strings, (*len+1) * sizeof(char *)); if ( strings == NULL ) { return NULL; } strings[*len] = token; *len = *len + 1; string = p; } return strings; } int cim_msg2disk(const char *objpathname, struct ha_msg *msg) { struct stat st; FILE *fobj; char pathname[MAXLEN], *buf; char *msgstr = NULL; if ( stat(HA_CIM_VARDIR, &st) < 0 ) { if ( errno == ENOENT ) { /* not exist, create */ if ( mkdir(HA_CIM_VARDIR, 0660) < 0){ cl_log(LOG_ERR,"msg2disk: mkdir failed."); cl_log(LOG_ERR,"reason:%s",strerror(errno)); return HA_FAIL; } } else { cl_log(LOG_ERR, "msg2disk: stat faild."); cl_log(LOG_ERR,"reason:%d(%s)",errno,strerror(errno)); return HA_FAIL; } } /* check stat */ /* write msg*/ if((buf = pathname_encode(objpathname))== NULL ) { return HA_FAIL; } snprintf(pathname, MAXLEN, "%s/%s", HA_CIM_VARDIR, buf); cim_free(buf); if ( ( fobj = fopen(pathname, "w") ) == NULL ) { cl_log(LOG_WARNING, "msg2disk: can't open file."); cl_log(LOG_WARNING, "reason:%d(%s)", errno, strerror(errno)); return HA_FAIL; } if ( msg->nfields == 0 ) { fclose(fobj); return HA_OK; } if ((msgstr = msg2string(msg)) == NULL ) { cl_log(LOG_ERR, "cim_msg2disk: msgstr NULL."); return HA_FAIL; } fprintf(fobj, "%s", msgstr); fclose(fobj); return HA_OK; } struct ha_msg* cim_disk2msg(const char *objpathname) { char pathname[MAXLEN], *buf; FILE *fobj = NULL; int ret; int bytes = 0; struct stat st; struct ha_msg *msg = NULL; if((buf = pathname_encode(objpathname))== NULL ) { return NULL; } snprintf(pathname, MAXLEN, "%s/%s", HA_CIM_VARDIR, buf); cim_free(buf); if ( ( ret = stat(pathname, &st)) < 0 ) { cl_log(LOG_WARNING, "disk2msg: stat faild for %s.", pathname); cl_log(LOG_WARNING,"reason:%d(%s)",errno,strerror(errno)); return NULL; } if (st.st_size == 0 ) { cl_log(LOG_WARNING, "disk2msg: size of %s is zero.", objpathname); return NULL; } if ((buf = cim_malloc(st.st_size)) == NULL ) { cl_log(LOG_ERR, "disk2msg: alloc msg failed for %s.", objpathname); return NULL; } if ( (fobj = fopen(pathname, "r")) == NULL ) { cl_log(LOG_WARNING, "msg2disk: can't open file %s.", pathname); cl_log(LOG_WARNING, "reason:%d(%s)", errno, strerror(errno)); return NULL; } while ( (ret = fread(buf, st.st_size, 1, fobj))){ bytes += ret*st.st_size; } if ( !feof(fobj) ) { cl_log(LOG_ERR, "msg2disk: read error for %s.", objpathname); cl_log(LOG_ERR, "reason: %d(%s).", errno, strerror(errno)); cim_free(msg); return NULL; } if ( bytes != st.st_size ) { cl_log(LOG_ERR, "msg2disk: incompete read:"); cl_log(LOG_ERR, "read: %d vs size: %d.", bytes, (int)st.st_size); cim_free(msg); return NULL; } msg = string2msg(buf, bytes); cim_free(buf); fclose(fobj); return msg; } int cim_disk_msg_del(const char *objpathname) { char fullpathname[MAXLEN]; char * pathname = pathname_encode(objpathname); snprintf(fullpathname, MAXLEN, "%s/%s", HA_CIM_VARDIR, pathname); cim_debug2(LOG_INFO, "%s: unlink %s", __FUNCTION__, fullpathname); unlink(fullpathname); cim_free(pathname); return HA_OK; } char* cim_dbget(const char *pathname, const char*key) { struct ha_msg *db = cim_disk2msg(pathname); const char * value; if ( db == NULL ) { return NULL; } value = cl_get_string(db, key); if ( value == NULL || strncmp(value, "null", MAXLEN) == 0) { return NULL; } return cim_strdup(value); } int cim_dbput(const char *pathname, const char*key, const char*value) { int ret; struct ha_msg* db = cim_disk2msg(pathname); if ( db == NULL ) { if ( (db = ha_msg_new(1)) == NULL ) { cl_log(LOG_ERR, "cim_dbput: alloc db failed."); return HA_FAIL; } } if ((cl_msg_modstring(db, key, value?value:"null")) != HA_OK ) { ha_msg_del(db); cl_log(LOG_ERR, "cim_dbput: put value failed."); return HA_FAIL; } ret = cim_msg2disk(pathname, db); ha_msg_del(db); return HA_OK; } int cim_dbdel(const char *pathname, const char*key) { int ret; struct ha_msg* db = cim_disk2msg(pathname); if ( db == NULL ) { cl_log(LOG_ERR, "cim_dbdel: get db failed."); return HA_FAIL; } if ((cl_msg_remove(db, key)) != HA_OK ) { ha_msg_del(db); cl_log(LOG_ERR, "cim_dbdel: remove failed."); return HA_FAIL; } ret = cim_msg2disk(pathname, db); ha_msg_del(db); return HA_OK; } struct ha_msg* cim_dbkeys(const char *pathname) { struct ha_msg * db = cim_disk2msg(pathname); struct ha_msg * list; int i; if ( db == NULL ) { cl_log(LOG_ERR, "cim_dbkeys: get db failed."); return NULL; } if ( (list = ha_msg_new(1)) == NULL ) { ha_msg_del(db); cl_log(LOG_ERR, "cim_dbkeys: alloc list failed."); return NULL; } for (i = 0; i < db->nfields; i++) { cim_list_add(list, db->names[i]); } ha_msg_del(db); return list; } static char* pathname_encode(const char *pathname) { char *new_pathname = NULL; char ch, *p; if ((new_pathname = cim_malloc(strlen(pathname)+1)) == NULL ) { cl_log(LOG_ERR, "pathname_enocde: alloc pathname failed."); return NULL; } p = new_pathname; while( (ch = *(pathname++)) ) { if (ch == '\\' || ch == '/') { *(p++) = '_'; } else { *(p++) = ch; } } *p = EOS; return new_pathname; } /**************************************************** * msg ****************************************************/ int cim_msg_children_count(struct ha_msg *parent) { int i, count = 0; for (i = 0; i < parent->nfields; i++) { if ( parent->types[i] == FT_STRUCT ) { count++; } } return count; } const char * cim_msg_child_name(struct ha_msg *parent, int index) { int i, current = 0; for (i = 0; i < parent->nfields; i++) { if ( parent->types[i] == FT_STRUCT ) { if ( index == current) { return parent->names[i]; } current++; } } return NULL; } struct ha_msg * cim_msg_child_index(struct ha_msg *parent, int index) { int i, current = 0; for (i = 0; i < parent->nfields; i++) { if ( parent->types[i] == FT_STRUCT ) { if ( index == current) { return parent->values[i]; } current++; } } return NULL; } int cim_list_find(struct ha_msg *list, const char *value) { int len = cim_list_length(list); int i = 0; for (i = 0; i * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef _UTILS_H #define _UTILS_H #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include #include #include #include #define MAXLEN 1024 /* memory routines */ #define cim_malloc malloc #define cim_free free #define cim_strdup strdup #define cim_realloc realloc typedef void (* cim_free_t)(void *); /* for debuging */ #define DEBUG_ENTER() cl_log(LOG_INFO, "%s: --- ENTER ---", __FUNCTION__) #define DEBUG_LEAVE() cl_log(LOG_INFO, "%s: --- LEAVE ---", __FUNCTION__) #ifndef ASSERT #ifdef HAVE_STRINGIZE # define ASSERT(X) {if(!(X)) cim_assert(#X, __LINE__, __FILE__);} #else # define ASSERT(X) {if(!(X)) cim_assert("X", __LINE__, __FILE__);} #endif #endif extern int debug_level; #define cim_debug2(prio, fmt...) \ do { \ if(debug_level > 2){ \ cl_log(prio, ##fmt); \ } \ }while(0) #define PROVIDER_INIT_LOGGER() cim_init_logger(PROVIDER_ID) #define cim_debug_msg(msg, fmt...) \ do { \ cl_log(LOG_INFO, ##fmt); \ cl_log(LOG_INFO, "%s", msg2string(msg));\ }while (0) int cim_init_logger(const char* entity); void cim_assert(const char* assertion, int line, const char* file); int run_shell_cmnd(const char* cmnd,int* ret,char*** out,char***); char** regex_search(const char * reg, const char * str, int * len); void free_2d_array(void *array, int len, cim_free_t free); void free_2d_zarray(void *zarray, cim_free_t free); char* uuid_to_str(const cl_uuid_t * uuid); char** split_string(const char *string, int *len, const char *delim); #define cim_dbget_msg(pathname, key) ({ \ struct ha_msg *msg = NULL; \ char *value = cim_dbget(pathname, key); \ if (value) { \ msg = string2msg(value, strlen(value)); \ cim_free(value); \ } \ msg; \ }) #define cim_dbput_msg(pathname,key,msg) \ cim_dbput(pathname, key, msg?msg2string(msg):NULL) struct ha_msg* cim_disk2msg(const char *objpathname); int cim_msg2disk(const char *objpathname, struct ha_msg *); int cim_disk_msg_del(const char *objpathname); char* cim_dbget(const char *pathname, const char*key); int cim_dbput(const char *pathname, const char*key, const char*value); int cim_dbdel(const char *pathname, const char*key); struct ha_msg* cim_dbkeys(const char *pathname); int cim_list_find(struct ha_msg *list, const char *value); #define cim_list_length(msg) cl_msg_list_length(msg, CIM_MSG_LIST) #define cim_list_index(msg,index) \ ((char *)cl_msg_list_nth_data(msg, CIM_MSG_LIST, index)) #define cim_list_add(msg, value) \ cl_msg_list_add_string(msg, CIM_MSG_LIST, value) #define cim_msg_add_child(parent,id, child) \ ha_msg_addstruct(parent, id, child) #define cim_msg_find_child(parent, id) cl_get_struct(parent,id) #define cim_msg_remove_child(parent, id) cl_msg_remove(parent,id) int cim_msg_children_count(struct ha_msg *parent); const char * cim_msg_child_name(struct ha_msg * parent, int index); struct ha_msg * cim_msg_child_index(struct ha_msg *parent, int index); #endif pacemaker-mgmt-pacemaker-mgmt-2.1.2/configure.in000066400000000000000000002124651211477743100216300ustar00rootroot00000000000000dnl dnl autoconf for heartbeat dnl Started by David Lee December 2000 dnl automake stuff dnl added by Michael Moerz February 2001 dnl dnl License: GNU General Public License (GPL) dnl =============================================== dnl Bootstrap dnl =============================================== dnl Initialiase, with sanity check of a unique file in the hierarchy AC_INIT(README.in) AC_PREREQ(2.53) PKG_FEATURES="" AC_CONFIG_AUX_DIR(.) AC_CANONICAL_HOST dnl Where #defines go (e.g. `AC_CHECK_HEADERS' below) dnl dnl Internal header: include/config.h dnl - Contains ALL defines dnl - include/config.h.in is generated automatically by autoheader dnl - NOT to be included in any header files except lha_internal.h dnl (which is also not to be included in any other header files) dnl dnl External header: include/mgmt_config.h dnl - Contains a subset of defines checked here dnl - Manually edit include/mgmt_config.h.in to have configure include dnl new defines dnl - Should not include HAVE_* defines dnl - Safe to include anywhere AM_CONFIG_HEADER(include/config.h include/mgmt_config.h) ALL_LINGUAS="en fr" AC_ARG_WITH(hapkgversion, [ --with-hapkgversion=name Override package version (if you're a packager needing to pretend) ], [ HAPKGVERSION="$withval" ], [ HAPKGVERSION="" ], ) if test -z "$HAPKGVERSION" ; then HAPKGVERSION="2.0" fi HB_PKG=heartbeat PKG_NAME=pacemaker-mgmt AM_INIT_AUTOMAKE($PKG_NAME, $HAPKGVERSION) dnl i18n GETTEXT_PACKAGE="haclient" AC_SUBST(GETTEXT_PACKAGE) AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [Gettext package]) #IT_PROG_INTLTOOL([0.40.5], [no-xml]) AC_PROG_INTLTOOL(0.35.2) AM_PO_SUBDIRS # Set DATADIRNAME correctly if it is not set yet # (copied from glib-gettext.m4) if test -z "$DATADIRNAME"; then AC_LINK_IFELSE( [AC_LANG_PROGRAM([[]], [[extern int _nl_msg_cat_cntr; return _nl_msg_cat_cntr]])], [DATADIRNAME=share], [case $host in *-*-solaris*) dnl On Solaris, if bind_textdomain_codeset is in libc, dnl GNU format message catalog is always supported, dnl since both are added to the libc all together. dnl Hence, we'd like to go with DATADIRNAME=share dnl in this case. AC_CHECK_FUNC(bind_textdomain_codeset, [DATADIRNAME=share], [DATADIRNAME=lib]) ;; *) [DATADIRNAME=lib] ;; esac]) fi AC_SUBST(DATADIRNAME) dnl =============================================== dnl Helpers dnl =============================================== MISSINGTHINGS="" MISSINGOPTIONALS="" FatalMissingThing() { if test X"$MISSINGTHINGS" = X; then MISSINGTHINGS="$MISSINGTHINGS $1" else MISSINGTHINGS="$MISSINGTHINGS, $1" fi shift AC_MSG_RESULT(configure: ERROR: $1 ====================) shift for j in "$@" do if test "X$j" != X-; then AC_MSG_RESULT(configure: $j ==) fi done } WarnMissingThing() { if test X"$MISSINGOPTIONALS" = X; then MISSINGOPTIONALS="$MISSINGOPTIONALS $1" else MISSINGOPTIONALS="$MISSINGOPTIONALS, $1" fi shift AC_MSG_RESULT(configure: WARNING: $1 ====================) shift for j in "$@" do if test "X$j" != X-; then AC_MSG_RESULT(configure: $j ==) fi done } CheckMissingThings() { if test "X$MISSINGOPTIONALS" != "X" then AC_MSG_WARN(The following recommended components noted earlier are missing: $MISSINGOPTIONALS We will continue but you may have lost some non-critical functionality.) fi if test "X$MISSINGTHINGS" != "X" then AC_MSG_ERROR(The following required components noted earlier are missing: $MISSINGTHINGS Please supply them and try again.) fi } extract_header_define() { AC_MSG_CHECKING(for $2 in $1) Cfile=/tmp/extract_define.$2.${$} printf "#include \n" > ${Cfile}.c printf "#include <%s>\n" $1 >> ${Cfile}.c printf "int main(int argc, char **argv) { printf(\"%%s\", %s); return 0; }\n" $2 >> ${Cfile}.c $CC $CFLAGS ${Cfile}.c -o ${Cfile} value=`${Cfile}` AC_MSG_RESULT($value) printf $value rm -f ${Cfile}.c ${Cfile} } dnl =============================================== dnl Configure Options dnl =============================================== dnl Some systems, like Solaris require a custom package name AC_ARG_WITH(pkgname, [ --with-pkgname=name name for pkg (typically for Solaris) ], [ PKGNAME="$withval" ], [ PKGNAME="LXHAhb" ], ) AC_SUBST(PKGNAME) AC_ARG_ENABLE([all], [ --enable-all Activate ALL features [default=no]]) AC_ARG_ENABLE([ansi], [ --enable-ansi force GCC to compile to ANSI/ANSI standard for older compilers. [default=yes]]) AC_ARG_ENABLE([fatal-warnings], [ --enable-fatal-warnings very pedantic and fatal warnings for gcc [default=yes]], [], [enable_fatal_warnings=unknown]) AC_ARG_ENABLE([no-long-long], [ --enable-no-long-long removes no long long warning for gcc [default=yes]], [], [enable_no_long_long=yes]) AC_ARG_ENABLE([traditional-warnings], [ --enable-traditional-warnings enable traditional warnings gcc (-Wtraditional) [default=no]]) AC_ARG_ENABLE([quiet], [ --enable-quiet Supress make output unless there is an error [default=no]]) AC_ARG_ENABLE([thread-safe], [ --enable-thread-safe Enable some client libraries to be thread safe. [default=no]]) AC_ARG_ENABLE([mgmt-client], [ --enable-mgmt-client Enable building of mgmt-client related functionality. [default=yes]], [], [enable_mgmt_client=yes]) AC_ARG_ENABLE([snmp], [ --enable-snmp Enable building of SNMP related functionality. [default=yes]]) AC_ARG_ENABLE([snmp-subagent], [ --enable-snmp-subagent Enable building of our SNMP subagent (lots of dependencies). [default=try]]) AC_ARG_ENABLE([bundled-ltdl], [ --enable-bundled-ltdl Configure, build and install the standalone ltdl library bundled with ${PKG_NAME} [default=no]]) LTDL_LIBS="" AC_ARG_ENABLE([cim-provider], [ --enable-cim-provider Enable CIM providers. [default=no]]) AC_ARG_WITH([cimom], [ --with-cimom Specify CIM server], [], []) AC_ARG_WITH([cmpiheader], [ --with-cmpi-headers Specify CMPI header files], [], []) AC_ARG_WITH([cmpiprovider], [ --with-provider-dir Specify CMPI providers directory], [], []) AC_ARG_ENABLE([tsa-plugin], [ --enable-tsa-plugin Enable TSA plugin. [default=no]], [], [enable_tsa_plugin=no]) AC_ARG_WITH(ais-support, [ --with-ais-support Support the OpenAIS-based stack ], [ SUPPORT_AIS=$withval ], [ SUPPORT_AIS=try ], ) AC_ARG_WITH(heartbeat-support, [ --with-heartbeat-support Support the Heartbeat-based stack ], [ SUPPORT_HEARTBEAT=$withval ], [ SUPPORT_HEARTBEAT=try ], ) AISPREFIX="" AC_ARG_WITH(ais-prefix, [ --with-ais-prefix=DIR Prefix used when OpenAIS was installed [$prefix]], [ AISPREFIX=$withval ], [ AISPREFIX=$prefix ]) LCRSODIR="" AC_ARG_WITH(lcrso-dir, [ --with-lcrso-dir=DIR OpenAIS lcrso files. ], [ LCRSODIR="$withval" ]) AC_ARG_WITH([JAVA_HOME], [ --with-java-home JAVA_HOME dir], [], []) AC_ARG_WITH([TSA_DIR], [ --with-tsa-dir TSA diretory, default = /opt/IBM/tsamp/], [], []) INITDIR="" AC_ARG_WITH(initdir, [ --with-initdir=DIR directory for init (rc) scripts [${INITDIR}]], [ INITDIR="$withval" ]) AC_ARG_WITH(mibsdir, [ --with-mibsdir=DIR directory for mib files. ], [ MIBS_DIR="$withval" ]) dnl ************ OCF (Open Cluster Framework) ********************** dnl Should be consistent with the OCF standard fixed pathname /usr/lib/ocf dnl Changing it from this value violates the OCF standard. dnl This is why it is not affected by the PREFIX setting. dnl We do not recommend changing it. dnl OCF_ROOT_DIR="/usr/lib/ocf" AC_ARG_WITH(ocf-root, [ --with-ocf-root=DIR directory for OCF scripts [${OCF_ROOT_DIR}]], [ if test x"$withval" = xprefix; then OCF_ROOT_DIR=${prefix}; else OCF_ROOT_DIR="$withval"; fi ]) dnl TODO: Allow libdir and libexecdir to be overwitten? dnl libdir=`dirname $libdir`/$LibDirSuffix dnl libexecdir=`dirname $libexecdir`/$LibDirSuffix dnl ********************************************************************** dnl TODO: Extract these values from the installed heartbeat program AC_ARG_WITH( group-name, [ --with-group-name=GROUP_NAME GROUP_NAME to run our programs as. [default=haclient] ], [ HA_APIGROUP="$withval" ], [ HA_APIGROUP="haclient" ], ) AC_SUBST(HA_APIGROUP) AC_ARG_WITH( ccmuser-name, [ --with-ccmuser-name=HA_CCMUSER_NAME HA_CCMUSER_NAME to run privileged non-root things as. [default=hacluster] ], [ HA_CCMUSER="$withval" ], [ HA_CCMUSER="hacluster" ], ) AC_SUBST(HA_CCMUSER) dnl =============================================== dnl General Processing dnl =============================================== AC_SUBST(HB_PKG) AC_SUBST(PKG_NAME) CC_IN_CONFIGURE=yes export CC_IN_CONFIGURE INIT_EXT="" echo Our Host OS: $host_os/$host AC_MSG_NOTICE(Sanitizing prefix: ${prefix}) case $prefix in NONE) prefix=/usr;; esac AC_MSG_NOTICE(Sanitizing exec_prefix: ${exec_prefix}) case $exec_prefix in dnl For consistency with Heartbeat, map NONE->$prefix NONE) exec_prefix=$prefix;; prefix) exec_prefix=$prefix;; esac AC_MSG_NOTICE(Sanitizing ais_prefix: ${AISPREFIX}) case $AISPREFIX in dnl For consistency with Heartbeat, map NONE->$prefix NONE) AISPREFIX=$prefix;; prefix) AISPREFIX=$prefix;; esac AC_MSG_NOTICE(Sanitizing INITDIR: ${INITDIR}) case $INITDIR in prefix) INITDIR=$prefix;; "") AC_MSG_CHECKING(which init (rc) directory to use) for initdir in /etc/init.d /etc/rc.d/init.d /sbin/init.d \ /usr/local/etc/rc.d /etc/rc.d do if test -d $initdir then INITDIR=$initdir break fi done AC_MSG_RESULT($INITDIR);; esac AC_MSG_NOTICE(Sanitizing libdir: ${libdir}) case $libdir in dnl For consistency with Heartbeat, map NONE->$prefix prefix|NONE|*exec_prefix*) AC_MSG_CHECKING(which lib directory to use) for aDir in lib64 lib do trydir="${exec_prefix}/${aDir}" if test -d ${trydir} then libdir=${trydir} break fi done AC_MSG_RESULT($libdir); ;; esac dnl Expand autoconf variables so that we dont end up with '${prefix}' dnl in #defines and python scripts dnl NOTE: Autoconf deliberately leaves them unexpanded to allow dnl make exec_prefix=/foo install dnl No longer being able to do this seems like no great loss to me... eval prefix="`eval echo ${prefix}`" eval exec_prefix="`eval echo ${exec_prefix}`" eval bindir="`eval echo ${bindir}`" eval sbindir="`eval echo ${sbindir}`" eval libexecdir="`eval echo ${libexecdir}`" eval datadir="`eval echo ${datadir}`" eval sysconfdir="`eval echo ${sysconfdir}`" eval sharedstatedir="`eval echo ${sharedstatedir}`" eval localstatedir="`eval echo ${localstatedir}`" eval libdir="`eval echo ${libdir}`" eval includedir="`eval echo ${includedir}`" eval oldincludedir="`eval echo ${oldincludedir}`" eval infodir="`eval echo ${infodir}`" eval mandir="`eval echo ${mandir}`" dnl Home-grown variables eval INITDIR="${INITDIR}" eval docdir="`eval echo ${docdir}`" for j in prefix exec_prefix bindir sbindir libexecdir datadir sysconfdir \ sharedstatedir localstatedir libdir includedir oldincludedir infodir \ mandir INITDIR docdir do dirname=`eval echo '${'${j}'}'` if test ! -d "$dirname" then AC_MSG_WARN([$j directory ($dirname) does not exist!]) fi done dnl This OS-based decision-making is poor autotools practice; dnl feature-based mechanisms are strongly preferred. dnl dnl So keep this section to a bare minimum; regard as a "necessary evil". pf_argv_set="" case "$host_os" in *bsd*) LIBS="-L/usr/local/lib" CPPFLAGS="$CPPFLAGS -I/usr/local/include" INIT_EXT=".sh" ;; *solaris*) pf_argv_set="PF_ARGV_NONE" ;; *linux*) AC_DEFINE_UNQUOTED(ON_LINUX, 1, Compiling for Linux platform) ;; darwin*) AC_DEFINE_UNQUOTED(ON_DARWIN, 1, Compiling for Darwin platform) LIBS="$LIBS -L${prefix}/lib" CFLAGS="$CFLAGS -I${prefix}/include" ;; esac CFLAGS="$CFLAGS -I${prefix}/include/heartbeat -I${prefix}/include/pacemaker" AC_SUBST(INIT_EXT) AC_DEFINE_UNQUOTED(HA_LOG_FACILITY, LOG_DAEMON, Default logging facility) LDD=ldd dnl Which C compiler? dnl Defaults to GNU C compiler if available. dnl Always tries to set the compiler to ANSI C via options (AM) dnl Can force other with environment variable "CC". AC_PROG_CC AC_PROG_CC_STDC case "$host_cpu" in ppc64|powerpc64) case $CFLAGS in *powerpc64*) ;; *) if test "$GCC" = yes; then CFLAGS="$CFLAGS -m64" fi ;; esac esac # # Other interesting variables: ${host_vendor} and ${host_os} # sample values: suse linux # dnl ************************************************************************* PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin" export PATH dnl checks for programs dnl AC_PROG_YACC AC_DECL_YYTEXT AM_PROG_LEX AM_PATH_PYTHON AC_LIBTOOL_DLOPEN dnl Enable dlopen support... AC_LIBLTDL_CONVENIENCE dnl make libltdl a convenience lib AC_PROG_LIBTOOL dnl =============================================== dnl Program Paths - Most of these need to go away dnl =============================================== dnl Replacing AC_PROG_LIBTOOL with AC_CHECK_PROG because LIBTOOL dnl was NOT being expanded all the time thus causing things to fail. AC_CHECK_PROGS(LIBTOOL, glibtool libtool libtool15 libtool13) AC_MSG_CHECKING(for glibtool or libtool*) if test x"${LIBTOOL}" = x""; then FatalMissingThing "libtool" "You need libtool to build ${PKG_NAME}." \ "You can get the source from ftp://www.gnu.org/pub/gnu/" \ "or you can locate it via http://www.gnu.org/software/libtool" else AC_MSG_RESULT($LIBTOOL has been found.) fi AC_CHECK_PROGS(MAKE, gmake make) AC_MSG_CHECKING(for gmake or make) if test x"${MAKE}" = x""; then FatalMissingThing "gmake" "You need gmake to build ${PKG_NAME}." \ "You can get the source from ftp://www.gnu.org/pub/gnu/" \ "or you can locate it via http://www.gnu.org/software/make/" else AC_MSG_RESULT($MAKE has been found.) fi AC_SYS_LARGEFILE AC_PATH_PROGS(HTML2TXT, lynx w3m) case $HTML2TXT in */*) ;; *) HTML2TXT="";; esac AC_PATH_PROGS(POD2MAN, pod2man, pod2man) AC_PATH_PROGS(ROUTE, route) AC_PATH_PROGS(RPM, rpmbuild) if test x"${RPM}" = x""; then AC_PATH_PROGS(RPM, rpm) fi AC_DEFINE_UNQUOTED(ROUTE, "$ROUTE", path to route command) AC_PATH_PROGS(NETSTAT, netstat, /sbin/netstat) AC_DEFINE_UNQUOTED(NETSTAT, "$NETSTAT", path to the netstat command) AC_PATH_PROGS(PING, ping, /bin/ping) AC_PATH_PROGS(IFCONFIG, ifconfig, /sbin/ifconfig) AC_PATH_PROGS(SSH, ssh, /usr/bin/ssh) AC_PATH_PROGS(SCP, scp, /usr/bin/scp) AC_PATH_PROGS(PYTHON, python) dnl - Determine which mail program exists. Mailx is Solaris AC_PATH_PROGS(MAILCMD, mail, mailx) AC_SUBST(MAILCMD) AC_DEFINE_UNQUOTED(IFCONFIG, "$IFCONFIG", path to the ifconfig command) AC_PATH_PROGS(GETENT, getent) AC_PATH_PROGS(IP2UTIL, ip, /sbin/ip) AC_PATH_PROGS(XML2CONFIG, xml2-config) AC_PATH_PROGS(REBOOT, reboot, /sbin/reboot) AC_PATH_PROGS(POWEROFF_CMD, poweroff, /sbin/poweroff) AC_SUBST(REBOOT) AC_SUBST(POWEROFF_CMD) AC_DEFINE_UNQUOTED(REBOOT, "$REBOOT", path to the reboot command) AC_DEFINE_UNQUOTED(POWEROFF_CMD, "$POWEROFF_CMD", path to the poweroff command) dnl "whoami", if it exists, may be hidden away on some System-V (e.g. Solaris) AC_PATH_PROGS(WHOAMI, whoami, , ${PATH}:/usr/ucb) AC_PATH_PROGS(SWIG, swig) AC_SUBST(SWIG) AC_PATH_PROGS(EGREP, egrep) AC_SUBST(EGREP) AC_PATH_PROGS(MSGFMT, msgfmt, [msgfmt not found],) AC_SUBST(MSGFMT) AC_PATH_PROGS(GZIP_PROG, gzip) AC_PATH_PROGS(TAR, tar) AC_PATH_PROGS(MD5, md5) AC_SUBST(GZIP_PROG) AC_SUBST(TAR) AC_SUBST(MD5) dnl The "test" program can be different from the "sh" builtin. AC_PATH_PROGS(TEST, test) AC_PATH_PROGS(PKGCONFIG, pkg-config) dnl ************************************************************************ dnl Check whether non-root user can chown. dnl ************************************************************************ AC_PATH_PROGS(MKTEMP, mktemp) if test -n "$WHOAMI"; then IAM=`$WHOAMI` fi AC_MSG_CHECKING(if chown works for non-root) dnl Prefer "mktemp" command. But some OSes lack it; they can "touch". if test -n "$MKTEMP"; then F=`$MKTEMP "./.chown-testXXXXX"` else F="./.chown-test.$$" touch $F fi if case "$IAM" in root) chown nobody $F; su nobody -c "chown root $F";; *) chown root $F esac >/dev/null 2>&1 then nonroot_chown=yes AC_MSG_RESULT(yes) else nonroot_chown=no AC_MSG_RESULT(no) fi rm -f $F AM_CONDITIONAL(NONROOT_CHOWN, test "$nonroot_chown" = yes ) dnl =============================================== dnl Libraries dnl =============================================== dnl ************************************************************************ dnl checks for libraries dnl Needed for libnet test. dnl ************************************************************************ AC_CHECK_LIB(nsl, t_open) dnl -lnsl AC_CHECK_LIB(socket, socket) dnl -lsocket AC_CHECK_LIB(posix4, sched_getscheduler) dnl -lposix4 AC_CHECK_LIB(c, dlopen) dnl if dlopen is in libc... AC_CHECK_LIB(dl, dlopen) dnl -ldl (for Linux) AC_CHECK_LIB(rt, sched_getscheduler) dnl -lrt (for Tru64) AC_CHECK_LIB(gnugetopt, getopt_long) dnl -lgnugetopt ( if available ) AC_CHECK_LIB(pam, pam_start) dnl -lpam (if available) EXTRALIBMSG="-" if test "X${PKGCONFIG}" = "X"; then AC_MSG_RESULT(not found) FatalMissingThing "pkgconfig" "Package pkgconfig is required" \ "See http://pkgconfig.sourceforge.net/" EXTRALIBMSG="(this message might be bogus because pkgconfig is missing)" fi if test "x${enable_thread_safe}" = "xyes"; then GPKGNAME="gthread-2.0" else GPKGNAME="glib-2.0" fi if test "X${PKGCONFIG}" != "X" && $PKGCONFIG --exists $GPKGNAME; then GLIBCONFIG="$PKGCONFIG $GPKGNAME" else set -x echo PKG_CONFIG_PATH=$PKG_CONFIG_PATH $PKGCONFIG --exists $GPKGNAME; echo $? $PKGCONFIG --cflags $GPKGNAME; echo $? $PKGCONFIG $GPKGNAME; echo $? set +x FatalMissingThing "glib2-devel" \ "Package glib2-devel is missing." \ "You can get the source from ftp://ftp.gtk.org/pub/gtk/" \ "or you can locate it via http://www.gtk.org/download/" "$EXTRALIBMSG" fi AC_MSG_RESULT(using $GLIBCONFIG) AC_MSG_CHECKING(where is python installed) if test "x${PYTHON}" = x; then PYTHON="/usr/bin/env python"; fi AC_MSG_RESULT(using $PYTHON); AC_MSG_CHECKING(if netstat supports -f inet flag) $NETSTAT -rn -f inet > /dev/null 2>&1 if test x"$?" = x"0"; then AC_DEFINE(NETSTATPARM, "-rn -f inet ", parameters to netstat to retrieve route information) AC_MSG_RESULT(yes) else AC_DEFINE(NETSTATPARM, "-rn ", parameters to netstat to retrieve route information) AC_MSG_RESULT(no) fi if test X${PING} = X then FatalMissingThing "ping" "ping command is mandantory" fi dnl Determine if we use -w1 or -t1 for ping (in PYTHON Scripts) AC_MSG_CHECKING(ping option for timeout - w or t) for PING_TIMEOUT_OPT in "-w1" "-t1" do $PING -nq -c1 $PING_TIMEOUT_OPT localhost > /dev/null 2>&1 if test "$?" = 0 then AC_DEFINE_UNQUOTED(PING_TIMEOUT_OPT, "$PING_TIMEOUT_OPT", option for ping timeout) AC_MSG_RESULT($PING_TIMEOUT_OPT) break fi done AC_SUBST(PING_TIMEOUT_OPT) dnl Determining a route (particularly for "findif"). dnl There are various mechanisms on different systems. dnl Some mechanisms require root access to evaluate, but configure is often dnl (indeed, some say should be always) running non-root. dnl dnl Therefore much of the determination has to be run-time. dnl So the principle here, at configure time, is to explore what might be dnl available, and offer as much as possible to run-time. dnl AC_DEFINE(ROUTEPARM, "-n get", paramters for route to retrieve route information) AC_DEFINE(PROCROUTE, "/proc/net/route", path were to find route information in proc) AC_MSG_CHECKING(ifconfig option to list interfaces) for IFCONFIG_A_OPT in "" "-A" "-a" do $IFCONFIG $IFCONFIG_A_OPT > /dev/null 2>&1 if test "$?" = 0 then AC_DEFINE_UNQUOTED(IFCONFIG_A_OPT, "$IFCONFIG_A_OPT", option for ifconfig command) AC_MSG_RESULT($IFCONFIG_A_OPT) break fi done AC_SUBST(IFCONFIG_A_OPT) AC_SUBST(WHOAMI) AC_SUBST(HTML2TXT) AC_SUBST(POD2MAN) AC_SUBST(ROUTEPARM) AC_SUBST(PROCROUTE) dnl Locales check - is a real ugly workaround for now til I find dnl something more useful dnl dnl "Eric Z. Ayers" wrote: dnl > dnl > Here are some more data points: dnl > dnl > SUN: /usr/lib/locale/ dnl > HP : /usr/lib/nls/loc/ dnl > OSF: /usr/lib/nls/loc/ dnl > LINUX: /usr/share/locale/ dnl > UNIXWARE: /usr/lib/locale/ dnl > FREEBSD: /usr/share/locale dnl > VMS: just kidding dnl FindADir() { type="$1" whatfor="$2" shift; shift; AC_MSG_CHECKING(for $whatfor directory) for dir do if test -d "$dir" then AC_MSG_RESULT($dir) echo $dir return 0 fi done AC_MSG_RESULT(not found) return 1 } locale_locations="/usr/share/locale /usr/lib/locale /usr/lib/nls/loc" LOCALE=`FindADir error "locale" $locale_locations` if test "X$LOCALE" = X then FatalMissingThing "Locale directory" "Locale directory is mandantory." fi RPMDIR=`FindADir warn "RPM" /usr/src/packages /usr/src/redhat` if test x"${HAVE_LIBRT}" = x""; then LIBRT="" else LIBRT=-lrt fi AC_SUBST(LIBRT) # # Where is dlopen? # if test "$ac_cv_lib_c_dlopen" = yes; then LIBADD_DL="" elif test "$ac_cv_lib_dl_dlopen" = yes; then LIBADD_DL=-ldl else LIBADD_DL=${lt_cv_dlopen_libs} fi dnl dnl Check for location of gettext dnl dnl On at least Solaris 2.x, where it is in libc, specifying lintl causes dnl grief. Ensure minimal result, not the sum of all possibilities. dnl And do libc first. dnl Known examples: dnl c: Linux, Solaris 2.6+ dnl intl: BSD, AIX FunIsInLib() { fun=$1 lib=$2 lib_var1="ac_cv_lib_${lib}_$fun" lib_var2="ac_cv_lib_${lib}___$fun" for v in $lib_var1 $lib_var2 do var=`eval echo '${'${v}'}'` case $var in yes) return 0;; no) return 1;; esac done return 0 } for gt_test_lib in c intl do AC_CHECK_LIB($gt_test_lib, gettext) if FunIsInLib gettext $gt_test_lib; then break fi done # # Where is gettext()? # if FunIsInLib gettext c ; then LIBADD_INTL="" elif FunIsInLib gettext intl ; then LIBADD_INTL=-lintl elif test -f /usr/local/lib/libintl.so -a -s /usr/local/lib/libintl.so; then # This was added for FreeBSD LIBADD_INTL="-lintl" elif test -f /sw/lib/libintl.a -a -s /sw/lib/libintl.la -a -s /sw/lib/libintl.dylib; then # This was added for Darwin + Fink LIBADD_INTL="-lintl" else FatalMissingThing "gettext function" "no library providing gettext found" fi dnl dnl Glib allows its headers/libraries to be installed anywhere. dnl And they provide a command to let you know where they are. dnl This is nice, but having them in standard places is nice too ;-) dnl if test "X$GLIBCONFIG" != X; then AC_MSG_CHECKING(for special glib includes: ) GLIBHEAD=`$GLIBCONFIG --cflags` AC_MSG_RESULT($GLIBHEAD) CPPFLAGS="$CPPFLAGS $GLIBHEAD" AC_SUBST(GLIBHEAD) dnl Note: Not bundling "GLIBLIB" with general "LIBS". dnl 1. Only very few programs require GLIBLIB dnl (This isn't true anymore -- AlanR) dnl 2. Danger of creating run-time dependency on build-time LD_LIBRARY_PATH AC_MSG_CHECKING(for glib library flags) GLIBLIB=`$GLIBCONFIG --libs` AC_MSG_RESULT($GLIBLIB) AC_SUBST(GLIBLIB) fi dnl ************************************************************************ dnl checks for header files dnl dnl check for ANSI *.h files first dnl asm/page.h: Linux, for system PAGE_SIZE AC_HEADER_STDC AC_CHECK_HEADERS(db.h) AC_CHECK_HEADERS(asm/page.h) AC_CHECK_HEADERS(time.h) AC_CHECK_HEADERS(stdarg.h) AC_CHECK_HEADERS(tcpd.h) AC_CHECK_HEADERS(sys/param.h) AC_CHECK_HEADERS(netinet/in.h) AC_CHECK_HEADERS([stdint.h unistd.h]) AC_CHECK_HEADERS(sys/termios.h) AC_CHECK_HEADERS(sys/reboot.h) AC_CHECK_HEADERS(termios.h) dnl ************************************************************************ dnl FreeBSD requires sys/param.h and in.h to compile test netinet headers. dnl ************************************************************************ if test "$ac_cv_header_sys_param_h" -a "$ac_cv_header_netinet_in_h" = no; then AC_CHECK_HEADERS(netinet/in_systm.h) AC_CHECK_HEADERS(netinet/ip.h) AC_CHECK_HEADERS(netinet/ip_var.h) AC_CHECK_HEADERS(netinet/ip_compat.h) AC_CHECK_HEADERS(netinet/ip_fw.h) else AC_CHECK_HEADERS(netinet/in_systm.h,[],[],[#include #include ]) if test "$ac_cv_header_in_systm_h" = no; then AC_CHECK_HEADERS(netinet/ip.h,[],[],[#include #include ]) else AC_CHECK_HEADERS(netinet/ip.h,[],[],[#include #include #include ]) fi AC_CHECK_HEADERS(netinet/ip_var.h,[],[],[#include #include ]) AC_CHECK_HEADERS(netinet/ip_compat.h,[],[],[#include #include ]) AC_CHECK_HEADERS(netinet/ip_fw.h,[],[],[#include #include ]) fi AC_CHECK_HEADERS(sys/sockio.h) AC_CHECK_HEADERS(libintl.h) AC_CHECK_HEADERS(sys/types.h) AC_CHECK_HEADERS(sys/socket.h) AC_CHECK_HEADERS(arpa/inet.h) AC_CHECK_HEADERS(net/ethernet.h) AC_CHECK_HEADERS(malloc.h) AC_CHECK_HEADERS(termio.h) AC_CHECK_HEADERS(getopt.h) AC_CHECK_HEADERS(sys/prctl.h) AC_CHECK_HEADERS(linux/watchdog.h,[],[],[#include ]) dnl Sockets are our preferred and supported comms mechanism. But the dnl implementation needs to be able to convey credentials: some don't. dnl So on a few OSes, credentials-carrying streams might be a better choice. dnl dnl Solaris releases up to and including "9" fall into this category dnl (its sockets don't carry credentials; streams do). dnl dnl At Solaris 10, "getpeerucred()" is available, for both sockets and dnl streams, so it should probably use (preferred) socket mechanism. AC_CHECK_HEADERS(stropts.h) dnl streams available (fallback option) AC_CHECK_HEADERS(ucred.h) dnl e.g. Solaris 10 decl. of "getpeerucred()" AC_CHECK_FUNCS(getpeerucred) dnl ************************************************************************ dnl checks for headers needed by clplumbing On BSD AC_CHECK_HEADERS(sys/syslimits.h) if test "$ac_cv_header_sys_param_h" = no; then AC_CHECK_HEADERS(sys/ucred.h) else AC_CHECK_HEADERS(sys/ucred.h,[],[],[#include ]) fi dnl ************************************************************************ dnl checks for headers needed by clplumbing On Solaris AC_CHECK_HEADERS(sys/cred.h xti.h) dnl ************************************************************************ dnl checks for headers needed by clplumbing On FreeBSD/Solaris AC_CHECK_HEADERS(sys/filio.h) AC_MSG_CHECKING(for special libxml2 includes) if test "x$XML2CONFIG" = "x"; then AC_MSG_RESULT(libxml2 config not found) else XML2HEAD=`$XML2CONFIG --cflags` AC_MSG_RESULT($XML2HEAD) AC_CHECK_LIB(xml2, xmlReadMemory) fi CPPFLAGS="$CPPFLAGS $XML2HEAD" dnl ************************************************************************ dnl * Check for linux/icmpv6.h to make enable the IPv6addr resource agent AC_CHECK_HEADERS(linux/icmpv6.h,[],[],[#include ]) AM_CONDITIONAL(USE_IPV6ADDR, test "$ac_cv_header_linux_icmpv6_h" = yes -a $new_libnet = yes ) AC_CHECK_HEADERS(libxml/xpath.h) dnl dnl Could check for the libraries, but if you have the headers, dnl you're a dolt for not having installed the libs ;-) dnl AM_CONDITIONAL(USE_VACM, test "$ac_cv_header_vacmclient_api_h" = yes) AM_CONDITIONAL(USE_DRAC3, test "$ac_cv_header_curl_curl_h" = yes -a "$ac_cv_header_libxml_xpath_h" = yes) AM_CONDITIONAL(USE_OPENHPI, test "$ac_cv_header_openhpi_SaHpi_h" = yes) dnl dnl On many systems libcrypto is needed when linking against libsnmp. dnl Check to see if it exists, and if so use it. dnl AC_CHECK_LIB(crypto, CRYPTO_free, CRYPTOLIB="-lcrypto",) AC_SUBST(CRYPTOLIB) dnl ************************************************************************ dnl Handy function for checking for typedefs or struct defs dnl ************************************************************************ check_for_type() { type="$1" headers="" shift for arg do headers="${headers}${arg} " done program="if ((${type} *) 0) return 0; if (sizeof(${type})) return 0; return 0;" have="HAVE_`echo "$type" | tr ' ' '_' | dd conv=ucase 2>/dev/null`" varhave="heartbeat_cv_$have" AC_CACHE_CHECK([for type $type ],$varhave,[ AC_TRY_COMPILE([$headers], [$program], eval $varhave=yes, eval $varhave=no , eval $varhave=cross) ]) if test x"`eval echo '${'$varhave'}'`" = xyes; then return 0 fi return 1 } check_for_type_member() { type="$1" member="$2" headers="" shift shift for arg do headers="${headers}${arg} " done program="${type} foo; if ((${type} *) 0) return 0; if (sizeof(${type})) return 0; if (sizeof(foo)) return 0; (void*)foo.${member}; return 0;" have="HAVE_`echo "$type" | tr ' ' '_' | dd conv=ucase 2>/dev/null`" varhave="heartbeat_cv_$have" AC_CACHE_CHECK([for type $type ],$varhave,[ AC_TRY_COMPILE([$headers], [$program], eval $varhave=yes, eval $varhave=no , eval $varhave=cross) ]) if test x"`eval echo '${'$varhave'}'`" = xyes; then return 0 fi return 1 } dnl ************************************************************************ dnl checks for typedefs dnl dnl if not known on this system, #define size_t unsigned AC_TYPE_SIZE_T dnl ************************************************************************ dnl checks for structures dnl # # Look for all the variants of local/UNIX socket credentials # # Include all of these headers that we can find... # headers="" for hdr in "sys/param.h" "sys/socket.h" "sys/ucred.h" do hdrvar=ac_cv_header_`echo $hdr | sed -e 's%\.%_%' -e 's%/%_%'` if test x"`eval echo '${'$hdrvar'}'`" = xyes; then headers="$headers #include <$hdr>" fi done dnl Check syslog.h for 'facilitynames' table dnl AC_CACHE_CHECK([for facilitynames in syslog.h],ac_cv_HAVE_SYSLOG_FACILITYNAMES,[ AC_TRY_COMPILE([ #define SYSLOG_NAMES #include #include ], [ void *fnames; fnames = facilitynames; ], ac_cv_HAVE_SYSLOG_FACILITYNAMES=yes,ac_cv_HAVE_SYSLOG_FACILITYNAMES=no,ac_cv_HAVE_SYSLOG_FACILITYNAMES=cross)]) if test x"$ac_cv_HAVE_SYSLOG_FACILITYNAMES" = x"yes"; then AC_DEFINE(HAVE_SYSLOG_FACILITYNAMES,1,[ ]) fi dnl ************************************************************************ dnl checks for compiler characteristics dnl dnl Warnings for C compilers. Note: generic, portable warnings only. dnl Things likely to be specific to a particular OS or module should be dnl carefully handled afterwards. AC_C_STRINGIZE dnl ********************************************************************** dnl time-related declarations etc. AC_STRUCT_TIMEZONE if check_for_type_member "struct tm" "tm_gmtoff" "#include "; then AC_DEFINE(HAVE_TM_GMTOFF,1,[Do we have structure member tm_gmtoff?]) fi dnl ********************************************************************** dnl Check the size of the integer types dnl So we can have integers of known sizes as needed dnl AC_CHECK_SIZEOF(char) AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(long) AC_CHECK_SIZEOF(long long) if test "X$INITDIR" = X then FatalMissingThing "init directory" "Could not locate init directory" fi AC_SUBST(INITDIR) CC_WARNINGS="" dnl - If requested, enable ALL subsystems. if test "${enable_all}" = "yes" ; then echo "Enabling all optional features." enable_ansi=yes; enable_crm=yes; enable_fatal_warnings=yes; enable_snmp_subagent=try; fi dnl Check before we enable -Wstrict-prototypes as it causes the test to fail AC_CHECK_LIB(ltdl, lt_dlopen, [LTDL_foo=1]) if test "x${enable_bundled_ltdl}" = "xyes"; then if test $ac_cv_lib_ltdl_lt_dlopen = yes; then AC_MSG_NOTICE([Disabling usage of installed ltdl]) fi ac_cv_lib_ltdl_lt_dlopen=no fi LIBLTDL_DIR="" if test $ac_cv_lib_ltdl_lt_dlopen != yes ; then AC_MSG_NOTICE([Installing local ltdl]) LIBLTDL_DIR=libltdl ( cd $srcdir ; $TAR -xvf libltdl.tar ) if test "$?" -ne 0; then AC_MSG_ERROR([$TAR of libltdl.tar in $srcdir failed]) fi AC_CONFIG_SUBDIRS(libltdl) else LIBS="$LIBS -lltdl" AC_MSG_NOTICE([Using installed ltdl]) INCLTDL="" LIBLTDL="" fi dnl libltdl additions AC_SUBST(INCLTDL) AC_SUBST(LIBLTDL) AC_SUBST(LIBLTDL_DIR) dnl ************ curses ********************** dnl A few OSes (e.g. Linux) deliver a default "ncurses" alongside "curses". dnl Many non-Linux deliver "curses"; sites may add "ncurses". dnl dnl However, the source-code recommendation for both is to #include "curses.h" dnl (i.e. "ncurses" still wants the include to be simple, no-'n', "curses.h"). dnl dnl Andrew Beekhof (author of heartbeat code that uses this functionality) dnl wishes "ncurses" to take precedence. So the following ordering has dnl been devised to implement this. dnl dnl Look first for the headers, then set the libraries accordingly. dnl (Normally autoconf suggests looking for libraries first.) dnl AC_CHECK_HEADERS(curses.h) AC_CHECK_HEADERS(curses/curses.h) AC_CHECK_HEADERS(ncurses.h) AC_CHECK_HEADERS(ncurses/ncurses.h) dnl Although n-library is preferred, only look for it if the n-header was found. CURSESLIBS='' if test "$ac_cv_header_ncurses_h" = "yes"; then AC_CHECK_LIB(ncurses, printw, [CURSESLIBS='-lncurses'; AC_DEFINE(HAVE_LIBNCURSES,1, have ncurses library)] ) fi if test "$ac_cv_header_ncurses_ncurses_h" = "yes"; then AC_CHECK_LIB(ncurses, printw, [CURSESLIBS='-lncurses'; AC_DEFINE(HAVE_LIBNCURSES,1, have ncurses library)] ) fi dnl Only look for non-n-library if there was no n-library. if test X"$CURSESLIBS" = X"" -a "$ac_cv_header_curses_h" = "yes"; then AC_CHECK_LIB(curses, printw, [CURSESLIBS='-lcurses'; AC_DEFINE(HAVE_LIBCURSES,1, have curses library)] ) fi dnl Only look for non-n-library if there was no n-library. if test X"$CURSESLIBS" = X"" -a "$ac_cv_header_curses_curses_h" = "yes"; then AC_CHECK_LIB(curses, printw, [CURSESLIBS='-lcurses'; AC_DEFINE(HAVE_LIBCURSES,1, have curses library)] ) fi AC_SUBST(CURSESLIBS) dnl Variables needed for substitution DTD_DIRECTORY="${datadir}/pacemaker" AC_DEFINE_UNQUOTED(DTD_DIRECTORY,"$DTD_DIRECTORY", Location for the Pacemaker Relax-NG Schema) AC_SUBST(DTD_DIRECTORY) AC_CHECK_HEADERS(hb_config.h) AC_CHECK_HEADERS(glue_config.h) GLUE_HEADER=none if test "$ac_cv_header_glue_config_h" = "yes"; then GLUE_HEADER=glue_config.h elif test "$ac_cv_header_hb_config_h" = "yes"; then GLUE_HEADER=hb_config.h else AC_MSG_FAILURE(Core development headers were not found) fi HA_HBCONF_DIR=`extract_header_define $GLUE_HEADER HA_HBCONF_DIR` AC_SUBST(HA_HBCONF_DIR) HB_RA_DIR=`extract_header_define $GLUE_HEADER HB_RA_DIR` AC_SUBST(HB_RA_DIR) LIBDIR="${libdir}" AC_SUBST(LIBDIR) AC_DEFINE_UNQUOTED(LIBDIR,"$LIBDIR", lib directory) #HA_LIBDIR=`extract_header_define $GLUE_HEADER HA_LIBDIR` #AC_SUBST(HA_LIBDIR) HA_LIBHBDIR=`extract_header_define $GLUE_HEADER HA_LIBHBDIR` AC_SUBST(HA_LIBHBDIR) HA_VARRUNDIR=`extract_header_define $GLUE_HEADER HA_VARRUNDIR` AC_DEFINE_UNQUOTED(HA_VARRUNDIR,"$HA_VARRUNDIR", Location for sockets) AC_SUBST(HA_VARRUNDIR) HA_VARLIBHBDIR=`extract_header_define $GLUE_HEADER HA_VARLIBHBDIR` AC_SUBST(HA_VARLIBHBDIR) OCF_ROOT_DIR=`extract_header_define $GLUE_HEADER OCF_ROOT_DIR` AC_DEFINE_UNQUOTED(OCF_ROOT_DIR,"$OCF_ROOT_DIR", OCF root directory - specified by the OCF standard) AC_SUBST(OCF_ROOT_DIR) OCF_RA_DIR=`extract_header_define $GLUE_HEADER OCF_RA_DIR` AC_DEFINE_UNQUOTED(OCF_RA_DIR,"$OCF_RA_DIR", Location for OCF RAs) AC_SUBST(OCF_RA_DIR) HA_APIGROUP=`extract_header_define $GLUE_HEADER HA_APIGROUP` AC_SUBST(HA_APIGROUP) HA_CCMUSER=`extract_header_define $GLUE_HEADER HA_CCMUSER` AC_SUBST(HA_CCMUSER) HA_DATADIR="${datadir}" AC_SUBST(HA_DATADIR) AC_DEFINE_UNQUOTED(HA_DATADIR,"$HA_DATADIR", data (arch-independent) directory) HA_NOARCHDATAHBDIR="${datadir}/heartbeat" AC_DEFINE_UNQUOTED(HA_NOARCHDATAHBDIR,"$HA_NOARCHDATAHBDIR", Heartbeat noarch data directory) AC_SUBST(HA_NOARCHDATAHBDIR) PKG_CHECK_MODULES([pacemaker_lrmd], [pacemaker-lrmd], [AM_CONDITIONAL([HAVE_PACEMAKER_LRMD], [true])], [AM_CONDITIONAL([HAVE_PACEMAKER_LRMD], [false])]) AC_CHECK_HEADERS(crm_config.h) CRM_HEADER=none if test "$ac_cv_header_crm_config_h" = "yes"; then CRM_HEADER=crm_config.h else AC_MSG_FAILURE(Pacemaker development headers were not found) fi CRM_DAEMON_DIR=`$PKGCONFIG pcmk --variable=daemondir` if test x"$CRM_DAEMON_DIR" = x""; then CRM_DAEMON_DIR=`extract_header_define $CRM_HEADER CRM_DAEMON_DIR` fi AC_DEFINE_UNQUOTED(CRM_DAEMON_DIR,"$CRM_DAEMON_DIR", Location for Pacemaker daemons) dnl pacemaker < 1.1.8 AC_CHECK_HEADERS(pacemaker/crm/common/cluster.h) dnl pacemaker >= 1.1.8 AC_CHECK_HEADERS(pacemaker/crm/cluster.h) dnl pacemaker >= 1.1.8 AC_CHECK_TYPE([crm_cluster_t],,,[[#include ]]) if test $ac_cv_type_crm_cluster_t = yes; then AC_DEFINE_UNQUOTED(HAVE_CRM_CLUSTER_T, 1, pacemaker has crm_cluster_t type) fi dnl pacemaker < 1.1.8 AC_CHECK_TYPE([crm_data_t],,,[[#include ]]) if test $ac_cv_type_crm_data_t = yes; then AC_DEFINE_UNQUOTED(HAVE_CRM_DATA_T, 1, pacemaker has crm_data_t type) fi dnl pacemaker >= 1.1.8 AC_CHECK_LIB(crmcommon, pcmk_strerror) if test $ac_cv_lib_crmcommon_pcmk_strerror = yes; then AC_DEFINE_UNQUOTED(HAVE_PCMK_STRERROR, 1, pacemaker has pcmk_strerror) fi dnl pacemaker >= 1.1.8 AC_CHECK_HEADERS(pacemaker/crm/services.h) if test $ac_cv_header_pacemaker_crm_services_h = yes; then AC_CHECK_DECLS(services_lrm_status_str,,,[[#include ]]) fi dnl pacemaker >= 1.1.8 AC_CHECK_DECLS(__xml_next,,,[[#include ]]) dnl pacemaker >= 1.1.8 AC_CHECK_LIB(crmcommon, crm_ipc_new) if test $ac_cv_lib_crmcommon_crm_ipc_new = yes; then AC_DEFINE_UNQUOTED(HAVE_CRM_IPC_NEW, 1, pacemaker has crm_ipc_new) fi AC_CHECK_LIB(cib, update_attr_delegate) if test $ac_cv_lib_cib_update_attr_delegate = yes; then AC_DEFINE_UNQUOTED(HAVE_UPDATE_ATTR_DELEGATE, 1, pacemaker has update_attr_delegate) fi dnl pacemaker < 1.1.8 AC_CHECK_LIB(crmcommon, new_ha_date) if test $ac_cv_lib_crmcommon_new_ha_date = yes; then AC_DEFINE_UNQUOTED(HAVE_NEW_HA_DATE, 1, pacemaker has new_ha_date) fi dnl pacemaker < 1.1.8 AC_CHECK_DECLS(crm_concat,,,[[#include ]]) dnl pacemaker < 1.1.8 AC_CHECK_DECLS(crm_int_helper,,,[[#include ]]) dnl pacemaker < 1.1.8 AC_CHECK_DECLS(generate_series_filename,,,[[#include ]]) dnl pacemaker < 1.1.8 AC_CHECK_DECLS(get_last_sequence,,,[[#include ]]) AC_PATH_PROGS(GIT, git false) AC_MSG_CHECKING(build revision) BUILD_REVISION=$Format:%h$ if test $BUILD_REVISION != ":%h$"; then AC_MSG_RESULT(archive hash: $BUILD_REVISION) elif test -x $GIT -a -d .git; then BUILD_REVISION=`$GIT log --pretty="format:%h" -n 1` AC_MSG_RESULT(git hash: $BUILD_REVISION) else # The current directory name make a reasonable default # Most generated archives will include the hash or tag BASE=`basename $PWD` BUILD_REVISION=`echo $BASE | sed s:.*[[Pp]]acemaker-mgmt::` AC_MSG_RESULT(directory based hash: $BUILD_REVISION) fi AC_DEFINE_UNQUOTED(BUILD_REVISION, "$BUILD_REVISION", Build revision) AC_MSG_RESULT($BUILD_REVISION) AC_SUBST(BUILD_REVISION) dnl ======================================================================== dnl Cluster infrastructure - Heartbeat dnl ======================================================================== dnl On Debian, AC_CHECK_LIBS fail if a library has any unresolved symbols dnl So check for all the depenancies (so they're added to LIBS) before checking for -lplumb AC_CHECK_LIB(pils, PILLoadPlugin) AC_CHECK_LIB(plumb, G_main_add_IPC_Channel) if test x"$ac_cv_lib_plumb_G_main_add_IPC_Channel" != x"yes"; then AC_MSG_FAILURE(Core Heartbeat utility libraries not found: $ac_cv_lib_plumb_G_main_add_IPC_Channel) fi dnl Compatability checks AC_CHECK_FUNCS(msgfromIPC_timeout) AC_CHECK_MEMBERS([struct lrm_ops.fail_rsc],,,[[#include ]]) dnl ======================================================================== dnl Cluster stack - Heartbeat dnl ======================================================================== case $SUPPORT_HEARTBEAT in 1|yes|true) AC_CHECK_LIB(hbclient, ll_cluster_new, [SUPPORT_HEARTBEAT=1], [AC_MSG_FAILURE(Unable to support Heartbeat: client libraries not found)]);; try) AC_CHECK_LIB(hbclient, ll_cluster_new, [SUPPORT_HEARTBEAT=1], [SUPPORT_HEARTBEAT=0]);; *) SUPPORT_HEARTBEAT=0;; esac AM_CONDITIONAL(BUILD_HEARTBEAT_SUPPORT, test $SUPPORT_HEARTBEAT = 1) AC_DEFINE_UNQUOTED(SUPPORT_HEARTBEAT, $SUPPORT_HEARTBEAT, Support the Heartbeat messaging and membership layer) dnl ======================================================================== dnl Cluster stack - OpenAIS dnl ======================================================================== AISLIB="" dnl Normalize the values case $SUPPORT_AIS in 1|yes|true) missingisfatal=1;; try) missingisfatal=0;; *) SUPPORT_AIS=no;; esac AC_MSG_CHECKING(for native AIS) AISMSGLIB="" AIS_VERSION="none" COROSYNC_PKG="$PKGCONFIG libcoroipcc" if test $SUPPORT_AIS = no; then AC_MSG_RESULT(no... not requested.) else AC_MSG_RESULT($SUPPORT_AIS, with '$AISPREFIX') AC_CHECK_HEADERS(openais/saAis.h) AC_CHECK_HEADERS(corosync/coroipcc.h) $COROSYNC_PKG --exists if test $? = 0; then AIS_VERSION="corosync" elif test "$ac_cv_header_openais_saAis_h" = "yes"; then AIS_VERSION="whitetank" else aisreason="Whitetank headers not found" fi fi if test $AIS_VERSION != "none"; then AC_MSG_CHECKING(for OpenAIS branch) AC_MSG_RESULT($AIS_VERSION) fi if test $AIS_VERSION = "corosync"; then if test "$ac_cv_header_corosync_coroipcc_h" != "yes"; then AIS_VERSION="none" aisreason="Corosync headers not found" fi saveLIBS="$LIBS" LIBS="$LIBS `$COROSYNC_PKG --libs-only-L`" AC_CHECK_LIB(coroipcc, coroipcc_msg_send_reply_receive, []) LIBS="$saveLIBS" if test $ac_cv_lib_coroipcc_coroipcc_msg_send_reply_receive != yes; then AC_MSG_RESULT(Cannot locate AIS messaging library) aisreason="requred Corosync libraries not found" AIS_VERSION="none" fi fi dnl continue? if test $AIS_VERSION = "whitetank"; then dnl Find it in lib, lib64, or wherever it wants to live... AC_MSG_CHECKING(location of OpenAIS libraries) dnl CoroSync location alib=`ls ${AISPREFIX}/*/libcpg.so | head -n 1` if test -z "$alib"; then dnl Whitetank location alib=`ls ${AISPREFIX}/*/*/libcpg.so | head -n 1` fi AISLIB=`dirname $alib` AC_MSG_RESULT($AISLIB) if test "x$AISLIB" = "x"; then AC_MSG_WARN(Use --with-ais-prefix to specify the prefix OpenAIS was installed with) aisreason="library directory not found" AIS_VERSION="none" elif test ! -d "$AISLIB"; then AC_MSG_WARN(Use --with-ais-prefix to specify the prefix OpenAIS was installed with) aisreason="specified library directory does not exist" AIS_VERSION="none" fi fi dnl continue? if test $AIS_VERSION = "whitetank"; then AC_MSG_CHECKING(location of OpenAIS plugins) if test -z "$LCRSODIR"; then LCRSODIR="$libexecdir/lcrso" alib=`ls ${AISPREFIX}/*/lcrso/objdb.lcrso | head -n 1` LCRSODIR=`dirname $alib` fi AC_MSG_RESULT($LCRSODIR) if test "x$LCRSODIR" = "x"; then AC_MSG_RESULT(Invalid. Please specify the correct location with --with-lcrso-dir) aisreason="plugin directory not found" AIS_VERSION="none" elif test ! -d "$LCRSODIR"; then AC_MSG_RESULT(Invalid. Please specify the correct location with --with-lcrso-dir) aisreason="specified plugin directory does not exist" AIS_VERSION="none" fi fi dnl continue? if test $AIS_VERSION = "whitetank"; then dnl Don't add the messaging library to LIBS since most daemons don't need/use it saveLIBS="$LIBS" LIBS="$LIBS -L${AISLIB} -R${AISLIB}" AC_CHECK_LIB(SaMsg, saSendReceiveReply, []) AC_CHECK_LIB(SaMsg, openais_msg_send_reply_receive, []) if test $ac_cv_lib_SaMsg_openais_msg_send_reply_receive = yes; then : OpenAIS elif test $ac_cv_lib_SaMsg_saSendReceiveReply = yes; then : OpenAIS AC_DEFINE_UNQUOTED(TRADITIONAL_AIS_IPC, 1, "Use the 'old' AIS IPC interface") else AC_MSG_RESULT(Cannot locate AIS messaging library) aisreason="requred libraries not found" AIS_VERSION="none" fi LIBS="$saveLIBS" fi SUPPORT_AIS=1 case $AIS_VERSION in corosync) AC_DEFINE_UNQUOTED(AIS_COROSYNC, 1, "AIS target is the corosync series") LCRSODIR=`$PKGCONFIG corosync --variable=lcrsodir` CFLAGS="$CFLAGS `$COROSYNC_PKG --cflags`" AISMSGLIB=`$COROSYNC_PKG --libs` ;; whitetank) AC_DEFINE_UNQUOTED(AIS_WHITETANK, 1, "AIS target is the whitetank series") CFLAGS="$CFLAGS -I$AISPREFIX/include/openais" AISMSGLIB="-L${AISLIB} -R${AISLIB} -lSaMsg" ;; none) SUPPORT_AIS=0 if test "x$aisreason" != x; then if test $missingisfatal = 0; then AC_MSG_WARN(Unable to support OpenAIS: $aisreason) else AC_MSG_FAILURE(Unable to support OpenAIS: $aisreason) fi fi ;; *) AC_MSG_FAILURE(Unknown OpenAIS branch: $AIS_VERSION);; esac AC_DEFINE_UNQUOTED(SUPPORT_AIS, $SUPPORT_AIS, Support the OpenAIS messaging and membership layer) AM_CONDITIONAL(BUILD_AIS_SUPPORT, test $SUPPORT_AIS = 1) dnl dnl Cluster stack - Sanity dnl STACKS="" CLUSTERLIBS="" if test $SUPPORT_HEARTBEAT = 1; then STACKS="$STACKS heartbeat" CLUSTERLIBS="$CLUSTERLIBS -lhbclient -lccmclient -lclm" fi if test $SUPPORT_AIS = 1; then STACKS="$STACKS $AIS_VERSION" #CLUSTERLIBS="$CLUSTERLIBS ${AISMSGLIB}" else AISPREFIX="" LCRSODIR="$libdir" fi PKG_FEATURES="$PKG_FEATURES$STACKS" AC_MSG_CHECKING(for supported stacks) if test x"$STACKS" = x; then AC_MSG_FAILURE(You must choose at least one cluster stack to support) fi AC_MSG_RESULT($STACKS) AC_SUBST(CLUSTERLIBS) AC_SUBST(LCRSODIR) dnl dnl mgmt checks dnl AM_CONDITIONAL(MGMT_CLIENT_BUILD, test "x${enable_mgmt_client}" != "xno") dnl dnl SNMP checks dnl SNMPLIB="" SNMPAGENTLIB="" SNMPCONFIG="" ENABLE_SNMP="yes" if test "x${enable_snmp}" = "xno"; then ENABLE_SNMP="no" enable_snmp_subagent="no" fi AC_CHECK_HEADERS(ucd-snmp/snmp.h,[],[],[#include #include ]) AC_CHECK_HEADERS(net-snmp/net-snmp-config.h) if test "x${ENABLE_SNMP}" = "xno"; then # nothing : elif test "x${ac_cv_header_net_snmp_net_snmp_config_h}" = "xyes"; then AC_PATH_PROGS(SNMPCONFIG, net-snmp-config) if test "X${SNMPCONFIG}" = "X"; then AC_MSG_RESULT(You need the net_snmp development package to continue.) ENABLE_SNMP="no" else AC_MSG_CHECKING(for special snmp libraries) SNMPLIB=`net-snmp-config --libs` SNMPAGENTLIB=`net-snmp-config --agent-libs` # KLUDGE!! # Apparently some versions of SUSE Linux don't include -lwrap in $SNMPAGENTLIB case $SNMPAGENTLIB in *wrap*) ;; *) SNMPAGENTLIB="$SNMPAGENTLIB -lwrap";; esac AC_MSG_RESULT($SNMPLIB) fi elif test "x${ac_cv_header_ucd_snmp_snmp_h}" = "xyes"; then # UCD SNMP # ucd-snmp-config does not seem to exist, so just # rely on people having their LDFLAGS set to the path where AC_CHECK_LIB(snmp, init_snmp, SNMPLIB="-lsnmp") if test "X${SNMPLIB}" = "X"; then AC_CHECK_LIB(ucdsnmp, init_snmp, SNMPLIB="-lucdsnmp") fi SNMPAGENTLIB="$SNMPLIB" if test "X${SNMPLIB}" = "X"; then ENABLE_SNMP="no" AC_MSG_RESULT("Could not find ucdsnmp libary." "Please make sure that libsnmp or libucdsnmp" "are in your library path. Or the path to LDFLAGS") fi else ENABLE_SNMP="no" fi if test "$ENABLE_SNMP" = "no" -a "x${enable_snmp_subagent}" = "xyes"; then FatalMissingThing "SNMP Development package" "Missing SNMP development libraries and/or headers" "" "Install net-snmp-devel to enable SNMP features" fi if test "$ENABLE_SNMP" = "no" -o "x${enable_snmp_subagent}" != "xyes"; then enable_snmp_subagent="no" fi check_snmp_libs () { OLDLIBS="$LIBS" LIBS="$LIBS $@" AC_MSG_CHECKING(snmp libraries: $LIBS) AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], , AC_MSG_ERROR(cannot link with requested libraries ($LIBS). Reported errors follow: $(cat conftest.err))) AC_MSG_RESULT(ok) LIBS="$OLDLIBS" } SNMPLIBSET="" if test "$ENABLE_SNMP" = "yes"; then check_snmp_libs $SNMPLIB SNMPLIBSET="$SNMPLIB" fi if test "$enable_snmp_subagent" = "yes"; then check_snmp_libs $SNMPAGENTLIB SNMPLIBSET="$SNMPLIBSET $SNMPAGENTLIB" fi if test "x${enable_snmp_subagent}" = "xyes" -a "X${MIBS_DIR}" = "X"; then AC_MSG_CHECKING(which MIB directory to use) for mibs_dir in /usr/share/snmp/mibs \ /usr/local/share/snmp/mibs; do if test -d "$mibs_dir"; then MIBS_DIR="$mibs_dir" fi done if test "X${MIBS_DIR}" = "X"; then AC_MSG_ERROR(Could not find mibs directory, please specify with --with-mibsdir); fi AC_MSG_RESULT($MIBS_DIR) fi AC_SUBST(MIBS_DIR) AC_SUBST(SNMPCONFIG) AC_SUBST(SNMPLIB) AC_SUBST(SNMPAGENTLIB) AM_CONDITIONAL(USE_APC_SNMP, test "$ENABLE_SNMP" = "yes") AM_CONDITIONAL(SNMP_SUBAGENT_BUILD, test "x${enable_snmp_subagent}" = "xyes") if test "$GCC" = yes; then cc_supports_flag() { AC_MSG_CHECKING(whether $CC supports "$@") Cfile=/tmp/foo${$} touch ${Cfile}.c $CC -c "$@" ${Cfile}.c -o ${Cfile}.o >/dev/null 2>&1 rc=$? rm -f ${Cfile}.c ${Cfile}.o case $rc in 0) AC_MSG_RESULT(yes);; *) AC_MSG_RESULT(no);; esac return $rc } if cc_supports_flag -fgnu89-inline then CFLAGS="$CFLAGS -fgnu89-inline" fi dnl ************ printw ********************** if test X"$CURSESLIBS" != X"" && cc_supports_flag -Wcast-qual \ && cc_supports_flag -Werror; then dnl Check for printw() prototype compatibility dnl FIXME: We can check che prototype compatibility only if $CC supports dnl -Wcast-qual and -Werror AC_MSG_CHECKING(whether printw() requires argument of "const char *") ac_save_LIBS=$LIBS LIBS="$CURSESLIBS $LIBS" ac_save_CFLAGS=$CFLAGS CFLAGS="-Wcast-qual -Werror" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [ #if defined(HAVE_CURSES_H) # include #elif defined(HAVE_NCURSES_H) # include #endif ], [printw((const char *)"Test");] )], [ac_cv_compatible_printw=yes], [ac_cv_compatible_printw=no] ) LIBS=$ac_save_LIBS CFLAGS=$ac_save_CFLAGS AC_MSG_RESULT([$ac_cv_compatible_printw]) if test "$ac_cv_compatible_printw" = no; then AC_MSG_WARN([The printw() function of your ncurses or curses library is old, we will disable usage of the library. If you want to use this library anyway, please update to newer version of the library, ncurses 5.4 or later is recommended. You can get the library from http://www.gnu.org/software/ncurses/.]) AC_MSG_NOTICE([Disabling curses]) AC_DEFINE(HAVE_INCOMPATIBLE_PRINTW, 1, [Do we have incompatible printw() in curses library?]) dnl AC_DEFINE(HAVE_CURSES_H, 0) dnl AC_DEFINE(HAVE_NCURSES_H, 0) fi fi dnl ************ printw ********************** EXTRA_WARNINGS="" # We had to eliminate -Wnested-externs because of libtool changes WARNLIST="all missing-prototypes missing-declarations strict-prototypes declaration-after-statement pointer-arith write-strings cast-qual cast-align bad-function-cast inline missing-format-attribute format=2 format-security format-nonliteral no-long-long no-strict-aliasing" for j in $WARNLIST do if cc_supports_flag -W$j then case $j in "no-long-long") if test "${enable_no_long_long}" = "yes"; then EXTRA_WARNINGS="$EXTRA_WARNINGS -W$j" fi;; *) EXTRA_WARNINGS="$EXTRA_WARNINGS -W$j";; esac fi done dnl Add any system specific options here. if test "${enable_ansi}" = "unknown" -o "${enable_ansi}x" = "x"; then enable_ansi=yes fi case "$host_os" in *linux*|*bsd*) if test "${enable_fatal_warnings}" = "unknown"; then enable_fatal_warnings=yes fi ;; *solaris*) ;; esac if test "${enable_ansi}" = yes && cc_supports_flag -std=iso9899:199409 ; then echo "Enabling ANSI Compatibility on this platform" ANSI="-ansi -D_GNU_SOURCE -DANSI_ONLY" fi if test "${enable_fatal_warnings}" = yes && cc_supports_flag -Werror ; then echo "Enabling Fatal Warnings (-Werror) on this platform" FATAL_WARNINGS="-Werror" fi if test "$enable_traditional_warning" = yes && \ cc_supports_flag -Wtraditional; then echo "Enabling traditional warnings" EXTRA_WARNINGS="$EXTRA_WARNINGS -Wtraditional" fi CC_WARNINGS="$EXTRA_WARNINGS $FATAL_WARNINGS $ANSI" NON_FATAL_CC_WARNINGS="$EXTRA_WARNINGS" fi dnl ************************************************************************ dnl checks for library functions to replace them dnl dnl alphasort: Only on BSD. dnl System-V systems may have it, but hidden and/or deprecated. dnl A replacement function is supplied for it. dnl dnl NoSuchFunctionName: dnl is a dummy function which no system supplies. It is here to make dnl the system compile semi-correctly on OpenBSD which doesn't know dnl how to create an empty archive dnl dnl scandir: Only on BSD. dnl System-V systems may have it, but hidden and/or deprecated. dnl A replacement function is supplied for it. dnl dnl setenv: is some bsdish function that should also be avoided (use dnl putenv instead) dnl On the other hand, putenv doesn't provide the right API for the dnl code and has memory leaks designed in (sigh...) Fortunately this dnl A replacement function is supplied for it. dnl dnl setproctitle: sets the process title to a given string dnl dnl strerror: returns a string that corresponds to an errno. dnl A replacement function is supplied for it. dnl dnl unsetenv: is some bsdish function that should also be avoided (No dnl replacement) dnl A replacement function is supplied for it. dnl dnl strnlen: is a gnu function similar to strlen, but safer. dnl We wrote a tolearably-fast replacement function for it. dnl dnl strndup: is a gnu function similar to strdup, but safer. dnl We wrote a tolearably-fast replacement function for it. dnl dnl daemon: is a GNU function. The daemon() function is for programs wishing to dnl detach themselves from the controlling terminal and run in the dnl background as system daemon dnl A replacement function is supplied for it. dnl dnl Check Only dnl dnl getopt: If this is valid, define HAVE_DECL_GETOPT to make the getopt.h header compile cleanly. dnl AC_REPLACE_FUNCS(alphasort inet_pton NoSuchFunctionName scandir setenv strerror unsetenv strnlen strndup daemon strlcpy strlcat) dnl AC_CHECK_FUNCS(alphasort inet_pton NoSuchFunctionName scandir setenv strerror unsetenv strnlen strndup daemon) AC_CHECK_FUNCS(getopt, AC_DEFINE(HAVE_DECL_GETOPT, 1, [Have getopt function])) AC_CHECK_FUNCS(fcntl) AC_CHECK_FUNCS(flock) AC_CHECK_FUNCS(inet_aton) AC_CHECK_FUNCS(mallinfo) AC_CHECK_FUNCS(mallopt) AC_CHECK_FUNCS(__default_morecore) AC_CHECK_FUNCS(seteuid) AC_CHECK_FUNCS(setegid) AC_CHECK_FUNCS(getpeereid) dnl ********************************************************************** dnl Check for various argv[] replacing functions on various OSs dnl dnl Borrowed from Proftpd dnl Proftpd is Licenced under the terms of the GNU General Public Licence dnl and is available from http://www.proftpd.org/ dnl AC_CHECK_FUNCS(setproctitle) AC_CHECK_HEADERS(libutil.h) AC_CHECK_LIB(util, setproctitle, [AC_DEFINE(HAVE_SETPROCTITLE,1,[ ]) ac_cv_func_setproctitle="yes" ; LIBS="$LIBS -lutil"]) if test "$ac_cv_func_setproctitle" = "yes"; then pf_argv_set="PF_ARGV_NONE" fi if test "$pf_argv_set" = ""; then AC_CHECK_HEADERS(sys/pstat.h) if test "$ac_cv_header_pstat_h" = "yes"; then AC_CHECK_FUNCS(pstat) if test "$ac_cv_func_pstat" = "yes"; then pf_argv_set="PF_ARGV_PSTAT" else pf_argv_set="PF_ARGV_WRITEABLE" fi fi if test "$pf_argv_set" = ""; then AC_EGREP_HEADER([#define.*PS_STRINGS.*],sys/exec.h, have_psstrings="yes",have_psstrings="no") if test "$have_psstrings" = "yes"; then pf_argv_set="PF_ARGV_PSSTRINGS" fi fi if test "$pf_argv_set" = ""; then AC_CACHE_CHECK(whether __progname and __progname_full are available, pf_cv_var_progname, AC_TRY_LINK([extern char *__progname, *__progname_full;], [__progname = "foo"; __progname_full = "foo bar";], pf_cv_var_progname="yes", pf_cv_var_progname="no")) if test "$pf_cv_var_progname" = "yes"; then AC_DEFINE(HAVE___PROGNAME,1,[ ]) fi AC_CACHE_CHECK(which argv replacement method to use, pf_cv_argv_type, AC_EGREP_CPP(yes,[ #if defined(__GNU_HURD__) yes #endif ],pf_cv_argv_type="new", pf_cv_argv_type="writeable")) if test "$pf_cv_argv_type" = "new"; then pf_argv_set="PF_ARGV_NEW" fi if test "$pf_argv_set" = ""; then pf_argv_set="PF_ARGV_WRITEABLE" fi fi fi AC_DEFINE_UNQUOTED(PF_ARGV_TYPE, $pf_argv_set, mechanism to pretty-print ps output: setproctitle-equivalent) dnl End of tests borrowed from Proftpd dnl check if header file and lib are there for zlib bz2_installed="yes" AC_CHECK_HEADERS(bzlib.h, , [bz2_installed="no"],) AC_CHECK_LIB(bz2, BZ2_bzBuffToBuffCompress , , [bz2_intalled="no"]) dnl ************************************************************************ AC_CHECK_HEADERS(gnutls/gnutls.h) AC_CHECK_HEADERS(security/pam_appl.h pam/pam_appl.h) dnl GNUTLS library: Attempt to determine by 'libgnutls-config' program. dnl If no 'libgnutls-config', try traditional autoconf means. AC_PATH_PROGS(LIBGNUTLS_CONFIG, libgnutls-config) if test -n "$LIBGNUTLS_CONFIG"; then AC_MSG_CHECKING(for gnutls header flags) GNUTLSHEAD="`$LIBGNUTLS_CONFIG --cflags`"; AC_MSG_RESULT($GNUTLSHEAD) AC_MSG_CHECKING(for gnutls library flags) GNUTLSLIBS="`$LIBGNUTLS_CONFIG --libs`"; AC_MSG_RESULT($GNUTLSLIBS) else PKG_CHECK_MODULES(GNUTLS, [gnutls]) GNUTLSHEAD=$GNUTLS_CFLAGS GNUTLSLIBS=$GNUTLS_LIBS fi AC_CHECK_LIB(gnutls, gnutls_init) AC_CHECK_FUNCS(gnutls_priority_set_direct) AC_SUBST(GNUTLSHEAD) AC_SUBST(GNUTLSLIBS) dnl NOTE: dnl This check should only be done after CFLAGS is set. Otherwise dnl linux box will complain because of a warning of the undefined dnl function sigignore(). dnl dnl In theory, all function checks should be done after the CFLAGS is dnl set since we are enforcing the -Werror. But this would have a big dnl impact on the whole source tree so I am only moving the dnl sigignore for now. A bit of a hack. dnl dnl sigignore: Only on Solaris. dnl it is a solaris replacement for signal(s,SIG_IGN). dnl AC_CHECK_FUNCS(sigignore) dnl dnl Lex and yacc can't be trusted to produce code that won't produce dnl warnings dnl NON_FATAL_CFLAGS="$CFLAGS $NON_FATAL_CC_WARNINGS" AC_SUBST(NON_FATAL_CFLAGS) dnl dnl We reset CFLAGS to include our warnings *after* all function dnl checking goes on, so that our warning flags don't keep the dnl AC_*FUNCS() calls above from working. In particular, -Werror will dnl *always* cause us troubles if we set it before here. dnl dnl CFLAGS="$CFLAGS $CC_WARNINGS" dnl dnl Make sure that CFLAGS is not exported. If the user did dnl not have CFLAGS in their environment then this should have dnl no effect. However if CFLAGS was exported from the user's dnl environment, then the new CFLAGS will also be exported dnl to sub processes. This causes a problem when configure dnl is run in the libltdl directory. Horms 16th July 2002 dnl if export | fgrep " CFLAGS=" > /dev/null; then export -n CFLAGS || true # We don't want to bomb out if this fails fi if test "$GCC" = yes; then CFLAGS="$CFLAGS -ggdb3" if cc_supports_flag -funsigned-char then CFLAGS="$CFLAGS -funsigned-char" fi else CFLAGS="$CFLAGS -g" fi dnl AC_SUBST(CC_WARNINGS) dnl ************************************************************************ dnl pre AC_OUTPUT stuff dnl dnl th aux dir (for holding config & autogenerated stuff) dnl AC_SUBST(ac_aux_dir) AC_SUBST(LIBADD_DL) dnl extra flags for dynamic linking libraries AC_SUBST(LIBADD_INTL) dnl extra flags for GNU gettext stuff... AC_SUBST(LOCALE) CRM_ENABLED=1 if test "X$OCF_ROOT_DIR" = X; then FatalMissingThing "OCF directory" "Could not locate OCF directory" fi AC_PATH_PROG(VALGRIND_BIN, valgrind) AC_DEFINE_UNQUOTED(VALGRIND_BIN, "$VALGRIND_BIN", Valgrind command) dnl ********************************************************************** dnl 'AWK' had been determined via 'aclocal.m4' as the simple name, using dnl the current PATH (i.e. in the context of 'configure'). dnl dnl Things within heartbeat will use 'AWK', but from a different context, dnl so we should determine, and substitute, the full path. dnl dnl Note: Even that may have a flaw, e.g. if 'configure' finds (say) 'gawk', dnl which we here convert to '/path/to/gawk', but the run-time machine lacks it. dnl We won't worry about that for now. dnl (David Lee; March 2007) AC_PATH_PROGS([AWK], $AWK) CheckMissingThings dnl Options for cleaning up the compiler output PRETTY_CC="" QUIET_LIBTOOL_OPTS="" QUIET_MAKE_OPTS="" if test "x${enable_quiet}" = "xyes"; then QUIET_LIBTOOL_OPTS="--quiet" QUIET_MAKE_OPTS="--quiet" fi AC_MSG_RESULT(Supressing make details: ${enable_quiet}) dnl Put the above variables to use LIBTOOL="${LIBTOOL} --tag=CC \$(QUIET_LIBTOOL_OPTS)" MAKE="${MAKE} \$(QUIET_MAKE_OPTS)" AC_SUBST(CC) AC_SUBST(MAKE) AC_SUBST(LIBTOOL) AC_SUBST(PRETTY_CC) AC_SUBST(QUIET_MAKE_OPTS) AC_SUBST(QUIET_LIBTOOL_OPTS) dnl *************************************************************************** dnl CIM provider configuration dnl *************************************************************************** CMPI_HEADER_PATH=${with_cmpi_headers} CIMOM=${with_cimom} CMPI_PROVIDER_DIR=${with_provider_dir} if test "x${enable_cim_provider}" != "xyes"; then enable_cim_provider="no" fi if test "x${CIMOM}" = "x"; then if test "x${CIMOM}" = "x"; then AC_CHECK_PROG([CIMOM], [cimserver], [pegasus]) fi if test "x${CIMOM}" = "x"; then AC_CHECK_PROG([CIMOM], [sfcbd], [sfcb]) fi if test "x${CIMOM}" = "x"; then AC_CHECK_PROG([CIMOM], [owcimomd], [openwbem]) fi if test "x${CIMOM}" = "x"; then AC_MSG_WARN([Cimom not found, MOF will not be installed!]) fi fi if test "x${enable_cim_provider}" != "xyes"; then if test "x${CIMOM}" != "x"; then echo "NOTE: CIM provider [--enable-cim-provider] not enabled." CIMOM="" fi else if test "x${CMPI_HEADER_PATH}" != "x"; then CPPFLAGS="$CPPFLAGS -I${CMPI_HEADER_PATH}" fi for header in cmpidt.h cmpift.h cmpimacs.h do AC_CHECK_HEADER([${header}], [], [AC_MSG_ERROR([Sorry, can't find CMPI header files, \ specify CMPI header files with --with-cmpi-headers please.])] ) done AC_MSG_CHECKING(CMPI provider directory) if test "x${CMPI_PROVIDER_DIR}" = "x"; then case ${CIMOM} in sfcbd) SFCBD_PREFIX=`which sfcbd` SFCBD_PREFIX=`dirname ${SFCBD_PREFIX}` SFCBD_PREFIX=`dirname ${SFCBD_PREFIX}` CMPI_PROVIDER_DIR=${SFCBD_PREFIX}/lib/cmpi;; openwbem) OPENWBEM_PREFIX=`which owcimomd` OPENWBEM_PREFIX=`dirname ${OPENWBEM_PREFIX}` OPENWBEM_PREFIX=`dirname ${OPENWBEM_PREFIX}` OPENWBEM_CONFIG=${OPENWBEM_PREFIX}/etc/openwbem/openwbem.conf OPENWBEM_CMPI_DIR=`grep -e "cmpiprovifc.prov_location.*=" \ ${OPENWBEM_CONFIG} | sed -e 's/.*=\s*\(\.*\)/\1/'` if test "x${OPENWBEM_CMPI_DIR}" != "x"; then CMPI_PROVIDER_DIR=${OPENWBEM_CMPI_DIR} echo cmpi provider dir set, using openwbem config file: \ ${OPENWBEM_CONFIG}. else CMPI_PROVIDER_DIR=${OPENWBEM_PREFIX}/lib/openwbem/cmpiproviders echo openwbem config not found, cmpi provider dir set to \ $(CMPI_PROVIDER_DIR) by default. fi;; pegasus|tog-pegasus) CMPI_PROVIDER_DIR=/opt/tog-pegasus/providers/lib;; *);; esac if test x"$CMPI_PROVIDER_DIR" = x ; then CMPI_PROVIDER_DIR="$libdir"/cmpi AC_MSG_RESULT(default directory: $CMPI_PROVIDER_DIR) fi AC_MSG_RESULT($CMPI_PROVIDER_DIR) fi fi AM_CONDITIONAL(CIM_PROVIDER_BUILD, test "x${enable_cim_provider}" = "xyes") AC_SUBST(CMPI_PROVIDER_DIR) AC_SUBST(CIMOM) AC_SUBST(CMPI_HEADER_PATH) AM_CHECK_PYTHON_HEADERS(,PYTHON_INCLUDES='') AC_SUBST(PYTHON_INCLUDES) dnl ************************************************************************ dnl * Check for (debian style?) $sysconfdir/pam.d/common-{account,auth} AC_CHECK_FILE($sysconfdir/pam.d/common-account) AC_CHECK_FILE($sysconfdir/pam.d/common-auth) AM_CONDITIONAL(USE_PAM_COMMON, test -f $sysconfdir/pam.d/common-account -a \ -f /etc/pam.d/common-auth) if test "x${enable_mgmt_client}" != "xno" -a "x${PYTHON_INCLUDES}" = "x"; then FatalMissingThing "Python.h" \ "The GUI managment module needs Python.h (Linux: python-devel package)" fi if test "$ac_cv_header_security_pam_appl_h" = "no" -a "$ac_cv_header_pam_pam_appl_h" = "no"; then FatalMissingThing "security/pam_appl.h" \ "The GUI managment module needs the pam-devel package" fi if test "$ac_cv_header_gnutls_gnutls_h" = "no"; then FatalMissingThing "gnutls/gnutls.h" \ "The GUI managment module needs GNU/TLS header files" fi if test "x${enable_mgmt_client}" != "xno" -a -z "$SWIG"; then FatalMissingThing "swig" \ "The GUI managment module needs swig" \ "You can get it from http://swig.org/" fi CheckMissingThings dnl ********************************************** dnl TSA plugin configuration dnl ********************************************** JAVA_HOME=${with_java_home} TSA_DIR=${with_tsa_dir} if test "x${enable_tsa_plugin}" != "xno"; then if test "x${JAVA_HOME}" = "x"; then JAVA_BIN=`which java` JAVA_BIN_DIR=`dirname ${JAVA_BIN}` JAVA_HOME=`dirname ${JAVA_BIN_DIR}` fi if test "x${TSA_DIR}" = "x"; then TSA_DIR="/opt/IBM/tsamp/" fi fi AC_SUBST(JAVA_HOME) AC_SUBST(TSA_DIR) AM_CONDITIONAL(TSA_PLUGIN_BUILD, test "x${enable_tsa_plugin}" != "xno") dnl *** "echo" adjustments (begin) *** dnl Some run-time scripts require options to "echo". dnl This configure is already determining and using "ac_n" and "ac_c" dnl for internal use, so make available externally. dnl (Not sure how "future proof" this is, but it at least seems clean.) dnl dnl This must be close to the end of "configure.in" otherwise it interferes dnl with output from the AC_MSG_*() macros. ECHO_N="$ac_n" ECHO_C="$ac_c" case $ac_n in -n) ECHO_E="-e";; *) ECHO_E="";; esac ECHO_CMD="echo" if test -x /usr/linux/bin/echo then # This is for AIX. I'm not sure it's necessary... ECHO_CMD="/usr/linux/bin/echo" ECHO_N="-n" ECHO_E="-e" fi AC_SUBST(ECHO_N) AC_SUBST(ECHO_C) AC_SUBST(ECHO_E) AC_SUBST(ECHO_CMD) dnl *** "echo" adjustments (end) *** AC_DEFINE_UNQUOTED(PKG_FEATURES, "$PKG_FEATURES", Set of enabled features) AC_SUBST(PKG_FEATURES) dnl The Makefiles and shell scripts we output AC_CONFIG_FILES(Makefile \ README \ debian/Makefile \ doc/Makefile include/Makefile \ include/mgmt/Makefile \ lib/Makefile \ lib/mgmt/Makefile \ cim/Makefile \ cim/mof/Makefile \ cim/mof/register_providers.sh \ cim/mof/unregister_providers.sh \ mgmt/Makefile \ mgmt/daemon/Makefile \ mgmt/client/Makefile \ mgmt/client/haclient.py \ mgmt/client/crm_gui.desktop \ mgmt/client/mgmtcmd.py \ po/Makefile.in replace/Makefile \ snmp_subagent/Makefile \ snmp_subagent/SNMPAgentSanityCheck \ tsa_plugin/Makefile \ tsa_plugin/testrun.sh \ tsa_plugin/linuxha-adapter \ ) dnl Now process the entire list of files added by previous dnl calls to AC_CONFIG_FILES() AC_OUTPUT() dnl ***************** dnl Configure summary dnl ***************** AC_MSG_RESULT([]) AC_MSG_RESULT([$PACKAGE configuration:]) AC_MSG_RESULT([ Version = ${VERSION} (Build: $BUILD_REVISION)]) AC_MSG_RESULT([ Prefix = ${prefix}]) AC_MSG_RESULT([ Executables = ${sbindir}]) AC_MSG_RESULT([ Man pages = ${mandir}]) AC_MSG_RESULT([ Libraries = ${libdir}]) AC_MSG_RESULT([ Header files = ${includedir}]) AC_MSG_RESULT([ Arch-independent files = ${datadir}]) AC_MSG_RESULT([ State information = ${localstatedir}]) AC_MSG_RESULT([ System configuration = ${sysconfdir}]) AC_MSG_RESULT([ Init (rc) scripts = ${INITDIR}]) AC_MSG_RESULT([ Use system LTDL = ${ac_cv_lib_ltdl_lt_dlopen}]) AC_MSG_RESULT([ HA group name = ${HA_APIGROUP}]) AC_MSG_RESULT([ HA user name = ${HA_CCMUSER}]) AC_MSG_RESULT([ Build snmp subagent = ${enable_snmp_subagent}]) if test "x${enable_snmp_subagent}" = "xyes"; then AC_MSG_RESULT([ SNMP MIB directory = ${MIBS_DIR}]) AC_MSG_RESULT([ SNMP agent libraries = ${SNMPAGENTLIB}]) fi AC_MSG_RESULT([ SNMP libraries = ${SNMPLIB}]) AC_MSG_RESULT([ With Heartbeat support = ${SUPPORT_HEARTBEAT}]) AC_MSG_RESULT([ With AIS support = ${AIS_VERSION}]) AC_MSG_RESULT([ With AIS prefix = ${AISPREFIX}]) AC_MSG_RESULT([ CC_WARNINGS = ${CC_WARNINGS}]) AC_MSG_RESULT([ Mangled CFLAGS = ${CFLAGS}]) AC_MSG_RESULT([ Libraries = ${LIBS}]) pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/000077500000000000000000000000001211477743100205275ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/Makefile.am000066400000000000000000000023431211477743100225650ustar00rootroot00000000000000# # linux-ha: Linux-HA heartbeat code # # Copyright (C) 2001 Michael Moerz # This instance created by Horms # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = apply changelog compat control copyright \ dpkg-checkbuild rules \ pacemaker-mgmt.install pacemaker-mgmt.dirs \ pacemaker-mgmt-client.install pacemaker-mgmt-client.dirs \ pacemaker-mgmt-dev.install pacemaker-mgmt-dev.dirs clean-local: rm -f *.substvars *.debhelper files rm -r -f pacemaker-mgmt pacemaker-mgmt-client pacemaker-mgmt-dev tmp pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/apply000066400000000000000000000126611211477743100216050ustar00rootroot00000000000000#!/bin/sh # Apply script for managing patches for debian builts # Taken from debian kernel-source-2.4.27 package # Original Author: Herbert Xu set -e length=50 die() { echo "E: $@" >&2 exit 1 } warn() { echo "W: $@" >&2 } uncompress_patch() { patch=$1 case "$patch" in *.bz2) bzcat $patch ;; *.gz) zcat $patch ;; *) cat $patch ;; esac } find_patch() { patch=$1 if [ -f "$patch" ]; then echo "$patch" elif [ -f "$patch.bz2" ]; then echo "$patch.bz2" elif [ -f "$patch.gz" ]; then echo "$patch.gz" else die "$patch is in the series, but doesn't exist!" fi } apply_patch() { patch=$(find_patch $home/$1) base=$1 if uncompress_patch "$patch" | patch -p1 -s -t --no-backup-if-mismatch; then printf "%-${length}s\tOK (+)\n" "$base" else printf "%-${length}s\tFAIL (+)\n" "$base" exit 1 fi } deapply_patch() { patch=$(find_patch $home/$1) base=$1 if uncompress_patch "$patch" | patch -p1 -s -t -R --no-backup-if-mismatch; then printf "%-${length}s\tOK (-)\n" "$base" else printf "%-${length}s\tFAIL (-)\n" "$base" exit 1 fi } unpatch_series() { series=$1 [ -f "$series" ] || die "I wasn't passed a series!" tac $series | while read action patch; do case "$action" in +) deapply_patch $patch ;; -) apply_patch $patch ;; X) bakfile="$(dirname $patch)/.$(basename $patch).bak" if [ -f "$bakfile" ]; then mv -f "$bakfile" "$patch" printf "%-${length}s\tRESTORED (X)\n" "$patch" else printf "%-${length}s\tNO BACKUP (X)\n" "$patch" fi ;; esac done echo "--> $(basename $series) fully unapplied." } patch_series() { series=$1 [ -f "$series" ] || die "I wasn't passed a series!" while read action patch; do case "$action" in +) apply_patch $patch ;; -) deapply_patch $patch ;; X) bakfile="$(dirname $patch)/.$(basename $patch).bak" if [ -f "$patch" ]; then mv -f "$patch" "$bakfile" printf "%-${length}s\tREMOVED (X)\n" "$patch" else printf "%-${length}s\tNO FILE (X)\n" "$patch" fi ;; esac done < $series echo "--> $(basename $series) fully applied." } bubble_sort () { DIR=$1 shift SORTED=$@ SWAPED=1 while [ $SWAPED = 1 ]; do X=0 A="" SWAPED=0 NEW="" for i in $SORTED; do if [ -z "$A" ]; then A="$i" continue fi B="$i" if dpkg --compare-versions "$A" "$DIR" "$B"; then SWAPED=1 NEW="$NEW $B" else NEW="$NEW $A" A="$B" fi X=$(($X + 1)) done SORTED="$NEW $A" done echo $SORTED } bubble_sort_fwd () { bubble_sort "lt" $@ } bubble_sort_rev () { bubble_sort "gt" $@ } if ! [ -d heartbeat ]; then die 'Not in heartbeat top level directory. Exiting' exit 1 fi # for THIS particular version of the source package #deb_version=$(sed -ne "/^heartbeat/ { s/.*(\([^)]*\)).*/\1/ p" -e "q}" \ # ${PWD}/debian/changelog) deb_version=$(dpkg-parsechangelog | awk '/^Version: / { print $2 }') version=${override_version:-$deb_version} upstream=${version%-*} revision=${version#*-} home="$PWD/debian/patches" if [ -f version.Debian ]; then current=$(cat version.Debian) current_rev=${current#*-} current_up=${current%-*} if [ "$current" = "$upstream" ]; then current_rev=0 fi else warn "No version.Debian file, assuming pristine heartbeat $upstream" current=$upstream current_rev=0 fi target=${1:-$version} target_rev=${target#*-} target_up=${target%-*} # Sanity checks if [ "$target_up" != "$upstream" ]; then die "Upstream $target_up doesn't match $upstream!" # We don't have that version out yet! elif [ ! -n "$target_rev" ] || ( [ "$target_rev" != "$target" ] && dpkg --compare-versions $target_rev gt $revision ); then year=$(($(date +%Y) + 1)) die "Can't patch to nonexistent revision $target_rev (wait until $year)" fi # At this point, we must handle three cases. # 1. $target_rev is greater than $current_rev. We must patch forward for this. # 2. $target_rev is less than $current_rev. We must reverse the list of series, # reverse each used series (tac) and unapply applied patches and vice versa. # 3. $target_rev is undefined, and $target is $upstream. # Revert to upstream. if [ "$target_rev" = "$target" ]; then # already reverted if [ "$current" = "$target" ]; then echo "Nothing to do, exiting." exit 0 fi for base in $(cd $home/series/ && bubble_sort_fwd $(ls -d *-*)); do srev=${base#*-} if [ -n "$srev" ]; then if dpkg --compare-versions $srev le $current_rev; then unpatch_series $home/series/$base fi else die "Series doesn't have a revision!" fi done elif [ "$current_rev" = "$upstream" ] || dpkg --compare-versions $target_rev gt $current_rev; then for base in $(cd $home/series/ && bubble_sort_rev $(ls -d *-*)); do srev=${base#*-} if [ -n "$srev" ]; then if dpkg --compare-versions $srev gt $current_rev && dpkg --compare-versions $srev le $target_rev; then patch_series $home/series/$base fi else die "Series doesn't have a revision!" fi done elif [ $target_rev = $current_rev ]; then echo "Nothing to do, exiting." exit 0 elif dpkg --compare-versions $target_rev lt $current_rev; then for base in $(cd $home/series/ && bubble_sort_fwd $(ls -d *-*)); do srev=${base#*-} if [ -n "$srev" ]; then # gt because you don't want to unapply the target series if dpkg --compare-versions $srev le $current_rev && dpkg --compare-versions $srev gt $target_rev; then unpatch_series $home/series/$base fi else die "Series doesn't have a revision!" fi done fi echo $target > version.Debian pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/changelog000066400000000000000000000306441211477743100224100ustar00rootroot00000000000000pacemaker-mgmt (1.99.2-1) unstable; urgency=medium * Update source tarball to revision: 0cc24125502d tip * Statistics: Changesets: 49 Diff: 13 files changed, 4164 insertions(+), 2759 deletions(-) * Changes since pacemaker-mgmt-1.99.1 + Dev: haclient: Add "About" + Dev: haclient: Add accelerators + Dev: haclient: Add Japanese translation + Dev: haclient: Improve thread synchronization + Dev: haclient: Provide the progress pulse when generating the transition information + Dev: haclient: Set default response for dialogs + Dev: haclient: Show progress pulse when generating shadow diff + Dev: haclient: Support viewing/editing/importing/exporting the whole cib xml or the configuration section + Dev: mgmt: Improve the performance and the user interface of "Transition Information" + Dev: mgmt: Provide more details of nodes + Dev: po: Add the translation of the license + Dev: po: Update pot and po + High: lib: Fix huge memory leak due to the behavior of swig + Low: Build: Add libgv-python dependency for Debian + Low: haclient: Avoid an error if there's no pengine input exists + Low: haclient: Avoid the possible key error of Manager.get_node_config() + Low: haclient: Concatenate error messages with the proper type + Low: haclient: Consider the possibility of IOError when creating temporary files + Low: haclient: Determine labels's width and align the following widgets properly + Low: haclient: Do not continue updating if the client is disconnected + Low: haclient: Fill the limited number of transitions into the drop-down list + Low: haclient: Make python-lxml optional + Low: haclient: Make sure the variable is assigned before referenced + Low: haclient: Make the marks of meta_attributes's default values consistent + Low: haclient: Set the default focus on "password" entry in the login dialog + Low: haclient: Set widgets's initial sizes to appropriate values for low resolutions + Low: mgmt: Log version details + Low: mgmt: Show its unclean resources if a node is uncleanly offline + Low: mgmtd: (LF#2142) Avoid redefinitions + Low: mgmtd: Add and adopt a new macro gen_msg_from_fstream() + Low: mgmtd: Adopt append_str() macro in on_get_pe_inputs() + Low: mgmtd: Can be compiled and work against pacemaker < 1.0.3 + Low: mgmtd: Optimize for tranferring schemas + Low: mgmtd: Optimize message generating for transferring cluster reports + Low: mgmtd: Optimize message generating for transferring crm DTD + Low: mgmtd: Optimize message generating for transferring transition information + Low: mgmtd: Use the variable instead of the macro directly + Low: snmp_subagent: Allow specifying the cache timeout through the argument if not SUPPORT_HEARTBEAT + Medium: haclient: Avoid hanging when getting or parsing CIB/schemas fail + Medium: haclient: Do manager.update() via gobject timeout + Medium: haclient: Increase the interval of gobject timeout to avoid consuming excessive CPU when update fails + Medium: haclient: Remove the graph when it's no longer needed + Medium: haclient: Set gobject timeout for manager.update() in the consistent way + Medium: haclient: Update crm metadata via gobject timeout (Optimize connecting time) + Medium: mgmt: Display the proper status of resources on the node which is uncleanly offline + Medium: mgmtd: Destroy the crmd channel in the end of on_cleanup_rsc() + Medium: mgmtd: Fix memory leaks -- Gao,Yan Mon, 29 Jun 2009 14:05:12 +0800 pacemaker-mgmt (1.99.1-1) unstable; urgency=medium * Update source tarball to revision: pacemaker-mgmt-1.99.1 (484883b2efe8+ tip) * Statistics: Changesets: 27 Diff: 26 files changed, 10335 insertions(+), 1290 deletions(-) * Changes since 1.99.0-3 + Build: (bnc#487697) Add copies of licenses + Dev: haclient: Automatically generate meaningful unique IDs instead of UUIDs + Dev: haclient: Automatically generate unique IDs for "op"s in "Simple Mode" + Dev: haclient: Improved for i18n + Dev: haclient: Make sure a generated ID is valid against schema + Dev: haclient: Propose ID for objects for which users may not want to set ID themselves + Dev: po: Maintain po in a separate directory. + High: mgmt: The path that keeps PEngine outputs has been changed! + High: mgmtd: Replace the adoptions of dirent->d_type which is not supported by some filesystems such as reiserfs + Low: Build: Improve i18n support for compatibility + Low: haclient: (bnc#484169) Add desktop file + Low: haclient: Make sure a created intermediate object's ID is unique + Low: haclient: Rename some terms + Low: haclient: Support objects with unicode IDs + Low: mgmtd: Try to stat the cluster report file directly + Medium: haclient: (bnc#486866) Check whether a specified time is valid + Medium: haclient: (bnc#488594) Additional prechecks for "primitive" + Medium: haclient: Generate an UUID first (since there are objects for which we could not generate a meaningful ID) + Medium: haclient: Set the focus back after dynamically tuning the layout + Medium: mgmt: Optimize viewing transition information + Medium: mgmtd: Avoid segmentation faults caused by missing the required user or group -- Gao,Yan Mon, 27 Apr 2009 11:45:06 +0800 pacemaker-mgmt (1.99.0-3) unstable; urgency=medium * Update source tarball to revision: f07b59e49f79 tip * Statistics: Changesets: 9 Diff: 6 files changed, 929 insertions(+), 95 deletions(-) * Changes since 1.99.0-2 + Dev: mgmt: Implement shadow configuration support + Low: haclient: Change the layout of buttons for TransitionInfoDlg() + Low: haclient: Do not set "target-role" in add wizard if working on a shadow CIB + Low: haclient: Fix file filters for saving transition graph + Medium: haclient: Get and cache CRM metadata in advance -- Gao,Yan Fri, 20 Mar 2009 02:00:41 +0800 pacemaker-mgmt (1.99.0-2) unstable; urgency=medium * Update source tarball to revision: 19e662ce6447+ tip * Statistics: Changesets: 7 Diff: 4 files changed, 58 insertions(+), 6 deletions(-) * Changes since pacemaker-mgmt-1.99.0 + Dev: haclient: Hide less used attributes of "op" in simple mode + Low: Build: Improve debian/control file + Low: haclient: Add "interleave" setting in wizard + Low: haclient: Hide optional attributes for "rsc_order" in simple mode + Medium: Build: Fix compilation -- Gao,Yan Sat, 14 Mar 2009 10:05:12 +0800 pacemaker-mgmt (1.99.0-1) unstable; urgency=medium * Update source tarball to pacemaker-mgmt-1.99.0 (revision: 286f917a201f+ tip) * Statistics: Changesets: 317 Diff: 57 files changed, 9929 insertions(+), 6936 deletions(-) * Changes since pacemaker-pygui-1.4 + Complete rewrite -- Gao,Yan Mon, 02 Mar 2009 16:10:14 +0800 pygui (2.0-1) stable; urgency=medium * Update source tarball to revision: 1485861613b7 tip * Statistics: Changesets: 119 Diff: 29 files changed, 4190 insertions(+), 700 deletions(-) * Changes since pacemaker-pygui-1.4 + Complete rewrite -- Andrew Beekhof Mon, 13 Oct 2008 20:27:12 +0200 pygui (1.4-1) stable; urgency=medium * Update source tarball to revision: e25a1969548c tip * Statistics: Changesets: 21 Diff: 5 files changed, 8 insertions(+), 5 deletions(-) * Changes since pygui-1.3.1 + configure.in: Check cluster stack before add extra warning options for gcc + haclient: Consider the conditions of RESPONSE_DELETE_EVENT + haclient: Consider the conflicts of file names before saving a cluster report + haclient: Improve the message box + haclient: Pop up a message box besides syslog if failed parsing the metadata of a RA (change my decision;-)) + haclient: Provide a confirm dialog before generate the cluster report + haclient: Resolve a compatibility issue for pygtk < 2.6 + haclient: Support doing command asynchronously through threading; Provide a progress pulse when waiting for a session I/O + High: Build: Add entries for the snmp on debian + High: Dont increment uninitialized variables + High: Only free data after we're done with it + Implement editing the description.txt from the archive of a cluster report + Medium: snmp: Fix building against Pacemaker 0.6.5 + mgmt: Compatible with openais-based cluster stack + mgmt: Implement cluster reporting through hb_report + mgmtd: Check arguments when getting metadata of crm for security + mgmtd: Resolve an implicit declaration + snmp_subagent: Retrieve LHANodeIndex value properly -- Andrew Beekhof Fri, 20 Jun 2008 08:32:47 +0200 pygui (1.3.1-1) stable; urgency=medium * Update source tarball to revision: 9ac514be51ff tip * Statistics: Changesets: 15 Diff: 6 files changed, 138 insertions(+), 169 deletions(-) * Changes since pygui-1.3 + High: Build: Build snmp on debian too + High: haclient: Use the correct XML wrapper functions to allow building with pacemaker 0.7 -- Andrew Beekhof Wed, 14 May 2008 16:24:45 +0200 pygui (1.3-1) stable; urgency=medium * Update source tarball to revision: 46736ff1b944 tip * Statistics: Changesets: 26 Diff: 96 files changed, 7120 insertions(+), 299 deletions(-) * Changes since pygui-1.2 + Added SNMP functionality from Heartbeat/Pacemaker + Bug 1814 - SNMP Subagent fix for failure on ppc + haclient: Fill all sub-resources into the list of combobox for selecting + haclient: Get all resources recursively (previously get only resources in top two level) + haclient: Provide options for cleaning up specified/all resource(s) on specified/all node(s) + mgmt: Clean up the failcount when cleaning up a resource + mgmt: Dynamic rendering fileds for tables according to DTD + mgmt: Pop up a description tip when leaving the pointer over the label of crm parameter. + mgmt: Remove hardcoded portions of instance_attributes, operations and rsc_location rule + mgmt: Resolve a compatibility issue for pygtk before 2.6 + mgmt: Resolve the issue caused by inconsistent names between DTD and RA. + mgmt: Resolve the problem while dynamic filling for an operation with role + mgmt: Return the actual value returned from cib_conn (Novell Bug #356170) + mgmt: Rewrite "instance_attributes", "operations" and "expression" based on the new model + mgmt: Tune some translations -- Andrew Beekhof Wed, 23 Apr 2008 17:51:20 +0200 pygui (1.2-1) unstable; urgency=low * Update source tarball to revision: 37598aa21f3f tip * Statistics: Changesets: 6 Diff: 6 files changed, 164 insertions(+), 20 deletions(-) * Changes since pygui-1.1 + mgmt: Implement migration and unmigration of resources + pam: replace debian specific '@include' with standard(?) syntax -- Andrew Beekhof Thu, 24 January 2008 21:21:00 +0200 pygui (1.1-1) unstable; urgency=low * Update source tarball to revision: d0c7cdc27d29 * Statistics: Changesets: 19 Diff: 26 files changed, 1102 insertions(+), 1839 deletions(-) * Changes since pygui-1.0.0 + High: Build: Make sure all required variables are expanded (and set consistently with Heartbeat) + mgmt: Exclude the resource with corrupted metadata from the list in adding resource dialog. + mgmt: Implement common classes for adding and viewing kinds of objects. + mgmt: Improve the commonality of the common model + mgmt: Provide correct message about failed login. + mgmt: Resolve a compatibility problem for old python + mgmt: Resolve a compatibility problem for pygtk under 2.6 + mgmt: Resume tls sending in outer function + mgmt: Tune the displaying of some text. -- Andrew Beekhof Mon, 21 January 2008 17:38:00 +0200 pygui (1.0.0-1) unstable; urgency=low * Initial package check-in * Update source tarball to revision: 10a1481e946b * Statistics: Changesets: 41 Diff: 1593 files changed, 754 insertions(+), 349296 deletions(-) * Changes since STABLE-2.1.3 + hbagent - corrected a minor typo from the change to squash certain errors during shutdown. A "#" had crept in somehow.. + hbmgmtd: use /etc/pam.d/common-{auth,account} if available + High: Build: Fix build after cleanup + High: Build: Remove everything not specific to the gui/tsa_agent or CIM -- Andrew Beekhof Fri, 11 January 2008 11:37:00 +0200 pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/compat000066400000000000000000000000021211477743100217250ustar00rootroot000000000000004 pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/control000066400000000000000000000035761211477743100221450ustar00rootroot00000000000000Source: pacemaker-mgmt Section: admin Priority: optional Maintainer: Gao,Yan Build-Depends: debhelper (>= 5.0.37.2), libsnmp10-dev | libsnmp-dev, libglib2.0-dev, net-tools, python, libtool, libcurl4-openssl-dev | libcurl3-openssl-dev, libxml2-dev, bison, flex, uuid-dev, lynx, libbz2-dev, zlib1g-dev, uuid-dev, libltdl3-dev, swig, openssh-client, libgnutls-dev, python-central (>= 0.5), python-dev, libpam0g-dev, libncurses5-dev, pacemaker-dev, heartbeat-dev, intltool Standards-Version: 3.7.3 XS-Python-Version: current Package: pacemaker-mgmt Section: admin Priority: optional Architecture: any Conflicts: pacemaker-pygui Replaces: pacemaker-pygui Depends: pacemaker, heartbeat (>= 2.99), snmpd, libxml2-utils, libpam-runtime (>= 0.76-14), findutils XB-Python-Version: ${python:Versions} Description: Pacemaker Management Tools A client/server GUI and a SNMP subagent for configuring, managing and monitoring the Pacemaker High-Availability cluster resource manager Package: pacemaker-mgmt-client Section: admin Priority: optional Architecture: any Conflicts: pacemaker-pygui Replaces: pacemaker-pygui Depends: ${python:Depends}, python-xml, python-gtk2, python-lxml, libgv-python XB-Python-Version: ${python:Versions} Description: Pacemaker Management Tools A client/server GUI and a SNMP subagent for configuring, managing and monitoring the Pacemaker High-Availability cluster resource manager . This package contains the front-end of GUI Package: pacemaker-mgmt-dev Section: devel Priority: optional Architecture: any Conflicts: pacemaker-pygui-dev Replaces: pacemaker-pygui-dev Depends: pacemaker-mgmt (= ${binary:Version}) XB-Python-Version: ${python:Versions} Description: Pacemaker Management Tools A client/server GUI and a SNMP subagent for configuring, managing and monitoring the Pacemaker High-Availability cluster resource manager . This package contains development files pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/copyright000066400000000000000000000027331211477743100224670ustar00rootroot00000000000000The management components that used to be part of Heartbeat (but isn't supposed to anymore since Heartbeat doesn't include the CRM aka. Pacemaker) The original sources can be found at: http://hg.clusterlabs.org/pacemaker/pygui/ Upstream Authors: NOTE: The work of everyone on this project is dearly appreciated. If you are not listed here but should be, please notify us! Gao,Yan The following people have kindly helped with pacemaker-mgmt development by providing code, documentation or testing, or fixes: Andrew Beekhof Lars Marowsky-Brée Xinwei Hu The GUI was first developed in 2005 by: Huang Zhen The SNMP subagent was first developed in 2002 by: Zou Yixiong (yixiong.zou@intel.com) Keisuke MORI SNMP subagent v2 support Contributors, ordered by last name: Code for the following pieces borrowed from code by: All binaries provided by this package are GNU GPL or GNU LGPL. Some source files are under the BSD licence or in the public domain, as annotated by those files. All source files without a specific licence statement are available licenced under the GNU GPL. A copy of the GNU GPL licence is available on Debian systems at /usr/share/common-licenses/GPL A copy of the GNU LGPL licence is available on Debian systems at /usr/share/common-licenses/LGPL A copy of the BSD licence is available on Debian systems at /usr/share/common-licenses/BSD pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/dpkg-checkbuild000066400000000000000000000120721211477743100234740ustar00rootroot00000000000000#!/usr/bin/perl -w # Copyright 2001 by Joey Hess # License: GNU General Public License (GPL) use strict; use Getopt::Long; sub usage { print STDERR < \$binary_only)) { usage(); exit(2); } my $control=shift || "debian/control"; open (CONTROL, $control) || die "$control: $!\n"; my @status=parse_status(); my (@unmet, @conflicts); while () { chomp; last if $_ eq ''; # end of first stanza if (/^Build-Depends:\s+(.*)/i) { push @unmet, build_depends($1, @status); } elsif (/^Build-Conflicts:\s+(.*)/i) { push @conflicts, build_conflicts($1, @status); } elsif (! $binary_only && /^Build-Depends-Indep:\s+(.*)/i) { push @unmet, build_depends($1, @status); } elsif (! $binary_only && /^Build-Conflicts-Indep:\s+(.*)/i) { push @conflicts, build_conflicts($1, @status); } } close CONTROL; if (@unmet) { print STDERR "$me: Unmet build dependancies: "; print STDERR join(", ", @unmet), "\n"; } if (@conflicts) { print STDERR "$me: Build conflicts: "; print STDERR join(", ", @conflicts), "\n"; } exit 1 if @unmet || @conflicts; # This part could be replaced. Silly little status file parser. # thanks to Matt Zimmerman. Returns two hash references that # are exactly what the other functions need... sub parse_status { my $status=shift || "/var/lib/dpkg/status"; my %providers; my %version; local $/ = ''; open(STATUS, "<$status") || die "$status: $!\n"; while () { next unless /^Status: .*ok installed$/m; my ($package) = /^Package: (.*)$/m; push @{$providers{$package}}, $package; ($version{$package}) = /^Version: (.*)$/m; if (/^Provides: (.*)$/m) { foreach (split(/,\s+/, $1)) { push @{$providers{$_}}, $package; } } } close STATUS; return \%version, \%providers; } # This function checks the build dependancies passed in as the first # parameter. If they are satisfied, returns false. If they are unsatisfied, # an list of the unsatisfied depends is returned. # # Additional parameters that must be passed: # * A reference to a hash of all "ok installed" the packages on the system, # with the hash key being the package name, and the value being the # installed version. # * A reference to a hash, where the keys are package names, and the # value is a true value iff some package installed on the system provides # that package (all installed packages provide themselves) # # Optionally, the architecture the package is to be built for can be passed # in as the 4th parameter. If not set, dpkg will be queried for the build # architecture. sub build_depends { return check_line(1, @_); } # This function is exactly like unmet_build_depends, except it # checks for build conflicts, and returns a list of the packages # that are installed and are conflicted with. sub build_conflicts { return check_line(0, @_); } # This function does all the work. The first parameter is 1 to check build # deps, and 0 to check build conflicts. sub check_line { my $build_depends=shift; my $line=shift; my %version=%{shift()}; my %providers=%{shift()}; my $build_arch=shift || `dpkg --print-architecture`; chomp $build_arch; my @unmet=(); foreach my $dep (split(/,\s+/, $line)) { my $ok=0; my @possibles=(); ALTERNATE: foreach my $alternate (split(/\s*\|\s*/, $dep)) { my ($package, $rest)=split(/\s+/, $alternate, 2); # Check arch specifications. if (defined $rest && $rest=~m/\[(.*?)\]/) { my $arches=lc($1); my $seen_arch=''; foreach my $arch (split(' ', $arches)) { if ($arch eq $build_arch) { $seen_arch=1; next; } elsif ($arch eq "!$build_arch") { next ALTERNATE; } elsif ($arch =~ /!/) { # This is equivilant to # having seen the current arch, # unless the current arch # is also listed.. $seen_arch=1; } } if (! $seen_arch) { next; } } # This is a possibile way to meet the dependancy. # Remove the arch stuff from $alternate. $alternate=~s/\s+\[.*?\]//; push @possibles, $alternate; # Check version. if (defined $rest && $rest=~m/\((..)\s+(.*?)\)/) { my $relation=$1; my $version=$2; if (! exists $version{$package}) { # Not installed at all, so fail. next; } else { # Compare installed and needed # version number. system("dpkg", "--compare-versions", $version{$package}, $relation, $version); if (($? >> 8) != 0) { next; # fail } } } elsif (! defined $providers{$package}) { # It's not a versioned dependancy, and # nothing provides it, so fail. next; } # If we get to here, the dependancy was met. $ok=1; } if (@possibles && (($build_depends && ! $ok) || (! $build_depends && $ok))) { # TODO: this could return a more complex # data structure instead to save re-parsing. push @unmet, join (" | ", @possibles); } } return @unmet; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/pacemaker-mgmt-client.dirs000066400000000000000000000001361211477743100255600ustar00rootroot00000000000000usr/bin usr/lib/heartbeat-gui usr/share/heartbeat-gui usr/share/applications usr/share/locale pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/pacemaker-mgmt-client.install000066400000000000000000000006301211477743100262640ustar00rootroot00000000000000usr/bin/crm_gui usr/bin/hb_gui usr/lib/heartbeat-gui usr/lib/heartbeat-gui/_pymgmt.so* usr/lib/heartbeat-gui/haclient.py usr/lib/heartbeat-gui/pymgmt.py usr/share/applications/crm_gui.desktop usr/share/heartbeat-gui usr/share/heartbeat-gui/*.png usr/share/heartbeat-gui/haclient.py usr/share/heartbeat-gui/mgmtcmd.py usr/share/locale/zh_CN/LC_MESSAGES/haclient.mo usr/share/locale/ja/LC_MESSAGES/haclient.mo pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/pacemaker-mgmt-dev.dirs000066400000000000000000000000711211477743100250560ustar00rootroot00000000000000usr/include/heartbeat usr/include/heartbeat/mgmt usr/lib pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/pacemaker-mgmt-dev.install000066400000000000000000000004741211477743100255720ustar00rootroot00000000000000usr/include/heartbeat/mgmt usr/include/heartbeat/mgmt/mgmt_client.h usr/include/heartbeat/mgmt/mgmt_common.h usr/include/heartbeat/mgmt/mgmt.h usr/include/heartbeat/mgmt/mgmt_tls.h usr/include/heartbeat/mgmt_config.h usr/lib/libhbmgmt.so usr/lib/libhbmgmttls.so usr/lib/libhbmgmtcommon.so usr/lib/libhbmgmtclient.so pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/pacemaker-mgmt.dirs000066400000000000000000000001511211477743100243010ustar00rootroot00000000000000etc/pam.d usr/lib usr/lib/heartbeat usr/share/heartbeat usr/share/snmp/mibs usr/share/doc/pacemaker-mgmt pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/pacemaker-mgmt.files000066400000000000000000000042451211477743100244520ustar00rootroot00000000000000/etc/pam.d/hbmgmtd usr/lib/libhbmgmtclient.so.0.0.0 usr/lib/libhbmgmt.so.0 usr/lib/libhbmgmt.so.0.0.0 usr/lib/libhbmgmtcommon.so.0.0.0 usr/lib/libhbmgmttls.so.0.0.0 usr/lib/libhbmgmttls.so.0 usr/lib/libhbmgmtcommon.so.0 usr/lib/libhbmgmtclient.so.0 usr/lib/heartbeat/mgmtd usr/lib/heartbeat/mgmtdtest usr/lib/heartbeat/hbagent usr/lib/heartbeat/SNMPAgentSanityCheck usr/share/snmp/mibs/LINUX-HA-MIB.txt usr/share/doc/pacemaker-mgmt/README.hbagent usr/share/doc/pacemaker-mgmt/README.hbagentv2 usr/bin/crm_gui usr/bin/hb_gui usr/lib/heartbeat-gui/_pymgmt.so.0 usr/lib/heartbeat-gui/_pymgmt.so.0.0.0 usr/lib/heartbeat-gui/haclient.py usr/lib/heartbeat-gui/pymgmt.py usr/share/heartbeat-gui/active-node.png usr/share/heartbeat-gui/add-resource.png usr/share/heartbeat-gui/cleanup-resource.png usr/share/heartbeat-gui/default-resource.png usr/share/heartbeat-gui/down-resource.png usr/share/heartbeat-gui/exit.png usr/share/heartbeat-gui/ha.png usr/share/heartbeat-gui/haclient.py usr/share/heartbeat-gui/login.png usr/share/heartbeat-gui/logout.png usr/share/heartbeat-gui/master-resource.png usr/share/heartbeat-gui/mgmtcmd.py usr/share/heartbeat-gui/remove-resource.png usr/share/heartbeat-gui/slave-resource.png usr/share/heartbeat-gui/standby-node.png usr/share/heartbeat-gui/start-resource.png usr/share/heartbeat-gui/stop-resource.png usr/share/heartbeat-gui/up-resource.png usr/share/heartbeat-gui/manage-resource.png usr/share/heartbeat-gui/unmanage-resource.png usr/share/heartbeat-gui/dirty-stopped.png usr/share/heartbeat-gui/failed.png usr/share/heartbeat-gui/running.png usr/share/heartbeat-gui/stopped.png usr/share/heartbeat-gui/starting.png usr/share/heartbeat-gui/stopping.png usr/share/heartbeat-gui/nodes.png usr/share/heartbeat-gui/node.png usr/share/heartbeat-gui/administration.png usr/share/heartbeat-gui/record-pending.png usr/share/locale/zh_CN/LC_MESSAGES/haclient.mo usr/include/heartbeat/mgmt/mgmt_client.h usr/include/heartbeat/mgmt/mgmt_common.h usr/include/heartbeat/mgmt/mgmt.h usr/include/heartbeat/mgmt/mgmt_tls.h usr/include/heartbeat/mgmt_config.h usr/lib/libhbmgmt.so usr/lib/libhbmgmttls.so usr/lib/libhbmgmtcommon.so usr/lib/libhbmgmtclient.so usr/lib/heartbeat-gui/_pymgmt.so pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/pacemaker-mgmt.install000066400000000000000000000006161211477743100250140ustar00rootroot00000000000000etc/pam.d/hbmgmtd usr/lib/libhbmgmt.so.* usr/lib/libhbmgmtclient.so.* usr/lib/libhbmgmtcommon.so.* usr/lib/libhbmgmttls.so.* usr/lib/heartbeat/mgmtd usr/lib/heartbeat/mgmtdtest usr/lib/heartbeat/hbagent usr/lib/heartbeat/SNMPAgentSanityCheck usr/share/snmp/mibs/LINUX-HA-MIB.txt usr/share/doc/pacemaker-mgmt usr/share/doc/pacemaker-mgmt/README.hbagent usr/share/doc/pacemaker-mgmt/README.hbagentv2 pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/pycompat000066400000000000000000000000021211477743100222760ustar00rootroot000000000000002 pacemaker-mgmt-pacemaker-mgmt-2.1.2/debian/rules000077500000000000000000000062601211477743100216130ustar00rootroot00000000000000#!/usr/bin/make -f # Sample debian/rules that uses debhelper. # Copyright 1997 to 1999 by Joey Hess. # License: GNU General Public License (GPL) #Thanks to Paolo Molaro and heartbeat_0.4.6-2.diff # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 cfg:=--prefix=/usr --libdir=/usr/lib --sysconfdir=/etc --localstatedir=/var \ --enable-snmp-subagent --with-mibsdir=/usr/share/snmp/mibs \ --disable-fatal-warnings --enable-glib-malloc \ --mandir=/usr/share/man # These are used for cross-compiling and for saving the configure script # from having to guess our platform (since we know it already) DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) CFLAGS = -Wall -g ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) CFLAGS += -O0 else CFLAGS += -O2 endif ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) INSTALL_PROGRAM += -s endif DTMP:=`pwd`/debian/tmp RELEASE := $(shell dpkg-parsechangelog | awk '/^Version: / { print $$2 }') UPSTREAM := $(shell echo "$(RELEASE)" | sed 's/:\?\([0-9\.]\+\)-[0-9].*/\1/') patch: override_version=$(RELEASE) sh debian/apply unpatch: override_version=$(RELEASE) sh debian/apply $(UPSTREAM) build: checkbuild build-stamp build-stamp: dh_testdir # Allow debian packages to also be built directly from Hg archives # Official debian packages are built from dist tarballs test ! -e ./configure || ./configure $(cfg) test -e ./configure || ./bootstrap $(cfg) $(MAKE) touch build-stamp clean: dh_testdir dh_testroot # Add here commands to clean up after the build process. -$(MAKE) clean MAKE=make -$(MAKE) distclean MAKE=make rm -f tools/ccdv -find . -name '*.py[co]' | xargs rm -f dh_clean build-stamp install-stamp rm -f debian/init debian/*.debhelper debian/*.substvars config.log rm -r -f debian/pacemaker-mgmt debian/pacemaker-mgmt-client \ debian/pacemaker-mgmt-dev debian/tmp # Zero autoconf foo rm -f config.status libltdl/config.log libltdl/config.status install: build install-stamp install-stamp: dh_testdir dh_testroot dh_clean -k $(MAKE) install DESTDIR=$(DTMP) \ MAKE=make \ docdir=/usr/share/doc/pacemaker-mgmt dh_installdirs dh_install --source=$(DTMP) --list-missing #dh_movefiles --source=debian/tmp binary-indep: build install binary-arch: build install dh_testdir -a dh_testroot -a dh_installdebconf -a dh_installdocs -a dh_installexamples -a # dh_installmenu -a # dh_installemacsen -a # dh_installpam -a dh_installinit -a -n -u 'defaults 20 32' # dh_installcron -a dh_installman -a # dh_installinfo -a # dh_undocumented -a dh_installchangelogs dh_link -a dh_strip -a dh_compress -a dh_fixperms -a --exclude usr/bin/cl_status # dh_suidregister -a dh_makeshlibs -a -V dh_installdeb -a dh_perl -a dh_pycentral -a dh_shlibdeps -a dh_gencontrol -a dh_md5sums -a dh_builddeb -a binary: binary-indep binary-arch @echo "All unpackaged files follow:" -cd $(DTMP) && find . \! -type d | egrep -v \\\.l?a checkbuild: chmod u+x ./debian/dpkg-checkbuild ./debian/dpkg-checkbuild debian/control .PHONY: build clean binary binary-indep binary-arch install checkbuild \ patch unpatch pacemaker-mgmt-pacemaker-mgmt-2.1.2/doc/000077500000000000000000000000001211477743100200525ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/doc/AUTHORS000066400000000000000000000027331211477743100211270ustar00rootroot00000000000000The management components that used to be part of Heartbeat (but isn't supposed to anymore since Heartbeat doesn't include the CRM aka. Pacemaker) The original sources can be found at: http://hg.clusterlabs.org/pacemaker/pygui/ Upstream Authors: NOTE: The work of everyone on this project is dearly appreciated. If you are not listed here but should be, please notify us! Gao,Yan The following people have kindly helped with pacemaker-mgmt development by providing code, documentation or testing, or fixes: Andrew Beekhof Lars Marowsky-Brée Xinwei Hu The GUI was first developed in 2005 by: Huang Zhen The SNMP subagent was first developed in 2002 by: Zou Yixiong (yixiong.zou@intel.com) Keisuke MORI SNMP subagent v2 support Contributors, ordered by last name: Code for the following pieces borrowed from code by: All binaries provided by this package are GNU GPL or GNU LGPL. Some source files are under the BSD licence or in the public domain, as annotated by those files. All source files without a specific licence statement are available licenced under the GNU GPL. A copy of the GNU GPL licence is available on Debian systems at /usr/share/common-licenses/GPL A copy of the GNU LGPL licence is available on Debian systems at /usr/share/common-licenses/LGPL A copy of the BSD licence is available on Debian systems at /usr/share/common-licenses/BSD pacemaker-mgmt-pacemaker-mgmt-2.1.2/doc/COPYING000066400000000000000000000431051211477743100211100ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. pacemaker-mgmt-pacemaker-mgmt-2.1.2/doc/COPYING.LGPL000066400000000000000000000636441211477743100216570ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. ^L Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. ^L GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. ^L Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. ^L 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. ^L 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. ^L 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. ^L 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS ^L How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! pacemaker-mgmt-pacemaker-mgmt-2.1.2/doc/Makefile.am000066400000000000000000000016271211477743100221140ustar00rootroot00000000000000# # doc: Pacemaker-mgmt code # # Copyright (C) 2009 Gao,Yan # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in docdir = $(datadir)/doc/packages/@PACKAGE@ doc_DATA = AUTHORS COPYING COPYING.LGPL EXTRA_DIST = $(doc_DATA) pacemaker-mgmt-pacemaker-mgmt-2.1.2/include/000077500000000000000000000000001211477743100207305ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/include/Makefile.am000066400000000000000000000041031211477743100227620ustar00rootroot00000000000000# # linux-ha: Linux-HA heartbeat code # # Copyright (C) 2001 Michael Moerz # This instance created by Horms # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in ha_version.h config.h.in EXTRA_DIST = ha_version.h topdir=$(includedir)/heartbeat noinst_HEADERS = config.h pygui_internal.h ha_version.h portability.h top_HEADERS = mgmt_config.h SUBDIRS = mgmt ## The backtick commands are not executed here, ## but rather as macro-expansions at use within the rules. HG_LIVE_VERSION=`$(HG) -R "$(top_srcdir)" id` ARCHIVE_VERSION="$(top_srcdir)/.hg_archival.txt" HG_TAR_VERSION=`$(EGREP) node: "$(ARCHIVE_VERSION)"` ha_version.h: $(ARCHIVE_VERSION) if [ -r ha_version.h -a ! -w ha_version.h ]; then \ hgv=""; \ echo "Saved Version"; \ elif [ -f $(ARCHIVE_VERSION) ]; then \ hgv="$(HG_TAR_VERSION)"; \ echo "Hg Archived Version: $${hgv}"; \ elif [ -x $(HG) -a -d $(top_srcdir)/.hg ]; then \ hgv="$(HG_LIVE_VERSION)"; \ echo "Hg Live Version: $${hgv}"; \ elif [ -r ha_version.h ]; then \ hgv=""; \ echo "Hg Saved Live Version"; \ cat ha_version.h; \ else \ hgv="Unknown"; \ echo "Unknown Hg Version"; \ fi ; \ if [ X"$${hgv}" != "X" ]; then \ echo "/* $${hgv} */" > ha_version.h; \ echo "#define HA_HG_VERSION \"$${hgv}\"" >> ha_version.h; \ fi .PHONY: $(ARCHIVE_VERSION) pacemaker-mgmt-pacemaker-mgmt-2.1.2/include/mgmt/000077500000000000000000000000001211477743100216745ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/include/mgmt/.cvsignore000066400000000000000000000000251211477743100236710ustar00rootroot00000000000000Makefile Makefile.in pacemaker-mgmt-pacemaker-mgmt-2.1.2/include/mgmt/Makefile.am000066400000000000000000000017011211477743100237270ustar00rootroot00000000000000# # Author: Sun Jiang Dong # Copyright (c) 2004 International Business Machines # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in mgmtdir=$(includedir)/heartbeat/mgmt mgmt_HEADERS = \ mgmt_client.h \ mgmt_common.h \ mgmt.h \ mgmt_tls.h pacemaker-mgmt-pacemaker-mgmt-2.1.2/include/mgmt/mgmt.h000066400000000000000000000024461211477743100230170ustar00rootroot00000000000000/* * API of management library. * * Author: Huang Zhen * Copyright (C) 2005 International Business Machines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef __MGMT_H #define __MGMT_H 1 #include #define ENABLE_HB 1 #define ENABLE_LRM 2 #define ENABLE_CRM 4 #define CACHE_CIB 8 extern int init_mgmt_lib(const char* client_name, int enable_components); extern int final_mgmt_lib(void); typedef int (*event_handler)(const char* event); extern char* process_msg(const char* msg); extern int reg_event(const char* type, event_handler func); #endif /* __MGMT_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/include/mgmt/mgmt_client.h000066400000000000000000000064061211477743100243550ustar00rootroot00000000000000/* * Client-side Linux HA manager API. * * Author: Huang Zhen * Copyright (C) 2005 International Business Machines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef __MGMT_CLIENT_H #define __MGMT_CLIENT_H 1 #include /*************************USER GUIDE*****************************************/ /* * daemon = management daemon 1. using mgmt_connect() to connect to the server running the daemon after connect, we should send MSG_LOGIN to daemon first. 2. using mgmt_sendmsg() to send message to daemon, the result will be returned by the same function 3. if we register some event by MSG_REGEVT message, we need watch the fd returned by mgmt_inputfd(), when event comes, call mgmt_recvmsg() to get the event message. 4. call mgmt_disconnect() to disconnect from daemon 5. the format of the message: an ASCII string using "\n" as separator 6. the message sent to daemon: MSG_XXXXX\nPARAMETER1\nPARAMETER2\n....\nPARAMETERN 7. the result message after you send a message to daemon: ok\nPARAMETER1\nPARAMETER2\n....\nPARAMETERN or fail\nPARAMETER1\nPARAMETER2\n....\nPARAMETERN 8. the event message from daemon: EVT_XXXXX\nPARAMETER1\nPARAMETER2\n....\nPARAMETERN 9. mgmt_new_msg(),mgmt_msg_append(),mgmt_msg_args(),mgmt_del_msg() and mgmt_del_args() are used for manipulating the message string */ /* mgmt_connect: connect to server running of daemon. We need send MSG_LOGIN message for login after we connected. parameters: server: ip address of server, like "192.168.30.12" user and passwd: the authorized user/password on the server. return: 0: success -1: fail */ extern int mgmt_connect(const char* server, const char* user , const char* passwd, const char* port); /* mgmt_sendmsg: send message to daemon. parameters: msg: see the comment above return: the result from daemon for success, see the comment above NULL for fail */ extern char* mgmt_sendmsg(const char* msg); /* mgmt_recvmsg: receive message from daemon when client get an event, see the comment above parameters: return: the message recieved */ extern char* mgmt_recvmsg(void); /* mgmt_inputfd: return the socket for select, pull, or g_main_loop parameters: return: >0: success -1: fail */ extern int mgmt_inputfd(void); /* mgmt_disconnect: disconnect from server parameters: return: 0: success -1: fail */ extern int mgmt_disconnect(void); /*FIXME: We haven't apply the port 5560 yet*/ #define PORT 5560 extern int mgmt_session_sendmsg(void* session, const char* msg); extern char* mgmt_session_recvmsg(void* session); #endif /* __MGMT_CLIENT_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/include/mgmt/mgmt_common.h000066400000000000000000000333751211477743100243740ustar00rootroot00000000000000/* * Common library for Linux-HA management tool * * Author: Huang Zhen * Copyright (C) 2005 International Business Machines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef __MGMT_COMMON_H #define __MGMT_COMMON_H 1 /*************************PROTOCOL*******************************************/ /* description increased, if daemon-client communication changes in an incompatible way */ #define MGMT_PROTOCOL_VERSION "2.1" /*************************MESSAGES*******************************************/ #define MSG_OK "o" #define MSG_FAIL "f" #define CHR_OK 'o' #define CHR_FAIL 'f' /* description: login to daemon. the username/password must be one of the authorized account on the server running the daemon format: MSG_LOGIN username password protocolversion return: MSG_OK or MSG_FAIL */ #define MSG_LOGIN "login" /* description: logout from daemon format: MSG_LOGOUT return: MSG_OK or MSG_FAIL */ #define MSG_LOGOUT "logout" /* description: do nothing except return the string ANYSTRING. using for test the sanity of daemon. format: MSG_ECHO anystring return: MSG_OK anystring or MSG_FAIL */ #define MSG_ECHO "echo" /* description: register event EVENTTYPE. when the event invoked, the client would be notified. format: MSG_REGEVT EVENTTYPE return: MSG_OK or MSG_FAIL */ #define MSG_REGEVT "regevt" /* description: get the active CIB name format: MSG_ACTIVE_CIB return: MSG_OK <""|shadow_name> */ #define MSG_ACTIVE_CIB "active_cib" /* description: shutdown working CIB. format: MSG_SHUTDOWN_CIB return: MSG_OK or MSG_FAIL REASON */ #define MSG_SHUTDOWN_CIB "shutdown_cib" /* description: initiate working CIB. format: MSG_INIT_CIB <""|shadow_name> return: MSG_OK or MSG_FAIL REASON */ #define MSG_INIT_CIB "init_cib" /* description: change working CIB. format: MSG_SWITCH_CIB <""|shadow_name> return: MSG_OK or MSG_FAIL REASON */ #define MSG_SWITCH_CIB "switch_cib" /* description: get shadow CIB list format: MSG_GET_SHADOWS return: MSG_OK SHADOWNAME1 SHADOWNAME2 ... SHADOWNAMEn or MSG_FAIL REASON */ #define MSG_GET_SHADOWS "get_shadows" /* description: execute specified crm_shadow command format: MSG_CRM_SHADOW command <""|shadow_name> is_force return: MSG_OK or MSG_FAIL REASON */ #define MSG_CRM_SHADOW "crm_shadow" /* description: return the cluster type format: MSG_CLUSTER_TYPE return: MSG_OK cluster_type or MSG_FAIL */ #define MSG_CLUSTER_TYPE "cluster_type" /* description: return CIB version format: MSG_CIB_VERSION return: MSG_OK version or MSG_FAIL */ #define MSG_CIB_VERSION "cib_version" /* description: return the dtd of crm format: MSG_CRM_SCHEMA VALIDATE_TYPE FILE return: MSG_OK LINE1 LINE2 ... LINEn or MSG_FAIL */ #define MSG_CRM_SCHEMA "crm_schema" /* description: return the dtd of crm format: MSG_CRM_DTD return: MSG_OK LINE1 LINE2 ... LINEn or MSG_FAIL */ #define MSG_CRM_DTD "crm_dtd" /* description: return the metadata of crm format: MSG_CRM_METADATA CRM_CMD return: MSG_OK LINE1 LINE2 ... LINEn or MSG_FAIL */ #define MSG_CRM_METADATA "crm_metadata" /* description: get or set specified attribute format: MSG_CRM_ATTRIBUTE type attribute return: MSG_OK [value] or MSG_FAIL reason */ #define MSG_CRM_ATTRIBUTE "crm_attribute" /* description: return heartbeat configuration format: MSG_HB_CONFIG return: MSG_OK name1 value1 name2 value2 ... namen valuen MSG_FAIL */ #define MSG_HB_CONFIG "hb_config" #define F_MGMT_APIAUTH 1 #define F_MGMT_AUTO_FAILBACK 2 #define F_MGMT_BAUD 3 #define F_MGMT_DEBUG 4 #define F_MGMT_DEBUGFILE 5 #define F_MGMT_DEADPING 6 #define F_MGMT_DEADTIME 7 #define F_MGMT_HBVERSION 8 #define F_MGMT_HOPFUDGE 9 #define F_MGMT_INITDEAD 10 #define F_MGMT_KEEPALIVE 11 #define F_MGMT_LOGFACILITY 12 #define F_MGMT_LOGFILE 13 #define F_MGMT_MSGFMT 14 #define F_MGMT_NICE_FAILBACK 15 #define F_MGMT_NODE 16 #define F_MGMT_NORMALPOLL 17 #define F_MGMT_STONITH 18 #define F_MGMT_UDPPORT 19 #define F_MGMT_WARNTIME 20 #define F_MGMT_WATCHDOG 21 #define F_MGMT_CLUSTER 22 /* description: return the name of all nodes configured in cluster format: MSG_ALLNODES return: MSG_OK node1 node2 ... noden or MSG_FAIL */ #define MSG_ALLNODES "all_nodes" /* description: return node's type format: MSG_NODE_TYPE NODENAME return: MSG_OK node_type("normal|ping|unknown") or MSG_FAIL */ #define MSG_NODE_TYPE "node_type" /* description: return active nodes configured in cluster format: MSG_ACTIVENODES return: MSG_OK node1 node2 ... noden or MSG_FAIL */ #define MSG_ACTIVENODES "active_nodes" /* description: return nodes configured in crm format: MSG_CRMNODES return: MSG_OK node1 node2 ... noden or MSG_FAIL */ #define MSG_CRMNODES "crm_nodes" /* description: return DC in cluster format: MSG_DC return: MSG_OK dc_node or MSG_FAIL */ #define MSG_DC "dc" /* description: return node's configured format: MSG_NODE_CONFIG NODENAME return: MSG_OK uname online(True|False) standby(True|False) unclean(True|False) shutdown(True|False) expected_up(True|False) is_dc(True|False) node_ping("ping|member") or MSG_FAIL */ #define MSG_NODE_CONFIG "node_config" #define F_MGMT_UNAME 1 #define F_MGMT_ONLINE 2 #define F_MGMT_STANDBY 3 #define F_MGMT_UNCLEAN 4 #define F_MGMT_SHUTDOWN 5 #define F_MGMT_EXPECTED_UP 6 #define F_MGMT_IS_DC 7 #define F_MGMT_NODE_PING 8 #define F_MGMT_NODE_PENDING 9 #define F_MGMT_NODE_STRANDBY_ONFAIL 10 /* description: migrate a resource format: MSG_MIGRATE rsc_id to_node force duration return: MSG_OK or MSG_FAIL reason */ #define MSG_MIGRATE "migrate" /* description: set standby on a node format: MSG_STANDBY node on|off return: MSG_OK or MSG_FAIL reason */ #define MSG_STANDBY "standby" /* new CRUD protocol */ /* description: accomplish the cib commands format: MSG_CIB_XXXXXX LINE return: MSG_OK LINE1 LINE2 ... LINEn or MSG_FAIL */ #define MSG_CIB_CREATE "cib_create" #define MSG_CIB_QUERY "cib_query" #define MSG_CIB_UPDATE "cib_update" #define MSG_CIB_REPLACE "cib_replace" #define MSG_CIB_DELETE "cib_delete" /* description: return names of all running resources on a given node format: MSG_RUNNING_RSC node return: MSG_OK resource1 resource2 ... resourcen or MSG_FAIL */ #define MSG_RUNNING_RSC "running_rsc" /* description: return all resources in the cluster format: MSG_ALL_RSC return: MSG_OK resource1 resource2 ... resourcen or MSG_FAIL */ #define MSG_ALL_RSC "all_rsc" /* description: return the type of a given resource format: MSG_RSC_TYPE resource return: MSG_OK type(unknown|native|group|clone|master) or MSG_FAIL */ #define MSG_RSC_TYPE "rsc_type" /* description: return the sub-resources of a given resource format: MSG_SUB_RSC resource return: MSG_OK sub-resource1 sub-resource2 ... sub-resourcen or MSG_FAIL */ #define MSG_SUB_RSC "sub_rsc" /* description: return the node on which the given resource is running on format: MSG_RSC_RUNNING_ON resource return: MSG_OK node or MSG_FAIL */ #define MSG_RSC_RUNNING_ON "rsc_running_on" /* description: return the status of a given resource format: MSG_RSC_STATUS resource return: MSG_OK status(unknown|unmanaged|failed|multi-running|running|group |clone|master) or MSG_FAIL */ #define MSG_RSC_STATUS "rsc_status" /* description: return the translated string of a operation status format: MSG_OP_STATUS2STR STATUS return: MSG_OK STRING */ #define MSG_OP_STATUS2STR "op_status2str" /* description: clean up a unmanaged resource format: MSG_CLEANUP_RSC node resource return: MSG_OK or MSG_FAIL */ #define MSG_CLEANUP_RSC "cleanup_rsc" /* description: execute specified crm_resource command format: MSG_CRM_RSC_CMD command return: MSG_OK or MSG_FAIL [reason] */ #define MSG_CRM_RSC_CMD "crm_rsc_cmd" /* description: set the named attribute for a given resource format: MSG_SET_RSC_ATTR rsc_id name value return: MSG_OK or MSG_FAIL */ #define MSG_SET_RSC_ATTR "set_rsc_attr" /* description: get the named attribute for a given resource format: MSG_GET_RSC_ATTR rsc_id name return: MSG_OK value or MSG_FAIL */ #define MSG_GET_RSC_ATTR "get_rsc_attr" /* description: delete the named attribute for a given resource format: MSG_DEL_RSC_ATTR rsc_id name return: MSG_OK or MSG_FAIL */ #define MSG_DEL_RSC_ATTR "del_rsc_attr" /* description: return all resource classes of resource agents format: MSG_RSC_CLASSES return: MSG_OK class1 class2 ... classn or MSG_FAIL */ #define MSG_RSC_CLASSES "rsc_classes" /* description: return all resource type of a given class format: MSG_RSC_TYPE class return: MSG_OK type1 type2 ... typen or MSG_FAIL */ #define MSG_RSC_TYPES "rsc_types" /* description: return all provider of a given class and type format: MSG_RSC_TYPE class type return: MSG_OK provider1 provider2 ... providern or MSG_FAIL */ #define MSG_RSC_PROVIDERS "rsc_providers" /* description: return the metadata of a given resource type format: MSG_RSC_METADATA RSC class type provider return: MSG_OK LINE1 LINE2 ... LINEn or MSG_FAIL */ #define MSG_RSC_METADATA "rsc_metadata" /* description: return the translated string of a lrm_rsc_op return code format: MSG_LRM_OP_RC2STR RC return: MSG_OK STRING */ #define MSG_LRM_OP_RC2STR "lrm_op_rc2str" /* description: generate cluster report and return the list of files format: MSG_GEN_CLUSTER_REPORT ftime ttime return: MSG_OK filename base64_str1 base64_str2 ... base64_strn or MSG_FAIL */ #define MSG_GEN_CLUSTER_REPORT "gen_cluster_report" /* description: get transition list format: MSG_GET_PE_INPUTS FTIME TTIME return: MSG_OK FILENAME1 TIME1 FILENAME2 TIME2 ... FILENAMEn TIMEn or MSG_FAIL REASON */ #define MSG_GET_PE_INPUTS "get_pe_inputs" /* description: get transition summary format: MSG_GET_PE_SUMMARY <""|SEQUENCE> return: MSG_OK TIME_STAMP or MSG_FAIL REASON */ #define MSG_GET_PE_SUMMARY "get_pe_summary" /* description: generate specified transition graph format: MSG_GEN_PE_GRAPH return: MSG_OK LINE1 LINE2 ... LINEn or MSG_FAIL REASON */ #define MSG_GEN_PE_GRAPH "gen_pe_graph" /* description: generate transition information format: MSG_GEN_PE_INFO return: MSG_OK LINE1 LINE2 ... LINEn or MSG_FAIL REASON */ #define MSG_GEN_PE_INFO "gen_pe_info" /*************************EVENTS*********************************************/ /* description: when the cib changed, client which registered this event will be notified with this event message format: EVT_CIB_CHANGED */ #define EVT_CIB_CHANGED "evt:cib_changed" /* description: when the management daemon losts connection with heartbeat, client which registered this event will be notified with this event message format: EVT_DISCONNECTED */ #define EVT_DISCONNECTED "evt:disconnected" #define EVT_TEST "evt:test" /*************************FUNTIONS*******************************************/ /* mgmt_set_mem_funcs: set user own memory functions, like malloc/realloc/free for linux-ha 2 parameters: the three memory functions return: none */ typedef void* (*malloc_t)(size_t size); typedef void* (*realloc_t)(void* oldval, size_t newsize); typedef void (*free_t)(void *ptr); extern void mgmt_set_mem_funcs(malloc_t m, realloc_t r, free_t f); extern void* mgmt_malloc(size_t size); extern void* mgmt_realloc(void* oldval, size_t newsize); extern void mgmt_free(void *ptr); /* mgmt_new_msg: create a new message parameters: type: should be the micro of MSG_XXX listed above ... : the parameters listed above return: a string as result, the format is described above */ extern char* mgmt_new_msg(const char* type, ...); /* mgmt_msg_append: append a new parameter to an existing message the memory of the msg will be realloced. parameters: msg: the original message append: the parameter to be appended return: the new message example: msg = mgmt_msg_append(msg, "new_param"); */ extern char* mgmt_msg_append(char* msg, const char* append); /* mgmt_del_msg: free a message parameters: msg: the message to be free return: */ extern void mgmt_del_msg(char* msg); /* mgmt_result_ok: return whether the result is ok parameters: msg: the message for determining return: 1: the result message is ok 0: the result message is fail */ extern int mgmt_result_ok(char* msg); /* mgmt_msg_args: parse the message to string arry parameters: msg: the message to be parsed num: return the number of parameters (include type of message if the message has one) return: the string arry, we should use mgmt_del_args() to free it example: int i,num; char** args = mgmt_msg_args(msg, &num); for(i=0; i * Copyright (C) 2005 International Business Machines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef __MGMT_TLS_H #define __MGMT_TLS_H 1 extern int tls_init_client(void); extern void* tls_attach_client(int sock); extern int tls_close_client(void); extern int tls_init_server(void); extern void* tls_attach_server(int sock); extern int tls_close_server(void); extern ssize_t tls_send(void* s, const void *buf, size_t len); extern ssize_t tls_recv(void* s, void* buf, size_t len); extern int tls_detach(void* s); #endif /* __MGMT_TLS_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/include/mgmt_config.h.in000066400000000000000000000000001211477743100237650ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/include/portability.h000066400000000000000000000061251211477743100234470ustar00rootroot00000000000000#ifndef PORTABILITY_H # define PORTABILITY_H /* * Copyright (C) 2001 Alan Robertson * This software licensed under the GNU LGPL. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #define EOS '\0' #define DIMOF(a) ((int) (sizeof(a)/sizeof(a[0])) ) #define STRLEN_CONST(conststr) ((size_t)((sizeof(conststr)/sizeof(char))-1)) #define STRNCMP_CONST(varstr, conststr) strncmp((varstr), conststr, STRLEN_CONST(conststr)+1) #define STRLEN(c) STRLEN_CONST(c) /* Needs to be defined before any other includes, otherwise some system * headers do not behave as expected! Major black magic... */ #undef _GNU_SOURCE /* in case it was defined on the command line */ #define _GNU_SOURCE /* Please leave this as the first #include - Solaris needs it there */ #ifdef HAVE_CONFIG_H #include #endif #include #ifdef BSD # define SCANSEL_CAST (void *) #else # define SCANSEL_CAST /* Nothing */ #endif #if defined(ANSI_ONLY) && !defined(inline) # define inline /* nothing */ # undef NETSNMP_ENABLE_INLINE # define NETSNMP_NO_INLINE 1 #endif #ifndef HAVE_DAEMON /* We supply a replacement function, but need a prototype */ int daemon(int nochdir, int noclose); #endif /* HAVE_DAEMON */ #ifndef HAVE_SETENV /* We supply a replacement function, but need a prototype */ int setenv(const char *name, const char * value, int why); #endif /* HAVE_SETENV */ #ifndef HAVE_STRERROR /* We supply a replacement function, but need a prototype */ char * strerror(int errnum); #endif /* HAVE_STRERROR */ #ifndef HAVE_ALPHASORT # include int alphasort(const void *dirent1, const void *dirent2); #endif /* HAVE_ALPHASORT */ #ifndef HAVE_INET_PTON /* We supply a replacement function, but need a prototype */ int inet_pton(int af, const char *src, void *dst); #endif /* HAVE_INET_PTON */ #ifndef HAVE_STRNLEN size_t strnlen(const char *s, size_t maxlen); #else # define USE_GNU #endif #ifndef HAVE_STRNDUP char *strndup(const char *str, size_t len); #else # define USE_GNU #endif #ifdef HAVE_STRUCT_UCRED_DARWIN # include # ifndef SYS_NMLN # define SYS_NMLN _SYS_NAMELEN # endif /* SYS_NMLN */ #endif #define POINTER_TO_SIZE_T(p) ((size_t)(p)) /*pointer cast as size_t*/ #define POINTER_TO_SSIZE_T(p) ((ssize_t)(p)) /*pointer cast as ssize_t*/ #define POINTER_TO_ULONG(p) ((unsigned long)(p)) /*pointer cast as unsigned long*/ #define HAURL(url) HA_URLBASE url #endif /* PORTABILITY_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/include/pygui_internal.h000066400000000000000000000002311211477743100241260ustar00rootroot00000000000000#if HAVE_HB_CONFIG_H #include #endif #if HAVE_GLUE_CONFIG_H #include #endif #include #include pacemaker-mgmt-pacemaker-mgmt-2.1.2/intltool-extract.in000066400000000000000000000546651211477743100231710ustar00rootroot00000000000000#!@INTLTOOL_PERL@ -w # -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*- # # The Intltool Message Extractor # # Copyright (C) 2000-2001, 2003 Free Software Foundation. # # Intltool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # Intltool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # # Authors: Kenneth Christiansen # Darin Adler # ## Release information my $PROGRAM = "intltool-extract"; my $PACKAGE = "intltool"; my $VERSION = "0.35.2"; ## Loaded modules use strict; use File::Basename; use Getopt::Long; ## Scalars used by the option stuff my $TYPE_ARG = "0"; my $LOCAL_ARG = "0"; my $HELP_ARG = "0"; my $VERSION_ARG = "0"; my $UPDATE_ARG = "0"; my $QUIET_ARG = "0"; my $SRCDIR_ARG = "."; my $FILE; my $OUTFILE; my $gettext_type = ""; my $input; my %messages = (); my %loc = (); my %count = (); my %comments = (); my $strcount = 0; my $XMLCOMMENT = ""; ## Use this instead of \w for XML files to handle more possible characters. my $w = "[-A-Za-z0-9._:]"; ## Always print first $| = 1; ## Handle options GetOptions ( "type=s" => \$TYPE_ARG, "local|l" => \$LOCAL_ARG, "help|h" => \$HELP_ARG, "version|v" => \$VERSION_ARG, "update" => \$UPDATE_ARG, "quiet|q" => \$QUIET_ARG, "srcdir=s" => \$SRCDIR_ARG, ) or &error; &split_on_argument; ## Check for options. ## This section will check for the different options. sub split_on_argument { if ($VERSION_ARG) { &version; } elsif ($HELP_ARG) { &help; } elsif ($LOCAL_ARG) { &place_local; &extract; } elsif ($UPDATE_ARG) { &place_normal; &extract; } elsif (@ARGV > 0) { &place_normal; &message; &extract; } else { &help; } } sub place_normal { $FILE = $ARGV[0]; $OUTFILE = "$FILE.h"; my $dirname = dirname ($OUTFILE); if (! -d "$dirname" && $dirname ne "") { system ("mkdir -p $dirname"); } } sub place_local { $FILE = $ARGV[0]; $OUTFILE = fileparse($FILE, ()); if (!-e "tmp/") { system("mkdir tmp/"); } $OUTFILE = "./tmp/$OUTFILE.h" } sub determine_type { if ($TYPE_ARG =~ /^gettext\/(.*)/) { $gettext_type=$1 } } ## Sub for printing release information sub version{ print <<_EOF_; ${PROGRAM} (${PACKAGE}) $VERSION Copyright (C) 2000, 2003 Free Software Foundation, Inc. Written by Kenneth Christiansen, 2000. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. _EOF_ exit; } ## Sub for printing usage information sub help { print <<_EOF_; Usage: ${PROGRAM} [OPTION]... [FILENAME] Generates a header file from an XML source file. It grabs all strings between <_translatable_node> and its end tag in XML files. Read manpage (man ${PROGRAM}) for more info. --type=TYPE Specify the file type of FILENAME. Currently supports: "gettext/glade", "gettext/ini", "gettext/keys" "gettext/rfc822deb", "gettext/schemas", "gettext/scheme", "gettext/xml", "gettext/quoted" -l, --local Writes output into current working directory (conflicts with --update) --update Writes output into the same directory the source file reside (conflicts with --local) --srcdir Root of the source tree -v, --version Output version information and exit -h, --help Display this help and exit -q, --quiet Quiet mode Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE") or send email to . _EOF_ exit; } ## Sub for printing error messages sub error{ print STDERR "Try `${PROGRAM} --help' for more information.\n"; exit; } sub message { print "Generating C format header file for translation.\n" unless $QUIET_ARG; } sub extract { &determine_type; &convert; open OUT, ">$OUTFILE"; binmode (OUT) if $^O eq 'MSWin32'; &msg_write; close OUT; print "Wrote $OUTFILE\n" unless $QUIET_ARG; } sub convert { ## Reading the file { local (*IN); local $/; #slurp mode open (IN, "<$SRCDIR_ARG/$FILE") || die "can't open $SRCDIR_ARG/$FILE: $!"; $input = ; } &type_ini if $gettext_type eq "ini"; &type_keys if $gettext_type eq "keys"; &type_xml if $gettext_type eq "xml"; &type_glade if $gettext_type eq "glade"; &type_scheme if $gettext_type eq "scheme"; &type_schemas if $gettext_type eq "schemas"; &type_rfc822deb if $gettext_type eq "rfc822deb"; &type_quoted if $gettext_type eq "quoted"; } sub entity_decode_minimal { local ($_) = @_; s/'/'/g; # ' s/"/"/g; # " s/&/&/g; return $_; } sub entity_decode { local ($_) = @_; s/'/'/g; # ' s/"/"/g; # " s/&/&/g; s/<//g; return $_; } sub escape_char { return '\"' if $_ eq '"'; return '\n' if $_ eq "\n"; return '\\\\' if $_ eq '\\'; return $_; } sub escape { my ($string) = @_; return join "", map &escape_char, split //, $string; } sub type_ini { ### For generic translatable desktop files ### while ($input =~ /^_.*=(.*)$/mg) { $messages{$1} = []; } } sub type_keys { ### For generic translatable mime/keys files ### while ($input =~ /^\s*_\w+=(.*)$/mg) { $messages{$1} = []; } } sub type_xml { ### For generic translatable XML files ### my $tree = readXml($input); parseTree(0, $tree); } sub print_var { my $var = shift; my $vartype = ref $var; if ($vartype =~ /ARRAY/) { my @arr = @{$var}; print "[ "; foreach my $el (@arr) { print_var($el); print ", "; } print "] "; } elsif ($vartype =~ /HASH/) { my %hash = %{$var}; print "{ "; foreach my $key (keys %hash) { print "$key => "; print_var($hash{$key}); print ", "; } print "} "; } else { print $var; } } # Same syntax as getAttributeString in intltool-merge.in.in, similar logic (look for ## differences comment) sub getAttributeString { my $sub = shift; my $do_translate = shift || 1; my $language = shift || ""; my $translate = shift; my $result = ""; foreach my $e (reverse(sort(keys %{ $sub }))) { my $key = $e; my $string = $sub->{$e}; my $quote = '"'; $string =~ s/^[\s]+//; $string =~ s/[\s]+$//; if ($string =~ /^'.*'$/) { $quote = "'"; } $string =~ s/^['"]//g; $string =~ s/['"]$//g; ## differences from intltool-merge.in.in if ($key =~ /^_/) { $comments{entity_decode($string)} = $XMLCOMMENT if $XMLCOMMENT; $messages{entity_decode($string)} = []; $$translate = 2; } ## differences end here from intltool-merge.in.in $result .= " $key=$quote$string$quote"; } return $result; } # Verbatim copy from intltool-merge.in.in sub getXMLstring { my $ref = shift; my $spacepreserve = shift || 0; my @list = @{ $ref }; my $result = ""; my $count = scalar(@list); my $attrs = $list[0]; my $index = 1; $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/)); $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/)); while ($index < $count) { my $type = $list[$index]; my $content = $list[$index+1]; if (! $type ) { # We've got CDATA if ($content) { # lets strip the whitespace here, and *ONLY* here $content =~ s/\s+/ /gs if (!$spacepreserve); $result .= $content; } } elsif ( "$type" ne "1" ) { # We've got another element $result .= "<$type"; $result .= getAttributeString(@{$content}[0], 0); # no nested translatable elements if ($content) { my $subresult = getXMLstring($content, $spacepreserve); if ($subresult) { $result .= ">".$subresult . ""; } else { $result .= "/>"; } } else { $result .= "/>"; } } $index += 2; } return $result; } # Verbatim copy from intltool-merge.in.in, except for MULTIPLE_OUTPUT handling removed # Translate list of nodes if necessary sub translate_subnodes { my $fh = shift; my $content = shift; my $language = shift || ""; my $singlelang = shift || 0; my $spacepreserve = shift || 0; my @nodes = @{ $content }; my $count = scalar(@nodes); my $index = 0; while ($index < $count) { my $type = $nodes[$index]; my $rest = $nodes[$index+1]; traverse($fh, $type, $rest, $language, $spacepreserve); $index += 2; } } # Based on traverse() in intltool-merge.in.in sub traverse { my $fh = shift; # unused, to allow us to sync code between -merge and -extract my $nodename = shift; my $content = shift; my $language = shift || ""; my $spacepreserve = shift || 0; if ($nodename && "$nodename" eq "1") { $XMLCOMMENT = $content; } elsif ($nodename) { # element my @all = @{ $content }; my $attrs = shift @all; my $translate = 0; my $outattr = getAttributeString($attrs, 1, $language, \$translate); if ($nodename =~ /^_/) { $translate = 1; $nodename =~ s/^_//; } my $lookup = ''; $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/)); $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/)); if ($translate) { $lookup = getXMLstring($content, $spacepreserve); if (!$spacepreserve) { $lookup =~ s/^\s+//s; $lookup =~ s/\s+$//s; } if ($lookup && $translate != 2) { $comments{$lookup} = $XMLCOMMENT if $XMLCOMMENT; $messages{$lookup} = []; } elsif ($translate == 2) { translate_subnodes($fh, \@all, $language, 1, $spacepreserve); } } else { $XMLCOMMENT = ""; my $count = scalar(@all); if ($count > 0) { my $index = 0; while ($index < $count) { my $type = $all[$index]; my $rest = $all[$index+1]; traverse($fh, $type, $rest, $language, $spacepreserve); $index += 2; } } } $XMLCOMMENT = ""; } } # Verbatim copy from intltool-merge.in.in, $fh for compatibility sub parseTree { my $fh = shift; my $ref = shift; my $language = shift || ""; my $name = shift @{ $ref }; my $cont = shift @{ $ref }; while (!$name || "$name" eq "1") { $name = shift @{ $ref }; $cont = shift @{ $ref }; } my $spacepreserve = 0; my $attrs = @{$cont}[0]; $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/)); traverse($fh, $name, $cont, $language, $spacepreserve); } # Verbatim copy from intltool-merge.in.in sub intltool_tree_comment { my $expat = shift; my $data = $expat->original_string(); my $clist = $expat->{Curlist}; my $pos = $#$clist; $data =~ s/^$//s; push @$clist, 1 => $data; } # Verbatim copy from intltool-merge.in.in sub intltool_tree_cdatastart { my $expat = shift; my $clist = $expat->{Curlist}; my $pos = $#$clist; push @$clist, 0 => $expat->original_string(); } # Verbatim copy from intltool-merge.in.in sub intltool_tree_cdataend { my $expat = shift; my $clist = $expat->{Curlist}; my $pos = $#$clist; $clist->[$pos] .= $expat->original_string(); } # Verbatim copy from intltool-merge.in.in sub intltool_tree_char { my $expat = shift; my $text = shift; my $clist = $expat->{Curlist}; my $pos = $#$clist; # Use original_string so that we retain escaped entities # in CDATA sections. # if ($pos > 0 and $clist->[$pos - 1] eq '0') { $clist->[$pos] .= $expat->original_string(); } else { push @$clist, 0 => $expat->original_string(); } } # Verbatim copy from intltool-merge.in.in sub intltool_tree_start { my $expat = shift; my $tag = shift; my @origlist = (); # Use original_string so that we retain escaped entities # in attribute values. We must convert the string to an # @origlist array to conform to the structure of the Tree # Style. # my @original_array = split /\x/, $expat->original_string(); my $source = $expat->original_string(); # Remove leading tag. # $source =~ s|^\s*<\s*(\S+)||s; # Grab attribute key/value pairs and push onto @origlist array. # while ($source) { if ($source =~ /^\s*([\w:-]+)\s*[=]\s*["]/) { $source =~ s|^\s*([\w:-]+)\s*[=]\s*["]([^"]*)["]||s; push @origlist, $1; push @origlist, '"' . $2 . '"'; } elsif ($source =~ /^\s*([\w:-]+)\s*[=]\s*[']/) { $source =~ s|^\s*([\w:-]+)\s*[=]\s*[']([^']*)[']||s; push @origlist, $1; push @origlist, "'" . $2 . "'"; } else { last; } } my $ol = [ { @origlist } ]; push @{ $expat->{Lists} }, $expat->{Curlist}; push @{ $expat->{Curlist} }, $tag => $ol; $expat->{Curlist} = $ol; } # Copied from intltool-merge.in.in and added comment handler. sub readXml { my $xmldoc = shift || return; my $ret = eval 'require XML::Parser'; if(!$ret) { die "You must have XML::Parser installed to run $0\n\n"; } my $xp = new XML::Parser(Style => 'Tree'); $xp->setHandlers(Char => \&intltool_tree_char); $xp->setHandlers(Start => \&intltool_tree_start); $xp->setHandlers(CdataStart => \&intltool_tree_cdatastart); $xp->setHandlers(CdataEnd => \&intltool_tree_cdataend); ## differences from intltool-merge.in.in $xp->setHandlers(Comment => \&intltool_tree_comment); ## differences end here from intltool-merge.in.in my $tree = $xp->parse($xmldoc); #print_var($tree); # Hello thereHowdydo # would be: # [foo, [{}, 1, "comment", head, [{id => "a"}, 0, "Hello ", em, [{}, 0, "there"]], bar, # [{}, 0, "Howdy", ref, [{}]], 0, "do" ] ] return $tree; } sub type_schemas { ### For schemas XML files ### # FIXME: We should handle escaped < (less than) while ($input =~ / \s* (\s*(?:\s*)?(.*?)\s*<\/default>\s*)? (\s*(?:\s*)?(.*?)\s*<\/short>\s*)? (\s*(?:\s*)?(.*?)\s*<\/long>\s*)? <\/locale> /sgx) { my @totranslate = ($3,$6,$9); my @eachcomment = ($2,$5,$8); foreach (@totranslate) { my $currentcomment = shift @eachcomment; next if !$_; s/\s+/ /g; $messages{entity_decode_minimal($_)} = []; $comments{entity_decode_minimal($_)} = $currentcomment if (defined($currentcomment)); } } } sub type_rfc822deb { ### For rfc822-style Debian configuration files ### my $lineno = 1; my $type = ''; while ($input =~ /\G(.*?)(^|\n)(_+)([^:]+):[ \t]*(.*?)(?=\n\S|$)/sg) { my ($pre, $newline, $underscore, $tag, $text) = ($1, $2, $3, $4, $5); while ($pre =~ m/\n/g) { $lineno ++; } $lineno += length($newline); my @str_list = rfc822deb_split(length($underscore), $text); for my $str (@str_list) { $strcount++; $messages{$str} = []; $loc{$str} = $lineno; $count{$str} = $strcount; my $usercomment = ''; while($pre =~ s/(^|\n)#([^\n]*)$//s) { $usercomment = "\n" . $2 . $usercomment; } $comments{$str} = $tag . $usercomment; } $lineno += ($text =~ s/\n//g); } } sub rfc822deb_split { # Debian defines a special way to deal with rfc822-style files: # when a value contain newlines, it consists of # 1. a short form (first line) # 2. a long description, all lines begin with a space, # and paragraphs are separated by a single dot on a line # This routine returns an array of all paragraphs, and reformat # them. # When first argument is 2, the string is a comma separated list of # values. my $type = shift; my $text = shift; $text =~ s/^[ \t]//mg; return (split(/, */, $text, 0)) if $type ne 1; return ($text) if $text !~ /\n/; $text =~ s/([^\n]*)\n//; my @list = ($1); my $str = ''; for my $line (split (/\n/, $text)) { chomp $line; if ($line =~ /^\.\s*$/) { # New paragraph $str =~ s/\s*$//; push(@list, $str); $str = ''; } elsif ($line =~ /^\s/) { # Line which must not be reformatted $str .= "\n" if length ($str) && $str !~ /\n$/; $line =~ s/\s+$//; $str .= $line."\n"; } else { # Continuation line, remove newline $str .= " " if length ($str) && $str !~ /\n$/; $str .= $line; } } $str =~ s/\s*$//; push(@list, $str) if length ($str); return @list; } sub type_quoted { while ($input =~ /\"(([^\"]|\\\")*[^\\\"])\"/g) { my $message = $1; my $before = $`; $message =~ s/\\\"/\"/g; $before =~ s/[^\n]//g; $messages{$message} = []; $loc{$message} = length ($before) + 2; } } sub type_glade { ### For translatable Glade XML files ### my $tags = "label|title|text|format|copyright|comments|preview_text|tooltip|message"; while ($input =~ /<($tags)>([^<]+)<\/($tags)>/sg) { # Glade sometimes uses tags that normally mark translatable things for # little bits of non-translatable content. We work around this by not # translating strings that only includes something like label4 or window1. $messages{entity_decode($2)} = [] unless $2 =~ /^(window|label|dialog)[0-9]+$/; } while ($input =~ /(..[^<]*)<\/items>/sg) { for my $item (split (/\n/, $1)) { $messages{entity_decode($item)} = []; } } ## handle new glade files while ($input =~ /<(property|atkproperty)\s+[^>]*translatable\s*=\s*"yes"(?:\s+[^>]*comments\s*=\s*"([^"]*)")?[^>]*>([^<]+)<\/\1>/sg) { $messages{entity_decode($3)} = [] unless $3 =~ /^(window|label)[0-9]+$/; if (defined($2) and !($3 =~ /^(window|label)[0-9]+$/)) { $comments{entity_decode($3)} = entity_decode($2) ; } } while ($input =~ /]*)"\s+description="([^>]+)"\/>/sg) { $messages{entity_decode_minimal($2)} = []; } } sub type_scheme { my ($line, $i, $state, $str, $trcomment, $char); for $line (split(/\n/, $input)) { $i = 0; $state = 0; # 0 - nothing, 1 - string, 2 - translatable string while ($i < length($line)) { if (substr($line,$i,1) eq "\"") { if ($state == 2) { $comments{$str} = $trcomment if ($trcomment); $messages{$str} = []; $str = ''; $state = 0; $trcomment = ""; } elsif ($state == 1) { $str = ''; $state = 0; $trcomment = ""; } else { $state = 1; $str = ''; if ($i>0 && substr($line,$i-1,1) eq '_') { $state = 2; } } } elsif (!$state) { if (substr($line,$i,1) eq ";") { $trcomment = substr($line,$i+1); $trcomment =~ s/^;*\s*//; $i = length($line); } elsif ($trcomment && substr($line,$i,1) !~ /\s|\(|\)|_/) { $trcomment = ""; } } else { if (substr($line,$i,1) eq "\\") { $char = substr($line,$i+1,1); if ($char ne "\"" && $char ne "\\") { $str = $str . "\\"; } $i++; } $str = $str . substr($line,$i,1); } $i++; } } } sub msg_write { my @msgids; if (%count) { @msgids = sort { $count{$a} <=> $count{$b} } keys %count; } else { @msgids = sort keys %messages; } for my $message (@msgids) { my $offsetlines = 1; $offsetlines++ if $message =~ /%/; if (defined ($comments{$message})) { while ($comments{$message} =~ m/\n/g) { $offsetlines++; } } print OUT "# ".($loc{$message} - $offsetlines). " \"$FILE\"\n" if defined $loc{$message}; print OUT "/* ".$comments{$message}." */\n" if defined $comments{$message}; print OUT "/* xgettext:no-c-format */\n" if $message =~ /%/; my @lines = split (/\n/, $message, -1); for (my $n = 0; $n < @lines; $n++) { if ($n == 0) { print OUT "char *s = N_(\""; } else { print OUT " \""; } print OUT escape($lines[$n]); if ($n < @lines - 1) { print OUT "\\n\"\n"; } else { print OUT "\");\n"; } } } } pacemaker-mgmt-pacemaker-mgmt-2.1.2/intltool-merge.in000066400000000000000000001071111211477743100225770ustar00rootroot00000000000000#!@INTLTOOL_PERL@ -w # -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*- # # The Intltool Message Merger # # Copyright (C) 2000, 2003 Free Software Foundation. # Copyright (C) 2000, 2001 Eazel, Inc # # Intltool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # version 2 published by the Free Software Foundation. # # Intltool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # # Authors: Maciej Stachowiak # Kenneth Christiansen # Darin Adler # # Proper XML UTF-8'ification written by Cyrille Chepelov # ## Release information my $PROGRAM = "intltool-merge"; my $PACKAGE = "intltool"; my $VERSION = "0.35.2"; ## Loaded modules use strict; use Getopt::Long; use Text::Wrap; use File::Basename; my $must_end_tag = -1; my $last_depth = -1; my $translation_depth = -1; my @tag_stack = (); my @entered_tag = (); my @translation_strings = (); my $leading_space = ""; ## Scalars used by the option stuff my $HELP_ARG = 0; my $VERSION_ARG = 0; my $BA_STYLE_ARG = 0; my $XML_STYLE_ARG = 0; my $KEYS_STYLE_ARG = 0; my $DESKTOP_STYLE_ARG = 0; my $SCHEMAS_STYLE_ARG = 0; my $RFC822DEB_STYLE_ARG = 0; my $QUOTED_STYLE_ARG = 0; my $QUIET_ARG = 0; my $PASS_THROUGH_ARG = 0; my $UTF8_ARG = 0; my $MULTIPLE_OUTPUT = 0; my $cache_file; ## Handle options GetOptions ( "help" => \$HELP_ARG, "version" => \$VERSION_ARG, "quiet|q" => \$QUIET_ARG, "oaf-style|o" => \$BA_STYLE_ARG, ## for compatibility "ba-style|b" => \$BA_STYLE_ARG, "xml-style|x" => \$XML_STYLE_ARG, "keys-style|k" => \$KEYS_STYLE_ARG, "desktop-style|d" => \$DESKTOP_STYLE_ARG, "schemas-style|s" => \$SCHEMAS_STYLE_ARG, "rfc822deb-style|r" => \$RFC822DEB_STYLE_ARG, "quoted-style" => \$QUOTED_STYLE_ARG, "pass-through|p" => \$PASS_THROUGH_ARG, "utf8|u" => \$UTF8_ARG, "multiple-output|m" => \$MULTIPLE_OUTPUT, "cache|c=s" => \$cache_file ) or &error; my $PO_DIR; my $FILE; my $OUTFILE; my %po_files_by_lang = (); my %translations = (); my $iconv = $ENV{"ICONV"} || $ENV{"INTLTOOL_ICONV"} || "@INTLTOOL_ICONV@"; my $devnull = ($^O eq 'MSWin32' ? 'NUL:' : '/dev/null'); # Use this instead of \w for XML files to handle more possible characters. my $w = "[-A-Za-z0-9._:]"; # XML quoted string contents my $q = "[^\\\"]*"; ## Check for options. if ($VERSION_ARG) { &print_version; } elsif ($HELP_ARG) { &print_help; } elsif ($BA_STYLE_ARG && @ARGV > 2) { &utf8_sanity_check; &preparation; &print_message; &ba_merge_translations; &finalize; } elsif ($XML_STYLE_ARG && @ARGV > 2) { &utf8_sanity_check; &preparation; &print_message; &xml_merge_output; &finalize; } elsif ($KEYS_STYLE_ARG && @ARGV > 2) { &utf8_sanity_check; &preparation; &print_message; &keys_merge_translations; &finalize; } elsif ($DESKTOP_STYLE_ARG && @ARGV > 2) { &utf8_sanity_check; &preparation; &print_message; &desktop_merge_translations; &finalize; } elsif ($SCHEMAS_STYLE_ARG && @ARGV > 2) { &utf8_sanity_check; &preparation; &print_message; &schemas_merge_translations; &finalize; } elsif ($RFC822DEB_STYLE_ARG && @ARGV > 2) { &preparation; &print_message; &rfc822deb_merge_translations; &finalize; } elsif ($QUOTED_STYLE_ARG && @ARGV > 2) { &utf8_sanity_check; &preparation; &print_message; "ed_merge_translations; &finalize; } else { &print_help; } exit; ## Sub for printing release information sub print_version { print <<_EOF_; ${PROGRAM} (${PACKAGE}) ${VERSION} Written by Maciej Stachowiak, Darin Adler and Kenneth Christiansen. Copyright (C) 2000-2003 Free Software Foundation, Inc. Copyright (C) 2000-2001 Eazel, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. _EOF_ exit; } ## Sub for printing usage information sub print_help { print <<_EOF_; Usage: ${PROGRAM} [OPTION]... PO_DIRECTORY FILENAME OUTPUT_FILE Generates an output file that includes some localized attributes from an untranslated source file. Mandatory options: (exactly one must be specified) -b, --ba-style includes translations in the bonobo-activation style -d, --desktop-style includes translations in the desktop style -k, --keys-style includes translations in the keys style -s, --schemas-style includes translations in the schemas style -r, --rfc822deb-style includes translations in the RFC822 style --quoted-style includes translations in the quoted string style -x, --xml-style includes translations in the standard xml style Other options: -u, --utf8 convert all strings to UTF-8 before merging (default for everything except RFC822 style) -p, --pass-through deprecated, does nothing and issues a warning -m, --multiple-output output one localized file per locale, instead of a single file containing all localized elements -c, --cache=FILE specify cache file name (usually \$top_builddir/po/.intltool-merge-cache) -q, --quiet suppress most messages --help display this help and exit --version output version information and exit Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE") or send email to . _EOF_ exit; } ## Sub for printing error messages sub print_error { print STDERR "Try `${PROGRAM} --help' for more information.\n"; exit; } sub print_message { print "Merging translations into $OUTFILE.\n" unless $QUIET_ARG; } sub preparation { $PO_DIR = $ARGV[0]; $FILE = $ARGV[1]; $OUTFILE = $ARGV[2]; &gather_po_files; &get_translation_database; } # General-purpose code for looking up translations in .po files sub po_file2lang { my ($tmp) = @_; $tmp =~ s/^.*\/(.*)\.po$/$1/; return $tmp; } sub gather_po_files { for my $po_file (glob "$PO_DIR/*.po") { $po_files_by_lang{po_file2lang($po_file)} = $po_file; } } sub get_local_charset { my ($encoding) = @_; my $alias_file = $ENV{"G_CHARSET_ALIAS"} || "@INTLTOOL_LIBDIR@/charset.alias"; # seek character encoding aliases in charset.alias (glib) if (open CHARSET_ALIAS, $alias_file) { while () { next if /^\#/; return $1 if (/^\s*([-._a-zA-Z0-9]+)\s+$encoding\b/i) } close CHARSET_ALIAS; } # if not found, return input string return $encoding; } sub get_po_encoding { my ($in_po_file) = @_; my $encoding = ""; open IN_PO_FILE, $in_po_file or die; while () { ## example: "Content-Type: text/plain; charset=ISO-8859-1\n" if (/Content-Type\:.*charset=([-a-zA-Z0-9]+)\\n/) { $encoding = $1; last; } } close IN_PO_FILE; if (!$encoding) { print STDERR "Warning: no encoding found in $in_po_file. Assuming ISO-8859-1\n" unless $QUIET_ARG; $encoding = "ISO-8859-1"; } system ("$iconv -f $encoding -t UTF-8 <$devnull 2>$devnull"); if ($?) { $encoding = get_local_charset($encoding); } return $encoding } sub utf8_sanity_check { print STDERR "Warning: option --pass-through has been removed.\n" if $PASS_THROUGH_ARG; $UTF8_ARG = 1; } sub get_translation_database { if ($cache_file) { &get_cached_translation_database; } else { &create_translation_database; } } sub get_newest_po_age { my $newest_age; foreach my $file (values %po_files_by_lang) { my $file_age = -M $file; $newest_age = $file_age if !$newest_age || $file_age < $newest_age; } $newest_age = 0 if !$newest_age; return $newest_age; } sub create_cache { print "Generating and caching the translation database\n" unless $QUIET_ARG; &create_translation_database; open CACHE, ">$cache_file" || die; print CACHE join "\x01", %translations; close CACHE; } sub load_cache { print "Found cached translation database\n" unless $QUIET_ARG; my $contents; open CACHE, "<$cache_file" || die; { local $/; $contents = ; } close CACHE; %translations = split "\x01", $contents; } sub get_cached_translation_database { my $cache_file_age = -M $cache_file; if (defined $cache_file_age) { if ($cache_file_age <= &get_newest_po_age) { &load_cache; return; } print "Found too-old cached translation database\n" unless $QUIET_ARG; } &create_cache; } sub create_translation_database { for my $lang (keys %po_files_by_lang) { my $po_file = $po_files_by_lang{$lang}; if ($UTF8_ARG) { my $encoding = get_po_encoding ($po_file); if (lc $encoding eq "utf-8") { open PO_FILE, "<$po_file"; } else { print "NOTICE: $po_file is not in UTF-8 but $encoding, converting...\n" unless $QUIET_ARG;; open PO_FILE, "$iconv -f $encoding -t UTF-8 $po_file|"; } } else { open PO_FILE, "<$po_file"; } my $nextfuzzy = 0; my $inmsgid = 0; my $inmsgstr = 0; my $msgid = ""; my $msgstr = ""; while () { $nextfuzzy = 1 if /^#, fuzzy/; if (/^msgid "((\\.|[^\\]+)*)"/ ) { $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr; $msgid = ""; $msgstr = ""; if ($nextfuzzy) { $inmsgid = 0; } else { $msgid = unescape_po_string($1); $inmsgid = 1; } $inmsgstr = 0; $nextfuzzy = 0; } if (/^msgstr "((\\.|[^\\]+)*)"/) { $msgstr = unescape_po_string($1); $inmsgstr = 1; $inmsgid = 0; } if (/^"((\\.|[^\\]+)*)"/) { $msgid .= unescape_po_string($1) if $inmsgid; $msgstr .= unescape_po_string($1) if $inmsgstr; } } $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr; } } sub finalize { } sub unescape_one_sequence { my ($sequence) = @_; return "\\" if $sequence eq "\\\\"; return "\"" if $sequence eq "\\\""; return "\n" if $sequence eq "\\n"; return "\r" if $sequence eq "\\r"; return "\t" if $sequence eq "\\t"; return "\b" if $sequence eq "\\b"; return "\f" if $sequence eq "\\f"; return "\a" if $sequence eq "\\a"; return chr(11) if $sequence eq "\\v"; # vertical tab, see ascii(7) return chr(hex($1)) if ($sequence =~ /\\x([0-9a-fA-F]{2})/); return chr(oct($1)) if ($sequence =~ /\\([0-7]{3})/); # FIXME: Is \0 supported as well? Kenneth and Rodney don't want it, see bug #48489 return $sequence; } sub unescape_po_string { my ($string) = @_; $string =~ s/(\\x[0-9a-fA-F]{2}|\\[0-7]{3}|\\.)/unescape_one_sequence($1)/eg; return $string; } ## NOTE: deal with < - < but not > - > because it seems its ok to have ## > in the entity. For further info please look at #84738. sub entity_decode { local ($_) = @_; s/'/'/g; # ' s/"/"/g; # " s/&/&/g; s/</; close INPUT; } open OUTPUT, ">$OUTFILE" or die "can't open $OUTFILE: $!"; # Binmode so that selftest works ok if using a native Win32 Perl... binmode (OUTPUT) if $^O eq 'MSWin32'; while ($source =~ s|^(.*?)([ \t]*<\s*$w+\s+($w+\s*=\s*"$q"\s*)+/?>)([ \t]*\n)?||s) { print OUTPUT $1; my $node = $2 . "\n"; my @strings = (); $_ = $node; while (s/(\s)_($w+\s*=\s*"($q)")/$1$2/s) { push @strings, entity_decode($3); } print OUTPUT; my %langs; for my $string (@strings) { for my $lang (keys %po_files_by_lang) { $langs{$lang} = 1 if $translations{$lang, $string}; } } for my $lang (sort keys %langs) { $_ = $node; s/(\sname\s*=\s*)"($q)"/$1"$2-$lang"/s; s/(\s)_($w+\s*=\s*")($q)"/$1 . $2 . entity_encoded_translation($lang, $3) . '"'/seg; print OUTPUT; } } print OUTPUT $source; close OUTPUT; } ## XML (non-bonobo-activation) merge code # Process tag attributes # Only parameter is a HASH containing attributes -> values mapping sub getAttributeString { my $sub = shift; my $do_translate = shift || 0; my $language = shift || ""; my $result = ""; my $translate = shift; foreach my $e (reverse(sort(keys %{ $sub }))) { my $key = $e; my $string = $sub->{$e}; my $quote = '"'; $string =~ s/^[\s]+//; $string =~ s/[\s]+$//; if ($string =~ /^'.*'$/) { $quote = "'"; } $string =~ s/^['"]//g; $string =~ s/['"]$//g; if ($do_translate && $key =~ /^_/) { $key =~ s|^_||g; if ($language) { # Handle translation my $decode_string = entity_decode($string); my $translation = $translations{$language, $decode_string}; if ($translation) { $translation = entity_encode($translation); $string = $translation; } $$translate = 2; } else { $$translate = 2 if ($translate && (!$$translate)); # watch not to "overwrite" $translate } } $result .= " $key=$quote$string$quote"; } return $result; } # Returns a translatable string from XML node, it works on contents of every node in XML::Parser tree sub getXMLstring { my $ref = shift; my $spacepreserve = shift || 0; my @list = @{ $ref }; my $result = ""; my $count = scalar(@list); my $attrs = $list[0]; my $index = 1; $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/)); $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/)); while ($index < $count) { my $type = $list[$index]; my $content = $list[$index+1]; if (! $type ) { # We've got CDATA if ($content) { # lets strip the whitespace here, and *ONLY* here $content =~ s/\s+/ /gs if (!$spacepreserve); $result .= $content; } } elsif ( "$type" ne "1" ) { # We've got another element $result .= "<$type"; $result .= getAttributeString(@{$content}[0], 0); # no nested translatable elements if ($content) { my $subresult = getXMLstring($content, $spacepreserve); if ($subresult) { $result .= ">".$subresult . ""; } else { $result .= "/>"; } } else { $result .= "/>"; } } $index += 2; } return $result; } # Translate list of nodes if necessary sub translate_subnodes { my $fh = shift; my $content = shift; my $language = shift || ""; my $singlelang = shift || 0; my $spacepreserve = shift || 0; my @nodes = @{ $content }; my $count = scalar(@nodes); my $index = 0; while ($index < $count) { my $type = $nodes[$index]; my $rest = $nodes[$index+1]; if ($singlelang) { my $oldMO = $MULTIPLE_OUTPUT; $MULTIPLE_OUTPUT = 1; traverse($fh, $type, $rest, $language, $spacepreserve); $MULTIPLE_OUTPUT = $oldMO; } else { traverse($fh, $type, $rest, $language, $spacepreserve); } $index += 2; } } sub isWellFormedXmlFragment { my $ret = eval 'require XML::Parser'; if(!$ret) { die "You must have XML::Parser installed to run $0\n\n"; } my $fragment = shift; return 0 if (!$fragment); $fragment = "$fragment"; my $xp = new XML::Parser(Style => 'Tree'); my $tree = 0; eval { $tree = $xp->parse($fragment); }; return $tree; } sub traverse { my $fh = shift; my $nodename = shift; my $content = shift; my $language = shift || ""; my $spacepreserve = shift || 0; if (!$nodename) { if ($content =~ /^[\s]*$/) { $leading_space .= $content; } print $fh $content; } else { # element my @all = @{ $content }; my $attrs = shift @all; my $translate = 0; my $outattr = getAttributeString($attrs, 1, $language, \$translate); if ($nodename =~ /^_/) { $translate = 1; $nodename =~ s/^_//; } my $lookup = ''; $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/)); $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/)); print $fh "<$nodename", $outattr; if ($translate) { $lookup = getXMLstring($content, $spacepreserve); if (!$spacepreserve) { $lookup =~ s/^\s+//s; $lookup =~ s/\s+$//s; } if ($lookup || $translate == 2) { my $translation = $translations{$language, $lookup} if isWellFormedXmlFragment($translations{$language, $lookup}); if ($MULTIPLE_OUTPUT && ($translation || $translate == 2)) { $translation = $lookup if (!$translation); print $fh " xml:lang=\"", $language, "\"" if $language; print $fh ">"; if ($translate == 2) { translate_subnodes($fh, \@all, $language, 1, $spacepreserve); } else { print $fh $translation; } print $fh ""; return; # this means there will be no same translation with xml:lang="$language"... # if we want them both, just remove this "return" } else { print $fh ">"; if ($translate == 2) { translate_subnodes($fh, \@all, $language, 1, $spacepreserve); } else { print $fh $lookup; } print $fh ""; } } else { print $fh "/>"; } for my $lang (sort keys %po_files_by_lang) { if ($MULTIPLE_OUTPUT && $lang ne "$language") { next; } if ($lang) { # Handle translation # my $translate = 0; my $localattrs = getAttributeString($attrs, 1, $lang, \$translate); my $translation = $translations{$lang, $lookup} if isWellFormedXmlFragment($translations{$lang, $lookup}); if ($translate && !$translation) { $translation = $lookup; } if ($translation || $translate) { print $fh "\n"; $leading_space =~ s/.*\n//g; print $fh $leading_space; print $fh "<", $nodename, " xml:lang=\"", $lang, "\"", $localattrs, ">"; if ($translate == 2) { translate_subnodes($fh, \@all, $lang, 1, $spacepreserve); } else { print $fh $translation; } print $fh ""; } } } } else { my $count = scalar(@all); if ($count > 0) { print $fh ">"; my $index = 0; while ($index < $count) { my $type = $all[$index]; my $rest = $all[$index+1]; traverse($fh, $type, $rest, $language, $spacepreserve); $index += 2; } print $fh ""; } else { print $fh "/>"; } } } } sub intltool_tree_comment { my $expat = shift; my $data = shift; my $clist = $expat->{Curlist}; my $pos = $#$clist; push @$clist, 1 => $data; } sub intltool_tree_cdatastart { my $expat = shift; my $clist = $expat->{Curlist}; my $pos = $#$clist; push @$clist, 0 => $expat->original_string(); } sub intltool_tree_cdataend { my $expat = shift; my $clist = $expat->{Curlist}; my $pos = $#$clist; $clist->[$pos] .= $expat->original_string(); } sub intltool_tree_char { my $expat = shift; my $text = shift; my $clist = $expat->{Curlist}; my $pos = $#$clist; # Use original_string so that we retain escaped entities # in CDATA sections. # if ($pos > 0 and $clist->[$pos - 1] eq '0') { $clist->[$pos] .= $expat->original_string(); } else { push @$clist, 0 => $expat->original_string(); } } sub intltool_tree_start { my $expat = shift; my $tag = shift; my @origlist = (); # Use original_string so that we retain escaped entities # in attribute values. We must convert the string to an # @origlist array to conform to the structure of the Tree # Style. # my @original_array = split /\x/, $expat->original_string(); my $source = $expat->original_string(); # Remove leading tag. # $source =~ s|^\s*<\s*(\S+)||s; # Grab attribute key/value pairs and push onto @origlist array. # while ($source) { if ($source =~ /^\s*([\w:-]+)\s*[=]\s*["]/) { $source =~ s|^\s*([\w:-]+)\s*[=]\s*["]([^"]*)["]||s; push @origlist, $1; push @origlist, '"' . $2 . '"'; } elsif ($source =~ /^\s*([\w:-]+)\s*[=]\s*[']/) { $source =~ s|^\s*([\w:-]+)\s*[=]\s*[']([^']*)[']||s; push @origlist, $1; push @origlist, "'" . $2 . "'"; } else { last; } } my $ol = [ { @origlist } ]; push @{ $expat->{Lists} }, $expat->{Curlist}; push @{ $expat->{Curlist} }, $tag => $ol; $expat->{Curlist} = $ol; } sub readXml { my $filename = shift || return; if(!-f $filename) { die "ERROR Cannot find filename: $filename\n"; } my $ret = eval 'require XML::Parser'; if(!$ret) { die "You must have XML::Parser installed to run $0\n\n"; } my $xp = new XML::Parser(Style => 'Tree'); $xp->setHandlers(Char => \&intltool_tree_char); $xp->setHandlers(Start => \&intltool_tree_start); $xp->setHandlers(CdataStart => \&intltool_tree_cdatastart); $xp->setHandlers(CdataEnd => \&intltool_tree_cdataend); my $tree = $xp->parsefile($filename); # Hello thereHowdydo # would be: # [foo, [{}, head, [{id => "a"}, 0, "Hello ", em, [{}, 0, "there"]], bar, [{}, # 0, "Howdy", ref, [{}]], 0, "do" ] ] return $tree; } sub print_header { my $infile = shift; my $fh = shift; my $source; if(!-f $infile) { die "ERROR Cannot find filename: $infile\n"; } print $fh qq{\n}; { local $/; open DOCINPUT, "<${FILE}" or die; $source = ; close DOCINPUT; } if ($source =~ /()/s) { print $fh "$1\n"; } elsif ($source =~ /(]*>)/s) { print $fh "$1\n"; } } sub parseTree { my $fh = shift; my $ref = shift; my $language = shift || ""; my $name = shift @{ $ref }; my $cont = shift @{ $ref }; while (!$name || "$name" eq "1") { $name = shift @{ $ref }; $cont = shift @{ $ref }; } my $spacepreserve = 0; my $attrs = @{$cont}[0]; $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/)); traverse($fh, $name, $cont, $language, $spacepreserve); } sub xml_merge_output { my $source; if ($MULTIPLE_OUTPUT) { for my $lang (sort keys %po_files_by_lang) { if ( ! -e $lang ) { mkdir $lang or die "Cannot create subdirectory $lang: $!\n"; } open OUTPUT, ">$lang/$OUTFILE" or die "Cannot open $lang/$OUTFILE: $!\n"; binmode (OUTPUT) if $^O eq 'MSWin32'; my $tree = readXml($FILE); print_header($FILE, \*OUTPUT); parseTree(\*OUTPUT, $tree, $lang); close OUTPUT; print "CREATED $lang/$OUTFILE\n" unless $QUIET_ARG; } } open OUTPUT, ">$OUTFILE" or die "Cannot open $OUTFILE: $!\n"; binmode (OUTPUT) if $^O eq 'MSWin32'; my $tree = readXml($FILE); print_header($FILE, \*OUTPUT); parseTree(\*OUTPUT, $tree); close OUTPUT; print "CREATED $OUTFILE\n" unless $QUIET_ARG; } sub keys_merge_translations { open INPUT, "<${FILE}" or die; open OUTPUT, ">${OUTFILE}" or die; binmode (OUTPUT) if $^O eq 'MSWin32'; while () { if (s/^(\s*)_(\w+=(.*))/$1$2/) { my $string = $3; print OUTPUT; my $non_translated_line = $_; for my $lang (sort keys %po_files_by_lang) { my $translation = $translations{$lang, $string}; next if !$translation; $_ = $non_translated_line; s/(\w+)=.*/[$lang]$1=$translation/; print OUTPUT; } } else { print OUTPUT; } } close OUTPUT; close INPUT; } sub desktop_merge_translations { open INPUT, "<${FILE}" or die; open OUTPUT, ">${OUTFILE}" or die; binmode (OUTPUT) if $^O eq 'MSWin32'; while () { if (s/^(\s*)_(\w+=(.*))/$1$2/) { my $string = $3; print OUTPUT; my $non_translated_line = $_; for my $lang (sort keys %po_files_by_lang) { my $translation = $translations{$lang, $string}; next if !$translation; $_ = $non_translated_line; s/(\w+)=.*/${1}[$lang]=$translation/; print OUTPUT; } } else { print OUTPUT; } } close OUTPUT; close INPUT; } sub schemas_merge_translations { my $source; { local $/; # slurp mode open INPUT, "<$FILE" or die "can't open $FILE: $!"; $source = ; close INPUT; } open OUTPUT, ">$OUTFILE" or die; binmode (OUTPUT) if $^O eq 'MSWin32'; # FIXME: support attribute translations # Empty nodes never need translation, so unmark all of them. # For example, <_foo/> is just replaced by . $source =~ s|<\s*_($w+)\s*/>|<$1/>|g; while ($source =~ s/ (.*?) (\s+)((\s*) (\s*(?:\s*)?(.*?)\s*<\/default>)?(\s*) (\s*(?:\s*)?(.*?)\s*<\/short>)?(\s*) (\s*(?:\s*)?(.*?)\s*<\/long>)?(\s*) <\/locale>) //sx) { print OUTPUT $1; my $locale_start_spaces = $2 ? $2 : ''; my $default_spaces = $4 ? $4 : ''; my $short_spaces = $7 ? $7 : ''; my $long_spaces = $10 ? $10 : ''; my $locale_end_spaces = $13 ? $13 : ''; my $c_default_block = $3 ? $3 : ''; my $default_string = $6 ? $6 : ''; my $short_string = $9 ? $9 : ''; my $long_string = $12 ? $12 : ''; print OUTPUT "$locale_start_spaces$c_default_block"; $default_string =~ s/\s+/ /g; $default_string = entity_decode($default_string); $short_string =~ s/\s+/ /g; $short_string = entity_decode($short_string); $long_string =~ s/\s+/ /g; $long_string = entity_decode($long_string); for my $lang (sort keys %po_files_by_lang) { my $default_translation = $translations{$lang, $default_string}; my $short_translation = $translations{$lang, $short_string}; my $long_translation = $translations{$lang, $long_string}; next if (!$default_translation && !$short_translation && !$long_translation); print OUTPUT "\n$locale_start_spaces"; print OUTPUT "$default_spaces"; if ($default_translation) { $default_translation = entity_encode($default_translation); print OUTPUT "$default_translation"; } print OUTPUT "$short_spaces"; if ($short_translation) { $short_translation = entity_encode($short_translation); print OUTPUT "$short_translation"; } print OUTPUT "$long_spaces"; if ($long_translation) { $long_translation = entity_encode($long_translation); print OUTPUT "$long_translation"; } print OUTPUT "$locale_end_spaces"; } } print OUTPUT $source; close OUTPUT; } sub rfc822deb_merge_translations { my %encodings = (); for my $lang (keys %po_files_by_lang) { $encodings{$lang} = ($UTF8_ARG ? 'UTF-8' : get_po_encoding($po_files_by_lang{$lang})); } my $source; $Text::Wrap::huge = 'overflow'; $Text::Wrap::break = qr/\n|\s(?=\S)/; { local $/; # slurp mode open INPUT, "<$FILE" or die "can't open $FILE: $!"; $source = ; close INPUT; } open OUTPUT, ">${OUTFILE}" or die; binmode (OUTPUT) if $^O eq 'MSWin32'; while ($source =~ /(^|\n+)(_*)([^:\s]+)(:[ \t]*)(.*?)(?=\n[\S\n]|$)/sg) { my $sep = $1; my $non_translated_line = $3.$4; my $string = $5; my $underscore = length($2); next if $underscore eq 0 && $non_translated_line =~ /^#/; # Remove [] dummy strings my $stripped = $string; $stripped =~ s/\[\s[^\[\]]*\],/,/g if $underscore eq 2; $stripped =~ s/\[\s[^\[\]]*\]$//; $non_translated_line .= $stripped; print OUTPUT $sep.$non_translated_line; if ($underscore) { my @str_list = rfc822deb_split($underscore, $string); for my $lang (sort keys %po_files_by_lang) { my $is_translated = 1; my $str_translated = ''; my $first = 1; for my $str (@str_list) { my $translation = $translations{$lang, $str}; if (!$translation) { $is_translated = 0; last; } # $translation may also contain [] dummy # strings, mostly to indicate an empty string $translation =~ s/\[\s[^\[\]]*\]$//; if ($first) { if ($underscore eq 2) { $str_translated .= $translation; } else { $str_translated .= Text::Tabs::expand($translation) . "\n"; } } else { if ($underscore eq 2) { $str_translated .= ', ' . $translation; } else { $str_translated .= Text::Tabs::expand( Text::Wrap::wrap(' ', ' ', $translation)) . "\n .\n"; } } $first = 0; # To fix some problems with Text::Wrap::wrap $str_translated =~ s/(\n )+\n/\n .\n/g; } next unless $is_translated; $str_translated =~ s/\n \.\n$//; $str_translated =~ s/\s+$//; $_ = $non_translated_line; s/^(\w+):\s*.*/$sep${1}-$lang.$encodings{$lang}: $str_translated/s; print OUTPUT; } } } print OUTPUT "\n"; close OUTPUT; close INPUT; } sub rfc822deb_split { # Debian defines a special way to deal with rfc822-style files: # when a value contain newlines, it consists of # 1. a short form (first line) # 2. a long description, all lines begin with a space, # and paragraphs are separated by a single dot on a line # This routine returns an array of all paragraphs, and reformat # them. # When first argument is 2, the string is a comma separated list of # values. my $type = shift; my $text = shift; $text =~ s/^[ \t]//mg; return (split(/, */, $text, 0)) if $type ne 1; return ($text) if $text !~ /\n/; $text =~ s/([^\n]*)\n//; my @list = ($1); my $str = ''; for my $line (split (/\n/, $text)) { chomp $line; if ($line =~ /^\.\s*$/) { # New paragraph $str =~ s/\s*$//; push(@list, $str); $str = ''; } elsif ($line =~ /^\s/) { # Line which must not be reformatted $str .= "\n" if length ($str) && $str !~ /\n$/; $line =~ s/\s+$//; $str .= $line."\n"; } else { # Continuation line, remove newline $str .= " " if length ($str) && $str !~ /\n$/; $str .= $line; } } $str =~ s/\s*$//; push(@list, $str) if length ($str); return @list; } sub quoted_translation { my ($lang, $string) = @_; $string =~ s/\\\"/\"/g; my $translation = $translations{$lang, $string}; $translation = $string if !$translation; $translation =~ s/\"/\\\"/g; return $translation } sub quoted_merge_translations { if (!$MULTIPLE_OUTPUT) { print "Quoted only supports Multiple Output.\n"; exit(1); } for my $lang (sort keys %po_files_by_lang) { if ( ! -e $lang ) { mkdir $lang or die "Cannot create subdirectory $lang: $!\n"; } open INPUT, "<${FILE}" or die; open OUTPUT, ">$lang/$OUTFILE" or die "Cannot open $lang/$OUTFILE: $!\n"; binmode (OUTPUT) if $^O eq 'MSWin32'; while () { s/\"(([^\"]|\\\")*[^\\\"])\"/"\"" . "ed_translation($lang, $1) . "\""/ge; print OUTPUT; } close OUTPUT; close INPUT; } } pacemaker-mgmt-pacemaker-mgmt-2.1.2/intltool-update.in000066400000000000000000000670661211477743100230000ustar00rootroot00000000000000#!@INTLTOOL_PERL@ -w # -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*- # # The Intltool Message Updater # # Copyright (C) 2000-2003 Free Software Foundation. # # Intltool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # version 2 published by the Free Software Foundation. # # Intltool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # # Authors: Kenneth Christiansen # Maciej Stachowiak # Darin Adler ## Release information my $PROGRAM = "intltool-update"; my $VERSION = "0.35.2"; my $PACKAGE = "intltool"; ## Loaded modules use strict; use Getopt::Long; use Cwd; use File::Copy; use File::Find; ## Scalars used by the option stuff my $HELP_ARG = 0; my $VERSION_ARG = 0; my $DIST_ARG = 0; my $POT_ARG = 0; my $HEADERS_ARG = 0; my $MAINTAIN_ARG = 0; my $REPORT_ARG = 0; my $VERBOSE = 0; my $GETTEXT_PACKAGE = ""; my $OUTPUT_FILE = ""; my @languages; my %varhash = (); my %po_files_by_lang = (); # Regular expressions to categorize file types. # FIXME: Please check if the following is correct my $xml_support = "xml(?:\\.in)*|". # http://www.w3.org/XML/ (Note: .in is not required) "ui|". # Bonobo specific - User Interface desc. files "lang|". # ? "glade2?(?:\\.in)*|". # Glade specific - User Interface desc. files (Note: .in is not required) "scm(?:\\.in)*|". # ? (Note: .in is not required) "oaf(?:\\.in)+|". # DEPRECATED: Replaces by Bonobo .server files "etspec|". # ? "server(?:\\.in)+|". # Bonobo specific "sheet(?:\\.in)+|". # ? "schemas(?:\\.in)+|". # GConf specific "pong(?:\\.in)+|". # DEPRECATED: PONG is not used [by GNOME] any longer. "kbd(?:\\.in)+"; # GOK specific. my $ini_support = "icon(?:\\.in)+|". # http://www.freedesktop.org/Standards/icon-theme-spec "desktop(?:\\.in)+|". # http://www.freedesktop.org/Standards/menu-spec "caves(?:\\.in)+|". # GNOME Games specific "directory(?:\\.in)+|". # http://www.freedesktop.org/Standards/menu-spec "soundlist(?:\\.in)+|". # GNOME specific "keys(?:\\.in)+|". # GNOME Mime database specific "theme(?:\\.in)+|". # http://www.freedesktop.org/Standards/icon-theme-spec "service(?:\\.in)+"; # DBus specific my $buildin_gettext_support = "c|y|cs|cc|cpp|c\\+\\+|h|hh|gob|py"; ## Always flush buffer when printing $| = 1; ## Sometimes the source tree will be rooted somewhere else. my $SRCDIR = $ENV{"srcdir"} || "."; my $POTFILES_in; $POTFILES_in = "<$SRCDIR/POTFILES.in"; my $devnull = ($^O eq 'MSWin32' ? 'NUL:' : '/dev/null'); ## Handle options GetOptions ( "help" => \$HELP_ARG, "version" => \$VERSION_ARG, "dist|d" => \$DIST_ARG, "pot|p" => \$POT_ARG, "headers|s" => \$HEADERS_ARG, "maintain|m" => \$MAINTAIN_ARG, "report|r" => \$REPORT_ARG, "verbose|x" => \$VERBOSE, "gettext-package|g=s" => \$GETTEXT_PACKAGE, "output-file|o=s" => \$OUTPUT_FILE, ) or &Console_WriteError_InvalidOption; &Console_Write_IntltoolHelp if $HELP_ARG; &Console_Write_IntltoolVersion if $VERSION_ARG; my $arg_count = ($DIST_ARG > 0) + ($POT_ARG > 0) + ($HEADERS_ARG > 0) + ($MAINTAIN_ARG > 0) + ($REPORT_ARG > 0); &Console_Write_IntltoolHelp if $arg_count > 1; my $PKGNAME = FindPackageName (); # --version and --help don't require a module name my $MODULE = $GETTEXT_PACKAGE || $PKGNAME || "unknown"; if ($POT_ARG) { &GenerateHeaders; &GeneratePOTemplate; } elsif ($HEADERS_ARG) { &GenerateHeaders; } elsif ($MAINTAIN_ARG) { &FindLeftoutFiles; } elsif ($REPORT_ARG) { &GenerateHeaders; &GeneratePOTemplate; &Console_Write_CoverageReport; } elsif ((defined $ARGV[0]) && $ARGV[0] =~ /^[a-z]/) { my $lang = $ARGV[0]; ## Report error if the language file supplied ## to the command line is non-existent &Console_WriteError_NotExisting("$SRCDIR/$lang.po") if ! -s "$SRCDIR/$lang.po"; if (!$DIST_ARG) { print "Working, please wait..." if $VERBOSE; &GenerateHeaders; &GeneratePOTemplate; } &POFile_Update ($lang, $OUTPUT_FILE); &Console_Write_TranslationStatus ($lang, $OUTPUT_FILE); } else { &Console_Write_IntltoolHelp; } exit; ######### sub Console_Write_IntltoolVersion { print <<_EOF_; ${PROGRAM} (${PACKAGE}) $VERSION Written by Kenneth Christiansen, Maciej Stachowiak, and Darin Adler. Copyright (C) 2000-2003 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. _EOF_ exit; } sub Console_Write_IntltoolHelp { print <<_EOF_; Usage: ${PROGRAM} [OPTION]... LANGCODE Updates PO template files and merge them with the translations. Mode of operation (only one is allowed): -p, --pot generate the PO template only -s, --headers generate the header files in POTFILES.in -m, --maintain search for left out files from POTFILES.in -r, --report display a status report for the module -d, --dist merge LANGCODE.po with existing PO template Extra options: -g, --gettext-package=NAME override PO template name, useful with --pot -o, --output-file=FILE write merged translation to FILE -x, --verbose display lots of feedback --help display this help and exit --version output version information and exit Examples of use: ${PROGRAM} --pot just create a new PO template ${PROGRAM} xy create new PO template and merge xy.po with it Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE") or send email to . _EOF_ exit; } sub echo_n { my $str = shift; my $ret = `echo "$str"`; $ret =~ s/\n$//; # do we need the "s" flag? return $ret; } sub POFile_DetermineType ($) { my $type = $_; my $gettext_type; my $xml_regex = "(?:" . $xml_support . ")"; my $ini_regex = "(?:" . $ini_support . ")"; my $buildin_regex = "(?:" . $buildin_gettext_support . ")"; if ($type =~ /\[type: gettext\/([^\]].*)]/) { $gettext_type=$1; } elsif ($type =~ /schemas(\.in)+$/) { $gettext_type="schemas"; } elsif ($type =~ /glade2?(\.in)*$/) { $gettext_type="glade"; } elsif ($type =~ /scm(\.in)*$/) { $gettext_type="scheme"; } elsif ($type =~ /keys(\.in)+$/) { $gettext_type="keys"; } # bucket types elsif ($type =~ /$xml_regex$/) { $gettext_type="xml"; } elsif ($type =~ /$ini_regex$/) { $gettext_type="ini"; } elsif ($type =~ /$buildin_regex$/) { $gettext_type="buildin"; } else { $gettext_type="unknown"; } return "gettext\/$gettext_type"; } sub TextFile_DetermineEncoding ($) { my $gettext_code="ASCII"; # All files are ASCII by default my $filetype=`file $_ | cut -d ' ' -f 2`; if ($? eq "0") { if ($filetype =~ /^(ISO|UTF)/) { chomp ($gettext_code = $filetype); } elsif ($filetype =~ /^XML/) { $gettext_code="UTF-8"; # We asume that .glade and other .xml files are UTF-8 } } return $gettext_code; } sub isNotValidMissing { my ($file) = @_; return if $file =~ /^\{arch\}\/.*$/; return if $file =~ /^$varhash{"PACKAGE"}-$varhash{"VERSION"}\/.*$/; } sub FindLeftoutFiles { my (@buf_i18n_plain, @buf_i18n_xml, @buf_i18n_xml_unmarked, @buf_i18n_ini, @buf_potfiles, @buf_potfiles_ignore, @buf_allfiles, @buf_allfiles_sorted, @buf_potfiles_sorted, @buf_potfiles_ignore_sorted ); ## Search and find all translatable files find sub { push @buf_i18n_plain, "$File::Find::name" if /\.($buildin_gettext_support)$/; push @buf_i18n_xml, "$File::Find::name" if /\.($xml_support)$/; push @buf_i18n_ini, "$File::Find::name" if /\.($ini_support)$/; push @buf_i18n_xml_unmarked, "$File::Find::name" if /\.(schemas(\.in)+)$/; }, ".."; open POTFILES, $POTFILES_in or die "$PROGRAM: there's no POTFILES.in!\n"; @buf_potfiles = grep !/^(#|\s*$)/, ; close POTFILES; foreach (@buf_potfiles) { s/^\[.*]\s*//; } print "Searching for missing translatable files...\n" if $VERBOSE; ## Check if we should ignore some found files, when ## comparing with POTFILES.in foreach my $ignore ("POTFILES.skip", "POTFILES.ignore") { (-s "$SRCDIR/$ignore") or next; if ("$ignore" eq "POTFILES.ignore") { print "The usage of POTFILES.ignore is deprecated. Please consider moving the\n". "content of this file to POTFILES.skip.\n"; } print "Found $ignore: Ignoring files...\n" if $VERBOSE; open FILE, "<$SRCDIR/$ignore" or die "ERROR: Failed to open $SRCDIR/$ignore!\n"; while () { push @buf_potfiles_ignore, $_ unless /^(#|\s*$)/; } close FILE; @buf_potfiles_ignore_sorted = sort (@buf_potfiles_ignore); } foreach my $file (@buf_i18n_plain) { my $in_comment = 0; my $in_macro = 0; open FILE, "<$file"; while () { # Handle continued multi-line comment. if ($in_comment) { next unless s-.*\*/--; $in_comment = 0; } # Handle continued macro. if ($in_macro) { $in_macro = 0 unless /\\$/; next; } # Handle start of macro (or any preprocessor directive). if (/^\s*\#/) { $in_macro = 1 if /^([^\\]|\\.)*\\$/; next; } # Handle comments and quoted text. while (m-(/\*|//|\'|\")-) # \' and \" keep emacs perl mode happy { my $match = $1; if ($match eq "/*") { if (!s-/\*.*?\*/--) { s-/\*.*--; $in_comment = 1; } } elsif ($match eq "//") { s-//.*--; } else # ' or " { if (!s-$match([^\\]|\\.)*?$match-QUOTEDTEXT-) { warn "mismatched quotes at line $. in $file\n"; s-$match.*--; } } } if (/\w\.GetString *\(QUOTEDTEXT/) { if (defined isNotValidMissing (unpack("x3 A*", $file))) { ## Remove the first 3 chars and add newline push @buf_allfiles, unpack("x3 A*", $file) . "\n"; } last; } ## N_ Q_ and _ are the three macros defined in gi8n.h if (/[NQ]?_ *\(QUOTEDTEXT/) { if (defined isNotValidMissing (unpack("x3 A*", $file))) { ## Remove the first 3 chars and add newline push @buf_allfiles, unpack("x3 A*", $file) . "\n"; } last; } } close FILE; } foreach my $file (@buf_i18n_xml) { open FILE, "<$file"; while () { # FIXME: share the pattern matching code with intltool-extract if (/\s_[-A-Za-z0-9._:]+\s*=\s*\"([^"]+)\"/ || /<_[^>]+>/ || /translatable=\"yes\"/) { if (defined isNotValidMissing (unpack("x3 A*", $file))) { push @buf_allfiles, unpack("x3 A*", $file) . "\n"; } last; } } close FILE; } foreach my $file (@buf_i18n_ini) { open FILE, "<$file"; while () { if (/_(.*)=/) { if (defined isNotValidMissing (unpack("x3 A*", $file))) { push @buf_allfiles, unpack("x3 A*", $file) . "\n"; } last; } } close FILE; } foreach my $file (@buf_i18n_xml_unmarked) { if (defined isNotValidMissing (unpack("x3 A*", $file))) { push @buf_allfiles, unpack("x3 A*", $file) . "\n"; } } @buf_allfiles_sorted = sort (@buf_allfiles); @buf_potfiles_sorted = sort (@buf_potfiles); my %in2; foreach (@buf_potfiles_sorted) { $in2{$_} = 1; } foreach (@buf_potfiles_ignore_sorted) { $in2{$_} = 1; } my @result; foreach (@buf_allfiles_sorted) { if (!exists($in2{$_})) { push @result, $_ } } my @buf_potfiles_notexist; foreach (@buf_potfiles_sorted) { chomp (my $dummy = $_); if ("$dummy" ne "" and !(-f "$SRCDIR/../$dummy" or -f "../$dummy")) { push @buf_potfiles_notexist, $_; } } ## Save file with information about the files missing ## if any, and give information about this procedure. if (@result + @buf_potfiles_notexist > 0) { if (@result) { print "\n" if $VERBOSE; unlink "missing"; open OUT, ">missing"; print OUT @result; close OUT; warn "\e[1mThe following files contain translations and are currently not in use. Please\e[0m\n". "\e[1mconsider adding these to the POTFILES.in file, located in the po/ directory.\e[0m\n\n"; print STDERR @result, "\n"; warn "If some of these files are left out on purpose then please add them to\n". "POTFILES.skip instead of POTFILES.in. A file \e[1m'missing'\e[0m containing this list\n". "of left out files has been written in the current directory.\n"; } if (@buf_potfiles_notexist) { unlink "notexist"; open OUT, ">notexist"; print OUT @buf_potfiles_notexist; close OUT; warn "\n" if ($VERBOSE or @result); warn "\e[1mThe following files do not exist anymore:\e[0m\n\n"; warn @buf_potfiles_notexist, "\n"; warn "Please remove them from POTFILES.in. A file \e[1m'notexist'\e[0m\n". "containing this list of absent files has been written in the current directory.\n"; } } ## If there is nothing to complain about, notify the user else { print "\nAll files containing translations are present in POTFILES.in.\n" if $VERBOSE; } } sub Console_WriteError_InvalidOption { ## Handle invalid arguments print STDERR "Try `${PROGRAM} --help' for more information.\n"; exit 1; } sub GenerateHeaders { my $EXTRACT = "@INTLTOOL_EXTRACT@"; chomp $EXTRACT; $EXTRACT = $ENV{"INTLTOOL_EXTRACT"} if $ENV{"INTLTOOL_EXTRACT"}; ## Generate the .h header files, so we can allow glade and ## xml translation support if (! -x "$EXTRACT") { print STDERR "\n *** The intltool-extract script wasn't found!" ."\n *** Without it, intltool-update can not generate files.\n"; exit; } else { open (FILE, $POTFILES_in) or die "$PROGRAM: POTFILES.in not found.\n"; while () { chomp; next if /^\[\s*encoding/; ## Find xml files in POTFILES.in and generate the ## files with help from the extract script my $gettext_type= &POFile_DetermineType ($1); if (/\.($xml_support|$ini_support)$/ || /^\[/) { s/^\[[^\[].*]\s*//; my $filename = "../$_"; if ($VERBOSE) { system ($EXTRACT, "--update", "--srcdir=$SRCDIR", "--type=$gettext_type", $filename); } else { system ($EXTRACT, "--update", "--type=$gettext_type", "--srcdir=$SRCDIR", "--quiet", $filename); } } } close FILE; } } # # Generate .pot file from POTFILES.in # sub GeneratePOTemplate { my $XGETTEXT = $ENV{"XGETTEXT"} || "@INTLTOOL_XGETTEXT@"; my $XGETTEXT_ARGS = $ENV{"XGETTEXT_ARGS"} || ''; chomp $XGETTEXT; if (! -x $XGETTEXT) { print STDERR " *** xgettext is not found on this system!\n". " *** Without it, intltool-update can not extract strings.\n"; exit; } print "Building $MODULE.pot...\n" if $VERBOSE; open INFILE, $POTFILES_in; unlink "POTFILES.in.temp"; open OUTFILE, ">POTFILES.in.temp" or die("Cannot open POTFILES.in.temp for writing"); my $gettext_support_nonascii = 0; # checks for GNU gettext >= 0.12 my $dummy = `$XGETTEXT --version --from-code=UTF-8 >$devnull 2>$devnull`; if ($? == 0) { $gettext_support_nonascii = 1; } else { # urge everybody to upgrade gettext print STDERR "WARNING: This version of gettext does not support extracting non-ASCII\n". " strings. That means you should install a version of gettext\n". " that supports non-ASCII strings (such as GNU gettext >= 0.12),\n". " or have to let non-ASCII strings untranslated. (If there is any)\n"; } my $encoding = "ASCII"; my $forced_gettext_code; my @temp_headers; my $encoding_problem_is_reported = 0; while () { next if (/^#/ or /^\s*$/); chomp; my $gettext_code; if (/^\[\s*encoding:\s*(.*)\s*\]/) { $forced_gettext_code=$1; } elsif (/\.($xml_support|$ini_support)$/ || /^\[/) { s/^\[.*]\s*//; print OUTFILE "../$_.h\n"; push @temp_headers, "../$_.h"; $gettext_code = &TextFile_DetermineEncoding ("../$_.h") if ($gettext_support_nonascii and not defined $forced_gettext_code); } else { print OUTFILE "$SRCDIR/../$_\n"; $gettext_code = &TextFile_DetermineEncoding ("$SRCDIR/../$_") if ($gettext_support_nonascii and not defined $forced_gettext_code); } next if (! $gettext_support_nonascii); if (defined $forced_gettext_code) { $encoding=$forced_gettext_code; } elsif (defined $gettext_code and "$encoding" ne "$gettext_code") { if ($encoding eq "ASCII") { $encoding=$gettext_code; } elsif ($gettext_code ne "ASCII") { # Only report once because the message is quite long if (! $encoding_problem_is_reported) { print STDERR "WARNING: You should use the same file encoding for all your project files,\n". " but $PROGRAM thinks that most of the source files are in\n". " $encoding encoding, while \"$_\" is (likely) in\n". " $gettext_code encoding. If you are sure that all translatable strings\n". " are in same encoding (say UTF-8), please \e[1m*prepend*\e[0m the following\n". " line to POTFILES.in:\n\n". " [encoding: UTF-8]\n\n". " and make sure that configure.in/ac checks for $PACKAGE >= 0.27 .\n". "(such warning message will only be reported once.)\n"; $encoding_problem_is_reported = 1; } } } } close OUTFILE; close INFILE; unlink "$MODULE.pot"; my @xgettext_argument=("$XGETTEXT", "--add-comments", "--directory\=\.", "--output\=$MODULE\.pot", "--files-from\=\.\/POTFILES\.in\.temp"); my $XGETTEXT_KEYWORDS = &FindPOTKeywords; push @xgettext_argument, $XGETTEXT_KEYWORDS; my $MSGID_BUGS_ADDRESS = &FindMakevarsBugAddress; push @xgettext_argument, "--msgid-bugs-address\=$MSGID_BUGS_ADDRESS" if $MSGID_BUGS_ADDRESS; push @xgettext_argument, "--from-code\=$encoding" if ($gettext_support_nonascii); push @xgettext_argument, $XGETTEXT_ARGS if $XGETTEXT_ARGS; my $xgettext_command = join ' ', @xgettext_argument; # intercept xgettext error message print "Running $xgettext_command\n" if $VERBOSE; my $xgettext_error_msg = `$xgettext_command 2>\&1`; my $command_failed = $?; unlink "POTFILES.in.temp"; print "Removing generated header (.h) files..." if $VERBOSE; unlink foreach (@temp_headers); print "done.\n" if $VERBOSE; if (! $command_failed) { if (! -e "$MODULE.pot") { print "None of the files in POTFILES.in contain strings marked for translation.\n" if $VERBOSE; } else { print "Wrote $MODULE.pot\n" if $VERBOSE; } } else { if ($xgettext_error_msg =~ /--from-code/) { # replace non-ASCII error message with a more useful one. print STDERR "ERROR: xgettext failed to generate PO template file because there is non-ASCII\n". " string marked for translation. Please make sure that all strings marked\n". " for translation are in uniform encoding (say UTF-8), then \e[1m*prepend*\e[0m the\n". " following line to POTFILES.in and rerun $PROGRAM:\n\n". " [encoding: UTF-8]\n\n"; } else { print STDERR "$xgettext_error_msg"; if (-e "$MODULE.pot") { # is this possible? print STDERR "ERROR: xgettext failed but still managed to generate PO template file.\n". " Please consult error message above if there is any.\n"; } else { print STDERR "ERROR: xgettext failed to generate PO template file. Please consult\n". " error message above if there is any.\n"; } } exit (1); } } sub POFile_Update { -f "$MODULE.pot" or die "$PROGRAM: $MODULE.pot does not exist.\n"; my $MSGMERGE = $ENV{"MSGMERGE"} || "@INTLTOOL_MSGMERGE@"; my ($lang, $outfile) = @_; print "Merging $SRCDIR/$lang.po with $MODULE.pot..." if $VERBOSE; my $infile = "$SRCDIR/$lang.po"; $outfile = "$SRCDIR/$lang.po" if ($outfile eq ""); # I think msgmerge won't overwrite old file if merge is not successful system ("$MSGMERGE", "-o", $outfile, $infile, "$MODULE.pot"); } sub Console_WriteError_NotExisting { my ($file) = @_; ## Report error if supplied language file is non-existing print STDERR "$PROGRAM: $file does not exist!\n"; print STDERR "Try '$PROGRAM --help' for more information.\n"; exit; } sub GatherPOFiles { my @po_files = glob ("./*.po"); @languages = map (&POFile_GetLanguage, @po_files); foreach my $lang (@languages) { $po_files_by_lang{$lang} = shift (@po_files); } } sub POFile_GetLanguage ($) { s/^(.*\/)?(.+)\.po$/$2/; return $_; } sub Console_Write_TranslationStatus { my ($lang, $output_file) = @_; my $MSGFMT = $ENV{"MSGFMT"} || "@INTLTOOL_MSGFMT@"; $output_file = "$SRCDIR/$lang.po" if ($output_file eq ""); system ("$MSGFMT", "-o", "$devnull", "--verbose", $output_file); } sub Console_Write_CoverageReport { my $MSGFMT = $ENV{"MSGFMT"} || "@INTLTOOL_MSGFMT@"; &GatherPOFiles; foreach my $lang (@languages) { print "$lang: "; &POFile_Update ($lang, ""); } print "\n\n * Current translation support in $MODULE \n\n"; foreach my $lang (@languages) { print "$lang: "; system ("$MSGFMT", "-o", "$devnull", "--verbose", "$SRCDIR/$lang.po"); } } sub SubstituteVariable { my ($str) = @_; # always need to rewind file whenever it has been accessed seek (CONF, 0, 0); # cache each variable. varhash is global to we can add # variables elsewhere. while () { if (/^(\w+)=(.*)$/) { ($varhash{$1} = $2) =~ s/^["'](.*)["']$/$1/; } } if ($str =~ /^(.*)\${?([A-Z_]+)}?(.*)$/) { my $rest = $3; my $untouched = $1; my $sub = ""; # Ignore recursive definitions of variables $sub = $varhash{$2} if defined $varhash{$2} and $varhash{$2} !~ /\${?$2}?/; return SubstituteVariable ("$untouched$sub$rest"); } # We're using Perl backticks ` and "echo -n" here in order to # expand any shell escapes (such as backticks themselves) in every variable return echo_n ($str); } sub CONF_Handle_Open { my $base_dirname = getcwd(); $base_dirname =~ s@.*/@@; my ($conf_in, $src_dir); if ($base_dirname =~ /^po(-.+)?$/) { if (-f "Makevars") { my $makefile_source; local (*IN); open (IN, ") { if (/^top_builddir[ \t]*=/) { $src_dir = $_; $src_dir =~ s/^top_builddir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/; chomp $src_dir; if (-f "$src_dir" . "/configure.ac") { $conf_in = "$src_dir" . "/configure.ac" . "\n"; } else { $conf_in = "$src_dir" . "/configure.in" . "\n"; } last; } } close IN; $conf_in || die "Cannot find top_builddir in Makevars."; } elsif (-f "../configure.ac") { $conf_in = "../configure.ac"; } elsif (-f "../configure.in") { $conf_in = "../configure.in"; } else { my $makefile_source; local (*IN); open (IN, ") { if (/^top_srcdir[ \t]*=/) { $src_dir = $_; $src_dir =~ s/^top_srcdir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/; chomp $src_dir; $conf_in = "$src_dir" . "/configure.in" . "\n"; last; } } close IN; $conf_in || die "Cannot find top_srcdir in Makefile."; } open (CONF, "<$conf_in"); } else { print STDERR "$PROGRAM: Unable to proceed.\n" . "Make sure to run this script inside the po directory.\n"; exit; } } sub FindPackageName { my $version; my $domain = &FindMakevarsDomain; my $name = $domain || "untitled"; &CONF_Handle_Open; my $conf_source; { local (*IN); open (IN, "<&CONF") || return $name; seek (IN, 0, 0); local $/; # slurp mode $conf_source = ; close IN; } # priority for getting package name: # 1. GETTEXT_PACKAGE # 2. first argument of AC_INIT (with >= 2 arguments) # 3. first argument of AM_INIT_AUTOMAKE (with >= 2 argument) # /^AM_INIT_AUTOMAKE\([\s\[]*([^,\)\s\]]+)/m # the \s makes this not work, why? if ($conf_source =~ /^AM_INIT_AUTOMAKE\(([^,\)]+),([^,\)]+)/m) { ($name, $version) = ($1, $2); $name =~ s/[\[\]\s]//g; $version =~ s/[\[\]\s]//g; $varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\${?AC_PACKAGE_NAME}?/); $varhash{"PACKAGE"} = $name if (not $name =~ /\${?PACKAGE}?/); $varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\${?AC_PACKAGE_VERSION}?/); $varhash{"VERSION"} = $version if (not $name =~ /\${?VERSION}?/); } if ($conf_source =~ /^AC_INIT\(([^,\)]+),([^,\)]+)/m) { ($name, $version) = ($1, $2); $name =~ s/[\[\]\s]//g; $version =~ s/[\[\]\s]//g; $varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\${?AC_PACKAGE_NAME}?/); $varhash{"PACKAGE"} = $name if (not $name =~ /\${?PACKAGE}?/); $varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\${?AC_PACKAGE_VERSION}?/); $varhash{"VERSION"} = $version if (not $name =~ /\${?VERSION}?/); } # \s makes this not work, why? $name = $1 if $conf_source =~ /^GETTEXT_PACKAGE=\[?([^\n\]]+)/m; # m4 macros AC_PACKAGE_NAME, AC_PACKAGE_VERSION etc. have same value # as corresponding $PACKAGE_NAME, $PACKAGE_VERSION etc. shell variables. $name =~ s/\bAC_PACKAGE_/\$PACKAGE_/g; $name = $domain if $domain; $name = SubstituteVariable ($name); $name =~ s/^["'](.*)["']$/$1/; return $name if $name; } sub FindPOTKeywords { my $keywords = "--keyword\=\_ --keyword\=N\_ --keyword\=U\_ --keyword\=Q\_"; my $varname = "XGETTEXT_OPTIONS"; my $make_source; { local (*IN); open (IN, "; close IN; } $keywords = $1 if $make_source =~ /^$varname[ ]*=\[?([^\n\]]+)/m; return $keywords; } sub FindMakevarsDomain { my $domain = ""; my $makevars_source; { local (*IN); open (IN, "; close IN; } $domain = $1 if $makevars_source =~ /^DOMAIN[ ]*=\[?([^\n\]\$]+)/m; $domain =~ s/^\s+//; $domain =~ s/\s+$//; return $domain; } sub FindMakevarsBugAddress { my $address = ""; my $makevars_source; { local (*IN); open (IN, "; close IN; } $address = $1 if $makevars_source =~ /^MSGID_BUGS_ADDRESS[ ]*=\[?([^\n\]\$]+)/m; $address =~ s/^\s+//; $address =~ s/\s+$//; return $address; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/lib/000077500000000000000000000000001211477743100200535ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/lib/Makefile.am000066400000000000000000000015451211477743100221140ustar00rootroot00000000000000# # heartbeat library directory: Linux-HA code # # Copyright (C) 2001 Alan Robertson # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in ## Subdirectories... SUBDIRS = mgmt pacemaker-mgmt-pacemaker-mgmt-2.1.2/lib/mgmt/000077500000000000000000000000001211477743100210175ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/lib/mgmt/.cvsignore000066400000000000000000000001321211477743100230130ustar00rootroot00000000000000Makefile.in Makefile *.beam .deps .libs *.la *.lo pymgmt.py pymgmt_wrap.c pymgmt_wrap.doc pacemaker-mgmt-pacemaker-mgmt-2.1.2/lib/mgmt/Makefile.am000066400000000000000000000047641211477743100230660ustar00rootroot00000000000000# # Author: Sun Jiang Dong # Copyright (c) 2005 International Business Machines # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_builddir)/linux-ha -I$(top_srcdir)/linux-ha \ -I$(top_builddir)/libltdl -I$(top_srcdir)/libltdl \ -I$(top_builddir) -I$(top_srcdir) halibdir = $(libdir)/@HB_PKG@ if MGMT_CLIENT_BUILD guilibdir = $(libdir)/heartbeat-gui endif havarlibdir = $(localstatedir)/lib/@HB_PKG@ COMMONLIBS = $(GLIBLIB) #MGMT_DIR = mgmt #mgmtdir = $(HA_VARLIBHBDIR)/$(MGMT_DIR) apigid = @HA_APIGROUP@ EXTRA_DIST = pymgmt.i lib_LTLIBRARIES = libhbmgmttls.la libhbmgmtclient.la libhbmgmtcommon.la libhbmgmttls_la_SOURCES = mgmt_tls_lib.c libhbmgmttls_la_LIBADD = $(COMMONLIBS) $(GNUTLSLIBS) libhbmgmttls_la_CFLAGS = $(INCLUDES) $(GNUTLSHEAD) libhbmgmtclient_la_SOURCES = mgmt_client_lib.c libhbmgmtclient_la_LIBADD = $(COMMONLIBS) libhbmgmttls.la $(top_builddir)/replace/libreplace.la libhbmgmtclient_la_CFLAGS = $(INCLUDES) libhbmgmtcommon_la_SOURCES = mgmt_common_lib.c libhbmgmtcommon_la_LIBADD = $(COMMONLIBS) $(top_builddir)/replace/libreplace.la libhbmgmtcommon_la_CFLAGS = $(INCLUDES) if MGMT_CLIENT_BUILD guilib_LTLIBRARIES = _pymgmt.la _pymgmt_la_SOURCES = pymgmt_wrap.c mgmt_client_lib.c mgmt_tls_lib.c mgmt_common_lib.c _pymgmt_la_CFLAGS = @PYTHON_INCLUDES@ -I$(top_builddir)/include -w _pymgmt_la_LDFLAGS = -module _pymgmt_la_LIBADD = $(GNUTLSLIBS) $(top_builddir)/replace/libreplace.la guilib_DATA = pymgmt.py pymgmt_wrap.c pymgmt.py: pymgmt.i $(SWIG) -python $^ endif #install-exec-local: # $(mkinstalldirs) $(DESTDIR)$(mgmtdir) # -chgrp $(apigid) $(DESTDIR)/$(mgmtdir) # chmod 770 $(DESTDIR)/$(mgmtdir) pacemaker-mgmt-pacemaker-mgmt-2.1.2/lib/mgmt/mgmt_client_lib.c000066400000000000000000000110561211477743100243160ustar00rootroot00000000000000/* * Client-side Linux HA management library * * Author: Huang Zhen * Copyright (C) 2005 International Business Machines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define ISCONNECTED() (session) int sock = 0; void* session = NULL; /* * return value * -1:can't connect to server * -2:auth failed * -3:protocol version mismatch * 0 :success */ int mgmt_connect(const char* server, const char* user , const char* passwd, const char* port) { struct sockaddr_in addr; char* msg; char* ret; int rv; /* if it has already connected, return fail */ if (ISCONNECTED()) { return -1; } /* create socket */ sock=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == -1 ) { return -1; } /* connect to server*/ memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(server); if (port == NULL || STRNCMP_CONST(port,"None")) { addr.sin_port = htons(PORT); } else { addr.sin_port = htons(atoi(port)); } if (connect(sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) { close(sock); return -1; } /* initialize GnuTls lib*/ if (tls_init_client() == -1) { return -1; } /* bind the socket to GnuTls lib */ session = tls_attach_client(sock); if (session == NULL) { close(sock); tls_close_client(); return -1; } /* login to server */ msg = mgmt_new_msg(MSG_LOGIN, user, passwd, MGMT_PROTOCOL_VERSION, NULL); ret = mgmt_sendmsg(msg); if (ret == NULL) { rv = -1; } else if (STRNCMP_CONST(ret,MSG_OK) == 0) { rv = 0; } else if (STRNCMP_CONST(ret,MSG_FAIL) == 0){ rv = -2; } else { rv = -3; } mgmt_del_msg(msg); mgmt_del_msg(ret); if (rv != 0) { close(sock); tls_close_client(); } return rv; } char* mgmt_sendmsg(const char* msg) { /* send the msg */ if (mgmt_session_sendmsg(session, msg) < 0) { return NULL; } /* get the result msg */ return mgmt_session_recvmsg(session); } char* mgmt_recvmsg(void) { return mgmt_session_recvmsg(session); } int mgmt_inputfd(void) { if (!ISCONNECTED()) { return -1; } return sock; } int mgmt_disconnect(void) { if (!ISCONNECTED()) { return -1; } if (session != NULL) { mgmt_session_sendmsg(session, MSG_LOGOUT); tls_detach(session); session = NULL; } if (sock != 0) { close(sock); sock = 0; } tls_close_client(); return 0; } int mgmt_session_sendmsg(void* session, const char* msg) { int len, ret, count = 0; if (session == NULL) { return -1; } /* send the msg, with the last zero */ /*len = strnlen(msg, MAX_MSGLEN)+1; if (len == MAX_MSGLEN + 1) { return -2; }*/ len = strlen(msg) + 1; while (count < len) { ret = tls_send(session, msg + count, len - count) ; if (ret < 0) { return -1; } else { count += ret; } } /* get the bytes sent */ return len; } char* mgmt_session_recvmsg(void* session) { char c; int cur = 0; int len = 0; char* buf = NULL; if (session == NULL) { return NULL; } while(1) { int rd = tls_recv(session, &c, 1); if (rd <= 0 && buf == NULL) { /* no msg or something wrong */ return NULL; } if (rd == 1) { /* read one char */ if (buf == NULL) { /* malloc buf */ buf = (char*)mgmt_malloc(INIT_SIZE); len = INIT_SIZE; } if (buf == NULL) { return NULL; } /* the buf is full, enlarge it */ if (cur == len) { buf = mgmt_realloc(buf, len+INC_SIZE); if (buf == NULL) { return NULL; } len += INC_SIZE; } buf[cur] = c; cur++; if (c == 0) { return buf; } } /* something wrong */ if (rd <= 0) { if(errno == EINTR) { continue; } mgmt_free(buf); return NULL; } } } pacemaker-mgmt-pacemaker-mgmt-2.1.2/lib/mgmt/mgmt_common_lib.c000066400000000000000000000103641211477743100243310ustar00rootroot00000000000000/* * Linux HA management common macros and functions * * Author: Huang Zhen * Copyright (C) 2005 International Business Machines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #include #include #include #include #include #include #include malloc_t malloc_f = NULL; realloc_t realloc_f = NULL; free_t free_f = NULL; char* mgmt_new_msg(const char* type, ...) { va_list ap; int len; char* buf; /* count the total len of fields */ len = strnlen(type, MAX_STRLEN)+1; va_start(ap,type); while(1) { char* arg = va_arg(ap, char*); if (arg == NULL) { break; } len += strnlen(arg, MAX_STRLEN)+1; } va_end(ap); /* alloc memory */ buf = (char*)mgmt_malloc(len+1); if (buf == NULL) { return NULL; } /* assign the first field */ snprintf(buf, len, "%s", type); /* then the others */ va_start(ap, type); while(1) { char* arg = va_arg(ap, char*); if (arg == NULL) { break; } strncat(buf, "\n", len-strlen(buf)-1); strncat(buf, arg, len-strlen(buf)-1); } va_end(ap); return buf; } char* mgmt_msg_append(char* msg, const char* append) { int msg_len; int append_len; int len; /*msg_len = strnlen(msg, MAX_MSGLEN);*/ msg_len = strlen(msg); if (append != NULL) { /*append_len = strnlen(append, MAX_STRLEN);*/ append_len = strlen(append); /* +2: one is the '\n', other is the end 0*/ len = msg_len+append_len+2; msg = (char*)mgmt_realloc(msg, len); strncat(msg, "\n", len-strlen(msg)-1); strncat(msg, append, len-strlen(msg)-1); } else { /* +2: one is the '\n', other is the end 0*/ len = msg_len+2; msg = (char*)mgmt_realloc(msg, len); strncat(msg, "\n", len-strlen(msg)-1); } return msg; } int mgmt_result_ok(char* msg) { int ret, num; char** args = mgmt_msg_args(msg, &num); if (args == NULL || num ==0) { ret = 0; } else if (STRNCMP_CONST(args[0], MSG_OK)!=0) { ret = 0; } else { ret = 1; } mgmt_del_args(args); return ret; } char** mgmt_msg_args(const char* msg, int* num) { char* p; char* buf; char** ret = NULL; int i,n; int len; if (msg == NULL) { return NULL; } /* alloc memory */ len = strnlen(msg, MAX_MSGLEN); buf = (char*)mgmt_malloc(len+1); if (buf == NULL) { return NULL; } strncpy(buf, msg, len); buf[len] = 0; /* find out how many fields first */ p = buf; n = 1; while(1) { p=strchr(p,'\n'); if (p != NULL) { p++; n++; } else { break; } } /* malloc the array for args */ ret = (char**)mgmt_malloc(sizeof(char*)*n); if (ret == NULL) { mgmt_free(buf); return NULL; } /* splite the string to fields */ ret[0] = buf; for (i = 1; i < n; i++) { ret[i] = strchr(ret[i-1],'\n'); *ret[i] = 0; ret[i]++; } if (num != NULL) { *num = n; } return ret; } void mgmt_del_msg(char* msg) { if (msg != NULL) { mgmt_free(msg); } } void mgmt_del_args(char** args) { if (args != NULL) { if (args[0] != NULL) { mgmt_free(args[0]); } mgmt_free(args); } } void mgmt_set_mem_funcs(malloc_t m, realloc_t r, free_t f) { malloc_f = m; realloc_f = r; free_f = f; } void* mgmt_malloc(size_t size) { if (malloc_f == NULL) { return malloc(size); } return (*malloc_f)(size); } void* mgmt_realloc(void* oldval, size_t newsize) { if (realloc_f == NULL) { return realloc(oldval, newsize); } return (*realloc_f)(oldval, newsize); } void mgmt_free(void *ptr) { if (free_f == NULL) { free(ptr); return; } (*free_f)(ptr); } pacemaker-mgmt-pacemaker-mgmt-2.1.2/lib/mgmt/mgmt_tls_lib.c000066400000000000000000000105271211477743100236440ustar00rootroot00000000000000/* * Linux HA management gnutls wrapper library * * Author: Huang Zhen * Copyright (C) 2005 International Business Machines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #include #include #include #include #include #include #include #define DH_BITS 1024 static gnutls_dh_params dh_params; gnutls_anon_server_credentials anoncred_server; gnutls_anon_client_credentials anoncred_client; const int kx_prio[] = { GNUTLS_KX_ANON_DH, 0 }; int tls_init_client(void) { gnutls_global_init(); gnutls_anon_allocate_client_credentials(&anoncred_client); return 0; } void* tls_attach_client(int sock) { int ret; gnutls_session* session = (gnutls_session*)gnutls_malloc(sizeof(gnutls_session)); gnutls_init(session, GNUTLS_CLIENT); #ifdef HAVE_GNUTLS_PRIORITY_SET_DIRECT /* http://www.manpagez.com/info/gnutls/gnutls-2.10.4/gnutls_81.php#Echo-Server-with-anonymous-authentication */ gnutls_priority_set_direct(*session, "NORMAL:+ANON-DH", NULL); #else gnutls_set_default_priority(*session); gnutls_kx_set_priority (*session, kx_prio); #endif gnutls_credentials_set(*session, GNUTLS_CRD_ANON, anoncred_client); gnutls_transport_set_ptr(*session, (gnutls_transport_ptr) GINT_TO_POINTER(sock)); ret = gnutls_handshake(*session); if (ret < 0) { fprintf(stderr, "*** Handshake failed\n"); gnutls_perror(ret); gnutls_deinit(*session); gnutls_free(session); return NULL; } return session; } ssize_t tls_send(void* s, const void *buf, size_t len) { gnutls_session* session = (gnutls_session*)s; while (1) { int ret = gnutls_record_send(*session, buf, len); if (ret != GNUTLS_E_INTERRUPTED && ret != GNUTLS_E_AGAIN) { return ret; } } } ssize_t tls_recv(void* s, void* buf, size_t len) { gnutls_session* session = (gnutls_session*)s; while (1) { int ret = gnutls_record_recv(*session, buf, len); if (ret != GNUTLS_E_INTERRUPTED && ret != GNUTLS_E_AGAIN) { return ret; } } } int tls_detach(void* s) { gnutls_session* session = (gnutls_session*)s; gnutls_bye(*session, GNUTLS_SHUT_RDWR); gnutls_deinit(*session); gnutls_free(session); return 0; } int tls_close_client(void) { gnutls_anon_free_client_credentials (anoncred_client); gnutls_global_deinit(); return 0; } int tls_init_server(void) { gnutls_global_init(); gnutls_anon_allocate_server_credentials (&anoncred_server); gnutls_dh_params_init(&dh_params); gnutls_dh_params_generate2(dh_params, DH_BITS); gnutls_anon_set_server_dh_params (anoncred_server, dh_params); return 0; } void* tls_attach_server(int sock) { int ret; gnutls_session* session = (gnutls_session*)gnutls_malloc(sizeof(gnutls_session)); gnutls_init(session, GNUTLS_SERVER); #ifdef HAVE_GNUTLS_PRIORITY_SET_DIRECT /* http://www.manpagez.com/info/gnutls/gnutls-2.10.4/gnutls_81.php#Echo-Server-with-anonymous-authentication */ gnutls_priority_set_direct(*session, "NORMAL:+ANON-DH", NULL); #else gnutls_set_default_priority(*session); gnutls_kx_set_priority (*session, kx_prio); #endif gnutls_credentials_set(*session, GNUTLS_CRD_ANON, anoncred_server); gnutls_dh_set_prime_bits(*session, DH_BITS); gnutls_transport_set_ptr(*session, (gnutls_transport_ptr) GINT_TO_POINTER(sock)); ret = gnutls_handshake(*session); if (ret < 0) { fprintf(stderr, "*** Handshake has failed (%s)\n\n", gnutls_strerror(ret)); gnutls_deinit(*session); gnutls_free(session); return NULL; } return session; } int tls_close_server(void) { gnutls_anon_free_server_credentials (anoncred_server); gnutls_global_deinit(); return 0; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/lib/mgmt/pymgmt.i000066400000000000000000000011301211477743100225010ustar00rootroot00000000000000%module pymgmt %newobject mgmt_recvmsg; %newobject mgmt_sendmsg; %newobject mgmt_thread_sendmsg; %{ #include "../../include/mgmt/mgmt_client.h" char* mgmt_thread_sendmsg(const char* msg) { char* ret_msg; Py_BEGIN_ALLOW_THREADS ret_msg = mgmt_sendmsg(msg); Py_END_ALLOW_THREADS return ret_msg; } %} int mgmt_connect(const char* server, const char* user, const char* passwd, const char* port); char* mgmt_sendmsg(const char* msg); char* mgmt_recvmsg(void); char* mgmt_thread_sendmsg(const char* msg); int mgmt_inputfd(void); int mgmt_disconnect(void); pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/000077500000000000000000000000001211477743100202515ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/.cvsignore000066400000000000000000000000631211477743100222500ustar00rootroot00000000000000Makefile.in Makefile .deps .libs *.la *.lo *.beam pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/Makefile.am000066400000000000000000000016121211477743100223050ustar00rootroot00000000000000# Author: Sun Jiang Dong # Copyright (c) 2004 International Business Machines # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in SUBDIRS = daemon if MGMT_CLIENT_BUILD SUBDIRS += client endif pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/000077500000000000000000000000001211477743100215275ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/.cvsignore000066400000000000000000000001061211477743100235240ustar00rootroot00000000000000Makefile.in Makefile .deps .libs *.la *.lo *.mo *.py *.beam mgmtdtest pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/Makefile.am000066400000000000000000000040001211477743100235550ustar00rootroot00000000000000# # heartbeat: Linux-HA heartbeat code # # Copyright (C) 2001 Michael Moerz # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in halibdir = $(libdir)/@HB_PKG@ guilibdir = @HA_DATADIR@/heartbeat-gui guilib_SCRIPTS = haclient.py mgmtcmd.py guilib_DATA = ha.png login.png logout.png exit.png \ standby-node.png active-node.png add-resource.png remove-resource.png \ start-resource.png stop-resource.png master-resource.png slave-resource.png \ default-resource.png up-resource.png down-resource.png cleanup-resource.png \ dirty-stopped.png failed.png running.png stopped.png starting.png stopping.png \ nodes.png node.png administration.png record-pending.png \ manage-resource.png unmanage-resource.png desktopdir = $(datadir)/applications desktop_DATA = crm_gui.desktop INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_builddir)/linux-ha -I$(top_srcdir)/linux-ha \ -I$(top_builddir)/libltdl -I$(top_srcdir)/libltdl MGMT_DIR = mgmt halib_PROGRAMS = mgmtdtest mgmtdtest_SOURCES = mgmtdtest.c mgmtdtest_LDADD = $(top_builddir)/lib/$(MGMT_DIR)/libhbmgmtclient.la \ $(top_builddir)/lib/$(MGMT_DIR)/libhbmgmttls.la \ $(top_builddir)/lib/$(MGMT_DIR)/libhbmgmtcommon.la mgmtdtest_LDFLAGS = $(GNUTLSLIBS) EXTRA_DIST = $(guilib_DATA) pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/active-node.png000066400000000000000000000006621211477743100244370ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞbKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÖ * FtŽ?IDATxÚíšÛ Â@ Dé›~y|ªbm!—I3¬(s<³«bfËäz,Ë`x­GE$¼Cš™ÐTöRU÷7ŽxÍPô©‡÷]KŽ¡½DЦÐ@fÀQ˜€€€àfujŽ,ŽÂȰ ¨µbÝ#õðëBö±uÕ1ùßß>¼tÓÛ¾tÑžKÀóSß! ÂHm‚ˆ¾!÷¯A½öøœ¯A=€S ÀÌÄóvÄ¥çßq’ML¶š j¬€7 gۻȂ½ʰ¡Ån0D«íp„vçÞ6´=ñ‚Ѐ=}¦Æujð–x‡oc@Dð"ƒÃ/Œðd‡4 ;<ŒÁa ¨ _j@uð2(ÁK–Zø4ƒ¿w•ü‹Ìð༡ÝDÌxpŽIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/add-resource.png000066400000000000000000000004001211477743100246040ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞbKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÖ &'„GÏ7IDATxÚíÛÑ €0 ÀFÜ[œ<ÝÀ~4¢{äãh(Iidæèœc4´Îùfñ¸cûŽÍ+à jGö§µxÅ<ÿuVû-€a¨¾¸ÇQ-ü0áÓ”è™ Þßs¬%ï¹IEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/administration.png000066400000000000000000000022061211477743100252620ustar00rootroot00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYsaa¨?§itIMEÕ %!€õ-UIDATHÇ•ÏOeÇ?³~hiZ’E FØØƒ‡z@å"!MŠÑЃ =Ê?`LÄ‹xð ñ Ý‹&FHiSZ‚°RŒÃËvvfwgvf^ÎLvÆ7yò¾ï¼ïóý>ß÷yŸw p{Àëß®;{®ó?š=™9=ÎøŽŽŠBߎç"‰F·=§ÍÍMaY–°,KbyyYbjjJd2‘N§E:ÓÓӮϣ€/: žÉx .øðð°GúàÁ¡ëºÐuÝ#H¥R" º{ðån„æL×9N£lüÀúú:Ñh”¡¡!$‰põêUb±±XŒx<γgÏØßß§®®Î•r*€äïáßÌóç/Ȧ™¦™eæñ#éÃÛwèïïçáÇôöör÷î]„øO¬Û»cI’ØÜÜ$Hr œmi}Mþ^/.ÐÝý###ôõõÑÛÛK"‘À¶m„‡ @’$Òé´ê;’‡”£ªÞé¥Ö¶klmEx÷íNÆÆÆ888 ›ÍbÛ¶g.;Îmòq7ÈB¡OOÓØPOGGTUUå)BPTT„eY'ˆÁ¯¹}ó~˜ 1ôñû¬­­ÑØØÈOŸråÊKtvv¢(Ê¡¸²,{k…Ä'_|KO× ¾ûù1%ç¨kjC–efggñ77³Ýe{gMÓ æÀçó‘J¥ æ@Üûfœž®ŒÿôˆŠêKÌOÿÊ?+‹\¾|™p8ÌÅK/ðÑ~¾þ’¦¦&EAUUTU%™L¢iÚñGôÖ›oœ qþb 3S¿ðãè½Cò…ÌÌÌÐüj áÅ"Û;LNNÒÓÓSPÍQß'Cìloç‚ `š&¦i"„ ¸¸˜ÙÙYZÛ® ±mI’<“eY– Ú@7pÓ™7"‰pÿþ}E¡¾¾¿ßOuu5‰D"/rÛ¶ÙÚÚ¢««+¯ÐÆË¿VB°±±ßïgnnŽææfPåÐýBPVV†$I§ÖAACC¡Pˆ[·nQZZJyy9•••yç.Ë2«««ÏMàs ÚÛÛ d³Y Ã@×õ¼èJJJ0MÓõ?ã;\ÎØ¶iš†ÁÒÒÑh”ùùy¢Ñ(+++$ )//?ú\”ȧD_ìX–åEZSSC2™¤¶¶Ã0¨­­eŸl6‹iš¹u Ÿ¦ È%È}k à “É`Yªªb©TʶmÛKßi ÎÄãqvwwH$hš†¦iìíí¡ª*±X ]׉Ç㨪š‹qᤗ ÀçÇüØO³Ï€阣N_œJ¹ì$ÞvL8J}9ªMgŸ’ÿ7¥ºˆƒê´IEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/cleanup-resource.png000066400000000000000000000011001211477743100255010ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞbKGDÿÿÿ ½§“ pHYs  šœtIMEÖ &ÛBG?ÍIDATxÚí›a®Ä „ é½7=¹ûk“—¦»¢0>õ*ƒ¢¢”RŽ•›‹· `7¹dªEåôèô/„ò* @èmC Ñ~ Ð Æöˆñ…È4f#4[‰uC`w‚]ø¥è¯PýMò¦‡Yy𫂍Žè ŽœÝá100|€|€¼}÷t5x9=x€Jð’ ~ä¤o o / /½©„ßÞJÁ·(ß ü{wñ_c‡— `À8·>ºÖÆ«áIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/dirty-stopped.png000066400000000000000000000031621211477743100250460ustar00rootroot00000000000000‰PNG  IHDRàw=øsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<ïIDATH‰•_l[WÇ?¾ÿü§Îu;qj§ÍŸ6k"ÉBÒLeC{Û¦nCE”J+°ñ¯Ù#*MÙ¨ö‚¦.MÓ!„xà”Ä@À-Œ—¾¤MÓô†š®¬q\7iì8Ží{}ï963QKÚ‰{ôÑ9:º¿ûÑ=çÞïñÔj5võ îúu]{Ø%„Œkšš.¹®˜.'§§.<ô€çA‚žÁ­š¦Ž„{>³ó}K<îki‰b64PX]åÎRétåúì‡N6››q…x19=5÷ zw=>¤iÚ‰/=÷¬¿¯·[«ÖªP«Q«Õ¨Vk(ŠÇŠGáj")ßýËß,!ÄáÄ¥‹?ÿTAÿî/œÝ?¹ß—ƒ€áº|Úz<4]§\¶ùíïþPL¥Ó—/œö‚Þ]u´mûöË_ :ŽÃJa…+W.cY6ÝÝ=´D£kEw¹šHøè ¡¡Ã0øÅøoŠÿ¾5wß›(÷¬ù‰ýûö-Û"·œcâü_?ð'Ž‘L&¸“¹”‚; ®&ŒŽŒòÒ7¾ÉùóäóËX¶Åþ}{ƒš¦õ n½O iÚéž{Æï5 –——™œœd軯Ðß?@0ä䨙ùàfoÜ`ff†±Ñ“˜¦Ißc}<ø ““Éçóx ƒö<ã×5íí5AÏÀàîH¸±§¯§[+¬H$üΟïëguµ@©T$à÷sòÄ[8ŽÃØè[ƒ(•Ь®®ðXï'’k×®QX-Ð×Û­†ÃÝõOèß¹£K·+6Âu±m›®®.¤ÔjUÊå>ŸcoŒ(•ŠÔj5¤t´·cYõúŠÍÎ]:РèºöDk,æsœ ²*éêÚÎá#‡(—˨Õ[Ù*‘_ÉQ*׿‚K%†0ÌÎ]ȪÄq*´Æb¾úωìŠF›±í BB¡Û:·qèð'Ÿ×r~_€R±ÈááClßÞIƒi"„À¶+D£Í»!d<2±m )%RJÌI$ÒÈÈè>Ÿ!Å:¼^ÇO' cšæZ­m[„B&BÈ8€¢ij:Ÿ_AUÔµ›²¹,KKK ˜r¹„b¥R‘#ÃGXZÊ‘Íf×jUE%Ÿ_¡žY(À¥……EtCGJÉrn™[§ysŸÏÇâÒ®p×q7»ˆaŒŽŒrëÖÙ\)%º¡³°°p @q]1‘Îdl¯áCJÁ\*ű7Žá÷ûIgR¸®ƒë:lÚØHÛ–6…6­ÍÝÎÌãõzyó8ó©y¤x éLÆ®§- pyöÆM×4MEÅð|ô¯ÐuƒjµŠã8D›7S±m^;ú*®ëÒÜÔ‚ã8T«5 ÃËìì,†¡£(*¦i2{㦠\Pï¤çS?ùéÏö„B ñöö6EJÁ¹sçhnnâ³~Ž@`VÙâèëGÑu3gÏðÔŸ¢qS˜¦H”‹S8õ«qÚÚÚhoïàŸ×gŵä?®\›šüÑZT¸B¼øÞ™÷-P‡#tt¶3>>ÎÔ¥‹‹«}ý‡l޵ÐÒÒÂæÍ-¼vôUÊV™ó“œúõ):;;ˆDš…÷μo !<4M¿õòàüü<Ùì©Ô<ŽãÅh0ÖÒt¥P “¹×ðljDšhmmå—ã§×¥éÿžÝ?ùÕ¯ìÝUÒéy¤”: PU•x¼Pxç÷,§Òé ®+žNNOU× z½@³†4]?ôüž§½}=ÝJ¡°‚eYX¶E¥RÁëõâ÷ùñûý˜fˆ«‰dõÏgÿ{x¸['“œž÷ ¢ÀyTÓÔï…ÃáØÎG¶«­±˜6³1"¿²ÂÂÂ"óéÛÕÙ›7«KK¹œ”òOÀ‡ÀÂ=|œœž*Ü+P& Vï#À°CSÕmg³2 ªª]«Õ²RÊÛÀpÈKuæ€Trzª¸nê"`A`#`ÖÇ: P,  €åzo%§§îÛ´ÿŸ¤,¦åukIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/down-resource.png000066400000000000000000000005431211477743100250330ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞbKGDÿÿÿ ½§“ pHYs  šœtIMEÖ & #Z”ðIDATxÚí›K„0…š{[ž ˆ ¬Z} x @Í‚7ëñ“r©þk,ðÎÕŸ »Þ¹úÓd¶À;W*€¬¸je¢æà- ^¡Õcc@–J­2 2ôëÊ}e©îò-°¢gO ´ð¼J"å ˆ‚æÕ*a@$,¯š˜¬¿ DCâ- Ôã;ZTvú]$(œ÷;Gã¯1Z4/Ï’s' ÞIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/exit.png000066400000000000000000000007161211477743100232120ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞbKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÖ *O%4[IDATxÚí›QÂ@DÁp0nf½7Ã/Sµ­º,lwöÓ¤Úy;ÃRÙÝiæu¡É̺$ê‹™9´Épw.ë€hñ-CFØ¥H¸R=£Ñn’‘›©êy|*ìYº‡èÙ;]*¿~ä¾5¬æøÖÎâëbᔘGáå¿ËŸ…›YhDâzeß [»}šfh‚ª’ª’™¥@"~¹>ª¨ Õ¯Å?\ÐJú< +û%¬w{«D¹¢T2¢Pb$ÖsÇKuƒë“ ãD8À¯Ç';ïŽ<¿:óòúyöØ%ŸàU%f&8E344€oêÅy0À’/3DÍ ZÜ»Œ(¼©ªvlŸD·¾_™Qt[ÖîåLîõ—™½‚•ÅTT¨?2£è”àI Øº÷>•&š[%bIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/expert-mode.png000066400000000000000000000022721211477743100244710ustar00rootroot00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  d_‘tIMEÖ!ót³FGIDATHǽ•]l“UÇo;¶1ÇØX6X'Ž #(´lÁJ¨P6>Cd¢‰ ‹ W:€3Ç7$+xc"ˆ€\,¸ †$Bb S\t Lבò± sÔnýZ7`ì«íö/h—®ë¦&ê¹99ÏûžÿïüŸsžsà?nJ¼ B…‡ïMªªÖýkT!„ôy=2’--7¥BVTT”N´ ˜ë¢º ~4|vøs¤¦‘k0PV¶™ÔÔÔs€œRT^“óÒž“ZQy͉‰ŠÂ ªª0X÷ 04H~~þ¤i-*¯1®ÓU/óæÚ‚YEå5u±¥²²RlBˆ}ˆÙlFQÆ™Ôâ°5ÛB{{;KŸZœž’Pùî§èõúwî(G§O|¨\¸p!óRCQ‚þŸ…FUU›£•o«6tttÐÝÝÍÎc­†qv=jß°~Ý“))S ƒH)‘RŽ ¥¥gPUe0„SÈüö“g`$VC?™¸¿Óéz±x.%Ë ÈNƒê³6}7YSRÊà@?ƒý¬))¥¾¾¾Âb±|]__ïù[€ˆø¦Õóxm½—ÓABÊt´À]Î^ö2ྲÃb±œ‰…è&ß¾qÛ6®àÛºïh¼é$#;—´Œ,Óf˜TU%3k&Ý]^^ÀØböd, "¾ç 3[J—rêL¿Ü¸ƒy……;¸Ñéõ蓦áõzýÁ`°0$))i D}aù;.õ­gØ´º§ÏÓît±ªt=­­mxœmüt[G¢ÖýÄ‘#GîZ­Öß<9 ƒlÝú:»wï°ø;¶·_}š –EÔžýžv§‹åÏÓÒr—ã ­!_“iÀïHf™v»=d·ÛKUUÅ;›C‡ÑÛÛ;F;!:Eysf3¢I|íãÄû~¿`ñ·\ …'fºK—. î¾¾¾Í<ÙÓÓƒ¦iWB¡5R£u0§Ä*×.3`*417'«×os¥±‘†VÇÅe¾ëü1®µ¨ù#@膀ápldÔÁŒY9‹Ï5¸š" 裡U#I×oÑ2rïþ¨âŒG^8-,8%.ÇUòâmÕ¦»)2N–øØµÚ O̽¢Äée”+-<–üíOQ4²ì4¥IEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/failed.png000066400000000000000000000023471211477743100234670ustar00rootroot00000000000000‰PNG  IHDRàw=øsBIT|dˆtEXtSoftwarewww.inkscape.org›î<yIDATH‰µ•MlUE†Ÿ9sîOÛÛö¶·´¥ô‡ÒZªˆhPKÒ@‚]qáN1ˆ v’hŠºÔ¸)±Æ„ð+‹$`š–¦PPÀJméßá¶½åž3sÆÅ½½iÔ8É›™Ìä|ï|ßûžo„1†ÿsØO:l" l—BÔm{¯§õF€€”}®RmÚ˜KÀÅÆ8+Å+epBˆ&;ø¾bëÖ`lýz+ºa9Ìãôõ1u÷®?ÔÝí*×}ç-cZŸ‰ Eˆ¢m·æ”—ïxíàA™‰€ëb’IÌÇ©B!D8 ‰ÍÍz~xø·¤RMŒ™\‘ Eˆ"Û¶ÿxaÿþ¼ê={Àq0Ί٧D£òç¹s\;y2®”ªYJ²Lƒm·>¿o_Þº†ü{÷0ž÷Äàfbá8¬khßÏ»qêT+°kñÜZ\œ¢)»´tGuc#zp“H€ç=L"`íîÝ䔕í8!DÓ²µ í:|8œ¥5fzú©7l¹ Y°mÚ}èyÞêÆ8‹l/«­ dgeáa\÷_Á#;fõ¦M`{F)D}¬²R&ÇǹÙÑÁÄýûh­Ak´RøÊC{ _)0!@ˆÌ PV³Žç,‹XE…¹zµ8km{o~e%ÝgÎ`mªeóñfdN6V0ˆ a…BÈP ",+Eâû©Ù0ßu¹óù1®ýrŽÚÆF‚¶½øÔð´Þ).fzt”úŸ~$«¼ü)Å)SËE·ƒT¿÷.¾ýŽHI ‹}ÆEF) ÀèM*LJ—ÙÛ‚To™"ºjýÇ¿"9>Žç8èùyü¤‹ÑzY £:‘À›™!9>ÎÂà ñÞkÜ:t„¢âbf‡†HÙi‘]¥ÚœÁÁÍ/oÛÆõö_¹ðC+ø>¾Öø¾Ñc –”©Ú–m#mKJ„m#¥¤è:}Ú7%%`YÏûGÀ²0¥¥\>{Ö¿­Ô'Í`„öbÁ mæÁƒ®;ÈššÔî 7}€¬©áNg'33=ŸA;›|£õÇ·¯\IÜêíŪ«C>µÑ‰‚¬º:nõör»§'ñ…ÖG–:W¤… Q o T¾/å±¢ÜÜ—^Ù¹ÓÊ 0Žƒ™ŸÇÌÍ rr‘"?ŸY­é>Þǯ©õ‘0 ĘÊ<8KH"@äCØÿª”‡Š×¬± b1+?#¯ €¸ãð`r’é©)ÿþè¨ú]©c_ÃÏÀ\S@Üc–½h"å¿0ä¼Åo¶5Bl]-åë–ïWø–54¢uÇ1=ípù&Lóé[ÏcT&æJ¾Â‚@ -X (ÀKÃ’Kƒ.ãû¢Mß±IEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/ha.png000066400000000000000000000141621211477743100226310ustar00rootroot00000000000000‰PNG  IHDRbc`ùÕ« pHYsÃÃÇo¨d$IDATxœìœiX•åºÇÿ ‹ÑÄœPqH­Ä¡¶8VÍ0Ì´måFm2í:´½M½ô˜©©;·Ó©°:j&f˜s™–¦ûˆá<  iÈ<-ÖZÿóá^¯›õ¾ÏDÜùá¾üàzîßû<Ïÿž$Q#fµ’f3Y\,ÿÚlb5õüZn·÷6›8ý×_É5kÈgž!$§O'Ïœ!óóïÁ¸­ l6²°LJ"ÿñ²_?²Ay@}úŸN^¼HZ­x Õë|«•ÌË#Ï#gÏgkÎ/o®®dÆäèÑä¶mäo¿ÉõµÀ)wmž7›É¬,rï^rêT²];Ò××1„²æéI[H­Ó¦Ñº?YZú‡U»ÕJ^½J&$ãǓ͛«9¿¼¹¸žžäŸþD¾ÿ>™’"@jƒj?³™ÌÈ -"#"* ¢éÊߟŒŠ"×®%srH‹å¤j 23ÉeËÈÁƒ«@@ Àâöí™ÿÊ+,NN¦¥¸øßFÕ@dd ÀŸ¾ °Àf¡¡1aOŸ?ÿo¡j JJd¡~õU²U«J°Ìxàt€=Ân:tà¤I“˜’’r„®‘©©äsÏ‘NA°,x àû¬gàââBoooöíÛ—óçÏç•+WîеÂB‘™#FˆÒQP0 à €ƒ6,3 Ê‚0`—.]Ê«W¯Þ¡kYYä¡Cä!d:¯MA¥o\ð™rÎ/knnnlР£££¹qãFfddÜQ¡iÑô¯¿’»vIÉËË!Íò&|Á¾ë âØ±c¹k×.feeÝá„Å"ÓÒš5d÷î€ÈxàhîîîlÚ¬'MšÄ¤¤$æççëƒÐÞ'?_Ò,……weT^ygÏ’}DÞ¿!Ìø#À'+Xʃfll,SRRXTT䨩%%"¡¿ÿžœ;—Œ‰‘lïáÃR÷¸‹’ˆ•a6“‰‰RWhÛV€¶Füp3Àž=u@˜L&†††rÞ¼y,(( ¥¢‡Ù,Òù«¯È‰ÉÒÃCR$õê‘O?M~öùË/dIÉ]£Æ@¤ü+èððð`çιdÉZ,Ú´L¬Õ*_ù… äÆä³Ï’-[Vü\WW²iSò7È;Uå@‘ß}G¾ðÙ¬™! $fX°ôööfDDW¯^}ËqyyRÑûøcòÉ'%ÅîêªûÜ›NΚEž>MÔZ•±s§|•‚(Ä ¶5áëëËÇ{ŒkÖ¬‘…79YòYýúÉ´£âüòæïOJ~ò yù²ŒèZàüê‘@öïÿû¨ˆcë@puueƒÀ@Žyé%~óÕWä‰䨱ާ g­U+rÌr÷nòÚ5™®jIªr rrÈuëÈ=H??Ý?^‹¦w|`3&“‰Mš6å«S¦ð»M›D õïOÖ¯_- l‹¼½™Ö¡SgÌàõädš‹‹i#ï8 ç/Òªr+VíÛFÕˆ­G ÒáååÅ6mÛrÖûï3ñÛoÉ-[ÈÎÕס²N} ði€Ñ½zñ½÷Þczz:­µ@æVDj*ùÁ¢L ¢j+$˜[ðq€ t@øúú2¬S'.\¶Œ?ïÙ#ê¨}û*AÈxàÇŸ²?ß `HHGÃòÆw›M¢Ö“'É™3eZrwwèM1eÙÑ `uëÖe÷àç6ðRb"¹~½4"T@$¥²DÖ-÷,vëÖ‹/æ‰'îBZ 1eŠRjà ælÐ[D}??öèÕ‹ÿÏK?ü Ó_ëÖÊÎ× LÇ R¹Á ¼ï>FÁ­[·²´´ôVÌRëAhAÕþýRRpN)ÀHáÇ×>-8tLÆì?h·oßÎŒ;È¿þU)N±Ùœ8`?€>]tž¥M…]ºtáüùóyþüyšï ¬uDQ‘È¿˜%f€§þ@wç4oÞœQQQüqÏf'$ìFtïo…ÈcM•8¿¼\öññatt4ããã™——w—€°X¤“oýz)@ÐbˆŸ¾©à˜6mÚðå_äÏû÷³díZ22Ò0N1¼ð3ˆªïÍzöìÉ9sæðêÕ«,½C™[çAääÈÜýè£J Š Y×qÎpرcG¾þæ›<›˜Hk\œR ¡XpôÅ€#kÔ¨‡ÎmÛ¶ñÚµkwˆÒR2;›\²DR 4Åô%ÀHg¸»»óÁ^½ø·Ù³y)9YÒÙ:‘>>º ‹¦AjßáµÁY ãìÙ³yìØ±»„ÖTöÎ;Juˆ€×®8LÇZúá~ýøßóç3íèQrÎò¾ûtå1í#î,Àw¶´ƒp­ŒÀÀ@>õÔSüúë¯YPPPãAžsh…˜É“•ô}!À‹gì¥bð!\ñÑG¼väùöÛ†÷מq’Çj УÉú¶k׎sæÌá©S§j\A9wAQ™–FŽ¥ÔBS‘®oì¢ãWWWÖ«WOFFrí_0ýðaÚÞzë¦4Õ{F¤ûD1éÉc5räHÆÇÇ—hï(ˆü|Ùû0l˜îÜ]Äy€/A?ë ºzz2¬[7¾Ãs Ði8-Ò”ðÀ U¡Y×®]ËÔÔT×`Ï­säåIEa¡Öœ” pô“}7¿J€nn|5(ˆ»hsw§+8zF6ÀoF£òëCYóóó〸qãF¦¥¥ÕR™™ääÃ+Èxéê•GËZ=HË͈ê2šš2~ð±*(kÁÁÁœ6mkm[ÖåËä×_“=¤"à·VaØàüAD)$µ`ÿjÀÇœëÖ­cVVV((uZ ÍÊ•ÊÝß—!1„ÞB]Ö|†œ ð¨Âý‹!b`vuðòòbpH§NÊC‡±¤:Aœ‘”$› jšÚI¸`w¨Íݾ;Ù¿ðÓ #¢CLø $—Uþž ™ß`ܪG轇‹‹ M&‡ʸ¸¸QPê ÌfòàAI+¶áçÙ: úqÄÍ)`oHÞè¢Âý 1ÄTH­£¢{z@¦»h€/õ4H§N8yòdž9s†·¹DDQ‘ôºFGKeNÁQ„s5ëÈó$dtoM LØ^D($ ÿ)dkµêïïÏ2>>þ¶+(ç@lÛ&1DP2­JWYXõ¢ìF‡ü’£Ò»§ ¢˜~ø<$ªv" àb€ÿð }tèõß–µÆÆÆÞvåˆ ÈnÝ*ÝUaµ;xDn”û£[|Öî¬|…ûimœÃí_yEެ Y?–|[6Ϩ†ÒRéA>¬[W)猕@ ÿßÜÙâ¥r]2¤Y ©Ž›AŠRßA"}íÚ û³‡ˆ#¾¾¾ìÕ«ãââxáÂ…;Âj•=o¾)ÚhjÂþ ‰!ôÙà‹TyN™km©ñCÈÔ¨2=5oÞœ¯½ö÷íÛG³Ù\­í7j Š‹Éo¿%Ç«´ÎïN‚þ¤0ûoÎA"ñ²÷É…HÚq)Ìú‹w½úõÙ#<œ+V¬àåË—«u­P±i“„î0„²'l-ãDGÎ{àLHɶü½,èÿ3H)רÞíææF___Nœ8‘{öì©Ö”ñ´‚«W“O<¡ä(-šÎ·…*élgLÛ*¼²UØOÇy}!Ò5Žë‡!iÕ…{àÀ\ºt)³³³«mTÿ¨´”ÌÍ•Sh 2t’vªÀ!€ŸØÿÀ Õ¸ÕB³ ÒBS¾¯µ<ˆ¿CçŠ>-®Ùm‡ª§À4 iÙ’cÇŽebbbµ50«ÈÉ!çÍ#{÷VQ©C¼iøQ(Õ¢’Ù] Ùé(p‡Ä kíÎÖ•—!#çagg===Ù½{w~øá‡<}út °XdDÌœ){ª œd¨“o 9 Hãñ ûüK5€ÐÒ߃ãÎ w€÷p~¯˜Ê›–® j#7iÂçFâ¶mÛ˜ŸŸ_eeü£âbi¡™2E©…Æ©#o€Ôªµ7AdædˆÚ©ÊºQIO,ÔÕ!4ãíÏ«(wõ›R ÀP[4«S§;wîÌ… òìÙ³U^+Œ”›+ þ³Rú[k*[ðÑr/¯ŽÁ?BåF‡ 2õLyADжø$‰X`¿^Û=´’–o õ4GE êå—_æöíÛ«¬ ÿ§væFVyô¨4(øRîìíà0lêâ©>><àããt¨²5FÇQÞí\ÜŠ!2¤¡Öºod\´h333«ÔÀl "=üñG9·O'Ù§)€W!ïý^ÞÅÝu8|È~ñÆÒÕײ¥ò^¹HîH¯Ÿ¶¤î±AƒÄôª¢óËZ“&MÍýû÷Wé$}V«lƒÝ¹SI12_„ {G›ÛM&qÌ_þÂÍ›7“—.É^ˆÐP¥gdÜ©C˜ p¤A¹|ý£:ÌÍÍíæZqòäÉÛÂb‘ËM›d+¯Žs´‘ÉûGÃqS™Édb£ÆùÚë¯s÷îÝr òôéJª¬R‡XIo;r¶X7FõtªŒŠ­[·277·R ÊÄ… U+8‰iã(ÀÿÀ­ãáÊ›——CZ¶ä´3x`ß>iÓ7N©)¡2âB½Êv»ÍÛÛ›!!!œ;w.O:U)e "9Y‚¹°0%™±7'Ð|||ؾ}{.X¼˜É‰‰rÂÀ¨Qºª¬ì^¹“šîµBY{þùç¹yóæJu’ëƒ0›å¸¸ØXÃSh4K‡äþÔyá:uê°Ëý÷sU\Ï'%‘?ýDöí«tžxÀD€!ÚÿN;¿¬õèу3fÌ`jj* ‚a bï^9¿ÂàÜo-+š0`WöóócxÏžÜÀkçΉ* Wªüݸ"][Õç—µÀÀ@>œ;vìpz ˜>ˆ’9è™g”O¡9‘Œa/ÜÀîþáæ^º$m:]»*É×ëwAÒz•¹;annnìØ±#gΜÉcÇŽýþ¼©*(,”SÂÂà Õ"ÞŸ Û¨ô¾Ö F8dèP:z”¥iiÒ¦Ó±£ÒÔwàvHtîÌV^§ ‰¶ØŸáõvÿÆ322’ ¼qãF5ÈÏ'¿ø‚ìÐAjÕ öB*bÁ:/Û¬Y3FFE1)9™Ö3gdã¢ât’ê‰Êí 52WHy5rlÅB€@¿æQÖ<==ÄY³fñĉÊäú ²²ÈåË¥ÉÍM×AÚá'[ Yׯ:/Û¢E Ž9’Ç'!ß}Wú¥ @Ûp«…¦#*¿_®"3AJ®/ÙA§ãV)u w:²¨¨(~ùå—Êi}²•WáKÕ@ÄCbGÓ†»»ûÍíQçÏŸU6mÙ¢…Òs’í_i»jÑ’.Ù‰Q´Ì° à%È9"áNÞ³uëÖŒ‰‰aRR³³³ aèƒÈΖý-4šbʆ4úvGÅU3m÷hï>}8{î\^¼tITÙ¸qJbÀ)kÎFõ,ÔÚ¡(Ÿ¿õÓ&Ndipð¿äÓnÜåPO6mÚ”£GV®â郰XÈãÇ¥±Ì`1ÕFÄ2Hj£¢¯U1hÐ þϪUüåÊé=Ú°±YSe{ ­š*{ò*\ì-”Æ ãÊ•+™’’‚¬,9št×.ò•W¤îbÿð̬í"HõÎhúûû³OŸ>\°`Áÿ·w~1Ma“i0Wÿ\,\Hva¯ˆFüBŒQ—q¡.ÎÍ.Æ ¼R9$¬¦Kˆ¦±12oªÙ…¬Áá"Ä]Ô¶$ÆÕJFZjµÖVþÛž]¼[Åž¶Ê,]½xïN““óëùÎ÷½Ïó=l6[òÈÔ´AÈ%ätù2·Â@x‰‡d ä¡©n÷nüÚÛ‹é‰ ž•íߟ²Å.ƒø“ljûH¿k×¢¶¶f³‡sssñ©Ümöz}IˆõRJ>ƒÚ¶m:::àp82v¦w¡lB¾s'鎡qRØiâÙÌ»šlõõõ8o6cÊë…øä ÷±jjR:Ì%âöÆï¢¸¸[¶lÁ`€ÝnO,‰p#Òj}ówAλ‰3¨ÂÂBTTT@ŒŒŒ  .sÓ/Ù €Å‹¼„‡$·ZhiZ­ÆÖ­[a4a³Ù’qý~66WW+NÓö#þ°~‘&„êêj‚»ÝžÖGózõЇ¬k×:zC6à• _Òb£¯¼­mmB0ü ´‚Ì$¯/nÝz„,µ†‰wïÈA«ÕbóæÍ0¸}û6fffâãe4 LMÝݬC¤Ø@%Vþ~!n'ëìÒâCÒét8qâ …Þ_S–u™‰ Œ_½ŠŸÂ÷{öà‡cÇÐ?0€É©©ŒVÐË"ñßâ÷W® vàÂÄS×o‰õ†;vÀ`0àáLJÃK‡‚h”¡3gx QX¨"BqË‹’…†ˆ÷I766Âf³-k–8?ïä$»Ý˜žž^Bþ·ÌÎ"22‚@{;.o܈Sz=ÚNŸÆ_wï"'¿IQ ­Û')æ"±öÜAÜ>ùŒ’4+«ªpòÔ)x<ž%ú߃X,Iyö þÑQøœN„ÂáÔ+JQ䯖–´@Ì+rÒz½^Aò€øô/±’]+.{ã½§áà˜%޵>®ð6Èû£wîÜ “É„§OŸf5¹2; 2)Ibg?pøpJXœ á;…7A^¬íÛ·—.]B È ÙÏŸsû;a¬TabþÁ4@444Àb±äÔùDÙá÷ó1{÷¦"D¼¾A„J¥ÂêÕ«qäÈôõõñze<ä• "a¿Ô… i8¥¸ ¿^„Z­ÆºuëÐÔÔ«Õú DÊšÆÆX‡PðK%žaç%n¼Õ(€(((@YYš››1<<üÑãàrÄ£G|àleeR‰3&'N«eÉ@¬Zµ åååhooǽ{÷2vRä'— hmåó!Òø>؈ð#)[h4 t::;;ár¹>j&_n‚³=FGAà^“B¬„l¡9HÊ‚PQQôz=Ξ= Ç“ÕÐõÜ!ÈÅ8žÎjeM"‰8ä'Ö!ö²s£¨¨•UU8wî|>_Ör¾s D"ùyVÝoÉ•^"üNlãüœÞ½9eýúõ¨««Coo/ÆÆÆ IRάªWÆÂŸj±ðL*¡->I¬Cèhik£¤¤»ví‚Ùl†Ûí~SuË¡Êú ,òò%pó&K•¥¥€J…ˆ-4_Q¼§$kß&“ ããã%1@È0b1Þ·wñ"°iîk4è&6­iµZlß¾===xðàÁ²gb|ñvI¤/ ^¿Ž[MMøiÍ|­×£«« N§3+‰öù  I’ Š"‚>¼.»Ý¯ÅùÿÃ[3 ä’üŠ8E1oAäCeý>ƒø†äxWsiIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/haclient.glade000066400000000000000000004043471211477743100243300ustar00rootroot00000000000000 True GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False True False 0 True True True True GTK_POS_TOP False False 5 True 1 2 False 0 0 False True True Informations False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab 5 True 1 2 False 0 0 False True True Configurations False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab 5 True 1 2 False 0 0 False True True Advanced False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab 10 True True True GTK_BUTTONBOX_END 0 True True True Apply True GTK_RELIEF_NORMAL True True True True Reset True GTK_RELIEF_NORMAL True True True True Default True GTK_RELIEF_NORMAL True 0 False False True GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False True False 0 5 168 214 True 8 2 False 0 0 True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 1 2 4 5 10 True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 1 2 5 6 10 True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 1 2 6 7 10 True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 1 2 7 8 10 True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 1 2 3 4 10 True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 1 2 2 3 10 True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 1 2 1 2 10 True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 1 2 0 1 10 True True False True label106 False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 1 2 10 True True False True label107 False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 2 3 10 True True False True label108 False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 3 4 10 True True False True label109 False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 4 5 10 True True False True label110 False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 5 6 10 True True False True label111 False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 6 7 10 True True False True label112 False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 7 8 10 True True False True label105 False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 0 1 10 10 True True True GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False True No Data Available False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 True GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False True False 0 True False 0 True Current Running on False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 False False True False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 False False 0 False True True True True True GTK_POS_TOP False False True False 0 True 0 0.5 GTK_SHADOW_ETCHED_IN True 0.5 0.5 1 1 0 0 12 0 True 2 4 False 0 10 True Resource ID: False False GTK_JUSTIFY_LEFT False False 0 0.5 10 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 0 1 fill True Class: False False GTK_JUSTIFY_LEFT False False 0 0.5 10 0 PANGO_ELLIPSIZE_NONE -1 False 0 2 3 0 1 fill True Type: False False GTK_JUSTIFY_LEFT False False 0 0.5 10 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 1 2 fill True Provider: False False GTK_JUSTIFY_LEFT False False 0 0.5 10 0 PANGO_ELLIPSIZE_NONE -1 False 0 2 3 1 2 fill True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 1 2 0 1 fill True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 1 2 1 2 fill True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 3 4 0 1 fill True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 3 4 1 2 fill 0 False False True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True False False True False False False 0 True True True GTK_BUTTONBOX_END 0 True True True Add Attribute True GTK_RELIEF_NORMAL True True True True Delete Attribute True GTK_RELIEF_NORMAL True 0 False False False True True Attributes False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab True False 0 True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True False False True False False False 0 True True True GTK_BUTTONBOX_END 0 True True True Add Parameter True GTK_RELIEF_NORMAL True True True True Delete Parameter True GTK_RELIEF_NORMAL True 0 False True False True True Parameters False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab True False 0 True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True False False True False False False 0 True True True GTK_BUTTONBOX_END 0 True True True Add Operation True GTK_RELIEF_NORMAL True True True True Delete Operation True GTK_RELIEF_NORMAL True 0 False True False True True Operations False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab 0 True True True GTK_BUTTONBOX_END 0 True True True Apply True GTK_RELIEF_NORMAL True True True True Reset True GTK_RELIEF_NORMAL True 0 False True True GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False True False 0 True 1 4 False 0 0 True True True True 0 resource_ True * False 1 2 0 1 10 True Resource ID: False False GTK_JUSTIFY_LEFT False False 1 0.5 10 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 0 1 fill True Belong to group: (type for new one) False False GTK_JUSTIFY_LEFT False False 1 0.5 10 0 PANGO_ELLIPSIZE_NONE -1 False 0 2 3 0 1 fill True False True True 3 4 0 1 fill 10 False True 150 True 0 0.5 GTK_SHADOW_ETCHED_IN True 0.5 0.5 1 1 0 0 12 0 True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True False False True False False False True Type(double click for detail): False True GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 label_item 0 True True 150 True 0 0.5 GTK_SHADOW_ETCHED_IN 200 True 0.5 0.5 1 1 0 0 12 0 True False 0 True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True False False True False False False 0 True True True GTK_BUTTONBOX_END 0 True True True Add Parameter True GTK_RELIEF_NORMAL True True True True Delete Parameter True GTK_RELIEF_NORMAL True 0 False True True Parameters: False True GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 label_item 0 True True True 0 0.5 GTK_SHADOW_ETCHED_IN True 0.5 0.5 1 1 0 0 12 0 True 3 4 False 0 0 True clone_max: False False GTK_JUSTIFY_LEFT False False 1 0.5 10 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 1 2 10 fill True Clone or Master/Slave ID: False False GTK_JUSTIFY_LEFT False False 1 0.5 10 10 PANGO_ELLIPSIZE_NONE -1 False 0 2 3 0 1 10 fill True clone_node_max: False False GTK_JUSTIFY_LEFT False False 1 0.5 10 0 PANGO_ELLIPSIZE_NONE -1 False 0 2 3 1 2 10 fill True master_max: False False GTK_JUSTIFY_LEFT False False 1 0.5 10 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 2 3 10 fill True master_node_max: False False GTK_JUSTIFY_LEFT False False 1 0.5 10 0 PANGO_ELLIPSIZE_NONE -1 False 0 2 3 2 3 10 fill True True Clone True GTK_RELIEF_NORMAL True False False True 0 1 0 1 10 fill True True True True 0 True * False 3 4 0 1 10 True True True True 0 True * False 3 4 1 2 10 True True True True 0 True * False 3 4 2 3 10 True True True True 0 True * False 1 2 1 2 10 True True True True 0 True * False 1 2 2 3 10 True True Master/Slave True GTK_RELIEF_NORMAL True False False True 1 2 0 1 10 fill True If belong to a clone or master/slave: False True GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 label_item 0 False True True GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False True True True 0 0.5 GTK_SHADOW_IN True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_NONE GTK_CORNER_TOP_LEFT True True True False False True False False False True False True 0 0.5 GTK_SHADOW_IN True True True GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False 5 True 3 2 False 5 10 True Server(:port): False False GTK_JUSTIFY_LEFT False False 0 0.5 5 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 0 1 fill True User Name: False False GTK_JUSTIFY_LEFT False False 0 0.5 5 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 1 2 fill True Password: False False GTK_JUSTIFY_LEFT False False 0 0.5 5 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 2 3 fill True True True True 0 True * False 1 2 0 1 True True True True 0 True * False 1 2 1 2 True True True False 0 True * False 1 2 2 3 True GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False True False 0 True 0 0.5 GTK_SHADOW_ETCHED_IN True 0.5 0.5 1 1 0 0 12 0 True 2 4 False 10 0 True ID: False False GTK_JUSTIFY_LEFT False False 0 0.5 10 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 0 1 fill True Score: False False GTK_JUSTIFY_LEFT False False 0 0.5 10 0 PANGO_ELLIPSIZE_NONE -1 False 0 2 3 0 1 fill True Resource: False False GTK_JUSTIFY_LEFT False False 0 0.5 10 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 1 2 fill True Boolean OP: False False GTK_JUSTIFY_LEFT False False 0 0.5 10 0 PANGO_ELLIPSIZE_NONE -1 False 0 2 3 1 2 fill True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 1 2 0 1 fill 115 True False True True 1 2 1 2 115 True INFINITY 100 -INFINITY False True True 3 4 0 1 115 True and or False True True 3 4 1 2 True Attributes: False True GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 label_item 0 False False True 0 0.5 GTK_SHADOW_ETCHED_IN True 0.5 0.5 1 1 0 0 12 0 True False 0 True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True False False True False False False 0 True True True GTK_BUTTONBOX_END 0 True True True Add Expression True GTK_RELIEF_NORMAL True True True True Delete Expression True GTK_RELIEF_NORMAL True 0 False True True Expressions: False True GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 label_item 0 True True True GTK_BUTTONBOX_END 0 True True True Apply True GTK_RELIEF_NORMAL True True True True Reset True GTK_RELIEF_NORMAL True 0 False False True GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False 5 True False 0 True False 0 0 True True True GTK_BUTTONBOX_END 0 True True True Apply True GTK_RELIEF_NORMAL True True True True Reset True GTK_RELIEF_NORMAL True 0 False False True GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False True False 0 True 0.5 0.5 1 1 0 0 12 0 True 1 4 True 0 10 True ID: False False GTK_JUSTIFY_LEFT False False 1 0.5 10 0 PANGO_ELLIPSIZE_NONE -1 False 0 0 1 0 1 fill True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 1 2 0 1 fill True Type: False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 2 3 0 1 fill True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 3 4 0 1 fill 0 False False True True True True GTK_POS_TOP False False True False 0 True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True False False True False False False 0 True True True GTK_BUTTONBOX_END 0 True True True Add Attribute True GTK_RELIEF_NORMAL True True True True Delete Attribute True GTK_RELIEF_NORMAL True 0 False False GTK_PACK_END False True True Attributes False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab True False 0 True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True False False True False False False 0 True True True GTK_BUTTONBOX_END 0 True True True Add Parameter True GTK_RELIEF_NORMAL True True True True Delete Parameter True GTK_RELIEF_NORMAL True 0 False True False True True Parameters False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 PANGO_ELLIPSIZE_NONE -1 False 0 tab 0 True True True GTK_BUTTONBOX_END 0 True True True Apply True GTK_RELIEF_NORMAL True True True True Reset True GTK_RELIEF_NORMAL True 0 False True pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/haclient.py.in000077500000000000000000012436021211477743100243100ustar00rootroot00000000000000#!@PYTHON@ '''haclient.py, the GUI manamgement tool for Linux-HA ''' __authors__ =''' Gao,Yan Huang Zhen , 2005-2006 ''' __copyright__=''' Copyright (C) 2007-2012 Gao,Yan Copyright (C) 2005-2006 International Business Machines ''' __license__ = ''' This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ''' import sys, os, string, socket, syslog, webbrowser, pickle, xml, gc, time, binascii, thread, tarfile, tempfile from stat import * from xml.dom.minidom import parseString from xml.dom.minidom import getDOMImplementation import re import locale, gettext app_name = "haclient" sys.path.append("@HA_DATADIR@/heartbeat-gui") sys.path.append("@LIBDIR@/heartbeat-gui") from pymgmt import * import pygtk pygtk.require('2.0') import gtk, gobject support_pyxml = False try: from xml.parsers.xmlproc.xmldtd import load_dtd_string support_pyxml = True except ImportError : pass support_lxml = False try : from lxml import etree support_lxml = True except ImportError : pass support_gv = False try : import gv support_gv = True except ImportError : pass validate_type = "dtd" mode_level = 0 name_cap = lambda name: name.replace("-"," ").replace("_"," ").title().replace("Crmd","CRMD").\ replace("Crm","CRM").replace("Pe ", "PE ").replace("Dc ","DC ").\ replace("Cib", "CIB").replace("Ccm", "CCM").replace("Ha", "HA").\ replace("Id", "ID").replace("Dtd", "DTD").replace("Uuid", "UUID").\ replace("HAve", "Have").replace("Op ", "Operation ").replace("Rsc", "Resource").\ replace("Lrm", "LRM").replace("Acl", "ACL") window = None manager = None debug_level = 0 top_window = None last_rsc_view_page_num = 0 last_compound_view_page_num = 0 last_cluster_view_page_num = 0 def log(string) : syslog.syslog(string) if debug_level > 0 : print string def debug(string) : if debug_level == 0 : return syslog.syslog(string) print string # If the built-in uuid module is available, don't use the external command uuidgen try : import uuid def gen_uuid() : return str(uuid.uuid4()) except ImportError : def gen_uuid() : return os.popen("uuidgen").readline()[:-1] def cond(condition, vtrue, vfalse) : if condition : return vtrue return vfalse def edited_cb(cell, path, new_text, user_data): liststore, column, call_back = user_data liststore[path][column] = new_text if call_back != None : call_back(None) return def pygtk_newer(major, minor) : if gtk.pygtk_version[0] > major : return True if gtk.pygtk_version[0] == major and gtk.pygtk_version[1] >= minor : return True return False def pygobject_newer(major, minor, rel) : if gobject.pygobject_version[0] > major : return True if gobject.pygobject_version[0] == major : if gobject.pygobject_version[1] > minor : return True if gobject.pygobject_version[1] == minor and gobject.pygobject_version[2] >= rel : return True return False def delete_dir(dir_path) : real_path = os.path.realpath(dir_path) if real_path.count(os.sep) == len(real_path) : msgbox(_("Do not delete the root directory")) return for root, dirs, files in os.walk(dir_path, False) : for name in files : try : os.unlink(os.path.join(root, name)) except OSError, msg : msgbox(_("System error") + _(": ") + str(msg)) continue for name in dirs : try : os.rmdir(os.path.join(root, name)) except OSError, msg : msgbox(_("System error") + _(": ") + str(msg)) continue try : os.rmdir(dir_path) except OSError, msg : msgbox(_("System error") + _(": ") + str(msg)) def add_column(widget, label, value, icon_cell_func = None, editable = False , options=None, call_back=None, visible = True, is_enum = False) : tvcolumn = gtk.TreeViewColumn(label) widget.append_column(tvcolumn) if options == None or options == [] or not pygtk_newer(2, 6): cell = gtk.CellRendererText() else : cell = gtk.CellRendererCombo() store = gtk.ListStore(str) cell.set_property("model",store) for option in options : store.append([option]) cell.set_property("text-column",0) if is_enum : cell.set_property('has-entry', False) if editable : cell.set_property('editable', True) cell.connect('edited', edited_cb, (widget.get_model(), value, call_back)) if icon_cell_func != None : icon_cell = gtk.CellRendererPixbuf() tvcolumn.pack_start(icon_cell, False) tvcolumn.set_cell_data_func(icon_cell, icon_cell_func) tvcolumn.set_resizable(True) tvcolumn.pack_start(cell, True) tvcolumn.add_attribute(cell, 'text', value) tvcolumn.set_visible(visible) def msgbox(msg) : global top_window dialog = gtk.Dialog(_("Message"), top_window, gtk.DIALOG_MODAL, (gtk.STOCK_OK, True)) dialog.set_border_width(5) im=gtk.Image() im.set_from_stock(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_DIALOG) hb=gtk.HBox() hb.pack_start(im) label = gtk.Label(msg) label.set_selectable(True) label.set_line_wrap(True) hb.pack_start(label) dialog.vbox.pack_start(hb) dialog.show_all() save_top_window = top_window top_window = dialog dialog.run() top_window = save_top_window dialog.destroy() def confirmbox(msg, button=(gtk.STOCK_NO, gtk.RESPONSE_NO, gtk.STOCK_YES, gtk.RESPONSE_YES), title ="") : global top_window dialog = gtk.Dialog(_("Confirm"), top_window, gtk.DIALOG_MODAL,button) dialog.set_border_width(5) im=gtk.Image() im.set_from_stock(gtk.STOCK_DIALOG_QUESTION, gtk.ICON_SIZE_DIALOG) frame = gtk.Frame() confirm_title = gtk.Label() confirm_title.set_markup(''+title+'') frame.set_label_widget(confirm_title) confirm_msg = gtk.Label() confirm_msg.set_text(msg) confirm_msg.set_selectable(True) confirm_msg.set_line_wrap(True) dialog.vbox.pack_start(frame) hb=gtk.HBox() hb.pack_start(im) hb.pack_start(confirm_msg) frame.add(hb) dialog.vbox.resize_children() dialog.set_default_response(gtk.RESPONSE_YES) dialog.show_all() save_top_window = top_window top_window = dialog ret = dialog.run() top_window = save_top_window dialog.destroy() return ret def on_label_active(event, widget, url) : if not url[0] == '/' and not url.startswith("http") : url = "http://"+url webbrowser.open(url) def make_label_active(label, text, url) : label.set_markup(''+text+'') label.get_parent().connect("button_press_event", on_label_active, url) #label.get_parent().window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND1)) def is_valid_time(time_input) : num_chars = "0123456789." valid_units = ["", "ms", "msec", "us", "usec", "s", "sec", "m", "min", "h", "hr"] time_str = time_input.strip() if time_str[0] not in num_chars : return (False, _("The specified time should be numeric prefixed.")) unit_str = "" for i in range(len(time_str)) : if time_str[i] not in num_chars : unit_str = time_str[i:].strip() break unit_list = valid_units[:] unit_list.remove("") if unit_str not in valid_units : return (False, _("The specified time should default with second unit, ") + _("or should be suffixed with one of the following units:\n %s")%(", ".join(unit_list))) return (True, None) def is_valid_id(id) : if id == None : return False id_regex = "^[A-Za-z_][\w.-]*$" return re.match(id_regex, id) def extract_int(int_str) : for i in range(len(int_str)) : if int_str[i].isdigit() : num_start = i break else : return None for i in range(num_start, len(int_str)) : if not int_str[i].isdigit() : return int_str[num_start:i] else : return int_str[num_start:] def kvbox(title, description, fields, auto_fill = None) : global top_window dialog = gtk.Dialog(title, top_window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)) dialog.set_border_width(5) ok_btn = dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) ok_btn.grab_default() ok_btn.grab_focus() if description != None : label = gtk.Label() #label.set_markup('' + action_des + '') label.set_markup('' + description + '') label.set_alignment(0, 0) #label.show() dialog.vbox.pack_start(label, False, padding = 2) separator = gtk.HSeparator() #separator.show() dialog.vbox.pack_start(separator, False, padding = 2) table = gtk.Table(2, 1, False) widgets = [] combos = {} for row in range(len(fields)): if fields[row].auto_gen : widgets.append(None) continue label = gtk.Label(fields[row].label+":") label.set_alignment(0, 0.5) table.attach(label, 0, 1, row, row+1, xoptions=gtk.FILL, yoptions=gtk.FILL, xpadding=5, ypadding=2) if fields[row].options != None and fields[row].options!=[]: if fields[row].entry_editable : combo = gtk.combo_box_entry_new_text() else : combo = gtk.combo_box_new_text() for option in fields[row].options: combo.append_text(option) if fields[row].default != None : if fields[row].entry_editable : combo.child.set_text(fields[row].default) combo.child.set_activates_default(True) else : model = combo.get_model() iter = model.get_iter_first() while iter != None : if model.get_value(iter,0) == fields[row].default : combo.set_active_iter(iter) break iter = model.iter_next(iter) else : if fields[row].entry_editable : combo.child.set_text(fields[row].options[0]) combo.child.set_activates_default(True) else : combo.set_active(0) widgets.append(combo) table.attach(combo, 1,2, row, row+1, yoptions=gtk.FILL, xpadding=5, ypadding=2) combos[fields[row].key] = combo else : entry = gtk.Entry() if fields[row].default != None : entry.set_text(fields[row].default) entry.set_activates_default(True) widgets.append(entry) table.attach(entry, 1,2, row, row+1, xpadding=5, ypadding=2) if auto_fill != None : if title == _("Add Parameter") and combos.has_key("name"): combos["name"].connect("changed", auto_fill, widgets) elif title == _("Add Operation") : if combos.has_key("name"): combos["name"].connect("changed", auto_fill, widgets, "name") if combos.has_key("role"): combos["role"].connect("changed", auto_fill, widgets, "role") dialog.vbox.pack_start(table, padding=2) dialog.vbox.show_all() save_top_window = top_window top_window = dialog while True : ret = dialog.run() if ret in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT] : top_window = save_top_window dialog.destroy() return None else : kv = {} passed = True for row in range(len(fields)): if fields[row].auto_gen : kv[fields[row].key] = gen_uuid() continue if fields[row].options != None and fields[row].options != []: combo = widgets[row] if fields[row].entry_editable : kv[fields[row].key] = combo.child.get_text() else : if pygtk_newer(2, 6) : kv[fields[row].key] = combo.get_active_text() else : iter = combo.get_active_iter() if iter != None : kv[fields[row].key] = combo.get_model().get_value(iter, 0) else : kv[fields[row].key] = "" else : entry = widgets[row] kv[fields[row].key] = entry.get_text() if not fields[row].can_be_empty and kv[fields[row].key] == "" : msgbox(fields[row].label+_(" can't be empty")) passed = False if passed : top_window = save_top_window dialog.destroy() return kv class Field : key = None label = None default = None options = None can_be_empty = True editable = True auto_gen = False entry_editable = True def __init__(self, key, label=None, default=None, options=None, can_be_empty=True, editable=True, auto_gen=False, entry_editable = True) : self.key = key self.label = cond(label==None, key, label) self.default = default self.options = options self.can_be_empty = can_be_empty self.editable = editable self.auto_gen = auto_gen self.entry_editable = entry_editable class RAMeta : name = "" version = None desc = "" parameters = [] actions = [] class ElementList: store = None widget = None id_index = None idref_index = None def __init__(self, obj_types, elem_node_list) : treeiter = {} attr_is_any_name = False elem_is_any_name = False id_is_idref = False attr_list = [] sub_obj_list = [] for obj_type in obj_types : if validate_type == "dtd" : self.dtd_elem = manager.get_dtd_elem(obj_type) for attr in self.dtd_elem.get_attr_list() : if attr_list.count(attr) == 0 : attr_list.append(attr) for sub_obj in self.dtd_elem.get_content_model()[1] : if sub_obj_list.count(sub_obj) == 0 : sub_obj_list.append(sub_obj) else : sorted_rng_nodes = manager.sorted_sub_rng_nodes_by_name(obj_type) if sorted_rng_nodes != None : attr_rng_nodes = sorted_rng_nodes.get("attribute", []) elem_rng_nodes = sorted_rng_nodes.get("element", []) for rng_node in attr_rng_nodes : name = rng_node[0][1].getAttribute("name") if name == "" : attr_is_any_name = True elif attr_list.count(name) == 0 : attr_list.append(name) if name != "id" : continue sub_rng_nodes = manager.sorted_sub_rng_nodes_by_node(*rng_node[0]) for sub_rng_node in sub_rng_nodes.get("data", []) : if sub_rng_nodes["data"][0][0][1].getAttribute("type") == "IDREF" : id_is_idref = True break for rng_node in elem_rng_nodes : name = rng_node[0][1].getAttribute("name") if name == "" : elem_is_any_name = True elif sub_obj_list.count(name) == 0 : sub_obj_list.append(name) else : attr_is_any_name = True elem_is_any_name = True if attr_is_any_name : for elem_node in elem_node_list : for attr_name in elem_node.attributes.keys() : if attr_list.count(attr_name) == 0 : if attr_name == "id" : attr_list.insert(0, attr_name) else : attr_list.append(attr_name) if len(sub_obj_list) > 0 or elem_is_any_name : has_elem = True else : has_elem = False self.store = gtk.ListStore(*(tuple(str for i in range(len(attr_list)+1)))) tree = gtk.TreeView(self.store) if len(obj_types) > 1 : visible = True else : visible = False add_column(tree, _("Type"), 0, self.render_icon, visible=visible) for i in range(len(attr_list)) : if i == 0 : icon_func = self.render_icon else : icon_func = None if attr_list[i] == "id" : self.id_index = i + 1 elif attr_list[i] == "id-ref" : self.idref_index = i + 1 if attr_list[i] == "id" and not id_is_idref and not has_elem : visible = False else : visible = True add_column(tree, _(name_cap(attr_list[i])), i+1, icon_func, visible=visible) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_IN) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) sw.add(tree) self.widget = sw self.tree = tree self.attr_list = attr_list self.update(elem_node_list) def render_icon(self, tvcolumn, cell, model, iter): icons = { "cluster_property_set": gtk.STOCK_PREFERENCES, "node": "node", "primitive": gtk.STOCK_DND, "template": gtk.STOCK_DND, "group": gtk.STOCK_DND_MULTIPLE, "clone": gtk.STOCK_COPY, "master": gtk.STOCK_COPY, "master_slave": gtk.STOCK_COPY, "rsc_order": gtk.STOCK_PROPERTIES, "rsc_location": gtk.STOCK_PROPERTIES, "rsc_colocation": gtk.STOCK_PROPERTIES, "rsc_ticket": gtk.STOCK_PROPERTIES, "operations": gtk.STOCK_DIALOG_AUTHENTICATION, "op": gtk.STOCK_DIALOG_AUTHENTICATION, "instance_attributes": gtk.STOCK_PREFERENCES, "meta_attributes": gtk.STOCK_PREFERENCES, "attributes": gtk.STOCK_PREFERENCES, "utilization": gtk.STOCK_PREFERENCES, "life_time": gtk.STOCK_INDENT, "rule" : gtk.STOCK_JUSTIFY_FILL, "expression": gtk.STOCK_MEDIA_STOP, "nvpair": gtk.STOCK_MEDIA_STOP, "date_expression": gtk.STOCK_JUSTIFY_FILL, "transient_attributes": gtk.STOCK_PREFERENCES, "date_spec": gtk.STOCK_MEDIA_STOP, "duration": gtk.STOCK_MEDIA_STOP, "node_state": gtk.STOCK_FIND, "lrm": gtk.STOCK_FIND, "lrm_resources": gtk.STOCK_DND_MULTIPLE, "lrm_resource": gtk.STOCK_DND, "lrm_rsc_op": gtk.STOCK_DIALOG_AUTHENTICATION, "acl_user": gtk.STOCK_ORIENTATION_LANDSCAPE, "acl_role": gtk.STOCK_ORIENTATION_LANDSCAPE, "read": gtk.STOCK_FIND, "write": gtk.STOCK_FIND_AND_REPLACE, "deny": gtk.STOCK_DIALOG_ERROR, } pb = self.tree.render_icon(icons.get(model.get_value(iter, 0), gtk.STOCK_MEDIA_STOP), gtk.ICON_SIZE_BUTTON, None) cell.set_property('pixbuf', pb) return def update(self, elem_node_list) : self.elem_node_list = elem_node_list self.store.clear() self.nodes = {} model = self.tree.get_model() for elem_node in elem_node_list : values = [elem_node.tagName] values.extend([elem_node.getAttribute(attr_name) for attr_name in self.attr_list]) iter = self.store.append(values) #elem_type = elem_node.tagName #elem_id = elem_node.getAttribute("id") #if elem_id == "" : # elem_id = elem_node.getAttribute("id-ref") #if elem_id == "" : # elem_id = values[1] #if elem_id == "" : # elem_id = elem_node.parentNode.getAttribute("id") #self.nodes[(elem_type, elem_id)] = elem_node (node_type, node_id) = self.get_node_key(model, iter) self.nodes[(node_type, node_id)] = elem_node def get_selected_node(self) : (model, iter) = self.tree.get_selection().get_selected() if iter != None : (node_type, node_id) = self.get_node_key(model, iter) return self.nodes.get((node_type, node_id)) else : return None def save_iter_status(self, model, path, iter, expand_status): (type, id) = self.get_node_key(model, iter) expand_status[(type, id)] = self.tree.row_expanded(path) def restore_iter_status(self, model, path, iter, user_data): (select_type, select_id, select_path, expand_status) = user_data (type, id) = self.get_node_key(model, iter) path = model.get_path(iter) if type == select_type and id == select_id : self.tree.get_selection().select_iter(iter) if expand_status.has_key((type, id)) : if expand_status[type, id] : self.tree.expand_row(path, False) else : self.tree.collapse_row(path) else : self.tree.collapse_row(path) def save_tree_status(self) : (model, iter) = self.tree.get_selection().get_selected() if iter != None : (select_type, select_id) = self.get_node_key(model, iter) select_path = model.get_path(iter) else : select_type = None select_id = None select_path = None expand_status = {} self.store.foreach(self.save_iter_status, expand_status) return (select_type, select_id, select_path, expand_status) def restore_tree_status(self, tree_status) : self.store.foreach(self.restore_iter_status, tree_status) def get_node_key(self, model, iter) : type = model.get_value(iter, 0) id = "" if self.id_index != None : id = model.get_value(iter, self.id_index) if id == "" and self.idref_index != None : id = model.get_value(iter, self.idref_index) if id == "" : id = model.get_value(iter, 1) if id == "" and model.iter_parent(iter) != None : id = model.get_value(model.iter_parent(iter), 1) return (type, id) class ElementTree(ElementList): def __init__(self, obj_types, elem_node_list) : self.store = gtk.TreeStore(*(tuple(str for i in range(2)))) tree = gtk.TreeView(self.store) add_column(tree, _("Type"), 0, self.render_icon) add_column(tree, _("ID"), 1) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_IN) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) sw.add(tree) self.widget = sw self.tree = tree self.update(elem_node_list) def update(self, elem_node_list) : self.elem_node_list = elem_node_list self.store.clear() self.nodes = {} for elem_node in elem_node_list : iter = self.append_node(None, elem_node) self.append_child_nodes(iter, elem_node) def append_node(self, iter, node) : model = self.tree.get_model() node_type = node.tagName node_id = node.getAttribute("id") values = [node_type, node_id] child_iter = self.store.append(iter, values) #if node_id == "" : # node_id = node.parentNode.getAttribute("id") #self.nodes[(node_type, node_id)] = node (type, id) = self.get_node_key(model, child_iter) self.nodes[(type, id)] = node return child_iter def append_child_nodes(self, iter, node) : for child_node in node.childNodes : if child_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue child_iter = self.append_node(iter, child_node) self.append_child_nodes(child_iter, child_node) class ManageView : def __init__(self) : vpaned = gtk.VPaned() self.widget = vpaned top_vbox = gtk.VBox() vpaned.add1(top_vbox) ui_xml = ''' ''' uimanager = gtk.UIManager() actiongroup = gtk.ActionGroup('management') if pygtk_newer(2, 6) : startrsc_icon = gtk.STOCK_MEDIA_PLAY stoprsc_icon = gtk.STOCK_MEDIA_STOP else : startrsc_icon = "ha-start-resource" stoprsc_icon = "ha-stop-resource" rsc_actions = [ ('startrsc', startrsc_icon, _('St_art'), None,_('Start resource'), self.on_rsc_action), ('stoprsc', stoprsc_icon, _('_Stop'), None,_('Stop resource'), self.on_rsc_action), ('defaultrsc', gtk.STOCK_EXECUTE, _('_Default'), None,_('Work as default'), self.on_rsc_action), ('cleanuprsc', gtk.STOCK_CLEAR, _('_Cleanup Resource'), None,_('Cleanup resource'), self.on_rsc_cleanup), ('migratersc', gtk.STOCK_GO_FORWARD, _('Migra_te Resource'), None, _('Migrate a resource to specified node'), self.on_migrate_rsc), ('unmigratersc', gtk.STOCK_GO_BACK, _('Clea_r Migrate Constraints'), None, _('Clear constraints created by migrate'), self.on_unmigrate_rsc), ('unmanagersc', "ha-unmanage-resource", _('_Unmanage Resource'), None, _('Put a resource into unmanaged mode'), self.on_manage_rsc), ('managersc', "ha-manage-resource", _('_Manage Resource'), None, _('Put a resource into managed mode'), self.on_manage_rsc), ('refresh', gtk.STOCK_REFRESH, _('Re_fresh Resources'), None, _('Refresh CIB from the LRM status'), self.on_crm_rsc_cmd), ('reprobe', gtk.STOCK_FIND, _('Re_probe Resources'), None, _('Reprobe for resources started outside of the CRM'), self.on_crm_rsc_cmd), ] node_actions = [ ('standby', "ha-standby-node", _('_Standby'), None,_('Make the node standby'), self.on_standby), ('active', "ha-active-node", _('_Active'), None,_('Make the node active'), self.on_active) ] toggle_tool_actions = [ ('group-by-node', gtk.STOCK_SORT_DESCENDING, _('_Group By Node'), None, _('Group resources by node'), self.change_group_mode), ('maintenance-mode', "administration", _('_Maintenance Mode'), None, _('Switch to maintenance mode'), self.change_maintenance_mode), ('record-pending', "record-pending", _('_Indicate Pending Operations'), None, _('Indicate pending(starting/stopping) operations'), self.change_record_pending), ] #toolbar = gtk.Toolbar() #toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL) #toolbar.set_style(gtk.TOOLBAR_ICONS) #self.vbox.pack_start(toolbar, False) rsc_action_group = gtk.ActionGroup("rsc_mgmt") rsc_action_group.add_actions(rsc_actions) self.rsc_action_group = rsc_action_group uimanager.insert_action_group(rsc_action_group, 0) #for action_entry in rsc_actions : # action_name = action_entry[0] # action = rsc_action_group.get_action(action_name) # tool_item = action.create_tool_item() # toolbar.insert(tool_item, -1) # action.set_accel_group(window.accelgroup) #separator = gtk.SeparatorToolItem() #toolbar.insert(separator, -1) node_action_group = gtk.ActionGroup("node_mgmt") node_action_group.add_actions(node_actions) self.node_action_group = node_action_group uimanager.insert_action_group(node_action_group, 1) #for action_entry in node_actions : # action_name = action_entry[0] # action = node_action_group.get_action(action_name) # tool_item = action.create_tool_item() # toolbar.insert(tool_item, -1) # action.set_accel_group(window.accelgroup) #separator = gtk.SeparatorToolItem() #toolbar.insert(separator, -1) self.toggle_tool_action_group = gtk.ActionGroup("toggle_tools") self.toggle_tool_action_group.add_toggle_actions(toggle_tool_actions) uimanager.insert_action_group(self.toggle_tool_action_group, 2) #for action_entry in toggle_tool_actions : # action_name = action_entry[0] # action = self.toggle_tool_action_group.get_action(action_name) # tool_item = action.create_tool_item() # toolbar.insert(tool_item, -1) # action.set_accel_group(window.accelgroup) uimanager.add_ui_from_string(ui_xml) self.uimanager = uimanager toolbar = uimanager.get_widget('/toolbar') toolbar.set_style(gtk.TOOLBAR_ICONS) top_vbox.pack_start(toolbar, False) self.manage_tree = ManageTree() top_vbox.pack_start(self.manage_tree.widget) self.manage_tree.tree.connect("cursor-changed", self.on_after_show) self.manage_tree.tree.connect("event-after", self.on_right_click) self.sub_vbox = gtk.VBox() vpaned.add2(self.sub_vbox) """notebook = gtk.Notebook() self.notebook = notebook vbox.pack_start(notebook, padding=2) check_vbox = gtk.VBox() check_vbox.set_border_width(5) tab_label = gtk.Label(_("Check")) notebook.append_page(check_vbox, tab_label) self.check_vbox = check_vbox scores_vbox = gtk.VBox() scores_vbox.set_border_width(5) tab_label = gtk.Label(_("Scores")) notebook.append_page(scores_vbox, tab_label) self.scores_vbox = scores_vbox""" self.update() def on_right_click(self, widget, event) : if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3 : menu = None (model, iter) = self.manage_tree.tree.get_selection().get_selected() cur_type = model.get_value(iter, 0) if cur_type in ["node"] : menu = self.uimanager.get_widget("/node_popup") elif cur_type in ["primitive", "group", "clone", "master"] : menu = self.uimanager.get_widget("/resource_popup") else : menu = self.uimanager.get_widget("/tools_popup") menu.popup(None, None, None, event.button, event.time) def change_group_mode(self, action) : self.update() def change_maintenance_mode(self, action) : if action.get_active() : value = "true" else : value = "false" manager.set_crm_attribute("crm_config", "maintenance-mode", value) if manager.failed_reason != "" : msgbox(manager.failed_reason) def change_record_pending(self, action) : if action.get_active() : value = "true" else : value = "false" manager.set_crm_attribute("op_defaults", "record-pending", value) if manager.failed_reason != "" : msgbox(manager.failed_reason) def on_after_show(self, treeview = None) : for child in self.sub_vbox.get_children() : self.sub_vbox.remove(child) (model, iter) = self.manage_tree.tree.get_selection().get_selected() if iter == None : self.update_ui(None, None) return cur_type = model.get_value(iter, 0) cur_status = model.get_value(iter, 2) self.update_ui(cur_type, cur_status) id = model.get_value(iter, 1) if cur_type == "primitive" : self.show_rsc_summary(id) self.show_operations(id) elif cur_type == "cluster" : self.show_sub_attrs(manager.xml_nodes["cib"]) elif cur_type == "node" : for node_state in manager.xml_nodes["cib"].getElementsByTagName("node_state") : if node_state.getAttribute("id") == id : self.show_sub_attrs(node_state) break def show_sub_attrs(self, selected_node) : if selected_node == None : return if validate_type == "dtd" : dtd_elem = manager.get_dtd_elem(selected_node.tagName) attr_list = dtd_elem.get_attr_list() else : attr_list = [] is_any_name = False sorted_rng_nodes = manager.sorted_sub_rng_nodes_by_name(selected_node.tagName) if sorted_rng_nodes != None : attr_rng_nodes = sorted_rng_nodes.get("attribute", []) for rng_node in attr_rng_nodes : name = rng_node[0][1].getAttribute("name") if name == "" : is_any_name = True elif attr_list.count(name) == 0 : attr_list.append(name) else : is_any_name = True if is_any_name : for attr_name in selected_node.attributes.keys() : if attr_list.count(attr_name) == 0 : if attr_name == "id" : attr_list.insert(0, attr_name) else : attr_list.append(attr_name) name_labels = {} name_label_max_len = 0 for attr_name in attr_list : if attr_name in ["admin_epoch", "num_peers", "cib_feature_revision", "remote_access_port", "ccm_transition", "ignore_dtd", "generated", "crm-debug-origin", "remote-tls-port", "remote-clear-port", "no-quorum-panic", "shutdown", "clear_shutdown"] : continue attr_value = selected_node.getAttribute(attr_name) if attr_value == "" or name_labels.get(attr_name) != None : continue hbox = gtk.HBox() name_label = gtk.Label(_(name_cap(attr_name)+":")) name_label.set_alignment(0, 0.5) name_label.set_selectable(True) name_labels[attr_name] = name_label name_label_len = name_label.size_request()[0] if name_label_len > name_label_max_len : name_label_max_len = name_label_len value_label = gtk.Label(attr_value) value_label.set_alignment(0, 0.5) value_label.set_selectable(True) hbox.pack_start(name_label, False, padding=5) hbox.pack_start(value_label, False, padding=5) self.sub_vbox.pack_start(hbox, False, padding=2) for name_label in name_labels.values() : name_label.set_size_request(name_label_max_len + 20, -1) self.sub_vbox.show_all() def show_rsc_summary(self, rsc_id) : rsc_summary = {} (status, mig_threshold) = manager.get_rsc_status(rsc_id) if mig_threshold != "0" : rsc_summary["migration-threshold"] = [mig_threshold] rsc_summary["fail-count"] = self.get_rsc_failcount(rsc_id) name_labels = [] name_label_max_len = 0 for attr_name in rsc_summary : for i in range(len(rsc_summary[attr_name])) : hbox = gtk.HBox() if i == 0 : name_label = gtk.Label(_(name_cap(attr_name)) + _(":")) else : name_label = gtk.Label("") name_label.set_alignment(0, 0.5) name_label.set_selectable(True) name_labels.append(name_label) name_label_len = name_label.size_request()[0] if name_label_len > name_label_max_len : name_label_max_len = name_label_len value_label = gtk.Label(rsc_summary[attr_name][i]) value_label.set_alignment(0, 0.5) value_label.set_selectable(True) hbox.pack_start(name_label, False, padding=5) hbox.pack_start(value_label, False, padding=5) self.sub_vbox.pack_start(hbox, False, padding=2) for name_label in name_labels : name_label.set_size_request(name_label_max_len, -1) self.sub_vbox.show_all() def get_rsc_failcount(self, rsc_id) : rsc_summary = [] for trans_attr_node in manager.xml_nodes["cib"].getElementsByTagName("transient_attributes") : node_id = trans_attr_node.getAttribute("id") fail_count = "" last_failure = "" for nv_node in trans_attr_node.getElementsByTagName("nvpair") : nv_name = nv_node.getAttribute("name") if nv_name.count("fail-count") and nv_name.count(rsc_id) : fail_count = nv_node.getAttribute("value") elif nv_name.count("last-failure") and nv_name.count(rsc_id) : last_failure = nv_node.getAttribute("value") if fail_count == "" : continue summary_str = fail_count node_name = manager.node_name(node_id) if node_name != "" : summary_str += " (%s, "%node_name else : summary_str += " (%s, "%node_id if last_failure != "" : last_failure_time = time.ctime(float(last_failure)) if len(summary_str) > 0 : summary_str += " " summary_str += _("last failure at \"%s\"")%last_failure_time summary_str += ")" rsc_summary.append(summary_str) return rsc_summary def show_operations(self, rsc_id) : op_fields = ["Call ID", "Operation", "Interval", "Return Code", "Status", "Last Run", "Exec Time", "Queue Time", "Last Return Code Change"] store = gtk.TreeStore(*(tuple(str for i in range(len(op_fields))))) tree = gtk.TreeView(store) for i in range(len(op_fields)) : add_column(tree, _(op_fields[i]), i) ops = self.get_operations(rsc_id) for node_id in ops : if len(ops[node_id]) == 0 : continue node_name = manager.node_name(node_id) if node_name == "" : node_name = node_id node_root = store.append(None, [node_name, "", "", "", "", "", "", "", ""]) call_ids = [call_id for call_id in ops[node_id]] call_ids.sort() for call_id in call_ids : store.append(node_root, ops[node_id][call_id]) tree.expand_all() sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_IN) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) sw.add(tree) self.sub_vbox.pack_start(sw) self.sub_vbox.show_all() def get_operations(self, rsc_id) : if validate_type == "dtd" : call_id_key = "call_id" rc_code_key = "rc_code" op_status_key = "op_status" last_run_key = "last_run" exec_time_key = "exec_time" queue_time_key = "queue_time" last_rc_change_key = "last_rc_change" else : call_id_key = "call-id" rc_code_key = "rc-code" op_status_key = "op-status" last_run_key = "last-run" exec_time_key = "exec-time" queue_time_key = "queue-time" last_rc_change_key = "last-rc-change" operations = {} for lrm_node in manager.xml_nodes["cib"].getElementsByTagName("lrm") : node_id = lrm_node.getAttribute("id") operations[node_id] = {} for lrm_resource_node in lrm_node.getElementsByTagName("lrm_resource") : if lrm_resource_node.getAttribute("id") == rsc_id : for lrm_rsc_op in lrm_resource_node.getElementsByTagName("lrm_rsc_op") : operation = lrm_rsc_op.getAttribute("operation") interval = lrm_rsc_op.getAttribute("interval") if interval == "0" : interval_time = "" if operation == "monitor" : operation = "probe" elif interval == "" : interval_time = "" else : interval_time = interval+"ms" rc_code = lrm_rsc_op.getAttribute(rc_code_key) if rc_code == "7" and operation == "probe" : continue elif operation == "notify" : continue rc_str = manager.lrm_op_rc2str(rc_code) if rc_code == "" : result_str = rc_str else : result_str = "%s (rc=%s)"%(rc_str, rc_code) call_id = lrm_rsc_op.getAttribute(call_id_key) op_status = lrm_rsc_op.getAttribute(op_status_key) op_status_str = manager.op_status2str(op_status) last_run = lrm_rsc_op.getAttribute(last_run_key) if last_run != "" : last_run_time = time.ctime(float(last_run)) else : last_run_time = "" exec_time = lrm_rsc_op.getAttribute(exec_time_key) if exec_time == "" : exec_time_str = "" else : exec_time_str = exec_time + "ms" queue_time = lrm_rsc_op.getAttribute(queue_time_key) if queue_time == "" : queue_time_str = "" else : queue_time_str = queue_time + "ms" last_rc_change = lrm_rsc_op.getAttribute(last_rc_change_key) if last_rc_change != "" : last_rc_change_time = time.ctime(float(last_rc_change)) else : last_rc_change_time = "" operations[node_id][int(call_id)] = [ call_id, operation, interval_time, result_str, op_status_str, last_run_time, exec_time_str, queue_time_str, last_rc_change_time ] break return operations def set_action_sensitive(self, action, sensitive) : if self.rsc_action_group.get_action(action) != None : self.rsc_action_group.get_action(action).set_property("sensitive", sensitive) elif self.node_action_group.get_action(action) != None : self.node_action_group.get_action(action).set_property("sensitive", sensitive) def update_ui(self, cur_type = None, cur_status = None) : all_rsc_type = ["primitive", "group", "clone", "master"] self.set_action_sensitive('standby', cur_type in ["node"] and string.find(cur_status, _("standby")) == -1 and string.find(cur_status, _("never started")) == -1) self.set_action_sensitive('active', cur_type in ["node"] and string.find(cur_status, _("standby")) != -1 and string.find(cur_status, _("never started")) == -1) self.set_action_sensitive('cleanuprsc', cur_type in all_rsc_type) self.set_action_sensitive('startrsc', cur_type in all_rsc_type) self.set_action_sensitive('stoprsc', cur_type in all_rsc_type) self.set_action_sensitive('defaultrsc', cur_type in all_rsc_type) self.set_action_sensitive('migratersc', cur_type in all_rsc_type) self.set_action_sensitive('managersc', cur_type in all_rsc_type) self.set_action_sensitive('unmanagersc', cur_type in all_rsc_type) def update(self, xml_node = None) : view_status = self.save_status() self.manage_tree.update(view_status[0]) self.widget.show_all() self.restore_status(view_status) def on_rsc_action(self, action) : (cur_type, cur_name) = self.manage_tree.get_selected_node() if action.get_name() == "startrsc" : target_role = "Started" elif action.get_name() == "stoprsc" : target_role = "Stopped" else : target_role = "#default" if validate_type == "dtd" : metaattr_name = "target_role" else : metaattr_name = "target-role" real_rsc_id = cur_name.split(":")[0] rsc_xml = None for resources_node in manager.xml_nodes["cib"].cloneNode(True).getElementsByTagName("resources") : for rsc_node in resources_node.getElementsByTagName(cur_type) : if rsc_node.getAttribute("id") == real_rsc_id : rsc_xml = rsc_node break if rsc_xml == None : msgbox(_("Cannot find the %s: %s")%(cur_type, real_rsc_id)) return supported_rsc_types = manager.get_supported_rsc_types() found_nv = False clear_all = False for nv_xml_node in rsc_xml.getElementsByTagName("nvpair") : if nv_xml_node.getAttribute("name") != metaattr_name : continue target_rsc = nv_xml_node while target_rsc.tagName not in supported_rsc_types : target_rsc = target_rsc.parentNode target_rsc_id = target_rsc.getAttribute("id") current_value = nv_xml_node.getAttribute("value") if target_rsc_id == real_rsc_id : found_nv = True if target_role == "#default" : nv_xml_node.parentNode.removeChild(nv_xml_node) else : nv_xml_node.setAttribute("value", target_role) else : if not clear_all : retval = confirmbox(_("Caused by your previous action, this attribute has been set to \"") +current_value +_("\".")+"\n\n" +_("Recommended") + _(":")+"\n" +_("Select \"Clear All\" to remove the attributes for all of the sub-resources.")+"\n" +_("All of the sub-resources will inherit the attributes from their parent."), (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_NO, gtk.RESPONSE_NO, gtk.STOCK_CLEAR, gtk.RESPONSE_OK, "Clear All", gtk.RESPONSE_YES), _("Clear the %s=\"%s\" attribute for sub-resource \"")%(metaattr_name, current_value) +target_rsc_id+_("\"?")) if retval in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT] : return if retval in [gtk.RESPONSE_OK, gtk.RESPONSE_YES] : nv_xml_node.parentNode.removeChild(nv_xml_node) if retval == gtk.RESPONSE_YES : clear_all = True else : nv_xml_node.parentNode.removeChild(nv_xml_node) if not found_nv and target_role != "#default" : (parent_xml_node, add_obj_type, new_mid_elem) = manager.real_add_obj_type(rsc_xml, "meta_attributes", True) if parent_xml_node == None : msgbox(_("Cannot %s %s: XML processing error")%(target_role, real_rsc_id)) return impl = getDOMImplementation() newdoc = impl.createDocument(None, "nvpair", None) nv = newdoc.documentElement parent_xml_node.appendChild(nv) attr_id = manager.auto_unique_id(nv, metaattr_name) nv.setAttribute("id", attr_id) nv.setAttribute("name", metaattr_name) nv.setAttribute("value", target_role) xml_str = rsc_xml.toxml().replace("\n", "") manager.cib_do_cmd("cib_replace\n%s\n%s"%(str(rsc_xml.tagName), str(xml_str))) if manager.failed_reason != "" : msgbox(manager.failed_reason) def on_rsc_cleanup(self, action) : (cur_type, cur_name) = self.manage_tree.get_selected_node() rsc_list = manager.get_all_rsc() if rsc_list == None : return rsc_options = rsc_list[:] rsc_options.insert(0, _("all resources")) node_list = manager.get_normal_nodes() if node_list == None : return node_options = node_list[:] node_options.insert(0, _("all nodes")) cleanup = kvbox(_("Cleanup Resource"), None, [Field("rsc", _("Resource"), cur_name, rsc_options, False, entry_editable = False), Field("node", _("Node"), _("all nodes"), node_options, False, entry_editable = False)]) if cleanup != None : cleanup_rscs = [] if cleanup["rsc"] == _("all resources") : for rsc in rsc_list : if manager.get_rsc_type(rsc) == "primitive" : cleanup_rscs.append(rsc) elif manager.get_rsc_type(cleanup["rsc"]) != "primitive" : all_subrscs = manager.get_all_subrsc(cleanup["rsc"]) if all_subrscs == None : return for rsc in all_subrscs : if manager.get_rsc_type(rsc) == "primitive" : cleanup_rscs.append(rsc) else : cleanup_rscs.append(cleanup["rsc"]) if cleanup["node"] == _("all nodes") : cleanup_nodes = node_list else : cleanup_nodes = [cleanup["node"]] for rsc in cleanup_rscs : for node in cleanup_nodes : #manager.do_cmd("cleanup_rsc\n" + node + "\n" + rsc) manager.do_cmd("crm_rsc_cmd\n%s\ncleanup\n%s"%(rsc, node)) def on_migrate_rsc(self, action) : global top_window (cur_type, cur_name) = self.manage_tree.get_selected_node() dialog = gtk.Dialog(_("Migrate Resource"), top_window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_border_width(5) dialog.set_default_response(gtk.RESPONSE_OK) duration_elems = ["yrs", "mths", "wks", "days", "hrs", "mins", "secs"] combos = {} checkbuttons = {} spinbuttons = {} name_labels = [] name_label_max_len = 0 for key in ["rsc", "to_node", "force", "duration", "period", "time"] : hbox = gtk.HBox() if key in ["rsc", "to_node"] : name_label = gtk.Label(_(name_cap(key))+_(":")) name_label.set_alignment(0, 0.5) name_labels.append(name_label) name_label_len = name_label.size_request()[0] if name_label_len > name_label_max_len : name_label_max_len = name_label_len hbox.pack_start(name_label, False, padding=2) if key == "rsc" : widget = gtk.combo_box_new_text() for rsc in manager.get_all_real_rsc() : widget.append_text(rsc) model = widget.get_model() iter = model.get_iter_first() while iter != None : if model.get_value(iter,0) == manager.obj_real_id(cur_name) : widget.set_active_iter(iter) break iter = model.iter_next(iter) combos[key] = widget hbox.pack_start(widget, True, padding=2) elif key == "to_node" : widget = gtk.combo_box_new_text() node_list = manager.get_normal_nodes() node_options = node_list[:] node_options.insert(0, "") for node in node_options : widget.append_text(node) combos[key] = widget hbox.pack_start(widget, True, padding=2) elif key == "force" : widget = gtk.CheckButton(_(name_cap(key))) checkbuttons[key] = widget hbox.pack_start(widget, True, padding=2) elif key == "duration" : widget = gtk.CheckButton(_(name_cap(key))) checkbuttons[key] = widget hbox.pack_start(widget, True, padding=2) widget.connect("toggled", self.on_duration_toggled) elif key == "period" : for key in duration_elems[:4] : adj = gtk.Adjustment(0, 00, 99, 1, 3) widget = gtk.SpinButton(adj, 0, 0) widget.set_width_chars(2) widget.set_wrap(True) hbox.pack_start(widget, False) spinbuttons[key] = widget label = gtk.Label(_(name_cap(key)) + " ") hbox.pack_start(label, False, padding=2) hbox.set_sensitive(False) self.period_hbox = hbox else : for key in duration_elems[4:] : adj = gtk.Adjustment(0, 00, 99, 1, 5) widget = gtk.SpinButton(adj, 0, 0) widget.set_width_chars(2) widget.set_wrap(True) hbox.pack_start(widget, False) spinbuttons[key] = widget label = gtk.Label(_(name_cap(key)) + " ") hbox.pack_start(label, False, padding=2) hbox.set_sensitive(False) self.time_hbox = hbox dialog.vbox.pack_start(hbox, False, padding=2) for name_label in name_labels : name_label.set_size_request(name_label_max_len, -1) widgets = {} widgets["combos"] = combos widgets["checkbuttons"] = checkbuttons widgets["spinbuttons"] = spinbuttons widget_group = WidgetGroup(widgets) save_top_window = top_window top_window = dialog dialog.show_all() ret = dialog.run() if ret in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT] : top_window = save_top_window dialog.destroy() return migrate = widget_group.get_values() top_window = save_top_window dialog.destroy() period = "" if self.period_hbox.get_property("sensitive") : for key in duration_elems[:4] : if migrate.get(key, "0.0") != "0.0" : period += migrate[key].split(".")[0] + key[0].upper() time = "" if self.time_hbox.get_property("sensitive") : for key in duration_elems[4:] : if migrate.get(key, "0.0") != "0.0" : time += migrate[key].split(".")[0] + key[0].upper() if period == "" and time == "" : duration = "" else : duration = "P" + period if time != "" : duration += "T" + time manager.do_cmd("migrate\n%s\n%s\n%s\n%s" %(migrate.get("rsc", ""), migrate.get("to_node", ""), migrate.get("force", ""), duration)) if manager.failed_reason != "" : msgbox(manager.failed_reason.replace("This message can be disabled with -Q", "").replace ("using the 'crm_resource -U' command or manually with cibadmin", "by \"Clear Migrate Constraints\"")) def on_duration_toggled(self, widget) : self.period_hbox.set_sensitive(widget.get_active()) self.time_hbox.set_sensitive(widget.get_active()) def on_unmigrate_rsc(self, action) : rsc_locations = {} for rsc_location in manager.xml_nodes["cib"].getElementsByTagName("rsc_location") : id = str(rsc_location.getAttribute("id")) rsc_locations[id] = rsc_location migrate_ids = {} rsc_ids = [] for id in rsc_locations : for prefix in ["cli-prefer-", "cli-standby-"] : if id.startswith(prefix) : split_id = id.split(prefix) if len(split_id) > 1 : rsc_id = split_id[1] if not migrate_ids.has_key(rsc_id) : migrate_ids[rsc_id] = [] migrate_ids[rsc_id].append(id) all_str = _("all migrated resources") rsc_list = migrate_ids.keys()[:] rsc_list.insert(0, all_str) (cur_type, cur_name) = self.manage_tree.get_selected_node() if cur_name in migrate_ids : default_option = cur_name else : default_option = all_str unmigrate = kvbox(_("Clear Migrate Constraints"), None, [Field("rsc", _("Resource"), default_option, rsc_list, False, entry_editable = False)]) if unmigrate != None : if unmigrate["rsc"] == all_str : for rsc_id in migrate_ids.keys() : for id in migrate_ids[rsc_id] : xml_str = rsc_locations[id].toxml().replace("\n", "") manager.cib_do_cmd("cib_delete\nconstraints\n%s"%(str(xml_str))) else : for id in migrate_ids[unmigrate["rsc"]] : xml_str = rsc_locations[id].toxml().replace("\n", "") manager.cib_do_cmd("cib_delete\nconstraints\n%s"%(str(xml_str))) def on_manage_rsc(self, action) : (cur_type, cur_name) = self.manage_tree.get_selected_node() if action.get_name() == "managersc" : is_managed = "true" elif action.get_name() == "unmanagersc" : is_managed = "false" else : is_managed = "#default" if validate_type == "dtd" : metaattr_name = "is_managed" else : metaattr_name = "is-managed" if is_managed == "#default" : manager.do_cmd("del_rsc_attr\n%s\nmeta\n%s"%(manager.obj_real_id(cur_name), metaattr_name)) else : manager.do_cmd("set_rsc_attr\n%s\nmeta\n%s\n%s"%(manager.obj_real_id(cur_name), metaattr_name, is_managed)) if manager.failed_reason != "" : msgbox(manager.failed_reason) def on_crm_rsc_cmd(self, action) : global top_window cmd = action.get_name() node_list = manager.get_normal_nodes() if node_list == None : node_list = [] #node_options = node_list[:] #node_options.insert(0, "") title = _("%s Resources")%_(name_cap(cmd)) dialog = gtk.Dialog(title, top_window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_border_width(5) dialog.set_default_response(gtk.RESPONSE_OK) combos ={} for key in ["node"] : hbox = gtk.HBox() name_label = gtk.Label(_(name_cap(key)) + _(":")) name_label.set_alignment(0, 0.5) checkbutton = gtk.CheckButton() checkbutton.add(name_label) hbox.pack_start(checkbutton, False, padding=2) value_widget = gtk.combo_box_new_text() for node in node_list : value_widget.append_text(node) value_widget.set_sensitive(False) hbox.pack_start(value_widget, True, padding=2) combos[key] = value_widget checkbutton.connect("toggled", self.on_checkbutton_toggled, value_widget) dialog.vbox.pack_start(hbox, False, padding=2) widgets = {} widgets["combos"] = combos widget_group = WidgetGroup(widgets) dialog.show_all() save_top_window = top_window top_window = dialog ret = dialog.run() if ret in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT] : top_window = save_top_window dialog.destroy() return cmd_args = widget_group.get_values() top_window = save_top_window dialog.destroy() #cmd_args = kvbox(_("%s Resources")%_(name_cap(cmd)), None, # [Field("node", _("Node"), "", node_options, True, entry_editable = False)]) #if cmd_args == None : # return manager.do_cmd("crm_rsc_cmd\n\n%s\n%s"%(cmd, cmd_args.get("node", ""))) if manager.failed_reason != "" : msgbox(manager.failed_reason) def on_checkbutton_toggled(self, checkbutton, widget) : widget.set_sensitive(checkbutton.get_active()) def on_standby(self, action) : (cur_type, cur_name) = self.manage_tree.get_selected_node() if confirmbox(_("Make") +" " +cur_name + " " +_("standby")+"?") == gtk.RESPONSE_YES: #manager.do_cmd("standby\n"+cur_name + "\n" + "on") manager.do_cmd("crm_attribute\nnodes\nset\nstandby\non\n%s\n\n"%cur_name) if manager.failed_reason != "" : msgbox(manager.failed_reason) def on_active(self, action) : (cur_type, cur_name) = self.manage_tree.get_selected_node() if confirmbox(_("Make") +" " +cur_name + " " + _("active")+"?") == gtk.RESPONSE_YES : #manager.do_cmd("standby\n"+cur_name + "\n" + "off") manager.do_cmd("crm_attribute\nnodes\nset\nstandby\noff\n%s\n\n"%cur_name) if manager.failed_reason != "" : msgbox(manager.failed_reason) def save_status(self) : group_by_node = self.toggle_tool_action_group.get_action("group-by-node").get_active() tree_status = self.manage_tree.save_tree_status() paned_position = self.widget.get_position() return (group_by_node, tree_status, paned_position) def restore_status(self, view_status) : #if view_status == None : # return (group_by_node, tree_status, paned_position) = view_status if group_by_node : self.toggle_tool_action_group.get_action("group-by-node").set_active(group_by_node) self.update_tool_button() self.manage_tree.restore_tree_status(tree_status) self.on_after_show() if paned_position : (paned_width, paned_height) = self.widget.size_request() self.manage_tree.widget.set_size_request(paned_width, paned_position) self.widget.set_position(paned_position) def update_tool_button(self) : #value = manager.do_cmd("crm_attribute\ncrm_config\nget\nmaintenance-mode\n\n\n\n") #if value != None and len(value) > 0 and value[0].count("true") : value = manager.find_attribute("crm_config", "maintenance-mode") action = self.toggle_tool_action_group.get_action("maintenance-mode") if pygtk_newer(2, 10) and pygobject_newer(2, 12, 3) : action.disconnect_by_func(self.change_maintenance_mode) if value == "true" : if not action.get_active() : action.set_active(True) else : if action.get_active() : action.set_active(False) if pygtk_newer(2, 10) and pygobject_newer(2, 12, 3) : action.connect("toggled", self.change_maintenance_mode) #value = manager.do_cmd("crm_attribute\nop_defaults\nget\nrecord-pending\n\n\n\n") #if value != None and len(value) > 0 and value[0].count("true") : value = manager.find_attribute("op_defaults", "record-pending") action = self.toggle_tool_action_group.get_action("record-pending") if pygtk_newer(2, 10) and pygobject_newer(2, 12, 3) : action.disconnect_by_func(self.change_record_pending) if value == "true" : if not action.get_active() : action.set_active(True) else : if action.get_active() : action.set_active(False) if pygtk_newer(2, 10) and pygobject_newer(2, 12, 3) : action.connect("toggled", self.change_record_pending) class ManageTree : store = None tree = None last_iter = None def __init__(self) : global top_window treeiter = {} self.store = gtk.TreeStore(str, str, str, str) tree = gtk.TreeView(self.store) add_column(tree, _("Type"), 0, self.render_type_icon, visible=False) add_column(tree, _("Name"), 1, self.render_type_icon) add_column(tree, _("Status"), 2, self.render_status_icon) add_column(tree, _("Details"), 3) (window_width, window_height) = top_window.get_size() tree.set_size_request(500, window_height / 2) #tree.connect("cursor-changed", self.on_cursor_changed, tree.get_selection()) #tree.connect("event-after", self.on_right_click) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_IN) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) sw.add(tree) self.widget = sw self.tree = tree def get_selected_node(self): (model, iter) = self.tree.get_selection().get_selected() type = model.get_value(iter, 0) name = model.get_value(iter, 1) return (type, name) def render_type_icon(self, tvcolumn, cell, model, iter) : icons = { "cluster": "nodes", "node": "node", "resources": gtk.STOCK_DIRECTORY, "inactive resources": gtk.STOCK_DIRECTORY, "primitive": gtk.STOCK_DND, "group": gtk.STOCK_DND_MULTIPLE, "clone": gtk.STOCK_COPY, "master": gtk.STOCK_COPY, "master_slave": gtk.STOCK_COPY, } pb = self.tree.render_icon(icons.get(model.get_value(iter, 0), gtk.STOCK_MEDIA_STOP), gtk.ICON_SIZE_BUTTON, None) cell.set_property('pixbuf', pb) return def render_status_icon(self, tvcolumn, cell, model, iter): icons = {-2:"stopped", -1:gtk.STOCK_PREFERENCES, 0:"running", 1:"stopped", 2:"dirty-stopped", 3:"failed", 4:"starting", 5:"stopping"} status = self.iter_status(model,iter) pb = self.tree.render_icon(icons[status], gtk.ICON_SIZE_SMALL_TOOLBAR, None) cell.set_property('pixbuf', pb) return def iter_status(self, model, iter) : # -1:config 0: ok, 1: stopped, 2: umanaged, 3:failed, 4:stop failed type = model.get_value(iter, 0) status = model.get_value(iter, 2) iter_status = 0 if type == "primitive" : if string.find(status, _("unmanaged")) != -1 \ or string.find(status, _("unclean")) != -1 \ or string.find(status, _("failure ignored")) != -1 : iter_status = 2 elif string.find(status, _("failed")) != -1 : iter_status = 3 elif string.find(status, _("starting")) != -1 : iter_status = 4 elif string.find(status, _("stopping")) != -1 : iter_status = 5 elif string.find(status, _("not running")) != -1 : iter_status = 1 elif string.find(status, _("running")) != -1 : iter_status = 0 else : iter_status = 2 elif type == "node" : if status == _("ping node") : iter_status = -1 elif string.find(status, _("online")) != -1 : iter_status = 0 else : iter_status = 1 elif type in ["group","resources","clone","master"]: iter_status = 0 else : iter_status = -2 if model.iter_has_child(iter) : for i in range(0, model.iter_n_children(iter)) : child = model.iter_nth_child(iter,i) child_status = self.iter_status(model, child) if child_status > iter_status : iter_status = child_status return iter_status def save_iter_status(self, model, path, iter, expand_status): type = model.get_value(iter, 0) name = model.get_value(iter, 1) expand_status[(type, name)] = self.tree.row_expanded(path) def restore_iter_status(self, model, path, iter, user_data): (select_name, select_type, select_path, expand_status) = user_data type = model.get_value(iter, 0) name = model.get_value(iter, 1) path = model.get_path(iter) if name == select_name and type == select_type : self.tree.get_selection().select_iter(iter) if expand_status.has_key((name,type)) : if expand_status[name, type] : self.tree.expand_row(path, False) else : self.tree.collapse_row(path) else : self.tree.expand_row(path, False) def save_tree_status(self) : (model, iter) = self.tree.get_selection().get_selected() if iter != None : select_type = model.get_value(iter, 0) select_name = model.get_value(iter, 1) select_path = model.get_path(iter) else : select_name = None select_type = None select_path = None expand_status = {} self.store.foreach(self.save_iter_status, expand_status) return (select_name, select_type, select_path, expand_status) def restore_tree_status(self, tree_status) : self.store.foreach(self.restore_iter_status, tree_status) (name, type, path, expand_status) = tree_status if name == None : self.tree.get_selection().select_path((0,)) self.tree.expand_all() def update(self, group_by_node = False) : self.store.clear() if not manager.connected : return nodes = manager.get_all_nodes() if nodes == None : return active_nodes = manager.get_active_nodes() if active_nodes == None : return crm_nodes = manager.get_crm_nodes() if crm_nodes == None : return have_quorum = False for attr_name in ["have-quorum", "have_quorum"] : attr_value = manager.xml_nodes["cib"].getAttribute(attr_name) if attr_value != "" : if attr_value in ["true", "yes", "1"] : have_quorum = True break if have_quorum : status = _("have quorum") else : status = _("no quorum") cluster_type = manager.get_cluster_type().capitalize() if len(cluster_type) > 0 : cluster_type += " & Pacemaker" else : cluster_type += "Pacemaker" #root = self.store.append(None, ["cluster", cluster_type, status, ""]) if group_by_node : nodes_root = self.store.append(None, ["cluster", _("Cluster"), status, cluster_type]) for node in nodes : self.add_node(nodes_root, node, node in active_nodes, node in crm_nodes) inactive_root = self.store.append(None, ["inactive resources", _("Inactive resources"), "", ""]) rscs = manager.get_all_rsc() for rsc in rscs : rsc_type = manager.get_rsc_type(rsc) if rsc_type != "primitive" : continue nodes = manager.get_rsc_running_on(rsc) if nodes != None and len(nodes) > 0 : continue else : (status, mig_threshold) = manager.get_rsc_status(rsc) info = self.get_rsc_info(rsc) self.store.append(inactive_root,[rsc_type, rsc, _(status), info]) else : nodes_root = self.store.append(None, ["cluster", _("Cluster"), status, cluster_type]) for node in nodes : self.add_node(nodes_root, node, node in active_nodes, node in crm_nodes, False) rscs_root = self.store.append(None, ["resources", _("Resources"), "", ""]) rscs = manager.get_top_rsc() for rsc in rscs : self.add_rsc(rscs_root, rsc) def add_rsc(self, parent, rsc) : type = manager.get_rsc_type(rsc) status = "" label = "" if type == "primitive" : (status, mig_threshold) = manager.get_rsc_status(rsc) nodes = manager.get_rsc_running_on(rsc) info = self.get_rsc_info(rsc) if nodes != None and len(nodes)>0: self.store.append(parent,[type, rsc, _(status) + _(" on ")+str(nodes), info]) else : self.store.append(parent,[type, rsc, _(status), info]) elif type in ["group","clone","master"] : status = type iter = self.store.append(parent,[type, rsc, _(status), ""]) for subrsc in manager.get_sub_rsc(rsc) : self.add_rsc(iter, subrsc) def get_rsc_info(self, rsc_id) : for lrm_rsc_node in manager.xml_nodes["cib"].getElementsByTagName("lrm_resource") : if lrm_rsc_node.getAttribute("id") == rsc_id : rsc_class = lrm_rsc_node.getAttribute("class") if rsc_class != "" : rsc_info = rsc_class + "::" else : rsc_info = "" rsc_provider = lrm_rsc_node.getAttribute("provider") if rsc_provider != "" : rsc_info += rsc_provider + ":" rsc_type = lrm_rsc_node.getAttribute("type") rsc_info += rsc_type return rsc_info return "" def add_node(self, nodes_root, node, active, started, add_rscs = True): status = _("unknown") if not started : node_type = manager.get_nodetype(node) if node_type == "normal" : status = _("never started") elif node_type == "ping" : status = _("ping node") else : status = _("unknown type") else : node_status = manager.get_node_config(node) if node_status.get("online") == "True" : status = _("online") elif node_status.get("pending") == "True" : status = _("pending") else : status = _("offline") if node_status.get("unclean") == "True" : status += " (" + _("unclean") + ")" if node_status.get("is_dc") == "True" : status += " (" + _("dc") + ")" if node_status.get("standby_onfail") == "True" \ and node_status.get("online") == "True" : status += " - " + _("standby") + " (" + _("on-fail") + ")" elif node_status.get("standby") == "True" : status += " - " + _("standby") node_iter = self.store.append(nodes_root,["node", node, status, ""]) if add_rscs : running_rsc = manager.get_running_rsc(node) for rsc in running_rsc : self.add_rsc(node_iter, rsc) class MainTree(ElementList) : def __init__(self) : obj_type = "cib" self.store = gtk.TreeStore(str, str) widget = gtk.TreeView(self.store) #widget.set_headers_visible(False) add_column(widget, None, 0, self.render_icon) title_label = gtk.Label() title_label.show() widget.get_column(0).set_widget(title_label) widget.set_size_request(180, 200) widget.connect("cursor-changed", self.on_cursor_changed, widget.get_selection()) #widget.connect("event-after", self.on_right_click) self.tree = widget self.widget = widget self.title_label = title_label def on_cursor_changed(self, treeview, selection) : try : if not window.can_change_view() : if self.last_iter != None : selection.select_iter(self.last_iter) return except : pass (model, iter) = selection.get_selected() if window.cur_type != None and window.cur_view != None : window.view_status[window.cur_type] = window.cur_view.save_status() if iter == None : window.select_view(None, None, None) return #type = model.get_value(iter, 2) name = model.get_value(iter, 0) type = model.get_value(iter, 1) #status = model.get_value(iter, 1) window.select_view(type, name) self.last_iter = iter def render_icon(self, tvcolumn, cell, model, iter): name = model.get_value(iter, 1) stocks = { "cib": gtk.STOCK_HARDDISK, "configuration": gtk.STOCK_HARDDISK, "status": gtk.STOCK_FIND, "crm_config": gtk.STOCK_PREFERENCES, "op_defaults": gtk.STOCK_PREFERENCES, "rsc_defaults": gtk.STOCK_PREFERENCES, "nodes": "nodes", "resources": gtk.STOCK_DIRECTORY, "constraints": gtk.STOCK_PROPERTIES, "acls": gtk.STOCK_DIALOG_AUTHENTICATION, "management" : gtk.STOCK_EXECUTE } icons = {-2:gtk.STOCK_DIALOG_INFO, -1:gtk.STOCK_PREFERENCES, 0:gtk.STOCK_YES, 1:gtk.STOCK_DIALOG_INFO, 2:gtk.STOCK_DIALOG_WARNING, 3:gtk.STOCK_DIALOG_ERROR} status = self.iter_status(model,iter) pb = self.widget.render_icon(stocks.get(name, gtk.STOCK_DIALOG_INFO), gtk.ICON_SIZE_BUTTON, None) cell.set_property('pixbuf', pb) return def iter_status(self, model, iter) : return 0 # -1:config 0: ok, 1: stopped, 2: umanaged, 3:failed, 4:stop failed type = model.get_value(iter, 2) status = model.get_value(iter, 1) iter_status = 0 if type == _("primitive") : if string.find(status, _("not running")) != -1 : iter_status = 1 elif string.find(status, _("running")) != -1 : iter_status = 0 elif string.find(status, _("fail")) != -1 : iter_status = 3 else : iter_status = 2 elif type == "node" : if status == _("ping node") : iter_status = -1 elif string.find(status, _("running")) != -1 : iter_status = 0 else : iter_status = 1 elif type in [_("group"),_("resources"),_("clone"),_("master")]: iter_status = 0 elif type in [_("orders"),_("locations"), _("colocations")] : iter_status = -1 else : iter_status = -2 if model.iter_has_child(iter) : for i in range(0, model.iter_n_children(iter)) : child = model.iter_nth_child(iter,i) child_status = self.iter_status(model, child) if child_status > iter_status : iter_status = child_status return iter_status def update(self) : tree_status = self.save_tree_status() self.title_label.set_text("") self.store.clear() if not manager.connected : window.select_view(None, None, None) return if manager.active_cib == "" : title_str = _("Live") else : title_str = _("Shadow: ") + manager.active_cib self.title_label.set_markup(''+title_str+'') treeiter = {} if validate_type == "dtd" : self.dtd_elem = manager.get_dtd_elem("cib") for (name, mod) in self.dtd_elem.get_content_model()[1] : if mod == '' : if mode_level != 2 and name == "status" : continue treeiter[name] = self.store.append(None, [_(name_cap(name)), name]) sub_dtd_elem = manager.get_dtd_elem(name) for (sub_name, sub_mod) in sub_dtd_elem.get_content_model()[1] : if sub_mod == '' : treeiter[sub_name] = \ self.store.append(treeiter[name], [_(name_cap(sub_name)), sub_name]) else : sorted_rng_nodes = manager.sorted_sub_rng_nodes_by_name("cib") for rng_node in sorted_rng_nodes.get("element", []) : name = rng_node[0][1].getAttribute("name") if mode_level != 2 and name == "status" : continue treeiter[name] = self.store.append(None, [_(name_cap(name)), name]) sub_rng_nodes = manager.sorted_sub_rng_nodes_by_node(*rng_node[0]) for sub_rng_node in sub_rng_nodes.get("element", []) : if manager.find_decl(sub_rng_node, "zeroOrMore") != 0 : continue sub_name = sub_rng_node[0][1].getAttribute("name") treeiter[sub_name] = \ self.store.append(treeiter[name], [_(name_cap(sub_name)), sub_name]) #(u',', [(u'configuration', ''), (u'status', '')], '') if manager.active_cib == "" : treeiter["management"] = self.store.append(None, [_("Management"), "management"]) self.treeiter = treeiter self.restore_tree_status(tree_status) (type, id, path, expand_status) = tree_status if expand_status == {} : self.widget.expand_all() selection = self.widget.get_selection() (model, iter) = selection.get_selected() if iter != None and window.cur_view != None and window.cur_type.count("crm_config") == 0 : cur_xml_nodes = manager.xml_nodes["cib"].getElementsByTagName(window.cur_type) if len(cur_xml_nodes) > 0 : cur_xml_node = cur_xml_nodes[0] else : cur_xml_node = window.cur_type window.cur_view.update(cur_xml_node) else : if iter == None : if manager.active_cib == "" : selection.select_iter(self.treeiter["management"]) else : selection.select_path("0") self.on_cursor_changed(self.widget, self.widget.get_selection()) class ClusterView : def update(self, xml_node = None) : self.cluster_info_labels = None self.cib_attrs_labels = None for line in self.cluster_info_vbox.get_children() : self.cluster_info_vbox.remove(line) for line in self.cib_attrs_vbox.get_children() : self.cib_attrs_vbox.remove(line) self.widget.show_all() config = manager.get_cluster_config() if config == None or len(config) == 0 : self.widget.get_nth_page(0).hide_all() else : cluster_info_labels= {} for key in config.keys(): if config.get(key, "") == "" : continue cluster_info_labels[key] = self.add_line(self.cluster_info_vbox, config.get(key,"")) self.cluster_info_labels = cluster_info_labels self.widget.get_nth_page(0).show_all() xml_node = manager.xml_nodes.get("cib") if xml_node == None : self.widget.get_nth_page(1).hide_all() else : obj_type = xml_node.tagName if validate_type == "dtd" : dtd_elem = manager.get_dtd_elem(obj_type) attr_names = dtd_elem.get_attr_list() else : sorted_rng_nodes = manager.sorted_sub_rng_nodes_by_name("cib") attr_node_list = sorted_rng_nodes.get("attribute", []) attr_names = [attr_node[0][1].getAttribute("name") for attr_node in attr_node_list] cib_attrs_labels = {} for attr_name in attr_names : attr_value = xml_node.getAttribute(attr_name) if attr_value == "" : continue cib_attrs_labels[attr_name] = self.add_line(self.cib_attrs_vbox, attr_value) self.cib_attrs_labels = cib_attrs_labels self.widget.get_nth_page(1).show_all() self.on_after_show() def add_line(self, vbox, value) : hbox = gtk.HBox() name_label = gtk.Label() name_label.set_alignment(0, 0.5) name_label.set_selectable(True) eventbox = gtk.EventBox() eventbox.add(name_label) value_label = gtk.Label(value) value_label.set_alignment(0, 0.5) value_label.set_selectable(True) hbox.pack_start(eventbox, False, padding=5) hbox.pack_start(value_label, False, padding=5) vbox.pack_start(hbox, False, padding=2) return name_label def on_after_show(self) : info_dict = { "quorum_server": "Quorum Server", "use_logd": "Use Logd", "autojoin": "Auto Join", "apiauth": "API Authentication", "auto_failback": "Auto Failback", "baud": "Baud Rate", "debug": "Debug Level", "debugfile": "Debug File", "deadping": "Dead Ping", "deadtime": "Dead Time", "hbversion": "Heartbeat Version", "hopfudge": "Hop Fudge", "initdead": "Initial Dead Time", "keepalive": "Keep Alive", "logfacility": "Log Facility", "logfile": "Log File", "msgfmt": "Message Format", "nice_failback": "Nice Failback", "node": "Node", "normalpoll": "Normal Poll", "stonith": "Stonith", "udpport": "UDP Port", "warntime": "Warning Time", "watchdog": "Watchdog", "cluster": "Cluster" } if self.cluster_info_labels != None : cluster_type = manager.get_cluster_type() if cluster_type == "openais" : target_site = "www.openais.org" elif cluster_type == "heartbeat" : target_site = "www.linux-ha.org" else : target_site = "www.clusterlabs.org" name_label_max_len = 0 for key in self.cluster_info_labels.keys() : make_label_active(self.cluster_info_labels[key], _(info_dict.get(key, key))+_(":"), target_site) name_label_len = self.cluster_info_labels[key].size_request()[0] if name_label_len > name_label_max_len : name_label_max_len = name_label_len for name_label in self.cluster_info_labels.values() : name_label.set_size_request(name_label_max_len, -1) if self.cib_attrs_labels != None : target_site = "www.clusterlabs.org" name_label_max_len = 0 for key in self.cib_attrs_labels.keys() : make_label_active(self.cib_attrs_labels[key], _(name_cap(key)+":"), target_site) name_label_len = self.cib_attrs_labels[key].size_request()[0] if name_label_len > name_label_max_len : name_label_max_len = name_label_len for name_label in self.cib_attrs_labels.values() : name_label.set_size_request(name_label_max_len, -1) def __init__(self) : notebook = gtk.Notebook() self.notebook = notebook self.widget = notebook cluster_info_vbox = gtk.VBox() cluster_info_vbox.set_border_width(5) tab_label = gtk.Label(_("Cluster")) notebook.append_page(cluster_info_vbox, tab_label) self.cluster_info_vbox = cluster_info_vbox cib_vbox = gtk.VBox() cib_vbox.set_border_width(5) tab_label = gtk.Label(_("CIB")) notebook.append_page(cib_vbox, tab_label) cib_attrs_vbox = gtk.VBox() cib_vbox.pack_start(cib_attrs_vbox) self.cib_attrs_vbox = cib_attrs_vbox bbox = gtk.HButtonBox() bbox.set_layout(gtk.BUTTONBOX_END) bbox.set_spacing(5) xml_btn = gtk.Button(_("View XML")) bbox.add(xml_btn) cib_vbox.pack_start(bbox, False) xml_menu = gtk.Menu() for obj_type in ["cib", "configuration"] : if obj_type == "cib" : label_text = _("The Whole CIB") elif obj_type == "configuration" : label_text = _("The Configuration Section") xml_menu_item = gtk.MenuItem(label_text) xml_menu.append(xml_menu_item) xml_menu_item.connect("activate", self.edit_xml, obj_type) xml_menu.show_all() xml_btn.connect_object("event", self.popup_menu, xml_menu) self.update() def popup_menu(self, menu, event) : if event.type == gtk.gdk.BUTTON_PRESS : menu.popup(None, None, None, event.button, event.time) return True elif event.type == gtk.gdk.KEY_PRESS and event.keyval == gtk.keysyms.Return : menu.popup(None, None, None, event.keyval, event.time) return True return False def edit_xml(self, widget, obj_type) : init_cib_xml_node = manager.xml_nodes["cib"] if obj_type == "cib" : xml_node = init_cib_xml_node else : xml_nodes = init_cib_xml_node.getElementsByTagName(obj_type) if len(xml_nodes) < 1 : msgbox(_("The object \"%s\" doesn't exist")%obj_type) return xml_node = xml_nodes[0] orig_xml_node = xml_node.cloneNode(True) replace_xml_node = xml_node xml_dlg = EditXMLDlg(xml_node) while True : new_xml_node = xml_dlg.run() if new_xml_node == None : if obj_type != "cib" : replace_xml_node.parentNode.replaceChild(orig_xml_node, replace_xml_node) self.update() break if obj_type == "cib" : init_cib_xml_node = new_xml_node else : replace_xml_node.parentNode.replaceChild(new_xml_node, replace_xml_node) replace_xml_node = new_xml_node xml_str = new_xml_node.toxml().replace("\n", "") if not manager.validate_cib(init_cib_xml_node) : continue manager.cib_do_cmd("cib_replace\n%s\n%s"%(str(xml_node.tagName), str(xml_str))) if manager.failed_reason != "" : msgbox(manager.failed_reason) else : if obj_type == "cib" : manager.set_update() else : self.update() xml_dlg.destroy() break def save_status(self) : page_num = self.notebook.get_current_page() if page_num < 0 : return None else : return (page_num,) def restore_status(self, view_status) : if view_status == None : return (page_num,) = view_status self.notebook.set_current_page(page_num) class View : changed = False def __init__(self, param=None) : bbox = gtk.HButtonBox() bbox.set_layout(gtk.BUTTONBOX_END) bbox.set_spacing(5) default_btn = gtk.Button(_("Default")) bbox.add(default_btn) reset_btn = gtk.Button(_("Reset")) bbox.add(reset_btn) apply_btn = gtk.Button(stock=gtk.STOCK_APPLY) bbox.add(apply_btn) self.bbox = bbox self.default_btn_handler = default_btn.connect("clicked", self.on_default) self.reset_btn_handler = reset_btn.connect("clicked", self.on_reset) self.apply_btn_handler = apply_btn.connect("clicked", self.on_apply) self.default_btn = default_btn self.reset_btn = reset_btn self.apply_btn = apply_btn self.widget.pack_start(self.bbox, False, padding = 2) def update(self) : self.apply_btn.set_property("sensitive", False) self.reset_btn.set_property("sensitive", False) self.changed = False def on_changed(self, widget) : self.apply_btn.set_property("sensitive", True) self.reset_btn.set_property("sensitive", True) self.changed = True def on_reset(self, widget): self.update() def on_apply(self, widget): self.apply_btn.set_property("sensitive", False) self.reset_btn.set_property("sensitive", False) self.changed = False def on_default(self, widget): self.on_changed(widget) def on_after_show(self) : pass class CRMConfigView(View) : pengine_metadata = None crmd_metadata = None pengine_widgetgroup = None crmd_widgetgroup = None def on_apply(self, widget): current_page = self.notebook.get_current_page() if current_page == 0 : (widgetgroup, metadata) = (self.pengine_widgetgroup, self.pengine_metadata) else : (widgetgroup, metadata) = (self.crmd_widgetgroup, self.crmd_metadata) new_crm_config = widgetgroup.get_values() self.update_crm_config(metadata, new_crm_config) self.update() View.on_apply(self, widget) def on_default(self, widget): current_page = self.notebook.get_current_page() if current_page == 0 : (widgetgroup, metadata) = (self.pengine_widgetgroup, self.pengine_metadata) else : (widgetgroup, metadata) = (self.crmd_widgetgroup, self.crmd_metadata) default_crm_config = {} for parameter in metadata.parameters: default_crm_config[parameter["name"]] = str(parameter["content"]["default"]) if default_crm_config != {}: widgetgroup.show_values(default_crm_config) View.on_default(self, widget) def update(self, xml_node = None) : for (widgetgroup, metadata) in ((self.pengine_widgetgroup, self.pengine_metadata), (self.crmd_widgetgroup, self.crmd_metadata)): if metadata != None and widgetgroup != None: crm_config = self.get_crm_config(metadata) if crm_config != None : widgetgroup.show_values(crm_config) else : return False View.update(self) self.on_after_show() return True def get_crm_config(self, metadata) : global mode_level config = {} for parameter in metadata.parameters : config[parameter["name"]] = str(parameter["content"]["default"]) cluster_property_sets = manager.xml_nodes["cib"].getElementsByTagName("cluster_property_set") if len(cluster_property_sets) == 0 : return config elif len(cluster_property_sets) == 1 : for nvpair in cluster_property_sets[0].getElementsByTagName("nvpair") : name = nvpair.getAttribute("name") value = nvpair.getAttribute("value") if value != "" : config[nvpair.getAttribute("name")] = nvpair.getAttribute("value") return config else : mode_level = 2 window.radio_tool_action_group.get_action("hack-mode").set_active(True) msgbox(_("Multiple \"Cluster Property Set\" in \"CRM Config\".") + "\n" + _("We are switching to \"Hack Mode\" to view them properly.")) return None def update_crm_config(self, metadata, new_crm_config) : crm_config_xml_nodes = manager.xml_nodes["cib"].getElementsByTagName("crm_config") if len(crm_config_xml_nodes) < 1 : msgbox(_("Cannot update the crm configuration: No \"crm_config\" in CIB")) return (parent_xml_node, add_obj_type, new_mid_elem) = \ manager.real_add_obj_type(crm_config_xml_nodes[0], "cluster_property_set") if parent_xml_node == None : msgbox(_("Cannot update the crm configuration")) return nv_xml_nodes = {} for nv_xml_node in parent_xml_node.getElementsByTagName("nvpair") : nv_name = nv_xml_node.getAttribute("name") nv_xml_nodes[nv_name] = nv_xml_node default_crm_config = {} for parameter in metadata.parameters : default_crm_config[parameter["name"]] = str(parameter["content"]["default"]) if parameter["content"]["type"] == "integer" : try : default_value = float(parameter["content"]["default"]) if default_value == float("inf") : default_crm_config[parameter["name"]] = "1000000" elif default_value == float("-inf") : default_crm_config[parameter["name"]] = "-1000000" except : pass impl = getDOMImplementation() for attr_name, value in new_crm_config.iteritems() : nv_xml_node = nv_xml_nodes.get(attr_name) if nv_xml_node != None : if value != default_crm_config.get(attr_name) : nv_xml_node.setAttribute("value", value) else : nv_xml_node.parentNode.removeChild(nv_xml_node) else : if value != default_crm_config.get(attr_name) : newdoc = impl.createDocument(None, "nvpair", None) nv = newdoc.documentElement parent_xml_node.appendChild(nv) attr_id = manager.auto_unique_id(nv, attr_name) nv.setAttribute("id", attr_id) nv.setAttribute("name", attr_name) nv.setAttribute("value", value) xml_str = parent_xml_node.toxml().replace("\n", "") if new_mid_elem == None : manager.cib_do_cmd("cib_replace\ncrm_config\n%s"%(str(xml_str))) else : manager.cib_do_cmd("cib_create\ncrm_config\n%s"%(str(xml_str))) if manager.failed_reason != "" : msgbox(manager.failed_reason) def on_after_show(self) : target_site = "www.clusterlabs.org" for widgets in (self.pengine_widgetgroup.widgets, self.crmd_widgetgroup.widgets): if widgets != None: name_label_max_len = 0 for key in widgets["name_labels"].keys(): make_label_active(widgets["name_labels"][key], name_cap(key)+":", target_site) name_label_len = widgets["name_labels"][key].size_request()[0] if name_label_len > name_label_max_len : name_label_max_len = name_label_len for name_label in widgets["name_labels"].values() : name_label.set_size_request(name_label_max_len, -1) def on_notebook_event(self, widget, page, page_num) : global last_cluster_view_page_num if self.changed == True: ret = confirmbox(_("There are unsaved changes in current page.")+"\n"+_("Apply the changes?"), (gtk.STOCK_NO, gtk.RESPONSE_NO, gtk.STOCK_YES, gtk.RESPONSE_YES)) if ret == gtk.RESPONSE_YES : self.on_apply(widget) else : self.update() def __init__(self) : vbox = gtk.VBox() self.widget = vbox notebook = gtk.Notebook() self.notebook = notebook vbox.pack_start(notebook) pe_vbox = gtk.VBox() pe_vbox.set_border_width(5) tab_label = gtk.Label(_("Policy Engine")) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_NONE) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) sw.add_with_viewport(pe_vbox) sw.child.set_shadow_type(gtk.SHADOW_NONE) notebook.append_page(sw, tab_label) self.pe_vbox = pe_vbox crmd_vbox = gtk.VBox() crmd_vbox.set_border_width(5) tab_label = gtk.Label(_("CRM Daemon")) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_NONE) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) sw.add_with_viewport(crmd_vbox) sw.child.set_shadow_type(gtk.SHADOW_NONE) notebook.append_page(sw, tab_label) self.crmd_vbox = crmd_vbox self.pengine_metadata = manager.get_crm_metadata("pengine") self.crmd_metadata = manager.get_crm_metadata("crmd") if self.pengine_metadata != None: pengine_widgets = self.render_crmconf_widgets(self.pengine_metadata) self.pengine_widgetgroup = WidgetGroup(pengine_widgets) if self.crmd_metadata != None: crmd_widgets = self.render_crmconf_widgets(self.crmd_metadata) self.crmd_widgetgroup = WidgetGroup(crmd_widgets) notebook.connect("switch-page", self.on_notebook_event) View.__init__(self) self.widget.show_all() #self.update() def render_crmconf_widgets(self, metadata): if metadata.name == "Policy Engine": vbox = self.pe_vbox elif metadata.name == "CRM Daemon": vbox = self.crmd_vbox widgets = {} name_labels = {} combos = {} combo_entries = {} checkbuttons = {} spinbuttons = {} entries = {} parameters = metadata.parameters for row in range(len(parameters)): param_name = parameters[row]["name"] param_type = parameters[row]["content"]["type"] param_default = parameters[row]["content"]["default"] hbox = gtk.HBox() label = gtk.Label(param_name + ":") label.set_alignment(0, 0.5) eventbox = gtk.EventBox() eventbox.add(label) hbox.pack_start(eventbox, False, padding=5) name_labels[param_name] = label longdesc = parameters[row].get("longdesc") shortdesc = parameters[row].get("shortdesc") if len(longdesc) == 0 : tip = shortdesc elif longdesc.find(shortdesc) > -1 : tip = longdesc else : if shortdesc.endswith(_(".")) : tip = shortdesc + "\n" + longdesc else : tip = shortdesc + _(".") + "\n" + longdesc if param_default != "" : default_str = _("Default") + _(": ") + param_default if len(tip) > 0 : tip += "\n\n" + default_str else : tip = default_str if pygtk_newer(2, 12) : label.set_tooltip_text(tip) else : tooltips = gtk.Tooltips() tooltips.set_tip(label, tip) if param_type == "enum" and parameters[row]["content"].has_key("values"): store = gtk.ListStore(str, str) for option in parameters[row]["content"]["values"]: if param_default != None and option == param_default : store.insert(0, [option, "[ "+ _("default") + " ]"]) else : store.append([option, ""]) combo = gtk.ComboBox(store) cell0 = gtk.CellRendererText() cell1 = gtk.CellRendererText() combo.pack_start(cell0, True) combo.pack_start(cell1, True) combo.add_attribute(cell0, 'text', 0) combo.add_attribute(cell1, 'text', 1) combo.connect("changed", self.on_changed) hbox.pack_start(combo, False, padding=3) combos[param_name] = combo elif param_type == "boolean": checkbutton = gtk.CheckButton() checkbutton.connect("toggled", self.on_changed) hbox.pack_start(checkbutton, False) checkbuttons[param_name] = checkbutton elif param_type == "integer" and param_name.count("time") == 0 : try : default_value = float(param_default) except : default_value = float(extract_int(param_default)) if default_value == None : default_value = 0 if default_value == float("inf") : default_value = 1000000 elif default_value == float("-inf") : default_value = -1000000 if param_name.count("node-health") or param_name.count("stickiness") : min_value = -1000000 page_incr = 100 elif default_value < 0 : min_value = default_value page_incr = 100 else : min_value = 0 page_incr = 10 adj = gtk.Adjustment(default_value, min_value, 1000000, 1, page_incr) spinbutton = gtk.SpinButton(adj, 0, 0) #spinbutton.set_width_chars(7) spinbutton.set_wrap(True) spinbutton.connect("changed", self.on_changed) hbox.pack_start(spinbutton, False, padding=3) spinbuttons[param_name] = spinbutton elif param_default != "" or parameters[row]["content"].has_key("values") : store = gtk.ListStore(str, str) if parameters[row]["content"].has_key("values") : for option in parameters[row]["content"]["values"] : if param_default != None and option == param_default : store.insert(0, [option, "[ "+ _("default") + " ]"]) else : store.append([option, ""]) else : store.insert(0, [param_default, "[ "+ _("default") + " ]"]) combo_entry = gtk.ComboBoxEntry(store) cell = gtk.CellRendererText() combo_entry.pack_start(cell, True) combo_entry.add_attribute(cell, 'text', 1) combo_entry.connect("changed", self.on_changed) combo_entry.child.connect("activate", self.on_apply) hbox.pack_start(combo_entry, False, padding=3) combo_entries[param_name] = combo_entry else: entry = gtk.Entry() entry.connect("changed", self.on_changed) entry.connect("activate", self.on_apply) hbox.pack_start(entry, False, padding=3) entries[param_name] = entry vbox.pack_start(hbox, False, padding=1) vbox.show_all() widgets["name_labels"] = name_labels widgets["combos"] = combos widgets["combo_entries"] = combo_entries widgets["checkbuttons"] = checkbuttons widgets["spinbuttons"] = spinbuttons widgets["entries"] = entries return widgets def save_status(self) : page_num = self.notebook.get_current_page() if page_num < 0 : return None else : return (page_num,) def restore_status(self, view_status) : if view_status == None : return (page_num,) = view_status self.notebook.set_current_page(page_num) class ObjectView : obj_attrs = None elem_notebook = None def __init__(self, xml_node, is_newobj = False, change_call_back = None, is_topview = False, missing_opt_obj_parent_type = None, show_mode = 0) : self.is_newobj = is_newobj self.change_call_back = change_call_back self.is_topview = is_topview self.missing_opt_obj_parent_type = missing_opt_obj_parent_type self.show_mode = show_mode vbox = gtk.VBox() self.vbox = vbox self.widget = vbox self.mode_combobox = gtk.combo_box_new_text() self.mode_combobox.append_text(_("List Mode")) self.mode_combobox.append_text(_("Tree Mode")) self.mode_combobox.append_text(_("XML Mode")) self.mode_combobox.set_active(self.show_mode) self.mode_combobox.connect("changed", self.on_changed) self.hbox = gtk.HBox() self.hbox.pack_end(self.mode_combobox, False) self.label = gtk.Label(_("Show") + _(": ")) self.hbox.pack_end(self.label, False) self.vbox.pack_start(self.hbox, False, padding=2) self.update(xml_node) def update(self, xml_node = None) : is_newobj = self.is_newobj if type(xml_node) == str: impl = getDOMImplementation() newdoc = impl.createDocument(None, xml_node, None) self.xml_node = newdoc.documentElement self.init_xml_node = self.xml_node.cloneNode(True) self.is_fake_xml_node = True elif xml_node != None : self.xml_node = xml_node self.init_xml_node = self.xml_node.cloneNode(True) self.is_fake_xml_node = False objview_status = self.save_status() for child in self.vbox.get_children() : if child != self.hbox : self.vbox.remove(child) obj_type = self.xml_node.tagName attr_is_any_name = False elem_is_any_name = False if validate_type == "dtd" : self.dtd_elem = manager.get_dtd_elem(obj_type) attr_list = self.dtd_elem.get_attr_list() sub_obj_list = self.dtd_elem.get_content_model()[1] else : sorted_rng_nodes = manager.sorted_sub_rng_nodes_by_name(obj_type) attr_list = [] sub_obj_list = [] if sorted_rng_nodes != None : attr_rng_nodes = sorted_rng_nodes.get("attribute", []) elem_rng_nodes = sorted_rng_nodes.get("element", []) for rng_node in attr_rng_nodes : name = rng_node[0][1].getAttribute("name") if name == "" : attr_is_any_name = True elif attr_list.count(name) == 0 : attr_list.append(name) for rng_node in elem_rng_nodes : name = rng_node[0][1].getAttribute("name") if name == "" : elem_is_any_name = True else : sub_obj_list.append(name) else : attr_is_any_name = True elem_is_any_name = True if attr_is_any_name : for attr_name in self.xml_node.attributes.keys() : if attr_list.count(attr_name) == 0 : attr_list.append(attr_name) if elem_is_any_name : for elem_node in self.xml_node.childNodes : if elem_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue elem_name = elem_node.tagName if sub_obj_list.count(elem_name) == 0 : sub_obj_list.append(elem_name) if not self.is_topview and (len(attr_list) >0 or attr_is_any_name) : has_attr = True else : has_attr = False if len(sub_obj_list) or elem_is_any_name > 0 : has_elem = True else : has_elem = False if len(attr_list) > 4 : obj_box = gtk.HBox() self.vbox.pack_start(obj_box) else : obj_box = self.vbox if has_attr : if obj_type in ["primitive", "template"] : obj_attrs = Primitive(self.xml_node, is_newobj, self.change_call_back) elif obj_type == "rsc_order" : obj_attrs = RscOrder(self.xml_node, is_newobj, self.change_call_back) elif obj_type == "rsc_colocation" : obj_attrs = RscColocation(self.xml_node, is_newobj, self.change_call_back) elif obj_type == "nvpair" : if validate_type == "dtd" : if self.xml_node.parentNode.parentNode.tagName == "instance_attributes" and \ self.xml_node.parentNode.parentNode.parentNode.tagName in ["primitive", "template"] : obj_attrs = PrimInstAttrsNV(self.xml_node, is_newobj, self.change_call_back) elif self.xml_node.parentNode.parentNode.tagName == "instance_attributes" and \ self.xml_node.parentNode.parentNode.parentNode.tagName == "op" : obj_attrs = OPInstAttrsNV(self.xml_node, is_newobj, self.change_call_back) elif self.xml_node.parentNode.parentNode.tagName == "instance_attributes" and \ self.xml_node.parentNode.parentNode.parentNode.tagName == "node" : obj_attrs = InstAttrsNV(self.xml_node, is_newobj, self.change_call_back) elif self.xml_node.parentNode.parentNode.tagName == "meta_attributes" : obj_attrs = MetaAttrsNV(self.xml_node, is_newobj, self.change_call_back) elif self.xml_node.parentNode.parentNode.tagName == "cluster_property_set" : obj_attrs = CRMConfNV(self.xml_node, is_newobj, self.change_call_back) elif self.xml_node.parentNode.parentNode.tagName == "utilization" : obj_attrs = UtilizationNV(self.xml_node, is_newobj, self.change_call_back) else : obj_attrs = ObjectAttrs(self.xml_node, is_newobj, self.change_call_back) else : if self.xml_node.parentNode.tagName == "instance_attributes" and \ self.xml_node.parentNode.parentNode.tagName in ["primitive", "template"]: obj_attrs = PrimInstAttrsNV(self.xml_node, is_newobj, self.change_call_back) elif self.xml_node.parentNode.tagName == "instance_attributes" and \ self.xml_node.parentNode.parentNode.tagName == "op" : obj_attrs = OPInstAttrsNV(self.xml_node, is_newobj, self.change_call_back) elif self.xml_node.parentNode.tagName == "instance_attributes" and \ self.xml_node.parentNode.parentNode.tagName == "node" : obj_attrs = InstAttrsNV(self.xml_node, is_newobj, self.change_call_back) elif self.xml_node.parentNode.tagName == "meta_attributes" : if self.xml_node.parentNode.parentNode.tagName == "op_defaults" : obj_attrs = OPDefaultsNV(self.xml_node, is_newobj, self.change_call_back) else : obj_attrs = MetaAttrsNV(self.xml_node, is_newobj, self.change_call_back) elif self.xml_node.parentNode.tagName == "cluster_property_set" : obj_attrs = CRMConfNV(self.xml_node, is_newobj, self.change_call_back) elif self.xml_node.parentNode.tagName == "utilization" : obj_attrs = UtilizationNV(self.xml_node, is_newobj, self.change_call_back) else : obj_attrs = ObjectAttrs(self.xml_node, is_newobj, self.change_call_back) elif obj_type == "expression" : obj_attrs = Expression(self.xml_node, is_newobj, self.change_call_back) elif obj_type == "op" : obj_attrs = OP(self.xml_node, is_newobj, self.change_call_back) else : obj_attrs = ObjectAttrs(self.xml_node, is_newobj, self.change_call_back) obj_attrs.dynamic_choice_elem() obj_attrs.update() obj_box.pack_start(obj_attrs.attrs_vbox) self.obj_attrs = obj_attrs if has_elem : if obj_type in ["acl_user", "acl_role"] : single_page = True else : single_page = False self.elem_notebook = ElementNotebook(self.xml_node, self.is_topview, self.elem_change_call_back, self.show_mode, self.is_fake_xml_node, self.missing_opt_obj_parent_type, single_page) if self.elem_notebook.update(self.xml_node) : obj_box.pack_start(self.elem_notebook.widget, True, padding = 5) self.vbox.pack_start(self.elem_notebook.bbox, False, padding = 2) else : #if not self.is_topview : # self.update() self.update() return self.restore_status(objview_status) self.vbox.show_all() self.on_after_show() if not has_elem : self.label.hide_all() self.mode_combobox.hide_all() def elem_change_call_back(self) : if self.obj_attrs != None : self.obj_attrs.dynamic_choice_elem() if self.change_call_back != None : self.change_call_back() def save_status(self) : attrs_status = None if self.obj_attrs != None : attrs_status = self.obj_attrs.save_status() notebook_status = None if self.elem_notebook != None : notebook_status = self.elem_notebook.save_status() return (self.show_mode, attrs_status, notebook_status) def restore_status(self, objview_status) : #if objview_status == None : # return (show_mode, attrs_status, notebook_status) = objview_status if self.obj_attrs != None and attrs_status != None : self.obj_attrs.restore_status(attrs_status) if self.elem_notebook != None and notebook_status != None : self.elem_notebook.restore_status(notebook_status) def on_after_show(self) : if self.obj_attrs != None : self.obj_attrs.on_after_show() if self.elem_notebook != None : self.elem_notebook.on_after_show() def on_changed(self, widget) : show_mode = self.mode_combobox.get_active() if show_mode != 2 : self.show_mode = show_mode self.update() return self.edit_xml() self.mode_combobox.set_active(self.show_mode) def edit_xml(self) : init_cib_xml_node = manager.xml_nodes["cib"] orig_xml_node = self.xml_node.cloneNode(True) replace_xml_node = self.xml_node xml_dlg = EditXMLDlg(self.xml_node) while True : new_xml_node = xml_dlg.run() if new_xml_node == None : replace_xml_node.parentNode.replaceChild(orig_xml_node, replace_xml_node) self.xml_node = orig_xml_node self.update() break replace_xml_node.parentNode.replaceChild(new_xml_node, replace_xml_node) replace_xml_node = new_xml_node if not self.is_topview : xml_dlg.destroy() #self.xml_node.parentNode.replaceChild(new_xml_node, self.xml_node) self.xml_node = new_xml_node self.update() if self.change_call_back != None : self.change_call_back() break else : xml_str = new_xml_node.toxml().replace("\n", "") if self.is_fake_xml_node : manager.cib_do_cmd("cib_create\n%s\n%s" %(str(self.missing_opt_obj_parent_type), str(xml_str))) if manager.failed_reason != "" : msgbox(manager.failed_reason) else : if manager.active_cib != "" : manager.set_update() xml_dlg.destroy() break else : if not manager.validate_cib(init_cib_xml_node) : continue manager.cib_do_cmd("cib_replace\n%s\n%s"%(str(self.xml_node.tagName), str(xml_str))) if manager.failed_reason != "" : msgbox(manager.failed_reason) else : #self.xml_node.parentNode.replaceChild(new_xml_node, self.xml_node) self.xml_node = new_xml_node self.update() xml_dlg.destroy() break def validate(self) : passed = True if self.obj_attrs != None : passed = self.obj_attrs.verify_values() return passed def reset(self) : new_xml_node = self.init_xml_node.cloneNode(True) try : self.xml_node.parentNode.replaceChild(new_xml_node, self.xml_node) except xml.dom.NotFoundErr : msgbox(_("The object doesn't exist")) return self.xml_node = new_xml_node class EditXMLDlg: def __init__(self, xml_node) : global top_window self.xml_node = xml_node dialog = gtk.Dialog(_("Edit XML"), top_window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, str(_("Reset")), gtk.RESPONSE_APPLY, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL) dialog.set_default_size(750, 550) ui_xml = ''' ''' actions = [ ("import", gtk.STOCK_REVERT_TO_SAVED, _("Import"), "o", _("Import XML"), self.import_xml), ("export", gtk.STOCK_SAVE_AS, _("Export"), "s", _("Export XML"), self.export_xml) ] action_group = gtk.ActionGroup("rw_xml_file") action_group.add_actions(actions) uimanager = gtk.UIManager() uimanager.insert_action_group(action_group, 0) uimanager.add_ui_from_string(ui_xml) #toolbar = gtk.Toolbar() #toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL) #toolbar.set_style(gtk.TOOLBAR_BOTH) toolbar = uimanager.get_widget('/toolbar') toolbar.set_style(gtk.TOOLBAR_BOTH) dialog.vbox.pack_start(toolbar, False) #tool_item = action_group.get_action("import").create_tool_item() #toolbar.insert(tool_item, -1) #tool_item = action_group.get_action("export").create_tool_item() #toolbar.insert(tool_item, -1) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_IN) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.xml_text = gtk.TextView() self.xml_text.set_wrap_mode(gtk.WRAP_WORD) self.xml_textbuffer = self.xml_text.get_buffer() sw.add(self.xml_text) dialog.vbox.pack_start(sw, padding=1) dialog.set_response_sensitive(gtk.RESPONSE_APPLY, False) self.statusbar = gtk.Statusbar() dialog.vbox.pack_end(self.statusbar, False) self.xml_str = xml_node.toxml() self.xml_textbuffer.set_text(self.xml_str) self.update_statusbar() self.xml_textbuffer.connect("changed", self.on_changed) self.xml_text.connect_after("move-cursor", self.update_statusbar) self.xml_text.connect("event-after", self.on_click_text) self.xml_text.connect_after("toggle-overwrite", self.update_statusbar) dialog.show_all() self.dialog = dialog self.save_top_window = top_window top_window = dialog def on_changed(self, widget) : self.dialog.set_response_sensitive(gtk.RESPONSE_APPLY, True) self.update_statusbar() def on_click_text(self, widget, event) : if event.type == gtk.gdk.BUTTON_PRESS and event.button == 1 : self.update_statusbar() def update_statusbar(self, textview = None , step_size = None, count = None, extend_selection = None) : iter = self.xml_textbuffer.get_iter_at_mark(self.xml_textbuffer.get_insert()) line = iter.get_line() column = iter.get_line_offset() if self.xml_text.get_overwrite() : overwrite = _("OVR") else : overwrite = _("INS") self.statusbar.pop(0) self.statusbar.push(0, _("Ln %d, Col %d\t%s")%(line+1, column+1, overwrite)) def run(self) : while True : ret = self.dialog.run() if ret in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT] : self.destroy() return None elif ret == gtk.RESPONSE_APPLY : self.xml_textbuffer.set_text(self.xml_str) self.dialog.set_response_sensitive(gtk.RESPONSE_APPLY, False) else : new_xml_str = self.xml_textbuffer.get_text(*self.xml_textbuffer.get_bounds()) try : new_xml_node = parseString(new_xml_str).documentElement except xml.parsers.expat.ExpatError, msg : msgbox(_("Failed to parse the XML") + _(": ") + str(msg)) continue return new_xml_node def destroy(self) : global top_window self.dialog.destroy() top_window = self.save_top_window def import_xml(self, widget) : global top_window file_dialog = gtk.FileChooserDialog(_("Open File"), None, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) save_top_window = top_window top_window = file_dialog filter = gtk.FileFilter() filter.set_name(_("All files")) filter.add_pattern("*") file_dialog.add_filter(filter) filter = gtk.FileFilter() filter.set_name(_("XML files")) filter.add_pattern("*.xml") file_dialog.add_filter(filter) ret = file_dialog.run() if ret in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT] : open_file = None else : open_file = file_dialog.get_filename() top_window = save_top_window file_dialog.destroy() if open_file == None : return try : file_obj = open(open_file) except IOError, msg : msgbox(_("I/O error") + _(": ") + str(msg)) return try : new_xml_str = file_obj.read() except IOError, msg : msgbox(_("I/O error") + _(": ") + str(msg)) file_obj.close() return file_obj.close() self.xml_textbuffer.set_text(new_xml_str) def export_xml(self, widget) : sfdlg = SelectFileDlg() node_id = self.xml_node.getAttribute("id") if node_id == "" : default_name = self.xml_node.tagName + ".xml" else : default_name = self.xml_node.tagName + "-" + self.xml_node.getAttribute("id") + ".xml" (save_file, save_type) = sfdlg.select_file(default_name) if save_file == None : return try : fd = os.open(save_file, os.O_RDWR|os.O_CREAT|os.O_TRUNC, 0644) except OSError, msg : msgbox(_("System error") + _(": ") + str(msg)) return new_xml_str = self.xml_textbuffer.get_text(*self.xml_textbuffer.get_bounds()) try : os.write(fd, new_xml_str) except OSError, msg : msgbox(_("System error") + _(": ") + str(msg)) os.close(fd) return os.close(fd) class ElementNotebook : notebook = None new_page_type = None def __init__(self, xml_node, is_topview = False, change_call_back = None, show_mode = 0, is_fake_xml_node = False, missing_opt_obj_parent_type = None, single_page = False) : self.is_topview = is_topview self.change_call_back = change_call_back self.show_mode = show_mode self.is_fake_xml_node = is_fake_xml_node self.missing_opt_obj_parent_type = missing_opt_obj_parent_type self.single_page = single_page vbox = gtk.VBox() self.widget = vbox self.hbox = gtk.HBox() vbox.pack_start(self.hbox) self.sub_vbox = gtk.VBox() vbox.pack_start(self.sub_vbox, False) bbox = gtk.HButtonBox() bbox.set_layout(gtk.BUTTONBOX_END) bbox.set_spacing(5) add_btn = gtk.Button(stock=gtk.STOCK_ADD) bbox.add(add_btn) edit_btn = gtk.Button(stock=gtk.STOCK_EDIT) bbox.add(edit_btn) del_btn = gtk.Button(stock=gtk.STOCK_REMOVE) bbox.add(del_btn) self.bbox = bbox self.add_btn_handler = add_btn.connect("clicked", self.on_add) self.edit_btn_handler = edit_btn.connect("clicked", self.on_edit) self.del_btn_handler = del_btn.connect("clicked", self.on_del) self.add_btn = add_btn self.edit_btn = edit_btn self.del_btn = del_btn def update(self, xml_node = None) : global mode_level if xml_node != None : self.xml_node = xml_node self.elem_lists = [] self.pages = [] self.obj_type = self.xml_node.tagName for child in self.hbox.get_children() : self.hbox.remove(child) self.notebook = gtk.Notebook() self.hbox.pack_start(self.notebook, True, padding=2) if validate_type == "dtd" : self.dtd_elem = manager.get_dtd_elem(self.obj_type) names = [name for (name, mod) in self.dtd_elem.get_content_model()[1]] if self.single_page : elem_node_list = [] for elem_node in self.xml_node.childNodes : if elem_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue elem_node_list.append(elem_node) self.pages.append(None) if self.show_mode == 0 : elem_list = ElementList(names, elem_node_list) else : elem_list = ElementTree(names, elem_node_list) self.notebook.append_page(elem_list.widget) self.notebook.set_show_tabs(False) self.elem_lists.append(elem_list) elem_list.tree.connect("cursor-changed", self.on_cursor_changed) elem_list.tree.connect("event-after", self.on_click) else : for name in names : elem_node_list = [] for elem_node in self.xml_node.getElementsByTagName(name) : if elem_node in self.xml_node.childNodes : elem_node_list.append(elem_node) if len(elem_node_list) == 0 : if self.is_topview : continue elif mode_level != 0 : continue elif name in ["resource_set", "rule", "lifetime", "expression", "date_expression", "duration", "date_spec"] \ or (self.obj_type in ["group"] and name in ["instance_attributes"]) \ or (self.obj_type in ["clone", "master"] and name in ["primitive", "group", "instance_attributes"]) \ or (self.obj_type in ["op"] and name in ["meta_attributes", "instance_attributes"]) : continue #if len(elem_node_list) > 0 : if True : self.pages.append(name) tab_label = gtk.Label(_(name_cap(name))) sub_dtd_elem = manager.get_dtd_elem(name) if len(sub_dtd_elem.get_attr_list()) == 0 \ or (mode_level != 2 and name in ["meta_attributes", "instance_attributes", "operations", "cluster_property_set", "utilization"]) : if len(elem_node_list) > 1 and len(sub_dtd_elem.get_attr_list()) > 0 : mode_level = 2 window.radio_tool_action_group.get_action("hack-mode").set_active(True) #if not self.is_topview : if True : msgbox(_("The \"%s\" has multiple \"%s\" sets.") %(_(name_cap(self.obj_type)), _(name_cap(name))) + "\n" + _("We are switching to \"Hack Mode\" to view them properly.")) return False if len(sub_dtd_elem.get_attr_list()) == 0 : (name, mod) = sub_dtd_elem.get_content_model()[1][0] else : (name, mod) = sub_dtd_elem.get_content_model()[1][1] sub_elem_node_list = [] for elem_node in elem_node_list : for sub_elem_node in elem_node.childNodes : if sub_elem_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue if sub_elem_node.tagName == name : sub_elem_node_list.append(sub_elem_node) else : mode_level = 2 window.radio_tool_action_group.get_action("hack-mode").set_active(True) #if not self.is_topview : if True : msgbox(_("The \"%s\" has a \"%s\".") %(_(name_cap(elem_node.tagName)), name_cap(sub_elem_node.tagName)) + "\n" + _("We are switching to \"Hack Mode\" to view them properly.")) return False if len(sub_dtd_elem.get_attr_list()) == 0 : elem_node_list = sub_elem_node_list else : sub_sub_dtd_elem = manager.get_dtd_elem(name) (name, mod) = sub_sub_dtd_elem.get_content_model()[1][0] sub_sub_elem_node_list = [] for sub_elem_node in sub_elem_node_list : for sub_sub_elem_node in sub_elem_node.getElementsByTagName(name) : if sub_sub_elem_node in sub_elem_node.childNodes : sub_sub_elem_node_list.append(sub_sub_elem_node) elem_node_list = sub_sub_elem_node_list if self.show_mode == 0 : elem_list = ElementList([name], elem_node_list) else : elem_list = ElementTree([name], elem_node_list) self.notebook.append_page(elem_list.widget, tab_label) self.elem_lists.append(elem_list) elem_list.tree.connect("cursor-changed", self.on_cursor_changed) elem_list.tree.connect("event-after", self.on_click) else : elem_node_dict = {} for elem_node in self.xml_node.childNodes : if elem_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue name = elem_node.tagName if elem_node_dict.get(name) == None : elem_node_dict[name] = [] elem_node_dict[name].append(elem_node) sorted_rng_nodes = manager.sorted_sub_rng_nodes_by_name(self.obj_type) self.elem_rng_node_dict = {} self.attr_rng_node_dict = {} is_any_name = False elem_type_list = [] if sorted_rng_nodes != None : self.elem_rng_nodes = sorted_rng_nodes.get("element", []) attr_rng_nodes = sorted_rng_nodes.get("attribute", []) for rng_node in self.elem_rng_nodes : name = rng_node[0][1].getAttribute("name") if name == "" : is_any_name = True else : if elem_type_list.count(name) == 0 : elem_type_list.append(name) self.elem_rng_node_dict[name] = [] self.elem_rng_node_dict[name].append(rng_node) for rng_node in attr_rng_nodes : name = rng_node[0][1].getAttribute("name") if not self.attr_rng_node_dict.has_key(name) : self.attr_rng_node_dict[name] = [] self.attr_rng_node_dict[name].append(rng_node) else : self.elem_rng_nodes = [] is_any_name = True self.is_any_name = is_any_name other_elem_types = [] if is_any_name : for name in elem_node_dict.keys() : if elem_type_list.count(name) == 0 : other_elem_types.append(name) if self.single_page : names = [] for rng_node in self.elem_rng_nodes : name = rng_node[0][1].getAttribute("name") if names.count(name) == 0 : names.append(name) elem_node_list = [] for elem_node in self.xml_node.childNodes : if elem_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue elem_node_list.append(elem_node) self.pages.append(None) if self.show_mode == 0 : elem_list = ElementList(names, elem_node_list) else : elem_list = ElementTree(names, elem_node_list) self.notebook.append_page(elem_list.widget) self.notebook.set_show_tabs(False) self.elem_lists.append(elem_list) elem_list.tree.connect("cursor-changed", self.on_cursor_changed) elem_list.tree.connect("event-after", self.on_click) else : for rng_node in self.elem_rng_nodes : name = rng_node[0][1].getAttribute("name") elem_node_list = elem_node_dict.get(name, []) if len(elem_node_list) == 0 : if self.is_topview : continue elif mode_level != 0 : continue elif name in ["resource_set", "rule", "lifetime", "expression", "date_expression", "duration", "date_spec"] \ or (self.obj_type in ["group"] and name in ["instance_attributes"]) \ or (self.obj_type in ["clone", "master"] and name in ["primitive", "group", "instance_attributes"]) \ or (self.obj_type in ["op"] and name in ["meta_attributes", "instance_attributes"]) : continue self.pages.append(name) tab_label = gtk.Label(_(name_cap(name))) sub_rng_nodes = manager.sorted_sub_rng_nodes_by_node(*rng_node[0]) if sub_rng_nodes != None : sub_attr_rng_nodes = sub_rng_nodes.get("attribute", []) sub_elem_rng_nodes = sub_rng_nodes.get("element", []) if len(sub_attr_rng_nodes) == 0 \ or (mode_level != 2 and name in ["meta_attributes", "instance_attributes", "operations", "cluster_property_set", "utilization"]) : if len(elem_node_list) > 1 and len(sub_attr_rng_nodes) > 0 : mode_level = 2 window.radio_tool_action_group.get_action("hack-mode").set_active(True) #if not self.is_topview : if True : msgbox(_("The \"%s\" has multiple \"%s\" sets.") %(_(name_cap(self.obj_type)), _(name_cap(name))) + "\n" + _("We are switching to \"Hack Mode\" to view them properly.")) return False sub_elem_node_list = [] for sub_elem_rng_node in sub_elem_rng_nodes : if manager.find_decl(sub_elem_rng_node, "optional") != 0 : continue name = sub_elem_rng_node[0][1].getAttribute("name") for elem_node in elem_node_list : for sub_elem_node in elem_node.childNodes : if sub_elem_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue if sub_elem_node.tagName == name : sub_elem_node_list.append(sub_elem_node) else : mode_level = 2 window.radio_tool_action_group.get_action("hack-mode").set_active(True) #if not self.is_topview : if True : msgbox(_("The \"%s\" has a \"%s\".") %(_(name_cap(elem_node.tagName)), name_cap(sub_elem_node.tagName)) + "\n" + _("We are switching to \"Hack Mode\" to view them properly.")) return False elem_node_list = sub_elem_node_list break if self.show_mode == 0 : elem_list = ElementList([name], elem_node_list) else : elem_list = ElementTree([name], elem_node_list) self.notebook.append_page(elem_list.widget, tab_label) self.elem_lists.append(elem_list) elem_list.tree.connect("cursor-changed", self.on_cursor_changed) elem_list.tree.connect("event-after", self.on_click) for name in other_elem_types : elem_node_list = elem_node_dict.get(name, []) if len(elem_node_list) == 0 : continue self.pages.append(name) tab_label = gtk.Label(_(name_cap(name))) sub_attr_list = [] for elem_node in elem_node_list : for attr_name in elem_node.attributes.keys() : if sub_attr_list.count(attr_name) == 0 : sub_attr_list.append(attr_name) if len(sub_attr_list) == 0 : sub_elem_node_list = [] for elem_node in elem_node_list : for sub_elem_node in elem_node.childNodes : if sub_elem_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue name = sub_elem_node.tagName sub_elem_node_list.append(sub_elem_node) elem_node_list = sub_elem_node_list if self.show_mode == 0 : elem_list = ElementList([name], elem_node_list) else : elem_list = ElementTree([name], elem_node_list) self.notebook.append_page(elem_list.widget, tab_label) self.elem_lists.append(elem_list) elem_list.tree.connect("cursor-changed", self.on_cursor_changed) elem_list.tree.connect("event-after", self.on_click) if self.notebook.get_n_pages() > 0 : bbox = gtk.VButtonBox() bbox.set_layout(gtk.BUTTONBOX_SPREAD) bbox.set_spacing(5) up_btn = gtk.Button(stock=gtk.STOCK_GO_UP) bbox.add(up_btn) down_btn = gtk.Button(stock=gtk.STOCK_GO_DOWN) bbox.add(down_btn) self.hbox.pack_start(bbox, False, padding=2) self.up_btn = up_btn self.down_btn = down_btn up_btn.connect("clicked", self.on_up) down_btn.connect("clicked", self.on_down) self.hbox.show_all() self.notebook.set_size_request(350, 180) self.notebook.set_scrollable(True) self.notebook.popup_enable() self.notebook.connect("switch-page", self.on_switch_page) return True def on_after_show(self, page_num = None) : selected_node = self.get_selected_node(page_num) self.edit_btn.set_sensitive(selected_node != None) self.del_btn.set_sensitive(selected_node != None) elem_list = self.get_elem_list(page_num) if elem_list == None or selected_node == None : self.show_sub_attrs(None) return (model, iter) = elem_list.tree.get_selection().get_selected() self.up_btn.set_sensitive(iter != None and model.get_path(iter)[-1] != 0) self.down_btn.set_sensitive(iter != None and model.iter_next(iter) != None) self.show_sub_attrs(selected_node) def show_sub_attrs(self, selected_node) : for child in self.sub_vbox.get_children() : self.sub_vbox.remove(child) if selected_node == None : return if validate_type == "dtd" : dtd_elem = manager.get_dtd_elem(selected_node.tagName) attr_list = dtd_elem.get_attr_list() else : attr_list = [] is_any_name = False sorted_rng_nodes = manager.sorted_sub_rng_nodes_by_name(selected_node.tagName) if sorted_rng_nodes != None : attr_rng_nodes = sorted_rng_nodes.get("attribute", []) for rng_node in attr_rng_nodes : name = rng_node[0][1].getAttribute("name") if name == "" : is_any_name = True elif attr_list.count(name) == 0 : attr_list.append(name) else : is_any_name = True if is_any_name : for attr_name in selected_node.attributes.keys() : if attr_list.count(attr_name) == 0 : if attr_name == "id" : attr_list.insert(0, attr_name) else : attr_list.append(attr_name) name_labels = {} name_label_max_len = 0 for attr_name in attr_list : attr_value = selected_node.getAttribute(attr_name) if attr_value == "" or name_labels.get(attr_name) != None : continue hbox = gtk.HBox() name_label = gtk.Label(_(name_cap(attr_name)+":")) name_label.set_alignment(0, 0.5) name_label.set_selectable(True) name_labels[attr_name] = name_label name_label_len = name_label.size_request()[0] if name_label_len > name_label_max_len : name_label_max_len = name_label_len value_label = gtk.Label(attr_value) value_label.set_alignment(0, 0.5) value_label.set_selectable(True) hbox.pack_start(name_label, False, padding=5) hbox.pack_start(value_label, False, padding=5) self.sub_vbox.pack_start(hbox, False, padding=2) for name_label in name_labels.values() : name_label.set_size_request(name_label_max_len + 20, -1) self.sub_vbox.show_all() def on_cursor_changed(self, treeview) : self.on_after_show() def on_click(self, widget, event) : if (event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1) \ or ( event.type == gtk.gdk.KEY_PRESS and event.keyval == gtk.keysyms.Return) : self.on_edit(widget) def on_switch_page(self, notebook, page, page_num) : self.on_after_show(page_num) def get_selected_node(self, page_num = None) : if page_num == None : page_num = self.notebook.get_current_page() if page_num >= 0 : selected_node = self.elem_lists[page_num].get_selected_node() else : selected_node = None return selected_node def get_elem_list(self, page_num = None) : if page_num == None : page_num = self.notebook.get_current_page() if page_num >= 0 : elem_list = self.elem_lists[page_num] else : elem_list = None return elem_list def on_add(self, widget = None, invoked_by_wizard = False, append_title = "") : global top_window init_cib_xml_node = manager.xml_nodes["cib"] elem_rng_nodes = [] if validate_type == "dtd" : option_list = self.get_elem_options_dtd() else : option_list = [] elem_is_any_name = False elem_rng_nodes = self.get_elem_options_rng() if elem_rng_nodes == [] : elem_is_any_name = self.is_any_name for rng_node in elem_rng_nodes : name = rng_node[0][1].getAttribute("name") if name == "" : elem_is_any_name = True else : option_list.append(rng_node) if elem_is_any_name : for elem_node in self.xml_node.childNodes : if elem_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue elem_name = elem_node.tagName if option_list.count(elem_name) == 0 : option_list.append(elem_name) page_num = self.notebook.get_current_page() if page_num >= 0 : current_type = self.pages[page_num] else : current_type = None if len(option_list) == 0 and not elem_is_any_name : return 0 elif len(option_list) == 1 and not elem_is_any_name and not invoked_by_wizard \ and ((validate_type == "dtd" and option_list[0] != "lifetime") or (validate_type != "dtd" and option_list[0][0][1].getAttribute("name") != "lifetime")) : obj_type = option_list[0] elif not invoked_by_wizard and mode_level == 0 and ( self.obj_type in ["node", "primitive", "template", "group"] or (self.obj_type in ["clone", "master"] and (self.pages.count("primitive") > 0 or self.pages.count("group") > 0)) ) : if self.obj_type in ["clone", "master"] \ and (self.pages.count("primitive") > 0 or self.pages.count("group") > 0) \ and current_type in ["primitive", "group"] : return 0 obj_type = current_type else : dialog = gtk.Dialog(_("Add"), top_window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_border_width(5) dialog.set_default_response(gtk.RESPONSE_OK) if append_title != "" : label = gtk.Label(append_title) label.set_markup('' + append_title + '') label.set_alignment(0, 0) dialog.vbox.pack_start(label, False, padding=2) separator = gtk.HSeparator() dialog.vbox.pack_start(separator, False, padding = 2) radio_btns = {} radio_btn = None for option in option_list : if type(option) == str or type(option) == unicode : opt_name = option else : opt_name = option[0][1].getAttribute("name") if opt_name == "" : continue if invoked_by_wizard and opt_name in ["meta_attributes", "instance_attributes", "operations"] : continue radio_btn = gtk.RadioButton(radio_btn, _(name_cap(opt_name))) if opt_name == current_type : radio_btn.set_active(True) dialog.vbox.pack_start(radio_btn, False, padding=2) radio_btns[radio_btn] = option if elem_is_any_name : radio_btn = gtk.RadioButton(radio_btn, _("Other") + _(":")) entry = gtk.Entry() entry.set_activates_default(True) hbox = gtk.HBox() hbox.pack_start(radio_btn, False, padding=2) hbox.pack_start(entry, True, padding=2) dialog.vbox.pack_start(hbox, False, padding=2) radio_btns[radio_btn] = entry if len(radio_btns) == 0 : return 0 save_top_window = top_window top_window = dialog dialog.vbox.show_all() while True : ret = dialog.run() if ret == gtk.RESPONSE_OK : passed = True for radio_btn in radio_btns : if radio_btn.get_active() : obj_type = radio_btns[radio_btn] if type(obj_type) == gtk.Entry and obj_type.get_text() == "" : msgbox(_("Please specify the type of object you want to add")) passed = False break if passed : break else : obj_type = None break top_window = save_top_window dialog.destroy() if obj_type == None : return 0 if validate_type == "dtd" : obj_type_name = obj_type else : if type(obj_type) == str or type(obj_type) == unicode : obj_type_name = obj_type #sorted_rng_nodes = manager.sorted_sub_rng_nodes_by_name(obj_type_name) elif type(obj_type) == gtk.Entry : obj_type_name = obj_type.get_text() #sorted_rng_nodes = manager.sorted_sub_rng_nodes_by_name(obj_type_name) else : obj_type_name = obj_type[0][1].getAttribute("name") #sorted_rng_nodes = manager.sorted_sub_rng_nodes_by_node(*obj_type[0]) (parent_xml_node, add_obj_type, new_mid_elem) = manager.real_add_obj_type(self.xml_node, obj_type_name) if parent_xml_node == None : return 1 if obj_type_name not in manager.get_supported_rsc_types() : add_mode = "dialog" elif invoked_by_wizard or mode_level == 0 : add_mode = "wizard" else : dialog = gtk.Dialog("Select Mode", top_window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_border_width(5) dialog.set_default_response(gtk.RESPONSE_OK) wizard_radio_btn = gtk.RadioButton(None, _("Wizard")) dialog.vbox.pack_start(wizard_radio_btn, False, padding=2) dialog_radio_btn = gtk.RadioButton(wizard_radio_btn, _("Dialog")) dialog.vbox.pack_start(dialog_radio_btn, False, padding=2) save_top_window = top_window top_window = dialog dialog.vbox.show_all() ret = dialog.run() if ret == gtk.RESPONSE_OK : if wizard_radio_btn.get_active() : add_mode = "wizard" else : add_mode = "dialog" else : add_mode = None top_window = save_top_window dialog.destroy() if add_mode == None : return 1 impl = getDOMImplementation() newdoc = impl.createDocument(None, add_obj_type, None) new_elem = newdoc.documentElement parent_xml_node.appendChild(new_elem) if add_mode == "wizard" : objdlg = AddWizard(new_elem) else : objdlg = ObjectViewDlg(new_elem, True) while True : new_xml_node = objdlg.run() if new_xml_node == None : tmp_elem = objdlg.obj_view.xml_node tmp_elem.parentNode.removeChild(tmp_elem) if new_mid_elem != None : new_mid_elem.parentNode.removeChild(new_mid_elem) if self.is_topview and window.cur_view != None : window.cur_view.update() return 2 if not self.is_topview : objdlg.destroy() self.new_page_type = obj_type_name self.on_changed() if self.change_call_back != None : self.change_call_back() return 3 else : if self.is_fake_xml_node : parent_xml_node = self.xml_node.cloneNode(True) #parent_xml_node.appendChild(new_xml_node) xml_str = parent_xml_node.toxml().replace("\n", "") parent_type = self.missing_opt_obj_parent_type if parent_type == None : if parent_xml_node.tagName != "node_state" : parent_type = "configuration" else : parent_type = "status" manager.cib_do_cmd("cib_create\n%s\n%s"%(str(parent_type), str(xml_str))) else : if not manager.validate_cib(init_cib_xml_node) : continue #xml_str = new_xml_node.toxml().replace("\n", "") #parent_type = self.obj_type xml_str = self.xml_node.toxml().replace("\n", "") manager.cib_do_cmd("cib_replace\n%s\n%s"%(str(self.obj_type), str(xml_str))) if manager.failed_reason != "" : msgbox(manager.failed_reason) else : if manager.active_cib != "" : manager.set_update() objdlg.destroy() self.new_page_type = obj_type_name return 3 def get_elem_options_dtd(self) : (sep,cont,mod) = self.dtd_elem.get_content_model() option_list = [] if mod == "*" : for sub in cont : if len(sub) == 2 : option_list.append(sub[0]) else : if sep != "|" : for sub in cont : if len(sub) == 2 : if sub[1] == "*" or sub[1] == "+": option_list.append(sub[0]) elif sub[1] == "" or sub[1] == "?" : elem_node_list = [] for elem_node in self.xml_node.getElementsByTagName(sub[0]) : if elem_node in self.xml_node.childNodes : elem_node_list.append(elem_node) if len(elem_node_list) < 1 or \ len(manager.get_dtd_elem(sub[0]).get_attr_list()) == 0 : option_list.append(sub[0]) return option_list def get_elem_options_rng(self) : attr_rng_node_dict = self.attr_rng_node_dict elem_rng_node_dict = self.elem_rng_node_dict object_attrs = {} for (k, v) in self.xml_node.attributes.items() : object_attrs[k] = v ref_match_value_decl_nodes_list = [] ref_decl_nodes_list = [] for key in object_attrs : for attr_rng_node in attr_rng_node_dict.get(key, []) : decl_rng_nodes = manager.get_decl_rng_nodes(attr_rng_node) value_list = [] sub_rng_nodes = manager.sorted_sub_rng_nodes_by_node(*attr_rng_node[0]) for value_node in sub_rng_nodes.get("value", []) : value_list.append(value_node[0][1].childNodes[0].data) if object_attrs.get(key, "") in value_list : ref_match_value_decl_nodes_list.append(decl_rng_nodes) elif len(sub_rng_nodes.get("data", [])) > 0 or len(sub_rng_nodes.get("text", [])) > 0 : ref_decl_nodes_list.append(decl_rng_nodes) if len(ref_match_value_decl_nodes_list) > 0 : ref_decl_nodes_list = ref_match_value_decl_nodes_list ref_sorted_nodes = {} for decl_type in ["choice", "first_choice", "group", "first_group"] : ref_sorted_nodes[decl_type] = manager.get_sorted_decl_nodes(ref_decl_nodes_list, decl_type) elem_node_dict = {} for elem_node in self.xml_node.childNodes : if elem_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue elem_type = elem_node.tagName if not elem_node_dict.has_key(elem_type) : elem_node_dict[elem_type] = [] elem_node_dict[elem_type].append(elem_node) exist_elem_rng_nodes = [] ref_elem_decl_nodes_list = [] for key in elem_node_dict : for elem_rng_node in elem_rng_node_dict.get(key, []): if len(elem_node_dict[key]) > 1 and manager.find_decl(elem_rng_node, "oneOrMore") == 0 \ and manager.find_decl(elem_rng_node, "zeroOrMore") == 0 : continue exist_elem_rng_nodes.append(elem_rng_node) decl_rng_nodes = manager.get_decl_rng_nodes(elem_rng_node) ref_elem_decl_nodes_list.append(decl_rng_nodes) ref_elem_sorted_nodes = {} for decl_type in ["choice", "first_choice", "group", "first_group"] : ref_elem_sorted_nodes[decl_type] = manager.get_sorted_decl_nodes(ref_elem_decl_nodes_list, decl_type) option_list = [] for rng_node in self.elem_rng_nodes : name = rng_node[0][1].getAttribute("name") if option_list.count(name) > 0 : continue can_add = True if rng_node not in exist_elem_rng_nodes : decl_rng_nodes = manager.get_decl_rng_nodes(rng_node) if decl_rng_nodes.get("choice") != None : for sorted_nodes in [ref_sorted_nodes, ref_elem_sorted_nodes] : if decl_rng_nodes["choice"] in sorted_nodes["choice"] : if manager.find_decl(rng_node, "zeroOrMore") != 0 and \ manager.find_decl(rng_node, "zeroOrMore") > \ manager.find_decl(rng_node, "choice") : continue if manager.find_decl(rng_node, "oneOrMore") != 0 and \ manager.find_decl(rng_node, "oneOrMore") > \ manager.find_decl(rng_node, "choice") : continue if len(sorted_nodes["group"]) == 0 : can_add = False else : if decl_rng_nodes.get("group") not in sorted_nodes["group"] : can_add = False elif decl_rng_nodes.get("first_choice") in sorted_nodes["first_choice"] and \ decl_rng_nodes.get("first_group") not in sorted_nodes["first_group"] : can_add = False if not can_add : continue if manager.find_decl(rng_node, "zeroOrMore") != 0 or manager.find_decl(rng_node, "oneOrMore") != 0 : option_list.append(rng_node) else : sub_rng_nodes = manager.sorted_sub_rng_nodes_by_node(*rng_node[0]) if len(elem_node_dict.get(name, [])) < 1 or len(sub_rng_nodes.get("attribute", [])) == 0 \ or (mode_level != 2 and name in ["operations"]): option_list.append(rng_node) return option_list def on_edit(self, widget) : init_cib_xml_node = manager.xml_nodes["cib"] selected_node = self.get_selected_node() if selected_node == None : return objdlg = ObjectViewDlg(selected_node, False) while True : new_xml_node = objdlg.run() if new_xml_node == None : if not self.is_topview : self.on_changed() else : if window.cur_view != None : window.cur_view.update() return if not self.is_topview : objdlg.destroy() self.on_changed() if self.change_call_back != None : self.change_call_back() return else : if not manager.validate_cib(init_cib_xml_node) : continue #if new_xml_node.getAttribute("id") != "" : # xml_str = new_xml_node.toxml().replace("\n", "") #else : # xml_str = new_xml_node.parentNode.toxml().replace("\n", "") xml_str = self.xml_node.toxml().replace("\n", "") manager.cib_do_cmd("cib_replace\n%s\n%s"%(str(self.obj_type), str(xml_str))) if manager.failed_reason != "" : msgbox(manager.failed_reason) else : if window.cur_view != None : window.cur_view.update() objdlg.destroy() return def on_del(self, widget) : selected_node = self.get_selected_node() if selected_node == None : return ret = confirmbox(_("This will delete the %s \"%s\"")%(_(name_cap(selected_node.tagName)), selected_node.getAttribute("id")), (gtk.STOCK_NO, gtk.RESPONSE_NO, gtk.STOCK_YES, gtk.RESPONSE_YES), _("Delete the selected object?")) if ret == gtk.RESPONSE_YES : selected_node.parentNode.removeChild(selected_node) if not self.is_topview : self.on_changed() if self.change_call_back != None : self.change_call_back() else : #manager.validate_cib() #xml_str = selected_node.toxml().replace("\n", "") #manager.cib_do_cmd("cib_delete\n%s\n%s"%(str(self.obj_type), str(xml_str))) #if manager.failed_reason != "" : # msgbox(manager.failed_reason) if manager.validate_cib() : xml_str = selected_node.toxml().replace("\n", "") manager.cib_do_cmd("cib_delete\n%s\n%s"%(str(self.obj_type), str(xml_str))) if manager.failed_reason != "" : msgbox(manager.failed_reason) if manager.active_cib != "" : manager.set_update() elif manager.active_cib != "" : self.on_changed() else : manager.set_update() def on_up(self, widget) : elem_list = self.get_elem_list() if elem_list == None : return (model, iter) = elem_list.tree.get_selection().get_selected() if iter == None or model.get_path(iter)[-1] == 0 : return (type, id) = elem_list.get_node_key(model, iter) path = model.get_path(iter) if path[-1] < 1 : return prev_path_list = list(path[:]) prev_path_list[-1] = prev_path_list[-1] - 1 prev_path = tuple(prev_path_list) prev_iter = model.get_iter(prev_path) (prev_type, prev_id) = elem_list.get_node_key(model, prev_iter) selected_node = elem_list.nodes[(type, id)] prev_node = elem_list.nodes[(prev_type, prev_id)] try : selected_node.parentNode.insertBefore(selected_node.cloneNode(True), prev_node) except : return selected_node.parentNode.removeChild(selected_node) if self.is_topview : if manager.validate_cib() : xml_str = self.xml_node.toxml().replace("\n", "") manager.cib_do_cmd("cib_replace\n%s\n%s"%(str(self.obj_type), str(xml_str))) if manager.failed_reason != "" : msgbox(manager.failed_reason) if manager.active_cib != "" : manager.set_update() else : self.on_changed() else : manager.set_update() else : self.on_changed() if self.change_call_back != None : self.change_call_back() def on_down(self, widget) : elem_list = self.get_elem_list() if elem_list == None : return (model, iter) = elem_list.tree.get_selection().get_selected() if iter == None or model.iter_next(iter) == None : return (type, id) = elem_list.get_node_key(model, iter) selected_node = elem_list.nodes[(type, id)] n_iter = model.iter_next(iter) nn_iter = model.iter_next(n_iter) if nn_iter == None : try : selected_node.parentNode.appendChild(selected_node.cloneNode(True)) except : return else : (nn_type, nn_id) = elem_list.get_node_key(model, nn_iter) nn_node = elem_list.nodes[(nn_type, nn_id)] try : selected_node.parentNode.insertBefore(selected_node.cloneNode(True), nn_node) except : return selected_node.parentNode.removeChild(selected_node) if self.is_topview : if manager.validate_cib() : xml_str = self.xml_node.toxml().replace("\n", "") manager.cib_do_cmd("cib_replace\n%s\n%s"%(str(self.obj_type), str(xml_str))) if manager.failed_reason != "" : msgbox(manager.failed_reason) if manager.active_cib != "" : manager.set_update() else : self.on_changed() else : manager.set_update() else : self.on_changed() if self.change_call_back != None : self.change_call_back() def on_changed(self) : notebook_status = self.save_status() self.update() if notebook_status != None : self.restore_status(notebook_status) else : self.on_after_show() def save_status(self) : page_num = self.notebook.get_current_page() if page_num < 0 : return None page_type = self.pages[page_num] new_page_type = self.new_page_type self.new_page_type = None tree_status = {} for i in range(len(self.elem_lists)) : tree_status[self.pages[i]] = self.elem_lists[i].save_tree_status() return (page_type, new_page_type, tree_status) def restore_status(self, notebook_status) : (page_type, new_page_type, tree_status) = notebook_status if new_page_type != None : set_page_type = new_page_type else : set_page_type = page_type for i in range(len(self.elem_lists)) : page_name = self.pages[i] if page_name == set_page_type : self.notebook.set_current_page(i) if tree_status.get(page_name) != None : self.elem_lists[i].restore_tree_status(tree_status[page_name]) self.on_after_show() class AddWizard : current_page = None def __init__(self, xml_node) : self.xml_node = xml_node self.obj_type = xml_node.tagName common_options = [ ("target-role", [["", "Defaults to \"Started\" or inherit from its parent"], ["Started", ""], ["Stopped", ""]], _("Initial state of resource")), ] clone_basic_options = [ ("clone-max", [], _("Maximum number of copies (Defaults to the number of nodes in the cluster)")), ("clone-node-max", [["1", _("[ default ]")]], _("Maximum number of copies on a single node (Defaults to 1)")), ] clone_other_options = [ ("notify", [["false", _("[ default ]")], ["true", ""]], _("Notify all the other copies before stopping or starting a copy and when the action was successful (Defaults to false)")), ("globally-unique", [["false", _("[ default ]")], ["true", ""]], _("Globally Unique (Does each copy of the clone perform a different function? Defaults to false)")), ("interleave", [["false", _("[ default ]")], ["true", ""]], _("Interleave (Changes the behavior of ordering constraints (between clones/masters) so that instances can start/stop as soon as their peer instance has (rather than waiting for every instance of the other clone has). Defaults to false)")), ] master_basic_options = [ ("master-max", [["1", _("[ default ]")]], _("Maximum number of master copies (Defaults to 1)")), ("master-node-max", [["1", _("[ default ]")]], _("Maximum number of master copies on a single node (Defaults to 1)")) ] meta_attributes_options = { "primitive": common_options, "template": common_options, "group": common_options, "clone": common_options + clone_basic_options + clone_other_options, "master": common_options + clone_basic_options + master_basic_options + clone_other_options, } self.meta_attributes_options = meta_attributes_options self.default_meta_attributes = {} for option in meta_attributes_options[self.obj_type] : if validate_type == "dtd" : key = option[0].replace("-", "_") else : key = option[0] for (value, decl) in option[1] : if decl.count(_("[ default ]")) > 0 : self.default_meta_attributes[key] = value def first_page_render(self) : title = _("Add") + " " + _(name_cap(self.xml_node.tagName)) dialog = gtk.Dialog(title, top_window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_GO_FORWARD, gtk.RESPONSE_OK)) dialog.set_border_width(5) dialog.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL) dialog.set_default_response(gtk.RESPONSE_OK) self.dialog = dialog self.current_page = 0 label = gtk.Label() label_text = title + " - " + _("Basic Settings") label.set_markup('' + label_text + '') label.set_alignment(0, 0) label.show() dialog.vbox.pack_start(label, False, padding = 2) separator = gtk.HSeparator() separator.show() dialog.vbox.pack_start(separator, False, padding = 2) if self.obj_type in ["primitive", "template"] : obj_attrs = Primitive(self.xml_node, True, hide_optional = True) else : obj_attrs = obj_attrs = ObjectAttrs(self.xml_node, True, hide_optional = True) obj_attrs.update() obj_attrs.on_after_show() dialog.vbox.pack_start(obj_attrs.attrs_vbox) self.obj_attrs = obj_attrs self.obj_view = obj_attrs label = gtk.Label() label.set_markup('' + _("Options") + '') label.set_alignment(0, 1) label.show() dialog.vbox.pack_start(label, False, padding = 2) meta_attributes = self.get_meta_attributes() combos = {} checkbuttons = {} spinbuttons = {} self.num_buttons_map = {} for option in self.meta_attributes_options[self.obj_type] : if validate_type == "dtd" : key = option[0].replace("-", "_") else : key = option[0] is_boolean = False for value in option[1] : if value[0] in ["true", "false"] : is_boolean = True break hbox = gtk.HBox() if not is_boolean : name_label = gtk.Label(option[2] + _(":")) name_label.set_alignment(0, 0.5) if key.count("max") > 0 : num_checkbutton = gtk.CheckButton() num_checkbutton.add(name_label) num_checkbutton.connect("toggled", self.on_num_checkbutton_toggled) if meta_attributes.get(key, "") != "" : num_checkbutton.set_active(True) hbox.pack_start(num_checkbutton, False, padding=2) else : hbox.pack_start(name_label, False, padding=2) if is_boolean : label = gtk.Label(option[2]) label.set_line_wrap(True) widget = gtk.CheckButton() widget.add(label) checkbuttons[key] = widget hbox.pack_start(widget, True, padding=2) elif key.count("max") > 0 : if key in ["clone-max", "clone_max"] : node_list = manager.get_normal_nodes() if node_list != None and len(node_list) > 0 : init_value = len(node_list) else : init_value = 1 else : init_value = 1 adj = gtk.Adjustment(init_value, 1, 999, 1, 3) widget = gtk.SpinButton(adj, 0, 0) widget.set_width_chars(3) widget.set_wrap(True) if meta_attributes.get(key, "") == "" : widget.set_sensitive(False) self.num_buttons_map[num_checkbutton] = widget hbox.pack_start(widget, False) spinbuttons[key] = widget else : store = gtk.ListStore(str, str) for value in option[1] : store.append(value) widget = gtk.ComboBox(store) cell0 = gtk.CellRendererText() cell1 = gtk.CellRendererText() widget.pack_start(cell0, True) widget.pack_start(cell1, True) widget.add_attribute(cell0, 'text', 0) widget.add_attribute(cell1, 'text', 1) combos[key] = widget hbox.pack_start(widget, True, padding=2) hbox.show_all() dialog.vbox.pack_start(hbox, False, padding=2) widgets = {} widgets["combos"] = combos widgets["checkbuttons"] = checkbuttons widgets["spinbuttons"] = spinbuttons widget_group = WidgetGroup(widgets) self.widget_group = widget_group if self.obj_type in ["primitive", "template"]: label = gtk.Label(_("Add monitor operation")) self.monitor_checkbutton = gtk.CheckButton() self.monitor_checkbutton.add(label) self.monitor_checkbutton.show_all() dialog.vbox.pack_start(self.monitor_checkbutton, False, padding=2) def on_num_checkbutton_toggled(self, widget) : spinbutton = self.num_buttons_map.get(widget) if spinbutton != None : spinbutton.set_sensitive(widget.get_active()) def get_meta_attributes(self) : meta_attributes = {} for meta_attributes_node in self.xml_node.getElementsByTagName("meta_attributes") : for nv_xml_node in meta_attributes_node.getElementsByTagName("nvpair") : attribute_name = nv_xml_node.getAttribute("name") meta_attributes[attribute_name] = nv_xml_node.getAttribute("value") break return meta_attributes def first_page_update(self) : meta_attributes = self.get_meta_attributes() tmp_meta_attributes = self.default_meta_attributes.copy() tmp_meta_attributes.update(meta_attributes) self.widget_group.show_values(tmp_meta_attributes) if self.obj_type in ["primitive", "template"]: monitors = self.get_monitors() if len(monitors) > 0 : self.monitor_checkbutton.set_active(True) else : self.monitor_checkbutton.set_active(False) def first_page_run(self) : global top_window dialog = self.dialog dialog.vbox.show() save_top_window = top_window top_window = dialog while True : ret = dialog.run() if ret == gtk.RESPONSE_OK : passed = self.obj_attrs.verify_values() if not passed : continue dialog.destroy() top_window = save_top_window self.set_meta_attributes() if self.obj_type in ["primitive", "template"] : meta = self.get_rsc_meta() self.set_monitor(meta) self.set_inst_attributes(meta) return self.last_page(True) else : dialog.destroy() top_window = save_top_window return None def set_meta_attributes(self) : meta_attributes = self.widget_group.get_values() (parent_xml_node, add_obj_type, new_mid_elem) = manager.real_add_obj_type(self.xml_node, "meta_attributes", True) if parent_xml_node == None : return nv_xml_nodes = {} for nv_xml_node in parent_xml_node.getElementsByTagName("nvpair") : nv_name = nv_xml_node.getAttribute("name") nv_xml_nodes[nv_name] = nv_xml_node impl = getDOMImplementation() for attr_name in meta_attributes : nv_xml_node = nv_xml_nodes.get(attr_name) if attr_name.count("max") > 0 : value = meta_attributes[attr_name].split(".")[0] else : value = meta_attributes[attr_name] if nv_xml_node != None : #if value != self.default_meta_attributes.get(attr_name) : nv_xml_node.setAttribute("value", value) #else : # nv_xml_node.parentNode.removeChild(nv_xml_node) else : if value != self.default_meta_attributes.get(attr_name) : newdoc = impl.createDocument(None, "nvpair", None) nv = newdoc.documentElement parent_xml_node.appendChild(nv) attr_id = manager.auto_unique_id(nv, attr_name) nv.setAttribute("id", attr_id) nv.setAttribute("name", attr_name) nv.setAttribute("value", value) for option in self.meta_attributes_options[self.obj_type] : if validate_type == "dtd" : attr_name = option[0].replace("-", "_") else : attr_name = option[0] nv_xml_node = nv_xml_nodes.get(attr_name) if nv_xml_node != None and meta_attributes.get(attr_name, "") == "" : nv_xml_node.parentNode.removeChild(nv_xml_node) if len(parent_xml_node.getElementsByTagName("nvpair")) == 0 : parent_xml_node.parentNode.removeChild(parent_xml_node) def get_monitors(self) : monitors = [] for operations_node in self.xml_node.getElementsByTagName("operations") : for op_node in operations_node.getElementsByTagName("op") : op_name = op_node.getAttribute("name") if op_name == "monitor" : monitors.append(op_node) return monitors def get_rsc_meta(self) : primitive_attrs = manager.get_rsc_attrs(self.xml_node, ["class", "type", "provider"]) primitive_class = str(primitive_attrs.get("class", "")) primitive_type = str(primitive_attrs.get("type", "")) primitive_provider = str(primitive_attrs.get("provider", "")) meta = manager.get_rsc_meta(primitive_class, primitive_type, primitive_provider) return meta def set_monitor(self, meta) : if self.obj_type not in ["primitive", "template"] or meta == None : return monitors = self.get_monitors() (parent_xml_node, add_obj_type, new_mid_elem) = manager.real_add_obj_type(self.xml_node, "operations", True) if parent_xml_node == None : return enable_monitor = self.monitor_checkbutton.get_active() if enable_monitor : if len(monitors) == 0 : impl = getDOMImplementation() if validate_type == "dtd" : dtd_elem = manager.get_dtd_elem(add_obj_type) attr_list = dtd_elem.get_attr_list() else : attr_list = [] sorted_rng_nodes = manager.sorted_sub_rng_nodes_by_name(add_obj_type) if sorted_rng_nodes != None : attr_rng_nodes = sorted_rng_nodes.get("attribute", []) for rng_node in attr_rng_nodes : name = rng_node[0][1].getAttribute("name") if attr_list.count(name) == 0 : attr_list.append(name) default_interval = "10" for action in meta.actions : if action.get("name") == "monitor" : newdoc = impl.createDocument(None, add_obj_type, None) op = newdoc.documentElement parent_xml_node.appendChild(op) primitive_id = str(self.xml_node.getAttribute("id")) op_id = primitive_id + "-" + add_obj_type + "-" + action["name"] role = action.get("role", "") if role != "" : op_id += "-" + role interval = action.get("interval", "") if interval == "" : interval = default_interval op_id += "-" + interval unique_id = manager.get_unique_id(op_id, op) op.setAttribute("id", unique_id) for attr_name in attr_list : key = attr_name.replace("_", "-") value = action.get(key, "") if value != "" : op.setAttribute(key, action[key]) else : if key == "interval" : op.setAttribute(key, default_interval) else : return else : for monitor in monitors : monitor.parentNode.removeChild(monitor) ops = [] for operations_node in self.xml_node.getElementsByTagName("operations") : for op_node in operations_node.getElementsByTagName("op") : op_name = op_node.getAttribute("name") ops.append(op_node) if len(ops) == 0 : parent_xml_node.parentNode.removeChild(parent_xml_node) def set_inst_attributes(self, meta) : if self.obj_type != "primitive" or meta == None : return (parent_xml_node, add_obj_type, new_mid_elem) = manager.real_add_obj_type(self.xml_node, "instance_attributes", True) if parent_xml_node == None : return nv_xml_nodes = {} for nv_xml_node in parent_xml_node.getElementsByTagName("nvpair") : nv_name = nv_xml_node.getAttribute("name") nv_xml_nodes[nv_name] = nv_xml_node impl = getDOMImplementation() param_list = [] for param in meta.parameters : attr_name = param.get("name", "") if attr_name == "" : continue param_list.append(attr_name) if nv_xml_nodes.get(attr_name) != None : continue if param.get("required") == "1" : newdoc = impl.createDocument(None, "nvpair", None) nv = newdoc.documentElement parent_xml_node.appendChild(nv) attr_id = manager.auto_unique_id(nv, attr_name) nv.setAttribute("id", attr_id) nv.setAttribute("name", attr_name) for nv_name in nv_xml_nodes : if nv_name not in param_list : nv_xml_nodes[nv_name].parentNode.removeChild(nv_xml_nodes[nv_name]) if len(parent_xml_node.getElementsByTagName("nvpair")) == 0 : parent_xml_node.parentNode.removeChild(parent_xml_node) def first_page_init_run(self) : self.first_page_render() self.first_page_update() if validate_type == "dtd" : target_role_widget = self.widget_group.widgets["combos"].get("target_role") else : target_role_widget = self.widget_group.widgets["combos"].get("target-role") if target_role_widget != None : if self.xml_node.parentNode.tagName == "resources" and manager.active_cib == "" : default_value = "Stopped" else : default_value = "" model = target_role_widget.get_model() iter = model.get_iter_first() while iter != None : if model.get_value(iter,0) == default_value : target_role_widget.set_active_iter(iter) break iter = model.iter_next(iter) if self.obj_type in ["primitive", "template"] : self.monitor_checkbutton.set_active(True) return self.first_page_run() def first_page_update_run(self) : self.first_page_render() self.first_page_update() return self.first_page_run() def last_page(self, add_prompt = False) : global top_window title = _("Add") + " " + _(name_cap(self.obj_type)) dialog = gtk.Dialog(title, top_window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_GO_BACK, gtk.RESPONSE_REJECT, gtk.STOCK_APPLY, gtk.RESPONSE_APPLY)) dialog.set_border_width(5) dialog.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL) dialog.set_default_response(gtk.RESPONSE_APPLY) self.current_page = 1 label_text = title + " - " rsc_id = self.xml_node.getAttribute("id") if rsc_id != "" : label_text += _("Summary Of \"%s\"")%rsc_id else : label_text += _("Summary") label = gtk.Label() label.set_markup('' + label_text + '') label.set_alignment(0, 0) dialog.vbox.pack_start(label, False, padding=2) separator = gtk.HSeparator() dialog.vbox.pack_start(separator, False, padding = 2) elem_notebook = ElementNotebook(self.xml_node, False) elem_notebook.update(self.xml_node) dialog.vbox.pack_start(elem_notebook.widget, True, padding = 5) dialog.vbox.pack_start(elem_notebook.bbox, False, padding = 2) dialog.vbox.show_all() if self.obj_type not in ["primitive", "template"] and add_prompt : if rsc_id != "" : title_suffix = _("Sub-resource For \"%s\"")%rsc_id else : title_suffix = _("Sub-resource") first_title = title + " - " + _("Add ") + title_suffix later_title = title + " - " + _("Continue Adding ") + title_suffix append_title = first_title while True : if elem_notebook.on_add(invoked_by_wizard = True, append_title = append_title) == 0 : break #if self.obj_type in ["clone", "master"] : # break append_title = later_title if self.obj_type == "primitive" : set_page_type = "instance_attributes" elif self.obj_type == "group" : set_page_type = "primitive" else : if len(self.xml_node.getElementsByTagName("group")) > 0 : set_page_type = "group" else : set_page_type = "primitive" elem_notebook.restore_status((set_page_type, None, {})) #elem_notebook.on_after_show() save_top_window = top_window top_window = dialog while True : ret = dialog.run() if ret == gtk.RESPONSE_APPLY : dialog.destroy() top_window = save_top_window return self.xml_node elif ret == gtk.RESPONSE_REJECT : dialog.destroy() top_window = save_top_window return self.first_page_update_run() else : dialog.destroy() top_window = save_top_window return None def run(self) : if self.current_page == None : ret = self.first_page_init_run() elif self.current_page == 0 : ret = self.first_page_update_run() else : ret = self.last_page() return ret def destroy(self) : #global top_window #self.dialog.destroy() #top_window = self.save_top_window pass class ObjectViewDlg : def __init__(self, xml_node, is_newobj = False) : self.xml_node = xml_node global top_window if is_newobj : title_prefix = _("Add") else : title_prefix = _("Edit") title = title_prefix + " " + _(name_cap(xml_node.tagName)) dialog = gtk.Dialog(title, top_window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, str(_("Reset")), gtk.RESPONSE_APPLY, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_border_width(5) dialog.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL) dialog.set_default_response(gtk.RESPONSE_OK) self.dialog = dialog obj_view = ObjectView(self.xml_node, is_newobj, self.on_changed) self.obj_view = obj_view dialog.vbox.pack_start(obj_view.widget) dialog.vbox.show() dialog.set_response_sensitive(gtk.RESPONSE_APPLY, False) self.save_top_window = top_window top_window = dialog def run(self) : while True : ret = self.dialog.run() if ret in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT] : self.obj_view.reset() self.destroy() return None elif ret == gtk.RESPONSE_APPLY : self.on_reset() else : passed = self.obj_view.validate() if passed : return self.obj_view.xml_node def destroy(self) : global top_window self.dialog.destroy() top_window = self.save_top_window def on_changed(self) : self.dialog.set_response_sensitive(gtk.RESPONSE_APPLY, True) def on_reset(self) : ret = confirmbox(_("This will reset the current object attributes and all sub-objects to the initial configurations."), (gtk.STOCK_NO, gtk.RESPONSE_NO, gtk.STOCK_YES, gtk.RESPONSE_YES), _("Reset the configurations?")) if ret == gtk.RESPONSE_YES : self.obj_view.reset() self.obj_view.update() self.dialog.set_response_sensitive(gtk.RESPONSE_APPLY, False) class TransitionInfoDlg : def __init__(self) : global top_window self.G = None dialog = gtk.Dialog(_("Transition Information"), top_window, gtk.DIALOG_MODAL, (gtk.STOCK_HELP, gtk.RESPONSE_HELP, gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE, gtk.STOCK_SAVE, gtk.RESPONSE_APPLY)) dialog.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL) dialog.set_default_size(750, 550) hbox = gtk.HBox() label = gtk.Label(_("Transition") + _(":")) label.set_alignment(0, 0.5) hbox.pack_start(label, False, padding=2) self.live_radio_btn = gtk.RadioButton(None, _("Live")) self.live_radio_btn.set_active(True) hbox.pack_start(self.live_radio_btn, False, padding=2) history_radio_btn = gtk.RadioButton(self.live_radio_btn, _("History") + _(":")) hbox.pack_start(history_radio_btn, False, padding=2) self.search_btn = gtk.Button(stock=gtk.STOCK_FIND) self.search_btn.set_sensitive(False) hbox.pack_start(self.search_btn, False, padding=2) store = gtk.ListStore(str, str) self.combo_entry = gtk.ComboBoxEntry(store) cell = gtk.CellRendererText() self.combo_entry.pack_start(cell, True) self.combo_entry.set_sensitive(False) self.combo_entry.add_attribute(cell, 'text', 1) hbox.pack_start(self.combo_entry, True, padding=2) self.refresh_btn = gtk.Button(stock=gtk.STOCK_REFRESH) hbox.pack_start(self.refresh_btn, False, padding=2) dialog.vbox.pack_start(hbox, False, padding=2) self.summary_label = gtk.Label() self.summary_label.set_alignment(0, 0.5) dialog.vbox.pack_start(self.summary_label, False, padding=5) notebook = gtk.Notebook() dialog.vbox.pack_start(notebook, True) self.notebook = notebook vbox = gtk.VBox() tab_label = gtk.Label(_("Graph")) notebook.append_page(vbox, tab_label) sw = gtk.ScrolledWindow() sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) vbox.pack_start(sw, True) self.image = gtk.Image() sw.add_with_viewport(self.image) vbox = gtk.VBox() tab_label = gtk.Label(_("Detail")) notebook.append_page(vbox, tab_label) hbox = gtk.HBox() label = gtk.Label(_("Verbosity") + _(":")) hbox.pack_start(label, False, padding=2) default_verbosity = 0 adj = gtk.Adjustment(default_verbosity, 0, 99, 1, 5) self.detail_spin_btn = gtk.SpinButton(adj, 0, 0) self.detail_spin_btn.set_width_chars(2) self.detail_spin_btn.set_wrap(True) hbox.pack_start(self.detail_spin_btn, False, padding=2) self.detail_refresh_btn = gtk.Button(stock=gtk.STOCK_REFRESH) hbox.pack_start(self.detail_refresh_btn, False, padding=2) vbox.pack_start(hbox, False, padding=2) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_IN) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) vbox.pack_start(sw, True) self.pe_detail_text = gtk.TextView() #self.pe_detail_text.set_wrap_mode(gtk.WRAP_WORD) self.pe_detail_text.set_property("editable", False) self.pe_detail_textbuffer = self.pe_detail_text.get_buffer() sw.add(self.pe_detail_text) vbox = gtk.VBox() tab_label = gtk.Label(_("Scores")) notebook.append_page(vbox, tab_label) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_IN) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) vbox.pack_start(sw, True) self.pe_scores_text = gtk.TextView() #self.pe_scores_text.set_wrap_mode(gtk.WRAP_WORD) self.pe_scores_text.set_property("editable", False) self.pe_scores_textbuffer = self.pe_scores_text.get_buffer() sw.add(self.pe_scores_text) self.live_radio_btn.connect("activate", self.on_refresh) history_radio_btn.connect("toggled", self.on_radio_changed) history_radio_btn.connect("activate", self.on_refresh) self.search_btn.connect("clicked", self.on_search) self.combo_entry.connect("changed", self.on_value_changed) self.combo_entry.child.connect("activate", self.on_refresh) self.refresh_btn.connect("clicked", self.on_refresh) self.detail_spin_btn.connect("value-changed", self.on_detail_value_changed) self.detail_refresh_btn.connect("clicked", self.on_detail_refresh) self.on_refresh() dialog.show_all() if not support_gv : notebook.get_nth_page(0).hide_all() save_top_window = top_window top_window = dialog while True : ret = dialog.run() if ret == gtk.RESPONSE_APPLY : self.save_transition_info() elif ret == gtk.RESPONSE_HELP : self.show_help() else : break if support_gv and self.G != None : gv.rm(self.G) dialog.destroy() top_window = save_top_window def on_radio_changed(self, radio_btn) : radio_active = radio_btn.get_active() self.search_btn.set_sensitive(radio_active) self.combo_entry.set_sensitive(radio_active) self.refresh_btn.set_sensitive(True) def on_value_changed(self, combo_entry) : self.refresh_btn.set_sensitive(True) def on_search(self, search_btn) : rpdlg = TimeFrameDlg() pe_params = rpdlg.set_params(_("Transitions"), (True, True, True, False)) if pe_params == None : return if pe_params.get("ftime") != None : pe_params["ftime"] = int(time.mktime(pe_params["ftime"])) if pe_params.get("ttime") != None : pe_params["ttime"] = int(time.mktime(pe_params["ttime"])) input_info_list = self.get_pe_inputs(pe_params.get("ftime", ""), pe_params.get("ttime", "")) if input_info_list == None : return show_len = 30 late_len = 27 early_len = show_len - late_len store = gtk.ListStore(str, str) if len(input_info_list) > show_len : for input_info in input_info_list[:late_len] : store.append(input_info) omit_len = len(input_info_list) - show_len store.append(["", _("[Omitted %d transitions...]")%omit_len]) for input_info in input_info_list[-early_len:] : store.append(input_info) else : for input_info in input_info_list : store.append(input_info) self.combo_entry.set_model(store) def get_pe_inputs(self, ftime, ttime) : cmd = "get_pe_inputs\n%s\n%s"%(ftime, ttime) input_info = window.do_cmd_with_pbar(cmd, _("Transitions"), _("Searching the transitions may take a while,") + "\n" + _("depending on the number of transitions..."), _("Cannot find any transition record")) if input_info == None : return None input_dict = {} for i in range(len(input_info)) : input_list = input_info[i].split() j = 0 while j < len(input_list) : time_stamp = float(input_list[j+1]) if not input_dict.has_key(time_stamp) : input_dict[time_stamp] = [] input_dict[time_stamp].append(input_list[j]) j += 2 input_time_list = input_dict.keys() input_time_list.sort(reverse = True) input_info_list = [] for i in range(len(input_time_list)) : input_time = input_time_list[i] input_files = input_dict[input_time] input_files.sort() for input_file in input_files : input_id = os.path.splitext(input_file)[0] info_text = time.ctime(input_time) input_info_list.append([input_id, info_text]) return input_info_list def on_detail_value_changed(self, spin_btn) : self.detail_refresh_btn.set_sensitive(True) def on_refresh(self, btn=None) : pe_input = self.get_pe_input_id() if pe_input == None : return pe_summary = manager.do_cmd("get_pe_summary\n%s\n%s"%(pe_input[0], pe_input[1])) if pe_summary == None or len(pe_summary) < 1 : msgbox(_("The specified transition doesn't exist")) return if pe_input[0] == "live" : label_text = "Live" else : label_text = "-".join(pe_input) time_str = time.ctime(float(pe_summary[0])) label_text += " (" + time_str + ")" self.summary_label.set_markup('' + label_text + '') self.show_pe_graph(pe_input) self.show_pe_detail(pe_input) self.show_pe_scores(pe_input) self.refresh_btn.set_sensitive(False) self.detail_refresh_btn.set_sensitive(False) def on_detail_refresh(self, btn=None) : pe_input = self.get_pe_input_id_label() if pe_input == None : return self.show_pe_detail(pe_input) self.detail_refresh_btn.set_sensitive(False) def get_pe_input_id(self) : if self.live_radio_btn.get_active() : pe_input = ("live", "") else : pe_series = ["error", "warn", "input"] error_str = _("Please specify a proper identity of a transition") + _(".") + "\n" \ + _("Such as") + _(":") \ + "\"pe-error-100\", \"warn-36\", \"input 62\", \"pe-error-45.bz2\"..." + "\n" \ + _("Transition type: \"error\", \"warn\" or \"input\"") pe_str = self.combo_entry.child.get_text() if len(pe_str) == 0 : msgbox(error_str) return None pe_str_lower = pe_str.lower() for pe_type in pe_series : if pe_str_lower.count(pe_type) : break else : msgbox(error_str) return None pe_num = extract_int(pe_str) if pe_num == None : msgbox(error_str) return None pe_input = ("pe-" + pe_type, pe_num) return pe_input def get_pe_input_id_label(self) : summary_text = self.summary_label.get_text() pe_input_id = summary_text.split("(")[0].rstrip() if pe_input_id == "Live" : pe_input = ("live", "") elif pe_input_id.startswith("pe-") : id_split = pe_input_id.split("-") if len(id_split) == 3 : pe_input = (id_split[0] + "-" + id_split[1], id_split[2]) else : pe_input = None else : pe_input = None return pe_input def show_pe_graph(self, pe_input) : if not support_gv : return if self.G != None : gv.rm(self.G) self.G = None self.image.clear() graph_str = self.gen_pe_graph(pe_input) if graph_str != None : G = gv.readstring(graph_str) gv.layout(G, "dot") try : (fd, tmp_png) = tempfile.mkstemp(suffix=".png") except IOError, msg : msgbox(_("I/O error") + _(": ") + str(msg)) return os.close(fd) gv.render(G, "png", tmp_png) self.G = G self.image.set_from_file(tmp_png) os.unlink(tmp_png) self.graph_str = graph_str def gen_pe_graph(self, pe_input) : cmd = "gen_pe_graph\n%s\n%s"%(pe_input[0], pe_input[1]) graph_lines = window.do_cmd_with_pbar(cmd, _("Transition Graph"), _("Generating the transition graph may take a while..."), _("Failed to generate the transition graph")) if graph_lines == None : return None graph_str = "\n".join(graph_lines) return graph_str def show_pe_detail(self, pe_input) : verbosity = int(self.detail_spin_btn.get_value()) self.pe_detail_textbuffer.set_text("") cmd = "gen_pe_info\n%s\n%s\n%s"%(pe_input[0], pe_input[1], verbosity) detail_lines = window.do_cmd_with_pbar(cmd, _("Transition Detail"), _("Generating the transition detail may take a while..."), _("Failed to generate the transition detail")) if detail_lines == None : return detail_str = "\n".join(detail_lines) self.pe_detail_textbuffer.set_text(detail_str) def show_pe_scores(self, pe_input) : self.pe_scores_textbuffer.set_text("") cmd = "gen_pe_info\n%s\n%s\nscores"%(pe_input[0], pe_input[1]) scores_lines = window.do_cmd_with_pbar(cmd, _("Transition Scores"), _("Generating the transition scores may take a while..."), _("Failed to generate the transition scores")) if scores_lines == None : return scores_str = "\n".join(scores_lines) self.pe_scores_textbuffer.set_text(scores_str) def save_transition_info(self) : page_num = self.notebook.get_current_page() if page_num == 0 : if not support_gv : msgbox(_("Cannot save the graph for specified transition")) return default_name = "pe-graph.png" filter_list = ((_("PNG Image"), ("*.png",)), (_("JPEG Image"), ("*.jpg", "*.jpeg", "*.jpe")), (_("GIF Image"), ("*.gif",)), (_("TIFF Image"), ("*.tiff", "*.tif")), (_("Dot File"), ("*.dot",)), ) elif page_num == 1 : default_name = "pe-detail" filter_list = None else: default_name = "pe-scores" filter_list = None sfdlg = SelectFileDlg() (save_file, save_type) = sfdlg.select_file(default_name, filter_list) if save_file == None : return save_str = None if page_num == 0 : for (filter_name, filter_pattern) in filter_list : if filter_name == save_type : format = filter_pattern[0][2:] if format != "dot" : gv.render(self.G, format, save_file) return else : save_str = self.graph_str break elif page_num == 1 : save_str = self.pe_detail_textbuffer.get_text(*self.pe_detail_textbuffer.get_bounds()) else : save_str = self.pe_scores_textbuffer.get_text(*self.pe_scores_textbuffer.get_bounds()) if save_str == None : msgbox(_("Cannot save the information for specified transition")) return try : fd = os.open(save_file, os.O_RDWR|os.O_CREAT|os.O_TRUNC, 0644) except OSError, msg : msgbox(_("System error") + _(": ") + str(msg)) return try : os.write(fd, save_str) except OSError, msg : msgbox(_("System error") + _(": ") + str(msg)) os.close(fd) return os.close(fd) def show_help(self) : global top_window help_str = _("""Interpreting the graph: * Arrows indicate ordering dependancies * Dashed-arrows indicate dependancies that are not present in the transition graph * Actions with a dashed border of any color do not form part of the transition graph * Actions with a green border form part of the transition graph * Actions with a red border are ones the cluster would like to execute but are unrunnable * Actions with a blue border are ones the cluster does not feel need to be executed * Actions with orange text are pseudo/pretend actions that the cluster uses to simplify the graph * Actions with black text are sent to the LRM * Resource actions have text of the form {rsc}_{action}_{interval} {node} * Any action depending on an action with a red border will not be able to execute. * Loops are really bad. Please report them to the development team.""") dialog = gtk.Dialog("Help", top_window, gtk.DIALOG_MODAL, (gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)) dialog.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL) dialog.set_size_request(590, 270) dialog.set_default_response(gtk.RESPONSE_CLOSE) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_IN) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) dialog.vbox.pack_start(sw, True) help_text = gtk.TextView() #help_text.set_wrap_mode(gtk.WRAP_WORD) help_text.set_property("editable", False) help_textbuffer = help_text.get_buffer() help_textbuffer.set_text(help_str) sw.add(help_text) dialog.show_all() save_top_window = top_window top_window = dialog dialog.run() dialog.destroy() top_window = save_top_window class TimeFrameDlg : def set_params(self, title, (from_chkbtn, from_sensitive, to_chkbtn, to_sensitive)) : global top_window dialog = gtk.Dialog(title, top_window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_border_width(5) dialog.set_default_response(gtk.RESPONSE_OK) self.dialog = dialog current_time = time.time() from_time = time.localtime(current_time - 1800) to_time = time.localtime(current_time) fdatetime = self.render_time_widgets(""+_("From")+"", from_time, from_chkbtn, from_sensitive) tdatetime = self.render_time_widgets(""+_("To")+"", to_time, to_chkbtn, to_sensitive) save_top_window = top_window top_window = dialog dialog.show_all() while True : ret = dialog.run() if ret in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT] : top_window = save_top_window dialog.destroy() return None else : if fdatetime.time_hbox.get_property("sensitive") : ftime = fdatetime.get_time() else : ftime = None if tdatetime.time_hbox.get_property("sensitive") : ttime = tdatetime.get_time() else : ttime = None passed = True if ftime != None and ttime != None and time.mktime(ftime) > time.mktime(ttime) : msgbox(_("The \"From\" time should before the \"To\" one")) passed = False if passed : params = {} if ftime != None : params["ftime"] = ftime if ttime != None : params["ttime"] = ttime top_window = save_top_window dialog.destroy() return params def render_time_widgets(self, label, default_time, chkbtn, sensitive) : time_label = gtk.Label() time_label.set_markup(_(label)) time_label.set_alignment(0, 0.5) datetime = DateTime(default_time) if chkbtn : time_checkbutton = gtk.CheckButton() time_checkbutton.add(time_label) if sensitive : time_checkbutton.set_active(True) time_checkbutton.connect("toggled", self.on_checkbutton_toggled, datetime.time_hbox) self.dialog.vbox.pack_start(time_checkbutton, False, padding=2) else : self.dialog.vbox.pack_start(time_label, False, padding=2) datetime.time_hbox.set_sensitive(sensitive) self.dialog.vbox.pack_start(datetime.time_hbox, False, padding=2) return datetime def on_checkbutton_toggled(self, widget, hbox) : hbox.set_sensitive(widget.get_active()) class SelectFileDlg : def select_file(self, orig_filename = None, filter_list = None) : global top_window file_dialog = gtk.FileChooserDialog(_("Save as ..."), None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) if orig_filename != None : file_dialog.set_current_name(orig_filename) save_top_window = top_window top_window = file_dialog if filter_list != None : for (filter_name, filter_patterns) in filter_list : filter = gtk.FileFilter() filter.set_name(filter_name) for filter_pattern in filter_patterns : filter.add_pattern(filter_pattern) file_dialog.add_filter(filter) while True : ret = file_dialog.run() if ret in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT] : top_window = save_top_window file_dialog.destroy() return (None, None) else : save_folder = file_dialog.get_current_folder() save_file = file_dialog.get_filename() passed = True try : if not os.access(save_folder, os.R_OK | os.W_OK | os.X_OK) : msgbox(_("Permission denied") + (": ") + save_folder) passed = False continue if os.access(save_file, os.F_OK) : retval = confirmbox(_("A file with the same name already exists") +_(": ") + os.path.basename(save_file) + "\n" +_("Do you want to overwrite it?"), (gtk.STOCK_NO, gtk.RESPONSE_NO, gtk.STOCK_YES, gtk.RESPONSE_YES), _("Replace it?")) if retval in [gtk.RESPONSE_NO, gtk.RESPONSE_DELETE_EVENT] : passed = False continue except OSError, msg : msgbox(_("System error") + _(": ") + str(msg)) passed = False if passed : top_window = save_top_window if filter_list != None : save_type = file_dialog.get_filter().get_name() else : save_type = None file_dialog.destroy() return (save_file, save_type) class DateTime: def __init__(self, default_time) : time_hbox = gtk.HBox() time_date = gtk.Entry() time_date.set_width_chars(10) time_date.set_editable(False) time_date.set_activates_default(True) time_hbox.pack_start(time_date, False) time_cal_window = gtk.Window(gtk.WINDOW_POPUP) time_cal = gtk.Calendar() time_cal_window.add(time_cal) time_cal_button = gtk.ToggleButton() arrow = gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_OUT) time_cal_button.add(arrow) time_cal_button.connect("toggled", self.on_toggled, time_cal_window) time_hbox.pack_start(time_cal_button, False) time_cal_window.connect("button-press-event", self.on_button_press, time_cal_button) time_cal_window.connect("key-press-event", self.on_key_press, time_cal_button) time_cal.connect("day-selected", self.on_day_selected, time_date) time_cal.select_month(default_time[1]-1, default_time[0]) time_cal.select_day(default_time[2]) space = gtk.Label(" ") time_hbox.pack_start(space, False) time_hr_adj = gtk.Adjustment(default_time[3], 00, 23, 1, 4) time_hr = gtk.SpinButton(time_hr_adj, 0, 0) time_hr.set_width_chars(2) time_hr.set_wrap(True) time_hbox.pack_start(time_hr, False) time_colon = gtk.Label(":") time_hbox.pack_start(time_colon, False) time_min_adj = gtk.Adjustment(default_time[4], 00, 59, 1, 5) time_min = gtk.SpinButton(time_min_adj, 0, 0) time_min.set_width_chars(2) time_min.set_wrap(True) time_hbox.pack_start(time_min, False) time_colon = gtk.Label(":") time_hbox.pack_start(time_colon, False) time_sec_adj = gtk.Adjustment(default_time[5], 00, 59, 1, 5) time_sec = gtk.SpinButton(time_sec_adj, 0, 0) time_sec.set_width_chars(2) time_sec.set_wrap(True) time_hbox.pack_start(time_sec, False) time_widgets = {} self.time_date = time_date self.time_hr = time_hr self.time_min = time_min self.time_sec = time_sec self.time_hbox = time_hbox def on_toggled(self, widget, cal_window) : if widget.get_active() : self.cal_popup(widget, cal_window) else : self.cal_hide(widget, cal_window) def cal_popup(self, widget, cal_window) : (x, y) = widget.get_parent_window().get_position() x += widget.allocation.x y += widget.allocation.y + widget.allocation.height cal_window.grab_add() cal_window.move(x, y) cal_window.grab_focus() cal_window.show_all() if gtk.gdk.pointer_grab(cal_window.window, True, gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.POINTER_MOTION_MASK, None, None, 0L) == gtk.gdk.GRAB_SUCCESS : if (gtk.gdk.keyboard_grab (cal_window.window, True, 0L) != 0): gtk.gdk.pointer_ungrab(0L) def cal_hide(self, widget, cal_window) : cal_window.hide() cal_window.grab_remove() gtk.gdk.pointer_ungrab(0L) gtk.gdk.keyboard_ungrab(0L) def on_button_press(self, cal_window, event, button) : button.set_active(False) def on_key_press(self, cal_window, event, button) : if event.keyval == gtk.keysyms.Escape : button.set_active(False) else : gtk.gdk.keyboard_grab (cal_window.window, True, 0L) def on_day_selected(self, cal_window, date_entry) : (year, month, day) = cal_window.get_date() mytime = time.mktime((year, month+1, day, 0, 0, 0, 0, 0, -1)) localtime = time.strftime("%Y-%m-%d", time.localtime(mytime)) date_entry.set_text(localtime) #date_entry.set_text("%d-%02d-%02d"%(year, month+1, day)) def get_time(self) : datetime = time.strptime("%s %02d:%02d:%02d"%(self.time_date.get_text(), self.time_hr.get_value(), self.time_min.get_value(), self.time_sec.get_value()), "%Y-%m-%d %H:%M:%S") return datetime class ProgressPulse : def __init__(self, title, msg, pulse_msg, button=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL), destroy_condition = None) : global top_window self.destroy_condition = destroy_condition dialog = gtk.Dialog(title, top_window, gtk.DIALOG_MODAL, button) dialog.set_border_width(5) if msg != None : label = gtk.Label(msg) dialog.vbox.pack_start(label, False, padding=2) self.pbar = gtk.ProgressBar() if pulse_msg != None : self.pbar.set_text(pulse_msg) self.timer = gobject.timeout_add(100, self.pulse) dialog.vbox.pack_start(self.pbar, False, padding=2) dialog.show_all() self.save_top_window = top_window self.dialog = dialog def pulse(self) : if self.destroy_condition != None and self.destroy_condition() : self.destroy() return False else : self.pbar.pulse() return True def destroy(self) : global top_window top_window = self.save_top_window self.dialog.destroy() gobject.source_remove(self.timer) def run(self) : ret = self.dialog.run() self.destroy() return ret class DesReportDlg: def __init__(self, des_file_lines) : global top_window self.des_file_lines = des_file_lines dialog = gtk.Dialog(_("Description of Cluster Report"), top_window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL) dialog.set_border_width(5) entries = {} combo_entries = {} name_labels = [] for line in des_file_lines : if line.startswith("Severity: [choose one] ") : options = line.replace("Severity: [choose one] ", "").split() hbox = gtk.HBox() label = gtk.Label(_("Severity") + _(":")) label.set_alignment(0, 0.5) hbox.pack_start(label, False) name_labels.append(label) combo_entry = gtk.combo_box_entry_new_text() combo_entry.append_text("") for option in options : combo_entry.append_text(option) hbox.pack_start(combo_entry) dialog.vbox.pack_start(hbox, False, padding=1) combo_entries["severity"] = combo_entry elif line.startswith("Component: [choose one] ") : options = line.replace("Component: [choose one] ", "").split() hbox = gtk.HBox() label = gtk.Label(_("Component") + _(":")) label.set_alignment(0, 0.5) hbox.pack_start(label, False) name_labels.append(label) combo_entry = gtk.combo_box_entry_new_text() combo_entry.append_text("") for option in options : combo_entry.append_text(option) hbox.pack_start(combo_entry) dialog.vbox.pack_start(hbox, False, padding=1) combo_entries["component"] = combo_entry elif line.startswith("Subject:") : hbox = gtk.HBox() label = gtk.Label(_("Subject") + _(":")) label.set_alignment(0, 0.5) name_labels.append(label) hbox.pack_start(label, False) entry = gtk.Entry() hbox.pack_start(entry) dialog.vbox.pack_start(hbox, False, padding=1) entries["subject"] = entry elif line.startswith("Detailed description:") : label = gtk.Label(_("Detailed description") + _(":")) label.set_alignment(0, 0.5) dialog.vbox.pack_start(label, False, padding=1) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_IN) sw.set_border_width(5) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) des_text = gtk.TextView() des_text.set_wrap_mode(gtk.WRAP_WORD) self.des_textbuffer = des_text.get_buffer() sw.add(des_text) dialog.vbox.pack_start(sw, padding=1) elif not line.startswith("[...]") and not line.startswith("---") : label = gtk.Label(line.replace("\n", "")) label.set_alignment(0, 0.5) label.set_selectable(True) dialog.vbox.pack_start(label, False, padding=1) name_label_max_len = 0 for name_label in name_labels : name_label_len = name_label.size_request()[0] if name_label_len > name_label_max_len : name_label_max_len = name_label_len for name_label in name_labels : name_label.set_size_request(name_label_max_len, -1) widgets = {} widgets["entries"] = entries widgets["combo_entries"] = combo_entries self.widget_group = WidgetGroup(widgets) dialog.show_all() self.dialog = dialog self.save_top_window = top_window def run(self) : global top_window des_file_lines = self.des_file_lines ret = self.dialog.run() if ret in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT] : top_window = self.save_top_window self.dialog.destroy() return None else : fields = self.widget_group.get_values() detailed_des = self.des_textbuffer.get_text(*self.des_textbuffer.get_bounds()) new_file_lines = [] for i in range(len(des_file_lines)) : if des_file_lines[i].startswith("Severity: [choose one] ") : des_file_lines[i] = "Severity: %s\n"%fields.get("severity", "") elif des_file_lines[i].startswith("Component: [choose one] ") : des_file_lines[i] = "Component: %s\n"%fields.get("component", "") elif des_file_lines[i].startswith("Subject:") : des_file_lines[i] = "Subject: %s\n"%fields.get("subject", "") elif des_file_lines[i-2].startswith("Detailed description:") : des_file_lines[i] = detailed_des + "\n" top_window = self.save_top_window self.dialog.destroy() return des_file_lines class MainWindow : ''' Main UI window to show information to user and get users input ''' win_widget = None actiongroup = None uimanager = None cur_type = None cur_status = None cur_name = None cur_view = None statusbar = None view_status = {} # utility functions def set_action_sensitive(self, action, sensitive) : if self.actiongroup.get_action(action) != None : self.actiongroup.get_action(action).set_property("sensitive", sensitive) elif self.radio_tool_action_group.get_action(action) != None : self.radio_tool_action_group.get_action(action).set_property("sensitive", sensitive) # system event handler def on_delete_event(self, widget, event, data=None) : self.do_quit(None) return False def update_ui(self) : self.set_action_sensitive('logout',manager.connected) self.set_action_sensitive('login',not manager.connected) self.set_action_sensitive('transition-info', manager.connected) self.set_action_sensitive('report', manager.connected) for action in ["new", "reset", "delete", "commit", "switch"] : self.set_action_sensitive(action, manager.connected) self.set_action_sensitive("diff", manager.connected and manager.active_cib != None and manager.active_cib != "") # functions def update(self) : self.maintree.update() self.statusbar.pop(2) window.statusbar.pop(1) if manager.connected : status_str = _("Connected to ") + manager.username + "@" + manager.server else : status_str = _("Not connected") if mode_level == 0 : status_str += " " + _("(") + _("Simple Mode") +_(")") elif mode_level == 1 : status_str += " " + _("(") + _("Expert Mode") +_(")") else : status_str += " " + _("(") + _("Hack Mode") +_(")") window.statusbar.push(1, status_str) self.update_ui() return False def can_change_view(self) : if not self.cur_view.changed : return True ret = confirmbox(_("The data of current view have been changed.")+"\n"+_("Apply the changes?"), (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_NO, gtk.RESPONSE_NO, gtk.STOCK_YES, gtk.RESPONSE_YES)) if ret == gtk.RESPONSE_YES : self.cur_view.on_apply(self.cur_view.widget) return True if ret == gtk.RESPONSE_NO : return True return False def select_view(self, type, name = None, status = None) : for child in self.mainview_sw.get_children() : self.mainview_sw.remove(child) if self.view_status.get(type) != None : last_show_mode = self.view_status[type][0] else : last_show_mode = 0 self.cur_type, self.cur_name, self.cur_status = type, name, status self.update_ui() if type == "configuration" : self.cur_view = ClusterView() elif type == "crm_config" and mode_level == 0 : self.cur_type = "crm_config_simple" self.cur_view = CRMConfigView() if not self.cur_view.update() : return elif type in ["crm_config", "nodes", "resources", "constraints", "status", "rsc_defaults", "op_defaults", "acls", "fencing-topology"] \ and manager.xml_nodes["cib"].getElementsByTagName(type) != [] : self.cur_view = ObjectView(manager.xml_nodes["cib"].getElementsByTagName(type)[0], is_topview = True, show_mode = last_show_mode) elif type in ["rsc_defaults", "op_defaults", "acls", "fencing-topology"] \ and manager.xml_nodes["cib"].getElementsByTagName(type) == [] : self.cur_view = ObjectView(type, is_topview = True, missing_opt_obj_parent_type = "configuration", show_mode = last_show_mode) elif type == "management" : self.cur_view = ManageView() else : self.cur_view = None return self.mainview_sw.add_with_viewport(self.cur_view.widget) #self.cur_view.on_after_show() if self.view_status.get(self.cur_type) != None : self.cur_view.restore_status(self.view_status[self.cur_type]) def do_cmd_with_pbar(self, cmd, title, msg, failed_msg, show_msgbox = True) : manager.async_do_cmd(cmd) pbar = ProgressPulse(title, msg, None, None, lambda : manager.async_ret_list.has_key(cmd)) ret = pbar.run() if ret in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT] : return None manager.async_ret_lock.acquire() if manager.async_ret_list.has_key(cmd) : ret_list = manager.async_ret_list.pop(cmd) else : ret_list = None manager.async_ret_lock.release() if manager.failed_reason != "" : if show_msgbox : msgbox(manager.failed_reason) return None elif len(ret_list) < 1 : if show_msgbox : msgbox(failed_msg + _(": ") + _("Empty information returned")) return None elif ret_list == None : if show_msgbox : msgbox(failed_msg + _(": ") + _("Nothing returned")) return None return ret_list # ui event handler def on_quit(self, action) : if confirmbox(_("Do you want to quit ?")) == gtk.RESPONSE_YES : self.do_quit(action) def do_quit(self, action) : manager.save_profile() if manager.connected : self.confirm_record_pending() gtk.main_quit() def on_login(self, action) : dialog = gtk.Dialog(_("Login"),self.win_widget, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_default_response(gtk.RESPONSE_OK) dialog.set_border_width(5) server = manager.profile["server"] user = manager.profile["user"] widgets = {} name_labels = [] name_label_max_len = 0 for key in ["server(:port)", "user_name", "password"] : hbox = gtk.HBox() name_label = gtk.Label(_(name_cap(key))+_(":")) name_label.set_alignment(0, 0.5) hbox.pack_start(name_label, False, padding=5) name_labels.append(name_label) name_label_len = name_label.size_request()[0] if name_label_len > name_label_max_len : name_label_max_len = name_label_len if key == "server(:port)" : widget = gtk.combo_box_entry_new_text() widget.append_text(server) widget.child.set_text(server) widget.child.set_activates_default(True) elif key == "user_name" : widget = gtk.combo_box_entry_new_text() widget.append_text(user) widget.child.set_text(user) widget.child.set_activates_default(True) if key == "password" : widget = gtk.Entry() widget.set_visibility(False) widget.set_activates_default(True) widgets[key] = widget hbox.pack_start(widget, True, padding=2) dialog.vbox.pack_start(hbox, False, padding=2) for name_label in name_labels : name_label.set_size_request(name_label_max_len, -1) dialog.set_focus(widgets["password"]) dialog.show_all() ret = dialog.run() server = widgets["server(:port)"].child.get_text() user = widgets["user_name"].child.get_text() password = widgets["password"].get_text() dialog.destroy() if ret == gtk.RESPONSE_OK: if not manager.login(server, user, password): msgbox(manager.failed_reason) return else: manager.profile["server"] = server manager.profile["user"] = user manager.save_profile() self.update_ui() def on_logout(self, action) : if confirmbox(_("Do you want to logout ?")) == gtk.RESPONSE_YES : self.confirm_record_pending() manager.logout() self.update_ui() def confirm_record_pending(self) : if manager.xml_nodes.has_key("cib") and manager.find_attribute("op_defaults", "record-pending") == "true" : retval = confirmbox((_("\"Indicate pending operations\" has been activated.") + "\n" + _("It could affect the performance.") + "\n" + _("Turn it off ?"))) if retval == gtk.RESPONSE_YES : manager.set_crm_attribute("op_defaults", "record-pending", "false") def on_shadow_action(self, action) : global top_window shadows = manager.do_cmd("get_shadows") if shadows == None or len(shadows) == 0 : msgbox(_("Cannot get any shadow CIB")) return shadow_list = [shadow[len("shadow."):] for shadow in shadows] shadow_list.sort() action_name = action.get_name() default_shadow = None if manager.active_cib != "" : #if action_name == "delete" : # if manager.active_cib in shadow_list : # shadow_list.remove(manager.active_cib) # if len(shadow_list) == 0 : # msgbox(_("The only one shadow CIB \"%s\" is currently active.")%manager.active_cib) # return #else : default_shadow = manager.active_cib title_str = _(name_cap(action_name)) + " " + _("Shadow CIB") if action_name == "reset" : action_des = _(name_cap(action_name)) + " - " + _("Recreate the specified shadow CIB from the live CIB") elif action_name == "delete" : action_des = _("Delete the specified shadow CIB") elif action_name == "commit" : action_des = _(name_cap(action_name)) + " - " + _("Upload the specified shadow CIB to the cluster") shadow_action = kvbox(title_str, action_des, [Field("shadow_name", _("Shadow Name"), default_shadow, shadow_list, False, entry_editable = False)]) if shadow_action == None : return shadow_name = shadow_action.get("shadow_name", "") if shadow_name == manager.active_cib and action_name == "delete" : reinit_name = "" else : reinit_name = manager.active_cib if shadow_name == manager.active_cib : manager.do_cmd("shutdown_cib") cmd_ret = manager.do_cmd("crm_shadow\n%s\n%s\ntrue" %(action_name, shadow_name)) if cmd_ret == None : if manager.failed_reason.count("Please remember to unset the CIB_shadow variable") == 0 : if manager.failed_reason != "" : msgbox(manager.failed_reason) #else : elif action_name == "commit" and manager.active_cib != "" : retval = confirmbox(_("The shadow CIB \"%s\"has been successfully commited.")%shadow_name + "\n" +_("Switch to the live CIB?"), (gtk.STOCK_NO, gtk.RESPONSE_NO, gtk.STOCK_YES, gtk.RESPONSE_YES), _("Switch to the live CIB?")) if retval == gtk.RESPONSE_YES : reinit_name = "" if shadow_name == manager.active_cib : manager.do_cmd("init_cib\n%s"%(reinit_name)) if manager.failed_reason != "" : msgbox(manager.failed_reason) else : manager.set_update() elif manager.active_cib != reinit_name : manager.do_cmd("switch_cib\n%s"%(reinit_name)) if manager.failed_reason != "" : msgbox(manager.failed_reason) else : manager.set_update() def on_shadow_diff(self, action) : global top_window dialog = gtk.Dialog(_("Shadow CIB Diff"), top_window, gtk.DIALOG_MODAL, (gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE, gtk.STOCK_SAVE, gtk.RESPONSE_APPLY)) dialog.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL) dialog.set_default_size(750, 550) dialog.set_default_response(gtk.RESPONSE_CLOSE) label = gtk.Label() label.set_markup('' + _("Differences between the live CIB and the shadow CIB \"%s\"")%manager.active_cib + _(": ") + '') label.set_alignment(0, 0) dialog.vbox.pack_start(label, False, padding = 5) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_IN) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) dialog.vbox.pack_start(sw, True) shadow_diff_text = gtk.TextView() shadow_diff_text.set_property("editable", False) shadow_diff_textbuffer = shadow_diff_text.get_buffer() sw.add(shadow_diff_text) reinit_name = manager.active_cib manager.do_cmd("shutdown_cib") cmd = "crm_shadow\ndiff\n\n" shadow_diff = window.do_cmd_with_pbar(cmd, _("Shadow CIB Diff"), _("Generating the shadow CIB differences may take a while..."), _("Failed to generate the shadow CIB differences"), False) if shadow_diff == None : #else : shadow_diff_textbuffer.set_text(manager.failed_reason) dialog.show_all() save_top_window = top_window top_window = dialog while True : ret = dialog.run() if ret == gtk.RESPONSE_APPLY : self.save_shadow_diff(shadow_diff_textbuffer) else : break dialog.destroy() top_window = save_top_window manager.do_cmd("init_cib\n%s"%(reinit_name)) if manager.failed_reason != "" : msgbox(manager.failed_reason) else : manager.set_update() def save_shadow_diff(self, textbuffer) : default_name = manager.active_cib + ".diff" filter_list = ((_("Diff Files"), ("*.diff",)), (_("All Files"), ("*"))) sfdlg = SelectFileDlg() (save_file, save_type) = sfdlg.select_file(default_name, filter_list) if save_file == None : return save_str = textbuffer.get_text(*textbuffer.get_bounds()) if save_str == None : msgbox(_("Cannot save the shadow diff")) return try : fd = os.open(save_file, os.O_RDWR|os.O_CREAT|os.O_TRUNC, 0644) except OSError, msg : msgbox(_("System error") + _(": ") + str(msg)) return try : os.write(fd, save_str) except OSError, msg : msgbox(_("System error") + _(": ") + str(msg)) os.close(fd) return os.close(fd) def on_create_cib(self, action) : global top_window shadows = manager.do_cmd("get_shadows") if shadows == None or len(shadows) == 0 : shadow_list = [] else : shadow_list = [shadow[len("shadow."):] for shadow in shadows] shadow_list.sort() dialog = gtk.Dialog(_("Create Shadow CIB"), top_window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_default_response(gtk.RESPONSE_OK) dialog.set_border_width(5) combo_entries = {} checkbuttons = {} radiobuttons = {} for key in ["shadow_name", "live", "empty","force"] : hbox = gtk.HBox() if key in ["shadow_name"] : name_label = gtk.Label(_(name_cap(key))+_(":")) name_label.set_alignment(0, 0.5) hbox.pack_start(name_label, False, padding=2) if key == "shadow_name" : widget = gtk.combo_box_entry_new_text() for shadow in shadow_list : widget.append_text(shadow) widget.child.set_activates_default(True) combo_entries[key] = widget elif key == "live" : widget = gtk.RadioButton(None, _("A copy of the live CIB")) radiobuttons[key] = widget live_radio_btn = widget elif key == "empty" : widget = gtk.RadioButton(live_radio_btn, _("A new CIB with empty cluster configuration")) radiobuttons[key] = widget elif key == "force" : widget = gtk.CheckButton(_(name_cap(key))) checkbuttons[key] = widget hbox.pack_start(widget, True, padding=2) dialog.vbox.pack_start(hbox, False, padding=2) widgets = {} widgets["combo_entries"] = combo_entries widgets["checkbuttons"] = checkbuttons widgets["radiobuttons"] = radiobuttons widget_group = WidgetGroup(widgets) save_top_window = top_window top_window = dialog dialog.show_all() while True: ret = dialog.run() if ret in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT] : break create_shadow = widget_group.get_values() shadow_name = create_shadow.get("shadow_name", "") if shadow_name == "" : msgbox(_("Please specify a name for the shadow CIB.")) continue if shadow_name == "Live" or shadow_name == "live" : msgbox(_("Please specify another name for avoiding confusion.")) continue elif shadow_name == manager.active_cib : msgbox(_("A shadow CIB \"%s\" already exists and it's currently active.")%(shadow_name)) continue elif shadow_name in shadow_list and create_shadow.get("force", "") != "true" : msgbox(_("A shadow CIB \"%s\" already exists.")%(shadow_name) + "\n" + _("Specify another name, or select \"Force\" if you want to override it.")) continue if create_shadow.get("live") == "true" : create_cmd = "create" else : create_cmd = "create-empty" cmd_ret = manager.do_cmd("crm_shadow\n%s\n%s\n%s" %(create_cmd, shadow_name, create_shadow.get("force", ""))) if cmd_ret == None : if manager.failed_reason == "" : #msgbox(_("Failed creating shadow CIB")) break if manager.failed_reason.count("A new shadow instance was created") == 0 : msgbox(manager.failed_reason) continue #else : retval = confirmbox(_("A new shadow CIB \"%s\" has been successfully created.")%shadow_name + "\n" +_("Switch to it now?"), (gtk.STOCK_NO, gtk.RESPONSE_NO, gtk.STOCK_YES, gtk.RESPONSE_YES), _("Switch to the new created shadow CIB \"%s\"?")%shadow_name) if retval == gtk.RESPONSE_YES : manager.do_cmd("switch_cib\n%s"%(create_shadow.get("shadow_name", ""))) manager.set_update() break top_window = save_top_window dialog.destroy() def on_switch_cib(self, action, current, switch_list) : switch_name = switch_list[action.get_current_value()] if switch_name == "live" : manager.do_cmd("switch_cib\n") else : manager.do_cmd("switch_cib\n%s"%(switch_name[len("shadow."):])) if manager.failed_reason != "" : msgbox(manager.failed_reason + "\n"+ _("Or you don't have the permission.")) manager.set_update() def render_switch_submenu(self, action) : for menuitem in self.switch_submenu.get_children() : self.switch_submenu.remove(menuitem) shadows = manager.do_cmd("get_shadows") if manager.failed_reason != "" : msgbox(manager.failed_reason) return if shadows == None or len(shadows) == 0 : return #shadow_list = [shadow[len("shadow."):] for shadow in shadows] shadow_list = shadows[:] shadow_list.sort() switch_list = shadow_list[:] switch_list.insert(0, "live") switch_radio_actions = [('live', None, _('Live'), None, None, 0)] for i in range(len(shadow_list)) : shadow = shadow_list[i] switch_radio_actions.append((shadow, None, shadow[len("shadow."):], None, None, i+1)) default_active = 0 if manager.active_cib != "" : active_shadow = "shadow." + manager.active_cib if active_shadow in switch_list : default_active = switch_list.index(active_shadow) switch_radio_actiongroup = gtk.ActionGroup("switch") switch_radio_actiongroup.add_radio_actions(switch_radio_actions, default_active, self.on_switch_cib, switch_list) for switch_name in switch_list : action = switch_radio_actiongroup.get_action(switch_name) action.set_accel_group(self.accelgroup) switch_menuitem = action.create_menu_item() self.switch_submenu.append(switch_menuitem) if switch_name == "live" : separator = gtk.SeparatorMenuItem() self.switch_submenu.append(separator) self.switch_submenu.show_all() def on_transition_info(self, action) : tidlg = TransitionInfoDlg() def on_cluster_report(self, action) : rpdlg = TimeFrameDlg() report_params = rpdlg.set_params(_("Cluster Report"), (False, True, True, False)) if report_params == None : return report_params["ftime"] = time.strftime("%F %T", report_params["ftime"]) if report_params.get("ttime") != None : report_params["ttime"] = time.strftime("%F %T", report_params["ttime"]) report_cmd = "gen_cluster_report\n%s\n%s"%(report_params["ftime"], report_params.get("ttime", "")) str_list = window.do_cmd_with_pbar(report_cmd, _("Cluster Report"), _("Generating the cluster report may take a while,")+"\n" +_("depending on the size of logs..."), _("Failed to generate the cluster report")) if str_list != None : self.save_cluster_report(str_list) def save_cluster_report(self, str_list) : if str_list == None or len(str_list) < 2 : msgbox(_("Failed to generate the cluster report")) return default_filename = os.path.basename(str_list[0]) default_filetype = default_filename.split(".")[-1] base64_str = "\n".join(str_list[1:]) try : bin_str = binascii.a2b_base64(base64_str) except binascii.Incomplete, msg : msgbox(_("Incomplete data") + (": ") + str(msg)) return try : (fd, tmp_file) = tempfile.mkstemp(suffix = ".tar." + default_filetype, prefix = "cluster-report-") except IOError, msg : msgbox(_("I/O error") + _(": ") + str(msg)) return #try : # fd = os.open(save_file, os.O_RDWR|os.O_CREAT|os.O_TRUNC, 0644) #except OSError, msg : # msgbox(_("System error") + _(": ") + str(msg)) # return try : os.write(fd, bin_str) except OSError, msg : msgbox(_("System error") + _(": ") + str(msg)) os.close(fd) return os.close(fd) self.des_cluster_report(tmp_file) def des_cluster_report(self, tmp_file) : tmp_dir = os.path.dirname(tmp_file) default_filename = os.path.basename(tmp_file) default_filetype = default_filename.split(".")[-1] try : tmp_tarfile = tarfile.open(tmp_file, "r:"+default_filetype) except IOError, msg : msgbox(_("I/O error") + _(": ") + str(msg)) return except tarfile.TarError, msg : msgbox(_("Tar error") + _(": ") + "%s: '%s'"%(str(msg), tmp_file)) return try : file_list = tmp_tarfile.getnames() for filename in file_list : tmp_tarfile.extract(filename, tmp_dir) except tarfile.TarError, msg : msgbox(_("Tar error") + _(": ") + "%s: '%s'"%(str(msg), tmp_file)) tmp_tarfile.close() return tmp_tarfile.close() os.unlink(tmp_file) des_filename = None for filename in file_list : if filename.endswith("description.txt") : des_filename = filename break if des_filename != None : des_filepath = os.path.join(tmp_dir, des_filename) try : des_f = open(des_filepath, "r+") except IOError, msg : msgbox(_("I/O error") + _(": ") + str(msg)) self.delete_files(tmp_dir, file_list) return try : file_lines = des_f.readlines() except IOError, msg : msgbox(_("I/O error") + _(": ") + str(msg)) des_f.close() self.delete_files(tmp_dir, file_list) return des_report = DesReportDlg(file_lines) new_file_lines = des_report.run() if new_file_lines == None : new_file_lines = file_lines try : des_f.seek(0) des_f.truncate() des_f.writelines(new_file_lines) except IOError, msg : msgbox(_("I/O error") + _(": ") + str(msg)) des_f.close() self.delete_files(tmp_dir, file_list) return des_f.close() sfdlg = SelectFileDlg() (save_file, save_type) = sfdlg.select_file(default_filename) if save_file == None : self.delete_files(tmp_dir, file_list) return try : new_tarfile = tarfile.open(save_file, "w:"+default_filetype) except IOError, msg : msgbox(_("I/O error") + _(": ") + str(msg)) self.delete_files(tmp_dir, file_list) return except tarfile.TarError, msg : msgbox(_("Tar error") + _(": ") + "%s: '%s'"%(str(msg), save_file)) self.delete_files(tmp_dir, file_list) return current_arcname = os.path.commonprefix(file_list).split(os.sep)[0] if current_arcname != '' : file_basename = os.path.basename(save_file) new_arcname = None for suffix in [".tar.gz", ".tgz", ".gz", ".tar.bz2", ".tbz", ".bz2"] : if save_file.endswith(suffix) : new_arcname = file_basename[:file_basename.rfind(suffix)] break if new_arcname == None : new_arcname = file_basename folder = os.path.join(tmp_dir, current_arcname) try : new_tarfile.add(folder, new_arcname) except IOError, msg : msgbox(_("I/O error") + _(": ") + str(msg)) self.delete_files(tmp_dir, file_list) return except tarfile.TarError, msg : msgbox(_("Tar error") + _(": ") + "%s: '%s'"%(str(msg), save_file)) new_tarfile.close() self.delete_files(tmp_dir, file_list) return new_tarfile.close() self.delete_files(tmp_dir, file_list) else : for filename in file_list : file_path = os.path.join(tmp_dir, filename) try : new_tarfile.add(file_path, recursive=False) except IOError, msg : msgbox(_("I/O error") + _(": ") + str(msg)) new_tarfile.close() self.delete_files(tmp_dir, file_list) return except tarfile.TarError, msg : msgbox(_("Tar error") + _(": ") + "%s: '%s'"%(str(msg), save_file)) new_tarfile.close() self.delete_files(tmp_dir, file_list) return new_tarfile.close() self.delete_files(tmp_dir, file_list) def delete_files(self, save_dir, file_list) : dir_list = [] for filename in file_list : file_path = os.path.join(save_dir, filename) try : mode = os.lstat(file_path)[ST_MODE] except OSError, msg : msgbox(_("System error") + _(": ") + str(msg)) continue if S_ISDIR(mode) : dir_list.append(file_path) else : try : os.unlink(file_path) except OSError, msg : msgbox(_("System error") + _(": ") + str(msg)) continue for dir_path in dir_list : if os.access(dir_path, os.F_OK) : delete_dir(dir_path) def on_about(self, action) : global top_window name = "@PACKAGE@".capitalize() #version = "@VERSION@" version = "" comments = "Pacemaker Management GUI" revision = "Revision: @BUILD_REVISION@" website = "http://www.clusterlabs.org" website_label = "Pacemaker Website" authors = __authors__.strip().split('\n') license = __license__.strip() copyright = "Copyright \xc2\xa9 2007-2012 Gao,Yan " + "\n" \ + "Copyright \xc2\xa9 2005-2006 Huang Zhen " copyright0 = "Copyright \xc2\xa9 2007-2012 Gao,Yan" + "\n" \ + "Copyright \xc2\xa9 2005-2006 Huang Zhen" translators = "Hideo Yamauchi \n" \ + "Gao,Yan " if not pygtk_newer(2, 6) : dialog = gtk.Dialog(_("About") + " " + name, top_window, gtk.DIALOG_MODAL) dialog.set_has_separator(False) dialog.set_border_width(5) dialog.set_resizable(False) dialog.vbox.set_spacing(5) im = gtk.Image() im.set_from_stock("ha", gtk.ICON_SIZE_DIALOG) dialog.vbox.pack_start(im, False) markup_text_list = ['' + name + ' ' + version + '', comments, revision, '' + copyright0 + '', website] for markup_text in markup_text_list : markup_label = gtk.Label() markup_label.set_justify(gtk.JUSTIFY_CENTER) if markup_text == website : markup_text = '' + website_label + '' linkbtn = gtk.Button() linkbtn.add(markup_label) linkbtn.set_relief(gtk.RELIEF_NONE) linkbtn.connect("clicked", self.open_url, website) hbox = gtk.HBox(True) hbox.pack_start(linkbtn, False, False) tooltips = gtk.Tooltips() tooltips.set_tip(linkbtn, website) widget = hbox else : markup_label.set_selectable(True) widget = markup_label markup_label.set_markup(markup_text) dialog.vbox.pack_start(widget, False) close_btn = dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CANCEL) close_btn.grab_default() close_btn.grab_focus() dialog.show_all() else : dialog = gtk.AboutDialog() dialog.set_transient_for(top_window) dialog.set_name(name) dialog.set_version(version) dialog.set_copyright(copyright) dialog.set_license(_(license)) comments += "\n" + revision dialog.set_comments(comments) gtk.about_dialog_set_url_hook(self.open_url) dialog.set_website(website) dialog.set_website_label(website_label) dialog.set_authors(authors) dialog.set_translator_credits(translators) dialog.set_logo(gtk.gdk.pixbuf_new_from_file("@HA_DATADIR@/heartbeat-gui/ha.png")) save_top_window = top_window top_window = dialog dialog.run() top_window = save_top_window dialog.destroy() def open_url(self, widget, link) : webbrowser.open(link) def change_mode_level(self, action, current) : global mode_level mode_level = action.get_current_value() self.update() def load_icon(self, name, file) : icons = gtk.IconFactory() icons.add(name,gtk.IconSet(gtk.gdk.pixbuf_new_from_file(file))) icons.add_default() # constructor def __init__(self) : # create window win_widget = gtk.Window() win_widget.connect("delete_event", self.on_delete_event) win_widget.set_title(_("Pacemaker GUI")) win_widget.set_default_size(manager.profile["width"], manager.profile["height"]) win_widget.set_icon_from_file("@HA_DATADIR@/heartbeat-gui/ha.png") # add the icons to gtk stock self.load_icon("ha", "@HA_DATADIR@/heartbeat-gui/ha.png") if not pygtk_newer(2, 6) : self.load_icon("ha-login","@HA_DATADIR@/heartbeat-gui/login.png") self.load_icon("ha-logout","@HA_DATADIR@/heartbeat-gui/logout.png") self.load_icon("ha-standby-node","@HA_DATADIR@/heartbeat-gui/standby-node.png") self.load_icon("ha-active-node","@HA_DATADIR@/heartbeat-gui/active-node.png") self.load_icon("ha-start-resource","@HA_DATADIR@/heartbeat-gui/start-resource.png") self.load_icon("ha-stop-resource","@HA_DATADIR@/heartbeat-gui/stop-resource.png") #self.load_icon("ha-master-resource","@HA_DATADIR@/heartbeat-gui/master-resource.png") #self.load_icon("ha-slave-resource","@HA_DATADIR@/heartbeat-gui/slave-resource.png") self.load_icon("ha-manage-resource","@HA_DATADIR@/heartbeat-gui/manage-resource.png") self.load_icon("ha-unmanage-resource","@HA_DATADIR@/heartbeat-gui/unmanage-resource.png") self.load_icon("administration","@HA_DATADIR@/heartbeat-gui/administration.png") self.load_icon("record-pending","@HA_DATADIR@/heartbeat-gui/record-pending.png") self.load_icon("nodes","@HA_DATADIR@/heartbeat-gui/nodes.png") self.load_icon("node","@HA_DATADIR@/heartbeat-gui/node.png") self.load_icon("failed","@HA_DATADIR@/heartbeat-gui/failed.png") self.load_icon("running","@HA_DATADIR@/heartbeat-gui/running.png") self.load_icon("stopped","@HA_DATADIR@/heartbeat-gui/stopped.png") self.load_icon("dirty-stopped","@HA_DATADIR@/heartbeat-gui/dirty-stopped.png") self.load_icon("starting","@HA_DATADIR@/heartbeat-gui/starting.png") self.load_icon("stopping","@HA_DATADIR@/heartbeat-gui/stopping.png") #self.load_icon("expert-mode","@HA_DATADIR@/heartbeat-gui/expert-mode.png") # create ui-manager ui_xml = ''' ''' uimanager = gtk.UIManager() self.accelgroup = uimanager.get_accel_group() win_widget.add_accel_group(self.accelgroup) actiongroup = gtk.ActionGroup('haclient') if pygtk_newer(2, 6) : login_icon = gtk.STOCK_CONNECT logout_icon = gtk.STOCK_DISCONNECT else : login_icon = "ha-login" logout_icon = "ha-logout" actiongroup.add_actions([ ('connection', None, _('_Connection')), ('login', login_icon, _('Log_in'), 'i', _('login to cluster'), self.on_login), ('logout', logout_icon, _('Log_out'), 'o', _('logout from cluster'), self.on_logout), ('quit', gtk.STOCK_QUIT, _('_Quit'), None,_('Quit the Program'), self.on_quit), ('view', None, _('_View')), ('shadow', None, _('_Shadow')), ('new', gtk.STOCK_NEW, _('_New'), None,_('Create a new shadow CIB'), self.on_create_cib), ('diff', gtk.STOCK_COPY, _('Di_ff'), 'f', _('Differences between the live CIB and the shadow CIB'), self.on_shadow_diff), ('reset', None, _('_Reset'), 'r', _('Recreate a shadow CIB from the live CIB'), self.on_shadow_action), ('delete', gtk.STOCK_DELETE, _('_Delete'), 'd', _('Delete a shadow CIB'), self.on_shadow_action), ('commit', gtk.STOCK_SAVE, _('_Commit'), 'c', _('Upload a shadow CIB to the cluster'), self.on_shadow_action), ('switch', None, _('_Switch'), None, _('Switch working CIB'), self.render_switch_submenu), ('tools', None, _('_Tools')), ('transition-info', gtk.STOCK_CONVERT, _('_Transition Information'), 't', _('Show Transition Information'), self.on_transition_info), ('report', gtk.STOCK_FIND_AND_REPLACE, _('Cluster Re_port'), 'p', _('generate a cluster report'), self.on_cluster_report), ('help', None, _('_Help')), ('about', gtk.STOCK_ABOUT, _('_About'), 'a', _('About'), self.on_about) ]) uimanager.insert_action_group(actiongroup, 0) radio_tool_actions = [ ('simple-mode', None, _('_Simple Mode'), 's', _('Switch to simple mode'), 0), ('expert-mode', None, _('_Expert Mode'), 'e', _('Switch to expert mode'), 1), ('hack-mode', None, _('_Hack Mode'), 'h', _('Switch to hack mode'), 2), ] self.radio_tool_action_group = gtk.ActionGroup("radio_mode_level") self.radio_tool_action_group.add_radio_actions(radio_tool_actions, 0, self.change_mode_level) uimanager.insert_action_group(self.radio_tool_action_group, 1) uimanager.add_ui_from_string(ui_xml) # put componets to window vbox = gtk.VBox() win_widget.add(vbox) menubar = uimanager.get_widget('/menubar') vbox.pack_start(menubar, False) switch_menu = uimanager.get_widget("/menubar/shadow/switch") self.switch_submenu = gtk.Menu() switch_menu.set_submenu(self.switch_submenu) #switch_menu.connect("focus", self.render_switch_submenu) toolbar = uimanager.get_widget('/toolbar') toolbar.set_style(gtk.TOOLBAR_ICONS) vbox.pack_start(toolbar, False) hpaned = gtk.HPaned() vbox.pack_start(hpaned) #maintree = MainTree("cib") maintree_sw = gtk.ScrolledWindow() maintree_sw.set_shadow_type(gtk.SHADOW_IN) maintree_sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.maintree = MainTree() maintree_sw.add(self.maintree.widget) #maintree_sw.add(maintree) #maintree_frame = gtk.Frame() #maintree_frame.add(maintree_sw) hpaned.add1(maintree_sw) mainview_sw = gtk.ScrolledWindow() mainview_sw.set_shadow_type(gtk.SHADOW_IN) mainview_sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) #mainview_frame = gtk.Frame() #mainview_frame.add(mainview_sw) hpaned.add2(mainview_sw) self.statusbar = gtk.Statusbar() vbox.pack_end(self.statusbar, False) # show the window win_widget.show_all() # keep some widgets self.win_widget = win_widget self.actiongroup = actiongroup self.uimanager = uimanager self.maintree_sw = maintree_sw self.mainview_sw = mainview_sw self.update_ui() self.statusbar.push(0,_("Not Connected")) class Manager : ''' Manager will connect to mgmtd and control the main window ''' connected = False window = None server = None username = None password = None cache = {} no_update_cache = {} parent = {} io_tag = None update_timer = -1 active_nodes = [] all_nodes = [] try_nodes = [] failed_reason = "" dtd_elems = {} session_lock = thread.allocate_lock() async_ret_lock = thread.allocate_lock() #async_ret_str = {} async_ret_list = {} xml_nodes = {} active_cib = None validate_name = None profile = {} # cache functions def __init__(self) : self.load_profile() def cache_lookup(self, key) : if self.cache.has_key(key) : return self.cache[key] if self.no_update_cache.has_key(key) : return self.no_update_cache[key] return None def cache_update(self, key, data, keep_in_cache = False) : if not keep_in_cache : self.cache[key] = data else : self.no_update_cache[key] = data def cache_delkey(self, key) : if self.cache.has_key(key) : del self.cache[key] def cache_clear(self) : self.cache.clear() # internal functions def split_attr_list(self, attrs, keys) : attr_list = [] if attrs != None : for i in range(0, len(attrs), len(keys)) : attr = {} for j in range (0, len(keys)) : attr[keys[j]] = attrs[i+j] attr_list.append(attr) return attr_list def run(self) : gtk.gdk.threads_init() gtk.main() if self.connected : mgmt_disconnect() # connection functions def load_profile(self) : keys = ["server", "user", "width", "height"] self.profile["server"] = "127.0.0.1" self.profile["user"] = "hacluster" self.profile["width"] = 790 self.profile["height"] = 550 save_path = os.environ["HOME"]+"/.haclient" if not os.path.exists(save_path) : return try: values = pickle.load(file(save_path,"r")) user_profile = dict(zip(keys, values)) self.profile.update(user_profile) return except: return def save_profile(self) : global top_window server = self.profile["server"] user = self.profile["user"] (width, height) = top_window.get_size() self.profile["width"] = width self.profile["height"] = height save_path = os.environ["HOME"]+"/.haclient" try: pickle.dump((server, user, width, height), file(save_path,"w")) except: os.remove(save_path) return def login(self, server, username, password) : # connect to one of the cluster self.failed_reason = "" if string.find(server, ":") != -1 : server_host, port = string.split(server,":") else : server_host = server port = "" try : ip = socket.gethostbyname(server_host) except socket.error : self.failed_reason = _("Can't resolve address of server ")+server_host return False try : ret = mgmt_connect(ip, username, password, port) except : self.failed_reason = _("Can't connect to server ")+server mgmt_disconnect() return False if ret != 0 : if ret == -1 : self.failed_reason = _("Can't connect to server ")+server elif ret == -2 : self.failed_reason =\ _("Failed in the authentication.\n User Name or Password may be wrong." \ "\n or the user doesn't belong to haclient group") else : self.failed_reason = _("Can't login to server.\n The protocols may be mismatched.") mgmt_disconnect() return False window.statusbar.pop(1) window.statusbar.push(1,_("Connected to ")+username+"@"+server_host) self.connected = True if server != None and server not in self.try_nodes : self.try_nodes.insert(0, server) self.server = server_host self.username = username self.password = password window.statusbar.push(2,_("Updating data from server...")) self.update_timer = gobject.timeout_add(500, self.update) self.do_cmd("regevt\nevt:cib_changed") self.do_cmd("regevt\nevt:disconnected") fd = mgmt_inputfd() self.io_tag = gobject.io_add_watch(fd, gobject.IO_IN, self.on_event, None) gobject.timeout_add(5000, self.update_crm_metadata, priority=gobject.PRIORITY_DEFAULT_IDLE) return True def query(self, query, keep_in_catch = False) : result = self.cache_lookup(query) if result != None : return result result = self.do_cmd(query) self.cache_update(query, result, keep_in_catch) return result def do_cmd(self, command) : self.failed_reason = "" self.session_lock.acquire() ret_str = mgmt_sendmsg(command) self.session_lock.release() if ret_str == None : debug(str(string.split(command, "\n"))+":None") self.failed_reason = "return None" return None while len(ret_str)>=4 and ret_str[:4] == "evt:" : gobject.idle_add(self.on_event, None, None, ret_str) self.session_lock.acquire() ret_str = mgmt_recvmsg() self.session_lock.release() if ret_str == None : debug(str(string.split(command, "\n"))+":None") self.failed_reason = "return None" return None return self.ret_str2list(ret_str, command) def ret_str2list(self, ret_str, command) : self.failed_reason = "" ret_list = string.split(ret_str, "\n") if ret_list[0] != "o" : debug(str(string.split(command, "\n"))+":"+ str(ret_list)) if len(ret_list) > 1 : self.failed_reason = string.join(ret_list[1:],"\n") return None debug(str(string.split(command, "\n"))+":"+ str(ret_list)) return ret_list[1:] def process_ret(self, command, ret_str) : self.failed_reason = "" if ret_str == None : debug(str(string.split(command, "\n"))+":None") self.failed_reason == "return None" return None return self.ret_str2list(ret_str, command) def async_sendmsg(self, command) : self.session_lock.acquire() gobject.source_remove(self.io_tag) async_ret_str = mgmt_thread_sendmsg(command) fd = mgmt_inputfd() self.io_tag = gobject.io_add_watch(fd, gobject.IO_IN, self.on_event, None) self.session_lock.release() self.async_ret_lock.acquire() self.async_ret_list[command] = self.process_ret(command, async_ret_str) self.async_ret_lock.release() def async_do_cmd(self, command) : self.async_ret_lock.acquire() #self.async_ret_str = {} #self.async_ret_list = {} if self.async_ret_list.has_key(command) : self.async_ret_list.pop(command) self.async_ret_lock.release() thread.start_new(self.async_sendmsg, (command, )) def logout(self) : mgmt_disconnect() gobject.source_remove(self.io_tag) self.connected = False window.update() window.statusbar.pop(1) # event handler def on_reconnect(self) : if self.all_nodes == [] : window.statusbar.pop(1) return False try_nodes = self.try_nodes[:] for node in self.all_nodes : if node not in try_nodes : try_nodes.append(node) for server in try_nodes : if self.login(server, self.username, self.password) : return False return True def process_event(self, event) : if event == "evt:cib_changed" : self.set_update() elif event == None or event == "evt:disconnected" : self.logout() try_nodes = self.try_nodes[:] for active_node in self.active_nodes : if active_node not in try_nodes : try_nodes.append(active_node) for server in try_nodes : if self.login(server, self.username, self.password) : break else : window.statusbar.push(1,_("Reconnecting...")) gobject.timeout_add(1000, self.on_reconnect) def set_update(self) : if self.update_timer != -1 : gobject.source_remove(self.update_timer) else : window.statusbar.push(2,_("Updating data from server...")) self.update_timer = gobject.timeout_add(500, self.update) def on_event(self, source, condition, event_str) : if event_str == None : # called by gtk self.session_lock.acquire() event = mgmt_recvmsg() self.session_lock.release() debug("on_event:"+str(event)) self.process_event(event) return True else : # called by do_cmd event = event_str log("on_event: from message queue: "+str(event)) self.process_event(event) return False def cib_do_cmd(self, command): self.failed_reason = "" ret_str = mgmt_sendmsg(command) if ret_str == None: debug(command + ":None") self.failed_reason = "return None" return None ret_list = string.split(ret_str, "\n") if ret_list[0] != "o": debug(str(string.split(command, "\n"))+":"+str(ret_list)) if len(ret_list) > 1: self.failed_reason = string.join(ret_list[1:], "\n") return None return string.join(ret_list[1:], "\n") def update_cib_xml(self) : global validate_type xml_nodes = self.xml_nodes cib_xml = self.cib_do_cmd("cib_query\ncib") if self.failed_reason != "" : #msgbox(self.failed_reason) log(self.failed_reason) return False if cib_xml == None or cib_xml == "" : #msgbox(_("Cannot get the CIB")) log("Cannot get the CIB") return False try : xml_nodes["cib"] = parseString(cib_xml).documentElement except xml.parsers.expat.ExpatError, msg : #msgbox(_("Failed to parse the CIB") + _(": ") + str(msg)) log("Failed to parse the CIB: " + str(msg)) return False """xml_status = self.cib_do_cmd("cib_query\nstatus") xml_rscs = self.cib_do_cmd("cib_query\nresources") xml_nodes = self.cib_do_cmd("cib_query\nnodes") xml_constraints = self.cib_do_cmd("cib_query\nconstraints") xml_crm_config = self.cib_do_cmd("cib_query\ncrm_config")""" if xml_nodes.get("cib") == None : #msgbox(_("Cannot parse the CIB")) log("Cannot parse the CIB") return False validate_type = self.get_validate_type() saved_validate_name = self.validate_name self.validate_name = self.get_validate_name() if validate_type == "dtd" : if not support_pyxml : log("Pacemaker GUI requires pyxml package to process DTD") msgbox(_("Pacemaker GUI requires pyxml package to process DTD")) sys.exit() dtd_elem = self.get_dtd_elem("cib") for (name, mod) in dtd_elem.get_content_model()[1] : if mod != '' : continue xml_nodes[name] = xml_nodes["cib"].getElementsByTagName(name)[0] if xml_nodes.get(name) == None : continue sub_dtd_elem = manager.get_dtd_elem(name) for (sub_name, sub_mod) in sub_dtd_elem.get_content_model()[1] : if sub_mod != '' : continue xml_nodes[sub_name] = xml_nodes[name].getElementsByTagName(sub_name)[0] else : if self.validate_name != saved_validate_name : self.rng_docs = {} self.rng_str_docs = {} self.update_rng_docs(self.validate_name, self.validate_name+".rng") self.supported_rsc_types = self.get_supported_rsc_types() return True """config_xml = self.cib_xml.getElementsByTagName("configuration") self.crm_xml = config_xml.getElementsByTagName("crm_config") self.nodes_xml = config_xml.getElementsByTagName("nodes") self.rscs_xml = config_xml.getElementsByTagName("resources") self.cns_xml = config_xml.getElementsByTagName("constraints") self.status_xml = self.cib_xml.getElementsByTagName("status") try: self.cib_xml = parseString(xml_cib).documentElement self.status_xml = parseString(xml_status) self.rscs_xml = parseString(xml_rscs) self.nodes_xml = parseString(xml_nodes) self.cns_xml = parseString(xml_constraints) self.crm_xml = parseString(xml_crm_config) except xml.parsers.expat.ExpatError: self.status_xml = None self.rscs_xml = None self.nodes_xml = None self.crm_xml = None self.cns_xml = None debug("fail to parse xml info") return None""" def get_active_cib(self) : active_cib = manager.do_cmd("active_cib") if active_cib == None or len(active_cib) == 0 : return if len(active_cib[0]) > 0 : self.active_cib = active_cib[0] else : self.active_cib = "" def get_supported_rsc_types(self) : rsc_types = [] if validate_type == "dtd" : dtd_elem = manager.get_dtd_elem("resources") for (name, mod) in dtd_elem.get_content_model()[1] : rsc_types.append(name) else : sorted_rng_nodes = manager.sorted_sub_rng_nodes_by_name("resources") for rng_node in sorted_rng_nodes.get("element", []) : rsc_types.append(rng_node[0][1].getAttribute("name")) return rsc_types def find_xml_node(self, obj_type, obj_name) : for xml_node in self.xml_nodes["cib"].getElementsByTagName(obj_type) : if xml_node.getAttribute("id") == obj_name : return xml_node return None def find_attribute(self, obj_type, attribute_name) : for xml_node in self.xml_nodes["cib"].getElementsByTagName(obj_type) : for nv_xml_node in xml_node.getElementsByTagName("nvpair") : if nv_xml_node.getAttribute("name") == attribute_name : return nv_xml_node.getAttribute("value") return None def set_crm_attribute(self, type, name, value) : for xml_node in self.xml_nodes["cib"].getElementsByTagName(type) : for attr_node in xml_node.getElementsByTagName("nvpair") : if attr_node.getAttribute("name") == name : attr_id = str(attr_node.getAttribute("id")) self.do_cmd("crm_attribute\n%s\nset\n%s\n%s\n\n\n%s" %(type, name, value, attr_id)) return for child_node in xml_node.childNodes : if child_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue set_id = str(child_node.getAttribute("id")) self.do_cmd("crm_attribute\n%s\nset\n%s\n%s\n\n%s\n" %(type, name, value, set_id)) return self.do_cmd("crm_attribute\n%s\nset\n%s\n%s\n\n\n"%(type, name, value)) def node_name(self, node_id) : for node_xml_node in manager.xml_nodes["cib"].getElementsByTagName("node") : if node_xml_node.getAttribute("id") == node_id : node_name = node_xml_node.getAttribute("uname") return node_name return "" def validate_cib(self, cib_xml_node = None) : if cib_xml_node == None : cib_xml_node = manager.xml_nodes["cib"] if validate_type == "dtd" : is_valid = True elif not support_lxml : is_valid = True else : is_valid = self.validate_with_rng(cib_xml_node) return is_valid def validate_with_rng(self, cib_xml_node) : rng_doc = self.tmp_rng_doc() if rng_doc == None : msgbox(_("Cannot expand the Relax-NG schema")) return False try : cib_doc = etree.fromstring(cib_xml_node.toxml()) except etree.Error, msg : msgbox(_("Failed to parse the CIB XML") + _(": ") + str(msg)) return False try : relaxng = etree.RelaxNG(file = rng_doc) except etree.Error, msg : msgbox(_("Failed to parse the Relax-NG schema") + _(": ") + str(msg)) return False #try : # relaxng.assertValid(cib_doc) #except etree.DocumentInvalid, err_msg : # print err_msg # print relaxng.error_log try : etree.clear_error_log() except : try : etree.clearErrorLog() except : pass is_valid = relaxng.validate(cib_doc) if not is_valid : error_msg = "" for error_entry in relaxng.error_log : error_msg += error_entry.level_name + ": " + error_entry.message + "\n" msgbox(_(error_msg)) delete_dir(os.path.dirname(rng_doc)) return is_valid def tmp_rng_doc(self) : try : tmp_dir = tempfile.mkdtemp() except IOError, msg : msgbox(_("I/O error") + _(": ") + str(msg)) return None for rng_doc_name in self.rng_str_docs : rng_doc_filename = os.path.join(tmp_dir, rng_doc_name) try : fd = os.open(rng_doc_filename, os.O_RDWR|os.O_CREAT|os.O_TRUNC, 0644) except OSError, msg : msgbox(_("System error") + _(": ") + str(msg)) return None rng_doc_str = self.rng_str_docs[rng_doc_name] try : os.write(fd, rng_doc_str) except OSError, msg : msgbox(_("System error") + _(": ") + str(msg)) os.close(fd) return None os.close(fd) if self.validate_name + ".rng" in self.rng_str_docs : return os.path.join(tmp_dir, self.validate_name + ".rng") else : return None def update_rng_docs(self, validate_name = "", file= "") : self.rng_docs[file] = self.get_start_rng_node(validate_name, file) if self.rng_docs[file] == None : return for extern_ref in self.rng_docs[file][0].getElementsByTagName("externalRef") : href_value = extern_ref.getAttribute("href") if self.rng_docs.get(href_value) == None : self.update_rng_docs(validate_name, href_value) def get_start_rng_node(self, validate_name = "", file = "") : schema_info = validate_name + " " + file crm_schema = self.get_crm_schema(validate_name, file) if crm_schema == None : #msgbox(_("Cannot get the Relax-NG schema") + _(": ") + schema_info) log("Cannot get the Relax-NG schema: " + schema_info) return None self.rng_str_docs[file] = crm_schema try : rng_doc = parseString(crm_schema).documentElement except xml.parsers.expat.ExpatError, msg : #msgbox(_("Failed to parse the Relax-NG schema") + _(": ") + str(msg) + schema_info) log("Failed to parse the Relax-NG schema: " + str(msg) + schema_info) return None start_nodes = rng_doc.getElementsByTagName("start") if len(start_nodes) > 0 : start_node = start_nodes[0] return (rng_doc, start_node) else : #msgbox(_("Cannot get started in Relax-NG schema") +_(": ") + schema_info) log("Cannot get started in Relax-NG schema: " + schema_info) return None #sub_start_node = None #for sub_start_node in start_node.childNodes : # if sub_start_node.nodeType == xml.dom.Node.ELEMENT_NODE : # break ##sub_start_nodes = self.get_sub_rng_nodes(start_node)["req_elem_nodes"] ##if sub_start_nodes == [] : #if sub_start_node == None : # #msgbox(_("Cannot get the start element in Relax-NG schema: ") + schema_info) # log("Cannot get the start element in Relax-NG schema: " + schema_info) # return None #else : # return (rng_doc, sub_start_node) def get_rng_elem(self, elem_name) : elem_node = None for (rng_doc, start_node) in self.rng_docs.values() : for elem_node in rng_doc.getElementsByTagName("element") : if elem_node.getAttribute("name") == elem_name : return (rng_doc, elem_node) return None def get_sub_rng_nodes(self, rng_doc, rng_node) : sub_rng_nodes = [] #sub_rng_nodes = {} #req_elem_nodes = [] #attr_nodes = [] for child_node in rng_node.childNodes : if child_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue if child_node.tagName == "ref" : for def_node in rng_doc.getElementsByTagName("define") : if def_node.getAttribute("name") == child_node.getAttribute("name") : break sub_rng_nodes.extend(self.get_sub_rng_nodes(rng_doc, def_node)) elif child_node.tagName == "externalRef" : nodes = self.get_sub_rng_nodes(*self.rng_docs[child_node.getAttribute("href")]) sub_rng_nodes.extend(nodes) elif child_node.tagName in ["element", "attribute", "value", "data", "text"] : sub_rng_nodes.append([(rng_doc, child_node)]) elif child_node.tagName in ["interleave", "optional", "zeroOrMore", "choice", "group", "oneOrMore"] : nodes = self.get_sub_rng_nodes(rng_doc, child_node) for node in nodes : node.append(child_node) sub_rng_nodes.extend(nodes) #sub_rng_nodes["req_elem_nodes"] = req_elem_nodes return sub_rng_nodes def sorted_sub_rng_nodes_by_name(self, obj_type) : rng_node = self.get_rng_elem(obj_type) if rng_node == None or rng_node[1] == None : # msgbox(_("Cannot get %s in Relax-NG schema")%obj_type) return None return self.sorted_sub_rng_nodes_by_node(*rng_node) def sorted_sub_rng_nodes_by_node(self, rng_doc, rng_node) : sub_rng_nodes = manager.get_sub_rng_nodes(rng_doc, rng_node) sorted_nodes = {} for sub_rng_node in sub_rng_nodes : name = sub_rng_node[0][1].tagName if sorted_nodes.get(name) == None : sorted_nodes[name] = [] sorted_nodes[name].append(sub_rng_node) return sorted_nodes def find_decl(self, rng_node, name, first = True) : decl_node_index = 0 for decl_node in rng_node[1:] : if decl_node.tagName == name : decl_node_index = rng_node.index(decl_node) - len(rng_node) if first : break return decl_node_index def get_decl_rng_nodes(self, rng_node) : decl_rng_nodes = {} choice_index = manager.find_decl(rng_node, "choice", False) if choice_index != 0 : decl_rng_nodes["choice"] = rng_node[choice_index] first_choice_index = manager.find_decl(rng_node, "choice") if first_choice_index != choice_index : decl_rng_nodes["first_choice"] = rng_node[first_choice_index] group_index = manager.find_decl(rng_node, "group", False) if group_index != 0 : decl_rng_nodes["group"] = rng_node[group_index] first_group_index = manager.find_decl(rng_node, "group") if first_group_index != group_index : decl_rng_nodes["first_group"] = rng_node[first_group_index] return decl_rng_nodes def get_sorted_decl_nodes(self, decl_nodes_list, decl_type) : sorted_nodes = [] for rng_nodes in decl_nodes_list : rng_node = rng_nodes.get(decl_type) if rng_node != None and rng_node not in sorted_nodes : sorted_nodes.append(rng_node) return sorted_nodes def get_rng_attr_type(self, attr_rng_node) : sub_rng_nodes = self.sorted_sub_rng_nodes_by_node(*attr_rng_node[0]) for sub_rng_node in sub_rng_nodes.get("data", []) : return sub_rng_nodes["data"][0][0][1].getAttribute("type") return None def real_add_obj_type(self, xml_node, obj_type_name, is_wizard = False) : sub_attr_is_any_name = False if validate_type == "dtd" : dtd_elem = manager.get_dtd_elem(obj_type_name) sub_attr_list = dtd_elem.get_attr_list() else : sorted_rng_nodes = manager.sorted_sub_rng_nodes_by_name(obj_type_name) sub_attr_list = [] sub_elem_type_list = [] sub_elem_is_any_name = False if sorted_rng_nodes != None : sub_attr_rng_nodes = sorted_rng_nodes.get("attribute", []) sub_elem_rng_nodes = sorted_rng_nodes.get("element", []) for rng_node in sub_attr_rng_nodes : name = rng_node[0][1].getAttribute("name") if name == "" : sub_attr_is_any_name = True elif sub_attr_list.count(name) == 0 : sub_attr_list.append(name) for rng_node in sub_elem_rng_nodes : name = rng_node[0][1].getAttribute("name") if name == "" : sub_elem_is_any_name = True elif sub_elem_type_list.count(name) == 0 : sub_elem_type_list.append(name) else : sub_attr_is_any_name = True sub_elem_is_any_name = True sub_elem_rng_nodes = [] if not sub_attr_is_any_name and (len(sub_attr_list) == 0 \ or ((mode_level != 2 or is_wizard) and obj_type_name in ["meta_attributes", "instance_attributes", "operations", "cluster_property_set", "utilization"])) : new_mid_elem = None impl = getDOMImplementation() elem_node_list = [] for elem_node in xml_node.getElementsByTagName(obj_type_name) : if elem_node in xml_node.childNodes : elem_node_list.append(elem_node) if len(elem_node_list) == 0 : newdoc = impl.createDocument(None, obj_type_name, None) mid_elem = newdoc.documentElement xml_node.appendChild(mid_elem) new_mid_elem = mid_elem if sub_attr_list.count("id") > 0 : mid_id = manager.auto_unique_id(mid_elem, obj_type_name) mid_elem.setAttribute("id", mid_id) else : mid_elem = elem_node_list[0] if validate_type == "dtd" : (sep,cont,mod) = dtd_elem.get_content_model() if len(cont) > 0 : if len(sub_attr_list) == 0 : sub_obj_type = cont[0][0] else : sub_obj_type = cont[1][0] sub_elem_node_list = [] for sub_elem_node in mid_elem.getElementsByTagName(sub_obj_type) : if sub_elem_node in mid_elem.childNodes : sub_elem_node_list.append(sub_elem_node) if len(sub_elem_node_list) == 0 : newdoc = impl.createDocument(None, sub_obj_type, None) sub_mid_elem = newdoc.documentElement mid_elem.appendChild(sub_mid_elem) mid_elem = sub_mid_elem if new_mid_elem == None : new_mid_elem = mid_elem else : mid_elem = sub_elem_node_list[0] sub_dtd_elem = manager.get_dtd_elem(sub_obj_type) (sub_obj_type, mod) = sub_dtd_elem.get_content_model()[1][0] else : return (None, None, None) else: sub_obj_type = None for sub_elem_rng_node in sub_elem_rng_nodes : if manager.find_decl(sub_elem_rng_node, "optional") != 0 : continue sub_obj_type = sub_elem_rng_node[0][1].getAttribute("name") break if sub_obj_type == None : return (None, None, None) return (mid_elem, sub_obj_type, new_mid_elem) else : return (xml_node, obj_type_name, None) def get_obj_ids(self, xml_node) : id_list = [] node_id = xml_node.getAttribute("id") if node_id != "" and id_list.count(node_id) == 0 : id_list.append(node_id) for child_node in xml_node.childNodes : if child_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue id_list.extend(self.get_obj_ids(child_node)) return id_list def exist_ids(self, xml_node = None) : all_ids = manager.get_obj_ids(manager.xml_nodes["cib"]) top_types = ["crm_config","rsc_defaults", "op_defaults", "nodes", "resources", "constraints", "acls", "fencing-topology", "status"] if xml_node == None : return all_ids top_parent = xml_node while top_parent.parentNode.tagName not in top_types : top_parent = top_parent.parentNode other_ids = manager.get_obj_ids(top_parent) for id in other_ids : if id not in all_ids : all_ids.append(id) current_id = xml_node.getAttribute("id") if current_id in all_ids : all_ids.remove(current_id) return all_ids def auto_id_prefix(self, xml_node, name) : parent_node = xml_node.parentNode parent_type = parent_node.tagName parent_id = parent_node.getAttribute("id") if parent_type == "crm_config" : return "cib-bootstrap-options" elif parent_type in ["rsc_defaults", "op_defaults"] : return parent_type + "-options" elif parent_type == "node" : if xml_node.tagName != "instance_attributes" : return "nodes-" + parent_id + "-" + xml_node.tagName else : return "nodes-" + parent_id elif name == "fencing-level" : return name if parent_id == "" : parent_parent_node = xml_node.parentNode.parentNode parent_parent_id = parent_parent_node.getAttribute("id") if parent_parent_id == "" : parent_parent_type = parent_parent_node.tagName id_prefix = parent_parent_type + "-" + parent_type + "-" + name else : id_prefix = parent_parent_id + "-" + parent_type + "-" + name else : id_prefix = parent_id + "-" + name return id_prefix def get_unique_id(self, id_prefix, xml_node = None) : all_exist_ids = self.exist_ids(xml_node) valid_id_prefix = self.sanify_id(id_prefix) id_suffix = "" new_id = valid_id_prefix while new_id in all_exist_ids : if id_suffix == "" : id_suffix = 0 else : id_suffix += 1 new_id = valid_id_prefix + "-" + str(id_suffix) return new_id def sanify_id(self, id) : valid_prefix = "_" valid_chrs = "-_." for i in range(len(id)) : if id[i].isalpha() or id[i] in valid_prefix : break valid_id = "" for chr in id[i:] : if chr.isalnum() or chr in valid_chrs : valid_id += chr else : valid_id += '.' return valid_id def auto_unique_id(self, xml_node, name) : id_prefix = self.auto_id_prefix(xml_node, name) return self.get_unique_id(id_prefix, xml_node) def update(self) : self.cache_clear() if not manager.connected : retval = False elif self.update_cib_xml() : self.get_active_cib() self.parent = {} window.update() retval = False else : retval = True gc.collect() self.update_timer = -1 return retval def get_validate_type(self) : validate_list = { "": "dtd", "pacemaker-0.6": "dtd", "transitional-0.6": "dtd", "pacemaker-0.7": "rng", "pacemaker-1.0": "rng" } validate_name = self.get_validate_name() if validate_name == None : return None else : return validate_list.get(validate_name) def get_validate_name(self) : if self.xml_nodes.get("cib") != None : return self.xml_nodes["cib"].getAttribute("validate-with") else : return None def get_crm_schema(self, validate_name="", file="") : lines = self.query("crm_schema\n%s\n%s"%(str(validate_name), str(file))) if lines == None : return None schema = "\n".join(lines) return schema def get_crm_dtd(self): lines = self.query("crm_dtd", True) if lines == None: return None dtd = "\n".join(lines) return dtd def get_dtd_elem(self, elem_name) : if not self.dtd_elems.has_key(elem_name) : dtd = self.get_crm_schema(self.validate_name) if dtd == None : #msgbox(_("Cannot get the DTD") + _(": ") + self.validate_name) log("Cannot get the DTD:" + self.validate_name) return None complete_dtd = load_dtd_string(dtd) self.dtd_elems[elem_name] = complete_dtd.get_elem(elem_name) return self.dtd_elems[elem_name] # cluster functions def update_crm_metadata(self) : for crm_cmd in ["pengine", "crmd"] : self.query("crm_metadata\n%s"%(crm_cmd),True) return False def get_crm_metadata(self, crm_cmd) : if crm_cmd == None : return None lines = self.query("crm_metadata\n%s"%(crm_cmd),True) if lines == None : return None meta_data = "\n".join(lines) try : doc_xml = parseString(meta_data).documentElement except xml.parsers.expat.ExpatError, msg : log("Failed to parse the metadata of %s: %s"%(crm_cmd, msg)) return None meta = RAMeta() meta.name = doc_xml.getAttribute("name") meta.version = "" version_xml = doc_xml.getElementsByTagName("version") if version_xml != [] and version_xml[0] in doc_xml.childNodes : meta.version = version_xml[0].childNodes[0].data meta.longdesc = self.get_locale_desc(doc_xml, "longdesc"); meta.shortdesc = self.get_locale_desc(doc_xml, "shortdesc"); params = {} for param_xml in doc_xml.getElementsByTagName("parameter") : param = {} param["name"] = param_xml.getAttribute("name") param["unique"] = param_xml.getAttribute("unique") param["longdesc"] = self.get_locale_desc(param_xml, "longdesc"); param["shortdesc"] = self.get_locale_desc(param_xml, "shortdesc"); content_xml = param_xml.getElementsByTagName("content")[0] content = {} content["type"] = content_xml.getAttribute("type") content["default"] = content_xml.getAttribute("default") if content["type"] == "enum" : values_tag = "Allowed values:" index = param["longdesc"].rfind(values_tag) if index != -1: strings = param["longdesc"][index+len(values_tag):].split(",") content["values"] = [] for string in strings: content["values"].append(string.strip()) param["content"] = content params[param["name"]] = param param_names = params.keys() param_names.sort() meta.parameters = [] for param_name in param_names : meta.parameters.append(params[param_name]) return meta def get_cluster_type(self) : typelist = manager.query("cluster_type") if typelist != None and len(typelist) > 0 : cluster_type = typelist[0] else : cluster_type = "" return cluster_type def get_hb_config(self) : values = manager.query("hb_config") hb_config = {} if values != None: i = 0 while i < len(values) : hb_config[values[i]] = values[i+1] i += 2 return hb_config def get_cluster_config(self) : config = {} cluster_type = self.get_cluster_type() if cluster_type == "heartbeat" : config = self.get_hb_config() return config # node functions def get_dc(self): return self.query("dc") def get_all_nodes(self) : all_nodes = self.query("all_nodes") if all_nodes == None : all_nodes = self.query("crm_nodes") if all_nodes != None : self.all_nodes = all_nodes else : self.all_nodes = [] return self.all_nodes def get_nodetype(self, node): node_type = self.query("node_type\n%s"%node) if node_type != None and len(node_type) > 0 : return node_type[0] else : return None def get_normal_nodes(self) : nodes = self.query("all_nodes") if nodes == None : return self.get_crm_nodes() normal_nodes = [] for node in nodes : if self.get_nodetype(node) == "normal" : normal_nodes.append(node) return normal_nodes def get_active_nodes(self): active_nodes = self.query("active_nodes") if active_nodes != None : self.active_nodes = active_nodes else : self.active_nodes = [] return self.active_nodes def get_crm_nodes(self): return self.query("crm_nodes") def get_node_config(self, node) : node_attr_names = ["uname", "online","standby", "unclean", "shutdown", "expected_up","is_dc","type", "pending","standby_onfail"] values = manager.query("node_config\n%s"%node) if values == None : values = ["" for i in range(8)] config = dict(zip(node_attr_names,values)) return config def get_running_rsc(self, node) : return self.query("running_rsc\n%s"%node) # resource functions def get_top_rsc(self) : return self.query("all_rsc") def get_rsc_type(self, rsc_id) : rsc_type_ret = self.query("rsc_type\n"+rsc_id) if rsc_type_ret != None and len(rsc_type_ret) > 0 : rsc_type = rsc_type_ret[0] else : rsc_type = None if rsc_type == "native" : return "primitive" else : return rsc_type def get_rsc_status(self, rsc_id) : status = self.query("rsc_status\n"+rsc_id) for lrm_node in manager.xml_nodes["cib"].getElementsByTagName("lrm") : node_id = lrm_node.getAttribute("id") for lrm_resource_node in lrm_node.getElementsByTagName("lrm_resource") : if lrm_resource_node.getAttribute("id") == rsc_id : for lrm_rsc_op in lrm_resource_node.getElementsByTagName("lrm_rsc_op") : operation = lrm_rsc_op.getAttribute("operation") if lrm_rsc_op.getAttribute("op-status") == "-1" : if operation == "start" : status[0] = "starting" break elif operation == "stop" : status[0] = "stopping" break return status def get_rsc_running_on(self, rsc_id) : return self.query("rsc_running_on\n"+rsc_id) def get_sub_rsc(self, rsc_id) : sub_rscs = self.query("sub_rsc\n"+rsc_id) if sub_rscs != None : for sub_rsc in sub_rscs : self.parent[sub_rsc] = rsc_id else : return [] return sub_rscs def get_all_subrsc(self, rsc_id) : all_subrscs = [] sub_rscs = self.get_sub_rsc(rsc_id) if sub_rscs != None : for sub_rsc in sub_rscs : all_subrscs.append(sub_rsc) all_sub_subrscs = self.get_all_subrsc(sub_rsc) if all_sub_subrscs != None : all_subrscs.extend(all_sub_subrscs) return all_subrscs def get_all_rsc(self) : all_rscs = [] top_rscs = self.query("all_rsc") if top_rscs != None : for top_rsc in top_rscs : all_rscs.append(top_rsc) all_subrscs = self.get_all_subrsc(top_rsc) if all_subrscs != None : all_rscs.extend(all_subrscs) return all_rscs def get_all_real_rsc(self) : all_rscs = self.get_all_rsc() all_real_rsc = [] for rsc in all_rscs : rsc_real_id = self.obj_real_id(rsc) if all_real_rsc.count(rsc_real_id) == 0 : all_real_rsc.append(rsc_real_id) return all_real_rsc def get_all_real_subrsc(self, rsc_id) : all_subrscs = self.get_all_subrsc(rsc_id) all_real_subrsc = [] for rsc in all_subrscs : rsc_real_id = self.obj_real_id(rsc) if all_real_subrsc.count(rsc_real_id) == 0 : all_real_subrsc.append(rsc_real_id) return all_real_subrsc def obj_real_id(self, obj_id) : return obj_id.split(":")[0] def op_status2str(self, op_status) : str_list = self.query("op_status2str\n%s"%str(op_status), True) if str_list != None and len(str_list) > 0 : return str_list[0] else : return "" def get_rsc_info(self, rsc_id) : for resources_node in manager.xml_nodes["cib"].getElementsByTagName("resources") : for primitive_node in resources_node.getElementsByTagName("primitive") : if primitive_node.getAttribute("id") == rsc_id : primitive_attrs = self.get_rsc_attrs(primitive_node, ["class", "type", "provider"]) rsc_class = str(primitive_attrs.get("class", "")) rsc_type = str(primitive_attrs.get("type", "")) rsc_provider = str(primitive_attrs.get("provider", "")) return (rsc_class, rsc_type, rsc_provider) return None def get_rsc_attrs(self, primitive_node, attr_names) : attrs ={} ref_node = primitive_node while ref_node and ref_node.nodeType == xml.dom.Node.ELEMENT_NODE : for attr_name in attr_names : if attrs.get(attr_name) : continue attr_value = ref_node.getAttribute(attr_name) if attr_value : attrs[attr_name] = str(attr_value) template_id = ref_node.getAttribute("template") if template_id : ref_node = self.get_template(template_id) else : break return attrs def get_template(self, template_id) : if not template_id : return None for resources_node in manager.xml_nodes["cib"].getElementsByTagName("resources") : for template_node in resources_node.getElementsByTagName("template") : if template_node.getAttribute("id") == template_id : return template_node return None def get_all_templates(self) : templates = [] for resources_node in manager.xml_nodes["cib"].getElementsByTagName("resources") : for template_node in resources_node.getElementsByTagName("template") : template_id = template_node.getAttribute("id") if template_id and template_id not in templates: templates.append(template_id) return templates def get_locale_desc(self, node, tag) : desc_en = "" desc_match = "" (lang, encode) = locale.getlocale() if lang == None: lang = "en" else: lang = string.lower(lang) if encode == None: encode = "" else: encode = string.lower(encode) for child in node.childNodes : if child.nodeType != node.ELEMENT_NODE : continue if child.tagName != tag : continue if len(child.childNodes) == 0: break langtag = string.lower(child.getAttribute("lang")) if langtag == "" : desc_en = child.childNodes[0].data else : langtag = string.split(langtag, ".") if string.find(langtag[0], "en") != -1 : desc_en = child.childNodes[0].data if len(langtag) == 1 and lang == langtag[0] : desc_match = child.childNodes[0].data if len(langtag) == 2 : if lang == langtag[0] and encode == langtag[1] : desc_match = child.childNodes[0].data if desc_match != "" : return desc_match return desc_en def get_rsc_meta(self, rsc_class, rsc_type, rsc_provider) : if rsc_class == None or rsc_class == "" \ or rsc_type == None or rsc_type == "" : return None if rsc_provider == None or rsc_provider == "" : rsc_provider = "heartbeat" lines = self.query("rsc_metadata\n%s\n%s\n%s"% \ (rsc_class, rsc_type, rsc_provider),True) if lines == None : return None meta_data = "" for line in lines : if len(line)!= 0 : meta_data = meta_data + line + "\n" try : doc_xml = parseString(meta_data).documentElement except xml.parsers.expat.ExpatError, msg : errmsg = "Failed to parse the metadata of %s: %s" log(errmsg%(rsc_type, msg)) msgbox(_(errmsg)%(rsc_type, _(msg))) return None meta = RAMeta() meta.name = doc_xml.getAttribute("name") meta.version = "" version_xml = doc_xml.getElementsByTagName("version") if version_xml != [] and version_xml[0] in doc_xml.childNodes : meta.version = version_xml[0].childNodes[0].data meta.longdesc = self.get_locale_desc(doc_xml, "longdesc"); meta.shortdesc = self.get_locale_desc(doc_xml, "shortdesc"); meta.parameters = [] for param_xml in doc_xml.getElementsByTagName("parameter") : param = {} param["name"] = param_xml.getAttribute("name") param["required"] = param_xml.getAttribute("required") param["unique"] = param_xml.getAttribute("unique") param["longdesc"] = self.get_locale_desc(param_xml, "longdesc"); param["shortdesc"] = self.get_locale_desc(param_xml, "shortdesc"); content_xml = param_xml.getElementsByTagName("content")[0] content = {} content["type"] = content_xml.getAttribute("type") content["default"] = content_xml.getAttribute("default") param["value"] = content["default"] param["content"] = content meta.parameters.append(param) meta.actions = [] for action_xml in doc_xml.getElementsByTagName("action") : action = {} for key in action_xml.attributes.keys() : action[key] = action_xml.getAttribute(key) meta.actions.append(action) return meta def get_rsc_classes(self) : return self.query("rsc_classes",True); def get_rsc_types(self, rsc_class) : return self.query("rsc_types\n"+rsc_class,True) def get_rsc_providers(self, rsc_class, rsc_type) : return self.query("rsc_providers\n%s\n%s"%(rsc_class, rsc_type),True) def lrm_op_rc2str(self, rc) : str_list = self.query("lrm_op_rc2str\n%s"%str(rc), True) if str_list != None and len(str_list) > 0 : return str_list[0] else : return "" def rsc_exists(self, rsc_id) : return rsc_id in self.get_all_rsc() class WidgetGroup : def __init__(self, widgets) : self.widgets = widgets def get_values(self) : object = {} widgets = self.widgets if widgets.has_key("value_labels") : for key in widgets["value_labels"].keys() : if widgets["value_labels"][key].get_property("sensitive") == False : continue object[key] = widgets["value_labels"][key].get_text() if object[key] == "" or object[key] == None : object.pop(key) if widgets.has_key("combos") : for key in widgets["combos"].keys() : if widgets["combos"][key].get_property("sensitive") == False : continue if pygtk_newer(2, 6) : object[key] = widgets["combos"][key].get_active_text() else : iter = widgets["combos"][key].get_active_iter() if iter != None : object[key] = widgets["combos"][key].get_model().get_value(iter, 0) else : object[key] = None if object[key] == "" or object[key] == None : object.pop(key) if widgets.has_key("bool_combos") : for key in widgets["bool_combos"].keys() : if widgets["bool_combos"][key].get_property("sensitive") == False : continue if pygtk_newer(2, 6) : object[key] = widgets["bool_combos"][key].get_active_text() else : iter = widgets["bool_combos"][key].get_active_iter() if iter != None : object[key] = widgets["bool_combos"][key].get_model().get_value(iter, 0) else : object[key] = None if object[key] == "" or object[key] == None : object.pop(key) if widgets.has_key("combo_entries") : for key in widgets["combo_entries"].keys() : if widgets["combo_entries"][key].get_property("sensitive") == False : continue object[key] = widgets["combo_entries"][key].child.get_text() if object[key] == "" or object[key] == None : object.pop(key) if widgets.has_key("checkbuttons") : for key in widgets["checkbuttons"].keys() : if widgets["checkbuttons"][key].get_property("sensitive") == False : continue if widgets["checkbuttons"][key].get_active() : object[key] = "true" else: object[key] = "false" if widgets.has_key("entries") : for key in widgets["entries"].keys() : if widgets["entries"][key].get_property("sensitive") == False : continue object[key] = widgets["entries"][key].get_text() if object[key] == "" or object[key] == None : object.pop(key) if widgets.has_key("spinbuttons") : for key in widgets["spinbuttons"].keys() : if widgets["spinbuttons"][key].get_property("sensitive") == False : continue object[key] = str(int(widgets["spinbuttons"][key].get_value())) if object[key] == "" or object[key] == None : object.pop(key) if widgets.has_key("anyname_combo_entries") : for key in widgets["anyname_combo_entries"].keys() : if widgets["anyname_combo_entries"][key].get_property("sensitive") == False : continue attr_name = key.get_text() object[attr_name] = widgets["anyname_combo_entries"][key].child.get_text() if attr_name == "" or object[attr_name] == "" or object[attr_name] == None : object.pop(attr_name) if widgets.has_key("radiobuttons") : for key in widgets["radiobuttons"].keys() : if widgets["radiobuttons"][key].get_property("sensitive") == False : continue if widgets["radiobuttons"][key].get_active() : object[key] = "true" else: object[key] = "false" return object def show_values(self, object) : widgets = self.widgets if widgets.has_key("value_labels") : for key in widgets["value_labels"].keys() : if object.has_key(key) : widgets["value_labels"][key].set_text(object[key]) if widgets.has_key("combos") : for key in widgets["combos"].keys() : if object.has_key(key) : iter = widgets["combos"][key].get_model().get_iter_first() while iter != None : if widgets["combos"][key].get_model().get_value(iter,0) == object[key] : widgets["combos"][key].set_active_iter(iter) iter = widgets["combos"][key].get_model().iter_next(iter) else : widgets["combos"][key].set_active(0) if widgets.has_key("bool_combos") : for key in widgets["bool_combos"].keys() : if object.has_key(key) : if object[key] == "true" or object[key] == "yes" or object[key] == "1" : bool_value = "true" elif object[key] == "false" or object[key] == "no" or object[key] == "0" : bool_value = "false" else : bool_value = object[key] iter = widgets["bool_combos"][key].get_model().get_iter_first() while iter != None : if widgets["bool_combos"][key].get_model().get_value(iter,0) == bool_value : widgets["bool_combos"][key].set_active_iter(iter) iter = widgets["bool_combos"][key].get_model().iter_next(iter) else : widgets["bool_combos"][key].set_active(0) if widgets.has_key("combo_entries") : for key in widgets["combo_entries"].keys(): if object.has_key(key) : widgets["combo_entries"][key].child.set_text(object[key]) else : widgets["combo_entries"][key].child.set_text("") if widgets.has_key("entries") : for key in widgets["entries"].keys() : if object.has_key(key) : widgets["entries"][key].set_text(object[key]) else : widgets["entries"][key].set_text("") if widgets.has_key("checkbuttons") : for key in widgets["checkbuttons"].keys() : if object.has_key(key) : lower_value = object[key].lower() widgets["checkbuttons"][key].set_active("true" == lower_value or "yes" == lower_value or "1" == lower_value) if widgets.has_key("spinbuttons") : for key in widgets["spinbuttons"].keys() : if object.has_key(key) : try : widgets["spinbuttons"][key].set_value(float(object[key])) except : pass if widgets.has_key("anyname_combo_entries") : for key in widgets["anyname_combo_entries"].keys() : attr_name = key.get_text() if object.has_key(attr_name) : widgets["anyname_combo_entries"][key].child.set_text(object[attr_name]) else : widgets["anyname_combo_entries"][key].child.set_text("") class ObjectAttrs(WidgetGroup) : dynamic_layout = None dynamic_fill = None dynamic_desc = None static_desc = None dynamic_render = None dynamic_set_id = None save_id = None def __init__(self, xml_node, is_newobj = False, change_call_back = None, hide_optional = False) : self.xml_node = xml_node self.obj_type = xml_node.tagName self.is_newobj = is_newobj self.change_call_back = change_call_back self.hide_optional = hide_optional self.render_attrs_vbox() if validate_type == "dtd" : self.dtd_elem = manager.get_dtd_elem(self.obj_type) self.attr_list = dtd_elem.get_attr_list() if self.dtd_elem.get_content_model()[1] == [] : self.auto_id = True self.dynamic_set_id = self.dynamic_set_id_auto else : self.auto_id = False self.render_widgets_dtd() else : self.render_widgets_rng() for widget_type in ("combos", "bool_combos", "combo_entries") : if self.widgets.has_key(widget_type) : for widget in self.widgets[widget_type].values() : if pygtk_newer(2, 10) and pygobject_newer(2, 12, 3) : widget.connect("changed", self.on_changed) else : widget.connect("changed", self.on_changed_later) for widget in self.widgets.get("anyname_combo_entries", {}) : if pygtk_newer(2, 10) and pygobject_newer(2, 12, 3) : widget.connect("changed", self.on_changed) self.widgets["anyname_combo_entries"][widget].connect("changed", self.on_changed) else : widget.connect("changed", self.on_changed_later) self.widgets["anyname_combo_entries"][widget].connect("changed", self.on_changed_later) def verify_values(self) : if validate_type == "dtd" : return self.verify_values_dtd() else : return self.verify_values_rng() def on_after_show(self) : if self.auto_id or (mode_level == 0 and self.dynamic_set_id != None) : self.hide_id_widget() if self.auto_id == True : if self.is_newobj : if self.widgets.has_key("combo_entries") and self.widgets["combo_entries"].has_key("id") : if len(self.widgets["combo_entries"]["id"].child.get_text()) == 0 : #self.widgets["combo_entries"]["id"].child.set_text(self.obj_type + "-" + gen_uuid()) obj_id = manager.auto_unique_id(self.xml_node, self.obj_type) self.widgets["combo_entries"]["id"].child.set_text(obj_id) # self.widgets["name_labels"]["id"].hide_all() # self.widgets["combo_entries"]["id"].hide_all() # else : # if self.widgets.has_key("name_labels") and self.widgets["name_labels"].has_key("id") : # self.widgets["name_labels"]["id"].hide_all() # self.widgets["value_labels"]["id"].hide_all() else : if self.is_newobj and not self.id_is_idref and self.obj_type not in \ ["node", "primitive", "template", "group", "clone", "master","master_slave", \ "rsc_location", "rsc_colocation", "rsc_order", "rsc_ticket", "acl_user", "acl_role"] : if self.widgets.has_key("combo_entries") and self.widgets["combo_entries"].has_key("id") \ and len(self.widgets["combo_entries"]["id"].child.get_text()) == 0 : obj_id = manager.auto_unique_id(self.xml_node, self.obj_type) self.widgets["combo_entries"]["id"].child.set_text(obj_id) # parent_id = self.xml_node.parentNode.getAttribute("id") # if parent_id == "" : # id_prefix = self.obj_type # else : # id_prefix = parent_id + "-" + self.obj_type # self.widgets["combo_entries"]["id"].child.set_text(id_prefix) if self.pref_expand and (mode_level != 0 or self.obj_type not in ["op", "rsc_order"] ) : self.optional_expander.set_expanded(True) self.auto_fill() if len(self.required_vbox.get_children()) < 2 : self.required_vbox.hide() if len(self.optional_vbox.get_children()) < 1 or self.hide_optional : self.optional_expander.hide() if self.dynamic_desc == None and self.static_desc == None : #self.vbox_labels["Description"].hide() self.desc_outer_vbox.hide() if self.static_desc != None : self.show_desc(self.static_desc) if not pygtk_newer(2, 10) or not pygobject_newer(2, 12, 3) : return for widget_type in ("combos", "bool_combos", "combo_entries") : if self.widgets.has_key(widget_type) : for widget in self.widgets[widget_type].values() : widget.disconnect_by_func(self.on_changed) widget.connect("changed", self.on_changed_later) for widget in self.widgets.get("anyname_combo_entries", {}) : widget.disconnect_by_func(self.on_changed) widget.connect("changed", self.on_changed_later) self.widgets["anyname_combo_entries"][widget].disconnect_by_func(self.on_changed) self.widgets["anyname_combo_entries"][widget].connect("changed", self.on_changed_later) def render_attrs_vbox(self) : required_vbox = gtk.VBox() optional_vbox = gtk.VBox() optional_expander = gtk.Expander() optional_expander.add(optional_vbox) desc_outer_vbox = gtk.VBox() widget_list = [(required_vbox, "Required"), (optional_expander, "Optional"), (desc_outer_vbox, "Description")] self.vbox_labels = {} for (widget, label_text) in widget_list : vbox_label = gtk.Label() vbox_label.set_markup('' + _(label_text) + '') vbox_label.set_alignment(0, 1) if label_text == "Optional" : widget.set_label_widget(vbox_label) else : widget.pack_start(vbox_label, False, padding=2) self.vbox_labels[label_text] = vbox_label desc_vbox = gtk.VBox() desc_sw = gtk.ScrolledWindow() desc_sw.set_shadow_type(gtk.SHADOW_NONE) desc_sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) desc_sw.add_with_viewport(desc_vbox) desc_sw.child.set_shadow_type(gtk.SHADOW_NONE) desc_outer_vbox.pack_start(desc_sw) desc_outer_vbox.set_size_request(380, 100) attrs_vbox = gtk.VBox() for (widget, label_text) in widget_list : if label_text == "Description" : attrs_vbox.pack_start(widget, True, padding = 2) else : attrs_vbox.pack_start(widget, False, padding = 2) self.attrs_vbox = attrs_vbox self.required_vbox = required_vbox self.optional_vbox = optional_vbox self.optional_expander = optional_expander self.desc_outer_vbox = desc_outer_vbox self.desc_vbox = desc_vbox def render_widgets_dtd(self): obj_type = self.obj_type is_newobj = self.is_newobj required_vbox = self.required_vbox optional_vbox = self.optional_vbox attrs_vbox = self.attrs_vbox dtd_elem = self.dtd_elem widgets = {} name_labels = {} value_labels = {} combos = {} bool_combos = {} combo_entries = {} required_row = 0 optional_row = 0 name_label_max_len = 0 self.hboxes = {} for attr_name in self.attr_list : attr = dtd_elem.get_attr(attr_name) label_text = _(name_cap(attr_name)) + _(":") label = gtk.Label(label_text) label.set_alignment(0, 0.5) label_len = label.size_request()[0] if label_len > name_label_max_len : name_label_max_len = label_len eventbox = gtk.EventBox() eventbox.add(label) name_labels[attr_name] = label attr_type = attr.get_type() attr_default = attr.get_default() attr_decl = attr.get_decl() if attr_name == "id" and is_newobj == False : widget = gtk.Label() widget.set_alignment(0, 0.5) value_labels[attr_name] = widget elif type(attr_type) == list: is_boolean = False store = gtk.ListStore(str, str) if attr_decl != "#REQUIRED" : store.append(["", ""]) if attr_type.count("true") > 0 and attr_type.count("false") > 0 : options = ("true", "false") is_boolean = True else: options = attr_type for option in options: if attr_default != None and option == attr_default : store.append([option, "["+_("default")+"]"]) else : store.append([option, ""]) widget = gtk.ComboBox(store) cell0 = gtk.CellRendererText() cell1 = gtk.CellRendererText() widget.pack_start(cell0, True) widget.pack_start(cell1, True) widget.add_attribute(cell0, 'text', 0) widget.add_attribute(cell1, 'text', 1) if is_boolean == False : combos[attr_name] = widget else : bool_combos[attr_name] = widget else : store = gtk.ListStore(str, str) if attr_decl != "#REQUIRED" : store.append(["", ""]) if attr_default != None : store.append([attr_default, "["+_("default")+"]"]) widget = gtk.ComboBoxEntry(store) cell = gtk.CellRendererText() widget.pack_start(cell, True) widget.add_attribute(cell, 'text', 1) widget.child.set_activates_default(True) combo_entries[attr_name] = widget hbox = gtk.HBox() hbox.pack_start(eventbox, False, padding=5) hbox.pack_start(widget, padding=5) if attr_decl == "#REQUIRED": required_vbox.pack_start(hbox, False, padding=2) else: optional_vbox.pack_start(hbox, False, padding=2) self.hboxes[attr_name] = hbox attrs_vbox.show_all() for name_label in name_labels.values() : name_label.set_size_request(name_label_max_len, -1) widgets["name_labels"] = name_labels widgets["value_labels"] = value_labels widgets["combos"] = combos widgets["bool_combos"] = bool_combos widgets["combo_entries"] = combo_entries self.widgets = widgets def verify_values_dtd(self) : widgets = self.widgets obj_type = self.obj_type passed = True dtd_elem = self.dtd_elem object = self.get_values() for attr_name in self.attr_list : attr = dtd_elem.get_attr(attr_name) attr_decl = attr.get_decl() if attr_decl == "#REQUIRED" and not object.has_key(attr_name) : msgbox(_(name_cap(attr_name)) + (":")+_(" can't be empty")) passed =False return passed def render_widgets_rng(self): obj_type = self.obj_type is_newobj = self.is_newobj required_vbox = self.required_vbox optional_vbox = self.optional_vbox attrs_vbox = self.attrs_vbox widgets = {} name_labels = {} value_labels = {} combos = {} bool_combos = {} combo_entries = {} required_row = 0 optional_row = 0 name_label_max_len = 0 self.attr_rng_node_dict = {} self.elem_rng_node_dict = {} attr_is_any_name = False any_attr_decl = [] elem_is_any_name = False attr_list = [] elem_type_list = [] id_is_idref = False sorted_rng_nodes = manager.sorted_sub_rng_nodes_by_name(self.obj_type) if sorted_rng_nodes != None : attr_rng_nodes = sorted_rng_nodes.get("attribute", []) elem_rng_nodes = sorted_rng_nodes.get("element", []) for rng_node in attr_rng_nodes : name = rng_node[0][1].getAttribute("name") if name == "" : attr_is_any_name = True for decl in ["optional", "zeroOrMore", "oneOrMore"] : if manager.find_decl(rng_node, decl) != 0 : any_attr_decl.append(decl) else: if attr_list.count(name) == 0 : attr_list.append(name) self.attr_rng_node_dict[name] = [] if name == "id" : sub_rng_nodes = manager.sorted_sub_rng_nodes_by_node(*rng_node[0]) for sub_rng_node in sub_rng_nodes.get("data", []) : if sub_rng_nodes["data"][0][0][1].getAttribute("type") == "IDREF" : id_is_idref = True break self.attr_rng_node_dict[name].append(rng_node) for rng_node in elem_rng_nodes : name = rng_node[0][1].getAttribute("name") if name == "" : elem_is_any_name = True else : if elem_type_list.count(name) == 0 : elem_type_list.append(name) self.elem_rng_node_dict[name] = [] self.elem_rng_node_dict[name].append(rng_node) else : attr_is_any_name = True any_attr_decl.append("zeroOrMore") elem_is_any_name = True attr_rng_nodes = [] elem_rng_nodes = None self.attr_list = attr_list self.any_attr_decl = any_attr_decl self.attr_rng_nodes = attr_rng_nodes self.id_is_idref = id_is_idref other_attrs = [] if attr_is_any_name : for attr_name in self.xml_node.attributes.keys() : if attr_list.count(attr_name) == 0 : if attr_name == "id" : other_attrs.insert(0, attr_name) else : other_attrs.append(attr_name) attr_list.extend(other_attrs) if any_attr_decl.count("zeroOrMore") or any_attr_decl.count("oneOrMore") : other_attrs.append("") if elem_rng_nodes == [] and not id_is_idref : self.auto_id = True self.dynamic_set_id = self.dynamic_set_id_auto else : self.auto_id = False sub_elem_node_list = [] for child_node in self.xml_node.childNodes : if child_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue sub_elem_node_list.append(child_node) if len(sub_elem_node_list) == 0 : self.pref_expand = True else : self.pref_expand = False self.hboxes = {} store_list = {} for attr_node in attr_rng_nodes : attr_name = attr_node[0][1].getAttribute("name") if attr_name == "" : continue sub_rng_nodes = manager.sorted_sub_rng_nodes_by_node(*attr_node[0]) if store_list.get(attr_name) != None : if len(sub_rng_nodes.get("value",[])) > 0 : for value_node in sub_rng_nodes["value"] : store_list[attr_name].append([value_node[0][1].childNodes[0].data, ""]) for sub_rng_node in sub_rng_nodes.get("data", []) : if sub_rng_nodes["data"][0][0][1].getAttribute("type") == "boolean" : for option in ("true", "false") : store_list[attr_name].append([option, ""]) continue label_text = _(name_cap(attr_name)) + _(":") label = gtk.Label(label_text) label.set_alignment(0, 0.5) label_len = label.size_request()[0] if label_len > name_label_max_len : name_label_max_len = label_len eventbox = gtk.EventBox() eventbox.add(label) name_labels[attr_name] = label if attr_name == "id" and not id_is_idref and is_newobj == False : widget = gtk.Label() widget.set_alignment(0, 0.5) value_labels[attr_name] = widget elif len(sub_rng_nodes.get("value",[])) > 0 \ and len(sub_rng_nodes.get("data", [])) == 0 \ and len(sub_rng_nodes.get("text", [])) == 0 : store = gtk.ListStore(str, str) store_list[attr_name] = store if manager.find_decl(attr_node, "optional") != 0 : store.append(["", ""]) for value_node in sub_rng_nodes["value"] : store.append([value_node[0][1].childNodes[0].data, ""]) #for option in options: # if attr_default != None and option == attr_default : # store.append([option, "["+_("default")+"]"]) # else : # store.append([option, ""]) widget = gtk.ComboBox(store) cell0 = gtk.CellRendererText() cell1 = gtk.CellRendererText() widget.pack_start(cell0, True) widget.pack_start(cell1, True) widget.add_attribute(cell0, 'text', 0) widget.add_attribute(cell1, 'text', 1) combos[attr_name] = widget elif len(sub_rng_nodes.get("data",[])) == 1 \ and sub_rng_nodes["data"][0][0][1].getAttribute("type") == "boolean" \ and len(sub_rng_nodes.get("text", [])) == 0 : store = gtk.ListStore(str, str) store_list[attr_name] = store if manager.find_decl(attr_node, "optional") != 0 : store.append(["", ""]) for option in ("true", "false") : store.append([option, ""]) if len(sub_rng_nodes.get("value",[])) > 0 : for value_node in sub_rng_nodes["value"] : store.append([value_node[0][1].childNodes[0].data, ""]) widget = gtk.ComboBox(store) cell0 = gtk.CellRendererText() cell1 = gtk.CellRendererText() widget.pack_start(cell0, True) widget.pack_start(cell1, True) widget.add_attribute(cell0, 'text', 0) widget.add_attribute(cell1, 'text', 1) bool_combos[attr_name] = widget else : store = gtk.ListStore(str, str) store_list[attr_name] = store if manager.find_decl(attr_node, "optional") != 0 : store.append(["", ""]) #if attr_default != None : # store.append([attr_default, "["+_("default")+"]"]) if len(sub_rng_nodes.get("value",[])) > 0 : for value_node in sub_rng_nodes["value"] : store.append([value_node[0][1].childNodes[0].data, ""]) for sub_rng_node in sub_rng_nodes.get("data", []) : if sub_rng_nodes["data"][0][0][1].getAttribute("type") == "boolean" : for option in ("true", "false") : store.append([option, ""]) widget = gtk.ComboBoxEntry(store) cell = gtk.CellRendererText() widget.pack_start(cell, True) widget.add_attribute(cell, 'text', 1) widget.child.set_activates_default(True) combo_entries[attr_name] = widget hbox = gtk.HBox() hbox.pack_start(eventbox, False, padding=5) hbox.pack_start(widget, padding=5) if manager.find_decl(attr_node, "optional") == 0 : required_vbox.pack_start(hbox, False, padding=2) else: optional_vbox.pack_start(hbox, False, padding=2) self.hboxes[attr_name] = hbox anyname_combo_entries = {} for attr_name in other_attrs : (name_entry, widget) = self.render_anyname_widgets(attr_name) anyname_combo_entries[name_entry] = widget attrs_vbox.show_all() for name_label in name_labels.values() : name_label.set_size_request(name_label_max_len, -1) widgets["name_labels"] = name_labels widgets["value_labels"] = value_labels widgets["combos"] = combos widgets["bool_combos"] = bool_combos widgets["combo_entries"] = combo_entries widgets["anyname_combo_entries"] = anyname_combo_entries self.widgets = widgets def render_anyname_widgets(self, attr_name) : any_attr_decl = self.any_attr_decl name_entry = gtk.Entry() name_entry.set_text(attr_name) name_entry.set_activates_default(True) label = gtk.Label(_(":")) store = gtk.ListStore(str, str) widget = gtk.ComboBoxEntry(store) cell = gtk.CellRendererText() widget.pack_start(cell, True) widget.add_attribute(cell, 'text', 1) widget.child.set_activates_default(True) hbox = gtk.HBox() hbox.pack_start(name_entry, False, padding=5) hbox.pack_start(label, False) hbox.pack_start(widget, padding=5) if any_attr_decl.count("optional") or any_attr_decl.count("zeroOrMore") : self.optional_vbox.pack_start(hbox, False, padding=2) elif any_attr_decl.count("oneOrMore") and len(self.widgets.get("anyname_combo_entries", {})) > 0: self.optional_vbox.pack_start(hbox, False, padding=2) else : self.required_vbox.pack_start(hbox, False, padding=2) hbox.show_all() return (name_entry, widget) def verify_values_rng(self) : widgets = self.widgets obj_type = self.obj_type passed = True object = self.get_values() choice_attrs = [] for attr_node in self.attr_rng_nodes : attr_name = attr_node[0][1].getAttribute("name") attr_value = object.get(attr_name) if attr_value != None and manager.get_rng_attr_type(attr_node) in ["ID", "IDREF"]: if not is_valid_id(attr_value) : msgbox(_(name_cap(attr_name))+ _(": ")+_("Invalid identifier \"%s\"")%attr_value) passed = False if object.has_key(attr_name) or manager.find_decl(attr_node, "optional") != 0 \ or manager.find_decl(attr_node, "zeroOrMore") != 0 : continue if manager.find_decl(attr_node, "choice") == 0 : msgbox(_(name_cap(attr_name))+ _(":")+_(" can't be empty")) passed = False else : choice_attrs.append(attr_node) return passed def combobox_store_append(self, combo, append_options) : current_store = combo.get_model() retained_store = [] for i in range(len(current_store)) : if current_store[i][0] == "" : retained_store.insert(0, current_store[i]) elif current_store[i][1] == "["+_("default")+"]" : retained_store.append(current_store[i]) new_store = gtk.ListStore(str, str) for retained in retained_store : new_store.append(retained) retained_list = [k[0] for k in retained_store] for append_option in append_options : if retained_list.count(append_option[0]) == 0 : new_store.append(append_option) combo.set_model(new_store) def auto_fill(self) : widgets = self.widgets rsc_store = gtk.ListStore(str, str) all_real_rsc = manager.get_all_real_rsc() for rsc in all_real_rsc : rsc_store.append([rsc, ""]) node_list = manager.get_normal_nodes() if node_list == None : node_list = [] node_store = [[node, ""] for node in node_list] all_templates = manager.get_all_templates() template_store = [[template, ""] for template in all_templates] rsc_refs = all_real_rsc[:] rsc_refs.extend(all_templates) rsc_refs_store = [[rsc, ""] for rsc in rsc_refs] if widgets.has_key("combo_entries") : for key in ["rsc", "with-rsc", "first", "then", "from", "to"] : if widgets["combo_entries"].has_key(key) : if self.obj_type == "rsc_location" : self.combobox_store_append(widgets["combo_entries"][key], rsc_store) else : self.combobox_store_append(widgets["combo_entries"][key], rsc_refs_store) if widgets["combo_entries"].has_key("id") and self.id_is_idref : self.combobox_store_append(widgets["combo_entries"]["id"], rsc_store) for key in ["template"] : if widgets["combo_entries"].has_key(key) : self.combobox_store_append(widgets["combo_entries"][key], template_store) for key in ["node"] : if widgets["combo_entries"].has_key(key) : self.combobox_store_append(widgets["combo_entries"][key], node_store) if widgets["combo_entries"].has_key("role-ref") : acl_roles = [] for acls in manager.xml_nodes["cib"].getElementsByTagName("acls") : for acl_role in acls.getElementsByTagName("acl_role") : acl_role_id = acl_role.getAttribute("id") if acl_role_id != "" and acl_roles.count(acl_role_id) == 0 : acl_roles.append(acl_role_id) acl_role_store = [[acl_role, ""] for acl_role in acl_roles] self.combobox_store_append(widgets["combo_entries"]["role-ref"], acl_role_store) role_attr_type = None if validate_type == "dtd" : try : op_dtd_elem = manager.get_dtd_elem("op") role_attr = op_dtd_elem.get_attr("role") role_attr_type = role_attr.get_type() except KeyError : pass if role_attr_type != None and type(role_attr_type) == list : roles = role_attr_type else : roles = ["Master", "Slave", "Started", "Stopped"] role_store = [[role, ""] for role in roles] if widgets.has_key("combo_entries") : for key in ["role", "from_role", "to_role"] : if widgets["combo_entries"].has_key(key) : self.combobox_store_append(widgets["combo_entries"][key], role_store) if validate_type != "dtd" : return scores = ["INFINITY", "-INFINITY"] score_store = [[score, ""] for score in scores] if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("score") : self.combobox_store_append(widgets["combo_entries"]["score"], score_store) def on_changed(self, widget) : if self.dynamic_layout != None : self.dynamic_layout(widget) if self.dynamic_choice != None and validate_type != "dtd" : self.dynamic_choice(widget) if self.dynamic_fill != None : self.dynamic_fill(widget) if self.dynamic_desc != None : desc = self.dynamic_desc(widget) if desc != None : self.show_desc(desc) self.save() def on_changed_later(self, widget) : if self.dynamic_layout != None : self.dynamic_layout(widget) if self.dynamic_choice != None and validate_type != "dtd" : self.dynamic_choice(widget) if self.dynamic_fill != None : self.dynamic_fill(widget) if self.dynamic_desc != None : desc = self.dynamic_desc(widget) if desc != None : self.show_desc(desc) if self.change_call_back != None : self.change_call_back() if self.dynamic_render != None : self.dynamic_render(widget) if self.dynamic_set_id != None : self.dynamic_set_id(widget) save_id = self.xml_node.getAttribute("id") if save_id != "" : self.save_id = save_id self.save() new_id = self.xml_node.getAttribute("id") if self.save_id != None and new_id != "" and new_id != self.save_id : self.auto_change_child_ids(self.xml_node, new_id) def auto_change_child_ids(self, xml_node, new_id) : for child_node in xml_node.childNodes : if child_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue id = child_node.getAttribute("id") if id.count(self.save_id + "-") > 0 : child_node.setAttribute("id", id.replace(self.save_id + "-", new_id + "-")) self.auto_change_child_ids(child_node, new_id) def dynamic_render(self, widget) : if widget in self.widgets.get("anyname_combo_entries", {}) : changed_attr_name = widget.get_text() if len(changed_attr_name) > 0 : need_add = True for name_widget in self.widgets["anyname_combo_entries"] : if name_widget.get_text() == "" : need_add = False break if need_add : (name_entry, widget) = self.render_anyname_widgets("") self.widgets["anyname_combo_entries"][name_entry] = widget name_entry.connect("changed", self.on_changed_later) widget.connect("changed", self.on_changed_later) def show_desc(self, desc) : widgets = self.widgets desc_vbox = self.desc_vbox if not widgets.has_key("desc_labels") : desc_labels = [] for row in range(len(desc)) : desc_label = gtk.Label(desc[row]) desc_label.set_alignment(0, 0.5) desc_label.set_padding(5, 0) desc_label.set_line_wrap(True) desc_label.set_selectable(True) desc_vbox.pack_start(desc_label, False, padding=2) desc_labels.append(desc_label) if desc_labels != [] : widgets["desc_labels"] = desc_labels else : for row in range(len(desc)) : widgets["desc_labels"][row].set_text(desc[row]) desc_vbox.show_all() def update(self, xml_node = None) : if xml_node != None : self.xml_node = xml_node object_attrs = {} for attr_name in self.attr_list : attr_value = self.xml_node.getAttribute(attr_name) if attr_value != None : object_attrs[attr_name] = attr_value self.show_values(object_attrs) def save(self) : object_attrs = self.get_values() for attr_name in object_attrs : self.xml_node.setAttribute(attr_name, object_attrs.get(attr_name , "")) for attr_name in self.xml_node.attributes.keys() : if object_attrs.get(attr_name) == None : self.xml_node.removeAttribute(attr_name) def save_status(self) : return self.optional_expander.get_expanded() def restore_status(self, saved_status) : self.optional_expander.set_expanded(saved_status) def get_score(self, score_str) : try : score = int(score_str) except : if score_str in ["INFINITY", "infinity", "+INFINITY", "+infinity"] : score = 1000000 elif score_str in ["-INFINITY", "-infinity"] : score = -1000000 else : score = 0 return score def dynamic_choice(self, widget) : widgets = self.widgets attr_rng_node_dict = self.attr_rng_node_dict attr_name = None for widget_type in widgets : if type(widgets[widget_type]) != dict : continue for key in widgets[widget_type] : if widgets[widget_type][key] == widget : attr_name = key break if attr_name == None : return attr_rng_nodes = attr_rng_node_dict.get(attr_name) if attr_rng_nodes == None : return object_attrs = self.get_values() ref_match_value_decl_nodes_list = [] ref_decl_nodes_list = [] for key in object_attrs : for attr_rng_node in attr_rng_node_dict.get(key, []) : decl_rng_nodes = manager.get_decl_rng_nodes(attr_rng_node) value_list = [] sub_rng_nodes = manager.sorted_sub_rng_nodes_by_node(*attr_rng_node[0]) for value_node in sub_rng_nodes.get("value", []) : value_list.append(value_node[0][1].childNodes[0].data) if object_attrs.get(key, "") in value_list : ref_match_value_decl_nodes_list.append(decl_rng_nodes) elif len(sub_rng_nodes.get("data", [])) > 0 or len(sub_rng_nodes.get("text", [])) > 0 : ref_decl_nodes_list.append(decl_rng_nodes) if len(ref_match_value_decl_nodes_list) > 0 : ref_decl_nodes_list = ref_match_value_decl_nodes_list ref_sorted_nodes = {} for decl_type in ["choice", "first_choice", "group", "first_group"] : ref_sorted_nodes[decl_type] = manager.get_sorted_decl_nodes(ref_decl_nodes_list, decl_type) match_value_decl_nodes_list = [] decl_nodes_list = [] for attr_rng_node in attr_rng_nodes : decl_rng_nodes = manager.get_decl_rng_nodes(attr_rng_node) if decl_rng_nodes.get("choice") == None : return if decl_rng_nodes.get("choice") in ref_sorted_nodes["choice"] and \ decl_rng_nodes.get("group") != None and \ len(ref_sorted_nodes["group"]) > 0 and \ decl_rng_nodes.get("group") not in ref_sorted_nodes["group"] : continue value_list = [] sub_rng_nodes = manager.sorted_sub_rng_nodes_by_node(*attr_rng_node[0]) for value_node in sub_rng_nodes.get("value", []) : value_list.append(value_node[0][1].childNodes[0].data) if object_attrs.get(attr_name, "") in value_list : match_value_decl_nodes_list.append(decl_rng_nodes) else : if len(sub_rng_nodes.get("data", [])) > 0 or len(sub_rng_nodes.get("text", [])) > 0 : decl_nodes_list.append(decl_rng_nodes) if len(match_value_decl_nodes_list) > 0 : decl_nodes_list = match_value_decl_nodes_list sorted_nodes = {} for decl_type in ["choice", "first_choice", "group", "first_group"] : sorted_nodes[decl_type] = manager.get_sorted_decl_nodes(decl_nodes_list, decl_type) friend_attrs = [] opposite_attrs = [] sub_opposite_attrs = [] for key in attr_rng_node_dict : if key == attr_name : continue match_value = False for attr_rng_node in attr_rng_node_dict[key] : decl_rng_nodes = manager.get_decl_rng_nodes(attr_rng_node) if decl_rng_nodes.get("choice") == None or \ decl_rng_nodes.get("choice") not in sorted_nodes["choice"] : continue value_list = [] sub_rng_nodes = manager.sorted_sub_rng_nodes_by_node(*attr_rng_node[0]) for value_node in sub_rng_nodes.get("value", []) : value_list.append(value_node[0][1].childNodes[0].data) if object_attrs.get(key, "") in value_list : if key in friend_attrs : friend_attrs.remove(key) if key in opposite_attrs : opposite_attrs.remove(key) if key in sub_opposite_attrs : sub_opposite_attrs.remove(key) match_value = True if len(sorted_nodes["group"]) == 0 : opposite_attrs.append(key) else : if decl_rng_nodes.get("group") not in sorted_nodes["group"] : if key not in opposite_attrs : opposite_attrs.append(key) elif decl_rng_nodes.get("first_choice") in sorted_nodes["first_choice"] and \ decl_rng_nodes.get("first_group") not in sorted_nodes["first_group"] : if key not in sub_opposite_attrs : sub_opposite_attrs.append(key) else : if key not in friend_attrs : friend_attrs.append(key) if match_value : break if len(opposite_attrs) == 0 and len(sub_opposite_attrs) == 0 and len(friend_attrs) == 0 : return if object_attrs.get(attr_name, "") == "" : friends_clean = True for key in friend_attrs : if object_attrs.get(key, "") != "" : friends_clean = False break if friends_clean : self.set_sensibility(opposite_attrs, True) self.set_sensibility(sub_opposite_attrs, True) else : self.set_sensibility(opposite_attrs, False) self.set_sensibility(sub_opposite_attrs, False) self.set_sensibility(friend_attrs, True) def dynamic_choice_elem(self) : elem_rng_node_dict = self.elem_rng_node_dict attr_rng_node_dict = self.attr_rng_node_dict object_attrs = self.get_values() ref_match_value_decl_nodes_list = [] ref_decl_nodes_list = [] for key in object_attrs : for attr_rng_node in attr_rng_node_dict.get(key, []) : decl_rng_nodes = manager.get_decl_rng_nodes(attr_rng_node) value_list = [] sub_rng_nodes = manager.sorted_sub_rng_nodes_by_node(*attr_rng_node[0]) for value_node in sub_rng_nodes.get("value", []) : value_list.append(value_node[0][1].childNodes[0].data) if object_attrs.get(key, "") in value_list : ref_match_value_decl_nodes_list.append(decl_rng_nodes) elif len(sub_rng_nodes.get("data", [])) > 0 or len(sub_rng_nodes.get("text", [])) > 0 : ref_decl_nodes_list.append(decl_rng_nodes) if len(ref_match_value_decl_nodes_list) > 0 : ref_decl_nodes_list = ref_match_value_decl_nodes_list ref_sorted_nodes = {} for decl_type in ["choice", "first_choice", "group", "first_group"] : ref_sorted_nodes[decl_type] = manager.get_sorted_decl_nodes(ref_decl_nodes_list, decl_type) elem_node_dict = {} for elem_node in self.xml_node.childNodes : if elem_node.nodeType != xml.dom.Node.ELEMENT_NODE : continue elem_type = elem_node.tagName if not elem_node_dict.has_key(elem_type) : elem_node_dict[elem_type] = [] elem_node_dict[elem_type].append(elem_node) decl_nodes_list = [] for key in elem_node_dict : for elem_rng_node in elem_rng_node_dict.get(key, []): if len(elem_node_dict[key]) > 1 and manager.find_decl(elem_rng_node, "oneOrMore") == 0 \ and manager.find_decl(elem_rng_node, "zeroOrMore") == 0 : continue decl_rng_nodes = manager.get_decl_rng_nodes(elem_rng_node) if decl_rng_nodes.get("choice") == None : return if decl_rng_nodes.get("choice") in ref_sorted_nodes["choice"] and \ decl_rng_nodes.get("group") != None and \ len(ref_sorted_nodes["group"]) > 0 and \ decl_rng_nodes.get("group") not in ref_sorted_nodes["group"] : continue decl_nodes_list.append(decl_rng_nodes) sorted_nodes = {} for decl_type in ["choice", "first_choice", "group", "first_group"] : sorted_nodes[decl_type] = manager.get_sorted_decl_nodes(decl_nodes_list, decl_type) friend_attrs = [] opposite_attrs = [] sub_opposite_attrs = [] for key in attr_rng_node_dict : match_value = False for attr_rng_node in attr_rng_node_dict[key] : decl_rng_nodes = manager.get_decl_rng_nodes(attr_rng_node) if decl_rng_nodes.get("choice") == None or \ decl_rng_nodes.get("choice") not in sorted_nodes["choice"] : friend_attrs.append(key) continue value_list = [] sub_rng_nodes = manager.sorted_sub_rng_nodes_by_node(*attr_rng_node[0]) for value_node in sub_rng_nodes.get("value", []) : value_list.append(value_node[0][1].childNodes[0].data) if object_attrs.get(key, "") in value_list : if key in friend_attrs : friend_attrs.remove(key) if key in opposite_attrs : opposite_attrs.remove(key) if key in sub_opposite_attrs : sub_opposite_attrs.remove(key) match_value = True if len(sorted_nodes["group"]) == 0 : opposite_attrs.append(key) else : if decl_rng_nodes.get("group") not in sorted_nodes["group"] : if key not in opposite_attrs : opposite_attrs.append(key) elif decl_rng_nodes.get("first_choice") in sorted_nodes["first_choice"] and \ decl_rng_nodes.get("first_group") not in sorted_nodes["first_group"] : if key not in sub_opposite_attrs : sub_opposite_attrs.append(key) else : if key not in friend_attrs : friend_attrs.append(key) if match_value : break if len(opposite_attrs) == 0 and len(sub_opposite_attrs) == 0 and len(friend_attrs) == 0 : return self.set_sensibility(opposite_attrs, False) self.set_sensibility(sub_opposite_attrs, False) self.set_sensibility(friend_attrs, True) def set_sensibility(self, keys, sensibility) : widgets = self.widgets for widget_type in widgets : if type(widgets[widget_type]) != dict : continue for key in widgets[widget_type] : if key in keys : widgets[widget_type][key].set_sensitive(sensibility) def set_id_widget(self, id) : widgets = self.widgets if self.is_newobj : if widgets.get("combo_entries", {}).has_key("id") : widgets["combo_entries"]["id"].child.set_text(id) else : if widgets.get("value_labels", {}).has_key("id") : widgets["value_labels"]["id"].set_text(id) def hide_id_widget(self) : widgets = self.widgets if widgets.get("name_labels", {}).has_key("id") : widgets["name_labels"]["id"].hide_all() if self.is_newobj : if widgets.get("combo_entries", {}).has_key("id") : widgets["combo_entries"]["id"].hide_all() else : if widgets.get("value_labels", {}).has_key("id") : widgets["value_labels"]["id"].hide_all() def dynamic_set_id_auto(self, widget) : key_attrs = ["name", "attribute"] widgets = self.widgets if not widgets.has_key("combo_entries") : return if widget not in [widgets["combo_entries"].get(attr) for attr in key_attrs] : return object_attrs = self.get_values() for attr in key_attrs : name = object_attrs.get(attr, "") if name != "" : break if name == "" : name = self.obj_type new_id = manager.auto_unique_id(self.xml_node, name) self.set_id_widget(new_id) class Primitive(ObjectAttrs) : def dynamic_fill(self, widget) : widgets = self.widgets primitive = self.get_values() primitive_class = primitive.get("class", "") if primitive_class == "" : return if widgets.has_key("combos") and widgets["combos"].has_key("class") \ and widget == widgets["combos"]["class"] : ra_list = manager.get_rsc_types(primitive_class) self.fill_provider(primitive, ra_list) self.fill_type(primitive, ra_list) elif widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("provider") \ and widget == widgets["combo_entries"]["provider"] : ra_list = manager.get_rsc_types(primitive_class) self.fill_type(primitive, ra_list) def fill_provider(self, primitive, ra_list = None) : widgets = self.widgets primitive_class = primitive.get("class", "") provider_list = [] if primitive_class == "ocf" and ra_list != None : for ra in ra_list : providers = manager.get_rsc_providers(primitive_class, ra) for provider in providers : if provider_list.count(provider) == 0 : provider_list.append(provider) providers_store = [[provider, ""] for provider in provider_list] if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("provider") : self.combobox_store_append(widgets["combo_entries"]["provider"], providers_store) # if provider_list != None and len(provider_list) > 0 : # widgets["combo_entries"]["provider"].child.set_text(provider_list[0]) def fill_type(self, primitive, ra_list = None) : widgets = self.widgets primitive_class = primitive.get("class", "") primitive_provider = primitive.get("provider", "") if ra_list != None : ra_list.sort() if primitive_class != "ocf" or primitive_provider == "" : type_store = [[ra, ""] for ra in ra_list] else : type_store = [] for ra in ra_list : provider_list = manager.get_rsc_providers(primitive_class, ra) if provider_list != None and primitive_provider in provider_list : type_store.append([ra, ""]) if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("type") : self.combobox_store_append(widgets["combo_entries"]["type"], type_store) def dynamic_desc(self, widget) : widgets = self.widgets desc = None if widgets.has_key("combos") and widgets["combos"].has_key("class") \ and widget == widgets["combos"]["class"] : desc = self.get_meta_desc() if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("type") \ and widget == widgets["combo_entries"]["type"] : desc = self.get_meta_desc() if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("provider") \ and widget == widgets["combo_entries"]["provider"] : desc = self.get_meta_desc() if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("template") \ and widget == widgets["combo_entries"]["template"] : desc = self.get_meta_desc() return desc def get_meta_desc(self) : primitive = self.get_values() primitive_template = primitive.get("template") title = "" if not primitive_template : primitive_class = primitive.get("class", "") primitive_type = primitive.get("type", "") primitive_provider = primitive.get("provider", "heartbeat") else : template_node = manager.get_template(primitive_template) if template_node == None : return [""] primitive_attrs = manager.get_rsc_attrs(template_node, ["class", "type", "provider"]) primitive_class = str(primitive_attrs.get("class", "")) primitive_type = str(primitive_attrs.get("type", "")) primitive_provider = str(primitive_attrs.get("provider", "heartbeat")) title = "%s:%s:%s\n\n"%(primitive_class, primitive_provider, primitive_type) meta = manager.get_rsc_meta(primitive_class, primitive_type, primitive_provider) if meta == None : return [""] longdesc = meta.longdesc if longdesc == None : longdesc = "" else : longdesc = longdesc.replace(_(". "), _(".\n")) shortdesc = meta.shortdesc if shortdesc == None : shortdesc = "" if len(longdesc) == 0 : desc = [title + shortdesc] elif longdesc.find(shortdesc) > -1 : desc = [title + longdesc] else : if shortdesc.endswith(_(".")) : desc = [title + shortdesc + "\n" + longdesc] else : desc = [title + shortdesc + _(".") + "\n" + longdesc] return desc def verify_values(self) : if not ObjectAttrs.verify_values(self) : return False primitive = self.get_values() if primitive.get("template", "") == "" and primitive.get("class", "") == "" : msgbox(_("\"%s\" or \"%s\" is required")%(_("Class"), _("Template"))) return False if primitive.get("class", "") == "ocf" and primitive.get("provider", "") == "" : msgbox(_("\"%s\" is required")%_("Provider") + " " + _("for an OCF primitive")) return False return True class MetaAttrsNV(ObjectAttrs) : def __init__(self, xml_node, is_newobj = False, change_call_back = None) : common_options = [ ("priority", [], _("If not all resources can be active, the cluster will stop lower priority resources in order to keep higher priority ones active.")), ("target-role", [["Started", _("[ default ]")], ["Stopped", ""]], _("What state should the cluster attempt to keep this resource in?")), ("is-managed", [["true", _("[ default ]")], ["false", ""]], _("Is the cluster allowed to start and stop the resource?")) ] primitive_options = [ ("resource-stickiness", [], _("How much does the resource prefer to stay where it is? Defaults to the value of \"default-resource-stickiness\"")), ("migration-threshold", [], _("How many failures should occur for this resource on a node before making the node ineligible to host this resource. Default: \"none\"")), ("multiple-active", [["stop_start", _("[ default ]")], ["stop_only", ""], ["block", _("(mark the resource as unmanaged)")]], _("What should the cluster do if it ever finds the resource active on more than one node.")), ("failure-timeout", [], _("How many seconds to wait before acting as if the failure had not occurred (and potentially allowing the resource back to the node on which it failed. Default: \"never\"")), ("allow-migrate", [["false", _("[ default ]")], ["true", ""]], _("Allow resource migration for resources which support migrate_to/migrate_from actions")) ] clone_basic_options = [ ("clone-max", [], _("How many copies of the resource to start. Defaults to the number of nodes in the cluster.")), ("clone-node-max", [["1", _("[ default ]")]], _("How many copies of the resource can be started on a single node.")), ] clone_other_options = [ ("notify", [["false", _("[ default ]")], ["true", ""]], _("When stopping or starting a copy of the clone, tell all the other copies beforehand and when the action was successful.")), ("globally-unique", [["false", _("[ default ]")], ["true", ""]], _("Does each copy of the clone perform a different function?")), ("ordered", [["false", _("[ default ]")], ["true", ""]], _("Should the copies be started in series (instead of in parallel)")), ("interleave", [["false", _("[ default ]")], ["true", ""]], _("Changes the behavior of ordering constraints (between clones/masters) so that instances can start/stop as soon as their peer instance has (rather than waiting for every instance of the other clone has).")) ] master_basic_options = [ ("master-max", [["1", _("[ default ]")]], _("How many copies of the resource can be promoted to master status.")), ("master-node-max", [["1", _("[ default ]")]], _("How many copies of the resource can be promoted to master status on a single node.")) ] self.meta_attributes_options = { "primitive": common_options + primitive_options, "template": common_options + primitive_options, "group": common_options, "clone": common_options + clone_basic_options + clone_other_options, "master": common_options + clone_basic_options + master_basic_options + clone_other_options, "rsc_defaults": common_options + primitive_options, } if validate_type == "dtd" : self.target_node = xml_node.parentNode.parentNode.parentNode self.target_type = self.target_node.tagName self.target_dtd_elem = manager.get_dtd_elem(self.target_type) self.target_attrlist = self.target_dtd_elem.get_attr_list() self.auto_fill = self.auto_fill_dtd self.dynamic_fill = self.dynamic_fill_dtd else : self.target_node = xml_node.parentNode.parentNode self.target_type = self.target_node.tagName self.auto_fill = self.auto_fill_rng self.dynamic_fill = self.dynamic_fill_rng self.dynamic_desc = self.dynamic_desc_rng ObjectAttrs.__init__(self, xml_node, is_newobj, change_call_back) def auto_fill_rng(self) : widgets = self.widgets name_store = [[option[0], ""] for option in self.meta_attributes_options.get(self.target_type, [])] if widgets.get("combo_entries", {}).has_key("name") : self.combobox_store_append(widgets["combo_entries"]["name"], name_store) def dynamic_fill_rng(self, widget) : widgets = self.widgets if widgets.get("combo_entries", {}).has_key("name") \ and widget == widgets["combo_entries"]["name"] : value_store = [] nvpair = self.get_values() if nvpair.has_key("name") : options = self.meta_attributes_options.get(self.target_type, []) for i in range(len(options)) : if options[i][0] == nvpair["name"] : value_store = options[i][1] break if widgets.get("combo_entries", {}).has_key("value") : self.combobox_store_append(widgets["combo_entries"]["value"], value_store) def dynamic_desc_rng(self, widget) : widgets = self.widgets if widgets.get("combo_entries", {}).get("name") != widget : return None desc = [""] nvpair = self.get_values() if nvpair.has_key("name") : options = self.meta_attributes_options.get(self.target_type, []) for i in range(len(options)) : if options[i][0] == nvpair["name"] : desc = [options[i][2]] break return desc def auto_fill_dtd(self) : widgets = self.widgets attr_store = [] if self.target_type in ["primitive", "template", "group", "clone", "master_slave"] : attr_store.append(["target_role", ""]) for attr_name in self.target_attrlist : attr = self.target_dtd_elem.get_attr(attr_name) if attr.get_decl() != "#REQUIRED" : attr_store.append([attr_name, ""]) if self.target_type in ["clone", "master_slave"] : attr_store.extend([attr_name, ""] for attr_name in ["clone_max", "clone_node_max"]) if self.target_type == "master_slave" : attr_store.extend([attr_name, ""] for attr_name in ["master_max", "master_node_max"]) if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("name") : self.combobox_store_append(widgets["combo_entries"]["name"], attr_store) def dynamic_fill_dtd(self, widget) : widgets = self.widgets options_dict = {"target_role": ["started", "stopped", "default"]} if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("name") \ and widget == widgets["combo_entries"]["name"] : metaattr = self.get_values() attr_name = metaattr.get("name", None) if attr_name == None : return value_store = [] if attr_name in self.target_attrlist : attr = self.target_dtd_elem.get_attr(attr_name) attr_type = attr.get_type() attr_default = attr.get_default() if type(attr_type) == list : if attr_type.count("true") > 0 and attr_type.count("false") > 0 : options = ("true", "false") else : options = attr_type for option in options : if attr_default != None and option == attr_default : value_store.append([attr_default, "[ " + _("default") + " ]"]) else : value_store.append([option, ""]) elif attr_default != None : value_store.append([attr_default, "["+_("default")+"]"]) elif attr_name in options_dict.keys() : value_store.extend([attr_value, ""] for attr_value in options_dict[attr_name]) if self.target_node.parentNode.tagName == "clone" : value_store.extend([attr_value, ""] for attr_value in ["master", "slave"]) if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("value") : self.combobox_store_append(widgets["combo_entries"]["value"], value_store) class MetaNV(ObjectAttrs) : meta = None def auto_fill(self) : widgets = self.widgets meta = self.meta if meta != None : instattr_store = [] for param in meta.parameters : param_attr = "" if param.get("required", None) == "1" : param_attr = param_attr + _("required") if param.get("unique", None) == "1" : if param_attr != "" : param_attr = param_attr + _(", ") param_attr = param_attr + _("unique") if param_attr != "" : param_attr = "[ "+ param_attr + " ]" instattr_store.append([param["name"], param_attr]) if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("name") : self.combobox_store_append(widgets["combo_entries"]["name"], instattr_store) def dynamic_fill(self, widget) : widgets = self.widgets meta = self.meta if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("name") \ and widget == widgets["combo_entries"]["name"] \ and meta != None : instattr = self.get_values() value_store = [] if instattr.has_key("name") : for param in meta.parameters : if instattr["name"] == param["name"] : param_type = param["content"].get("type") options = [] default_value = param["content"]["default"] if param_type == "boolean" : boolean_values = [["true", "false"], ["yes", "no"], ["1", "0"]] if default_value : options = None for value_pair in boolean_values : if default_value in value_pair : options = value_pair break if options == None : options = [default_value] else : options = boolean_values[0] elif param_type == "enum" and param["content"].has_key("values"): options = param["content"]["values"] elif default_value != None : options = [default_value] for option in options : if default_value != None and option == default_value : value_store.insert(0, [option, "[ "+ _("default") + " ]"]) else : value_store.append([option, ""]) break if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("value") : self.combobox_store_append(widgets["combo_entries"]["value"], value_store) def dynamic_desc(self, widget) : widgets = self.widgets meta = self.meta if meta == None or not widgets.has_key("combo_entries") \ or widget != widgets["combo_entries"].get("name") : return None desc = [""] instattr = self.get_values() if instattr.has_key("name") : for param in meta.parameters : if instattr["name"] == param["name"] : longdesc = param.get("longdesc", "").replace(_(". "), _(".\n")) shortdesc = param.get("shortdesc", "") if len(longdesc) == 0 : desc = [shortdesc] elif longdesc.find(shortdesc) > -1 : desc = [longdesc] else : if shortdesc.endswith(_(".")) : desc = [shortdesc + "\n" + longdesc] else : desc = [shortdesc + _(".") + "\n" + longdesc] break return desc class CRMConfNV(MetaNV) : meta = None def __init__(self, xml_node, is_newobj = False, change_call_back = None) : self.meta = manager.get_crm_metadata("pengine") crmd_meta = manager.get_crm_metadata("crmd") if self.meta != None : if crmd_meta != None: self.meta.parameters.extend(crmd_meta.parameters) params = {} for param in self.meta.parameters : params[param["name"]] = param param_names = params.keys() param_names.sort() self.meta.parameters = [] for param_name in param_names : self.meta.parameters.append(params[param_name]) else : self.meta = crmd_meta MetaNV.__init__(self, xml_node, is_newobj, change_call_back) class PrimInstAttrsNV(MetaNV) : meta = None def __init__(self, xml_node, is_newobj = False, change_call_back = None) : if validate_type == "dtd" : primitive_node = xml_node.parentNode.parentNode.parentNode else : primitive_node = xml_node.parentNode.parentNode primitive_attrs = manager.get_rsc_attrs(primitive_node, ["class", "type", "provider"]) primitive_class = str(primitive_attrs.get("class", "")) primitive_type = str(primitive_attrs.get("type", "")) primitive_provider = str(primitive_attrs.get("provider", "")) self.meta = manager.get_rsc_meta(primitive_class, primitive_type, primitive_provider) MetaNV.__init__(self, xml_node, is_newobj, change_call_back) class OPInstAttrsNV(ObjectAttrs) : def auto_fill(self) : widgets = self.widgets name_store = [["OCF_CHECK_LEVEL", ""]] if widgets.get("combo_entries", {}).has_key("name") : self.combobox_store_append(widgets["combo_entries"]["name"], name_store) class UtilizationNV(ObjectAttrs) : def auto_fill(self) : widgets = self.widgets utilization_names = ["cpu", "memory"] name_store = [[name, ""] for name in utilization_names] if widgets.get("combo_entries", {}).has_key("name") : self.combobox_store_append(widgets["combo_entries"]["name"], name_store) class InstAttrsNV(ObjectAttrs) : def __init__(self, xml_node, is_newobj = False, change_call_back = None) : self.attributes_options = { "node": [ ("standby", [["false", "[ default ]"], ["true", ""]]), ("cpu_mips", []) ] } if validate_type == "dtd" : self.target_node = xml_node.parentNode.parentNode.parentNode self.target_type = self.target_node.tagName else : self.target_node = xml_node.parentNode.parentNode self.target_type = self.target_node.tagName ObjectAttrs.__init__(self, xml_node, is_newobj, change_call_back) def auto_fill(self) : widgets = self.widgets name_store = [[option[0], ""] for option in self.attributes_options.get(self.target_type, [])] if widgets.get("combo_entries", {}).has_key("name") : self.combobox_store_append(widgets["combo_entries"]["name"], name_store) def dynamic_fill(self, widget) : widgets = self.widgets if widgets.get("combo_entries", {}).has_key("name") \ and widget == widgets["combo_entries"]["name"] : value_store = [] nvpair = self.get_values() if nvpair.has_key("name") : options = self.attributes_options.get(self.target_type, []) for i in range(len(options)) : if options[i][0] == nvpair["name"] : value_store = options[i][1] break if widgets.get("combo_entries", {}).has_key("value") : self.combobox_store_append(widgets["combo_entries"]["value"], value_store) class OPDefaultsNV(ObjectAttrs) : def __init__(self, xml_node, is_newobj = False, change_call_back = None) : self.op_attr_rng_nodes = {} self.op_attr_list = [] sorted_rng_nodes = manager.sorted_sub_rng_nodes_by_name("op") if sorted_rng_nodes != None : attr_rng_nodes = sorted_rng_nodes.get("attribute", []) for rng_node in attr_rng_nodes : name = rng_node[0][1].getAttribute("name") if name in ["id", "name", "description"] : continue if not self.op_attr_rng_nodes.has_key(name) : self.op_attr_rng_nodes[name] = [] self.op_attr_list.append(name) self.op_attr_rng_nodes[name].append(rng_node) ObjectAttrs.__init__(self, xml_node, is_newobj, change_call_back) def auto_fill(self) : widgets = self.widgets name_store = [[name, ""] for name in self.op_attr_list] if widgets.get("combo_entries", {}).has_key("name") : self.combobox_store_append(widgets["combo_entries"]["name"], name_store) def dynamic_fill(self, widget) : widgets = self.widgets if widgets.get("combo_entries", {}).has_key("name") \ and widget == widgets["combo_entries"]["name"] : nvpair = self.get_values() if nvpair.has_key("name") : value_store = [] for attr_rng_node in self.op_attr_rng_nodes.get(nvpair["name"], []): sub_rng_nodes = manager.sorted_sub_rng_nodes_by_node(*attr_rng_node[0]) if len(sub_rng_nodes.get("value",[])) > 0 : for value_node in sub_rng_nodes["value"] : value_store.append([value_node[0][1].childNodes[0].data, ""]) for sub_rng_node in sub_rng_nodes.get("data", []) : if sub_rng_nodes["data"][0][0][1].getAttribute("type") == "boolean" : for option in ("true", "false") : value_store.append([option, ""]) if widgets.get("combo_entries", {}).has_key("value") : self.combobox_store_append(widgets["combo_entries"]["value"], value_store) class Expression(ObjectAttrs) : def __init__(self, xml_node, is_newobj = False, change_call_back = None) : ObjectAttrs.__init__(self, xml_node, is_newobj, change_call_back) def auto_fill(self) : widgets = self.widgets attr_names = ["#uname","#id", "#is_dc"] attr_store = [[attr_name, ""] for attr_name in attr_names] if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("attribute") : self.combobox_store_append(widgets["combo_entries"]["attribute"], attr_store) def dynamic_fill(self, widget) : widgets = self.widgets if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("attribute") \ and widget == widgets["combo_entries"]["attribute"] : expr = self.get_values() value_store = [] if expr.has_key("attribute") : if expr["attribute"] == "#uname" : value_store = [[node, ""] for node in manager.get_normal_nodes()] elif expr["attribute"] == "#is_dc" : value_store = [[boolean_val, ""] for boolean_val in ["true", "false"]] if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("value") : self.combobox_store_append(widgets["combo_entries"]["value"], value_store) class OP(ObjectAttrs) : def __init__(self, xml_node, is_newobj = False, change_call_back = None) : if mode_level == 0 : self.dynamic_layout = self.dynamic_layout_simple primitive_node = xml_node.parentNode.parentNode primitive_attrs = manager.get_rsc_attrs(primitive_node, ["class", "type", "provider"]) primitive_class = str(primitive_attrs.get("class", "")) primitive_type = str(primitive_attrs.get("type", "")) primitive_provider = str(primitive_attrs.get("provider", "")) meta = manager.get_rsc_meta(primitive_class, primitive_type, primitive_provider) self.meta = meta ObjectAttrs.__init__(self, xml_node, is_newobj, change_call_back) self.dynamic_fill = self.dynamic_fill_later def auto_fill(self) : widgets = self.widgets meta = self.meta actions = ["start", "stop", "reload", "monitor", "status", "migrate_from", "migrate_to", "promote", "demote"] op_names = [] if meta != None : for action in meta.actions : if action["name"] not in op_names : op_names.append(action["name"]) else : op_names = actions op_name_store = [[op_name, ""] for op_name in op_names] if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("name") : self.combobox_store_append(widgets["combo_entries"]["name"], op_name_store) def dynamic_fill_later(self, widget) : widgets = self.widgets meta = self.meta if meta == None or not widgets.has_key("combo_entries") : return elif widget != widgets["combo_entries"].get("name") : if not widgets.has_key("combos") : return elif widget != widgets["combos"].get("role") : return op = self.get_values() if op.has_key("name") : if validate_type == "dtd" : default_role = manager.get_dtd_elem("op").get_attr("role").get_default() else : default_role = None for action in meta.actions : if action["name"] == op["name"] : if action.get("role") == op.get("role") \ or ( action.get("role") == None and op.get("role") == default_role ) \ or ( action.get("role") == default_role and op.get("role") == None) : for attr_name in widgets["combo_entries"].keys() : if attr_name != "id" and attr_name != "name" and attr_name != "role": attr_store = [] if attr_name == "start_delay" and action.has_key("start-delay") : action["start_delay"] = action["start-delay"] if action.has_key(attr_name) : attr_store.append([action[attr_name], ""]) self.combobox_store_append(widgets["combo_entries"][attr_name], attr_store) widgets["combo_entries"][attr_name].child.set_text(action.get(attr_name, "")) break if op["name"] != "monitor" and widgets["combo_entries"].has_key("interval") \ and widgets["combo_entries"]["interval"].get_property("sensitive") \ and widgets["combo_entries"]["interval"].child.get_text() == "" : is_required = False for child_widget in self.required_vbox.get_children() : if type(child_widget) == gtk.HBox \ and widgets["combo_entries"]["interval"] in child_widget.get_children() : is_required = True break if is_required or mode_level == 0 : widgets["combo_entries"]["interval"].child.set_text("0") else : for attr_name in widgets["combo_entries"].keys() : if attr_name != "name" : self.combobox_store_append(widgets["combo_entries"][attr_name], []) widgets["combo_entries"][attr_name].child.set_text("") def dynamic_layout_simple(self, widget) : widgets = self.widgets required_vbox = self.required_vbox optional_vbox = self.optional_vbox if not widgets.has_key("combo_entries") : return elif widget != widgets["combo_entries"].get("name") : return op = self.get_values() if op.get("name", "") in ["", "monitor"] : required_attrs = ["id", "name", "interval", "timeout"] else : required_attrs = ["id", "name", "timeout"] for vbox in [required_vbox, optional_vbox] : for child in vbox.get_children() : vbox.remove(child) for attr_name in self.attr_list : if attr_name in required_attrs : required_vbox.pack_start(self.hboxes[attr_name], False, padding=2) else : optional_vbox.pack_start(self.hboxes[attr_name], False, padding=2) required_vbox.show_all() optional_vbox.show_all() if mode_level == 0 : self.hide_id_widget() top_window.set_focus(widgets["combo_entries"]["name"].child) def verify_values(self) : if not ObjectAttrs.verify_values(self) : return False time_attrs = ["interval", "timeout"] if validate_type == "dtd" : time_attrs.append("start_delay") else : time_attrs.append("start-delay") op = self.get_values() for time_attr in time_attrs : if op.get(time_attr, "") != "" : (is_valid, error_msg) = is_valid_time(op[time_attr]) if not is_valid : msgbox(_("Invalid \"%s\"")%(_(name_cap(time_attr))) + _(":") + "\n" + error_msg) return False return True def dynamic_set_id(self, widget) : widgets = self.widgets if mode_level != 0 or not widgets.has_key("combo_entries") : return if widget not in [widgets["combo_entries"].get("name"), widgets["combo_entries"].get("interval")] : if not widgets.has_key("combos") : return if widget != widgets["combos"].get("role") : return op = self.get_values() primitive_id = self.xml_node.parentNode.parentNode.getAttribute("id") op_id = primitive_id + "-op" name = op.get("name", "") if name != "" : op_id += "-" + name role = op.get("role", "") if role != "" : op_id += "-" + role interval = op.get("interval", "") if interval != "" : op_id += "-" + interval new_id = manager.get_unique_id(op_id, self.xml_node) self.set_id_widget(new_id) class RscOrder(ObjectAttrs) : def __init__(self, xml_node, is_newobj = False, change_call_back = None) : if validate_type == "dtd" : self.dynamic_fill = self.dynamic_fill_dtd self.dynamic_desc = self.dynamic_desc_dtd else : self.dynamic_desc = self.dynamic_desc_rng ObjectAttrs.__init__(self, xml_node, is_newobj, change_call_back) def dynamic_fill_dtd(self, widget) : widgets = self.widgets if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("from") \ and widget == widgets["combo_entries"]["from"] : key_pair = ["from", "action"] elif widgets.has_key("combo_entries") and widgets["combo_entries"].has_key("to") \ and widget == widgets["combo_entries"]["to"] : key_pair = ["to", "to_action"] else : return object = self.get_values() actions_list = ["start", "stop", "reload", "monitor", "status", "migrate_from", "migrate_to", "promote", "demote"] actions = actions_list if object.has_key(key_pair[0]) : rsc_info = manager.get_rsc_info(object[key_pair[0]]) if rsc_info != None : meta = manager.get_rsc_meta(*rsc_info) if meta != None : actions = [] for f in meta.actions : if not f["name"] in actions : actions.append(f["name"]) action_store = [[action, ""] for action in actions] if widgets.has_key("combo_entries") and widgets["combo_entries"].has_key(key_pair[1]) : self.combobox_store_append(widgets["combo_entries"][key_pair[1]], action_store) def dynamic_desc_dtd(self, widget) : dtd_elem = self.dtd_elem order = self.get_values() for attr_name in dtd_elem.get_attr_list() : attr = dtd_elem.get_attr(attr_name) if not order.has_key(attr_name) : if attr_name != "id" and attr.get_decl() == "#REQUIRED" : return [_("* Specify dependencies between the actions on two resources"), _("* Please set the required attributes"), "", ""] order[attr_name] = attr.get_default() if order[attr_name] == None : order[attr_name] = "" desc = [] desc.append(_("* %s %s %s %s %s") %(order["action"].capitalize(), order["from"], order["type"], order["to_action"], order["to"])) if order["score"] == "INFINITY" or order["score"] == "infinity": if order["type"] == "before" : desc.append(_("* If cannot %s %s, do not %s %s") %(order["action"], order["from"], order["to_action"], order["to"])) else : desc.append(_("* If cannot %s %s, do not %s %s") %(order["to_action"], order["to"], order["action"], order["from"])) else : desc.append("") action = self.invert_action(order["action"]) to_action = self.invert_action(order["to_action"]) if order["symmetrical"] == "true" and action != None and to_action != None : desc.append(_("* %s %s %s %s %s") %(to_action.capitalize(), order["to"], order["type"], action, order["from"])) if order["score"] == "INFINITY" or order["score"] == "infinity": if order["type"] == "before" : desc.append(_("* If cannot %s %s, do not %s %s") %(to_action, order["to"], action, order["from"])) else : desc.append(_("* If cannot %s %s, do not %s %s") %(action, order["from"], to_action, order["to"])) else: desc.append("") else : desc.append("") desc.append("") return desc def invert_action(self, action) : if action == "start" : return "stop" elif action == "stop" : return "start" elif action == "promote" : return "demote" elif action == "demote" : return "promote" elif action == "promoted" : return "demoted" elif action == "demoted" : return "promoted" if action == "started" : return "stopped" elif action == "stopped" : return "started" else : return None def dynamic_desc_rng(self, widget) : attr_list = self.attr_list order = self.get_values() for attr_name in self.attr_list : if attr_name in ["first", "then"] and not order.has_key(attr_name) : return [_("* Specify the order of actions on resources"), _("* Please set the required attributes or add resource sets"), "", ""] if order.get(attr_name) == None : if attr_name in ["first-action", "then-action"] : order[attr_name] = "start" elif attr_name == "score" : order[attr_name] = "INFINITY" elif attr_name == "symmetrical" : order[attr_name] = "true" else : order[attr_name] = "" desc = [] desc.append(_("* %s %s before %s %s") %(order["first-action"].capitalize(), order["first"], order["then-action"], order["then"])) score = self.get_score(order["score"]) if score > 0 : desc.append(_("* If cannot %s %s, do not %s %s") %(order["first-action"], order["first"], order["then-action"], order["then"])) else : desc.append("") first_action = self.invert_action(order["first-action"]) then_action = self.invert_action(order["then-action"]) if order["symmetrical"] == "true" and first_action != None and then_action != None : desc.append(_("* %s %s before %s %s") %(then_action.capitalize(), order["then"], first_action, order["first"])) if score > 0 : desc.append(_("* If cannot %s %s, do not %s %s") %(then_action, order["then"], first_action, order["first"])) else: desc.append("") else : desc.append("") desc.append("") return desc class RscColocation(ObjectAttrs) : def __init__(self, xml_node, is_newobj = False, change_call_back = None) : if validate_type == "dtd" : self.dynamic_desc = self.dynamic_desc_dtd else : self.dynamic_desc = self.dynamic_desc_rng ObjectAttrs.__init__(self, xml_node, is_newobj, change_call_back) def dynamic_desc_dtd(self, widget) : dtd_elem = self.dtd_elem colocation = self.get_values() for attr_name in dtd_elem.get_attr_list() : attr = dtd_elem.get_attr(attr_name) if not colocation.has_key(attr_name) : if attr_name != "id" and attr.get_decl() == "#REQUIRED" : return [_("* Specify where a resource should run relative to another resource"), _("* Please set the required attributes"), "", ""] colocation[attr_name] = attr.get_default() if colocation[attr_name] == None : colocation[attr_name] = "" desc = [] if colocation["score"] == "INFINITY" or colocation["score"] == "infinity" : desc.append(_("* Make %s %s on the same node as %s %s ( %s according to %s )") %(colocation["from"], colocation["from_role"], colocation["to"], colocation["to_role"], colocation["from"], colocation["to"])) desc.append(_("* If %s cannot be %s on any node, then %s won't be %s anywhere") %(colocation["to"], colocation["to_role"], colocation["from"], colocation["from_role"])) if colocation["symmetrical"] == "false" : desc.append(_("* If %s cannot be %s on any node, %s won't be affected") %(colocation["from"], colocation["from_role"], colocation["to"])) desc.append("") else : desc.append(_("* Make %s %s on the same node as %s %s ( %s according to %s )") %(colocation["to"], colocation["to_role"], colocation["from"], colocation["from_role"], colocation["to"], colocation["from"])) desc.append(_("* If %s cannot be %s on any node, then %s won't be %s anywhere") %(colocation["from"], colocation["from_role"], colocation["to"], colocation["to_role"])) elif colocation["score"] == "-INFINITY" or colocation["score"] == "-infinity" : desc.append(_("* Prevent %s from being %s on the same node as %s %s ( %s according to %s )") %(colocation["from"], colocation["from_role"], colocation["to"], colocation["to_role"], colocation["from"], colocation["to"])) desc.append(_("* If %s is %s on the only (or every) available node, then %s won't be %s anywhere") %(colocation["to"], colocation["to_role"], colocation["from"], colocation["from_role"])) if colocation["symmetrical"] == "false" : desc.append(_("* If %s is %s on the only (or every) available node, %s won't be affected") %(colocation["from"], colocation["from_role"], colocation["to"])) desc.append("") else : desc.append(_("* Prevent %s from being %s on the same node as %s %s ( %s according to %s )") %(colocation["to"], colocation["to_role"], colocation["from"], colocation["from_role"], colocation["to"], colocation["from"])) desc.append(_("* If %s is %s on the only (or every) available node, then %s won't be %s anywhere") %(colocation["from"], colocation["from_role"], colocation["to"], colocation["to_role"])) else : desc.append(_("* Combine this colocation score and the appropriate location scores to decide where to put the resources")) desc.append("") desc.append("") desc.append("") return desc def dynamic_desc_rng(self, widget) : attr_list = self.attr_list colocation = self.get_values() for attr_name in self.attr_list : if attr_name in ["rsc", "with-rsc"] and not colocation.has_key(attr_name) : return [_("* Specify where resources should run relative to other resources"), _("* Please set the required attributes or add resource sets"), ""] if colocation.get(attr_name) == None : colocation[attr_name] = "" desc = [] score = self.get_score(colocation["score"]) comb_tip = _("* Combine this \"Score\" and corresponding location scores to decide where to place %s") \ %colocation["rsc"] if score > 0 : if colocation["score"] in ["INFINITY", "infinity", "+INFINITY", "+infinity"] : desc.append(_("* Make %s %s on the same node as %s %s ( %s according to %s )") %(colocation["rsc"], colocation["rsc-role"], colocation["with-rsc"], colocation["with-rsc-role"], colocation["rsc"], colocation["with-rsc"])) desc.append(_("* If %s cannot be %s on any node, then %s won't be %s anywhere") %(colocation["with-rsc"], colocation["with-rsc-role"], colocation["rsc"], colocation["rsc-role"])) desc.append(_("* If %s cannot be %s on any node, %s won't be affected") %(colocation["rsc"], colocation["rsc-role"], colocation["with-rsc"])) else : desc.append(_("* Prefer to make %s %s on the same node as %s %s ( %s according to %s )") %(colocation["rsc"], colocation["rsc-role"], colocation["with-rsc"], colocation["with-rsc-role"], colocation["rsc"], colocation["with-rsc"])) desc.append(comb_tip) desc.append("") elif score < 0 : if colocation["score"] in ["-INFINITY", "-infinity"] : desc.append(_("* Prevent %s from being %s on the same node as %s %s ( %s according to %s )") %(colocation["rsc"], colocation["rsc-role"], colocation["with-rsc"], colocation["with-rsc-role"], colocation["rsc"], colocation["with-rsc"])) desc.append(_("* If %s is %s on the only (or every) available node, then %s won't be %s anywhere") %(colocation["with-rsc"], colocation["with-rsc-role"], colocation["rsc"], colocation["rsc-role"])) desc.append(_("* If %s is %s on the only (or every) available node, %s won't be affected") %(colocation["rsc"], colocation["rsc-role"], colocation["with-rsc"])) else : desc.append(_("* Prefer to prevent %s from being %s on the same node as %s %s ( %s according to %s )") %(colocation["rsc"], colocation["rsc-role"], colocation["with-rsc"], colocation["with-rsc-role"], colocation["rsc"], colocation["with-rsc"])) desc.append(comb_tip) desc.append("") else : desc.append(_("* Please specify a valid \"Score\" to determine the location relationship between %s and %s") %(colocation["rsc"], colocation["with-rsc"])) desc.append("") desc.append("") return desc if __name__ == '__main__' : try : gtk._gtk.init_check() except RuntimeError : print "Could not open display" sys.exit() except AttributeError : pass if not pygtk_newer(2, 4) : print "the pygtk 2.4 or newer is needed." sys.exit() gc.enable() syslog.openlog("haclient", 0, syslog.LOG_USER) locale.setlocale(locale.LC_ALL, '') gettext.bindtextdomain(app_name) gettext.textdomain(app_name) gettext.install(app_name,"/usr/share/locale",unicode=1) if "-v" in sys.argv : debug_level = 1 manager = Manager() window = MainWindow() top_window = window.win_widget manager.run() syslog.closelog() pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/login.png000066400000000000000000000005341211477743100233470ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞ pHYsÃÃÇo¨dIDATxœí—Ñ Â0ïÓóçñEJQÐÐ\n.¹¥ bAºN÷šÔzïV< €@ƒ ÁÐàh¾O˜õÕÐZF´ÖÜÙN€õßŸÇ PÔ5@ (Ý @½†K@6á×Ms'n"ßAR @€=³4 ƒ€ðDÔþßH  È&kÀŠ‹K%Àn‡T…dP~(+`fçvÄNPž~/“à,`õ³&ý”@1ñCß() Åþc6¼8X±ô.‹)Fà v;¶pUêÉ÷­|Δƒ€­FÀ Øy€CÀÐàhð4x< €@ƒ y.–?qF) IEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/logout.png000066400000000000000000000007101211477743100235440ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞ pHYsÃÃÇo¨dzIDATxœí—ÛŽƒ0 Dýéüyö‰*ÝbÇÎmlb¡QE!à9™\ R ,xhÁ @ ^ZðЂ€¼´~ÿ *«…64®ëš®p¨È¿¯ Èd2G' $€@H[ >À7Ûßë¦'*;¿A\€&6{I€Û°#ö­!M€7°¬x¹¶0W¨:À‰v)xpü*p,“ˆŠZQv‚Ów€ð `ļ‚_Œ™{Ÿ`m×°z®±zSzh«m H‹&Ì »¤À{œÙP¤b¥Þlõ43Œ û3Ψ&æ¯ðdØÚ¦°béÓ.‹Ý¨Í+Pu„ð‰Ø}Tç_÷U×B†@/€8C`ò$èÀ3½×þV.Ö^æÚÞóHOâÚ¶Ý,ù†Ì·<Ñ><€y©7-r`¶À(FÇô€p`p>€— ^ZðÐúÝM¤#üëê¡IEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/manage-resource.png000077500000000000000000000027211211477743100253170ustar00rootroot00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs × ×B(›xtIME×/E&H^IDATHǽ•kl“UÆŸsÞ÷¼[Ûsn“Q¶RlØ`‚AÁ€ (“›‚ƒ‰?y‰FÄ®ÐO^JÞ5ÆDMôƒ‰Q£1¢xë 7Çpˆ8dk·–­[·ÑuíÚ¾·sü@Yª©ôŸœO'y~çyÎyŸø‡L´©å,Ÿ×ŸVƒ·,ÉG)%­ÛžõnRƒÀ­Îø¼þÔ¿¨Á€ÌdBTš–Ù$Q©iå²;ÚN4FR#‹˜ÌvÚí¶{s¹ÜþmÏzï¿–À³¸UóèCØc¡’eÛìÙsäµMkJ(¥'\µu·Ü³Y¡„z r©Á€}Bj0`—eù,a†i¼ª0%øôÏHœsXÜ T–À K2ò¹Þzç­KÚr»Vïöç|7kÊVBœ[·5 f³áM÷Uèšv—Â|´ÿcö·w°goðàÆµZB¨$!íçΟëŽEe@`†ÓeÖ{f9\®DÏfA(EûÙSÚñö¶Þ`ø¼~s SÆÞ¦„z,Á]›×oª¨ª¸–B?„²ÑÞX‡nè-NαP‘Yóôši w.[i—Eb€ñÃAÁ-KPBã&·æù¼þ‘+ÍcŒmX¿j­âp”¡Ìî(Áƒ_f£c¯[Üjöyý¢ÈhX >î鵄}÷äš«ì×—M¦mÙŠÁDû U°Š_Ñq]7öi=šs”Ú`äòèê¼ zã½Wø¼~aqÞÜ—ˆwtvu 3¯!ŸÍዟ¾ÍYÜjòyýéq€Ïë7 ÓØO t& B)~»p>£FËÕÄ‹!ºi¶tFÃ*ÉÈeAá”Ð&5pöì ~j·Ù^¾h)SèåÔzúXQæÍÉä0à šŽÕ —8ê.ŸDéÑqçb‘§n«*/—¸¦ý뾑%Fn˜ˆ'¬È@¯A@ZǦe.ùõB‡úé·ÆFÒ£pÞPcXøôÖÕ8MÓ00šÍà—H‡‘7ôÅÛ·û6ßAÄâ<$§Ä´`é&æxŠ,7«ÁÀD}E˜$5×»o´ëé,˜ÉQ¦Ø¸LèÎB^¨ÁÀ$‰ÒÐò¹7Û$dC˜éñšê© ¥-Wƒ¨Á¡„¶4ÖÏ™SUQIFû0<2ϤJ;€{ M;^!dèÐéÖ›Üõb~™CÞp÷Fûƒ_?Õ}1z‡ üéCcTjžß8¯qémËKº·"–Ĺdÿ%JH€NgþTK ÀãµÕ/Ýân°—UW¢jÖLĺÂâ÷Hg.ë‘EËYËK§”—“Xk;Ɔ.áb&‰ó©Ä7ÛŸß±zÂ.ÚýŠ]ìž];¦åA à®r¢¼Î‰Ò)“P:e2¸i"—LalhƒçȦ†ÌamLŸV:É~:׸õ>¯¿çZmZÊ-ÎuÓ ]k“›[&•LÎgÒÈäspH çÈh9P0Bð[ªŸÆãýo$¦NÝ ãóϿʮTE±ƒRen÷ŒjçôiµG ¼ü»‹]õž_czÖÐȬò¤ÊR=ÞÖ‚×MSNôYªº{]òRr@@ºh‰â?š ‰t9|, §éZ´½?bĉÖ}Ÿ|æëJ šÝ©a3éù2úîÅödŸÆMkXËçGä +]‰¿F$ c…çËN´ýò°Ç3sÁûï}x6™LÊë×­Y×ÇùÜHw÷kߨ+Î|PU]if³¹Af!ÿsþu=Œdêæ/IEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/master-resource.png000066400000000000000000000012241211477743100253540ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞbKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÖ &¥ó;‚!IDATxÚí™1rƒ0E¿2>ž4)rÒáq›ˆŽ–ŒKJÆnÝÁ1<¦ñ„C¤Í˜›l.„$Œ³ªÅ"Þÿ»Z!ADXóxÁÊ` €0À` `cãóPA©¶˜¨¾AˆÅ6ôaõ®wHD€ÝV(PÎÛ ]l§ê[|¡q|߸) k¤h¼oQà¤]žøÁïüj€¯ :£~‚"èéwõà¯!”jlx¨¯JÜqDìXÅ‚-v´Õ– uØÆŠ;qp±¬Ð-Ýä~xú„­ÅijÃ6»°N°Æ¹Ç-U8=q+Üë‚°êOrèvAxõÇ räÊÕõMñæê€=J$ÊÞAýÞ–—ëZPQahp²¥Ö€ØÒ RÔºK}‰h¹EPŠ~L§~]À삪~õÅ¢˜]+ÿþYú“ ºF‚Ìùd7ãFÈà‚õ£–¾ :ÁùìÔÜ gv?Rª@$¤… Bª?Áa¨Ç*Ág@õ'Ðç‚d@õ'9wº@%(_Í&<€HH¤Â,߯€×½À‚jw¹"{‹\E;ÃixüZxߦ$êŽ+¢ét!â)P[Ý „‹ÏE0ô “‘;=×ø/~yæ·¸\‘1?#\©r´ø+‚œ €0À` €0°ðñäƒÉ¨NåÈÌIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/mgmtcmd.py.in000077500000000000000000000037231211477743100241460ustar00rootroot00000000000000#!@PYTHON@ ''' sample.py ''' __copyright__=''' Author: Huang Zhen Copyright (C) 2005 International Business Machines ''' # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. import sys sys.path.append("@LIBDIR@/heartbeat-gui") sys.path.append("@HA_DATADIR@/heartbeat-gui") from pymgmt import * from select import * import sys if __name__=="__main__" : server = "127.0.0.1" port = "5560" username = "hacluster" password = "hacluster" messages = [] skipthis=False args=sys.argv[1:] for i in range(0, len(args)) : if skipthis : skipthis=False continue elif args[i] == "-s" : skipthis=True server = args[i+1] elif args[i] == "-u" : skipthis=True username = args[i+1] elif args[i] == "-p" : skipthis=True password = args[i+1] elif args[i] == "-P" : skipthis=True port = args[i+1] elif args[i] == "-h" : print "usage : %s [-s server] [-u username] [-p password] [-P port] msg_type field1 ..." sys.exit() else : messages = args[i:] break if mgmt_connect(server,username,password,port) == -1: print "login failed" sys.exit() print "---------------------------" command = "" for i in messages: command = command + i +"\n" command = command[:-1] print mgmt_sendmsg(command) print "---------------------------" mgmt_disconnect() pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/mgmtdtest.c000066400000000000000000000033741211477743100237120ustar00rootroot00000000000000/* * Test client for Linux HA management daemon * * Author: Huang Zhen * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include int main (int argc, char* argv[]) { char* ret; int num; char** args; if(mgmt_connect("127.0.0.1", "hacluster","hacluster",NULL) != 0) { printf("can't conenct to mgmtd\n"); return 1; } ret = mgmt_sendmsg(MSG_ECHO"\nhello"); if (ret == NULL) { printf("can't process message\n"); return 1; } args = mgmt_msg_args(ret, &num); if (ret == NULL) { printf("can't parse the return message\n"); return 1; } if (num != 2) { printf("the return message has wrong field number\n"); return 1; } if (strncmp(args[0],"ok",strlen("ok")) != 0) { printf("the return message is not \"ok\"\n"); return 1; } if (strncmp(args[1],"hello",strlen("hello")) != 0) { printf("the echo string is not same as we sent\"ok\"\n"); return 1; } mgmt_del_args(args); mgmt_del_msg(ret); mgmt_disconnect(); return 0; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/node.png000066400000000000000000000015441211477743100231660ustar00rootroot00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYsHHFÉk> vpAgxL¥¦ÁIDATHǽ”O‹œEÆUõÎûŽ“Ý½Æì\LrD0àm!›†9ù-¼‘Á ‹ü½~Åâ!^’è^’àÕIœdþt¿ÝíáY×uÜU(ªºè~žîªî†ÿ2úýƒOCw=#g4³ÝîÍ»¯e{½~pÎ¥³Â9—z½~˜óf+ªj¼ûñ—<NNµõ­7øñ«OX­ÂªeˆüþrÂWÞÁLÈLg¶ŒOÂ×ßÞûS.;nb" AD0M J©„H@J R"¦Y| Žˆ)‘©¡ª¨¢†©¢&¨.O’R"¦Tù¸®€€Ú’\MV‰TBxñjÊ«‰g4ö¼»uO KRYbÊ4~ýmÊpäˆ)C$Ä„š­_"ÑJDDP5L2&£)SI@½¨b"„HRãú)AHà#_5]U) Ò’¼ ”Â_âXI j5¡†‘eJ-³ê©b¢ ‘RÂbCq[”™²µQðÓýœ;ÍÆÉfÊ7w;§"_§DÑ{¯çÏÐ{°èøBÀÌnÜù×~Óù@þnöÁýTÔ ò=zx8 !¼÷{Ý[·JÕí½fs{³Ó¹¾UÔsÉ󜢑Ójµ(9»ÚœK/S4r.Îü<ßÚ®æõ\:ë[­Öö¦÷þ}æõŽ1]mïî6cŒx_âœ#¸Ä`0à\±ÁÓgO ǰaÊŒßS/!›Í`&Ž“E‰ë:ˆŸ®G™ašDH) =r¬àgé}Ö¿.e®ë#„ §uaƒöëWB²e¡ÕØ9¨ß êÆÎAý¿NÛ•œë~»7"áÞk©–ßož®,–²UI¾ó‡ATéû‡*vP]&x1:Çð”þÜØñ†ùé ´&^WCue £ŸF(ݹ‹Ù¹Jb%¤—Òlß¶ƒ…ÅyÊ÷í'5>†ï{¼®VÆî<\YŠm)ªË@õádíoÊF?‰XÌÎÍ ”"½”FÁÂâ<¦a’#jG‰ÅJÖ8ì¼ìÛ'CñªÝ9>|Y¾K»ú`~Èõ)[K}/_ýiÐÛs÷Œ§n¿‹Tá»#OÜ:ûæñ½¯m×Z?†¥lÍKÕnöàSÀ¯hVlÌÑÍþká›%—º\K!ÔIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/record-pending.png000066400000000000000000000024331211477743100251370ustar00rootroot00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ÐIDATxÚµ–Kh”WÇßc&ß<㤘«q|Œ“dªÁ¦5” Fˆ´ˆtÑtS(Ô ëîÔ¥…RAi } –ÖTpQñŒ±&ÅGÒd45˜‡L&Ç™ùæûæ{u‘⦤.çÞ³8¿{8÷ð¿s&â¼_ s{Þ³{~³’ë dp4MclllE®®ë:MMMÛQ NÓÕÕÅ7PI’E¯×‹®ësu;²,cÛ6’$Q__Ͼ}û°m›ááaª««) ¬M@V^8ݼy'P¢¡9ŠÇë! `²$¢ë&6ÅW ½B¡XÆÔ º.œåèÑ£\¿~/>ÿ”ÇOžsòäÉ…”~@Y¸ÝnVEœ;ñ>¹ÅÓÉ´rÙ-¡5Lò³y ¥üècΜ9³0Å‹¶øLeY&—ÍñxðÁUÕØ†Å×çNàˆFÅÀ6Îþð-/ 9dQA]ŠE‚Á «W¯æðáÆAMMÍò€rA£TÐQñ¸½˜¦Mu ˆ·6€€ˆVPq»ä¹øª †n!Ë2ôöö …Èf³ËöîÝK"‘ÀÌgEÌŒŠÇãaÖeãñx$ LS‹3ëæê•›‚Ààà ›7Õp©ûµµµË,Ëâøñãø|>ÇADQ¤¦¦†r¹L]]ŽãÌ5NÑu‘‘îÝ»G(bum{öÈ:thy@"‘@×uFGGQ…óçÏsðàA¦§§éììdxxMÓ¨ªªÂï÷“Ëåðz½´´´púôiöïßO__Š¢¼€¯Ž9Âøø8©T UUéé顽½¡¡!Âá0ýýý(ŠÂää$UUU\¾|™P(D©TÂq¢Ñ(ÇŽ#™LÒÜÜL__ÀïÀ3`||œp8ŒeY¼xñ‚`0H2™$‹ÑÚÚJ$! ¢ø|>|>²,sñâEÚÚÚ˜šš"—Ë-•MàËÿA2¯ŸdàW`Øx– Ÿðž¼˜ÏY×¼@‡e6 ¯€¼°¤Ù®úº,@,Àüí@Jôç@IEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/remove-resource.png000066400000000000000000000003551211477743100253620ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞbKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÖ &«(³°zIDATxÚíÚÁ 1ÀÒ÷‘Ê7„|gß¾A+Éèœ9šÐ'륨výî|”/¥\¶\ORF GË {RI cIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/running.png000066400000000000000000000025601211477743100237200ustar00rootroot00000000000000‰PNG  IHDRàw=øsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<íIDATH‰•KlœWÇ÷ÎÓ3Žóòƒ¸ž&vÒ8NTRC B^"UbÓM]•"U"•Ú¬(›°-;T±-BM%6ФVˆJÙgAd9ظRÚ˜4ϱåÖqâàÄ3óÝÇ9,¾oìIPG:º3ßÜûûŸû?÷|ר*OûŒŸ18LäŠfÒÀéൖ/˜ºÂåèôp˜›?ÿ? €yšÀø3’+˜éýC£'Nœ( ×—‡úGè©îecs¥Õ›Üªßh]½zÕ¯¬.-F¯Sóçõæ·8õ¦9[,û³W^yaìE+Q1jDk-ÖZÔ(6g˜ûü²|4ý§†sîÜÜúþÿ˜8k/|cêíJ±PB‚W0õõG÷‡ÉƒI& Ð6$…FÑ ¸=/µG‰"T ]¬o¬as¦žY¹¼´zk¸ö̳Y‘·¡¢mÏ;¡í]mCU1)•«,­ÞÕË6z½t§~£•3y|ðøàð¡…—.8BL²çéÑôÑbBâ[„˜à²uÎ;Êù]Ô—o·$r©ÝW¾¸ö…/Ú Q2èñ!!ÄN¨Ë É4‡ ÉÖ\aw©Å/?÷¤¯r,0·²V_ü×µÙW©¥ÙFGÈš¬ m uB]H›,d»Þ’Ï®ÏÊW÷—9;^USÿýB#»è*ìÁ‡ÖжUÛc êÒÎÇÞÊÕü~>¹x¡!‘©ö%dæÏëÍÄ»sþÛZÏÕÂþ-X;[Ühô÷¾ÊÆ~Ì…O?l8ïÎu^>OÜß{Ë^<üìèä«?ýE¥×ùrmŽ nëœ+²Õéª`åØÀØ•`úÓ›7î\ÿG˜ŸøÉÂìŒì8ùýK@¿}îêÙâîðË—_š*=ÿÜ„Yo­ð(Yãaó“tzØ]ÜKoµÆg‹³úÉÅ¿8·VýHï¹ÜËbeav&t iô¬?Ÿ;xçï =|Ì:”ì=ÄÞ]ý¬?ZeùÞmî.ÝÖÅ×â×_ÝûO¼5ò1îEà뎸½0;³Ñ)ú€ÁtÔ>öÞÁtm³Ý#¦«5(øªÕBS›]kò¨º¬î»lìù7˜ÀZwúÂìÌã5È„ Pº=@Oö½’…  4€ `=› ³3±“÷_§ÇÄ:©pIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/slave-resource.png000066400000000000000000000013611211477743100251750ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞbKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÖ &*úö³Š~IDATxÚíš?nâ@Æ¿å FiRäFÛØâ¸Io´åhÊŽ€o@áÙÇØfå¹ÉÛ"Údcˆí7f oZa~~ÿ¾o†˜÷¼pçK( €P @(pŸëq¬rHyfËö/˜ Œ˜n, NAL–Îoìd‰ )ƒ#ûñŒN\»“? ææØØ0¼á3¸Ü0Ö  àJë)¨„SåaR›ü†;J‘€Ô¼ò¾ù€»@ýœ?¾5ˆçv²j~˜·1˜ØŒB(ÞÛß~Ç¢ƒ©1É´ÔØ´l>G…¸óó"üDnnbZ îÕ³cZÜ»ˆ‘·|ò„Hpò à Eïž½ø2 ò)å@ëÛ²%2¬P÷‚Ó[$GÓˆŽÁ‚£ðåÙ?1 öˆ(´TÓåîIwH°ÅKá·ye14PšÖ=»F0jPP d„/‡=Gùº !=Óû*¢äû†H§âx…´ q¯È OéH ëßêE¸…Rx—¤VLv3ZÉaúg] vƒ<»5±9ï ”8ˆù‚ƒ8¤§ÕÞf˜¡ü#ì©jõv8„!†Pzûƒñ'1 àð«Eîà0…åÍÈS‡w›ÝŸ!2¸üжêOÁø Áºj~ˆž› bÚ`O°´3\n‘Ž‹ož$KÚb£V›a† RL%j‹Më†HÏsáy´ÍoÑ`)j‰ D@D?|9«³ÉE½Æ’"¦ˆˆ:1?þÓì—ÅÍØ&ÈÕà¸Jo¢røFFa €P @( Â^óÕ/Õ ŒVIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/standby-node.png000066400000000000000000000005361211477743100246300ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞbKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÖ * óIIíëIDATxÚíšÁƒ DÙÆÿvüòíÉÄC‹Ò²Šî›Äx5y Êš»—Ìz•ä’kª5šYxBº»á€Q°JR÷GÜ3ÔšU=ßUV+„Ö ˆtÀm2àÛ”ÂÓ¡R8R”Â#;€ H éŠy?R&à€o go[_µM¾û]`»å¥EyÐeT‹þêg˱<òù÷ÜØwÀG¬B]—Aµ÷Û.ƒgLÞ?"½Ž–â§õ2Ð.þa ·ÞàJ¦¸ÒP¸ÅIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/start-resource.png000066400000000000000000000006061211477743100252210ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞbKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÖ & _üáIDATxÚíÛ˃PPiúß_NWÝWå1ÃÚÍœ ÞK¢¹û±¹^Çò€ @ÀÕ²Ó|}ØiÎò 0C„ÎFˆ”!È‘ú`€(ù "C”ž!ZBH­'Aˆ£p'Ô] ò2T }¬€ ¸gBPí2 ("‘Ô¡ˆ+±'£v‚w F.E¯ ŒðۿϾ·p'ø€'Áég@Dxʈ Nœ +8<@vpè!X®*ƒCt‡è Þ>·tJðr´àe¨ÁÓЃ§A–ðáÀ<€1xsð_™þ[^€ `o}9y¿ŒðIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/starting.png000066400000000000000000000027311211477743100240730ustar00rootroot00000000000000‰PNG  IHDRàw=øsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<VIDATH‰•]L×Çwvgfg?c Æ8ÁÆu ÇVvŸ¢¦²,ÕREÓÈŽ’ª*ÉC•HV«ªQûœ—Tª*ÛýŠÚºiLTp,µ}iZ×HeM‰LPjXœ4€Ù5» ìtwgwfvoXV8@•#]ÍŒtæÿ»çgÎRJvŠH=^U=%„èu§Í«ª Rʨë8#ÀÀ¥è•E± Ò;pЫªƒš»NñIµ«³]o‹ÔSô‘ÊXÌ&RLß›+ŽŒNØ ’3®ãô/E¯|ú¹Í}/¿bú?ºøbà©ÇÚÅÜâ:‰•uWYJ›4Ö‡ˆ„ëׇhÚ[ÇÓ÷åO.½³‹ö÷G/_ú¿€¶Óßýˉc‡OÿøÕçüñ“?ÝúžC ´6„k| Y«DÒ,OYŒÏ¤è=~˜úº?ûÕP~*öŸ‘…[?}vG@sßË'áÍ7~ð‚qã‘Ëg9××JÐçÝÍ^²—áÑ8Rhœè~”Ë¿¹aMLܽ¸µ!¥$Ò;Ðî÷ûîýâõÀ_oÏ©ôuíEˆ]µ«!%ŒÆÒÌ<(ðÄ‘ƒ\|ýͬcÛÝ›g¢Dz„ªjïüðµ þDê¿äòÙª¸¢(hšŽªjˆ]hB@_×^¼Âae5÷¿Õï÷ªê`å+DŽ?ÒyüÄÑâÏ·&9×׊ „Àç3Ðuº¾ùlœûÆ…*ä\_+M}JGk“Òº/r„OèùÒÓÝêüò:=‡ªž«ª†ªj躯R… ˆ‡Ä‡¯ý®úôy9y$Ìʪɱc©@€âUÕS‡;ÛõÄJ†Ö£ú‚ÇãÁëUÑuMÓñx¼U›>+¾­ k™,Í-MšWUOx…½m‘=¼;ÆS"[¼(Š@UU¤” ]¿Áµ?ѱߎâá™Ì!z×qÚBËi“ á©&K))—%ŽãP.—æúà˜½ŸØQ hx0sš¦á:NÛ¦E éLžðžY«TM.•J¸®C±XÄ43œýêWøZÿ7éØ¿Ûqvd­ÃGÎ*âUÕ¯”2:›Hu45Ô‘4 Ô‚¸®‹mÛäó9Çæì™g9{fã'í?ÿWßú9šª>Hš?©Õ RÊè¦E#Ó÷æ‹õuâ)«š\.—(ò8޽m§ƒWßâüKßÙVI½=a7Ö×ð¯X’lÁ}èv‹MHÕž‚Ktj…`(Hl:æ°ÑÊQ€;‹Ëkÿž˜ž—=݇6zËîºÛ áÑ8‘f–“ë2_œî(KÑ+Òqìç.ýòZ¾6äÇ)«ŒÆÒŸ²Ù‹Rf‰`m Ãï¾—¯Ì¹YKÑ+óŽí\¼üë!ëÉ£™ZÈsõæÜCvíÙ‚ËÕ›sŒÍ¬ÓÚ¾Ÿ›± Vþ{[‡Ï¶yÐÕõÈ—Ÿï?c¤WMbÏòô‘Æ]çAtj…pS„P]-7ß¿UˆÝúg½5þÌäøXy ûÄIh\õ~µöÕó¾®w´5‰ôšIÆÌ‘1³äòü†Žá÷cø ‚¡ Éôº|ïÝëv9·øNmiö¬¬ÅÉñ1wë4©öÔ»3/–j’¿ÿíÛ¯56·4=þÄQ¥e_‹§ãà4]Ã*ؤ×2ÌÍÇåDZ{ååøüº¿øÉ°F~eÀ2€¹µO%¡KÄžcŽt¡†-+F‹íÊ€æ–RΧ„“I¨2w_—æ=«@ª²î “ãcÙmgP @‚•ªj*÷þÊR€"`yÀÖ*Wkr|¬´Uï».\ÄȃIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/stop-resource.png000066400000000000000000000003561211477743100250530ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞbKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEÖ &Lž·{IDATxÚíÚ± €0 DÑÊÞˆÉ ¨RPøý\<ÙM”´]“»ÖðÀÄöé€<ùýA¡wcÀwñ]Þ Óz {¯FÔIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/stopped.png000066400000000000000000000024711211477743100237170ustar00rootroot00000000000000‰PNG  IHDRàw=øsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<¶IDATH‰•ÏnUÆ¿{fì;míñ¿ ;.ZDºè"•’6é"eÇ´ o@YP\XWµ*`Aߢ<‚ "!%!ŠDUÑ® ij7mÛ ãùsÏa1{LšŠÙÌèÞ;¿sÎ÷Ýs¯ó¨Ú7µ÷”È„A˜è<3Ñs€hÆš(õ¨z£úÀñרÕj3I·3™ìéJ¹læó¹d6ëÀ¶SèõÐé´±³ÓòÍf°»ÛY<¾Y­Vÿ+@íέ«–e]ŸžºhS˜Ì "AAÁ4M<Ù|ÂõúJÏuÝ»Õù¯¾c€¯¿½ó]©Tšœ™µ‰~àWyÿI˜ 03—{/^¼Xûü³ùOãóϼT*M^™»bCáÍp Ãó\ˆ®ÌÍÙ¥Ri²vçÖÕ#jµZŲ¬ë³3³¶ç{ÐZ fB¹´fˆ0|ßC¯×Ãì¥YÛ²¬ëµZ­ Ì$Ýžšš¶‰h.r*"`ˆÍ€Ãõ\@SSÓ¶™¤ÛöI{ÂÉ:_˜¼t=7Fð0iéÇ‚„Â!‹@AÀ(%‚ÅBQ5Í‘û ÷»Ô{É$Ñwä ù…¾dDö»]„g@?Øët@†™:ÐU¢j$®=BP?óè­u(W"‘À^§€iÆÚöNË3Èè›Ü7ñtðŽC+ÑÌH$Øiµ<ÍX¥5šÍÀ4ÍØbÚ1ÃÙÊ”™ûý¡ `%-4šÍ@”zT½Q}¼»ÛYß|ºÉ#é­ÿÓÌ6ë1¿™LO›¼»ÛYî  <¾¹ºZï)¥LXCÙ«B† ƒ&Øv ¦a¢^¯÷oF§WxØU«Õ†ëºw—–—z™L–eôŽU‡ŠÎ R©ò¹<––—Â{!vù¼ö>˜¹4ckÐî´#9ÂVSQ³ ¥€\®Ó0±¼²ìn5ŸýñÅü—ŸHØÃΞ=›´Çùàý¹«¥RáËÓcccÊu{ð|®ëÂó<˜¦ ˲LZH§ÒØ|úDVVêþ_¯ÿ¸¸øûO¢¨Í¤Û…‘‘í……mF²óùðqꇟ]}û­b»»ßý¨8ZÌ•+T*éTÖA©˜Æ~·‹½NÒh6ùÙ³­W‹K«¿ìì´6`Àa†&}ppð À~¿‚k׮џëëŽÁFQ ;H(çññw Næt>çŒg²'‹¦aÚ~¸íönçåvëåv«½Õlnm°'àiÕÑ -qíç.txJ)uæÌ™„™Ë¥L­OJSZ6LØÂJ)_ qE©‰¼¢ ùç%öÏ+öîÝ»ÇqÞ¿ÖÄxºÉŒ®IEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/stopping.png000066400000000000000000000026311211477743100241020ustar00rootroot00000000000000‰PNG  IHDRàw=øbKGDÿÿÿ ½§“ pHYs  šœtIMEÖ($Õ^ÏgtEXtCommentid logo†Æw¹ IDATHǵ•ÛkUÇ?3gfvgoÉnÚMvÓ6&kD­I5ôÅKíE/Qñ¡ø`Pé ú `|Pãï µB!… õÒjÕÔ ±Mµ‚mº†j.›t7Év¯3sŽ;©IÑÌÎç÷ýýÎï{àÚ?ýàj`;° è¢@8†úv3üŸ#ôƒV8Øïh%’ŒˆÚÓÀs\jÅ çs ãÓÔKÕýÀξݜøW€‘îv¥z3¢¥³sg&X˜ÌS](áÕ]„eŒ…‰¥´t¥9—brtÌvôíæ½Œ p¯0ßí¸úrª e¦~ÌRêº/³V]Œ´Âhõf!‹qæ0¡ÓûI®ïÄŠ†>‰[sî[ ÑV¤å‡Ì– ¢8U`b6@}óÃéõ˜ßîB/œÚ/¢¤DMÿ„uhUÍìÕqÆ÷€«–¦K_LõfDu¡Ìï3œ;^"|QÍÃOѳî,==ŠXùñx3M±‘X”Àº«w½ÉÜ‚W.“êÍ`p©}ñ¶Xá`Kg¹“Yä¶G&Röîà⎺¬^lÛa¡¡ ´M«©nÙÉ©,-]mXá`¿û–)Øïh%Ÿ Ö} Æš^B¶ÍÏ­[8“¢QhB  aš˜–…ešèí¨v÷S>;A¼£ÿj/lŠ$ã”sy¸äìi˜ôÝö/|ã±½uÎÌJÐ4¤ô Q…È0†À麑z>O$Çï›e€î@ÔÆ9_BO­Ç0Q aðij¯3¯âl»Îk?%8øÉgH©R¡¡B`ê^ò2d¹D jã7å2@T˜štÑ‚M~ºJI4]çѧߠ5䳉Ͼø2wßs?ìÙÃ×Ãß07?nè¡8BºÓÀïøe€¢ç¸˜–ªÎ!¥D)Õ˜R¢ë:×o½yI-_~u”CŸa¡Xä|©Œé–V£Ó};Àð×Sµbec0FäN"£I<ÃCÓtÀC“°uË&zz® ÞÜÄE°€’tÅŒ†©+ø^µ pä|®°1œL`e?¥Òqš£7ºPhšG{{š5íí Ñ(´¢@¢„ÇbÄäs|#\–¢¡Âø4á5iâãЦŽá8u×Áó<¤”H%‘ÊCJ%åŸß¤BLŽÉîÃhMSŸú;«Ø—êÍôG#:ùÈÝð FS¦ibšº¦ƒ¦¡JÒ(Ðʳ´|´ƒP“"?/™Ûß·›ÛÿbŽä±ÉÑ1ϳB$šj¤?ˆ˜:†ã:8®ƒ+J<é+ñÆÔ-íÀ¶«TEˆÉÑ1¯âòøÒÀÅ¢’wN0wg†iu.[,³ŽHÐ!vü}´…ß‘”Aé&zµ€5ùÑcoÿþ9ÉfjVŒñá“üZÝô!‡¹ØÚ%a õÕmÜwMŠé }UW^n9—GUJàº`hv½9H¦™=3ÅÄñ1ùÕÏþØbôÞ(Ê NµÏu¡H*ÇÁÌìûœûím¶ºÈ¦rç|Î Ó3'3AðWSÆ"˜BÍ÷ wò\lgclbdxT„¸^D"‚(ŠèééÅ¥K{ûú÷®\XZ¾|WÍ¿iøp‚I²Ë6!Ë*TeDA„iéPÝÝ=⥕Áv"-£"ÇF˜$EaZ䨂²eáø»°, ª²š±I’ðê× …‹[-ZlE;g²,òM(’ Ó41?ÿ¯ùþ|©´ÒÛÕõ¨¨**tsª¢¢³³K\[[|¦¿ï¶/nŠ žÇG™¬(°Ê&ä¨Ý0°°ç¼æ¥S¹a^ó‡ -pÝС*;¡é7¡( öï?ÀDA8{Ǩ¨u¤¨ Ýб¸˜çºi¼’Måγ©Üy«\~ùô鹦iP•‚õZ½eTlX´´ôÕ/O=ýdiuµôbw÷‘{‹‹yÿÚõ‡N¼7õàâ·_÷óî=»×®\ùißÃtŠžëâÌ™Ox¹b¿49~üSàïpjfQ@@$žˆí»×®üzõêù¹…Ïø®7ŠÅ_ᡜ€k¿]?87ÿ €×èÚæ° 7DBñÑX?ùT;uêÃo@¯!ðO°ÿWûú(¢¼ä±G¯IEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/client/up-resource.png000066400000000000000000000005231211477743100245060ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞbKGDÿÿÿ ½§“ pHYs  šœtIMEÖ &¢žÿ›àIDATxÚí›ÁÃ0cmÞÉÝW¨c XÇ œdá<2æœsé1/€´Ÿ1mü†Ï„À¨bý,à€JÁ—áPmív* O&€’³ú¥Cð09«_~ ž'gõ[\„¢ÊYýP;‡É·@ëG¹t ¾ˆgã€nko÷;ÔixB0¶œÕo‚» ËYýökp|9«ÅEè­rV@µáßô÷À-Ö_í Ü|+ýá€ÛÖÞ¿}þá0¬/ÕGO Þ–dIEND®B`‚pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/daemon/000077500000000000000000000000001211477743100215145ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/daemon/.cvsignore000066400000000000000000000000701211477743100235110ustar00rootroot00000000000000Makefile.in Makefile .deps .libs *.la *.lo *.beam mgmtd pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/daemon/Makefile.am000066400000000000000000000044001211477743100235460ustar00rootroot00000000000000# # Author: Sun Jiang Dong # Copyright (c) 2005 International Business Machines # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_builddir)/libltdl -I$(top_srcdir)/libltdl \ -I$(top_builddir)/linux-ha -I$(top_srcdir)/linux-ha \ -I$(top_builddir) -I$(top_srcdir) halibdir = $(libdir)/@HB_PKG@ COMMONLIBS = -lplumb $(GLIBLIB) noinst_HEADERS = mgmt_internal.h EXTRA_DIST = mgmtd.pam mgmtd.pam.common LRM_DIR = lrm pamdir = $(sysconfdir)/pam.d if USE_PAM_COMMON pam_DATA = mgmtd.pam.common else pam_DATA = mgmtd.pam endif install-data-hook: mv $(DESTDIR)$(pamdir)/$(pam_DATA) $(DESTDIR)$(pamdir)/hbmgmtd halib_PROGRAMS = mgmtd mgmtd_SOURCES = mgmtd.c mgmtd_LDFLAGS = -lpam mgmtd_LDADD = $(top_builddir)/lib/mgmt/libhbmgmtclient.la \ $(top_builddir)/lib/mgmt/libhbmgmttls.la \ libhbmgmt.la \ $(top_builddir)/lib/mgmt/libhbmgmtcommon.la \ $(COMMONLIBS) if HAVE_PACEMAKER_LRMD mgmtd_LDADD += -llrmd else mgmtd_LDADD += -llrm endif lib_LTLIBRARIES = libhbmgmt.la libhbmgmt_la_SOURCES = mgmt_lib.c mgmt_crm.c if HAVE_PACEMAKER_LRMD libhbmgmt_la_SOURCES += mgmt_pacemaker_lrm.c else libhbmgmt_la_SOURCES += mgmt_lrm.c endif if BUILD_HEARTBEAT_SUPPORT libhbmgmt_la_SOURCES += mgmt_hb.c endif libhbmgmt_la_CFLAGS = $(INCLUDES) libhbmgmt_la_LDFLAGS = $(GNUTLSLIBS) libhbmgmt_la_LIBADD = $(top_builddir)/lib/mgmt/libhbmgmttls.la \ -lcib -lcrmcommon -lpe_status -lcrmcluster \ $(COMMONLIBS) $(CLUSTERLIBS) $(CURSESLIBS) pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/daemon/mgmt_crm.c000066400000000000000000002117661211477743100235020ustar00rootroot00000000000000/* * Linux HA management library * * Author: Huang Zhen * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #if HAVE_HB_CONFIG_H #include #endif #if HAVE_GLUE_CONFIG_H #include #endif #include #include #include #include #include #include #ifdef SUPPORT_AIS #undef SUPPORT_AIS #endif #ifdef SUPPORT_HEARTBEAT #undef SUPPORT_HEARTBEAT #endif #include #if HAVE_PACEMAKER_CRM_COMMON_CLUSTER_H # include #endif #if HAVE_PACEMAKER_CRM_CLUSTER_H # include #endif #if HAVE_PACEMAKER_CRM_SERVICES_H # include #endif #include "mgmt_internal.h" #if !HAVE_CRM_DATA_T typedef xmlNode crm_data_t; #endif #if !HAVE_CRM_IPC_NEW typedef IPC_Channel crm_ipc_t; #endif extern resource_t *group_find_child(resource_t *rsc, const char *id); /*extern crm_data_t * do_calculations( pe_working_set_t *data_set, crm_data_t *xml_input, ha_time_t *now);*/ extern int *client_id; cib_t* cib_conn = NULL; int in_shutdown = FALSE; int init_crm(int cache_cib); void final_crm(void); int set_crm(void); static GHashTable* cib_conns = NULL; static GHashTable* cib_envs = NULL; static void on_cib_diff(const char *event, crm_data_t *msg); static char* on_active_cib(char* argv[], int argc); static char* on_shutdown_cib(char* argv[], int argc); static char* on_init_cib(char* argv[], int argc); static char* on_switch_cib(char* argv[], int argc); static char* on_get_shadows(char* argv[], int argc); static char* on_crm_shadow(char* argv[], int argc); static char* on_get_cluster_type(char* argv[], int argc); static char* on_get_cib_version(char* argv[], int argc); static char* on_get_crm_schema(char* argv[], int argc); static char* on_get_crm_dtd(char* argv[], int argc); static char* on_get_crm_metadata(char* argv[], int argc); static char* on_crm_attribute(char* argv[], int argc); static char* on_get_activenodes(char* argv[], int argc); static char* on_get_crmnodes(char* argv[], int argc); static char* on_get_dc(char* argv[], int argc); static char* on_migrate_rsc(char* argv[], int argc); static char* on_set_node_standby(char* argv[], int argc); static char* on_get_node_config(char* argv[], int argc); static char* on_get_running_rsc(char* argv[], int argc); static char* on_cleanup_rsc(char* argv[], int argc); static char* on_get_all_rsc(char* argv[], int argc); static char* on_get_rsc_type(char* argv[], int argc); static char* on_get_sub_rsc(char* argv[], int argc); static char* on_get_rsc_running_on(char* argv[], int argc); static char* on_get_rsc_status(char* argv[], int argc); static char* on_op_status2str(char* argv[], int argc); static char* on_crm_rsc_cmd(char* argv[], int argc); static char* on_set_rsc_attr(char* argv[], int argc); static char* on_get_rsc_attr(char* argv[], int argc); static char* on_del_rsc_attr(char* argv[], int argc); /* new CRUD protocol */ static char* on_cib_create(char* argv[], int argc); static char* on_cib_query(char* argv[], int argc); static char* on_cib_update(char* argv[], int argc); static char* on_cib_replace(char* argv[], int argc); static char* on_cib_delete(char* argv[], int argc); /* end new protocol */ static char* on_gen_cluster_report(char* argv[], int argc); static char* on_get_pe_inputs(char* argv[], int argc); static char* on_get_pe_summary(char* argv[], int argc); static char* on_gen_pe_graph(char* argv[], int argc); static char* on_gen_pe_info(char* argv[], int argc); /* static int delete_object(const char* type, const char* entry, const char* id, crm_data_t** output); static GList* find_xml_node_list(crm_data_t *root, const char *search_path); */ static int refresh_lrm(crm_ipc_t *crmd_channel, const char *host_uname); static int delete_lrm_rsc(crm_ipc_t *crmd_channel, const char *host_uname, const char *rsc_id); static pe_working_set_t* get_data_set(void); static void free_data_set(pe_working_set_t* data_set); static void on_cib_connection_destroy(gpointer user_data); static char* crm_failed_msg(crm_data_t* output, int rc); static const char* uname2id(const char* node); /* static resource_t* get_parent(resource_t* child); */ int regex_match(const char *regex, const char *str); pid_t popen2(const char *command, FILE **fp_in, FILE **fp_out); int pclose2(FILE *fp_in, FILE *fp_out, pid_t pid); pe_working_set_t* cib_cached = NULL; int cib_cache_enable = FALSE; #if !HAVE_PCMK_STRERROR # define pcmk_strerror(rc) cib_error2string(rc) #endif #if !HAVE_DECL_CRM_CONCAT static char * crm_concat(const char *prefix, const char *suffix, char join) { int len = 0; char *new_str = NULL; CRM_ASSERT(prefix != NULL); CRM_ASSERT(suffix != NULL); len = strlen(prefix) + strlen(suffix) + 2; new_str = calloc(1, (len)); sprintf(new_str, "%s%c%s", prefix, join, suffix); new_str[len - 1] = 0; return new_str; } #endif #if !HAVE_DECL_CRM_INT_HELPER static long long crm_int_helper(const char *text, char **end_text) { long long result = -1; char *local_end_text = NULL; int saved_errno = 0; errno = 0; if (text != NULL) { #ifdef ANSI_ONLY if (end_text != NULL) { result = strtol(text, end_text, 10); } else { result = strtol(text, &local_end_text, 10); } #else if (end_text != NULL) { result = strtoll(text, end_text, 10); } else { result = strtoll(text, &local_end_text, 10); } #endif saved_errno = errno; /* CRM_CHECK(errno != EINVAL); */ if (errno == EINVAL) { crm_err("Conversion of %s failed", text); result = -1; } else if (errno == ERANGE) { crm_err("Conversion of %s was clipped: %lld", text, result); } else if (errno != 0) { crm_perror(LOG_ERR, "Conversion of %s failed:", text); } if (local_end_text != NULL && local_end_text[0] != '\0') { crm_err("Characters left over after parsing '%s': '%s'", text, local_end_text); } errno = saved_errno; } return result; } #endif #if !HAVE_DECL_GENERATE_SERIES_FILENAME static char * generate_series_filename(const char *directory, const char *series, int sequence, gboolean bzip) { int len = 40; char *filename = NULL; const char *ext = "raw"; CRM_CHECK(directory != NULL, return NULL); CRM_CHECK(series != NULL, return NULL); len += strlen(directory); len += strlen(series); filename = calloc(1, len); CRM_CHECK(filename != NULL, return NULL); if (bzip) { ext = "bz2"; } sprintf(filename, "%s/%s-%d.%s", directory, series, sequence, ext); return filename; } #endif #if !HAVE_DECL_GET_LAST_SEQUENCE static int get_last_sequence(const char *directory, const char *series) { FILE *file_strm = NULL; int start = 0, length = 0, read_len = 0; char *series_file = NULL; char *buffer = NULL; int seq = 0; int len = 36; CRM_CHECK(directory != NULL, return 0); CRM_CHECK(series != NULL, return 0); len += strlen(directory); len += strlen(series); series_file = calloc(1, len); CRM_CHECK(series_file != NULL, return 0); sprintf(series_file, "%s/%s.last", directory, series); file_strm = fopen(series_file, "r"); if (file_strm == NULL) { crm_debug("Series file %s does not exist", series_file); free(series_file); return 0; } /* see how big the file is */ start = ftell(file_strm); fseek(file_strm, 0L, SEEK_END); length = ftell(file_strm); fseek(file_strm, 0L, start); CRM_ASSERT(length >= 0); CRM_ASSERT(start == ftell(file_strm)); if (length <= 0) { crm_info("%s was not valid", series_file); free(buffer); buffer = NULL; } else { crm_trace("Reading %d bytes from file", length); buffer = calloc(1, (length + 1)); read_len = fread(buffer, 1, length, file_strm); if (read_len != length) { crm_err("Calculated and read bytes differ: %d vs. %d", length, read_len); free(buffer); buffer = NULL; } } seq = crm_parse_int(buffer, "0"); fclose(file_strm); crm_trace("Found %d in %s", seq, series_file); free(series_file); free(buffer); return seq; } #endif #define CIB_CHECK() \ if (cib_conn == NULL) { \ mgmt_log(LOG_ERR, "No cib connection: client_id=%d", *client_id); \ return strdup(MSG_FAIL"\nNo cib connection"); \ } #define GET_CIB_NAME(cib_name) \ if (getenv("CIB_shadow") == NULL) { \ strncpy(cib_name, "live", sizeof(cib_name)-1); \ } else { \ snprintf(cib_name, sizeof(cib_name),"shadow.%s", getenv("CIB_shadow")); \ } #define GET_RESOURCE() rsc = pe_find_resource(data_set->resources, argv[1]); \ if (rsc == NULL) { \ char *as_clone = crm_concat(argv[1], "0", ':'); \ rsc = pe_find_resource(data_set->resources, as_clone); \ free(as_clone); \ if (rsc == NULL) { \ free_data_set(data_set); \ return strdup(MSG_FAIL"\nno such resource"); \ } \ } #define free_cib_cached() \ if (cib_cache_enable) { \ if (cib_cached != NULL) { \ cleanup_calculations(cib_cached); \ free(cib_cached); \ cib_cached = NULL; \ } \ } #define append_str(msg, buf, str) \ if (strlen(buf)+strlen(str) >= sizeof(buf)) { \ msg = mgmt_msg_append(msg, buf); \ memset(buf, 0, sizeof(buf)); \ } \ strncat(buf, str, sizeof(buf)-strlen(buf)-1); #define gen_msg_from_fstream(fstream, msg, buf, str) \ memset(buf, 0, sizeof(buf)); \ while (!feof(fstream)){ \ if (fgets(str, sizeof(str), fstream) != NULL){ \ append_str(msg, buf, str); \ } \ else{ \ sleep(1); \ } \ } \ msg = mgmt_msg_append(msg, buf); \ if (msg[strlen(msg)-1] == '\n'){ \ msg[strlen(msg)-1] = '\0'; \ } /* internal functions */ /* GList* find_xml_node_list(crm_data_t *root, const char *child_name) { GList* list = NULL; xml_child_iter_filter(root, child, child_name, list = g_list_append(list, child)); return list; } int delete_object(const char* type, const char* entry, const char* id, crm_data_t** output) { int rc; crm_data_t* cib_object = NULL; char xml[MAX_STRLEN]; snprintf(xml, MAX_STRLEN, "<%s id=\"%s\">", entry, id); cib_object = string2xml(xml); if(cib_object == NULL) { return -1; } mgmt_log(LOG_INFO, "(delete)xml:%s",xml); rc = cib_conn->cmds->delete( cib_conn, type, cib_object, cib_sync_call); free_xml(cib_object); return rc; } */ pe_working_set_t* get_data_set(void) { pe_working_set_t* data_set; if (cib_cache_enable) { if (cib_cached != NULL) { return cib_cached; } } data_set = (pe_working_set_t*)malloc(sizeof(pe_working_set_t)); if (data_set == NULL) { mgmt_log(LOG_ERR, "%s:Can't alloc memory for data set.",__FUNCTION__); return NULL; } set_working_set_defaults(data_set); data_set->input = get_cib_copy(cib_conn); #if HAVE_NEW_HA_DATE data_set->now = new_ha_date(TRUE); #else data_set->now = NULL; #endif cluster_status(data_set); if (cib_cache_enable) { cib_cached = data_set; } return data_set; } void free_data_set(pe_working_set_t* data_set) { /* we only release the cib when cib is not cached. the cached cib will be released in on_cib_diff() */ if (!cib_cache_enable) { cleanup_calculations(data_set); free(data_set); } } char* crm_failed_msg(crm_data_t* output, int rc) { const char* reason = NULL; crm_data_t* failed_tag; char* ret; /* beekhof: you can pretend that the return code is success, its an internal CIB thing*/ #if !HAVE_PCMK_STRERROR if (rc == cib_diff_resync) { #else if (rc == -pcmk_err_diff_resync) { #endif if (output != NULL) { free_xml(output); } return strdup(MSG_OK); } ret = strdup(MSG_FAIL); ret = mgmt_msg_append(ret, pcmk_strerror(rc)); if (output == NULL) { return ret; } failed_tag = find_entity(output, XML_FAIL_TAG_CIB, NULL); if (failed_tag != NULL) { reason = crm_element_value(failed_tag, XML_FAILCIB_ATTR_REASON); if (reason != NULL) { ret = mgmt_msg_append(ret, reason); } } free_xml(output); return ret; } const char* uname2id(const char* uname) { node_t* node; GList* cur; pe_working_set_t* data_set; data_set = get_data_set(); cur = data_set->nodes; while (cur != NULL) { node = (node_t*) cur->data; if (strncmp(uname,node->details->uname,MAX_STRLEN) == 0) { free_data_set(data_set); return node->details->id; } cur = g_list_next(cur); } free_data_set(data_set); return NULL; } /* static resource_t* get_parent(resource_t* child) { GList* cur; pe_working_set_t* data_set; data_set = get_data_set(); cur = data_set->resources; while (cur != NULL) { resource_t* rsc = (resource_t*)cur->data; if(is_not_set(rsc->flags, pe_rsc_orphan) || rsc->role != RSC_ROLE_STOPPED) { GList* child_list = rsc->children; if (g_list_find(child_list, child) != NULL) { free_data_set(data_set); return rsc; } } cur = g_list_next(cur); } free_data_set(data_set); return NULL; } */ /* mgmtd functions */ int init_crm(int cache_cib) { int ret = 0; int i, max_try = 5; char cib_name[MAX_STRLEN]; GET_CIB_NAME(cib_name) mgmt_log(LOG_INFO,"init_crm: client_id=%d cib_name=%s", *client_id, cib_name); crm_log_level = LOG_ERR; cib_conn = cib_new(); in_shutdown = FALSE; cib_cache_enable = cache_cib?TRUE:FALSE; cib_cached = NULL; for (i = 1; i <= max_try ; i++) { ret = cib_conn->cmds->signon(cib_conn, client_name, cib_command); if (ret == 0) { break; } mgmt_log(LOG_INFO,"login to cib '%s': %d, ret=%d (%s)", cib_name, i, ret, pcmk_strerror(ret)); sleep(1); } if (ret != 0) { mgmt_log(LOG_INFO,"login to cib '%s' failed: %s", cib_name, pcmk_strerror(ret)); cib_conn = NULL; return ret; } ret = cib_conn->cmds->add_notify_callback(cib_conn, T_CIB_DIFF_NOTIFY , on_cib_diff); ret = cib_conn->cmds->set_connection_dnotify(cib_conn , on_cib_connection_destroy); reg_msg(MSG_ACTIVE_CIB, on_active_cib); reg_msg(MSG_SHUTDOWN_CIB, on_shutdown_cib); reg_msg(MSG_INIT_CIB, on_init_cib); reg_msg(MSG_SWITCH_CIB, on_switch_cib); reg_msg(MSG_GET_SHADOWS, on_get_shadows); reg_msg(MSG_CRM_SHADOW, on_crm_shadow); reg_msg(MSG_CLUSTER_TYPE, on_get_cluster_type); reg_msg(MSG_CIB_VERSION, on_get_cib_version); reg_msg(MSG_CRM_SCHEMA, on_get_crm_schema); reg_msg(MSG_CRM_DTD, on_get_crm_dtd); reg_msg(MSG_CRM_METADATA, on_get_crm_metadata); reg_msg(MSG_CRM_ATTRIBUTE, on_crm_attribute); reg_msg(MSG_DC, on_get_dc); reg_msg(MSG_ACTIVENODES, on_get_activenodes); reg_msg(MSG_CRMNODES, on_get_crmnodes); reg_msg(MSG_NODE_CONFIG, on_get_node_config); reg_msg(MSG_RUNNING_RSC, on_get_running_rsc); reg_msg(MSG_MIGRATE, on_migrate_rsc); reg_msg(MSG_STANDBY, on_set_node_standby); reg_msg(MSG_CLEANUP_RSC, on_cleanup_rsc); reg_msg(MSG_ALL_RSC, on_get_all_rsc); reg_msg(MSG_SUB_RSC, on_get_sub_rsc); reg_msg(MSG_RSC_RUNNING_ON, on_get_rsc_running_on); reg_msg(MSG_RSC_STATUS, on_get_rsc_status); reg_msg(MSG_RSC_TYPE, on_get_rsc_type); reg_msg(MSG_OP_STATUS2STR, on_op_status2str); reg_msg(MSG_CRM_RSC_CMD, on_crm_rsc_cmd); reg_msg(MSG_SET_RSC_ATTR, on_set_rsc_attr); reg_msg(MSG_GET_RSC_ATTR, on_get_rsc_attr); reg_msg(MSG_DEL_RSC_ATTR, on_del_rsc_attr); reg_msg(MSG_GEN_CLUSTER_REPORT, on_gen_cluster_report); reg_msg(MSG_GET_PE_INPUTS, on_get_pe_inputs); reg_msg(MSG_GET_PE_SUMMARY, on_get_pe_summary); reg_msg(MSG_GEN_PE_GRAPH, on_gen_pe_graph); reg_msg(MSG_GEN_PE_INFO, on_gen_pe_info); reg_msg(MSG_CIB_CREATE, on_cib_create); reg_msg(MSG_CIB_QUERY, on_cib_query); reg_msg(MSG_CIB_UPDATE, on_cib_update); reg_msg(MSG_CIB_REPLACE, on_cib_replace); reg_msg(MSG_CIB_DELETE, on_cib_delete); if (cib_conns == NULL) { cib_conns = g_hash_table_new(g_int_hash, g_int_equal); } g_hash_table_insert(cib_conns, client_id, cib_conn); if (cib_envs == NULL) { cib_envs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free); } g_hash_table_insert(cib_envs, cib_conn, getenv("CIB_shadow")?strdup(getenv("CIB_shadow")):NULL); return 0; } void final_crm(void) { char cib_name[MAX_STRLEN]; GET_CIB_NAME(cib_name) mgmt_log(LOG_INFO,"final_crm: client_id=%d cib_name=%s", *client_id, cib_name); if(cib_conn != NULL) { in_shutdown = TRUE; cib_conn->cmds->signoff(cib_conn); cib_delete(cib_conn); g_hash_table_remove(cib_conns, client_id); g_hash_table_remove(cib_envs, cib_conn); cib_conn = NULL; if (g_hash_table_size(cib_conns) == 0) { g_hash_table_destroy(cib_conns); cib_conns = NULL; } if (g_hash_table_size(cib_envs) == 0) { g_hash_table_destroy(cib_envs); cib_envs = NULL; } } free_cib_cached(); } int set_crm(void) { free_cib_cached(); cib_conn = g_hash_table_lookup(cib_conns, client_id); if (cib_conn != NULL) { const char *env = g_hash_table_lookup(cib_envs, cib_conn); if (env == NULL) { unsetenv("CIB_shadow"); } else { setenv("CIB_shadow", env, 1); } mgmt_debug(LOG_DEBUG, "set_crm: client_id=%d cib_conn=%p cib_name=%s", *client_id, cib_conn, env); return 0; } mgmt_log(LOG_WARNING, "No cib connection recorded for set_crm: client_id=%d", *client_id); return -1; } /* event handler */ void on_cib_diff(const char *event, crm_data_t *msg) { if (debug_level) { mgmt_debug(LOG_DEBUG,"update cib finished"); } free_cib_cached(); fire_event(EVT_CIB_CHANGED); } void on_cib_connection_destroy(gpointer user_data) { if (!in_shutdown) { fire_event(EVT_DISCONNECTED); cib_conn = NULL; } return; } char* on_active_cib(char* argv[], int argc) { char* ret = strdup(MSG_OK); const char *active_cib = getenv("CIB_shadow"); if (active_cib != NULL) { ret = mgmt_msg_append(ret, active_cib); } else { ret = mgmt_msg_append(ret, ""); } return ret; } char* on_shutdown_cib(char* argv[], int argc) { final_crm(); return strdup(MSG_OK); } char* on_init_cib(char* argv[], int argc) { char buf[MAX_STRLEN]; char* ret = NULL; char cib_name[MAX_STRLEN]; int rc = 0; ARGC_CHECK(2); if (strnlen(argv[1], MAX_STRLEN) == 0) { unsetenv("CIB_shadow"); strncpy(cib_name, "live", sizeof(cib_name)-1); } else { setenv("CIB_shadow", argv[1], 1); snprintf(cib_name, sizeof(cib_name), "shadow.%s", argv[1]); } if ((rc = init_crm(TRUE)) != 0) { ret = strdup(MSG_FAIL); snprintf(buf, sizeof(buf), "Cannot initiate CIB '%s': %s", cib_name, pcmk_strerror(rc)); ret = mgmt_msg_append(ret, buf); } else { ret = strdup(MSG_OK); } return ret; } char* on_switch_cib(char* argv[], int argc) { char cib_name[MAX_STRLEN]; char buf[MAX_STRLEN]; char* ret = NULL; const char* saved_env = getenv("CIB_shadow"); int rc = 0; ARGC_CHECK(2) final_crm(); if (strnlen(argv[1], MAX_STRLEN) == 0) { unsetenv("CIB_shadow"); strncpy(cib_name, "live", sizeof(cib_name)-1); } else { setenv("CIB_shadow", argv[1], 1); snprintf(cib_name, sizeof(cib_name), "shadow.%s", argv[1]); } mgmt_log(LOG_INFO, "Switch to the CIB '%s'", cib_name); if ((rc = init_crm(TRUE)) != 0) { mgmt_log(LOG_ERR, "Cannot switch to the CIB '%s': %s", cib_name, pcmk_strerror(rc)); ret = strdup(MSG_FAIL); snprintf(buf, sizeof(buf), "Cannot switch to the CIB '%s': %s", cib_name, pcmk_strerror(rc)); ret = mgmt_msg_append(ret, buf); if (saved_env == NULL) { unsetenv("CIB_shadow"); strncpy(cib_name, "live", sizeof(cib_name)-1); } else { setenv("CIB_shadow", saved_env, 1); snprintf(cib_name, sizeof(cib_name), "shadow.%s", saved_env); } if ((rc = init_crm(TRUE)) != 0) { mgmt_log(LOG_ERR, "Cannot switch back to the previous CIB '%s': %s", cib_name, pcmk_strerror(rc)); memset(buf, 0, sizeof(buf)); snprintf(buf, sizeof(buf), "Cannot switch back to the previous CIB '%s': %s", cib_name, pcmk_strerror(rc)); ret = mgmt_msg_append(ret, buf); if (saved_env) { unsetenv("CIB_shadow"); strncpy(cib_name, "live", sizeof(cib_name)-1); if ((rc = init_crm(TRUE)) != 0) { mgmt_log(LOG_ERR, "Cannot recover to the CIB '%s': %s", cib_name, pcmk_strerror(rc)); memset(buf, 0, sizeof(buf)); snprintf(buf, sizeof(buf), "Cannot recover to the CIB '%s': %s", cib_name, pcmk_strerror(rc)); ret = mgmt_msg_append(ret, buf); } } } } else { ret = strdup(MSG_OK); } return ret; } char* on_get_shadows(char* argv[], int argc) { char *ret = NULL; char *test_file = NULL; const char *shadow_dir = NULL; struct dirent *dirp; DIR *dp; char fullpath[MAX_STRLEN]; struct stat statbuf; if ((test_file = get_shadow_file("test"))) { shadow_dir = dirname(test_file); } else { shadow_dir = CRM_CONFIG_DIR; } if ((dp = opendir(shadow_dir)) == NULL){ mgmt_log(LOG_ERR, "error on opendir \"%s\": %s", shadow_dir, strerror(errno)); if (test_file) { free(test_file); } return strdup(MSG_FAIL"\nCannot open the CIB shadow directory"); } ret = strdup(MSG_OK); while ((dirp = readdir(dp)) != NULL) { if (strstr(dirp->d_name, "shadow.") == dirp->d_name) { snprintf(fullpath, sizeof(fullpath), "%s/%s", shadow_dir, dirp->d_name); if (stat(fullpath, &statbuf) < 0){ mgmt_log(LOG_WARNING, "Cannot stat the file \"%s\": %s", fullpath, strerror(errno)); continue; } if (S_ISREG(statbuf.st_mode)){ ret = mgmt_msg_append(ret, dirp->d_name); } } } if (closedir(dp) < 0){ mgmt_log(LOG_WARNING, "failed to closedir \"%s\": %s", shadow_dir, strerror(errno) ); } if (test_file) { free(test_file); } return ret; } char* on_crm_shadow(char* argv[], int argc) { char cmd[MAX_STRLEN]; char buf[MAX_STRLEN]; char str[MAX_STRLEN]; char* ret = NULL; int require_name = 0; const char* name = ""; FILE *fp_in = NULL; FILE *fp_out = NULL; pid_t childpid = 0; int stat; ARGC_CHECK(4); strncpy(cmd, "/usr/bin/xargs -0 crm_shadow 2>&1", sizeof(cmd)-1); if (STRNCMP_CONST(argv[3], "true") == 0) { strncat(cmd, " --force", sizeof(cmd)-strlen(cmd)-1); } if (STRNCMP_CONST(argv[1], "create") == 0) { strncat(cmd, " -b -c", sizeof(cmd)-strlen(cmd)-1); require_name = 1; } else if (STRNCMP_CONST(argv[1], "create-empty") == 0) { strncat(cmd, " -b --create-empty", sizeof(cmd)-strlen(cmd)-1); require_name = 1; } else if (STRNCMP_CONST(argv[1], "delete") == 0) { strncat(cmd, " -D", sizeof(cmd)-strlen(cmd)-1); require_name = 1; } else if (STRNCMP_CONST(argv[1], "reset") == 0) { strncat(cmd, " -r", sizeof(cmd)-strlen(cmd)-1); require_name = 1; } else if (STRNCMP_CONST(argv[1], "commit") == 0) { strncat(cmd, " -C", sizeof(cmd)-strlen(cmd)-1); require_name = 1; } else if (STRNCMP_CONST(argv[1], "diff") == 0) { strncat(cmd, " -d", sizeof(cmd)-strlen(cmd)-1); } else { mgmt_log(LOG_ERR, "invalid arguments specified: \"%s\"", argv[1]); return strdup(MSG_FAIL"\nInvalid arguments"); } if (require_name) { if (strnlen(argv[2], MAX_STRLEN) != 0) { name = argv[2]; } else if (getenv("CIB_shadow") != NULL) { name = getenv("CIB_shadow"); } /*strncat(cmd, " ", sizeof(cmd)-strlen(cmd)-1); strncat(cmd, name, sizeof(cmd)-strlen(cmd)-1);*/ } if ((childpid = popen2(cmd, &fp_in, &fp_out)) < 0){ mgmt_log(LOG_ERR, "error on popen2 \"%s\": %s", cmd, strerror(errno)); return strdup(MSG_FAIL"\nInvoke crm_shadow failed"); } if (fputs(name, fp_in) == EOF) { mgmt_log(LOG_ERR, "error on fputs arguments to \"%s\": %s", cmd, strerror(errno)); return strdup(MSG_FAIL"\nPut arguments to crm_shadow failed"); } if (fclose(fp_in) == EOF) { mgmt_log(LOG_WARNING, "failed to close input pipe"); } ret = strdup(MSG_FAIL); gen_msg_from_fstream(fp_out, ret, buf, str); /*if (pclose2(fp_in, fp_out, childpid) == -1) {*/ if ((stat = pclose2(NULL, fp_out, childpid)) == -1) { mgmt_log(LOG_WARNING, "failed to close pipe"); /*} else if (WIFEXITED(stat) && WEXITSTATUS(stat) == 0) { ret[0] = CHR_OK;*/ } return ret; } /* cluster functions */ char* on_get_cluster_type(char* argv[], int argc) { char* ret = NULL; if (is_openais_cluster()) { ret = strdup(MSG_OK); ret = mgmt_msg_append(ret, "openais"); } else if (is_heartbeat_cluster()) { ret = strdup(MSG_OK); ret = mgmt_msg_append(ret, "heartbeat"); } else { ret = strdup(MSG_FAIL); } return ret; } char* on_get_cib_version(char* argv[], int argc) { const char* version = NULL; pe_working_set_t* data_set; char* ret; data_set = get_data_set(); version = crm_element_value(data_set->input, "num_updates"); if (version != NULL) { ret = strdup(MSG_OK); ret = mgmt_msg_append(ret, version); } else { ret = strdup(MSG_FAIL); } free_data_set(data_set); return ret; } static char* on_get_crm_schema(char* argv[], int argc) { const char *schema_file = NULL; const char *validate_type = NULL; const char *file_name = NULL; char buf[MAX_STRLEN]; char str[MAX_STRLEN]; char* ret = NULL; FILE *fstream = NULL; ARGC_CHECK(3); validate_type = argv[1]; file_name = argv[2]; if (STRNCMP_CONST(validate_type, "") == 0){ schema_file = HA_NOARCHDATAHBDIR"/crm.dtd"; } else if (STRNCMP_CONST(validate_type, "pacemaker-0.6") == 0){ schema_file = DTD_DIRECTORY"/crm.dtd"; } else if (STRNCMP_CONST(validate_type, "transitional-0.6") == 0){ schema_file = DTD_DIRECTORY"/crm-transitional.dtd"; } else{ if (STRNCMP_CONST(file_name, "") == 0){ snprintf(buf, sizeof(buf), DTD_DIRECTORY"/%s.rng", validate_type); schema_file = buf; } else{ snprintf(buf, sizeof(buf), DTD_DIRECTORY"/%s", file_name); schema_file = buf; } } if ((fstream = fopen(schema_file, "r")) == NULL){ mgmt_log(LOG_ERR, "error on fopen %s: %s", schema_file, strerror(errno)); return strdup(MSG_FAIL); } ret = strdup(MSG_OK); gen_msg_from_fstream(fstream, ret, buf, str); if (fclose(fstream) == -1) mgmt_log(LOG_WARNING, "failed to fclose stream"); return ret; } static char* on_get_crm_dtd(char* argv[], int argc) { const char *dtd_file = HA_NOARCHDATAHBDIR"/crm.dtd"; char buf[MAX_STRLEN]; char str[MAX_STRLEN]; char* ret = NULL; FILE *fstream = NULL; if ((fstream = fopen(dtd_file, "r")) == NULL){ mgmt_log(LOG_ERR, "error on fopen %s: %s", dtd_file, strerror(errno)); return strdup(MSG_FAIL); } ret = strdup(MSG_OK); gen_msg_from_fstream(fstream, ret, buf, str); if (fclose(fstream) == -1) mgmt_log(LOG_WARNING, "failed to fclose stream"); return ret; } static char* on_crm_attribute(char* argv[], int argc) { char cmd[MAX_STRLEN]; char buf[MAX_STRLEN]; char* ret = NULL; const char* nv_regex = "^[A-Za-z0-9_-]+$"; FILE *fstream = NULL; ARGC_CHECK(8); snprintf(cmd, sizeof(cmd), "crm_attribute -t %s", argv[1]); if (regex_match(nv_regex, argv[3])){ if (STRNCMP_CONST(argv[2], "get") == 0){ strncat(cmd, " -Q -G", sizeof(cmd)-strlen(cmd)-1); } else if (STRNCMP_CONST(argv[2], "del") == 0){ strncat(cmd, " -D", sizeof(cmd)-strlen(cmd)-1); } strncat(cmd, " -n \"", sizeof(cmd)-strlen(cmd)-1); strncat(cmd, argv[3], sizeof(cmd)-strlen(cmd)-1); strncat(cmd, "\"", sizeof(cmd)-strlen(cmd)-1); } else { mgmt_log(LOG_ERR, "invalid attribute name specified: \"%s\"", argv[3]); return strdup(MSG_FAIL"\nInvalid attribute name"); } if (STRNCMP_CONST(argv[2], "set") == 0){ if (regex_match(nv_regex, argv[4])){ strncat(cmd, " -v \"", sizeof(cmd)-strlen(cmd)-1); strncat(cmd, argv[4], sizeof(cmd)-strlen(cmd)-1); strncat(cmd, "\"", sizeof(cmd)-strlen(cmd)-1); } else { mgmt_log(LOG_ERR, "invalid attribute value specified: \"%s\"", argv[4]); return strdup(MSG_FAIL"\nInvalid attribute value"); } } if (STRNCMP_CONST(argv[5], "") != 0){ if (uname2id(argv[5]) == NULL) { return strdup(MSG_FAIL"\nNo such node"); } else{ strncat(cmd, " -N ", sizeof(cmd)-strlen(cmd)-1); strncat(cmd, argv[5], sizeof(cmd)-strlen(cmd)-1); } } if (STRNCMP_CONST(argv[6], "") != 0){ if (regex_match(nv_regex, argv[6])){ strncat(cmd, " -s \"", sizeof(cmd)-strlen(cmd)-1); strncat(cmd, argv[6], sizeof(cmd)-strlen(cmd)-1); strncat(cmd, "\"", sizeof(cmd)-strlen(cmd)-1); } else { mgmt_log(LOG_ERR, "invalid attribute set ID specified: \"%s\"", argv[6]); return strdup(MSG_FAIL"\nInvalid attribute set ID"); } } if (STRNCMP_CONST(argv[7], "") != 0){ if (regex_match(nv_regex, argv[7])){ strncat(cmd, " -i \"", sizeof(cmd)-strlen(cmd)-1); strncat(cmd, argv[7], sizeof(cmd)-strlen(cmd)-1); strncat(cmd, "\"", sizeof(cmd)-strlen(cmd)-1); } else { mgmt_log(LOG_ERR, "invalid attribute ID specified: \"%s\"", argv[7]); return strdup(MSG_FAIL"\nInvalid attribute ID"); } } strncat(cmd, " 2>&1", sizeof(cmd)-strlen(cmd)-1); if ((fstream = popen(cmd, "r")) == NULL){ mgmt_log(LOG_ERR, "error on popen %s: %s", cmd, strerror(errno)); return strdup(MSG_FAIL"\nInvoke crm_attribute failed"); } if (STRNCMP_CONST(argv[2], "get") == 0){ ret = strdup(MSG_OK); } else{ ret = strdup(MSG_FAIL); } while (!feof(fstream)){ memset(buf, 0, sizeof(buf)); if (fgets(buf, sizeof(buf), fstream) != NULL){ ret = mgmt_msg_append(ret, buf); ret[strlen(ret)-1] = '\0'; } else{ sleep(1); } } if (pclose(fstream) == -1) mgmt_log(LOG_WARNING, "failed to close pipe"); return ret; } static char* on_get_crm_metadata(char* argv[], int argc) { char cmd[MAX_STRLEN]; char buf[MAX_STRLEN]; char str[MAX_STRLEN]; char* ret = NULL; FILE *fstream = NULL; ARGC_CHECK(2); if (STRNCMP_CONST(argv[1], "pengine") != 0 && STRNCMP_CONST(argv[1], "crmd") != 0) { return strdup(MSG_FAIL); } snprintf(cmd, sizeof(cmd), CRM_DAEMON_DIR"/%s metadata", argv[1]); if ((fstream = popen(cmd, "r")) == NULL){ mgmt_log(LOG_ERR, "error on popen %s: %s", cmd, strerror(errno)); return strdup(MSG_FAIL); } ret = strdup(MSG_OK); gen_msg_from_fstream(fstream, ret, buf, str); if (pclose(fstream) == -1) mgmt_log(LOG_WARNING, "failed to close pipe"); return ret; } /* node functions */ char* on_get_activenodes(char* argv[], int argc) { node_t* node; GList* cur; char* ret; pe_working_set_t* data_set; data_set = get_data_set(); cur = data_set->nodes; ret = strdup(MSG_OK); while (cur != NULL) { node = (node_t*) cur->data; if (node->details->online) { ret = mgmt_msg_append(ret, node->details->uname); } cur = g_list_next(cur); } free_data_set(data_set); return ret; } char* on_get_crmnodes(char* argv[], int argc) { node_t* node; GList* cur; char* ret; pe_working_set_t* data_set; data_set = get_data_set(); cur = data_set->nodes; ret = strdup(MSG_OK); while (cur != NULL) { node = (node_t*) cur->data; ret = mgmt_msg_append(ret, node->details->uname); cur = g_list_next(cur); } free_data_set(data_set); return ret; } char* on_get_dc(char* argv[], int argc) { pe_working_set_t* data_set; data_set = get_data_set(); if (data_set->dc_node != NULL) { char* ret = strdup(MSG_OK); ret = mgmt_msg_append(ret, data_set->dc_node->details->uname); free_data_set(data_set); return ret; } free_data_set(data_set); return strdup(MSG_FAIL); } char* on_get_node_config(char* argv[], int argc) { node_t* node; GList* cur; pe_working_set_t* data_set; data_set = get_data_set(); cur = data_set->nodes; ARGC_CHECK(2); while (cur != NULL) { node = (node_t*) cur->data; if (strncmp(argv[1],node->details->uname,MAX_STRLEN) == 0) { char* ret = strdup(MSG_OK); ret = mgmt_msg_append(ret, node->details->uname); ret = mgmt_msg_append(ret, node->details->online?"True":"False"); ret = mgmt_msg_append(ret, node->details->standby?"True":"False"); ret = mgmt_msg_append(ret, node->details->unclean?"True":"False"); ret = mgmt_msg_append(ret, node->details->shutdown?"True":"False"); ret = mgmt_msg_append(ret, node->details->expected_up?"True":"False"); ret = mgmt_msg_append(ret, node->details->is_dc?"True":"False"); ret = mgmt_msg_append(ret, node->details->type==node_ping?"ping":"member"); ret = mgmt_msg_append(ret, node->details->pending?"True":"False"); ret = mgmt_msg_append(ret, node->details->standby_onfail?"True":"False"); free_data_set(data_set); return ret; } cur = g_list_next(cur); } free_data_set(data_set); return strdup(MSG_FAIL); } char* on_get_running_rsc(char* argv[], int argc) { node_t* node; GList* cur; pe_working_set_t* data_set; data_set = get_data_set(); cur = data_set->nodes; ARGC_CHECK(2); while (cur != NULL) { node = (node_t*) cur->data; /*if (node->details->online) {*/ if (strncmp(argv[1],node->details->uname,MAX_STRLEN) == 0) { GList* cur_rsc; char* ret = strdup(MSG_OK); cur_rsc = node->details->running_rsc; while(cur_rsc != NULL) { resource_t* rsc = (resource_t*)cur_rsc->data; ret = mgmt_msg_append(ret, rsc->id); cur_rsc = g_list_next(cur_rsc); } free_data_set(data_set); return ret; } /*}*/ cur = g_list_next(cur); } free_data_set(data_set); return strdup(MSG_FAIL); } char* on_migrate_rsc(char* argv[], int argc) { const char* id = NULL; char cmd[MAX_STRLEN]; char buf[MAX_STRLEN]; pe_working_set_t* data_set; resource_t* rsc; char* ret = NULL; const char* duration_regex = "^[A-Za-z0-9:-]+$"; FILE *fstream = NULL; ARGC_CHECK(5) data_set = get_data_set(); GET_RESOURCE() free_data_set(data_set); snprintf(cmd, sizeof(cmd), "crm_resource -M -r %s", argv[1]); if (STRNCMP_CONST(argv[2], "") != 0){ id = uname2id(argv[2]); if (id == NULL) { return strdup(MSG_FAIL"\nNo such node"); } else{ strncat(cmd, " -H ", sizeof(cmd)-strlen(cmd)-1); strncat(cmd, argv[2], sizeof(cmd)-strlen(cmd)-1); } } if (STRNCMP_CONST(argv[3], "true") == 0){ strncat(cmd, " -f", sizeof(cmd)-strlen(cmd)-1); } if (STRNCMP_CONST(argv[4], "") != 0){ if (regex_match(duration_regex, argv[4])) { strncat(cmd, " -u \"", sizeof(cmd)-strlen(cmd)-1); strncat(cmd, argv[4], sizeof(cmd)-strlen(cmd)-1); strncat(cmd, "\"", sizeof(cmd)-strlen(cmd)-1); } else { mgmt_log(LOG_ERR, "invalid duration specified: \"%s\"", argv[1]); return strdup(MSG_FAIL"\nInvalid duration.\nPlease refer to " "http://en.wikipedia.org/wiki/ISO_8601#Duration for examples of valid durations"); } } strncat(cmd, " 2>&1", sizeof(cmd)-strlen(cmd)-1); if ((fstream = popen(cmd, "r")) == NULL){ mgmt_log(LOG_ERR, "error on popen %s: %s", cmd, strerror(errno)); return strdup(MSG_FAIL"\nMigrate failed"); } ret = strdup(MSG_FAIL); while (!feof(fstream)){ memset(buf, 0, sizeof(buf)); if (fgets(buf, sizeof(buf), fstream) != NULL){ ret = mgmt_msg_append(ret, buf); ret[strlen(ret)-1] = '\0'; } else{ sleep(1); } } if (pclose(fstream) == -1) mgmt_log(LOG_WARNING, "failed to close pipe"); return ret; } char* on_set_node_standby(char* argv[], int argc) { int rc; const char* id = NULL; const char* attr_value = NULL; ARGC_CHECK(3); id = uname2id(argv[1]); if (id == NULL) { return strdup(MSG_FAIL"\nNo such node"); } if (STRNCMP_CONST(argv[2], "on") == 0 || STRNCMP_CONST(argv[2], "true") == 0){ attr_value = "true"; } else if (STRNCMP_CONST(argv[2], "off") == 0 || STRNCMP_CONST(argv[2], "false") == 0){ attr_value = "false"; } else{ return strdup(MSG_FAIL"\nInvalid attribute value"); } rc = set_standby(cib_conn, id, NULL, attr_value); if (rc < 0) { return crm_failed_msg(NULL, rc); } return strdup(MSG_OK); } /* char* on_set_node_standby(char* argv[], int argc) { int rc; const char* id = NULL; crm_data_t* fragment = NULL; crm_data_t* cib_object = NULL; crm_data_t* output = NULL; char xml[MAX_STRLEN]; ARGC_CHECK(3); id = uname2id(argv[1]); if (id == NULL) { return strdup(MSG_FAIL"\nno such node"); } snprintf(xml, MAX_STRLEN, "" "" "", id, id, id, argv[2]); cib_object = string2xml(xml); if(cib_object == NULL) { return strdup(MSG_FAIL); } fragment = create_cib_fragment(cib_object, "nodes"); mgmt_log(LOG_INFO, "(update)xml:%s",xml); rc = cib_conn->cmds->update( cib_conn, "nodes", fragment, cib_sync_call); free_xml(fragment); free_xml(cib_object); if (rc < 0) { return crm_failed_msg(output, rc); } free_xml(output); return strdup(MSG_OK); } */ /* resource functions */ static int delete_lrm_rsc(crm_ipc_t *crmd_channel, const char *host_uname, const char *rsc_id) { crm_data_t *cmd = NULL; crm_data_t *msg_data = NULL; crm_data_t *rsc = NULL; crm_data_t *params = NULL; char our_pid[11]; char *key = NULL; snprintf(our_pid, 10, "%d", getpid()); our_pid[10] = '\0'; key = crm_concat(client_name, our_pid, '-'); msg_data = create_xml_node(NULL, XML_GRAPH_TAG_RSC_OP); crm_xml_add(msg_data, XML_ATTR_TRANSITION_KEY, key); rsc = create_xml_node(msg_data, XML_CIB_TAG_RESOURCE); crm_xml_add(rsc, XML_ATTR_ID, rsc_id); params = create_xml_node(msg_data, XML_TAG_ATTRS); crm_xml_add(params, XML_ATTR_CRM_VERSION, CRM_FEATURE_SET); cmd = create_request(CRM_OP_LRM_DELETE, msg_data, host_uname, CRM_SYSTEM_CRMD, client_name, our_pid); free_xml(msg_data); free(key); #if !HAVE_CRM_IPC_NEW if(send_ipc_message(crmd_channel, cmd)) { #else if(crm_ipc_send(crmd_channel, cmd, 0, 0, NULL)){ #endif free_xml(cmd); return 0; } free_xml(cmd); return -1; } static int refresh_lrm(crm_ipc_t *crmd_channel, const char *host_uname) { crm_data_t *cmd = NULL; char our_pid[11]; snprintf(our_pid, 10, "%d", getpid()); our_pid[10] = '\0'; cmd = create_request(CRM_OP_LRM_REFRESH, NULL, host_uname, CRM_SYSTEM_CRMD, client_name, our_pid); #if !HAVE_CRM_IPC_NEW if(send_ipc_message(crmd_channel, cmd)) { #else if(crm_ipc_send(crmd_channel, cmd, 0, 0, NULL)){ #endif free_xml(cmd); return 0; } free_xml(cmd); return -1; } char* on_cleanup_rsc(char* argv[], int argc) { crm_ipc_t *crmd_channel = NULL; char our_pid[11]; char *now_s = NULL; time_t now = time(NULL); char *dest_node = NULL; int rc; char *buffer = NULL; ARGC_CHECK(3); snprintf(our_pid, 10, "%d", getpid()); our_pid[10] = '\0'; #if !HAVE_CRM_IPC_NEW init_client_ipc_comms(CRM_SYSTEM_CRMD, NULL, NULL, &crmd_channel); send_hello_message(crmd_channel, our_pid, client_name, "0", "1"); #else crmd_channel = crm_ipc_new(CRM_SYSTEM_CRMD, 0); if (crmd_channel && crm_ipc_connect(crmd_channel)) { xmlNode *hello = NULL; hello = create_hello_message(our_pid, client_name, "0", "1"); rc = crm_ipc_send(crmd_channel, hello, 0, 0, NULL); free_xml(hello); } else { rc = -ENOTCONN; } if (rc < 0) { if (crmd_channel) { crm_ipc_close(crmd_channel); crm_ipc_destroy(crmd_channel); } mgmt_log(LOG_ERR, "Error signing on to the CRMd service: %s", pcmk_strerror(rc)); return strdup(MSG_FAIL"\nError signing on to the CRMd service"); } #endif delete_lrm_rsc(crmd_channel, argv[1], argv[2]); refresh_lrm(crmd_channel, NULL); rc = query_node_uuid(cib_conn, argv[1], &dest_node); if (rc != 0) { mgmt_log(LOG_WARNING, "Could not map uname=%s to a UUID: %s\n", argv[1], pcmk_strerror(rc)); } else { buffer = crm_concat("fail-count", argv[2], '-'); #if !HAVE_UPDATE_ATTR_DELEGATE delete_attr(cib_conn, cib_sync_call, XML_CIB_TAG_STATUS, dest_node, NULL, NULL, NULL, buffer, NULL, FALSE); #else delete_attr_delegate(cib_conn, cib_sync_call, XML_CIB_TAG_STATUS, dest_node, NULL, NULL, NULL, buffer, NULL, FALSE, NULL); #endif free(dest_node); free(buffer); mgmt_log(LOG_INFO, "Delete fail-count for %s from %s", argv[2], argv[1]); } /* force the TE to start a transition */ sleep(2); /* wait for the refresh */ now_s = crm_itoa(now); #if !HAVE_UPDATE_ATTR_DELEGATE update_attr(cib_conn, cib_sync_call, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL, "last-lrm-refresh", now_s, FALSE); #else update_attr_delegate(cib_conn, cib_sync_call, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL, "last-lrm-refresh", now_s, FALSE, NULL); #endif free(now_s); #if !HAVE_CRM_IPC_NEW crmd_channel->ops->destroy(crmd_channel); #else if (crmd_channel) { crm_ipc_close(crmd_channel); crm_ipc_destroy(crmd_channel); } #endif return strdup(MSG_OK); } /* get all resources*/ char* on_get_all_rsc(char* argv[], int argc) { GList* cur; char* ret; pe_working_set_t* data_set; data_set = get_data_set(); ret = strdup(MSG_OK); cur = data_set->resources; while (cur != NULL) { resource_t* rsc = (resource_t*)cur->data; if(is_not_set(rsc->flags, pe_rsc_orphan) || rsc->role != RSC_ROLE_STOPPED) { ret = mgmt_msg_append(ret, rsc->id); } cur = g_list_next(cur); } free_data_set(data_set); return ret; } /* basic information of resource */ char* on_get_rsc_running_on(char* argv[], int argc) { resource_t* rsc; char* ret; GList* cur; pe_working_set_t* data_set; data_set = get_data_set(); GET_RESOURCE() ret = strdup(MSG_OK); cur = rsc->running_on; while (cur != NULL) { node_t* node = (node_t*)cur->data; ret = mgmt_msg_append(ret, node->details->uname); cur = g_list_next(cur); } free_data_set(data_set); return ret; } char* on_get_rsc_status(char* argv[], int argc) { resource_t* rsc; char* ret; pe_working_set_t* data_set; char* num_s; char buf[MAX_STRLEN]; data_set = get_data_set(); GET_RESOURCE() ret = strdup(MSG_OK); switch (rsc->variant) { case pe_unknown: ret = mgmt_msg_append(ret, "unknown"); break; case pe_native: memset(buf, 0, sizeof(buf)); if(is_not_set(rsc->flags, pe_rsc_managed)) { strncat(buf, "unmanaged", sizeof(buf)-strlen(buf)-1); } else if(is_set(rsc->flags, pe_rsc_failed)) { strncat(buf, "failed", sizeof(buf)-strlen(buf)-1); } else if (g_list_length(rsc->running_on) > 0 && rsc->fns->active(rsc, TRUE) == FALSE) { strncat(buf, "unclean", sizeof(buf)-strlen(buf)-1); } else if (g_list_length(rsc->running_on) == 0) { strncat(buf, "not running", sizeof(buf)-strlen(buf)-1); } else if (g_list_length(rsc->running_on) > 1) { strncat(buf, "multi-running", sizeof(buf)-strlen(buf)-1); } else if(is_set(rsc->flags, pe_rsc_start_pending)) { strncat(buf, "starting", sizeof(buf)-strlen(buf)-1); } else if(rsc->role == RSC_ROLE_MASTER) { strncat(buf, "running (Master)", sizeof(buf)-strlen(buf)-1); } else if(rsc->role == RSC_ROLE_SLAVE) { strncat(buf, "running (Slave)", sizeof(buf)-strlen(buf)-1); } else if(rsc->role == RSC_ROLE_STARTED) { strncat(buf, "running", sizeof(buf)-strlen(buf)-1); } else { strncat(buf, role2text(rsc->role), sizeof(buf)-strlen(buf)-1); } if(is_set(rsc->flags, pe_rsc_orphan)) { strncat(buf, " (orphaned)", sizeof(buf)-strlen(buf)-1); } if(is_set(rsc->flags, pe_rsc_failure_ignored)) { strncat(buf, " (failure ignored)", sizeof(buf)-strlen(buf)-1); } ret = mgmt_msg_append(ret, buf); break; case pe_group: ret = mgmt_msg_append(ret, "group"); break; case pe_clone: ret = mgmt_msg_append(ret, "clone"); break; case pe_master: ret = mgmt_msg_append(ret, "master"); break; } num_s = crm_itoa(rsc->migration_threshold); ret = mgmt_msg_append(ret, num_s); free(num_s); free_data_set(data_set); return ret; } char* on_get_rsc_type(char* argv[], int argc) { resource_t* rsc; char* ret; pe_working_set_t* data_set; data_set = get_data_set(); GET_RESOURCE() ret = strdup(MSG_OK); switch (rsc->variant) { case pe_unknown: ret = mgmt_msg_append(ret, "unknown"); break; case pe_native: ret = mgmt_msg_append(ret, "native"); break; case pe_group: ret = mgmt_msg_append(ret, "group"); break; case pe_clone: ret = mgmt_msg_append(ret, "clone"); break; case pe_master: ret = mgmt_msg_append(ret, "master"); break; } free_data_set(data_set); return ret; } char* on_op_status2str(char* argv[], int argc) { int op_status; char* ret = strdup(MSG_OK); ARGC_CHECK(2); op_status = atoi(argv[1]); #if !HAVE_DECL_SERVICES_LRM_STATUS_STR ret = mgmt_msg_append(ret, op_status2text(op_status)); #else ret = mgmt_msg_append(ret, services_lrm_status_str(op_status)); #endif return ret; } char* on_get_sub_rsc(char* argv[], int argc) { resource_t* rsc; char* ret; GList* cur = NULL; pe_working_set_t* data_set; data_set = get_data_set(); GET_RESOURCE() cur = rsc->children; ret = strdup(MSG_OK); while (cur != NULL) { resource_t* rsc = (resource_t*)cur->data; gboolean is_active = rsc->fns->active(rsc, TRUE); if (is_not_set(rsc->flags, pe_rsc_orphan) || is_active) { ret = mgmt_msg_append(ret, rsc->id); } cur = g_list_next(cur); } free_data_set(data_set); return ret; } char* on_crm_rsc_cmd(char* argv[], int argc) { char cmd[MAX_STRLEN]; pe_working_set_t* data_set; resource_t* rsc; char* ret = NULL; FILE* fstream = NULL; char buf[MAX_STRLEN]; ARGC_CHECK(4) if (STRNCMP_CONST(argv[2], "refresh") == 0){ strncpy(cmd, "crm_resource -R", sizeof(cmd)-1) ; } else if (STRNCMP_CONST(argv[2], "reprobe") == 0){ strncpy(cmd, "crm_resource -P", sizeof(cmd)-1) ; } else if (STRNCMP_CONST(argv[2], "cleanup") == 0){ strncpy(cmd, "crm_resource -C", sizeof(cmd)-1) ; } else if (STRNCMP_CONST(argv[2], "fail") == 0){ strncpy(cmd, "crm_resource -F", sizeof(cmd)-1) ; } else{ return strdup(MSG_FAIL"\nNo such command"); } if (strlen(argv[1]) > 0){ data_set = get_data_set(); GET_RESOURCE() free_data_set(data_set); strncat(cmd, " -r ", sizeof(cmd)-strlen(cmd)-1); strncat(cmd, argv[1], sizeof(cmd)-strlen(cmd)-1); } if (strlen(argv[3]) > 0){ if (uname2id(argv[3]) == NULL){ return strdup(MSG_FAIL"\nNo such node"); } else{ strncat(cmd, " -H ", sizeof(cmd)-strlen(cmd)-1); strncat(cmd, argv[3], sizeof(cmd)-strlen(cmd)-1); } } strncat(cmd, " 2>&1", sizeof(cmd)-strlen(cmd)-1); if ((fstream = popen(cmd, "r")) == NULL){ mgmt_log(LOG_ERR, "error on popen %s: %s", cmd, strerror(errno)); return strdup(MSG_FAIL"\nDo crm_resource command failed"); } ret = strdup(MSG_FAIL); while (!feof(fstream)){ memset(buf, 0, sizeof(buf)); if (fgets(buf, sizeof(buf), fstream) != NULL){ ret = mgmt_msg_append(ret, buf); ret[strlen(ret)-1] = '\0'; } else{ sleep(1); } } if (pclose(fstream) == -1){ mgmt_log(LOG_WARNING, "failed to close pipe"); } return ret; } char* on_set_rsc_attr(char* argv[], int argc) { char cmd[MAX_STRLEN]; char buf[MAX_STRLEN]; pe_working_set_t* data_set; resource_t* rsc; char* ret = NULL; const char* nv_regex = "^[A-Za-z0-9_-]+$"; FILE *fstream = NULL; ARGC_CHECK(5) data_set = get_data_set(); GET_RESOURCE() free_data_set(data_set); if (STRNCMP_CONST(argv[2], "meta") == 0){ snprintf(cmd, sizeof(cmd), "crm_resource --meta -r %s", argv[1]); } else{ snprintf(cmd, sizeof(cmd), "crm_resource -r %s", argv[1]); } if (regex_match(nv_regex, argv[3])) { strncat(cmd, " -p \"", sizeof(cmd)-strlen(cmd)-1); strncat(cmd, argv[3], sizeof(cmd)-strlen(cmd)-1); strncat(cmd, "\"", sizeof(cmd)-strlen(cmd)-1); } else { mgmt_log(LOG_ERR, "invalid attribute name specified: \"%s\"", argv[3]); return strdup(MSG_FAIL"\nInvalid attribute name"); } if (regex_match(nv_regex, argv[4])) { strncat(cmd, " -v \"", sizeof(cmd)-strlen(cmd)-1); strncat(cmd, argv[4], sizeof(cmd)-strlen(cmd)-1); strncat(cmd, "\"", sizeof(cmd)-strlen(cmd)-1); } else { mgmt_log(LOG_ERR, "invalid attribute value specified: \"%s\"", argv[4]); return strdup(MSG_FAIL"\nInvalid attribute value"); } strncat(cmd, " 2>&1", sizeof(cmd)-strlen(cmd)-1); if ((fstream = popen(cmd, "r")) == NULL){ mgmt_log(LOG_ERR, "error on popen %s: %s", cmd, strerror(errno)); return strdup(MSG_FAIL"\nSet the named attribute failed"); } ret = strdup(MSG_FAIL); while (!feof(fstream)){ memset(buf, 0, sizeof(buf)); if (fgets(buf, sizeof(buf), fstream) != NULL){ ret = mgmt_msg_append(ret, buf); ret[strlen(ret)-1] = '\0'; } else{ sleep(1); } } if (pclose(fstream) == -1) mgmt_log(LOG_WARNING, "failed to close pipe"); return ret; } char* on_get_rsc_attr(char* argv[], int argc) { char cmd[MAX_STRLEN]; char buf[MAX_STRLEN]; pe_working_set_t* data_set; resource_t* rsc; char* ret = NULL; const char* nv_regex = "^[A-Za-z0-9_-]+$"; FILE *fstream = NULL; ARGC_CHECK(4) data_set = get_data_set(); GET_RESOURCE() free_data_set(data_set); if (STRNCMP_CONST(argv[2], "meta") == 0){ snprintf(cmd, sizeof(cmd), "crm_resource --meta -r %s", argv[1]); } else{ snprintf(cmd, sizeof(cmd), "crm_resource -r %s", argv[1]); } if (regex_match(nv_regex, argv[3])) { strncat(cmd, " -g \"", sizeof(cmd)-strlen(cmd)-1); strncat(cmd, argv[3], sizeof(cmd)-strlen(cmd)-1); strncat(cmd, "\"", sizeof(cmd)-strlen(cmd)-1); } else { mgmt_log(LOG_ERR, "invalid attribute name specified: \"%s\"", argv[3]); return strdup(MSG_FAIL"\nInvalid attribute name"); } if ((fstream = popen(cmd, "r")) == NULL){ mgmt_log(LOG_ERR, "error on popen %s: %s", cmd, strerror(errno)); return strdup(MSG_FAIL"\nGet the named attribute failed"); } ret = strdup(MSG_OK); while (!feof(fstream)){ memset(buf, 0, sizeof(buf)); if (fgets(buf, sizeof(buf), fstream) != NULL){ ret = mgmt_msg_append(ret, buf); ret[strlen(ret)-1] = '\0'; } else{ sleep(1); } } if (pclose(fstream) == -1) mgmt_log(LOG_WARNING, "failed to close pipe"); return ret; } char* on_del_rsc_attr(char* argv[], int argc) { char cmd[MAX_STRLEN]; char buf[MAX_STRLEN]; pe_working_set_t* data_set; resource_t* rsc; char* ret = NULL; const char* nv_regex = "^[A-Za-z0-9_-]+$"; FILE *fstream = NULL; ARGC_CHECK(4) data_set = get_data_set(); GET_RESOURCE() free_data_set(data_set); if (STRNCMP_CONST(argv[2], "meta") == 0){ snprintf(cmd, sizeof(cmd), "crm_resource --meta -r %s", argv[1]); } else{ snprintf(cmd, sizeof(cmd), "crm_resource -r %s", argv[1]); } if (regex_match(nv_regex, argv[3])) { strncat(cmd, " -d \"", sizeof(cmd)-strlen(cmd)-1); strncat(cmd, argv[3], sizeof(cmd)-strlen(cmd)-1); strncat(cmd, "\"", sizeof(cmd)-strlen(cmd)-1); } else { mgmt_log(LOG_ERR, "invalid attribute name specified: \"%s\"", argv[3]); return strdup(MSG_FAIL"\nInvalid attribute name"); } strncat(cmd, " 2>&1", sizeof(cmd)-strlen(cmd)-1); if ((fstream = popen(cmd, "r")) == NULL){ mgmt_log(LOG_ERR, "error on popen %s: %s", cmd, strerror(errno)); return strdup(MSG_FAIL"\nGet the named attribute failed"); } ret = strdup(MSG_FAIL); while (!feof(fstream)){ memset(buf, 0, sizeof(buf)); if (fgets(buf, sizeof(buf), fstream) != NULL){ ret = mgmt_msg_append(ret, buf); ret[strlen(ret)-1] = '\0'; } else{ sleep(1); } } if (pclose(fstream) == -1) mgmt_log(LOG_WARNING, "failed to close pipe"); return ret; } char* on_cib_create(char* argv[], int argc) { int rc; crm_data_t* cib_object = NULL; crm_data_t* output = NULL; const char* type = NULL; const char* xmls = NULL; ARGC_CHECK(3) type = argv[1]; xmls = argv[2]; cib_object = string2xml(xmls); if (cib_object == NULL) { return strdup(MSG_FAIL); } mgmt_log(LOG_INFO, "CIB create: %s", type); rc = cib_conn->cmds->create(cib_conn, type, cib_object, cib_sync_call); free_xml(cib_object); if (rc < 0) { return crm_failed_msg(output, rc); } else { free_xml(output); return strdup(MSG_OK); } } /* char* on_cib_query(char* argv[], int argc) { const char* type = NULL; char cmd[MAX_STRLEN]; char buf[MAX_STRLEN]; char str[MAX_STRLEN]; char* ret = strdup(MSG_OK); FILE *fstream = NULL; ARGC_CHECK(2) type = argv[1]; mgmt_log(LOG_INFO, "CIB query: %s", type); snprintf(cmd, sizeof(cmd), "cibadmin -Q -o %s", type); if ((fstream = popen(cmd, "r")) == NULL){ mgmt_log(LOG_ERR, "error on popen %s: %s", cmd, strerror(errno)); return strdup(MSG_FAIL); } gen_msg_from_fstream(fstream, ret, buf, str); if (pclose(fstream) == -1) mgmt_log(LOG_WARNING, "failed to close pipe"); return ret; } */ char* on_cib_query(char* argv[], int argc) { int rc; crm_data_t* output = NULL; const char* type = NULL; char* ret = NULL; char* buffer = NULL; CIB_CHECK() ARGC_CHECK(2) type = argv[1]; mgmt_log(LOG_INFO, "CIB query: %s", type); rc = cib_conn->cmds->query(cib_conn, type, &output, cib_sync_call|cib_scope_local); if (rc < 0) { return crm_failed_msg(output, rc); } else { ret = strdup(MSG_OK); buffer = dump_xml_formatted(output); ret = mgmt_msg_append(ret, buffer); #if 0 mgmt_log(LOG_INFO, "%s", buffer); #endif free(buffer); free_xml(output); return ret; } } char* on_cib_update(char* argv[], int argc) { int rc; crm_data_t* fragment = NULL; crm_data_t* cib_object = NULL; crm_data_t* output = NULL; const char* type = NULL; const char* xmls = NULL; ARGC_CHECK(3) type = argv[1]; xmls = argv[2]; cib_object = string2xml(xmls); if (cib_object == NULL) { return strdup(MSG_FAIL); } mgmt_log(LOG_INFO, "CIB update: %s", xmls); fragment = create_cib_fragment(cib_object, type); rc = cib_conn->cmds->update(cib_conn, type, fragment, cib_sync_call); free_xml(fragment); free_xml(cib_object); if (rc < 0) { return crm_failed_msg(output, rc); } else { free_xml(output); return strdup(MSG_OK); } } char* on_cib_replace(char* argv[], int argc) { int rc; /*crm_data_t* fragment = NULL;*/ crm_data_t* cib_object = NULL; crm_data_t* output = NULL; const char* type = NULL; const char* xmls = NULL; ARGC_CHECK(3) type = argv[1]; xmls = argv[2]; cib_object = string2xml(xmls); if (cib_object == NULL) { return strdup(MSG_FAIL); } mgmt_log(LOG_INFO, "CIB replace: %s", type); /*fragment = create_cib_fragment(cib_object, type);*/ rc = cib_conn->cmds->replace(cib_conn, type, cib_object, cib_sync_call); /*free_xml(fragment);*/ free_xml(cib_object); if (rc < 0) { return crm_failed_msg(output, rc); } else { free_xml(output); return strdup(MSG_OK); } } char* on_cib_delete(char* argv[], int argc) { int rc; crm_data_t* cib_object = NULL; crm_data_t* output = NULL; const char* type = NULL; const char* xmls = NULL; ARGC_CHECK(3) type = argv[1]; xmls = argv[2]; cib_object = string2xml(xmls); if (cib_object == NULL) { return strdup(MSG_FAIL); } mgmt_log(LOG_INFO, "CIB delete: %s", type); rc = cib_conn->cmds->delete(cib_conn, type, cib_object, cib_sync_call); free_xml(cib_object); if (rc < 0) { return crm_failed_msg(output, rc); } else { free_xml(output); return strdup(MSG_OK); } } static char* on_gen_cluster_report(char* argv[], int argc) { char cmd[MAX_STRLEN]; char buf[MAX_STRLEN]; char str[MAX_STRLEN]; char filename[MAX_STRLEN]; const char *tempdir = "/tmp"; char *dest = tempnam(tempdir, "clrp."); struct stat statbuf; char *ret = NULL; FILE *fstream = NULL; const char* date_regex = \ "^[0-9]{4}-[0-1][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]$"; ARGC_CHECK(3); if (regex_match(date_regex, argv[1])) { snprintf(buf, sizeof(buf), "-f \"%s\"", argv[1]); } else { mgmt_log(LOG_ERR, "cluster_report: invalid \"from\" date expression: \"%s\"", argv[1]); free(dest); return strdup(MSG_FAIL"\nInvalid \"from\" date expression"); } if (strnlen(argv[2], MAX_STRLEN) != 0) { if (regex_match(date_regex, argv[2])) { strncat(buf, " -t \"", sizeof(buf)-strlen(buf)-1); strncat(buf, argv[2], sizeof(buf)-strlen(buf)-1); strncat(buf, "\"", sizeof(buf)-strlen(buf)-1); } else { mgmt_log(LOG_ERR, "cluster_report: invalid \"to\" date expression: \"%s\"", argv[2]); free(dest); return strdup(MSG_FAIL"\nInvalid \"to\" date expression"); } } if (is_openais_cluster()){ snprintf(cmd, sizeof(cmd), "hb_report -ADC %s %s", buf, dest); } else{ snprintf(cmd, sizeof(cmd), "hb_report -DC %s %s", buf, dest); } mgmt_log(LOG_INFO, "cluster_report: %s", cmd); if (system(cmd) < 0) { mgmt_log(LOG_ERR, "cluster_report: error on system \"%s\": %s", cmd, strerror(errno)); free(dest); return strdup(MSG_FAIL"\nError on execute the cluster report command"); } snprintf(filename, sizeof(filename), "%s.tar.bz2", dest); if (stat(filename, &statbuf) < 0){ snprintf(filename, sizeof(filename), "%s.tar.gz", dest); if (stat(filename, &statbuf) < 0){ free(dest); mgmt_log(LOG_WARNING, "cluster_report: cannot stat the report file"); mgmt_log(LOG_ERR, "cluster_report: failed to generate a cluster report"); return strdup(MSG_FAIL"\nFailed to generate a cluster report"); } } free(dest); mgmt_log(LOG_INFO, "cluster_report: successfully generated the cluster report"); snprintf(cmd, sizeof(cmd), "/usr/bin/base64 %s", filename); if ((fstream = popen(cmd, "r")) == NULL) { mgmt_log(LOG_ERR, "cluster_report: error on popen \"%s\": %s", cmd, strerror(errno)); unlink(filename); return strdup(MSG_FAIL"\nFailed to encode the cluster report to base64"); } ret = strdup(MSG_OK); ret = mgmt_msg_append(ret, filename); gen_msg_from_fstream(fstream, ret, buf, str); if (pclose(fstream) == -1){ mgmt_log(LOG_WARNING, "cluster_report: failed to close pipe"); } mgmt_log(LOG_INFO, "cluster_report: send out the report"); unlink(filename); return ret; } #ifdef PE_STATE_DIR static const char* pe_state_dir = PE_STATE_DIR; #else static const char* pe_state_dir = HA_VARLIBHBDIR"/pengine"; #endif typedef struct pe_series_s { const char *name; const char *param; int wrap; } pe_series_t; pe_series_t pe_series[] = { { "pe-unknown", "_dont_match_anything_", -1 }, { "pe-error", "pe-error-series-max", -1, }, { "pe-warn", "pe-warn-series-max", 200, }, { "pe-input", "pe-input-series-max", 400, }, }; #define get_seq(seq, last, max, offset, new_seq) \ if (max > 0) { \ if (seq <= last) { \ if (seq + offset > last) { \ new_seq = -1; \ } else if (seq + offset <= 0 && seq + offset + max > last) { \ new_seq += max; \ } else { \ new_seq = seq + offset; \ } \ } else { \ if (seq + offset <= last) { \ new_seq = -1; \ } else if (seq + offset > max && seq + offset - max <= last) { \ new_seq -= max; \ } else { \ new_seq = seq + offset; \ } \ } \ } else { \ new_seq = seq + offset; \ } #define get_mid_seq(first, last, max, mid) \ if (max > 0 && first > last) { \ mid = (first + last + max) / 2; \ if (mid > max) { \ mid -= max; \ } \ } else { \ mid = (first + last) / 2; \ } #define seq_lt(seq1, seq2, last, max, is_lt) \ if (max > 0) { \ if (seq1 > last && seq2 <= last) { \ is_lt = (seq1 - max < seq2); \ } else if (seq1 <= last && seq2 > last) { \ is_lt = (seq1 < seq2 - max); \ } else { \ is_lt = (seq1 < seq2); \ } \ } else { \ is_lt = (seq1 < seq2); \ } static char* on_get_pe_inputs(char* argv[], int argc) { char* ret = NULL; time_t from_time = -1; time_t to_time = -1; pe_working_set_t* data_set; int i = 0; int wrap = -1; char* value = NULL; int last_seq = -1; int start_seq = -1; int end_seq = -1; int first = -1; int last = -1; int from_seq = -1; int to_seq = -1; int mid = -1; char* filename = NULL; struct stat statbuf; int stat_rc = -1; int try_count = 0; int is_lt = 0; int seq = 0; char info[MAX_STRLEN]; char buf[MAX_STRLEN]; int compress = TRUE; ARGC_CHECK(3); if (STRNCMP_CONST(argv[1], "") != 0) { from_time = crm_int_helper(argv[1], NULL); } if (STRNCMP_CONST(argv[2], "") != 0) { to_time = crm_int_helper(argv[2], NULL); } if (from_time >= 0 && to_time >= 0 && from_time > to_time) { return strdup(MSG_FAIL"\n\"From\" time should be earlier than \"To\" time"); } data_set = get_data_set(); ret = strdup(MSG_OK); for (i = 0; i < 4 ; i++) { wrap = pe_series[i].wrap; if (data_set != NULL && data_set->config_hash != NULL) { value = g_hash_table_lookup(data_set->config_hash, pe_series[i].param); if (value != NULL) { wrap = crm_int_helper(value, NULL); } } last_seq = get_last_sequence(pe_state_dir, pe_series[i].name); if (wrap > 0) { for (compress = 1, stat_rc = -1; compress >= 0; compress--) { filename = generate_series_filename( pe_state_dir, pe_series[i].name, last_seq, compress); stat_rc = stat(filename, &statbuf); free(filename); if (stat_rc == 0) { break; } } if (stat_rc == 0) { start_seq = last_seq; if (last_seq == 1) { end_seq = wrap; } else { end_seq = last_seq -1; } } else { start_seq = 0; end_seq = last_seq - 1; } } else { start_seq = 0; end_seq = last_seq - 1; } if (end_seq < 0) { continue; } first = start_seq; last = end_seq; mid = first; try_count = 50; while (first != last && try_count > 0) { for (compress = 1, stat_rc = -1; compress >= 0; compress--) { filename = generate_series_filename( pe_state_dir, pe_series[i].name, mid, compress); stat_rc = stat(filename, &statbuf); free(filename); if (stat_rc == 0) { break; } } if (stat_rc == 0 && from_time < 0) { first = mid; break; } if (stat_rc < 0 || statbuf.st_mtime < from_time) { if (mid == last) { first = mid; } else { get_seq(mid, end_seq, wrap, 1, first); } } else { last = mid; } get_mid_seq(first, last, wrap, mid); try_count--; } from_seq = first; first = start_seq; last = end_seq; mid = last; try_count = 50; while (first != last && try_count > 0) { for (compress = 1, stat_rc = -1; compress >= 0; compress--) { filename = generate_series_filename( pe_state_dir, pe_series[i].name, mid, compress); stat_rc = stat(filename, &statbuf); free(filename); if (stat_rc == 0) { break; } } if (stat_rc == 0 && to_time < 0) { last = mid; break; } if (stat_rc < 0 || statbuf.st_mtime <= to_time) { if (mid == last) { first = mid; } else { get_seq(mid, end_seq, wrap, 1, first); } } else { last = mid; } get_mid_seq(first, last, wrap, mid); try_count--; } to_seq = last; memset(buf, 0, sizeof(buf)); seq_lt(from_seq, to_seq, end_seq, wrap, is_lt); seq = from_seq; while (seq >= 0 && (is_lt || seq == to_seq)) { for (compress = 1, stat_rc = -1; compress >= 0; compress--) { filename = generate_series_filename( pe_state_dir, pe_series[i].name, seq, compress); stat_rc = stat(filename, &statbuf); if (stat_rc == 0) { break; } else { free(filename); } } if (stat_rc == 0) { snprintf(info, sizeof(info), "%s %ld ", basename(filename), (long)statbuf.st_mtime); append_str(ret, buf, info); free(filename); } get_seq(seq, end_seq, wrap, 1, seq); seq_lt(seq, to_seq, end_seq, wrap, is_lt); } ret = mgmt_msg_append(ret, buf); } if (data_set != NULL) { free_data_set(data_set); } return ret; } static char* on_get_pe_summary(char* argv[], int argc) { char* ret = NULL; time_t time_stamp; char* filename = NULL; char info[MAX_STRLEN]; struct stat statbuf; int stat_rc = -1; int compress = TRUE; ARGC_CHECK(3) if (STRNCMP_CONST(argv[1], "live") == 0) { time(&time_stamp); snprintf(info, sizeof(info), "%ld", time_stamp); ret = strdup(MSG_OK); ret = mgmt_msg_append(ret, info); } else { for (compress = 1, stat_rc = -1; compress >= 0; compress--) { filename = generate_series_filename( pe_state_dir, argv[1], crm_int_helper(argv[2], NULL), compress); stat_rc = stat(filename, &statbuf); free(filename); if (stat_rc == 0) { break; } } if (stat_rc == 0) { snprintf(info, sizeof(info), "%ld", statbuf.st_mtime); ret = strdup(MSG_OK); ret = mgmt_msg_append(ret, info); } else { mgmt_log(LOG_WARNING, "Cannot stat the transition file \"%s/%s-%s.*\": %s", pe_state_dir, argv[1], argv[2], strerror(errno)); ret = strdup(MSG_FAIL"\nThe specified transition doesn't exist"); } } return ret; } static char* on_gen_pe_graph(char* argv[], int argc) { char* ret = NULL; char* filename = NULL; struct stat statbuf; int stat_rc = -1; char cmd[MAX_STRLEN]; char buf[MAX_STRLEN]; char str[MAX_STRLEN]; char *dotfile = NULL; FILE *fstream = NULL; int compress = TRUE; ARGC_CHECK(3) if (STRNCMP_CONST(argv[1], "live") == 0) { strncpy(cmd, "crm_simulate -L", sizeof(cmd)-1); } else { for (compress = 1, stat_rc = -1; compress >= 0; compress--) { filename = generate_series_filename( pe_state_dir, argv[1], crm_int_helper(argv[2], NULL), compress); stat_rc = stat(filename, &statbuf); if (stat_rc == 0) { break; } else { free(filename); } } if (stat_rc == 0) { snprintf(cmd, sizeof(cmd), "crm_simulate -x %s", filename); free(filename); } else { mgmt_log(LOG_WARNING, "Cannot stat the transition file \"%s/%s-%s.*\": %s", pe_state_dir, argv[1], argv[2], strerror(errno)); return strdup(MSG_FAIL"\nThe specified transition doesn't exist"); } } strncat(cmd, " -D ", sizeof(cmd)-strlen(cmd)-1); dotfile = tempnam("/tmp", "dot."); strncat(cmd, dotfile, sizeof(cmd)-strlen(cmd)-1); if (system(cmd) < 0){ mgmt_log(LOG_ERR, "error on execute \"%s\": %s", cmd, strerror(errno)); free(dotfile); return strdup(MSG_FAIL"\nError on execute the crm_simulate command"); } if ((fstream = fopen(dotfile, "r")) == NULL){ mgmt_log(LOG_ERR, "error on fopen %s: %s", dotfile, strerror(errno)); free(dotfile); unlink(dotfile); return strdup(MSG_FAIL"\nError on read the transition graph file"); } ret = strdup(MSG_OK); gen_msg_from_fstream(fstream, ret, buf, str); if (fclose(fstream) == -1){ mgmt_log(LOG_WARNING, "failed to fclose stream"); } unlink(dotfile); free(dotfile); return ret; } static char* on_gen_pe_info(char* argv[], int argc) { char* ret = NULL; char* filename = NULL; struct stat statbuf; int stat_rc = -1; char cmd[MAX_STRLEN]; int i; char buf[MAX_STRLEN]; char str[MAX_STRLEN]; FILE *fstream = NULL; int compress = TRUE; ARGC_CHECK(4) if (STRNCMP_CONST(argv[1], "live") == 0){ strncpy(cmd, "crm_simulate -L", sizeof(cmd)-1); } else { for (compress = 1, stat_rc = -1; compress >= 0; compress--) { filename = generate_series_filename( pe_state_dir, argv[1], crm_int_helper(argv[2], NULL), compress); stat_rc = stat(filename, &statbuf); if (stat_rc == 0) { break; } else { free(filename); } } if (stat_rc == 0) { snprintf(cmd, sizeof(cmd), "crm_simulate -x %s", filename); free(filename); } else { mgmt_log(LOG_WARNING, "Cannot stat the transition file \"%s/%s-%s.*\": %s", pe_state_dir, argv[1], argv[2], strerror(errno)); return strdup(MSG_FAIL"\nThe specified transition doesn't exist"); } } if (STRNCMP_CONST(argv[3], "scores") == 0) { strncat(cmd, " -s -Q", sizeof(cmd)-strlen(cmd)-1); } else { strncat(cmd, " -S", sizeof(cmd)-strlen(cmd)-1); for (i = 0; i < atoi(argv[3]); i++) { if (i == 0){ strncat(cmd, " -V", sizeof(cmd)-strlen(cmd)-1); } else{ strncat(cmd, "V", sizeof(cmd)-strlen(cmd)-1); } } } strncat(cmd, " 2>&1", sizeof(cmd)-strlen(cmd)-1); if ((fstream = popen(cmd, "r")) == NULL){ mgmt_log(LOG_ERR, "error on popen \"%s\": %s", cmd, strerror(errno)); return strdup(MSG_FAIL"\nError on popen the crm_simulate command"); } ret = strdup(MSG_OK); gen_msg_from_fstream(fstream, ret, buf, str); if (fclose(fstream) == -1){ mgmt_log(LOG_WARNING, "failed to fclose stream"); } return ret; } int regex_match(const char *regex, const char *str) { regex_t preg; int ret; if (regcomp(&preg, regex, REG_EXTENDED|REG_NOSUB) != 0){ mgmt_log(LOG_ERR, "error regcomp regular expression: \"%s\"", regex); return 0; } ret = regexec(&preg, str, 0, NULL, 0); if (ret != 0) { mgmt_log(LOG_WARNING, "no match or error regexec: \"%s\" \"%s\"", regex, str); } regfree(&preg); return (ret == 0); } pid_t popen2(const char *command, FILE **fp_in, FILE **fp_out) { int pfd_in[2]; int pfd_out[2]; pid_t pid; if (fp_in != NULL) { if (pipe(pfd_in) < 0) { return -1; /* errno set by pipe() */ } } if (fp_out != NULL) { if (pipe(pfd_out) < 0) { return -1; } } if ((pid = fork()) < 0) { return -1; /* errno set by fork() */ } else if (pid == 0) { /* child */ if (fp_in != NULL) { close(pfd_in[1]); if (pfd_in[0] != STDIN_FILENO) { dup2(pfd_in[0], STDIN_FILENO); close(pfd_in[0]); } } if (fp_out != NULL) { close(pfd_out[0]); if (pfd_out[1] != STDOUT_FILENO) { dup2(pfd_out[1], STDOUT_FILENO); close(pfd_out[1]); } } execl("/bin/sh", "sh", "-c", command, NULL); _exit(127); } /* parent continues... */ if (fp_in != NULL) { close(pfd_in[0]); if ((*fp_in = fdopen(pfd_in[1], "w")) == NULL) { return -1; } } if (fp_out != NULL) { close(pfd_out[1]); if ((*fp_out = fdopen(pfd_out[0], "r")) == NULL) { return -1; } } return pid; } int pclose2(FILE *fp_in, FILE *fp_out, pid_t pid) { int stat; if (fp_in != NULL && fclose(fp_in) != 0) { return -1; } if (fp_out != NULL && fclose(fp_out) != 0) { return -1; } while (waitpid(pid, &stat, 0) < 0) { if (errno != EINTR) return -1; /* error other than EINTR from waitpid() */ } return stat; /* return child's termination status */ } pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/daemon/mgmt_hb.c000066400000000000000000000106201211477743100232740ustar00rootroot00000000000000/* * Linux HA management library * * Author: Huang Zhen * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include "mgmt_internal.h" int init_heartbeat(void); void final_heartbeat(void); static ll_cluster_t * hb = NULL; static char* on_get_allnodes(char* argv[], int argc); static char* on_get_hb_config(char* argv[], int argc); static char* on_get_nodetype(char* argv[], int argc); static gboolean on_hb_input(ll_cluster_t* hb, gpointer data); static char* on_echo(char* argv[], int argc); static void on_hb_quit(gpointer); char* hb_config = NULL; const char* param_name[] = { "quorum_server", "use_logd", "autojoin", "apiauth", "auto_failback", "baud", "debug", "debugfile", "deadping", "deadtime", "hbversion", "hopfudge", "initdead", "keepalive", "logfacility", "logfile", "msgfmt", "nice_failback", "node", "normalpoll", "stonith", "udpport", "warntime", "watchdog", "cluster" }; char* on_get_allnodes(char* argv[], int argc) { const char* name = NULL; char* ret = strdup(MSG_OK); if (hb->llc_ops->init_nodewalk(hb) != HA_OK) { mgmt_log(LOG_ERR, "Cannot start node walk"); mgmt_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb)); free(ret); return strdup(MSG_FAIL); } while((name = hb->llc_ops->nextnode(hb))!= NULL) { ret = mgmt_msg_append(ret, name); } if (hb->llc_ops->end_nodewalk(hb) != HA_OK) { mgmt_log(LOG_ERR, "Cannot end node walk"); mgmt_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb)); free(ret); return strdup(MSG_FAIL); } return ret; } char* on_get_hb_config(char* argv[], int argc) { int i; char* value = NULL; if (hb_config == NULL) { hb_config = strdup(MSG_OK); for (i = 0; i < sizeof(param_name)/sizeof(param_name[0]); i++) { value = hb->llc_ops->get_parameter(hb, param_name[i]); hb_config = mgmt_msg_append(hb_config, param_name[i]); hb_config = mgmt_msg_append(hb_config, value!=NULL?value:""); if (value != NULL) { free(value); } } } return strdup(hb_config); } char* on_get_nodetype(char* argv[], int argc) { const char* type; char* ret; type = hb->llc_ops->node_type(hb,argv[1]); if (type != NULL) { ret = strdup(MSG_OK); ret = mgmt_msg_append(ret, type); } else { ret = strdup(MSG_FAIL); } return ret; } int init_heartbeat(void) { hb = ll_cluster_new("heartbeat"); if (hb->llc_ops->signon(hb, client_name)!= HA_OK) { mgmt_log(LOG_ERR, "Cannot sign on with heartbeat"); mgmt_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb)); hb->llc_ops->delete(hb); hb = NULL; return -1; } G_main_add_ll_cluster(G_PRIORITY_LOW, hb, FALSE, on_hb_input, NULL, on_hb_quit); reg_msg(MSG_ALLNODES, on_get_allnodes); reg_msg(MSG_HB_CONFIG, on_get_hb_config); reg_msg(MSG_NODE_TYPE, on_get_nodetype); reg_msg(MSG_ECHO, on_echo); return 0; } void final_heartbeat(void) { if (hb != NULL) { hb->llc_ops->delete(hb); hb = NULL; } fire_event(EVT_DISCONNECTED); } gboolean on_hb_input(ll_cluster_t *hb, gpointer data) { struct ha_msg* msg; IPC_Channel *chan = NULL; if(hb != NULL) { chan = hb->llc_ops->ipcchan(hb); } if (chan == NULL || !IPC_ISRCONN(chan)) { fire_event(EVT_DISCONNECTED); mgmt_log(LOG_ERR, "Lost connection to heartbeat service."); hb = NULL; return FALSE; } msg = hb->llc_ops->readmsg(hb, 0); if (msg != NULL) { ha_msg_del(msg); } return TRUE; } void on_hb_quit(gpointer user_data) { return; } char* on_echo(char* argv[], int argc) { char* ret = strdup(MSG_OK); ret = mgmt_msg_append(ret, argv[1]); return ret; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/daemon/mgmt_internal.h000066400000000000000000000035061211477743100245310ustar00rootroot00000000000000/* * internal header file of management libray * * Author: Huang Zhen * Copyright (C) 2005 International Business Machines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef __MGMT_INTERNAL_H #define __HAM__MGMT_INTERNAL_H 1 #include #ifndef ENV_PREFIX #define ENV_PREFIX "HA_" #endif #ifndef KEY_LOGDAEMON #define KEY_LOGDAEMON "use_logd" #endif #ifndef HADEBUGVAL #define HADEBUGVAL "HA_debug" #endif #define mgmt_log(priority, fmt...) \ cl_log(priority, fmt); \ #define mgmt_debug(priority, fmt...) \ if ( debug_level > 0 ) { \ cl_log(priority, fmt); \ } #define STRNCPY(dest,src,n) \ strncpy(dest,src,n); dest[n-1]='\0'; #define ARGC_CHECK(n) \ if (argc != (n)) { \ mgmt_log(LOG_DEBUG, "%s msg should have %d params, but %d given",argv[0],n,argc); \ return strdup(MSG_FAIL"\nwrong parameter number"); \ } extern const char* client_name; extern int debug_level; typedef char* (*msg_handler)(char* argv[], int argc); extern int reg_msg(const char* type, msg_handler fun); extern int fire_event(const char* event); #endif /* __MGMT_INTERNAL_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/daemon/mgmt_lib.c000066400000000000000000000100501211477743100234460ustar00rootroot00000000000000/* * Linux HA management library * * Author: Huang Zhen * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #if HAVE_SECURITY_PAM_APPL_H # include #else # if HAVE_PAM_PAM_APPL_H # include # endif #endif #include #if HAVE_HB_CONFIG_H #include #endif #if HAVE_GLUE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #ifdef SUPPORT_AIS #undef SUPPORT_AIS #endif #ifdef SUPPORT_HEARTBEAT #undef SUPPORT_HEARTBEAT #endif #include #if HAVE_PACEMAKER_CRM_COMMON_CLUSTER_H # include #endif #if HAVE_PACEMAKER_CRM_CLUSTER_H # include #endif #include #include "mgmt_internal.h" /* common daemon and debug functions */ /* the initial func for modules */ extern int init_general(void); extern void final_general(void); #if SUPPORT_HEARTBEAT extern int init_heartbeat(void); #endif extern void final_heartbeat(void); extern int init_lrm(void); extern void final_lrm(void); static GHashTable* msg_map = NULL; static GHashTable* event_map = NULL; const char* client_name = NULL; static int components = 0; int init_mgmt_lib(const char* client, int enable_components) { /* create the internal data structures */ msg_map = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL); event_map = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL); client_name = client?client:"unknown"; components = enable_components; mgmt_set_mem_funcs(malloc, realloc, free); /* init modules */ #if SUPPORT_HEARTBEAT if(is_heartbeat_cluster()) { if (components & ENABLE_HB) { if (init_heartbeat() != 0) { return -1; } } } #endif if (components & ENABLE_LRM) { if (init_lrm() != 0) { return -1; } } return 0; } int final_mgmt_lib() { if (components & ENABLE_LRM) { final_lrm(); } #if SUPPORT_HEARTBEAT if(is_heartbeat_cluster()) { if (components & ENABLE_HB) { final_heartbeat(); } } #endif g_hash_table_destroy(msg_map); g_hash_table_destroy(event_map); return 0; } int reg_msg(const char* type, msg_handler fun) { if (g_hash_table_lookup(msg_map, type) != NULL) { return -1; } g_hash_table_insert(msg_map, strdup(type),(gpointer)fun); return 0; } int fire_event(const char* event) { event_handler func = NULL; char** args = mgmt_msg_args(event, NULL); if (args == NULL) { return -1; } func = (event_handler)g_hash_table_lookup(event_map, args[0]); if (func != NULL) { func(event); } mgmt_del_args(args); return 0; } char* process_msg(const char* msg) { msg_handler handler; char* ret; int num; char** args = mgmt_msg_args(msg, &num); if (args == NULL) { return NULL; } handler = (msg_handler)g_hash_table_lookup(msg_map, args[0]); if ( handler == NULL) { mgmt_del_args(args); return NULL; } ret = (*handler)(args, num); mgmt_del_args(args); return ret; } int reg_event(const char* type, event_handler func) { g_hash_table_replace(event_map, strdup(type), (gpointer)func); return 0; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/daemon/mgmt_lrm.c000066400000000000000000000072651211477743100235100ustar00rootroot00000000000000/* * Linux HA management library * * Author: Huang Zhen * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #if HAVE_HB_CONFIG_H #include #endif #if HAVE_GLUE_CONFIG_H #include #endif #include #include #include "mgmt_internal.h" #include static char* on_rsc_class(char* argv[], int argc); static char* on_rsc_type(char* argv[], int argc); static char* on_rsc_provider(char* argv[], int argc); static char* on_rsc_metadata(char* argv[], int argc); static char* on_lrm_op_rc2str(char* argv[], int argc); ll_lrm_t* lrm = NULL; int init_lrm(void); void final_lrm(void); int init_lrm(void) { int ret; int i, max_try = 5; lrm = ll_lrm_new("lrm"); for (i = 0; i < max_try ; i++) { ret = lrm->lrm_ops->signon(lrm,"mgmtd"); if (ret == HA_OK) { break; } mgmt_log(LOG_INFO,"login to lrm: %d, ret:%d",i,ret); sleep(1); } if (ret != HA_OK) { mgmt_log(LOG_INFO,"login to lrm failed"); lrm->lrm_ops->delete(lrm); lrm = NULL; return -1; } reg_msg(MSG_RSC_CLASSES, on_rsc_class); reg_msg(MSG_RSC_TYPES, on_rsc_type); reg_msg(MSG_RSC_PROVIDERS, on_rsc_provider); reg_msg(MSG_RSC_METADATA, on_rsc_metadata); reg_msg(MSG_LRM_OP_RC2STR, on_lrm_op_rc2str); return 0; } void final_lrm(void) { if (lrm != NULL) { lrm->lrm_ops->signoff(lrm); lrm->lrm_ops->delete(lrm); lrm = NULL; } } char* on_rsc_class(char* argv[], int argc) { GList* classes; GList* cur; char* ret = strdup(MSG_OK); classes = lrm->lrm_ops->get_rsc_class_supported(lrm); cur = classes; while (cur != NULL) { ret = mgmt_msg_append(ret, (char*)cur->data); cur = g_list_next(cur); } lrm_free_str_list(classes); return ret; } char* on_rsc_type(char* argv[], int argc) { GList* types; GList* cur; char* ret; ARGC_CHECK(2) ret = strdup(MSG_OK); types = lrm->lrm_ops->get_rsc_type_supported(lrm, argv[1]); cur = types; while (cur != NULL) { ret = mgmt_msg_append(ret, (char*)cur->data); cur = g_list_next(cur); } lrm_free_str_list(types); return ret; } char* on_rsc_provider(char* argv[], int argc) { GList* providers; GList* cur; char* ret = strdup(MSG_OK); providers = lrm->lrm_ops->get_rsc_provider_supported(lrm, argv[1], argv[2]); cur = providers; while (cur != NULL) { ret = mgmt_msg_append(ret, (char*)cur->data); cur = g_list_next(cur); } lrm_free_str_list(providers); return ret; } char* on_rsc_metadata(char* argv[], int argc) { char* ret; char* metadata = lrm->lrm_ops->get_rsc_type_metadata(lrm, argv[1], argv[2], argv[3]); if (metadata != NULL) { ret = strdup(MSG_OK); ret = mgmt_msg_append(ret, metadata); g_free(metadata); return ret; } return strdup(MSG_FAIL); } char* on_lrm_op_rc2str(char* argv[], int argc) { int rc; char* ret = strdup(MSG_OK); rc = atoi(argv[1]); ret = mgmt_msg_append(ret, execra_code2string(rc)); return ret; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/daemon/mgmt_pacemaker_lrm.c000066400000000000000000000102511211477743100255050ustar00rootroot00000000000000/* * Copyright (C) 2012 Gao,Yan * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include "mgmt_internal.h" #include static char* on_rsc_class(char* argv[], int argc); static char* on_rsc_type(char* argv[], int argc); static char* on_rsc_provider(char* argv[], int argc); static char* on_rsc_metadata(char* argv[], int argc); static char* on_lrm_op_rc2str(char* argv[], int argc); lrmd_t *lrmd_conn = NULL; int init_lrm(void); void final_lrm(void); int init_lrm(void) { int rc = 0; int i = 0; int max_try = 5; lrmd_conn = lrmd_api_new(); for (i = 0; i < max_try; i++) { rc = lrmd_conn->cmds->connect(lrmd_conn, "mgmtd", NULL); if (rc == 0) { break; } mgmt_log(LOG_NOTICE,"connect to lrmd: %d, rc=%d", i, rc); sleep(1); } if (rc != 0) { mgmt_log(LOG_WARNING,"connect to lrmd failed"); lrmd_api_delete(lrmd_conn); lrmd_conn = NULL; return -1; } reg_msg(MSG_RSC_CLASSES, on_rsc_class); reg_msg(MSG_RSC_TYPES, on_rsc_type); reg_msg(MSG_RSC_PROVIDERS, on_rsc_provider); reg_msg(MSG_RSC_METADATA, on_rsc_metadata); reg_msg(MSG_LRM_OP_RC2STR, on_lrm_op_rc2str); return 0; } void final_lrm(void) { if (lrmd_conn != NULL) { lrmd_conn->cmds->disconnect(lrmd_conn); lrmd_api_delete(lrmd_conn); lrmd_conn = NULL; } } char* on_rsc_class(char* argv[], int argc) { int rc = 0; lrmd_list_t *list = NULL; lrmd_list_t *iter = NULL; char* ret = strdup(MSG_OK); rc = lrmd_conn->cmds->list_standards(lrmd_conn, &list); if (rc > 0) { for (iter = list; iter != NULL; iter = iter->next) { ret = mgmt_msg_append(ret, iter->val); } lrmd_list_freeall(list); } else { mgmt_log(LOG_ERR, "No resource classes found"); } return ret; } char* on_rsc_type(char* argv[], int argc) { int rc = 0; lrmd_list_t *list = NULL; lrmd_list_t *iter = NULL; char* ret = NULL; ARGC_CHECK(2) ret = strdup(MSG_OK); rc = lrmd_conn->cmds->list_agents(lrmd_conn, &list, argv[1], NULL); if (rc > 0) { for (iter = list; iter != NULL; iter = iter->next) { ret = mgmt_msg_append(ret, iter->val); } lrmd_list_freeall(list); } else { mgmt_log(LOG_NOTICE, "No %s resource types found", argv[1]); } return ret; } char* on_rsc_provider(char* argv[], int argc) { int rc = 0; lrmd_list_t *list = NULL; lrmd_list_t *iter = NULL; char* ret = strdup(MSG_OK); rc = lrmd_conn->cmds->list_ocf_providers(lrmd_conn, argv[2], &list); if (rc > 0) { for (iter = list; iter != NULL; iter = iter->next) { ret = mgmt_msg_append(ret, iter->val); } lrmd_list_freeall(list); } else { mgmt_log(LOG_ERR, "No %s providers found for %s", argv[1], argv[2]); } return ret; } char* on_rsc_metadata(char* argv[], int argc) { int rc = 0; char *output = NULL; char* ret = NULL; rc = lrmd_conn->cmds->get_metadata(lrmd_conn, argv[1], argv[3], argv[2], &output, 0); if (rc == 0) { ret = strdup(MSG_OK); ret = mgmt_msg_append(ret, output); free(output); return ret; } return strdup(MSG_FAIL); } char* on_lrm_op_rc2str(char* argv[], int argc) { int rc = 0; char* ret = strdup(MSG_OK); rc = atoi(argv[1]); ret = mgmt_msg_append(ret, lrmd_event_rc2str(rc)); return ret; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/daemon/mgmtd.c000066400000000000000000000477541211477743100230110ustar00rootroot00000000000000/* * Linux HA management daemon * * Author: Huang Zhen * Copyright (c) 2005 International Business Machines * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_SYS_SOCKIO_H #include #endif #include #include #include #include #include #ifdef HAVE_STRING_H #include #endif #include #include #if HAVE_SECURITY_PAM_APPL_H # include #else # if HAVE_PAM_PAM_APPL_H # include # endif #endif #include #if HAVE_HB_CONFIG_H #include #endif #if HAVE_GLUE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include "mgmt_internal.h" #define OPTARGS "skrhvtp:" #define PID_FILE HA_VARRUNDIR"/mgmtd.pid" #define ALLOW_GRP "haclient" /* common daemon and debug functions */ static gboolean debug_level_adjust(int nsig, gpointer user_data); static gboolean sigterm_action(int nsig, gpointer unused); static void usage(const char* cmd, int exit_status); static int init_start(void); static int init_stop(const char *pid_file); static int init_status(const char *pid_file, const char *client_name); static void shutdown_mgmtd(void); static int on_event(const char* event); static int usr_belong_grp(const char* usr, const char* grp); static int _mgmt_session_sendmsg(void* session, const char* msg); /* management daemon internal data structure */ typedef struct { int id; uid_t uid; GIOChannel* ch; void* session; }client_t; /* management daemon internal functions */ static gboolean on_listen(GIOChannel *source , GIOCondition condition , gpointer data); static gboolean on_msg_arrived(GIOChannel *source , GIOCondition condition , gpointer data); static int new_client(int sock, void* session, const char *user); static client_t* lookup_client(int id); static gboolean end_client(gpointer key, gpointer value, gpointer user_data); static int del_client(int id); static int pam_auth(const char* user, const char* passwd); static int pam_conv(int n, const struct pam_message **msg, struct pam_response **resp, void *data); static char* dispatch_msg(const char* msg, client_t *client); const char* mgmtd_name = "mgmtd"; const char* mgmtd_pam = "hbmgmtd"; extern int debug_level; int test_mode = FALSE; int port = -1; static GMainLoop* mainloop = NULL; static GHashTable* clients = NULL; static GHashTable* evt_map = NULL; static gid_t gid = 0; int *client_id = NULL; extern int init_crm(int cache_cib); extern void final_crm(void); extern int set_crm(void); int main(int argc, char ** argv) { int req_restart = FALSE; int req_status = FALSE; int req_stop = FALSE; int argerr = 0; int flag; char * inherit_debuglevel; while ((flag = getopt(argc, argv, OPTARGS)) != EOF) { switch(flag) { case 'h': /* Help message */ usage(mgmtd_name, LSB_EXIT_OK); break; case 'v': /* Debug mode, more logs*/ ++debug_level; break; case 's': /* Status */ req_status = TRUE; break; case 'k': /* Stop (kill) */ req_stop = TRUE; break; case 'r': /* Restart */ req_restart = TRUE; break; case 't': /* in test mode, any password is acceptable */ test_mode = TRUE; break; case 'p': /* Get apphb interval */ if (optarg) { port = atoi(optarg); } break; default: ++argerr; break; } } if (optind > argc) { mgmt_log(LOG_ERR,"WHY WE ARE HERE?"); ++argerr; } if (argerr) { usage(mgmtd_name, LSB_EXIT_GENERIC); } inherit_debuglevel = getenv(HADEBUGVAL); if (inherit_debuglevel != NULL) { debug_level = atoi(inherit_debuglevel); if (debug_level > 2) { debug_level = 2; } } else { debug_level = 0; } cl_log_set_entity(mgmtd_name); cl_log_enable_stderr(FALSE); cl_log_set_facility(HA_LOG_FACILITY); cl_inherit_logging_environment(0); mgmt_log(LOG_INFO, "Pacemaker-mgmt Git Version: %s", BUILD_REVISION); if (req_status){ return init_status(PID_FILE, mgmtd_name); } if (req_stop){ return init_stop(PID_FILE); } if (req_restart) { init_stop(PID_FILE); } return init_start(); } int init_status(const char *pid_file, const char *client_name) { long pid = cl_read_pidfile(pid_file); if (pid > 0) { fprintf(stderr, "%s is running [pid: %ld]\n" , client_name, pid); return LSB_STATUS_OK; } fprintf(stderr, "%s is stopped.\n", client_name); return LSB_STATUS_STOPPED; } int init_stop(const char *pid_file) { long pid; int rc = LSB_EXIT_OK; if (pid_file == NULL) { mgmt_log(LOG_ERR, "No pid file specified to kill process"); return LSB_EXIT_GENERIC; } pid = cl_read_pidfile(pid_file); if (pid > 0) { if (CL_KILL((pid_t)pid, SIGTERM) < 0) { rc = (errno == EPERM ? LSB_EXIT_EPERM : LSB_EXIT_GENERIC); fprintf(stderr, "Cannot kill pid %ld\n", pid); }else{ mgmt_log(LOG_INFO, "Signal sent to pid=%ld," " waiting for process to exit", pid); while (CL_PID_EXISTS(pid)) { sleep(1); } } } return rc; } static const char usagemsg[] = "[-srkhvt]\n\ts: status\n\tr: restart" "\n\tk: kill\n\t" "h: help\n\tv: debug\n\tt: testmode(e.g. no authority checking)\n"; void usage(const char* cmd, int exit_status) { FILE* stream; stream = exit_status ? stderr : stdout; fprintf(stream, "usage: %s %s", cmd, usagemsg); fflush(stream); exit(exit_status); } gboolean sigterm_action(int nsig, gpointer user_data) { shutdown_mgmtd(); return TRUE; } static void register_pid(gboolean do_fork, gboolean (*shutdown)(int nsig, gpointer userdata)) { int j; umask(022); for (j = 0; j < 3; ++j) { close(j); (void)open("/dev/null", j == 0 ? O_RDONLY : O_RDONLY); } CL_IGNORE_SIG(SIGINT); CL_IGNORE_SIG(SIGHUP); G_main_add_SignalHandler(G_PRIORITY_HIGH, SIGTERM , shutdown, NULL, NULL); cl_signal_set_interrupt(SIGTERM, 1); cl_signal_set_interrupt(SIGCHLD, 1); /* At least they are harmless, I think. ;-) */ cl_signal_set_interrupt(SIGINT, 0); cl_signal_set_interrupt(SIGHUP, 0); } static gboolean debug_level_adjust(int nsig, gpointer user_data) { switch (nsig) { case SIGUSR1: debug_level++; if (debug_level > 2) { debug_level = 2; } break; case SIGUSR2: debug_level--; if (debug_level < 0) { debug_level = 0; } break; default: mgmt_log(LOG_WARNING, "debug_level_adjust: Received an " "unexpected signal(%d). Something wrong?.",nsig); } return TRUE; } /* main loop of the daemon*/ int init_start () { int ssock; struct sockaddr_in saddr; GIOChannel* sch; int ret; int optval; /* register pid */ if (cl_lock_pidfile(PID_FILE) < 0) { mgmt_log(LOG_ERR, "already running: [pid %d]." , cl_read_pidfile(PID_FILE)); mgmt_log(LOG_ERR, "Startup aborted (already running)." "Shutting down."); exit(100); } register_pid(FALSE, sigterm_action); /* enable coredumps */ mgmt_debug(LOG_DEBUG, "Enabling coredumps"); cl_cdtocoredir(); cl_enable_coredumps(TRUE); cl_set_all_coredump_signal_handlers(); /* enable dynamic up/down debug level */ G_main_add_SignalHandler(G_PRIORITY_HIGH, SIGUSR1, debug_level_adjust, NULL, NULL); G_main_add_SignalHandler(G_PRIORITY_HIGH, SIGUSR2, debug_level_adjust, NULL, NULL); /* create the internal data structures */ clients = g_hash_table_new(g_int_hash, g_int_equal); evt_map = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL); /* create the mainloop */ mainloop = g_main_new(FALSE); /* init library */ ret = init_mgmt_lib(mgmtd_name, ENABLE_HB|ENABLE_LRM|ENABLE_CRM|CACHE_CIB); if (ret != 0) { mgmt_log(LOG_ERR, "Can't initialize management library." "Shutting down.(%d)",ret); exit(1); } reg_event(EVT_DISCONNECTED, on_event); /* init ham & gnutls lib */ tls_init_server(); mgmt_set_mem_funcs(malloc, realloc, free); /* create server socket */ ssock = socket(AF_INET, SOCK_STREAM, 0); if (ssock == -1) { mgmt_log(LOG_ERR, "Can not create server socket." "Shutting down."); exit(100); } /* reuse address */ optval = 1; setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); /* bind server socket*/ memset(&saddr, '\0', sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = INADDR_ANY; saddr.sin_port = htons(port==-1?PORT:port); if (bind(ssock, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) { mgmt_log(LOG_ERR, "Can not bind server socket." "Shutting down."); exit(100); } if (listen(ssock, 10) == -1) { mgmt_log(LOG_ERR, "Can not start listen." "Shutting down."); exit(100); } /* create source for server socket and add to the mainloop */ sch = g_io_channel_unix_new(ssock); g_io_add_watch(sch, G_IO_IN|G_IO_ERR|G_IO_HUP, on_listen, NULL); /* run the mainloop */ mgmt_debug(LOG_DEBUG, "main: run the loop..."); mgmt_log(LOG_INFO, "Started."); g_main_run(mainloop); /* exit, clean the pid file */ g_hash_table_foreach_remove(clients, end_client, NULL); g_hash_table_destroy(clients); final_mgmt_lib(); if (cl_unlock_pidfile(PID_FILE) == 0) { mgmt_log(LOG_DEBUG, "[%s] stopped", mgmtd_name); } return 0; } gboolean on_listen(GIOChannel *source, GIOCondition condition, gpointer data) { char* msg; void* session; int ssock, csock; unsigned laddr; struct sockaddr_in addr; int num = 0; char** args = NULL; const char *client_proto = "1.0"; /* allow old clients to connect */ if (condition & G_IO_IN) { /* accept the connection */ ssock = g_io_channel_unix_get_fd(source); laddr = sizeof(addr); csock = accept(ssock, (struct sockaddr*)&addr, &laddr); if (csock == -1) { mgmt_log(LOG_ERR, "%s accept socket failed", __FUNCTION__); return TRUE; } /* create gnutls session for the server socket */ session = tls_attach_server(csock); if (session == NULL) { mgmt_log(LOG_ERR, "%s attach server socket failed", __FUNCTION__); close(csock); return TRUE; } msg = mgmt_session_recvmsg(session); args = mgmt_msg_args(msg, &num); if (msg == NULL || num<3 || num>4 || STRNCMP_CONST(args[0], MSG_LOGIN) != 0) { mgmt_del_args(args); mgmt_del_msg(msg); _mgmt_session_sendmsg(session, MSG_FAIL); tls_detach(session); close(csock); mgmt_log(LOG_ERR, "%s receive login msg failed", __FUNCTION__); return TRUE; } mgmt_debug(LOG_DEBUG, "recv msg: %s %s **** %s", args[0], args[1], num==4 ? args[3] : ""); if ( num == 4 ) { client_proto = args[3]; } /* protocol version check */ if (STRNCMP_CONST(client_proto, MGMT_PROTOCOL_VERSION) != 0) { mgmt_del_args(args); mgmt_del_msg(msg); mgmt_session_sendmsg(session, MGMT_PROTOCOL_VERSION); tls_detach(session); close(csock); mgmt_log(LOG_ERR, "%s protocol mismatch. Want %s but got %s", __FUNCTION__, MGMT_PROTOCOL_VERSION, client_proto); return TRUE; } /* authorization check with pam */ if (pam_auth(args[1],args[2]) != 0 || !usr_belong_grp(args[1],ALLOW_GRP)) { mgmt_del_args(args); mgmt_del_msg(msg); _mgmt_session_sendmsg(session, MSG_FAIL); tls_detach(session); close(csock); mgmt_log(LOG_ERR, "%s pam auth failed", __FUNCTION__); return TRUE; } if (new_client(csock, session, args[1]) !=0) { mgmt_del_args(args); mgmt_del_msg(msg); _mgmt_session_sendmsg(session, MSG_FAIL"Processing for the new client failed"); tls_detach(session); close(csock); mgmt_log(LOG_ERR, "%s processing for the new client failed", __FUNCTION__); return TRUE; } mgmt_del_args(args); mgmt_del_msg(msg); mgmt_debug(LOG_DEBUG, "send msg: %s", MSG_OK); _mgmt_session_sendmsg(session, MSG_OK); return TRUE; } return TRUE; } gboolean on_msg_arrived(GIOChannel *source, GIOCondition condition, gpointer data) { client_t* client; char* msg; char* ret; if (condition & G_IO_IN) { client = lookup_client(GPOINTER_TO_INT(data)); if (client == NULL) { return TRUE; } msg = mgmt_session_recvmsg(client->session); mgmt_debug(LOG_DEBUG, "recv msg: %s", msg); if (msg == NULL || STRNCMP_CONST(msg, MSG_LOGOUT) == 0) { mgmt_del_msg(msg); del_client(client->id); return FALSE; } ret = dispatch_msg(msg, client); if (ret != NULL) { mgmt_debug(LOG_DEBUG, "send msg: %s", ret); _mgmt_session_sendmsg(client->session, ret); mgmt_del_msg(ret); } else { mgmt_debug(LOG_DEBUG, "send msg: %s", MSG_FAIL); _mgmt_session_sendmsg(client->session, MSG_FAIL); } mgmt_del_msg(msg); } return TRUE; } int new_client(int sock, void* session, const char *user) { static int id = 1; struct passwd *pwd = NULL; client_t* client = NULL; pwd = getpwnam(user); if (pwd == NULL) { mgmt_log(LOG_ERR, "error on getpwnam: %s", strerror(errno)); return -1; } client = malloc(sizeof(client_t)); if (client == NULL) { mgmt_log(LOG_ERR, "malloc failed for new client"); return -1; } client->id = id; client->uid = pwd->pw_uid; if (ENABLE_CRM) { int rc = 0; client_id = &client->id; unsetenv("CIB_shadow"); if (setresgid(gid, gid, -1) < 0) { mgmt_log(LOG_ERR, "Could not set group to %d: %s", gid, strerror(errno)); return -1; } if (setresuid(client->uid, client->uid, -1) < 0){ mgmt_log(LOG_ERR, "Could not set user to %d: %s", client->uid, strerror(errno)); return -1; } rc = init_crm(CACHE_CIB); if (setresuid(0, 0, -1) < 0) { mgmt_log(LOG_ERR, "Could not reset user to 0: %s", strerror(errno)); } if (setresgid(0, 0, -1) < 0) { mgmt_log(LOG_ERR, "Could not reset group to 0: %s", strerror(errno)); } if (rc != 0) { free(client); return -1; } } client->ch = g_io_channel_unix_new(sock); g_io_channel_set_close_on_unref(client->ch,TRUE); g_io_add_watch(client->ch, G_IO_IN|G_IO_ERR|G_IO_HUP , on_msg_arrived, GINT_TO_POINTER(client->id)); client->session = session; g_hash_table_insert(clients, (gpointer)&client->id, client); id++; return 0; } client_t* lookup_client(int id) { client_t* client = (client_t*)g_hash_table_lookup(clients, &id); return client; } static gboolean end_client(gpointer key, gpointer value, gpointer user_data) { client_t *client = value; if (ENABLE_CRM) { client_id = &client->id; if (set_crm() == 0) { final_crm(); } } tls_detach(client->session); g_io_channel_unref(client->ch); free(client); return TRUE; } int del_client(int id) { client_t* client = lookup_client(id); if (client == NULL) { return -1; } g_hash_table_remove(clients, (gpointer)&client->id); end_client(&id, client, NULL); return 0; } int pam_auth(const char* user, const char* passwd) { pam_handle_t *pamh = NULL; int ret; struct pam_conv conv; if (test_mode) { return 0; } conv.conv = pam_conv; conv.appdata_ptr = strdup(passwd); ret = pam_start (mgmtd_pam, user, &conv, &pamh); if (ret == PAM_SUCCESS) { ret = pam_authenticate (pamh, 0); } pam_end (pamh, ret); return ret == PAM_SUCCESS?0:-1; } int pam_conv(int n, const struct pam_message **msg, struct pam_response **resp, void *data) { struct pam_response *reply; int i; char* passwd = (char*)data; *resp = NULL; /* Alloc memory for response. refer to the url, we must use malloc. http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/pam_appl-4.html#ss4.1 */ reply = malloc(n * sizeof(*reply)); if (reply == NULL) { return PAM_CONV_ERR; } memset(reply, 0, n * sizeof(*reply)); /* process the msg from pam modules */ for (i = 0; i < n; ++i) { switch (msg[i]->msg_style) { case PAM_PROMPT_ECHO_OFF: case PAM_PROMPT_ECHO_ON: reply[i].resp = passwd; break; case PAM_ERROR_MSG: case PAM_TEXT_INFO: break; default: free(reply); return PAM_CONV_ERR; } } *resp = reply; return PAM_SUCCESS; } int on_event(const char* event) { GList* id_list; GList* node; int list_changed = 0; char** args = mgmt_msg_args(event, NULL); if (args == NULL) { return -1; } id_list = g_hash_table_lookup(evt_map, args[0]); if (id_list == NULL) { if (STRNCMP_CONST(args[0],EVT_DISCONNECTED) == 0) { goto do_exit; } mgmt_del_args(args); return -1; } node = id_list; while (node != NULL) { client_t* client; int id = GPOINTER_TO_INT(node->data); client = lookup_client(id); if (client == NULL) { /* remove the client id */ node = g_list_next(node); id_list = g_list_remove(id_list, GINT_TO_POINTER(id)); list_changed = 1; continue; } mgmt_debug(LOG_DEBUG, "send evt: %s", event); _mgmt_session_sendmsg(client->session, event); mgmt_debug(LOG_DEBUG, "send evt: %s done", event); node = g_list_next(node); } if (list_changed == 1) { g_hash_table_replace(evt_map, strdup(args[0]), (gpointer)id_list); } do_exit: if (STRNCMP_CONST(args[0],EVT_DISCONNECTED) == 0) { mgmt_log(LOG_ERR,"Connection to the CIB terminated... exiting"); /*cib exits abnormally, mgmtd exits too and wait heartbeat restart us in order*/ exit(LSB_EXIT_OK); } mgmt_del_args(args); return 0; } char* dispatch_msg(const char* msg, client_t *client) { char* ret; int num; char** args = mgmt_msg_args(msg, &num); if (args == NULL) { return NULL; } if (strncmp(args[0], MSG_REGEVT, strlen(MSG_REGEVT)) == 0) { GList* id_list = g_hash_table_lookup(evt_map, args[1]); id_list = g_list_append(id_list, GINT_TO_POINTER(client->id)); g_hash_table_replace(evt_map, strdup(args[1]), (gpointer)id_list); reg_event(args[1], on_event); ret = strdup(MSG_OK); } else { const char *saved_env = getenv("HOME"); unsetenv("HOME"); if (ENABLE_CRM) { client_id = &client->id; set_crm(); } if (setresgid(gid, gid, -1) < 0) { mgmt_log(LOG_ERR, "Could not set group to %d: %s", gid, strerror(errno)); return NULL; } if (setresuid(client->uid, client->uid, -1) < 0){ mgmt_log(LOG_ERR, "Could not set user to %d: %s", client->uid, strerror(errno)); return NULL; } ret = process_msg(msg); if (setresuid(0, 0, -1) < 0) { mgmt_log(LOG_ERR, "Could not reset user to 0: %s", strerror(errno)); } if (setresgid(0, 0, -1) < 0) { mgmt_log(LOG_ERR, "Could not reset group to 0: %s", strerror(errno)); } setenv("HOME", saved_env, 1); } mgmt_del_args(args); return ret; } void shutdown_mgmtd(void) { mgmt_log(LOG_INFO,"mgmtd is shutting down"); if (mainloop != NULL && g_main_is_running(mainloop)) { g_main_quit(mainloop); }else { exit(LSB_EXIT_OK); } } static int usr_belong_grp(const char* usr, const char* grp) { int index = 0; char* grp_usr = NULL; struct group *gren = NULL; struct passwd *pwd = NULL; if (test_mode) { return 1; } pwd = getpwnam(usr); if (pwd == NULL) { return 0; } gren = getgrgid(pwd->pw_gid); if (gren == NULL) { return 0; } if (strncmp(grp, gren->gr_name,MAX_STRLEN) == 0) { return 1; } gren = getgrnam(grp); if (gren == NULL) { return 0; } grp_usr = gren->gr_mem[index]; while (grp_usr != NULL) { if (strncmp(usr,grp_usr,MAX_STRLEN) == 0) { gid = gren->gr_gid; return 1; } index ++; grp_usr = gren->gr_mem[index]; } return 0; } int _mgmt_session_sendmsg(void* session, const char* msg) { int ret = mgmt_session_sendmsg(session, msg); if(ret == -1) { mgmt_log(LOG_ERR,"send msg %s failed", msg); } else if (ret == -2) { mgmt_log(LOG_ERR,"send msg %s failed(msg too long)", msg); } return ret; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/daemon/mgmtd.pam000066400000000000000000000001111211477743100233140ustar00rootroot00000000000000auth required pam_unix.so account required pam_unix.so pacemaker-mgmt-pacemaker-mgmt-2.1.2/mgmt/daemon/mgmtd.pam.common000066400000000000000000000001031211477743100246040ustar00rootroot00000000000000#%PAM-1.0 auth include common-auth account include common-account pacemaker-mgmt-pacemaker-mgmt-2.1.2/po/000077500000000000000000000000001211477743100177235ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/po/LINGUAS000066400000000000000000000000111211477743100207400ustar00rootroot00000000000000ja zh_CN pacemaker-mgmt-pacemaker-mgmt-2.1.2/po/Makefile.in.in000066400000000000000000000153041211477743100224000ustar00rootroot00000000000000# Makefile for program source directory in GNU NLS utilities package. # Copyright (C) 1995, 1996, 1997 by Ulrich Drepper # # This file file be copied and used freely without restrictions. It can # be used in projects which are not available under the GNU Public License # but which still want to provide support for the GNU gettext functionality. # Please note that the actual code is *not* freely available. # # - Modified by Owen Taylor to use GETTEXT_PACKAGE # instead of PACKAGE and to look for po2tbl in ./ not in intl/ # # - Modified by jacob berkman to install # Makefile.in.in and po2tbl.sed.in for use with glib-gettextize # # - Modified by Rodney Dawes for use with intltool # # We have the following line for use by intltoolize: # INTLTOOL_MAKEFILE GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ PACKAGE = @PACKAGE@ VERSION = @VERSION@ SHELL = /bin/sh srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = @top_builddir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ datadir = @datadir@ datarootdir = @datarootdir@ libdir = @libdir@ DATADIRNAME = @DATADIRNAME@ itlocaledir = $(prefix)/$(DATADIRNAME)/locale subdir = po install_sh = @install_sh@ # Automake >= 1.8 provides @mkdir_p@. # Until it can be supposed, use the safe fallback: mkdir_p = $(install_sh) -d INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ GMSGFMT = @GMSGFMT@ MSGFMT = @MSGFMT@ XGETTEXT = @XGETTEXT@ INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ MSGMERGE = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist GENPOT = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot ALL_LINGUAS = @ALL_LINGUAS@ PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; fi) USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep ^$$lang$$ $(srcdir)/LINGUAS`" -o -n "`echo $$ALINGUAS|grep ' ?$$lang ?'`"; then printf "$$lang "; fi; done; fi) USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done) POFILES=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.po "; done) DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(POFILES) EXTRA_DISTFILES = POTFILES.skip Makevars LINGUAS POTFILES = \ # This comment gets stripped out CATALOGS=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.gmo "; done) .SUFFIXES: .SUFFIXES: .po .pox .gmo .mo .msg .cat .po.pox: $(MAKE) $(GETTEXT_PACKAGE).pot $(MSGMERGE) $< $(GETTEXT_PACKAGE).pot -o $*.pox .po.mo: $(MSGFMT) -o $@ $< .po.gmo: file=`echo $* | sed 's,.*/,,'`.gmo \ && rm -f $$file && $(GMSGFMT) -o $$file $< .po.cat: sed -f ../intl/po2msg.sed < $< > $*.msg \ && rm -f $@ && gencat $@ $*.msg all: all-@USE_NLS@ all-yes: $(CATALOGS) all-no: $(GETTEXT_PACKAGE).pot: $(POTFILES) $(GENPOT) install: install-data install-data: install-data-@USE_NLS@ install-data-no: all install-data-yes: all $(mkdir_p) $(DESTDIR)$(itlocaledir) linguas="$(USE_LINGUAS)"; \ for lang in $$linguas; do \ dir=$(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES; \ $(mkdir_p) $$dir; \ if test -r $$lang.gmo; then \ $(INSTALL_DATA) $$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ echo "installing $$lang.gmo as $$dir/$(GETTEXT_PACKAGE).mo"; \ else \ $(INSTALL_DATA) $(srcdir)/$$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ echo "installing $(srcdir)/$$lang.gmo as" \ "$$dir/$(GETTEXT_PACKAGE).mo"; \ fi; \ if test -r $$lang.gmo.m; then \ $(INSTALL_DATA) $$lang.gmo.m $$dir/$(GETTEXT_PACKAGE).mo.m; \ echo "installing $$lang.gmo.m as $$dir/$(GETTEXT_PACKAGE).mo.m"; \ else \ if test -r $(srcdir)/$$lang.gmo.m ; then \ $(INSTALL_DATA) $(srcdir)/$$lang.gmo.m \ $$dir/$(GETTEXT_PACKAGE).mo.m; \ echo "installing $(srcdir)/$$lang.gmo.m as" \ "$$dir/$(GETTEXT_PACKAGE).mo.m"; \ else \ true; \ fi; \ fi; \ done # Empty stubs to satisfy archaic automake needs dvi info tags TAGS ID: # Define this as empty until I found a useful application. installcheck: uninstall: linguas="$(USE_LINGUAS)"; \ for lang in $$linguas; do \ rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo; \ rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo.m; \ done check: all $(GETTEXT_PACKAGE).pot rm -f missing notexist srcdir=$(srcdir) $(INTLTOOL_UPDATE) -m if [ -r missing -o -r notexist ]; then \ exit 1; \ fi mostlyclean: rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp rm -f .intltool-merge-cache clean: mostlyclean distclean: clean rm -f Makefile Makefile.in POTFILES stamp-it rm -f *.mo *.msg *.cat *.cat.m *.gmo maintainer-clean: distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." rm -f Makefile.in.in distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) dist distdir: $(DISTFILES) dists="$(DISTFILES)"; \ extra_dists="$(EXTRA_DISTFILES)"; \ for file in $$extra_dists; do \ test -f $(srcdir)/$$file && dists="$$dists $(srcdir)/$$file"; \ done; \ for file in $$dists; do \ test -f $$file || file="$(srcdir)/$$file"; \ ln $$file $(distdir) 2> /dev/null \ || cp -p $$file $(distdir); \ done update-po: Makefile $(MAKE) $(GETTEXT_PACKAGE).pot tmpdir=`pwd`; \ linguas="$(USE_LINGUAS)"; \ for lang in $$linguas; do \ echo "$$lang:"; \ result="`$(MSGMERGE) -o $$tmpdir/$$lang.new.po $$lang`"; \ if $$result; then \ if cmp $(srcdir)/$$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$lang.new.po; \ else \ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ :; \ else \ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ rm -f $$tmpdir/$$lang.new.po; \ exit 1; \ fi; \ fi; \ else \ echo "msgmerge for $$lang.gmo failed!"; \ rm -f $$tmpdir/$$lang.new.po; \ fi; \ done Makefile POTFILES: stamp-it @if test ! -f $@; then \ rm -f stamp-it; \ $(MAKE) stamp-it; \ fi stamp-it: Makefile.in.in $(top_builddir)/config.status POTFILES.in cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/Makefile.in CONFIG_HEADERS= CONFIG_LINKS= \ $(SHELL) ./config.status # Tell versions [3.59,3.63) of GNU make not to export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: pacemaker-mgmt-pacemaker-mgmt-2.1.2/po/POTFILES.in000066400000000000000000000000331211477743100214740ustar00rootroot00000000000000mgmt/client/haclient.py.in pacemaker-mgmt-pacemaker-mgmt-2.1.2/po/haclient.pot000066400000000000000000001256301211477743100222450ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-04-17 16:29+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: ../mgmt/client/haclient.py.in:139 msgid "Do not delete the root directory" msgstr "" #: ../mgmt/client/haclient.py.in:147 ../mgmt/client/haclient.py.in:153 #: ../mgmt/client/haclient.py.in:158 ../mgmt/client/haclient.py.in:3334 #: ../mgmt/client/haclient.py.in:3342 ../mgmt/client/haclient.py.in:5396 #: ../mgmt/client/haclient.py.in:5402 ../mgmt/client/haclient.py.in:5575 #: ../mgmt/client/haclient.py.in:6233 ../mgmt/client/haclient.py.in:6239 #: ../mgmt/client/haclient.py.in:6458 ../mgmt/client/haclient.py.in:6603 #: ../mgmt/client/haclient.py.in:6612 ../mgmt/client/haclient.py.in:7414 #: ../mgmt/client/haclient.py.in:7422 msgid "System error" msgstr "" #: ../mgmt/client/haclient.py.in:147 ../mgmt/client/haclient.py.in:153 #: ../mgmt/client/haclient.py.in:158 ../mgmt/client/haclient.py.in:2729 #: ../mgmt/client/haclient.py.in:2877 ../mgmt/client/haclient.py.in:3262 #: ../mgmt/client/haclient.py.in:3307 ../mgmt/client/haclient.py.in:3313 #: ../mgmt/client/haclient.py.in:3334 ../mgmt/client/haclient.py.in:3342 #: ../mgmt/client/haclient.py.in:5299 ../mgmt/client/haclient.py.in:5396 #: ../mgmt/client/haclient.py.in:5402 ../mgmt/client/haclient.py.in:5564 #: ../mgmt/client/haclient.py.in:5575 ../mgmt/client/haclient.py.in:5986 #: ../mgmt/client/haclient.py.in:5990 ../mgmt/client/haclient.py.in:6169 #: ../mgmt/client/haclient.py.in:6233 ../mgmt/client/haclient.py.in:6239 #: ../mgmt/client/haclient.py.in:6446 ../mgmt/client/haclient.py.in:6458 #: ../mgmt/client/haclient.py.in:6474 ../mgmt/client/haclient.py.in:6477 #: ../mgmt/client/haclient.py.in:6485 ../mgmt/client/haclient.py.in:6504 #: ../mgmt/client/haclient.py.in:6511 ../mgmt/client/haclient.py.in:6527 #: ../mgmt/client/haclient.py.in:6543 ../mgmt/client/haclient.py.in:6547 #: ../mgmt/client/haclient.py.in:6567 ../mgmt/client/haclient.py.in:6571 #: ../mgmt/client/haclient.py.in:6584 ../mgmt/client/haclient.py.in:6589 #: ../mgmt/client/haclient.py.in:6603 ../mgmt/client/haclient.py.in:6612 #: ../mgmt/client/haclient.py.in:7371 ../mgmt/client/haclient.py.in:7377 #: ../mgmt/client/haclient.py.in:7407 ../mgmt/client/haclient.py.in:7414 #: ../mgmt/client/haclient.py.in:7422 ../mgmt/client/haclient.py.in:8923 msgid ": " msgstr "" #: ../mgmt/client/haclient.py.in:191 msgid "Message" msgstr "" #: ../mgmt/client/haclient.py.in:211 msgid "Confirm" msgstr "" #: ../mgmt/client/haclient.py.in:253 msgid "The specified time should be numeric prefixed." msgstr "" #: ../mgmt/client/haclient.py.in:264 msgid "The specified time should default with second unit, " msgstr "" #: ../mgmt/client/haclient.py.in:265 #, python-format msgid "" "or should be suffixed with one of the following units:\n" " %s" msgstr "" #: ../mgmt/client/haclient.py.in:358 msgid "Add Parameter" msgstr "" #: ../mgmt/client/haclient.py.in:360 msgid "Add Operation" msgstr "" #: ../mgmt/client/haclient.py.in:401 ../mgmt/client/haclient.py.in:8640 #: ../mgmt/client/haclient.py.in:8931 msgid " can't be empty" msgstr "" #: ../mgmt/client/haclient.py.in:508 ../mgmt/client/haclient.py.in:665 #: ../mgmt/client/haclient.py.in:1744 msgid "Type" msgstr "" #: ../mgmt/client/haclient.py.in:666 msgid "ID" msgstr "" #: ../mgmt/client/haclient.py.in:771 msgid "St_art" msgstr "" #: ../mgmt/client/haclient.py.in:771 msgid "Start resource" msgstr "" #: ../mgmt/client/haclient.py.in:772 msgid "_Stop" msgstr "" #: ../mgmt/client/haclient.py.in:772 msgid "Stop resource" msgstr "" #: ../mgmt/client/haclient.py.in:773 msgid "_Default" msgstr "" #: ../mgmt/client/haclient.py.in:773 msgid "Work as default" msgstr "" #: ../mgmt/client/haclient.py.in:774 msgid "_Cleanup Resource" msgstr "" #: ../mgmt/client/haclient.py.in:774 msgid "Cleanup resource" msgstr "" #: ../mgmt/client/haclient.py.in:775 msgid "Migra_te Resource" msgstr "" #: ../mgmt/client/haclient.py.in:775 msgid "Migrate a resource to specified node" msgstr "" #: ../mgmt/client/haclient.py.in:777 msgid "Clea_r Migrate Constraints" msgstr "" #: ../mgmt/client/haclient.py.in:778 msgid "Clear constraints created by migrate" msgstr "" #: ../mgmt/client/haclient.py.in:780 msgid "_Unmanage Resource" msgstr "" #: ../mgmt/client/haclient.py.in:780 msgid "Put a resource into unmanaged mode" msgstr "" #: ../mgmt/client/haclient.py.in:782 msgid "_Manage Resource" msgstr "" #: ../mgmt/client/haclient.py.in:782 msgid "Put a resource into managed mode" msgstr "" #: ../mgmt/client/haclient.py.in:784 msgid "Re_fresh Resources" msgstr "" #: ../mgmt/client/haclient.py.in:784 msgid "Refresh CIB from the LRM status" msgstr "" #: ../mgmt/client/haclient.py.in:786 msgid "Re_probe Resources" msgstr "" #: ../mgmt/client/haclient.py.in:786 msgid "Reprobe for resources started outside of the CRM" msgstr "" #: ../mgmt/client/haclient.py.in:790 msgid "_Standby" msgstr "" #: ../mgmt/client/haclient.py.in:790 msgid "Make the node standby" msgstr "" #: ../mgmt/client/haclient.py.in:791 msgid "_Active" msgstr "" #: ../mgmt/client/haclient.py.in:791 msgid "Make the node active" msgstr "" #: ../mgmt/client/haclient.py.in:795 msgid "_Group By Node" msgstr "" #: ../mgmt/client/haclient.py.in:795 msgid "Group resources by node" msgstr "" #: ../mgmt/client/haclient.py.in:796 msgid "_Maintenance Mode" msgstr "" #: ../mgmt/client/haclient.py.in:797 msgid "Switch to maintenance mode" msgstr "" #: ../mgmt/client/haclient.py.in:798 msgid "_Indicate Pending Operations" msgstr "" #: ../mgmt/client/haclient.py.in:799 msgid "Indicate pending(starting/stopping) operations" msgstr "" #: ../mgmt/client/haclient.py.in:987 ../mgmt/client/haclient.py.in:1024 #: ../mgmt/client/haclient.py.in:1307 ../mgmt/client/haclient.py.in:1410 #: ../mgmt/client/haclient.py.in:1619 ../mgmt/client/haclient.py.in:2304 #: ../mgmt/client/haclient.py.in:2316 ../mgmt/client/haclient.py.in:3755 #: ../mgmt/client/haclient.py.in:3894 ../mgmt/client/haclient.py.in:4481 #: ../mgmt/client/haclient.py.in:4993 ../mgmt/client/haclient.py.in:5001 #: ../mgmt/client/haclient.py.in:5045 ../mgmt/client/haclient.py.in:5243 #: ../mgmt/client/haclient.py.in:5756 ../mgmt/client/haclient.py.in:5771 #: ../mgmt/client/haclient.py.in:5785 ../mgmt/client/haclient.py.in:5794 #: ../mgmt/client/haclient.py.in:6018 ../mgmt/client/haclient.py.in:6266 #: ../mgmt/client/haclient.py.in:8545 ../mgmt/client/haclient.py.in:8762 #: ../mgmt/client/haclient.py.in:8885 ../mgmt/client/haclient.py.in:8931 #: ../mgmt/client/haclient.py.in:10103 msgid ":" msgstr "" #: ../mgmt/client/haclient.py.in:1075 #, python-format msgid "last failure at \"%s\"" msgstr "" #: ../mgmt/client/haclient.py.in:1219 ../mgmt/client/haclient.py.in:1224 #: ../mgmt/client/haclient.py.in:1670 ../mgmt/client/haclient.py.in:2007 #: ../mgmt/client/haclient.py.in:2009 msgid "standby" msgstr "" #: ../mgmt/client/haclient.py.in:1220 ../mgmt/client/haclient.py.in:1225 #: ../mgmt/client/haclient.py.in:1985 msgid "never started" msgstr "" #: ../mgmt/client/haclient.py.in:1278 #, python-format msgid "Cannot find the %s: %s" msgstr "" #: ../mgmt/client/haclient.py.in:1304 msgid "Caused by your previous action, this attribute has been set to \"" msgstr "" #: ../mgmt/client/haclient.py.in:1306 msgid "\"." msgstr "" #: ../mgmt/client/haclient.py.in:1307 msgid "Recommended" msgstr "" #: ../mgmt/client/haclient.py.in:1308 msgid "" "Select \"Clear All\" to remove the attributes for all of the sub-resources." msgstr "" #: ../mgmt/client/haclient.py.in:1309 msgid "All of the sub-resources will inherit the attributes from their parent." msgstr "" #: ../mgmt/client/haclient.py.in:1314 #, python-format msgid "Clear the %s=\"%s\" attribute for sub-resource \"" msgstr "" #: ../mgmt/client/haclient.py.in:1315 msgid "\"?" msgstr "" #: ../mgmt/client/haclient.py.in:1330 #, python-format msgid "Cannot %s %s: XML processing error" msgstr "" #: ../mgmt/client/haclient.py.in:1353 ../mgmt/client/haclient.py.in:1367 msgid "all resources" msgstr "" #: ../mgmt/client/haclient.py.in:1359 ../mgmt/client/haclient.py.in:1363 #: ../mgmt/client/haclient.py.in:1381 msgid "all nodes" msgstr "" #: ../mgmt/client/haclient.py.in:1361 msgid "Cleanup Resource" msgstr "" #: ../mgmt/client/haclient.py.in:1362 ../mgmt/client/haclient.py.in:1566 msgid "Resource" msgstr "" #: ../mgmt/client/haclient.py.in:1363 msgid "Node" msgstr "" #: ../mgmt/client/haclient.py.in:1395 msgid "Migrate Resource" msgstr "" #: ../mgmt/client/haclient.py.in:1556 msgid "all migrated resources" msgstr "" #: ../mgmt/client/haclient.py.in:1565 msgid "Clear Migrate Constraints" msgstr "" #. node_options = node_list[:] #. node_options.insert(0, "") #: ../mgmt/client/haclient.py.in:1610 #, python-format msgid "%s Resources" msgstr "" #: ../mgmt/client/haclient.py.in:1670 ../mgmt/client/haclient.py.in:1678 msgid "Make" msgstr "" #: ../mgmt/client/haclient.py.in:1678 msgid "active" msgstr "" #: ../mgmt/client/haclient.py.in:1745 msgid "Name" msgstr "" #: ../mgmt/client/haclient.py.in:1746 msgid "Status" msgstr "" #: ../mgmt/client/haclient.py.in:1747 msgid "Details" msgstr "" #: ../mgmt/client/haclient.py.in:1803 msgid "unmanaged" msgstr "" #: ../mgmt/client/haclient.py.in:1804 ../mgmt/client/haclient.py.in:2000 msgid "unclean" msgstr "" #: ../mgmt/client/haclient.py.in:1806 msgid "failed" msgstr "" #: ../mgmt/client/haclient.py.in:1808 msgid "starting" msgstr "" #: ../mgmt/client/haclient.py.in:1810 msgid "stopping" msgstr "" #: ../mgmt/client/haclient.py.in:1812 ../mgmt/client/haclient.py.in:2094 msgid "not running" msgstr "" #: ../mgmt/client/haclient.py.in:1814 ../mgmt/client/haclient.py.in:2096 #: ../mgmt/client/haclient.py.in:2106 msgid "running" msgstr "" #: ../mgmt/client/haclient.py.in:1820 ../mgmt/client/haclient.py.in:1987 #: ../mgmt/client/haclient.py.in:2104 msgid "ping node" msgstr "" #: ../mgmt/client/haclient.py.in:1822 ../mgmt/client/haclient.py.in:1993 msgid "online" msgstr "" #: ../mgmt/client/haclient.py.in:1905 msgid "have quorum" msgstr "" #: ../mgmt/client/haclient.py.in:1907 msgid "no quorum" msgstr "" #: ../mgmt/client/haclient.py.in:1918 ../mgmt/client/haclient.py.in:1935 #: ../mgmt/client/haclient.py.in:2331 msgid "Cluster" msgstr "" #: ../mgmt/client/haclient.py.in:1921 msgid "Inactive resources" msgstr "" #: ../mgmt/client/haclient.py.in:1938 msgid "Resources" msgstr "" #: ../mgmt/client/haclient.py.in:1952 msgid " on " msgstr "" #: ../mgmt/client/haclient.py.in:1981 msgid "unknown" msgstr "" #: ../mgmt/client/haclient.py.in:1989 msgid "unknown type" msgstr "" #: ../mgmt/client/haclient.py.in:1995 msgid "pending" msgstr "" #: ../mgmt/client/haclient.py.in:1997 msgid "offline" msgstr "" #: ../mgmt/client/haclient.py.in:2003 msgid "dc" msgstr "" #: ../mgmt/client/haclient.py.in:2007 msgid "on-fail" msgstr "" #: ../mgmt/client/haclient.py.in:2093 msgid "primitive" msgstr "" #: ../mgmt/client/haclient.py.in:2098 msgid "fail" msgstr "" #: ../mgmt/client/haclient.py.in:2110 msgid "group" msgstr "" #: ../mgmt/client/haclient.py.in:2110 msgid "resources" msgstr "" #: ../mgmt/client/haclient.py.in:2110 msgid "clone" msgstr "" #: ../mgmt/client/haclient.py.in:2110 msgid "master" msgstr "" #: ../mgmt/client/haclient.py.in:2112 msgid "orders" msgstr "" #: ../mgmt/client/haclient.py.in:2112 msgid "locations" msgstr "" #: ../mgmt/client/haclient.py.in:2112 msgid "colocations" msgstr "" #: ../mgmt/client/haclient.py.in:2135 ../mgmt/client/haclient.py.in:4997 #: ../mgmt/client/haclient.py.in:6381 msgid "Live" msgstr "" #: ../mgmt/client/haclient.py.in:2137 msgid "Shadow: " msgstr "" #: ../mgmt/client/haclient.py.in:2172 msgid "Management" msgstr "" #: ../mgmt/client/haclient.py.in:2337 msgid "CIB" msgstr "" #: ../mgmt/client/haclient.py.in:2347 msgid "View XML" msgstr "" #: ../mgmt/client/haclient.py.in:2354 msgid "The Whole CIB" msgstr "" #: ../mgmt/client/haclient.py.in:2356 msgid "The Configuration Section" msgstr "" #: ../mgmt/client/haclient.py.in:2383 #, python-format msgid "The object \"%s\" doesn't exist" msgstr "" #: ../mgmt/client/haclient.py.in:2439 ../mgmt/client/haclient.py.in:2729 msgid "Default" msgstr "" #: ../mgmt/client/haclient.py.in:2441 ../mgmt/client/haclient.py.in:3160 #: ../mgmt/client/haclient.py.in:4936 msgid "Reset" msgstr "" #: ../mgmt/client/haclient.py.in:2549 msgid "Multiple \"Cluster Property Set\" in \"CRM Config\"." msgstr "" #: ../mgmt/client/haclient.py.in:2550 ../mgmt/client/haclient.py.in:3457 #: ../mgmt/client/haclient.py.in:3479 ../mgmt/client/haclient.py.in:3607 #: ../mgmt/client/haclient.py.in:3628 msgid "We are switching to \"Hack Mode\" to view them properly." msgstr "" #: ../mgmt/client/haclient.py.in:2556 msgid "Cannot update the crm configuration: No \"crm_config\" in CIB" msgstr "" #: ../mgmt/client/haclient.py.in:2563 msgid "Cannot update the crm configuration" msgstr "" #: ../mgmt/client/haclient.py.in:2631 msgid "There are unsaved changes in current page." msgstr "" #: ../mgmt/client/haclient.py.in:2631 ../mgmt/client/haclient.py.in:5917 msgid "Apply the changes?" msgstr "" #: ../mgmt/client/haclient.py.in:2649 msgid "Policy Engine" msgstr "" #: ../mgmt/client/haclient.py.in:2661 msgid "CRM Daemon" msgstr "" #: ../mgmt/client/haclient.py.in:2723 ../mgmt/client/haclient.py.in:2726 #: ../mgmt/client/haclient.py.in:5242 ../mgmt/client/haclient.py.in:9537 #: ../mgmt/client/haclient.py.in:9540 ../mgmt/client/haclient.py.in:9808 #: ../mgmt/client/haclient.py.in:9811 msgid "." msgstr "" #: ../mgmt/client/haclient.py.in:2746 ../mgmt/client/haclient.py.in:2803 #: ../mgmt/client/haclient.py.in:2807 ../mgmt/client/haclient.py.in:8576 #: ../mgmt/client/haclient.py.in:8595 ../mgmt/client/haclient.py.in:8944 #: ../mgmt/client/haclient.py.in:9713 ../mgmt/client/haclient.py.in:9717 #: ../mgmt/client/haclient.py.in:9781 msgid "default" msgstr "" #: ../mgmt/client/haclient.py.in:2868 msgid "List Mode" msgstr "" #: ../mgmt/client/haclient.py.in:2869 msgid "Tree Mode" msgstr "" #: ../mgmt/client/haclient.py.in:2870 msgid "XML Mode" msgstr "" #: ../mgmt/client/haclient.py.in:2877 msgid "Show" msgstr "" #: ../mgmt/client/haclient.py.in:3150 msgid "The object doesn't exist" msgstr "" #: ../mgmt/client/haclient.py.in:3159 msgid "Edit XML" msgstr "" #: ../mgmt/client/haclient.py.in:3174 msgid "Import" msgstr "" #: ../mgmt/client/haclient.py.in:3175 msgid "Import XML" msgstr "" #: ../mgmt/client/haclient.py.in:3176 msgid "Export" msgstr "" #: ../mgmt/client/haclient.py.in:3177 msgid "Export XML" msgstr "" #: ../mgmt/client/haclient.py.in:3241 msgid "OVR" msgstr "" #: ../mgmt/client/haclient.py.in:3243 msgid "INS" msgstr "" #: ../mgmt/client/haclient.py.in:3246 #, python-format msgid "Ln %d, Col %d\t%s" msgstr "" #: ../mgmt/client/haclient.py.in:3262 msgid "Failed to parse the XML" msgstr "" #: ../mgmt/client/haclient.py.in:3274 msgid "Open File" msgstr "" #: ../mgmt/client/haclient.py.in:3283 msgid "All files" msgstr "" #: ../mgmt/client/haclient.py.in:3288 msgid "XML files" msgstr "" #: ../mgmt/client/haclient.py.in:3307 ../mgmt/client/haclient.py.in:3313 #: ../mgmt/client/haclient.py.in:5299 ../mgmt/client/haclient.py.in:6446 #: ../mgmt/client/haclient.py.in:6474 ../mgmt/client/haclient.py.in:6504 #: ../mgmt/client/haclient.py.in:6511 ../mgmt/client/haclient.py.in:6527 #: ../mgmt/client/haclient.py.in:6543 ../mgmt/client/haclient.py.in:6567 #: ../mgmt/client/haclient.py.in:6584 ../mgmt/client/haclient.py.in:7407 msgid "I/O error" msgstr "" #: ../mgmt/client/haclient.py.in:3455 ../mgmt/client/haclient.py.in:3605 #, python-format msgid "The \"%s\" has multiple \"%s\" sets." msgstr "" #: ../mgmt/client/haclient.py.in:3476 ../mgmt/client/haclient.py.in:3625 #, python-format msgid "The \"%s\" has a \"%s\"." msgstr "" #: ../mgmt/client/haclient.py.in:3858 ../mgmt/client/haclient.py.in:4422 #: ../mgmt/client/haclient.py.in:4827 ../mgmt/client/haclient.py.in:4930 msgid "Add" msgstr "" #: ../mgmt/client/haclient.py.in:3894 msgid "Other" msgstr "" #: ../mgmt/client/haclient.py.in:3920 msgid "Please specify the type of object you want to add" msgstr "" #: ../mgmt/client/haclient.py.in:3962 msgid "Wizard" msgstr "" #: ../mgmt/client/haclient.py.in:3965 msgid "Dialog" msgstr "" #: ../mgmt/client/haclient.py.in:4209 #, python-format msgid "This will delete the %s \"%s\"" msgstr "" #: ../mgmt/client/haclient.py.in:4211 msgid "Delete the selected object?" msgstr "" #: ../mgmt/client/haclient.py.in:4378 msgid "Initial state of resource" msgstr "" #: ../mgmt/client/haclient.py.in:4383 msgid "" "Maximum number of copies (Defaults to the number of nodes in the cluster)" msgstr "" #: ../mgmt/client/haclient.py.in:4384 ../mgmt/client/haclient.py.in:4388 #: ../mgmt/client/haclient.py.in:4390 ../mgmt/client/haclient.py.in:4392 #: ../mgmt/client/haclient.py.in:4397 ../mgmt/client/haclient.py.in:4399 #: ../mgmt/client/haclient.py.in:4418 ../mgmt/client/haclient.py.in:9564 #: ../mgmt/client/haclient.py.in:9566 ../mgmt/client/haclient.py.in:9575 #: ../mgmt/client/haclient.py.in:9579 ../mgmt/client/haclient.py.in:9586 #: ../mgmt/client/haclient.py.in:9590 ../mgmt/client/haclient.py.in:9592 #: ../mgmt/client/haclient.py.in:9594 ../mgmt/client/haclient.py.in:9596 #: ../mgmt/client/haclient.py.in:9601 ../mgmt/client/haclient.py.in:9603 msgid "[ default ]" msgstr "" #: ../mgmt/client/haclient.py.in:4385 msgid "Maximum number of copies on a single node (Defaults to 1)" msgstr "" #: ../mgmt/client/haclient.py.in:4389 msgid "" "Notify all the other copies before stopping or starting a copy and when the " "action was successful (Defaults to false)" msgstr "" #: ../mgmt/client/haclient.py.in:4391 msgid "" "Globally Unique (Does each copy of the clone perform a different function? " "Defaults to false)" msgstr "" #: ../mgmt/client/haclient.py.in:4393 msgid "" "Interleave (Changes the behavior of ordering constraints (between clones/" "masters) so that instances can start/stop as soon as their peer instance has " "(rather than waiting for every instance of the other clone has). Defaults to " "false)" msgstr "" #: ../mgmt/client/haclient.py.in:4398 msgid "Maximum number of master copies (Defaults to 1)" msgstr "" #: ../mgmt/client/haclient.py.in:4400 msgid "Maximum number of master copies on a single node (Defaults to 1)" msgstr "" #: ../mgmt/client/haclient.py.in:4432 msgid "Basic Settings" msgstr "" #: ../mgmt/client/haclient.py.in:4454 msgid "Options" msgstr "" #: ../mgmt/client/haclient.py.in:4553 msgid "Add monitor operation" msgstr "" #: ../mgmt/client/haclient.py.in:4839 #, python-format msgid "Summary Of \"%s\"" msgstr "" #: ../mgmt/client/haclient.py.in:4841 msgid "Summary" msgstr "" #: ../mgmt/client/haclient.py.in:4860 #, python-format msgid "Sub-resource For \"%s\"" msgstr "" #: ../mgmt/client/haclient.py.in:4862 msgid "Sub-resource" msgstr "" #: ../mgmt/client/haclient.py.in:4864 msgid "Add " msgstr "" #: ../mgmt/client/haclient.py.in:4865 msgid "Continue Adding " msgstr "" #: ../mgmt/client/haclient.py.in:4932 msgid "Edit" msgstr "" #: ../mgmt/client/haclient.py.in:4974 msgid "" "This will reset the current object attributes and all sub-objects to the " "initial configurations." msgstr "" #: ../mgmt/client/haclient.py.in:4976 msgid "Reset the configurations?" msgstr "" #: ../mgmt/client/haclient.py.in:4986 msgid "Transition Information" msgstr "" #: ../mgmt/client/haclient.py.in:4993 msgid "Transition" msgstr "" #: ../mgmt/client/haclient.py.in:5001 msgid "History" msgstr "" #: ../mgmt/client/haclient.py.in:5030 msgid "Graph" msgstr "" #: ../mgmt/client/haclient.py.in:5041 msgid "Detail" msgstr "" #: ../mgmt/client/haclient.py.in:5045 msgid "Verbosity" msgstr "" #: ../mgmt/client/haclient.py.in:5072 msgid "Scores" msgstr "" #: ../mgmt/client/haclient.py.in:5133 ../mgmt/client/haclient.py.in:5166 msgid "Transitions" msgstr "" #: ../mgmt/client/haclient.py.in:5155 #, python-format msgid "[Omitted %d transitions...]" msgstr "" #: ../mgmt/client/haclient.py.in:5167 msgid "Searching the transitions may take a while," msgstr "" #: ../mgmt/client/haclient.py.in:5168 msgid "depending on the number of transitions..." msgstr "" #: ../mgmt/client/haclient.py.in:5169 msgid "Cannot find any transition record" msgstr "" #: ../mgmt/client/haclient.py.in:5211 msgid "The specified transition doesn't exist" msgstr "" #: ../mgmt/client/haclient.py.in:5242 msgid "Please specify a proper identity of a transition" msgstr "" #: ../mgmt/client/haclient.py.in:5243 msgid "Such as" msgstr "" #: ../mgmt/client/haclient.py.in:5245 msgid "Transition type: \"error\", \"warn\" or \"input\"" msgstr "" #: ../mgmt/client/haclient.py.in:5310 msgid "Transition Graph" msgstr "" #: ../mgmt/client/haclient.py.in:5311 msgid "Generating the transition graph may take a while..." msgstr "" #: ../mgmt/client/haclient.py.in:5312 msgid "Failed to generate the transition graph" msgstr "" #: ../mgmt/client/haclient.py.in:5325 msgid "Transition Detail" msgstr "" #: ../mgmt/client/haclient.py.in:5326 msgid "Generating the transition detail may take a while..." msgstr "" #: ../mgmt/client/haclient.py.in:5327 msgid "Failed to generate the transition detail" msgstr "" #: ../mgmt/client/haclient.py.in:5339 msgid "Transition Scores" msgstr "" #: ../mgmt/client/haclient.py.in:5340 msgid "Generating the transition scores may take a while..." msgstr "" #: ../mgmt/client/haclient.py.in:5341 msgid "Failed to generate the transition scores" msgstr "" #: ../mgmt/client/haclient.py.in:5352 msgid "Cannot save the graph for specified transition" msgstr "" #: ../mgmt/client/haclient.py.in:5355 msgid "PNG Image" msgstr "" #: ../mgmt/client/haclient.py.in:5356 msgid "JPEG Image" msgstr "" #: ../mgmt/client/haclient.py.in:5357 msgid "GIF Image" msgstr "" #: ../mgmt/client/haclient.py.in:5358 msgid "TIFF Image" msgstr "" #: ../mgmt/client/haclient.py.in:5359 msgid "Dot File" msgstr "" #: ../mgmt/client/haclient.py.in:5390 msgid "Cannot save the information for specified transition" msgstr "" #: ../mgmt/client/haclient.py.in:5410 msgid "" "Interpreting the graph:\n" "* Arrows indicate ordering dependancies\n" "* Dashed-arrows indicate dependancies that are not present in the transition " "graph\n" "* Actions with a dashed border of any color do not form part of the " "transition graph\n" "* Actions with a green border form part of the transition graph\n" "* Actions with a red border are ones the cluster would like to execute but " "are unrunnable\n" "* Actions with a blue border are ones the cluster does not feel need to be " "executed\n" "* Actions with orange text are pseudo/pretend actions that the cluster uses " "to simplify the graph\n" "* Actions with black text are sent to the LRM\n" "* Resource actions have text of the form {rsc}_{action}_{interval} {node}\n" "* Any action depending on an action with a red border will not be able to " "execute.\n" "* Loops are really bad. Please report them to the development team." msgstr "" #: ../mgmt/client/haclient.py.in:5462 msgid "From" msgstr "" #: ../mgmt/client/haclient.py.in:5463 msgid "To" msgstr "" #: ../mgmt/client/haclient.py.in:5488 msgid "The \"From\" time should before the \"To\" one" msgstr "" #: ../mgmt/client/haclient.py.in:5530 msgid "Save as ..." msgstr "" #: ../mgmt/client/haclient.py.in:5560 msgid "Permission denied" msgstr "" #: ../mgmt/client/haclient.py.in:5564 msgid "A file with the same name already exists" msgstr "" #: ../mgmt/client/haclient.py.in:5566 msgid "Do you want to overwrite it?" msgstr "" #: ../mgmt/client/haclient.py.in:5569 msgid "Replace it?" msgstr "" #: ../mgmt/client/haclient.py.in:5743 msgid "Description of Cluster Report" msgstr "" #: ../mgmt/client/haclient.py.in:5756 msgid "Severity" msgstr "" #: ../mgmt/client/haclient.py.in:5771 msgid "Component" msgstr "" #: ../mgmt/client/haclient.py.in:5785 msgid "Subject" msgstr "" #: ../mgmt/client/haclient.py.in:5794 msgid "Detailed description" msgstr "" #: ../mgmt/client/haclient.py.in:5899 ../mgmt/client/haclient.py.in:7032 msgid "Connected to " msgstr "" #: ../mgmt/client/haclient.py.in:5901 msgid "Not connected" msgstr "" #: ../mgmt/client/haclient.py.in:5903 ../mgmt/client/haclient.py.in:5905 #: ../mgmt/client/haclient.py.in:5907 msgid "(" msgstr "" #: ../mgmt/client/haclient.py.in:5903 msgid "Simple Mode" msgstr "" #: ../mgmt/client/haclient.py.in:5903 ../mgmt/client/haclient.py.in:5905 #: ../mgmt/client/haclient.py.in:5907 msgid ")" msgstr "" #: ../mgmt/client/haclient.py.in:5905 msgid "Expert Mode" msgstr "" #: ../mgmt/client/haclient.py.in:5907 msgid "Hack Mode" msgstr "" #: ../mgmt/client/haclient.py.in:5917 msgid "The data of current view have been changed." msgstr "" #: ../mgmt/client/haclient.py.in:5986 msgid "Empty information returned" msgstr "" #: ../mgmt/client/haclient.py.in:5990 msgid "Nothing returned" msgstr "" #: ../mgmt/client/haclient.py.in:5997 msgid "Do you want to quit ?" msgstr "" #: ../mgmt/client/haclient.py.in:6006 msgid "Login" msgstr "" #: ../mgmt/client/haclient.py.in:6070 msgid "Do you want to logout ?" msgstr "" #: ../mgmt/client/haclient.py.in:6077 msgid "\"Indicate pending operations\" has been activated." msgstr "" #: ../mgmt/client/haclient.py.in:6078 msgid "It could affect the performance." msgstr "" #: ../mgmt/client/haclient.py.in:6079 msgid "Turn it off ?" msgstr "" #: ../mgmt/client/haclient.py.in:6088 msgid "Cannot get any shadow CIB" msgstr "" #: ../mgmt/client/haclient.py.in:6107 msgid "Shadow CIB" msgstr "" #: ../mgmt/client/haclient.py.in:6109 msgid "Recreate the specified shadow CIB from the live CIB" msgstr "" #: ../mgmt/client/haclient.py.in:6111 msgid "Delete the specified shadow CIB" msgstr "" #: ../mgmt/client/haclient.py.in:6113 msgid "Upload the specified shadow CIB to the cluster" msgstr "" #: ../mgmt/client/haclient.py.in:6116 msgid "Shadow Name" msgstr "" #: ../mgmt/client/haclient.py.in:6139 #, python-format msgid "The shadow CIB \"%s\"has been successfully commited." msgstr "" #: ../mgmt/client/haclient.py.in:6140 ../mgmt/client/haclient.py.in:6142 msgid "Switch to the live CIB?" msgstr "" #: ../mgmt/client/haclient.py.in:6162 ../mgmt/client/haclient.py.in:6187 msgid "Shadow CIB Diff" msgstr "" #: ../mgmt/client/haclient.py.in:6169 #, python-format msgid "Differences between the live CIB and the shadow CIB \"%s\"" msgstr "" #: ../mgmt/client/haclient.py.in:6188 msgid "Generating the shadow CIB differences may take a while..." msgstr "" #: ../mgmt/client/haclient.py.in:6189 msgid "Failed to generate the shadow CIB differences" msgstr "" #: ../mgmt/client/haclient.py.in:6217 msgid "Diff Files" msgstr "" #: ../mgmt/client/haclient.py.in:6218 msgid "All Files" msgstr "" #: ../mgmt/client/haclient.py.in:6227 msgid "Cannot save the shadow diff" msgstr "" #: ../mgmt/client/haclient.py.in:6254 msgid "Create Shadow CIB" msgstr "" #: ../mgmt/client/haclient.py.in:6277 msgid "A copy of the live CIB" msgstr "" #: ../mgmt/client/haclient.py.in:6281 msgid "A new CIB with empty cluster configuration" msgstr "" #: ../mgmt/client/haclient.py.in:6310 msgid "Please specify a name for the shadow CIB." msgstr "" #: ../mgmt/client/haclient.py.in:6313 msgid "Please specify another name for avoiding confusion." msgstr "" #: ../mgmt/client/haclient.py.in:6316 #, python-format msgid "A shadow CIB \"%s\" already exists and it's currently active." msgstr "" #: ../mgmt/client/haclient.py.in:6319 #, python-format msgid "A shadow CIB \"%s\" already exists." msgstr "" #: ../mgmt/client/haclient.py.in:6320 msgid "Specify another name, or select \"Force\" if you want to override it." msgstr "" #. else : #: ../mgmt/client/haclient.py.in:6339 #, python-format msgid "A new shadow CIB \"%s\" has been successfully created." msgstr "" #: ../mgmt/client/haclient.py.in:6340 msgid "Switch to it now?" msgstr "" #: ../mgmt/client/haclient.py.in:6342 #, python-format msgid "Switch to the new created shadow CIB \"%s\"?" msgstr "" #: ../mgmt/client/haclient.py.in:6359 msgid "Or you don't have the permission." msgstr "" #: ../mgmt/client/haclient.py.in:6411 ../mgmt/client/haclient.py.in:6421 msgid "Cluster Report" msgstr "" #: ../mgmt/client/haclient.py.in:6422 msgid "Generating the cluster report may take a while," msgstr "" #: ../mgmt/client/haclient.py.in:6423 msgid "depending on the size of logs..." msgstr "" #: ../mgmt/client/haclient.py.in:6424 ../mgmt/client/haclient.py.in:6430 msgid "Failed to generate the cluster report" msgstr "" #: ../mgmt/client/haclient.py.in:6440 msgid "Incomplete data" msgstr "" #: ../mgmt/client/haclient.py.in:6477 ../mgmt/client/haclient.py.in:6485 #: ../mgmt/client/haclient.py.in:6547 ../mgmt/client/haclient.py.in:6571 #: ../mgmt/client/haclient.py.in:6589 msgid "Tar error" msgstr "" #: ../mgmt/client/haclient.py.in:6638 ../mgmt/client/haclient.py.in:6841 msgid "About" msgstr "" #: ../mgmt/client/haclient.py.in:6720 msgid "Pacemaker GUI" msgstr "" #: ../mgmt/client/haclient.py.in:6824 msgid "_Connection" msgstr "" #: ../mgmt/client/haclient.py.in:6825 msgid "Log_in" msgstr "" #: ../mgmt/client/haclient.py.in:6825 msgid "login to cluster" msgstr "" #: ../mgmt/client/haclient.py.in:6826 msgid "Log_out" msgstr "" #: ../mgmt/client/haclient.py.in:6826 msgid "logout from cluster" msgstr "" #: ../mgmt/client/haclient.py.in:6827 msgid "_Quit" msgstr "" #: ../mgmt/client/haclient.py.in:6827 msgid "Quit the Program" msgstr "" #: ../mgmt/client/haclient.py.in:6828 msgid "_View" msgstr "" #: ../mgmt/client/haclient.py.in:6829 msgid "_Shadow" msgstr "" #: ../mgmt/client/haclient.py.in:6830 msgid "_New" msgstr "" #: ../mgmt/client/haclient.py.in:6830 msgid "Create a new shadow CIB" msgstr "" #: ../mgmt/client/haclient.py.in:6831 msgid "Di_ff" msgstr "" #: ../mgmt/client/haclient.py.in:6831 msgid "Differences between the live CIB and the shadow CIB" msgstr "" #: ../mgmt/client/haclient.py.in:6832 msgid "_Reset" msgstr "" #: ../mgmt/client/haclient.py.in:6832 msgid "Recreate a shadow CIB from the live CIB" msgstr "" #: ../mgmt/client/haclient.py.in:6833 msgid "_Delete" msgstr "" #: ../mgmt/client/haclient.py.in:6833 msgid "Delete a shadow CIB" msgstr "" #: ../mgmt/client/haclient.py.in:6834 msgid "_Commit" msgstr "" #: ../mgmt/client/haclient.py.in:6834 msgid "Upload a shadow CIB to the cluster" msgstr "" #: ../mgmt/client/haclient.py.in:6835 msgid "_Switch" msgstr "" #: ../mgmt/client/haclient.py.in:6835 msgid "Switch working CIB" msgstr "" #: ../mgmt/client/haclient.py.in:6836 msgid "_Tools" msgstr "" #: ../mgmt/client/haclient.py.in:6837 msgid "_Transition Information" msgstr "" #: ../mgmt/client/haclient.py.in:6838 msgid "Show Transition Information" msgstr "" #: ../mgmt/client/haclient.py.in:6839 msgid "Cluster Re_port" msgstr "" #: ../mgmt/client/haclient.py.in:6839 msgid "generate a cluster report" msgstr "" #: ../mgmt/client/haclient.py.in:6840 msgid "_Help" msgstr "" #: ../mgmt/client/haclient.py.in:6841 msgid "_About" msgstr "" #: ../mgmt/client/haclient.py.in:6847 msgid "_Simple Mode" msgstr "" #: ../mgmt/client/haclient.py.in:6847 msgid "Switch to simple mode" msgstr "" #: ../mgmt/client/haclient.py.in:6848 msgid "_Expert Mode" msgstr "" #: ../mgmt/client/haclient.py.in:6848 msgid "Switch to expert mode" msgstr "" #: ../mgmt/client/haclient.py.in:6849 msgid "_Hack Mode" msgstr "" #: ../mgmt/client/haclient.py.in:6849 msgid "Switch to hack mode" msgstr "" #: ../mgmt/client/haclient.py.in:6912 msgid "Not Connected" msgstr "" #: ../mgmt/client/haclient.py.in:7009 msgid "Can't resolve address of server " msgstr "" #: ../mgmt/client/haclient.py.in:7015 ../mgmt/client/haclient.py.in:7021 msgid "Can't connect to server " msgstr "" #: ../mgmt/client/haclient.py.in:7024 msgid "" "Failed in the authentication.\n" " User Name or Password may be wrong.\n" " or the user doesn't belong to haclient group" msgstr "" #: ../mgmt/client/haclient.py.in:7027 msgid "" "Can't login to server.\n" " The protocols may be mismatched." msgstr "" #: ../mgmt/client/haclient.py.in:7040 ../mgmt/client/haclient.py.in:7169 msgid "Updating data from server..." msgstr "" #: ../mgmt/client/haclient.py.in:7162 msgid "Reconnecting..." msgstr "" #: ../mgmt/client/haclient.py.in:7240 msgid "Pacemaker GUI requires pyxml package to process DTD" msgstr "" #: ../mgmt/client/haclient.py.in:7365 msgid "Cannot expand the Relax-NG schema" msgstr "" #: ../mgmt/client/haclient.py.in:7371 msgid "Failed to parse the CIB XML" msgstr "" #: ../mgmt/client/haclient.py.in:7377 msgid "Failed to parse the Relax-NG schema" msgstr "" #: ../mgmt/client/haclient.py.in:8923 #, python-format msgid "Invalid identifier \"%s\"" msgstr "" #: ../mgmt/client/haclient.py.in:9526 ../mgmt/client/haclient.py.in:9800 msgid ". " msgstr "" #: ../mgmt/client/haclient.py.in:9526 ../mgmt/client/haclient.py.in:9800 msgid ".\n" msgstr "" #: ../mgmt/client/haclient.py.in:9549 ../mgmt/client/haclient.py.in:9553 #, python-format msgid "\"%s\" is required" msgstr "" #: ../mgmt/client/haclient.py.in:9549 msgid "Class" msgstr "" #: ../mgmt/client/haclient.py.in:9553 msgid "Provider" msgstr "" #: ../mgmt/client/haclient.py.in:9554 msgid "for an OCF primitive" msgstr "" #: ../mgmt/client/haclient.py.in:9563 msgid "" "If not all resources can be active, the cluster will stop lower priority " "resources in order to keep higher priority ones active." msgstr "" #: ../mgmt/client/haclient.py.in:9565 msgid "What state should the cluster attempt to keep this resource in?" msgstr "" #: ../mgmt/client/haclient.py.in:9567 msgid "Is the cluster allowed to start and stop the resource?" msgstr "" #: ../mgmt/client/haclient.py.in:9572 msgid "" "How much does the resource prefer to stay where it is? Defaults to the value " "of \"default-resource-stickiness\"" msgstr "" #: ../mgmt/client/haclient.py.in:9574 msgid "" "How many failures should occur for this resource on a node before making the " "node ineligible to host this resource. Default: \"none\"" msgstr "" #: ../mgmt/client/haclient.py.in:9575 msgid "(mark the resource as unmanaged)" msgstr "" #: ../mgmt/client/haclient.py.in:9576 msgid "" "What should the cluster do if it ever finds the resource active on more than " "one node." msgstr "" #: ../mgmt/client/haclient.py.in:9578 msgid "" "How many seconds to wait before acting as if the failure had not occurred " "(and potentially allowing the resource back to the node on which it failed. " "Default: \"never\"" msgstr "" #: ../mgmt/client/haclient.py.in:9580 msgid "" "Allow resource migration for resources which support migrate_to/migrate_from " "actions" msgstr "" #: ../mgmt/client/haclient.py.in:9585 msgid "" "How many copies of the resource to start. Defaults to the number of nodes in " "the cluster." msgstr "" #: ../mgmt/client/haclient.py.in:9587 msgid "How many copies of the resource can be started on a single node." msgstr "" #: ../mgmt/client/haclient.py.in:9591 msgid "" "When stopping or starting a copy of the clone, tell all the other copies " "beforehand and when the action was successful." msgstr "" #: ../mgmt/client/haclient.py.in:9593 msgid "Does each copy of the clone perform a different function?" msgstr "" #: ../mgmt/client/haclient.py.in:9595 msgid "Should the copies be started in series (instead of in parallel)" msgstr "" #: ../mgmt/client/haclient.py.in:9597 msgid "" "Changes the behavior of ordering constraints (between clones/masters) so " "that instances can start/stop as soon as their peer instance has (rather " "than waiting for every instance of the other clone has)." msgstr "" #: ../mgmt/client/haclient.py.in:9602 msgid "How many copies of the resource can be promoted to master status." msgstr "" #: ../mgmt/client/haclient.py.in:9604 msgid "" "How many copies of the resource can be promoted to master status on a single " "node." msgstr "" #: ../mgmt/client/haclient.py.in:9736 msgid "required" msgstr "" #: ../mgmt/client/haclient.py.in:9739 msgid ", " msgstr "" #: ../mgmt/client/haclient.py.in:9740 msgid "unique" msgstr "" #: ../mgmt/client/haclient.py.in:10103 #, python-format msgid "Invalid \"%s\"" msgstr "" #: ../mgmt/client/haclient.py.in:10180 msgid "* Specify dependencies between the actions on two resources" msgstr "" #: ../mgmt/client/haclient.py.in:10181 ../mgmt/client/haclient.py.in:10299 msgid "* Please set the required attributes" msgstr "" #: ../mgmt/client/haclient.py.in:10186 ../mgmt/client/haclient.py.in:10202 #, python-format msgid "* %s %s %s %s %s" msgstr "" #: ../mgmt/client/haclient.py.in:10191 ../mgmt/client/haclient.py.in:10194 #: ../mgmt/client/haclient.py.in:10206 ../mgmt/client/haclient.py.in:10209 #: ../mgmt/client/haclient.py.in:10262 ../mgmt/client/haclient.py.in:10273 #, python-format msgid "* If cannot %s %s, do not %s %s" msgstr "" #: ../mgmt/client/haclient.py.in:10244 msgid "* Specify the order of actions on resources" msgstr "" #: ../mgmt/client/haclient.py.in:10245 ../mgmt/client/haclient.py.in:10351 msgid "* Please set the required attributes or add resource sets" msgstr "" #: ../mgmt/client/haclient.py.in:10256 ../mgmt/client/haclient.py.in:10270 #, python-format msgid "* %s %s before %s %s" msgstr "" #: ../mgmt/client/haclient.py.in:10298 msgid "* Specify where a resource should run relative to another resource" msgstr "" #: ../mgmt/client/haclient.py.in:10306 ../mgmt/client/haclient.py.in:10316 #: ../mgmt/client/haclient.py.in:10363 #, python-format msgid "* Make %s %s on the same node as %s %s ( %s according to %s )" msgstr "" #: ../mgmt/client/haclient.py.in:10309 ../mgmt/client/haclient.py.in:10319 #: ../mgmt/client/haclient.py.in:10366 #, python-format msgid "* If %s cannot be %s on any node, then %s won't be %s anywhere" msgstr "" #: ../mgmt/client/haclient.py.in:10312 ../mgmt/client/haclient.py.in:10368 #, python-format msgid "* If %s cannot be %s on any node, %s won't be affected" msgstr "" #: ../mgmt/client/haclient.py.in:10322 ../mgmt/client/haclient.py.in:10332 #: ../mgmt/client/haclient.py.in:10380 #, python-format msgid "" "* Prevent %s from being %s on the same node as %s %s ( %s according to %s )" msgstr "" #: ../mgmt/client/haclient.py.in:10325 ../mgmt/client/haclient.py.in:10335 #: ../mgmt/client/haclient.py.in:10383 #, python-format msgid "" "* If %s is %s on the only (or every) available node, then %s won't be %s " "anywhere" msgstr "" #: ../mgmt/client/haclient.py.in:10328 ../mgmt/client/haclient.py.in:10385 #, python-format msgid "" "* If %s is %s on the only (or every) available node, %s won't be affected" msgstr "" #: ../mgmt/client/haclient.py.in:10338 msgid "" "* Combine this colocation score and the appropriate location scores to " "decide where to put the resources" msgstr "" #: ../mgmt/client/haclient.py.in:10350 msgid "* Specify where resources should run relative to other resources" msgstr "" #: ../mgmt/client/haclient.py.in:10358 #, python-format msgid "" "* Combine this \"Score\" and corresponding location scores to decide where " "to place %s" msgstr "" #: ../mgmt/client/haclient.py.in:10371 #, python-format msgid "" "* Prefer to make %s %s on the same node as %s %s ( %s according to %s )" msgstr "" #: ../mgmt/client/haclient.py.in:10388 #, python-format msgid "" "* Prefer to prevent %s from being %s on the same node as %s %s ( %s " "according to %s )" msgstr "" #: ../mgmt/client/haclient.py.in:10394 #, python-format msgid "" "* Please specify a valid \"Score\" to determine the location relationship " "between %s and %s" msgstr "" msgid "Delete" msgstr "" msgid "Commit" msgstr "" msgid "Clone" msgstr "" msgid "Expression" msgstr "" msgid "Operations" msgstr "" msgid "Password" msgstr "" msgid "Score" msgstr "" msgid "Interval" msgstr "" msgid "Interval Origin" msgstr "" msgid "Timeout" msgstr "" msgid "Start Delay" msgstr "" msgid "Enabled" msgstr "" msgid "Disabled" msgstr "" msgid "Record Pending" msgstr "" msgid "Role" msgstr "" msgid "Requires" msgstr "" msgid "Prereq" msgstr "" msgid "On Fail" msgstr "" msgid "First" msgstr "" msgid "Then" msgstr "" msgid "First Action" msgstr "" msgid "Then Action" msgstr "" msgid "Action" msgstr "" msgid "To Action" msgstr "" msgid "Symmetrical" msgstr "" msgid "With Resource" msgstr "" msgid "Resource Role" msgstr "" msgid "With Resource Role" msgstr "" msgid "From Role" msgstr "" msgid "To Role" msgstr "" msgid "Node Attribute" msgstr "" msgid "Optional" msgstr "" msgid "User Name" msgstr "" msgid "Nodes" msgstr "" msgid "Constraints" msgstr "" msgid "Resource Location" msgstr "" msgid "Resource Order" msgstr "" msgid "Resource Colocation" msgstr "" msgid "Value" msgstr "" msgid "Description" msgstr "" msgid "Attribute" msgstr "" msgid "Operation" msgstr "" msgid "Debug Level" msgstr "" msgid "UDP Port" msgstr "" msgid "Keep Alive" msgstr "" msgid "Warning Time" msgstr "" msgid "Dead Time" msgstr "" msgid "Initial Dead Time" msgstr "" msgid "Quorum Server" msgstr "" msgid "Use Logd" msgstr "" msgid "Auto Join" msgstr "" msgid "API Authentication" msgstr "" msgid "Auto Failback" msgstr "" msgid "Baud Rate" msgstr "" msgid "Debug File" msgstr "" msgid "Dead Ping" msgstr "" msgid "Heartbeat Version" msgstr "" msgid "Log Facility" msgstr "" msgid "Message Format" msgstr "" msgid "Nice Failback" msgstr "" msgid "running (Master)" msgstr "" msgid "running (Slave)" msgstr "" msgid "Force" msgstr "" msgid "Server(:Port)" msgstr "" msgid "Boolean Op" msgstr "" msgid "Score Attribute" msgstr "" msgid "Score Attribute Mangle" msgstr "" msgid "Configuration" msgstr "" msgid "Refresh" msgstr "" msgid "Reprobe" msgstr "" msgid "Required" msgstr "" msgid "Primitive" msgstr "" msgid "Group" msgstr "" msgid "Master" msgstr "" msgid "Uname" msgstr "" msgid "CRM Config" msgstr "" msgid "Cluster Property Set" msgstr "" msgid "Resource Defaults" msgstr "" msgid "Operation Defaults" msgstr "" msgid "Meta Attributes" msgstr "" msgid "Instance Attributes" msgstr "" msgid "Utilization" msgstr "" msgid "Nvpair" msgstr "" msgid "To Node" msgstr "" msgid "Duration" msgstr "" msgid "Migration Threshold" msgstr "" msgid "Fail Count" msgstr "" msgid "Call ID" msgstr "" msgid "Return Code" msgstr "" msgid "Last Run" msgstr "" msgid "Exec Time" msgstr "" msgid "Queue Time" msgstr "" msgid "Last Return Code Change" msgstr "" msgid "ID Ref" msgstr "" msgid "End" msgstr "" msgid "Rule" msgstr "" msgid "Lifetime" msgstr "" msgid "Date Expression" msgstr "" msgid "Date Spec" msgstr "" msgid "Resource Set" msgstr "" msgid "Sequential" msgstr "" msgid "Resource Ref" msgstr "" msgid "" "This program is free software; you can redistribute it and/or\n" "modify it under the terms of the GNU General Public License\n" "as published by the Free Software Foundation; either version 2\n" "of the License, or (at your option) any later version.\n" "\n" "This program is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" "GNU General Public License for more details.\n" "\n" "You should have received a copy of the GNU General Public License\n" "along with this program; if not, write to the Free Software\n" "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA." msgstr "" pacemaker-mgmt-pacemaker-mgmt-2.1.2/po/ja.po000066400000000000000000001657441211477743100206760ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: pacemaker-mgmt 2.0.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-04-17 16:29+0800\n" "PO-Revision-Date: 2009-05-14 17:07+0800\n" "Last-Translator: Hideo Yamauchi \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: ../mgmt/client/haclient.py.in:139 msgid "Do not delete the root directory" msgstr "ルートディレクトリã¯å‰Šé™¤å‡ºæ¥ã¾ã›ã‚“" #: ../mgmt/client/haclient.py.in:147 ../mgmt/client/haclient.py.in:153 #: ../mgmt/client/haclient.py.in:158 ../mgmt/client/haclient.py.in:3334 #: ../mgmt/client/haclient.py.in:3342 ../mgmt/client/haclient.py.in:5396 #: ../mgmt/client/haclient.py.in:5402 ../mgmt/client/haclient.py.in:5575 #: ../mgmt/client/haclient.py.in:6233 ../mgmt/client/haclient.py.in:6239 #: ../mgmt/client/haclient.py.in:6458 ../mgmt/client/haclient.py.in:6603 #: ../mgmt/client/haclient.py.in:6612 ../mgmt/client/haclient.py.in:7414 #: ../mgmt/client/haclient.py.in:7422 msgid "System error" msgstr "システムエラー" #: ../mgmt/client/haclient.py.in:147 ../mgmt/client/haclient.py.in:153 #: ../mgmt/client/haclient.py.in:158 ../mgmt/client/haclient.py.in:2729 #: ../mgmt/client/haclient.py.in:2877 ../mgmt/client/haclient.py.in:3262 #: ../mgmt/client/haclient.py.in:3307 ../mgmt/client/haclient.py.in:3313 #: ../mgmt/client/haclient.py.in:3334 ../mgmt/client/haclient.py.in:3342 #: ../mgmt/client/haclient.py.in:5299 ../mgmt/client/haclient.py.in:5396 #: ../mgmt/client/haclient.py.in:5402 ../mgmt/client/haclient.py.in:5564 #: ../mgmt/client/haclient.py.in:5575 ../mgmt/client/haclient.py.in:5986 #: ../mgmt/client/haclient.py.in:5990 ../mgmt/client/haclient.py.in:6169 #: ../mgmt/client/haclient.py.in:6233 ../mgmt/client/haclient.py.in:6239 #: ../mgmt/client/haclient.py.in:6446 ../mgmt/client/haclient.py.in:6458 #: ../mgmt/client/haclient.py.in:6474 ../mgmt/client/haclient.py.in:6477 #: ../mgmt/client/haclient.py.in:6485 ../mgmt/client/haclient.py.in:6504 #: ../mgmt/client/haclient.py.in:6511 ../mgmt/client/haclient.py.in:6527 #: ../mgmt/client/haclient.py.in:6543 ../mgmt/client/haclient.py.in:6547 #: ../mgmt/client/haclient.py.in:6567 ../mgmt/client/haclient.py.in:6571 #: ../mgmt/client/haclient.py.in:6584 ../mgmt/client/haclient.py.in:6589 #: ../mgmt/client/haclient.py.in:6603 ../mgmt/client/haclient.py.in:6612 #: ../mgmt/client/haclient.py.in:7371 ../mgmt/client/haclient.py.in:7377 #: ../mgmt/client/haclient.py.in:7407 ../mgmt/client/haclient.py.in:7414 #: ../mgmt/client/haclient.py.in:7422 ../mgmt/client/haclient.py.in:8923 msgid ": " msgstr ": " #: ../mgmt/client/haclient.py.in:191 msgid "Message" msgstr "メッセージ" #: ../mgmt/client/haclient.py.in:211 msgid "Confirm" msgstr "確èª" #: ../mgmt/client/haclient.py.in:253 msgid "The specified time should be numeric prefixed." msgstr "æ™‚é–“ã¯æ•°å€¤ã§æŒ‡å®šã—ã¦ä¸‹ã•ã„." #: ../mgmt/client/haclient.py.in:264 msgid "The specified time should default with second unit, " msgstr "時間ã®ãƒ‡ãƒ•ォルtå˜ä½ã¯ç§’(s)ã§ã™." #: ../mgmt/client/haclient.py.in:265 #, python-format msgid "" "or should be suffixed with one of the following units:\n" " %s" msgstr "" "ã‚‚ã—ãã¯ã€æ¬¡ã®å˜ä½ã®ï¼‘ã¤ã‚’最後ã«ä»˜ã‘ã¦ä¸‹ã•ã„:\n" " %s" #: ../mgmt/client/haclient.py.in:358 msgid "Add Parameter" msgstr "パラメータã®è¿½åŠ " #: ../mgmt/client/haclient.py.in:360 msgid "Add Operation" msgstr "オペレーションã®è¿½åŠ " #: ../mgmt/client/haclient.py.in:401 ../mgmt/client/haclient.py.in:8640 #: ../mgmt/client/haclient.py.in:8931 msgid " can't be empty" msgstr "空ã«ã¯å‡ºæ¥ã¾ã›ã‚“" #: ../mgmt/client/haclient.py.in:508 ../mgmt/client/haclient.py.in:665 #: ../mgmt/client/haclient.py.in:1744 msgid "Type" msgstr "タイプ" #: ../mgmt/client/haclient.py.in:666 msgid "ID" msgstr "ID" #: ../mgmt/client/haclient.py.in:771 msgid "St_art" msgstr "é–‹å§‹(_A)" #: ../mgmt/client/haclient.py.in:771 msgid "Start resource" msgstr "リソースã®é–‹å§‹" #: ../mgmt/client/haclient.py.in:772 msgid "_Stop" msgstr "åœæ­¢(_S)" #: ../mgmt/client/haclient.py.in:772 msgid "Stop resource" msgstr "リソースã®åœæ­¢" #: ../mgmt/client/haclient.py.in:773 msgid "_Default" msgstr "デフォルト(_D)" #: ../mgmt/client/haclient.py.in:773 msgid "Work as default" msgstr "作業デフォルト" #: ../mgmt/client/haclient.py.in:774 msgid "_Cleanup Resource" msgstr "リソースã®ã‚¯ãƒªãƒ¼ãƒ³ã‚¢ãƒƒãƒ—(_C)" #: ../mgmt/client/haclient.py.in:774 msgid "Cleanup resource" msgstr "リソースã®ã‚¯ãƒªãƒ¼ãƒ³ã‚¢ãƒƒãƒ—" #: ../mgmt/client/haclient.py.in:775 msgid "Migra_te Resource" msgstr "リソースã®ç§»å‹•(_T)" #: ../mgmt/client/haclient.py.in:775 msgid "Migrate a resource to specified node" msgstr "リソースを指定ノードã«ç§»å‹•" #: ../mgmt/client/haclient.py.in:777 msgid "Clea_r Migrate Constraints" msgstr "移動制約ã®ã‚¯ãƒªã‚¢(_R)" #: ../mgmt/client/haclient.py.in:778 msgid "Clear constraints created by migrate" msgstr "移動ã«ã‚ˆã£ã¦è¨­å®šã•れãŸåˆ¶ç´„をクリア" #: ../mgmt/client/haclient.py.in:780 msgid "_Unmanage Resource" msgstr "リソースを管ç†å¤–ã«è¨­å®š(_U)" #: ../mgmt/client/haclient.py.in:780 msgid "Put a resource into unmanaged mode" msgstr "リソースを管ç†å¤–ã«è¨­å®š" #: ../mgmt/client/haclient.py.in:782 msgid "_Manage Resource" msgstr "リソースを管ç†çŠ¶æ…‹ã«è¨­å®š(_M)" #: ../mgmt/client/haclient.py.in:782 msgid "Put a resource into managed mode" msgstr "リソースを管ç†çŠ¶æ…‹ã«è¨­å®š" #: ../mgmt/client/haclient.py.in:784 msgid "Re_fresh Resources" msgstr "リソースã®ãƒªãƒ•レッシュ(_F)" #: ../mgmt/client/haclient.py.in:784 msgid "Refresh CIB from the LRM status" msgstr "LRMステータスã‹ã‚‰ã®CIBã®ãƒªãƒ•レッシュ" #: ../mgmt/client/haclient.py.in:786 msgid "Re_probe Resources" msgstr "リソースã®å†ãƒ—ローブ(_P)" #: ../mgmt/client/haclient.py.in:786 msgid "Reprobe for resources started outside of the CRM" msgstr "CRM外ã§é–‹å§‹ã•れるリソースã®ç‚ºã®å†ãƒ—ローブ" #: ../mgmt/client/haclient.py.in:790 msgid "_Standby" msgstr "スタンãƒã‚¤(_S)" #: ../mgmt/client/haclient.py.in:790 msgid "Make the node standby" msgstr "ノードをスタンãƒã‚¤ã«è¨­å®š" #: ../mgmt/client/haclient.py.in:791 msgid "_Active" msgstr "アクティブ(_A)" #: ../mgmt/client/haclient.py.in:791 msgid "Make the node active" msgstr "ノードをアクティブã«è¨­å®š" #: ../mgmt/client/haclient.py.in:795 msgid "_Group By Node" msgstr "ノードã§ã‚°ãƒ«ãƒ¼ãƒ—化(_G)" #: ../mgmt/client/haclient.py.in:795 msgid "Group resources by node" msgstr "ノードã®ãƒªã‚½ãƒ¼ã‚¹ã§ã‚°ãƒ«ãƒ¼ãƒ—化" #: ../mgmt/client/haclient.py.in:796 msgid "_Maintenance Mode" msgstr "ä¿å®ˆãƒ¢ãƒ¼ãƒ‰(_M)" #: ../mgmt/client/haclient.py.in:797 msgid "Switch to maintenance mode" msgstr "ä¿å®ˆãƒ¢ãƒ¼ãƒ‰ã¸åˆ‡æ›ãˆ" #: ../mgmt/client/haclient.py.in:798 msgid "_Indicate Pending Operations" msgstr "å¾…ã¡æ“作ã®è¡¨ç¤º(_I)" #: ../mgmt/client/haclient.py.in:799 msgid "Indicate pending(starting/stopping) operations" msgstr "å¾…ã¡æ“作(開始中/åœæ­¢ä¸­)動作ã®è¡¨ç¤º" #: ../mgmt/client/haclient.py.in:987 ../mgmt/client/haclient.py.in:1024 #: ../mgmt/client/haclient.py.in:1307 ../mgmt/client/haclient.py.in:1410 #: ../mgmt/client/haclient.py.in:1619 ../mgmt/client/haclient.py.in:2304 #: ../mgmt/client/haclient.py.in:2316 ../mgmt/client/haclient.py.in:3755 #: ../mgmt/client/haclient.py.in:3894 ../mgmt/client/haclient.py.in:4481 #: ../mgmt/client/haclient.py.in:4993 ../mgmt/client/haclient.py.in:5001 #: ../mgmt/client/haclient.py.in:5045 ../mgmt/client/haclient.py.in:5243 #: ../mgmt/client/haclient.py.in:5756 ../mgmt/client/haclient.py.in:5771 #: ../mgmt/client/haclient.py.in:5785 ../mgmt/client/haclient.py.in:5794 #: ../mgmt/client/haclient.py.in:6018 ../mgmt/client/haclient.py.in:6266 #: ../mgmt/client/haclient.py.in:8545 ../mgmt/client/haclient.py.in:8762 #: ../mgmt/client/haclient.py.in:8885 ../mgmt/client/haclient.py.in:8931 #: ../mgmt/client/haclient.py.in:10103 msgid ":" msgstr ":" #: ../mgmt/client/haclient.py.in:1075 #, python-format msgid "last failure at \"%s\"" msgstr "æœ€å¾Œã®æ•…éšœã¯\"%s\"" #: ../mgmt/client/haclient.py.in:1219 ../mgmt/client/haclient.py.in:1224 #: ../mgmt/client/haclient.py.in:1670 ../mgmt/client/haclient.py.in:2007 #: ../mgmt/client/haclient.py.in:2009 msgid "standby" msgstr "スタンãƒã‚¤" #: ../mgmt/client/haclient.py.in:1220 ../mgmt/client/haclient.py.in:1225 #: ../mgmt/client/haclient.py.in:1985 msgid "never started" msgstr "é–‹å§‹ã—ãªã„" #: ../mgmt/client/haclient.py.in:1278 #, python-format msgid "Cannot find the %s: %s" msgstr "%s: %sãŒè¦‹ä»˜ã‹ã‚Šã¾ã›ã‚“." #: ../mgmt/client/haclient.py.in:1304 msgid "Caused by your previous action, this attribute has been set to \"" msgstr "å‰ã®æ“作ã«ã‚ˆã£ã¦ã€å±žæ€§ã¯ã‚»ãƒƒãƒˆã•れã¾ã—ãŸã€‚設定値㯠\"" #: ../mgmt/client/haclient.py.in:1306 msgid "\"." msgstr "\"." #: ../mgmt/client/haclient.py.in:1307 msgid "Recommended" msgstr "推奨ã™ã‚‹æ“作" #: ../mgmt/client/haclient.py.in:1308 msgid "" "Select \"Clear All\" to remove the attributes for all of the sub-resources." msgstr "サブリソースã®å±žæ€§ã‚’解除ã®ç‚ºã«\"Clear All\"ã‚’é¸æŠžã—ã¦ä¸‹ã•ã„." #: ../mgmt/client/haclient.py.in:1309 msgid "All of the sub-resources will inherit the attributes from their parent." msgstr "å…¨ã¦ã®ã‚µãƒ–リソースã¯ã€è¦ªã®å±žæ€§ã‚’継承ã—ã¾ã™." #: ../mgmt/client/haclient.py.in:1314 #, python-format msgid "Clear the %s=\"%s\" attribute for sub-resource \"" msgstr "サブリソースã®å±žæ€§å€¤ %s=\"%s\" をクリアã—ã¾ã™ã‹ \"" #: ../mgmt/client/haclient.py.in:1315 msgid "\"?" msgstr "\"?" #: ../mgmt/client/haclient.py.in:1330 #, python-format msgid "Cannot %s %s: XML processing error" msgstr "%s ã« %s を出æ¥ã¾ã›ã‚“。XML処ç†ã‚¨ãƒ©ãƒ¼ã§ã™." #: ../mgmt/client/haclient.py.in:1353 ../mgmt/client/haclient.py.in:1367 msgid "all resources" msgstr "全リソース" #: ../mgmt/client/haclient.py.in:1359 ../mgmt/client/haclient.py.in:1363 #: ../mgmt/client/haclient.py.in:1381 msgid "all nodes" msgstr "全ノード" #: ../mgmt/client/haclient.py.in:1361 msgid "Cleanup Resource" msgstr "リソースã®ã‚¯ãƒªãƒ¼ãƒ³ã‚¢ãƒƒãƒ—" #: ../mgmt/client/haclient.py.in:1362 ../mgmt/client/haclient.py.in:1566 msgid "Resource" msgstr "リソース" #: ../mgmt/client/haclient.py.in:1363 msgid "Node" msgstr "ノード" #: ../mgmt/client/haclient.py.in:1395 msgid "Migrate Resource" msgstr "リソースã®ç§»å‹•" #: ../mgmt/client/haclient.py.in:1556 msgid "all migrated resources" msgstr "全リソースを移動" #: ../mgmt/client/haclient.py.in:1565 msgid "Clear Migrate Constraints" msgstr "移動制約ã®ã‚¯ãƒªã‚¢" #. node_options = node_list[:] #. node_options.insert(0, "") #: ../mgmt/client/haclient.py.in:1610 #, python-format msgid "%s Resources" msgstr "%s リソース" #: ../mgmt/client/haclient.py.in:1670 ../mgmt/client/haclient.py.in:1678 msgid "Make" msgstr "ノード " #: ../mgmt/client/haclient.py.in:1678 msgid "active" msgstr "をアクティブã«ã—ã¾ã™ã‹" #: ../mgmt/client/haclient.py.in:1745 msgid "Name" msgstr "åå‰" #: ../mgmt/client/haclient.py.in:1746 msgid "Status" msgstr "状態" #: ../mgmt/client/haclient.py.in:1747 msgid "Details" msgstr "詳細" #: ../mgmt/client/haclient.py.in:1803 msgid "unmanaged" msgstr "管ç†å¤–" #: ../mgmt/client/haclient.py.in:1804 ../mgmt/client/haclient.py.in:2000 msgid "unclean" msgstr "éžã‚¯ãƒªãƒ¼ãƒ³" #: ../mgmt/client/haclient.py.in:1806 msgid "failed" msgstr "æ•…éšœ" #: ../mgmt/client/haclient.py.in:1808 msgid "starting" msgstr "開始中" #: ../mgmt/client/haclient.py.in:1810 msgid "stopping" msgstr "åœæ­¢ä¸­" #: ../mgmt/client/haclient.py.in:1812 ../mgmt/client/haclient.py.in:2094 msgid "not running" msgstr "未起動" #: ../mgmt/client/haclient.py.in:1814 ../mgmt/client/haclient.py.in:2096 #: ../mgmt/client/haclient.py.in:2106 msgid "running" msgstr "起動中" #: ../mgmt/client/haclient.py.in:1820 ../mgmt/client/haclient.py.in:1987 #: ../mgmt/client/haclient.py.in:2104 msgid "ping node" msgstr "pingノード" #: ../mgmt/client/haclient.py.in:1822 ../mgmt/client/haclient.py.in:1993 msgid "online" msgstr "オンライン" #: ../mgmt/client/haclient.py.in:1905 msgid "have quorum" msgstr "QUORUM有" #: ../mgmt/client/haclient.py.in:1907 msgid "no quorum" msgstr "QUORUMç„¡" #: ../mgmt/client/haclient.py.in:1918 ../mgmt/client/haclient.py.in:1935 #: ../mgmt/client/haclient.py.in:2331 msgid "Cluster" msgstr "クラスタ" #: ../mgmt/client/haclient.py.in:1921 msgid "Inactive resources" msgstr "アクティブã§ãªã„リソース" #: ../mgmt/client/haclient.py.in:1938 msgid "Resources" msgstr "リソース" #: ../mgmt/client/haclient.py.in:1952 msgid " on " msgstr " on " #: ../mgmt/client/haclient.py.in:1981 msgid "unknown" msgstr "䏿˜Ž" #: ../mgmt/client/haclient.py.in:1989 msgid "unknown type" msgstr "䏿˜Žãªã‚¿ã‚¤ãƒ—" #: ../mgmt/client/haclient.py.in:1995 msgid "pending" msgstr "Pingノード障害検出時間" #: ../mgmt/client/haclient.py.in:1997 msgid "offline" msgstr "オフライン" #: ../mgmt/client/haclient.py.in:2003 msgid "dc" msgstr "dc" #: ../mgmt/client/haclient.py.in:2007 msgid "on-fail" msgstr "æ•…éšœ" #: ../mgmt/client/haclient.py.in:2093 msgid "primitive" msgstr "プリミティブ" #: ../mgmt/client/haclient.py.in:2098 msgid "fail" msgstr "æ•…éšœ" #: ../mgmt/client/haclient.py.in:2110 msgid "group" msgstr "グループ" #: ../mgmt/client/haclient.py.in:2110 msgid "resources" msgstr "リソース" #: ../mgmt/client/haclient.py.in:2110 msgid "clone" msgstr "クローン" #: ../mgmt/client/haclient.py.in:2110 msgid "master" msgstr "マスタ" #: ../mgmt/client/haclient.py.in:2112 msgid "orders" msgstr "é †åº" #: ../mgmt/client/haclient.py.in:2112 msgid "locations" msgstr "é…ç½®" #: ../mgmt/client/haclient.py.in:2112 msgid "colocations" msgstr "組ã¿åˆã‚ã›é…ç½®" #: ../mgmt/client/haclient.py.in:2135 ../mgmt/client/haclient.py.in:4997 #: ../mgmt/client/haclient.py.in:6381 msgid "Live" msgstr "ライブ" #: ../mgmt/client/haclient.py.in:2137 msgid "Shadow: " msgstr "シャドー: " #: ../mgmt/client/haclient.py.in:2172 msgid "Management" msgstr "ä¿å®ˆ" #: ../mgmt/client/haclient.py.in:2337 msgid "CIB" msgstr "CIB" #: ../mgmt/client/haclient.py.in:2347 msgid "View XML" msgstr "XMLビュー" #: ../mgmt/client/haclient.py.in:2354 msgid "The Whole CIB" msgstr "CIB全体" #: ../mgmt/client/haclient.py.in:2356 msgid "The Configuration Section" msgstr "æ§‹æˆã‚»ã‚¯ã‚·ãƒ§ãƒ³" #: ../mgmt/client/haclient.py.in:2383 #, python-format msgid "The object \"%s\" doesn't exist" msgstr "オブジェクト\"%s\"ãŒå­˜åœ¨ã—ã¾ã›ã‚“" #: ../mgmt/client/haclient.py.in:2439 ../mgmt/client/haclient.py.in:2729 msgid "Default" msgstr "デフォルト" #: ../mgmt/client/haclient.py.in:2441 ../mgmt/client/haclient.py.in:3160 #: ../mgmt/client/haclient.py.in:4936 msgid "Reset" msgstr "リセット" #: ../mgmt/client/haclient.py.in:2549 msgid "Multiple \"Cluster Property Set\" in \"CRM Config\"." msgstr "" "é‡è¤‡ã—㟠\"クラスタプロパティセット\" ㌠\"CRMã®æ§‹æˆ\"ã«è¨­å®šã•れã¦ã„ã¾ã™." #: ../mgmt/client/haclient.py.in:2550 ../mgmt/client/haclient.py.in:3457 #: ../mgmt/client/haclient.py.in:3479 ../mgmt/client/haclient.py.in:3607 #: ../mgmt/client/haclient.py.in:3628 msgid "We are switching to \"Hack Mode\" to view them properly." msgstr "モードを\"Hackモード\"ã«åˆ‡ã‚Šæ›¿ãˆã¦ã€ãƒ—ロパティを確èªã—ã¦ä¸‹ã•ã„." #: ../mgmt/client/haclient.py.in:2556 msgid "Cannot update the crm configuration: No \"crm_config\" in CIB" msgstr "CIBã®ä¸­ã«\"crm_config\"ãŒå­˜åœ¨ã—ãªã„ãŸã‚ã€æ§‹æˆã‚’更新出æ¥ã¾ã›ã‚“." #: ../mgmt/client/haclient.py.in:2563 msgid "Cannot update the crm configuration" msgstr "æ§‹æˆã‚’更新出æ¥ã¾ã›ã‚“." #: ../mgmt/client/haclient.py.in:2631 msgid "There are unsaved changes in current page." msgstr "ä¿å­˜ã•れã¦ã„ãªã„変更ãŒã€ç¾åœ¨ã®ãƒšãƒ¼ã‚¸ã«ã‚りã¾ã™." #: ../mgmt/client/haclient.py.in:2631 ../mgmt/client/haclient.py.in:5917 msgid "Apply the changes?" msgstr "変更ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹?" #: ../mgmt/client/haclient.py.in:2649 msgid "Policy Engine" msgstr "ãƒãƒªã‚·ãƒ¼ã‚¨ãƒ³ã‚¸ãƒ³" #: ../mgmt/client/haclient.py.in:2661 msgid "CRM Daemon" msgstr "CRMデーモン" #: ../mgmt/client/haclient.py.in:2723 ../mgmt/client/haclient.py.in:2726 #: ../mgmt/client/haclient.py.in:5242 ../mgmt/client/haclient.py.in:9537 #: ../mgmt/client/haclient.py.in:9540 ../mgmt/client/haclient.py.in:9808 #: ../mgmt/client/haclient.py.in:9811 msgid "." msgstr "." #: ../mgmt/client/haclient.py.in:2746 ../mgmt/client/haclient.py.in:2803 #: ../mgmt/client/haclient.py.in:2807 ../mgmt/client/haclient.py.in:8576 #: ../mgmt/client/haclient.py.in:8595 ../mgmt/client/haclient.py.in:8944 #: ../mgmt/client/haclient.py.in:9713 ../mgmt/client/haclient.py.in:9717 #: ../mgmt/client/haclient.py.in:9781 msgid "default" msgstr "デフォルト" #: ../mgmt/client/haclient.py.in:2868 msgid "List Mode" msgstr "リストモード" #: ../mgmt/client/haclient.py.in:2869 msgid "Tree Mode" msgstr "ツリーモード" #: ../mgmt/client/haclient.py.in:2870 msgid "XML Mode" msgstr "XMLモード" #: ../mgmt/client/haclient.py.in:2877 msgid "Show" msgstr "表示" #: ../mgmt/client/haclient.py.in:3150 msgid "The object doesn't exist" msgstr "オブジェクトãŒå­˜åœ¨ã—ã¾ã›ã‚“" #: ../mgmt/client/haclient.py.in:3159 msgid "Edit XML" msgstr "XML編集" #: ../mgmt/client/haclient.py.in:3174 msgid "Import" msgstr "インãƒãƒ¼ãƒˆ" #: ../mgmt/client/haclient.py.in:3175 msgid "Import XML" msgstr "XMLをインãƒãƒ¼ãƒˆ" #: ../mgmt/client/haclient.py.in:3176 msgid "Export" msgstr "エキスãƒãƒ¼ãƒˆ" #: ../mgmt/client/haclient.py.in:3177 msgid "Export XML" msgstr "XMLをエキスãƒãƒ¼ãƒˆ" #: ../mgmt/client/haclient.py.in:3241 msgid "OVR" msgstr "上書" #: ../mgmt/client/haclient.py.in:3243 msgid "INS" msgstr "挿入" #: ../mgmt/client/haclient.py.in:3246 #, python-format msgid "Ln %d, Col %d\t%s" msgstr "ライン %d カラム %d\t%s" #: ../mgmt/client/haclient.py.in:3262 msgid "Failed to parse the XML" msgstr "XMLã®ãƒ‘ースã«å¤±æ•—ã—ã¾ã—ãŸ" #: ../mgmt/client/haclient.py.in:3274 msgid "Open File" msgstr "ファイルオープン" #: ../mgmt/client/haclient.py.in:3283 msgid "All files" msgstr "å…¨ã¦ã®ãƒ•ァイル" #: ../mgmt/client/haclient.py.in:3288 msgid "XML files" msgstr "XMLファイル" #: ../mgmt/client/haclient.py.in:3307 ../mgmt/client/haclient.py.in:3313 #: ../mgmt/client/haclient.py.in:5299 ../mgmt/client/haclient.py.in:6446 #: ../mgmt/client/haclient.py.in:6474 ../mgmt/client/haclient.py.in:6504 #: ../mgmt/client/haclient.py.in:6511 ../mgmt/client/haclient.py.in:6527 #: ../mgmt/client/haclient.py.in:6543 ../mgmt/client/haclient.py.in:6567 #: ../mgmt/client/haclient.py.in:6584 ../mgmt/client/haclient.py.in:7407 msgid "I/O error" msgstr "I/Oエラー" #: ../mgmt/client/haclient.py.in:3455 ../mgmt/client/haclient.py.in:3605 #, python-format msgid "The \"%s\" has multiple \"%s\" sets." msgstr "\"%s\"ã¯ã€è¤‡æ•°ã®\"%s\"ãŒã‚りã¾ã™." #: ../mgmt/client/haclient.py.in:3476 ../mgmt/client/haclient.py.in:3625 #, python-format msgid "The \"%s\" has a \"%s\"." msgstr "\"%s\"ã¯ã€\"%s\"ãŒã‚りã¾ã™." #: ../mgmt/client/haclient.py.in:3858 ../mgmt/client/haclient.py.in:4422 #: ../mgmt/client/haclient.py.in:4827 ../mgmt/client/haclient.py.in:4930 msgid "Add" msgstr "追加" #: ../mgmt/client/haclient.py.in:3894 msgid "Other" msgstr "ãã®ä»–" #: ../mgmt/client/haclient.py.in:3920 msgid "Please specify the type of object you want to add" msgstr "追加ã™ã‚‹ã‚ªãƒ–ジェクトã®ã‚¿ã‚¤ãƒ—を指定ã—ã¦ä¸‹ã•ã„" #: ../mgmt/client/haclient.py.in:3962 msgid "Wizard" msgstr "ウィザード" #: ../mgmt/client/haclient.py.in:3965 msgid "Dialog" msgstr "ダイアログ" #: ../mgmt/client/haclient.py.in:4209 #, python-format msgid "This will delete the %s \"%s\"" msgstr "%s \"%s\"を削除ã—ã¾ã™" #: ../mgmt/client/haclient.py.in:4211 msgid "Delete the selected object?" msgstr "é¸æŠžã•れãŸã‚ªãƒ–ジェクトを削除ã—ã¾ã™ã‹?" #: ../mgmt/client/haclient.py.in:4378 msgid "Initial state of resource" msgstr "リソース状態ã®åˆæœŸåŒ–" #: ../mgmt/client/haclient.py.in:4383 msgid "" "Maximum number of copies (Defaults to the number of nodes in the cluster)" msgstr "ã‚¯ãƒ©ã‚¹ã‚¿å†…ã®æœ€å¤§ã‚¯ãƒ­ãƒ¼ãƒ³æ•°(デフォルト:ノード数)" #: ../mgmt/client/haclient.py.in:4384 ../mgmt/client/haclient.py.in:4388 #: ../mgmt/client/haclient.py.in:4390 ../mgmt/client/haclient.py.in:4392 #: ../mgmt/client/haclient.py.in:4397 ../mgmt/client/haclient.py.in:4399 #: ../mgmt/client/haclient.py.in:4418 ../mgmt/client/haclient.py.in:9564 #: ../mgmt/client/haclient.py.in:9566 ../mgmt/client/haclient.py.in:9575 #: ../mgmt/client/haclient.py.in:9579 ../mgmt/client/haclient.py.in:9586 #: ../mgmt/client/haclient.py.in:9590 ../mgmt/client/haclient.py.in:9592 #: ../mgmt/client/haclient.py.in:9594 ../mgmt/client/haclient.py.in:9596 #: ../mgmt/client/haclient.py.in:9601 ../mgmt/client/haclient.py.in:9603 msgid "[ default ]" msgstr "[ デフォルト ]" #: ../mgmt/client/haclient.py.in:4385 msgid "Maximum number of copies on a single node (Defaults to 1)" msgstr "ノード内ã®ã‚¯ãƒ­ãƒ¼ãƒ³æ•°(デフォルト:1)" #: ../mgmt/client/haclient.py.in:4389 msgid "" "Notify all the other copies before stopping or starting a copy and when the " "action was successful (Defaults to false)" msgstr "クローンãŒé–‹å§‹ãƒ»åœæ­¢ã™ã‚‹å‰ã«é€šçŸ¥ã™ã‚‹(デフォルト:false)" #: ../mgmt/client/haclient.py.in:4391 msgid "" "Globally Unique (Does each copy of the clone perform a different function? " "Defaults to false)" msgstr "" "グローãƒãƒ«ãƒ¦ãƒ‹ãƒ¼ã‚¯(個々ã®ã‚¯ãƒ­ãƒ¼ãƒ³ãŒç•°ãªã‚‹æ©Ÿèƒ½ã‚’æä¾›ã™ã‚‹ã‹ã©ã†ã‹?デフォルト:" "false)" #: ../mgmt/client/haclient.py.in:4393 msgid "" "Interleave (Changes the behavior of ordering constraints (between clones/" "masters) so that instances can start/stop as soon as their peer instance has " "(rather than waiting for every instance of the other clone has). Defaults to " "false)" msgstr "" "インターリーブ (マスタ・クローンã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹é”ãŒã€ä»–ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã‚’å¾…ãŸãš" "ã«ã™ãã«é–‹å§‹ãƒ»åœæ­¢å‡ºæ¥ã‚‹ã‚ˆã†ã«ã€ãƒžã‚¹ã‚¿ãƒ»ã‚¯ãƒ­ãƒ¼ãƒ³å†…ã§ã®åˆ¶ç´„ã®ä½œç”¨ を変更ã—ã¾" "ã™ã€‚(デフォルト:false)." #: ../mgmt/client/haclient.py.in:4398 msgid "Maximum number of master copies (Defaults to 1)" msgstr "ã‚¯ãƒ©ã‚¹ã‚¿å†…ã®æœ€å¤§ãƒžã‚¹ã‚¿æ•°(デフォルト:1)" #: ../mgmt/client/haclient.py.in:4400 msgid "Maximum number of master copies on a single node (Defaults to 1)" msgstr "ãƒŽãƒ¼ãƒ‰å†…ã®æœ€å¤§ãƒžã‚¹ã‚¿æ•°(デフォルト:1)" #: ../mgmt/client/haclient.py.in:4432 msgid "Basic Settings" msgstr "基本設定" #: ../mgmt/client/haclient.py.in:4454 msgid "Options" msgstr "オプション" #: ../mgmt/client/haclient.py.in:4553 msgid "Add monitor operation" msgstr "モニタæ“作ã®è¿½åŠ " #: ../mgmt/client/haclient.py.in:4839 #, python-format msgid "Summary Of \"%s\"" msgstr "\"%s\"ã®æ¦‚è¦" #: ../mgmt/client/haclient.py.in:4841 msgid "Summary" msgstr "概è¦" #: ../mgmt/client/haclient.py.in:4860 #, python-format msgid "Sub-resource For \"%s\"" msgstr "\"%s\" サブリソース用" #: ../mgmt/client/haclient.py.in:4862 msgid "Sub-resource" msgstr "サブリソース" #: ../mgmt/client/haclient.py.in:4864 msgid "Add " msgstr "追加ã™ã‚‹" #: ../mgmt/client/haclient.py.in:4865 msgid "Continue Adding " msgstr "追加を続ã‘ã‚‹" #: ../mgmt/client/haclient.py.in:4932 msgid "Edit" msgstr "編集" #: ../mgmt/client/haclient.py.in:4974 msgid "" "This will reset the current object attributes and all sub-objects to the " "initial configurations." msgstr "" "ç¾åœ¨ã®ã‚ªãƒ–ジェクトã®å±žæ€§ã‚’リセットã—ã¾ã™.ãã—ã¦å…¨ã¦ã®ã‚µãƒ–ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã®æ§‹æˆã‚‚" "åˆæœŸåŒ–ã•れã¾ã™." #: ../mgmt/client/haclient.py.in:4976 msgid "Reset the configurations?" msgstr "æ§‹æˆã‚’リセットã—ã¾ã™ã‹?" #: ../mgmt/client/haclient.py.in:4986 msgid "Transition Information" msgstr "é·ç§»æƒ…å ±" #: ../mgmt/client/haclient.py.in:4993 msgid "Transition" msgstr "é·ç§»" #: ../mgmt/client/haclient.py.in:5001 msgid "History" msgstr "履歴" #: ../mgmt/client/haclient.py.in:5030 msgid "Graph" msgstr "グラフ" #: ../mgmt/client/haclient.py.in:5041 msgid "Detail" msgstr "詳細" #: ../mgmt/client/haclient.py.in:5045 msgid "Verbosity" msgstr "é¸æŠž" #: ../mgmt/client/haclient.py.in:5072 msgid "Scores" msgstr "スコア" #: ../mgmt/client/haclient.py.in:5133 ../mgmt/client/haclient.py.in:5166 msgid "Transitions" msgstr "é·ç§»" #: ../mgmt/client/haclient.py.in:5155 #, python-format msgid "[Omitted %d transitions...]" msgstr "[リスト表示ã‹ã‚‰çœç•¥ã•れ㟠%d 個ã®é·ç§»æƒ…å ±ãŒã‚りã¾ã™...]" #: ../mgmt/client/haclient.py.in:5167 msgid "Searching the transitions may take a while," msgstr "é·ç§»æƒ…報を検索中ã§ã™" #: ../mgmt/client/haclient.py.in:5168 msgid "depending on the number of transitions..." msgstr "å¿…è¦ã¨ãªã‚‹ã‚µã‚¤ã‚ºã‚’計算ã—ã¦ã„ã¦ã¾ã™..." #: ../mgmt/client/haclient.py.in:5169 msgid "Cannot find any transition record" msgstr "é·ç§»æƒ…å ±ãŒè¦‹ä»˜ã‹ã‚Šã¾ã›ã‚“" #: ../mgmt/client/haclient.py.in:5211 msgid "The specified transition doesn't exist" msgstr "オブジェクトãŒå­˜åœ¨ã—ã¾ã›ã‚“" #: ../mgmt/client/haclient.py.in:5242 msgid "Please specify a proper identity of a transition" msgstr "システムã§äºˆç´„ã•れãŸåå‰ã®ç‚ºã€åˆ¥ã®åå‰ã§æŒ‡å®šã—ã¦ä¸‹ã•ã„." #: ../mgmt/client/haclient.py.in:5243 msgid "Such as" msgstr "例" #: ../mgmt/client/haclient.py.in:5245 msgid "Transition type: \"error\", \"warn\" or \"input\"" msgstr "é·ç§»æƒ…報タイプ: \"error\", \"warn\" or \"input\"" #: ../mgmt/client/haclient.py.in:5310 msgid "Transition Graph" msgstr "é·ç§»ã‚°ãƒ©ãƒ•" #: ../mgmt/client/haclient.py.in:5311 msgid "Generating the transition graph may take a while..." msgstr "é·ç§»ã‚°ãƒ©ãƒ•を作æˆä¸­ã§ã™ã€‚æš«ããŠå¾…ã¡ä¸‹ã•ã„..." #: ../mgmt/client/haclient.py.in:5312 msgid "Failed to generate the transition graph" msgstr "é·ç§»ã‚°ãƒ©ãƒ•ã®ç”Ÿæˆã«å¤±æ•—ã—ã¾ã—ãŸ" #: ../mgmt/client/haclient.py.in:5325 msgid "Transition Detail" msgstr "é·ç§»è©³ç´°" #: ../mgmt/client/haclient.py.in:5326 msgid "Generating the transition detail may take a while..." msgstr "é·ç§»è©³ç´°ã‚’作æˆä¸­ã§ã™ã€‚æš«ããŠå¾…ã¡ä¸‹ã•ã„..." #: ../mgmt/client/haclient.py.in:5327 msgid "Failed to generate the transition detail" msgstr "é·ç§»è©³ç´°ã®ç”Ÿæˆã«å¤±æ•—ã—ã¾ã—ãŸ" #: ../mgmt/client/haclient.py.in:5339 msgid "Transition Scores" msgstr "é·ç§»ã‚¹ã‚³ã‚¢" #: ../mgmt/client/haclient.py.in:5340 msgid "Generating the transition scores may take a while..." msgstr "é·ç§»ã‚¹ã‚³ã‚¢ã‚’作æˆä¸­ã§ã™ã€‚æš«ããŠå¾…ã¡ä¸‹ã•ã„..." #: ../mgmt/client/haclient.py.in:5341 msgid "Failed to generate the transition scores" msgstr "é·ç§»ã‚¹ã‚³ã‚¢ã®ç”Ÿæˆã«å¤±æ•—ã—ã¾ã—ãŸ" #: ../mgmt/client/haclient.py.in:5352 msgid "Cannot save the graph for specified transition" msgstr "指定ã•れãŸé·ç§»ã‚°ãƒ©ãƒ•ã¯ä¿å­˜å‡ºæ¥ã¾ã›ã‚“" #: ../mgmt/client/haclient.py.in:5355 msgid "PNG Image" msgstr "PNGイメージ" #: ../mgmt/client/haclient.py.in:5356 msgid "JPEG Image" msgstr "JPEGイメージ" #: ../mgmt/client/haclient.py.in:5357 msgid "GIF Image" msgstr "GIFイメージ" #: ../mgmt/client/haclient.py.in:5358 msgid "TIFF Image" msgstr "TIFFイメージ" #: ../mgmt/client/haclient.py.in:5359 msgid "Dot File" msgstr "Dotファイル" #: ../mgmt/client/haclient.py.in:5390 msgid "Cannot save the information for specified transition" msgstr "指定ã•れãŸé·ç§»æƒ…報をä¿å­˜å‡ºæ¥ã¾ã›ã‚“" #: ../mgmt/client/haclient.py.in:5410 msgid "" "Interpreting the graph:\n" "* Arrows indicate ordering dependancies\n" "* Dashed-arrows indicate dependancies that are not present in the transition " "graph\n" "* Actions with a dashed border of any color do not form part of the " "transition graph\n" "* Actions with a green border form part of the transition graph\n" "* Actions with a red border are ones the cluster would like to execute but " "are unrunnable\n" "* Actions with a blue border are ones the cluster does not feel need to be " "executed\n" "* Actions with orange text are pseudo/pretend actions that the cluster uses " "to simplify the graph\n" "* Actions with black text are sent to the LRM\n" "* Resource actions have text of the form {rsc}_{action}_{interval} {node}\n" "* Any action depending on an action with a red border will not be able to " "execute.\n" "* Loops are really bad. Please report them to the development team." msgstr "" "グラフã®è§£é‡ˆã«ã¤ã„ã¦:\n" "* 矢å°ã¯ã€ä¾å­˜çŠ¶æ…‹ã®é †åºã‚’示ã—ã¾ã™ã€‚\n" "* ç ´ç·šã®çŸ¢å°ã¯ã€é·ç§»ã®ä¸­ã§å­˜åœ¨ã—ãªã„ä¾å­˜çŠ¶æ…‹ã‚’ç¤ºã—ã¾ã™ã€‚\n" "* 色ã®ã¤ã„ãŸç ´ç·šã®å‹•作もã€é·ç§»ã®ä¸€éƒ¨ã«ã¯ãªã‚Šã¾ã›ã‚“。\n" "* ç·‘ã®å¢ƒç•Œã®å‹•作ã¯ã€é·ç§»ã®ä¸€éƒ¨ã«ãªã‚Šã¾ã™ã€‚\n" "* 赤ã®å¢ƒç•Œã®å‹•作ã¯ã€ã‚¯ãƒ©ã‚¹ã‚¿ã§å®Ÿè¡Œã—よã†ã¨ã—ã¦ã„ã¦ã„ã¾ã™ãŒã€æœªå®Ÿè¡Œã§ã™ã€‚ \n" "* é’ã®å¢ƒç•Œã®å‹•作ã¯ã€ã‚¯ãƒ©ã‚¹ã‚¿ãŒå®Ÿè¡Œã™ã‚‹å¿…è¦ãŒãªã„ã¨åˆ¤æ–­ãŸã‚‚ã®ã§ã™ã€‚\n" "* ã‚ªãƒ¬ãƒ³ã‚¸ã®æ–‡å­—ã®å‹•作ã¯ã€é›†å›£ãŒã‚°ãƒ©ãƒ•ã‚’å˜ç´”化ã™ã‚‹ãŸã‚ã«ä½¿ã†pseudo/pretendã‚¢" "クションã§ã™ã€‚\n" "* é»’ã®æ–‡å­—ã®å‹•作ã¯ã€LRMã«é€ã‚‰ã‚Œã¾ã™ã€‚\n" "* リソースã®å‹•作ã¯ã€{リソース_動作_実行間隔 実行ã™ã‚‹ãƒŽãƒ¼ãƒ‰}ã‹ã‚‰ãªã‚‹ãƒ†ã‚­ã‚¹ãƒˆã‚’" "æŒã£ã¦ã„ã¾ã™ã€‚\n" "* 赤ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã«ä¾å­˜ã—ã¦ã„る動作ã¯ã€å®Ÿè¡Œã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã›ã‚“。\n" "* ループã—ã¦ã„ã‚‹é·ç§»ã¯å•題ã§ã™ã€‚å•題ã¨ãªã£ã¦ã„ã‚‹é·ç§»ã‚’開発ãƒãƒ¼ãƒ ã«å ±å‘Šã—ã¦ä¸‹" "ã•ã„。" #: ../mgmt/client/haclient.py.in:5462 msgid "From" msgstr "開始時間" #: ../mgmt/client/haclient.py.in:5463 msgid "To" msgstr "終了時間" #: ../mgmt/client/haclient.py.in:5488 msgid "The \"From\" time should before the \"To\" one" msgstr "\"開始時間\"ã¯ã€ \"終了時間\"ã®å‰ã®æ™‚é–“ã§ãªãã¦ã¯ã„ã‘ã¾ã›ã‚“." #: ../mgmt/client/haclient.py.in:5530 msgid "Save as ..." msgstr "åå‰ã‚’付ã‘ã¦ä¿å­˜" #: ../mgmt/client/haclient.py.in:5560 msgid "Permission denied" msgstr "権é™ãŒã‚りã¾ã›ã‚“" #: ../mgmt/client/haclient.py.in:5564 msgid "A file with the same name already exists" msgstr "æ—¢ã«åŒã˜åå‰ã®ãƒ•ァイルãŒå­˜åœ¨ã—ã¾ã™" #: ../mgmt/client/haclient.py.in:5566 msgid "Do you want to overwrite it?" msgstr "上書ãã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹?" #: ../mgmt/client/haclient.py.in:5569 msgid "Replace it?" msgstr "ç½®ãæ›ãˆã¾ã™ã‹?" #: ../mgmt/client/haclient.py.in:5743 msgid "Description of Cluster Report" msgstr "クラスタリãƒãƒ¼ãƒˆã®èª¬æ˜Ž" #: ../mgmt/client/haclient.py.in:5756 msgid "Severity" msgstr "深刻度" #: ../mgmt/client/haclient.py.in:5771 msgid "Component" msgstr "æ§‹æˆè¦ç´ " #: ../mgmt/client/haclient.py.in:5785 msgid "Subject" msgstr "題å" #: ../mgmt/client/haclient.py.in:5794 msgid "Detailed description" msgstr "詳細ãªèª¬æ˜Ž" #: ../mgmt/client/haclient.py.in:5899 ../mgmt/client/haclient.py.in:7032 msgid "Connected to " msgstr "接続中..." #: ../mgmt/client/haclient.py.in:5901 msgid "Not connected" msgstr "未接続" #: ../mgmt/client/haclient.py.in:5903 ../mgmt/client/haclient.py.in:5905 #: ../mgmt/client/haclient.py.in:5907 msgid "(" msgstr "(" #: ../mgmt/client/haclient.py.in:5903 msgid "Simple Mode" msgstr "ç°¡å˜ãƒ¢ãƒ¼ãƒ‰" #: ../mgmt/client/haclient.py.in:5903 ../mgmt/client/haclient.py.in:5905 #: ../mgmt/client/haclient.py.in:5907 msgid ")" msgstr ")" #: ../mgmt/client/haclient.py.in:5905 msgid "Expert Mode" msgstr "エキスパートモード" #: ../mgmt/client/haclient.py.in:5907 msgid "Hack Mode" msgstr "Hackモード" #: ../mgmt/client/haclient.py.in:5917 msgid "The data of current view have been changed." msgstr "表示ã—ã¦ã„るビューã®å…ƒã®ãƒ‡ãƒ¼ã‚¿ãŒå¤‰æ›´ã•れã¾ã—ãŸ." #: ../mgmt/client/haclient.py.in:5986 msgid "Empty information returned" msgstr "ç©ºã®æƒ…å ±ãŒè¿”ã•れã¾ã—ãŸ." #: ../mgmt/client/haclient.py.in:5990 msgid "Nothing returned" msgstr "何も返ã•れã¾ã›ã‚“ã§ã—ãŸ." #: ../mgmt/client/haclient.py.in:5997 msgid "Do you want to quit ?" msgstr "終了ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹?" #: ../mgmt/client/haclient.py.in:6006 msgid "Login" msgstr "ログイン" #: ../mgmt/client/haclient.py.in:6070 msgid "Do you want to logout ?" msgstr "ログアウトã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹?" #: ../mgmt/client/haclient.py.in:6077 msgid "\"Indicate pending operations\" has been activated." msgstr "å¾…ã¡ä¸­ã®æ“作ã®è¡¨ç¤ºãƒ¢ãƒ¼ãƒ‰ãŒã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã«ãªã£ã¦ã„ã¾ã™." #: ../mgmt/client/haclient.py.in:6078 msgid "It could affect the performance." msgstr "ã“ã®ã¾ã¾ã§ã¯ã€ãƒ‘フォーマンスã«å½±éŸ¿ã—ã¾ã™." #: ../mgmt/client/haclient.py.in:6079 msgid "Turn it off ?" msgstr "モードを解除ã—ã™ã‹?" #: ../mgmt/client/haclient.py.in:6088 msgid "Cannot get any shadow CIB" msgstr "シャドーCIBãŒå–得出æ¥ã¾ã›ã‚“ã§ã—ãŸ" #: ../mgmt/client/haclient.py.in:6107 msgid "Shadow CIB" msgstr "シャドーCIB" #: ../mgmt/client/haclient.py.in:6109 msgid "Recreate the specified shadow CIB from the live CIB" msgstr "シャドーCIBをライブCIBã‹ã‚‰ä½œæˆã™ã‚‹" #: ../mgmt/client/haclient.py.in:6111 msgid "Delete the specified shadow CIB" msgstr "シャドーCIBを削除ã™ã‚‹" #: ../mgmt/client/haclient.py.in:6113 msgid "Upload the specified shadow CIB to the cluster" msgstr "クラスタã«ã‚·ãƒ£ãƒ‰ãƒ¼CIBをアップロードã™ã‚‹" #: ../mgmt/client/haclient.py.in:6116 msgid "Shadow Name" msgstr "シャドーå" #: ../mgmt/client/haclient.py.in:6139 #, python-format msgid "The shadow CIB \"%s\"has been successfully commited." msgstr "シャドーCIB\"%s\"をコミットã—ã¾ã—ãŸã€‚" #: ../mgmt/client/haclient.py.in:6140 ../mgmt/client/haclient.py.in:6142 msgid "Switch to the live CIB?" msgstr "ライブCIBã«åˆ‡ã‚Šæ›ãˆã¾ã™ã‹?" #: ../mgmt/client/haclient.py.in:6162 ../mgmt/client/haclient.py.in:6187 msgid "Shadow CIB Diff" msgstr "シャドーCIBã®å·®åˆ†" #: ../mgmt/client/haclient.py.in:6169 #, python-format msgid "Differences between the live CIB and the shadow CIB \"%s\"" msgstr "ライブCIBã¨ã‚·ãƒ£ãƒ‰ãƒ¼CIB \"%s\" ã®é•ã„" #: ../mgmt/client/haclient.py.in:6188 msgid "Generating the shadow CIB differences may take a while..." msgstr "シャドーCIBã¨ã®é•ã„を生æˆä¸­ã§ã™ã€‚æš«ããŠå¾…ã¡ä¸‹ã•ã„..." #: ../mgmt/client/haclient.py.in:6189 msgid "Failed to generate the shadow CIB differences" msgstr "シャドーCIBã¨ã®é•ã„ã®ç”Ÿæˆã«å¤±æ•—ã—ã¾ã—ãŸ" #: ../mgmt/client/haclient.py.in:6217 msgid "Diff Files" msgstr "差分ファイル" #: ../mgmt/client/haclient.py.in:6218 msgid "All Files" msgstr "å…¨ã¦ã®ãƒ•ァイル" #: ../mgmt/client/haclient.py.in:6227 msgid "Cannot save the shadow diff" msgstr "差分ã®ä¿å­˜ã«å¤±æ•—ã—ã¾ã—ãŸ" #: ../mgmt/client/haclient.py.in:6254 msgid "Create Shadow CIB" msgstr "シャドーCIBã®ä½œæˆ" #: ../mgmt/client/haclient.py.in:6277 msgid "A copy of the live CIB" msgstr "ライブCIBã‹ã‚‰ã®ã‚³ãƒ”ー" #: ../mgmt/client/haclient.py.in:6281 msgid "A new CIB with empty cluster configuration" msgstr "æ–°ã—ã„CIBを空ã®ã‚¯ãƒ©ã‚¹ã‚¿æ§‹æˆã§ä½œæˆ" #: ../mgmt/client/haclient.py.in:6310 msgid "Please specify a name for the shadow CIB." msgstr "シャドーCIBã®åå‰ã‚’指定ã—ã¦ä¸‹ã•ã„." #: ../mgmt/client/haclient.py.in:6313 msgid "Please specify another name for avoiding confusion." msgstr "システムã§äºˆç´„ã•れãŸåå‰ã®ç‚ºã€åˆ¥ã®åå‰ã§æŒ‡å®šã—ã¦ä¸‹ã•ã„." #: ../mgmt/client/haclient.py.in:6316 #, python-format msgid "A shadow CIB \"%s\" already exists and it's currently active." msgstr "指定ã•れãŸã‚·ãƒ£ãƒ‰ãƒ¼CIB \"%s\"ã¯ã€æ—¢ã«å­˜åœ¨ã—ã¦ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã«ãªã£ã¦ã„ã¾ã™." #: ../mgmt/client/haclient.py.in:6319 #, python-format msgid "A shadow CIB \"%s\" already exists." msgstr "指定ã•れãŸã‚·ãƒ£ãƒ‰ãƒ¼CIB \"%s\" ã¯ã€æ—¢ã«å­˜åœ¨ã—ã¾ã™ã€‚" #: ../mgmt/client/haclient.py.in:6320 msgid "Specify another name, or select \"Force\" if you want to override it." msgstr "別ã®åå‰ã‚’指定ã™ã‚‹ã‹ã€\"強制\"を指定ã—ã¦ä¸Šæ›¸ãã—ã¦ä¸‹ã•ã„。" #. else : #: ../mgmt/client/haclient.py.in:6339 #, python-format msgid "A new shadow CIB \"%s\" has been successfully created." msgstr "æ–°ã—ã„シャドーCIB \"%s\" ãŒä½œæˆã•れã¾ã—ãŸã€‚" #: ../mgmt/client/haclient.py.in:6340 msgid "Switch to it now?" msgstr "切りæ›ãˆã¾ã™ã‹?" #: ../mgmt/client/haclient.py.in:6342 #, python-format msgid "Switch to the new created shadow CIB \"%s\"?" msgstr "æ–°ã—ã„シャドーCIB \"%s\"ã«åˆ‡ã‚Šæ›ãˆã¾ã™ã‹?" #: ../mgmt/client/haclient.py.in:6359 msgid "Or you don't have the permission." msgstr "ã¾ãŸã¯ã€ã‚ãªãŸã¯æ¨©é™ã‚’æŒã£ã¦ã„ã¾ã›ã‚“." #: ../mgmt/client/haclient.py.in:6411 ../mgmt/client/haclient.py.in:6421 msgid "Cluster Report" msgstr "クラスタリãƒãƒ¼ãƒˆ" #: ../mgmt/client/haclient.py.in:6422 msgid "Generating the cluster report may take a while," msgstr "クラスタリãƒãƒ¼ãƒˆã‚’作æˆä¸­ã§ã™ã€‚æš«ããŠå¾…ã¡ä¸‹ã•ã„..." #: ../mgmt/client/haclient.py.in:6423 msgid "depending on the size of logs..." msgstr "å¿…è¦ã¨ãªã‚‹ã‚µã‚¤ã‚ºã‚’計算ã—ã¦ã„ã¦ã¾ã™..." #: ../mgmt/client/haclient.py.in:6424 ../mgmt/client/haclient.py.in:6430 msgid "Failed to generate the cluster report" msgstr "クラスタリãƒãƒ¼ãƒˆã®ç”Ÿæˆã«å¤±æ•—ã—ã¾ã—ãŸ" #: ../mgmt/client/haclient.py.in:6440 msgid "Incomplete data" msgstr "ä¸å®Œå…¨ãªãƒ‡ãƒ¼ã‚¿" #: ../mgmt/client/haclient.py.in:6477 ../mgmt/client/haclient.py.in:6485 #: ../mgmt/client/haclient.py.in:6547 ../mgmt/client/haclient.py.in:6571 #: ../mgmt/client/haclient.py.in:6589 msgid "Tar error" msgstr "圧縮(Tar)エラー" #: ../mgmt/client/haclient.py.in:6638 ../mgmt/client/haclient.py.in:6841 msgid "About" msgstr "Pacemaker GUIã«ã¤ã„ã¦" #: ../mgmt/client/haclient.py.in:6720 msgid "Pacemaker GUI" msgstr "Pacemaker GUI" #: ../mgmt/client/haclient.py.in:6824 msgid "_Connection" msgstr "接続(_C)" #: ../mgmt/client/haclient.py.in:6825 msgid "Log_in" msgstr "ログイン(_I)" #: ../mgmt/client/haclient.py.in:6825 msgid "login to cluster" msgstr "クラスタã«ãƒ­ã‚°ã‚¤ãƒ³" #: ../mgmt/client/haclient.py.in:6826 msgid "Log_out" msgstr "ログアウト(_O)" #: ../mgmt/client/haclient.py.in:6826 msgid "logout from cluster" msgstr "クラスタã‹ã‚‰ãƒ­ã‚°ã‚¢ã‚¦ãƒˆ" #: ../mgmt/client/haclient.py.in:6827 msgid "_Quit" msgstr "終了(_Q)" #: ../mgmt/client/haclient.py.in:6827 msgid "Quit the Program" msgstr "プログラムを終了" #: ../mgmt/client/haclient.py.in:6828 msgid "_View" msgstr "ビュー(_V)" #: ../mgmt/client/haclient.py.in:6829 msgid "_Shadow" msgstr "シャドー(_S)" #: ../mgmt/client/haclient.py.in:6830 msgid "_New" msgstr "æ–°è¦(_N)" #: ../mgmt/client/haclient.py.in:6830 msgid "Create a new shadow CIB" msgstr "シャドーCIBã®ä½œæˆ" #: ../mgmt/client/haclient.py.in:6831 msgid "Di_ff" msgstr "差分(_F)" #: ../mgmt/client/haclient.py.in:6831 msgid "Differences between the live CIB and the shadow CIB" msgstr "ライブCIBã¨ã‚·ãƒ£ãƒ‰ãƒ¼CIBã®é•ã„" #: ../mgmt/client/haclient.py.in:6832 msgid "_Reset" msgstr "リセット(_R)" #: ../mgmt/client/haclient.py.in:6832 msgid "Recreate a shadow CIB from the live CIB" msgstr "ライブCIBã§ã‚·ãƒ£ãƒ‰ãƒ¼CIBã‚’å†ä½œæˆ" #: ../mgmt/client/haclient.py.in:6833 msgid "_Delete" msgstr "削除(_D)" #: ../mgmt/client/haclient.py.in:6833 msgid "Delete a shadow CIB" msgstr "シャドーCIBã®å‰Šé™¤" #: ../mgmt/client/haclient.py.in:6834 msgid "_Commit" msgstr "コミット(_C)" #: ../mgmt/client/haclient.py.in:6834 msgid "Upload a shadow CIB to the cluster" msgstr "シャドーCIBをクラスタã«ã‚¢ãƒƒãƒ—ロード" #: ../mgmt/client/haclient.py.in:6835 msgid "_Switch" msgstr "切りæ›ãˆ(_S)" #: ../mgmt/client/haclient.py.in:6835 msgid "Switch working CIB" msgstr "作業中ã®CIBã«åˆ‡ã‚Šæ›ãˆ" #: ../mgmt/client/haclient.py.in:6836 msgid "_Tools" msgstr "ツール(_T)" #: ../mgmt/client/haclient.py.in:6837 msgid "_Transition Information" msgstr "é·ç§»æƒ…å ±(_T)" #: ../mgmt/client/haclient.py.in:6838 msgid "Show Transition Information" msgstr "é·ç§»æƒ…å ±ã®è¡¨ç¤º" #: ../mgmt/client/haclient.py.in:6839 msgid "Cluster Re_port" msgstr "クラスタリãƒãƒ¼ãƒˆ(_R)" #: ../mgmt/client/haclient.py.in:6839 msgid "generate a cluster report" msgstr "クラスタリãƒãƒ¼ãƒˆã®ç”Ÿæˆ" #: ../mgmt/client/haclient.py.in:6840 msgid "_Help" msgstr "ヘルプ(_H)" #: ../mgmt/client/haclient.py.in:6841 msgid "_About" msgstr "Pacemaker GUIã«ã¤ã„ã¦(_A)" #: ../mgmt/client/haclient.py.in:6847 msgid "_Simple Mode" msgstr "ç°¡å˜ãƒ¢ãƒ¼ãƒ‰(_S)" #: ../mgmt/client/haclient.py.in:6847 msgid "Switch to simple mode" msgstr "ç°¡å˜ãƒ¢ãƒ¼ãƒ‰ã«åˆ‡ã‚Šæ›ãˆ" #: ../mgmt/client/haclient.py.in:6848 msgid "_Expert Mode" msgstr "エキスパートモード(_E)" #: ../mgmt/client/haclient.py.in:6848 msgid "Switch to expert mode" msgstr "エキスパートモードã«åˆ‡ã‚Šæ›ãˆ" #: ../mgmt/client/haclient.py.in:6849 msgid "_Hack Mode" msgstr "Hackモード(_H)" #: ../mgmt/client/haclient.py.in:6849 msgid "Switch to hack mode" msgstr "Hackモードã«åˆ‡ã‚Šæ›ãˆ" #: ../mgmt/client/haclient.py.in:6912 msgid "Not Connected" msgstr "未接続" #: ../mgmt/client/haclient.py.in:7009 msgid "Can't resolve address of server " msgstr "サーãƒã®ã‚¢ãƒ‰ãƒ¬ã‚¹ãŒè§£æ±ºå‡ºæ¥ã¾ã›ã‚“ã§ã—ãŸ. " #: ../mgmt/client/haclient.py.in:7015 ../mgmt/client/haclient.py.in:7021 msgid "Can't connect to server " msgstr "サーãƒã«æŽ¥ç¶šå‡ºæ¥ã¾ã›ã‚“ã§ã—ãŸ. " #: ../mgmt/client/haclient.py.in:7024 msgid "" "Failed in the authentication.\n" " User Name or Password may be wrong.\n" " or the user doesn't belong to haclient group" msgstr "" "ログインèªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸã€‚\n" "ユーザã€ãƒ‘スワードã«èª¤ã‚ŠãŒã‚ã‚‹ã‹ã€\n" "ユーザãŒhaclientグループã«è¨­å®šã•れã¦ã„ãªã„å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚" #: ../mgmt/client/haclient.py.in:7027 msgid "" "Can't login to server.\n" " The protocols may be mismatched." msgstr "" "サーãƒã«ãƒ­ã‚°ã‚¤ãƒ³å‡ºæ¥ã¾ã›ã‚“ã§ã—ãŸã€‚\n" " プロトコルãŒåˆã£ã¦ã„ãªã„å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚" #: ../mgmt/client/haclient.py.in:7040 ../mgmt/client/haclient.py.in:7169 msgid "Updating data from server..." msgstr "サーãƒã‹ã‚‰æ›´æ–°ãƒ‡ãƒ¼ã‚¿å—信中..." #: ../mgmt/client/haclient.py.in:7162 msgid "Reconnecting..." msgstr "å†æŽ¥ç¶šã—ã¦ã„ã¾ã™..." #: ../mgmt/client/haclient.py.in:7240 msgid "Pacemaker GUI requires pyxml package to process DTD" msgstr "Pacemaker GUIã«ã¯pyxmlパッケージãŒå¿…è¦ã§ã™" #: ../mgmt/client/haclient.py.in:7365 msgid "Cannot expand the Relax-NG schema" msgstr "Relax-NGスキーマをå–得出æ¥ã¾ã›ã‚“ã§ã—ãŸ" #: ../mgmt/client/haclient.py.in:7371 msgid "Failed to parse the CIB XML" msgstr "CIB XMLã®ãƒ‘ースã«å¤±æ•—ã—ã¾ã—ãŸ" #: ../mgmt/client/haclient.py.in:7377 msgid "Failed to parse the Relax-NG schema" msgstr "Relax-NGスキーマã®ãƒ‘ースã«å¤±æ•—ã—ã¾ã—ãŸ" #: ../mgmt/client/haclient.py.in:8923 #, python-format msgid "Invalid identifier \"%s\"" msgstr "無効ãªè­˜åˆ¥å­ \"%s\"" #: ../mgmt/client/haclient.py.in:9526 ../mgmt/client/haclient.py.in:9800 msgid ". " msgstr ". " #: ../mgmt/client/haclient.py.in:9526 ../mgmt/client/haclient.py.in:9800 msgid ".\n" msgstr ".\n" #: ../mgmt/client/haclient.py.in:9549 ../mgmt/client/haclient.py.in:9553 #, python-format msgid "\"%s\" is required" msgstr "\"%s\" ãŒå¿…è¦ã§ã™ã€‚" #: ../mgmt/client/haclient.py.in:9549 msgid "Class" msgstr "クラス" #: ../mgmt/client/haclient.py.in:9553 msgid "Provider" msgstr "プロãƒã‚¤ãƒ€" #: ../mgmt/client/haclient.py.in:9554 msgid "for an OCF primitive" msgstr "OCFプリミティブ用" #: ../mgmt/client/haclient.py.in:9563 msgid "" "If not all resources can be active, the cluster will stop lower priority " "resources in order to keep higher priority ones active." msgstr "" "全リソースを起動出æ¥ãªã„時ã€ã‚¯ãƒ©ã‚¹ã‚¿ã¯é«˜ã„優先度ã®ãƒªã‚½ãƒ¼ã‚¹ã®ç‚ºã«ã€ä½Žã„優先度" "ã®ãƒªã‚½ãƒ¼ã‚¹ã‚’åœæ­¢ã—ã¾ã™." #: ../mgmt/client/haclient.py.in:9565 msgid "What state should the cluster attempt to keep this resource in?" msgstr "クラスタã¯ãƒªã‚½ãƒ¼ã‚¹ã‚’ã©ã‚“ãªçŠ¶æ…‹ã«ã—ã¦ãŠãã¾ã™ã‹?" #: ../mgmt/client/haclient.py.in:9567 msgid "Is the cluster allowed to start and stop the resource?" msgstr "クラスタã¯ãƒªã‚½ãƒ¼ã‚¹ã‚’制御(é–‹å§‹ãƒ»åœæ­¢)ã—ã¾ã™ã‹?" #: ../mgmt/client/haclient.py.in:9572 msgid "" "How much does the resource prefer to stay where it is? Defaults to the value " "of \"default-resource-stickiness\"" msgstr "" "ã©ã®ãらã„リソースãŒç•™ã¾ã‚‹äº‹ã‚’期待ã—ã¦ã„ã¾ã™ã‹?\n" "デフォルト:\"default-resource-stickiness\"" #: ../mgmt/client/haclient.py.in:9574 msgid "" "How many failures should occur for this resource on a node before making the " "node ineligible to host this resource. Default: \"none\"" msgstr "" "ä½•å›žã®æ•…éšœãŒãƒªã‚½ãƒ¼ã‚¹ã§ç™ºç”Ÿã—ãŸæ™‚ã«ã€ãƒŽãƒ¼ãƒ‰ä¸Šã§ãƒªã‚½ãƒ¼ã‚¹ã®ç®¡ç†ã‚’出æ¥ãªãã™ã‚‹" "ã‹. デフォルト:\"none\"" #: ../mgmt/client/haclient.py.in:9575 msgid "(mark the resource as unmanaged)" msgstr "(リソースã¯ç®¡ç†å¤–ã«ãƒžãƒ¼ã‚¯ã•れã¾ã™)" #: ../mgmt/client/haclient.py.in:9576 msgid "" "What should the cluster do if it ever finds the resource active on more than " "one node." msgstr "" "リソースãŒï¼‘ã¤ã®ãƒŽãƒ¼ãƒ‰ä»¥å¤–ã®è¤‡æ•°ã®ãƒŽãƒ¼ãƒ‰ã§å®Ÿè¡Œã•れã¦ã„る事を検知ã—ãŸæ™‚〠クラ" "スタã¯ä½•ã‚’ã—ãªã‘れã°ãªã‚‰ãªã„ã‹." #: ../mgmt/client/haclient.py.in:9578 msgid "" "How many seconds to wait before acting as if the failure had not occurred " "(and potentially allowing the resource back to the node on which it failed. " "Default: \"never\"" msgstr "" "何秒ã®é–“ã€æ•…éšœãŒèµ·ã“らãªã‹ã£ãŸã‚ˆã†ã«ã™ã‚‹ç‚ºã«å¾…ã¤ã‹. (ã“れã«ã‚ˆã£ã¦ã€æ•…éšœã—ãŸ" "ノードã§å†ã³ãƒªã‚½ãƒ¼ã‚¹ãŒç¨¼åƒã‚’ç¶šã‘る機会を与ãˆã‚‹.デフォルト: \"never\")" #: ../mgmt/client/haclient.py.in:9580 msgid "" "Allow resource migration for resources which support migrate_to/migrate_from " "actions" msgstr "" "マイグレーション(migrate_to/migrate_from)動作をサãƒãƒ¼ãƒˆã™ã‚‹ãƒªã‚½ãƒ¼ã‚¹ã®ã€ç§»å‹•ã‚’" "許å¯ã™ã‚‹ã‹." #: ../mgmt/client/haclient.py.in:9585 msgid "" "How many copies of the resource to start. Defaults to the number of nodes in " "the cluster." msgstr "ã„ãã¤ã®ãƒªã‚½ãƒ¼ã‚¹ã®ã‚³ãƒ”ーを開始ã™ã‚‹ã‹. デフォルト:クラスタã®ãƒŽãƒ¼ãƒ‰æ•°." #: ../mgmt/client/haclient.py.in:9587 msgid "How many copies of the resource can be started on a single node." msgstr "ã„ãã¤ã®ãƒªã‚½ãƒ¼ã‚¹ã®ã‚³ãƒ”ーを1ã¤ã®ãƒŽãƒ¼ãƒ‰ã§é–‹å§‹ã™ã‚‹ã‹." #: ../mgmt/client/haclient.py.in:9591 msgid "" "When stopping or starting a copy of the clone, tell all the other copies " "beforehand and when the action was successful." msgstr "" "クローンã®ã‚³ãƒ”ーãŒé–‹å§‹ã™ã‚‹ã‹åœæ­¢ã™ã‚‹æ™‚ã€ å‹•ä½œã®æˆåŠŸã‚’ä»–ã®ã‚³ãƒ”ーã«é€šçŸ¥ã™ã‚‹ã‹." #: ../mgmt/client/haclient.py.in:9593 msgid "Does each copy of the clone perform a different function?" msgstr "クローンã®ãれãžã‚Œã®ã‚³ãƒ”ーã¯ã€ç•°ãªã‚‹æ©Ÿèƒ½ã‚’実行ã™ã‚‹ã‹?" #: ../mgmt/client/haclient.py.in:9595 msgid "Should the copies be started in series (instead of in parallel)" msgstr "コピーã¯ç›´åˆ—ã«å§‹ã¾ã‚‹ã¹ãã§ã‚ã‚‹.(並列ã®ä»£ã‚りã«)" #: ../mgmt/client/haclient.py.in:9597 msgid "" "Changes the behavior of ordering constraints (between clones/masters) so " "that instances can start/stop as soon as their peer instance has (rather " "than waiting for every instance of the other clone has)." msgstr "" "マスタ・クローンã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹é”ãŒã€ä»–ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã‚’å¾…ãŸãšã«ã™ãã«é–‹å§‹ãƒ»åœ" "止出æ¥ã‚‹ã‚ˆã†ã«ã€ãƒžã‚¹ã‚¿ãƒ»ã‚¯ãƒ­ãƒ¼ãƒ³å†…ã§ã®åˆ¶ç´„ã®ä½œç”¨ を変更ã—ã¾ã™." #: ../mgmt/client/haclient.py.in:9602 msgid "How many copies of the resource can be promoted to master status." msgstr "ã„ãã¤ã®ã‚³ãƒ”ーãŒãƒžã‚¹ã‚¿ã«ãªã‚Œã‚‹ã‹." #: ../mgmt/client/haclient.py.in:9604 msgid "" "How many copies of the resource can be promoted to master status on a single " "node." msgstr "ã„ã¤ãã®ã‚³ãƒ”ーãŒï¼‘ã¤ã®ãƒŽãƒ¼ãƒ‰ã§ãƒžã‚¹ã‚¿ã«ãªã‚Œã‚‹ã‹." #: ../mgmt/client/haclient.py.in:9736 msgid "required" msgstr "å¿…é ˆ" #: ../mgmt/client/haclient.py.in:9739 msgid ", " msgstr ", " #: ../mgmt/client/haclient.py.in:9740 msgid "unique" msgstr "ユニーク" #: ../mgmt/client/haclient.py.in:10103 #, python-format msgid "Invalid \"%s\"" msgstr "無効 \"%s\"" #: ../mgmt/client/haclient.py.in:10180 msgid "* Specify dependencies between the actions on two resources" msgstr "* ï¼’ã¤ã®ãƒªã‚½ãƒ¼ã‚¹ã«å½±éŸ¿ã™ã‚‹å‹•作ã®é–“ã§ã€ä¾å­˜ã‚’指定ã—ã¦ä¸‹ã•ã„." #: ../mgmt/client/haclient.py.in:10181 ../mgmt/client/haclient.py.in:10299 msgid "* Please set the required attributes" msgstr "* 必須属性を設定ã—ã¦ä¸‹ã•ã„." #: ../mgmt/client/haclient.py.in:10186 ../mgmt/client/haclient.py.in:10202 #, python-format msgid "* %s %s %s %s %s" msgstr "* %s %s %s %s %s" #: ../mgmt/client/haclient.py.in:10191 ../mgmt/client/haclient.py.in:10194 #: ../mgmt/client/haclient.py.in:10206 ../mgmt/client/haclient.py.in:10209 #: ../mgmt/client/haclient.py.in:10262 ../mgmt/client/haclient.py.in:10273 #, python-format msgid "* If cannot %s %s, do not %s %s" msgstr "* %s %sã«ã¯å‡ºæ¥ã¾ã›ã‚“。%sã«%sã‚’ã—ãªã„ã§ä¸‹ã•ã„." #: ../mgmt/client/haclient.py.in:10244 msgid "* Specify the order of actions on resources" msgstr "* リソースã®å‹•作ã®é †åºã‚’指定ã—ã¦ä¸‹ã•ã„." #: ../mgmt/client/haclient.py.in:10245 ../mgmt/client/haclient.py.in:10351 msgid "* Please set the required attributes or add resource sets" msgstr "* å¿…é ˆã®å±žæ€§ã‚’設定ã™ã‚‹ã‹ã€ãƒªã‚½ãƒ¼ã‚¹ã‚»ãƒƒãƒˆã‚’設定ã—ã¦ä¸‹ã•ã„." #: ../mgmt/client/haclient.py.in:10256 ../mgmt/client/haclient.py.in:10270 #, python-format msgid "* %s %s before %s %s" msgstr "* %s %s ã®å¾Œã‚ã® %s %s" #: ../mgmt/client/haclient.py.in:10298 msgid "* Specify where a resource should run relative to another resource" msgstr "* リソースãŒä»–ã®ãƒªã‚½ãƒ¼ã‚¹ã¨ã—ã¦ã€ã©ã®ã‚ˆã†ã«å‹•作ã™ã‚‹ã‹æŒ‡å®šã—ã¦ä¸‹ã•ã„." #: ../mgmt/client/haclient.py.in:10306 ../mgmt/client/haclient.py.in:10316 #: ../mgmt/client/haclient.py.in:10363 #, python-format msgid "* Make %s %s on the same node as %s %s ( %s according to %s )" msgstr "" "* %s ã® %s ã¯ã€%s ã® %s ã¨åŒã˜ãƒŽãƒ¼ãƒ‰ã«ãªã‚‹ã‚ˆã†ã«è¨­å®šã—ã¦ä¸‹ã•ã„.( %s 㯠%s ã«" "従ã†)" #: ../mgmt/client/haclient.py.in:10309 ../mgmt/client/haclient.py.in:10319 #: ../mgmt/client/haclient.py.in:10366 #, python-format msgid "* If %s cannot be %s on any node, then %s won't be %s anywhere" msgstr "" "* ã‚‚ã—ã€%s ãŒã©ã®ãƒŽãƒ¼ãƒ‰ã§ã‚‚ %s ã§ãªã„ãªã‚‰ã°ã€ %s ã¯ã©ã“ã§ã‚‚ %s ã§ã¯ã‚りã¾ã›" "ã‚“." #: ../mgmt/client/haclient.py.in:10312 ../mgmt/client/haclient.py.in:10368 #, python-format msgid "* If %s cannot be %s on any node, %s won't be affected" msgstr "* ã‚‚ã—ã€%s ãŒã©ã®ãƒŽãƒ¼ãƒ‰ã§ã‚‚ %s ã§ãªã„ãªã‚‰ã°ã€ %s ã¯å½±éŸ¿ã‚’å—ã‘ã¾ã›ã‚“." #: ../mgmt/client/haclient.py.in:10322 ../mgmt/client/haclient.py.in:10332 #: ../mgmt/client/haclient.py.in:10380 #, python-format msgid "" "* Prevent %s from being %s on the same node as %s %s ( %s according to %s )" msgstr "" "* %s ã® %s ãŒã€%s ã® %s ã¨åŒã˜ãƒŽãƒ¼ãƒ‰ã«ãªã‚‹ã“ã¨ã‚’防ã„ã§ä¸‹ã•ã„. ( %s 㯠%s ã«" "従ã†)" #: ../mgmt/client/haclient.py.in:10325 ../mgmt/client/haclient.py.in:10335 #: ../mgmt/client/haclient.py.in:10383 #, python-format msgid "" "* If %s is %s on the only (or every) available node, then %s won't be %s " "anywhere" msgstr "" "* %s ãŒå”¯ä¸€ã®ï¼ˆã¾ãŸã¯æ¯Žï¼‰åˆ©ç”¨ã§ãるノードã®ä¸Šã® %s ã§ã‚ã‚‹ãªã‚‰ã°ã€ %s ã¯ã©ã“ã«" "ã‚‚ %s ã§ã¯ã‚りã¾ã›ã‚“." #: ../mgmt/client/haclient.py.in:10328 ../mgmt/client/haclient.py.in:10385 #, python-format msgid "" "* If %s is %s on the only (or every) available node, %s won't be affected" msgstr "" "* %s ãŒå”¯ä¸€ã®ï¼ˆã¾ãŸã¯æ¯Žï¼‰åˆ©ç”¨ã§ãるノードã®ä¸Šã® %s ã§ã‚ã‚‹ãªã‚‰ã°ã€%s ã¯å½±éŸ¿ã‚’" "å—ã‘ã¾ã›ã‚“." #: ../mgmt/client/haclient.py.in:10338 msgid "" "* Combine this colocation score and the appropriate location scores to " "decide where to put the resources" msgstr "" "* リソースã®å ´æ‰€ã‚’決定ã™ã‚‹ç‚ºã«ã€colocationã®ã‚¹ã‚³ã‚¢ã¨locationã®ã‚¹ã‚³ã‚¢ã‚’組ã¿åˆ" "ã‚ã›ã¦ä¸‹ã•ã„" #: ../mgmt/client/haclient.py.in:10350 msgid "* Specify where resources should run relative to other resources" msgstr "* リソースãŒä»–ã®ãƒªã‚½ãƒ¼ã‚¹ã¨ã©ã®ã‚ˆã†ã«å‹•作ã™ã‚‹ã‹æŒ‡å®šã—ã¦ä¸‹ã•ã„" #: ../mgmt/client/haclient.py.in:10358 #, python-format msgid "" "* Combine this \"Score\" and corresponding location scores to decide where " "to place %s" msgstr "" "* %s ã®å ´æ‰€ã‚’決定ã™ã‚‹ã™ã‚‹ç‚ºã«ã€ã“ã®\"スコア\"ã¨locationã®ã‚¹ã‚³ã‚¢ã‚’組ã¿åˆã‚ã›ã¦" "下ã•ã„" #: ../mgmt/client/haclient.py.in:10371 #, python-format msgid "" "* Prefer to make %s %s on the same node as %s %s ( %s according to %s )" msgstr "" "* %s ã® %s 㨠%s ã® %s ãŒã€åŒã˜ãƒŽãƒ¼ãƒ‰ã«ãªã‚‹ã‚ˆã†ã«è¨­å®šã—ã¦ä¸‹ã•ã„.( %s 㯠%s ã«" "従ã†) " #: ../mgmt/client/haclient.py.in:10388 #, python-format msgid "" "* Prefer to prevent %s from being %s on the same node as %s %s ( %s " "according to %s )" msgstr "" "* %s ã® %s 㨠%s ã® %s ãŒã€åŒã˜ãƒŽãƒ¼ãƒ‰ã«ãªã‚‰ãªã„よã†ã«è¨­å®šã—ã¦ä¸‹ã•ã„.( %s 㯠" "%s ã«å¾“ã†) " #: ../mgmt/client/haclient.py.in:10394 #, python-format msgid "" "* Please specify a valid \"Score\" to determine the location relationship " "between %s and %s" msgstr "" "* %s 㨠%s ã®å ´æ‰€ã®é–¢ä¿‚を決定ã™ã‚‹ç‚ºã«ã€æœ‰åйãª\"スコア\"を指定ã—ã¦ä¸‹ã•ã„" msgid "Delete" msgstr "削除" msgid "Commit" msgstr "コミット" msgid "Clone" msgstr "クローン" msgid "Expression" msgstr "å¼" msgid "Operations" msgstr "æ“作" msgid "Password" msgstr "パスワード" msgid "Score" msgstr "スコア" msgid "Interval" msgstr "é–“éš”" msgid "Interval Origin" msgstr "間隔起点" msgid "Timeout" msgstr "タイムアウト" msgid "Start Delay" msgstr "é–‹å§‹é…å»¶" msgid "Enabled" msgstr "æ“作å¯èƒ½" msgid "Disabled" msgstr "æ“作無効" msgid "Record Pending" msgstr "å¾…ã¡æ“作ã®è¨˜éŒ²" msgid "Role" msgstr "ロール" msgid "Requires" msgstr "é–‹å§‹å‰" msgid "Prereq" msgstr "é–‹å§‹å‰" msgid "On Fail" msgstr "故障時ã®å‹•作" msgid "First" msgstr "最åˆ" msgid "Then" msgstr "次" msgid "First Action" msgstr "最åˆã®å‹•作" msgid "Then Action" msgstr "次ã®å‹•作" msgid "Action" msgstr "動作" msgid "To Action" msgstr "動作ã¸" msgid "Symmetrical" msgstr "対称形" msgid "With Resource" msgstr "連æºã™ã‚‹ãƒªã‚½ãƒ¼ã‚¹" msgid "Resource Role" msgstr "リソースロール" msgid "With Resource Role" msgstr "連æºã™ã‚‹ãƒªã‚½ãƒ¼ã‚¹ãƒ­ãƒ¼ãƒ«" msgid "From Role" msgstr "ロールã‹ã‚‰" msgid "To Role" msgstr "ロールã¸" msgid "Node Attribute" msgstr "ノード属性" msgid "Optional" msgstr "オプション" msgid "User Name" msgstr "ユーザå" msgid "Nodes" msgstr "ノード" msgid "Constraints" msgstr "制約" msgid "Resource Location" msgstr "リソースã®é…ç½®" msgid "Resource Order" msgstr "リソースã®é †åº" msgid "Resource Colocation" msgstr "リソースã®çµ„ã¿åˆã‚ã›é…ç½®" msgid "Value" msgstr "値" msgid "Description" msgstr "説明" msgid "Attribute" msgstr "属性" msgid "Operation" msgstr "æ“作" msgid "Debug Level" msgstr "デãƒãƒƒã‚¯ãƒ¬ãƒ™ãƒ«" msgid "UDP Port" msgstr "UDPãƒãƒ¼ãƒˆ" msgid "Keep Alive" msgstr "監視間隔" msgid "Warning Time" msgstr "é…延警告時間" msgid "Dead Time" msgstr "故障検出時間" msgid "Initial Dead Time" msgstr "åˆæœŸåœæ­¢æ™‚é–“" msgid "Quorum Server" msgstr "Quorumサーãƒ" msgid "Use Logd" msgstr "Logd利用" msgid "Auto Join" msgstr "自動å‚加" msgid "API Authentication" msgstr "API権é™" msgid "Auto Failback" msgstr "自動ファイルãƒãƒƒã‚¯" msgid "Baud Rate" msgstr "ボーレート" msgid "Debug File" msgstr "デãƒãƒƒã‚¯ãƒ•ァイル" msgid "Dead Ping" msgstr "Pingノード障害検出時間" msgid "Heartbeat Version" msgstr "Heartbeatãƒãƒ¼ã‚¸ãƒ§ãƒ³" msgid "Log Facility" msgstr "ログファシリティ" msgid "Message Format" msgstr "メッセージ形å¼" msgid "Nice Failback" msgstr "Nice Failback" msgid "running (Master)" msgstr "起動中(マスタ)" msgid "running (Slave)" msgstr "起動中(スレーブ)" msgid "Force" msgstr "強制" msgid "Server(:Port)" msgstr "サーãƒ(:Port)" msgid "Boolean Op" msgstr "è«–ç†æ“作" msgid "Score Attribute" msgstr "スコア属性" msgid "Score Attribute Mangle" msgstr "Score Attribute Mangle" msgid "Configuration" msgstr "æ§‹æˆ" msgid "Refresh" msgstr "リフレッシュ" msgid "Reprobe" msgstr "å†ãƒ—ローブ" msgid "Required" msgstr "å¿…é ˆ" msgid "Primitive" msgstr "プリミティブ" msgid "Group" msgstr "グループ" msgid "Master" msgstr "マスタ" msgid "Uname" msgstr "ホストå" msgid "CRM Config" msgstr "CRMã®æ§‹æˆ" msgid "Cluster Property Set" msgstr "クラスタプロパティセット" msgid "Resource Defaults" msgstr "リソースã®ãƒ‡ãƒ•ォルト" msgid "Operation Defaults" msgstr "æ“作ã®ãƒ‡ãƒ•ォルト" msgid "Meta Attributes" msgstr "メタ属性" msgid "Instance Attributes" msgstr "インスタンス属性" msgid "Utilization" msgstr "利用制é™" msgid "Nvpair" msgstr "åå‰ãƒ»è¨­å®šå€¤" msgid "To Node" msgstr "ノードã¸" msgid "Duration" msgstr "期間" msgid "Migration Threshold" msgstr "移動閾値" msgid "Fail Count" msgstr "故障回数" msgid "Call ID" msgstr "呼出ID" msgid "Return Code" msgstr "返値" msgid "Last Run" msgstr "最後ã®å®Ÿè¡Œæ™‚é–“" msgid "Exec Time" msgstr "実行時間" msgid "Queue Time" msgstr "キュー時間" msgid "Last Return Code Change" msgstr "最後ã®è¿”値ã®å¤‰åŒ–時間" msgid "ID Ref" msgstr "å‚ç…§ID" msgid "End" msgstr "終了" msgid "Rule" msgstr "ルール" msgid "Lifetime" msgstr "生存時間" msgid "Date Expression" msgstr "日付å¼" msgid "Date Spec" msgstr "日付スペック" msgid "Resource Set" msgstr "リソースセット" msgid "Sequential" msgstr "連続" msgid "Resource Ref" msgstr "å‚照リソース" msgid "" "This program is free software; you can redistribute it and/or\n" "modify it under the terms of the GNU General Public License\n" "as published by the Free Software Foundation; either version 2\n" "of the License, or (at your option) any later version.\n" "\n" "This program is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" "GNU General Public License for more details.\n" "\n" "You should have received a copy of the GNU General Public License\n" "along with this program; if not, write to the Free Software\n" "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA." msgstr "" #~ msgid "online(dc)" #~ msgstr "オンライン(dc)" #~ msgid "Login..." #~ msgstr "ログイン" #~ msgid "Cannot get the CIB" #~ msgstr "CIBã‚’å–得出æ¥ã¾ã›ã‚“ã§ã—ãŸ" #~ msgid "Failed to parse the CIB" #~ msgstr "CIBã®ãƒ‘ースã«å¤±æ•—ã—ã¾ã—ãŸ" #~ msgid "Cannot parse the CIB" #~ msgstr "CIBãŒãƒ‘ース出æ¥ã¾ã›ã‚“ã§ã—ãŸ" #~ msgid "Cannot get started in Relax-NG schema" #~ msgstr "Relax-NGスキーマã®å–å¾—é–‹å§‹ã«å¤±æ•—ã—ã¾ã—ãŸ" #~ msgid "Cannot get the DTD" #~ msgstr "DTDã®å–å¾—ã«å¤±æ•—ã—ã¾ã—ãŸ" pacemaker-mgmt-pacemaker-mgmt-2.1.2/po/zh_CN.po000066400000000000000000001546361211477743100213030ustar00rootroot00000000000000# Translation of Simplified Chinese for pacemaker-mgmt. # Copyright (C) 2009 Gao,Yan # This file is distributed under the same license as the package. # Gao,Yan , 2009. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: pacemaker-mgmt 2.0.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-04-17 16:29+0800\n" "PO-Revision-Date: 2009-04-17 15:37+0800\n" "Last-Translator: Gao,Yan \n" "Language-Team: Simplified Chinese \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: ../mgmt/client/haclient.py.in:139 msgid "Do not delete the root directory" msgstr "请ä¸è¦åˆ é™¤æ ¹ç›®å½•" #: ../mgmt/client/haclient.py.in:147 ../mgmt/client/haclient.py.in:153 #: ../mgmt/client/haclient.py.in:158 ../mgmt/client/haclient.py.in:3334 #: ../mgmt/client/haclient.py.in:3342 ../mgmt/client/haclient.py.in:5396 #: ../mgmt/client/haclient.py.in:5402 ../mgmt/client/haclient.py.in:5575 #: ../mgmt/client/haclient.py.in:6233 ../mgmt/client/haclient.py.in:6239 #: ../mgmt/client/haclient.py.in:6458 ../mgmt/client/haclient.py.in:6603 #: ../mgmt/client/haclient.py.in:6612 ../mgmt/client/haclient.py.in:7414 #: ../mgmt/client/haclient.py.in:7422 msgid "System error" msgstr "系统错误" #: ../mgmt/client/haclient.py.in:147 ../mgmt/client/haclient.py.in:153 #: ../mgmt/client/haclient.py.in:158 ../mgmt/client/haclient.py.in:2729 #: ../mgmt/client/haclient.py.in:2877 ../mgmt/client/haclient.py.in:3262 #: ../mgmt/client/haclient.py.in:3307 ../mgmt/client/haclient.py.in:3313 #: ../mgmt/client/haclient.py.in:3334 ../mgmt/client/haclient.py.in:3342 #: ../mgmt/client/haclient.py.in:5299 ../mgmt/client/haclient.py.in:5396 #: ../mgmt/client/haclient.py.in:5402 ../mgmt/client/haclient.py.in:5564 #: ../mgmt/client/haclient.py.in:5575 ../mgmt/client/haclient.py.in:5986 #: ../mgmt/client/haclient.py.in:5990 ../mgmt/client/haclient.py.in:6169 #: ../mgmt/client/haclient.py.in:6233 ../mgmt/client/haclient.py.in:6239 #: ../mgmt/client/haclient.py.in:6446 ../mgmt/client/haclient.py.in:6458 #: ../mgmt/client/haclient.py.in:6474 ../mgmt/client/haclient.py.in:6477 #: ../mgmt/client/haclient.py.in:6485 ../mgmt/client/haclient.py.in:6504 #: ../mgmt/client/haclient.py.in:6511 ../mgmt/client/haclient.py.in:6527 #: ../mgmt/client/haclient.py.in:6543 ../mgmt/client/haclient.py.in:6547 #: ../mgmt/client/haclient.py.in:6567 ../mgmt/client/haclient.py.in:6571 #: ../mgmt/client/haclient.py.in:6584 ../mgmt/client/haclient.py.in:6589 #: ../mgmt/client/haclient.py.in:6603 ../mgmt/client/haclient.py.in:6612 #: ../mgmt/client/haclient.py.in:7371 ../mgmt/client/haclient.py.in:7377 #: ../mgmt/client/haclient.py.in:7407 ../mgmt/client/haclient.py.in:7414 #: ../mgmt/client/haclient.py.in:7422 ../mgmt/client/haclient.py.in:8923 msgid ": " msgstr ": " #: ../mgmt/client/haclient.py.in:191 msgid "Message" msgstr "消æ¯" #: ../mgmt/client/haclient.py.in:211 msgid "Confirm" msgstr "确认" #: ../mgmt/client/haclient.py.in:253 msgid "The specified time should be numeric prefixed." msgstr "指定的时间应为数字开头。" #: ../mgmt/client/haclient.py.in:264 msgid "The specified time should default with second unit, " msgstr "指定的时间应该缺çœå•ä½ä¸ºç§’," #: ../mgmt/client/haclient.py.in:265 #, python-format msgid "" "or should be suffixed with one of the following units:\n" " %s" msgstr "" "或者应该以如下任一å•ä½ç»“尾:\n" " %s" #: ../mgmt/client/haclient.py.in:358 msgid "Add Parameter" msgstr "æ·»åŠ å‚æ•°" #: ../mgmt/client/haclient.py.in:360 msgid "Add Operation" msgstr "添加æ“作" #: ../mgmt/client/haclient.py.in:401 ../mgmt/client/haclient.py.in:8640 #: ../mgmt/client/haclient.py.in:8931 msgid " can't be empty" msgstr "ä¸èƒ½ä¸ºç©º" #: ../mgmt/client/haclient.py.in:508 ../mgmt/client/haclient.py.in:665 #: ../mgmt/client/haclient.py.in:1744 msgid "Type" msgstr "类型" #: ../mgmt/client/haclient.py.in:666 msgid "ID" msgstr "标识符" #: ../mgmt/client/haclient.py.in:771 msgid "St_art" msgstr "å¯åЍ(_A)" #: ../mgmt/client/haclient.py.in:771 msgid "Start resource" msgstr "å¯åŠ¨èµ„æº" #: ../mgmt/client/haclient.py.in:772 msgid "_Stop" msgstr "åœæ­¢(_S)" #: ../mgmt/client/haclient.py.in:772 msgid "Stop resource" msgstr "åœæ­¢èµ„æº" #: ../mgmt/client/haclient.py.in:773 msgid "_Default" msgstr "缺çœ(_D)" #: ../mgmt/client/haclient.py.in:773 msgid "Work as default" msgstr "缺çœè¿è¡Œ" #: ../mgmt/client/haclient.py.in:774 msgid "_Cleanup Resource" msgstr "清ç†èµ„æº(_C)" #: ../mgmt/client/haclient.py.in:774 msgid "Cleanup resource" msgstr "清ç†èµ„æº" #: ../mgmt/client/haclient.py.in:775 msgid "Migra_te Resource" msgstr "è¿ç§»èµ„æº(_T)" #: ../mgmt/client/haclient.py.in:775 msgid "Migrate a resource to specified node" msgstr "è¿ç§»èµ„æºåˆ°æŒ‡å®šèŠ‚ç‚¹" #: ../mgmt/client/haclient.py.in:777 msgid "Clea_r Migrate Constraints" msgstr "清ç†è¿ç§»é™åˆ¶(_R)" #: ../mgmt/client/haclient.py.in:778 msgid "Clear constraints created by migrate" msgstr "清ç†è¿ç§»æ—¶æ‰€åˆ›å»ºçš„é™åˆ¶æ¡ä»¶" #: ../mgmt/client/haclient.py.in:780 msgid "_Unmanage Resource" msgstr "ä¸ç®¡ç†èµ„æº(_U)" #: ../mgmt/client/haclient.py.in:780 msgid "Put a resource into unmanaged mode" msgstr "将资æºç½®ä¸ºéžç®¡ç†æ¨¡å¼" #: ../mgmt/client/haclient.py.in:782 msgid "_Manage Resource" msgstr "管ç†èµ„æº(_M)" #: ../mgmt/client/haclient.py.in:782 msgid "Put a resource into managed mode" msgstr "将资æºç½®ä¸ºç®¡ç†æ¨¡å¼" #: ../mgmt/client/haclient.py.in:784 msgid "Re_fresh Resources" msgstr "刷新资æº(_F)" #: ../mgmt/client/haclient.py.in:784 msgid "Refresh CIB from the LRM status" msgstr "从 LRM 状æ€åˆ·æ–° CIB" #: ../mgmt/client/haclient.py.in:786 msgid "Re_probe Resources" msgstr "釿–°æ£€æŸ¥èµ„æº(_P)" #: ../mgmt/client/haclient.py.in:786 msgid "Reprobe for resources started outside of the CRM" msgstr "釿–°æ£€æŸ¥åœ¨ CRM 之外å¯åŠ¨çš„èµ„æº" #: ../mgmt/client/haclient.py.in:790 msgid "_Standby" msgstr "备用(_S)" #: ../mgmt/client/haclient.py.in:790 msgid "Make the node standby" msgstr "让节点备用" #: ../mgmt/client/haclient.py.in:791 msgid "_Active" msgstr "活动(_A)" #: ../mgmt/client/haclient.py.in:791 msgid "Make the node active" msgstr "让节点活动" #: ../mgmt/client/haclient.py.in:795 msgid "_Group By Node" msgstr "按节点分组资æº(_G)" #: ../mgmt/client/haclient.py.in:795 msgid "Group resources by node" msgstr "按节点分组资æº" #: ../mgmt/client/haclient.py.in:796 msgid "_Maintenance Mode" msgstr "维护模å¼(_M)" #: ../mgmt/client/haclient.py.in:797 msgid "Switch to maintenance mode" msgstr "切æ¢åˆ°ç»´æŠ¤æ¨¡å¼" #: ../mgmt/client/haclient.py.in:798 msgid "_Indicate Pending Operations" msgstr "显示进行中的æ“作(_I)" #: ../mgmt/client/haclient.py.in:799 msgid "Indicate pending(starting/stopping) operations" msgstr "显示进行中的(å¯åЍ䏭ï¼åœæ­¢ä¸­ï¼‰çš„æ“ä½œ" #: ../mgmt/client/haclient.py.in:987 ../mgmt/client/haclient.py.in:1024 #: ../mgmt/client/haclient.py.in:1307 ../mgmt/client/haclient.py.in:1410 #: ../mgmt/client/haclient.py.in:1619 ../mgmt/client/haclient.py.in:2304 #: ../mgmt/client/haclient.py.in:2316 ../mgmt/client/haclient.py.in:3755 #: ../mgmt/client/haclient.py.in:3894 ../mgmt/client/haclient.py.in:4481 #: ../mgmt/client/haclient.py.in:4993 ../mgmt/client/haclient.py.in:5001 #: ../mgmt/client/haclient.py.in:5045 ../mgmt/client/haclient.py.in:5243 #: ../mgmt/client/haclient.py.in:5756 ../mgmt/client/haclient.py.in:5771 #: ../mgmt/client/haclient.py.in:5785 ../mgmt/client/haclient.py.in:5794 #: ../mgmt/client/haclient.py.in:6018 ../mgmt/client/haclient.py.in:6266 #: ../mgmt/client/haclient.py.in:8545 ../mgmt/client/haclient.py.in:8762 #: ../mgmt/client/haclient.py.in:8885 ../mgmt/client/haclient.py.in:8931 #: ../mgmt/client/haclient.py.in:10103 msgid ":" msgstr ":" #: ../mgmt/client/haclient.py.in:1075 #, python-format msgid "last failure at \"%s\"" msgstr "上次失败于“%sâ€" #: ../mgmt/client/haclient.py.in:1219 ../mgmt/client/haclient.py.in:1224 #: ../mgmt/client/haclient.py.in:1670 ../mgmt/client/haclient.py.in:2007 #: ../mgmt/client/haclient.py.in:2009 msgid "standby" msgstr "备用" #: ../mgmt/client/haclient.py.in:1220 ../mgmt/client/haclient.py.in:1225 #: ../mgmt/client/haclient.py.in:1985 msgid "never started" msgstr "未曾å¯åЍ" #: ../mgmt/client/haclient.py.in:1278 #, fuzzy, python-format msgid "Cannot find the %s: %s" msgstr "æ— æ³•èŽ·å– CIB" #: ../mgmt/client/haclient.py.in:1304 msgid "Caused by your previous action, this attribute has been set to \"" msgstr "您之å‰çš„æ“ä½œå°†æ­¤å±žæ€§è®¾ç½®ä¸ºâ€œ" #: ../mgmt/client/haclient.py.in:1306 msgid "\"." msgstr "â€ã€‚" #: ../mgmt/client/haclient.py.in:1307 msgid "Recommended" msgstr "建议" #: ../mgmt/client/haclient.py.in:1308 #, fuzzy msgid "" "Select \"Clear All\" to remove the attributes for all of the sub-resources." msgstr "选择“清除â€åˆ é™¤æ­¤è®¾ç½®ã€‚" #: ../mgmt/client/haclient.py.in:1309 #, fuzzy msgid "All of the sub-resources will inherit the attributes from their parent." msgstr "å­èµ„æºå°†ä»Žå…¶çˆ¶èµ„æºç»§æ‰¿æ­¤å±žæ€§ã€‚" #: ../mgmt/client/haclient.py.in:1314 #, fuzzy, python-format msgid "Clear the %s=\"%s\" attribute for sub-resource \"" msgstr "ä¿ç•™å¯¹å­èµ„æºçš„“%sâ€è®¾ç½®ï¼š “" #: ../mgmt/client/haclient.py.in:1315 msgid "\"?" msgstr "â€ï¼Ÿ" #: ../mgmt/client/haclient.py.in:1330 #, python-format msgid "Cannot %s %s: XML processing error" msgstr "" #: ../mgmt/client/haclient.py.in:1353 ../mgmt/client/haclient.py.in:1367 msgid "all resources" msgstr "所有资æº" #: ../mgmt/client/haclient.py.in:1359 ../mgmt/client/haclient.py.in:1363 #: ../mgmt/client/haclient.py.in:1381 msgid "all nodes" msgstr "所有节点" #: ../mgmt/client/haclient.py.in:1361 msgid "Cleanup Resource" msgstr "清ç†èµ„æº" #: ../mgmt/client/haclient.py.in:1362 ../mgmt/client/haclient.py.in:1566 msgid "Resource" msgstr "资æº" #: ../mgmt/client/haclient.py.in:1363 msgid "Node" msgstr "节点" #: ../mgmt/client/haclient.py.in:1395 msgid "Migrate Resource" msgstr "è¿ç§»èµ„æº" #: ../mgmt/client/haclient.py.in:1556 msgid "all migrated resources" msgstr "所有被è¿ç§»çš„资æº" #: ../mgmt/client/haclient.py.in:1565 msgid "Clear Migrate Constraints" msgstr "清ç†è¿ç§»é™åˆ¶" #. node_options = node_list[:] #. node_options.insert(0, "") #: ../mgmt/client/haclient.py.in:1610 #, python-format msgid "%s Resources" msgstr "%s资æº" #: ../mgmt/client/haclient.py.in:1670 ../mgmt/client/haclient.py.in:1678 msgid "Make" msgstr "让" #: ../mgmt/client/haclient.py.in:1678 msgid "active" msgstr "活动" #: ../mgmt/client/haclient.py.in:1745 msgid "Name" msgstr "åç§°" #: ../mgmt/client/haclient.py.in:1746 msgid "Status" msgstr "状æ€" #: ../mgmt/client/haclient.py.in:1747 msgid "Details" msgstr "详细信æ¯" #: ../mgmt/client/haclient.py.in:1803 msgid "unmanaged" msgstr "未管ç†" #: ../mgmt/client/haclient.py.in:1804 ../mgmt/client/haclient.py.in:2000 msgid "unclean" msgstr "未知" #: ../mgmt/client/haclient.py.in:1806 msgid "failed" msgstr "失败" #: ../mgmt/client/haclient.py.in:1808 msgid "starting" msgstr "å¯åЍ䏭" #: ../mgmt/client/haclient.py.in:1810 msgid "stopping" msgstr "åœæ­¢ä¸­" #: ../mgmt/client/haclient.py.in:1812 ../mgmt/client/haclient.py.in:2094 msgid "not running" msgstr "未è¿è¡Œ" #: ../mgmt/client/haclient.py.in:1814 ../mgmt/client/haclient.py.in:2096 #: ../mgmt/client/haclient.py.in:2106 msgid "running" msgstr "è¿è¡Œ" #: ../mgmt/client/haclient.py.in:1820 ../mgmt/client/haclient.py.in:1987 #: ../mgmt/client/haclient.py.in:2104 msgid "ping node" msgstr "ping 节点" #: ../mgmt/client/haclient.py.in:1822 ../mgmt/client/haclient.py.in:1993 msgid "online" msgstr "在线" #: ../mgmt/client/haclient.py.in:1905 msgid "have quorum" msgstr "节点个数有效" #: ../mgmt/client/haclient.py.in:1907 msgid "no quorum" msgstr "节点个数无效" #: ../mgmt/client/haclient.py.in:1918 ../mgmt/client/haclient.py.in:1935 #: ../mgmt/client/haclient.py.in:2331 msgid "Cluster" msgstr "集群" #: ../mgmt/client/haclient.py.in:1921 msgid "Inactive resources" msgstr "åœæ­¢çš„资æº" #: ../mgmt/client/haclient.py.in:1938 msgid "Resources" msgstr "资æº" #: ../mgmt/client/haclient.py.in:1952 msgid " on " msgstr "于 " #: ../mgmt/client/haclient.py.in:1981 msgid "unknown" msgstr "æƒ…å†µä¸æ˜Ž" #: ../mgmt/client/haclient.py.in:1989 msgid "unknown type" msgstr "未知类型" #: ../mgmt/client/haclient.py.in:1995 msgid "pending" msgstr "æ“作中" #: ../mgmt/client/haclient.py.in:1997 msgid "offline" msgstr "离线" #: ../mgmt/client/haclient.py.in:2003 msgid "dc" msgstr "主控节点" #: ../mgmt/client/haclient.py.in:2007 msgid "on-fail" msgstr "失败" #: ../mgmt/client/haclient.py.in:2093 msgid "primitive" msgstr "普通资æº" #: ../mgmt/client/haclient.py.in:2098 msgid "fail" msgstr "失败" #: ../mgmt/client/haclient.py.in:2110 msgid "group" msgstr "资æºç»„" #: ../mgmt/client/haclient.py.in:2110 msgid "resources" msgstr "资æº" #: ../mgmt/client/haclient.py.in:2110 msgid "clone" msgstr "克隆资æº" #: ../mgmt/client/haclient.py.in:2110 msgid "master" msgstr "主从资æº" #: ../mgmt/client/haclient.py.in:2112 msgid "orders" msgstr "顺åº" #: ../mgmt/client/haclient.py.in:2112 msgid "locations" msgstr "ä½ç½®" #: ../mgmt/client/haclient.py.in:2112 msgid "colocations" msgstr "ååŒ" #: ../mgmt/client/haclient.py.in:2135 ../mgmt/client/haclient.py.in:4997 #: ../mgmt/client/haclient.py.in:6381 msgid "Live" msgstr "" #: ../mgmt/client/haclient.py.in:2137 msgid "Shadow: " msgstr "" #: ../mgmt/client/haclient.py.in:2172 msgid "Management" msgstr "管ç†" #: ../mgmt/client/haclient.py.in:2337 msgid "CIB" msgstr "" #: ../mgmt/client/haclient.py.in:2347 msgid "View XML" msgstr "查看 XML" #: ../mgmt/client/haclient.py.in:2354 msgid "The Whole CIB" msgstr "完整的CIB" #: ../mgmt/client/haclient.py.in:2356 msgid "The Configuration Section" msgstr "é…置段" #: ../mgmt/client/haclient.py.in:2383 #, python-format msgid "The object \"%s\" doesn't exist" msgstr "对象“%sâ€ä¸å­˜åœ¨" #: ../mgmt/client/haclient.py.in:2439 ../mgmt/client/haclient.py.in:2729 msgid "Default" msgstr "缺çœ" #: ../mgmt/client/haclient.py.in:2441 ../mgmt/client/haclient.py.in:3160 #: ../mgmt/client/haclient.py.in:4936 msgid "Reset" msgstr "é‡ç½®" #: ../mgmt/client/haclient.py.in:2549 msgid "Multiple \"Cluster Property Set\" in \"CRM Config\"." msgstr "“CRM é…ç½®â€ä¸­å­˜åœ¨å¤šä¸ªâ€œé›†ç¾¤å±žæ€§é›†â€ã€‚" #: ../mgmt/client/haclient.py.in:2550 ../mgmt/client/haclient.py.in:3457 #: ../mgmt/client/haclient.py.in:3479 ../mgmt/client/haclient.py.in:3607 #: ../mgmt/client/haclient.py.in:3628 msgid "We are switching to \"Hack Mode\" to view them properly." msgstr "现在自动切æ¢è‡³â€œHack 模å¼â€ä»¥ä¾¿æ­£ç¡®æ˜¾ç¤ºã€‚" #: ../mgmt/client/haclient.py.in:2556 msgid "Cannot update the crm configuration: No \"crm_config\" in CIB" msgstr "" #: ../mgmt/client/haclient.py.in:2563 #, fuzzy msgid "Cannot update the crm configuration" msgstr "é‡ç½®è®¾ç½®ï¼Ÿ" #: ../mgmt/client/haclient.py.in:2631 msgid "There are unsaved changes in current page." msgstr "在当å‰é¡µä¸­æœ‰æœªä¿å­˜çš„修改。" #: ../mgmt/client/haclient.py.in:2631 ../mgmt/client/haclient.py.in:5917 msgid "Apply the changes?" msgstr "您想应用修改å—?" #: ../mgmt/client/haclient.py.in:2649 msgid "Policy Engine" msgstr "策略引擎" #: ../mgmt/client/haclient.py.in:2661 msgid "CRM Daemon" msgstr "CRM 守护程åº" #: ../mgmt/client/haclient.py.in:2723 ../mgmt/client/haclient.py.in:2726 #: ../mgmt/client/haclient.py.in:5242 ../mgmt/client/haclient.py.in:9537 #: ../mgmt/client/haclient.py.in:9540 ../mgmt/client/haclient.py.in:9808 #: ../mgmt/client/haclient.py.in:9811 msgid "." msgstr "。" #: ../mgmt/client/haclient.py.in:2746 ../mgmt/client/haclient.py.in:2803 #: ../mgmt/client/haclient.py.in:2807 ../mgmt/client/haclient.py.in:8576 #: ../mgmt/client/haclient.py.in:8595 ../mgmt/client/haclient.py.in:8944 #: ../mgmt/client/haclient.py.in:9713 ../mgmt/client/haclient.py.in:9717 #: ../mgmt/client/haclient.py.in:9781 msgid "default" msgstr "缺çœ" #: ../mgmt/client/haclient.py.in:2868 msgid "List Mode" msgstr "列表模å¼" #: ../mgmt/client/haclient.py.in:2869 msgid "Tree Mode" msgstr "树形模å¼" #: ../mgmt/client/haclient.py.in:2870 msgid "XML Mode" msgstr "XML 模å¼" #: ../mgmt/client/haclient.py.in:2877 msgid "Show" msgstr "显示" #: ../mgmt/client/haclient.py.in:3150 msgid "The object doesn't exist" msgstr "对象ä¸å­˜åœ¨" #: ../mgmt/client/haclient.py.in:3159 msgid "Edit XML" msgstr "编辑 XML" #: ../mgmt/client/haclient.py.in:3174 msgid "Import" msgstr "导入" #: ../mgmt/client/haclient.py.in:3175 msgid "Import XML" msgstr "导入 XML" #: ../mgmt/client/haclient.py.in:3176 msgid "Export" msgstr "导出" #: ../mgmt/client/haclient.py.in:3177 msgid "Export XML" msgstr "导出 XML" #: ../mgmt/client/haclient.py.in:3241 msgid "OVR" msgstr "覆盖" #: ../mgmt/client/haclient.py.in:3243 msgid "INS" msgstr "æ’å…¥" #: ../mgmt/client/haclient.py.in:3246 #, python-format msgid "Ln %d, Col %d\t%s" msgstr "行 %d, 列 %d\t%s" #: ../mgmt/client/haclient.py.in:3262 msgid "Failed to parse the XML" msgstr "è§£æž XML 失败" #: ../mgmt/client/haclient.py.in:3274 msgid "Open File" msgstr "打开文件" #: ../mgmt/client/haclient.py.in:3283 msgid "All files" msgstr "所有文件" #: ../mgmt/client/haclient.py.in:3288 msgid "XML files" msgstr "XML 文件" #: ../mgmt/client/haclient.py.in:3307 ../mgmt/client/haclient.py.in:3313 #: ../mgmt/client/haclient.py.in:5299 ../mgmt/client/haclient.py.in:6446 #: ../mgmt/client/haclient.py.in:6474 ../mgmt/client/haclient.py.in:6504 #: ../mgmt/client/haclient.py.in:6511 ../mgmt/client/haclient.py.in:6527 #: ../mgmt/client/haclient.py.in:6543 ../mgmt/client/haclient.py.in:6567 #: ../mgmt/client/haclient.py.in:6584 ../mgmt/client/haclient.py.in:7407 msgid "I/O error" msgstr "输入输出错误" #: ../mgmt/client/haclient.py.in:3455 ../mgmt/client/haclient.py.in:3605 #, python-format msgid "The \"%s\" has multiple \"%s\" sets." msgstr "“%sâ€å­˜åœ¨å¤šä¸ªâ€œ%sâ€é›†ã€‚" #: ../mgmt/client/haclient.py.in:3476 ../mgmt/client/haclient.py.in:3625 #, python-format msgid "The \"%s\" has a \"%s\"." msgstr "“%sâ€ä¸­å­˜åœ¨â€œ%sâ€ã€‚" #: ../mgmt/client/haclient.py.in:3858 ../mgmt/client/haclient.py.in:4422 #: ../mgmt/client/haclient.py.in:4827 ../mgmt/client/haclient.py.in:4930 msgid "Add" msgstr "添加" #: ../mgmt/client/haclient.py.in:3894 msgid "Other" msgstr "其它" #: ../mgmt/client/haclient.py.in:3920 msgid "Please specify the type of object you want to add" msgstr "请指定添加对象的类型" #: ../mgmt/client/haclient.py.in:3962 msgid "Wizard" msgstr "å‘导" #: ../mgmt/client/haclient.py.in:3965 msgid "Dialog" msgstr "对è¯" #: ../mgmt/client/haclient.py.in:4209 #, python-format msgid "This will delete the %s \"%s\"" msgstr "这会删除%s “%sâ€" #: ../mgmt/client/haclient.py.in:4211 msgid "Delete the selected object?" msgstr "删除选定的对象?" #: ../mgmt/client/haclient.py.in:4378 msgid "Initial state of resource" msgstr "资æºçš„åˆå§‹çжæ€" #: ../mgmt/client/haclient.py.in:4383 msgid "" "Maximum number of copies (Defaults to the number of nodes in the cluster)" msgstr "最大实例个数(缺çœä¸ºé›†ç¾¤çš„节点个数)" #: ../mgmt/client/haclient.py.in:4384 ../mgmt/client/haclient.py.in:4388 #: ../mgmt/client/haclient.py.in:4390 ../mgmt/client/haclient.py.in:4392 #: ../mgmt/client/haclient.py.in:4397 ../mgmt/client/haclient.py.in:4399 #: ../mgmt/client/haclient.py.in:4418 ../mgmt/client/haclient.py.in:9564 #: ../mgmt/client/haclient.py.in:9566 ../mgmt/client/haclient.py.in:9575 #: ../mgmt/client/haclient.py.in:9579 ../mgmt/client/haclient.py.in:9586 #: ../mgmt/client/haclient.py.in:9590 ../mgmt/client/haclient.py.in:9592 #: ../mgmt/client/haclient.py.in:9594 ../mgmt/client/haclient.py.in:9596 #: ../mgmt/client/haclient.py.in:9601 ../mgmt/client/haclient.py.in:9603 msgid "[ default ]" msgstr "ï¼» ç¼ºçœ ï¼½" #: ../mgmt/client/haclient.py.in:4385 msgid "Maximum number of copies on a single node (Defaults to 1)" msgstr "å•个节点上的最大实例个数(缺çœä¸º 1)" #: ../mgmt/client/haclient.py.in:4389 msgid "" "Notify all the other copies before stopping or starting a copy and when the " "action was successful (Defaults to false)" msgstr "" "在å¯åŠ¨æˆ–åœæ­¢ä¸€ä¸ªå®žä¾‹ä¹‹å‰, 并且在æˆåŠŸå®Œæˆä¹‹æ—¶ï¼Œé€šçŸ¥æ‰€æœ‰å…¶å®ƒå®žä¾‹ï¼ˆç¼ºçœä¸º " "false)" #: ../mgmt/client/haclient.py.in:4391 msgid "" "Globally Unique (Does each copy of the clone perform a different function? " "Defaults to false)" msgstr "全局唯一(克隆的æ¯ä¸ªå®žä¾‹æ‰§è¡Œä¸åŒçš„功能? 缺çœä¸º false)" #: ../mgmt/client/haclient.py.in:4393 msgid "" "Interleave (Changes the behavior of ordering constraints (between clones/" "masters) so that instances can start/stop as soon as their peer instance has " "(rather than waiting for every instance of the other clone has). Defaults to " "false)" msgstr "" "交错(改å˜é¡ºåºé™åˆ¶æ¡ä»¶çš„æ“ä½œæ–¹å¼(克隆ï¼ä¸»ä»Žèµ„æºä¹‹é—´ï¼‰ï¼Œ 这样实例能够在相关的" "实例å¯åŠ¨æˆ–åœæ­¢ä¹‹åŽç«‹åˆ»å¯åœï¼ˆä¸å¿…等待å¦ä¸€å…‹éš†èµ„æºçš„æ¯ä¸ªå®žä¾‹æ“作完æˆï¼‰ã€‚ 缺çœ" "为 false)" #: ../mgmt/client/haclient.py.in:4398 msgid "Maximum number of master copies (Defaults to 1)" msgstr "最大主实例个数 (缺çœä¸º 1)" #: ../mgmt/client/haclient.py.in:4400 msgid "Maximum number of master copies on a single node (Defaults to 1)" msgstr "å•个节点上的最大主实例个数 (缺çœä¸º 1)" #: ../mgmt/client/haclient.py.in:4432 msgid "Basic Settings" msgstr "基本设置" #: ../mgmt/client/haclient.py.in:4454 msgid "Options" msgstr "选项" #: ../mgmt/client/haclient.py.in:4553 msgid "Add monitor operation" msgstr "添加监视æ“作" #: ../mgmt/client/haclient.py.in:4839 #, python-format msgid "Summary Of \"%s\"" msgstr "“%s†概è¦" #: ../mgmt/client/haclient.py.in:4841 msgid "Summary" msgstr "概è¦" #: ../mgmt/client/haclient.py.in:4860 #, python-format msgid "Sub-resource For \"%s\"" msgstr "“%sâ€çš„å­èµ„æº" #: ../mgmt/client/haclient.py.in:4862 msgid "Sub-resource" msgstr "å­èµ„æº" #: ../mgmt/client/haclient.py.in:4864 msgid "Add " msgstr "添加" #: ../mgmt/client/haclient.py.in:4865 msgid "Continue Adding " msgstr "继续添加" #: ../mgmt/client/haclient.py.in:4932 msgid "Edit" msgstr "编辑" #: ../mgmt/client/haclient.py.in:4974 msgid "" "This will reset the current object attributes and all sub-objects to the " "initial configurations." msgstr "这会é‡ç½®å½“å‰å¯¹è±¡å±žæ€§ä»¥åŠæ‰€æœ‰å­å¯¹è±¡ä¸ºåˆå§‹è®¾ç½®ã€‚" #: ../mgmt/client/haclient.py.in:4976 msgid "Reset the configurations?" msgstr "é‡ç½®è®¾ç½®ï¼Ÿ" #: ../mgmt/client/haclient.py.in:4986 msgid "Transition Information" msgstr "集群æ“作信æ¯" #: ../mgmt/client/haclient.py.in:4993 msgid "Transition" msgstr "集群æ“作" #: ../mgmt/client/haclient.py.in:5001 msgid "History" msgstr "历å²" #: ../mgmt/client/haclient.py.in:5030 msgid "Graph" msgstr "图解" #: ../mgmt/client/haclient.py.in:5041 msgid "Detail" msgstr "详细信æ¯" #: ../mgmt/client/haclient.py.in:5045 msgid "Verbosity" msgstr "详细程度" #: ../mgmt/client/haclient.py.in:5072 msgid "Scores" msgstr "得分" #: ../mgmt/client/haclient.py.in:5133 ../mgmt/client/haclient.py.in:5166 msgid "Transitions" msgstr "集群æ“作" #: ../mgmt/client/haclient.py.in:5155 #, python-format msgid "[Omitted %d transitions...]" msgstr "ï¼»çœç•¥ %d 个集群æ“作...ï¼½" #: ../mgmt/client/haclient.py.in:5167 msgid "Searching the transitions may take a while," msgstr "æœç´¢é›†ç¾¤æ“作需è¦ä¸€æ®µæ—¶é—´ï¼Œ" #: ../mgmt/client/haclient.py.in:5168 msgid "depending on the number of transitions..." msgstr "å–决于集群æ“作的数é‡..." #: ../mgmt/client/haclient.py.in:5169 msgid "Cannot find any transition record" msgstr "无法获å–任何集群æ“作记录" #: ../mgmt/client/haclient.py.in:5211 msgid "The specified transition doesn't exist" msgstr "指定的集群æ“作ä¸å­˜åœ¨" #: ../mgmt/client/haclient.py.in:5242 msgid "Please specify a proper identity of a transition" msgstr "请指定集群æ“作的正确标识" #: ../mgmt/client/haclient.py.in:5243 msgid "Such as" msgstr "例如" #: ../mgmt/client/haclient.py.in:5245 msgid "Transition type: \"error\", \"warn\" or \"input\"" msgstr "集群æ“作类型:“errorâ€ï¼Œâ€œwarnâ€æˆ–者“inputâ€" #: ../mgmt/client/haclient.py.in:5310 msgid "Transition Graph" msgstr "集群æ“作图解" #: ../mgmt/client/haclient.py.in:5311 msgid "Generating the transition graph may take a while..." msgstr "生æˆé›†ç¾¤æ“作图解需è¦ä¸€æ®µæ—¶é—´..." #: ../mgmt/client/haclient.py.in:5312 msgid "Failed to generate the transition graph" msgstr "生æˆé›†ç¾¤æ“作图解失败" #: ../mgmt/client/haclient.py.in:5325 msgid "Transition Detail" msgstr "集群æ“作详细信æ¯" #: ../mgmt/client/haclient.py.in:5326 msgid "Generating the transition detail may take a while..." msgstr "生æˆé›†ç¾¤æ“作详细信æ¯éœ€è¦ä¸€æ®µæ—¶é—´..." #: ../mgmt/client/haclient.py.in:5327 msgid "Failed to generate the transition detail" msgstr "生æˆé›†ç¾¤æ“作详细信æ¯å¤±è´¥" #: ../mgmt/client/haclient.py.in:5339 msgid "Transition Scores" msgstr "集群æ“作得分" #: ../mgmt/client/haclient.py.in:5340 msgid "Generating the transition scores may take a while..." msgstr "生æˆé›†ç¾¤æ“作得分需è¦ä¸€æ®µæ—¶é—´..." #: ../mgmt/client/haclient.py.in:5341 msgid "Failed to generate the transition scores" msgstr "生æˆé›†ç¾¤æ“作得分失败" #: ../mgmt/client/haclient.py.in:5352 msgid "Cannot save the graph for specified transition" msgstr "无法ä¿å­˜æŒ‡å®šçš„集群æ“作图解" #: ../mgmt/client/haclient.py.in:5355 msgid "PNG Image" msgstr "PNG 图åƒ" #: ../mgmt/client/haclient.py.in:5356 msgid "JPEG Image" msgstr "JPEG 图åƒ" #: ../mgmt/client/haclient.py.in:5357 msgid "GIF Image" msgstr "GIF 图åƒ" #: ../mgmt/client/haclient.py.in:5358 msgid "TIFF Image" msgstr "TIFF 图åƒ" #: ../mgmt/client/haclient.py.in:5359 msgid "Dot File" msgstr "Dot 文件" #: ../mgmt/client/haclient.py.in:5390 msgid "Cannot save the information for specified transition" msgstr "无法ä¿å­˜æŒ‡å®šçš„集群æ“作信æ¯" #: ../mgmt/client/haclient.py.in:5410 msgid "" "Interpreting the graph:\n" "* Arrows indicate ordering dependancies\n" "* Dashed-arrows indicate dependancies that are not present in the transition " "graph\n" "* Actions with a dashed border of any color do not form part of the " "transition graph\n" "* Actions with a green border form part of the transition graph\n" "* Actions with a red border are ones the cluster would like to execute but " "are unrunnable\n" "* Actions with a blue border are ones the cluster does not feel need to be " "executed\n" "* Actions with orange text are pseudo/pretend actions that the cluster uses " "to simplify the graph\n" "* Actions with black text are sent to the LRM\n" "* Resource actions have text of the form {rsc}_{action}_{interval} {node}\n" "* Any action depending on an action with a red border will not be able to " "execute.\n" "* Loops are really bad. Please report them to the development team." msgstr "" "图解说明:\n" "* 箭头表示顺åºä¾èµ–关系\n" "* 虚线箭头表示没有出现在该集群æ“作中的ä¾èµ–关系\n" "* ä»»ä½•é¢œè‰²è™šçº¿è¾¹æ¡†çš„åŠ¨ä½œä¸æ˜¯è¯¥é›†ç¾¤æ“作的组æˆéƒ¨åˆ†\n" "* 绿色边框的动作是该集群æ“作的组æˆéƒ¨åˆ†\n" "* 红色边框的动作是指集群想è¦ä½†ä¸èƒ½æ‰§è¡Œçš„动作\n" "* è“色边框的动作是指集群认为ä¸éœ€è¦æ‰§è¡Œçš„动作\n" "* 橙色文本的动作是集群用以简化图解的伪动作\n" "* 黑色文本的动作是å‘é€ç»™ LRM 的动作\n" "* 资æºåŠ¨ä½œçš„æ–‡æœ¬æ ¼å¼ä¸º {资æº}_{动作}_{é—´éš”} {节点}\n" "* 任何动作如果ä¾èµ–于红色边框的动作,则ä¸èƒ½æ‰§è¡Œ\n" "* 如果é‡åˆ°çŽ¯è·¯æƒ…å†µï¼Œè¯·æŠ¥å‘Šç»™å¼€å‘团队。" #: ../mgmt/client/haclient.py.in:5462 msgid "From" msgstr "èµ·å§‹" #: ../mgmt/client/haclient.py.in:5463 msgid "To" msgstr "目标" #: ../mgmt/client/haclient.py.in:5488 msgid "The \"From\" time should before the \"To\" one" msgstr "\"èµ·å§‹\"时间应早于\"截止\"æ—¶é—´" #: ../mgmt/client/haclient.py.in:5530 msgid "Save as ..." msgstr "ä¿å­˜ä¸º..." #: ../mgmt/client/haclient.py.in:5560 msgid "Permission denied" msgstr "æƒé™ä¸å¤Ÿ" #: ../mgmt/client/haclient.py.in:5564 msgid "A file with the same name already exists" msgstr "åŒå文件已ç»å­˜åœ¨" #: ../mgmt/client/haclient.py.in:5566 msgid "Do you want to overwrite it?" msgstr "您想è¦è¦†ç›–该文件å—?" #: ../mgmt/client/haclient.py.in:5569 msgid "Replace it?" msgstr "替æ¢ï¼Ÿ" #: ../mgmt/client/haclient.py.in:5743 msgid "Description of Cluster Report" msgstr "集群报告æè¿°" #: ../mgmt/client/haclient.py.in:5756 msgid "Severity" msgstr "䏥釿€§" #: ../mgmt/client/haclient.py.in:5771 msgid "Component" msgstr "组件" #: ../mgmt/client/haclient.py.in:5785 msgid "Subject" msgstr "主题" #: ../mgmt/client/haclient.py.in:5794 msgid "Detailed description" msgstr "详细æè¿°" #: ../mgmt/client/haclient.py.in:5899 ../mgmt/client/haclient.py.in:7032 msgid "Connected to " msgstr "已连接至 " #: ../mgmt/client/haclient.py.in:5901 msgid "Not connected" msgstr "未连接" #: ../mgmt/client/haclient.py.in:5903 ../mgmt/client/haclient.py.in:5905 #: ../mgmt/client/haclient.py.in:5907 msgid "(" msgstr "(" #: ../mgmt/client/haclient.py.in:5903 msgid "Simple Mode" msgstr "ç®€å•æ¨¡å¼" #: ../mgmt/client/haclient.py.in:5903 ../mgmt/client/haclient.py.in:5905 #: ../mgmt/client/haclient.py.in:5907 msgid ")" msgstr ")" #: ../mgmt/client/haclient.py.in:5905 msgid "Expert Mode" msgstr "专家模å¼" #: ../mgmt/client/haclient.py.in:5907 msgid "Hack Mode" msgstr "Hack 模å¼" #: ../mgmt/client/haclient.py.in:5917 msgid "The data of current view have been changed." msgstr "当å‰è§†å›¾ä¸­çš„æ•°æ®å·²æ›´æ”¹ã€‚" #: ../mgmt/client/haclient.py.in:5986 msgid "Empty information returned" msgstr "" #: ../mgmt/client/haclient.py.in:5990 msgid "Nothing returned" msgstr "" #: ../mgmt/client/haclient.py.in:5997 msgid "Do you want to quit ?" msgstr "您想è¦é€€å‡ºå—?" #: ../mgmt/client/haclient.py.in:6006 msgid "Login" msgstr "登录" #: ../mgmt/client/haclient.py.in:6070 msgid "Do you want to logout ?" msgstr "æ‚¨æƒ³è¦æ–­å¼€å—?" #: ../mgmt/client/haclient.py.in:6077 msgid "\"Indicate pending operations\" has been activated." msgstr "“显示进行中的æ“作†已被激活。" #: ../mgmt/client/haclient.py.in:6078 msgid "It could affect the performance." msgstr "这会影å“集群性能。" #: ../mgmt/client/haclient.py.in:6079 msgid "Turn it off ?" msgstr "将其关闭å—?" #: ../mgmt/client/haclient.py.in:6088 msgid "Cannot get any shadow CIB" msgstr "无法获å–任何 Shadow CIB" #: ../mgmt/client/haclient.py.in:6107 msgid "Shadow CIB" msgstr "" #: ../mgmt/client/haclient.py.in:6109 msgid "Recreate the specified shadow CIB from the live CIB" msgstr "釿–°ä»Ž Live CIB 创建指定的 Shadow CIB" #: ../mgmt/client/haclient.py.in:6111 msgid "Delete the specified shadow CIB" msgstr "删除选定的 Shadow CIB" #: ../mgmt/client/haclient.py.in:6113 msgid "Upload the specified shadow CIB to the cluster" msgstr "加载指定的 Shadow CIB 到集群" #: ../mgmt/client/haclient.py.in:6116 msgid "Shadow Name" msgstr "Shadow åç§°" #: ../mgmt/client/haclient.py.in:6139 #, python-format msgid "The shadow CIB \"%s\"has been successfully commited." msgstr "æˆåŠŸæäº¤ Shadow CIB “%sâ€" #: ../mgmt/client/haclient.py.in:6140 ../mgmt/client/haclient.py.in:6142 msgid "Switch to the live CIB?" msgstr "转到 Live CIB?" #: ../mgmt/client/haclient.py.in:6162 ../mgmt/client/haclient.py.in:6187 msgid "Shadow CIB Diff" msgstr "Shadow CIB 差异" #: ../mgmt/client/haclient.py.in:6169 #, python-format msgid "Differences between the live CIB and the shadow CIB \"%s\"" msgstr "Live CIB 与 Shadow CIB “%s†之间的差异" #: ../mgmt/client/haclient.py.in:6188 msgid "Generating the shadow CIB differences may take a while..." msgstr "ç”Ÿæˆ shadow CIB 差异需è¦ä¸€æ®µæ—¶é—´..." #: ../mgmt/client/haclient.py.in:6189 msgid "Failed to generate the shadow CIB differences" msgstr "ç”Ÿæˆ shadow CIB 差异失败" #: ../mgmt/client/haclient.py.in:6217 msgid "Diff Files" msgstr "Diff 文件" #: ../mgmt/client/haclient.py.in:6218 msgid "All Files" msgstr "所有文件" #: ../mgmt/client/haclient.py.in:6227 msgid "Cannot save the shadow diff" msgstr "无法ä¿å­˜ Shadow 差异" #: ../mgmt/client/haclient.py.in:6254 msgid "Create Shadow CIB" msgstr "创建 Shadow CIB" #: ../mgmt/client/haclient.py.in:6277 msgid "A copy of the live CIB" msgstr "Live CIB 的拷è´" #: ../mgmt/client/haclient.py.in:6281 msgid "A new CIB with empty cluster configuration" msgstr "新的空é…置的 CIB" #: ../mgmt/client/haclient.py.in:6310 msgid "Please specify a name for the shadow CIB." msgstr "请指定 Shadow CIB çš„åç§°" #: ../mgmt/client/haclient.py.in:6313 msgid "Please specify another name for avoiding confusion." msgstr "请指定其它的å称以防混淆。" #: ../mgmt/client/haclient.py.in:6316 #, python-format msgid "A shadow CIB \"%s\" already exists and it's currently active." msgstr "Shadow CIB “%s†已ç»å­˜åœ¨å¹¶ä¸”正在æ“作当中。" #: ../mgmt/client/haclient.py.in:6319 #, python-format msgid "A shadow CIB \"%s\" already exists." msgstr "Shadow CIB “%s†已ç»å­˜åœ¨ã€‚" #: ../mgmt/client/haclient.py.in:6320 msgid "Specify another name, or select \"Force\" if you want to override it." msgstr "请指定其它的å称, 或者选择“强制â€å°†å…¶è¦†ç›–。" #. else : #: ../mgmt/client/haclient.py.in:6339 #, python-format msgid "A new shadow CIB \"%s\" has been successfully created." msgstr "æˆåŠŸåˆ›å»ºæ–°çš„ Shadow CIB “%sâ€ã€‚" #: ../mgmt/client/haclient.py.in:6340 msgid "Switch to it now?" msgstr "转到此 CIB?" #: ../mgmt/client/haclient.py.in:6342 #, python-format msgid "Switch to the new created shadow CIB \"%s\"?" msgstr "转到新创建的 Shadow CIB “%sâ€ï¼Ÿ" #: ../mgmt/client/haclient.py.in:6359 msgid "Or you don't have the permission." msgstr "" #: ../mgmt/client/haclient.py.in:6411 ../mgmt/client/haclient.py.in:6421 msgid "Cluster Report" msgstr "集群报告" #: ../mgmt/client/haclient.py.in:6422 msgid "Generating the cluster report may take a while," msgstr "生æˆé›†ç¾¤æŠ¥å‘Šéœ€è¦ä¸€æ®µæ—¶é—´ï¼Œ" #: ../mgmt/client/haclient.py.in:6423 msgid "depending on the size of logs..." msgstr "å–决于日志的大å°..." #: ../mgmt/client/haclient.py.in:6424 ../mgmt/client/haclient.py.in:6430 msgid "Failed to generate the cluster report" msgstr "生æˆé›†ç¾¤æŠ¥å‘Šå¤±è´¥" #: ../mgmt/client/haclient.py.in:6440 msgid "Incomplete data" msgstr "ä¸å®Œæ•´çš„æ•°æ®" #: ../mgmt/client/haclient.py.in:6477 ../mgmt/client/haclient.py.in:6485 #: ../mgmt/client/haclient.py.in:6547 ../mgmt/client/haclient.py.in:6571 #: ../mgmt/client/haclient.py.in:6589 msgid "Tar error" msgstr "归档错误" #: ../mgmt/client/haclient.py.in:6638 ../mgmt/client/haclient.py.in:6841 msgid "About" msgstr "关于" #: ../mgmt/client/haclient.py.in:6720 msgid "Pacemaker GUI" msgstr "Pacemaker 图形用户界é¢" #: ../mgmt/client/haclient.py.in:6824 msgid "_Connection" msgstr "连接(_C)" #: ../mgmt/client/haclient.py.in:6825 msgid "Log_in" msgstr "登录(_I)" #: ../mgmt/client/haclient.py.in:6825 msgid "login to cluster" msgstr "登录到集群" #: ../mgmt/client/haclient.py.in:6826 msgid "Log_out" msgstr "æ–­å¼€(_O)" #: ../mgmt/client/haclient.py.in:6826 msgid "logout from cluster" msgstr "从集群中断开" #: ../mgmt/client/haclient.py.in:6827 msgid "_Quit" msgstr "退出(_Q)" #: ../mgmt/client/haclient.py.in:6827 msgid "Quit the Program" msgstr "退出客户端" #: ../mgmt/client/haclient.py.in:6828 msgid "_View" msgstr "查看(_V)" #: ../mgmt/client/haclient.py.in:6829 msgid "_Shadow" msgstr "Shadow é…ç½®(_S)" #: ../mgmt/client/haclient.py.in:6830 msgid "_New" msgstr "新建(_N)" #: ../mgmt/client/haclient.py.in:6830 msgid "Create a new shadow CIB" msgstr "创建新的 Shadow CIB" #: ../mgmt/client/haclient.py.in:6831 msgid "Di_ff" msgstr "差异(_F)" #: ../mgmt/client/haclient.py.in:6831 msgid "Differences between the live CIB and the shadow CIB" msgstr "Live CIB 与 Shadow CIB 之间的差异" #: ../mgmt/client/haclient.py.in:6832 msgid "_Reset" msgstr "é‡ç½®(_R)" #: ../mgmt/client/haclient.py.in:6832 msgid "Recreate a shadow CIB from the live CIB" msgstr "从 Live CIB 釿–°åˆ›å»º Shadow CIB" #: ../mgmt/client/haclient.py.in:6833 msgid "_Delete" msgstr "删除(_D)" #: ../mgmt/client/haclient.py.in:6833 msgid "Delete a shadow CIB" msgstr "删除 Shadow CIB" #: ../mgmt/client/haclient.py.in:6834 msgid "_Commit" msgstr "æäº¤(_C)" #: ../mgmt/client/haclient.py.in:6834 msgid "Upload a shadow CIB to the cluster" msgstr "加载 Shadow CIB 到集群" #: ../mgmt/client/haclient.py.in:6835 msgid "_Switch" msgstr "转到(_S)" #: ../mgmt/client/haclient.py.in:6835 msgid "Switch working CIB" msgstr "切æ¢è¦æ“作的 CIB" #: ../mgmt/client/haclient.py.in:6836 msgid "_Tools" msgstr "工具(_T)" #: ../mgmt/client/haclient.py.in:6837 msgid "_Transition Information" msgstr "集群æ“作信æ¯(_T)" #: ../mgmt/client/haclient.py.in:6838 msgid "Show Transition Information" msgstr "查看集群æ“作信æ¯" #: ../mgmt/client/haclient.py.in:6839 msgid "Cluster Re_port" msgstr "集群报告(_P)" #: ../mgmt/client/haclient.py.in:6839 msgid "generate a cluster report" msgstr "生æˆé›†ç¾¤æŠ¥å‘Š" #: ../mgmt/client/haclient.py.in:6840 msgid "_Help" msgstr "帮助(_H)" #: ../mgmt/client/haclient.py.in:6841 msgid "_About" msgstr "关于(_A)" #: ../mgmt/client/haclient.py.in:6847 msgid "_Simple Mode" msgstr "ç®€å•æ¨¡å¼(_S)" #: ../mgmt/client/haclient.py.in:6847 msgid "Switch to simple mode" msgstr "切æ¢åˆ°ç®€å•模å¼" #: ../mgmt/client/haclient.py.in:6848 msgid "_Expert Mode" msgstr "专家模å¼(_E)" #: ../mgmt/client/haclient.py.in:6848 msgid "Switch to expert mode" msgstr "切æ¢åˆ°ä¸“家模å¼" #: ../mgmt/client/haclient.py.in:6849 msgid "_Hack Mode" msgstr "Hack 模å¼(_H)" #: ../mgmt/client/haclient.py.in:6849 msgid "Switch to hack mode" msgstr "切æ¢åˆ° Hack 模å¼" #: ../mgmt/client/haclient.py.in:6912 msgid "Not Connected" msgstr "未连接" #: ../mgmt/client/haclient.py.in:7009 msgid "Can't resolve address of server " msgstr "æ— æ³•è§£æžæœåŠ¡å™¨åœ°å€ " #: ../mgmt/client/haclient.py.in:7015 ../mgmt/client/haclient.py.in:7021 msgid "Can't connect to server " msgstr "无法连接到æœåС噍 " #: ../mgmt/client/haclient.py.in:7024 msgid "" "Failed in the authentication.\n" " User Name or Password may be wrong.\n" " or the user doesn't belong to haclient group" msgstr "用户认è¯å¤±è´¥ï¼Œå¯èƒ½æ˜¯ç”¨æˆ·æˆ–密ç ä¸å¯¹ï¼Œæˆ–该用户ä¸å±žäºŽ haclient 组" #: ../mgmt/client/haclient.py.in:7027 msgid "" "Can't login to server.\n" " The protocols may be mismatched." msgstr "无法登录到æœåŠ¡å™¨ï¼Œå¯èƒ½æ˜¯åè®®ä¸åŒ¹é…" #: ../mgmt/client/haclient.py.in:7040 ../mgmt/client/haclient.py.in:7169 msgid "Updating data from server..." msgstr "正在从æœåŠ¡å™¨æ›´æ–°æ•°æ®..." #: ../mgmt/client/haclient.py.in:7162 msgid "Reconnecting..." msgstr "釿–°è¿žæŽ¥ä¸­..." #: ../mgmt/client/haclient.py.in:7240 msgid "Pacemaker GUI requires pyxml package to process DTD" msgstr "" #: ../mgmt/client/haclient.py.in:7365 msgid "Cannot expand the Relax-NG schema" msgstr "无法展开 Relax-NG Schema" #: ../mgmt/client/haclient.py.in:7371 msgid "Failed to parse the CIB XML" msgstr "è§£æž CIB XML 失败" #: ../mgmt/client/haclient.py.in:7377 msgid "Failed to parse the Relax-NG schema" msgstr "è§£æž Relax-NG Schema 失败" #: ../mgmt/client/haclient.py.in:8923 #, python-format msgid "Invalid identifier \"%s\"" msgstr "无效的标识符 “%sâ€" #: ../mgmt/client/haclient.py.in:9526 ../mgmt/client/haclient.py.in:9800 msgid ". " msgstr "。 " #: ../mgmt/client/haclient.py.in:9526 ../mgmt/client/haclient.py.in:9800 msgid ".\n" msgstr "。\n" #: ../mgmt/client/haclient.py.in:9549 ../mgmt/client/haclient.py.in:9553 #, python-format msgid "\"%s\" is required" msgstr "“%sâ€æ˜¯å¿…å¡«çš„" #: ../mgmt/client/haclient.py.in:9549 msgid "Class" msgstr "类别" #: ../mgmt/client/haclient.py.in:9553 msgid "Provider" msgstr "æä¾›è€…" #: ../mgmt/client/haclient.py.in:9554 msgid "for an OCF primitive" msgstr "对于一个 OCF 的普通资æº" #: ../mgmt/client/haclient.py.in:9563 msgid "" "If not all resources can be active, the cluster will stop lower priority " "resources in order to keep higher priority ones active." msgstr "" "å¦‚æžœèµ„æºæ— æ³•全部工作, é›†ç¾¤ä¼šåœæ­¢ä½Žä¼˜å…ˆçº§çš„资æºï¼Œ 以便让高优先级的资æºå·¥ä½œã€‚" #: ../mgmt/client/haclient.py.in:9565 msgid "What state should the cluster attempt to keep this resource in?" msgstr "集群试图让该资æºä¿æŒçš„状æ€ã€‚" #: ../mgmt/client/haclient.py.in:9567 msgid "Is the cluster allowed to start and stop the resource?" msgstr "是å¦è®©é›†ç¾¤è´Ÿè´£å¯åœå’Œç®¡ç†èµ„æºï¼Ÿ" #: ../mgmt/client/haclient.py.in:9572 msgid "" "How much does the resource prefer to stay where it is? Defaults to the value " "of \"default-resource-stickiness\"" msgstr "" "èµ„æºæœ‰å¤šå¤§ç¨‹åº¦å€¾å‘于åœç•™åœ¨å½“å‰èŠ‚ç‚¹ï¼Ÿç¼ºçœä¸ºâ€œdefault-resource-stickinessâ€çš„值" #: ../mgmt/client/haclient.py.in:9574 msgid "" "How many failures should occur for this resource on a node before making the " "node ineligible to host this resource. Default: \"none\"" msgstr "" "å…许该资æºåœ¨ä¸€ä¸ªèŠ‚ç‚¹ä¸Šçš„å¤±è´¥æ¬¡æ•°ï¼Œ 之åŽç¦æ­¢è¯¥èµ„æºåœ¨å…¶ä¸Šè¿è¡Œã€‚缺çœï¼š æ— é™åˆ¶" #: ../mgmt/client/haclient.py.in:9575 msgid "(mark the resource as unmanaged)" msgstr "(将该资æºè§†ä¸ºå¤±æŽ§)" #: ../mgmt/client/haclient.py.in:9576 msgid "" "What should the cluster do if it ever finds the resource active on more than " "one node." msgstr "如果å‘现资æºåœ¨å¤šä¸ªèŠ‚ç‚¹ä¸Šè¿è¡Œï¼Œé›†ç¾¤å¦‚何处ç†ï¼Ÿ" #: ../mgmt/client/haclient.py.in:9578 msgid "" "How many seconds to wait before acting as if the failure had not occurred " "(and potentially allowing the resource back to the node on which it failed. " "Default: \"never\"" msgstr "" "等待多少秒之åŽå°±è§†ä½œå¤±è´¥ä»Žæœªå‘生过(æ„味å…许资æºå›žåˆ°ä¹‹å‰å¤±æ•ˆè¿‡çš„节点)缺çœï¼š " "从ä¸" #: ../mgmt/client/haclient.py.in:9580 msgid "" "Allow resource migration for resources which support migrate_to/migrate_from " "actions" msgstr "å…许è¿ç§»æ”¯æŒ migrate_to å’Œ migrate_from æ“作的资æº" #: ../mgmt/client/haclient.py.in:9585 msgid "" "How many copies of the resource to start. Defaults to the number of nodes in " "the cluster." msgstr "能够å¯åŠ¨çš„æœ€å¤§èµ„æºå®žä¾‹ä¸ªæ•°ã€‚ 缺çœä¸ºé›†ç¾¤çš„节点个数。" #: ../mgmt/client/haclient.py.in:9587 msgid "How many copies of the resource can be started on a single node." msgstr "å•个节点上能够å¯åŠ¨çš„æœ€å¤§èµ„æºå®žä¾‹ä¸ªæ•°ã€‚" #: ../mgmt/client/haclient.py.in:9591 msgid "" "When stopping or starting a copy of the clone, tell all the other copies " "beforehand and when the action was successful." msgstr "在å¯åŠ¨æˆ–åœæ­¢ä¸€ä¸ªå®žä¾‹ä¹‹å‰, 并且在æˆåŠŸå®Œæˆä¹‹æ—¶ï¼Œé€šçŸ¥æ‰€æœ‰å…¶å®ƒå®žä¾‹" #: ../mgmt/client/haclient.py.in:9593 msgid "Does each copy of the clone perform a different function?" msgstr "克隆的æ¯ä¸ªå®žä¾‹æ‰§è¡Œä¸åŒçš„功能?" #: ../mgmt/client/haclient.py.in:9595 msgid "Should the copies be started in series (instead of in parallel)" msgstr "串行地å¯åŠ¨å®žä¾‹ï¼ˆè€Œéžå¹¶è¡Œåœ°ï¼‰" #: ../mgmt/client/haclient.py.in:9597 msgid "" "Changes the behavior of ordering constraints (between clones/masters) so " "that instances can start/stop as soon as their peer instance has (rather " "than waiting for every instance of the other clone has)." msgstr "" "改å˜é¡ºåºé™åˆ¶æ¡ä»¶çš„æ“ä½œæ–¹å¼(克隆ï¼ä¸»ä»Žèµ„æºä¹‹é—´ï¼‰ï¼Œ 这样实例能够在相关的实例å¯" "åŠ¨æˆ–åœæ­¢ä¹‹åŽç«‹åˆ»å¯åœï¼ˆä¸å¿…等待å¦ä¸€å…‹éš†èµ„æºçš„æ¯ä¸ªå®žä¾‹æ“作完æˆï¼‰ã€‚ 缺çœä¸º false" #: ../mgmt/client/haclient.py.in:9602 msgid "How many copies of the resource can be promoted to master status." msgstr "能够æå‡ä¸ºä¸»çжæ€çš„æœ€å¤§èµ„æºå®žä¾‹ä¸ªæ•°ã€‚" #: ../mgmt/client/haclient.py.in:9604 msgid "" "How many copies of the resource can be promoted to master status on a single " "node." msgstr "å•个节点上能够æå‡ä¸ºä¸»çжæ€çš„æœ€å¤§èµ„æºå®žä¾‹ä¸ªæ•°ã€‚" #: ../mgmt/client/haclient.py.in:9736 msgid "required" msgstr "必需" #: ../mgmt/client/haclient.py.in:9739 msgid ", " msgstr ", " #: ../mgmt/client/haclient.py.in:9740 msgid "unique" msgstr "唯一" #: ../mgmt/client/haclient.py.in:10103 #, python-format msgid "Invalid \"%s\"" msgstr "无效的“%sâ€" #: ../mgmt/client/haclient.py.in:10180 msgid "* Specify dependencies between the actions on two resources" msgstr "* 指定两个资æºå…¶åŠ¨ä½œä¹‹é—´çš„ä¾èµ–关系" #: ../mgmt/client/haclient.py.in:10181 ../mgmt/client/haclient.py.in:10299 msgid "* Please set the required attributes" msgstr "* 请设置必填的属性" #: ../mgmt/client/haclient.py.in:10186 ../mgmt/client/haclient.py.in:10202 #, python-format msgid "* %s %s %s %s %s" msgstr "" #: ../mgmt/client/haclient.py.in:10191 ../mgmt/client/haclient.py.in:10194 #: ../mgmt/client/haclient.py.in:10206 ../mgmt/client/haclient.py.in:10209 #: ../mgmt/client/haclient.py.in:10262 ../mgmt/client/haclient.py.in:10273 #, python-format msgid "* If cannot %s %s, do not %s %s" msgstr "* 如果ä¸èƒ½ %s %s, åˆ™ä¸ %s %s" #: ../mgmt/client/haclient.py.in:10244 msgid "* Specify the order of actions on resources" msgstr "* 指定资æºåŠ¨ä½œçš„é¡ºåº" #: ../mgmt/client/haclient.py.in:10245 ../mgmt/client/haclient.py.in:10351 msgid "* Please set the required attributes or add resource sets" msgstr "* 请设置必填属性或者添加资æºé›†" #: ../mgmt/client/haclient.py.in:10256 ../mgmt/client/haclient.py.in:10270 #, python-format msgid "* %s %s before %s %s" msgstr "* å…ˆ %s %s, ç„¶åŽ %s %s" #: ../mgmt/client/haclient.py.in:10298 msgid "* Specify where a resource should run relative to another resource" msgstr "* 指定一个资æºç›¸å¯¹äºŽå¦ä¸€èµ„æºçš„è¿è¡Œä½ç½®" #: ../mgmt/client/haclient.py.in:10306 ../mgmt/client/haclient.py.in:10316 #: ../mgmt/client/haclient.py.in:10363 #, python-format msgid "* Make %s %s on the same node as %s %s ( %s according to %s )" msgstr "* 让 %s %s 在 %s %s 的相åŒèŠ‚ç‚¹ä¸Š (%s å‚ç…§ %s)" #: ../mgmt/client/haclient.py.in:10309 ../mgmt/client/haclient.py.in:10319 #: ../mgmt/client/haclient.py.in:10366 #, python-format msgid "* If %s cannot be %s on any node, then %s won't be %s anywhere" msgstr "* 如果 %s 无法 %s 在任何节点上, 则 %s 也ä¸èƒ½ %s 在任何节点上" #: ../mgmt/client/haclient.py.in:10312 ../mgmt/client/haclient.py.in:10368 #, python-format msgid "* If %s cannot be %s on any node, %s won't be affected" msgstr "* 如果 %s 无法 %s 在任何节点上, %s ä¸å—å½±å“" #: ../mgmt/client/haclient.py.in:10322 ../mgmt/client/haclient.py.in:10332 #: ../mgmt/client/haclient.py.in:10380 #, python-format msgid "" "* Prevent %s from being %s on the same node as %s %s ( %s according to %s )" msgstr "* é¿å… %s %s 在 %s %s 的相åŒèŠ‚ç‚¹ä¸Š (%s å‚ç…§ %s)" #: ../mgmt/client/haclient.py.in:10325 ../mgmt/client/haclient.py.in:10335 #: ../mgmt/client/haclient.py.in:10383 #, python-format msgid "" "* If %s is %s on the only (or every) available node, then %s won't be %s " "anywhere" msgstr "* 如果 %s 在唯一的(或æ¯ä¸ªï¼‰å¯ç”¨èŠ‚ç‚¹ä¸Š %s, 则 %s ä¸ä¼š %s 在任何节点上" #: ../mgmt/client/haclient.py.in:10328 ../mgmt/client/haclient.py.in:10385 #, python-format msgid "" "* If %s is %s on the only (or every) available node, %s won't be affected" msgstr "* 如果 %s 在唯一的(或æ¯ä¸ªï¼‰å¯ç”¨èŠ‚ç‚¹ä¸Š %s, %s ä¸å—å½±å“" #: ../mgmt/client/haclient.py.in:10338 msgid "" "* Combine this colocation score and the appropriate location scores to " "decide where to put the resources" msgstr "* ç»¼åˆæ­¤ååŒæƒé‡ä»¥åŠç›¸åº”çš„ä½ç½®æƒé‡ä»¥å†³å®šèµ„æºè¿è¡Œä½ç½®" #: ../mgmt/client/haclient.py.in:10350 msgid "* Specify where resources should run relative to other resources" msgstr "* 指定资æºç›¸å¯¹äºŽå…¶ä»–资æºçš„è¿è¡Œä½ç½®" #: ../mgmt/client/haclient.py.in:10358 #, python-format msgid "" "* Combine this \"Score\" and corresponding location scores to decide where " "to place %s" msgstr "* ç»¼åˆæ­¤â€œæƒé‡â€ä»¥åŠç›¸åº”çš„ä½ç½®æƒé‡ä»¥å†³å®šèµ„æºâ€œ%sâ€çš„è¿è¡Œä½ç½®" #: ../mgmt/client/haclient.py.in:10371 #, python-format msgid "" "* Prefer to make %s %s on the same node as %s %s ( %s according to %s )" msgstr "* 倾å‘于让 %s %s 在 %s %s 的相åŒèŠ‚ç‚¹ä¸Šï¼ˆ%s å‚ç…§ %s)" #: ../mgmt/client/haclient.py.in:10388 #, python-format msgid "" "* Prefer to prevent %s from being %s on the same node as %s %s ( %s " "according to %s )" msgstr "* 倾å‘于é¿å… %s %s 在 %s %s 的相åŒèŠ‚ç‚¹ä¸Š (%s å‚ç…§ %s)" #: ../mgmt/client/haclient.py.in:10394 #, python-format msgid "" "* Please specify a valid \"Score\" to determine the location relationship " "between %s and %s" msgstr "* 请指定有效的“æƒé‡â€ä»¥å†³å®š %s 与 %s 之间的ä½ç½®å…³ç³»" msgid "Delete" msgstr "删除" msgid "Commit" msgstr "æäº¤" msgid "Clone" msgstr "克隆资æº" msgid "Expression" msgstr "表达å¼" msgid "Operations" msgstr "æ“作" msgid "Password" msgstr "å£ä»¤" msgid "Score" msgstr "æƒé‡" msgid "Interval" msgstr "é—´éš”" msgid "Interval Origin" msgstr "é—´éš” Origin" msgid "Timeout" msgstr "è¶…æ—¶" msgid "Start Delay" msgstr "å¯åŠ¨å»¶æ—¶" msgid "Enabled" msgstr "激活" msgid "Disabled" msgstr "关闭" msgid "Record Pending" msgstr "记录进行中的æ“作" msgid "Role" msgstr "角色" msgid "Requires" msgstr "ä¾èµ–" msgid "Prereq" msgstr "ä¾èµ–" msgid "On Fail" msgstr "失败时" msgid "First" msgstr "首先" msgid "Then" msgstr "ç„¶åŽ" msgid "First Action" msgstr "首先æ“作" msgid "Then Action" msgstr "ç„¶åŽæ“作" msgid "Action" msgstr "æ“作" msgid "To Action" msgstr "目标æ“作" msgid "Symmetrical" msgstr "对称" msgid "With Resource" msgstr "与资æº" msgid "Resource Role" msgstr "资æºè§’色" msgid "With Resource Role" msgstr "与资æºè§’色" msgid "From Role" msgstr "起始角色" msgid "To Role" msgstr "目标角色" msgid "Node Attribute" msgstr "节点属性" msgid "Optional" msgstr "选填" msgid "User Name" msgstr "用户å" msgid "Nodes" msgstr "节点" msgid "Constraints" msgstr "é™åˆ¶æ¡ä»¶" msgid "Resource Location" msgstr "资æºä½ç½®" msgid "Resource Order" msgstr "资æºé¡ºåº" msgid "Resource Colocation" msgstr "资æºååŒ" msgid "Value" msgstr "值" msgid "Description" msgstr "æè¿°" msgid "Attribute" msgstr "属性" msgid "Operation" msgstr "æ“作" msgid "Debug Level" msgstr "调试级别" msgid "UDP Port" msgstr "UDP 端å£" msgid "Keep Alive" msgstr "心跳间隔" msgid "Warning Time" msgstr "警报时间" msgid "Dead Time" msgstr "认定宕机时间" msgid "Initial Dead Time" msgstr "å¯åŠ¨æ—¶è®¤å®šå®•æœºæ—¶é—´" msgid "Quorum Server" msgstr "Quorum æœåС噍" msgid "Use Logd" msgstr "使用 Logd" msgid "Auto Join" msgstr "自动加入节点" msgid "API Authentication" msgstr "API 认è¯" msgid "Auto Failback" msgstr "自动回è¿" msgid "Baud Rate" msgstr "波特率" msgid "Debug File" msgstr "调试文件" msgid "Dead Ping" msgstr "认定 Ping 节点宕机时间" msgid "Heartbeat Version" msgstr "Heartbeat 版本" msgid "Log Facility" msgstr "日志机制" msgid "Message Format" msgstr "æ¶ˆæ¯æ ¼å¼" msgid "Nice Failback" msgstr "回è¿" msgid "running (Master)" msgstr "è¿è¡Œ(主)" msgid "running (Slave)" msgstr "è¿è¡Œ(从)" msgid "Force" msgstr "强制" msgid "Server(:Port)" msgstr "æœåС噍(:端å£å·)" msgid "Boolean Op" msgstr "布尔è¿ç®—" msgid "Score Attribute" msgstr "æƒé‡å±žæ€§" msgid "Score Attribute Mangle" msgstr "æƒé‡å±žæ€§ Mangle" msgid "Configuration" msgstr "é…ç½®" msgid "Refresh" msgstr "刷新" msgid "Reprobe" msgstr "釿–°æ£€æŸ¥" msgid "Required" msgstr "å¿…å¡«" msgid "Primitive" msgstr "普通资æº" msgid "Group" msgstr "资æºç»„" msgid "Master" msgstr "主从资æº" msgid "Uname" msgstr "节点å" msgid "CRM Config" msgstr "CRM é…ç½®" msgid "Cluster Property Set" msgstr "集群属性集" msgid "Resource Defaults" msgstr "资æºç¼ºçœè®¾ç½®" msgid "Operation Defaults" msgstr "æ“作缺çœè®¾ç½®" msgid "Meta Attributes" msgstr "元属性" msgid "Instance Attributes" msgstr "实例属性" msgid "Utilization" msgstr "è´Ÿè½½" msgid "Nvpair" msgstr "åç§°/值对" msgid "To Node" msgstr "目标节点" msgid "Duration" msgstr "æŒç»­æ—¶é—´" msgid "Migration Threshold" msgstr "è¿ç§»é˜ˆå€¼" msgid "Fail Count" msgstr "失败计数" msgid "Call ID" msgstr "调用标识ç " msgid "Return Code" msgstr "返回ç " msgid "Last Run" msgstr "上次è¿è¡Œ" msgid "Exec Time" msgstr "执行时间" msgid "Queue Time" msgstr "排队时间" msgid "Last Return Code Change" msgstr "ä¸Šæ¬¡è¿”å›žç æ”¹å˜" msgid "ID Ref" msgstr "标识符引用" msgid "End" msgstr "截止" msgid "Rule" msgstr "规则" msgid "Lifetime" msgstr "生效期é™" msgid "Date Expression" msgstr "日期表达å¼" msgid "Date Spec" msgstr "日期指定" msgid "Resource Set" msgstr "资æºé›†" msgid "Sequential" msgstr "顺åº" msgid "Resource Ref" msgstr "资æºå¼•用" msgid "" "This program is free software; you can redistribute it and/or\n" "modify it under the terms of the GNU General Public License\n" "as published by the Free Software Foundation; either version 2\n" "of the License, or (at your option) any later version.\n" "\n" "This program is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" "GNU General Public License for more details.\n" "\n" "You should have received a copy of the GNU General Public License\n" "along with this program; if not, write to the Free Software\n" "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA." msgstr "" "æ­¤ç¨‹åºæ˜¯è‡ªç”±è½¯ä»¶ï¼›æ‚¨å¯ä»¥éµç…§è‡ªç”±è½¯ä»¶åŸºé‡‘会所å‘表的 GNU GPL åè®®é‡æ–°\n" "å‘布或修改它;GPL å议应采用第二版或您所愿æ„选择的更新的版本。\n" "\n" "此程åºå‘布的目的是希望它能够在一定程度上对您有所帮助,但我们并ä¸ä¸ºå®ƒ\n" "æä¾›ä»»ä½•å½¢å¼çš„æ‹…ä¿ï¼›å¯¹äºŽä»¥ä»»ä½•特定用途使用它所造æˆçš„任何直接或间接åŽ\n" "æžœéƒ½ä¸æ‰¿æ‹…任何责任。请å‚看 GNU GPL å议中的更多细节。\n" "\n" "您应该在收到此程åºçš„åŒæ—¶æ”¶åˆ°äº† GNU GPL å议的副本;如果您没有收到的\n" "è¯ï¼Œè¯·ç»™è‡ªç”±è½¯ä»¶åŸºé‡‘ä¼šå†™ä¿¡ï¼Œåœ°å€æ˜¯\n" "51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA" #~ msgid "online(dc)" #~ msgstr "在线(主控节点)" #~ msgid "Login..." #~ msgstr "登录..." #~ msgid "Cannot get the CIB" #~ msgstr "æ— æ³•èŽ·å– CIB" #~ msgid "Failed to parse the CIB" #~ msgstr "è§£æž CIB 失败" #~ msgid "Cannot parse the CIB" #~ msgstr "æ— æ³•è§£æž CIB" #~ msgid "Cannot get started in Relax-NG schema" #~ msgstr "æ— æ³•èŽ·å– Relax-NG Schema 的起始点" #~ msgid "Cannot get the DTD" #~ msgstr "æ— æ³•èŽ·å– DTD" pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/000077500000000000000000000000001211477743100207205ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/.cvsignore000066400000000000000000000001251211477743100227160ustar00rootroot00000000000000.deps .libs Makefile.in Makefile *.la *.lo .*.swp *.beam parser-messages MISC_ERRORS pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/Makefile.am000066400000000000000000000020231211477743100227510ustar00rootroot00000000000000# # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \ -I$(top_srcdir)/linux-ha -I$(top_builddir)/linux-ha QUIET_LIBTOOL_OPTS = @QUIET_LIBTOOL_OPTS@ LIBTOOL = @LIBTOOL@ @QUIET_LIBTOOL_OPTS@ noinst_LTLIBRARIES = libreplace.la libreplace_la_SOURCES = libreplace_la_LIBADD = @LTLIBOBJS@ pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/NoSuchFunctionName.c000066400000000000000000000020661211477743100245760ustar00rootroot00000000000000/* * Copyright (C) 2002 Alan Robertson * This software licensed under the GNU LGPL. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ void nosuchfunctionname(void); /* * This is a completely useless function put here only to make OpenBSD make * procedures happy. I hope no one ever makes such a function ;-) */ void nosuchfunctionname(void) { return; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/alphasort.c000066400000000000000000000027051211477743100230650ustar00rootroot00000000000000/* * * alphasort - replacement for alphasort functions. * * Matt Soffen * Copyright (C) 2001 Matt Soffen * * Taken from the FreeBSD file (with copyright notice) * /usr/src/gnu/lib/libdialog/dir.c *************************************************************************** * Program: dir.c * Author: Marc van Kempen * desc: Directory routines, sorting and reading * * Copyright (c) 1995, Marc van Kempen * * All rights reserved. * * This software may be used, modified, copied, distributed, and * sold, in both source and binary form provided that the above * copyright and these terms are retained, verbatim, as the first * lines of this file. Under no circumstances is the author * responsible for the proper functioning of this software, nor does * the author assume any responsibility for damages incurred with * its use. * *************************************************************************** */ #include #include #include #include /* XXX for _POSIX_VERSION ifdefs */ #if HAVE_STRINGS_H #include #endif #if !defined sgi && !defined _POSIX_VERSION #include #endif #include #include #include #include int alphasort(const void *dirent1, const void *dirent2) { return(strcmp((*(const struct dirent **)dirent1)->d_name, (*(const struct dirent **)dirent2)->d_name)); } pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/daemon.c000066400000000000000000000053641211477743100223370ustar00rootroot00000000000000/*- * * daemon - replacement for daemon function. * * Matt Soffen * Copyright (C) 2004 Matt Soffen * * Taken from the FreeBSD file (with copyright notice) * ------------------------------------------------------------ * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 THE REGENTS OR 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. * * $FreeBSD: src/lib/libc/gen/daemon.c,v 1.3 2000/01/27 23:06:14 jasone Exp $ * */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)daemon.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include int daemon(nochdir, noclose) int nochdir, noclose; { int fd; switch (fork()) { case -1: return (-1); case 0: break; default: _exit(0); } if (setsid() == -1) return (-1); if (!nochdir) (void)chdir("/"); if (!noclose && (fd = _open("/dev/null", O_RDWR, 0)) != -1) { (void)dup2(fd, STDIN_FILENO); (void)dup2(fd, STDOUT_FILENO); (void)dup2(fd, STDERR_FILENO); if (fd > 2) (void)_close(fd); } return (0); } pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/inet_pton.c000066400000000000000000000132141211477743100230640ustar00rootroot00000000000000/* * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* Chris Wright June 22, 2001 * Merged contents of inet_pton.c from Apache2.0.16 and BIND8 * The Apache base is more portable within heartbeat's envrionment, * however, the BIND8 version has two small logic changes that are * newer. */ #include #if HAVE_SYS_TYPES_H #include #endif #if HAVE_SYS_SOCKET_H #include #endif #if HAVE_NETINET_IN_H #include #endif #if HAVE_ARPA_INET_H #include #endif #include #include #ifndef IN6ADDRSZ #define IN6ADDRSZ 16 #endif #ifndef INT16SZ #define INT16SZ sizeof(short) #endif #ifndef INADDRSZ #define INADDRSZ 4 #endif #ifndef __P #define __P(x) x #endif /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static int inet_pton4 __P((const char *src, unsigned char *dst)); #if HAVE_IPV6 static int inet_pton6 __P((const char *src, unsigned char *dst)); #endif /* int * inet_pton(af, src, dst) * convert from presentation format (which usually means ASCII printable) * to network format (which is usually some kind of binary format). * return: * 1 if the address was valid for the specified address family * 0 if the address wasn't valid (`dst' is untouched in this case) * -1 if some other error occurred (`dst' is untouched in this case, too) * author: * Paul Vixie, 1996. */ int inet_pton(int af, const char *src, void *dst) { switch (af) { case AF_INET: return (inet_pton4(src, dst)); #if HAVE_IPV6 case AF_INET6: return (inet_pton6(src, dst)); #endif default: errno = EAFNOSUPPORT; return (-1); } /* NOTREACHED */ } /* int * inet_pton4(src, dst) * like inet_aton() but without all the hexadecimal and shorthand. * return: * 1 if `src' is a valid dotted quad, else 0. * notice: * does not touch `dst' unless it's returning 1. * author: * Paul Vixie, 1996. */ static int inet_pton4(const char *src, unsigned char *dst) { static const char digits[] = "0123456789"; int saw_digit, octets, ch; unsigned char tmp[INADDRSZ], *tp; saw_digit = 0; octets = 0; *(tp = tmp) = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr(digits, ch)) != NULL) { unsigned int new = *tp * 10 + (pch - digits); if (new > 255) return (0); *tp = new; if (! saw_digit) { if (++octets > 4) return (0); saw_digit = 1; } } else if (ch == '.' && saw_digit) { if (octets == 4) return (0); *++tp = 0; saw_digit = 0; } else return (0); } if (octets < 4) return (0); memcpy(dst, tmp, INADDRSZ); return (1); } #if HAVE_IPV6 /* int * inet_pton6(src, dst) * convert presentation level address to network order binary form. * return: * 1 if `src' is a valid [RFC1884 2.2] address, else 0. * notice: * (1) does not touch `dst' unless it's returning 1. * (2) :: in a full address is silently ignored. * credit: * inspired by Mark Andrews. * author: * Paul Vixie, 1996. */ static int inet_pton6(const char *src, unsigned char *dst) { static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp; const char *xdigits, *curtok; int ch, saw_xdigit; unsigned int val; memset((tp = tmp), '\0', IN6ADDRSZ); endp = tp + IN6ADDRSZ; colonp = NULL; /* Leading :: requires some special handling. */ if (*src == ':') if (*++src != ':') return (0); curtok = src; saw_xdigit = 0; val = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) pch = strchr((xdigits = xdigits_u), ch); if (pch != NULL) { val <<= 4; val |= (pch - xdigits); if (val > 0xffff) return (0); saw_xdigit = 1; continue; } if (ch == ':') { curtok = src; if (!saw_xdigit) { if (colonp) return (0); colonp = tp; continue; } else if (*src == '\0') { return (0); } if (tp + INT16SZ > endp) return (0); *tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) val & 0xff; saw_xdigit = 0; val = 0; continue; } if (ch == '.' && ((tp + INADDRSZ) <= endp) && inet_pton4(curtok, tp) > 0) { tp += INADDRSZ; saw_xdigit = 0; break; /* '\0' was seen by inet_pton4(). */ } return (0); } if (saw_xdigit) { if (tp + INT16SZ > endp) return (0); *tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) val & 0xff; } if (colonp != NULL) { /* * Since some memmove()'s erroneously fail to handle * overlapping regions, we'll do the shift by hand. */ const int n = tp - colonp; int i; if (tp == endp) return (0); for (i = 1; i <= n; i++) { endp[- i] = colonp[n - i]; colonp[n - i] = 0; } tp = endp; } if (tp != endp) return (0); memcpy(dst, tmp, IN6ADDRSZ); return (1); } #endif /* HAVE_IPV6 */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/scandir.c000066400000000000000000000164721211477743100225210ustar00rootroot00000000000000/* scandir: Scan a directory, collecting all (selected) items into a an array. * * This code borrowed from 'libit', which can be found here: * * http://www.iro.umontreal.ca/~pinard/libit/dist/scandir/ * * The original author put this code in the public domain. * It has been modified slightly to get rid of warnings, etc. * * Below is the email I received from pinard@iro.umontreal.ca (François Pinard) * when I sent him an email asking him about the license, etc. of this * code which I obtained from his site. * * I think the correct spelling of his name is Rich Salz. I think he's now * rsalz@datapower.com... * -- * Rich Salz, Chief Security Architect * DataPower Technology http://www.datapower.com * XS40 XML Security Gateway http://www.datapower.com/products/xs40.html * * Copyright(C): none (public domain) * License: none (public domain) * Author: Rich Salz * * * * -- Alan Robertson * alanr@unix.sh * ************************************************************************** * * Subject: Re: Scandir replacement function * Date: 18 May 2001 12:00:48 -0400 * From: pinard@iro.umontreal.ca (François Pinard) * To: Alan Robertson * References: 1 * * * [Alan Robertson] * * > Hi, I'd like to use your scandir replacement function found here: * > http://www.iro.umontreal.ca/~pinard/libit/dist/scandir/ But, it does * > not indicate authorship or licensing terms in it. Could you tell me * > who wrote this code, under what license you distribute it, and whether * > and under what terms I may further distribute it? * * Hello, Alan. These are (somewhat) explained in UNSHAR.HDR found in the * same directory. The routines have been written by Rick Saltz (I'm not * completely sure of the spelling) a long while ago. I think that nowadays, * Rick is better known as the main author of the nice INN package. * ************************************************************************** * * I spent a little time verifying this with Rick Salz. * The results are below: * ************************************************************************** * * Date: Tue, 20 Sep 2005 21:52:09 -0400 (EDT) * From: Rich Salz * To: Alan Robertson * Subject: Re: Verifying permissions/licenses/etc on some old code of yours - * scandir.c * In-Reply-To: <433071CA.8000107@unix.sh> * Message-ID: * Content-Type: TEXT/PLAIN; charset=US-ASCII * * yes, it's most definitely in the public domain. * * I'm glad you find it useful. I'm surprised it hasn't been replaced by, * e.g,. something in GLibC. Ii'm impressed you tracked me down. * * /r$ * * -- * Rich Salz Chief Security Architect * DataPower Technology http://www.datapower.com * XS40 XML Security Gateway http://www.datapower.com/products/xs40.html * ----------------------------------------------------------------------> * Subject: scandir, ftw REDUX * Date: 1 Jan 88 00:47:01 GMT * From: rsalz@pebbles.bbn.com * Newsgroups: comp.sources.misc * * * Forget my previous message -- I just decided for completeness's sake to * implement the SysV ftw(3) routine, too. * * To repeat, these are public-domain implementations of the SystemV ftw() * routine, the BSD scandir() and alphasort() routines, and documentation for * same. The FTW manpage could be more readable, but so it goes. * * Anyhow, feel free to post these, and incorporate them into your existing * packages. I have readdir() routiens for MSDOS and the Amiga if anyone * wants them, and should have them for VMS by the end of January; let me * know if you want copies. * * Yours in filesystems, * /r$ * * Anyhow, feel free to post * ----------------------------------------------------------------------< * */ #include #include #include #include #include #include #ifndef NULL # define NULL ((void *) 0) #endif /* Initial guess at directory allocated. */ #define INITIAL_ALLOCATION 20 int scandir (const char *directory_name, struct dirent ***array_pointer, int (*select_function) (const struct dirent *), #ifdef USE_SCANDIR_COMPARE_STRUCT_DIRENT /* This is what the Linux man page says */ int (*compare_function) (const struct dirent**, const struct dirent**) #else /* This is what the Linux header file says ... */ int (*compare_function) (const void *, const void *) #endif ); int scandir (const char *directory_name, struct dirent ***array_pointer, int (*select_function) (const struct dirent *), #ifdef USE_SCANDIR_COMPARE_STRUCT_DIRENT /* This is what the linux man page says */ int (*compare_function) (const struct dirent**, const struct dirent**) #else /* This is what the linux header file says ... */ int (*compare_function) (const void *, const void *) #endif ) { DIR *directory; struct dirent **array; struct dirent *entry; struct dirent *copy; int allocated = INITIAL_ALLOCATION; int counter = 0; /* Get initial list space and open directory. */ if (directory = opendir (directory_name), directory == NULL) return -1; if (array = (struct dirent **) malloc (allocated * sizeof (struct dirent *)), array == NULL) return -1; /* Read entries in the directory. */ while (entry = readdir (directory), entry) if (select_function == NULL || (*select_function) (entry)) { /* User wants them all, or he wants this one. Copy the entry. */ /* * On some OSes the declaration of "entry->d_name" is a minimal-length * placeholder. Example: Solaris: * /usr/include/sys/dirent.h: * "char d_name[1];" * man page "dirent(3)": * The field d_name is the beginning of the character array * giving the name of the directory entry. This name is * null terminated and may have at most MAXNAMLEN chars. * So our malloc length may need to be increased accordingly. * sizeof(entry->d_name): space (possibly minimal) in struct. * strlen(entry->d_name): actual length of the entry. * * John Kavadias * David Lee */ int namelength = strlen(entry->d_name) + 1; /* length with NULL */ int extra = 0; if (sizeof(entry->d_name) <= namelength) { /* allocated space <= required space */ extra += namelength - sizeof(entry->d_name); } if (copy = (struct dirent *) malloc (sizeof (struct dirent) + extra), copy == NULL) { closedir (directory); free (array); return -1; } copy->d_ino = entry->d_ino; copy->d_reclen = entry->d_reclen; strcpy (copy->d_name, entry->d_name); /* Save the copy. */ if (counter + 1 == allocated) { allocated <<= 1; array = (struct dirent **) realloc ((char *) array, allocated * sizeof (struct dirent *)); if (array == NULL) { closedir (directory); free (array); free (copy); return -1; } } array[counter++] = copy; } /* Close things off. */ array[counter] = NULL; *array_pointer = array; closedir (directory); /* Sort? */ if (counter > 1 && compare_function) qsort ((char *) array, counter, sizeof (struct dirent *) , (int (*)(const void *, const void *))(compare_function)); return counter; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/setenv.c000066400000000000000000000025761211477743100224020ustar00rootroot00000000000000/* * Copyright (C) 2001 Alan Robertson * This software licensed under the GNU LGPL. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include /* * Small replacement function for setenv() */ int setenv(const char *name, const char * value, int why) { int rc = -1; if ( name && value ) { char * envp = NULL; envp = malloc(strlen(name)+strlen(value)+2); if (envp) { /* * Unfortunately, the putenv API guarantees memory leaks when * changing environment variables repeatedly... :-( */ sprintf(envp, "%s=%s", name, value); /* Cannot free envp (!) */ rc = putenv(envp); } } return(rc); } pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/strerror.c000066400000000000000000000021741211477743100227520ustar00rootroot00000000000000/* * Copyright (C) 2002 Alan Robertson * This software licensed under the GNU LGPL. * * This library is free software; you can redistribute it and/or * modify it under the terms of version 2.1 of the GNU Lesser General Public * License as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include extern const char * sys_err[]; extern int sys_nerr; char * strerror(int errnum) { static char whaterr[32]; if (errnum < 0) { return "negative errno"; } if (errnum >= sys_nerr) { snprintf(whaterr, sizeof(whaterr),"error %d", errnum); return whaterr; } return sys_err[sys_nerr]; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/strlcat.c000066400000000000000000000022071211477743100225410ustar00rootroot00000000000000#include #include /* * Copyright (C) 2007 Alan Robertson * This software licensed under the GNU LGPL. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ size_t strlcat(char *dest, const char * src, size_t maxlen) { size_t curlen = strlen(dest); size_t addlen = strlen(src); size_t appendlen = (maxlen-1) - curlen; if (appendlen > 0) { strlcpy(dest+curlen, src, maxlen-curlen); } return curlen + addlen; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/strlcpy.c000066400000000000000000000020731211477743100225660ustar00rootroot00000000000000#include #include /* * Copyright (C) 2007 Alan Robertson * This software licensed under the GNU LGPL. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ size_t strlcpy(char *dest, const char * src, size_t maxlen) { size_t srclen = strlen(src); if (maxlen > 0) { strncpy(dest, src, maxlen); dest[maxlen-1]=EOS; } return srclen; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/strndup.c000066400000000000000000000022471211477743100225700ustar00rootroot00000000000000#include #include #include /* * Copyright (C) 2004 Matt Soffen * This software licensed under the GNU LGPL. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ /* Taken from the GlibC implementation of strndup */ char *strndup(const char *str, size_t len) { size_t n = strnlen(str,len); char *new = (char *) malloc (len+1); if (NULL == new) { return NULL; } new[n] = '\0'; return (char *)memcpy (new, str, len); } pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/strnlen.c000066400000000000000000000020541211477743100225520ustar00rootroot00000000000000#include #include /* * Copyright (C) 2003 Alan Robertson * This software licensed under the GNU LGPL. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ size_t strnlen(const char *s, size_t maxlen) { const char * eospos; eospos = memchr(s, (int)'\0', maxlen); return (eospos == NULL ? maxlen : (size_t)(eospos-s)); } pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/unsetenv.c000066400000000000000000000026441211477743100227410ustar00rootroot00000000000000/* * Copyright (C) 2001 Alan Robertson * This software licensed under the GNU LGPL. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #define __environ environ #ifndef HAVE_ENVIRON_DECL extern char **environ; #endif int unsetenv (const char *name) { const size_t len = strlen (name); char **ep; for (ep = __environ; *ep; ++ep) { if (!strncmp (*ep, name, len) && (*ep)[len] == '=') { /* Found it. */ /* Remove this pointer by moving later ones back. */ char **dp = ep; do dp[0] = dp[1]; while (*dp++); /* Continue the loop in case NAME appears again. */ } } return 0; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/replace/uuid_parse.c000066400000000000000000000256421211477743100232350ustar00rootroot00000000000000/* * uuid: emulation of e2fsprogs interface if implementation lacking. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Original uuid implementation: copyright (C) Theodore Ts'o * * This importation into heartbeat: * Copyright (C) 2004 David Lee * */ #include #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #include #include #include /* * Local "replace" implementation of uuid functions. */ #include #include #include /* UUID Variant definitions */ #define UUID_VARIANT_NCS 0 #define UUID_VARIANT_DCE 1 #define UUID_VARIANT_MICROSOFT 2 #define UUID_VARIANT_OTHER 3 /* UUID Type definitions */ #define UUID_TYPE_DCE_TIME 1 #define UUID_TYPE_DCE_RANDOM 4 /* For uuid_compare() */ #define UUCMP(u1,u2) if (u1 != u2) return((u1 < u2) ? -1 : 1); /************************************ * Private types ************************************/ #define longlong long long /* * Offset between 15-Oct-1582 and 1-Jan-70 */ #define TIME_OFFSET_HIGH 0x01B21DD2 #define TIME_OFFSET_LOW 0x13814000 #if (SIZEOF_INT == 4) typedef unsigned int __u32; #elif (SIZEOF_LONG == 4) typedef unsigned long __u32; #endif #if (SIZEOF_INT == 2) typedef int __s16; typedef unsigned int __u16; #elif (SIZEOF_SHORT == 2) typedef short __s16; typedef unsigned short __u16; #endif typedef unsigned char __u8; struct uuid { __u32 time_low; __u16 time_mid; __u16 time_hi_and_version; __u16 clock_seq; __u8 node[6]; }; /************************************ * internal routines ************************************/ static void uuid_pack(const struct uuid *uu, uuid_t ptr) { __u32 tmp; unsigned char *out = ptr; tmp = uu->time_low; out[3] = (unsigned char) tmp; tmp >>= 8; out[2] = (unsigned char) tmp; tmp >>= 8; out[1] = (unsigned char) tmp; tmp >>= 8; out[0] = (unsigned char) tmp; tmp = uu->time_mid; out[5] = (unsigned char) tmp; tmp >>= 8; out[4] = (unsigned char) tmp; tmp = uu->time_hi_and_version; out[7] = (unsigned char) tmp; tmp >>= 8; out[6] = (unsigned char) tmp; tmp = uu->clock_seq; out[9] = (unsigned char) tmp; tmp >>= 8; out[8] = (unsigned char) tmp; memcpy(out+10, uu->node, 6); } static void uuid_unpack(const uuid_t in, struct uuid *uu) { const __u8 *ptr = in; __u32 tmp; tmp = *ptr++; tmp = (tmp << 8) | *ptr++; tmp = (tmp << 8) | *ptr++; tmp = (tmp << 8) | *ptr++; uu->time_low = tmp; tmp = *ptr++; tmp = (tmp << 8) | *ptr++; uu->time_mid = tmp; tmp = *ptr++; tmp = (tmp << 8) | *ptr++; uu->time_hi_and_version = tmp; tmp = *ptr++; tmp = (tmp << 8) | *ptr++; uu->clock_seq = tmp; memcpy(uu->node, ptr, 6); } /************************************ * Main routines, except uuid_generate*() ************************************/ void uuid_clear(uuid_t uu) { memset(uu, 0, 16); } int uuid_compare(const uuid_t uu1, const uuid_t uu2) { struct uuid uuid1, uuid2; uuid_unpack(uu1, &uuid1); uuid_unpack(uu2, &uuid2); UUCMP(uuid1.time_low, uuid2.time_low); UUCMP(uuid1.time_mid, uuid2.time_mid); UUCMP(uuid1.time_hi_and_version, uuid2.time_hi_and_version); UUCMP(uuid1.clock_seq, uuid2.clock_seq); return memcmp(uuid1.node, uuid2.node, 6); } void uuid_copy(uuid_t dst, const uuid_t src) { unsigned char *cp1; const unsigned char *cp2; int i; for (i=0, cp1 = dst, cp2 = src; i < 16; i++) *cp1++ = *cp2++; } /* if uu is the null uuid, return 1 else 0 */ int uuid_is_null(const uuid_t uu) { const unsigned char *cp; int i; for (i=0, cp = uu; i < 16; i++) if (*cp++) return 0; return 1; } /* 36byte-string=>uuid */ int uuid_parse(const char *in, uuid_t uu) { struct uuid uuid; int i; const char *cp; char buf[3]; if (strlen(in) != 36) return -1; for (i=0, cp = in; i <= 36; i++,cp++) { if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) { if (*cp == '-') continue; else return -1; } if (i== 36) if (*cp == 0) continue; if (!isxdigit((int) *cp)) return -1; } uuid.time_low = strtoul(in, NULL, 16); uuid.time_mid = strtoul(in+9, NULL, 16); uuid.time_hi_and_version = strtoul(in+14, NULL, 16); uuid.clock_seq = strtoul(in+19, NULL, 16); cp = in+24; buf[2] = 0; for (i=0; i < 6; i++) { buf[0] = *cp++; buf[1] = *cp++; uuid.node[i] = strtoul(buf, NULL, 16); } uuid_pack(&uuid, uu); return 0; } /* uuid=>36byte-string-with-null */ void uuid_unparse(const uuid_t uu, char *out) { struct uuid uuid; uuid_unpack(uu, &uuid); sprintf(out, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", uuid.time_low, uuid.time_mid, uuid.time_hi_and_version, uuid.clock_seq >> 8, uuid.clock_seq & 0xFF, uuid.node[0], uuid.node[1], uuid.node[2], uuid.node[3], uuid.node[4], uuid.node[5]); } /************************************ * Main routines: uuid_generate*() ************************************/ #include #include #include #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_SYS_SOCKIO_H #include #endif #ifdef HAVE_NET_IF_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_SRANDOM #define srand(x) srandom(x) #define rand() random() #endif static int get_random_fd(void) { struct timeval tv; static int fd = -2; int i; if (fd == -2) { gettimeofday(&tv, 0); fd = open("/dev/urandom", O_RDONLY); if (fd == -1) fd = open("/dev/random", O_RDONLY | O_NONBLOCK); srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec); } /* Crank the random number generator a few times */ gettimeofday(&tv, 0); for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--) rand(); return fd; } /* * Generate a series of random bytes. Use /dev/urandom if possible, * and if not, use srandom/random. */ static void get_random_bytes(void *buf, int nbytes) { int i, n = nbytes, fd = get_random_fd(); int lose_counter = 0; unsigned char *cp = (unsigned char *) buf; if (fd >= 0) { while (n > 0) { i = read(fd, cp, n); if (i <= 0) { if (lose_counter++ > 16) break; continue; } n -= i; cp += i; lose_counter = 0; } } /* * We do this all the time, but this is the only source of * randomness if /dev/random/urandom is out to lunch. */ for (cp = buf, i = 0; i < nbytes; i++) *cp++ ^= (rand() >> 7) & 0xFF; return; } /* * Get the ethernet hardware address, if we can find it... */ static int get_node_id(unsigned char *node_id) { #ifdef HAVE_NET_IF_H int sd; struct ifreq ifr, *ifrp; struct ifconf ifc; char buf[1024]; int n, i; unsigned char *a; /* * BSD 4.4 defines the size of an ifreq to be * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len * However, under earlier systems, sa_len isn't present, so the size is * just sizeof(struct ifreq) */ #ifdef HAVE_SA_LEN #ifndef max #define max(a,b) ((a) > (b) ? (a) : (b)) #endif #define ifreq_size(i) max(sizeof(struct ifreq),\ sizeof((i).ifr_name)+(i).ifr_addr.sa_len) #else #define ifreq_size(i) sizeof(struct ifreq) #endif /* HAVE_SA_LEN*/ sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (sd < 0) { return -1; } memset(buf, 0, sizeof(buf)); ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) { close(sd); return -1; } n = ifc.ifc_len; for (i = 0; i < n; i+= ifreq_size(*ifr) ) { ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i); strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ); #ifdef SIOCGIFHWADDR if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0) continue; a = (unsigned char *) &ifr.ifr_hwaddr.sa_data; #else #ifdef SIOCGENADDR if (ioctl(sd, SIOCGENADDR, &ifr) < 0) continue; a = (unsigned char *) ifr.ifr_enaddr; #else /* * XXX we don't have a way of getting the hardware * address */ close(sd); return 0; #endif /* SIOCGENADDR */ #endif /* SIOCGIFHWADDR */ if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]) continue; if (node_id) { memcpy(node_id, a, 6); close(sd); return 1; } } close(sd); #endif return 0; } /* Assume that the gettimeofday() has microsecond granularity */ #define MAX_ADJUSTMENT 10 static int get_clock(__u32 *clock_high, __u32 *clock_low, __u16 *ret_clock_seq) { static int adjustment = 0; static struct timeval last = {0, 0}; static __u16 clock_seq; struct timeval tv; unsigned longlong clock_reg; try_again: gettimeofday(&tv, 0); if ((last.tv_sec == 0) && (last.tv_usec == 0)) { get_random_bytes(&clock_seq, sizeof(clock_seq)); clock_seq &= 0x1FFF; last = tv; last.tv_sec--; } if ((tv.tv_sec < last.tv_sec) || ((tv.tv_sec == last.tv_sec) && (tv.tv_usec < last.tv_usec))) { clock_seq = (clock_seq+1) & 0x1FFF; adjustment = 0; last = tv; } else if ((tv.tv_sec == last.tv_sec) && (tv.tv_usec == last.tv_usec)) { if (adjustment >= MAX_ADJUSTMENT) goto try_again; adjustment++; } else { adjustment = 0; last = tv; } clock_reg = tv.tv_usec*10 + adjustment; clock_reg += ((unsigned longlong) tv.tv_sec)*10000000; clock_reg += (((unsigned longlong) 0x01B21DD2) << 32) + 0x13814000; *clock_high = clock_reg >> 32; *clock_low = clock_reg; *ret_clock_seq = clock_seq; return 0; } /* create a new uuid, based on randomness */ void uuid_generate_random(uuid_t out) { uuid_t buf; struct uuid uu; get_random_bytes(buf, sizeof(buf)); uuid_unpack(buf, &uu); uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000; uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000; uuid_pack(&uu, out); } /* create a new uuid, based on time */ static void uuid_generate_time(uuid_t out) { static unsigned char node_id[6]; static int has_init = 0; struct uuid uu; __u32 clock_mid; if (!has_init) { if (get_node_id(node_id) <= 0) { get_random_bytes(node_id, 6); /* * Set multicast bit, to prevent conflicts * with IEEE 802 addresses obtained from * network cards */ node_id[0] |= 0x80; } has_init = 1; } get_clock(&clock_mid, &uu.time_low, &uu.clock_seq); uu.clock_seq |= 0x8000; uu.time_mid = (__u16) clock_mid; uu.time_hi_and_version = (clock_mid >> 16) | 0x1000; memcpy(uu.node, node_id, 6); uuid_pack(&uu, out); } void uuid_generate(uuid_t out) { if (get_random_fd() >= 0) { uuid_generate_random(out); }else{ uuid_generate_time(out); } } pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/000077500000000000000000000000001211477743100221525ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/.cvsignore000066400000000000000000000002251211477743100241510ustar00rootroot00000000000000Makefile.in Makefile .deps .libs *.la *.lo .*.swp hbagent *.beam MISC_ERRORS parser-messages SNMPAgentSanityCheck *.beam parser-messages MISC_ERRORS pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAClusterInfo.c000066400000000000000000000157061211477743100251110ustar00rootroot00000000000000/* * Copyright (c) 2004 Intel Corp. * * Author: Zou Yixiong (yixiong.zou@intel.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ /* * Note: this file originally auto-generated by mib2c using * : mib2c.scalar.conf,v 1.7 2003/04/08 14:57:04 dts12 Exp $ */ #include #ifdef PACKAGE_BUGREPORT #undef PACKAGE_BUGREPORT #endif #ifdef PACKAGE_NAME #undef PACKAGE_NAME #endif #ifdef PACKAGE_STRING #undef PACKAGE_STRING #endif #ifdef PACKAGE_TARNAME #undef PACKAGE_TARNAME #endif #ifdef PACKAGE_VERSION #undef PACKAGE_VERSION #endif #include #include #include #include "hbagent.h" #include "LHAClusterInfo.h" /** Initializes the LHAClusterInfo module */ void init_LHAClusterInfo(void) { static oid LHAResourceGroupCount_oid[] = { 1,3,6,1,4,1,4682,1,4 }; static oid LHACurrentNodeID_oid[] = { 1,3,6,1,4,1,4682,1,3 }; static oid LHALiveNodeCount_oid[] = { 1,3,6,1,4,1,4682,1,2 }; static oid LHATotalNodeCount_oid[] = { 1,3,6,1,4,1,4682,1,1 }; DEBUGMSGTL(("LHAClusterInfo", "Initializing\n")); netsnmp_register_scalar( netsnmp_create_handler_registration("LHAResourceGroupCount", handle_LHAResourceGroupCount, LHAResourceGroupCount_oid, OID_LENGTH(LHAResourceGroupCount_oid), HANDLER_CAN_RONLY )); netsnmp_register_scalar( netsnmp_create_handler_registration("LHACurrentNodeID", handle_LHACurrentNodeID, LHACurrentNodeID_oid, OID_LENGTH(LHACurrentNodeID_oid), HANDLER_CAN_RONLY )); netsnmp_register_scalar( netsnmp_create_handler_registration("LHALiveNodeCount", handle_LHALiveNodeCount, LHALiveNodeCount_oid, OID_LENGTH(LHALiveNodeCount_oid), HANDLER_CAN_RONLY )); netsnmp_register_scalar( netsnmp_create_handler_registration("LHATotalNodeCount", handle_LHATotalNodeCount, LHATotalNodeCount_oid, OID_LENGTH(LHATotalNodeCount_oid), HANDLER_CAN_RONLY )); } int handle_LHAResourceGroupCount(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { /* We are never called for a GETNEXT if it's registered as a "instance", as it's "magically" handled for us. */ /* a instance handler also only hands us one request at a time, so we don't need to loop over a list of requests; we'll only get one. */ size_t value = 0; switch(reqinfo->mode) { case MODE_GET: get_int_value(LHA_CLUSTERINFO, RESOURCE_GROUP_COUNT, 0, (uint32_t *) & value); snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, (u_char *) & value, sizeof(value)); break; default: /* we should never get here, so this is a really bad error */ return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; } int handle_LHACurrentNodeID(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { /* We are never called for a GETNEXT if it's registered as a "instance", as it's "magically" handled for us. */ /* a instance handler also only hands us one request at a time, so we don't need to loop over a list of requests; we'll only get one. */ uint32_t value = 0; switch(reqinfo->mode) { case MODE_GET: get_int_value(LHA_CLUSTERINFO, CURRENT_NODE_ID, 0, (uint32_t *) & value); snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, (u_char *) & value, sizeof(value)); break; default: /* we should never get here, so this is a really bad error */ return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; } int handle_LHALiveNodeCount(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { /* We are never called for a GETNEXT if it's registered as a "instance", as it's "magically" handled for us. */ /* a instance handler also only hands us one request at a time, so we don't need to loop over a list of requests; we'll only get one. */ size_t value = 0; switch(reqinfo->mode) { case MODE_GET: get_int_value(LHA_CLUSTERINFO, LIVE_NODE_COUNT, 0, (uint32_t *) & value); snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, (u_char *) & value, sizeof(value)); break; default: /* we should never get here, so this is a really bad error */ return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; } int handle_LHATotalNodeCount(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { /* We are never called for a GETNEXT if it's registered as a "instance", as it's "magically" handled for us. */ /* a instance handler also only hands us one request at a time, so we don't need to loop over a list of requests; we'll only get one. */ size_t value = 0; switch(reqinfo->mode) { case MODE_GET: get_int_value(LHA_CLUSTERINFO, TOTAL_NODE_COUNT, 0, (uint32_t *) & value); snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, (u_char *) & value, sizeof(value)); break; default: /* we should never get here, so this is a really bad error */ return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAClusterInfo.h000066400000000000000000000007231211477743100251070ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.scalar.conf,v 1.7 2003/04/08 14:57:04 dts12 Exp $ */ #ifndef LHACLUSTERINFO_H #define LHACLUSTERINFO_H /* function declarations */ void init_LHAClusterInfo(void); Netsnmp_Node_Handler handle_LHAResourceGroupCount; Netsnmp_Node_Handler handle_LHACurrentNodeID; Netsnmp_Node_Handler handle_LHALiveNodeCount; Netsnmp_Node_Handler handle_LHATotalNodeCount; #endif /* LHACLUSTERINFO_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAHeartbeatConfigInfo.c000066400000000000000000000337331211477743100265150ustar00rootroot00000000000000/* * Copyright (c) 2004 Intel Corp. * * Author: Zou Yixiong (yixiong.zou@intel.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ /* * Note: this file originally auto-generated by mib2c using * : mib2c.scalar.conf,v 1.7 2003/04/08 14:57:04 dts12 Exp $ */ #include #ifdef PACKAGE_BUGREPORT #undef PACKAGE_BUGREPORT #endif #ifdef PACKAGE_NAME #undef PACKAGE_NAME #endif #ifdef PACKAGE_STRING #undef PACKAGE_STRING #endif #ifdef PACKAGE_TARNAME #undef PACKAGE_TARNAME #endif #ifdef PACKAGE_VERSION #undef PACKAGE_VERSION #endif #include #include #include #include "LHAHeartbeatConfigInfo.h" #include "hbagent.h" #if SUPPORT_HEARTBEAT #include #endif #ifndef HA_OK #define HA_OK 0 #endif /** Initializes the LHAHeartbeatConfigInfo module */ void init_LHAHeartbeatConfigInfo(void) { static oid LHAHBVersion_oid[] = { 1,3,6,1,4,1,4682,7,1 }; static oid LHAKeepAlive_oid[] = { 1,3,6,1,4,1,4682,7,3 }; static oid LHADeadTime_oid[] = { 1,3,6,1,4,1,4682,7,4 }; static oid LHADeadPing_oid[] = { 1,3,6,1,4,1,4682,7,5 }; static oid LHAWarnTime_oid[] = { 1,3,6,1,4,1,4682,7,6 }; static oid LHAInitDead_oid[] = { 1,3,6,1,4,1,4682,7,7 }; static oid LHABaudRate_oid[] = { 1,3,6,1,4,1,4682,7,9 }; static oid LHAutoFailBack_oid[] = { 1,3,6,1,4,1,4682,7,12 }; static oid LHAStonith_oid[] = { 1,3,6,1,4,1,4682,7,13 }; static oid LHAStonithHost_oid[] = { 1,3,6,1,4,1,4682,7,14 }; static oid LHARespawn_oid[] = { 1,3,6,1,4,1,4682,7,15 }; DEBUGMSGTL(("LHAHeartbeatConfigInfo", "Initializing\n")); netsnmp_register_scalar( netsnmp_create_handler_registration("LHAHBVersion", handle_LHAHBVersion, LHAHBVersion_oid, OID_LENGTH(LHAHBVersion_oid), HANDLER_CAN_RONLY )); netsnmp_register_scalar( netsnmp_create_handler_registration("LHAKeepAlive", handle_LHAKeepAlive, LHAKeepAlive_oid, OID_LENGTH(LHAKeepAlive_oid), HANDLER_CAN_RONLY )); netsnmp_register_scalar( netsnmp_create_handler_registration("LHADeadTime", handle_LHADeadTime, LHADeadTime_oid, OID_LENGTH(LHADeadTime_oid), HANDLER_CAN_RONLY )); netsnmp_register_scalar( netsnmp_create_handler_registration("LHADeadPing", handle_LHADeadPing, LHADeadPing_oid, OID_LENGTH(LHADeadPing_oid), HANDLER_CAN_RONLY )); netsnmp_register_scalar( netsnmp_create_handler_registration("LHAWarnTime", handle_LHAWarnTime, LHAWarnTime_oid, OID_LENGTH(LHAWarnTime_oid), HANDLER_CAN_RONLY )); netsnmp_register_scalar( netsnmp_create_handler_registration("LHAInitDead", handle_LHAInitDead, LHAInitDead_oid, OID_LENGTH(LHAInitDead_oid), HANDLER_CAN_RONLY )); netsnmp_register_scalar( netsnmp_create_handler_registration("LHABaudRate", handle_LHABaudRate, LHABaudRate_oid, OID_LENGTH(LHABaudRate_oid), HANDLER_CAN_RONLY )); netsnmp_register_scalar( netsnmp_create_handler_registration("LHAutoFailBack", handle_LHAutoFailBack, LHAutoFailBack_oid, OID_LENGTH(LHAutoFailBack_oid), HANDLER_CAN_RONLY )); netsnmp_register_scalar( netsnmp_create_handler_registration("LHAStonith", handle_LHAStonith, LHAStonith_oid, OID_LENGTH(LHAStonith_oid), HANDLER_CAN_RONLY )); netsnmp_register_scalar( netsnmp_create_handler_registration("LHAStonithHost", handle_LHAStonithHost, LHAStonithHost_oid, OID_LENGTH(LHAStonithHost_oid), HANDLER_CAN_RONLY )); netsnmp_register_scalar( netsnmp_create_handler_registration("LHARespawn", handle_LHARespawn, LHARespawn_oid, OID_LENGTH(LHARespawn_oid), HANDLER_CAN_RONLY )); } int handle_LHAHBVersion(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { /* We are never called for a GETNEXT if it's registered as a "instance", as it's "magically" handled for us. */ /* a instance handler also only hands us one request at a time, so we don't need to loop over a list of requests; we'll only get one. */ char * value; if (hbconfig_get_str(LHA_CONF_HBVERSION, &value) != HA_OK) return SNMP_ERR_GENERR; switch(reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) value, strlen(value) + 1); break; default: /* we should never get here, so this is a really bad error */ free(value); return SNMP_ERR_GENERR; } free(value); return SNMP_ERR_NOERROR; } int handle_LHAKeepAlive(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { char * value; if (hbconfig_get_str(LHA_CONF_KEEPALIVE, &value) != HA_OK) return SNMP_ERR_GENERR; switch(reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) value, strlen(value) + 1); break; default: /* we should never get here, so this is a really bad error */ free(value); return SNMP_ERR_GENERR; } free(value); return SNMP_ERR_NOERROR; } int handle_LHADeadTime(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { char * value; if (hbconfig_get_str(LHA_CONF_DEADTIME, &value) != HA_OK) return SNMP_ERR_GENERR; switch(reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) value, strlen(value) + 1); break; default: /* we should never get here, so this is a really bad error */ free(value); return SNMP_ERR_GENERR; } free(value); return SNMP_ERR_NOERROR; } int handle_LHADeadPing(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { char * value; if (hbconfig_get_str(LHA_CONF_DEADPING, &value) != HA_OK) return SNMP_ERR_GENERR; switch(reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) value, strlen(value) + 1); break; default: /* we should never get here, so this is a really bad error */ free(value); return SNMP_ERR_GENERR; } free(value); return SNMP_ERR_NOERROR; } int handle_LHAWarnTime(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { char * value; if (hbconfig_get_str(LHA_CONF_WARNTIME, &value) != HA_OK) return SNMP_ERR_GENERR; switch(reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) value, strlen(value) + 1); break; default: /* we should never get here, so this is a really bad error */ free(value); return SNMP_ERR_GENERR; } free(value); return SNMP_ERR_NOERROR; } int handle_LHAInitDead(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { char * value; if (hbconfig_get_str(LHA_CONF_INITDEAD, &value) != HA_OK) return SNMP_ERR_GENERR; switch(reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) value, strlen(value) + 1); break; default: /* we should never get here, so this is a really bad error */ free(value); return SNMP_ERR_GENERR; } free(value); return SNMP_ERR_NOERROR; } int handle_LHABaudRate(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { char * value; if (hbconfig_get_str(LHA_CONF_BAUDRATE, &value) != HA_OK) return SNMP_ERR_GENERR; switch(reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) value, strlen(value) + 1); break; default: /* we should never get here, so this is a really bad error */ free(value); return SNMP_ERR_GENERR; } free(value); return SNMP_ERR_NOERROR; } int handle_LHAutoFailBack(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { char * ret; uint32_t value; if (hbconfig_get_str(LHA_CONF_AUTOFAIL, &ret) != HA_OK) return SNMP_ERR_GENERR; if (strcmp(ret, "on") == 0) {value = 1;} else if (strcmp(ret, "off") == 0) {value = 2;} else if (strcmp(ret, "legacy") == 0) {value = 3;} else {value = 0;} switch(reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, (u_char *) & value, sizeof(value)); break; default: /* we should never get here, so this is a really bad error */ free(ret); return SNMP_ERR_GENERR; } free(ret); return SNMP_ERR_NOERROR; } int handle_LHAStonith(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { char * value; if (hbconfig_get_str(LHA_CONF_STONITH, &value) != HA_OK) return SNMP_ERR_GENERR; switch(reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) value, strlen(value) + 1); break; default: /* we should never get here, so this is a really bad error */ free(value); return SNMP_ERR_GENERR; } free(value); return SNMP_ERR_NOERROR; } int handle_LHAStonithHost(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { char * value; if (hbconfig_get_str(LHA_CONF_STONITHHOST, &value) != HA_OK) return SNMP_ERR_GENERR; switch(reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) value, strlen(value) + 1); break; default: /* we should never get here, so this is a really bad error */ free(value); return SNMP_ERR_GENERR; } free(value); return SNMP_ERR_NOERROR; } int handle_LHARespawn(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { char * value; if (hbconfig_get_str(LHA_CONF_RESPAWN, &value) != HA_OK) return SNMP_ERR_GENERR; switch(reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) value, strlen(value) + 1); break; default: /* we should never get here, so this is a really bad error */ free(value); return SNMP_ERR_GENERR; } free(value); return SNMP_ERR_NOERROR; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAHeartbeatConfigInfo.h000066400000000000000000000025051211477743100265130ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.scalar.conf,v 1.7 2003/04/08 14:57:04 dts12 Exp $ */ #ifndef LHAHEARTBEATCONFIGINFO_H #define LHAHEARTBEATCONFIGINFO_H /* function declarations */ void init_LHAHeartbeatConfigInfo(void); Netsnmp_Node_Handler handle_LHAHBVersion; Netsnmp_Node_Handler handle_LHAAPIAuth; Netsnmp_Node_Handler handle_LHADebugFile; Netsnmp_Node_Handler handle_LHADebug; Netsnmp_Node_Handler handle_LHAHOPFudge; Netsnmp_Node_Handler handle_LHARespawn; Netsnmp_Node_Handler handle_LHADeadTime; Netsnmp_Node_Handler handle_LHAInitDead; Netsnmp_Node_Handler handle_LHAUDPPort; Netsnmp_Node_Handler handle_LHALogFile; Netsnmp_Node_Handler handle_LHAStonith; Netsnmp_Node_Handler handle_LHABaudRate; Netsnmp_Node_Handler handle_LHNiceFailBack; Netsnmp_Node_Handler handle_LHARTPriority; Netsnmp_Node_Handler handle_LHAMsgFmt; Netsnmp_Node_Handler handle_LHARealTime; Netsnmp_Node_Handler handle_LHAStonithHost; Netsnmp_Node_Handler handle_LHANormalPoll; Netsnmp_Node_Handler handle_LHAGenMethod; Netsnmp_Node_Handler handle_LHAWarnTime; Netsnmp_Node_Handler handle_LHADeadPing; Netsnmp_Node_Handler handle_LHAKeepAlive; Netsnmp_Node_Handler handle_LHAWatchdogTimer; Netsnmp_Node_Handler handle_LHALogFacility; Netsnmp_Node_Handler handle_LHAutoFailBack; #endif /* LHAHEARTBEATCONFIGINFO_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAIFStatusTable.c000066400000000000000000000252511211477743100253220ustar00rootroot00000000000000/* * Copyright (c) 2004 Intel Corp. * * Author: Zou Yixiong (yixiong.zou@intel.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ /* * Note: this file originally auto-generated by mib2c using * : mib2c.iterate.conf,v 5.9 2003/06/04 00:14:41 hardaker Exp $ */ #include #ifdef PACKAGE_BUGREPORT #undef PACKAGE_BUGREPORT #endif #ifdef PACKAGE_NAME #undef PACKAGE_NAME #endif #ifdef PACKAGE_STRING #undef PACKAGE_STRING #endif #ifdef PACKAGE_TARNAME #undef PACKAGE_TARNAME #endif #ifdef PACKAGE_VERSION #undef PACKAGE_VERSION #endif #include #include #include #include "LHAIFStatusTable.h" #include "hbagent.h" static GPtrArray * gIFInfo = NULL; extern const int snmp_cache_time_out; int LHAIFStatusTable_load(netsnmp_cache *cache, void *vmagic); void LHAIFStatusTable_free(netsnmp_cache *cache, void *vmagic); /** Initialize the LHAIFStatusTable table by defining its contents and how it's structured */ void initialize_table_LHAIFStatusTable(void) { static oid LHAIFStatusTable_oid[] = {1,3,6,1,4,1,4682,3}; netsnmp_table_registration_info *table_info; netsnmp_handler_registration *my_handler; netsnmp_iterator_info *iinfo; /** create the table registration information structures */ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); /** if your table is read only, it's easiest to change the HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */ my_handler = netsnmp_create_handler_registration("LHAIFStatusTable", LHAIFStatusTable_handler, LHAIFStatusTable_oid, OID_LENGTH(LHAIFStatusTable_oid), HANDLER_CAN_RONLY); if (!my_handler || !table_info || !iinfo) { snmp_log(LOG_ERR, "malloc failed in initialize_table_LHAIFStatusTable"); SNMP_FREE(iinfo); SNMP_FREE(table_info); return; /* Serious error. */ } /*************************************************** * Setting up the table's definition */ netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: LHANodeIndex */ ASN_INTEGER, /* index: LHAIFIndex */ 0); /** Define the minimum and maximum accessible columns. This optimizes retrival. */ table_info->min_column = 2; table_info->max_column = 3; /* iterator access routines */ iinfo->get_first_data_point = LHAIFStatusTable_get_first_data_point; iinfo->get_next_data_point = LHAIFStatusTable_get_next_data_point; /** you may wish to set these as well */ #ifdef MAYBE_USE_THESE iinfo->make_data_context = LHAIFStatusTable_context_convert_function; iinfo->free_data_context = LHAIFStatusTable_data_free; /** pick *only* one of these if you use them */ iinfo->free_loop_context = LHAIFStatusTable_loop_free; iinfo->free_loop_context_at_end = LHAIFStatusTable_loop_free; #endif /** tie the two structures together */ iinfo->table_reginfo = table_info; /*************************************************** * registering the table with the master agent */ DEBUGMSGTL(("initialize_table_LHAIFStatusTable", "Registering table LHAIFStatusTable as a table iterator\n")); netsnmp_register_table_iterator(my_handler, iinfo); /* * .... with a local cache */ netsnmp_inject_handler(my_handler, netsnmp_get_cache_handler(snmp_cache_time_out, LHAIFStatusTable_load, LHAIFStatusTable_free, LHAIFStatusTable_oid, OID_LENGTH(LHAIFStatusTable_oid))); } /** Initializes the LHAIFStatusTable module */ void init_LHAIFStatusTable(void) { /** here we initialize all the tables we're planning on supporting */ initialize_table_LHAIFStatusTable(); } /** returns the first data point within the LHAIFStatusTable table data. Set the my_loop_context variable to the first data point structure of your choice (from which you can find the next one). This could be anything from the first node in a linked list, to an integer pointer containing the beginning of an array variable. Set the my_data_context variable to something to be returned to you later (in your main LHAIFStatusTable_handler routine) that will provide you with the data to return in a given row. This could be the same pointer as what my_loop_context is set to, or something different. The put_index_data variable contains a list of snmp variable bindings, one for each index in your table. Set the values of each appropriately according to the data matching the first row and return the put_index_data variable at the end of the function. */ netsnmp_variable_list * LHAIFStatusTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { if (gIFInfo && gIFInfo->len == 0) return NULL; *my_loop_context = NULL; return LHAIFStatusTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } /** functionally the same as LHAIFStatusTable_get_first_data_point, but my_loop_context has already been set to a previous value and should be updated to the next in the list. For example, if it was a linked list, you might want to cast it to your local data type and then return my_loop_context->next. The my_data_context pointer should be set to something you need later (in your main LHAIFStatusTable_handler routine) and the indexes in put_index_data updated again. */ netsnmp_variable_list * LHAIFStatusTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { static size_t i = 0; struct hb_ifinfo * info; netsnmp_variable_list *vptr; if (*my_loop_context != NULL) { i = *((size_t *) *my_loop_context); } else { i = 0; } if (!gIFInfo || i >= gIFInfo->len) return NULL; vptr = put_index_data; info = (struct hb_ifinfo *) g_ptr_array_index(gIFInfo, i); snmp_set_var_value(vptr, (u_char *) &(info->nodeid), sizeof(size_t)); vptr = vptr->next_variable; snmp_set_var_value(vptr, (u_char *) &(info->id), sizeof(size_t)); vptr = vptr->next_variable; i++; *my_loop_context = (void *) &i; *my_data_context = (void *) info; return put_index_data; } /** handles requests for the LHAIFStatusTable table, if anything else needs to be done */ int LHAIFStatusTable_handler( netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; netsnmp_variable_list *var; struct hb_ifinfo * entry; for(request = requests; request; request = request->next) { var = request->requestvb; if (request->processed != 0) continue; /** perform anything here that you need to do before each request is processed. */ /** the following extracts the my_data_context pointer set in the loop functions above. You can then use the results to help return data for the columns of the LHAIFStatusTable table in question */ entry = (struct hb_ifinfo *) netsnmp_extract_iterator_context(request); if (entry == NULL) { if (reqinfo->mode == MODE_GET) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } /** XXX: no row existed, if you support creation and this is a set, start dealing with it here, else continue */ } /** extracts the information about the table from the request */ table_info = netsnmp_extract_table_info(request); /** table_info->colnum contains the column number requested */ /** table_info->indexes contains a linked list of snmp variable bindings for the indexes of the table. Values in the list have been set corresponding to the indexes of the request */ if (table_info==NULL) { continue; } switch(reqinfo->mode) { /** the table_iterator helper should change all GETNEXTs into GETs for you automatically, so you don't have to worry about the GETNEXT case. Only GETs and SETs need to be dealt with here */ case MODE_GET: switch(table_info->colnum) { case COLUMN_LHAIFNAME: snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *) entry->name, strlen(entry->name) + 1); break; case COLUMN_LHAIFSTATUS: snmp_set_var_typed_value(var, ASN_INTEGER, (u_char *) & entry->status, sizeof(entry->status)); break; default: /** We shouldn't get here */ snmp_log(LOG_ERR, "problem encountered in LHAIFStatusTable_handler: unknown column\n"); } break; case MODE_SET_RESERVE1: /** set handling... */ default: snmp_log(LOG_ERR, "problem encountered in LHAIFStatusTable_handler: unsupported mode\n"); } } return SNMP_ERR_NOERROR; } int LHAIFStatusTable_load(netsnmp_cache *cache, void *vmagic) { LHAIFStatusTable_free(cache, vmagic); gIFInfo = get_hb_info(LHA_IFSTATUSINFO); return 0; } void LHAIFStatusTable_free(netsnmp_cache *cache, void *vmagic) { return; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAIFStatusTable.h000066400000000000000000000012341211477743100253220ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.iterate.conf,v 5.9 2003/06/04 00:14:41 hardaker Exp $ */ #ifndef LHAIFSTATUSTABLE_H #define LHAIFSTATUSTABLE_H /* function declarations */ void init_LHAIFStatusTable(void); void initialize_table_LHAIFStatusTable(void); Netsnmp_Node_Handler LHAIFStatusTable_handler; Netsnmp_First_Data_Point LHAIFStatusTable_get_first_data_point; Netsnmp_Next_Data_Point LHAIFStatusTable_get_next_data_point; /* column number definitions for table LHAIFStatusTable */ #include "LHAIFStatusTable_columns.h" /* enum definions */ #include "LHAIFStatusTable_enums.h" #endif /* LHAIFSTATUSTABLE_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAIFStatusTable_columns.h000066400000000000000000000006421211477743100270640ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.column_defines.conf,v 5.1 2002/05/08 05:42:47 hardaker Exp $ */ #ifndef LHAIFSTATUSTABLE_COLUMNS_H #define LHAIFSTATUSTABLE_COLUMNS_H /* column number definitions for table LHAIFStatusTable */ #define COLUMN_LHAIFINDEX 1 #define COLUMN_LHAIFNAME 2 #define COLUMN_LHAIFSTATUS 3 #endif /* LHAIFSTATUSTABLE_COLUMNS_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAIFStatusTable_enums.h000066400000000000000000000006151211477743100265330ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.column_enums.conf,v 5.2 2003/02/22 04:09:25 hardaker Exp $ */ #ifndef LHAIFSTATUSTABLE_ENUMS_H #define LHAIFSTATUSTABLE_ENUMS_H /* enums for column LHAIFStatus */ #define LHAIFSTATUS_UNKNOWN 0 #define LHAIFSTATUS_UP 1 #define LHAIFSTATUS_DOWN 2 #endif /* LHAIFSTATUSTABLE_ENUMS_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAMembershipTable.c000066400000000000000000000273401211477743100257140ustar00rootroot00000000000000/* * Copyright (c) 2004 Intel Corp. * * Author: Zou Yixiong (yixiong.zou@intel.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ /* * Note: this file originally auto-generated by mib2c using * : mib2c.iterate.conf,v 5.9 2003/06/04 00:14:41 hardaker Exp $ */ #include #ifdef PACKAGE_BUGREPORT #undef PACKAGE_BUGREPORT #endif #ifdef PACKAGE_NAME #undef PACKAGE_NAME #endif #ifdef PACKAGE_STRING #undef PACKAGE_STRING #endif #ifdef PACKAGE_TARNAME #undef PACKAGE_TARNAME #endif #ifdef PACKAGE_VERSION #undef PACKAGE_VERSION #endif #include #include #include #include "LHAMembershipTable.h" #include "hbagent.h" static GPtrArray * gMembershipInfo = NULL; extern const int snmp_cache_time_out; int LHAMembershipTable_load(netsnmp_cache *cache, void *vmagic); void LHAMembershipTable_free(netsnmp_cache *cache, void *vmagic); /** Initialize the LHAMembershipTable table by defining its contents and how it's structured */ void initialize_table_LHAMembershipTable(void) { static oid LHAMembershipTable_oid[] = {1,3,6,1,4,1,4682,6}; netsnmp_table_registration_info *table_info; netsnmp_handler_registration *my_handler; netsnmp_iterator_info *iinfo; /** create the table registration information structures */ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); /** if your table is read only, it's easiest to change the HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */ my_handler = netsnmp_create_handler_registration("LHAMembershipTable", LHAMembershipTable_handler, LHAMembershipTable_oid, OID_LENGTH(LHAMembershipTable_oid), HANDLER_CAN_RONLY); if (!my_handler || !table_info || !iinfo) { snmp_log(LOG_ERR, "malloc failed in initialize_table_LHAMembershipTable"); SNMP_FREE(iinfo); SNMP_FREE(table_info); return; /* Serious error. */ } /*************************************************** * Setting up the table's definition */ netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: LHAMemberIndex */ 0); /** Define the minimum and maximum accessible columns. This optimizes retrival. */ table_info->min_column = 2; table_info->max_column = 7; /* iterator access routines */ iinfo->get_first_data_point = LHAMembershipTable_get_first_data_point; iinfo->get_next_data_point = LHAMembershipTable_get_next_data_point; /** tie the two structures together */ iinfo->table_reginfo = table_info; /*************************************************** * registering the table with the master agent */ DEBUGMSGTL(("initialize_table_LHAMembershipTable", "Registering table LHAMembershipTable as a table iterator\n")); netsnmp_register_table_iterator(my_handler, iinfo); /* * .... with a local cache */ netsnmp_inject_handler(my_handler, netsnmp_get_cache_handler(snmp_cache_time_out, LHAMembershipTable_load, LHAMembershipTable_free, LHAMembershipTable_oid, OID_LENGTH(LHAMembershipTable_oid))); } /** Initializes the LHAMembershipTable module */ void init_LHAMembershipTable(void) { /** here we initialize all the tables we're planning on supporting */ initialize_table_LHAMembershipTable(); } /** returns the first data point within the LHAMembershipTable table data. Set the my_loop_context variable to the first data point structure of your choice (from which you can find the next one). This could be anything from the first node in a linked list, to an integer pointer containing the beginning of an array variable. Set the my_data_context variable to something to be returned to you later (in your main LHAMembershipTable_handler routine) that will provide you with the data to return in a given row. This could be the same pointer as what my_loop_context is set to, or something different. The put_index_data variable contains a list of snmp variable bindings, one for each index in your table. Set the values of each appropriately according to the data matching the first row and return the put_index_data variable at the end of the function. */ netsnmp_variable_list * LHAMembershipTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { if (gMembershipInfo && gMembershipInfo->len == 0) return NULL; *my_loop_context = NULL; return LHAMembershipTable_get_next_data_point( my_loop_context, my_data_context, put_index_data, mydata); } /** functionally the same as LHAMembershipTable_get_first_data_point, but my_loop_context has already been set to a previous value and should be updated to the next in the list. For example, if it was a linked list, you might want to cast it to your local data type and then return my_loop_context->next. The my_data_context pointer should be set to something you need later (in your main LHAMembershipTable_handler routine) and the indexes in put_index_data updated again. */ netsnmp_variable_list * LHAMembershipTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { static size_t i = 0; netsnmp_variable_list *vptr; #if SUPPORT_HEARTBEAT SaClmClusterNotificationT * info; #endif if (*my_loop_context != NULL) { i = *((size_t *) *my_loop_context); } else { i = 0; } if (!gMembershipInfo || i >= gMembershipInfo->len) return NULL; vptr = put_index_data; #if SUPPORT_HEARTBEAT info = (SaClmClusterNotificationT *) g_ptr_array_index(gMembershipInfo, i); #endif snmp_set_var_value(vptr, (u_char *) &i, sizeof(i)); vptr = vptr->next_variable; i++; *my_loop_context = (void *) &i; #if SUPPORT_HEARTBEAT *my_data_context = (void *) info; #endif return put_index_data; } /** handles requests for the LHAMembershipTable table, if anything else needs to be done */ int LHAMembershipTable_handler( netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; netsnmp_variable_list *var; #if SUPPORT_HEARTBEAT SaClmClusterNotificationT * entry; #endif int member; for(request = requests; request; request = request->next) { var = request->requestvb; if (request->processed != 0) continue; /** perform anything here that you need to do before each request is processed. */ /** the following extracts the my_data_context pointer set in the loop functions above. You can then use the results to help return data for the columns of the LHAMembershipTable table in question */ #if SUPPORT_HEARTBEAT entry = (SaClmClusterNotificationT *) netsnmp_extract_iterator_context(request); if (entry == NULL) { if (reqinfo->mode == MODE_GET) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } /** XXX: no row existed, if you support creation and this is a set, start dealing with it here, else continue */ } #endif /** extracts the information about the table from the request */ table_info = netsnmp_extract_table_info(request); /** table_info->colnum contains the column number requested */ /** table_info->indexes contains a linked list of snmp variable bindings for the indexes of the table. Values in the list have been set corresponding to the indexes of the request */ if (table_info==NULL) { continue; } switch(reqinfo->mode) { /** the table_iterator helper should change all GETNEXTs into GETs for you automatically, so you don't have to worry about the GETNEXT case. Only GETs and SETs need to be dealt with here */ case MODE_GET: switch(table_info->colnum) { case COLUMN_LHAMEMBERNAME: #if SUPPORT_HEARTBEAT snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *) entry->clusterNode.nodeName.value, strlen((char *)entry->clusterNode.nodeName.value) + 1); #endif break; case COLUMN_LHAMEMBERADDRESS: #if SUPPORT_HEARTBEAT snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *) entry->clusterNode.nodeAddress.value, SA_CLM_MAX_ADDRESS_LENGTH); #endif break; case COLUMN_LHAMEMBERCLUSTERNAME: #if SUPPORT_HEARTBEAT snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *) entry->clusterNode.clusterName.value, strlen((char *)entry->clusterNode.clusterName.value) + 1); #endif break; case COLUMN_LHAMEMBERISMEMBER: #if SUPPORT_HEARTBEAT if (entry->clusterNode.member) member = 1; else member = 2; #endif snmp_set_var_typed_value(var, ASN_INTEGER, (u_char *) &member, sizeof(member)); break; case COLUMN_LHAMEMBERLASTCHANGE: #if SUPPORT_HEARTBEAT snmp_set_var_typed_value(var, ASN_INTEGER, (u_char *) & entry->clusterChanges, sizeof(entry->clusterChanges)); #endif break; case COLUMN_LHAMEMBERBOOTTIME: #if SUPPORT_HEARTBEAT snmp_set_var_typed_value(var, ASN_TIMETICKS, (u_char *) & entry->clusterNode.bootTimestamp, sizeof(entry->clusterNode.bootTimestamp)); #endif break; default: /** We shouldn't get here */ snmp_log(LOG_ERR, "problem encountered in LHAMembershipTable_handler: unknown column\n"); } break; case MODE_SET_RESERVE1: /** set handling... */ default: snmp_log(LOG_ERR, "problem encountered in LHAMembershipTable_handler: unsupported mode\n"); } } return SNMP_ERR_NOERROR; } int LHAMembershipTable_load(netsnmp_cache *cache, void *vmagic) { LHAMembershipTable_free(cache, vmagic); gMembershipInfo = get_hb_info(LHA_MEMBERSHIPINFO); return 0; } void LHAMembershipTable_free(netsnmp_cache *cache, void *vmagic) { return; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAMembershipTable.h000066400000000000000000000012621211477743100257140ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.iterate.conf,v 5.9 2003/06/04 00:14:41 hardaker Exp $ */ #ifndef LHAMEMBERSHIPTABLE_H #define LHAMEMBERSHIPTABLE_H /* function declarations */ void init_LHAMembershipTable(void); void initialize_table_LHAMembershipTable(void); Netsnmp_Node_Handler LHAMembershipTable_handler; Netsnmp_First_Data_Point LHAMembershipTable_get_first_data_point; Netsnmp_Next_Data_Point LHAMembershipTable_get_next_data_point; /* column number definitions for table LHAMembershipTable */ #include "LHAMembershipTable_columns.h" /* enum definions */ #include "LHAMembershipTable_enums.h" #endif /* LHAMEMBERSHIPTABLE_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAMembershipTable_columns.h000066400000000000000000000011501211477743100274500ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.column_defines.conf,v 5.1 2002/05/08 05:42:47 hardaker Exp $ */ #ifndef LHAMEMBERSHIPTABLE_COLUMNS_H #define LHAMEMBERSHIPTABLE_COLUMNS_H /* column number definitions for table LHAMembershipTable */ #define COLUMN_LHAMEMBERINDEX 1 #define COLUMN_LHAMEMBERNAME 2 #define COLUMN_LHAMEMBERADDRESS 3 #define COLUMN_LHAMEMBERCLUSTERNAME 4 #define COLUMN_LHAMEMBERISMEMBER 5 #define COLUMN_LHAMEMBERLASTCHANGE 6 #define COLUMN_LHAMEMBERBOOTTIME 7 #endif /* LHAMEMBERSHIPTABLE_COLUMNS_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAMembershipTable_enums.h000066400000000000000000000011611211477743100271210ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.column_enums.conf,v 5.2 2003/02/22 04:09:25 hardaker Exp $ */ #ifndef LHAMEMBERSHIPTABLE_ENUMS_H #define LHAMEMBERSHIPTABLE_ENUMS_H /* enums for column LHAMemberIsMember */ #define LHAMEMBERISMEMBER_TRUE 1 #define LHAMEMBERISMEMBER_FALSE 2 /* enums for column LHAMemberLastChange */ #define LHAMEMBERLASTCHANGE_UNDEFINED 0 #define LHAMEMBERLASTCHANGE_NOCHANGE 1 #define LHAMEMBERLASTCHANGE_JOINED 2 #define LHAMEMBERLASTCHANGE_LEFT 3 #endif /* LHAMEMBERSHIPTABLE_ENUMS_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHANodeTable.c000066400000000000000000000251221211477743100245020ustar00rootroot00000000000000/* * Copyright (c) 2004 Intel Corp. * * Author: Zou Yixiong (yixiong.zou@intel.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ /* * Note: this file originally auto-generated by mib2c using * : mib2c.iterate.conf,v 5.9 2003/06/04 00:14:41 hardaker Exp $ */ #include #ifdef PACKAGE_BUGREPORT #undef PACKAGE_BUGREPORT #endif #ifdef PACKAGE_NAME #undef PACKAGE_NAME #endif #ifdef PACKAGE_STRING #undef PACKAGE_STRING #endif #ifdef PACKAGE_TARNAME #undef PACKAGE_TARNAME #endif #ifdef PACKAGE_VERSION #undef PACKAGE_VERSION #endif #include #include #include #include "LHANodeTable.h" #include "hbagent.h" static GPtrArray * gNodeInfo = NULL; extern const int snmp_cache_time_out; int LHANodeTable_load(netsnmp_cache *cache, void *vmagic); void LHANodeTable_free(netsnmp_cache *cache, void *vmagic); /** Initialize the LHANodeTable table by defining its contents and how it's structured */ void initialize_table_LHANodeTable(void) { static oid LHANodeTable_oid[] = {1,3,6,1,4,1,4682,2}; netsnmp_table_registration_info *table_info; netsnmp_handler_registration *my_handler; netsnmp_iterator_info *iinfo; /** create the table registration information structures */ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); /** if your table is read only, it's easiest to change the HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */ my_handler = netsnmp_create_handler_registration("LHANodeTable", LHANodeTable_handler, LHANodeTable_oid, OID_LENGTH(LHANodeTable_oid), HANDLER_CAN_RONLY); if (!my_handler || !table_info || !iinfo) { snmp_log(LOG_ERR, "malloc failed in initialize_table_LHANodeTable"); SNMP_FREE(iinfo); SNMP_FREE(table_info); return; /* Serious error. */ } /*************************************************** * Setting up the table's definition */ netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: LHANodeIndex */ 0); /** Define the minimum and maximum accessible columns. This optimizes retrival. */ table_info->min_column = 2; table_info->max_column = 6; /* iterator access routines */ iinfo->get_first_data_point = LHANodeTable_get_first_data_point; iinfo->get_next_data_point = LHANodeTable_get_next_data_point; /** tie the two structures together */ iinfo->table_reginfo = table_info; /*************************************************** * registering the table with the master agent */ DEBUGMSGTL(("initialize_table_LHANodeTable", "Registering table LHANodeTable as a table iterator\n")); netsnmp_register_table_iterator(my_handler, iinfo); /* * .... with a local cache */ netsnmp_inject_handler(my_handler, netsnmp_get_cache_handler(snmp_cache_time_out, LHANodeTable_load, LHANodeTable_free, LHANodeTable_oid, OID_LENGTH(LHANodeTable_oid))); } /** Initializes the LHANodeTable module */ void init_LHANodeTable(void) { /** here we initialize all the tables we're planning on supporting */ initialize_table_LHANodeTable(); } /** returns the first data point within the LHANodeTable table data. Set the my_loop_context variable to the first data point structure of your choice (from which you can find the next one). This could be anything from the first node in a linked list, to an integer pointer containing the beginning of an array variable. Set the my_data_context variable to something to be returned to you later (in your main LHANodeTable_handler routine) that will provide you with the data to return in a given row. This could be the same pointer as what my_loop_context is set to, or something different. The put_index_data variable contains a list of snmp variable bindings, one for each index in your table. Set the values of each appropriately according to the data matching the first row and return the put_index_data variable at the end of the function. */ netsnmp_variable_list * LHANodeTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { if (gNodeInfo && gNodeInfo->len == 0) return NULL; *my_loop_context = NULL; return LHANodeTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } /** functionally the same as LHANodeTable_get_first_data_point, but my_loop_context has already been set to a previous value and should be updated to the next in the list. For example, if it was a linked list, you might want to cast it to your local data type and then return my_loop_context->next. The my_data_context pointer should be set to something you need later (in your main LHANodeTable_handler routine) and the indexes in put_index_data updated again. */ netsnmp_variable_list * LHANodeTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { static size_t i; netsnmp_variable_list *vptr; struct hb_nodeinfo * info; if (*my_loop_context != NULL) { i = *((size_t *) *my_loop_context); } else { i = 0; } if (!gNodeInfo || i >= gNodeInfo->len) return NULL; vptr = put_index_data; info = (struct hb_nodeinfo *) g_ptr_array_index(gNodeInfo, i); snmp_set_var_value(vptr, (u_char *) & info->id, sizeof(size_t)); vptr = vptr->next_variable; i++; *my_data_context = (void *) info; *my_loop_context = (void *) &i; return put_index_data; } /** handles requests for the LHANodeTable table, if anything else needs to be done */ int LHANodeTable_handler( netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; netsnmp_variable_list *var; struct hb_nodeinfo * entry; for (request = requests; request; request = request->next) { var = request->requestvb; if (request->processed != 0) continue; /** perform anything here that you need to do before each request is processed. */ entry = (struct hb_nodeinfo *) netsnmp_extract_iterator_context(request); if (entry == NULL) { if (reqinfo->mode == MODE_GET) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } /** XXX: no row existed, if you support creation and this is a set, start dealing with it here, else continue */ } /** extracts the information about the table from the request */ table_info = netsnmp_extract_table_info(request); /** table_info->colnum contains the column number requested */ /** table_info->indexes contains a linked list of snmp variable bindings for the indexes of the table. Values in the list have been set corresponding to the indexes of the request */ if (table_info==NULL) { continue; } switch(reqinfo->mode) { /** the table_iterator helper should change all GETNEXTs into GETs for you automatically, so you don't have to worry about the GETNEXT case. Only GETs and SETs need to be dealt with here */ case MODE_GET: switch(table_info->colnum) { case COLUMN_LHANODEINDEX: snmp_set_var_typed_value(var, ASN_INTEGER, (u_char*)&entry->id, sizeof(entry->id)); break; case COLUMN_LHANODENAME: snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *) (entry->name), strlen(entry->name) + 1); break; case COLUMN_LHANODETYPE: snmp_set_var_typed_value(var, ASN_INTEGER, (u_char *) & entry->type, sizeof(entry->type)); break; case COLUMN_LHANODESTATUS: snmp_set_var_typed_value(var, ASN_INTEGER, (u_char *) & entry->status, sizeof(entry->status)); break; #ifdef HAVE_NEW_HB_API case COLUMN_LHANODEUUID: snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *) &entry->uuid, sizeof(entry->uuid)); break; #endif /* HAVE_NEW_HB_API */ case COLUMN_LHANODEIFCOUNT: snmp_set_var_typed_value(var, ASN_COUNTER, (u_char *) & entry->ifcount, sizeof(entry->ifcount)); break; default: /** We shouldn't get here */ snmp_log(LOG_ERR, "problem encountered in LHANodeTable_handler: unknown column\n"); } break; case MODE_SET_RESERVE1: /** set handling... */ default: snmp_log(LOG_ERR, "problem encountered in LHANodeTable_handler: unsupported mode\n"); } } return SNMP_ERR_NOERROR; } int LHANodeTable_load(netsnmp_cache *cache, void *vmagic) { LHANodeTable_free(cache, vmagic); gNodeInfo = get_hb_info(LHA_NODEINFO); return 0; } void LHANodeTable_free(netsnmp_cache *cache, void *vmagic) { return; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHANodeTable.h000066400000000000000000000011601211477743100245030ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.iterate.conf,v 5.9 2003/06/04 00:14:41 hardaker Exp $ */ #ifndef LHANODETABLE_H #define LHANODETABLE_H /* function declarations */ void init_LHANodeTable(void); void initialize_table_LHANodeTable(void); Netsnmp_Node_Handler LHANodeTable_handler; Netsnmp_First_Data_Point LHANodeTable_get_first_data_point; Netsnmp_Next_Data_Point LHANodeTable_get_next_data_point; /* column number definitions for table LHANodeTable */ #include "LHANodeTable_columns.h" /* enum definions */ #include "LHANodeTable_enums.h" #endif /* LHANODETABLE_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHANodeTable_columns.h000066400000000000000000000010121211477743100262370ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.column_defines.conf,v 5.1 2002/05/08 05:42:47 hardaker Exp $ */ #ifndef LHANODETABLE_COLUMNS_H #define LHANODETABLE_COLUMNS_H /* column number definitions for table LHANodeTable */ #define COLUMN_LHANODEINDEX 1 #define COLUMN_LHANODENAME 2 #define COLUMN_LHANODETYPE 3 #define COLUMN_LHANODESTATUS 4 #define COLUMN_LHANODEUUID 5 #define COLUMN_LHANODEIFCOUNT 6 #endif /* LHANODETABLE_COLUMNS_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHANodeTable_enums.h000066400000000000000000000011721211477743100257150ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.column_enums.conf,v 5.2 2003/02/22 04:09:25 hardaker Exp $ */ #ifndef LHANODETABLE_ENUMS_H #define LHANODETABLE_ENUMS_H /* enums for column LHANodeType */ #define LHANODETYPE_UNKNOWN 0 #define LHANODETYPE_NORMAL 1 #define LHANODETYPE_PING 2 /* enums for column LHANodeStatus */ #define LHANODESTATUS_UNKNOWN 0 #define LHANODESTATUS_INIT 1 #define LHANODESTATUS_UP 2 #define LHANODESTATUS_ACTIVE 3 #define LHANODESTATUS_DEAD 4 #endif /* LHANODETABLE_ENUMS_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAResourceGroupTable.c000066400000000000000000000261441211477743100264260ustar00rootroot00000000000000/* * Copyright (c) 2004 Intel Corp. * * Author: Zou Yixiong (yixiong.zou@intel.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ /* * Note: this file originally auto-generated by mib2c using * : mib2c.iterate.conf,v 5.9 2003/06/04 00:14:41 hardaker Exp $ */ #include #ifdef PACKAGE_BUGREPORT #undef PACKAGE_BUGREPORT #endif #ifdef PACKAGE_NAME #undef PACKAGE_NAME #endif #ifdef PACKAGE_STRING #undef PACKAGE_STRING #endif #ifdef PACKAGE_TARNAME #undef PACKAGE_TARNAME #endif #ifdef PACKAGE_VERSION #undef PACKAGE_VERSION #endif #include #include #include #include "LHAResourceGroupTable.h" #include "hbagent.h" static GPtrArray * gResourceGroupInfo = NULL; extern const int snmp_cache_time_out; int LHAResourceGroupTable_load(netsnmp_cache *cache, void *vmagic); void LHAResourceGroupTable_free(netsnmp_cache *cache, void *vmagic); /** Initialize the LHAResourceGroupTable table by defining its contents and how it's structured */ void initialize_table_LHAResourceGroupTable(void) { static oid LHAResourceGroupTable_oid[] = {1,3,6,1,4,1,4682,4}; netsnmp_table_registration_info *table_info; netsnmp_handler_registration *my_handler; netsnmp_iterator_info *iinfo; /** create the table registration information structures */ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); /** if your table is read only, it's easiest to change the HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */ my_handler = netsnmp_create_handler_registration("LHAResourceGroupTable", LHAResourceGroupTable_handler, LHAResourceGroupTable_oid, OID_LENGTH(LHAResourceGroupTable_oid), HANDLER_CAN_RONLY); if (!my_handler || !table_info || !iinfo) { snmp_log(LOG_ERR, "malloc failed in initialize_table_LHAResourceGroupTable"); SNMP_FREE(iinfo); SNMP_FREE(table_info); return; /* Serious error. */ } /*************************************************** * Setting up the table's definition */ netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: LHAResourceGroupIndex */ 0); /** Define the minimum and maximum accessible columns. This optimizes retrival. */ table_info->min_column = 2; table_info->max_column = 4; /* iterator access routines */ iinfo->get_first_data_point = LHAResourceGroupTable_get_first_data_point; iinfo->get_next_data_point = LHAResourceGroupTable_get_next_data_point; /** you may wish to set these as well */ #ifdef MAYBE_USE_THESE iinfo->make_data_context = LHAResourceGroupTable_context_convert_function; iinfo->free_data_context = LHAResourceGroupTable_data_free; /** pick *only* one of these if you use them */ iinfo->free_loop_context = LHAResourceGroupTable_loop_free; iinfo->free_loop_context_at_end = LHAResourceGroupTable_loop_free; #endif /** tie the two structures together */ iinfo->table_reginfo = table_info; /*************************************************** * registering the table with the master agent */ DEBUGMSGTL(("initialize_table_LHAResourceGroupTable", "Registering table LHAResourceGroupTable as a table iterator\n")); netsnmp_register_table_iterator(my_handler, iinfo); /* * .... with a local cache */ netsnmp_inject_handler(my_handler, netsnmp_get_cache_handler(snmp_cache_time_out, LHAResourceGroupTable_load, LHAResourceGroupTable_free, LHAResourceGroupTable_oid, OID_LENGTH(LHAResourceGroupTable_oid))); } /** Initializes the LHAResourceGroupTable module */ void init_LHAResourceGroupTable(void) { /** here we initialize all the tables we're planning on supporting */ initialize_table_LHAResourceGroupTable(); } /** returns the first data point within the LHAResourceGroupTable table data. Set the my_loop_context variable to the first data point structure of your choice (from which you can find the next one). This could be anything from the first node in a linked list, to an integer pointer containing the beginning of an array variable. Set the my_data_context variable to something to be returned to you later (in your main LHAResourceGroupTable_handler routine) that will provide you with the data to return in a given row. This could be the same pointer as what my_loop_context is set to, or something different. The put_index_data variable contains a list of snmp variable bindings, one for each index in your table. Set the values of each appropriately according to the data matching the first row and return the put_index_data variable at the end of the function. */ netsnmp_variable_list * LHAResourceGroupTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { if (gResourceGroupInfo && gResourceGroupInfo->len == 0) return NULL; *my_loop_context = NULL; return LHAResourceGroupTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } /** functionally the same as LHAResourceGroupTable_get_first_data_point, but my_loop_context has already been set to a previous value and should be updated to the next in the list. For example, if it was a linked list, you might want to cast it to your local data type and then return my_loop_context->next. The my_data_context pointer should be set to something you need later (in your main LHAResourceGroupTable_handler routine) and the indexes in put_index_data updated again. */ netsnmp_variable_list * LHAResourceGroupTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { static size_t i = 0; netsnmp_variable_list *vptr; struct hb_rsinfo * info; uint32_t status; if (*my_loop_context != NULL) { i = *((size_t *) *my_loop_context); } else { i = 0; } if (!gResourceGroupInfo || i >= gResourceGroupInfo->len) return NULL; vptr = put_index_data; info = (struct hb_rsinfo *) g_ptr_array_index(gResourceGroupInfo, i); rsinfo_get_int_value(RESOURCE_STATUS, i, (unsigned int *)&status); info->status = status; snmp_set_var_value(vptr, (u_char *) &info->id, sizeof(size_t)); vptr = vptr->next_variable; i++; *my_loop_context = (void *) &i; *my_data_context = (void *) info; return put_index_data; } /** handles requests for the LHAResourceGroupTable table, if anything else needs to be done */ int LHAResourceGroupTable_handler( netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; netsnmp_variable_list *var; struct hb_rsinfo * entry; for(request = requests; request; request = request->next) { var = request->requestvb; if (request->processed != 0) continue; /** perform anything here that you need to do before each request is processed. */ /** the following extracts the my_data_context pointer set in the loop functions above. You can then use the results to help return data for the columns of the LHAResourceGroupTable table in question */ entry = (struct hb_rsinfo *) netsnmp_extract_iterator_context(request); if (entry == NULL) { if (reqinfo->mode == MODE_GET) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } /** XXX: no row existed, if you support creation and this is a set, start dealing with it here, else continue */ } /** extracts the information about the table from the request */ table_info = netsnmp_extract_table_info(request); /** table_info->colnum contains the column number requested */ /** table_info->indexes contains a linked list of snmp variable bindings for the indexes of the table. Values in the list have been set corresponding to the indexes of the request */ if (table_info==NULL) { continue; } switch(reqinfo->mode) { /** the table_iterator helper should change all GETNEXTs into GETs for you automatically, so you don't have to worry about the GETNEXT case. Only GETs and SETs need to be dealt with here */ case MODE_GET: switch(table_info->colnum) { case COLUMN_LHARESOURCEGROUPMASTER: snmp_set_var_typed_value(var, ASN_INTEGER, (u_char *) & entry->masternodeid, sizeof(entry->masternodeid)); break; case COLUMN_LHARESOURCEGROUPRESOURCES: snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *) entry->resource, strlen(entry->resource) + 1); break; case COLUMN_LHARESOURCEGROUPSTATUS: snmp_set_var_typed_value(var, ASN_UNSIGNED, (u_char *) & entry->status, sizeof(entry->status)); break; default: /** We shouldn't get here */ snmp_log(LOG_ERR, "problem encountered in LHAResourceGroupTable_handler: unknown column\n"); } break; case MODE_SET_RESERVE1: /** set handling... */ default: snmp_log(LOG_ERR, "problem encountered in LHAResourceGroupTable_handler: unsupported mode\n"); } } return SNMP_ERR_NOERROR; } int LHAResourceGroupTable_load(netsnmp_cache *cache, void *vmagic) { LHAResourceGroupTable_free(cache, vmagic); gResourceGroupInfo = get_hb_info(LHA_RESOURCEINFO); return 0; } void LHAResourceGroupTable_free(netsnmp_cache *cache, void *vmagic) { return; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAResourceGroupTable.h000066400000000000000000000013231211477743100264230ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.iterate.conf,v 5.9 2003/06/04 00:14:41 hardaker Exp $ */ #ifndef LHARESOURCEGROUPTABLE_H #define LHARESOURCEGROUPTABLE_H /* function declarations */ void init_LHAResourceGroupTable(void); void initialize_table_LHAResourceGroupTable(void); Netsnmp_Node_Handler LHAResourceGroupTable_handler; Netsnmp_First_Data_Point LHAResourceGroupTable_get_first_data_point; Netsnmp_Next_Data_Point LHAResourceGroupTable_get_next_data_point; /* column number definitions for table LHAResourceGroupTable */ #include "LHAResourceGroupTable_columns.h" /* enum definions */ #include "LHAResourceGroupTable_enums.h" #endif /* LHARESOURCEGROUPTABLE_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAResourceGroupTable_columns.h000066400000000000000000000010141211477743100301600ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.column_defines.conf,v 5.1 2002/05/08 05:42:47 hardaker Exp $ */ #ifndef LHARESOURCEGROUPTABLE_COLUMNS_H #define LHARESOURCEGROUPTABLE_COLUMNS_H /* column number definitions for table LHAResourceGroupTable */ #define COLUMN_LHARESOURCEGROUPINDEX 1 #define COLUMN_LHARESOURCEGROUPMASTER 2 #define COLUMN_LHARESOURCEGROUPRESOURCES 3 #define COLUMN_LHARESOURCEGROUPSTATUS 4 #endif /* LHARESOURCEGROUPTABLE_COLUMNS_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAResourceGroupTable_enums.h000066400000000000000000000004021211477743100276270ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.column_enums.conf,v 5.2 2003/02/22 04:09:25 hardaker Exp $ */ #ifndef LHARESOURCEGROUPTABLE_ENUMS_H #define LHARESOURCEGROUPTABLE_ENUMS_H #endif /* LHARESOURCEGROUPTABLE_ENUMS_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAResourceStatusUpdate.c000066400000000000000000000060061211477743100270030ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.notify.conf,v 5.2.2.1 2004/04/15 12:29:06 dts12 Exp $ */ #include #include "hbagent.h" #include "hbagentv2.h" #include #include #include #include "LHAResourceStatusUpdate.h" static oid snmptrap_oid[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 }; int send_LHAResourceStatusUpdate_trap(struct hb_rsinfov2 *resource) { netsnmp_variable_list *var_list = NULL; oid LHAResourceStatusUpdate_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 900, 11 }; oid LHAResourceName_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 8, 1, 2, /* insert index here */ }; oid LHAResourceNode_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 8, 1, 4, /* insert index here */ }; oid LHAResourceStatus_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 8, 1, 5, /* insert index here */ }; /* * Set the snmpTrapOid.0 value */ snmp_varlist_add_variable(&var_list, snmptrap_oid, OID_LENGTH(snmptrap_oid), ASN_OBJECT_ID, (u_char *)LHAResourceStatusUpdate_oid, sizeof(LHAResourceStatusUpdate_oid)); /* * Add any objects from the trap definition */ snmp_varlist_add_variable(&var_list, LHAResourceName_oid, OID_LENGTH(LHAResourceName_oid), ASN_OCTET_STR, /* * Set an appropriate value for LHAResourceName */ (u_char *)resource->resourceid, strlen(resource->resourceid)); snmp_varlist_add_variable(&var_list, LHAResourceNode_oid, OID_LENGTH(LHAResourceNode_oid), ASN_OCTET_STR, /* * Set an appropriate value for LHAResourceNode */ (u_char *)resource->node, strlen(resource->node)); snmp_varlist_add_variable(&var_list, LHAResourceStatus_oid, OID_LENGTH(LHAResourceStatus_oid), ASN_INTEGER, /* * Set an appropriate value for LHAResourceStatus */ (u_char *)&(resource->status), sizeof(resource->status)); /* * Add any extra (optional) objects here */ /* * Send the trap to the list of configured destinations * and clean up */ send_v2trap(var_list); snmp_free_varbind(var_list); return SNMP_ERR_NOERROR; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAResourceStatusUpdate.h000066400000000000000000000006041211477743100270060ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.notify.conf,v 5.2.2.1 2004/04/15 12:29:06 dts12 Exp $ */ #ifndef LHARESOURCESTATUSUPDATE_H #define LHARESOURCESTATUSUPDATE_H /* * function declarations */ int send_LHAResourceStatusUpdate_trap(struct hb_rsinfov2 *resource); #endif /* LHARESOURCESTATUSUPDATE_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAResourceTable.c000066400000000000000000000304061211477743100254050ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.iterate.conf,v 5.9 2003/06/04 00:14:41 hardaker Exp $ */ #include #include #include #include #include "LHAResourceTable.h" #include "hbagent.h" #include "hbagentv2.h" #if SUPPORT_HEARTBEAT #include "hb_api.h" #endif /*#include "heartbeat.h"*/ /*#include "clplumbing/cl_log.h"*/ static GPtrArray * gResourceTableV2 = NULL; extern const int snmp_cache_time_out; static int LHAResourceTable_load(netsnmp_cache *cache, void *vmagic); static void LHAResourceTable_free(netsnmp_cache *cache, void *vmagic); /** Initialize the LHAResourceTable table by defining its contents and how it's structured */ void initialize_table_LHAResourceTable(void) { static oid LHAResourceTable_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 8 }; netsnmp_table_registration_info *table_info; netsnmp_handler_registration *my_handler; netsnmp_iterator_info *iinfo; /** create the table registration information structures */ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); /** if your table is read only, it's easiest to change the HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */ my_handler = netsnmp_create_handler_registration("LHAResourceTable", LHAResourceTable_handler, LHAResourceTable_oid, OID_LENGTH (LHAResourceTable_oid), HANDLER_CAN_RONLY); if (!my_handler || !table_info || !iinfo) { snmp_log(LOG_ERR, "malloc failed in initialize_table_LHAResourceTable"); SNMP_FREE(iinfo); SNMP_FREE(table_info); return; /* Serious error. */ } /*************************************************** * Setting up the table's definition */ netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: LHAResourceIndex */ 0); /** Define the minimum and maximum accessible columns. This optimizes retrival. */ table_info->min_column = 2; table_info->max_column = 8; /* * iterator access routines */ iinfo->get_first_data_point = LHAResourceTable_get_first_data_point; iinfo->get_next_data_point = LHAResourceTable_get_next_data_point; /** you may wish to set these as well */ #ifdef MAYBE_USE_THESE iinfo->make_data_context = LHAResourceTable_context_convert_function; iinfo->free_data_context = LHAResourceTable_data_free; /** pick *only* one of these if you use them */ iinfo->free_loop_context = LHAResourceTable_loop_free; iinfo->free_loop_context_at_end = LHAResourceTable_loop_free; #endif /** tie the two structures together */ iinfo->table_reginfo = table_info; /*************************************************** * registering the table with the master agent */ DEBUGMSGTL(("initialize_table_LHAResourceTable", "Registering table LHAResourceTable as a table iterator\n")); netsnmp_register_table_iterator(my_handler, iinfo); /* * enable local cache */ netsnmp_inject_handler(my_handler, netsnmp_get_cache_handler(snmp_cache_time_out, LHAResourceTable_load, LHAResourceTable_free, LHAResourceTable_oid, OID_LENGTH (LHAResourceTable_oid))); snmp_log(LOG_INFO, "LHAResourceTable initialization completed.\n"); } /** Initializes the LHAResourceTable module */ void init_LHAResourceTable(void) { /** here we initialize all the tables we're planning on supporting */ initialize_table_LHAResourceTable(); } /** returns the first data point within the LHAResourceTable table data. Set the my_loop_context variable to the first data point structure of your choice (from which you can find the next one). This could be anything from the first node in a linked list, to an integer pointer containing the beginning of an array variable. Set the my_data_context variable to something to be returned to you later (in your main LHAResourceTable_handler routine) that will provide you with the data to return in a given row. This could be the same pointer as what my_loop_context is set to, or something different. The put_index_data variable contains a list of snmp variable bindings, one for each index in your table. Set the values of each appropriately according to the data matching the first row and return the put_index_data variable at the end of the function. */ netsnmp_variable_list * LHAResourceTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list * put_index_data, netsnmp_iterator_info *mydata) { if (gResourceTableV2 && gResourceTableV2->len == 0) { return NULL; } *my_loop_context = NULL; return LHAResourceTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata); } /** functionally the same as LHAResourceTable_get_first_data_point, but my_loop_context has already been set to a previous value and should be updated to the next in the list. For example, if it was a linked list, you might want to cast it to your local data type and then return my_loop_context->next. The my_data_context pointer should be set to something you need later (in your main LHAResourceTable_handler routine) and the indexes in put_index_data updated again. */ netsnmp_variable_list * LHAResourceTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list * put_index_data, netsnmp_iterator_info *mydata) { static size_t i = 0; netsnmp_variable_list *vptr; struct hb_rsinfov2 *info; if (*my_loop_context != NULL) { i = *((size_t *) *my_loop_context); } else { i = 0; } if (!gResourceTableV2 || i >= gResourceTableV2->len) { return NULL; } vptr = put_index_data; info = (struct hb_rsinfov2 *)g_ptr_array_index(gResourceTableV2, i); snmp_set_var_value(vptr, (u_char *)&info->index, sizeof(size_t)); vptr = vptr->next_variable; i++; *my_loop_context = (void *)&i; *my_data_context = (void *)info; return put_index_data; } /** handles requests for the LHAResourceTable table, if anything else needs to be done */ int LHAResourceTable_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; netsnmp_variable_list *var; struct hb_rsinfov2 *entry; for (request = requests; request; request = request->next) { var = request->requestvb; if (request->processed != 0) continue; /** perform anything here that you need to do before each request is processed. */ /** the following extracts the my_data_context pointer set in the loop functions above. You can then use the results to help return data for the columns of the LHAResourceTable table in question */ entry = (struct hb_rsinfov2 *)netsnmp_extract_iterator_context(request); if (entry == NULL) { if (reqinfo->mode == MODE_GET) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } /** XXX: no row existed, if you support creation and this is a set, start dealing with it here, else continue */ } /** extracts the information about the table from the request */ table_info = netsnmp_extract_table_info(request); /** table_info->colnum contains the column number requested */ /** table_info->indexes contains a linked list of snmp variable bindings for the indexes of the table. Values in the list have been set corresponding to the indexes of the request */ if (table_info == NULL) { continue; } switch (reqinfo->mode) { /** the table_iterator helper should change all GETNEXTs into GETs for you automatically, so you don't have to worry about the GETNEXT case. Only GETs and SETs need to be dealt with here */ case MODE_GET: switch (table_info->colnum) { case COLUMN_LHARESOURCENAME: snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *)entry->resourceid, strlen(entry->resourceid) + 1 ); break; case COLUMN_LHARESOURCETYPE: snmp_set_var_typed_value(var, ASN_INTEGER, (u_char *)&entry->type, sizeof(entry->type) ); break; case COLUMN_LHARESOURCESTATUS: snmp_set_var_typed_value(var, ASN_INTEGER, (u_char *)&entry->status, sizeof(entry->status) ); break; case COLUMN_LHARESOURCENODE: snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *)entry->node, strlen(entry->node) + 1 ); break; case COLUMN_LHARESOURCEISMANAGED: snmp_set_var_typed_value(var, ASN_INTEGER, (u_char *)&entry->is_managed, sizeof(entry->is_managed) ); break; case COLUMN_LHARESOURCEFAILCOUNT: snmp_set_var_typed_value(var, ASN_INTEGER, (u_char *)&entry->failcount, sizeof(entry->failcount) ); break; case COLUMN_LHARESOURCEPARENT: snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *)entry->parent, strlen(entry->parent) + 1 ); break; default: /** We shouldn't get here */ snmp_log(LOG_ERR, "problem encountered in LHAResourceTable_handler: unknown column\n"); } break; case MODE_SET_RESERVE1: /** set handling... */ default: snmp_log(LOG_ERR, "problem encountered in LHAResourceTable_handler: unsupported mode\n"); } } return SNMP_ERR_NOERROR; } static int LHAResourceTable_load(netsnmp_cache *cache, void *vmagic) { LHAResourceTable_free(cache, vmagic); gResourceTableV2 = get_resource_table_v2(); return 0; } static void LHAResourceTable_free(netsnmp_cache *cache, void *vmagic) { /* do nothing. */ return; } /** * Emacs stuff: * Local Variables: * mode: C * c-basic-offset: 4 * indent-tabs-mode: nil * End: * */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAResourceTable.h000066400000000000000000000013271211477743100254120ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.iterate.conf,v 5.9 2003/06/04 00:14:41 hardaker Exp $ */ #ifndef LHARESOURCETABLE_H #define LHARESOURCETABLE_H /* * function declarations */ void init_LHAResourceTable(void); void initialize_table_LHAResourceTable(void); Netsnmp_Node_Handler LHAResourceTable_handler; Netsnmp_First_Data_Point LHAResourceTable_get_first_data_point; Netsnmp_Next_Data_Point LHAResourceTable_get_next_data_point; /* * column number definitions for table LHAResourceTable */ #include "LHAResourceTable_columns.h" /* * enum definions */ #include "LHAResourceTable_enums.h" #endif /* LHARESOURCETABLE_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAResourceTable_columns.h000066400000000000000000000012211211477743100271430ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.column_defines.conf,v 5.1 2002/05/08 05:42:47 hardaker Exp $ */ #ifndef LHARESOURCETABLE_COLUMNS_H #define LHARESOURCETABLE_COLUMNS_H /* * column number definitions for table LHAResourceTable */ #define COLUMN_LHARESOURCEINDEX 1 #define COLUMN_LHARESOURCENAME 2 #define COLUMN_LHARESOURCETYPE 3 #define COLUMN_LHARESOURCENODE 4 #define COLUMN_LHARESOURCESTATUS 5 #define COLUMN_LHARESOURCEISMANAGED 6 #define COLUMN_LHARESOURCEFAILCOUNT 7 #define COLUMN_LHARESOURCEPARENT 8 #endif /* LHARESOURCETABLE_COLUMNS_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LHAResourceTable_enums.h000066400000000000000000000015501211477743100266170ustar00rootroot00000000000000/* * Note: this file originally auto-generated by mib2c using * : mib2c.column_enums.conf,v 5.2 2003/02/22 04:09:25 hardaker Exp $ */ #ifndef LHARESOURCETABLE_ENUMS_H #define LHARESOURCETABLE_ENUMS_H /* * enums for column LHAResourceType */ #define LHARESOURCETYPE_UNKNOWN 0 #define LHARESOURCETYPE_PRIMITIVE 1 #define LHARESOURCETYPE_GROUP 2 #define LHARESOURCETYPE_CLONE 3 #define LHARESOURCETYPE_MASTERSLAVE 4 /* * enums for column LHAResourceStatus */ #define LHARESOURCESTATUS_UNKNOWN 0 #define LHARESOURCESTATUS_STOPPED 1 #define LHARESOURCESTATUS_STARTED 2 #define LHARESOURCESTATUS_SLAVE 3 #define LHARESOURCESTATUS_MASTER 4 /* * enums for column LHAResourceIsManaged */ #define LHARESOURCEISMANAGED_UNMANAGED 0 #define LHARESOURCEISMANAGED_MANAGED 1 #endif /* LHARESOURCETABLE_ENUMS_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/LINUX-HA-MIB.txt000066400000000000000000000445301211477743100245130ustar00rootroot00000000000000-- Linux-HA: SNMP Subagent -- -- Copyright (C) 2002 Yixiong Zou (yixiong.zou@intel.com) -- -- This program is free software; you can redistribute it and/or -- modify it under the terms of the GNU General Public License -- as published by the Free Software Foundation; either version 2 -- of the License, or (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -- LINUX-HA-MIB DEFINITIONS ::= BEGIN IMPORTS MODULE-IDENTITY, OBJECT-TYPE, enterprises, Counter32, INTEGER, Integer32, Unsigned32, IpAddress FROM SNMPv2-SMI TEXTUAL-CONVENTION, DisplayString, TimeStamp, TruthValue, DateAndTime FROM SNMPv2-TC MODULE-COMPLIANCE, OBJECT-GROUP FROM SNMPv2-CONF; LinuxHA MODULE-IDENTITY LAST-UPDATED "200711260000Z" -- Nov. 26, 2007 ORGANIZATION "High-Availability Linux Project" CONTACT-INFO "Alan Robertson Postal: Linux-HA Project 13750 Bayberry Drive Broomfield, CO 80020-6163 Phone: 303-466-7405 FAX: n/a Email: alanr@unix.sh Yixiong Zou Postal: Intel Corp. CO5-162 15400 NW Greenbrier Parkway Beaverton, OR 97006 USA Phone: 503-677-4988 Fax: 503-677-6670 Email: yixiong.zou@intel.com In addition, the Linux-HA mailing list is where all the discussion about this MIB happens. To join the mailing list, send a request message to linux-ha-subscribe@muc.de. The mailing list address is linux-ha-dev@lists.community.tummy.com." DESCRIPTION "This MIB can be used to manage a Linux-HA cluster. The initial plan is to make the heartbeat, resource managment, and memberships accessible through SNMP. Hopefully more things can be added as Linux-HA matures." REVISION "200711260000Z" -- Nov. 26, 2007 DESCRIPTION "The original version of this MIB." ::= { enterprises 4682 } -- Current LinuxHA core MIB entries -- LHAClusterInfo OBJECT IDENTIFIER ::= { LinuxHA 1 } -- LHANodeTable OBJECT IDENTIFIER ::= { LinuxHA 2 } -- LHAIFStatusTable OBJECT IDENTIFIER ::= { LinuxHA 3 } -- LHAResourceGroupTable OBJECT IDENTIFIER ::= { LinuxHA 4 } -- LHAMembershipTable OBJECT IDENTIFIER ::= { LinuxHA 6 } -- LHAHeartbeatConfigInfo OBJECT IDENTIFIER ::= { LinuxHA 7 } -- LHAResourceTable OBJECT IDENTIFIER ::= { LinuxHA 8 } -- LHATrapTable OBJECT IDENTIFIER ::= { LinuxHA 900 } LHAUUIDString ::= TEXTUAL-CONVENTION DISPLAY-HINT "4x-2x-2x-2x-4x2x" STATUS current DESCRIPTION "A string that represents a UUID" SYNTAX OCTET STRING (SIZE (16)) LHAClusterInfo OBJECT IDENTIFIER ::= { LinuxHA 1 } LHATotalNodeCount OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The number of nodes that are currently configured for this cluster." ::= { LHAClusterInfo 1 } LHALiveNodeCount OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The number of nodes that are currently active in this cluster." ::= { LHAClusterInfo 2 } LHACurrentNodeID OBJECT-TYPE SYNTAX Integer32 MAX-ACCESS read-only STATUS current DESCRIPTION "The nodes id of the host that this agent currently represents. This value is the same as the LHANodeIndex value of this node." ::= { LHAClusterInfo 3 } LHAResourceGroupCount OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The total number of Resource Groups that have been configured for this cluster." ::= { LHAClusterInfo 4 } LHANodeTable OBJECT-TYPE SYNTAX SEQUENCE OF lhaNodeEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A table contains information about all the nodes in the cluster." ::= { LinuxHA 2 } LHANodeEntry OBJECT-TYPE SYNTAX lhaNodeEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry containing a node and its statistics." INDEX { LHANodeIndex } ::= { LHANodeTable 1 } lhaNodeEntry ::= SEQUENCE { LHANodeIndex Integer32, LHANodeName DisplayString, LHANodeType INTEGER, LHANodeStatus INTEGER, LHANodeUUID DisplayString, LHANodeIFCount Counter32, } LHANodeIndex OBJECT-TYPE SYNTAX Integer32 (0..65535) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An integer that identifies a node in a cluster for a given snmp session." ::= { LHANodeEntry 1 } LHANodeName OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "A human readable name that represents that node." ::= { LHANodeEntry 2 } LHANodeType OBJECT-TYPE SYNTAX INTEGER { unknown (0), normal (1), ping (2) } MAX-ACCESS read-only STATUS current DESCRIPTION "There could be many types of nodes in the cluster. For example, a node could be a normal node, or a ping node depending on the configuration. This object shows the type of this node as an integer. So far only the normal node and ping node are defined. All the rest will fall into the 'unknown' catagory. " ::= { LHANodeEntry 3 } LHANodeStatus OBJECT-TYPE SYNTAX INTEGER { unknown (0), init (1), up (2), active (3), dead (4) } MAX-ACCESS read-only STATUS current DESCRIPTION "The status of the node as an integer. For heartbeat, this would normally be init, up, active, or dead. So far, only these four states are defined. All the rest falls in 'unknown' catagory." ::= { LHANodeEntry 4 } LHANodeUUID OBJECT-TYPE SYNTAX LHAUUIDString MAX-ACCESS read-only STATUS current DESCRIPTION "The UUID of the current node in string representatio. This UUID will be persisted over the heartbeat session. So it can be used as a unique identifier for a node." ::= { LHANodeEntry 5 } LHANodeIFCount OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The number of interfaces that is used by heartbeat for this node." ::= { LHANodeEntry 6 } LHAIFStatusTable OBJECT-TYPE SYNTAX SEQUENCE OF lhaIFEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A table describes all the interfaces that are used by the heartbeat cluster." ::= { LinuxHA 3 } LHAIFStatusEntry OBJECT-TYPE SYNTAX lhaIFStatusEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry containing information about that interface. The LHANodeIndex is listed in the LHANodeTable." INDEX { LHANodeIndex, LHAIFIndex } ::= { LHAIFStatusTable 1 } lhaIFStatusEntry ::= SEQUENCE { LHAIFIndex Integer32, LHAIFName DisplayString, LHAIFStatus INTEGER } LHAIFIndex OBJECT-TYPE SYNTAX Integer32 (0..65535) MAX-ACCESS not-accessible STATUS current DESCRIPTION "An unique integer identifies this interface." ::= { LHAIFStatusEntry 1 } LHAIFName OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "A name for this interface." ::= { LHAIFStatusEntry 2 } LHAIFStatus OBJECT-TYPE SYNTAX INTEGER { unknown (0), up (1), down (2) } MAX-ACCESS read-only STATUS current DESCRIPTION "The status for this interface as an integer. Currently only up and down are defined as the interface status. All the others will fall into the unknown catagory." ::= { LHAIFStatusEntry 3 } LHAResourceGroupTable OBJECT-TYPE SYNTAX SEQUENCE OF lhaResourceGroupEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A table containing information of all the resource groups." ::= { LinuxHA 4 } LHAResourceGroupEntry OBJECT-TYPE SYNTAX lhaResourceGroupEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry that describes the resource group and its information." INDEX { LHAResourceGroupIndex } ::= { LHAResourceGroupTable 1 } lhaResourceGroupEntry ::= SEQUENCE { LHAResourceGroupIndex Integer32, LHAResourceGroupMaster DisplayString, LHAResourceGroupResources DisplayString, LHAResourceGroupStatus Integer32 } LHAResourceGroupIndex OBJECT-TYPE SYNTAX Integer32 (0..65535) MAX-ACCESS not-accessible STATUS current DESCRIPTION "A unique integer that identifies this resource group." ::= { LHAResourceGroupEntry 1 } LHAResourceGroupMaster OBJECT-TYPE SYNTAX Integer32 (0..65535) MAX-ACCESS read-only STATUS current DESCRIPTION "The master node id of this resource group. This is the LHANodeIndex for the master node of this resource group. " ::= { LHAResourceGroupEntry 2 } LHAResourceGroupResources OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "The resources contained in this resource group." ::= { LHAResourceGroupEntry 3 } LHAResourceGroupStatus OBJECT-TYPE SYNTAX Unsigned32 (0..255) MAX-ACCESS read-only STATUS current DESCRIPTION "The status of this resource group. 0 program is running 1 program is dead and /var/run pid file exists 2 program is dead and /var/lock lock file exists 3 program is stopped 4-100 reserved for future LSB use 100-149 reserved for distribution use 150-199 reserved for application use 200-254 reserved " ::= { LHAResourceGroupEntry 4 } LHAMembershipTable OBJECT-TYPE SYNTAX SEQUENCE OF lhaMembershipEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A table containing membership information for the cluster. A successful membership has to have qurom. NOTE WELL If this table does not contain any entries, that means the node is not part of the cluster membership." ::= { LinuxHA 6 } LHAMembershipEntry OBJECT-TYPE SYNTAX lhaMembershipEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry containing a member and its status." INDEX { LHAMemberIndex } ::= { LHAMembershipTable 1 } lhaMembershipEntry ::= SEQUENCE { LHAMemberIndex Integer32, LHAMemberName DisplayString, LHAMemberAddress DisplayString, LHAMemberClusterName DisplayString, LHAMemberIsMember TruthValue, LHAMemberLastChange INTEGER, LHAMemberBootTime TimeStamp, } LHAMemberIndex OBJECT-TYPE SYNTAX Integer32 (0..65535) MAX-ACCESS not-accessible STATUS current DESCRIPTION "A unique integer that identifies this member." ::= { LHAMembershipEntry 1 } LHAMemberName OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "The name of the cluster member." ::= { LHAMembershipEntry 2 } LHAMemberAddress OBJECT-TYPE SYNTAX OCTET STRING (SIZE (64)) MAX-ACCESS read-only STATUS current DESCRIPTION "The address of the cluster member." ::= { LHAMembershipEntry 3 } LHAMemberClusterName OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "The name of this cluster." ::= { LHAMembershipEntry 4 } LHAMemberIsMember OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-only STATUS current DESCRIPTION "If this node is part of the membership or not." ::= { LHAMembershipEntry 5 } LHAMemberLastChange OBJECT-TYPE SYNTAX INTEGER { undefined (0), nochange (1), joined (2), left (3) } MAX-ACCESS read-only STATUS current DESCRIPTION "If this node is part of the membership or not." ::= { LHAMembershipEntry 6 } LHAMemberBootTime OBJECT-TYPE SYNTAX TimeStamp MAX-ACCESS read-only STATUS current DESCRIPTION "The time when this cluster member last started." ::= { LHAMembershipEntry 7 } LHAHeartbeatConfigInfo OBJECT IDENTIFIER ::= { LinuxHA 7 } LHAHBVersion OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "The heartbeat version." ::= { LHAHeartbeatConfigInfo 1 } LHAKeepAlive OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "The heartbeat interval." ::= { LHAHeartbeatConfigInfo 3 } LHADeadTime OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "The time it waits before declaring a node to be dead." ::= { LHAHeartbeatConfigInfo 4 } LHADeadPing OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "The time it waits before declaring a ping node to be dead." ::= { LHAHeartbeatConfigInfo 5 } LHAWarnTime OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "The time it waits before issuing a 'late heartbeat' warning." ::= { LHAHeartbeatConfigInfo 6 } LHAInitDead OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "Very first dead time. Should be twice the normal dead time." ::= { LHAHeartbeatConfigInfo 7 } LHABaudRate OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "Baud rate for serial ports." ::= { LHAHeartbeatConfigInfo 9 } LHAAutoFailBack OBJECT-TYPE SYNTAX INTEGER { undefined (0), on (1), off (2), legacy (3), } MAX-ACCESS read-only STATUS current DESCRIPTION "Determins whether a resource will automatically fail back to its primary node, or remain on whatever the node is serving. Possible values are: on, off, legacy." ::= { LHAHeartbeatConfigInfo 12 } LHAStonith OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "The STONITH device configured for this cluster." ::= { LHAHeartbeatConfigInfo 13 } LHAStonithHost OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "The STONITH host configured for this cluster." ::= { LHAHeartbeatConfigInfo 14 } LHARespawn OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "The other services that got respawned by heartbeat daemon." ::= { LHAHeartbeatConfigInfo 15 } LHAResourceTable OBJECT-TYPE SYNTAX SEQUENCE OF lhaResourceEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "A table containing information of all the resource for V2." ::= { LinuxHA 8 } LHAResourceEntry OBJECT-TYPE SYNTAX lhaResourceEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry that describes the resource and its status for V2." INDEX { LHAResourceIndex } ::= { LHAResourceTable 1 } lhaResourceEntry ::= SEQUENCE { LHAResourceIndex Integer32, LHAResourceName DisplayString, LHAResourceType INTEGER, LHAResourceNode DisplayString, LHAResourceStatus INTEGER, LHAResourceIsManaged INTEGER, LHAResourceFailCount Integer32, LHAResourceParent DisplayString, } LHAResourceIndex OBJECT-TYPE SYNTAX Integer32 (0..65535) MAX-ACCESS not-accessible STATUS current DESCRIPTION "A unique integer that identifies this resource." ::= { LHAResourceEntry 1 } LHAResourceName OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "The name of this resource." ::= { LHAResourceEntry 2 } LHAResourceType OBJECT-TYPE SYNTAX INTEGER { unknown (0), primitive (1), group (2), clone (3), masterSlave (4) } MAX-ACCESS read-only STATUS current DESCRIPTION "The type of this resource. 0 unknown type 1 primitive resource. 2 group resource. 3 clone resource. 4 master/slave resource. " ::= { LHAResourceEntry 3 } LHAResourceNode OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "The node name that this resource resides on." ::= { LHAResourceEntry 4 } LHAResourceStatus OBJECT-TYPE SYNTAX INTEGER { unknown (0), stopped (1), started (2), slave (3), master (4) } MAX-ACCESS read-only STATUS current DESCRIPTION "The status of this resource. 0 unknown status 1 program is stopped. 2 program is started. 3 program is started in slave state. 4 program is started in master state. " ::= { LHAResourceEntry 5 } LHAResourceIsManaged OBJECT-TYPE SYNTAX INTEGER { unmanaged (0), managed (1) } MAX-ACCESS read-only STATUS current DESCRIPTION "The status of this resource. 0 resource is not managed. 1 resource is managed. " ::= { LHAResourceEntry 6 } LHAResourceFailCount OBJECT-TYPE SYNTAX Integer32 (0..65535) MAX-ACCESS read-only STATUS current DESCRIPTION "The value of this resource's fail-count." ::= { LHAResourceEntry 7 } LHAResourceParent OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only STATUS current DESCRIPTION "The name of this resource's parent resource." ::= { LHAResourceEntry 8 } LHATrapTable OBJECT IDENTIFIER ::= { LinuxHA 900 } LHANodeStatusUpdate NOTIFICATION-TYPE OBJECTS { LHANodeName LHANodeStatus } STATUS current DESCRIPTION "A node status change event just happened." ::= { LHATrapTable 1 } LHAIFStatusUpdate NOTIFICATION-TYPE OBJECTS { LHANodeName LHAIFName LHAIFStatus } STATUS current DESCRIPTION "A link status just changed." ::= { LHATrapTable 3 } LHAMembershipChange NOTIFICATION-TYPE OBJECTS { LHANodeName LHAMemberLastChange } STATUS current DESCRIPTION "A node just changed it membership. " ::= { LHATrapTable 5 } LHAHBAgentOnline NOTIFICATION-TYPE OBJECTS { LHANodeName } STATUS current DESCRIPTION "The heartbeat agent for this node is online and ready to accept queries. " ::= { LHATrapTable 7 } LHAHBAgentOffline NOTIFICATION-TYPE OBJECTS { LHANodeName } STATUS current DESCRIPTION "The heartbeat agent for this node is offline. " ::= { LHATrapTable 9 } LHAResourceStatusUpdate NOTIFICATION-TYPE OBJECTS { LHAResourceName LHAResourceNode LHAResourceStatus } STATUS current DESCRIPTION "A resource status change event just happened." ::= { LHATrapTable 11 } END pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/Makefile.am000066400000000000000000000046771211477743100242240ustar00rootroot00000000000000# Linux-HA: SNMP Subagent # # Copyright (C) 2002 Yixiong Zou (yixiong.zou@intel.com) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in hbagent_srces = snmp-config-resolve.h \ hbagent.h \ hbagent.c \ hbagentv2.h \ hbagentv2.c \ LHANodeTable.h \ LHANodeTable_columns.h \ LHANodeTable_enums.h \ LHANodeTable.c \ LHAClusterInfo.h \ LHAClusterInfo.c \ LHAIFStatusTable.h \ LHAIFStatusTable_enums.h \ LHAIFStatusTable_columns.h \ LHAIFStatusTable.c \ LHAMembershipTable_columns.h \ LHAMembershipTable_enums.h \ LHAMembershipTable.h \ LHAMembershipTable.c \ LHAHeartbeatConfigInfo.c \ LHAHeartbeatConfigInfo.h \ LHAResourceGroupTable_columns.h \ LHAResourceGroupTable_enums.h \ LHAResourceGroupTable.h \ LHAResourceGroupTable.c \ LHAResourceTable_columns.h \ LHAResourceTable_enums.h \ LHAResourceTable.h \ LHAResourceTable.c \ LHAResourceStatusUpdate.h \ LHAResourceStatusUpdate.c test_scrs = SNMPAgentSanityCheck mibsdir = @MIBS_DIR@ mibs_DATA = LINUX-HA-MIB.txt DIST_LIST = SNMPAgentSanityCheck.in $(mibs_DATA) EXTRA_DIST = $(DIST_LIST) docdir = $(datadir)/doc/packages/@PKG_NAME@ doc_DATA = README.hbagent README.hbagentv2 INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_builddir)/libltdl -I$(top_srcdir)/libltdl halibdir = $(libdir)/@HB_PKG@ # binary programs halib_PROGRAMS = hbagent hbagent_SOURCES = $(hbagent_srces) hbagent_LDADD = \ -lplumb -lcrmcommon -lcib -lpe_status \ $(CLUSTERLIBS) $(CURSESLIBS) $(GLIBLIB) if !BUILD_HEARTBEAT_SUPPORT hbagent_LDADD += -lcrmcluster endif hbagent_LDFLAGS = @SNMPAGENTLIB@ # test cases testdir = $(HA_LIBHBDIR) test_SCRIPTS = $(test_scrs) hadir = $(sysconfdir)/ha.d AM_CFLAGS = @CFLAGS@ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/README.hbagent000066400000000000000000000134251211477743100244460ustar00rootroot00000000000000 Linux-HA SNMP Subagent 1. Introduction The SNMP Subagent is based on AgentX protocol. It is implemented using the NET-SNMP api. It exports the Linux-HA cluster information through the SNMP interface so that the cluster can be monitored remotely. Currently, node, link, membership and heartbeat configuration parameters can be viewed through SNMP command. In addition, SNMP traps will be sent for node, link, and membership events. 2. Build Here's how to build the subagent: ./ConfigureMe config --enable-snmp-subagent You must have NET-SNMP library and header installed. On most systems, these are the net-snmp and net-snmp-devel packages. The old UCD-SNMP is no longer supported. As of this writing, the latest NET-SNMP version is 5.1. 3. SNMP daemon Configuration You need to turn on the Agentx support in the SNMP daemon. Also you need to define at least one trap sink in order to receive the traps. Also, the LINUX-HA-MIB.txt file needs to be installed to your default mib location so the SNMP daemon can parse it. This should be taken care of by the 'make install' though. Here's what it normally takes in your snmpd.conf file: # create a SNMPv1/SNMPv2 community rocommunity public # if you want to limit access to a host you can use # rocommunity public xxx.xxx.xxx.xxx/24 # For more complex setups consult the snmpd.conf man page # this makes the snmpd a master snmp agent, which can # support AgentX subagents. master yes # this defines your localhost as the trapsink. so traps # or rather the SNMPv2 informs, will be sent to localhost. trap2sink localhost 4. Test the setup a) (re)start your master SNMP daemon (e.g. net-snmpd) /etc/init.d/snmpd restart b) start the HB agent /usr/lib/heartbeat/hbagent -d c) run snmpwalk (while hbagent is running) snmpwalk -c public -v2c \ -mLINUX-HA-MIB enterprises.4682 (if you get a error message you may have to copy /usr/share/snmp/mibs/LINUX-HA-MIB.txt from one of the cluster machines to your management station to /usr/share/snmp/mibs/) You shoud see a output like the one shown in step (7). d) end the hbagent process (CRTL+C) 5. Make the snmp subagent started by heartbeat # /etc/ha.d/ha.cf #[...] respawn root /usr/lib/heartbeat/hbagent (note: also make sure that the snmp master daemon is startet before heartbeat during system boot) 6. Restart Heartbeat note: Watch out on production systems. Restarting heartbeat without proper handling will cause downtime. hint: You can use is-managed-default=false on heartbeatv2 clusters 7. Demo Output yourshell# snmpwalk -c public -v2c -mLINUX-HA-MIB enterprises.4682 LINUX-HA-MIB::LHATotalNodeCount.0 = Counter32: 2 LINUX-HA-MIB::LHALiveNodeCount.0 = Counter32: 2 LINUX-HA-MIB::LHANodeName.0 = STRING: phantom LINUX-HA-MIB::LHANodeName.1 = STRING: matrix LINUX-HA-MIB::LHANodeType.0 = STRING: normal LINUX-HA-MIB::LHANodeType.1 = STRING: normal LINUX-HA-MIB::LHANodeStatus.0 = STRING: active LINUX-HA-MIB::LHANodeStatus.1 = STRING: active LINUX-HA-MIB::LHAIFStatus."matrix.".0."eth0." = STRING: up LINUX-HA-MIB::LHAIFStatus."phantom.".0."eth0." = STRING: up LINUX-HA-MIB::LHAResourceGroupResources."matrix.".1 = STRING: 192.168.1.112 LINUX-HA-MIB::LHAResourceGroupResources."phantom.".1 = STRING: 192.168.1.111 httpd LINUX-HA-MIB::LHAResourceGroupStatus."matrix.".1 = INTEGER: 0 LINUX-HA-MIB::LHAResourceGroupStatus."phantom.".1 = INTEGER: 3 LINUX-HA-MIB::LHAMemberName.0 = STRING: matrix LINUX-HA-MIB::LHAMemberAddress.0 = STRING: LINUX-HA-MIB::LHAMemberClusterName.0 = STRING: LINUX-HA-MIB::LHAMemberIsMember.0 = INTEGER: true(1) LINUX-HA-MIB::LHAMemberLastChange.0 = INTEGER: nochange(1) LINUX-HA-MIB::LHAMemberBootTime.0 = Timeticks: (0) 0:00:00.00 LINUX-HA-MIB::LHAHBVersion.0 = STRING: 1.3.0.cvs.20040616 LINUX-HA-MIB::LHAHOPFudge.0 = STRING: 1 LINUX-HA-MIB::LHAKeepAlive.0 = STRING: 500ms LINUX-HA-MIB::LHADeadTime.0 = STRING: 30 LINUX-HA-MIB::LHADeadPing.0 = STRING: 30000ms LINUX-HA-MIB::LHAWarnTime.0 = STRING: 10 LINUX-HA-MIB::LHAInitDead.0 = STRING: 120 LINUX-HA-MIB::LHAWatchdogTimer.0 = STRING: N/A LINUX-HA-MIB::LHABaudRate.0 = STRING: 19200 LINUX-HA-MIB::LHAUDPPort.0 = STRING: 694 LINUX-HA-MIB::LHNiceFailBack.0 = STRING: N/A LINUX-HA-MIB::LHAutoFailBack.0 = STRING: on LINUX-HA-MIB::LHAStonith.0 = STRING: N/A LINUX-HA-MIB::LHAStonithHost.0 = STRING: N/A LINUX-HA-MIB::LHARespawn.0 = STRING: N/A LINUX-HA-MIB::LHAGenMethod.0 = STRING: file LINUX-HA-MIB::LHARealTime.0 = STRING: true LINUX-HA-MIB::LHARTPriority.0 = STRING: N/A LINUX-HA-MIB::LHADebugLevel.0 = STRING: 0 LINUX-HA-MIB::LHANormalPoll.0 = STRING: true LINUX-HA-MIB::LHAAPIAuth.0 = STRING: N/A LINUX-HA-MIB::LHAMsgFmt.0 = STRING: classic LINUX-HA-MIB::LHALogFile.0 = STRING: /var/log/ha-log LINUX-HA-MIB::LHADebugFile.0 = STRING: /var/log/ha-debug LINUX-HA-MIB::LHALogFacility.0 = STRING: local0 8. About LHAIFStatus LHAIFStatus shows the status of a heartbeat link, as the "cl_status hblinkstatus " command does. That indicates whether the local node can recieve the heartbeats from "node-name" through "interface-name". Note: If you have set "ucast " as the heartbeat communication in the ha.cf file, the LHAIFStatus of the local node will be shown as "down". Because for this case, the local node isn't meant to send itself any heartbeat traffic. That doesn't affect the cluster membership. You could ignore that. 9. Bugs Please forward all bug report to Linux-HA dev mailing list. pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/README.hbagentv2000066400000000000000000000335241211477743100247200ustar00rootroot00000000000000 SNMP Subagent Extention for CRM Resources 1. Introduction The purpose of this patch is to extend the SNMP subagent to get and receive a trap about the CRM resource information provided by Heartbeat Version 2. This patch introduces two new SNMP MIB objects. 1) LHAResourceTable: resources' name, type, on which node they are running, and their status. On the other words, you can get the information which is provided with crm_mon through the SNMP interface. 2) LHAResourceStatusUpdate: when a resource's status changes, you are notified with this SNMP trap. 2. Added MIB The following is the added MIB at this patch. --------------------------------------------------------------------------- | OID | Object Name | Value type | Description | --------------------------------------------------------------------------- |4682.8 | | LHAResourceTable | table | | --------------------------------------------------------------------------- | |.1 | LHAResourceEntry | | | --------------------------------------------------------------------------- | |.1.1 | LHAResourceIndex | Integer32 | | --------------------------------------------------------------------------- | |.1.2 | LHAResourceName | DisplayString | | --------------------------------------------------------------------------- | |.1.3 | LHAResourceType | INTEGER | unknown(0) | | | | | | primitive(1) | | | | | | group(2) | | | | | | clone(3) | | | | | | masterSlave(4) | --------------------------------------------------------------------------- | |.1.4 | LHAResourceNode | DisplayString | | --------------------------------------------------------------------------- | |.1.5 | LHAResourceStatus | INTEGER | unknown(0) | | | | | | stopped(1) | | | | | | started(2) | | | | | | slave(3) | | | | | | master(4) | --------------------------------------------------------------------------- | |.1.6 | LHAResourceIsManaged | INTEGER | unmanaged(0) | | | | | | managed(1) | --------------------------------------------------------------------------- | |.1.7 | LHAResourceFailcount | Integer32 | | --------------------------------------------------------------------------- | |.1.8 | LHAResourceParent | DisplayString | | --------------------------------------------------------------------------- NOTE : "master" status means "promoted", and "slave" means "demoted". All master/slave resources start up as slave at first, and until they are demoted or promoted explicitly, heartbeat only knows they "started". So, LHAResourceStatus's value is according to the crm_mon output. NOTE : For the present, you can get the information only about *running* resources or the resources that their values of fail-count are larger than 1. Because it's difficult to decide which node a resource *stopped* on... 3. Added Trap The following is the added Trap at this patch. --------------------------------------------------------------------------- | OID | Object Name | Value type | Description | --------------------------------------------------------------------------- |4682.900.8 | LHAResourceStatusUpdate | | | | |------------------------------------------------------------ | | LHAResourceName | DisplayString | | | |------------------------------------------------------------ | | LHAResourceNode | DisplayString | | | |------------------------------------------------------------ | | LHAResourceStatus | INTEGER | 0 : unknown | | | | | 1 : stopped | | | | | 2 : started | | | | | 3 : slave | | | | | 4 : master | --------------------------------------------------------------------------- NOTE : This trap is sent only when the resource operation succeeds. Concretely, the extended hbagent gets the cib information when it changes, and parse it. And if the rc_code of the operation (like CRMD_ACTION_START) is "0", then the hbagent sends a trap. 4. Demo Output [root@u5node1 ~]# snmpwalk -v 1 \ -c public localhost LINUX-HA-MIB::LHAResourceTable LINUX-HA-MIB::LHAResourceName.1 = STRING: group0 LINUX-HA-MIB::LHAResourceName.2 = STRING: prmIp LINUX-HA-MIB::LHAResourceName.3 = STRING: prmApPostgreSQLDB LINUX-HA-MIB::LHAResourceName.4 = STRING: clone0 LINUX-HA-MIB::LHAResourceName.5 = STRING: clone0 LINUX-HA-MIB::LHAResourceName.6 = STRING: clone0-dummy:0 LINUX-HA-MIB::LHAResourceName.7 = STRING: clone0-dummy:1 LINUX-HA-MIB::LHAResourceName.8 = STRING: ms-sf LINUX-HA-MIB::LHAResourceName.9 = STRING: ms-sf LINUX-HA-MIB::LHAResourceName.10 = STRING: master_slave_Stateful:0 LINUX-HA-MIB::LHAResourceName.11 = STRING: master_slave_Stateful:1 LINUX-HA-MIB::LHAResourceType.1 = INTEGER: group(2) LINUX-HA-MIB::LHAResourceType.2 = INTEGER: primitive(1) LINUX-HA-MIB::LHAResourceType.3 = INTEGER: primitive(1) LINUX-HA-MIB::LHAResourceType.4 = INTEGER: clone(3) LINUX-HA-MIB::LHAResourceType.5 = INTEGER: clone(3) LINUX-HA-MIB::LHAResourceType.6 = INTEGER: primitive(1) LINUX-HA-MIB::LHAResourceType.7 = INTEGER: primitive(1) LINUX-HA-MIB::LHAResourceType.8 = INTEGER: masterSlave(4) LINUX-HA-MIB::LHAResourceType.9 = INTEGER: masterSlave(4) LINUX-HA-MIB::LHAResourceType.10 = INTEGER: primitive(1) LINUX-HA-MIB::LHAResourceType.11 = INTEGER: primitive(1) LINUX-HA-MIB::LHAResourceNode.1 = STRING: u5node1 LINUX-HA-MIB::LHAResourceNode.2 = STRING: u5node1 LINUX-HA-MIB::LHAResourceNode.3 = STRING: u5node1 LINUX-HA-MIB::LHAResourceNode.4 = STRING: u5node1 LINUX-HA-MIB::LHAResourceNode.5 = STRING: u5node2 LINUX-HA-MIB::LHAResourceNode.6 = STRING: u5node2 LINUX-HA-MIB::LHAResourceNode.7 = STRING: u5node1 LINUX-HA-MIB::LHAResourceNode.8 = STRING: u5node1 LINUX-HA-MIB::LHAResourceNode.9 = STRING: u5node2 LINUX-HA-MIB::LHAResourceNode.10 = STRING: u5node2 LINUX-HA-MIB::LHAResourceNode.11 = STRING: u5node1 LINUX-HA-MIB::LHAResourceStatus.1 = INTEGER: started(2) LINUX-HA-MIB::LHAResourceStatus.2 = INTEGER: started(2) LINUX-HA-MIB::LHAResourceStatus.3 = INTEGER: started(2) LINUX-HA-MIB::LHAResourceStatus.4 = INTEGER: started(2) LINUX-HA-MIB::LHAResourceStatus.5 = INTEGER: started(2) LINUX-HA-MIB::LHAResourceStatus.6 = INTEGER: started(2) LINUX-HA-MIB::LHAResourceStatus.7 = INTEGER: started(2) LINUX-HA-MIB::LHAResourceStatus.8 = INTEGER: master(4) LINUX-HA-MIB::LHAResourceStatus.9 = INTEGER: master(4) LINUX-HA-MIB::LHAResourceStatus.10 = INTEGER: started(2) LINUX-HA-MIB::LHAResourceStatus.11 = INTEGER: master(4) LINUX-HA-MIB::LHAResourceIsManaged.1 = INTEGER: managed(1) LINUX-HA-MIB::LHAResourceIsManaged.2 = INTEGER: managed(1) LINUX-HA-MIB::LHAResourceIsManaged.3 = INTEGER: managed(1) LINUX-HA-MIB::LHAResourceIsManaged.4 = INTEGER: managed(1) LINUX-HA-MIB::LHAResourceIsManaged.5 = INTEGER: managed(1) LINUX-HA-MIB::LHAResourceIsManaged.6 = INTEGER: managed(1) LINUX-HA-MIB::LHAResourceIsManaged.7 = INTEGER: managed(1) LINUX-HA-MIB::LHAResourceIsManaged.8 = INTEGER: managed(1) LINUX-HA-MIB::LHAResourceIsManaged.9 = INTEGER: managed(1) LINUX-HA-MIB::LHAResourceIsManaged.10 = INTEGER: managed(1) LINUX-HA-MIB::LHAResourceIsManaged.11 = INTEGER: managed(1) LINUX-HA-MIB::LHAResourceFailCount.1 = INTEGER: 0 LINUX-HA-MIB::LHAResourceFailCount.2 = INTEGER: 0 LINUX-HA-MIB::LHAResourceFailCount.3 = INTEGER: 0 LINUX-HA-MIB::LHAResourceFailCount.4 = INTEGER: 0 LINUX-HA-MIB::LHAResourceFailCount.5 = INTEGER: 0 LINUX-HA-MIB::LHAResourceFailCount.6 = INTEGER: 0 LINUX-HA-MIB::LHAResourceFailCount.7 = INTEGER: 0 LINUX-HA-MIB::LHAResourceFailCount.8 = INTEGER: 0 LINUX-HA-MIB::LHAResourceFailCount.9 = INTEGER: 0 LINUX-HA-MIB::LHAResourceFailCount.10 = INTEGER: 0 LINUX-HA-MIB::LHAResourceFailCount.11 = INTEGER: 0 LINUX-HA-MIB::LHAResourceParent.1 = STRING: LINUX-HA-MIB::LHAResourceParent.2 = STRING: group0 LINUX-HA-MIB::LHAResourceParent.3 = STRING: group0 LINUX-HA-MIB::LHAResourceParent.4 = STRING: LINUX-HA-MIB::LHAResourceParent.5 = STRING: LINUX-HA-MIB::LHAResourceParent.6 = STRING: clone0 LINUX-HA-MIB::LHAResourceParent.7 = STRING: clone0 LINUX-HA-MIB::LHAResourceParent.8 = STRING: LINUX-HA-MIB::LHAResourceParent.9 = STRING: LINUX-HA-MIB::LHAResourceParent.10 = STRING: ms-sf LINUX-HA-MIB::LHAResourceParent.11 = STRING: ms-sf cf.) Then crm_mon's output is... ============ Last updated: Mon Dec 3 17:39:27 2007 Current DC: u5node2 (7e035df7-607d-42b4-a1e7-e8d9db108e6c) 2 Nodes configured. 3 Resources configured. ============ Node: u5node1 (77b7c7b1-68ba-4542-9f10-b75de73e9ffd): online Node: u5node2 (7e035df7-607d-42b4-a1e7-e8d9db108e6c): online Resource Group: group0 prmIp (heartbeat::ocf:IPaddr): Started u5node1 prmApPostgreSQLDB (heartbeat::ocf:pgsql): Started u5node1 Clone Set: clone0 clone0-dummy:0 (heartbeat::ocf:Dummy): Started u5node2 clone0-dummy:1 (heartbeat::ocf:Dummy): Started u5node1 Master/Slave Set: ms-sf master_slave_Stateful:0 (heartbeat::ocf:Stateful): Started u5node2 master_slave_Stateful:1 (heartbeat::ocf:Stateful): Master u5node1 Sample SNMP traps Dec 3 17:38:31 manager_node snmptrapd[1343]: 2007-12-03 17:38:31 u5node2 [ 192.168.70.129]: DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (22408) 0 :03:44.08 SNMPv2-MIB::snmpTrapOID.0 = OID: LINUX-HA-MIB::LHAResourceStatu sUpdate LINUX-HA-MIB::LHAResourceName = STRING: master_slave_Stateful:0 LI NUX-HA-MIB::LHAResourceNode = STRING: u5node2 LINUX-HA-MIB::LHAResourceStat us = INTEGER: started(2) Dec 3 17:38:31 manager_node snmptrapd[1343]: 2007-12-03 17:38:31 u5node2 [ 192.168.70.129]: DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (22420) 0 :03:44.20 SNMPv2-MIB::snmpTrapOID.0 = OID: LINUX-HA-MIB::LHAResourceStatu sUpdate LINUX-HA-MIB::LHAResourceName = STRING: clone0-dummy:0 LINUX-HA-M IB::LHAResourceNode = STRING: u5node2 LINUX-HA-MIB::LHAResourceStatus = INT EGER: started(2) Dec 3 17:38:32 manager_node snmptrapd[1343]: 2007-12-03 17:38:32 u5node1 [ 192.168.70.128]: DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (19126) 0 :03:11.26 SNMPv2-MIB::snmpTrapOID.0 = OID: LINUX-HA-MIB::LHAResourceStatu sUpdate LINUX-HA-MIB::LHAResourceName = STRING: clone0-dummy:1 LINUX-HA-M IB::LHAResourceNode = STRING: u5node1 LINUX-HA-MIB::LHAResourceStatus = INT EGER: started(2) Dec 3 17:38:32 manager_node snmptrapd[1343]: 2007-12-03 17:38:32 u5node1 [ 192.168.70.128]: DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (19129) 0 :03:11.29 SNMPv2-MIB::snmpTrapOID.0 = OID: LINUX-HA-MIB::LHAResourceStatu sUpdate LINUX-HA-MIB::LHAResourceName = STRING: master_slave_Stateful:1 LI NUX-HA-MIB::LHAResourceNode = STRING: u5node1 LINUX-HA-MIB::LHAResourceStat us = INTEGER: started(2) Dec 3 17:38:34 manager_node snmptrapd[1343]: 2007-12-03 17:38:34 u5node1 [ 192.168.70.128]: DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (19314) 0 :03:13.14 SNMPv2-MIB::snmpTrapOID.0 = OID: LINUX-HA-MIB::LHAResourceStatu sUpdate LINUX-HA-MIB::LHAResourceName = STRING: master_slave_Stateful:1 LI NUX-HA-MIB::LHAResourceNode = STRING: u5node1 LINUX-HA-MIB::LHAResourceStat us = INTEGER: master(4) Dec 3 17:38:36 manager_node snmptrapd[1343]: 2007-12-03 17:38:36 u5node1 [ 192.168.70.128]: DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (19516) 0 :03:15.16 SNMPv2-MIB::snmpTrapOID.0 = OID: LINUX-HA-MIB::LHAResourceStatu sUpdate LINUX-HA-MIB::LHAResourceName = STRING: prmIp LINUX-HA-MIB::LHAR esourceNode = STRING: u5node1 LINUX-HA-MIB::LHAResourceStatus = INTEGER: st arted(2) Dec 3 17:38:42 manager_node snmptrapd[1343]: 2007-12-03 17:38:42 u5node1 [ 192.168.70.128]: DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (20067) 0 :03:20.67 SNMPv2-MIB::snmpTrapOID.0 = OID: LINUX-HA-MIB::LHAResourceStatu sUpdate LINUX-HA-MIB::LHAResourceName = STRING: prmApPostgreSQLDB LI NUX-HA-MIB::LHAResourceNode = STRING: u5node1 LINUX-HA-MIB::LHAResourceStat us = INTEGER: started(2) 5. Other changes This patch modifies the following too. 1) Make SNMP_CACHE_TIME_OUT variable. apply the value which is specified with -r option. 2) Fix some memory leaks. debug with valgrind. 3) Update SNMPAgentSanityCheck to keep up with the new functionality. 6. Work with OpenAIS You have to manually start the SNMP subagent for an openAIS based cluster as the following : # export HA_cluster_type=openais; /usr/lib/heartbeat/hbagent & Note: People on 64-bit platforms will probably need to replace lib with lib64 pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/SNMPAgentSanityCheck.in000077500000000000000000000130111211477743100263630ustar00rootroot00000000000000#!/bin/sh # # Copyright (C) 2002 Yixiong Zou (yixiong.zou@intel.com) # Support: linux-ha-dev@lists.tummy.com # License: GNU General Public License (GPL) # set +x # # BasicSanityCheck has to run as root. # # Perhaps a better way to do this is to use the cl_status command... # -- AlanR # NODE0=`uname -n` NODE1=imalwaysdead.com # make sure the agent and the subagent are dead killall -9 hbagent killall -9 snmpd # make sure the snmpd is running and agentX support is turned on GenerateSNMPDConf() { cat <<-! >$1 rocommunity public master yes trap2sink localhost ! chmod 644 $1 } which snmpd ret=$? if test $ret != 0 then echo "snmpd file is not in the path, skip agent test..." exit $ret fi # start the snmpd manually with our own config file SNMPDCONF=/var/run/testsnmpd.conf SNMPPIDFILE=/var/run/testsnmpd.pid SNMPD=`which snmpd` GenerateSNMPDConf $SNMPDCONF $SNMPD -C -c $SNMPDCONF -p $SNMPPIDFILE #@INITDIR@/snmpd status #ret=$? #if test $ret != 0 # then echo "snmpd cannot be started correctly. skip agent test..." # exit $ret #else # echo "snmpd is already running, good" #fi # we want to wait for a couple seconds to let the master agent fully # ready before we start the subagent. sleep 3 # start the linux-ha snmp subagent @libdir@/heartbeat/hbagent -d & HBAGENTPID=$! sleep 5 # get the nodename for node0 and node1 # node0 should be the value of the localhost # node1 should be "ImAlwaysDead.com" export MIBS=ALL #snmpwalk -v2c localhost -c public LinuxHA node0=`snmpget -v2c localhost -c public LHANodeName.1 | sed -ne 's/LINUX-HA-MIB::LHANodeName.1 = STRING: //p'` echo node0 = $node0 node1=`snmpget -v2c localhost -c public LHANodeName.2 | sed -ne 's/LINUX-HA-MIB::LHANodeName.2 = STRING: //p'` echo node1 = $node1 ret=1 ret2=1 for name in $NODE0 $NODE1; do echo name = $name, node0 = $node0 if test "$node0" = "$name"; then ret=0 echo "found $node0" break fi done if test $ret = 0; then for name in $NODE0 $NODE1; do echo name = $name, node1 = $node1 if test "$node1" = "$name"; then ret2=0 echo "found $node1" break fi done fi if test $ret2 = 0; then echo "BasicSanityCheck for SNMP Subagent passed." # exit 0 else echo "BasicSanityCheck for SNMP Subagent failed." # exit 1 fi # # BasicSanityCheck for SNMP Subagent about CRM resources. # # wait to let cib ready to execute variant_op sleep 10 # add CRM resource. RSC0NAME="prmDummy" RSC0TYPE="primitive(1)" RSC0NODE="$NODE0" RSC0STATUS="started(2)" RSC0ISMANAGED="managed(1)" RSC0FAILCOUNT="0" RSC0PARENT="" # clear resources cibadmin --cib_replace -X '' cibadmin --cib_create -o resources \ -X '' sleep 3 # get resource's information with snmp subagent. rsc0name=`snmpget -v2c localhost -c public LHAResourceName.1 \ | sed -ne 's/LINUX-HA-MIB::LHAResourceName.1 = STRING: //p'` rsc0type=`snmpget -v2c localhost -c public LHAResourceType.1 \ | sed -ne 's/LINUX-HA-MIB::LHAResourceType.1 = INTEGER: //p'` rsc0node=`snmpget -v2c localhost -c public LHAResourceNode.1 \ | sed -ne 's/LINUX-HA-MIB::LHAResourceNode.1 = STRING: //p'` rsc0status=`snmpget -v2c localhost -c public LHAResourceStatus.1 \ | sed -ne 's/LINUX-HA-MIB::LHAResourceStatus.1 = INTEGER: //p'` rsc0ismanaged=`snmpget -v2c localhost -c public LHAResourceIsManaged.1 \ | sed -ne 's/LINUX-HA-MIB::LHAResourceIsManaged.1 = INTEGER: //p'` rsc0failcount=`snmpget -v2c localhost -c public LHAResourceFailCount.1 \ | sed -ne 's/LINUX-HA-MIB::LHAResourceFailCount.1 = INTEGER: //p'` rsc0parent=`snmpget -v2c localhost -c public LHAResourceParent.1 \ | sed -ne 's/LINUX-HA-MIB::LHAResourceParent.1 = STRING: //p'` # check for LHAResourceName ret=0 echo "rsc0name = $rsc0name, RSC0NAME = $RSC0NAME" if test "$rsc0name" != "$RSC0NAME"; then echo "failed to get resource name." >&2 ret=1 fi # check for LHAResourceType if test $ret = 0; then echo "rsc0type = $rsc0type, RSC0TYPE = $RSC0TYPE" if test "$rsc0type" != "$RSC0TYPE"; then echo "failed to get resource type." >&2 ret=1 fi fi # check for LHAResourceNode if test $ret = 0; then echo "rsc0node = $rsc0node, RSC0NODE = $RSC0NODE" if test "$rsc0node" != "$RSC0NODE"; then echo "failed to get resource node." >&2 ret=1 fi fi # check for LHAResourceStatus if test $ret = 0; then echo "rsc0status = $rsc0status, RSC0STATUS = $RSC0STATUS" if test "$rsc0status" != "$RSC0STATUS"; then echo "failed to get resource status." >&2 ret=1 fi fi # check for LHAResourceIsManaged if test $ret = 0; then echo "rsc0ismanaged = $rsc0ismanaged, RSC0ISMANAGED = $RSC0ISMANAGED" if test "$rsc0ismanaged" != "$RSC0ISMANAGED"; then echo "failed to get resource ismanaged." >&2 ret=1 fi fi # check for LHAResourceFailCount if test $ret = 0; then echo "rsc0failcount = $rsc0failcount, RSC0FAILCOUNT = $RSC0FAILCOUNT" if test "$rsc0failcount" != "$RSC0FAILCOUNT"; then echo "failed to get resource failcount." >&2 ret=1 fi fi # check for LHAResourceParent if test $ret = 0; then echo "rsc0parent = $rsc0parent, RSC0PARENT = $RSC0PARENT" if test "$rsc0parent" != "$RSC0PARENT"; then echo "failed to get resource parent." >&2 ret=1 fi fi # show the result. if test $ret = 0; then echo "BasicSanityCheck for SNMP Subagent about CRM resources passed." else echo "BasicSanityCheck for SNMP Subagent about CRM resources failed." fi kill $HBAGENTPID if [ -f $SNMPPIDFILE -a ! -z $SNMPPIDFILE ] then kill `cat $SNMPPIDFILE` rm -f $SNMPPIDFILE fi # clear resources cibadmin --cib_replace -X '' exit $ret pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/hbagent.c000066400000000000000000001202751211477743100237350ustar00rootroot00000000000000/* * hbagent.c: heartbeat snmp subagnet code. * * Copyright (c) 2004 Intel Corp. * * Author: Zou Yixiong (yixiong.zou@intel.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #ifdef SUPPORT_AIS #undef SUPPORT_AIS #endif #ifdef SUPPORT_HEARTBEAT #undef SUPPORT_HEARTBEAT #endif #include #include "hbagent.h" #include "hbagentv2.h" #if SUPPORT_HEARTBEAT #include "hb_api.h" #include "heartbeat.h" #else # if HAVE_PACEMAKER_CRM_COMMON_CLUSTER_H # include # endif # if HAVE_PACEMAKER_CRM_CLUSTER_H # include # endif #endif #include "clplumbing/cl_log.h" #include "clplumbing/coredumps.h" #ifdef PACKAGE_BUGREPORT #undef PACKAGE_BUGREPORT #endif #ifdef PACKAGE_NAME #undef PACKAGE_NAME #endif #ifdef PACKAGE_STRING #undef PACKAGE_STRING #endif #ifdef PACKAGE_TARNAME #undef PACKAGE_TARNAME #endif #ifdef PACKAGE_VERSION #undef PACKAGE_VERSION #endif #include #include #include #include #include "LHAClusterInfo.h" #include "LHANodeTable.h" #include "LHAIFStatusTable.h" #include "LHAMembershipTable.h" #include "LHAResourceGroupTable.h" #include "LHAHeartbeatConfigInfo.h" #include #include /* getpid() */ #include /* fstat() */ #include #include #include #if SUPPORT_HEARTBEAT #include "saf/ais.h" #endif #include "clplumbing/cl_uuid.h" /* UU_UNPARSE_SIZEOF */ char * myid = NULL; /* my node id */ char * myuuid = NULL; /* my node uuid */ #if SUPPORT_HEARTBEAT static unsigned long hbInitialized = 0; static ll_cluster_t * hb = NULL; /* heartbeat handle */ static SaClmHandleT clm = 0; static unsigned long clmInitialized = 0; static GPtrArray * gNodeTable = NULL; static GPtrArray * gIFTable = NULL; static GPtrArray * gMembershipTable = NULL; static GPtrArray * gResourceTable = NULL; #endif static int keep_running; int snmp_cache_time_out = CACHE_TIME_OUT; #if SUPPORT_HEARTBEAT int init_heartbeat(void); int get_heartbeat_fd(void); int handle_heartbeat_msg(void); int init_membership(void); int get_membership_fd(void); int handle_membership_msg(void); int init_resource_table(void); int init_storage(void); void free_storage(void); int walk_nodetable(void); int walk_iftable(void); int nodestatus_trap(const char * node, const char * status); int ifstatus_trap(const char * node, const char * lnk, const char * status); int membership_trap(const char * node, SaClmClusterChangesT status); int ping_membership(int * mem_fd); #endif int hbagent_trap(int online, const char * node); /* LHAHeartbeatConfigInfo partial-mode */ #define DEFAULT_REFRESH_TIMING (0) #if SUPPORT_HEARTBEAT int init_hbconfig(void); void free_hbconfig(void); int hbconfig_get_str_value(const char * attr, char * * value); static int hbconfig_partial = 0; static char * hbconfig[LHA_CONF_END]; static struct hbconfig_map { lha_hbconfig_t attr_no; const char * attr; } hbconfig_map[] = { {LHA_CONF_HBVERSION, KEY_HBVERSION}, {LHA_CONF_KEEPALIVE, KEY_KEEPALIVE}, {LHA_CONF_DEADTIME, KEY_DEADTIME}, {LHA_CONF_DEADPING, KEY_DEADPING}, {LHA_CONF_WARNTIME, KEY_WARNTIME}, {LHA_CONF_INITDEAD, KEY_INITDEAD}, {LHA_CONF_BAUDRATE, KEY_BAUDRATE}, {LHA_CONF_AUTOFAIL, KEY_AUTOFAIL}, {LHA_CONF_STONITH, KEY_STONITH}, {LHA_CONF_STONITHHOST, KEY_STONITHHOST}, {LHA_CONF_RESPAWN, KEY_CLIENT_CHILD}, {LHA_CONF_END, NULL} }; uint32_t get_status_value(const char * status, const char * * status_array, uint32_t * value_array); const char * NODE_STATUS [] = { "", INITSTATUS, UPSTATUS, ACTIVESTATUS, DEADSTATUS, "" }; static uint32_t NODE_STATUS_VALUE[] = { LHANODESTATUS_UNKNOWN, LHANODESTATUS_INIT, LHANODESTATUS_UP, LHANODESTATUS_ACTIVE, LHANODESTATUS_DEAD, }; const char * NODE_TYPE [] = { UNKNOWNNODE, NORMALNODE, PINGNODE, "" }; static uint32_t NODE_TYPE_VALUE[] = { LHANODETYPE_UNKNOWN, LHANODETYPE_NORMAL, LHANODETYPE_PING }; const char * IF_STATUS[] = { "", LINKUP, DEADSTATUS, "" }; static uint32_t IF_STATUS_VALUE[] = { LHAIFSTATUS_UNKNOWN, LHAIFSTATUS_UP, LHAIFSTATUS_DOWN }; #endif static RETSIGTYPE stop_server(int a) { keep_running = 0; } #if SUPPORT_HEARTBEAT uint32_t get_status_value(const char * status, const char * * status_array, uint32_t * value_array) { int i = 1; int found = 0; while (strlen(status_array[i])) { if (strncmp(status, status_array[i], strlen(status_array[i])) == 0) { found = 1; break; } i++; } if (found) return value_array[i]; else return value_array[0]; } int get_int_value(lha_group_t group, lha_attribute_t attr, size_t index, uint32_t * value) { switch (group) { case LHA_CLUSTERINFO: return clusterinfo_get_int_value(attr, index, value); case LHA_RESOURCEINFO: return rsinfo_get_int_value(attr, index, value); case LHA_NODEINFO: case LHA_IFSTATUSINFO: default: return HA_FAIL; } } int get_str_value(lha_group_t group, lha_attribute_t attr, size_t index, char * * value) { switch (group) { case LHA_HBCONFIGINFO: case LHA_NODEINFO: case LHA_IFSTATUSINFO: case LHA_RESOURCEINFO: default: return HA_FAIL; } } int clusterinfo_get_int_value(lha_attribute_t attr, size_t index, uint32_t * value) { int i; uint32_t status; size_t count; const struct hb_nodeinfo * node; *value = 0; if (!gNodeTable) return HA_FAIL; switch (attr) { case TOTAL_NODE_COUNT: *value = gNodeTable->len; break; case LIVE_NODE_COUNT: count = 0; for (i = 0; i < gNodeTable->len; i++) { status = ((struct hb_nodeinfo *) g_ptr_array_index(gNodeTable, i))->status; if (status != LHANODESTATUS_DEAD && status != LHANODESTATUS_UNKNOWN ) { count++; } } *value = count; break; case RESOURCE_GROUP_COUNT: *value = gResourceTable->len; break; case CURRENT_NODE_ID: for (i = 0; i < gNodeTable->len; i++) { node = (struct hb_nodeinfo *) g_ptr_array_index(gNodeTable, i); if (strcmp(node->name, myid) == 0) { *value = node->id; break; } } break; default: return HA_FAIL; } return HA_OK; } /* LHAHeartbeatConfigInfo partial-mode */ int init_hbconfig(void) { lha_hbconfig_t attr_no; char * value; for (attr_no = LHA_CONF_HBVERSION; attr_no < LHA_CONF_END; ++attr_no) { hbconfig[attr_no] = NULL; if(!hbconfig_partial) continue; if (hbconfig_get_str_value(hbconfig_map[attr_no].attr, &value) != HA_OK) { cl_log(LOG_INFO, "LHAHeartbeatConfigInfo initialization error. " "maybe get_parameter returned NULL."); continue; } hbconfig[attr_no] = value; } return HA_OK; } void free_hbconfig(void) { lha_hbconfig_t attr_no; if (!hbconfig_partial) return; for (attr_no = LHA_CONF_HBVERSION; attr_no < LHA_CONF_END; ++attr_no) { if (hbconfig[attr_no] != NULL) free(hbconfig[attr_no]); } } int hbconfig_get_str(lha_hbconfig_t attr_no, char * * value) { static char err[] = "N/A"; if (hbconfig[attr_no] != NULL) { *value = strdup(hbconfig[attr_no]); } else { if (hbconfig_get_str_value(hbconfig_map[attr_no].attr, value) != HA_OK) { cl_log(LOG_INFO, "LHAHeartbeatConfigInfo getting parameter error. " "maybe get_parameter returned NULL."); *value = strdup(err); } } return HA_OK; } int hbconfig_get_str_value(const char * attr, char * * value) { char * ret; static char err[] = "N/A"; if ((ret = hb->llc_ops->get_parameter(hb, attr)) == NULL) { /* cl_log(LOG_INFO, "getting parameter [%s] error.", attr); cl_log(LOG_INFO, "reason: %s.", hb->llc_ops->errmsg(hb)); */ /* we have to return HA_OK here otherwise the agent code would not progress */ *value = strdup(err); return HA_OK; }; *value = ret; return HA_OK; } GPtrArray * get_hb_info(lha_group_t group) { switch (group) { case LHA_NODEINFO: return gNodeTable; case LHA_IFSTATUSINFO: return gIFTable; case LHA_RESOURCEINFO: return gResourceTable; case LHA_MEMBERSHIPINFO: return gMembershipTable; default: return NULL; } } /* functions which talk to heartbeat */ static void NodeStatus(const char * node, const char * status, void * private) { cl_log(LOG_NOTICE, "Status update: Node %s now has status %s" , node, status); walk_nodetable(); walk_iftable(); nodestatus_trap(node, status); } static void LinkStatus(const char * node, const char * lnk, const char * status , void * private) { cl_log(LOG_NOTICE, "Link Status update: Link %s/%s now has status %s" , node, lnk, status); walk_iftable(); ifstatus_trap(node, lnk, status); } int init_storage(void) { gNodeTable = g_ptr_array_new(); gIFTable = g_ptr_array_new(); gResourceTable = g_ptr_array_new(); gMembershipTable = g_ptr_array_new(); if (!gNodeTable || !gIFTable || !gResourceTable || !gMembershipTable){ cl_log(LOG_ERR, "Storage allocation failure. Out of Memory."); return HA_FAIL; } return HA_OK; } static void free_nodetable(void) { struct hb_nodeinfo * node; if (!gNodeTable) return; while (gNodeTable->len) { node = (struct hb_nodeinfo *) g_ptr_array_remove_index_fast(gNodeTable, 0); free(node->name); free(node); } return; } static void free_iftable(void) { struct hb_ifinfo * interface; if (!gIFTable) return; while (gIFTable->len) { interface = (struct hb_ifinfo *) g_ptr_array_remove_index_fast(gIFTable, 0); free(interface->name); free(interface->node); free(interface); } return; } static void free_resourcetable(void) { struct hb_rsinfo * resource; if (!gResourceTable) return; while (gResourceTable->len) { resource = (struct hb_rsinfo *) g_ptr_array_remove_index_fast(gResourceTable, 0); free(resource->resource); free(resource); } return; } static void free_membershiptable(void) { if (!gMembershipTable) return; /* the membership info buffer is provided by us when we initiated the session, so don't really need to free any memory. */ while (gMembershipTable->len) { g_ptr_array_remove_index_fast(gMembershipTable, 0); } return; } void free_storage(void) { free_nodetable(); g_ptr_array_free(gNodeTable, 1); gNodeTable = NULL; free_iftable(); g_ptr_array_free(gIFTable, 1); gIFTable = NULL; free_resourcetable(); g_ptr_array_free(gResourceTable, 1); gResourceTable = NULL; free_membershiptable(); g_ptr_array_free(gMembershipTable, 1); gMembershipTable = NULL; } int init_heartbeat(void) { char * parameter; cl_uuid_t uuid; hb = NULL; cl_log_set_entity("lha-snmpagent"); cl_log_set_facility(HA_LOG_FACILITY); /* Use logd if it's enabled by heartbeat */ cl_inherit_logging_environment(0); hb = ll_cluster_new("heartbeat"); cl_log(LOG_DEBUG, "PID=%ld", (long)getpid()); cl_log(LOG_DEBUG, "Signing in with heartbeat"); if (hb->llc_ops->signon(hb, LHAAGENTID)!= HA_OK) { cl_log(LOG_ERR, "Cannot sign on with heartbeat"); cl_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb)); return HA_FAIL; } /* See if we should drop cores somewhere odd... */ parameter = hb->llc_ops->get_parameter(hb, KEY_COREROOTDIR); if (parameter) { cl_set_corerootdir(parameter); free(parameter); } cl_cdtocoredir(); if (NULL == (myid = strdup(hb->llc_ops->get_mynodeid(hb)))) { cl_log(LOG_ERR, "Cannot get mynodeid"); cl_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb)); return HA_FAIL; } /* * get uuid for trap message. * see: hbagentv2_update_diff() in hbagentv2.c */ if (hb->llc_ops->get_uuid_by_name(hb, myid, &uuid) == HA_FAIL) { cl_log(LOG_ERR, "Cannot get mynodeid"); cl_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb)); return HA_FAIL; } myuuid = malloc(UU_UNPARSE_SIZEOF); cl_uuid_unparse(&uuid, myuuid); if (hb->llc_ops->set_nstatus_callback(hb, NodeStatus, NULL) !=HA_OK){ cl_log(LOG_ERR, "Cannot set node status callback"); cl_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb)); return HA_FAIL; } if (hb->llc_ops->set_ifstatus_callback(hb, LinkStatus, NULL)!=HA_OK){ cl_log(LOG_ERR, "Cannot set if status callback"); cl_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb)); return HA_FAIL; } #if 1 /* walk the node table */ if ( HA_OK != walk_nodetable() || HA_OK != walk_iftable() ) { return HA_FAIL; } #endif hbInitialized = 1; return HA_OK; } int get_heartbeat_fd(void) { int ret, fd; if(!hbInitialized) { ret = init_heartbeat(); if (ret != HA_OK) { return ret; } } if ((fd = hb->llc_ops->inputfd(hb)) < 0) { cl_log(LOG_ERR, "Cannot get inputfd"); cl_log(LOG_ERR, "REASON, %s", hb->llc_ops->errmsg(hb)); } return fd; } int walk_nodetable(void) { const char *name, *type, *status; struct hb_nodeinfo * node; size_t id = 0; cl_uuid_t uuid; if (gNodeTable) { free_nodetable(); } if (hb->llc_ops->init_nodewalk(hb) != HA_OK) { cl_log(LOG_ERR, "Cannot start node walk"); cl_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb)); return HA_FAIL; } while((name = hb->llc_ops->nextnode(hb))!= NULL) { id++; status = hb->llc_ops->node_status(hb, name); type = hb->llc_ops->node_type(hb, name); cl_log(LOG_INFO, "node %ld: %s, type: %s, status: %s", (unsigned long)id, name , type, status); node = (struct hb_nodeinfo *) malloc(sizeof(struct hb_nodeinfo)); if (!node) { cl_log(LOG_CRIT, "malloc failed for node info."); return HA_FAIL; } node->name = g_strdup(name); node->ifcount = 0; node->id = id; memset(&uuid, 0, sizeof(cl_uuid_t)); #ifdef HAVE_NEW_HB_API /* the get_uuid_by_name is not available for STABLE_1_2 branch. */ if (hb->llc_ops->get_uuid_by_name(hb, name, &uuid) == HA_FAIL) { cl_log(LOG_DEBUG, "Cannot get the uuid for node: %s", name); } #endif /* HAVE_NEW_HB_API */ node->uuid = uuid; node->type = get_status_value(type, NODE_TYPE, NODE_TYPE_VALUE); node->status = get_status_value(status, NODE_STATUS, NODE_STATUS_VALUE); g_ptr_array_add(gNodeTable, (gpointer *) node); } if (hb->llc_ops->end_nodewalk(hb) != HA_OK) { cl_log(LOG_ERR, "Cannot end node walk"); cl_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb)); return HA_FAIL; } return HA_OK; } int walk_iftable(void) { const char *name, * status; struct hb_nodeinfo * node; struct hb_ifinfo * interface; int i; size_t ifcount; if (gIFTable) { free_iftable(); } for (i = 0; i < gNodeTable->len; i++) { node = (struct hb_nodeinfo *) g_ptr_array_index(gNodeTable, i); ifcount = 0; if (hb->llc_ops->init_ifwalk(hb, node->name) != HA_OK) { cl_log(LOG_ERR, "Cannot start if walk"); cl_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb)); return HA_FAIL; } while((name = hb->llc_ops->nextif(hb))!=NULL) { status = hb->llc_ops->if_status(hb, node->name, name); cl_log(LOG_INFO, "node: %s, interface: %s, status: %s", node->name, name, status); interface = (struct hb_ifinfo *) malloc(sizeof(struct hb_ifinfo)); if (!interface) { cl_log(LOG_CRIT, "malloc failed for if info."); return HA_FAIL; } interface->name = g_strdup(name); interface->node = g_strdup(node->name); interface->nodeid = node->id; interface->id = ++ifcount; interface->status = get_status_value(status, IF_STATUS, IF_STATUS_VALUE); g_ptr_array_add(gIFTable, (gpointer *) interface); } node->ifcount = ifcount; if (hb->llc_ops->end_ifwalk(hb) != HA_OK) { cl_log(LOG_ERR, "Cannot end if walk."); cl_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb)); return HA_FAIL; } } return HA_OK; } int handle_heartbeat_msg(void) { IPC_Channel * chan; struct ha_msg * msg; const char * type, * node; while (hb->llc_ops->msgready(hb)) { chan = hb->llc_ops->ipcchan(hb); /* this happens when the main heartbeat daemon is not there any more */ if (chan->ch_status == IPC_DISCONNECT) { return HA_FAIL; } msg = hb->llc_ops->readmsg(hb, 0); if (!msg) { cl_log(LOG_DEBUG, "read_hb_msg returned NULL."); continue; } type = ha_msg_value(msg, F_TYPE); node = ha_msg_value(msg, F_ORIG); if (!type || !node) { /* can't read type. log and ignore the msg. */ cl_log(LOG_DEBUG, "Can't read msg type."); return HA_OK; } /* we only handle the shutdown msg for now. */ if (strcmp(myid, node) == 0 && STRNCMP_CONST(type, T_SHUTDONE) == 0) { return HA_FAIL; } ha_msg_del(msg); msg = NULL; } return HA_OK; } static void clm_track_cb(SaClmClusterNotificationT *nbuf, SaUint32T nitem, SaUint32T nmem, SaUint64T nview, SaErrorT error) { int i; const char * node; SaClmClusterChangesT status; free_membershiptable(); for (i = 0; i < nitem; i++) { cl_log(LOG_INFO, "adding %s in membership table", nbuf[i].clusterNode.nodeName.value); g_ptr_array_add(gMembershipTable, (gpointer *) &nbuf[i]); } if (clmInitialized) { for (i = 0; i < nitem; i++) { status = nbuf[i].clusterChanges; node = (char *)nbuf[i].clusterNode.nodeName.value; if (status == SA_CLM_NODE_NO_CHANGE) { continue; } membership_trap(node, status); } } } static void clm_node_cb(SaInvocationT invocation, SaClmClusterNodeT *clusterNode, SaErrorT error) { return; } int init_membership(void) { SaErrorT ret; static SaClmClusterNotificationT * nbuf = NULL; SaClmHandleT handle; SaClmCallbacksT my_callbacks = { .saClmClusterTrackCallback = (SaClmClusterTrackCallbackT) clm_track_cb, .saClmClusterNodeGetCallback = (SaClmClusterNodeGetCallbackT) clm_node_cb, }; if ((ret = saClmInitialize(&handle, &my_callbacks, NULL)) != SA_OK) { cl_log(LOG_DEBUG, "Membership service currently not available. Will try again later. errno [%d]",ret); return HA_OK; } if (nbuf) { free(nbuf); } nbuf = (SaClmClusterNotificationT *) malloc(gNodeTable->len * sizeof (SaClmClusterNotificationT)); if (!nbuf) { cl_log(LOG_ERR, "%s: malloc failed for SaClmClusterNotificationT.", __FUNCTION__); return HA_FAIL; } if (saClmClusterTrackStart(&handle, SA_TRACK_CURRENT, nbuf, gNodeTable->len) != SA_OK) { cl_log(LOG_ERR, "SA_TRACK_CURRENT error, errno [%d]", ret); free(nbuf); return HA_FAIL; } /* Start to track cluster membership changes events */ if (saClmClusterTrackStart(&handle, SA_TRACK_CHANGES, nbuf, gNodeTable->len) != SA_OK) { cl_log(LOG_ERR, "SA_TRACK_CURRENT error, errno [%d]", ret); free(nbuf); return HA_FAIL; } clm = handle; clmInitialized = 1; cl_log(LOG_INFO, "Membership service initialized successfully."); return HA_OK; } int get_membership_fd(void) { SaErrorT ret; SaSelectionObjectT st; if (!clmInitialized) return 0; if ((ret = saClmSelectionObjectGet(&clm, &st)) != SA_OK) { cl_log(LOG_ERR, "saClmSelectionObjectGet error, errno [%d]", ret); return -1; } return (int) st; } int handle_membership_msg(void) { SaErrorT ret; if ((ret = saClmDispatch(&clm, SA_DISPATCH_ALL)) != SA_OK) { if (ret == SA_ERR_LIBRARY) { cl_log(LOG_DEBUG, "I am evicted."); /* mark the membership as uninitialized and try again later. */ clmInitialized = 0; free_membershiptable(); /* finalize membership */ saClmFinalize(&clm); return HA_OK; } else { cl_log(LOG_WARNING, "saClmDispatch error, ret = [%d]", ret); } } return HA_OK; } int ping_membership(int * mem_fd) { int fd; if (clmInitialized) return 0; init_membership(); fd = get_membership_fd(); *mem_fd = fd; return HA_OK; } int init_resource_table(void) { int rc, i, count, found; FILE * rcsf; char buf[MAXLINE]; char host[MAXLINE], pad[MAXLINE]; struct hb_rsinfo * resource; struct hb_nodeinfo * node; size_t nodeid = 0; if (gResourceTable) { free_resourcetable(); } if ((rcsf = fopen(RESOURCE_CFG, "r")) == NULL) { cl_log(LOG_ERR, "Cannot open file %s", RESOURCE_CFG); return HA_FAIL; } count = 0; for (;;) { errno = 0; if (fgets(buf, MAXLINE, rcsf) == NULL) { if (ferror(rcsf)) { cl_perror("fgets failure"); } break; } /* remove the comments */ if (buf[0] == '#') { continue; } if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = EOS; if ((rc = sscanf(buf, "%s %[^\n\t\r]", host, pad)) < 1) { cl_log(LOG_WARNING, "%s syntax error?", RESOURCE_CFG); }; /* make sure that the host node is in the node list */ found = 0; for (i = 0; i < gNodeTable->len; i++) { node = (struct hb_nodeinfo *) g_ptr_array_index(gNodeTable, i); if (strcmp(node->name, host) == 0) { found = 1; nodeid = node->id; break; } } if (!found) continue; resource = (struct hb_rsinfo *) malloc(sizeof(struct hb_rsinfo)); if (!resource) { cl_log(LOG_CRIT, "malloc resource info failed."); fclose(rcsf); return HA_FAIL; } resource->id = ++count; resource->masternodeid = nodeid; resource->resource = g_strdup(pad); g_ptr_array_add(gResourceTable, (gpointer *) resource); } fclose(rcsf); return HA_OK; } int rsinfo_get_int_value(lha_attribute_t attr, size_t index, uint32_t * value) { uint32_t rc = 0; char getcmd[MAXLINE]; char * resource; *value = 0; if (!gResourceTable) return HA_FAIL; switch (attr) { case RESOURCE_STATUS: resource = ((struct hb_rsinfo *) g_ptr_array_index(gResourceTable, index))->resource; sprintf(getcmd, HA_NOARCHDATAHBDIR "/ResourceManager status %s", resource); rc = system(getcmd); /* cl_log(LOG_INFO, "resource [%s] status: [%d]", resource, WEXITSTATUS(rc)); */ *value = WEXITSTATUS(rc); break; default: return HA_FAIL; } return HA_OK; } int nodestatus_trap(const char * node, const char * status) { uint32_t svalue = 0; oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 }; size_t objid_snmptrap_len = OID_LENGTH(objid_snmptrap); oid trap_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 900, 1 }; size_t trap_oid_len = OID_LENGTH(trap_oid); oid nodename_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 2, 1, 2 }; size_t nodename_oid_len = OID_LENGTH(nodename_oid); oid nodestatus_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 2, 1, 4 }; size_t nodestatus_oid_len = OID_LENGTH(nodestatus_oid); netsnmp_variable_list *notification_vars = NULL; svalue = get_status_value(status, NODE_STATUS, NODE_STATUS_VALUE); snmp_varlist_add_variable(¬ification_vars, /* * the snmpTrapOID.0 variable */ objid_snmptrap, objid_snmptrap_len, /* * value type is an OID */ ASN_OBJECT_ID, /* * value contents is our notification OID */ (u_char *) trap_oid, /* * size in bytes = oid length * sizeof(oid) */ trap_oid_len * sizeof(oid)); snmp_varlist_add_variable(¬ification_vars, nodename_oid, nodename_oid_len, ASN_OCTET_STR, (const u_char *) node, strlen(node)); /* do NOT use strlen() +1 */ snmp_varlist_add_variable(¬ification_vars, nodestatus_oid, nodestatus_oid_len, ASN_INTEGER, (const u_char *) & svalue, sizeof(svalue)); cl_log(LOG_INFO, "sending node status trap. node: %s: status %s, value:%d", node, status, svalue); send_v2trap(notification_vars); snmp_free_varbind(notification_vars); return HA_OK; } int ifstatus_trap(const char * node, const char * lnk, const char * status) { uint32_t svalue = 0; oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 }; size_t objid_snmptrap_len = OID_LENGTH(objid_snmptrap); oid trap_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 900, 3 }; size_t trap_oid_len = OID_LENGTH(trap_oid); oid nodename_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 2, 1, 2 }; size_t nodename_oid_len = OID_LENGTH(nodename_oid); oid ifname_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 3, 1, 2 }; size_t ifname_oid_len = OID_LENGTH(ifname_oid); oid ifstatus_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 3, 1, 3 }; size_t ifstatus_oid_len = OID_LENGTH(ifstatus_oid); netsnmp_variable_list *notification_vars = NULL; svalue = get_status_value(status, IF_STATUS, IF_STATUS_VALUE); snmp_varlist_add_variable(¬ification_vars, /* * the snmpTrapOID.0 variable */ objid_snmptrap, objid_snmptrap_len, /* * value type is an OID */ ASN_OBJECT_ID, /* * value contents is our notification OID */ (u_char *) trap_oid, /* * size in bytes = oid length * sizeof(oid) */ trap_oid_len * sizeof(oid)); snmp_varlist_add_variable(¬ification_vars, nodename_oid, nodename_oid_len, ASN_OCTET_STR, (const u_char *) node, strlen(node)); /* do NOT use strlen() +1 */ snmp_varlist_add_variable(¬ification_vars, ifname_oid, ifname_oid_len, ASN_OCTET_STR, (const u_char *) lnk, strlen(lnk)); /* do NOT use strlen() +1 */ snmp_varlist_add_variable(¬ification_vars, ifstatus_oid, ifstatus_oid_len, ASN_INTEGER, (const u_char *) & svalue, sizeof(svalue)); cl_log(LOG_INFO, "sending ifstatus trap. node:%s, lnk: %s, status:%s, value: %d", node, lnk, status, svalue); send_v2trap(notification_vars); snmp_free_varbind(notification_vars); return HA_OK; } int membership_trap(const char * node, SaClmClusterChangesT status) { oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 }; size_t objid_snmptrap_len = OID_LENGTH(objid_snmptrap); oid trap_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 900, 5 }; size_t trap_oid_len = OID_LENGTH(trap_oid); oid nodename_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 2, 1, 2 }; size_t nodename_oid_len = OID_LENGTH(nodename_oid); oid membershipchange_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 6, 1, 6 }; size_t membershipchange_oid_len = OID_LENGTH(membershipchange_oid); netsnmp_variable_list *notification_vars = NULL; snmp_varlist_add_variable(¬ification_vars, /* * the snmpTrapOID.0 variable */ objid_snmptrap, objid_snmptrap_len, /* * value type is an OID */ ASN_OBJECT_ID, /* * value contents is our notification OID */ (u_char *) trap_oid, /* * size in bytes = oid length * sizeof(oid) */ trap_oid_len * sizeof(oid)); snmp_varlist_add_variable(¬ification_vars, nodename_oid, nodename_oid_len, ASN_OCTET_STR, (const u_char *) node, strlen(node)); /* do NOT use strlen() +1 */ snmp_varlist_add_variable(¬ification_vars, membershipchange_oid, membershipchange_oid_len, ASN_INTEGER, (u_char *) & status, sizeof(status)); cl_log(LOG_INFO, "sending membership trap. node:%s, status:%d", node, status); send_v2trap(notification_vars); snmp_free_varbind(notification_vars); return HA_OK; } #else GPtrArray * get_hb_info(lha_group_t group) { return NULL; } int get_int_value(lha_group_t group, lha_attribute_t attr, size_t index, uint32_t * value) { return 0; } int hbconfig_get_str(lha_hbconfig_t attr_no, char * * value) { return 0; } int rsinfo_get_int_value(lha_attribute_t attr, size_t index, uint32_t * value) { return 0; } #endif int hbagent_trap(int online, const char * node) { netsnmp_variable_list *notification_vars = NULL; oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 }; size_t objid_snmptrap_len = OID_LENGTH(objid_snmptrap); oid nodename_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 2, 1, 2 }; size_t nodename_oid_len = OID_LENGTH(nodename_oid); /* this is the oid for the hbagent online trap */ oid trap_oid[] = { 1, 3, 6, 1, 4, 1, 4682, 900, 7 }; size_t trap_oid_len = OID_LENGTH(trap_oid); /* this is the oid for the offline trap */ if (!online) { trap_oid[trap_oid_len - 1] = 9; } snmp_varlist_add_variable(¬ification_vars, /* * the snmpTrapOID.0 variable */ objid_snmptrap, objid_snmptrap_len, /* * value type is an OID */ ASN_OBJECT_ID, /* * value contents is our notification OID */ (u_char *) trap_oid, /* * size in bytes = oid length * sizeof(oid) */ trap_oid_len * sizeof(oid)); snmp_varlist_add_variable(¬ification_vars, nodename_oid, nodename_oid_len, ASN_OCTET_STR, (const u_char *) node, strlen(node)); /* do NOT use strlen() +1 */ cl_log(LOG_INFO, "sending hbagent trap. status:%d", online); send_v2trap(notification_vars); snmp_free_varbind(notification_vars); return HA_OK; } static void usage(void) { fprintf(stderr, "Usage: hbagent [Options]\n" "Options:\n" " -d enable logging to STDERR\n" " -r SECOND set LHAHeartbeatConfigInfo to partial-mode\n" " SECOND -- time interval between update " "LHAHeartbeatConfigInfo\n" " o multiple of 5\n" " o '0' keeps initial value (not update)\n" ); } int main(int argc, char ** argv) { int ret; fd_set fdset; struct timeval tv, *tvp; #if SUPPORT_HEARTBEAT int flag, block = 0, numfds, hb_fd = 0, mem_fd = 0, debug = 0; int hb_already_dead = 0; #else int flag, block = 0, numfds, mem_fd = 0, debug = 0; #endif int cib_fd = 0; /* change this if you want to be a SNMP master agent */ int agentx_subagent=1; /* change this if you want to run in the background */ int background = 0; /* LHAHeartbeatConfigInfo partial-mode */ #if SUPPORT_HEARTBEAT int hbconfig_refresh_timing = 0; int hbconfig_refresh_cnt; #endif while ((flag = getopt(argc, argv, "dr:h")) != EOF) { int i; switch (flag) { case 'd': debug++ ; break; case 'r': /* LHAHeartbeatConfigInfo partial-mode */ i = atoi(optarg); #if SUPPORT_HEARTBEAT hbconfig_partial = 1; if (i > 0) hbconfig_refresh_timing = i / DEFAULT_TIME_OUT; else hbconfig_refresh_timing = DEFAULT_REFRESH_TIMING; #endif snmp_cache_time_out = i; break; case 'h': usage(); exit(0); default: usage(); exit(1); } } if (debug) { cl_log_enable_stderr(TRUE); snmp_enable_stderrlog(); } else { cl_log_enable_stderr(FALSE); snmp_enable_calllog(); } /* we're an agentx subagent? */ if (agentx_subagent) { /* make us a agentx client. */ netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1); } /* run in background, if requested */ if (background && netsnmp_daemonize(1, debug)) exit(1); /* initialize the agent library */ if (init_agent("LHA-agent")) { cl_log(LOG_ERR, "AgentX initialization failure. You can only run this as root. Also make sure that the master snmpd is started and is accepting AgentX connetions. The subagent will not be respawned."); return 100; } /* initialize mib code here */ #if SUPPORT_HEARTBEAT if (is_heartbeat_cluster()) { if ((ret = init_storage()) != HA_OK) { return -2; } if ((ret = init_heartbeat()) != HA_OK || (hb_fd = get_heartbeat_fd()) <=0) { return -1; } if ((ret = init_resource_table()) != HA_OK) { cl_log(LOG_ERR, "resource table initialization failure."); } ret = init_membership(); mem_fd = get_membership_fd(); if (ret != HA_OK) { cl_log(LOG_ERR, "fatal error during membership initialization. "); } } #endif #if SUPPORT_AIS if (is_openais_cluster()) { # if HAVE_CRM_CLUSTER_T crm_cluster_t crm_cluster; # endif #if SUPPORT_HEARTBEAT struct utsname name; if(uname(&name) < 0) { cl_log(LOG_ERR, "uname(2) call failed: %s", strerror(errno)); } else { myid = strdup(name.nodename); } if (myid != NULL) { myuuid = strdup(myid); } #else # if !HAVE_CRM_CLUSTER_T crm_cluster_connect(&myid, &myuuid, NULL, NULL, NULL); # else if (crm_cluster_connect(&crm_cluster)) { myid = crm_cluster.uname; myuuid = crm_cluster.uuid; } # endif #endif } #endif /* if ((ret = init_membership() != HA_OK) || (mem_fd = get_membership_fd()) <= 0) { cl_log(LOG_DEBUG, "membership initialization failure. You will not be able to view any membership information in this cluster."); } */ #if SUPPORT_HEARTBEAT if (is_heartbeat_cluster()) { /* LHAHeartbeatConfigInfo partial-mode */ if ((ret = init_hbconfig()) != HA_OK) { return -3; } init_LHAClusterInfo(); init_LHANodeTable(); init_LHAIFStatusTable(); init_LHAResourceGroupTable(); init_LHAMembershipTable(); init_LHAHeartbeatConfigInfo(); } #endif /* now implementing: hbagentv2 */ if ((ret = init_hbagentv2()) != HA_OK || (cib_fd = get_cib_fd()) <= 0) { return -4; } /* LHA-agent will be used to read LHA-agent.conf files. */ init_snmp("LHA-agent"); /* If we're going to be a snmp master agent, initial the ports */ if (!agentx_subagent) init_master_agent(); /* open the port to listen on (defaults to udp:161) */ /* In case we recevie a request to stop (kill -TERM or kill -INT) */ keep_running = 1; signal(SIGTERM, stop_server); signal(SIGINT, stop_server); snmp_log(LOG_INFO,"LHA-agent is up and running.\n"); hbagent_trap(1, myid); #if SUPPORT_HEARTBEAT hbconfig_refresh_cnt = 0; #endif /* you're main loop here... */ while(keep_running) { int save_errno; /* if you use select(), see snmp_select_info() in snmp_api(3) */ /* --- OR --- */ /* 0 == don't block */ /* agent_check_and_process(1); */ FD_ZERO(&fdset); #if SUPPORT_HEARTBEAT if (is_heartbeat_cluster()) { FD_SET(hb_fd, &fdset); numfds = hb_fd + 1; if (clmInitialized) { FD_SET(mem_fd, &fdset); if (mem_fd > hb_fd) numfds = mem_fd + 1; } } #endif FD_SET(cib_fd, &fdset); if (numfds < (cib_fd + 1)) { numfds = cib_fd + 1; } tv.tv_sec = DEFAULT_TIME_OUT; tv.tv_usec = 0; tvp = &tv; snmp_select_info(&numfds, &fdset, tvp, &block); if (block) { tvp = NULL; } else if (tvp->tv_sec == 0) { tvp->tv_sec = DEFAULT_TIME_OUT; tvp->tv_usec = 0; } ret = select(numfds, &fdset, 0, 0, tvp); save_errno=errno; if (ret < 0) { if (errno == EBADF && keep_running) { struct stat foo; /* Probably the membership layer shut down for some reason. */ if (mem_fd >= 0 && fstat(mem_fd, &foo) < 0 && errno == EBADF) { cl_log(LOG_WARNING, "membership layer shut down."); FD_CLR(mem_fd, &fdset); if (numfds == mem_fd + 1) { numfds--; } mem_fd = -1; break; } } /* error */ if (keep_running) { errno = save_errno; cl_perror("%s: select() returned an error, shutting down." , __FUNCTION__); } break; } else if (ret == 0) { /* timeout */ #if SUPPORT_HEARTBEAT if (is_heartbeat_cluster()) { ping_membership(&mem_fd); /* LHAHeartbeatConfigInfo partial-mode */ if (hbconfig_refresh_timing && ++hbconfig_refresh_cnt >= hbconfig_refresh_timing) { free_hbconfig(); init_hbconfig(); hbconfig_refresh_cnt = 0; } } #endif snmp_timeout(); goto process_pending; } #if SUPPORT_HEARTBEAT if (is_heartbeat_cluster()) { if (FD_ISSET(hb_fd, &fdset)) { /* heartbeat */ if ((ret = handle_heartbeat_msg()) == HA_FAIL) { cl_log(LOG_DEBUG, "no heartbeat. quit now."); hb_already_dead = 1; break; } } else if (clmInitialized && FD_ISSET(mem_fd, &fdset)) { /* membership events */ if ((ret = handle_membership_msg()) == HA_FAIL) { cl_log(LOG_DEBUG, "unrecoverable membership error. quit now."); break; } } else if (FD_ISSET(cib_fd, &fdset)) { /* change cib info events */ if ((ret = handle_cib_msg()) == HA_FAIL) { cl_log(LOG_DEBUG, "unrecoverable CIB error. quit now."); break; } } else { /* snmp request */ snmp_read(&fdset); } } else { if (FD_ISSET(cib_fd, &fdset)) { #else if (TRUE) { if (FD_ISSET(cib_fd, &fdset)) { #endif /* change cib info events */ if ((ret = handle_cib_msg()) == HA_FAIL) { cl_log(LOG_DEBUG, "unrecoverable CIB error. quit now."); break; } } else { /* snmp request */ snmp_read(&fdset); } } process_pending: run_alarms(); netsnmp_check_outstanding_agent_requests(); #if SUPPORT_HEARTBEAT if (is_heartbeat_cluster()) { if ((ret = handle_heartbeat_msg()) == HA_FAIL) { cl_log(LOG_DEBUG, "no heartbeat. quit now."); hb_already_dead = 1; break; } } #endif } /* at shutdown time */ hbagent_trap(0, myid); snmp_shutdown("LHA-agent"); free_hbagentv2(); if (myid != NULL) { free(myid); } if (myuuid != NULL) { free(myuuid); } #if SUPPORT_HEARTBEAT if (is_heartbeat_cluster()) { free_hbconfig(); free_storage(); if (!hb_already_dead && hb->llc_ops->signoff(hb, TRUE) != HA_OK) { cl_log(LOG_ERR, "Cannot sign off from heartbeat."); cl_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb)); exit(10); } if (hb->llc_ops->delete(hb) != HA_OK) { cl_log(LOG_ERR, "Cannot delete API object."); cl_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb)); exit(11); } } #endif return 0; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/hbagent.h000066400000000000000000000052661211477743100237440ustar00rootroot00000000000000/* * hbagent.h: heartbeat snmp subagnet header file. * * Copyright (c) 2004 Intel Corp. * * Author: Zou Yixiong (yixiong.zou@intel.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef __hasubagent_h__ #define __hasubagent_h__ #include #ifdef HAVE_STDINT_H #include #endif #include #if SUPPORT_HEARTBEAT #include "saf/ais.h" #endif #include "snmp-config-resolve.h" #include #define CACHE_TIME_OUT 5 #define LHAAGENTID "lha-snmpagent" #define DEFAULT_TIME_OUT 5 /* default timeout value for snmp in sec. */ typedef enum lha_group { LHA_CLUSTERINFO, LHA_NODEINFO, LHA_IFSTATUSINFO, LHA_RESOURCEINFO, LHA_MEMBERSHIPINFO, LHA_HBCONFIGINFO, } lha_group_t; typedef enum lha_attribute { /* LHA_CLUSTERINFO stats */ TOTAL_NODE_COUNT, LIVE_NODE_COUNT, RESOURCE_GROUP_COUNT, CURRENT_NODE_ID, /* LHA_RESOURCEINFO stats */ RESOURCE_STATUS, } lha_attribute_t; int get_int_value(lha_group_t group, lha_attribute_t attr, size_t index, uint32_t * value); int get_str_value(lha_group_t group, lha_attribute_t attr, size_t index, char * * value); int clusterinfo_get_int_value(lha_attribute_t attr, size_t index, uint32_t * value); int rsinfo_get_int_value(lha_attribute_t attr, size_t index, uint32_t * value); /* LHAHeartbeatConfigInfo partial-mode */ typedef enum lha_hbconfig { LHA_CONF_HBVERSION, LHA_CONF_KEEPALIVE, LHA_CONF_DEADTIME, LHA_CONF_DEADPING, LHA_CONF_WARNTIME, LHA_CONF_INITDEAD, LHA_CONF_BAUDRATE, LHA_CONF_AUTOFAIL, LHA_CONF_STONITH, LHA_CONF_STONITHHOST, LHA_CONF_RESPAWN, LHA_CONF_END } lha_hbconfig_t; int hbconfig_get_str(lha_hbconfig_t attr_no, char * * value); GPtrArray * get_hb_info(lha_group_t group); struct hb_nodeinfo { size_t id; char * name; uint32_t type; uint32_t status; size_t ifcount; cl_uuid_t uuid; }; struct hb_ifinfo { size_t id; size_t nodeid; char * name; char * node; uint32_t status; }; struct hb_rsinfo { size_t id; size_t masternodeid; char * resource; uint32_t status; }; #endif /* __hasubagent_h__ */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/hbagentv2.c000066400000000000000000000502371211477743100242050ustar00rootroot00000000000000#include "crm/crm.h" #include "crm/cib.h" #include "crm/pengine/status.h" #include "crm/msg_xml.h" #include "crm/transition.h" #ifdef SUPPORT_AIS #undef SUPPORT_AIS #endif #ifdef SUPPORT_HEARTBEAT #undef SUPPORT_HEARTBEAT #endif #include #include "hbagent.h" #include "hbagentv2.h" #if SUPPORT_HEARTBEAT #include "hb_api.h" #include "heartbeat.h" #endif #include "clplumbing/cl_log.h" #include "clplumbing/coredumps.h" #include #include #include #include #include #include #include "LHAResourceTable.h" #include "LHAResourceStatusUpdate.h" #if !HAVE_CRM_DATA_T typedef xmlNode crm_data_t; #endif #if !HAVE_PCMK_STRERROR # define pcmk_strerror(rc) cib_error2string(rc) #endif #ifndef F_CIB_UPDATE_RESULT # define F_CIB_UPDATE_RESULT "cib_update_result" #endif #ifndef EXECRA_OK # define EXECRA_OK 0 #endif /* * Agent MIB value conversion macros from the internal value */ /* ref. crm/pengine/complex.h:enum pe_obj_types */ #define PE_OBJ_TYPES2AGENTTYPE(variant) ((int)(variant) + 1) /* ref. crm/pengine/common.h:enum rsc_role_e */ #define RSC_ROLE_E2AGENTSTATUS(role) ((int)(role)) /* the value is identical */ /* need more than (RID_LEN + sizeof(CRMD_ACTION_xxx) + sizeof(rc_code) */ #define MAX_OP_STR_LEN 256 /* need more than sizeof(rc_code). ref. UNIFORM_RET_EXECRA in lrm/raexec.h */ #define MAX_RCCODE_STR_LEN 4 static cib_t *cib_conn = NULL; static GPtrArray * gResourceTableV2 = NULL; static int err_occurs = 0; /* the flag which means an error occurs in callback func. */ extern const char *myid; extern const char *myuuid; #if !HAVE_DECL_CRM_CONCAT static char * crm_concat(const char *prefix, const char *suffix, char join) { int len = 0; char *new_str = NULL; CRM_ASSERT(prefix != NULL); CRM_ASSERT(suffix != NULL); len = strlen(prefix) + strlen(suffix) + 2; new_str = calloc(1, (len)); sprintf(new_str, "%s%c%s", prefix, join, suffix); new_str[len - 1] = 0; return new_str; } #endif /* for debug */ void debugPrint(crm_data_t *msg, int depth, FILE *fp); /** * Initialize of resource table v2. */ int init_resource_table_v2(void) { if (gResourceTableV2) { free_resource_table_v2(); } return HA_OK; } /** * This is the main function to update resource table v2. * Return the number of resources. */ static int update_resources_recursively(GListPtr reslist, GListPtr nodelist, int index) { GListPtr gIter1 = NULL; if (reslist == NULL) { return index; } /* * Set resource info to resource table v2 from data_set, * and add it to Glib's array. */ for(gIter1 = reslist; gIter1 != NULL; gIter1 = gIter1->next) { resource_t *rsc = gIter1->data; GListPtr gIter2 = NULL; cl_log(LOG_DEBUG, "resource %s processing.", rsc->id); for(gIter2 = nodelist; gIter2 != NULL; gIter2 = gIter2->next) { node_t *node = gIter2->data; struct hb_rsinfov2 *rsinfo; enum rsc_role_e rsstate; rsinfo = (struct hb_rsinfov2 *) malloc(sizeof(struct hb_rsinfov2)); if (!rsinfo) { cl_log(LOG_CRIT, "malloc resource info v2 failed."); return HA_FAIL; } rsinfo->resourceid = strdup(rsc->id); rsinfo->type = PE_OBJ_TYPES2AGENTTYPE(rsc->variant); /* using a temp var to suppress casting warning of the compiler */ rsstate = rsc->fns->state(rsc, TRUE); { GListPtr running_on_nodes = NULL; rsc->fns->location(rsc, &running_on_nodes, TRUE); if (pe_find_node_id( running_on_nodes, node->details->id) == NULL) { /* * if the resource is not running on current node, * its status is "stopped(1)". */ rsstate = RSC_ROLE_STOPPED; } g_list_free(running_on_nodes); } rsinfo->status = RSC_ROLE_E2AGENTSTATUS(rsstate); rsinfo->node = strdup(node->details->uname); if (is_not_set(rsc->flags, pe_rsc_managed)) { rsinfo->is_managed = LHARESOURCEISMANAGED_UNMANAGED; } else { rsinfo->is_managed = LHARESOURCEISMANAGED_MANAGED; } /* get fail-count from */ { char *attr_name = NULL; char *attr_value = NULL; crm_data_t *tmp_xml = NULL; attr_name = crm_concat("fail-count", rsinfo->resourceid, '-'); attr_value = g_hash_table_lookup(node->details->attrs, attr_name); rsinfo->failcount = crm_parse_int(attr_value, "0"); free(attr_name); free_xml(tmp_xml); } if (rsc->parent != NULL) { rsinfo->parent = strdup(rsc->parent->id); } else { rsinfo->parent = strdup(""); } /* * if the resource stops, and its fail-count is 0, * don't list it up. */ if (rsinfo->status != LHARESOURCESTATUS_STOPPED || rsinfo->failcount > 0) { rsinfo->index = index++; g_ptr_array_add(gResourceTableV2, (gpointer *)rsinfo); } else { free(rsinfo->resourceid); free(rsinfo->node); free(rsinfo->parent); free(rsinfo); } } /* end slist_iter(node) */ /* add resources recursively for group/clone/master */ index = update_resources_recursively(rsc->children, nodelist, index); } /* end slist_iter(rsc) */ return index; } /** * Send query to the CIB and update the information of resource table v2. */ int update_resource_table_v2(void) { crm_data_t *cib_object = NULL; pe_working_set_t data_set; int rc = 0; int options = cib_scope_local|cib_sync_call; int index; if (!gResourceTableV2) { cl_log(LOG_ERR, "resource table v2 is NULL."); return HA_FAIL; } free_resource_table_v2(); rc = cib_conn->cmds->query(cib_conn, NULL, &cib_object, options); if (rc != 0) { cl_log(LOG_ERR, "CIB query failed: %s", pcmk_strerror(rc)); return HA_FAIL; } if (cib_object == NULL) { cl_log(LOG_ERR, "CIB query failed: empty result."); return HA_FAIL; } cl_log(LOG_DEBUG, "CIB query done. Updating resource table v2."); set_working_set_defaults(&data_set); data_set.input = cib_object; /* parse cib xml info (cib_object). */ cluster_status(&data_set); index = update_resources_recursively(data_set.resources, data_set.nodes, 1); if (index == HA_FAIL) { cl_log(LOG_ERR, "Update resources failed."); data_set.input = NULL; cleanup_calculations(&data_set); free_xml(cib_object); return HA_FAIL; } cl_log(LOG_DEBUG, "Updated %d resources.", index-1); data_set.input = NULL; cleanup_calculations(&data_set); free_xml(cib_object); return HA_OK; } /** * Update resource table v2 and return it's pointer. * To get latest information of resources. * This function is called in LHAResourceTable_load(), * only when snmp cache timeout occurs. */ GPtrArray * get_resource_table_v2(void) { update_resource_table_v2(); return gResourceTableV2; } /** * Free resource table v2. */ void free_resource_table_v2(void) { struct hb_rsinfov2 *resource; if (!gResourceTableV2) { return; } cl_log(LOG_DEBUG, "Freeing %d resources.", gResourceTableV2->len); while (gResourceTableV2->len) { resource = (struct hb_rsinfov2 *) g_ptr_array_remove_index_fast(gResourceTableV2, 0); free(resource->resourceid); free(resource->node); free(resource->parent); free(resource); } return; } /** * This is the main function to send a trap to tell a resource's status is changed. * This function is called when a change occurs on the cib information. * First, it parses a received xml message, and if the msg tells that the status of * a resource changes, it sends a trap to SNMP manager via Net-SNMP daemon. * Note1: It sends a trap when the resouce [stopped|started|been Slave|been Master]. * And it sends a trap only when the execution of RA method is succeeded. * Note2: If an error occurs in this function, set the variable "err_occurs" to tell * that to the handler. (see: handle_cib_msg()) */ static void hbagentv2_update_diff(const char *event, crm_data_t *msg) { /*implement parsing the diff and send a trap */ /* const char *op = NULL; */ crm_data_t *diff = NULL; const char *set_name = NULL; crm_data_t *change_set = NULL; crm_data_t *lrm_rsc = NULL; const char *node_id = NULL; const char *rsc_id = NULL; const char *rsc_op_id = NULL; const char *rc_code = NULL; const char *t_magic = NULL; const char *operation = NULL; char tmp_op_str[MAX_OP_STR_LEN]; char tmp_rc_str[MAX_RCCODE_STR_LEN]; char *tmp = tmp_op_str; #if HAVE_DECL___XML_NEXT crm_data_t *node_state = NULL; #endif /* Initialize err flag. */ err_occurs = 0; if (!msg) { cl_log(LOG_ERR, "cib message is NULL."); err_occurs = 1; return; } /* op = cl_get_string(msg, F_CIB_OPERATION); */ diff = get_message_xml(msg, F_CIB_UPDATE_RESULT); if (!diff) { cl_log(LOG_ERR, "update result is NULL."); return; } /* for debug */ /* { FILE * fp; fp = fopen("/tmp/msgdiff.out", "a"); debugPrint(diff, 0, fp); fclose(fp); } */ /* * start to get the following information from difference of cib xml. * */ /* get the head pointer of */ set_name = "diff-added"; /* we need the cib info only which have been updated. */ change_set = find_xml_node(diff, set_name, FALSE); change_set = find_xml_node(change_set, XML_TAG_CIB, FALSE); change_set = find_xml_node(change_set, XML_CIB_TAG_STATUS, FALSE); if (!change_set) { /* There is no information of */ free_xml(diff); return; } #if !HAVE_DECL___XML_NEXT xml_child_iter_filter( change_set, node_state, XML_CIB_TAG_STATE, #else for(node_state = __xml_first_child(change_set); node_state != NULL; node_state = __xml_next(node_state)) { crm_data_t *lrm_rsc_op = NULL; if(STRNCMP_CONST((const char *)node_state->name, XML_CIB_TAG_STATE) != 0) { continue; } #endif /* get the node id at which the resources changed */ node_id = crm_element_value(node_state, XML_ATTR_ID); if (!node_id) { /* There is no information of */ free_xml(diff); return; } if (myuuid != NULL && STRNCMP_CONST(node_id, myuuid) != 0) { /* This change is not at my node */ free_xml(diff); return; } /* get the head pointer of */ lrm_rsc = find_xml_node(node_state, XML_CIB_TAG_LRM, FALSE); lrm_rsc = find_xml_node(lrm_rsc, XML_LRM_TAG_RESOURCES, FALSE); if (!lrm_rsc) { /* There is no information of */ free_xml(diff); return; } lrm_rsc = find_xml_node(lrm_rsc, XML_LRM_TAG_RESOURCE, FALSE); if (!lrm_rsc) { /* There is no information of */ free_xml(diff); return; } /* * now, get the head pointer of , * and parse it's resource id, operation, and rc_code. */ #if !HAVE_DECL___XML_NEXT xml_child_iter_filter( lrm_rsc, lrm_rsc_op, XML_LRM_TAG_RSC_OP, #else for(lrm_rsc_op = __xml_first_child(lrm_rsc); lrm_rsc_op != NULL; lrm_rsc_op = __xml_next(lrm_rsc_op)) { if(STRNCMP_CONST((const char *)lrm_rsc_op->name, XML_LRM_TAG_RSC_OP) != 0) { continue; } #endif rsc_id = crm_element_value(lrm_rsc, XML_ATTR_ID); operation = crm_element_value(lrm_rsc_op, XML_LRM_ATTR_TASK); rc_code = crm_element_value(lrm_rsc_op, XML_LRM_ATTR_RC); rsc_op_id = crm_element_value(lrm_rsc_op, XML_ATTR_ID); t_magic = crm_element_value(lrm_rsc_op, XML_ATTR_TRANSITION_MAGIC); #if !HAVE_DECL___XML_NEXT ); /* end of xml_child_iter_filter(lrm_rsc) */ ); /* end of xml_child_iter_filter(change_set) */ #else } } #endif /* * Sometimes, the difference of cib infomation doesn't include operation and rc_code. * Like when you move resources by hand (ex. crm_resource -M, or -F), or * resources move according to and so on. * In these cases, get them from other attributes' value. */ /* get operation from lrm_rsc_op's id */ if (!operation) { strcpy(tmp_op_str, rsc_op_id); tmp = strrchr(tmp_op_str, '_'); *tmp = '\0'; operation = strrchr(tmp_op_str, '_') + 1; } /* get rc_code from transition magic number */ if (!rc_code) { if (t_magic != NULL) { int transition_id = -1; int action_id = -1; int status = -1; int op_rc = -1; int target_rc = -1; char *uuid = NULL; if (!decode_transition_magic( t_magic, &uuid, &transition_id, &action_id, &status, &op_rc, &target_rc)) { cl_log(LOG_ERR, "decode_transition_magic() is failed."); free_xml(diff); return; } free(uuid); sprintf(tmp_rc_str, "%d\n", op_rc); rc_code = tmp_rc_str; } } /* now, send a trap. */ if (operation != NULL && rc_code != NULL) { if (atoi(rc_code) == EXECRA_OK) { struct hb_rsinfov2 resource; resource.resourceid = strdup(rsc_id); #if SUPPORT_HEARTBEAT if (is_heartbeat_cluster()) { resource.node = strdup(myid); } else { resource.node = strdup(node_id); } #else resource.node = strdup(node_id); #endif /* LHAResourceStatus is ... */ if (safe_str_eq(operation, CRMD_ACTION_STOP)) { /* 1: Stopped */ resource.status = LHARESOURCESTATUS_STOPPED; } else if (safe_str_eq(operation, CRMD_ACTION_START)) { /* 2: Started */ resource.status = LHARESOURCESTATUS_STARTED; } else if (safe_str_eq(operation, CRMD_ACTION_DEMOTE)) { /* 3: Slave */ resource.status = LHARESOURCESTATUS_SLAVE; } else if (safe_str_eq(operation, CRMD_ACTION_PROMOTE)) { /* 4: Master */ resource.status = LHARESOURCESTATUS_MASTER; } else { /* other action. send no trap. */ free(resource.resourceid); free(resource.node); free_xml(diff); return; } send_LHAResourceStatusUpdate_trap(&resource); free(resource.resourceid); free(resource.node); } else { /* operation does not succeed. */ /* do nothing (for the present) */ } } free_xml(diff); return; } /** * Initialization of connection to the CIB. * Have a connection made newly. And set callback function, hbagentv2_update_diff(), * that is called when cib infomation message changes. */ static int init_cib(void) { int rc; cib_conn = cib_new(); if (cib_conn == NULL) { cl_log(LOG_ERR, "CIB connection initialization failed."); return HA_FAIL; } rc = cib_conn->cmds->signon(cib_conn, LHAAGENTID, cib_query); if (rc != 0) { cl_log(LOG_ERR, "CIB connection signon failed."); return HA_FAIL; } rc = cib_conn->cmds->add_notify_callback(cib_conn, T_CIB_DIFF_NOTIFY, hbagentv2_update_diff); if (rc != 0) { cl_log(LOG_ERR, "CIB connection adding callback failed."); return HA_FAIL; } cl_log(LOG_INFO, "CIB connection initialization completed."); return HA_OK; } /** * Sign off and clean the connection to the CIB. */ static void free_cib(void) { if (cib_conn) { if (cib_conn->cmds->signoff(cib_conn) != 0) { cl_log(LOG_WARNING, "CIB connection signoff failed(ignored)."); } cib_delete(cib_conn); cib_conn = NULL; } return; } /** * Returns a file discripter of the connection to the CIB. * -1 : error occurs. * else : cib conn's fd. */ int get_cib_fd(void) { int fd; if (!cib_conn) { cl_log(LOG_ERR, "CIB is not initialized."); return -1; } if ((fd = cib_conn->cmds->inputfd(cib_conn)) < 0) { cl_log(LOG_ERR, "Can not get CIB inputfd."); return -1; } return fd; } /** * Handler of cib information message changes. * Set this function in the select loop to send a trap. */ /* TODO: this prototype is not exported in any headers */ /* Beekhof: Uh yeah, for a _reason_ */ #if !HAVE_CRM_IPC_NEW gboolean cib_native_dispatch(IPC_Channel *channel, gpointer user_data); IPC_Channel *cib_native_channel(cib_t* cib); #else bool cib_native_dispatch(cib_t * cib); #endif int handle_cib_msg(void) { /* call callback function. */ #if !HAVE_CRM_IPC_NEW if (!cib_native_dispatch(cib_native_channel(cib_conn), cib_conn)) { #else if (!cib_native_dispatch(cib_conn)) { #endif cl_log(LOG_ERR, "cib_native_dispatch() failed."); return HA_FAIL; } /* check if an error occurs in callback function. */ if (err_occurs) { return HA_FAIL; } return HA_OK; } /** * Initialization of hbagentv2. * hbagentv2 is agent which keeps watching on operation of resources. * (see: LHAResourceTable and LHAResourceStatusUpdate) */ int init_hbagentv2(void) { int ret; gResourceTableV2 = g_ptr_array_new(); if (gResourceTableV2 == NULL) { cl_log(LOG_ERR, "Storage allocation failure for hbagentv2."); return HA_FAIL; } ret = init_cib(); if (ret != HA_OK) { cl_log(LOG_ERR, "init_cib() failed."); return ret; } ret = init_resource_table_v2(); if (ret != HA_OK) { cl_log(LOG_ERR, "resource table v2 initialization failure."); } init_LHAResourceTable(); cl_log(LOG_INFO, "hbagentv2 initialization completed."); return HA_OK; } /** * Free and clear resource table v2 and cib connection. * Disposer which is called before stopping agent. */ void free_hbagentv2(void) { free_resource_table_v2(); g_ptr_array_free(gResourceTableV2, 1); gResourceTableV2 = NULL; free_cib(); } /* * debug print for cib info. */ void debugPrint(crm_data_t *msg, int depth, FILE *fp) { #if 0 /* non functional for crm_data_t == xmlNode */ int i; if (msg == NULL) { return; } if (fp == NULL) { fp = stdout; } for (i = 0; i < msg->nfields; i++) { int j; for (j = 0; j < depth; j++) { fprintf(fp, " "); fflush(fp); } if (msg->types[i] == FT_STRING) { fprintf(fp, "[%2d] %s = %s\n", i, msg->names[i], (char*)msg->values[i]); fflush(fp); } else if (msg->types[i] == FT_STRUCT || msg->types[i] == FT_UNCOMPRESS) { fprintf(fp, "[%2d] %s {\n", i, msg->names[i]); fflush(fp); debugPrint(msg->values[i], depth + 1, fp); for (j = 0; j < depth; j++) { fprintf(fp, " "); fflush(fp); } fprintf(fp, "}\n"); fflush(fp); } else { fprintf(fp, "[%2d] %s is [%d] TYPE.\n", i, msg->names[i], msg->types[i]); fflush(fp); } } #endif } /** * Emacs stuff: * Local Variables: * mode: C * c-basic-offset: 4 * indent-tabs-mode: nil * End: * */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/hbagentv2.h000066400000000000000000000010021211477743100241740ustar00rootroot00000000000000#ifndef _HBAGENTV2_H #define _HBAGENTV2_H struct hb_rsinfov2 { size_t index; char * resourceid; uint32_t type; uint32_t status; char * node; uint32_t is_managed; uint32_t failcount; char * parent; }; int init_hbagentv2(void); void free_hbagentv2(void); int get_cib_fd(void); int handle_cib_msg(void); int init_resource_table_v2(void); int update_resource_table_v2(void); GPtrArray *get_resource_table_v2(void); void free_resource_table_v2(void); #endif /* _HBAGENTV2_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/snmp_subagent/snmp-config-resolve.h000066400000000000000000000027011211477743100262200ustar00rootroot00000000000000/* * Copyright (c) 2004 Intel Corp. * * Author: Zou Yixiong (yixiong.zou@intel.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef __SNMP_CONFIG_RESOLVE_H #define __SNMP_CONFIG_RESOLVE_H /* the following undef is needed because these values are defined in both the config.h for linux-ha and net-snmp. So they created a conflict. To resolve this, we include the net-snmp-config.h first, and include this file before we include other heartbeat header files. */ #ifdef PACKAGE_BUGREPORT #undef PACKAGE_BUGREPORT #endif #ifdef PACKAGE_NAME #undef PACKAGE_NAME #endif #ifdef PACKAGE_STRING #undef PACKAGE_STRING #endif #ifdef PACKAGE_TARNAME #undef PACKAGE_TARNAME #endif #ifdef PACKAGE_VERSION #undef PACKAGE_VERSION #endif #endif /* __SNMP_CONFIG_RESOLVE_H */ pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/000077500000000000000000000000001211477743100214525ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/.cvsignore000066400000000000000000000000601211477743100234460ustar00rootroot00000000000000Makefile Makefile.in linuxha-adapter testrun.sh pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/Makefile.am000066400000000000000000000107021211477743100235060ustar00rootroot00000000000000# Linux-HA: TSA plugin # # Author: Jia Ming Pan # Copyright (c) 2006 International Business Machines # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # TSA_LIBDIR=$(TSA_DIR)/sam/lib CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar:${TSA_LIBDIR}/eezadapter.jar:${TSA_LIBDIR}/jlanclient.jar:${TSA_LIBDIR}/eezcfghelp.jar:${TSA_LIBDIR}/jlog.jar:${TSA_LIBDIR}/eezmsgs.jar:${TSA_LIBDIR}/log.jar:${TSA_LIBDIR}/eezmsgs_lang.jar:${TSA_LIBDIR}/remoteaccess.jar:${TSA_LIBDIR}/eezpolldr.jar:${TSA_LIBDIR}/samfla.jar:${TSA_LIBDIR}/eezsdk.jar:${TSA_LIBDIR}/sammsgs.jar:${TSA_LIBDIR}/eezutils.jar:${TSA_LIBDIR}/sampolicy.jar:${TSA_LIBDIR}/evd.jar:${TSA_LIBDIR}/samrmc.jar:${TSA_LIBDIR}/jffdc.jar:${TSA_LIBDIR}/ssh.jar:${TSA_LIBDIR}/jhall.jar:${TSA_LIBDIR}/tivolicommondir.jar INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_builddir)/linux-ha -I$(top_srcdir)/linux-ha \ -I$(top_builddir)/libltdl -I$(top_srcdir)/libltdl \ -I$(CMPI_HEADER_PATH) COMMONLIBS = $(top_builddir)/lib/clplumbing/libplumb.la \ $(top_builddir)/lib/hbclient/libhbclient.la \ $(top_builddir)/membership/ccm/libccmclient.la \ $(top_builddir)/membership/ccm/libclm.la \ $(GLIBLIB) LRM_DIR = lrm MGMTLIBS = $(top_builddir)/mgmt/daemon/libhbmgmt.la \ $(top_builddir)/lib/mgmt/libhbmgmtcommon.la \ $(top_builddir)/lib/$(LRM_DIR)/liblrm.la hamgmtlibdir = /usr/lib hamgmtlib_LTLIBRARIES = liblhamgmt.la jardir = $(TSA_LIBDIR) jar_DATA = linuxhafla.jar swig_gen_files = ${JAVA_PACKAGE_DIR}/LHAMgmtLibJNI.java \ ${JAVA_PACKAGE_DIR}/LHAMgmtLib.java \ ha_mgmt_client_wrap.c JAVA_PACKAGE_DIR = $(top_srcdir)/tsa_plugin/org/linuxha/sam/plugin java_sources = ${JAVA_PACKAGE_DIR}/LHAMgmtLibJNI.java \ ${JAVA_PACKAGE_DIR}/LHANativeResource.java \ ${JAVA_PACKAGE_DIR}/LHANodeResource.java \ ${JAVA_PACKAGE_DIR}/LHAClusterManager.java \ ${JAVA_PACKAGE_DIR}/LHAOrderConstraint.java \ ${JAVA_PACKAGE_DIR}/LHAColocationConstraint.java\ ${JAVA_PACKAGE_DIR}/LHAResource.java \ ${JAVA_PACKAGE_DIR}/LHAConstraint.java \ ${JAVA_PACKAGE_DIR}/LHAResourceGroup.java \ ${JAVA_PACKAGE_DIR}/LHALocationConstraint.java\ ${JAVA_PACKAGE_DIR}/LinuxHAFLA.java \ ${JAVA_PACKAGE_DIR}/LHANativeClient.java \ ${JAVA_PACKAGE_DIR}/LHACLIClient.java \ ${JAVA_PACKAGE_DIR}/LHAEventdClient.java \ ${JAVA_PACKAGE_DIR}/LinuxHAPlugin.java \ ${JAVA_PACKAGE_DIR}/LHAMgmtLib.java \ ${JAVA_PACKAGE_DIR}/Utilities.java EXTRA_DIST = ha_mgmt_client.i ${swig_gen_files}: ha_mgmt_client.i $(SWIG) -java -package org.linuxha.sam.plugin -outdir org/linuxha/sam/plugin/ $^ linuxhafla.jar:${java_sources} ${JAVA_HOME}/bin/javac -classpath ${CLASSPATH} ${JAVA_PACKAGE_DIR}/*.java ${JAVA_HOME}/bin/jar cf linuxhafla.jar ${JAVA_PACKAGE_DIR}/*.class liblhamgmt_la_SOURCES = ha_mgmt_client_wrap.c ha_mgmt_client.c ha_mgmt_client.h \ ha_tsa_common.h ha_tsa_common.c liblhamgmt_la_CFLAGS = $(INCLUDES) -I$(top_builddir)/include -w liblhamgmt_la_LIBADD = $(COMMONLIBS) $(MGMTLIBS) tsadir = $(libdir)/@HB_PKG@ tsa_PROGRAMS = tsa_eventd tsa_eventd_SOURCES = tsa_eventd.c ha_tsa_common.c tsa_eventd_LDADD = $(COMMONLIBS) $(MGMTLIBS) cleancore: rm -rf core.* javacore* CLEANFILES=org/linuxha/sam/plugin/*.class *.jar ${swig_gen_files} clidir = $(libdir)/@HB_PKG@ cli_PROGRAMS = tsa_hacli tsa_hacli_SOURCES = tsa_hacli.c ha_tsa_common.c tsa_hacli_LDADD = $(COMMONLIBS) $(MGMTLIBS) adapterdir = $(libdir)/@HB_PKG@ adapter_SCRIPTS = linuxha-adapter noinst_PROGRAMS = dummy dummy_SOURCES = dummy.c dummy_LDADD = liblhamgmt.la pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/README000066400000000000000000000052431211477743100223360ustar00rootroot00000000000000linux-ha plugin for TSA README 1. REQUIREMENTS Compiling the TSA plugin requires various software packages. First of all you need to install the Java SDK software. You also need the TSA software including the rsct, sam and sam.adapter. Although in theory the plugin only depends on the sam.adapter, not installing the sam package will prevent you from installing the sam.adapter package due to the dependency between the sam.adater RPM and the sam RPM. Therefor you might have to install all of them. The SWIG is also used to generate the interface files at the compling time. Running the TSA plugin requires the Java runtime environment and the sam.adapater package. 2. COMPILING THE PLUGIN To build the TSA plugin, apply the --enable-tsa-plugin option: ./ConfigureMe bootstrap --enable-tsa-plugin=yes Options --with-java-home and --with-tsa-dir and optional. The --with-java-home option specifies the Java sdk directory and the --with-tsa-dir option specifies the TSA directory. If they are not presented, the configuration will try to find the Java sdk directory and set the TSA directory to /opt/IBM/tsamp. By default, the TSA software is installed to /opt/IBM/tsamp. So usually you don't need the --with-tsa-dir option but you often need to present the --with-java-home option. For example: ./ConfigureMe bootstrap --enable-tsa-plugin=yes \ --with-java-home=/opt/IBMJava2-141 3. CONFIGURATION First, you need to add the apiauth directives as follows to the ha.cf to allow the plugin to sign on to heartbeat: apiauth tsa uid=root gid=root apiauth tsad uid=root gid=root Besides, you need to edit the plugin config file: /etc/opt/IBM/tsamp/sam/cfg/sam.adapter.plugin.properties and set the value of plugin-impl-class to org.linuxha.sam.plugin.LinuxHAPlugin. For example: plugin-impl-class = org.linuxha.sam.plugin.LinuxHAPlugin This tells the adapater to use the linux-ha plugin. 4. START AND STOP THE PLUGIN To start the plugin: /usr/lib/heartbeat/linuxha-adapter start This will start the tsa_eventd and the adapter in order. To stop the plugin: /usr/lib/heartbeat/linuxha-adapter stop This will stop the adapter and the tsa_eventd in order. Notice: linuxha-adapter is modified and simplified from the sam adapter script /usr/bin/samadapter. If linuxha-adapter does not work. You may want to try the original one: cp /usr/bin/samadapter /usr/bin/linuxha-samadapter then edit /usr/bin/linuxha-samadapter and append ":$plib/linuxhafla.jar" to the end of line 365. This tells the adapter to load the linux-ha plugin when it starts. You should start or stop the tsa_eventd manually if you use the original samadapter. pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/dummy.c000066400000000000000000000027521211477743100227570ustar00rootroot00000000000000/* * dummy.c: dummy * * Author: Jia Ming Pan * Copyright (c) 2006 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ha_mgmt_client.h" #define MAX_CMD_LEN 1024 int main(int argc, char *argv[]) { char *result; init_logger("dummy"); result = process_cmnd_eventd("hb_config"); printf("%s", result); return 0; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/ha_mgmt_client.c000066400000000000000000000155121211477743100245740ustar00rootroot00000000000000/* * ha_mgmt_client.c: functions called by JAVA * * Author: Jia Ming Pan * Copyright (c) 2006 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ha_mgmt_client.h" #include "ha_tsa_common.h" #define CMD_SUBSCRIBE_EVENT "cmd_subscribe_event" #define IPC_PATH_ATTR "path" /* pathname attribute */ #define TSA_CMDPATH HA_VARRUNDIR"/heartbeat/tsa_eventd" #define TSA_HA_CLI HA_LIBHBDIR"/tsa_hacli" /*FIXME: remove hardcode pathname */ #define HB_SCRIPT "/etc/init.d/heartbeat" static IPC_Channel* eventd_signon(void); static int eventd_signoff(IPC_Channel*); static IPC_Channel* eventd_signon () { GHashTable* eventd_chan_attrs; IPC_Channel * ipc_chan; char path[] = IPC_PATH_ATTR; char cmd_path[] = TSA_CMDPATH; /* create the command ipc channel to eventd*/ eventd_chan_attrs = g_hash_table_new(g_str_hash, g_str_equal); g_hash_table_insert(eventd_chan_attrs, path, cmd_path); ipc_chan = ipc_channel_constructor(IPC_ANYTYPE, eventd_chan_attrs); g_hash_table_destroy(eventd_chan_attrs); if ( ipc_chan == NULL ){ eventd_signoff(ipc_chan); cl_log(LOG_WARNING, "eventd_signon: can not connect to eventd channel"); return NULL; } if ( ipc_chan->ops->initiate_connection(ipc_chan) != IPC_OK) { eventd_signoff(ipc_chan); cl_log(LOG_WARNING, "eventd_signon: can not initiate connection"); return NULL; } return ipc_chan; } static int eventd_signoff (IPC_Channel * ipc_chan) { if (ipc_chan) { if (IPC_ISWCONN(ipc_chan)) { ipc_chan->ops->destroy(ipc_chan); } ipc_chan = NULL; } return HA_OK; } /* wait_for_events: block until an event received, called by Java code */ char * wait_for_events(void) { static char buf[1024]; /* to avoid memory leak */ struct ha_msg *msg = NULL, *cmd = NULL; IPC_Channel * ipc_chan; while ( (ipc_chan = eventd_signon()) == NULL ) { sleep(3); } if ( ( cmd = ha_msg_new(1) ) == NULL ) { cl_log(LOG_ERR, "%s: alloc msg failed.", __FUNCTION__); goto exit; } ha_msg_add(cmd, "cmd", CMD_SUBSCRIBE_EVENT); if ( msg2ipcchan(cmd, ipc_chan) != HA_OK ) { cl_log(LOG_ERR, "%s: send msg to ipchan failed.", __FUNCTION__); } msg = msgfromIPC(ipc_chan, MSG_ALLOWINTR); ha_msg_del(cmd); exit: eventd_signoff(ipc_chan); if ( msg ) { strncpy(buf, ha_msg_value(msg, "event"), 1024); ha_msg_del(msg); return buf; } return NULL; } void clLog(int priority, const char* logs) { init_logger("TSA"); cl_log(priority, "%s", logs); } void start_heartbeat(const char* node) { char * ssh_path = NULL; int rc, len; ssh_path = run_shell_cmnd("which ssh", &rc, &len); if ( ssh_path == NULL ) { return; } ssh_path[strlen(ssh_path) - 1] = '\0'; if ( fork() == 0 ) { char cmd[1024]; snprintf(cmd, 1024, "%s %s \"%s start\"", ssh_path, node, HB_SCRIPT); if (system(cmd) != 0) { cl_log(LOG_ERROR, "%s: system(%s) returned non-zero" , __FUNCTION__, cmd); } } free(ssh_path); } void stop_heartbeat(const char* node) { char * ssh_path = NULL; int rc, len; ssh_path = run_shell_cmnd("which ssh", &rc, &len); if ( ssh_path == NULL ) { return; } ssh_path[strlen(ssh_path) - 1] = '\0'; if ( fork() == 0 ) { char cmd[1024]; snprintf(cmd, 1024, "%s %s \"%s start\"", ssh_path, node, HB_SCRIPT); if (system(cmd) != 0) { cl_log(LOG_ERRROR, "%s: system(%s) failed.", __FUNCTION__ , cmd); } } free(ssh_path); } /* native way: talk to library with JNI */ char* process_cmnd_native(const char* cmd) { static char buf[1024]; /* to avoid memory leak */ char *msg = NULL, *result = NULL, **cmd_args = NULL; int i, len; init_logger("TSA"); init_mgmt_lib("tsa", ENABLE_LRM|ENABLE_CRM|ENABLE_HB|CACHE_CIB); cl_log(LOG_DEBUG, "%s: begin.", __FUNCTION__); /* cl_log(LOG_INFO, "%s: cmd: %s", __FUNCTION__, cmd); */ cmd_args = split_string(cmd, &len, " "); if ( cmd_args == NULL ) { cl_log(LOG_INFO, "%s: cmd_args is NULL.", __FUNCTION__); final_mgmt_lib(); return NULL; } msg = mgmt_new_msg(cmd_args[0], NULL); for(i = 1; i < len; i++ ) { msg = mgmt_msg_append(msg, cmd_args[i]); } cl_log(LOG_DEBUG, "process_command: [%s}", msg); result = process_msg(msg); cl_log(LOG_DEBUG, "process_command: [%s] => [%s]", msg, result); mgmt_del_msg(msg); free_array((void**)cmd_args, len); if ( result == NULL ) { cl_log(LOG_ERR, "%s: end. result is NULL.", __FUNCTION__); final_mgmt_lib(); return NULL; } strncpy(buf, result, 1024); mgmt_del_msg(result); cl_log(LOG_DEBUG, "%s: end.", __FUNCTION__); final_mgmt_lib(); return buf; } /* external way: invoke the external tool tsa_hacli to operate on linux-ha */ char* process_cmnd_external(const char *cmd) { static char result[4096]; char cmd_buf[1024]; char * buf = NULL; int rc, len; memset(result, 0, 4096); snprintf(cmd_buf, 1024, "%s %s", TSA_HA_CLI, cmd); buf = run_shell_cmnd(cmd_buf, &rc, &len); if ( buf ) { strncpy(result, buf, 4096); free(buf); } return result; } /* eventd way: talk to event daemon with IPC */ char* process_cmnd_eventd(const char *cmd) { static char buf[1024]; /* to avoid memory leak */ struct ha_msg *cmd_msg = NULL, *msg = NULL; IPC_Channel * ipc_chan = NULL; const char * result = NULL; memset(buf, 0, 1024); while ( ( ipc_chan = eventd_signon()) == NULL ) { sleep(3); } if ( ( cmd_msg = ha_msg_new(1) ) == NULL ) { cl_log(LOG_ERR, "%s: alloc msg failed.", __FUNCTION__); goto exit; } ha_msg_add(cmd_msg, "cmd", cmd); if ( msg2ipcchan(cmd_msg, ipc_chan) != HA_OK ) { cl_log(LOG_ERR, "%s: send msg to ipchan failed.", __FUNCTION__); } ha_msg_del(cmd_msg); msg = msgfromIPC(ipc_chan, MSG_ALLOWINTR); if ( msg && ( result = ha_msg_value(msg, "result"))) { strncpy(buf, result, 1024); } exit: eventd_signoff(ipc_chan); return buf; } pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/ha_mgmt_client.h000066400000000000000000000023661211477743100246040ustar00rootroot00000000000000/* * ha_mgmt_client.h: header file for ha_mgmt_client.c * * Author: Jia Ming Pan * Copyright (c) 2006 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef _HA_MGMT_CLIENT_H #define _HA_MGMT_CLIENT_H char* wait_for_events(void); void clLog(int priority, const char* logs); void start_heartbeat(const char* node); void stop_heartbeat(const char* node); char* process_cmnd_native(const char* cmd); char* process_cmnd_external(const char *cmd); char* process_cmnd_eventd(const char* cmd); void init_logger(const char *entity); #endif pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/ha_mgmt_client.i000066400000000000000000000117011211477743100245760ustar00rootroot00000000000000/* * ha_mgmt_client.i: swig interface file * * Author: Jia Ming Pan * Copyright (c) 2006 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ %module LHAMgmtLib %{ #include "ha_mgmt_client.h" %} %pragma(java) jniclasscode=%{ static { try { System.loadLibrary("lhamgmt"); } catch (UnsatisfiedLinkError e) { System.exit(1); } } %} %pragma(java) modulecode=%{ public static final String MSG_OK = "ok"; public static final String MSG_FAIL = "fail"; public static final String MSG_LOGIN = "login"; public static final String MSG_LOGOUT = "logout"; public static final String MSG_ECHO = "echo"; public static final String MSG_REGEVT = "regevt"; public static final String MSG_CIB_VERSION = "cib_version"; public static final String MSG_CRM_CONFIG = "crm_config"; public static final String MSG_UP_CRM_CONFIG = "up_crm_config"; public static final String MSG_HB_CONFIG = "hb_config"; public static final String MSG_ALLNODES = "all_nodes"; public static final String MSG_ACTIVENODES = "active_nodes"; public static final String MSG_CRMNODES = "crm_nodes"; public static final String MSG_DC = "dc"; public static final String MSG_NODE_CONFIG = "node_config"; public static final String MSG_STANDBY = "standby"; public static final String MSG_RUNNING_RSC = "running_rsc"; public static final String MSG_ALL_RSC = "all_rsc"; public static final String MSG_RSC_ATTRS = "rsc_attrs"; public static final String MSG_RSC_TYPE = "rsc_type"; public static final String MSG_SUB_RSC = "sub_rsc"; public static final String MSG_RSC_RUNNING_ON = "rsc_running_on"; public static final String MSG_RSC_STATUS = "rsc_status"; public static final String MSG_ADD_RSC = "add_rsc"; public static final String MSG_ADD_GRP = "add_grp"; public static final String MSG_DEL_RSC = "del_rsc"; public static final String MSG_CLEANUP_RSC = "cleanup_rsc"; public static final String MSG_MOVE_RSC = "move_rsc"; public static final String MSG_UP_RSC_ATTR = "up_rsc_attr"; public static final String MSG_RSC_PARAMS = "rsc_params"; public static final String MSG_UP_RSC_PARAMS = "up_rsc_params"; public static final String MSG_DEL_RSC_PARAM = "del_rsc_param"; public static final String MSG_SET_TARGET_ROLE = "set_target_role"; public static final String MSG_RSC_OPS = "rsc_ops"; public static final String MSG_UP_RSC_OPS = "up_rsc_ops"; public static final String MSG_DEL_RSC_OP = "del_rsc_op"; public static final String MSG_UPDATE_CLONE = "up_clone"; public static final String MSG_GET_CLONE = "get_clone"; public static final String MSG_UPDATE_MASTER = "up_master"; public static final String MSG_GET_MASTER = "get_master"; public static final String MSG_GET_CONSTRAINTS = "get_cos"; public static final String MSG_GET_CONSTRAINT = "get_co"; public static final String MSG_DEL_CONSTRAINT = "del_co"; public static final String MSG_UP_CONSTRAINT = "up_co"; public static final String MSG_RSC_CLASSES = "rsc_classes"; public static final String MSG_RSC_TYPES = "rsc_types"; public static final String MSG_RSC_PROVIDERS = "rsc_providers"; public static final String MSG_RSC_METADATA = "rsc_metadata"; public static final String EVT_CIB_CHANGED = "evt:cib_changed"; public static final String EVT_DISCONNECTED = "evt:disconnected"; public static final String EVT_TEST = "evt:test"; public static final int LOG_INFO = 6; public static final int LOG_DEBUG = 7; public static final int LOG_WARNING = 4; public static final int LOG_ERR = 3; %} char* process_cmnd_native(const char* cmd); char* process_cmnd_external(const char *cmd); char* process_cmnd_eventd(const char *cmd); char* wait_for_events(void); void clLog(int priority, const char* logs); void start_heartbeat(const char* node); void stop_heartbeat(const char* node); pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/ha_tsa_common.c000066400000000000000000000063301211477743100244270ustar00rootroot00000000000000/* * ha_tsa_common.c: common functions * * Author: Jia Ming Pan * Copyright (c) 2006 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ha_tsa_common.h" void init_logger(const char * entity) { int debug_level = 2; cl_log_set_entity(entity); cl_log_enable_stderr(debug_level?TRUE:FALSE); cl_log_set_facility(HA_LOG_FACILITY); } char ** split_string(const char* string, int *len, const char *delim) { char **strings = NULL; const char *p; *len = 0; while(*string){ char * token = NULL; /* eat up delim chars */ while (*string && strchr(delim, *string)) { string++; continue; } if(!*string) { break; } /* reach a delim char */ p = string; while ( *p && !strchr(delim, *p) ) { p ++; continue; } /* copy string~(p-1) to token */ token = malloc(p-string+1); if ( token == NULL ) { return strings; } memcpy(token, string, p - string); token[p-string] = EOS; strings = realloc(strings, (*len+1) * sizeof(char *)); if ( strings == NULL ) { return NULL; } strings[*len] = token; *len = *len + 1; string = p; } return strings; } void free_array(void** array, int len) { int i; for (i=0; i * Copyright (c) 2006 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef _HA_TSA_COMMON_H #define _HA_TSA_COMMON_H void init_logger(const char * entity); char** split_string(const char *string, int *len, const char *delim); void free_array(void** array, int len); char* run_shell_cmnd(const char *cmnd, int *rc, int *len); #endif pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/linuxha-adapter.in000077500000000000000000000144071211477743100251010ustar00rootroot00000000000000#! /bin/sh # # Copyright (c) 2006 International Business Machines # # This script is modified from the /usr/bin/samadapter script # of IBM sam.adapter Software Package # # LOG_LVL=0 ONLINE=0 OFFLINE=3 HB_BIN_DIR=@HA_LIBHBDIR@ TSA_EVENTD=${HB_BIN_DIR}/tsa_eventd MSG_NOUNAME='Cannot determine OS - exit.' MSG_NOJAVA='Cannot find Java - exit.' UNAME=`uname -s` function logit () { if [ $LOG_LVL -ge $1 ] then logger -i -t $0: "$2" fi } # function getValue # get the Value string from key in file # parameters: # $1 File to parse # $2 key to search for string # $3 ==1, if removal of trailing CR(13) is required # return: # Value: String after "=" # function getValue () { R=$(cat $1 | grep ^$2 | sed s/' '//g | sed s/.*=// | sed s/\"//g ) if [ -z "$R" ] then R="Cannot get text for $1=" fi if [ $3 -eq 1 ] then # remove CR RCNT=$(echo $R | wc -c) RCNT=`expr $RCNT - 1` R=$(echo $R | cut -b1-$RCNT) fi echo $R } function getJavaPath () { JPATH="" case "$UNAME" in AIX) JPATH=$(find /usr -name "java[1-9][4-9]*" | grep -v 64 | sort -r | head -1) ;; Linux) JPATH=$pfixed/java ;; *) echo $MSG_NOUNAME ;; esac if [ -n "$JPATH" ] then JPATH=$JPATH$1 fi echo $JPATH } function getStatus () { RC=0 PID=$(ps ax | grep -v grep | grep "$SAM_EYE_CATCHER" | grep -v " D " | head -1 | sed s/' '*// | cut -f1 -d" ") if [ -z "$PID" ] then echo "Adapter is not running." RC=$OFFLINE else echo "Adapter is running [pid: $PID]." RC=$ONLINE fi return $RC } function startEventd () { ${TSA_EVENTD} -s if [ $? -eq 0 ] ; then echo "eventd already started." return 0 fi ${TSA_EVENTD} & ${TSA_EVENTD} -s if [ $? -eq 3 ] ; then echo "Can not start eventd." exit 3 fi return 0 } function stopEventd () { ${TSA_EVENTD} -k } function startAdapter () { getStatus RC=$? if [ $RC -eq $OFFLINE ] ; then if [ "$UNAME" = AIX ] ; then MKTEMP='' LSOF='' else #linux MKTEMP=`whereis mktemp | cut -d' ' -f2 | cut -d' ' -f3` LSOF=`whereis lsof | cut -d' ' -f2 | cut -d' ' -f3` fi rm -f /tmp/$adapter.* # Create a tempfile to capture the first few lines of the output if [ -n "$MKTEMP" ] ; then TMPFILE=`$MKTEMP -q /tmp/$adapter.XXXXXX` else # It's better to use mktemp, but we don't have it, we make it cryptic RNDM=$(echo $RANDOM) TMPFILE=/tmp/$adapter.XXXXXX-RNDM touch $TMPFILE fi # set LIBRAY path for jni parts NATIVE_LIBPATH=/lib:/usr/lib if [ "$UNAME" = "AIX" ] ; then export LIBPATH=$plib:$LIBPATH:$NATIVE_LIBPATH else export LD_LIBRARY_PATH=$plib:$LD_LIBRARY_PATH:$NATIVE_LIBPATH fi $pjava/bin/java -$SAM_EYE_CATCHER -cp $jars \ -Djava.security.auth.login.config=$pcfgm/sam.adapter.jaas.properties \ -Dcom.ibm.eez.adapter.configFile=$ADAPTER_CFG \ -Dcom.ibm.eez.adapter.configSSL=$pcfgm/sam.adapter.ssl.properties \ -Djlog.propertyFileDir=$pcfgm \ -Djlog.propertyFileName=sam.adapter.jlog.properties com.ibm.eez.adapter.EEZAdapterMain 2>&1 \ | head -1 > $TMPFILE & logit 0 "Started, waiting for $adapter to become ready..." if [ -n "$LSOF" ] ; then # Check if the tempfile is closed $LSOF 2> /dev/null | grep $TMPFILE > /dev/null 2>&1 RETCODE=$? # If the tempfile is not yet closed, sleep for a second and try again while [ $RETCODE -ne 1 ]; do sleep 2 $LSOF 2> /dev/null | grep $TMPFILE > /dev/null 2>&1 RETCODE=$? done else sleep 4 fi # cat the output to the screen and remove the tempfile cat $TMPFILE && rm -f $TMPFILE echo "$adapter has started." logit 0 "$adapter has started." RC=0 else # already online echo "$adapter is not started because it is already running on $RUNS_ON_NODE" logit 0 "$adapter is not started because it is already running on $RUNS_ON_NODE" RC=0 fi return $RC } function stopAdapter() { rm -f /tmp/$adapter.* getStatus RC=$? if [ $RC -eq $ONLINE ]; then HOST_NAME=$(getValue $ADAPTER_CFG "eez-remote-contact-hostname" 1) PORT=$(getValue $ADAPTER_CFG "eez-remote-contact-port" 1) SSLVAL=$(getValue $ADAPTER_CFG "eez-remote-contact-over-ssl" 1) SSL="" if [ "$SSLVAL" = "true" ] ; then SSL="-ssl" fi $pjava/bin/java -cp $jars \ -Djava.security.auth.login.config=$pcfgm/sam.adapter.jaas.properties \ -Dcom.ibm.eez.adapter.configFile=$ADAPTER_CFG \ -Dcom.ibm.eez.adapter.configSSL=$pcfgm/sam.adapter.ssl.properties \ -Djlog.propertyFileDir=$pcfgm \ -Djlog.propertyFileName=sam.adapter.jlog.properties com.ibm.eez.adapter.EEZAdapterCmd\ -terminate -host $HOST_NAME -port $PORT $SSL >/dev/null 2>&1 logit 2 "Waiting 10 seconds after sending stop to $adapter PID $PID..." logit 0 "$adapter with PID $PIDSAVE stopped" RC=0 else echo "$adapter is not running" logit 2 "$adapter is not running" RC=0 fi return $RC } adapter=samadapter SAM_EYE_CATCHER=Dcom.ibm.sam.samadapter pprod=IBM/tsamp/sam pfixed=/opt/$pprod plib=$pfixed/lib pcfgm=/etc$pfixed/cfg jars=$plib/eezadapter.jar:$plib/eezmsgs.jar:$plib/eezmsgs_lang.jar:$plib/eezsdk.jar:$plib/eezutils.jar:$plib/evd.jar:$plib/log.jar:$plib/jlog.jar:$plib/jffdc.jar:$plib/tivolicommondir.jar:/usr/sbin/rsct/codebase/rmcapi.jar:/usr/sbin/rsct/codebase:$plib/samrmc.jar:$plib/samfla.jar:$plib/sammsgs.jar:$plib/linuxhafla.jar pit=/var/ibm/tivoli/common pitlogcfg=/etc/ibm/tivoli/common/cfg peezlogs=eez/logs peezffdc=eez/ffdc tivoli_common_dir="" if [ -r "$pitlogcfg/log.properties" ] ; then # read the tivoli_common_dir attribute . $pitlogcfg/log.properties fi if [ -z "$tivoli_common_dir" ] ; then logit 0 "Warning - 'tivoli_common_dir' not specified in $pitlogcfg/log.properties" logit 0 "Will use default: $pit" tivoli_common_dir=$pit fi ADAPTER_CFG=$pcfgm/sam.adapter.properties if [ -z "$ADAPTER_CFG" ] ; then echo "$adapter configuration '$ADAPTER_CFG' does not exist - exit." exit 1 fi ########################################### # main begin ########################################### ACTION=${1} RC=0 PID="" RUNS_ON_NODE="" POLICY_FILE=$pcfgm/sam.adapter.conf if [ ! -r "$POLICY_FILE" ] ; then echo "$POLICY_FILE does not exist - exit." fi pjava=$(getJavaPath /jre) if [ -z "$pjava" ] then echo $MSG_NOJAVA exit 1 fi case ${ACTION} in start) startEventd startAdapter RC=$? ;; stop) stopAdapter RC=$? stopEventd ;; status) getStatus RC=$? ;; esac exit $RC pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/org/000077500000000000000000000000001211477743100222415ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/org/linuxha/000077500000000000000000000000001211477743100237115ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/org/linuxha/sam/000077500000000000000000000000001211477743100244715ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/org/linuxha/sam/plugin/000077500000000000000000000000001211477743100257675ustar00rootroot00000000000000pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/org/linuxha/sam/plugin/LHACLIClient.java000066400000000000000000000005211211477743100307230ustar00rootroot00000000000000package org.linuxha.sam.plugin; public class LHACLIClient extends LHALIBClient { synchronized String[] processCommand(String[] command) { String msg = ""; for(int i=0; i pos + 2){ if (attrs[pos + 1].equals("target_role")){ rsc.setTargetRole(attrs[pos + 2]); break; } pos += 3; } return rsc; } private LHAResourceGroup makeResourceGroup(String rscname) { LHAResourceGroup group = new LHAResourceGroup(); group.setResourceName(rscname); group.setResourceClass(EEZResource.GROUP_CLASS_COLLECTION); group.setGroupClass(EEZResource.GROUP_CLASS_COLLECTION); return group; } public EEZDomain getDomain() { EEZDomain domain = new EEZDomain(); String[] result = processCommand(new String[]{LHAMgmtLib.MSG_HB_CONFIG}); domain.setAutomationVersion(result[8]); domain.setDomainName(result[22]); EEZPropertyList extraProperties = new EEZPropertyList();; domain.setProperties(extraProperties); return domain; } public EEZResourceList getNodeResourceList() { EEZResourceList list = new EEZResourceList(); String[] result = processCommand(new String[]{LHAMgmtLib.MSG_ALLNODES}); if(!result[0].equals(LHAMgmtLib.MSG_OK)){ return list; } for(int i=1; i pos + 4){ cons.setRule(attr[pos + 2], attr[pos + 3], attr[pos + 4]); pos += 4; } list.add(cons); } return list; } public ArrayList getColocationConstraintList() { ArrayList list = new ArrayList(); String[] consid = processCommand( new String[]{LHAMgmtLib.MSG_GET_CONSTRAINTS, "rsc_colocation"}); for(int i=1; i 0) { value = crit.getValues()[0]; } LHAMgmtLib.clLog(LHAMgmtLib.LOG_INFO, "LinuxHAFLA:enumerateResources(): " + crit.getName() + crit.getOperation() + value); int nrrsc = list.size(); for (int j = nrrsc -1 ; j >= 0; j--) { LHAResource rsc = (LHAResource) list.get(j); if (! matchResourceCriteria(rsc, crit)){ list.remove(j); } } } } EEZResourceList new_list = new EEZResourceList(); for(int i = 0; i < list.size(); i++) { LHAResource rsc = (LHAResource)list.get(i); LHAMgmtLib.clLog(LHAMgmtLib.LOG_INFO, "LinuxHAFLA:enumerateResources(): Got ResourceName = " + rsc.getResourceName()); new_list.add(rsc.getEEZResource()); } LHAMgmtLib.clLog(LHAMgmtLib.LOG_INFO, "LinuxHAFLA:enumerateResources() done."); return new_list; } void addAllNoDuplicates(EEZRelationList target, EEZRelationList src) { int size = src.size(); for (int i = 0; i < size; i++) { if (!target.contains(src.get(i))) { target.add(src.get(i)); } } } public EEZRelationList enumerateRelations(EEZFilterCriteriaList filter, Properties context) throws EEZAdapterException { LHAMgmtLib.clLog(LHAMgmtLib.LOG_INFO, "LinuxHAFLA:enumerateRelations() begin. filter contains " + filter.size() + " Criterias."); // first divide criteria into resource specific and relation specific EEZFilterCriteriaList res_filter = new EEZFilterCriteriaList(); EEZFilterCriteriaList rel_filter = new EEZFilterCriteriaList(); int size = filter.size(); String rel_direction = null; for (int i = 0; i < size; i++) { EEZFilterCriteria crit = (EEZFilterCriteria)filter.get(i); LHAMgmtLib.clLog(LHAMgmtLib.LOG_INFO, "LinuxHAFLA:enumerateRelations() CriteriaName = " + crit.getName()); if (crit.getName().equals(EEZFilterCriteria.RESOURCE_NAME) || crit.getName().equals(EEZFilterCriteria.RESOURCE_TYPE) || crit.getName().equals(EEZFilterCriteria.RESOURCE_CLASS) || crit.getName().equals(EEZFilterCriteria.RESOURCE_NODE)) { res_filter.add(crit); } else { if (crit.getName().equals(EEZFilterCriteria.RELATION_DIRECTION)) { if (crit.getOperation().equals(EEZFilterCriteria.EQUAL)) { rel_direction = crit.getValues()[0]; } else { if (crit.getValues()[0].equals(EEZFilterCriteria.RELATION_DIRECTION_FORWARD)) rel_direction = EEZFilterCriteria.RELATION_DIRECTION_FORWARD; else rel_direction = EEZFilterCriteria.RELATION_DIRECTION_FORWARD; } } else if (crit.getName().equals(EEZFilterCriteria.RELATION_TYPE)) { rel_filter.add(crit); } else if (crit.getName().equals(EEZFilterCriteria.RELATION_NAME)) { rel_filter.add(crit); } } } if (rel_direction == null) { rel_direction = EEZFilterCriteria.RELATION_DIRECTION_FORWARD; } EEZRelationList relations = new EEZRelationList(); if (res_filter.size() == 0) { relations.addAll(clusterManager.getAllRelations()); } else { EEZResourceList rl = enumerateResources(res_filter, context); if (rl == null || rl.size() == 0) { return new EEZRelationList(); } size = rl.size(); for (int i = 0; i < size; i++) { EEZResource act_res = (EEZResource)rl.get(i); EEZRelationList res_rels; if (rel_direction.equals(EEZFilterCriteria.RELATION_DIRECTION_FORWARD)) { res_rels = clusterManager.findRelations( null, null, act_res.resourceKey(), null); } else { res_rels = clusterManager.findRelations(null, null, null, act_res.resourceKey()); } addAllNoDuplicates(relations, res_rels); } } int num_crit = rel_filter.size(); for (int run = 0; run < num_crit; run++) { size = relations.size(); for (int i = size-1; i >= 0; i--) { // the usual backwards filtering EEZRelation act_rel = (EEZRelation)relations.get(i); if (!matchRelationCriteria(act_rel, (EEZFilterCriteria)rel_filter.get(run))) { relations.remove(i); } } } for( int i = 0; i < relations.size(); i++){ EEZRelation rel = (EEZRelation)relations.get(i); LHAMgmtLib.clLog(LHAMgmtLib.LOG_INFO, "LinuxHAFLA:enumerateRelations(): Got relation: " + rel.toString()); } LHAMgmtLib.clLog(LHAMgmtLib.LOG_INFO, "LinuxHAFLA:enumerateRelations() end."); return relations; } public EEZResourceKeyList subscribeResources(EEZResourceKeyList keylist, Properties context) throws EEZAdapterException { LHAMgmtLib.clLog(LHAMgmtLib.LOG_INFO, "LinuxHAFLA:subscribeResources() begin."); EEZResourceKeyList failedList = new EEZResourceKeyList(); for(int i = 0; i < keylist.size(); i++){ LHAResource rsc = clusterManager.findLHAResource(((EEZResourceKey)keylist.get(i)).getResourceName()); if (rsc != null ){ rsc.setSubscribed(true); }else { failedList.add((EEZResourceKey)keylist.get(i)); } } LHAMgmtLib.clLog(LHAMgmtLib.LOG_INFO, "LinuxHAFLA:subscribeResources() end."); return failedList; } public EEZResourceKeyList unsubscribeResources(EEZResourceKeyList keylist, Properties context) throws EEZAdapterException { LHAMgmtLib.clLog(LHAMgmtLib.LOG_INFO, "LinuxHAFLA:unsubscribeResources() begin."); EEZResourceKeyList failedList = new EEZResourceKeyList(); for(int i=0; i * Copyright (c) 2006 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ha_tsa_common.h" #define IPC_PATH_ATTR "path" /* pathname attribute */ #define TSA_CMDPATH HA_VARRUNDIR"/heartbeat/tsa_eventd" #define PID_FILE HA_VARRUNDIR"/tsa_eventd.pid" #define MAX_CLIENT 16 #define CMD_SUBSCRIBE_EVENT "cmd_subscribe_event" typedef struct { GCHSource * gsrc; IPC_Channel *ch; } eventd_client_t; eventd_client_t *event_client = NULL; GMainLoop* mainloop = NULL; void tsa_shutdown(int signo); void * tsa_main_loop(void * param); int eventd_stop(const char *pid_file); int cib_event_handler(const char *event); int disconnected_handler(const char *event); void init_logger(const char * entity); gboolean sigterm_action(int nsig, gpointer user_data); void register_pid(gboolean do_fork, gboolean (*shutdown)(int nsig, gpointer userdata)); int eventd_start(int debug); int eventd_status(void); int eventd_stop(const char *pid_file); gboolean on_channel_connect (IPC_Channel* ch, gpointer user_data); void on_channel_remove (gpointer user_data); gboolean on_receive_cmnd(IPC_Channel *ch, gpointer user_data); char* process_mgmt_msg(const char *arg); char* process_mgmt_msg(const char *arg) { char *msg = NULL, *result = NULL; int i, len; char *buf = NULL; char ** cmd = NULL; cl_log(LOG_DEBUG, "%s: arg = %s", __FUNCTION__, arg); if ( (cmd = split_string(arg , &len, " ")) == NULL || len == 0) { return NULL; } msg = mgmt_new_msg(cmd[0], NULL); for(i = 1; i < len; i++ ) { msg = mgmt_msg_append(msg, cmd[i]); } result = process_msg(msg); mgmt_del_msg(msg); if ( result == NULL ) { free_array((void**)cmd, len); final_mgmt_lib(); return NULL; } buf = strdup(result); mgmt_del_msg(result); free_array((void**)cmd, len); return buf; } int cib_event_handler(const char *event) { struct ha_msg* msg = NULL; cl_log(LOG_INFO, "%s: event received: %s", __FUNCTION__, event); if ( event_client && event_client->ch ) { if ((msg = ha_msg_new(1)) == NULL ) { return 0; } ha_msg_add(msg, "event", event); if ( msg2ipcchan(msg, event_client->ch) != HA_OK ) { cl_log(LOG_ERR, "%s: send msg to client failed.", __FUNCTION__); } ha_msg_del(msg); } else { cl_log(LOG_WARNING, "%s: no event client.", __FUNCTION__); } return 1; } int disconnected_handler(const char *event) { /* TODO: send event */ return 1; } gboolean sigterm_action(int nsig, gpointer user_data) { tsa_shutdown(0); return TRUE; } void register_pid(gboolean do_fork, gboolean (*shutdown)(int nsig, gpointer userdata)) { int j; umask(022); for (j = 0; j < 3; ++j) { close(j); (void)open("/dev/null", j == 0 ? O_RDONLY : O_RDONLY); } CL_IGNORE_SIG(SIGINT); CL_IGNORE_SIG(SIGHUP); G_main_add_SignalHandler(G_PRIORITY_HIGH, SIGTERM , shutdown, NULL, NULL); cl_signal_set_interrupt(SIGTERM, 1); cl_signal_set_interrupt(SIGCHLD, 1); cl_signal_set_interrupt(SIGINT, 0); cl_signal_set_interrupt(SIGHUP, 0); } gboolean on_channel_connect (IPC_Channel* ch, gpointer user_data) { eventd_client_t* client = NULL; cl_log(LOG_INFO, "%s: client with farside_pid %u signon", __FUNCTION__, ch->farside_pid); if ( (client = malloc(sizeof(eventd_client_t))) == NULL ) { cl_log(LOG_ERR, "%s: create client failed.", __FUNCTION__); return TRUE; } client->ch = ch; client->gsrc = G_main_add_IPC_Channel(G_PRIORITY_DEFAULT, ch, FALSE, on_receive_cmnd, client, on_channel_remove); return TRUE; } void on_channel_remove(gpointer user_data) { eventd_client_t *client = (eventd_client_t*) user_data; cl_log(LOG_INFO, "%s: client with farside pid %u removed.", __FUNCTION__, client->ch->farside_pid); /* if it is the event client, set event client to NULL */ if ( client == event_client ) { event_client = NULL; } if ( client->gsrc != NULL ) { G_main_del_IPC_Channel(client->gsrc); } free(client); } gboolean on_receive_cmnd(IPC_Channel *ch, gpointer user_data) { eventd_client_t *client = NULL; struct ha_msg *msg = NULL; const char * cmd = NULL; client = (eventd_client_t*) user_data; if (ch->ch_status == IPC_DISCONNECT ) { return FALSE; } if ( ! ch->ops->is_message_pending(ch)) { return FALSE; } if ((msg = msgfromIPC_noauth(ch)) == NULL ) { return TRUE; } if ( (cmd = ha_msg_value(msg, "cmd")) == NULL ) { return TRUE; } if ( strcmp(cmd, CMD_SUBSCRIBE_EVENT) == 0 ) { cl_log(LOG_INFO, "%s: client with farside_pid %u is the event client.", __FUNCTION__, ch->farside_pid); event_client = client; } else { char* buf = NULL; struct ha_msg * result = ha_msg_new(1); if ( result == NULL ) { cl_log(LOG_ERR, "%s: alloc result failed.", __FUNCTION__); ha_msg_del(msg); return TRUE; } buf = process_mgmt_msg(cmd); if ( buf ) { cl_log(LOG_DEBUG, "%s: got result: %s.", __FUNCTION__, buf); ha_msg_add(result, "result", buf); } else { ha_msg_add(result, "result", ""); } if ( msg2ipcchan(result, ch) != HA_OK ) { cl_log(LOG_ERR, "%s: send msg to client failed.", __FUNCTION__); } if ( buf ) { free(buf); } ha_msg_del(result); } ha_msg_del(msg); return TRUE; } int eventd_status(void) { long pid = cl_read_pidfile(PID_FILE); if (pid > 0) { fprintf(stderr, "eventd is running [pid: %ld]\n", pid); return LSB_STATUS_OK; } fprintf(stderr, "eventd is stopped.\n"); return LSB_STATUS_STOPPED; } void tsa_shutdown(int signo) { if ( mainloop && g_main_is_running(mainloop)) { g_main_quit(mainloop); } } int eventd_start(int debug) { char path[] = IPC_PATH_ATTR; char cmd_path[] = TSA_CMDPATH; GHashTable * conn_attrs; IPC_WaitConnection * conn_cmd = NULL; /* init */ if(cl_lock_pidfile(PID_FILE) < 0 ){ cl_log(LOG_ERR, "already running."); exit(100); } register_pid( FALSE, sigterm_action); cl_cdtocoredir(); cl_enable_coredumps(TRUE); cl_set_all_coredump_signal_handlers(); /* mgmt lib */ init_mgmt_lib("tsad", ENABLE_LRM|ENABLE_CRM|ENABLE_HB|CACHE_CIB); reg_event(EVT_CIB_CHANGED, cib_event_handler); reg_event(EVT_DISCONNECTED, disconnected_handler); /* IPC channel */ conn_attrs = g_hash_table_new(g_str_hash, g_str_equal); g_hash_table_insert(conn_attrs, path, cmd_path); conn_cmd = ipc_wait_conn_constructor(IPC_ANYTYPE, conn_attrs); g_hash_table_destroy(conn_attrs); G_main_add_IPC_WaitConnection(G_PRIORITY_HIGH, conn_cmd, NULL, FALSE, on_channel_connect, conn_cmd, NULL); /* main loop */ mainloop = g_main_new(FALSE); if ( mainloop == NULL ) { cl_log(LOG_ERR, "%s: couldn't creat mainloop", __FUNCTION__); } g_main_run(mainloop); /* loop completes, clean up */ final_mgmt_lib(); return 0; } int eventd_stop(const char *pid_file) { long pid; int rc = LSB_EXIT_OK; pid = cl_read_pidfile(pid_file); if (pid > 0) { if (CL_KILL((pid_t)pid, SIGTERM) < 0) { rc = (errno == EPERM ? LSB_EXIT_EPERM : LSB_EXIT_GENERIC); fprintf(stderr, "Cannot kill pid %ld\n", pid); } else { while (CL_PID_EXISTS(pid)) { sleep(1); } } } return rc; } int main(int argc, char ** argv) { int flag = 0; int debug_level = 0; int rq_stop = 0; int rq_status = 0; int argerr = 0; init_logger("TSA-eventd"); while ((flag = getopt(argc, argv, "dsk")) != -1) { switch(flag) { case 'd': ++debug_level; break; case 'k': rq_stop = TRUE; break; case 's': rq_status = TRUE; break; default: ++argerr; break; } } if(rq_stop) { return eventd_stop(PID_FILE); } else if(rq_status){ return eventd_status(); } else { return eventd_start(debug_level); } } pacemaker-mgmt-pacemaker-mgmt-2.1.2/tsa_plugin/tsa_hacli.c000066400000000000000000000042711211477743100235510ustar00rootroot00000000000000/* * tsa_hacli.c: command line tool * * Author: Jia Ming Pan * Copyright (c) 2006 International Business Machines * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ha_tsa_common.h" #define PID_FILE HA_VARRUNDIR"/tsa_hacli.pid" #define MAX_CMD_LEN 1024 static char* process_command(int argc, char * argv[]) { char *msg = NULL, *result = NULL; int i; char *buf = NULL; msg = mgmt_new_msg(argv[1], NULL); for(i = 2; i < argc; i++ ) { msg = mgmt_msg_append(msg, argv[i]); } cl_log(LOG_DEBUG, "msg sent: %s", msg); result = process_msg(msg); mgmt_del_msg(msg); if ( result == NULL ) { return NULL; } buf = strdup(result); mgmt_del_msg(result); return buf; } int main(int argc, char *argv[]) { char *result = NULL; init_logger("tsa_cli"); if ( argc < 2 ) { return 1; } if(cl_lock_pidfile(PID_FILE) < 0 ){ exit(100); } init_mgmt_lib("tsa", ENABLE_LRM|ENABLE_CRM|ENABLE_HB|CACHE_CIB); result = process_command(argc, argv); final_mgmt_lib(); if (result) { printf("%s\n", result); } return 0; }