diff --git a/dag/extdeps/exec/command.dag b/dag/extdeps/exec/command.dag index a74f09bae04..083f6dd2a31 100644 --- a/dag/extdeps/exec/command.dag +++ b/dag/extdeps/exec/command.dag @@ -82,6 +82,7 @@ fn argv_command(program: NonEmptyStr, arguments: List) -> ArgvCommand decl_ref(module_path: "extdeps.tools.gnu_coreutils", decl_name: "true_command"), decl_ref(module_path: "extdeps.tools.gnu_coreutils", decl_name: "whoami_command"), decl_ref(module_path: "extdeps.tools.gnu_coreutils", decl_name: "readlink_command"), + decl_ref(module_path: "extdeps.tools.gnu_coreutils", decl_name: "ls_one_per_line_command"), decl_ref(module_path: "extdeps.tools.findutils", decl_name: "find_symlink_target_glob_command"), decl_ref(module_path: "extdeps.tools.chmod", decl_name: "chmod_set_mode_command"), decl_ref(module_path: "extdeps.tools.stat", decl_name: "stat_owner_user_name_command"), diff --git a/dag/extdeps/tools/gnu_coreutils.dag b/dag/extdeps/tools/gnu_coreutils.dag index 11e1f8e3706..4e497249752 100644 --- a/dag/extdeps/tools/gnu_coreutils.dag +++ b/dag/extdeps/tools/gnu_coreutils.dag @@ -41,6 +41,7 @@ data printf_program: NonEmptyStr = "printf" data true_program: NonEmptyStr = "true" data whoami_program: NonEmptyStr = "whoami" data readlink_program: NonEmptyStr = "readlink" +data ls_program: NonEmptyStr = "ls" fn cat_command(path: String) -> ArgvCommand { argv_command(program: cat_program, arguments: [path]) @@ -81,6 +82,15 @@ fn readlink_command(path: String) -> ArgvCommand { argv_command(program: readlink_program, arguments: [path]) } +// -1 ALONE, NEVER -la OR A GLOB. One entry per line is what makes the output parseable as a list +// of names; a long listing would put mode, owner and size in front of every name and force the +// caller to re-parse them out. The directory is the operand, so an out-of-band entry -- one nobody +// desired -- is listed like any other, which is what keeps an observed population independent of +// the desired one. +fn ls_one_per_line_command(directory: String) -> ArgvCommand { + argv_command(program: ls_program, arguments: ["-1", directory]) +} + // install(1) — GNU coreutils, "Setting file attributes" / install invocation. The flags used // here are the ones that manual defines: -d creates each named directory, -m sets the mode, // -o and -g set owner and group at creation. Owner-at-creation is why this repository installs diff --git a/dag/gunbc/runner_slot_provision.dag b/dag/gunbc/runner_slot_provision.dag index 85c8d06ec31..2249b225855 100644 --- a/dag/gunbc/runner_slot_provision.dag +++ b/dag/gunbc/runner_slot_provision.dag @@ -38,7 +38,7 @@ import gunbc.command_runner { run_shell_command_capture, LocalExec, } -import extdeps.exec.command { ArgvCommand } +import extdeps.tools.gnu_coreutils { ls_one_per_line_command } // RunnerSlotProvision owns runner installation end-to-end in gunbc (operator ruling 2026-08-06: // ctrl is a dead repo; prior ctrl:install-actions-runner citations are void legacy pointers). @@ -237,7 +237,7 @@ func observe_runner_slot_members_wet() -> RunnerSlotObservation uses net: Network { match run_shell_command_capture( - command: ArgvCommand { argv: ["ls", "-1", actions_runner_base_dir] }, + command: ls_one_per_line_command(directory: actions_runner_base_dir), transport: LocalExec, ) { ProcessRefused { exit_code: code, stderr: err } =>