Skip to content

Commit

Permalink
Add rootless build support to 'build' command for 'kvm' and 'podman' …
Browse files Browse the repository at this point in the history
…vm types

To avoid filesystem permission collisions with the builds using su_wrapper,
use an alternative buildroot path that appends username to '/var/tmp/build-root' for the rootless builds.
  • Loading branch information
dmach committed Sep 27, 2023
1 parent 2f1cb0e commit 8eb3602
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 12 deletions.
34 changes: 28 additions & 6 deletions osc/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# either version 2, or (at your option) any later version.

import fnmatch
import getpass
import glob
import os
import re
Expand Down Expand Up @@ -605,9 +606,24 @@ def calculate_prj_pac(store, opts, descr):
return project, package


def calculate_build_root(apihost, prj, pac, repo, arch):
buildroot = conf.config["build-root"] \
% {'repo': repo, 'arch': arch, 'project': prj, 'package': pac, 'apihost': apihost}
def calculate_build_root_user(vm_type):
if vm_type in ("kvm", "podman"):
return getpass.getuser()
return None


def calculate_build_root(apihost, prj, pac, repo, arch, user=None):
user = user or ""
dash_user = f"-{user:s}" if user else ""
buildroot = conf.config["build-root"] % {
'apihost': apihost,
'project': prj,
'package': pac,
'repo': repo,
'arch': arch,
"user": user,
"dash_user": dash_user,
}
return buildroot


Expand All @@ -632,9 +648,12 @@ def su_wrapper(cmd):
def run_build(opts, *args):
cmd = [conf.config['build-cmd']]
cmd += args

cmd = su_wrapper(cmd)

user = calculate_build_root_user(opts.vm_type)
if not user:
cmd = su_wrapper(cmd)

if not opts.userootforbuild:
cmd.append('--norootforbuild')
return run_external(cmd[0], *cmd[1:])
Expand Down Expand Up @@ -793,7 +812,8 @@ def main(apiurl, store, opts, argv):
pacname = os.path.splitext(os.path.basename(build_descr))[0]
apihost = urlsplit(apiurl)[1]
if not build_root:
build_root = calculate_build_root(apihost, prj, pacname, repo, arch)
user = calculate_build_root_user(vm_type)
build_root = calculate_build_root(apihost, prj, pacname, repo, arch, user)

# We configure sccache after pacname, so that in default cases we can have an sccache for each
# package to prevent cross-cache polutions. It helps to make the local-use case a bit nicer.
Expand Down Expand Up @@ -1472,7 +1492,9 @@ def __str__(self):
cmd += specialcmdopts + vm_options + buildargs
cmd += [build_descr]

cmd = su_wrapper(cmd)
# determine if we're building under root (user == None) and use su_wrapper accordingly
if calculate_build_root_user(vm_type) is None:
cmd = su_wrapper(cmd)

# change personality, if needed
if hostarch != bi.buildarch and bi.buildarch in change_personality:
Expand Down
7 changes: 4 additions & 3 deletions osc/commandline.py
Original file line number Diff line number Diff line change
Expand Up @@ -7267,7 +7267,8 @@ def do_build(self, subcmd, opts, *args):
repo, arch, build_descr = args
prj, pac = osc_build.calculate_prj_pac(store, opts, build_descr)
apihost = urlsplit(self.get_api_url())[1]
build_root = osc_build.calculate_build_root(apihost, prj, pac, repo, arch)
user = osc_build.calculate_build_root_user(opts.vm_type)
build_root = osc_build.calculate_build_root(apihost, prj, pac, repo, arch, user)
print(build_root)
return

Expand All @@ -7280,8 +7281,8 @@ def do_build(self, subcmd, opts, *args):
repo, arch, build_descr = args
prj, pac = osc_build.calculate_prj_pac(store, opts, build_descr)
apihost = urlsplit(self.get_api_url())[1]
build_root = osc_build.calculate_build_root(apihost, prj, pac, repo,
arch)
user = osc_build.calculate_build_root_user(opts.vm_type)
build_root = osc_build.calculate_build_root(apihost, prj, pac, repo, arch, user)
if opts.wipe and not opts.force:
# Confirm delete
print("Really wipe '%s'? [y/N]: " % build_root)
Expand Down
9 changes: 6 additions & 3 deletions osc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -997,13 +997,16 @@ def apiurl_aliases(self):
) # type: ignore[assignment]

build_root: str = Field(
default="/var/tmp/build-root/%(repo)s-%(arch)s",
default="/var/tmp/build-root%(dash_user)s/%(repo)s-%(arch)s",
description=textwrap.dedent(
"""
Path to the build root directory.
Supported substitutions: ``%(repo)s``, ``%(arch)s``, ``%(project)s``, ``%(package)s`` and ``%(apihost)s``
where ``apihost`` is the hostname extracted from the currently used ``apiurl``.
Supported substitutions: ``%(repo)s``, ``%(arch)s``, ``%(project)s``, ``%(package)s``, ``%(apihost)s``, ``%(user)s``, ``%(dash_user)s``
where::
- ``apihost`` is the hostname extracted from the currently used ``apiurl``.
- ``dash_user`` is the username prefixed with a dash. If ``user`` is empty, ``dash_user`` is also empty.
NOTE: The configuration holds the original unexpanded string. Call ``osc.build.get_build_root()`` with proper arguments to retrieve an actual path.
Expand Down

0 comments on commit 8eb3602

Please sign in to comment.