Skip to content

Commit

Permalink
fix: use /tmp dir if $HOME isn't writable (#1770)
Browse files Browse the repository at this point in the history
* fix: use tmp dir if $HOME isn't writable

* Test for running without home

---------

Co-authored-by: Alejandro R. Mosteo <[email protected]>
  • Loading branch information
atalii and mosteo authored Oct 2, 2024
1 parent 8972bc5 commit 0288880
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 9 deletions.
24 changes: 24 additions & 0 deletions src/alire/alire-platforms-common.adb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
with AAA.Enum_Tools;
with GNAT.OS_Lib;

with Alire.OS_Lib.Subprocess;

Expand Down Expand Up @@ -71,4 +72,27 @@ package body Alire.Platforms.Common is
end Detect;
end Machine_Hardware_Name;

----------------------
-- Unix_Home_Folder --
----------------------

function Unix_Home_Folder return String
is
Home_Var : constant String := OS_Lib.Getenv ("HOME", "unset");
Maybe_Windows : constant Boolean := Home_Var = "unset"
and then GNAT.OS_Lib.Directory_Separator = '\';
begin
if Maybe_Windows then
raise Checked_Error with
"$HOME is not set, you might be running an"
& " `alr` built for a non-Windows OS";
elsif Home_Var = "unset" or else
not GNAT.OS_Lib.Is_Write_Accessible_File (Home_Var)
then
return "/tmp";
else
return Home_Var;
end if;
end Unix_Home_Folder;

end Alire.Platforms.Common;
10 changes: 1 addition & 9 deletions src/alire/alire-platforms-common.ads
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,7 @@ private package Alire.Platforms.Common is
-- Unix_Home_Folder --
---------------------

function Unix_Home_Folder return String
is (if OS_Lib.Getenv ("HOME", "unset") = "unset" and then
GNAT.OS_Lib.Directory_Separator = '\'
then
raise Checked_Error with
"$HOME is not set, you might be running an"
& " `alr` built for a non-Windows OS"
else
OS_Lib.Getenv ("HOME", Default => "/tmp"));
function Unix_Home_Folder return String;

----------------------
-- Unix_Temp_Folder --
Expand Down
1 change: 1 addition & 0 deletions src/alr/alr-commands-version.adb
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ package body Alr.Commands.Version is

Add ("");
Add ("CONFIGURATION");
Add ("home folder:", Alire.Platforms.Folders.Home);
Add ("settings folder:", Alire.Settings.Edit.Path);
Add ("cache folder:", Alire.Cache.Path);
Add ("vault folder:", Paths.Vault.Path);
Expand Down
40 changes: 40 additions & 0 deletions testsuite/tests/dockerized/misc/no-home/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""
Verify that alr can run with no HOME set, or with it set to an
unwritable/nonexistent directory.
NOTE: This same test is duplicated to be run under docker as a regular user.
"""

import os
from drivers.alr import run_alr


def check_no_home():
# Verify that alr is using the fallback home directory.
p = run_alr("--format", "version")
assert """{
"key": "home folder",
"value": "/tmp"
}""" in p.out, "Unexpected output: " + p.out


# Remove HOME
os.environ.pop("HOME", None)
check_no_home()

# Set HOME to a nonexistent directory
fake_home = "/tmp/fake_home_for_alr"
assert not os.path.exists(fake_home)
os.environ["HOME"] = fake_home
check_no_home()

# Set HOME to an unwritable directory
# Under our docker, we should be a regular user and this should succeed
os.makedirs(fake_home)
os.chmod(fake_home, 0o444)
check_no_home()
# Cleanup
os.chmod(fake_home, 0o777)
os.rmdir(fake_home)


print("SUCCESS")
7 changes: 7 additions & 0 deletions testsuite/tests/dockerized/misc/no-home/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
driver: docker-wrapper
build_mode: both
control:
- [SKIP, "skip_docker", "Test is Docker-only"]
- [SKIP, "skip_unix", "Test is Unix-only"]
indexes:
compiler_only_index: {}
42 changes: 42 additions & 0 deletions testsuite/tests/misc/no-home/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""
Verify that alr can run with no HOME set, or with it set to an
unwritable/nonexistent directory.
NOTE: This same test is duplicated to be run under docker as a regular user.
"""

import os
from drivers.alr import run_alr


def check_no_home():
# Verify that alr is using the fallback home directory.
p = run_alr("--format", "version")
assert """{
"key": "home folder",
"value": "/tmp"
}""" in p.out, "Unexpected output: " + p.out


# Remove HOME
os.environ.pop("HOME", None)
check_no_home()

# Set HOME to a nonexistent directory
fake_home = "/tmp/fake_home_for_alr"
assert not os.path.exists(fake_home)
os.environ["HOME"] = fake_home
check_no_home()

# Set HOME to an unwritable directory
# This will fail if running under root, in which case we skip this part.
# This is tested properly under docker
if os.getuid() != 0:
os.makedirs(fake_home)
os.chmod(fake_home, 0o444)
check_no_home()
# Cleanup
os.chmod(fake_home, 0o777)
os.rmdir(fake_home)


print("SUCCESS")
6 changes: 6 additions & 0 deletions testsuite/tests/misc/no-home/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
driver: python-script
build_mode: both
control:
- [SKIP, "skip_unix", "Test is Unix-only"]
indexes:
compiler_only_index: {}

0 comments on commit 0288880

Please sign in to comment.