2

I am writing a post-install script for Ubuntu in Perl (same script as seen here). One of the steps is to install a list of packages. The problem is that if apt-get install fails in some of many different ways for any one of the packages the script dies badly. I would like to prevent that from happening.

This happens because of the ways that apt-get install fails for packages that it doesn't like. For example when I try to install a nonsense word (i.e. typed in the wrong package name)

$ sudo apt-get install oblihbyvl
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package oblihbyvl

but if instead the package name has been obsoleted (installing handbrake from ppa)

$ sudo apt-get install handbrake
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Package handbrake is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

E: Package 'handbrake' has no installation candidate
$ apt-cache search handbrake
handbrake-cli - versatile DVD ripper and video transcoder - command line
handbrake-gtk - versatile DVD ripper and video transcoder - GTK GUI

etc, etc ...

I have tried parsing the results of apt-cache and apt-get -s install to try to catch all possibilities before doing the install, but I seem to keep finding new ways to allow failures to continue to the actual install system command.

My question is, is there some facility either in Perl (e.g. a module, though I would like to avoid installing modules if possible as this is supposed to be the first thing run after a new install of Ubuntu) or apt-* or dpkg that would let me be sure that the packages are all available to be installed before installing and if not fail gracefully in some way that lets the user decide what to do?

N.B. I am doing something along the lines of:

my @list_of_install_candidates = (...);
my @to_install = grep { my $output = qx{ apt-get -s install $_ }; parse_output($output); } @list_of_install_candidates;
system('apt-get', 'install', @to_install);
Community
  • 1
  • 1
Joel Berger
  • 20,180
  • 5
  • 49
  • 104

1 Answers1

2

You might try apt-cache policy. examples:

$ apt-cache policy handbrake
handbrake:
  Installed: (none)
  Candidate: (none)
  Version table:

$ apt-cache policy foo
N: Unable to locate package foo

$ apt-cache policy openbox
openbox:
  Installed: 3.4.11.1-1
  Candidate: 3.4.11.1-1
  Version table:
 *** 3.4.11.1-1 0
        500 http://mirrors.xmission.com/ubuntu/ maverick/universe i386 Packages
        100 /var/lib/dpkg/status

Anything with a non-blank version table should be installable.

cam
  • 14,192
  • 1
  • 44
  • 29
  • Even something with a non-blank version may conflict with some other package that's installed. – ysth Jan 07 '11 at 18:46
  • hmm, in that case maybe it would make more sense to try and parse the output of a dry run (`apt-get -s install ...`) – cam Jan 07 '11 at 18:50
  • @cam, thanks, I'll give this a go. @ysth, that may be ok, since the intention is to be the first thing to run after an install, as long as the packages don't conflict with the distro standard packages (and they shouldn't) this should be ok. – Joel Berger Jan 07 '11 at 19:41
  • actually, it seems that reading candidate might be easier than parsing the version table, do you agree that that would be enough, `/Candidate: (.*)/; $1 !~ /\(none\)/;` – Joel Berger Jan 07 '11 at 20:12
  • Joel, checking Candidate is a good idea. Does that handle the case of conflicting packages though? – cam Jan 07 '11 at 20:38
  • Seems to work so far, if I find a counter I will post for future readers. Thanks – Joel Berger Jan 07 '11 at 21:31
  • Again, not too worried about conflicting packages, but I will keep an eye out for it. – Joel Berger Jan 07 '11 at 21:31