pkgr 1.3.2 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -64,6 +64,10 @@ module Pkgr
64
64
  @table.delete(key)
65
65
  end
66
66
 
67
+ def safe_name
68
+ name.gsub("-", "_")
69
+ end
70
+
67
71
  def home
68
72
  "/opt/#{name}"
69
73
  end
@@ -93,7 +97,7 @@ module Pkgr
93
97
  end
94
98
 
95
99
  def env
96
- Pkgr::Env.new(@table[:env])
100
+ @table[:env].is_a?(Pkgr::Env) ? @table[:env] : Pkgr::Env.new(@table[:env])
97
101
  end
98
102
 
99
103
  def valid?
@@ -111,6 +115,30 @@ module Pkgr
111
115
  @errors ||= []
112
116
  end
113
117
 
118
+ def addons
119
+ # make proper Addon objects out of existing addon slugs
120
+ (@table[:addons] || []).map do |addon_slug|
121
+ Addon.new(addon_slug, addons_dir, self)
122
+ end
123
+ end
124
+
125
+ def installer
126
+ return nil if @table[:installer].nil? || @table[:installer] == false
127
+ @table[:installer]
128
+ end
129
+
130
+ def wizards
131
+ @wizards ||= (@table[:wizards] || []).map do |wizard_string|
132
+ wizard_string.split(/\s*\|\s*/).map do |wizard|
133
+ Addon.new(wizard, nil, nil)
134
+ end
135
+ end
136
+ end
137
+
138
+ def crons
139
+ @table[:crons] || []
140
+ end
141
+
114
142
  def before_hook
115
143
  if before_precompile.nil? || before_precompile.empty?
116
144
  before_steps = self.before || []
@@ -155,6 +183,16 @@ module Pkgr
155
183
  Pathname.new(source_dir).join(@table[:after_install]).realpath.to_s
156
184
  end
157
185
 
186
+ def before_remove
187
+ return nil if @table[:before_remove].nil?
188
+ Pathname.new(source_dir).join(@table[:before_remove]).realpath.to_s
189
+ end
190
+
191
+ def after_remove
192
+ return nil if @table[:after_remove].nil?
193
+ Pathname.new(source_dir).join(@table[:after_remove]).realpath.to_s
194
+ end
195
+
158
196
  # TODO: DRY this with cli.rb
159
197
  def to_args
160
198
  args = [
@@ -175,6 +213,9 @@ module Pkgr
175
213
  args.push "--after-precompile \"#{after_precompile}\"" unless after_precompile.nil? || after_precompile.empty?
176
214
  args.push "--before-install \"#{before_install}\"" unless before_install.nil? || before_install.empty?
177
215
  args.push "--after-install \"#{after_install}\"" unless after_install.nil? || after_install.empty?
216
+ args.push "--before-remove \"#{before_remove}\"" unless before_remove.nil? || before_remove.empty?
217
+ args.push "--after-remove \"#{after_remove}\"" unless after_remove.nil? || after_remove.empty?
218
+
178
219
  args.push "--license \"#{license}\"" unless license.nil? || license.empty?
179
220
  args.push "--buildpack \"#{buildpack}\"" unless buildpack.nil? || buildpack.empty?
180
221
  args.push "--buildpack_list \"#{buildpack_list}\"" unless buildpack_list.nil? || buildpack_list.empty?
@@ -183,6 +224,7 @@ module Pkgr
183
224
  args.push "--env #{env.variables.map{|v| "\"#{v}\""}.join(" ")}" if env.present?
184
225
  args.push "--auto" if auto
185
226
  args.push "--verbose" if verbose
227
+ args.push "--store-cache" if store_cache
186
228
  args.push "--debug" if debug
187
229
  args.push "--no-clean" if !clean
188
230
  args.push "--no-edge" if !edge
