diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am index d4750bf09..1333f8feb 100644 --- a/heartbeat/Makefile.am +++ b/heartbeat/Makefile.am @@ -1,197 +1,198 @@ # Makefile.am for OCF RAs # # Author: Sun Jing Dong # Copyright (C) 2004 IBM # # 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 = $(ocf_SCRIPTS) $(ocfcommon_DATA) \ $(common_DATA) $(hb_DATA) $(dtd_DATA) \ README AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/linux-ha halibdir = $(libexecdir)/heartbeat ocfdir = $(OCF_RA_DIR_PREFIX)/heartbeat dtddir = $(datadir)/$(PACKAGE_NAME) dtd_DATA = ra-api-1.dtd metadata.rng if USE_IPV6ADDR_AGENT ocf_PROGRAMS = IPv6addr else ocf_PROGRAMS = endif if IPV6ADDR_COMPATIBLE halib_PROGRAMS = send_ua else halib_PROGRAMS = endif IPv6addr_SOURCES = IPv6addr.c IPv6addr_utils.c send_ua_SOURCES = send_ua.c IPv6addr_utils.c IPv6addr_LDADD = -lplumb $(LIBNETLIBS) send_ua_LDADD = $(LIBNETLIBS) ocf_SCRIPTS = AoEtarget \ AudibleAlarm \ ClusterMon \ CTDB \ Delay \ Dummy \ EvmsSCC \ Evmsd \ Filesystem \ ICP \ IPaddr \ IPaddr2 \ IPsrcaddr \ LVM \ LinuxSCSI \ lvmlockd \ LVM-activate \ MailTo \ ManageRAID \ ManageVE \ NodeUtilization \ Pure-FTPd \ Raid1 \ Route \ SAPDatabase \ SAPInstance \ SendArp \ ServeRAID \ SphinxSearchDaemon \ Squid \ Stateful \ SysInfo \ VIPArip \ VirtualDomain \ WAS \ WAS6 \ WinPopup \ Xen \ Xinetd \ ZFS \ anything \ apache \ asterisk \ aws-vpc-move-ip \ aws-vpc-route53 \ awseip \ awsvip \ azure-lb \ clvm \ conntrackd \ db2 \ dhcpd \ dnsupdate \ docker \ eDir88 \ ethmonitor \ exportfs \ fio \ galera \ garbd \ gcp-vpc-move-ip \ gcp-vpc-move-vip \ gcp-vpc-move-route \ iSCSILogicalUnit \ iSCSITarget \ ids \ iface-bridge \ iface-vlan \ ipsec \ iscsi \ jboss \ jira \ kamailio \ lxc \ lxd-info \ machine-info \ mariadb \ minio \ mysql \ mysql-proxy \ nagios \ named \ nfsnotify \ nfsserver \ nginx \ openstack-cinder-volume \ openstack-floating-ip \ openstack-info \ oraasm \ oracle \ oralsnr \ ovsmonitor \ pgagent \ pgsql \ pingd \ portblock \ postfix \ pound \ proftpd \ rabbitmq-cluster \ redis \ rkt \ rsyncd \ rsyslog \ scsi2reservation \ sfex \ sg_persist \ mpathpersist \ slapd \ sybaseASE \ symlink \ syslog-ng \ tomcat \ varnish \ vmware \ vsftpd \ zabbixserver ocfcommondir = $(OCF_LIB_DIR_PREFIX)/heartbeat ocfcommon_DATA = ocf-shellfuncs \ ocf-binaries \ ocf-directories \ ocf-returncodes \ ocf-rarun \ ocf-distro \ apache-conf.sh \ http-mon.sh \ sapdb-nosha.sh \ sapdb.sh \ lvm-clvm.sh \ lvm-plain.sh \ lvm-tag.sh \ ora-common.sh \ mysql-common.sh \ nfsserver-redhat.sh \ - findif.sh + findif.sh \ + ocf.py # Legacy locations hbdir = $(sysconfdir)/ha.d hb_DATA = shellfuncs check: $(ocf_SCRIPTS:=.check) %.check: % OCF_ROOT=$(abs_srcdir) OCF_FUNCTIONS_DIR=$(abs_srcdir) ./$< meta-data | xmllint --path $(abs_srcdir) --noout --relaxng $(abs_srcdir)/metadata.rng - diff --git a/heartbeat/ocf.py b/heartbeat/ocf.py new file mode 100644 index 000000000..12be7a2a4 --- /dev/null +++ b/heartbeat/ocf.py @@ -0,0 +1,136 @@ +# +# Copyright (c) 2016 Red Hat, Inc, Oyvind Albrigtsen +# All Rights Reserved. +# +# +# 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 +# + +import sys, os, logging, syslog + +argv=sys.argv +env=os.environ + +# +# Common variables for the OCF Resource Agents supplied by +# heartbeat. +# + +OCF_SUCCESS=0 +OCF_ERR_GENERIC=1 +OCF_ERR_ARGS=2 +OCF_ERR_UNIMPLEMENTED=3 +OCF_ERR_PERM=4 +OCF_ERR_INSTALLED=5 +OCF_ERR_CONFIGURED=6 +OCF_NOT_RUNNING=7 + +# Non-standard values. +# +# OCF does not include the concept of master/slave resources so we +# need to extend it so we can discover a resource's complete state. +# +# OCF_RUNNING_MASTER: +# The resource is in "master" mode and fully operational +# OCF_FAILED_MASTER: +# The resource is in "master" mode but in a failed state +# +# The extra two values should only be used during a probe. +# +# Probes are used to discover resources that were started outside of +# the CRM and/or left behind if the LRM fails. +# +# They can be identified in RA scripts by checking for: +# [ "${__OCF_ACTION}" = "monitor" -a "${OCF_RESKEY_CRM_meta_interval}" = "0" ] +# +# Failed "slaves" should continue to use: OCF_ERR_GENERIC +# Fully operational "slaves" should continue to use: OCF_SUCCESS +# +OCF_RUNNING_MASTER=8 +OCF_FAILED_MASTER=9 + + +## Own logger handler that uses old-style syslog handler as otherwise +## everything is sourced from /dev/syslog +class SyslogLibHandler(logging.StreamHandler): + """ + A handler class that correctly push messages into syslog + """ + def emit(self, record): + syslog_level = { + logging.CRITICAL:syslog.LOG_CRIT, + logging.ERROR:syslog.LOG_ERR, + logging.WARNING:syslog.LOG_WARNING, + logging.INFO:syslog.LOG_INFO, + logging.DEBUG:syslog.LOG_DEBUG, + logging.NOTSET:syslog.LOG_DEBUG, + }[record.levelno] + + msg = self.format(record) + + # syslog.syslog can not have 0x00 character inside or exception + # is thrown + syslog.syslog(syslog_level, msg.replace("\x00","\n")) + return + + +OCF_RESOURCE_INSTANCE = env.get("OCF_RESOURCE_INSTANCE") + +HA_DEBUG = env.get("HA_debug", 0) +HA_DATEFMT = env.get("HA_DATEFMT", "%b %d %T ") +HA_LOGFACILITY = env.get("HA_LOGFACILITY") +HA_LOGFILE = env.get("HA_LOGFILE") +HA_DEBUGLOG = env.get("HA_DEBUGLOG") + +log = logging.getLogger(os.path.basename(argv[0])) +log.setLevel(logging.DEBUG) + +## add logging to stderr +if sys.stdout.isatty(): + seh = logging.StreamHandler(stream=sys.stderr) + if HA_DEBUG == 0: + seh.setLevel(logging.WARNING) + sehformatter = logging.Formatter('%(filename)s(%(OCF_RESOURCE_INSTANCE)s)[%(process)s]:\t%(asctime)s%(levelname)s: %(message)s', datefmt=HA_DATEFMT) + seh.setFormatter(sehformatter) + log.addHandler(seh) + +## add logging to syslog +if HA_LOGFACILITY: + slh = SyslogLibHandler() + if HA_DEBUG == 0: + slh.setLevel(logging.WARNING) + slhformatter = logging.Formatter('%(levelname)s: %(message)s') + slh.setFormatter(slhformatter) + log.addHandler(slh) + +## add logging to file +if HA_LOGFILE: + lfh = logging.FileHandler(HA_LOGFILE) + if HA_DEBUG == 0: + lfh.setLevel(logging.WARNING) + lfhformatter = logging.Formatter('%(filename)s(%(OCF_RESOURCE_INSTANCE)s)[%(process)s]:\t%(asctime)s%(levelname)s: %(message)s', datefmt=HA_DATEFMT) + lfh.setFormatter(lfhformatter) + log.addHandler(lfh) + +## add debug logging to file +if HA_DEBUGLOG and HA_LOGFILE != HA_DEBUGLOG: + dfh = logging.FileHandler(HA_DEBUGLOG) + if HA_DEBUG == 0: + dfh.setLevel(logging.WARNING) + dfhformatter = logging.Formatter('%(filename)s(%(OCF_RESOURCE_INSTANCE)s)[%(process)s]:\t%(asctime)s%(levelname)s: %(message)s', datefmt=HA_DATEFMT) + dfh.setFormatter(dfhformatter) + log.addHandler(dfh) + +logger = logging.LoggerAdapter(log, {'OCF_RESOURCE_INSTANCE': OCF_RESOURCE_INSTANCE})