UNPKG

7.85 kBJavaScriptView Raw
1// Generated by CoffeeScript 1.3.3
2(function() {
3 var Cron, PREFIX, Service, spawn,
4 __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
5
6 spawn = require('child_process').spawn;
7
8 Cron = require("./Cron");
9
10 PREFIX = "ggg";
11
12 Service = (function() {
13
14 Service.prototype.log = function(msg) {
15 return this.parent.log(this.host, msg);
16 };
17
18 Service.prototype.runCommand = function(commands, cb) {
19 if (this.isLocal) {
20 return this.localCommand("bash", ["-c", commands], cb);
21 } else {
22 return this.sshCommand(commands, cb);
23 }
24 };
25
26 Service.prototype.sshCommand = function(commands, cb) {
27 return this.localCommand('ssh', ["-o StrictHostKeyChecking=no", this.host, commands], function(err) {
28 if (err != null) {
29 return cb(new Error("SSH Command Failed"));
30 }
31 return cb();
32 });
33 };
34
35 Service.prototype.localCommand = function(command, args, cb) {
36 var proc,
37 _this = this;
38 proc = spawn(command, args, {
39 env: process.env
40 });
41 proc.stdout.on('data', function(data) {
42 return _this.log(data.toString().replace(/\n$/, ""));
43 });
44 proc.stderr.on('data', function(data) {
45 return _this.log(data.toString().replace(/\n$/, ""));
46 });
47 proc.on('exit', function(code) {
48 if (code) {
49 return cb(new Error("Command Failed"));
50 }
51 return cb();
52 });
53 return proc;
54 };
55
56 function Service(name, repoName, config, parent, isLocal) {
57 this.name = name;
58 this.repoName = repoName;
59 this.config = config;
60 this.parent = parent;
61 this.isLocal = isLocal != null ? isLocal : false;
62 this.sshCommand = __bind(this.sshCommand, this);
63
64 this.runCommand = __bind(this.runCommand, this);
65
66 this.id = this.repoName + "_" + this.name;
67 this.repoDir = "$HOME/" + PREFIX + "/" + this.id;
68 this.historyFile = "$HOME/" + PREFIX + "/" + this.id + "-history.txt";
69 this.serverUser = this.config.getUser();
70 this.hookFile = "" + this.repoDir + "/.git/hooks/post-receive";
71 this.logFile = "" + this.repoDir + "/ggg.log";
72 this.upstartFile = "/etc/init/" + this.id + ".conf";
73 if (!this.config.getStart()) {
74 this.noUpstart = true;
75 }
76 if (this.isLocal) {
77 this.host = "localhost";
78 this.repoDir = "" + process.env.HOME + "/" + PREFIX + "/" + this.id;
79 this.repoUrl = this.repoDir;
80 } else {
81 this.host = this.config.getHost();
82 this.repoUrl = "ssh://" + this.host + "/~/" + PREFIX + "/" + this.id;
83 }
84 }
85
86 Service.prototype.create = function(cb) {
87 var createRemoteScript, cron, cronConfig, cronScript, hookScript, upstartScript;
88 this.log(" - id: " + this.id);
89 this.log(" - repo: " + this.repoDir);
90 this.log(" - remote: " + this.repoUrl);
91 this.log(" - start: " + (this.config.getStart()));
92 this.log(" - install: " + (this.config.getInstall()));
93 upstartScript = "";
94 if (!this.noUpstart) {
95 upstartScript = this.makeUpstartScript();
96 }
97 hookScript = this.makeHookScript();
98 cronConfig = this.config.getCron();
99 cronScript = '';
100 if (cronConfig) {
101 cron = new Cron(cronConfig, this.id, this.repoDir, this.serverUser);
102 cronScript = cron.buildCron();
103 }
104 createRemoteScript = this.makeCreateScript(upstartScript, hookScript, cronScript);
105 return this.runCommand(createRemoteScript, function(err) {
106 if (err != null) {
107 return cb(err);
108 }
109 return cb();
110 });
111 };
112
113 Service.prototype.makeUpstartScript = function() {
114 return "description '" + this.id + "'\nstart on [2345]\nstop on [!2345]\nlimit nofile 10000 15000\nrespawn\nrespawn limit 5 5 \nexec su " + this.serverUser + " -c 'cd " + this.repoDir + " && " + (this.config.getStart()) + "' >> " + this.logFile + " 2>&1";
115 };
116
117 Service.prototype.makeHookScript = function() {
118 return "read oldrev newrev refname\necho 'GOGOGO checking out:'\necho \\$newrev\necho \\`date\\` - \\$newrev >> " + this.historyFile + "\ncd " + this.repoDir + "/.git\nGIT_WORK_TREE=" + this.repoDir + " git reset --hard \\$newrev || exit 1;";
119 };
120
121 Service.prototype.makeCreateScript = function(upstart, hook, cronInstallScript) {
122 var upstartInstall;
123 upstartInstall = "";
124 if (upstart) {
125 upstartInstall = "echo \"" + upstart + "\" | sudo tee " + this.upstartFile;
126 }
127 return "echo '\nCREATING...'\nmkdir -p " + this.repoDir + "\ncd " + this.repoDir + "\necho \"Locating git\"\nwhich git \nif (( $? )); then\n echo \"Could not locate git\"\n exit 1\nfi\ngit init\ngit config receive.denyCurrentBranch ignore\n\n" + upstartInstall + "\n\necho \"" + hook + "\" > " + this.hookFile + "\nchmod +x " + this.hookFile + "\necho \"[√] created\"\n" + cronInstallScript;
128 };
129
130 Service.prototype.deploy = function(branch, cb) {
131 var _this = this;
132 this.log(" - name: " + this.name);
133 this.log(" - server: " + this.host);
134 this.log(" - branch: " + branch);
135 return this.create(function(err) {
136 if (err != null) {
137 return cb(err);
138 }
139 _this.log("\nPUSHING");
140 return _this.localCommand("git", ["push", _this.repoUrl, branch, "-f"], function(err) {
141 var installCommand;
142 if (err != null) {
143 return cb(err);
144 }
145 _this.log("[√] pushed");
146 installCommand = _this.makeInstallCommand() + "\n" + _this.makeRestartCommand();
147 return _this.runCommand(installCommand, function(err) {
148 var command, kill;
149 if (err != null) {
150 return cb(err);
151 }
152 command = _this.serverLogs(10, function() {});
153 kill = function() {
154 command.kill();
155 return cb();
156 };
157 return setTimeout(kill, 2000);
158 });
159 });
160 });
161 };
162
163 Service.prototype.makeInstallCommand = function() {
164 return "echo '\nINSTALLING'\ncd " + this.repoDir + "\n" + (this.config.getInstall()) + " || exit 1;\necho '[√] installed'";
165 };
166
167 Service.prototype.makeRestartCommand = function() {
168 if (this.noUpstart) {
169 return "";
170 }
171 return "echo '\nRESTARTING'\nsudo stop " + this.id + "\nsudo start " + this.id + "\necho '[√] restarted'";
172 };
173
174 Service.prototype.restart = function(cb) {
175 if (this.noUpstart) {
176 return this.log("nothing to restart");
177 }
178 this.log("RESTARTING");
179 return this.runCommand(this.makeRestartCommand(), cb);
180 };
181
182 Service.prototype.stop = function(cb) {
183 if (this.noUpstart) {
184 return this.log("nothing to stop");
185 }
186 this.log("STOPPING");
187 return this.runCommand("sudo stop " + this.id + ";", cb);
188 };
189
190 Service.prototype.start = function(cb) {
191 if (this.noUpstart) {
192 return this.log("nothing to start");
193 }
194 this.log("STARTING");
195 return this.runCommand("sudo start " + this.id + ";", cb);
196 };
197
198 Service.prototype.serverLogs = function(lines, cb) {
199 this.log("Tailing " + this.logFile + "... Control-C to exit");
200 this.log("-------------------------------------------------------------");
201 return this.runCommand("tail -n " + lines + " -f " + this.logFile, cb);
202 };
203
204 Service.prototype.getHistory = function(revisions, cb) {
205 this.log("Retrieving last " + revisions + " deploys, most recent first!");
206 this.log("-------------------------------------------------------------");
207 return this.runCommand("tail -n " + revisions + " " + this.historyFile + " | tac", cb);
208 };
209
210 return Service;
211
212 })();
213
214 module.exports = Service;
215
216}).call(this);