pkgr 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Plug this [Railtie](http://api.rubyonrails.org/classes/Rails/Railtie.html)
4
4
  into your Rails 3 app (ruby1.9 only), and you'll be ready to package your
5
- Rails app as a DEB or RPM (coming soon) package.
5
+ Rails app as a DEB package. RPM support could be added in the short future.
6
6
 
7
7
  ## Why?
8
8
 
@@ -37,7 +37,7 @@ So, how are we going to easily package Ruby applications and avoid dependency
37
37
  issues? Well, I know package maintainers will scream at me, but we'll just
38
38
  vendor the required gems in the package we'll build, and use bundler to manage
39
39
  those dependencies. Thus, the only dependency we'll put in our package will be
40
- the Ruby1.9 (+rubygems).
40
+ Ruby1.9 (+rubygems).
41
41
 
42
42
  ## What?
43
43
 
@@ -50,13 +50,271 @@ few other things.
50
50
  The default target installation directory for the other app files will be
51
51
  `/opt/local/app-name`. This can be configured.
52
52
 
53
- ## Usage
53
+ ## Requirements
54
+
55
+ * You must use Rails3+ and ruby1.9+ in your application. This may work with
56
+ other rubies but then you'll need to add a rubygems dependency.
57
+
58
+ * Your Rails application must be able to run with the
59
+ [`thin`](http://code.macournoyer.com/thin/) web server. Don't forget to add
60
+ `thin` to your Gemfile!
61
+
62
+ * Your application must be checked into a **Git** repository. Your name and
63
+ email is taken from the git configuration, and the changelog is populated
64
+ based on the git log between two versions.
65
+
66
+ ## Getting started
67
+
68
+ Or, how to build a debian package of your Rails app in 5 minutes.
69
+
70
+ ### Setup
71
+
72
+ Create a new Rails app:
73
+
74
+ $ rails new my-app --skip-bundle
75
+ create
76
+ create README.rdoc
77
+ create Rakefile
78
+ ...
79
+ create vendor/plugins
80
+ create vendor/plugins/.gitkeep
81
+
82
+ Go into your app directory, and add `pkgr` to your Gemfile:
83
+
84
+ $ cd my-app
85
+ $ echo "gem 'pkgr', :group => :development" >> Gemfile
86
+
87
+ For now, this packaging tool only supports `thin` (would be easy to add others, though), so add it to your Gemfile:
88
+
89
+ $ echo "gem 'thin'" >> Gemfile
90
+
91
+ Install the gems:
92
+
93
+ $ bundle install
94
+
95
+ If it's not already done, initialize a git repository and create a first commit:
96
+
97
+ $ git init
98
+ $ git add .
99
+ $ git commit -m "First commit"
100
+
101
+ Setup `pkgr`:
102
+
103
+ $ rake pkgr:setup
104
+ Setting up configuration file...
105
+ ...
106
+ Edit '/Users/crohr/tmp/my-app/config/pkgr.yml' and fill in the required information, then enter 'rake pkgr:generate' to generate the debian files.
107
+
108
+ As outlined, edit `config/pkgr.yml` and fill in your app name. In our example I'll fill in `my-app` as the app name. Also, you should edit the runtime and build dependencies (though the default ones should be fine with a base Rails app).
109
+
110
+ An example `pkgr.yml` file is given below:
111
+
112
+ ---
113
+ version: 0.4.0
114
+ name: my-app
115
+ description: This is a description
116
+ git_ref: HEAD
117
+ config_files:
118
+ - pkgr.yml
119
+ - database.yml
120
+ architecture: amd64
121
+ debian_runtime_dependencies:
122
+ - ${shlibs:Depends}
123
+ - ${misc:Depends}
124
+ - ruby1.9.1-full
125
+ - git-core
126
+ - libxml2
127
+ - libxslt1.1
128
+ debian_build_dependencies:
129
+ - debhelper (>= 7)
130
+ - dpkg-dev
131
+ - libmysqlclient15-dev
132
+ - libxml2-dev
133
+ - libxslt-dev
134
+ - libsqlite3-dev
135
+
136
+ ### Generate the packaging files
137
+
138
+ Now generate the required files for packaging:
139
+
140
+ $ rake pkgr:generate
141
+ mkdir -p /Users/crohr/tmp/my-app/debian
142
+ cp /Users/crohr/.rvm/gems/ruby-1.9.3-p125/gems/pkgr-0.1.0/lib/pkgr/data/debian/changelog /Users/crohr/tmp/my-app/debian/changelog
143
+ cp /Users/crohr/.rvm/gems/ruby-1.9.3-p125/gems/pkgr-0.1.0/lib/pkgr/data/debian/cron.d /Users/crohr/tmp/my-app/debian/cron.d
144
+ Correctly set up debian files.
145
+ mkdir -p /Users/crohr/tmp/my-app/bin
146
+ cp /Users/crohr/.rvm/gems/ruby-1.9.3-p125/gems/pkgr-0.1.0/lib/pkgr/data/bin/executable /Users/crohr/tmp/my-app/bin/my-app
147
+ chmod 755 /Users/crohr/tmp/my-app/bin/my-app
148
+ Correctly set up executable file. Try running './bin/my-app console'.
149
+
150
+ This will have created the required `debian/` files, plus an executable for your app, so that you're able to do the following:
151
+
152
+ $ ./bin/my-app console development
153
+ $ ./bin/my-app server start -e development
154
+ $ ./bin/my-app rake some_task
155
+
156
+ This is especially useful when the app is deployed on a server, since the executable will be added to the path!
157
+
158
+ By default, you should not have to change anything in the `debian/` folder, so let's package our app.
159
+
160
+ ### Package the app
161
+
162
+ First, make sure you committed all your changes:
163
+
164
+ $ git add .
165
+ $ git commit -m "..."
166
+
167
+ Then increase the version number:
168
+
169
+ $ rake pkgr:bump:minor
170
+ Committing changelog and version file...
171
+ git add debian/changelog /Users/crohr/tmp/my-app/config/pkgr.yml && git commit -m 'v0.1.0' debian/changelog /Users/crohr/tmp/my-app/config/pkgr.yml
172
+ [master c05dd73] v0.1.0
173
+ 2 files changed, 29 insertions(+), 31 deletions(-)
174
+ rewrite config/pkgr.yml (82%)
175
+ create mode 100755 debian/changelog
176
+
177
+ Make sure you do not have any staged change (otherwise, commit them):
178
+
179
+ $ git status
180
+ # On branch master
181
+ nothing to commit (working directory clean)
182
+
183
+ Finally, ask to build the package on a machine running Debian Squeeze (I generally use my SSH config file to handle the SSH connection details for the specified host):
184
+
185
+ $ HOST=debian-build-machine rake pkgr:build:deb
186
+
187
+ After some time, you should get a final line with the name of your debian package:
188
+
189
+ [... lots of lines ...]
190
+ my-app_0.1.0-1_amd64.deb
191
+
192
+ Make sure it is really here:
193
+
194
+ $ ls -l pkg/
195
+ total 12128
196
+ -rw-r--r-- 1 crohr staff 6207392 May 4 10:57 my-app_0.1.0-1_amd64.deb
197
+
198
+ ### Use it
199
+
200
+ Now you can either upload it to an apt repository (if you have one, I'll make a tutorial on how to set up a simple one), or just test that the package works by installing it on your build machine (or another one, for that matter, but you'll have to manually re-install the dependencies):
201
+
202
+ $ scp pkg/my-app_0.1.0-1_amd64.deb debian-build-machine:/tmp/
203
+ $ ssh debian-build-machine
204
+ debian-build-machine $ sudo dpkg -i /tmp/my-app_0.1.0-1_amd64.deb
205
+ Selecting previously deselected package my-app.
206
+ (Reading database ... 53073 files and directories currently installed.)
207
+ Unpacking my-app (from /tmp/my-app_0.1.0-1_amd64.deb) ...
208
+ Setting up my-app (0.1.0-1) ...
209
+ Installing new version of config file /etc/my-app/pkgr.yml ...
210
+ Adding system user `my-app' (UID 105) ...
211
+ Adding new group `my-app' (GID 108) ...
212
+ Adding new user `my-app' (UID 105) with group `my-app' ...
213
+ Not creating home directory `/home/my-app'.
214
+ Starting my-app: OK.
215
+
216
+ Make sure your app is running:
217
+
218
+ debian-build-machine $ ps aux | grep my-app | grep -v grep
219
+ my-app 13928 3.5 10.5 143436 40004 ? Sl 11:06 0:02 thin server (0.0.0.0:8000) [my-app-0.1.0]
220
+
221
+ Notice how the process name shows the version number? From experience, this is really useful.
222
+
223
+ Now you can send a first request:
224
+
225
+ $ curl localhost:8000/
226
+ <!DOCTYPE html>
227
+ <html>
228
+ <head>
229
+ <title>The page you were looking for doesn't exist (404)</title>
230
+ <style type="text/css">
231
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
232
+ div.dialog {
233
+ width: 25em;
234
+ padding: 0 4em;
235
+ margin: 4em auto 0 auto;
236
+ border: 1px solid #ccc;
237
+ border-right-color: #999;
238
+ border-bottom-color: #999;
239
+ }
240
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
241
+ </style>
242
+ </head>
243
+
244
+ <body>
245
+ <!-- This file lives in public/404.html -->
246
+ <div class="dialog">
247
+ <h1>The page you were looking for doesn't exist.</h1>
248
+ <p>You may have mistyped the address or the page may have moved.</p>
249
+ </div>
250
+ </body>
251
+ </html>
252
+
253
+ Obviously this app does nothing, so you'll get a 404. So go back to building your app, and then just type `rake pkgr:bump:patch` and `HOST=debian-build-machine rake pkgr:build:deb` to generate a new package !
254
+
255
+ ## Release it (debian)
256
+
257
+ As of 0.2.0, you can now release the latest package on a server, and add it to
258
+ your list of APT sources for easy installation. In the following we'll assume
259
+ that you want to serve your packages from a host called `apt-server`.
260
+
261
+ Once you've built the package, run the following to upload it to the
262
+ apt-server and generate the manifest:
263
+
264
+ $ HOST=apt-server rake pkgr:release:deb
265
+
266
+ Note that you need **sudo** privileges for this. If all goes well, you should
267
+ now have a directory named `/var/www/my-app` on `apt-server`. The next step is
268
+ to serve this directory over HTTP. Simply enough, install `apache2` and you're
269
+ good to go:
270
+
271
+ $ ssh apt-server 'sudo apt-get install apache2 -y'
272
+
273
+ Now, on the server on which you want to install the package (let's say
274
+ `production-server`), just add an additional APT source file referencing this
275
+ new APT server:
276
+
277
+
278
+ production-server # cat /etc/apt/sources.list.d/my-app.list
279
+ deb http://apt-server.ltd/my-app /
280
+
281
+ And then:
282
+
283
+ production-server # apt-get update && apt-get install my-app
284
+
285
+ Note that you may need to add the following to a
286
+ `/etc/apt/apt.conf.d/allow-unauthenticated` file if apt complains about
287
+ unauthenticated packages:
288
+
289
+ production-server # echo 'APT::Get::AllowUnauthenticated "true";' >> /etc/apt/apt.conf.d/allow-unauthenticated
290
+
291
+ Easy.
292
+
293
+ ## Notes of interest
294
+
295
+ * your configuration files will be stored in `/etc/my-app/*.yml`, making it easy to manage with Puppet or manually (don't forget to `/etc/init.d/my-app restart` after making changes).
296
+
297
+ * you can change how the Thin server is launched by adding options to the `/etc/default/my-app` file.
298
+
299
+ * your log files will be stored in `/var/log/my-app/`.
300
+
301
+ * your db files will be stored in `var/db/my-app/`.
302
+
303
+ * if you've got migrations to run, just do a `my-app rake db:migrate` (we might want to run them automatically as part of the postinstall process).
304
+
305
+ * you can launch a console using `my-app console`.
306
+
307
+ * use the initd script to start and stop the app: `/etc/init.d/my-app [start|stop|status]`.
308
+
309
+ ## General usage
54
310
 
55
311
  Declare `pkgr` as one of your **development** dependencies in your `Gemfile`:
56
312
 
57
- group :development do
58
- gem 'pkgr'
59
- end
313
+ gem 'pkgr', :group => :development
314
+
315
+ Also add `thin`:
316
+
317
+ gem 'thin'
60
318
 
61
319
  Now make sure you have all the gems installed:
62
320
 
@@ -80,24 +338,20 @@ Now you can generate all the files required for building a debian package:
80
338
  A new directory `debian/` should have been created. You can have a look at it,
81
339
  but you should not have to edit anything manually.
82
340
 
83
- Once you're ready to package your app, just run the following steps:
84
-
85
- * Increment the version number:
86
-
87
- rake pkgr:bump:patch # or rake pkgr:bump:minor or rake pkgr:bump:major
88
-
89
- * Re-generate the debian files:
90
-
91
- rake pkgr:generate
341
+ Once you're ready to package your app, just run the following commands:
92
342
 
93
343
  * Commit your changes (the `pkgr` app will `git archive HEAD`, which means all
94
344
  your changes must be committed first -- we may want to change this):
95
345
 
96
346
  commit -am "..."
97
347
 
348
+ * Increment the version number:
349
+
350
+ rake pkgr:bump:patch # or rake pkgr:bump:minor or rake pkgr:bump:major
351
+
98
352
  * Build the package on your machine (default, but you better be running a
99
- Debian Squeeze), or on a remote machine (recommended, for instance you can
100
- get a Vagrant VM in no time):
353
+ Debian Squeeze, and have an SSH server running), or on a remote machine
354
+ (recommended, for instance you can get a Vagrant VM in no time):
101
355
 
102
356
  HOST=debian-build-machine rake pkgr:build:deb
103
357
  # or HOST=localhost rake pkgr:build:deb, or just rake pkgr:build:deb
@@ -105,7 +359,7 @@ Once you're ready to package your app, just run the following steps:
105
359
  Note that the user with which you're connecting to the build machine **must
106
360
  have `sudo` privileges** (required to install build and runtime
107
361
  dependencies).
108
-
362
+
109
363
  Also, it's most likely that you'll have to do this a few times at first, as
110
364
  well as adding missing runtime and build dependencies, before your app can
111
365
  be successfully packaged.
@@ -114,22 +368,8 @@ Once you're ready to package your app, just run the following steps:
114
368
  app. Next step is probably to upload it to a local apt repository, and then
115
369
  a simple `apt-get install my-app` will install everything. Enjoy!
116
370
 
117
- Have a look at the Getting Started guide in the `doc` folder of this repository.
118
-
119
- ## Requirements
120
-
121
- * You must use Rails3+ and ruby1.9+ in your application. This may work with
122
- other rubies but then you'll need to add a rubygems dependency.
123
-
124
- * Your Rails application must be able to run with the
125
- [`thin`](http://code.macournoyer.com/thin/) web server. Don't forget to add
126
- `thin` to your Gemfile!
127
-
128
- * Your application must be checked into a **Git** repository. Your name and
129
- email is taken from the git configuration, and the changelog is populated
130
- based on the git log between two versions.
131
371
 
132
- ## TODO
372
+ ## Todo
133
373
 
134
374
  * Speed up the packaging process (currently, bundler re-downloads all the gems
135
375
  each time you package an app).
data/lib/pkgr/app.rb CHANGED
@@ -197,25 +197,18 @@ module Pkgr
197
197
  puts "Building debian package on '#{host}'..."
198
198
  Dir.chdir(root) do
199
199
  Pkgr.mkdir("pkg")
200
- case host
201
- when 'localhost'
202
- debian_steps.each do |step|
203
- sh step
204
- end
205
- else
206
- archive = "#{name}-#{version}"
207
- sh "scp #{File.expand_path("../data/config/pre_boot.rb", __FILE__)} #{host}:/tmp/"
208
- cmd = %Q{
209
- git archive #{git_ref} --prefix=#{archive}/ | ssh #{host} 'cat - > /tmp/#{archive}.tar &&
210
- set -x && rm -rf /tmp/#{archive} &&
211
- cd /tmp && tar xf #{archive}.tar && cd #{archive} &&
212
- cat config/boot.rb >> /tmp/pre_boot.rb && cp -f /tmp/pre_boot.rb config/boot.rb &&
213
- #{debian_steps.join(" &&\n")}'
214
- }
215
- sh cmd
216
- # Fetch the .deb, and put it in the `pkg` directory
217
- sh "scp #{host}:/tmp/#{name}_#{version}*.deb pkg/"
218
- end
200
+ archive = "#{name}-#{version}"
201
+ sh "scp #{File.expand_path("../data/config/pre_boot.rb", __FILE__)} #{host}:/tmp/"
202
+ cmd = %Q{
203
+ git archive #{git_ref} --prefix=#{archive}/ | ssh #{host} 'cat - > /tmp/#{archive}.tar &&
204
+ set -x && rm -rf /tmp/#{archive} &&
205
+ cd /tmp && tar xf #{archive}.tar && cd #{archive} &&
206
+ cat config/boot.rb >> /tmp/pre_boot.rb && cp -f /tmp/pre_boot.rb config/boot.rb &&
207
+ #{debian_steps.join(" &&\n")}'
208
+ }
209
+ sh cmd
210
+ # Fetch the .deb, and put it in the `pkg` directory
211
+ sh "scp #{host}:/tmp/#{name}_#{version}*.deb pkg/"
219
212
  end
220
213
  end
221
214
 
@@ -231,6 +224,23 @@ module Pkgr
231
224
  "dpkg-buildpackage -us -uc -d"
232
225
  ]
233
226
  end
227
+
228
+ def release_debian_package(host, apt_directory = nil)
229
+ apt_directory ||= "/var/www/#{name}"
230
+ latest = Dir[File.join(root, "pkg", "*.deb")].find{|file| file =~ /#{version}/}
231
+ raise "No .deb available in pkg/" if latest.nil?
232
+ latest_name = File.basename(latest)
233
+ sh "scp #{latest} #{host}:/tmp/"
234
+ sh "ssh #{host} 'sudo mkdir -p #{apt_directory} && sudo chown $USER #{apt_directory} && mv /tmp/#{latest_name} #{apt_directory} && cd #{apt_directory} && ( which dpkg-scanpackages || sudo apt-get update && sudo apt-get install dpkg-dev -y ) && dpkg-scanpackages . | gzip -f9 > Packages.gz'"
235
+ puts "****"
236
+ puts "Now you just need to serve the '#{apt_directory}' directory over HTTP, and add a new source to your APT configuration on the production server:"
237
+ puts "$ cat /etc/apt/sources.list.d/#{name}.list"
238
+ puts "deb http://apt-server.ltd/#{name} /"
239
+ puts
240
+ puts "And then:"
241
+ puts "$ sudo apt-get update && sudo apt-get install #{name}"
242
+ puts "****"
243
+ end
234
244
 
235
245
  private
236
246
  def bundler_version
data/lib/pkgr/pkgr.rake CHANGED
@@ -38,5 +38,13 @@ namespace :pkgr do
38
38
  APP.build_debian_package(build_host)
39
39
  end
40
40
  end
41
+
42
+ namespace :release do
43
+ desc "Release the latest package on a custom APT repository"
44
+ task :deb do
45
+ apt_host = ENV.fetch('HOST') { 'localhost' }
46
+ APP.release_debian_package(apt_host)
47
+ end
48
+ end
41
49
  end
42
50
  end
data/lib/pkgr/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pkgr
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pkgr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: