pauper 0.0.12 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -1,12 +1,56 @@
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
1
+ To setup a dev environment
2
+
3
+ Install 11.10
4
+
5
+ sudo apt-get install build-essential aptitude lxc bridge-utils libvirt-bin ruby openssh-server curl libssl-dev libxml2-dev libxslt-dev git-core libreadline6-dev
6
+
7
+ Install rvm
8
+
9
+ See https://rvm.io/
10
+ rvm install 1.9.3
11
+ rvm use 1.9.3 --default
12
+ source ~/.profile
13
+
14
+ gem install ohai chef
15
+
16
+ Setup .ssh, .chef, .gitconfig
17
+ https://gist.github.com/eb11025e7c0e53ef58be
18
+
19
+ mkdir fastly
20
+ cd fastly
21
+ git clone git@github.com:fastly/Chef.git
22
+ git clone git@github.com:macros/Pauper.git
23
+ git clone git@github.com:fastly/pauper-env.git
24
+ # Customizations for lxc
25
+ https://gist.github.com/d15219c4edcf0f112c1c
26
+
27
+ git clone git@github.com:fastly/Heavenly.git
28
+ touch Heavenly/heavenly.log
29
+ chmod 777 Heavenly/heavenly.log
30
+ git clone git@github.com:fastly/Northstar.git
31
+ mv Northstar northstar
32
+ git clone git@github.com:fastly/Sierra.git
33
+ git clone git@github.com:fastly/conduction.git
34
+ git clone git@github.com:fastly/Website.git
35
+
36
+ cd Pauper
37
+ gem build pauper.gemspec
38
+ gem install pauper-0.0.6.gem
39
+ knife environment create <username>-dev
40
+ (If knife cant be found, try 'source ~/.rvm/scripts/rvm')
41
+
42
+ cd ../pauper-env
43
+ pauper bootstrap
44
+ pauper start
45
+ pauper setup
46
+
47
+ * Assumes ssh user/pass in container is root as setup by lxc (TODO)
48
+
49
+ pauper bootstrap
50
+ pauper start <node>
51
+ pauper setup <node>
52
+ pauper stop <node>
53
+
54
+ The base node can be run, not normally started
11
55
 
12
56
  DONE!
data/bin/pauper CHANGED
@@ -5,6 +5,12 @@ require 'thor'
5
5
  require 'pauper'
6
6
 
7
7
  class CLI < Thor
8
+ desc "bootstrap", "Initialize the base image"
9
+ def bootstrap
10
+ pauper = Pauper.new
11
+ pauper.bootstrap
12
+ end
13
+
8
14
  desc "destroy [NODENAME]", "Completely destroy a VM"
9
15
  def destroy(node_name=nil)
10
16
  pauper = Pauper.new
@@ -35,6 +41,29 @@ class CLI < Thor
35
41
  end
36
42
  end
37
43
 
44
+ desc "resume [NODENAME]", "Resume a VM"
45
+ def resume(node_name=nil)
46
+ pauper = Pauper.new
47
+ if node_name
48
+ pauper.resume(node_name)
49
+ else
50
+ pauper.resume_all
51
+ end
52
+ end
53
+
54
+
55
+ desc "suspend [NODENAME]", "Suspends a VM"
56
+ def suspend(node_name=nil)
57
+ pauper = Pauper.new
58
+ if node_name
59
+ pauper.suspend(node_name)
60
+ else
61
+ pauper.suspend_all
62
+ end
63
+ end
64
+
65
+
66
+
38
67
  desc "setup [NODENAME]", "Refresh configs and run Chef on a VM"
39
68
  def setup(node_name=nil)
40
69
  pauper = Pauper.new
data/lib/dhcpd.rb CHANGED
@@ -11,7 +11,7 @@ class DHCPD
11
11
  end
12
12
 
13
13
  def subnet
14
- @preamble.match(/subnet (\d+\.\d+\.\d+)\.0 netmask/)[1]
14
+ @preamble.match(/(172\.16\.\d+)\.0/)[1]
15
15
  end
