How absolute symlinks in charms can break your deployments?
If you try to build and deploy a charm that contains absolute symlinks,
you will find out that juju deploy
aborts the deployment with an error
such as the following:
ERROR cannot deploy bundle: cannot repackage charm: symlink
"$the-symlink-name" is absolute: "$path-where-the-symlink-points-to"
Many charm authors use tox to run
python-based unit tests for the charms they maintain. Tools like tox tend to
create symlinks to the system python binaries within the charm folder. These
symlink files will get typically committed to version-control and, unless
somehow explicitly excluded, will end up in the charm archive causing the above
error to be emitted when either:
- deploying the charm, or
- while attempting to run functional unit-tests.
Excluding files/folders from charm archives using .jujuignore files
When an operator deploys a bundle, juju will retrieve the charm and
automatically repackage its contents into a fresh charm archive that gets
cached by the controller. So, how can we actually exclude the bits we don’t
really need from the generated charm archives? There are two documented
ways of achieving this:
- Rely on the built-in exclusion list used by the charm archiving code (backwards-compatibility way).
- Provide a
.jujuignore
file (the new way).
.jujuignore
files allow charm authors to define their own set of exclusion
patterns using the same pattern syntax as .gitignore
files. This feature is
available since juju 2.5.3 and in order to use it, charm authors need to
place a file named .jujuignore
in the root folder of the charm.
Here is a quick summary of the syntax used in .jujuignore
files together
with some useful examples:
- A blank line matches no files, so it can serve as a separator for
readability. - A line starting with
#
serves as a comment. Put a backslash (\
) in
front of the first hash for patterns that begin with a hash. - Trailing spaces are ignored unless they are quoted with backslash (
\
). - An optional prefix
!
negates the pattern; any matching file excluded
by a previous pattern will become included again. - If the pattern ends with a slash, it is removed but the rule will ONLY
match directories. For example,foo/
will match a directoryfoo
and
paths underneath it, but will not match a regular file or a symbolic
link namedfoo
. - All other patterns are treated as shell globs. For details regarding
the supported glob expressions please refer to the gobwas/glob package
documentation. - A leading slash matches the beginning of the pathname. For example,
/*.go
matchesfoo.go
but notpkg/foo.go
. - Double-star patterns have a special meaning:
- A leading
**
followed by a slash means match in all directories.
For example,**/foo
matches file or directoryfoo
anywhere, the
same as patternfoo
.**/foo/bar
matches file or directorybar
anywhere that is directly under directoryfoo
. - A trailing
/**
matches everything inside. For example,abc/**
matches all files inside directoryabc
but NOTabc
. - A slash followed by two consecutive asterisks then a slash matches
zero or more directories. For example,a/**/b
matchesa/b
,
a/x/b
,a/x/y/b
and so on.
- A leading
Let’s now revisit the above example! With the above rules in mind, we can easily filter
out any tox-related resources from the generated charm archives by creating a .jujuignore
file with the following content:
# Ignore tox-related resources
.tox/