zergrush_vagrant 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9dd98a5c71a254b0c02f3826f144f510891feada
4
- data.tar.gz: facd3cf108c86b6ca007812562f7ebe86e99fdd8
3
+ metadata.gz: 613db97e270ed84ab042953b3e2b0b9f190eee07
4
+ data.tar.gz: a31d61d4a70873d6661a8499d95bd6035951ac11
5
5
  SHA512:
6
- metadata.gz: 0049d7c9350f748c4065418a52be9a81f27f26935ef57d4eeef13a46b49e3c554f82e1dc8e0de2ae1a0a577997db5f7651376b1080cca8825559cc3a438a317b
7
- data.tar.gz: 113adfdbfd8c0873f1c6b6e9e75ec638d9d3e624ba2d58ebe00a3970ef5c791a85114914e0fa3b8a867d01ab860b706e86bdb21dbfa3536c21c1cf46042a785e
6
+ metadata.gz: 0cb6d4938d637ecd4f2eea9eea1193b9337eca37f838fe0483b12a647ea515c870f3b0f8f92d1ed5c7e25c855742bf77aadfdff8b06cf7b437f240eaf8601894
7
+ data.tar.gz: e80ee37bbdb5552b8d9939a3a662e93c93faf3a26c441a620546e619d68c5110d2c829dec944512d649b75ad8de14beef9b7fcddaae2f3dc8e5d44551011a704
data/README.md CHANGED
@@ -1,17 +1,113 @@
1
- zergrush_vagrant GemPlugin
1
+ Vagrant driver for Zerg
2
2
  ===
3
3
 
4
- Tasks
4
+ Dependencies
5
5
  --------------
