tpkg 2.2.4 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +7 -7
- data/bin/cpan2tpkg +37 -42
- data/bin/gem2tpkg +60 -52
- data/bin/tpkg +636 -205
- data/bin/tpkg_xml_to_yml +5 -3
- data/lib/tpkg.rb +229 -75
- data/lib/tpkg/deployer.rb +0 -1
- data/lib/tpkg/metadata.rb +0 -1
- data/lib/tpkg/thread_pool.rb +0 -1
- data/lib/tpkg/versiontype.rb +0 -1
- metadata +5 -16
data/Rakefile
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
require 'rake/gempackagetask'
|
2
2
|
spec = Gem::Specification.new do |s|
|
3
|
-
s.name
|
4
|
-
s.summary
|
5
|
-
s.
|
6
|
-
s.add_dependency('net-ssh')
|
7
|
-
s.add_dependency('kwalify')
|
8
|
-
s.version = '2.2.4'
|
3
|
+
s.name = 'tpkg'
|
4
|
+
s.summary = 'tpkg Application Packaging & Deployment'
|
5
|
+
s.version = '2.3.0'
|
9
6
|
s.authors = ['Darren Dao', 'Jason Heiss']
|
10
7
|
s.email = 'tpkg-users@lists.sourceforge.net'
|
11
8
|
s.homepage = 'http://tpkg.sourceforge.net'
|
12
9
|
s.rubyforge_project = 'tpkg'
|
13
10
|
s.platform = Gem::Platform::RUBY
|
14
11
|
s.required_ruby_version = '>=1.8'
|
15
|
-
s.files
|
12
|
+
s.files = Dir['**/**']
|
16
13
|
s.executables = [ 'tpkg', 'cpan2tpkg', 'gem2tpkg', 'tpkg_xml_to_yml' ]
|
14
|
+
s.add_dependency('facter')
|
15
|
+
s.add_dependency('net-ssh')
|
16
|
+
s.add_dependency('kwalify')
|
17
17
|
end
|
18
18
|
Rake::GemPackageTask.new(spec).define
|
19
19
|
|
data/bin/cpan2tpkg
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
#!/opt/tpkg/bin/perl
|
2
2
|
##############################################################################
|
3
3
|
# tpkg package management system
|
4
|
-
# Copyright 2009, 2010, 2011 AT&T Interactive
|
5
4
|
# License: MIT (http://www.opensource.org/licenses/mit-license.php)
|
6
5
|
##############################################################################
|
7
6
|
|
@@ -78,7 +77,7 @@ while (scalar @extradepsopts)
|
|
78
77
|
{
|
79
78
|
my $dep = shift @extradepsopts;
|
80
79
|
# These are optional, shift will return undef if they aren't present
|
81
|
-
# and we'll handle that properly when creating tpkg.
|
80
|
+
# and we'll handle that properly when creating tpkg.yml
|
82
81
|
my $depminver = shift @extradepsopts;
|
83
82
|
my $depmaxver = shift @extradepsopts;
|
84
83
|
$extradeps{$dep} = {};
|
@@ -90,7 +89,7 @@ while (scalar @nativedepsopts)
|
|
90
89
|
{
|
91
90
|
my $dep = shift @nativedepsopts;
|
92
91
|
# These are optional, shift will return undef if they aren't present
|
93
|
-
# and we'll handle that properly when creating tpkg.
|
92
|
+
# and we'll handle that properly when creating tpkg.yml
|
94
93
|
my $depminver = shift @nativedepsopts;
|
95
94
|
my $depmaxver = shift @nativedepsopts;
|
96
95
|
$nativedeps{$dep} = {};
|
@@ -315,23 +314,29 @@ MODULE: foreach my $name ($extinst->modules)
|
|
315
314
|
$packlistfile =~ s/^$workdir//;
|
316
315
|
# Make directory tree in $tpkgdir
|
317
316
|
mkpath("$tpkgdir/root/" . dirname($packlistfile));
|
317
|
+
|
318
318
|
# Copy file
|
319
|
-
|
319
|
+
my $src = "$workdir/$packlistfile";
|
320
|
+
my $dst = "$tpkgdir/root/$packlistfile";
|
321
|
+
copy($src, $dst);
|
322
|
+
|
323
|
+
# preserve permissions
|
324
|
+
# (avoiding dependency on File::Copy::Recursive::fcopy)
|
325
|
+
my $mode = (stat($src))[2];
|
326
|
+
chmod($mode & 07777, $dst);
|
327
|
+
|
320
328
|
if ($packlistfile =~ quotemeta($Config{archname}))
|
321
329
|
{
|
322
330
|
$nativefile = 1;
|
323
331
|
}
|
324
332
|
}
|
325
|
-
# Create tpkg.
|
326
|
-
open(my $
|
327
|
-
print $
|
328
|
-
print $
|
329
|
-
print $
|
330
|
-
print $
|
331
|
-
print $
|
332
|
-
print $xmlfh " <package_version>$pkgver</package_version>", "\n";
|
333
|
-
print $xmlfh " <description>cpan package for $pkgname</description>", "\n";
|
334
|
-
print $xmlfh ' <maintainer>cpan2tpkg</maintainer>', "\n";
|
333
|
+
# Create tpkg.yml
|
334
|
+
open(my $ymlfh, '>', "$tpkgdir/tpkg.yml") or die;
|
335
|
+
print $ymlfh "name: cpan-perl$majorminor-$pkgname", "\n";
|
336
|
+
print $ymlfh "version: $ver", "\n";
|
337
|
+
print $ymlfh "package_version: $pkgver", "\n";
|
338
|
+
print $ymlfh "description: cpan package for $pkgname", "\n";
|
339
|
+
print $ymlfh 'maintainer: cpan2tpkg', "\n";
|
335
340
|
# If the package has native code then it needs to be flagged as
|
336
341
|
# specific to the OS and architecture
|
337
342
|
if ($nativefile)
|
@@ -360,68 +365,58 @@ MODULE: foreach my $name ($extinst->modules)
|
|
360
365
|
# vice-versa
|
361
366
|
if ($os =~ /RedHat-(.*)/)
|
362
367
|
{
|
363
|
-
$os = $os . ",CentOS-$1";
|
368
|
+
$os = $os . ", CentOS-$1";
|
364
369
|
}
|
365
370
|
elsif ($os =~ /CentOS-(.*)/)
|
366
371
|
{
|
367
|
-
$os = $os . ",RedHat-$1";
|
372
|
+
$os = $os . ", RedHat-$1";
|
368
373
|
}
|
369
|
-
print $
|
370
|
-
print $
|
374
|
+
print $ymlfh "operatingsystem: [$os]", "\n";
|
375
|
+
print $ymlfh "architecture: [$arch]", "\n";
|
371
376
|
}
|
372
377
|
# Insert appropriate dependencies into the package
|
373
|
-
print $
|
378
|
+
print $ymlfh 'dependencies:', "\n";
|
374
379
|
foreach my $dep (keys %deps)
|
375
380
|
{
|
376
|
-
print $
|
377
|
-
print $xmlfh " <name>cpan-perl$majorminor-$dep</name>", "\n";
|
381
|
+
print $ymlfh " - name: cpan-perl$majorminor-$dep", "\n";
|
378
382
|
if ($deps{$dep}{minimum_version})
|
379
383
|
{
|
380
|
-
print $
|
384
|
+
print $ymlfh " minimum_version: $deps{$dep}{minimum_version}", "\n";
|
381
385
|
}
|
382
386
|
if ($deps{$dep}{maximum_version})
|
383
387
|
{
|
384
|
-
print $
|
388
|
+
print $ymlfh " maximum_version: $deps{$dep}{maximum_version}", "\n";
|
385
389
|
}
|
386
|
-
print $xmlfh ' </dependency>', "\n";
|
387
390
|
}
|
388
391
|
foreach my $extradep (keys %extradeps)
|
389
392
|
{
|
390
|
-
print $
|
391
|
-
print $xmlfh " <name>$extradep</name>", "\n";
|
393
|
+
print $ymlfh " - name: $extradep", "\n";
|
392
394
|
if ($extradeps{$extradep}{minimum_version})
|
393
395
|
{
|
394
|
-
print $
|
396
|
+
print $ymlfh " minimum_version: $extradeps{$extradep}{minimum_version}", "\n";
|
395
397
|
}
|
396
398
|
if ($extradeps{$extradep}{maximum_version})
|
397
399
|
{
|
398
|
-
|
400
|
+
print $ymlfh " maximum_version: $extradeps{$extradep}{maximum_version}", "\n";
|
399
401
|
}
|
400
|
-
print $xmlfh ' </dependency>', "\n";
|
401
402
|
}
|
402
403
|
foreach my $nativedep (keys %nativedeps)
|
403
404
|
{
|
404
|
-
print $
|
405
|
-
print $xmlfh " <name>$nativedep</name>", "\n";
|
405
|
+
print $ymlfh " - name: $nativedep", "\n";
|
406
406
|
if ($nativedeps{$nativedep}{minimum_version})
|
407
407
|
{
|
408
|
-
print $
|
408
|
+
print $ymlfh " minimum_version: $nativedeps{$nativedep}{minimum_version}", "\n";
|
409
409
|
}
|
410
410
|
if ($nativedeps{$nativedep}{maximum_version})
|
411
411
|
{
|
412
|
-
print $
|
412
|
+
print $ymlfh " maximum_version: $nativedeps{$nativedep}{maximum_version}", "\n";
|
413
413
|
}
|
414
|
-
print $
|
415
|
-
print $xmlfh ' </dependency>', "\n";
|
414
|
+
print $ymlfh ' native: true', "\n";
|
416
415
|
}
|
417
416
|
# Insert an appropriate dependency on Perl itself
|
418
|
-
print $
|
419
|
-
print $
|
420
|
-
print $
|
421
|
-
print $xmlfh " <maximum_version>$majordotminor.9999</maximum_version>", "\n";
|
422
|
-
print $xmlfh ' </dependency>', "\n";
|
423
|
-
print $xmlfh ' </dependencies>', "\n";
|
424
|
-
print $xmlfh '</tpkg>', "\n";
|
417
|
+
print $ymlfh ' - name: perl', "\n";
|
418
|
+
print $ymlfh ' minimum_version: ', sprintf("%vd", $^V), "\n";
|
419
|
+
print $ymlfh " maximum_version: $majordotminor.9999", "\n";
|
425
420
|
# Build package
|
426
421
|
system("tpkg --make $tpkgdir");
|
427
422
|
}
|
data/bin/gem2tpkg
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
#!/usr/bin/ruby -w
|
2
2
|
##############################################################################
|
3
3
|
# tpkg package management system
|
4
|
-
# Copyright 2009, 2010, 2011 AT&T Interactive
|
5
4
|
# License: MIT (http://www.opensource.org/licenses/mit-license.php)
|
6
5
|
##############################################################################
|
7
6
|
|
8
|
-
#
|
9
|
-
|
7
|
+
# When run from the source repository or from an unpacked copy of the
|
8
|
+
# distribution we want to find the local library, even if there's a copy
|
9
|
+
# installed on the system. The installed copy is likely older, and the API
|
10
|
+
# may be out of sync with this executable.
|
11
|
+
$:.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
|
10
12
|
|
11
13
|
require 'fileutils' # FileUtils.cp, rm, etc.
|
12
14
|
require 'tempfile' # Tempfile
|
@@ -56,7 +58,7 @@ opts.on('--extra-deps', '=EXTRADEPS', Array, 'Extra dependencies to add to the p
|
|
56
58
|
while !opt.empty?
|
57
59
|
dep = opt.shift
|
58
60
|
# These are optional, shift will return nil if they aren't present
|
59
|
-
# and we'll handle that properly when creating tpkg.
|
61
|
+
# and we'll handle that properly when creating tpkg.yml
|
60
62
|
depminver = opt.shift
|
61
63
|
depmaxver = opt.shift
|
62
64
|
@extradeps[dep] = {}
|
@@ -69,7 +71,7 @@ opts.on('--native-deps', '=NATIVEDEPS', Array, 'Native dependencies to add to th
|
|
69
71
|
while !opt.empty?
|
70
72
|
dep = opt.shift
|
71
73
|
# These are optional, shift will return nil if they aren't present
|
72
|
-
# and we'll handle that properly when creating tpkg.
|
74
|
+
# and we'll handle that properly when creating tpkg.yml
|
73
75
|
depminver = opt.shift
|
74
76
|
depmaxver = opt.shift
|
75
77
|
@nativedeps[dep] = {}
|
@@ -273,7 +275,7 @@ def package(gem)
|
|
273
275
|
operator.sub!(/^\(/, '')
|
274
276
|
depver.sub!(/\)$/, '')
|
275
277
|
depver.sub!(/,$/, '')
|
276
|
-
# Save the dependency info for tpkg.
|
278
|
+
# Save the dependency info for tpkg.yml
|
277
279
|
# http://rubygems.org/read/chapter/16
|
278
280
|
deps[depgem] = {}
|
279
281
|
case operator
|
@@ -393,77 +395,83 @@ def package(gem)
|
|
393
395
|
pkgnamesuffix = '-' + @gemdep.first.sub(/\W/, '')
|
394
396
|
end
|
395
397
|
|
396
|
-
#
|
398
|
+
# Determine if we're packaging a gem the user requested or a dependency gem.
|
399
|
+
# If we're packaging a dependency gem we don't want to add @extradeps or
|
400
|
+
# @nativedeps. Say you run gem2tpkg for gem foo. You specify some extra
|
401
|
+
# dependencies with --extra-deps and/or --native-deps. Gem foo depends on
|
402
|
+
# gems bar and baz. The generated tpkgs for bar and baz will include those
|
403
|
+
# extra dependencies. I don't think they should. Bar and baz may be very
|
404
|
+
# general gems with no close relationship to foo. It seems to me if the user
|
405
|
+
# needs bar and baz to have the same extra dependencies they should gem2tpkg
|
406
|
+
# those separately. We shouldn't assume everything in the dependency chain
|
407
|
+
# needs those same dependencies.
|
408
|
+
packaging_requested_gem = false
|
409
|
+
if @gems.include?(gem)
|
410
|
+
packaging_requested_gem = true
|
411
|
+
end
|
412
|
+
|
413
|
+
# Add tpkg.yml
|
397
414
|
os = nil
|
398
415
|
arch = nil
|
399
|
-
File.open(File.join(pkgdir, 'tpkg.
|
400
|
-
|
401
|
-
file.puts
|
402
|
-
file.puts
|
403
|
-
file.puts "
|
404
|
-
file.puts "
|
405
|
-
file.puts
|
406
|
-
file.puts " <description>Ruby gem for #{gem}</description>"
|
407
|
-
file.puts ' <maintainer>gem2tpkg</maintainer>'
|
416
|
+
File.open(File.join(pkgdir, 'tpkg.yml'), 'w') do |file|
|
417
|
+
|
418
|
+
file.puts "name: gem-#{gem}#{pkgnamesuffix}"
|
419
|
+
file.puts "version: #{gemspec.version.to_s}"
|
420
|
+
file.puts "package_version: #{@pkgver}"
|
421
|
+
file.puts "description: Ruby gem for #{gem}"
|
422
|
+
file.puts 'maintainer: gem2tpkg'
|
408
423
|
# If the gemspec lists any extensions then the package has native
|
409
424
|
# code and needs to be flagged as specific to the OS and architecture
|
410
425
|
if gemspec.extensions && !gemspec.extensions.empty?
|
411
426
|
os = Tpkg::get_os
|
412
427
|
if os =~ /RedHat-(.*)/
|
413
|
-
os = os + ",CentOS-#{$1}"
|
428
|
+
os = os + ", CentOS-#{$1}"
|
414
429
|
elsif os =~ /CentOS-(.*)/
|
415
|
-
os = os + ",RedHat-#{$1}"
|
430
|
+
os = os + ", RedHat-#{$1}"
|
416
431
|
end
|
417
432
|
arch = Facter['hardwaremodel'].value
|
418
|
-
file.puts "
|
419
|
-
file.puts "
|
433
|
+
file.puts "operatingsystem: [#{os}]"
|
434
|
+
file.puts "architecture: [#{arch}]"
|
420
435
|
end
|
421
436
|
if !deps.empty? ||
|
422
|
-
!@extradeps.empty?
|
437
|
+
(!@extradeps.empty? && packaging_requested_gem) ||
|
438
|
+
(!@nativedeps.empty? && packaging_requested_gem) ||
|
423
439
|
!@gemdep.empty?
|
424
|
-
file.puts '
|
440
|
+
file.puts 'dependencies:'
|
425
441
|
deps.each do |depgem, depvers|
|
426
|
-
file.puts
|
427
|
-
file.puts " <name>gem-#{depgem}#{pkgnamesuffix}</name>"
|
428
|
-
if depvers[:minimum_version]
|
429
|
-
file.puts " <minimum_version>#{depvers[:minimum_version]}</minimum_version>"
|
430
|
-
end
|
431
|
-
if depvers[:maximum_version]
|
432
|
-
file.puts " <maximum_version>#{depvers[:maximum_version]}</maximum_version>"
|
433
|
-
end
|
434
|
-
file.puts ' </dependency>'
|
435
|
-
end
|
436
|
-
@extradeps.each do |extradep, depvers|
|
437
|
-
file.puts ' <dependency>'
|
438
|
-
file.puts " <name>#{extradep}</name>"
|
442
|
+
file.puts " - name: gem-#{depgem}#{pkgnamesuffix}"
|
439
443
|
if depvers[:minimum_version]
|
440
|
-
file.puts "
|
444
|
+
file.puts " minimum_version: #{depvers[:minimum_version]}"
|
441
445
|
end
|
442
446
|
if depvers[:maximum_version]
|
443
|
-
file.puts "
|
447
|
+
file.puts " maximum_version: #{depvers[:maximum_version]}"
|
444
448
|
end
|
445
|
-
file.puts ' </dependency>'
|
446
449
|
end
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
450
|
+
if packaging_requested_gem
|
451
|
+
@extradeps.each do |extradep, depvers|
|
452
|
+
file.puts " - name: #{extradep}"
|
453
|
+
if depvers[:minimum_version]
|
454
|
+
file.puts " minimum_version: #{depvers[:minimum_version]}"
|
455
|
+
end
|
456
|
+
if depvers[:maximum_version]
|
457
|
+
file.puts " maximum_version: #{depvers[:maximum_version]}"
|
458
|
+
end
|
452
459
|
end
|
453
|
-
|
454
|
-
file.puts "
|
460
|
+
@nativedeps.each do |nativedep, depvers|
|
461
|
+
file.puts " - name: #{nativedep}"
|
462
|
+
if depvers[:minimum_version]
|
463
|
+
file.puts " minimum_version: #{depvers[:minimum_version]}"
|
464
|
+
end
|
465
|
+
if depvers[:maximum_version]
|
466
|
+
file.puts " maximum_version: #{depvers[:maximum_version]}"
|
467
|
+
end
|
468
|
+
file.puts ' native: true'
|
455
469
|
end
|
456
|
-
file.puts ' <native/>'
|
457
|
-
file.puts ' </dependency>'
|
458
470
|
end
|
459
471
|
@gemdep.each do |gemdep|
|
460
|
-
file.puts
|
461
|
-
file.puts " <name>#{gemdep}</name>"
|
462
|
-
file.puts ' </dependency>'
|
472
|
+
file.puts " - name: #{gemdep}"
|
463
473
|
end
|
464
|
-
file.puts ' </dependencies>'
|
465
474
|
end
|
466
|
-
file.puts '</tpkg>'
|
467
475
|
end
|
468
476
|
|
469
477
|
# Make package
|
data/bin/tpkg
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
#!/usr/bin/ruby -w
|
2
2
|
##############################################################################
|
3
3
|
# tpkg package management system
|
4
|
-
# Copyright 2009, 2010, 2011 AT&T Interactive
|
5
4
|
# License: MIT (http://www.opensource.org/licenses/mit-license.php)
|
6
5
|
##############################################################################
|
7
6
|
|
8
|
-
#
|
9
|
-
|
7
|
+
# When run from the source repository or from an unpacked copy of the
|
8
|
+
# distribution we want to find the local library, even if there's a copy
|
9
|
+
# installed on the system. The installed copy is likely older, and the API
|
10
|
+
# may be out of sync with this executable.
|
11
|
+
$:.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
|
10
12
|
|
11
13
|
require 'optparse'
|
12
14
|
require 'tpkg'
|
@@ -20,15 +22,23 @@ require 'tpkg'
|
|
20
22
|
@debug = false
|
21
23
|
@prompt = true
|
22
24
|
@quiet = false
|
23
|
-
@sudo =
|
24
|
-
|
25
|
+
@sudo = nil
|
26
|
+
# Neither of the common Windows environments for running Ruby have
|
27
|
+
# sudo, so turn it off by default on those platforms
|
28
|
+
if RUBY_PLATFORM == 'i386-mingw32' || RUBY_PLATFORM == 'i386-cygwin'
|
29
|
+
@sudo = false
|
30
|
+
else
|
31
|
+
@sudo = true
|
32
|
+
end
|
25
33
|
@force = false
|
26
34
|
@deploy = false
|
27
35
|
@deploy_params = ARGV # hold parameters for how to invoke tpkg on the machines we're deploying to
|
28
36
|
@deploy_options = {} # options for how to run the deployer
|
29
|
-
@servers =
|
37
|
+
@servers = []
|
38
|
+
@groups = nil
|
30
39
|
@worker_count = 10
|
31
40
|
@rerun_with_sudo = false
|
41
|
+
@sources = []
|
32
42
|
@tpkg_options = {} # options for instantiating Tpkg object
|
33
43
|
@init_options = {} # options for how to run init scripts
|
34
44
|
@other_options = {}
|
@@ -37,7 +47,7 @@ require 'tpkg'
|
|
37
47
|
|
38
48
|
def rerun_with_sudo_if_necessary
|
39
49
|
if Process.euid != 0 && @sudo
|
40
|
-
warn "Executing with sudo"
|
50
|
+
warn "Executing with sudo" if !@quiet
|
41
51
|
# Depending on how sudo is configured it might remove TPKG_HOME from the
|
42
52
|
# environment. As such we set the base as a command line option to ensure
|
43
53
|
# it survives the sudo process.
|
@@ -49,21 +59,53 @@ def rerun_with_sudo_if_necessary
|
|
49
59
|
end
|
50
60
|
end
|
51
61
|
|
62
|
+
# This method can only be safely called after command line option parsing is
|
63
|
+
# complete
|
64
|
+
@config_file_settings = nil
|
65
|
+
def parse_config_files
|
66
|
+
if @config_file_settings
|
67
|
+
return @config_file_settings
|
68
|
+
end
|
69
|
+
|
70
|
+
# FIXME: Move config file parsing to tpkg.rb
|
71
|
+
# http://sourceforge.net/apps/trac/tpkg/ticket/28
|
72
|
+
fsroot = @tpkg_options[:file_system_root] ? @tpkg_options[:file_system_root] : ''
|
73
|
+
settings = {:sources => []}
|
74
|
+
[File.join(fsroot, Tpkg::DEFAULT_CONFIGDIR, 'tpkg.conf'),
|
75
|
+
File.join(fsroot, ENV['HOME'], ".tpkg.conf")].each do |configfile|
|
76
|
+
if File.exist?(configfile)
|
77
|
+
IO.foreach(configfile) do |line|
|
78
|
+
line.chomp!
|
79
|
+
next if (line =~ /^\s*$/); # Skip blank lines
|
80
|
+
next if (line =~ /^\s*#/); # Skip comments
|
81
|
+
line.strip! # Remove leading/trailing whitespace
|
82
|
+
key, value = line.split(/\s*=\s*/, 2)
|
83
|
+
if key == 'base'
|
84
|
+
settings[:base] = value
|
85
|
+
puts "Loaded base #{value} from #{configfile}" if @debug
|
86
|
+
elsif key == 'source'
|
87
|
+
settings[:sources] << value
|
88
|
+
puts "Loaded source #{value} from #{configfile}" if @debug
|
89
|
+
elsif key == 'report_server'
|
90
|
+
settings[:report_server] = value
|
91
|
+
puts "Loaded report server #{value} from #{configfile}" if @debug
|
92
|
+
elsif key == 'host_group_script'
|
93
|
+
settings[:host_group_script] = value
|
94
|
+
puts "Loaded host group script #{value} from #{configfile}" if @debug
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
@config_file_settings = settings
|
101
|
+
end
|
102
|
+
|
52
103
|
opts = OptionParser.new(nil, 24, ' ')
|
53
104
|
opts.banner = 'Usage: tpkg [options]'
|
54
|
-
opts.on('--servers', '-s', '=SERVERS', Array, 'Servers to apply the actions to') do |opt|
|
55
|
-
@servers = opt
|
56
|
-
@deploy = true
|
57
|
-
@deploy_params = @deploy_params - ['--servers', '-s', @servers.join(","), "--servers=#{@servers.join(',')}"]
|
58
|
-
end
|
59
105
|
opts.on('--make', '-m', '=DIRECTORY', 'Make a package out of the contents of the directory') do |opt|
|
60
106
|
@action = :make
|
61
107
|
@action_value = opt
|
62
108
|
end
|
63
|
-
opts.on('--extract', '-x', '=DIRECTORY', 'Extract the metadata for a directory of packages') do |opt|
|
64
|
-
@action = :extract
|
65
|
-
@action_value = opt
|
66
|
-
end
|
67
109
|
installexample = " --install pkgname=version=package_version\n (Example: tpkg --install hive=2.1) Will install hive version 2.1"
|
68
110
|
opts.on('--install', '-i', '=PACKAGES', "Install one or more packages\n#{installexample}", Array) do |opt|
|
69
111
|
@rerun_with_sudo = true
|
@@ -81,6 +123,27 @@ opts.on('--downgrade', '=PACKAGES', 'Downgrade one or more packages', Array) do
|
|
81
123
|
@action = :upgrade
|
82
124
|
@action_value = opt
|
83
125
|
end
|
126
|
+
opts.on('--servers', '-s', '=SERVERS', Array, 'Servers on which to apply actions, defaults to local') do |opt|
|
127
|
+
@servers.concat(opt)
|
128
|
+
@deploy = true
|
129
|
+
# FIXME: this won't remove options that the user specified as an
|
130
|
+
# abbreviation. I.e. if the option is --servers and the user specified
|
131
|
+
# --serv (which OptionParser will accept as long as it is unambiguous) this
|
132
|
+
# won't detect and remove it.
|
133
|
+
@deploy_params = @deploy_params - ['--servers', '-s', @servers.join(","), "--servers=#{@servers.join(',')}"]
|
134
|
+
end
|
135
|
+
opts.on('--groups', '-g', '=GROUP', Array, 'Group of server on which to apply actions') do |opt|
|
136
|
+
# We'll finish processing this later. To expand the groups we need the name
|
137
|
+
# of the host_group_script from the config file, but we can't safely call
|
138
|
+
# parse_config_files until we're done processing command line options.
|
139
|
+
@groups = opt
|
140
|
+
@deploy = true
|
141
|
+
# FIXME: this won't remove options that the user specified as an
|
142
|
+
# abbreviation. I.e. if the option is --servers and the user specified
|
143
|
+
# --serv (which OptionParser will accept as long as it is unambiguous) this
|
144
|
+
# won't detect and remove it.
|
145
|
+
@deploy_params = @deploy_params - ['--groups', '-g', @groups.join(","), "--servers=#{@groups.join(',')}"]
|
146
|
+
end
|
84
147
|
opts.on('--ua', 'Upgrade all packages') do |opt|
|
85
148
|
@rerun_with_sudo = true
|
86
149
|
@action = :upgrade
|
@@ -174,7 +237,7 @@ opts.on('--init-cmd', '=CMD', 'Invoke specified init script command') do |opt|
|
|
174
237
|
@rerun_with_sudo = true
|
175
238
|
@init_options[:cmd] = opt
|
176
239
|
end
|
177
|
-
opts.on('--query', '-q', '=NAMES', '
|
240
|
+
opts.on('--query', '-q', '=NAMES', 'Check if a package is installed', Array) do |opt|
|
178
241
|
# People mistype -qa instead of --qa frequently
|
179
242
|
if opt == ['a']
|
180
243
|
warn "NOTE: tpkg -qa queries for a pkg named 'a', you probably want --qa for all pkgs"
|
@@ -182,49 +245,67 @@ opts.on('--query', '-q', '=NAMES', 'List installed packages', Array) do |opt|
|
|
182
245
|
@action = :query_installed
|
183
246
|
@action_value = opt
|
184
247
|
end
|
248
|
+
# --qv is deprecated
|
249
|
+
opts.on('--qs', '--qv', '=NAME', 'Check if a package is available on server', Array) do |opt|
|
250
|
+
@action = :query_available
|
251
|
+
@action_value = opt
|
252
|
+
end
|
185
253
|
opts.on('--qa', 'List all installed packages') do |opt|
|
186
254
|
@action = :query_installed
|
187
255
|
end
|
188
|
-
|
256
|
+
# --qva is deprecated
|
257
|
+
opts.on('--qas', '--qva', 'List all packages on server') do |opt|
|
258
|
+
@action = :query_available
|
259
|
+
end
|
260
|
+
opts.on('--qi', '=NAME', 'Display the info for a package') do |opt|
|
189
261
|
@action = :query_info
|
190
262
|
@action_value = opt
|
191
263
|
end
|
192
|
-
opts.on('--
|
193
|
-
@action = :
|
264
|
+
opts.on('--qis', '=NAME', 'Display the info for a package on the server') do |opt|
|
265
|
+
@action = :query_info_available
|
194
266
|
@action_value = opt
|
195
267
|
end
|
196
|
-
opts.on('--
|
197
|
-
@action = :
|
268
|
+
opts.on('--ql', '=NAME', 'List the files in a package') do |opt|
|
269
|
+
@action = :query_list_files
|
198
270
|
@action_value = opt
|
199
271
|
end
|
200
|
-
opts.on('--
|
201
|
-
@action = :
|
272
|
+
opts.on('--qls', '=NAME', 'List the files in a package on the server') do |opt|
|
273
|
+
@action = :query_list_files_available
|
202
274
|
@action_value = opt
|
203
275
|
end
|
204
|
-
opts.on('--
|
205
|
-
@action = :
|
276
|
+
opts.on('--qf', '=FILE', 'List the package that owns a file') do |opt|
|
277
|
+
@action = :query_who_owns_file
|
278
|
+
@action_value = opt
|
206
279
|
end
|
207
280
|
opts.on('--qr', '=NAME', 'List installed packages that require package') do |opt|
|
208
281
|
@action = :query_requires
|
209
282
|
@action_value = opt
|
210
283
|
end
|
211
|
-
opts.on('--qd', '=NAME', 'List the packages
|
284
|
+
opts.on('--qd', '=NAME', 'List the packages on which the given package depends') do |opt|
|
212
285
|
@action = :query_depends
|
213
286
|
@action_value = opt
|
214
287
|
end
|
215
|
-
opts.on('--
|
216
|
-
@action = :
|
288
|
+
opts.on('--qds', '=NAME', 'List pkgs on which given package on server depends') do |opt|
|
289
|
+
@action = :query_depends_available
|
217
290
|
@action_value = opt
|
218
291
|
end
|
219
292
|
|
220
293
|
opts.on('--dw', '=INTEGER', 'Number of workers for deploying') do |opt|
|
221
294
|
@worker_count = opt.to_i
|
295
|
+
# FIXME: this won't remove options that the user specified as an
|
296
|
+
# abbreviation. I.e. if the option is --servers and the user specified
|
297
|
+
# --serv (which OptionParser will accept as long as it is unambiguous) this
|
298
|
+
# won't detect and remove it.
|
222
299
|
@deploy_params = @deploy_params - ['--dw', @worker_count, "--dw=#{opt}"]
|
223
300
|
end
|
224
|
-
opts.on('--qX', '=FILENAME', 'Display
|
301
|
+
opts.on('--qX', '=FILENAME', 'Display raw metadata (tpkg.yml) of the given package') do |opt|
|
225
302
|
@action = :query_tpkg_metadata
|
226
303
|
@action_value = opt
|
227
304
|
end
|
305
|
+
opts.on('--qXs', '=FILENAME', 'Display raw metadata of given package on the server') do |opt|
|
306
|
+
@action = :query_tpkg_metadata_available
|
307
|
+
@action_value = opt
|
308
|
+
end
|
228
309
|
opts.on('--history', 'Display package installation history') do |opt|
|
229
310
|
@action = :query_history
|
230
311
|
end
|
@@ -237,8 +318,12 @@ end
|
|
237
318
|
opts.on('--base', '=BASE', 'Base directory for tpkg operations') do |opt|
|
238
319
|
@tpkg_options[:base] = opt
|
239
320
|
end
|
321
|
+
opts.on('--extract', '-x', '=DIRECTORY', 'Extract the metadata for a directory of packages') do |opt|
|
322
|
+
@action = :extract
|
323
|
+
@action_value = opt
|
324
|
+
end
|
240
325
|
opts.on('--source', '=NAME', 'Sources where packages are located', Array) do |opt|
|
241
|
-
@
|
326
|
+
@sources = opt
|
242
327
|
end
|
243
328
|
opts.on('--download', '=PACKAGES', 'Download one or more packages', Array) do |opt|
|
244
329
|
@action = :download
|
@@ -255,7 +340,7 @@ opts.on('--no-sudo', 'No calls to sudo for operations that might need root') do
|
|
255
340
|
@sudo = opt
|
256
341
|
end
|
257
342
|
opts.on('--lock-force', 'Force the removal of an existing lockfile') do |opt|
|
258
|
-
@lockforce = opt
|
343
|
+
@tpkg_options[:lockforce] = opt
|
259
344
|
end
|
260
345
|
opts.on('--force-replace', 'Replace conflicting pkgs with the new one(s)') do |opt|
|
261
346
|
@other_options[:force_replace] = opt
|
@@ -263,20 +348,38 @@ end
|
|
263
348
|
opts.on('--force', 'Force the execution of a given task') do |opt|
|
264
349
|
@force = opt
|
265
350
|
end
|
266
|
-
opts.on('-o', '--out', '=DIR', 'Output directory for the
|
351
|
+
opts.on('-o', '--out', '=DIR', 'Output directory for the --make option') do |opt|
|
267
352
|
@other_options[:out] = opt
|
268
353
|
end
|
354
|
+
opts.on('--skip-remove-stop', 'Do not run init script stop on package removal') do |opt|
|
355
|
+
@other_options[:skip_remove_stop] = opt
|
356
|
+
end
|
269
357
|
opts.on('--use-ssh-key [FILE]', 'Use ssh key for deploying instead of password') do |opt|
|
270
358
|
@deploy_options["use-ssh-key"] = true
|
271
359
|
@deploy_options["ssh-key"] = opt
|
360
|
+
# FIXME: this won't remove options that the user specified as an
|
361
|
+
# abbreviation. I.e. if the option is --servers and the user specified
|
362
|
+
# --serv (which OptionParser will accept as long as it is unambiguous) this
|
363
|
+
# won't detect and remove it.
|
272
364
|
@deploy_params = @deploy_params - ['--use-ssh-key', opt, "--use-ssh-key=#{opt}"]
|
273
365
|
end
|
274
366
|
opts.on('--deploy-as', '=USERNAME', 'What username to use for deploying to remote server') do |opt|
|
275
367
|
@deploy_options["deploy-as"] = opt
|
368
|
+
# FIXME: this won't remove options that the user specified as an
|
369
|
+
# abbreviation. I.e. if the option is --servers and the user specified
|
370
|
+
# --serv (which OptionParser will accept as long as it is unambiguous) this
|
371
|
+
# won't detect and remove it.
|
276
372
|
@deploy_params = @deploy_params - ['--deploy-as']
|
277
373
|
end
|
278
|
-
|
279
|
-
|
374
|
+
acceptable_compress_arguments = ['gzip', 'bz2', 'no']
|
375
|
+
opts.on('--compress [TYPE]',
|
376
|
+
acceptable_compress_arguments,
|
377
|
+
"Compress files when making packages " +
|
378
|
+
"(#{acceptable_compress_arguments.join(',')})") do |opt|
|
379
|
+
# Acceptable
|
380
|
+
if opt == nil # No argument specified by user
|
381
|
+
@compress = true
|
382
|
+
elsif opt == "no"
|
280
383
|
@compress= false
|
281
384
|
else
|
282
385
|
@compress = opt
|
@@ -297,7 +400,14 @@ opts.on_tail("-h", "--help", "Show this message") do
|
|
297
400
|
exit
|
298
401
|
end
|
299
402
|
|
300
|
-
leftovers =
|
403
|
+
leftovers = nil
|
404
|
+
begin
|
405
|
+
leftovers = opts.parse(ARGV)
|
406
|
+
rescue OptionParser::ParseError => e
|
407
|
+
$stderr.puts "Error parsing arguments, try --help"
|
408
|
+
$stderr.puts e.message
|
409
|
+
exit 1
|
410
|
+
end
|
301
411
|
|
302
412
|
# Rerun with sudo if necessary, unless it's a deploy, then
|
303
413
|
# we don't need to run with sudo on this machine. It will run with sudo
|
@@ -312,69 +422,75 @@ if !@action
|
|
312
422
|
exit
|
313
423
|
end
|
314
424
|
|
425
|
+
if @groups
|
426
|
+
settings = parse_config_files
|
427
|
+
if settings[:host_group_script]
|
428
|
+
if !File.executable?(settings[:host_group_script])
|
429
|
+
warn "Warning: host group script #{settings[:host_group_script]} is not executable, execution will likely fail"
|
430
|
+
end
|
431
|
+
servers = []
|
432
|
+
@groups.each do |group|
|
433
|
+
IO.popen(settings[:host_group_script]) do |pipe|
|
434
|
+
pipe.each_line do |line|
|
435
|
+
servers << line.chomp
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
servers.uniq!
|
440
|
+
puts "Expanded groups into #{servers.length} servers" if @debug
|
441
|
+
@servers.concat(servers)
|
442
|
+
else
|
443
|
+
abort "No host_group_script defined in config files, can't expand groups"
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
315
447
|
#
|
316
448
|
# Figure out base directory, sources and other configuration
|
317
449
|
#
|
318
450
|
|
319
|
-
def instantiate_tpkg
|
320
|
-
|
321
|
-
sources = options[:sources] || []
|
322
|
-
report_server = nil
|
451
|
+
def instantiate_tpkg
|
452
|
+
settings = parse_config_files
|
323
453
|
|
324
454
|
# base can come from four possible places. They take precedence in this
|
325
455
|
# order:
|
326
456
|
# - command line option
|
327
457
|
# - TPKG_HOME environment variable
|
328
458
|
# - config file
|
329
|
-
# - Tpkg::DEFAULT_BASE
|
330
|
-
|
459
|
+
# - Tpkg::DEFAULT_BASE constant defined in tpkg.rb
|
331
460
|
if ENV['TPKG_HOME']
|
332
|
-
if
|
333
|
-
base = ENV['TPKG_HOME']
|
461
|
+
if !@tpkg_options[:base]
|
462
|
+
@tpkg_options[:base] = ENV['TPKG_HOME']
|
334
463
|
# Warn the user, as this could potentially be confusing
|
335
464
|
# if they don't realize there's an environment variable set.
|
336
|
-
warn "Using base '#{base}' base from $TPKG_HOME"
|
465
|
+
warn "Using base '#{@tpkg_options[:base]}' base from $TPKG_HOME" if !@quiet
|
337
466
|
else
|
338
|
-
warn "Ignoring TPKG_HOME" if @debug
|
467
|
+
warn "Ignoring $TPKG_HOME" if @debug
|
339
468
|
end
|
340
469
|
end
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
next if (line =~ /^\s*#/); # Skip comments
|
351
|
-
line.strip! # Remove leading/trailing whitespace
|
352
|
-
key, value = line.split(/\s*=\s*/, 2)
|
353
|
-
if key == 'base'
|
354
|
-
if !base
|
355
|
-
# Warn the user, as this could potentially be confusing
|
356
|
-
# if they don't realize there's a config file lying
|
357
|
-
# around
|
358
|
-
base = value
|
359
|
-
warn "Using base #{base} from #{configfile}"
|
360
|
-
else
|
361
|
-
warn "Ignoring 'base' option in #{@configfile}" if @debug
|
362
|
-
end
|
363
|
-
elsif key == 'source'
|
364
|
-
sources << value
|
365
|
-
puts "Loaded source #{value} from #{configfile}" if (@debug)
|
366
|
-
elsif key == 'report_server'
|
367
|
-
report_server = value
|
368
|
-
puts "Loaded report server #{report_server} from #{configfile}" if (@debug)
|
369
|
-
end
|
370
|
-
end
|
470
|
+
if settings[:base]
|
471
|
+
if !@tpkg_options[:base]
|
472
|
+
# Warn the user, as this could potentially be confusing
|
473
|
+
# if they don't realize there's a config file lying
|
474
|
+
# around
|
475
|
+
@tpkg_options[:base] = settings[:base]
|
476
|
+
warn "Using base #{@tpkg_options[:base]} from config file" if !@quiet
|
477
|
+
else
|
478
|
+
warn "Ignoring 'base' option in config file" if @debug
|
371
479
|
end
|
372
480
|
end
|
373
|
-
|
374
|
-
|
375
|
-
base = Tpkg::DEFAULT_BASE
|
481
|
+
if !@tpkg_options[:base]
|
482
|
+
@tpkg_options[:base] = Tpkg::DEFAULT_BASE
|
376
483
|
end
|
377
484
|
|
485
|
+
# Sources can come from the command line and config files. We use the
|
486
|
+
# combined set of sources.
|
487
|
+
@sources.concat(settings[:sources])
|
488
|
+
@tpkg_options[:sources] = @sources
|
489
|
+
|
490
|
+
@tpkg_options[:report_server] = settings[:report_server]
|
491
|
+
@tpkg_options[:sudo] = @sudo
|
492
|
+
@tpkg_options[:force] = @force
|
493
|
+
|
378
494
|
if !@sudo
|
379
495
|
curruid = Process.euid
|
380
496
|
if curruid == 0
|
@@ -383,23 +499,19 @@ def instantiate_tpkg(options = {})
|
|
383
499
|
# modified by other users who properly run --no-sudo as a regular user.
|
384
500
|
raise "--no-sudo cannot be used as 'root' user or via sudo"
|
385
501
|
end
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
502
|
+
fsroot = @tpkg_options[:file_system_root] ? @tpkg_options[:file_system_root] : ''
|
503
|
+
base = File.join(fsroot, @tpkg_options[:base])
|
504
|
+
if File.exist?(base)
|
505
|
+
baseuid = File.stat(base).uid
|
506
|
+
# We want to ensure that all --no-sudo usage within a given base directory
|
507
|
+
# is done under the same account.
|
508
|
+
if baseuid != curruid
|
509
|
+
raise "Base dir #{@tpkg_options[:base]} owned by UID #{baseuid}, not your UID #{curruid}"
|
510
|
+
end
|
391
511
|
end
|
392
512
|
end
|
393
513
|
|
394
|
-
|
395
|
-
# call Tpkg.new(options)
|
396
|
-
tpkg = Tpkg.new(:file_system_root => options[:file_system_root],
|
397
|
-
:base => base,
|
398
|
-
:sources => sources,
|
399
|
-
:report_server => report_server,
|
400
|
-
:lockforce => @lockforce,
|
401
|
-
:force => @force,
|
402
|
-
:sudo => @sudo)
|
514
|
+
tpkg = Tpkg.new(@tpkg_options)
|
403
515
|
end
|
404
516
|
|
405
517
|
passphrase_callback = lambda do | package |
|
@@ -466,25 +578,25 @@ when :make
|
|
466
578
|
when :extract
|
467
579
|
Tpkg::extract_metadata(@action_value)
|
468
580
|
when :install
|
469
|
-
tpkg = instantiate_tpkg
|
581
|
+
tpkg = instantiate_tpkg
|
470
582
|
ret_val = tpkg.install(@action_value, passphrase_callback, @other_options)
|
471
583
|
when :upgrade
|
472
|
-
tpkg = instantiate_tpkg
|
584
|
+
tpkg = instantiate_tpkg
|
473
585
|
ret_val = tpkg.upgrade(@action_value, passphrase_callback, @other_options)
|
474
586
|
when :remove
|
475
|
-
tpkg = instantiate_tpkg
|
587
|
+
tpkg = instantiate_tpkg
|
476
588
|
ret_val = tpkg.remove(@action_value, @other_options)
|
477
589
|
when :download
|
478
|
-
tpkg = instantiate_tpkg
|
590
|
+
tpkg = instantiate_tpkg
|
479
591
|
ret_val = tpkg.download_pkgs(@action_value, @other_options)
|
480
592
|
when :verify
|
481
593
|
result = nil
|
482
594
|
# Verify a given .tpkg file
|
483
|
-
if File.
|
595
|
+
if File.file?(@action_value)
|
484
596
|
Tpkg::verify_package_checksum(@action_value)
|
485
597
|
# Verify an installed pkg
|
486
598
|
else
|
487
|
-
tpkg = instantiate_tpkg
|
599
|
+
tpkg = instantiate_tpkg
|
488
600
|
results = tpkg.verify_file_metadata([@action_value])
|
489
601
|
if results.length == 0
|
490
602
|
puts "No package found"
|
@@ -501,206 +613,525 @@ when :verify
|
|
501
613
|
puts "Package verification failed" unless success
|
502
614
|
end
|
503
615
|
when :execute_init
|
504
|
-
tpkg = instantiate_tpkg
|
616
|
+
tpkg = instantiate_tpkg
|
505
617
|
if @init_options[:cmd].nil?
|
506
618
|
raise "You didn't specify what init command to run"
|
507
619
|
end
|
508
620
|
ret_val = tpkg.execute_init(@init_options)
|
509
621
|
when :query_installed
|
510
|
-
tpkg = instantiate_tpkg
|
511
|
-
queryreq = nil
|
622
|
+
tpkg = instantiate_tpkg
|
512
623
|
matches = []
|
513
624
|
if @action_value
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
625
|
+
# The --query switch is set to accept multiple values (the "Array"
|
626
|
+
# parameter in the opts.on line for --query) so users can do things like
|
627
|
+
# "tpkg -q foo,bar" to check multiple packages at once. As such
|
628
|
+
# @action_value is an Array for this switch.
|
629
|
+
requirements = []
|
630
|
+
packages = {}
|
631
|
+
tpkg.parse_requests(@action_value, requirements, packages,
|
632
|
+
:installed_only => true)
|
633
|
+
if packages.values.all? {|pkg| pkg.empty?}
|
518
634
|
# If the user requested specific packages and we found no matches
|
519
635
|
# then exit with a non-zero value to indicate failure. This allows
|
520
636
|
# command-line syntax like "tpkg -q foo || tpkg -i foo" to ensure
|
521
637
|
# that a package is installed.
|
522
|
-
ret_val = 1
|
523
|
-
|
638
|
+
ret_val = 1
|
639
|
+
$stderr.puts "No packages matching '#{@action_value}' installed" if !@quiet
|
640
|
+
else
|
641
|
+
packages.each do | name, pkgs |
|
642
|
+
matches.concat(pkgs)
|
643
|
+
end
|
524
644
|
end
|
525
645
|
else
|
526
|
-
|
646
|
+
# --qa is implemented by setting @action to :query_installed and
|
647
|
+
# @action_value to nil
|
648
|
+
matches = tpkg.installed_packages_that_meet_requirement
|
649
|
+
if matches.empty?
|
650
|
+
ret_val = 1
|
651
|
+
$stderr.puts "No packages installed" if !@quiet
|
652
|
+
end
|
527
653
|
end
|
528
|
-
|
529
654
|
if !@quiet
|
530
655
|
matches.sort(&Tpkg::SORT_PACKAGES).each do |pkg|
|
531
656
|
puts pkg[:metadata][:filename]
|
532
657
|
end
|
533
658
|
end
|
534
659
|
when :query_info
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
packages.each do | name, pkgs |
|
545
|
-
pkgs.each do | pkg |
|
546
|
-
metadatas << pkg[:metadata]
|
547
|
-
end
|
660
|
+
tpkg = instantiate_tpkg
|
661
|
+
requirements = []
|
662
|
+
packages = {}
|
663
|
+
tpkg.parse_requests([@action_value], requirements, packages,
|
664
|
+
:installed_only => true)
|
665
|
+
metadatas = []
|
666
|
+
packages.each do | name, pkgs |
|
667
|
+
pkgs.each do | pkg |
|
668
|
+
metadatas << pkg[:metadata]
|
548
669
|
end
|
549
670
|
end
|
671
|
+
output_strings = []
|
550
672
|
already_displayed = {}
|
551
673
|
metadatas.each do |metadata|
|
552
674
|
next if already_displayed[metadata[:filename]]
|
553
675
|
already_displayed[metadata[:filename]] = true
|
676
|
+
output_string = ''
|
554
677
|
[:name, :version, :package_version, :operatingsystem, :architecture, :maintainer, :description, :bugreporting].each do |field|
|
555
678
|
metadata[field] = 'any' if field == :operatingsystem && metadata[field].nil?
|
556
679
|
metadata[field] = 'any' if field == :architecture && metadata[field].nil?
|
557
680
|
if metadata[field]
|
558
681
|
if metadata[field].kind_of?(Array)
|
559
|
-
|
682
|
+
output_string << "#{field}: #{metadata[field].join(',')}\n"
|
560
683
|
else
|
561
|
-
|
684
|
+
output_string << "#{field}: #{metadata[field]}\n"
|
562
685
|
end
|
563
686
|
end
|
564
687
|
end
|
688
|
+
if metadata[:dependencies]
|
689
|
+
output_string << "(This package depends on other packages, use --qd to view the dependencies)\n"
|
690
|
+
end
|
691
|
+
# Older versions of tpkg did not insert a tpkg_version field into the
|
692
|
+
# package metadata when building packages
|
565
693
|
tpkg_version = metadata[:tpkg_version] || "< 1.26.1"
|
566
|
-
|
567
|
-
|
568
|
-
|
694
|
+
output_string << "(This package was built with tpkg version #{tpkg_version})\n"
|
695
|
+
output_strings << output_string
|
696
|
+
end
|
697
|
+
print output_strings.join("================================================================================\n")
|
698
|
+
if already_displayed.empty?
|
699
|
+
ret_val = 1
|
700
|
+
# --qi --quiet doesn't seem like a meaningful combination, so I'm not
|
701
|
+
# suppressing this for @quiet
|
702
|
+
$stderr.puts "No packages matching '#{@action_value}' installed"
|
703
|
+
end
|
704
|
+
when :query_info_available
|
705
|
+
tpkg = instantiate_tpkg
|
706
|
+
requirements = []
|
707
|
+
packages = {}
|
708
|
+
tpkg.parse_requests([@action_value], requirements, packages)
|
709
|
+
availpkgs = []
|
710
|
+
packages.each do | name, pkgs |
|
711
|
+
availpkgs.concat(pkgs)
|
712
|
+
end
|
713
|
+
available = availpkgs.select do |pkg|
|
714
|
+
pkg[:source] != :native_installed &&
|
715
|
+
pkg[:source] != :native_available &&
|
716
|
+
pkg[:source] != :currently_installed
|
717
|
+
end
|
718
|
+
if available.empty?
|
719
|
+
ret_val = 1
|
720
|
+
# --qis --quiet doesn't seem like a meaningful combination, so I'm not
|
721
|
+
# suppressing this for @quiet
|
722
|
+
$stderr.puts "No packages matching '#{@action_value}' available"
|
723
|
+
else
|
724
|
+
metadatas = available.collect {|avail| avail[:metadata]}
|
725
|
+
output_strings = []
|
726
|
+
already_displayed = {}
|
727
|
+
metadatas.each do |metadata|
|
728
|
+
next if already_displayed[metadata[:filename]]
|
729
|
+
already_displayed[metadata[:filename]] = true
|
730
|
+
output_string = ''
|
731
|
+
[:name, :version, :package_version, :operatingsystem, :architecture, :maintainer, :description, :bugreporting].each do |field|
|
732
|
+
metadata[field] = 'any' if field == :operatingsystem && metadata[field].nil?
|
733
|
+
metadata[field] = 'any' if field == :architecture && metadata[field].nil?
|
734
|
+
if metadata[field]
|
735
|
+
if metadata[field].kind_of?(Array)
|
736
|
+
output_string << "#{field}: #{metadata[field].join(',')}\n"
|
737
|
+
else
|
738
|
+
output_string << "#{field}: #{metadata[field]}\n"
|
739
|
+
end
|
740
|
+
end
|
741
|
+
end
|
742
|
+
if metadata[:dependencies]
|
743
|
+
output_string << "(This package depends on other packages, use --qd to view the dependencies)\n"
|
744
|
+
end
|
745
|
+
# Older versions of tpkg did not insert a tpkg_version field into the
|
746
|
+
# package metadata when building packages
|
747
|
+
tpkg_version = metadata[:tpkg_version] || "< 1.26.1"
|
748
|
+
output_string << "(This package was built with tpkg version #{tpkg_version})\n"
|
749
|
+
output_strings << output_string
|
569
750
|
end
|
570
|
-
|
751
|
+
print output_strings.join("================================================================================\n")
|
571
752
|
end
|
572
753
|
when :query_list_files
|
573
|
-
tpkg = instantiate_tpkg
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
754
|
+
tpkg = instantiate_tpkg
|
755
|
+
requirements = []
|
756
|
+
packages = {}
|
757
|
+
tpkg.parse_requests([@action_value], requirements, packages,
|
758
|
+
:installed_only => true)
|
759
|
+
if packages.values.all? {|pkg| pkg.empty?}
|
760
|
+
ret_val = 1
|
761
|
+
# --ql --quiet doesn't seem like a meaningful combination, so I'm not
|
762
|
+
# suppressing this for @quiet
|
763
|
+
$stderr.puts "No packages matching '#{@action_value}' installed"
|
580
764
|
else
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
765
|
+
# For this switch we need separate handling for installed and uninstalled
|
766
|
+
# packages. For installed packages we know where their relocatable files
|
767
|
+
# ended up and can give the user regular paths. For uninstalled packaages
|
768
|
+
# we don't know what base will be used when the package is installed, so
|
769
|
+
# we need to indicate to the user that their are relocatable files and
|
770
|
+
# just display their path relative to the eventual base directory.
|
771
|
+
ci_pkgfiles = []
|
772
|
+
packages.each do | name, pkgs |
|
773
|
+
pkgs.each do | pkg |
|
774
|
+
if pkg[:source] == :currently_installed
|
775
|
+
ci_pkgfiles << pkg[:metadata][:filename]
|
776
|
+
else
|
777
|
+
puts "#{pkg[:source]}:"
|
778
|
+
fip = Tpkg.files_in_package(pkg[:source])
|
779
|
+
fip[:root].each { |file| puts file }
|
780
|
+
fip[:reloc].each { |file| puts '<relocatable>/' + file }
|
781
|
+
end
|
782
|
+
end
|
594
783
|
end
|
595
|
-
|
596
|
-
files = tpkg.files_for_installed_packages(pkgfiles)
|
784
|
+
files = tpkg.files_for_installed_packages(ci_pkgfiles)
|
597
785
|
files.each do |pkgfile, fip|
|
598
786
|
puts "#{pkgfile}:"
|
599
787
|
fip[:normalized].each { |file| puts file }
|
600
788
|
end
|
601
789
|
end
|
790
|
+
when :query_list_files_available
|
791
|
+
tpkg = instantiate_tpkg
|
792
|
+
requirements = []
|
793
|
+
packages = {}
|
794
|
+
tpkg.parse_requests([@action_value], requirements, packages)
|
795
|
+
availpkgs = []
|
796
|
+
packages.each do | name, pkgs |
|
797
|
+
availpkgs.concat(pkgs)
|
798
|
+
end
|
799
|
+
available = availpkgs.select do |pkg|
|
800
|
+
pkg[:source] != :native_installed &&
|
801
|
+
pkg[:source] != :native_available &&
|
802
|
+
pkg[:source] != :currently_installed
|
803
|
+
end
|
804
|
+
if available.empty?
|
805
|
+
ret_val = 1
|
806
|
+
# --qls --quiet doesn't seem like a meaningful combination, so I'm not
|
807
|
+
# suppressing this for @quiet
|
808
|
+
$stderr.puts "No packages matching '#{@action_value}' available"
|
809
|
+
else
|
810
|
+
downloaddir = Tpkg::tempdir('download')
|
811
|
+
available.each do |pkg|
|
812
|
+
# FIXME: I've duplicated from the install and upgrade methods this logic
|
813
|
+
# to calculate pkgfile, it should be encapsulated in a method
|
814
|
+
pkgfile = nil
|
815
|
+
if File.file?(pkg[:source])
|
816
|
+
pkgfile = pkg[:source]
|
817
|
+
elsif File.directory?(pkg[:source])
|
818
|
+
pkgfile = File.join(pkg[:source], pkg[:metadata][:filename])
|
819
|
+
else
|
820
|
+
pkgfile = download(pkg[:source], pkg[:metadata][:filename], downloaddir)
|
821
|
+
end
|
822
|
+
puts "#{pkg[:metadata][:filename]}:"
|
823
|
+
fip = Tpkg.files_in_package(pkgfile)
|
824
|
+
fip[:root].each { |file| puts file }
|
825
|
+
fip[:reloc].each { |file| puts '<relocatable>/' + file }
|
826
|
+
end
|
827
|
+
FileUtils.rm_rf(downloaddir)
|
828
|
+
end
|
602
829
|
when :query_who_owns_file
|
603
|
-
tpkg = instantiate_tpkg
|
830
|
+
tpkg = instantiate_tpkg
|
831
|
+
owned = false
|
832
|
+
expanded_file = File.expand_path(@action_value)
|
604
833
|
tpkg.files_for_installed_packages.each do |pkgfile, fip|
|
605
834
|
fip[:normalized].each do |file|
|
606
|
-
if file ==
|
835
|
+
if file == expanded_file
|
607
836
|
puts "#{file}: #{pkgfile}"
|
837
|
+
owned = true
|
608
838
|
end
|
609
839
|
end
|
610
840
|
end
|
841
|
+
if !owned
|
842
|
+
ret_val = 1
|
843
|
+
# --qf --quiet doesn't seem like a meaningful combination, so I'm not
|
844
|
+
# suppressing this for @quiet
|
845
|
+
$stderr.puts "No package owns file '#{@action_value}'"
|
846
|
+
end
|
611
847
|
when :query_available
|
612
|
-
tpkg = instantiate_tpkg
|
613
|
-
|
848
|
+
tpkg = instantiate_tpkg
|
849
|
+
availpkgs = []
|
614
850
|
if @action_value
|
615
|
-
|
851
|
+
# The --qs switch is set to accept multiple values (the "Array"
|
852
|
+
# parameter in the opts.on line for --qs) so users can do things like
|
853
|
+
# "tpkg --qs foo,bar" to check multiple packages at once. As such
|
854
|
+
# @action_value is an Array for this switch.
|
855
|
+
requirements = []
|
856
|
+
packages = {}
|
857
|
+
tpkg.parse_requests(@action_value, requirements, packages)
|
858
|
+
packages.each do | name, pkgs |
|
859
|
+
availpkgs.concat(pkgs)
|
860
|
+
end
|
861
|
+
else
|
862
|
+
# --qas is implemented by setting @action to :query_available and
|
863
|
+
# @action_value to nil
|
864
|
+
availpkgs.concat(tpkg.available_packages_that_meet_requirement)
|
616
865
|
end
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
866
|
+
available = availpkgs.select do |pkg|
|
867
|
+
pkg[:source] != :native_installed &&
|
868
|
+
pkg[:source] != :native_available &&
|
869
|
+
# The tpkg library treats currently installed packages as "available"
|
870
|
+
# because they are available to meet a user's requirement. I.e. if the
|
871
|
+
# user asks to install ruby and a ruby package is already installed that
|
872
|
+
# satisfies the user's requirement even if there's no ruby package in any
|
873
|
+
# of the sources. But for these query options I think the reasonable
|
874
|
+
# interpretation is that the user would like to know if there's a package
|
875
|
+
# in a source that could be installed. For example, if the user queries
|
876
|
+
# for the availability of ruby and we show it as available because it is
|
877
|
+
# installed, but then they go to another machine with the same sources
|
878
|
+
# defined and try to install ruby and it fails because there is no ruby in
|
879
|
+
# any of the sources I think the user is likely to find that unexpected
|
880
|
+
# and annoying.
|
881
|
+
pkg[:source] != :currently_installed
|
882
|
+
end
|
883
|
+
if available.empty?
|
884
|
+
ret_val = 1
|
885
|
+
if !@quiet
|
886
|
+
if @action_value
|
887
|
+
$stderr.puts "No packages matching '#{@action_value}' available"
|
888
|
+
else
|
889
|
+
$stderr.puts "No packages available"
|
890
|
+
end
|
891
|
+
end
|
892
|
+
else
|
893
|
+
if !@quiet
|
894
|
+
available.sort(&Tpkg::SORT_PACKAGES).each do |pkg|
|
895
|
+
puts "#{pkg[:metadata][:filename]} (#{pkg[:source]})"
|
896
|
+
end
|
897
|
+
end
|
621
898
|
end
|
622
899
|
when :query_requires
|
623
|
-
tpkg = instantiate_tpkg
|
624
|
-
|
625
|
-
#
|
900
|
+
tpkg = instantiate_tpkg
|
901
|
+
|
902
|
+
# Parse the request
|
626
903
|
requirements = []
|
627
904
|
packages = {}
|
628
|
-
tpkg.parse_requests([@action_value], requirements, packages
|
629
|
-
|
630
|
-
|
905
|
+
tpkg.parse_requests([@action_value], requirements, packages,
|
906
|
+
:installed_only => true)
|
907
|
+
|
908
|
+
# Note that we don't stop here in the case of this switch, but continue to
|
909
|
+
# check if anything depends on the package the user asked about. There
|
910
|
+
# shouldn't be a situation where there's another package installed that
|
911
|
+
# depends on the package the user is asking about, but the user's package is
|
912
|
+
# not installed. I.e. if foo depends on bar but only foo is installed and
|
913
|
+
# the user asks what depends on bar, the answer is still foo. That
|
914
|
+
# information might be useful to the user, even though that situation should
|
915
|
+
# have been avoided in the first place. Broken dependency trees due to
|
916
|
+
# manually messing with the repo, using --force, etc. can happen and the
|
917
|
+
# user may be using the --qr option just because they're trying to sort out
|
918
|
+
# a mess.
|
919
|
+
if packages.values.all? {|pkg| pkg.empty?}
|
920
|
+
ret_val = 1
|
921
|
+
# --qr --quiet doesn't seem like a meaningful combination, so I'm not
|
922
|
+
# suppressing this for @quiet
|
923
|
+
$stderr.puts "No packages matching '#{@action_value}' installed"
|
924
|
+
end
|
925
|
+
|
926
|
+
# Get dependencies of all installed packages
|
631
927
|
dependencies = {}
|
632
928
|
tpkg.metadata_for_installed_packages.each do |metadata|
|
633
929
|
dependencies[metadata[:filename]] = metadata[:dependencies]
|
634
930
|
end
|
635
|
-
|
636
|
-
#
|
637
|
-
#
|
931
|
+
|
932
|
+
# Check to see if any dependencies match with what the user specified in the
|
933
|
+
# request
|
934
|
+
requirees = {}
|
638
935
|
packages.each do |name, pkgs|
|
639
936
|
pkgs.each do |pkg|
|
640
937
|
next if pkg[:source] != :currently_installed
|
641
|
-
puts "The following package(s) require #{pkg[:metadata][:filename]}:"
|
642
938
|
dependencies.each do | requiree, deps |
|
643
939
|
next if deps.nil?
|
644
940
|
deps.each do | dep |
|
645
941
|
if Tpkg::package_meets_requirement?(pkg, dep)
|
646
|
-
|
942
|
+
pkgfilename = pkg[:metadata][:filename]
|
943
|
+
if !requirees[pkgfilename]
|
944
|
+
requirees[pkgfilename] = []
|
945
|
+
end
|
946
|
+
requirees[pkgfilename] << requiree
|
647
947
|
end
|
648
948
|
end
|
649
949
|
end
|
650
950
|
end
|
651
951
|
end
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
puts " Requires #{req[:name]}"
|
661
|
-
req.each do |field, value|
|
662
|
-
next if field == :name
|
663
|
-
puts " #{field}: #{value}"
|
664
|
-
end
|
665
|
-
end
|
952
|
+
|
953
|
+
if !requirees.empty?
|
954
|
+
requirees.keys.sort.each do |pkgfilename|
|
955
|
+
puts "The following package(s) require #{pkgfilename}:"
|
956
|
+
# uniq probably isn't necessary, but it can't hurt
|
957
|
+
requirees[pkgfilename].sort.uniq.each do |requiree|
|
958
|
+
puts " #{requiree}"
|
959
|
+
end
|
666
960
|
end
|
961
|
+
else
|
962
|
+
puts "No other package depends on '#{@action_value}'"
|
667
963
|
end
|
668
964
|
when :query_depends
|
669
|
-
tpkg = instantiate_tpkg
|
965
|
+
tpkg = instantiate_tpkg
|
966
|
+
|
967
|
+
requirements = []
|
968
|
+
packages = {}
|
969
|
+
tpkg.parse_requests([@action_value], requirements, packages,
|
970
|
+
:installed_only => true)
|
971
|
+
|
972
|
+
if packages.values.all? {|pkg| pkg.empty?}
|
973
|
+
ret_val = 1
|
974
|
+
# --qd --quiet doesn't seem like a meaningful combination, so I'm not
|
975
|
+
# suppressing this for @quiet
|
976
|
+
$stderr.puts "No packages matching '#{@action_value}' installed"
|
977
|
+
else
|
978
|
+
depends = {}
|
979
|
+
packages.each do |name, pkgs|
|
980
|
+
pkgs.each do |pkg|
|
981
|
+
if pkg[:metadata][:dependencies]
|
982
|
+
pkgfilename = pkg[:metadata][:filename]
|
983
|
+
if !depends[pkgfilename]
|
984
|
+
depends[pkgfilename] = []
|
985
|
+
end
|
986
|
+
pkg[:metadata][:dependencies].each do |req|
|
987
|
+
depends[pkgfilename] << req
|
988
|
+
end
|
989
|
+
end
|
990
|
+
end
|
991
|
+
end
|
992
|
+
|
993
|
+
if !depends.empty?
|
994
|
+
outputs = []
|
995
|
+
depends.keys.sort.each do |pkgfilename|
|
996
|
+
output = "Package #{pkgfilename} depends on:\n"
|
997
|
+
# uniq probably isn't necessary, but it can't hurt
|
998
|
+
outs = []
|
999
|
+
depends[pkgfilename].sort{|a,b| a[:name]<=>b[:name]}.uniq.each do |req|
|
1000
|
+
out = " name: #{req[:name]}\n"
|
1001
|
+
req.each do |field, value|
|
1002
|
+
next if field == 'name'
|
1003
|
+
out << " #{field}: #{value}\n"
|
1004
|
+
end
|
1005
|
+
outs << out
|
1006
|
+
end
|
1007
|
+
outputs << output + outs.join("\n")
|
1008
|
+
end
|
1009
|
+
print outputs.join("\n")
|
1010
|
+
else
|
1011
|
+
puts "Package '#{@action_value}' does not depend on other packages"
|
1012
|
+
end
|
1013
|
+
end
|
1014
|
+
when :query_depends_available
|
1015
|
+
tpkg = instantiate_tpkg
|
670
1016
|
requirements = []
|
671
1017
|
packages = {}
|
672
1018
|
tpkg.parse_requests([@action_value], requirements, packages)
|
673
|
-
|
674
|
-
|
675
|
-
pkgs
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
1019
|
+
availpkgs = []
|
1020
|
+
packages.each do | name, pkgs |
|
1021
|
+
availpkgs.concat(pkgs)
|
1022
|
+
end
|
1023
|
+
available = availpkgs.select do |pkg|
|
1024
|
+
pkg[:source] != :native_installed &&
|
1025
|
+
pkg[:source] != :native_available &&
|
1026
|
+
pkg[:source] != :currently_installed
|
1027
|
+
end
|
1028
|
+
|
1029
|
+
if available.empty?
|
1030
|
+
ret_val = 1
|
1031
|
+
# --qds --quiet doesn't seem like a meaningful combination, so I'm not
|
1032
|
+
# suppressing this for @quiet
|
1033
|
+
$stderr.puts "No packages matching '#{@action_value}' available"
|
1034
|
+
else
|
1035
|
+
depends = {}
|
1036
|
+
available.each do |pkg|
|
681
1037
|
if pkg[:metadata][:dependencies]
|
1038
|
+
pkgfilename = pkg[:metadata][:filename]
|
1039
|
+
if !depends[pkgfilename]
|
1040
|
+
depends[pkgfilename] = []
|
1041
|
+
end
|
682
1042
|
pkg[:metadata][:dependencies].each do |req|
|
683
|
-
|
1043
|
+
depends[pkgfilename] << req
|
1044
|
+
end
|
1045
|
+
end
|
1046
|
+
end
|
1047
|
+
|
1048
|
+
if !depends.empty?
|
1049
|
+
outputs = []
|
1050
|
+
depends.keys.sort.each do |pkgfilename|
|
1051
|
+
output = "Package #{pkgfilename} depends on:\n"
|
1052
|
+
# uniq probably isn't necessary, but it can't hurt
|
1053
|
+
outs = []
|
1054
|
+
depends[pkgfilename].sort{|a,b| a[:name]<=>b[:name]}.uniq.each do |req|
|
1055
|
+
out = " name: #{req[:name]}\n"
|
684
1056
|
req.each do |field, value|
|
685
|
-
next if field ==
|
686
|
-
|
1057
|
+
next if field == 'name'
|
1058
|
+
out << " #{field}: #{value}\n"
|
687
1059
|
end
|
1060
|
+
outs << out
|
688
1061
|
end
|
1062
|
+
outputs << output + outs.join("\n")
|
689
1063
|
end
|
1064
|
+
print outputs.join("\n")
|
1065
|
+
else
|
1066
|
+
puts "Package '#{@action_value}' does not depend on other packages"
|
690
1067
|
end
|
691
1068
|
end
|
692
1069
|
when :query_tpkg_metadata
|
693
|
-
tpkg = instantiate_tpkg
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
1070
|
+
tpkg = instantiate_tpkg
|
1071
|
+
requirements = []
|
1072
|
+
packages = {}
|
1073
|
+
tpkg.parse_requests([@action_value], requirements, packages,
|
1074
|
+
:installed_only => true)
|
1075
|
+
|
1076
|
+
if packages.values.all? {|pkg| pkg.empty?}
|
1077
|
+
ret_val = 1
|
1078
|
+
# --qX --quiet doesn't seem like a meaningful combination, so I'm not
|
1079
|
+
# suppressing this for @quiet
|
1080
|
+
$stderr.puts "No packages matching '#{@action_value}' installed"
|
698
1081
|
else
|
699
|
-
|
1082
|
+
packages.each do | name, pkgs |
|
1083
|
+
pkgs.each do | pkg |
|
1084
|
+
pkgfile = nil
|
1085
|
+
if pkg[:source] == :currently_installed
|
1086
|
+
pkgfile = File.join(tpkg.installed_directory, pkg[:metadata][:filename])
|
1087
|
+
else
|
1088
|
+
pkgfile = pkg[:source]
|
1089
|
+
end
|
1090
|
+
puts Tpkg::extract_tpkg_metadata_file(pkgfile)
|
1091
|
+
end
|
1092
|
+
end
|
1093
|
+
end
|
1094
|
+
when :query_tpkg_metadata_available
|
1095
|
+
tpkg = instantiate_tpkg
|
1096
|
+
requirements = []
|
1097
|
+
packages = {}
|
1098
|
+
tpkg.parse_requests([@action_value], requirements, packages)
|
1099
|
+
availpkgs = []
|
1100
|
+
packages.each do | name, pkgs |
|
1101
|
+
availpkgs.concat(pkgs)
|
1102
|
+
end
|
1103
|
+
available = availpkgs.select do |pkg|
|
1104
|
+
pkg[:source] != :native_installed &&
|
1105
|
+
pkg[:source] != :native_available &&
|
1106
|
+
pkg[:source] != :currently_installed
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
if available.empty?
|
1110
|
+
ret_val = 1
|
1111
|
+
# --qXs --quiet doesn't seem like a meaningful combination, so I'm not
|
1112
|
+
# suppressing this for @quiet
|
1113
|
+
$stderr.puts "No packages matching '#{@action_value}' available"
|
1114
|
+
else
|
1115
|
+
downloaddir = Tpkg::tempdir('download')
|
1116
|
+
available.each do |pkg|
|
1117
|
+
# FIXME: I've duplicated from the install and upgrade methods this logic
|
1118
|
+
# to calculate pkgfile, it should be encapsulated in a method
|
1119
|
+
pkgfile = nil
|
1120
|
+
if File.file?(pkg[:source])
|
1121
|
+
pkgfile = pkg[:source]
|
1122
|
+
elsif File.directory?(pkg[:source])
|
1123
|
+
pkgfile = File.join(pkg[:source], pkg[:metadata][:filename])
|
1124
|
+
else
|
1125
|
+
pkgfile = download(pkg[:source], pkg[:metadata][:filename], downloaddir)
|
1126
|
+
end
|
1127
|
+
puts Tpkg::extract_tpkg_metadata_file(pkgfile)
|
1128
|
+
end
|
1129
|
+
FileUtils.rm_rf(downloaddir)
|
700
1130
|
end
|
701
1131
|
when :query_env
|
702
1132
|
puts "Operating System: #{Tpkg::get_os}"
|
703
1133
|
puts "Architecture: #{Tpkg::get_arch}"
|
1134
|
+
puts "Tar: #{Tpkg::find_tar}"
|
704
1135
|
when :query_conf
|
705
1136
|
# This is somewhat arbitrarily limited to the options read from the
|
706
1137
|
# tpkg.conf config files. The reason it exists at all is that it is
|
@@ -708,12 +1139,12 @@ when :query_conf
|
|
708
1139
|
# without recreating all of our logic about deciding which config files to
|
709
1140
|
# read, which order to read them in, what environment variables override the
|
710
1141
|
# config files, etc.
|
711
|
-
tpkg = instantiate_tpkg
|
1142
|
+
tpkg = instantiate_tpkg
|
712
1143
|
puts "Base: #{tpkg.base}"
|
713
1144
|
puts "Sources: #{tpkg.sources.inspect}"
|
714
1145
|
puts "Report server: #{tpkg.report_server}"
|
715
1146
|
when :query_history
|
716
|
-
tpkg = instantiate_tpkg
|
1147
|
+
tpkg = instantiate_tpkg
|
717
1148
|
tpkg.installation_history
|
718
1149
|
when :query_version
|
719
1150
|
puts Tpkg::VERSION
|