Skip to content

Commit 3e35940

Browse files
committed
vmm: Don't include compose file in brief mode
1 parent bfd3b25 commit 3e35940

File tree

3 files changed

+85
-57
lines changed

3 files changed

+85
-57
lines changed

vmm/src/app.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ impl App {
138138
let image_path = self.config.image_path.join(&manifest.image);
139139
let image = Image::load(&image_path).context("Failed to load image")?;
140140
let vm_id = manifest.id.clone();
141+
let app_compose = vm_work_dir
142+
.app_compose()
143+
.context("Failed to read compose file")?;
141144
{
142145
let mut teapot = self.lock();
143146
let cid = teapot
@@ -152,6 +155,7 @@ impl App {
152155
cid,
153156
networking: self.config.networking.clone(),
154157
workdir: vm_work_dir.path().to_path_buf(),
158+
gateway_enabled: app_compose.gateway_enabled(),
155159
};
156160
if vm_config.manifest.disk_size > self.config.cvm.max_disk_size {
157161
bail!(
@@ -349,7 +353,7 @@ impl App {
349353
&self.work_dir(&vm.config.manifest.id),
350354
)
351355
})
352-
.map(|info| info.to_pb(&self.config.gateway))
356+
.map(|info| info.to_pb(&self.config.gateway, request.brief))
353357
.collect::<Vec<_>>();
354358
Ok(StatusResponse {
355359
vms,
@@ -378,7 +382,7 @@ impl App {
378382
};
379383
let info = vm_state
380384
.merged_info(proc_state.as_ref(), &self.work_dir(id))
381-
.to_pb(&self.config.gateway);
385+
.to_pb(&self.config.gateway, false);
382386
Ok(Some(info))
383387
}
384388

vmm/src/app/qemu.rs

Lines changed: 65 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ use std::{
1515
use super::{image::Image, VmState};
1616
use anyhow::{bail, Context, Result};
1717
use bon::Builder;
18-
use dstack_types::shared_filenames::{APP_COMPOSE, ENCRYPTED_ENV, INSTANCE_INFO, USER_CONFIG};
18+
use dstack_types::{
19+
shared_filenames::{APP_COMPOSE, ENCRYPTED_ENV, INSTANCE_INFO, USER_CONFIG},
20+
AppCompose,
21+
};
1922
use dstack_vmm_rpc as pb;
2023
use fs_err as fs;
2124
use serde::{Deserialize, Serialize};
@@ -37,6 +40,7 @@ pub struct VmInfo {
3740
pub boot_error: String,
3841
pub shutdown_progress: String,
3942
pub image_version: String,
43+
pub gateway_enabled: bool,
4044
}
4145

4246
#[derive(Debug, Builder)]
@@ -46,6 +50,7 @@ pub struct VmConfig {
4650
pub cid: u32,
4751
pub networking: Networking,
4852
pub workdir: PathBuf,
53+
pub gateway_enabled: bool,
4954
}
5055

5156
#[derive(Deserialize, Serialize)]
@@ -79,7 +84,7 @@ fn create_hd(
7984
}
8085

8186
impl VmInfo {
82-
pub fn to_pb(&self, gw: &GatewayConfig) -> pb::VmInfo {
87+
pub fn to_pb(&self, gw: &GatewayConfig, brief: bool) -> pb::VmInfo {
8388
let workdir = VmWorkDir::new(&self.workdir);
8489
pb::VmInfo {
8590
id: self.manifest.id.clone(),
@@ -90,47 +95,57 @@ impl VmInfo {
9095
boot_error: self.boot_error.clone(),
9196
shutdown_progress: self.shutdown_progress.clone(),
9297
image_version: self.image_version.clone(),
93-
configuration: Some(pb::VmConfiguration {
94-
name: self.manifest.name.clone(),
95-
image: self.manifest.image.clone(),
96-
compose_file: {
97-
fs::read_to_string(workdir.app_compose_path()).unwrap_or_default()
98-
},
99-
encrypted_env: { fs::read(workdir.encrypted_env_path()).unwrap_or_default() },
100-
user_config: { fs::read_to_string(workdir.user_config_path()).unwrap_or_default() },
101-
vcpu: self.manifest.vcpu,
102-
memory: self.manifest.memory,
103-
disk_size: self.manifest.disk_size,
104-
ports: self
105-
.manifest
106-
.port_map
107-
.iter()
108-
.map(|pm| pb::PortMapping {
109-
protocol: pm.protocol.as_str().into(),
110-
host_address: pm.address.to_string(),
111-
host_port: pm.from as u32,
112-
vm_port: pm.to as u32,
113-
})
114-
.collect(),
115-
app_id: Some(self.manifest.app_id.clone()),
116-
hugepages: self.manifest.hugepages,
117-
pin_numa: self.manifest.pin_numa,
118-
gpus: self
119-
.manifest
120-
.gpus
121-
.iter()
122-
.map(|gpu| pb::GpuSpec {
123-
product_id: gpu.product_id.clone(),
124-
slot: gpu.slot.clone(),
125-
})
126-
.collect(),
127-
}),
128-
app_url: self.instance_id.as_ref().map(|id| {
129-
format!(
130-
"https://{id}-{}.{}:{}",
131-
gw.agent_port, gw.base_domain, gw.port
132-
)
133-
}),
98+
configuration: if brief {
99+
None
100+
} else {
101+
Some(pb::VmConfiguration {
102+
name: self.manifest.name.clone(),
103+
image: self.manifest.image.clone(),
104+
compose_file: {
105+
fs::read_to_string(workdir.app_compose_path()).unwrap_or_default()
106+
},
107+
encrypted_env: { fs::read(workdir.encrypted_env_path()).unwrap_or_default() },
108+
user_config: {
109+
fs::read_to_string(workdir.user_config_path()).unwrap_or_default()
110+
},
111+
vcpu: self.manifest.vcpu,
112+
memory: self.manifest.memory,
113+
disk_size: self.manifest.disk_size,
114+
ports: self
115+
.manifest
116+
.port_map
117+
.iter()
118+
.map(|pm| pb::PortMapping {
119+
protocol: pm.protocol.as_str().into(),
120+
host_address: pm.address.to_string(),
121+
host_port: pm.from as u32,
122+
vm_port: pm.to as u32,
123+
})
124+
.collect(),
125+
app_id: Some(self.manifest.app_id.clone()),
126+
hugepages: self.manifest.hugepages,
127+
pin_numa: self.manifest.pin_numa,
128+
gpus: self
129+
.manifest
130+
.gpus
131+
.iter()
132+
.map(|gpu| pb::GpuSpec {
133+
product_id: gpu.product_id.clone(),
134+
slot: gpu.slot.clone(),
135+
})
136+
.collect(),
137+
})
138+
},
139+
app_url: self
140+
.gateway_enabled
141+
.then_some(self.instance_id.as_ref())
142+
.flatten()
143+
.map(|id| {
144+
format!(
145+
"https://{id}-{}.{}:{}",
146+
gw.agent_port, gw.base_domain, gw.port
147+
)
148+
}),
134149
app_id: self.manifest.app_id.clone(),
135150
instance_id: self.instance_id.as_deref().map(Into::into),
136151
exited_at: self.exited_at.clone(),
@@ -178,6 +193,7 @@ impl VmState {
178193
boot_error: self.state.boot_error.clone(),
179194
shutdown_progress: self.state.shutdown_progress.clone(),
180195
image_version: self.config.image.info.version.clone(),
196+
gateway_enabled: self.config.gateway_enabled,
181197
}
182198
}
183199
}
@@ -527,4 +543,10 @@ impl VmWorkDir {
527543
let info: InstanceInfo = serde_json::from_slice(&fs::read(&info_file)?)?;
528544
Ok(info)
529545
}
546+
547+
pub fn app_compose(&self) -> Result<AppCompose> {
548+
let compose_file = self.app_compose_path();
549+
let compose: AppCompose = serde_json::from_str(&fs::read_to_string(compose_file)?)?;
550+
Ok(compose)
551+
}
530552
}

vmm/src/console.html

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,17 +1418,19 @@ <h3>Derive VM</h3>
14181418
totalVMs.value = data.total || data.vms.length;
14191419
hasMorePages.value = data.vms.length === pageSize.value && totalVMs.value > (currentPage.value * pageSize.value);
14201420

1421-
vms.value = data.vms.map(vm => ({
1422-
...vm,
1423-
appCompose: (() => {
1424-
try {
1425-
return JSON.parse(vm.configuration?.compose_file || '{}');
1426-
} catch (e) {
1427-
console.error('Error parsing app config:', e);
1428-
return {};
1429-
}
1430-
})()
1431-
}));
1421+
const previousVms = vms.value;
1422+
const previousVmMap = new Map(previousVms.map(vm => [vm.id, vm]));
1423+
vms.value = data.vms.map(vm => {
1424+
const previousVm = previousVmMap.get(vm.id);
1425+
if (previousVm) {
1426+
return {
1427+
...vm,
1428+
configuration: previousVm.configuration,
1429+
appCompose: previousVm.appCompose
1430+
};
1431+
}
1432+
return vm;
1433+
});
14321434

14331435
config.value = {
14341436
portMappingEnabled: data.port_mapping_enabled
@@ -1516,6 +1518,7 @@ <h3>Derive VM</h3>
15161518
}
15171519
if (imgFeatures.compose_version < 3) {
15181520
app_compose.tproxy_enabled = app_compose.gateway_enabled;
1521+
delete app_compose["gateway_enabled"];
15191522
}
15201523
return JSON.stringify(app_compose);
15211524
};
@@ -1750,7 +1753,6 @@ <h3>Derive VM</h3>
17501753
};
17511754

17521755
const dashboardAvailable = (vm) => {
1753-
if (!gatewayEnabled(vm)) return false;
17541756
return vm.app_url
17551757
};
17561758

0 commit comments

Comments
 (0)