16
16
 
17
17
  def save
data/lib/libvirt.rb ADDED
@@ -0,0 +1,80 @@
1
+ class LIBVIRT
2
+ attr_reader :subnet
3
+ attr_reader :ip
4
+
5
+ CONF_FILE = "/etc/libvirt/qemu/networks/pauper.xml"
6
+
7
+ def initialize(subnet)
8
+ @subnet = subnet
9
+ @ip = @subnet + '.1'
10
+ @template = ERB.new <<EOF
11
+ <network>
12
+ <name>pauper</name>
13
+ <bridge name="pauperbr%d" />
14
+ <forward/>
15
+ <ip address="<%= ip %>" netmask="255.255.255.0">
16
+ <dhcp>
17
+ <range start="<%= subnet %>.100" stop="<%= subnet %>.200" />
18
+ </dhcp>
19
+ </ip>
20
+ </network>
21
+ EOF
22
+ end
23
+
24
+ def enable
25
+ write_config
26
+ unless active?
27
+ unless loaded?
28
+ load_config
29
+ end
30
+ start_network
31
+ # The bridge needs a bit to settle
32
+ sleep 3
33
+ end
34
+ end
35
+
36
+ def interface
37
+ `sudo virsh net-info pauper | grep Bridge`.split(%r{\s+})[1]
38
+ end
39
+
40
+ private
41
+ def write_config
42
+ config_data = @template.result(OpenStruct.new(:ip => @ip, :subnet => @subnet).send(:binding))
43
+ File.open(".tmp.pauper.xml",'w') do |f|
44
+ f.puts config_data
45
+ end
46
+
47
+ system("sudo mv .tmp.pauper.xml #{CONF_FILE}")
48
+ end
49
+
50
+ def load_config
51
+ system("sudo virsh net-define #{CONF_FILE}")
52
+ end
53
+
54
+ def unload_config
55
+ system("sudo virsh net-undefine pauper")
56
+ end
57
+
58
+ def start_network
59
+ system("sudo rm /var/lib/misc/dnsmasq.leases")
60
+ system("sudo virsh net-start pauper >> pauper.log 2>&1")
61
+ end
62
+
63
+ def stop_network
64
+ system("sudo virsh net-destroy pauper >> pauper.log 2>&1")
65
+ end
66
+
67
+ def active?
68
+ virsh = `sudo virsh net-info pauper | grep '^Active.*yes$'`
69
+ unless virsh == ""
70
+ return true
71
+ end
72
+ end
73
+
74
+ def loaded?
75
+ virsh = `sudo virsh net-info pauper | grep '^Name.*pauper$'`
76
+ unless virsh == ""
77
+ return true
78
+ end
79
+ end
80
+ end
data/lib/lxc.rb ADDED
@@ -0,0 +1,53 @@
1
+ require 'fileutils'
2
+
3
+ class LXC
4
+ attr_accessor :interface
5
+ attr_accessor :mac
6
+ attr_reader :node_name
7
+
8
+ def initialize(node_name)
9
+ @node_name = node_name
10
+ @filename = "/var/lib/lxc/#{node_name}/config"
11
+ @mac = ''
12
+ @interface = ''
13
+ @template = ERB.new <<EOF
14
+ lxc.utsname = <%= node_name %>
15
+ lxc.pts = 1024
16
+ lxc.tty = 4
17
+ lxc.cgroup.cpu.shares = 512
18
+ lxc.rootfs = /var/lib/lxc/<%= node_name %>/rootfs
19
+ lxc.mount = /var/lib/lxc/<%= node_name %>/fstab
20
+ lxc.network.type = veth
21
+ lxc.network.name = eth0
22
+ lxc.network.link = <%= interface %>
23
+ lxc.network.hwaddr = <%= mac %>
24
+ lxc.network.flags = up
25
+ lxc.cgroup.devices.deny = a
26
+ lxc.cgroup.devices.allow = c 1:3 rwm
27
+ lxc.cgroup.devices.allow = c 1:5 rwm
28
+ lxc.cgroup.devices.allow = c 5:1 rwm
29
+ lxc.cgroup.devices.allow = c 5:0 rwm
30
+ lxc.cgroup.devices.allow = c 4:0 rwm
31
+ lxc.cgroup.devices.allow = c 4:1 rwm
32
+ lxc.cgroup.devices.allow = c 1:9 rwm
33
+ lxc.cgroup.devices.allow = c 1:8 rwm
34
+ lxc.cgroup.devices.allow = c 136:* rwm
35
+ lxc.cgroup.devices.allow = c 5:2 rwm
36
+ lxc.cgroup.devices.allow = b 7:0 rwm
37
+ lxc.cgroup.devices.allow = c 254:0 rwm
38
+ lxc.cgroup.devices.allow = c 108:0 rwm
39
+ lxc.cgroup.devices.allow = c 10:229 rwm
40
+ lxc.cgroup.devices.allow = c 10:200 rwm
41
+ EOF
42
+
43
+ end
44
+
45
+ def save(filename=@filename)
46
+ config_data = @template.result(OpenStruct.new(:node_name => @node_name,
47
+ :mac => @mac, :interface => @interface ).send(:binding))
48
+ File.open(".tmp.lxc.conf",'w') do |f|
49
+ f.puts config_data
50
+ end
51
+ system "sudo mv .tmp.lxc.conf #{@filename}"
52
+ end
53
+ end
data/lib/pauper.rb CHANGED
@@ -7,74 +7,123 @@ require 'fileutils'
7
7
  require 'erb'
