Skip to content

Commit 0ceca00

Browse files
committed
feat(cli): wait for tls cert on create
This adds logic to wait up to 5 seconds for the tls cert file to be created on the `create` command. Since this command may be called immediately after xud is launched for the first time and the cert won't be created until xud is done initializing, this will help avoid unnecessary failures and repeated attempts.
1 parent a25b99e commit 0ceca00

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

lib/cli/command.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ import { getDefaultCertPath } from './utils';
99
* @param argv the command line arguments
1010
*/
1111
export const loadXudClient = (argv: Arguments) => {
12-
const certPath = argv.tlscertpath ? argv.tlscertpath : getDefaultCertPath();
12+
const certPath = argv.tlscertpath || getDefaultCertPath();
1313
const cert = fs.readFileSync(certPath);
1414
const credentials = grpc.credentials.createSsl(cert);
1515

1616
return new XudClient(`${argv.rpchost}:${argv.rpcport}`, credentials);
1717
};
1818

1919
export const loadXudInitClient = (argv: Arguments) => {
20-
const certPath = argv.tlscertpath ? argv.tlscertpath : getDefaultCertPath();
20+
const certPath = argv.tlscertpath || getDefaultCertPath();
2121
const cert = fs.readFileSync(certPath);
2222
const credentials = grpc.credentials.createSsl(cert);
2323

lib/cli/commands/create.ts

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,47 @@
1+
import { accessSync, watch } from 'fs';
2+
import path from 'path';
13
import readline from 'readline';
24
import { Arguments } from 'yargs';
35
import { CreateNodeRequest, CreateNodeResponse } from '../../proto/xudrpc_pb';
46
import { callback, loadXudInitClient } from '../command';
7+
import { getDefaultCertPath } from '../utils';
58

69
export const command = 'create';
710

811
export const describe = 'use this to create a new xud instance and set a password';
912

1013
export const builder = {};
1114

15+
const waitForCert = (certPath: string) => {
16+
return new Promise<void>((resolve, reject) => {
17+
try {
18+
accessSync(certPath);
19+
resolve();
20+
} catch (err) {
21+
if (err.code === 'ENOENT') {
22+
// wait up to 5 seconds for the tls.cert file to be created in case
23+
// this is the first time xud has been run
24+
const certDir = path.dirname(certPath);
25+
const certFilename = path.basename(certPath);
26+
const fsWatcher = watch(certDir, (event, filename) => {
27+
if (event === 'change' && filename === certFilename) {
28+
clearTimeout(timeout);
29+
fsWatcher.close();
30+
resolve();
31+
}
32+
});
33+
const timeout = setTimeout(() => {
34+
fsWatcher.close();
35+
reject(`timed out waiting for cert to be created at ${certPath}`);
36+
}, 5000);
37+
} else {
38+
// we handle errors due to file not existing, otherwise reject
39+
reject(err);
40+
}
41+
}
42+
});
43+
};
44+
1245
const formatOutput = (response: CreateNodeResponse.AsObject) => {
1346
if (response.seedMnemonicList.length === 24) {
1447
const WORDS_PER_ROW = 4;
@@ -49,19 +82,30 @@ export const handler = (argv: Arguments) => {
4982
process.stdout.write('Enter a password: ');
5083
rl.question('', (password1) => {
5184
process.stdout.write('\nRe-enter password: ');
52-
rl.question('', (password2) => {
85+
rl.question('', async (password2) => {
5386
process.stdout.write('\n\n');
5487
rl.close();
5588
if (password1 === password2) {
5689
const request = new CreateNodeRequest();
5790
request.setPassword(password1);
91+
92+
const certPath = argv.tlscertpath ? argv.tlscertpath : getDefaultCertPath();
93+
try {
94+
await waitForCert(certPath);
95+
} catch (err) {
96+
console.error(err);
97+
process.exitCode = 1;
98+
return;
99+
}
100+
58101
const client = loadXudInitClient(argv);
59102
// wait up to 3 seconds for rpc server to listen before call in case xud was just started
60103
client.waitForReady(Date.now() + 3000, () => {
61104
client.createNode(request, callback(argv, formatOutput));
62105
});
63106
} else {
64-
console.log('Passwords do not match, please try again.');
107+
process.exitCode = 1;
108+
console.error('Passwords do not match, please try again');
65109
}
66110
});
67111
});

0 commit comments

Comments
 (0)