Merge pull request #2890 from tclinken/expose-lock-fdbcli

Add lock and unlock commands to fdbcli
This commit is contained in:
A.J. Beamon 2020-04-10 13:54:47 -07:00 committed by GitHub
commit bcb0a4cc78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 2 deletions

View File

@ -216,7 +216,6 @@ The following options are available for use with the ``option`` command:
``TIMEOUT`` - Set a timeout in milliseconds which, when elapsed, will cause the transaction automatically to be cancelled. Valid parameter values are ``[0, INT_MAX]``. If set to 0, will disable all timeouts. All pending and any future uses of the transaction will throw an exception. The transaction can be used again after it is reset. Like all transaction options, a timeout must be reset after a call to ``onError``. This behavior allows the user to make the timeouts dynamic.
include
-------
@ -232,6 +231,11 @@ For each IP address or IP:port pair in ``<ADDRESS...>``, the command removes any
For information on adding machines to a cluster, see :ref:`adding-machines-to-a-cluster`.
lock
----
The ``lock`` command locks the database with a randomly generated lockUID.
option
------
@ -290,3 +294,8 @@ status json
^^^^^^^^^^^
``status json`` will provide the cluster status in its JSON format. For a detailed description of this format, see :doc:`mr-status`.
unlock
------
The ``unlock`` command unlocks the database with the specified lock UID. Because this is a potentially dangerous operation, users must copy a passphrase before the unlock command is executed.

View File

@ -568,6 +568,14 @@ void initHelp() {
"consistencycheck [on|off]",
"permits or prevents consistency checking",
"Calling this command with `on' permits consistency check processes to run and `off' will halt their checking. Calling this command with no arguments will display if consistency checking is currently allowed.\n");
helpMap["lock"] = CommandHelp(
"lock",
"lock the database with a randomly generated lockUID",
"Randomly generates a lockUID, prints this lockUID, and then uses the lockUID to lock the database.");
helpMap["unlock"] =
CommandHelp("unlock <UID>", "unlock the database with the provided lockUID",
"Unlocks the database with the provided lockUID. This is a potentially dangerous operation, so the "
"user will be asked to enter a passphrase to confirm their intent.");
hiddenCommands.insert("expensive_data_check");
hiddenCommands.insert("datadistribution");
@ -2844,7 +2852,8 @@ ACTOR Future<int> cli(CLIOptions opt, LineNoise* plinenoise) {
continue;
// Don't put dangerous commands in the command history
if (line.find("writemode") == std::string::npos && line.find("expensive_data_check") == std::string::npos)
if (line.find("writemode") == std::string::npos && line.find("expensive_data_check") == std::string::npos &&
line.find("unlock") == std::string::npos)
linenoise.historyAdd(line);
}
@ -3059,6 +3068,52 @@ ACTOR Future<int> cli(CLIOptions opt, LineNoise* plinenoise) {
continue;
}
if (tokencmp(tokens[0], "lock")) {
if (tokens.size() != 1) {
printUsage(tokens[0]);
is_error = true;
} else {
state UID lockUID = deterministicRandom()->randomUniqueID();
printf("Locking database with lockUID: %s\n", lockUID.toString().c_str());
wait(makeInterruptable(lockDatabase(db, lockUID)));
printf("Database locked.\n");
}
continue;
}
if (tokencmp(tokens[0], "unlock")) {
if ((tokens.size() != 2) || (tokens[1].size() != 32) ||
!std::all_of(tokens[1].begin(), tokens[1].end(), &isxdigit)) {
printUsage(tokens[0]);
is_error = true;
} else {
state std::string passPhrase = deterministicRandom()->randomAlphaNumeric(10);
warn.cancel(); // don't warn while waiting on user input
printf("Unlocking the database is a potentially dangerous operation.\n");
Optional<std::string> input = wait(linenoise.read(
format("Repeat the following passphrase if you would like to proceed (%s) : ",
passPhrase.c_str())));
warn = checkStatus(timeWarning(5.0, "\nWARNING: Long delay (Ctrl-C to interrupt)\n"), db);
if (input.present() && input.get() == passPhrase) {
UID unlockUID = UID::fromString(tokens[1].toString());
try {
wait(makeInterruptable(unlockDatabase(db, unlockUID)));
printf("Database unlocked.\n");
} catch (Error& e) {
if (e.code() == error_code_database_locked) {
printf(
"Unable to unlock database. Make sure to unlock with the correct lock UID.\n");
}
throw e;
}
} else {
printf("ERROR: Incorrect passphrase entered.\n");
is_error = true;
}
}
continue;
}
if (tokencmp(tokens[0], "setclass")) {
if (tokens.size() != 3 && tokens.size() != 1) {
printUsage(tokens[0]);