root / doc / examples / ganeti-node-role.ocf.in @ 17071597
History | View | Annotate | Download (3.9 kB)
1 |
#!/bin/bash |
---|---|
2 |
# ganeti node role OCF resource |
3 |
# See http://linux-ha.org/wiki/OCF_Resource_Agents |
4 |
|
5 |
set -e -u |
6 |
|
7 |
@SHELL_ENV_INIT@ |
8 |
|
9 |
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin |
10 |
|
11 |
SCRIPTNAME="@LIBDIR@/ocf/resource.d/ganeti/ganeti-node-role" |
12 |
|
13 |
# If this file exists don't act on notifications, thus allowing them to happen |
14 |
# during the service configuration. |
15 |
NORUNFILE="$DATA_DIR/ha_node_role_config" |
16 |
|
17 |
# Where to grep for tags |
18 |
TAGSFILE="$DATA_DIR/ssconf_cluster_tags" |
19 |
|
20 |
# If this tag is set we won't try to powercycle nodes |
21 |
POWERCYCLETAG="ocf:node-offline:use-powercycle" |
22 |
|
23 |
# If this tag is set will use IPMI to power off an offline node |
24 |
POWEROFFTAG="ocf:node-offline:use-poweroff" |
25 |
|
26 |
# We'll need the hostname in a few places, so we'll get it once, now. |
27 |
MYHOSTNAME=$(hostname --fqdn) |
28 |
|
29 |
is_master() { |
30 |
local -r master=$(gnt-cluster getmaster) |
31 |
[[ "$MYHOSTNAME" == "$master" ]] |
32 |
} |
33 |
|
34 |
start_action() { |
35 |
# If we're alive we consider ourselves a node, without starting anything. |
36 |
# TODO: improve on this |
37 |
exit 0 |
38 |
} |
39 |
|
40 |
stop_action() { |
41 |
# We can't "really" stop the service locally. |
42 |
# TODO: investigate whether a "fake" stop will work. |
43 |
exit 1 |
44 |
} |
45 |
|
46 |
recover_action() { |
47 |
# Nothing to recover, as long as we're alive. |
48 |
exit 0 |
49 |
} |
50 |
|
51 |
monitor_action() { |
52 |
# If we're alive we consider ourselves a working node. |
53 |
# TODO: improve on this |
54 |
exit 0 |
55 |
} |
56 |
|
57 |
offline_node() { |
58 |
local -r node=$1 |
59 |
grep -Fx $POWERCYCLETAG $TAGSFILE && gnt-node powercycle $node |
60 |
grep -Fx $POWEROFFTAG $TAGSFILE && gnt-node power off $node |
61 |
# TODO: do better than just --auto-promote |
62 |
# (or make sure auto-promote gets better in Ganeti) |
63 |
gnt-node modify -O yes --auto-promote $node |
64 |
} |
65 |
|
66 |
drain_node() { |
67 |
node=$1 |
68 |
# TODO: do better than just --auto-promote |
69 |
# (or make sure auto-promote gets better in Ganeti) |
70 |
gnt-node modify -D yes --auto-promote $node || return 1 |
71 |
} |
72 |
|
73 |
notify_action() { |
74 |
is_master || exit 0 |
75 |
[[ -f $NORUNFILE ]] && exit 0 |
76 |
# TODO: also implement the "start" operation for readding a node |
77 |
[[ $OCF_RESKEY_CRM_meta_notify_operation == "stop" ]] || exit 0 |
78 |
[[ $OCF_RESKEY_CRM_meta_notify_type == "post" ]] || exit 0 |
79 |
local -r target=$OCF_RESKEY_CRM_meta_notify_stop_uname |
80 |
local -r node=$(gnt-node list --no-headers -o name $target) |
81 |
# TODO: use drain_node when we can |
82 |
offline_node $node |
83 |
exit 0 |
84 |
} |
85 |
|
86 |
return_meta() { |
87 |
cat <<END |
88 |
<?xml version="1.0"?> |
89 |
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> |
90 |
<resource-agent name="ganeti-node-role" version="0.1"> |
91 |
<version>0.1</version> |
92 |
<longdesc lang="en"> |
93 |
OCF script to manage the ganeti node role in a cluster. |
94 |
|
95 |
Can be used to online and offline nodes. Should be cloned on all nodes of the |
96 |
cluster, with notification enabled. |
97 |
|
98 |
</longdesc> |
99 |
<shortdesc lang="en">Manages the ganeti cluster nodes</shortdesc> |
100 |
|
101 |
<parameters/> |
102 |
<actions> |
103 |
<action name="start" timeout="10s" /> |
104 |
<action name="stop" timeout="10s" /> |
105 |
<action name="monitor" depth="0" timeout="10s" interval="30s" /> |
106 |
<action name="meta-data" timeout="5s" /> |
107 |
<action name="recover" timeout="20s" /> |
108 |
<action name="reload" timeout="5s" /> |
109 |
<action name="notify" timeout="1000s" /> |
110 |
</actions> |
111 |
</resource-agent> |
112 |
END |
113 |
exit 0 |
114 |
} |
115 |
|
116 |
case "$1" in |
117 |
# Mandatory OCF commands |
118 |
start) |
119 |
start_action |
120 |
;; |
121 |
stop) |
122 |
stop_action |
123 |
;; |
124 |
monitor) |
125 |
monitor_action |
126 |
;; |
127 |
meta-data) |
128 |
return_meta |
129 |
;; |
130 |
# Optional OCF commands |
131 |
recover) |
132 |
recover_action |
133 |
;; |
134 |
reload) |
135 |
# The ganeti node role has no "configuration" that is reloadable on |
136 |
# the pacemaker side. We declare the operation anyway to make sure |
137 |
# pacemaker doesn't decide to stop and start the service needlessly. |
138 |
exit 0 |
139 |
;; |
140 |
notify) |
141 |
# Notification of a change to the ganeti node role |
142 |
notify_action |
143 |
exit 0 |
144 |
;; |
145 |
promote|demote|migrate_to|migrate_from|validate-all) |
146 |
# Not implemented (nor declared by meta-data) |
147 |
exit 3 # OCF_ERR_UNIMPLEMENTED |
148 |
;; |
149 |
*) |
150 |
log_success_msg "Usage: $SCRIPTNAME {start|stop|monitor|meta-data|recover|reload}" |
151 |
exit 1 |
152 |
;; |
153 |
esac |
154 |
|
155 |
exit 0 |