UNPKG

mecano

Version:

Common functions for system deployment.

121 lines (117 loc) 5.76 kB
// Generated by CoffeeScript 1.11.1 var each, misc, slice = [].slice; module.exports = function(options) { var extract_servers, host, i, j, k, len, len1, port, quorum_target, ref, ref1, ref2, ref3, server, servers; options.log({ message: "Entering wait for connection", level: 'DEBUG', module: 'mecano/connection/wait' }); extract_servers = function(options) { var host, hosts, i, j, k, l, len, len1, len2, len3, m, port, ports, ref, ref1, ref2, ref3, servers; if ((options.port || options.ports) && !options.host) { throw Error("Invalid host: " + server.host); } if ((options.host || options.hosts) && !options.port) { throw Error("Invalid port: " + server.port); } ref = ['host', 'hosts']; for (i = 0, len = ref.length; i < len; i++) { k = ref[i]; if (options[k] == null) { options[k] = []; } if ((ref1 = typeof options[k]) !== 'string' && ref1 !== 'object') { throw error("Invalid option '" + options[k] + "'"); } if (!Array.isArray(options[k])) { options[k] = [options[k]]; } } hosts = slice.call(options.host).concat(slice.call(options.hosts)); ref2 = ['port', 'ports']; for (j = 0, len1 = ref2.length; j < len1; j++) { k = ref2[j]; if (options[k] == null) { options[k] = []; } if ((ref3 = typeof options[k]) !== 'string' && ref3 !== 'number' && ref3 !== 'object') { throw error("Invalid option '" + options[k] + "'"); } if (!Array.isArray(options[k])) { options[k] = [options[k]]; } } ports = slice.call(options.port).concat(slice.call(options.ports)); servers = []; for (l = 0, len2 = hosts.length; l < len2; l++) { host = hosts[l]; for (m = 0, len3 = ports.length; m < len3; m++) { port = ports[m]; servers.push({ host: host, port: port }); } } return servers; }; servers = extract_servers(options); ref = ['server', 'servers']; for (i = 0, len = ref.length; i < len; i++) { k = ref[i]; if (options[k] == null) { options[k] = []; } if ((ref1 = typeof options[k]) !== 'string' && ref1 !== 'object') { throw error("Invalid option '" + options[k] + "'"); } if (typeof options[k] === 'string') { ref2 = options[k].split(':'), host = ref2[0], port = ref2[1]; options[k] = { host: host, port: port }; } if (!Array.isArray(options[k])) { options[k] = [options[k]]; } options[k] = misc.array.flatten(options[k]); ref3 = options[k]; for (j = 0, len1 = ref3.length; j < len1; j++) { server = ref3[j]; servers.push.apply(servers, extract_servers(server)); } } if (!servers.length) { options.log({ message: "No connection to wait for", level: 'WARN', module: 'mecano/connection/wait' }); return; } if (options.interval == null) { options.interval = 2000; } options.interval = Math.round(options.interval / 1000); quorum_target = options.quorum; if (quorum_target && quorum_target === true) { quorum_target = Math.ceil(servers.length / 2); } else if (quorum_target == null) { quorum_target = servers.length; } if (!(options.timeout > 0)) { options.timeout = ''; } return this.execute({ cmd: "function compute_md5 {\n echo $1 | openssl md5 | sed 's/^.* \\([a-z0-9]*\\)$/\\1/g'\n}\naddresses=( " + (servers.map(function(server) { return "'" + server.host + ":" + server.port + "'"; }).join(' ')) + " )\ntimeout=" + (options.timeout || '') + "\nmd5=`compute_md5 ${addresses[@]}`\nranddir=\"" + (options.randdir || '') + "\"\nif [ -z $randir ]; then\n if [ -w /dev/shm ]; then\n randdir=\"/dev/shm/$md5\"\n else\n randdir=\"/tmp/$md5\"\n fi\nfi\nquorum_target=" + quorum_target + "\necho \"[INFO] randdir is: $randdir\"\nmkdir -p $randdir\necho 3 > $randdir/signal\necho 0 > $randdir/quorum\nfunction remove_randdir {\n for address in \"${addresses[@]}\" ; do\n host=\"${address%%:*}\"\n port=\"${address##*:}\"\n rm -f $randdir/`compute_md5 $host:$port`\n done\n}\nfunction check_quorum {\n quorum_current=`cat $randdir/quorum`\n if [ $quorum_current -ge $quorum_target ]; then\n echo '[INFO] Quorum is reached'\n remove_randdir\n fi\n}\nfunction check_timeout {\n local timeout=$1\n local randfile=$2\n wait $timeout\n rm -f $randfile\n}\nfunction wait_connection {\n local host=$1\n local port=$2\n local randfile=$3\n local count=0\n echo \"[DEBUG] Start wait for $host:$port\"\n isopen=\"echo > '/dev/tcp/$host/$port'\"\n touch \"$randfile\"\n while [[ -f \"$randfile\" ]] && ! `bash -c \"$isopen\" 2>/dev/null`; do\n ((count++))\n echo \"[DEBUG] Connection failed to $host:$port on attempt $count\" >&2\n sleep " + options.interval + "\n done\n if [[ -f \"$randfile\" ]]; then\n echo \"[DEBUG] Connection ready to $host:$port\"\n fi\n echo $(( $(cat $randdir/quorum) + 1 )) > $randdir/quorum\n check_quorum\n if [ \"$count\" -gt \"0\" ]; then\n echo \"[WARN] Status is now active, count is $count\"\n echo 0 > $randdir/signal\n fi\n}\nif [ ! -z \"$timeout\" ]; then\n host=\"${address%%:*}\"\n port=\"${address##*:}\"\n check_timeout $timeout `compute_md5 $host:$port` &\nfi\nfor address in \"${addresses[@]}\" ; do\n host=\"${address%%:*}\"\n port=\"${address##*:}\"\n randfile=$randdir/`compute_md5 $host:$port`\n wait_connection $host $port $randfile &\ndone\nwait\n# Clean up\nsignal=`cat $randdir/signal`\nremove_randdir\necho \"[INFO] Exit code is $signal\"\nexit $signal", code_skipped: 3, stdin_log: false }); }; each = require('each'); misc = require('../misc');