This repository contains some basic dibspacks that can be used with dibs. To use them, you can…
-
… put a
gitreference to the main repository, e.g.:
packs:
foo:
type: git
origin: https://github.com/polettix/dibspack-basic
-
… use it from a stroke:
actions:
some-stroke:
pack: foo
path: perl/build
user: ubuntu
But there’s more: some parts in this repository are actually aimed at being included inside the target containers, e.g. to smooth some sharp edges.
This dibspack helps checking out a git repository. It is called like this:
git/fetch [git_uri]
where the optional parameter is a URI where the code can be found. In case
this parameters is absent, environment variable DIBSPACK_GIT_URI is used
instead (or an exception is thrown if this is not defined properly too).
The git URI can include a fragment section, interpreted as whatever comes
after the first dash character #. When present, the fragment represents the
ref to check out; by default, the master branch is considered. This can help
pinning a specific revision and avoid surprises due to updates.
The checkout is performed in the src_dir directory, i.e. the directory
passed via the DIBS_DIR_SRC envile. If this directory already contains a
.git sub-directory and environment variable DIBSPACK_GIT_REFRESH is set to
1 (exactly), then the current contents will be used for a fetch from the
current origin remote. Otherwise, the src_dir is wiped out completely and
the remote is cloned to get a fresh copy.
It is possible to set variable DIBSPACK_GIT_DEBUG to 1 (exactly) and
activate the shell’s capabilities for debugging (options -x and '-v').
Example usage in a dibs.yml file:
packs:
foo:
type: git
origin: https://github.com/polettix/dibspack-basic
actions:
bar:
pack: foo
path: git/fetch
args: ['https://github.com/polettix/sample-mojo#844f256']
This dibspack requires git to be available in the container; it contains
some scripts to assist in the installation of git depending on the operating
system tools inside the container (e.g. Alpine, Debian, …).
This buildpack copies files from a source to a destination. It is invoked like this:
install/plain-copy source destination
If source is missing or empty, src_dir is used instead (according to the
contents of envile DIBS_DIR_SRC). If destination is empty, path /app is
used instead.
This dibspack tries hard to get rid of destination before starting the copy.
The copy is done using cp -pPR to keep the same permissions as in the
source.
Example usage in a dibs.yml file:
packs:
foo:
type: git
origin: https://github.com/polettix/dibspack-basic
actions:
bar:
pack: foo
path: install/plain-copy
args: [{path_cache: '/app'}, '/app']
This buildpack copies files from a source to a destination, pruning those that match patterns defined inside a file. This allows selecting only part of the files in a wider source, leaving behind those that possibly help building/testing artifacts but are then unneeded in the normal runtime phase.
It is invoked like this:
install/with-dibsignore [options...] [step]
This program is a Perl program and supports flexible GNU-style parameters:
-
--debug/-D: boolean option, turn on debug mode (defaults to value of environment variableDIBSPACK_INSTALL_DEBUGand tooffas a fallback). -
--dibsignore/-f: string option, sets the name of the file where to take patterns for exclusions. It defaults to environment variableDIBSPACK_INSTALL_DIBSIGNOREand, as a fallback. to the string.dibsignore. There can be one such file inside each directory where you want to do pruning. -
--dst/-d: string setting the destination of the copy. It defaults to the environment variableDIBSPACK_INSTALL_DSTand, depending on thestepparameter, to something else as a fallback (see below). -
--preserve/-p: boolean option, when set it does not wipe the previous content of the destination directory. It defaults to the environment variableDIBSPACK_INSTALL_PRESERVEor to a false value as fallback. -
--print/-P: boolean option, when set it does not copy anything but prints on standard output what will be copied. Defaults to environment variableDIBSPACK_INSTALL_PRINTor to a false value as fallback. -
--src/-s: string setting the source of the copy. It defaults to the environment variableDIBSPACK_INSTALL_SRCand, depending to thestepparameter, to something else as a fallback (see below).
The optional parameter step is a shorthand to set fallback defaults for the
source and destination directories, namely:
-
if it takes value
build, then the source eventually defaults tosrc_dir(i.e. the content of envileDIBS_DIR_SRC) and the destination to sub-directoryappinside the cache directory (i.e. the second parameter). -
if it takes value
bundle, then the source eventually defaults to sub-directoryappinside the cache directory (i.e. the content of envileDIBS_DIR_CACHE) and the destination defaults to/app. -
any other value throws an exception.
The step can also be set via environment variable DIBSPACK_STEP.
The dibsignore file has the same format and follows the same rules as the more
popular .gitignore file used by Git.
This program requires to run Perl inside the container. This should be a
no-problem in the build steps, but might be trickier in the bundle steps.
If this is actually the case, the suggestion is to prepare the copy with
install/with-dibsignore during the build step, then use
install/simple-copy (which only relies on POSIX compliant /bin/sh) to
place the artifacts in the right place during the bundle step.
This dibspack aims at compiling Perl code. As a matter of fact, it only
makes sure that prerequisites modules are properly installed, e.g. via cpanm
or carton. It is invoked like this:
perl/build [work_dir]
When set, work_dir indicates that installations should be done "from within"
the specific directory. To do this, work_dir is created as a symlink to
src_dir (i.e. the content of envile DIBS_DIR_SRC) and then the rest of
operations performed from there. If not set, it defaults to the environment
variable DIBSPACK_PERL_APP or, as a fallback, the string /app.
The dibspack saves some configurations inside the target directory
(work_dir/src_dir) in file .profile/10.perl-env.sh (directory .profile
is the profile_dir). This is mainly aimed at setting the right paths for
executing the shipped Perl programs.
Other environment variables can influence the dibspack execution:
-
DIBSPACK_VERBOSE, when set to1(exactly) turns on verbose mode. -
DIBSPACK_SAVE_ENVcan be set to a path where the environment is saved (bothenvandset). If the variable is defined but it does not start with a slash, then the environment is saved inside directory/.build_env. -
DIBSPACK_SET_VERSION, when set to a non-empty string, triggers its saving inside the profile_dir inside file20.version-env.sh. -
CPANM_OPTSoptions passed to cpanm. -
DIBSPACK_CPANM_VERBOSEsets verbose mode when running cpanm. Defaults to--quiet. -
DIBSPACK_CPANM_TESTsets or disable testing of modules. Defaults to--notest.
The outcome of compilation is saved in the cache (i.e. the directory saved in
envile DIBS_DIR_CACHE), inside sub-directory perl/local.
This dibspack supports in the installation of OS-specific packages/prerequisites. It is invoked like this:
prereqs [--os OS] [-w|--workdir|--work-dir DIR] [step]
The source project is supposed to have a prereqs sub-directory, and have
executable files like this inside:
prereqs/
alpine.build
alpine.bundle
debian.build
debian.bundle
debian.some-other-step...
It works like this:
-
loads all enviles as environment variables;
-
it establishes the platform’s os based on command-line option
--os, environment variableDIBS_OS, or looking at theIDinside/etc/os-release; -
it establishes the work dir base on command-line option
--workdir(or its aliases), on environment variableDIBS_WORK_DIRor, as a fallback, on the contents of envileDIBS_DIR_SRC; -
it establishes a step name from the command line or from environment variable
DIBS_PREREQS(leaving it blank by default); -
it runs file
$work_dir/prereqs/$os.$stepif the step is defined, otherwise it run$work_dir/prereqs/$os.
This adds a simple handler for Procfile-like configurations support. This
means that it’s possible to put a Procfile file inside the application
directory, and it will hopefully honored (it also requires to set the
associated program as the entry point of the generated container image).
This dibspack is controlled by environment variables (or enviles, all of them are loaded) with sensible defaults:
-
DIBSPACK_PROCFILE_DEFAULT: sets the default process to run, defaults toweb. -
DIBSPACK_PROCFILE_RUNNER: sets the name of the runner inside the container, defaults to/procfilerun. -
DIBSPACK_PROCFILE_SPEC: sets the position of theProcfilefile, defaults to/app/Procfile.
As anticipated, to use this dibspack effectively it is necessary to ensure
that the dibs.yml configuration file sets the right entry point and command
while saving the image, like this:
packs:
foo:
type: git
origin: https://github.com/polettix/dibspack-basic
actions:
bundle:
- from: 'some-image:latest'
- name: add procfile
pack: foo
path: procfile/add
commit:
entrypoint: ['/procfilerun']
cmd: []
- tags: 'new-image:1.0'
# ...
This dibspack is a swiss-army knife that allows running multiple shell commands. It is invoked like this:
shellrun [command1 [command2 [...]]]
Each argument is a shell command that is run "plainly". For example, if the
argument is echo ciao a tutti, then the following is executed:
echo ciao a tutti
and so on.
Example usage:
packs:
foo:
type: git
origin: https://github.com/polettix/dibspack-basic
actions:
foobar:
path: shellrun
args:
- "printf '%s\n' 'whatever you want'"
- 'ls -l /'
# ...
For simplicity, all standard output is redirected to standard error, so that
execution of command appears in the run log of dibs.
Within wrapexec, this is actually the only dibspack. Its goal is to put
other programs in wrapexec inside the root directory of the target container
image, so that it can be later used.
Just pass the list of the other programs to install in the args.
Example usage:
packs:
foo:
type: git
origin: https://github.com/polettix/dibspack-basic
actions:
foobar:
path: wrapexec/install
args:
- procexec
- suexec
This is a wrapper intended for inclusion inside the target container image. It’s easier to read what it does directly:
if [ -r "$HOME/.profile" ] ; then
. "$HOME/.profile"
elif [ -d "$HOME/.profile.d" ] ; then
for file in "$HOME"/.profile.d/*.sh ; do
. "$file"
done
fi
exec "$@"
It ensures that either $HOME/.profile or whatever is in $HOME/.profile.d
is sourced before running the real command that is passed on the command
line. This allows saving pre-condition stuff (like environment variables) in a
file or a bunch of files, then set the program as the entrypoint.
Example:
packs:
foo:
type: git
origin: https://github.com/polettix/dibspack-basic
actions:
install-procexec:
path: wrapexec/install
args:
- procexec
some-sketch:
# ...
- name: some final stroke
# ...
commit:
entrypoint: ['/procexec']
cmd: ['/bin/sh', '-l']
Now, whatever you pass as the command when running this container, will be
actually executed through procexec.
When building container images to distribute software for the command line, many times there’s a mismatch between the user that the software runs as within the container and the user that runs the container from the host.
wrapexec/suexec is meant to address the mismatch. It’s intended to be
included inside the container image (e.g. through wrapexec/install) and then
invoked by default setting it as the entrypoint, like this:
packs:
foo:
type: git
origin: https://github.com/polettix/dibspack-basic
actions:
install-procexec:
path: wrapexec/install
args:
- procexec
some-sketch:
# ...
- name: some final stroke
# ...
commit:
entrypoint: ['/suexec', '--reference', '/mnt', '--']
cmd: ['/bin/sh', '-l']
In this example, suexec sets the user and group to match the owner of
/mnt, so that when the container is run like this:
$ docker run -v "$PWD:/mnt" ...
the user that the command will be run as is the same as the owner of $PWD in
the host.
The generic invocation of wrapexec/suexec is as follows:
/suexec [options] -- command [arguments]
Options are:
--also|-agroup-
add group to the list of additional groups for the target user
--also-for|-Apath-in-container-
add the group associated to file at path-in-container to the list of additional groups for the target user
--gid|-Ggroup-id-
set the main group identifier for the target user (defaults to environment variable
GROUP_ID) --group|-ggroup-name-
set the main group name for the target user (defaults to environment variable
GROUP_NAME) --home|-h-
set the home directory path (defaults to environment variable
HOME_DIR); --osos-name-
set the name of the Linux distribution. This is used to figure out which tools are available for manipulating
/etc/passwdand/etc/group(defaults to environment variableOSor is auto-detected) --reference|-rpath-in-container-
set the user identifier and group identifier from the owner and group of the file at path-in-container. When you bind-mount a directory in the container, this is probably the most straightforward way to set the proper
uid/gidpair for the user that should run thecommandinside the container. --source|-spath-in-container-
source (via
.) the file at path-in-container, which might e.g. contain a few environment variables to set different defaults --uid|-Uuser-id-
set the user identifier for the target user (defaults to environment variable
USER_ID) --user|-uuser-name-
set the user name for the target user (defaults to environment variable
USER_NAME)
After analyzing command-line options, the program tries its best to figure out the missing parts, e.g. a username or a main group name.
After setting up the container with the options above, wrapexec/suexec runs
su-exec with the provided command and arguments. This allows
executing the command with the right user, while at the same time doing a
proper exec instead of putting any process in the middle (thus also
guaranteeing that the exit code of command is correctly propagated as the
return value from the container).
You have to "independently" ensure that su-exec is present in the
container image. As an example, {Alpine Linux}[alpine] includes the su-exec
package for it.