8
8
  require 'ostruct'
9
9
 
10
- require 'vmx'
11
- require 'dhcpd'
10
+ require 'lxc'
11
+ require 'libvirt'
12
12
  require 'hosts'
13
13
 
14
14
  class Pauper
15
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"
16
+ DEFAULT_VM_PATH = File.expand_path('/var/lib/lxc/')
20
17
 
21
18
  def initialize(pauperfile=DEFAULT_PAUPERFILE)
22
19
  @pauper_config = Pauper::Config.new(DEFAULT_PAUPERFILE)
20
+ network = LIBVIRT.new(@pauper_config.config[:subnet])
21
+ network.enable
22
+ @pauper_config.config[:bridge] = network.interface
23
23
  end
24
24
 
25
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
26
+ raise "Base already exists!" if vm_exists?("base")
27
+ system("sudo touch /var/lib/lxc/lxc.conf")
28
+ system("sudo lxc-create -n base -t ubuntu -f /var/lib/lxc/lxc.conf -- -a amd64 -r lucid")
29
+ mac = generate_mac
30
+ ip = "#{@pauper_config.config[:subnet]}.2"
31
+
32
+ lxc = LXC.new('base')
33
+ lxc.interface = @pauper_config.config[:bridge]
34
+ lxc.mac = mac
35
+ lxc.save
36
+
37
+ prepare_fstab('base')
38
+ prepare_vm_network('base',ip)
39
+ prepare_base_cache
40
+
41
+ puts "Installing chef.."
42
+ start_node('base')
43
+ chef_node = "base#{@pauper_config.config[:node_suffix]}"
44
+
45
+ cmd "knife bootstrap --bootstrap-version chef-full -N #{chef_node} -E #{@pauper_config.config[:chef_environment]} -x #{@pauper_config.config[:ssh_user]} -P #{@pauper_config.config[:ssh_password]} -r \"#{@pauper_config.config[:default_run_list].join(",")}\" #{ip}"
46
+ stop_node('base')
47
+ end
48
+
49
+ def prepare_fstab(node_name)
50
+ File.open('.tmp.fstab','w') do |f|
51
+ @pauper_config.config[:shares].each do |share_name, guest_path, host_path, options|
52
+ f.puts "#{host_path} #{DEFAULT_VM_PATH}/#{node_name}/rootfs/#{guest_path} none defaults,bind 0 0"
53
+ end
54
+ end
55
+ system "sudo mv .tmp.fstab #{DEFAULT_VM_PATH}/#{node_name}/fstab"
56
+ end
57
+
58
+ def prepare_vm_network(node_name,ip)
59
+ host_ip = "#{@pauper_config.config[:subnet]}.1"
60
+ File.open('.tmp.interfaces', 'w') do |f|
61
+ f.puts "auto lo"
62
+ f.puts "iface lo inet loopback"
63
+ f.puts ""
64
+ f.puts "auto eth0"
65
+ f.puts "iface eth0 inet static"
66
+ f.puts " address #{ip}"
67
+ f.puts " netmask 255.255.255.0"
68
+ f.puts " gateway #{host_ip}"
69
+ end
70
+ File.open('.tmp.resolv.conf', 'w') do |f|
71
+ f.puts "nameserver #{host_ip}"
72
+ end
73
+ system "sudo mv .tmp.interfaces #{DEFAULT_VM_PATH}/#{node_name}/rootfs/etc/network/interfaces"
74
+ system "sudo mv .tmp.resolv.conf #{DEFAULT_VM_PATH}/#{node_name}/rootfs/etc/resolv.conf"
75
+ end
76
+
77
+ def prepare_base_cache
78
+ @pauper_config.config[:shares].each do |share_name, guest_path, host_path, options|
79
+ cmd "sudo mkdir -p #{host_path}"
80
+ cmd "sudo mkdir -p /var/lib/lxc/base/rootfs#{guest_path}"
81
+ end
82
+ cmd "sudo mkdir -p /var/cache/lxc/lucid/cache/apt/partial"
30
83
  end
