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