API Documentation

bci_build module

bci_build.package module

class bci_build.package.ApplicationStackContainer(name: 'str', os_version: 'OsVersion', pretty_name: 'str', package_name: 'str | None' = None, from_image: 'str | None' = '', from_target_image: 'str | None' = None, exclusive_arch: 'list[Arch] | None' = None, is_latest: 'bool' = False, is_singleton_image: 'bool' = False, entrypoint: 'list[str] | None' = None, entrypoint_user: 'str | None' = '', cmd: 'list[str] | None' = None, volumes: 'list[str] | None' = None, exposes_ports: 'list[NetworkPort] | None' = None, env: 'dict[str, str | int] | dict[str, str] | dict[str, int]' = <factory>, build_flavor: 'str | None' = None, crate: 'ContainerCrate' = None, replacements_via_service: 'list[Replacement]' = <factory>, extra_labels: 'dict[str, str]' = <factory>, package_list: 'list[str] | list[Package]' = <factory>, custom_end: 'str' = '', build_stage_custom_end: 'str | None' = None, buildcounter_synctag: 'str | None' = None, config_sh_script: 'str' = '', config_sh_interpreter: 'str' = '/bin/bash', oci_authors: 'str | None' = None, extra_files: 'dict[str, str | bytes] | dict[str, bytes] | dict[str, str]' = <factory>, additional_names: 'list[str]' = <factory>, custom_labelprefix_end: 'str' = '', custom_description: 'str' = '', build_recipe_type: 'BuildType | None' = None, kiwi_ignore_packages: 'list[str] | None' = None, license: 'str' = 'MIT', support_level: 'SupportLevel' = <SupportLevel.TECHPREVIEW: 'techpreview'>, supported_until: 'datetime.date | None' = None, no_recommends: 'bool' = True, logo_url: 'str' = '', _min_release_counter: 'int | None' = None, _publish_registry: 'Registry | None' = None, version: 'str | int' = '', tag_version: 'str | None' = None, stability_tag: 'str | None' = None, additional_versions: 'list[str]' = <factory>, version_in_uid: 'bool' = True)
property eula: str

SLE BCI Application containers are non-redistributable by default.

property image_type: ImageType

Define the value of the com.suse.image-type label.

property registry_prefix: str
property title: str

The image title that is inserted into the org.opencontainers.image.title label.

It is generated from BaseContainerImage.pretty_name as follows: "{distribution_base_name} BCI {self.pretty_name}", where distribution_base_name is taken from distribution_base_name.

class bci_build.package.BaseContainerImage(name: str, os_version: ~bci_build.os_version.OsVersion, pretty_name: str, package_name: str | None = None, from_image: str | None = '', from_target_image: str | None = None, exclusive_arch: list[~bci_build.container_attributes.Arch] | None = None, is_latest: bool = False, is_singleton_image: bool = False, entrypoint: list[str] | None = None, entrypoint_user: str | None = '', cmd: list[str] | None = None, volumes: list[str] | None = None, exposes_ports: list[~bci_build.container_attributes.NetworkPort] | None = None, env: dict[str, str | int] | dict[str, str] | dict[str, int] = <factory>, build_flavor: str | None = None, crate: ~bci_build.containercrate.ContainerCrate = None, replacements_via_service: list[~bci_build.package.Replacement] = <factory>, extra_labels: dict[str, str] = <factory>, package_list: list[str] | list[~bci_build.package.Package] = <factory>, custom_end: str = '', build_stage_custom_end: str | None = None, buildcounter_synctag: str | None = None, config_sh_script: str = '', config_sh_interpreter: str = '/bin/bash', oci_authors: str | None = None, extra_files: dict[str, str | bytes] | dict[str, bytes] | dict[str, str] = <factory>, additional_names: list[str] = <factory>, custom_labelprefix_end: str = '', custom_description: str = '', build_recipe_type: ~bci_build.container_attributes.BuildType | None = None, kiwi_ignore_packages: list[str] | None = None, license: str = 'MIT', support_level: ~bci_build.container_attributes.SupportLevel = SupportLevel.TECHPREVIEW, supported_until: ~datetime.date | None = None, no_recommends: bool = True, logo_url: str = '', _min_release_counter: int | None = None, _publish_registry: ~bci_build.registry.Registry | None = None)

Base class for all Base Containers.

additional_names: list[str]

Additional names under which this image should be published alongside name. These names are only inserted into the build_tags

property base_image_registry: str

The registry where the base image is available on.

build_flavor: str | None = None

