vagabond 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +2 -0
- data/README.md +94 -0
- data/bin/vagabond +6 -0
- data/lib/vagabond.rb +1 -0
- data/lib/vagabond/actions/create.rb +29 -0
- data/lib/vagabond/actions/destroy.rb +31 -0
- data/lib/vagabond/actions/freeze.rb +14 -0
- data/lib/vagabond/actions/provision.rb +31 -0
- data/lib/vagabond/actions/ssh.rb +13 -0
- data/lib/vagabond/actions/status.rb +29 -0
- data/lib/vagabond/actions/thaw.rb +14 -0
- data/lib/vagabond/actions/up.rb +27 -0
- data/lib/vagabond/bootstraps/server.erb +62 -0
- data/lib/vagabond/commands.rb +58 -0
- data/lib/vagabond/config.rb +7 -0
- data/lib/vagabond/cookbooks/lxc/CHANGELOG.md +21 -0
- data/lib/vagabond/cookbooks/lxc/Gemfile +3 -0
- data/lib/vagabond/cookbooks/lxc/Gemfile.lock +132 -0
- data/lib/vagabond/cookbooks/lxc/README.md +83 -0
- data/lib/vagabond/cookbooks/lxc/attributes/default.rb +26 -0
- data/lib/vagabond/cookbooks/lxc/files/default/knife_lxc +228 -0
- data/lib/vagabond/cookbooks/lxc/libraries/lxc.rb +279 -0
- data/lib/vagabond/cookbooks/lxc/libraries/lxc_expanded_resources.rb +40 -0
- data/lib/vagabond/cookbooks/lxc/libraries/lxc_file_config.rb +81 -0
- data/lib/vagabond/cookbooks/lxc/metadata.rb +11 -0
- data/lib/vagabond/cookbooks/lxc/providers/config.rb +82 -0
- data/lib/vagabond/cookbooks/lxc/providers/container.rb +342 -0
- data/lib/vagabond/cookbooks/lxc/providers/fstab.rb +71 -0
- data/lib/vagabond/cookbooks/lxc/providers/interface.rb +99 -0
- data/lib/vagabond/cookbooks/lxc/providers/service.rb +53 -0
- data/lib/vagabond/cookbooks/lxc/recipes/containers.rb +13 -0
- data/lib/vagabond/cookbooks/lxc/recipes/default.rb +45 -0
- data/lib/vagabond/cookbooks/lxc/recipes/install_dependencies.rb +15 -0
- data/lib/vagabond/cookbooks/lxc/recipes/knife.rb +37 -0
- data/lib/vagabond/cookbooks/lxc/resources/#container.rb# +28 -0
- data/lib/vagabond/cookbooks/lxc/resources/config.rb +19 -0
- data/lib/vagabond/cookbooks/lxc/resources/container.rb +28 -0
- data/lib/vagabond/cookbooks/lxc/resources/fstab.rb +11 -0
- data/lib/vagabond/cookbooks/lxc/resources/interface.rb +10 -0
- data/lib/vagabond/cookbooks/lxc/resources/service.rb +5 -0
- data/lib/vagabond/cookbooks/lxc/templates/default/client.rb.erb +13 -0
- data/lib/vagabond/cookbooks/lxc/templates/default/default-lxc.erb +3 -0
- data/lib/vagabond/cookbooks/lxc/templates/default/fstab.erb +5 -0
- data/lib/vagabond/cookbooks/lxc/templates/default/interface.erb +21 -0
- data/lib/vagabond/cookbooks/lxc/test/kitchen/Kitchenfile +7 -0
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/metadata.rb +2 -0
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/centos_lxc.rb +0 -0
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/chef-bootstrap.rb +0 -0
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/lxc_files.rb +0 -0
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/lxc_templates.rb +0 -0
- data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/ubuntu_lxc.rb +0 -0
- data/lib/vagabond/cookbooks/vagabond/attributes/default.rb +2 -0
- data/lib/vagabond/cookbooks/vagabond/libraries/vagabond.rb +10 -0
- data/lib/vagabond/cookbooks/vagabond/metadata.rb +6 -0
- data/lib/vagabond/cookbooks/vagabond/recipes/create.rb +3 -0
- data/lib/vagabond/cookbooks/vagabond/recipes/default.rb +30 -0
- data/lib/vagabond/internal_configuration.rb +147 -0
- data/lib/vagabond/server.rb +158 -0
- data/lib/vagabond/vagabond.rb +109 -0
- data/lib/vagabond/vagabondfile.rb +34 -0
- data/lib/vagabond/version.rb +10 -0
- data/vagabond.gemspec +18 -0
- metadata +125 -0
data/CHANGELOG.md
ADDED
data/README.md
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# Vagabond
|
2
|
+
|
3
|
+
* Issue: VMs are slow. Especially when creating over and over.
|
4
|
+
* Discovery: Linux provides LXC tools similar to BSD jails
|
5
|
+
* Helpful: LXCs can provide different distributions
|
6
|
+
* Implementation: Vagabond
|
7
|
+
|
8
|
+
Awesome
|
9
|
+
|
10
|
+
## What is this thing?
|
11
|
+
|
12
|
+
Vagabond is a tool integrated with Chef to build local nodes
|
13
|
+
easily and most importantly, quickly. It uses Linux containers
|
14
|
+
instead of full blown VMs which means things are faster. Lots
|
15
|
+
faster.
|
16
|
+
|
17
|
+
## How it is?
|
18
|
+
|
19
|
+
Currently, this is built to run within a classic Chef repository.
|
20
|
+
It requires a Vagabond file, that simply outputs a Hash. The file
|
21
|
+
is Ruby though, so you can do lots of crazy stuff to build the
|
22
|
+
Hash you return. Heres a simple example:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
{
|
26
|
+
:boxes => {
|
27
|
+
:precise => {
|
28
|
+
:template => 'ubuntu_1204',
|
29
|
+
:run_list => %w(role[base])
|
30
|
+
},
|
31
|
+
:db => {
|
32
|
+
:template => 'ubuntu_1204',
|
33
|
+
:run_list => %w(role[db])
|
34
|
+
}
|
35
|
+
},
|
36
|
+
:local_chef_server => {
|
37
|
+
:enabled => true,
|
38
|
+
:auto_upload => true
|
39
|
+
}
|
40
|
+
}
|
41
|
+
```
|
42
|
+
|
43
|
+
Pretty simple, right?
|
44
|
+
|
45
|
+
## Commands
|
46
|
+
|
47
|
+
```
|
48
|
+
# create and provision
|
49
|
+
$ vagabond up precise
|
50
|
+
|
51
|
+
# provision existing
|
52
|
+
$ vagabond provision precise
|
53
|
+
|
54
|
+
# freeze (pause) node
|
55
|
+
$ vagabond freeze precise
|
56
|
+
|
57
|
+
# thaw (unpause) node
|
58
|
+
$ vagabond thaw node
|
59
|
+
|
60
|
+
# destroy node
|
61
|
+
$ vagabond destroy precise
|
62
|
+
|
63
|
+
# status of defined nodes
|
64
|
+
$ vagabond status [node]
|
65
|
+
|
66
|
+
# ssh to node
|
67
|
+
$ vagabond ssh precise
|
68
|
+
|
69
|
+
## Local chef server?
|
70
|
+
|
71
|
+
Yep, that's right. You can let vagabond set you up with a local chef
|
72
|
+
server hanging out in a container, which all your vagabond nodes can
|
73
|
+
then run against. Isolated building and test? You betcha!
|
74
|
+
|
75
|
+
Server provides a superset of the commands available for regular
|
76
|
+
vagabond nodes. They are accessed using:
|
77
|
+
|
78
|
+
`$ vagabond server COMMAND`
|
79
|
+
|
80
|
+
## Important note
|
81
|
+
|
82
|
+
Until namespaces hit Linux proper, vagabond `sudo`s its way around. You
|
83
|
+
_can_ get around this using the setcap stuff, but it's pretty meh. If you
|
84
|
+
do go that road, just turn off `sudo` in your Vagabond file by setting
|
85
|
+
`:sudo => false`.
|
86
|
+
|
87
|
+
## Extra note
|
88
|
+
|
89
|
+
This is still very much in alpha testing phase. So if you find bugs, please
|
90
|
+
report them!
|
91
|
+
|
92
|
+
## Infos
|
93
|
+
|
94
|
+
* Repository: https://github.com/chrisroberts/vagabond
|
data/bin/vagabond
ADDED
data/lib/vagabond.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'vagabond/version'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Vagabond
|
2
|
+
module Actions
|
3
|
+
module Create
|
4
|
+
def create
|
5
|
+
create
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# Lets get this out proper!
|
11
|
+
def do_create
|
12
|
+
unless(check_existing!)
|
13
|
+
@ui.info "LXC: Creating #{name}..."
|
14
|
+
com = "#{sudo}lxc-start-ephemeral -d -o #{config[:template]}"
|
15
|
+
c = Mixlib::ShellOut.new("#{com} && sleep 3")
|
16
|
+
c.run_command
|
17
|
+
e_name = c.stdout.split("\n").last.split(' ').last.strip
|
18
|
+
@internal_config[:mappings][name] = e_name
|
19
|
+
@internal_config.save
|
20
|
+
@lxc = Lxc.new(e_name)
|
21
|
+
@ui.info "LXC: #{name} has been created!"
|
22
|
+
else
|
23
|
+
lxc.start unless lxc.running?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Vagabond
|
2
|
+
module Actions
|
3
|
+
module Destroy
|
4
|
+
def destroy
|
5
|
+
ui.info "Destroying instance: #{name}..."
|
6
|
+
do_destroy
|
7
|
+
ui.info 'Complete!'
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def do_destroy
|
13
|
+
lxc.stop if lxc.running?
|
14
|
+
com = "#{Config[:sudo]}lxc-destroy -n #{lxc.name}"
|
15
|
+
cmd = Mixlib::ShellOut.new(com)
|
16
|
+
cmd.run_command
|
17
|
+
cmd.error!
|
18
|
+
if(cmd.stderr.include?('skipping'))
|
19
|
+
ui.warn 'Failed to unmount some resource. Doing so manually'
|
20
|
+
%w(rootfs ephemeralbind).each do |mnt|
|
21
|
+
cmd = Mixlib::ShellOut.new("#{Config[:sudo]}umount /var/lib/lxc/#{lxc.name}/#{mnt}")
|
22
|
+
cmd.run_command
|
23
|
+
cmd = Mixlib::ShellOut.new("#{Config[:sudo]}lxc-destroy -n #{lxc.name}")
|
24
|
+
cmd.run_command
|
25
|
+
cmd.error!
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Vagabond
|
2
|
+
module Actions
|
3
|
+
module Provision
|
4
|
+
def provision
|
5
|
+
if(lxc.exists? && lxc.running?)
|
6
|
+
do_provision
|
7
|
+
else
|
8
|
+
ui.fatal "LXC: Requested container: #{name} has not been created!"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def do_provision
|
15
|
+
@ui.info "LXC: Provisioning #{name}..."
|
16
|
+
com = "#{sudo}knife bootstrap #{lxc.container_ip(10, true)} -d chef-full -N #{name} -i /opt/hw-lxc-config/id_rsa "
|
17
|
+
com << "--no-host-key-verify --run-list \"#{config[:run_list].join(',')}\" "
|
18
|
+
if(config[:environment])
|
19
|
+
com << "-E #{config[:environment]}"
|
20
|
+
end
|
21
|
+
if(Config[:knife_opts])
|
22
|
+
com << Conifg[:knife_opts]
|
23
|
+
end
|
24
|
+
cmd = Mixlib::ShellOut.new(com, :live_stream => STDOUT)
|
25
|
+
cmd.run_command
|
26
|
+
@ui.info "LXC: Provisioning of #{name} complete!"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Vagabond
|
2
|
+
module Actions
|
3
|
+
module SSH
|
4
|
+
def ssh
|
5
|
+
if(lxc.running?)
|
6
|
+
exec("#{Config[:sudo]}ssh root@#{lxc.container_ip(10, true)} -i /opt/hw-lxc-config/id_rsa -oStrictHostKeyChecking=no")
|
7
|
+
else
|
8
|
+
ui.error "Container #{name} is not currently running"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Vagabond
|
2
|
+
module Actions
|
3
|
+
module Status
|
4
|
+
def status
|
5
|
+
if(name)
|
6
|
+
status_for(name)
|
7
|
+
else
|
8
|
+
(Array(vagabondfile[:boxes].keys) | Array(internal_config[:mappings].keys)).sort.each do |n|
|
9
|
+
status_for(n)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def status_for(c_name)
|
15
|
+
m_name = internal_config[:mappings][c_name]
|
16
|
+
if(Lxc.exists?(m_name))
|
17
|
+
info = Lxc.info(m_name)
|
18
|
+
status = info[:state].to_s
|
19
|
+
if(info[:pid])
|
20
|
+
status << " - PID: #{info[:pid]}"
|
21
|
+
end
|
22
|
+
else
|
23
|
+
status = 'does not exist'
|
24
|
+
end
|
25
|
+
ui.info "Status of #{c_name}: #{status}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Vagabond
|
2
|
+
module Actions
|
3
|
+
module Up
|
4
|
+
def up
|
5
|
+
if(@lxc.exists?)
|
6
|
+
ui.warn "Existing container found for: #{name}. Starting..."
|
7
|
+
do_start
|
8
|
+
else
|
9
|
+
do_start
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def do_start
|
16
|
+
if(lxc.running?)
|
17
|
+
ui.error "LXC: #{name} is already running!"
|
18
|
+
else
|
19
|
+
do_create
|
20
|
+
ui.info "LXC: #{name} has been started!"
|
21
|
+
do_provision unless Config[:disable_auto_provision]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
bash -c '
|
2
|
+
|
3
|
+
apt-get install -y -q wget
|
4
|
+
curl -L https://www.opscode.com/chef/install.sh | sudo bash
|
5
|
+
mkdir -p /var/chef/cache /var/chef/cookbooks/chef-server /var/chef/cookbooks/chef-server-populator
|
6
|
+
wget -qO- https://github.com/opscode-cookbooks/chef-server/archive/master.tar.gz | tar xvzC /var/chef/cookbooks/chef-server --strip-components=1
|
7
|
+
wget -qO- https://github.com/hw-cookbooks/chef-server-populator/tarball/master | tar xvzC /var/chef/cookbooks/chef-server-populator --strip-components=1
|
8
|
+
|
9
|
+
mkdir -p /tmp/chef-server-setup
|
10
|
+
(
|
11
|
+
cat <<'EOP'
|
12
|
+
<%= IO.read(Chef::Config[:validation_key]) %>
|
13
|
+
EOP
|
14
|
+
) > /tmp/chef-server-setup/validation.pem
|
15
|
+
(
|
16
|
+
cat <<'EOP'
|
17
|
+
<%= %x{openssl rsa -in #{Chef::Config[:validation_key]} -pubout} %>
|
18
|
+
EOP
|
19
|
+
) > /tmp/chef-server-setup/validation_pub.pem
|
20
|
+
(
|
21
|
+
cat <<'EOP'
|
22
|
+
<%= %x{openssl rsa -in #{Chef::Config[:client_key]} -pubout} %>
|
23
|
+
EOP
|
24
|
+
) > /tmp/chef-server-setup/client_key_pub.pem
|
25
|
+
|
26
|
+
mkdir -p /etc/chef
|
27
|
+
cp /tmp/chef-server-setup/validation.pem /etc/chef/validation.pem
|
28
|
+
chmod 600 /etc/chef/validation.pem
|
29
|
+
|
30
|
+
IPADDR=`ip addr show eth0 | grep "inet " | awk -F" " '\''{print $2}'\'' | sed -e "s/\/24//"`
|
31
|
+
(
|
32
|
+
echo "
|
33
|
+
{
|
34
|
+
\"chef-server\": {
|
35
|
+
\"configuration\": {
|
36
|
+
\"chef_server_webui\": {
|
37
|
+
\"enable\": false
|
38
|
+
}
|
39
|
+
}
|
40
|
+
},
|
41
|
+
\"chef_server_populator\": {
|
42
|
+
\"clients\": {
|
43
|
+
\"<%= Chef::Config[:node_name] %>\": \"client_key_pub.pem\",
|
44
|
+
\"<%= Chef::Config[:validation_client_name] %>\": \"validation_pub.pem\"
|
45
|
+
},
|
46
|
+
\"servername_override\": \"${IPADDR}\",
|
47
|
+
\"base_path\": \"/tmp/chef-server-setup\"
|
48
|
+
},
|
49
|
+
\"run_list\": [ \"recipe[chef-server-populator::solo]\", \"recipe[chef-server]\" ]
|
50
|
+
}
|
51
|
+
"
|
52
|
+
) > /tmp/chef-server.json
|
53
|
+
|
54
|
+
chef-solo -j /tmp/chef-server.json
|
55
|
+
|
56
|
+
rm -rf /tmp/chef-server-setup
|
57
|
+
|
58
|
+
echo "**********************************************"
|
59
|
+
echo "* NOTE: Update chef_server_url in knife.rb! *"
|
60
|
+
echo "* IP: ${IPADDR} *"
|
61
|
+
echo "**********************************************"
|
62
|
+
'
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'mixlib/cli'
|
2
|
+
require 'vagabond/config'
|
3
|
+
require 'vagabond/vagabond'
|
4
|
+
require 'vagabond/server'
|
5
|
+
|
6
|
+
module Vagabond
|
7
|
+
class Commands
|
8
|
+
|
9
|
+
include Mixlib::CLI
|
10
|
+
|
11
|
+
VALID_COMMANDS = %w(
|
12
|
+
up destroy provision status freeze thaw ssh server
|
13
|
+
)
|
14
|
+
|
15
|
+
option(:force_solo,
|
16
|
+
:long => '--force-solo',
|
17
|
+
:boolean => true,
|
18
|
+
:default => false
|
19
|
+
)
|
20
|
+
|
21
|
+
option(:disable_solo,
|
22
|
+
:long => '--disable-solo',
|
23
|
+
:boolean => true,
|
24
|
+
:default => false
|
25
|
+
)
|
26
|
+
|
27
|
+
option(:disable_auto_provision,
|
28
|
+
:long => '--disable-auto-provision',
|
29
|
+
:boolean => true,
|
30
|
+
:default => false
|
31
|
+
)
|
32
|
+
|
33
|
+
option(:vagabond_file,
|
34
|
+
:short => '-f FILE',
|
35
|
+
:long => '--vagabond-file FILE'
|
36
|
+
)
|
37
|
+
|
38
|
+
option(:disable_local_server,
|
39
|
+
:long => '--disable-local-server',
|
40
|
+
:boolean => true,
|
41
|
+
:default => false
|
42
|
+
)
|
43
|
+
|
44
|
+
def run!(argv)
|
45
|
+
parse_options
|
46
|
+
name_args = parse_options(argv)
|
47
|
+
unless(VALID_COMMANDS.include?(name_args.first))
|
48
|
+
raise ArgumentError.new('Invalid command provided!')
|
49
|
+
end
|
50
|
+
Config.merge!(config)
|
51
|
+
if(name_args.first.to_s == 'server')
|
52
|
+
Server.new(name_args.shift, name_args).execute
|
53
|
+
else
|
54
|
+
Vagabond.new(name_args.shift, name_args).execute
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|