|
| 1 | +use k8s_openapi::apiextensions_apiserver::pkg::apis::apiextensions::v1::CustomResourceDefinition; |
| 2 | +use kube::runtime::wait; |
1 | 3 | use snafu::{ResultExt, Snafu}; |
| 4 | +use stackable_shared::time::Duration; |
2 | 5 | use tokio::{ |
3 | 6 | signal::unix::{SignalKind, signal}, |
4 | 7 | sync::watch, |
5 | 8 | }; |
6 | 9 |
|
| 10 | +use crate::client::Client; |
| 11 | + |
7 | 12 | #[derive(Debug, Snafu)] |
8 | 13 | #[snafu(display("failed to construct signal watcher"))] |
9 | 14 | pub struct SignalError { |
@@ -71,3 +76,46 @@ impl SignalWatcher<()> { |
71 | 76 | Ok(Self { watch_rx }) |
72 | 77 | } |
73 | 78 | } |
| 79 | + |
| 80 | +pub const DEFAULT_CRD_ESTABLISHED_TIMEOUT: Duration = Duration::from_secs(5); |
| 81 | + |
| 82 | +#[derive(Debug, Snafu)] |
| 83 | +pub enum CrdEstablishedError { |
| 84 | + #[snafu(display("failed to meet CRD established condition before the timeout elapsed"))] |
| 85 | + TimeoutElapsed { source: tokio::time::error::Elapsed }, |
| 86 | + |
| 87 | + #[snafu(display("failed to await CRD established condition due to api error"))] |
| 88 | + Api { source: kube::runtime::wait::Error }, |
| 89 | +} |
| 90 | + |
| 91 | +/// Waits for a CRD named `crd_name` to be established before `timeout_duration` (or by default |
| 92 | +/// [`DEFAULT_CRD_ESTABLISHED_TIMEOUT`]) is elapsed. |
| 93 | +/// |
| 94 | +/// The same caveats from [`conditions::is_crd_established`](wait::conditions::is_crd_established) |
| 95 | +/// apply here as well. |
| 96 | +/// |
| 97 | +/// ### Errors |
| 98 | +/// |
| 99 | +/// This function returns errors either if the timeout elapsed without the condition being met or |
| 100 | +/// when the underlying API returned errors (CRD is unknown to the Kubernetes API server or due to |
| 101 | +/// missing permissions). |
| 102 | +pub async fn crd_established( |
| 103 | + client: &Client, |
| 104 | + crd_name: &str, |
| 105 | + timeout_duration: impl Into<Option<Duration>>, |
| 106 | +) -> Result<(), CrdEstablishedError> { |
| 107 | + let api: kube::Api<CustomResourceDefinition> = client.get_api(&()); |
| 108 | + let crd_established = |
| 109 | + wait::await_condition(api, crd_name, wait::conditions::is_crd_established()); |
| 110 | + let _ = tokio::time::timeout( |
| 111 | + *timeout_duration |
| 112 | + .into() |
| 113 | + .unwrap_or(DEFAULT_CRD_ESTABLISHED_TIMEOUT), |
| 114 | + crd_established, |
| 115 | + ) |
| 116 | + .await |
| 117 | + .context(TimeoutElapsedSnafu)? |
| 118 | + .context(ApiSnafu)?; |
| 119 | + |
| 120 | + Ok(()) |
| 121 | +} |
0 commit comments