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.
Files changed (63) hide show
  1. data/CHANGELOG.md +2 -0
  2. data/README.md +94 -0
  3. data/bin/vagabond +6 -0
  4. data/lib/vagabond.rb +1 -0
  5. data/lib/vagabond/actions/create.rb +29 -0
  6. data/lib/vagabond/actions/destroy.rb +31 -0
  7. data/lib/vagabond/actions/freeze.rb +14 -0
  8. data/lib/vagabond/actions/provision.rb +31 -0
  9. data/lib/vagabond/actions/ssh.rb +13 -0
  10. data/lib/vagabond/actions/status.rb +29 -0
  11. data/lib/vagabond/actions/thaw.rb +14 -0
  12. data/lib/vagabond/actions/up.rb +27 -0
  13. data/lib/vagabond/bootstraps/server.erb +62 -0
  14. data/lib/vagabond/commands.rb +58 -0
  15. data/lib/vagabond/config.rb +7 -0
  16. data/lib/vagabond/cookbooks/lxc/CHANGELOG.md +21 -0
  17. data/lib/vagabond/cookbooks/lxc/Gemfile +3 -0
  18. data/lib/vagabond/cookbooks/lxc/Gemfile.lock +132 -0
  19. data/lib/vagabond/cookbooks/lxc/README.md +83 -0
  20. data/lib/vagabond/cookbooks/lxc/attributes/default.rb +26 -0
  21. data/lib/vagabond/cookbooks/lxc/files/default/knife_lxc +228 -0
  22. data/lib/vagabond/cookbooks/lxc/libraries/lxc.rb +279 -0
  23. data/lib/vagabond/cookbooks/lxc/libraries/lxc_expanded_resources.rb +40 -0
  24. data/lib/vagabond/cookbooks/lxc/libraries/lxc_file_config.rb +81 -0
  25. data/lib/vagabond/cookbooks/lxc/metadata.rb +11 -0
  26. data/lib/vagabond/cookbooks/lxc/providers/config.rb +82 -0
  27. data/lib/vagabond/cookbooks/lxc/providers/container.rb +342 -0
  28. data/lib/vagabond/cookbooks/lxc/providers/fstab.rb +71 -0
  29. data/lib/vagabond/cookbooks/lxc/providers/interface.rb +99 -0
  30. data/lib/vagabond/cookbooks/lxc/providers/service.rb +53 -0
  31. data/lib/vagabond/cookbooks/lxc/recipes/containers.rb +13 -0
  32. data/lib/vagabond/cookbooks/lxc/recipes/default.rb +45 -0
  33. data/lib/vagabond/cookbooks/lxc/recipes/install_dependencies.rb +15 -0
  34. data/lib/vagabond/cookbooks/lxc/recipes/knife.rb +37 -0
  35. data/lib/vagabond/cookbooks/lxc/resources/#container.rb# +28 -0
  36. data/lib/vagabond/cookbooks/lxc/resources/config.rb +19 -0
  37. data/lib/vagabond/cookbooks/lxc/resources/container.rb +28 -0
  38. data/lib/vagabond/cookbooks/lxc/resources/fstab.rb +11 -0
  39. data/lib/vagabond/cookbooks/lxc/resources/interface.rb +10 -0
  40. data/lib/vagabond/cookbooks/lxc/resources/service.rb +5 -0
  41. data/lib/vagabond/cookbooks/lxc/templates/default/client.rb.erb +13 -0
  42. data/lib/vagabond/cookbooks/lxc/templates/default/default-lxc.erb +3 -0
  43. data/lib/vagabond/cookbooks/lxc/templates/default/fstab.erb +5 -0
  44. data/lib/vagabond/cookbooks/lxc/templates/default/interface.erb +21 -0
  45. data/lib/vagabond/cookbooks/lxc/test/kitchen/Kitchenfile +7 -0
  46. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/metadata.rb +2 -0
  47. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/centos_lxc.rb +0 -0
  48. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/chef-bootstrap.rb +0 -0
  49. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/lxc_files.rb +0 -0
  50. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/lxc_templates.rb +0 -0
  51. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/ubuntu_lxc.rb +0 -0
  52. data/lib/vagabond/cookbooks/vagabond/attributes/default.rb +2 -0
  53. data/lib/vagabond/cookbooks/vagabond/libraries/vagabond.rb +10 -0
  54. data/lib/vagabond/cookbooks/vagabond/metadata.rb +6 -0
  55. data/lib/vagabond/cookbooks/vagabond/recipes/create.rb +3 -0
  56. data/lib/vagabond/cookbooks/vagabond/recipes/default.rb +30 -0
  57. data/lib/vagabond/internal_configuration.rb +147 -0
  58. data/lib/vagabond/server.rb +158 -0
  59. data/lib/vagabond/vagabond.rb +109 -0
  60. data/lib/vagabond/vagabondfile.rb +34 -0
  61. data/lib/vagabond/version.rb +10 -0
  62. data/vagabond.gemspec +18 -0
  63. metadata +125 -0
data/CHANGELOG.md ADDED
@@ -0,0 +1,2 @@
1
+ ## v0.1.0
2
+ * Initial release!
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
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'vagabond/commands'
5
+
6
+ Vagabond::Commands.new.run!(ARGV)
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,14 @@
1
+ module Vagabond
2
+ module Actions
3
+ module Freeze
4
+ def freeze
5
+ if(lxc.running?)
6
+ lxc.freeze
7
+ ui.info "Container has been frozen: #{name}"
8
+ else
9
+ ui.error "Container #{name} is not currently running"
10
+ end
11
+ end
12
+ end
13
+ end
14
+ 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,14 @@
1
+ module Vagabond
2
+ module Actions
3
+ module Thaw
4
+ def thaw
5
+ if(lxc.frozen?)
6
+ lxc.unfreeze
7
+ ui.info "Container has been thawed: #{name}"
8
+ else
9
+ ui.error "Container #{name} is not currently frozen"
10
+ end
11
+ end
12
+ end
13
+ end
14
+ 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
@@ -0,0 +1,7 @@
1
+ require 'mixlib/config'
2
+
3
+ module Vagabond
4
+ class Config
5
+ extend Mixlib::Config
6
+ end
7
+ end