Utils¶
Some helper shell and Python utilities are available in utils/bin and
utils/pyHDLC, respectively.
A utils/setup.sh script is provided for installing Python dependencies and adding the bin
subdir to the PATH
.
Since pip
is used for installing utils/pyHDLC/requirements.txt, it is
desirable to create a virtual environment (docs.python.org/3/library/venv)
before running setup.sh
:
virtualenv venv
source venv/bin/activate
./utils/setup.sh
pyHDLC¶
Helper tool for building one or multiple images, for easily browsing publicly available tags, and for generating graphs showing the dependencies between them.
usage: pyHDLC [-n] {help,jobs,pull,build,test,push} ...
Happy hacking!
options¶
- -n, --noexec¶
Print commands but do not execute them.
pyHDLC build¶
Build one or multiple images (and optionally test them) at once, reusing common parameters.
Important
DOCKERFILE defaults to Image if None.
usage: pyHDLC build [-h] [-a ARCHITECTURE] [-c COLLECTION] [-r REGISTRY]
[-f DOCKERFILE] [-t TARGET] [-i ARGIMG] [-p] [-d] [-q]
Image [Image ...]
- image¶
Image name(s), without registry prefix.
- -h, --help¶
show this help message and exit
- -a <architecture>, --arch <architecture>¶
Name of the architecture.
- -c <collection>, --collection <collection>¶
Name of the collection/subset of images.
- -r <registry>, --registry <registry>¶
Container image registry prefix.
- -f <dockerfile>, --dockerfile <dockerfile>¶
Dockerfile to be built, from the collection.
- -t <target>, --target <target>¶
Target stage in the dockerfile.
- -i <argimg>, --argimg <argimg>¶
Base image passed as an ARG to the dockerfile.
- -p, --pkg¶
Preprend ‘pkg/’ to Image and set Target to ‘pkg’ (if unset).
- -d, --default¶
Set default Dockerfile, Target and ArgImg options, given the image name(s).
- -q, --test¶
Test each image right after building it.
pyHDLC help¶
usage: pyHDLC help [-h] [Command]
- command¶
Print help page(s) for a command.
- -h, --help¶
show this help message and exit
pyHDLC jobs¶
Generate list of jobs for a named task.
usage: pyHDLC jobs [-h] [-f {gha,GHA}] Name
- name¶
Identifier to extract jobs from the YAML configuration file.
- -h, --help¶
show this help message and exit
- -f {gha,GHA}, --format {gha,GHA}¶
Output format (by default, print GitHub Actions’ set-output syntax).
pyHDLC pull¶
Pull container image(s) from registry.
usage: pyHDLC pull [-h] [-a ARCHITECTURE] [-c COLLECTION] [-r REGISTRY]
Image [Image ...]
- image¶
Image name(s), without registry prefix.
- -h, --help¶
show this help message and exit
- -a <architecture>, --arch <architecture>¶
Name of the architecture.
- -c <collection>, --collection <collection>¶
Name of the collection/subset of images.
- -r <registry>, --registry <registry>¶
Container image registry prefix.
pyHDLC push¶
Push container image(s) to registry/registries.
usage: pyHDLC push [-h] [-a ARCHITECTURE] [-c COLLECTION] [-r REGISTRY]
[-m [MIRROR ...]]
Image [Image ...]
- image¶
Image name(s), without registry prefix.
- -h, --help¶
show this help message and exit
- -a <architecture>, --arch <architecture>¶
Name of the architecture.
- -c <collection>, --collection <collection>¶
Name of the collection/subset of images.
- -r <registry>, --registry <registry>¶
Container image registry prefix.
- -m <mirror>, --mirror <mirror>¶
List of additional registry/registries to push to. Supported placeholders: #A (architecture), #C (collection).
pyHDLC test¶
Test container image(s).
Important
The supported syntax for each Image is name[#<DirName>]
, where the optional <DirName>
is used as the location in
package images to copy the content from.
usage: pyHDLC test [-h] [-a ARCHITECTURE] [-c COLLECTION] [-r REGISTRY]
Image [Image ...]
- image¶
Image name(s), without registry prefix.
- -h, --help¶
show this help message and exit
- -a <architecture>, --arch <architecture>¶
Name of the architecture.
- -c <collection>, --collection <collection>¶
Name of the collection/subset of images.
- -r <registry>, --registry <registry>¶
Container image registry prefix.
Smoke-tests¶
There is a test script in test/ for each image in this ecosystem, according to the following convention:
Scripts for package images,
/[ARCHITECTURE/][COLLECTION/]pkg/TOOL_NAME[/SUBNAME]
, are namedTOOL_NAME[--SUBNAME].pkg.sh
.Scripts for other images,
/[ARCHITECTURE/][COLLECTION/]NAME[/SUBNAME]
, are namedNAME[--SUBNAME].sh
.Other helper scripts are named
_*.sh
.
Furthermore, gh:hdl/smoke-tests is a submodule of this repository (test/smoke-tests). Smoke-tests contains fine-grained tests that cover the most important functionalities of the tools. Those are used in other packaging projects too. Therefore, container tests are expected to execute the smoke-tests corresponding to the tools available in the image, before executing more specific tests.
pyHDLC test
allows testing the runnable and package images.
It is used in CI but can be useful locally too.
When using pyHDLC test, DirName
allows to optionally specify the name of the directory inside the package image
which needs to be copied to the temporary image for testing.
By default, the escaped name of the image is used as the location.
Inspect¶
All ready-to-use images (coloured GREEN or BROWN in the Graphs) are
runnable.
Therefore, users/contributors can run containers and test the tools interactively or through scripting.
However, since pkg
images are not runnable, creating another image is required in order to inspect their content
from a container.
For instance:
FROM busybox
COPY --from=REGISTRY/pkg/TOOL_NAME /TOOL_NAME /
In fact, pyHDLC test
uses a similar dockerfile for running .pkg.sh
scripts from test/.
See Test.
Alternatively, or as a complement, gh:wagoodman/dive is a lightweight tool with a nice terminal based GUI for exploring layers and contents of container images. It can be downloaded as a tarball/zipfile, or used as a container:
docker run --rm -it \
-v //var/run/docker.sock://var/run/docker.sock \
wagoodman/dive \
REGISTRY/[ARCHITECTURE/][COLLECTION/]IMAGE[:TAG]
dockerDive is a wrapper around the wagoodman/dive container, which supports one
or two arguments for specifying the image to be inspected.
The default registry prefix is gcr.io/hdl-containers
, however, it can be overriden through envvar HDL_REGISTRY
.
For instance, inspect image gcr.io/hdl-containers/debian/bullseye/ghdl
:
dockerDive debian/bullseye ghdl
or, inspect any image from any registry:
HDL_REGISTRY=docker.io dockerDive python:slim-bookworm
YAML Configuration File¶
Most of the complexity regarding images, dockerfiles, arguments and jobs is defined in the YAML configuration file (see config.yml), which contains two data fields:
defaults: which dockerfile and (optionally) target stage or base image to be used when building “non-regular” images. That is, using a non-empty target, an specific base image, etc. If the image name is not defined in this field, the dockerfile defaults to the image name and the target depends on option package.
jobs: which images and for which collections and architectures to build each list of tasks. For convenienve, the keywords match the name of the main tool/group in the list.
Tip
Contributors will find that field anchors in config.yml is ignored by pyHDLC commands when analyzing the file. That’s because anchors are used to reduce the verbosity of the YAML file, but they are resolved by the loader.
The fields and types supported in the configuration file are defined through dataclasses (see Dataclasses). However, some details about the syntax can be non-obvious. See the clarifications below:
Defaults¶
If the following conditions are met, images need not to be explicitly listed in the configuration file:
The dockerfile to be used matches the image name.
The default target is empty, or
pkg
if a package image is being built.The
argimg
is empty.
Otherwise, a dictionary is expected, with the fields that need to be overriden (dockerfile
, target
and/or
argimg
).
Jobs¶
There are four kinds of job lists:
default: two images are built for each collection and architecture, a regular image and a package image.
pkgonly: a package image is built for each collection and architecture.
runonly: a regular image is built for each collection and architecture.
custom: the lists of jobs/tasks are declared as cross-products, and
exclude
is supported.
In default, pkgonly and runonly, a dictionary of lists is expected per keyword; each key corresponding to a collection and the lists specifying the architectures. Conversely, in custom three fields are expected:
sys: a dictionary of lists, such as the one expected in default, pkgonly and runonly.
images: either a list or a list of lists of image names.
If a single list is provided, all images are built sequentially in a single job:
images: - formal/min - formal - formal/all
If a list of lists is provided, each of them is built sequentially in a different job:
images: - [ conda/f4pga/xc7/a50t ] - [ conda/f4pga/xc7/a100t ] - [ conda/f4pga/xc7/a200t ]
Argument substitution is supported through
${arg}
. If any of the items in the list is a dictionary, instead of a string, it is used as an argument in the substitution phase. If the same argument is provided multiple times, a cross-product of the arguments and the lists is produced:images: - sim/${prj}-slim - sim/${prj} - prj: scipy - prj: octave
images: - pkg/nextpnr/${arch} - nextpnr/${arch} - nextpnr/${prj} - { arch: ice40, prj: icestorm } - { arch: ecp5, prj: prjtrellis }
exclude: optionally, declare combinations of sys and images which should be excluded from the produced cross-products. For example:
images: - pkg/nextpnr/${arch} - nextpnr/${arch} - nextpnr/${prj} - { arch: ecp5, prj: prjtrellis } - { arch: nexus, prj: prjoxide } sys: *SysDebianAmd64 exclude: - sys: { debian/buster: [amd64] } params: { arch: nexus, prj: prjoxide }