Skip to content

Commit e64716e

Browse files
committed
Implemented stop / state
Signed-off-by: Lukas Frank <lukas.frank@sap.com>
1 parent 2afb9e8 commit e64716e

File tree

4 files changed

+66
-16
lines changed

4 files changed

+66
-16
lines changed

src/daemon.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,8 @@ impl FeosGrpc for FeOSAPI {
349349
let id = Uuid::parse_str(&request.get_ref().uuid)
350350
.map_err(|_| Status::invalid_argument("Failed to parse UUID"))?;
351351

352-
self.vmm.shutdown_vm(id).map_err(handle_error)?;
352+
// TODO differentiate between kill and shutdown
353+
self.vmm.kill_vm(id).map_err(handle_error)?;
353354

354355
Ok(Response::new(feos_grpc::ShutdownVmResponse {}))
355356
}

src/isolated_container/mod.rs

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::container::container_service::container_service_client::ContainerServiceClient;
2-
use crate::container::container_service::{CreateContainerRequest, RunContainerRequest};
2+
use crate::container::container_service::{CreateContainerRequest, RunContainerRequest, StateContainerRequest};
33
use crate::daemon::FeOSAPI;
44
use crate::feos_grpc::Empty;
55
use crate::ringbuffer::RingBuffer;
@@ -88,7 +88,7 @@ fn handle_error(e: vm::Error) -> tonic::Status {
8888
}
8989
}
9090

91-
async fn retry_get_channel(path: String) -> Result<Channel, Error> {
91+
async fn get_channel(path: String) -> Result<Channel, Error> {
9292
async fn get_channel(path: String) -> Result<Channel, Error> {
9393
let channel = Endpoint::try_from("http://[::]:50051")
9494
.map_err(|e| Error::Failed)?
@@ -192,7 +192,7 @@ impl IsolatedContainerService for IsolatedContainerAPI {
192192
.expect("failed to start network");
193193

194194
let path = format!("vsock{}.sock", network::Manager::device_name(&id));
195-
let channel = retry_get_channel(path).await.expect("abc");
195+
let channel = get_channel(path).await.expect("abc");
196196

197197
let mut client = ContainerServiceClient::new(channel);
198198
let request = tonic::Request::new(CreateContainerRequest {
@@ -236,7 +236,7 @@ impl IsolatedContainerService for IsolatedContainerAPI {
236236
};
237237

238238
let path = format!("vsock{}.sock", network::Manager::device_name(&vm_id));
239-
let channel = retry_get_channel(path).await.expect("abc");
239+
let channel = get_channel(path).await.expect("abc");
240240

241241
let mut client = ContainerServiceClient::new(channel);
242242
let request = tonic::Request::new(RunContainerRequest {
@@ -255,7 +255,20 @@ impl IsolatedContainerService for IsolatedContainerAPI {
255255
) -> Result<Response<isolated_container_service::StopContainerResponse>, Status> {
256256
info!("Got stop_container request");
257257

258+
258259
let container_id: String = request.get_ref().uuid.clone();
260+
let container_id = Uuid::parse_str(&container_id)
261+
.map_err(|_| Status::invalid_argument("failed to parse uuid"))?;
262+
263+
self.network
264+
.stop_dhcp(container_id)
265+
.await
266+
.expect("failed to start network");
267+
268+
self.vmm.kill_vm(container_id).map_err(handle_error)?;
269+
270+
let mut vm_to_container = self.vm_to_container.lock().unwrap();
271+
vm_to_container.remove(&container_id);
259272

260273
Ok(Response::new(
261274
isolated_container_service::StopContainerResponse {},
@@ -270,10 +283,34 @@ impl IsolatedContainerService for IsolatedContainerAPI {
270283

271284
let container_id: String = request.get_ref().uuid.clone();
272285

286+
let vm_id: String = request.get_ref().uuid.clone();
287+
let vm_id = Uuid::parse_str(&vm_id)
288+
.map_err(|_| Status::invalid_argument("failed to parse uuid"))?;
289+
290+
let container_id = {
291+
let vm_to_container = self
292+
.vm_to_container
293+
.lock()
294+
.map_err(|_| Status::internal("Failed to lock mutex"))?;
295+
*vm_to_container
296+
.get(&vm_id)
297+
.ok_or_else(|| Status::not_found(format!("VM with ID '{}' not found", vm_id)))?
298+
};
299+
300+
let path = format!("vsock{}.sock", network::Manager::device_name(&vm_id));
301+
let channel = get_channel(path).await.expect("abc");
302+
303+
let mut client = ContainerServiceClient::new(channel);
304+
let request = tonic::Request::new( StateContainerRequest {
305+
uuid: container_id.to_string(),
306+
});
307+
let response = client.state_container(request).await?;
308+
309+
273310
Ok(Response::new(
274311
isolated_container_service::StateContainerResponse {
275-
state: "".to_string(),
276-
pid: None,
312+
state: response.get_ref().state.to_string(),
313+
pid: response.get_ref().pid,
277314
},
278315
))
279316
}

src/network/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,15 @@ impl Manager {
7979
Ok(())
8080
}
8181

82+
pub async fn stop_dhcp(&self, id: Uuid) -> Result<(), Error> {
83+
let mut instances = self.instances.lock().unwrap();
84+
if let Some(handle) = instances.remove(&id) {
85+
handle.radv_handle.abort();
86+
handle.dhcpv6_handle.abort();
87+
}
88+
89+
Ok(())
90+
}
8291
pub async fn start_dhcp(&self, id: Uuid) -> Result<(), Error> {
8392
self.exists(id)?;
8493

src/vm/mod.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ impl Manager {
376376
Ok(String::new())
377377
}
378378

379-
pub fn shutdown_vm(&self, id: Uuid) -> Result<String, Error> {
379+
pub fn kill_vm(&self, id: Uuid) -> Result<String, Error> {
380380
let mut vms = self.vms.lock().unwrap();
381381
let vm_info = match vms.get_mut(&id) {
382382
Some(info) => info,
@@ -396,17 +396,20 @@ impl Manager {
396396
info!("shutdown vm: id {}, response: {}", id, x);
397397
}
398398

399-
if let Err(e) = vm_info.child.kill() {
400-
error!("Failed to kill child process for VM {}: {}", id, e);
401-
} else {
402-
info!("Sent kill signal to VM {}", id);
403-
}
404399

405-
match vm_info.child.wait() {
406-
Ok(status) => info!("VM {} exited with status {}", id, status),
407-
Err(e) => error!("Failed to wait for VM {}: {}", id, e),
400+
let response = api_client::simple_api_full_command_and_response(
401+
&mut socket,
402+
"PUT",
403+
"vmm.shutdown",
404+
None,
405+
)
406+
.map_err(Error::CHApiFailure)?;
407+
408+
if let Some(x) = &response {
409+
info!("shutdown vmm: id {}, response: {}", id, x);
408410
}
409411

412+
410413
vms.remove(&id);
411414

412415
Ok(String::new())

0 commit comments

Comments
 (0)