Abstract
Software deployment is the set of activities related to getting
software components to work on the machines of end users. It includes
activities such as installation, upgrading, uninstallation, and so on.
Many tools have been developed to support deployment, but they all
have serious limitations with respect to correctness. For instance,
the installation
... read more
of a component can lead to the failure of previously
installed components; a component might require other components that
are not present; and it is generally difficult to undo deployment
actions. The fundamental causes of these problems are a lack of
isolation between components, the difficulty in identifying the
dependencies between components, and incompatibilities between
versions and variants of components.
This thesis describes a better approach based on a purely functional
deployment model, implemented in a deployment system called Nix.
Components are stored in isolation from each other in a Nix store.
Each component has a name that contains a cryptographic hash of all
inputs that contributed to its build process, and the content of a
component never changes after it has been built. Hence the model is
purely functional.
This storage scheme provides several important advantages. First, it
ensures isolation between components: if two components differ in any
way, they will be stored in different locations and will not overwrite
each other. Second, it allows us to identify component dependencies.
Undeclared build time dependencies are prevented due to the absence of
"global" component directories used in other deployment systems.
Runtime dependencies can be found by scanning for cryptographic hashes
in the binary contents of components, a technique analogous to
conservative garbage collection in programming language
implementation. Since dependency information is complete, complete
deployment can be performed by copying closures of components under
the dependency relation.
Developers and users are not confronted with components' cryptographic
hashes directly. Components are built automatically from Nix
expressions, which describe how to build and compose arbitrary
software components; hashes are computed as part of this process.
Components are automatically made available to users through "user
environments", which are synthesised sets of activated components.
User environments enable atomic upgrades and rollbacks, as well as
different sets of activated components for different users.
Nix expressions provide a source-based deployment model. However,
source-based deployment can be transparently optimised into binary
deployment by making pre-built binaries (keyed on their cryptographic
hashes) available in a shared location such as a network server. This
is referred to as transparent source/binary deployment.
The purely functional deployment model has been validated by applying
it to the deployment of more than 278 existing Unix packages. In
addition, this thesis shows that the model can be applied naturally to
the related activities of continuous integration using build farms,
service deployment and build management.
show less