vagabund 0.0.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +32 -0
- data/Gemfile +13 -0
- data/README.md +301 -0
- data/Rakefile +1 -0
- data/Vagrantfile +50 -0
- data/lib/monkey_patches.rb +16 -0
- data/lib/vagabund/boxer/command.rb +202 -0
- data/lib/vagabund/boxer.rb +4 -0
- data/lib/vagabund/settler/config.rb +49 -0
- data/lib/vagabund/settler/errors.rb +48 -0
- data/lib/vagabund/settler/packages/base.rb +215 -0
- data/lib/vagabund/settler/packages/config.rb +39 -0
- data/lib/vagabund/settler/packages/package_config.rb +118 -0
- data/lib/vagabund/settler/packages.rb +101 -0
- data/lib/vagabund/settler/projects/base.rb +120 -0
- data/lib/vagabund/settler/projects/config.rb +51 -0
- data/lib/vagabund/settler/projects/project_config.rb +123 -0
- data/lib/vagabund/settler/projects/rails.rb +8 -0
- data/lib/vagabund/settler/projects/ruby.rb +38 -0
- data/lib/vagabund/settler/projects.rb +19 -0
- data/lib/vagabund/settler/provisioner.rb +34 -0
- data/lib/vagabund/settler/sources/git.rb +59 -0
- data/lib/vagabund/settler/sources/local.rb +28 -0
- data/lib/vagabund/settler/sources/url.rb +37 -0
- data/lib/vagabund/settler/sources.rb +10 -0
- data/lib/vagabund/settler.rb +4 -0
- data/lib/vagabund/squatter/config.rb +36 -0
- data/lib/vagabund/squatter/provisioner.rb +199 -0
- data/lib/vagabund/squatter/user.rb +56 -0
- data/lib/vagabund/squatter.rb +4 -0
- data/lib/vagabund/version.rb +3 -0
- data/lib/vagabund.rb +45 -0
- data/templates/locales/en.yml +15 -0
- data/vagabund.gemspec +24 -0
- metadata +121 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
module Vagabund
|
2
|
+
module Settler
|
3
|
+
module Errors
|
4
|
+
class SettlerError < Vagrant::Errors::VagrantError
|
5
|
+
attr_reader :original_error
|
6
|
+
|
7
|
+
error_namespace "vagabund.settler.errors"
|
8
|
+
|
9
|
+
def message(orig=true)
|
10
|
+
return super() if !orig || original_error.nil?
|
11
|
+
"#{original_error.class.name}: #{original_error.message}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def backtrace(orig=true)
|
15
|
+
!orig || original_error.nil? ? super() : original_error.backtrace
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(*args)
|
19
|
+
@original_error = args.shift if args.first.is_a?(Exception)
|
20
|
+
super(*args)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class PackageError < SettlerError; end
|
25
|
+
class ProjectError < SettlerError; end
|
26
|
+
|
27
|
+
class PackageBuildError < PackageError
|
28
|
+
error_key :package_build_error
|
29
|
+
end
|
30
|
+
|
31
|
+
class PackageCleanError < PackageError
|
32
|
+
error_key :package_clean_error
|
33
|
+
end
|
34
|
+
|
35
|
+
class PackageExtractionError < PackageError
|
36
|
+
error_key :package_extraction_error
|
37
|
+
end
|
38
|
+
|
39
|
+
class PackageInstallError < PackageError
|
40
|
+
error_key :package_install_error
|
41
|
+
end
|
42
|
+
|
43
|
+
class PackagePullError < PackageError
|
44
|
+
error_key :package_pull_error
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,215 @@
|
|
1
|
+
require_relative 'package_config'
|
2
|
+
|
3
|
+
module Vagabund
|
4
|
+
module Settler
|
5
|
+
module Packages
|
6
|
+
class Base
|
7
|
+
attr_reader :config
|
8
|
+
|
9
|
+
def provision(machine)
|
10
|
+
exec_before :package, machine
|
11
|
+
|
12
|
+
if skip?
|
13
|
+
machine.ui.warn "Skipping package #{name}-#{version} because skip flag was set."
|
14
|
+
return
|
15
|
+
end
|
16
|
+
|
17
|
+
pull machine
|
18
|
+
extract machine
|
19
|
+
build machine
|
20
|
+
install machine
|
21
|
+
clean machine
|
22
|
+
|
23
|
+
exec_after :package, machine
|
24
|
+
end
|
25
|
+
|
26
|
+
def build(machine)
|
27
|
+
exec_before :build, machine
|
28
|
+
machine.ui.detail "Building #{name}-#{version}..."
|
29
|
+
action_exec config.builder, machine
|
30
|
+
exec_after :build, machine
|
31
|
+
rescue StandardError => e
|
32
|
+
raise Settler::Errors::PackageBuildError, e
|
33
|
+
end
|
34
|
+
|
35
|
+
def clean(machine)
|
36
|
+
exec_before :clean, machine
|
37
|
+
machine.ui.detail "Cleaning up after #{name}-#{version}..."
|
38
|
+
action_exec config.cleaner, machine
|
39
|
+
exec_after :clean, machine
|
40
|
+
rescue StandardError => e
|
41
|
+
raise Settler::Errors::PackageCleanError, e
|
42
|
+
end
|
43
|
+
|
44
|
+
def extract(machine)
|
45
|
+
exec_before :extract, machine
|
46
|
+
machine.ui.detail "Unpacking #{name}-#{version}..."
|
47
|
+
action_exec config.extractor, machine
|
48
|
+
exec_after :extract, machine
|
49
|
+
rescue StandardError => e
|
50
|
+
raise Settler::Errors::PackageExtractionError, e
|
51
|
+
end
|
52
|
+
|
53
|
+
def install(machine)
|
54
|
+
exec_before :install, machine
|
55
|
+
machine.ui.detail "Installing #{name}-#{version}..."
|
56
|
+
action_exec config.installer, machine
|
57
|
+
exec_after :install, machine
|
58
|
+
rescue StandardError => e
|
59
|
+
raise Settler::Errors::PackageInstallError, e
|
60
|
+
end
|
61
|
+
|
62
|
+
def pull(machine)
|
63
|
+
exec_before :pull, machine
|
64
|
+
machine.ui.detail "Retrieving sources for #{name}-#{version}..."
|
65
|
+
action_exec config.puller, machine
|
66
|
+
exec_after :pull, machine
|
67
|
+
rescue StandardError => e
|
68
|
+
raise Settler::Errors::PackagePullError, e
|
69
|
+
end
|
70
|
+
|
71
|
+
def exec_before(action, machine)
|
72
|
+
hook_exec :before, action, machine
|
73
|
+
end
|
74
|
+
|
75
|
+
def exec_after(action, machine)
|
76
|
+
hook_exec :after, action, machine
|
77
|
+
end
|
78
|
+
|
79
|
+
def hook_exec(hook, action, machine)
|
80
|
+
hook_action = "#{hook.to_s}_#{action.to_s.gsub(/[eo]r$/, '')}"
|
81
|
+
return if config.send(hook_action).nil? || config.send(hook_action).empty?
|
82
|
+
|
83
|
+
machine.ui.detail "Executing custom :#{hook_action} hooks for package #{name}-#{version}..."
|
84
|
+
config.send(hook_action).each do |hact|
|
85
|
+
action_exec hact, machine
|
86
|
+
end
|
87
|
+
rescue StandardError => e
|
88
|
+
raise Settler::Errors::PackageError, e
|
89
|
+
end
|
90
|
+
|
91
|
+
def action_exec(command, machine)
|
92
|
+
self.class.instance_eval do
|
93
|
+
[:ask, :detail, :error, :info, :output, :warn].each do |cmd|
|
94
|
+
define_method cmd do |*args, &block|
|
95
|
+
machine.ui.send cmd, *args, &block
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
[:execute, :sudo, :test].each do |cmd|
|
100
|
+
define_method cmd do |*args, &block|
|
101
|
+
opts = {verbose: false}.merge(args.extract_options!)
|
102
|
+
if opts[:verbose] == true
|
103
|
+
machine.communicate.send cmd, *args, opts do |type,data|
|
104
|
+
color = type == :stderr ? :red : :green
|
105
|
+
options = {
|
106
|
+
color: color,
|
107
|
+
new_line: false,
|
108
|
+
prefix: false
|
109
|
+
}
|
110
|
+
|
111
|
+
detail(data, options)
|
112
|
+
block.call(type, data) unless block.nil?
|
113
|
+
end
|
114
|
+
else
|
115
|
+
machine.communicate.send cmd, *args, opts, &block
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
define_method :capture do |*args, &block|
|
121
|
+
output = ''
|
122
|
+
machine.communicate.execute *args do |type,data|
|
123
|
+
output += data if type == :stdout
|
124
|
+
block.call(type, data) unless block.nil?
|
125
|
+
end
|
126
|
+
output
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
instance_exec self, machine, machine.communicate, &command if command.is_a?(Proc)
|
131
|
+
|
132
|
+
self.class.instance_eval do
|
133
|
+
[:ask, :detail, :error, :info, :output, :warn, :capture, :execute, :sudo, :test].each do |cmd|
|
134
|
+
undef_method cmd
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def configure(&block)
|
140
|
+
config.configure &block
|
141
|
+
end
|
142
|
+
|
143
|
+
def local_package
|
144
|
+
config.local_package
|
145
|
+
end
|
146
|
+
alias_method :local_file, :local_package
|
147
|
+
|
148
|
+
def build_path
|
149
|
+
config.build_path
|
150
|
+
end
|
151
|
+
|
152
|
+
def build_root
|
153
|
+
config.build_root
|
154
|
+
end
|
155
|
+
|
156
|
+
def name
|
157
|
+
config.name
|
158
|
+
end
|
159
|
+
|
160
|
+
def version
|
161
|
+
config.version
|
162
|
+
end
|
163
|
+
|
164
|
+
def source
|
165
|
+
config.source
|
166
|
+
end
|
167
|
+
|
168
|
+
def skip(s)
|
169
|
+
@skip = s unless s.nil?
|
170
|
+
@skip
|
171
|
+
end
|
172
|
+
alias_method :skip=, :skip
|
173
|
+
|
174
|
+
def skip?
|
175
|
+
@skip
|
176
|
+
end
|
177
|
+
|
178
|
+
protected
|
179
|
+
|
180
|
+
#
|
181
|
+
# Base.new 'poppler', '0.24.5', {url: 'http://poppler.freedesktop.org/poppler-0.24.5.tar.xz'}
|
182
|
+
#
|
183
|
+
# Supported source types:
|
184
|
+
# git: 'git url'
|
185
|
+
# local: '/path/to/local/file'
|
186
|
+
# url: 'http://example.com/path/to/file'
|
187
|
+
# url: 'ftp://user:pass@example.com/path/to/file'
|
188
|
+
# scp: '[user@]example.com:/path/to/file' # this might require ssh forwarding
|
189
|
+
def initialize(*args, &block)
|
190
|
+
opts = args.extract_options!
|
191
|
+
opts = {name: args.shift, version: args.shift}.merge(opts)
|
192
|
+
@config = PackageConfig.new(opts, &block)
|
193
|
+
end
|
194
|
+
|
195
|
+
def build_path_exists?(machine)
|
196
|
+
return machine.communicate.test("[ -d #{build_path} ]") ? true : false
|
197
|
+
end
|
198
|
+
|
199
|
+
def package_exists?(machine)
|
200
|
+
return machine.communicate.test("[ -f #{existing_package_file(machine)} ]") ? true : false
|
201
|
+
end
|
202
|
+
|
203
|
+
def existing_package_file(machine)
|
204
|
+
pkg_file = local_file
|
205
|
+
|
206
|
+
while !machine.communicate.test("[ -f #{pkg_file} ]") && !File.extname(pkg_file).empty? do
|
207
|
+
pkg_file = File.join(build_root, File.basename(pkg_file, File.extname(pkg_file)))
|
208
|
+
end
|
209
|
+
pkg_file
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Vagabund
|
2
|
+
module Settler
|
3
|
+
module Packages
|
4
|
+
class Config
|
5
|
+
|
6
|
+
def packages
|
7
|
+
@packages ||= []
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_package(*args, &block)
|
11
|
+
if args.first.is_a?(Packages::Base)
|
12
|
+
pkg = args.shift
|
13
|
+
pkg.configure &block if block_given?
|
14
|
+
packages << pkg
|
15
|
+
else
|
16
|
+
add_package Package.new(*args, &block)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
alias_method :package, :add_package
|
20
|
+
alias_method :package=, :add_package
|
21
|
+
|
22
|
+
def method_missing(meth, *args, &block)
|
23
|
+
packages.send meth, *args, &block
|
24
|
+
end
|
25
|
+
|
26
|
+
def respond_to_missing?(meth, include_private=false)
|
27
|
+
packages.respond_to? meth, include_private
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def initialize(*args)
|
33
|
+
@settler_config = args.shift if args.first.is_a?(Settler::Config)
|
34
|
+
@packages = args.shift if args.first.is_a?(Array)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Vagabund
|
2
|
+
module Settler
|
3
|
+
module Packages
|
4
|
+
class PackageConfig
|
5
|
+
attr_reader :config, :source
|
6
|
+
|
7
|
+
# Bit of metaprogramming to define methods like builder, installer,
|
8
|
+
# before_build, after_install, etc.
|
9
|
+
%w(package builder cleaner extractor installer puller).each do |action|
|
10
|
+
%w(before after).each do |hook|
|
11
|
+
hook_action = "#{hook}_#{action.gsub(/[eo]r$/, '')}"
|
12
|
+
|
13
|
+
# Defines before/after 'hook' methods for each action: before_build,
|
14
|
+
# before_pull, after_install, etc.
|
15
|
+
define_method hook_action.to_sym do |*args, &block|
|
16
|
+
if args.first.is_a?(String)
|
17
|
+
command = args.shift
|
18
|
+
opts = args.extract_options!
|
19
|
+
|
20
|
+
cmd_proc = Proc.new do |package, machine, channel|
|
21
|
+
cmd = "cd #{package.build_path}; #{command}"
|
22
|
+
execute cmd, {verbose: true}.merge(opts)
|
23
|
+
end
|
24
|
+
|
25
|
+
config.send "#{hook_action}=".to_sym, [] if config.send(hook_action.to_sym).nil?
|
26
|
+
config.send(hook_action.to_sym) << cmd_proc
|
27
|
+
end
|
28
|
+
|
29
|
+
if !args.empty? && (args.first.nil? || args.first.is_a?(Proc))
|
30
|
+
config.send "#{hook_action}=".to_sym, [] if config.send(hook_action.to_sym).nil?
|
31
|
+
config.send(hook_action.to_sym) << args.shift
|
32
|
+
end
|
33
|
+
|
34
|
+
if !block.nil? # block_given? doesn't work here
|
35
|
+
config.send "#{hook_action}=".to_sym, [] if config.send(hook_action.to_sym).nil?
|
36
|
+
config.send(hook_action.to_sym) << block
|
37
|
+
end
|
38
|
+
|
39
|
+
config.send "#{hook_action}".to_sym
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if action == 'package'
|
44
|
+
alias_method :before, :before_package
|
45
|
+
alias_method :after, :after_package
|
46
|
+
next
|
47
|
+
end
|
48
|
+
|
49
|
+
# Defines custom action methods to override the built-in puller,
|
50
|
+
# extractor, builder, installer and cleaner.
|
51
|
+
define_method action.to_sym do |*args, &block|
|
52
|
+
if args.first.is_a?(String)
|
53
|
+
command = args.shift
|
54
|
+
opts = args.extract_options!
|
55
|
+
|
56
|
+
cmd_proc = Proc.new do |package, machine, channel|
|
57
|
+
cmd = "cd #{package.build_path}; #{command}"
|
58
|
+
execute cmd, {verbose: true}.merge(opts)
|
59
|
+
end
|
60
|
+
|
61
|
+
config.send "#{action}=".to_sym, cmd_proc
|
62
|
+
end
|
63
|
+
|
64
|
+
config.send "#{action}=".to_sym, args.shift if !args.empty? && (args.first.nil? || args.first.is_a?(Proc))
|
65
|
+
config.send "#{action}=".to_sym, block if !block.nil? # block_given? doesn't work here
|
66
|
+
|
67
|
+
config.send action.to_sym
|
68
|
+
end
|
69
|
+
alias_method "#{action}=".to_sym, action.to_sym
|
70
|
+
alias_method "#{action.gsub(/[eo]r$/, '')}_with".to_sym, action.to_sym
|
71
|
+
end
|
72
|
+
|
73
|
+
def build_root
|
74
|
+
config.build_root ||= "/tmp/#{name}-#{version}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def build_path
|
78
|
+
config.build_path ||= File.join(build_root, "#{name}-#{version}")
|
79
|
+
end
|
80
|
+
|
81
|
+
def local_package
|
82
|
+
config.local_package ||= File.join(build_root, (File.basename(source.origin) rescue "#{name}-#{version}"))
|
83
|
+
end
|
84
|
+
alias_method :local_file, :local_package
|
85
|
+
|
86
|
+
def configure(&block)
|
87
|
+
instance_eval &block if block_given?
|
88
|
+
end
|
89
|
+
|
90
|
+
def method_missing(meth, *args, &block)
|
91
|
+
config.send meth, *args, &block
|
92
|
+
end
|
93
|
+
|
94
|
+
def respond_to_missing?(meth, include_private=false)
|
95
|
+
config.respond_to? meth, include_private
|
96
|
+
end
|
97
|
+
|
98
|
+
protected
|
99
|
+
|
100
|
+
def initialize(*args, &block)
|
101
|
+
@config = OpenStruct.new({builder: Package::BUILDER, cleaner: Package::CLEANER, extractor: Package::EXTRACTOR, installer: Package::INSTALLER, puller: Package::PULLER}.merge(args.extract_options!))
|
102
|
+
|
103
|
+
if config.respond_to?(:git)
|
104
|
+
@source = Sources::Git.new(config.git)
|
105
|
+
elsif config.respond_to?(:url)
|
106
|
+
@source = Sources::Url.new(config.url)
|
107
|
+
elsif config.respond_to?(:local)
|
108
|
+
@source = Sources::Local.new(config.local)
|
109
|
+
#elsif config.respond_to?(:scp)
|
110
|
+
# remote scp
|
111
|
+
end
|
112
|
+
|
113
|
+
configure &block if block_given?
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require_relative 'errors'
|
2
|
+
require_relative 'packages/base'
|
3
|
+
|
4
|
+
module Vagabund
|
5
|
+
module Settler
|
6
|
+
module Packages
|
7
|
+
end
|
8
|
+
|
9
|
+
class Package < Packages::Base
|
10
|
+
EXTENSIONS = ['.gz', '.bz', '.bz2', '.xz', '.zip', '.tar', '.tgz', '.tbz', '.tbz2', '.txz']
|
11
|
+
|
12
|
+
BUILDER = Proc.new do |package, machine, channel|
|
13
|
+
execute "cd #{build_path}; ./configure && make", verbose: true
|
14
|
+
end
|
15
|
+
|
16
|
+
CLEANER = Proc.new do |package, machine, channel|
|
17
|
+
sudo "rm -rf #{build_root}"
|
18
|
+
end
|
19
|
+
|
20
|
+
EXTRACTOR = Proc.new do |package, machine, channel|
|
21
|
+
if build_path_exists?(machine)
|
22
|
+
machine.ui.warn "Build path #{build_path} already exists, using it for the build. If you would like to use a clean source tree, you should manually remove it and run `vagrant provision` again."
|
23
|
+
elsif File.directory?(local_package)
|
24
|
+
execute "cp -r #{local_package} #{build_path}" if local_package != build_path
|
25
|
+
else
|
26
|
+
execute "mkdir -p #{build_path}"
|
27
|
+
local_ext = File.extname(local_package)
|
28
|
+
|
29
|
+
case local_ext
|
30
|
+
when '.gz'
|
31
|
+
execute "cd #{build_root}; gzip -dc #{local_package} > #{build_path}/#{File.basename(local_package, local_ext)}"
|
32
|
+
when '.tgz'
|
33
|
+
execute "cd #{build_root}; gzip -dc #{local_package} > #{build_path}/#{File.basename(local_package, local_ext)}.tar"
|
34
|
+
when '.bz', '.bz2'
|
35
|
+
execute "cd #{build_root}; bzip2 -dc #{local_package} > #{build_path}/#{File.basename(local_package, local_ext)}"
|
36
|
+
when '.tbz', '.tbz2'
|
37
|
+
execute "cd #{build_root}; bzip2 -dc #{local_package} > #{build_path}/#{File.basename(local_package, local_ext)}.tar"
|
38
|
+
when '.xz'
|
39
|
+
execute "cd #{build_root}; xz -dc #{local_package} > #{build_path}/#{File.basename(local_package, local_ext)}"
|
40
|
+
when '.txz'
|
41
|
+
execute "cd #{build_root}; xz -dc #{local_package} > #{build_path}/#{File.basename(local_package, local_ext)}.tar"
|
42
|
+
when '.zip'
|
43
|
+
execute "cd #{build_root}; unzip #{local_package} -d #{build_path}"
|
44
|
+
execute("cd #{build_path}; mv #{File.basename(local_package, local_ext)}/* ./") rescue nil
|
45
|
+
execute("cd #{build_path}; mv #{File.basename(local_package, local_ext)}/.* ./") rescue nil
|
46
|
+
execute("cd #{build_path}; mv #{name}-#{version}/* ./") rescue nil
|
47
|
+
execute("cd #{build_path}; mv #{name}-#{version}/.* ./") rescue nil
|
48
|
+
execute("cd #{build_path}; rm -rf #{File.basename(local_package, local_ext)}") rescue nil
|
49
|
+
when '.tar'
|
50
|
+
begin
|
51
|
+
execute "cd #{build_root}; tar xf #{local_package} #{File.basename(local_package, local_ext)} -C #{build_path}"
|
52
|
+
rescue
|
53
|
+
begin
|
54
|
+
execute "cd #{build_root}; tar xf #{local_package} #{name}-#{version} -C #{build_path}"
|
55
|
+
rescue
|
56
|
+
execute "cd #{build_root}; tar xf #{local_package} -C #{build_path}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
build_files = ""
|
62
|
+
execute "cd #{build_path}; ls" do |type, data|
|
63
|
+
build_files = data
|
64
|
+
end
|
65
|
+
|
66
|
+
if build_files.split($/).length == 1
|
67
|
+
new_package_file = File.basename(build_files.chomp)
|
68
|
+
if Package::EXTENSIONS.include?(File.extname(new_package_file))
|
69
|
+
execute "mv #{File.join(build_path, new_package_file)} #{build_root}"
|
70
|
+
sudo "rm -rf #{local_package} #{build_path}"
|
71
|
+
config.local_package = File.join(build_root, new_package_file)
|
72
|
+
|
73
|
+
# Re-execute this proc directly instead of going back through extract() or action_exec()
|
74
|
+
detail "Unpacking #{local_package}..."
|
75
|
+
instance_exec self, machine, machine.communicate, &EXTRACTOR
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
INSTALLER = Proc.new do |package, machine, channel|
|
83
|
+
sudo "cd #{build_path}; make install", verbose: true
|
84
|
+
end
|
85
|
+
|
86
|
+
PULLER = Proc.new do |package, machine, channel|
|
87
|
+
if package_exists?(machine)
|
88
|
+
config.local_package = existing_package_file(machine)
|
89
|
+
machine.ui.warn "Package #{local_package} already exists, using it for the build. If you would like to re-download the package, you should manually remove it then run `vagrant provision` again."
|
90
|
+
else
|
91
|
+
source.pull machine, local_package
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.new(*args, &block)
|
96
|
+
Packages::Base.new(*args, &block)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require_relative 'project_config'
|
2
|
+
|
3
|
+
module Vagabund
|
4
|
+
module Settler
|
5
|
+
module Projects
|
6
|
+
class Base
|
7
|
+
attr_reader :config
|
8
|
+
|
9
|
+
def provision(machine)
|
10
|
+
exec_before :project, machine
|
11
|
+
pull machine
|
12
|
+
exec_after :project, machine
|
13
|
+
end
|
14
|
+
|
15
|
+
def pull(machine)
|
16
|
+
exec_before :pull, machine
|
17
|
+
if config.puller.nil?
|
18
|
+
config.source.pull machine, project_path
|
19
|
+
else
|
20
|
+
action_exec config.puller, machine
|
21
|
+
end
|
22
|
+
exec_after :pull, machine
|
23
|
+
rescue StandardError => e
|
24
|
+
raise Settler::Errors::ProjectError, e
|
25
|
+
end
|
26
|
+
|
27
|
+
def exec_before(action, machine)
|
28
|
+
hook_exec :before, action, machine
|
29
|
+
end
|
30
|
+
|
31
|
+
def exec_after(action, machine)
|
32
|
+
hook_exec :after, action, machine
|
33
|
+
end
|
34
|
+
|
35
|
+
def hook_exec(hook, action, machine)
|
36
|
+
hook_action = "#{hook.to_s}_#{action.to_s.gsub(/[eo]r$/, '')}"
|
37
|
+
return if config.send(hook_action).nil? || config.send(hook_action).empty?
|
38
|
+
|
39
|
+
machine.ui.detail "Executing custom :#{hook_action} hooks for project #{name}..."
|
40
|
+
config.send(hook_action).each do |hact|
|
41
|
+
action_exec hact, machine
|
42
|
+
end
|
43
|
+
rescue StandardError => e
|
44
|
+
raise Settler::Errors::ProjectError, e
|
45
|
+
end
|
46
|
+
|
47
|
+
def action_exec(command, machine)
|
48
|
+
self.class.instance_eval do
|
49
|
+
[:ask, :detail, :error, :info, :output, :warn].each do |cmd|
|
50
|
+
define_method cmd do |*args, &block|
|
51
|
+
machine.ui.send cmd, *args, &block
|
52
|
+
end
|
53
|
+
end
|
54
|
+
[:execute, :sudo, :test].each do |cmd|
|
55
|
+
define_method cmd do |*args, &block|
|
56
|
+
opts = {verbose: false}.merge(args.extract_options!)
|
57
|
+
if opts[:verbose] == true
|
58
|
+
machine.communicate.send cmd, *args, opts do |type,data|
|
59
|
+
color = type == :stderr ? :red : :green
|
60
|
+
options = {
|
61
|
+
color: color,
|
62
|
+
new_line: false,
|
63
|
+
prefix: false
|
64
|
+
}
|
65
|
+
|
66
|
+
detail(data, options)
|
67
|
+
block.call(type, data) unless block.nil?
|
68
|
+
end
|
69
|
+
else
|
70
|
+
machine.communicate.send cmd, *args, opts, &block
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
define_method :capture do |*args, &block|
|
76
|
+
output = ''
|
77
|
+
machine.communicate.execute *args do |type,data|
|
78
|
+
output += data if type == :stdout
|
79
|
+
block.call(type, data) unless block.nil?
|
80
|
+
end
|
81
|
+
output
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
instance_exec self, machine, machine.communicate, &command if command.is_a?(Proc)
|
86
|
+
|
87
|
+
self.class.instance_eval do
|
88
|
+
[:ask, :detail, :error, :info, :output, :warn, :capture, :execute, :sudo, :test].each do |cmd|
|
89
|
+
undef_method cmd
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def configure(&block)
|
95
|
+
config.configure &block
|
96
|
+
end
|
97
|
+
|
98
|
+
def name
|
99
|
+
config.name
|
100
|
+
end
|
101
|
+
|
102
|
+
def project_path
|
103
|
+
config.project_path
|
104
|
+
end
|
105
|
+
|
106
|
+
protected
|
107
|
+
|
108
|
+
#
|
109
|
+
# Base.new 'my_project', {git: 'git@github.com:/user/repo.git'}
|
110
|
+
#
|
111
|
+
def initialize(*args, &block)
|
112
|
+
opts = args.extract_options!
|
113
|
+
opts = {name: args.shift}.merge(opts)
|
114
|
+
@config = ProjectConfig.new(opts, &block)
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Vagabund
|
2
|
+
module Settler
|
3
|
+
module Projects
|
4
|
+
class Config
|
5
|
+
|
6
|
+
def projects_path
|
7
|
+
@projects_path ||= '/vagrant'
|
8
|
+
end
|
9
|
+
alias_method :path, :projects_path
|
10
|
+
|
11
|
+
def projects_path=(path)
|
12
|
+
@projects_path = path
|
13
|
+
end
|
14
|
+
alias_method :path=, :projects_path=
|
15
|
+
|
16
|
+
def projects
|
17
|
+
@projects ||= []
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_project(*args, &block)
|
21
|
+
if args.first.is_a?(Projects::Base)
|
22
|
+
prj = args.shift
|
23
|
+
prj.config.projects_path ||= projects_path
|
24
|
+
prj.configure &block if block_given?
|
25
|
+
projects << prj
|
26
|
+
else
|
27
|
+
args.push({projects_path: projects_path}.merge(args.extract_options!))
|
28
|
+
add_project Project.new(*args, &block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
alias_method :project, :add_project
|
32
|
+
alias_method :project=, :add_project
|
33
|
+
|
34
|
+
def method_missing(meth, *args, &block)
|
35
|
+
projects.send meth, *args, &block
|
36
|
+
end
|
37
|
+
|
38
|
+
def respond_to_missing?(meth, include_private=false)
|
39
|
+
projects.respond_to? meth, include_private
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
def initialize(*args)
|
45
|
+
@settler_config = args.shift if args.first.is_a?(Settler::Config)
|
46
|
+
@projects = args.shift if args.first.is_a?(Array)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|