vagabond 0.1.0 → 0.1.2
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 +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
@@ -1,16 +1,43 @@
|
|
1
|
+
include_recipe 'lxc::install_dependencies'
|
2
|
+
|
3
|
+
cookbook_file '/usr/share/lxc/templates/lxc-centos' do
|
4
|
+
source 'lxc-centos'
|
5
|
+
mode 0755
|
6
|
+
end
|
1
7
|
|
2
8
|
node[:vagabond][:bases].each do |name, options|
|
9
|
+
|
10
|
+
next unless options[:enabled]
|
11
|
+
|
12
|
+
pkg_coms = [
|
13
|
+
'update -y -q',
|
14
|
+
'upgrade -y -q',
|
15
|
+
'install curl -y -q'
|
16
|
+
]
|
17
|
+
if(%w(debian ubuntu).include?(options[:template]))
|
18
|
+
pkg_man = 'apt-get'
|
19
|
+
elsif(%w(fedora centos).include?(options[:template]))
|
20
|
+
pkg_man = 'yum'
|
21
|
+
end
|
22
|
+
if(pkg_man)
|
23
|
+
pkg_coms.map! do |c|
|
24
|
+
"#{pkg_man} #{c}"
|
25
|
+
end
|
26
|
+
else
|
27
|
+
pkg_coms = []
|
28
|
+
end
|
3
29
|
|
4
30
|
lxc_container name do
|
5
31
|
template options[:template]
|
6
32
|
template_opts options[:template_options]
|
7
33
|
default_config false if options[:memory]
|
34
|
+
create_environment options[:environment] if options[:environment]
|
8
35
|
initialize_commands [
|
9
36
|
'rm -f /etc/sysctl.d/10-console-messages.conf',
|
10
37
|
'rm -f /etc/sysctl.d/10-ptrace.conf',
|
11
|
-
'rm -f /etc/sysctl.d/10-kernel-hardening.conf'
|
12
|
-
|
13
|
-
'curl -L https://www.opscode.com/chef/install.sh |
|
38
|
+
'rm -f /etc/sysctl.d/10-kernel-hardening.conf'
|
39
|
+
] + pkg_coms + [
|
40
|
+
'curl -L https://www.opscode.com/chef/install.sh | bash'
|
14
41
|
]
|
15
42
|
end
|
16
43
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Vagabond
|
2
|
+
module Helpers
|
3
|
+
private
|
4
|
+
def sudo
|
5
|
+
case @vagabondfile[:sudo]
|
6
|
+
when TrueClass
|
7
|
+
'sudo '
|
8
|
+
when String
|
9
|
+
"#{@vagabondfile[:sudo]} "
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def debug(s)
|
14
|
+
ui.info "#{ui.color('DEBUG:', :red, :bold)} #{s}" if Config[:debug]
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
require 'digest/sha2'
|
2
|
+
require 'vagabond/helpers'
|
2
3
|
|
3
4
|
module Vagabond
|
4
5
|
class InternalConfiguration
|
5
6
|
|
7
|
+
include Helpers
|
8
|
+
|
6
9
|
attr_reader :config
|
7
10
|
attr_reader :ui
|
8
11
|
|
@@ -58,21 +61,21 @@ module Vagabond
|
|
58
61
|
end
|
59
62
|
|
60
63
|
def write_dna_json
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
64
|
+
conf = Mash.new
|
65
|
+
@v_config.config[:boxes].map(&:last).map{|i| i[:template]}.compact.uniq.each do |t|
|
66
|
+
conf[t] = Mash.new(:enabled => true)
|
67
|
+
end
|
68
|
+
if(@v_config.config[:templates])
|
69
|
+
@v_config.config[:templates].each do |t|
|
70
|
+
conf[t] ||= Mash.new
|
71
|
+
conf[t].merge!(@v_config[:templates][t])
|
72
|
+
end
|
73
|
+
end
|
71
74
|
File.open(dna_path, 'w') do |file|
|
72
75
|
file.write(
|
73
76
|
JSON.dump(
|
74
77
|
:vagabond => {
|
75
|
-
:bases =>
|
78
|
+
:bases => conf
|
76
79
|
},
|
77
80
|
:run_list => %w(recipe[vagabond])
|
78
81
|
)
|
@@ -130,9 +133,11 @@ module Vagabond
|
|
130
133
|
end
|
131
134
|
|
132
135
|
def run_solo
|
133
|
-
ui.info 'Ensuring expected system state
|
136
|
+
ui.info ui.color('Ensuring expected system state (creating required template containers)', :yellow)
|
137
|
+
ui.info ui.color(' - This can take a while...', :yellow)
|
134
138
|
com = "#{Config[:sudo]}chef-solo -j #{File.join(store_path, 'dna.json')} -c #{File.join(store_path, 'solo.rb')}"
|
135
|
-
|
139
|
+
debug(com)
|
140
|
+
cmd = Mixlib::ShellOut.new(com, :timeout => 1200, :live_stream => Config[:debug])
|
136
141
|
cmd.run_command
|
137
142
|
cmd.error!
|
138
143
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'vagabond/helpers'
|
2
|
+
|
3
|
+
module Vagabond
|
4
|
+
class Knife
|
5
|
+
|
6
|
+
include Helpers
|
7
|
+
|
8
|
+
attr_reader :name_args
|
9
|
+
|
10
|
+
def initialize(name, name_args)
|
11
|
+
@name_args = name_args
|
12
|
+
@vagabondfile = Vagabondfile.new(Config[:vagabond_file])
|
13
|
+
Config[:disable_solo] = true
|
14
|
+
Config[:sudo] = sudo
|
15
|
+
Lxc.use_sudo = @vagabondfile[:sudo].nil? ? true : @vagabondfile[:sudo]
|
16
|
+
@internal_config = InternalConfiguration.new(@vagabondfile, nil)
|
17
|
+
unless(Config[:disable_local_server])
|
18
|
+
if(@vagabondfile[:local_chef_server] && @vagabondfile[:local_chef_server][:enabled])
|
19
|
+
srv = Lxc.new(@internal_config[:mappings][:server])
|
20
|
+
if(srv.running?)
|
21
|
+
Config[:knife_opts] = " -s https://#{srv.container_ip(10, true)}"
|
22
|
+
else
|
23
|
+
Config[:knife_opts] = ' -s https://no-local-server'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
def execute
|
31
|
+
exec("knife #{name_args.join(' ')} #{Config[:knife_opts]}")
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
data/lib/vagabond/server.rb
CHANGED
@@ -12,120 +12,85 @@ module Vagabond
|
|
12
12
|
@action = actions.shift
|
13
13
|
setup_ui
|
14
14
|
load_configurations
|
15
|
+
Config[:disable_auto_provision] = true
|
15
16
|
end
|
16
17
|
|
17
|
-
def
|
18
|
+
def stop
|
18
19
|
if(lxc.exists?)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
lxc.start
|
24
|
-
ui.info 'Server container has been started'
|
20
|
+
if(lxc.running?)
|
21
|
+
ui.info 'Shutting down Chef server container...'
|
22
|
+
lxc.shutdown
|
23
|
+
ui.info 'Chef server container shut down!'
|
25
24
|
else
|
26
|
-
ui.
|
25
|
+
ui.error 'Chef server container not currently running'
|
27
26
|
end
|
28
27
|
else
|
29
|
-
ui.
|
30
|
-
do_create
|
28
|
+
ui.error 'Chef server container has not been created'
|
31
29
|
end
|
32
30
|
end
|
33
31
|
|
34
|
-
def destroy
|
35
|
-
if(lxc.exists?)
|
36
|
-
ui.info 'Destroying Chef server container...'
|
37
|
-
do_destroy
|
38
|
-
else
|
39
|
-
ui.fatal 'No Chef server exists within this environment'
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def do_create
|
44
|
-
cmd = Mixlib::ShellOut.new("#{Config[:sudo]}lxc-clone -n #{generated_name} -o #{@base_template}")
|
45
|
-
cmd.run_command
|
46
|
-
cmd.error!
|
47
|
-
@lxc = Lxc.new(generated_name)
|
48
|
-
@internal_config[:mappings][name] = generated_name
|
49
|
-
@internal_config.save
|
50
|
-
ui.info "Chef Server container created!"
|
51
|
-
lxc.start
|
52
|
-
ui.info "Bootstrapping erchef..."
|
53
|
-
tem_file = File.expand_path(File.join(File.dirname(__FILE__), 'bootstraps/server.erb'))
|
54
|
-
com = "#{Config[:sudo]}knife bootstrap #{lxc.container_ip(10, true)} --template-file #{tem_file} -i /opt/hw-lxc-config/id_rsa"
|
55
|
-
cmd = Mixlib::ShellOut.new(com, :live_stream => STDOUT, :timeout => 1200)
|
56
|
-
cmd.run_command
|
57
|
-
cmd.error!
|
58
|
-
ui.info 'Chef Server has been created!'
|
59
|
-
auto_upload if vagabondfile[:local_chef_server][:auto_upload]
|
60
|
-
end
|
61
|
-
|
62
32
|
def auto_upload
|
63
33
|
ui.info 'Auto uploading all assets to local Chef server...'
|
64
34
|
upload_roles
|
65
35
|
upload_databags
|
66
36
|
upload_environments
|
67
37
|
upload_cookbooks
|
68
|
-
ui.info 'All assets uploaded
|
38
|
+
ui.info ui.color(' -> All assets uploaded!', :green)
|
69
39
|
end
|
70
40
|
|
71
41
|
def upload_roles
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
42
|
+
am_uploading('roles') do
|
43
|
+
com = "knife role from file #{File.join(base_dir, 'roles/*')} #{Config[:knife_opts]}"
|
44
|
+
debug(com)
|
45
|
+
cmd = Mixlib::ShellOut.new(com, :live_stream => Config[:debug])
|
46
|
+
cmd.run_command
|
47
|
+
cmd.error!
|
48
|
+
end
|
78
49
|
end
|
79
50
|
|
80
51
|
def upload_databags
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
52
|
+
am_uploading('data bags') do
|
53
|
+
Dir.glob(File.join(base_dir, "data_bags/*")).each do |b|
|
54
|
+
next if %w(. ..).include?(b)
|
55
|
+
coms = [
|
56
|
+
"knife data bag create #{File.basename(b)} #{Config[:knife_opts]}",
|
57
|
+
"knife data bag from file #{File.basename(b)} #{Config[:knife_opts]} --all"
|
58
|
+
].each do |com|
|
59
|
+
debug(com)
|
60
|
+
cmd = Mixlib::ShellOut.new(com, :live_stream => Config[:debug])
|
61
|
+
cmd.run_command
|
62
|
+
cmd.error!
|
63
|
+
end
|
91
64
|
end
|
92
65
|
end
|
93
|
-
ui.info "Data bags uploaded to local Chef server!"
|
94
66
|
end
|
95
67
|
|
96
68
|
def upload_environments
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
69
|
+
am_uploading('environments') do
|
70
|
+
com = "knife environment from file #{File.join(base_dir, 'environments/*')} #{Config[:knife_opts]}"
|
71
|
+
debug(com)
|
72
|
+
cmd = Mixlib::ShellOut.new(com, :live_stream => Config[:debug])
|
73
|
+
cmd.run_command
|
74
|
+
cmd.error!
|
75
|
+
end
|
103
76
|
end
|
104
77
|
|
105
78
|
def upload_cookbooks
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
79
|
+
am_uploading('cookbooks') do
|
80
|
+
if(vagabondfile[:local_chef_server][:berkshelf])
|
81
|
+
berks_upload
|
82
|
+
else
|
83
|
+
raw_upload
|
84
|
+
end
|
111
85
|
end
|
112
86
|
end
|
113
87
|
|
114
|
-
|
115
|
-
write_berks_config
|
116
|
-
com = "berks upload -c #{File.join(vagabond_dir, 'berks.json')}"
|
117
|
-
cmd = Mixlib::ShellOut.new(com)
|
118
|
-
cmd.run_command
|
119
|
-
cmd.error!
|
120
|
-
ui.info "Berks cookbook upload complete!"
|
121
|
-
end
|
88
|
+
private
|
122
89
|
|
123
|
-
def
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
cmd.error!
|
128
|
-
ui.info "Cookbook upload complete!"
|
90
|
+
def am_uploading(thing)
|
91
|
+
ui.info "#{ui.color('Local chef server:', :bold)} Uploading #{ui.color(thing, :green)}"
|
92
|
+
yield
|
93
|
+
ui.info ui.color(" -> UPLOADED #{thing.upcase}", :green)
|
129
94
|
end
|
130
95
|
|
131
96
|
def write_berks_config
|
@@ -154,5 +119,47 @@ module Vagabond
|
|
154
119
|
@_gn
|
155
120
|
end
|
156
121
|
|
122
|
+
def do_create
|
123
|
+
com = "#{Config[:sudo]}lxc-clone -n #{generated_name} -o #{@base_template}"
|
124
|
+
debug(com)
|
125
|
+
cmd = Mixlib::ShellOut.new(com, :live_stream => Config[:debug])
|
126
|
+
cmd.run_command
|
127
|
+
cmd.error!
|
128
|
+
@lxc = Lxc.new(generated_name)
|
129
|
+
@internal_config[:mappings][name] = generated_name
|
130
|
+
@internal_config.save
|
131
|
+
ui.info ui.color(' -> Chef Server container created!', :cyan)
|
132
|
+
lxc.start
|
133
|
+
ui.info ui.color(' -> Bootstrapping erchef...', :cyan)
|
134
|
+
tem_file = File.expand_path(File.join(File.dirname(__FILE__), 'bootstraps/server.erb'))
|
135
|
+
com = "#{Config[:sudo]}knife bootstrap #{lxc.container_ip(10, true)} --template-file #{tem_file} -i /opt/hw-lxc-config/id_rsa"
|
136
|
+
debug(com)
|
137
|
+
cmd = Mixlib::ShellOut.new(com, :live_stream => Config[:debug], :timeout => 1200)
|
138
|
+
cmd.run_command
|
139
|
+
cmd.error!
|
140
|
+
ui.info ui.color(' -> Chef Server CREATED!', :green)
|
141
|
+
Config[:knife_opts] = " --server-url https://#{lxc.container_ip(20, true)}"
|
142
|
+
auto_upload if vagabondfile[:local_chef_server][:auto_upload]
|
143
|
+
end
|
144
|
+
|
145
|
+
def berks_upload
|
146
|
+
write_berks_config
|
147
|
+
com = "berks upload -c #{File.join(vagabond_dir, 'berks.json')}"
|
148
|
+
debug(com)
|
149
|
+
cmd = Mixlib::ShellOut.new(com, :live_stream => Config[:debug])
|
150
|
+
cmd.run_command
|
151
|
+
cmd.error!
|
152
|
+
ui.info "Berks cookbook upload complete!"
|
153
|
+
end
|
154
|
+
|
155
|
+
def raw_upload
|
156
|
+
com = "knife cookbook upload#{Config[:knife_opts]} --all"
|
157
|
+
debug(com)
|
158
|
+
cmd = Mixlib::ShellOut.new(com, :live_stream => Config[:debug])
|
159
|
+
cmd.run_command
|
160
|
+
cmd.error!
|
161
|
+
ui.info "Cookbook upload complete!"
|
162
|
+
end
|
163
|
+
|
157
164
|
end
|
158
165
|
end
|
data/lib/vagabond/vagabond.rb
CHANGED
@@ -8,12 +8,15 @@ end
|
|
8
8
|
|
9
9
|
require 'vagabond/vagabondfile'
|
10
10
|
require 'vagabond/internal_configuration'
|
11
|
+
require 'vagabond/helpers'
|
11
12
|
require 'chef/knife/core/ui'
|
12
13
|
require File.join(File.dirname(__FILE__), 'cookbooks/lxc/libraries/lxc.rb')
|
13
14
|
|
14
15
|
module Vagabond
|
15
16
|
class Vagabond
|
16
17
|
|
18
|
+
include Helpers
|
19
|
+
|
17
20
|
class << self
|
18
21
|
attr_accessor :ui
|
19
22
|
end
|
@@ -55,29 +58,40 @@ module Vagabond
|
|
55
58
|
unless(Config[:disable_local_server])
|
56
59
|
if(@vagabondfile[:local_chef_server] && @vagabondfile[:local_chef_server][:enabled])
|
57
60
|
srv = Lxc.new(@internal_config[:mappings][:server])
|
58
|
-
|
61
|
+
if(srv.running?)
|
62
|
+
Config[:knife_opts] = " --server-url https://#{srv.container_ip(10, true)}"
|
63
|
+
else
|
64
|
+
ui.warn 'Local chef server is not currently running!' unless @action.to_sym == :status
|
65
|
+
Config[:knife_opts] = ' --server-url https://no-local-server'
|
66
|
+
end
|
59
67
|
end
|
60
68
|
end
|
61
69
|
end
|
62
70
|
|
71
|
+
protected
|
72
|
+
|
63
73
|
def setup_ui
|
64
|
-
Chef::Config[:color] =
|
74
|
+
Chef::Config[:color] = Config[:color]
|
65
75
|
@ui = Chef::Knife::UI.new(STDOUT, STDERR, STDIN, {})
|
66
76
|
self.class.ui = @ui
|
67
77
|
end
|
68
78
|
|
69
79
|
def validate!
|
70
80
|
if(name.to_s == 'server')
|
71
|
-
|
81
|
+
ui.fatal "Invalid name supplied: #{ui.color(name, :red)}"
|
82
|
+
ui.info ui.color(" -> Try: vagabond server #{@action}", :cyan)
|
83
|
+
exit -1
|
72
84
|
end
|
73
85
|
end
|
74
86
|
|
75
87
|
def execute
|
76
|
-
|
88
|
+
if(public_methods.include?(@action.to_sym))
|
89
|
+
send(@action)
|
90
|
+
else
|
91
|
+
ui.error "Invalid action received: #{@action}"
|
92
|
+
end
|
77
93
|
end
|
78
94
|
|
79
|
-
private
|
80
|
-
|
81
95
|
def generate_hash
|
82
96
|
Digest::MD5.hexdigest(@vagabondfile.path)
|
83
97
|
end
|
@@ -89,15 +103,6 @@ module Vagabond
|
|
89
103
|
end
|
90
104
|
end
|
91
105
|
|
92
|
-
def sudo
|
93
|
-
case @vagabondfile[:sudo]
|
94
|
-
when TrueClass
|
95
|
-
'sudo '
|
96
|
-
when String
|
97
|
-
"#{@vagabondfile[:sudo]} "
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
106
|
def base_dir
|
102
107
|
File.dirname(vagabondfile.path)
|
103
108
|
end
|