@@ -0,0 +1,12 @@
1
+ module Pkgr
2
+ class Cron
3
+ # the source, in /opt/app-name/...
4
+ attr_reader :source
5
+ # the destination, most likely in /etc/cron.d/...
6
+ attr_reader :destination
7
+
8
+ def initialize(source, destination)
9
+ @source, @destination = source, destination
10
+ end
11
+ end
12
+ end
@@ -36,14 +36,13 @@ module Pkgr
36
36
 
37
37
  def tarify
38
38
  tmpfile = Tempfile.new(["pkgr-tarball", ".tar.gz"])
39
- system("tar czf #{tmpfile.path} --exclude .git --exclude .svn -C \"#{path}\" .") || raise(Pkgr::Errors::Base, "Can't compress input directory")
39
+ system("tar czf #{tmpfile.path} --exclude .svn -C \"#{path}\" .") || raise(Pkgr::Errors::Base, "Can't compress input directory")
40
40
  # Remove any non-digit characters that may be before the version number
41
41
  config.version ||= begin
42
42
  v = (Git.new(path).latest_tag || "").gsub(/^[^\d]+(\d.*)/, '\1')
43
43
  v = "0.0.0" if v !~ /^\d/
44
44
  v
45
45
  end
46
- config.compile_cache_dir ||= File.join(path, ".git", "cache")
47
46
  config.name ||= File.basename(path)
48
47
  @path = tmpfile.path
49
48
  end
@@ -1,11 +1,13 @@
1
1
  require 'pkgr/templates/file_template'
2
2
  require 'pkgr/templates/dir_template'
3
3
  require 'pkgr/distributions/base'
4
+ require 'pkgr/config'
4
5
  require 'facter'
5
6
 
6
7
  module Pkgr
7
8
  module Distributions
8
- def current(force_os = nil)
9
+ def current(config = Config.new)
10
+ force_os = config.force_os
9
11
  os, release = if force_os.nil?
10
12
  [Facter.value('operatingsystem'), Facter.value('operatingsystemrelease')]
11
13
  else
@@ -15,7 +17,7 @@ module Pkgr
15
17
  os.downcase!
16
18
 
17
19
  klass = const_get(os.capitalize)
18
- klass.new(release)
20
+ klass.new(release, config)
19
21
  rescue NameError => e
20
22
  raise Errors::UnknownDistribution, "Don't know about the current distribution you're on: #{os}-#{release}"
21
23
  end
@@ -1,7 +1,9 @@
1
1
  require 'pkgr/buildpack'
2
2
  require 'pkgr/env'
3
3
  require 'pkgr/distributions/runner'
4
+ require 'pkgr/config'
4
5
  require 'yaml'
6
+ require 'open-uri'
5
7
 
6
8
  module Pkgr
7
9
  module Distributions
@@ -9,8 +11,10 @@ module Pkgr
9
11
  class Base
10
12
  attr_reader :release
11
13
  attr_writer :runner
14
+ attr_accessor :config
12
15
 
13
- def initialize(release)
16
+ def initialize(release, config = Config.new)
17
+ @config = config
14
18
  @release = release
15
19
  end
16
20
 
@@ -32,7 +36,7 @@ module Pkgr
32
36
  end
33
37
 
34
38
  # Check if all build dependencies are present.
35
- def check(config)
39
+ def check
36
40
  missing_packages = (build_dependencies(config.build_dependencies) || []).select do |package|
37
41
  test_command = package_test_command(package)
38
42
  Pkgr.debug "sh(#{test_command})"
@@ -42,6 +46,7 @@ module Pkgr
42
46
  unless missing_packages.empty?
43
47
  install_command = package_install_command(missing_packages)
44
48
  if config.auto
49
+ puts "-----> Installing missing build dependencies: #{missing_packages.join(", ")}"
45
50
  package_install = Mixlib::ShellOut.new(install_command)
46
51
  package_install.logger = Pkgr.logger
47
52
  package_install.run_command
