vagabond 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,2 +1,13 @@
1
+ ## v0.1.2
2
+ * Added support for centos guests
3
+ * Added new base templates for centos and debian
4
+ * Debugging output support
5
+ * Pretty CLI output
6
+ * Actual help output
7
+ * Improved status output
8
+ * SSH functionality to nodes
9
+ * Improved server functionality
10
+ * Other stuff I probably forgot
11
+
1
12
  ## v0.1.0
2
13
  * Initial release!
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Vagabond
2
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
3
+ * Issue: VMs are slow.
4
+ * Discovery: Linux has LXC, which is pretty cool.
5
+ * Helpful: LXCs can run different distributions.
6
6
  * Implementation: Vagabond
7
7
 
8
8
  Awesome
@@ -42,53 +42,116 @@ Hash you return. Heres a simple example:
42
42
 
43
43
  Pretty simple, right?
44
44
 
45
- ## Commands
46
-
47
- ```
48
- # create and provision
49
- $ vagabond up precise
45
+ ### Templates available
50
46
 
51
- # provision existing
52
- $ vagabond provision precise
47
+ Currently builtin templates:
53
48
 
54
- # freeze (pause) node
55
- $ vagabond freeze precise
49
+ * ubuntu_1204
50
+ * ubuntu_1210
51
+ * debian_6
52
+ * debian_7
53
+ * centos_58
54
+ * centos_63
55
+ * centos_64
56
56
 
57
- # thaw (unpause) node
58
- $ vagabond thaw node
59
-
60
- # destroy node
61
- $ vagabond destroy precise
57
+ ## Commands
62
58
 
63
- # status of defined nodes
64
- $ vagabond status [node]
59
+ Lots of commands. What to see them all? Just ask:
65
60
 
66
- # ssh to node
67
- $ vagabond ssh precise
61
+ ```
62
+ $ vagabond --help
63
+ Nodes:
64
+ vagabond create NODE [options]
65
+ vagabond destroy NODE [options]
66
+ vagabond freeze NODE [options]
67
+ vagabond provision NODE [options]
68
+ vagabond rebuild NODE [options]
69
+ vagabond ssh NODE [options]
70
+ vagabond start NODE [options]
71
+ vagabond status NODE [options]
72
+ vagabond thaw NODE [options]
73
+ vagabond up NODE [options]
74
+ Server:
75
+ vagabond server auto_upload [options]
76
+ vagabond server create [options]
77
+ vagabond server destroy [options]
78
+ vagabond server freeze [options]
79
+ vagabond server provision [options]
80
+ vagabond server rebuild [options]
81
+ vagabond server ssh [options]
82
+ vagabond server start [options]
83
+ vagabond server status [options]
84
+ vagabond server stop [options]
85
+ vagabond server thaw [options]
86
+ vagabond server up [options]
87
+ vagabond server upload_cookbooks [options]
88
+ vagabond server upload_databags [options]
89
+ vagabond server upload_environments [options]
90
+ vagabond server upload_roles [options]
91
+ Options:
92
+ --debug
93
+ --disable-auto-provision
94
+ --disable-local-server
95
+ --disable-configure
96
+ --force-configure
97
+ -f, --vagabond-file FILE
98
+ ```
68
99
 
69
100
  ## Local chef server?
70
101
 
71
102
  Yep, that's right. You can let vagabond set you up with a local chef
72
103
  server hanging out in a container, which all your vagabond nodes can
73
- then run against. Isolated building and test? You betcha!
104
+ then run against. Isolated building and testing? You betcha!
105
+
106
+ Server containers are isolated by project. This means you will have an
107
+ erchef instance running in an isolated container for every project the
108
+ local server option is enabled. It's just an important bit of information
109
+ to remember so you can make a mental note to stop or freeze it when not
110
+ in use. Or just let them run. What ever floats your boat.
111
+
112
+ ### Vagabond knife
74
113
 
75
- Server provides a superset of the commands available for regular
76
- vagabond nodes. They are accessed using:
114
+ Since you can have a local chef server running, it can also be helpful
115
+ to be able to actually interact with that server. Vagabond has commands
116
+ for doing bulk uploads of assets, but you can access it too with knife
117
+ to do isolated uploads, or to just do knifey things:
118
+
119
+ ```
120
+ vagabond knife SOME COOL KNIFE COMMAND
121
+ ```
77
122
 
78
- `$ vagabond server COMMAND`
123
+ This will just push the command into the local chef server.
79
124
 
80
125
  ## Important note
81
126
 
82
127
  Until namespaces hit Linux proper, vagabond `sudo`s its way around. You
83
128
  _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`.
