Skip to content

Commit

Permalink
feat: add mosquitto image (#19)
Browse files Browse the repository at this point in the history
* feat: add mosquitto image
* style: fix formatting issue

---------

Co-authored-by: Igor Laborie <[email protected]>
  • Loading branch information
fooker and IgorLaborieWefox authored Mar 31, 2024
1 parent 8e67497 commit c5b9c24
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 1 deletion.
3 changes: 3 additions & 0 deletions rustainers/src/images/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub use self::mongo::*;
mod alpine;
pub use self::alpine::*;

mod mosquitto;
pub use self::mosquitto::*;

/// A Generic Image
#[derive(Debug)]
pub struct GenericImage(RunnableContainer);
Expand Down
110 changes: 110 additions & 0 deletions rustainers/src/images/mosquitto.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
use std::time::Duration;

use crate::{
ExposedPort, ImageName, Port, PortError, RunnableContainer, RunnableContainerBuilder,
ToRunnableContainer, WaitStrategy,
};

const MOSQUITTO_IMAGE: &ImageName = &ImageName::new("eclipse-mosquitto");

const PORT: Port = Port(6379);

/// A `mosquitto` image
///
/// # Example
///
/// ```rust, no_run
/// # async fn run() -> anyhow::Result<()> {
/// use rustainers::images::Mosquitto;
///
/// let default_image = Mosquitto::default();
///
/// let custom_image = Mosquitto::default()
/// .with_tag("2.0.18");
///
/// # let runner = rustainers::runner::Runner::auto()?;
/// // ...
/// let container = runner.start(default_image).await?;
/// let endpoint = container.endpoint().await?;
/// // ...
/// # Ok(())
/// # }
#[derive(Debug)]
pub struct Mosquitto {
image: ImageName,
port: ExposedPort,
}

impl Mosquitto {
/// Set the image tag
#[must_use]
pub fn with_tag(self, tag: impl Into<String>) -> Self {
let Self { mut image, .. } = self;
image.set_tag(tag);
Self { image, ..self }
}

/// Set the image digest
#[must_use]
pub fn with_digest(self, digest: impl Into<String>) -> Self {
let Self { mut image, .. } = self;
image.set_digest(digest);
Self { image, ..self }
}
}

impl Mosquitto {
/// Get endpoint URL
///
/// # Errors
///
/// Could fail if the port is not bind
pub async fn endpoint(&self) -> Result<String, PortError> {
let port = self.port.host_port().await?;
let url = format!("mqtt://localhost:{port}");

Ok(url)
}
}

impl Default for Mosquitto {
fn default() -> Self {
Self {
image: MOSQUITTO_IMAGE.clone(),
port: ExposedPort::new(PORT),
}
}
}

impl ToRunnableContainer for Mosquitto {
fn to_runnable(&self, builder: RunnableContainerBuilder) -> RunnableContainer {
builder
.with_image(self.image.clone())
.with_command(["mosquitto", "-c", "/mosquitto-no-auth.conf"])
.with_wait_strategy(WaitStrategy::ScanPort {
container_port: PORT,
timeout: Duration::from_secs(10),
})
.with_port_mappings([self.port.clone()])
.build()
}
}

#[cfg(test)]
#[allow(clippy::ignored_unit_patterns)]
mod tests {

use super::*;
use assert2::{check, let_assert};

#[tokio::test]
async fn should_create_endpoint() {
let image = Mosquitto {
port: ExposedPort::fixed(PORT, Port::new(9123)),
..Default::default()
};
let result = image.endpoint().await;
let_assert!(Ok(endpoint) = result);
check!(endpoint == "mqtt://localhost:9123");
}
}
2 changes: 1 addition & 1 deletion rustainers/src/runner/podman.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ mod tests {
let json = include_str!("../../tests/assets/podman_version.json");
let version = serde_json::from_str::<PodmanVersion>(json).unwrap();
let result = serde_json::to_string_pretty(&version).unwrap();
insta::assert_display_snapshot!(result);
insta::assert_snapshot!(result);
}
#[test]
fn should_serde_compose() {
Expand Down

0 comments on commit c5b9c24

Please sign in to comment.