Statistics
| Branch: | Tag: | Revision:

root / doc / examples / ganeti-node-role.ocf.in @ ab6536ba

History | View | Annotate | Download (3.9 kB)

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