Initial import from AT&T
Using 'gem contents' to figure out the directory where the gem is
installed wasn't working with the ruby-oci8 gem (paths returned were
relative to that directory), so switch to an alternate approach. This
new method isn't particularly any more elegant, so it too may break at
some point.

Only call refresh_metadata when needed (which is only in one place), not
in Tpkg::init. Loading the native package data takes many seconds on
platforms with lots of native packages, which introduces unnecessary and
unwelcome delay if that metadata is not needed.

Bug fix for packages not at base URL

Explicitely set permissions on tpkg.conf, and cron.d/tpkg on Red Hat.
We were setting the permissions on other files in the package, just not 
those two.  Cron is particular about the permissions of crontab files,
and will ignore them if the permissions aren't acceptable.
A couple of libraries that the client depends on.  Including them here
so the user doesn't have to install them.
Rename the Solaris package scripts so that it is clear which OS they
belong to.
Improve the handling of the package version so that it is only defined
in one place instead of hard-coded in a bunch of files.

Add the third party libraries into the packages that are built.

Update the Debian package to go into /usr/local/lib, as that seems to be
where Debian's ruby is looking for additional libraries.

Add tpkgpkg target to Makefile.  See comments there for more detail.
Add tpkgpkg target to Makefile.  See comments there for more detail.
Changes involving tpkg.rb
-------------------------

Updated deployment feature to pass all the options over to the remote
client, thus enabling any action to be applicable to the remote client.
For example, you can now run

tpkg -i my_pkg -s myhost1,myhost2 --lock-force
tpkg --qa -s myhost1,myhost2
etc.

The code which added a / to the end of source URLs to make them
compatible with URI.join was written improperly.  As such the / was not
actually added and subsequent code with used URI.join to build URLs
ended up building bad URLs.

Modify refresh_metadata to trap an access exception when trying to save
a cached copy of metadata fetched from a source server, as we do
elsewhere in the code to allow non-root users to run query operations.
We proceed using the metadata contents in memory.  Each future run would
of course need to re-grab the metadata, but that's better than failing.

Update path for tpkg client to send update back to report server.

Rename source_to_local_path to source_to_local_directory to better
reflect what it does, and modify it to not create the directory so that
callers call control if/when the directory is created and how they
handle problems with the creation.  Specifically refresh_metadata would
only prefer to save a cached copy of the metadata from the source, it is
not an error if that can't be done, and having to wrap the call to
source_to_local_directory in a rescue block to catch that exception
seems like bad design.  Now refresh_metadata can try to make the
directory in a separate operation and wrap just that in a rescue block,
which more clearly conveys the reason for that logic.

No hardcoding the report server controller inside the code. Better to
specify it in tpkg.conf

For FreeBSD, which doesn't normally use runlevels, add a special case
that if runlevels are specified as empty the init script is not linked.  
This roughly follows the desired behavior on SysV platforms where if 
runlevels is specified empty the script is not linked into any
runlevels.

Apply default permissions to files and directories unless the user 
overrides via tpkg.xml.
Description from ticket:
tpkg currently leaves file and directory permissions as they came out of
tar unless the user requests otherwise via tpkg.xml. For shared
directories like /home/t, /home/t/bin, etc. this leaves us at the whim
of whatever they were set to by the last package installed. And even for
regular, non-shared files that leaves the user with the probably
confusing behavior of the installed files owned by their own account
unless they took special precautions when building the package. I think
we should apply default permissions and ownership to all files and
directories unless the user overrides that via tpkg.xml. This amounts to
the equivalent of having global "file_defaults" that are applied if
neither a file_defaults section or perms for that specific file appear
in the tpkg.xml.

Fix handling of empty init/levels element.  If you call REXML's text
method on something like <levels></levels> it seems you get back nil
rather than ''.

Follow-up to above permissions change:
Don't apply default permissions to files.  That breaks executables.
Need to think more about whether there is a meaningful way to implement
default permissions, i.e. a default umask or something.

