lib/vagrant/compose/util/cluster.rb in vagrant-compose-0.2.3 vs lib/vagrant/compose/util/cluster.rb in vagrant-compose-0.2.4

- old
+ new

@@ -3,39 +3,37 @@ module VagrantPlugins module Compose # This class defines a cluster, thas is a set of group of nodes, where nodes in each group has similar characteristics. - # Basically, a cluster is a data structure that can be used as a recipe for setting up and provisioning a + # Basically, a cluster is a data structure that can be used as a recipe for setting up and provisioning a # vagrant cluster composed by several machines with different roles. class Cluster # The name of the cluster attr_reader :name - # The default vagrant base box to be used for creating vagrant machines in this cluster. + # The default vagrant base box to be used for creating vagrant machines in this cluster. # This setting can be changed at group/node level attr_accessor :box - + # The network domain to wich the cluster belongs (used for computing nodes fqdn) attr_accessor :domain - + # The root path for ansible playbook; it is used as a base path for computing ansible_group_vars and ansible_host_vars # It defaults to current directory/provisioning attr_accessor :ansible_playbook_path - - # The path where ansible group vars files are stores. - # It default to ansible_playbook_path/group_vars - attr_accessor :ansible_group_vars - - # The path where ansible group vars files are stores. - # It default to ansible_playbook_path/host_vars - attr_accessor :ansible_host_vars + # A dictionary, allowing to setup ansible_group_vars generators foreach node_group + attr_reader :ansible_group_vars + + # A dictionary, allowing to setup ansible_host_vars generators foreach node_group + attr_reader :ansible_host_vars + # A dictionary, allowing to setup context vars to be uses is value_generators when composing nodes - attr_accessor :ansible_context_vars + attr_reader :ansible_context_vars # A variable that reflects if vagrant is tageting a single machine, like f.i. when executing vagrant up machine-name attr_reader :multimachine_filter # Costruttore di una istanza di cluster. @@ -45,53 +43,51 @@ @ansible_context_vars = {} @ansible_group_vars = {} @ansible_host_vars = {} @multimachine_filter = "" @ansible_playbook_path = File.join(Dir.pwd, 'provisioning') - @ansible_group_vars_path = File.join(@ansible_playbook_path, 'group_vars') - @ansible_host_vars_path = File.join(@ansible_playbook_path, 'host_vars') - @name = name + @name = name @box = 'ubuntu/trusty64' @domain = 'vagrant' - end + end # Metodo per la creazione di un gruppo di nodi; in fase di creazione, il blocco inizializza # i valori/le expressioni da utilizzarsi nella valorizzazione degli attributi dei nodi in fase di compose. # # Oltre alla creazione dei nodi, il metodo prevede anche l'esecuzione di un blocco di codice per # la configurazione del gruppo di nodi stesso. def nodes(instances, name, &block) raise RuntimeError, "Nodes #{name} already exists in this cluster." unless not @node_groups.has_key?(name) @node_groups[name] = NodeGroup.new(@group_index, instances, name) - @node_groups[name].box = @box + @node_groups[name].box = @box @node_groups[name].boxname = lambda { |group_index, group_name, node_index| return "#{group_name}#{node_index + 1}" } @node_groups[name].hostname = lambda { |group_index, group_name, node_index| return "#{group_name}#{node_index + 1}" } @node_groups[name].aliases = [] @node_groups[name].ip = lambda { |group_index, group_name, node_index| return "172.31.#{group_index}.#{100 + node_index + 1}" } @node_groups[name].cpus = 1 @node_groups[name].memory = 256 @node_groups[name].ansible_groups = [] @node_groups[name].attributes = {} - @group_index += 1 + @group_index += 1 block.call(@node_groups[name]) if block_given? - end + end # Prepara il provisioning del cluster - def compose + def compose - @multimachine_filter = ARGV.length > 1 ? ARGV[1] : "" # detect if running vagrant up/provision MACHINE + @multimachine_filter = ((['up', 'provision'].include? ARGV[0]) && ARGV.length > 1) ? ARGV.drop(1) : [] # detect if running vagrant up/provision MACHINE ## Fase1: Creazione dei nodi # sviluppa i vari gruppi di nodi, creando i singoli nodi nodes = [] - @node_groups.each do |key, group| + @node_groups.each do |key, group| group.compose(@name, @domain, nodes.size) do |node| nodes << node end end @@ -100,24 +96,24 @@ ansible_groups= {} nodes.each do |node| node.ansible_groups.each do |ansible_group| ansible_groups[ansible_group] = [] unless ansible_groups.has_key? (ansible_group) ansible_groups[ansible_group] << node - end + end end ## Fase2: Configurazione provisioning del cluster via Ansible - # Ogni nodo diventerà una vm su cui sarà fatto il provisioning, ovvero un host nell'inventory di ansible + # Ogni nodo diventerà una vm su cui sarà fatto il provisioning, ovvero un host nell'inventory di ansible # Ad ogni gruppo corrispondono nodi con caratteristiche simili # genearazione inventory file per ansible, aka ansible_groups in Vagrant (NB. 1 group = 1 gruppo ansible) ansible_groups_provision = {} ansible_groups.each do |ansible_group, ansible_group_nodes| ansible_groups_provision[ansible_group] = [] ansible_group_nodes.each do |node| - ansible_groups_provision[ansible_group] << node.hostname if @multimachine_filter.empty? or @multimachine_filter == node.boxname #filter ansible groups if vagrant command on one node - end + ansible_groups_provision[ansible_group] << node.hostname if checkMultimachineFilter(node.boxname) #filter ansible groups if vagrant command on one node + end end ansible_groups_provision['all_groups:children'] = ansible_groups.keys # Oltre alla creazione del file di inventory per ansible, contenente gruppi e host, è supportata: # - la creazione di file ansible_group_vars, ovvero di file preposti a contenere una serie di variabili - specifico di ogni gruppo di host - @@ -130,105 +126,140 @@ context = {} #genearazione context (NB. 1 group = 1 gruppo host ansible) ansible_groups.each do |ansible_group, ansible_group_nodes| - # genero le variabili per il group provisioners = @ansible_context_vars[ansible_group] unless provisioners.nil? + # se necessario, normalizzo provisioner in array provisioners - provisioners = [ provisioners ] if not provisioners.respond_to?('each') - # per tutti i provisioners abbinati al ruolo + provisioners = [ provisioners ] if not provisioners.respond_to?('each') + # per tutti i provisioners abbinati al ruolo provisioners.each do |provisioner| begin vars = provisioner.call(context, ansible_group_nodes) #TODO: gestire conflitto (n>=2 gruppi che generano la stessa variabile - con valori diversi) context = context.merge(vars) rescue Exception => e raise VagrantPlugins::Compose::Errors::ContextVarExpressionError, :message => e.message, :ansible_group => ansible_group end - end + end end end # cleanup ansible_group_vars files # TODO: make safe - FileUtils.mkdir_p(@ansible_group_vars_path) unless File.exists?(@ansible_group_vars_path) - Dir.foreach(@ansible_group_vars_path) {|f| fn = File.join(@ansible_group_vars_path, f); File.delete(fn) if f.end_with?(".yml")} + ansible_group_vars_path = File.join(@ansible_playbook_path, 'group_vars') + FileUtils.mkdir_p(ansible_group_vars_path) unless File.exists?(ansible_group_vars_path) + Dir.foreach(ansible_group_vars_path) {|f| fn = File.join(ansible_group_vars_path, f); File.delete(fn) if f.end_with?(".yml")} + #generazione ansible_group_vars file (NB. 1 group = 1 gruppo host ansible) ansible_groups.each do |ansible_group, ansible_group_nodes| ansible_group_vars = {} # genero le variabili per il group provisioners = @ansible_group_vars[ansible_group] unless provisioners.nil? # se necessario, normalizzo provisioner in array provisioners - provisioners = [ provisioners ] if not provisioners.respond_to?('each') - # per tutti i provisioners abbinati al ruolo + provisioners = [ provisioners ] if not provisioners.respond_to?('each') + # per tutti i provisioners abbinati al ruolo provisioners.each do |provisioner| begin vars = provisioner.call(context, ansible_group_nodes) #TODO: gestire conflitto (n>=2 gruppi che generano la stessa variabile - con valori diversi) ansible_group_vars = ansible_group_vars.merge(vars) rescue Exception => e raise VagrantPlugins::Compose::Errors::GroupVarExpressionError, :message => e.message, :ansible_group => ansible_group end - end + end end # crea il file (se sono state generate delle variabili) unless ansible_group_vars.empty? - # TODO: make safe - File.open(File.join(@ansible_group_vars_path,"#{ansible_group}.yml") , 'w+') do |file| + # TODO: make safe + File.open(File.join(ansible_group_vars_path,"#{ansible_group}.yml") , 'w+') do |file| file.puts YAML::dump(ansible_group_vars) - end + end end end # cleanup ansible_host_vars files (NB. 1 nodo = 1 host) # TODO: make safe - FileUtils.mkdir_p(@ansible_host_vars_path) unless File.exists?(@ansible_host_vars_path) - Dir.foreach(@ansible_host_vars_path) {|f| fn = File.join(@ansible_host_vars_path, f); File.delete(fn) if f.end_with?(".yml")} + ansible_host_vars_path = File.join(@ansible_playbook_path, 'host_vars') + FileUtils.mkdir_p(ansible_host_vars_path) unless File.exists?(ansible_host_vars_path) + Dir.foreach(ansible_host_vars_path) {|f| fn = File.join(ansible_host_vars_path, f); File.delete(fn) if f.end_with?(".yml")} + #generazione ansible_host_vars file nodes.each do |node| # genero le variabili per il nodo; il nodo, può essere abbinato a diversi gruppi ansible_host_vars = {} node.ansible_groups.each do |ansible_group| # genero le variabili per il gruppo provisioners = @ansible_host_vars[ansible_group] unless provisioners.nil? # se necessario, normalizzo provisioner in array provisioners - provisioners = [ provisioners ] if not provisioners.respond_to?('each') + provisioners = [ provisioners ] if not provisioners.respond_to?('each') # per tutti i provisioners abbinati al gruppo provisioners.each do |provisioner| begin vars = provisioner.call(context, node) #TODO: gestire conflitto (n>=2 gruppi che generano la stessa variabile - con valori diversi) ansible_host_vars = ansible_host_vars.merge(vars) rescue Exception => e raise VagrantPlugins::Compose::Errors::HostVarExpressionError, :message => e.message, :host => node.hostname, :ansible_group => ansible_group end - end + end end end # crea il file (se sono state generate delle variabili) unless ansible_host_vars.empty? - # TODO: make safe - File.open(File.join(@ansible_host_vars_path,"#{node.hostname}.yml") , 'w+') do |file| + # TODO: make safe + File.open(File.join(ansible_host_vars_path,"#{node.hostname}.yml") , 'w+') do |file| file.puts YAML::dump(ansible_host_vars) - end + end end end return nodes, ansible_groups_provision end - end - end -end + # Prepara il provisioning del cluster + def from(file) + puts "from #{file}" + begin + a = `ls` + puts "get #{a}" + rescue Exception => e + raise VagrantPlugins::Compose::Errors::PyComposeError, :message => e.message + end + end + def checkMultimachineFilter(boxname) + if @multimachine_filter.length > 0 + @multimachine_filter.each do |name| + if pattern = name[/^\/(.+?)\/$/, 1] + # This is a regular expression name, so we convert to a regular + # expression and allow that sort of matching. + regex = Regexp.new(pattern) + return boxname =~ regex + else + # String name, just look for a specific VM + return boxname == name + end + end + else + # No name was given, so we return every VM in the order + # configured. + return true + end + end + + end + + end +end