Class: FPM::Package::RPM
- Inherits:
-
FPM::Package
- Object
- FPM::Package
- FPM::Package::RPM
- Defined in:
- lib/fpm/package/rpm.rb
Overview
RPM Package type.
Build RPMs without having to waste hours reading Maximum-RPM. Well, in case you want to read it, here: www.rpm.org/max-rpm/
The following attributes are supported:
-
:rpm_rpmbuild_define - an array of definitions to give to rpmbuild. These are used, verbatim, each as: –define ITEM
Constant Summary collapse
- DIGEST_ALGORITHM_MAP =
{ "md5" => 1, "sha1" => 2, "sha256" => 8, "sha384" => 9, "sha512" => 10 }
- COMPRESSION_MAP =
{ "none" => "w0.gzdio", "xz" => ".xzdio", "xzmt" => "T.xzdio", "gzip" => ".gzdio", "bzip2" => ".bzdio" }
Instance Attribute Summary
Attributes inherited from FPM::Package
#attributes, #attrs, #category, #config_files, #conflicts, #dependencies, #description, #directories, #license, #maintainer, #name, #provides, #replaces, #scripts, #url, #vendor
Instance Method Summary collapse
-
#architecture ⇒ Object
Handle any architecture naming conversions.
-
#build_sub_dir ⇒ Object
def prefix.
-
#converted_from(origin) ⇒ Object
See FPM::Package#converted_from.
-
#digest_algorithm ⇒ Object
def payload_compression.
-
#epoch ⇒ Object
The default epoch value must be nil, see #381.
-
#input(path) ⇒ Object
def rpm_get_trigger.
-
#iteration ⇒ Object
This method ensures a default value for iteration if none is provided.
-
#output(output_path) ⇒ Object
def prefixed_path.
-
#payload_compression ⇒ Object
def to_s.
-
#prefix ⇒ Object
def output.
-
#prefixed_path(path) ⇒ Object
def input.
-
#summary ⇒ Object
def build_sub_dir.
- #to_s(format = nil) ⇒ Object
-
#version ⇒ Object
def summary.
Methods inherited from FPM::Package
apply_options, #build_path, #cleanup, #cleanup_build, #cleanup_staging, #convert, default_attributes, #edit_file, #files, inherited, #initialize, option, #script, #staging_path, #type, type, types
Methods included from Util
#ar_cmd, #ar_cmd_deterministic?, #copied_entries, #copy_entry, #copy_metadata, #default_shell, #execmd, #expand_pessimistic_constraints, #logger, #mknod_w, #program_exists?, #program_in_path?, #safesystem, #safesystemout, #tar_cmd, #tar_cmd_supports_sort_names_and_set_mtime?
Constructor Details
This class inherits a constructor from FPM::Package
Instance Method Details
#architecture ⇒ Object
Handle any architecture naming conversions. For example, debian calls amd64 what redhat calls x86_64, this method fixes those types of things.
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/fpm/package/rpm.rb', line 236 def architecture case @architecture when nil return %x{uname -m}.chomp # default to current arch when "amd64" # debian and redhat disagree on architecture names return "x86_64" when "native" return %x{uname -m}.chomp # 'native' is current arch when "all" # Translate fpm "all" arch to what it means in RPM. return "noarch" else return @architecture end end |
#build_sub_dir ⇒ Object
def prefix
564 565 566 567 |
# File 'lib/fpm/package/rpm.rb', line 564 def build_sub_dir return "BUILD" #return File.join("BUILD", prefix) end |
#converted_from(origin) ⇒ Object
See FPM::Package#converted_from
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/fpm/package/rpm.rb', line 258 def converted_from(origin) if origin == FPM::Package::Gem fixed_deps = [] self.dependencies.collect do |dep| # Gem dependency operator "~>" is not compatible with rpm. Translate any found. fixed_deps = fixed_deps + (dep) end self.dependencies = fixed_deps # Convert 'rubygem-foo' provides values to 'rubygem(foo)' # since that's what most rpm packagers seem to do. self.provides = self.provides.collect do |provides| # Tries to match rubygem_prefix [1], gem_name [2] and version [3] if present # and return it in rubygem_prefix(gem_name) form if name=/^(#{attributes[:gem_package_name_prefix]})-([^\s]+)\s*(.*)$/.match(provides) "#{name[1]}(#{name[2]})#{name[3] ? " #{name[3]}" : ""}" else provides end end if !self.attributes[:rpm_verbatim_gem_dependencies?] self.dependencies = self.dependencies.collect do |dependency| # Tries to match rubygem_prefix [1], gem_name [2] and version [3] if present # and return it in rubygem_prefix(gem_name) form if name=/^(#{attributes[:gem_package_name_prefix]})-([^\s]+)\s*(.*)$/.match(dependency) "#{name[1]}(#{name[2]})#{name[3] ? " #{name[3]}" : ""}" else dependency end end end end # Convert != dependency as Conflict =, as rpm doesn't understand != self.dependencies = self.dependencies.select do |dep| name, op, version = dep.split(/\s+/) dep_ok = true if op == '!=' self.conflicts << "#{name} = #{version}" dep_ok = false end dep_ok end # if --ignore-iteration-in-dependencies is true convert foo = X, to # foo >= X , foo < X+1 if self.attributes[:rpm_ignore_iteration_in_dependencies?] self.dependencies = self.dependencies.collect do |dep| name, op, version = dep.split(/\s+/) if op == '=' nextversion = version.split('.').collect { |v| v.to_i } nextversion[-1] += 1 nextversion = nextversion.join(".") logger.warn("Converting dependency #{dep} to #{name} >= #{version}, #{name} < #{nextversion}") ["#{name} >= #{version}", "#{name} < #{nextversion}"] else dep end end.flatten end setscript = proc do |scriptname| script_path = self.attributes[scriptname] # Skip scripts not set next if script_path.nil? if !File.exist?(script_path) logger.error("No such file (for #{scriptname.to_s}): #{script_path.inspect}") script_errors << script_path end # Load the script into memory. scripts[scriptname] = File.read(script_path) end setscript.call(:rpm_verifyscript) setscript.call(:rpm_posttrans) setscript.call(:rpm_pretrans) end |
#digest_algorithm ⇒ Object
def payload_compression
622 623 624 |
# File 'lib/fpm/package/rpm.rb', line 622 def digest_algorithm return DIGEST_ALGORITHM_MAP[attributes[:rpm_digest]] end |
#epoch ⇒ Object
The default epoch value must be nil, see #381
588 589 590 591 592 593 594 595 596 |
# File 'lib/fpm/package/rpm.rb', line 588 def epoch return @epoch if @epoch.is_a?(Numeric) if @epoch.nil? or @epoch.empty? return nil end return @epoch end |
#input(path) ⇒ Object
def rpm_get_trigger
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 |
# File 'lib/fpm/package/rpm.rb', line 354 def input(path) rpm = ::RPM::File.new(path) = {} rpm.header..each do |tag| [tag.tag] = tag.value end self.architecture = [:arch] self.category = [:group] self.description = [:description] self.epoch = ([:epoch] || [nil]).first # for some reason epoch is an array self.iteration = [:release] self.license = [:license] self.maintainer = maintainer self.name = [:name] self.url = [:url] self.vendor = [:vendor] self.version = [:version] self.scripts[:before_install] = [:prein] self.scripts[:after_install] = [:postin] self.scripts[:before_remove] = [:preun] self.scripts[:after_remove] = [:postun] self.scripts[:rpm_verifyscript] = [:verifyscript] self.scripts[:rpm_posttrans] = [:posttrans] self.scripts[:rpm_pretrans] = [:pretrans] # TODO(sissel): prefix these scripts above with a shebang line if there isn't one? # Also taking into account the value of tags[preinprog] etc, something like: # #!#{tags[:preinprog]} # #{tags[prein]} if ![:triggerindex].nil? val = [:triggerindex].zip([:triggername],[:triggerflags],[:triggerversion]).group_by{ |x| x[0]} val = val.collect do |order,data| new_data = data.collect { |x| [ x[1], rpm.operator(x[2]), x[3]].join(" ").strip}.join(", ") [order, rpm_get_trigger_type(data[0][2]), new_data] end val.each do |order, attr,data| self.attributes[attr] = [] if self.attributes[attr].nil? scriptprog = ([:triggerscriptprog][order] == '/bin/sh') ? "" : "-p #{[:triggerscriptprog][order]}" self.attributes[attr] << [data,[:triggerscripts][order],scriptprog] end end if !attributes[:no_auto_depends?] self.dependencies += rpm.requires.collect do |name, operator, version| [name, operator, version].join(" ") end end self.conflicts += rpm.conflicts.collect do |name, operator, version| [name, operator, version].join(" ") end self.provides += rpm.provides.collect do |name, operator, version| [name, operator, version].join(" ") end #input.replaces += replaces self.config_files += rpm.config_files # rpms support '%dir' things for specifying empty directories to package, # but the rpm header itself doesn't actually record this information. # so there's no 'directories' to copy, so don't try to merge in the # 'directories' feature. # TODO(sissel): If you want this feature, we'll have to find scan # the extracted rpm for empty directories. I'll wait until someone asks for # this feature #self.directories += rpm.directories # Extract to the staging directory rpm.extract(staging_path) end |
#iteration ⇒ Object
This method ensures a default value for iteration if none is provided.
253 254 255 |
# File 'lib/fpm/package/rpm.rb', line 253 def iteration return @iteration ? @iteration : 1 end |
#output(output_path) ⇒ Object
def prefixed_path
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 |
# File 'lib/fpm/package/rpm.rb', line 432 def output(output_path) output_check(output_path) %w(BUILD RPMS SRPMS SOURCES SPECS).each { |d| FileUtils.mkdir_p(build_path(d)) } args = ["rpmbuild", "-bb"] if %x{uname -m}.chomp != self.architecture rpm_target = self.architecture end # issue #309 if !attributes[:rpm_os].nil? rpm_target = "#{architecture}-unknown-#{attributes[:rpm_os]}" end # issue #707 if !rpm_target.nil? args += ["--target", rpm_target] end # set the rpm dist tag args += ["--define", "dist .#{attributes[:rpm_dist]}"] if attributes[:rpm_dist] args += [ "--define", "buildroot #{build_path}/BUILD", "--define", "_topdir #{build_path}", "--define", "_sourcedir #{build_path}", "--define", "_rpmdir #{build_path}/RPMS", "--define", "_tmppath #{attributes[:workdir]}" ] args += ["--sign"] if attributes[:rpm_sign?] if attributes[:rpm_auto_add_directories?] fs_dirs_list = File.join(template_dir, "rpm", "filesystem_list") fs_dirs = File.readlines(fs_dirs_list).reject { |x| x =~ /^\s*#/}.map { |x| x.chomp } fs_dirs.concat((attributes[:auto_add_exclude_directories] or [])) Find.find(staging_path) do |path| next if path == staging_path if File.directory? path and !File.symlink? path add_path = path.gsub(/^#{staging_path}/,'') self.directories << add_path if not fs_dirs.include? add_path end end else self.directories = self.directories.map { |x| self.prefixed_path(x) } alldirs = [] self.directories.each do |path| Find.find(File.join(staging_path, path)) do |subpath| if File.directory? subpath and !File.symlink? subpath alldirs << subpath.gsub(/^#{staging_path}/, '') end end end self.directories = alldirs end # include external config files (attributes[:config_files] or []).each do |conf| dest_conf = File.join(staging_path, conf) if File.exist?(dest_conf) logger.debug("Using --config-file from staging area", :path => conf) elsif File.exist?(conf) logger.info("Copying --config-file from local path", :path => conf) FileUtils.mkdir_p(File.dirname(dest_conf)) FileUtils.cp_r conf, dest_conf else logger.error("Failed to find given --config-file", :path => conf) raise "Could not find config file '#{conf}' in staging area or on host. This can happen if you specify `--config-file '#{conf}'` but this file does not exist in the source package and also does not exist in filesystem." end end # scan all conf file paths for files and add them allconfigs = [] self.config_files.each do |path| cfg_path = File.join(staging_path, path) raise "Config file path #{cfg_path} does not exist" unless File.exist?(cfg_path) Find.find(cfg_path) do |p| allconfigs << p.gsub("#{staging_path}/", '') if File.file? p end end allconfigs.sort!.uniq! self.config_files = allconfigs.map { |x| File.join("/", x) } # add init script if present (attributes[:rpm_init_list] or []).each do |init| name = File.basename(init, ".init") dest_init = File.join(staging_path, "etc/init.d/#{name}") FileUtils.mkdir_p(File.dirname(dest_init)) FileUtils.cp init, dest_init File.chmod(0755, dest_init) end (attributes[:rpm_rpmbuild_define] or []).each do |define| args += ["--define", define] end # copy all files from staging to BUILD dir # [#1538] Be sure to preserve the original timestamps. Find.find(staging_path) do |path| src = path.gsub(/^#{staging_path}/, '') dst = File.join(build_path, build_sub_dir, src) copy_entry(path, dst, preserve=true) end rpmspec = template("rpm.erb").result(binding) specfile = File.join(build_path("SPECS"), "#{name}.spec") File.write(specfile, rpmspec) edit_file(specfile) if attributes[:edit?] args << specfile logger.info("Running rpmbuild", :args => args) safesystem(*args) ::Dir["#{build_path}/RPMS/**/*.rpm"].each do |rpmpath| # This should only output one rpm, should we verify this? FileUtils.cp(rpmpath, output_path) end end |
#payload_compression ⇒ Object
def to_s
613 614 615 616 617 618 619 620 |
# File 'lib/fpm/package/rpm.rb', line 613 def payload_compression if attributes[:rpm_compression] == 'none' # when 'none' ignore any compression level and return w0.gzdio return COMPRESSION_MAP[attributes[:rpm_compression]] else return "w#{attributes[:rpm_compression_level]}" + COMPRESSION_MAP[attributes[:rpm_compression]] end end |
#prefix ⇒ Object
def output
556 557 558 559 560 561 562 |
# File 'lib/fpm/package/rpm.rb', line 556 def prefix if attributes[:prefix] and attributes[:prefix] != '/' return attributes[:prefix].chomp('/') else return "/" end end |
#prefixed_path(path) ⇒ Object
def input
428 429 430 |
# File 'lib/fpm/package/rpm.rb', line 428 def prefixed_path(path) Pathname.new(path).absolute?() ? path : File.join(self.prefix, path) end |
#summary ⇒ Object
def build_sub_dir
569 570 571 572 573 574 575 |
# File 'lib/fpm/package/rpm.rb', line 569 def summary if !attributes[:rpm_summary] return @description.split("\n").find { |line| !line.strip.empty? } || "_" end return attributes[:rpm_summary] end |
#to_s(format = nil) ⇒ Object
602 603 604 605 606 607 608 609 610 611 |
# File 'lib/fpm/package/rpm.rb', line 602 def to_s(format=nil) if format.nil? format = if attributes[:rpm_dist] "NAME-VERSION-ITERATION.DIST.ARCH.EXTENSION" else "NAME-VERSION-ITERATION.ARCH.EXTENSION" end end return super(format.gsub("DIST", to_s_dist)) end |
#version ⇒ Object
def summary
577 578 579 580 581 582 583 584 585 |
# File 'lib/fpm/package/rpm.rb', line 577 def version if @version.kind_of?(String) and @version.include?("-") logger.warn("Package version '#{@version}' includes dashes, converting" \ " to underscores") @version = @version.gsub(/-/, "_") end return @version end |