netavark/commands/
teardown.rs1use crate::commands::get_config_dir;
2use crate::dns::aardvark::{Aardvark, AardvarkEntry};
3use crate::error::{NetavarkError, NetavarkErrorList, NetavarkResult};
4use crate::network::constants::DRIVER_BRIDGE;
5use crate::network::core_utils;
6use crate::network::driver::{get_network_driver, DriverInfo};
7
8use crate::{firewall, network};
9use clap::builder::NonEmptyStringValueParser;
10use clap::Parser;
11use log::debug;
12use nix::sys::signal;
13use std::ffi::OsString;
14use std::os::fd::AsFd;
15use std::path::Path;
16
17#[derive(Parser, Debug)]
18pub struct Teardown {
19 #[clap(required = true, value_parser = NonEmptyStringValueParser::new())]
21 network_namespace_path: String,
22}
23
24impl Teardown {
25 pub fn new(network_namespace_path: String) -> Self {
27 Self {
28 network_namespace_path,
29 }
30 }
31
32 pub fn exec(
33 &self,
34 input_file: Option<OsString>,
35 config_dir: Option<OsString>,
36 firewall_driver: Option<String>,
37 aardvark_bin: OsString,
38 plugin_directories: Option<Vec<OsString>>,
39 rootless: bool,
40 ) -> NetavarkResult<()> {
41 debug!("Tearing down..");
42
43 let _ = unsafe { signal::signal(signal::SIGTERM, signal::SigHandler::SigIgn) };
49 let _ = unsafe { signal::signal(signal::SIGINT, signal::SigHandler::SigIgn) };
50
51 let network_options = network::types::NetworkOptions::load(input_file)?;
52
53 let mut error_list = NetavarkErrorList::new();
54
55 let dns_port = core_utils::get_netavark_dns_port()?;
56 let config_dir = get_config_dir(config_dir, "teardown")?;
57
58 let mut aardvark_entries = Vec::new();
59 for (key, network) in &network_options.network_info {
60 if network.dns_enabled && network.driver == DRIVER_BRIDGE {
61 match network_options.container_id.as_str().try_into() {
62 Ok(id) => {
63 aardvark_entries.push(AardvarkEntry {
64 network_name: key,
65 network_gateways: Vec::new(),
66 network_dns_servers: &None,
67 container_id: id,
68 container_ips_v4: Vec::new(),
69 container_ips_v6: Vec::new(),
70 container_names: Vec::new(),
71 container_dns_servers: &None,
72 is_internal: network.internal,
73 });
74 }
75 Err(err) => log::warn!(
76 "invalid container id {}: {err}",
77 network_options.container_id
78 ),
79 }
80 }
81 }
82
83 if !aardvark_entries.is_empty() {
84 let path = Path::new(&config_dir).join("aardvark-dns");
86
87 let aardvark_interface = Aardvark::new(path, rootless, aardvark_bin, dns_port);
88 if let Err(err) = aardvark_interface.delete_from_netavark_entries(&aardvark_entries) {
89 error_list.push(NetavarkError::wrap("remove aardvark entries", err));
90 }
91 }
92
93 let firewall_driver = firewall::get_supported_firewall_driver(firewall_driver)?;
94
95 let (mut hostns, mut netns) =
96 core_utils::open_netlink_sockets(&self.network_namespace_path)?;
97
98 for (net_name, network) in network_options.network_info.iter() {
99 let per_network_opts = match network_options.networks.get(net_name) {
100 Some(opts) => opts,
101 None => {
102 error_list.push(NetavarkError::Message(format!(
103 "network options for network {net_name} not found"
104 )));
105 continue;
106 }
107 };
108
109 let driver = match get_network_driver(
110 DriverInfo {
111 firewall: firewall_driver.as_ref(),
112 container_id: &network_options.container_id,
113 container_name: &network_options.container_name,
114 container_hostname: &network_options.container_hostname,
115 container_dns_servers: &network_options.dns_servers,
116 netns_host: hostns.file.as_fd(),
117 netns_container: netns.file.as_fd(),
118 netns_path: &self.network_namespace_path,
119 network,
120 per_network_opts,
121 port_mappings: &network_options.port_mappings,
122 dns_port,
123 config_dir: Path::new(&config_dir),
124 rootless,
125 },
126 &plugin_directories,
127 ) {
128 Ok(driver) => driver,
129 Err(err) => {
130 error_list.push(err);
131 continue;
132 }
133 };
134
135 match driver.teardown((&mut hostns.netlink, &mut netns.netlink)) {
136 Ok(_) => {}
137 Err(err) => {
138 error_list.push(err);
139 continue;
140 }
141 };
142 }
143
144 if !error_list.is_empty() {
145 return Err(NetavarkError::List(error_list));
146 }
147
148 debug!("Teardown complete");
149 Ok(())
150 }
151}