Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(composer): allow setting 'host' network mode #96

Merged
merged 1 commit into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions composer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ tracing = "0.1.37"
once_cell = "1.18.0"
ipnetwork = "0.20.0"
bollard = "0.15.0"
strum = "0.25"
strum_macros = "0.25"

[dev-dependencies.serde]
# v1.0.198 introduces a breaking change by making use of unstable feature saturating_int_impl!
Expand Down
63 changes: 57 additions & 6 deletions composer/src/composer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use bollard::{
use futures::{StreamExt, TryStreamExt};
use ipnetwork::Ipv4Network;
use once_cell::sync::OnceCell;
use strum_macros::{Display, EnumString};

use bollard::{
auth::DockerCredentials,
Expand All @@ -44,6 +45,13 @@ pub const TEST_NET_NAME: &str = "engine-testing-network";
pub const TEST_LABEL_PREFIX: &str = "io.composer.test";
pub const TEST_NET_NETWORK: &str = "10.1.0.0/16";

#[derive(Clone, EnumString, Display, Debug, PartialEq)]
pub enum NetworkMode {
#[strum(serialize = "host")]
Host,
#[strum(serialize = "bridge")]
Bridge,
}
/// Additional configuration.
#[derive(Default, Debug)]
struct AdditionalConfig {
Expand Down Expand Up @@ -549,6 +557,10 @@ pub struct Builder {
shutdown_order: Vec<ContainerName>,
/// the network used by this experiment
network: Ipv4Network,
/// network mode for the test.
dsharma-dc marked this conversation as resolved.
Show resolved Hide resolved
/// XXX: Currently only use this to set 'host' mode if needed. Untested with
/// other modes.
network_mode: Option<NetworkMode>,
/// reuse existing containers
reuse: bool,
/// prefix for labels set on containers and networks
Expand Down Expand Up @@ -595,6 +607,7 @@ impl Builder {
existing_containers: Default::default(),
shutdown_order: vec![],
network: TEST_NET_NETWORK.parse().expect("Valid network config"),
network_mode: None,
reuse: false,
label_prefix: TEST_LABEL_PREFIX.to_string(),
allow_clean_on_panic: true,
Expand Down Expand Up @@ -694,6 +707,12 @@ impl Builder {
Ok(self)
}

/// set the network mode for this test.
pub fn network_mode(mut self, mode: NetworkMode) -> Builder {
self.network_mode = Some(mode);
self
}

/// the name to be used as labels and network name
pub fn name(mut self, name: &str) -> Builder {
self.name = name.to_string();
Expand Down Expand Up @@ -736,7 +755,11 @@ impl Builder {
self.existing_containers.remove(&spec.name);
self.containers.push((spec, next_ip));
} else {
let next_ip = self.next_ip().unwrap();
let next_ip = if self.network_mode == Some(NetworkMode::Host) {
Ipv4Addr::new(127, 0, 0, 1)
} else {
self.next_ip().unwrap()
};
tracing::debug!("Adding container: {}, ip: {}", spec.name, next_ip);
self.containers.push((spec, next_ip));
}
Expand Down Expand Up @@ -917,9 +940,14 @@ impl Builder {
srcdir,
docker,
network_id: "".to_string(),
network_mode: self.network_mode.clone(),
containers: Default::default(),
shutdown_order: self.shutdown_order,
ipam,
ipam: if self.network_mode == Some(NetworkMode::Host) {
None
} else {
Some(ipam)
},
label_prefix: self.label_prefix,
reuse: self.reuse,
allow_clean_on_panic: self.allow_clean_on_panic,
Expand All @@ -932,7 +960,12 @@ impl Builder {
rust_log_silence: self.rust_log_silence,
};

compose.network_id = compose.network_create().await.map_err(|e| e.to_string())?;
if self.network_mode == Some(NetworkMode::Host) {
let host_nw = &compose.host_network().await?[0];
dsharma-dc marked this conversation as resolved.
Show resolved Hide resolved
compose.network_id = host_nw.id.clone().unwrap();
dsharma-dc marked this conversation as resolved.
Show resolved Hide resolved
} else {
compose.network_id = compose.network_create().await.map_err(|e| e.to_string())?;
}

let compose_ref = &compose;
let create_threads = self
Expand Down Expand Up @@ -978,14 +1011,18 @@ pub struct ComposeTest {
docker: Docker,
/// the network id is used to attach containers to networks
network_id: NetworkId,
/// network mode for the test.
/// XXX: Currently only use this to set 'host' mode if needed. Untested with
/// other modes.
network_mode: Option<NetworkMode>,
/// the name of containers and their (IDs, Ipv4) we have created
/// perhaps not an ideal data structure, but we can improve it later
/// if we need to
containers: HashMap<ContainerName, (ContainerId, Ipv4Addr)>,
/// container shutdown order
shutdown_order: Vec<ContainerName>,
/// the default network configuration we use for our test cases
ipam: Ipam,
ipam: Option<Ipam>,
/// prefix for labels set on containers and networks
/// $prefix.name = $name will be created automatically
label_prefix: String,
Expand Down Expand Up @@ -1076,7 +1113,7 @@ impl ComposeTest {
internal: false,
attachable: true,
ingress: false,
ipam: self.ipam.clone(),
ipam: self.ipam.clone().unwrap_or_default(),
enable_ipv6: false,
options: vec![("com.docker.network.bridge.name", "mayabridge0")]
.into_iter()
Expand Down Expand Up @@ -1167,6 +1204,15 @@ impl ComposeTest {
.await
}

/// get host network.
pub async fn host_network(&self) -> Result<Vec<Network>, Error> {
self.docker
.list_networks(Some(ListNetworksOptions {
filters: vec![("driver", vec!["host"])].into_iter().collect(),
}))
.await
}

async fn list_network_containers(&self, name: &str) -> Result<Vec<ContainerSummary>, Error> {
self.docker
.list_containers(Some(ListContainersOptions {
Expand Down Expand Up @@ -1359,6 +1405,7 @@ impl ComposeTest {
security_opt: Some(vec!["seccomp=unconfined".into()]),
init: spec.init,
port_bindings: spec.port_map.clone(),
network_mode: self.network_mode.as_ref().map(|n| n.to_string()),
..Default::default()
};

Expand All @@ -1368,7 +1415,11 @@ impl ComposeTest {
EndpointSettings {
network_id: Some(self.network_id.to_string()),
ipam_config: Some(EndpointIpamConfig {
ipv4_address: Some(ipv4.to_string()),
ipv4_address: if self.network_mode == Some(NetworkMode::Host) {
None
} else {
Some(ipv4.to_string())
},
..Default::default()
}),
aliases: spec.network_aliases.clone(),
Expand Down
1 change: 1 addition & 0 deletions composer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ mod composer;

pub use crate::composer::{
initialize, Binary, Builder, BuilderConfigure, ComposeTest, ContainerSpec, ImagePullPolicy,
NetworkMode,
};
Loading