build flavors to produce for this container variant

property build_name: str | None
build_recipe_type: BuildType | None = None

Define whether this container image is built using docker or kiwi. If not set, then the build type will default to docker from SP4 onwards.

property build_release: str | None
build_stage_custom_end: str | None = None

This string is appended to the the build stage in a multistage build and can contain arbitrary instructions valid for a Dockerfile.

abstract property build_tags: list[str]

All build tags that will be added to this image. Note that build tags are full paths on the registry and not just a tag.

property build_version: str | None
buildcounter_synctag: str | None = None

This string defines which build counter identifier should be used for this container. can be an arbitrary string is used to derive the checkin-counter. Defaults to the main package for packages with a flavor.

cmd: list[str] | None = None

An optional CMD for the image, it is omitted if empty or None

property cmd_docker: str | None
property cmd_kiwi: str | None
property config_sh: str

The full config.sh script required for kiwi builds.

config_sh_interpreter: str = '/bin/bash'

The interpreter of the config.sh script that is executed by kiwi during the image build. It defaults to /bin/bash and has no effect for Dockerfile based builds. Warning: Using a different interpreter than /bin/bash could lead to unpredictable results as kiwi’s internal functions are written for bash and not for a different shell.

config_sh_script: str = ''

A script that is put into config.sh if a kiwi image is created. If a Dockerfile based build is used then this script is prependend with a DOCKERFILE_RUN and added at the end of the Dockerfile. It must thus fit on a single line if you want to be able to build from a kiwi and Dockerfile at the same time!

crate: ContainerCrate = None

create that this container is part of

custom_description: str = ''

Provide a custom description instead of the automatically generated one

custom_end: str = ''

This string is appended to the automatically generated dockerfile and can contain arbitrary instructions valid for a Dockerfile.

Note

Setting both this property and config_sh_script is not possible and will result in an error.

custom_labelprefix_end: str = ''

By default the containers get the labelprefix {label_prefix}.bci.{self.name}. If this value is not an empty string, then it is used instead of the name after com.suse.bci..

property description: str

The description of this image which is inserted into the org.opencontainers.image.description label.

If BaseContainerImage.custom_description is set, then that value is used. Custom descriptions can use str.format() substitution to expand the custom description with the following options:

  • {pretty_name}: the value of the pretty_name property

  • {based_on_container}: the standard “based on the $distro Base Container Image” suffix that descriptions have

  • {podman_only}: “This container is only supported with podman.”

  • {privileged_only}: “This container is only supported in privileged mode.”

Otherwise it reuses BaseContainerImage.pretty_name to generate a description.

property dockerfile_custom_end: str

This part is appended at the end of the Dockerfile. It is either generated from BaseContainerImage.custom_end or by prepending RUN in front of BaseContainerImage.config_sh_script. The later implies that the script in that variable fits on a single line or newlines are escaped, e.g. via ansi escapes.

property dockerfile_from_line: str
property dockerfile_from_target_ref: str

Provide the reference for the target image if multistage build is used, empty string otherwise.

entrypoint: list[str] | None = None

An optional entrypoint for the image, it is omitted if empty or None If you provide a string, then it will be included in the container build recipe as is, i.e. it will be called via a shell as sh -c "MY_CMD". If your entrypoint must not be called through a shell, then pass the binary and its parameters as a list

property entrypoint_docker: str | None

The entrypoint line in a Dockerfile.

property entrypoint_kiwi: str | None
entrypoint_user: str | None = ''
env: dict[str, str | int] | dict[str, str] | dict[str, int]

Extra environment variables to be set in the container

property env_lines: str

Part of the Dockerfile that sets every environment variable defined in env.

property eula: str

EULA covering this image. can be sle-eula or sle-bci.

exclusive_arch: list[Arch] | None = None

Architectures of this image.

If supplied, then this image will be restricted to only build on the supplied architectures. By default, there is no restriction

property expose_dockerfile: str
property exposes_kiwi: str

The EXPOSES for this image as kiwi xml elements.

exposes_ports: list[NetworkPort] | None = None

An optional list of port exposes, it is omitted if empty or None.

extra_files: dict[str, str | bytes] | dict[str, bytes] | dict[str, str]

Additional files that belong into this container-package. The key is the filename, the values are the file contents.

property extra_label_lines: str

Lines for a Dockerfile to set the additional labels defined in BaseContainerImage.extra_labels.

property extra_label_xml_lines: str

XML Elements for a kiwi build description to set the additional labels defined in BaseContainerImage.extra_labels.

