vagabond 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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