31
84
 
85
+ def reconfigure_ssh(node_name)
86
+ cmd "sudo chroot /var/lib/lxc/#{node_name}/rootfs/ /usr/sbin/dpkg-reconfigure openssh-server"
87
+ end
88
+
32
89
  def create(node_name)
33
90
  node_config = get_node_config(node_name)
34
91
 
35
92
  raise "VM already exists!" if vm_exists?(node_name)
36
93
 
37
- puts "Cloning template..."
38
- clone_template node_name
39
-
40
- puts "Updating machine configuration..."
94
+ puts "Cloning base..."
95
+ clone_base(node_name)
41
96
  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
- ip = node_ip(node_config)
55
-
56
- dhcpd.config[node_name] = {
57
- 'hardware ethernet' => mac,
58
- 'fixed-address' => ip
59
- }
60
- dhcpd.save
61
-
62
- puts "Restarting dhcpd..."
63
- dhcpd.restart
64
-
97
+ ip = "#{@pauper_config.config[:subnet]}.#{node_config.config[:last_octet]}"
98
+
99
+ lxc = LXC.new(node_name)
100
+ lxc.interface = @pauper_config.config[:bridge]
101
+ lxc.mac = mac
102
+ lxc.save
103
+
104
+ prepare_fstab(node_name)
105
+ prepare_vm_network(node_name,ip)
106
+ reconfigure_ssh(node_name)
65
107
  puts "Starting..."
66
108
  start_node(node_name)
67
-
109
+ sleep 3
68
110
  setup(node_name)
69
111
  end
70
112
 
71
113
  def setup(node_name)
72
114
  node_config = get_node_config(node_name)
73
-
115
+ config = @pauper_config.config
74
116
  puts "Setting up #{node_name}..."
75
-
76
- client_erb = ERB.new(File.read(File.join(File.dirname(__FILE__), 'client.rb.erb')))
77
- client_rb_data = client_erb.result(OpenStruct.new(:config => @pauper_config.config, :node_config => node_config).send(:binding))
117
+ client_erb = ERB.new <<EOF
118
+ node_name "<%= chef_node %>"
119
+ chef_server_url "<%= config[:chef_server_url] %>"
120
+ validation_client_name "<%= config[:validation_client_name] %>"
121
+ environment "<%= config[:chef_environment] %>"
122
+ verbose_logging false
123
+ json_attribs "/etc/chef/client-config.json"
124
+ EOF
125
+ chef_node = "#{node_name}#{config[:node_suffix]}"
126
+ client_rb_data = client_erb.result(OpenStruct.new(:config => config, :chef_node => chef_node).send(:binding))
78
127
  tmp_client_rb_path = ".tmp.#{node_name}.client.rb"
79
128
  File.open(tmp_client_rb_path,'w') do |f|
80
129
  f.puts client_rb_data
@@ -83,69 +132,59 @@ class Pauper
83
132
  ip = node_ip(node_config)
84
133
 
85
134
  chef_attribs = {
86
- :run_list => @pauper_config.config[:default_run_list] + node_config.config[:run_list],
135
+ :run_list => config[:default_run_list] + node_config.config[:run_list],
87
136
  :ip => {
88
137
  :private => ip,
89
138
  :private_netmask => '255.255.255.0'
90
139
  }
91
- }.merge(@pauper_config.config[:chef_options]).merge(node_config.config[:chef_options])
140
+ }.merge(config[:chef_options]).merge(node_config.config[:chef_options])
92
141
 
93
142
  puts "Uploading Chef files..."
94
- Net::SCP.start ip, @pauper_config.config[:ssh_user], :password => @pauper_config.config[:ssh_password] do |scp|
143
+ Net::SCP.start ip, config[:ssh_user], :password => config[:ssh_password] do |scp|
95
144
  scp.upload! tmp_client_rb_path, "client.rb"
96
- scp.upload! @pauper_config.config[:validation_key_path], "validation.pem"
145
+ scp.upload! config[:validation_key_path], "validation.pem"
97
146
  scp.upload! StringIO.new(chef_attribs.to_json), "client-config.json"
98
147
  end
99
148
 
100
149
  FileUtils.rm(tmp_client_rb_path)
101
150
 
102
- enable_shared_folders node_name
103
- @pauper_config.config[:shares].each do |share_name, guest_path, host_path, options|
104
- cmd "mkdir -p #{host_path}"
105
- share_folder node_name, share_name, host_path
106
- end
107
-
108
151
  puts "Connecting over SSH..."
109
- Net::SSH.start ip, @pauper_config.config[:ssh_user], :password => @pauper_config.config[:ssh_password] do |ssh|
110
- ssh_exec ssh, "sudo hostname #{node_name}"
111
- ssh_exec ssh, "sudo bash -c \"echo #{node_name} > /etc/hostname\""
112
-
113
- ssh_exec ssh, "sudo mkdir /etc/chef"
114
-
115
- @pauper_config.config[:shares].each do |share_name, guest_path, host_path, options|
116
- ssh_exec ssh, "sudo mkdir -p #{File.dirname(guest_path)} && sudo ln -sf /mnt/hgfs/#{share_name} #{guest_path}"
117
- end
118
-
119
- ssh_exec ssh, "sudo mv client.rb /etc/chef/"
120
- ssh_exec ssh, "sudo mv validation.pem /etc/chef/"
121
- ssh_exec ssh, "sudo mv client-config.json /etc/chef/"
152
+ Net::SSH.start ip, config[:ssh_user], :password => config[:ssh_password] do |ssh|
153
+ ssh_exec ssh, "mv client.rb /etc/chef/"
154
+ ssh_exec ssh, "mv client-config.json /etc/chef/"
122
155
 
123
- ssh.exec! "sudo /var/lib/gems/1.8/bin/chef-client" do |channel, stream, data|
156
+ ssh.exec! "/usr/bin/chef-client" do |channel, stream, data|
124
157
  print data
125
158
  end
126
159
  end
127
160
  end
128
-
161
+
129
162
  def destroy(node_name)
