tpkg 2.2.4 → 2.3.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.
- 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
|