zergrush_vagrant 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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 %>"