Browse files

[docs] pushed to gh-pages

  • Loading branch information...
1 parent 36c425c commit 64809e32e68a01b06b28707e0eaa833b6e700d4c nlco committed May 11, 2011
Showing with 54 additions and 5,497 deletions.
  1. +0 −19 LICENSE
  2. +0 −194 README.md
  3. +0 −78 bin/carapace
  4. 0 bin/haibu
  5. +0 −52 bin/haibu-balancer
  6. +0 −57 bin/haibu-server
  7. +0 −18 bin/mkdirs
  8. +0 −6 config/auth.json.example
  9. 0 {docs → }/docco.css
  10. BIN examples/haibu.png
  11. +0 −35 examples/hello-spawn.js
  12. 0 {docs → }/haibu.html
  13. 0 {docs → }/haibu/balancer/balancer.html
  14. 0 {docs → }/haibu/balancer/index.html
  15. 0 {docs → }/haibu/core/config.html
  16. 0 {docs → }/haibu/core/process-store.html
  17. 0 {docs → }/haibu/core/spawner.html
  18. 0 {docs → }/haibu/drone/client.html
  19. 0 {docs → }/haibu/drone/drone.html
  20. 0 {docs → }/haibu/drone/index.html
  21. 0 {docs → }/haibu/drone/service.html
  22. 0 {docs → }/haibu/plugins/changelog.html
  23. 0 {docs → }/haibu/plugins/chroot.html
  24. 0 {docs → }/haibu/plugins/logger.html
  25. 0 {docs → }/haibu/repositories/git.html
  26. 0 {docs → }/haibu/repositories/index.html
  27. 0 {docs → }/haibu/repositories/local-file.html
  28. 0 {docs → }/haibu/repositories/npm.html
  29. 0 {docs → }/haibu/repositories/remote-file.html
  30. 0 {docs → }/haibu/repositories/repository.html
  31. 0 {docs → }/haibu/repositories/tar.html
  32. 0 {docs → }/haibu/repositories/zip.html
  33. 0 {docs → }/haibu/utils/base64.html
  34. 0 {docs → }/haibu/utils/bin.html
  35. 0 {docs → }/haibu/utils/index.html
  36. +54 −0 index.html
  37. +0 −65 lib/haibu.js
  38. +0 −301 lib/haibu/balancer/balancer.js
  39. +0 −63 lib/haibu/balancer/index.js
  40. +0 −230 lib/haibu/core/config.js
  41. +0 −109 lib/haibu/core/process-store.js
  42. +0 −218 lib/haibu/core/spawner.js
  43. +0 −164 lib/haibu/drone/client.js
  44. +0 −231 lib/haibu/drone/drone.js
  45. +0 −47 lib/haibu/drone/index.js
  46. +0 −137 lib/haibu/drone/service.js
  47. +0 −2 lib/haibu/plugins/changelog.js
  48. +0 −58 lib/haibu/plugins/chroot.js
  49. +0 −163 lib/haibu/plugins/logger.js
  50. +0 −158 lib/haibu/repositories/git.js
  51. +0 −101 lib/haibu/repositories/index.js
  52. +0 −87 lib/haibu/repositories/local-file.js
  53. +0 −240 lib/haibu/repositories/npm.js
  54. +0 −114 lib/haibu/repositories/remote-file.js
  55. +0 −210 lib/haibu/repositories/repository.js
  56. +0 −63 lib/haibu/repositories/tar.js
  57. +0 −65 lib/haibu/repositories/zip.js
  58. +0 −44 lib/haibu/utils/base64.js
  59. +0 −71 lib/haibu/utils/bin.js
  60. +0 −310 lib/haibu/utils/index.js
  61. +0 −39 package.json
  62. +0 −66 test/core/config-api-test.js
  63. +0 −38 test/core/config-dirs-test.js
  64. +0 −64 test/core/config-test.js
  65. +0 −27 test/core/package-test.js
  66. +0 −117 test/core/spawner-test.js
  67. +0 −139 test/drone/client-test.js
  68. +0 −230 test/drone/drone-api-test.js
  69. +0 −210 test/drone/drone-test.js
  70. +0 −48 test/drone/process-store-test.js
  71. +0 −47 test/fixtures/apps.js
  72. +0 −4 test/fixtures/repositories/bad-app/index.js
  73. +0 −13 test/fixtures/repositories/bad-app/package.json
  74. BIN test/fixtures/repositories/chat.tgz
  75. +0 −7 test/fixtures/repositories/local-file/package.json
  76. +0 −9 test/fixtures/repositories/local-file/run.js
  77. BIN test/fixtures/repositories/npm-deps.tgz
  78. +0 −9 test/fixtures/repositories/npm-deps/index.js
  79. +0 −16 test/fixtures/repositories/npm-deps/package.json
  80. BIN test/fixtures/repositories/test.tgz
  81. +0 −78 test/helpers.js
  82. +0 −4 test/mocks/mailer.js
  83. +0 −133 test/plugins/chroot-test.js
  84. +0 −25 test/plugins/logger-test.js
  85. +0 −51 test/repositories/git-test.js
  86. +0 −64 test/repositories/local-file-test.js
  87. +0 −69 test/repositories/npm-test.js
  88. +0 −95 test/repositories/remote-file-test.js
  89. +0 −93 test/repositories/tar-test.js
  90. +0 −92 test/repositories/zip-test.js
