1############################################################
2#
3#  Chinese Dragon Dancing on a Star
4#
5#  This method works with either Community or Enterprise.
6#  and uses named signals
7#
8#  If you want to test this on localhost, just edit /etc/hosts
9#  to add host1 host2 host3 host4 as aliases to localhost
10#
11# Start a switch file /tmp/switch_file with
12#   host1 ON
13#   host2 ON
14#   host3 ON etc
15
16
17############################################################
18
19body common control
20{
21      bundlesequence => { "dragon_symphony" };
22      inputs => { "$(sys.libdir)/stdlib.cf" };
23}
24
25############################################################
26
27bundle agent dragon_symphony
28{
29  methods:
30
31      # We have to seed the beginning by creating the dragon
32      # /tmp/dragon_localhost
33
34      "dragon"  usebundle => upgrade_host("localhost","host1","chapter1");
35
36      "dragon"  usebundle => upgrade_host("host1","host2","chapter2");
37
38      "dragon"  usebundle => upgrade_host("host2","host3","chapter3");
39
40      "dragon"  usebundle => upgrade_host("host3","host4","chapter4"),
41      classes => if_ok("finale");
42
43    finale::
44
45      "dragon"  usebundle => restore_final("host4"),
46      comment => "Restore all the deactivated satellites";
47
48
49  reports:
50
51    finale::
52
53      "The dragon is slain!!!"
54      printfile => visitors_book("/tmp/shoo_dragon_host4");
55
56      "And the switch state is..."
57      printfile => visitors_book("/tmp/switch_file");
58}
59
60############################################################
61# Define the
62############################################################
63
64bundle agent chapter1(x)
65{
66      # Do something significant here
67
68  reports:
69
70    host1::
71      " ----> Breathing fire on $(x)";
72}
73
74################################
75
76bundle agent chapter2(x)
77{
78      # Do something significant here
79
80  reports:
81
82    host2::
83      " ----> Breathing fire on $(x)";
84
85}
86
87################################
88
89bundle agent chapter3(x)
90{
91      # Do something significant here
92
93  reports:
94
95    host3::
96      " ----> Breathing fire on $(x)";
97
98}
99
100################################
101
102bundle agent chapter4(x)
103{
104      # Do something significant here
105
106  reports:
107
108    host4::
109      " ----> Breathing fire on $(x)";
110
111}
112
113############################################################
114# Orchestration wrappers
115############################################################
116
117bundle agent upgrade_host(predecessor,satellite,method)
118{
119
120      # This is a wrapper for the orchestration will be acted on
121      # first by the dragon's lair and then by the satellite
122
123  vars:
124
125      "dragons_lair" string => "host0";
126
127  files:
128
129      # We start in the dragon's lair ..
130
131      "/tmp/unleash_dragon"
132
133      comment => "Unleash the dragon",
134      rename => to("/tmp/enter_the_dragon"),
135      classes => if_repaired("dispatch_dragon_$(satellite)"),
136      if => "$(dragons_lair)";
137
138      # if we are the dragon's lair, welcome the dragon back, shooed from the satellite
139
140      "/tmp/enter_the_dragon"
141
142      comment => "Returning from a visit to a satellite",
143      copy_from => secure_cp("/tmp/shoo_dragon_$(predecessor)","$(predecessor)"),
144      classes => if_repaired("dispatch_dragon_$(satellite)"),
145      if => "$(dragons_lair)";
146
147      # If we are a satellite, receive the dragon from its lair
148
149      "/tmp/enter_the_dragon"
150      comment => "Wait for our cue or relay/conductor baton",
151      copy_from => secure_cp("/tmp/dragon_$(satellite)","$(dragons_lair)"),
152      classes => if_repaired("cue_action_on_$(satellite)"),
153      if => "$(satellite)";
154
155  methods:
156
157      "check in at home"
158      comment => "Edit the load balancer?",
159      usebundle => next_host("$(satellite)","$(predecessor)"),
160      classes => if_repaired("send_the_dragon_to_$(satellite)"),
161      if => "dispatch_dragon_$(satellite)";
162
163      "dragon visits"
164      comment => "One off activity that the nodes carry out while the dragon visits",
165      usebundle => $(method)("$(satellite)"),
166      classes => if_repaired("send_the_dragon_back_from_$(satellite)"),
167      if => "cue_action_on_$(satellite)";
168
169
170  files:
171
172      # hub/lair hub signs the book too and schedules the dragon for next satellite
173
174      "/tmp/dragon_$(satellite)"
175      create => "true",
176      comment => "Add our signature to the dragon's tail",
177      edit_line => sign_visitor_book("Dragon returned from $(predecessor)"),
178      if => "send_the_dragon_to_$(satellite)";
179
180      # Satellite signs the book and shoos dragon for hub to collect
181
182      "/tmp/shoo_dragon_$(satellite)"
183      create => "true",
184      comment => "Add our signature to the dragon's tail",
185      edit_line => sign_visitor_book("Dragon visited $(satellite) and did: $(method)"),
186      if => "send_the_dragon_back_from_$(satellite)";
187
188  reports:
189
190      "Done $(satellite)"
191      if => "$(satellite)";
192}
193
194############################################################
195
196bundle agent next_host(name,pred)
197{
198  files:
199
200      "/tmp/enter_the_dragon"
201      comment => "Add our signature to the dragon's tail",
202      edit_line => append_if_no_line("Switch new dragon's target $(name)");
203
204      # Edit the switch file
205
206      "/tmp/switch_file"
207      comment => "Restore whatever is missing and comment out",
208      edit_line => restore_and_comment("$(name)","$(pred)"),
209      classes => if_repaired("reload_switch_$(name)");
210
211  reports:
212
213    !problem::
214
215      "Returned from $(pred), heading out to $(name)";
216
217      " X Restoring $(pred) and switching new dragon's target $(name)"
218      if => "reload_switch_$(name)";
219}
220
221############################################################
222
223bundle agent restore_final(name)
224{
225  files:
226
227    host0::
228
229      "/tmp/switch_file"
230      comment => "Restore whatever is missing and comment out",
231      edit_line => restore_and_comment("NONE","$(name)"),
232      classes => if_repaired("reload_switch");
233
234  reports:
235
236    reload_switch::
237      " X Restoring $(name) to tidy up loose ends";
238
239}
240
241############################################################
242
243bundle edit_line sign_visitor_book(s)
244{
245  insert_lines:
246
247      "/tmp/enter_the_dragon"
248      comment => "Import the current visitor's book",
249      insert_type => "file";
250
251      "$(s)" comment => "Append this string to the visitor's book";
252}
253
254#
255
256bundle edit_line restore_and_comment(name,pred)
257{
258  replace_patterns:
259
260      "$(name) ON"
261
262      replace_with => value("$(name) OFF"),
263      comment => "Uncomment the predecessor to reactivate";
264
265      "$(pred) OFF"
266
267      replace_with => value("$(pred) ON"),
268      comment => "Comment out the new host",
269      classes => if_repaired("show_switch_$(name)");
270
271  reports:
272
273    !problem::
274
275      "The state of the switch was:"
276      printfile => visitors_book("/tmp/switch_file"),
277      if => "show_switch_$(name)";
278
279
280}
281
282############################################################
283
284
285bundle server access_rules()
286{
287  access:
288
289      "/tmp"
290
291      admit => { "127.0.0.1" };
292
293      "did.*"
294      resource_type => "context",
295      admit => { "127.0.0.1" };
296
297}
298
299############################################################
300
301body printfile visitors_book(file)
302{
303      file_to_print   => "$(file)";
304      number_of_lines => "100";
305}
306
307
308