modules/mu/config.rb in cloud-mu-3.4.0 vs modules/mu/config.rb in cloud-mu-3.5.0

- old
+ new

@@ -435,31 +435,31 @@ # @param resource [Hash] # @param name [String] # @param type [String] # @param phase [String] # @param no_create_wait [Boolean] - def self.addDependency(resource, name, type, phase: "create", no_create_wait: false) - if ![nil, "create", "groom"].include?(phase) - raise MuError, "Invalid phase '#{phase}' while adding dependency #{type} #{name} to #{resource['name']}" + def self.addDependency(resource, name, type, their_phase: "create", my_phase: nil) + if ![nil, "create", "groom"].include?(their_phase) + raise MuError, "Invalid their_phase '#{their_phase}' while adding dependency #{type} #{name} to #{resource['name']}" end resource['dependencies'] ||= [] _shortclass, cfg_name, _cfg_plural, _classname = MU::Cloud.getResourceNames(type) resource['dependencies'].each { |dep| if dep['type'] == cfg_name and dep['name'].to_s == name.to_s - dep["no_create_wait"] = no_create_wait - dep["phase"] = phase if phase + dep["their_phase"] = their_phase if their_phase + dep["my_phase"] = my_phase if my_phase return end } newdep = { "type" => cfg_name, - "name" => name.to_s, - "no_create_wait" => no_create_wait + "name" => name.to_s } - newdep["phase"] = phase if phase + newdep["their_phase"] = their_phase if their_phase + newdep["my_phase"] = my_phase if my_phase resource['dependencies'] << newdep end @@ -744,11 +744,11 @@ if !descriptor["add_firewall_rules"].nil? descriptor["add_firewall_rules"].each { |acl_include| next if !acl_include["name"] and !acl_include["rule_name"] acl_include["name"] ||= acl_include["rule_name"] if haveLitterMate?(acl_include["name"], "firewall_rules") - MU::Config.addDependency(descriptor, acl_include["name"], "firewall_rule", no_create_wait: (cfg_name == "vpc")) + MU::Config.addDependency(descriptor, acl_include["name"], "firewall_rule", my_phase: ((cfg_name == "vpc") ? "groom" : "create")) elsif acl_include["name"] MU.log shortclass.to_s+" #{descriptor['name']} depends on FirewallRule #{acl_include["name"]}, but no such rule declared.", MU::ERR ok = false end } @@ -890,10 +890,14 @@ next if !resource.kind_of?(Hash) or resource["dependencies"].nil? addme = [] deleteme = [] resource["dependencies"].each { |dependency| + dependency["their_phase"] ||= dependency["phase"] + dependency.delete("phase") + dependency["my_phase"] ||= dependency["no_create_wait"] ? "groom" : "create" + dependency.delete("no_create_wait") # make sure the thing we depend on really exists sibling = haveLitterMate?(dependency['name'], dependency['type']) if !sibling MU.log "Missing dependency: #{type}{#{resource['name']}} needs #{cfg_name}{#{dependency['name']}}", MU::ERR ok = false @@ -927,23 +931,35 @@ next end end end + if dependency['their_phase'] == "groom" + sibling['dependencies'].each { |sib_dep| + next if sib_dep['type'] != cfg_name or sib_dep['their_phase'] != "groom" + cousin = haveLitterMate?(sib_dep['name'], sib_dep['type']) + if cousin and cousin['name'] == resource['name'] + MU.log "Circular dependency between #{type} #{resource['name']} <=> #{dependency['type']} #{dependency['name']}", MU::ERR, details: [ resource['name'] => dependency, sibling['name'] => sib_dep ] + ok = false + end + } + end + # Check for a circular relationship that will lead to a deadlock # when creating resource. This only goes one layer deep, and does # not consider groom-phase deadlocks. - if dependency['phase'] == "groom" or dependency['no_create_wait'] or ( + if dependency['their_phase'] == "groom" or + dependency['my_phase'] == "groom" or ( !MU::Cloud.resourceClass(sibling['cloud'], type).deps_wait_on_my_creation and !MU::Cloud.resourceClass(resource['cloud'], type).waits_on_parent_completion ) next end if sibling['dependencies'] sibling['dependencies'].each { |sib_dep| - next if sib_dep['type'] != cfg_name or sib_dep['no_create_wait'] + next if sib_dep['type'] != cfg_name or sib_dep['my_phase'] == "groom" cousin = haveLitterMate?(sib_dep['name'], sib_dep['type']) if cousin and cousin['name'] == resource['name'] MU.log "Circular dependency between #{type} #{resource['name']} <=> #{dependency['type']} #{dependency['name']}", MU::ERR, details: [ resource['name'] => dependency, sibling['name'] => sib_dep ] ok = false end @@ -1236,10 +1252,10 @@ ruleset["rules"] << { "proto" => "tcp", "port" => db["port"], "sgs" => [cfg_name+server['name']] } - MU::Config.addDependency(ruleset, cfg_name+server['name'], "firewall_rule", no_create_wait: true) + MU::Config.addDependency(ruleset, cfg_name+server['name'], "firewall_rule", my_phase: "groom") end } } } end