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 +54 -10
- data/bin/pauper +29 -0
- data/lib/dhcpd.rb +1 -1
- data/lib/libvirt.rb +80 -0
- data/lib/lxc.rb +53 -0
- data/lib/pauper.rb +172 -112
- metadata +8 -6
- data/lib/client.rb.erb +0 -7
data/README
CHANGED
@@ -1,12 +1,56 @@
|
|
1
|
-
To
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
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 '
|
11
|
-
require '
|
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('
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
38
|
-
|
39
|
-
|
40
|
-
puts "Updating machine configuration..."
|
94
|
+
puts "Cloning base..."
|
95
|
+
clone_base(node_name)
|
41
96
|
mac = generate_mac
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
77
|
-
|
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 =>
|
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(
|
140
|
+
}.merge(config[:chef_options]).merge(node_config.config[:chef_options])
|
92
141
|
|
93
142
|
puts "Uploading Chef files..."
|
94
|
-
Net::SCP.start ip,
|
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!
|
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,
|
110
|
-
ssh_exec ssh, "
|
111
|
-
ssh_exec ssh, "
|
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! "
|
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
|
-
|
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 #{
|
137
|
-
`knife client delete #{
|
175
|
+
`knife node delete #{chef_node} -y`
|
176
|
+
`knife client delete #{chef_node} -y`
|
138
177
|
|
139
178
|
puts "Destroying #{node_name}..."
|
140
|
-
|
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
|
-
`'#{
|
296
|
+
`sudo lxc-info -n '#{node_name}'`.include?("RUNNING")
|
245
297
|
end
|
246
298
|
|
247
|
-
def
|
248
|
-
|
299
|
+
def vm_frozen?(node_name)
|
300
|
+
`sudo lxc-info -n '#{node_name}'`.include?("FROZEN")
|
249
301
|
end
|
250
302
|
|
251
|
-
def
|
252
|
-
|
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
|
256
|
-
|
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 "
|
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 "
|
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
|
-
"
|
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}
|
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
|
-
:
|
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
|
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,
|
424
|
+
@config[:shares] << [share_name, guest_path, host_path, options]
|
365
425
|
end
|
366
426
|
|
367
427
|
def node_suffix(suffix)
|
368
|
-
@config[:
|
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:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
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:
|
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
|
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"
|