diff --git a/lib/pip.js b/lib/pip.js index 7d350c6c..da4dd059 100644 --- a/lib/pip.js +++ b/lib/pip.js @@ -14,6 +14,10 @@ const { getUserCachePath } = require('./shared'); +function quote_single(quoteme) { + return quote([quoteme]); +} + /** * Just generate the requirements file in the .serverless folder * @param {string} requirementsPath @@ -100,7 +104,7 @@ function installRequirements(targetFolder, serverless, options) { ); serverless.cli.log(`Using download cache directory ${downloadCacheDir}`); fse.ensureDirSync(downloadCacheDir); - pipCmd.push('--cache-dir', downloadCacheDir); + pipCmd.push('--cache-dir', quote_single(downloadCacheDir)); } // Check if pip has Debian's --system option and set it if so @@ -145,18 +149,23 @@ function installRequirements(targetFolder, serverless, options) { // Prepare bind path depending on os platform const bindPath = getBindPath(serverless, targetFolder); - cmdOptions = ['run', '--rm', '-v', `"${bindPath}:/var/task:z"`]; + cmdOptions = ['run', '--rm', '-v', quote_single(`${bindPath}:/var/task:z`)]; if (options.dockerSsh) { // Mount necessary ssh files to work with private repos cmdOptions.push( '-v', - `"${process.env.HOME}/.ssh/id_rsa:/root/.ssh/id_rsa:z"` + quote_single(`${process.env.HOME}/.ssh/id_rsa:/root/.ssh/id_rsa:z`) ); cmdOptions.push( '-v', - `"${process.env.HOME}/.ssh/known_hosts:/root/.ssh/known_hosts:z"` + quote_single( + `${process.env.HOME}/.ssh/known_hosts:/root/.ssh/known_hosts:z` + ) + ); + cmdOptions.push( + '-v', + quote_single(`${process.env.SSH_AUTH_SOCK}:/tmp/ssh_sock:z`) ); - cmdOptions.push('-v', `"${process.env.SSH_AUTH_SOCK}:/tmp/ssh_sock:z"`); cmdOptions.push('-e', 'SSH_AUTH_SOCK=/tmp/ssh_sock'); } @@ -177,8 +186,11 @@ function installRequirements(targetFolder, serverless, options) { ); const windowsized = getBindPath(serverless, downloadCacheDir); // And now push it to a volume mount and to pip... - cmdOptions.push('-v', `"${windowsized}:${dockerDownloadCacheDir}:z"`); - pipCmd.push('--cache-dir', dockerDownloadCacheDir); + cmdOptions.push( + '-v', + quote_single(`${windowsized}:${dockerDownloadCacheDir}:z`) + ); + pipCmd.push('--cache-dir', quote_single(dockerDownloadCacheDir)); } if (process.platform === 'linux') { @@ -189,7 +201,7 @@ function installRequirements(targetFolder, serverless, options) { commands.push(quote(['chown', '-R', '0:0', dockerDownloadCacheDir])); } // Install requirements with pip - commands.push(quote(pipCmd)); + commands.push(pipCmd.join(' ')); // Set the ownership of the current folder to user commands.push( quote([ @@ -213,7 +225,7 @@ function installRequirements(targetFolder, serverless, options) { pipCmd = ['/bin/bash', '-c', '"' + commands.join(' && ') + '"']; } else { // Use same user so --cache-dir works - cmdOptions.push('-u', getDockerUid(bindPath)); + cmdOptions.push('-u', quote_single(getDockerUid(bindPath))); } cmdOptions.push(dockerImage); cmdOptions.push(...pipCmd); @@ -262,7 +274,7 @@ function dockerPathForWin(options, path) { if (process.platform === 'win32' && options.dockerizePip) { return path.replace(/\\/g, '/'); } - return path; + return quote_single(path); } /** create a filtered requirements.txt without anything from noDeploy