mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-25 23:11:57 +00:00
Merge pull request #704 from liubin/feature/689-setup-guest-DNS
agent: setup DNS for guest
This commit is contained in:
commit
6e328c0599
@ -3,8 +3,17 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
|
use anyhow::{anyhow, Context, Result};
|
||||||
|
use nix::mount::{self, MntFlags, MsFlags};
|
||||||
use protocols::types::{Interface, Route};
|
use protocols::types::{Interface, Route};
|
||||||
|
use slog::Logger;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
use crate::Sandbox;
|
||||||
|
|
||||||
|
const KATA_GUEST_SANDBOX_DNS_FILE: &str = "/run/kata-containers/sandbox/resolv.conf";
|
||||||
|
const GUEST_DNS_FILE: &str = "/etc/resolv.conf";
|
||||||
|
|
||||||
// Network fully describes a sandbox network with its interfaces, routes and dns
|
// Network fully describes a sandbox network with its interfaces, routes and dns
|
||||||
// related information.
|
// related information.
|
||||||
@ -28,3 +37,116 @@ impl Network {
|
|||||||
self.dns.push(dns);
|
self.dns.push(dns);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setup_guest_dns(logger: Logger, dns_list: Vec<String>) -> Result<()> {
|
||||||
|
do_setup_guest_dns(
|
||||||
|
logger,
|
||||||
|
dns_list,
|
||||||
|
KATA_GUEST_SANDBOX_DNS_FILE,
|
||||||
|
GUEST_DNS_FILE,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_setup_guest_dns(logger: Logger, dns_list: Vec<String>, src: &str, dst: &str) -> Result<()> {
|
||||||
|
let logger = logger.new(o!( "subsystem" => "network"));
|
||||||
|
|
||||||
|
if dns_list.len() == 0 {
|
||||||
|
info!(
|
||||||
|
logger,
|
||||||
|
"Did not set sandbox DNS as DNS not received as part of request."
|
||||||
|
);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let attr = fs::metadata(dst);
|
||||||
|
if attr.is_err() {
|
||||||
|
// not exists or other errors that we could not use it anymore.
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if attr.unwrap().is_dir() {
|
||||||
|
return Err(anyhow!("{} is a directory", GUEST_DNS_FILE));
|
||||||
|
}
|
||||||
|
|
||||||
|
// write DNS to file
|
||||||
|
let content = dns_list
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.trim())
|
||||||
|
.collect::<Vec<&str>>()
|
||||||
|
.join("\n");
|
||||||
|
fs::write(src, &content)?;
|
||||||
|
|
||||||
|
// bind mount to /etc/resolv.conf
|
||||||
|
mount::mount(Some(src), dst, Some("bind"), MsFlags::MS_BIND, None::<&str>)
|
||||||
|
.map_err(|err| anyhow!(err).context("failed to setup guest DNS"))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::skip_if_not_root;
|
||||||
|
use nix::mount;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
use tempfile::tempdir;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_setup_guest_dns() {
|
||||||
|
skip_if_not_root!();
|
||||||
|
|
||||||
|
let drain = slog::Discard;
|
||||||
|
let logger = slog::Logger::root(drain, o!());
|
||||||
|
|
||||||
|
// create temp for /run/kata-containers/sandbox/resolv.conf
|
||||||
|
let src_dir = tempdir().expect("failed to create tmpdir");
|
||||||
|
let tmp = src_dir.path().join("resolv.conf");
|
||||||
|
let src_filename = tmp.to_str().expect("failed to get resolv file filename");
|
||||||
|
|
||||||
|
// create temp for /etc/resolv.conf
|
||||||
|
let dst_dir = tempdir().expect("failed to create tmpdir");
|
||||||
|
let tmp = dst_dir.path().join("resolv.conf");
|
||||||
|
let dst_filename = tmp.to_str().expect("failed to get resolv file filename");
|
||||||
|
{
|
||||||
|
let _file = File::create(dst_filename).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// test DNS
|
||||||
|
let dns = vec![
|
||||||
|
"nameserver 1.2.3.4".to_string(),
|
||||||
|
"nameserver 5.6.7.8".to_string(),
|
||||||
|
];
|
||||||
|
|
||||||
|
// write to /run/kata-containers/sandbox/resolv.conf
|
||||||
|
let mut src_file =
|
||||||
|
File::create(src_filename).expect(&format!("failed to create file {:?}", src_filename));
|
||||||
|
let content = dns.join("\n");
|
||||||
|
src_file
|
||||||
|
.write_all(content.as_bytes())
|
||||||
|
.expect(&format!("failed to write file contents"));
|
||||||
|
|
||||||
|
// call do_setup_guest_dns
|
||||||
|
let result = do_setup_guest_dns(logger, dns.clone(), src_filename, dst_filename);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
true,
|
||||||
|
result.is_ok(),
|
||||||
|
"result should be ok, but {:?}",
|
||||||
|
result
|
||||||
|
);
|
||||||
|
|
||||||
|
// get content of /etc/resolv.conf
|
||||||
|
let content = fs::read_to_string(dst_filename);
|
||||||
|
assert_eq!(true, content.is_ok());
|
||||||
|
let content = content.unwrap();
|
||||||
|
|
||||||
|
let expected_DNS: Vec<&str> = content.split('\n').collect();
|
||||||
|
|
||||||
|
// assert the data are the same as /run/kata-containers/sandbox/resolv.conf
|
||||||
|
assert_eq!(dns, expected_DNS);
|
||||||
|
|
||||||
|
// umount /etc/resolv.conf
|
||||||
|
let _ = mount::umount(dst_filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -37,6 +37,8 @@ use crate::linux_abi::*;
|
|||||||
use crate::metrics::get_metrics;
|
use crate::metrics::get_metrics;
|
||||||
use crate::mount::{add_storages, remove_mounts, BareMount, STORAGEHANDLERLIST};
|
use crate::mount::{add_storages, remove_mounts, BareMount, STORAGEHANDLERLIST};
|
||||||
use crate::namespace::{NSTYPEIPC, NSTYPEPID, NSTYPEUTS};
|
use crate::namespace::{NSTYPEIPC, NSTYPEPID, NSTYPEUTS};
|
||||||
|
use crate::network::setup_guest_dns;
|
||||||
|
use crate::network::Network;
|
||||||
use crate::random;
|
use crate::random;
|
||||||
use crate::sandbox::Sandbox;
|
use crate::sandbox::Sandbox;
|
||||||
use crate::version::{AGENT_VERSION, API_VERSION};
|
use crate::version::{AGENT_VERSION, API_VERSION};
|
||||||
@ -1066,6 +1068,7 @@ impl protocols::agent_ttrpc::AgentService for agentService {
|
|||||||
) -> ttrpc::Result<Empty> {
|
) -> ttrpc::Result<Empty> {
|
||||||
Ok(Empty::new())
|
Ok(Empty::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_sandbox(
|
fn create_sandbox(
|
||||||
&self,
|
&self,
|
||||||
_ctx: &ttrpc::TtrpcContext,
|
_ctx: &ttrpc::TtrpcContext,
|
||||||
@ -1131,8 +1134,27 @@ impl protocols::agent_ttrpc::AgentService for agentService {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
match setup_guest_dns(sl!(), req.dns.to_vec()) {
|
||||||
|
Ok(dns_list) => {
|
||||||
|
let sandbox = self.sandbox.clone();
|
||||||
|
let mut s = sandbox.lock().unwrap();
|
||||||
|
let _ = req
|
||||||
|
.dns
|
||||||
|
.to_vec()
|
||||||
|
.iter()
|
||||||
|
.map(|dns| s.network.set_dns(dns.to_string()));
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
return Err(ttrpc::Error::RpcStatus(ttrpc::get_status(
|
||||||
|
ttrpc::Code::INTERNAL,
|
||||||
|
e.to_string(),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Empty::new())
|
Ok(Empty::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroy_sandbox(
|
fn destroy_sandbox(
|
||||||
&self,
|
&self,
|
||||||
_ctx: &ttrpc::TtrpcContext,
|
_ctx: &ttrpc::TtrpcContext,
|
||||||
|
Loading…
Reference in New Issue
Block a user