130
- node_config = get_node_config(node_name)
163
+ if node_name == 'base'
164
+ ip = @pauper_config.config[:subnet] + '.2'
165
+ else
166
+ node_config = get_node_config(node_name)
167
+ ip = node_ip(node_config)
168
+ end
131
169
 
132
170
  if vm_exists?(node_name)
133
171
  stop_node(node_name)
134
172
 
173
+ chef_node = "#{node_name}#{@pauper_config.config[:node_suffix]}"
135
174
  puts "Removing #{node_name} from Chef..."
136
- `knife node delete #{node_name} -y`
137
- `knife client delete #{node_name} -y`
175
+ `knife node delete #{chef_node} -y`
176
+ `knife client delete #{chef_node} -y`
138
177
 
139
178
  puts "Destroying #{node_name}..."
140
- FileUtils.rm_rf(node_name_to_vm_path(node_name))
179
+ cmd "sudo lxc-destroy -n '#{node_name}' >> pauper.log 2>&1"
180
+ cmd "ssh-keygen -R '#{node_name}' >> pauper.log 2>&1"
181
+ cmd "ssh-keygen -R '#{ip}' >> pauper.log 2>&1"
141
182
  else
142
183
  puts "#{node_name} hasn't even been created yet, thusly you can't destroy it!"
143
184
  end
144
185
  end
145
186
 
146
187
  def stop(node_name)
147
- node_config = get_node_config(node_name)
148
-
149
188
  if vm_running?(node_name)
150
189
  puts "Stopping #{node_name}..."
151
190
  stop_node(node_name)
@@ -155,8 +194,6 @@ class Pauper
155
194
  end
156
195
 
157
196
  def start(node_name)
158
- node_config = get_node_config(node_name)
159
-
160
197
  if vm_running?(node_name)
161
198
  puts "Dude, #{node_name} is already running!"
162
199
  elsif vm_exists?(node_name)
@@ -168,6 +205,25 @@ class Pauper
168
205
  end
169
206
  end
170
207
 
208
+
209
+ def resume(node_name)
210
+ if vm_frozen?(node_name)
211
+ puts "Resuming #{node_name}..."
212
+ resume_node(node_name)
213
+ else
214
+ puts "wtf, #{node_name} is not suspended."
215
+ end
216
+ end
217
+
218
+ def suspend(node_name)
219
+ if vm_frozen?(node_name)
220
+ puts "Dude, #{node_name} is already suspended!"
221
+ else
222
+ puts "Suspending #{node_name}..."
223
+ suspend_node(node_name)
224
+ end
225
+ end
226
+
171
227
  def write_hosts
172
228
  puts "Writing /etc/hosts file..."
173
229
  hosts = Hosts.new
@@ -188,6 +244,16 @@ class Pauper
188
244
  @pauper_config.config[:nodes].each { |n| stop(n.name) }
189
245
  end
190
246
 
247
+ def resume_all
248
+ puts "Resuming all nodes..."
249
+ @pauper_config.config[:nodes].each { |n| resume(n.name) }
250
+ end
251
+
252
+ def suspend_all
253
+ puts "Suspending all nodes..."
254
+ @pauper_config.config[:nodes].each { |n| suspend(n.name) }
255
+ end
256
+
191
257
  def destroy_all
192
258
  puts "Destroying all nodes..."
193
259
  @pauper_config.config[:nodes].each { |n| destroy(n.name) }
@@ -202,12 +268,7 @@ class Pauper
202
268
 
203
269
  def node_ip(node_config)
204
270
  return node_config.config[:ip] if node_config.config[:ip]
205
-
206
- @subnet ||= begin
207
- dhcpd = DHCPD.new(DHCPD_CONF_PATH)
208
- dhcpd.subnet
209
- end
210
-
271
+ @subnet = @pauper_config.config[:subnet]
211
272
  return @subnet + '.' + node_config.config[:last_octet]
212
273
  end
213
274
 
@@ -221,15 +282,6 @@ class Pauper
221
282
  print ssh.exec!(cmd)
