From ae2033865cf59c2072c1591d58fff9ee1f4d5308 Mon Sep 17 00:00:00 2001 From: Mikkeli Date: Wed, 26 Aug 2026 23:50:09 +0900 Subject: [PATCH] fix(ci): probe writability by writing, not with test -w MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The setup script refused to provision, reporting /opt/flutter/bin/cache and /opt/android-sdk unwritable by the service account, while a touch as that same account succeeded. Cause: this machine's /usr/bin/test is uutils coreutils 0.8.0, whose -w does not credit supplementary group membership. Write access to both directories comes from the flutterdev group rather than the owner bits, so -w reports false for any account that should be building here — including the developer's own. -r and -x pass only because `other` carries r-x, which is what made the failure look ACL-shaped. bash's builtin [ -w ] evaluates it correctly, but sudo execs the external binary, so the builtin was never in play. Replaced with a real write probe: create a file as the service account and remove it. That tests the operation a build actually performs and is immune to whichever test implementation is installed, which is the better check regardless of the bug that prompted it. Co-Authored-By: Claude Opus 5 --- tool/setup_ci_runner.sh | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/tool/setup_ci_runner.sh b/tool/setup_ci_runner.sh index 382aa49..0d629ec 100755 --- a/tool/setup_ci_runner.sh +++ b/tool/setup_ci_runner.sh @@ -123,20 +123,32 @@ id "$RUNNER_USER" # Group membership is worthless if the ACLs disagree, so prove it rather than # assume it — as the service user, against the paths a build actually writes. +# +# By actually writing a file, not by asking `test -w`. This machine's +# /usr/bin/test is uutils coreutils 0.8.0, whose -w does not credit +# supplementary group membership: it reports /opt/android-sdk unwritable for +# any account whose write access comes from the flutterdev group rather than +# from the owner bits — which is every account that should be running builds +# here. (-r and -x pass only because `other` has r-x.) bash's builtin `[ -w ]` +# gets it right, but sudo execs the external binary, so the builtin is not +# available here. A write probe is immune to the whole question. say "Verifying $RUNNER_USER can write the SDKs" -acl_ok=1 +write_ok=1 for d in "/opt/flutter/bin/cache" "$SDK"; do - if sudo -u "$RUNNER_USER" test -w "$d"; then + if sudo -u "$RUNNER_USER" env probe="$d/.gitea-runner-probe.$$" \ + sh -c 'touch "$probe" && rm -f "$probe"' 2>/dev/null; then printf ' ok writable: %s\n' "$d" else printf ' FAIL not writable: %s\n' "$d" - acl_ok=0 + sudo -u "$RUNNER_USER" rm -f "$d/.gitea-runner-probe.$$" 2>/dev/null || true + write_ok=0 fi done -if [[ $acl_ok -ne 1 ]]; then +if [[ $write_ok -ne 1 ]]; then echo - echo "$RUNNER_USER is in $SDK_GROUP but still cannot write. Check the ACLs:" >&2 + echo "$RUNNER_USER is in $SDK_GROUP but still cannot write. Check:" >&2 echo " getfacl /opt/flutter /opt/android-sdk" >&2 + echo " id $RUNNER_USER" >&2 exit 1 fi