acbuild is a command line utility to build and modify App Container images (ACIs).
Dockerfiles are powerful and feature useful concepts such as build layers, controlled build environment. At the same time, they lack flexibility (impossible to extend, re-use environment variables) and don't play nicely with the app spec and Linux toolchain (e.g. shell, makefiles)
This proposal introduces the concept of a command-line build tool, acbuild,
that natively supports ACI builds and integrates well with shell, makefiles and
other Unix tools.
acbuild requires a handful of commands be available:
systemd-nspawncpmountmodprobetar
Currently the only way to install acbuild is to build the program from
source. Follow these steps to do so:
- Grab the source code for
acbuildbygit cloneing the source repository:
cd ~
git clone git@github.com:appc/acbuild
- Run the
buildscript from the root source repository directory:
cd acbuild
./build
- A
bin/directory will be created that contains theacbuildtool. To make sure your shell can find this executable, append this directory to your environment's$PATHvariable. You can do this in your.bashrcor similar file, for example:
vi ~/.bashrc
and put the following lines at the end of the file:
export ACBUILD_BIN_DIR=~/acbuild/bin
export PATH=$PATH:$ACBUILD_BIN_DIR
A build with acbuild is explicitly started with begin and finished with
end. While a build is in progress the current ACI is stored expanded in the
current working directory at .acbuild.tmp. A build can be started with an
empty ACI, or an initial ACI can be provided.
The following commands are supported:
-
acbuild beginBegin a build.
-
acbuild end ACI_PATHEnd a build, writing the resulting ACI to
ACI_PATH. -
acbuild abortAbort the current build, throwing away any changes since
beginwas called. -
acbuild annotation add NAME VALUEUpdates the ACI to contain an annotation with the given name and value. If the annotation already exists, its value will be changed.
-
acbuild annotation remove NAMERemoves the annotation with the given name from the ACI.
-
acbuild dependency add IMAGE_NAME --image-id sha512-... --label env=canaryUpdates the ACI to contain a dependency with the given name. If the dependency already exists, its values will be changed.
-
acbuild dependency remove IMAGE_NAMERemoves the dependency with the given image name from the ACI.
-
acbuild environment add NAME VALUEUpdates the ACI to contain an environment variable with the given name and value. If the variable already exists, its value will be changed.
-
acbuild environment remove NAMERemoves the environment variable with the given name from the ACI.
-
acbuild label add NAME VALUEUpdates the ACI to contain a label with the given name and value. If the label already exists, its value will be changed.
-
acbuild label remove NAMERemoves the label with the given name from the ACI.
-
acbuild mount add NAME PATHUpdates the ACI to contain a mount point with the given name and path. If the mount point already exists, its path will be changed.
-
acbuild mount remove NAMERemoves the mount point with the given name from the ACI.
-
acbuild port add NAME PROTOCOL PORTUpdates the ACI to contain a port with the given name, protocol, and port. If the port already exists, its values will be changed.
-
acbuild port remove NAMERemoves the port with the given name from the ACI.
-
acbuild copy PATH_ON_HOST PATH_IN_ACICopy a file or directory from the local filesystem into the ACI.
-
acbuild run CMD [ARGS]Run a given command in the ACI.
-
acbuild set-name ACI_NAMEChanges the name of the ACI in its manifest.
-
acbuild set-group GROUPSet the group the app will run as inside the container.
-
acbuild set-user USERSet the user the app will run as inside the container
-
acbuild set-exec CMD [ARGS]Sets the exec command in the ACI's manifest.
acbuild run builds the root filesystem with any dependencies the ACI has
using overlayfs, and then executes the given command using systemd-nspawn. The
current ACI being built is the upper level in the overlayfs, and thus modified
files that came from the ACI's dependencies will be copied into the ACI. More
information on this behavior is available
here.
acbuild run requires overlayfs if the ACI being operated upon has
dependencies.
acbuild run also requires root.
There are scenarios in which it is not convenient to need to call begin and
end, the most obvious being when a single change is made to an existing ACI.
A flag will be added to allow every subcommand to be performed on a given ACI,
instead of looking for a current build in progress.
It would be convenient if the appropriate gpg keys could be passed into acbuild end, and a ASC file would then be produced in addition to the ACI file.
acbuild squash: fetch all the dependencies for the given image and squash them
together into the ACI without dependencies.
Pass in an image name, instead of a path to the ACI for acbuild begin, and the
image will be fetched and used as the starting point for the build.
Support multiple execution engines, notably runc.
Use apt-get to install nginx.
acbuild begin
acbuild add-dep quay.io/fermayo/ubuntu
acbuild run -- apt-get update
acbuild run -- apt-get -y install nginx
acbuild end ubuntu-nginx.aci
- https://github.com/sgotti/baci
- https://github.com/appc/spec/tree/master/actool - particularly the
buildandpatch-manifestsubcommands.acbuildmay subsume such functionality, leavingactoolas a validator only.