129
+ do go that road, just turn off `sudo` in your Vagabond file by setting:
130
+
131
+ ```
132
+ :sudo => false
133
+ ```
134
+
135
+ Oh, and if you use `rvm` and would rather be using `rvmsudo` instead of
136
+ boring old `sudo`, you can do that to:
137
+
138
+ ```
139
+ :sudo => 'rvmsudo'
140
+ ```
86
141
 
87
142
  ## Extra note
88
143
 
89
144
  This is still very much in alpha testing phase. So if you find bugs, please
90
145
  report them!
91
146
 
147
+ ## Contributing
148
+
149
+ No hard and fast rules for contributing just preferences. I'm always happy to
150
+ get help making things better!
151
+
152
+ * Base updates and pull requests on the `develop` branch
153
+ * Please don't update core files like `version.rb` or `vagabond.gemspec`
154
+
92
155
  ## Infos
93
156
 
94
157
  * Repository: https://github.com/chrisroberts/vagabond
@@ -2,26 +2,27 @@ module Vagabond
2
2
  module Actions
3
3
  module Create
4
4
  def create
5
- create
5
+ if(lxc.exists?)
6
+ ui.warn "Node already exists: #{name}" unless name == 'server'
7
+ start
8
+ else
9
+ ui.info "#{ui.color('Vagabond:', :bold)} Creating #{ui.color(name, :green)}"
10
+ do_create
11
+ ui.info ui.color(' -> CREATED!', :green)
12
+ end
6
13
  end
7
14
 
8
15
  private
9
16
 
10
- # Lets get this out proper!
11
17
  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
18
+ com = "#{sudo}lxc-start-ephemeral -d -o #{config[:template]}"
19
+ debug(com)
20
+ c = Mixlib::ShellOut.new("#{com} && sleep 3", :live_stream => Config[:debug])
21
+ c.run_command
22
+ e_name = c.stdout.split("\n").last.split(' ').last.strip
23
+ @internal_config[:mappings][name] = e_name
24
+ @internal_config.save
25
+ @lxc = Lxc.new(e_name)
25
26
  end
26
27
 
27
28
  end
@@ -2,9 +2,13 @@ module Vagabond
2
2
  module Actions
3
3
  module Destroy
4
4
  def destroy
5
- ui.info "Destroying instance: #{name}..."
6
- do_destroy
7
- ui.info 'Complete!'
5
+ if(lxc.exists?)
6
+ ui.info "#{ui.color('Vagabond:', :bold)} Destroying node: #{ui.color(name, :red)}"
7
+ do_destroy
8
+ ui.info ui.color(' -> DESTROYED', :red)
9
+ else
10
+ ui.error "Node not created: #{name}"
11
+ end
8
12
  end
9
13
 
10
14
  private
@@ -12,18 +16,25 @@ module Vagabond
12
16
  def do_destroy
13
17
  lxc.stop if lxc.running?
14
18
  com = "#{Config[:sudo]}lxc-destroy -n #{lxc.name}"
15
- cmd = Mixlib::ShellOut.new(com)
19
+ debug(com)
20
+ cmd = Mixlib::ShellOut.new(com, :live_stream => Config[:debug])
16
21
  cmd.run_command
17
22
  cmd.error!
18
23
  if(cmd.stderr.include?('skipping'))
19
- ui.warn 'Failed to unmount some resource. Doing so manually'
24
+ ui.info ui.color(' -> Failed to unmount some resources. Forcing manually.', :yellow)
20
25
  %w(rootfs ephemeralbind).each do |mnt|
