Procházet zdrojové kódy

使用 libvirt 添加 kvm 管理接口

reghao před 5 roky
rodič
revize
8a9fb922ac
21 změnil soubory, kde provedl 475 přidání a 65 odebrání
  1. 15 15
      common/src/main/java/cn/reghao/autodop/common/stat/linux/LinuxSys.java
  2. 1 1
      common/src/main/java/cn/reghao/autodop/common/stat/linux/pojo/LinuxSysInfo.java
  3. 1 1
      common/src/main/java/cn/reghao/autodop/common/stat/linux/pojo/LinuxSysStat.java
  4. 2 2
      dagent/src/main/java/cn/reghao/autodop/dagent/node/agent/AgentInfo.java
  5. 0 12
      dagent/src/main/java/cn/reghao/autodop/dagent/service/MachineStatusScheduler.java
  6. 18 0
      dmaster/pom.xml
  7. 2 2
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/tools/updater/GitImpl.java
  8. 1 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/config/WebSecurityConfig.java
  9. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/jwt/JwtTokenFilter.java
  10. 18 18
      dmaster/src/main/java/cn/reghao/autodop/dmaster/monitor/MonitorController.java
  11. 13 13
      dmaster/src/main/java/cn/reghao/autodop/dmaster/monitor/MonitorService.java
  12. 29 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/controller/PhysicalHostController.java
  13. 51 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/controller/VirtualDiskController.java
  14. 15 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/controller/VirtualHostController.java
  15. 29 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/kvm/Network.java
  16. 131 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/kvm/Storage.java
  17. 78 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/kvm/VirtualHost.java
  18. 25 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/pojo/PoolInfo.java
  19. 23 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/pojo/VolumeInfo.java
  20. 11 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/service/VirtualDiskService.java
  21. 11 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/service/VirtualHostService.java

+ 15 - 15
common/src/main/java/cn/reghao/autodop/common/stat/linux/LinuxSys.java

@@ -1,7 +1,7 @@
 package cn.reghao.autodop.common.stat.linux;
 
-import cn.reghao.autodop.common.stat.linux.pojo.SysInfo;
-import cn.reghao.autodop.common.stat.linux.pojo.SysStat;
+import cn.reghao.autodop.common.stat.linux.pojo.LinuxSysInfo;
+import cn.reghao.autodop.common.stat.linux.pojo.LinuxSysStat;
 
 /**
  * @author reghao
@@ -22,24 +22,24 @@ public class LinuxSys {
         this.network = new Network();
     }
 
-    public SysInfo info() {
-        SysInfo sysInfo = new SysInfo();
-        sysInfo.setOs(os.info());
-        sysInfo.setCpu(cpu.info());
-        sysInfo.setMemory(memory.info());
-        sysInfo.setDisk(disk.info());
-        sysInfo.setNetwork(network.info());
-        return sysInfo;
+    public LinuxSysInfo info() {
+        LinuxSysInfo linuxSysInfo = new LinuxSysInfo();
+        linuxSysInfo.setOs(os.info());
+        linuxSysInfo.setCpu(cpu.info());
+        linuxSysInfo.setMemory(memory.info());
+        linuxSysInfo.setDisk(disk.info());
+        linuxSysInfo.setNetwork(network.info());
+        return linuxSysInfo;
     }
 
-    public SysStat stat() {
-        SysStat sysStat = new SysStat();
+    public LinuxSysStat stat() {
+        LinuxSysStat linuxSysStat = new LinuxSysStat();
         try {
-            sysStat.setOs(os.stat());
+            linuxSysStat.setOs(os.stat());
         } catch (Exception e) {
             e.printStackTrace();
         }
-        sysStat.setMemory(memory.info());
-        return sysStat;
+        linuxSysStat.setMemory(memory.info());
+        return linuxSysStat;
     }
 }

+ 1 - 1
common/src/main/java/cn/reghao/autodop/common/stat/linux/pojo/SysInfo.java → common/src/main/java/cn/reghao/autodop/common/stat/linux/pojo/LinuxSysInfo.java

@@ -9,7 +9,7 @@ import java.util.List;
  * @date 2020-10-22 15:45:29
  */
 @Data
