-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdocker_utils.rs
121 lines (108 loc) · 4.79 KB
/
docker_utils.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// SPDX-FileCopyrightText: © 2024 Claudio Cicconetti <c.cicconetti@iit.cnr.it>
// SPDX-License-Identifier: MIT
/// Docker utilities.
pub struct Docker {}
impl Docker {
/// Connect to a Docker daemon.
pub fn connect() -> anyhow::Result<rs_docker::Docker> {
let path = "/var/run/docker.sock";
if !std::path::Path::new(path).exists() {
Err(anyhow::anyhow!(
"the path to Docker ({}) does not exist, this likely means that Docker is not installed: bailing out ot the test",
path
))
} else {
match rs_docker::Docker::connect(format!("unix://{}", path).as_str()) {
Ok(docker) => Ok(docker),
Err(err) => Err(anyhow::anyhow!("could not connect to Docker, bailing out: {}", err)),
}
}
}
/// Start a container with a given image, which must be available locally.
/// The name is automatically selected as a random UUID; the ID is returned.
/// It is assumed that a TCP port bound to 0.0.0.0 is published, the
/// public port number is returned, too.
pub fn start(docker: &mut rs_docker::Docker, image_name: String) -> anyhow::Result<(String, u64)> {
let name: String = uuid::Uuid::new_v4().to_string();
let mut devices = vec![];
// SecureExecutor will create trusted containers. In all these cases, image names
// have the following pattern "edgeless-sgx-function-<language>-<function_name>"
// Hence, if this pattern is detected, this means that we need to pass the SGX driver to the container
// This is mandatory to utilize SGX functionalities from within the container
// NUC devices are used for now that support SGX in the edge devices
if image_name.contains("edgeless-sgx-function-") {
let sgx_nuc_driver = crate::container_runner::container_devices::get_sgx_nuc_driver();
devices.push(sgx_nuc_driver);
}
let id = match docker.create_container(
name.to_string(),
rs_docker::container::ContainerCreate {
Image: image_name.clone(),
Labels: None,
ExposedPorts: None,
HostConfig: Some(rs_docker::container::HostConfigCreate {
NetworkMode: None,
PublishAllPorts: Some(true),
PortBindings: None,
Devices: Some(devices),
}),
},
) {
Ok(id) => id,
Err(err) => {
return Err(anyhow::anyhow!(
"could not create the container, this likely means that the image is not available locally, please run: docker image pull {}: {}",
image_name,
err
))
}
};
if let Err(err) = docker.start_container(&name.to_string()) {
return Err(anyhow::anyhow!("could not start the container with image {}: {}", image_name, err));
}
let containers = match docker.get_containers(false) {
Ok(containers) => containers,
Err(err) => return Err(anyhow::anyhow!("could not list the containers: {}", err)),
};
let container = match containers.iter().find(|x| id == x.Id) {
Some(container) => container,
None => return Err(anyhow::anyhow!("could not find the newly-created container with ID {}", id)),
};
let public_port = match container.Ports.iter().find(|x| {
if let Some(ip) = &x.IP {
if ip == "0.0.0.0" {
return true;
}
}
false
}) {
Some(port) => match port.PublicPort {
Some(val) => val,
None => {
return Err(anyhow::anyhow!(
"could not find a public port to which {} is mapped for the newly-created container with ID {}",
port.PrivatePort,
id
))
}
},
None => {
return Err(anyhow::anyhow!(
"could not find a published port bound to 0.0.0.0 the newly-created container with ID {}",
id
))
}
};
Ok((id, public_port))
}
/// Stop and delete the container with a given ID.
pub fn stop(docker: &mut rs_docker::Docker, id: String) -> anyhow::Result<()> {
if let Err(err) = docker.stop_container(&id) {
return Err(anyhow::anyhow!("could not stop container with ID {}: {}", id, err));
}
if let Err(err) = docker.delete_container(&id) {
return Err(anyhow::anyhow!("could not delete container with ID {}: {}", id, err));
}
Ok(())
}
}