vagabond 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/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
|