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