cany 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +38 -0
- data/Gemfile +12 -0
- data/Guardfile +20 -0
- data/Rakefile +11 -0
- data/lib/cany.rb +88 -19
- data/lib/cany/dependency.rb +70 -0
- data/lib/cany/dpkg/builder.rb +4 -16
- data/lib/cany/dpkg/creator.rb +39 -29
- data/lib/cany/dpkg/deb_helper_recipe.rb +105 -20
- data/lib/cany/errors.rb +62 -0
- data/lib/cany/mixins/depend_mixin.rb +22 -0
- data/lib/cany/recipe.rb +182 -11
- data/lib/cany/recipes/bundler.rb +28 -5
- data/lib/cany/recipes/bundler/gem.rb +50 -0
- data/lib/cany/recipes/bundler/gem_db.rb +27 -0
- data/lib/cany/recipes/rails.rb +19 -2
- data/lib/cany/recipes/sidekiq.rb +38 -0
- data/lib/cany/recipes/thin.rb +24 -18
- data/lib/cany/recipes/unicorn.rb +16 -0
- data/lib/cany/recipes/web_server.rb +5 -19
- data/lib/cany/specification.rb +49 -1
- data/lib/cany/specification/dsl.rb +23 -3
- data/lib/cany/version.rb +2 -2
- data/spec/cany/dependency_spec.rb +120 -0
- data/spec/cany/dpkg/builder_spec.rb +38 -0
- data/spec/{dpkg → cany/dpkg}/creator_spec.rb +26 -2
- data/spec/cany/dpkg/deb_helper_recipe_spec.rb +91 -0
- data/spec/cany/recipe_spec.rb +213 -0
- data/spec/cany/recipes/bundler/gem_spec.rb +46 -0
- data/spec/cany/recipes/bundler_spec.rb +29 -0
- data/spec/cany/recipes/rails_spec.rb +28 -0
- data/spec/cany/recipes/sidekiq_spec.rb +52 -0
- data/spec/cany/specification_spec.rb +113 -1
- data/spec/spec_helper.rb +31 -4
- metadata +29 -6
- data/spec/dpkg/builder_spec.rb +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 689bd4e09a4407570532a6ec0679c9d75c67f020
|
4
|
+
data.tar.gz: fda3db01834b24bb64435e07f1c12cd37463e551
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be07431ce48ede3893ebb6b3cfcbdd45ac97313cc8239852239a9560bc054e42c7cb468193678a656e7735a7523b95b7ffeb4d4ee855b1e6707c8c04ccdf35d0
|
7
|
+
data.tar.gz: da2e5f74092021b94313860e4bf32ad9142b5fd16fea636e07563c3e6d8633bbe4776c16c21465b5b27bacd7af064ca14ba5014f85bd9f66d16c62179f9c5f5d
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
0.1.0 / 2013-09-23
|
2
|
+
==================
|
3
|
+
|
4
|
+
Features:
|
5
|
+
|
6
|
+
+ Support recipe hooks
|
7
|
+
+ Support recipe (configuration) option
|
8
|
+
+ Rewritten and extended dependency management
|
9
|
+
+ Support (source) package generation adjustments by recipes
|
10
|
+
+ canspec: new require_cany directive
|
11
|
+
+ Support per rails configuration
|
12
|
+
+ Refactored init script management (supports multiple services per package)
|
13
|
+
+ sidekiq recipe
|
14
|
+
+ unicorn recipe
|
15
|
+
|
16
|
+
Bug fixes:
|
17
|
+
|
18
|
+
* rails: export RAILS_ENV in wrapper script
|
19
|
+
* bundler: add some more gem dependencies
|
20
|
+
* recipe: exit on failed command (like bundle install)
|
21
|
+
* dpkg: create compat 9 packages
|
22
|
+
|
23
|
+
|
24
|
+
0.0.2 / 2013-09-13
|
25
|
+
==================
|
26
|
+
|
27
|
+
Bug fixes:
|
28
|
+
|
29
|
+
* rails: run asset compilation inside assets environment
|
30
|
+
* dpkg: replace hard coded package name
|
31
|
+
* rails: run rake inside bundle
|
32
|
+
* recipe: use same ruby intepreter as for cany
|
33
|
+
|
34
|
+
|
35
|
+
0.0.1 / 2013-09-12
|
36
|
+
==================
|
37
|
+
|
38
|
+
* Basic support to pack a rails application
|
data/Gemfile
CHANGED
@@ -3,6 +3,18 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in cany.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
+
group :development do
|
7
|
+
gem 'yard', '~> 0.8.6'
|
8
|
+
gem 'guard'
|
9
|
+
gem 'libnotify', :require => false
|
10
|
+
gem 'rb-inotify', :require => false
|
11
|
+
gem 'rb-fsevent', :require => false
|
12
|
+
gem 'rb-fchange', :require => false
|
13
|
+
gem 'guard-rspec'
|
14
|
+
gem 'guard-yard'
|
15
|
+
gem 'redcarpet', platform: :ruby
|
16
|
+
end
|
17
|
+
|
6
18
|
group :test do
|
7
19
|
gem 'deb_control', '~> 0.0.1'
|
8
20
|
gem 'coveralls', require: false
|
data/Guardfile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#
|
2
|
+
# Guardfile -- for RSpec
|
3
|
+
#
|
4
|
+
|
5
|
+
guard 'rspec', all_after_pass: true, all_on_start: true do
|
6
|
+
watch(%r{^spec/(.+)_spec\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
7
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
8
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
9
|
+
watch('spec/spec_helper.rb') { "spec" }
|
10
|
+
end
|
11
|
+
|
12
|
+
guard 'yard' do
|
13
|
+
watch(%r{lib/.+\.rb})
|
14
|
+
end
|
15
|
+
|
16
|
+
# load Guardfile.local
|
17
|
+
local_guardfile = File.dirname(__FILE__) + "/Guardfile.local"
|
18
|
+
if File.file?(local_guardfile)
|
19
|
+
self.instance_eval(Bundler.read_file(local_guardfile))
|
20
|
+
end
|
data/Rakefile
CHANGED
@@ -3,3 +3,14 @@ require 'rspec/core/rake_task'
|
|
3
3
|
|
4
4
|
RSpec::Core::RakeTask.new(:spec)
|
5
5
|
task default: :spec
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'yard'
|
9
|
+
require 'yard/rake/yardoc_task'
|
10
|
+
|
11
|
+
YARD::Rake::YardocTask.new do |t|
|
12
|
+
t.files = %w(lib/**/*.rb)
|
13
|
+
t.options = %w(--output-dir doc/)
|
14
|
+
end
|
15
|
+
rescue LoadError
|
16
|
+
end
|
data/lib/cany.rb
CHANGED
@@ -1,29 +1,98 @@
|
|
1
|
-
require '
|
2
|
-
require 'cany/specification'
|
3
|
-
require 'cany/recipe'
|
4
|
-
require 'cany/recipes/bundler'
|
5
|
-
require 'cany/recipes/rails'
|
6
|
-
require 'cany/recipes/web_server'
|
7
|
-
require 'cany/recipes/thin'
|
8
|
-
require 'cany/dpkg'
|
9
|
-
require 'cany/dpkg/creator'
|
10
|
-
require 'cany/dpkg/builder'
|
11
|
-
require 'cany/dpkg/deb_helper_recipe'
|
1
|
+
require 'logger'
|
12
2
|
|
13
3
|
module Cany
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
class MultipleSpecifications < Exception
|
18
|
-
end
|
19
|
-
|
4
|
+
# @raise [MissingSpecification] if no canspec is found in the directory
|
5
|
+
# @raise [MultipleSpecifications] if multiple canspec files are found inside
|
6
|
+
# the directory
|
20
7
|
def self.setup(directory='.')
|
21
8
|
specs = Dir[directory + '/*.' + Specification::EXT]
|
22
|
-
raise MissingSpecification
|
23
|
-
raise MultipleSpecifications
|
9
|
+
raise MissingSpecification.new(directory) if specs.size == 0
|
10
|
+
raise MultipleSpecifications.new(directory) if specs.size > 1
|
24
11
|
file = specs.first
|
25
12
|
spec = eval File::read(file), binding, file
|
26
13
|
spec.base_dir = directory
|
27
14
|
spec
|
28
15
|
end
|
16
|
+
|
17
|
+
# This methods creates a hash that returns an array as default value and also
|
18
|
+
# stores it directly inside the hash, so that the return value can be changed
|
19
|
+
# without additional actions.
|
20
|
+
# @example
|
21
|
+
# hash = hash_with_array_as_default
|
22
|
+
# hash[:hans] << 'otto'
|
23
|
+
# hash[:hash] == ['otto']
|
24
|
+
def self.hash_with_array_as_default
|
25
|
+
{}.tap do |hash|
|
26
|
+
hash.default_proc = Proc.new do |_, key|
|
27
|
+
hash[key] = []
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @api public
|
33
|
+
# @return [Logger]
|
34
|
+
def self.logger
|
35
|
+
@logger ||= create_logger
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.create_logger
|
39
|
+
logger = Logger.new(STDOUT)
|
40
|
+
logger.level = Logger::INFO
|
41
|
+
org_formatter = Logger::Formatter.new
|
42
|
+
logger.formatter = proc do |severity, datetime, progname, msg|
|
43
|
+
if severity == "INFO"
|
44
|
+
" #{msg}\n"
|
45
|
+
else
|
46
|
+
org_formatter.call severity, datetime, progname, msg
|
47
|
+
end
|
48
|
+
end
|
49
|
+
logger
|
50
|
+
end
|
51
|
+
|
52
|
+
require 'cany/version'
|
53
|
+
require 'cany/errors'
|
54
|
+
# This module contains ruby mixins that are used within multiple classes to share code.
|
55
|
+
module Mixins
|
56
|
+
require 'cany/mixins/depend_mixin'
|
57
|
+
end
|
58
|
+
require 'cany/dependency'
|
59
|
+
require 'cany/specification'
|
60
|
+
require 'cany/recipe'
|
61
|
+
|
62
|
+
|
63
|
+
# Applications using common libraries to concentrate on things that are new
|
64
|
+
# and no solved by existing software. Therefore there are similar deploy
|
65
|
+
# tasks that are needed for applications.
|
66
|
+
#
|
67
|
+
# Cany groups common deploy aspects in recipes. This recipes can be included
|
68
|
+
# and used by the application. Normally there exists one recipe for every
|
69
|
+
# important software that is used by the application and influences directly
|
70
|
+
# the way the applications needs to be installed.
|
71
|
+
#
|
72
|
+
# Central recipes are bundler as gem package manager and rails as popular
|
73
|
+
# web framework.
|
74
|
+
#
|
75
|
+
# To support starting the applications there is also a collection of recipes
|
76
|
+
# deploying ruby web server or background services.
|
77
|
+
module Recipes
|
78
|
+
require 'cany/recipes/bundler'
|
79
|
+
require 'cany/recipes/bundler/gem'
|
80
|
+
require 'cany/recipes/bundler/gem_db'
|
81
|
+
require 'cany/recipes/rails'
|
82
|
+
require 'cany/recipes/web_server'
|
83
|
+
require 'cany/recipes/thin'
|
84
|
+
require 'cany/recipes/unicorn'
|
85
|
+
require 'cany/recipes/sidekiq'
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
# Cany is designed to be able to pack applications for multiple package
|
90
|
+
# managers. Although there is currently only support for debian/ubuntu.
|
91
|
+
# All DPKG specific things are group into the Dpkg namespace.
|
92
|
+
module Dpkg
|
93
|
+
require 'cany/dpkg'
|
94
|
+
require 'cany/dpkg/creator'
|
95
|
+
require 'cany/dpkg/builder'
|
96
|
+
require 'cany/dpkg/deb_helper_recipe'
|
97
|
+
end
|
29
98
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Cany
|
2
|
+
# This class representing a dependency on an abstract object like a gem or a external software.
|
3
|
+
#
|
4
|
+
# Depending on the platform different packages are needed to satisfy the dependency. This class
|
5
|
+
# stores which packages (and optional a version constraint) is needed for every platform,
|
6
|
+
# distribution or distribution release.
|
7
|
+
#
|
8
|
+
# This class differs between two different situation where dependencies are needed: to build
|
9
|
+
# the package (:build) or to run/use the packages (:runtime).
|
10
|
+
#
|
11
|
+
# A dependency has also a priority:
|
12
|
+
# - :required: The dependency have to be fulfilled in every situation otherwise it is not
|
13
|
+
# possible to build or run the application.
|
14
|
+
# Other priorities are planed but currently not implemented.
|
15
|
+
class Dependency
|
16
|
+
def initialize(opts={})
|
17
|
+
opts = { situations: [:runtime] }.merge opts
|
18
|
+
@default = []
|
19
|
+
@distros = Cany.hash_with_array_as_default
|
20
|
+
@distro_releases ||= Cany.hash_with_array_as_default
|
21
|
+
self.situations = opts[:situations]
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_reader :situations
|
25
|
+
def situations=(value)
|
26
|
+
@situations = value.kind_of?(Array) ? value : [value]
|
27
|
+
end
|
28
|
+
def runtime?; @situations.include? :runtime; end
|
29
|
+
def build?; @situations.include? :build; end
|
30
|
+
|
31
|
+
# Define the default package name and an optional version constraint for all
|
32
|
+
# @param name[String] A package name
|
33
|
+
# @param version[String, nil] A version constraint
|
34
|
+
def define_default(name, version=nil)
|
35
|
+
default << [name, version]
|
36
|
+
end
|
37
|
+
|
38
|
+
# Define the default package name and an optional version constraint for a distribution
|
39
|
+
# @param distro[Symbol] The distribution name like :ubuntu, :debian ...
|
40
|
+
# @param name[String] A package name
|
41
|
+
# @param version[String, nil] A version constraint
|
42
|
+
def define_on_distro(distro, name, version=nil)
|
43
|
+
distros[distro] << [name, version]
|
44
|
+
end
|
45
|
+
|
46
|
+
# Define the package name and an optional version constraint for a distribution release
|
47
|
+
# @param distro[Symbol] The distribution name like :ubuntu, :debian ...
|
48
|
+
# @param release[Symbol] The distribution release like :precise for ubuntu 12.04
|
49
|
+
# @param name[String] A package name
|
50
|
+
# @param version[String, nil] A version constraint
|
51
|
+
def define_on_distro_release(distro, release, name, version=nil)
|
52
|
+
distro_releases[[distro, release]] << [name, version]
|
53
|
+
end
|
54
|
+
|
55
|
+
# Evaluation which packages (with version constraint) are needed for the given distrobution
|
56
|
+
# release.
|
57
|
+
# @param distro[Symbol] The distribution name like :ubuntu, :debian ...
|
58
|
+
# @param release[Symbol] The distribution release like :precise for ubuntu 12.04
|
59
|
+
# @return [Array<String, String>]
|
60
|
+
def determine(distro, release)
|
61
|
+
return distro_releases[[distro, release]] if distro_releases.has_key? [distro, release]
|
62
|
+
return distros[distro] if distros.has_key? distro
|
63
|
+
default
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
|
68
|
+
attr_reader :default, :distros, :distro_releases
|
69
|
+
end
|
70
|
+
end
|
data/lib/cany/dpkg/builder.rb
CHANGED
@@ -11,26 +11,14 @@ module Cany
|
|
11
11
|
@spec = spec
|
12
12
|
end
|
13
13
|
|
14
|
-
def debian(*args)
|
15
|
-
File.join spec.base_dir, 'debian', *args
|
16
|
-
end
|
17
|
-
|
18
14
|
# This method is called to do the actual work
|
19
15
|
# @api public
|
20
16
|
# @param [String] build_step_name The name of the dpkg build step (clean, build, binary)
|
21
17
|
def run(build_step_name)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
# @api private
|
27
|
-
# This method creates recipe instances for all required recipes from the given spec.
|
28
|
-
def setup_recipes
|
29
|
-
@recipes = []
|
30
|
-
@recipes << DebHelperRecipe.new(spec, nil)
|
31
|
-
spec.recipes.reverse.each do |name|
|
32
|
-
@recipes.unshift Recipe.from_name(name).new(spec, @recipes.first)
|
33
|
-
end
|
18
|
+
spec.system_recipe = DebHelperRecipe.new spec
|
19
|
+
spec.setup_recipes
|
20
|
+
spec.system_recipe.exec 'dh_prep' if build_step_name.to_s == 'binary'
|
21
|
+
spec.recipes.first.send build_step_name.to_s
|
34
22
|
end
|
35
23
|
end
|
36
24
|
end
|
data/lib/cany/dpkg/creator.rb
CHANGED
@@ -48,6 +48,12 @@ module Cany
|
|
48
48
|
def run(*args)
|
49
49
|
parse_opts *args
|
50
50
|
|
51
|
+
# let recipes influence package creating
|
52
|
+
@spec.system_recipe = DebHelperRecipe.new(spec)
|
53
|
+
@spec.recipes.each do |recipe|
|
54
|
+
recipe.create(self)
|
55
|
+
end
|
56
|
+
|
51
57
|
Dir.mkdir debian
|
52
58
|
create_compact
|
53
59
|
create_source_format
|
@@ -64,29 +70,11 @@ module Cany
|
|
64
70
|
|
65
71
|
def create_compact
|
66
72
|
File.open debian('compat'), 'w' do |f|
|
67
|
-
f.write '
|
73
|
+
f.write '9'
|
68
74
|
end
|
69
75
|
end
|
70
76
|
|
71
77
|
def create_source_control
|
72
|
-
require 'bundler'
|
73
|
-
lock_path = File.join(spec.base_dir, 'Gemfile.lock')
|
74
|
-
extra_libs = {
|
75
|
-
pg: ['libpq-dev', 'libpq5'],
|
76
|
-
ethon: ['libcurl3 | libcurl3-gnutls | libcurl3-nss', 'libcurl3 | libcurl3-gnutls | libcurl3-nss']
|
77
|
-
}
|
78
|
-
src_deps = ['debhelper (>= 7.0.50~)', ruby_deb, ruby_deb + '-dev']
|
79
|
-
bin_deps = ['${shlibs:Depends}', '${misc:Depends}', ruby_deb]
|
80
|
-
if File.exists? lock_path
|
81
|
-
lock = Bundler::LockfileParser.new File.read lock_path
|
82
|
-
lock.specs.each do |spec|
|
83
|
-
if extra_libs.has_key? spec.name.to_sym
|
84
|
-
src, bin = extra_libs[spec.name.to_sym]
|
85
|
-
src_deps << src
|
86
|
-
bin_deps << bin
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
78
|
File.open debian('control'), 'w' do |f|
|
91
79
|
# write source package fields:
|
92
80
|
f.write("Source: #{spec.name}\n")
|
@@ -95,13 +83,13 @@ module Cany
|
|
95
83
|
f.write("Maintainer: #{spec.maintainer_name} <#{spec.maintainer_email}>\n")
|
96
84
|
f.write("Standards-Version: 3.9.2\n")
|
97
85
|
f.write("Homepage: #{spec.website}\n")
|
98
|
-
f.write("Build-Depends: #{
|
86
|
+
f.write("Build-Depends: #{resolve_dependencies(@spec.build_dependencies)}\n")
|
99
87
|
|
100
88
|
# write binary package fields:
|
101
89
|
f.write("\n")
|
102
90
|
f.write("Package: #{spec.name}\n")
|
103
91
|
f.write("Architecture: any\n")
|
104
|
-
f.write("Depends: #{
|
92
|
+
f.write("Depends: #{resolve_dependencies(@spec.runtime_dependencies)}\n")
|
105
93
|
f.write("Description: #{spec.description}\n")
|
106
94
|
end
|
107
95
|
end
|
@@ -119,14 +107,22 @@ module Cany
|
|
119
107
|
|
120
108
|
def create_rules
|
121
109
|
File.open debian('rules'), 'w' do |f|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
f.write
|
110
|
+
unless @spec.cany_version_constraint
|
111
|
+
gem_version = ''
|
112
|
+
else
|
113
|
+
gem_version = " --version \"#{@spec.cany_version_constraint}\""
|
114
|
+
gem_version += ' --prerelease' if @spec.cany_version_constraint.match /[a-zA-Z]/
|
115
|
+
end
|
116
|
+
|
117
|
+
f.write <<EOM.gsub /^ /, ''
|
118
|
+
#!/usr/bin/make -f
|
119
|
+
export PATH := debian/bin:${PATH}
|
120
|
+
export GEM_PATH := debian/gems:${GEM_PATH}
|
121
|
+
%:
|
122
|
+
\t#{ruby_exe} -cS cany >/dev/null || #{ruby_exe} -S gem install --no-ri --no-rdoc --install-dir debian/gems --bindir debian/bin $${CANY_GEM:-cany}#{gem_version}
|
123
|
+
\t#{ruby_exe} -S cany dpkg-builder $@\n
|
124
|
+
override_dh_prep:
|
125
|
+
EOM
|
130
126
|
|
131
127
|
f.chmod(0755)
|
132
128
|
end
|
@@ -141,6 +137,20 @@ module Cany
|
|
141
137
|
f.write " -- #{spec.maintainer_name} <#{spec.maintainer_email}> #{Time.now.strftime "%a, %d %b %Y %H:%M:%S %z" }"
|
142
138
|
end
|
143
139
|
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
# Converts the given array of dependencies objects into a dependency string used inside
|
144
|
+
# debians source control files
|
145
|
+
# @param dependencies[Array<Dependency>]
|
146
|
+
# @return [String] A dependency string
|
147
|
+
def resolve_dependencies(dependencies)
|
148
|
+
dependencies.inject([]) do |deps, dep|
|
149
|
+
deps + dep.determine(:ubuntu, :precise).map do |pkg, version|
|
150
|
+
!version.nil? ? "#{pkg} (#{version})" : pkg
|
151
|
+
end
|
152
|
+
end.join(', ')
|
153
|
+
end
|
144
154
|
end
|
145
155
|
end
|
146
156
|
end
|
@@ -1,28 +1,113 @@
|
|
1
|
-
|
2
|
-
module Dpkg
|
3
|
-
class DebHelperRecipe < Cany::Recipe
|
4
|
-
register_as :deb_helper
|
5
|
-
|
6
|
-
def initialize(*args)
|
7
|
-
super *args
|
8
|
-
@log = File.read('debian/xikolo-account.debhelper.log') if File.exists? 'debian/xikolo-account.debhelper.log'
|
9
|
-
exec 'dh_prep'
|
10
|
-
end
|
1
|
+
require 'erb'
|
11
2
|
|
12
|
-
|
13
|
-
|
14
|
-
|
3
|
+
module Cany::Dpkg
|
4
|
+
class DebHelperRecipe < Cany::Recipe
|
5
|
+
register_as :deb_helper
|
6
|
+
|
7
|
+
option :service_pre_scripts
|
8
|
+
|
9
|
+
def initialize(*args)
|
10
|
+
super *args
|
11
|
+
@services = {}
|
12
|
+
@pre_scripts = []
|
13
|
+
@log = File.read debhelper_log if File.exists? debhelper_log
|
14
|
+
end
|
15
|
+
|
16
|
+
def create(creator)
|
17
|
+
depend 'debhelper', version: '>= 7.0.50~', situation: :build
|
18
|
+
depend '${shlibs:Depends}'
|
19
|
+
depend '${misc:Depends}'
|
20
|
+
depend creator.ruby_deb, situation: [:build, :runtime]
|
21
|
+
depend creator.ruby_deb + '-dev', situation: :build
|
22
|
+
end
|
23
|
+
|
24
|
+
def clean
|
25
|
+
exec %w(dh clean)
|
26
|
+
end
|
27
|
+
|
28
|
+
def build
|
29
|
+
instance_eval &spec.build if spec.build
|
30
|
+
exec %w(dh build)
|
31
|
+
end
|
32
|
+
|
33
|
+
def binary
|
34
|
+
instance_eval &spec.binary if spec.binary
|
35
|
+
install_base_service
|
36
|
+
install_services
|
37
|
+
File.write debhelper_log, @log if File.exists? debhelper_log
|
38
|
+
exec %w(dh binary)
|
39
|
+
end
|
40
|
+
|
41
|
+
def install_service(name, command, opts={})
|
42
|
+
opts = {user: 'root', group: 'root'}.merge opts
|
43
|
+
opts[:command] = command
|
44
|
+
@services[name] = opts
|
45
|
+
end
|
46
|
+
|
47
|
+
def install_services
|
48
|
+
@services.each do |name, opts|
|
49
|
+
File.write debian("#{spec.name}.#{spec.name}-#{name}.upstart"), render(<<-EOF.gsub(/^ {10}/, ''), opts.merge(name: name))
|
50
|
+
description "<%= spec.description %> - <%= name %>"
|
15
51
|
|
16
|
-
|
17
|
-
|
18
|
-
|
52
|
+
start on started <%= spec.name %>
|
53
|
+
stop on stopping <%= spec.name %>
|
54
|
+
|
55
|
+
respawn
|
56
|
+
respawn limit 10 5
|
57
|
+
umask 022
|
58
|
+
|
59
|
+
chdir /usr/share/<%= spec.name %>
|
60
|
+
|
61
|
+
<% if user %>
|
62
|
+
setuid <%= user %>
|
63
|
+
<% end %>
|
64
|
+
<% if group %>
|
65
|
+
setgid <%= group %>
|
66
|
+
<% end %>
|
67
|
+
|
68
|
+
exec <%= command.join(' ') %>
|
69
|
+
EOF
|
70
|
+
exec %w{dh_installinit --name}, "#{spec.name}-#{name}"
|
19
71
|
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def install_base_service
|
75
|
+
File.write debian("#{spec.name}.upstart"), render(<<-EOF.gsub(/^ {8}/, ''))
|
76
|
+
description "#{spec.description}"
|
77
|
+
|
78
|
+
start on filesystem or runlevel [2345]
|
79
|
+
stop on runlevel [!2345]
|
80
|
+
|
81
|
+
respawn
|
82
|
+
respawn limit 10 5
|
83
|
+
umask 022
|
20
84
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
85
|
+
pre-start script
|
86
|
+
<% pre_scripts.each do |k, command| %>
|
87
|
+
<%= command %>
|
88
|
+
<% end %>
|
89
|
+
end script
|
90
|
+
|
91
|
+
exec sleep 1d
|
92
|
+
EOF
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
def render(template, opts={})
|
97
|
+
def opts.method_missing(name)
|
98
|
+
self[name]
|
25
99
|
end
|
100
|
+
opts[:spec] = spec
|
101
|
+
opts[:pre_scripts] = option :service_pre_scripts
|
102
|
+
ERB.new(template, nil, '<>').result opts.instance_eval { binding }
|
103
|
+
end
|
104
|
+
|
105
|
+
def debian(*args)
|
106
|
+
File.join('debian', *args)
|
107
|
+
end
|
108
|
+
|
109
|
+
def debhelper_log
|
110
|
+
debian("#{spec.name}.debhelper.log")
|
26
111
|
end
|
27
112
|
end
|
28
113
|
end
|