extra_labels: dict[str, str]
from_image: str | None = ''

The container from which the build stage is running. On SLE15, this defaults to suse/sle15:15.$SP for Application Containers and bci/bci-base:15.$SP for all other images. On openSUSE, opensuse/tumbleweed:latest is used when an empty string is used.

When from image is None, then this image will not be based on anything, i.e. the FROM line is missing in the Dockerfile.

from_target_image: str | None = None

The container that is used to install this image into. If this is not set, then only a single stage build is produced, otherwise a multistage build

abstract property image_ref_name: str

The immutable reference for this target under which this image can be pulled. It is used to set the org.opencontainers.image.ref.name OCI annotation and defaults to {self.build_tags[0]}.

abstract property image_type: ImageType

Define the value of the com.suse.image-type label.

property is_base_container_annotation_available: bool

return True if the obs-service-kiwi_metainfo_helper can provide base.name/digest annotations.

is_latest: bool = False

Determines whether this image will have the latest tag.

is_singleton_image: bool = False

Determines whether only one version of this image will be published under the same registry path.

property kiwi_additional_tags: str | None

Entry for the additionaltags attribute in the kiwi build description.

This attribute is used by kiwi to add additional tags to the image under it’s primary name. This string contains a coma separated list of all build tags (except for the primary one) that have the same name as the image itself.

property kiwi_derived_from_entry: str
property kiwi_env_entry: str

Environment variable settings for a kiwi build recipe.

kiwi_ignore_packages: list[str] | None = None

Define packages that should be ignored by kiwi in the creation of the final container image even if dependencies would otherwise pull them in.

property kiwi_packages: str

The package list as xml elements that are inserted into a kiwi build description file.

property kiwi_version: str
property labelprefix: str

The label prefix used to duplicate the labels. See https://en.opensuse.org/Building_derived_containers#Labels for further information.

This value is by default com.suse.bci.{self.name} for images of type ImageType.SLE_BCI and `com.suse.application.{self.name} for images of type ImageType.APPLICATION unless BaseContainerImage.custom_labelprefix_end is set. In that case self.name is replaced by custom_labelprefix_end.

license: str = 'MIT'

A license string to be placed in a comment at the top of the Dockerfile or kiwi build description file.

property lifecycle_url: str
logo_url: str = ''

URL to the logo of this container image. This value is added to the io.artifacthub.package.logo-url label if present

name: str

Name of this image. It is used to generate the build tags, i.e. it defines under which name this image is published.

no_recommends: bool = True

flag whether to not install recommended packages in the call to zypper in Dockerfile

oci_authors: str | None = None

The oci image author annotation for this image, defaults to SUSE/openSUSE

abstract property oci_version: str

The “main” version label of this image.

It is added as the org.opencontainers.image.version label to the container image.

os_version: OsVersion

The SLE service pack to which this package belongs

package_list: list[str] | list[Package]

Packages to be installed inside the container image

package_name: str | None = None
property packages: str

The list of packages joined so that it can be appended to a zypper in.

property packages_to_delete: str

The list of packages joined that can be passed to zypper -n rm after an install`.

abstract prepare_template() None

Hook to do delayed expensive work prior template rendering

pretty_name: str

Human readable name that will be inserted into the image title and description

abstract property pretty_reference: str

Returns the human readable registry URL to this image. It is intended to be used in the image documentation.

This url needn’t point to an exact version-release but can include just the major os version or the latest tag.

property publish_registry: Registry
property readme: str
property readme_name: str
property readme_path: str
property readme_url: str
abstract property reference: str

The primary URL via which this image can be pulled. It is used to set the org.opensuse.reference label and defaults to {self.registry}/{self.image_ref_name}.

property registry: str

The registry where the image is available on.

property registry_prefix: str
property release_stage: ReleaseStage

This container images’ release stage.

It is RELEASED if the container images’ operating system version is in the list RELEASED_OS_VERSIONS. Otherwise it is BETA.

replacements_via_service: list[Replacement]

Add any replacements via obs-service-replace_using_package_version that are used in this image into this list. See also Replacement

support_level: SupportLevel = 'techpreview'

The support level for this image, defaults to SupportLevel.TECHPREVIEW

supported_until: date | None = None

The support level end date

property title: str

The image title that is inserted into the org.opencontainers.image.title label.

It is generated from BaseContainerImage.pretty_name as follows: "{distribution_base_name} BCI {self.pretty_name}", where distribution_base_name is taken from distribution_base_name.

abstract property uid: str