-public class SysInfo {
+public class LinuxSysInfo {
     private OSInfo os;
     private CPUInfo cpu;
     private MemoryInfo memory;

+ 1 - 1
common/src/main/java/cn/reghao/autodop/common/stat/linux/pojo/SysStat.java → common/src/main/java/cn/reghao/autodop/common/stat/linux/pojo/LinuxSysStat.java

@@ -10,7 +10,7 @@ import java.util.List;
  * @date 2020-10-22 15:45:43
  */
 @Data
-public class SysStat {
+public class LinuxSysStat {
     private OSStat os;
     private CpuStat cpu;
     private MemoryInfo memory;

+ 2 - 2
dagent/src/main/java/cn/reghao/autodop/dagent/node/agent/AgentInfo.java

@@ -1,7 +1,7 @@
 package cn.reghao.autodop.dagent.node.agent;
 
 import cn.reghao.autodop.common.stat.jvm.pojo.JVMInfo;
-import cn.reghao.autodop.common.stat.linux.pojo.SysInfo;
+import cn.reghao.autodop.common.stat.linux.pojo.LinuxSysInfo;
 import lombok.Data;
 
 /**
@@ -13,7 +13,7 @@ public class AgentInfo {
     private String agentId;
     private String agentAddress;
     private JVMInfo jvmInfo;
-    private SysInfo sysInfo;
+    private LinuxSysInfo linuxSysInfo;
 
     public AgentInfo() {
     }

+ 0 - 12
dagent/src/main/java/cn/reghao/autodop/dagent/service/MachineStatusScheduler.java

@@ -1,9 +1,5 @@
 package cn.reghao.autodop.dagent.service;
 
-import cn.reghao.autodop.common.stat.linux.CPU;
-import cn.reghao.autodop.common.stat.linux.Memory;
-import cn.reghao.autodop.common.stat.linux.Network;
-import cn.reghao.autodop.common.stat.linux.Process;
 import cn.reghao.autodop.common.stat.linux.pojo.os.SysStat;
 import cn.reghao.autodop.common.mq.MqMessage;
 import cn.reghao.autodop.common.mq.MsgType;
@@ -21,16 +17,8 @@ import org.springframework.stereotype.Component;
 @Component
 public class MachineStatusScheduler {
     private MessageSender sender;
-    private CPU cpu;
-    private Memory mem;
-    private Process proc;
-    private Network net;
 
     public MachineStatusScheduler(MessageSender sender) {
-        this.cpu = new CPU();
-        this.mem = new Memory();
-        this.proc = new Process();
-        this.net = new Network();
         this.sender = sender;
     }
 

+ 18 - 0
dmaster/pom.xml

@@ -112,6 +112,24 @@
             <artifactId>jjwt</artifactId>
             <version>0.9.1</version>
         </dependency>
+
+        <dependency>
+            <groupId>net.java.dev.jna</groupId>
+            <artifactId>jna</artifactId>
+            <version>4.1.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.libvirt</groupId>
+            <artifactId>libvirt</artifactId>
+            <version>0.5.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dom4j</groupId>
+            <artifactId>dom4j</artifactId>
+            <version>2.1.1</version>
+        </dependency>
     </dependencies>
 
     <profiles>

+ 2 - 2
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/tools/updater/GitImpl.java

@@ -215,8 +215,8 @@ public class GitImpl implements CodeUpdater {
 
     public static void main(String[] args) throws Exception {
         GitImpl git = new GitImpl("azyadmin", "xjV^Ilw2");
-        String remote = "https://codeup.aliyun.com/5f1f8daf6207a1a8b17f6742/FrontEnd/IQuizoo.BMS.git";
-        String local = "/home/reghao/opt/data/autodop/local-repo/dnkt-mgr";
+        String remote = "https://codeup.aliyun.com/5f1f8daf6207a1a8b17f6742/background/ContentService.git";
+        String local = "/home/reghao/opt/data/autodop/local-repo/content";
         CommitLog log = git.update(remote, "develop", local);
         System.out.println();
     }

+ 1 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/config/WebSecurityConfig.java

@@ -40,6 +40,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                 .antMatchers("/**").permitAll()
                 // TODO 放行所有接口(测试时使用)
                 .antMatchers("/api/monitor/**").permitAll()
+                .antMatchers("/api/vm/**").permitAll()
                 .antMatchers("/logout").permitAll()
                 .antMatchers("/actuator/health").permitAll()
                 .anyRequest().authenticated();

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/jwt/JwtTokenFilter.java

@@ -29,7 +29,7 @@ public class JwtTokenFilter extends OncePerRequestFilter {
         String uri = request.getRequestURI();
         String method = request.getMethod();
         // TODO 不处理 OPTIONS 请求、webhook 接口和非 /api 开头的请求
-        if ("OPTIONS".equals(method) || uri.startsWith("/api/monitor") || !uri.startsWith("/api")) {
+        if ("OPTIONS".equals(method) || uri.startsWith("/api/monitor") || uri.startsWith("/api/vm") || !uri.startsWith("/api")) {
             chain.doFilter(request, response);
             return;
         }

+ 18 - 18
dmaster/src/main/java/cn/reghao/autodop/dmaster/sys/SysController.java → dmaster/src/main/java/cn/reghao/autodop/dmaster/monitor/MonitorController.java

@@ -1,4 +1,4 @@
-package cn.reghao.autodop.dmaster.sys;
+package cn.reghao.autodop.dmaster.monitor;
 
 import cn.reghao.autodop.common.result.WebResult;
 import io.swagger.annotations.Api;
@@ -8,33 +8,33 @@ import org.springframework.web.bind.annotation.*;
  * @author reghao
  * @date 2019-11-15 08:44:50
  */
-@Api(tags = "系统接口")
+@Api(tags = "监控接口")
 @RestController
 @RequestMapping("/api/monitor")
-public class SysController {
-    private SysService sysService;
+public class MonitorController {
+    private MonitorService monitorService;
 
-    public SysController(SysService sysService) {
-        this.sysService = sysService;
-    }
-
-    @GetMapping("/linux/info")
-    public String osInfo() {
-        return WebResult.success(sysService.linuxSysInfo());
-    }
-
-    @GetMapping("/linux/stat")
-    public String osStat() {
-        return WebResult.success(sysService.linuxSysStat());
+    public MonitorController(MonitorService monitorService) {
+        this.monitorService = monitorService;
     }
 
     @GetMapping("/jvm/info")
     public String jvmInfo() {
-        return WebResult.success(sysService.jvmInfo());
+        return WebResult.success(monitorService.jvmInfo());
     }
 
     @GetMapping("/jvm/stat")
     public String jvmStat() {
-        return WebResult.success(sysService.jvmStat());
+        return WebResult.success(monitorService.jvmStat());
+    }
+
+    @GetMapping("/linux/info")
+    public String osInfo() {
+        return WebResult.success(monitorService.linuxSysInfo());
+    }
+
+    @GetMapping("/linux/stat")
+    public String osStat() {
+        return WebResult.success(monitorService.linuxSysStat());
     }
 }

+ 13 - 13
dmaster/src/main/java/cn/reghao/autodop/dmaster/sys/SysService.java → dmaster/src/main/java/cn/reghao/autodop/dmaster/monitor/MonitorService.java

@@ -1,11 +1,11 @@
-package cn.reghao.autodop.dmaster.sys;
+package cn.reghao.autodop.dmaster.monitor;
 
 import cn.reghao.autodop.common.stat.jvm.JVM;
 import cn.reghao.autodop.common.stat.jvm.pojo.JVMInfo;
 import cn.reghao.autodop.common.stat.jvm.pojo.JVMStat;
 import cn.reghao.autodop.common.stat.linux.LinuxSys;
-import cn.reghao.autodop.common.stat.linux.pojo.SysInfo;
-import cn.reghao.autodop.common.stat.linux.pojo.SysStat;
+import cn.reghao.autodop.common.stat.linux.pojo.LinuxSysInfo;
+import cn.reghao.autodop.common.stat.linux.pojo.LinuxSysStat;
 import org.springframework.stereotype.Service;
 
 /**
@@ -13,23 +13,15 @@ import org.springframework.stereotype.Service;
  * @date 2020-10-22 17:51:56
  */
 @Service
-public class SysService {
+public class MonitorService {
     private JVM jvm;
     private LinuxSys linuxSys;
 
-    public SysService() {
+    public MonitorService() {
         this.jvm = new JVM();
         this.linuxSys = new LinuxSys();
     }
 
-    public SysInfo linuxSysInfo() {
-        return linuxSys.info();
-    }
-
-    public SysStat linuxSysStat() {
-        return null;
-    }
-
     public JVMInfo jvmInfo() {
         return jvm.info();
     }
@@ -37,4 +29,12 @@ public class SysService {
     public JVMStat jvmStat() {
         return jvm.stat();
     }
+
+    public LinuxSysInfo linuxSysInfo() {
+        return linuxSys.info();
+    }
+
+    public LinuxSysStat linuxSysStat() {
+        return null;
+    }
 }

+ 29 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/controller/PhysicalHostController.java

@@ -0,0 +1,29 @@
+package cn.reghao.autodop.dmaster.vm.controller;
+
+import cn.reghao.autodop.common.result.WebResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author reghao
+ * @date 2020-10-31 16:04:58
+ */
+@Api(tags = "物理主机管理接口")
+@RestController
+@RequestMapping("/api/vm/phost")
+public class PhysicalHostController {
+    @PostMapping
+    public String addPhysicalHost() {
+        return WebResult.success("ok");
+    }
+
+    @ApiOperation(value = "")
+    @GetMapping("/list")
+    public String nodeList() {
+        return WebResult.success("ok");
+    }
+}

+ 51 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/controller/VirtualDiskController.java

@@ -0,0 +1,51 @@
+package cn.reghao.autodop.dmaster.vm.controller;
+
+import cn.reghao.autodop.common.result.WebResult;
+import cn.reghao.autodop.dmaster.vm.kvm.Storage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author reghao
+ * @date 2020-10-31 16:04:58
+ */
+@Api(tags = "虚拟磁盘管理接口")
+@RestController
+@RequestMapping("/api/vm/vdisk")
+public class VirtualDiskController {
+    private String uri = "qemu:///system";
+    private Storage storage = new Storage(uri);
+
+    @ApiOperation(value = "")
+    @PostMapping("/pool")
+    public String addPool(@RequestBody String data) throws Exception {
+        storage.createStoragePool();
+        return WebResult.success("ok");
+    }
+
+    @ApiOperation(value = "")
+    @GetMapping("/pool")
+    public String getPool() throws Exception {
+        return WebResult.success(storage.listStoragePool());
+    }
+
+    @ApiOperation(value = "")
+    @DeleteMapping("/pool/{poolName}")
+    public String deletePool(@PathVariable("poolName") String poolName) throws Exception {
+        storage.deleteStoragePool(poolName);
+        return WebResult.success("ok");
+    }
+
+    @ApiOperation(value = "")
+    @PostMapping("/volume/{poolName}")
+    public String addVolume(@PathVariable("poolName") String poolName) throws Exception {
+        return WebResult.success(storage.listStorageVolume(poolName));
+    }
+
+    @ApiOperation(value = "")
+    @GetMapping("/volume/{poolName}")
+    public String getVolume(@PathVariable("poolName") String poolName) throws Exception {
+        return WebResult.success(storage.listStorageVolume(poolName));
+    }
+}

+ 15 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/controller/VirtualHostController.java

@@ -0,0 +1,15 @@
+package cn.reghao.autodop.dmaster.vm.controller;
+
+import io.swagger.annotations.Api;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author reghao
+ * @date 2020-10-31 16:04:58
+ */
+@Api(tags = "虚拟主机管理接口")
+@RestController
+@RequestMapping("/api/vm/vhost")
+public class VirtualHostController {
+}

+ 29 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/kvm/Network.java

@@ -0,0 +1,29 @@
+package cn.reghao.autodop.dmaster.vm.kvm;
+
+import org.libvirt.Connect;
+
+/**
+ * @author reghao
+ * @date 2020-10-29 14:29:40
+ */
+public class Network {
+    private String uri;
+
+    public Network(String uri) {
+        this.uri = uri;
+    }
+
+    public void listNetwork() throws Exception {
+        Connect conn = new Connect(uri, false);
+        String[] networks = conn.listNetworks();
+        String[] networkFilters = conn.listNetworkFilters();
+        String[] definedNetworks = conn.listDefinedNetworks();
+        System.out.println();
+    }
+
+    public static void main(String[] args) throws Exception {
+        String uri = "qemu:///system";
+        Network network = new Network(uri);
+        network.listNetwork();
+    }
+}

+ 131 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/kvm/Storage.java

@@ -0,0 +1,131 @@
+package cn.reghao.autodop.dmaster.vm.kvm;
+
+import cn.reghao.autodop.dmaster.vm.pojo.PoolInfo;
+import cn.reghao.autodop.dmaster.vm.pojo.VolumeInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.dom4j.Document;
+import org.dom4j.io.SAXReader;
+import org.libvirt.*;
+
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 存储
+ *
+ * @author reghao
+ * @date 2020-10-28 21:44:01
+ */
+@Slf4j
+public class Storage {
+    private String uri;
+
+    public Storage(String uri) {
+        this.uri = uri;
+    }
+
+    public void createStoragePool() throws Exception {
+        Connect conn = new Connect(uri, false);
+        String xml = "/home/reghao/docs/zzz/backend/kvm/xml/pool.xml";
+        Document doc = new SAXReader().read(new FileInputStream(xml));
+        StoragePool storagePool = conn.storagePoolCreateXML(doc.asXML(), 0);
+    }
+
+    public List<PoolInfo> listStoragePool() throws Exception {
+        Connect conn = new Connect(uri, false);
+
+        List<PoolInfo> list = new ArrayList<>();
+        String[] inactivePoolNames = conn.listDefinedStoragePools();
+        for (String poolName : inactivePoolNames) {
+            StoragePool storagePool = conn.storagePoolLookupByName(poolName);
+            storagePool.isPersistent();
+            storagePool.isActive();
+            storagePool.getAutostart();
+            storagePool.getXMLDesc(0);
+            storagePool.getUUIDString();
+            list.add(new PoolInfo(poolName, storagePool.getInfo()));
+        }
+
+        String[] activePoolNames = conn.listStoragePools();
+        for (String poolName : activePoolNames) {
+            StoragePool storagePool = conn.storagePoolLookupByName(poolName);
+            list.add(new PoolInfo(poolName, storagePool.getInfo()));
+        }
+
+        return list;
+    }
+
+    public void deleteStoragePool(String poolName) throws Exception {
+        Connect conn = new Connect(uri, false);
+        StoragePool storagePool = conn.storagePoolLookupByName(poolName);
+        int res = storagePool.isActive();
+        if (res == 1) {
+            //storagePool.destroy();
+            //storagePool.undefine();
+            // 释放所有与存储池关联的内存,存储池的状态不会改变
+            storagePool.free();
+        } else if (res == 0) {
+            //
+            storagePool.undefine();
+            storagePool.free();
+        } else {
+            throw new Exception("存储池状态错误...");
+        }
+    }
+
+    public StorageVol createStorageVolume(StoragePool storagePool) throws Exception {
+        String xml = "/home/reghao/docs/zzz/backend/kvm/xml/volume.xml";
+        Document doc = new SAXReader().read(new FileInputStream(xml));
+        return storagePool.storageVolCreateXML(doc.asXML(), 0);
+    }
+
+    public List<VolumeInfo> listStorageVolume(String poolName) throws Exception {
+        Connect conn = new Connect(uri, false);
+        StoragePool storagePool = conn.storagePoolLookupByName(poolName);
+
+        List<VolumeInfo> list = new ArrayList<>();
+        String[] volumeNames = storagePool.listVolumes();
+        for (String volName : volumeNames) {
+            StorageVol storageVol = storagePool.storageVolLookupByName(volName);
+            list.add(new VolumeInfo(volName, storageVol.getInfo()));
+            //list.add(storagePool.storageVolLookupByName(vol));
+            /*StorageVolInfo volInfo = storageVol.getInfo();
+            log.info("存储卷的类型:{}", volInfo.type);
+            log.info("存储卷的容量:{}GB", volInfo.capacity / 1024.00 / 1024.00 / 1024.00);
+            log.info("存储卷的已用容量:{}GB", volInfo.allocation / 1024.00 / 1024.00 / 1024.00);*/
+        }
+        return list;
+    }
+
+    public static void main(String[] args) throws Exception {
+        String uri = "qemu:///system";
+        Storage storage = new Storage(uri);
+
+        /*List<StoragePool> storagePools = storage.listStoragePool();
+        if (storagePools.isEmpty()) {
+            StoragePool storagePool = storage.createStoragePool();
+            //StorageVol storageVol = storage.createStorageVolume(storagePool);
+            return;
+        }
+
+        for (StoragePool storagePool: storagePools) {
+            String poolName = storagePool.getName();
+            log.info("存储池: {}", poolName);
+
+            List<StorageVol> storageVols = storage.listStorageVolume(storagePool.getName());
+            if (!storageVols.isEmpty()) {
+                for (StorageVol storageVol : storageVols) {
+                    // 释放所有指向 volume 的指针(domain)
+                    //storageVol.free();
+                    // 物理删除
+                    storageVol.delete(0);
+                    log.info("存储卷:{}", storageVol.getName());
+                }
+            } else {
+                storage.createStorageVolume(storagePool);
+            }
+            log.info("---------------------------------------------------------------------");
+        }*/
+    }
+}

+ 78 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/kvm/VirtualHost.java

@@ -0,0 +1,78 @@
+package cn.reghao.autodop.dmaster.vm.kvm;
+
+import org.dom4j.Document;
+import org.dom4j.io.SAXReader;
+import org.libvirt.Connect;
+import org.libvirt.Domain;
+
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 虚拟主机
+ *
+ * @author reghao
+ * @date 2020-10-28 18:48:52
+ */
+public class VirtualHost {
+    private String uri;
+
+    public VirtualHost(String uri) {
+        this.uri = uri;
+    }
+
+    public void start(Domain domain) throws Exception {
+        domain.create();
+    }
+
+    public void restart(Domain domain) throws Exception {
+        domain.reboot(0);
+    }
+
+    public void stop(Domain domain) throws Exception {
+        domain.shutdown();
+    }
+
+    public Domain createDomain() throws Exception {
+        Connect conn = new Connect(uri, false);
+        String xml = "/home/reghao/docs/zzz/backend/kvm/xml/vhost.xml";
+        Document doc = new SAXReader().read(new FileInputStream(xml));
+        return conn.domainDefineXML(doc.asXML());
+    }
+
+    public List<Domain> listDomain() throws Exception {
+        Connect conn = new Connect(uri, false);
+        List<Domain> list = new ArrayList<>();
+        String[] domainNames = conn.listDefinedDomains();
+        for (String domainName : domainNames) {
+            list.add(conn.domainLookupByName(domainName));
+        }
+
+        int[] active = conn.listDomains();
+        for (int id : active) {
+            list.add(conn.domainLookupByID(id));
+        }
+        return list;
+    }
+
+    public static void main(String[] args) throws Exception {
+        String uri = "qemu:///system";
+
+        VirtualHost vhost = new VirtualHost(uri);
+        Domain domain1 = vhost.createDomain();
+
+        List<Domain> domains = vhost.listDomain();
+        for (Domain domain : domains) {
+            String domainName = domain.getName();
+            domain.undefine();
+            domain.free();
+
+            /*String xmlDesc = domain.getXMLDesc(0);
+            domain.detachDevice(xmlDesc);
+            domain.destroy();*/
+        }
+
+        System.out.println();
+    }
+}

+ 25 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/pojo/PoolInfo.java

@@ -0,0 +1,25 @@
+package cn.reghao.autodop.dmaster.vm.pojo;
+
+import lombok.Data;
+import org.libvirt.StoragePoolInfo;
+
+/**
+ * @author reghao
+ * @date 2020-10-31 19:08:19
+ */
+@Data
+public class PoolInfo {
+    private String name;
+    private String state;
+    private long capacity;
+    private long allocation;
+    private long available;
+
+    public PoolInfo(String name, StoragePoolInfo storagePoolInfo) {
+        this.name = name;
+        this.state = storagePoolInfo.state.name();
+        this.capacity = storagePoolInfo.capacity;
+        this.allocation = storagePoolInfo.allocation;
+        this.available = storagePoolInfo.available;
+    }
+}

+ 23 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/pojo/VolumeInfo.java

@@ -0,0 +1,23 @@
+package cn.reghao.autodop.dmaster.vm.pojo;
+
+import lombok.Data;
+import org.libvirt.StorageVolInfo;
+
+/**
+ * @author reghao
+ * @date 2020-10-31 19:08:26
+ */
+@Data
+public class VolumeInfo {
+    private String name;
+    private String type;
+    private long capacity;
+    private long allocation;
+
+    public VolumeInfo(String name, StorageVolInfo storageVolInfo) {
+        this.name = name;
+        this.type = storageVolInfo.type.name();
+        this.capacity = storageVolInfo.capacity;
+        this.allocation = storageVolInfo.allocation;
+    }
+}

+ 11 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/service/VirtualDiskService.java

@@ -0,0 +1,11 @@
+package cn.reghao.autodop.dmaster.vm.service;
+
+import org.springframework.stereotype.Service;
+
+/**
+ * @author reghao
+ * @date 2020-10-31 16:04:58
+ */
+@Service
+public class VirtualDiskService {
+}

+ 11 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/vm/service/VirtualHostService.java

@@ -0,0 +1,11 @@
+package cn.reghao.autodop.dmaster.vm.service;
+
+import org.springframework.stereotype.Service;
+
+/**
+ * @author reghao
+ * @date 2020-10-31 16:04:58
+ */
+@Service
+public class VirtualHostService {
+}