Server issue Docker dev environment compatibility: account for faulty 9p filesystem driver

Affected version
2.2.1

PaulB

Well-known member
WSL2's 9p filesystem driver is faulty: http://github.com/microsoft/WSL/issues/5074

This can cause problems with cross-platform Docker-based devkits. While this is ultimately a problem that Microsoft needs to fix, there's a quick workaround that XenForo can implement to mitigate issues with cmd.php. Microsoft hasn't shown any sign of fixing the issue, so it would be helpful to have a workaround for now.

When invoking cmd.php while src is on a bridged volume using p9fs, inodes aren't fully enumerated. Repros can be a bit finicky, but the file for xf-dev:import has a tendency to be skipped, resulting in xf-dev:import being treated as a nonexistent command.

This is specific to development on Windows; I haven't run into this issue on macOS.

Workaround for XF\Cli\Runner#getValidCommandClasses:
PHP:
protected function getValidCommandClasses(array $directoryMap)
{
    $classes = [];

    foreach ($directoryMap AS $dir => $baseClass)
    {
        $fullPath = \XF\Util\File::canonicalizePath($dir);
        if (!file_exists($fullPath) || !is_dir($fullPath))
        {
            continue;
        }

        $files = [];
        $dirStack = [];

        for ($currentDir = $fullPath; $currentDir !== null; $currentDir = array_pop($dirStack))
        {
            foreach (scandir($currentDir) AS $baseName)
            {
                if ($baseName === '.' || $baseName === '..')
                {
                    continue;
                }

                $path = $currentDir . \XF::$DS . $baseName;

                if (0 === substr_compare($baseName, '.php', -4, 4))
                {
                    $files[] = $path;
                }
                else if (is_dir($path))
                {
                    $dirStack[] = $path;
                }
            }
        }

        foreach ($files AS $file)
        {
            $localPath = substr($file, strlen($fullPath));
            $localPath = trim(strtr($localPath, '\\', '/'), '/');

            $className = $baseClass . '\\' . strtr($localPath, '/', '\\');
            $className = substr($className, 0, -4);

            if ($this->isValidCommandClass($className))
            {
                $classes[] = $className;
            }
        }
    }

    return $classes;
}
 
Last edited:

PaulB

Well-known member
On second thought, there are a lot of other places where this is an issue, so it may not be worth it.
 

PaulB

Well-known member
This bug doesn't seem to trigger with glibc builds of PHP, even though the WSL bug report seems to indicate it's possible to reproduce with glibc. Switching from Alpine to Debian is a suitable workaround for now.
 

Mike

XenForo developer
Staff member
Ultimately, I don't think this is the sort of thing that we would generally intend to workaround.
 
Top