Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

added the inittab format

  • Loading branch information...
commit 9af1881212555290f87d6608f7bffc45b8287bea 1 parent 5ec0f82
Wong Liang Zan authored

Showing 2 changed files with 207 additions and 0 deletions. Show diff stats Hide diff stats

  1. +203 0 lib/export/inittab.js
  2. +4 0 lib/exporter.js
203 lib/export/inittab.js
... ... @@ -0,0 +1,203 @@
  1 +var fs = require('fs')
  2 + , path = require('path')
  3 + , exec = require('child_process').exec
  4 + , _ = require('underscore')
  5 + , Mustache = require('mustache')
  6 + , winston = require('winston').cli()
  7 + , async = require('async')
  8 + , parser = require('../parser');
  9 +
  10 +/*
  11 + * inittab
  12 + *
  13 + * exports the procfile into the inittab format
  14 + *
  15 + */
  16 +var inittab = exports;
  17 +
  18 +/*
  19 + * public functions
  20 + */
  21 +inittab.writeTemplates = function(processes, cmdOptions, callback) {
  22 + var app = cmdOptions.app;
  23 + var user = cmdOptions.user;
  24 + var logRoot = cmdOptions.log || ('/var/log/' + cmdOptions.app);
  25 +
  26 + return async.series([
  27 + function(checkLocationCallback) {
  28 + checkLocation(cmdOptions, checkLocationCallback);
  29 + },
  30 + function(makeDirCallback) {
  31 + makeDirectories([logRoot], makeDirCallback);
  32 + },
  33 + function(chownCallback) {
  34 + chownDirectory(user, logRoot, chownCallback);
  35 + }], function(err, results) {
  36 + if (err) {
  37 + return callback(err);
  38 + } else {
  39 + return buildMasterTemplate({
  40 + app: app,
  41 + processes: buildProcessOptions(processes, logRoot, cmdOptions),
  42 + writePath: path.normalize(cmdOptions.location),
  43 + templateOpt: cmdOptions.template
  44 + }, callback);
  45 + }
  46 + });
  47 +};
  48 +
  49 +/*
  50 + * builds the process options
  51 + *
  52 + * @param {obj} obj of process key and commands
  53 + * @param {string} log root path
  54 + * @param {obj} obj of command line options
  55 + * @return {array} array of option objects
  56 + */
  57 +function buildProcessOptions(processes, logRoot, cmdOptions) {
  58 + return _.flatten(_.map(_.keys(processes), function(procKey) {
  59 + var concurrentCount = parser.parseConcurrencyOpts(cmdOptions)[procKey] || 1;
  60 + return _.map(_.range(concurrentCount), function(index) {
  61 + return {
  62 + id: getID(procKey, index),
  63 + user: cmdOptions.user,
  64 + port: cmdOptions.port,
  65 + processCommand: processes[procKey],
  66 + logRoot: logRoot,
  67 + processName: procKey,
  68 + num: index
  69 + };
  70 + });
  71 + }));
  72 +}
  73 +
  74 +/*
  75 + * builds the process templates
  76 + *
  77 + * @param {obj} obj of options
  78 + * @callback {err}
  79 + */
  80 +function buildMasterTemplate(opts, callback) {
  81 + var viewOpt = {
  82 + app: opts.app,
  83 + processes: opts.processes
  84 + };
  85 +
  86 + renderTemplate(templateFilePath('master', opts.templateOpt), viewOpt, function(err, renderedOutput) {
  87 + if (err) {
  88 + return callback(err.message);
  89 + } else {
  90 + return fs.writeFile(opts.writePath, renderedOutput, function(err) {
  91 + if (err) {
  92 + return callback(err.message);
  93 + } else {
  94 + return callback(null);
  95 + }
  96 + });
  97 + }
  98 + });
  99 +}
  100 +
  101 +/* returns the template path given the template name
  102 + * overrides with command line template option if given
  103 + *
  104 + * @param {string} template name. currently only master.conf, process.conf, process_master.conf
  105 + * @param {string} optional template path. overrides the default path
  106 + * @return {string} path to template
  107 + */
  108 +function templateFilePath(templateName, templateOpt) {
  109 + var parsedTemplateOpt = parser.parseTemplateOpts(templateOpt);
  110 + var tmpPath = parsedTemplateOpt[templateName];
  111 + if (tmpPath) {
  112 + if (!tmpPath.match(/^\/.*/)) {
  113 + return path.normalize(process.cwd() + '/' + tmpPath);
  114 + } else {
  115 + return path.normalize(tmpPath);
  116 + }
  117 + } else {
  118 + return path.normalize(__dirname + '/../../templates/inittab/' + templateName
  119 + + '.mustache');
  120 + }
  121 +}
  122 +
  123 +/*
  124 + * renders the template
  125 + *
  126 + * @param {string} path to run template
  127 + * @param {obj} object of options
  128 + * @callback {err} err, {string} rendered template
  129 + */
  130 +function renderTemplate(templatePath, viewOpts, callback) {
  131 + templateContent(templatePath, function(err, content) {
  132 + if (err) {
  133 + return callback(err, null);
  134 + } else {
  135 + return callback(null, Mustache.to_html(content, viewOpts));
  136 + }
  137 + });
  138 +}
  139 +
  140 +/*
  141 + * reads the mustache template from file
  142 + *
  143 + * @param {string} path to run template
  144 + * @callback {err} err, (string) mustache template
  145 + */
  146 +function templateContent(templatePath, callback) {
  147 + fs.readFile(templatePath, 'utf8', callback);
  148 +}
  149 +
  150 +/*
  151 + * returns the inittab id
  152 + *
  153 + * @param {string} processName
  154 + * @param {int} index
  155 + * @return {string} inittab id
  156 + */
  157 +function getID(processName, index) {
  158 + return processName.toUpperCase() + index;
  159 +}
  160 +
  161 +/*
  162 + * creates the required directories
  163 + *
  164 + * @param {array} array of directories. created in order
  165 + * @callback {err} err
  166 + */
  167 +function makeDirectories(dirs, callback) {
  168 + var mkdir = function(dir, mkCallback) {
  169 + exec('mkdir -p ' + dir, function(err, stdout, stderr) {
  170 + return mkCallback(err);
  171 + });
  172 + };
  173 +
  174 + async.forEach(dirs, mkdir, callback);
  175 +}
  176 +
  177 +/*
  178 + * command to chown a file
  179 + * need to run it manually as i don't have the uid/gid
  180 + *
  181 + * @param (string) user
  182 + * @param (string} path to chown
  183 + * @callback {err} err
  184 + */
  185 +function chownDirectory(user, filePath, callback) {
  186 + var cmd = 'chown ' + user + ' ' + filePath;
  187 + exec(cmd, callback);
  188 +}
  189 +
  190 +/*
  191 + * checks if the location is entered
  192 + * it is required for runit
  193 + *
  194 + * @param {obj} obj of command line options
  195 + * @callback {err} err
  196 + */
  197 +function checkLocation(cmdOptions, callback) {
  198 + if (typeof cmdOptions.location === 'undefined') {
  199 + return callback(new Error('Inittab requires a location argument'));
  200 + } else {
  201 + return callback(null);
  202 + }
  203 +}
4 lib/exporter.js
... ... @@ -1,5 +1,6 @@
1 1 var winston = require('winston').cli()
2 2 , runit = require('./export/runit')
  3 + , inittab = require('./export/inittab')
3 4 , upstart = require('./export/upstart');
4 5
5 6 /*
@@ -29,6 +30,9 @@ exporter.writeTemplates = function(processes, cmdOptions, callback) {
29 30 case 'upstart':
30 31 return upstart.writeTemplates(processes, cmdOptions, callback);
31 32 break;
  33 + case 'inittab':
  34 + return inittab.writeTemplates(processes, cmdOptions, callback);
  35 + break;
32 36 default:
33 37 return callback(new Error('Unknown format. Please select inittab, runit, '
34 38 + 'supervisord, upstart or monit'));

0 comments on commit 9af1881

Please sign in to comment.
Something went wrong with that request. Please try again.