From: Aliaksei Karpovich <akarpovich@ilbers.de>
To: Quirin Gylstorff <quirin.gylstorff@siemens.com>,
isar-users@googlegroups.com
Cc: Uladzimir Bely <ubely@ilbers.de>
Subject: Re: [v8 01/14] scripts: Add debrepo python script handling base-apt
Date: Wed, 29 Jul 2026 12:03:54 +0300 [thread overview]
Message-ID: <6fe406cf-38fe-4db1-b5e2-28c71039830e@ilbers.de> (raw)
In-Reply-To: <0bb0f167-54b7-4f11-abde-ec3ee6c44c8f@siemens.com>
On 7/27/26 15:36, Quirin Gylstorff wrote:
>
>
> On 7/27/26 1:26 PM, Aliaksei Karpovich wrote:
>> From: Uladzimir Bely <ubely@ilbers.de>
>>
>> This is the main utility responsible for prefetching packages
>> into local `base-apt` repo from external Debian mirrors. It uses
>> python-apt module and requires some kind of minimal `rootfs` to work
>> (let's call it "debrepo context").
>
> This has a naming clash with https://github.com/filiprojek/debrepo. I
> would suggest another name.
What about "deb_repo" ?
> Does this work with newer releases of apt as it uses the host apt?
>
>>
>> Once initialized with `--init --workdir=<path>`, it stores the initial
>> configuration in `repo.opts` file inside the context and uses it at
>> futher calls.
>>
>> In future, the logic `debrepo` script implements could be directly
>> implemented inside bitbake classes.
>>
>> Signed-off-by: Uladzimir Bely <ubely@ilbers.de>
>> ---
>> scripts/debrepo | 589 ++++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 589 insertions(+)
>> create mode 100755 scripts/debrepo
>>
>> diff --git a/scripts/debrepo b/scripts/debrepo
>> new file mode 100755
>> index 00000000..81056c3a
>> --- /dev/null
>> +++ b/scripts/debrepo
>> @@ -0,0 +1,589 @@
>> +#!/usr/bin/env python3
>> +
>> +"""
>> +# This software is a part of Isar.
>> +# Copyright (C) 2026 ilbers GmbH
>> +
>> +# debrepo: build Debian-like repo using "python3-apt" library.
>> +
>> +When building the image, Isar downloads required Debian packages
>> from external
>> +mirrors. After build completed, it can pick all downloaded packages
>> from DL_DIR
>> +and build local 'base-apt' Debian-like repo from them.
>> +
>> +This tool allows to download packages and create local repo in
>> advance. So,
>> +Isar just uses this local repository and does not interact with
>> external
>> +mirrors. Such approach makes deb-dl import/export functionality
>> redundant.
>> +
>> +Script `debrepo` works in so-called "context" directory. It means some
>> +rootfs-like directory with bare minimum of directories/files
>> required for
>> +python3-apt to work.
>> +
>> +Context directory path is passed with "--workdir <dir>" command-line
>> option.
>> +On context creating, all passed parameters are stored in the context
>> directory
>> +and picked every time the context is used again.
>> +
>> +1. Repo for building Debian system
>> +```
>> +debrepo --workdir=d12 --init locales gnupg
>> +```
>> +Initialize the context in "d12" directory and create a repository in
>> +"d12/repo/apt" directory sufficient to debootstrap default system
>> +(e.g., debian-bookworm-amd64). Additionally, packages "locales" and
>> "gnupg"
>> +with all their dependencies will be available in this repo.
>> +
>> +```
>> +debrepo --workdir=d12 docbook-to-man
>> +```
>> +Adds "docbook-to-man" packages with its dependencies to earlier
>> created repo.
>> +
>> +```
>> +debrepo --workdir=d12 --srcmode docbook-to-man
>> +```
>> +Downloads source package for "docbook-to-man" and adds it to the repo
>> +
>> +2. Repo for building Ubuntu system
>> +```
>> +debrepo --init --workdir=uf \
>> +--distro=ubuntu --codename=focal --arch=arm64 \
>> +--aptsrcsfile=/work/isar/meta-isar/conf/distro/ubuntu-focal-ports.list
>> \
>> +--repodir=repo/apt --repodbdir=repo/db \
>> +--mirror=http://ports.ubuntu.com/ubuntu-ports \
>> +locales gnupg
>> +```
>> +Initialize the context in "uf" directory and create a repository in
>> "repo/apt"
>> +directory sufficient deboostraup ubuntu-focal arm64 system. Mirror
>> to use and
>> +source list are specified by corresponding arguments. Packages
>> "locales" and
>> +" gnupg" with the dependencies will be also placed to the repo.
>> +
>> +```
>> +debrepo --workdir=uf gnupg,locales
>> +```
>> +Add "gnupg" and "locales" packages with their dependencies to
>> earlier created
>> +ubuntu repo. Other parameters (distro, codename, arch) are ommited
>> since they
>> +are picked from the context.
>> +
>> +3. Repo for cross-building Debian system
>> +```
>> +debrepo --init --workdir=d11 --codename=bullseye--arch=amd64
>> --crossarch=armhf
>> +```
>> +Initialize the context in "d11" directory sufficient to deboostrap
>> Debian
>> +Bullseye (amd64) with foreign "armhf" architecture support
>> +
>> +```
>> +debrepo --workdir=d11 gcc
>> +```
>> +Add "gcc" package (amd64 version) to earlier created repo.
>> +
>> +```
>> +debrepo --workdir=d11 --crossbuild gcc
>> +```
>> +Add "gcc" package (armhf version) to earlier created repo.
>> +"""
>> +
>> +import os
>> +import sys
>> +import fcntl
>> +
>> +import argparse
>> +import shutil
>> +import subprocess
>> +import pickle
>> +import urllib.parse
>> +
>> +import apt_pkg
>> +import apt.progress.base
>> +
>> +
>> +REPREPRO_TIMEOUT = 1200
>> +
>> +
>> +class DebRepo(object):
>> + class DebRepoCtx(object):
>> + def __init__(self, workdir):
>> + self.distro = "debian"
>> + self.codename = "bullseye"
>> + self.arch = "amd64"
>> + self.mirror = "http://deb.debian.org/debian"
>> +
>> + self.repodir = f"{workdir}/repo/apt"
>> + self.repodbdir = f"{workdir}/repo/db"
>> +
>> + self.crossarch = self.arch
>> + self.compatarch = None
>> + self.keydir = "/etc/apt/trusted.gpg.d"
>> +
>> + def __init__(self, args):
>> + self.workdir = os.path.abspath(args.workdir)
>> + self.ctx = self.DebRepoCtx(self.workdir)
>> +
>> + self.cache = None
>> + self.depcache = None
>> + self.sr = None
>> + self.extrarepo = None
>> +
>> + self.ctx_load()
>> + self.ctx_update(args)
>> + self.ctx_save()
>> +
>> + print(
>> + f"ctx workdir: {self.workdir}\n"
>> + f" distro: {self.ctx.distro}\n"
>> + f" codename: {self.ctx.codename}\n"
>> + f" arch: {self.ctx.arch}\n"
>> + f" mirror: {self.ctx.mirror}\n"
>> + f" repodir: {self.ctx.repodir}\n"
>> + f" repodbdir: {self.ctx.repodbdir}\n"
>> + f" crossarch: {self.ctx.crossarch}\n"
>> + f" compatarch: {self.ctx.compatarch}\n"
>> + f" keydir: {self.ctx.keydir}"
>> + )
>> +
>> + if args.extrarepo:
>> + self.extrarepo = os.path.abspath(args.extrarepo)
>> +
>> + def ctx_load(self):
>> + ctxfile = f"{self.workdir}/debrepo.ctx"
>> +
>> + if os.path.isfile(ctxfile):
>> + with open(ctxfile, 'rb') as f:
>> + self.ctx = pickle.load(f)
>> +
>> + def ctx_save(self):
>> + ctxfile = f"{self.workdir}/debrepo.ctx"
>> +
>> + with open(ctxfile, 'wb') as f:
>> + pickle.dump(self.ctx, f)
>> +
>> + def ctx_update(self, args):
>> + if args.distro:
>> + self.ctx.distro = args.distro
>> + if args.codename:
>> + self.ctx.codename = args.codename
>> + if args.arch:
>> + self.ctx.arch = args.arch
>> + if args.mirror:
>> + self.ctx.mirror = args.mirror
>> +
>> + if args.repodir:
>> + self.ctx.repodir = os.path.abspath(args.repodir)
>> + if args.repodbdir:
>> + self.ctx.repodbdir = os.path.abspath(args.repodbdir)
>> +
>> + if args.crossarch:
>> + self.ctx.crossarch = args.crossarch
>> + if args.compatarch:
>> + self.ctx.compatarch = args.compatarch
>> + if args.keydir:
>> + self.ctx.keydir = args.keydir
>> +
>> + def create_rootfs(self, aptsrcsfile):
>
> I would call it create_context_rootfs like in the description.
>
>> + os.makedirs(f"{self.workdir}/var/lib/dpkg", exist_ok=True)
>> + with open(f"{self.workdir}/var/lib/dpkg/status", "w"):
>> + pass
>> +
>> + os.makedirs(f"{self.workdir}/etc/apt/sources.list.d",
>> exist_ok=True)
>> +
>> + srcfile =
>> f"{self.workdir}/etc/apt/sources.list.d/bootstrap.list"
>> + if aptsrcsfile and os.path.exists(aptsrcsfile):
>> + shutil.copy(aptsrcsfile, srcfile)
>> + else:
>> + with open(srcfile, "w") as f:
>> + repo = f"{self.ctx.mirror} {self.ctx.codename} main"
>> + f.write(f"deb {repo}\n")
>> + f.write(f"deb-src {repo}\n")
>> +
>> + dir_cache =
>> f"../apt_cache/{self.ctx.distro}-{self.ctx.codename}"
>> + os.makedirs(f"{self.workdir}/{dir_cache}/archives/partial",
>> + exist_ok=True)
>> +
>> + os.makedirs(f"{self.workdir}/tmp", exist_ok=True)
>> +
>> + def create_repo_dist(self):
>> + conf_dir = f"{self.ctx.repodir}/{self.ctx.distro}/conf"
>> + os.makedirs(conf_dir, exist_ok=True)
>> + if not os.path.exists(f"{conf_dir}/distributions"):
>> + with open(f"{conf_dir}/distributions", "w") as f:
>> + f.write(f"Codename: {self.ctx.codename}\n")
>> + f.write(
>> + "Architectures: "
>> + "i386 armhf arm64 amd64 mipsel riscv64 source\n")
>> + f.write("Components: main\n")
>> +
>> + def apt_config(self, init, crossbuild):
>> + if not init and self.ctx.compatarch:
>> + apt_pkg.config["APT::Architectures::"] =
>> self.ctx.compatarch
>> +
>> + if not init and self.ctx.arch != self.ctx.crossarch:
>> + apt_pkg.config["APT::Architectures::"] = self.ctx.crossarch
>> + apt_pkg.config["APT::Architectures::"] = self.ctx.arch
>> +
>> + apt_pkg.config.set("APT::Architecture", self.ctx.arch)
>> +
>> + apt_pkg.config.set("Dir", self.workdir)
>> +
>> + dir_cache =
>> f"../apt_cache/{self.ctx.distro}-{self.ctx.codename}"
>> + apt_pkg.config.set("Dir::Cache", f"{self.workdir}/{dir_cache}")
>> + apt_pkg.config.set("Dir::State::status",
>> + f"{self.workdir}/var/lib/dpkg/status")
>> +
>> + apt_pkg.config.set("APT::Install-Recommends", "0")
>> + apt_pkg.config.set("APT::Install-Suggests", "0")
>> +
>> + # Use host keys for authentification
>> + apt_pkg.config.set("Dir::Etc::TrustedParts", self.ctx.keydir)
>> +
>> + # Allow using repositories without keys
>> + apt_pkg.config.set("Acquire::AllowInsecureRepositories", "1")
>> +
>> + def mark_essential(self):
>> + for pkg in self.cache.packages:
>> + if pkg.architecture == self.ctx.arch:
>> + if pkg.essential:
>> + self.depcache.mark_install(pkg)
>> +
>> + def mark_by_prio(self, priority):
>> + for pkg in self.cache.packages:
>> + if pkg.architecture == self.ctx.arch:
>> + ver = self.depcache.get_candidate_ver(pkg)
>> + if ver and ver.priority <= priority:
>> + self.depcache.mark_install(pkg)
>> +
>> + def mark_pkg(self, name, crossbuild):
>> + pkgname = name
>> +
>> + if pkgname and (pkgname not in self.cache):
>> + # Try for cross arch
>> + if (pkgname, self.ctx.crossarch) in self.cache:
>> + pkgname += f":{self.ctx.crossarch}"
>> +
>> + if pkgname not in self.cache:
>> + print(f"Error: package '{name}' not found")
>> + return False
>> +
>> + pkg = self.cache[pkgname]
>> +
>> + if (not crossbuild) or (':' in pkgname) or (not
>> pkg.has_versions):
>> + if (pkg.has_provides) and (not pkg.has_versions):
>> + print("pkgname is virtual package, selecting best
>> provide")
>> + # Select first provide
>> + pkg_provide = pkg.provides_list[0][2]
>> + # Find better provide with higher version
>> + for provide in pkg.provides_list:
>> + if apt_pkg.version_compare(provide[2].ver_str,
>> + pkg_provide.ver_str) > 0:
>> + pkg_provide = provide[2]
>> + self.depcache.mark_install(pkg_provide.parent_pkg)
>> + else:
>> + self.depcache.mark_install(pkg)
>> + else:
>> + version = pkg.version_list[0]
>> + if version.arch == "all":
>> + self.depcache.mark_install(pkg)
>> + else:
>> + if version.multi_arch == version.MULTI_ARCH_FOREIGN:
>> + if (pkgname, self.ctx.arch) in self.cache:
>> + nativepkg = self.cache[pkgname, self.ctx.arch]
>> + self.depcache.mark_install(nativepkg)
>> + else:
>> + return False
>> + else:
>> + if (pkgname, self.ctx.crossarch) in self.cache:
>> + crosspkg = self.cache[pkgname,
>> self.ctx.crossarch]
>> + self.depcache.mark_install(crosspkg)
>> + else:
>> + return False
>> +
>> + return True
>> +
>> + def mark_list(self, pkglist, crossbuild):
>> + ret = True
>> + if pkglist:
>> + for pkgname in pkglist:
>> + ret = ret and self.mark_pkg(pkgname, crossbuild)
>> +
>> + return ret
>> +
>> + def handle_deb(self, item):
>> + fd = open(f"{self.ctx.repodir}/repo.lock", 'w')
>> + fcntl.flock(fd, fcntl.LOCK_EX)
>> + subprocess.run([
>> + "reprepro",
>> + "--dbdir", f"{self.ctx.repodbdir}/{self.ctx.distro}",
>> + "--outdir", f"{self.ctx.repodir}/{self.ctx.distro}",
>> + "--confdir", f"{self.ctx.repodir}/{self.ctx.distro}/conf",
>> + "-C", "main",
>> + "includedeb",
>> + self.ctx.codename,
>> + item.destfile
>> + ], timeout=REPREPRO_TIMEOUT)
>> + fd.close()
>> +
>> + def handle_repo(self, fetcher):
>> + dir_cache =
>> f"../apt_cache/{self.ctx.distro}-{self.ctx.codename}"
>> + fd = open(f"{self.workdir}/{dir_cache}.lock", "w")
>> + fcntl.flock(fd, fcntl.LOCK_EX)
>> + fetcher.run()
>> + fd.close()
>> + for item in fetcher.items:
>> + if item.status == item.STAT_ERROR:
>> + print("Some error ocured: '%s'" % item.error_text)
>> + pass
>> + else:
>> + self.handle_deb(item)
>> +
>> + def get_filename(self, uri):
>> + path = urllib.parse.urlparse(uri).path
>> + unquoted_path = urllib.parse.unquote(path)
>> + basename = os.path.basename(unquoted_path)
>> + return basename
>> +
>> + def fetch_file(self, uri):
>> + filename = self.get_filename(uri)
>> + subprocess.run([
>> + "wget",
>> + "-H",
>> + "--timeout=30",
>> + "--tries=3",
>> + "-nv",
>> + uri,
>> + "-O",
>> + f"{self.workdir}/tmp/{filename}"
>> + ],
>> + stdout=subprocess.PIPE)
>
> This adds the new dependency wget.
>
> Please add to the user_manual.md
> Quirin
>
>> +
>> + def handle_dsc(self, uri):
>> + filename = self.get_filename(uri)
>> + fd = open(f"{self.ctx.repodir}/repo.lock", 'w')
>> + fcntl.flock(fd, fcntl.LOCK_EX)
>> + subprocess.run([
>> + "reprepro",
>> + "--dbdir", f"{self.ctx.repodbdir}/{self.ctx.distro}",
>> + "--outdir", f"{self.ctx.repodir}/{self.ctx.distro}",
>> + "--confdir", f"{self.ctx.repodir}/{self.ctx.distro}/conf",
>> + "-C", "main",
>> + "-S", "-", "-P" "source",
>> + "--delete",
>> + "includedsc",
>> + self.ctx.codename,
>> + os.path.realpath(f"{self.workdir}/tmp/{filename}")
>> + ], timeout=REPREPRO_TIMEOUT)
>> + fd.close()
>> +
>> + def handle_src_list(self, pkgs):
>> + if pkgs:
>> + fetched_files = []
>> + for pkg in pkgs:
>> + pkgname = pkg
>> + pkgver = ""
>> + if '=' in pkg:
>> + pkgname = pkg.split("=")[0]
>> + pkgver = pkg.split("=")[1]
>> +
>> + self.sr.restart()
>> + while self.sr.lookup(pkgname):
>> + if pkgver and pkgver != self.sr.version:
>> + continue
>> +
>> + for sr_file in self.sr.files:
>> + print(self.sr.index.archive_uri(sr_file[2]))
>> + filename = os.path.basename(sr_file.path)
>> + if filename not in fetched_files:
>> + self.fetch_file(self.sr.index.archive_uri(sr_file[2]))
>> + fetched_files.append(filename)
>> +
>> + dsc_uri =
>> self.sr.index.archive_uri(self.sr.files[0][2])
>> + self.handle_dsc(dsc_uri)
>> + break
>> +
>> + def apt_run(self, init, srcmode, pkgs, dscfile, crossbuild):
>> + apt_pkg.init()
>> +
>> + extrarepo_list =
>> f"{self.workdir}/etc/apt/sources.list.d/extrarepo.list"
>
> What happen if deb822 is mandatory?
>> + if self.extrarepo:
>> + extrarepo_list =
>> f"{self.workdir}/etc/apt/sources.list.d/extrarepo.list"
>> + with open(extrarepo_list, "w") as f:
>> + distdir=os.path.join(self.extrarepo, "dists")
>> + if os.path.isdir(distdir):
>> + for dist in os.listdir(distdir):
>> + repodir = os.path.join(distdir,dist)
>> + if os.path.isdir(repodir):
>> + for repo in os.listdir(repodir):
>> + if
>> os.path.isdir(os.path.join(repodir, repo)):
>> + f.write(f"deb
>> file://{self.extrarepo} "
>> + f"{dist} {repo}\n")
>> +
>> + sources = apt_pkg.SourceList()
>> + sources.read_main_list()
>> +
>> + progress = apt.progress.text.AcquireProgress()
>> +
>> + self.cache = apt_pkg.Cache()
>> + if init:
>> + self.cache.update(progress, sources)
>> + self.cache = apt_pkg.Cache()
>> +
>> + if self.extrarepo:
>> + apt_pkg.config.set("Dir::Etc::SourceList", extrarepo_list)
>> + apt_pkg.config.set("APT::Get::List-Cleanup", "0")
>> + self.cache.update(progress, sources)
>> + self.cache = apt_pkg.Cache()
>> + os.remove(extrarepo_list)
>> +
>> + self.depcache = apt_pkg.DepCache(self.cache)
>> + self.sr = apt_pkg.SourceRecords()
>> +
>> + ret = True
>> +
>> + if init:
>> + self.mark_essential()
>> + # 1(required), 2(important), 3(standard), 4(optional),
>> 5(extra)
>> + self.mark_by_prio(1)
>> +
>> + pkgs = list(filter(None, ','.join(pkgs).split(',')))
>> + if srcmode:
>> + self.handle_src_list(set(pkgs))
>> + else:
>> + ret = self.mark_list(pkgs, crossbuild)
>> +
>> + if dscfile:
>> + fobj = open(dscfile, "r")
>> +
>> + try:
>> + tagfile = apt_pkg.TagFile(fobj)
>> + while tagfile.step() == 1:
>> + deps = tagfile.section.get("Build-Depends", "")
>> + # Remove extra commas and spaces -
>> apt_pkg.parse_src_depends
>> + # doesnt like lines like ", device-tree-compiler"
>> + deps = ', '.join(
>> + [s.strip() for s in deps.split(',') if
>> s.strip()]
>> + )
>> + print(f"parsed deps: {deps}")
>> + for item in apt_pkg.parse_src_depends(deps, False):
>> + pkgname = item[0][0]
>> + self.mark_pkg(pkgname, crossbuild)
>> +
>> + finally:
>> + fobj.close()
>> +
>> + if not ret:
>> + sys.exit("Some of requested packages not found")
>> +
>> + if init or not srcmode:
>> + fetcher = apt_pkg.Acquire(progress)
>> + pm = apt_pkg.PackageManager(self.depcache)
>> +
>> + recs = apt_pkg.PackageRecords(self.cache)
>> + pm.get_archives(fetcher, sources, recs)
>> +
>> + self.handle_repo(fetcher)
>> +
>> +
>> +def parse_arguments():
>> + parser = argparse.ArgumentParser()
>> + parser.add_argument(
>> + "--init",
>> + default=False, action="store_true",
>> + help="initialize context in WORKDIR")
>> + parser.add_argument(
>> + "--workdir",
>> + type=str, required=True,
>> + help="work directory storing debrepo context")
>> + parser.add_argument(
>> + "--aptsrcsfile",
>> + type=str, metavar="PATH",
>> + help="sources.list file to use when init")
>> + parser.add_argument(
>> + "--srcmode",
>> + default=False, action="store_true",
>> + help="add source packages instead of debs")
>> + parser.add_argument(
>> + "--repodir",
>> + type=str, metavar="REPO",
>> + help="repository directory")
>> + parser.add_argument(
>> + "--repodbdir",
>> + type=str, metavar="REPODB",
>> + help="repository database directory")
>> + parser.add_argument(
>> + "--extrarepo",
>> + type=str, metavar="REPO",
>> + help="extra repository to consider")
>> + parser.add_argument(
>> + "--mirror",
>> + type=str,
>> + help="use custom distro mirror")
>> + parser.add_argument(
>> + "--distro",
>> + type=str,
>> + help="select distro to use")
>> + parser.add_argument(
>> + "--codename",
>> + type=str,
>> + help="distro codename")
>> + parser.add_argument(
>> + "--arch",
>> + type=str,
>> + help="distro arch")
>> + parser.add_argument(
>> + "--compatarch",
>> + type=str, metavar="ARCH",
>> + help="compat arch to use")
>> + parser.add_argument(
>> + "--crossarch",
>> + type=str, metavar="ARCH",
>> + help="cross-build arch")
>> + parser.add_argument(
>> + "--keydir",
>> + type=str,
>> + help="directory with distro keys")
>> + parser.add_argument(
>> + "--no-check-gpg",
>> + default=False, action="store_true",
>> + help="allow insecure repositories")
>> + parser.add_argument(
>> + "--dscfile",
>> + type=str, metavar="PATH",
>> + help="Debian source file to parse")
>> + parser.add_argument(
>> + "--crossbuild",
>> + default=False, action="store_true",
>> + help="add packages with cross arch")
>> +
>> + parser.add_argument(
>> + "packages",
>> + nargs='*', type=str,
>> + help="space- or comma-separated list of packages to add")
>> +
>> + args = parser.parse_args()
>> +
>> + return args
>> +
>> +
>> +def main():
>> + args = parse_arguments()
>> +
>> + if not (args.init or args.packages or args.dscfile):
>> + sys.exit("Nothing to do")
>> +
>> + workdir = os.path.abspath(args.workdir)
>> + os.makedirs(workdir, exist_ok=True)
>> +
>> + with open(f"{workdir}/debrepo.lock", "a") as file:
>> + fcntl.flock(file.fileno(), fcntl.LOCK_EX)
>> +
>> + debrepo = DebRepo(args)
>> +
>> + if args.init:
>> + debrepo.create_rootfs(args.aptsrcsfile)
>> + debrepo.create_repo_dist()
>> +
>> + debrepo.apt_config(args.init, args.crossbuild)
>> + debrepo.apt_run(args.init, args.srcmode, args.packages,
>> + args.dscfile, args.crossbuild)
>> +
>> + #Unlock debrepo context
>> + fcntl.flock(file.fileno(), fcntl.LOCK_UN)
>> +
>> +
>> +if __name__ == "__main__":
>> + main()
>
--
You received this message because you are subscribed to the Google Groups "isar-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to isar-users+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/isar-users/6fe406cf-38fe-4db1-b5e2-28c71039830e%40ilbers.de.
next prev parent reply other threads:[~2026-07-29 9:04 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-27 11:26 [v8 00/14] Improving base-apt usage Aliaksei Karpovich
2026-07-27 11:26 ` [v8 01/14] scripts: Add debrepo python script handling base-apt Aliaksei Karpovich
2026-07-27 12:36 ` 'Quirin Gylstorff' via isar-users
2026-07-29 9:03 ` Aliaksei Karpovich [this message]
2026-07-27 11:26 ` [v8 02/14] meta: Add debrepo bbclass handling base-apt prefetching Aliaksei Karpovich
2026-07-27 11:26 ` [v8 03/14] meta: Always use base-apt repo in local mode Aliaksei Karpovich
2026-07-27 11:26 ` [v8 04/14] meta: Use cached base-apt repo to bootstrap Aliaksei Karpovich
2026-07-27 11:26 ` [v8 05/14] base-apt: Predownload packages to base-apt before install Aliaksei Karpovich
2026-07-27 11:26 ` [v8 06/14] meta: Add cache-deb-src functionality in base-apt mode Aliaksei Karpovich
2026-07-27 11:26 ` [v8 07/14] testsuite: Set ISAR_PREFETCH_BASE_APT by default Aliaksei Karpovich
2026-07-27 11:26 ` [v8 08/14] Disable deb-dl-dir in base-apt prefetch mode Aliaksei Karpovich
2026-07-27 11:26 ` [v8 09/14] kas: Add PREFETCH_BASE_APT config entry Aliaksei Karpovich
2026-07-27 11:53 ` 'Jan Kiszka' via isar-users
2026-07-29 8:59 ` Aliaksei Karpovich
2026-07-27 11:26 ` [v8 10/14] ci_build.sh: Install python3-apt if not installed Aliaksei Karpovich
2026-07-27 11:26 ` [v8 11/14] rootfs: Fix URL parsing Aliaksei Karpovich
2026-07-27 11:45 ` 'Jan Kiszka' via isar-users
2026-07-29 8:54 ` Aliaksei Karpovich
2026-07-27 11:26 ` [v8 12/14] rootfs: Add version and arch for downloaded package Aliaksei Karpovich
2026-07-27 11:46 ` 'Jan Kiszka' via isar-users
2026-07-28 8:25 ` 'MOESSBAUER, Felix' via isar-users
2026-07-29 8:55 ` Aliaksei Karpovich
2026-07-30 6:33 ` 'Jan Kiszka' via isar-users
2026-07-30 7:09 ` 'MOESSBAUER, Felix' via isar-users
2026-07-27 11:26 ` [v8 13/14] sbom-chroot: Fix python3-apt dependency Aliaksei Karpovich
2026-07-27 11:49 ` 'Jan Kiszka' via isar-users
2026-07-27 11:26 ` [v8 14/14] debrepo: Add using override for reprepro Aliaksei Karpovich
2026-07-27 12:35 ` 'Quirin Gylstorff' via isar-users
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=6fe406cf-38fe-4db1-b5e2-28c71039830e@ilbers.de \
--to=akarpovich@ilbers.de \
--cc=isar-users@googlegroups.com \
--cc=quirin.gylstorff@siemens.com \
--cc=ubely@ilbers.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox