Images can be imported from files or URLs, using the image import command:
jetpack image import AMI
jetpack image import ROOTFS MANIFEST
The parameters should be either URLs pointing directly at archives, or
filesystem paths. The contents are retrieved using fetch(1) command.
AMI should point at Application Manifest Image that contains rootfs
and manifest, as described in the Application Container Specification
(caveat: the dependencies are not supported).
Alternatively, ROOTFS can point to a tar archive (which may be
compressed with gzip, bzip2, or xz) of the root filesystem, and
MANIFEST can point at raw JSON manifest.
An existing image can be used to build a derivative image. The low-level mechanism is the image build command:
jetpack image BASE-IMAGE build [-dir=PATH] [-cp=PATH [-cp-PATH [...]]] COMMAND ARGS...
The build process is:
- Create a new container (the build container) from
BASE-IMAGE. - Copy the build directory (by default it is the current directory,
but a different one can be provided with the
-dir=PATHoption) to a working directory inside the container. The working directory is a newly created temporary directory with a unique name, created in the container's filesystem root. - Copy any additional files (specified by
-cp=PATHoption, which can be provided multiple times) to the working directory. - Run the build container, executing
COMMAND ARGS...(the build command) as root in the work directory. - Copy the
manifest.jsonfile from the work directory as a new image's manifest. This way, if the manifest is static, it can be simply a part of the build directory - but it can be generated or modified by the build command as well. The build command can fill in image's version label by inspecting version of the package it has installed or add other annotations. For example, thefreebsd-baseimage uses this to include release patchlevel in the version number. The manifest is merged with some defaults (acKind,acVersion, timestamp annotation,osandarchlabels from parent image), so the manifest doesn't need to include everything. - Remove the work directory from the build container.
- Save the build container's rootfs + manifest from previous step as the new image, removing the build container in the process.
A Make macro file, jetpack.image.mk, is provided to automate the
process and wrap the common pieces. It is in share/ subdirectory of
this repository, and is installed as
/usr/local/share/jetpack/jetpack.image.mk. The example images in the
images/ subdirectory use these macros.
There are three "wildcard targets": prepare, build, and
clean. Each of these is defined, but does not have any commands
associated, so any dependencies or commands can be added in the
Makefile. Each of them will also automatically depend on any task that
starts with its name and a dot. For example, if you define targets
clean.something and clean.something_else, the clean target will
depend on them.
The basic structure of image Makefile is:
# Add sharedir (/usr/local/share/jetpack for system-wide
# installation, ./share for in-place build) to the include path.
.MAKEFLAGS: -I${/path/to/sharedir:L:tA}
VARIABLES = values
targets:
commands
# Include Jetpack macros. They need to be at the end.
.include "jetpack.image.mk"
You can specify JETPACK=jetpack-command when running make, to
specify location of the jetpack binary if it's not in $PATH, or to
call jetpack with sudo (JETPACK='sudo path/to/jetpack').
The default Make target is image. It depends on wildcard target
prepare. Makefile can define commands and dependencies for the
prepare task, or define prepare.* tasks that prepare will
automatically depend on.
The image task itself, after prepare, will:
- run
${JETPACK} image import …ifIMPORT_FILEorIMPORT_URLis defined (see Importing Images for details), or - run
${JETPACK} image ${PARENT_IMAGE} build …ifPARENT_IMAGEis defined (see Building Images for details), or - raise an error if neiter import file/url, nor parent image is defined.
Run make clean to clean up the build directory.
Makefile can define commands for the clean target, some extra
clean.* targets, or add file names to the CLEAN_FILES
variable. This concerns only build directory on host, the work
directory in the container is always removed.
See the images/freebsd-release.base/Makefile file for a complete
example. Most of the time, only some variables need to be defined:
IMPORT_FILEwill specify a file to import (AMI or rootfs). The file can be provided in the build dir, or can be created by Makefile.IMPORT_MANIFEST-- ifIMPORT_FILEis a rootfs tarball, it specifies location of the manifest file.IMPORT_URL-- if specified, Makefile will downloadIMPORT_FILEfrom that URL. IfIMPORT_URLis defined, andIMPORT_FILEis not defined, theIMPORT_FILEwill be extracted automatically from theIMPORT_URL.IMPORT_SHA256-- a checksum to verify download fromIMPORT_URL.
The Makefile can also include detailed instructions on how to get the
IMPORT_FILE. For example:
IMPORT_FILE = secret.aci
CLEAN_FILES = secret.aci.gpg secret.aci
secret.aci: secret.aci.gpg
gpg --decrypt --output $@ secret.aci.gpg
secret.aci.gpg:
scp secret.login@secret.location:/path/to/secret.aci.gpg $@
side note: the
jetpack.image.mkitself uses wildcard targets internally. IfIMPORT_URLis defined:IMPORT_FILEis automatically defined if not set by user; a${IMPORT_FILE}target is added that downloads from${IMPORT_URL}; aprepare..import_filetarget (with double dot to avoid conflicts with user's Makefile), depending on${IMPORT_FILE}, checks${IMPORT_SHA256}. Thepreparetarget automatically depends onprepare..import_file.
If PARENT_IMAGE variable is defined, the image target will run:
${JETPACK} image ${PARENT_IMAGE} build ${BUILD_COMMAND} ${BUILD_ARGS}
If BUILD_COMMAND haven't been redefined by user, it is make .jetpack.build., so the process wraps back into the Makefile. The
.jetpack.build. target calls the build wildcard target (which
should prepare the image), and then manifest.json to ensure that the
manifest file exists, and give Make a chance to build it. The
following variables can be used to modify this process:
BUILD_DIRcan specify a build directory other than..BUILD_CPcan specify a list of files to copy to the work directory. By default, thejetpack.image.mkitself is added to this list, so that.include "jetpack.image.mk"works inside the container. To prevent that, setBUILD_CP_JETPACK_IMAGE_MK=no.BUILD_VARScan specify list of Make (or environment) variables that will be added toBUILD_ARGS. For example, ifBUILD_VARSincludeshttp_proxy, and ahttp_proxyvariable is defined,http_proxy=${http_proxy}will be added toBUILD_ARGS.BUILD_ARGScan specify additional targets or variables for Make (or for the customized${BUILD_COMMAND}).PKG_INSTALLcan specify list of packages to install withpkg install(if it is defined, abuild..pkg-installtarget will be defined).