21
- cmd = Mixlib::ShellOut.new("#{Config[:sudo]}umount /var/lib/lxc/#{lxc.name}/#{mnt}")
26
+ com = "#{Config[:sudo]}umount /var/lib/lxc/#{lxc.name}/#{mnt}"
27
+ debug(com)
28
+ cmd = Mixlib::ShellOut.new(com, :live_stream => Config[:debug])
22
29
  cmd.run_command
23
- cmd = Mixlib::ShellOut.new("#{Config[:sudo]}lxc-destroy -n #{lxc.name}")
30
+ com = "#{Config[:sudo]}lxc-destroy -n #{lxc.name}"
31
+ debug(com)
32
+ cmd = Mixlib::ShellOut.new(com, :live_stream => Config[:debug])
24
33
  cmd.run_command
25
34
  cmd.error!
35
+ internal_config[:mappings].delete(name)
26
36
  end
37
+ internal_config.save
27
38
  end
28
39
  end
29
40
  end
@@ -2,11 +2,16 @@ module Vagabond
2
2
  module Actions
3
3
  module Freeze
4
4
  def freeze
5
- if(lxc.running?)
6
- lxc.freeze
7
- ui.info "Container has been frozen: #{name}"
5
+ if(lxc.exists?)
6
+ ui.info "#{ui.color('Vagabond:', :bold)} Freezing node: #{ui.color(name, :blue)}"
7
+ if(lxc.running?)
8
+ lxc.freeze
9
+ ui.info ui.color(' -> FROZEN', :blue)
10
+ else
11
+ ui.error "Node is not currently running: #{name}"
12
+ end
8
13
  else
9
- ui.error "Container #{name} is not currently running"
14
+ ui.error "Node not created: #{name}"
10
15
  end
11
16
  end
12
17
  end
@@ -2,28 +2,40 @@ module Vagabond
2
2
  module Actions
3
3
  module Provision
4
4
  def provision
5
- if(lxc.exists? && lxc.running?)
6
- do_provision
5
+ if(lxc.exists?)
6
+ if(lxc.running?)
7
+ do_provision
8
+ else
9
+ ui.error "Node is not currently running: #{name}"
10
+ end
7
11
  else
8
- ui.fatal "LXC: Requested container: #{name} has not been created!"
12
+ ui.error "Node not created: #{name}"
9
13
  end
10
14
  end
11
-
15
+
12
16
  private
13
17
 
14
18
  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 "
19
+ ui.info "#{ui.color('Vagabond:', :bold)} Provisioning node: #{ui.color(name, :magenta)}"
20
+ com = "sudo knife bootstrap #{lxc.container_ip(10, true)} -d chef-full -N #{name} -i /opt/hw-lxc-config/id_rsa "
17
21
  com << "--no-host-key-verify --run-list \"#{config[:run_list].join(',')}\" "
18
22
  if(config[:environment])
19
23
  com << "-E #{config[:environment]}"
20
24
  end
21
25
  if(Config[:knife_opts])
22
- com << Conifg[:knife_opts]
26
+ com << Config[:knife_opts]
23
27
  end
28
+ debug(com)
29
+ # Send the live stream out since people will generally want to
30
+ # know what's happening
24
31
  cmd = Mixlib::ShellOut.new(com, :live_stream => STDOUT)
25
32
  cmd.run_command
26
- @ui.info "LXC: Provisioning of #{name} complete!"
33
+ # NOTE: cmd.status.success? won't be valid, so check for FATAL
34
+ unless(cmd.stdout.split("\n").last.to_s.include?('FATAL'))
35
+ ui.info ui.color(' -> PROVISIONED', :magenta)
36
+ else
37
+ ui.info ui.color(' -> PROVISION FAILED', :red)
38
+ end
27
39
  end
28
40
 
29
41
  end
@@ -0,0 +1,18 @@
1
+ module Vagabond
2
+ module Actions
3
+ module Rebuild
4
+ def rebuild
5
+ ui.info "#{ui.color('Vagabond:', :bold)} Rebuilding #{ui.color(name, :blue)}"
6
+ destroy
7
+ @lxc = Lxc.new(name)
8
+ destroy
9
+ Config[:force_solo] = true
10
+ ui.info ui.color(' -> DESTROYED!', :red)
11
+ internal_config.run_solo
12
+ internal_config[:mappings].delete(name)
13
+ internal_config.save
14
+ ui.info ui.color(' -> REBUILT!', :green)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -2,10 +2,15 @@ module Vagabond
2
2
  module Actions
