vagrant-compose 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 03a7541ea3a7eab57a665a0d510467c444c1683b
4
+ data.tar.gz: c78fe102cb943bf9f724379a762a6e268c471bda
5
+ SHA512:
6
+ metadata.gz: 67e92a734dc62de90c13123df626f02830f5a328f6f7619708ef891ade36b4f890ec2f827ade85dbdf1ed91cce89bd51713d4403e038424ee8a3e78534f12e8c
7
+ data.tar.gz: 0640c723ad84731e00651c5f50ebad963e7fec8931057e12b0ae2542c334099300f97c33d079ae802d38068d94f8e469b5844d09c0ac3dedb64099c17efe09fa
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ # OS-specific
2
+ .DS_Store
3
+
4
+ # editors
5
+ *.swp
6
+
7
+ # Bundler/Rubygems
8
+ *.gem
9
+ .bundle
10
+ pkg/*
11
+ tags
12
+ Gemfile.lock
13
+
14
+ # Vagrant
15
+ .vagrant
16
+ Vagrantfile
17
+
18
+ # Test
19
+ provisioning
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --format doc --order random --color --fail-fast
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ before_install: gem install bundler -v 1.10.5
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # 0.1.0 (December 27, 2015)
2
+
3
+ * Initial release.
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vagrant-compose.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ # We depend on Vagrant for development, but we don't add it as a
8
+ # gem dependency because we expect to be installed within the
9
+ # Vagrant environment itself using `vagrant plugin`.
10
+ gem "vagrant", :git => "https://github.com/mitchellh/vagrant.git"
11
+ end
12
+
13
+ group :plugins do
14
+ gem "vagrant-compose" , path: "."
15
+ end
data/LICENCE ADDED
@@ -0,0 +1,8 @@
1
+ The MIT License (MIT)
2
+ Copyright (c) 2015 Fabrizio Pandini
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5
+
6
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7
+
8
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # vagrant-compose
2
+ A Vagrant plugin that helps building complex multi-machine scenarios
3
+
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'rspec/core/rake_task'
4
+
5
+ # Immediately sync all stdout so that tools like buildbot can
6
+ # immediately load in the output.
7
+ $stdout.sync = true
8
+ $stderr.sync = true
9
+
10
+ # Change to the directory of this file.
11
+ Dir.chdir(File.expand_path("../", __FILE__))
12
+
13
+ # This installs the tasks that help with gem creation and
14
+ # publishing.
15
+ Bundler::GemHelper.install_tasks
16
+
17
+ # Install the `spec` task so that we can run tests.
18
+ RSpec::Core::RakeTask.new
19
+
20
+ # Default task is to run the unit tests
21
+ task :default => "spec"
22
+
23
+ print "zzz"
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "vagrant/compose"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,37 @@
1
+ en:
2
+ vagrant_compose:
3
+ already_status: |-
4
+ The machine is already %{status}.
5
+ errors:
6
+ initialize_error: |-
7
+ Error executing initialize code for cluster => %{cluster_name}.
8
+ The error message is shown below:
9
+ %{message}
10
+
11
+ attribute_expression_error: |-
12
+ Error generating attribute => %{attribute} for node => %{node_index} in group => %{node_group_name}.
13
+ The error message is shown below:
14
+ %{message}
15
+
16
+ Attribute expression expected to be a literal or a code block returning a literal (see documentation).
17
+
18
+ context_var_expression_error: |-
19
+ Error generating ansible context vars for ansible_group => %{ansible_group}
20
+ The error message is shown below:
21
+ %{message}
22
+
23
+ Ansible context var expression expected to be a Hash literal or a code block returning an Hash literal (see documentation).
24
+
25
+ group_var_expression_error: |-
26
+ Error generating ansible group vars for ansible_group => %{ansible_group}
27
+ The error message is shown below:
28
+ %{message}
29
+
30
+ Ansible group var expression expected to be a Hash literal or a code block returning an Hash literal (see documentation).
31
+
32
+ host_var_expression_error: |-
33
+ Error generating ansible host vars for host => %{host} in ansible_group => %{ansible_group}
34
+ The error message is shown below:
35
+ %{message}
36
+
37
+ Ansible host var expression expected to be a Hash literal or a code block returning an Hash literal (see documentation).
@@ -0,0 +1,18 @@
1
+ require "pathname"
2
+
3
+ require "vagrant/compose/plugin"
4
+
5
+ module VagrantPlugins
6
+ module Compose
7
+ lib_path = Pathname.new(File.expand_path("../compose", __FILE__))
8
+
9
+ autoload :Errors, lib_path.join("errors")
10
+
11
+ # This returns the path to the source of this plugin.
12
+ #
13
+ # @return [Pathname]
14
+ def self.source_root
15
+ @source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,38 @@
1
+ require "vagrant"
2
+
3
+ require_relative "util/cluster"
4
+
5
+ module VagrantPlugins
6
+ module Compose
7
+ class Config < Vagrant.plugin("2", :config)
8
+
9
+ attr_reader :nodes, :ansible_groups
10
+
11
+ def initialize
12
+ @nodes = {}
13
+ @ansible_groups = {}
14
+ end
15
+
16
+ def compose (name, &block)
17
+ # implementa la creazione di un cluster, l'esecuzione di un blocco di codice
18
+ # per la configurazione del cluster stesso, e l'esecuzione della sequenza di compose.
19
+ @cluster = Cluster.new(name)
20
+ begin
21
+ block.call(@cluster)
22
+ rescue Exception => e
23
+ raise VagrantPlugins::Compose::Errors::ClusterInitializeError, :message => e.message, :cluster_name => name
24
+ end
25
+ @nodes, @ansible_groups = @cluster.compose
26
+ end
27
+
28
+ def debug
29
+ puts "==> cluster #{@cluster.name} with #{nodes.size} nodes"
30
+ @nodes.each do |node|
31
+ puts " #{node.boxname} accessible as #{node.fqdn} #{node.aliases} #{node.ip} => [#{node.box}, #{node.cpus} cpus, #{node.memory} memory]"
32
+
33
+ end
34
+ puts " ansible_groups filtered by #{@cluster.multimachine_filter}" if not @cluster.multimachine_filter.empty?
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,31 @@
1
+ require "vagrant"
2
+
3
+ module VagrantPlugins
4
+ module Compose
5
+ module Errors
6
+ class VagrantComposeError < Vagrant::Errors::VagrantError
7
+ error_namespace("vagrant_compose.errors")
8
+ end
9
+
10
+ class ClusterInitializeError < VagrantComposeError
11
+ error_key(:initialize_error)
12
+ end
13
+
14
+ class AttributeExpressionError < VagrantComposeError
15
+ error_key(:attribute_expression_error)
16
+ end
17
+
18
+ class ContextVarExpressionError < VagrantComposeError
19
+ error_key(:context_var_expression_error)
20
+ end
21
+
22
+ class GroupVarExpressionError < VagrantComposeError
23
+ error_key(:group_var_expression_error)
24
+ end
25
+
26
+ class HostVarExpressionError < VagrantComposeError
27
+ error_key(:host_var_expression_error)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,67 @@
1
+ begin
2
+ require "vagrant"
3
+ rescue LoadError
4
+ raise "The Vagrant Compose plugin must be run within Vagrant."
5
+ end
6
+
7
+ # This is a sanity check to make sure no one is attempting to install
8
+ # this into an early Vagrant version.
9
+ if Vagrant::VERSION < "1.8.1"
10
+ raise "The Vagrant Compose plugin is only compatible with Vagrant 1.8.1+"
11
+ end
12
+
13
+ module VagrantPlugins
14
+ module Compose
15
+ class Plugin < Vagrant.plugin("2")
16
+ name "Compose"
17
+ description <<-DESC
18
+ This plugin installs ...
19
+ DESC
20
+
21
+ config "cluster" do
22
+ # Setup logging and i18n
23
+ setup_logging
24
+ setup_i18n
25
+
26
+ require_relative "config"
27
+ Config
28
+ end
29
+
30
+
31
+ # This initializes the internationalization strings.
32
+ def self.setup_i18n
33
+ I18n.load_path << File.expand_path("locales/en.yml", Compose.source_root)
34
+ I18n.reload!
35
+ end
36
+
37
+ # This sets up our log level to be whatever VAGRANT_LOG is.
38
+ def self.setup_logging
39
+ require "log4r"
40
+
41
+ level = nil
42
+ begin
43
+ level = Log4r.const_get(ENV["VAGRANT_LOG"].upcase)
44
+ rescue NameError
45
+ # This means that the logging constant wasn't found,
46
+ # which is fine. We just keep `level` as `nil`. But
47
+ # we tell the user.
48
+ level = nil
49
+ end
50
+
51
+ # Some constants, such as "true" resolve to booleans, so the
52
+ # above error checking doesn't catch it. This will check to make
53
+ # sure that the log level is an integer, as Log4r requires.
54
+ level = nil if !level.is_a?(Integer)
55
+
56
+ # Set the logging level on all "vagrant" namespaced
57
+ # logs as long as we have a valid level.
58
+ if level
59
+ logger = Log4r::Logger.new("vagrant_compose")
60
+ logger.outputters = Log4r::Outputter.stderr
61
+ logger.level = level
62
+ logger = nil
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,207 @@
1
+ require_relative "node_group"
2
+
3
+ # Definisce un cluster, ovvero l'insieme di 1..n gruppi di nodi con caratteristiche simili.
4
+ class Cluster
5
+
6
+ attr_reader :name
7
+ attr_reader :multimachine_filter
8
+ attr_accessor :box
9
+ attr_accessor :domain
10
+ attr_accessor :ansible_playbook_path
11
+ attr_accessor :ansible_context_vars
12
+ attr_accessor :ansible_group_vars
13
+ attr_accessor :ansible_host_vars
14
+
15
+ # Costruttore di una istanza di cluster.
16
+ def initialize(name)
17
+ @group_uid = 0
18
+ @node_groups = {}
19
+ @ansible_context_vars = {}
20
+ @ansible_group_vars = {}
21
+ @ansible_host_vars = {}
22
+ @multimachine_filter = ""
23
+ @ansible_playbook_path = File.join(Dir.pwd, 'provisioning')
24
+
25
+ @name = name
26
+ @box = 'ubuntu/trusty64'
27
+ @domain = 'vagrant'
28
+ end
29
+
30
+ # Metodo per la creazione di un gruppo di nodi; in fase di creazione, il blocco inizializza
31
+ # i valori/le expressioni da utilizzarsi nella valorizzazione degli attributi dei nodi in fase di compose.
32
+ #
33
+ # Oltre alla creazione dei nodi, il metodo prevede anche l'esecuzione di un blocco di codice per
34
+ # la configurazione del gruppo di nodi stesso.
35
+ def nodes(name, &block)
36
+ raise RuntimeError, "Nodes #{name} already exists in this cluster." unless not @node_groups.has_key?(name)
37
+
38
+ @node_groups[name] = NodeGroup.new(@group_uid, name)
39
+ @node_groups[name].box = @box
40
+ @node_groups[name].boxname = lambda { |group_uid, group_name, node_index| return "#{group_name}#{node_index + 1}" }
41
+ @node_groups[name].hostname = lambda { |group_uid, group_name, node_index| return "#{group_name}#{node_index + 1}" }
42
+ @node_groups[name].aliases = []
43
+ @node_groups[name].ip = lambda { |group_uid, group_name, node_index| return "172.31.#{group_uid}.#{100 + node_index + 1}" }
44
+ @node_groups[name].cpus = 1
45
+ @node_groups[name].memory = 256
46
+ @node_groups[name].ansible_groups = []
47
+ @node_groups[name].attributes = {}
48
+
49
+ @group_uid += 1
50
+
51
+ block.call(@node_groups[name])
52
+ end
53
+
54
+ # Prepara il provisioning del cluster
55
+ def compose
56
+
57
+ @multimachine_filter = ARGV.length > 1 ? ARGV[1] : "" # detect if running vagrant up/provision MACHINE
58
+
59
+ ## Fase1: Creazione dei nodi
60
+
61
+ # sviluppa i vari gruppi di nodi, creando i singoli nodi
62
+ nodes = []
63
+
64
+ @node_groups.each do |key, group|
65
+ group.compose(@name, @domain, nodes.size) do |node|
66
+ nodes << node
67
+ end
68
+ end
69
+
70
+ # sviluppa i gruppi abbinando a ciascono i nodi creati
71
+ # NB. tiene in considerazione anche l'eventualità che un gruppo possa essere composto da nodi appartenenti a diversi node_groups
72
+ ansible_groups= {}
73
+ nodes.each do |node|
74
+ node.ansible_groups.each do |ansible_group|
75
+ ansible_groups[ansible_group] = [] unless ansible_groups.has_key? (ansible_group)
76
+ ansible_groups[ansible_group] << node
77
+ end
78
+ end
79
+
80
+ ## Fase2: Configurazione provisioning del cluster via Ansible
81
+ # Ogni nodo diventerà una vm su cui sarà fatto il provisioning, ovvero un host nell'inventory di ansible
82
+ # Ad ogni gruppo corrispondono nodi con caratteristiche simili
83
+
84
+ # genearazione inventory file per ansible, aka ansible_groups in Vagrant (NB. 1 group = 1 gruppo ansible)
85
+ ansible_groups_provision = {}
86
+ ansible_groups.each do |ansible_group, ansible_group_nodes|
87
+ ansible_groups_provision[ansible_group] = []
88
+ ansible_group_nodes.each do |node|
89
+ 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
90
+ end
91
+ end
92
+ ansible_groups_provision['all_groups:children'] = ansible_groups.keys
93
+
94
+ # Oltre alla creazione del file di inventory per ansible, contenente gruppi e host, è supportata:
95
+ # - la creazione di file ansible_group_vars, ovvero di file preposti a contenere una serie di variabili - specifico di ogni gruppo di host -
96
+ # per condizionare il provisioning ansible sulla base delle caratteristiche del cluster specifico
97
+ # - la creazione di file ansible_host_vars, ovvero di file preposti a contenere una serie di variabili - specifico di ogni host -
98
+ # per condizionare il provisioning ansible sulla base delle caratteristiche del cluster specifico
99
+
100
+ # La generazione delle variabili utilizza una serie di VariableProvisioner, uno o più d'uno per ogni gruppo di hosts, configurati durante la
101
+ # definizione del cluster.
102
+
103
+ context = {}
104
+
105
+ #genearazione context (NB. 1 group = 1 gruppo host ansible)
106
+ ansible_groups.each do |ansible_group, ansible_group_nodes|
107
+
108
+ # genero le variabili per il group
109
+ provisioners = @ansible_context_vars[ansible_group]
110
+ unless provisioners.nil?
111
+ # se necessario, normalizzo provisioner in array provisioners
112
+ provisioners = [ provisioners ] if not provisioners.respond_to?('each')
113
+ # per tutti i provisioners abbinati al ruolo
114
+ provisioners.each do |provisioner|
115
+ begin
116
+ vars = provisioner.call(context, ansible_group_nodes)
117
+
118
+ #TODO: gestire conflitto (n>=2 gruppi che generano la stessa variabile - con valori diversi)
119
+ context = context.merge(vars)
120
+ rescue Exception => e
121
+ raise VagrantPlugins::Compose::Errors::ContextVarExpressionError, :message => e.message, :ansible_group => ansible_group
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ # cleanup ansible_group_vars files
128
+ # TODO: make variable public
129
+ @ansible_group_vars_path = File.join(@ansible_playbook_path, 'group_vars')
130
+ # TODO: make safe
131
+ FileUtils.mkdir_p(@ansible_group_vars_path) unless File.exists?(@ansible_group_vars_path)
132
+ Dir.foreach(@ansible_group_vars_path) {|f| fn = File.join(@ansible_group_vars_path, f); File.delete(fn) if f.end_with?(".yml")}
133
+
134
+ #generazione ansible_group_vars file (NB. 1 group = 1 gruppo host ansible)
135
+ ansible_groups.each do |ansible_group, ansible_group_nodes|
136
+ ansible_group_vars = {}
137
+ # genero le variabili per il group
138
+ provisioners = @ansible_group_vars[ansible_group]
139
+ unless provisioners.nil?
140
+ # se necessario, normalizzo provisioner in array provisioners
141
+ provisioners = [ provisioners ] if not provisioners.respond_to?('each')
142
+ # per tutti i provisioners abbinati al ruolo
143
+ provisioners.each do |provisioner|
144
+ begin
145
+ vars = provisioner.call(context, ansible_group_nodes)
146
+
147
+ #TODO: gestire conflitto (n>=2 gruppi che generano la stessa variabile - con valori diversi)
148
+ ansible_group_vars = ansible_group_vars.merge(vars)
149
+ rescue Exception => e
150
+ raise VagrantPlugins::Compose::Errors::GroupVarExpressionError, :message => e.message, :ansible_group => ansible_group
151
+ end
152
+ end
153
+ end
154
+
155
+ # crea il file (se sono state generate delle variabili)
156
+ unless ansible_group_vars.empty?
157
+ # TODO: make safe
158
+ File.open(File.join(@ansible_group_vars_path,"#{ansible_group}.yml") , 'w+') do |file|
159
+ file.puts YAML::dump(ansible_group_vars)
160
+ end
161
+ end
162
+ end
163
+
164
+ # cleanup ansible_host_vars files (NB. 1 nodo = 1 host)
165
+ # TODO: make variable public
166
+ @ansible_host_vars_path = File.join(@ansible_playbook_path, 'host_vars')
167
+ # TODO: make safe
168
+ FileUtils.mkdir_p(@ansible_host_vars_path) unless File.exists?(@ansible_host_vars_path)
169
+ Dir.foreach(@ansible_host_vars_path) {|f| fn = File.join(@ansible_host_vars_path, f); File.delete(fn) if f.end_with?(".yml")}
170
+
171
+ #generazione ansible_host_vars file
172
+ nodes.each do |node|
173
+ # genero le variabili per il nodo; il nodo, può essere abbinato a diversi gruppi
174
+ ansible_host_vars = {}
175
+ node.ansible_groups.each do |ansible_group|
176
+ # genero le variabili per il gruppo
177
+ provisioners = @ansible_host_vars[ansible_group]
178
+ unless provisioners.nil?
179
+ # se necessario, normalizzo provisioner in array provisioners
180
+ provisioners = [ provisioners ] if not provisioners.respond_to?('each')
181
+ # per tutti i provisioners abbinati al gruppo
182
+ provisioners.each do |provisioner|
183
+ begin
184
+ vars = provisioner.call(context, node)
185
+
186
+ #TODO: gestire conflitto (n>=2 gruppi che generano la stessa variabile - con valori diversi)
187
+ ansible_host_vars = ansible_host_vars.merge(vars)
188
+ rescue Exception => e
189
+ raise VagrantPlugins::Compose::Errors::HostVarExpressionError, :message => e.message, :host => node.hostname, :ansible_group => ansible_group
190
+ end
191
+ end
192
+ end
193
+ end
194
+
195
+ # crea il file (se sono state generate delle variabili)
196
+ unless ansible_host_vars.empty?
197
+ # TODO: make safe
198
+ File.open(File.join(@ansible_host_vars_path,"#{node.hostname}.yml") , 'w+') do |file|
199
+ file.puts YAML::dump(ansible_host_vars)
200
+ end
201
+ end
202
+ end
203
+
204
+ return nodes.map.with_index, ansible_groups_provision
205
+ end
206
+
207
+ end
@@ -0,0 +1,30 @@
1
+ # Definisce un nodo, ovvero uno delle istanze di nodi che compongono il cluster
2
+ class Node
3
+ attr_reader :box
4
+ attr_reader :boxname
5
+ attr_reader :hostname
6
+ attr_reader :fqdn
7
+ attr_reader :aliases
8
+ attr_reader :ip
9
+ attr_reader :cpus
10
+ attr_reader :memory
11
+ attr_reader :ansible_groups
12
+ attr_reader :attributes
13
+ attr_reader :index
14
+ attr_reader :group_index
15
+
16
+ def initialize(box, boxname, hostname, fqdn, aliases, ip, cpus, memory, ansible_groups, attributes, index, group_index)
17
+ @box = box
18
+ @boxname = boxname
19
+ @hostname = hostname
20
+ @fqdn = fqdn
21
+ @aliases = aliases
22
+ @ip = ip
23
+ @cpus = cpus
24
+ @memory = memory
25
+ @ansible_groups = ansible_groups
26
+ @attributes = attributes
27
+ @index = index
28
+ @group_index = group_index
29
+ end
30
+ end
@@ -0,0 +1,58 @@
1
+ require_relative "node"
2
+
3
+ # Definisce un node group, ovvero un insieme di nodi con caratteristiche omogenee.
4
+ # i singoli nodi del gruppo, sono generati in fase di compose tramite delle espressioni
5
+ # che generano i valori degli attributi che caratterizzano ogni nodo
6
+ class NodeGroup
7
+ attr_reader :uid, :name
8
+ attr_accessor :instances
9
+ attr_accessor :box
10
+ attr_accessor :boxname
11
+ attr_accessor :hostname
12
+ attr_accessor :aliases
13
+ attr_accessor :ip
14
+ attr_accessor :cpus
15
+ attr_accessor :memory
16
+ attr_accessor :ansible_groups
17
+ attr_accessor :attributes
18
+
19
+ def initialize(uid, name)
20
+ @uid = uid
21
+ @name = name
22
+ @instances = 1
23
+ end
24
+
25
+ # compone il gruppo, generando le istanze dei vari nodi
26
+ def compose(cluster_name, cluster_domain, cluster_offset)
27
+ node_index = 0
28
+ while node_index < @instances
29
+ box = generate(:box, @box, node_index)
30
+ boxname = "#{cluster_name}-#{generate(:boxname, @boxname, node_index)}"
31
+ hostname = "#{cluster_name}-#{generate(:hostname, @hostname, node_index)}"
32
+ aliases = generate(:aliases, @aliases, node_index).join(',')
33
+ fqdn = "#{hostname}.#{cluster_domain}"
34
+ ip = generate(:ip, @ip, node_index)
35
+ cpus = generate(:cpus, @cpus, node_index)
36
+ memory = generate(:memory, @memory, node_index)
37
+ ansible_groups = generate(:ansible_groups, @ansible_groups, node_index)
38
+ attributes = generate(:attributes, @attributes, node_index)
39
+ yield Node.new(box, boxname, hostname, fqdn, aliases, ip, cpus, memory, ansible_groups, attributes, cluster_offset + node_index, node_index)
40
+
41
+ node_index += 1
42
+ end
43
+ end
44
+
45
+ # funzione di utilità per l'esecuzione delle espressioni che generano
46
+ # i valori degli attributi
47
+ def generate(var, generator, node_index)
48
+ unless generator.respond_to? :call
49
+ return generator
50
+ else
51
+ begin
52
+ return generator.call(@uid, @name, node_index)
53
+ rescue Exception => e
54
+ raise VagrantPlugins::Compose::Errors::AttributeExpressionError, :message => e.message, :attribute => var, :node_index => node_index, :node_group_name => name
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,5 @@
1
+ module Vagrant
2
+ module Compose
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ ---
2
+ x: 1
@@ -0,0 +1,55 @@
1
+ $:.unshift File.expand_path("../lib", __FILE__)
2
+ require 'vagrant/compose/version'
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "vagrant-compose"
6
+ spec.version = Vagrant::Compose::VERSION
7
+ spec.platform = Gem::Platform::RUBY
8
+ spec.license = "MIT"
9
+ spec.authors = ["Fabrizio Pandini"]
10
+ spec.email = ["fabrizio.pandini@unicredit.eu"]
11
+ spec.homepage = "https://github.com/fabriziopandini/vagrant-compose/"
12
+ spec.summary = %q{A Vagrant plugin that helps building complex multi-machine scenarios.}
13
+ spec.description = %q{A Vagrant plugin that helps building complex multi-machine scenarios.}
14
+
15
+ spec.required_rubygems_version = ">= 2.0.13"
16
+
17
+ spec.add_development_dependency "rake", "~> 10.4.2"
18
+ spec.add_development_dependency "rspec", "~> 3.4.0"
19
+ spec.add_development_dependency "rspec-its", "~> 1.2.0"
20
+
21
+ # The following block of code determines the files that should be included
22
+ # in the gem. It does this by reading all the files in the directory where
23
+ # this gemspec is, and parsing out the ignored files from the gitignore.
24
+ # Note that the entire gitignore(5) syntax is not supported, specifically
25
+ # the "!" syntax, but it should mostly work correctly.
26
+ root_path = File.dirname(__FILE__)
27
+ all_files = Dir.chdir(root_path) { Dir.glob("**/{*,.*}") }
28
+ all_files.reject! { |file| [".", ".."].include?(File.basename(file)) }
29
+ gitignore_path = File.join(root_path, ".gitignore")
30
+ gitignore = File.readlines(gitignore_path)
31
+ gitignore.map! { |line| line.chomp.strip }
32
+ gitignore.reject! { |line| line.empty? || line =~ /^(#|!)/ }
33
+
34
+ unignored_files = all_files.reject do |file|
35
+ # Ignore any directories, the gemspec only cares about files
36
+ next true if File.directory?(file)
37
+
38
+ # Ignore any paths that match anything in the gitignore. We do
39
+ # two tests here:
40
+ #
41
+ # - First, test to see if the entire path matches the gitignore.
42
+ # - Second, match if the basename does, this makes it so that things
43
+ # like '.DS_Store' will match sub-directories too (same behavior
44
+ # as git).
45
+ #
46
+ gitignore.any? do |ignore|
47
+ File.fnmatch(ignore, file, File::FNM_PATHNAME) ||
48
+ File.fnmatch(ignore, File.basename(file), File::FNM_PATHNAME)
49
+ end
50
+ end
51
+
52
+ spec.files = unignored_files
53
+ spec.executables = unignored_files.map { |f| f[/^bin\/(.*)/, 1] }.compact
54
+ spec.require_path = 'lib'
55
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-compose
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Fabrizio Pandini
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 10.4.2
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 10.4.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 3.4.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 3.4.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-its
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 1.2.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.2.0
55
+ description: A Vagrant plugin that helps building complex multi-machine scenarios.
56
+ email:
57
+ - fabrizio.pandini@unicredit.eu
58
+ executables:
59
+ - console
60
+ - setup
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - bin/console
65
+ - bin/setup
66
+ - CHANGELOG.md
67
+ - Gemfile
68
+ - lib/locales/en.yml
69
+ - lib/vagrant/compose/config.rb
70
+ - lib/vagrant/compose/errors.rb
71
+ - lib/vagrant/compose/plugin.rb
72
+ - lib/vagrant/compose/util/cluster.rb
73
+ - lib/vagrant/compose/util/node.rb
74
+ - lib/vagrant/compose/util/node_group.rb
75
+ - lib/vagrant/compose/version.rb
76
+ - lib/vagrant/compose.rb
77
+ - LICENCE
78
+ - provisioning/group_vars/zookeeper.yml
79
+ - Rakefile
80
+ - README.md
81
+ - vagrant-compose.gemspec
82
+ - .gitignore
83
+ - .rspec
84
+ - .travis.yml
85
+ homepage: https://github.com/fabriziopandini/vagrant-compose/
86
+ licenses:
87
+ - MIT
88
+ metadata: {}
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - '>='
101
+ - !ruby/object:Gem::Version
102
+ version: 2.0.13
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 2.0.14
106
+ signing_key:
107
+ specification_version: 4
108
+ summary: A Vagrant plugin that helps building complex multi-machine scenarios.
109
+ test_files: []