fpm 1.0.2 → 1.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 +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: []
|