summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2023-10-13 14:43:03 +0000
committerAlyssa Ross <hi@alyssa.is>2023-10-13 14:56:56 +0000
commit75973286335ecdf855f7aac6d8100608b0d96a33 (patch)
treea9bbd315c461121c5f323e48e09b0aba82e3fad8
parent8669722d8c26d14f5b1e10cb9a6f5e3424df7a3d (diff)
downloadspectrum-75973286335ecdf855f7aac6d8100608b0d96a33.tar
spectrum-75973286335ecdf855f7aac6d8100608b0d96a33.tar.gz
spectrum-75973286335ecdf855f7aac6d8100608b0d96a33.tar.bz2
spectrum-75973286335ecdf855f7aac6d8100608b0d96a33.tar.lz
spectrum-75973286335ecdf855f7aac6d8100608b0d96a33.tar.xz
spectrum-75973286335ecdf855f7aac6d8100608b0d96a33.tar.zst
spectrum-75973286335ecdf855f7aac6d8100608b0d96a33.zip
host/start-vm: find config from symlink in service
This decouples start-vm from where VM configs are stored, and
decouples VM configs from VM names, which will make it possible to
have VMs that are built in to the system, and multiple VMs using the
same config with different environments (e.g. the multiple instances
of the same application).

Signed-off-by: Alyssa Ross <hi@alyssa.is>
-rw-r--r--host/rootfs/etc/s6-rc/ext-rc-init/up3
-rw-r--r--host/start-vm/lib.rs12
-rw-r--r--host/start-vm/start-vm.rs4
-rw-r--r--host/start-vm/tests/vm_command-basic.rs7
-rw-r--r--host/start-vm/tests/vm_command-multiple-disks.rs20
-rw-r--r--host/start-vm/tests/vm_command-shared-dir.rs5
6 files changed, 22 insertions, 29 deletions
diff --git a/host/rootfs/etc/s6-rc/ext-rc-init/up b/host/rootfs/etc/s6-rc/ext-rc-init/up
index cd5d2d0..92bb15c 100644
--- a/host/rootfs/etc/s6-rc/ext-rc-init/up
+++ b/host/rootfs/etc/s6-rc/ext-rc-init/up
@@ -10,7 +10,8 @@ if {
   forx -po0 -E dir { $dirs }
   backtick -E name { basename -- $dir }
 
-  if { mkdir -- ${name} ${name}/dependencies.d ${name}/env }
+  if { mkdir -- $name ${name}/data ${name}/dependencies.d ${name}/env }
+  if { ln -s $dir ${name}/data/config }
   if { redirfd -w 1 ${name}/type echo longrun }
   if { redirfd -w 1 ${name}/notification-fd echo 3 }
   if { redirfd -w 1 ${name}/run printf "#!/bin/execlineb -P\n/bin/start-vm" }
diff --git a/host/start-vm/lib.rs b/host/start-vm/lib.rs
index 8834202..3074ace 100644
--- a/host/start-vm/lib.rs
+++ b/host/start-vm/lib.rs
@@ -47,11 +47,7 @@ pub fn create_api_socket() -> Result<UnixListener, String> {
     Ok(api_socket)
 }
 
-pub fn vm_command(
-    dir: PathBuf,
-    config_root: &Path,
-    api_socket_fd: RawFd,
-) -> Result<Command, String> {
+pub fn vm_command(dir: PathBuf, api_socket_fd: RawFd) -> Result<Command, String> {
     let vm_name = dir
         .file_name()
         .ok_or_else(|| "directory has no name".to_string())?;
@@ -60,7 +56,7 @@ pub fn vm_command(
         return Err(format!("VM name may not contain a comma: {:?}", vm_name));
     }
 
-    let config_dir = config_root.join(vm_name);
+    let config_dir = dir.join("data/config");
 
     let mut command = Command::new("cloud-hypervisor");
     command.args(["--api-socket", &format!("fd={api_socket_fd}")]);
@@ -175,8 +171,6 @@ mod tests {
 
     #[test]
     fn test_vm_name_comma() {
-        assert!(vm_command("/v,m".into(), Path::new("/"), -1)
-            .unwrap_err()
-            .contains("comma"));
+        assert!(vm_command("/v,m".into(), -1).unwrap_err().contains("comma"));
     }
 }
diff --git a/host/start-vm/start-vm.rs b/host/start-vm/start-vm.rs
index df1ce0a..e3595f6 100644
--- a/host/start-vm/start-vm.rs
+++ b/host/start-vm/start-vm.rs
@@ -8,8 +8,6 @@ use std::process::exit;
 
 use start_vm::{create_api_socket, notify_readiness, prog_name, vm_command};
 
-const CONFIG_ROOT: &str = "/ext/svc/data";
-
 /// # Safety
 ///
 /// Calls [`notify_readiness`], so can only be called once.
@@ -28,7 +26,7 @@ unsafe fn run() -> String {
         return e;
     }
 
-    match vm_command(dir, Path::new(CONFIG_ROOT), api_socket.into_raw_fd()) {
+    match vm_command(dir, api_socket.into_raw_fd()) {
         Ok(mut command) => format!("failed to exec: {}", command.exec()),
         Err(e) => e,
     }
diff --git a/host/start-vm/tests/vm_command-basic.rs b/host/start-vm/tests/vm_command-basic.rs
index dc12ef2..71f20fd 100644
--- a/host/start-vm/tests/vm_command-basic.rs
+++ b/host/start-vm/tests/vm_command-basic.rs
@@ -13,15 +13,14 @@ fn main() -> std::io::Result<()> {
     let service_dir = tmp_dir.path().join("testvm");
     create_dir(&service_dir)?;
 
-    let kernel_path = tmp_dir.path().join("svc/data/testvm/vmlinux");
-    let image_path = tmp_dir.path().join("svc/data/testvm/blk/root.img");
+    let kernel_path = service_dir.join("data/config/vmlinux");
+    let image_path = service_dir.join("data/config/blk/root.img");
 
-    create_dir_all(kernel_path.parent().unwrap())?;
     create_dir_all(image_path.parent().unwrap())?;
     File::create(&kernel_path)?;
     File::create(&image_path)?;
 
-    let command = vm_command(service_dir, &tmp_dir.path().join("svc/data"), 4).unwrap();
+    let command = vm_command(service_dir, 4).unwrap();
     assert_eq!(command.get_program(), "cloud-hypervisor");
 
     let mut expected_disk_arg = OsString::from("path=");
diff --git a/host/start-vm/tests/vm_command-multiple-disks.rs b/host/start-vm/tests/vm_command-multiple-disks.rs
index 3b6f9aa..dac838e 100644
--- a/host/start-vm/tests/vm_command-multiple-disks.rs
+++ b/host/start-vm/tests/vm_command-multiple-disks.rs
@@ -12,22 +12,24 @@ fn main() -> std::io::Result<()> {
     let tmp_dir = TempDir::new()?;
 
     let service_dir = tmp_dir.path().join("testvm");
-    let vm_config = tmp_dir.path().join("svc/data/testvm");
+    let vm_config = service_dir.join("data/config");
 
-    create_dir(&service_dir)?;
     create_dir_all(&vm_config)?;
     File::create(vm_config.join("vmlinux"))?;
     create_dir(vm_config.join("blk"))?;
-    symlink("/dev/null", vm_config.join("blk/disk1.img"))?;
-    symlink("/dev/null", vm_config.join("blk/disk2.img"))?;
 
-    let command = vm_command(service_dir, &tmp_dir.path().join("svc/data"), -1).unwrap();
+    let image_paths: Vec<_> = (1..=2)
+        .map(|n| vm_config.join(format!("blk/disk{n}.img")))
+        .collect();
+
+    for image_path in &image_paths {
+        symlink("/dev/null", image_path)?;
+    }
+
+    let command = vm_command(service_dir, -1).unwrap();
     let args: Box<[_]> = command.get_args().collect();
 
-    for i in 1..=2 {
-        let image_path = tmp_dir
-            .path()
-            .join(format!("svc/data/testvm/blk/disk{i}.img"));
+    for image_path in &image_paths {
         let mut expected_disk_arg = OsString::from("path=");
         expected_disk_arg.push(image_path);
         expected_disk_arg.push(",readonly=on");
diff --git a/host/start-vm/tests/vm_command-shared-dir.rs b/host/start-vm/tests/vm_command-shared-dir.rs
index 583d19d..bfabf46 100644
--- a/host/start-vm/tests/vm_command-shared-dir.rs
+++ b/host/start-vm/tests/vm_command-shared-dir.rs
@@ -11,9 +11,8 @@ fn main() -> std::io::Result<()> {
     let tmp_dir = TempDir::new()?;
 
     let service_dir = tmp_dir.path().join("testvm");
-    let vm_config = tmp_dir.path().join("svc/data/testvm");
+    let vm_config = service_dir.join("data/config");
 
-    create_dir(&service_dir)?;
     create_dir_all(&vm_config)?;
     File::create(vm_config.join("vmlinux"))?;
     create_dir(vm_config.join("blk"))?;
@@ -27,7 +26,7 @@ fn main() -> std::io::Result<()> {
     create_dir(vm_config.join("shared-dirs/dir2"))?;
     symlink("/", vm_config.join("shared-dirs/dir2/dir"))?;
 
-    let command = vm_command(service_dir, &tmp_dir.path().join("svc/data"), -1).unwrap();
+    let command = vm_command(service_dir, -1).unwrap();
     let args: Box<[_]> = command.get_args().collect();
 
     for i in 1..=2 {