@@ -5,7 +5,7 @@ import { generate as generate_password } from "generate-password";
5
5
6
6
import { exec , execFile } from 'child_process' ;
7
7
import { promisify } from 'util' ;
8
- import { withDir } from 'tmp-promise'
8
+ import { withDir } from 'tmp-promise' ;
9
9
10
10
import { open , rm , mkdir } from 'fs/promises' ;
11
11
@@ -18,7 +18,8 @@ import {
18
18
IMultiClientInstaller ,
19
19
NodeStatus ,
20
20
ValidatorStatus ,
21
- InstallDetails
21
+ InstallDetails ,
22
+ OutputLogs
22
23
} from "./IMultiClientInstaller" ;
23
24
import { Network , networkToExecution } from '../react/types' ;
24
25
import { doesFileExist , doesDirectoryExist } from './BashUtils' ;
@@ -40,47 +41,74 @@ type SystemdServiceDetails = {
40
41
unitFileState : string | undefined ;
41
42
}
42
43
44
+ const writeOutput = ( message : string , outputLogs ?: OutputLogs ) : void => {
45
+ if ( outputLogs ) {
46
+ outputLogs ( message ) ;
47
+ }
48
+ } ;
49
+
43
50
export class EthDockerInstaller implements IMultiClientInstaller {
44
51
45
52
title = 'Electron' ;
46
53
47
- async preInstall ( ) : Promise < boolean > {
54
+ async preInstall ( outputLogs ?: OutputLogs ) : Promise < boolean > {
48
55
49
56
let packagesToInstall = new Array < string > ( ) ;
50
57
51
58
// We need git installed
52
59
const gitPackageName = 'git' ;
53
60
61
+ writeOutput ( `Checking if ${ gitPackageName } is installed.` , outputLogs ) ;
54
62
const gitInstalled = await this . checkForInstalledUbuntuPackage ( gitPackageName ) ;
55
63
if ( ! gitInstalled ) {
64
+ writeOutput ( `${ gitPackageName } is not installed. We will install it.` , outputLogs ) ;
56
65
packagesToInstall . push ( gitPackageName ) ;
66
+ } else {
67
+ writeOutput ( `${ gitPackageName } is already installed. We will not install it.` , outputLogs ) ;
57
68
}
58
69
59
70
// We need docker installed, enabled and running
60
71
const dockerPackageName = 'docker-compose' ;
61
72
let needToEnableDockerService = true ;
62
73
let needToStartDockerService = false ;
63
74
75
+ writeOutput ( `Checking if ${ dockerPackageName } is installed.` , outputLogs ) ;
64
76
const dockerInstalled = await this . checkForInstalledUbuntuPackage ( dockerPackageName ) ;
65
77
if ( ! dockerInstalled ) {
78
+ writeOutput ( `${ dockerPackageName } is not installed. We will install it.` , outputLogs ) ;
66
79
packagesToInstall . push ( dockerPackageName ) ;
67
80
} else {
81
+ writeOutput ( `${ dockerPackageName } is already installed. We will not install it.` , outputLogs ) ;
82
+
83
+ writeOutput ( `Checking if we need to enable or start the ${ dockerServiceName } service.` , outputLogs ) ;
68
84
const dockerServiceDetails = await this . getSystemdServiceDetails ( dockerServiceName ) ;
69
85
needToEnableDockerService = dockerServiceDetails . unitFileState != 'enabled' ;
86
+ if ( needToEnableDockerService ) {
87
+ writeOutput ( `The ${ dockerServiceName } service is not enabled. We will enable it.` , outputLogs ) ;
88
+ }
70
89
needToStartDockerService = dockerServiceDetails . subState != 'running' ;
90
+ if ( needToStartDockerService ) {
91
+ writeOutput ( `The ${ dockerServiceName } service is not started. We will start it.` , outputLogs ) ;
92
+ }
71
93
}
72
94
73
95
// We need our user to be in docker group
96
+ writeOutput ( `Checking if current user is in ${ dockerGroupName } group.` , outputLogs ) ;
74
97
const needUserInDockerGroup = ! await this . isUserInGroup ( dockerGroupName ) ;
98
+ if ( needUserInDockerGroup ) {
99
+ writeOutput ( `Current user is not in ${ dockerGroupName } group. We will add it.` , outputLogs ) ;
100
+ }
75
101
76
102
// We need our installPath directory
103
+ writeOutput ( `Creating install directory in ${ installPath } .` , outputLogs ) ;
77
104
await mkdir ( installPath , { recursive : true } ) ;
78
105
79
106
return await this . preInstallAdminScript (
80
107
packagesToInstall ,
81
108
needUserInDockerGroup ,
82
109
needToEnableDockerService ,
83
- needToStartDockerService ) ;
110
+ needToStartDockerService ,
111
+ outputLogs ) ;
84
112
}
85
113
86
114
async getSystemdServiceDetails ( serviceName : string ) : Promise < SystemdServiceDetails > {
@@ -132,7 +160,8 @@ export class EthDockerInstaller implements IMultiClientInstaller {
132
160
packagesToInstall : Array < string > ,
133
161
needUserInDockerGroup : boolean ,
134
162
needToEnableDockerService : boolean ,
135
- needToStartDockerService : boolean ) : Promise < boolean > {
163
+ needToStartDockerService : boolean ,
164
+ outputLogs ?: OutputLogs ) : Promise < boolean > {
136
165
137
166
if (
138
167
packagesToInstall . length > 0 ||
@@ -148,36 +177,55 @@ export class EthDockerInstaller implements IMultiClientInstaller {
148
177
await withDir ( async dirResult => {
149
178
150
179
const scriptPath = path . join ( dirResult . path , 'commands.sh' ) ;
180
+ let scriptContent = '' ;
151
181
152
182
const scriptFile = await open ( scriptPath , 'w' ) ;
153
183
await scriptFile . write ( '#!/bin/bash\n' ) ;
154
184
155
185
// Install APT packages
156
186
if ( packagesToInstall . length > 0 ) {
157
- await scriptFile . write ( 'apt -y update\n' ) ;
158
- await scriptFile . write ( 'apt -y install ' + commandJoin ( packagesToInstall ) + '\n' ) ;
187
+ const aptUpdate = 'apt -y update\n' ;
188
+ const aptInstall = 'apt -y install ' + commandJoin ( packagesToInstall ) + '\n' ;
189
+
190
+ scriptContent += aptUpdate + aptInstall ;
191
+
192
+ await scriptFile . write ( aptUpdate ) ;
193
+ await scriptFile . write ( aptInstall ) ;
159
194
}
160
195
161
196
// Enable docker service
162
197
if ( needToEnableDockerService ) {
163
- await scriptFile . write ( 'systemctl enable --now ' + commandJoin ( [ dockerServiceName ] ) + '\n' ) ;
198
+ const systemctlEnable = 'systemctl enable --now ' + commandJoin ( [ dockerServiceName ] ) + '\n' ;
199
+
200
+ scriptContent += systemctlEnable ;
201
+
202
+ await scriptFile . write ( systemctlEnable ) ;
164
203
}
165
204
166
205
// Start docker service
167
206
if ( needToStartDockerService ) {
168
- await scriptFile . write ( 'systemctl start ' + commandJoin ( [ dockerServiceName ] ) + '\n' ) ;
207
+ const systemctlStart = 'systemctl start ' + commandJoin ( [ dockerServiceName ] ) + '\n' ;
208
+
209
+ scriptContent += systemctlStart ;
210
+
211
+ await scriptFile . write ( systemctlStart ) ;
169
212
}
170
213
171
214
// Add user in docker group
172
215
if ( needUserInDockerGroup ) {
173
216
const userName = await this . getUsername ( ) ;
217
+ const usermodUser = `usermod -aG ${ dockerGroupName } ${ userName } \n` ;
218
+
219
+ scriptContent += usermodUser ;
174
220
175
- await scriptFile . write ( `usermod -aG ${ dockerGroupName } ${ userName } \n` ) ;
221
+ await scriptFile . write ( usermodUser ) ;
176
222
}
177
223
178
224
await scriptFile . chmod ( 0o500 ) ;
179
225
await scriptFile . close ( ) ;
180
226
227
+ writeOutput ( `Running script ${ scriptPath } with the following content as root:\n${ scriptContent } ` , outputLogs ) ;
228
+
181
229
const promise = new Promise < boolean > ( async ( resolve , reject ) => {
182
230
const options = {
183
231
name : this . title
@@ -186,6 +234,9 @@ export class EthDockerInstaller implements IMultiClientInstaller {
186
234
sudo . exec ( scriptPath , options ,
187
235
function ( error , stdout , stderr ) {
188
236
if ( error ) reject ( error ) ;
237
+ if ( stdout ) {
238
+ writeOutput ( stdout . toString ( ) , outputLogs ) ;
239
+ }
189
240
resolve ( true ) ;
190
241
}
191
242
) ;
@@ -230,7 +281,7 @@ export class EthDockerInstaller implements IMultiClientInstaller {
230
281
return stdout . indexOf ( '[installed]' ) > 0
231
282
}
232
283
233
- async install ( details : InstallDetails ) : Promise < boolean > {
284
+ async install ( details : InstallDetails , outputLogs ?: OutputLogs ) : Promise < boolean > {
234
285
// Install and update eth-docker
235
286
if ( ! await this . installUpdateEthDockerCode ( details . network ) ) {
236
287
return false ;
@@ -422,11 +473,11 @@ EONG
422
473
return true ;
423
474
}
424
475
425
- async postInstall ( network : Network ) : Promise < boolean > {
426
- return this . startNodes ( network ) ;
476
+ async postInstall ( network : Network , outputLogs ?: OutputLogs ) : Promise < boolean > {
477
+ return this . startNodes ( network , outputLogs ) ;
427
478
}
428
479
429
- async stopNodes ( network : Network ) : Promise < boolean > {
480
+ async stopNodes ( network : Network , outputLogs ?: OutputLogs ) : Promise < boolean > {
430
481
const networkPath = path . join ( installPath , network . toLowerCase ( ) ) ;
431
482
const ethDockerPath = path . join ( networkPath , 'eth-docker' ) ;
432
483
448
499
return true ;
449
500
}
450
501
451
- async startNodes ( network : Network ) : Promise < boolean > {
502
+ async startNodes ( network : Network , outputLogs ?: OutputLogs ) : Promise < boolean > {
452
503
const networkPath = path . join ( installPath , network . toLowerCase ( ) ) ;
453
504
const ethDockerPath = path . join ( networkPath , 'eth-docker' ) ;
454
505
@@ -470,13 +521,13 @@ EONG
470
521
return true ;
471
522
}
472
523
473
- async updateExecutionClient ( ) : Promise < void > {
524
+ async updateExecutionClient ( outputLogs ?: OutputLogs ) : Promise < void > {
474
525
// TODO: implement
475
526
console . log ( "Executing updateExecutionClient" ) ;
476
527
return ;
477
528
}
478
529
479
- async updateConsensusClient ( ) : Promise < void > {
530
+ async updateConsensusClient ( outputLogs ?: OutputLogs ) : Promise < void > {
480
531
// TODO: implement
481
532
console . log ( "Executing updateConsensusClient" ) ;
482
533
return ;
485
536
async importKeys (
486
537
network : Network ,
487
538
keyStoreDirectoryPath : string ,
488
- keyStorePassword : string ) : Promise < boolean > {
539
+ keyStorePassword : string ,
540
+ outputLogs ?: OutputLogs ) : Promise < boolean > {
489
541
490
542
const networkPath = path . join ( installPath , network . toLowerCase ( ) ) ;
491
543
const ethDockerPath = path . join ( networkPath , 'eth-docker' ) ;
0 commit comments