Pull the code which extracts the list of init scripts out of a package's
metadata out of the top of the init_links method into a separate
init_scripts method.  The execute_init method needs the list of init
scripts in a package even if the package is configured so that some/all
of those init scripts are not linked into a runlevel.

Made deploy a class method

If loading facter fails try again after loading rubygems.  Depending on 
the environment the user might have installed facter via gems.

In download and extract_metadata set reasonable (i.e. world readable 
permissions) on the files we're generating.  We initially create the 
files there via Tempfile, which sets restrictive permissions by default.

When manipulating crontabs match permissions and ownership to the 
existing crontab, otherwise we get Tempfile's default permissions.

Set tpkg version as a constant in the library (Tpkg::VERSION).

Add a command line option to tpkg to display the version.

Modify the make targets to insert the version into the appropriate place
rather than having the version hard-coded in a bunch of files.

Populate @metadata has a hash by package name, rather than an array.
Greatly reduces the number of packages that
available_packages_that_meet_requirement has to check.

metadata_for_installed_packages caches the REXML document for each
package.  This allows comparisons between pkg hashes representing the
same package generated at different times to work as expected, as the
REXML document representing the package metadata in the pkg hash is the
same object.

Add installed_packages method to generate pkg hashes for all installed
packages.

Fixed installed_packages_that_meet_requirement to handle reqs for native
packages.

Add a bunch of debugging messages in various places triggered by @@debug

Fix the scoring algorithm in best_solution.  It probably worked
more-or-less as it was, but it wasn't quite perfect.

De-dup requirements as they are collected to avoid an excess number of
them that we have to check and avoid problems with circular
dependencies.

De-dup solutions as they are collected to avoid an excess number of them
that we have to score.

Add requirements_for_currently_installed_package method.

Modify available_packages_that_meet_requirement to add in results from
installed_packages_that_meet_requirement, as an installed package should
count as available.  Modify
requirements_for_currently_installed_packages to not separately add in
an entry for the currently installed package to the list it gets back
from available_packages_that_meet_requirement.

Add - to the allowed characters in a basic package request, so that
things like 'mogwai-client' are recognized.

Add prompt_for_install method.

install and upgrade no longer add requirements for all currently
installed packages, except for an upgrade of all packages.  This can
greatly cut down on the number of requirements we have to solve, and the
number of resulting solutions we have to score.  solve_dependencies adds
in requirements for currently installed packages as it encounters them,
so we only have the minimal number of requirements we need.

Available package information is now loaded in a two-step process.  We 
initially fetch it from package and URL sources, but perform only 
minimal processing of the XML before storing it in @metadata.  The XML 
is then converted to a Ruby hash format on an as needed basis and stored
in @available_packages (a new variable).  This minimizes the amount of 
XML processing we need to perform, as that was proving to be our #1 CPU
consumer.  The refresh_metadata method has been replaced with
prep_metadata and load_available_packages.

Native package info is also now loaded incrementally as needed and 
stored in @native_available_packages (a new variable).  This should 
prove helpful on systems like Debian and derivatives where the 10s of 
thousands of available native packages were taking much too long to 
parse.  The new load_available_native_packages method handles this 
process.

Add metadata_xml_to_hash method to perform the conversion of available 
package info from XML to Ruby.  
  
In the process fix the handling of multiple OSs and architectures to
match the documentation, i.e. multiple OSs or architectures can now be
specified via multiple instances of the appropriate XML element, as an
alternative to the comma-separated system that I originally implemented.
See the comments in the code or the ticket for more info.

sort_packages now uses info about whether a package is currently 
installed vs. just available as a last deciding factor even if 
:prefer==false.  This ensures we select the currently installed version
of two otherwise identical packages.

