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 +11 -0
- data/README.md +90 -27
- data/lib/vagabond/actions/create.rb +16 -15
- data/lib/vagabond/actions/destroy.rb +18 -7
- data/lib/vagabond/actions/freeze.rb +9 -4
- data/lib/vagabond/actions/provision.rb +20 -8
- data/lib/vagabond/actions/rebuild.rb +18 -0
- data/lib/vagabond/actions/ssh.rb +8 -3
- data/lib/vagabond/actions/start.rb +18 -0
- data/lib/vagabond/actions/status.rb +23 -6
- data/lib/vagabond/actions/thaw.rb +9 -4
- data/lib/vagabond/actions/up.rb +10 -16
- data/lib/vagabond/commands.rb +40 -11
- data/lib/vagabond/cookbooks/lxc/libraries/lxc.rb +57 -25
- data/lib/vagabond/cookbooks/lxc/providers/container.rb +1 -0
- data/lib/vagabond/cookbooks/lxc/resources/container.rb +1 -0
- data/lib/vagabond/cookbooks/vagabond/attributes/default.rb +10 -0
- data/lib/vagabond/cookbooks/vagabond/files/default/lxc-centos +453 -0
- data/lib/vagabond/cookbooks/vagabond/recipes/default.rb +30 -3
- data/lib/vagabond/helpers.rb +18 -0
- data/lib/vagabond/internal_configuration.rb +18 -13
- data/lib/vagabond/knife.rb +36 -0
- data/lib/vagabond/server.rb +88 -81
- data/lib/vagabond/vagabond.rb +20 -15
- data/lib/vagabond/version.rb +1 -1
- data/vagabond-0.1.0.gem +0 -0
- metadata +8 -3
- data/lib/vagabond/cookbooks/vagabond/recipes/create.rb +0 -3
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.
|
4
|
-
* Discovery: Linux
|
5
|
-
* Helpful: LXCs can
|
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
|
-
|
46
|
-
|
47
|
-
```
|
48
|
-
# create and provision
|
49
|
-
$ vagabond up precise
|
45
|
+
### Templates available
|
50
46
|
|
51
|
-
|
52
|
-
$ vagabond provision precise
|
47
|
+
Currently builtin templates:
|
53
48
|
|
54
|
-
|
55
|
-
|
49
|
+
* ubuntu_1204
|
50
|
+
* ubuntu_1210
|
51
|
+
* debian_6
|
52
|
+
* debian_7
|
53
|
+
* centos_58
|
54
|
+
* centos_63
|
55
|
+
* centos_64
|
56
56
|
|
57
|
-
|
58
|
-
$ vagabond thaw node
|
59
|
-
|
60
|
-
# destroy node
|
61
|
-
$ vagabond destroy precise
|
57
|
+
## Commands
|
62
58
|
|
63
|
-
|
64
|
-
$ vagabond status [node]
|
59
|
+
Lots of commands. What to see them all? Just ask:
|
65
60
|
|
66
|
-
|
67
|
-
$ vagabond
|
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
|
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
|
-
|
76
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
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.
|
24
|
+
ui.info ui.color(' -> Failed to unmount some resources. Forcing manually.', :yellow)
|
20
25
|
%w(rootfs ephemeralbind).each do |mnt|
|
21
|
-
|
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
|
-
|
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.
|
6
|
-
|
7
|
-
|
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 "
|
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?
|
6
|
-
|
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.
|
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
|
-
|
16
|
-
com = "
|
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 <<
|
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
|
-
|
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
|
data/lib/vagabond/actions/ssh.rb
CHANGED
@@ -2,10 +2,15 @@ module Vagabond
|
|
2
2
|
module Actions
|
3
3
|
module SSH
|
4
4
|
def ssh
|
5
|
-
if(lxc.
|
6
|
-
|
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 "
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
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.
|
6
|
-
lxc.
|
7
|
-
|
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 "
|
14
|
+
ui.error "Node does not exist: #{name}"
|
10
15
|
end
|
11
16
|
end
|
12
17
|
end
|