222
283
  end
223
284
 
224
- def enable_shared_folders(node_name)
225
- cmd "'#{VMWARE_PATH}/vmrun' enableSharedFolders '#{node_name_to_vmx(node_name)}'"
226
- end
227
-
228
- def share_folder(node_name, share_name, path)
229
- cmd "'#{VMWARE_PATH}/vmrun' removeSharedFolder '#{node_name_to_vmx(node_name)}' '#{share_name}'"
230
- cmd "'#{VMWARE_PATH}/vmrun' addSharedFolder '#{node_name_to_vmx(node_name)}' '#{share_name}' '#{path}'"
231
- end
232
-
233
285
  def get_node_config(node_name)
234
286
  node_config = @pauper_config.get_node(node_name)
235
287
  raise "Alas, I don't know about a node named #{node_name.inspect}..." unless node_config
@@ -241,31 +293,42 @@ class Pauper
241
293
  end
242
294
 
243
295
  def vm_running?(node_name)
244
- `'#{VMWARE_PATH}/vmrun' list`.include?("#{node_name}.vmwarevm")
296
+ `sudo lxc-info -n '#{node_name}'`.include?("RUNNING")
245
297
  end
246
298
 
247
- def clone_template(node_name)
248
- FileUtils.cp_r(template_vm_path, node_name_to_vm_path(node_name))
299
+ def vm_frozen?(node_name)
300
+ `sudo lxc-info -n '#{node_name}'`.include?("FROZEN")
249
301
  end
250
302
 
251
- def template_vmx
252
- @template_vmx ||= VMX.new(@pauper_config.config[:vmx])
303
+ def clone_base(node_name)
304
+ cmd "sudo cp -ax #{DEFAULT_VM_PATH}/base #{DEFAULT_VM_PATH}/#{node_name}"
305
+ cmd "sudo rm #{DEFAULT_VM_PATH}/#{node_name}/rootfs/etc/chef/client.pem"
306
+ cmd "sudo rm #{DEFAULT_VM_PATH}/#{node_name}/rootfs/etc/ssh/ssh*key*"
307
+ cmd "sudo sed -i \"s/base/#{node_name}/g\" /var/lib/lxc/#{node_name}/rootfs/etc/hostname /var/lib/lxc/#{node_name}/rootfs/etc/chef/client.rb"
253
308
  end
254
309
 
255
- def node_vmx(node_name)
256
- VMX.new(node_name_to_vmx(node_name))
310
+ def vm_config(node_name)
311
+ LXC.new("#{DEFAULT_VM_PATH}/#{node_name}/config")
257
312
  end
258
313
 
259
314
  def start_node(node_name)
260
- cmd "'#{VMWARE_PATH}/vmrun' start '#{node_name_to_vmx(node_name)}' nogui >>vmware.log 2>&1"
315
+ cmd "sudo lxc-start -d -n '#{node_name}' >> pauper.log 2>&1"
261
316
  end
262
317
 
263
318
  def stop_node(node_name)
264
- cmd "'#{VMWARE_PATH}/vmrun' stop '#{node_name_to_vmx(node_name)}' >>vmware.log 2>&1"
319
+ cmd "sudo lxc-stop -n '#{node_name}' >> pauper.log 2>&1"
320
+ end
321
+
322
+ def resume_node(node_name)
323
+ cmd "sudo lxc-unfreeze -n '#{node_name}' >> pauper.log 2>&1"
324
+ end
325
+
326
+ def suspend_node(node_name)
327
+ cmd "sudo lxc-freeze -n '#{node_name}' >> pauper.log 2>&1"
265
328
  end
266
329
 
267
330
  def generate_mac
268
- "00:50:56:" + 3.times.map { ("%2s" % rand(256).to_s(16)).gsub(' ','0') }.join(':').upcase
331
+ "ce:71:52:" + 3.times.map { ("%2s" % rand(256).to_s(16)).gsub(' ','0') }.join(':').upcase
269
332
  end
