Skip to content
Open
38 changes: 32 additions & 6 deletions pool_bin
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,10 @@ def pool_info(
pool_info(function, recursive, subpool)


def pool_init(buildroot: str) -> None:
def pool_init(buildroot: str | None) -> None:
logger.debug(f"pool_init({buildroot=})")
try:
Pool.init_create(os.path.abspath(buildroot))
Pool.init_create(buildroot)
except PoolError as e:
if DEBUG:
raise e
Expand Down Expand Up @@ -464,7 +464,7 @@ def main() -> None:
command = os.path.split(sys.argv[0])[-1]
sys.argv[0] = PROG
if command.startswith(PROG + "-"):
subcommand = command[len(PROG + "-") :]
subcommand = command[len(PROG + "-"):]
sys.argv.insert(1, subcommand)

env_vars = (
Expand Down Expand Up @@ -675,7 +675,20 @@ def main() -> None:
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=env_vars,
)
parser_init.add_argument("buildroot", help="/path/to/build-chroot")
parser_init_conflicts = parser_init.add_mutually_exclusive_group()
parser_init_conflicts.add_argument(
"buildroot",
nargs="?",
default=None,
help="/path/to/build-chroot",
)
parser_init_conflicts.add_argument(
"-N",
"--no-buildroot",
action="store_true",
help="create pool with no buildroot (for pool of pools or pre-built"
" packages)"
)
parser_init.set_defaults(func=pool_init)

# pool-list
Expand Down Expand Up @@ -743,8 +756,18 @@ def main() -> None:
if args.cmd:
func = args.func
args_dict = vars(args)
if args.cmd == "init":
# argparse handles error if both buildroot and --no-buildroot, but
# to force user to make explicit choice, error if neither set
if args.buildroot is None and not args.no_buildroot:
fatal(
"pool-init requires one of /path/to/buildroot or"
" --no-buildroot"
)
# if no_buildroot == True then buildroot is None
del args_dict["no_buildroot"]
# only pass debug for pool-get
if func.__name__ != "get" and "debug" in args:
if args.cmd != "get" and "debug" in args:
del args_dict["debug"]
del args_dict["cmd"]
del args_dict["func"]
Expand All @@ -753,7 +776,10 @@ def main() -> None:
fatal(f"{args.outputdir} does not exist")
elif not isdir(args.outputdir):
fatal(f"{args.outputdir} exists, but is not a directory")
func(**args_dict)
try:
func(**args_dict)
except PoolError as e:
fatal(e)
else:
fatal("Subcommand required.", parser.print_help)

Expand Down
34 changes: 27 additions & 7 deletions pool_lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def parse_package_filename(filename: str) -> tuple[str, str]:
return name, version


def set_deckdebuild_env(filename: str) -> dict[str, str]:
def read_pkg_deckdebuild_env(filename: str) -> dict[str, str]:
"""Read 'DECKDEBUILD_*' env vars from file.

Return dict of 'DECKDEBUILD_*' values. Values are read from repo env file
Expand Down Expand Up @@ -880,7 +880,12 @@ def __init__(
if not exists(spath):
raise PoolError(f"no pool found (POOL_DIR={self.path})")

self.buildroot = os.readlink(self.path_build_root)
self.buildroot: str | None
if islink(self.path_build_root):
self.buildroot = os.readlink(self.path_build_root)
else:
self.buildroot = None

self.pkgcache = PackageCache(self.path_pkgcache)
self.stocks = Stocks(
self.path_stocks, self.pkgcache, [*recursed_paths, self.path]
Expand Down Expand Up @@ -1014,6 +1019,11 @@ def resolve(self, unresolved: RS) -> RS:
def _build_package_source(
self, source_path: str, name: str, version: str, source: bool = False
) -> None:
if self.buildroot is None:
raise PoolError(
"Cannot build a package in a pool without a buildroot"
" configured"
)
build_outputdir = tempfile.mkdtemp(
dir=self.path_tmp, prefix=f"{name}-{version}."
)
Expand All @@ -1032,7 +1042,9 @@ def _build_package_source(
if source:
args.append("--build-source")
# read DECKDEBUILD_ENV if it exists, but existing env takes precidence
build_env = set_deckdebuild_env(join(source_path, "DECKDEBUILD_ENV"))
build_env = read_pkg_deckdebuild_env(
join(source_path, "DECKDEBUILD_ENV")
)
with in_dir(source_path):
command = [
"/usr/bin/deckdebuild",
Expand Down Expand Up @@ -1259,7 +1271,9 @@ def sort(self, key: Callable | None, reverse: bool = False) -> None:

@classmethod
def init_create(
cls: type["Pool"], buildroot: AnyPath, path: AnyPath | None = None
cls: type["Pool"],
buildroot: AnyPath | None,
path: AnyPath | None = None,
) -> "Pool":
if path is None:
cwd = os.getcwd()
Expand All @@ -1280,7 +1294,7 @@ def init_create(
if isdir(spath):
raise PoolError("pool already initialized")

if not isdir(buildroot):
if buildroot is not None and not isdir(buildroot):
raise PoolError(f"buildroot `{buildroot}' is not a directory")

mkdir(path_stocks)
Expand Down Expand Up @@ -1311,12 +1325,18 @@ def init_create(

Git.set_gitignore(spath, ["tmp"])

os.symlink(buildroot, path_build_root)
# if set, symlink path_build_root -> buildroot, otherwise touch
if buildroot is not None:
os.symlink(abspath(buildroot), path_build_root)
else:
open(path_build_root, "w").close()

return cls(path)

def __init__(
self, path: AnyPath | None = None, preserve_buildroot: str = "on-error"
self,
path: AnyPath | None = None,
preserve_buildroot: str | None = "on-error",
) -> None:
kernel = PoolKernel(path, preserve_buildroot=preserve_buildroot)
if kernel.drop_privileges(pretend=True):
Expand Down