From 0e0dfed6a89897d15c008656321d49c5c5ba175c Mon Sep 17 00:00:00 2001 From: David Glasser Date: Wed, 28 Jan 2015 15:13:58 -0800 Subject: [PATCH 1/8] Remove "control program" support This was support code for a now unused system. --- packages/ctl-helper/.gitignore | 1 - packages/ctl-helper/.npm/package/.gitignore | 1 - packages/ctl-helper/.npm/package/README | 7 - .../.npm/package/npm-shrinkwrap.json | 15 - packages/ctl-helper/README.md | 2 - packages/ctl-helper/ctl-helper.js | 275 ------------------ packages/ctl-helper/package.js | 12 - packages/ctl/.gitignore | 1 - packages/ctl/README.md | 2 - packages/ctl/ctl.js | 194 ------------ packages/ctl/package.js | 10 - tools/bundler.js | 20 -- tools/commands.js | 3 +- tools/deploy-galaxy.js | 3 +- tools/project-context.js | 15 - 15 files changed, 2 insertions(+), 559 deletions(-) delete mode 100644 packages/ctl-helper/.gitignore delete mode 100644 packages/ctl-helper/.npm/package/.gitignore delete mode 100644 packages/ctl-helper/.npm/package/README delete mode 100644 packages/ctl-helper/.npm/package/npm-shrinkwrap.json delete mode 100644 packages/ctl-helper/README.md delete mode 100644 packages/ctl-helper/ctl-helper.js delete mode 100644 packages/ctl-helper/package.js delete mode 100644 packages/ctl/.gitignore delete mode 100644 packages/ctl/README.md delete mode 100644 packages/ctl/ctl.js delete mode 100644 packages/ctl/package.js diff --git a/packages/ctl-helper/.gitignore b/packages/ctl-helper/.gitignore deleted file mode 100644 index 677a6fc263..0000000000 --- a/packages/ctl-helper/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.build* diff --git a/packages/ctl-helper/.npm/package/.gitignore b/packages/ctl-helper/.npm/package/.gitignore deleted file mode 100644 index 3c3629e647..0000000000 --- a/packages/ctl-helper/.npm/package/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/packages/ctl-helper/.npm/package/README b/packages/ctl-helper/.npm/package/README deleted file mode 100644 index 3d492553a4..0000000000 --- a/packages/ctl-helper/.npm/package/README +++ /dev/null @@ -1,7 +0,0 @@ -This directory and the files immediately inside it are automatically generated -when you change this package's NPM dependencies. Commit the files in this -directory (npm-shrinkwrap.json, .gitignore, and this README) to source control -so that others run the same versions of sub-dependencies. - -You should NOT check in the node_modules directory that Meteor automatically -creates; if you are using git, the .gitignore file tells git to ignore it. diff --git a/packages/ctl-helper/.npm/package/npm-shrinkwrap.json b/packages/ctl-helper/.npm/package/npm-shrinkwrap.json deleted file mode 100644 index 18e7c137ad..0000000000 --- a/packages/ctl-helper/.npm/package/npm-shrinkwrap.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "dependencies": { - "optimist": { - "version": "0.6.0", - "dependencies": { - "wordwrap": { - "version": "0.0.2" - }, - "minimist": { - "version": "0.0.5" - } - } - } - } -} diff --git a/packages/ctl-helper/README.md b/packages/ctl-helper/README.md deleted file mode 100644 index 9b1b1619cc..0000000000 --- a/packages/ctl-helper/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This was an internal Meteor package used for interacting with internal prototype -systems that no longer exist. diff --git a/packages/ctl-helper/ctl-helper.js b/packages/ctl-helper/ctl-helper.js deleted file mode 100644 index a5904a08a5..0000000000 --- a/packages/ctl-helper/ctl-helper.js +++ /dev/null @@ -1,275 +0,0 @@ -var optimist = Npm.require('optimist'); -var Future = Npm.require('fibers/future'); - -Ctl = {}; - -var connection; -var checkConnection; - -_.extend(Ctl, { - Commands: [], - - main: function (argv) { - var opt = optimist(argv) - .alias('h', 'help') - .boolean('help'); - argv = opt.argv; - - if (argv.help) { - argv._.splice(0, 0, "help"); - delete argv.help; - } - - var cmdName = 'help'; - if (argv._.length) - cmdName = argv._.splice(0,1)[0]; - - Ctl.findCommand(cmdName).func(argv); - Ctl.disconnect(); - return 0; - }, - - startServerlikeProgramIfNotPresent: function (program, tags, admin) { - var numServers = Ctl.getJobsByApp( - Ctl.myAppName(), {program: program, done: false}).count(); - if (numServers === 0) { - return Ctl.startServerlikeProgram(program, tags, admin); - } else { - console.log(program, "already running."); - } - return null; - }, - - startServerlikeProgram: function (program, tags, admin) { - var appConfig = Ctl.prettyCall( - Ctl.findGalaxy(), 'getAppConfiguration', [Ctl.myAppName()]); - if (typeof admin == 'undefined') - admin = appConfig.admin; - admin = !!admin; - - var jobId = null; - var rootUrl = Ctl.rootUrl; - if (! rootUrl) { - var bindPathPrefix = ""; - if (admin) { - bindPathPrefix = "/" + encodeURIComponent(Ctl.myAppName()).replace(/\./g, '_'); - } - rootUrl = "https://" + appConfig.sitename + bindPathPrefix; - } - - // Allow appConfig settings to be objects or strings. We need to stringify - // them to pass them to the app in the env var. - // Backwards compat with old app config format. - _.each(["settings", "METEOR_SETTINGS"], function (settingsKey) { - if (appConfig[settingsKey] && typeof appConfig[settingsKey] === "object") - appConfig[settingsKey] = JSON.stringify(appConfig[settingsKey]); - }); - - // XXX args? env? - var env = { - ROOT_URL: rootUrl, - METEOR_SETTINGS: appConfig.settings || appConfig.METEOR_SETTINGS - }; - if (admin) - env.ADMIN_APP = 'true'; - jobId = Ctl.prettyCall(Ctl.findGalaxy(), 'run', [Ctl.myAppName(), program, { - exitPolicy: 'restart', - env: env, - ports: { - "main": { - bindEnv: "PORT", - routeEnv: "ROUTE"//, - //bindIpEnv: "BIND_IP" // Later, we can teach Satellite to do - //something like recommend the process bind to a particular IP here. - //For now, we don't have a way of setting this, so Satellite binds - //to 0.0.0.0 - } - }, - tags: tags - }]); - console.log("Started", program); - return jobId; - }, - - findCommand: function (name) { - var cmd = _.where(Ctl.Commands, { name: name })[0]; - if (! cmd) { - console.log("'" + name + "' is not a ctl command. See 'ctl --help'."); - process.exit(1); - } - - return cmd; - }, - - hasProgram: function (name) { - Ctl.subscribeToAppJobs(Ctl.myAppName()); - var myJob = Ctl.jobsCollection().findOne(Ctl.myJobId()); - var manifest = Ctl.prettyCall(Ctl.findGalaxy(), 'getStarManifest', [myJob.star]); - if (!manifest) - return false; - var found = false; - return _.find(manifest.programs, function (prog) { return prog.name === name; }); - }, - - findGalaxy: _.once(function () { - if (!('GALAXY' in process.env)) { - console.log( - "GALAXY environment variable must be set. See 'galaxy --help'."); - process.exit(1); - } - - connection = Follower.connect(process.env['ULTRAWORLD_DDP_ENDPOINT']); - checkConnection = Meteor.setInterval(function () { - if (Ctl.findGalaxy().status().status !== "connected" && - Ctl.findGalaxy().status().retryCount > 2) { - console.log("Cannot connect to galaxy; exiting"); - process.exit(3); - } - }, 2*1000); - return connection; - }), - - disconnect: function () { - if (connection) { - connection.disconnect(); - } - if (checkConnection) { - Meteor.clearInterval(checkConnection); - checkConnection = null; - } - }, - - updateProxyActiveTags: function (tags, options) { - var proxy; - var proxyTagSwitchFuture = new Future; - options = options || {}; - AppConfig.configureService('proxy', 'pre0', function (proxyService) { - if (proxyService && ! _.isEmpty(proxyService)) { - try { - proxy = Follower.connect(proxyService, { - group: "proxy" - }); - var tries = 0; - while (tries < 100) { - try { - proxy.call('updateTags', Ctl.myAppName(), tags, options); - break; - } catch (e) { - if (e.error === 'not-enough-bindings') { - tries++; - // try again in a sec. - Meteor._sleepForMs(1000); - } else { - throw e; - } - } - } - proxy.disconnect(); - if (!proxyTagSwitchFuture.isResolved()) - proxyTagSwitchFuture['return'](); - } catch (e) { - if (!proxyTagSwitchFuture.isResolved()) - proxyTagSwitchFuture['throw'](e); - } - } - }); - - var proxyTimeout = Meteor.setTimeout(function () { - if (!proxyTagSwitchFuture.isResolved()) - proxyTagSwitchFuture['throw']( - new Error("Timed out looking for a proxy " + - "or trying to change tags on it. Status: " + - (proxy ? proxy.status().status : "no connection")) - ); - }, 50*1000); - proxyTagSwitchFuture.wait(); - Meteor.clearTimeout(proxyTimeout); - }, - - jobsCollection: _.once(function () { - return new Mongo.Collection("jobs", {manager: Ctl.findGalaxy()}); - }), - - // use _.memoize so that this is called only once per app. - subscribeToAppJobs: _.memoize(function (appName) { - Ctl.findGalaxy()._subscribeAndWait("jobsByApp", [appName]); - }), - - // XXX this never unsubs... - getJobsByApp: function (appName, restOfSelector) { - var galaxy = Ctl.findGalaxy(); - Ctl.subscribeToAppJobs(appName); - var selector = {app: appName}; - if (restOfSelector) - _.extend(selector, restOfSelector); - return Ctl.jobsCollection().find(selector); - }, - - myAppName: _.once(function () { - if (!('GALAXY_APP' in process.env)) { - console.log("GALAXY_APP environment variable must be set."); - process.exit(1); - } - return process.env.GALAXY_APP; - }), - - myJobId: _.once(function () { - if (!('GALAXY_JOB' in process.env)) { - console.log("GALAXY_JOB environment variable must be set."); - process.exit(1); - } - return process.env.GALAXY_JOB; - }), - - usage: function() { - process.stdout.write( - "Usage: ctl [--help] []\n" + - "\n" + - "For now, the GALAXY environment variable must be set to the location of\n" + - "your Galaxy management server (Ultraworld.) This string is in the same\n" + - "format as the argument to DDP.connect().\n" + - "\n" + - "Commands:\n"); - _.each(Ctl.Commands, function (cmd) { - if (cmd.help && ! cmd.hidden) { - var name = cmd.name + " ".substr(cmd.name.length); - process.stdout.write(" " + name + cmd.help + "\n"); - } - }); - process.stdout.write("\n"); - process.stdout.write( - "See 'ctl help ' for details on a command.\n"); - process.exit(1); - }, - - // XXX copied to meteor/tools/deploy-galaxy.js - exitWithError: function (error, messages) { - messages = messages || {}; - - if (! (error instanceof Meteor.Error)) - throw error; // get a stack - - var msg = messages[error.error]; - if (msg) - process.stderr.write(msg + "\n"); - else if (error instanceof Meteor.Error) - process.stderr.write("Denied: " + error.message + "\n"); - - process.exit(1); - }, - - // XXX copied to meteor/tools/deploy-galaxy.js - prettyCall: function (galaxy, name, args, messages) { - try { - var ret = galaxy.apply(name, args); - } catch (e) { - Ctl.exitWithError(e, messages); - } - return ret; - }, - - kill: function (programName, jobId) { - console.log("Killing %s (%s)", programName, jobId); - Ctl.prettyCall(Ctl.findGalaxy(), 'kill', [jobId]); - } -}); diff --git a/packages/ctl-helper/package.js b/packages/ctl-helper/package.js deleted file mode 100644 index 3bf09a0f87..0000000000 --- a/packages/ctl-helper/package.js +++ /dev/null @@ -1,12 +0,0 @@ -Package.describe({ - summary: "Helpers for control programs", - version: "1.0.5" -}); - -Npm.depends({optimist: '0.6.0'}); - -Package.onUse(function (api) { - api.use(['logging', 'underscore', 'ddp', 'mongo', 'follower-livedata', 'application-configuration'], 'server'); - api.export('Ctl', 'server'); - api.addFiles('ctl-helper.js', 'server'); -}); diff --git a/packages/ctl/.gitignore b/packages/ctl/.gitignore deleted file mode 100644 index 677a6fc263..0000000000 --- a/packages/ctl/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.build* diff --git a/packages/ctl/README.md b/packages/ctl/README.md deleted file mode 100644 index 9b1b1619cc..0000000000 --- a/packages/ctl/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This was an internal Meteor package used for interacting with internal prototype -systems that no longer exist. diff --git a/packages/ctl/ctl.js b/packages/ctl/ctl.js deleted file mode 100644 index a2c0c2a2a5..0000000000 --- a/packages/ctl/ctl.js +++ /dev/null @@ -1,194 +0,0 @@ -var Future = Npm.require("fibers/future"); - -Ctl.Commands.push({ - name: "help", - func: function (argv) { - if (!argv._.length || argv.help) - Ctl.usage(); - var cmd = argv._.splice(0,1)[0]; - argv.help = true; - - Ctl.findCommand(cmd).func(argv); - } -}); - -var startFun = function (argv) { - if (argv.help || argv._.length !== 0) { - process.stderr.write( - "Usage: ctl start\n" + - "\n" + - "Starts the app. For now, this just means that it runs the 'server'\n" + - "program.\n" - ); - process.exit(1); - } - Ctl.subscribeToAppJobs(Ctl.myAppName()); - var jobs = Ctl.jobsCollection(); - var thisJob = jobs.findOne(Ctl.myJobId()); - Ctl.updateProxyActiveTags(['', thisJob.star]); - if (Ctl.hasProgram("console")) { - console.log("starting console for app", Ctl.myAppName()); - Ctl.startServerlikeProgramIfNotPresent("console", ["admin"], true); - } - console.log("starting server for app", Ctl.myAppName()); - Ctl.startServerlikeProgramIfNotPresent("server", ["runner"]); -}; - -Ctl.Commands.push({ - name: "start", - help: "Start this app", - func: startFun -}); - - -Ctl.Commands.push({ - name: "endUpdate", - help: "Start this app to end an update", - func: startFun -}); - -var stopFun = function (argv) { - if (argv.help || argv._.length !== 0) { - process.stderr.write( - "Usage: ctl stop\n" + - "\n" + - "Stops the app. For now, this just means that it kills all jobs\n" + - "other than itself.\n" - ); - process.exit(1); - } - - // Get all jobs (other than this job: don't commit suicide!) that are not - // already killed. - var jobs = Ctl.getJobsByApp( - Ctl.myAppName(), {_id: {$ne: Ctl.myJobId()}, done: false}); - jobs.forEach(function (job) { - // Don't commit suicide. - if (job._id === Ctl.myJobId()) - return; - // It's dead, Jim. - if (job.done) - return; - Ctl.kill(job.program, job._id); - }); - console.log("Server stopped."); -}; - -Ctl.Commands.push({ - name: "stop", - help: "Stop this app", - func: stopFun -}); - -var waitForDone = function (jobCollection, jobId) { - var fut = new Future(); - var found = false; - try { - var observation = jobCollection.find(jobId).observe({ - added: function (doc) { - found = true; - if (doc.done) - fut['return'](); - }, - changed: function (doc) { - if (doc.done) - fut['return'](); - }, - removed: function (doc) { - fut['return'](); - } - }); - // if the document doesn't exist at all, it's certainly done. - if (!found) - fut['return'](); - fut.wait(); - } finally { - observation.stop(); - } -}; - - -Ctl.Commands.push({ - name: "beginUpdate", - help: "Stop this app to begin an update", - func: function (argv) { - Ctl.subscribeToAppJobs(Ctl.myAppName()); - var jobs = Ctl.jobsCollection(); - var thisJob = jobs.findOne(Ctl.myJobId()); - // Look at all the server jobs that are on the old star. - var oldJobSelector = { - app: Ctl.myAppName(), - star: {$ne: thisJob.star}, - program: "server", - done: false - }; - var oldServers = jobs.find(oldJobSelector).fetch(); - // Start a new job for each of them. - var newServersAlreadyPresent = jobs.find({ - app: Ctl.myAppName(), - star: thisJob.star, - program: "server", - done: false - }).count(); - // discount any new servers we've already started. - oldServers.splice(0, newServersAlreadyPresent); - console.log("starting " + oldServers.length + " new servers to match old"); - _.each(oldServers, function (oldServer) { - Ctl.startServerlikeProgram("server", - oldServer.tags, - oldServer.env.ADMIN_APP); - }); - // Wait for them all to come up and bind to the proxy. - var updateProxyActiveTagsOptions = { - requireRegisteredBindingCount: {} - }; - // How many new servers should be up when we update the tags, given how many - // servers we're aiming at: - var target; - switch (oldServers.length) { - case 0: - target = 0; - break; - case 1: - target = 1; - break; - case 2: - target = 1; - break; - default: - var c = oldServers.length; - target = Math.min(c - 1, Math.ceil(c*.8)); - break; - } - updateProxyActiveTagsOptions.requireRegisteredBindingCount[thisJob.star] = - target; - Ctl.updateProxyActiveTags(['', thisJob.star], updateProxyActiveTagsOptions); - - // (eventually) tell the proxy to switch over to using the new star - // One by one, kill all the old star's server jobs. - var jobToKill = jobs.findOne(oldJobSelector); - while (jobToKill) { - Ctl.kill("server", jobToKill._id); - // Wait for it to go down - waitForDone(jobs, jobToKill._id); - // Spend some time in between to allow any reconnect storm to die down. - Meteor._sleepForMs(5000); - jobToKill = jobs.findOne(oldJobSelector); - } - // Now kill all old non-server jobs. They're less important. - jobs.find({ - app: Ctl.myAppName(), - star: {$ne: thisJob.star}, - program: {$ne: "server"}, - done: false - }).forEach(function (job) { - Ctl.kill(job.program, job._id); - }); - // fin - process.exit(0); - } -}); - -main = function (argv) { - return Ctl.main(argv); -}; diff --git a/packages/ctl/package.js b/packages/ctl/package.js deleted file mode 100644 index 3065164c1e..0000000000 --- a/packages/ctl/package.js +++ /dev/null @@ -1,10 +0,0 @@ -Package.describe({ - summary: "Default control program for an application", - version: "1.0.3" -}); - -Package.onUse(function (api) { - api.use(['underscore', 'ddp', 'mongo', 'ctl-helper', 'application-configuration', 'follower-livedata'], 'server'); - api.export('main', 'server'); - api.addFiles('ctl.js', 'server'); -}); diff --git a/tools/bundler.js b/tools/bundler.js index a85d0725fa..0e02d12a38 100644 --- a/tools/bundler.js +++ b/tools/bundler.js @@ -1793,7 +1793,6 @@ var writeTargetToPath = function (name, target, outputPath, options) { // options: // - includeNodeModulesSymlink: bool // - builtBy: vanity identification string to write into metadata -// - controlProgram: name of the control program (should be a target name) // - releaseName: The Meteor release version // - getRelativeTargetPath: see doc at ServerTarget.write var writeSiteArchive = function (targets, outputPath, options) { @@ -1804,16 +1803,11 @@ var writeSiteArchive = function (targets, outputPath, options) { symlink: options.includeNodeModulesSymlink }); - if (options.controlProgram && ! (options.controlProgram in targets)) - throw new Error("controlProgram '" + options.controlProgram + - "' is not the name of a target?"); - try { var json = { format: "site-archive-pre1", builtBy: options.builtBy, programs: [], - control: options.controlProgram || undefined, meteorRelease: options.releaseName }; @@ -1868,7 +1862,6 @@ var writeSiteArchive = function (targets, outputPath, options) { json.programs.push(writeTargetToPath(name, target, builder.buildPath, { includeNodeModulesSymlink: options.includeNodeModulesSymlink, builtBy: options.builtBy, - controlProgram: options.controlProgram, releaseName: options.releaseName, getRelativeTargetPath: options.getRelativeTargetPath })); @@ -1925,9 +1918,6 @@ var writeSiteArchive = function (targets, outputPath, options) { * - hasCachedBundle: true if we already have a cached bundle stored in * /build. When true, we only build the new client targets in the bundle. * - * - requireControlProgram: true if we need to include a "ctl" program in - * the bundle. This is required for an old prototype of Galaxy. - * * Returns an object with keys: * - errors: A buildmessage.MessageSet, or falsy if bundling succeeded. * - serverWatchSet: Information about server files and paths that were @@ -2044,15 +2034,6 @@ exports.bundle = function (options) { targets.server = server; } - // Create a "control program". This is required for an old version of - // Galaxy. - var controlProgram = null; - if (options.requireControlProgram) { - var target = makeServerTarget("ctl"); - targets["ctl"] = target; - controlProgram = "ctl"; - } - // Hack to let servers find relative paths to clients. Should find // another solution eventually (probably some kind of mount // directive that mounts the client bundle in the server at runtime) @@ -2076,7 +2057,6 @@ exports.bundle = function (options) { var writeOptions = { includeNodeModulesSymlink: includeNodeModulesSymlink, builtBy: builtBy, - controlProgram: controlProgram, releaseName: releaseName, getRelativeTargetPath: getRelativeTargetPath }; diff --git a/tools/commands.js b/tools/commands.js index 8f4b3d7368..4a1243e884 100644 --- a/tools/commands.js +++ b/tools/commands.js @@ -1074,8 +1074,7 @@ main.registerCommand({ var projectContext = new projectContextModule.ProjectContext({ projectDir: options.appDir, - serverArchitectures: _.uniq([buildArch, archinfo.host()]), - requireControlProgram: useGalaxy + serverArchitectures: _.uniq([buildArch, archinfo.host()]) }); main.captureAndExit("=> Errors while initializing project:", function () { diff --git a/tools/deploy-galaxy.js b/tools/deploy-galaxy.js index d542396d4d..9db8496e50 100644 --- a/tools/deploy-galaxy.js +++ b/tools/deploy-galaxy.js @@ -195,8 +195,7 @@ exports.deploy = function (options) { var bundleResult = bundler.bundle({ projectContext: options.projectContext, outputPath: bundlePath, - buildOptions: options.buildOptions, - requireControlProgram: true + buildOptions: options.buildOptions }); if (bundleResult.errors) { diff --git a/tools/project-context.js b/tools/project-context.js index e608c3992e..405c91f3bd 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -113,9 +113,6 @@ _.extend(ProjectContext.prototype, { // package names. self._upgradePackageNames = options.upgradePackageNames; - // Set when deploying to a previous Galaxy prototype. - self._requireControlProgram = options.requireControlProgram; - // Set by publishing commands to ensure that published packages always have // a web.cordova slice (because we aren't yet smart enough to just default // to using the web.browser slice instead or make a common 'web' slice). @@ -501,7 +498,6 @@ _.extend(ProjectContext.prototype, { self._addAppConstraints(depsAndConstraints); self._addLocalPackageConstraints(depsAndConstraints); self._addReleaseConstraints(depsAndConstraints); - self._addGalaxyPrototypeConstraints(depsAndConstraints); return depsAndConstraints; }, @@ -540,17 +536,6 @@ _.extend(ProjectContext.prototype, { }); }, - // We only need to build ctl if deploying to the legacy Galaxy - // prototype. (Note that this means that we will need a new constraint - // solution when deploying vs when running locally. This code will be deleted - // soon anyway.) - _addGalaxyPrototypeConstraints: function (depsAndConstraints) { - var self = this; - if (self._requireControlProgram) { - depsAndConstraints.deps.push('ctl'); - } - }, - _getAnticipatedPrereleases: function (rootConstraints, cachedVersions) { var self = this; From 5cc93cea1af045069ee22a7765f8d40ebf15be21 Mon Sep 17 00:00:00 2001 From: David Glasser Date: Wed, 28 Jan 2015 15:20:43 -0800 Subject: [PATCH 2/8] Remove legacy support from deploy-style commands This includes removing the options `deploy --star`, `deploy --admin`, and `logs -f` --- tools/commands.js | 109 ++--------- tools/deploy-galaxy.js | 418 ----------------------------------------- tools/help.txt | 1 - 3 files changed, 15 insertions(+), 513 deletions(-) delete mode 100644 tools/deploy-galaxy.js diff --git a/tools/commands.js b/tools/commands.js index 4a1243e884..ae0400638e 100644 --- a/tools/commands.js +++ b/tools/commands.js @@ -23,8 +23,8 @@ var execFileSync = require('./utils.js').execFileSync; var Console = require('./console.js').Console; var projectContextModule = require('./project-context.js'); -// The architecture used by Galaxy servers; it's the architecture used -// by 'meteor deploy'. +// The architecture used by MDG's hosted servers; it's the architecture used by +// 'meteor deploy'. var DEPLOY_ARCH = 'os.linux.x86_64'; // The default port that the development server listens on. @@ -55,14 +55,6 @@ var qualifySitename = function (site) { return site; }; -// Given a (non necessarily fully qualified) site name from the -// command line, return true if the site is hosted by a Galaxy, else -// false. -var hostedWithGalaxy = function (site) { - var site = qualifySitename(site); - return !! require('./deploy-galaxy.js').discoverGalaxy(site); -}; - // Display a message showing valid Meteor architectures. var showInvalidArchMsg = function (arch) { Console.info("Invalid architecture: " + arch); @@ -917,13 +909,8 @@ main.registerCommand({ var site = qualifySitename(options.args[0]); config.printUniverseBanner(); - if (hostedWithGalaxy(site)) { - var deployGalaxy = require('./deploy-galaxy.js'); - mongoUrl = deployGalaxy.temporaryMongoUrl(site); - } else { - mongoUrl = deploy.temporaryMongoUrl(site); - usedMeteorAccount = true; - } + mongoUrl = deploy.temporaryMongoUrl(site); + usedMeteorAccount = true; if (! mongoUrl) // temporaryMongoUrl() will have printed an error message @@ -997,14 +984,9 @@ main.registerCommand({ 'delete': { type: Boolean, short: 'D' }, debug: { type: Boolean }, settings: { type: String }, - star: { type: String }, // No longer supported, but we still parse it out so that we can // print a custom error message. password: { type: String }, - // Shouldn't be documented until the Galaxy release. Marks the - // application as an admin app, so that it will be available in - // Galaxy admin interface. - admin: { type: Boolean }, // Override architecture to deploy whatever stuff we have locally, even if // it contains binary packages that should be incompatible. A hack to allow // people to deploy from checkout or do other weird shit. We are not @@ -1012,42 +994,24 @@ main.registerCommand({ 'override-architecture-with-local' : { type: Boolean } }, requiresApp: function (options) { - return options.delete || options.star ? false : true; + return ! options.delete; }, catalogRefresh: new catalog.Refresh.Never() }, function (options) { var site = qualifySitename(options.args[0]); config.printUniverseBanner(); - var useGalaxy = hostedWithGalaxy(site); - var deployGalaxy; if (options.delete) { - if (useGalaxy) { - deployGalaxy = require('./deploy-galaxy.js'); - return deployGalaxy.deleteApp(site); - } else { - return deploy.deleteApp(site); - } + return deploy.deleteApp(site); } if (options.password) { - if (useGalaxy) { - Console.error("Galaxy does not support --password."); - } else { - Console.error( - "Setting passwords on apps is no longer supported. Now there are " + + Console.error( + "Setting passwords on apps is no longer supported. Now there are " + "user accounts and your apps are associated with your account so " + "that only you (and people you designate) can access them. See the " + Console.command("'meteor claim'") + " and " + Console.command("'meteor authorized'") + " commands."); - } - return 1; - } - - var starball = options.star; - if (starball && ! useGalaxy) { - // XXX it would be nice to support this for non-Galaxy deploys too - Console.error("--star: only supported when deploying to Galaxy."); return 1; } @@ -1088,25 +1052,12 @@ main.registerCommand({ serverArch: buildArch }; - var deployResult; - if (useGalaxy) { - deployGalaxy = require('./deploy-galaxy.js'); - deployResult = deployGalaxy.deploy({ - projectContext: projectContext, - app: site, - settingsFile: options.settings, - starball: starball, - buildOptions: buildOptions, - admin: options.admin - }); - } else { - deployResult = deploy.bundleAndDeploy({ - projectContext: projectContext, - site: site, - settingsFile: options.settings, - buildOptions: buildOptions - }); - } + var deployResult = deploy.bundleAndDeploy({ + projectContext: projectContext, + site: site, + settingsFile: options.settings, + buildOptions: buildOptions + }); if (deployResult === 0) { auth.maybePrintRegistrationLink({ @@ -1129,27 +1080,11 @@ main.registerCommand({ name: 'logs', minArgs: 1, maxArgs: 1, - options: { - // XXX once Galaxy is released, document this - stream: { type: Boolean, short: 'f' } - }, catalogRefresh: new catalog.Refresh.Never() }, function (options) { var site = qualifySitename(options.args[0]); - if (hostedWithGalaxy(site)) { - var deployGalaxy = require('./deploy-galaxy.js'); - var ret = deployGalaxy.logs({ - app: site, - streaming: options.stream - }); - if (options.stream && ret === null) { - throw new main.WaitForExit; - } - return ret; - } else { - return deploy.logs(site); - } + return deploy.logs(site); }); /////////////////////////////////////////////////////////////////////////////// @@ -1190,14 +1125,6 @@ main.registerCommand({ auth.pollForRegistrationCompletion(); var site = qualifySitename(options.args[0]); - if (hostedWithGalaxy(site)) { - Console.error( - "Sites hosted on Galaxy do not have an authorized user list. " + - "Instead, go to your Galaxy dashboard to change the authorized users " + - "of your Galaxy.\n"); - return 1; - } - if (! auth.isLoggedIn()) { Console.error( "You must be logged in for that. Try " + @@ -1238,12 +1165,6 @@ main.registerCommand({ return 1; } - if (hostedWithGalaxy(site)) { - Console.error( - "Sorry, you can't claim sites that are hosted on Galaxy."); - return 1; - } - return deploy.claim(site); }); diff --git a/tools/deploy-galaxy.js b/tools/deploy-galaxy.js deleted file mode 100644 index 9db8496e50..0000000000 --- a/tools/deploy-galaxy.js +++ /dev/null @@ -1,418 +0,0 @@ -var Future = require('fibers/future'); -var files = require('./files.js'); -var config = require('./config.js'); -var path = require('path'); -var isopackets = require("./isopackets.js"); -var httpHelpers = require('./http-helpers.js'); -var auth = require('./auth.js'); -var url = require('url'); -var _ = require('underscore'); -var buildmessage = require('./buildmessage.js'); -var ServiceConnection = require('./service-connection.js'); -var stats = require('./stats.js'); -var Console = require('./console.js').Console; - -// If 'error' is an exception that we know how to report in a -// user-friendly way, print an approprite message to stderr and return -// an appropriate exit status for a command. Else rethrow error. -// -// galaxyName should be the name of the galaxy that we're talking to. -// If messages is provided, it is a map from DDP error names to -// human-readable explanation to use. -var handleError = function (error, galaxyName, messages) { - messages = messages || {}; - - if (error.errorType === "Meteor.Error") { - var msg = messages[error.error]; - if (msg) - Console.error(msg); - else if (error.message) - Console.error("Denied: " + error.message); - return 1; - } else if (error.errorType === "DDP.ConnectionError") { - // If we have an http/https URL for a galaxyName instead of a - // proper galaxyName (which is what the code in this file - // currently passes), strip off the scheme and trailing slash. - var m = galaxyName.match(/^https?:\/\/(.*[^\/])\/?$/); - if (m) - galaxyName = m[1]; - - Console.error(galaxyName + ": connection failed"); - return 1; - } else { - throw error; - } -}; - -// Returns a ServiceConnection to a galaxy service that is authenticated -// from the credential cache. -// -// - galaxy: the name of the galaxy to connect to, as returned by -// discoverGalaxy (as described there, should probably be a galaxy -// name, but currently is a https or http URL) -// - service: the service to connect to within the Galaxy, such as -// 'ultraworld' or 'log-reader'. -var galaxyServiceConnection = function (galaxy, service) { - var endpointUrl = galaxy + "/" + service; - var parsedEndpoint = url.parse(endpointUrl); - var authToken = auth.getSessionToken(parsedEndpoint.hostname); - - // XXX XXX higher up on the stack, we need to get the galaxy name - // from the hostname of endpointUrl, and run the login command for - // that galaxy. - if (! authToken) - throw new Error("not logged in to galaxy?"); - - return new ServiceConnection(endpointUrl, { - headers: { - cookie: "GALAXY_AUTH=" + authToken - } - }); -}; - -// Determine if a particular site is hosted by Galaxy, and if so, by -// which Galaxy. 'app' should be a hostname, like 'myapp.meteor.com' -// or 'mysite.com'. Returns the base URL for the Galaxy -// (https://[galaxyname], or possibly http://[galaxyname] if running -// locally). The URL will not have a trailing slash. Returns null if -// the site is not hosted by Galaxy. -// -// The result is cached, so there is no penality for calling this -// function multiple times (during the same run of the -// tool). (Assuming you wait for the first call to complete before -// making the subsequent calls. The caching doesn't kick in until the -// first call returns.) -// -// XXX in the future, should probably return the name of the Galaxy, -// rather than a URL. -// -// XXX at many places in this file we call discoverGalaxy and don't -// check its return value. This is safe because we expect that -// command.js will have already called discoverGalaxy on the same app -// before we get here, and gotten a satisfactory value, which is now -// cached. But it's not great -- add better error handling. -var discoveryCache = {}; -exports.discoverGalaxy = function (app) { - var cacheKey = app; - if (_.has(discoveryCache, cacheKey)) - return discoveryCache[cacheKey]; - - app = app + ":" + config.getDiscoveryPort(); - var discoveryUrl = "https://" + app + "/_GALAXY_"; - var fut = new Future(); - - if (process.env.GALAXY) - return process.env.GALAXY; - - // At some point we may want to send a version in the request so that galaxy - // can respond differently to different versions of meteor. - httpHelpers.request({ - url: discoveryUrl, - json: true, - strictSSL: true, - // We don't want to be confused by, eg, a non-Galaxy-hosted site which - // redirects to a Galaxy-hosted site. - followRedirect: false - }, function (err, resp, body) { - if (! err && - resp.statusCode === 200 && - body && - _.has(body, "galaxyDiscoveryVersion") && - _.has(body, "galaxyUrl") && - (body.galaxyDiscoveryVersion === "galaxy-discovery-pre0")) { - var result = body.galaxyUrl; - - if (result.indexOf("https://") === -1) - result = "https://" + result; - - if (result[result.length - 1] === "/") - result = result.substring(0, result.length - 1); - - fut.return(result); - } else { - fut.return(null); - } - }); - - var result = fut.wait(); - discoveryCache[cacheKey] = result; - return result; -}; - -exports.deleteApp = function (app) { - var galaxy = exports.discoverGalaxy(app); - var conn = galaxyServiceConnection(galaxy, "ultraworld"); - - try { - conn.call("destroyApp", app); - Console.info("Deleted."); - } catch (e) { - return handleError(e, galaxy); - } finally { - conn.close(); - } -}; - -// Returns exit code for deploy command. -// -// options: -// - app -// - appDir -// - settingsFile -// - buildOptions -// - starball -// XXX refactor this to separate the "maybe bundle" part from "actually deploy" -// so we can be careful to not rely on any of the app dir context when -// in --star mode. -exports.deploy = function (options) { - var conn = null; - - try { - var tmpdir = files.mkdtemp('deploy'); - var buildDir = path.join(tmpdir, 'build'); - var topLevelDirName = path.basename(options.appDir); - var bundlePath = path.join(buildDir, topLevelDirName); - var bundler = require('./bundler.js'); - var starball; - - var settings = null; - var messages = buildmessage.capture({ - title: "preparing to deploy", - rootPath: process.cwd() - }, function () { - if (options.settingsFile) - settings = files.getSettings(options.settingsFile); - }); - - // Don't try to connect to galaxy before the bundle is - // done. Because bundling doesn't yield, this will cause the - // connection to time out. Eventually we'd like to have bundle - // yield, so that we can connect (and make sure auth works) - // concurrent with bundling. - - if (! options.starball && ! messages.hasMessages()) { - Console.info('Deploying ' + options.app + '. Bundling...'); - var bundleResult = bundler.bundle({ - projectContext: options.projectContext, - outputPath: bundlePath, - buildOptions: options.buildOptions - }); - - if (bundleResult.errors) { - messages = bundleResult.errors; - } else { - stats.recordPackages({ - what: "sdk.deploy", - projectContext: options.projectContext, - site: options.app - }); - - // S3 (which is what's likely on the other end our upload) - // requires a content-length header for HTTP PUT uploads. That - // means that we have to actually tgz up the bundle before we - // can start the upload rather than streaming it. S3 has an - // alternate API for doing chunked uploads, but (a) it has a - // minimum chunk size of 5 MB, so it doesn't help us much - // (many/most stars will be smaller than that), and (b) it's - // nonstandard, so we'd have to bake in S3's specific - // scheme. Doesn't seem worthwhile for now, so just tar to a - // temporary directory. If stars get radically bigger then it - // might be worthwhile to tar to memory and spill to S3 every - // 5MB. - starball = path.join(tmpdir, topLevelDirName + ".tar.gz"); - files.createTarball(bundlePath, starball); - } - } else { - starball = options.starball; - } - - if (messages.hasMessages()) { - Console.info("\nErrors prevented deploying:"); - Console.info(messages.formatMessages()); - return 1; - } - - Console.info('Uploading...'); - - var galaxy = exports.discoverGalaxy(options.app); - conn = galaxyServiceConnection(galaxy, "ultraworld"); - - var created = true; - var appConfig = {}; - if (settings !== null) - appConfig.settings = settings; - - if (options.admin) - appConfig.admin = true; - - try { - conn.call('createApp', options.app, appConfig); - } catch (e) { - if (e.errorType === 'Meteor.Error' && e.error === 'already-exists') { - // Cool, it already exists. No problem. Just set the settings - // if they were passed. We explicitly check for undefined - // because we want to allow you to unset settings by passing - // an empty file. - if (appConfig.settings !== undefined) { - conn.call('updateAppConfiguration', options.app, appConfig); - } - created = false; - } else { - return handleError(e, galaxy); - } - } - - // Get the upload information from Galaxy. It's a surprise if this - // fails (we already know the app exists). - try { - var info = conn.call('beginUploadStar', options.app, - bundleResult.starManifest); - } catch (e) { - return handleError(e, galaxy); - } - - // Upload - // XXX copied from galaxy/tool/galaxy.js - var fileSize = files.stat(starball).size; - var fileStream = files.createReadStream(starball); - var future = new Future; - var req = httpHelpers.request({ - method: "PUT", - url: info.put, - headers: { 'content-length': fileSize, - 'content-type': 'application/octet-stream' }, - strictSSL: true - }, function (error, response, body) { - if (error || ((response.statusCode !== 200) - && (response.statusCode !== 201))) { - if (error && error.message) - Console.error("Upload failed: " + error.message); - else - Console.error("Upload failed" + - (response.statusCode ? - " (" + response.statusCode + ")" : "")); - future['return'](false); - } else - future['return'](true); - }); - - fileStream.pipe(req); - var uploadSucceeded = future.wait(); - if (! uploadSucceeded) - return 1; - - try { - var result = conn.call('completeUploadStar', info.id); - } catch (e) { - return handleError(e, galaxy, { - 'no-such-upload': 'Upload request expired. Try again.' - }); - } - - if (created) - Console.error(options.app + ": created app\n"); - - Console.error(options.app + ": " + - "pushed revision " + result.serial); - return 0; - } finally { - // Close the connection to Galaxy (otherwise Node will continue running). - conn && conn.close(); - } -}; - -// options: -// - app -// - streaming (BOOL) -// -// The log messages are printed. Returns a command exit code, or if -// streaming is true and streaming was successfully started, returns -// null. -exports.logs = function (options) { - var galaxy = exports.discoverGalaxy(options.app); - var logReader = galaxyServiceConnection(galaxy, "log-reader"); - - try { - var lastLogId = null; - var Log = isopackets.load('logging').logging.Log; - - // XXX we're cheating a bit here, relying on the server sending - // the log messages in order - var ok = logReader.connection.registerStore('logs', { - update: function (msg) { - // Ignore all messages but 'changed' - if (msg.msg !== 'changed') - return; - var obj = msg.fields.obj; - lastLogId = msg.fields.id; - obj = Log.parse(obj); - obj && console.log(Log.format(obj, {color: true})); - } - }); - - if (! ok) - throw new Error("Can't listen to messages on the logs collection"); - - var logsSubscription = null; - try { - logsSubscription = - logReader.subscribeAndWait("logsForApp", options.app, - { streaming: options.streaming }); - } catch (e) { - return handleError(e, galaxy, { - "no-such-app": "No such app: " + options.app - }); - } - - // In case of reconnect recover the state so user sees only new logs. - // Only set up the onReconnect handler after the subscribe and wait - // has returned; if we set it up before, then we'll end up with two - // subscriptions, because the onReconnect handler will run for the - // first time before the subscribeAndWait returns. - logReader.connection.onReconnect = function () { - logsSubscription && logsSubscription.stop(); - var opts = { streaming: options.streaming }; - if (lastLogId) - opts.resumeAfterId = lastLogId; - // Don't use subscribeAndWait here; it'll deadlock. We can't - // process the sub messages until `onReconnect` returns, and - // `onReconnect` won't return unless the sub messages have been - // processed. There's no reason we need to wait for the sub to be - // ready here anyway. - // XXX correctly handle errors on resubscribe - logsSubscription = logReader.connection.subscribe( - "logsForApp", - options.app, - opts - ); - }; - - return options.streaming ? null : 0; - } finally { - // If not streaming, close the connection to log-reader so that - // Node can exit cleanly. If streaming, leave the connection open - // so that we continue to get logs. - if (! options.streaming) { - logReader.close(); - } - } -}; - -// On failure, prints a message to stderr and returns null. Otherwise, -// returns a temporary authenticated Mongo URL allowing access to this -// site's database. -exports.temporaryMongoUrl = function (app) { - var galaxy = exports.discoverGalaxy(app); - var conn = galaxyServiceConnection(galaxy, "ultraworld"); - - try { - var mongoUrl = conn.call('getTemporaryMongoUrl', app); - } catch (e) { - handleError(e, galaxy); - return null; - } finally { - conn.close(); - } - - return mongoUrl; -}; diff --git a/tools/help.txt b/tools/help.txt index 6995fe34bb..f60e5d5c34 100644 --- a/tools/help.txt +++ b/tools/help.txt @@ -359,7 +359,6 @@ Options: --delete, -D permanently delete this deployment --debug deploy in debug mode (don't minify, etc) --settings set optional data for Meteor.settings - --star a star (tarball) to deploy instead of the current Meteor app >>> logs From df37fe5a9dbcbf797a189b9b2f42b03e7bd72950 Mon Sep 17 00:00:00 2001 From: David Glasser Date: Wed, 28 Jan 2015 15:27:11 -0800 Subject: [PATCH 3/8] Remove legacy login support This includes `meteor login --galaxy`. We still should be capable of cleaning up legacy tokens when we find them. --- tools/auth.js | 204 +++------------------------------------------- tools/commands.js | 5 +- 2 files changed, 12 insertions(+), 197 deletions(-) diff --git a/tools/auth.js b/tools/auth.js index 13165a82b1..e970aec268 100644 --- a/tools/auth.js +++ b/tools/auth.js @@ -181,7 +181,8 @@ var getSession = function (sessionData, domain) { // types: // - "meteor-account": a login to your Meteor Account -// - "galaxy": a login to a Galaxy +// We previously used: +// - "galaxy": a login to a legacy Galaxy prototype server var ensureSessionType = function (session, type) { if (! _.has(session, 'type')) session.type = type; @@ -259,53 +260,6 @@ var removePendingRevoke = function (domain, tokenIds) { writeSessionData(data); }; -var tryRevokeGalaxyTokens = function (domain, tokenIds, options) { - var oauthInfo = fetchGalaxyOAuthInfo(domain, options.timeout); - if (oauthInfo) { - url = oauthInfo.revokeUri; - } else { - return false; - } - - try { - var result = httpHelpers.request({ - url: url, - method: "POST", - form: { - tokenId: tokenIds.join(',') - }, - useSessionHeader: true, - timeout: options.timeout - }); - } catch (e) { - // most likely we don't have a net connection - return false; - } - var response = result.response; - - if (response.statusCode === 200 && - response.body) { - try { - var body = JSON.parse(response.body); - if (body.tokenRevoked) { - // Server confirms that the tokens have been revoked. Checking for a - // `tokenRevoked` key in the response confirms that we hit an actual - // galaxy auth server that understands that we were trying to revoke some - // tokens, not just a random URL that happened to return a 200 - // response. - - // (Be careful to reread session data in case httpHelpers changed it) - removePendingRevoke(domain, tokenIds); - } - } catch (e) { - return false; - } - return true; - } else { - return false; - } -}; - // If there are any logged out (pendingRevoke) tokens that haven't // been sent to the server for revocation yet, try to send // them. Reads the session file and then writes it back out to @@ -364,9 +318,10 @@ var tryRevokeOldTokens = function (options) { } return; } else if (session.type === "galaxy") { - if (! tryRevokeGalaxyTokens(domain, tokenIds, options)) { - logoutFailWarning(domain); - } + // These are tokens from a legacy Galaxy prototype, which cannot be + // revoked (because the prototype no longer exists), but we can at least + // remove them from the file. + removePendingRevoke(domain, tokenIds); } else { // don't know how to revoke tokens of this type logoutFailWarning(domain); @@ -375,40 +330,6 @@ var tryRevokeOldTokens = function (options) { }); }; -// Sends a request to https://: to find out the -// galaxy's OAuth client id and redirect_uri that should be used for -// authorization codes for this galaxy. Returns an object with keys -// 'oauthClientId', 'redirectUri', and 'revokeUri', or null if the -// request failed. -// -// 'timeout' is an optional request timeout in milliseconds. -var fetchGalaxyOAuthInfo = function (galaxyName, timeout) { - var galaxyAuthUrl = 'https://' + galaxyName + ':' + - config.getDiscoveryPort() + '/_GALAXYAUTH_'; - try { - var result = httpHelpers.request({ - url: galaxyAuthUrl, - json: true, - // on by default in our version of request, but just in case - strictSSL: true, - followRedirect: false, - timeout: timeout || 5000 - }); - } catch (e) { - return null; - } - - if (result.response.statusCode === 200 && - result.body && - result.body.oauthClientId && - result.body.redirectUri && - result.body.revokeUri) { - return result.body; - } else { - return null; - } -}; - var sendAuthorizeRequest = function (clientId, redirectUri, state) { var authCodeUrl = config.getOauthUrl() + "/authorize?" + querystring.stringify({ @@ -506,77 +427,6 @@ var oauthFlow = function (conn, options) { } }; -// Uses meteor accounts to log in to the specified galaxy. Returns an -// object with keys `token` and `tokenId` if the login was -// successful. If an error occurred, returns one of: -// { error: 'access-denied' } -// { error: 'no-galaxy' } -// { error: 'no-account-server' } -var logInToGalaxy = function (galaxyName) { - var oauthInfo = fetchGalaxyOAuthInfo(galaxyName); - if (! oauthInfo) { - return { error: 'no-galaxy' }; - } - - var galaxyClientId = oauthInfo.oauthClientId; - var galaxyRedirect = oauthInfo.redirectUri; - - // If the redirect URI is not in the DNS namespace that belongs to the - // Galaxy, then something is wrong. - if (url.parse(galaxyRedirect).hostname !== galaxyName) { - // XXX It's more like 'bad-galaxy' than 'no-galaxy'. - return { error: 'no-galaxy' }; - } - - // Ask the accounts server for an authorization code. - var crypto = require('crypto'); - var session = crypto.randomBytes(16).toString('hex'); - var stateInfo = { session: session }; - - var authorizeResult; - - try { - authorizeResult = sendAuthorizeRequest( - galaxyClientId, - galaxyRedirect, - encodeURIComponent(JSON.stringify(stateInfo)) - ); - } catch (err) { - return { error: err.message }; - } - - // Ask the galaxy to log us in with our auth code. - try { - var galaxyResult = httpHelpers.request({ - url: authorizeResult.location, - method: 'GET', - strictSSL: true, - headers: { - cookie: 'GALAXY_OAUTH_SESSION=' + session + - '; GALAXY_USER_AGENT_TOOL=' + - encodeURIComponent(JSON.stringify(utils.getAgentInfo())) - } - }); - var body = JSON.parse(galaxyResult.body); - } catch (e) { - return { error: (body && body.error) || 'no-galaxy' }; - } - var response = galaxyResult.response; - - // 'access-denied' isn't exactly right because it's possible that the galaxy - // went down since our last request, but close enough. - - if (response.statusCode !== 200 || - ! body || - ! _.has(galaxyResult.setCookie, 'GALAXY_AUTH')) - return { error: (body && body.error) || 'access-denied' }; - - return { - token: galaxyResult.setCookie.GALAXY_AUTH, - tokenId: body.tokenId - }; -}; - // Prompt the user for a password, and then log in. Returns true if a // successful login was accomplished, else false. // @@ -681,11 +531,9 @@ exports.loginCommand = withAccountsConnection(function (options, config.printUniverseBanner(); var data = readSessionData(); - var galaxy = options.galaxy; - if (! galaxy && - (! getSession(data, config.getAccountsDomain()).token || - options.overwriteExistingToken)) { + if (! getSession(data, config.getAccountsDomain()).token || + options.overwriteExistingToken) { var loginOptions = {}; if (options.email) { @@ -707,43 +555,13 @@ exports.loginCommand = withAccountsConnection(function (options, } } - // XXX Make the galaxy login not do a login if there is an existing token, just like MA - if (galaxy) { - var galaxyLoginResult = logInToGalaxy(galaxy); - if (galaxyLoginResult.error) { - // XXX add human readable error messages - var failedLoginMsg = "\nLogin to ' + galaxy + ' failed. "; - if (galaxyLoginResult.error === 'unauthorized') { - Console.error( - failedLoginMsg + 'You are not authorized for this galaxy.'); - } else if (galaxyLoginResult.error === 'no_oauth_server') { - Console.error( - failedLoginMsg + 'The galaxy could not contact Meteor Accounts.'); - } else if (galaxyLoginResult.error === 'no_identity') { - Console.error( - failedLoginMsg + 'Your login information could not be found.'); - } else { - Console.error(failedLoginMsg + 'Error: ' + galaxyLoginResult.error ); - } - - return 1; - } - data = readSessionData(); // be careful to reread data file after RPC - var session = getSession(data, galaxy); - ensureSessionType(session, "galaxy"); - session.token = galaxyLoginResult.token; - session.tokenId = galaxyLoginResult.tokenId; - writeSessionData(data); - } - tryRevokeOldTokens({ firstTry: true, connection: connection }); data = readSessionData(); Console.error(); - Console.error("Logged in" + (galaxy ? " to " + galaxy : "") + - (currentUsername(data) ? - " as " + currentUsername(data) : "") + ".", - "Thanks for being a Meteor developer!"); + Console.error("Logged in" + + (currentUsername(data) ? " as " + currentUsername(data) : "") + + ". Thanks for being a Meteor developer!"); return 0; }); diff --git a/tools/commands.js b/tools/commands.js index ae0400638e..3c3589fa84 100644 --- a/tools/commands.js +++ b/tools/commands.js @@ -1507,10 +1507,7 @@ main.registerCommand({ main.registerCommand({ name: 'login', options: { - email: { type: Boolean }, - // Undocumented: get credentials on a specific Galaxy. Do we still - // need this? - galaxy: { type: String } + email: { type: Boolean } }, catalogRefresh: new catalog.Refresh.Never() }, function (options) { From 62037959fe53e1e415f20c7b19ec647081d8cd47 Mon Sep 17 00:00:00 2001 From: David Glasser Date: Wed, 28 Jan 2015 15:31:53 -0800 Subject: [PATCH 4/8] Clean up comments about legacy code --- packages/mongo/mongo_driver.js | 2 +- tools/bundler.js | 18 ++++++++---------- tools/config.js | 3 +-- tools/tests/logs-mongo-auth.js | 3 +++ 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/mongo/mongo_driver.js b/packages/mongo/mongo_driver.js index 18540ecb07..88150bb5f7 100644 --- a/packages/mongo/mongo_driver.js +++ b/packages/mongo/mongo_driver.js @@ -1229,7 +1229,7 @@ MongoConnection.prototype._observeChangesTailable = function ( // XXX We probably need to find a better way to expose this. Right now // it's only used by tests, but in fact you need it in normal -// operation to interact with capped collections (eg, Galaxy uses it). +// operation to interact with capped collections. MongoInternals.MongoTimestamp = MongoDB.Timestamp; MongoInternals.Connection = MongoConnection; diff --git a/tools/bundler.js b/tools/bundler.js index 0e02d12a38..41998b3c11 100644 --- a/tools/bundler.js +++ b/tools/bundler.js @@ -36,10 +36,9 @@ // running in standalone mode (after setting appropriate environment // variables as documented in README) // -// /server/.bundle_version.txt: contains the dev_bundle version that -// legacy (read: current) Galaxy version read in order to set -// NODE_PATH to point to arch-specific builds of binary node modules -// (primarily this is for node-fibers) +// /server/.bundle_version.txt: contains the dev_bundle version that the meteor +// deploy server reads in order to set NODE_PATH to point to arch-specific +// builds of binary node modules // // XXX in the future one program (which must be a server-type // architecture) will be designated as the 'init' program. The @@ -1811,12 +1810,11 @@ var writeSiteArchive = function (targets, outputPath, options) { meteorRelease: options.releaseName }; - // Tell Galaxy what version of the dependency kit we're using, so - // it can load the right modules. (Include this even if we copied - // or symlinked a node_modules, since that's probably enough for - // it to work in spite of the presence of node_modules for the - // wrong arch). The place we stash this is grody for temporary - // reasons of backwards compatibility. + // Tell the deploy server what version of the dependency kit we're using, so + // it can load the right modules. (Include this even if we copied or + // symlinked a node_modules, since that's probably enough for it to work in + // spite of the presence of node_modules for the wrong arch). The place we + // stash this is grody for temporary reasons of backwards compatibility. builder.write(files.pathJoin('server', '.bundle_version.txt'), { file: files.pathJoin(files.getDevBundle(), '.bundle_version.txt') }); diff --git a/tools/config.js b/tools/config.js index 2b516508e8..eef605457a 100644 --- a/tools/config.js +++ b/tools/config.js @@ -19,8 +19,7 @@ var tropohouse = require('./tropohouse.js'); // We're not quite there yet though: // - When developing locally, you may need to set DISCOVERY_PORT (see // getDiscoveryPort below) -// - GALAXY can still be used to override Galaxy discovery, and -// DELPOY_HOSTNAME can still be set to override classic-style +// - DEPLOY_HOSTNAME can still be set to override classic-style // deploys // - The update/warehouse system hasn't been touched and still has its // hardcoded URLs for now (update.meteor.com and diff --git a/tools/tests/logs-mongo-auth.js b/tools/tests/logs-mongo-auth.js index 9ee9fd7ffb..c87a3641b6 100644 --- a/tools/tests/logs-mongo-auth.js +++ b/tools/tests/logs-mongo-auth.js @@ -40,6 +40,9 @@ var logsOrMongoForApp = function (sandbox, command, appName, options) { // I suppose it's possible that we don't have any INFO messages in // the logs, but it seems unlikely. Every time we run a command we // hit /_GALAXY_ on the site. + // XXX This is no longer true now that we've removed legacy Galaxy + // prototype support, so if this causes test flakiness, it may + // need to be tweaked. matchString = 'INFO'; } else { throw new Error('Command must be "logs" or "mongo"'); From 7c40c3c5a664692f86158c5a0d07ca2ed817a613 Mon Sep 17 00:00:00 2001 From: David Glasser Date: Wed, 28 Jan 2015 15:43:57 -0800 Subject: [PATCH 5/8] Remove legacy proxy-binding Also remove SIGHUP handler. This was designed for a legacy system, and SIGHUP would be a better fit for what autoupdate currently uses SIGUSR2 for. This includes removing some code in the ddp server to close sockets on SIGHUP. --- packages/ddp/stream_server.js | 18 -- packages/webapp/package.js | 4 +- packages/webapp/webapp_server.js | 363 ------------------------------- 3 files changed, 1 insertion(+), 384 deletions(-) diff --git a/packages/ddp/stream_server.js b/packages/ddp/stream_server.js index 83dffadb59..e28b4cb331 100644 --- a/packages/ddp/stream_server.js +++ b/packages/ddp/stream_server.js @@ -56,28 +56,10 @@ StreamServer = function () { self.server.installHandlers(Package.webapp.WebApp.httpServer); Package.webapp.WebApp.httpServer.addListener('request', Package.webapp.WebApp._timeoutAdjustmentRequestCallback); - Package.webapp.WebApp.httpServer.on('meteor-closing', function () { - _.each(self.open_sockets, function (socket) { - socket.end(); - }); - }); - // Support the /websocket endpoint self._redirectWebsocketEndpoint(); self.server.on('connection', function (socket) { - - if (Package.webapp.WebAppInternals.usingDdpProxy) { - // If we are behind a DDP proxy, immediately close any sockjs connections - // that are not using websockets; the proxy will terminate sockjs for us, - // so we don't expect to be handling any other transports. - if (socket.protocol !== "websocket" && - socket.protocol !== "websocket-raw") { - socket.close(); - return; - } - } - socket.send = function (data) { socket.write(data); }; diff --git a/packages/webapp/package.js b/packages/webapp/package.js index 3fefda4d42..3e9f66ee5d 100644 --- a/packages/webapp/package.js +++ b/packages/webapp/package.js @@ -16,9 +16,7 @@ Package.onUse(function (api) { api.use(['logging', 'underscore', 'routepolicy', 'boilerplate-generator', 'spacebars', 'htmljs', 'blaze', 'webapp-hashing'], 'server'); api.use(['underscore'], 'client'); - api.use(['application-configuration', 'follower-livedata'], { - unordered: true - }); + // At response serving time, webapp uses browser-policy if it is loaded. If // browser-policy is loaded, then it must be loaded after webapp // (browser-policy depends on webapp). So we don't explicitly depend in any diff --git a/packages/webapp/webapp_server.js b/packages/webapp/webapp_server.js index b5bd652d0e..6d0f18b668 100644 --- a/packages/webapp/webapp_server.js +++ b/packages/webapp/webapp_server.js @@ -701,39 +701,6 @@ var runWebAppServer = function () { httpServer.on('request', WebApp._timeoutAdjustmentRequestCallback); - // For now, handle SIGHUP here. Later, this should be in some centralized - // Meteor shutdown code. - process.on('SIGHUP', Meteor.bindEnvironment(function () { - shuttingDown = true; - // tell others with websockets open that we plan to close this. - // XXX: Eventually, this should be done with a standard meteor shut-down - // logic path. - httpServer.emit('meteor-closing'); - - httpServer.close(Meteor.bindEnvironment(function () { - if (proxy) { - try { - proxy.call('removeBindingsForJob', process.env.GALAXY_JOB); - } catch (e) { - Log.error("Error removing bindings: " + e.message); - process.exit(1); - } - } - process.exit(0); - - }, "On http server close failed")); - - // Ideally we will close before this hits. - Meteor.setTimeout(function () { - Log.warn("Closed by SIGHUP but one or more HTTP requests may not have finished."); - process.exit(1); - }, 5000); - - }, function (err) { - console.log(err); - process.exit(1); - })); - // start up app _.extend(WebApp, { connectHandlers: packageAndAppHandlers, @@ -759,10 +726,6 @@ var runWebAppServer = function () { // middlewares and update __meteor_runtime_config__, then keep going to set up // actually serving HTML. main = function (argv) { - // main happens post startup hooks, so we don't need a Meteor.startup() to - // ensure this happens after the galaxy package is loaded. - var AppConfig = Package["application-configuration"].AppConfig; - WebAppInternals.generateBoilerplate(); // only start listening after all the startup code has run. @@ -772,49 +735,6 @@ var runWebAppServer = function () { httpServer.listen(localPort, localIp, Meteor.bindEnvironment(function() { if (process.env.METEOR_PRINT_ON_LISTEN) console.log("LISTENING"); // must match run-app.js - var proxyBinding; - - AppConfig.configurePackage('webapp', function (configuration) { - if (proxyBinding) - proxyBinding.stop(); - if (configuration && configuration.proxy) { - // TODO: We got rid of the place where this checks the app's - // configuration, because this wants to be configured for some things - // on a per-job basis. Discuss w/ teammates. - proxyBinding = AppConfig.configureService( - "proxy", - "pre0", - function (proxyService) { - if (proxyService && ! _.isEmpty(proxyService)) { - var proxyConf; - // XXX Figure out a per-job way to specify bind location - // (besides hardcoding the location for ADMIN_APP jobs). - if (process.env.ADMIN_APP) { - var bindPathPrefix = ""; - if (process.env.GALAXY_APP !== "panel") { - bindPathPrefix = "/" + bindPathPrefix + - encodeURIComponent( - process.env.GALAXY_APP - ).replace(/\./g, '_'); - } - proxyConf = { - bindHost: process.env.GALAXY_NAME, - bindPathPrefix: bindPathPrefix, - requiresAuth: true - }; - } else { - proxyConf = configuration.proxy; - } - Log("Attempting to bind to proxy at " + - proxyService); - WebAppInternals.bindToProxy(_.extend({ - proxyEndpoint: proxyService - }, proxyConf)); - } - } - ); - } - }); var callbacks = onListeningCallbacks; onListeningCallbacks = null; @@ -830,289 +750,6 @@ var runWebAppServer = function () { }; -var proxy; -WebAppInternals.bindToProxy = function (proxyConfig) { - var securePort = proxyConfig.securePort || 4433; - var insecurePort = proxyConfig.insecurePort || 8080; - var bindPathPrefix = proxyConfig.bindPathPrefix || ""; - // XXX also support galaxy-based lookup - if (!proxyConfig.proxyEndpoint) - throw new Error("missing proxyEndpoint"); - if (!proxyConfig.bindHost) - throw new Error("missing bindHost"); - if (!process.env.GALAXY_JOB) - throw new Error("missing $GALAXY_JOB"); - if (!process.env.GALAXY_APP) - throw new Error("missing $GALAXY_APP"); - if (!process.env.LAST_START) - throw new Error("missing $LAST_START"); - - // XXX rename pid argument to bindTo. - // XXX factor out into a 'getPid' function in a 'galaxy' package? - var pid = { - job: process.env.GALAXY_JOB, - lastStarted: +(process.env.LAST_START), - app: process.env.GALAXY_APP - }; - var myHost = os.hostname(); - - WebAppInternals.usingDdpProxy = true; - - // This is run after packages are loaded (in main) so we can use - // Follower.connect. - if (proxy) { - // XXX the concept here is that our configuration has changed and - // we have connected to an entirely new follower set, which does - // not have the state that we set up on the follower set that we - // were previously connected to, and so we need to recreate all of - // our bindings -- analogous to getting a SIGHUP and rereading - // your configuration file. so probably this should actually tear - // down the connection and make a whole new one, rather than - // hot-reconnecting to a different URL. - proxy.reconnect({ - url: proxyConfig.proxyEndpoint - }); - } else { - proxy = Package["follower-livedata"].Follower.connect( - proxyConfig.proxyEndpoint, { - group: "proxy" - } - ); - } - - var route = process.env.ROUTE; - var ourHost = route.split(":")[0]; - var ourPort = +route.split(":")[1]; - - var outstanding = 0; - var startedAll = false; - var checkComplete = function () { - if (startedAll && ! outstanding) - Log("Bound to proxy."); - }; - var makeCallback = function () { - outstanding++; - return function (err) { - if (err) - throw err; - outstanding--; - checkComplete(); - }; - }; - - // for now, have our (temporary) requiresAuth flag apply to all - // routes created by this process. - var requiresDdpAuth = !! proxyConfig.requiresAuth; - var requiresHttpAuth = (!! proxyConfig.requiresAuth) && - (pid.app !== "panel" && pid.app !== "auth"); - - // XXX a current limitation is that we treat securePort and - // insecurePort as a global configuration parameter -- we assume - // that if the proxy wants us to ask for 8080 to get port 80 traffic - // on our default hostname, that's the same port that we would use - // to get traffic on some other hostname that our proxy listens - // for. Likewise, we assume that if the proxy can receive secure - // traffic for our domain, it can assume secure traffic for any - // domain! Hopefully this will get cleaned up before too long by - // pushing that logic into the proxy service, so we can just ask for - // port 80. - - // XXX BUG: if our configuration changes, and bindPathPrefix - // changes, it appears that we will not remove the routes derived - // from the old bindPathPrefix from the proxy (until the process - // exits). It is not actually normal for bindPathPrefix to change, - // certainly not without a process restart for other reasons, but - // it'd be nice to fix. - - _.each(routes, function (route) { - var parsedUrl = url.parse(route.url, /* parseQueryString */ false, - /* slashesDenoteHost aka workRight */ true); - if (parsedUrl.protocol || parsedUrl.port || parsedUrl.search) - throw new Error("Bad url"); - parsedUrl.host = null; - parsedUrl.path = null; - if (! parsedUrl.hostname) { - parsedUrl.hostname = proxyConfig.bindHost; - if (! parsedUrl.pathname) - parsedUrl.pathname = ""; - if (! parsedUrl.pathname.indexOf("/") !== 0) { - // Relative path - parsedUrl.pathname = bindPathPrefix + parsedUrl.pathname; - } - } - var version = ""; - - var AppConfig = Package["application-configuration"].AppConfig; - version = AppConfig.getStarForThisJob() || ""; - - - var parsedDdpUrl = _.clone(parsedUrl); - parsedDdpUrl.protocol = "ddp"; - // Node has a hardcoded list of protocols that get '://' instead - // of ':'. ddp needs to be added to that whitelist. Until then, we - // can set the undocumented attribute 'slashes' to get the right - // behavior. It's not clear whether than is by design or accident. - parsedDdpUrl.slashes = true; - parsedDdpUrl.port = '' + securePort; - var ddpUrl = url.format(parsedDdpUrl); - - var proxyToHost, proxyToPort, proxyToPathPrefix; - if (! _.has(route, 'forwardTo')) { - proxyToHost = ourHost; - proxyToPort = ourPort; - proxyToPathPrefix = parsedUrl.pathname; - } else { - var parsedFwdUrl = url.parse(route.forwardTo, false, true); - if (! parsedFwdUrl.hostname || parsedFwdUrl.protocol) - throw new Error("Bad forward url"); - proxyToHost = parsedFwdUrl.hostname; - proxyToPort = parseInt(parsedFwdUrl.port || "80"); - proxyToPathPrefix = parsedFwdUrl.pathname || ""; - } - - if (route.ddp) { - proxy.call('bindDdp', { - pid: pid, - bindTo: { - ddpUrl: ddpUrl, - insecurePort: insecurePort - }, - proxyTo: { - tags: [version], - host: proxyToHost, - port: proxyToPort, - pathPrefix: proxyToPathPrefix + '/websocket' - }, - requiresAuth: requiresDdpAuth - }, makeCallback()); - } - - if (route.http) { - proxy.call('bindHttp', { - pid: pid, - bindTo: { - host: parsedUrl.hostname, - port: insecurePort, - pathPrefix: parsedUrl.pathname - }, - proxyTo: { - tags: [version], - host: proxyToHost, - port: proxyToPort, - pathPrefix: proxyToPathPrefix - }, - requiresAuth: requiresHttpAuth - }, makeCallback()); - - // Only make the secure binding if we've been told that the - // proxy knows how terminate secure connections for us (has an - // appropriate cert, can bind the necessary port..) - if (proxyConfig.securePort !== null) { - proxy.call('bindHttp', { - pid: pid, - bindTo: { - host: parsedUrl.hostname, - port: securePort, - pathPrefix: parsedUrl.pathname, - ssl: true - }, - proxyTo: { - tags: [version], - host: proxyToHost, - port: proxyToPort, - pathPrefix: proxyToPathPrefix - }, - requiresAuth: requiresHttpAuth - }, makeCallback()); - } - } - }); - - startedAll = true; - checkComplete(); -}; - -// (Internal, unsupported interface -- subject to change) -// -// Listen for HTTP and/or DDP traffic and route it somewhere. Only -// takes effect when using a proxy service. -// -// 'url' is the traffic that we want to route, interpreted relative to -// the default URL where this app has been told to serve itself. It -// may not have a scheme or port, but it may have a host and a path, -// and if no host is provided the path need not be absolute. The -// following cases are possible: -// -// //somehost.com -// All incoming traffic for 'somehost.com' -// //somehost.com/foo/bar -// All incoming traffic for 'somehost.com', but only when -// the first two path components are 'foo' and 'bar'. -// /foo/bar -// Incoming traffic on our default host, but only when the -// first two path components are 'foo' and 'bar'. -// foo/bar -// Incoming traffic on our default host, but only when the path -// starts with our default path prefix, followed by 'foo' and -// 'bar'. -// -// (Yes, these scheme-less URLs that start with '//' are legal URLs.) -// -// You can select either DDP traffic, HTTP traffic, or both. Both -// secure and insecure traffic will be gathered (assuming the proxy -// service is capable, eg, has appropriate certs and port mappings). -// -// With no 'forwardTo' option, the traffic is received by this process -// for service by the hooks in this 'webapp' package. The original URL -// is preserved (that is, if you bind "/a", and a user visits "/a/b", -// the app receives a request with a path of "/a/b", not a path of -// "/b"). -// -// With 'forwardTo', the process is instead sent to some other remote -// host. The URL is adjusted by stripping the path components in 'url' -// and putting the path components in the 'forwardTo' URL in their -// place. For example, if you forward "//somehost/a" to -// "//otherhost/x", and the user types "//somehost/a/b" into their -// browser, then otherhost will receive a request with a Host header -// of "somehost" and a path of "/x/b". -// -// The routing continues until this process exits. For now, all of the -// routes must be set up ahead of time, before the initial -// registration with the proxy. Calling addRoute from the top level of -// your JS should do the trick. -// -// When multiple routes are present that match a given request, the -// most specific route wins. When routes with equal specificity are -// present, the proxy service will distribute the traffic between -// them. -// -// options may be: -// - ddp: if true, the default, include DDP traffic. This includes -// both secure and insecure traffic, and both websocket and sockjs -// transports. -// - http: if true, the default, include HTTP/HTTPS traffic. -// - forwardTo: if provided, should be a URL with a host, optional -// path and port, and no scheme (the scheme will be derived from the -// traffic type; for now it will always be a http or ws connection, -// never https or wss, but we could add a forwardSecure flag to -// re-encrypt). -var routes = []; -WebAppInternals.addRoute = function (url, options) { - options = _.extend({ - ddp: true, - http: true - }, options || {}); - - if (proxy) - // In the future, lift this restriction - throw new Error("Too late to add routes"); - - routes.push(_.extend({ url: url }, options)); -}; - -// Receive traffic on our default URL. -WebAppInternals.addRoute(""); - runWebAppServer(); From 5990e71ddc0872756689ec51818002c98093a629 Mon Sep 17 00:00:00 2001 From: David Glasser Date: Wed, 28 Jan 2015 16:00:46 -0800 Subject: [PATCH 6/8] Remove legacy AppConfig code Nothing ever made full use of the promise of the complexity of the API (configuration that can change at runtime) anyway. This includes completely ignoring the $APP_CONFIG variable. I opened GitHub issues against the only Atmosphere packages that had dependencies on application-configuration (none of which actually used the package other than by declaring the dependency). --- docs/client/full-api/api/packagejs.md | 4 +- packages/application-configuration/.gitignore | 2 - packages/application-configuration/README.md | 4 - packages/application-configuration/config.js | 200 ------------------ packages/application-configuration/package.js | 13 -- packages/email/email.js | 31 +-- packages/email/package.js | 1 - packages/meteor/server_environment.js | 21 +- packages/mongo/package.js | 2 +- packages/mongo/remote_collection_driver.js | 14 +- 10 files changed, 16 insertions(+), 276 deletions(-) delete mode 100644 packages/application-configuration/.gitignore delete mode 100644 packages/application-configuration/README.md delete mode 100644 packages/application-configuration/config.js delete mode 100644 packages/application-configuration/package.js diff --git a/docs/client/full-api/api/packagejs.md b/docs/client/full-api/api/packagejs.md index 017d70b08a..c3cd2eeb01 100644 --- a/docs/client/full-api/api/packagejs.md +++ b/docs/client/full-api/api/packagejs.md @@ -31,8 +31,8 @@ rest of this section will explain the specific API commands in greater detail. // Use Underscore package, but only on the server. // Version not specified, so it will be as of Meteor 0.9.0. api.use('underscore', 'server'); - // Use application-configuration package, version 1.0.0 or newer. - api.use('application-configuration@1.0.0'); + // Use iron:router package, version 1.0.0 or newer. + api.use('iron:router@1.0.0'); // Give users of this package access to the Templating package. api.imply('templating') // Export the object 'Email' to packages or apps that use this package. diff --git a/packages/application-configuration/.gitignore b/packages/application-configuration/.gitignore deleted file mode 100644 index 5e677eb9b5..0000000000 --- a/packages/application-configuration/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.build -.build* diff --git a/packages/application-configuration/README.md b/packages/application-configuration/README.md deleted file mode 100644 index 79021c6882..0000000000 --- a/packages/application-configuration/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Application-Configuration - -This was an internal Meteor package used for interacting with internal prototype -systems that no longer exist. diff --git a/packages/application-configuration/config.js b/packages/application-configuration/config.js deleted file mode 100644 index 64b5f36091..0000000000 --- a/packages/application-configuration/config.js +++ /dev/null @@ -1,200 +0,0 @@ -var Future = Npm.require("fibers/future"); - -AppConfig = {}; - - -AppConfig.findGalaxy = _.once(function () { - if (!('GALAXY' in process.env || 'ULTRAWORLD_DDP_ENDPOINT' in process.env)) { - return null; - } - return Follower.connect(process.env.ULTRAWORLD_DDP_ENDPOINT || process.env.GALAXY); -}); - -var ultra = AppConfig.findGalaxy(); - -var subFuture = new Future(); -var subFutureJobs = new Future(); -if (ultra) { - ultra.subscribe("oneApp", process.env.GALAXY_APP, subFuture.resolver()); - ultra.subscribe("oneJob", process.env.GALAXY_JOB, subFutureJobs.resolver()); -} - -var Apps; -var Jobs; -var Services; -var collectionFuture = new Future(); - -Meteor.startup(function () { - var Mongo = Package.mongo.Mongo; - if (ultra) { - Apps = new Mongo.Collection("apps", { - connection: ultra - }); - Jobs = new Mongo.Collection("jobs", { - connection: ultra - }); - Services = new Mongo.Collection('services', { - connection: ultra - }); - // allow us to block on the collections being ready - collectionFuture.return(); - } -}); - -// XXX: Remove this once we allow the same collection to be new'd from multiple -// places. -AppConfig._getAppCollection = function () { - collectionFuture.wait(); - return Apps; -}; - -AppConfig._getJobsCollection = function () { - collectionFuture.wait(); - return Jobs; -}; - - -var staticAppConfig; - -try { - if (process.env.APP_CONFIG) { - staticAppConfig = JSON.parse(process.env.APP_CONFIG); - } else { - var settings; - try { - if (process.env.METEOR_SETTINGS) { - settings = JSON.parse(process.env.METEOR_SETTINGS); - } - } catch (e) { - Log.warn("Could not parse METEOR_SETTINGS as JSON"); - } - staticAppConfig = { - settings: settings, - packages: { - 'mongo-livedata': { - url: process.env.MONGO_URL, - oplog: process.env.MONGO_OPLOG_URL - } - } - }; - } -} catch (e) { - Log.warn("Could not parse initial APP_CONFIG environment variable"); -}; - -AppConfig.getAppConfig = function () { - if (!subFuture.isResolved() && staticAppConfig) { - return staticAppConfig; - } - subFuture.wait(); - var myApp = Apps.findOne(process.env.GALAXY_APP); - if (!myApp) { - throw new Error("there is no app config for this app"); - } - var config = myApp.config; - return config; -}; - -AppConfig.getStarForThisJob = function () { - if (ultra) { - subFutureJobs.wait(); - var job = Jobs.findOne(process.env.GALAXY_JOB); - if (job) { - return job.star; - } - } - return null; -}; - -AppConfig.configurePackage = function (packageName, configure) { - var appConfig = AppConfig.getAppConfig(); // Will either be based in the env var, - // or wait for galaxy to connect. - var lastConfig = - (appConfig && appConfig.packages && - appConfig.packages[packageName]) || {}; - - // Always call the configure callback "soon" even if the initial configuration - // is empty (synchronously, though deferred would be OK). - // XXX make sure that all callers of configurePackage deal well with multiple - // callback invocations! eg, email does not - configure(lastConfig); - var configureIfDifferent = function (app) { - if (!EJSON.equals( - app.config && app.config.packages && app.config.packages[packageName], - lastConfig)) { - lastConfig = app.config.packages[packageName]; - configure(lastConfig); - } - }; - var subHandle; - var observed = new Future(); - - // This is not required to finish, so defer it so it doesn't block anything - // else. - Meteor.defer( function () { - // there's a Meteor.startup() that produces the various collections, make - // sure it runs first before we continue. - collectionFuture.wait(); - subHandle = Apps.find(process.env.GALAXY_APP).observe({ - added: configureIfDifferent, - changed: configureIfDifferent - }); - observed.return(); - }); - - return { - stop: function () { - observed.wait(); - subHandle.stop(); - } - }; -}; - -AppConfig.configureService = function (serviceName, version, configure) { - - // Collect all the endpoints for this service, from both old- and new-format - // documents, and call the `configure` callback with all the service endpoints - // that we know about. - var callConfigure = function (doc) { - var serviceDocs = Services.find({ - name: serviceName, - version: version - }); - var endpoints = []; - serviceDocs.forEach(function (serviceDoc) { - if (serviceDoc.providers) { - _.each(serviceDoc.providers, function (endpoint, app) { - endpoints.push(endpoint); - }); - } else { - endpoints.push(serviceDoc.endpoint); - } - }); - configure(endpoints); - }; - - if (ultra) { - // there's a Meteor.startup() that produces the various collections, make - // sure it runs first before we continue. - collectionFuture.wait(); - // First try to subscribe to the new format service registrations; if that - // sub doesn't exist, then ultraworld hasn't updated to the new format yet, - // so try the old format `servicesByName` sub instead. - ultra.subscribe('services', serviceName, version, { - onError: function (err) { - if (err.error === 404) { - ultra.subscribe('servicesByName', serviceName); - } - } - }); - return Services.find({ - name: serviceName, - version: version - }).observe({ - added: callConfigure, - changed: callConfigure, - removed: callConfigure - }); - } - -}; diff --git a/packages/application-configuration/package.js b/packages/application-configuration/package.js deleted file mode 100644 index f5fd5cafba..0000000000 --- a/packages/application-configuration/package.js +++ /dev/null @@ -1,13 +0,0 @@ -Package.describe({ - summary: "Interaction with the configuration sources for your apps", - version: '1.0.4' -}); - -Package.onUse(function (api) { - api.use(['logging', 'underscore', 'ddp', 'ejson', 'follower-livedata']); - api.use(['mongo'], { - unordered: true - }); - api.addFiles(['config.js'], 'server'); - api.export('AppConfig', 'server'); -}); diff --git a/packages/email/email.js b/packages/email/email.js index 033a187ecf..34da903903 100644 --- a/packages/email/email.js +++ b/packages/email/email.js @@ -31,29 +31,14 @@ var makePool = function (mailUrlString) { return pool; }; -// We construct smtpPool at the first call to Email.send, so that -// Meteor.startup code can set $MAIL_URL. -var smtpPoolFuture = new Future;; -var configured = false; - -var getPool = function () { - // We check MAIL_URL in case someone else set it in Meteor.startup code. - if (!configured) { - configured = true; - AppConfig.configurePackage('email', function (config) { - // XXX allow reconfiguration when the app config changes - if (smtpPoolFuture.isResolved()) - return; - var url = config.url || process.env.MAIL_URL; - var pool = null; - if (url) - pool = makePool(url); - smtpPoolFuture.return(pool); - }); - } - - return smtpPoolFuture.wait(); -}; +var getPool = _.once(function () { + // We delay this check until the first call to Email.send, in case someone + // set process.env.MAIL_URL in startup code. + var url = process.env.MAIL_URL; + if (! url) + return null; + return makePool(url); +}); var next_devmode_mail_id = 0; var output_stream = process.stdout; diff --git a/packages/email/package.js b/packages/email/package.js index b7a015fd3c..986ddab994 100644 --- a/packages/email/package.js +++ b/packages/email/package.js @@ -12,7 +12,6 @@ Npm.depends({ Package.onUse(function (api) { api.use('underscore', 'server'); - api.use('application-configuration'); api.export('Email', 'server'); api.export('EmailTest', 'server', {testOnly: true}); api.addFiles('email.js', 'server'); diff --git a/packages/meteor/server_environment.js b/packages/meteor/server_environment.js index 4f9dea89d9..8c950318f7 100644 --- a/packages/meteor/server_environment.js +++ b/packages/meteor/server_environment.js @@ -5,26 +5,7 @@ Meteor = { Meteor.settings = {}; -if (process.env.APP_CONFIG) { - // put settings from the app configuration in the settings. Don't depend on - // the Galaxy package for now, to avoid silly loops. - try { - var appConfig = JSON.parse(process.env.APP_CONFIG); - if (!appConfig.settings) { - Meteor.settings = {}; - } else if (typeof appConfig.settings === "string") { - Meteor.settings = JSON.parse(appConfig.settings); - } else { - // Old versions of Galaxy may store settings in MongoDB as objects. Newer - // versions store it as strings (so that we aren't restricted to - // MongoDB-compatible objects). This line makes it work on older Galaxies. - // XXX delete this eventually - Meteor.settings = appConfig.settings; - } - } catch (e) { - throw new Error("Settings from APP_CONFIG are not valid JSON: " + process.env.APP_CONFIG); - } -} else if (process.env.METEOR_SETTINGS) { +if (process.env.METEOR_SETTINGS) { try { Meteor.settings = JSON.parse(process.env.METEOR_SETTINGS); } catch (e) { diff --git a/packages/mongo/package.js b/packages/mongo/package.js index 7f65bb1522..ac74465298 100644 --- a/packages/mongo/package.js +++ b/packages/mongo/package.js @@ -22,7 +22,7 @@ Npm.strip({ Package.onUse(function (api) { api.use(['random', 'ejson', 'json', 'underscore', 'minimongo', 'logging', - 'ddp', 'tracker', 'application-configuration'], + 'ddp', 'tracker'], ['client', 'server']); api.use('check', ['client', 'server']); diff --git a/packages/mongo/remote_collection_driver.js b/packages/mongo/remote_collection_driver.js index 259a5e3fce..fea53c42bc 100644 --- a/packages/mongo/remote_collection_driver.js +++ b/packages/mongo/remote_collection_driver.js @@ -24,22 +24,16 @@ _.extend(MongoInternals.RemoteCollectionDriver.prototype, { // only require Mongo configuration if it's actually used (eg, not if // you're only trying to receive data from a remote DDP server.) MongoInternals.defaultRemoteCollectionDriver = _.once(function () { - var mongoUrl; var connectionOptions = {}; - AppConfig.configurePackage("mongo-livedata", function (config) { - // This will keep running if mongo gets reconfigured. That's not ideal, but - // should be ok for now. - mongoUrl = config.url; + var mongoUrl = process.env.MONGO_URL; - if (config.oplog) - connectionOptions.oplogUrl = config.oplog; - }); + if (process.env.MONGO_OPLOG_URL) { + connectionOptions.oplogUrl = process.env.MONGO_OPLOG_URL; + } - // XXX bad error since it could also be set directly in METEOR_DEPLOY_CONFIG if (! mongoUrl) throw new Error("MONGO_URL must be set in environment"); - return new MongoInternals.RemoteCollectionDriver(mongoUrl, connectionOptions); }); From aff7f37d04e635ca16c3b1c8d04885f2d64d835c Mon Sep 17 00:00:00 2001 From: David Glasser Date: Wed, 28 Jan 2015 16:03:16 -0800 Subject: [PATCH 7/8] Remove legacy follower-livedata package --- packages/follower-livedata/.gitignore | 1 - packages/follower-livedata/README.md | 2 - packages/follower-livedata/follower.js | 244 ------------------------- packages/follower-livedata/package.js | 10 - 4 files changed, 257 deletions(-) delete mode 100644 packages/follower-livedata/.gitignore delete mode 100644 packages/follower-livedata/README.md delete mode 100644 packages/follower-livedata/follower.js delete mode 100644 packages/follower-livedata/package.js diff --git a/packages/follower-livedata/.gitignore b/packages/follower-livedata/.gitignore deleted file mode 100644 index 677a6fc263..0000000000 --- a/packages/follower-livedata/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.build* diff --git a/packages/follower-livedata/README.md b/packages/follower-livedata/README.md deleted file mode 100644 index 9b1b1619cc..0000000000 --- a/packages/follower-livedata/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This was an internal Meteor package used for interacting with internal prototype -systems that no longer exist. diff --git a/packages/follower-livedata/follower.js b/packages/follower-livedata/follower.js deleted file mode 100644 index 1e8f4b2b61..0000000000 --- a/packages/follower-livedata/follower.js +++ /dev/null @@ -1,244 +0,0 @@ -var fs = Npm.require('fs'); -var Future = Npm.require('fibers/future'); - - -var MONITOR_INTERVAL = 5*1000; // every 5 seconds - -/** - * Follower.connect() replaces DDP.connect() for connecting to DDP services that - * implement a leadership set. The follower connection tries to keep connected - * to the leader, and fails over as the leader changes. - * - * Options: { - * group: The name of the leadership group to connect to. Default "package.leadershipLivedata" - * } - * - * A Follower connection implements the following interfaces over and above a - * normal DDP connection: - * - * onLost(callback): calls callback when the library considers itself to have - * tried all its known options for the leadership group. - * - * onFound(callback): Called when the follower was previously lost, but has now - * successfully connected to something in the right leadership group. - */ -Follower = { - connect: function (urlSet, options) { - var electorTries; - options = _.extend({ - group: "package.leadershipLivedata" - }, options); - // start each elector as untried/assumed connectable. - - var makeElectorTries = function (urlSet) { - - electorTries = {}; - if (typeof urlSet === 'string') { - urlSet = _.map(urlSet.split(','), function (url) {return url.trim();}); - } - _.each(urlSet, function (url) { - electorTries[url] = 0; - }); - }; - - makeElectorTries(urlSet); - - var tryingUrl = null; - var outstandingGetElectorate = false; - var conn = null; - var prevReconnect = null; - var prevDisconnect = null; - var prevApply = null; - var leader = null; - var connectedTo = null; - var intervalHandle = null; - - - // Used to defer all method calls until we're sure that we connected to the - // right leadership group. - var connectedToLeadershipGroup = new Future(); - - var lost = false; - var lostCallbacks = []; - var foundCallbacks = []; - - var findFewestTries = function () { - var min = 10000; - var minElector = null; - _.each(electorTries, function (tries, elector) { - if (tries < min) { - min = tries; - minElector = elector; - } - }); - if (min > 1 && !lost) { - // we've tried everything once; we just became lost. - lost = true; - _.each(lostCallbacks, function (f) { f(); }); - } - return minElector; - }; - - var updateElectorate = function (res) { - leader = res.leader; - electorTries = {}; - _.each(res.electorate, function (elector) { - electorTries[elector] = 0; // verified that this is in the current elector set. - }); - }; - - var tryElector = function (url) { - if (tryingUrl) { - electorTries[tryingUrl]++; - } - url = url || findFewestTries(); - //console.log("trying", url, electorTries, tryingUrl, process.env.GALAXY_JOB); - - // Don't keep trying the same url as fast as we can if it's not working. - if (electorTries[url] > 2) { - Meteor._sleepForMs(3 * 1000); - } - - if (conn) { - prevReconnect.apply(conn, [{ - url: url - }]); - } else { - conn = DDP.connect(url, options); - prevReconnect = conn.reconnect; - prevDisconnect = conn.disconnect; - prevApply = conn.apply; - } - tryingUrl = url; - - if (!outstandingGetElectorate) { - outstandingGetElectorate = true; - conn.call('getElectorate', options.group, function (err, res) { - outstandingGetElectorate = false; - connectedTo = tryingUrl; - if (err) { - tryElector(); - return; - } - if (!_.contains(res.electorate, connectedTo)) { - Log.warn("electorate " + res.electorate + " does not contain " + connectedTo); - } - tryingUrl = null; - if (! connectedToLeadershipGroup.isResolved()) { - connectedToLeadershipGroup["return"](); - } - // we got an answer! Connected! - electorTries[url] = 0; - - if (res.leader === connectedTo) { - // we're good. - if (lost) { - // we're found. - lost = false; - _.each(foundCallbacks, function (f) { f(); }); - } - } else { - // let's connect to the leader anyway, if we think it - // is connectable. - if (electorTries[res.leader] == 0) { - tryElector(res.leader); - } else { - // XXX: leader is probably down, we're probably going to elect - // soon. Wait for the next round. - } - - } - updateElectorate(res); - }); - } - - }; - - tryElector(); - - var checkConnection = function () { - if (conn.status().status !== 'connected' || connectedTo !== leader) { - tryElector(); - } else { - conn.call('getElectorate', options.group, function (err, res) { - if (err) { - electorTries[connectedTo]++; - tryElector(); - } else if (res.leader !== leader) { - // update the electorate, and then definitely try to connect to the leader. - updateElectorate(res); - tryElector(res.leader); - } else { - if (! connectedToLeadershipGroup.isResolved()) { - connectedToLeadershipGroup["return"](); - } - //console.log("updating electorate with", res); - updateElectorate(res); - } - }); - } - }; - - var monitorConnection = function () { - return Meteor.setInterval(checkConnection, MONITOR_INTERVAL); - }; - - intervalHandle = monitorConnection(); - - conn.disconnect = function () { - if (intervalHandle) - Meteor.clearInterval(intervalHandle); - intervalHandle = null; - prevDisconnect.apply(conn); - }; - - conn.reconnect = function () { - if (!intervalHandle) - intervalHandle = monitorConnection(); - if (arguments[0] && arguments[0].url) { - makeElectorTries(arguments[0].url); - tryElector(); - } else { - prevReconnect.apply(conn, arguments); - } - }; - - conn.getUrl = function () { - return _.keys(electorTries).join(','); - }; - - conn.tries = function () { - return electorTries; - }; - - - // Assumes that `call` is implemented in terms of `apply`. All method calls - // should be deferred until we are sure we've connected to the right - // leadership group. - conn.apply = function (/* arguments */) { - var args = _.toArray(arguments); - if (typeof args[args.length-1] === 'function') { - // this needs to be independent of this fiber if there is a callback. - Meteor.defer(function () { - connectedToLeadershipGroup.wait(); - return prevApply.apply(conn, args); - }); - return null; // if there is a callback, the return value is not used - } else { - connectedToLeadershipGroup.wait(); - return prevApply.apply(conn, args); - } - }; - - conn.onLost = function (callback) { - lostCallbacks.push(callback); - }; - - conn.onFound = function (callback) { - foundCallbacks.push(callback); - }; - - return conn; - } - -}; diff --git a/packages/follower-livedata/package.js b/packages/follower-livedata/package.js deleted file mode 100644 index bf1a33f50e..0000000000 --- a/packages/follower-livedata/package.js +++ /dev/null @@ -1,10 +0,0 @@ -Package.describe({ - summary: "Maintain a connection to the leader of an election set", - version: '1.0.3' -}); - -Package.onUse(function (api) { - api.use(['logging', 'underscore', 'ddp', 'ejson']); - api.addFiles(['follower.js'], 'server'); - api.export('Follower'); -}); From 299f4136175476e1a7ec1d6f7b7a5dd1eebed234 Mon Sep 17 00:00:00 2001 From: David Glasser Date: Wed, 28 Jan 2015 16:28:58 -0800 Subject: [PATCH 8/8] Remove support code for legacy systems Summary: What I'm looking for here is: attention to the few parts that aren't just deletions (eg in auth.js), and thoughts about if removing any of these things might break systems I haven't thought about. Test Plan: test-packages, self-test (which mostly passes) Reviewers: ekatek Differential Revision: https://phabricator.meteor.io/D18 --- meteor | 1 - packages/dev-bundle-fetcher/.gitignore | 1 - packages/dev-bundle-fetcher/README.md | 2 - packages/dev-bundle-fetcher/dev-bundle | 78 ------------ packages/dev-bundle-fetcher/dev-bundle.js | 5 - packages/dev-bundle-fetcher/package.js | 9 -- packages/star-translate/.gitignore | 1 - .../star-translate/.npm/package/.gitignore | 1 - packages/star-translate/.npm/package/README | 7 -- .../.npm/package/npm-shrinkwrap.json | 7 -- packages/star-translate/README.md | 2 - packages/star-translate/package.js | 12 -- packages/star-translate/translator.js | 112 ------------------ tools/bundler.js | 24 +--- tools/compiler.js | 4 +- tools/isopackets.js | 1 - 16 files changed, 6 insertions(+), 261 deletions(-) delete mode 100644 packages/dev-bundle-fetcher/.gitignore delete mode 100644 packages/dev-bundle-fetcher/README.md delete mode 100644 packages/dev-bundle-fetcher/dev-bundle delete mode 100644 packages/dev-bundle-fetcher/dev-bundle.js delete mode 100644 packages/dev-bundle-fetcher/package.js delete mode 100644 packages/star-translate/.gitignore delete mode 100644 packages/star-translate/.npm/package/.gitignore delete mode 100644 packages/star-translate/.npm/package/README delete mode 100644 packages/star-translate/.npm/package/npm-shrinkwrap.json delete mode 100644 packages/star-translate/README.md delete mode 100644 packages/star-translate/package.js delete mode 100644 packages/star-translate/translator.js diff --git a/meteor b/meteor index 141d16d314..0d8b04a8b9 100755 --- a/meteor +++ b/meteor @@ -60,7 +60,6 @@ function install_dev_bundle { rm -rf "$BUNDLE_TMPDIR" mkdir "$BUNDLE_TMPDIR" - # fyi: URL duplicated in packages/dev-bundle-fetcher/dev-bundle DEV_BUNDLE_URL_ROOT="https://d3sqy0vbqsdhku.cloudfront.net/" # If you set $USE_TEST_DEV_BUNDLE_SERVER then we will download # dev bundles copied by copy-dev-bundle-from-jenkins.sh without --prod. diff --git a/packages/dev-bundle-fetcher/.gitignore b/packages/dev-bundle-fetcher/.gitignore deleted file mode 100644 index 677a6fc263..0000000000 --- a/packages/dev-bundle-fetcher/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.build* diff --git a/packages/dev-bundle-fetcher/README.md b/packages/dev-bundle-fetcher/README.md deleted file mode 100644 index 9b1b1619cc..0000000000 --- a/packages/dev-bundle-fetcher/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This was an internal Meteor package used for interacting with internal prototype -systems that no longer exist. diff --git a/packages/dev-bundle-fetcher/dev-bundle b/packages/dev-bundle-fetcher/dev-bundle deleted file mode 100644 index b167113969..0000000000 --- a/packages/dev-bundle-fetcher/dev-bundle +++ /dev/null @@ -1,78 +0,0 @@ -set -e -trap "echo Failed to fetch binary dependencies." EXIT - -if [ -z "$DATA_DIR" ]; then - echo "Please set DATA_DIR to a writeable directory." - exit 1 -fi - -cd `dirname $0` - -# Duplicated from scripts/admin/launch-meteor, except that we hardcode the path -# to sysctl. (When satellite spawns ultraworld, ultraworld doesn't have a PATH -# and so can't find sysctl itself.) -UNAME=$(uname) -if [ "$UNAME" != "Linux" -a "$UNAME" != "Darwin" ] ; then - echo "Sorry, this OS is not supported yet." 1>&2 - exit 1 -fi - -# If you change this, also change host() in tools/archinfo.js -if [ "$UNAME" = "Darwin" ] ; then - if [ "i386" != "$(uname -p)" -o "1" != "$(/usr/sbin/sysctl -n hw.cpu64bit_capable 2>/dev/null || echo 0)" ] ; then - # Can't just test uname -m = x86_64, because Snow Leopard can - # return other values. - echo "Only 64-bit Intel processors are supported at this time." 1>&2 - exit 1 - fi - ARCH="x86_64" -elif [ "$UNAME" = "Linux" ] ; then - ARCH="$(uname -m)" - if [ "$ARCH" != "i686" -a "$ARCH" != "x86_64" ] ; then - echo "Unsupported architecture: $ARCH" 1>&2 - echo "Meteor only supports i686 and x86_64 for now." 1>&2 - exit 1 - fi -fi -PLATFORM="${UNAME}_${ARCH}" - - -# XXX don't hardcode linux :) -TARBALL="dev_bundle_${PLATFORM}_##BUNDLE_VERSION##.tar.gz" -BUNDLE_TMPDIR="$DATA_DIR/dependencies.fetch" - -rm -rf "$BUNDLE_TMPDIR" -mkdir "$BUNDLE_TMPDIR" - -# Cache dev bundles in /tmp. -# XXX something more secure is needed in production -CACHED_TARBALL="/tmp/$TARBALL" -if [ ! -r "$CACHED_TARBALL" ]; then - # Duplicated from 'meteor' script in root of repository - TEMP_TARBALL="${CACHED_TARBALL}.tmp.${RANDOM}" - curl -s "https://d3sqy0vbqsdhku.cloudfront.net/$TARBALL" >"$TEMP_TARBALL" - mv "$TEMP_TARBALL" "$CACHED_TARBALL" -fi -tar -xzf "$CACHED_TARBALL" -C "$BUNDLE_TMPDIR" - -# Delete old dev bundle and rename the new one on top of it. -# XXX probably we can just trust that dependencies from last time are good -DEPS_DIR="$DATA_DIR/dependencies" -rm -rf "$DEPS_DIR" -mv "$BUNDLE_TMPDIR" "$DEPS_DIR" - -trap - EXIT -set +e - -# If there are global node_modules in the bundle, remove them, since -# they override NODE_PATH. Why are these present? Well, 'meteor -# bundle' historically embeds them to give you a self-contained -# bundle. But that never worked very well, because you'd get the -# version for the arch you built on, and you'd have to manually -# rebuild the binary modules (node-fibers) on the target system. It is -# not ideal to have the bundle modify itself (much better for it to be -# immutable) but it'll do for now. -rm -rf node_modules 2>/dev/null || true - -export NODE_PATH="$DEPS_DIR/lib/node_modules" -exec "$DEPS_DIR/bin/node" ##RUN_FILE## ##IMAGE## "$@" diff --git a/packages/dev-bundle-fetcher/dev-bundle.js b/packages/dev-bundle-fetcher/dev-bundle.js deleted file mode 100644 index 486dadc741..0000000000 --- a/packages/dev-bundle-fetcher/dev-bundle.js +++ /dev/null @@ -1,5 +0,0 @@ -DevBundleFetcher = { - script: function () { - return Assets.getText("dev-bundle"); - } -}; diff --git a/packages/dev-bundle-fetcher/package.js b/packages/dev-bundle-fetcher/package.js deleted file mode 100644 index b720ccf5d5..0000000000 --- a/packages/dev-bundle-fetcher/package.js +++ /dev/null @@ -1,9 +0,0 @@ -Package.describe({ - summary: "A shell script for downloading the Meteor dev bundle", - version: "1.0.2" -}); - -Package.onUse(function (api) { - api.export('DevBundleFetcher', 'server'); - api.addFiles(['dev-bundle', 'dev-bundle.js'], ['server']); -}); diff --git a/packages/star-translate/.gitignore b/packages/star-translate/.gitignore deleted file mode 100644 index 677a6fc263..0000000000 --- a/packages/star-translate/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.build* diff --git a/packages/star-translate/.npm/package/.gitignore b/packages/star-translate/.npm/package/.gitignore deleted file mode 100644 index 3c3629e647..0000000000 --- a/packages/star-translate/.npm/package/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/packages/star-translate/.npm/package/README b/packages/star-translate/.npm/package/README deleted file mode 100644 index 3d492553a4..0000000000 --- a/packages/star-translate/.npm/package/README +++ /dev/null @@ -1,7 +0,0 @@ -This directory and the files immediately inside it are automatically generated -when you change this package's NPM dependencies. Commit the files in this -directory (npm-shrinkwrap.json, .gitignore, and this README) to source control -so that others run the same versions of sub-dependencies. - -You should NOT check in the node_modules directory that Meteor automatically -creates; if you are using git, the .gitignore file tells git to ignore it. diff --git a/packages/star-translate/.npm/package/npm-shrinkwrap.json b/packages/star-translate/.npm/package/npm-shrinkwrap.json deleted file mode 100644 index 070620ecc8..0000000000 --- a/packages/star-translate/.npm/package/npm-shrinkwrap.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "dependencies": { - "ncp": { - "version": "0.4.2" - } - } -} diff --git a/packages/star-translate/README.md b/packages/star-translate/README.md deleted file mode 100644 index 9b1b1619cc..0000000000 --- a/packages/star-translate/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This was an internal Meteor package used for interacting with internal prototype -systems that no longer exist. diff --git a/packages/star-translate/package.js b/packages/star-translate/package.js deleted file mode 100644 index 5ef91c52f8..0000000000 --- a/packages/star-translate/package.js +++ /dev/null @@ -1,12 +0,0 @@ -Package.describe({ - summary: "A package for translating old bundles into stars", - version: "1.0.5" -}); - -Package.onUse(function (api) { - api.use(['dev-bundle-fetcher']); - api.export('StarTranslator'); - api.addFiles(['translator.js'], 'server'); -}); - -Npm.depends({ncp: "0.4.2"}); diff --git a/packages/star-translate/translator.js b/packages/star-translate/translator.js deleted file mode 100644 index 24150d0c79..0000000000 --- a/packages/star-translate/translator.js +++ /dev/null @@ -1,112 +0,0 @@ -var fs = Npm.require('fs'); -var path = Npm.require('path'); -var ncp = Npm.require('ncp').ncp; - -StarTranslator = {}; - -// Produces a star version of bundlePath in translatedPath, where bundlePath can -// point to either an old Meteor bundle or a star. Returns the star's manifest. -// bundlePath can equal translatedPath, in which case bundlePath is converted -// directly into a star. -StarTranslator.maybeTranslate = function (bundlePath, translatedPath) { - var self = this; - if (path.resolve(bundlePath) !== path.resolve(translatedPath)) { - var _ncp = Meteor.wrapAsync(ncp); - _ncp(bundlePath, translatedPath); - } - - try { - // If the directory contains a star.json file with JSON inside it, then we - // consider it a star. Otherwise we translate it into a star. - var manifest = JSON.parse(fs.readFileSync(path.join(translatedPath, - "star.json"), - 'utf8')); - return manifest; - } catch (e) { - return self._translate(translatedPath); - } -}; - -StarTranslator._translate = function (bundlePath) { - var self = this; - var clientProgPath = path.join(bundlePath, 'client.json'); - var serverProgPath = path.join(bundlePath, 'server.sh'); - var starPath = path.join(bundlePath, 'star.json'); - - // Format defined in meteor/tools/bundler.js - var manifest = { - "format": "site-archive-pre1", - "builtBy": "Star translator", - "programs": [ - { - "name": "web.browser", - "arch": "web.browser", - "path": "client.json" - }, - { - "name": "server", - "arch": self._getArch(), - "path": "server.sh" - } - ] - }; - - self._writeServerProg(bundlePath, serverProgPath); - self._writeClientProg(bundlePath, clientProgPath); - - fs.writeFileSync(starPath, JSON.stringify(manifest, null, 2)); - return manifest; -}; - -StarTranslator._writeServerProg = function (bundlePath, serverProgPath) { - var platform = this._getPlatform(); - var bundleVersion = this._getBundleVersion(bundlePath); - var runFile = 'main.js'; - var serverScript = DevBundleFetcher.script(); - // Duplicated from meteor/tools/bundler.js - serverScript = serverScript.replace(/##PLATFORM##/g, platform); - serverScript = serverScript.replace(/##BUNDLE_VERSION##/g, bundleVersion); - serverScript = serverScript.replace(/##RUN_FILE##/g, runFile); - serverScript = serverScript.replace(/##IMAGE##/g, ''); - fs.writeFileSync(serverProgPath, serverScript); - fs.chmodSync(serverProgPath, '744'); -}; - -StarTranslator._getArch = function () { - return Meteor.settings.arch; -}; - -StarTranslator._getPlatform = function () { - var self = this; - // Duplicated from meteor/tools/bundler.js - var archToPlatform = { - 'os.linux.x86_32': 'Linux_i686', - 'os.linux.x86_64': 'Linux_x86_64', - 'os.osx.x86_64': 'Darwin_x86_64' - }; - return archToPlatform[self._getArch()]; -}; - -StarTranslator._getBundleVersion = function (bundlePath) { - var version = fs.readFileSync(path.join(bundlePath, - "server", ".bundle_version.txt"), - 'utf8'); - return version.trim(); -}; - -StarTranslator._writeClientProg = function (bundlePath, clientProgPath) { - var origClientManifest = JSON.parse(fs.readFileSync(path.join(bundlePath, - "app.json"), - 'utf8')); - var clientManifest = { - "format": "web-program-pre1", - "manifest": origClientManifest.manifest, - // XXX Haven't updated this for the app.html -> head/body change, but - // surely we don't need to because code in pre-star apps doesn't - // even read this file? - "page": "app.html", - "static": "static", - "staticCacheable": "static_cacheable" - }; - fs.writeFileSync(clientProgPath, JSON.stringify(clientManifest, null, 2)); -}; diff --git a/tools/bundler.js b/tools/bundler.js index 41998b3c11..d4c05af82a 100644 --- a/tools/bundler.js +++ b/tools/bundler.js @@ -1647,11 +1647,6 @@ _.extend(ServerTarget.prototype, { write: function (builder, options) { var self = this; - // Pick a start script name - // XXX base it on the name of the target - var scriptName = 'start.sh'; - builder.reserve(scriptName); - // This is where the dev_bundle will be downloaded and unpacked builder.reserve('dependencies'); @@ -1717,21 +1712,10 @@ _.extend(ServerTarget.prototype, { return; } - var devBundleVersion = - files.readFile( - files.pathJoin(files.getDevBundle(), '.bundle_version.txt'), 'utf8'); - devBundleVersion = devBundleVersion.split('\n')[0]; - - var Packages = isopackets.load('dev-bundle-fetcher'); - var script = Packages["dev-bundle-fetcher"].DevBundleFetcher.script(); - script = script.replace(/##PLATFORM##/g, platform); - script = script.replace(/##BUNDLE_VERSION##/g, devBundleVersion); - script = script.replace(/##IMAGE##/g, imageControlFile); - script = script.replace(/##RUN_FILE##/g, 'boot.js'); - builder.write(scriptName, { data: new Buffer(script, 'utf8'), - executable: true }); - - return scriptName; + // Nothing actually pays attention to the `path` field for a server program + // in star.json any more, so it might as well be boot.js. (It used to be + // start.sh, a script included for the legacy Galaxy prototype.) + return 'boot.js'; } }); diff --git a/tools/compiler.js b/tools/compiler.js index f768f9bfe3..009d1efecd 100644 --- a/tools/compiler.js +++ b/tools/compiler.js @@ -24,8 +24,8 @@ var compiler = exports; // You should also update this whenever you update any of the packages used // directly by the isopack creation process (eg js-analyze) since they do not // end up as watched dependencies. (At least for now, packages only used in -// target creation (eg minifiers and dev-bundle-fetcher) don't require you to -// update BUILT_BY, though you will need to quit and rerun "meteor run".) +// target creation (eg minifiers) don't require you to update BUILT_BY, though +// you will need to quit and rerun "meteor run".) compiler.BUILT_BY = 'meteor/15'; // This is a list of all possible architectures that a build can target. (Client diff --git a/tools/isopackets.js b/tools/isopackets.js index 03777bd54f..73435dc198 100644 --- a/tools/isopackets.js +++ b/tools/isopackets.js @@ -50,7 +50,6 @@ var ISOPACKETS = { 'mongo': ['mongo'], 'ejson': ['ejson'], 'minifiers': ['minifiers'], - 'dev-bundle-fetcher': ['dev-bundle-fetcher'], 'constraint-solver': ['constraint-solver'], 'cordova-support': ['boilerplate-generator', 'logging', 'webapp-hashing', 'xmlbuilder'],