Reproducible Charms¶
When building charms, multiple layers are brought together in an ordered,
depth-first recursive fashion. The individual files of each layer are merged,
and then python modules are brought in according to wheelhouse.txt
files
that may exist in each layer.
Layers (and Interfaces) are typically Git repositories, and by default the
default branch (usually called master
) of the repository is fetched and
used.
Also, although the top level Python modules can be pinned in the
wheelhouse.txt
files, any dependent modules are fetched as their latest
versions. This makes re-building a charm with the same layers and modules
tricky, which may be required for stable charms. It is possible, by populating
layer and interface directories directly, and by pinning every Python module in
a wheelhouse.txt
override file that is passed using the
--wheelhouse-overrides
option to the charm build
command.
An alternative strategy is to use a new feature of the charm build
command
which can generate a lock file that contains all of the layers and Python
modules, and their versions. This can then, for subsequent builds, be used to
fetch the same layer versions and Python modules to re-create the charm.
As the lock file is a JSON
file, it can be manually edited to change a
layer version if a new version of a stable charm is needed, or a python module
can be changed.
Additionally, it is possible to track a branch in the repository for a layer so that a stable (or feature) branch can be maintained and then charms rebuilt from that branch.
The new options for this feature are:
--write-lock-file
--use-lock-file-branches
--ignore-lock-file
Creating the lock file¶
To create a lock file, the option --write-lock-file
is passed to the
charm build
command. This option automatically ignores the existing lock
file, and rebuilds the charm using the latest versions of the layers and the
versions of the modules as determined in the various wheelhouse.txt
files.
Python module versions are also recorded. If a VCS repository is used for the python module, then any branch specified is also recorded, along with the commit.
At the end of the build, the lock file is written with all of the layer and Python module information.
The lock file is installed in the base layer directory so that it can be committed into the VCS and used for subsequent builds.
The name of the lock file is build.lock
.
Rebuilding the charm from the lock file¶
If a lock file (build.lock
) is available in the top layer, then it will be
used to control the versions of the layers and modules by default. i.e. the
presence of the lock file controls the build.
Three options are available which can influence the build when a lock file is present:
--ignore-lock-file
--use-lock-file-branches
--wheelhouse-overrides
If the --ignore-lock-file
option is used, then the charm is built as though
there is no lock file.
If the --use-lock-file-branches
is used, then, for VCS items (layers,
interfaces, and Python modules specified using a VCS string), then the branch
(if there was one) will be used, rather than the commit version. This can be
used to track a branch in a layer or Python module.
Note: if --wheelhouse-overrides
is used, then that wheelhouse will override
the lock file. i.e. the lock file overrides the layers’ wheelhouse.txt
file, and then the --wheelhouse-overrides
then can override the lock-file.
This is intentional to allow the build to perform specific overrides as
needed.
Other useful information¶
This is the first iteration of ‘reproducible charms’. As such, only Git is supported as the VCS for the layers, and Git and Bazaar for Python modules. A future iteration may support more VCS systems.
Only the top layer is inspected for a build.lock
file. Any other layers
are considered inputs and their build.lock
files are ignored (if they are
present).
Also, regardless of the wheelhouse.txt
layers, the lock file will override
any changes that may be introduced in stable branches, if they are bing tracked
using --use-lock-file-branches
. This may lead to unexpected behaviour.