fpm 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELIST +31 -0
- data/lib/fpm/command.rb +11 -2
- data/lib/fpm/package/cpan.rb +21 -2
- data/lib/fpm/package/deb.rb +31 -21
- data/lib/fpm/package/gem.rb +14 -0
- data/lib/fpm/package/pyfpm/__init__.pyc +0 -0
- data/lib/fpm/package/pyfpm/get_metadata.pyc +0 -0
- data/lib/fpm/package/python.rb +32 -2
- data/lib/fpm/package/rpm.rb +26 -20
- data/lib/fpm/package/sh.rb +75 -0
- data/lib/fpm/package/zip.rb +63 -0
- data/lib/fpm/util.rb +41 -8
- data/lib/fpm/version.rb +1 -1
- data/templates/rpm.erb +1 -2
- data/templates/sh.erb +297 -0
- metadata +53 -92
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d61a0cdec8509988ddad4461c5d8e97ec8e13e7d
|
4
|
+
data.tar.gz: 1450b23e93208cf29b03ee1e65fc2b3e4c21502f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2f93f3d2dad2f43aa06db81125b39962855519e7e6c854636b95a378336ca8be63888b65a53c7400528c6b43278d711eaf3d2803df4f980231b7891495c78813
|
7
|
+
data.tar.gz: 5533a18ec9ef6c1a8b43a8a9e7c26bef3bd878eb79b3e7cfd086080ce2f0d17cbc5d606ec6808b5c20b0469ca0c0d7ce325750dc6f80ab549a0cd44ce66bc964
|
data/CHANGELIST
CHANGED
@@ -1,3 +1,34 @@
|
|
1
|
+
1.1.0 (???)
|
2
|
+
- New package type: zip, for converting to and from zip files (Jordan Sissel)
|
3
|
+
- New package type: sh, a self-extracting package installation shell archive. (#651, Chris Gerber)
|
4
|
+
- 'fpm --version' will now emit the version of fpm.
|
5
|
+
- rpm: supports packaging fifo files (Adam Stephens)
|
6
|
+
- deb: Add --deb-use-file-permissions (Adam Stephens)
|
7
|
+
- cpan: Improve how fpm tries to find cpan artifacts for download (#614, Tim Nicholas)
|
8
|
+
- gem: Add --gem-disable-dependency for removing one or more specific rubygem
|
9
|
+
dependencies from the automatically-generated list (#598, Derek Olsen)
|
10
|
+
- python: Add --python-scripts-executable for setting a custom interpreter to
|
11
|
+
use for the hashbang line at the top of may python package scripts.
|
12
|
+
(#628, Vladimir Rutsky)
|
13
|
+
- Allow absolute paths with --directories even when --prefix is used (Vladimir Rutsky)
|
14
|
+
- dir: Now correctly identifies hardlinked files and creates a package correctly
|
15
|
+
with that knowledge (#365, #623, #659; Vladimir Rutsky)
|
16
|
+
- rpm: Add --rpm-auto-add-exclude-directories for excluding directories
|
17
|
+
from the --rpm-auto-add-directories behavior (#640, Vladimir Rutsky)
|
18
|
+
- general: --config-files now accepts directories and will recursively mark any
|
19
|
+
files within as config files inside the package (#642, Vladimir Rutsky)
|
20
|
+
- general: If you specify a --config-files path that doesn't exist, you will
|
21
|
+
now get an error. (#654, Alan Franzoni)
|
22
|
+
- python: Support --python-pypi when using --python-pip (#652, David Lindquist)
|
23
|
+
- deb: Tests now try to make packages ensure we don't upset lintian (#648, Sam Crang)
|
24
|
+
- rpm: Fix architecture targeting (#676, Rob Kinyon)
|
25
|
+
- rpm: Allow --rpm-user and --rpm-group to override the user/group even if
|
26
|
+
--rpm-use-file-permissions is enabled. (#679, Jordan Sissel)
|
27
|
+
- gem: Add --gem-version-bins for appending the gem version to the file name
|
28
|
+
of executable scripts a rubygem may install. (Jan Vansteenkiste)
|
29
|
+
- python: Attempt to provide better error messages for known issues in python
|
30
|
+
environments (#664, Jordan Sissel)
|
31
|
+
|
1
32
|
1.0.2 (January 10, 2013)
|
2
33
|
- rpm: No longer converts - to _ in dependency strings (#603, Bulat
|
3
34
|
Shakirzyanov)
|
data/lib/fpm/command.rb
CHANGED
@@ -101,7 +101,8 @@ class FPM::Command < Clamp::Command
|
|
101
101
|
option "--config-files", "CONFIG_FILES",
|
102
102
|
"Mark a file in the package as being a config file. This uses 'conffiles'" \
|
103
103
|
" in debs and %config in rpm. If you have multiple files to mark as " \
|
104
|
-
"configuration files, specify this flag multiple times."
|
104
|
+
"configuration files, specify this flag multiple times. If argument is " \
|
105
|
+
"directory all files inside it will be recursively marked as config files.",
|
105
106
|
:multivalued => true, :attribute_name => :config_files
|
106
107
|
option "--directories", "DIRECTORIES", "Recursively mark a directory as being owned " \
|
107
108
|
"by the package", :multivalued => true, :attribute_name => :directories
|
@@ -217,6 +218,12 @@ class FPM::Command < Clamp::Command
|
|
217
218
|
|
218
219
|
# Execute this command. See Clamp::Command#execute and Clamp's documentation
|
219
220
|
def execute
|
221
|
+
# Short-circuit if someone simply runs `fpm --version`
|
222
|
+
if ARGV == [ "--version" ]
|
223
|
+
puts FPM::VERSION
|
224
|
+
return 0
|
225
|
+
end
|
226
|
+
|
220
227
|
@logger.level = :warn
|
221
228
|
|
222
229
|
if (stray_flags = args.grep(/^-/); stray_flags.any?)
|
@@ -385,8 +392,9 @@ class FPM::Command < Clamp::Command
|
|
385
392
|
|
386
393
|
# Write the output somewhere, package can be nil if no --package is specified,
|
387
394
|
# and that's OK.
|
395
|
+
package_file = output.to_s(package)
|
388
396
|
begin
|
389
|
-
output.output(
|
397
|
+
output.output(package_file)
|
390
398
|
rescue FPM::Package::FileAlreadyExists => e
|
391
399
|
@logger.fatal(e.message)
|
392
400
|
return 1
|
@@ -395,6 +403,7 @@ class FPM::Command < Clamp::Command
|
|
395
403
|
return 1
|
396
404
|
end
|
397
405
|
|
406
|
+
@logger.log("Created package", :path => package_file)
|
398
407
|
return 0
|
399
408
|
rescue FPM::Util::ExecutableNotFound => e
|
400
409
|
@logger.error("Need executable '#{e}' to convert #{input_type} to #{output_type}")
|
data/lib/fpm/package/cpan.rb
CHANGED
@@ -242,6 +242,7 @@ class FPM::Package::CPAN < FPM::Package
|
|
242
242
|
def download(metadata, cpan_version=nil)
|
243
243
|
distribution = metadata["distribution"]
|
244
244
|
author = metadata["author"]
|
245
|
+
|
245
246
|
@logger.info("Downloading perl module",
|
246
247
|
:distribution => distribution,
|
247
248
|
:version => cpan_version)
|
@@ -257,9 +258,27 @@ class FPM::Package::CPAN < FPM::Package
|
|
257
258
|
end
|
258
259
|
end
|
259
260
|
|
260
|
-
|
261
|
+
metacpan_release_url = "http://api.metacpan.org/v0/release/#{author}/#{distribution}-#{self.version}"
|
262
|
+
begin
|
263
|
+
release_response = httpfetch(metacpan_release_url)
|
264
|
+
rescue Net::HTTPServerException => e
|
265
|
+
@logger.error("metacpan release query failed.", :error => e.message,
|
266
|
+
:module => package, :url => metacpan_release_url)
|
267
|
+
raise FPM::InvalidPackageConfiguration, "metacpan release query failed"
|
268
|
+
end
|
269
|
+
|
270
|
+
data = release_response.body
|
271
|
+
release_metadata = JSON.parse(data)
|
272
|
+
archive = release_metadata["archive"]
|
273
|
+
|
274
|
+
# should probably be basepathed from the url
|
275
|
+
tarball = File.basename(archive)
|
276
|
+
|
277
|
+
url_base = "http://www.cpan.org/"
|
278
|
+
url_base = "#{attributes[:cpan_mirror]}" if !attributes[:cpan_mirror].nil?
|
279
|
+
|
261
280
|
#url = "http://www.cpan.org/CPAN/authors/id/#{author[0,1]}/#{author[0,2]}/#{author}/#{tarball}"
|
262
|
-
url = "
|
281
|
+
url = "#{url_base}/authors/id/#{author[0,1]}/#{author[0,2]}/#{author}/#{archive}"
|
263
282
|
@logger.debug("Fetching perl module", :url => url)
|
264
283
|
|
265
284
|
begin
|
data/lib/fpm/package/deb.rb
CHANGED
@@ -76,6 +76,9 @@ class FPM::Package::Deb < FPM::Package
|
|
76
76
|
option "--priority", "PRIORITY",
|
77
77
|
"The debian package 'priority' value.", :default => "extra"
|
78
78
|
|
79
|
+
option "--use-file-permissions", :flag,
|
80
|
+
"Use existing file permissions when defining ownership and modes"
|
81
|
+
|
79
82
|
option "--user", "USER", "The owner of files in this package", :default => 'root'
|
80
83
|
|
81
84
|
option "--group", "GROUP", "The group owner of files in this package", :default => 'root'
|
@@ -342,23 +345,6 @@ class FPM::Package::Deb < FPM::Package
|
|
342
345
|
"Unknown compression type '#{self.attributes[:deb_compression]}'"
|
343
346
|
end
|
344
347
|
|
345
|
-
tar_flags = []
|
346
|
-
if !attributes[:deb_user].nil?
|
347
|
-
if attributes[:deb_user] == 'root'
|
348
|
-
tar_flags += [ "--numeric-owner", "--owner", "0" ]
|
349
|
-
else
|
350
|
-
tar_flags += [ "--owner", attributes[:deb_user] ]
|
351
|
-
end
|
352
|
-
end
|
353
|
-
|
354
|
-
if !attributes[:deb_group].nil?
|
355
|
-
if attributes[:deb_group] == 'root'
|
356
|
-
tar_flags += [ "--numeric-owner", "--group", "0" ]
|
357
|
-
else
|
358
|
-
tar_flags += [ "--group", attributes[:deb_group] ]
|
359
|
-
end
|
360
|
-
end
|
361
|
-
|
362
348
|
if attributes[:deb_changelog]
|
363
349
|
dest_changelog = File.join(staging_path, "usr/share/doc/#{name}/changelog.Debian")
|
364
350
|
FileUtils.mkdir_p(File.dirname(dest_changelog))
|
@@ -396,7 +382,7 @@ class FPM::Package::Deb < FPM::Package
|
|
396
382
|
FileUtils.ln_s("/lib/init/upstart-job", dest_init)
|
397
383
|
end
|
398
384
|
|
399
|
-
args = [ tar_cmd, "-C", staging_path, compression ] +
|
385
|
+
args = [ tar_cmd, "-C", staging_path, compression ] + data_tar_flags + [ "-cf", datatar, "." ]
|
400
386
|
safesystem(*args)
|
401
387
|
|
402
388
|
# pack up the .deb, which is just an 'ar' archive with 3 files
|
@@ -406,7 +392,6 @@ class FPM::Package::Deb < FPM::Package
|
|
406
392
|
safesystem("ar", "-qc", output_path, "debian-binary", "control.tar.gz", datatar)
|
407
393
|
end
|
408
394
|
end
|
409
|
-
@logger.log("Created deb package", :path => output_path)
|
410
395
|
end # def output
|
411
396
|
|
412
397
|
def converted_from(origin)
|
@@ -612,7 +597,10 @@ class FPM::Package::Deb < FPM::Package
|
|
612
597
|
File.open(control_path("conffiles"), "w") do |out|
|
613
598
|
# 'config_files' comes from FPM::Package and is usually set with
|
614
599
|
# FPM::Command's --config-files flag
|
615
|
-
allconfigs.each
|
600
|
+
allconfigs.each do |cf|
|
601
|
+
# We need to put the leading / back. Stops lintian relative-conffile error.
|
602
|
+
out.puts("/" + cf)
|
603
|
+
end
|
616
604
|
end
|
617
605
|
end # def write_conffiles
|
618
606
|
|
@@ -664,5 +652,27 @@ class FPM::Package::Deb < FPM::Package
|
|
664
652
|
return super(format)
|
665
653
|
end # def to_s
|
666
654
|
|
667
|
-
|
655
|
+
def data_tar_flags
|
656
|
+
data_tar_flags = []
|
657
|
+
if attributes[:deb_use_file_permissions?].nil?
|
658
|
+
if !attributes[:deb_user].nil?
|
659
|
+
if attributes[:deb_user] == 'root'
|
660
|
+
data_tar_flags += [ "--numeric-owner", "--owner", "0" ]
|
661
|
+
else
|
662
|
+
data_tar_flags += [ "--owner", attributes[:deb_user] ]
|
663
|
+
end
|
664
|
+
end
|
665
|
+
|
666
|
+
if !attributes[:deb_group].nil?
|
667
|
+
if attributes[:deb_group] == 'root'
|
668
|
+
data_tar_flags += [ "--numeric-owner", "--group", "0" ]
|
669
|
+
else
|
670
|
+
data_tar_flags += [ "--group", attributes[:deb_group] ]
|
671
|
+
end
|
672
|
+
end
|
673
|
+
end
|
674
|
+
return data_tar_flags
|
675
|
+
end # def data_tar_flags
|
676
|
+
|
677
|
+
public(:input, :output, :architecture, :name, :prefix, :converted_from, :to_s, :data_tar_flags)
|
668
678
|
end # class FPM::Target::Deb
|
data/lib/fpm/package/gem.rb
CHANGED
@@ -38,6 +38,11 @@ class FPM::Package::Gem < FPM::Package
|
|
38
38
|
"shebang rewritten to use env?", :default => true
|
39
39
|
|
40
40
|
option "--prerelease", :flag, "Allow prerelease versions of a gem", :default => false
|
41
|
+
option "--disable-dependency", "gem_name",
|
42
|
+
"The gem name to remove from dependency list",
|
43
|
+
:multivalued => true, :attribute_name => :gem_disable_dependencies
|
44
|
+
|
45
|
+
option "--version-bins", :flag, "Append the version to the bins", :default => false
|
41
46
|
|
42
47
|
def input(gem)
|
43
48
|
# 'arg' is the name of the rubygem we should unpack.
|
@@ -147,6 +152,10 @@ class FPM::Package::Gem < FPM::Package
|
|
147
152
|
|
148
153
|
# Some reqs can be ">= a, < b" versions, let's handle that.
|
149
154
|
reqs.to_s.split(/, */).each do |req|
|
155
|
+
if attributes[:gem_disable_dependencies]
|
156
|
+
next if attributes[:gem_disable_dependencies].include?(dep.name)
|
157
|
+
end
|
158
|
+
|
150
159
|
if attributes[:gem_fix_dependencies?]
|
151
160
|
name = fix_name(dep.name)
|
152
161
|
else
|
@@ -198,6 +207,11 @@ class FPM::Package::Gem < FPM::Package
|
|
198
207
|
::Dir.rmdir(tmp)
|
199
208
|
tmp = File.dirname(tmp)
|
200
209
|
end
|
210
|
+
if attributes[:gem_version_bins?]
|
211
|
+
(::Dir.entries(bin_path) - ['.','..']).each do |bin|
|
212
|
+
FileUtils.mv("#{bin_path}/#{bin}", "#{bin_path}/#{bin}-#{self.version}")
|
213
|
+
end
|
214
|
+
end
|
201
215
|
end # def install_to_staging
|
202
216
|
|
203
217
|
# Sanitize package name.
|
Binary file
|
Binary file
|
data/lib/fpm/package/python.rb
CHANGED
@@ -63,6 +63,12 @@ class FPM::Package::Python < FPM::Package
|
|
63
63
|
option "--obey-requirements-txt", :flag, "Use a requirements.txt file " \
|
64
64
|
"in the top-level directory of the python package for dependency " \
|
65
65
|
"detection.", :default => false
|
66
|
+
option "--scripts-executable", "PYTHON_EXECUTABLE", "Set custom python " \
|
67
|
+
"interpreter in installing scripts. By default distutils will replace " \
|
68
|
+
"python interpreter in installing scripts (specified by shebang) with " \
|
69
|
+
"current python interpreter (sys.executable). This option is equivalent " \
|
70
|
+
"to appending 'build_scripts --executable PYTHON_EXECUTABLE' arguments " \
|
71
|
+
"to 'setup.py install' command."
|
66
72
|
|
67
73
|
private
|
68
74
|
|
@@ -121,8 +127,7 @@ class FPM::Package::Python < FPM::Package
|
|
121
127
|
"--build-directory", target, want_pkg)
|
122
128
|
else
|
123
129
|
@logger.debug("using pip", :pip => attributes[:python_pip])
|
124
|
-
safesystem(attributes[:python_pip], "install", "--no-install",
|
125
|
-
"-U", "--build", target, want_pkg)
|
130
|
+
safesystem(attributes[:python_pip], "install", "--no-install", "-i", attributes[:python_pypi], "-U", "--build", target, want_pkg)
|
126
131
|
end
|
127
132
|
|
128
133
|
# easy_install will put stuff in @tmpdir/packagename/, so find that:
|
@@ -140,6 +145,26 @@ class FPM::Package::Python < FPM::Package
|
|
140
145
|
attributes[:python_package_name_prefix] = attributes[:python_package_prefix]
|
141
146
|
end
|
142
147
|
|
148
|
+
begin
|
149
|
+
json_test_code = [
|
150
|
+
"try:",
|
151
|
+
" import json",
|
152
|
+
"except ImportError:",
|
153
|
+
" import simplejson as json"
|
154
|
+
].join("\n")
|
155
|
+
safesystem("#{attributes[:python_bin]} -c '#{json_test_code}'")
|
156
|
+
rescue FPM::Util::ProcessFailed => e
|
157
|
+
@logger.error("Your python environment is missing json support (either json or simplejson python module). I cannot continue without this.", :python => attributes[:python_bin], :error => e)
|
158
|
+
raise FPM::Util::ProcessFailed, "Python (#{attributes[:python_bin]}) is missing simplejson or json modules."
|
159
|
+
end
|
160
|
+
|
161
|
+
begin
|
162
|
+
safesystem("#{attributes[:python_bin]} -c 'import pkg_resources'")
|
163
|
+
rescue FPM::Util::ProcessFailed => e
|
164
|
+
@logger.error("Your python environment is missing a working setuptools module. I tried to find the 'pkg_resources' module but failed.", :python => attributes[:python_bin], :error => e)
|
165
|
+
raise FPM::Util::ProcessFailed, "Python (#{attributes[:python_bin]}) is missing pkg_resources module."
|
166
|
+
end
|
167
|
+
|
143
168
|
# Add ./pyfpm/ to the python library path
|
144
169
|
pylib = File.expand_path(File.dirname(__FILE__))
|
145
170
|
|
@@ -272,6 +297,11 @@ class FPM::Package::Python < FPM::Package
|
|
272
297
|
flags += [ "--install-scripts", File.join(prefix, "bin") ]
|
273
298
|
end
|
274
299
|
|
300
|
+
if !attributes[:python_scripts_executable].nil?
|
301
|
+
# Overwrite installed python scripts shebang binary with provided executable
|
302
|
+
flags += [ "build_scripts", "--executable", attributes[:python_scripts_executable] ]
|
303
|
+
end
|
304
|
+
|
275
305
|
safesystem(attributes[:python_bin], "setup.py", "install", *flags)
|
276
306
|
end
|
277
307
|
end # def install_to_staging
|
data/lib/fpm/package/rpm.rb
CHANGED
@@ -30,19 +30,11 @@ class FPM::Package::RPM < FPM::Package
|
|
30
30
|
} unless defined?(COMPRESSION_MAP)
|
31
31
|
|
32
32
|
option "--use-file-permissions", :flag,
|
33
|
-
"Use existing file permissions when defining ownership and modes"
|
33
|
+
"Use existing file permissions when defining ownership and modes."
|
34
34
|
|
35
|
-
option "--user", "USER",
|
36
|
-
"Set the user to USER in the %files section.",
|
37
|
-
:default => 'root' do |value|
|
38
|
-
value
|
39
|
-
end
|
35
|
+
option "--user", "USER", "Set the user to USER in the %files section. Overrides the user when used with use-file-permissions setting."
|
40
36
|
|
41
|
-
option "--group", "GROUP",
|
42
|
-
"Set the group to GROUP in the %files section.",
|
43
|
-
:default => 'root' do |value|
|
44
|
-
value
|
45
|
-
end
|
37
|
+
option "--group", "GROUP", "Set the group to GROUP in the %files section. Overrides the group when used with use-file-permissions setting."
|
46
38
|
|
47
39
|
option "--defattrfile", "ATTR",
|
48
40
|
"Set the default file mode (%defattr).",
|
@@ -95,6 +87,9 @@ class FPM::Package::RPM < FPM::Package
|
|
95
87
|
option "--sign", :flag, "Pass --sign to rpmbuild"
|
96
88
|
|
97
89
|
option "--auto-add-directories", :flag, "Auto add directories not part of filesystem"
|
90
|
+
option "--auto-add-exclude-directories", "DIRECTORIES",
|
91
|
+
"Additional directories ignored by '--rpm-auto-add-directories' flag",
|
92
|
+
:multivalued => true, :attribute_name => :auto_add_exclude_directories
|
98
93
|
|
99
94
|
option "--autoreqprov", :flag, "Enable RPM's AutoReqProv option"
|
100
95
|
option "--autoreq", :flag, "Enable RPM's AutoReq option"
|
@@ -141,8 +136,11 @@ class FPM::Package::RPM < FPM::Package
|
|
141
136
|
# Stat the original filename in the relative staging path
|
142
137
|
::Dir.chdir(staging_path) do
|
143
138
|
stat = File.stat(original_file.gsub(/\"/, '').sub(/^\//,''))
|
144
|
-
|
145
|
-
|
139
|
+
|
140
|
+
# rpm_user and rpm_group attribute should override file ownership
|
141
|
+
# otherwise use the current file user/group by name.
|
142
|
+
user = attributes[:rpm_user] || Etc.getpwuid(stat.uid).name
|
143
|
+
group = attributes[:rpm_group] || Etc.getgrgid(stat.gid).name
|
146
144
|
mode = stat.mode
|
147
145
|
return sprintf("%%attr(%o, %s, %s) %s\n", mode & 4095 , user, group, file)
|
148
146
|
end
|
@@ -301,11 +299,19 @@ class FPM::Package::RPM < FPM::Package
|
|
301
299
|
rpm.extract(staging_path)
|
302
300
|
end # def input
|
303
301
|
|
302
|
+
def prefixed_path(path)
|
303
|
+
Pathname.new(path).absolute?() ? path : File.join(self.prefix, path)
|
304
|
+
end # def prefixed_path
|
305
|
+
|
304
306
|
def output(output_path)
|
305
307
|
output_check(output_path)
|
306
308
|
%w(BUILD RPMS SRPMS SOURCES SPECS).each { |d| FileUtils.mkdir_p(build_path(d)) }
|
307
309
|
args = ["rpmbuild", "-bb"]
|
308
310
|
|
311
|
+
if %x{uname -m}.chomp != self.architecture
|
312
|
+
args += [ '--target', self.architecture ]
|
313
|
+
end
|
314
|
+
|
309
315
|
# issue #309
|
310
316
|
if !attributes[:rpm_os].nil?
|
311
317
|
rpm_target = "#{architecture}-unknown-#{attributes[:rpm_os]}"
|
@@ -324,6 +330,7 @@ class FPM::Package::RPM < FPM::Package
|
|
324
330
|
if attributes[:rpm_auto_add_directories?]
|
325
331
|
fs_dirs_list = File.join(template_dir, "rpm", "filesystem_list")
|
326
332
|
fs_dirs = File.readlines(fs_dirs_list).reject { |x| x =~ /^\s*#/}.map { |x| x.chomp }
|
333
|
+
fs_dirs.concat((attributes[:auto_add_exclude_directories] or []))
|
327
334
|
|
328
335
|
Find.find(staging_path) do |path|
|
329
336
|
next if path == staging_path
|
@@ -333,7 +340,7 @@ class FPM::Package::RPM < FPM::Package
|
|
333
340
|
end
|
334
341
|
end
|
335
342
|
else
|
336
|
-
self.directories = self.directories.map { |x|
|
343
|
+
self.directories = self.directories.map { |x| self.prefixed_path(x) }
|
337
344
|
alldirs = []
|
338
345
|
self.directories.each do |path|
|
339
346
|
Find.find(File.join(staging_path, path)) do |subpath|
|
@@ -348,14 +355,15 @@ class FPM::Package::RPM < FPM::Package
|
|
348
355
|
# scan all conf file paths for files and add them
|
349
356
|
allconfigs = []
|
350
357
|
self.config_files.each do |path|
|
351
|
-
cfg_path = File.
|
358
|
+
cfg_path = File.join(staging_path, path)
|
359
|
+
raise "Config file path #{cfg_path} does not exist" unless File.exist?(cfg_path)
|
352
360
|
Find.find(cfg_path) do |p|
|
353
361
|
allconfigs << p.gsub("#{staging_path}/", '') if File.file? p
|
354
362
|
end
|
355
363
|
end
|
356
364
|
allconfigs.sort!.uniq!
|
357
365
|
|
358
|
-
self.config_files = allconfigs.map { |x| File.join(
|
366
|
+
self.config_files = allconfigs.map { |x| File.join("/", x) }
|
359
367
|
|
360
368
|
(attributes[:rpm_rpmbuild_define] or []).each do |define|
|
361
369
|
args += ["--define", define]
|
@@ -383,8 +391,6 @@ class FPM::Package::RPM < FPM::Package
|
|
383
391
|
# This should only output one rpm, should we verify this?
|
384
392
|
FileUtils.cp(rpmpath, output_path)
|
385
393
|
end
|
386
|
-
|
387
|
-
@logger.log("Created rpm", :path => output_path)
|
388
394
|
end # def output
|
389
395
|
|
390
396
|
def prefix
|
@@ -394,7 +400,7 @@ class FPM::Package::RPM < FPM::Package
|
|
394
400
|
def build_sub_dir
|
395
401
|
return "BUILD"
|
396
402
|
#return File.join("BUILD", prefix)
|
397
|
-
end # def
|
403
|
+
end # def build_sub_dir
|
398
404
|
|
399
405
|
def version
|
400
406
|
if @version.kind_of?(String) and @version.include?("-")
|
@@ -433,5 +439,5 @@ class FPM::Package::RPM < FPM::Package
|
|
433
439
|
|
434
440
|
public(:input, :output, :converted_from, :architecture, :to_s, :iteration,
|
435
441
|
:payload_compression, :digest_algorithm, :prefix, :build_sub_dir,
|
436
|
-
:epoch, :version)
|
442
|
+
:epoch, :version, :prefixed_path)
|
437
443
|
end # class FPM::Package::RPM
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require "erb"
|
2
|
+
require "fpm/namespace"
|
3
|
+
require "fpm/package"
|
4
|
+
require "fpm/errors"
|
5
|
+
require "fpm/util"
|
6
|
+
require "backports"
|
7
|
+
require "fileutils"
|
8
|
+
require "digest"
|
9
|
+
|
10
|
+
# Support for self extracting sh files (.sh files)
|
11
|
+
#
|
12
|
+
# This class only supports output of packages.
|
13
|
+
#
|
14
|
+
# The sh package is a single sh file with a bzipped tar payload concatenated to the end.
|
15
|
+
# The script can unpack the tarball to install it and call optional post install scripts.
|
16
|
+
class FPM::Package::Sh < FPM::Package
|
17
|
+
|
18
|
+
def output(output_path)
|
19
|
+
create_scripts
|
20
|
+
|
21
|
+
# Make one file. The installscript can unpack itself.
|
22
|
+
`cat #{install_script} #{payload} > #{output_path}`
|
23
|
+
FileUtils.chmod("+x", output_path)
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_scripts
|
27
|
+
if script?(:before_install)
|
28
|
+
# the scripts are kept in the payload so what would before install be if we've already
|
29
|
+
# unpacked the payload?
|
30
|
+
raise "sh package does not support before install scripts."
|
31
|
+
end
|
32
|
+
|
33
|
+
if script?(:after_install)
|
34
|
+
File.write(File.join(fpm_meta_path, "after_install"), script(:after_install))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def install_script
|
39
|
+
path = build_path("installer.sh")
|
40
|
+
File.open(path, "w") do |file|
|
41
|
+
file.write template("sh.erb").result(binding)
|
42
|
+
end
|
43
|
+
path
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the path to the tar file containing the packed up staging directory
|
47
|
+
def payload
|
48
|
+
payload_tar = build_path("payload.tar")
|
49
|
+
@logger.info("Creating payload tar ", :path => payload_tar)
|
50
|
+
|
51
|
+
args = [ tar_cmd,
|
52
|
+
"-C",
|
53
|
+
staging_path,
|
54
|
+
"-cf",
|
55
|
+
payload_tar,
|
56
|
+
"--owner=0",
|
57
|
+
"--group=0",
|
58
|
+
"--numeric-owner",
|
59
|
+
"." ]
|
60
|
+
|
61
|
+
unless safesystem(*args)
|
62
|
+
raise "Command failed while creating payload tar: #{args}"
|
63
|
+
end
|
64
|
+
payload_tar
|
65
|
+
end
|
66
|
+
|
67
|
+
# Where we keep metadata and post install scripts and such
|
68
|
+
def fpm_meta_path
|
69
|
+
@fpm_meta_path ||= begin
|
70
|
+
path = File.join(staging_path, ".fpm")
|
71
|
+
FileUtils.mkdir_p(path)
|
72
|
+
path
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "backports" # gem backports
|
2
|
+
require "fpm/package"
|
3
|
+
require "fpm/util"
|
4
|
+
require "fileutils"
|
5
|
+
require "fpm/package/dir"
|
6
|
+
|
7
|
+
# Use a zip as a package.
|
8
|
+
#
|
9
|
+
# This provides no metadata. Both input and output are supported.
|
10
|
+
class FPM::Package::Zip < FPM::Package
|
11
|
+
|
12
|
+
# Input a zipfile.
|
13
|
+
def input(input_path)
|
14
|
+
# use part of the filename as the package name
|
15
|
+
self.name = File.extname(input_path)[1..-1]
|
16
|
+
|
17
|
+
realpath = Pathname.new(input_path).realpath.to_s
|
18
|
+
::Dir.chdir(build_path) do
|
19
|
+
safesystem("unzip", realpath)
|
20
|
+
end
|
21
|
+
|
22
|
+
# use dir to set stuff up properly, mainly so I don't have to reimplement
|
23
|
+
# the chdir/prefix stuff special for zip.
|
24
|
+
dir = convert(FPM::Package::Dir)
|
25
|
+
if attributes[:chdir]
|
26
|
+
dir.attributes[:chdir] = File.join(build_path, attributes[:chdir])
|
27
|
+
else
|
28
|
+
dir.attributes[:chdir] = build_path
|
29
|
+
end
|
30
|
+
|
31
|
+
cleanup_staging
|
32
|
+
# Tell 'dir' to input "." and chdir/prefix will help it figure out the
|
33
|
+
# rest.
|
34
|
+
dir.input(".")
|
35
|
+
@staging_path = dir.staging_path
|
36
|
+
dir.cleanup_build
|
37
|
+
end # def input
|
38
|
+
|
39
|
+
# Output a tarball.
|
40
|
+
#
|
41
|
+
# If the output path ends predictably (like in .tar.gz) it will try to obey
|
42
|
+
# the compression type.
|
43
|
+
def output(output_path)
|
44
|
+
output_check(output_path)
|
45
|
+
|
46
|
+
files = Find.find(staging_path).to_a
|
47
|
+
safesystem("zip", output_path, *files)
|
48
|
+
end # def output
|
49
|
+
|
50
|
+
# Generate the proper tar flags based on the path name.
|
51
|
+
def tar_compression_flag(path)
|
52
|
+
case path
|
53
|
+
when /\.tar\.bz2$/
|
54
|
+
return "-j"
|
55
|
+
when /\.tar\.gz$|\.tgz$/
|
56
|
+
return "-z"
|
57
|
+
when /\.tar\.xz$/
|
58
|
+
return "-J"
|
59
|
+
else
|
60
|
+
return nil
|
61
|
+
end
|
62
|
+
end # def tar_compression_flag
|
63
|
+
end # class FPM::Package::Tar
|
data/lib/fpm/util.rb
CHANGED
@@ -30,18 +30,29 @@ module FPM::Util
|
|
30
30
|
return envpath.select { |p| File.executable?(File.join(p, program)) }.any?
|
31
31
|
end # def program_in_path
|
32
32
|
|
33
|
+
def program_exists?(program)
|
34
|
+
# Scan path to find the executable
|
35
|
+
# Do this to help the user get a better error message.
|
36
|
+
return program_in_path?(program) if !program.include?("/")
|
37
|
+
return File.executable?(program)
|
38
|
+
end # def program_exists?
|
39
|
+
|
40
|
+
def default_shell
|
41
|
+
shell = ENV["SHELL"]
|
42
|
+
return "/bin/sh" if shell.nil? || shell.empty?
|
43
|
+
return shell
|
44
|
+
end
|
45
|
+
|
33
46
|
# Run a command safely in a way that gets reports useful errors.
|
34
47
|
def safesystem(*args)
|
35
48
|
# ChildProcess isn't smart enough to run a $SHELL if there's
|
36
49
|
# spaces in the first arg and there's only 1 arg.
|
37
50
|
if args.size == 1
|
38
|
-
args = [
|
51
|
+
args = [ default_shell, "-c", args[0] ]
|
39
52
|
end
|
40
53
|
program = args[0]
|
41
54
|
|
42
|
-
|
43
|
-
# Do this to help the user get a better error message.
|
44
|
-
if !program.include?("/") and !program_in_path?(program)
|
55
|
+
if !program_exists?(program)
|
45
56
|
raise ExecutableNotFound.new(program)
|
46
57
|
end
|
47
58
|
|
@@ -73,7 +84,7 @@ module FPM::Util
|
|
73
84
|
return success
|
74
85
|
end # def safesystem
|
75
86
|
|
76
|
-
# Run a command safely in a way that captures output and status.
|
87
|
+
# Run a command safely in a way that captures output and status.
|
77
88
|
def safesystemout(*args)
|
78
89
|
if args.size == 1
|
79
90
|
args = [ ENV["SHELL"], "-c", args[0] ]
|
@@ -155,7 +166,29 @@ module FPM::Util
|
|
155
166
|
when 'directory'
|
156
167
|
FileUtils.mkdir(dst) unless File.exists? dst
|
157
168
|
else
|
158
|
-
|
159
|
-
|
160
|
-
|
169
|
+
# if the file with the same dev and inode has been copied already -
|
170
|
+
# hard link it's copy to `dst`, otherwise make an actual copy
|
171
|
+
st = File.lstat(src)
|
172
|
+
known_entry = copied_entries[[st.dev, st.ino]]
|
173
|
+
if known_entry
|
174
|
+
FileUtils.ln(known_entry, dst)
|
175
|
+
else
|
176
|
+
FileUtils.copy_entry(src, dst)
|
177
|
+
copied_entries[[st.dev, st.ino]] = dst
|
178
|
+
end
|
179
|
+
end # else...
|
180
|
+
end # def copy_entry
|
181
|
+
|
182
|
+
def copied_entries
|
183
|
+
# TODO(sissel): I wonder that this entry-copy knowledge needs to be put
|
184
|
+
# into a separate class/module. As is, calling copy_entry the same way
|
185
|
+
# in slightly different contexts will result in weird or bad behavior.
|
186
|
+
# What I mean is if we do:
|
187
|
+
# pkg = FPM::Package::Dir...
|
188
|
+
# pkg.output()...
|
189
|
+
# pkg.output()...
|
190
|
+
# The 2nd output call will fail or behave weirdly because @copied_entries
|
191
|
+
# is already populated. even though this is anew round of copying.
|
192
|
+
return @copied_entries ||= {}
|
193
|
+
end # def copied_entries
|
161
194
|
end # module FPM::Util
|
data/lib/fpm/version.rb
CHANGED
data/templates/rpm.erb
CHANGED
@@ -41,7 +41,6 @@ Epoch: <%= epoch %>
|
|
41
41
|
Release: <%= iteration or 1 %>
|
42
42
|
<%# use the first line of the description as the summary -%>
|
43
43
|
Summary: <%= description.split("\n").first.empty? ? "_" : description.split("\n").first %>
|
44
|
-
BuildArch: <%= architecture %>
|
45
44
|
<% if !attributes[:rpm_autoreqprov?] -%>
|
46
45
|
AutoReqProv: no
|
47
46
|
<% else -%>
|
@@ -127,7 +126,7 @@ Obsoletes: <%= repl %>
|
|
127
126
|
<% end -%>
|
128
127
|
|
129
128
|
%files
|
130
|
-
%defattr(<%= attributes[:rpm_defattrfile] %>,<%= attributes[:rpm_user] %>,<%= attributes[:rpm_group] %>,<%= attributes[:rpm_defattrdir] %>)
|
129
|
+
%defattr(<%= attributes[:rpm_defattrfile] %>,<%= attributes[:rpm_user] || "root" %>,<%= attributes[:rpm_group] || "root" %>,<%= attributes[:rpm_defattrdir] %>)
|
131
130
|
<%# Output config files and then regular files. -%>
|
132
131
|
<% config_files.each do |path| -%>
|
133
132
|
%config(noreplace) <%= rpm_file_entry(path) %>
|
data/templates/sh.erb
ADDED
@@ -0,0 +1,297 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# bail out if any part of this fails
|
4
|
+
set -e
|
5
|
+
|
6
|
+
# This is the self-extracting installer script for an FPM shell installer package.
|
7
|
+
# It contains the logic to unpack a tar archive appended to the end of this script
|
8
|
+
# and, optionally, to run post install logic.
|
9
|
+
# Run the package file with -h to see a usage message or look at the print_usage method.
|
10
|
+
#
|
11
|
+
# The post install scripts are called with INSTALL_ROOT, INSTALL_DIR and VERBOSE exported
|
12
|
+
# into the environment for their use.
|
13
|
+
#
|
14
|
+
# INSTALL_ROOT = the path passed in with -i or a relative directory of the name of the package
|
15
|
+
# file with no extension
|
16
|
+
# INSTALL_DIR = the same as INSTALL_ROOT unless -c (capistrano release directory) argumetn
|
17
|
+
# is used. Then it is $INSTALL_ROOT/releases/<datestamp>
|
18
|
+
# CURRENT_DIR = if -c argument is used, this is set to the $INSTALL_ROOT/current which is
|
19
|
+
# symlinked to INSTALL_DIR
|
20
|
+
# VERBOSE = is set if the package was called with -v for verbose output
|
21
|
+
function main() {
|
22
|
+
set_install_dir
|
23
|
+
|
24
|
+
create_pid
|
25
|
+
|
26
|
+
wait_for_others
|
27
|
+
|
28
|
+
kill_others
|
29
|
+
|
30
|
+
set_owner
|
31
|
+
|
32
|
+
unpack_payload
|
33
|
+
|
34
|
+
if [ "$UNPACK_ONLY" == "1" ] ; then
|
35
|
+
echo "Unpacking complete, not moving symlinks or restarting because unpack only was specified."
|
36
|
+
else
|
37
|
+
create_symlinks
|
38
|
+
|
39
|
+
set +e # don't exit on errors to allow us to clean up
|
40
|
+
if ! run_post_install ; then
|
41
|
+
revert_symlinks
|
42
|
+
log "Installation failed."
|
43
|
+
exit 1
|
44
|
+
else
|
45
|
+
clean_out_old_releases
|
46
|
+
log "Installation complete."
|
47
|
+
fi
|
48
|
+
fi
|
49
|
+
}
|
50
|
+
|
51
|
+
# deletes the PID file for this installation
|
52
|
+
function delete_pid(){
|
53
|
+
rm -f ${INSTALL_ROOT}/$$.pid 2> /dev/null
|
54
|
+
}
|
55
|
+
|
56
|
+
# creates a PID file for this installation
|
57
|
+
function create_pid(){
|
58
|
+
trap "delete_pid" EXIT
|
59
|
+
echo $$> ${INSTALL_ROOT}/$$.pid
|
60
|
+
}
|
61
|
+
|
62
|
+
|
63
|
+
# checks for other PID files and sleeps for a grace period if found
|
64
|
+
function wait_for_others(){
|
65
|
+
local count=`ls ${INSTALL_ROOT}/*.pid | wc -l`
|
66
|
+
|
67
|
+
if [ $count -gt 1 ] ; then
|
68
|
+
sleep 10
|
69
|
+
fi
|
70
|
+
}
|
71
|
+
|
72
|
+
# kills other running installations
|
73
|
+
function kill_others(){
|
74
|
+
for PID_FILE in $(ls ${INSTALL_ROOT}/*.pid) ; do
|
75
|
+
local p=`cat ${PID_FILE}`
|
76
|
+
if ! [ $p == $$ ] ; then
|
77
|
+
kill -9 $p
|
78
|
+
rm -f $PID_FILE 2> /dev/null
|
79
|
+
fi
|
80
|
+
done
|
81
|
+
}
|
82
|
+
|
83
|
+
# echos metadata file. A function so that we can have it change after we set INSTALL_ROOT
|
84
|
+
function fpm_metadata_file(){
|
85
|
+
echo "${INSTALL_ROOT}/.install-metadata"
|
86
|
+
}
|
87
|
+
|
88
|
+
# if this package was installed at this location already we will find a metadata file with the details
|
89
|
+
# about the installation that we left here. Load from that if available but allow command line args to trump
|
90
|
+
function load_environment(){
|
91
|
+
local METADATA=$(fpm_metadata_file)
|
92
|
+
if [ -r "${METADATA}" ] ; then
|
93
|
+
log "Found existing metadata file '${METADATA}'. Loading previous install details. Env vars in current environment will take precedence over saved values."
|
94
|
+
local TMP="/tmp/$(basename $0).$$.tmp"
|
95
|
+
# save existing environment, load saved environment from previous run from install-metadata and then
|
96
|
+
# overlay current environment so that anything set currencly will take precedence
|
97
|
+
# but missing values will be loaded from previous runs.
|
98
|
+
save_environment "$TMP"
|
99
|
+
source "${METADATA}"
|
100
|
+
source $TMP
|
101
|
+
rm "$TMP"
|
102
|
+
fi
|
103
|
+
}
|
104
|
+
|
105
|
+
# write out metadata for future installs
|
106
|
+
function save_environment(){
|
107
|
+
local METADATA=$1
|
108
|
+
echo -n "" > ${METADATA} # empty file
|
109
|
+
|
110
|
+
# just piping env to a file doesn't quote the variables. This does
|
111
|
+
# filter out multiline junk and _. _ is a readonly variable
|
112
|
+
env | egrep "^[^ ]+=.*" | grep -v "^_=" | while read ENVVAR ; do
|
113
|
+
local NAME=${ENVVAR%%=*}
|
114
|
+
# sed is to preserve variable values with dollars (for escaped variables or $() style command replacement),
|
115
|
+
# and command replacement backticks
|
116
|
+
# Escaped parens captures backward reference \1 which gets replaced with backslash and \1 to esape them in the saved
|
117
|
+
# variable value
|
118
|
+
local VALUE=$(eval echo '$'$NAME | sed 's/\([$`]\)/\\\1/g')
|
119
|
+
echo "export $NAME=\"$VALUE\"" >> ${METADATA}
|
120
|
+
done
|
121
|
+
|
122
|
+
if [ -n "${OWNER}" ] ; then
|
123
|
+
chown ${OWNER} ${METADATA}
|
124
|
+
fi
|
125
|
+
}
|
126
|
+
|
127
|
+
function set_install_dir(){
|
128
|
+
# if INSTALL_ROOT isn't set by parsed args, use basename of package file with no extension
|
129
|
+
DEFAULT_DIR=$(echo $(basename $0) | sed -e 's/\.[^\.]*$//')
|
130
|
+
INSTALL_DIR=${INSTALL_ROOT:-$DEFAULT_DIR}
|
131
|
+
|
132
|
+
DATESTAMP=$(date +%Y%m%d%H%M%S)
|
133
|
+
if [ -z "$USE_FLAT_RELEASE_DIRECTORY" ] ; then
|
134
|
+
<%= "RELEASE_ID=#{release_id}" if respond_to?(:release_id) %>
|
135
|
+
INSTALL_DIR="${RELEASES_DIR}/${RELEASE_ID:-$DATESTAMP}"
|
136
|
+
fi
|
137
|
+
|
138
|
+
mkdir -p "$INSTALL_DIR" || die "Unable to create install directory $INSTALL_DIR"
|
139
|
+
|
140
|
+
export INSTALL_DIR
|
141
|
+
|
142
|
+
log "Installing package to '$INSTALL_DIR'"
|
143
|
+
}
|
144
|
+
|
145
|
+
function set_owner(){
|
146
|
+
export OWNER=${OWNER:-$USER}
|
147
|
+
log "Installing as user $OWNER"
|
148
|
+
}
|
149
|
+
|
150
|
+
function unpack_payload(){
|
151
|
+
if [ "$FORCE" == "1" ] || [ ! "$(ls -A $INSTALL_DIR)" ] ; then
|
152
|
+
log "Unpacking payload . . ."
|
153
|
+
local archive_line=$(grep -a -n -m1 '__ARCHIVE__$' $0 | sed 's/:.*//')
|
154
|
+
tail -n +$((archive_line + 1)) $0 | tar -C $INSTALL_DIR -xf - > /dev/null || die "Failed to unpack payload from the end of '$0' into '$INSTALL_DIR'"
|
155
|
+
else
|
156
|
+
# Files are already here, just move symlinks
|
157
|
+
log "Directory already exists and has contents ($INSTALL_DIR). Not unpacking payload."
|
158
|
+
fi
|
159
|
+
}
|
160
|
+
|
161
|
+
function run_post_install(){
|
162
|
+
local AFTER_INSTALL=$INSTALL_DIR/.fpm/after_install
|
163
|
+
if [ -r $AFTER_INSTALL ] ; then
|
164
|
+
chmod +x $AFTER_INSTALL
|
165
|
+
log "Running post install script"
|
166
|
+
log $($AFTER_INSTALL)
|
167
|
+
return $?
|
168
|
+
fi
|
169
|
+
return 0
|
170
|
+
}
|
171
|
+
|
172
|
+
function create_symlinks(){
|
173
|
+
[ -n "$USE_FLAT_RELEASE_DIRECTORY" ] && return
|
174
|
+
|
175
|
+
export CURRENT_DIR="$INSTALL_ROOT/current"
|
176
|
+
if [ -e "$CURRENT_DIR" ] ; then
|
177
|
+
OLD_CURRENT_TARGET=$(readlink $CURRENT_DIR)
|
178
|
+
rm "$CURRENT_DIR"
|
179
|
+
fi
|
180
|
+
ln -s "$INSTALL_DIR" "$CURRENT_DIR"
|
181
|
+
|
182
|
+
log "Symlinked '$INSTALL_DIR' to '$CURRENT_DIR'"
|
183
|
+
}
|
184
|
+
|
185
|
+
# in case post install fails we may have to back out switching the symlink to current
|
186
|
+
# We can't switch the symlink after because post install may assume that it is in the
|
187
|
+
# exact state of being installed (services looking to current for their latest code)
|
188
|
+
function revert_symlinks(){
|
189
|
+
if [ -n "$OLD_CURRENT_TARGET" ] ; then
|
190
|
+
log "Putting current symlink back to '$OLD_CURRENT_TARGET'"
|
191
|
+
if [ -e "$CURRENT_DIR" ] ; then
|
192
|
+
rm "$CURRENT_DIR"
|
193
|
+
fi
|
194
|
+
ln -s "$OLD_CURRENT_TARGET" "$CURRENT_DIR"
|
195
|
+
fi
|
196
|
+
}
|
197
|
+
|
198
|
+
function clean_out_old_releases(){
|
199
|
+
[ -n "$USE_FLAT_RELEASE_DIRECTORY" ] && return
|
200
|
+
|
201
|
+
while [ $(ls -tr "${RELEASES_DIR}" | wc -l) -gt 2 ] ; do
|
202
|
+
OLDEST_RELEASE=$(ls -tr "${RELEASES_DIR}" | head -1)
|
203
|
+
log "Deleting old release '${OLDEST_RELEASE}'"
|
204
|
+
rm -rf "${RELEASES_DIR}/${OLDEST_RELEASE}"
|
205
|
+
done
|
206
|
+
}
|
207
|
+
|
208
|
+
function print_usage(){
|
209
|
+
echo "Usage: `basename $0` [options]"
|
210
|
+
echo "Install this package"
|
211
|
+
echo " -i <DIRECTORY> : install_root - an optional directory to install to."
|
212
|
+
echo " Default is package file name without file extension"
|
213
|
+
echo " -o <USER> : owner - the name of the user that will own the files installed"
|
214
|
+
echo " by the package. Defaults to current user"
|
215
|
+
echo " -r: disable capistrano style release directories - Default behavior is to create a releases directory inside"
|
216
|
+
echo " install_root and unpack contents into a date stamped (or build time id named) directory under the release"
|
217
|
+
echo " directory. Then create a 'current' symlink under install_root to the unpacked"
|
218
|
+
echo " directory once installation is complete replacing the symlink if it already "
|
219
|
+
echo " exists. If this flag is set just install into install_root directly"
|
220
|
+
echo " -u: Unpack the package, but do not install and symlink the payload"
|
221
|
+
echo " -f: force - Always overwrite existing installations"
|
222
|
+
echo " -y: yes - Don't prompt to clobber existing installations"
|
223
|
+
echo " -v: verbose - More output on installation"
|
224
|
+
echo " -h: help - Display this message"
|
225
|
+
}
|
226
|
+
|
227
|
+
function die () {
|
228
|
+
local message=$*
|
229
|
+
echo "Error: $message : $!"
|
230
|
+
exit 1
|
231
|
+
}
|
232
|
+
|
233
|
+
function log(){
|
234
|
+
local message=$*
|
235
|
+
if [ -n "$VERBOSE" ] ; then
|
236
|
+
echo "$*"
|
237
|
+
fi
|
238
|
+
}
|
239
|
+
|
240
|
+
function parse_args() {
|
241
|
+
args=`getopt i:o:rfuyvh $*`
|
242
|
+
|
243
|
+
if [ $? != 0 ] ; then
|
244
|
+
print_usage
|
245
|
+
exit 2
|
246
|
+
fi
|
247
|
+
set -- $args
|
248
|
+
for i
|
249
|
+
do
|
250
|
+
case "$i"
|
251
|
+
in
|
252
|
+
-r)
|
253
|
+
USE_FLAT_RELEASE_DIRECTORY=1
|
254
|
+
shift;;
|
255
|
+
-i)
|
256
|
+
shift;
|
257
|
+
export INSTALL_ROOT="$1"
|
258
|
+
export RELEASES_DIR="${INSTALL_ROOT}/releases"
|
259
|
+
shift;;
|
260
|
+
-o)
|
261
|
+
shift;
|
262
|
+
export OWNER="$1"
|
263
|
+
shift;;
|
264
|
+
-v)
|
265
|
+
export VERBOSE=1
|
266
|
+
shift;;
|
267
|
+
-u)
|
268
|
+
UNPACK_ONLY=1
|
269
|
+
shift;;
|
270
|
+
-f)
|
271
|
+
FORCE=1
|
272
|
+
shift;;
|
273
|
+
-y)
|
274
|
+
CONFIRM="y"
|
275
|
+
shift;;
|
276
|
+
-h)
|
277
|
+
print_usage
|
278
|
+
exit 0
|
279
|
+
shift;;
|
280
|
+
--)
|
281
|
+
shift; break;;
|
282
|
+
esac
|
283
|
+
done
|
284
|
+
}
|
285
|
+
|
286
|
+
# parse args first to get install root
|
287
|
+
parse_args $*
|
288
|
+
# load environment from previous installations so we get defaults from that
|
289
|
+
load_environment
|
290
|
+
# reparse args so they can override any settings from previous installations if provided on the command line
|
291
|
+
parse_args $*
|
292
|
+
|
293
|
+
main
|
294
|
+
save_environment $(fpm_metadata_file)
|
295
|
+
exit 0
|
296
|
+
|
297
|
+
__ARCHIVE__
|
metadata
CHANGED
@@ -1,100 +1,74 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fpm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
5
|
-
prerelease:
|
4
|
+
version: 1.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Jordan Sissel
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2014-
|
11
|
+
date: 2014-04-23 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: json
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: 1.7.7
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 1.7.7
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: cabin
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: 0.6.0
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: 0.6.0
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: backports
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: 2.6.2
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: 2.6.2
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: arr-pm
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
59
|
- - ~>
|
68
60
|
- !ruby/object:Gem::Version
|
69
|
-
version: 0.0.
|
61
|
+
version: 0.0.9
|
70
62
|
type: :runtime
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
66
|
- - ~>
|
76
67
|
- !ruby/object:Gem::Version
|
77
|
-
version: 0.0.
|
78
|
-
- !ruby/object:Gem::Dependency
|
79
|
-
name: ftw
|
80
|
-
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
|
-
requirements:
|
83
|
-
- - ~>
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
version: 0.0.30
|
86
|
-
type: :runtime
|
87
|
-
prerelease: false
|
88
|
-
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
|
-
requirements:
|
91
|
-
- - ~>
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
version: 0.0.30
|
68
|
+
version: 0.0.9
|
94
69
|
- !ruby/object:Gem::Dependency
|
95
70
|
name: clamp
|
96
71
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
72
|
requirements:
|
99
73
|
- - ~>
|
100
74
|
- !ruby/object:Gem::Version
|
@@ -102,7 +76,6 @@ dependencies:
|
|
102
76
|
type: :runtime
|
103
77
|
prerelease: false
|
104
78
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
79
|
requirements:
|
107
80
|
- - ~>
|
108
81
|
- !ruby/object:Gem::Version
|
@@ -110,55 +83,48 @@ dependencies:
|
|
110
83
|
- !ruby/object:Gem::Dependency
|
111
84
|
name: childprocess
|
112
85
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
86
|
requirements:
|
115
|
-
- -
|
87
|
+
- - '>='
|
116
88
|
- !ruby/object:Gem::Version
|
117
89
|
version: '0'
|
118
90
|
type: :runtime
|
119
91
|
prerelease: false
|
120
92
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
93
|
requirements:
|
123
|
-
- -
|
94
|
+
- - '>='
|
124
95
|
- !ruby/object:Gem::Version
|
125
96
|
version: '0'
|
126
97
|
- !ruby/object:Gem::Dependency
|
127
98
|
name: ffi
|
128
99
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
100
|
requirements:
|
131
|
-
- -
|
101
|
+
- - '>='
|
132
102
|
- !ruby/object:Gem::Version
|
133
103
|
version: '0'
|
134
104
|
type: :runtime
|
135
105
|
prerelease: false
|
136
106
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
107
|
requirements:
|
139
|
-
- -
|
108
|
+
- - '>='
|
140
109
|
- !ruby/object:Gem::Version
|
141
110
|
version: '0'
|
142
111
|
- !ruby/object:Gem::Dependency
|
143
112
|
name: rspec
|
144
113
|
requirement: !ruby/object:Gem::Requirement
|
145
|
-
none: false
|
146
114
|
requirements:
|
147
|
-
- -
|
115
|
+
- - '>='
|
148
116
|
- !ruby/object:Gem::Version
|
149
117
|
version: '0'
|
150
118
|
type: :development
|
151
119
|
prerelease: false
|
152
120
|
version_requirements: !ruby/object:Gem::Requirement
|
153
|
-
none: false
|
154
121
|
requirements:
|
155
|
-
- -
|
122
|
+
- - '>='
|
156
123
|
- !ruby/object:Gem::Version
|
157
124
|
version: '0'
|
158
125
|
- !ruby/object:Gem::Dependency
|
159
126
|
name: insist
|
160
127
|
requirement: !ruby/object:Gem::Requirement
|
161
|
-
none: false
|
162
128
|
requirements:
|
163
129
|
- - ~>
|
164
130
|
- !ruby/object:Gem::Version
|
@@ -166,7 +132,6 @@ dependencies:
|
|
166
132
|
type: :development
|
167
133
|
prerelease: false
|
168
134
|
version_requirements: !ruby/object:Gem::Requirement
|
169
|
-
none: false
|
170
135
|
requirements:
|
171
136
|
- - ~>
|
172
137
|
- !ruby/object:Gem::Version
|
@@ -174,49 +139,43 @@ dependencies:
|
|
174
139
|
- !ruby/object:Gem::Dependency
|
175
140
|
name: minitest
|
176
141
|
requirement: !ruby/object:Gem::Requirement
|
177
|
-
none: false
|
178
142
|
requirements:
|
179
|
-
- -
|
143
|
+
- - '>='
|
180
144
|
- !ruby/object:Gem::Version
|
181
145
|
version: '0'
|
182
146
|
type: :development
|
183
147
|
prerelease: false
|
184
148
|
version_requirements: !ruby/object:Gem::Requirement
|
185
|
-
none: false
|
186
149
|
requirements:
|
187
|
-
- -
|
150
|
+
- - '>='
|
188
151
|
- !ruby/object:Gem::Version
|
189
152
|
version: '0'
|
190
153
|
- !ruby/object:Gem::Dependency
|
191
154
|
name: pry
|
192
155
|
requirement: !ruby/object:Gem::Requirement
|
193
|
-
none: false
|
194
156
|
requirements:
|
195
|
-
- -
|
157
|
+
- - '>='
|
196
158
|
- !ruby/object:Gem::Version
|
197
159
|
version: '0'
|
198
160
|
type: :development
|
199
161
|
prerelease: false
|
200
162
|
version_requirements: !ruby/object:Gem::Requirement
|
201
|
-
none: false
|
202
163
|
requirements:
|
203
|
-
- -
|
164
|
+
- - '>='
|
204
165
|
- !ruby/object:Gem::Version
|
205
166
|
version: '0'
|
206
167
|
- !ruby/object:Gem::Dependency
|
207
168
|
name: stud
|
208
169
|
requirement: !ruby/object:Gem::Requirement
|
209
|
-
none: false
|
210
170
|
requirements:
|
211
|
-
- -
|
171
|
+
- - '>='
|
212
172
|
- !ruby/object:Gem::Version
|
213
173
|
version: '0'
|
214
174
|
type: :development
|
215
175
|
prerelease: false
|
216
176
|
version_requirements: !ruby/object:Gem::Requirement
|
217
|
-
none: false
|
218
177
|
requirements:
|
219
|
-
- -
|
178
|
+
- - '>='
|
220
179
|
- !ruby/object:Gem::Version
|
221
180
|
version: '0'
|
222
181
|
description: Convert directories, rpms, python eggs, rubygems, and more to rpms, debs,
|
@@ -228,39 +187,42 @@ executables:
|
|
228
187
|
extensions: []
|
229
188
|
extra_rdoc_files: []
|
230
189
|
files:
|
231
|
-
- lib/fpm.rb
|
232
|
-
- lib/fpm/package.rb
|
233
|
-
- lib/fpm/version.rb
|
234
|
-
- lib/fpm/namespace.rb
|
235
|
-
- lib/fpm/util.rb
|
236
|
-
- lib/fpm/errors.rb
|
237
190
|
- lib/fpm/command.rb
|
238
|
-
- lib/fpm/
|
239
|
-
- lib/fpm/
|
240
|
-
- lib/fpm/package/
|
241
|
-
- lib/fpm/package/
|
242
|
-
- lib/fpm/package/pyfpm/get_metadata.py
|
243
|
-
- lib/fpm/package/pyfpm/__init__.py
|
191
|
+
- lib/fpm/errors.rb
|
192
|
+
- lib/fpm/namespace.rb
|
193
|
+
- lib/fpm/package/cpan.rb
|
194
|
+
- lib/fpm/package/deb.rb
|
244
195
|
- lib/fpm/package/dir.rb
|
245
|
-
- lib/fpm/package/
|
196
|
+
- lib/fpm/package/empty.rb
|
246
197
|
- lib/fpm/package/gem.rb
|
247
|
-
- lib/fpm/package/
|
198
|
+
- lib/fpm/package/npm.rb
|
199
|
+
- lib/fpm/package/osxpkg.rb
|
200
|
+
- lib/fpm/package/pear.rb
|
201
|
+
- lib/fpm/package/pkgin.rb
|
248
202
|
- lib/fpm/package/puppet.rb
|
249
|
-
- lib/fpm/package/
|
203
|
+
- lib/fpm/package/pyfpm/__init__.py
|
204
|
+
- lib/fpm/package/pyfpm/__init__.pyc
|
205
|
+
- lib/fpm/package/pyfpm/get_metadata.py
|
206
|
+
- lib/fpm/package/pyfpm/get_metadata.pyc
|
250
207
|
- lib/fpm/package/python.rb
|
251
|
-
- lib/fpm/package/osxpkg.rb
|
252
|
-
- lib/fpm/package/solaris.rb
|
253
208
|
- lib/fpm/package/rpm.rb
|
254
|
-
- lib/fpm/package/
|
255
|
-
- lib/fpm/package/
|
209
|
+
- lib/fpm/package/sh.rb
|
210
|
+
- lib/fpm/package/solaris.rb
|
211
|
+
- lib/fpm/package/tar.rb
|
212
|
+
- lib/fpm/package/zip.rb
|
213
|
+
- lib/fpm/package.rb
|
214
|
+
- lib/fpm/util.rb
|
215
|
+
- lib/fpm/version.rb
|
216
|
+
- lib/fpm.rb
|
256
217
|
- bin/fpm
|
257
|
-
- templates/
|
218
|
+
- templates/deb/ldconfig.sh.erb
|
258
219
|
- templates/deb.erb
|
259
220
|
- templates/osxpkg.erb
|
260
|
-
- templates/rpm/filesystem_list
|
261
|
-
- templates/deb/ldconfig.sh.erb
|
262
|
-
- templates/puppet/package.pp.erb
|
263
221
|
- templates/puppet/package/remove.pp.erb
|
222
|
+
- templates/puppet/package.pp.erb
|
223
|
+
- templates/rpm/filesystem_list
|
224
|
+
- templates/rpm.erb
|
225
|
+
- templates/sh.erb
|
264
226
|
- templates/solaris.erb
|
265
227
|
- LICENSE
|
266
228
|
- CONTRIBUTORS
|
@@ -268,27 +230,26 @@ files:
|
|
268
230
|
homepage: https://github.com/jordansissel/fpm
|
269
231
|
licenses:
|
270
232
|
- MIT-like
|
233
|
+
metadata: {}
|
271
234
|
post_install_message:
|
272
235
|
rdoc_options: []
|
273
236
|
require_paths:
|
274
237
|
- lib
|
275
238
|
- lib
|
276
239
|
required_ruby_version: !ruby/object:Gem::Requirement
|
277
|
-
none: false
|
278
240
|
requirements:
|
279
|
-
- -
|
241
|
+
- - '>='
|
280
242
|
- !ruby/object:Gem::Version
|
281
243
|
version: '0'
|
282
244
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
283
|
-
none: false
|
284
245
|
requirements:
|
285
|
-
- -
|
246
|
+
- - '>='
|
286
247
|
- !ruby/object:Gem::Version
|
287
248
|
version: '0'
|
288
249
|
requirements: []
|
289
250
|
rubyforge_project:
|
290
|
-
rubygems_version: 1.
|
251
|
+
rubygems_version: 2.1.11
|
291
252
|
signing_key:
|
292
|
-
specification_version:
|
253
|
+
specification_version: 4
|
293
254
|
summary: fpm - package building and mangling
|
294
255
|
test_files: []
|