@@ -58,13 +63,13 @@ module Pkgr
58
63
  end # def default_buildpack_list
59
64
 
60
65
  # Returns a list of Buildpack objects
61
- def buildpacks(config)
66
+ def buildpacks
62
67
  custom_buildpack_uri = config.buildpack
63
68
  if custom_buildpack_uri
64
69
  uuid = Digest::SHA1.hexdigest(custom_buildpack_uri)
65
70
  [Buildpack.new(custom_buildpack_uri, :custom, config.env)]
66
71
  else
67
- load_buildpack_list(config)
72
+ load_buildpack_list
68
73
  end
69
74
  end # def buildpacks
70
75
 
@@ -79,7 +84,7 @@ module Pkgr
79
84
  end # def build_dependencies
80
85
 
81
86
  # Returns a list of file and directory templates.
82
- def templates(config)
87
+ def templates
83
88
  app_name = config.name
84
89
  list = []
85
90
 
@@ -89,8 +94,9 @@ module Pkgr
89
94
  config.home.gsub(/^\//, ""),
90
95
  "etc/#{app_name}/conf.d",
91
96
  "etc/default",
92
- "etc/init",
93
- "var/log/#{app_name}"
97
+ "var/log/#{app_name}",
98
+ "var/db/#{app_name}",
99
+ "usr/share/#{app_name}"
94
100
  ].each{|dir| list.push Templates::DirTemplate.new(dir) }
95
101
 
96
102
  list.push Templates::FileTemplate.new("etc/default/#{app_name}", data_file("environment", "default.erb"))
@@ -116,23 +122,45 @@ module Pkgr
116
122
  list
117
123
  end
118
124
 
119
- def preinstall_file(config)
120
- @preinstall_file ||= generate_hook_file("preinstall.sh", config)
125
+ def crons_dir
126
+ "etc/cron.d"
127
+ end
128
+
129
+ def add_addon(addon)
130
+ nil
131
+ end
132
+
133
+ def preinstall_file
134
+ @preinstall_file ||= generate_hook_file("preinstall.sh")
121
135
  @preinstall_file.path
122
136
  end
123
137
 
124
- def postinstall_file(config)
125
- @postinstall_file ||= generate_hook_file("postinstall.sh", config)
138
+ def postinstall_file
139
+ @postinstall_file ||= generate_hook_file("postinstall.sh")
126
140
  @postinstall_file.path
127
141
  end
128
142
 
143
+ def preuninstall_file
144
+ @preuninstall_file ||= generate_hook_file("preuninstall.sh")
145
+ @preuninstall_file.path
146
+ end
147
+
148
+ def postuninstall_file
149
+ @postuninstall_file ||= generate_hook_file("postuninstall.sh")
150
+ @postuninstall_file.path
151
+ end
152
+
153
+ def installer_dependencies
154
+ ["dialog", "bash"]
155
+ end
156
+
129
157
  protected
130
158
 
131
- def load_buildpack_list(config)
159
+ def load_buildpack_list
132
160
  file = config.buildpack_list || default_buildpack_list
133
161
  return [] if file.nil?
134
162
 
135
- File.read(file).split("\n").map do |line|
163
+ open(file).read.split("\n").map do |line|
136
164
  url, *raw_env = line.split(",")
137
165
  buildpack_env = (config.env || Env.new).merge(Env.new(raw_env))
138
166
  Buildpack.new(url, :builtin, buildpack_env)
@@ -143,7 +171,7 @@ module Pkgr
143
171
  File.new(File.join(Pkgr.data_dir, *names))
144
172
  end
145
173
 
146
- def generate_hook_file(hook_name, config)
174
+ def generate_hook_file(hook_name)
147
175
  source = data_file("hooks", hook_name)
148
176
  file = Tempfile.new("postinstall")
149
177
  file.write ERB.new(File.read(source)).result(config.sesame)
