Problem/Motivation
In #3475974: Preserve environment variables when running testing jobs there's work ongoing to allow all environment variables to be visible to test runners during test execution.
run-tests.sh fails when using sudo -E, that would allow passing the current environment variables.
Original post
In #3475974: Preserve environment variables when running testing jobs there's work ongoing to allow dropping usage of sudo to run tests. sudo prevents passing the current environment variables to the runners, and there are some that are now used for configuring PHPUnit extensions behaviour.
It would be good to try that in core, too, and in such occasion fix any permission issues with www-data.
Proposed resolution
Fix run-tests.sh bug, and adjust CI jobs to use sudo -E as appropriate.
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
Issue fork drupal-3476189
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3476189-sudo-e
changes, plain diff MR !9585
- 3476189-drop-using-sudo
changes, plain diff MR !9582
Comments
Comment #4
fjgarlin commentedThe MR shows permission denied failures: https://git.drupalcode.org/issue/drupal-3476189/-/jobs/2831557
Comment #5
cmlara-1 as this could hide real issues in file access. It is less than I originally thought (as the webserver is not running root part of functional tests will still be non-root) however that still leaves kernel and unit tests to run excessive permissions.
Sudo supports passing all environment variables using the -E flag. Tagging as needs an IS a update.
I noted in the linked issues that it appeared the problem was that run-tests.sh appeared to accidentally call sudo inside its loops (probably some how confused when looking at argv would be my guess) I would suggest core debug and fixing the underlying fault in run-tests.sh instead of switching to a privileged user for testing.
Comment #6
fjgarlin commentedThe MR made just shows the problem. It’s not the solution )or at least all of it). I agree that root should not be needed.
I think that we agree on the solution but maybe the issue description or title does not reflect that.
Comment #7
cmlaraFew minutes with the debugger. Global $php is indeed being set to the sudo path.
I have not run a full test run however it appears the solution to the root fault is to move
elseif ($sudo = getenv('SUDO_COMMAND')) {block beforeelseif ($php_env = getenv('_')) {insimpletest_script_init()(check for sudo before checking if _ is set)
Edit: I have not validated how that change would work if a user does
SUDO_COMMAND will be set in the environment however not present on the command line of the call to run-tests.sh)
Comment #8
mondrakeIt looks like we do not agree on the solution yet, actually.
I think first of all we need to agree on: what is the user (meaning, the op sys user) that should run PHPUnit tests in the context of GitLabCI? Then, with a decision, adjust accordingly.
At the moment in HEAD it's
www-databecause of the usage ofsudo.However, I repeat my comment from the related issue #3475974-27: Preserve environment variables when running testing jobs:
Elaborating a bit: I think we should run the test without sudo, just with whatever user we are executing the rest of the commands in the context of the test job. In CI, this happens to be
root.Comment #9
cmlaraCounter view:
Generally you want all tests that execute code to run as close to production as possible, this includes unit and kernel tests. Both of these can access the file system and running as root can mask faults.
In production it is unlikely the process running any of the Drupal code will have root privileges.
All our other tests (cspell, phpstan, lint, etc) are not executing the code they are just reading it for analysis as such the execution user is not relevant to the code.
Comment #11
mondrakeMR!9585 goes in the alternative direction of using the
-Eflag withsudoto keep all the env variables.Also possibly related, #3476011: Change run-tests.sh to use Symfony Process instead of proc_open.
Comment #12
cmlaraFixed up the tests to pass in HOME to clean up the small few errors that remained.
The last two remaining errors are related to Telemetry. It appears that
OTEL_COLLECTORis being set to a literal string$OTEL_COLLECTORon cursory glance I'm not 100% sure why.Perhaps Gitlab does this when its an undefined value? Though I don't understand why it would work before the sudo. Unless this was kept in an environment file for user www-data we are no longer loading, although I don't see any code doing so on cursory glance either.
Comment #14
mondrakeComment #15
mondrakeComment #16
fjgarlin commentedReally minor feedback in the MR. Two questions and a small character left.
Comment #17
fjgarlin commentedI think this is a great improvement as we know can pass all variables via
-Einstead of needing to pass one by one.There is some really minor feedback on the MR, some of it already addressed and some of it might just be a non-issue at all.
This change will also simplify the solution for the
gitlab_templatesrelated issue.I'm setting it to RTBC.
Comment #18
mondrakeAdded a test skip in case OTEL_COLLECTOR is empty. But not sure we want to skip the test overall in that case. Anyway, up for review.
Comment #19
mondrakeReverted last commit on a better thinking. Back to RTBC as it was.
Comment #20
mondrakeIMHO this needs backport to all branches currently tested so the parallel contrib issue can benefit as well.
Comment #21
cmlaraI will note gitlab_templates probably should just use the
—phpflag for run-tests.sh as it allows them to support versions this can’t be backported for (existing tagged releases) for those who may do min/max testing.They could do the above today without waiting for this issue.
Comment #22
quietone commentedEverything looks in order here, no unanswered questions.
Comment #23
larowlanLeft one question on the MR
Comment #24
andypostMaybe instead of using such a long
sudocommand it's better to add simple wrapper-script tosource .test.envbefore running the command.Moreover it will make logs shorter and less noisy to parse!
Comment #25
andypostAlso it should be enough to use
sufor this purpose so more secure environmentComment #26
mondrakeComment #27
murzNow we use
sudo -u www-data -E HOME=/var/wwwto set the correct home directory path, butsudoprovides also-H, --set-homeoption that does the same, so maybe let's use it instead?Comment #28
mondrake@murz that seems sensible; let’s try it and see if it works
Comment #29
murzI pushed the changes, please review.
Comment #30
mondrakeTests pass (apart from the usual bunch of random fails in functional ones), so it seems to be working. Setting back to RTBC.
Comment #31
mondrakeFrom https://linux.die.net/man/8/sudo, emphasis mine:
Comment #32
longwaveRe
OTEL_COLLECTORthis is injected into the scheduled core performance test pipelines directly in GitLab.There is also code in PerformanceTestTrait::openTelemetryTracing() that skips sending to the collector if the variable is not set:
The scheduled performance runs ensure that we get precise timings recorded regularly. Outside of those, the same tests should still run without the collector as they perform various assertions about numbers of queries, etc, and it is important to know for every MR whether we have affected cold/warm cached page loads.
Comment #33
quietone commentedI did a light review of the comment and I don't see any response to the suggestions by andypost in #24.
Comment #34
mondrake#24 is
abovebeyond me, but to me it sounds like it can be a follow up anyway.Comment #35
longwaveAdded a comment about OTEL_COLLECTOR, setting it to the empty string is a bit confusing when we shouldn't need it at all - I think we can remove it entirely.
Comment #36
mondrakeApplied suggestion.
Comment #37
mondrakeI think the change is minor enough to let me RTBC back. Tests are green.
Comment #39
longwaveI think we only need this on 11.x, it doesn't backport cleanly to 10.x either. Please open a backport MR if you disagree!
Committed eba0136 and pushed to 11.x. Thanks!
Comment #41
mondrake#39 agree backport is not necessary for core, but I am not sure about contrib. Will drop a line in Slack/gitlab.
Comment #42
mondrakeSlack discussion on backport: https://drupal.slack.com/archives/CGKLP028K/p1735851033816899