The best_solution method now takes an additional parameter of 
core_packages, a list of the packages that represent the core of the 
user's request.  The score of those packages matters more than the score
of other packages.  An example of where this is useful is a state where
currently a=0.9 is installed and a=0.9 has no dependencies.  The user 
requests an upgrade, and a=1.0 is available.  However, a=1.0 adds some
dependencies and the available packages that satisfy those dependencies
don't score well.  best_solution was previously picking the current 
a=0.9 as preferable to a=1.0 because the score of the a=1.0 solution was
lower overall, even though a=1.0 by itself scores better than a=0.9.  
However, if the user has requested an upgrade of 'a' they want the newer
package.  The scores of the dependencies don't really have any meaning 
to the user.  Added a unit test for this scenario.

Fix the handling of scores of 0 in best_solution again.  My previous fix
was incorrect.  

Add a check for individual packages that are specifically requested to
ensure that they will install on this machine.  Otherwise we just
eventually cough up a dependency failure, which is not very user
friendly.

Added options to specify what user to use when deploying. Added option
to tell the deployer to use ssh key rather than asking for password.
This will be helpful people who want to use tpkg in their script. Added
code to better handle lock.  Updated deploy method signature to be more
generic and flexible

Better error message when tpkg fails to download pkg. Updated tpkg to
not echo passphrase

Add a test for available_packages_that_meet_requirement and
load_available_packages to ensure that they handle requests for a
package for which there are no available packages.  Fix a typo in
tpkg.rb that was causing tpkg to throw an exception in that situation.

Fix bug with executing init script

Fix logic error that caused an exception to be thrown unnecessarily when
trying to process conflicting init or crontab links.  The exception was
thrown when trying to process the third instance of a given init script
or crontab filename.  The loop that tries to make "filename1",
"filename2", etc. links failed if "filename1" didn't work.

Improved unit tests to test that scenario, previously they only tested
the creation of "filename1", now they test "filename2" as well.  And
fixed the unit tests so that they don't interpret every exception in
that code as meaning that there is no support for init scripts or
crontabs on the platform.

Fill in unit tests for requirements_for_currently_installed_package.  
Fix bug with same, it was not filling in :minimum_package_version if the
package had a package version.

Fix upgrade so that it properly handles requests for upgrades using a 
package filename or URL.  Add unit test for same.

Add some more debug statements.

Redesign the method of finding the best solution to a set of
dependencies.  Rather than computing all solutions, sorting them, and
picking the top one possible solutions are now checked in order until
one works.  This uses much less CPU time and memory if the number of
possible solutions is non-trivial.

Fix the following issues:
* tpkg should not change file permissions for existing files unless
specifically told to do so 
* <file_defaults> equivalent for directories 
* removing a package does not stop it 
Added unit tests for these

Fixed bug where default dir was set to root when user doesn't specify
default dir perm/ownership. For cases like this, we want to use values
from default file settting

Changes specific to the tpkg executable
---------------------------------------

Two separate problems, a typo in specifying the --qv argument to
OptionParser prevents --qv from ever getting an argument, and a typo in
handling the data from the tpkg library means that no packages are
printed even when the correct results are returned by the library.

Modify the query_depends option (--qd) to handle any type of package
specification, not just packages that are already installed.  So you can
now query package files or URLs.

Mark the argument to --upgrade as optional and properly handle that
situation, as specifying --upgrade with no argument should attempt to
upgrade all installed packages.

User can now specify number for worker for deploying. Fixed version bug

Updated --verify option to also allow user to verify .tpkg file (not
installed)

Fixed bug where we couldn't do --qi existing_pkg.tpkg
Remove sudo call, no longer necessary as tpkg applies default
permissions
Package for sphinx
Package for jdk
Package for matplotlib
Package for pylot
Remove calls to sudo, no longer necessary now that tpkg applies default
file permissions.

Fix bug in postinstall, need the g option to sed.
Remove calls to sudo, no longer necessary now that tpkg applies default
permissions.
Package for nload
Package for tokyocabinet
Remove the calls to sudo, no longer necessary now that tpkg applies
default permissions.
Package for monit
Remove calls to sudo, no longer necessary now that tpkg applies default
permissions.
Package for google perftools