view src/command.rs @ 30:f4b655fae2a3

...
author AnaTofuZ <anatofuz@gmail.com>
date Sat, 21 Nov 2020 16:51:11 +0900
parents 1c3b6b6ee0b1
children 26111ba2fea1
line wrap: on
line source

use super::user;
use super::virsh;
use super::xml;

use std::{fs, io};

const TEMPLATE_DIR: &str = "/ie-ryukyu/kvm/images/templates/";
const TEMPLATE_SUFFIX: &str = "template-";
const TEMPLATE_FILE_EXTENSION: &str = ".qcow2";

pub fn list(user_name: &str) {
    let (ldump_msg, vm_list_strs) = virsh::get_vm_list(user_name);
    println!("{}", ldump_msg.info_msg);
    println!("{}", ldump_msg.border_line);
    for vm_info in vm_list_strs {
        println!("{}", vm_info);
    }
}

pub fn templates() -> io::Result<()> {
    let mut entries = fs::read_dir(TEMPLATE_DIR)?
        .map(|res| res.map(|e| e.path().display().to_string()))
        .collect::<Result<Vec<_>, io::Error>>()?;

    entries.sort();

    for entry in entries {
        let template_vm = entry
            .replace(TEMPLATE_DIR, "")
            .replace(TEMPLATE_SUFFIX, "")
            .replace(TEMPLATE_FILE_EXTENSION, "");
        println!("{}", template_vm);
    }

    Ok(())
}

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, false);
    if let Ok(xml_path) = vm_arg.generate() {
        virsh::command_require_vm_name(xml_path, "define")
    }
}

pub fn start(user_name: &str, vm_name: String) {
    virsh::command_require_vm_name(get_vm_name(user_name, &vm_name), "start");
}

pub fn shutdown(user_name: &str, vm_name: String) {
    exec_cmd_from_name_or_id(user_name, &vm_name, "shutdown")
}

pub fn destroy(user_name: &str, vm_name: String) {
    exec_cmd_from_name_or_id(user_name, &vm_name, "destroy")
}

pub fn console(user_name: &str, vm_name: String) {
    exec_cmd_from_name_or_id(user_name, &vm_name, "console")
}

pub fn vncdisplay(user_name: &str, vm_name: String) {
    exec_cmd_from_name_or_id(user_name, &vm_name, "vncdisplay")
}

pub fn ttyconsole(user_name: &str, vm_name: String) {
    exec_cmd_from_name_or_id(user_name, &vm_name, "ttyconsole")
}

pub fn dumpxml(user_name: &str, vm_name: String) {
    exec_cmd_from_name_or_id(user_name, &vm_name, "dumpxml")
}

pub fn undefine(user_name: &str, vm_name: String) {
    exec_cmd_from_name_or_id(user_name, &vm_name, "undefine")
}

pub fn domiflist(user_name: &str, vm_name: String) {
    exec_cmd_from_name_or_id(user_name, &vm_name, "domiflist")
}

pub fn dominfo(user_name: &str, vm_name: String) {
    exec_cmd_from_name_or_id(user_name, &vm_name, "dominfo")
}

pub fn dumpvncpasswd(user_name: &str, vm_name: String) {}

fn exec_cmd_from_name_or_id(user_name: &str, name_or_id: &str, command: &str) {
    if name_or_id.parse::<u8>().is_ok() {
        let vm_name_or_none = get_vm_name_from_id(user_name, &name_or_id);
        if let Some(vm_name) = vm_name_or_none {
            return virsh::command_require_vm_name(vm_name, command);
        }
    }
    virsh::command_require_vm_name(get_vm_name(user_name, name_or_id), command);
}

fn get_vm_name_from_id(user_name: &str, arg_id: &str) -> Option<String> {
    let (_, vm_list_strs) = virsh::get_vm_list(user_name);
    for vm in vm_list_strs {
        let mut splitted = vm.split_whitespace();
        let vm_id = splitted.next().unwrap();
        if (vm_id != "-") && (vm_id == arg_id) {
            let vm_name = splitted.next().unwrap();
            return Some(String::from(vm_name));
        }
    }
    None
}

fn get_vm_name(user_name: &str, vm_name: &str) -> String {
    let vm_name = match vm_name.parse::<u8>() {
        Ok(_) => format!("{}-{}", user_name, vm_name),
        Err(_) => vm_name.to_string(),
    };

    if vm_name.starts_with(user_name) {
        return vm_name;
    }
    format!("{}-{}", user_name, vm_name)
}

fn generate_vm_name(user_name: &str, vm_name: &str) -> String {
    if vm_name.starts_with(user_name) {
        return vm_name.to_string();
    }
    format!("{}-{}", user_name, vm_name)
}