diff --git a/cts/LSBDummy.in b/cts/LSBDummy.in index 41cbdb8970..eb2978bc92 100644 --- a/cts/LSBDummy.in +++ b/cts/LSBDummy.in @@ -1,102 +1,85 @@ #!/bin/sh # # # Dummy LSB RA. Does nothing but touch and remove a state file # -# Copyright 2006-2018 the Pacemaker project contributors +# Copyright 2006-2021 the Pacemaker project contributors # # The version control history for this file may have further details. # -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it would be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# -# Further, this software is distributed without any warranty that it is -# free of the rightful claim of any third person regarding infringement -# or the like. Any license provided herein, whether implied or -# otherwise, applies only to this software file. Patent licenses, if -# any, provided herein do not apply to combinations of this program with -# other software, or any other product whatsoever. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -# +# This source code is licensed under the GNU General Public License version 2 +# (GPLv2) WITHOUT ANY WARRANTY. ####################################################################### # Initialization: desc="Dummy LSB service" . @OCF_ROOT_DIR@/resource.d/heartbeat/.ocf-directories : ${HA_VARRUN=/tmp} # Backup in case .ocf-directories doesn't exist ####################################################################### success() { printf "[ OK ]\r" } failure() { printf "[FAILED]\r" } dummy_usage() { cat < + * Copyright 2015-2021 the Pacemaker project contributors + * + * The version control history for this file may have further details. * * This source code is licensed under the GNU Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #ifndef CONTROLD_ALERTS__H # define CONTROLD_ALERTS__H # include # include # include void crmd_unpack_alerts(xmlNode *alerts); void crmd_alert_node_event(crm_node_t *node); void crmd_alert_fencing_op(stonith_event_t *e); void crmd_alert_resource_op(const char *node, lrmd_event_data_t *op); #endif diff --git a/daemons/controld/controld_callbacks.h b/daemons/controld/controld_callbacks.h index cb3ac150b6..8af99cc996 100644 --- a/daemons/controld/controld_callbacks.h +++ b/daemons/controld/controld_callbacks.h @@ -1,21 +1,23 @@ /* - * Copyright 2004-2018 Andrew Beekhof + * Copyright 2004-2021 the Pacemaker project contributors + * + * The version control history for this file may have further details. * * This source code is licensed under the GNU Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #ifndef CONTROLD_CALLBACKS__H # define CONTROLD_CALLBACKS__H #include extern void crmd_ha_msg_filter(xmlNode * msg); extern void crmd_cib_connection_destroy(gpointer user_data); extern gboolean crm_fsa_trigger(gpointer user_data); extern void peer_update_callback(enum crm_status_type type, crm_node_t * node, const void *data); #endif diff --git a/daemons/controld/controld_membership.h b/daemons/controld/controld_membership.h index 1d348de207..789c330762 100644 --- a/daemons/controld/controld_membership.h +++ b/daemons/controld/controld_membership.h @@ -1,24 +1,26 @@ /* - * Copyright 2012-2018 Andrew Beekhof + * Copyright 2012-2021 the Pacemaker project contributors + * + * The version control history for this file may have further details. * * This source code is licensed under the GNU Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #ifndef MEMBERSHIP__H # define MEMBERSHIP__H #ifdef __cplusplus extern "C" { #endif #include void post_cache_update(int instance); extern gboolean check_join_state(enum crmd_fsa_state cur_state, const char *source); #ifdef __cplusplus } #endif #endif diff --git a/daemons/controld/controld_throttle.h b/daemons/controld/controld_throttle.h index 9d1b97b89a..cb352e548e 100644 --- a/daemons/controld/controld_throttle.h +++ b/daemons/controld/controld_throttle.h @@ -1,27 +1,17 @@ /* - * Copyright (C) 2013 Andrew Beekhof + * Copyright 2013-2021 the Pacemaker project contributors * - * This program 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. + * The version control history for this file may have further details. * - * 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 Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * This source code is licensed under the GNU Lesser General Public License + * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ - void throttle_init(void); void throttle_fini(void); void throttle_set_load_target(float target); void throttle_update(xmlNode *xml); void throttle_update_job_max(const char *preference); int throttle_get_job_limit(const char *node); int throttle_get_total_job_limit(int l); diff --git a/daemons/execd/pacemaker_remote.service.in b/daemons/execd/pacemaker_remote.service.in index cad70d23bd..1e48d1472e 100644 --- a/daemons/execd/pacemaker_remote.service.in +++ b/daemons/execd/pacemaker_remote.service.in @@ -1,52 +1,52 @@ [Unit] Description=Pacemaker Remote executor daemon Documentation=man:pacemaker-remoted -Documentation=https://clusterlabs.org/pacemaker/doc/en-US/Pacemaker/2.0/html-single/Pacemaker_Remote/index.html +Documentation=https://clusterlabs.org/pacemaker/doc/ # See main pacemaker unit file for descriptions of why these are needed After=network.target After=time-sync.target After=dbus.service Wants=dbus.service After=resource-agents-deps.target Wants=resource-agents-deps.target After=syslog.service After=rsyslog.service [Install] Alias=pacemaker-remote.service WantedBy=multi-user.target [Service] Type=simple KillMode=process NotifyAccess=none EnvironmentFile=-@CONFIGDIR@/pacemaker EnvironmentFile=-@CONFIGDIR@/sbd # Not actually success, but fatal failure -- this ensures no respawn SuccessExitStatus=100 ExecStart=@sbindir@/pacemaker-remoted # Systemd v227 and above can limit the number of processes spawned by a # service. That is a bad idea for an HA cluster resource manager, so disable it # by default. The administrator can create a local override if they really want # a limit. If your systemd version does not support TasksMax, and you want to # get rid of the resulting log warnings, comment out this option. TasksMax=infinity # If connected to the cluster and when the service functions properly, it will # wait to exit until the cluster notifies it all resources on the remote node # have been stopped. The default of 30min should cover most typical cluster # configurations, but it may need an increase to adapt to local conditions # (e.g. a large, clustered database could conceivably take longer to stop). TimeoutStopSec=30min TimeoutStartSec=30s # Restart options include: no, on-success, on-failure, on-abort or always Restart=on-failure # crm_perror() writes directly to stderr, so ignore it here # to avoid double-logging with the wrong format StandardError=null diff --git a/daemons/fenced/fence_legacy.in b/daemons/fenced/fence_legacy.in index 9f527f7e81..86d20912d5 100755 --- a/daemons/fenced/fence_legacy.in +++ b/daemons/fenced/fence_legacy.in @@ -1,272 +1,272 @@ #!@PYTHON@ -__copyright__ = "Copyright 2018-2020 Andrew Beekhof " +__copyright__ = "Copyright 2018-2021 the Pacemaker project contributors" __license__ = "GNU General Public License version 2 or later (GPLv2+) WITHOUT ANY WARRANTY" import os import sys import argparse import subprocess VERSION = "1.1.0" USAGE = """Helper that presents a Pacemaker-style interface for Linux-HA stonith plugins Should never be invoked by the user directly Usage: fence_legacy [options] Options: -h usage -t sub agent -n nodename -o Action: on | off | reset (default) | stat | hostlist -s stonith command -q quiet mode -V version""" META_DATA = """ This agent should never be invoked by the user directly. https://www.clusterlabs.org/ Fencing Action Physical plug number or name of virtual machine Display help and exit """ ACTIONS = [ "on", "off", "reset", "reboot", "stat", "status", "metadata", "monitor", "list", "hostlist", "poweroff", "poweron" ] # These values must be kept in sync with include/crm/crm.h class CrmExit(object): OK = 0 ERROR = 1 INVALID_PARAM = 2 def parse_cli_options(): """ Return parsed command-line options (as argparse namespace) """ # Don't add standard help option, so we can format it how we want parser = argparse.ArgumentParser(add_help=False) parser.add_argument("-t", metavar="SUBAGENT", dest="subagent", nargs=1, default="none", help="sub-agent") parser.add_argument("-n", metavar="NODE", dest="node", nargs=1, default="", help="name of target node") # The help text here is consistent with the original version, though # perhaps all actions should be listed. parser.add_argument("-o", metavar="ACTION", dest="action", nargs=1, choices=ACTIONS, default="reset", help="action: on | off | reset (default) | stat | hostlist") parser.add_argument("-s", metavar="COMMAND", dest="command", nargs=1, default="stonith", help="stonith command") parser.add_argument("-q", dest="quiet", action="store_true", help="quiet mode") parser.add_argument("-h", "--help", action="store_true", help="show usage and exit") # Don't use action="version", because that printed to stderr before # Python 3.4, and help2man doesn't like that. parser.add_argument("-V", "--version", action="store_true", help="show version and exit") return parser.parse_args() def parse_stdin_options(options): """ Update options namespace with options parsed from stdin """ nlines = 0 for line in sys.stdin: # Remove leading and trailing whitespace line = line.strip() # Skip blank lines and comments if line == "" or line[0] == "#": continue nlines = nlines + 1 # Parse option name and value (allow whitespace around equals sign) try: (name, value) = line.split("=", 1) name = name.rstrip() if name == "": raise ValueError except ValueError: print("parse error: illegal name in option %d" % nlines, file=sys.stderr) sys.exit(CrmExit.INVALID_PARAM) value = value.lstrip() if name == "plugin": options.subagent = value elif name in [ "option", "action" ]: options.action = value elif name == "nodename": options.node = value os.environ[name] = value elif name == "stonith": options.command = value elif name != "agent": # agent is used by fenced os.environ[name] = value def normalize_options(options): """ Use string rather than list of one string """ if not hasattr(options.subagent, "strip"): options.subagent = options.subagent[0] if not hasattr(options.node, "strip"): options.node = options.node[0] if not hasattr(options.action, "strip"): options.action = options.action[0] if not hasattr(options.command, "strip"): options.command = options.command[0] def build_command(options): """ Return command to execute (as list of arguments) """ if options.action in [ "hostlist", "list" ]: extra_args = [ "-l" ] elif options.action in [ "monitor", "stat", "status" ]: extra_args = [ "-S" ] else: if options.node == "": if not options.quiet: print("failed: no plug number") sys.exit(CrmExit.ERROR) extra_args = [ "-T", options.action, options.node ] return [ options.command, "-t", options.subagent, "-E" ] + extra_args def handle_local_options(options): """ Handle options that don't require the fence agent """ if options.help: print(USAGE) sys.exit(CrmExit.OK) if options.version: print(VERSION) sys.exit(CrmExit.OK) def remap_action(options): """ Pre-process requested action """ options.action = options.action.lower() if options.action == "metadata": print(META_DATA) sys.exit(CrmExit.OK) elif options.action in [ "hostlist", "list" ]: options.quiet = True # Remap accepted aliases to their actual commands elif options.action == "reboot": options.action = "reset" elif options.action == "poweron": options.action = "on" elif options.action == "poweroff": options.action = "off" def execute_command(options, cmd): """ Execute command and return its exit status """ if not options.quiet: print("Performing: " + " ".join(cmd)) return subprocess.call(cmd) def handle_result(options, status): """ Process fence agent result """ if status == 0: message = "success" exitcode = CrmExit.OK else: message = "failed" exitcode = CrmExit.ERROR if not options.quiet: print("%s: %s %d" % (message, options.node, status)) sys.exit(exitcode) def main(): """ Execute an LHA-style fence agent """ options = parse_cli_options() handle_local_options(options) normalize_options(options) parse_stdin_options(options) remap_action(options) cmd = build_command(options) status = execute_command(options, cmd) handle_result(options, status) if __name__ == "__main__": main() diff --git a/daemons/pacemakerd/pacemaker.service.in b/daemons/pacemakerd/pacemaker.service.in index 000f4099d2..b128ddcb3d 100644 --- a/daemons/pacemakerd/pacemaker.service.in +++ b/daemons/pacemakerd/pacemaker.service.in @@ -1,97 +1,97 @@ [Unit] Description=Pacemaker High Availability Cluster Manager Documentation=man:pacemakerd -Documentation=https://clusterlabs.org/pacemaker/doc/en-US/Pacemaker/2.0/html-single/Pacemaker_Explained/index.html +Documentation=https://clusterlabs.org/pacemaker/doc/ # DefaultDependencies takes care of sysinit.target, # basic.target, and shutdown.target # We need networking to bind to a network address. It is recommended not to # use Wants or Requires with network.target, and not to use # network-online.target for server daemons. After=network.target # Time syncs can make the clock jump backward, which messes with logging # and failure timestamps, so wait until it's done. After=time-sync.target # Managing systemd resources requires DBus. After=dbus.service Wants=dbus.service # Some OCF resources may have dependencies that aren't managed by the cluster; # these must be started before Pacemaker and stopped after it. The # resource-agents package provides this target, which lets system adminstrators # add drop-ins for those dependencies. After=resource-agents-deps.target Wants=resource-agents-deps.target After=syslog.service After=rsyslog.service After=corosync.service Requires=corosync.service [Install] WantedBy=multi-user.target [Service] Type=simple KillMode=process NotifyAccess=main EnvironmentFile=-@CONFIGDIR@/pacemaker EnvironmentFile=-@CONFIGDIR@/sbd SuccessExitStatus=100 ExecStart=@sbindir@/pacemakerd -f # Systemd v227 and above can limit the number of processes spawned by a # service. That is a bad idea for an HA cluster resource manager, so disable it # by default. The administrator can create a local override if they really want # a limit. If your systemd version does not support TasksMax, and you want to # get rid of the resulting log warnings, comment out this option. TasksMax=infinity # If pacemakerd doesn't stop, it's probably waiting on a cluster # resource. Sending -KILL will just get the node fenced SendSIGKILL=no # If we ever hit the StartLimitInterval/StartLimitBurst limit, and the # admin wants to stop the cluster while pacemakerd is not running, it # might be a good idea to enable the ExecStopPost directive below. # # However, the node will likely end up being fenced as a result, so it's # not enabled by default. # # ExecStopPost=/usr/bin/killall -TERM pacemaker-attrd pacemaker-based \ # pacemaker-controld pacemaker-execd pacemaker-fenced \ # pacemaker-schedulerd # If you want Corosync to stop whenever Pacemaker is stopped, # uncomment the next line too: # # ExecStopPost=/bin/sh -c 'pidof pacemaker-controld || killall -TERM corosync' # Pacemaker will restart along with Corosync if Corosync is stopped while # Pacemaker is running. # In this case, if you want to be fenced always (if you do not want to restart) # uncomment ExecStopPost below. # # ExecStopPost=/bin/sh -c 'pidof corosync || \ # /usr/bin/systemctl --no-block stop pacemaker' # When the service functions properly, it will wait to exit until all resources # have been stopped on the local node, and potentially across all nodes that # are shutting down. The default of 30min should cover most typical cluster # configurations, but it may need an increase to adapt to local conditions # (e.g. a large, clustered database could conceivably take longer to stop). TimeoutStopSec=30min TimeoutStartSec=60s # Restart options include: no, on-success, on-failure, on-abort or always Restart=on-failure # crm_perror() writes directly to stderr, so ignore it here # to avoid double-logging with the wrong format StandardError=null diff --git a/daemons/pacemakerd/pacemakerd.h b/daemons/pacemakerd/pacemakerd.h index 5f475fd492..ac26aef186 100644 --- a/daemons/pacemakerd/pacemakerd.h +++ b/daemons/pacemakerd/pacemakerd.h @@ -1,29 +1,31 @@ /* - * Copyright 2010-2018 Andrew Beekhof + * Copyright 2010-2021 the Pacemaker project contributors + * + * The version control history for this file may have further details. * * This source code is licensed under the GNU General Public License version 2 * or later (GPLv2+) WITHOUT ANY WARRANTY. */ #include #include #include #include #include #include #include #include #define SIZEOF(a) (sizeof(a) / sizeof(a[0])) #define MAX_RESPAWN 100 gboolean mcp_read_config(void); gboolean cluster_connect_cfg(void); gboolean cluster_disconnect_cfg(void); void pcmkd_shutdown_corosync(void); void pcmk_shutdown(int nsig); diff --git a/doc/Makefile.am b/doc/Makefile.am index cb3b185865..6a3a065bac 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,141 +1,141 @@ # # Copyright 2003-2020 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # include $(top_srcdir)/mk/common.mk # What formats to use for book uploads (i.e. "make www"; # use BOOK_FORMATS in sphinx subdirectory to change local builds) BOOK_FORMATS ?= html singlehtml pdf epub # Deprecated plaintext documents (dynamically converted to HTML) DEPRECATED_ORIGINAL = crm_fencing.txt DEPRECATED_GENERATED = if BUILD_ASCIIDOC DEPRECATED_GENERATED += $(DEPRECATED_ORIGINAL:%.txt=%.html) endif DEPRECATED_ALL = $(DEPRECATED_ORIGINAL) $(DEPRECATED_GENERATED) doc_DATA = $(DEPRECATED_ALL) noinst_SCRIPTS = abi-check SUBDIRS = sphinx -EXTRA_DIST = $(DEPRECATED_ORIGINAL) pcs-crmsh-quick-ref.md +EXTRA_DIST = $(DEPRECATED_ORIGINAL) # toplevel rsync destination for www targets (without trailing slash) RSYNC_DEST ?= root@www.clusterlabs.org:/var/www/html # recursive, preserve symlinks/permissions/times, verbose, compress, # don't cross filesystems, sparse, show progress RSYNC_OPTS = -rlptvzxS --progress LAST_RELEASE ?= Pacemaker-$(VERSION) TAG ?= $(shell [ -n "`git tag --points-at HEAD | head -1`" ] \ && ( git tag --points-at HEAD | head -1 ) \ || git log --pretty=format:%H -n 1 HEAD) if IS_ASCIIDOC ASCIIDOC_HTML_ARGS = --unsafe --backend=xhtml11 ASCIIDOC_DBOOK_ARGS = -b docbook -d book else ASCIIDOC_HTML_ARGS = --backend=html5 ASCIIDOC_DBOOK_ARGS = -b docbook45 -d book endif %.html: %.txt $(AM_V_GEN)$(ASCIIDOC_CONV) $(ASCIIDOC_HTML_ARGS) --out-file=$@ $< $(PCMK_quiet) # For Makefile debugging .PHONY: vars vars: @echo DEPRECATED_ORIGINAL=\'$(DEPRECATED_ORIGINAL)\' @echo DEPRECATED_GENERATED=\'$(DEPRECATED_GENERATED)\' @echo LAST_RELEASE=\'$(LAST_RELEASE)\' @echo TAG=\'$(TAG)\' .PHONY: deprecated-upload deprecated-upload: $(DEPRECATED_ALL) rsync $(RSYNC_OPTS) $(DEPRECATED_ALL) "$(RSYNC_DEST)/$(PACKAGE)/doc/" .PHONY: deprecated-clean deprecated-clean: -rm -f $(DEPRECATED_GENERATED) # Annotated source code as HTML global: $(MAKE) $(AM_MAKEFLAGS) -C .. clean-generic cd .. && gtags -q && htags -sanhIT doc global-upload: global rsync $(RSYNC_OPTS) HTML/ "$(RSYNC_DEST)/$(PACKAGE)/global/$(TAG)/" global-clean: -rm -rf HTML # Man pages as HTML %.8.html: %.8 groff -mandoc `man -w ./$<` -T html > $@ %.7.html: %.7 groff -mandoc `man -w ./$<` -T html > $@ manhtml: $(MAKE) $(AM_MAKEFLAGS) -C .. all find .. -name "[a-z]*.[78]" -exec $(MAKE) $(AM_MAKEFLAGS) \{\}.html \; manhtml-upload: manhtml find .. -name "[a-z]*.[78].html" -exec \ rsync $(RSYNC_OPTS) \{\} "$(RSYNC_DEST)/$(PACKAGE)/man/" \; manhtml-clean: -find .. -name "[a-z]*.[78].html" -exec rm \{\} \; # API documentation as HTML doxygen: Doxyfile doxygen Doxyfile doxygen-upload: doxygen rsync $(RSYNC_OPTS) api/html/ "$(RSYNC_DEST)/$(PACKAGE)/doxygen/$(TAG)/" doxygen-clean: -rm -rf api # ABI compatibility report as HTML abi: abi-check ./abi-check $(PACKAGE) $(LAST_RELEASE) $(TAG) abi-www: export RSYNC_DEST=$(RSYNC_DEST); ./abi-check -u $(PACKAGE) $(LAST_RELEASE) $(TAG) abi-clean: -rm -rf abi_dumps compat_reports # The main documentation books (which are actually in the sphinx subdirectory) books-upload: $(MAKE) $(AM_MAKEFLAGS) -C sphinx clean $(MAKE) $(AM_MAKEFLAGS) -C sphinx \ RSYNC_DEST="$(RSYNC_DEST)" \ BOOK_FORMATS="$(BOOK_FORMATS)" \ books-upload # All online documentation (except ABI compatibility, which is run separately) .PHONY: www www: clean-local deprecated-upload manhtml-upload global-upload doxygen-upload books-upload clean-local: global-clean manhtml-clean doxygen-clean abi-clean deprecated-clean diff --git a/doc/pcs-crmsh-quick-ref.md b/doc/pcs-crmsh-quick-ref.md deleted file mode 100644 index 9fa16d8314..0000000000 --- a/doc/pcs-crmsh-quick-ref.md +++ /dev/null @@ -1,365 +0,0 @@ - - - - -**Table of Contents** - -- [General Operations](#general-operations) - - [Display the configuration](#display-the-configuration) - - [Display the current status](#display-the-current-status) - - [Node standby](#node-standby) - - [Set cluster property](#set-cluster-property) -- [Resource manipulation](#resource-manipulation) - - [List Resource Agent (RA) classes](#list-resource-agent-ra-classes) - - [List available RAs](#list-available-ras) - - [List RA info](#list-ra-info) - - [Create a resource](#create-a-resource) - - [Display a resource](#display-a-resource) - - [Display fencing resources](#display-fencing-resources) - - [Display Stonith RA info](#display-stonith-ra-info) - - [Start a resource](#start-a-resource) - - [Stop a resource](#stop-a-resource) - - [Remove a resource](#remove-a-resource) - - [Modify a resource](#modify-a-resource) - - [Delete parameters for a given resource](#delete-parameters-for-a-given-resource) - - [List the current resource defaults](#list-the-current-resource-defaults) - - [Set resource defaults](#set-resource-defaults) - - [List the current operation defaults](#list-the-current-operation-defaults) - - [Set operation defaults](#set-operation-defaults) - - [Set Colocation](#set-colocation) - - [Set ordering](#set-ordering) - - [Set preferred location](#set-preferred-location) - - [Move resources](#move-resources) - - [Resource tracing](#resource-tracing) - - [Clear fail counts](#clear-fail-counts) - - [Edit fail counts](#edit-fail-counts) - - [Handling configuration elements by type](#handling-configuration-elements-by-type) - - [Create a clone](#create-a-clone) - - [Create a promotable (master/slave) clone](#create-a-promotable-masterslave-clone) -- [Other operations](#other-operations) - - [Batch changes](#batch-changes) - - [Template creation](#template-creation) - - [Log analysis](#log-analysis) - - [Configuration scripts](#configuration-scripts) - - - -# General Operations - -## Display the configuration - - crmsh # crm configure show xml - pcs # pcs cluster cib - -To show a simplified (non-xml) syntax - - crmsh # crm configure show - pcs # pcs config - -## Display the current status - - crmsh # crm status - pcs # pcs status - -also - - # crm_mon -1 - -## Node standby - -Put node in standby - - crmsh # crm node standby pcmk-1 - pcs-0.9 # pcs cluster standby pcmk-1 - pcs-0.10 # pcs node standby pcmk-1 - -Remove node from standby - - crmsh # crm node online pcmk-1 - pcs-0.9 # pcs cluster unstandby pcmk-1 - pcs-0.10 # pcs node unstandby pcmk-1 - -crm has the ability to set the status on reboot or forever. -pcs can apply the change to all the nodes. - -## Set cluster property - - crmsh # crm configure property stonith-enabled=false - pcs # pcs property set stonith-enabled=false - -# Resource manipulation - -## List Resource Agent (RA) classes - - crmsh # crm ra classes - pcs # pcs resource standards - -## List available RAs - - crmsh # crm ra list ocf - crmsh # crm ra list lsb - crmsh # crm ra list service - crmsh # crm ra list stonith - pcs # pcs resource agents ocf - pcs # pcs resource agents lsb - pcs # pcs resource agents service - pcs # pcs resource agents stonith - pcs # pcs resource agents - -You can also filter by provider - - crmsh # crm ra list ocf pacemaker - pcs # pcs resource agents ocf:pacemaker - -## List RA info - - crmsh # crm ra meta IPaddr2 - pcs # pcs resource describe IPaddr2 - -Use any RA name (like IPaddr2) from the list displayed with the previous command -You can also use the full class:provider:RA format if multiple RAs with the same name are available : - - crmsh # crm ra meta ocf:heartbeat:IPaddr2 - pcs # pcs resource describe ocf:heartbeat:IPaddr2 - -## Create a resource - - crmsh # crm configure primitive ClusterIP ocf:heartbeat:IPaddr2 \ - params ip=192.168.122.120 cidr_netmask=24 \ - op monitor interval=30s - pcs # pcs resource create ClusterIP IPaddr2 ip=192.168.0.120 cidr_netmask=24 - -The standard and provider (`ocf:heartbeat`) are determined automatically since `IPaddr2` is unique. -The monitor operation is automatically created based on the agent's metadata. - -## Display a resource - - crmsh # crm configure show - pcs-0.9 # pcs resource show --full - pcs-0.10 # pcs resource config - -crmsh also displays fencing resources. -The result can be filtered by supplying a resource name (IE `ClusterIP`): - - crmsh # crm configure show ClusterIP - pcs-0.9 # pcs resource show ClusterIP - pcs-0.10 # pcs resource config ClusterIP - -crmsh also displays fencing resources. - -## Display fencing resources - - crmsh # crm resource show - pcs-0.9 # pcs stonith show --full - pcs-0.10 # pcs stonith config - -pcs treats STONITH devices separately. - -## Display Stonith RA info - - crmsh # crm ra meta stonith:fence_ipmilan - pcs # pcs stonith describe fence_ipmilan - -## Start a resource - - crmsh # crm resource start ClusterIP - pcs # pcs resource enable ClusterIP - -## Stop a resource - - crmsh # crm resource stop ClusterIP - pcs # pcs resource disable ClusterIP - -## Remove a resource - - crmsh # crm configure delete ClusterIP - pcs # pcs resource delete ClusterIP - -## Modify a resource - - crmsh # crm resource param ClusterIP set clusterip_hash=sourceip - pcs # pcs resource update ClusterIP clusterip_hash=sourceip - -crmsh also has an `edit` command which edits the simplified CIB syntax -(same commands as the command line) via a configurable text editor. - - crmsh # crm configure edit ClusterIP - -Using the interactive shell mode of crmsh, multiple changes can be -edited and verified before committing to the live configuration. - - crmsh # crm configure - crmsh # edit - crmsh # verify - crmsh # commit - -## Delete parameters for a given resource - - crmsh # crm resource param ClusterIP delete nic - pcs # pcs resource update ClusterIP ip=192.168.0.98 nic= - -## List the current resource defaults - - crmsh # crm configure show type:rsc_defaults - pcs # pcs resource defaults - -## Set resource defaults - - crmsh # crm configure rsc_defaults resource-stickiness=100 - pcs # pcs resource defaults resource-stickiness=100 - -## List the current operation defaults - - crmsh # crm configure show type:op_defaults - pcs # pcs resource op defaults - -## Set operation defaults - - crmsh # crm configure op_defaults timeout=240s - pcs # pcs resource op defaults timeout=240s - -## Set Colocation - - crmsh # crm configure colocation website-with-ip INFINITY: WebSite ClusterIP - pcs # pcs constraint colocation add ClusterIP with WebSite INFINITY - -With roles - - crmsh # crm configure colocation another-ip-with-website inf: AnotherIP WebSite:Master - pcs # pcs constraint colocation add Started AnotherIP with Master WebSite INFINITY - -## Set ordering - - crmsh # crm configure order apache-after-ip mandatory: ClusterIP WebSite - pcs # pcs constraint order ClusterIP then WebSite - -With roles: - - crmsh # crm configure order ip-after-website Mandatory: WebSite:Master AnotherIP - pcs # pcs constraint order promote WebSite then start AnotherIP - -## Set preferred location - - crmsh # crm configure location prefer-pcmk-1 WebSite 50: pcmk-1 - pcs # pcs constraint location WebSite prefers pcmk-1=50 - -With roles: - - crmsh # crm configure location prefer-pcmk-1 WebSite rule role=Master 50: \#uname eq pcmk-1 - pcs # pcs constraint location WebSite rule role=master 50 \#uname eq pcmk-1 - -## Move resources - - crmsh # crm resource move WebSite pcmk-1 - pcs # pcs resource move WebSite pcmk-1 - - crmsh # crm resource unmove WebSite - pcs # pcs resource clear WebSite - -A resource can also be moved away from a given node: - - crmsh # crm resource ban Website pcmk-2 - pcs # pcs resource ban Website pcmk-2 - -Remember that moving a resource sets a stickyness to -INF to a given node until unmoved - -## Resource tracing - - crmsh # crm resource trace Website - -## Clear fail counts - - crmsh # crm resource cleanup Website - pcs # pcs resource cleanup Website - -## Edit fail counts - - crmsh # crm resource failcount Website show pcmk-1 - crmsh # crm resource failcount Website set pcmk-1 100 - -## Handling configuration elements by type - -pcs deals with constraints differently. These can be manipulated by the command above as well as the following and others - - pcs # pcs constraint list --full - pcs # pcs constraint remove cli-ban-Website-on-pcmk-1 - -Removing a constraint in crmsh uses the same command as removing a -resource. - - crmsh # crm configure remove cli-ban-Website-on-pcmk-1 - -The `show` and `edit` commands in crmsh can be used to manage -resources and constraints by type: - - crmsh # crm configure show type:primitive - crmsh # crm configure edit type:colocation - -## Create a clone - - crmsh # crm configure clone WebIP ClusterIP meta globally-unique=true clone-max=2 clone-node-max=2 - pcs # pcs resource clone ClusterIP globally-unique=true clone-max=2 clone-node-max=2 - -## Create a promotable (master/slave) clone - - crmsh # crm configure ms WebDataClone WebData \ - meta master-max=1 master-node-max=1 \ - clone-max=2 clone-node-max=1 notify=true - pcs-0.9 # pcs resource master WebDataClone WebData \ - master-max=1 master-node-max=1 \ - clone-max=2 clone-node-max=1 notify=true - pcs-0.10 # pcs resource promotable WebData \ - promoted-max=1 promoted-node-max=1 \ - clone-max=2 clone-node-max=1 notify=true - -# Other operations - -## Batch changes - - crmsh # crm - crmsh # cib new drbd_cfg - crmsh # configure primitive WebData ocf:linbit:drbd params drbd_resource=wwwdata \ - op monitor interval=60s - crmsh # configure ms WebDataClone WebData meta master-max=1 master-node-max=1 \ - clone-max=2 clone-node-max=1 notify=true - crmsh # cib commit drbd_cfg - crmsh # quit -. - - pcs # pcs cluster cib drbd_cfg - pcs # pcs -f drbd_cfg resource create WebData ocf:linbit:drbd drbd_resource=wwwdata \ - op monitor interval=60s - pcs-0.9 # pcs -f drbd_cfg resource master WebDataClone WebData master-max=1 master-node-max=1 \ - clone-max=2 clone-node-max=1 notify=true - pcs-0.10 # pcs -f drbd_cfg resource promotable WebData promoted-max=1 promoted-node-max=1 \ - clone-max=2 clone-node-max=1 notify=true - pcs # pcs cluster push cib drbd_cfg - -## Template creation - -Create a resource template based on a list of primitives of the same -type - - crmsh # crm configure assist template ClusterIP AdminIP - -## Log analysis - -Display information about recent cluster events - - crmsh # crm history - crmsh # peinputs - crmsh # transition pe-input-10 - crmsh # transition log pe-input-10 - -## Configuration scripts - -Create and apply multiple-step cluster configurations including -configuration of cluster resources - - crmsh # crm script show apache - crmsh # crm script run apache \ - id=WebSite \ - install=true \ - virtual-ip:ip=192.168.0.15 \ - database:id=WebData \ - database:install=true diff --git a/doc/sphinx/Pacemaker_Administration/index.rst b/doc/sphinx/Pacemaker_Administration/index.rst index 97731245d0..9686863a0a 100644 --- a/doc/sphinx/Pacemaker_Administration/index.rst +++ b/doc/sphinx/Pacemaker_Administration/index.rst @@ -1,34 +1,35 @@ Pacemaker Administration ======================== *Managing Pacemaker Clusters* Abstract -------- This document has instructions and tips for system administrators who manage high-availability clusters using Pacemaker. Table of Contents ----------------- .. toctree:: :maxdepth: 3 :numbered: intro installing cluster configuring tools troubleshooting upgrading agents + pcs-crmsh Index ----- * :ref:`genindex` * :ref:`search` diff --git a/doc/sphinx/Pacemaker_Administration/pcs-crmsh.rst b/doc/sphinx/Pacemaker_Administration/pcs-crmsh.rst new file mode 100644 index 0000000000..61ab4e6b64 --- /dev/null +++ b/doc/sphinx/Pacemaker_Administration/pcs-crmsh.rst @@ -0,0 +1,441 @@ +Quick Comparison of pcs and crm shell +------------------------------------- + +``pcs`` and ``crm shell`` are two popular higher-level command-line interfaces +to Pacemaker. Each has its own syntax; this chapter gives a quick comparion of +how to accomplish the same tasks using either one. Some examples also show the +equivalent command using low-level Pacmaker command-line tools. + +These examples show the simplest syntax; see the respective man pages for all +possible options. + +Show Cluster Configuration and Status +##################################### + +.. topic:: Show Configuration (Raw XML) + + .. code-block:: none + + crmsh # crm configure show xml + pcs # pcs cluster cib + pacemaker # cibadmin -Q + +.. topic:: Show Configuration (Human-friendly) + + .. code-block:: none + + crmsh # crm configure show + pcs # pcs config + +.. topic:: Show Cluster Status + + .. code-block:: none + + crmsh # crm status + pcs # pcs status + pacemaker # crm_mon -1 + +Manage Nodes +############ + +.. topic:: Put node "pcmk-1" in standby mode + + .. code-block:: none + + crmsh # crm node standby pcmk-1 + pcs-0.9 # pcs cluster standby pcmk-1 + pcs-0.10 # pcs node standby pcmk-1 + pacemaker # crm_standby -N pcmk-1 -v on + +.. topic:: Remove node "pcmk-1" from standby mode + + .. code-block:: none + + crmsh # crm node online pcmk-1 + pcs-0.9 # pcs cluster unstandby pcmk-1 + pcs-0.10 # pcs node unstandby pcmk-1 + pacemaker # crm_standby -N pcmk-1 -v off + +Manage Cluster Properties +######################### + +.. topic:: Set the "stonith-enabled" cluster property to "false" + + .. code-block:: none + + crmsh # crm configure property stonith-enabled=false + pcs # pcs property set stonith-enabled=false + pacemaker # crm_attribute -n stonith-enabled -v false + +Show Resource Agent Information +############################### + +.. topic:: List Resource Agent (RA) Classes + + .. code-block:: none + + crmsh # crm ra classes + pcs # pcs resource standards + pacmaker # crm_resource --list-standards + +.. topic:: List Available Resource Agents (RAs) by Standard + + .. code-block:: none + + crmsh # crm ra list ocf + pcs # pcs resource agents ocf + pacemaker # crm_resource --list-agents ocf + +.. topic:: List Available Resource Agents (RAs) by OCF Provider + + .. code-block:: none + + crmsh # crm ra list ocf pacemaker + pcs # pcs resource agents ocf:pacemaker + pacemaker # crm_resource --list-agents ocf:pacemaker + +.. topic:: List Available Resource Agent Parameters + + .. code-block:: none + + crmsh # crm ra info IPaddr2 + pcs # pcs resource describe IPaddr2 + pacemaker # crm_resource --show-metadata ocf:heartbeat:IPaddr2 + +You can also use the full ``class:provider:type`` format with crmsh and pcs if +multiple RAs with the same name are available. + +.. topic:: Show Available Fence Agent Parameters + + .. code-block:: none + + crmsh # crm ra info stonith:fence_ipmilan + pcs # pcs stonith describe fence_ipmilan + +Manage Resources +################ + +.. topic:: Create a Resource + + .. code-block:: none + + crmsh # crm configure primitive ClusterIP ocf:heartbeat:IPaddr2 \ + params ip=192.168.122.120 cidr_netmask=24 \ + op monitor interval=30s + pcs # pcs resource create ClusterIP IPaddr2 ip=192.168.122.120 cidr_netmask=24 + +pcs determines the standard and provider (``ocf:heartbeat``) automatically +since ``IPaddr2`` is unique, and automatically creates operations (including +monitor) based on the agent's meta-data. + +.. topic:: Show Configuration of All Resources + + .. code-block:: none + + crmsh # crm configure show + pcs-0.9 # pcs resource show --full + pcs-0.10 # pcs resource config + +.. topic:: Show Configuration of One Resource + + .. code-block:: none + + crmsh # crm configure show ClusterIP + pcs-0.9 # pcs resource show ClusterIP + pcs-0.10 # pcs resource config ClusterIP + +.. topic:: Show Configuration of Fencing Resources + + .. code-block:: none + + crmsh # crm resource status + pcs-0.9 # pcs stonith show --full + pcs-0.10 # pcs stonith config + +.. topic:: Start a Resource + + .. code-block:: none + + crmsh # crm resource start ClusterIP + pcs # pcs resource enable ClusterIP + pacemaker # crm_resource -r ClusterIP --set-parameter target-role --meta -v Started + +.. topic:: Stop a Resource + + .. code-block:: none + + crmsh # crm resource stop ClusterIP + pcs # pcs resource disable ClusterIP + pacemaker # crm_resource -r ClusterIP --set-parameter target-role --meta -v Stopped + +.. topic:: Remove a Resource + + .. code-block:: none + + crmsh # crm configure delete ClusterIP + pcs # pcs resource delete ClusterIP + +.. topic:: Modify a Resource's Instance Parameters + + .. code-block:: none + + crmsh # crm resource param ClusterIP set clusterip_hash=sourceip + pcs # pcs resource update ClusterIP clusterip_hash=sourceip + pacemaker # crm_resource -r ClusterIP --set-parameter clusterip_hash -v sourceip + +crmsh also has an `edit` command which edits the simplified CIB syntax +(same commands as the command line) via a configurable text editor. + +.. topic:: Modify a Resource's Instance Parameters Interactively + + .. code-block:: none + + crmsh # crm configure edit ClusterIP + +Using the interactive shell mode of crmsh, multiple changes can be +edited and verified before committing to the live configuration: + +.. topic:: Make Multiple Configuration Changes Interactively + + .. code-block:: none + + crmsh # crm configure + crmsh # edit + crmsh # verify + crmsh # commit + +.. topic:: Delete a Resource's Instance Parameters + + .. code-block:: none + + crmsh # crm resource param ClusterIP delete nic + pcs # pcs resource update ClusterIP nic= + pacemaker # crm_resource -r ClusterIP --delete-parameter nic + +.. topic:: List Current Resource Defaults + + .. code-block:: none + + crmsh # crm configure show type:rsc_defaults + pcs # pcs resource defaults + pacemaker # cibadmin -Q --scope rsc_defaults + +.. topic:: Set Resource Defaults + + .. code-block:: none + + crmsh # crm configure rsc_defaults resource-stickiness=100 + pcs # pcs resource defaults resource-stickiness=100 + +.. topic:: List Current Operation Defaults + + .. code-block:: none + + crmsh # crm configure show type:op_defaults + pcs # pcs resource op defaults + pacemaker # cibadmin -Q --scope op_defaults + +.. topic:: Set Operation Defaults + + .. code-block:: none + + crmsh # crm configure op_defaults timeout=240s + pcs # pcs resource op defaults timeout=240s + +.. topic:: Enable Resource Agent Tracing for a Resource + + .. code-block:: none + + crmsh # crm resource trace Website + +.. topic:: Clear Fail Counts for a Resource + + .. code-block:: none + + crmsh # crm resource cleanup Website + pcs # pcs resource cleanup Website + pacemaker # crm_resource --cleanup -r Website + +.. topic:: Create a Clone Resource + + .. code-block:: none + + crmsh # crm configure clone WebIP ClusterIP meta globally-unique=true clone-max=2 clone-node-max=2 + pcs # pcs resource clone ClusterIP globally-unique=true clone-max=2 clone-node-max=2 + +.. topic:: Create a Promotable Clone Resource + + .. code-block:: none + + crmsh # crm configure ms WebDataClone WebData \ + meta master-max=1 master-node-max=1 \ + clone-max=2 clone-node-max=1 notify=true + pcs-0.9 # pcs resource master WebDataClone WebData \ + master-max=1 master-node-max=1 \ + clone-max=2 clone-node-max=1 notify=true + pcs-0.10 # pcs resource promotable WebData WebDataClone \ + promoted-max=1 promoted-node-max=1 \ + clone-max=2 clone-node-max=1 notify=true + +pcs will generate the clone name automatically if it is omitted from the +command line. + + +Manage Constraints +################## + +.. topic:: Create a Colocation Constraint + + .. code-block:: none + + crmsh # crm configure colocation website-with-ip INFINITY: WebSite ClusterIP + pcs # pcs constraint colocation add ClusterIP with WebSite INFINITY + +.. topic:: Create a Colocation Constraint Based on Role + + .. code-block:: none + + crmsh # crm configure colocation another-ip-with-website inf: AnotherIP WebSite:Master + pcs # pcs constraint colocation add Started AnotherIP with Promoted WebSite INFINITY + +.. topic:: Create an Ordering Constraint + + .. code-block:: none + + crmsh # crm configure order apache-after-ip mandatory: ClusterIP WebSite + pcs # pcs constraint order ClusterIP then WebSite + +.. topic:: Create an Ordering Constraint Based on Role + + .. code-block:: none + + crmsh # crm configure order ip-after-website Mandatory: WebSite:Master AnotherIP + pcs # pcs constraint order promote WebSite then start AnotherIP + +.. topic:: Create a Location Constraint + + .. code-block:: none + + crmsh # crm configure location prefer-pcmk-1 WebSite 50: pcmk-1 + pcs # pcs constraint location WebSite prefers pcmk-1=50 + +.. topic:: Create a Location Constraint Based on Role + + .. code-block:: none + + crmsh # crm configure location prefer-pcmk-1 WebSite rule role=Master 50: \#uname eq pcmk-1 + pcs # pcs constraint location WebSite rule role=Promoted 50 \#uname eq pcmk-1 + +.. topic:: Move a Resource to a Specific Node (by Creating a Location Constraint) + + .. code-block:: none + + crmsh # crm resource move WebSite pcmk-1 + pcs # pcs resource move WebSite pcmk-1 + pacemaker # crm_resource -r WebSite --move -N pcmk-1 + +.. topic:: Move a Resource Away from Its Current Node (by Creating a Location Constraint) + + .. code-block:: none + + crmsh # crm resource ban Website pcmk-2 + pcs # pcs resource ban Website pcmk-2 + pacemaker # crm_resource -r WebSite --move + +.. topic:: Remove any Constraints Created by Moving a Resource + + .. code-block:: none + + crmsh # crm resource unmove WebSite + pcs # pcs resource clear WebSite + pacemaker # crm_resource -r WebSite --clear + +Advanced Configuration +###################### + +Manipulate Configuration Elements by Type +_________________________________________ + +.. topic:: List Constraints with IDs + + .. code-block:: none + + pcs # pcs constraint list --full + +.. topic:: Remove Constraint by ID + + .. code-block:: none + + pcs # pcs constraint remove cli-ban-Website-on-pcmk-1 + crmsh # crm configure remove cli-ban-Website-on-pcmk-1 + +crmsh's `show` and `edit` commands can be used to manage resources and +constraints by type: + +.. topic:: Show Configuration Elements + + .. code-block:: none + + crmsh # crm configure show type:primitive + crmsh # crm configure edit type:colocation + +Batch Changes +_____________ + +.. topic:: Make Multiple Changes and Apply Together + + .. code-block:: none + + crmsh # crm + crmsh # cib new drbd_cfg + crmsh # configure primitive WebData ocf:linbit:drbd params drbd_resource=wwwdata \ + op monitor interval=60s + crmsh # configure ms WebDataClone WebData meta master-max=1 master-node-max=1 \ + clone-max=2 clone-node-max=1 notify=true + crmsh # cib commit drbd_cfg + crmsh # quit + + pcs # pcs cluster cib drbd_cfg + pcs # pcs -f drbd_cfg resource create WebData ocf:linbit:drbd drbd_resource=wwwdata \ + op monitor interval=60s + pcs-0.9 # pcs -f drbd_cfg resource master WebDataClone WebData \ + master-max=1 master-node-max=1 clone-max=2 clone-node-max=1 notify=true + pcs-0.10 # pcs -f drbd_cfg resource promotable WebData WebDataClone \ + promoted-max=1 promoted-node-max=1 clone-max=2 clone-node-max=1 notify=true + pcs # pcs cluster cib-push drbd_cfg + +Template Creation +_________________ + +.. topic:: Create Resource Template Based on Existing Primitives of Same Type + + .. code-block:: none + + crmsh # crm configure assist template ClusterIP AdminIP + +Log Analysis +____________ + +.. topic:: Show Information About Recent Cluster Events + + .. code-block:: none + + crmsh # crm history + crmsh # peinputs + crmsh # transition pe-input-10 + crmsh # transition log pe-input-10 + +Configuration Scripts +_____________________ + +.. topic:: Script Multiple-step Cluster Configurations + + .. code-block:: none + + crmsh # crm script show apache + crmsh # crm script run apache \ + id=WebSite \ + install=true \ + virtual-ip:ip=192.168.0.15 \ + database:id=WebData \ + database:install=true diff --git a/doc/sphinx/Pacemaker_Administration/upgrading.rst b/doc/sphinx/Pacemaker_Administration/upgrading.rst index 5b35d3fc04..687a875002 100644 --- a/doc/sphinx/Pacemaker_Administration/upgrading.rst +++ b/doc/sphinx/Pacemaker_Administration/upgrading.rst @@ -1,504 +1,535 @@ .. index:: upgrade Upgrading a Pacemaker Cluster ----------------------------- .. index:: version Pacemaker Versioning #################### Pacemaker has an overall release version, plus separate version numbers for certain internal components. .. index:: single: version; release * **Pacemaker release version:** This version consists of three numbers (*x.y.z*). The major version number (the *x* in *x.y.z*) increases when at least some rolling upgrades are not possible from the previous major version. For example, a rolling upgrade from 1.0.8 to 1.1.15 should always be supported, but a rolling upgrade from 1.0.8 to 2.0.0 may not be possible. The minor version (the *y* in *x.y.z*) increases when there are significant changes in cluster default behavior, tool behavior, and/or the API interface (for software that utilizes Pacemaker libraries). The main benefit is to alert you to pay closer attention to the release notes, to see if you might be affected. The release counter (the *z* in *x.y.z*) is increased with all public releases of Pacemaker, which typically include both bug fixes and new features. .. index:: single: feature set single: version; feature set * **CRM feature set:** This version number applies to the communication between full cluster nodes, and is used to avoid problems in mixed-version clusters. The major version number increases when nodes with different versions would not work (rolling upgrades are not allowed). The minor version number increases when mixed-version clusters are allowed only during rolling upgrades. The minor-minor version number is ignored, but allows resource agents to detect cluster support for various features. [#]_ Pacemaker ensures that the longest-running node is the cluster's DC. This ensures new features are not enabled until all nodes are upgraded to support them. .. index:: single: version; Pacemaker Remote protocol * **Pacemaker Remote protocol version:** This version applies to communication between a Pacemaker Remote node and the cluster. It increases when an older cluster node would have problems hosting the connection to a newer Pacemaker Remote node. To avoid these problems, Pacemaker Remote nodes will accept connections only from cluster nodes with the same or newer Pacemaker Remote protocol version. Unlike with CRM feature set differences between full cluster nodes, mixed Pacemaker Remote protocol versions between Pacemaker Remote nodes and full cluster nodes are fine, as long as the Pacemaker Remote nodes have the older version. This can be useful, for example, to host a legacy application in an older operating system version used as a Pacemaker Remote node. .. index:: single: version; XML schema * **XML schema version:** Pacemaker’s configuration syntax — what's allowed in the Configuration Information Base (CIB) — has its own version. This allows the configuration syntax to evolve over time while still allowing clusters with older configurations to work without change. .. index:: single: upgrade; methods Upgrading Cluster Software ########################## There are three approaches to upgrading a cluster, each with advantages and disadvantages. .. table:: **Upgrade Methods** +---------------------------------------------------+----------+----------+--------+---------+----------+----------+ | Method | Available| Can be | Service| Service | Exercises| Allows | | | between | used with| outage | recovery| failover | change of| | | all | Pacemaker| during | during | logic | messaging| | | versions | Remote | upgrade| upgrade | | layer | | | | nodes | | | | [#]_ | +===================================================+==========+==========+========+=========+==========+==========+ | Complete cluster shutdown | yes | yes | always | N/A | no | yes | +---------------------------------------------------+----------+----------+--------+---------+----------+----------+ | Rolling (node by node) | no | yes | always | yes | yes | no | | | | | [#]_ | | | | +---------------------------------------------------+----------+----------+--------+---------+----------+----------+ | Detach and reattach | yes | no | only | no | no | yes | | | | | due to | | | | | | | | failure| | | | +---------------------------------------------------+----------+----------+--------+---------+----------+----------+ .. index:: single: upgrade; shutdown Complete Cluster Shutdown _________________________ In this scenario, one shuts down all cluster nodes and resources, then upgrades all the nodes before restarting the cluster. #. On each node: a. Shutdown the cluster software (pacemaker and the messaging layer). #. Upgrade the Pacemaker software. This may also include upgrading the messaging layer and/or the underlying operating system. #. Check the configuration with the ``crm_verify`` tool. #. On each node: a. Start the cluster software. Currently, only Corosync version 2 and greater is supported as the cluster layer, but if another stack is supported in the future, the stack does not need to be the same one before the upgrade. One variation of this approach is to build a new cluster on new hosts. This allows the new version to be tested beforehand, and minimizes downtime by having the new nodes ready to be placed in production as soon as the old nodes are shut down. .. index:: single: upgrade; rolling upgrade Rolling (node by node) ______________________ In this scenario, each node is removed from the cluster, upgraded, and then brought back online, until all nodes are running the newest version. Special considerations when planning a rolling upgrade: * If you plan to upgrade other cluster software -- such as the messaging layer -- at the same time, consult that software's documentation for its compatibility with a rolling upgrade. * If the major version number is changing in the Pacemaker version you are upgrading to, a rolling upgrade may not be possible. Read the new version's release notes (as well the information here) for what limitations may exist. * If the CRM feature set is changing in the Pacemaker version you are upgrading to, you should run a mixed-version cluster only during a small rolling upgrade window. If one of the older nodes drops out of the cluster for any reason, it will not be able to rejoin until it is upgraded. * If the Pacemaker Remote protocol version is changing, all cluster nodes should be upgraded before upgrading any Pacemaker Remote nodes. See the ClusterLabs wiki's `release calendar `_ to figure out whether the CRM feature set and/or Pacemaker Remote protocol version changed between the the Pacemaker release versions in your rolling upgrade. To perform a rolling upgrade, on each node in turn: #. Put the node into standby mode, and wait for any active resources to be moved cleanly to another node. (This step is optional, but allows you to deal with any resource issues before the upgrade.) #. Shutdown the cluster software (pacemaker and the messaging layer) on the node. #. Upgrade the Pacemaker software. This may also include upgrading the messaging layer and/or the underlying operating system. #. If this is the first node to be upgraded, check the configuration with the ``crm_verify`` tool. #. Start the messaging layer. This must be the same messaging layer (currently only Corosync version 2 and greater is supported) that the rest of the cluster is using. .. note:: Even if a rolling upgrade from the current version of the cluster to the newest version is not directly possible, it may be possible to perform a rolling upgrade in multiple steps, by upgrading to an intermediate version first. .. table:: **Version Compatibility Table** +-------------------------+---------------------------+ | Version being Installed | Oldest Compatible Version | +=========================+===========================+ | Pacemaker 2.y.z | Pacemaker 1.1.11 [#]_ | +-------------------------+---------------------------+ | Pacemaker 1.y.z | Pacemaker 1.0.0 | +-------------------------+---------------------------+ | Pacemaker 0.7.z | Pacemaker 0.6.z | +-------------------------+---------------------------+ .. index:: single: upgrade; detach and reattach Detach and Reattach ___________________ The reattach method is a variant of a complete cluster shutdown, where the resources are left active and get re-detected when the cluster is restarted. This method may not be used if the cluster contains any Pacemaker Remote nodes. #. Tell the cluster to stop managing services. This is required to allow the services to remain active after the cluster shuts down. .. code-block:: none # crm_attribute --name maintenance-mode --update true #. On each node, shutdown the cluster software (pacemaker and the messaging layer), and upgrade the Pacemaker software. This may also include upgrading the messaging layer. While the underlying operating system may be upgraded at the same time, that will be more likely to cause outages in the detached services (certainly, if a reboot is required). #. Check the configuration with the ``crm_verify`` tool. #. On each node, start the cluster software. Currently, only Corosync version 2 and greater is supported as the cluster layer, but if another stack is supported in the future, the stack does not need to be the same one before the upgrade. #. Verify that the cluster re-detected all resources correctly. #. Allow the cluster to resume managing resources again: .. code-block:: none # crm_attribute --name maintenance-mode --delete .. note:: While the goal of the detach-and-reattach method is to avoid disturbing running services, resources may still move after the upgrade if any resource's location is governed by a rule based on transient node attributes. Transient node attributes are erased when the node leaves the cluster. A common example is using the ``ocf:pacemaker:ping`` resource to set a node attribute used to locate other resources. .. index:: pair: upgrade; CIB Upgrading the Configuration ########################### The CIB schema version can change from one Pacemaker version to another. After cluster software is upgraded, the cluster will continue to use the older schema version that it was previously using. This can be useful, for example, when administrators have written tools that modify the configuration, and are based on the older syntax. [#]_ However, when using an older syntax, new features may be unavailable, and there is a performance impact, since the cluster must do a non-persistent configuration upgrade before each transition. So while using the old syntax is possible, it is not advisable to continue using it indefinitely. Even if you wish to continue using the old syntax, it is a good idea to follow the upgrade procedure outlined below, except for the last step, to ensure that the new software has no problems with your existing configuration (since it will perform much the same task internally). If you are brave, it is sufficient simply to run ``cibadmin --upgrade``. A more cautious approach would proceed like this: #. Create a shadow copy of the configuration. The later commands will automatically operate on this copy, rather than the live configuration. .. code-block:: none # crm_shadow --create shadow .. index:: single: configuration; verify #. Verify the configuration is valid with the new software (which may be stricter about syntax mistakes, or may have dropped support for deprecated features): .. code-block:: none # crm_verify --live-check #. Fix any errors or warnings. #. Perform the upgrade: .. code-block:: none # cibadmin --upgrade #. If this step fails, there are three main possibilities: a. The configuration was not valid to start with (did you do steps 2 and 3?). #. The transformation failed; `report a bug `_. #. The transformation was successful but produced an invalid result. If the result of the transformation is invalid, you may see a number of errors from the validation library. If these are not helpful, visit the `Validation FAQ wiki page `_ and/or try the manual upgrade procedure described below. #. Check the changes: .. code-block:: none # crm_shadow --diff If at this point there is anything about the upgrade that you wish to fine-tune (for example, to change some of the automatic IDs), now is the time to do so: .. code-block:: none # crm_shadow --edit This will open the configuration in your favorite editor (whichever is specified by the standard ``$EDITOR`` environment variable). #. Preview how the cluster will react: .. code-block:: none # crm_simulate --live-check --save-dotfile shadow.dot -S # dot -Tsvg shadow.dot -o shadow.svg You can then view shadow.svg with any compatible image viewer or web browser. Verify that either no resource actions will occur or that you are happy with any that are scheduled. If the output contains actions you do not expect (possibly due to changes to the score calculations), you may need to make further manual changes. See :ref:`crm_simulate` for further details on how to interpret the output of ``crm_simulate`` and ``dot``. #. Upload the changes: .. code-block:: none # crm_shadow --commit shadow --force In the unlikely event this step fails, please report a bug. .. note:: It is also possible to perform the configuration upgrade steps manually: #. Locate the ``upgrade*.xsl`` conversion scripts provided with the source code. These will often be installed in a location such as ``/usr/share/pacemaker``, or may be obtained from the `source repository `_. #. Run the conversion scripts that apply to your older version, for example: .. code-block:: none # xsltproc /path/to/upgrade06.xsl config06.xml > config10.xml #. Locate the ``pacemaker.rng`` script (from the same location as the xsl files). #. Check the XML validity: .. code-block:: none # xmllint --relaxng /path/to/pacemaker.rng config10.xml The advantage of this method is that it can be performed without the cluster running, and any validation errors are often more informative. +What Changed in 2.1 +################### + +The Pacemaker 2.1 release is fully backward-compatible in both the CIB XML and +the C API. Highlights: + +* Pacemaker now supports the **OCF Resource Agent API version 1.1**. + Most notably, the ``Master`` and ``Slave`` role names have been renamed to + ``Promoted`` and ``Unpromoted``. + +* Pacemaker now supports colocations where the dependent resource does not + affect the primary resource's placement (via a new ``influence`` colocation + constraint option and ``critical`` resource meta-attribute). This is intended + for cases where a less-important resource must be colocated with an essential + resource, but it is preferred to leave the less-important resource stopped if + it fails, rather than move both resources. + +* If Pacemaker is built with libqb 2.0 or later, the detail log will use + **millisecond-resolution timestamps**. + +* In addition to crm_mon and stonith_admin, the crmadmin, crm_resource, + crm_simulate, and crm_verify commands now support the ``--output-as`` and + ``--output-to`` options, including **XML output** (which scripts and + higher-level tools are strongly recommended to use instead of trying to parse + the text output, which may change from release to release). + +For a detailed list of changes, see the release notes and the +`Pacemaker 2.1 Changes `_ +page on the ClusterLabs wiki. + + What Changed in 2.0 ################### The main goal of the 2.0 release was to remove support for deprecated syntax, along with some small changes in default configuration behavior and tool behavior. Highlights: * Only Corosync version 2 and greater is now supported as the underlying cluster layer. Support for Heartbeat and Corosync 1 (including CMAN) is removed. * The Pacemaker detail log file is now stored in ``/var/log/pacemaker/pacemaker.log`` by default. * The record-pending cluster property now defaults to true, which allows status tools such as crm_mon to show operations that are in progress. * Support for a number of deprecated build options, environment variables, and configuration settings has been removed. * The ``master`` tag has been deprecated in favor of using the ``clone`` tag with the new ``promotable`` meta-attribute set to ``true``. "Master/slave" clone resources are now referred to as "promotable" clone resources. * The public API for Pacemaker libraries that software applications can use has changed significantly. For a detailed list of changes, see the release notes and the `Pacemaker 2.0 Changes `_ page on the ClusterLabs wiki. What Changed in 1.0 ################### New ___ * Failure timeouts. * New section for resource and operation defaults. * Tool for making offline configuration changes. * ``Rules``, ``instance_attributes``, ``meta_attributes`` and sets of operations can be defined once and referenced in multiple places. * The CIB now accepts XPath-based create/modify/delete operations. See ``cibadmin --help``. * Multi-dimensional colocation and ordering constraints. * The ability to connect to the CIB from non-cluster machines. * Allow recurring actions to be triggered at known times. Changed _______ * Syntax * All resource and cluster options now use dashes (-) instead of underscores (_) * ``master_slave`` was renamed to ``master`` * The ``attributes`` container tag was removed * The operation field ``pre-req`` has been renamed ``requires`` * All operations must have an ``interval``, ``start``/``stop`` must have it set to zero * The ``stonith-enabled`` option now defaults to true. * The cluster will refuse to start resources if ``stonith-enabled`` is true (or unset) and no STONITH resources have been defined * The attributes of colocation and ordering constraints were renamed for clarity. * ``resource-failure-stickiness`` has been replaced by ``migration-threshold``. * The parameters for command-line tools have been made consistent * Switched to 'RelaxNG' schema validation and 'libxml2' parser * id fields are now XML IDs which have the following limitations: * id's cannot contain colons (:) * id's cannot begin with a number * id's must be globally unique (not just unique for that tag) * Some fields (such as those in constraints that refer to resources) are IDREFs. This means that they must reference existing resources or objects in order for the configuration to be valid. Removing an object which is referenced elsewhere will therefore fail. * The CIB representation, from which a MD5 digest is calculated to verify CIBs on the nodes, has changed. This means that every CIB update will require a full refresh on any upgraded nodes until the cluster is fully upgraded to 1.0. This will result in significant performance degradation and it is therefore highly inadvisable to run a mixed 1.0/0.6 cluster for any longer than absolutely necessary. * Ping node information no longer needs to be added to ``ha.cf``. Simply include the lists of hosts in your ping resource(s). Removed _______ * Syntax * It is no longer possible to set resource meta options as top-level attributes. Use meta-attributes instead. * Resource and operation defaults are no longer read from ``crm_config``. .. rubric:: Footnotes .. [#] Before CRM feature set 3.1.0 (Pacemaker 2.0.0), the minor-minor version number was treated the same as the minor version. .. [#] Currently, Corosync version 2 and greater is the only supported cluster stack, but other stacks have been supported by past versions, and may be supported by future versions. .. [#] Any active resources will be moved off the node being upgraded, so there will be at least a brief outage unless all resources can be migrated "live". .. [#] Rolling upgrades from Pacemaker 1.1.z to 2.y.z are possible only if the cluster uses corosync version 2 or greater as its messaging layer, and the Cluster Information Base (CIB) uses schema 1.0 or higher in its ``validate-with`` property. .. [#] As of Pacemaker 2.0.0, only schema versions pacemaker-1.0 and higher are supported (excluding pacemaker-1.1, which was an experimental schema now known as pacemaker-next). diff --git a/doc/sphinx/Pacemaker_Development/python.rst b/doc/sphinx/Pacemaker_Development/python.rst index b97919685a..d73dc91566 100644 --- a/doc/sphinx/Pacemaker_Development/python.rst +++ b/doc/sphinx/Pacemaker_Development/python.rst @@ -1,81 +1,81 @@ .. index:: single: Python pair: Python; guidelines Python Coding Guidelines ------------------------ .. index:: pair: Python; boilerplate pair: license; Python pair: copyright; Python .. _s-python-boilerplate: Python Boilerplate ################## If a Python file is meant to be executed (as opposed to imported), it should have a ``.in`` extension, and its first line should be: .. code-block:: python #!@PYTHON@ which will be replaced with the appropriate python executable when Pacemaker is -built. To make that happen, add an ``AC_CONFIG_FILES()`` line to +built. To make that happen, add an entry to ``CONFIG_FILES_EXEC()`` in ``configure.ac``, and add the file name without ``.in`` to ``.gitignore`` (see existing examples). After the above line if any, every Python file should start like this: .. code-block:: python """ """ __copyright__ = "Copyright the Pacemaker project contributors" __license__ = " WITHOUT ANY WARRANTY" ** is obviously a brief description of the file's purpose. The string may contain any other information typically used in a Python file `docstring `_. ```` should follow the policy set forth in the `COPYING `_ file, generally one of "GNU General Public License version 2 or later (GPLv2+)" or "GNU Lesser General Public License version 2.1 or later (LGPLv2.1+)". .. index:: single: Python; 3 single: Python; version Python Version Compatibility ############################ Pacemaker targets compatibility with Python 3.4 and later. Do not use features not available in all targeted Python versions. An example is the ``subprocess.run()`` function. .. index:: pair: Python; whitespace Formatting Python Code ###################### * Indentation must be 4 spaces, no tabs. * Do not leave trailing whitespace. * Lines should be no longer than 80 characters unless limiting line length significantly impacts readability. For Python, this limitation is flexible since breaking a line often impacts readability, but definitely keep it under 120 characters. * Where not conflicting with this style guide, it is recommended (but not required) to follow `PEP 8 `_. * It is recommended (but not required) to format Python code such that ``pylint --disable=line-too-long,too-many-lines,too-many-instance-attributes,too-many-arguments,too-many-statements`` produces minimal complaints (even better if you don't need to disable all those checks). diff --git a/extra/alerts/alert_file.sh.sample b/extra/alerts/alert_file.sh.sample index e482e934ce..7844c77e60 100644 --- a/extra/alerts/alert_file.sh.sample +++ b/extra/alerts/alert_file.sh.sample @@ -1,120 +1,109 @@ #!/bin/sh # -# Copyright 2015-2017 the Pacemaker project contributors +# Copyright 2015-2021 the Pacemaker project contributors # # The version control history for this file may have further details. # -# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# This source code is licensed under the GNU General Public License version 2 +# or later (GPLv2+) WITHOUT ANY WARRANTY. # ############################################################################## # Sample configuration (cib fragment in xml notation) # ================================ # # # # # # # # # # # # # # No one will probably ever see this echo, unless they run the script manually. # An alternative would be to log to the system log, or similar. (We can't send # this to the configured recipient, because that variable won't be defined in # this case either.) if [ -z $CRM_alert_version ]; then echo "$0 must be run by Pacemaker version 1.1.15 or later" exit 0 fi # Alert agents must always handle the case where no recipients are defined, # even if it's a no-op (a recipient might be added to the configuration later). if [ -z "${CRM_alert_recipient}" ]; then echo "$0 requires a recipient configured with a full filename path" exit 0 fi debug_exec_order_default="false" # Pacemaker passes instance attributes to alert agents as environment variables. # It is completely up to the agent what instance attributes to support. # Here, we define an instance attribute "debug_exec_order". : ${debug_exec_order=${debug_exec_order_default}} if [ "${debug_exec_order}" = "true" ]; then tstamp=`printf "%04d. " "$CRM_alert_node_sequence"` if [ ! -z "$CRM_alert_timestamp" ]; then tstamp="${tstamp} $CRM_alert_timestamp (`date "+%H:%M:%S.%06N"`): " fi else if [ ! -z "$CRM_alert_timestamp" ]; then tstamp="$CRM_alert_timestamp: " fi fi case $CRM_alert_kind in node) echo "${tstamp}Node '${CRM_alert_node}' is now '${CRM_alert_desc}'" >> "${CRM_alert_recipient}" ;; fencing) # Other keys: # # CRM_alert_node # CRM_alert_task # CRM_alert_rc # echo "${tstamp}Fencing ${CRM_alert_desc}" >> "${CRM_alert_recipient}" ;; resource) # Other keys: # # CRM_alert_target_rc # CRM_alert_status # CRM_alert_rc # if [ ${CRM_alert_interval} = "0" ]; then CRM_alert_interval="" else CRM_alert_interval=" (${CRM_alert_interval})" fi if [ ${CRM_alert_target_rc} = "0" ]; then CRM_alert_target_rc="" else CRM_alert_target_rc=" (target: ${CRM_alert_target_rc})" fi case ${CRM_alert_desc} in Cancelled) ;; *) echo "${tstamp}Resource operation '${CRM_alert_task}${CRM_alert_interval}' for '${CRM_alert_rsc}' on '${CRM_alert_node}': ${CRM_alert_desc}${CRM_alert_target_rc}" >> "${CRM_alert_recipient}" ;; esac ;; attribute) # echo "${tstamp}Attribute '${CRM_alert_attribute_name}' on node '${CRM_alert_node}' was updated to '${CRM_alert_attribute_value}'" >> "${CRM_alert_recipient}" ;; *) echo "${tstamp}Unhandled $CRM_alert_kind alert" >> "${CRM_alert_recipient}" env | grep CRM_alert >> "${CRM_alert_recipient}" ;; esac diff --git a/extra/alerts/alert_smtp.sh.sample b/extra/alerts/alert_smtp.sh.sample index b40d7a47b1..5da83ade4a 100644 --- a/extra/alerts/alert_smtp.sh.sample +++ b/extra/alerts/alert_smtp.sh.sample @@ -1,117 +1,106 @@ #!/bin/sh # # Copyright 2016-2017 the Pacemaker project contributors # # The version control history for this file may have further details. # -# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# This source code is licensed under the GNU General Public License version 2 +# or later (GPLv2+) WITHOUT ANY WARRANTY. # ############################################################################## # # Sample configuration (cib fragment in xml notation) # ================================ # # # # # # # # # # # # email_client_default="sendmail" email_sender_default="hacluster" email_recipient_default="root" : ${email_client=${email_client_default}} : ${email_sender=${email_sender_default}} email_recipient="${CRM_alert_recipient-${email_recipient_default}}" node_name=`uname -n` cluster_name=`crm_attribute --query -n cluster-name -q` email_body=`env | grep CRM_alert_` if [ ! -z "${email_sender##*@*}" ]; then email_sender="${email_sender}@${node_name}" fi if [ ! -z "${email_recipient##*@*}" ]; then email_recipient="${email_recipient}@${node_name}" fi if [ -z ${CRM_alert_version} ]; then email_subject="Pacemaker version 1.1.15 or later is required for alerts" else case ${CRM_alert_kind} in node) email_subject="${CRM_alert_timestamp} ${cluster_name}: Node '${CRM_alert_node}' is now '${CRM_alert_desc}'" ;; fencing) email_subject="${CRM_alert_timestamp} ${cluster_name}: Fencing ${CRM_alert_desc}" ;; resource) if [ ${CRM_alert_interval} = "0" ]; then CRM_alert_interval="" else CRM_alert_interval=" (${CRM_alert_interval})" fi if [ ${CRM_alert_target_rc} = "0" ]; then CRM_alert_target_rc="" else CRM_alert_target_rc=" (target: ${CRM_alert_target_rc})" fi case ${CRM_alert_desc} in Cancelled) ;; *) email_subject="${CRM_alert_timestamp} ${cluster_name}: Resource operation '${CRM_alert_task}${CRM_alert_interval}' for '${CRM_alert_rsc}' on '${CRM_alert_node}': ${CRM_alert_desc}${CRM_alert_target_rc}" ;; esac ;; attribute) # email_subject="${CRM_alert_timestamp} ${cluster_name}: The '${CRM_alert_attribute_name}' attribute of the '${CRM_alert_node}' node was updated in '${CRM_alert_attribute_value}'" ;; *) email_subject="${CRM_alert_timestamp} ${cluster_name}: Unhandled $CRM_alert_kind alert" ;; esac fi if [ ! -z "${email_subject}" ]; then case $email_client in # This sample script supports only sendmail for sending the email. # Support for additional senders can easily be added by adding # new cases here. sendmail) sendmail -t -r "${email_sender}" <<__EOF__ From: ${email_sender} To: ${email_recipient} Return-Path: ${email_sender} Subject: ${email_subject} ${email_body} __EOF__ ;; *) ;; esac fi diff --git a/extra/alerts/alert_snmp.sh.sample b/extra/alerts/alert_snmp.sh.sample index b790a4473e..8354f82308 100644 --- a/extra/alerts/alert_snmp.sh.sample +++ b/extra/alerts/alert_snmp.sh.sample @@ -1,182 +1,183 @@ #!/bin/sh # -# Copyright 2016-2018 NIPPON TELEGRAPH AND TELEPHONE CORPORATION +# Copyright 2013 Florian CROUZAT +# Later changes copyright 2013-2021 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # # Description: Manages a SNMP trap, provided by NTT OSSC as a # script under Pacemaker control # ############################################################################## # This sample script assumes that only users who already have # hacluster-equivalent access to the cluster nodes can edit the CIB. Otherwise, # a malicious user could run commands as hacluster by inserting shell code into # the trap_options or timestamp-format parameters. # # Sample configuration (cib fragment in xml notation) # ================================ # # # # # # # # # # # # # # ================================ # # This uses the official Pacemaker MIB. # 1.3.6.1.4.1.32723 has been assigned to the project by IANA: # http://www.iana.org/assignments/enterprise-numbers if [ -z "$CRM_alert_version" ]; then echo "$0 must be run by Pacemaker version 1.1.15 or later" exit 0 fi if [ -z "$CRM_alert_recipient" ]; then echo "$0 requires a recipient configured with the SNMP server IP address" exit 0 fi # Defaults for user-configurable values trap_binary_default="/usr/bin/snmptrap" trap_version_default="2c" trap_options_default="" trap_community_default="public" trap_node_states_default="all" trap_fencing_tasks_default="all" trap_resource_tasks_default="all" trap_monitor_success_default="false" trap_add_hires_timestamp_oid_default="true" trap_snmp_persistent_dir_default="/var/lib/pacemaker/snmp" trap_ignore_int32_default=2147483647 # maximum Integer32 value trap_ignore_string_default="n/a" # doesn't conflict with valid XML IDs # Ensure all user-provided variables have values. : ${trap_binary=${trap_binary_default}} : ${trap_version=${trap_version_default}} : ${trap_options=${trap_options_default}} : ${trap_community=${trap_community_default}} : ${trap_node_states=${trap_node_states_default}} : ${trap_fencing_tasks=${trap_fencing_tasks_default}} : ${trap_resource_tasks=${trap_resource_tasks_default}} : ${trap_monitor_success=${trap_monitor_success_default}} : ${trap_add_hires_timestamp_oid=${trap_add_hires_timestamp_oid_default}} : ${trap_snmp_persistent_dir=${trap_snmp_persistent_dir_default}} : ${trap_ignore_int32=${trap_ignore_int32_default}} : ${trap_ignore_string=${trap_ignore_string_default}} # Ensure all cluster-provided variables have values, regardless of alert type. : ${CRM_alert_node=${trap_ignore_string}} : ${CRM_alert_rsc=${trap_ignore_string}} : ${CRM_alert_task=${trap_ignore_string}} : ${CRM_alert_desc=${trap_ignore_string}} : ${CRM_alert_status=${trap_ignore_int32}} : ${CRM_alert_rc=${trap_ignore_int32}} : ${CRM_alert_target_rc=${trap_ignore_int32}} : ${CRM_alert_attribute_name=${trap_ignore_string}} : ${CRM_alert_attribute_value=${trap_ignore_string}} # Echo a high-resolution equivalent of the Pacemaker-provided time values # using NetSNMP's DateAndTime specification ("%Y-%m-%d,%H:%M:%S.%01N"). get_system_date() { : ${CRM_alert_timestamp_epoch=$(date +%s)} : ${CRM_alert_timestamp_usec=0} YMDHMS=$(date --date="@${CRM_alert_timestamp_epoch}" +"%Y-%m-%d,%H:%M:%S") USEC=$(echo ${CRM_alert_timestamp_usec} | cut -b 1) echo "${YMDHMS}.${USEC}" } is_in_list() { item_list=`echo "$1" | tr ',' ' '` if [ "${item_list}" = "all" ]; then return 0 else for act in $item_list do act=`echo "$act" | tr A-Z a-z` [ "$act" != "$2" ] && continue return 0 done fi return 1 } send_pacemaker_trap() { PREFIX="PACEMAKER-MIB::pacemakerNotification" OUTPUT=$("${trap_binary}" -v "${trap_version}" ${trap_options} \ -c "${trap_community}" "${CRM_alert_recipient}" "" \ "${PREFIX}Trap" \ "${PREFIX}Node" s "${CRM_alert_node}" \ "${PREFIX}Resource" s "${CRM_alert_rsc}" \ "${PREFIX}Operation" s "${CRM_alert_task}" \ "${PREFIX}Description" s "${CRM_alert_desc}" \ "${PREFIX}Status" i "${CRM_alert_status}" \ "${PREFIX}ReturnCode" i "${CRM_alert_rc}" \ "${PREFIX}TargetReturnCode" i "${CRM_alert_target_rc}" \ "${PREFIX}AttributeName" s "${CRM_alert_attribute_name}" \ "${PREFIX}AttributeValue" s "${CRM_alert_attribute_value}" \ ${hires_timestamp} 2>&1) if [ $? -ne 0 ]; then echo "${trap_binary} returned error : rc=$? $OUTPUT" fi } if [ "${trap_add_hires_timestamp_oid}" = "true" ]; then hires_timestamp="HOST-RESOURCES-MIB::hrSystemDate s $(get_system_date)" fi if [ -z ${SNMP_PERSISTENT_DIR} ]; then export SNMP_PERSISTENT_DIR="${trap_snmp_persistent_dir}" # mkdir for snmp trap tools. if [ ! -d ${SNMP_PERSISTENT_DIR} ]; then mkdir -p ${SNMP_PERSISTENT_DIR} fi fi case "$CRM_alert_kind" in node) if is_in_list "${trap_node_states}" "${CRM_alert_desc}"; then send_pacemaker_trap fi ;; fencing) if is_in_list "${trap_fencing_tasks}" "${CRM_alert_task}"; then send_pacemaker_trap fi ;; resource) if is_in_list "${trap_resource_tasks}" "${CRM_alert_task}" && \ [ "${CRM_alert_desc}" != "Cancelled" ] ; then if [ "${trap_monitor_success}" = "false" ] && \ [ "${CRM_alert_rc}" = "${CRM_alert_target_rc}" ] && \ [ "${CRM_alert_task}" = "monitor" ]; then exit 0 fi send_pacemaker_trap fi ;; attribute) send_pacemaker_trap ;; *) ;; esac diff --git a/extra/ansible/docker/roles/docker-host/files/fence_docker_cts b/extra/ansible/docker/roles/docker-host/files/fence_docker_cts index ae102bfbb7..1b928ff75d 100644 --- a/extra/ansible/docker/roles/docker-host/files/fence_docker_cts +++ b/extra/ansible/docker/roles/docker-host/files/fence_docker_cts @@ -1,203 +1,186 @@ #!/bin/bash # -# Copyright 2014-2015 the Pacemaker project contributors +# Copyright 2014-2021 the Pacemaker project contributors # # The version control history for this file may have further details. # -# This program is free software; you can redistribute it and/or modify -# it under the terms of version 2 of the GNU General Public License as -# published by the Free Software Foundation. +# This source code is licensed under the GNU General Public License version 2 +# (GPLv2) WITHOUT ANY WARRANTY. # -# This program is distributed in the hope that it would be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# -# Further, this software is distributed without any warranty that it is -# free of the rightful claim of any third person regarding infringement -# or the like. Any license provided herein, whether implied or -# otherwise, applies only to this software file. Patent licenses, if -# any, provided herein do not apply to combinations of this program with -# other software, or any other product whatsoever. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -# -####################################################################### port="" action="list" # Default fence action function usage() { cat < fence_docker_cts fences docker containers for testing purposes. Fencing Action The name/id of docker container to control/check EOF exit 0; } function docker_log() { if ! [ "$action" = "list" ]; then printf "$*\n" 1>&2 fi } # stdin option processing if [ -z $1 ]; then # If there are no command line args, look for options from stdin while read line; do for word in $(echo "$line"); do case $word in option=*|action=*) action=`echo $word | sed s/.*=//`;; port=*) port=`echo $word | sed s/.*=//`;; node=*) port=`echo $word | sed s/.*=//`;; nodename=*) port=`echo $word | sed s/.*=//`;; --);; *) docker_log "Invalid command: $word";; esac done done fi # Command line option processing while true ; do if [ -z "$1" ]; then break; fi case "$1" in -o|--action|--option) action=$2; shift; shift;; -n|--port) port=$2; shift; shift;; -V|--version) echo "1.0.0"; exit 0;; --help|-h) usage; exit 0;; --) shift ; break ;; *) docker_log "Unknown option: $1. See --help for details."; exit 1;; esac done action=`echo $action | tr 'A-Z' 'a-z'` case $action in hostlist|list) action=list;; stat|status) action=status;; restart|reboot|reset) action=reboot;; poweron|on) action=start;; poweroff|off) action=stop;; esac function fence_done() { if [ $1 -eq 0 ]; then docker_log "Operation $action (port=$port) passed" else docker_log "Operation $action (port=$port) failed: $1" fi if [ -z "$returnfile" ]; then rm -f $returnfile fi if [ -z "$helperscript" ]; then rm -f $helperscript fi exit $1 } case $action in metadata) metadata;; esac returnfile=$(mktemp /tmp/fence_docker_cts_returnfileXXXX) returnstring="" helper_script=$(mktemp /tmp/fence_docker_cts_helperXXXX) exec_action() { echo "#!/bin/bash" > $helper_script echo "sleep 10000" >> $helper_script chmod 755 $helper_script src="$(uname -n)" $helper_script "$src" "$action" "$returnfile" "$port" > /dev/null 2>&1 & pid=$! docker_log "waiting on pid $pid" wait $pid > /dev/null 2>&1 returnstring=$(cat $returnfile) if [ -z "$returnstring" ]; then docker_log "fencing daemon did not respond" fence_done 1 fi if [ "$returnstring" == "fail" ]; then docker_log "fencing daemon failed to execute action [$action on port $port]" fence_done 1 fi return 0 } exec_action case $action in list) cat $returnfile fence_done 0 ;; status) # 0 if container is on # 1 if container can not be contacted or unknown # 2 if container is off if [ "$returnstring" = "true" ]; then fence_done 0 else fence_done 2 fi ;; monitor|stop|start|reboot) : ;; *) docker_log "Unknown action: $action"; fence_done 1;; esac fence_done $? diff --git a/extra/showscores.sh b/extra/showscores.sh index 09e0777f87..a8647ba21a 100644 --- a/extra/showscores.sh +++ b/extra/showscores.sh @@ -1,147 +1,136 @@ #!/bin/bash # -# Copyright 2008-2017 the Pacemaker project contributors +# Copyright 2008-2021 the Pacemaker project contributors # # The version control history for this file may have further details. # -# 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. +# This source code is licensed under the GNU General Public License version 2 +# or later (GPLv2+) WITHOUT ANY WARRANTY. # # Display scores of Pacemaker resources if [ "$1" = "--help" -o "$1" = "-h" ] then echo "showscores.sh - basically parsing crm_simulate -Ls." echo "Usage: " echo "$0 (to display score information for all resources on all nodes sorted by resource name)" echo "$0 node (to display score information for all resources on all nodes sorted by nodename)" echo "$0 (to display score information for a specific resource on all nodes)" echo "$0 (to display score information for a specific resource on a specific node)" echo "$0 singlescore (to display just the score number (not additional info) for a specific resource on a specific node)" exit 0 fi tmpfile=/tmp/dkshowscorestmpfiledk tmpfile2=/tmp/dkshowscorestmpfile2dk sortby=1 if [ "$1" = "node" ] then sortby=3 fi export default_stickiness=`crm_attribute -G -n default-resource-stickiness -t rsc_defaults -Q 2>/dev/null` if [ -z "$default_stickiness" ]; then default_stickiness=0; fi export default_migrationthreshold=`crm_attribute -G -n migration-threshold -t rsc_defaults -Q 2>/dev/null` if [ -n "$1" -a "$1" != "node" ] then resource=$1 fi if [ -n "$2" ] then nodename=$2 fi 2>&1 crm_simulate -Ls | grep -E "$resource" | grep -E "$nodename" > $tmpfile parseline() { if ! echo $*|grep -q "promotion score"; then shift; fi res=$1; shift; shift; shift; shift; node=$(echo $1|sed 's/:$//'); shift; score=$1; } get_stickiness() { res="$1" # get meta attribute resource_stickiness if ! stickiness=`crm_resource -g resource-stickiness -r $res --meta -Q 2>/dev/null` then # if no resource-specific stickiness is confiugured, use the default value stickiness="$default_stickiness" fi # get meta attribute resource_failure_stickiness if ! migrationthreshold=`crm_resource -g migration-threshold -r $res --meta -Q 2>/dev/null` then # if that doesn't exist, use the default value migrationthreshold="$default_migrationthreshold" fi } get_failcount() { #usage $0 res node failcount=`crm_failcount -G -r $1 -U $2 -Q 2>/dev/null|grep -o "^[0-9]*$"` } #determine the longest resource name to adjust width of the first column max_res_id_len=0 for res_id in $(tail -n +2 $tmpfile | sed 's/^[a-zA-Z_-]*\:\ //' | cut -d " " -f 1 | sort | uniq); do res_id_len=$(echo $res_id|wc -c) [ $res_id_len -gt $max_res_id_len ] && export max_res_id_len=$res_id_len; done # we'll later add "_(master)" to master scores, so add 9 chars to max_res_id_len max_res_id_len=$(($max_res_id_len+9)) #same for nodenames max_node_id_len=0 for node_id in $(sed 's/^[a-zA-Z_-]*\:\ //' $tmpfile | cut -d " " -f 5 | grep -v "^$" | sort | uniq | sed 's/\://'); do node_id_len=$(echo $node_id|wc -c) [ $node_id_len -gt $max_node_id_len ] && export max_node_id_len=$node_id_len; done # display allocation scores grep native_color $tmpfile | while read line do unset node res score stickiness failcount migrationthreshold parseline $line get_stickiness $res get_failcount $res $node printf "%-${max_res_id_len}s%-10s%-${max_node_id_len}s%-11s%-9s%-16s\n" $res $score $node $stickiness $failcount $migrationthreshold done >> $tmpfile2 # display promotion scores grep "promotion score" $tmpfile | while read line do unset node res score stickiness failcount migrationthreshold parseline $line # Skip if node=none. Sometimes happens for clones but is internally mapped to another clone instance, so this is skipped [ "$node" = "none" ] && continue inflines=`grep "promotion score" $tmpfile | grep $res | grep 1000000 | wc -l` if [ $inflines -eq 1 ] then # [10:24] the non INFINITY values are the true ones # [10:25] except for when the actually resulting score is [-]INFINITY # [10:25] yeah actualline=`grep "promotion score" $tmpfile | grep $res | grep -v 1000000` parseline $actualline fi get_stickiness $res get_failcount $res $node res=$res"_(master)" printf "%-${max_res_id_len}s%-10s%-${max_node_id_len}s%-11s%-9s%-16s\n" $res $score $node $stickiness $failcount $migrationthreshold done | sort | uniq >> $tmpfile2 if [ "$3" = "singlescore" ] then sed 's/ */ /g' $tmpfile2 | cut -d ' ' -f 2 | tail -n 1 else # Heading printf "%-${max_res_id_len}s%-10s%-${max_node_id_len}s%-11s%-9s%-16s\n" "Resource" "Score" "Node" "Stickiness" "#Fail" "Migration-Threshold" sort -k $sortby $tmpfile2 fi rm -f $tmpfile $tmpfile2 diff --git a/include/crm/cib/Makefile.am b/include/crm/cib/Makefile.am index 237cdbbb8a..27d23fd2c6 100644 --- a/include/crm/cib/Makefile.am +++ b/include/crm/cib/Makefile.am @@ -1,25 +1,14 @@ # # Copyright 2012-2021 the Pacemaker project contributors # # The version control history for this file may have further details. # -# 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. +# This source code is licensed under the GNU General Public License version 2 +# or later (GPLv2+) WITHOUT ANY WARRANTY. # MAINTAINERCLEANFILES = Makefile.in headerdir=$(pkgincludedir)/crm/cib noinst_HEADERS = internal.h header_HEADERS = util.h util_compat.h cib_types.h diff --git a/include/crm/cluster/Makefile.am b/include/crm/cluster/Makefile.am index b4a0821f5f..96f2bd0eb5 100644 --- a/include/crm/cluster/Makefile.am +++ b/include/crm/cluster/Makefile.am @@ -1,25 +1,14 @@ # # Copyright 2012-2021 the Pacemaker project contributors # # The version control history for this file may have further details. # -# 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. +# This source code is licensed under the GNU General Public License version 2 +# or later (GPLv2+) WITHOUT ANY WARRANTY. # MAINTAINERCLEANFILES = Makefile.in headerdir=$(pkgincludedir)/crm/cluster noinst_HEADERS = internal.h election_internal.h header_HEADERS = compat.h diff --git a/include/crm/crm.h b/include/crm/crm.h index 230a683aa8..dc3e7b7693 100644 --- a/include/crm/crm.h +++ b/include/crm/crm.h @@ -1,235 +1,238 @@ /* * Copyright 2004-2021 the Pacemaker project contributors * * The version control history for this file may have further details. * * This source code is licensed under the GNU Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #ifndef CRM__H # define CRM__H #ifdef __cplusplus extern "C" { #endif /** * \file * \brief A dumping ground * \ingroup core */ # include # include # include # include # include # include #ifndef PCMK_ALLOW_DEPRECATED /*! * \brief Allow use of deprecated Pacemaker APIs * * By default, external code using Pacemaker headers is allowed to use * deprecated Pacemaker APIs. If PCMK_ALLOW_DEPRECATED is defined to 0 before * including any Pacemaker headers, deprecated APIs will be unusable. It is * strongly recommended to leave this unchanged for production and release * builds, to avoid breakage when users upgrade to new Pacemaker releases that * deprecate more APIs. This should be defined to 0 only for development and * testing builds when desiring to check for usage of currently deprecated APIs. */ #define PCMK_ALLOW_DEPRECATED 1 #endif /*! * The CRM feature set assists with compatibility in mixed-version clusters. * The major version number increases when nodes with different versions * would not work (rolling upgrades are not allowed). The minor version * number increases when mixed-version clusters are allowed only during * rolling upgrades (a node with the oldest feature set will be elected DC). The * minor-minor version number is ignored, but allows resource agents to detect * cluster support for various features. * * The feature set also affects the processing of old saved CIBs (such as for * many scheduler regression tests). * * Particular feature points currently tested by Pacemaker code: * * >2.1: Operation updates include timing data * >=3.0.5: XML v2 digests are created * >=3.0.8: Peers do not need acks for cancellations * >=3.0.9: DC will send its own shutdown request to all peers * XML v2 patchsets are created by default * >=3.0.13: Fail counts include operation name and interval * >=3.2.0: DC supports PCMK_LRM_OP_INVALID and PCMK_LRM_OP_NOT_CONNECTED */ # define CRM_FEATURE_SET "3.9.0" -# ifndef MAX_NAME -# define MAX_NAME 256 -# endif +/* Pacemaker's CPG protocols use fixed-width binary fields for the sender and + * recipient of a CPG message. This imposes an arbitrary limit on cluster node + * names. + */ +//! \brief Maximum length of a Corosync cluster node name (in bytes) +#define MAX_NAME 256 # define CRM_META "CRM_meta" extern char *crm_system_name; /* *INDENT-OFF* */ // How we represent "infinite" scores # define CRM_SCORE_INFINITY 1000000 # define CRM_INFINITY_S "INFINITY" # define CRM_PLUS_INFINITY_S "+" CRM_INFINITY_S # define CRM_MINUS_INFINITY_S "-" CRM_INFINITY_S /* @COMPAT API < 2.0.0 Deprecated "infinity" aliases * * INFINITY might be defined elsewhere (e.g. math.h), so undefine it first. * This, of course, complicates any attempt to use the other definition in any * code that includes this header. */ # undef INFINITY # define INFINITY_S "INFINITY" # define MINUS_INFINITY_S "-INFINITY" # define INFINITY 1000000 /* Sub-systems */ # define CRM_SYSTEM_DC "dc" # define CRM_SYSTEM_DCIB "dcib" /* The master CIB */ # define CRM_SYSTEM_CIB "cib" # define CRM_SYSTEM_CRMD "crmd" # define CRM_SYSTEM_LRMD "lrmd" # define CRM_SYSTEM_PENGINE "pengine" # define CRM_SYSTEM_TENGINE "tengine" # define CRM_SYSTEM_STONITHD "stonithd" # define CRM_SYSTEM_MCP "pacemakerd" // Names of internally generated node attributes # define CRM_ATTR_UNAME "#uname" # define CRM_ATTR_ID "#id" # define CRM_ATTR_KIND "#kind" # define CRM_ATTR_ROLE "#role" # define CRM_ATTR_IS_DC "#is_dc" # define CRM_ATTR_CLUSTER_NAME "#cluster-name" # define CRM_ATTR_SITE_NAME "#site-name" # define CRM_ATTR_UNFENCED "#node-unfenced" # define CRM_ATTR_DIGESTS_ALL "#digests-all" # define CRM_ATTR_DIGESTS_SECURE "#digests-secure" # define CRM_ATTR_RA_VERSION "#ra-version" # define CRM_ATTR_PROTOCOL "#attrd-protocol" /* Valid operations */ # define CRM_OP_NOOP "noop" # define CRM_OP_JOIN_ANNOUNCE "join_announce" # define CRM_OP_JOIN_OFFER "join_offer" # define CRM_OP_JOIN_REQUEST "join_request" # define CRM_OP_JOIN_ACKNAK "join_ack_nack" # define CRM_OP_JOIN_CONFIRM "join_confirm" # define CRM_OP_PING "ping" # define CRM_OP_NODE_INFO "node-info" # define CRM_OP_THROTTLE "throttle" # define CRM_OP_VOTE "vote" # define CRM_OP_NOVOTE "no-vote" # define CRM_OP_HELLO "hello" # define CRM_OP_PECALC "pe_calc" # define CRM_OP_QUIT "quit" # define CRM_OP_LOCAL_SHUTDOWN "start_shutdown" # define CRM_OP_SHUTDOWN_REQ "req_shutdown" # define CRM_OP_SHUTDOWN "do_shutdown" # define CRM_OP_FENCE "stonith" # define CRM_OP_REGISTER "register" # define CRM_OP_IPC_FWD "ipc_fwd" # define CRM_OP_INVOKE_LRM "lrm_invoke" # define CRM_OP_LRM_REFRESH "lrm_refresh" /* Deprecated */ # define CRM_OP_LRM_QUERY "lrm_query" # define CRM_OP_LRM_DELETE "lrm_delete" # define CRM_OP_LRM_FAIL "lrm_fail" # define CRM_OP_PROBED "probe_complete" # define CRM_OP_REPROBE "probe_again" # define CRM_OP_CLEAR_FAILCOUNT "clear_failcount" # define CRM_OP_REMOTE_STATE "remote_state" # define CRM_OP_RELAXED_SET "one-or-more" # define CRM_OP_RELAXED_CLONE "clone-one-or-more" # define CRM_OP_RM_NODE_CACHE "rm_node_cache" # define CRM_OP_MAINTENANCE_NODES "maintenance_nodes" /* Possible cluster membership states */ # define CRMD_JOINSTATE_DOWN "down" # define CRMD_JOINSTATE_PENDING "pending" # define CRMD_JOINSTATE_MEMBER "member" # define CRMD_JOINSTATE_NACK "banned" # define CRMD_ACTION_DELETE "delete" # define CRMD_ACTION_CANCEL "cancel" # define CRMD_ACTION_RELOAD "reload" # define CRMD_ACTION_MIGRATE "migrate_to" # define CRMD_ACTION_MIGRATED "migrate_from" # define CRMD_ACTION_START "start" # define CRMD_ACTION_STARTED "running" # define CRMD_ACTION_STOP "stop" # define CRMD_ACTION_STOPPED "stopped" # define CRMD_ACTION_PROMOTE "promote" # define CRMD_ACTION_PROMOTED "promoted" # define CRMD_ACTION_DEMOTE "demote" # define CRMD_ACTION_DEMOTED "demoted" # define CRMD_ACTION_NOTIFY "notify" # define CRMD_ACTION_NOTIFIED "notified" # define CRMD_ACTION_STATUS "monitor" # define CRMD_ACTION_METADATA "meta-data" # define CRMD_METADATA_CALL_TIMEOUT 30000 /* short names */ # define RSC_DELETE CRMD_ACTION_DELETE # define RSC_CANCEL CRMD_ACTION_CANCEL # define RSC_MIGRATE CRMD_ACTION_MIGRATE # define RSC_MIGRATED CRMD_ACTION_MIGRATED # define RSC_START CRMD_ACTION_START # define RSC_STARTED CRMD_ACTION_STARTED # define RSC_STOP CRMD_ACTION_STOP # define RSC_STOPPED CRMD_ACTION_STOPPED # define RSC_PROMOTE CRMD_ACTION_PROMOTE # define RSC_PROMOTED CRMD_ACTION_PROMOTED # define RSC_DEMOTE CRMD_ACTION_DEMOTE # define RSC_DEMOTED CRMD_ACTION_DEMOTED # define RSC_NOTIFY CRMD_ACTION_NOTIFY # define RSC_NOTIFIED CRMD_ACTION_NOTIFIED # define RSC_STATUS CRMD_ACTION_STATUS # define RSC_METADATA CRMD_ACTION_METADATA /* *INDENT-ON* */ # include # include static inline const char * crm_action_str(const char *task, guint interval_ms) { if ((task != NULL) && (interval_ms == 0) && (strcasecmp(task, RSC_STATUS) == 0)) { return "probe"; } return task; } #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1) #include #endif #ifdef __cplusplus } #endif #endif diff --git a/include/crm/fencing/Makefile.am b/include/crm/fencing/Makefile.am index 92aaad5a2b..8bfc8d818c 100644 --- a/include/crm/fencing/Makefile.am +++ b/include/crm/fencing/Makefile.am @@ -1,25 +1,14 @@ # # Copyright 2012-2021 the Pacemaker project contributors # # The version control history for this file may have further details. # -# 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. +# This source code is licensed under the GNU General Public License version 2 +# or later (GPLv2+) WITHOUT ANY WARRANTY. # MAINTAINERCLEANFILES = Makefile.in headerdir=$(pkgincludedir)/crm/fencing header_HEADERS = compat.h noinst_HEADERS = internal.h diff --git a/include/crm/pengine/Makefile.am b/include/crm/pengine/Makefile.am index 351cef3137..fac60317a3 100644 --- a/include/crm/pengine/Makefile.am +++ b/include/crm/pengine/Makefile.am @@ -1,28 +1,17 @@ # # Copyright 2006-2021 the Pacemaker project contributors # # The version control history for this file may have further details. # -# 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. +# This source code is licensed under the GNU General Public License version 2 +# or later (GPLv2+) WITHOUT ANY WARRANTY. # MAINTAINERCLEANFILES = Makefile.in headerdir=$(pkgincludedir)/crm/pengine noinst_HEADERS = internal.h remote_internal.h rules_internal.h header_HEADERS = common.h complex.h pe_types.h rules.h status.h \ common_compat.h \ pe_types_compat.h \ rules_compat.h diff --git a/lib/fencing/st_lha.c b/lib/fencing/st_lha.c index cb610f4d4d..f9fe5f194b 100644 --- a/lib/fencing/st_lha.c +++ b/lib/fencing/st_lha.c @@ -1,281 +1,283 @@ /* - * Copyright 2004-2018 Andrew Beekhof + * Copyright 2004-2021 the Pacemaker project contributors + * + * The version control history for this file may have further details. * * This source code is licensed under the GNU Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define LHA_STONITH_LIBRARY "libstonith.so.1" static void *lha_agents_lib = NULL; static const char META_TEMPLATE[] = "\n" "\n" "\n" " 1.0\n" " \n" "%s\n" " \n" " %s\n" "%s\n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " 2.0\n" " \n" "\n"; static void * find_library_function(void **handle, const char *lib, const char *fn) { void *a_function; if (*handle == NULL) { *handle = dlopen(lib, RTLD_LAZY); if ((*handle) == NULL) { crm_err("Could not open %s: %s", lib, dlerror()); return NULL; } } a_function = dlsym(*handle, fn); if (a_function == NULL) { crm_err("Could not find %s in %s: %s", fn, lib, dlerror()); } return a_function; } /*! * \brief Determine namespace of a fence agent * * \param[in] agent Fence agent type * \param[in] namespace_s Name of agent namespace as string, if known * * \return Namespace of specified agent, as enum value */ bool stonith__agent_is_lha(const char *agent) { Stonith *stonith_obj = NULL; static gboolean need_init = TRUE; static Stonith *(*st_new_fn) (const char *) = NULL; static void (*st_del_fn) (Stonith *) = NULL; if (need_init) { need_init = FALSE; st_new_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY, "stonith_new"); st_del_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY, "stonith_delete"); } if (lha_agents_lib && st_new_fn && st_del_fn) { stonith_obj = (*st_new_fn) (agent); if (stonith_obj) { (*st_del_fn) (stonith_obj); return TRUE; } } return FALSE; } int stonith__list_lha_agents(stonith_key_value_t **devices) { static gboolean need_init = TRUE; int count = 0; char **entry = NULL; char **type_list = NULL; static char **(*type_list_fn) (void) = NULL; static void (*type_free_fn) (char **) = NULL; if (need_init) { need_init = FALSE; type_list_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY, "stonith_types"); type_free_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY, "stonith_free_hostlist"); } if (type_list_fn) { type_list = (*type_list_fn) (); } for (entry = type_list; entry != NULL && *entry; ++entry) { crm_trace("Added: %s", *entry); *devices = stonith_key_value_add(*devices, NULL, *entry); count++; } if (type_list && type_free_fn) { (*type_free_fn) (type_list); } return count; } static inline char * strdup_null(const char *val) { if (val) { return strdup(val); } return NULL; } static void stonith_plugin(int priority, const char *fmt, ...) G_GNUC_PRINTF(2, 3); static void stonith_plugin(int priority, const char *format, ...) { int err = errno; va_list ap; int len = 0; char *string = NULL; va_start(ap, format); len = vasprintf (&string, format, ap); va_end(ap); CRM_ASSERT(len > 0); do_crm_log_alias(priority, __FILE__, __func__, __LINE__, "%s", string); free(string); errno = err; } int stonith__lha_metadata(const char *agent, int timeout, char **output) { int rc = 0; char *buffer = NULL; static const char *no_parameter_info = ""; Stonith *stonith_obj = NULL; static gboolean need_init = TRUE; static Stonith *(*st_new_fn) (const char *) = NULL; static const char *(*st_info_fn) (Stonith *, int) = NULL; static void (*st_del_fn) (Stonith *) = NULL; static void (*st_log_fn) (Stonith *, PILLogFun) = NULL; if (need_init) { need_init = FALSE; st_new_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY, "stonith_new"); st_del_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY, "stonith_delete"); st_log_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY, "stonith_set_log"); st_info_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY, "stonith_get_info"); } if (lha_agents_lib && st_new_fn && st_del_fn && st_info_fn && st_log_fn) { char *xml_meta_longdesc = NULL; char *xml_meta_shortdesc = NULL; char *meta_param = NULL; char *meta_longdesc = NULL; char *meta_shortdesc = NULL; stonith_obj = (*st_new_fn) (agent); if (stonith_obj) { (*st_log_fn) (stonith_obj, (PILLogFun) & stonith_plugin); meta_longdesc = strdup_null((*st_info_fn) (stonith_obj, ST_DEVICEDESCR)); if (meta_longdesc == NULL) { crm_warn("no long description in %s's metadata.", agent); meta_longdesc = strdup(no_parameter_info); } meta_shortdesc = strdup_null((*st_info_fn) (stonith_obj, ST_DEVICEID)); if (meta_shortdesc == NULL) { crm_warn("no short description in %s's metadata.", agent); meta_shortdesc = strdup(no_parameter_info); } meta_param = strdup_null((*st_info_fn) (stonith_obj, ST_CONF_XML)); if (meta_param == NULL) { crm_warn("no list of parameters in %s's metadata.", agent); meta_param = strdup(no_parameter_info); } (*st_del_fn) (stonith_obj); } else { errno = EINVAL; crm_perror(LOG_ERR, "Agent %s not found", agent); return -EINVAL; } xml_meta_longdesc = (char *)xmlEncodeEntitiesReentrant(NULL, (const unsigned char *)meta_longdesc); xml_meta_shortdesc = (char *)xmlEncodeEntitiesReentrant(NULL, (const unsigned char *)meta_shortdesc); buffer = crm_strdup_printf(META_TEMPLATE, agent, xml_meta_longdesc, xml_meta_shortdesc, meta_param); xmlFree(xml_meta_longdesc); xmlFree(xml_meta_shortdesc); free(meta_shortdesc); free(meta_longdesc); free(meta_param); } if (output) { *output = buffer; } else { free(buffer); } return rc; } /* Implement a dummy function that uses -lpils so that linkers don't drop the * reference. */ #include const char *i_hate_pils(int rc); const char * i_hate_pils(int rc) { return PIL_strerror(rc); } int stonith__lha_validate(stonith_t *st, int call_options, const char *target, const char *agent, GHashTable *params, int timeout, char **output, char **error_output) { errno = EOPNOTSUPP; crm_perror(LOG_ERR, "Cannot validate Linux-HA fence agents"); return -EOPNOTSUPP; } diff --git a/lib/pacemaker/pcmk_cluster_queries.c b/lib/pacemaker/pcmk_cluster_queries.c index 0bb399edae..7dd9032987 100644 --- a/lib/pacemaker/pcmk_cluster_queries.c +++ b/lib/pacemaker/pcmk_cluster_queries.c @@ -1,499 +1,508 @@ +/* + * Copyright 2020-2021 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * + * This source code is licensed under the GNU Lesser General Public License + * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. + */ + #include // gboolean, GMainLoop, etc. #include // xmlNode #include #include #include #include #include #include #include #include #include #include #include #include #define DEFAULT_MESSAGE_TIMEOUT_MS 30000 typedef struct { pcmk__output_t *out; GMainLoop *mainloop; int rc; guint message_timer_id; guint message_timeout_ms; } data_t; static void quit_main_loop(data_t *data) { if (data->mainloop != NULL) { GMainLoop *mloop = data->mainloop; data->mainloop = NULL; // Don't re-enter this block pcmk_quit_main_loop(mloop, 10); g_main_loop_unref(mloop); } } static gboolean admin_message_timeout(gpointer user_data) { data_t *data = user_data; pcmk__output_t *out = data->out; out->err(out, "error: No reply received from controller before timeout (%dms)", data->message_timeout_ms); data->message_timer_id = 0; data->rc = ETIMEDOUT; quit_main_loop(data); return FALSE; // Tells glib to remove source } static void start_main_loop(data_t *data) { if (data->message_timeout_ms < 1) { data->message_timeout_ms = DEFAULT_MESSAGE_TIMEOUT_MS; } data->rc = ECONNRESET; // For unexpected disconnects data->mainloop = g_main_loop_new(NULL, FALSE); data->message_timer_id = g_timeout_add(data->message_timeout_ms, admin_message_timeout, data); g_main_loop_run(data->mainloop); } static void event_done(data_t *data, pcmk_ipc_api_t *api) { pcmk_disconnect_ipc(api); quit_main_loop(data); } static pcmk_controld_api_reply_t * controld_event_reply(data_t *data, pcmk_ipc_api_t *controld_api, enum pcmk_ipc_event event_type, crm_exit_t status, void *event_data) { pcmk__output_t *out = data->out; pcmk_controld_api_reply_t *reply = event_data; switch (event_type) { case pcmk_ipc_event_disconnect: if (data->rc == ECONNRESET) { // Unexpected out->err(out, "error: Lost connection to controller"); } event_done(data, controld_api); return NULL; case pcmk_ipc_event_reply: break; default: return NULL; } if (data->message_timer_id != 0) { g_source_remove(data->message_timer_id); data->message_timer_id = 0; } if (status != CRM_EX_OK) { out->err(out, "error: Bad reply from controller: %s", crm_exit_str(status)); data->rc = EBADMSG; event_done(data, controld_api); return NULL; } if (reply->reply_type != pcmk_controld_reply_ping) { out->err(out, "error: Unknown reply type %d from controller", reply->reply_type); data->rc = EBADMSG; event_done(data, controld_api); return NULL; } return reply; } static void controller_status_event_cb(pcmk_ipc_api_t *controld_api, enum pcmk_ipc_event event_type, crm_exit_t status, void *event_data, void *user_data) { data_t *data = user_data; pcmk__output_t *out = data->out; pcmk_controld_api_reply_t *reply = controld_event_reply(data, controld_api, event_type, status, event_data); if (reply != NULL) { out->message(out, "health", reply->data.ping.sys_from, reply->host_from, reply->data.ping.fsa_state, reply->data.ping.result); data->rc = pcmk_rc_ok; } event_done(data, controld_api); } static void designated_controller_event_cb(pcmk_ipc_api_t *controld_api, enum pcmk_ipc_event event_type, crm_exit_t status, void *event_data, void *user_data) { data_t *data = user_data; pcmk__output_t *out = data->out; pcmk_controld_api_reply_t *reply = controld_event_reply(data, controld_api, event_type, status, event_data); if (reply != NULL) { out->message(out, "dc", reply->host_from); data->rc = pcmk_rc_ok; } event_done(data, controld_api); } static void pacemakerd_event_cb(pcmk_ipc_api_t *pacemakerd_api, enum pcmk_ipc_event event_type, crm_exit_t status, void *event_data, void *user_data) { data_t *data = user_data; pcmk__output_t *out = data->out; pcmk_pacemakerd_api_reply_t *reply = event_data; crm_time_t *crm_when; char *pinged_buf = NULL; switch (event_type) { case pcmk_ipc_event_disconnect: if (data->rc == ECONNRESET) { // Unexpected out->err(out, "error: Lost connection to pacemakerd"); } event_done(data, pacemakerd_api); return; case pcmk_ipc_event_reply: break; default: return; } if (data->message_timer_id != 0) { g_source_remove(data->message_timer_id); data->message_timer_id = 0; } if (status != CRM_EX_OK) { out->err(out, "error: Bad reply from pacemakerd: %s", crm_exit_str(status)); event_done(data, pacemakerd_api); return; } if (reply->reply_type != pcmk_pacemakerd_reply_ping) { out->err(out, "error: Unknown reply type %d from pacemakerd", reply->reply_type); event_done(data, pacemakerd_api); return; } // Parse desired information from reply crm_when = crm_time_new(NULL); crm_time_set_timet(crm_when, &reply->data.ping.last_good); pinged_buf = crm_time_as_string(crm_when, crm_time_log_date | crm_time_log_timeofday | crm_time_log_with_timezone); out->message(out, "pacemakerd-health", reply->data.ping.sys_from, (reply->data.ping.status == pcmk_rc_ok)? pcmk_pacemakerd_api_daemon_state_enum2text( reply->data.ping.state):"query failed", (reply->data.ping.status == pcmk_rc_ok)?pinged_buf:""); data->rc = pcmk_rc_ok; crm_time_free(crm_when); free(pinged_buf); event_done(data, pacemakerd_api); } static pcmk_ipc_api_t * ipc_connect(data_t *data, enum pcmk_ipc_server server, pcmk_ipc_callback_t cb) { int rc; pcmk__output_t *out = data->out; pcmk_ipc_api_t *api = NULL; rc = pcmk_new_ipc_api(&api, server); if (api == NULL) { out->err(out, "error: Could not connect to %s: %s", pcmk_ipc_name(api, true), pcmk_rc_str(rc)); data->rc = rc; return NULL; } if (cb != NULL) { pcmk_register_ipc_callback(api, cb, data); } rc = pcmk_connect_ipc(api, pcmk_ipc_dispatch_main); if (rc != pcmk_rc_ok) { out->err(out, "error: Could not connect to %s: %s", pcmk_ipc_name(api, true), pcmk_rc_str(rc)); data->rc = rc; return NULL; } return api; } int pcmk__controller_status(pcmk__output_t *out, char *dest_node, guint message_timeout_ms) { data_t data = { .out = out, .mainloop = NULL, .rc = pcmk_rc_ok, .message_timer_id = 0, .message_timeout_ms = message_timeout_ms }; pcmk_ipc_api_t *controld_api = ipc_connect(&data, pcmk_ipc_controld, controller_status_event_cb); if (controld_api != NULL) { int rc = pcmk_controld_api_ping(controld_api, dest_node); if (rc != pcmk_rc_ok) { out->err(out, "error: Command failed: %s", pcmk_rc_str(rc)); data.rc = rc; } start_main_loop(&data); pcmk_free_ipc_api(controld_api); } return data.rc; } int pcmk_controller_status(xmlNodePtr *xml, char *dest_node, unsigned int message_timeout_ms) { pcmk__output_t *out = NULL; int rc = pcmk_rc_ok; rc = pcmk__out_prologue(&out, xml); if (rc != pcmk_rc_ok) { return rc; } pcmk__register_lib_messages(out); rc = pcmk__controller_status(out, dest_node, (guint) message_timeout_ms); pcmk__out_epilogue(out, xml, rc); return rc; } int pcmk__designated_controller(pcmk__output_t *out, guint message_timeout_ms) { data_t data = { .out = out, .mainloop = NULL, .rc = pcmk_rc_ok, .message_timer_id = 0, .message_timeout_ms = message_timeout_ms }; pcmk_ipc_api_t *controld_api = ipc_connect(&data, pcmk_ipc_controld, designated_controller_event_cb); if (controld_api != NULL) { int rc = pcmk_controld_api_ping(controld_api, NULL); if (rc != pcmk_rc_ok) { out->err(out, "error: Command failed: %s", pcmk_rc_str(rc)); data.rc = rc; } start_main_loop(&data); pcmk_free_ipc_api(controld_api); } return data.rc; } int pcmk_designated_controller(xmlNodePtr *xml, unsigned int message_timeout_ms) { pcmk__output_t *out = NULL; int rc = pcmk_rc_ok; rc = pcmk__out_prologue(&out, xml); if (rc != pcmk_rc_ok) { return rc; } pcmk__register_lib_messages(out); rc = pcmk__designated_controller(out, (guint) message_timeout_ms); pcmk__out_epilogue(out, xml, rc); return rc; } int pcmk__pacemakerd_status(pcmk__output_t *out, char *ipc_name, guint message_timeout_ms) { data_t data = { .out = out, .mainloop = NULL, .rc = pcmk_rc_ok, .message_timer_id = 0, .message_timeout_ms = message_timeout_ms }; pcmk_ipc_api_t *pacemakerd_api = ipc_connect(&data, pcmk_ipc_pacemakerd, pacemakerd_event_cb); if (pacemakerd_api != NULL) { int rc = pcmk_pacemakerd_api_ping(pacemakerd_api, ipc_name); if (rc != pcmk_rc_ok) { out->err(out, "error: Command failed: %s", pcmk_rc_str(rc)); data.rc = rc; } start_main_loop(&data); pcmk_free_ipc_api(pacemakerd_api); } return data.rc; } int pcmk_pacemakerd_status(xmlNodePtr *xml, char *ipc_name, unsigned int message_timeout_ms) { pcmk__output_t *out = NULL; int rc = pcmk_rc_ok; rc = pcmk__out_prologue(&out, xml); if (rc != pcmk_rc_ok) { return rc; } pcmk__register_lib_messages(out); rc = pcmk__pacemakerd_status(out, ipc_name, (guint) message_timeout_ms); pcmk__out_epilogue(out, xml, rc); return rc; } /* user data for looping through remote node xpath searches */ struct node_data { pcmk__output_t *out; int found; const char *field; /* XML attribute to check for node name */ const char *type; gboolean BASH_EXPORT; }; static void remote_node_print_helper(xmlNode *result, void *user_data) { struct node_data *data = user_data; pcmk__output_t *out = data->out; const char *name = crm_element_value(result, XML_ATTR_UNAME); const char *id = crm_element_value(result, data->field); // node name and node id are the same for remote/guest nodes out->message(out, "crmadmin-node", data->type, name ? name : id, id, data->BASH_EXPORT); data->found++; } // \return Standard Pacemaker return code int pcmk__list_nodes(pcmk__output_t *out, char *node_types, gboolean BASH_EXPORT) { cib_t *the_cib = cib_new(); xmlNode *xml_node = NULL; int rc; if (the_cib == NULL) { return ENOMEM; } rc = the_cib->cmds->signon(the_cib, crm_system_name, cib_command); if (rc != pcmk_ok) { return pcmk_legacy2rc(rc); } rc = the_cib->cmds->query(the_cib, NULL, &xml_node, cib_scope_local | cib_sync_call); if (rc == pcmk_ok) { struct node_data data = { .out = out, .found = 0, .BASH_EXPORT = BASH_EXPORT }; out->begin_list(out, NULL, NULL, "nodes"); if (!pcmk__str_empty(node_types) && strstr(node_types, "all")) { node_types = NULL; } if (pcmk__str_empty(node_types) || strstr(node_types, "cluster")) { data.field = "id"; data.type = "cluster"; crm_foreach_xpath_result(xml_node, PCMK__XP_MEMBER_NODE_CONFIG, remote_node_print_helper, &data); } if (pcmk__str_empty(node_types) || strstr(node_types, "guest")) { data.field = "value"; data.type = "guest"; crm_foreach_xpath_result(xml_node, PCMK__XP_GUEST_NODE_CONFIG, remote_node_print_helper, &data); } if (pcmk__str_empty(node_types) || !pcmk__strcmp(node_types, ",|^remote", pcmk__str_regex)) { data.field = "id"; data.type = "remote"; crm_foreach_xpath_result(xml_node, PCMK__XP_REMOTE_NODE_CONFIG, remote_node_print_helper, &data); } out->end_list(out); if (data.found == 0) { out->info(out, "No nodes configured"); } free_xml(xml_node); } the_cib->cmds->signoff(the_cib); return pcmk_legacy2rc(rc); } int pcmk_list_nodes(xmlNodePtr *xml, char *node_types) { pcmk__output_t *out = NULL; int rc = pcmk_rc_ok; rc = pcmk__out_prologue(&out, xml); if (rc != pcmk_rc_ok) { return rc; } pcmk__register_lib_messages(out); rc = pcmk__list_nodes(out, node_types, FALSE); pcmk__out_epilogue(out, xml, rc); return rc; } diff --git a/lib/services/services_lsb.h b/lib/services/services_lsb.h index 11a07ca863..df9d8b356a 100644 --- a/lib/services/services_lsb.h +++ b/lib/services/services_lsb.h @@ -1,16 +1,18 @@ /* - * Copyright 2010-2018 Andrew Beekhof + * Copyright 2010-2021 the Pacemaker project contributors + * + * The version control history for this file may have further details. * * This source code is licensed under the GNU Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #ifndef SERVICES_LSB__H # define SERVICES_LSB__H G_GNUC_INTERNAL int services__get_lsb_metadata(const char *type, char **output); G_GNUC_INTERNAL GList *services__list_lsb_agents(void); G_GNUC_INTERNAL char *services__lsb_agent_path(const char *agent); G_GNUC_INTERNAL bool services__lsb_agent_exists(const char *agent); #endif diff --git a/lib/services/services_private.h b/lib/services/services_private.h index f669ce4925..00aba05f1e 100644 --- a/lib/services/services_private.h +++ b/lib/services/services_private.h @@ -1,81 +1,84 @@ /* - * Copyright 2010-2018 Red Hat, Inc. + * Copyright 2010-2011 Red Hat, Inc. + * Later changes copyright 2012-2021 the Pacemaker project contributors + * + * The version control history for this file may have further details. * * This source code is licensed under the GNU Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #ifndef SERVICES_PRIVATE__H # define SERVICES_PRIVATE__H # include # include "crm/services.h" #if SUPPORT_DBUS # include #endif #define MAX_ARGC 255 struct svc_action_private_s { char *exec; char *args[MAX_ARGC]; uid_t uid; gid_t gid; guint repeat_timer; void (*callback) (svc_action_t * op); void (*fork_callback) (svc_action_t * op); int stderr_fd; mainloop_io_t *stderr_gsource; int stdout_fd; mainloop_io_t *stdout_gsource; int stdin_fd; #if SUPPORT_DBUS DBusPendingCall* pending; unsigned timerid; #endif }; G_GNUC_INTERNAL GList *services_os_get_directory_list(const char *root, gboolean files, gboolean executable); G_GNUC_INTERNAL gboolean services_os_action_execute(svc_action_t * op); G_GNUC_INTERNAL GList *resources_os_list_ocf_providers(void); G_GNUC_INTERNAL GList *resources_os_list_ocf_agents(const char *provider); G_GNUC_INTERNAL gboolean services__ocf_agent_exists(const char *provider, const char *agent); G_GNUC_INTERNAL gboolean cancel_recurring_action(svc_action_t * op); G_GNUC_INTERNAL gboolean recurring_action_timer(gpointer data); G_GNUC_INTERNAL gboolean operation_finalize(svc_action_t * op); G_GNUC_INTERNAL void services_add_inflight_op(svc_action_t *op); G_GNUC_INTERNAL void services_untrack_op(svc_action_t *op); G_GNUC_INTERNAL gboolean is_op_blocked(const char *rsc); #if SUPPORT_DBUS G_GNUC_INTERNAL void services_set_op_pending(svc_action_t *op, DBusPendingCall *pending); #endif #endif /* SERVICES_PRIVATE__H */ diff --git a/lib/services/systemd.h b/lib/services/systemd.h index 23e3479f34..9a46ba70d9 100644 --- a/lib/services/systemd.h +++ b/lib/services/systemd.h @@ -1,30 +1,21 @@ -/* - * This program 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 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 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 +/* + * Copyright 2012-2021 the Pacemaker project contributors * - * Copyright (C) 2012 Andrew Beekhof + * The version control history for this file may have further details. + * + * This source code is licensed under the GNU Lesser General Public License + * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #ifndef SYSTEMD__H # define SYSTEMD__H # include # include "crm/services.h" G_GNUC_INTERNAL GList *systemd_unit_listall(void); G_GNUC_INTERNAL gboolean systemd_unit_exec(svc_action_t * op); G_GNUC_INTERNAL gboolean systemd_unit_exists(const gchar * name); G_GNUC_INTERNAL void systemd_cleanup(void); #endif /* SYSTEMD__H */ diff --git a/lib/services/upstart.h b/lib/services/upstart.h index 7bb9b0d2fa..d44306edd2 100644 --- a/lib/services/upstart.h +++ b/lib/services/upstart.h @@ -1,30 +1,22 @@ -/* - * This program 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 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 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 +/* + * Copyright 2010 Senko Rasic + * Copyright 2010 Ante Karamatic + * Later changes copyright 2012-2021 the Pacemaker project contributors * - * Copyright (C) 2010 Senko Rasic - * Copyright (c) 2010 Ante Karamatic + * The version control history for this file may have further details. + * + * This source code is licensed under the GNU Lesser General Public License + * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #ifndef UPSTART__H # define UPSTART__H # include # include "crm/services.h" G_GNUC_INTERNAL GList *upstart_job_listall(void); G_GNUC_INTERNAL gboolean upstart_job_exec(svc_action_t * op); G_GNUC_INTERNAL gboolean upstart_job_exists(const gchar * name); G_GNUC_INTERNAL void upstart_cleanup(void); #endif /* UPSTART__H */ diff --git a/scratch.c b/scratch.c index a552ab120c..bd0358f5a0 100644 --- a/scratch.c +++ b/scratch.c @@ -1,64 +1,53 @@ -/* - * Copyright 2004-2013 the Pacemaker project contributors +/* + * Copyright 2004-2021 the Pacemaker project contributors * * The version control history for this file may have further details. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * This source code is licensed under the GNU General Public License version 2 + * or later (GPLv2+) WITHOUT ANY WARRANTY. */ #include #include #include #include #include #include #include #include #include #include #include #define OPTARGS "X:" int main(int argc, char **argv) { int flag; xmlNode *top = NULL; const char *xml_file = NULL; crm_log_init(NULL, LOG_TRACE, FALSE, TRUE, argc, argv, FALSE); while (1) { flag = getopt(argc, argv, OPTARGS); if (flag == -1) break; switch (flag) { case 'X': xml_file = optarg; break; default: printf("Unknown option: -%c\n", flag); break; } } top = filename2xml(xml_file); free_xml(top); return 0; }