From nobody Sat Feb 7 21:15:20 2026 Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 695D734402D; Thu, 22 Jan 2026 14:07:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769090842; cv=none; b=iY0p2+X3Unws3p07TI6cjoPunm/mXaJWkIwIEg0Iae8N2F9bACCu5abseO1P47WeE1Jf9bjWTnjn/RIC2exIVQ4zX5fmlGSJNswvXNPJT90kk3GB7aa7BDqmCdpFUuqEtL0giKbqMrlm2odkRZClrDQbXbfK8+UCp4d20IyELyY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769090842; c=relaxed/simple; bh=7vHTCrEOiEJkfsBFKnpnS6aRcKX8QOUns3U4parp2ro=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=s7osuggkPIIVtxUXBrIG2O6UdpbZzP0sM/RHEQnRkLwJyuIiG/an2nZXLr9Gp4A2BXrKc0vzn/0/l9U74syzb39NNkbpuOd8dURZ0LwehxdM4h1tW0HlRc+XxrDLJ+hLqvKJ6VkcpQtsek3xND9Ua2mtt4ieGCvNFkQ5pcaMl68= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=gtucker.io; spf=pass smtp.mailfrom=gtucker.io; dkim=pass (2048-bit key) header.d=gtucker.io header.i=@gtucker.io header.b=OEHVZmZ3; arc=none smtp.client-ip=217.70.183.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=gtucker.io Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gtucker.io Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gtucker.io header.i=@gtucker.io header.b="OEHVZmZ3" Received: by mail.gandi.net (Postfix) with ESMTPSA id A199643B48; Thu, 22 Jan 2026 14:07:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gtucker.io; s=gm1; t=1769090832; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ELUAB8rPpZBfx/pf2+f40Rmk9ME9ideSlq/XiQKdxsg=; b=OEHVZmZ3Wa2VEfOmAQ4IbraGv3rGSI1L9cychL3LrYkOjEsoPFiofWpCGIDrFeNdL7/gok PS8uBdt1S6IIlGxBcZnMD3pIyEET35nlHRXoExiHaHAdQRsB9U6Zj6Lw4OLhNmLDH2wCeo 3SQy9SOUft8Ze5ZZ001EwciZAFA6jUPwC2/HlR4wLI0tOt6QqutHLAScm5va4DVIQN61aL WLnPN/2ARmoECox9ErlqvCYLK4KHtwuVffQN/JlZ7U0nMQkHbyuE0LAgsK0VoFokMWCAgK zscWWP0o7/+h+8Jp36yN/vGBzaOWwXxf6PaVGbMCG5Edt7zxvU5sPeIv1gTLPg== From: Guillaume Tucker To: Nathan Chancellor , Nicolas Schier , Miguel Ojeda , David Gow , =?UTF-8?q?Onur=20=C3=96zkan?= Cc: Guillaume Tucker , Arnd Bergmann , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kbuild@vger.kernel.org, automated-testing@lists.yoctoproject.org, workflows@vger.kernel.org, llvm@lists.linux.dev Subject: [PATCH v4 1/2] scripts: add tool to run containerized builds Date: Thu, 22 Jan 2026 15:06:59 +0100 Message-ID: <9b8da20157e409e8fa3134d2101678779e157256.1769090419.git.gtucker@gtucker.io> X-Mailer: git-send-email 2.47.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-GND-Sasl: gtucker@gtucker.io X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgddugeeifeeiucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuifetpfffkfdpucggtfgfnhhsuhgsshgtrhhisggvnecuuegrihhlohhuthemuceftddunecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfgggtgfesthekredtredtjeenucfhrhhomhepifhuihhllhgruhhmvgcuvfhutghkvghruceoghhtuhgtkhgvrhesghhtuhgtkhgvrhdrihhoqeenucggtffrrghtthgvrhhnpeeiudettdfhkeehveehfeegueelgeelteeuteettddtgeeiudeiudejfedvleegteenucffohhmrghinhepkhgvrhhnvghlrdhorhhgnecukfhppedvtddtudemkeeiudemgegrgedtmeekiedvtdemvdeigegsmedurgefheemuggsheegmedufeegvgenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpedvtddtudemkeeiudemgegrgedtmeekiedvtdemvdeigegsmedurgefheemuggsheegmedufeegvgdphhgvlhhopehrihhnghhordhlrghnpdhmrghilhhfrhhomhepghhtuhgtkhgvrhesghhtuhgtkhgvrhdrihhopdhqihgupeetudelleeigeefueegkedpmhhouggvpehsmhhtphhouhhtpdhnsggprhgtphhtthhopedufedprhgtphhtthhopehnrghthhgrnheskhgvrhhnvghlrdhorhhgpdhrtghpthhtohepnhhstgeskhgvrhhnvghlrdhorhhgpdhrtghpthhtohepohhjvggurgeskhgvr hhnvghlrdhorhhgpdhrtghpthhtohepuggrvhhiughgohifsehgohhoghhlvgdrtghomhdprhgtphhtthhopeifohhrkhesohhnuhhrohiikhgrnhdruggvvhdprhgtphhtthhopehgthhutghkvghrsehgthhutghkvghrrdhioh X-GND-State: clean X-GND-Score: -100 Add a 'scripts/container' tool written in Python to run any command in the source tree from within a container. This can typically be used to call 'make' with a compiler toolchain image to run reproducible builds but any arbitrary command can be run too. Only Docker and Podman are supported in this initial version. Add a new entry to MAINTAINERS accordingly. Cc: Nathan Chancellor Cc: Nicolas Schier Cc: Miguel Ojeda Cc: David Gow Cc: "Onur =C3=96zkan" Link: https://lore.kernel.org/all/affb7aff-dc9b-4263-bbd4-a7965c19ac4e@gtuc= ker.io/ Signed-off-by: Guillaume Tucker --- MAINTAINERS | 6 ++ scripts/container | 199 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 205 insertions(+) create mode 100755 scripts/container diff --git a/MAINTAINERS b/MAINTAINERS index da9dbc1a4019..affd55ff05e0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6384,6 +6384,11 @@ S: Supported F: drivers/video/console/ F: include/linux/console* =20 +CONTAINER BUILD SCRIPT +M: Guillaume Tucker +S: Maintained +F: scripts/container + CONTEXT TRACKING M: Frederic Weisbecker M: "Paul E. McKenney" @@ -13676,6 +13681,7 @@ F: scripts/Makefile* F: scripts/bash-completion/ F: scripts/basic/ F: scripts/clang-tools/ +F: scripts/container F: scripts/dummy-tools/ F: scripts/include/ F: scripts/mk* diff --git a/scripts/container b/scripts/container new file mode 100755 index 000000000000..09663eccb8d3 --- /dev/null +++ b/scripts/container @@ -0,0 +1,199 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) 2025 Guillaume Tucker + +"""Containerized builds""" + +import abc +import argparse +import logging +import os +import pathlib +import shutil +import subprocess +import sys +import uuid + + +class ContainerRuntime(abc.ABC): + """Base class for a container runtime implementation""" + + name =3D None # Property defined in each implementation class + + def __init__(self, args, logger): + self._uid =3D args.uid or os.getuid() + self._gid =3D args.gid or args.uid or os.getgid() + self._env_file =3D args.env_file + self._shell =3D args.shell + self._logger =3D logger + + @classmethod + def is_present(cls): + """Determine whether the runtime is present on the system""" + return shutil.which(cls.name) is not None + + @abc.abstractmethod + def _do_run(self, image, cmd, container_name): + """Runtime-specific handler to run a command in a container""" + + @abc.abstractmethod + def _do_abort(self, container_name): + """Runtime-specific handler to abort a running container""" + + def run(self, image, cmd): + """Run a command in a runtime container""" + container_name =3D str(uuid.uuid4()) + self._logger.debug("container: %s", container_name) + try: + return self._do_run(image, cmd, container_name) + except KeyboardInterrupt: + self._logger.error("user aborted") + self._do_abort(container_name) + return 1 + + +class CommonRuntime(ContainerRuntime): + """Common logic for Docker and Podman""" + + def _do_run(self, image, cmd, container_name): + cmdline =3D [self.name, 'run'] + cmdline +=3D self._get_opts(container_name) + cmdline.append(image) + cmdline +=3D cmd + self._logger.debug('command: %s', ' '.join(cmdline)) + return subprocess.call(cmdline) + + def _get_opts(self, container_name): + opts =3D [ + '--name', container_name, + '--rm', + '--volume', f'{pathlib.Path.cwd()}:/src', + '--workdir', '/src', + ] + if self._env_file: + opts +=3D ['--env-file', self._env_file] + if self._shell: + opts +=3D ['--interactive', '--tty'] + return opts + + def _do_abort(self, container_name): + subprocess.call([self.name, 'kill', container_name]) + + +class DockerRuntime(CommonRuntime): + """Run a command in a Docker container""" + + name =3D 'docker' + + def _get_opts(self, container_name): + return super()._get_opts(container_name) + [ + '--user', f'{self._uid}:{self._gid}' + ] + + +class PodmanRuntime(CommonRuntime): + """Run a command in a Podman container""" + + name =3D 'podman' + + def _get_opts(self, container_name): + return super()._get_opts(container_name) + [ + '--userns', f'keep-id:uid=3D{self._uid},gid=3D{self._gid}', + ] + + +class Runtimes: + """List of all supported runtimes""" + + runtimes =3D [PodmanRuntime, DockerRuntime] + + @classmethod + def get_names(cls): + """Get a list of all the runtime names""" + return list(runtime.name for runtime in cls.runtimes) + + @classmethod + def get(cls, name): + """Get a single runtime class matching the given name""" + for runtime in cls.runtimes: + if runtime.name =3D=3D name: + if not runtime.is_present(): + raise ValueError(f"runtime not found: {name}") + return runtime + raise ValueError(f"unknown runtime: {runtime}") + + @classmethod + def find(cls): + """Find the first runtime present on the system""" + for runtime in cls.runtimes: + if runtime.is_present(): + return runtime + raise ValueError("no runtime found") + + +def _get_logger(verbose): + """Set up a logger with the appropriate level""" + logger =3D logging.getLogger('container') + handler =3D logging.StreamHandler() + handler.setFormatter(logging.Formatter( + fmt=3D'[container {levelname}] {message}', style=3D'{' + )) + logger.addHandler(handler) + logger.setLevel(logging.DEBUG if verbose is True else logging.INFO) + return logger + + +def main(args): + """Main entry point for the container tool""" + logger =3D _get_logger(args.verbose) + try: + cls =3D Runtimes.get(args.runtime) if args.runtime else Runtimes.f= ind() + except ValueError as ex: + logger.error(ex) + return 1 + logger.debug("runtime: %s", cls.name) + logger.debug("image: %s", args.image) + return cls(args, logger).run(args.image, args.cmd) + + +if __name__ =3D=3D '__main__': + parser =3D argparse.ArgumentParser( + 'container', + description=3D"See the documentation for more details: " + "https://docs.kernel.org/dev-tools/container.html" + ) + parser.add_argument( + '-e', '--env-file', + help=3D"Path to an environment file to load in the container." + ) + parser.add_argument( + '-g', '--gid', + help=3D"Group ID to use inside the container." + ) + parser.add_argument( + '-i', '--image', required=3DTrue, + help=3D"Container image name." + ) + parser.add_argument( + '-r', '--runtime', choices=3DRuntimes.get_names(), + help=3D"Container runtime name. If not specified, the first one f= ound " + "on the system will be used i.e. Podman if present, otherwise Dock= er." + ) + parser.add_argument( + '-s', '--shell', action=3D'store_true', + help=3D"Run the container in an interactive shell." + ) + parser.add_argument( + '-u', '--uid', + help=3D"User ID to use inside the container. If the -g option is = not " + "specified, the user ID will also be set as the group ID." + ) + parser.add_argument( + '-v', '--verbose', action=3D'store_true', + help=3D"Enable verbose output." + ) + parser.add_argument( + 'cmd', nargs=3D'+', + help=3D"Command to run in the container" + ) + sys.exit(main(parser.parse_args(sys.argv[1:]))) --=20 2.47.3 From nobody Sat Feb 7 21:15:20 2026 Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 67580345743; Thu, 22 Jan 2026 14:07:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769090844; cv=none; b=ETZgIWnLCmlMTqZWXrdFndltjK2kAS9MGOaoOQ8v2KTp1Mh3Vw75MKpWh/Y4ibP4ZEoCNdsiIW7/UoGaFuz6v94S8Q+ZDWH2FM6lCot3VyM5M2BzOz32Svg+utT/eXcCLrqsBDr4L1ZH1CBwvz/z8hBSSKLIRPVifMB9KadWOoY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769090844; c=relaxed/simple; bh=MPFWzCRMQFvNBBWMESM2u/ts+T7p/a41Aaoq0Z93YoA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=hXShk0z2YE0mMnD2Hlb9IxF9SIOGL2C8Ged8P/sbkabBpuVbhEHBx3fosDd61ESUxHo6VpxG/sQy04QUqbJcJrc5V7twfccKGlhSXvHmsWm7wQfSAdzcgQH4TLLGTuxm6D/YPSRELcg8klueWBTRz0qavqtuaItkcmgNWwIJA9k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=gtucker.io; spf=pass smtp.mailfrom=gtucker.io; dkim=pass (2048-bit key) header.d=gtucker.io header.i=@gtucker.io header.b=Rud1y+dt; arc=none smtp.client-ip=217.70.183.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=gtucker.io Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gtucker.io Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gtucker.io header.i=@gtucker.io header.b="Rud1y+dt" Received: by mail.gandi.net (Postfix) with ESMTPSA id 3638441DF3; Thu, 22 Jan 2026 14:07:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gtucker.io; s=gm1; t=1769090833; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WV9yo6vv4rX2CVpVHGPy28S5A9jqZyPD+02tk7gtpU8=; b=Rud1y+dtpT/bj7voBBSMnGGDvn4VTaL5IRHgqhteS2DwWbu5dUf+CtFa4kPxqxdawUlvkA /pC8rOFJvyOjg2Vqd2fIW5qPI3vvPNxJSI+4w9if86BDai56XXzOxDXF4niNVwhwclbrVl DM+wSISOhCigEBIb+ah4ffBX0ohqYpKpZUsjk5GDWYczk4fWK5Li5TUKAkmRLvalImtWTC y0fqy6dBhUxOT1mNhx+2wUXlsn6Fi+78PkMQNAjZ0RDb7LC2mxIB03oMHsc6JXPf2MM2dB CkunDy7M90x0oEp4jM1i2CCVx/eiNaMwJLxSFIMhgFWb3Yva+1TZZspFX8IyUg== From: Guillaume Tucker To: Nathan Chancellor , Nicolas Schier , Miguel Ojeda , David Gow , =?UTF-8?q?Onur=20=C3=96zkan?= Cc: Guillaume Tucker , Arnd Bergmann , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kbuild@vger.kernel.org, automated-testing@lists.yoctoproject.org, workflows@vger.kernel.org, llvm@lists.linux.dev Subject: [PATCH v4 2/2] Documentation: dev-tools: add container.rst page Date: Thu, 22 Jan 2026 15:07:00 +0100 Message-ID: X-Mailer: git-send-email 2.47.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-GND-Sasl: gtucker@gtucker.io X-GND-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgddugeeifeeiucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuifetpfffkfdpucggtfgfnhhsuhgsshgtrhhisggvnecuuegrihhlohhuthemuceftddunecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfgggtgfesthekredtredtjeenucfhrhhomhepifhuihhllhgruhhmvgcuvfhutghkvghruceoghhtuhgtkhgvrhesghhtuhgtkhgvrhdrihhoqeenucggtffrrghtthgvrhhnpeelvdegheehuedvhfehheevfeekleefgefgieevteeugfdvteeiudduvddvvdfgvdenucffohhmrghinhepughotghkvghrrdhiohdpphhoughmrghnqdguvghskhhtohhprdhiohdpughotghkvghrrdgtohhmpdhkvghrnhgvlhdrohhrghdpghhithhlrggsrdgtohhmnecukfhppedvtddtudemkeeiudemgegrgedtmeekiedvtdemvdeigegsmedurgefheemuggsheegmedufeegvgenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpedvtddtudemkeeiudemgegrgedtmeekiedvtdemvdeigegsmedurgefheemuggsheegmedufeegvgdphhgvlhhopehrihhnghhordhlrghnpdhmrghilhhfrhhomhepghhtuhgtkhgvrhesghhtuhgtkhgvrhdrihhopdhqihgupeefieefkeeggedufffhfedpmhhouggvpehsmhhtphhouhhtpdhnsggprhgtphhtthhopedufedprhgtphhtthhopehnrghthhgrn heskhgvrhhnvghlrdhorhhgpdhrtghpthhtohepnhhstgeskhgvrhhnvghlrdhorhhgpdhrtghpthhtohepohhjvggurgeskhgvrhhnvghlrdhorhhgpdhrtghpthhtohepuggrvhhiughgohifsehgohhoghhlvgdrtghomhdprhgtphhtthhopeifohhrkhesohhnuhhrohiikhgrnhdruggvvhdprhgtphhtthhopehgthhutghkvghrsehgthhutghkvghrrdhioh X-GND-State: clean X-GND-Score: -100 Add a dev-tools/container.rst documentation page for the scripts/container tool. This covers the basic usage with additional information about environment variables and user IDs. It also includes a number of practical examples with a reference to the experimental kernel.org toolchain images. Update MAINTAINERS accordingly with a reference to the added file. Cc: Nathan Chancellor Cc: Nicolas Schier Cc: Miguel Ojeda Cc: David Gow Cc: "Onur =C3=96zkan" Signed-off-by: Guillaume Tucker Reviewed-by: Onur =C3=96zkan --- Documentation/dev-tools/container.rst | 227 ++++++++++++++++++++++++++ Documentation/dev-tools/index.rst | 1 + MAINTAINERS | 1 + 3 files changed, 229 insertions(+) create mode 100644 Documentation/dev-tools/container.rst diff --git a/Documentation/dev-tools/container.rst b/Documentation/dev-tool= s/container.rst new file mode 100644 index 000000000000..452415b64662 --- /dev/null +++ b/Documentation/dev-tools/container.rst @@ -0,0 +1,227 @@ +.. SPDX-License-Identifier: GPL-2.0-only +.. Copyright (C) 2025 Guillaume Tucker + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Containerized Builds +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The ``container`` tool can be used to run any command in the kernel source= tree +from within a container. Doing so facilitates reproducing builds across +various platforms, for example when a test bot has reported an issue which +requires a specific version of a compiler or an external test suite. While +this can already be done by users who are familiar with containers, having= a +dedicated tool in the kernel tree lowers the barrier to entry by solving c= ommon +problems once and for all (e.g. user id management). It also makes it eas= ier +to share an exact command line leading to a particular result. The main u= se +case is likely to be kernel builds but virtually anything can be run: KUni= t, +checkpatch etc. provided a suitable image is available. + + +Options +=3D=3D=3D=3D=3D=3D=3D + +Command line syntax:: + + scripts/container -i IMAGE [OPTION]... CMD... + +Available options: + +``-e, --env-file ENV_FILE`` + + Path to an environment file to load in the container. + +``-g, --gid GID`` + + Group id to use inside the container. + +``-i, --image IMAGE`` + + Container image name (required). + +``-r, --runtime RUNTIME`` + + Container runtime name. Supported runtimes: ``docker``, ``podman``. + + If not specified, the first one found on the system will be used + i.e. Podman if present, otherwise Docker. + +``-s, --shell`` + + Run the container in an interactive shell. + +``-u, --uid UID`` + + User id to use inside the container. + + If the ``-g`` option is not specified, the user id will also be used f= or + the group id. + +``-v, --verbose`` + + Enable verbose output. + +``-h, --help`` + + Show the help message and exit. + + +Usage +=3D=3D=3D=3D=3D + +It's entirely up to the user to choose which image to use and the ``CMD`` +arguments are passed directly as an arbitrary command line to run in the +container. The tool will take care of mounting the source tree as the cur= rent +working directory and adjust the user and group id as needed. + +The container image which would typically include a compiler toolchain is +provided by the user and selected via the ``-i`` option. The container ru= ntime +can be selected with the ``-r`` option, which can be either ``docker`` or +``podman``. If none is specified, the first one found on the system will = be +used while giving priority to Podman. Support for other runtimes may be a= dded +later depending on their popularity among users. + +By default, commands are run non-interactively. The user can abort a runn= ing +container with SIGINT (Ctrl-C). To run commands interactively with a TTY,= the +``--shell`` or ``-s`` option can be used. Signals will then be received b= y the +shell directly rather than the parent ``container`` process. To exit an +interactive shell, use Ctrl-D or ``exit``. + +.. note:: + + The only host requirement aside from a container runtime is Python 3.10= or + later. + +.. note:: + + Out-of-tree builds are not fully supported yet. The ``O=3D`` option can + however already be used with a relative path inside the source tree to = keep + separate build outputs. A workaround to build outside the tree is to u= se + ``mount --bind``, see the examples section further down. + + +Environment Variables +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Environment variables are not propagated to the container so they have to = be +either defined in the image itself or via the ``-e`` option using an +environment file. In some cases it makes more sense to have them defined = in +the Containerfile used to create the image. For example, a Clang-only com= piler +toolchain image may have ``LLVM=3D1`` defined. + +The local environment file is more useful for user-specific variables added +during development. It is passed as-is to the container runtime so its fo= rmat +may vary. Typically, it will look like the output of ``env``. For exampl= e:: + + INSTALL_MOD_STRIP=3D1 + SOME_RANDOM_TEXT=3DOne upon a time + +Please also note that ``make`` options can still be passed on the command = line, +so while this can't be done since the first argument needs to be the +executable:: + + scripts/container -i docker.io/tuxmake/korg-clang LLVM=3D1 make # won't= work + +this will work:: + + scripts/container -i docker.io/tuxmake/korg-clang make LLVM=3D1 + + +User IDs +=3D=3D=3D=3D=3D=3D=3D=3D + +This is an area where the behaviour will vary slightly depending on the +container runtime. The goal is to run commands as the user invoking the t= ool. +With Podman, a namespace is created to map the current user id to a differ= ent +one in the container (1000 by default). With Docker, while this is also +possible with recent versions it requires a special feature to be enabled = in +the daemon so it's not used here for simplicity. Instead, the container i= s run +with the current user id directly. In both cases, this will provide the s= ame +file permissions for the kernel source tree mounted as a volume. The only +difference is that when using Docker without a namespace, the user id may = not +be the same as the default one set in the image. + +Say, we're using an image which sets up a default user with id 1000 and the +current user calling the ``container`` tool has id 1234. The kernel source +tree was checked out by this same user so the files belong to user 1234. = With +Podman, the container will be running as user id 1000 with a mapping to id= 1234 +so that the files from the mounted volume appear to belong to id 1000 insi= de +the container. With Docker and no namespace, the container will be running +with user id 1234 which can access the files in the volume but not in the = user +1000 home directory. This shouldn't be an issue when running commands onl= y in +the kernel tree but it is worth highlighting here as it might matter for +special corner cases. + +.. note:: + + Podman's `Docker compatibility + `__ + mode to run ``docker`` commands on top of a Podman backend is more comp= lex + and not fully supported yet. As such, Podman will take priority if both + runtimes are available on the system. + + +Examples +=3D=3D=3D=3D=3D=3D=3D=3D + +The TuxMake project provides a variety of prebuilt container images availa= ble +on `Docker Hub `__. Here's the shortest +example to build a kernel using a TuxMake Clang image:: + + scripts/container -i docker.io/tuxmake/korg-clang -- make LLVM=3D1 defco= nfig + scripts/container -i docker.io/tuxmake/korg-clang -- make LLVM=3D1 -j$(n= proc) + +.. note:: + + When running a command with options within the container, it should be + separated with a double dash ``--`` to not confuse them with the + ``container`` tool options. Plain commands with no options don't stric= tly + require the double dashes e.g.:: + + scripts/container -i docker.io/tuxmake/korg-clang make mrproper + +To run ``checkpatch.pl`` in a ``patches`` directory with a generic Perl im= age:: + + scripts/container -i perl:slim-trixie scripts/checkpatch.pl patches/* + +As an alternative to the TuxMake images, the examples below refer to +``kernel.org`` images which are based on the `kernel.org compiler toolchai= ns +`__. These aren't (yet) offic= ially +available in any public registry but users can build their own locally ins= tead +using this `experimental repository +`__ by running ``make +PREFIX=3Dkernel.org/``. + +To build just ``bzImage`` using Clang:: + + scripts/container -i kernel.org/clang -- make bzImage -j$(nproc) + +Same with GCC 15 as a particular version tag:: + + scripts/container -i kernel.org/gcc:15 -- make bzImage -j$(nproc) + +For an out-of-tree build, a trick is to bind-mount the destination directo= ry to +a relative path inside the source tree:: + + mkdir -p $HOME/tmp/my-kernel-build + mkdir -p build + sudo mount --bind $HOME/tmp/my-kernel-build build + scripts/container -i kernel.org/gcc -- make mrproper + scripts/container -i kernel.org/gcc -- make O=3Dbuild defconfig + scripts/container -i kernel.org/gcc -- make O=3Dbuild -j$(nproc) + +To run KUnit in an interactive shell and get the full output:: + + scripts/container -s -i kernel.org/gcc:kunit -- \ + tools/testing/kunit/kunit.py \ + run \ + --arch=3Dx86_64 \ + --cross_compile=3Dx86_64-linux- + +To just start an interactive shell:: + + scripts/container -si kernel.org/gcc bash + +To build the HTML documentation, which requires the ``kdocs`` image built = with +``make PREFIX=3Dkernel.org/ extra`` as it's not a compiler toolchain:: + + scripts/container -i kernel.org/kdocs make htmldocs diff --git a/Documentation/dev-tools/index.rst b/Documentation/dev-tools/in= dex.rst index 4b8425e348ab..527a0e4cf2ed 100644 --- a/Documentation/dev-tools/index.rst +++ b/Documentation/dev-tools/index.rst @@ -38,6 +38,7 @@ Documentation/process/debugging/index.rst gpio-sloppy-logic-analyzer autofdo propeller + container =20 =20 .. only:: subproject and html diff --git a/MAINTAINERS b/MAINTAINERS index affd55ff05e0..4e82dba3bd25 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6387,6 +6387,7 @@ F: include/linux/console* CONTAINER BUILD SCRIPT M: Guillaume Tucker S: Maintained +F: Documentation/dev-tools/container.rst F: scripts/container =20 CONTEXT TRACKING --=20 2.47.3