Skip to content

Commit fad5d45

Browse files
committed
fix: handle missing service version
Endpoint version discovery ran under 'try_join_all', so the first service that failed aborted the whole batch. A cloud that advertises a service in its catalog without serving a version document (an Octavia or an Cinder on its own port with nothing at '/') made the TUI unusable for every other service too: the connect itself returned an error. Signed-off-by: Gabin L <gabin.lanore@gmail.com>
1 parent b321d0d commit fad5d45

1 file changed

Lines changed: 18 additions & 27 deletions

File tree

openstack_tui/src/cloud_worker.rs

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ use secrecy::SecretString;
2828
use std::path::PathBuf;
2929
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
3030
use tokio::sync::oneshot;
31-
use tracing::{debug, instrument, trace};
31+
use tracing::{debug, instrument, trace, warn};
3232

33-
use futures::future::try_join_all;
33+
use futures::future::join_all;
3434

3535
use crate::action::Action;
3636

@@ -135,7 +135,7 @@ impl Cloud {
135135
.connect()
136136
.await?;
137137

138-
Self::discover_services(&session, &TUI_SERVICES).await?;
138+
Self::discover_services(&session, &TUI_SERVICES).await;
139139

140140
// Replacing `self.cloud` also happens here; assigning a new
141141
// `_renew_handle` first drops (aborts) any renewal task for the
@@ -153,24 +153,27 @@ impl Cloud {
153153
async fn discover_services(
154154
session: &AsyncOpenStack,
155155
services: &[openstack_sdk::types::ServiceType],
156-
) -> Result<()> {
157-
try_join_all(services.iter().map(|st| {
156+
) {
157+
join_all(services.iter().map(|service_type| {
158158
let session = session.clone();
159159
async move {
160-
session.discover_service_endpoint(st).await?;
161-
Ok::<_, openstack_sdk::OpenStackError>(())
160+
if let Err(err) = session.discover_service_endpoint(service_type).await {
161+
warn!(
162+
"Version discovery for the `{}` service failed, continuing with its unversioned catalog endpoint: {}",
163+
service_type, err
164+
);
165+
}
162166
}
163167
}))
164-
.await?;
165-
Ok(())
168+
.await;
166169
}
167170

168171
/// Re-authorise and rediscovers service endpoints for the given session,
169-
/// sending [`Action::Error`] on failure instead of propagating the error
170-
/// out of the worker loop.
172+
/// sending [`Action::Error`] on re-authorisation failure instead of propagating the error
173+
/// out of the worker loop. Endpoint discovery is best-effort, see [`Cloud::discover_services`].
171174
///
172-
/// Returns `true` when the whole sequence completed without errors,
173-
/// `false` when an [`Action::Error`] was already emitted.
175+
/// Returns `true` when re-authorisation succeeded, `false` when an [`Action::Error`] was
176+
/// already emitted.
174177
async fn prepare_session_for_work(
175178
session: &mut AsyncOpenStack,
176179
services: &[openstack_sdk::types::ServiceType],
@@ -187,13 +190,7 @@ impl Cloud {
187190
return false;
188191
}
189192

190-
if let Err(err) = Cloud::discover_services(session, services).await {
191-
let _ = app_tx.send(Action::Error {
192-
msg: format!("Service discovery failed: {err:?}"),
193-
action: Some(Box::new(action.clone())),
194-
});
195-
return false;
196-
}
193+
Cloud::discover_services(session, services).await;
197194
true
198195
}
199196

@@ -231,13 +228,7 @@ impl Cloud {
231228
}
232229
debug!("Authed as {:?}", session.get_auth_info());
233230

234-
if let Err(err) = Cloud::discover_services(session, &TUI_SERVICES).await {
235-
let _ = app_tx.send(Action::Error {
236-
msg: format!("Service discovery failed: {err:?}"),
237-
action: Some(Box::new(action.clone())),
238-
});
239-
return false;
240-
}
231+
Cloud::discover_services(session, &TUI_SERVICES).await;
241232

242233
if let Some(auth_info) = session.get_auth_info() {
243234
let _ = app_tx.send(Action::ConnectedToCloud(Box::new(auth_info.token)));

0 commit comments

Comments
 (0)