unique identifier of this image, either its name or $name-$tag_version.

property url: str

The default url that is put into the org.opencontainers.image.url label

property volume_dockerfile: str
volumes: list[str] | None = None

An optional list of volumes, it is omitted if empty or None

property volumes_kiwi: str

The volumes for this image as xml elements that are inserted into a container.

async write_files_to_folder(dest: str) list[str]

Writes all files required to build this image into the destination folder and returns the filenames (not full paths) that were written to the disk.

bci_build.package.DOCKERFILE_RUN: str = 'RUN set -euo pipefail;'

a RUN command with a common set of bash flags applied to prevent errors from not being noticed

class bci_build.package.DevelopmentContainer(name: 'str', os_version: 'OsVersion', pretty_name: 'str', package_name: 'str | None' = None, from_image: 'str | None' = '', from_target_image: 'str | None' = None, exclusive_arch: 'list[Arch] | None' = None, is_latest: 'bool' = False, is_singleton_image: 'bool' = False, entrypoint: 'list[str] | None' = None, entrypoint_user: 'str | None' = '', cmd: 'list[str] | None' = None, volumes: 'list[str] | None' = None, exposes_ports: 'list[NetworkPort] | None' = None, env: 'dict[str, str | int] | dict[str, str] | dict[str, int]' = <factory>, build_flavor: 'str | None' = None, crate: 'ContainerCrate' = None, replacements_via_service: 'list[Replacement]' = <factory>, extra_labels: 'dict[str, str]' = <factory>, package_list: 'list[str] | list[Package]' = <factory>, custom_end: 'str' = '', build_stage_custom_end: 'str | None' = None, buildcounter_synctag: 'str | None' = None, config_sh_script: 'str' = '', config_sh_interpreter: 'str' = '/bin/bash', oci_authors: 'str | None' = None, extra_files: 'dict[str, str | bytes] | dict[str, bytes] | dict[str, str]' = <factory>, additional_names: 'list[str]' = <factory>, custom_labelprefix_end: 'str' = '', custom_description: 'str' = '', build_recipe_type: 'BuildType | None' = None, kiwi_ignore_packages: 'list[str] | None' = None, license: 'str' = 'MIT', support_level: 'SupportLevel' = <SupportLevel.TECHPREVIEW: 'techpreview'>, supported_until: 'datetime.date | None' = None, no_recommends: 'bool' = True, logo_url: 'str' = '', _min_release_counter: 'int | None' = None, _publish_registry: 'Registry | None' = None, version: 'str | int' = '', tag_version: 'str | None' = None, stability_tag: 'str | None' = None, additional_versions: 'list[str]' = <factory>, version_in_uid: 'bool' = True)
additional_versions: list[str]

versions that to include as tags to this container

property build_name: str | None

Create a stable BuildName, either by using stability_tag or by falling back to _variant.

property build_tags: list[str]

All build tags that will be added to this image. Note that build tags are full paths on the registry and not just a tag.

property build_version: str | None
property image_ref_name: str

The immutable reference for this target under which this image can be pulled. It is used to set the org.opencontainers.image.ref.name OCI annotation and defaults to {self.build_tags[0]}.

property image_type: ImageType

Define the value of the com.suse.image-type label.

property oci_version: str

The “main” version label of this image.

It is added as the org.opencontainers.image.version label to the container image.

prepare_template() None

Hook to do delayed expensive work prior template rendering

property pretty_reference: str

Returns the human readable registry URL to this image. It is intended to be used in the image documentation.

This url needn’t point to an exact version-release but can include just the major os version or the latest tag.

property reference: str

The primary URL via which this image can be pulled. It is used to set the org.opensuse.reference label and defaults to {self.registry}/{self.image_ref_name}.

property registry_prefix: str
stability_tag: str | None = None
tag_version: str | None = None

the floating tag version-$variant to add to the tags if set. used to determine a stable buildname

property uid: str

unique identifier of this image, either its name or $name-$tag_version.

version: str | int = ''

the main version of the language or application inside this container used for org.opencontainers.image.version

version_in_uid: bool = True

flag whether the version is included in the uid

bci_build.package.LOG_CLEAN: str = 'rm -rf {/target,}/var/log/{alternatives.log,lastlog,tallylog,zypper.log,zypp/history,YaST2}'

