mediasoup: npm postinstall fails in Windows: rd /s /q worker\out\msys => The system cannot find the file specified
Bug Report
This is a recent error happening in Windows CI: https://github.com/versatica/mediasoup/actions/runs/6536142903/job/17747178461?pr=1178
npm-scripts [INFO] [postinstall] executeCmd(): rd /s /q worker\out\msys
The system cannot find the file specified.
npm-scripts [ERROR] [postinstall] executeCmd() failed, exiting: Error: Command failed: rd /s /q worker\out\msys
Nothing has changed so this is related to Windows. No idea. We need to make it work reliably in all supported Windows versions.
Somehow the issue doesn’t make sense. When installing mediasoup on Windows (and forcing it to compile the worker instead of fetching a prebuilt worker), this is the flow:
MEDIASOUP_SKIP_WORKER_PREBUILT_DOWNLOAD=true npm install mediasoup --foreground-scripts(well, whichever syntax is needed in Windows to set environment variables).- The npm ‘postinstall’ task will run the ‘postinstall’ section in
npm-scripts.mjs. - It will first fun
buildWorker():
function buildWorker()
{
logInfo('buildWorker()');
if (IS_WINDOWS)
{
if (!fs.existsSync('worker/out/msys/bin/make.exe'))
{
installMsysMake();
}
const msysPath = `${process.cwd()}\\worker\\out\\msys\\bin`;
if (!process.env.PATH.includes(msysPath))
{
process.env.PATH = `${msysPath};${process.env.PATH}`;
}
}
executeCmd(`${MAKE} -C worker`);
}
- Note that if
worker/out/msys/bin/make.exedoesn’t exist then it callsinstallMsysMake()which does this:
function installMsysMake()
{
logInfo('installMsysMake()');
let res = spawnSync('where', [ 'python3.exe' ]);
if (res.status !== 0)
{
res = spawnSync('where', [ 'python.exe' ]);
if (res.status !== 0)
{
logError('`installMsysMake() | cannot find Python executable');
exitWithError();
}
}
executeCmd(`${String(res.stdout).trim()} worker\\scripts\\getmake.py`);
}
- So here it ensures that we have
python3.exeand then runsworker/scripts/getmake.pywhich does this:
import io, hashlib, tarfile, urllib.request
def get(url, digest):
data = urllib.request.urlopen(url).read()
assert hashlib.sha256(data).hexdigest() == digest
tar = tarfile.open(fileobj=io.BytesIO(data))
tar.extractall('worker/out/msys')
tar.close()
get('https://sourceforge.net/projects/mingw/files/MSYS/Base/msys-core/msys-1.0.19-1/msysCORE-1.0.19-1-msys-1.0.19-bin.tar.xz/download', '8c4157d739a460f85563bc4451e9f1bbd42b13c4f63770d43b9f45a781f07858')
get('https://sourceforge.net/projects/mingw/files/MSYS/Base/libiconv/libiconv-1.14-1/libiconv-1.14-1-msys-1.0.17-dll-2.tar.lzma/download', '196921e8c232259c8e6a6852b9ee8d9ab2d29a91419f0c8dc27ba6f034231683')
get('https://sourceforge.net/projects/mingw/files/MSYS/Base/gettext/gettext-0.18.1.1-1/libintl-0.18.1.1-1-msys-1.0.17-dll-8.tar.lzma/download', '29db8c969661c511fbe2a341ab25c993c5f9c555842a75d6ddbcfa70dec16910')
get('https://sourceforge.net/projects/mingw/files/MSYS/Base/coreutils/coreutils-5.97-3/coreutils-5.97-3-msys-1.0.13-bin.tar.lzma/download', 'f8c7990416ea16a74ac336dcfe0f596bc46b8724b2d58cf8a3509414220b2366')
get('https://sourceforge.net/projects/mingw/files/MSYS/Base/regex/regex-1.20090805-2/libregex-1.20090805-2-msys-1.0.13-dll-1.tar.lzma/download', '85dd8c1e27a90675c5f867be57ba7ae2bb55dde8cd2d19f284c896be134bd3d1')
get('https://sourceforge.net/projects/mingw/files/MSYS/Base/termcap/termcap-0.20050421_1-2/libtermcap-0.20050421_1-2-msys-1.0.13-dll-0.tar.lzma/download', '62b58fe0880f0972fcc84a819265989b02439c1c5185870227bd25f870f7adb6')
get('https://sourceforge.net/projects/mingw/files/MSYS/Base/bash/bash-3.1.23-1/bash-3.1.23-1-msys-1.0.18-bin.tar.xz/download', '38da5419969ab883058a96322bb0f51434dd4e9f71de09cd4f75b96750944533')
get('https://sourceforge.net/projects/mingw/files/MSYS/Base/make/make-3.81-3/make-3.81-3-msys-1.0.13-bin.tar.lzma/download', '847f0cbbf07135801c8e67bf692d29b1821e816ad828753c997fa869a9b89988')
- Here it clearly extracts things in
worker/out/msysfolder, notice thetar.extractall('worker/out/msys')line. - So then
buildWorker()continues. It adds${process.cwd()}\\worker\\out\\msys\\binto thePATHand runsmaketo compile the worker. - And then
buildWorker()completes socleanWorkerArtifacts()is called which does this:
function cleanWorkerArtifacts()
{
logInfo('cleanWorkerArtifacts()');
// Clean build artifacts except `mediasoup-worker`.
executeCmd(`${MAKE} clean-build -C worker`);
// Clean downloaded dependencies.
executeCmd(`${MAKE} clean-subprojects -C worker`);
// Clean PIP/Meson/Ninja.
executeCmd(`${MAKE} clean-pip -C worker`);
if (IS_WINDOWS)
{
executeCmd('rd /s /q worker\\out\\msys');
}
}
- And somehow the last command
rd /s /q worker\\out\\msysfails only in some cases (see https://github.com/versatica/mediasoup/issues/1179#issuecomment-1770463999) with this error:
npm-scripts [INFO] [postinstall] executeCmd(): rd /s /q worker\out\msys
The system cannot find the file specified.
npm-scripts [ERROR] [postinstall] executeCmd() failed, exiting: Error: Command failed: rd /s /q worker\out\msys
- How is it possible? Obviously
worker\out\msysfolder DOES exist, it’s guaranteed by steps before.
About this issue
- Original URL
- State: closed
- Created 8 months ago
- Comments: 26 (13 by maintainers)
I do not know how/what/where, but it is clear that the files are not there. Or maybe they are extracted into
worker/out/msys, but it is notworker/out/msysthat we think it is or something (maybepwdinside of Python script is different, so it extracts files elsewhere, providing an absolute path would fix that particular issue).Asking to a workmate.
@jmillan @nazar-pc are we ok with the temporary solution I suggest in my comment above?