diff --git a/data-node/src/main/java/org/graylog/datanode/Configuration.java b/data-node/src/main/java/org/graylog/datanode/Configuration.java index 2a523e4ec0..0f3480d164 100644 --- a/data-node/src/main/java/org/graylog/datanode/Configuration.java +++ b/data-node/src/main/java/org/graylog/datanode/Configuration.java @@ -89,7 +89,7 @@ public class Configuration extends BaseConfiguration { @Parameter(value = "opensearch_plugins_location", validators = DirectoryReadableValidator.class) private Path opensearchPluginsDir = Path.of("dist/plugins"); - @Parameter(value = "opensearch_data_location", required = true, validators = DirectoryWritableValidator.class) + @Parameter(value = "opensearch_data_location", required = true, validators = DirectoryReadableValidator.class) private Path opensearchDataLocation = Path.of("datanode/data"); @Parameter(value = "opensearch_logs_location", required = true, validators = DirectoryWritableValidator.class) diff --git a/data-node/src/main/java/org/graylog/datanode/bootstrap/preflight/DatanodeDirectoriesLockfileCheck.java b/data-node/src/main/java/org/graylog/datanode/bootstrap/preflight/DatanodeDirectoriesLockfileCheck.java index 8411e76de0..2aa537fd80 100644 --- a/data-node/src/main/java/org/graylog/datanode/bootstrap/preflight/DatanodeDirectoriesLockfileCheck.java +++ b/data-node/src/main/java/org/graylog/datanode/bootstrap/preflight/DatanodeDirectoriesLockfileCheck.java @@ -17,14 +17,13 @@ package org.graylog.datanode.bootstrap.preflight; import com.google.common.io.CharStreams; +import jakarta.inject.Inject; import org.graylog.datanode.configuration.DatanodeConfiguration; import org.graylog.datanode.configuration.DatanodeDirectories; import org.graylog2.bootstrap.preflight.PreflightCheck; import org.graylog2.bootstrap.preflight.PreflightCheckException; import org.graylog2.plugin.system.NodeId; -import jakarta.inject.Inject; - import java.io.IOException; import java.io.Reader; import java.io.Writer; @@ -61,11 +60,10 @@ public class DatanodeDirectoriesLockfileCheck implements PreflightCheck { @Override public void runCheck() throws PreflightCheckException { checkDatanodeLock(directories.getConfigurationTargetDir()); - checkDatanodeLock(directories.getDataTargetDir()); checkDatanodeLock(directories.getLogsTargetDir()); } - private void checkDatanodeLock(Path dir) { + public void checkDatanodeLock(Path dir) { final Path lockfile = dir.resolve(DATANODE_LOCKFILE); try (FileChannel channel = FileChannel.open(lockfile, StandardOpenOption.READ, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) { doCheckLockFile(channel, dir); diff --git a/data-node/src/main/java/org/graylog/datanode/bootstrap/preflight/DatanodeDirectoryException.java b/data-node/src/main/java/org/graylog/datanode/bootstrap/preflight/DatanodeDirectoryException.java deleted file mode 100644 index 91ae434fa4..0000000000 --- a/data-node/src/main/java/org/graylog/datanode/bootstrap/preflight/DatanodeDirectoryException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2020 Graylog, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * . - */ -package org.graylog.datanode.bootstrap.preflight; - -import java.io.IOException; - -public class DatanodeDirectoryException extends IOException { - public DatanodeDirectoryException(String message) { - super(message); - } - - public DatanodeDirectoryException(String message, IOException cause) { - super(message, cause); - } -} diff --git a/data-node/src/main/java/org/graylog/datanode/management/OpensearchProcessService.java b/data-node/src/main/java/org/graylog/datanode/management/OpensearchProcessService.java index cd89d18d0b..39df8a3da5 100644 --- a/data-node/src/main/java/org/graylog/datanode/management/OpensearchProcessService.java +++ b/data-node/src/main/java/org/graylog/datanode/management/OpensearchProcessService.java @@ -24,6 +24,7 @@ import jakarta.inject.Inject; import jakarta.inject.Provider; import jakarta.inject.Singleton; import org.graylog.datanode.Configuration; +import org.graylog.datanode.bootstrap.preflight.DatanodeDirectoriesLockfileCheck; import org.graylog.datanode.configuration.DatanodeConfiguration; import org.graylog.datanode.metrics.ConfigureMetricsIndexSettings; import org.graylog.datanode.process.OpensearchConfiguration; @@ -58,6 +59,7 @@ public class OpensearchProcessService extends AbstractIdleService implements Pro private final DataNodeProvisioningService dataNodeProvisioningService; private final IndexFieldTypesService indexFieldTypesService; private final ClusterEventBus clusterEventBus; + private final DatanodeDirectoriesLockfileCheck lockfileCheck; @Inject @@ -72,13 +74,15 @@ public class OpensearchProcessService extends AbstractIdleService implements Pro final IndexFieldTypesService indexFieldTypesService, final ObjectMapper objectMapper, final ProcessStateMachine processStateMachine, - final ClusterEventBus clusterEventBus) { + final ClusterEventBus clusterEventBus, + final DatanodeDirectoriesLockfileCheck lockfileCheck) { this.configurationProvider = configurationProvider; this.eventBus = eventBus; this.nodeId = nodeId; this.dataNodeProvisioningService = dataNodeProvisioningService; this.indexFieldTypesService = indexFieldTypesService; this.clusterEventBus = clusterEventBus; + this.lockfileCheck = lockfileCheck; this.process = createOpensearchProcess(datanodeConfiguration, trustManager, configuration, nodeService, objectMapper, processStateMachine); eventBus.register(this); } @@ -142,7 +146,14 @@ public class OpensearchProcessService extends AbstractIdleService implements Pro final OpensearchConfiguration config = configurationProvider.get(); configure(); if (config.securityConfigured()) { - this.process.start(); + + try { + lockfileCheck.checkDatanodeLock(config.datanodeDirectories().getDataTargetDir()); + this.process.start(); + } catch (Exception e) { + LOG.error("Could not start up data node", e); + } + } } diff --git a/data-node/src/main/java/org/graylog/datanode/process/ProcessStateMachine.java b/data-node/src/main/java/org/graylog/datanode/process/ProcessStateMachine.java index 30f553f190..d9c52a6574 100644 --- a/data-node/src/main/java/org/graylog/datanode/process/ProcessStateMachine.java +++ b/data-node/src/main/java/org/graylog/datanode/process/ProcessStateMachine.java @@ -48,6 +48,7 @@ public class ProcessStateMachine extends StateMachine { - const url = 'datanodes/rest/indices-directory/compatibility'; + const url = 'datanodes/any/rest/indices-directory/compatibility'; return fetch('GET', qualifyUrl(url)); }; diff --git a/graylog2-web-interface/src/components/datanode/migrations/MigrationDatanodeList.tsx b/graylog2-web-interface/src/components/datanode/migrations/MigrationDatanodeList.tsx index b83daaa771..cc4dd11c8a 100644 --- a/graylog2-web-interface/src/components/datanode/migrations/MigrationDatanodeList.tsx +++ b/graylog2-web-interface/src/components/datanode/migrations/MigrationDatanodeList.tsx @@ -22,11 +22,15 @@ import { Alert, Table } from 'components/bootstrap'; import { DocumentationLink } from 'components/support'; import useDataNodes from 'components/datanode/hooks/useDataNodes'; +type Props = { + showProvisioningState?: boolean +} + const StyledIcon = styled(Icon)` margin-right: 0.5em; `; -const MigrationDatanodeList = () => { +const MigrationDatanodeList = ({ showProvisioningState }: Props) => { const { data: dataNodes, isInitialLoading } = useDataNodes(); if (isInitialLoading) { @@ -61,7 +65,7 @@ const MigrationDatanodeList = () => { {datanode.hostname} {datanode.transport_address} - {datanode.status} + {showProvisioningState ? datanode.status : datanode.data_node_status} {datanode.cert_valid_until ? : 'No certificate'} ))} @@ -73,4 +77,8 @@ const MigrationDatanodeList = () => { ); }; +MigrationDatanodeList.defaultProps = { + showProvisioningState: true, +}; + export default MigrationDatanodeList; diff --git a/graylog2-web-interface/src/components/datanode/migrations/in-place/RestartGraylog.tsx b/graylog2-web-interface/src/components/datanode/migrations/in-place/RestartGraylog.tsx index e3cd1438b9..d01b7a1e20 100644 --- a/graylog2-web-interface/src/components/datanode/migrations/in-place/RestartGraylog.tsx +++ b/graylog2-web-interface/src/components/datanode/migrations/in-place/RestartGraylog.tsx @@ -19,6 +19,7 @@ import React from 'react'; import type { MigrationStepComponentProps } from 'components/datanode/Types'; import MigrationStepTriggerButtonToolbar from 'components/datanode/migrations/common/MigrationStepTriggerButtonToolbar'; import { Space } from 'preflight/components/common'; +import MigrationDatanodeList from 'components/datanode/migrations/MigrationDatanodeList'; const RestartGraylog = ({ currentStep, onTriggerStep }: MigrationStepComponentProps) => ( <> @@ -26,6 +27,10 @@ const RestartGraylog = ({ currentStep, onTriggerStep }: MigrationStepComponentPr

Please remove the elasticsearch_hosts line from your graylog.conf

E.g., elasticsearch_hosts = https://admin:admin@opensearch1:9200,https://admin:admin@opensearch2:9200,https://admin:admin@opensearch3:9200

+ +

Please wait for all data nodes to become 'AVAILABLE'. Please check the data node's log if they do + not become available within 1-2 minutes. +

{/* eslint-disable-next-line react/no-unescaped-entities */}

Once that's done, please restart Graylog to finish the migration.

diff --git a/graylog2-web-interface/src/components/datanode/migrations/in-place/StopMessageProcessing.tsx b/graylog2-web-interface/src/components/datanode/migrations/in-place/StopMessageProcessing.tsx index 6be11c9102..69f96a53d2 100644 --- a/graylog2-web-interface/src/components/datanode/migrations/in-place/StopMessageProcessing.tsx +++ b/graylog2-web-interface/src/components/datanode/migrations/in-place/StopMessageProcessing.tsx @@ -36,6 +36,10 @@ const StopMessageProcessing = ({ currentStep, onTriggerStep }: MigrationStepComp

Please stop your OpenSearch cluster before proceeding.

+

If you are migrating existing OpenSearch data by pointing the data node to its data directory, make sure that + the user running the data node (usually graylog-datanode) has permissions to write to the data directory set + in the data node configuration. +