UNPKG

gardener

Version:

A node process manager for couchapps that depend on npm modules, or have npm modules bundled with them.

102 lines (92 loc) 3.23 kB
module.exports = poll; var async = require('async'), url = require('url'), request = require('request'), watchlist = require('./watchlist'), logger = require('./logger'), utils = require('./utils'), process_manager = require('./processes'); function poll(couch_url, base_url, includes, excludes, dashboard, force) { logger.info('polling couch for design doc changes.'); async.auto({ all_dbs: function(cb) { utils.all_dbs(couch_url, cb); }, tree: ['all_dbs', function(cb, data) { cb(null, watchlist(base_url, couch_url, data.all_dbs, includes, excludes)); }], modules: ['tree', function(cb, data) { ddocs_with_modules(couch_url, data.tree, cb); }], install: ['modules', function(cb, data) { data.modules.forEach(function(module) { if (!module) return; process_manager.install({ couch_root_url: couch_url, db_name: module.db_name, db_url: url.resolve(couch_url, module.db_name), module_name: module.module_name, module_digest: module.module_digest, ddoc_url: to_ddoc_url(couch_url, module.db_name, module.ddoc_id), start_immediate: true, force_install: force }); }); cb(); }], check: ['install', function(cb) { process_manager.list(cb); }], remove_poll: ['check', function(cb, data) { remove_poll(data.check, cb); }], remove: ['remove_poll', function(cb, data) { data.remove_poll.forEach(function(module){ process_manager.uninstall(module.local_name, module); }); cb(); }] }, function(err, data) { if (err) { logger.error('polling failed.', err); } }); } function remove_poll(modules, callback) { var to_remove = []; async.each(modules, function(module, cb){ var url = module.ddoc_url; request.head(url, function(err, resp){ /* * Ignore errors and only remove modules if we get a 404. */ if (resp && resp.statusCode === 404) { to_remove.push(module); } cb(); }); }, function(err){ callback(err, to_remove); }); } function ddocs_with_modules(couch_root_url, tree, callback) { var all = []; if (!tree.dbs || tree.dbs.length === 0) { return callback(null, all); } async.forEachLimit(tree.dbs, 1, function(db_name, cb) { var filter = { includes: tree.ddocs.includes[db_name] || [], excludes: tree.ddocs.excludes[db_name] || [] }; utils.find_design_docs_with_modules(couch_root_url, db_name, filter, function(err, info){ all = all.concat(info); return cb(null); }); }, function(err) { callback(err, all); }); } function to_ddoc_url(couch_root_url, db_name, doc_id) { return url.resolve(couch_root_url, db_name + '/' + doc_id); }