270
333
 
271
334
  # not actually universal - doesn't fucking matter
@@ -277,14 +340,8 @@ class Pauper
277
340
  }.join('-')
278
341
  end
279
342
 
280
- def node_name_to_vmx(node_name)
281
- vmxes = Dir[File.join(node_name_to_vm_path(node_name), '*.vmx')]
282
- raise "Can't find a vmx file in #{node_name_to_vm_path(node_name)}" unless vmxes[0]
283
- vmxes[0]
284
- end
285
-
286
343
  def node_name_to_vm_path(node_name)
287
- File.join(DEFAULT_VM_PATH, "#{node_name}.vmwarevm")
344
+ File.join(DEFAULT_VM_PATH, "#{node_name}/config")
288
345
  end
289
346
 
290
347
  def template_vm_path
@@ -301,7 +358,7 @@ class Pauper
301
358
  :ssh_password => 'password',
302
359
  :run_list => [],
303
360
  :shares => [],
304
- :suffix => '',
361
+ :subnet => '172.16.254',
305
362
  :chef_options => {}
306
363
  }
307
364
  instance_eval File.read(pauperfile)
@@ -311,7 +368,6 @@ class Pauper
311
368
  @config[:nodes].detect { |n| n.name == node_name }
312
369
  end
313
370
 
314
-
315
371
  def ssh_user(user)
316
372
  @config[:ssh_user] = user
317
373
  end
@@ -320,12 +376,16 @@ class Pauper
320
376
  @config[:ssh_password] = pass
321
377
  end
322
378
 
379
+ def subnet(net)
380
+ @config[:subnet] = net
381
+ end
382
+
323
383
  def vmx(vmx_file)
324
384
  @config[:vmx] = File.expand_path(vmx_file)
325
385
  end
326
386
 
327
387
  def node(name, &block)
328
- @config[:nodes] << Node.new(name + @config[:suffix], name, &block)
388
+ @config[:nodes] << Node.new(name, name, &block)
329
389
  end
330
390
 
331
391
  def ram(megabytes)
@@ -361,11 +421,11 @@ class Pauper
361
421
  end
362
422
 
363
423
  def share(share_name, guest_path, host_path, options={})
364
- @config[:shares] << [share_name, guest_path, File.expand_path(host_path), options]
424
+ @config[:shares] << [share_name, guest_path, host_path, options]
365
425
  end
366
426
 
367
427
  def node_suffix(suffix)
368
- @config[:suffix] = suffix
428
+ @config[:node_suffix] = suffix
369
429
  end
370
430
 
371
431
  class Node
metadata CHANGED
@@ -1,21 +1,22 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pauper
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 12
10
- version: 0.0.12
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tyler McMullen
14
+ - Jason Cook
14
15
  autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2011-09-13 00:00:00 -07:00
19
+ date: 2012-06-08 00:00:00 -07:00
19
20
  default_executable:
20
21
  dependencies:
21
22
  - !ruby/object:Gem::Dependency
@@ -74,7 +75,7 @@ dependencies:
74
75
  version: "0"
75
76
  type: :runtime
76
77
  version_requirements: *id004
77
- description: Inspired by Vagrant but much much simpler. Also uses VMware, instead of Virtualbox.
78
+ description: Inspired by Vagrant but much much simpler. Also uses LXC, instead of Virtualbox.
78
79
  email:
79
80
  - tyler@fastly.com
80
81
  executables:
@@ -85,9 +86,10 @@ extra_rdoc_files: []
85
86
 
86
87
  files:
87
88
  - bin/pauper
88
- - lib/client.rb.erb
89
89
  - lib/dhcpd.rb
90
90
  - lib/hosts.rb
91
+ - lib/libvirt.rb
92
+ - lib/lxc.rb
91
93
  - lib/pauper.rb
92
94
  - lib/vmx.rb
93
95
  - README
data/lib/client.rb.erb DELETED
@@ -1,7 +0,0 @@
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"