6
+
7
+ - [vagrant-aws](https://github.com/mitchellh/vagrant-aws)
8
+ - [vagrant-libvirt](https://github.com/pradels/vagrant-libvirt)
9
+ - [vagrant-omnibus](https://github.com/schisamo/vagrant-omnibus)
10
+ - [vagrant-berkshelf](https://github.com/berkshelf/vagrant-berkshelf)
11
+
12
+ Additional properties defined
13
+ --------------
14
+
15
+ ######[Synchronized folders](resources/folder_schema.template)
16
+
17
+ Defined by [Vagrant synced folders](http://docs.vagrantup.com/v2/synced-folders/)
18
+
19
+ Example use:
20
+ ```
21
+ ...
22
+ "create": true,
23
+ "mount_options": ["rw", "vers=3", "tcp"]
24
+ ...
25
+ ```
26
+
27
+ ######[Networks](resources/networks_schema.template)
28
+
29
+ Defined by [Vagrant networking](http://docs.vagrantup.com/v2/networking/index.html)
30
+
31
+ Example use:
32
+ ```
33
+ ...
34
+ "type": "public_network",
35
+ "bridge": "en1: Wi-Fi (AirPort)"
36
+ ...
37
+ ```
38
+
39
+ ######[Driver options](resources/option_schema.template)
40
+
41
+ - providertype - One of the supported Vagrant providers. Currenlty supported providers are: virtualbox, libvirt, aws
42
+ - provider_options - hash of provider specific options.
43
+ - raw_options - if some of the provider options do not map to a hash format - you can specify them as an array of strings. Each string should start with '[provider].'
44
+
45
+ Example use:
46
+ ```
47
+ ...
48
+ "driver": {
49
+ "drivertype": "vagrant",
50
+ "driveroptions": [
51
+ {
52
+ "providertype": "aws",
53
+ "provider_options" : {
54
+ "instance_type": "t1.micro",
55
+ "access_key_id": "blah blah blah",
56
+ "secret_access_key": "yadda yadda",
57
+ "keypair_name": "HURGHBURGHLGHRL",
58
+ "ami": "ami-3fec7956",
59
+ "region": "us-east-1"
60
+ }
61
+ },
62
+ {
63
+ "providertype": "virtualbox",
64
+ "provider_options" : {
65
+ "gui": false,
66
+ "memory": 256
67
+ },
68
+ "raw_options": [
69
+ "virtualbox.customize [\"modifyvm\", :id, \"--natdnsproxy1\", \"off\"]",
70
+ "virtualbox.customize [\"modifyvm\", :id, \"--natdnshostresolver1\", \"off\"]"
71
+ ]
72
+ }
73
+ ]
74
+ }
75
+ ...
76
+ ```
77
+
78
+ ######[Forwarded ports](resources/ports_schema.template)
79
+
80
+ Defined by [Vagrant forwarded ports](http://docs.vagrantup.com/v2/networking/forwarded_ports.html)
81
+
82
+ Example use:
83
+ ```
84
+ ...
85
+ "guest_port": 8080,
86
+ "host_port": 80,
87
+ "protocol": "tcp"
88
+ ...
89
+ ```
90
+
91
+ ######[SSH](resources/ssh_schema.template)
92
+
93
+ Defined by [Vagrant SSH](http://docs.vagrantup.com/v2/vagrantfile/ssh_settings.html)
94
+
95
+ Example use:
96
+ ```
97
+ ...
98
+ "username": "ubuntu",
99
+ "private_key_path": "PATH_TO_YOUR_PK",
100
+ "shell": "bash -l"
101
+ ...
102
+ ```
103
+
104
+ ######[Tasks](resources/tasks_schema.template)
105
+
106
+ Describes what tasks a VM should run at provisioning step
107
+
6
108
  - type - Type of task payload. 'shell', 'chef_client' or 'chef_solo'
7
- - shell task parameters:
8
- - [shell provisioner]
109
+ - shell task parameters are defined by [Vagrant shell provisioner](http://docs.vagrantup.com/v2/provisioning/shell.html)
9
110
  - chef_client and chef_solo task parameters map directly to Vagrant provisioner docs, **EXCEPT the node_name parameter**:
10
- - [chef_solo provisioner]
11
- - [chef_client provisioner]
12
- - [chef common options]
13
-
14
- [chef_solo provisioner]:http://docs.vagrantup.com/v2/provisioning/chef_solo.html
15
- [chef_client provisioner]:https://docs.vagrantup.com/v2/provisioning/chef_client.html
16
- [chef common options]:http://docs.vagrantup.com/v2/provisioning/chef_common.html
17
- [shell provisioner]:http://docs.vagrantup.com/v2/provisioning/shell.html
111
+ - [chef_solo provisioner](http://docs.vagrantup.com/v2/provisioning/chef_solo.html)
112
+ - [chef_client provisioner](https://docs.vagrantup.com/v2/provisioning/chef_client.html)
113
+ - [chef common options](http://docs.vagrantup.com/v2/provisioning/chef_common.html)
@@ -22,12 +22,13 @@
22
22
  #++
23
23
 
24
24
  require 'zerg'
25
+ require 'rbconfig'
25
26
  require_relative 'renderer'
26
27
 
27
28
  # give this class the name you want for your command zergrush_vagrant
28
29
  class Vagrant < ZergGemPlugin::Plugin "/driver"
29
30
  def rush hive_location, task_name, task_hash, debug
30
- abort("ERROR: Vagrant not installed!") unless which("vagrant") != nil
31
+ check_dependencies
31
32
  puts ("Will perform task #{task_name} with contents:\n #{task_hash.ai}")
32
33
 
33
34
  renderer = Renderer.new(
@@ -38,13 +39,20 @@ class Vagrant < ZergGemPlugin::Plugin "/driver"
38
39
 
39
40
  debug_string = (debug == true) ? " --debug" : ""
40
41
 
42
+ # last explicitly defined driver option set
43
+ last_defined_driveroption = nil
44
+
41
45
  # bring up all of the VMs first.
42
46
  puts("Starting vagrant in #{File.join("#{hive_location}", "driver", task_hash["vm"]["driver"]["drivertype"], task_name)}")
43
- for index in 0..task_hash["instances"] - 1
47
+ for index in 0..task_hash["num_instances"] - 1
48
+
49
+ # grab last defined driver options set, or keep the current one
50
+ last_defined_driveroption = (task_hash["vm"]["driver"]["driveroptions"][index] == nil) ? last_defined_driveroption : task_hash["vm"]["driver"]["driveroptions"][index]
51
+
44
52
  create_pid = Process.spawn(
45
53
  {
46
54
  "VAGRANT_CWD" => File.join("#{hive_location}", "driver", task_hash["vm"]["driver"]["drivertype"], task_name),
47
- "VAGRANT_DEFAULT_PROVIDER" => task_hash["vm"]["driver"]["providertype"]
55
+ "VAGRANT_DEFAULT_PROVIDER" => last_defined_driveroption["providertype"]
48
56
  },
49
57
  "vagrant up zergling_#{index} --no-provision#{debug_string}")
50
58
  Process.wait(create_pid)
@@ -56,15 +64,19 @@ class Vagrant < ZergGemPlugin::Plugin "/driver"
56
64
  end
57
65
  end
58
66
 
67
+ last_defined_driveroption = nil
59
68
  puts("Running tasks in vagrant virtual machines...")
60
69
  # and provision them all at once (sort of)
61
70
  provisioners = Array.new
62
71
  provision_pid = nil
63
- for index in 0..task_hash["instances"] - 1
72
+ for index in 0..task_hash["num_instances"] - 1
73
+ # grab last defined driver options set, or keep the current one
74
+ last_defined_driveroption = (task_hash["vm"]["driver"]["driveroptions"][index] == nil) ? last_defined_driveroption : task_hash["vm"]["driver"]["driveroptions"][index]
75
+
64
76
  provision_pid = Process.spawn(
65
77
  {
66
78
  "VAGRANT_CWD" => File.join("#{hive_location}", "driver", task_hash["vm"]["driver"]["drivertype"], task_name),
67
- "VAGRANT_DEFAULT_PROVIDER" => task_hash["vm"]["driver"]["providertype"]
79
+ "VAGRANT_DEFAULT_PROVIDER" => last_defined_driveroption["providertype"]
68
80
  },
69
81
  "vagrant provision zergling_#{index}#{debug_string}")
70
82
  provisioners.push({:name => "zergling_#{index}", :pid => provision_pid})
@@ -82,17 +94,40 @@ class Vagrant < ZergGemPlugin::Plugin "/driver"
82
94
  }.join
83
95
  }
84
96
 
85
- if task_hash["vm"]["keepalive"] == false
86
- halt(hive_location, task_name, task_hash, debug)
87
- else
88
- puts "Will leave instances running."
89
- end
97
+ # halt only the machines that are not marked as "keepalive"
98
+ last_defined_driveroption = nil
99
+ last_defined_vm = nil
90
100
 
101
+ halt_pid = nil
102
+ keepalive_left = false
103
+ for index in 0..task_hash["num_instances"] - 1
104
+
105
+ # grab last defined driver options set, or keep the current one
106
+ last_defined_driveroption = (task_hash["vm"]["driver"]["driveroptions"][index] == nil) ? last_defined_driveroption : task_hash["vm"]["driver"]["driveroptions"][index]
107
+
108
+ # grab last defined vm instance, or keep the current one
109
+ last_defined_vm = (task_hash["vm"]["instances"][index] == nil) ? last_defined_vm : task_hash["vm"]["instances"][index]
110
+
111
+ if last_defined_vm["keepalive"] != true
112
+ halt_pid = Process.spawn(
113
+ {
114
+ "VAGRANT_CWD" => File.join("#{hive_location}", "driver", task_hash["vm"]["driver"]["drivertype"], task_name),
115
+ "VAGRANT_DEFAULT_PROVIDER" => last_defined_driveroption["providertype"]
116
+ },
117
+ "vagrant halt zergling_#{index}#{debug_string}")
118
+ Process.wait(halt_pid)
119
+ abort("ERROR: vagrant halt failed on machine zergling_#{index}!") unless $?.exitstatus == 0
120
+ else
121
+ keepalive_left = true
122
+ puts "zergling_#{index} is marked as keepalive, skipping halt..."
123
+ end
124
+ end
91
125
  abort("ERROR: Finished with errors in: #{errors.to_s}") unless errors.length == 0
126
+ puts "Some instances were left running." unless keepalive_left == false
92
127
  end
93
128
 
94
129
  def clean hive_location, task_name, task_hash, debug
95
- abort("ERROR: Vagrant not installed!") unless which("vagrant") != nil
130
+ check_dependencies
96
131
  puts("Cleaning task #{task_name} ...")
97
132
 
98
133
  renderer = Renderer.new(
@@ -104,27 +139,47 @@ class Vagrant < ZergGemPlugin::Plugin "/driver"
104
139
  # run vagrant cleanup
105
140
  debug_string = (debug == true) ? " --debug" : ""
106
141
 
107
- for index in 0..task_hash["instances"] - 1
142
+ last_defined_driveroption = nil
143
+
144
+ for index in 0..task_hash["num_instances"] - 1
145
+
146
+ # grab last defined driver options set, or keep the current one
147
+ last_defined_driveroption = (task_hash["vm"]["driver"]["driveroptions"][index] == nil) ? last_defined_driveroption : task_hash["vm"]["driver"]["driveroptions"][index]
148
+
108
149
  cleanup_pid = Process.spawn(
109
150
  {
110
151
  "VAGRANT_CWD" => File.join("#{hive_location}", "driver", task_hash["vm"]["driver"]["drivertype"], task_name),
111
- "VAGRANT_DEFAULT_PROVIDER" => task_hash["vm"]["driver"]["providertype"]
152
+ "VAGRANT_DEFAULT_PROVIDER" => last_defined_driveroption["providertype"]
112
153
  },
113
154
  "vagrant destroy zergling_#{index} --force#{debug_string}")
114
155
  Process.wait(cleanup_pid)
115
156
  abort("ERROR: vagrant failed!") unless $?.exitstatus == 0
116
157
  end
117
158
 
118
- cleanup_pid = Process.spawn(
119
- {
120
- "VAGRANT_CWD" => File.join("#{hive_location}", "driver", task_hash["vm"]["driver"]["drivertype"], task_name)
121
- },
122
- "vagrant box remove zergling_#{task_name}_#{task_hash["vm"]["driver"]["providertype"]}#{debug_string} #{task_hash["vm"]["driver"]["providertype"]}")
123
- Process.wait(cleanup_pid)
159
+ last_defined_driveroption = nil
160
+
161
+ # last explicitly defined vm instance.
162
+ last_defined_vm = nil
163
+
164
+ for index in 0..task_hash["num_instances"] - 1
165
+ # grab last defined driver options set, or keep the current one
166
+ last_defined_driveroption = (task_hash["vm"]["driver"]["driveroptions"][index] == nil) ? last_defined_driveroption : task_hash["vm"]["driver"]["driveroptions"][index]
167
+
168
+ # grab last defined vm instance, or keep the current one
169
+ last_defined_vm = (task_hash["vm"]["instances"][index] == nil) ? last_defined_vm : task_hash["vm"]["instances"][index]
170
+
171
+ boxname = Digest::SHA1.hexdigest "#{task_name}#{last_defined_driveroption["providertype"]}#{last_defined_vm["basebox"]}"
172
+ cleanup_pid = Process.spawn(
173
+ {
174
+ "VAGRANT_CWD" => File.join("#{hive_location}", "driver", task_hash["vm"]["driver"]["drivertype"], task_name)
175
+ },
176
+ "vagrant box remove #{boxname} #{last_defined_driveroption["providertype"]}#{debug_string}")
177
+ Process.wait(cleanup_pid)
178
+ end
124
179
  end
125
180
 
126
181
  def halt hive_location, task_name, task_hash, debug
127
- abort("ERROR: Vagrant not installed!") unless which("vagrant") != nil
182
+ check_dependencies
128
183
  puts("Halting all vagrant virtual machines for task #{task_name} ...")
129
184
 
130
185
  renderer = Renderer.new(
@@ -137,11 +192,18 @@ class Vagrant < ZergGemPlugin::Plugin "/driver"
137
192
 
138
193
  # halt all machines
139
194
  halt_pid = nil
140
- for index in 0..task_hash["instances"] - 1
195
+
196
+ last_defined_driveroption = nil
197
+
198
+ for index in 0..task_hash["num_instances"] - 1
199
+
200
+ # grab last defined driver options set, or keep the current one
201
+ last_defined_driveroption = (task_hash["vm"]["driver"]["driveroptions"][index] == nil) ? last_defined_driveroption : task_hash["vm"]["driver"]["driveroptions"][index]
202
+
141
203
  halt_pid = Process.spawn(
142
204
  {
143
205
  "VAGRANT_CWD" => File.join("#{hive_location}", "driver", task_hash["vm"]["driver"]["drivertype"], task_name),
144
- "VAGRANT_DEFAULT_PROVIDER" => task_hash["vm"]["driver"]["providertype"]
206
+ "VAGRANT_DEFAULT_PROVIDER" => last_defined_driveroption["providertype"]
145
207
  },
146
208
  "vagrant halt zergling_#{index}#{debug_string}")
147
209
  Process.wait(halt_pid)
@@ -153,6 +215,22 @@ class Vagrant < ZergGemPlugin::Plugin "/driver"
153
215
  return File.open(File.join("#{File.dirname(__FILE__)}", "..", "..", "resources", "tasks_schema.template"), 'r').read
154
216
  end
155
217
 
218
+ def option_schema
219
+ return File.open(File.join("#{File.dirname(__FILE__)}", "..", "..", "resources", "option_schema.template"), 'r').read
220
+ end
221
+
222
+ def folder_schema
223
+ return File.open(File.join("#{File.dirname(__FILE__)}", "..", "..", "resources", "folders_schema.template"), 'r').read
224
+ end
225
+
226
+ def port_schema
227
+ return File.open(File.join("#{File.dirname(__FILE__)}", "..", "..", "resources", "ports_schema.template"), 'r').read
228
+ end
229
+
230
+ def ssh_schema
231
+ return File.open(File.join("#{File.dirname(__FILE__)}", "..", "..", "resources", "ssh_schema.template"), 'r').read
232
+ end
233
+
156
234
  def which(cmd)
157
235
  exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
158
236
  ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
@@ -163,5 +241,25 @@ class Vagrant < ZergGemPlugin::Plugin "/driver"
163
241
  end
164
242
  return nil
165
243
  end
244
+
245
+ def check_dependencies
246
+ abort("ERROR: Vagrant not installed!") unless which("vagrant") != nil
247
+ required_plugins = ["vagrant-aws", "vagrant-omnibus", "vagrant-berkshelf"]
248
+ if /linux|arch/i === RbConfig::CONFIG['host_os']
249
+ required_plugins.push("vagrant-libvirt")
250
+ end
251
+
252
+ required_plugins.each { |plugin|
253
+ plugin_check_pid = Process.spawn("vagrant plugin list | grep #{plugin}")
254
+ Process.wait(plugin_check_pid)
255
+
256
+ if $?.exitstatus != 0
257
+ puts "Installing #{plugin}"
258
+ plugin_check_pid = Process.spawn("vagrant plugin install #{plugin}")
259
+ Process.wait(plugin_check_pid)
260
+ abort("ERROR: #{plugin} installation failed!") unless $?.exitstatus == 0
261
+ end
262
+ }
263
+ end
166
264
  end
167
265
 
@@ -24,24 +24,18 @@
24
24
  require 'awesome_print'
25
25
  require 'fileutils'
26
26
  require 'securerandom'
27
+ require 'ipaddress'
28
+ require 'digest/sha1'
29
+ require 'ipaddress'
27
30
  require_relative 'erbalize'
28
31
 
29
32
  class Renderer
30
33
 
31
- # generate a virtualbox - compatible MAC address
32
- def generateMACAddress()
33
- firstChar = (0..255).map(&:chr).select{|x| x =~ /[0-9A-Fa-f]/}.sample(1).join
34
- secondChar = (0..255).map(&:chr).select{|x| x =~ /[02468ACEace]/}.sample(1).join
35
- restOfChars = (0..255).map(&:chr).select{|x| x =~ /[0-9A-Fa-f]/}.sample(10).join
36
- return "#{firstChar}#{secondChar}#{restOfChars}"
37
- end
38
-
39
34
  def initialize(hive_location, task_name, task_hash)
40
35
  @vm = task_hash["vm"]
41
36
  @name = task_name
42
- @instances = task_hash["instances"]
43
- @tasks = task_hash["tasks"]
44
- @synced_folders = task_hash["synced_folders"]
37
+ @num_instances = task_hash["num_instances"]
38
+ @vm_instances = task_hash["vm"]["instances"]
45
39
  @hive_location = hive_location
46
40
  end
47
41
 
@@ -57,103 +51,220 @@ class Renderer
57
51
  # load the machine details template
58
52
  machine_template = File.open(File.join("#{File.dirname(__FILE__)}", "..", "..", "resources", "machine.template"), 'r').read
59
53
 
60
- # load the bridge details template
61
- bridge_template = File.open(File.join("#{File.dirname(__FILE__)}", "..", "..", "resources", "bridging.template"), 'r').read
62
-
63
- # load the host only network details template
64
- hostonly_template = File.open(File.join("#{File.dirname(__FILE__)}", "..", "..", "resources", "hostonly.template"), 'r').read
65
54
 
66
55
  # render templates....
67
- # render provider details to string
68
- #
69
- # render provider details into a string
70
- provider_details_array = @vm["driver"]["provider_options"]
71
- provider_details = ""
72
- for index in 0..provider_details_array.length - 1
73
- provider_details += "\t\t" + provider_details_array[index] + "\n"
56
+
57
+ # all machines
58
+ all_machines = ""
59
+
60
+ # JSON - defined range of ip addresses in CIDR format
61
+ ip_range = (@vm.has_key?("private_ip_range")) ? IPAddress(@vm["private_ip_range"]).hosts : nil
62
+ if ip_range != nil
63
+ abort("ERROR: ip range (#{@vm["private_ip_range"]}) does not have enough ip addresses for all instances.") unless ip_range.length > @num_instances
74
64
  end
75
65
 
76
- # render provider parent
77
- sources = {
78
- :provider => @vm["driver"]["providertype"],
79
- :provider_specifics => provider_details
80
- }
81
- provider_parent_string = Erbalize.erbalize_hash(provider_parent_template, sources)
66
+ # last explicitly defined vm instance.
67
+ last_defined_vm = nil
82
68
 
83
- # render machine template
84
- all_macs = Array.new
85
- all_machines = ""
86
- for index in 0..@instances - 1
69
+ # last explicitly defined driver option set
70
+ last_defined_driveroption = nil
87
71
 
88
- # last ip octet offset for host only networking
89
- ip_octet_offset = index
72
+ # render a machine section for each instance.
73
+ # each machine gets an explicitly defined instance
74
+ # if there is no explicitly defined instance - last known explicitly defined instance information is used.
75
+ # For example: if num_instances = 3 and there are 2 vm instances defined, then machine_0 gets instance definition 0, machine_1 gets instance
76
+ # definition 1, machine_2 gets instance definition 2
77
+ for index in 0..@num_instances - 1
90
78
 
91
- # inject randomized node_name into chef_client tasks
92
- @tasks.each { |task|
93
- if task["type"] == "chef_client"
94
- task["node_name"] = "zergling_#{index}_#{SecureRandom.hex(20)}"
79
+ # grab last defined vm instance, or keep the current one
80
+ last_defined_vm = (@vm_instances[index] == nil) ? last_defined_vm : @vm_instances[index]
81
+
82
+ # grab last defined driver options set, or keep the current one
83
+ last_defined_driveroption = (@vm["driver"]["driveroptions"][index] == nil) ? last_defined_driveroption : @vm["driver"]["driveroptions"][index]
84
+
85
+ # provider type
86
+ provider = last_defined_driveroption["providertype"]
87
+
88
+ # unique name
89
+ unique_name = "zergling_#{index}_#{SecureRandom.hex(20)}"
90
+
91
+ # render provider details to string
92
+ provider_specifics = ""
93
+
94
+ if provider == "aws"
95
+ # inject private ip for aws provider (if not specified explicitly and if ip range is provided)
96
+ if last_defined_driveroption.has_key?("provider_options")
97
+ if last_defined_driveroption["provider_options"].has_key?("subnet_id")
98
+ if !last_defined_driveroption["provider_options"].has_key?("private_ip_address")
99
+ if ip_range != nil
100
+ provider_specifics += "\t\t\t#{provider}.private_ip_address = #{ip_range[index]}"
101
+ end
102
+ end
103
+ end
95
104
  end
96
- }
97
105
 
98
- # tasks array rendered to ruby string. double encoding to escape quotes and allow for variable expansion
99
- tasks_array = @tasks.to_json.to_json
100
-
101
- # do we need the bridging template as well?
102
- bridge_section = nil
103
- if @vm.has_key?("bridge_description")
104
- # mac address to use?
105
- new_mac = ""
106
- begin
107
- new_mac = generateMACAddress()
108
- end while all_macs.include? new_mac
109
-
110
- sources = {
111
- :machine_mac => new_mac,
112
- :bridged_eth_description => @vm["bridge_description"]
106
+ # inject name tag
107
+ if last_defined_driveroption.has_key?("provider_options")
108
+ if last_defined_driveroption["provider_options"].has_key?("tags")
109
+ if !last_defined_driveroption["provider_options"]["tags"].has_key?("Name")
110
+ last_defined_driveroption["provider_options"]["tags"]["Name"] = unique_name
111
+ end
112
+ else
113
+ last_defined_driveroption["provider_options"]["tags"] = { "Name" => unique_name }
114
+ end
115
+ end
116
+
117
+ end
118
+
119
+ if last_defined_driveroption.has_key?("provider_options")
120
+ provider_options = last_defined_driveroption["provider_options"]
121
+
122
+ provider_options.each do |key, value|
123
+ if value.is_a?(String)
124
+ provider_specifics += "\t\t\t#{provider}.#{key} = \"#{value}\"\n"
125
+ elsif value.is_a?(Array)
126
+ provider_specifics += "\t\t\t#{provider}.#{key} = #{value.to_json}\n"
127
+ else
128
+ provider_specifics += "\t\t\t#{provider}.#{key} = #{value}\n"
129
+ end
130
+ end
131
+ end
132
+
133
+ if last_defined_driveroption.has_key?("raw_options")
134
+ raw_provider_options = last_defined_driveroption["raw_options"]
135
+ raw_provider_options.each { |raw_option|
136
+ provider_specifics += "\t\t\t#{raw_option}\n"
137
+ }
138
+ end
139
+
140
+ # render networks
141
+ network_specifics = ""
142
+ if last_defined_vm.has_key?("networks")
143
+ last_defined_vm["networks"].each { |network|
144
+ network_specifics += "\t\tzergling_#{index}.vm.network \"#{network["type"]}\""
145
+ if network.has_key?("bridge")
146
+ network_specifics += ", bridge: \"#{network["bridge"]}\""
147
+ end
148
+ if network.has_key?("ip")
149
+ network_specifics += ", ip: \"#{network["ip"]}\""
150
+ elsif ip_range != nil && network["type"] != "public_network"
151
+ # first host IP is the host machine
152
+ network_specifics += ", ip: \"#{ip_range[index + 1]}\""
153
+ end
154
+
155
+ if network.has_key?("additional")
156
+ network["additional"].each do |key, value|
157
+ if value.is_a?(String)
158
+ network_specifics += ", #{key}: \"#{value}\""
159
+ else
160
+ network_specifics += ", #{key}: #{value}"
161
+ end
162
+ end
163
+ end
164
+ network_specifics += "\n"
113
165
  }
114
- bridge_section = Erbalize.erbalize_hash(bridge_template, sources)
115
166
  end
116
167
 
117
- # do we need the host only template as well?
118
- hostonly_section = nil
119
- if @vm["private_network"] == true
120
- sources = {
121
- :machine_name => "zergling_#{index}",
122
- :last_octet => ip_octet_offset + 4, # TODO: this is probably specific to virtualbox networking
168
+ # render sync folders
169
+ folder_specifics = ""
170
+ if last_defined_vm.has_key?("synced_folders")
171
+ last_defined_vm["synced_folders"].each { |folder|
172
+ folder_specifics += "\t\tzergling_#{index}.vm.synced_folder \"#{folder["host_path"]}\", \"#{folder["guest_path"]}\""
173
+ if folder.has_key?("additional")
174
+ folder["additional"].each do |key, value|
175
+ if value.is_a?(String)
176
+ folder_specifics += ", #{key}: \"#{value}\""
177
+ else
178
+ folder_specifics += ", #{key}: #{value}"
179
+ end
180
+ end
181
+ end
182
+ folder_specifics += "\n"
123
183
  }
124
- hostonly_section = Erbalize.erbalize_hash(hostonly_template, sources)
125
184
  end
126
185
 
127
- # synced folders
128
- folder_definitions = nil
129
- if @synced_folders != nil
130
- folder_definitions = ""
131
- @synced_folders.each { |folder|
132
- other_options = ""
133
- if folder.has_key?("options")
134
- folder["options"].each { |option|
186
+ # render forwarded ports
187
+ port_specifics = ""
188
+ if last_defined_vm.has_key?("forwarded_ports")
189
+ last_defined_vm["forwarded_ports"].each { |port|
190
+ port_specifics += "\t\tzergling_#{index}.vm.network \"forwarded_port\", guest: #{port["guest_port"]}, host: #{port["host_port"]}"
191
+ if port.has_key?("additional")
192
+ port["additional"].each { |option|
135
193
  option.each do |key, value|
136
194
  if value.is_a?(String)
137
- other_options += ", :#{key} => \"#{value}\""
195
+ port_specifics += ", #{key}: \"#{value}\""
138
196
  else
139
- other_options += ", :#{key} => #{value}"
197
+ port_specifics += ", #{key}: #{value}"
140
198
  end
141
199
  end
142
200
  }
143
201
  end
144
-
145
- folder_definition = "zergling_#{index}.vm.synced_folder \"#{folder['host_path']}\", \"#{folder['guest_path']}\""
146
- folder_definition = "#{folder_definition}#{other_options}" unless other_options.empty?()
147
- folder_definitions += "\t\t#{folder_definition}\n"
202
+ port_specifics += "\n"
148
203
  }
149
204
  end
150
205
 
206
+ # render ssh settings
207
+ ssh_specifics = ""
208
+ if last_defined_vm.has_key?("ssh")
209
+ if last_defined_vm["ssh"].has_key?("username")
210
+ ssh_specifics += "\t\tzergling_#{index}.ssh.username = \"#{last_defined_vm["ssh"]["username"]}\"\n"
211
+ end
212
+
213
+ if last_defined_vm["ssh"].has_key?("host")
214
+ ssh_specifics += "\t\tzergling_#{index}.ssh.host = \"#{last_defined_vm["ssh"]["host"]}\"\n"
215
+ end
216
+
217
+ if last_defined_vm["ssh"].has_key?("port")
218
+ ssh_specifics += "\t\tzergling_#{index}.ssh.port = #{last_defined_vm["ssh"]["port"]}\n"
219
+ end
220
+
221
+ if last_defined_vm["ssh"].has_key?("guest_port")
222
+ ssh_specifics += "\t\tzergling_#{index}.ssh.guest_port = #{last_defined_vm["ssh"]["guest_port"]}\n"
223
+ end
224
+
225
+ if last_defined_vm["ssh"].has_key?("private_key_path")
226
+ ssh_specifics += "\t\tzergling_#{index}.ssh.private_key_path = \"#{last_defined_vm["ssh"]["private_key_path"]}\"\n"
227
+ end
228
+
229
+ if last_defined_vm["ssh"].has_key?("forward_agent")
230
+ ssh_specifics += "\t\tzergling_#{index}.ssh.forward_agent = #{last_defined_vm["ssh"]["forward_agent"]}\n"
231
+ end
232
+
233
+ if last_defined_vm["ssh"].has_key?("additional")
234
+ last_defined_vm["ssh"]["additional"].each { |option|
235
+ option.each do |key, value|
236
+ if value.is_a?(String)
237
+ ssh_specifics += "\t\tzergling_#{index}.ssh.#{key} = \"#{value}\"\n"
238
+ else
239
+ ssh_specifics += "\t\tzergling_#{index}.ssh.#{key} = #{value}\n"
240
+ end
241
+ end
242
+ }
243
+ end
244
+ end
245
+
246
+ # render tasks array
247
+ # inject randomized node_name into chef_client tasks
248
+ last_defined_vm["tasks"].each { |task|
249
+ if task["type"] == "chef_client"
250
+ task["node_name"] = unique_name
251
+ end
252
+ }
253
+
254
+ # tasks array rendered to ruby string. double encoding to escape quotes and allow for variable expansion
255
+ tasks_array = last_defined_vm["tasks"].to_json.to_json
256
+
151
257
  sources = {
152
258
  :machine_name => "zergling_#{index}",
153
- :bridge_specifics => bridge_section,
154
- :hostonly_specifics => hostonly_section,
155
- :tasks_array => tasks_array,
156
- :sync_folders_array => folder_definitions
259
+ :basebox_path => last_defined_vm["basebox"],
260
+ :box_name => Digest::SHA1.hexdigest("#{@name}#{provider}#{last_defined_vm["basebox"]}"),
261
+ :provider => provider,
262
+ :provider_specifics => provider_specifics,
263
+ :networks_array => network_specifics,
264
+ :sync_folders_array => folder_specifics,
265
+ :ports_array => port_specifics,
266
+ :ssh_specifics => ssh_specifics,
267
+ :tasks_array => tasks_array
157
268
  }.delete_if { |k, v| v.nil? }
158
269
 
159
270
  machine_section = Erbalize.erbalize_hash(machine_template, sources)
@@ -161,9 +272,6 @@ class Renderer
161
272
  end
162
273
 
163
274
  sources = {
164
- :provider_section => provider_parent_string,
165
- :basebox_path => @vm["basebox"],
166
- :box_name => "zergling_#{@name}_#{@vm["driver"]["providertype"]}",
167
275
  :vm_defines => all_machines
168
276
  }
169
277
  full_template = Erbalize.erbalize_hash(main_template, sources)
@@ -22,5 +22,5 @@
22
22
  #++
23
23
 
24
24
  module ZergrushVagrant
25
- VERSION = "0.0.1"
25
+ VERSION = "0.0.2"
26
26
  end
@@ -0,0 +1,18 @@
1
+ "create": {
2
+ "type": "boolean"
3
+ },
4
+ "disabled": {
5
+ "type": "boolean"
6
+ },
7
+ "group": {
8
+ "type": "string"
9
+ },
10
+ "mount_options": {
11
+ "type": "array"
12
+ },
13
+ "owner": {
14
+ "type": "string"
15
+ },
16
+ "type": {
17
+ "type": "string"
18
+ }
@@ -1,8 +1,17 @@
1
1
  # define the machine name
2
2
  config.vm.define "<%= machine_name %>" do |<%= machine_name %>|
3
- <%= bridge_specifics -%>
4
- <%= hostonly_specifics %>
3
+ <%= machine_name %>.vm.box_url = "<%= basebox_path %>"
4
+ <%= machine_name %>.vm.box = "<%= box_name %>"
5
+
6
+ <%= ssh_specifics -%>
7
+
8
+ <%= machine_name %>.vm.provider :<%= provider %> do |<%= provider %>|
9
+ <%= provider_specifics -%>
10
+ end
11
+
12
+ <%= networks_array -%>
5
13
  <%= sync_folders_array -%>
14
+ <%= ports_array -%>
6
15
 
7
16
  # provisioning
8
17
  tasks = JSON.parse(<%= tasks_array %>)
@@ -1,9 +1,5 @@
1
1
  Vagrant.configure(2) do |config|
2
- <%= provider_section %>
3
-
4
2
  config.vagrant.host = :detect
5
- config.vm.box_url = "<%= basebox_path %>"
6
- config.vm.box = "<%= box_name %>"
7
3
  config.vm.boot_timeout = 300
8
4
  config.vm.graceful_halt_timeout = 60
9
5
  <%= vm_defines -%>
@@ -0,0 +1,12 @@
1
+ "type": {
2
+ "type": "string"
3
+ },
4
+ "bridge": {
5
+ "type": "string"
6
+ },
7
+ "ip": {
8
+ "type": "string"
9
+ },
10
+ "additonal": {
11
+ "type": "object"
12
+ }
@@ -0,0 +1,9 @@
1
+ "providertype": {
2
+ "type": "string"
3
+ },
4
+ "provider_options": {
5
+ "type": "object"
6
+ },
7
+ "raw_options": {
8
+ "type": "array"
9
+ }
@@ -0,0 +1,12 @@
1
+ "guest_ip": {
2
+ "type": "string"
3
+ },
4
+ "host_ip": {
5
+ "type": "string"
6
+ },
7
+ "protocol": {
8
+ "type": "string"
9
+ },
10
+ "autocorrect": {
11
+ "type": "boolean"
12
+ }
@@ -0,0 +1,6 @@
1
+ "forward_x11": {
2
+ "type": "boolean"
3
+ },
4
+ "shell": {
5
+ "type": "string"
6
+ }
@@ -1,174 +1,172 @@
1
- "properties": {
2
- "type": {
3
- "type": "string",
4
- "pattern": "^(shell|chef_client|chef_solo)$"
5
- },
6
- "inline": {
7
- "type": "string"
8
- },
9
- "path": {
10
- "type": "string"
11
- },
12
- "parameters": {
13
- "type": "string"
14
- },
15
- "environment": {
16
- "type": "string"
17
- },
18
- "upload_path": {
19
- "type": "string"
20
- },
21
- "recipe_url": {
22
- "type": "string"
23
- },
24
- "client_key_path": {
25
- "type": "string"
26
- },
27
- "validation_client_name": {
28
- "type": "string"
29
- },
30
- "arguments": {
31
- "type": "string"
32
- },
33
- "chef_server_url": {
34
- "type": "string"
35
- },
36
- "validation_key_path": {
37
- "type": "string"
38
- },
39
- "encrypted_data_bag_secret_key_path": {
40
- "type": "string"
41
- },
42
- "binary_path": {
43
- "type": "string"
44
- },
45
- "custom_config_path": {
46
- "type": "string"
47
- },
48
- "formatter": {
49
- "type": "string"
50
- },
51
- "http_proxy": {
52
- "type": "string"
53
- },
54
- "http_proxy_user": {
55
- "type": "string"
56
- },
57
- "http_proxy_pass": {
58
- "type": "string"
59
- },
60
- "no_proxy": {
61
- "type": "string"
62
- },
63
- "https_proxy": {
64
- "type": "string"
65
- },
66
- "https_proxy_user": {
67
- "type": "string"
68
- },
69
- "https_proxy_pass": {
70
- "type": "string"
71
- },
72
- "log_level": {
73
- "type": "string"
74
- },
75
- "provisioning_path": {
76
- "type": "string"
77
- },
78
- "file_cache_path": {
79
- "type": "string"
80
- },
81
- "file_backup_path": {
82
- "type": "string"
83
- },
84
- "verbose_logging": {
85
- "type": "boolean"
86
- },
87
- "delete_node": {
88
- "type": "boolean"
89
- },
90
- "delete_client": {
91
- "type": "boolean"
92
- },
93
- "nfs": {
94
- "type": "boolean"
95
- },
96
- "binary": {
97
- "type": "boolean"
98
- },
99
- "keep_color": {
100
- "type": "boolean"
101
- },
102
- "priveleged": {
103
- "type": "boolean"
104
- },
105
- "attempts": {
106
- "type": "integer"
107
- },
108
- "json": {
109
- "type": "object"
110
- },
111
- "cookbooks_path": {
112
- "type": "array",
113
- "minItems": 1,
114
- "items": [
115
- {
116
- "type": "string"
117
- }
118
- ]
119
- },
120
- "args": {
121
- "type": "array",
122
- "minItems": 1,
123
- "items": [
124
- {
125
- "type": "string"
126
- }
127
- ]
128
- },
129
- "roles_path": {
130
- "type": "array",
131
- "minItems": 1,
132
- "items": [
133
- {
134
- "type": "string"
135
- }
136
- ]
137
- },
138
- "data_bags_path": {
139
- "type": "array",
140
- "minItems": 1,
141
- "items": [
142
- {
143
- "type": "string"
144
- }
145
- ]
146
- },
147
- "environments_path": {
148
- "type": "array",
149
- "minItems": 1,
150
- "items": [
151
- {
152
- "type": "string"
153
- }
154
- ]
155
- },
156
- "run_list": {
157
- "type": "array",
158
- "minItems": 1,
159
- "items": [
160
- {
161
- "type": "string"
162
- }
163
- ]
164
- },
165
- "roles": {
166
- "type": "array",
167
- "minItems": 1,
168
- "items": [
169
- {
170
- "type": "string"
171
- }
172
- ]
173
- }
174
- }
1
+ "type": {
2
+ "type": "string",
3
+ "pattern": "^(shell|chef_client|chef_solo)$"
4
+ },
5
+ "inline": {
6
+ "type": "string"
7
+ },
8
+ "path": {
9
+ "type": "string"
10
+ },
11
+ "parameters": {
12
+ "type": "string"
13
+ },
14
+ "environment": {
15
+ "type": "string"
16
+ },
17
+ "upload_path": {
18
+ "type": "string"
19
+ },
20
+ "recipe_url": {
21
+ "type": "string"
22
+ },
23
+ "client_key_path": {
24
+ "type": "string"
25
+ },
26
+ "validation_client_name": {
27
+ "type": "string"
28
+ },
29
+ "arguments": {
30
+ "type": "string"
31
+ },
32
+ "chef_server_url": {
33
+ "type": "string"
34
+ },
35
+ "validation_key_path": {
36
+ "type": "string"
37
+ },
38
+ "encrypted_data_bag_secret_key_path": {
39
+ "type": "string"
40
+ },
41
+ "binary_path": {
42
+ "type": "string"
43
+ },
44
+ "custom_config_path": {
45
+ "type": "string"
46
+ },
47
+ "formatter": {
48
+ "type": "string"
49
+ },
50
+ "http_proxy": {
51
+ "type": "string"
52
+ },
53
+ "http_proxy_user": {
54
+ "type": "string"
55
+ },
56
+ "http_proxy_pass": {
57
+ "type": "string"
58
+ },
59
+ "no_proxy": {
60
+ "type": "string"
61
+ },
62
+ "https_proxy": {
63
+ "type": "string"
64
+ },
65
+ "https_proxy_user": {
66
+ "type": "string"
67
+ },
68
+ "https_proxy_pass": {
69
+ "type": "string"
70
+ },
71
+ "log_level": {
72
+ "type": "string"
73
+ },
74
+ "provisioning_path": {
75
+ "type": "string"
76
+ },
77
+ "file_cache_path": {
78
+ "type": "string"
79
+ },
80
+ "file_backup_path": {
81
+ "type": "string"
82
+ },
83
+ "verbose_logging": {
84
+ "type": "boolean"
85
+ },
86
+ "delete_node": {
87
+ "type": "boolean"
88
+ },
89
+ "delete_client": {
90
+ "type": "boolean"
91
+ },
92
+ "nfs": {
93
+ "type": "boolean"
94
+ },
95
+ "binary": {
96
+ "type": "boolean"
97
+ },
98
+ "keep_color": {
99
+ "type": "boolean"
100
+ },
101
+ "priveleged": {
102
+ "type": "boolean"
103
+ },
104
+ "attempts": {
105
+ "type": "integer"
106
+ },
107
+ "json": {
108
+ "type": "object"
109
+ },
110
+ "cookbooks_path": {
111
+ "type": "array",
112
+ "minItems": 1,
113
+ "items": [
114
+ {
115
+ "type": "string"
116
+ }
117
+ ]
118
+ },
119
+ "args": {
120
+ "type": "array",
121
+ "minItems": 1,
122
+ "items": [
123
+ {
124
+ "type": "string"
125
+ }
126
+ ]
127
+ },
128
+ "roles_path": {
129
+ "type": "array",
130
+ "minItems": 1,
131
+ "items": [
132
+ {
133
+ "type": "string"
134
+ }
135
+ ]
136
+ },
137
+ "data_bags_path": {
138
+ "type": "array",
139
+ "minItems": 1,
140
+ "items": [
141
+ {
142
+ "type": "string"
143
+ }
144
+ ]
145
+ },
146
+ "environments_path": {
147
+ "type": "array",
148
+ "minItems": 1,
149
+ "items": [
150
+ {
151
+ "type": "string"
152
+ }
153
+ ]
154
+ },
155
+ "run_list": {
156
+ "type": "array",
157
+ "minItems": 1,
158
+ "items": [
159
+ {
160
+ "type": "string"
161
+ }
162
+ ]
163
+ },
164
+ "roles": {
165
+ "type": "array",
166
+ "minItems": 1,
167
+ "items": [
168
+ {
169
+ "type": "string"
170
+ }
171
+ ]
172
+ }
@@ -19,9 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.add_development_dependency "rake"
20
20
  s.add_development_dependency "zergrush"
21
21
 
22
- s.add_dependency "vagrant-omnibus"
23
- s.add_dependency "vagrant-aws"
24
- s.add_dependency "vagrant-libvirt"
22
+ s.add_dependency "ipaddress"
25
23
 
26
24
  s.files = `git ls-files`.split("\n")
27
25
  s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zergrush_vagrant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - MTN Satellite Communications
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-20 00:00:00.000000000 Z
11
+ date: 2014-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,35 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: vagrant-omnibus
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - '>='
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: vagrant-aws
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - '>='
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - '>='
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: vagrant-libvirt
56
+ name: ipaddress
85
57
  requirement: !ruby/object:Gem::Requirement
86
58
  requirements:
87
59
  - - '>='
@@ -110,12 +82,15 @@ files:
110
82
  - lib/zergrush_vagrant/init.rb
111
83
  - lib/zergrush_vagrant/renderer.rb
112
84
  - lib/zergrush_vagrant/version.rb
113
- - resources/bridging.template
114
85
  - resources/defaults.yaml
115
- - resources/hostonly.template
86
+ - resources/folders_schema.template
116
87
  - resources/machine.template
117
88
  - resources/main.template
89
+ - resources/networks_schema.template
90
+ - resources/option_schema.template
91
+ - resources/ports_schema.template
118
92
  - resources/provider.template
93
+ - resources/ssh_schema.template
119
94
  - resources/tasks_schema.template
120
95
  - zergrush_vagrant.gemspec
121
96
  homepage: https://github.com/MTNSatelliteComm/zerg
@@ -1 +0,0 @@
1
- <%= machine_name %>.vm.network :public_network, :bridge => "<%= bridged_eth_description %>", :mac => <%= machine_mac %>, :use_dhcp_assigned_default_route => true
@@ -1 +0,0 @@
1
- <%= machine_name %>.vm.network :private_network, ip: "192.168.50.<%= last_octet %>"