Skip to content

Commit

Permalink
Disable building Arch packages when Docker is mapping users
Browse files Browse the repository at this point in the history
- Arch's `makepkg` cannot be run as root
  • Loading branch information
rmartin16 committed Jul 9, 2023
1 parent 24cdf4c commit 3a331b2
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 4 deletions.
15 changes: 15 additions & 0 deletions src/briefcase/platforms/linux/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,21 @@ def finalize_app_config(self, app: AppConfig):

if not self.use_docker:
app.target_image = f"{app.target_vendor}:{app.target_codename}"
else:
if app.target_vendor_base == ARCH and self.tools.docker.is_users_mapped:
raise BriefcaseCommandError(
"""\
Briefcase cannot use this Docker installation to target Arch Linux since the
tools to build packages for Arch cannot be run as root.
However, the Docker available to Briefcase requires the use of the root user in
containers to maintain accurate file permissions of the build artefacts.
This most likely means you're using Docker Desktop or rootless Docker.
Install Docker Engine and try again or run Briefcase on an Arch host system.
"""
)

# Merge target-specific configuration items into the app config This
# means:
Expand Down
59 changes: 55 additions & 4 deletions tests/platforms/linux/system/test_mixin__finalize_app_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@


def test_docker(create_command, first_app_config):
"An app can be finalized inside docker"
"""An app can be finalized inside docker."""
# Build the app on a specific target
create_command.target_image = "somevendor:surprising"
create_command.tools.docker = MagicMock()
Expand Down Expand Up @@ -41,7 +41,7 @@ def test_docker(create_command, first_app_config):


def test_nodocker(create_command, first_app_config, tmp_path):
"An app can be finalized without docker"
"""An app can be finalized without docker."""
# Build the app without docker
create_command.target_image = None
create_command.target_glibc_version = MagicMock(return_value="2.42")
Expand Down Expand Up @@ -77,7 +77,7 @@ def test_nodocker(create_command, first_app_config, tmp_path):


def test_nodocker_non_freedesktop(create_command, first_app_config, tmp_path):
"If the system isn't FreeDesktop compliant raise an error"
"""If the system isn't FreeDesktop compliant raise an error."""
# Build the app without docker
create_command.target_image = None
create_command.target_glibc_version = MagicMock(return_value="2.42")
Expand All @@ -100,6 +100,57 @@ def test_nodocker_non_freedesktop(create_command, first_app_config, tmp_path):
create_command.finalize_app_config(first_app_config)


def test_docker_arch_with_user_mapping(create_command, first_app_config, tmp_path):
"""If Docker is mapping users and the host system is Arch, an error is raised."""
# Build the app on a specific target
create_command.target_image = "somearch:surprising"
create_command.tools.docker = MagicMock()
create_command.tools.docker.is_users_mapped = True
create_command.target_glibc_version = MagicMock(return_value="2.42")

# Mock a minimal response for an Arch /etc/os-release
create_command.tools.docker.check_output.return_value = "\n".join(
[
"ID=arch",
"VERSION_ID=20230625.0.160368",
]
)

# Finalize the app config
with pytest.raises(
BriefcaseCommandError,
match="Briefcase cannot use this Docker installation",
):
create_command.finalize_app_config(first_app_config)


def test_docker_arch_without_user_mapping(create_command, first_app_config, tmp_path):
"""If Docker is *not* mapping users and the host system is Arch, an error is not
raised."""
# Build the app on a specific target
create_command.target_image = "somearch:surprising"
create_command.tools.docker = MagicMock()
create_command.tools.docker.is_users_mapped = False
create_command.target_glibc_version = MagicMock(return_value="2.42")

# Mock a minimal response for an Arch /etc/os-release
create_command.tools.docker.check_output.return_value = "\n".join(
[
"ID=arch",
"VERSION_ID=20230625.0.160368",
]
)

# Finalize the app config
create_command.finalize_app_config(first_app_config)

# The app's image, vendor and codename have been constructed from the target image
assert first_app_config.target_image == "somearch:surprising"
assert first_app_config.target_vendor == "arch"
assert first_app_config.target_codename == "20230625"
assert first_app_config.target_vendor_base == "arch"


def test_properties(create_command, first_app_config):
"""The final app config is the result of merging target properties, plus other
derived properties."""
Expand Down Expand Up @@ -414,7 +465,7 @@ def test_properties_no_version(create_command, first_app_config):


def test_passive_mixin(first_app_config, tmp_path):
"An app using the PassiveMixin can be finalized"
"""An app using the PassiveMixin can be finalized."""
run_command = LinuxSystemRunCommand(
logger=Log(),
console=Console(),
Expand Down

0 comments on commit 3a331b2

Please sign in to comment.