Skip to content

Commit

Permalink
fixes bug where *.json *.js could not be used as startup files
Browse files Browse the repository at this point in the history
  • Loading branch information
patricklee2 committed Aug 9, 2018
1 parent a7255bd commit 67fd270
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 55 deletions.
201 changes: 148 additions & 53 deletions 10.1.0/startup/generateStartupCommand.js
@@ -1,78 +1,173 @@
#!/usr/bin/env node
const fs = require('fs'),
util = require('util');
const fs = require('fs');

console.log("Generating app startup command");

const DEFAULTAPP = "/opt/startup/default-static-site.js";
const CMDFILE = "/opt/startup/startupCommand";

var httpLoggingEnabled = process.env.HTTP_LOGGING_ENABLED;
httpLoggingEnabled = (typeof httpLoggingEnabled !== 'undefined'
&& httpLoggingEnabled !== null
&& (httpLoggingEnabled.toLowerCase() === 'true' || httpLoggingEnabled.toLowerCase() === '1'))

var roleInstanceId = '';
if (typeof process.env.WEBSITE_ROLE_INSTANCE_ID !== 'undefined'
&& process.env.WEBSITE_ROLE_INSTANCE_ID !== null) {
roleInstanceId = process.env.WEBSITE_ROLE_INSTANCE_ID;
function getJsStartupCommand(jsFile) {
if (process.env.APPSVC_REMOTE_DEBUGGING == "TRUE") {
if (process.env.APPSVC_REMOTE_DEBUGGING_BREAK == "TRUE") {
return "node --inspect-brk=0.0.0.0:" + process.env.APPSVC_TUNNEL_PORT + " " + jsFile;
} else {
return "node --inspect=0.0.0.0:" + process.env.APPSVC_TUNNEL_PORT + " " + jsFile;
}
} else {
// Run with pm2
return "pm2 start " + jsFile + " --no-daemon";
}
}

var startupCommand = fs.readFileSync(CMDFILE, 'utf8').trim();
function getStartupCommand(CMDFILE) {
const CUSTOM_STARTUP_CMD_FLAG = "/opt/startup/CUSTOM_STARTUP_CMD_FLAG";
fs.writeFileSync(CUSTOM_STARTUP_CMD_FLAG, "FALSE");
const PACKAGE_JSON_FLAG = "/opt/startup/PACKAGE_JSON_FLAG";
fs.writeFileSync(PACKAGE_JSON_FLAG, "FALSE");
const PROCESS_JSON_FLAG = "/opt/startup/PROCESS_JSON_FLAG";
fs.writeFileSync(PROCESS_JSON_FLAG, "FALSE");

const CUSTOM_STARTUP_CMD_FLAG = "/opt/startup/CUSTOM_STARTUP_CMD_FLAG";
fs.writeFileSync(CUSTOM_STARTUP_CMD_FLAG, "FALSE");
if (startupCommand) {
fs.writeFileSync(CUSTOM_STARTUP_CMD_FLAG, "TRUE"); // set CUSTOM_STARTUP_CMD_FLAG for remote debugging
}
const DEFAULTAPP = "/opt/startup/default-static-site.js";
var userStartupCommand = fs.readFileSync(CMDFILE, 'utf8').trim();

// No user-provided startup command, check for scripts.start
const PACKAGE_JSON_FLAG = "/opt/startup/PACKAGE_JSON_FLAG";
fs.writeFileSync(PACKAGE_JSON_FLAG, "FALSE");
if (!startupCommand) {
var packageJsonPath = "/home/site/wwwroot/package.json";
var json = fs.existsSync(packageJsonPath) && JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
if (typeof json == 'object' && typeof json.scripts == 'object' && typeof json.scripts.start == 'string') {
console.log("Found scripts.start in package.json")
startupCommand = 'npm start';
fs.writeFileSync(PACKAGE_JSON_FLAG, "TRUE"); // set PACKAGE_JSON_FLAG for remote debugging
if (userStartupCommand) {
fs.writeFileSync(CUSTOM_STARTUP_CMD_FLAG, "TRUE"); // set CUSTOM_STARTUP_CMD_FLAG for remote debugging
}

// contains spaces, so multipart command
// eg: npm start
if (userStartupCommand.indexOf(" ") != -1) {
console.log("Found command: "+ userStartupCommand);
return userStartupCommand;
}

// look for package.json
if (userStartupCommand.endsWith("package.json") || !userStartupCommand) {
var packageJsonPath = "";
if (!userStartupCommand) {
packageJsonPath = "/home/site/wwwroot/package.json";
} else {
packageJsonPath = userStartupCommand;
}
if (fs.existsSync(packageJsonPath)) {
var json = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
if (typeof json == 'object' && typeof json.scripts == 'object' && typeof json.scripts.start == 'string') {
console.log("Found scripts.start in " + packageJsonPath);
fs.writeFileSync(PACKAGE_JSON_FLAG, "TRUE"); // set PACKAGE_JSON_FLAG for remote debugging
if (packageJsonPath != "package.json") {
var packageJsonDir = packageJsonPath.substring(0, packageJsonPath.indexOf("package.json")-1);
return "npm --prefix=" + packageJsonDir + " start";
} else {
return 'npm start';
}
}
}
}

// look for process.json or *.json
if (userStartupCommand.endsWith(".json") || !userStartupCommand) {
var processJsonPath = "";
if (!userStartupCommand) {
processJsonPath = "/home/site/wwwroot/process.json";
} else {
processJsonPath = userStartupCommand;
}
if (fs.existsSync(processJsonPath)) {
var json = JSON.parse(fs.readFileSync(processJsonPath, 'utf8'))
console.log("Found script in " + processJsonPath)
fs.writeFileSync(PROCESS_JSON_FLAG, "TRUE"); // set PROCESS_JSON_FLAG for remote debugging
if (process.env.APPSVC_REMOTE_DEBUGGING == "TRUE") {
if (typeof json == 'object' && typeof json.script == 'string') {
var nodeFile = json.script; // run the script directly with node
if (process.env.APPSVC_REMOTE_DEBUGGING_BREAK == "TRUE") {
return "node --inspect-brk=0.0.0.0:" + process.env.APPSVC_TUNNEL_PORT + " " + nodeFile;
} else {
return "node --inspect=0.0.0.0:" + process.env.APPSVC_TUNNEL_PORT + " " + nodeFile;
}
} else {
// did not find script tag
return "pm2 start " + processJsonPath + " --no-daemon";
}
} else {
// Run with pm2
return "pm2 start " + processJsonPath + " --no-daemon";
}
}
}

// look for *.config.js
if (userStartupCommand.endsWith(".config.js") || !userStartupCommand) {
var configJsPath = "";
if (!userStartupCommand) {
configJsPath = "/home/site/wwwroot/ecosystem.config.js";
} else {
configJsPath = userStartupCommand;
}
if (fs.existsSync(configJsPath)) {
console.log("Found script in " + configJsPath)
fs.writeFileSync(PROCESS_JSON_FLAG, "TRUE"); // set PROCESS_JSON_FLAG for remote debugging

if (process.env.APPSVC_REMOTE_DEBUGGING == "TRUE") {
// debugging not yet supported
return "pm2 start " + configJsPath + " --no-daemon";
} else {
// Run with pm2
return "pm2 start " + configJsPath + " --no-daemon";
}
}
}

// look for *.yaml and *.yml
if (userStartupCommand.endsWith(".yml") || userStartupCommand.endsWith(".yaml")) {
var processYamlPath = userStartupCommand;
if (fs.existsSync(processYamlPath)) {
console.log("Found script in " + processYamlPath)
fs.writeFileSync(PROCESS_JSON_FLAG, "TRUE"); // set PROCESS_JSON_FLAG for remote debugging

if (process.env.APPSVC_REMOTE_DEBUGGING == "TRUE") {
// debugging not yet supported
return "pm2 start " + processYamlPath + " --no-daemon";
} else {
// Run with pm2
return "pm2 start " + processYamlPath + " --no-daemon";
}
}
}

// look for *.js
if (userStartupCommand.endsWith(".js")) {
console.log("Found js file " + userStartupCommand);
return getJsStartupCommand(userStartupCommand);
}
}

var nodeFile = startupCommand;
// otherwise, use the user input
if (userStartupCommand) {
console.log(userStartupCommand + " is an executable file");
// eg: /home/site/wwwroot/run.sh or ./bin/www
return userStartupCommand;
}

// No scripts.start; can we autodetect an app?
if (!startupCommand) {
// No scripts.start; can we autodetect an app?
var autos = ['bin/www', 'server.js', 'app.js', 'index.js', 'hostingstart.js'];
for (var i = 0; i < autos.length; i++) {
var filename = "/home/site/wwwroot/" + autos[i];
if (fs.existsSync(filename)) {
console.log("No startup command entered, but found " + filename);
nodeFile = filename;
break;
return getJsStartupCommand(filename);
}
}
}

// Still nothing, run the default static site
if (!startupCommand && !nodeFile) {

// Still nothing, run the default static site
console.log("No startup command or autodetected startup script " +
"found. Running default static site.");
nodeFile = DEFAULTAPP;
return getJsStartupCommand(DEFAULTAPP);
}

if (!startupCommand && nodeFile && fs.existsSync(nodeFile)) {
if (process.env.APPSVC_REMOTE_DEBUGGING == "TRUE") {
if (process.env.APPSVC_REMOTE_DEBUGGING_BREAK == "TRUE") {
startupCommand = "node --inspect-brk=0.0.0.0:" + process.env.APPSVC_TUNNEL_PORT + " " + nodeFile;
} else {
startupCommand = "node --inspect=0.0.0.0:" + process.env.APPSVC_TUNNEL_PORT + " " + nodeFile;
}
} else {
// Run with pm2
startupCommand = "pm2 start " + nodeFile + " --no-daemon";
}
}
console.log("Generating app startup command");

var httpLoggingEnabled = process.env.HTTP_LOGGING_ENABLED;
httpLoggingEnabled = (typeof httpLoggingEnabled !== 'undefined'
&& httpLoggingEnabled !== null
&& (httpLoggingEnabled.toLowerCase() === 'true' || httpLoggingEnabled.toLowerCase() === '1'))

var startupCommand = getStartupCommand(CMDFILE);

// Write to file
fs.writeFileSync(CMDFILE, startupCommand);
4 changes: 4 additions & 0 deletions 10.1.0/startup/init_container.sh
Expand Up @@ -29,7 +29,11 @@ then
mv /opt/startup/node-wrapper.sh /usr/local/bin/node
chmod a+x /usr/local/bin/node
sed -i 's/env node/env node-original/' /usr/local/lib/node_modules/npm/bin/npm-cli.js
sed -i 's/env node/env node-original/' /usr/local/lib/node_modules/npm/bin/npx-cli.js
sed -i 's/env node/env node-original/' /usr/local/lib/node_modules/pm2/bin/pm2
sed -i 's/env node/env node-original/' /usr/local/lib/node_modules/pm2/bin/pm2-dev
sed -i 's/env node/env node-original/' /usr/local/lib/node_modules/pm2/bin/pm2-docker
sed -i 's/env node/env node-original/' /usr/local/lib/node_modules/pm2/bin/pm2-runtime
sed -i 's/env node/env node-original/' /opt/startup/generateStartupCommand.js
fi

Expand Down
20 changes: 18 additions & 2 deletions 10.1.0/startup/node-wrapper.sh
Expand Up @@ -21,19 +21,35 @@ then
package_json=`cat /opt/startup/PACKAGE_JSON_FLAG`
fi

process_json="FALSE"
if [ -e "/opt/startup/PROCESS_JSON_FLAG" ]
then
process_json=`cat /opt/startup/PROCESS_JSON_FLAG`
fi

custom_startup="FALSE"
if [ -e "/opt/startup/CUSTOM_STARTUP_CMD_FLAG" ]
then
custom_startup=`cat /opt/startup/CUSTOM_STARTUP_CMD_FLAG`
fi

# enable remote debugging when node started with npm
if [ "$APPSVC_REMOTE_DEBUGGING" = "TRUE" ] && ([ "$package_json" = "TRUE" ] || [ "$custom_startup" = "TRUE" ]) && [ $args_contain_inspect = false ]
if [ "$APPSVC_REMOTE_DEBUGGING" = "TRUE" ] && [ "$package_json" = "TRUE" ] && [ $args_contain_inspect = false ]
then
node-original --inspect=0.0.0.0:$APPSVC_TUNNEL_PORT "$@"
elif [ "$APPSVC_REMOTE_DEBUGGING_BREAK" = "TRUE" ] && ([ "$package_json" = "TRUE" ] || [ "$custom_startup" = "TRUE" ]) && [ $args_contain_inspect = false ]
elif [ "$APPSVC_REMOTE_DEBUGGING_BREAK" = "TRUE" ] && [ "$package_json" = "TRUE" ] && [ $args_contain_inspect = false ]
then
node-original --inspect-brk=0.0.0.0:$APPSVC_TUNNEL_PORT "$@"
# if using pm2
elif ([ "$APPSVC_REMOTE_DEBUGGING" = "TRUE" ] || [ "$APPSVC_REMOTE_DEBUGGING_BREAK" = "TRUE" ] ) && [ "$process_json" = "TRUE" ] && [ $args_contain_inspect = false ]
then
node-original "$@"
elif [ "$APPSVC_REMOTE_DEBUGGING" = "TRUE" ] && [ "$custom_startup" = "TRUE" ] && [ $args_contain_inspect = false ]
then
node-original --inspect=0.0.0.0:$APPSVC_TUNNEL_PORT "$@"
elif [ "$APPSVC_REMOTE_DEBUGGING_BREAK" = "TRUE" ] && [ "$custom_startup" = "TRUE" ] && [ $args_contain_inspect = false ]
then
node-original --inspect-brk=0.0.0.0:$APPSVC_TUNNEL_PORT "$@"
else
node-original "$@"
fi

0 comments on commit 67fd270

Please sign in to comment.