[CORDA-1572] Create marker file to track initial registration status. (#3621)

[CORDA-1572] Create marker file to track initial registration status.
This commit is contained in:
Florian Friemel 2018-07-19 16:20:04 +01:00 committed by GitHub
parent a94dbc9c9a
commit 7466463b89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -5,6 +5,8 @@ import com.typesafe.config.Config
import com.typesafe.config.ConfigException
import com.typesafe.config.ConfigRenderOptions
import io.netty.channel.unix.Errors
import joptsimple.OptionParser
import joptsimple.util.PathConverter
import net.corda.core.crypto.Crypto
import net.corda.core.internal.Emoji
import net.corda.core.internal.concurrent.thenMatch
@ -39,6 +41,7 @@ import org.fusesource.jansi.AnsiConsole
import org.slf4j.bridge.SLF4JBridgeHandler
import sun.misc.VMSupport
import java.io.Console
import java.io.File
import java.io.RandomAccessFile
import java.lang.management.ManagementFactory
import java.net.InetAddress
@ -53,8 +56,10 @@ open class NodeStartup(val args: Array<String>) {
private val logger by lazy { loggerFor<Node>() } // I guess this is lazy to allow for logging init, but why Node?
const val LOGS_DIRECTORY_NAME = "logs"
const val LOGS_CAN_BE_FOUND_IN_STRING = "Logs can be found in"
private const val INITIAL_REGISTRATION_MARKER = ".initialregistration"
}
/**
* @return true if the node startup was successful. This value is intended to be the exit code of the process.
*/
@ -65,13 +70,23 @@ open class NodeStartup(val args: Array<String>) {
println("Corda will now exit...")
return false
}
val cmdlineOptions = NodeArgsParser().parseOrExit(*args)
val registrationMode = checkRegistrationMode()
val cmdlineOptions: CmdLineOptions = if (registrationMode && !args.contains("--initial-registration")) {
"Node was started before with `--initial-registration`, but the registration was not completed.\nResuming registration.".let {
println(it)
logger.info(it)
}
// Pretend that the node was started with `--initial-registration` to help prevent user error.
NodeArgsParser().parseOrExit(*args.plus("--initial-registration"))
} else {
NodeArgsParser().parseOrExit(*args)
}
// We do the single node check before we initialise logging so that in case of a double-node start it
// doesn't mess with the running node's logs.
enforceSingleNodeIsRunning(cmdlineOptions.baseDirectory)
initLogging(cmdlineOptions)
// Register all cryptography [Provider]s.
// Required to install our [SecureRandom] before e.g., UUID asks for one.
// This needs to go after initLogging(netty clashes with our logging).
@ -133,6 +148,8 @@ open class NodeStartup(val args: Array<String>) {
if (cmdlineOptions.nodeRegistrationOption != null) {
// Null checks for [compatibilityZoneURL], [rootTruststorePath] and [rootTruststorePassword] has been done in [CmdLineOptions.loadConfig]
registerWithNetwork(conf, versionInfo, cmdlineOptions.nodeRegistrationOption)
// At this point the node registration was succesfull. We can delete the marker file.
deleteNodeRegistrationMarker(cmdlineOptions.baseDirectory)
return true
}
logStartupInfo(versionInfo, cmdlineOptions, conf)
@ -184,6 +201,49 @@ open class NodeStartup(val args: Array<String>) {
return true
}
private fun checkRegistrationMode(): Boolean {
// Parse the command line args just to get the base directory. The base directory is needed to determine
// if the node registration marker file exists, _before_ we call NodeArgsParser.parse().
// If it does exist, we call NodeArgsParser with `--initial-registration` added to the argument list. This way
// we make sure that the initial registration is completed, even if the node was restarted before the first
// attempt to register succeeded and the node administrator forgets to specify `--initial-registration` upon
// restart.
val optionParser = OptionParser()
optionParser.allowsUnrecognizedOptions()
val baseDirectoryArg = optionParser
.accepts("base-directory", "The node working directory where all the files are kept")
.withRequiredArg()
.withValuesConvertedBy(PathConverter())
.defaultsTo(Paths.get("."))
val isRegistrationArg =
optionParser.accepts("initial-registration", "Start initial node registration with Corda network to obtain certificate from the permissioning server.")
val optionSet = optionParser.parse(*args)
val baseDirectory = optionSet.valueOf(baseDirectoryArg).normalize().toAbsolutePath()
// If the node was started with `--initial-registration`, create marker file.
// We do this here to ensure the marker is created even if parsing the args with NodeArgsParser fails.
val marker = File((baseDirectory / INITIAL_REGISTRATION_MARKER).toUri())
if (!optionSet.has(isRegistrationArg) && !marker.exists()) {
return false
}
try {
marker.createNewFile()
} catch (e: Exception) {
logger.warn("Could not create marker file for `--initial-registration`.", e)
}
return true
}
private fun deleteNodeRegistrationMarker(baseDir: Path) {
try {
val marker = File((baseDir / INITIAL_REGISTRATION_MARKER).toUri())
if (marker.exists()) {
marker.delete()
}
} catch (e: Exception) {
logger.warn("Could not delete the marker file that was created for `--initial-registration`.", e)
}
}
protected open fun preNetworkRegistration(conf: NodeConfiguration) = Unit
protected open fun createNode(conf: NodeConfiguration, versionInfo: VersionInfo): Node = Node(conf, versionInfo)