@@ -156,4 +184,4 @@ module Pkgr
156
184
  end # module Pkgr
157
185
 
158
186
  require 'pkgr/distributions/debian'
159
- require 'pkgr/distributions/redhat'
187
+ require 'pkgr/distributions/fedora'
@@ -1,12 +1,20 @@
1
- require "pkgr/distributions/redhat"
1
+ require "pkgr/distributions/fedora"
2
2
 
3
3
  module Pkgr
4
4
  module Distributions
5
5
  # Contains the various components required to make a packaged app integrate well with a CentOS system.
6
- class Centos < Redhat
6
+ class Centos < Fedora
7
7
  def runner
8
+ # in truth it is 0.6.5, but it also works with 1.5 templates.
9
+ # maybe adopt the same structure as pleaserun, with defaults, etc.
8
10
  @runner ||= Runner.new("upstart", "1.5")
9
11
  end
12
+
13
+ def templates
14
+ list = super
15
+ list.push Templates::DirTemplate.new("etc/init")
16
+ list
17
+ end
10
18
  end
11
19
  end
12
20
  end
@@ -23,33 +23,83 @@ module Pkgr
23
23
  "sudo apt-get update && sudo apt-get install --force-yes -y #{packages.map{|package| "\"#{package}\""}.join(" ")}"
24
24
  end
25
25
 
