UNPKG

domotz-remote-pawn

Version:

Domotz Agent

125 lines (109 loc) 5.02 kB
/** This file is part of Domotz Agent. * Copyright (C) 2016 Domotz Ltd * * Domotz Agent is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Domotz Agent is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>. **/ /** * Created by Tommaso Latini <tommaso@domotz.com> on 18/12/15. */ const MODULE = 'UPDATE_PACKAGE'; const NODE_MODULES = 'node_modules'; const NODE_CMD = 'domotz_node'; var factory = function (q, path, random, http, log, status, file, proc, mutex, eventUtils, engineRequest) { var env = process.env; var exec = proc.exec; var spawn = proc.spawn; var kill = proc.kill; var join = path.join; var rootDir = env.DOMOTZ_ROOT_DIR; var binDir = env.DOMOTZ_BIN_DIR; var libDir = env.DOMOTZ_LIB_DIR; var tmpInstallFolder = join(libDir, 'tmp_inst'); var npmArgs = [ join(binDir, 'domotz_npm'), '--cache', join(rootDir, '.npm'), '--userconfig', join(rootDir, '.npmrc') ]; var lockId = random.md5(String(Math.random())); function updateAgent(registry, name, version) { if (mutex.lock(MODULE, lockId)) { var tmpPawnFolder = join(tmpInstallFolder, NODE_MODULES, name); var pawnFolder = join(libDir, NODE_MODULES, name); var oldPawnFolder = pawnFolder + '_old'; var npmInstallArgs = npmArgs.concat(['install', name + '@' + version, '--prefix', tmpInstallFolder]); var previousStatus = status.get(); status.set(status.UPDATING); console.info('%s - Start Update Agent from %s. Name: %s, Version: %s.', MODULE, registry, name, version); exec('rm -rf ' + oldPawnFolder) .then(function() { console.info('%s - Removed %s', MODULE, oldPawnFolder); return exec('rm -rf ' + tmpInstallFolder); }) .then(function() { console.info('%s - Creating %s', MODULE, tmpInstallFolder); return exec('mkdir -p ' + tmpInstallFolder); }) .then(function () { console.info('%s - Created %s', MODULE, tmpInstallFolder); return spawn(NODE_CMD, npmInstallArgs); }) .then(function() { console.info('%s - Finished download of package: %s@%s', MODULE, name, version); // NOTE: The domotz package replacement must be synchronous // to minimize other routines interference file.rename(pawnFolder, oldPawnFolder); file.rename(tmpPawnFolder, pawnFolder); console.info('%s - Moved %s -> %s. Finish installation of: %s@%s', MODULE, tmpPawnFolder, pawnFolder, name, version); }) .then(function() { console.info('%s - Removing %s', MODULE, tmpInstallFolder); return exec('rm -rf ' + tmpInstallFolder); }) .then(function () { var deferred = q.defer(); if (!engineRequest || typeof engineRequest !== 'object' || typeof engineRequest.sendWithPromise !== 'function') { deferred.resolve(); } else { var body = eventUtils.getBodyForEvent("down", "updateAgent"); engineRequest.sendWithPromise( '/event', 'POST', body, undefined, undefined, {maxAttempts: 5, retryDelay: 3000}) .finally(function () { deferred.resolve(); }); } return deferred; }) .then(function() { return kill(process.pid); }) .catch(function errorHandler(err) { console.warn('%s - Failed update procedure', MODULE); console.error('%s - Error: %s', MODULE, JSON.stringify(err)); console.error(err.stack); }) .finally(function () { mutex.unlock(MODULE, lockId); status.set(previousStatus); }); } } return { updateAgent: updateAgent }; }; module.exports.factory = factory;