
云计算应该是现如今最火的领域,什么东西沾点云计算都感觉相当的Sophisticated,但真正学了以后发现没那么邪乎,虽然这项技术,或者说这个概念相当牛逼,但是只要这门课有课设,就说明这东西是能被当代大学生做出来(虽然做课设相当头疼)
那么,一个人,一个混子的故事就此开启。两台电脑,无数个日夜,终于将这个作业完成。
下面,全体观众,请欣赏 云计算Ultra Plus Pro Max(都没有)系列
SystemManager类 该模块主要用于全局管理,包括提供KVM和Docker的IP地址等信息
package manager;
import entity.Container;
import entity.Image;
import entity.VM;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.libvirt.*;
import utils.DockerUtils;
import utils.XMLUtils;
import utils.ZKClient;
import java.io.FileReader;
import java.io.IOException;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
public class SystemManager {
private static final Map vmTable;//name-domain
private static final Map vmInfoTable;//name-vm
private static final Map connectTable;//ip-connect
private static final Map ipStateTable;//ip-bool
private static final Map dnTable;//nodeIp-dn
private static final Map volTable;//name-vol
private static final Map pwdTable;//name-vol
private static final Map> ctTable;//name-container
private static final Map> imageTable;//p:v-image
public static final double B2GB = 1 << 30;
public static final double KB2GB = 1 << 20;
public static final String POOL = "pool01";
public static final String POOL_PATH = "/opt/kvm/images";
public static final String LINUX_USER_NAME = "root";
public static final String LINUX_PASSWORD = "ldw20000702";
public static final String NET_CONF_PATH = "/etc/sysconfig/network-scripts/ifcfg-ens3";
public static final String HOSTNAME_PATH = "/etc/hostname";
public static final String NFS_SERVER_IP = "192.168.43.130";
public static final String REGISTRY_IP = "192.168.43.130";
public static final int REGISTRY_PORT = 5000;
public static JSONObject NET_CONF;
public static final DecimalFormat round2 = new DecimalFormat("0.00");
public static final DecimalFormat round4 = new DecimalFormat("0.0000");
// public static Connect NFS_SERVER = null;
static {
round2.setRoundingMode(RoundingMode.HALF_UP);
round4.setRoundingMode(RoundingMode.HALF_UP);
vmTable = new HashMap<>();
vmInfoTable = new HashMap<>();
connectTable = new HashMap<>();
ipStateTable = new TreeMap<>();
dnTable = new TreeMap<>();
volTable = new HashMap<>();
pwdTable = new HashMap<>();
ctTable = new HashMap<>();
imageTable = new HashMap<>();
try {
//解析JSON文件的内容
JSONParser jsonParser = new JSONParser();
String path = Objects.requireNonNull(SystemManager.class.getClassLoader().getResource("ifcfg-ens3.json")).getPath();
NET_CONF = (JSONObject) jsonParser.parse(new FileReader(path));
} catch (ParseException | IOException e) {
e.printStackTrace();
}
refreshVM();
refreshDocker();
}
public static void refreshVM() {
vmTable.clear();
vmInfoTable.clear();
connectTable.clear();
ipStateTable.clear();
dnTable.clear();
volTable.clear();
pwdTable.clear();
try {
for (int i = 128; i < 255; i++) {
ipStateTable.put("192.168.43." + i, false);
}
ZKClient zkClient = new ZKClient();
Map ip4PM = zkClient.listIP4PM();
pwdTable.putAll(zkClient.listPSW4PM());
for (Map.Entry entry : ip4PM.entrySet()) {
String hostname = entry.getKey();
String nodeIp = entry.getValue();
String uri = "qemu+tcp://" + nodeIp + ":16509/system";
Connect connect = new Connect(uri);
connectTable.put(nodeIp, connect);
dnTable.put(nodeIp, hostname);
ipStateTable.put(nodeIp, true);
int[] ids = connect.listDomains();
String[] names = connect.listDefinedDomains();
List nameList = new LinkedList<>();
for (int id : ids) {
String name = connect.domainLookupByID(id).getName();
nameList.add(name);
}
nameList.addAll(Arrays.asList(names));
for (String domainName : nameList) {
Domain domain = connect.domainLookupByName(domainName);
long memory = (long) (domain.getInfo().memory / SystemManager.KB2GB);
int vcpu = domain.getInfo().nrVirtCpu;
int state = domain.isActive();
String ip = zkClient.getIP4VM(hostname, domainName);
String volPath = XMLUtils.getVolPath(domain.getXMLDesc(0));
StoragePool pool = connect.storagePoolLookupByName(SystemManager.POOL);
pool.refresh(0);
StorageVol vol = connect.storageVolLookupByPath(volPath);
long capacity = (long) (vol.getInfo().capacity / SystemManager.B2GB);
VM vm = new VM(nodeIp, domainName, state, ip, memory, vcpu, capacity, domain.isPersistent() == 1);
vmTable.put(domainName, domain);
vmInfoTable.put(domainName, vm);
volTable.put(domainName, vol);
ipStateTable.put(ip, true);
}
}
zkClient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void refreshDocker() {
imageTable.clear();
ctTable.clear();
dnTable.clear();
pwdTable.clear();
try {
ZKClient zkClient = new ZKClient();
pwdTable.putAll(zkClient.listPSW4PM());
Map ip4PM = zkClient.listIP4PM();
for (Map.Entry entry : ip4PM.entrySet()) {
String hostname = entry.getKey();
String nodeIp = entry.getValue();
dnTable.put(nodeIp, hostname);
DockerUtils dockerUtils = new DockerUtils(nodeIp);
imageTable.put(nodeIp, new HashMap<>());
ctTable.put(nodeIp, new HashMap<>());
for (Image image : dockerUtils.listImages()) {
imageTable.get(nodeIp).put(image.getName(), image);
}
for (Container container : dockerUtils.listContainer()) {
ctTable.get(nodeIp).put(container.getName(), container);
}
}
zkClient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static String chooseNodeIP() {
String ip = null;
double bestScore = 0;
try {
for (Map.Entry entry : connectTable.entrySet()) {
Connect connect = entry.getValue();
StoragePool pool = connect.storagePoolLookupByName(SystemManager.POOL);
if (pool.getInfo().state != StoragePoolInfo.StoragePoolState.VIR_STORAGE_POOL_RUNNING)
continue;
long freeMem = connect.getFreeMemory();
int maxVcpu = connect.getMaxVcpus("kvm");
long curVcpu = 0;
long curMem = 0;
int[] ids = connect.listDomains();
for (int id : ids) {
Domain domain = connect.domainLookupByID(id);
if (domain.isActive() == 1) {
curVcpu += domain.getInfo().nrVirtCpu;
curMem += domain.getInfo().memory;
}
}
double curScore = freeMem + maxVcpu - curMem - curVcpu;
if (curScore > bestScore) {
bestScore = curScore;
ip = entry.getKey();
}
}
} catch (LibvirtException e) {
e.printStackTrace();
}
return ip;
}
// public static String chooseIP() {
// for (Map.Entry entry : ipStateTable.entrySet()) {
// if (!entry.getValue())
// return entry.getKey();
// }
// return null;
// }
public static Map getVmTable() {
return vmTable;
}
public static Map getVmInfoTable() {
return vmInfoTable;
}
public static Map getConnectTable() {
return connectTable;
}
public static Map getIpStateTable() {
return ipStateTable;
}
public static Map getVolTable() {
return volTable;
}
public static Map getDnTable() {
return dnTable;
}
public static Map getPwdTable() {
return pwdTable;
}
public static Map> getCtTable() {
return ctTable;
}
public static Map> getImageTable() {
return imageTable;
}
}
Image类 同上,就不多写了
package entity;
public class Image {
private String id;
private String name;
private String nodeIp;
private String size;
public String getId() {
return this.id;
}
public String getName() {
return this.name;
}
public String getNodeIp() {
return this.nodeIp;
}
public String getSize() {
return this.size;
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setNodeIp(String nodeIp) {
this.nodeIp = nodeIp;
}
public void setSize(String size) {
this.size = size;
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Image)) {
return false;
} else {
Image other = (Image)o;
if (!other.canEqual(this)) {
return false;
} else {
label59: {
Object this$id = this.getId();
Object other$id = other.getId();
if (this$id == null) {
if (other$id == null) {
break label59;
}
} else if (this$id.equals(other$id)) {
break label59;
}
return false;
}
Object this$name = this.getName();
Object other$name = other.getName();
if (this$name == null) {
if (other$name != null) {
return false;
}
} else if (!this$name.equals(other$name)) {
return false;
}
Object this$nodeIp = this.getNodeIp();
Object other$nodeIp = other.getNodeIp();
if (this$nodeIp == null) {
if (other$nodeIp != null) {
return false;
}
} else if (!this$nodeIp.equals(other$nodeIp)) {
return false;
}
Object this$size = this.getSize();
Object other$size = other.getSize();
if (this$size == null) {
if (other$size != null) {
return false;
}
} else if (!this$size.equals(other$size)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(Object other) {
return other instanceof Image;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $id = this.getId();
int result = result * 59 + ($id == null ? 43 : $id.hashCode());
Object $name = this.getName();
result = result * 59 + ($name == null ? 43 : $name.hashCode());
Object $nodeIp = this.getNodeIp();
result = result * 59 + ($nodeIp == null ? 43 : $nodeIp.hashCode());
Object $size = this.getSize();
result = result * 59 + ($size == null ? 43 : $size.hashCode());
return result;
}
public String toString() {
return "Image(id=" + this.getId() + ", name=" + this.getName() + ", nodeIp=" + this.getNodeIp() + ", size=" + this.getSize() + ")";
}
public Image() {
}
public Image(String id, String name, String nodeIp, String size) {
this.id = id;
this.name = name;
this.nodeIp = nodeIp;
this.size = size;
}
}
VM类
package entity;
public class VM {
private String nodeIp;
private String domainName;
private int state;
private String ip;
private long memory;
private int vcpu;
private long capacity;
private boolean persistent;
public String getNodeIp() {
return this.nodeIp;
}
public String getDomainName() {
return this.domainName;
}
public int getState() {
return this.state;
}
public String getIp() {
return this.ip;
}
public long getMemory() {
return this.memory;
}
public int getVcpu() {
return this.vcpu;
}
public long getCapacity() {
return this.capacity;
}
public boolean isPersistent() {
return this.persistent;
}
public void setNodeIp(String nodeIp) {
this.nodeIp = nodeIp;
}
public void setDomainName(String domainName) {
this.domainName = domainName;
}
public void setState(int state) {
this.state = state;
}
public void setIp(String ip) {
this.ip = ip;
}
public void setMemory(long memory) {
this.memory = memory;
}
public void setVcpu(int vcpu) {
this.vcpu = vcpu;
}
public void setCapacity(long capacity) {
this.capacity = capacity;
}
public void setPersistent(boolean persistent) {
this.persistent = persistent;
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof VM)) {
return false;
} else {
VM other = (VM)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$nodeIp = this.getNodeIp();
Object other$nodeIp = other.getNodeIp();
if (this$nodeIp == null) {
if (other$nodeIp != null) {
return false;
}
} else if (!this$nodeIp.equals(other$nodeIp)) {
return false;
}
Object this$domainName = this.getDomainName();
Object other$domainName = other.getDomainName();
if (this$domainName == null) {
if (other$domainName != null) {
return false;
}
} else if (!this$domainName.equals(other$domainName)) {
return false;
}
if (this.getState() != other.getState()) {
return false;
} else {
Object this$ip = this.getIp();
Object other$ip = other.getIp();
if (this$ip == null) {
if (other$ip != null) {
return false;
}
} else if (!this$ip.equals(other$ip)) {
return false;
}
if (this.getMemory() != other.getMemory()) {
return false;
} else if (this.getVcpu() != other.getVcpu()) {
return false;
} else if (this.getCapacity() != other.getCapacity()) {
return false;
} else if (this.isPersistent() != other.isPersistent()) {
return false;
} else {
return true;
}
}
}
}
}
protected boolean canEqual(Object other) {
return other instanceof VM;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $nodeIp = this.getNodeIp();
int result = result * 59 + ($nodeIp == null ? 43 : $nodeIp.hashCode());
Object $domainName = this.getDomainName();
result = result * 59 + ($domainName == null ? 43 : $domainName.hashCode());
result = result * 59 + this.getState();
Object $ip = this.getIp();
result = result * 59 + ($ip == null ? 43 : $ip.hashCode());
long $memory = this.getMemory();
result = result * 59 + (int)($memory >>> 32 ^ $memory);
result = result * 59 + this.getVcpu();
long $capacity = this.getCapacity();
result = result * 59 + (int)($capacity >>> 32 ^ $capacity);
result = result * 59 + (this.isPersistent() ? 79 : 97);
return result;
}
public String toString() {
return "VM(nodeIp=" + this.getNodeIp() + ", domainName=" + this.getDomainName() + ", state=" + this.getState() + ", ip=" + this.getIp() + ", memory=" + this.getMemory() + ", vcpu=" + this.getVcpu() + ", capacity=" + this.getCapacity() + ", persistent=" + this.isPersistent() + ")";
}
public VM() {
}
public VM(String nodeIp, String domainName, int state, String ip, long memory, int vcpu, long capacity, boolean persistent) {
this.nodeIp = nodeIp;
this.domainName = domainName;
this.state = state;
this.ip = ip;
this.memory = memory;
this.vcpu = vcpu;
this.capacity = capacity;
this.persistent = persistent;
}
}
#########################################################################################
package entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class VM {
private String nodeIp;
private String domainName;
private int state;
private String ip;
private long memory;
private int vcpu;
private long capacity;
private boolean persistent;
}
VMInfo类 该模块用于获取KVM的基础信息
package entity;
import lombok.Data;
import lombok.NoArgsConstructor;
import manager.SystemManager;
@Data
@NoArgsConstructor
public class VMInfo {
private int nVcpu;
private double cpuRate;
private double memRate;
private double memTotal;
private double diskAllocation;
private double diskTotal;
public VMInfo(int nVcpu, double cpuRate, double diskAllocation, double diskTotal, double memTotal, double memAvailable) {
this.nVcpu = nVcpu;
this.cpuRate = Double.parseDouble(SystemManager.round4.format(cpuRate));
this.diskAllocation = Double.parseDouble(SystemManager.round2.format(diskAllocation));
this.diskTotal = Double.parseDouble(SystemManager.round2.format(diskTotal));
this.memTotal = Double.parseDouble(SystemManager.round2.format(memTotal));
this.memRate = Double.parseDouble(SystemManager.round2.format(1 - memAvailable / memTotal));
}
@Override
public String toString() {
return "VMInfo{" +
"nVcpu=" + nVcpu +
", cpuRate=" + cpuRate +
", memRate=" + memRate +
", memTotal=" + memTotal +
", diskAllocation=" + diskAllocation +
", diskTotal=" + diskTotal +
'}';
}
}
Container类 该模块用于
package entity;
public class Container {
private String id;
private String image;
private boolean running;
private String ip;
private String nodeIp;
private String name;
public String getId() {
return this.id;
}
public String getImage() {
return this.image;
}
public boolean isRunning() {
return this.running;
}
public String getIp() {
return this.ip;
}
public String getNodeIp() {
return this.nodeIp;
}
public String getName() {
return this.name;
}
public void setId(String id) {
this.id = id;
}
public void setImage(String image) {
this.image = image;
}
public void setRunning(boolean running) {
this.running = running;
}
public void setIp(String ip) {
this.ip = ip;
}
public void setNodeIp(String nodeIp) {
this.nodeIp = nodeIp;
}
public void setName(String name) {
this.name = name;
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Container)) {
return false;
} else {
Container other = (Container)o;
if (!other.canEqual(this)) {
return false;
} else {
//判断id是否相等
label75: {
Object this$id = this.getId();
Object other$id = other.getId();
if (this$id == null) {
if (other$id == null) {
break label75;
}
} else if (this$id.equals(other$id)) {
break label75;
}
return false;
}
//判断存储图片是否相等
Object this$image = this.getImage();
Object other$image = other.getImage();
if (this$image == null) {
if (other$image != null) {
return false;
}
} else if (!this$image.equals(other$image)) {
return false;
}
if (this.isRunning() != other.isRunning()) {
return false;
} else {
label60: {
//判断IP是否相等
Object this$ip = this.getIp();
Object other$ip = other.getIp();
if (this$ip == null) {
if (other$ip == null) {
break label60;
}
} else if (this$ip.equals(other$ip)) {
break label60;
}
return false;
}
//判断nodeIP是否相等
Object this$nodeIp = this.getNodeIp();
Object other$nodeIp = other.getNodeIp();
if (this$nodeIp == null) {
if (other$nodeIp != null) {
return false;
}
} else if (!this$nodeIp.equals(other$nodeIp)) {
return false;
}
//判断名字是否相等
Object this$name = this.getName();
Object other$name = other.getName();
if (this$name == null) {
if (other$name != null) {
return false;
}
} else if (!this$name.equals(other$name)) {
return false;
}
return true;
}
}
}
}
protected boolean canEqual(Object other) {
return other instanceof Container;
}
//用哈希表存储
public int hashCode() {
int PRIME = true;
int result = 1;
Object $id = this.getId();
int result = result * 59 + ($id == null ? 43 : $id.hashCode());
Object $image = this.getImage();
result = result * 59 + ($image == null ? 43 : $image.hashCode());
result = result * 59 + (this.isRunning() ? 79 : 97);
Object $ip = this.getIp();
result = result * 59 + ($ip == null ? 43 : $ip.hashCode());
Object $nodeIp = this.getNodeIp();
result = result * 59 + ($nodeIp == null ? 43 : $nodeIp.hashCode());
Object $name = this.getName();
result = result * 59 + ($name == null ? 43 : $name.hashCode());
return result;
}
public String toString() {
return "Container(id=" + this.getId() + ", image=" + this.getImage() + ", running=" + this.isRunning() + ", ip=" + this.getIp() + ", nodeIp=" + this.getNodeIp() + ", name=" + this.getName() + ")";
}
public Container(String id, String image, boolean running, String ip, String nodeIp, String name) {
this.id = id;
this.image = image;
this.running = running;
this.ip = ip;
this.nodeIp = nodeIp;
this.name = name;
}
public Container() {
}
}
######################################################################################
package entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Container {
private String id;
private String image;
private boolean running;
private String ip;
private String nodeIp;
private String name;
// docker run -d --name mpi01 --privileged=true centos_mpi:v1 /usr/sbin/init
}
VMServlet类 用于获取前端指令,调用后端函数
package controller;
import entity.Container;
import entity.Image;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import service.CTService;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.logging.Logger;
public class CTServlet extends HttpServlet {
private final CTService service = new CTService();
private final Logger logger = Logger.getLogger("CTServlet");
public static JSONObject receivePost(HttpServletRequest request) throws IOException {
// 读取请求内容
BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
String line;
StringBuilder stringBuilder = new StringBuilder();
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
//将json字符串转换为json对象
return JSONObject.fromObject(stringBuilder.toString());
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
JSONObject parameter = receivePost(req);
String type = String.valueOf(parameter.get("type"));
System.out.println(type);
PrintWriter writer = resp.getWriter();
boolean success = false;
JSONObject jsonObject = new JSONObject();
switch (type) {
case "list":
List vmList = service.listCT();
String jsonArray = JSONArray.fromObject(vmList).toString();
jsonObject.put("ctList", jsonArray);
success = true;
break;
case "create":
String name = String.valueOf(parameter.get("name"));
String imageName = String.valueOf(parameter.get("imageName"));
String nodeIp = String.valueOf(parameter.get("nodeIp"));
Container ct = service.createCT(nodeIp, name, imageName);
success = ct != null;
jsonObject.put("ct", ct);
break;
case "open":
name = String.valueOf(parameter.get("name"));
nodeIp = String.valueOf(parameter.get("nodeIp"));
ct = service.openCT(nodeIp, name);
success = ct != null;
jsonObject.put("ct", ct);
break;
case "close":
name = String.valueOf(parameter.get("name"));
nodeIp = String.valueOf(parameter.get("nodeIp"));
success = service.closeCT(nodeIp, name);
break;
case "delete":
name = String.valueOf(parameter.get("name"));
nodeIp = String.valueOf(parameter.get("nodeIp"));
success = service.deleteCT(nodeIp, name);
break;
case "commit":
name = String.valueOf(parameter.get("name"));
nodeIp = String.valueOf(parameter.get("nodeIp"));
String author = String.valueOf(parameter.get("author"));
String describe = String.valueOf(parameter.get("describe"));
String repository = String.valueOf(parameter.get("repository"));
String tag = String.valueOf(parameter.get("tag"));
Image image = service.commitCT(nodeIp, name, author, describe, repository, tag);
success = image != null;
jsonObject.put("image", image);
break;
}
jsonObject.put("success", success);
writer.append(jsonObject.toString());
logger.info(jsonObject.toString());
}
}
CTServlet类 同上,但是面对Docker
package controller;
import entity.Container;
import entity.Image;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import service.CTService;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.logging.Logger;
public class CTServlet extends HttpServlet {
private final CTService service = new CTService();
private final Logger logger = Logger.getLogger("CTServlet");
public static JSONObject receivePost(HttpServletRequest request) throws IOException {
// 读取请求内容
BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
String line;
StringBuilder stringBuilder = new StringBuilder();
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
//将json字符串转换为json对象
return JSONObject.fromObject(stringBuilder.toString());
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
JSONObject parameter = receivePost(req);
String type = String.valueOf(parameter.get("type"));
System.out.println(type);
PrintWriter writer = resp.getWriter();
boolean success = false;
JSONObject jsonObject = new JSONObject();
switch (type) {
case "list":
List vmList = service.listCT();
String jsonArray = JSONArray.fromObject(vmList).toString();
jsonObject.put("ctList", jsonArray);
success = true;
break;
case "create":
String name = String.valueOf(parameter.get("name"));
String imageName = String.valueOf(parameter.get("imageName"));
String nodeIp = String.valueOf(parameter.get("nodeIp"));
Container ct = service.createCT(nodeIp, name, imageName);
success = ct != null;
jsonObject.put("ct", ct);
break;
case "open":
name = String.valueOf(parameter.get("name"));
nodeIp = String.valueOf(parameter.get("nodeIp"));
ct = service.openCT(nodeIp, name);
success = ct != null;
jsonObject.put("ct", ct);
break;
case "close":
name = String.valueOf(parameter.get("name"));
nodeIp = String.valueOf(parameter.get("nodeIp"));
success = service.closeCT(nodeIp, name);
break;
case "delete":
name = String.valueOf(parameter.get("name"));
nodeIp = String.valueOf(parameter.get("nodeIp"));
success = service.deleteCT(nodeIp, name);
break;
case "commit":
name = String.valueOf(parameter.get("name"));
nodeIp = String.valueOf(parameter.get("nodeIp"));
String author = String.valueOf(parameter.get("author"));
String describe = String.valueOf(parameter.get("describe"));
String repository = String.valueOf(parameter.get("repository"));
String tag = String.valueOf(parameter.get("tag"));
Image image = service.commitCT(nodeIp, name, author, describe, repository, tag);
success = image != null;
jsonObject.put("image", image);
break;
}
jsonObject.put("success", success);
writer.append(jsonObject.toString());
logger.info(jsonObject.toString());
}
}
ImageServlet类 老样子
package controller;
import entity.Image;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import service.ImageService;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.logging.Logger;
public class ImageServlet extends HttpServlet {
private final ImageService service = new ImageService();
private final Logger logger = Logger.getLogger("ImageServlet");
public static JSONObject receivePost(HttpServletRequest request) throws IOException {
// 读取请求内容
BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
String line;
StringBuilder stringBuilder = new StringBuilder();
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
//将json字符串转换为json对象
return JSONObject.fromObject(stringBuilder.toString());
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
JSONObject parameter = receivePost(req);
String type = String.valueOf(parameter.get("type"));
System.out.println(type);
PrintWriter writer = resp.getWriter();
boolean success = false;
JSONObject jsonObject = new JSONObject();
switch (type) {
case "list":
List vmList = service.listImage();
String jsonArray = JSONArray.fromObject(vmList).toString();
jsonObject.put("imageList", jsonArray);
success = true;
break;
case "pull":
String name = String.valueOf(parameter.get("name"));
String nodeIp = String.valueOf(parameter.get("nodeIp"));
Image image = service.pullImage(nodeIp, name);
success = image != null;
jsonObject.put("image", image);
break;
case "delete":
name = String.valueOf(parameter.get("name"));
nodeIp = String.valueOf(parameter.get("nodeIp"));
success = service.deleteImage(nodeIp, name);
break;
case "push":
name = String.valueOf(parameter.get("name"));
nodeIp = String.valueOf(parameter.get("nodeIp"));
success = service.pushImage(nodeIp, name);
break;
}
jsonObject.put("success", success);
writer.append(jsonObject.toString());
logger.info(jsonObject.toString());
}
}
VMService类 该模块用于实现KVM的创建、管理、删除的行为
package service;
import entity.VM;
import entity.VMInfo;
import manager.SystemManager;
import org.apache.log4j.Logger;
import org.json.simple.JSONObject;
import org.libvirt.*;
import utils.LinuxConnection;
import utils.RandomCreator;
import utils.XMLUtils;
import utils.ZKClient;
import java.io.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class VMService {
private final Logger logger = Logger.getLogger("VMService");
public List listVM() {
SystemManager.refreshVM();
List vmList = new LinkedList<>();
for (Map.Entry entry : SystemManager.getVmInfoTable().entrySet()) {
vmList.add(entry.getValue());
}
return vmList;
}
public VM createVM(String domainName, long capacity, long memory, int vcpu, String ip, String nodeIp) {
if (nodeIp == null)
nodeIp = SystemManager.chooseNodeIP();
String nodeHostname = SystemManager.getDnTable().get(nodeIp);
String poolName = SystemManager.POOL;
String poolPath = SystemManager.POOL_PATH;
Connect connect = SystemManager.getConnectTable().get(nodeIp);
String volName = domainName + "_" + System.currentTimeMillis();
String volPath = poolPath + "/" + volName;
String volXML = XMLUtils.createVolXML(volPath, volName, capacity);
String mac = RandomCreator.createMac();
String domainXML = XMLUtils.createDomainXML(domainName, memory, vcpu, volPath, mac);
try {
StoragePool pool = connect.storagePoolLookupByName(poolName);
StorageVol vol = pool.storageVolCreateXML(volXML, 0);
Domain domain = connect.domainDefineXML(domainXML);
domain.setAutostart(false);
VM vm = new VM(nodeIp, domainName, 0, ip, memory, vcpu, capacity, domain.isPersistent() == 1);
SystemManager.getVmInfoTable().put(domainName, vm);
SystemManager.getVmTable().put(domainName, domain);
SystemManager.getVolTable().put(domainName, vol);
SystemManager.getIpStateTable().put(ip, true);
ZKClient zkClient = new ZKClient();
zkClient.createIP4VM(nodeHostname, domainName, ip);
zkClient.close();
return vm;
} catch (LibvirtException e) {
e.printStackTrace();
return null;
}
}
public VMInfo getStatistic(String domainName) {
VM vm = SystemManager.getVmInfoTable().get(domainName);
Domain domain = SystemManager.getVmTable().get(domainName);
StorageVol vol = SystemManager.getVolTable().get(domainName);
try {
//cpu信息
long start = System.currentTimeMillis();
long cpuTime1 = domain.getInfo().cpuTime;
Thread.sleep(1000);
long cpuTime2 = domain.getInfo().cpuTime;
long end = System.currentTimeMillis();
int nrVirtCpu = domain.getInfo().nrVirtCpu;
System.out.println(cpuTime2 - cpuTime1);
System.out.println(end - start);
double cpuRate = Math.min(1.0, (cpuTime2 - cpuTime1) / ((end - start) * nrVirtCpu * 1e6));
System.out.println(cpuRate);
//磁盘信息
double capacity = vol.getInfo().capacity / SystemManager.B2GB;
double allocation = vol.getInfo().allocation / SystemManager.B2GB;
//内存信息
LinuxConnection linuxConnection = new LinuxConnection(vm.getIp(), SystemManager.LINUX_USER_NAME, SystemManager.LINUX_PASSWORD);
InputStream inputStream = new ByteArrayInputStream(linuxConnection.execute("cat /proc/meminfo").getBytes());
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
double memTotal = Long.parseLong(bufferedReader.readLine().split("\s+")[1]) / SystemManager.KB2GB;
bufferedReader.readLine();
double memAvailable = Long.parseLong(bufferedReader.readLine().split("\s+")[1]) / SystemManager.KB2GB;
VMInfo vmInfo = new VMInfo(nrVirtCpu, cpuRate, allocation, capacity, memTotal, memAvailable);
System.out.println(vmInfo);
linuxConnection.close();
return vmInfo;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public boolean closeVM(String domainName) {
try {
Domain domain = SystemManager.getVmTable().get(domainName);
VM vm = SystemManager.getVmInfoTable().get(domainName);
String hostname = SystemManager.getDnTable().get(vm.getNodeIp());
domain.destroy();
vm.setState(0);
if (!vm.isPersistent()) {
SystemManager.getVmTable().remove(domainName);
SystemManager.getVmInfoTable().remove(domainName);
SystemManager.getVolTable().remove(domainName);
ZKClient zkClient = new ZKClient();
zkClient.deleteIP4VM(hostname, vm.getDomainName());
zkClient.close();
}
return true;
} catch (LibvirtException e) {
e.printStackTrace();
return false;
}
}
public boolean deleteVM(String domainName) {
try {
VM vm = SystemManager.getVmInfoTable().get(domainName);
String hostname = SystemManager.getDnTable().get(vm.getNodeIp());
Domain domain = SystemManager.getVmTable().get(domainName);
StorageVol vol = SystemManager.getVolTable().get(domainName);
if (domain.isActive() == 1)
domain.destroy();
domain.undefine();
vol.wipe();
vol.delete(0);
SystemManager.getVmTable().remove(domainName);
SystemManager.getVmInfoTable().remove(domainName);
SystemManager.getVolTable().remove(domainName);
SystemManager.getIpStateTable().put(vm.getIp(), false);
ZKClient zkClient = new ZKClient();
zkClient.deleteIP4VM(hostname, vm.getDomainName());
zkClient.close();
return true;
} catch (LibvirtException e) {
e.printStackTrace();
return false;
}
}
public VM cloneVM(String srcDomainName, String destDomainName, String ip, String nodeIp) {
try {
//获取原domain所在的连接
VM vm1 = SystemManager.getVmInfoTable().get(srcDomainName);
Domain domain1 = SystemManager.getVmTable().get(srcDomainName);
if (domain1.isActive() == 1) {
closeVM(srcDomainName);
}
if (nodeIp == null)
nodeIp = vm1.getNodeIp();
Connect connect = SystemManager.getConnectTable().get(nodeIp);
Connect nfsConnection = SystemManager.getConnectTable().get(SystemManager.NFS_SERVER_IP);
long mem = vm1.getMemory();
int vcpu = vm1.getVcpu();
//获取克隆vol
StorageVol srcVol = SystemManager.getVolTable().get(srcDomainName);
long capacity = (long) (srcVol.getInfo().capacity / SystemManager.B2GB);
//分配,只能本地克隆
String hostname = SystemManager.getDnTable().get(nodeIp);
//按时间戳取名
String destVolName = destDomainName + "_" + System.currentTimeMillis();
String destVolPath = SystemManager.POOL_PATH + "/" + destVolName;
//创建vol,注意单位转换
String volXML = XMLUtils.createVolXML(destVolPath, destVolName, capacity);
StoragePool nfsPool = nfsConnection.storagePoolLookupByName(SystemManager.POOL);
//本地克隆
StorageVol destVol = nfsPool.storageVolCreateXMLFrom(volXML, srcVol, 0);
String mac = RandomCreator.createMac();
String domainXML = XMLUtils.createDomainXML(destDomainName, mem, vcpu, destVol.getPath(), mac);
//远程刷新
StoragePool destPool = connect.storagePoolLookupByName(SystemManager.POOL);
destPool.refresh(0);
//创建domain
Domain domain = connect.domainDefineXML(domainXML);
domain.setAutostart(false);
//修改全集变量
VM vm2 = new VM(nodeIp, destDomainName, 0, ip, mem, vcpu, capacity, domain.isPersistent() == 1);
SystemManager.getVmInfoTable().put(destDomainName, vm2);
SystemManager.getVmTable().put(destDomainName, domain);
SystemManager.getVolTable().put(destDomainName, destVol);
SystemManager.getIpStateTable().put(ip, true);
ZKClient zkClient = new ZKClient();
zkClient.createIP4VM(hostname, destDomainName, ip);
zkClient.close();
openVM(destDomainName);
Thread.sleep(60000);
LinuxConnection linuxConnection;
while (true) {
try {
linuxConnection = new LinuxConnection(vm1.getIp(), SystemManager.LINUX_USER_NAME, SystemManager.LINUX_PASSWORD);
break;
} catch (IOException e) {
e.printStackTrace();
}
}
JSONObject conf = (JSONObject) SystemManager.NET_CONF.clone();
conf.put("IPADDR", ip);
StringBuilder stringBuilder = new StringBuilder();
try {
stringBuilder.append("rm -f " + SystemManager.HOSTNAME_PATH).append(" && ")
.append("touch " + SystemManager.HOSTNAME_PATH).append(" && ").append("echo ")
.append(destDomainName).append(">>").append(SystemManager.HOSTNAME_PATH).append(" && ")
.append("rm -f " + SystemManager.NET_CONF_PATH).append(" && ")
.append("touch " + SystemManager.NET_CONF_PATH).append(" && ");
for (Object key : conf.keySet()) {
String attr = key.toString();
String val = conf.get(attr).toString();
stringBuilder.append("echo ").append(attr).append("=").append(val).append(">>").append(SystemManager.NET_CONF_PATH).append(" && ");
}
stringBuilder.append("reboot");
linuxConnection.execute(stringBuilder.toString());
vm2.setState(1);
} catch (Exception e) {
e.printStackTrace();
vm2.setState(-1);
} finally {
linuxConnection.close();
}
return vm2;
} catch (LibvirtException | InterruptedException e) {
e.printStackTrace();
return null;
}
}
public boolean openVM(String domainName) {
try {
VM vm = SystemManager.getVmInfoTable().get(domainName);
Domain domain = SystemManager.getVmTable().get(domainName);
domain.create();
vm.setState(1);
return true;
} catch (LibvirtException e) {
e.printStackTrace();
return false;
}
}
public VM migrateVM(String srcDomainName, String destDomainName, String nodeIp) {
String linuxIP = SystemManager.getVmInfoTable().get(srcDomainName).getNodeIp();
String srcHostname = SystemManager.getDnTable().get(linuxIP);
String destHostname = SystemManager.getDnTable().get(nodeIp);
String passwd = SystemManager.getPwdTable().get(srcHostname);
String usrName = SystemManager.LINUX_USER_NAME;
LinuxConnection linuxConnection = null;
try {
linuxConnection = new LinuxConnection(linuxIP, usrName, passwd);
} catch (IOException e) {
e.printStackTrace();
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("virsh migrate --live ").append(srcDomainName)
.append(" --dname ").append(destDomainName)
.append(" qemu+tcp://").append(nodeIp).append("/system ")
.append("tcp://").append(nodeIp).append(" --unsafe");
logger.info(stringBuilder.toString());
// 执行命令
try {
linuxConnection.execute(stringBuilder.toString());
ZKClient zkClient = new ZKClient();
VM vm = SystemManager.getVmInfoTable().get(srcDomainName);
if (!vm.isPersistent()) {
SystemManager.getVmTable().remove(srcDomainName);
SystemManager.getVmInfoTable().remove(srcDomainName);
SystemManager.getVolTable().remove(srcDomainName);
zkClient.deleteIP4VM(srcHostname, vm.getDomainName());
}
// removeVM(srcDomainName);
VM vm2 = new VM(nodeIp, destDomainName, 1, vm.getIp(), vm.getMemory(), vm.getVcpu(), vm.getCapacity(), false);
StorageVol vol = SystemManager.getVolTable().get(srcDomainName);
Connect connect = SystemManager.getConnectTable().get(nodeIp);
Domain domain2 = connect.domainLookupByName(destDomainName);
SystemManager.getVmInfoTable().put(destDomainName, vm2);
SystemManager.getVmTable().put(destDomainName, domain2);
SystemManager.getVolTable().put(destDomainName, vol);
zkClient.createIP4VM(destHostname, destDomainName, vm2.getIp());
zkClient.close();
return vm2;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
linuxConnection.close();
}
}
public List listIP() {
List ipList = new ArrayList<>();
for (Map.Entry entry : SystemManager.getIpStateTable().entrySet()) {
if (!entry.getValue()) {
ipList.add(entry.getKey());
}
}
return ipList;
}
public List listNodeIP() {
return new ArrayList<>(SystemManager.getDnTable().keySet());
}
}
CTService类
package service;
import entity.Container;
import entity.Image;
import manager.SystemManager;
import utils.DockerUtils;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class CTService {
public List listCT() {
SystemManager.refreshDocker();
List ctList = new LinkedList<>();
for (Map.Entry> mapEntry : SystemManager.getCtTable().entrySet()) {
for (Map.Entry entry : mapEntry.getValue().entrySet()) {
ctList.add(entry.getValue());
}
}
return ctList;
}
public Container createCT(String nodeIp, String name,String imageName) {
DockerUtils docker = new DockerUtils(nodeIp);
try {
docker.run(name, imageName);
Container container = docker.getCTByName(name);
SystemManager.getCtTable().get(nodeIp).put(name, container);
return container;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public boolean closeCT(String nodeIp, String name) {
DockerUtils docker = new DockerUtils(nodeIp);
try {
docker.stop(name);
Container container = SystemManager.getCtTable().get(nodeIp).get(name);
container.setRunning(false);
container.setIp("");
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public boolean deleteCT(String nodeIp, String name) {
DockerUtils docker = new DockerUtils(nodeIp);
try {
docker.rm(name);
SystemManager.getCtTable().remove(name);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public Image commitCT(String nodeIp, String name, String author, String describe, String repository, String tag) {
DockerUtils docker = new DockerUtils(nodeIp);
try {
docker.commit(name, author, describe, repository, tag);
SystemManager.refreshDocker();
return SystemManager.getImageTable().get(nodeIp).get(repository + ":" + tag);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public Container openCT(String nodeIp, String name) {
DockerUtils docker = new DockerUtils(nodeIp);
try {
docker.start(name);
Container container = SystemManager.getCtTable().get(nodeIp).get(name);
container.setIp(docker.getIP(name));
container.setRunning(true);
return container;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
ImgService类 该模块用于镜像
package service;
import entity.Image;
import manager.SystemManager;
import utils.DockerUtils;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class ImageService {
public List listImage() {
SystemManager.refreshDocker();
List imageList = new LinkedList<>();
for (Map.Entry> mapEntry : SystemManager.getImageTable().entrySet()) {
for (Map.Entry entry : mapEntry.getValue().entrySet()) {
imageList.add(entry.getValue());
}
}
return imageList;
}
public boolean deleteImage(String nodeIp, String name) {
DockerUtils docker = new DockerUtils(nodeIp);
try {
docker.rmi(name);
SystemManager.getImageTable().remove(name);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public Image pullImage(String nodeIp, String name) {
DockerUtils docker = new DockerUtils(nodeIp);
try {
if (!SystemManager.getImageTable().get(nodeIp).containsKey(name))
docker.pull(name);
SystemManager.refreshDocker();
return SystemManager.getImageTable().get(nodeIp).get(name);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public boolean pushImage(String nodeIp, String name) {
DockerUtils docker = new DockerUtils(nodeIp);
try {
docker.push(name, SystemManager.REGISTRY_IP, SystemManager.REGISTRY_PORT);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
DockerUtil类 该模块用于接收并转换Docker的相关指令
package manager;
import entity.Container;
import entity.Image;
import entity.VM;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.libvirt.*;
import utils.DockerUtils;
import utils.XMLUtils;
import utils.ZKClient;
import java.io.FileReader;
import java.io.IOException;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
public class SystemManager {
private static final Map vmTable;//name-domain
private static final Map vmInfoTable;//name-vm
private static final Map connectTable;//ip-connect
private static final Map ipStateTable;//ip-bool
private static final Map dnTable;//nodeIp-dn
private static final Map volTable;//name-vol
private static final Map pwdTable;//name-vol
private static final Map> ctTable;//name-container
private static final Map> imageTable;//p:v-image
public static final double B2GB = 1 << 30;
public static final double KB2GB = 1 << 20;
public static final String POOL = "pool01";
public static final String POOL_PATH = "/opt/kvm/images";
public static final String LINUX_USER_NAME = "root";
public static final String LINUX_PASSWORD = "ldw20000702";
public static final String NET_CONF_PATH = "/etc/sysconfig/network-scripts/ifcfg-ens3";
public static final String HOSTNAME_PATH = "/etc/hostname";
public static final String NFS_SERVER_IP = "192.168.43.130";
public static final String REGISTRY_IP = "192.168.43.130";
public static final int REGISTRY_PORT = 5000;
public static JSONObject NET_CONF;
public static final DecimalFormat round2 = new DecimalFormat("0.00");
public static final DecimalFormat round4 = new DecimalFormat("0.0000");
// public static Connect NFS_SERVER = null;
static {
round2.setRoundingMode(RoundingMode.HALF_UP);
round4.setRoundingMode(RoundingMode.HALF_UP);
vmTable = new HashMap<>();
vmInfoTable = new HashMap<>();
connectTable = new HashMap<>();
ipStateTable = new TreeMap<>();
dnTable = new TreeMap<>();
volTable = new HashMap<>();
pwdTable = new HashMap<>();
ctTable = new HashMap<>();
imageTable = new HashMap<>();
try {
//解析JSON文件的内容
JSONParser jsonParser = new JSONParser();
String path = Objects.requireNonNull(SystemManager.class.getClassLoader().getResource("ifcfg-ens3.json")).getPath();
NET_CONF = (JSONObject) jsonParser.parse(new FileReader(path));
} catch (ParseException | IOException e) {
e.printStackTrace();
}
refreshVM();
refreshDocker();
}
public static void refreshVM() {
vmTable.clear();
vmInfoTable.clear();
connectTable.clear();
ipStateTable.clear();
dnTable.clear();
volTable.clear();
pwdTable.clear();
try {
for (int i = 128; i < 255; i++) {
ipStateTable.put("192.168.43." + i, false);
}
ZKClient zkClient = new ZKClient();
Map ip4PM = zkClient.listIP4PM();
pwdTable.putAll(zkClient.listPSW4PM());
for (Map.Entry entry : ip4PM.entrySet()) {
String hostname = entry.getKey();
String nodeIp = entry.getValue();
String uri = "qemu+tcp://" + nodeIp + ":16509/system";
Connect connect = new Connect(uri);
connectTable.put(nodeIp, connect);
dnTable.put(nodeIp, hostname);
ipStateTable.put(nodeIp, true);
int[] ids = connect.listDomains();
String[] names = connect.listDefinedDomains();
List nameList = new LinkedList<>();
for (int id : ids) {
String name = connect.domainLookupByID(id).getName();
nameList.add(name);
}
nameList.addAll(Arrays.asList(names));
for (String domainName : nameList) {
Domain domain = connect.domainLookupByName(domainName);
long memory = (long) (domain.getInfo().memory / SystemManager.KB2GB);
int vcpu = domain.getInfo().nrVirtCpu;
int state = domain.isActive();
String ip = zkClient.getIP4VM(hostname, domainName);
String volPath = XMLUtils.getVolPath(domain.getXMLDesc(0));
StoragePool pool = connect.storagePoolLookupByName(SystemManager.POOL);
pool.refresh(0);
StorageVol vol = connect.storageVolLookupByPath(volPath);
long capacity = (long) (vol.getInfo().capacity / SystemManager.B2GB);
VM vm = new VM(nodeIp, domainName, state, ip, memory, vcpu, capacity, domain.isPersistent() == 1);
vmTable.put(domainName, domain);
vmInfoTable.put(domainName, vm);
volTable.put(domainName, vol);
ipStateTable.put(ip, true);
}
}
zkClient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void refreshDocker() {
imageTable.clear();
ctTable.clear();
dnTable.clear();
pwdTable.clear();
try {
ZKClient zkClient = new ZKClient();
pwdTable.putAll(zkClient.listPSW4PM());
Map ip4PM = zkClient.listIP4PM();
for (Map.Entry entry : ip4PM.entrySet()) {
String hostname = entry.getKey();
String nodeIp = entry.getValue();
dnTable.put(nodeIp, hostname);
DockerUtils dockerUtils = new DockerUtils(nodeIp);
imageTable.put(nodeIp, new HashMap<>());
ctTable.put(nodeIp, new HashMap<>());
for (Image image : dockerUtils.listImages()) {
imageTable.get(nodeIp).put(image.getName(), image);
}
for (Container container : dockerUtils.listContainer()) {
ctTable.get(nodeIp).put(container.getName(), container);
}
}
zkClient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static String chooseNodeIP() {
String ip = null;
double bestScore = 0;
try {
for (Map.Entry entry : connectTable.entrySet()) {
Connect connect = entry.getValue();
StoragePool pool = connect.storagePoolLookupByName(SystemManager.POOL);
if (pool.getInfo().state != StoragePoolInfo.StoragePoolState.VIR_STORAGE_POOL_RUNNING)
continue;
long freeMem = connect.getFreeMemory();
int maxVcpu = connect.getMaxVcpus("kvm");
long curVcpu = 0;
long curMem = 0;
int[] ids = connect.listDomains();
for (int id : ids) {
Domain domain = connect.domainLookupByID(id);
if (domain.isActive() == 1) {
curVcpu += domain.getInfo().nrVirtCpu;
curMem += domain.getInfo().memory;
}
}
double curScore = freeMem + maxVcpu - curMem - curVcpu;
if (curScore > bestScore) {
bestScore = curScore;
ip = entry.getKey();
}
}
} catch (LibvirtException e) {
e.printStackTrace();
}
return ip;
}
// public static String chooseIP() {
// for (Map.Entry entry : ipStateTable.entrySet()) {
// if (!entry.getValue())
// return entry.getKey();
// }
// return null;
// }
public static Map getVmTable() {
return vmTable;
}
public static Map getVmInfoTable() {
return vmInfoTable;
}
public static Map getConnectTable() {
return connectTable;
}
public static Map getIpStateTable() {
return ipStateTable;
}
public static Map getVolTable() {
return volTable;
}
public static Map getDnTable() {
return dnTable;
}
public static Map getPwdTable() {
return pwdTable;
}
public static Map> getCtTable() {
return ctTable;
}
public static Map> getImageTable() {
return imageTable;
}
}
ZKClient类
package utils;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ZKClient {
private ZooKeeper zooKeeper;
private final static String IP_PARENT = "/ip";
private final static String PSW_PARENT = "/psw";
private final static String connectionString = "192.168.43.130:2181,192.168.43.128:2181";
public ZKClient() {
try {
zooKeeper = new ZooKeeper(connectionString, 15000, watchedEvent -> {
});
} catch (IOException e) {
e.printStackTrace();
}
}
public String getIP4PM(String hostname) {
try {
String path = IP_PARENT + "/" + hostname;
return new String(zooKeeper.getData(path, true, new Stat()));
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
return null;
}
}
public String getIP4VM(String hostname, String domainName) {
try {
String path = IP_PARENT + "/" + hostname + "/" + domainName;
return new String(zooKeeper.getData(path, true, new Stat()));
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
return null;
}
}
public Map listIP4PM() {
Map ipTable = new HashMap<>();
try {
List children = zooKeeper.getChildren(IP_PARENT, true);
for (String child : children) {
String ip = (new String(zooKeeper.getData(IP_PARENT + "/" + child, true, new Stat())));
ipTable.put(child, ip);
}
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
return ipTable;
}
public Map listPSW4PM() {
Map pwdTable = new HashMap<>();
try {
List children = zooKeeper.getChildren(PSW_PARENT, true);
for (String child : children) {
String pwd = (new String(zooKeeper.getData(PSW_PARENT + "/" + child, true, new Stat())));
pwdTable.put(child, pwd);
}
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
return pwdTable;
}
public Map listIP4VM() {
Map ipTable = new HashMap<>();
try {
List children = zooKeeper.getChildren(IP_PARENT, true);
for (String child : children) {
String pmPath = IP_PARENT + "/" + child;
List children2 = zooKeeper.getChildren(pmPath, true);
for (String child2 : children2) {
String vmPath = pmPath + "/" + child2;
String ip = (new String(zooKeeper.getData(vmPath, true, new Stat())));
ipTable.put(child2, ip);
}
}
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
return ipTable;
}
public void createIP4PM(String hostname, String ip) {
try {
String path = IP_PARENT + "/" + hostname;
zooKeeper.create(path, ip.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
}
public void createIP4VM(String hostname, String domainName, String ip) {
try {
String path = IP_PARENT + "/" + hostname + "/" + domainName;
zooKeeper.create(path, ip.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
}
public void deleteIP4PM(String hostname) {
try {
String path = IP_PARENT + "/" + hostname;
List children = zooKeeper.getChildren(path, true);
for (String child : children) {
zooKeeper.delete(path + "/" + child, -1);
}
zooKeeper.delete(path, -1);
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
}
public void deleteIP4VM(String hostname, String domainName) {
try {
String path = IP_PARENT + "/" + hostname + "/" + domainName;
zooKeeper.delete(path, -1);
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
}
public boolean existsIP(String path) {
try {
Stat exists = zooKeeper.exists(path, true);
return exists != null;
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
return false;
}
public void close() {
try {
zooKeeper.close();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
XMLUtil类
package utils;
import org.dom4j.*;
import org.dom4j.io.SAXReader;
import java.io.*;
import java.util.Objects;
import java.util.logging.Logger;
public class XMLUtils {
private static final String volXMLT = "storage-volume.xml";
private static final String poolXMLT = "storage-pool.xml";
private static final String domainXMLT = "domain.xml";
private static final Logger logger = Logger.getLogger("XMLCreator");
public static String createVolXML(String volPath, String volName, long capacity) {
try {
SAXReader saxReader = new SAXReader();
String path = Objects.requireNonNull(XMLUtils.class.getClassLoader().getResource(volXMLT)).getPath();
Document document = saxReader.read(new File(path));
Node node = document.selectSingleNode("//volume/name");//确保节点是真的唯一
System.out.println(document.asXML());
node.setText(volName);
node = document.selectSingleNode("//volume/capacity");
node.setText(Long.toString(capacity));
node = document.selectSingleNode("//volume/target/path");
node.setText(volPath);
logger.info(document.asXML());
logger.info(document.asXML());
return document.asXML();
} catch (IOException | DocumentException e) {
e.printStackTrace();
return "";
}
}
public static String createPoolXML(String poolName, int capacity, String poolPath) {
try {
SAXReader saxReader = new SAXReader();
String path = Objects.requireNonNull(XMLUtils.class.getClassLoader().getResource(poolXMLT)).getPath();
Document document = saxReader.read(new File(path));
Node node = document.selectSingleNode("//pool/name");//确保节点是真的唯一
System.out.println(document.asXML());
node.setText(poolName);
node = document.selectSingleNode("//pool/capacity");
node.setText(Long.toString(capacity));
node = document.selectSingleNode("//pool/target/path");
node.setText(poolPath);
logger.info(document.asXML());
logger.info(document.asXML());
return document.asXML();
} catch (IOException | DocumentException e) {
e.printStackTrace();
return "";
}
}
public static String createDomainXML(String domainName, long memory, int vcpu, String volPath, String mac) {
try {
SAXReader saxReader = new SAXReader();
String path = Objects.requireNonNull(XMLUtils.class.getClassLoader().getResource(domainXMLT)).getPath();
Document document = saxReader.read(new File(path));
Node node = document.selectSingleNode("//domain/name");//确保节点是真的唯一
node.setText(domainName);
// node = document.selectSingleNode("//domain/uuid");//确保节点是真的唯一
// node.setText(uuid);
node = document.selectSingleNode("//domain/memory");//确保节点是真的唯一
node.setText(Long.toString(memory));
node = document.selectSingleNode("//domain/currentMemory");//确保节点是真的唯一
node.setText(Long.toString(memory));
node = document.selectSingleNode("//domain/vcpu");//确保节点是真的唯一
node.setText(Integer.toString(vcpu));
node = document.selectSingleNode("//domain/devices/disk[@device='disk']/source");//确保节点是真的唯一
Element element = (Element) (node);
Attribute attribute = element.attribute("file");
element.remove(attribute);
element.addAttribute("file", volPath);
node = document.selectSingleNode("//domain/devices/interface/mac");//确保节点是真的唯一
element = (Element) (node);
attribute = element.attribute("address");
element.remove(attribute);
element.addAttribute("address", mac);
node = document.selectSingleNode("//domain/devices/interface/target");//确保节点是真的唯一
element = (Element) (node);
attribute = element.attribute("dev");
element.remove(attribute);
element.addAttribute("dev", "vnet" + System.currentTimeMillis());
// node = document.selectSingleNode("//domain/devices/interface/ip");//确保节点是真的唯一
// element = (Element) (node);
// attribute = element.attribute("address");
// element.remove(attribute);
// element.addAttribute("address", ip);
logger.info(document.asXML());
return document.asXML();
} catch (IOException | DocumentException e) {
e.printStackTrace();
return "";
}
}
public static String createDomainXML(String domainName, String domainXML) {
try {
SAXReader saxReader = new SAXReader();
InputStream inputStream = new ByteArrayInputStream(domainXML.getBytes());
Document document = saxReader.read(new InputStreamReader(inputStream));
Node node = document.selectSingleNode("//domain/name");//确保节点是真的唯一
node.setText(domainName);
return document.asXML();
} catch (DocumentException e) {
e.printStackTrace();
return "";
}
}
public static String getVolPath(String domainXML) {
try {
SAXReader saxReader = new SAXReader();
//字符串转流
InputStream inputStream = new ByteArrayInputStream(domainXML.getBytes());
Document document = saxReader.read(new InputStreamReader(inputStream));
Node node = document.selectSingleNode("//domain/devices/disk[@device='disk']/source");//确保节点是真的唯一
Element element = (Element) (node);
Attribute attribute = element.attribute("file");
return attribute.getValue();
} catch (DocumentException e) {
e.printStackTrace();
return null;
}
}
}
LinuxConnection类
package utils;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import org.apache.commons.lang.StringUtils;
import java.io.*;
public class LinuxConnection {
private final Connection connection;
public LinuxConnection(String ip, String userName, String userPwd) throws IOException {
System.out.println(ip);
connection = new Connection(ip);
connection.connect();
connection.authenticateWithPassword(userName, userPwd);
}
public String execute(String cmd) throws Exception {
System.out.println(cmd);
String result;
Session session = connection.openSession();
session.execCommand(cmd);
// 字符编码默认是utf-8
String encoding = "UTF-8";
result = processStdout(session.getStdout(), encoding);
// 如果为输出为空,说明脚本执行出错了
if (StringUtils.isBlank(result)) {
result = processStdout(session.getStderr(), encoding);
}
return result;
}
private String processStdout(InputStream in, String charset) throws Exception {
InputStream stdout = new StreamGobbler(in);
StringBuilder stringBuilder = new StringBuilder();
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
try {
inputStreamReader = new InputStreamReader(stdout, charset);
bufferedReader = new BufferedReader(inputStreamReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append("n");
}
} catch (UnsupportedEncodingException e) {
throw new Exception("不支持的编码字符集异常", e);
} catch (IOException e) {
throw new Exception("读取指纹失败", e);
} finally {
if (bufferedReader != null)
bufferedReader.close();
if (bufferedReader != null)
inputStreamReader.close();
if (bufferedReader != null)
stdout.close();
}
return stringBuilder.toString();
}
public void close() {
connection.close();
}
}
OK,初稿完结