26
- def fpm_command(build_dir, config)
27
- %{fpm #{fpm_args(build_dir, config).join(" ")} .}
28
- end
29
-
30
- def fpm_args(build_dir, config)
31
- args = []
32
- args << "-t deb"
33
- args << "-s dir"
34
- args << "--verbose"
35
- args << "--force"
36
- args << %{-C "#{build_dir}"}
37
- args << %{-n "#{config.name}"}
38
- args << %{--version "#{config.version}"}
39
- args << %{--iteration "#{config.iteration}"}
40
- args << %{--url "#{config.homepage}"}
41
- args << %{--provides "#{config.name}"}
42
- args << %{--deb-user "root"}
43
- args << %{--deb-group "root"}
44
- args << %{--license "#{config.license}"} unless config.license.nil?
45
- args << %{-a "#{config.architecture}"}
46
- args << %{--description "#{config.description}"}
47
- args << %{--maintainer "#{config.maintainer}"}
48
- args << %{--template-scripts}
49
- args << %{--before-install #{preinstall_file(config)}}
50
- args << %{--after-install #{postinstall_file(config)}}
51
- dependencies(config.dependencies).each{|d| args << "-d '#{d}'"}
52
- args
26
+ def installer_dependencies
27
+ super.push("debianutils").uniq
28
+ end
29
+
30
+ def fpm_command(build_dir)
31
+ DebianFpm.new(self, build_dir).command
32
+ end
33
+
34
+ def debconfig
35
+ @debconfig ||= begin
36
+ tmpfile = Tempfile.new("debconfig")
37
+ tmpfile.puts "#!/bin/bash"
38
+ tmpfile.rewind
39
+ tmpfile
40
+ end
41
+ @debconfig
42
+ end
43
+
44
+ def debtemplates
45
+ @debtemplates ||= Tempfile.new("debtemplates")
46
+ end
47
+
48
+ def add_addon(addon)
49
+ # make a debian package out of the addon
50
+ Dir.chdir(addon.dir) do
51
+ make_package = Mixlib::ShellOut.new %{dpkg-buildpackage -b -d}
52
+ make_package.logger = Pkgr.logger
53
+ make_package.run_command
54
+ make_package.error!
55
+ end
56
+ FileUtils.mv(Dir.glob(File.join(File.dirname(addon.dir), "*.deb")), Dir.pwd)
57
+ # return name of the dependency
58
+ addon.debian_dependency_name
59
+ end
60
+
61
+ class DebianFpm
62
+ attr_reader :distribution, :build_dir, :config
63
+
64
+ def initialize(distribution, build_dir)
65
+ @distribution = distribution
66
+ @build_dir = build_dir
67
+ @config = distribution.config
68
+ end
69
+
70
+ def command
71
+ %{fpm #{args.join(" ")} .}
72
+ end
73
+
74
+ def args
75
+ list = []
76
+ list << "-t deb"
77
+ list << "-s dir"
78
+ list << "--verbose"
79
+ list << "--force"
80
+ list << "--exclude '**/.git**'"
81
+ list << %{-C "#{build_dir}"}
82
+ list << %{-n "#{config.name}"}
83
+ list << %{--version "#{config.version}"}
84
+ list << %{--iteration "#{config.iteration}"}
85
+ list << %{--url "#{config.homepage}"}
86
+ list << %{--provides "#{config.name}"}
87
+ list << %{--deb-user "root"}
88
+ list << %{--deb-group "root"}
89
+ list << %{--license "#{config.license}"} unless config.license.nil?
90
+ list << %{-a "#{config.architecture}"}
91
+ list << %{--description "#{config.description}"}
92
+ list << %{--maintainer "#{config.maintainer}"}
93
+ list << %{--template-scripts}
94
+ list << %{--deb-config #{distribution.debconfig.path}}
95
+ list << %{--deb-templates #{distribution.debtemplates.path}}
96
+ list << %{--before-install #{distribution.preinstall_file}}
97
+ list << %{--after-install #{distribution.postinstall_file}}
98
+ list << %{--before-remove #{distribution.preuninstall_file}}
99
+ list << %{--after-remove #{distribution.postuninstall_file}}
100
+ distribution.dependencies(config.dependencies).each{|d| list << "-d '#{d}'"}
101
+ list.compact
102
+ end
53
103
  end
54
104
  end
55
105
  end
@@ -0,0 +1,58 @@
1
+ require 'pkgr/buildpack'
2
+ require 'pkgr/process'
3
+ require 'pkgr/distributions/base'
4
+
5
+ module Pkgr
6
+ module Distributions
7
+ # Contains the various components required to make a packaged app integrate well with a Debian system.
8
+ class Fedora < Base
9
+ # Only keep major digits
10
+ def release
11
+ @release[/^[0-9]+/]
12
+ end
13
+
14
+ def runner
15
+ @runner ||= Runner.new("sysv", "lsb-3.1")
16
+ end
17
+
18
+ def package_test_command(package)
19
+ "rpm -qa '#{package}' | grep '#{package}' > /dev/null 2>&1"
20
+ end
21
+
22
+ def package_install_command(packages)
23
+ "sudo yum -q check-update ; sudo yum install -y #{packages.map{|package| "\"#{package}\""}.join(" ")}"
24
+ end
25
+
26
+ def installer_dependencies
27
+ super.push("which").uniq
28
+ end
29
+
30
+ def fpm_command(build_dir)
31
+ %{
32
+ fpm -t rpm -s dir --verbose --force \
33
+ -C "#{build_dir}" \
34
+ -n "#{config.name}" \
35
+ --version "#{config.version}" \
36
+ --iteration "#{config.iteration}" \
37
+ --url "#{config.homepage}" \
38
+ --provides "#{config.name}" \
39
+ --deb-user "root" \
40
+ --deb-group "root" \
41
+ -a "#{config.architecture}" \
42
+ --description "#{config.description}" \
43
+ --maintainer "#{config.maintainer}" \
44
+ --template-scripts \
45
+ --before-install #{preinstall_file} \
46
+ --after-install #{postinstall_file} \
47
+ --before-remove #{preuninstall_file} \
48
+ --after-remove #{postuninstall_file} \
49
+ #{dependencies(config.dependencies).map{|d| "-d '#{d}'"}.join(" ")} \
50
+ .
51
+ }
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ require 'pkgr/distributions/redhat'
58
+ require 'pkgr/distributions/centos'