bunchr 0.1.1

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/README.md ADDED
@@ -0,0 +1,323 @@
1
+ Bunchr
2
+ ======
3
+
4
+ Overview
5
+ --------
6
+
7
+ Bunchr is a Rake/Ruby-based DSL for building and bundling complex software
8
+ projects into various package formats, ie: RPM, DEB, etc (packaging performed
9
+ by [fpm](https://github.com/jordansissel/fpm).
10
+
11
+ Originally developed to create "omnibus" style packages that include an entire
12
+ ruby stack along with one or more gems, but useful for general compilation and
13
+ packaging as well.
14
+
15
+ It is typically intended to be used in conjunction with [Vagrant](http://vagrantup.com)
16
+ but can be used without Vagrant as well.
17
+
18
+ History
19
+ -------
20
+
21
+ Bunchr was conceived as a tool to help the [Sensu](https://github.com/sensu)
22
+ monitoring project find a better way to create packages that would be as
23
+ easy as possible to deploy on a variety of platforms with minimal friction and
24
+ with little or no knowledge about the idiosyncrasies of the Ruby universe
25
+ (version incompatibilities, gem conflicts, etc). This was particularly desirable
26
+ for Sensu because one of the components is an agent that will be installed
27
+ on most or all servers in an infrastructure. Thus, the package should be easy
28
+ to install and should not interfere with any other Ruby apps or scripts on the
29
+ server.
30
+
31
+ About the time the Sensu project was discussing a new packaging approach,
32
+ (Adam Jacob) from [Opscode/Chef](http://opscode.com/) took notice and suggested
33
+ a slightly different approach that achieved the same goals. The approach was
34
+ called 'omnibus' and was already in use at Opscode to produce a simple and
35
+ uniform installer for Chef.
36
+
37
+ Opscode was using a Clojure-based tool at the time called [omnibus](https://github.com/opscode/omnibus)
38
+ and were working on a Ruby-based version of omnibus as well.
39
+
40
+ However, the Ruby based Omnibus was not available at the time, so Bunchr was
41
+ created and it re-implements many of the concepts of the Clojure-based Omnibus
42
+ but on top of Ruby / Rake with a few differences.
43
+
44
+ Installation
45
+ ------------
46
+
47
+ ```
48
+ gem install bunchr
49
+ ```
50
+
51
+ DSL Overview
52
+ ------------
53
+
54
+ A typical Bunchr project is comprised of one or more `Bunchr::Software` objects
55
+ and a single `Bunchr::Packages` object. Define these all in a `Rakefile` or
56
+ separate them into files.
57
+
58
+ `Software` objects are responsible for downloading, building, and installing
59
+ a single software component, such as `zlib` or `ruby`. `Software` objects
60
+ support platform-specific compilation options by making Ohai data available
61
+ for decision making.
62
+
63
+ `Packages` objects are used to combine `Software` objects into a single package.
64
+ It will automatically try to generate any packages supported by the current
65
+ platform, for example, RPMs will be built if the platform supports it, DEB
66
+ will be built if the platform supports it.
67
+
68
+ The goal is to be able to use a single code base to build _and_ package a
69
+ project on multiple platforms.
70
+
71
+ Currently supported package types:
72
+
73
+ * tar.gz
74
+ * .deb
75
+ * .rpm
76
+
77
+ ### Software DSL
78
+
79
+ * Example software recipes: https://github.com/joemiller/bunchr/tree/master/example_recipes
80
+
81
+ Example recipe for building and installing `ruby`:
82
+
83
+ ```
84
+ Bunchr::Software.new do |t|
85
+ t.name = 'ruby'
86
+ t.version = '1.9.3-p125'
87
+
88
+ t.depends_on('autoconf')
89
+ t.depends_on('zlib')
90
+ t.depends_on('openssl')
91
+ t.depends_on('libyaml')
92
+
93
+ install_prefix = "#{Bunchr.install_dir}/embedded"
94
+
95
+ os = t.ohai['os']
96
+ arch = t.ohai['kernel']['machine']
97
+
98
+ t.download_commands << "curl -O http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p125.tar.gz"
99
+ t.download_commands << "tar xfvz ruby-1.9.3-p125.tar.gz"
100
+
101
+ if os == 'darwin' && arch == 'x86_64'
102
+ t.build_environment['LDFLAGS'] = "-arch x86_64 -R#{install_prefix}/lib -L#{install_prefix}/lib -I#{install_prefix}/include"
103
+ t.build_environment['CFLAGS'] = "-arch x86_64 -m64 -L#{install_prefix}/lib -I#{install_prefix}/include"
104
+ elsif os == 'linux'
105
+ t.build_environment['LDFLAGS'] = "-Wl,-rpath #{install_prefix}/lib -L#{install_prefix}/lib -I#{install_prefix}/include"
106
+ t.build_environment['CFLAGS'] = "-L#{install_prefix}/lib -I#{install_prefix}/include"
107
+ elsif os == 'solaris2'
108
+ t.build_environment['LDFLAGS'] = "-R#{install_prefix}/lib -L#{install_prefix}/lib -I#{install_prefix}/include"
109
+ t.build_environment['CFLAGS'] = "-L#{install_prefix}/lib -I#{install_prefix}/include"
110
+ end
111
+
112
+ t.build_commands << "./configure --prefix=#{install_prefix} \
113
+ --with-opt-dir=#{install_prefix} \
114
+ --enable-shared \
115
+ --disable-install-doc"
116
+ t.build_commands << "make"
117
+
118
+ t.install_commands << "make install"
119
+
120
+ CLEAN << install_prefix
121
+ end
122
+ ```
123
+
124
+ * `t.name` - Required. Name of the software component.
125
+
126
+ * `t.version` - Optional. Version of the software component.
127
+
128
+ * `t.depends_on(name)` - Optional. This is used to tell Bunchr that other
129
+ `Software` components should be built before this one.
130
+
131
+ * `t.ohai` - This provides access to the `Bunchr::Ohai` object which contains
132
+ Ohai data about the system. By default, only the `platform` and `os` plugins
133
+ are loaded. Since you have direct access to the Ohai object, other plugins
134
+ can be loaded by calling `t.ohai.require_plugin`
135
+
136
+ * `t.download_commands` - An array of shell commands used to download and
137
+ uncompress the source. You could also do a `git clone ..` here. These commands
138
+ are executed in the `download_dir` which is as `#{Bunchr.build_dir}/#{t.name}`.
139
+ The `download_dir` cannot be changed.
140
+
141
+ * `t.build_commands` - An array of shell commands used to compile the downloaded
142
+ source. These commands are executed in the directory defined by
143
+ `t.work_dir` which will be automatically determined from:
144
+ 1) `#{download_dir}/#{t.name}-#{t.version}` (common for most tarballs), or
145
+ 2) `#{download_dir}/#{t.name}` (if no `t.version` set), or
146
+ 3) explicitly set by calling `t.work_dir = '/some/absolute/path'`
147
+
148
+ * `t.install_commands` - An array of shell commands used to download and
149
+ uncompress the source. You could also do a `git clone ..` here. These commands
150
+ are executed in `t.work_dir` directory.
151
+
152
+ * `CLEAN` - Optional. This is an array of files and directories that should be deleted
153
+ when `rake clean` is executed.
154
+
155
+ `download_commands`, `build_commands`, and `install_commands` are all optional,
156
+ but unless one of them contains some commands your `Software` object won't be
157
+ doing anything useful.
158
+
159
+ If any of `download_commands`, `build_commands`, or `install_commands` exit
160
+ with a non-zero status, the entire Bunchr process will stop
161
+ and print any STDOUT or STDERR from the failed command to the Logger.
162
+
163
+ Bunchr will keep track of what has succeeded so that you can restart a failed
164
+ build after fixing an error. This can save quite a bit of time during package
165
+ development, but you should consider doing a full `rake clean` before building
166
+ any official packages.
167
+
168
+
169
+ All tasks created by a `Bunchr::Software` object are prefixed into the
170
+ `software:` namespace. To see the generated tasks:
171
+
172
+ ```
173
+ $ rake -T software:ruby
174
+ rake software:ruby # Download, build, and install ruby 1.9.3-p125
175
+ rake software:ruby:build # Build ruby 1.9.3-p125
176
+ rake software:ruby:download # Download ruby 1.9.3-p125
177
+ rake software:ruby:install # Install ruby 1.9.3-p125
178
+ ```
179
+
180
+ `Software` recipes can be defined directly in the Rakefile or they can
181
+ be separated into individual files and loaded via `Bunchr.load_recipes(files)`.
182
+
183
+ ### Packages DSL
184
+
185
+ A project will typically only contain a single `Bunchr::Packages` object which
186
+ is essentially a wrapper around `fpm` to create a single package. The Ohai
187
+ `platform` data will be used to determined what type of packages can be built
188
+ on the current system. Typically you would run the same Bunchr code on a
189
+ Debian based box to build the .deb, and a Redhat based box to build the .rpm.
190
+
191
+ Example `Rakefile`:
192
+
193
+ ```
194
+ require 'bunchr'
195
+
196
+ Bunchr.build_dir = '/tmp/build'
197
+ Bunchr.install_dir = '/opt/sensu'
198
+
199
+ Bunchr.load_recipes Dir['recipes/**/*.rake']
200
+
201
+ Bunchr::Packages.new do |t|
202
+ t.name = 'sensu'
203
+ t.version = ENV['SENSU_VERSION'] || '0.9.5'
204
+ t.iteration = ENV['BUILD_NUMBER'] || '1'
205
+
206
+ t.category = 'Monitoring'
207
+ t.license = 'MIT License'
208
+ t.vendor = 'Sonian Inc.'
209
+ t.url = 'https://github.com/sonian/sensu'
210
+ t.description = 'A monitoring framework that aims to be simple, malleable, and scalable. Publish/subscribe model.'
211
+
212
+ case t.ohai.platform_family
213
+ when 'debian'
214
+ t.scripts[:after_install] = 'pkg_scripts/deb/postinst'
215
+ t.scripts[:before_remove] = 'pkg_scripts/deb/prerm'
216
+ t.scripts[:after_remove] = 'pkg_scripts/deb/postrm'
217
+ when 'rhel', 'fedora'
218
+ t.scripts[:before_install] = 'pkg_scripts/rpm/pre'
219
+ t.scripts[:after_install] = 'pkg_scripts/rpm/post'
220
+ t.scripts[:before_remove] = 'pkg_scripts/rpm/preun'
221
+ end
222
+
223
+ t.include_software('ruby')
224
+ t.include_software('sensu')
225
+ t.include_software('sensu_dashboard')
226
+ t.include_software('sensu_configs')
227
+ t.include_software('sensu_bin_stubs')
228
+
229
+ t.files << Bunchr.install_dir # /opt/sensu
230
+ t.files << '/usr/share/sensu'
231
+ t.files << '/var/log/sensu'
232
+
233
+ t.files << '/etc/init.d/sensu-api'
234
+ t.files << '/etc/init.d/sensu-client'
235
+ t.files << '/etc/init.d/sensu-server'
236
+ t.files << '/etc/init.d/sensu-dashboard'
237
+
238
+ # need to enumerate config files for fpm
239
+ # these are installed from recipe/sensu_configs.rake
240
+ t.config_files << "/etc/sensu/handlers/default"
241
+ t.config_files << "/etc/sensu/conf.d/client.json"
242
+ t.config_files << "/etc/sensu/conf.d/checks.json"
243
+ t.config_files << "/etc/sensu/conf.d/handlers.json"
244
+ t.config_files << "/etc/sensu/config.json"
245
+
246
+ t.config_files << '/etc/logrotate.d/sensu'
247
+ end
248
+
249
+ # default task executed when `rake` is run with no args.
250
+ task :default => ['packages:sensu']
251
+ ```
252
+
253
+ Let's break it all down:
254
+
255
+ * `Bunchr.build_dir` - Required. This variable is available to all
256
+ `Bunchr::Software` recipes specifying a temporary directory used for
257
+ downloading and compiling.
258
+
259
+ * `Bunchr.install_dir` - Required. This variable is available to all
260
+ `Bunchr::Software` recipes. It will typically be the base directory
261
+ where all software is installed.
262
+
263
+ The following variables are used to drive `fpm` when building packages:
264
+
265
+ * `t.name`, `t.version`, `t.iteration` - Required.
266
+ Used by `fpm` to construct the package names, ie:
267
+ `name-version-iteration-arch.rpm`
268
+
269
+ * `t.arch` - Optional. Can be used to override the default detected
270
+ architecture, eg: `all` or `noarch`.
271
+
272
+ * `t.category`, `t.license`, `t.vendor`, `t.url`, `t.description` -
273
+ Optional. Package metadata.
274
+
275
+ * `t.include_software(name)` - Optional. This is used to tell Bunchr what
276
+ `Software` components should be built and installed before creating
277
+ packages.
278
+
279
+ * `t.scripts` - Optional. A hash with keys: `:after_install`, `:before_install`,
280
+ `:after_remove`, and `:before_remove`. The specified files will be included
281
+ with the packages.
282
+
283
+ * `t.files` - Required. An array of files and directories to include.
284
+
285
+ * `t.config_files` - Optional. An array of files that will be marked as
286
+ configuration files (if supported by the underlying package type).
287
+ Config_files are automatically added to the `t.files` array.
288
+
289
+ NOTE: you must specify individual files, not directories.
290
+
291
+ All tasks created by a `Bunchr::Packages` object are prefixed into the
292
+ `packages:` namespace. To see the generated tasks:
293
+
294
+ ```
295
+ $ rake -T packages
296
+ rake packages:sensu # Create bunchr packages for sensu 0.9.5-1
297
+ rake packages:sensu:build # Build all packages: sensu-0.9.5-1-x86_64
298
+ rake packages:sensu:build_deb # Build deb: sensu-0.9.5-1-x86_64
299
+ rake packages:sensu:build_rpm # Build RPM: sensu-0.9.5-1-x86_64
300
+ rake packages:sensu:build_tarball # Build tarball: sensu-0.9.5-1-x86_64.tar.gz
301
+ ```
302
+
303
+ The main task is `packages:#{name}`. Exec this task to create all relevant
304
+ packages.
305
+
306
+ Integration with Vagrant
307
+ ------------------------
308
+
309
+ * TODO. maybe link to sensu-bunchr here.
310
+
311
+ Other Examples
312
+ --------------
313
+
314
+ * TODO. maybe link to sensu-bunchr here, or a complete example of fpm
315
+
316
+ Author
317
+ ------
318
+
319
+ * [Joe Miller](https://twitter.com/miller_joe) - http://joemiller.me / https://github.com/joemiller
320
+
321
+ Licensing
322
+ ---------
323
+ todo, apache
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'rubygems/package_task'
3
+
4
+ spec = eval(File.read('bunchr.gemspec'))
5
+
6
+ Gem::PackageTask.new(spec) do |pkg|
7
+ end
8
+
9
+ task :default => :gem
data/TODO ADDED
@@ -0,0 +1,7 @@
1
+ x rakefile
2
+ readme
3
+ vagrant examples (or link to sensu?)
4
+ other examples (or link to sensu-bunchr?)
5
+ refactor sensu project to use the gem
6
+ publish to github
7
+ twitter to those who were interested
data/bunchr.gemspec ADDED
@@ -0,0 +1,34 @@
1
+
2
+ # -*- encoding: utf-8 -*-
3
+ $:.push('lib')
4
+ require "bunchr/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "bunchr"
8
+ s.version = Bunchr::VERSION.dup
9
+ s.date = "2012-04-17"
10
+ s.summary = "A DSL for bundling complex software projects into 'omnibus'-style packages."
11
+ s.email = "joeym@joeym.net"
12
+ s.homepage = "https://github.com/joemiller/bunchr"
13
+ s.authors = ['Joe Miller']
14
+
15
+ s.description = <<-EOF
16
+ A DSL for building complex software projects and packaging them (RPM, DEB, etc).
17
+ Originally developed to create "omnibus" style packages that include an entire
18
+ ruby stack along with one or more gems, but useful for general compilation and
19
+ packaging as well.
20
+ EOF
21
+
22
+ s.files = Dir['**/*']
23
+ s.require_paths = ["lib"]
24
+
25
+ ## Make sure you can build the gem on older versions of RubyGems too:
26
+ s.rubygems_version = "1.3.6"
27
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
28
+ s.specification_version = 3 if s.respond_to? :specification_version
29
+
30
+ s.add_dependency("rake", ">= 0.8.0")
31
+ s.add_dependency("ohai")
32
+ s.add_dependency("systemu")
33
+ s.add_dependency("fpm", "~> 0.4.6")
34
+ end
@@ -0,0 +1,201 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
+ <title>
7
+ Class: Bunchr::Logger
8
+
9
+ &mdash; Documentation by YARD 0.7.5
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="../css/style.css" type="text/css" media="screen" charset="utf-8" />
14
+
15
+ <link rel="stylesheet" href="../css/common.css" type="text/css" media="screen" charset="utf-8" />
16
+
17
+ <script type="text/javascript" charset="utf-8">
18
+ relpath = '..';
19
+ if (relpath != '') relpath += '/';
20
+ </script>
21
+
22
+ <script type="text/javascript" charset="utf-8" src="../js/jquery.js"></script>
23
+
24
+ <script type="text/javascript" charset="utf-8" src="../js/app.js"></script>
25
+
26
+
27
+ </head>
28
+ <body>
29
+ <script type="text/javascript" charset="utf-8">
30
+ if (window.top.frames.main) document.body.className = 'frames';
31
+ </script>
32
+
33
+ <div id="header">
34
+ <div id="menu">
35
+
36
+ <a href="../_index.html">Index (L)</a> &raquo;
37
+ <span class='title'><span class='object_link'><a href="../Bunchr.html" title="Bunchr (module)">Bunchr</a></span></span>
38
+ &raquo;
39
+ <span class="title">Logger</span>
40
+
41
+
42
+ <div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
43
+ </div>
44
+
45
+ <div id="search">
46
+
47
+ <a id="class_list_link" href="#">Class List</a>
48
+
49
+ <a id="method_list_link" href="#">Method List</a>
50
+
51
+ <a id="file_list_link" href="#">File List</a>
52
+
53
+ </div>
54
+ <div class="clear"></div>
55
+ </div>
56
+
57
+ <iframe id="search_frame"></iframe>
58
+
59
+ <div id="content"><h1>Class: Bunchr::Logger
60
+
61
+
62
+
63
+ </h1>
64
+
65
+ <dl class="box">
66
+
67
+ <dt class="r1">Inherits:</dt>
68
+ <dd class="r1">
69
+ <span class="inheritName">Object</span>
70
+
71
+ <ul class="fullTree">
72
+ <li>Object</li>
73
+
74
+ <li class="next">Bunchr::Logger</li>
75
+
76
+ </ul>
77
+ <a href="#" class="inheritanceTree">show all</a>
78
+
79
+ </dd>
80
+
81
+
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+ <dt class="r2 last">Defined in:</dt>
90
+ <dd class="r2 last">lib/bunchr/logger.rb</dd>
91
+
92
+ </dl>
93
+ <div class="clear"></div>
94
+
95
+
96
+ <h2>Constant Summary</h2>
97
+
98
+ <dl class="constants">
99
+
100
+ <dt id="log-classvariable" class="">@@log =
101
+
102
+ </dt>
103
+ <dd><pre class="code"><span class='kw'>nil</span></pre></dd>
104
+
105
+ </dl>
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+ <h2>
116
+ Class Method Summary
117
+ <small>(<a href="#" class="summary_toggle">collapse</a>)</small>
118
+ </h2>
119
+
120
+ <ul class="summary">
121
+
122
+ <li class="public ">
123
+ <span class="summary_signature">
124
+
125
+ <a href="#logger-class_method" title="logger (class method)">+ (Object) <strong>logger</strong> </a>
126
+
127
+
128
+
129
+ </span>
130
+
131
+
132
+
133
+
134
+
135
+
136
+
137
+
138
+ <span class="summary_desc"><div class='inline'></div></span>
139
+
140
+ </li>
141
+
142
+
143
+ </ul>
144
+
145
+
146
+
147
+
148
+ <div id="class_method_details" class="method_details_list">
149
+ <h2>Class Method Details</h2>
150
+
151
+
152
+ <div class="method_details first">
153
+ <p class="signature first" id="logger-class_method">
154
+
155
+ + (<tt>Object</tt>) <strong>logger</strong>
156
+
157
+
158
+
159
+ </p><table class="source_code">
160
+ <tr>
161
+ <td>
162
+ <pre class="lines">
163
+
164
+
165
+ 8
166
+ 9
167
+ 10
168
+ 11
169
+ 12
170
+ 13
171
+ 14
172
+ 15</pre>
173
+ </td>
174
+ <td>
175
+ <pre class="code"><span class="info file"># File 'lib/bunchr/logger.rb', line 8</span>
176
+
177
+ <span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_logger'>logger</span><span class='lparen'>(</span><span class='rparen'>)</span>
178
+ <span class='kw'>if</span> <span class='cvar'>@@log</span><span class='period'>.</span><span class='id identifier rubyid_nil?'>nil?</span>
179
+ <span class='cvar'>@@log</span> <span class='op'>||=</span> <span class='op'>::</span><span class='const'>Logger</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='lparen'>(</span><span class='const'>STDOUT</span><span class='rparen'>)</span>
180
+ <span class='cvar'>@@log</span><span class='period'>.</span><span class='id identifier rubyid_level'>level</span> <span class='op'>=</span> <span class='const'>ENV</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>BUNCHR_DEBUG</span><span class='tstring_end'>'</span></span><span class='rbracket'>]</span> <span class='op'>?</span> <span class='op'>::</span><span class='const'>Logger</span><span class='op'>::</span><span class='const'>DEBUG</span> <span class='op'>:</span> <span class='op'>::</span><span class='const'>Logger</span><span class='op'>::</span><span class='const'>INFO</span>
181
+ <span class='comment'># @@log.level = ::Logger::DEBUG
182
+ </span> <span class='kw'>end</span>
183
+ <span class='cvar'>@@log</span>
184
+ <span class='kw'>end</span></pre>
185
+ </td>
186
+ </tr>
187
+ </table>
188
+ </div>
189
+
190
+ </div>
191
+
192
+ </div>
193
+
194
+ <div id="footer">
195
+ Generated on Wed Apr 18 17:18:48 2012 by
196
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
197
+ 0.7.5 (ruby-1.9.2).
198
+ </div>
199
+
200
+ </body>
201
+ </html>