Skip to content

Commit 4dd0151

Browse files
committed
refactor: move gRPC handlers to their own files
1 parent d25ba6a commit 4dd0151

26 files changed

+1626
-1575
lines changed

mgmtd/src/grpc.rs

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::license::LicensedFeature;
77
use crate::types::{ResolveEntityId, SqliteEnumExt};
88
use anyhow::{Context as AContext, Result, anyhow, bail};
99
use protobuf::{beegfs as pb, management as pm};
10-
use rusqlite::{OptionalExtension, Transaction, TransactionBehavior, params};
10+
use rusqlite::{OptionalExtension, Row, Transaction, TransactionBehavior, named_params, params};
1111
use shared::grpc::*;
1212
use shared::impl_grpc_handler;
1313
use shared::run_state::RunStateHandle;
@@ -21,13 +21,28 @@ use std::pin::Pin;
2121
use tonic::transport::{Identity, Server, ServerTlsConfig};
2222
use tonic::{Code, Request, Response, Status};
2323

24-
mod buddy_group;
25-
mod license;
26-
mod misc;
27-
mod node;
28-
mod pool;
29-
mod quota;
30-
mod target;
24+
mod common;
25+
26+
mod assign_pool;
27+
mod create_buddy_group;
28+
mod create_pool;
29+
mod delete_buddy_group;
30+
mod delete_node;
31+
mod delete_pool;
32+
mod delete_target;
33+
mod get_buddy_groups;
34+
mod get_license;
35+
mod get_nodes;
36+
mod get_pools;
37+
mod get_quota_limits;
38+
mod get_quota_usage;
39+
mod get_targets;
40+
mod mirror_root_inode;
41+
mod set_alias;
42+
mod set_default_quota_limits;
43+
mod set_quota_limits;
44+
mod set_target_state;
45+
mod start_resync;
3146

