changeset 35:f589d5baab5f

use builder
author AnaTofuZ <anatofuz@gmail.com>
date Sun, 22 Nov 2020 10:11:02 +0900
parents 5026bf93b48e
children 91a99ff9c4c5
files src/command.rs src/xml.rs
diffstat 2 files changed, 59 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/command.rs	Sun Nov 22 09:04:24 2020 +0900
+++ b/src/command.rs	Sun Nov 22 10:11:02 2020 +0900
@@ -25,7 +25,7 @@
 
 pub fn define(user: &user::User, vm_name: String) {
     let vm_name = generate_vm_name(&user.name, &vm_name);
-    let vm_arg = xml::GenerateVMArg::new(&user.name, &vm_name, None, None);
+    let vm_arg = xml::Builder::new(user.name.clone(), vm_name).finalize();
     if let Ok(xml_path) = vm_arg.generate() {
         virsh::command_require_vm_name(xml_path, "define")
     }
--- a/src/xml.rs	Sun Nov 22 09:04:24 2020 +0900
+++ b/src/xml.rs	Sun Nov 22 10:11:02 2020 +0900
@@ -31,15 +31,6 @@
 const LIBVIRT_XML_DIR: &str = "/etc/libvirt/qemu";
 const QCOW2_PATH: &str = "/mnt/ie-virsh";
 
-pub struct GenerateVMArg {
-    vm_name: String,
-    qcow2_path: String,
-    xml_path: String,
-    vnc_password: String,
-    debug_tcp_port: Option<u64>,
-    backing_file: Option<String>,
-}
-
 pub fn dump_vnc_passwd(user: user::UserDetail, _vm_name: &str) -> Result<String, Error> {
     let user_pass = user.getpass();
     let mut reader = Reader::from_reader(BufReader::new(File::open(get_xml_dir(&user_pass))?));
@@ -59,48 +50,79 @@
     format!("{}/{}", LIBVIRT_XML_DIR, user_path)
 }
 
-impl GenerateVMArg {
-    pub fn new(
-        user_name: &str,
-        vm_name: &str,
-        debug_tcp_port: Option<u64>,
-        backing_file: Option<String>,
-    ) -> GenerateVMArg {
-        let year = user_name.chars().skip(1).take(2).collect::<String>();
+pub struct Builder {
+    user_name: String,
+    vm_name: String,
+    debug_tcp_port: Option<u64>,
+    backing_file: Option<String>,
+}
+
+pub struct GenerateVM {
+    vm_name: String,
+    qcow2_path: String,
+    xml_path: String,
+    vnc_password: String,
+    debug_tcp_port: Option<u64>,
+    backing_file: Option<String>,
+}
+
+impl Builder {
+    pub fn new(user_name: String, vm_name: String) -> Builder {
+        Builder {
+            user_name,
+            vm_name,
+            debug_tcp_port: None,
+            backing_file: None,
+        }
+    }
+
+    pub fn debug_tcp_port(&mut self, port: Option<u64>) -> &mut Builder {
+        self.debug_tcp_port = port;
+        self
+    }
+
+    pub fn backing(&mut self, backing_file: Option<String>) -> &mut Builder {
+        self.backing_file = backing_file;
+        self
+    }
+
+    pub fn finalize(&mut self) -> GenerateVM {
+        let year = self.user_name.chars().skip(1).take(2).collect::<String>();
         let affilication = if year.parse::<u8>().is_ok() {
             // /etc/libvirt/qemu/e19/e195729
-            user_name.chars().take(3).collect::<String>()
+            self.user_name.chars().take(3).collect::<String>()
         } else {
             "teacher".to_string()
         };
 
-        let xml_dir = format!("{}/{}/{}", LIBVIRT_XML_DIR, affilication, user_name);
-        let xml_path = format!("{}/{}.xml", xml_dir, vm_name);
+        let xml_dir = format!("{}/{}/{}", LIBVIRT_XML_DIR, affilication, self.user_name);
+        let xml_path = format!("{}/{}.xml", xml_dir, self.vm_name);
 
         if !Path::new(&xml_dir).exists() {
             fs::create_dir_all(xml_dir).ok();
         }
 
-        let qcow2_dir = format!("{}/{}/{}", QCOW2_PATH, affilication, user_name);
+        let qcow2_dir = format!("{}/{}/{}", QCOW2_PATH, affilication, self.user_name);
 
-        let qcow2_path = format!("{}/{}.qcow2", qcow2_dir, vm_name);
+        let qcow2_path = format!("{}/{}.qcow2", qcow2_dir, self.vm_name);
 
         if !Path::new(&qcow2_dir).exists() {
             fs::create_dir_all(qcow2_dir).ok();
         }
 
         let pw = generate_pw();
-
-        GenerateVMArg {
-            vm_name: vm_name.to_string(),
+        GenerateVM {
+            vm_name: self.vm_name.clone(),
             qcow2_path,
             xml_path,
             vnc_password: pw,
-            debug_tcp_port,
-            backing_file,
+            debug_tcp_port: self.debug_tcp_port,
+            backing_file: self.backing_file.clone(),
         }
     }
+}
 
+impl GenerateVM {
     pub fn generate(self) -> Result<String, Error> {
         let mut reader = Reader::from_reader(BufReader::new(File::open(TEMPLATE_XML_FILE)?));
 
@@ -169,17 +191,26 @@
                         .write_event(Event::Empty(backing_store_start))
                         .unwrap();
 
+                    writer.write(b"\n").unwrap();
+
                     let mut format_elem = BytesStart::borrowed_name(b"format");
                     format_elem.push_attribute(("type", "qcow2"));
                     writer.write_event(Event::Empty(format_elem)).unwrap();
+                    writer.write(b"\n").unwrap();
 
                     let mut backing_sorce = BytesStart::borrowed_name(b"sorce");
                     let backing_file: &str = self.backing_file.as_ref().unwrap();
                     backing_sorce.push_attribute(("file", backing_file));
                     writer.write_event(Event::Empty(backing_sorce)).unwrap();
+                    writer.write(b"\n").unwrap();
 
                     let backing_store_end = BytesEnd::borrowed(b"backingStore");
                     writer.write_event(Event::End(backing_store_end)).unwrap();
+                    writer.write(b"\n").unwrap();
+
+                    let disk_end = BytesEnd::borrowed(b"disk");
+                    writer.write_event(Event::End(disk_end)).unwrap();
+                    writer.write(b"\n").unwrap();
                 }
 
                 // replace qcow2 file