1 | fs = require "fs"
|
2 | os = require "os"
|
3 | url = require "url"
|
4 | net = require "net"
|
5 | http = require "http"
|
6 | nodePath = require "path"
|
7 | shell = require "shelljs"
|
8 | colors = require "colors"
|
9 | utils = require "../lib/utils"
|
10 | {logger} = utils
|
11 | {template} = require "underscore"
|
12 | {exec, spawn} = require "child_process"
|
13 | {Socket} = net
|
14 |
|
15 | log = logger "server"
|
16 |
|
17 |
|
18 | unless fs.existsSync
|
19 | fs.existsSync = nodePath.existsSync
|
20 |
|
21 | module.exports = class Server
|
22 |
|
23 | SERVER_MANIFEST_FILE = nodePath.join process.env.HOME, ".kd", "server.json"
|
24 | SERVER_RABBIT_BIN = nodePath.join process.env.HOME, ".kd", "bin", "server"
|
25 | SERVER_RABBIT_ZIP = nodePath.join os.tmpDir(), "server.zip"
|
26 | SERVER_RABBIT_BIN_URL= "http://arsln.org/rabbit_mac_x86.zip"
|
27 |
|
28 | help: "Starts a Koding server."
|
29 |
|
30 | alias:
|
31 | run: "start"
|
32 |
|
33 | defaultCommand: "start"
|
34 |
|
35 | constructor: ({@config})->
|
36 | @config.KODING_ROOT or= "https://koding.com"
|
37 | @config.PROXY_ROOT or= "http://koding.com"
|
38 |
|
39 | dummy: (port=1337)->
|
40 | httpd = http.createServer (req, res)->
|
41 | res.writeHead 200, {'Content-Type': 'text/html'}
|
42 | data = (fs.readFileSync nodePath.join __dirname, "templates", "server", "dummy.tpl.html").toString()
|
43 | data = template data, {user: process.env.USER}
|
44 | res.end "#{data}\n"
|
45 | httpd.listen parseInt(port), '127.0.0.1'
|
46 | httpd.on "request", (req, res)->
|
47 | log "#{colors.green req.method.toLowerCase()} #{req.url}"
|
48 | log "Server running at http://127.0.0.1:#{port} with PID #{process.pid}"
|
49 |
|
50 | start: (name="server", version="1", port="1337", host="127.0.0.1")->
|
51 |
|
52 | {argv: {verbose}} = @options
|
53 | .usage("Runs the local Koding server.")
|
54 | .alias("v", "verbose")
|
55 | .describe("v", "Show error details")
|
56 |
|
57 | unless @config["user.name"]
|
58 | return log """
|
59 | You should set your username:
|
60 |
|
61 | kd config set user.name <your username>
|
62 |
|
63 | """
|
64 |
|
65 | runserver = =>
|
66 | log "Listening #{host}:#{port} and sharing with the name '#{name}-#{version}'. Please wait...", "magenta"
|
67 | try
|
68 | manifest = JSON.parse fs.readFileSync SERVER_MANIFEST_FILE
|
69 | catch err
|
70 | if err.errno is 34
|
71 | log "Creating a new manifest file '#{SERVER_MANIFEST_FILE}'", "red" if verbose
|
72 | else
|
73 | log "Server manifest file seems corrupted '#{SERVER_MANIFEST_FILE}'", "red"
|
74 | log err, "red"
|
75 | process.exit 3
|
76 |
|
77 |
|
78 | socket = new Socket()
|
79 | socket.setTimeout 10000
|
80 | socket.on "timeout", ->
|
81 | log "Couldn't connect to #{host}:#{port}. I think it's not working.", "red"
|
82 | socket.destroy()
|
83 |
|
84 | socket.on "connect", =>
|
85 | socket.end()
|
86 | log "#{host}:#{port} has something on it!", "green"
|
87 | fs.writeFileSync SERVER_MANIFEST_FILE, (JSON.stringify {name, version, host, port, apiAddress: url.parse(@config.PROXY_ROOT).hostname}, null, 2)
|
88 | server = spawn SERVER_RABBIT_BIN
|
89 | log "Started instance on #{server.pid}", "magenta"
|
90 | process.on "SIGINT", ->
|
91 | console.log os.EOL
|
92 | log "fin.", "red"
|
93 | process.kill server.pid, "SIGINT"
|
94 | server.stdout.on "data", (data)-> log data.toString().trim(), "blue"
|
95 | server.stdout.on "error", (data)-> log data.toString().trim(), "red"
|
96 |
|
97 | socket.on "error", ->
|
98 | log """
|
99 | There is nothing working on #{host}:#{port}
|
100 |
|
101 | You can run a dummy server with
|
102 |
|
103 | kd server dummy
|
104 |
|
105 | Also you can use `start` command to change connecting parameters:
|
106 |
|
107 | kd server start <name> <version> <port> <host>
|
108 |
|
109 | """, "red"
|
110 |
|
111 | socket.connect port, host
|
112 |
|
113 | unless fs.existsSync SERVER_RABBIT_BIN
|
114 | exec "uname -s", (err, data)->
|
115 | uname = data.toString().trim()
|
116 | log "downloading dependencies...", "magenta"
|
117 | shell.mkdir "-p", nodePath.dirname SERVER_RABBIT_BIN
|
118 | zip = fs.createWriteStream SERVER_RABBIT_ZIP
|
119 | request = http.get SERVER_RABBIT_BIN_URL, (response)->
|
120 |
|
121 | response.pipe zip
|
122 |
|
123 | response.on "end", ->
|
124 | log "dependencies downloaded.", "green"
|
125 | shell.rm "-rf", nodePath.join nodePath.dirname(SERVER_RABBIT_BIN), "*"
|
126 | exec "unzip #{SERVER_RABBIT_ZIP} -d #{nodePath.dirname SERVER_RABBIT_BIN}", (err)->
|
127 | log "dependencies installing..."
|
128 | if err
|
129 | log "installation error!", "red"
|
130 | process.exit 1
|
131 | runserver()
|
132 |
|
133 | request.on "error", (error)->
|
134 | log "Some resources couldn't be downloaded. Check your internet connection.", "red"
|
135 | process.exit 1
|
136 | else
|
137 | runserver()
|
138 |
|