3247
/// Management gRPC service implementation struct
3348
#[derive(Debug)]
@@ -44,8 +59,9 @@ impl pm::management_server::Management for ManagementService {
4459
// Example: Implement pm::management_server::Management::set_alias using the impl_grpc_handler
4560
// macro
4661
impl_grpc_handler! {
47-
// <the function to implement (as defined by the trait)> => <the actual, custom handler function to call>,
48-
set_alias => misc::set_alias,
62+
// the function to implement (as defined by the trait) as well as the handler to call (must
63+
// be named the same and in a submodule named the same),
64+
set_alias,
4965
// <request message passed to the fn impl (as defined by the trait)> => <response message,
5066
// returned by the fn impl (as defined by the trait)>,
5167
pm::SetAliasRequest => pm::SetAliasResponse,
@@ -54,102 +70,102 @@ impl pm::management_server::Management for ManagementService {
5470
}
5571

5672
impl_grpc_handler! {
57-
get_nodes => node::get,
73+
get_nodes,
5874
pm::GetNodesRequest => pm::GetNodesResponse,
5975
"Get nodes"
6076
}
6177
impl_grpc_handler! {
62-
delete_node => node::delete,
78+
delete_node,
6379
pm::DeleteNodeRequest => pm::DeleteNodeResponse,
6480
"Delete node"
6581
}
6682

6783
impl_grpc_handler! {
68-
get_targets => target::get,
84+
get_targets,
6985
pm::GetTargetsRequest => pm::GetTargetsResponse,
7086
"Get targets"
7187
}
7288
impl_grpc_handler! {
73-
delete_target => target::delete,
89+
delete_target,
7490
pm::DeleteTargetRequest => pm::DeleteTargetResponse,
7591
"Delete target"
7692
}
7793
impl_grpc_handler! {
78-
set_target_state => target::set_state,
94+
set_target_state,
7995
pm::SetTargetStateRequest => pm::SetTargetStateResponse,
8096
"Set target state"
8197
}
8298

8399
impl_grpc_handler! {
84-
get_pools => pool::get,
100+
get_pools,
85101
pm::GetPoolsRequest => pm::GetPoolsResponse,
86102
"Get pools"
87103
}
88104
impl_grpc_handler! {
89-
create_pool => pool::create,
105+
create_pool,
90106
pm::CreatePoolRequest => pm::CreatePoolResponse,
91107
"Create pool"
92108
}
93109
impl_grpc_handler! {
94-
assign_pool => pool::assign,
110+
assign_pool,
95111
pm::AssignPoolRequest => pm::AssignPoolResponse,
96112
"Assign pool"
97113
}
98114
impl_grpc_handler! {
99-
delete_pool => pool::delete,
115+
delete_pool,
100116
pm::DeletePoolRequest => pm::DeletePoolResponse,
101117
"Delete pool"
102118
}
103119

104120
impl_grpc_handler! {
105-
get_buddy_groups => buddy_group::get,
121+
get_buddy_groups,
106122
pm::GetBuddyGroupsRequest => pm::GetBuddyGroupsResponse,
107123
"Get buddy groups"
108124
}
109125
impl_grpc_handler! {
110-
create_buddy_group => buddy_group::create,
126+
create_buddy_group,
111127
pm::CreateBuddyGroupRequest => pm::CreateBuddyGroupResponse,
112128
"Create buddy group"
113129
}
114130
impl_grpc_handler! {
115-
delete_buddy_group => buddy_group::delete,
131+
delete_buddy_group,
116132
pm::DeleteBuddyGroupRequest => pm::DeleteBuddyGroupResponse,
117133
"Delete buddy group"
118134
}
119135
impl_grpc_handler! {
120-
mirror_root_inode => buddy_group::mirror_root_inode,
136+
mirror_root_inode,
121137
pm::MirrorRootInodeRequest => pm::MirrorRootInodeResponse,
122138
"Mirror root inode"
123139
}
124140
impl_grpc_handler! {
125-
start_resync => buddy_group::start_resync,
141+
start_resync,
126142
pm::StartResyncRequest => pm::StartResyncResponse,
127143
"Start resync"
128144
}
129145

130146
impl_grpc_handler! {
131-
set_default_quota_limits => quota::set_default_quota_limits,
147+
set_default_quota_limits,
132148
pm::SetDefaultQuotaLimitsRequest => pm::SetDefaultQuotaLimitsResponse,
133149
"Set default quota limits"
134150
}
135151
impl_grpc_handler! {
136-
set_quota_limits => quota::set_quota_limits,
152+
set_quota_limits,
137153
pm::SetQuotaLimitsRequest => pm::SetQuotaLimitsResponse,
138154
"Set quota limits"
139155
}
140156
impl_grpc_handler! {
141-
get_quota_limits => quota::get_quota_limits,
157+
get_quota_limits,
142158
pm::GetQuotaLimitsRequest => STREAM(GetQuotaLimitsStream, pm::GetQuotaLimitsResponse),
143159
"Get quota limits"
144160
}
145161
impl_grpc_handler! {
146-
get_quota_usage => quota::get_quota_usage,
162+
get_quota_usage,
147163
pm::GetQuotaUsageRequest => STREAM(GetQuotaUsageStream, pm::GetQuotaUsageResponse),
148164
"Get quota usage"
149165
}
150166

151167
impl_grpc_handler! {
152-
get_license => license::get,
168+
get_license,
153169
pm::GetLicenseRequest => pm::GetLicenseResponse,
154170
"Get license"
155171
}

mgmtd/src/grpc/assign_pool.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
use super::*;
2+
use shared::bee_msg::storage_pool::RefreshStoragePools;
3+
4+
/// Assigns a pool to a list of targets and buddy groups.
5+
pub(crate) async fn assign_pool(
6+
ctx: Context,
7+
req: pm::AssignPoolRequest,
8+
) -> Result<pm::AssignPoolResponse> {
9+
needs_license(&ctx, LicensedFeature::Storagepool)?;
10+
fail_on_pre_shutdown(&ctx)?;
11+
12+
let pool: EntityId = required_field(req.pool)?.try_into()?;
13+
14+
let pool = ctx
15+
.db
16+
.write_tx(move |tx| {
17+
let pool = pool.resolve(tx, EntityType::Pool)?;
18+
do_assign(tx, pool.num_id().try_into()?, req.targets, req.buddy_groups)?;
19+
Ok(pool)
20+
})
21+
.await?;
22+
23+
log::info!("Pool assigned: {pool}");
24+
25+
notify_nodes(
26+
&ctx,
27+
&[NodeType::Meta, NodeType::Storage],
28+
&RefreshStoragePools { ack_id: "".into() },
29+
)
30+
.await;
31+
32+
Ok(pm::AssignPoolResponse {
33+
pool: Some(pool.into()),
34+
})
35+
}
36+
37+
/// Do the actual assign work
38+
pub(super) fn do_assign(
39+
tx: &Transaction,
40+
pool_id: PoolId,
41+
targets: Vec<pb::EntityIdSet>,
42+
groups: Vec<pb::EntityIdSet>,
43+
) -> Result<()> {
44+
// Target being part of a buddy group can not be assigned individually
45+
let mut check_group_membership = tx.prepare_cached(sql!(
46+
"SELECT COUNT(*) FROM storage_buddy_groups AS g
47+
INNER JOIN targets AS p_t ON p_t.target_id = g.p_target_id AND p_t.node_type = g.node_type
48+
INNER JOIN targets AS s_t ON s_t.target_id = g.s_target_id AND s_t.node_type = g.node_type
49+
WHERE p_t.target_uid = ?1 OR s_t.target_uid = ?1"
50+
))?;
51+
52+
let mut assign_target = tx.prepare_cached(sql!(
53+
"UPDATE targets SET pool_id = ?1 WHERE target_uid = ?2"
54+
))?;
55+
56+
// Do the checks and assign for each target in the given list. This is expensive, but shouldn't
57+
// matter as this command should only be run occasionally and not with very large lists of
58+
// targets.
59+
for t in targets {
60+
let eid = EntityId::try_from(t)?;
61+
let target = eid.resolve(tx, EntityType::Target)?;
62+
if check_group_membership.query_row([target.uid], |row| row.get::<_, i64>(0))? > 0 {
63+
bail!("Target {eid} can't be assigned directly as it's part of a buddy group");
64+
}
65+
66+
assign_target.execute(params![pool_id, target.uid])?;
67+
}
68+
69+
let mut assign_group = tx.prepare_cached(sql!(
70+
"UPDATE buddy_groups SET pool_id = ?1 WHERE group_uid = ?2"
71+
))?;
72+
73+
// Targets being part of buddy groups are auto-assigned to the new pool
74+
let mut assign_grouped_targets = tx.prepare_cached(sql!(
75+
"UPDATE targets SET pool_id = ?1
76+
FROM (
77+
SELECT p_t.target_uid AS p_uid, s_t.target_uid AS s_uid FROM buddy_groups AS g
78+
INNER JOIN targets AS p_t ON p_t.target_id = g.p_target_id AND p_t.node_type = g.node_type
79+
INNER JOIN targets AS s_t ON s_t.target_id = g.s_target_id AND s_t.node_type = g.node_type
80+
WHERE group_uid = ?2
81+
)
82+
WHERE target_uid IN (p_uid, s_uid)"
83+
))?;
84+
85+
// Assign each group and their targets to the new pool
86+
for g in groups {
87+
let eid = EntityId::try_from(g)?;
88+
let group = eid.resolve(tx, EntityType::BuddyGroup)?;
89+
90+
assign_group.execute(params![pool_id, group.uid])?;
91+
assign_grouped_targets.execute(params![pool_id, group.uid])?;
92+
}
93+
94+
Ok(())
95+
}

0 commit comments

Comments
 (0)