Skip to content

Commit 8f04a02

Browse files
committed
fix: properly handle root requirement for apt build-dep in build drivers
1 parent f2d4276 commit 8f04a02

File tree

7 files changed

+41
-21
lines changed

7 files changed

+41
-21
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,6 @@ jobs:
123123
- name: Install the project
124124
run: uv sync --locked --all-extras --dev
125125
- name: Install required apt
126-
run: apt-get install -y devscripts
126+
run: sudo apt-get install -y devscripts
127127
- name: Run Debmagic build on ourself
128128
run: uv run debmagic build --driver=none

src/debmagic/_build_driver/build.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def _create_driver(build_driver: BuildDriverType, config: BuildConfig) -> BuildD
1818
def build(build_driver: BuildDriverType, config: BuildConfig):
1919
driver = _create_driver(build_driver, config)
2020
try:
21-
driver.run_command(["apt-get", "-y", "build-dep", "."], cwd=config.source_dir)
21+
driver.run_command(["apt-get", "-y", "build-dep", "."], cwd=config.source_dir, requires_root=True)
2222
driver.run_command(["debuild", "-nc", "-uc", "-b"], cwd=config.source_dir)
2323

2424
# TODO: copy packages to output directory

src/debmagic/_build_driver/common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def create(cls, config: BuildConfig) -> "BuildDriver":
2727
pass
2828

2929
@abc.abstractmethod
30-
def run_command(self, args: Sequence[str | Path], cwd: Path | None = None):
30+
def run_command(self, args: Sequence[str | Path], cwd: Path | None = None, requires_root: bool = False):
3131
pass
3232

3333
@abc.abstractmethod

src/debmagic/_build_driver/driver_docker.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ def create(cls, config: BuildConfig):
9797
instance = cls(config=config, workdir=workdir, container_name=docker_container_name)
9898
return instance
9999

100-
def run_command(self, args: Sequence[str | Path], cwd: Path | None = None):
100+
def run_command(self, args: Sequence[str | Path], cwd: Path | None = None, requires_root: bool = False):
101+
del requires_root # we assume to always be root in the container
102+
101103
if cwd:
102104
cwd = self._translate_source_path(cwd)
103105

src/debmagic/_build_driver/driver_lxd.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@ class BuildDriverLxd(BuildDriver):
99
def create(cls, config: BuildConfig):
1010
return cls()
1111

12-
def run_command(self, args: Sequence[str | Path], cwd: Path | None = None):
12+
def run_command(self, args: Sequence[str | Path], cwd: Path | None = None, requires_root: bool = False):
13+
raise NotImplementedError()
14+
15+
def copy_file(self, source_dir: Path, glob: str, dest_dir: Path):
1316
raise NotImplementedError()
1417

1518
def cleanup(self):
16-
pass
19+
raise NotImplementedError()
20+
21+
def drop_into_shell(self):
22+
raise NotImplementedError()

src/debmagic/_build_driver/driver_none.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
import shutil
23
from pathlib import Path
34
from typing import Sequence
@@ -14,7 +15,9 @@ def __init__(self, config: BuildConfig) -> None:
1415
def create(cls, config: BuildConfig):
1516
return cls(config=config)
1617

17-
def run_command(self, args: Sequence[str | Path], cwd: Path | None = None):
18+
def run_command(self, args: Sequence[str | Path], cwd: Path | None = None, requires_root: bool = False):
19+
if requires_root and not os.getuid() == 0:
20+
args = ["sudo", *args]
1821
run_cmd(args=args, dry_run=self._config.dry_run, cwd=cwd)
1922

2023
def copy_file(self, source_dir: Path, glob: str, dest_dir: Path):

src/debmagic/_utils.py

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import subprocess
77
import sys
88
from pathlib import Path
9-
from typing import Sequence
9+
from typing import Callable, Sequence
1010

1111

1212
class Namespace:
@@ -88,22 +88,31 @@ def run_cmd_in_foreground(args: Sequence[str | Path], **kwargs):
8888
old_pgrp = os.tcgetpgrp(sys.stdin.fileno())
8989
old_attr = termios.tcgetattr(sys.stdin.fileno())
9090

91-
# generally, the child process should stop itself
92-
# before exec so the parent can set its new pgid.
93-
# (setting pgid has to be done before the child execs).
94-
# however, Python 'guarantee' that `preexec_fn`
95-
# is run before `Popen` returns.
96-
# this is because `Popen` waits for the closure of
97-
# the error relay pipe '`errpipe_write`',
98-
# which happens at child's exec.
99-
# this is also the reason the child can't stop itself
100-
# in Python's `Popen`, since the `Popen` call would never
101-
# terminate then.
102-
# `os.kill(os.getpid(), signal.SIGSTOP)`
91+
user_preexec_fn: Callable | None = kwargs.pop("preexec_fn", None)
92+
93+
def new_pgid():
94+
if user_preexec_fn:
95+
user_preexec_fn()
96+
97+
# set a new process group id
98+
os.setpgid(os.getpid(), os.getpid())
99+
100+
# generally, the child process should stop itself
101+
# before exec so the parent can set its new pgid.
102+
# (setting pgid has to be done before the child execs).
103+
# however, Python 'guarantee' that `preexec_fn`
104+
# is run before `Popen` returns.
105+
# this is because `Popen` waits for the closure of
106+
# the error relay pipe '`errpipe_write`',
107+
# which happens at child's exec.
108+
# this is also the reason the child can't stop itself
109+
# in Python's `Popen`, since the `Popen` call would never
110+
# terminate then.
111+
# `os.kill(os.getpid(), signal.SIGSTOP)`
103112

104113
try:
105114
# fork the child
106-
child = subprocess.Popen(args, process_group=os.getpid(), **kwargs)
115+
child = subprocess.Popen(args, preexec_fn=new_pgid, **kwargs) # noqa: PLW1509
107116

108117
# we can't set the process group id from the parent since the child
109118
# will already have exec'd. and we can't SIGSTOP it before exec,

0 commit comments

Comments
 (0)