Skip to content

Commit 00df5a6

Browse files
authored
fix(dashmate): invalid drive status check (#2248)
1 parent 0a57e76 commit 00df5a6

File tree

9 files changed

+80
-64
lines changed

9 files changed

+80
-64
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/dashmate/src/commands/status/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,12 @@ export default class StatusCommand extends ConfigBaseCommand {
108108

109109
plain['Platform Enabled'] = platform.enabled || 'n/a';
110110

111+
const platformStatus = platform.tenderdash.serviceStatus !== ServiceStatusEnum.up
112+
? platform.tenderdash.serviceStatus
113+
: platform.drive.serviceStatus;
114+
111115
if (platform.enabled) {
112-
plain['Platform Status'] = colors.status(platform.tenderdash.serviceStatus)(platform.tenderdash.serviceStatus) || 'n/a';
116+
plain['Platform Status'] = colors.status(platformStatus)(platformStatus) || 'n/a';
113117

114118
if (platform.tenderdash.serviceStatus === ServiceStatusEnum.up) {
115119
plain['Platform Version'] = platform.tenderdash.version || 'n/a';

packages/dashmate/src/config/generateEnvsFactory.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export default function generateEnvsFactory(configFile, homeDir, getConfigProfil
6969

7070
let driveAbciMetricsUrl = '';
7171
if (config.get('platform.drive.abci.metrics.enabled')) {
72+
// IP and port inside container
7273
driveAbciMetricsUrl = 'http://0.0.0.0:29090';
7374
}
7475

packages/dashmate/src/status/determineStatus.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ export default {
4949
return coreIsSynced ? ServiceStatusEnum.up : ServiceStatusEnum.wait_for_core;
5050
}
5151

52+
if (dockerStatus === DockerStatusEnum.not_started) {
53+
return ServiceStatusEnum.stopped;
54+
}
55+
5256
return ServiceStatusEnum.error;
5357
},
5458
};

packages/dashmate/src/status/scopes/overview.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ export default function getOverviewScopeFactory(
5757
}
5858

5959
if (config.get('platform.enable')) {
60-
const { tenderdash } = await getPlatformScope(config);
60+
const { drive, tenderdash } = await getPlatformScope(config);
6161

62+
platform.drive = drive;
6263
platform.tenderdash = tenderdash;
6364
}
6465

packages/dashmate/src/status/scopes/platform.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import prettyMs from 'pretty-ms';
2+
import DockerComposeError from '../../docker/errors/DockerComposeError.js';
23
import providers from '../providers.js';
34
import { DockerStatusEnum } from '../enums/dockerStatus.js';
45
import { ServiceStatusEnum } from '../enums/serviceStatus.js';
@@ -162,31 +163,36 @@ export default function getPlatformScopeFactory(
162163

163164
try {
164165
info.dockerStatus = await determineStatus.docker(dockerCompose, config, 'drive_abci');
165-
info.serviceStatus = determineStatus.platform(info.dockerStatus, isCoreSynced, mnRRSoftFork);
166+
} catch (e) {
167+
if (e instanceof ContainerIsNotPresentError) {
168+
info.dockerStatus = DockerStatusEnum.not_started;
169+
} else {
170+
throw e;
171+
}
172+
}
173+
174+
info.serviceStatus = determineStatus.platform(info.dockerStatus, isCoreSynced, mnRRSoftFork);
166175

167-
if (info.serviceStatus === ServiceStatusEnum.up) {
168-
const driveEchoResult = await dockerCompose.execCommand(
176+
// Get Drive status to make sure it's responding
177+
if (info.serviceStatus === ServiceStatusEnum.up) {
178+
try {
179+
await dockerCompose.execCommand(
169180
config,
170181
'drive_abci',
171182
'drive-abci status',
172183
);
173-
174-
if (driveEchoResult.exitCode !== 0) {
184+
} catch (e) {
185+
if (e instanceof DockerComposeError
186+
&& e.dockerComposeExecutionResult
187+
&& e.dockerComposeExecutionResult.exitCode !== 0) {
175188
info.serviceStatus = ServiceStatusEnum.error;
189+
} else {
190+
throw e;
176191
}
177192
}
178-
179-
return info;
180-
} catch (e) {
181-
if (e instanceof ContainerIsNotPresentError) {
182-
return {
183-
dockerStatus: DockerStatusEnum.not_started,
184-
serviceStatus: ServiceStatusEnum.stopped,
185-
};
186-
}
187-
188-
return info;
189193
}
194+
195+
return info;
190196
};
191197

192198
/**

packages/dashmate/test/unit/status/scopes/platform.spec.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import ContainerIsNotPresentError
2+
from '../../../../src/docker/errors/ContainerIsNotPresentError.js';
13
import providers from '../../../../src/status/providers.js';
24
import determineStatus from '../../../../src/status/determineStatus.js';
35
import getConfigMock from '../../../../src/test/mock/getConfigMock.js';
@@ -377,7 +379,7 @@ describe('getPlatformScopeFactory', () => {
377379
mockDetermineDockerStatus.withArgs(mockDockerCompose, config, 'drive_tenderdash')
378380
.returns(DockerStatusEnum.running);
379381
mockDetermineDockerStatus.withArgs(mockDockerCompose, config, 'drive_abci')
380-
.throws();
382+
.throws(new ContainerIsNotPresentError('drive_abci'));
381383
mockDockerCompose.execCommand.returns({ exitCode: 0, out: '' });
382384
mockMNOWatchProvider.returns(Promise.resolve('OPEN'));
383385

@@ -430,8 +432,8 @@ describe('getPlatformScopeFactory', () => {
430432
network: 'test',
431433
},
432434
drive: {
433-
dockerStatus: null,
434-
serviceStatus: null,
435+
dockerStatus: DockerStatusEnum.not_started,
436+
serviceStatus: ServiceStatusEnum.stopped,
435437
},
436438
};
437439

packages/rs-drive-abci/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ metrics-exporter-prometheus = { version = "0.15", default-features = false, feat
6363
"http-listener",
6464
] }
6565
url = { version = "2.3.1" }
66-
ureq = { "version" = "2.6.2" }
6766
tokio = { version = "1.40", features = [
6867
"macros",
6968
"signal",

packages/rs-drive-abci/src/main.rs

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
//! RS-Drive-ABCI server starts a single-threaded server and listens to connections from Tenderdash.
44
55
use clap::{Parser, Subcommand};
6+
use dapi_grpc::platform::v0::get_status_request;
7+
use dapi_grpc::platform::v0::get_status_request::GetStatusRequestV0;
8+
use dapi_grpc::platform::v0::platform_client::PlatformClient;
9+
use dapi_grpc::tonic::transport::Uri;
610
use dpp::version::PlatformVersion;
711
use drive_abci::config::{FromEnv, PlatformConfig};
812
use drive_abci::core::wait_for_core_to_sync::v0::wait_for_core_to_sync_v0;
913
use drive_abci::logging::{LogBuilder, LogConfig, LogDestination, Loggers};
10-
use drive_abci::metrics::{Prometheus, DEFAULT_PROMETHEUS_PORT};
14+
use drive_abci::metrics::Prometheus;
1115
use drive_abci::platform_types::platform::Platform;
1216
use drive_abci::rpc::core::DefaultCoreRPC;
1317
use drive_abci::{logging, server};
@@ -17,6 +21,7 @@ use std::fs::remove_file;
1721
use std::net::SocketAddr;
1822
use std::path::PathBuf;
1923
use std::process::ExitCode;
24+
use std::str::FromStr;
2025
use std::sync::Arc;
2126
use tokio::runtime::{Builder, Runtime};
2227
use tokio::signal::unix::{signal, SignalKind};
@@ -98,6 +103,13 @@ impl Cli {
98103
) -> Result<(), String> {
99104
match self.command {
100105
Commands::Start => {
106+
tracing::info!(
107+
version = env!("CARGO_PKG_VERSION"),
108+
features = list_enabled_features().join(","),
109+
rust = env!("CARGO_PKG_RUST_VERSION"),
110+
"drive-abci server initializing",
111+
);
112+
101113
if config.drive.grovedb_verify_on_startup {
102114
verify_grovedb(&config.db_path, false)?;
103115
}
@@ -129,10 +141,12 @@ impl Cli {
129141

130142
server::start(runtime, Arc::new(platform), config, cancel);
131143

144+
tracing::info!("drive-abci server is stopped");
145+
132146
return Ok(());
133147
}
134148
Commands::Config => dump_config(&config)?,
135-
Commands::Status => check_status(&config)?,
149+
Commands::Status => runtime.block_on(check_status(&config))?,
136150
Commands::Verify => verify_grovedb(&config.db_path, true)?,
137151
};
138152

@@ -202,13 +216,6 @@ fn main() -> Result<(), ExitCode> {
202216
install_panic_hook(cancel.clone());
203217

204218
// Start runtime in the main thread
205-
tracing::info!(
206-
version = env!("CARGO_PKG_VERSION"),
207-
features = list_enabled_features().join(","),
208-
rust = env!("CARGO_PKG_RUST_VERSION"),
209-
"drive-abci server initializing",
210-
);
211-
212219
let runtime_guard = runtime.enter();
213220

214221
runtime.spawn(handle_signals(cancel.clone(), loggers));
@@ -219,15 +226,13 @@ fn main() -> Result<(), ExitCode> {
219226
Ok(())
220227
}
221228
Err(e) => {
222-
tracing::error!(error = e, "drive-abci failed");
229+
tracing::error!(error = e, "drive-abci failed: {e}");
223230
Err(ExitCode::FAILURE)
224231
}
225232
};
226233

227234
drop(runtime_guard);
228235
runtime.shutdown_timeout(Duration::from_millis(SHUTDOWN_TIMEOUT_MILIS));
229-
tracing::info!("drive-abci server is stopped");
230-
231236
result
232237
}
233238

@@ -303,31 +308,27 @@ fn list_enabled_features() -> Vec<&'static str> {
303308
}
304309

305310
/// Check status of ABCI server.
306-
fn check_status(config: &PlatformConfig) -> Result<(), String> {
307-
if let Some(prometheus_addr) = &config.prometheus_bind_address {
308-
let url =
309-
url::Url::parse(prometheus_addr).expect("cannot parse ABCI_PROMETHEUS_BIND_ADDRESS");
310-
311-
let addr = format!(
312-
"{}://{}:{}/metrics",
313-
url.scheme(),
314-
url.host()
315-
.ok_or("ABCI_PROMETHEUS_BIND_ADDRESS must contain valid host".to_string())?,
316-
url.port().unwrap_or(DEFAULT_PROMETHEUS_PORT)
317-
);
318-
319-
let body: String = ureq::get(&addr)
320-
.set("Content-type", "text/plain")
321-
.call()
322-
.map_err(|e| e.to_string())?
323-
.into_string()
324-
.map_err(|e| e.to_string())?;
311+
async fn check_status(config: &PlatformConfig) -> Result<(), String> {
312+
// Convert the gRPC bind address string to a Uri
313+
let uri = Uri::from_str(&format!("http://{}", config.grpc_bind_address))
314+
.map_err(|e| format!("invalid url: {e}"))?;
315+
316+
// Connect to the gRPC server
317+
let mut client = PlatformClient::connect(uri.clone())
318+
.await
319+
.map_err(|e| format!("can't connect to grpc server {uri}: {e}"))?;
320+
321+
// Make a request to the server
322+
let request = dapi_grpc::platform::v0::GetStatusRequest {
323+
version: Some(get_status_request::Version::V0(GetStatusRequestV0 {})),
324+
};
325325

326-
println!("{}", body);
327-
Ok(())
328-
} else {
329-
Err("ABCI_PROMETHEUS_BIND_ADDRESS not defined, cannot check status".to_string())
330-
}
326+
// Should return non-zero error code if Drive is not responding
327+
client
328+
.get_status(request)
329+
.await
330+
.map(|_| ())
331+
.map_err(|e| format!("can't request status: {e}"))
331332
}
332333

333334
/// Verify GroveDB integrity.
@@ -415,7 +416,7 @@ fn configure_logging(cli: &Cli, config: &PlatformConfig) -> Result<Loggers, logg
415416
if configs.is_empty() || cli.verbose > 0 {
416417
let cli_config = LogConfig {
417418
destination: LogDestination::StdOut,
418-
level: cli.verbose.try_into().unwrap(),
419+
level: cli.verbose.try_into()?,
419420
color: cli.color,
420421
..Default::default()
421422
};
@@ -442,15 +443,14 @@ fn install_panic_hook(cancel: CancellationToken) {
442443

443444
#[cfg(test)]
444445
mod test {
446+
use ::drive::{drive::Drive, query::Element};
447+
use dpp::block::epoch::Epoch;
448+
use drive::drive::credit_pools::epochs::epoch_key_constants;
445449
use std::{
446450
fs,
447451
path::{Path, PathBuf},
448452
};
449453

450-
use ::drive::{drive::Drive, query::Element};
451-
use dpp::block::epoch::Epoch;
452-
use drive::drive::credit_pools::epochs::epoch_key_constants;
453-
454454
use dpp::version::PlatformVersion;
455455
use drive::drive::credit_pools::epochs::paths::EpochProposers;
456456
use drive_abci::logging::LogLevel;

0 commit comments

Comments
 (0)