############################################################ # # Chinese Dragon Dancing on a Star # # This method works with either Community or Enterprise. # and uses named signals # # If you want to test this on localhost, just edit /etc/hosts # to add host1 host2 host3 host4 as aliases to localhost # # Start a switch file /tmp/switch_file with # host1 ON # host2 ON # host3 ON etc ############################################################ body common control { bundlesequence => { "dragon_symphony" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } ############################################################ bundle agent dragon_symphony { methods: # We have to seed the beginning by creating the dragon # /tmp/dragon_localhost "dragon" usebundle => upgrade_host("localhost","host1","chapter1"); "dragon" usebundle => upgrade_host("host1","host2","chapter2"); "dragon" usebundle => upgrade_host("host2","host3","chapter3"); "dragon" usebundle => upgrade_host("host3","host4","chapter4"), classes => if_ok("finale"); finale:: "dragon" usebundle => restore_final("host4"), comment => "Restore all the deactivated satellites"; reports: finale:: "The dragon is slain!!!" printfile => visitors_book("/tmp/shoo_dragon_host4"); "And the switch state is..." printfile => visitors_book("/tmp/switch_file"); } ############################################################ # Define the ############################################################ bundle agent chapter1(x) { # Do something significant here reports: host1:: " ----> Breathing fire on $(x)"; } ################################ bundle agent chapter2(x) { # Do something significant here reports: host2:: " ----> Breathing fire on $(x)"; } ################################ bundle agent chapter3(x) { # Do something significant here reports: host3:: " ----> Breathing fire on $(x)"; } ################################ bundle agent chapter4(x) { # Do something significant here reports: host4:: " ----> Breathing fire on $(x)"; } ############################################################ # Orchestration wrappers ############################################################ bundle agent upgrade_host(predecessor,satellite,method) { # This is a wrapper for the orchestration will be acted on # first by the dragon's lair and then by the satellite vars: "dragons_lair" string => "host0"; files: # We start in the dragon's lair .. "/tmp/unleash_dragon" comment => "Unleash the dragon", rename => to("/tmp/enter_the_dragon"), classes => if_repaired("dispatch_dragon_$(satellite)"), if => "$(dragons_lair)"; # if we are the dragon's lair, welcome the dragon back, shooed from the satellite "/tmp/enter_the_dragon" comment => "Returning from a visit to a satellite", copy_from => secure_cp("/tmp/shoo_dragon_$(predecessor)","$(predecessor)"), classes => if_repaired("dispatch_dragon_$(satellite)"), if => "$(dragons_lair)"; # If we are a satellite, receive the dragon from its lair "/tmp/enter_the_dragon" comment => "Wait for our cue or relay/conductor baton", copy_from => secure_cp("/tmp/dragon_$(satellite)","$(dragons_lair)"), classes => if_repaired("cue_action_on_$(satellite)"), if => "$(satellite)"; methods: "check in at home" comment => "Edit the load balancer?", usebundle => next_host("$(satellite)","$(predecessor)"), classes => if_repaired("send_the_dragon_to_$(satellite)"), if => "dispatch_dragon_$(satellite)"; "dragon visits" comment => "One off activity that the nodes carry out while the dragon visits", usebundle => $(method)("$(satellite)"), classes => if_repaired("send_the_dragon_back_from_$(satellite)"), if => "cue_action_on_$(satellite)"; files: # hub/lair hub signs the book too and schedules the dragon for next satellite "/tmp/dragon_$(satellite)" create => "true", comment => "Add our signature to the dragon's tail", edit_line => sign_visitor_book("Dragon returned from $(predecessor)"), if => "send_the_dragon_to_$(satellite)"; # Satellite signs the book and shoos dragon for hub to collect "/tmp/shoo_dragon_$(satellite)" create => "true", comment => "Add our signature to the dragon's tail", edit_line => sign_visitor_book("Dragon visited $(satellite) and did: $(method)"), if => "send_the_dragon_back_from_$(satellite)"; reports: "Done $(satellite)" if => "$(satellite)"; } ############################################################ bundle agent next_host(name,pred) { files: "/tmp/enter_the_dragon" comment => "Add our signature to the dragon's tail", edit_line => append_if_no_line("Switch new dragon's target $(name)"); # Edit the switch file "/tmp/switch_file" comment => "Restore whatever is missing and comment out", edit_line => restore_and_comment("$(name)","$(pred)"), classes => if_repaired("reload_switch_$(name)"); reports: !problem:: "Returned from $(pred), heading out to $(name)"; " X Restoring $(pred) and switching new dragon's target $(name)" if => "reload_switch_$(name)"; } ############################################################ bundle agent restore_final(name) { files: host0:: "/tmp/switch_file" comment => "Restore whatever is missing and comment out", edit_line => restore_and_comment("NONE","$(name)"), classes => if_repaired("reload_switch"); reports: reload_switch:: " X Restoring $(name) to tidy up loose ends"; } ############################################################ bundle edit_line sign_visitor_book(s) { insert_lines: "/tmp/enter_the_dragon" comment => "Import the current visitor's book", insert_type => "file"; "$(s)" comment => "Append this string to the visitor's book"; } # bundle edit_line restore_and_comment(name,pred) { replace_patterns: "$(name) ON" replace_with => value("$(name) OFF"), comment => "Uncomment the predecessor to reactivate"; "$(pred) OFF" replace_with => value("$(pred) ON"), comment => "Comment out the new host", classes => if_repaired("show_switch_$(name)"); reports: !problem:: "The state of the switch was:" printfile => visitors_book("/tmp/switch_file"), if => "show_switch_$(name)"; } ############################################################ bundle server access_rules() { access: "/tmp" admit => { "127.0.0.1" }; "did.*" resource_type => "context", admit => { "127.0.0.1" }; } ############################################################ body printfile visitors_book(file) { file_to_print => "$(file)"; number_of_lines => "100"; }