-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
119 lines (103 loc) · 3.25 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
const child_process = require("child_process")
const json2toml = require("json2toml")
const flat = require("flat")
const { EventEmitter } = require("events")
const tempy = require("tempy")
const debug = require("debug")("traefik")
const bunyan = require("bunyan")
const log = bunyan.createLogger({
name: "traefik",
level: debug.enabled ? "trace" : "info",
})
const downloadtraefik = require("./download-traefik")
class TraefikService extends EventEmitter {
// proc = null
// stop = null
}
module.exports.start = async (params) => {
if (!params)
throw new Error(
"No parameters provided to traefik.start (static config or path to static config must be specified)"
)
const traefikPath = await downloadtraefik()
const traefikService = new TraefikService()
let pathToStaticConfigFile = typeof params === "string" ? params : null
let staticConfigObject
if (params.staticConfig) {
staticConfigObject = params.staticConfig
} else if (typeof params === "object") {
if (params.dynamicConfig)
throw new Error(
"When specifying dynamicConfig parameter, make sure to specify staticConfig parameter"
)
staticConfigObject = params
}
if (params.dynamicConfig && staticConfigObject) {
staticConfigObject["providers.file.filename"] = tempy.writeSync(
json2toml(flat.unflatten(params.dynamicConfig)),
{ name: "traefik-dynamic.toml" }
)
log.trace({
traefikDynamicTomlPath: staticConfigObject["providers.file.filename"],
})
}
if (staticConfigObject) {
pathToStaticConfigFile = tempy.writeSync(
json2toml(flat.unflatten(staticConfigObject)),
{ name: "traefik-static.toml" }
)
}
const argList = ["--configFile", pathToStaticConfigFile]
log.trace(`Running ${traefikPath} ${argList.join(" ")}`)
const proc = child_process.spawn(traefikPath, argList, {
shell: true,
})
proc.stdout.on("data", (data) => {
traefikService.emit("data", data)
})
let recentStderrLines = []
proc.stderr.on("data", (data) => {
traefikService.emit("data", data)
recentStderrLines.push(data)
recentStderrLines = recentStderrLines.slice(-10)
log.trace({ stderr: data.toString() })
})
let isClosed = false
proc.on("close", (code) => {
traefikService.emit("close", code)
log.trace(`traefik closing (code: ${code})`)
isClosed = true
})
await new Promise((resolve, reject) => {
const processCloseTimeout = setTimeout(() => {
if (isClosed) {
reject(
`traefik didn't start properly:\n\n${recentStderrLines.join("\n")}`
)
} else {
reject(`traefik didn't respond`)
proc.kill("SIGINT")
}
}, 5000)
async function checkIfRunning() {
setTimeout(() => {
// TODO ping traefik
const traefikIsHealthy = !isClosed
if (traefikIsHealthy) {
clearTimeout(processCloseTimeout)
resolve()
}
}, 2000)
}
checkIfRunning()
})
process.on("SIGINT", () => proc.kill("SIGINT"))
process.on("SIGUSR1", () => proc.kill("SIGINT"))
process.on("SIGUSR2", () => proc.kill("SIGINT"))
process.on("exit", () => proc.kill("SIGINT"))
traefikService.proc = proc
traefikService.stop = async () => {
proc.kill("SIGINT")
}
return traefikService
}