/dev/null || true"], $server, false )); $paths = collect([...self::UPGRADE_PATHS, $dockerRootDir ?: self::DEFAULT_DOCKER_ROOT_DIR]) ->map(fn (string $path) => escapeshellarg($path)) ->implode(' '); $output = instant_remote_process(["df -Pk {$paths} 2>/dev/null || true"], $server, false); return self::parseDfOutput((string) $output); } /** * Read the smallest "Available" column (in 1K blocks) from `df -Pk` output and return it in GB. */ public static function parseDfOutput(string $output): ?float { $availableKb = collect(preg_split('/\R/', trim($output))) ->skip(1) ->map(fn (string $line) => preg_split('/\s+/', trim($line))[3] ?? null) ->filter(fn (?string $value) => $value !== null && ctype_digit($value)) ->map(fn (string $value) => (int) $value) ->min(); if ($availableKb === null) { return null; } return round($availableKb / 1024 / 1024, 1); } public static function isLow(?float $availableGb): bool { return $availableGb !== null && $availableGb < self::REQUIRED_GB; } }