summaryrefslogtreecommitdiff
path: root/mdbp/mmdebstrap.py
diff options
context:
space:
mode:
authorHelmut Grohne <helmut@subdivi.de>2021-07-06 13:51:41 +0200
committerHelmut Grohne <helmut@subdivi.de>2021-07-06 13:51:41 +0200
commit58e77f47adf737c27e87e185adfe437dfebed6df (patch)
tree74ba8c2856e15dd210232e4cc4c4c2876810c80d /mdbp/mmdebstrap.py
parent2e9f3bddc0c9c7fd3411a2e41f49d048c93ba52e (diff)
downloadmdbp-58e77f47adf737c27e87e185adfe437dfebed6df.tar.gz
mmdebstrap and sbuild shall agree on what build_path means
While mmdebstrap would extract the package precisely to the build_path, sbuild would create a subdirectory <source>-<upstream_version> inside the build_path. Changing sbuild to do the mmdebstrap behaviour looks next to impossible, so this commit changes mmdebstrap to behave like sbuild. pbuilder also allows changing the build_path in principle. The documented BUILDDIR variable works quite similar to the sbuild option --build-path. pbuilder also allows changing the sub directory using the undocumented BUILDSUBDIR variable. That's another reason to do it like sbuild.
Diffstat (limited to 'mdbp/mmdebstrap.py')
-rw-r--r--mdbp/mmdebstrap.py55
1 files changed, 31 insertions, 24 deletions
diff --git a/mdbp/mmdebstrap.py b/mdbp/mmdebstrap.py
index c864bce..9858b65 100644
--- a/mdbp/mmdebstrap.py
+++ b/mdbp/mmdebstrap.py
@@ -16,8 +16,10 @@ import subprocess
import sys
import typing
+import debian.debian_support
+
from .common import buildjson, clean_dir, compute_env, download_dsc, \
- get_dsc_files, json_load, profile_option
+ get_dsc_files, json_load, parse_dsc, profile_option
libc = ctypes.CDLL(ctypes.util.find_library("c"))
def unshare_network() -> None:
@@ -59,19 +61,25 @@ def native_architecture() -> str:
return subprocess.check_output(["dpkg", "--print-architecture"],
encoding="ascii").strip()
+def build_subdir(dsc: debian.deb822.Dsc) -> str:
+ """Compute the subdirectory that dpkg-source normally extracts to."""
+ ver = debian.debian_support.BaseVersion(dsc["Version"]).upstream_version
+ assert ver is not None # please mypy
+ return "%s-%s" % (dsc["Source"], ver)
+
def hook_main(buildjsonfilename: str, chrootname: str) -> None:
"""The entry point for the --hook-helper invocation run from mmdebstrap."""
build = json_load(pathlib.Path(buildjsonfilename).open("r"))
chroot = pathlib.Path(chrootname)
- buildpath = pathlib.PurePath(build.get("build_path", "/build/build"))
- fullbuildpath = chroot / buildpath.relative_to("/")
+ builddir = pathlib.PurePath(build.get("build_path", "/build"))
+ fullbuilddir = chroot / builddir.relative_to("/")
if "source_package_path" in build["input"]:
- dscpath = fullbuildpath.parent / \
+ dscpath = fullbuilddir / \
pathlib.PurePath(build["input"]["source_package_path"]).name
elif "source_package_url" in build["input"]:
- dscpath = download_dsc(build["input"], fullbuildpath.parent)
+ dscpath = download_dsc(build["input"], fullbuilddir)
priv_drop(["chown", "-R", "build:build", "."],
- chroot=chroot, chdir=buildpath.parent)
+ chroot=chroot, chdir=builddir)
apt_get = ["apt-get", "--yes", "-oAPT::Keep-Downloaded-Packages=false"]
if "sourcename" in build["input"]:
sourcename = build["input"]["sourcename"]
@@ -79,13 +87,13 @@ def hook_main(buildjsonfilename: str, chrootname: str) -> None:
sourcename += "=" + build["input"]["version"]
priv_drop([*apt_get, "--only-source", "--download-only", "source",
sourcename],
- chroot=chroot, chdir=buildpath.parent, setuid="build")
- [dscpath] = fullbuildpath.parent.glob(build["input"]["sourcename"] +
- "_*.dsc")
- priv_drop(["dpkg-source", "--no-check", "--extract", dscpath.name,
- buildpath.name],
- setuid="build", chroot=chroot, chdir=buildpath.parent)
- for path in [*get_dsc_files(dscpath), dscpath]:
+ chroot=chroot, chdir=builddir, setuid="build")
+ [dscpath] = fullbuilddir.glob(build["input"]["sourcename"] + "_*.dsc")
+ dsc = parse_dsc(dscpath)
+ subdir = build_subdir(dsc)
+ priv_drop(["dpkg-source", "--no-check", "--extract", dscpath.name, subdir],
+ setuid="build", chroot=chroot, chdir=builddir)
+ for path in [*get_dsc_files(dscpath, dsc), dscpath]:
path.unlink()
hostarch = build.get("host_architecture") or \
build.get("build_architecture") or \
@@ -96,7 +104,7 @@ def hook_main(buildjsonfilename: str, chrootname: str) -> None:
*profile_option(build, "--build-profiles"),
"./"]
try:
- priv_drop(cmd, chroot=chroot, chdir=buildpath)
+ priv_drop(cmd, chroot=chroot, chdir=builddir / subdir)
except subprocess.CalledProcessError:
if build.get("bd-uninstallable-explainer") != "apt" or \
not build["output"].get("log", True):
@@ -105,20 +113,20 @@ def hook_main(buildjsonfilename: str, chrootname: str) -> None:
'-oDebug::pkgDepCache::Marker=1',
'-oDebug::pkgDepCache::AutoInstall=1',
'-oDebug::BuildDeps=1']
- priv_drop(cmd, chroot=chroot, chdir=buildpath)
+ priv_drop(cmd, chroot=chroot, chdir=builddir / subdir)
priv_drop(["dpkg-buildpackage", "-uc", "--host-arch=" + hostarch,
"--build=" + build.get("type", "binary"),
*profile_option(build, "--build-profiles=")],
chroot=chroot, setuid="build",
privnet=not build.get("network") in ("enable", "try-enable"),
- chdir=buildpath, env=compute_env(build))
- shutil.rmtree(fullbuildpath)
+ chdir=builddir / subdir, env=compute_env(build))
+ shutil.rmtree(fullbuilddir / subdir)
if build.get("lintian", {}).get("run"):
priv_drop([*apt_get, "install", "lintian"], chroot=chroot)
priv_drop(["lintian", *build["lintian"].get("options", ()),
"%s_%s.changes" % (dscpath.stem, hostarch)],
- chroot=chroot, setuid="build", chdir=buildpath.parent)
- clean_dir(fullbuildpath.parent, build["output"].get("artifacts", ["*"]))
+ chroot=chroot, setuid="build", chdir=builddir)
+ clean_dir(fullbuilddir, build["output"].get("artifacts", ["*"]))
class RawStoreAction(argparse.Action):
"""An action that stores the raw value in addition to the type-parsed
@@ -168,7 +176,7 @@ def main() -> None:
"libc-dev:" + hostarch,
"libstdc++-dev:" + hostarch,
"fakeroot"))
- buildpath = pathlib.PurePath(build.get("build_path", "/build/build"))
+ builddir = build.get("build_path", "/build")
enablelog = build["output"].get("log", True)
cmd = [
@@ -182,18 +190,17 @@ def main() -> None:
'--essential-hook=echo man-db man-db/auto-update boolean false | ' \
'chroot "$1" debconf-set-selections',
'--customize-hook=chroot "$1" useradd --user-group --create-home '
- '--home-dir %s build --skel /nonexistent' %
- shlex.quote(str(buildpath.parent)),
+ '--home-dir %s build --skel /nonexistent' % shlex.quote(builddir),
*(["--customize-hook=copy-in " + shlex.join([
build["input"]["source_package_path"],
*map(str, get_dsc_files(pathlib.Path(
build["input"]["source_package_path"]))),
- str(buildpath.parent)])]
+ builddir])]
if "source_package_path" in build["input"] else ()),
'--customize-hook=mdbp-mmdebstrap --hook-helper %s "$1"' %
shlex.quote(args.raw_buildjson),
*(["--customize-hook=sync-out " +
- shlex.join([str(buildpath.parent), build["output"]["directory"]])]
+ shlex.join([builddir, build["output"]["directory"]])]
if build["output"].get("artifacts", ["*"]) else ()),
build["distribution"],
"/dev/null",