Developer Guide
Deploy for development
This project uses pip to manage the package. If you want to work on the project yourself you can create the necessary links via:
$ pip3 install --user -e .
That will install a backlink ~/.local/bin/kas to this project. Now you are
able to call it from anywhere.
For local development, use the run-kas wrapper from the project root
directory. In this case, replace kas with path/to/run-kas.
Changes of the project configuration
When changing the project configuration, you need to update the json
configuration schema (schema-kas.json). Further, a short description of
the changes needs to be added to Configuration Format Changes.
After making the changes, you need to update the minimum and maximum values
of header.version. If the version was already updated after the last
release, the version bump is not required.
Add a new sub-command (plugin)
To add a new sub-command, you need to create a new python file in the
kas/plugins directory. It then needs to be imported and registered
in kas/plugins/__init__.py. Further, it needs to be registered in
kas-container, as well as in the container-entrypoint.
Each sub-command must be documented and have its own man page. The
documentation is generated from the docstrings of the sub-command file and
must be registered in docs/userguide/plugins.rst. In addition, a manpage
should be added in docs/_man/kas-plugin-<name> and registered in
docs/conf.py (as kas-<name>.1).
Container image build
To build the container images kas provides, there is a script provided for your convenience. It uses docker buildx and requires BuildKit 0.13.0 or newer. To start the build both container variants, invoke:
$ scripts/build-container.sh
You can limit the target type to either Yocto/OE (kas) or isar
(kas-isar) via the --target options. See the script help for more
options.
Since release 4.3, the containers officially provided via ghcr.io are fully reproducible. To test this, you can use the following script, e.g. to validate that release:
$ scripts/reproduce-container.sh kas:4.3
Both scripts also support building/checking of the arm64 container images. See the help of both scripts for more details.
Testing
The kas project has an extensive test suite. When adding new features or fixing
bugs, it is recommended to add a test. The tests are written using the pytest
framework. Please make sure to decouple the tests from your local environment.
To simplify this, we provide the monkeykas fixture to clean up the
environment prior to each test. When adding new kas environment variables,
make sure to add these to the cleanup handler as well.
Note
The menu plugin tests require the snack package to be installed. On
most distros this is packaged in python3-newt, on Arch Linux it is
part of libnewt.
To run the tests, invoke:
$ python3 -m pytest
Online and offline testing
Some tests require internet access to fetch resources. These tests are marked
with the online marker. To run these tests, invoke:
$ python3 -m pytest -m online
To run all tests except the online tests, invoke:
$ python3 -m pytest -m "not online"
When adding new tests, please consider whether they require internet access or not and mark them accordingly. In general, we prefer offline tests.
Measure code coverage
To measure the code coverage of the unit tests, the pytest-cov package is
required. On Debian systems, this is provided in python3-pytest-cov.
Once installed, run:
$ python3 -m pytest --cov --cov-report html
The coverage in HTML format can then be found in htmlcov.
Community Resources
Project home:
Source code:
git@github.com:siemens/kas.git
Documentation:
Mailing list:
Class reference documentation
kas.kas Module
This module is the main entry point for kas, setup tool for bitbake based
projects. In case of user errors (e.g. invalid configuration, repo fetch
failure) kas exits with error code 2, while exiting with 1 for internal
errors. When cancelled by SIGINT, kas exits with 130. For details on error
handling, see kas.kasusererror.
- class kas.kas.ArgumentChoicesHelpFormatter(prog, indent_increment=2, max_help_position=24, width=None)[source]
Help message formatter which adds choices to argument help.
If the default METAVAR is used, this will do nothing, as the default METAVAR shows the available choices already. If the METAVAR is overridden, and %(choice)s is not present in the help string, add them.
kas.libkas Module
This module contains the core implementation of kas.
- exception kas.libkas.EnvNotValidError[source]
The caller environment is not suited for the requested operation
- class kas.libkas.ExtendConstAction(option_strings, dest, const, default=None, required=False, help=None, metavar=None)[source]
Add an ‘extend_const’ action similar to ‘append_const’.
Based on the existing ‘append_const’ and ‘extend’ actions.
- exception kas.libkas.InitBuildEnvError[source]
Error related to the OE / ISAR environment setup scripts
- exception kas.libkas.TaskExecError(command, ret_code)[source]
Similar to
kas.kasusererror.CommandExecErrorbut for kas internal tasks
- kas.libkas.find_program(paths, name)[source]
Find a file within the paths array and returns its path.
- kas.libkas.repos_apply_patches(repos)[source]
Applies the patches to the repositories.
Note
termination point of the asyncio event loop.
- kas.libkas.repos_fetch(repos)[source]
Fetches the list of repositories to the kas_work_dir.
Note
termination point of the asyncio event loop.
kas.libcmds Module
This module contains common commands used by kas plugins.
- class kas.libcmds.CleanupSSHAgent[source]
Removes all the identities and stops the ssh-agent instance.
- class kas.libcmds.Macro(use_common_setup=True)[source]
Contains commands and provides method to run them.
- class kas.libcmds.ReposApplyPatches[source]
Applies the patches defined in the configuration to the repositories.
- class kas.libcmds.ReposCheckout[source]
Ensures that the right revision of each repo is checked out.
kas.config Module
This module contains the implementation of the kas configuration.
- class kas.config.Config(ctx, filename, target=None, task=None)[source]
Implements the kas configuration based on config files.
- get_artifacts(missing_ok=True)[source]
Returns the found artifacts after glob expansion, relative to the build_dir as a list of tuples (name, path). If missing_ok=False, raises an ArtifactNotFoundError if no artifact for a given name is found.
kas.repos Module
This module contains the Repo class.
- class kas.repos.GitRepo(name, url, path, commit, tag, branch, refspec, layers, patches, disable_operations)[source]
Provides the git functionality for a Repo.
- class kas.repos.MercurialRepo(name, url, path, commit, tag, branch, refspec, layers, patches, disable_operations)[source]
Provides the hg functionality for a Repo.
- class kas.repos.Repo(name, url, path, commit, tag, branch, refspec, layers, patches, disable_operations)[source]
Represents a repository in the kas configuration.
- static factory(name, repo_config, repo_defaults, repo_fallback_path, repo_overrides={})[source]
Returns a Repo instance depending on params. This factory function is referential transparent.
- class kas.repos.RepoImpl(name, url, path, commit, tag, branch, refspec, layers, patches, disable_operations)[source]
Provides a generic implementation for a Repo.
kas.includehandler Module
This module implements how includes of configuration files are handled in kas.
- exception kas.includehandler.IncludeException[source]
Class for exceptions that appear in the include mechanism.
- class kas.includehandler.IncludeHandler(top_files, top_repo_path, use_lock=True)[source]
Implements a handler where every configuration file should contain a dictionary as the base type with and ‘includes’ key containing a list of includes.
The includes can be specified in two ways: as a string containing the path, relative to the repository root from the current file, or as a dictionary. The dictionary must have a ‘file’ key containing the path to the include file and a ‘repo’ key containing the key of the repository. The path is interpreted relative to the repository root path.
The includes are read and merged from the deepest level upwards.
In case
use_lockisTrue, kas checks if a file<file>.lock.<ext>exists next to the first entry intop_files. This filename is then appended to the list oftop_files.
kas.kasusererror Module
This module provides a common base class for all exceptions which are related to user or configuration errors. These exceptions should be caught and reported to the user using a meaningful message instead of a stacktrace.
When handling errors in KAS, never return directly using sys.exit,
but instead throw an exception derived from KasUserError (for user
errors), or one derived from Exception for internal errors. These
are then handled centrally, mapped to correct return codes and pretty
printed.
- exception kas.kasusererror.ArgsCombinationError(message)[source]
Invalid combination of CLI arguments provided
- exception kas.kasusererror.ArtifactNotFoundError(name, artifact)[source]
A configured artifact is not found (or the glob matches 0 elements).
- exception kas.kasusererror.CommandExecError(command, ret_code, forward_ret_code=False)[source]
Failure in execution of a shell command. The forward_error_code parameter can be used to request the receiver of the exception to sys.exit with that code instead of a generic one. Only use this in special cases, where the return code can actually be related to a single shell command.
kas.plugins Module
This module contains and manages kas plugins