diff --git a/src/rpc/ddl_apply.rs b/src/rpc/ddl_apply.rs index 081bc3726a52b333c61b900a79c4ea37806bf164..f874d8e4be483152f2b13d05c9b2f0868fb23bd1 100644 --- a/src/rpc/ddl_apply.rs +++ b/src/rpc/ddl_apply.rs @@ -7,7 +7,7 @@ use crate::traft::node; use crate::traft::Result; use crate::traft::{RaftIndex, RaftTerm}; use std::time::Duration; -use tarantool::error::TarantoolError; +use tarantool::error::{TarantoolError, TarantoolErrorCode}; use tarantool::ffi::tarantool as ffi; use tarantool::space::{Space, SystemSpace}; @@ -25,6 +25,14 @@ crate::define_rpc_request! { return Ok(Response::Ok); } + if crate::tarantool::eval("return box.info.ro")? { + let e = tarantool::set_and_get_error!( + TarantoolErrorCode::Readonly, + "cannot apply schema change on a read only instance" + ); + return Err(e.into()); + } + let ddl = storage.properties.pending_schema_change()?.ok_or_else(|| Error::other("pending schema change not found"))?; // FIXME: start_transaction api is awful, it would be too ugly to diff --git a/src/traft/error.rs b/src/traft/error.rs index 7d9f5ce7664f468f20ebce4916e712fbd2f51371..8884a7495cbcb674c5e6b167c6a180c6c1c6902c 100644 --- a/src/traft/error.rs +++ b/src/traft/error.rs @@ -104,6 +104,12 @@ impl From<::tarantool::error::TransactionError> for Error { } } +impl From<::tarantool::error::TarantoolError> for Error { + fn from(err: ::tarantool::error::TarantoolError) -> Self { + Self::Tarantool(err.into()) + } +} + #[derive(Debug, Error)] pub enum CoercionError { #[error("unknown entry type ({0})")]