pauper 0.0.12 → 0.1.0

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 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"