View
19 LICENSE
@@ -1,19 +0,0 @@
-Copyright (c) 2010 Nodejitsu Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
View
194 README.md
@@ -1,194 +0,0 @@
-# haibu
-
-<img src="https://github.com/nodejitsu/haibu/raw/master/examples/haibu.png"/></img>
-
-*spawn your own node.js clouds, on your own hardware*
-
-# What is haibu?
-
-haibu is the open-source [node.js](http://nodejs.org) project for spawning and managing several node.js applications on a single server. It's an integral part of [Nodejitsu's](http://nodejitsu.com) production stack and is fully supported by a dedicated team of core node.js developers.
-
-# How does it work?
-
-haibu (which is Japanese for "hive") transforms node.js applications (using a [Carapace](https://github.com/nodejitsu/haibu/blob/master/bin/carapace)) into "drones". This approach allows haibu to directly interact with node.js applications and add all sorts of additional functionality. haibu also contains a plugin system, so you can easily add even more functionality without needing to dive too far into the codebase.
-
-`haibu` builds on this concept of "drones" and exposes a robust and granular API for interacting with your node.js applications. At a low level, haibu's API is exposed as a RESTFul HTTP webservice. Any system that supports basic HTTP requests can communicate with a haibu server. If you are working in Node.js, haibu comes with a high-level Node.js API client.
-
-## Where can I run haibu?
-
-`haibu` doesn't discriminate. If your environment supports node.js, you can install `haibu` and start up your own node.js cloud. This makes `haibu` an ideal tool for both development purposes and production usage since you can seamlessly setup haibu on your local machine, on utility computing providers (such as Amazon EC2 or Rackspace), on dedicated servers, or even on a mobile phone!
-
-# Installation
-
- [sudo] npm install haibu -g
-
-# Documentation
-
-haibu's documentation is still very much a work in progress. We'll be actively updating the documentation in the upcoming weeks to make it easier to get acclimated with `haibu`. Aside from the overview provided in this `README.md` file, `haibu` uses docco and literate style programming to provide comprehensive source code documentation. Check out `/docs/haibu.html` for more information.
-
-# An overview of using haibu
-
-## Starting up a haibu-server
-
-```
-[sudo] node bin/haibu-server
-(...)
-haibu started @ 127.0.0.1 on port 9002 as api-server
-```
-
-**Now that there is a haibu server running, we can begin to interact with it's API.**
-
-##Starting an application using the haibu Client
-*(From: /examples/hello-spawn.js)*
-
-Allows you to call haibu programmatically from inside your node.js scripts.
-
-```javascript
-var eyes = require('eyes'),
- haibu = require('haibu');
-
-// Create a new client for communicating with the haibu server
-var client = new haibu.drone.Client({
- host: 'localhost',
- port: 9002
-});
-
-// A basic package.json for a node.js application on haibu
-var app = {
- "user": "marak",
- "name": "test",
- "domain": "devjitsu.com",
- "repository": {
- "type": "git",
- "url": "https://github.com/Marak/hellonode.git",
- },
- "scripts": {
- "start": "server.js"
- }
-};
-
-// Attempt to start up a new application
-client.start(app, function (err, result) {
- if (err) {
- console.log('Error spawning app: ' + app.name);
- return eyes.inspect(err);
- }
-
- console.log('Successfully spawned app:');
- eyes.inspect(result);
-});
-
-
-client.start(app, function (err, result) {
- eyes.inspect(err);
- eyes.inspect(result);
-});
-```
-
-## Using haibu-balancer
-
-Once your node.js application has been started on `haibu` you're going to want to access it. `haibu-balancer` will load balance multiple instances of your application using [node-http-proxy][1] based on the `domain` property supplied in the package.json sent to each `start` request. Starting `haibu-balancer` is very simple:
-
-```
-sudo haibu-balancer
-(...)
-haibu started @ 127.0.0.1 on port 80 as balancer
-```
-
-Lets look at the sample data we sent to the `haibu-server` in the above example
-
-```javascript
-{
- "user": "marak",
- "name": "test",
- "domain": "devjitsu.com",
- "repository": {
- "type": "git",
- "url": "https://github.com/Marak/hellonode.git",
- },
- "scripts": {
- "start": "server.js"
- }
-}
-```
-
-As you can see, the `domain` property is set to `devjitsu.com`. This means that incoming HTTP requests which have their `HOST` header set to `devjitsu.com` will be round-robin load-balanced across all instances of your application managed by `haibu`. If you're testing locally you can modify your `/etc/hosts` file for `devjitsu.com` and see your applications running in your local development environment.
-
-## RESTful Webservice
-
-If you need to integrate non-node.js systems with haibu, you can use haibu's RESTful JSON API. We recommend using haibu's native Node.js Client, but if you need to integrate with none-node.js systems this is not always a viable option.
-
-**Starting an application through the webservice**
-
- POST http://127.0.0.1:9002/drones/test/start
- ...
- {
- "start": {
- "user": "marak",
- "name": "test",
- "domain": "devjitsu.com",
- "repository": {
- "type": "git",
- "url": "https://github.com/Marak/hellonode.git"
- },
- "scripts": {
- "start": "server.js"
- }
- }
- }
-
- **Response**
-
- HTTP/1.1 200 OK
- Date: Thu, 05 May 2011 18:15:36 GMT
- Server: journey/0.4.0
- Content-Type: application/json
- Content-Length: 353
- Connection: close
- ...
- {
- drone: {
- uid: 'gbE3',
- ctime: 1304619335818,
- pid: 7903,
- foreverPid: 7195,
- logFile: '/Users/Charlie/.forever/gbE3.log',
- options: [ '/Users/Charlie/Nodejitsu/haibu/local/marak/test/hellonode/server.js', '127.0.0.1', 8001 ],
- file: '/Users/Charlie/Nodejitsu/haibu/bin/carapace',
- pidFile: '/Users/Charlie/.forever/pids/gbE3.pid',
- port: 8001,
- host: '127.0.0.1'
- }
- }
-
-**Stopping an application through the webservice**
-
-
- POST http://127.0.0.1:9002/drones/test/stop
- ...
- {
- "stop": {
- "name": "test"
- }
- }
-
- **response**
-
- HTTP/1.1 200 OK
- Date: Thu, 05 May 2011 18:16:22 GMT
- Server: journey/0.4.0
- Connection: close
- Transfer-Encoding: chunked
-
-## Run Tests
-All of the `haibu` tests are written in [vows][0], and cover all of the use cases described above.
-<pre>
- sudo vows test/**/*-test.js --spec
-</pre>
-
-*If you copy and paste the above link, the test suite will attempt to connect to Rackspace for some of the remote file tests. You don't need to run these tests or use Rackspace to get started. We'll be improving our test runner soon to help make this process a bit more intuitive.*
-
-#### Author: [Nodejitsu Inc.](http://www.nodejitsu.com)
-
-[0]: http://vowsjs.org
-[1]: http://github.com/nodejitsu/node-http-proxy
View
78 bin/carapace
@@ -1,78 +0,0 @@
-/*
- * carapace.js: Light-weight wrapper thats envelopes a drone, allowing us to override
- * several aspects of the drone, such as the HTTP server. We also have the
- * benefit of getting returned process informations about the drone.
- *
- * (C) 2010, Nodejitsu Inc.
- *
- */
-
-var util = require('util'),
- daemon = require('daemon'),
- net = require('net'),
- http = require('http');
-
-//
-// TODO (indexzero): Make this more robust when forever is included.
-//
-var carapace = {};
-carapace.config = {
- script : process.argv[2],
- server : process.argv[3],
- port : process.argv[4],
- root : process.argv[5],
- appPath : process.argv[6],
- pid : process.pid
-};
-
-var netListen = net.Server.prototype.listen;
-
-//
-// Helper function from Node code to parse port arguments
-// passed to net.prototype.Server.listen
-//
-function toPort(x) {
- return (x = Number(x)) >= 0 ? x : false;
-}
-
-//
-// Donkey punch the listen() function.
-//
-// 1. Listen on a UNIX socket: server.listen('/tmp/socket');
-// Ignore these cases, pass through to netListen
-//
-// 2. Listen on port 8000, accept connections from INADDR_ANY: server.listen(8000);
-// Change the port to the port we have been passed by the config
-//
-// 3. Listen on port 8000, accept connections to '192.168.1.2': server.listen(8000, '192.168.1.2');
-// Change the port to the port we have been passed by the config
-//
-net.Server.prototype.listen = function () {
- var args = Array.prototype.slice.call(arguments),
- port = toPort(args[0]);
-
- //
- // If arguments[0] is a port, assume (2, 3) from the documentation
- // above and change the value of the arguments to what we've been passed.
- //
- if (port) {
- args[0] = carapace.config.port;
- }
-
- return netListen.apply(this, args);
-};
-
-// Update the require path of the target drone start script
-var p = carapace.config.script.replace('.js', ''),
- tmp = util.puts, drone;
-
-// Set the root of the child process if requested
-if (carapace.config.root) {
- daemon.chroot(carapace.config.root);
- process.chdir(carapace.config.appPath);
-}
-
-require.paths.unshift(process.cwd());
-
-// Now just require the drone to get things moving.
-drone = require(p);
View
0 bin/haibu
No changes.
View
52 bin/haibu-balancer
@@ -1,52 +0,0 @@
-#!/usr/bin/env node
-
-require.paths.unshift(require('path').join(__dirname, '..', 'lib'));
-
-var util = require('util'),
- colors = require('colors'),
- argv = require('optimist').argv,
- haibu = require('haibu');
-
-var help = [
- 'usage: haibu-balancer [options]',
- '',
- 'Starts the haibu balancer server responsible for handling all incoming HTTP requests.',
- '',
- 'options:',
- ' -a IP Address that you want the server to bind to [dynamic]',
- ' -p Port that you want the server to run on [80]',
- ' -e [env] The environment to the specified command in [development]',
- ' --logger Use the haibu logger plugin [true]',
- ' -s --silent Suppress the log messages from the output',
- ' -h, --help You\'re staring at it',
-].join('\n');
-
-if (argv.h || argv.help) {
- return util.puts(help);
-}
-
-var env = argv.env || 'development',
- logger = typeof argv.logger !== 'undefined' ? argv.logger : true,
- port = argv.p || 80;
-
-haibu.utils.bin.getAddress(argv.a, function (err, address) {
- if (err) {
- log('Error getting IP Address: ' + err.message);
- }
-
- haibu.utils.bin.tryLoadCache(function (err, config) {
- var options = {
- env: env,
- port: port,
- config: config
- };
-
- haibu.balancer.start(options, function (err, server, proxy, active) {
- if (logger) {
- haibu.use(haibu.plugins.logger);
- }
-
- haibu.utils.showWelcome('balancer', address, port);
- });
- });
-});
View
57 bin/haibu-server
@@ -1,57 +0,0 @@
-#!/usr/bin/env node
-
-require.paths.unshift(require('path').join(__dirname, '..', 'lib'));
-
-var util = require('util'),
- colors = require('colors'),
- argv = require('optimist').argv,
- haibu = require('haibu');
-
-var help = [
- 'usage: haibu-server [options]',
- '',
- 'Starts the haibu API server responsible for spawning node.js applications.',
- '',
- 'options:',
- ' -a IP Address that you want the server to bind to [dynamic]',
- ' -p Port that you want the server to run on [9002]',
- ' -e [env] The environment to the specified command in [development]',
- ' --logger Use the haibu logger plugin [true]',
- ' --chroot Deploy drones using chroot',
- ' -s --silent Suppress the log messages from the output',
- ' -h, --help You\'re staring at it',
-].join('\n');
-
-if (argv.h || argv.help) {
- return util.puts(help);
-}
-
-if (argv.chroot) {
- haibu.use(haibu.plugins.chroot);
-}
-
-var env = argv.env || 'development',
- logger = typeof argv.logger !== 'undefined' ? argv.logger : true,
- port = argv.p || 9002;
-
-haibu.utils.bin.getAddress(argv.a, function (err, address) {
- if (err) {
- log('Error getting IP Address: ' + err.message);
- }
-
- haibu.utils.bin.tryLoadCache(function (err, config) {
- var options = {
- env: env,
- port: port,
- config: config
- };
-
- haibu.drone.start(options, function () {
- if (logger) {
- haibu.use(haibu.plugins.logger);
- }
-
- haibu.utils.showWelcome('api-server', address, port);
- });
- });
-});
View
18 bin/mkdirs
@@ -1,18 +0,0 @@
-#!/usr/bin/env node
-
-require.paths.unshift(require('path').join(__dirname, '..', 'lib'));
-
-var sys = require('sys'),
- haibu = require('haibu');
-
-haibu.utils.initDirectories(function (err, paths) {
- if (err) {
- sys.puts('Failed to create directories for haibu: ' + err.message);
- return;
- }
-
- sys.puts('Successfully created directories for haibu: ');
- paths.forEach(function (path) {
- sys.puts(' ' + path);
- });
-});
View
6 config/auth.json.example
@@ -1,6 +0,0 @@
-{
- "auth": {
- "username": "test-username",
- "apiKey": "test-apiKey"
- }
-}
View
0 docs/docco.css → docco.css
File renamed without changes.
View
BIN examples/haibu.png
Deleted file not rendered
View
35 examples/hello-spawn.js
@@ -1,35 +0,0 @@
-require.paths.unshift(require('path').join(__dirname, '..', 'lib'));
-
-var eyes = require('eyes'),
- haibu = require('haibu');
-
-// Create a new client for communicating with the haibu server
-var client = new haibu.drone.Client({
- host: 'localhost',
- port: 9002
-});
-
-// A basic package.json for a node.js application on Haibu
-var app = {
- "user": "marak",
- "name": "test",
- "domain": "devjitsu.com",
- "repository": {
- "type": "git",
- "url": "https://github.com/Marak/hellonode.git",
- },
- "scripts": {
- "start": "server.js"
- }
-};
-
-// Attempt to start up a new application
-client.start(app, function (err, result) {
- if (err) {
- console.log('Error spawning app: ' + app.name);
- return eyes.inspect(err);
- }
-
- console.log('Successfully spawned app:');
- eyes.inspect(result);
-});
View
0 docs/haibu.html → haibu.html
File renamed without changes.
View
0 docs/haibu/balancer/balancer.html → haibu/balancer/balancer.html
File renamed without changes.
View
0 docs/haibu/balancer/index.html → haibu/balancer/index.html
File renamed without changes.
View
0 docs/haibu/core/config.html → haibu/core/config.html
File renamed without changes.
View
0 docs/haibu/core/process-store.html → haibu/core/process-store.html
File renamed without changes.
View
0 docs/haibu/core/spawner.html → haibu/core/spawner.html
File renamed without changes.
View
0 docs/haibu/drone/client.html → haibu/drone/client.html
File renamed without changes.
View
0 docs/haibu/drone/drone.html → haibu/drone/drone.html
File renamed without changes.
View
0 docs/haibu/drone/index.html → haibu/drone/index.html
File renamed without changes.
View
0 docs/haibu/drone/service.html → haibu/drone/service.html
File renamed without changes.
View
0 docs/haibu/plugins/changelog.html → haibu/plugins/changelog.html
File renamed without changes.
View
0 docs/haibu/plugins/chroot.html → haibu/plugins/chroot.html
File renamed without changes.
View
0 docs/haibu/plugins/logger.html → haibu/plugins/logger.html
File renamed without changes.
View
0 docs/haibu/repositories/git.html → haibu/repositories/git.html
File renamed without changes.
View
0 docs/haibu/repositories/index.html → haibu/repositories/index.html
File renamed without changes.
View
0 docs/haibu/repositories/local-file.html → haibu/repositories/local-file.html
File renamed without changes.
View
0 docs/haibu/repositories/npm.html → haibu/repositories/npm.html
File renamed without changes.
View
0 docs/haibu/repositories/remote-file.html → haibu/repositories/remote-file.html
File renamed without changes.
View
0 docs/haibu/repositories/repository.html → haibu/repositories/repository.html
File renamed without changes.
View
0 docs/haibu/repositories/tar.html → haibu/repositories/tar.html
File renamed without changes.
View
0 docs/haibu/repositories/zip.html → haibu/repositories/zip.html
File renamed without changes.
View
0 docs/haibu/utils/base64.html → haibu/utils/base64.html
File renamed without changes.
View
0 docs/haibu/utils/bin.html → haibu/utils/bin.html
File renamed without changes.
View
0 docs/haibu/utils/index.html → haibu/utils/index.html
File renamed without changes.
View
54 index.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html> <html> <head> <title>haibu.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="haibu/balancer/balancer.html"> haibu/balancer/balancer.html </a> <a class="source" href="haibu/balancer/index.html"> haibu/balancer/index.html </a> <a class="source" href="haibu/core/config.html"> haibu/core/config.html </a> <a class="source" href="haibu/core/process-store.html"> haibu/core/process-store.html </a> <a class="source" href="haibu/core/spawner.html"> haibu/core/spawner.html </a> <a class="source" href="haibu/drone/client.html"> haibu/drone/client.html </a> <a class="source" href="haibu/drone/drone.html"> haibu/drone/drone.html </a> <a class="source" href="haibu/drone/index.html"> haibu/drone/index.html </a> <a class="source" href="haibu/drone/service.html"> haibu/drone/service.html </a> <a class="source" href="haibu/plugins/changelog.html"> haibu/plugins/changelog.html </a> <a class="source" href="haibu/plugins/chroot.html"> haibu/plugins/chroot.html </a> <a class="source" href="haibu/plugins/logger.html"> haibu/plugins/logger.html </a> <a class="source" href="haibu/repositories/git.html"> haibu/repositories/git.html </a> <a class="source" href="haibu/repositories/index.html"> haibu/repositories/index.html </a> <a class="source" href="haibu/repositories/local-file.html"> haibu/repositories/local-file.html </a> <a class="source" href="haibu/repositories/npm.html"> haibu/repositories/npm.html </a> <a class="source" href="haibu/repositories/remote-file.html"> haibu/repositories/remote-file.html </a> <a class="source" href="haibu/repositories/repository.html"> haibu/repositories/repository.html </a> <a class="source" href="haibu/repositories/tar.html"> haibu/repositories/tar.html </a> <a class="source" href="haibu/repositories/zip.html"> haibu/repositories/zip.html </a> <a class="source" href="haibu/utils/base64.html"> haibu/utils/base64.html </a> <a class="source" href="haibu/utils/bin.html"> haibu/utils/bin.html </a> <a class="source" href="haibu/utils/index.html"> haibu/utils/index.html </a> <a class="source" href="haibu.html"> haibu.html </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> haibu.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="cm">/*</span>
+<span class="cm"> * haibu.js: Top level include for the haibu module</span>
+<span class="cm"> *</span>
+<span class="cm"> * (C) 2010, Nodejitsu Inc.</span>
+<span class="cm"> *</span>
+<span class="cm"> */</span>
+
+<span class="kd">var</span> <span class="nx">fs</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;fs&#39;</span><span class="p">),</span>
+ <span class="nx">events</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;events&#39;</span><span class="p">);</span>
+
+<span class="nx">require</span><span class="p">.</span><span class="nx">paths</span><span class="p">.</span><span class="nx">unshift</span><span class="p">(</span><span class="nx">__dirname</span><span class="p">);</span>
+
+<span class="kd">var</span> <span class="nx">haibu</span> <span class="o">=</span> <span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">events</span><span class="p">.</span><span class="nx">EventEmitter</span><span class="p">();</span>
+
+<span class="nx">haibu</span><span class="p">.</span><span class="nx">config</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;haibu/core/config&#39;</span><span class="p">);</span>
+<span class="nx">haibu</span><span class="p">.</span><span class="nx">utils</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;haibu/utils&#39;</span><span class="p">);</span>
+<span class="nx">haibu</span><span class="p">.</span><span class="nx">Spawner</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;haibu/core/spawner&#39;</span><span class="p">).</span><span class="nx">Spawner</span><span class="p">;</span>
+<span class="nx">haibu</span><span class="p">.</span><span class="nx">ProcessStore</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;haibu/core/process-store&#39;</span><span class="p">).</span><span class="nx">ProcessStore</span><span class="p">;</span>
+<span class="nx">haibu</span><span class="p">.</span><span class="nx">repository</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;haibu/repositories&#39;</span><span class="p">);</span>
+<span class="nx">haibu</span><span class="p">.</span><span class="nx">drone</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;haibu/drone&#39;</span><span class="p">);</span>
+<span class="nx">haibu</span><span class="p">.</span><span class="nx">balancer</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;haibu/balancer&#39;</span><span class="p">);</span>
+<span class="nx">haibu</span><span class="p">.</span><span class="nx">initialized</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
+<span class="nx">haibu</span><span class="p">.</span><span class="nx">plugins</span> <span class="o">=</span> <span class="p">{};</span>
+<span class="nx">haibu</span><span class="p">.</span><span class="nx">_plugins</span> <span class="o">=</span> <span class="p">{};</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>function init (options, callback)
+Initializes haibu directories and models</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">haibu</span><span class="p">.</span><span class="nx">init</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">options</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="nx">haibu</span><span class="p">.</span><span class="nx">initialized</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="nx">callback</span><span class="p">();</span>
+ <span class="p">}</span>
+
+ <span class="nx">haibu</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="nx">options</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">haibu</span><span class="p">.</span><span class="nx">utils</span><span class="p">.</span><span class="nx">initDirectories</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
+ <span class="nx">haibu</span><span class="p">.</span><span class="nx">initialized</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
+ <span class="nx">callback</span><span class="p">();</span>
+ <span class="p">});</span>
+ <span class="p">});</span>
+<span class="p">};</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <h3>function use (plugin)</h3>
+
+<h4>@plugin {Object} Instance of a plugin from <code>haibu.plugins</code></h4>
+
+<p>Adds the specified <code>plugin</code> to the set of active plugins used by haibu.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">haibu</span><span class="p">.</span><span class="nx">use</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">plugin</span><span class="p">)</span> <span class="p">{</span>
+ <span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">),</span>
+ <span class="nx">callback</span> <span class="o">=</span> <span class="k">typeof</span> <span class="nx">args</span><span class="p">[</span><span class="nx">args</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">===</span> <span class="s1">&#39;function&#39;</span> <span class="o">&amp;&amp;</span> <span class="nx">args</span><span class="p">.</span><span class="nx">pop</span><span class="p">(),</span>
+ <span class="nx">options</span> <span class="o">=</span> <span class="nx">args</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="nx">args</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
+
+ <span class="nx">haibu</span><span class="p">.</span><span class="nx">_plugins</span><span class="p">[</span><span class="nx">plugin</span><span class="p">.</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="nx">plugin</span><span class="p">;</span>
+ <span class="nx">plugin</span><span class="p">.</span><span class="nx">init</span><span class="p">(</span><span class="nx">options</span><span class="p">,</span> <span class="nx">callback</span><span class="p">);</span>
+<span class="p">};</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>Define each of our plugins as a lazy loaded <code>require</code> statement</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">fs</span><span class="p">.</span><span class="nx">readdirSync</span><span class="p">(</span><span class="nx">__dirname</span> <span class="o">+</span> <span class="s1">&#39;/haibu/plugins&#39;</span><span class="p">).</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">plugin</span><span class="p">)</span> <span class="p">{</span>
+ <span class="nx">plugin</span> <span class="o">=</span> <span class="nx">plugin</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="s1">&#39;.js&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">);</span>
+ <span class="nx">haibu</span><span class="p">.</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">__defineGetter__</span><span class="p">(</span><span class="nx">plugin</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./haibu/plugins/&#39;</span> <span class="o">+</span> <span class="nx">plugin</span><span class="p">);</span>
+ <span class="p">});</span>
+<span class="p">});</span>
+
+</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>
View
65 lib/haibu.js
@@ -1,65 +0,0 @@
-/*
- * haibu.js: Top level include for the haibu module
- *
- * (C) 2010, Nodejitsu Inc.
- *
- */
-
-var fs = require('fs'),
- events = require('events');
-
-require.paths.unshift(__dirname);
-
-var haibu = module.exports = new events.EventEmitter();
-
-haibu.config = require('haibu/core/config');
-haibu.utils = require('haibu/utils');
-haibu.Spawner = require('haibu/core/spawner').Spawner;
-haibu.ProcessStore = require('haibu/core/process-store').ProcessStore;
-haibu.repository = require('haibu/repositories');
-haibu.drone = require('haibu/drone');
-haibu.balancer = require('haibu/balancer');
-haibu.initialized = false;
-haibu.plugins = {};
-haibu._plugins = {};
-
-//
-// function init (options, callback)
-// Initializes haibu directories and models
-//
-haibu.init = function (options, callback) {
- if (haibu.initialized) {
- return callback();
- }
-
- haibu.config.load(options, function (err) {
- haibu.utils.initDirectories(function () {
- haibu.initialized = true;
- callback();
- });
- });
-};
-
-//
-// ### function use (plugin)
-// #### @plugin {Object} Instance of a plugin from `haibu.plugins`
-// Adds the specified `plugin` to the set of active plugins used by haibu.
-//
-haibu.use = function (plugin) {
- var args = Array.prototype.slice.call(arguments),
- callback = typeof args[args.length - 1] === 'function' && args.pop(),
- options = args.length > 1 && args.pop();
-
- haibu._plugins[plugin.name] = plugin;
- plugin.init(options, callback);
-};
-
-//
-// Define each of our plugins as a lazy loaded `require` statement
-//
-fs.readdirSync(__dirname + '/haibu/plugins').forEach(function (plugin) {
- plugin = plugin.replace('.js', '');
- haibu.plugins.__defineGetter__(plugin, function () {
- return require('./haibu/plugins/' + plugin);
- });
-});
View
301 lib/haibu/balancer/balancer.js
@@ -1,301 +0,0 @@
-/*
- * proxy.js: Responsible for proxying across all applications available to haibu.
- *
- * (C) 2010, Nodejitsu Inc.
- *
- */
-
-var util = require('util'),
- path = require('path'),
- fs = require('fs'),
- events = require('events'),
- async = require('async'),
- colors = require('colors'),
- qs = require('querystring'),
- httpProxy = require('http-proxy'),
- haibu = require('haibu');
-
-//
-// ### @matchers
-// Regular expression parsers for handling different
-// persistent storage files used by `haibu`.
-//
-var matchers = {
- app: /^([\w|\-]+)\.package\.json/,
- pid: /^([\w|\-]+)\.(\d+)\.json/
-};
-
-//
-// ### function Balancer (options)
-// #### @options {Object} Options for this instance.
-// Constructor function for the `haibu` Balancer responsible
-// for load balancing across all applications know to haibu on
-// this machine.
-//
-var Balancer = exports.Balancer = function (options) {
- events.EventEmitter.call(this);
-
- var self = this;
-
- //
- // Setup shared state for the `haibu.ProcessStore`.
- //
- this.active = {};
- this.processes = new haibu.ProcessStore(options);
-
- //
- // Load files into Memory when they are found
- // in the ProcessStore
- //
- this.processes.on('created', function (file) {
- self._add(file, function () {
- self.emit('created', file);
- haibu.emit('balancer:created', 'info', { file: file });
- });
- });
-
- //
- // Remove files from the Balancer when they are removed
- // from the ProcessStore.
- //
- this.processes.on('removed', function (file) {
- self._remove(file);
- self.emit('removed', file);
- haibu.emit('balancer:removed', 'info', { file: file });
- });
-
- //
- // Load all relevant files on initial load.
- //
- this.processes.once('load', function (files) {
- function checkFile (file, next) {
- return files[file].isFile() ? self._add(file, next) : next();
- }
-
- async.forEach(Object.keys(files), checkFile, function (err) {
- return err ? self.emit('error', err) : self.emit('ready', self.active);
- });
- })
-
- //
- // Start monitoring for process files.
- //
- this.processes.monitor();
-
- //
- // Setup the balancing proxy using `node-http-proxy`.
- //
- this.httpProxy = new httpProxy.HttpProxy(options);
-
- this.httpProxy.on('end', function (req, res) {
- var diff = Date.now() - req.ptime;
- haibu.emit('balancer:proxy', 'info', {
- url: req.url,
- method: req.method,
- time: diff + 'ms'
- });
- });
-};
-
-//
-// Inherit from `events.EventEmitter`.
-//
-util.inherits(Balancer, events.EventEmitter);
-
-//
-// ### function handle (req, res)
-// #### @req {ServerRequest} Incoming server request to balancer
-// #### @res {ServerResponse} Outoing server request to write to.
-// Attempts to proxy the incoming request to the specified application
-// by using the `req.headers.host` property.
-//
-Balancer.prototype.handle = function (req, res) {
- var record = this.findDrone(req), drone;
-
- req.ptime = Date.now();
- haibu.emit('balancer:incoming', 'info', req.headers);
-
- if (!record) {
- return this.serveText(req, res, {
- code: 400,
- message: 'Application not found for: ' + req.headers.host
- });
- }
- else if (!record.drones || record.drones.length === 0) {
- return this.serveText(req, res, {
- code: 400,
- message: 'No drones for: ' + req.headers.host
- });
- }
-
- drone = record.drones.shift();
- this.httpProxy.proxyRequest(req, res, drone);
- record.drones.push(drone);
-};
-
-//
-// ### function findDrone (req)
-// #### @req {ServerRequest} Incoming server request to find drones against
-// Attempts to find a drone for the incoming server request
-// by cross-referencing `req.headers.host` against the `domain`
-// or `domains` property of each application known to `haibu`.
-//
-Balancer.prototype.findDrone = function (req) {
- var self = this,
- host = req.headers.host.split('.'),
- domain = host.slice(-2).join('.');
-
- return Object.keys(this.active).map(function (app) {
- return self.active[app];
- }).filter(function (rec) {
- return rec.app.domain === domain || (rec.app.domains
- && rec.app.domains.indexOf(domain) !== -1);
- })[0];
-};
-
-//
-// ### function serveText (req, res, data)
-// #### @req {ServerRequest} Incoming server request
-// #### @res {ServerResponse} Outoing server request to write to.
-// Writes `data.message` to the outgoing `res` along with any
-// metadata passed as `data.meta`.
-//
-Balancer.prototype.serveText = function (req, res, data) {
- var text = data.message,
- diff = Date.now() - req.ptime;
-
- if (data.meta) {
- text = [message, qs.unescape(qs.stringify(data.meta, ', '))].join(' | ');
- }
-
- res.writeHead(data.code, {
- 'Content-Length': text.length,
- 'Content-Type': 'text/plain'
- });
-
- if (req.method !== 'HEAD') {
- res.write(text);
- }
-
- haibu.emit('balancer:serve', 'info', {
- text: text,
- code: data.code,
- time: diff + 'ms'
- });
-
- res.end();
-};
-
-//
-// ### function close ()
-// Closes this balancer by shutting down the child
-// `HttpProxy` instance.
-//
-Balancer.prototype.close = function () {
- this.httpProxy.close();
-};
-
-//
-// ### function _add (file, callback)
-// #### @file {string} Filename to add to this instance.
-// #### @callback {function} **Optional** Continuation to respond to when complete.
-// Adds the data in the specified `file` to the managed state for
-// this balancer instance.
-//
-Balancer.prototype._add = function (file, callback) {
- var self = this;
-
- fs.readFile(file, function (err, data) {
- if (err) {
- return callback ? callback(err) : null;
- }
-
- try {
- var json = JSON.parse(data.toString()),
- app = self._parseFilename(file);
-
- if (app && app.type) {
- switch (app.type) {
- case 'package':
- self.active[app.name] = self.active[app.name] || {
- drones: []
- };
-
- self.active[app.name].app = json;
- break;
- case 'pid':
- self.active[app.name] = self.active[app.name] || {
- drones: []
- };
-
- self.active[app.name].drones.push({
- pid: json.pid,
- host: json.host,
- port: json.port
- });
- break;
- }
- }
-
- return callback ? callback() : null;
- }
- catch (ex) {
- return callback ? callback(ex) : null;
- }
- });
-};
-
-//
-// ### function _remove (file)
-// #### @file {string} Filename to remove from this instance
-// Removes the data in the specified `file` from the managed state
-// for this instance.
-//
-Balancer.prototype._remove = function (file) {
- var app = this._parseFilename(file), index;
-
- if (app && app.type) {
- switch (app.type) {
- case 'package':
- delete this.active[app.name];
- break;
- case 'pid':
- if (this.active[app.name] && this.active[app.name].drones) {
- index = this.active[app.name].drones.map(function (d) {
- return d.pid;
- }).indexOf(parseInt(app.drone, 10));
-
- this.active[app.name].drones.splice(index, 1);
- }
- break;
- }
- }
-};
-
-//
-// ### function _parseFilename (file)
-// #### @file {string} Filename to parse
-// Parses the data out of the specified `file` to be used
-// in the managed application state for this instance.
-//
-Balancer.prototype._parseFilename = function (file) {
- var base = path.basename(file),
- match, drone, app;
-
- if (matchers.app.test(base)) {
- return {
- type: 'package',
- name: base.match(matchers.app)[1]
- }
- }
- else if (matchers.pid.test(base)) {
- match = base.match(matchers.pid);
- return {
- type: 'pid',
- name: match[1],
- drone: match[2]
- };
- }
-
- return null;
-};
View
63 lib/haibu/balancer/index.js
@@ -1,63 +0,0 @@
-/*
- * index.js: Responsible for balancing across all the instances available to haibu.
- *
- * (C) 2010, Nodejitsu Inc.
- *
- */
-
-var http = require('http'),
- haibu = require('haibu');
-
-//
-// ### Include Exports
-// Export other components in the module
-//
-exports.Balancer = require('./balancer').Balancer;
-
-//
-// ### function createServer (options)
-// #### @options {Object} Options to use when creating this server
-// Creates a server for the haibu `balancer` webservice.
-//
-exports.createServer = function (options, balancer) {
- balancer = balancer || new exports.Balancer(options);
-
- var server = http.createServer(function (request, response) {
- balancer.handle(request, response);
- });
-
- if (options.port) {
- server.listen(options.port);
- }
-
- balancer.once('ready', function (active) {
- server.emit('ready', active);
- });
-
- return server;
-};
-
-//
-// ### function start (options, callback)
-// #### @options {Object} Options to use when starting this module.
-// #### @callback {function} Continuation to respond to when complete.
-// Starts the haibu `balancer` webservice with the specified options.
-//
-exports.start = function (options, callback) {
- function startServer (err) {
- if (err) {
- return callback(err);
- }
-
- var balancer = new exports.Balancer(options),
- server = exports.createServer(options, balancer);
-
- balancer.once('ready', function (active) {
- callback(null, server, balancer, active);
- });
- }
-
- return options.init !== false
- ? haibu.init(options, startServer)
- : startServer();
-};
View
230 lib/haibu/core/config.js
@@ -1,230 +0,0 @@
-/*
- * index.js: Top level module include for config module.
- *
- * (C) 2010, Nodejitsu Inc.
- *
- */
-
-var fs = require('fs'),
- eyes = require('eyes'),
- path = require('path'),
- exec = require('child_process').exec,
- async = require('async'),
- nconf = require('nconf'),
- haibu = require('haibu');
-
-var root = path.join(__dirname, '..', '..', '..'),
- config = module.exports = nconf;
-
-//
-// ### function (options)
-// #### @options {Object} Options to setup for flexibility
-// Sets up configuration options with default options for
-// maximum flexibility in usage.
-//
-function setupOptions (options) {
- options = options || {};
- options.env = options.env || 'development';
- options.data = options.data || {};
- options.config = options.config || {};
- options.config.files = options.config.files || [];
- options.config.namespace = options.config.namespace || options.env;
- return options;
-}
-
-//
-// ### Expose the simple routes for the haibu config API.
-//
-config.addRoutes = function () {
- return function (map) {
- map.post(/\/reload/).bind(function (response, data) {
- //
- // **TODO: _(indexzero)_**: Ensure this request is authenticated.
- //
-
- data = data.config ? data : haibu.config.get('config');
- haibu.config.load(data, function (err) {
- if (err) {
- return response.send(500, {}, { error: err.message });
- }
-
- response.send(200);
- });
- });
- };
-};
-
-//
-// ### function seed (options, callback)
-// #### @options {Object} Options for nconf store.
-// #### @callback {function} Continuation to respond to when complete.
-// Seeds any existing data from `options.files` into a Redis store
-// for distributed use.
-//
-config.seed = function (options, callback) {
- if (!callback) {
- callback = options;
- options = {};
- }
-
- //
- // Setup `options` to be _really_ flexible.
- //
- options = setupOptions(options);
- var store = new nconf.stores.Redis(options.config), keys;
-
- config.loadFiles(options.config.files, function (err, loaded) {
- if (err) {
- return callback(err);
- }
-
- function storeValue (key, next) {
- store.set(key, options.data[key], next);
- }
-
- Object.keys(loaded).forEach(function (key) {
- options.data[key] = loaded[key];
- });
-
- var keys = Object.keys(options.data);
- async.forEach(keys, storeValue, function (err) {
- if (err) {
- return callback(err);
- }
-
- store.set('loaded', true, function (err) {
- store.redis.quit();
- return err ? callback(err) : callback();
- });
- });
- });
-};
-
-//
-// ### function load (options, callback)
-// #### @options {Object} Options for nconf store.
-// #### @callback {function} Continuation to respond to when complete.
-// Basically a complex version of `nconf.load` which will skip the `load`
-// operation when using the memory engine instead of throwing an exception
-// and always be async. Also loads any existing configuration from a remote
-// Redis server into memory for usage with this process.
-//
-config.load = function (options, callback) {
- if (!callback) {
- callback = options;
- options = {};
- }
-
- //
- // Setup `options` to be _really_ flexible.
- //
- options = setupOptions(options);
-
- function setObject (obj) {
- if (!obj) {
- return;
- }
-
- Object.keys(obj).forEach(function (key) {
- config.set(key, obj[key]);
- });
- }
-
- function loadRemote () {
- //
- // Load the haibu configuration, then extend it with extra information
- // read from the nodejitsu config.json.
- //
- var store = new nconf.stores.Redis(options.config);
- store.load(function (err, remote) {
- //
- // Shutdown the temporary Redis store.
- //
- store.redis.quit();
-
- //
- // Handle errors appropriately
- //
- if (err) {
- return callback(err);
- }
- else if (!remote.loaded) {
- return config.seed(options, function (err) {
- return err ? callback(err) : config.load(options, callback);
- });
- }
-
- //
- // Set the cache information in the current Memory store.
- //
- config.set('cache', {
- host: options.config.host,
- port: options.config.port || 6379,
- auth: options.config.auth
- });
-
- //
- // Add any existing remote configuration to the current Memory store.
- //
- setObject(remote);
-
- callback();
- });
- }
-
- function loadAll (err, local) {
- setObject(local);
- return options.config.host ? loadRemote() : callback();
- }
-
- return options.config.files
- ? config.loadFiles(options.config.files, loadAll)
- : loadAll();
-};
-
-//
-// ### function loadFiles (files)
-// #### @files {Array} List of files to load.
-// Loads all the data in the specified `files`.
-//
-config.loadFiles = function (files, callback) {
- if (!files) {
- return callback(null, {});
- }
-
- var allData = {};
-
- function loadFile (file, next) {
- fs.readFile(file, function (err, data) {
- if (err) {
- return next(err);
- }
-
- data = JSON.parse(data.toString());
- Object.keys(data).forEach(function (key) {
- allData[key] = data[key];
- });
-
- next();
- });
- }
-
- async.forEach(files, loadFile, function (err) {
- return err ? callback(err) : callback(null, allData);
- });
-};
-
-config.set('directories', {
- apps: path.join(root, 'local'),
- log: path.join(root, 'log'),
- packages: path.join(root, 'packages'),
- running: path.join(root, 'running'),
- tmp: path.join(root, 'tmp')
-});
-
-config.set('npm', {
- log: path.join(root, 'log', 'npm.log'),
- out: path.join(root, 'log', 'npm.out')
-});
-
-config.set('requiredNodeVersion', '0.4.5');
View
109 lib/haibu/core/process-store.js
@@ -1,109 +0,0 @@
-/*
- * process-store.js: Keeps track of process files `app.package.json`, `app.pid.json`, etc.
- *
- * (C) 2010, Nodejitsu Inc.
- *
- */
-
-var util = require('util'),
- fs = require('fs'),
- events = require('events'),
- path = require('path'),
- watch = require('watch'),
- haibu = require('haibu');
-
-//
-// ### function ProcessStore ()
-// Constructor function for the ProcessStore responsible for
-// managing persistent `app.package.json` and `app.pid.json`
-// files in `haibu`.
-//
-var ProcessStore = exports.ProcessStore = function () {
- events.EventEmitter.call(this);
-
- this.runningDir = haibu.config.get('directories:running');
- this.active = {};
-};
-
-//
-// Inherit from `events.EventEmitter`
-//
-util.inherits(ProcessStore, events.EventEmitter);
-
-//
-// ### function save (name, data, callback)
-// #### @name {string} Application name for the file to save
-// #### @data {Object} Data to save in the specified file
-// #### @callback {function} Continuation to respond to when complete.
-// Saves the specified `data` into an appropriate `package.json` or
-// `pid.json` file for `haibu` on this machine.
-//
-ProcessStore.prototype.save = function (name, data, callback) {
- //
- // Save the data to the correct filepath for this type of data.
- //
- var filepath = this._filename(name, data);
- fs.writeFile(filepath, JSON.stringify(data, null, 2), function (err) {
- return err ? callback(err) : callback(null, filepath);
- });
-};
-
-//
-// ### function remove (name, data, callback)
-// #### @name {string} Application name for the file to remove.
-// #### @data {Object} Data in the specified file to remove.
-// #### @callback {function} Continuation to respond to when complete.
-// Removes the file with `data` for the application with the specified `name`.
-//
-ProcessStore.prototype.remove = function (name, data, callback) {
- //
- // Remove the file, ignoring any errors that are returned.
- //
- var filepath = this._filename(name, data);
- fs.unlink(filepath, function (err) {
- callback();
- });
-};
-
-//
-// ### function monitor ()
-// Starts monitoring all files in the `runningDir` for this
-// ProcessStore instance.
-//
-ProcessStore.prototype.monitor = function () {
- var self = this;
-
- watch.createMonitor(this.runningDir, function (monitor) {
- self.emit('load', monitor.files);
-
- monitor.on('created', function (file, curr, prev) {
- if (curr.isFile()) {
- self.emit('created', file);
- }
- });
-
- monitor.on('removed', function (file, stats) {
- if (stats.isFile()) {
- self.emit('removed', file);
- }
- });
- });
-};
-
-//
-// ### private function _filename (name, data)
-// #### @name {string} Application name for the filename.
-// #### @data {Object} Data in the specified filename to generate.
-// Generates the appropriate filename (e.g. `app.package.json` or
-// `app.12345.json`) for the specified `name` and `data`.
-//
-ProcessStore.prototype._filename = function (name, data) {
- var ext = data.pid || (data._id, 'package'),
- filename = [name, ext, 'json'].join('.');
-
- //
- // Save information about applications at `appname.package.json`
- // and save pid information at `appname.pid.json`
- //
- return filepath = path.join(this.runningDir, filename);
-};
View
218 lib/haibu/core/spawner.js
@@ -1,218 +0,0 @@
-/*
- * spawner.js: Responsible for checking, downloading, and spawning drones
- * inside of carapace objects.
- *
- * (C) 2010, Nodejitsu Inc.
- *
- */
-
-var sys = require('sys'),
- fs = require('fs'),
- colors = require('colors'),
- path = require('path'),
- eyes = require('eyes'),
- forever = require('forever'),
- events = require('events'),
- haibu = require('haibu');
-
-//
-// ### Port Management Constants
-// TODO (indexzero): Stop using these / make them more intelligent
-// and / or configurable.
-//
-var ports = {},
- lastPort = 8000;
-
-//
-// ### function Spawner (options)
-// #### @options {Object} Options for this instance.
-// Constructor function for the Spawner object. Controls the
-// low-level aspects of the life-cycle of applications running
-// inside of haibu.
-//
-var Spawner = exports.Spawner = function (options) {
- options = options || {};
-
- this.maxRestart = options.maxRestart;
- this.minUptime = options.minUptime;
- this.silent = options.silent || false;
- this.appsDir = options.appsDir || haibu.config.get('directories:apps');
- this.packageDir = options.packageDir || haibu.config.get('directories:packages');
- this.host = options.host || '127.0.0.1';
-};
-
-
-//
-// ### function bindPort (app)
-// #### @app {App} Application to bind a port for
-// Gets a free port for the requesting application to bind to.
-//
-// Remark (indexzero): Move this into carapace with shared data for this instance ... ALFRED!!!
-//
-Spawner.prototype.bindPort = function (app) {
- lastPort += 1;
- var port = lastPort;
- ports[port] = app;
- return port;
-};
-
-//
-// ### function releasePort (port)
-// #### @port {int} The port to relase.
-// Releases the port if it is bound to an application.
-//
-// Remark (indexzero): Move this into carapace with shared data for this instance ... ALFRED!!!
-//
-Spawner.prototype.releasePort = function (port) {
- if (ports[port]) {
- delete ports[port];
- return true;
- }
-
- return false;
-};
-
-//
-// ### function trySpawn (app, callback)
-// #### @app {App} Application to attempt to spawn on this server.
-// #### @callback {function} Continuation passed to respond to.
-// Attempts to spawn the application with the package.json manifest
-// represented by @app, then responds to @callback.
-//
-Spawner.prototype.trySpawn = function (app, callback) {
- var self = this, repo;
- repo = app instanceof haibu.repository.Repository ? app : haibu.repository.create(app);
- repo.bootstrap(function (err, existed) {
- if (err) {
- return callback(err);
- }
- else if (existed) {
- return self.spawn(repo, callback);
- }
-
- repo.init(function (err, inited) {
- if (err) {
- return callback(err);
- }
-
- self.spawn(repo, callback);
- });
- });
-};
-
-Spawner.prototype.spawnOptions = function (repo, host, port) {
- return {
- carapace: path.join(__dirname, '..', '..', '..', 'bin', 'carapace'),
- drone: [repo.startScript, host, port]
- };
-};
-
-//
-// ### function spawn (repo, callback)
-// #### @repo Repository object initialized with target application to spawn.
-// #### @callback Continuation passed to respond to.
-// Does the heavy lifting for creating a Forever Monitor to be managed by haibu.
-// Reads configuration from haibu, and the repository and calls the appripriate
-// internal APIs.
-//
-Spawner.prototype.spawn = function (repo, callback) {
- haibu.emit('spawn:setup', 'info', { app: repo.app.id, username: repo.app.user });
-
- var self = this, drone, options, port, result,
- foreverOptions, meta, errState, errMsg = '', responded;
-
- port = this.bindPort();
-
- // Setup meta logging information
- meta = { app: repo.app.name, user: repo.app.user };
-
- Object.keys(haibu._plugins).forEach(function (plugin) {
- if (!options && haibu._plugins[plugin] && haibu._plugins[plugin].spawnOptions) {
- options = haibu._plugins[plugin].spawnOptions(repo, self.host, port);
- }
- });
-
- if (!options) {
- options = this.spawnOptions(repo, this.host, port);
- }
-
- //
- // Before we attempt to spawn, let's check if the startPath actually points to a file
- // Trapping this specific error is useful as the error indicates an incorrect
- // scripts.start property in the package.json
- //
- fs.stat(repo.startScript, function (err, stats) {
- if (err) {
- return callback(new Error('package.json error: ' + 'can\'t find starting script: ' + repo.app.scripts.start));
- }
-
- haibu.emit('spawn:start', 'info', { options: options.drone.join(' '), app: meta.app, user: meta.user });
- foreverOptions = {
- minUptime: self.minUptime,
- options: options.drone,
- silent: true,
- spawnWith: {
- cwd: repo.homeDir
- }
- };
-
- foreverOptions.forever = !self.maxRestart;
- if (self.maxRestart) {
- foreverOptions.max = self.maxRestart;
- }
-
- drone = new forever.Monitor(options.carapace, foreverOptions);
-
- //
- // TODO (indexzero): This output should be in its own Loggly input (i.e. log.user instead of log.drone)
- //
- drone.on('stdout', function (data) {
- haibu.emit('drone:stdout', 'info', data.toString(), meta);
- });
-
- drone.on('stderr', function (data) {
- if (!responded) {
- errMsg += data + '\n';
- }
-
- haibu.emit('drone:stderr', 'error', data.toString(), meta);
- });
-
- drone.on('error', function (data) {
- haibu.emit('drone:err', 'error', data.toString(), meta);
- });
-
-
- drone.once('start', function (monitor, file, data) {
- result = {
- monitor: monitor,
- process: monitor.child,
- drone: data
- };
-
- result.drone.port = port;
- result.drone.host = self.host;
- });
-
- drone.on('exit', function () {
- errState = true;
- });
-
- //
- // Wait briefly to see if the application exits immediately.
- //
- setTimeout(function () {
- var error;
- if (errState) {
- result.monitor.stop();
- error = new Error('Application failed to start on first attempt');
- error.message = errMsg;
- return callback(error);
- }
-
- callback(null, result);
- }, 200);
-
- drone.start();
- });
-};
View
164 lib/haibu/drone/client.js
@@ -1,164 +0,0 @@
-/*
- * client.js: API Client for the haibu Drone API.
- *
- * (C) 2010, Nodejitsu Inc.
- *
- */
-
-var sys = require('sys'),
- fs = require('fs'),
- path = require('path'),
- eyes = require('eyes'),
- request = require('request'),
- haibu = require('haibu');
-
-// Failure HTTP Response codes based
-// off of `/lib/haibu/drone/service.js`
-var failCodes = {
- 400: 'Bad Request',
- 404: 'Item not found',
- 500: 'Internal Server Error'
-};
-
-// Success HTTP Response codes based
-// off of `/lib/haibu/drone/service.js`
-var successCodes = {
- 200: 'OK'
-};
-
-//
-// ### function Client (options)
-// #### @options {Object} Options to use for this instance.
-// Constructor function for the Client to the haibu Haibu server.
-//
-var Client = exports.Client = function (options) {
- if (!options.host) {
- throw new Error('options.host is required.');
- }
-
- //
- // TODO (indexzero): Configure the drone port globally somewhere.
- //
- this.options = options;
- this.options.port = this.options.port || 9000;
-};
-
-//
-// ### function get (name, callback)
-// #### @name {string} name of the application to get from the Haibu server.
-// #### @callback {function} Continuation to pass control back to when complete.
-// Gets the data about all the drones for the app with the specified `name`
-// on the remote Haibu server.
-//
-Client.prototype.get = function (name, callback) {
- this._request('GET', '/drones/' + name, callback, function (res, result) {
- callback(null, result);
- });
-};
-
-//
-// ### function start (app, callback)
-// #### @app {Object} Application to start on the Haibu server.
-// #### @callback {function} Continuation to pass control back to when complete.
-// Starts the the app with the specified `app.name` on the remote Haibu server.
-//
-Client.prototype.start = function (app, callback) {
- this._request('POST', '/drones/' + app.name + '/start', { start: app }, callback, function (res, result) {
- callback(null, result);
- });
-};
-
-//
-// ### function stop (name, callback)
-// #### @name {string} Name of the application to stop on the Haibu server.
-// #### @callback {function} Continuation to pass control back to when complete.
-// Stops the application with the specified `name` on the remote Haibu server.
-//
-Client.prototype.stop = function (name, callback) {
- this._request('POST', '/drones/' + name + '/stop', { stop: { name: name } }, callback, function (res, result) {
- callback(null, null);
- });
-};
-
-//
-// ### function restart (name, callback)
-// #### @name {string} Name of the application to restart on the Haibu server.
-// #### @callback {function} Continuation to pass control back to when complete.
-// Restarts the application with the specified :id on the remote Haibu server.
-//
-Client.prototype.restart = function (name, callback) {
- this._request('POST', '/drones/' + name + '/restart', { restart: { name: name } }, callback, function (res, result) {
- callback(null, result.drones);
- });
-};
-
-//
-// ### function clean (app, callback)
-// #### @app {Object} Application to clean on the Haibu server.
-// #### @callback {function} Continuation to pass control back to when complete.
-//
-Client.prototype.clean = function (app, callback) {
- this._request('POST', '/drones/' + app.name + '/clean', app, callback, function (res, result) {
- callback(null, result);
- });
-};
-
-//
-// ### @remoteUri {string}
-// Full URI for the remote Haibu server this client
-// is configured to request against.
-//
-Client.prototype.__defineGetter__('remoteUri', function () {
- return 'http://' + this.options.host + ':' + this.options.port;
-});
-
-//
-// ### @private _request (method, uri, [body], callback, success)
-// #### @method {string} HTTP verb to request with
-// #### @uri {string} Path to request on the Haibu server
-// #### [@body] {Object} JSON object to use as the body of the request
-// #### @callback {function} Continuation to short-circuit to if request is unsuccessful.
-// #### @success {function} Continuation to call if the request is successful
-// Core method for making requests against the haibu Drone API. Flexible with respect
-// to continuation passing given success and callback.
-//
-Client.prototype._request = function (method, uri /* variable arguments */) {
- var options, args = Array.prototype.slice.call(arguments),
- success = args.pop(),
- callback = args.pop(),
- body = typeof args[args.length - 1] === 'object' && args.pop();
-
- options = {
- method: method || 'GET',
- uri: this.remoteUri + uri,
- headers: {
- 'Content-Type': 'application/json'
- }
- };
-
- if (body) {
- options.body = JSON.stringify(body);
- }
-
- request(options, function (err, response, body) {
- if (err) {
- return callback(err);
- }
-
- var error, result, statusCode = response.statusCode.toString();
- try {
- result = JSON.parse(body);
- }
- catch (ex) {
- // Ignore Errors
- }
-
- if (Object.keys(failCodes).indexOf(statusCode) !== -1) {
- error = new Error('haibu Error (' + statusCode + '): ' + failCodes[statusCode]);
- error.result = result;
- return callback(error);
- }
-
- success(response, result);
- });
-};
View
231 lib/haibu/drone/drone.js
@@ -1,231 +0,0 @@
-/*
- * drone.js: Controls the application lifetime for nodejs applications on a single server.
- *
- * (C) 2010, Nodejitsu Inc.
- *
- */
-
-var sys = require('sys'),
- fs = require('fs'),
- path = require('path'),
- colors = require('colors'),
- async = require('async'),
- haibu = require('haibu');
-
-//
-// ### function Drone (options)
-// #### @options {Object} Options for this instance.
-// Constructor function for the Drone resource.
-//
-var Drone = exports.Drone = function (options) {
- this.apps = {};
- this.appsDir = options.appsDir || haibu.config.get('directories:apps');
- this.ipAddress = options.ipAddress;
- this.processes = new haibu.ProcessStore(options);
- this.spawner = new haibu.Spawner(options);
-};
-
-//
-// ### function start (app, callback)
-// #### @app {App} Application to start in this instance.
-// #### @callback {function} Continuation passed to respond to.
-// Attempts to spawn the @app by passing it to the spawner.
-//
-Drone.prototype.start = function (app, callback) {
- var self = this;
- this.spawner.trySpawn(app, function (err, result) {
- if (err) {
- return callback(err, false);
- }
- else if (typeof result === 'undefined') {
- return callback(new Error('Unknown error from Spawner.'));
- }
-
- var response = {
- drone: result.drone
- };
-
- self._add(app, {
- process: result.drone,
- monitor: result.monitor
- }, function (err) {
- //
- // If there is an error persisting the drone
- // to disk then just respond anyway since the
- // drone process started correctly.
- //
-
- callback(null, response);
- });
- });
-};
-
-//
-// ### function stop (name, callback)
-// #### @name {string} Name of the application to stop (i.e. app.name).
-// #### @callback {function} Continuation passed to respond to.
-// Stops all drones with app.name === name managed by this instance
-//
-Drone.prototype.stop = function (name, callback) {
- if (typeof this.apps[name] === 'undefined') {
- return callback(new Error('Cannot stop application that is not running.'));
- }
-
- var self = this,
- app = this.apps[name],
- keys = Object.keys(app.drones),
- results = [];
-
- function removeAndSave (key, next) {
- app.drones[key].monitor.stop();
- results.push(app.drones[key].process);
- self._remove(app, app.drones[key], function () {
- next();
- });
- }
-
- async.forEach(keys, removeAndSave, function () {
- callback(null, results);
- });
-};
-
-//
-// ### function restart (name, callback)
-// #### @name {string} Name of the application to restart (i.e. app.name).
-// Restarts all drones with app = name managed by this instance and
-// responds with the list of processes of new processes.
-//
-Drone.prototype.restart = function (name, callback) {
- if (typeof this.apps[name] === 'undefined') {
- return callback(new Error('Cannot restart application that is not running.'));
- }
-
- var self = this,
- app = this.apps[name],
- keys = Object.keys(app.drones),
- processes = [];
-
- function restartAndSave (key, next) {
- var existing = app.drones[key].process.pid;
-
- app.drones[key].monitor.once('save', function (file, data) {
- self._update(app, existing, data.pid, function () {
- processes.push(app.drones[data.pid].process);
- next();
- });
- });
-
- app.drones[key].monitor.restart();
- }
-
- async.forEach(keys, restartAndSave, function () {
- callback(null, processes);
- });
-};
-
-//
-// ### function clean (app)
-// #### @app {App} Application to start in this instance.
-// #### @callback {function} Continuation passed to respond to.
-// Stops the potentially running application then removes all dependencies
-// and source files associated with the application.
-//
-Drone.prototype.clean = function (app, callback) {
- var self = this,
- repo = haibu.repository.create(app);
-
- this.stop(app.name, function (err, result) {
- // Ignore errors and continue cleaning
- repo.clean(function (err) {
- if (err) {
- return callback(err);
- }
-
- callback(null, repo);
- });
- });
-};
-
-//
-// ### function show (name)
-// #### @name {string} Name of the application to show (i.e. app.name)
-// Shows details for drone with `name` managed by this instance
-//
-Drone.prototype.show = function (name) {
- return this.apps[name];
-};
-
-//
-// ### function list ()
-// Lists details about all drones managed by this instance
-//
-Drone.prototype.list = function () {
- return this.apps;
-};
-
-//
-// ### function _add (app, drone)
-// #### @app {App} Application for which to attach @drone to
-// #### @drone {Object} Drone to attach to @app
-// Attaches the specified drone to the application in
-// this instance.
-//
-Drone.prototype._add = function (app, drone, callback) {
- var self = this;
-
- function saveDrone (err) {
- self.apps[app.name].drones[drone.process.pid] = drone;
- self.processes.save(app.name, drone.process, callback);
- }
-
- if (typeof this.apps[app.name] === 'undefined') {
- this.apps[app.name] = {
- app: app,
- drones: {}
- };
-
- return this.processes.save(app.name, app, saveDrone);
- }
-
- saveDrone();
-};
-
-//
-// ### function _remove (a, drone)
-// #### @a {Object} Wrapped {app, drone} tuple set in _add
-// #### @drone {Object} Drone metadata to remove from the specified application
-// Removes the specified drone object from the bookkeeping of this instance.
-//
-Drone.prototype._remove = function (a, drone, callback) {
- var self = this,
- app = this.apps[a.app.name];
-
- delete app.drones[drone.process.pid];
-
- this.processes.remove(a.app.name, drone.process, function () {
- //
- // If there are no more drones for this app
- // delete the entire app
- //
- if (Object.keys(app.drones).length === 0) {
- delete self.apps[a.app.name];
- return self.processes.remove(a.app.name, app, callback);
- }
-
- callback();
- });
-};
-
-Drone.prototype._update = function (a, existing, update, callback) {
- var self = this,
- app = this.apps[a.app.name],
- drone = app.drones[existing];
-
- this.processes.remove(a.app.name, drone.process, function () {
- delete app.drones[drone.process.pid];
- drone.process.pid = update;
- app.drones[update] = drone;
-
- self.processes.save(a.app.name, drone.process, callback);
- });
-};
View
47 lib/haibu/drone/index.js
@@ -1,47 +0,0 @@
-/*
- * index.js: Top-level include for the drone module.
- *
- * (C) 2010, Nodejitsu Inc.