cany 0.0.2 → 0.1.0
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.
- 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
|