From aa1c225a940677bc6fd531381464e5f45d51a74e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89verton=20Ribeiro?= Date: Wed, 17 Jun 2015 02:00:21 -0300 Subject: [PATCH 1/4] [agent] Fixing agent start in daemon monde if the first time it is run --- bin/azk | 20 ++++++++++---------- src/cli/ui.js | 14 +++++++++++--- src/cmds/agent.js | 26 +++++++++++++++----------- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/bin/azk b/bin/azk index ab02f49c..4bbd61d6 100755 --- a/bin/azk +++ b/bin/azk @@ -111,34 +111,34 @@ azk_main() { # Run agent trap gracefulExit INT + set -m azk_node_run "${@}" > $AZK_AGENT_LOG_FILE 2>&1 & AGENT_PID="$!" tail -n0 -f $AZK_AGENT_LOG_FILE 2>/dev/null & TAIL_PID="$!" kill_and_wait() { - kill -s TERM ${1} 2>/dev/null - while kill -0 ${1} 2>/dev/null; do + kill -s TERM ${1} 2>&1 >/dev/null || true + while kill -0 ${1} 2>&1 >/dev/null; do sleep 1; done } gracefulExit() { - set +e - kill_and_wait ${AGENT_PID} - disown ${TAIL_PID} - kill_and_wait ${TAIL_PID} - echo "exit"; + kill_and_wait ${AGENT_PID} 2>&1 >/dev/null || true + disown ${TAIL_PID} || true + kill_and_wait ${TAIL_PID} 2>&1 >/dev/null || true exit 1; } # Wait for start - until tail -1 $AZK_AGENT_LOG_FILE | grep -q 'Agent has been successfully started.'; do - kill -0 ${AGENT_PID} 2>/dev/null || gracefulExit; + msg='Agent has been successfully started.' + until grep -q "${msg}" "${AZK_AGENT_LOG_FILE}"; do + kill -0 ${AGENT_PID} 2>&1 >/dev/null || gracefulExit; sleep 1; done - kill -9 $TAIL_PID + kill -9 $TAIL_PID 2>&1 >/dev/null || true ;; *) azk_load_nvm diff --git a/src/cli/ui.js b/src/cli/ui.js index 2c2299c4..3f46e6da 100644 --- a/src/cli/ui.js +++ b/src/cli/ui.js @@ -135,9 +135,17 @@ var UI = { }, // User interactions methods - execSh(...args) { - var result = (err) => { return (err) ? err.code : 0; }; - return nfcall(lazy.execShLib, ...args).spread(result, result); + execSh(command, options = {}, callback = null) { + if (_.isFunction(options)) { + [callback, options] = [options, {}]; + } + + if (callback) { + return lazy.execShLib(command, options, callback); + } else { + var result = (err) => { return (err) ? err.code : 0; }; + return nfcall(lazy.execShLib, command, options).spread(result, result); + } }, prompt(questions) { diff --git a/src/cmds/agent.js b/src/cmds/agent.js index 5a0d8b85..7f3f53fd 100644 --- a/src/cmds/agent.js +++ b/src/cmds/agent.js @@ -1,7 +1,7 @@ import { CliTrackerController } from 'azk/cli/cli_tracker_controller.js'; import { Helpers } from 'azk/cli/helpers'; import { _, config, lazy_require, log } from 'azk'; -import { asyncUnsubscribe } from 'azk/utils/promises'; +import { defer, asyncUnsubscribe } from 'azk/utils/promises'; import { subscribe } from 'azk/utils/postal'; var lazy = lazy_require({ @@ -17,12 +17,7 @@ class Agent extends CliTrackerController { } index(opts) { - return this - .callAgent(opts) - .then((result) => { - process.stdin.pause(); - return result; - }); + return this.callAgent(opts); } callAgent(opts) { @@ -94,10 +89,19 @@ class Agent extends CliTrackerController { } _runDaemon(cmd) { - this._captureSignal(() => {}); - return this.ui.execSh(cmd, { - detached: false, - stdio: [ 'ignore', process.stdout, process.stderr ] + return defer((resolve) => { + var opts = { + detached: true, + stdio: [ process.stdin, process.stdout, process.stderr ] + }; + + var child = this.ui.execSh(cmd, opts, (err) => { + resolve(err ? err.code : 0); + }); + + this._captureSignal((signal) => { + child.kill(signal); + }); }); } From e695bcb37408f47824c9291cca1df85c27853e07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89verton=20Ribeiro?= Date: Wed, 17 Jun 2015 13:15:36 -0300 Subject: [PATCH 2/4] [agent] Refactoring agent start in daemon mode to use config file. --- bin/azk | 82 +++++++++++++++++++--------------- shared/locales/usage-en-US.txt | 2 +- src/agent/index.js | 8 ++-- src/cli/index.js | 2 +- src/cmds/agent.js | 40 ++++++++++++----- src/config.js | 4 +- 6 files changed, 84 insertions(+), 54 deletions(-) diff --git a/bin/azk b/bin/azk index 4bbd61d6..642b0fbb 100755 --- a/bin/azk +++ b/bin/azk @@ -50,7 +50,10 @@ export LIBNSS_RESOLVER_VERSION=${LIBNSS_RESOLVER_VERSION} export RSYNC_MIN_VERSION=${RSYNC_MIN_VERSION} # Agent opts -export AZK_AGENT_LOG_FILE=$AZK_DATA_PATH/logs/agent.log +export AZK_AGENT_LOG_OUT_FILE=$AZK_DATA_PATH/logs/agent.log.out +export AZK_AGENT_LOG_ERR_FILE=$AZK_DATA_PATH/logs/agent.log.err +export AZK_AGENT_CONF_FILE=$AZK_DATA_PATH/run/agent.json +export AZK_AGENT_PING_FILE=$AZK_DATA_PATH/run/ping # No use DOCKER_HOST unset DOCKER_HOST @@ -86,12 +89,50 @@ azk_load_nvm() { fi } +npm() { + exec $AZK_NODE_PATH/npm --cache=${AZK_DATA_PATH}/nvm/cache ${@} +} + azk_node_run() { exec $AZK_NODE_PATH/node --harmony $AZK_ROOT_PATH/bin/azk.js "${@}" } -npm() { - exec $AZK_NODE_PATH/npm --cache=${AZK_DATA_PATH}/nvm/cache ${@} +azk_agent_daemon() { + # Clean log + echo "" > ${AZK_AGENT_LOG_OUT_FILE} + echo "" > ${AZK_AGENT_LOG_ERR_FILE} + + # Run agent + set -m + tail -n0 -f ${AZK_AGENT_LOG_OUT_FILE} & + tail -n0 -f ${AZK_AGENT_LOG_ERR_FILE} 1>&2 & + + quiet() { + "${@}" >/dev/null 2>&1 + } + + wait_started() { + while quiet kill -0 "${AGENT_PID}" && [ ! -f "${AZK_AGENT_PING_FILE}" ]; do + sleep 1; + done + } + + trap "graceExit" INT TERM + graceExit() { + quiet kill -TERM ${AGENT_PID} || true + while quiet kill -0 "${AGENT_PID}"; do + sleep 1; + done + quiet kill %1 %2 || true + exit 1; + } + + rm -f "${AZK_AGENT_PING_FILE}" + azk_node_run "${@}" > "${AZK_AGENT_LOG_OUT_FILE}" 2> "${AZK_AGENT_LOG_ERR_FILE}" & + AGENT_PID="$!" + wait_started & + wait $! + quiet kill %1 %2 || true } azk_main() { @@ -105,40 +146,7 @@ azk_main() { agent-daemon) # Removing agent-daemon shift; - - # Reset log - echo "" > $AZK_AGENT_LOG_FILE - - # Run agent - trap gracefulExit INT - set -m - azk_node_run "${@}" > $AZK_AGENT_LOG_FILE 2>&1 & - AGENT_PID="$!" - tail -n0 -f $AZK_AGENT_LOG_FILE 2>/dev/null & - TAIL_PID="$!" - - kill_and_wait() { - kill -s TERM ${1} 2>&1 >/dev/null || true - while kill -0 ${1} 2>&1 >/dev/null; do - sleep 1; - done - } - - gracefulExit() { - kill_and_wait ${AGENT_PID} 2>&1 >/dev/null || true - disown ${TAIL_PID} || true - kill_and_wait ${TAIL_PID} 2>&1 >/dev/null || true - exit 1; - } - - # Wait for start - msg='Agent has been successfully started.' - until grep -q "${msg}" "${AZK_AGENT_LOG_FILE}"; do - kill -0 ${AGENT_PID} 2>&1 >/dev/null || gracefulExit; - sleep 1; - done - - kill -9 $TAIL_PID 2>&1 >/dev/null || true + azk_agent_daemon "${@}" ;; *) azk_load_nvm diff --git a/shared/locales/usage-en-US.txt b/shared/locales/usage-en-US.txt index b0313f0b..b954df76 100644 --- a/shared/locales/usage-en-US.txt +++ b/shared/locales/usage-en-US.txt @@ -1,7 +1,7 @@ $ azk [options] [*command] Usage: - azk agent (start|status|stop) [--no-daemon --child --no-reload-vm -q -h -l ] [-v]... + azk agent (start|status|stop) [--no-daemon --child --no-reload-vm -q -h -l --configure-file=] [-v]... azk config (track-toggle|track-status) [-q -h -l ] [-v]... azk doctor [--logo -q -h -l ] [-v]... azk docker [-q -h -l ] [-v]... [-- ...] diff --git a/src/agent/index.js b/src/agent/index.js index 0cb09cfb..a2fccf38 100644 --- a/src/agent/index.js +++ b/src/agent/index.js @@ -1,5 +1,5 @@ -import { _, config, log, lazy_require, set_config } from 'azk'; -import { defer, promiseResolve } from 'azk/utils/promises'; +import { _, config, log, lazy_require, set_config, fsAsync } from 'azk'; +import { defer, async, promiseResolve } from 'azk/utils/promises'; import { publish } from 'azk/utils/postal'; import { Pid } from 'azk/utils/pid'; import { AgentStopError } from 'azk/utils/errors'; @@ -128,8 +128,10 @@ var Agent = { this.processStateHandler(); // Start server and subsistems - return lazy.Server.start(this.stop.bind(this)).then(() => { + return async(this, function* () { + yield lazy.Server.start(this.stop.bind(this)); if (!this.stopping) { + yield fsAsync.writeFile(config("paths:agent_ping"), ""); this.change_status("started"); publish("agent.agent.started.event", {}); log.info("[azk] agent start with pid: " + process.pid); diff --git a/src/cli/index.js b/src/cli/index.js index 9ace4f91..3f4c8913 100644 --- a/src/cli/index.js +++ b/src/cli/index.js @@ -21,7 +21,7 @@ export function cli(args, cwd, ui = UI) { .route('help', (p, args) => p.help || p['--help'] || _.isEmpty(args)) .route('version', (p) => p.version || p['--version']) // Commands - .route('agent', (p, args) => p.agent && /(start|status|stop)/.test(args)) + .route('agent', (p, args) => p.agent && /(start|status|stop|configure)/.test(args)) .route('vm', (p, args) => p.vm && /(ssh|start|status|installed|stop|remove)/.test(args)) .route('config', (p, args) => p.config && /(track-toggle|track-status)/.test(args)) .route('docker') diff --git a/src/cmds/agent.js b/src/cmds/agent.js index 7f3f53fd..abb0444f 100644 --- a/src/cmds/agent.js +++ b/src/cmds/agent.js @@ -1,7 +1,7 @@ import { CliTrackerController } from 'azk/cli/cli_tracker_controller.js'; import { Helpers } from 'azk/cli/helpers'; -import { _, config, lazy_require, log } from 'azk'; -import { defer, asyncUnsubscribe } from 'azk/utils/promises'; +import { _, path, config, lazy_require, log, fsAsync } from 'azk'; +import { defer, async, asyncUnsubscribe } from 'azk/utils/promises'; import { subscribe } from 'azk/utils/postal'; var lazy = lazy_require({ @@ -35,11 +35,20 @@ class Agent extends CliTrackerController { // And no running var status = yield lazy.Client.status(opts.action, false); if (!status.agent) { + // Check and load configures + var configure_file = this.normalized_params.options['configure-file']; + if (!_.isEmpty(configure_file)) { + configure_file = path.resolve(this.cwd, configure_file); + params.configs = require(configure_file); + } else { + this.ui.warning('status.agent.wait'); + params.configs = yield Helpers.configure(this.ui); + } + // Run in daemon mode if (!opts['no-daemon']) { var args = _.clone(this.args); - var cmd = `azk agent-daemon --no-daemon "${args.join('" "')}"`; - return this._runDaemon(cmd); + return this._runDaemon(args, params.configs); } // Save pid and connect signals @@ -58,10 +67,6 @@ class Agent extends CliTrackerController { }); status.pid.update(process.pid); - // Check and load configures - this.ui.warning('status.agent.wait'); - params.configs = yield Helpers.configure(this.ui); - // Remove and adding vm (to refresh vm configs) if (config('agent:requires_vm') && !opts['no-reload-vm']) { var cmd_vm = new lazy.VMController({ ui: this.ui }); @@ -88,11 +93,24 @@ class Agent extends CliTrackerController { }); } - _runDaemon(cmd) { + _runDaemon(args, configs) { + return async(this, function* () { + var file = config("paths:agent_config"); + log.debug("[agent] save config file", file); + yield fsAsync.writeFile(file, JSON.stringify(configs)); + + args = args.concat(["--configure", file]); + var cmd = `azk agent-daemon --no-daemon "${args.join('" "')}"`; + return this._runDaemonCommand(cmd); + }); + + } + + _runDaemonCommand(cmd) { return defer((resolve) => { var opts = { - detached: true, - stdio: [ process.stdin, process.stdout, process.stderr ] + detached: false, + stdio: [ 'ignore', process.stdout, process.stderr ] }; var child = this.ui.execSh(cmd, opts, (err) => { diff --git a/src/config.js b/src/config.js index 3864a47b..afc9e8b7 100644 --- a/src/config.js +++ b/src/config.js @@ -50,9 +50,11 @@ var options = mergeConfig({ azk_meta : path.join(data_path, azk_dir, "shared", "Azkfile.js"), pems : path.join(paths.vm , '.docker'), agent_pid : path.join(paths.run, 'agent.pid'), + agent_socket : path.join(paths.run, 'agent.socket'), + agent_ping : envs("AZK_AGENT_PING_FILE"), + agent_config : envs("AZK_AGENT_CONF_FILE"), memcached_pid : path.join(paths.run, 'memcachedjs.pid'), hipache_pid : path.join(paths.run, 'hipache.pid'), - agent_socket : path.join(paths.run, 'agent.socket'), balancer_file : path.join(paths.run, 'hipache.json'), memcached_socket : path.join(paths.run, 'memcachedjs.socket'), api_socket : path.join(paths.run, 'api.socket'), From 51ad28b6e015803067e07b086b10237d7df9b4a2 Mon Sep 17 00:00:00 2001 From: Felipe Arenales Date: Wed, 17 Jun 2015 13:49:59 -0300 Subject: [PATCH 3/4] [agent] Fixing tail message + cleaning containers before checking ports --- bin/azk | 2 +- shared/locales/en-US.js | 2 +- src/agent/configure.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/azk b/bin/azk index 642b0fbb..a4c7bbfc 100755 --- a/bin/azk +++ b/bin/azk @@ -128,7 +128,7 @@ azk_agent_daemon() { } rm -f "${AZK_AGENT_PING_FILE}" - azk_node_run "${@}" > "${AZK_AGENT_LOG_OUT_FILE}" 2> "${AZK_AGENT_LOG_ERR_FILE}" & + azk_node_run "${@}" >> "${AZK_AGENT_LOG_OUT_FILE}" 2>> "${AZK_AGENT_LOG_ERR_FILE}" & AGENT_PID="$!" wait_started & wait $! diff --git a/shared/locales/en-US.js b/shared/locales/en-US.js index b9aad6a3..b665d91d 100644 --- a/shared/locales/en-US.js +++ b/shared/locales/en-US.js @@ -244,7 +244,7 @@ module.exports = { github_azk_version_error : 'Failed to access Github to get azk latest version number', check_version_no_internet: 'Checking version: there is no internet connection to check azk version.', check_version_error : 'Checking version: %(error_message)s', - clean_containers : "Clearing %(count)d lost containers", + clean_containers : "Cleaning %(count)d lost containers", migrations: { alert : "azk updated, checking update procedures...", changing_domain: "Changing domain upgrading, (issue: #255)", diff --git a/src/agent/configure.js b/src/agent/configure.js index 5fe49062..c5f7cce0 100644 --- a/src/agent/configure.js +++ b/src/agent/configure.js @@ -72,10 +72,10 @@ export class Configure extends UIProxy { { 'agent:dns:port': ports.dns, 'agent:balancer:port': ports.balancer }, yield this._checkDockerSocket(socket), yield this._checkAndConfigureNetwork(ports, false), + yield this._cleanContainers(), yield this._checkPorts(ports.dns, dns_key, 'dns', 'AZK_DNS_PORT'), yield this._checkPorts(ports.balancer, balancer_key, 'balancer', 'AZK_BALANCER_PORT'), - yield this._loadDnsServers(), - yield this._cleanContainers() + yield this._loadDnsServers() ); }) .catch(function (err) { From 4528a0455ec04a483242653e711b673f8e78c440 Mon Sep 17 00:00:00 2001 From: Felipe Arenales Date: Wed, 17 Jun 2015 15:08:09 -0300 Subject: [PATCH 4/4] Bumping version to azk v0.14.1 --- CHANGELOG.md | 5 +++++ npm-shrinkwrap.json | 2 +- package.json | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd5259da..97e903bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## v0.14.1 - (2015-06-17) + +* Bug + * [Agent] Fixing agent start progress in daemon mode + ## v0.14.0 - (2015-06-16) * Bug diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 9496e48e..62f0030c 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,6 +1,6 @@ { "name": "azk", - "version": "0.13.1", + "version": "0.14.1", "dependencies": { "archiver": { "version": "0.13.1", diff --git a/package.json b/package.json index 5a3075ef..2dfd7da0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "azk", - "version": "0.14.0", + "version": "0.14.1", "description": "Orchestrate development environments with agility and automation", "main": "index.js", "scripts": {