forked from bitfocus/companion
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.js
executable file
·172 lines (145 loc) · 5.1 KB
/
main.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/usr/bin/env node
// Setup logging before anything else runs
import Logging from './lib/Log/Controller.js'
// Now we can think about startup
import { Command } from 'commander'
import Registry from './lib/Registry.js'
import os from 'os'
import path from 'path'
import fs from 'fs-extra'
import envPaths from 'env-paths'
import { nanoid } from 'nanoid'
import logger from './lib/Log/Controller.js'
const program = new Command()
program.command('check-launches', { hidden: true }).action(() => {
// This is a 'test' command used to make sure builds are able to run
console.log('It launches!')
process.exit(89)
})
program
.option('--list-interfaces', 'List the available network interfaces that can be passed to --admin-interface')
.option('--admin-port <number>', 'Set the port the admin ui should bind to (default: 8000)', 8000)
.option(
'--admin-interface <string>',
"Set the interface the admin ui should bind to. The first ip on this interface will be used (default: '')"
)
.option('--admin-address <string>', 'Set the ip address the admin ui should bind to (default: 0.0.0.0)', '0.0.0.0')
.option(
'--config-dir <string>',
'Use the specified directory for storing configuration. The default path varies by system, and is different to 2.2 (the old path will be used if existing config is found)'
)
.option('--extra-module-path <string>', 'Search an extra directory for modules to load')
.option('--machine-id <string>', 'Unique id for this installation')
.option('--log-level <string>', 'Log level to output to console')
program.command('start', { isDefault: true, hidden: true }).action(() => {
const options = program.opts()
if (options.listInterfaces) {
console.error('Available Interfaces:')
const interfaces = os.networkInterfaces()
for (const [ifname, ifgroup] of Object.entries(interfaces)) {
for (const ifAddr of ifgroup) {
// onlt show non-ipv4 addresses for now
if ('IPv4' === ifAddr.family) {
console.error(ifname, ifAddr.address)
}
}
}
process.exit(0)
}
logger.logger.info('Application starting')
if (isNaN(options.adminPort)) {
console.error(`Port number is not valid`)
process.exit(1)
}
if (options.adminAddress && options.adminInterface) {
console.error(`Only one of admin-interface and admin-address can be specified`)
process.exit(1)
}
let adminIp = options.adminAddress || '0.0.0.0' // default to admin global
if (options.adminInterface) {
adminIp = null
const interfaceInfo = os.networkInterfaces()[options.adminInterface]
if (interfaceInfo) {
for (const ifAddr of interfaceInfo) {
// only show non-ipv4 addresses for now
if ('IPv4' === ifAddr.family) {
adminIp = ifAddr.address
break
}
}
}
if (!adminIp) {
console.error(`Invalid interface name "${options.adminInterface}"`)
process.exit(1)
}
}
let configDir = options.configDir
if (!configDir) {
// Check the old location first
configDir = path.join(process.env[process.platform == 'win32' ? 'USERPROFILE' : 'HOME'], 'companion')
if (!fs.pathExistsSync(configDir)) {
// Creating a new folder, so use the proper place
const paths = envPaths('companion')
configDir = paths.config
}
}
// machid is always in the configDir
const machineIdPath = path.join(configDir, 'machid')
// develop should use subfolder. This should be disabled when ready for mass testing
const rootConfigDir = configDir
configDir = path.join(configDir, 'develop')
// Hack: move config from older 3.0 config. This should be removed before 3.0 switches to the main config path
const oldConfigPath = path.join(configDir, '../../companion3-test')
if (!fs.existsSync(configDir) && fs.existsSync(oldConfigPath)) fs.moveSync(oldConfigPath, configDir)
const oldConfigPath2 = envPaths('companion3-test').config
if (!fs.existsSync(configDir) && fs.existsSync(oldConfigPath2)) fs.moveSync(oldConfigPath2, configDir)
try {
fs.ensureDirSync(configDir)
} catch (e) {
console.error(`Failed to create config directory. Do you have the correct permissions?`)
process.exit(1)
}
// try and import the non-develop copy. we only need to take `db` for this
if (
configDir !== rootConfigDir &&
!fs.existsSync(path.join(configDir, 'db')) &&
fs.existsSync(path.join(rootConfigDir, 'db'))
)
fs.copyFileSync(path.join(rootConfigDir, 'db'), path.join(configDir, 'db'))
if (options.logLevel) {
logger.setLogLevel(options.logLevel)
}
let machineId = options.machineId
if (!machineId) {
// Use stored value
if (fs.pathExistsSync(machineIdPath)) {
let text = ''
try {
text = fs.readFileSync(machineIdPath)
if (text) {
machineId = text.toString()
}
} catch (e) {
console.warn(`Error reading machid file: ${e}`)
}
} else {
machineId = nanoid()
try {
fs.writeFileSync(machineIdPath, machineId)
} catch (e) {
console.warn(`Error writing machid file: ${e}`)
}
}
}
const registry = new Registry(configDir, machineId)
registry
.ready(options.extraModulePath, adminIp, options.adminPort)
.then(() => {
console.log('Started')
})
.catch((e) => {
console.error(`Startup failed: ${e} ${e.stack}`)
process.exit(1)
})
})
program.parse()