Revision 17071597

b/.gitignore
67 67
/doc/examples/ganeti.initd
68 68
/doc/examples/ganeti-kvm-poweroff.initd
69 69
/doc/examples/ganeti-master-role.ocf
70
/doc/examples/ganeti-node-role.ocf
70 71
/doc/examples/gnt-config-backup
71 72
/doc/examples/hooks/ipsec
72 73

  
b/Makefile.am
209 209
	doc/examples/ganeti.cron \
210 210
	doc/examples/ganeti.initd \
211 211
	doc/examples/ganeti-master-role.ocf \
212
	doc/examples/ganeti-node-role.ocf \
212 213
	doc/examples/gnt-config-backup \
213 214
	doc/examples/hooks/ipsec
214 215

  
b/devel/upload
103 103
install -D --mode=0755 doc/examples/ganeti-master-role.ocf \
104 104
  "$TXD/$LIBDIR/ocf/resource.d/ganeti/ganeti-master-role"
105 105

  
106
[ -f doc/examples/ganeti-node-role.ocf ] && \
107
install -D --mode=0755 doc/examples/ganeti-node-role.ocf \
108
  "$TXD/$LIBDIR/ocf/resource.d/ganeti/ganeti-node-role"
109

  
106 110
[ -f doc/examples/ganeti.default-debug -a -z "$NO_DEBUG" ] && \
107 111
install -D --mode=0644 doc/examples/ganeti.default-debug \
108 112
  "$TXD/$SYSCONFDIR/default/ganeti"
b/doc/examples/ganeti-node-role.ocf.in
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

Also available in: Unified diff