1
- 'use strict' ;
2
-
3
1
const fs = require ( 'fs-extra' ) ;
4
2
const os = require ( 'os' ) ;
5
3
const dns = require ( 'dns' ) ;
6
4
const url = require ( 'url' ) ;
7
5
const isIP = require ( 'validator/lib/isIP' ) ;
8
6
const path = require ( 'path' ) ;
9
- const execa = require ( 'execa' ) ;
10
7
const Promise = require ( 'bluebird' ) ;
11
8
const template = require ( 'lodash/template' ) ;
9
+ const sysinfo = require ( 'systeminformation' ) ;
12
10
13
11
const { Extension, errors} = require ( '../../lib' ) ;
14
- const { CliError, ProcessError} = errors ;
12
+ const { CliError} = errors ;
13
+
14
+ const { errorWrapper} = require ( './utils' ) ;
15
15
16
16
const nginxConfigPath = process . env . NGINX_CONFIG_PATH || '/etc/nginx' ;
17
17
const nginxProgramName = process . env . NGINX_PROGRAM_NAME || 'nginx' ;
@@ -35,10 +35,11 @@ class NginxExtension extends Extension {
35
35
return [ {
36
36
id : 'nginx' ,
37
37
name : 'Nginx' ,
38
- task : ( ...args ) => this . setupNginx ( ...args ) ,
38
+ task : errorWrapper ( ( ...args ) => this . setupNginx ( ...args ) ) ,
39
39
enabled,
40
- skip : ( { instance} ) => {
41
- if ( ! this . isSupported ( ) ) {
40
+ skip : async ( { instance} ) => {
41
+ const isSupported = await this . isSupported ( ) ;
42
+ if ( ! isSupported ) {
42
43
return 'Nginx is not installed. Skipping Nginx setup.' ;
43
44
}
44
45
@@ -94,7 +95,7 @@ class NginxExtension extends Extension {
94
95
} ] ;
95
96
}
96
97
97
- setupNginx ( { instance} ) {
98
+ async setupNginx ( { instance} ) {
98
99
const { hostname, pathname} = url . parse ( instance . config . get ( 'url' ) ) ;
99
100
const conf = template ( fs . readFileSync ( path . join ( __dirname , 'templates' , 'nginx.conf' ) , 'utf8' ) ) ;
100
101
@@ -108,18 +109,9 @@ class NginxExtension extends Extension {
108
109
port : instance . config . get ( 'server.port' )
109
110
} ) ;
110
111
111
- return this . template ( instance , generatedConfig , 'nginx config' , confFile , `${ nginxConfigPath } /sites-available` ) . then (
112
- ( ) => this . ui . sudo ( `ln -sf ${ nginxConfigPath } /sites-available/${ confFile } ${ nginxConfigPath } /sites-enabled/${ confFile } ` )
113
- ) . then (
114
- ( ) => this . restartNginx ( )
115
- ) . catch ( ( error ) => {
116
- // CASE: error is already a cli error, just pass it along
117
- if ( error instanceof CliError ) {
118
- return Promise . reject ( error ) ;
119
- }
120
-
121
- return Promise . reject ( new ProcessError ( error ) ) ;
122
- } ) ;
112
+ await this . template ( instance , generatedConfig , 'nginx config' , confFile , `${ nginxConfigPath } /sites-available` ) ;
113
+ await this . ui . sudo ( `ln -sf ${ nginxConfigPath } /sites-available/${ confFile } ${ nginxConfigPath } /sites-enabled/${ confFile } ` ) ;
114
+ await this . restartNginx ( ) ;
123
115
}
124
116
125
117
setupSSL ( { instance, argv} ) {
@@ -158,23 +150,18 @@ class NginxExtension extends Extension {
158
150
} )
159
151
} , {
160
152
title : 'Getting additional configuration' ,
161
- task : ( ) => {
162
- let promise ;
163
-
153
+ task : async ( ) => {
164
154
if ( argv . sslemail ) {
165
- promise = Promise . resolve ( argv . sslemail ) ;
166
- } else {
167
- promise = this . ui . prompt ( {
168
- name : 'email' ,
169
- type : 'input' ,
170
- message : 'Enter your email (For SSL Certificate)' ,
171
- validate : value => Boolean ( value ) || 'You must supply an email'
172
- } ) . then ( ( { email} ) => {
173
- argv . sslemail = email ;
174
- } ) ;
155
+ return ;
175
156
}
176
157
177
- return promise ;
158
+ const { email} = await this . ui . prompt ( {
159
+ name : 'email' ,
160
+ type : 'input' ,
161
+ message : 'Enter your email (For SSL Certificate)' ,
162
+ validate : value => Boolean ( value ) || 'You must supply an email'
163
+ } ) ;
164
+ argv . sslemail = email ;
178
165
}
179
166
} , {
180
167
title : 'Installing acme.sh' ,
@@ -185,22 +172,18 @@ class NginxExtension extends Extension {
185
172
} , {
186
173
title : 'Generating Encryption Key (may take a few minutes)' ,
187
174
skip : ( ) => fs . existsSync ( dhparamFile ) ,
188
- task : ( ) => this . ui . sudo ( `openssl dhparam -out ${ dhparamFile } 2048` )
189
- . catch ( error => Promise . reject ( new ProcessError ( error ) ) )
175
+ task : errorWrapper ( ( ) => this . ui . sudo ( `openssl dhparam -out ${ dhparamFile } 2048` ) )
190
176
} , {
191
177
title : 'Generating SSL security headers' ,
192
178
skip : ( ) => fs . existsSync ( sslParamsFile ) ,
193
- task : ( ) => {
179
+ task : errorWrapper ( async ( ) => {
194
180
const tmpfile = path . join ( os . tmpdir ( ) , 'ssl-params.conf' ) ;
195
-
196
- return fs . writeFile ( tmpfile , sslParamsConf ( { dhparam : dhparamFile } ) , { encoding : 'utf8' } )
197
- . then ( ( ) => this . ui . sudo ( `mv ${ tmpfile } ${ sslParamsFile } ` ) . catch (
198
- error => Promise . reject ( new ProcessError ( error ) )
199
- ) ) ;
200
- }
181
+ await fs . writeFile ( tmpfile , sslParamsConf ( { dhparam : dhparamFile } ) , { encoding : 'utf8' } ) ;
182
+ await this . ui . sudo ( `mv ${ tmpfile } ${ sslParamsFile } ` ) ;
183
+ } )
201
184
} , {
202
185
title : 'Generating SSL configuration' ,
203
- task : ( ) => {
186
+ task : errorWrapper ( async ( ) => {
204
187
const acmeFolder = path . join ( '/etc/letsencrypt' , parsedUrl . hostname ) ;
205
188
const sslConf = template ( fs . readFileSync ( path . join ( __dirname , 'templates' , 'nginx-ssl.conf' ) , 'utf8' ) ) ;
206
189
const generatedSslConfig = sslConf ( {
@@ -213,77 +196,81 @@ class NginxExtension extends Extension {
213
196
port : instance . config . get ( 'server.port' )
214
197
} ) ;
215
198
216
- return this . template ( instance , generatedSslConfig , 'ssl config' , confFile , `${ nginxConfigPath } /sites-available` ) . then (
217
- ( ) => this . ui . sudo ( `ln -sf ${ nginxConfigPath } /sites-available/${ confFile } ${ nginxConfigPath } /sites-enabled/${ confFile } ` )
218
- ) . catch ( error => Promise . reject ( new ProcessError ( error ) ) ) ;
219
- }
199
+ await this . template ( instance , generatedSslConfig , 'ssl config' , confFile , `${ nginxConfigPath } /sites-available` ) ;
200
+ await this . ui . sudo ( `ln -sf ${ nginxConfigPath } /sites-available/${ confFile } ${ nginxConfigPath } /sites-enabled/${ confFile } ` ) ;
201
+ } )
220
202
} , {
221
203
title : 'Restarting Nginx' ,
222
204
task : ( ) => this . restartNginx ( )
223
205
} ] , false ) ;
224
206
}
225
207
226
- uninstall ( { config} ) {
208
+ async uninstall ( { config} ) {
227
209
const instanceUrl = config . get ( 'url' ) ;
228
210
229
211
if ( ! instanceUrl ) {
230
- return Promise . resolve ( ) ;
212
+ return ;
231
213
}
232
214
233
215
const parsedUrl = url . parse ( instanceUrl ) ;
234
216
const confFile = `${ parsedUrl . hostname } .conf` ;
235
217
const sslConfFile = `${ parsedUrl . hostname } -ssl.conf` ;
236
218
237
- const promises = [ ] ;
219
+ let restart = false ;
238
220
239
221
if ( fs . existsSync ( `${ nginxConfigPath } /sites-available/${ confFile } ` ) ) {
222
+ restart = true ;
223
+
240
224
// Nginx config exists, remove it
241
- promises . push (
242
- Promise . all ( [
243
- this . ui . sudo ( `rm -f ${ nginxConfigPath } /sites-available /${ confFile } ` ) ,
244
- this . ui . sudo ( `rm -f ${ nginxConfigPath } /sites-enabled/ ${ confFile } ` )
245
- ] ) . catch ( error => Promise . reject ( new CliError ( {
225
+ try {
226
+ await this . ui . sudo ( `rm -f ${ nginxConfigPath } /sites-available/ ${ confFile } ` ) ;
227
+ await this . ui . sudo ( `rm -f ${ nginxConfigPath } /sites-enabled /${ confFile } ` ) ;
228
+ } catch ( error ) {
229
+ throw new CliError ( {
246
230
message : `Nginx config file link could not be removed, you will need to do this manually for ${ nginxConfigPath } /sites-available/${ confFile } .` ,
247
231
help : `Try running 'rm -f ${ nginxConfigPath } /sites-available/${ confFile } && rm -f ${ nginxConfigPath } /sites-enabled/${ confFile } '` ,
248
232
err : error
249
- } ) ) )
250
- ) ;
233
+ } ) ;
234
+ }
251
235
}
252
236
253
237
if ( fs . existsSync ( `${ nginxConfigPath } /sites-available/${ sslConfFile } ` ) ) {
238
+ restart = true ;
239
+
254
240
// SSL config exists, remove it
255
- promises . push (
256
- Promise . all ( [
257
- this . ui . sudo ( `rm -f ${ nginxConfigPath } /sites-available /${ sslConfFile } ` ) ,
258
- this . ui . sudo ( `rm -f ${ nginxConfigPath } /sites-enabled/ ${ sslConfFile } ` )
259
- ] ) . catch ( error => Promise . reject ( new CliError ( {
241
+ try {
242
+ await this . ui . sudo ( `rm -f ${ nginxConfigPath } /sites-available/ ${ sslConfFile } ` ) ;
243
+ await this . ui . sudo ( `rm -f ${ nginxConfigPath } /sites-enabled /${ sslConfFile } ` ) ;
244
+ } catch ( error ) {
245
+ throw new CliError ( {
260
246
message : `SSL config file link could not be removed, you will need to do this manually for ${ nginxConfigPath } /sites-available/${ sslConfFile } .` ,
261
247
help : `Try running 'rm -f ${ nginxConfigPath } /sites-available/${ sslConfFile } && rm -f ${ nginxConfigPath } /sites-enabled/${ sslConfFile } '` ,
262
248
err : error
263
- } ) ) )
264
- ) ;
249
+ } ) ;
250
+ }
265
251
}
266
252
267
- if ( ! promises . length ) {
268
- return Promise . resolve ( ) ;
253
+ if ( restart ) {
254
+ await this . restartNginx ( ) ;
269
255
}
270
-
271
- return Promise . all ( promises ) . then ( ( ) => this . restartNginx ( ) ) ;
272
256
}
273
257
274
- restartNginx ( ) {
275
- return this . ui . sudo ( `${ nginxProgramName } -s reload` )
276
- . catch ( error => Promise . reject ( new CliError ( {
258
+ async restartNginx ( ) {
259
+ try {
260
+ await this . ui . sudo ( `${ nginxProgramName } -s reload` ) ;
261
+ } catch ( error ) {
262
+ throw new CliError ( {
277
263
message : 'Failed to restart Nginx.' ,
278
264
err : error
279
- } ) ) ) ;
265
+ } ) ;
266
+ }
280
267
}
281
268
282
- isSupported ( ) {
269
+ async isSupported ( ) {
283
270
try {
284
- execa . shellSync ( `dpkg -l | grep ${ nginxProgramName } ` , { stdio : 'ignore' } ) ;
285
- return true ;
286
- } catch ( e ) {
271
+ const services = await sysinfo . services ( '*' ) ;
272
+ return services . some ( s => s . name === nginxProgramName ) ;
273
+ } catch ( error ) {
287
274
return false ;
288
275
}
289
276
}
0 commit comments