var async = require('async'); var semver = require('semver'); var UError = require('./error').UserError; var Local = require('./local-storage'); var Proxy = require('./up-storage'); var mystreams = require('./streams'); var utils = require('./utils'); // // Implements Storage interface // (same for storage.js, local-storage.js, up-storage.js) // function Storage(config) { if (!(this instanceof Storage)) return new Storage(config); this.config = config; // we support a number of uplinks, but only one local storage // Proxy and Local classes should have similar API interfaces this.uplinks = {}; for (var p in config.uplinks) { this.uplinks[p] = new Proxy(config.uplinks[p], config); } this.local = new Local(config); return this; } // // Add a {name} package to a system // // Function checks if package with the same name is available from uplinks. // If it isn't, we create package metadata locally and send requests to do // the same to all uplinks with write access. If all actions succeeded, we // report success, if just one uplink fails, we abort. // // TODO: if a package is uploaded to uplink1, but upload to uplink2 fails, // we report failure, but package is not removed from uplink1. This might // require manual intervention. // // Used storages: local (write) && uplinks (proxy_access, r/o) && // uplinks (proxy_publish, write) // Storage.prototype.add_package = function(name, metadata, callback) { var self = this; var uplinks = []; for (var i in self.uplinks) { if (self.config.proxy_access(name, i)) { uplinks.push(self.uplinks[i]); } } async.map(uplinks, function(up, cb) { up.get_package(name, function(err, res) { cb(null, [err, res]); }); }, function(err, results) { for (var i=0; i