3
3
  module SSH
4
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")
5
+ if(lxc.exists?)
6
+ if(lxc.running?)
7
+ ui.info "#{ui.color('Vagabond:', :bold)} SSH connect to: #{ui.color(name, :cyan)}"
8
+ exec("#{Config[:sudo]}ssh root@#{lxc.container_ip(10, true)} -i /opt/hw-lxc-config/id_rsa -oStrictHostKeyChecking=no")
9
+ else
10
+ ui.error "Node not running: #{name}"
11
+ end
7
12
  else
8
- ui.error "Container #{name} is not currently running"
13
+ ui.error "Node not created: #{name}"
9
14
  end
10
15
  end
11
16
  end
@@ -0,0 +1,18 @@
1
+ module Vagabond
2
+ module Actions
3
+ module Start
4
+
5
+ def start
6
+ ui.info "#{ui.color('Vagabond:', :bold)} Starting node: #{ui.color(name, :green)}"
7
+ do_start
8
+ ui.info ui.color(' -> STARTED', :green)
9
+ end
10
+
11
+ protected
12
+
13
+ def do_start
14
+ lxc.start
15
+ end
16
+ end
17
+ end
18
+ end
@@ -2,6 +2,7 @@ module Vagabond
2
2
  module Actions
3
3
  module Status
4
4
  def status
5
+ ui.info ui.color("Vagabond node status:\n", :bold)
5
6
  if(name)
6
7
  status_for(name)
7
8
  else
@@ -11,18 +12,34 @@ module Vagabond
11
12
  end
12
13
  end
13
14
 
15
+ private
16
+
14
17
  def status_for(c_name)
15
18
  m_name = internal_config[:mappings][c_name]
19
+ state = nil
20
+ status = []
16
21
  if(Lxc.exists?(m_name))
22
+ @lxc = Lxc.new(m_name) unless lxc.name == m_name
17
23
  info = Lxc.info(m_name)
18
- status = info[:state].to_s
19
- if(info[:pid])
20
- status << " - PID: #{info[:pid]}"
21
- end
24
+ state = info[:state]
25
+ status << "PID: #{info[:pid] == -1 ? 'N/A' : info[:pid]}"
26
+ status << "Address: #{lxc.container_ip || 'unknown'}"
27
+ status << "\n"
28
+ end
29
+ case state
30
+ when :running
31
+ color = :green
32
+ when :frozen
33
+ color = :blue
34
+ when :stopped
35
+ color = :yellow
22
36
  else
23
- status = 'does not exist'
37
+ color = :red
38
+ end
39
+ ui.info ui.color(" #{c_name}: #{state || "Not currently created\n"}", color)
40
+ unless(status.empty?)
41
+ ui.info(status.map{|s| " #{s}"}.join("\n").chomp)
24
42
  end
25
- ui.info "Status of #{c_name}: #{status}"
26
43
  end
27
44
  end
28
45
  end
@@ -2,11 +2,16 @@ module Vagabond
2
2
  module Actions
3
3
  module Thaw
4
4
  def thaw
5
- if(lxc.frozen?)
6
- lxc.unfreeze
7
- ui.info "Container has been thawed: #{name}"
5
+ if(lxc.exists?)
6
+ if(lxc.frozen?)
7
+ ui.info "#{ui.color('Vagabond:', :bold)} Thawing node: #{ui.color(name, :yellow)}"
8
+ lxc.unfreeze
9
+ ui.info ui.color(' -> THAWED!', :yellow)
10
+ else
11
+ ui.error "Node is not currently frozen: #{name}"
12
+ end
8
13
  else
9
- ui.error "Container #{name} is not currently frozen"
14
+ ui.error "Node does not exist: #{name}"
10
15
  end
11
16
  end
12
17
  end