Remove various log files. While it is possible to just rm -rf /var/log/*, that would also remove some package owned directories (not %ghost)

class bci_build.package.OsContainer(name: 'str', os_version: 'OsVersion', pretty_name: 'str', package_name: 'str | None' = None, from_image: 'str | None' = '', from_target_image: 'str | None' = None, exclusive_arch: 'list[Arch] | None' = None, is_latest: 'bool' = False, is_singleton_image: 'bool' = False, entrypoint: 'list[str] | None' = None, entrypoint_user: 'str | None' = '', cmd: 'list[str] | None' = None, volumes: 'list[str] | None' = None, exposes_ports: 'list[NetworkPort] | None' = None, env: 'dict[str, str | int] | dict[str, str] | dict[str, int]' = <factory>, build_flavor: 'str | None' = None, crate: 'ContainerCrate' = None, replacements_via_service: 'list[Replacement]' = <factory>, extra_labels: 'dict[str, str]' = <factory>, package_list: 'list[str] | list[Package]' = <factory>, custom_end: 'str' = '', build_stage_custom_end: 'str | None' = None, buildcounter_synctag: 'str | None' = None, config_sh_script: 'str' = '', config_sh_interpreter: 'str' = '/bin/bash', oci_authors: 'str | None' = None, extra_files: 'dict[str, str | bytes] | dict[str, bytes] | dict[str, str]' = <factory>, additional_names: 'list[str]' = <factory>, custom_labelprefix_end: 'str' = '', custom_description: 'str' = '', build_recipe_type: 'BuildType | None' = None, kiwi_ignore_packages: 'list[str] | None' = None, license: 'str' = 'MIT', support_level: 'SupportLevel' = <SupportLevel.TECHPREVIEW: 'techpreview'>, supported_until: 'datetime.date | None' = None, no_recommends: 'bool' = True, logo_url: 'str' = '', _min_release_counter: 'int | None' = None, _publish_registry: 'Registry | None' = None)
property build_tags: list[str]

All build tags that will be added to this image. Note that build tags are full paths on the registry and not just a tag.

property image_ref_name: str

The immutable reference for this target under which this image can be pulled. It is used to set the org.opencontainers.image.ref.name OCI annotation and defaults to {self.build_tags[0]}.

property image_type: ImageType

Define the value of the com.suse.image-type label.

property oci_version: str

The “main” version label of this image.

It is added as the org.opencontainers.image.version label to the container image.

prepare_template() None

Hook to do delayed expensive work prior template rendering

property pretty_reference: str

Returns the human readable registry URL to this image. It is intended to be used in the image documentation.

This url needn’t point to an exact version-release but can include just the major os version or the latest tag.

property reference: str

The primary URL via which this image can be pulled. It is used to set the org.opensuse.reference label and defaults to {self.registry}/{self.image_ref_name}.

property uid: str

unique identifier of this image, either its name or $name-$tag_version.

static version_to_container_os_version(os_version: OsVersion) str
class bci_build.package.Package(name: str, pkg_type: PackageType = PackageType.IMAGE)

Representation of a package in a kiwi build, for Dockerfile based builds the pkg_type.

name: str

The name of the package

pkg_type: PackageType = 'image'

The package type. This parameter is only applicable for kiwi builds and defines into which <packages> element this package is inserted.

class bci_build.package.ParseVersion(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
MAJOR = 'major'
MINOR = 'minor'
OFFSET = 'offset'
PATCH = 'patch'
PATCH_UPDATE = 'patch_update'
class bci_build.package.Replacement(regex_in_build_description: str, package_name: str, file_name: str | None = None, parse_version: None | ParseVersion = None)

Represents a replacement via the obs-service-replace_using_package_version.

file_name: str | None = None

override file name, if unset use Dockerfile or $pkg_name.kiwi

package_name: str

package name to be queried for the version

parse_version: None | ParseVersion = None

specify how the version should be formatted, see https://github.com/openSUSE/obs-service-replace_using_package_version#usage for further details

regex_in_build_description: str

regex to be replaced in file_name, Dockerfile or $pkg_name.kiwi

to_service(default_file_name: str) Service

Convert this replacement into a Service.

bci_build.package.generate_disk_size_constraints(size_gb: int) str

Creates the contents of a _constraints file for OBS to require workers with at least size_gb GB of disk space.

bci_build.package.main() None

bci_build.package.versions module

This module contains a simple mechanism to store the package versions for various code streams in a json file.

We need to know the version of certain packages in the distribution to be able to hardcode it in READMEs as we cannot let the build service create READMEs for us (this is a hard to work around limitation of OBS and the replace_using_package_version service).

Therefore we keep a single json file in the code with all packages and their version per code stream in the git repository of the following form:

{
    "nginx": {
        "Tumbleweed": "1.25.5",
        "6": "1.21.5",
        "5": "1.21.5"
    }
}

The package versions are available via the function get_pkg_version().

The json file is updated via the function run_version_update(). It can also be called directly via poetry run update-versions and is also run in the CI via .github/workflows/update-versions.yml.

To add a new package to the versions json, add it’s package name and all code streams with a dummy version, e.g.:

{
    "mariadb": {
        "Tumbleweed": "",
        "6": ""
    }
}

Save the file and run the version update. update_versions() will fetch the current version for every code stream that is present in the dictionary.

For some packages we do not need to know the full version, to prevent pointless automated churn. In such a case, add the additional key version_format to a package dictionary and set the value to the version format limit (e.g. major or minor). The value must correspond to a enum value of ParseVersion. Applied to the above example, this results in:

{
    "nginx": {
        "parse_version": "minor",
        "Tumbleweed": "1.25",
        "6": "1.21",
        "5": "1.21"
    }
}
bci_build.package.versions.PACKAGE_VERSIONS_JSON_PATH = PosixPath('/__w/BCI-dockerfile-generator/BCI-dockerfile-generator/src/bci_build/package/package_versions.json')

Path to the json file where the package versions are stored

bci_build.package.versions.format_version(ver: str, format: Literal[ParseVersion.MAJOR, ParseVersion.MINOR, ParseVersion.PATCH]) str
bci_build.package.versions.format_version(ver: str, format: Literal[ParseVersion.PATCH_UPDATE, ParseVersion.OFFSET]) NoReturn

Format the string ver to the supplied format, e.g.:

>>> format_version('1.2.3', ParseVersion.MAJOR)
1
>>> format_version('1.2.3', ParseVersion.MINOR)
1.2
>>> format_version('1.2', ParseVersion.PATCH)
1.2.0
bci_build.package.versions.get_pkg_version(pkg_name: str, os_version: OsVersion) str
bci_build.package.versions.run_version_update() None

Fetch the new package versions via update_versions() and write the result to the package versions json file.

async bci_build.package.versions.update_versions(osc: Osc) dict[str, dict[str, str]]

Fetch all package versions from the build service and return the result. This function fetches all versions for every package and every code stream defined in PACKAGE_VERSIONS.

bci_build.templates module

This module contains the Jinja2 templates used to generate the build descriptions.

bci_build.templates.DOCKERFILE_TEMPLATE = <Template memory:7fb55dd67380>

Jinja2 template used to generate Dockerfile

bci_build.templates.KIWI_TEMPLATE = <Template memory:7fb55db76ad0>

Jinja2 template used to generate $pkg_name.kiwi

bci_build.templates.SERVICE_TEMPLATE = <Template memory:7fb55db77110>

Jinja2 template used to generate _service.

dotnet module

staging module

staging.bot module

staging.bot.GIT_COMMITTER_EMAIL = 'bci-internal@suse.de'

email address of the bot account performing git actions

staging.bot.GIT_COMMITTER_NAME = 'SUSE Update Bot'

full name of the bot account performing git actions

staging.bot.OSC_PASSWORD_ENVVAR_NAME = 'OSC_PASSWORD'

environment variable from which the password of the bot’s user is taken

staging.bot.OSC_USER_ENVVAR_NAME = 'OSC_USER'

environment variable name from which the osc username for the bot is read

staging.bot.OS_VERSION_NEEDS_BASE_CONTAINER: tuple[OsVersion, ...] = ()

tuple of OsVersion that need the base container to be linked into the staging project this is usually only necessary during the early stages of a new SLE service pack when autobuild has not yet synced the binaries of the container images from IBS to OBS

class staging.bot.ProjectConfig(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
META = 'prj'
PRJCONF = 'prjconf'
class staging.bot.StagingBot(os_version: ~bci_build.os_version.OsVersion, branch_name: str = '', osc_username: str = '', repositories: list[str] = <factory>, _packages: list[str] | None = None, _osc_conf_file: str = '', _xdg_state_home_dir: ~tempfile.TemporaryDirectory | None = None, _run_cmd: ~obs_package_update.util.RunCommand = <factory>)

Bot that creates a staging project for the BCI images in the Open Build Service via the git scm bridge.

This bot creates a new worktree based on the “deployment branch” (see deployment_branch_name) and writes all build recipes into it. If this results in a change, then the changes are committed and pushed to github.

A new staging project with the name staging_project_name is then created where all packages that were changed are inserted via the scm bridge.

The bot needs to know the name of the user as whom it should act. The username has to be set via the attribute osc_username. This is unfortunately necessary, as osc does not provide a straightforward way how to get the default username…

Additionally, the bot stores its current settings in an environment file (with the file name DOTENV_FILE_NAME), which can be either sourced directly in bash or used to create an instance of the bot via StagingBot.from_env_file().

The bot supports running all actions as a user that is not configured in osc’s configuration file. All you have to do is to set the environment variable OSC_PASSWORD_ENVVAR_NAME to the password of the user that is going to be used. The setup() function will then create a temporary configuration file for osc and also set XDG_STATE_HOME to a temporary directory so that your local osc cookiejar is not modified. Both files are cleaned up via teardown()

DOTENV_FILE_NAME: ClassVar[str] = 'test-build.env'

filename of the environment file used to store the bot’s settings

MAX_WAIT_TIME_SEC: ClassVar[int] = 21600

Maximum time to wait for a build to finish. github actions will run for 6h at most, no point in waiting longer

async add_changelog_entry(entry: str, package_names: list[str] | None) str
property bcis: Generator[BaseContainerImage, None, None]

Generator for creating an iterable yielding all BaseContainerImage that are in the bot’s staging project.

branch_name: str = ''

Name of the branch to which the changes are pushed. If none is provided, then deployment_branch_name is used with a few random ASCII characters appended.

property changelog_check_github_action: str
async configure_devel_bci_package(package_name: str) None
async configure_devel_bci_project() None

Adjust to project meta of the devel project on OBS to match the template generated via staging.project_setup.generate_meta(). Additionally set the project meta from the file _config in the deployment branch, set the OSRT:Config attribute for pkglistgen to function as expected and set the OBS:RejectRequests attribute to a warning that SRs do not work.

container_urls_html() str

Pretty print the output of StagingBot.fetch_container_urls() wrapped in a <details></details> HTML element for GitHub.

property continuous_rebuild_project_name: str

The name of the continuous rebuild project on OBS.

property deployment_branch_name: str

The name of the branch for this os_version where the build recipes are checked out by default.

async fetch_build_results() list[RepositoryBuildResult]

Retrieves the current build results of the staging project.

fetch_container_urls() list[str]

Fetch the full urls to all published containers in the staging project including their most relevant tag (either latest or the first tag). Querying a staging project without published images results in a RuntimeError.

property find_missing_packages_action: str
async find_missing_packages_on_obs() list[str]

Returns the name of all packages that are currently in a git deployment branch, but have not been setup on OBS.

async force_rebuild() str

Deletes all binaries of the project on OBS and force rebuilds everything.

async static from_env_file() StagingBot

Read the last saved settings from the environment file (DOTENV_FILE_NAME) in the current working directory and create a StagingBot from them.

static from_github_comment(comment_text: str, osc_username: str) StagingBot
get_packages_without_changelog_addition(base_ref: str, change_ref: str) list[str]

Runs a simple heuristic whether a packages’ changelog has had an addition between base_ref and change_ref.

Returns:

The list of packages without a commit in the range base_ref and change_ref that added at least four lines (= minimum length of a one line osc vc entry).

Links the base container for this os into StagingBot.staging_project_name. This function does nothing if the current os_version is not in the list OS_VERSION_NEEDS_BASE_CONTAINER.

property obs_workflows_yml: str

The contents of .obs/workflows.yml for branching each package from the continuous rebuild project (continuous_rebuild_project_name) to the staging sub-project.

os_version: OsVersion

The operating system for which this instance has been created

osc_username: str = ''

username of the user that will be used to perform the actions by the bot.

This value must be provided, otherwise the post initialization function raises an exception.

property package_names: list[str] | None

Name of the packages in the staging project or None if the staging project has not been setup yet.

async remote_cleanup(branches: bool = True, obs_project: bool = True) None

Deletes the branch with the test commit locally and on the remote and removes the staging project.

All performed actions are permitted to fail without raising an exception to ensure that a partially setup test run is cleaned up as much as possible.

Parameters:
  • branches – if True, removes the branch locally and on the remote (defaults to True)

  • obs_project – if True, removes the staging project on OBS (defaults to True)

repositories: list[str]
async scratch_build(commit_message: str = '') None | str
async setup() None
property staging_project_name: str

The name of the staging project on OBS.

It is constructed as follows: home:$OSC_USER:BCI:Staging:$OS_VER:$BRANCH where:

property staging_project_url: str

URL to the staging project.

async teardown() None

Local cleanup after the bot (nothing on OBS is removed and the git repository itself is left untouched).

async wait_for_build_to_finish(timeout_sec: int | None = None) list[RepositoryBuildResult]

Blocks until all builds in the staging project have finished and the repositories are no longer dirty.

Parameters:

timeout_sec – Total time in seconds to block. Defaults to MAX_WAIT_TIME_SEC

Raises:
  • asyncio.TimeoutError – when build takes longer than the specified timeout

  • RuntimeError – when the staging project has no build results (this is most likely an issue with OBS)

Returns:

The last state of all packages in the staging project after the builds finished

async write_all_build_recipes_to_branch(commit_msg: str = '') str | None

Creates a worktree for the branch based on the deployment branch of this os_version, writes all image build recipes into it, commits and then pushes the changes. Afterwards the worktree is removed.

Returns:

The hash of the commit including all changes by the writing the build recipes into the worktree. If no changes were made, then None is returned.

async write_all_image_build_recipes(destination_prj_folder: str) list[str]

Writes all build recipes into the folder destination_prj_folder and returns a list of files that were written.

Returns:

A list of all files that were written to destination_prj_folder. The files are listed relative to destination_prj_folder and don’t contain any leading path components.

async write_cr_project_config() None

Send the configuration of the continuous rebuild project to OBS.

This will create the project if it did not exist already. If it exists, then its configuration (= meta in OBS jargon) will be updated.

async write_env_file()
async write_pkg_configs(packages: Iterable[BaseContainerImage], git_branch_name: str, target_obs_project: str) None

Write all package configurations (= _meta) for every package in packages to the project target_obs_project so that the package is fetched via the scm bridge from the branch git_branch_name.

Parameters:
  • packages – the BCI packages that should be added

  • git_branch_name – the name of the git branch from which the sources will be retrieved

  • target_obs_project – name of the project on OBS to which the packages will be added

async write_staging_project_configs() None

Submit the prjconf and meta to the test project on OBS.

The meta is generated using a template via py.func:~staging.project_setup.generate_project_name.

The prjconf is taken from the file:_config file in the deployment branch.

staging.bot.main() None

staging.build_result module

class staging.build_result.PackageBuildResult(name: str, code: PackageStatusCode, detail_message: str | None = None)

The build result of a single package.

code: PackageStatusCode

build status of the package

detail_message: str | None = None

an optional message providing additional details, e.g. on which worker this package is being built or why it is not resolvable

name: str

The package name

class staging.build_result.PackageStatusCode(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Possible package states

BLOCKED = 'blocked'
BROKEN = 'broken'
BUILDING = 'building'
DISABLED = 'disabled'
EXCLUDED = 'excluded'
FAILED = 'failed'
FINISHED = 'finished'
SCHEDULED = 'scheduled'
SIGNING = 'signing'
SUCCEEDED = 'succeeded'
UNRESOLVABLE = 'unresolvable'
pretty_print()

Returns the value of this enum with an emoji visualizing the status.

class staging.build_result.RepositoryBuildResult(project: str, repository: str, arch: ~bci_build.container_attributes.Arch, code: str, state: str, packages: list[~staging.build_result.PackageBuildResult] = <factory>, dirty: bool = False)

The build results of a repository for a specific architecture.

arch: Arch

repository architecture

code: str

status code (usually equals to state)

dirty: bool = False

if a repository is dirty, then it is still processing build jobs and has not been fully published yet

static from_resultlist(obs_api_reply: str) list[RepositoryBuildResult]

Creates a list of :py:class`RepositoryBuildResult` from the xml API reply received from OBS via osc results --xml.

packages: list[PackageBuildResult]

state of all packages in this repository & arch

project: str

name of the project to which this repository belongs

repository: str

repository name

state: str

repository status

staging.build_result.is_build_failed(build_results: list[RepositoryBuildResult]) bool

Returns True if any package in the list of build results is either unresolvable or failed to build. The repositories must not be dirty, otherwise a ValueError is raised.

staging.build_result.render_as_markdown(results: list[RepositoryBuildResult], base_url: str = 'https://build.opensuse.org/') str

staging.project_setup module

class staging.project_setup.ProjectType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
CR = 2
DEVEL = 1
STAGING = 3
staging.project_setup.generate_meta(os_version: OsVersion, project_type: ProjectType, osc_username: str, branch_name: None | str = None) tuple[str, str]
staging.project_setup.generate_project_name(os_version: OsVersion, project_type: ProjectType, osc_username: str, branch_name: str | None = None) str