pauper 0.0.4
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.
- data/README +12 -0
- data/bin/pauper +55 -0
- data/lib/client.rb.erb +7 -0
- data/lib/dhcpd.rb +84 -0
- data/lib/hosts.rb +61 -0
- data/lib/pauper.rb +385 -0
- data/lib/vmx.rb +24 -0
- metadata +116 -0
data/README
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
To make a new base VM:
|
2
|
+
|
3
|
+
1) Install your OS (only tested with Ubuntu 10.04 64-bit)
|
4
|
+
2) Setup a user with a password that you don't mind hardcoding in your Pauperfile
|
5
|
+
3) Make sure that user has no-password sudo access
|
6
|
+
4) sudo apt-get install ruby1.8 ruby1.8-dev libopenssl-ruby rubygems ssh
|
7
|
+
5) sudo gem install chef
|
8
|
+
6) Delete /etc/udev/rules.d/70-persistent-net.whatever
|
9
|
+
7) Shut down VM
|
10
|
+
8) Remove all *.lck files from inside the VM's vmwarevm folder
|
11
|
+
|
12
|
+
DONE!
|
data/bin/pauper
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'thor'
|
5
|
+
require 'pauper'
|
6
|
+
|
7
|
+
class CLI < Thor
|
8
|
+
desc "destroy [NODENAME]", "Completely destroy a VM"
|
9
|
+
def destroy(node_name=nil)
|
10
|
+
pauper = Pauper.new
|
11
|
+
if node_name
|
12
|
+
pauper.destroy(node_name)
|
13
|
+
else
|
14
|
+
pauper.destroy_all
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "start [NODENAME]", "Start a VM"
|
19
|
+
def start(node_name=nil)
|
20
|
+
pauper = Pauper.new
|
21
|
+
if node_name
|
22
|
+
pauper.start(node_name)
|
23
|
+
else
|
24
|
+
pauper.start_all
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "stop [NODENAME]", "Stop a VM"
|
29
|
+
def stop(node_name=nil)
|
30
|
+
pauper = Pauper.new
|
31
|
+
if node_name
|
32
|
+
pauper.stop(node_name)
|
33
|
+
else
|
34
|
+
pauper.stop_all
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "setup [NODENAME]", "Refresh configs and run Chef on a VM"
|
39
|
+
def setup(node_name=nil)
|
40
|
+
pauper = Pauper.new
|
41
|
+
if node_name
|
42
|
+
pauper.setup(node_name)
|
43
|
+
else
|
44
|
+
pauper.setup_all
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
desc 'write_hosts', 'Write out a new /etc/hosts file'
|
49
|
+
def write_hosts
|
50
|
+
pauper = Pauper.new
|
51
|
+
pauper.write_hosts
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
CLI.start
|
data/lib/client.rb.erb
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
# Managed by Pauper
|
2
|
+
|
3
|
+
node_name "<%= node_config.name %>"
|
4
|
+
chef_server_url "<%= config[:chef_server_url] %>"
|
5
|
+
validation_client_name "<%= config[:validation_client_name] %>"
|
6
|
+
environment "<%= config[:chef_environment] %>"
|
7
|
+
json_attribs "/etc/chef/client-config.json"
|
data/lib/dhcpd.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
class DHCPD
|
2
|
+
attr_reader :config
|
3
|
+
|
4
|
+
def initialize(conf_path)
|
5
|
+
@conf_path = conf_path
|
6
|
+
@preamble = ''
|
7
|
+
@postamble = ''
|
8
|
+
@config = {}
|
9
|
+
|
10
|
+
parse
|
11
|
+
end
|
12
|
+
|
13
|
+
def save
|
14
|
+
tmp_path = '.tmp.dhcpd.conf'
|
15
|
+
File.open(tmp_path, 'w') do |f|
|
16
|
+
f.write @preamble
|
17
|
+
f.puts BEGIN_BUM
|
18
|
+
|
19
|
+
@config.each do |host, host_config|
|
20
|
+
f.puts "host #{host} {"
|
21
|
+
host_config.each do |key, value|
|
22
|
+
f.puts "\t#{key} #{value};"
|
23
|
+
end
|
24
|
+
f.puts "}"
|
25
|
+
end
|
26
|
+
|
27
|
+
f.puts END_BUM
|
28
|
+
f.write @postamble
|
29
|
+
end
|
30
|
+
|
31
|
+
system 'sudo', 'mv', tmp_path, @conf_path
|
32
|
+
end
|
33
|
+
|
34
|
+
def restart
|
35
|
+
system 'sudo "/Library/Application Support/VMware Fusion/boot.sh" --restart >>vmware.log 2>&1'
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
BEGIN_BUM = "#### BEGIN BUM ####"
|
42
|
+
END_BUM = "#### END BUM ####"
|
43
|
+
|
44
|
+
def parse
|
45
|
+
state = :preamble
|
46
|
+
host = nil
|
47
|
+
|
48
|
+
File.open(@conf_path).each_line do |rawline|
|
49
|
+
line = rawline.strip
|
50
|
+
|
51
|
+
case state
|
52
|
+
when :preamble
|
53
|
+
if line == BEGIN_BUM
|
54
|
+
state = :outside_host
|
55
|
+
else
|
56
|
+
@preamble << rawline
|
57
|
+
end
|
58
|
+
|
59
|
+
when :outside_host
|
60
|
+
next unless line =~ /^host .* \{$/
|
61
|
+
words = line.split(' ').map { |x| x.strip }
|
62
|
+
host = words[1]
|
63
|
+
@config[host] = {}
|
64
|
+
state = :inside_host
|
65
|
+
|
66
|
+
when :inside_host
|
67
|
+
next if line.size == 0 || line.strip =~ /^#/
|
68
|
+
if line == '}'
|
69
|
+
state = :outside_host
|
70
|
+
host = nil
|
71
|
+
elsif line == END_BUM
|
72
|
+
state = :postamble
|
73
|
+
else
|
74
|
+
parts = line.chomp(';').split(' ')
|
75
|
+
@config[host][parts[0..-2].join(' ')] = parts[-1]
|
76
|
+
end
|
77
|
+
|
78
|
+
when :postamble
|
79
|
+
@postamble << rawline
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
data/lib/hosts.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# Class for parsing and writing /etc/hosts file
|
2
|
+
|
3
|
+
class Hosts
|
4
|
+
def initialize
|
5
|
+
@preamble = ""
|
6
|
+
@postamble = ""
|
7
|
+
@config = {}
|
8
|
+
|
9
|
+
parse
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :config
|
13
|
+
|
14
|
+
def save
|
15
|
+
File.open('.tmp.hosts','w') do |f|
|
16
|
+
f.write @preamble
|
17
|
+
f.puts BEGIN_LINE
|
18
|
+
|
19
|
+
@config.each do |ip, host|
|
20
|
+
f.puts "#{ip}\t#{host}"
|
21
|
+
end
|
22
|
+
|
23
|
+
f.puts END_LINE
|
24
|
+
f.write @postamble
|
25
|
+
end
|
26
|
+
system "sudo mv .tmp.hosts /etc/hosts"
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
BEGIN_LINE = "#### BEGIN PAUPER ####"
|
32
|
+
END_LINE = "#### END PAUPER ####"
|
33
|
+
|
34
|
+
def parse
|
35
|
+
state = :preamble
|
36
|
+
|
37
|
+
File.open('/etc/hosts').each_line do |line|
|
38
|
+
case state
|
39
|
+
when :preamble
|
40
|
+
if line.include? BEGIN_LINE
|
41
|
+
state = :pauper
|
42
|
+
else
|
43
|
+
@preamble << line
|
44
|
+
end
|
45
|
+
when :pauper
|
46
|
+
if line.include? END_LINE
|
47
|
+
state = :postamble
|
48
|
+
else
|
49
|
+
if line.strip =~ /^#/
|
50
|
+
# skip
|
51
|
+
else
|
52
|
+
ip, host = line.split(/\s+/)
|
53
|
+
@config[ip] = host
|
54
|
+
end
|
55
|
+
end
|
56
|
+
when :postamble
|
57
|
+
@postamble << line
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/pauper.rb
ADDED
@@ -0,0 +1,385 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'net/ssh'
|
3
|
+
require 'net/scp'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
require 'fileutils'
|
7
|
+
require 'erb'
|
8
|
+
require 'ostruct'
|
9
|
+
|
10
|
+
require 'vmx'
|
11
|
+
require 'dhcpd'
|
12
|
+
require 'hosts'
|
13
|
+
|
14
|
+
class Pauper
|
15
|
+
DEFAULT_PAUPERFILE = './Pauperfile'
|
16
|
+
DEFAULT_VM_PATH = File.expand_path('~/Documents/Virtual Machines.localized/')
|
17
|
+
|
18
|
+
VMWARE_PATH = '/Library/Application Support/VMware Fusion'
|
19
|
+
DHCPD_CONF_PATH = "#{VMWARE_PATH}/vmnet8/dhcpd.conf"
|
20
|
+
|
21
|
+
def initialize(pauperfile=DEFAULT_PAUPERFILE)
|
22
|
+
@pauper_config = Pauper::Config.new(DEFAULT_PAUPERFILE)
|
23
|
+
end
|
24
|
+
|
25
|
+
def bootstrap
|
26
|
+
vmx = template_vmx
|
27
|
+
vmx.data['sharedFolder0.hostPath'] = File.expand_path('~')
|
28
|
+
vmx.data['sharedFolder0.guestName'] = 'host_home'
|
29
|
+
vmx.save
|
30
|
+
end
|
31
|
+
|
32
|
+
def create(node_name)
|
33
|
+
node_config = get_node_config(node_name)
|
34
|
+
|
35
|
+
raise "VM already exists!" if vm_exists?(node_name)
|
36
|
+
|
37
|
+
puts "Cloning template..."
|
38
|
+
clone_template node_name
|
39
|
+
|
40
|
+
puts "Updating machine configuration..."
|
41
|
+
mac = generate_mac
|
42
|
+
uuid = generate_uuid
|
43
|
+
|
44
|
+
vmx = node_vmx(node_name)
|
45
|
+
vmx.data['displayName'] = node_name
|
46
|
+
vmx.data['memsize'] = node_config.config[:ram] || @pauper_config.config[:default_ram] || 512
|
47
|
+
vmx.data['numvcpus'] = node_config.config[:cpus] || @pauper_config.config[:default_cpus] || 1
|
48
|
+
vmx.data['ethernet0.address'] = mac
|
49
|
+
vmx.data['uuid.bios'] = uuid
|
50
|
+
vmx.data['uuid.location'] = uuid
|
51
|
+
vmx.save
|
52
|
+
|
53
|
+
dhcpd = DHCPD.new(DHCPD_CONF_PATH)
|
54
|
+
dhcpd.config[node_name] = {
|
55
|
+
'hardware ethernet' => mac,
|
56
|
+
'fixed-address' => node_config.config[:ip]
|
57
|
+
}
|
58
|
+
dhcpd.save
|
59
|
+
|
60
|
+
puts "Restarting dhcpd..."
|
61
|
+
dhcpd.restart
|
62
|
+
|
63
|
+
puts "Starting..."
|
64
|
+
start_node(node_name)
|
65
|
+
|
66
|
+
setup(node_name)
|
67
|
+
end
|
68
|
+
|
69
|
+
def setup(node_name)
|
70
|
+
node_config = get_node_config(node_name)
|
71
|
+
|
72
|
+
puts "Setting up #{node_name}..."
|
73
|
+
|
74
|
+
client_erb = ERB.new(File.read(File.join(File.dirname(__FILE__), 'client.rb.erb')))
|
75
|
+
client_rb_data = client_erb.result(OpenStruct.new(:config => @pauper_config.config, :node_config => node_config).send(:binding))
|
76
|
+
tmp_client_rb_path = ".tmp.#{node_name}.client.rb"
|
77
|
+
File.open(tmp_client_rb_path,'w') do |f|
|
78
|
+
f.puts client_rb_data
|
79
|
+
end
|
80
|
+
|
81
|
+
chef_attribs = {
|
82
|
+
:run_list => @pauper_config.config[:default_run_list] + node_config.config[:run_list],
|
83
|
+
:ip => {
|
84
|
+
:private => node_config.config[:ip],
|
85
|
+
:private_netmask => '255.255.255.0'
|
86
|
+
}
|
87
|
+
}.merge(@pauper_config.config[:chef_options]).merge(node_config.config[:chef_options])
|
88
|
+
|
89
|
+
puts "Uploading Chef files..."
|
90
|
+
Net::SCP.start node_config.config[:ip], @pauper_config.config[:ssh_user], :password => @pauper_config.config[:ssh_password] do |scp|
|
91
|
+
scp.upload! tmp_client_rb_path, "client.rb"
|
92
|
+
scp.upload! @pauper_config.config[:validation_key_path], "validation.pem"
|
93
|
+
scp.upload! StringIO.new(chef_attribs.to_json), "client-config.json"
|
94
|
+
end
|
95
|
+
|
96
|
+
FileUtils.rm(tmp_client_rb_path)
|
97
|
+
|
98
|
+
enable_shared_folders node_name
|
99
|
+
@pauper_config.config[:shares].each do |share_name, guest_path, host_path, options|
|
100
|
+
cmd "mkdir -p #{host_path}"
|
101
|
+
share_folder node_name, share_name, host_path
|
102
|
+
end
|
103
|
+
|
104
|
+
puts "Connecting over SSH..."
|
105
|
+
Net::SSH.start node_config.config[:ip], @pauper_config.config[:ssh_user], :password => @pauper_config.config[:ssh_password] do |ssh|
|
106
|
+
ssh_exec ssh, "sudo hostname #{node_name}"
|
107
|
+
ssh_exec ssh, "sudo mkdir /etc/chef"
|
108
|
+
|
109
|
+
@pauper_config.config[:shares].each do |share_name, guest_path, host_path, options|
|
110
|
+
ssh_exec ssh, "sudo mkdir -p #{File.dirname(guest_path)} && sudo ln -sf /mnt/hgfs/#{share_name} #{guest_path}"
|
111
|
+
end
|
112
|
+
|
113
|
+
ssh_exec ssh, "sudo mv client.rb /etc/chef/"
|
114
|
+
ssh_exec ssh, "sudo mv validation.pem /etc/chef/"
|
115
|
+
ssh_exec ssh, "sudo mv client-config.json /etc/chef/"
|
116
|
+
|
117
|
+
ssh.exec! "sudo /var/lib/gems/1.8/bin/chef-client" do |channel, stream, data|
|
118
|
+
print data
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def destroy(node_name)
|
124
|
+
node_config = get_node_config(node_name)
|
125
|
+
|
126
|
+
if vm_exists?(node_name)
|
127
|
+
stop_node(node_name)
|
128
|
+
|
129
|
+
puts "Removing #{node_name} from Chef..."
|
130
|
+
`knife node delete #{node_name} -y`
|
131
|
+
`knife client delete #{node_name} -y`
|
132
|
+
|
133
|
+
puts "Destroying #{node_name}..."
|
134
|
+
FileUtils.rm_rf(node_name_to_vm_path(node_name))
|
135
|
+
else
|
136
|
+
puts "#{node_name} hasn't even been created yet, thusly you can't destroy it!"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def stop(node_name)
|
141
|
+
node_config = get_node_config(node_name)
|
142
|
+
|
143
|
+
if vm_running?(node_name)
|
144
|
+
puts "Stopping #{node_name}..."
|
145
|
+
stop_node(node_name)
|
146
|
+
else
|
147
|
+
puts "wtf, #{node_name} is not running."
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def start(node_name)
|
152
|
+
node_config = get_node_config(node_name)
|
153
|
+
|
154
|
+
if vm_running?(node_name)
|
155
|
+
puts "Dude, #{node_name} is already running!"
|
156
|
+
elsif vm_exists?(node_name)
|
157
|
+
puts "Starting #{node_name}..."
|
158
|
+
start_node node_name
|
159
|
+
else
|
160
|
+
puts "Generating, then starting #{node_name}..."
|
161
|
+
create node_name
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def write_hosts
|
166
|
+
puts "Writing /etc/hosts file..."
|
167
|
+
hosts = Hosts.new
|
168
|
+
@pauper_config.config[:nodes].each do |node|
|
169
|
+
hosts.config[node.config[:ip]] = node.name
|
170
|
+
end
|
171
|
+
hosts.save
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
def start_all
|
176
|
+
puts "Starting all nodes..."
|
177
|
+
@pauper_config.config[:nodes].each { |n| start(n.name) }
|
178
|
+
end
|
179
|
+
|
180
|
+
def stop_all
|
181
|
+
puts "Stopping all nodes..."
|
182
|
+
@pauper_config.config[:nodes].each { |n| stop(n.name) }
|
183
|
+
end
|
184
|
+
|
185
|
+
def destroy_all
|
186
|
+
puts "Destroying all nodes..."
|
187
|
+
@pauper_config.config[:nodes].each { |n| destroy(n.name) }
|
188
|
+
end
|
189
|
+
|
190
|
+
def setup_all
|
191
|
+
puts "Setting up all nodes..."
|
192
|
+
@pauper_config.config[:nodes].each { |n| setup(n.name) }
|
193
|
+
end
|
194
|
+
|
195
|
+
private
|
196
|
+
|
197
|
+
def cmd(*args)
|
198
|
+
puts ["local>", *args].join(" ")
|
199
|
+
system *args
|
200
|
+
end
|
201
|
+
|
202
|
+
def ssh_exec(ssh, cmd)
|
203
|
+
puts "ssh> #{cmd}"
|
204
|
+
print ssh.exec!(cmd)
|
205
|
+
end
|
206
|
+
|
207
|
+
def enable_shared_folders(node_name)
|
208
|
+
cmd "'#{VMWARE_PATH}/vmrun' enableSharedFolders '#{node_name_to_vmx(node_name)}'"
|
209
|
+
end
|
210
|
+
|
211
|
+
def share_folder(node_name, share_name, path)
|
212
|
+
cmd "'#{VMWARE_PATH}/vmrun' addSharedFolder '#{node_name_to_vmx(node_name)}' '#{share_name}' '#{path}'"
|
213
|
+
end
|
214
|
+
|
215
|
+
def get_node_config(node_name)
|
216
|
+
node_config = @pauper_config.get_node(node_name)
|
217
|
+
raise "Alas, I don't know about a node named #{node_name.inspect}..." unless node_config
|
218
|
+
node_config
|
219
|
+
end
|
220
|
+
|
221
|
+
def vm_exists?(node_name)
|
222
|
+
File.exists? node_name_to_vm_path(node_name)
|
223
|
+
end
|
224
|
+
|
225
|
+
def vm_running?(node_name)
|
226
|
+
`'#{VMWARE_PATH}/vmrun' list`.include?("#{node_name}.vmwarevm")
|
227
|
+
end
|
228
|
+
|
229
|
+
def clone_template(node_name)
|
230
|
+
FileUtils.cp_r(template_vm_path, node_name_to_vm_path(node_name))
|
231
|
+
end
|
232
|
+
|
233
|
+
def template_vmx
|
234
|
+
@template_vmx ||= VMX.new(@pauper_config.config[:vmx])
|
235
|
+
end
|
236
|
+
|
237
|
+
def node_vmx(node_name)
|
238
|
+
VMX.new(node_name_to_vmx(node_name))
|
239
|
+
end
|
240
|
+
|
241
|
+
def start_node(node_name)
|
242
|
+
cmd "'#{VMWARE_PATH}/vmrun' start '#{node_name_to_vmx(node_name)}' nogui >>vmware.log 2>&1"
|
243
|
+
end
|
244
|
+
|
245
|
+
def stop_node(node_name)
|
246
|
+
cmd "'#{VMWARE_PATH}/vmrun' stop '#{node_name_to_vmx(node_name)}' >>vmware.log 2>&1"
|
247
|
+
end
|
248
|
+
|
249
|
+
def generate_mac
|
250
|
+
"00:50:56:" + 3.times.map { ("%2s" % rand(256).to_s(16)).gsub(' ','0') }.join(':').upcase
|
251
|
+
end
|
252
|
+
|
253
|
+
# not actually universal - doesn't fucking matter
|
254
|
+
def generate_uuid
|
255
|
+
2.times.map {
|
256
|
+
8.times.map {
|
257
|
+
("%2s" % rand(256).to_s(16)).gsub(' ','0')
|
258
|
+
}.join(' ')
|
259
|
+
}.join('-')
|
260
|
+
end
|
261
|
+
|
262
|
+
def node_name_to_vmx(node_name)
|
263
|
+
Dir[File.join(node_name_to_vm_path(node_name), '*.vmx')][0]
|
264
|
+
end
|
265
|
+
|
266
|
+
def node_name_to_vm_path(node_name)
|
267
|
+
File.join(DEFAULT_VM_PATH, "#{node_name}.vmwarevm")
|
268
|
+
end
|
269
|
+
|
270
|
+
def template_vm_path
|
271
|
+
File.dirname(@pauper_config.config[:vmx])
|
272
|
+
end
|
273
|
+
|
274
|
+
class Config
|
275
|
+
attr_reader :config
|
276
|
+
|
277
|
+
def initialize(pauperfile)
|
278
|
+
@config = {
|
279
|
+
:nodes => [],
|
280
|
+
:ssh_user => 'dev',
|
281
|
+
:ssh_password => 'password',
|
282
|
+
:run_list => [],
|
283
|
+
:shares => [],
|
284
|
+
:suffix => '',
|
285
|
+
:chef_options => {}
|
286
|
+
}
|
287
|
+
instance_eval File.read(pauperfile)
|
288
|
+
end
|
289
|
+
|
290
|
+
def get_node(node_name)
|
291
|
+
@config[:nodes].detect { |n| n.name == node_name }
|
292
|
+
end
|
293
|
+
|
294
|
+
|
295
|
+
def ssh_user(user)
|
296
|
+
@config[:ssh_user] = user
|
297
|
+
end
|
298
|
+
|
299
|
+
def ssh_password(pass)
|
300
|
+
@config[:ssh_password] = pass
|
301
|
+
end
|
302
|
+
|
303
|
+
def vmx(vmx_file)
|
304
|
+
@config[:vmx] = File.expand_path(vmx_file)
|
305
|
+
end
|
306
|
+
|
307
|
+
def node(name, &block)
|
308
|
+
@config[:nodes] << Node.new(name + @config[:suffix], name, &block)
|
309
|
+
end
|
310
|
+
|
311
|
+
def ram(megabytes)
|
312
|
+
@config[:default_ram] = megabytes
|
313
|
+
end
|
314
|
+
|
315
|
+
def cpus(count)
|
316
|
+
@config[:default_cpus] = count
|
317
|
+
end
|
318
|
+
|
319
|
+
def chef_server_url(url)
|
320
|
+
@config[:chef_server_url] = url
|
321
|
+
end
|
322
|
+
|
323
|
+
def validation_key_path(path)
|
324
|
+
@config[:validation_key_path] = File.expand_path(path)
|
325
|
+
end
|
326
|
+
|
327
|
+
def validation_client_name(name)
|
328
|
+
@config[:validation_client_name] = name
|
329
|
+
end
|
330
|
+
|
331
|
+
def chef_environment(env)
|
332
|
+
@config[:chef_environment] = env
|
333
|
+
end
|
334
|
+
|
335
|
+
def chef_options(opts)
|
336
|
+
@config[:chef_options] = opts
|
337
|
+
end
|
338
|
+
|
339
|
+
def default_run_list(list)
|
340
|
+
@config[:default_run_list] = list
|
341
|
+
end
|
342
|
+
|
343
|
+
def share(share_name, guest_path, host_path, options={})
|
344
|
+
@config[:shares] << [share_name, guest_path, File.expand_path(host_path), options]
|
345
|
+
end
|
346
|
+
|
347
|
+
def node_suffix(suffix)
|
348
|
+
@config[:suffix] = suffix
|
349
|
+
end
|
350
|
+
|
351
|
+
class Node
|
352
|
+
attr_reader :name, :pretty_name, :config
|
353
|
+
|
354
|
+
def initialize(name, pretty_name, &block)
|
355
|
+
@name = name
|
356
|
+
@pretty_name = pretty_name
|
357
|
+
@config = {
|
358
|
+
:run_list => [],
|
359
|
+
:chef_options => {}
|
360
|
+
}
|
361
|
+
instance_eval &block
|
362
|
+
end
|
363
|
+
|
364
|
+
def run_list(*recipes)
|
365
|
+
@config[:run_list] = recipes
|
366
|
+
end
|
367
|
+
|
368
|
+
def ip(addr)
|
369
|
+
@config[:ip] = addr
|
370
|
+
end
|
371
|
+
|
372
|
+
def chef_options(options)
|
373
|
+
@config[:chef_options] = options
|
374
|
+
end
|
375
|
+
|
376
|
+
def ram(megabytes)
|
377
|
+
@config[:ram] = megabytes
|
378
|
+
end
|
379
|
+
|
380
|
+
def cpus(count)
|
381
|
+
@config[:cpus] = count
|
382
|
+
end
|
383
|
+
end
|
384
|
+
end
|
385
|
+
end
|
data/lib/vmx.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
class VMX
|
4
|
+
attr_reader :data
|
5
|
+
|
6
|
+
def initialize(filename)
|
7
|
+
@filename = filename
|
8
|
+
@data = {}
|
9
|
+
|
10
|
+
File.open(filename).each_line do |line|
|
11
|
+
key, value = line.split('=', 2)
|
12
|
+
@data[key.strip] = eval(value)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def save(filename=@filename)
|
17
|
+
FileUtils.cp(filename, filename + '.bak')
|
18
|
+
File.open(filename, 'w') do |f|
|
19
|
+
@data.sort_by { |(k,v)| k }.each do |(k,v)|
|
20
|
+
f.puts "#{k} = #{v.to_s.inspect}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pauper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 4
|
9
|
+
version: 0.0.4
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Tyler McMullen
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-08-17 00:00:00 -07:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: thor
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: net-ssh
|
34
|
+
prerelease: false
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 0
|
41
|
+
version: "0"
|
42
|
+
type: :runtime
|
43
|
+
version_requirements: *id002
|
44
|
+
- !ruby/object:Gem::Dependency
|
45
|
+
name: net-scp
|
46
|
+
prerelease: false
|
47
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
segments:
|
52
|
+
- 0
|
53
|
+
version: "0"
|
54
|
+
type: :runtime
|
55
|
+
version_requirements: *id003
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: json
|
58
|
+
prerelease: false
|
59
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
version: "0"
|
66
|
+
type: :runtime
|
67
|
+
version_requirements: *id004
|
68
|
+
description: Inspired by Vagrant but much much simpler. Also uses VMware, instead of Virtualbox.
|
69
|
+
email:
|
70
|
+
- tyler@fastly.com
|
71
|
+
executables:
|
72
|
+
- pauper
|
73
|
+
extensions: []
|
74
|
+
|
75
|
+
extra_rdoc_files: []
|
76
|
+
|
77
|
+
files:
|
78
|
+
- bin/pauper
|
79
|
+
- lib/client.rb.erb
|
80
|
+
- lib/dhcpd.rb
|
81
|
+
- lib/hosts.rb
|
82
|
+
- lib/pauper.rb
|
83
|
+
- lib/vmx.rb
|
84
|
+
- README
|
85
|
+
has_rdoc: true
|
86
|
+
homepage: http://github.com/fastly/Pauper
|
87
|
+
licenses: []
|
88
|
+
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
segments:
|
99
|
+
- 0
|
100
|
+
version: "0"
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
segments:
|
106
|
+
- 0
|
107
|
+
version: "0"
|
108
|
+
requirements: []
|
109
|
+
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 1.3.6
|
112
|
+
signing_key:
|
113
|
+
specification_version: 3
|
114
|
+
summary: A semi-sane way to manage a multi-vm dev environment
|
115
|
+
test_files: []
|
116
|
+
|