omnibus 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/.yardopts +7 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +9 -0
- data/LICENSE +201 -0
- data/NOTICE +9 -0
- data/README.md +186 -0
- data/Rakefile +7 -0
- data/bin/makeself-header.sh +401 -0
- data/bin/makeself.sh +407 -0
- data/bin/omnibus +11 -0
- data/lib/omnibus.rb +280 -0
- data/lib/omnibus/build_version.rb +281 -0
- data/lib/omnibus/builder.rb +323 -0
- data/lib/omnibus/clean_tasks.rb +30 -0
- data/lib/omnibus/cli.rb +35 -0
- data/lib/omnibus/cli/application.rb +136 -0
- data/lib/omnibus/cli/base.rb +112 -0
- data/lib/omnibus/cli/build.rb +66 -0
- data/lib/omnibus/cli/cache.rb +60 -0
- data/lib/omnibus/config.rb +186 -0
- data/lib/omnibus/exceptions.rb +54 -0
- data/lib/omnibus/fetcher.rb +184 -0
- data/lib/omnibus/fetchers.rb +22 -0
- data/lib/omnibus/fetchers/git_fetcher.rb +212 -0
- data/lib/omnibus/fetchers/net_fetcher.rb +191 -0
- data/lib/omnibus/fetchers/path_fetcher.rb +65 -0
- data/lib/omnibus/fetchers/s3_cache_fetcher.rb +42 -0
- data/lib/omnibus/health_check.rb +260 -0
- data/lib/omnibus/library.rb +70 -0
- data/lib/omnibus/overrides.rb +69 -0
- data/lib/omnibus/project.rb +566 -0
- data/lib/omnibus/reports.rb +99 -0
- data/lib/omnibus/s3_cacher.rb +136 -0
- data/lib/omnibus/software.rb +430 -0
- data/lib/omnibus/templates/Berksfile.erb +3 -0
- data/lib/omnibus/templates/Gemfile.erb +4 -0
- data/lib/omnibus/templates/README.md.erb +102 -0
- data/lib/omnibus/templates/Vagrantfile.erb +95 -0
- data/lib/omnibus/templates/gitignore.erb +8 -0
- data/lib/omnibus/templates/omnibus.rb.example.erb +5 -0
- data/lib/omnibus/templates/package_scripts/makeselfinst.erb +27 -0
- data/lib/omnibus/templates/package_scripts/postinst.erb +17 -0
- data/lib/omnibus/templates/package_scripts/postrm.erb +9 -0
- data/lib/omnibus/templates/project.rb.erb +21 -0
- data/lib/omnibus/templates/software/c-example.rb.erb +42 -0
- data/lib/omnibus/templates/software/erlang-example.rb.erb +38 -0
- data/lib/omnibus/templates/software/ruby-example.rb.erb +24 -0
- data/lib/omnibus/util.rb +61 -0
- data/lib/omnibus/version.rb +20 -0
- data/omnibus.gemspec +34 -0
- data/spec/build_version_spec.rb +228 -0
- data/spec/data/overrides/bad_line.overrides +3 -0
- data/spec/data/overrides/good.overrides +5 -0
- data/spec/data/overrides/with_dupes.overrides +4 -0
- data/spec/data/software/erchef.rb +40 -0
- data/spec/overrides_spec.rb +114 -0
- data/spec/software_spec.rb +71 -0
- data/spec/spec_helper.rb +28 -0
- metadata +239 -0
@@ -0,0 +1,323 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2012 Opscode, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require 'forwardable'
|
19
|
+
|
20
|
+
module Omnibus
|
21
|
+
class Builder
|
22
|
+
|
23
|
+
# Proxies method calls to either a Builder object or the Software that the
|
24
|
+
# builder belongs to. Provides compatibility with our DSL where we never
|
25
|
+
# yield objects to blocks and hopefully hides some of the confusion that
|
26
|
+
# can arise from instance_eval.
|
27
|
+
class DSLProxy
|
28
|
+
extend Forwardable
|
29
|
+
|
30
|
+
# @todo def_delegators :@builder, :patch, :command, :ruby, ...
|
31
|
+
|
32
|
+
def_delegator :@builder, :patch
|
33
|
+
def_delegator :@builder, :command
|
34
|
+
def_delegator :@builder, :ruby
|
35
|
+
def_delegator :@builder, :gem
|
36
|
+
def_delegator :@builder, :bundle
|
37
|
+
def_delegator :@builder, :rake
|
38
|
+
def_delegator :@builder, :block
|
39
|
+
def_delegator :@builder, :name
|
40
|
+
|
41
|
+
def initialize(builder, software)
|
42
|
+
@builder, @software = builder, software
|
43
|
+
end
|
44
|
+
|
45
|
+
def eval_block(&block)
|
46
|
+
instance_eval(&block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def respond_to?(method)
|
50
|
+
super || @software.respond_to?(method)
|
51
|
+
end
|
52
|
+
|
53
|
+
def methods
|
54
|
+
super | @software.methods
|
55
|
+
end
|
56
|
+
|
57
|
+
def method_missing(method_name, *args, &block)
|
58
|
+
if @software.respond_to?(method_name)
|
59
|
+
@software.send(method_name, *args, &block)
|
60
|
+
else
|
61
|
+
super
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
# @todo code duplication with {Fetcher::ErrorReporter}
|
69
|
+
class ErrorReporter
|
70
|
+
|
71
|
+
# @todo fetcher isn't even used
|
72
|
+
def initialize(error, fetcher)
|
73
|
+
@error, @fetcher = error, fetcher
|
74
|
+
end
|
75
|
+
|
76
|
+
# @todo this isn't necessary
|
77
|
+
def e
|
78
|
+
@error
|
79
|
+
end
|
80
|
+
|
81
|
+
def explain(why)
|
82
|
+
$stderr.puts "* " * 40
|
83
|
+
$stderr.puts why
|
84
|
+
$stderr.puts "Exception:"
|
85
|
+
$stderr.puts indent("#{e.class}: #{e.message.strip}", 2)
|
86
|
+
Array(e.backtrace).each {|l| $stderr.puts indent(l, 4) }
|
87
|
+
$stderr.puts "* " * 40
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def indent(string, n)
|
93
|
+
string.split("\n").map {|l| " ".rjust(n) << l }.join("\n")
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
# @todo Look at using Bundler.with_clean_env{ ... } instead
|
99
|
+
BUNDLER_BUSTER = { "RUBYOPT" => nil,
|
100
|
+
"BUNDLE_BIN_PATH" => nil,
|
101
|
+
"BUNDLE_GEMFILE" => nil,
|
102
|
+
"GEM_PATH" => nil,
|
103
|
+
"GEM_HOME" => nil }
|
104
|
+
|
105
|
+
attr_reader :build_commands
|
106
|
+
|
107
|
+
def initialize(software, &block)
|
108
|
+
@software = software
|
109
|
+
@build_commands = []
|
110
|
+
@dsl_proxy = DSLProxy.new(self, software)
|
111
|
+
@dsl_proxy.eval_block(&block) if block_given?
|
112
|
+
end
|
113
|
+
|
114
|
+
def name
|
115
|
+
@software.name
|
116
|
+
end
|
117
|
+
|
118
|
+
def command(*args)
|
119
|
+
@build_commands << args
|
120
|
+
end
|
121
|
+
|
122
|
+
def patch(*args)
|
123
|
+
args = args.dup.pop
|
124
|
+
|
125
|
+
# we'll search for a patch file in the project root AND
|
126
|
+
# the omnibus-software gem
|
127
|
+
candidate_roots = [Omnibus.project_root]
|
128
|
+
candidate_roots << Omnibus.omnibus_software_root if Omnibus.omnibus_software_root
|
129
|
+
|
130
|
+
candidate_paths = candidate_roots.map do |root|
|
131
|
+
File.expand_path("#{root}/config/patches/#{name}/#{args[:source]}")
|
132
|
+
end
|
133
|
+
|
134
|
+
source = candidate_paths.find{|path| File.exists?(path) }
|
135
|
+
|
136
|
+
plevel = args[:plevel] || 1
|
137
|
+
if args[:target]
|
138
|
+
target = File.expand_path("#{project_dir}/#{args[:target]}")
|
139
|
+
@build_commands <<
|
140
|
+
"cat #{source} | patch -p#{plevel} #{target}"
|
141
|
+
else
|
142
|
+
@build_commands <<
|
143
|
+
"patch -d #{project_dir} -p#{plevel} -i #{source}"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# @todo all these ruby commands (ruby, gem, bundle, rake) could
|
148
|
+
# all be collapsed into a single underlying implementation, since
|
149
|
+
# they all just differ on the executable being called
|
150
|
+
def ruby(*args)
|
151
|
+
@build_commands << bundle_bust(*prepend_cmd("#{install_dir}/embedded/bin/ruby", *args))
|
152
|
+
end
|
153
|
+
|
154
|
+
def gem(*args)
|
155
|
+
@build_commands << bundle_bust(*prepend_cmd("#{install_dir}/embedded/bin/gem", *args))
|
156
|
+
end
|
157
|
+
|
158
|
+
def bundle(*args)
|
159
|
+
@build_commands << bundle_bust(*prepend_cmd("#{install_dir}/embedded/bin/bundle", *args))
|
160
|
+
end
|
161
|
+
|
162
|
+
def rake(*args)
|
163
|
+
@build_commands << bundle_bust(*prepend_cmd("#{install_dir}/embedded/bin/rake", *args))
|
164
|
+
end
|
165
|
+
|
166
|
+
def block(&rb_block)
|
167
|
+
@build_commands << rb_block
|
168
|
+
end
|
169
|
+
|
170
|
+
def project_dir
|
171
|
+
@software.project_dir
|
172
|
+
end
|
173
|
+
|
174
|
+
def install_dir
|
175
|
+
@software.install_dir
|
176
|
+
end
|
177
|
+
|
178
|
+
def log(message)
|
179
|
+
puts "[builder:#{name}] #{message}"
|
180
|
+
end
|
181
|
+
|
182
|
+
def build
|
183
|
+
log "building #{name}"
|
184
|
+
time_it("#{name} build") do
|
185
|
+
@build_commands.each do |cmd|
|
186
|
+
execute(cmd)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def execute(cmd)
|
192
|
+
case cmd
|
193
|
+
when Proc
|
194
|
+
execute_proc(cmd)
|
195
|
+
else
|
196
|
+
execute_sh(cmd)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
private
|
201
|
+
|
202
|
+
def execute_proc(cmd)
|
203
|
+
cmd.call
|
204
|
+
rescue Exception => e
|
205
|
+
# In Ruby 1.9, Procs have a #source_location method with file/line info.
|
206
|
+
# Too bad we can't use it :(
|
207
|
+
ErrorReporter.new(e, self).explain("Failed to build #{name} while running ruby block build step")
|
208
|
+
raise
|
209
|
+
end
|
210
|
+
|
211
|
+
def execute_sh(cmd)
|
212
|
+
retries ||= 0
|
213
|
+
shell = nil
|
214
|
+
cmd_args = Array(cmd)
|
215
|
+
options = {
|
216
|
+
:cwd => project_dir,
|
217
|
+
:timeout => 5400
|
218
|
+
}
|
219
|
+
options[:live_stream] = STDOUT if ENV['DEBUG']
|
220
|
+
if cmd_args.last.is_a? Hash
|
221
|
+
cmd_options = cmd_args.last
|
222
|
+
cmd_args[cmd_args.size - 1] = options.merge(cmd_options)
|
223
|
+
else
|
224
|
+
cmd_args << options
|
225
|
+
end
|
226
|
+
|
227
|
+
cmd_string = cmd_args[0..-2].join(' ')
|
228
|
+
cmd_opts_for_display = to_kv_str(cmd_args.last)
|
229
|
+
|
230
|
+
log "Executing: `#{cmd_string}` with #{cmd_opts_for_display}"
|
231
|
+
|
232
|
+
shell = Mixlib::ShellOut.new(*cmd)
|
233
|
+
shell.environment["HOME"] = "/tmp" unless ENV["HOME"]
|
234
|
+
|
235
|
+
cmd_name = cmd_string.split(/\s+/).first
|
236
|
+
time_it("#{cmd_name} command") do
|
237
|
+
shell.run_command
|
238
|
+
shell.error!
|
239
|
+
end
|
240
|
+
rescue Exception => e
|
241
|
+
# Getting lots of errors from github, particularly with erlang/rebar
|
242
|
+
# projects fetching tons of deps via git all the time. This isn't a
|
243
|
+
# particularly elegant way to solve that problem. But it should work.
|
244
|
+
if retries >= 3
|
245
|
+
ErrorReporter.new(e, self).explain("Failed to build #{name} while running `#{cmd_string}` with #{cmd_opts_for_display}")
|
246
|
+
raise
|
247
|
+
else
|
248
|
+
time_to_sleep = 5 * (2 ** retries)
|
249
|
+
retries +=1
|
250
|
+
log "Failed to execute cmd #{cmd} #{retries} time(s). Retrying in #{time_to_sleep}s."
|
251
|
+
sleep(time_to_sleep)
|
252
|
+
retry
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def prepend_cmd(str, *cmd_args)
|
257
|
+
if cmd_args.size == 1
|
258
|
+
# command as a string, no opts
|
259
|
+
"#{str} #{cmd_args.first}"
|
260
|
+
elsif cmd_args.size == 2 && cmd_args.last.is_a?(Hash)
|
261
|
+
# command as a string w/ opts
|
262
|
+
["#{str} #{cmd_args.first}", cmd_args.last]
|
263
|
+
elsif cmd_args.size == 0
|
264
|
+
raise ArgumentError, "I don't even"
|
265
|
+
else
|
266
|
+
# cmd given as argv array
|
267
|
+
cmd_args.dup.unshift(str)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
def bundle_bust(*cmd_args)
|
272
|
+
if cmd_args.last.is_a?(Hash)
|
273
|
+
cmd_args = cmd_args.dup
|
274
|
+
cmd_opts = cmd_args.pop.dup
|
275
|
+
cmd_opts[:env] = cmd_opts[:env] ? BUNDLER_BUSTER.merge(cmd_opts[:env]) : BUNDLER_BUSTER
|
276
|
+
cmd_args << cmd_opts
|
277
|
+
else
|
278
|
+
cmd_args << {:env => BUNDLER_BUSTER}
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
|
283
|
+
def time_it(what)
|
284
|
+
start = Time.now
|
285
|
+
yield
|
286
|
+
rescue Exception
|
287
|
+
elapsed = Time.now - start
|
288
|
+
log "#{what} failed, #{elapsed.to_f}s"
|
289
|
+
raise
|
290
|
+
else
|
291
|
+
elapsed = Time.now - start
|
292
|
+
log "#{what} succeeded, #{elapsed.to_f}s"
|
293
|
+
end
|
294
|
+
|
295
|
+
# Convert a hash to a string in the form `key=value`. It should work with
|
296
|
+
# whatever input is given but is designed to make the options to ShellOut
|
297
|
+
# look nice.
|
298
|
+
def to_kv_str(hash, join_str=",")
|
299
|
+
hash.inject([]) do |kv_pair_strs, (k,v)|
|
300
|
+
val_str = case v
|
301
|
+
when Hash
|
302
|
+
%Q["#{to_kv_str(v, " ")}"]
|
303
|
+
else
|
304
|
+
v.to_s
|
305
|
+
end
|
306
|
+
kv_pair_strs << "#{k}=#{val_str}"
|
307
|
+
end.join(join_str)
|
308
|
+
end
|
309
|
+
|
310
|
+
end
|
311
|
+
|
312
|
+
# @todo What's the point of this class? Can we not just detect that
|
313
|
+
# there are no commands in {Omnibus::Builder#build} and output the
|
314
|
+
# appropriate message? Seems like a lot of extra ceremony.
|
315
|
+
class NullBuilder < Builder
|
316
|
+
|
317
|
+
def build
|
318
|
+
log "Nothing to build for #{name}"
|
319
|
+
end
|
320
|
+
|
321
|
+
end
|
322
|
+
|
323
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2012 Opscode, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
# Adds source and build artifacts to Rake's CLEAN list, and install
|
19
|
+
# and cache artifacts to its CLOBBER list, ensuring that the `clean`
|
20
|
+
# and `clobber` Rake tasks do the right thing for Omnibus projects.
|
21
|
+
#
|
22
|
+
# @see https://github.com/jimweirich/rake/blob/master/lib/rake/clean.rb
|
23
|
+
|
24
|
+
require 'rake/clean'
|
25
|
+
|
26
|
+
::CLEAN.include("#{Omnibus.config.source_dir}/**/*",
|
27
|
+
"#{Omnibus.config.build_dir}/**/*")
|
28
|
+
|
29
|
+
::CLOBBER.include("#{Omnibus.config.cache_dir}/**/*",
|
30
|
+
"#{Omnibus.config.package_dir}/**/*")
|
data/lib/omnibus/cli.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2012 Opscode, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require 'omnibus/cli/application'
|
19
|
+
require 'omnibus/cli/base'
|
20
|
+
require 'omnibus/cli/build'
|
21
|
+
|
22
|
+
module Omnibus
|
23
|
+
module CLI
|
24
|
+
|
25
|
+
class Error < StandardError
|
26
|
+
attr_reader :original
|
27
|
+
|
28
|
+
def initialize(msg, original=nil)
|
29
|
+
super(msg)
|
30
|
+
@original = original
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2013 Opscode, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require 'omnibus'
|
19
|
+
require 'omnibus/cli/base'
|
20
|
+
require 'omnibus/cli/build'
|
21
|
+
require 'omnibus/cli/cache'
|
22
|
+
|
23
|
+
module Omnibus
|
24
|
+
module CLI
|
25
|
+
class Application < Base
|
26
|
+
|
27
|
+
method_option :purge,
|
28
|
+
:type => :boolean,
|
29
|
+
:default => false,
|
30
|
+
:desc => "Remove ALL files generated during the build (including packages)."
|
31
|
+
method_option :path,
|
32
|
+
:aliases => [:p],
|
33
|
+
:type => :string,
|
34
|
+
:default => Dir.pwd,
|
35
|
+
:desc => "Path to the Omnibus project root."
|
36
|
+
desc "clean PROJECT", "Remove temporary files generated during the build process."
|
37
|
+
def clean(project_name)
|
38
|
+
project = load_project!(project_name)
|
39
|
+
|
40
|
+
deletion_list = []
|
41
|
+
deletion_list << Dir.glob("#{Omnibus.config.source_dir}/**/*")
|
42
|
+
deletion_list << Dir.glob("#{Omnibus.config.build_dir}/**/*")
|
43
|
+
|
44
|
+
if options[:purge]
|
45
|
+
deletion_list << Dir.glob("#{Omnibus.config.package_dir}/**/*")
|
46
|
+
deletion_list << Dir.glob("#{Omnibus.config.cache_dir}/**/*")
|
47
|
+
deletion_list << project.install_path if File.exist?(project.install_path)
|
48
|
+
end
|
49
|
+
|
50
|
+
deletion_list.flatten!
|
51
|
+
deletion_list.each{|f| remove_file(f) }
|
52
|
+
end
|
53
|
+
|
54
|
+
desc "project PROJECT", "Creates a skeletal Omnibus project"
|
55
|
+
def project(name)
|
56
|
+
name = name.chomp("/") # remove trailing slash if present
|
57
|
+
target = File.join(Dir.pwd, "omnibus-#{name}")
|
58
|
+
install_path = File.join("/opt", name)
|
59
|
+
opts = {
|
60
|
+
:name => name,
|
61
|
+
:install_path => install_path
|
62
|
+
}
|
63
|
+
|
64
|
+
# core project files
|
65
|
+
template(File.join("Gemfile.erb"), File.join(target, "Gemfile"), opts)
|
66
|
+
template(File.join("gitignore.erb"), File.join(target, ".gitignore"), opts)
|
67
|
+
template(File.join("README.md.erb"), File.join(target, "README.md"), opts)
|
68
|
+
template(File.join("omnibus.rb.example.erb"), File.join(target, "omnibus.rb.example"), opts)
|
69
|
+
|
70
|
+
# project definition
|
71
|
+
template(File.join("project.rb.erb"), File.join(target, "config", "projects", "#{name}.rb"), opts)
|
72
|
+
|
73
|
+
# example software definitions
|
74
|
+
config_software = File.join(target, "config", "software")
|
75
|
+
template(File.join("software", "c-example.rb.erb"),
|
76
|
+
File.join(config_software, "c-example.rb"), opts)
|
77
|
+
template(File.join("software", "erlang-example.rb.erb"),
|
78
|
+
File.join(config_software, "erlang-example.rb"), opts)
|
79
|
+
template(File.join("software", "ruby-example.rb.erb"),
|
80
|
+
File.join(config_software, "ruby-example.rb"), opts)
|
81
|
+
|
82
|
+
# Vagrant build lab
|
83
|
+
template(File.join("Berksfile.erb"), File.join(target, "Berksfile"), opts)
|
84
|
+
template(File.join("Vagrantfile.erb"), File.join(target, "Vagrantfile"), opts)
|
85
|
+
|
86
|
+
# render out stub packge scripts
|
87
|
+
%w{ makeselfinst postinst postrm }.each do |package_script|
|
88
|
+
script_path = File.join(target, "package-scripts", name, package_script)
|
89
|
+
template_path = File.join("package_scripts", "#{package_script}.erb")
|
90
|
+
# render the package script
|
91
|
+
template(template_path, script_path, opts)
|
92
|
+
# ensure the package script is executable
|
93
|
+
FileUtils.chmod(0755, script_path)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
desc "version", "Display version information"
|
98
|
+
def version
|
99
|
+
say("Omnibus: #{Omnibus::VERSION}", :yellow)
|
100
|
+
end
|
101
|
+
|
102
|
+
###########################################################################
|
103
|
+
# Subcommands
|
104
|
+
###########################################################################
|
105
|
+
|
106
|
+
desc "build [COMMAND]", "Perform build-related tasks"
|
107
|
+
subcommand "build", Omnibus::CLI::Build
|
108
|
+
|
109
|
+
desc "cache [COMMAND]", "Perform cache management tasks"
|
110
|
+
subcommand "cache", Omnibus::CLI::Cache
|
111
|
+
|
112
|
+
###########################################################################
|
113
|
+
# Class Methods
|
114
|
+
###########################################################################
|
115
|
+
|
116
|
+
# Override start so we can catch and process any exceptions bubbling up
|
117
|
+
def self.start(*args)
|
118
|
+
begin
|
119
|
+
super
|
120
|
+
rescue => e
|
121
|
+
error_msg = "Something went wrong...the Omnibus just ran off the road!"
|
122
|
+
error_msg << "\n\nError raised was:\n\n\t#{$!}"
|
123
|
+
error_msg << "\n\nBacktrace:\n\n\t#{e.backtrace.join("\n\t")}"
|
124
|
+
if e.respond_to?(:original) && e.original
|
125
|
+
error_msg << "\n\nOriginal Error:\n\n\t#{e.original}"
|
126
|
+
error_msg << "\n\nOriginal Backtrace:\n\n\t#{e.original.backtrace.join("\n\t")}"
|
127
|
+
end
|
128
|
+
# TODO - we need a proper UI class
|
129
|
+
Thor::Base.shell.new.say(error_msg, :red)
|
130
|
+
exit 1
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|