serverless-python-requirements: Invalid Mode /test when deploying using 4.2.5

After running sls deploy invalid mode error appears when using 4.2.5, works fine on 4.2.4.

I think it might be due to #187 adding quotes to the bindpath.

Serverless: Trying bindPath D:/Workspace/analysis-api/.serverless/requirements (run,--rm,-v,D:/Workspace/analysis-api/.serverless/requirements:/test,alpine,ls,/test/requirements.txt)
Serverless: /test/requirements.txt

  Error --------------------------------------------------

  docker: Error response from daemon: invalid mode: /test.
See 'docker run --help'.

Environment Info

     OS: win32(10 pro)
     Node Version: 9.5.0
     Serverless Version: 1.32.0
     Docker Version :  18.06.1-ce-win73 (19507)

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 6
  • Comments: 27 (2 by maintainers)

Commits related to this issue

Most upvoted comments

FWIW, T-Tmnr’s change worked for me as well.

@dschep I have just tested the build and it works, I am now able to deploy my flask app. I did encounter issue #226 but just had to regenerate the requirements.txt in bash using wsl

Windows 10 Pro v1803 Build 17134.345 node v8.11.4 Serverless 1.32.0 python 3.7.0 Docker version 18.06.1-ce, build e68fc7a

nvm v1.1.7 npm 6.4.1 pip 18.0

My information was “ONLY” bat file. https://github.com/UnitedIncome/serverless-python-requirements/issues/274#issuecomment-438748776

I try to explore behavior with other command-line application. Another result is there. Windows bat-file has a darkness…

I make simple application “outarg.exe”.

#include <fstream>
#include <iostream>
#include <string>

int main(int argc, char* argv[])
{
	std::ofstream ofs("result.txt", std::ofstream::app);
	for (int i = 0; i < argc; i++) {
		ofs << "argv[" << i << "]=" << argv[i] << "\n";
	}
}

And check spawnSync behavior.


With options ['-v', 'host path:guest_path']

When default.

argv[0]=outarg.exe
argv[1]=case1
argv[2]=-v
argv[3]=host path:guest_path

It does not corrupt! Docker can recognize option.

When windowsVerbatimArguments or shell option enabled.

argv[0]=outarg.exe
argv[1]=case2
argv[2]=-v
argv[3]=host
argv[4]=path:guest_path

Parameters are corrupted.


With options ['-v', '"host path":guest_path']

When default.

argv[0]=outarg.exe
argv[1]=case1
argv[2]=-v
argv[3]="host path":guest_path

It does not corrupt! But in this case, docker cannot recognize option correctly.

When windowsVerbatimArguments or shell option enabled.

argv[0]=outarg.exe
argv[1]=case2
argv[2]=-v
argv[3]=host path:guest_path

It does not corrupt and does not have double-quate! Docker can recognize option.


With options ['-v', '"host path:guest_path"']

When default.

argv[0]=outarg.exe
argv[1]=case1
argv[2]=-v
argv[3]="host path:guest_path"

This case is not in current code. Modify docker.js to do this quoting, but docker cannot recognize option correctly.

When windowsVerbatimArguments or shell option enabled.

argv[0]=outarg.exe
argv[1]=case2
argv[2]=-v
argv[3]=host path:guest_path

It does not corrupt and does not have double-quate too! Docker can recognize option.


In docker.js, calling spawnSync with default option. In pip.js, calling spawnSync with shell option. If bindPath has space-char, docker.js wants un-quoted bindPath but pip.js wants quoted bindPath.

My solution on fix-issue-274, https://github.com/T-Tmnr/serverless-python-requirements/tree/fix-issue-274 bindPath keeps quoted and modify spawnSync option on docker.js.

Another solution on fix-issue-274-another, https://github.com/T-Tmnr/serverless-python-requirements/tree/fix-issue-274-another bindPath is not quoted and modify docker option to quote on pip.js.

Both solutions fix this issue.

@dschep, I opened PR with modifying about dockerizePip.

That’s great news @naingyelin!

@T-Tmnr, could you open a PR for your change? Also, could you make the change from python.exe to python only for when dockerizePip is set?

There is maybe some differences between command-line and spawnSync on Windows. I explored spawnSync behavior on windows by below code.

testcode.js

const { spawnSync } = require('child_process');
const options = ['arg1', '"arg2"', 'arg 3', '"arg 4"'];
// case1 like docker.js:13
spawnSync('reciever.bat', options, { });
// case2 
spawnSync('reciever.bat', options, { windowsVerbatimArguments:true });
// case3 likes pip.js:249
spawnSync('reciever.bat', options, { shell:true });

reciever.bat

echo ALL=%* >> result.txt
echo $1=%1 >> result.txt
echo $2=%2 >> result.txt
echo $3=%3 >> result.txt
echo $4=%4 >> result.txt
echo $5=%5 >> result.txt

Result

rem case1
ALL=arg1 "\"arg2\"" "arg 3" "\"arg 4\"" 
$1=arg1 
$2="\"arg2\"" 
$3="arg 3" 
$4="\"arg 
$5=4\"" 

rem case2
ALL=arg1 "arg2" arg 3 "arg 4" 
$1=arg1 
$2="arg2" 
$3=arg 
$4=3 
$5="arg 4"

rem case3
ALL=arg1 "arg2" arg 3 "arg 4" 
$1=arg1 
$2="arg2" 
$3=arg 
$4=3 
$5="arg 4" 

Case1: double-quate in arg2 and arg4 are escaped and corrupted. But arg3 is escaped well. Case2 and case3: arg3 is corrupted.

I tryed to fix this issue on my branch. but can not test on Mac. https://github.com/T-Tmnr/serverless-python-requirements/tree/fix-issue-274

Same and debugged. At ver 4.2.5, project directory becomes encorted by double quoat. (at pip.js) at Ver.4.2.4 -> projectdir/.serverless/requirements at Ver.4.2.5 -> "projectdir/.serverless/requirements" It got the bad effect by child_process.spawnSync quoting and escaping process. Call child_process.spawnSync with option windowsVerbatimArguments = true, this issue does not reproduced.

After fixing it, next calling ‘python.exe’ on Docker container.

docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"python.exe\": executable file not found in $PATH": unknown.

I fixed issues on my branch ‘fix-issue-274’, and it goes well using the serverless command on my pc.

@kichik That is not the complete log but only where it failed. Everything else ran fine.

D: is definitely shared.

Is that the complete log with SLS_DEBUG=*? It should have tried a few more options.

If I had to guess, I would say the D: drive is not shared with Docker.