Full opensource

This commit is contained in:
frank 2011-08-23 19:52:19 -07:00
parent fb6fb03175
commit b3478c377e
279 changed files with 33523 additions and 157 deletions

137
agent/bindir/mycloud-setup-agent Executable file
View File

@ -0,0 +1,137 @@
#!/usr/bin/python
import os
import logging
import sys
import socket
import subprocess
import time
from cloudutils.cloudException import CloudRuntimeException, CloudInternalException
from cloudutils.utilities import initLoging, bash
from cloudutils.configFileOps import configFileOps
from cloudutils.globalEnv import globalEnv
from cloudutils.networkConfig import networkConfig
from cloudutils.syscfg import sysConfigFactory
from optparse import OptionParser
url="http://rightscale-cloudstack.s3.amazonaws.com/kvm/centos/5.4/RightImage_CentOS_5.4_x64_v5.6.34.qcow2.bz2"
destFolder="/mnt/template/tmpl/1/4/"
metaFile="template.properties"
def getUserInputs():
print "Welcome to myCloud Setup:"
mgtSvr = "myagent.cloud.com"
cfo = configFileOps("/etc/cloud/agent/agent.properties")
oldToken = cfo.getEntry("zone")
if oldToken == "default":
oldToken = ""
zoneToken = raw_input("Please input the Zone Token:[%s]"%oldToken)
if zoneToken == "":
if oldToken == "":
print "Please input a valid zone token"
exit(1)
zoneToken = oldToken
try:
defaultNic = networkConfig.getDefaultNetwork()
except:
print "Failed to get default route. Please configure your network to add a default route"
exit(1)
network = defaultNic.name
return [mgtSvr, zoneToken, network]
def downloadTemplate():
if not os.path.exists(destFolder):
os.makedirs(destFolder)
oldName =url.split("/")[-1]
templateFile=url.split("/")[-1].replace(".bz2","")
templateFullPath = destFolder + templateFile
metaFullPath = destFolder + metaFile
if os.path.exists(templateFullPath):
if os.path.exists(metaFullPath):
return True
os.remove(templateFullPath)
print "Need to download myCloud template into your local disk, from " + url + " to " + destFolder + " :"
try:
proc = subprocess.Popen(["/bin/bash", "-c", "wget -O - " + url + " | bunzip2 > " + destFolder + templateFile])
proc.communicate()
ret = proc.poll()
if ret is None or ret < 0:
raise CloudRuntimeException("Failed to download template")
except KeyboardInterrupt:
if os.path.exists(templateFullPath):
os.remove(templateFullPath)
raise CloudRuntimeException("Downloading process is interrupted")
file = open(metaFullPath, "w")
physicalSize = os.stat(templateFullPath).st_size
virtualSize = bash("qemu-img info " + templateFullPath + " |grep virtual").getStdout().split("(")[1].split(" ")[0]
cfo = configFileOps(metaFullPath)
cfo.addEntry("filename", templateFile)
cfo.addEntry("id", "4")
cfo.addEntry("qcow2.size", str(physicalSize))
cfo.addEntry("public", "true")
cfo.addEntry("uniquename", "Rightscale CentOS 5.4")
cfo.addEntry("qcow2.virtualsize", virtualSize)
cfo.addEntry("virtualsize", virtualSize)
cfo.addEntry("hvm", "true")
cfo.addEntry("description", "Rightscale CentOS 5.4")
cfo.addEntry("qcow2", "true")
cfo.addEntry("qcow2.filename", templateFile)
cfo.addEntry("size", str(physicalSize))
cfo.save()
if __name__ == '__main__':
initLoging("/var/log/cloud/setupAgent.log")
glbEnv = globalEnv()
glbEnv.mode = "Agent"
glbEnv.agentMode = "myCloud"
parser = OptionParser()
parser.add_option("-z", "--zone-token", dest="zone", help="zone token")
(options, args) = parser.parse_args()
if options.zone is None:
userInputs = getUserInputs()
glbEnv.mgtSvr = userInputs[0]
glbEnv.zone = userInputs[1]
glbEnv.defaultNic = userInputs[2]
else:
glbEnv.zone = options.zone
try:
defaultNic = networkConfig.getDefaultNetwork()
glbEnv.defaultNic = defaultNic.name
except:
print "Failed to get default route. Please configure your network to have a default route"
sys.exit(2)
#generate UUID
glbEnv.uuid = configFileOps("/etc/cloud/agent/agent.properties").getEntry("guid")
if glbEnv.uuid == "":
glbEnv.uuid = bash("uuidgen").getStdout()
print "Starting to configure your system:"
syscfg = sysConfigFactory.getSysConfigFactory(glbEnv)
try:
syscfg.config()
downloadTemplate()
syscfg.svo.stopService("cloud-agent")
syscfg.svo.enableService("cloud-agent")
print "myCloud setup is Done!"
except (CloudRuntimeException,CloudInternalException), e:
print e
print "Try to restore your system:"
try:
syscfg.restore()
except:
pass

View File

@ -0,0 +1,258 @@
package com.cloud.agent.dhcp;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Formatter;
import org.apache.log4j.Logger;
import org.jnetpcap.packet.JMemoryPacket;
import org.jnetpcap.packet.JPacket;
import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.protocol.lan.Ethernet;
import org.jnetpcap.protocol.lan.IEEE802dot1q;
import org.jnetpcap.protocol.network.Ip4;
import org.jnetpcap.protocol.tcpip.Udp;
import com.cloud.agent.dhcp.DhcpSnooperImpl.DHCPState;
public class DhcpPacketParser implements Runnable{
private static final Logger s_logger = Logger.getLogger(DhcpPacketParser.class);
private enum DHCPPACKET {
OP(0),
HTYPE(1),
HLEN(2),
HOPS(3),
XID(4),
SECS(8),
FLAGS(10),
CIADDR(12),
YIADDR(16),
SIDADDR(20),
GIADDR(24),
CHADDR(28),
SNAME(44),
FILE(108),
MAGIC(236),
OPTIONS(240);
int offset;
DHCPPACKET(int i) {
offset = i;
}
int getValue() {
return offset;
}
}
private enum DHCPOPTIONTYPE {
PAD(0),
MESSAGETYPE(53),
REQUESTEDIP(50),
END(255);
int type;
DHCPOPTIONTYPE(int i) {
type = i;
}
int getValue() {
return type;
}
}
private enum DHCPMSGTYPE {
DHCPDISCOVER(1),
DHCPOFFER(2),
DHCPREQUEST(3),
DHCPDECLINE(4),
DHCPACK(5),
DHCPNAK(6),
DHCPRELEASE(7),
DHCPINFORM(8);
int _type;
DHCPMSGTYPE(int type) {
_type = type;
}
int getValue() {
return _type;
}
public static DHCPMSGTYPE valueOf(int type) {
for (DHCPMSGTYPE t : values()) {
if (type == t.getValue()) {
return t;
}
}
return null;
}
}
private class DHCPMSG {
DHCPMSGTYPE msgType;
byte[] caddr;
byte[] yaddr;
byte[] chaddr;
byte[] requestedIP;
public DHCPMSG() {
caddr = new byte[4];
yaddr = new byte[4];
chaddr = new byte[6];
}
}
private PcapPacket _buffer;
private int _offset;
private int _len;
private DhcpSnooperImpl _manager;
public DhcpPacketParser(PcapPacket buffer, int offset, int len, DhcpSnooperImpl manager) {
_buffer = buffer;
_offset = offset;
_len = len;
_manager = manager;
}
private int getPos(int pos) {
return _offset + pos;
}
private byte getByte(int offset) {
return _buffer.getByte(getPos(offset));
}
private void getByteArray(int offset, byte[] array) {
_buffer.getByteArray(getPos(offset), array);
}
private long getUInt(int offset) {
return _buffer.getUInt(getPos(offset));
}
private DHCPMSG getDhcpMsg() {
long magic = getUInt(DHCPPACKET.MAGIC.getValue());
if (magic != 0x63538263) {
return null;
}
DHCPMSG msg = new DHCPMSG();
int pos = DHCPPACKET.OPTIONS.getValue();
while (pos <= _len) {
int type = (int)getByte(pos++) & 0xff;
if (type == DHCPOPTIONTYPE.END.getValue()) {
break;
}
if (type == DHCPOPTIONTYPE.PAD.getValue()) {
continue;
}
int len = 0;
if (pos <= _len) {
len = ((int)getByte(pos++)) & 0xff;
}
if (type == DHCPOPTIONTYPE.MESSAGETYPE.getValue() || type == DHCPOPTIONTYPE.REQUESTEDIP.getValue()) {
/*Read data only if needed */
byte[] data = null;
if ((len + pos) <= _len) {
data = new byte[len];
getByteArray(pos, data);
}
if (type == DHCPOPTIONTYPE.MESSAGETYPE.getValue()) {
msg.msgType = DHCPMSGTYPE.valueOf((int)data[0]);
} else if (type == DHCPOPTIONTYPE.REQUESTEDIP.getValue()) {
msg.requestedIP = data;
}
}
pos += len;
}
if (msg.msgType == DHCPMSGTYPE.DHCPREQUEST) {
getByteArray(DHCPPACKET.CHADDR.getValue(), msg.chaddr);
getByteArray(DHCPPACKET.CIADDR.getValue(), msg.caddr);
} else if (msg.msgType == DHCPMSGTYPE.DHCPACK) {
getByteArray(DHCPPACKET.YIADDR.getValue(), msg.yaddr);
}
return msg;
}
private String formatMacAddress(byte[] mac) {
StringBuffer sb = new StringBuffer();
Formatter formatter = new Formatter(sb);
for (int i = 0; i < mac.length; i++) {
formatter.format("%02X%s", mac[i], (i < mac.length - 1) ? ":" : "");
}
return sb.toString();
}
private String getDestMacAddress() {
Ethernet ether = new Ethernet();
if (_buffer.hasHeader(ether)) {
byte[] destMac = ether.destination();
return formatMacAddress(destMac);
}
return null;
}
private InetAddress getDHCPServerIP() {
Ip4 ip = new Ip4();
if (_buffer.hasHeader(ip)) {
try {
return InetAddress.getByAddress(ip.source());
} catch (UnknownHostException e) {
s_logger.debug("Failed to get dhcp server ip address: " + e.toString());
}
}
return null;
}
@Override
public void run() {
DHCPMSG msg = getDhcpMsg();
if (msg == null) {
return;
}
if (msg.msgType == DHCPMSGTYPE.DHCPACK) {
InetAddress ip = null;
try {
ip = InetAddress.getByAddress(msg.yaddr);
String macAddr = getDestMacAddress();
_manager.setIPAddr(macAddr, ip, DHCPState.DHCPACKED, getDHCPServerIP());
} catch (UnknownHostException e) {
}
} else if (msg.msgType == DHCPMSGTYPE.DHCPREQUEST) {
InetAddress ip = null;
if (msg.requestedIP != null) {
try {
ip = InetAddress.getByAddress(msg.requestedIP);
} catch (UnknownHostException e) {
}
}
if (ip == null) {
try {
ip = InetAddress.getByAddress(msg.caddr);
} catch (UnknownHostException e) {
}
}
if (ip != null) {
String macAddr = formatMacAddress(msg.chaddr);
_manager.setIPAddr(macAddr, ip, DHCPState.DHCPREQUESTED, null);
}
}
}
private void test() {
JPacket packet = new JMemoryPacket(Ethernet.ID,
" 06fa 8800 00b3 0656 d200 0027 8100 001a 0800 4500 0156 64bf 0000 4011 f3f2 ac1a 6412 ac1a 649e 0043 0044 0001 0000 0001");
Ethernet eth = new Ethernet();
if (packet.hasHeader(eth)) {
System.out.print(" ether:" + eth);
}
IEEE802dot1q vlan = new IEEE802dot1q();
if (packet.hasHeader(vlan)) {
System.out.print(" vlan: " + vlan);
}
if (packet.hasHeader(Udp.ID)) {
System.out.print("has udp");
}
}
}

View File

@ -0,0 +1,45 @@
package com.cloud.agent.dhcp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import com.cloud.utils.concurrency.NamedThreadFactory;
public class DhcpProtocolParserServer extends Thread {
private static final Logger s_logger = Logger.getLogger(DhcpProtocolParserServer.class);;
protected ExecutorService _executor;
private int dhcpServerPort = 67;
private int bufferSize = 300;
protected boolean _running = false;
public DhcpProtocolParserServer(int workers) {
_executor = new ThreadPoolExecutor(workers, 10 * workers, 1, TimeUnit.DAYS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("DhcpListener"));
_running = true;
}
public void run() {
while(_running) {
try {
DatagramSocket dhcpSocket = new DatagramSocket(dhcpServerPort, InetAddress.getByAddress(new byte[]{0,0,0,0}));
dhcpSocket.setBroadcast(true);
while (true) {
byte[] buf = new byte[bufferSize];
DatagramPacket dgp = new DatagramPacket(buf, buf.length);
dhcpSocket.receive(dgp);
// _executor.execute(new DhcpPacketParser(buf));
}
} catch (IOException e) {
s_logger.debug(e.getMessage());
}
}
}
}

View File

@ -0,0 +1,327 @@
/**
* * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.agent.dhcp;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.jnetpcap.Pcap;
import org.jnetpcap.PcapBpfProgram;
import org.jnetpcap.PcapIf;
import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.packet.PcapPacketHandler;
import org.jnetpcap.protocol.tcpip.Udp;
import com.cloud.utils.Pair;
import com.cloud.utils.concurrency.NamedThreadFactory;
@Local(value = { DhcpSnooper.class})
public class DhcpSnooperImpl implements DhcpSnooper {
private static final Logger s_logger = Logger.getLogger(DhcpSnooperImpl.class);
public enum DHCPState {
DHCPACKED,
DHCPREQUESTED,
DHCPRESET;
}
public class IPAddr {
String _vmName;
InetAddress _ip;
DHCPState _state;
public IPAddr(InetAddress ip, DHCPState state, String vmName) {
_ip = ip;
_state = state;
_vmName = vmName;
}
}
protected ExecutorService _executor;
protected Map<String, IPAddr> _macIpMap;
protected Map<InetAddress, String> _ipMacMap;
private DhcpServer _server;
protected long _timeout = 1200000;
protected InetAddress _dhcpServerIp;
public DhcpSnooperImpl(String bridge, long timeout) {
_timeout = timeout;
_executor = new ThreadPoolExecutor(10, 10 * 10, 1, TimeUnit.DAYS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("DhcpListener"));
_macIpMap = new ConcurrentHashMap<String, IPAddr>();
_ipMacMap = new ConcurrentHashMap<InetAddress, String>();
_server = new DhcpServer(this, bridge);
_server.start();
}
@Override
public InetAddress getIPAddr(String macAddr, String vmName) {
String macAddrLowerCase = macAddr.toLowerCase();
IPAddr addr = _macIpMap.get(macAddrLowerCase);
if (addr == null) {
addr = new IPAddr(null, DHCPState.DHCPRESET, vmName);
_macIpMap.put(macAddrLowerCase, addr);
} else {
addr._state = DHCPState.DHCPRESET;
}
synchronized(addr) {
try {
addr.wait(_timeout);
} catch (InterruptedException e) {
}
if (addr._state == DHCPState.DHCPACKED) {
addr._state = DHCPState.DHCPRESET;
return addr._ip;
}
}
return null;
}
public InetAddress getDhcpServerIP() {
return _dhcpServerIp;
}
@Override
public void cleanup(String macAddr, String vmName) {
try {
if (macAddr == null) {
return;
}
_macIpMap.remove(macAddr);
_ipMacMap.values().remove(macAddr);
} catch (Exception e) {
s_logger.debug("Failed to cleanup: " + e.toString());
}
}
@Override
public Map<String, InetAddress> syncIpAddr() {
Collection<IPAddr> ips = _macIpMap.values();
HashMap<String, InetAddress> vmIpMap = new HashMap<String, InetAddress>();
for(IPAddr ip : ips) {
if (ip._state == DHCPState.DHCPACKED) {
vmIpMap.put(ip._vmName, ip._ip);
}
}
return vmIpMap;
}
@Override
public void initializeMacTable(List<Pair<String, String>> macVmNameList) {
for (Pair<String, String> macVmname : macVmNameList) {
IPAddr ipAdrr = new IPAddr(null, DHCPState.DHCPRESET, macVmname.second());
_macIpMap.put(macVmname.first(), ipAdrr);
}
}
protected void setIPAddr(String macAddr, InetAddress ip, DHCPState state, InetAddress dhcpServerIp) {
String macAddrLowerCase = macAddr.toLowerCase();
if (state == DHCPState.DHCPREQUESTED) {
IPAddr ipAddr = _macIpMap.get(macAddrLowerCase);
if (ipAddr == null) {
return;
}
_ipMacMap.put(ip, macAddr);
} else if (state == DHCPState.DHCPACKED) {
_dhcpServerIp = dhcpServerIp;
String destMac = macAddrLowerCase;
if (macAddrLowerCase.equalsIgnoreCase("ff:ff:ff:ff:ff:ff")) {
destMac = _ipMacMap.get(ip);
if (destMac == null) {
return;
}
}
IPAddr addr = _macIpMap.get(destMac);
if (addr != null) {
addr._ip = ip;
addr._state = state;
synchronized (addr) {
addr.notify();
}
}
}
}
/* (non-Javadoc)
* @see com.cloud.agent.dhcp.DhcpSnooper#stop()
*/
@Override
public boolean stop() {
_executor.shutdown();
_server.StopServer();
return true;
}
private class DhcpServer extends Thread {
private DhcpSnooperImpl _manager;
private String _bridge;
private Pcap _pcapedDev;
private boolean _loop;
public DhcpServer(DhcpSnooperImpl mgt, String bridge) {
_manager = mgt;
_bridge = bridge;
_loop = true;
}
public void StopServer() {
_loop = false;
_pcapedDev.breakloop();
_pcapedDev.close();
}
private Pcap initializePcap() {
try {
List<PcapIf> alldevs = new ArrayList<PcapIf>();
StringBuilder errBuf = new StringBuilder();
int r = Pcap.findAllDevs(alldevs, errBuf);
if (r == Pcap.NOT_OK || alldevs.isEmpty()) {
return null;
}
PcapIf dev = null;
for (PcapIf device : alldevs) {
if (device.getName().equalsIgnoreCase(_bridge)) {
dev = device;
break;
}
}
if (dev == null) {
s_logger.debug("Pcap: Can't find device: " + _bridge + " to listen on");
return null;
}
int snaplen = 64*1024;
int flags = Pcap.MODE_PROMISCUOUS;
int timeout = 10 * 1000;
Pcap pcap = Pcap.openLive(dev.getName(), snaplen, flags, timeout, errBuf);
if (pcap == null) {
s_logger.debug("Pcap: Can't open " + _bridge);
return null;
}
PcapBpfProgram program = new PcapBpfProgram();
String expr = "dst port 68 or 67";
int optimize = 0;
int netmask = 0xFFFFFF00;
if (pcap.compile(program, expr, optimize, netmask) != Pcap.OK) {
s_logger.debug("Pcap: can't compile BPF");
return null;
}
if(pcap.setFilter(program) != Pcap.OK) {
s_logger.debug("Pcap: Can't set filter");
return null;
}
return pcap;
} catch (Exception e) {
s_logger.debug("Failed to initialized: " + e.toString());
}
return null;
}
public void run() {
while (_loop) {
try {
_pcapedDev = initializePcap();
if (_pcapedDev == null) {
return;
}
PcapPacketHandler<String> jpacketHandler = new PcapPacketHandler<String>() {
public void nextPacket(PcapPacket packet, String user) {
Udp u = new Udp();
if (packet.hasHeader(u)) {
int offset = u.getOffset() + u.getLength();
_executor.execute(new DhcpPacketParser(packet, offset, u.length() - u.getLength(), _manager));
}
}
};
s_logger.debug("Starting DHCP snooping on " + _bridge);
int retValue = _pcapedDev.loop(-1, jpacketHandler, "pcapPacketHandler");
if ( retValue == -1) {
s_logger.debug("Pcap: failed to set loop handler");
} else if ( retValue == -2 && !_loop) {
s_logger.debug("Pcap: terminated");
return;
}
_pcapedDev.close();
} catch (Exception e) {
s_logger.debug("Pcap error:" + e.toString());
}
}
}
}
static public void main(String args[]) {
s_logger.addAppender(new org.apache.log4j.ConsoleAppender(new org.apache.log4j.PatternLayout(), "System.out"));
final DhcpSnooperImpl manager = new DhcpSnooperImpl("cloudbr0", 10000);
s_logger.debug(manager.getIPAddr("02:00:4c:66:00:03", "i-2-5-VM"));
manager.stop();
}
@Override
public boolean configure(String name, Map<String, Object> params)
throws ConfigurationException {
// TODO configure timeout here
return true;
}
@Override
public boolean start() {
return true;
}
@Override
public String getName() {
return "DhcpSnooperImpl";
}
}

View File

@ -0,0 +1,312 @@
/**
* * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.agent.resource.computing;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.StartAnswer;
import com.cloud.agent.api.StartCommand;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.routing.SavePasswordCommand;
import com.cloud.agent.api.routing.VmDataCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.dhcp.DhcpSnooper;
import com.cloud.agent.dhcp.DhcpSnooperImpl;
import com.cloud.agent.resource.computing.LibvirtComputingResource;
import com.cloud.agent.resource.computing.LibvirtConnection;
import com.cloud.agent.resource.computing.LibvirtVMDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.DiskDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.InterfaceDef;
import com.cloud.agent.vmdata.JettyVmDataServer;
import com.cloud.agent.vmdata.VmDataServer;
import com.cloud.network.Networks.TrafficType;
import com.cloud.utils.Pair;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.State;
/**
* Logic specific to the Cloudzones feature
*
* }
**/
public class CloudZonesComputingResource extends LibvirtComputingResource {
private static final Logger s_logger = Logger.getLogger(CloudZonesComputingResource.class);
protected DhcpSnooper _dhcpSnooper;
String _parent;
long _dhcpTimeout;
protected String _hostIp;
protected String _hostMacAddress;
protected VmDataServer _vmDataServer = new JettyVmDataServer();
private void setupDhcpManager(Connect conn, String bridgeName) {
_dhcpSnooper = new DhcpSnooperImpl(bridgeName, _dhcpTimeout);
List<Pair<String, String>> macs = new ArrayList<Pair<String, String>>();
try {
int[] domainIds = conn.listDomains();
for (int i = 0; i < domainIds.length; i++) {
Domain vm = conn.domainLookupByID(domainIds[i]);
if (vm.getName().startsWith("i-")) {
List<InterfaceDef> nics = getInterfaces(conn, vm.getName());
InterfaceDef nic = nics.get(0);
macs.add(new Pair<String, String>(nic.getMacAddress(), vm.getName()));
}
}
} catch (LibvirtException e) {
s_logger.debug("Failed to get MACs: " + e.toString());
}
_dhcpSnooper.initializeMacTable(macs);
}
@Override
public boolean configure(String name, Map<String, Object> params)
throws ConfigurationException {
boolean success = super.configure(name, params);
if (! success) {
return false;
}
_parent = (String)params.get("mount.path");
try {
_dhcpTimeout = Long.parseLong((String)params.get("dhcp.timeout"));
} catch (Exception e) {
_dhcpTimeout = 1200000;
}
_hostIp = (String)params.get("host.ip");
_hostMacAddress = (String)params.get("host.mac.address");
try {
Connect conn;
conn = LibvirtConnection.getConnection();
setupDhcpManager(conn, _guestBridgeName);
} catch (LibvirtException e) {
s_logger.debug("Failed to get libvirt connection:" + e.toString());
return false;
}
_dhcpSnooper.configure(name, params);
_vmDataServer.configure(name, params);
return true;
}
@Override
protected synchronized StartAnswer execute(StartCommand cmd) {
VirtualMachineTO vmSpec = cmd.getVirtualMachine();
String vmName = vmSpec.getName();
LibvirtVMDef vm = null;
State state = State.Stopped;
Connect conn = null;
try {
conn = LibvirtConnection.getConnection();
synchronized (_vms) {
_vms.put(vmName, State.Starting);
}
vm = createVMFromSpec(vmSpec);
createVbd(conn, vmSpec, vmName, vm);
createVifs(conn, vmSpec, vm);
s_logger.debug("starting " + vmName + ": " + vm.toString());
startDomain(conn, vmName, vm.toString());
NicTO[] nics = vmSpec.getNics();
for (NicTO nic : nics) {
if (nic.isSecurityGroupEnabled()) {
if (vmSpec.getType() != VirtualMachine.Type.User) {
default_network_rules_for_systemvm(conn, vmName);
} else {
nic.setIp(null);
default_network_rules(conn, vmName, nic, vmSpec.getId());
}
}
}
// Attach each data volume to the VM, if there is a deferred attached disk
for (DiskDef disk : vm.getDevices().getDisks()) {
if (disk.isAttachDeferred()) {
attachOrDetachDisk(conn, true, vmName, disk.getDiskPath(), disk.getDiskSeq());
}
}
if (vmSpec.getType() == VirtualMachine.Type.User) {
for (NicTO nic: nics) {
if (nic.getType() == TrafficType.Guest) {
InetAddress ipAddr = _dhcpSnooper.getIPAddr(nic.getMac(), vmName);
if (ipAddr == null) {
s_logger.debug("Failed to get guest DHCP ip, stop it");
StopCommand stpCmd = new StopCommand(vmName);
execute(stpCmd);
return new StartAnswer(cmd, "Failed to get guest DHCP ip, stop it");
}
s_logger.debug(ipAddr);
nic.setIp(ipAddr.getHostAddress());
post_default_network_rules(conn, vmName, nic, vmSpec.getId(), _dhcpSnooper.getDhcpServerIP(), _hostIp, _hostMacAddress);
_vmDataServer.handleVmStarted(cmd.getVirtualMachine());
}
}
}
state = State.Running;
return new StartAnswer(cmd);
} catch (Exception e) {
s_logger.warn("Exception ", e);
if (conn != null) {
handleVmStartFailure(conn, vmName, vm);
}
return new StartAnswer(cmd, e.getMessage());
} finally {
synchronized (_vms) {
if (state != State.Stopped) {
_vms.put(vmName, state);
} else {
_vms.remove(vmName);
}
}
}
}
protected Answer execute(StopCommand cmd) {
final String vmName = cmd.getVmName();
Long bytesReceived = new Long(0);
Long bytesSent = new Long(0);
State state = null;
synchronized(_vms) {
state = _vms.get(vmName);
_vms.put(vmName, State.Stopping);
}
try {
Connect conn = LibvirtConnection.getConnection();
try {
Domain dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName.getBytes()));
} catch (LibvirtException e) {
state = State.Stopped;
return new StopAnswer(cmd, null, 0, bytesSent, bytesReceived);
}
String macAddress = null;
if (vmName.startsWith("i-")) {
List<InterfaceDef> nics = getInterfaces(conn, vmName);
if (!nics.isEmpty()) {
macAddress = nics.get(0).getMacAddress();
}
}
destroy_network_rules_for_vm(conn, vmName);
String result = stopVM(conn, vmName, defineOps.UNDEFINE_VM);
try {
cleanupVnet(conn, cmd.getVnet());
_dhcpSnooper.cleanup(macAddress, vmName);
_vmDataServer.handleVmStopped(cmd.getVmName());
} catch (Exception e) {
}
state = State.Stopped;
return new StopAnswer(cmd, result, 0, bytesSent, bytesReceived);
} catch (LibvirtException e) {
return new StopAnswer(cmd, e.getMessage());
} finally {
synchronized(_vms) {
if (state != null) {
_vms.put(vmName, state);
} else {
_vms.remove(vmName);
}
}
}
}
@Override
public Answer executeRequest(Command cmd) {
if (cmd instanceof VmDataCommand) {
return execute((VmDataCommand)cmd);
} else if (cmd instanceof SavePasswordCommand) {
return execute ((SavePasswordCommand)cmd);
}
return super.executeRequest(cmd);
}
protected Answer execute(final VmDataCommand cmd) {
return _vmDataServer.handleVmDataCommand(cmd);
}
protected Answer execute(final SavePasswordCommand cmd) {
return new Answer(cmd);
}
}

View File

@ -17,25 +17,12 @@
<property file="${build-cloud.properties.file}"/>
<property name="premium.name" value="cloudstack-proprietary"/>
<property name="premium.base.dir" location="${base.dir}/${premium.name}"/>
<condition property="my.build.dir" value="${premium.base.dir}/build" else="${base.dir}/build">
<and>
<available file="${premium.base.dir}/build"/>
<not>
<isset property="OSS"/>
</not>
</and>
</condition>
<property name="dist.dir" location="${base.dir}/dist"/>
<property name="target.dir" location="${base.dir}/target"/>
<import file="${my.build.dir}/build-cloud.xml" optional="false"/>
<import file="${my.build.dir}/build-docs.xml" optional="true"/>
<import file="${my.build.dir}/build-tests.xml" optional="true"/>
<import file="${my.build.dir}/package.xml" optional="true"/>
<import file="${my.build.dir}/developer.xml" optional="true"/>
<import file="${base.dir}/build/build-cloud.xml" optional="false"/>
<import file="${base.dir}/build/build-docs.xml" optional="true"/>
<import file="${base.dir}/build/build-tests.xml" optional="true"/>
<import file="${base.dir}/build/package.xml" optional="true"/>
<import file="${base.dir}/build/developer.xml" optional="true"/>
</project>

View File

@ -218,7 +218,7 @@
<path refid="deps.classpath" />
<path refid="dist.classpath" />
</path>
<target name="compile-server" depends="-init, compile-utils, compile-core" description="Compile the management server.">
<target name="compile-server" depends="-init, compile-utils, compile-core, compile-agent" description="Compile the management server.">
<compile-java jar.name="${server.jar}" top.dir="${server.dir}" classpath="server.classpath" />
</target>
@ -280,6 +280,8 @@
</copy>
</target>
<target name="build-ovm" depends="compile-ovm" />
<target name="build-server" depends="compile-server">
<mkdir dir="${server.dist.dir}" />
<mkdir dir="${server.dist.dir}/lib" />
@ -529,7 +531,7 @@
<target name="build-servers" depends="-init, build-server" />
<target name="build-opensource" depends="-init, build-server, build-agent, build-console-proxy, build-scripts, build-ui, package-oss-systemvm-iso">
<target name="build-opensource" depends="-init, build-server, build-agent, build-console-proxy, build-scripts, build-ui, build-ovm, package-oss-systemvm-iso">
<copy overwrite="true" todir="${dist.dir}">
<fileset dir="${base.dir}/build/deploy/">
<include name="deploy-agent.sh" />
@ -629,7 +631,19 @@
<delete dir="${unittest.dir}"/>
</target>
<target name="compile-all" description="Compile all of the jars" depends="compile-utils, compile-api, compile-core, compile-server"/>
<!-- ===================== Ovm.Jar ===================== -->
<property name="ovm.jar" value="cloud-ovm.jar" />
<property name="ovm.dir" location="${base.dir}/ovm" />
<property name="ovm-scripts.dir" location="${ovm.dir}/scripts" />
<path id="ovm.classpath" >
<path refid="thirdparty.classpath" />
<path refid="dist.classpath" />
</path>
<target name="compile-ovm" depends="-init, compile-server" description="Compile OVM">
<compile-java jar.name="${ovm.jar}" top.dir="${ovm.dir}" classpath="ovm.classpath" />
</target>
<target name="compile-all" description="Compile all of the jars" depends="compile-utils, compile-api, compile-core, compile-server, compile-ovm"/>
<target name="clean-all" depends="clean" description="Clean all of the generated files, including dependency cache and javadoc">
<delete dir="${target.dir}" />

View File

@ -0,0 +1,38 @@
#### usage commands
generateUsageRecords=com.cloud.api.commands.GenerateUsageRecordsCmd;1
listUsageRecords=com.cloud.api.commands.GetUsageRecordsCmd;1
listUsageTypes=com.cloud.api.commands.ListUsageTypesCmd;1
#### external firewall commands
addExternalFirewall=com.cloud.api.commands.AddExternalFirewallCmd;1
deleteExternalFirewall=com.cloud.api.commands.DeleteExternalFirewallCmd;1
listExternalFirewalls=com.cloud.api.commands.ListExternalFirewallsCmd;1
#### external loadbalancer commands
addExternalLoadBalancer=com.cloud.api.commands.AddExternalLoadBalancerCmd;1
deleteExternalLoadBalancer=com.cloud.api.commands.DeleteExternalLoadBalancerCmd;1
listExternalLoadBalancers=com.cloud.api.commands.ListExternalLoadBalancersCmd;1
### Network Devices commands
addNetworkDevice=com.cloud.api.commands.AddNetworkDeviceCmd;1
listNetworkDevice=com.cloud.api.commands.ListNetworkDeviceCmd;1
deleteNetworkDevice=com.cloud.api.commands.DeleteNetworkDeviceCmd;1
#### traffic monitor commands
addTrafficMonitor=com.cloud.api.commands.AddTrafficMonitorCmd;1
deleteTrafficMonitor=com.cloud.api.commands.DeleteTrafficMonitorCmd;1
listTrafficMonitors=com.cloud.api.commands.ListTrafficMonitorsCmd;1
####Netapp integration commands
createVolumeOnFiler=com.cloud.api.commands.netapp.CreateVolumeCmd;15
destroyVolumeOnFiler=com.cloud.api.commands.netapp.DestroyVolumeCmd;15
listVolumesOnFiler=com.cloud.api.commands.netapp.ListVolumesCmd;15
createLunOnFiler=com.cloud.api.commands.netapp.CreateLunCmd;15
destroyLunOnFiler=com.cloud.api.commands.netapp.DestroyLunCmd;15
listLunsOnFiler=com.cloud.api.commands.netapp.ListLunsCmd;15
associateLun=com.cloud.api.commands.netapp.AssociateLunCmd;15
dissociateLun=com.cloud.api.commands.netapp.DissociateLunCmd;15
createPool=com.cloud.api.commands.netapp.CreatePoolCmd;15
deletePool=com.cloud.api.commands.netapp.DeletePoolCmd;15
modifyPool=com.cloud.api.commands.netapp.ModifyPoolCmd;15
listPools=com.cloud.api.commands.netapp.ListPoolsCmd;15

View File

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<components-cloudzones.xml>
<system-integrity-checker class="com.cloud.upgrade.DatabaseUpgradeChecker">
<checker name="ManagementServerNode" class="com.cloud.cluster.ManagementServerNode"/>
<checker name="PremiumDatabaseUpgradeChecker" class="com.cloud.upgrade.PremiumDatabaseUpgradeChecker"/>
</system-integrity-checker>
<management-server class="com.cloud.server.ManagementServerExtImpl" library="com.cloud.configuration.CloudZonesComponentLibrary" extends="components-premium.xml:management-server"/>
<configuration-server class="com.cloud.server.ConfigurationServerImpl" extends="components.xml:configuration-server">
<dao name="Configuration configuration server" class="com.cloud.configuration.dao.ConfigurationDaoImpl" singleton="false">
<param name="premium">true</param>
</dao>
</configuration-server>
</components-cloudzones.xml>

View File

@ -0,0 +1,77 @@
<?xml version="1.0"?>
<components-premium.xml>
<system-integrity-checker class="com.cloud.upgrade.DatabaseUpgradeChecker">
<checker name="ManagementServerNode" class="com.cloud.cluster.ManagementServerNode"/>
<checker name="DatabaseIntegrityChecker" class="com.cloud.upgrade.DatabaseIntegrityChecker"/>
<checker name="PremiumDatabaseUpgradeChecker" class="com.cloud.upgrade.PremiumDatabaseUpgradeChecker"/>
</system-integrity-checker>
<management-server class="com.cloud.server.ManagementServerExtImpl" library="com.cloud.configuration.PremiumComponentLibrary" extends="components.xml:management-server">
<dao name="Configuration configuration server" class="com.cloud.configuration.dao.ConfigurationDaoImpl">
<param name="premium">true</param>
</dao>
<adapters key="com.cloud.ha.Investigator">
<adapter name="SimpleInvestigator" class="com.cloud.ha.CheckOnAgentInvestigator"/>
<adapter name="XenServerInvestigator" class="com.cloud.ha.XenServerInvestigator"/>
<adapter name="PingInvestigator" class="com.cloud.ha.UserVmDomRInvestigator"/>
<adapter name="ManagementIPSysVMInvestigator" class="com.cloud.ha.ManagementIPSystemVMInvestigator"/>
</adapters>
<adapters key="com.cloud.ha.FenceBuilder">
<adapter name="XenServerFenceBuilder" class="com.cloud.ha.XenServerFencer"/>
<adapter name="KVMFenceBuilder" class="com.cloud.ha.KVMFencer"/>
</adapters>
<adapters key="com.cloud.network.guru.NetworkGuru">
<adapter name="ExternalGuestNetworkGuru" class="com.cloud.network.guru.ExternalGuestNetworkGuru"/>
<adapter name="OvsGuestNetworkGuru" class="com.cloud.network.guru.OvsGuestNetworkGuru"/>
<adapter name="PublicNetworkGuru" class="com.cloud.network.guru.PublicNetworkGuru"/>
<adapter name="PodBasedNetworkGuru" class="com.cloud.network.guru.PodBasedNetworkGuru"/>
<adapter name="ControlNetworkGuru" class="com.cloud.network.guru.ControlNetworkGuru"/>
<adapter name="DirectNetworkGuru" class="com.cloud.network.guru.DirectNetworkGuru"/>
<adapter name="DirectPodBasedNetworkGuru" class="com.cloud.network.guru.DirectPodBasedNetworkGuru"/>
</adapters>
<adapters key="com.cloud.network.element.NetworkElement">
<adapter name="ExternalFirewall" class="com.cloud.network.element.ExternalFirewallElement"/>
<adapter name="ExternalLoadBalancer" class="com.cloud.network.element.ExternalLoadBalancerElement"/>
<adapter name="DomainRouter" class="com.cloud.network.element.VirtualRouterElement"/>
<adapter name="Dhcp" class="com.cloud.network.element.DhcpElement"/>
<adapter name="Ovs" class="com.cloud.network.element.OvsElement"/>
<adapter name="ExternalDhcp" class="com.cloud.network.element.ExternalDhcpElement"/>
<adapter name="BareMetal" class="com.cloud.network.element.BareMetalElement"/>
<adapter name="ElasticLoadBalancer" class="com.cloud.network.element.ElasticLoadBalancerElement"/>
</adapters>
<adapters key="com.cloud.resource.Discoverer">
<adapter name="XCP Agent" class="com.cloud.hypervisor.xen.discoverer.XcpServerDiscoverer"/>
<adapter name="SecondaryStorage" class="com.cloud.storage.secondary.SecondaryStorageDiscoverer"/>
<adapter name="KVM Agent" class="com.cloud.hypervisor.kvm.discoverer.KvmServerDiscoverer"/>
<adapter name="VShpereServer" class="com.cloud.hypervisor.vmware.VmwareServerDiscoverer"/>
<adapter name="Bare Metal Agent" class="com.cloud.baremetal.BareMetalDiscoverer"/>
<adapter name="SCVMMServer" class="com.cloud.hypervisor.hyperv.HypervServerDiscoverer"/>
<adapter name="Ovm Discover" class="com.cloud.ovm.hypervisor.OvmDiscoverer" />
</adapters>
<adapters key="com.cloud.alert.AlertAdapter">
<adapter name="ClusterAlert" class="com.cloud.alert.ClusterAlertAdapter"/>
<adapter name="ConsoleProxyAlert" class="com.cloud.alert.ConsoleProxyAlertAdapter"/>
<adapter name="SecondaryStorageVmAlert" class="com.cloud.alert.SecondaryStorageVmAlertAdapter"/>
</adapters>
<adapters key="com.cloud.hypervisor.HypervisorGuru">
<adapter name="XenServerGuru" class="com.cloud.hypervisor.XenServerGuru"/>
<adapter name="KVMGuru" class="com.cloud.hypervisor.KVMGuru"/>
<adapter name="VMwareGuru" class="com.cloud.hypervisor.guru.VMwareGuru"/>
<adapter name="BareMetalGuru" class="com.cloud.baremetal.BareMetalGuru"/>
<adapter name="HypervGuru" class="com.cloud.hypervisor.guru.HypervGuru"/>
<adapter name="OvmGuru" class="com.cloud.ovm.hypervisor.OvmGuru" />
</adapters>
<adapters key="com.cloud.agent.StartupCommandProcessor">
<adapter name="BasicAgentAuthorizer" class="com.cloud.agent.manager.authn.impl.BasicAgentAuthManager"/>
</adapters>
</management-server>
<configuration-server class="com.cloud.server.ConfigurationServerImpl" extends="components.xml:configuration-server">
<dao name="Configuration configuration server" class="com.cloud.configuration.dao.ConfigurationDaoImpl" singleton="false">
<param name="premium">true</param>
</dao>
</configuration-server>
</components-premium.xml>

View File

@ -0,0 +1,14 @@
host=127.0.0.1
port=8250
workers=3
zone=1
pod=1
run=13
sequence=r
agent.save.path=/tmp/agents
latency=2
latency.start.range=2
latency.end.range=2
delay.distribution={(5,10); (5,10); (5,10); (5,10); (5,10); (5,10); (5,10); (5,10); (5,10); (10,120)}
property.scan.enabled=1
property.scan.interval=300

View File

@ -36,7 +36,7 @@ BuildRequires: glibc-devel
BuildRequires: /usr/bin/mkisofs
BuildRequires: MySQL-python
%global _premium %(tar jtvmf %{SOURCE0} '*/cloudstack-proprietary/' --occurrence=1 2>/dev/null | wc -l)
#%global _premium %(tar jtvmf %{SOURCE0} '*/cloudstack-proprietary/' --occurrence=1 2>/dev/null | wc -l)
%description
This is the Cloud.com Stack, a highly-scalable elastic, open source,
@ -161,6 +161,8 @@ Requires: /usr/bin/ssh-keygen
Requires: mkisofs
Requires: MySQL-python
Requires: python-paramiko
Requires: ipmitool
Requires: %{name}-utils = %{version}
Group: System Environment/Libraries
%description client
The Cloud.com management server is the central point of coordination,
@ -223,13 +225,21 @@ Requires: /sbin/service
Requires: /sbin/chkconfig
Group: System Environment/Libraries
%if 0%{?rhel} >= 6
Requires: cloud-kvm
%else
Requires: kvm
%endif
%if 0%{?fedora} >= 14
Requires: cloud-qemu-kvm
Requires: cloud-qemu-img
%endif
%if 0%{?rhel} >= 6
Requires: cloud-qemu-img
%endif
%if 0%{?rhel} >= 5
Requires: qemu-img
%endif
@ -290,64 +300,37 @@ Group: System Environment/Libraries
The Cloud.com command line tools contain a few Python modules that can call cloudStack APIs.
%if %{_premium}
%package premium-agent
Summary: Cloud.com premium agent
Requires: cloud-agent
Requires: jnetpcap
Group: System Environment/Libraries
%description premium-agent
The Cloud.com premium agent
%package test
Summary: Cloud.com test suite
Requires: java >= 1.6.0
Requires: %{name}-utils = %{version}, %{name}-deps = %{version}, wget
Group: System Environment/Libraries
Obsoletes: vmops-test < %{version}-%{release}
%description test
The Cloud.com test package contains a suite of automated tests
that the very much appreciated QA team at Cloud.com constantly
uses to help increase the quality of the Cloud.com Stack.
%package premium
Summary: Cloud.com premium components
Obsoletes: vmops-premium < %{version}-%{release}
Provides: %{name}-premium-plugin-zynga = %{version}-%{release}
Obsoletes: %{name}-premium-plugin-zynga < %{version}-%{release}
Provides: %{name}-premium-vendor-zynga = %{version}-%{release}
Obsoletes: %{name}-premium-vendor-zynga < %{version}-%{release}
Requires: java >= 1.6.0
Requires: ipmitool
Requires: %{name}-utils = %{version}
License: CSL 1.1
Group: System Environment/Libraries
%description premium
The Cloud.com premium components expand the range of features on your Cloud.com Stack.
%package usage
Summary: Cloud.com usage monitor
Obsoletes: vmops-usage < %{version}-%{release}
Requires: java >= 1.6.0
Requires: %{name}-utils = %{version}, %{name}-core = %{version}, %{name}-deps = %{version}, %{name}-server = %{version}, %{name}-premium = %{version}, %{name}-daemonize = %{version}
Requires: %{name}-setup = %{version}
Requires: %{name}-client = %{version}
License: CSL 1.1
Group: System Environment/Libraries
%description usage
The Cloud.com usage monitor provides usage accounting across the entire cloud for
cloud operators to charge based on usage parameters.
%endif
#%if %{_premium}
#
#%package test
#Summary: Cloud.com test suite
#Requires: java >= 1.6.0
#Requires: %{name}-utils = %{version}, %{name}-deps = %{version}, wget
#Group: System Environment/Libraries
#Obsoletes: vmops-test < %{version}-%{release}
#%description test
#The Cloud.com test package contains a suite of automated tests
#that the very much appreciated QA team at Cloud.com constantly
#uses to help increase the quality of the Cloud.com Stack.
#
#%package usage
#Summary: Cloud.com usage monitor
#Obsoletes: vmops-usage < %{version}-%{release}
#Requires: java >= 1.6.0
#Requires: %{name}-utils = %{version}, %{name}-core = %{version}, %{name}-deps = %{version}, %{name}-server = %{version}, %{name}-premium = %{version}, %{name}-daemonize = %{version}
#Requires: %{name}-setup = %{version}
#Requires: %{name}-client = %{version}
#License: CSL 1.1
#Group: System Environment/Libraries
#%description usage
#The Cloud.com usage monitor provides usage accounting across the entire cloud for
#cloud operators to charge based on usage parameters.
#
#%endif
%prep
%if %{_premium}
echo Doing premium build
%else
echo Doing open source build
%endif
echo Doing CloudStack build
%setup -q -n %{name}-%{_ver}
@ -381,11 +364,9 @@ id %{name} > /dev/null 2>&1 || /usr/sbin/useradd -M -c "Cloud.com unprivileged u
-r -s /bin/sh -d %{_sharedstatedir}/%{name}/management %{name}|| true
# set max file descriptors for cloud user to 4096
grep "cloud" /etc/security/limits.conf &>/dev/null
if [ $? -eq 1 ]; then
echo "cloud hard nofile 4096" >> /etc/security/limits.conf
echo "cloud soft nofile 4096" >> /etc/security/limits.conf
fi
sed -i /"cloud"/d /etc/security/limits.conf
echo "cloud hard nofile 4096" >> /etc/security/limits.conf
echo "cloud soft nofile 4096" >> /etc/security/limits.conf
rm -rf %{_localstatedir}/cache/%{name}
# user harcoded here, also hardcoded on wscript
@ -409,28 +390,28 @@ fi
%if %{_premium}
%preun usage
if [ "$1" == "0" ] ; then
/sbin/chkconfig --del %{name}-usage > /dev/null 2>&1 || true
/sbin/service %{name}-usage stop > /dev/null 2>&1 || true
fi
%pre usage
id %{name} > /dev/null 2>&1 || /usr/sbin/useradd -M -c "Cloud.com unprivileged user" \
-r -s /bin/sh -d %{_sharedstatedir}/%{name}/management %{name}|| true
# user harcoded here, also hardcoded on wscript
%post usage
if [ "$1" == "1" ] ; then
/sbin/chkconfig --add %{name}-usage > /dev/null 2>&1 || true
/sbin/chkconfig --level 345 %{name}-usage on > /dev/null 2>&1 || true
else
/sbin/service %{name}-usage condrestart >/dev/null 2>&1 || true
fi
%endif
#%if %{_premium}
#
#%preun usage
#if [ "$1" == "0" ] ; then
# /sbin/chkconfig --del %{name}-usage > /dev/null 2>&1 || true
# /sbin/service %{name}-usage stop > /dev/null 2>&1 || true
#fi
#
#%pre usage
#id %{name} > /dev/null 2>&1 || /usr/sbin/useradd -M -c "Cloud.com unprivileged user" \
# -r -s /bin/sh -d %{_sharedstatedir}/%{name}/management %{name}|| true
## user harcoded here, also hardcoded on wscript
#
#%post usage
#if [ "$1" == "1" ] ; then
# /sbin/chkconfig --add %{name}-usage > /dev/null 2>&1 || true
# /sbin/chkconfig --level 345 %{name}-usage on > /dev/null 2>&1 || true
#else
# /sbin/service %{name}-usage condrestart >/dev/null 2>&1 || true
#fi
#
#%endif
%pre agent-scripts
id %{name} > /dev/null 2>&1 || /usr/sbin/useradd -M -c "Cloud.com unprivileged user" \
@ -484,6 +465,8 @@ fi
%files server
%defattr(0644,root,root,0755)
%{_javadir}/%{name}-server.jar
%{_javadir}/%{name}-vmware-base.jar
%{_javadir}/%{name}-ovm.jar
%{_sysconfdir}/%{name}/server/*
%files agent-scripts
@ -524,10 +507,7 @@ fi
%{_javadir}/%{name}-jsch-0.1.42.jar
%{_javadir}/%{name}-iControl.jar
%{_javadir}/%{name}-manageontap.jar
%defattr(0644,root,root,0755)
%{_javadir}/%{name}-premium/*.jar
%exclude %{_javadir}/%{name}-premium/servlet-api.jar
%{_javadir}/vmware*.jar
%files core
%defattr(0644,root,root,0755)
@ -555,9 +535,7 @@ fi
%files client
%defattr(0644,root,root,0775)
%{_sysconfdir}/%{name}/management/*
%if %{_premium}
%exclude %{_sysconfdir}/%{name}/management/*premium*
%endif
%{_sysconfdir}/%{name}/management/*premium*
%config(noreplace) %attr(0640,root,%{name}) %{_sysconfdir}/%{name}/management/db.properties
%config(noreplace) %{_sysconfdir}/%{name}/management/log4j-%{name}.xml
%config(noreplace) %{_sysconfdir}/%{name}/management/tomcat6.conf
@ -596,6 +574,7 @@ fi
%{_libdir}/%{name}/agent/images
%attr(0755,root,root) %{_bindir}/%{name}-setup-agent
%dir %attr(0770,root,root) %{_localstatedir}/log/%{name}/agent
%attr(0755,root,root) %{_bindir}/mycloud-setup-agent
%files console-proxy
%defattr(0644,root,root,0755)
@ -618,44 +597,27 @@ fi
%files baremetal-agent
%attr(0755,root,root) %{_bindir}/cloud-setup-baremetal
%if %{_premium}
%files premium-agent
%{_javadir}/cloud-agent-extras.jar
%attr(0755,root,root) %{_bindir}/mycloud-setup-agent
%files test
%defattr(0644,root,root,0755)
%attr(0755,root,root) %{_bindir}/%{name}-run-test
%{_javadir}/%{name}-test.jar
%{_sharedstatedir}/%{name}/test/*
%{_libdir}/%{name}/test/*
%{_sysconfdir}/%{name}/test/*
%files premium
%defattr(0644,root,root,0755)
%{_javadir}/%{name}-core-extras.jar
%{_javadir}/%{name}-server-extras.jar
%{_javadir}/%{name}-vmware-base.jar
%{_javadir}/%{name}-ovm.jar
# maintain the following list in sync with files agent-scripts
%{_libdir}/%{name}/agent/premium-scripts/*
%{_sysconfdir}/%{name}/management/commands-ext.properties
%{_sysconfdir}/%{name}/management/components-premium.xml
%{_datadir}/%{name}/setup/create-database-premium.sql
%{_datadir}/%{name}/setup/create-schema-premium.sql
%files usage
%defattr(0644,root,root,0775)
%{_javadir}/%{name}-usage.jar
%attr(0755,root,root) %{_initrddir}/%{name}-usage
%attr(0755,root,root) %{_libexecdir}/usage-runner
%dir %attr(0770,root,%{name}) %{_localstatedir}/log/%{name}/usage
%{_sysconfdir}/%{name}/usage/usage-components.xml
%config(noreplace) %{_sysconfdir}/%{name}/usage/log4j-%{name}_usage.xml
%config(noreplace) %attr(0640,root,%{name}) %{_sysconfdir}/%{name}/usage/db.properties
%endif
#%if %{_premium}
#
#%files test
#%defattr(0644,root,root,0755)
#%attr(0755,root,root) %{_bindir}/%{name}-run-test
#%{_javadir}/%{name}-test.jar
#%{_sharedstatedir}/%{name}/test/*
#%{_libdir}/%{name}/test/*
#%{_sysconfdir}/%{name}/test/*
#
#%files usage
#%defattr(0644,root,root,0775)
#%{_javadir}/%{name}-usage.jar
#%attr(0755,root,root) %{_initrddir}/%{name}-usage
#%attr(0755,root,root) %{_libexecdir}/usage-runner
#%dir %attr(0770,root,%{name}) %{_localstatedir}/log/%{name}/usage
#%{_sysconfdir}/%{name}/usage/usage-components.xml
#%config(noreplace) %{_sysconfdir}/%{name}/usage/log4j-%{name}_usage.xml
#%config(noreplace) %attr(0640,root,%{name}) %{_sysconfdir}/%{name}/usage/db.properties
#
#%endif
%changelog
* Mon May 3 2010 Manuel Amador (Rudd-O) <manuel@vmops.com> 1.9.12

View File

@ -0,0 +1,59 @@
/**
* * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.agent.api;
import java.util.HashMap;
import java.util.Map;
public class DirectNetworkUsageAnswer extends Answer {
Map<String, long[]> ipBytesSentAndReceived;
protected DirectNetworkUsageAnswer() {
}
public DirectNetworkUsageAnswer(Command command) {
super(command);
this.ipBytesSentAndReceived = new HashMap<String, long[]>();
}
public DirectNetworkUsageAnswer(Command command, Exception e) {
super(command, e);
this.ipBytesSentAndReceived = null;
}
public void put(String ip, long[] bytesSentAndReceived) {
this.ipBytesSentAndReceived.put(ip, bytesSentAndReceived);
}
public long[] get(String ip) {
long[] entry = ipBytesSentAndReceived.get(ip);
if (entry == null) {
ipBytesSentAndReceived.put(ip, new long[]{0, 0});
return ipBytesSentAndReceived.get(ip);
} else {
return entry;
}
}
public Map<String, long[]> getIpBytesSentAndReceived() {
return ipBytesSentAndReceived;
}
}

View File

@ -0,0 +1,65 @@
/**
* * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.agent.api;
import java.util.Date;
import java.util.List;
public class DirectNetworkUsageCommand extends Command {
private List<String> publicIps;
private Date start;
private Date end;
public DirectNetworkUsageCommand(List<String> publicIps, Date start, Date end) {
this.setPublicIps(publicIps);
this.setStart(start);
this.setEnd(end);
}
@Override
public boolean executeInSequence() {
return false;
}
public void setPublicIps(List<String> publicIps) {
this.publicIps = publicIps;
}
public List<String> getPublicIps() {
return publicIps;
}
public void setStart(Date start) {
this.start = start;
}
public Date getStart() {
return start;
}
public void setEnd(Date end) {
this.end = end;
}
public Date getEnd() {
return end;
}
}

View File

@ -0,0 +1,44 @@
/**
* * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.agent.api;
import java.util.HashMap;
import java.util.Map;
public class ExternalNetworkResourceUsageAnswer extends Answer {
public Map<String, long[]> ipBytes;
public Map<String, long[]> guestVlanBytes;
protected ExternalNetworkResourceUsageAnswer() {
}
public ExternalNetworkResourceUsageAnswer(Command command) {
super(command);
this.ipBytes = new HashMap<String, long[]>();
this.guestVlanBytes = new HashMap<String, long[]>();
}
public ExternalNetworkResourceUsageAnswer(Command command, Exception e) {
super(command, e);
this.ipBytes = null;
this.guestVlanBytes = null;
}
}

View File

@ -0,0 +1,31 @@
/**
* * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.agent.api;
public class ExternalNetworkResourceUsageCommand extends Command {
public ExternalNetworkResourceUsageCommand() {
}
@Override
public boolean executeInSequence() {
return false;
}
}

View File

@ -0,0 +1,37 @@
/**
* * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.agent.api;
public class RecurringNetworkUsageAnswer extends Answer {
protected RecurringNetworkUsageAnswer() {
}
public RecurringNetworkUsageAnswer(Command command) {
super(command);
}
public RecurringNetworkUsageAnswer(Command command, Exception e) {
super(command, e);
}
}

View File

@ -0,0 +1,39 @@
/**
* * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.agent.api;
public class RecurringNetworkUsageCommand extends Command implements CronCommand{
int interval;
public RecurringNetworkUsageCommand(int interval) {
this.interval = interval;
}
public int getInterval() {
return interval;
}
@Override
public boolean executeInSequence() {
return false;
}
}

View File

@ -0,0 +1,87 @@
/**
* * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.agent.api;
import com.cloud.agent.api.Command;
import com.cloud.host.Host;
/**
* Implementation of bootstrap command sent from management server to agent running on
* System Center Virtual Machine Manager host
**/
public class StartupVMMAgentCommand extends Command {
Host.Type type;
long dataCenter;
Long pod;
String clusterName;
String guid;
String managementServerIP;
String port;
String version;
public StartupVMMAgentCommand() {
}
public StartupVMMAgentCommand(long dataCenter, Long pod, String clusterName, String guid, String managementServerIP, String port, String version) {
super();
this.dataCenter = dataCenter;
this.pod = pod;
this.clusterName = clusterName;
this.guid = guid;
this.type = Host.Type.Routing;
this.managementServerIP = managementServerIP;
this.port = port;
}
public long getDataCenter() {
return dataCenter;
}
public Long getPod() {
return pod;
}
public String getClusterName() {
return clusterName;
}
public String getGuid() {
return guid;
}
public String getManagementServerIP() {
return managementServerIP;
}
public String getport() {
return port;
}
public void setVersion(String version) {
this.version = version;
}
@Override
public boolean executeInSequence() {
return false;
}
}

View File

@ -0,0 +1,67 @@
/**
* * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.hypervisor.hyperv.resource;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.host.Host.Type;
import com.cloud.resource.ServerResource;
import com.cloud.resource.ServerResourceBase;
/**
* Implementation of dummy resource to be returned from discoverer
**/
public class HypervDummyResourceBase extends ServerResourceBase implements
ServerResource {
@Override
public Type getType() {
// TODO Auto-generated method stub
return null;
}
@Override
public StartupCommand[] initialize() {
// TODO Auto-generated method stub
return null;
}
@Override
public PingCommand getCurrentStatus(long id) {
// TODO Auto-generated method stub
return null;
}
@Override
public Answer executeRequest(Command cmd) {
// TODO Auto-generated method stub
return null;
}
@Override
protected String getDefaultScriptsDir() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -0,0 +1,954 @@
/**
* * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.hypervisor.hyperv.resource;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.agent.IAgentControl;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.AttachIsoCommand;
import com.cloud.agent.api.AttachVolumeCommand;
import com.cloud.agent.api.BackupSnapshotCommand;
import com.cloud.agent.api.CheckHealthCommand;
import com.cloud.agent.api.CheckOnHostCommand;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.DeleteSnapshotBackupCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.DeleteStoragePoolCommand;
import com.cloud.agent.api.GetHostStatsAnswer;
import com.cloud.agent.api.GetHostStatsCommand;
import com.cloud.agent.api.GetStorageStatsAnswer;
import com.cloud.agent.api.GetStorageStatsCommand;
import com.cloud.agent.api.GetVmStatsCommand;
import com.cloud.agent.api.GetVncPortCommand;
import com.cloud.agent.api.HostStatsEntry;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.ManageSnapshotCommand;
import com.cloud.agent.api.MigrateCommand;
import com.cloud.agent.api.ModifySshKeysCommand;
import com.cloud.agent.api.ModifyStoragePoolAnswer;
import com.cloud.agent.api.ModifyStoragePoolCommand;
import com.cloud.agent.api.NetworkUsageCommand;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.PingRoutingCommand;
import com.cloud.agent.api.PingTestCommand;
import com.cloud.agent.api.PoolEjectCommand;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.ReadyAnswer;
import com.cloud.agent.api.ReadyCommand;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.RebootRouterCommand;
import com.cloud.agent.api.SetupCommand;
import com.cloud.agent.api.StartAnswer;
import com.cloud.agent.api.StartCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupRoutingCommand;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.ValidateSnapshotCommand;
import com.cloud.agent.api.check.CheckSshAnswer;
import com.cloud.agent.api.check.CheckSshCommand;
import com.cloud.agent.api.routing.DhcpEntryCommand;
import com.cloud.agent.api.routing.IpAssocCommand;
import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
import com.cloud.agent.api.routing.NetworkElementCommand;
import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
import com.cloud.agent.api.routing.SavePasswordCommand;
import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
import com.cloud.agent.api.routing.VmDataCommand;
import com.cloud.agent.api.routing.VpnUsersCfgCommand;
import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.agent.api.storage.CreateAnswer;
import com.cloud.agent.api.storage.CreateCommand;
import com.cloud.agent.api.storage.DestroyCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.api.to.VolumeTO;
import com.cloud.host.Host.Type;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.vmware.resource.SshHelper;
import com.cloud.resource.ServerResource;
import com.cloud.resource.ServerResourceBase;
import com.cloud.serializer.GsonHelper;
import com.cloud.storage.Volume;
import com.cloud.storage.template.TemplateInfo;
import com.cloud.utils.Pair;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.DiskProfile;
import com.cloud.vm.VirtualMachine.State;
import com.google.gson.Gson;
/**
* Implementation of resource base class for Hyper-V hypervisor
**/
@Local(value={ServerResource.class})
public class HypervResource extends ServerResourceBase implements ServerResource{
private String _dcId;
private String _podId;
private String _clusterId;
private String _guid;
private String _name;
private static final Logger s_logger = Logger.getLogger(HypervResource.class);
private IAgentControl agentControl;
private volatile Boolean _wakeUp = false;
protected Gson _gson;
protected HashMap<String, State> _vms = new HashMap<String, State>(512);
protected final int DEFAULT_DOMR_SSHPORT = 3922;
public HypervResource()
{
_gson = GsonHelper.getGsonLogger();
}
@Override
public Answer executeRequest(Command cmd) {
if (cmd instanceof CreateCommand) {
return execute((CreateCommand) cmd);
} else if (cmd instanceof SetPortForwardingRulesCommand) {
s_logger.info("SCVMM agent recived command SetPortForwardingRulesCommand");
//return execute((SetPortForwardingRulesCommand) cmd);
} else if (cmd instanceof SetStaticNatRulesCommand) {
s_logger.info("SCVMM agent recived command SetStaticNatRulesCommand");
//return execute((SetStaticNatRulesCommand) cmd);
}else if (cmd instanceof LoadBalancerConfigCommand) {
s_logger.info("SCVMM agent recived command SetStaticNatRulesCommand");
//return execute((LoadBalancerConfigCommand) cmd);
} else if (cmd instanceof IpAssocCommand) {
s_logger.info("SCVMM agent recived command IPAssocCommand");
//return execute((IPAssocCommand) cmd);
} else if (cmd instanceof SavePasswordCommand) {
s_logger.info("SCVMM agent recived command SavePasswordCommand");
//return execute((SavePasswordCommand) cmd);
} else if (cmd instanceof DhcpEntryCommand) {
return execute((DhcpEntryCommand) cmd);
} else if (cmd instanceof VmDataCommand) {
//return execute((VmDataCommand) cmd);
} else if (cmd instanceof ReadyCommand) {
s_logger.info("SCVMM agent recived ReadyCommand: " + _gson.toJson(cmd));
return new ReadyAnswer((ReadyCommand) cmd);
} else if (cmd instanceof GetHostStatsCommand) {
return execute((GetHostStatsCommand) cmd);
} else if (cmd instanceof GetVmStatsCommand) {
s_logger.info("SCVMM agent recived command GetVmStatsCommand");
//return execute((GetVmStatsCommand) cmd);
} else if (cmd instanceof CheckHealthCommand) {
//return execute((CheckHealthCommand) cmd);
} else if (cmd instanceof StopCommand) {
//return execute((StopCommand) cmd);
} else if (cmd instanceof RebootRouterCommand) {
//return execute((RebootRouterCommand) cmd);
} else if (cmd instanceof RebootCommand) {
//return execute((RebootCommand) cmd);
} else if (cmd instanceof CheckVirtualMachineCommand) {
s_logger.info("SCVMM agent recived command CheckVirtualMachineCommand");
//return execute((CheckVirtualMachineCommand) cmd);
} else if (cmd instanceof PrepareForMigrationCommand) {
//return execute((PrepareForMigrationCommand) cmd);
} else if (cmd instanceof MigrateCommand) {
//return execute((MigrateCommand) cmd);
} else if (cmd instanceof DestroyCommand) {
//return execute((DestroyCommand) cmd);
} else if (cmd instanceof ModifyStoragePoolCommand) {
return execute((ModifyStoragePoolCommand) cmd);
} else if (cmd instanceof DeleteStoragePoolCommand) {
s_logger.info("SCVMM agent recived command DeleteStoragePoolCommand");
Answer answer = new Answer(cmd, true, "success");
return answer;
//return execute((DeleteStoragePoolCommand) cmd);
} else if (cmd instanceof CopyVolumeCommand) {
s_logger.info("SCVMM agent recived command CopyVolumeCommand");
//return execute((CopyVolumeCommand) cmd);
} else if (cmd instanceof AttachVolumeCommand) {
s_logger.info("SCVMM agent recived command AttachVolumeCommand");
//return execute((AttachVolumeCommand) cmd);
} else if (cmd instanceof AttachIsoCommand) {
//return execute((AttachIsoCommand) cmd);
} else if (cmd instanceof ValidateSnapshotCommand) {
//return execute((ValidateSnapshotCommand) cmd);
} else if (cmd instanceof ManageSnapshotCommand) {
//return execute((ManageSnapshotCommand) cmd);
} else if (cmd instanceof BackupSnapshotCommand) {
//return execute((BackupSnapshotCommand) cmd);
} else if (cmd instanceof DeleteSnapshotBackupCommand) {
//return execute((DeleteSnapshotBackupCommand) cmd);
} else if (cmd instanceof CreateVolumeFromSnapshotCommand) {
//return execute((CreateVolumeFromSnapshotCommand) cmd);
} else if (cmd instanceof DeleteSnapshotsDirCommand) {
//return execute((DeleteSnapshotsDirCommand) cmd);
} else if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) {
//return execute((CreatePrivateTemplateFromVolumeCommand) cmd);
} else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) {
//return execute((CreatePrivateTemplateFromSnapshotCommand) cmd);
} else if (cmd instanceof GetStorageStatsCommand) {
return execute((GetStorageStatsCommand) cmd);
} else if (cmd instanceof PrimaryStorageDownloadCommand) {
s_logger.info("SCVMM agent recived command PrimaryStorageDownloadCommand");
return execute((PrimaryStorageDownloadCommand) cmd);
} else if (cmd instanceof GetVncPortCommand) {
//return execute((GetVncPortCommand) cmd);
} else if (cmd instanceof SetupCommand) {
//return execute((SetupCommand) cmd);
} else if (cmd instanceof MaintainCommand) {
//return execute((MaintainCommand) cmd);
} else if (cmd instanceof PingTestCommand) {
s_logger.info("SCVMM agent recived command PingTestCommand");
//return execute((PingTestCommand) cmd);
} else if (cmd instanceof CheckOnHostCommand) {
s_logger.info("SCVMM agent recived command CheckOnHostCommand");
//return execute((CheckOnHostCommand) cmd);
} else if (cmd instanceof ModifySshKeysCommand) {
//return execute((ModifySshKeysCommand) cmd);
} else if (cmd instanceof PoolEjectCommand) {
//return execute((PoolEjectCommand) cmd);
} else if (cmd instanceof NetworkUsageCommand) {
//return execute((NetworkUsageCommand) cmd);
} else if (cmd instanceof StartCommand) {
return execute((StartCommand) cmd);
} else if (cmd instanceof RemoteAccessVpnCfgCommand) {
//return execute((RemoteAccessVpnCfgCommand) cmd);
} else if (cmd instanceof VpnUsersCfgCommand) {
//return execute((VpnUsersCfgCommand) cmd);
} else if (cmd instanceof CheckSshCommand) {
return execute((CheckSshCommand)cmd);
} else {
s_logger.info("SCVMM agent recived unimplemented command: " + _gson.toJson(cmd));
return Answer.createUnsupportedCommandAnswer(cmd);
}
return Answer.createUnsupportedCommandAnswer(cmd);
}
public PrimaryStorageDownloadAnswer execute(PrimaryStorageDownloadCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource PrimaryStorageDownloadCommand: " + _gson.toJson(cmd));
}
try {
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
String primaryStroageUrl = cmd.getPrimaryStorageUrl();
String templateUuidName =null;
assert ((primaryStroageUrl != null) && (secondaryStorageUrl != null));
// FIXME: paths and system vm name are hard coded
String templateUrl = cmd.getUrl();
String templatePath = templateUrl.replace('/', '\\');
templatePath = templatePath.substring(4);
if (!templatePath.endsWith(".vhd")) {
String templateName = cmd.getName();
templateUuidName = UUID.nameUUIDFromBytes((templateName + "@" + cmd.getPoolUuid()).getBytes()).toString();
if (!templatePath.endsWith("\\")) {
templatePath = templatePath + "\\";
}
//templatePath = templatePath + templateUuidName + ".vhd";
templatePath = templatePath + "systemvm.vhd";
}
s_logger.info("template URL: "+ templateUrl + "template name: "+ cmd.getName() + " sec storage " + secondaryStorageUrl+ " pri storage" + primaryStroageUrl);
StringBuilder cmdStr = new StringBuilder("cmd /c powershell.exe ");
cmdStr.append("copy-item '");
cmdStr.append(templatePath.toCharArray());
cmdStr.append("' 'C:\\programdata\\Virtual Machine Manager Library Files\\VHDs\\';");
s_logger.info("Running command: " + cmdStr);
Process p = Runtime.getRuntime().exec(cmdStr.toString());
p.getOutputStream().close();
InputStreamReader temperrReader = new InputStreamReader(new BufferedInputStream(p.getErrorStream()));
BufferedReader errreader = new BufferedReader(temperrReader);
if (errreader.ready()) {
String errorOutput = new String("");
s_logger.info("errors found while running cmdlet: " + cmdStr.toString());
while (true){
String errline = errreader.readLine();
if (errline == null) {
break;
}
errorOutput = errorOutput + errline;
}
s_logger.info(errorOutput);
}
p.getErrorStream().close();
InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(p.getInputStream()));
BufferedReader reader = new BufferedReader(tempReader);
String output = new String("");
while (true){
String line = reader.readLine();
if (line == null) {
break;
}
output = output + line;
}
p.getInputStream().close();
s_logger.info("Command output: "+ output);
if (output.contains("FullyQualifiedErrorId") || output.contains("Error") || output.contains("Exception")) {
return new PrimaryStorageDownloadAnswer("Failed to copy template to SCVMM library share from secondary storage.");
}
return new PrimaryStorageDownloadAnswer(templateUuidName, 0);
} catch (Exception e)
{
s_logger.info("Exception caught: "+e.getMessage());
return new PrimaryStorageDownloadAnswer("Failed to copy template to SCVMM library share from secondary storage.");
}
}
protected Answer execute(CreateCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource CreateCommand: " + _gson.toJson(cmd));
}
try {
long volId = cmd.getVolumeId();
String templateUrl = cmd.getTemplateUrl();;
StorageFilerTO pool = cmd.getPool();
DiskProfile diskchar = cmd.getDiskCharacteristics();
if (diskchar.getType() == Volume.Type.ROOT) {
if (cmd.getTemplateUrl() == null) {
//create root volume
VolumeTO vol = new VolumeTO(cmd.getVolumeId(),
diskchar.getType(),
pool.getType(), pool.getUuid(), cmd.getDiskCharacteristics().getName(),
pool.getPath(), cmd.getDiskCharacteristics().getName(), cmd.getDiskCharacteristics().getSize(),
null);
return new CreateAnswer(cmd, vol);
} else {
VolumeTO vol = new VolumeTO(cmd.getVolumeId(),
diskchar.getType(),
pool.getType(), pool.getUuid(), cmd.getDiskCharacteristics().getName(),
pool.getPath(), cmd.getDiskCharacteristics().getName(), cmd.getDiskCharacteristics().getSize(), null);
return new CreateAnswer(cmd, vol);
}
} else {
//create data volume
String volumeUuid = "cloud.worker." + UUID.randomUUID().toString();
VolumeTO vol = new VolumeTO(cmd.getVolumeId(),
diskchar.getType(),
pool.getType(), pool.getUuid(), cmd.getDiskCharacteristics().getName(),
pool.getPath(), volumeUuid, cmd.getDiskCharacteristics().getSize(), null);
return new CreateAnswer(cmd, vol);
}
} catch (Exception ex) {
return null;
}
}
protected StartAnswer execute(StartCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource StartCommand: " + _gson.toJson(cmd));
}
VirtualMachineTO vmSpec = cmd.getVirtualMachine();
String vmName = vmSpec.getName();
State state = State.Stopped;
String scriptFileName = vmName+ ".ps1";
String newLine = System.getProperty("line.separator");
String bootArgsDiskName = vmName+"-bootparams.vhd";
String bootArgsDiskPath = "C:\\ProgramData\\Virtual Machine Manager Library Files\\VHDs\\"+bootArgsDiskName;
try {
// mark VM as starting state so that sync() can know not to report stopped too early
synchronized (_vms) {
_vms.put(vmName, State.Starting);
{
// create and attach boot parameter disk
String diskpartScriptName = vmName+"-Diskpart.txt";
StringBuilder cmdDiskpart = new StringBuilder("create vdisk file=\"");cmdDiskpart.append(bootArgsDiskPath.toCharArray());cmdDiskpart.append("\" maximum=10 type=expandable" + newLine);
cmdDiskpart.append("select vdisk file=\"");cmdDiskpart.append(bootArgsDiskPath.toCharArray());cmdDiskpart.append("\"" + newLine);
cmdDiskpart.append("attach vdisk" + newLine);
cmdDiskpart.append("create partition primary" + newLine);
cmdDiskpart.append("format fs=ntfs label=\"test vhd\" quick" + newLine);
cmdDiskpart.append("assign letter="+vmName.toCharArray()[0]+ newLine);
cmdDiskpart.append("attach vdisk" + newLine);
File f=new File(diskpartScriptName);
FileOutputStream fop=new FileOutputStream(f);
fop.write(cmdDiskpart.toString().getBytes());
fop.flush();
fop.close();
s_logger.info("Running diskpart attach command");
Process p = Runtime.getRuntime().exec("cmd.exe /c diskpart.exe /s "+diskpartScriptName);
p.getOutputStream().close();
InputStreamReader temperrReader = new InputStreamReader(new BufferedInputStream(p.getErrorStream()));
BufferedReader errreader = new BufferedReader(temperrReader);
if (errreader.ready()) {
String errorOutput = new String("");
while (true){
String errline = errreader.readLine();
if (errline == null) {
break;
}
errorOutput = errorOutput + errline;
}
s_logger.info("errors found while running diskpart command: " + errorOutput);
}
p.getErrorStream().close();
InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(p.getInputStream()));
BufferedReader reader = new BufferedReader(tempReader);
String output = new String("");
while (true){
String line = reader.readLine();
if (line == null) {
break;
}
output = output + line;
}
p.getInputStream().close();
s_logger.info("diskpart detahc command output: "+ output);
}
// wait for a while so that disk formatting is done
Thread.sleep(60000);
//create boot args on the disk
String bootArgs = vmSpec.getBootArgs();
String Drive = vmName.substring(0,1);
File fBootargs =new File(Drive+":\\cmdline");
FileOutputStream fopBoot=new FileOutputStream(fBootargs);
fopBoot.write(bootArgs.toString().getBytes());
fopBoot.flush();
fopBoot.close();
//detach the boot parameter disk
{
String diskpartDetachScriptName = vmName+"-Detach-Diskpart.txt";
StringBuilder cmdDetachDiskpart = new StringBuilder("select vdisk file=\"");
cmdDetachDiskpart.append(bootArgsDiskPath.toCharArray());cmdDetachDiskpart.append("\"" + newLine);
cmdDetachDiskpart.append("detach vdisk" + newLine);
File fd=new File(diskpartDetachScriptName);
FileOutputStream fdop=new FileOutputStream(fd);
fdop.write(cmdDetachDiskpart.toString().getBytes());
fdop.flush();
fdop.close();
s_logger.info("Running diskpart detach command");
Process pd = Runtime.getRuntime().exec("cmd.exe /c diskpart.exe /s "+diskpartDetachScriptName);
pd.getOutputStream().close();
InputStreamReader temperrReader1 = new InputStreamReader(new BufferedInputStream(pd.getErrorStream()));
BufferedReader errreader1 = new BufferedReader(temperrReader1);
if (errreader1.ready()) {
String errorOutput = new String("");
while (true){
String errline = errreader1.readLine();
if (errline == null) {
break;
}
errorOutput = errorOutput + errline;
}
s_logger.info("errors found while running diskpart detach command: " + errorOutput);
}
pd.getErrorStream().close();
InputStreamReader tempReader1 = new InputStreamReader(new BufferedInputStream(pd.getInputStream()));
BufferedReader reader1 = new BufferedReader(tempReader1);
String output1 = new String("");
while (true){
String line = reader1.readLine();
if (line == null) {
break;
}
output1 = output1 + line;
}
pd.getInputStream().close();
s_logger.info("diskpart detach command output: "+ output1);
}
}
UUID id = UUID.randomUUID();
String hwProfileId = id.toString();
StringBuilder cmdStr = new StringBuilder("Add-PSSnapin Microsoft.SystemCenter.VirtualMachineManager;" + newLine);
cmdStr.append("Get-VMMServer -ComputerName localhost;" + newLine);
cmdStr.append("$JobGroupId = [Guid]::NewGuid().ToString();" + newLine);
cmdStr.append("$hwProfileId = [Guid]::NewGuid().ToString(); " + newLine);
cmdStr.append("$CPUType = Get-CPUType -VMMServer localhost | where {$_.Name -eq " + "'1.20 GHz Athlon MP'}; " + newLine);
cmdStr.append("$ISO = Get-ISO -VMMServer localhost | where { $_.Name -match \"systemvm\" }; " + newLine);
cmdStr.append("$VMHost = Get-VMHost -VMMServer localhost | where {$_.Name -eq \"HYPERVHOST.hypervdc.intranet.lab.vmops.com\"}; " + newLine);
cmdStr.append("$VNetwork = Get-VirtualNetwork -VMHost $VMHost -Name \"public\"; " + newLine);
cmdStr.append("New-VirtualNetworkAdapter -VMMServer localhost -JobGroup $JobGroupID -PhysicalAddressType Dynamic -VirtualNetwork $vnetwork; " + newLine);
cmdStr.append("New-VirtualNetworkAdapter -VMMServer localhost -JobGroup $JobGroupID -PhysicalAddressType Dynamic -VirtualNetwork $vnetwork; " + newLine);
cmdStr.append("New-VirtualNetworkAdapter -VMMServer localhost -JobGroup $JobGroupID -PhysicalAddressType Dynamic -VirtualNetwork $vnetwork; " + newLine);
cmdStr.append("New-VirtualDVDDrive -VMMServer localhost -JobGroup $JobGroupID -Bus 1 -LUN 0 -ISO $ISO ; " + newLine);
cmdStr.append("New-HardwareProfile -VMMServer localhost -JobGroup $JobGroupID -Owner \"HYPERVDC\\Administrator\" -CPUType $CPUType -Name $hwProfileId");
cmdStr.append(" -Description \"Profile used to create a VM/Template\"" +
" -CPUCount 1 -MemoryMB 512 -RelativeWeight 100 -HighlyAvailable $true -NumLock $false -BootOrder \"CD\", " +
"\"IdeHardDrive\", \"PxeBoot\", \"Floppy\" -LimitCPUFunctionality $false -LimitCPUForMigration $false; " + newLine);
cmdStr.append("$JobGroupId = [Guid]::NewGuid().ToString(); " + newLine);
//refresh library share
cmdStr.append("$share = Get-LibraryShare;"+newLine);
cmdStr.append("Refresh-LibraryShare -LibraryShare $share;"+newLine);
// create root disk
cmdStr.append("$VirtualHardDisk1 = Get-VirtualHardDisk -VMMServer localhost | where {$_.Location -eq \"\\\\scvmm.hypervdc.intranet.lab.vmops.com\\MSSCVMMLibrary\\VHDs\\systemvm.vhd\"} | where {$_.HostName -eq \"scvmm.hypervdc.intranet.lab.vmops.com\"}" + newLine);
cmdStr.append("New-VirtualDiskDrive -VMMServer localhost -JobGroup $JobGroupID -IDE -Bus 0 -LUN 0 -VirtualHardDisk $VirtualHardDisk1 -Filename \"");
cmdStr.append(vmName.toCharArray());
cmdStr.append("-systemvm.vhd\"; " + newLine);
// create boot param data disk
cmdStr.append("$VirtualHardDisk2 = Get-VirtualHardDisk -VMMServer localhost " +
" | where {$_.Location -eq \"\\\\scvmm.hypervdc.intranet.lab.vmops.com\\MSSCVMMLibrary\\VHDs\\");
cmdStr.append(bootArgsDiskName.toCharArray());
cmdStr.append("\" } | where {$_.HostName -eq \"scvmm.hypervdc.intranet.lab.vmops.com\"}" + newLine);
cmdStr.append("New-VirtualDiskDrive -VMMServer localhost -JobGroup $JobGroupID -IDE -Bus 0 -LUN 1 -VirtualHardDisk $VirtualHardDisk2 -Filename \"");
cmdStr.append(bootArgsDiskName.toCharArray());
cmdStr.append("\";"+newLine);
cmdStr.append("$HardwareProfile = Get-HardwareProfile -VMMServer localhost | where {$_.Name -eq $hwProfileId};" + newLine);
cmdStr.append("$OperatingSystem = Get-OperatingSystem -VMMServer localhost | where {$_.Name -eq 'Other Linux (32 bit)'};" + newLine);
cmdStr.append("New-VM -VMMServer localhost -Name \"");
cmdStr.append(vmName.toCharArray());
cmdStr.append("\" -Description \"\" -Owner \"HYPERVDC\\Administrator\" -VMHost $VMHost -Path \"C:\\ClusterStorage\\Volume1\" -HardwareProfile $HardwareProfile " +
" -JobGroup $JobGroupID" +
" -OperatingSystem $OperatingSystem -RunAsSystem -StartVM -StartAction NeverAutoTurnOnVM -StopAction SaveVM;" + newLine);
File f=new File(scriptFileName);
FileOutputStream fop=new FileOutputStream(f);
fop.write(cmdStr.toString().getBytes());
fop.flush();
fop.close();
s_logger.info("Running command: " + cmdStr);
Process p = Runtime.getRuntime().exec("cmd.exe /c Powershell -Command \" & '.\\" + scriptFileName +"'\"");
p.getOutputStream().close();
InputStreamReader temperrReader = new InputStreamReader(new BufferedInputStream(p.getErrorStream()));
BufferedReader errreader = new BufferedReader(temperrReader);
if (errreader.ready()) {
String errorOutput = new String("");
while (true){
String errline = errreader.readLine();
if (errline == null) {
break;
}
errorOutput = errorOutput + errline;
}
s_logger.info("errors found while running cmdlet to create VM: " + errorOutput);
}
p.getErrorStream().close();
InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(p.getInputStream()));
BufferedReader reader = new BufferedReader(tempReader);
String output = new String("");
while (true){
String line = reader.readLine();
if (line == null) {
break;
}
output = output + line;
}
p.getInputStream().close();
s_logger.info("vm create cmmdlet output: "+ output);
if (output.contains("FullyQualifiedErrorId") || output.contains("Error") || output.contains("Exception")) {
s_logger.info("No errors found in running cmdlet "+ cmdStr.toString());
return new StartAnswer(cmd, "Failed to start VM");
}
state = State.Running;
return new StartAnswer(cmd);
} catch (Exception e){
return new StartAnswer(cmd, "Failed to start VM");
} finally {
//delete the PS script file
//File f=new File(".\\"+scriptFileName);
//f.delete();
synchronized (_vms) {
if (state != State.Stopped) {
_vms.put(vmName, state);
} else {
_vms.remove(vmName);
}
}
}
}
protected Answer execute(DhcpEntryCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource DhcpEntryCommand: " + _gson.toJson(cmd));
}
String args = " " + cmd.getVmMac();
args += " " + cmd.getVmIpAddress();
args += " " + cmd.getVmName();
if (s_logger.isDebugEnabled()) {
s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/edithosts.sh " + args);
}
try {
Pair<Boolean, String> result = SshHelper.sshExecute(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), DEFAULT_DOMR_SSHPORT, "root",
new File("id_rsa.cloud"), null, "/root/edithosts.sh " + args);
if (!result.first()) {
s_logger.error("dhcp_entry command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)
+ " failed, message: " + result.second());
return new Answer(cmd, false, "DhcpEntry failed due to " + result.second());
}
if (s_logger.isInfoEnabled()) {
s_logger.info("dhcp_entry command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed");
}
} catch (Throwable e) {
s_logger.error("Unexpected exception ", e);
return new Answer(cmd, false, "DhcpEntry failed due to exception");
}
return new Answer(cmd);
}
protected CheckSshAnswer execute(CheckSshCommand cmd) {
String vmName = cmd.getName();
String privateIp = cmd.getIp();
int cmdPort = cmd.getPort();
if (s_logger.isInfoEnabled()) {
s_logger.info("Ping VM:" + cmd.getName() + " IP:" + privateIp + " port:" + cmdPort);
}
return new CheckSshAnswer(cmd);
}
@Override
public void setAgentControl(IAgentControl agentControl) {
this.agentControl = agentControl;
}
@Override
public Type getType() {
// TODO Auto-generated method stub
return null;
}
@Override
public StartupCommand[] initialize() {
s_logger.info("recieved initialize request for cluster:" + _clusterId);
List<String> vmHostList = getHostsInCluster(_clusterId);
if (vmHostList.size() == 0) {
s_logger.info("cluster is not recognized or zero instances in the cluster");
}
StartupCommand[] answerCmds = new StartupCommand[vmHostList.size()];
int index =0;
for (String hostName: vmHostList) {
s_logger.info("Node :" + hostName);
StartupRoutingCommand cmd = new StartupRoutingCommand();
answerCmds[index] = cmd;
fillHostInfo(cmd,hostName);
index++;
}
s_logger.info("response sent to initialize request for cluster:" + _clusterId);
return answerCmds;
}
protected void fillHostInfo(StartupRoutingCommand cmd, String hostName) {
Map<String, String> details = cmd.getHostDetails();
if (details == null) {
details = new HashMap<String, String>();
}
try {
fillHostHardwareInfo(cmd);
fillHostNetworkInfo(cmd);
fillHostDetailsInfo(details);
} catch (Exception e) {
s_logger.error("Exception while retrieving host info ", e);
throw new CloudRuntimeException("Exception while retrieving host info");
}
cmd.setName(hostName);
cmd.setHostDetails(details);
cmd.setGuid(_guid);
cmd.setDataCenter(_dcId);
cmd.setPod(_podId);
cmd.setCluster(_clusterId);
cmd.setHypervisorType(HypervisorType.Hyperv);
}
private void fillHostDetailsInfo(Map<String, String> details) throws Exception {
}
private Answer execute(GetHostStatsCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource GetHostStatsCommand: " + _gson.toJson(cmd));
}
try {
// FIXME: get the actual host stats by running powershell cmdlet. This is just for prototype.
HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), 0, 10000, 10000,
"host", 2*1024*1024, 1*1024*1024, 1*1024*1024, 0);
s_logger.info("returning stats :" + 2*1024*1024 + " " + 1*1024*1024 + " " + 1*1024*1024);
return new GetHostStatsAnswer(cmd, hostStats);
} catch (Exception e) {
HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), 0, 0, 0,
"host", 0, 0, 0, 0);
String msg = "Unable to execute GetHostStatsCommand due to exception " + e.getMessage();
s_logger.error(msg, e);
return new GetHostStatsAnswer(cmd, hostStats);
}
}
protected Answer execute(ModifyStoragePoolCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource ModifyStoragePoolCommand: " + _gson.toJson(cmd));
}
try {
StorageFilerTO pool = cmd.getPool();
s_logger.info("Primary storage pool details: " + pool.getHost() + " " + pool.getPath());
Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>();
// FIXME: get the actual storage capacity and storage stats of CSV volume
// by running powershell cmdlet. This hardcoding just for prototype.
ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd,
1024*1024*1024*1024L, 512*1024*1024*1024L, tInfo);
return answer;
} catch (Throwable e) {
return new Answer(cmd, false, "Unable to execute ModifyStoragePoolCommand due to exception " + e.getMessage());
}
}
protected Answer execute(GetStorageStatsCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing GetStorageStatsCommand command: " + _gson.toJson(cmd));
}
// FIXME: get the actual storage capacity and storage stats of CSV volume
return new GetStorageStatsAnswer(cmd, 1024*1024*1024*1024L, 512*1024*1024*1024L);
}
private void fillHostHardwareInfo(StartupRoutingCommand cmd) throws RemoteException {
try {
// FIXME: get the actual host capacity by running cmdlet.This hardcoding just for prototype
cmd.setCaps("hvm");
cmd.setDom0MinMemory(0);
cmd.setSpeed(100000);
cmd.setCpus(6);
long ram = new Long("211642163904");
cmd.setMemory(ram);
} catch (Throwable e) {
s_logger.error("Unable to query host network info due to exception ", e);
throw new CloudRuntimeException("Unable to query host network info due to exception");
}
}
private void fillHostNetworkInfo(StartupRoutingCommand cmd) throws RemoteException {
try {
// FIXME: get the actual host and storage IP by running cmdlet.This hardcoding just for prototype
cmd.setPrivateIpAddress("192.168.154.236");
cmd.setPrivateNetmask("255.255.255.0");
cmd.setPrivateMacAddress("00:16:3e:77:e2:a0");
cmd.setStorageIpAddress("192.168.154.36");
cmd.setStorageNetmask("255.255.255.0");
cmd.setStorageMacAddress("00:16:3e:77:e2:a0");
} catch (Throwable e) {
s_logger.error("Unable to query host network info due to exception ", e);
throw new CloudRuntimeException("Unable to query host network info due to exception");
}
}
private List <String> getHostsInCluster(String clusterName)
{
List<String> hypervHosts = new ArrayList<String>();
try {
//StringBuilder cmd = new StringBuilder("cmd /c powershell.exe -OutputFormat XML ");
StringBuilder cmd = new StringBuilder("cmd /c powershell.exe ");
cmd.append("-Command Add-PSSnapin Microsoft.SystemCenter.VirtualMachineManager; ");
cmd.append("Get-VMMServer -ComputerName localhost; ");
cmd.append("Get-VMHostCluster ");
cmd.append(clusterName.toCharArray());
Process p = Runtime.getRuntime().exec(cmd.toString());
p.getOutputStream().close();
InputStreamReader temperrReader = new InputStreamReader(new BufferedInputStream(p.getErrorStream()));
BufferedReader errreader = new BufferedReader(temperrReader);
if (errreader.ready()) {
String errorOutput = new String("");
s_logger.info("errors found while running cmdlet Get-VMHostCluster");
while (true){
String errline = errreader.readLine();
if (errline == null) {
break;
}
errorOutput = errorOutput + errline;
}
s_logger.info(errorOutput);
} else {
s_logger.info("No errors found in running cmdlet:" + cmd);
}
p.getErrorStream().close();
/*
InputStream in = (InputStream) p.getInputStream();
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader parser = factory.createXMLStreamReader(in);
while(parser.hasNext()) {
int eventType = parser.next();
switch (eventType) {
case START_ELEMENT:
// Do something
break;
case END_ELEMENT:
// Do something
break;
// And so on ...
}
}
parser.close();
*/
InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(p.getInputStream()));
BufferedReader reader = new BufferedReader(tempReader);
String output = new String("");
while (true){
String line = reader.readLine();
if (line == null) {
break;
}
output = output + line;
}
String nodesListStr = output.substring(output.indexOf("Nodes"));
nodesListStr = nodesListStr.substring(nodesListStr.indexOf('{', 0)+1, nodesListStr.indexOf('}', 0));
String[] nodesList = nodesListStr.split(",");
for (String node : nodesList) {
hypervHosts.add(node);
}
p.getInputStream().close();
} catch (Exception e)
{
s_logger.info("Exception caught: "+e.getMessage());
}
return hypervHosts;
}
protected HashMap<String, State> sync() {
HashMap<String, State> changes = new HashMap<String, State>();
try {
synchronized (_vms) {
}
} catch (Throwable e) {
s_logger.error("Unable to perform sync information collection process at this point due to exception ", e);
return null;
}
return changes;
}
@Override
public PingCommand getCurrentStatus(long id) {
HashMap<String, State> newStates = sync();
if (newStates == null) {
newStates = new HashMap<String, State>();
}
PingRoutingCommand cmd = new PingRoutingCommand(com.cloud.host.Host.Type.Routing, id, newStates);
return cmd;
}
@Override
public boolean configure(String name, Map<String, Object> params)
throws ConfigurationException {
_dcId = params.get("zone").toString();
_podId= params.get("pod").toString();
_clusterId = params.get("cluster").toString();
_guid = params.get("guid").toString();
boolean success = super.configure(name, params);
if (! success) {
return false;
}
return true;
}
@Override
protected String getDefaultScriptsDir() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -0,0 +1,989 @@
/**
* * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.network.resource;
import iControl.CommonEnabledState;
import iControl.CommonIPPortDefinition;
import iControl.CommonStatistic;
import iControl.CommonStatisticType;
import iControl.CommonVirtualServerDefinition;
import iControl.Interfaces;
import iControl.LocalLBLBMethod;
import iControl.LocalLBNodeAddressBindingStub;
import iControl.LocalLBPoolBindingStub;
import iControl.LocalLBProfileContextType;
import iControl.LocalLBVirtualServerBindingStub;
import iControl.LocalLBVirtualServerVirtualServerPersistence;
import iControl.LocalLBVirtualServerVirtualServerProfile;
import iControl.LocalLBVirtualServerVirtualServerResource;
import iControl.LocalLBVirtualServerVirtualServerStatisticEntry;
import iControl.LocalLBVirtualServerVirtualServerStatistics;
import iControl.LocalLBVirtualServerVirtualServerType;
import iControl.NetworkingMemberTagType;
import iControl.NetworkingMemberType;
import iControl.NetworkingRouteDomainBindingStub;
import iControl.NetworkingSelfIPBindingStub;
import iControl.NetworkingVLANBindingStub;
import iControl.NetworkingVLANMemberEntry;
import iControl.SystemConfigSyncBindingStub;
import iControl.SystemConfigSyncSaveMode;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.agent.IAgentControl;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer;
import com.cloud.agent.api.ExternalNetworkResourceUsageCommand;
import com.cloud.agent.api.MaintainAnswer;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.ReadyAnswer;
import com.cloud.agent.api.ReadyCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupExternalLoadBalancerCommand;
import com.cloud.agent.api.routing.IpAssocCommand;
import com.cloud.agent.api.routing.IpAssocAnswer;
import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
import com.cloud.agent.api.routing.NetworkElementCommand;
import com.cloud.agent.api.to.IpAddressTO;
import com.cloud.agent.api.to.LoadBalancerTO;
import com.cloud.agent.api.to.LoadBalancerTO.DestinationTO;
import com.cloud.host.Host;
import com.cloud.resource.ServerResource;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.exception.ExecutionException;
import com.cloud.utils.net.NetUtils;
public class F5BigIpResource implements ServerResource {
private enum LbAlgorithm {
RoundRobin(null, LocalLBLBMethod.LB_METHOD_ROUND_ROBIN),
LeastConn(null, LocalLBLBMethod.LB_METHOD_LEAST_CONNECTION_MEMBER);
String persistenceProfileName;
LocalLBLBMethod method;
LbAlgorithm(String persistenceProfileName, LocalLBLBMethod method) {
this.persistenceProfileName = persistenceProfileName;
this.method = method;
}
public String getPersistenceProfileName() {
return persistenceProfileName;
}
public LocalLBLBMethod getMethod() {
return method;
}
}
private enum LbProtocol {
tcp,
udp;
}
private String _name;
private String _zoneId;
private String _ip;
private String _username;
private String _password;
private String _publicInterface;
private String _privateInterface;
private Integer _numRetries;
private String _guid;
private boolean _inline;
private Interfaces _interfaces;
private LocalLBVirtualServerBindingStub _virtualServerApi;
private LocalLBPoolBindingStub _loadbalancerApi;
private LocalLBNodeAddressBindingStub _nodeApi;
private NetworkingVLANBindingStub _vlanApi;
private NetworkingSelfIPBindingStub _selfIpApi;
private NetworkingRouteDomainBindingStub _routeDomainApi;
private SystemConfigSyncBindingStub _configSyncApi;
private String _objectNamePathSep = "-";
private String _routeDomainIdentifier = "%";
private static final Logger s_logger = Logger.getLogger(F5BigIpResource.class);
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
try {
XTrustProvider.install();
_name = (String) params.get("name");
if (_name == null) {
throw new ConfigurationException("Unable to find name");
}
_zoneId = (String) params.get("zoneId");
if (_zoneId == null) {
throw new ConfigurationException("Unable to find zone");
}
_ip = (String) params.get("ip");
if (_ip == null) {
throw new ConfigurationException("Unable to find IP");
}
_username = (String) params.get("username");
if (_username == null) {
throw new ConfigurationException("Unable to find username");
}
_password = (String) params.get("password");
if (_password == null) {
throw new ConfigurationException("Unable to find password");
}
_publicInterface = (String) params.get("publicInterface");
if (_publicInterface == null) {
throw new ConfigurationException("Unable to find public interface");
}
_privateInterface = (String) params.get("privateInterface");
if (_privateInterface == null) {
throw new ConfigurationException("Unable to find private interface");
}
_numRetries = NumbersUtil.parseInt((String) params.get("numRetries"), 1);
_guid = (String)params.get("guid");
if (_guid == null) {
throw new ConfigurationException("Unable to find the guid");
}
_inline = Boolean.parseBoolean((String) params.get("inline"));
if (!login()) {
throw new ExecutionException("Failed to login to the F5 BigIp.");
}
return true;
} catch (Exception e) {
throw new ConfigurationException(e.getMessage());
}
}
@Override
public StartupCommand[] initialize() {
StartupExternalLoadBalancerCommand cmd = new StartupExternalLoadBalancerCommand();
cmd.setName(_name);
cmd.setDataCenter(_zoneId);
cmd.setPod("");
cmd.setPrivateIpAddress(_ip);
cmd.setStorageIpAddress("");
cmd.setVersion("");
cmd.setGuid(_guid);
return new StartupCommand[]{cmd};
}
@Override
public Host.Type getType() {
return Host.Type.ExternalLoadBalancer;
}
@Override
public String getName() {
return _name;
}
@Override
public PingCommand getCurrentStatus(final long id) {
return new PingCommand(Host.Type.ExternalLoadBalancer, id);
}
@Override
public boolean start() {
return true;
}
@Override
public boolean stop() {
return true;
}
@Override
public void disconnected() {
return;
}
@Override
public IAgentControl getAgentControl() {
return null;
}
@Override
public void setAgentControl(IAgentControl agentControl) {
return;
}
@Override
public Answer executeRequest(Command cmd) {
return executeRequest(cmd, _numRetries);
}
private Answer executeRequest(Command cmd, int numRetries) {
if (cmd instanceof ReadyCommand) {
return execute((ReadyCommand) cmd);
} else if (cmd instanceof MaintainCommand) {
return execute((MaintainCommand) cmd);
} else if (cmd instanceof IpAssocCommand) {
return execute((IpAssocCommand) cmd, numRetries);
} else if (cmd instanceof LoadBalancerConfigCommand) {
return execute((LoadBalancerConfigCommand) cmd, numRetries);
} else if (cmd instanceof ExternalNetworkResourceUsageCommand) {
return execute((ExternalNetworkResourceUsageCommand) cmd);
} else {
return Answer.createUnsupportedCommandAnswer(cmd);
}
}
private Answer retry(Command cmd, int numRetries) {
int numRetriesRemaining = numRetries - 1;
s_logger.error("Retrying " + cmd.getClass().getSimpleName() + ". Number of retries remaining: " + numRetriesRemaining);
return executeRequest(cmd, numRetriesRemaining);
}
private boolean shouldRetry(int numRetries) {
return (numRetries > 0 && login());
}
private Answer execute(ReadyCommand cmd) {
return new ReadyAnswer(cmd);
}
private Answer execute(MaintainCommand cmd) {
return new MaintainAnswer(cmd);
}
private synchronized Answer execute(IpAssocCommand cmd, int numRetries) {
String[] results = new String[cmd.getIpAddresses().length];
int i = 0;
try {
IpAddressTO[] ips = cmd.getIpAddresses();
for (IpAddressTO ip : ips) {
long guestVlanTag = Long.valueOf(ip.getVlanId());
String vlanSelfIp = _inline ? tagAddressWithRouteDomain(ip.getVlanGateway(), guestVlanTag) : ip.getVlanGateway();
String vlanNetmask = ip.getVlanNetmask();
// Delete any existing guest VLAN with this tag, self IP, and netmask
deleteGuestVlan(guestVlanTag, vlanSelfIp, vlanNetmask);
if (ip.isAdd()) {
// Add a new guest VLAN
addGuestVlan(guestVlanTag, vlanSelfIp, vlanNetmask);
}
saveConfiguration();
results[i++] = ip.getPublicIp() + " - success";
}
} catch (ExecutionException e) {
s_logger.error("Failed to execute IPAssocCommand due to " + e);
if (shouldRetry(numRetries)) {
return retry(cmd, numRetries);
} else {
results[i++] = IpAssocAnswer.errorResult;
}
}
return new IpAssocAnswer(cmd, results);
}
private synchronized Answer execute(LoadBalancerConfigCommand cmd, int numRetries) {
try {
long guestVlanTag = Long.parseLong(cmd.getAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG));
LoadBalancerTO[] loadBalancers = cmd.getLoadBalancers();
for (LoadBalancerTO loadBalancer : loadBalancers) {
LbProtocol lbProtocol;
try {
if (loadBalancer.getProtocol() == null) {
lbProtocol = LbProtocol.tcp;
} else {
lbProtocol = LbProtocol.valueOf(loadBalancer.getProtocol());
}
} catch (IllegalArgumentException e) {
throw new ExecutionException("Got invalid protocol: " + loadBalancer.getProtocol());
}
LbAlgorithm lbAlgorithm;
if (loadBalancer.getAlgorithm().equals("roundrobin")) {
lbAlgorithm = LbAlgorithm.RoundRobin;
} else if (loadBalancer.getAlgorithm().equals("leastconn")) {
lbAlgorithm = LbAlgorithm.LeastConn;
} else {
throw new ExecutionException("Got invalid algorithm: " + loadBalancer.getAlgorithm());
}
String srcIp = _inline ? tagAddressWithRouteDomain(loadBalancer.getSrcIp(), guestVlanTag) : loadBalancer.getSrcIp();
int srcPort = loadBalancer.getSrcPort();
String virtualServerName = genVirtualServerName(lbProtocol, srcIp, srcPort);
boolean destinationsToAdd = false;
for (DestinationTO destination : loadBalancer.getDestinations()) {
if (!destination.isRevoked()) {
destinationsToAdd = true;
break;
}
}
if (!loadBalancer.isRevoked() && destinationsToAdd) {
// Add the pool
addPool(virtualServerName, lbAlgorithm);
// Add pool members
List<String> activePoolMembers = new ArrayList<String>();
for (DestinationTO destination : loadBalancer.getDestinations()) {
if (!destination.isRevoked()) {
String destIp = _inline ? tagAddressWithRouteDomain(destination.getDestIp(), guestVlanTag) : destination.getDestIp();
addPoolMember(virtualServerName, destIp, destination.getDestPort());
activePoolMembers.add(destIp + "-" + destination.getDestPort());
}
}
// Delete any pool members that aren't in the current list of destinations
deleteInactivePoolMembers(virtualServerName, activePoolMembers);
// Add the virtual server
addVirtualServer(virtualServerName, lbProtocol, srcIp, srcPort);
} else {
// Delete the virtual server with this protocol, source IP, and source port, along with its default pool and all pool members
deleteVirtualServerAndDefaultPool(virtualServerName);
}
}
saveConfiguration();
return new Answer(cmd);
} catch (ExecutionException e) {
s_logger.error("Failed to execute LoadBalancerConfigCommand due to " + e);
if (shouldRetry(numRetries)) {
return retry(cmd, numRetries);
} else {
return new Answer(cmd, e);
}
}
}
private synchronized ExternalNetworkResourceUsageAnswer execute(ExternalNetworkResourceUsageCommand cmd) {
try {
return getIpBytesSentAndReceived(cmd);
} catch (ExecutionException e) {
return new ExternalNetworkResourceUsageAnswer(cmd, e);
}
}
private void saveConfiguration() throws ExecutionException {
try {
_configSyncApi.save_configuration("", SystemConfigSyncSaveMode.SAVE_BASE_LEVEL_CONFIG);
_configSyncApi.save_configuration("", SystemConfigSyncSaveMode.SAVE_HIGH_LEVEL_CONFIG);
s_logger.debug("Successfully saved F5 BigIp configuration.");
} catch (RemoteException e) {
s_logger.error("Failed to save F5 BigIp configuration due to: " + e);
throw new ExecutionException(e.getMessage());
}
}
private void addGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask) throws ExecutionException {
try {
String vlanName = genVlanName(vlanTag);
List<String> allVlans = getVlans();
if (!allVlans.contains(vlanName)) {
String[] vlanNames = genStringArray(vlanName);
long[] vlanTags = genLongArray(vlanTag);
CommonEnabledState[] commonEnabledState = {CommonEnabledState.STATE_DISABLED};
// Create the interface name
NetworkingVLANMemberEntry[][] vlanMemberEntries = {{new NetworkingVLANMemberEntry()}};
vlanMemberEntries[0][0].setMember_type(NetworkingMemberType.MEMBER_INTERFACE);
vlanMemberEntries[0][0].setTag_state(NetworkingMemberTagType.MEMBER_TAGGED);
vlanMemberEntries[0][0].setMember_name(_privateInterface);
s_logger.debug("Creating a guest VLAN with tag " + vlanTag);
_vlanApi.create(vlanNames, vlanTags, vlanMemberEntries, commonEnabledState, new long[]{10L}, new String[]{"00:00:00:00:00:00"});
if (!getVlans().contains(vlanName)) {
throw new ExecutionException("Failed to create vlan with tag " + vlanTag);
}
}
if (_inline) {
List<Long> allRouteDomains = getRouteDomains();
if (!allRouteDomains.contains(vlanTag)) {
long[] routeDomainIds = genLongArray(vlanTag);
String[][] vlanNames = new String[][]{genStringArray(genVlanName(vlanTag))};
s_logger.debug("Creating route domain " + vlanTag);
_routeDomainApi.create(routeDomainIds, vlanNames);
if (!getRouteDomains().contains(vlanTag)) {
throw new ExecutionException("Failed to create route domain " + vlanTag);
}
}
}
List<String> allSelfIps = getSelfIps();
if (!allSelfIps.contains(vlanSelfIp)) {
String[] selfIpsToCreate = genStringArray(vlanSelfIp);
String[] vlans = genStringArray(vlanName);
String[] netmasks = genStringArray(vlanNetmask);
long[] unitIds = genLongArray(0L);
CommonEnabledState[] enabledStates = new CommonEnabledState[]{CommonEnabledState.STATE_DISABLED};
s_logger.debug("Creating self IP " + vlanSelfIp);
_selfIpApi.create(selfIpsToCreate, vlans, netmasks, unitIds, enabledStates);
if (!getSelfIps().contains(vlanSelfIp)) {
throw new ExecutionException("Failed to create self IP " + vlanSelfIp);
}
}
} catch (RemoteException e) {
s_logger.error(e);
throw new ExecutionException(e.getMessage());
}
}
private void deleteGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask) throws ExecutionException {
try {
// Delete all virtual servers and pools that use this guest VLAN
deleteVirtualServersInGuestVlan(vlanSelfIp, vlanNetmask);
List<String> allSelfIps = getSelfIps();
if (allSelfIps.contains(vlanSelfIp)) {
s_logger.debug("Deleting self IP " + vlanSelfIp);
_selfIpApi.delete_self_ip(genStringArray(vlanSelfIp));
if (getSelfIps().contains(vlanSelfIp)) {
throw new ExecutionException("Failed to delete self IP " + vlanSelfIp);
}
}
if (_inline) {
List<Long> allRouteDomains = getRouteDomains();
if (allRouteDomains.contains(vlanTag)) {
s_logger.debug("Deleting route domain " + vlanTag);
_routeDomainApi.delete_route_domain(genLongArray(vlanTag));
if (getRouteDomains().contains(vlanTag)) {
throw new ExecutionException("Failed to delete route domain " + vlanTag);
}
}
}
String vlanName = genVlanName(vlanTag);
List<String> allVlans = getVlans();
if (allVlans.contains(vlanName)) {
_vlanApi.delete_vlan(genStringArray(vlanName));
if (getVlans().contains(vlanName)) {
throw new ExecutionException("Failed to delete VLAN with tag: " + vlanTag);
}
}
} catch (RemoteException e) {
throw new ExecutionException(e.getMessage());
}
}
private void deleteVirtualServersInGuestVlan(String vlanSelfIp, String vlanNetmask) throws ExecutionException {
vlanSelfIp = stripRouteDomainFromAddress(vlanSelfIp);
List<String> virtualServersToDelete = new ArrayList<String>();
List<String> allVirtualServers = getVirtualServers();
for (String virtualServerName : allVirtualServers) {
// Check if the virtual server's default pool has members in this guest VLAN
List<String> poolMembers = getMembers(virtualServerName);
for (String poolMemberName : poolMembers) {
String poolMemberIp = stripRouteDomainFromAddress(getIpAndPort(poolMemberName)[0]);
if (NetUtils.sameSubnet(vlanSelfIp, poolMemberIp, vlanNetmask)) {
virtualServersToDelete.add(virtualServerName);
break;
}
}
}
for (String virtualServerName : virtualServersToDelete) {
s_logger.debug("Found a virtual server (" + virtualServerName + ") for guest network with self IP " + vlanSelfIp + " that is active when the guest network is being destroyed.");
deleteVirtualServerAndDefaultPool(virtualServerName);
}
}
private String genVlanName(long vlanTag) {
return "vlan-" + String.valueOf(vlanTag);
}
private List<Long> getRouteDomains() throws ExecutionException {
try {
List<Long> routeDomains = new ArrayList<Long>();
long[] routeDomainsArray = _routeDomainApi.get_list();
for (long routeDomainName : routeDomainsArray) {
routeDomains.add(routeDomainName);
}
return routeDomains;
} catch (RemoteException e) {
throw new ExecutionException(e.getMessage());
}
}
private List<String> getSelfIps() throws ExecutionException {
try {
List<String> selfIps = new ArrayList<String>();
String[] selfIpsArray = _selfIpApi.get_list();
for (String selfIp : selfIpsArray) {
selfIps.add(selfIp);
}
return selfIps;
} catch (RemoteException e) {
throw new ExecutionException(e.getMessage());
}
}
private List<String> getVlans() throws ExecutionException {
try {
List<String> vlans = new ArrayList<String>();
String[] vlansArray = _vlanApi.get_list();
for (String vlan : vlansArray) {
vlans.add(vlan);
}
return vlans;
} catch (RemoteException e) {
throw new ExecutionException(e.getMessage());
}
}
// Login
private boolean login() {
try {
_interfaces = new Interfaces();
if (!_interfaces.initialize(_ip, _username, _password)) {
throw new ExecutionException("Failed to log in to BigIp appliance");
}
_virtualServerApi = _interfaces.getLocalLBVirtualServer();
_loadbalancerApi = _interfaces.getLocalLBPool();
_nodeApi = _interfaces.getLocalLBNodeAddress();
_vlanApi = _interfaces.getNetworkingVLAN();
_selfIpApi = _interfaces.getNetworkingSelfIP();
_routeDomainApi = _interfaces.getNetworkingRouteDomain();
_configSyncApi = _interfaces.getSystemConfigSync();
return true;
} catch (Exception e) {
return false;
}
}
// Virtual server methods
private void addVirtualServer(String virtualServerName, LbProtocol protocol, String srcIp, int srcPort) throws ExecutionException {
try {
if (!virtualServerExists(virtualServerName)) {
s_logger.debug("Adding virtual server " + virtualServerName);
_virtualServerApi.create(genVirtualServerDefinition(virtualServerName, protocol, srcIp, srcPort), new String[]{"255.255.255.255"}, genVirtualServerResource(virtualServerName), genVirtualServerProfile(protocol));
_virtualServerApi.set_snat_automap(genStringArray(virtualServerName));
if (!virtualServerExists(virtualServerName)) {
throw new ExecutionException("Failed to add virtual server " + virtualServerName);
}
}
} catch (RemoteException e) {
throw new ExecutionException(e.getMessage());
}
}
private void deleteVirtualServerAndDefaultPool(String virtualServerName) throws ExecutionException {
try {
if (virtualServerExists(virtualServerName)) {
// Delete the default pool's members
List<String> poolMembers = getMembers(virtualServerName);
for (String poolMember : poolMembers) {
String[] destIpAndPort = getIpAndPort(poolMember);
deletePoolMember(virtualServerName, destIpAndPort[0], Integer.valueOf(destIpAndPort[1]));
}
// Delete the virtual server
s_logger.debug("Deleting virtual server " + virtualServerName);
_virtualServerApi.delete_virtual_server(genStringArray(virtualServerName));
if (getVirtualServers().contains(virtualServerName)) {
throw new ExecutionException("Failed to delete virtual server " + virtualServerName);
}
// Delete the default pool
deletePool(virtualServerName);
}
} catch (RemoteException e) {
throw new ExecutionException(e.getMessage());
}
}
private String genVirtualServerName(LbProtocol protocol, String srcIp, long srcPort) {
srcIp = stripRouteDomainFromAddress(srcIp);
return genObjectName("vs", protocol, srcIp, srcPort);
}
private boolean virtualServerExists(String virtualServerName) throws ExecutionException {
return getVirtualServers().contains(virtualServerName);
}
private List<String> getVirtualServers() throws ExecutionException {
try {
List<String> virtualServers = new ArrayList<String>();
String[] virtualServersArray = _virtualServerApi.get_list();
for (String virtualServer : virtualServersArray) {
virtualServers.add(virtualServer);
}
return virtualServers;
} catch (RemoteException e) {
throw new ExecutionException(e.getMessage());
}
}
private iControl.CommonVirtualServerDefinition[] genVirtualServerDefinition(String name, LbProtocol protocol, String srcIp, long srcPort) {
CommonVirtualServerDefinition vsDefs[] = {new CommonVirtualServerDefinition()};
vsDefs[0].setName(name);
vsDefs[0].setAddress(srcIp);
vsDefs[0].setPort(srcPort);
if (protocol.equals(LbProtocol.tcp)) {
vsDefs[0].setProtocol(iControl.CommonProtocolType.PROTOCOL_TCP);
} else if (protocol.equals(LbProtocol.udp)) {
vsDefs[0].setProtocol(iControl.CommonProtocolType.PROTOCOL_UDP);
}
return vsDefs;
}
private iControl.LocalLBVirtualServerVirtualServerResource[] genVirtualServerResource(String poolName) {
LocalLBVirtualServerVirtualServerResource vsRes[] = {new LocalLBVirtualServerVirtualServerResource()};
vsRes[0].setType(LocalLBVirtualServerVirtualServerType.RESOURCE_TYPE_POOL);
vsRes[0].setDefault_pool_name(poolName);
return vsRes;
}
private LocalLBVirtualServerVirtualServerProfile[][] genVirtualServerProfile(LbProtocol protocol) {
LocalLBVirtualServerVirtualServerProfile vsProfs[][] = {{new LocalLBVirtualServerVirtualServerProfile()}};
vsProfs[0][0].setProfile_context(LocalLBProfileContextType.PROFILE_CONTEXT_TYPE_ALL);
if (protocol.equals(LbProtocol.tcp)) {
vsProfs[0][0].setProfile_name("http");
} else if (protocol.equals(LbProtocol.udp)) {
vsProfs[0][0].setProfile_name("udp");
}
return vsProfs;
}
private LocalLBVirtualServerVirtualServerPersistence[][] genPersistenceProfile(String persistenceProfileName) {
LocalLBVirtualServerVirtualServerPersistence[][] persistenceProfs = {{new LocalLBVirtualServerVirtualServerPersistence()}};
persistenceProfs[0][0].setDefault_profile(true);
persistenceProfs[0][0].setProfile_name(persistenceProfileName);
return persistenceProfs;
}
// Load balancing pool methods
private void addPool(String virtualServerName, LbAlgorithm algorithm) throws ExecutionException {
try {
if (!poolExists(virtualServerName)) {
if (algorithm.getPersistenceProfileName() != null) {
algorithm = LbAlgorithm.RoundRobin;
}
s_logger.debug("Adding pool for virtual server " + virtualServerName + " with algorithm " + algorithm);
_loadbalancerApi.create(genStringArray(virtualServerName), genLbMethod(algorithm), genEmptyMembersArray());
if (!poolExists(virtualServerName)) {
throw new ExecutionException("Failed to create new pool for virtual server " + virtualServerName);
}
}
} catch (RemoteException e) {
throw new ExecutionException(e.getMessage());
}
}
private void deletePool(String virtualServerName) throws ExecutionException {
try {
if (poolExists(virtualServerName) && getMembers(virtualServerName).size() == 0) {
s_logger.debug("Deleting pool for virtual server " + virtualServerName);
_loadbalancerApi.delete_pool(genStringArray(virtualServerName));
if (poolExists(virtualServerName)) {
throw new ExecutionException("Failed to delete pool for virtual server " + virtualServerName);
}
}
} catch (RemoteException e) {
throw new ExecutionException(e.getMessage());
}
}
private void addPoolMember(String virtualServerName, String destIp, int destPort) throws ExecutionException {
try {
String memberIdentifier = destIp + "-" + destPort;
if (poolExists(virtualServerName) && !memberExists(virtualServerName, memberIdentifier)) {
s_logger.debug("Adding member " + memberIdentifier + " into pool for virtual server " + virtualServerName);
_loadbalancerApi.add_member(genStringArray(virtualServerName), genMembers(destIp, destPort));
if (!memberExists(virtualServerName, memberIdentifier)) {
throw new ExecutionException("Failed to add new member " + memberIdentifier + " into pool for virtual server " + virtualServerName);
}
}
} catch (RemoteException e) {
throw new ExecutionException(e.getMessage());
}
}
private void deleteInactivePoolMembers(String virtualServerName, List<String> activePoolMembers) throws ExecutionException {
List<String> allPoolMembers = getMembers(virtualServerName);
for (String member : allPoolMembers) {
if (!activePoolMembers.contains(member)) {
String[] ipAndPort = member.split("-");
deletePoolMember(virtualServerName, ipAndPort[0], Integer.valueOf(ipAndPort[1]));
}
}
}
private void deletePoolMember(String virtualServerName, String destIp, int destPort) throws ExecutionException {
try {
String memberIdentifier = destIp + "-" + destPort;
List<String> lbPools = getAllLbPools();
if (lbPools.contains(virtualServerName) && memberExists(virtualServerName, memberIdentifier)) {
s_logger.debug("Deleting member " + memberIdentifier + " from pool for virtual server " + virtualServerName);
_loadbalancerApi.remove_member(genStringArray(virtualServerName), genMembers(destIp, destPort));
if (memberExists(virtualServerName, memberIdentifier)) {
throw new ExecutionException("Failed to delete member " + memberIdentifier + " from pool for virtual server " + virtualServerName);
}
if (nodeExists(destIp)) {
boolean nodeNeeded = false;
done:
for (String poolToCheck : lbPools) {
for (String memberInPool : getMembers(poolToCheck)) {
if (getIpAndPort(memberInPool)[0].equals(destIp)) {
nodeNeeded = true;
break done;
}
}
}
if (!nodeNeeded) {
s_logger.debug("Deleting node " + destIp);
_nodeApi.delete_node_address(genStringArray(destIp));
if (nodeExists(destIp)) {
throw new ExecutionException("Failed to delete node " + destIp);
}
}
}
}
} catch (RemoteException e) {
throw new ExecutionException(e.getMessage());
}
}
private boolean poolExists(String poolName) throws ExecutionException {
return getAllLbPools().contains(poolName);
}
private boolean memberExists(String poolName, String memberIdentifier) throws ExecutionException {
return getMembers(poolName).contains(memberIdentifier);
}
private boolean nodeExists(String destIp) throws RemoteException {
return getNodes().contains(destIp);
}
private String[] getIpAndPort(String memberIdentifier) {
return memberIdentifier.split("-");
}
public List<String> getAllLbPools() throws ExecutionException {
try {
List<String> lbPools = new ArrayList<String>();
String[] pools = _loadbalancerApi.get_list();
for (String pool : pools) {
lbPools.add(pool);
}
return lbPools;
} catch (RemoteException e) {
throw new ExecutionException(e.getMessage());
}
}
private List<String> getMembers(String virtualServerName) throws ExecutionException {
try {
List<String> members = new ArrayList<String>();
String[] virtualServerNames = genStringArray(virtualServerName);
CommonIPPortDefinition[] membersArray = _loadbalancerApi.get_member(virtualServerNames)[0];
for (CommonIPPortDefinition member : membersArray) {
members.add(member.getAddress() + "-" + member.getPort());
}
return members;
} catch (RemoteException e) {
throw new ExecutionException(e.getMessage());
}
}
private List<String> getNodes() throws RemoteException {
List<String> nodes = new ArrayList<String>();
String[] nodesArray = _nodeApi.get_list();
for (String node : nodesArray) {
nodes.add(node);
}
return nodes;
}
private iControl.CommonIPPortDefinition[][] genMembers(String destIp, long destPort) {
iControl.CommonIPPortDefinition[] membersInnerArray = new iControl.CommonIPPortDefinition[1];
membersInnerArray[0] = new iControl.CommonIPPortDefinition(destIp, destPort);
return new iControl.CommonIPPortDefinition[][]{membersInnerArray};
}
private iControl.CommonIPPortDefinition[][] genEmptyMembersArray() {
iControl.CommonIPPortDefinition[] membersInnerArray = new iControl.CommonIPPortDefinition[0];
return new iControl.CommonIPPortDefinition[][]{membersInnerArray};
}
private LocalLBLBMethod[] genLbMethod(LbAlgorithm algorithm) {
if (algorithm.getMethod() != null) {
return new LocalLBLBMethod[]{algorithm.getMethod()};
} else {
return new LocalLBLBMethod[]{LbAlgorithm.RoundRobin.getMethod()};
}
}
// Stats methods
private ExternalNetworkResourceUsageAnswer getIpBytesSentAndReceived(ExternalNetworkResourceUsageCommand cmd) throws ExecutionException {
ExternalNetworkResourceUsageAnswer answer = new ExternalNetworkResourceUsageAnswer(cmd);
try {
LocalLBVirtualServerVirtualServerStatistics stats = _virtualServerApi.get_all_statistics();
for (LocalLBVirtualServerVirtualServerStatisticEntry entry : stats.getStatistics()) {
String virtualServerIp = entry.getVirtual_server().getAddress();
if (_inline) {
virtualServerIp = stripRouteDomainFromAddress(virtualServerIp);
}
long[] bytesSentAndReceived = answer.ipBytes.get(virtualServerIp);
if (bytesSentAndReceived == null) {
bytesSentAndReceived = new long[]{0, 0};
}
for (CommonStatistic stat : entry.getStatistics()) {
if (stat.getType().equals(CommonStatisticType.STATISTIC_CLIENT_SIDE_BYTES_OUT)) {
// Add to the outgoing bytes
bytesSentAndReceived[0] += stat.getValue().getLow();
} else if (stat.getType().equals(CommonStatisticType.STATISTIC_CLIENT_SIDE_BYTES_IN)) {
// Add to the incoming bytes
bytesSentAndReceived[1] += stat.getValue().getLow();
}
}
if (bytesSentAndReceived[0] >= 0 && bytesSentAndReceived[1] >= 0) {
answer.ipBytes.put(virtualServerIp, bytesSentAndReceived);
}
}
} catch (Exception e) {
s_logger.error(e);
throw new ExecutionException(e.getMessage());
}
return answer;
}
// Misc methods
private String tagAddressWithRouteDomain(String address, long vlanTag) {
return address + _routeDomainIdentifier + vlanTag;
}
private String stripRouteDomainFromAddress(String address) {
int i = address.indexOf(_routeDomainIdentifier);
if (i > 0) {
address = address.substring(0, i);
}
return address;
}
private String genObjectName(Object... args) {
String objectName = "";
for (int i = 0; i < args.length; i++) {
objectName += args[i];
if (i != args.length -1) {
objectName += _objectNamePathSep;
}
}
return objectName;
}
private long[] genLongArray(long l) {
return new long[]{l};
}
private static String[] genStringArray(String s) {
return new String[]{s};
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,294 @@
/**
* * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
*
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.network.resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.agent.IAgentControl;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.DirectNetworkUsageAnswer;
import com.cloud.agent.api.DirectNetworkUsageCommand;
import com.cloud.agent.api.MaintainAnswer;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.ReadyAnswer;
import com.cloud.agent.api.ReadyCommand;
import com.cloud.agent.api.RecurringNetworkUsageAnswer;
import com.cloud.agent.api.RecurringNetworkUsageCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupTrafficMonitorCommand;
import com.cloud.host.Host;
import com.cloud.resource.ServerResource;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.exception.ExecutionException;
public class TrafficSentinelResource implements ServerResource {
private String _name;
private String _zoneId;
private String _ip;
private String _guid;
private String _url;
private static Integer _numRetries;
private static Integer _timeoutInSeconds;
private static final Logger s_logger = Logger.getLogger(TrafficSentinelResource.class);
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
try {
_name = name;
_zoneId = (String) params.get("zone");
if (_zoneId == null) {
throw new ConfigurationException("Unable to find zone");
}
_ip = (String) params.get("ipaddress");
if (_ip == null) {
throw new ConfigurationException("Unable to find IP");
}
_guid = (String)params.get("guid");
if (_guid == null) {
throw new ConfigurationException("Unable to find the guid");
}
_url = (String)params.get("url");
if (_url == null) {
throw new ConfigurationException("Unable to find url");
}
_numRetries = NumbersUtil.parseInt((String) params.get("numRetries"), 1);
_timeoutInSeconds = NumbersUtil.parseInt((String) params.get("timeoutInSeconds"), 300);
return true;
} catch (Exception e) {
throw new ConfigurationException(e.getMessage());
}
}
@Override
public StartupCommand[] initialize() {
StartupTrafficMonitorCommand cmd = new StartupTrafficMonitorCommand();
cmd.setName(_name);
cmd.setDataCenter(_zoneId);
cmd.setPod("");
cmd.setPrivateIpAddress(_ip);
cmd.setStorageIpAddress("");
cmd.setVersion("");
cmd.setGuid(_guid);
return new StartupCommand[]{cmd};
}
@Override
public Host.Type getType() {
return Host.Type.TrafficMonitor;
}
@Override
public String getName() {
return _name;
}
@Override
public PingCommand getCurrentStatus(final long id) {
return new PingCommand(Host.Type.TrafficMonitor, id);
}
@Override
public boolean start() {
return true;
}
@Override
public boolean stop() {
return true;
}
@Override
public void disconnected() {
return;
}
@Override
public IAgentControl getAgentControl() {
return null;
}
@Override
public void setAgentControl(IAgentControl agentControl) {
return;
}
@Override
public Answer executeRequest(Command cmd) {
if (cmd instanceof ReadyCommand) {
return execute((ReadyCommand) cmd);
} else if (cmd instanceof MaintainCommand) {
return execute((MaintainCommand) cmd);
} else if (cmd instanceof DirectNetworkUsageCommand) {
return execute((DirectNetworkUsageCommand) cmd);
} else if (cmd instanceof RecurringNetworkUsageCommand) {
return execute((RecurringNetworkUsageCommand) cmd);
} else {
return Answer.createUnsupportedCommandAnswer(cmd);
}
}
private Answer execute(ReadyCommand cmd) {
return new ReadyAnswer(cmd);
}
private synchronized RecurringNetworkUsageAnswer execute(RecurringNetworkUsageCommand cmd) {
return new RecurringNetworkUsageAnswer(cmd);
}
private synchronized DirectNetworkUsageAnswer execute(DirectNetworkUsageCommand cmd) {
try {
return getPublicIpBytesSentAndReceived(cmd);
} catch (ExecutionException e) {
return new DirectNetworkUsageAnswer(cmd, e);
}
}
private Answer execute(MaintainCommand cmd) {
return new MaintainAnswer(cmd);
}
private DirectNetworkUsageAnswer getPublicIpBytesSentAndReceived(DirectNetworkUsageCommand cmd) throws ExecutionException {
DirectNetworkUsageAnswer answer = new DirectNetworkUsageAnswer(cmd);
try {
//Direct Network Usage
URL trafficSentinel;
try {
//Query traffic Sentinel
trafficSentinel = new URL(_url+"/inmsf/Query?script="+URLEncoder.encode(getScript(cmd.getPublicIps(), cmd.getStart(), cmd.getEnd()),"UTF-8")
+"&authenticate=basic&resultFormat=txt");
BufferedReader in = new BufferedReader(
new InputStreamReader(trafficSentinel.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null){
//Parse the script output
StringTokenizer st = new StringTokenizer(inputLine, ",");
if(st.countTokens() == 3){
String publicIp = st.nextToken();
Long bytesSent = new Long(st.nextToken());
Long bytesRcvd = new Long(st.nextToken());
if(bytesSent == null || bytesRcvd == null){
s_logger.debug("Incorrect bytes for IP: "+publicIp);
}
long[] bytesSentAndReceived = new long[2];
bytesSentAndReceived[0] = bytesSent;
bytesSentAndReceived[1] = bytesRcvd;
answer.put(publicIp, bytesSentAndReceived);
}
}
in.close();
} catch (MalformedURLException e1) {
s_logger.info("Invalid Traffic Sentinel URL",e1);
} catch (IOException e) {
s_logger.debug("Error in direct network usage accounting",e);
}
} catch (Exception e) {
s_logger.error(e);
throw new ExecutionException(e.getMessage());
}
return answer;
}
private String getScript(List<String> Ips, Date start, Date end){
String IpAddresses = "";
for(int i=0; i<Ips.size(); i++ ){
IpAddresses += Ips.get(i);
if(i != (Ips.size() - 1)){
// Append comma for all Ips except the last Ip
IpAddresses += ",";
}
}
String startDate = getDateString(start);
String endtDate = getDateString(end);
StringBuffer sb = new StringBuffer();
sb.append("var q = Query.topN(\"historytrmx\",");
sb.append(" \"ipsource,bytes\",");
sb.append(" \"ipsource = "+IpAddresses+" & destinationzone = EXTERNAL\",");
sb.append(" \""+startDate+", "+endtDate+"\",");
sb.append(" \"bytes\",");
sb.append(" 100000);");
sb.append("var totalsSent = {};");
sb.append("var t = q.run(");
sb.append(" function(row,table) {");
sb.append(" if(row[0]) { ");
sb.append(" totalsSent[row[0]] = row[1];");
sb.append(" }");
sb.append(" });");
sb.append("var q = Query.topN(\"historytrmx\",");
sb.append(" \"ipdestination,bytes\",");
sb.append(" \"ipdestination = "+IpAddresses+" & sourcezone = EXTERNAL\",");
sb.append(" \""+startDate+", "+endtDate+"\",");
sb.append(" \"bytes\",");
sb.append(" 100000);");
sb.append("var totalsRcvd = {};");
sb.append("var t = q.run(");
sb.append(" function(row,table) {");
sb.append(" if(row[0]) {");
sb.append(" totalsRcvd[row[0]] = row[1];");
sb.append(" }");
sb.append(" });");
sb.append("for (var addr in totalsSent) {");
sb.append(" var TS = 0;");
sb.append(" var TR = 0;");
sb.append(" if(totalsSent[addr]) TS = totalsSent[addr];");
sb.append(" if(totalsRcvd[addr]) TR = totalsRcvd[addr];");
sb.append(" println(addr + \",\" + TS + \",\" + TR);");
sb.append("}");
return sb.toString();
}
private String getDateString(Date date){
DateFormat dfDate = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
return dfDate.format(date);
}
}

View File

@ -0,0 +1,98 @@
/*
* The contents of this file are subject to the "END USER LICENSE AGREEMENT FOR F5
* Software Development Kit for iControl"; you may not use this file except in
* compliance with the License. The License is included in the iControl
* Software Development Kit.
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is iControl Code and related documentation
* distributed by F5.
*
* Portions created by F5 are Copyright (C) 1996-2004 F5 Networks
* Inc. All Rights Reserved. iControl (TM) is a registered trademark of
* F5 Networks, Inc.
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License (the "GPL"), in which case the
* provisions of GPL are applicable instead of those above. If you wish
* to allow use of your version of this file only under the terms of the
* GPL and not to allow others to use your version of this file under the
* License, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the GPL.
* If you do not delete the provisions above, a recipient may use your
* version of this file under either the License or the GPL.
*/
package com.cloud.network.resource;
import java.security.AccessController;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.PrivilegedAction;
import java.security.Security;
import java.security.cert.X509Certificate;
import javax.net.ssl.ManagerFactoryParameters;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactorySpi;
import javax.net.ssl.X509TrustManager;
public final class XTrustProvider extends java.security.Provider
{
private final static String NAME = "XTrustJSSE";
private final static String INFO =
"XTrust JSSE Provider (implements trust factory with truststore validation disabled)";
private final static double VERSION = 1.0D;
public XTrustProvider()
{
super(NAME, VERSION, INFO);
AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
put("TrustManagerFactory." + TrustManagerFactoryImpl.getAlgorithm(),
TrustManagerFactoryImpl.class.getName());
return null;
}
});
}
public static void install()
{
if(Security.getProvider(NAME) == null)
{
Security.insertProviderAt(new XTrustProvider(), 2);
Security.setProperty("ssl.TrustManagerFactory.algorithm",
TrustManagerFactoryImpl.getAlgorithm());
}
}
public final static class TrustManagerFactoryImpl extends TrustManagerFactorySpi
{
public TrustManagerFactoryImpl() { }
public static String getAlgorithm() { return "XTrust509"; }
protected void engineInit(KeyStore keystore) throws KeyStoreException { }
protected void engineInit(ManagerFactoryParameters mgrparams)
throws InvalidAlgorithmParameterException
{
throw new InvalidAlgorithmParameterException(
XTrustProvider.NAME + " does not use ManagerFactoryParameters");
}
protected TrustManager[] engineGetTrustManagers()
{
return new TrustManager[] { new X509TrustManager()
{
public X509Certificate[] getAcceptedIssuers() { return null; }
public void checkClientTrusted(X509Certificate[] certs, String authType) { }
public void checkServerTrusted(X509Certificate[] certs, String authType) { }
}};
}
}
}

View File

@ -0,0 +1,159 @@
import re
class ConfigFileOps:
class entry:
def __init__(self, name, value, op, separator):
self.name = name
self.value = value
self.state = "new"
self.op = op
self.separator = separator
def setState(self, state):
self.state = state
def getState(self):
return self.state
def __init__(self, fileName, cfg=None):
self.fileName = fileName
self.entries = []
self.backups = []
if cfg is not None:
cfg.cfoHandlers.append(self)
def addEntry(self, name, value, separator="="):
e = self.entry(name, value, "add", separator)
self.entries.append(e)
def rmEntry(self, name, value, separator="="):
entry = self.entry(name, value, "rm", separator)
self.entries.append(entry)
def getEntry(self, name, separator="="):
try:
ctx = file(self.fileName).read(-1)
match = re.search("^" + name + ".*", ctx, re.MULTILINE)
if match is None:
return ""
line = match.group(0).split(separator, 1)
return line[1]
except:
return ""
def save(self):
fp = open(self.fileName, "r")
newLines = []
for line in fp.readlines():
matched = False
for entry in self.entries:
if entry.op == "add":
if entry.separator == "=":
matchString = "^\ *" + entry.name + ".*"
elif entry.separator == " ":
matchString = "^\ *" + entry.name + "\ *" + entry.value
else:
if entry.separator == "=":
matchString = "^\ *" + entry.name + "\ *=\ *" + entry.value
else:
matchString = "^\ *" + entry.name + "\ *" + entry.value
match = re.match(matchString, line)
if match is not None:
if entry.op == "add" and entry.separator == "=":
newline = entry.name + "=" + entry.value + "\n"
entry.setState("set")
newLines.append(newline)
self.backups.append([line, newline])
matched = True
break
elif entry.op == "rm":
entry.setState("set")
self.backups.append([line, None])
matched = True
break
if not matched:
newLines.append(line)
for entry in self.entries:
if entry.getState() != "set":
if entry.op == "add":
newline = entry.name + entry.separator + entry.value + "\n"
newLines.append(newline)
self.backups.append([None, newline])
entry.setState("set")
fp.close()
file(self.fileName, "w").writelines(newLines)
def replace_line(self, startswith,stanza,always_add=False):
lines = [ s.strip() for s in file(self.fileName).readlines() ]
newlines = []
replaced = False
for line in lines:
if re.search(startswith, line):
if stanza is not None:
newlines.append(stanza)
self.backups.append([line, stanza])
replaced = True
else: newlines.append(line)
if not replaced and always_add:
newlines.append(stanza)
self.backups.append([None, stanza])
newlines = [ s + '\n' for s in newlines ]
file(self.fileName,"w").writelines(newlines)
def replace_or_add_line(self, startswith,stanza):
return self.replace_line(startswith,stanza,always_add=True)
def add_lines(self, lines, addToBackup=True):
fp = file(self.fileName).read(-1)
sh = re.escape(lines)
match = re.search(sh, fp, re.MULTILINE)
if match is not None:
return
fp += lines
file(self.fileName, "w").write(fp)
self.backups.append([None, lines])
def replace_lines(self, src, dst, addToBackup=True):
fp = file(self.fileName).read(-1)
sh = re.escape(src)
if dst is None:
dst = ""
repl,nums = re.subn(sh, dst, fp)
if nums <=0:
return
file(self.fileName, "w").write(repl)
if addToBackup:
self.backups.append([src, dst])
def append_lines(self, match_lines, append_lines):
fp = file(self.fileName).read(-1)
sh = re.escape(match_lines)
match = re.search(sh, fp, re.MULTILINE)
if match is None:
return
sh = re.escape(append_lines)
if re.search(sh, fp, re.MULTILINE) is not None:
return
newlines = []
for line in file(self.fileName).readlines():
if re.search(match_lines, line) is not None:
newlines.append(line + append_lines)
self.backups.append([line, line + append_lines])
else:
newlines.append(line)
file(self.fileName, "w").writelines(newlines)
def backup(self):
for oldLine, newLine in self.backups:
if newLine is None:
self.add_lines(oldLine, False)
else:
self.replace_lines(newLine, oldLine, False)

View File

@ -0,0 +1,114 @@
'''
Created on May 17, 2011
@author: frank
'''
try:
import json
except ImportError:
import simplejson as json
from OvmObjectModule import *
import types
import logging
import popen2
from OvmFaultConstants import toErrCode, dispatchErrCode, NoVmFoundException
from xmlrpclib import Fault as XmlRpcFault
from OVSCommons import *
from OvmLoggerModule import OvmLogger
from OVSXXenStore import xen_get_vm_path
HEARTBEAT_TIMESTAMP_FORMAT='<timestamp>%s</timestamp>'
HEARTBEAT_TIMESTAMP_PATTERN='(\<timestamp\>\d+.\d+<\/timestamp\>)'
HEARTBEAT_DIR='heart_beat'
ETC_HOSTS='/etc/hosts'
logger = OvmLogger('OvmCommon')
def setAttrFromDict(obj, name, refDict, convertFunc=None):
if not convertFunc:
setattr(obj, name, refDict[name])
else:
setattr(obj, name, convertFunc(refDict[name]))
def safeSetAttr(obj, name, value):
if not hasattr(obj, name): raise Exception("%s doesn't have attribute %s"%(obj.__class__.__name__, name))
setattr(obj, name, value)
def toAscii(jstr):
return str(jstr).encode('ascii', 'ignore')
def toAsciiHook(dct):
for k in dct:
v = dct[k]
if type(v) is types.UnicodeType:
v = toAscii(v)
del dct[k]
k = toAscii(k)
dct[k] = v
return dct
def asciiLoads(jStr):
jStr = str(jStr).replace("'", '"').replace('False', 'false').replace('True', 'true')
return json.loads(jStr, object_hook=toAsciiHook)
def exceptionIfNoSuccess(str, errMsg=None):
if not errMsg: errMsg = str
if not "success" in str: raise Exception("%s (%s)"%(errMsg, str))
def successToMap(str, sep=';'):
if not str.startswith("success"): raise Exception(str)
str = str[len('success:'):]
dct = {}
for pair in str.split(sep):
(key, value) = pair.split('=', 1)
dct[key] = value
return dct
def jsonSuccessToMap(str):
dct = json.loads(str)
if dct['status'] != 'SUCC': raise Exception(str)
return dct['value']
def safeDictSet(obj, dct, name):
if not hasattr(obj, name): raise Exception("%s has no attribute %s for encoding"%(obj.__class__.__name__, name))
dct[name] = getattr(obj, name)
def normalizeToGson(str):
return str.replace('\\', '').strip('"').replace('"{', '{').replace('}"', '}');
def toGson(obj):
return normalizeToGson(json.dumps(obj))
def MtoBytes(M):
return M * 1024 * 1024
def BytesToM(bytes):
return bytes/(1024*1024)
def BytesToG(bytes):
return bytes/(1024*1024*1024)
def doCmd(lst):
cmds = [str(i) for i in lst]
logger.debug(doCmd, ' '.join(cmds))
res = run_cmd(cmds)
logger.debug(doCmd, 'result:' + res)
return res
def execute(cmd):
p = popen2.Popen3(cmd, True)
if (p.wait() != 0):
raise Exception("Failed to execute command. Command: " + cmd + ", Error: " + p.childerr.read())
return p.fromchild.read()
def getDomId(vm_name):
return execute("xm list | grep " + vm_name + " | awk '{print $2}'").strip()
def raiseExceptionIfFail(res):
if not "success" in res and not "SUCC" in res: raise Exception(res)
def ipToHeartBeatFileName(ip):
return ip.replace('.', '_') + "_HEARTBEAT"

View File

@ -0,0 +1,50 @@
'''
Created on May 17, 2011
@author: frank
'''
from OvmCommonModule import *
class OvmDiskDecoder(json.JSONDecoder):
def decode(self, jStr):
deDict = asciiLoads(jStr)
disk = OvmDisk()
setAttrFromDict(disk, 'path', deDict)
setAttrFromDict(disk, 'type', deDict)
setAttrFromDict(disk, 'isIso', deDict)
return disk
class OvmDiskEncoder(json.JSONEncoder):
def default(self, obj):
if not isinstance(obj, OvmDisk): raise Exception("%s is not instance of OvmDisk"%type(obj))
dct = {}
safeDictSet(obj, dct, 'path')
safeDictSet(obj, dct, 'type')
return dct
def fromOvmDisk(disk):
return normalizeToGson(json.dumps(disk, cls=OvmDiskEncoder))
def fromOvmDiskList(diskList):
return [fromOvmDisk(d) for d in diskList]
def toOvmDisk(jStr):
return json.loads(jStr, cls=OvmDiskDecoder)
def toOvmDiskList(jStr):
disks = []
for i in jStr:
d = toOvmDisk(i)
disks.append(d)
return disks
class OvmDisk(OvmObject):
path = ''
type = ''
isIso = False
if __name__ == "__main__":
print toOvmDisk('''{"type":"w","path":"/data/data.raw"}''')
print toOvmDisk('''{"path":"/data/data.raw'","type":"w"}''')

View File

@ -0,0 +1,46 @@
import types
from OvmCommonModule import *
from xmlrpclib import Fault
from OVSCommons import *
import OvmFaultConstants
import OvmHostModule
import OvmStoragePoolModule
import OvmVmModule
import OvmNetworkModule
import OvmVolumeModule
import OvmSecurityGroupModule
from OvmHaHeartBeatModule import OvmHaHeartBeat
ExposedClass = {}
logger = OvmLogger('OvmDispatcher')
def InitOvmDispacther():
global ExposedClass
modules = [ eval(attr) for attr in globals() if isinstance(eval(attr), types.ModuleType) ]
for m in modules:
for name in dir(m):
clz = getattr(m, name)
if type(clz) is types.TypeType and issubclass(clz, OvmObject):
ExposedClass[name] = clz
logger.debug(InitOvmDispacther, "Discovered exposed class:\n\n%s"%"\n".join(ExposedClass))
@exposed
def OvmDispatch(methodName, *params):
global ExposedClass
p = methodName.split('.')
if len(p) != 2:
logger.error(OvmDispatch, "%s is not a vaild format, should be classname.methodname"%p)
raise Fault(dispatchErrCode('InvalidCallMethodFormat'), "%s is not a vaild format, should be classname.methodname"%p)
clzName = p[0]
funcName = p[1]
if clzName not in ExposedClass.keys():
logger.error(OvmDispatch, "class %s is not exposed by agent"%clzName)
raise Fault(dispatchErrCode('InvaildClass'), "class %s is not exposed by agent"%clzName)
clz = ExposedClass[clzName]
if not hasattr(clz, funcName):
logger.error(OvmDispatch, "class %s has no function %s"%(clzName, funcName))
raise Fault(dispatchErrCode('InvaildFunction'), "class %s has no function %s"%(clzName, funcName))
logger.debug(OvmDispatch, "Entering %s.%s ===>"%(clzName, funcName))
rs = getattr(clz, funcName)(*params)
logger.debug(OvmDispatch, "Exited %s.%s <==="%(clzName, funcName))
return rs

View File

@ -0,0 +1,13 @@
diff --git a/OVSAgentAutoStart.py b/OVSAgentAutoStart.py
index 88fa18c..794a363 100755
--- a/OVSAgentAutoStart.py
+++ b/OVSAgentAutoStart.py
@@ -111,8 +111,6 @@ def prepare_cluster_heartbeat():
JOBS = [
["command", join(dirname(__file__), "utils/upgrade_agent.py")],
["function", "get_agent_version", ()],
- ["function", "prepare_cluster_root", ()],
- ["function", "prepare_cluster_heartbeat", ()],
["command", join(dirname(__file__), "utils/upgrade.py")],
["command_bg", join(dirname(__file__), "OVSRemasterServer.py")],
["command_bg", join(dirname(__file__), "OVSMonitorServer.py")],

View File

@ -0,0 +1,67 @@
OvmDispatcherStub = 0
OvmHostErrCodeStub = 1000
OvmVmErrCodeStub = 2000
OvmStoragePoolErrCodeStub = 3000
OvmNetworkErrCodeStub = 4000
OvmVolumeErrCodeStub = 5000
class NoVmFoundException(Exception):
pass
errCode = {
# OvmDispatch is not class, these error codes are reserved
"OvmDispatch.InvalidCallMethodFormat":OvmDispatcherStub+1,
"OvmDispatch.InvaildClass":OvmDispatcherStub+2,
"OvmDispatch.InvaildFunction":OvmDispatcherStub+3,
"OvmVm.reboot":OvmDispatcherStub+4,
"OvmHost.registerAsMaster":OvmHostErrCodeStub+1,
"OvmHost.registerAsVmServer":OvmHostErrCodeStub+2,
"OvmHost.ping":OvmHostErrCodeStub+3,
"OvmHost.getDetails":OvmHostErrCodeStub+4,
"OvmHost.getPerformanceStats":OvmHostErrCodeStub+5,
"OvmHost.getAllVms":OvmHostErrCodeStub+6,
"OvmHost.fence":OvmHostErrCodeStub+7,
"OvmHost.setupHeartBeat":OvmHostErrCodeStub+8,
"OvmHost.pingAnotherHost":OvmHostErrCodeStub+9,
"OvmVm.create":OvmVmErrCodeStub+1,
"OvmVm.stop":OvmVmErrCodeStub+2,
"OvmVm.getDetails":OvmVmErrCodeStub+3,
"OvmVm.getVmStats":OvmVmErrCodeStub+4,
"OvmVm.migrate":OvmVmErrCodeStub+5,
"OvmVm.register":OvmVmErrCodeStub+6,
"OvmVm.getVncPort":OvmVmErrCodeStub+7,
"OvmVm.detachOrAttachIso":OvmVmErrCodeStub+8,
"OvmStoragePool.create":OvmStoragePoolErrCodeStub+1,
"OvmStoragePool.getDetailsByUuid":OvmStoragePoolErrCodeStub+2,
"OvmStoragePool.downloadTemplate":OvmStoragePoolErrCodeStub+3,
"OvmStoragePool.prepareOCFS2Nodes":OvmStoragePoolErrCodeStub+4,
"OvmNetwork.createBridge":OvmNetworkErrCodeStub+1,
"OvmNetwork.deleteBridge":OvmNetworkErrCodeStub+2,
"OvmNetwork.createVlan":OvmNetworkErrCodeStub+3,
"OvmNetwork.deleteVlan":OvmNetworkErrCodeStub+4,
"OvmNetwork.getAllBridges":OvmNetworkErrCodeStub+5,
"OvmNetwork.getBridgeByIp":OvmNetworkErrCodeStub+6,
"OvmNetwork.createVlanBridge":OvmNetworkErrCodeStub+7,
"OvmNetwork.deleteVlanBridge":OvmNetworkErrCodeStub+8,
"OvmVolume.createDataDisk":OvmVolumeErrCodeStub+1,
"OvmVolume.createFromTemplate":OvmVolumeErrCodeStub+2,
"OvmVolume.destroy":OvmVolumeErrCodeStub+3,
}
def toErrCode(clz, func):
global errCode
if not callable(func): raise Exception("%s is not a callable, cannot get error code"%func)
name = clz.__name__ + '.' + func.__name__
if name not in errCode.keys(): return -1
return errCode[name]
def dispatchErrCode(funcName):
name = "OvmDispatch." + funcName
if name not in errCode.keys(): return -1
return errCode[name]

View File

@ -0,0 +1,90 @@
'''
Created on Jun 6, 2011
@author: frank
'''
from OvmCommonModule import *
try:
from multiprocessing import Process, Manager
except ImportError:
from processing import Process, Manager
import signal
logger = OvmLogger("OvmHaHeartBeat")
class OvmHaHeartBeat(object):
'''
classdocs
'''
def __init__(self, mountPoint, ip):
self.mountPoint = mountPoint
self.ip = ip
def mark(self, file):
timestamp = HEARTBEAT_TIMESTAMP_FORMAT % time.time()
try:
fd = open(file, 'w')
fd.write(timestamp)
fd.close()
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmHaHeartBeat.mark, errmsg)
def run(self):
'''
Constructor
'''
heartBeatDir = join(self.mountPoint, HEARTBEAT_DIR)
if not exists(heartBeatDir):
os.makedirs(heartBeatDir)
hearBeatFile = join(heartBeatDir, ipToHeartBeatFileName(self.ip))
while True:
self.mark(hearBeatFile)
time.sleep(120)
@staticmethod
def start(poolPath, ip):
pidFile = join(PID_DIR, "heartbeat.pid")
def isLive():
if exists(pidFile):
f = open(pidFile)
pid = f.read().strip()
f.close()
if isdir("/proc/%s" % pid):
return long(pid)
return None
def stopOldHeartBeat(pid):
os.kill(pid, signal.SIGTERM)
time.sleep(5)
pid = isLive()
if pid != None:
logger.debug(OvmHaHeartBeat.start, "SIGTERM cannot stop heartbeat process %s, will try SIGKILL"%pid)
os.kill(pid, signal.SIGKILL)
time.sleep(5)
pid = isLive()
if pid != None:
raise Exception("Cannot stop old heartbeat process %s, setup heart beat failed"%pid)
def heartBeat(hb):
hb.run()
def setupHeartBeat():
hb = OvmHaHeartBeat(poolPath, ip)
p = Process(target=heartBeat, args=(hb,))
p.start()
pid = p.pid
if not isdir(PID_DIR):
os.makedirs(PID_DIR)
pidFd = open(pidFile, 'w')
pidFd.write(str(pid))
pidFd.close()
logger.info(OvmHaHeartBeat.start, "Set up heart beat successfully, pid is %s" % pid)
pid = isLive()
if pid != None:
stopOldHeartBeat(pid)
setupHeartBeat()

View File

@ -0,0 +1,260 @@
#/usr/bin/python
from OvmCommonModule import *
from OVSSiteRMServer import get_master_ip, register_server
from OVSCommons import *
from OVSXMonitor import xen_get_xm_info
from OVSXSysInfo import get_agent_version
from OVSSiteRMServer import get_srv_agent_status
from OVSXMonitor import sys_perf_info
from OVSDB import db_get_vm
from OvmStoragePoolModule import OvmStoragePool
from OvmHaHeartBeatModule import OvmHaHeartBeat
import re
logger = OvmLogger('OvmHost')
class OvmHostEncoder(json.JSONEncoder):
def default(self, obj):
if not isinstance(obj, OvmHost): raise Exception("%s is not instance of OvmHost"%type(obj))
dct = {}
safeDictSet(obj, dct, 'masterIp')
safeDictSet(obj, dct, 'cpuNum')
safeDictSet(obj, dct, 'cpuSpeed')
safeDictSet(obj, dct, 'totalMemory')
safeDictSet(obj, dct, 'freeMemory')
safeDictSet(obj, dct, 'dom0Memory')
safeDictSet(obj, dct, 'agentVersion')
safeDictSet(obj, dct, 'name')
safeDictSet(obj, dct, 'dom0KernelVersion')
safeDictSet(obj, dct, 'hypervisorVersion')
return dct
def fromOvmHost(host):
return normalizeToGson(json.dumps(host, cls=OvmHostEncoder))
class OvmHost(OvmObject):
masterIp = ''
cpuNum = 0
cpuSpeed = 0
totalMemory = 0
freeMemory = 0
dom0Memory = 0
agentVersion = ''
name = ''
dom0KernelVersion = ''
hypervisorVersion = ''
def _getVmPathFromPrimaryStorage(self, vmName):
'''
we don't have a database to store vm states, so there is no way to retrieve information of a vm
when it was already stopped. The trick is to try to find the vm path in primary storage then we
can read information from its configure file.
'''
mps = OvmStoragePool()._getAllMountPoints()
vmPath = None
for p in mps:
vmPath = join(p, 'running_pool', vmName)
if exists(vmPath): break
if not vmPath:
logger.error(self._getVmPathFromPrimaryStorage, "Cannot find link for %s in any primary storage, the vm was really gone!"%vmName)
raise Exception("Cannot find link for %s in any primary storage, the vm was really gone!"%vmName)
return vmPath
def _vmNameToPath(self, vmName):
return successToMap(xen_get_vm_path(vmName))['path']
def _getAllDomains(self):
stdout = timeout_command(["xm", "list"])
l = [ line.split()[:2] for line in stdout.splitlines() ]
l = [ (name, id) for (name, id) in l if name not in ("Name", "Domain-0") ]
return l
def _getDomainIdByName(self, vmName):
l = self._getAllDomains()
for name, id in l:
if vmName == name: return id
raise NoVmFoundException("No domain id for %s found"%vmName)
@staticmethod
def registerAsMaster(hostname, username="oracle", password="password", port=8899, isSsl=False):
try:
logger.debug(OvmHost.registerAsMaster, "ip=%s, username=%s, password=%s, port=%s, isSsl=%s"%(hostname, username, password, port, isSsl))
exceptionIfNoSuccess(register_server(hostname, 'site', False, username, password, port, isSsl),
"Register %s as site failed"%hostname)
exceptionIfNoSuccess(register_server(hostname, 'utility', False, username, password, port, isSsl),
"Register %s as utility failed"%hostname)
rs = SUCC()
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmHost.registerAsMaster, errmsg)
raise XmlRpcFault(toErrCode(OvmHost, OvmHost.registerAsMaster), errmsg)
@staticmethod
def registerAsVmServer(hostname, username="oracle", password="password", port=8899, isSsl=False):
try:
logger.debug(OvmHost.registerAsVmServer, "ip=%s, username=%s, password=%s, port=%s, isSsl=%s"%(hostname, username, password, port, isSsl))
exceptionIfNoSuccess(register_server(hostname, 'xen', False, username, password, port, isSsl),
"Register %s as site failed"%hostname)
rs = SUCC()
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmHost.registerAsVmServer, errmsg)
raise XmlRpcFault(toErrCode(OvmHost, OvmHost.registerAsVmServer), errmsg)
@staticmethod
def ping(hostname):
try:
logger.debug(OvmHost.ping, "ping %s"%hostname)
exceptionIfNoSuccess(get_srv_agent_status(hostname), "Ovs agent is down")
rs = SUCC()
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmHost.ping, errmsg)
raise XmlRpcFault(toErrCode(OvmHost, OvmHost.ping, errmsg))
@staticmethod
def getDetails():
try:
obj = OvmHost()
masterIp = successToMap(get_master_ip())
safeSetAttr(obj, 'masterIp', masterIp['ip'])
xmInfo = successToMap(xen_get_xm_info())
totalMemory = MtoBytes(long(xmInfo['total_memory']))
safeSetAttr(obj, 'totalMemory', totalMemory)
freeMemory = MtoBytes(long(xmInfo['free_memory']))
safeSetAttr(obj, 'freeMemory', freeMemory)
dom0Memory = totalMemory - freeMemory
safeSetAttr(obj, 'dom0Memory', dom0Memory)
cpuNum = int(xmInfo['nr_cpus'])
safeSetAttr(obj, 'cpuNum', cpuNum)
cpuSpeed = int(xmInfo['cpu_mhz'])
safeSetAttr(obj, 'cpuSpeed', cpuSpeed)
name = xmInfo['host']
safeSetAttr(obj, 'name', name)
dom0KernelVersion = xmInfo['release']
safeSetAttr(obj, 'dom0KernelVersion', dom0KernelVersion)
hypervisorVersion = xmInfo['xen_major'] + '.' + xmInfo['xen_minor'] + xmInfo['xen_extra']
safeSetAttr(obj, 'hypervisorVersion', hypervisorVersion)
agtVersion = successToMap(get_agent_version())
safeSetAttr(obj, 'agentVersion', agtVersion['agent_version'])
res = fromOvmHost(obj)
logger.debug(OvmHost.getDetails, res)
return res
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmHost.getDetails, errmsg)
raise XmlRpcFault(toErrCode(OvmHost, OvmHost.getDetails), errmsg)
@staticmethod
def getPerformanceStats(bridgeName):
try:
rxBytesPath = join("/sys/class/net/", bridgeName, "statistics/rx_bytes")
txBytesPath = join("/sys/class/net/", bridgeName, "statistics/tx_bytes")
if not exists(rxBytesPath): raise Exception("Cannot find %s"%rxBytesPath)
if not exists(txBytesPath): raise Exception("Cannot find %s"%txBytesPath)
rxBytes = long(doCmd(['cat', rxBytesPath])) / 1000
txBytes = long(doCmd(['cat', txBytesPath])) / 1000
sysPerf = successToMap(sys_perf_info())
cpuUtil = float(100 - float(sysPerf['cpu_idle']) * 100)
freeMemory = MtoBytes(long(sysPerf['mem_free']))
xmInfo = successToMap(xen_get_xm_info())
totalMemory = MtoBytes(long(xmInfo['total_memory']))
rs = toGson({"cpuUtil":cpuUtil, "totalMemory":totalMemory, "freeMemory":freeMemory, "rxBytes":rxBytes, "txBytes":txBytes})
logger.info(OvmHost.getPerformanceStats, rs)
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmHost.getPerformanceStats, errmsg)
raise XmlRpcFault(toErrCode(OvmHost, OvmHost.getPerformanceStats), errmsg)
@staticmethod
def getAllVms():
try:
l = OvmHost()._getAllDomains()
dct = {}
host = OvmHost()
for name, id in l:
vmPath = host._getVmPathFromPrimaryStorage(name)
vmStatus = db_get_vm(vmPath)
dct[name] = vmStatus['status']
rs = toGson(dct)
logger.info(OvmHost.getAllVms, rs)
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmHost.getAllVms, errmsg)
raise XmlRpcFault(toErrCode(OvmHost, OvmHost.getAllVms), errmsg)
@staticmethod
def fence(ip):
# try 3 times to avoid race condition that read when heartbeat file is being written
def getTimeStamp(hbFile):
for i in range(1, 3):
f = open(hbFile, 'r')
str = f.readline()
items = re.findall(HEARTBEAT_TIMESTAMP_PATTERN, str)
if len(items) == 0:
logger.debug(OvmHost.fence, "Get an incorrect heartbeat data %s, will retry %s times" % (str, 3-i))
f.close()
time.sleep(5)
else:
f.close()
timestamp = items[0]
return timestamp.lstrip('<timestamp>').rstrip('</timestamp>')
# totally check in 6 mins, the update frequency is 2 mins
def check(hbFile):
for i in range(1, 6):
ts = getTimeStamp(hbFile)
time.sleep(60)
nts = getTimeStamp(hbFile)
if ts != nts: return True
else: logger.debug(OvmHost.fence, '%s is not updated, old value=%s, will retry %s times'%(hbFile, ts, 6-i))
return False
try:
mountpoints = OvmStoragePool()._getAllMountPoints()
hbFile = None
for m in mountpoints:
p = join(m, HEARTBEAT_DIR, ipToHeartBeatFileName(ip))
if exists(p):
hbFile = p
break
if not hbFile: raise Exception('Can not find heartbeat file for %s in pools %s'%(ip, mountpoints))
rs = toGson({"isLive":check(hbFile)})
logger.debug(OvmHost.fence, rs)
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmHost.fence, errmsg)
raise XmlRpcFault(toErrCode(OvmHost, OvmHost.fence), errmsg)
@staticmethod
def setupHeartBeat(poolUuid, ip):
try:
sr = OvmStoragePool()._getSrByNameLable(poolUuid)
OvmHaHeartBeat.start(sr.mountpoint, ip)
return SUCC()
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmHost.setupHeartBeat, errmsg)
raise XmlRpcFault(toErrCode(OvmHost, OvmHost.setupHeartBeat), errmsg)
@staticmethod
def pingAnotherHost(ip):
try:
doCmd(['ping', '-c', '1', '-n', '-q', ip])
return SUCC()
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmHost.pingAnotherHost, errmsg)
raise XmlRpcFault(toErrCode(OvmHost, OvmHost.pingAnotherHost), errmsg)
if __name__ == "__main__":
print OvmHost.getAllVms()

View File

@ -0,0 +1,39 @@
'''
Created on May 19, 2011
@author: frank
'''
import logging
class OvmLogger(object):
'''
classdocs
'''
def __init__(self, className):
'''
Constructor
'''
self.className = className
self.logger = logging.getLogger(className)
def info(self, func, msg=None):
assert callable(func), "%s is not a function"%func
fmt = "[%s.%s]: "%(self.className, func.__name__)
self.logger.info("%s%s"%(fmt,msg))
def debug(self, func, msg=None):
assert callable(func), "%s is not a function"%func
fmt = "[%s.%s]: "%(self.className, func.__name__)
self.logger.debug("%s%s"%(fmt,msg))
def error(self, func, msg=None):
assert callable(func), "%s is not a function"%func
fmt = "[%s.%s]: "%(self.className, func.__name__)
self.logger.error("%s%s"%(fmt,msg))
def warning(self, func, msg=None):
assert callable(func), "%s is not a function"%func
fmt = "[%s.%s]: "%(self.className, func.__name__)
self.logger.warning("%s%s"%(fmt,msg))

View File

@ -0,0 +1,416 @@
from OvmCommonModule import *
import traceback
import time
import re
logger = OvmLogger("OvmNetwork")
class Filter:
class Network:
IFNAME_LO = r'(lo)'
IFNAME_PIF = r'(eth\d+$)'
IFNAME_VLAN = r'(eth\d+.\d+$)'
IFNAME_BRIDGE = r'(xenbr\d+|vlan\d+)'
class Parser(object):
'''
classdocs
'''
def findall(self, pattern, samples):
"""
@param pattern: search pattern
@param result: Parser line execution result
@return : list of search
find result of Parser which has same pattern
findall Parser find all pattern in a string
"""
result = []
for line in samples:
items = re.findall(pattern, line)
for item in items:
result.append(item)
return result
def checkPattern(self, pattern, cmd_result):
"""
@param pattern: search pattern
@param cmd_result: Parser line execution result
@return : True (if pattern is occurred)
"""
for line in cmd_result:
items = re.findall(pattern, line)
if len(items) > 0:
return True
return False
def search(self, cmd_result, pattern):
return None
class OvmVlanDecoder(json.JSONDecoder):
def decode(self, jStr):
deDict = asciiLoads(jStr)
vlan = OvmVlan()
setAttrFromDict(vlan, 'vid', deDict, int)
setAttrFromDict(vlan, 'pif', deDict)
return vlan
class OvmVlanEncoder(json.JSONEncoder):
def default(self, obj):
if not isinstance(obj, OvmVlan): raise Exception("%s is not instance of OvmVlan"%type(obj))
dct = {}
safeDictSet(obj, dct, 'name')
safeDictSet(obj, dct, 'vid')
safeDictSet(obj, dct, 'pif')
return dct
def toOvmVlan(jStr):
return json.loads(jStr, cls=OvmVlanDecoder)
def fromOvmVlan(vlan):
return normalizeToGson(json.dumps(vlan, cls=OvmVlanEncoder))
class OvmBridgeDecoder(json.JSONDecoder):
def decode(self, jStr):
deDic = asciiLoads(jStr)
bridge = OvmBridge()
setAttrFromDict(bridge, 'name', deDic)
setAttrFromDict(bridge, 'attach', deDic)
return bridge
class OvmBridgeEncoder(json.JSONEncoder):
def default(self, obj):
if not isinstance(obj, OvmBridge): raise Exception("%s is not instance of OvmBridge"%type(obj))
dct = {}
safeDictSet(obj, dct, 'name')
safeDictSet(obj, dct, 'attach')
safeDictSet(obj, dct, 'interfaces')
return dct
def toOvmBridge(jStr):
return json.loads(jStr, cls=OvmBridgeDecoder)
def fromOvmBridge(bridge):
return normalizeToGson(json.dumps(bridge, cls=OvmBridgeEncoder))
class OvmInterface(OvmObject):
name = ''
class OvmVlan(OvmInterface):
vid = 0
pif = ''
class OvmBridge(OvmInterface):
attach = ''
interfaces = []
class OvmNetwork(OvmObject):
'''
Network
'''
@property
def pifs(self):
return self._getInterfaces("pif")
@property
def vlans(self):
return self._getInterfaces("vlan")
@property
def bridges(self):
return self._getInterfaces("bridge")
def __init__(self):
self.Parser = Parser()
def _createVlan(self, vlan):
"""
@param jsonString : parameter from client side
@return : succ xxxxx
ex. jsonString => {vid:100, pif:eth0}
ex. return =>
"""
#Pre-condition
#check Physical Interface Name
if vlan.pif not in self.pifs.keys():
msg = "Physical Interface(%s) does not exist" % vlan.pif
logger.debug(self._createVlan, msg)
raise Exception(msg)
#Pre-condition
#check Vlan Interface Name
ifName = "%s.%s" % (vlan.pif, vlan.vid)
if ifName in self.vlans.keys():
msg = "Vlan Interface(%s) already exist, return it" % ifName
logger.debug(self._createVlan, msg)
return self.vlans[ifName]
doCmd(['vconfig', 'add', vlan.pif, vlan.vid])
self.bringUP(ifName)
logger.debug(self._createVlan, "Create vlan %s successfully"%ifName)
return self.vlans[ifName]
def _deleteVlan(self, name):
if name not in self.vlans.keys():
raise Exception("No vlan device %s found"%name)
vlan = self.vlans[name]
self.bringDown(vlan.name)
doCmd(['vconfig', 'rem', vlan.name])
logger.debug(self._deleteVlan, "Delete vlan %s successfully"%vlan.name)
def _createBridge(self, bridge):
"""
@return : success
ex. {bridge:xapi100, attach:eth0.100}
create bridge interface, and attached it
cmd 1: brctl addbr bridge
cmd 2: brctl addif brdige attach
"""
if "xenbr" not in bridge.name and "vlan" not in bridge.name:
raise Exception("Invalid bridge name %s. Bridge name must be in partten xenbr/vlan, e.g. xenbr0"%bridge.name)
#pre-condition
#check Bridge Interface Name
if bridge.name in self.bridges.keys():
msg = "Bridge(%s) already exist, return it" % bridge.name
logger.debug(self._createBridge, msg)
return self.bridges[bridge.name]
#pre-condition
#check attach must exist
#possible to attach in PIF or VLAN
if bridge.attach not in self.vlans.keys() and bridge.attach not in self.pifs.keys():
msg = "%s is not either pif or vlan" % bridge.attach
logger.error(self._createBridge, msg)
raise Exception(msg)
doCmd(['brctl', 'addbr', bridge.name])
doCmd(['brctl', 'addif', bridge.name, bridge.attach])
self.bringUP(bridge.name)
logger.debug(self._createBridge, "Create bridge %s on %s successfully"%(bridge.name, bridge.attach))
return self.bridges[bridge.name]
def _getBridges(self):
return self.bridges.keys()
def _getVlans(self):
return self.vlans.keys()
def _deleteBridge(self, name):
if name not in self.bridges.keys():
raise Exception("Can not find bridge %s"%name)
bridge = self.bridges[name]
if bridge.attach in bridge.interfaces: bridge.interfaces.remove(bridge.attach)
if len(bridge.interfaces) != 0:
logger.debug(self._deleteBridge, "There are still some interfaces(%s) on bridge %s"%(bridge.interfaces, bridge.name))
return False
self.bringDown(bridge.name)
doCmd(['brctl', 'delbr', bridge.name])
logger.debug(self._deleteBridge, "Delete bridge %s successfully"%bridge.name)
return True
def _getInterfaces(self, type):
"""
@param type : ["pif", "bridge", "tap"]
@return : dictionary of Interface Objects
get All Interfaces based on type
"""
devices = os.listdir('/sys/class/net')
ifs = {}
if type == "pif":
devs = self.Parser.findall(Filter.Network.IFNAME_PIF, devices)
for dev in set(devs):
ifInst = OvmInterface()
ifInst.name = dev
ifs[dev] = ifInst
elif type == "vlan":
devs = self.Parser.findall(Filter.Network.IFNAME_VLAN, devices)
for dev in set(devs):
ifInst = OvmVlan()
ifInst.name = dev
(pif, vid) = dev.split('.')
ifInst.pif = pif
ifInst.vid = vid
ifs[dev] = ifInst
elif type == "bridge":
devs = self.Parser.findall(Filter.Network.IFNAME_BRIDGE, devices)
for dev in set(devs):
ifInst = OvmBridge()
ifInst.name = dev
devs = os.listdir(join('/sys/class/net', dev, 'brif'))
ifInst.interfaces = devs
attches = self.Parser.findall(Filter.Network.IFNAME_PIF, devs) + self.Parser.findall(Filter.Network.IFNAME_VLAN, devs)
if len(attches) > 1: raise Exception("Multiple PIF on bridge %s (%s)"%(dev, attches))
elif len(attches) == 0: ifInst.attach = "null"
elif len(attches) == 1: ifInst.attach = attches[0]
ifs[dev] = ifInst
return ifs
def bringUP(self, ifName):
doCmd(['ifconfig', ifName, 'up'])
def bringDown(self, ifName):
doCmd(['ifconfig', ifName, 'down'])
@staticmethod
def createBridge(jStr):
try:
network = OvmNetwork()
network._createBridge(toOvmBridge(jStr))
return SUCC()
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmNetwork.createBridge, errmsg)
raise XmlRpcFault(toErrCode(OvmNetwork, OvmNetwork.createBridge), errmsg)
@staticmethod
def deleteBridge(name):
try:
network = OvmNetwork()
network._deleteBridge(name)
return SUCC()
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmNetwork.deleteBridge, errmsg)
raise XmlRpcFault(toErrCode(OvmNetwork, OvmNetwork.deleteBridge), errmsg)
@staticmethod
def getAllBridges():
try:
network = OvmNetwork()
rs = toGson(network._getBridges())
logger.debug(OvmNetwork.getAllBridges, rs)
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmNetwork.getAllBridges, errmsg)
raise XmlRpcFault(toErrCode(OvmNetwork, OvmNetwork.getAllBridges), errmsg)
@staticmethod
def getBridgeByIp(ip):
try:
routes = doCmd(['ip', 'route']).split('\n')
brName = None
for r in routes:
if ip in r and "xenbr" in r or "vlan" in r:
brName = r.split(' ')[2]
break
if not brName: raise Exception("Cannot find bridge with IP %s"%ip)
logger.debug(OvmNetwork.getBridgeByIp, "bridge:%s, ip:%s"%(brName, ip))
return toGson({"bridge":brName})
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmNetwork.getBridgeByIp, errmsg)
raise XmlRpcFault(toErrCode(OvmNetwork, OvmNetwork.getBridgeByIp), errmsg)
@staticmethod
def getVlans():
try:
network = OvmNetwork()
rs = toGson(network._getVlans())
logger.debug(OvmNetwork.getVlans, rs)
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmNetwork.getVlans, errmsg)
raise XmlRpcFault(toErrCode(OvmNetwork, OvmNetwork.getVlans), errmsg)
@staticmethod
def createVlan(jStr):
try:
network = OvmNetwork()
vlan = network._createVlan(toOvmVlan(jStr))
rs = fromOvmVlan(vlan)
logger.debug(OvmNetwork.createVlan, rs)
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmNetwork.createVlan, errmsg)
raise XmlRpcFault(toErrCode(OvmNetwork, OvmNetwork.createVlan), errmsg)
@staticmethod
def createVlanBridge(bridgeDetails, vlanDetails):
try:
network = OvmNetwork()
v = toOvmVlan(vlanDetails)
b = toOvmBridge(bridgeDetails)
vlan = network._createVlan(v)
b.attach = vlan.name
network._createBridge(b)
return SUCC()
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmNetwork.createVlanBridge, errmsg)
raise XmlRpcFault(toErrCode(OvmNetwork, OvmNetwork.createVlanBridge), errmsg)
@staticmethod
def deleteVlanBridge(name):
try:
network = OvmNetwork()
if name not in network.bridges.keys():
logger.debug(OvmNetwork.deleteVlanBridge, "No bridge %s found"%name)
return SUCC()
bridge = network.bridges[name]
vlanName = bridge.attach
if network._deleteBridge(name):
if vlanName != "null":
network._deleteVlan(vlanName)
else:
logger.warning(OvmNetwork.deleteVlanBridge, "Bridge %s has no vlan device"%name)
return SUCC()
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmNetwork.deleteVlanBridge, errmsg)
raise XmlRpcFault(toErrCode(OvmNetwork, OvmNetwork.deleteVlanBridge), errmsg)
@staticmethod
def getBridgeDetails(name):
try:
network = OvmNetwork()
if name not in network.bridges.keys():
raise Exception("No bridge %s found"%name)
bridge = network.bridges[name]
rs = fromOvmBridge(bridge)
logger.debug(OvmNetwork.getBridgeDetails, rs)
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmNetwork.getBridgeDetails, errmsg)
raise XmlRpcFault(toErrCode(OvmNetwork, OvmNetwork.getBridgeDetails), errmsg)
@staticmethod
def deleteVlan(name):
try:
network = OvmNetwork()
network._deleteVlan(name)
return SUCC()
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmNetwork.deleteVlan, errmsg)
raise XmlRpcFault(toErrCode(OvmNetwork, OvmNetwork.deleteVlan), errmsg)
if __name__ == "__main__":
try:
OvmNetwork.getBridgeDetails(sys.argv[1])
#=======================================================================
# txt = json.dumps({"vid":104, "pif":"eth0"})
# txt2 = json.dumps({"name":"xapi3", "attach":"eth0.104"})
# print nw.createVlan(txt)
# print nw.createBridge(txt2)
#
# nw.deleteBridge("xapi3")
# nw.deleteVlan("eth0.104")
#=======================================================================
except Exception, e:
print e

View File

@ -0,0 +1,8 @@
'''
Created on May 17, 2011
@author: frank
'''
class OvmObject(object):
pass

View File

@ -0,0 +1,23 @@
*** OVSServices.py 2011-06-06 12:31:23.279919998 -0700
--- /tmp/OVSServices.py 2011-06-06 12:32:13.275919997 -0700
***************
*** 68,73 ****
--- 68,75 ----
import OVSVMXParser #pylint: disable-msg=W0611
import OVSVMDKParser #pylint: disable-msg=W0611
+ import OvmDispatcher
+
from OVSWrappers import D
from OVSCommons import exposed
***************
*** 113,118 ****
--- 115,121 ----
self.sleep = sleep
self._load_modules()
+ OvmDispatcher.InitOvmDispacther()
# #xenapi
# import xen.xend.XendAPI as XendAPI

View File

@ -0,0 +1,466 @@
from OvmCommonModule import *
from ConfigFileOps import *
import os
import logging
class OvmSecurityGroup(OvmObject):
@staticmethod
def can_bridge_firewall():
try:
execute("which iptables")
except:
print "iptables was not found on the host"
return False
try:
execute("which ebtables")
except:
print "ebtables was not found on the host"
return False
if not os.path.exists('/var/run/cloud'):
os.makedirs('/var/run/cloud')
return OvmSecurityGroup.cleanup_rules()
@staticmethod
def cleanup_rules():
try:
chainscmd = "iptables-save | grep '^:' | grep -v '.*-def' | awk '{print $1}' | cut -d':' -f2"
chains = execute(chainscmd).split('\n')
cleaned = 0
cleanup = []
for chain in chains:
if 1 in [ chain.startswith(c) for c in ['r-', 'i-', 's-', 'v-'] ]:
vm_name = chain
else:
continue
cmd = "xm list | grep " + vm_name
try:
result = execute(cmd)
except:
result = None
if result == None or len(result) == 0:
logging.debug("chain " + chain + " does not correspond to a vm, cleaning up")
cleanup.append(vm_name)
for vm_name in cleanup:
OvmSecurityGroup.delete_all_network_rules_for_vm(vm_name)
logging.debug("Cleaned up rules for " + str(len(cleanup)) + " chains")
return True
except:
logging.debug("Failed to cleanup rules !")
return False
@staticmethod
def add_fw_framework(bridge_name):
try:
cfo = ConfigFileOps("/etc/sysctl.conf")
cfo.addEntry("net.bridge.bridge-nf-call-arptables", "1")
cfo.addEntry("net.bridge.bridge-nf-call-iptables", "1")
cfo.addEntry("net.bridge.bridge-nf-call-ip6tables", "1")
cfo.save()
execute("sysctl -p /etc/sysctl.conf")
except:
logging.debug("failed to turn on bridge netfilter")
return False
brfw = "BF-" + bridge_name
try:
execute("iptables -L " + brfw)
except:
execute("iptables -N " + brfw)
brfwout = brfw + "-OUT"
try:
execute("iptables -L " + brfwout)
except:
execute("iptables -N " + brfwout)
brfwin = brfw + "-IN"
try:
execute("iptables -L " + brfwin)
except:
execute("iptables -N " + brfwin)
try:
refs = execute("iptables -n -L " + brfw + " |grep " + brfw + " | cut -d \( -f2 | awk '{print $1}'").strip()
if refs == "0":
execute("iptables -I FORWARD -i " + bridge_name + " -j DROP")
execute("iptables -I FORWARD -o " + bridge_name + " -j DROP")
execute("iptables -I FORWARD -i " + bridge_name + " -m physdev --physdev-is-bridged -j " + brfw)
execute("iptables -I FORWARD -o " + bridge_name + " -m physdev --physdev-is-bridged -j " + brfw)
phydev = execute("brctl show |grep " + bridge_name + " | awk '{print $4}'").strip()
execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-out " + phydev + " -j ACCEPT")
execute("iptables -A " + brfw + " -m state --state RELATED,ESTABLISHED -j ACCEPT")
execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-is-out -j " + brfwout)
execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-is-in -j " + brfwin)
return True
except:
try:
execute("iptables -F " + brfw)
except:
return False
return False
@staticmethod
def default_network_rules_user_vm(vm_name, vm_id, vm_ip, vm_mac, vif, bridge_name):
if not OvmSecurityGroup.add_fw_framework(bridge_name):
return False
OvmSecurityGroup.delete_iptables_rules_for_vm(vm_name)
OvmSecurityGroup.delete_ebtables_rules_for_vm(vm_name)
bridge_firewall_chain = "BF-" + bridge_name
vm_chain = vm_name
default_vm_chain = '-'.join(vm_chain.split('-')[:-1]) + "-def"
dom_id = getDomId(vm_name)
try:
execute("iptables -N " + vm_chain)
except:
execute("iptables -F " + vm_chain)
try:
execute("iptables -N " + default_vm_chain)
except:
execute("iptables -F " + default_vm_chain)
try:
execute("iptables -A " + bridge_firewall_chain + "-OUT" + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + default_vm_chain)
execute("iptables -A " + bridge_firewall_chain + "-IN" + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -j " + default_vm_chain)
execute("iptables -A " + default_vm_chain + " -m state --state RELATED,ESTABLISHED -j ACCEPT")
# Allow DHCP
execute("iptables -A " + default_vm_chain + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -p udp --dport 67 --sport 68 -j ACCEPT")
execute("iptables -A " + default_vm_chain + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -p udp --dport 68 --sport 67 -j ACCEPT")
# Don't let a VM spoof its ip address
if vm_ip is not None:
execute("iptables -A " + default_vm_chain + " -m physdev --physdev-is-bridged --physdev-in " + vif + " --source " + vm_ip + " -j ACCEPT")
execute("iptables -A " + default_vm_chain + " -j " + vm_chain)
execute("iptables -A " + vm_chain + " -j DROP")
except:
logging.debug("Failed to program default rules for vm " + vm_name)
return False
OvmSecurityGroup.default_ebtables_rules(vm_chain, vm_ip, vm_mac, vif)
if vm_ip is not None:
if (OvmSecurityGroup.write_rule_log_for_vm(vm_name, vm_id, vm_ip, dom_id, '_initial_', '-1') == False):
logging.debug("Failed to log default network rules, ignoring")
logging.debug("Programmed default rules for vm " + vm_name)
return True
@staticmethod
def default_ebtables_rules(vm_name, vm_ip, vm_mac, vif):
vm_chain_in = vm_name + "-in"
vm_chain_out = vm_name + "-out"
for chain in [vm_chain_in, vm_chain_out]:
try:
execute("ebtables -t nat -N " + chain)
except:
execute("ebtables -t nat -F " + chain)
try:
execute("ebtables -t nat -A PREROUTING -i " + vif + " -j " + vm_chain_in)
execute("ebtables -t nat -A POSTROUTING -o " + vif + " -j " + vm_chain_out)
except:
logging.debug("Failed to program default rules")
return False
try:
execute("ebtables -t nat -A " + vm_chain_in + " -s ! " + vm_mac + " -j DROP")
execute("ebtables -t nat -A " + vm_chain_in + " -p ARP -s ! " + vm_mac + " -j DROP")
execute("ebtables -t nat -A " + vm_chain_in + " -p ARP --arp-mac-src ! " + vm_mac + " -j DROP")
if vm_ip is not None:
execute("ebtables -t nat -A " + vm_chain_in + " -p ARP --arp-ip-src ! " + vm_ip + " -j DROP")
execute("ebtables -t nat -A " + vm_chain_in + " -p ARP --arp-op Request -j ACCEPT")
execute("ebtables -t nat -A " + vm_chain_in + " -p ARP --arp-op Reply -j ACCEPT")
execute("ebtables -t nat -A " + vm_chain_in + " -p ARP -j DROP")
except:
logging.exception("Failed to program default ebtables IN rules")
return False
try:
execute("ebtables -t nat -A " + vm_chain_out + " -p ARP --arp-op Reply --arp-mac-dst ! " + vm_mac + " -j DROP")
if vm_ip is not None:
execute("ebtables -t nat -A " + vm_chain_out + " -p ARP --arp-ip-dst ! " + vm_ip + " -j DROP")
execute("ebtables -t nat -A " + vm_chain_out + " -p ARP --arp-op Request -j ACCEPT")
execute("ebtables -t nat -A " + vm_chain_out + " -p ARP --arp-op Reply -j ACCEPT")
execute("ebtables -t nat -A " + vm_chain_out + " -p ARP -j DROP")
except:
logging.debug("Failed to program default ebtables OUT rules")
return False
return True
@staticmethod
def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vm_mac, rules, vif, bridge_name):
try:
vm_chain = vm_name
dom_id = getDomId(vm_name)
changes = []
changes = OvmSecurityGroup.check_rule_log_for_vm(vm_name, vm_id, vm_ip, dom_id, signature, seqno)
if not 1 in changes:
logging.debug("Rules already programmed for vm " + vm_name)
return True
if changes[0] or changes[1] or changes[2] or changes[3]:
if not OvmSecurityGroup.default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, bridge_name):
return False
if rules == "" or rules == None:
lines = []
else:
lines = rules.split(';')[:-1]
logging.debug("Programming network rules for IP: " + vm_ip + " vmname=" + vm_name)
execute("iptables -F " + vm_chain)
for line in lines:
tokens = line.split(':')
if len(tokens) != 4:
continue
protocol = tokens[0]
start = tokens[1]
end = tokens[2]
cidrs = tokens.pop();
ips = cidrs.split(",")
ips.pop()
allow_any = False
if '0.0.0.0/0' in ips:
i = ips.index('0.0.0.0/0')
del ips[i]
allow_any = True
port_range = start + ":" + end
if ips:
if protocol == 'all':
for ip in ips:
execute("iptables -I " + vm_chain + " -m state --state NEW -s " + ip + " -j ACCEPT")
elif protocol != 'icmp':
for ip in ips:
execute("iptables -I " + vm_chain + " -p " + protocol + " -m " + protocol + " --dport " + port_range + " -m state --state NEW -s " + ip + " -j ACCEPT")
else:
port_range = start + "/" + end
if start == "-1":
port_range = "any"
for ip in ips:
execute("iptables -I " + vm_chain + " -p icmp --icmp-type " + port_range + " -s " + ip + " -j ACCEPT")
if allow_any and protocol != 'all':
if protocol != 'icmp':
execute("iptables -I " + vm_chain + " -p " + protocol + " -m " + protocol + " --dport " + port_range + " -m state --state NEW -j ACCEPT")
else:
port_range = start + "/" + end
if start == "-1":
port_range = "any"
execute("iptables -I " + vm_chain + " -p icmp --icmp-type " + port_range + " -j ACCEPT")
iptables = "iptables -A " + vm_chain + " -j DROP"
execute(iptables)
return OvmSecurityGroup.write_rule_log_for_vm(vm_name, vm_id, vm_ip, dom_id, signature, seqno)
except:
logging.debug("Failed to network rule !: " + sys.exc_type)
return False
@staticmethod
def delete_all_network_rules_for_vm(vm_name, vif = None):
OvmSecurityGroup.delete_iptables_rules_for_vm(vm_name)
OvmSecurityGroup.delete_ebtables_rules_for_vm(vm_name)
vm_chain = vm_name
default_vm_chain = None
if vm_name.startswith('i-') or vm_name.startswith('r-'):
default_vm_chain = '-'.join(vm_name.split('-')[:-1]) + "-def"
try:
if default_vm_chain != None:
execute("iptables -F " + default_vm_chain)
except:
logging.debug("Ignoring failure to delete chain " + default_vm_chain)
try:
if default_vm_chain != None:
execute("iptables -X " + vmchain_default)
except:
logging.debug("Ignoring failure to delete chain " + default_vm_chain)
try:
execute("iptables -F " + vm_chain)
except:
logging.debug("Ignoring failure to delete chain " + vm_chain)
try:
execute("iptables -X " + vm_chain)
except:
logging.debug("Ignoring failure to delete chain " + vm_chain)
if vif is not None:
try:
dnats = execute("iptables-save -t nat | grep " + vif + " | sed 's/-A/-D/'").split("\n")
for dnat in dnats:
try:
execute("iptables -t nat " + dnat)
except:
logging.debug("Igoring failure to delete dnat: " + dnat)
except:
pass
OvmSecurityGroup.remove_rule_log_for_vm(vm_name)
if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-'] ]:
return True
return True
@staticmethod
def delete_iptables_rules_for_vm(vm_name):
vm_name = OvmSecurityGroup.truncate_vm_name(vm_name)
vm_chain = vm_name
query = "iptables-save | grep " + vm_chain + " | grep physdev-is-bridged | sed 's/-A/-D/'"
delete_cmds = execute(query).split('\n')
delete_cmds.pop()
for cmd in delete_cmds:
try:
execute("iptables " + cmd)
except:
logging.exception("Ignoring failure to delete rules for vm " + vm_name)
@staticmethod
def delete_ebtables_rules_for_vm(vm_name):
vm_name = OvmSecurityGroup.truncate_vm_name(vm_name)
query = "ebtables -t nat -L --Lx | grep ROUTING | grep " + vm_name + " | sed 's/-A/-D/'"
delete_cmds = execute(query).split('\n')
delete_cmds.pop()
for cmd in delete_cmds:
try:
execute(cmd)
except:
logging.debug("Ignoring failure to delete ebtables rules for vm " + vm_name)
chains = [vm_name + "-in", vm_name + "-out"]
for chain in chains:
try:
execute("ebtables -t nat -F " + chain)
execute("ebtables -t nat -X " + chain)
except:
logging.debug("Ignoring failure to delete ebtables chain for vm " + vm_name)
@staticmethod
def truncate_vm_name(vm_name):
if vm_name.startswith('i-') or vm_name.startswith('r-'):
truncated_vm_name = '-'.join(vm_name.split('-')[:-1])
else:
truncated_vm_name = vm_name
return truncated_vm_name
@staticmethod
def write_rule_log_for_vm(vm_name, vm_id, vm_ip, dom_id, signature, seqno):
log_file_name = "/var/run/cloud/" + vm_name + ".log"
logging.debug("Writing log to " + log_file_name)
logf = open(log_file_name, 'w')
output = ','.join([vm_name, vm_id, vm_ip, dom_id, signature, seqno])
result = True
try:
logf.write(output)
logf.write('\n')
except:
logging.debug("Failed to write to rule log file " + log_file_name)
result = False
logf.close()
return result
@staticmethod
def remove_rule_log_for_vm(vm_name):
log_file_name = "/var/run/cloud/" + vm_name +".log"
result = True
try:
os.remove(log_file_name)
except:
logging.debug("Failed to delete rule log file " + log_file_name)
result = False
return result
@staticmethod
def check_rule_log_for_vm(vm_name, vm_id, vm_ip, dom_id, signature, seqno):
log_file_name = "/var/run/cloud/" + vm_name + ".log"
if not os.path.exists(log_file_name):
return [True, True, True, True, True, True]
try:
lines = (line.rstrip() for line in open(log_file_name))
except:
logging.debug("failed to open " + log_file_name)
return [True, True, True, True, True, True]
[_vm_name, _vm_id, _vm_ip, _dom_id, _signature, _seqno] = ['_', '-1', '_', '-1', '_', '-1']
try:
for line in lines:
[_vm_name, _vm_id, _vm_ip, _dom_id, _signature, _seqno] = line.split(',')
break
except:
logging.debug("Failed to parse log file for vm " + vm_name)
remove_rule_log_for_vm(vm_name)
return [True, True, True, True, True, True]
return [(vm_name != _vm_name), (vm_id != _vm_id), (vm_ip != _vm_ip), (dom_id != _dom_id), (signature != _signature), (seqno != _seqno)]

View File

@ -0,0 +1,289 @@
from OvmCommonModule import *
from OVSSiteSR import sp_create, sr_create, sr_do
from OVSParser import parse_ocfs2_cluster_conf
from OVSXCluster import clusterm_set_ocfs2_cluster_conf, clusterm_start_o2cb_service
import re
class OvmStoragePoolDecoder(json.JSONDecoder):
def decode(self, jStr):
dct = asciiLoads(jStr)
pool = OvmStoragePool()
setAttrFromDict(pool, 'uuid', dct)
setAttrFromDict(pool, 'type', dct)
setAttrFromDict(pool, 'path', dct)
return pool
class OvmStoragePoolEncoder(json.JSONEncoder):
def default(self, obj):
if not isinstance(obj, OvmStoragePool): raise Exception("%s is not instance of OvmStoragePool"%type(obj))
dct = {}
safeDictSet(obj, dct, 'uuid')
safeDictSet(obj, dct, 'type')
safeDictSet(obj, dct, 'path')
safeDictSet(obj, dct, 'mountPoint')
safeDictSet(obj, dct, 'totalSpace')
safeDictSet(obj, dct, 'freeSpace')
safeDictSet(obj, dct, 'usedSpace')
return dct
def fromOvmStoragePool(pool):
return normalizeToGson(json.dumps(pool, cls=OvmStoragePoolEncoder))
def toOvmStoragePool(jStr):
return json.loads(jStr, cls=OvmStoragePoolDecoder)
logger = OvmLogger('OvmStoragePool')
class OvmStoragePool(OvmObject):
uuid = ''
type = ''
path = ''
mountPoint = ''
totalSpace = 0
freeSpace = 0
usedSpace = 0
def _getSrByNameLable(self, poolUuid):
d = db_dump('sr')
for uuid, sr in d.items():
if sr.name_label == poolUuid:
return sr
raise Exception("No SR matching to %s" % poolUuid)
def _getSpaceinfoOfDir(self, dir):
stat = os.statvfs(dir)
freeSpace = stat.f_frsize * stat.f_bavail;
totalSpace = stat.f_blocks * stat.f_frsize;
return (totalSpace, freeSpace)
def _checkDirSizeForImage(self, dir, image):
(x, free_storage_size) = OvmStoragePool()._getSpaceinfoOfDir(dir)
image_size = os.path.getsize(image)
if image_size > (free_storage_size + 1024 * 1024 * 1024):
raise Exception("No space on dir %s (free storage:%s, vm size:%s)"%(dir, free_storage_size, image_size))
def _getAllMountPoints(self):
mps = []
d = db_dump('sr')
for uuid, sr in d.items():
mps.append(sr.mountpoint)
return mps
def _isMounted(self, path):
res = doCmd(['mount'])
return (path in res)
def _mount(self, target, mountpoint):
if not exists(mountpoint):
os.makedirs(mountpoint)
if not OvmStoragePool()._isMounted(mountpoint):
doCmd(['mount', target, mountpoint, '-r'])
@staticmethod
def create(jStr):
try:
pool = toOvmStoragePool(jStr)
logger.debug(OvmStoragePool.create, fromOvmStoragePool(pool))
spUuid = jsonSuccessToMap(sp_create(pool.type, pool.path))['uuid']
srUuid = jsonSuccessToMap(sr_create(spUuid, name_label=pool.uuid))['uuid']
sr_do(srUuid, "initialize")
rs = SUCC()
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmStoragePool.create, errmsg)
raise XmlRpcFault(toErrCode(OvmStoragePool, OvmStoragePool.create), errmsg)
@staticmethod
def getDetailsByUuid(uuid):
try:
sr = OvmStoragePool()._getSrByNameLable(uuid)
pool = OvmStoragePool()
safeSetAttr(pool, 'uuid', uuid)
#Note: the sr.sp.fs_type is not mapped to its class name which we use in mgmt server
safeSetAttr(pool, 'type', sr.sp.__class__.__name__)
safeSetAttr(pool, 'path', sr.sp.get_fs_spec())
safeSetAttr(pool, 'mountPoint', sr.mountpoint)
(totalSpace, freeSpace) = OvmStoragePool()._getSpaceinfoOfDir(sr.mountpoint)
safeSetAttr(pool, 'totalSpace', totalSpace)
safeSetAttr(pool, 'freeSpace', freeSpace)
safeSetAttr(pool, 'usedSpace', totalSpace - freeSpace)
res = fromOvmStoragePool(pool)
logger.debug(OvmStoragePool.getDetailsByUuid, res)
return res
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmStoragePool.getDetailsByUuid, errmsg)
raise XmlRpcFault(toErrCode(OvmStoragePool, OvmStoragePool.getDetailsByUuid), errmsg)
@staticmethod
def downloadTemplate(uuid, secPath):
secMountPoint = None
try:
logger.debug(OvmStoragePool.downloadTemplate, "download %s to pool %s"%(secPath, uuid))
try:
tmpUuid = get_uuid()
secMountPoint = join("/var/cloud/", tmpUuid)
if not exists(secMountPoint):
os.makedirs(secMountPoint)
templateFile = None
if secPath.endswith("raw"):
secPathDir = os.path.dirname(secPath)
templateFile = os.path.basename(secPath)
else:
secPathDir = secPath
# mount as read-only
mountCmd = ['mount.nfs', secPathDir, secMountPoint, '-r']
doCmd(mountCmd)
if not templateFile:
for f in os.listdir(secMountPoint):
if isfile(join(secMountPoint, f)) and f.endswith('raw'):
templateFile = f
break
if not templateFile:
raise Exception("Can not find raw template in secondary storage")
templateSecPath = join(secMountPoint, templateFile)
sr = OvmStoragePool()._getSrByNameLable(uuid)
priStorageMountPoint = sr.mountpoint
# Although mgmt server will check the size, we check again for safety
OvmStoragePool()._checkDirSizeForImage(priStorageMountPoint, templateSecPath)
seedDir = join(priStorageMountPoint, 'seed_pool', tmpUuid)
if exists(seedDir):
raise Exception("%s already here, cannot override existing template" % seedDir)
os.makedirs(seedDir)
tgt = join(seedDir, templateFile)
cpTemplateCmd = ['cp', templateSecPath, tgt]
logger.info(OvmStoragePool.downloadTemplate, " ".join(cpTemplateCmd))
doCmd(cpTemplateCmd)
templateSize = os.path.getsize(tgt)
logger.info(OvmStoragePool.downloadTemplate, "primary_storage_download success:installPath:%s, templateSize:%s"%(tgt,templateSize))
rs = toGson({"installPath":tgt, "templateSize":templateSize})
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmStoragePool.downloadTemplate, errmsg)
raise XmlRpcFault(toErrCode(OvmStoragePool, OvmStoragePool.downloadTemplate), errmsg)
finally:
if exists(secMountPoint):
try:
umountCmd = ['umount', '-f', secMountPoint]
doCmd(umountCmd)
ls = os.listdir(secMountPoint)
if len(ls) == 0:
rmDirCmd = ['rm', '-r', secMountPoint]
doCmd(rmDirCmd)
else:
logger.warning(OvmStoragePool.downloadTemplate, "Something wrong when umount %s, there are still files in directory:%s", secMountPoint, " ".join(ls))
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmStoragePool.downloadTemplate, 'unmount secondary storage at %s failed, %s'%(secMountPoint, errmsg))
@staticmethod
def prepareOCFS2Nodes(clusterName, nodeString):
def compareClusterConfig(nodes):
def sortNodes(nodes):
ns = []
for n in nodes:
ns.insert(int(n["number"]), n)
return ns
def compareNodes(ns1, ns2):
if len(ns1) != len(ns2):
return False
for i in range(0, len(ns1)):
n1 = ns1[i]
n2 = ns2[i]
if n1["ip_address"] != n2["ip_address"] or n1["number"] != n2["number"] \
or n1["name"] != n2["name"]:
return False
return True
if exists(OCFS2_CLUSTER_CONF):
oldConf = parse_ocfs2_cluster_conf()
cluster = oldConf["cluster"]
nodesNum = cluster["node_count"]
if len(nodes) != nodesNum:
return False
new = sortNodes(nodes)
old = sortNodes(oldConf["nodes"])
return compareNodes(new, old)
else:
return False
def configureEtcHosts(nodes):
if not exists(ETC_HOSTS):
orignalConf = ""
else:
fd = open(ETC_HOSTS, "r")
orignalConf = fd.read()
fd.close()
pattern = r"(.*%s.*)|(.*%s.*)"
newlines = []
for n in nodes:
p = pattern % (n["ip_address"], n["name"])
orignalConf = re.sub(p, "", orignalConf)
newlines.append("%s\t%s\n"%(n["ip_address"], n["name"]))
orignalConf = orignalConf + "".join(newlines)
# remove extra empty lines
orignalConf = re.sub(r"\n\s*\n*", "\n", orignalConf)
logger.debug(OvmStoragePool.prepareOCFS2Nodes, "Configure /etc/hosts:%s\n"%orignalConf)
fd = open(ETC_HOSTS, "w")
fd.write(orignalConf)
fd.close()
try:
nodeString = nodeString.strip(";")
nodes = []
for n in nodeString.split(";"):
params = n.split(":")
if len(params) != 3: raise Exception("Wrong parameter(%s) in node string(%s)"%(n, nodeString))
dict = {"number":params[0], "ip_address":params[1], "name":params[2]}
nodes.append(dict)
if len(nodes) > 255:
raise Exception("%s nodes beyond maximum 255 allowed by OCFS2"%len(nodes))
if compareClusterConfig(nodes):
logger.debug(OvmStoragePool.prepareOCFS2Nodes, "Nodes configure are the same, return")
rs = SUCC()
return rs
lines = []
for n in nodes:
lines.append("node:\n")
lines.append("\tip_port = %s\n" % "7777")
lines.append("\tip_address = %s\n" % n["ip_address"])
lines.append("\tnumber = %s\n" % n["number"])
lines.append("\tname = %s\n" % n["name"])
lines.append("\tcluster = %s\n" % clusterName)
lines.append("\n")
lines.append("cluster:\n")
lines.append("\tnode_count = %d\n" % len(nodes))
lines.append("\tname = %s\n" % clusterName)
lines.append("\n")
conf = "".join(lines)
clusterm_set_ocfs2_cluster_conf(conf)
clusterm_start_o2cb_service()
logger.debug(OvmStoragePool.prepareOCFS2Nodes, "Configure cluster.conf to:\n%s"%conf)
configureEtcHosts(nodes)
rs = SUCC()
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmStoragePool.prepareOCFS2Nodes, errmsg)
raise XmlRpcFault(toErrCode(OvmStoragePool, OvmStoragePool.prepareOCFS2Nodes), errmsg)

View File

@ -0,0 +1,50 @@
'''
Created on May 17, 2011
@author: frank
'''
from OvmCommonModule import *
class OvmVifDecoder(json.JSONDecoder):
def decode(self, jStr):
deDict = asciiLoads(jStr)
vif = OvmVif()
vif.mac = deDict['mac']
vif.bridge = deDict['bridge']
return vif
class OvmVifEncoder(json.JSONEncoder):
def default(self, obj):
if not isinstance(obj, OvmVif): raise Exception("%s is not instance of OvmVif"%type(obj))
dct = {}
safeDictSet(obj, dct, 'mac')
safeDictSet(obj, dct, 'bridge')
safeDictSet(obj, dct, 'type')
safeDictSet(obj, dct, 'name')
return dct
def fromOvmVif(vif):
return normalizeToGson(json.dumps(vif, cls=OvmVifEncoder))
def fromOvmVifList(vifList):
return [fromOvmVif(v) for v in vifList]
def toOvmVif(jStr):
return json.loads(jStr, cls=OvmVifDecoder)
def toOvmVifList(jStr):
vifs = []
for i in jStr:
vif = toOvmVif(i)
vifs.append(vif)
return vifs
class OvmVif(OvmObject):
name = ''
mac = ''
bridge = ''
type = ''
mode = ''
def toXenString(self):
return "%s,%s,%s"%(self.mac, self.bridge, self.type)

View File

@ -0,0 +1,497 @@
'''
Created on May 17, 2011
@author: frank
'''
from OvmCommonModule import *
from OvmDiskModule import *
from OvmVifModule import *
from OvmHostModule import OvmHost
from string import Template
from OVSXXenVMConfig import *
from OVSSiteVM import start_vm, stop_vm, reset_vm
from OVSSiteCluster import *
from OvmStoragePoolModule import OvmStoragePool
from OVSXXenStore import xen_get_vm_path, xen_get_vnc_port
from OVSDB import db_get_vm
from OVSXMonitor import xen_get_vm_perf_metrics, xen_get_xm_info
from OVSXXenVM import xen_migrate_vm
from OVSSiteRMVM import unregister_vm, register_vm
from OVSSiteVMInstall import install_vm_hvm
from OVSSiteRMServer import get_master_ip
from OVSXXenVMInstall import xen_change_vm_cdrom
from OVSXAPIUtil import XenAPIObject, session_login, session_logout
logger = OvmLogger("OvmVm")
class OvmVmDecoder(json.JSONDecoder):
def decode(self, jStr):
deDict = asciiLoads(jStr)
vm = OvmVm()
setAttrFromDict(vm, 'cpuNum', deDict, int)
setAttrFromDict(vm, 'memory', deDict, long)
setattr(vm, 'rootDisk', toOvmDisk(deDict['rootDisk']))
setattr(vm, 'vifs', toOvmVifList(deDict['vifs']))
setattr(vm, 'disks', toOvmDiskList(deDict['disks']))
setAttrFromDict(vm, 'name', deDict)
setAttrFromDict(vm, 'uuid', deDict)
setAttrFromDict(vm, 'bootDev', deDict)
setAttrFromDict(vm, 'type', deDict)
return vm
class OvmVmEncoder(json.JSONEncoder):
def default(self, obj):
if not isinstance(obj, OvmVm): raise Exception("%s is not instance of OvmVm"%type(obj))
dct = {}
safeDictSet(obj, dct, 'cpuNum')
safeDictSet(obj, dct, 'memory')
safeDictSet(obj, dct, 'powerState')
safeDictSet(obj, dct, 'name')
safeDictSet(obj, dct, 'type')
vifs = fromOvmVifList(obj.vifs)
dct['vifs'] = vifs
rootDisk = fromOvmDisk(obj.rootDisk)
dct['rootDisk'] = rootDisk
disks = fromOvmDiskList(obj.disks)
dct['disks'] = disks
return dct
def toOvmVm(jStr):
return json.loads(jStr, cls=OvmVmDecoder)
def fromOvmVm(vm):
return normalizeToGson(json.dumps(vm, cls=OvmVmEncoder))
class OvmVm(OvmObject):
cpuNum = 0
memory = 0
rootDisk = None
vifs = []
disks = []
powerState = ''
name = ''
bootDev = ''
type = ''
def _getVifs(self, vmName):
vmPath = OvmHost()._vmNameToPath(vmName)
domId = OvmHost()._getDomainIdByName(vmName)
vifs = successToMap(xen_get_vifs(vmPath))
lst = []
for k in vifs:
v = vifs[k]
vifName = 'vif' + domId + '.' + k[len('vif'):]
vif = OvmVif()
(mac, bridge, type) = v.split(',')
safeSetAttr(vif, 'name', vifName)
safeSetAttr(vif, 'mac', mac)
safeSetAttr(vif, 'bridge', bridge)
safeSetAttr(vif, 'type', type)
lst.append(vif)
return lst
def _getVifsFromConfig(self, vmPath):
vifs = successToMap(xen_get_vifs(vmPath))
lst = []
for k in vifs:
v = vifs[k]
vif = OvmVif()
(mac, bridge, type) = v.split(',')
safeSetAttr(vif, 'name', k)
safeSetAttr(vif, 'mac', mac)
safeSetAttr(vif, 'bridge', bridge)
safeSetAttr(vif, 'type', type)
lst.append(vif)
return lst
def _getIsoMountPath(self, vmPath):
vmName = basename(vmPath)
priStoragePath = vmPath.rstrip(join('running_pool', vmName))
return join(priStoragePath, 'iso_pool', vmName)
def _getVmTypeFromConfigFile(self, vmPath):
vmType = successToMap(xen_get_vm_type(vmPath))['type']
return vmType.replace('hvm', 'HVM').replace('para', 'PV')
@staticmethod
def create(jsonString):
def dumpCfg(vmName, cfgPath):
cfgFd = open(cfgPath, 'r')
cfg = cfgFd.readlines()
cfgFd.close()
logger.info(OvmVm.create, "Start %s with configure:\n\n%s\n"%(vmName, "".join(cfg)))
def setVifsType(vifs, type):
for vif in vifs:
vif.type = type
def hddBoot(vm, vmPath):
vmType = vm.type
if vmType == "FROMCONFIGFILE":
vmType = OvmVm()._getVmTypeFromConfigFile(vmPath)
cfgDict = {}
if vmType == "HVM":
cfgDict['builder'] = "'hvm'"
cfgDict['acpi'] = "1"
cfgDict['apic'] = "1"
cfgDict['device_model'] = "'/usr/lib/xen/bin/qemu-dm'"
cfgDict['kernel'] = "'/usr/lib/xen/boot/hvmloader'"
vifType = 'ioemu'
else:
cfgDict['bootloader'] = "'/usr/bin/pygrub'"
vifType = 'netfront'
cfgDict['name'] = "'%s'"%vm.name
cfgDict['disk'] = "[]"
cfgDict['vcpus'] = "''"
cfgDict['memory'] = "''"
cfgDict['on_crash'] = "'destroy'"
cfgDict['on_reboot'] = "'restart'"
cfgDict['vif'] = "[]"
items = []
for k in cfgDict.keys():
item = " = ".join([k, cfgDict[k]])
items.append(item)
vmSpec = "\n".join(items)
vmCfg = open(join(vmPath, 'vm.cfg'), 'w')
vmCfg.write(vmSpec)
vmCfg.close()
setVifsType(vm.vifs, vifType)
raiseExceptionIfFail(xen_set_vcpus(vmPath, vm.cpuNum))
raiseExceptionIfFail(xen_set_memory(vmPath, BytesToM(vm.memory)))
raiseExceptionIfFail(xen_add_disk(vmPath, vm.rootDisk.path, mode=vm.rootDisk.type))
vifs = [OvmVif.toXenString(v) for v in vm.vifs]
for vif in vifs:
raiseExceptionIfFail(xen_set_vifs(vmPath, vif))
for disk in vm.disks:
raiseExceptionIfFail(xen_add_disk(vmPath, disk.path, mode=disk.type))
raiseExceptionIfFail(xen_set_vm_vnc_password(vmPath, ""))
cfgFile = join(vmPath, 'vm.cfg')
# only HVM supports attaching cdrom
if vmType == 'HVM':
# Add an empty "hdc:cdrom" entry in config. Fisrt we set boot order to 'd' that is cdrom boot,
# then 'hdc:cdrom' entry will be in disk list. Second, change boot order to 'c' which
# is harddisk boot. VM can not start with an empty 'hdc:cdrom' when boot order is 'd'.
# it's tricky !
raiseExceptionIfFail(xen_config_boot_sequence(vmPath, 'd'))
raiseExceptionIfFail(xen_config_boot_sequence(vmPath, 'c'))
raiseExceptionIfFail(xen_correct_cfg(cfgFile, vmPath))
xen_correct_qos_cfg(cfgFile)
dumpCfg(vm.name, cfgFile)
server = successToMap(get_master_ip())['ip']
raiseExceptionIfFail(start_vm(vmPath, server))
rs = SUCC()
return rs
def cdBoot(vm, vmPath):
isoMountPath = None
try:
cdrom = None
for disk in vm.disks:
if disk.isIso == True:
cdrom = disk
break
if not cdrom: raise Exception("Cannot find Iso in disks")
isoOnSecStorage = dirname(cdrom.path)
isoName = basename(cdrom.path)
isoMountPath = OvmVm()._getIsoMountPath(vmPath)
OvmStoragePool()._mount(isoOnSecStorage, isoMountPath)
isoPath = join(isoMountPath, isoName)
if not exists(isoPath):
raise Exception("Cannot found iso %s at %s which mounts to %s"%(isoName, isoOnSecStorage, isoMountPath))
stdout = run_cmd(args=['file', isoPath])
if not stdout.strip().endswith("(bootable)"): raise Exception("ISO %s is not bootable"%cdrom.path)
#now alter cdrom to correct path
cdrom.path = isoPath
if len(vm.vifs) != 0:
vif = vm.vifs[0]
#ISO boot must be HVM
vifCfg = ','.join([vif.mac, vif.bridge, 'ioemu'])
else:
vifCfg = ''
rootDiskSize = os.path.getsize(vm.rootDisk.path)
rooDiskCfg = ':'.join([join(vmPath, basename(vm.rootDisk.path)), str(BytesToG(rootDiskSize)), 'True'])
disks = [rooDiskCfg]
for d in vm.disks:
if d.isIso: continue
size = os.path.getsize(d.path)
cfg = ':'.join([d.path, str(BytesToG(size)), 'True'])
disks.append(cfg)
disksCfg = ','.join(disks)
server = successToMap(get_master_ip())['ip']
raiseExceptionIfFail(install_vm_hvm(vmPath, BytesToM(vm.memory), vm.cpuNum, vifCfg, disksCfg, cdrom.path, vncpassword='', dedicated_server=server))
rs = SUCC()
return rs
except Exception, e:
if isoMountPath and OvmStoragePool()._isMounted(isoMountPath):
doCmd(['umount', '-f', isoMountPath])
errmsg = fmt_err_msg(e)
raise Exception(errmsg)
try:
vm = toOvmVm(jsonString)
logger.debug(OvmVm.create, "creating vm, spec:%s"%jsonString)
rootDiskPath = vm.rootDisk.path
if not exists(rootDiskPath): raise Exception("Cannot find root disk %s"%rootDiskPath)
rootDiskDir = dirname(rootDiskPath)
vmPath = join(dirname(rootDiskDir), vm.name)
if not exists(vmPath):
doCmd(['ln', '-s', rootDiskDir, vmPath])
vmNameFile = open(join(rootDiskDir, 'vmName'), 'w')
vmNameFile.write(vm.name)
vmNameFile.close()
if vm.bootDev == "HDD":
return hddBoot(vm, vmPath)
elif vm.bootDev == "CD":
return cdBoot(vm, vmPath)
else:
raise Exception("Unkown bootdev %s for %s"%(vm.bootDev, vm.name))
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmVm.create, errmsg)
raise XmlRpcFault(toErrCode(OvmVm, OvmVm.create), errmsg)
@staticmethod
def stop(vmName):
try:
try:
OvmHost()._getDomainIdByName(vmName)
except NoVmFoundException, e:
logger.info(OvmVm.stop, "vm %s is already stopped"%vmName)
return SUCC()
logger.info(OvmVm.stop, "Stop vm %s"%vmName)
vmPath = OvmHost()._vmNameToPath(vmName)
raiseExceptionIfFail(stop_vm(vmPath))
return SUCC()
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmVm.stop, errmsg)
raise XmlRpcFault(toErrCode(OvmVm, OvmVm.stop), errmsg)
@staticmethod
def reboot(vmName):
try:
#===================================================================
# Xend has a bug of reboot. If reboot vm too quick, xend return success
# but actually it refused reboot (seen from log)
# vmPath = successToMap(xen_get_vm_path(vmName))['path']
# raiseExceptionIfFail(reset_vm(vmPath))
#===================================================================
vmPath = OvmHost()._vmNameToPath(vmName)
OvmVm.stop(vmName)
raiseExceptionIfFail(start_vm(vmPath))
vncPort= successToMap(xen_get_vnc_port(vmName))['vnc_port']
logger.info(OvmVm.stop, "reboot vm %s, new vncPort is %s"%(vmName, vncPort))
return toGson({"vncPort":str(vncPort)})
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmVm.reboot, errmsg)
raise XmlRpcFault(toErrCode(OvmVm, OvmVm.reboot), errmsg)
@staticmethod
def getDetails(vmName):
try:
vm = OvmVm()
try:
OvmHost()._getDomainIdByName(vmName)
vmPath = OvmHost()._vmNameToPath(vmName)
vifsFromConfig = False
except NoVmFoundException, e:
vmPath = OvmHost()._getVmPathFromPrimaryStorage(vmName)
vifsFromConfig = True
if not isdir(vmPath):
# The case is, when vm starting was not completed at primaryStroageDownload or createVolume(e.g. mgmt server stop), the mgmt
# server will keep vm state in staring, then a stop command will be sent. The stop command will delete bridges that vm attaches,
# by retriving birdge info by OvmVm.getDetails(). In this case, the vm doesn't exists, so returns a fake object here.
fakeDisk = OvmDisk()
vm.rootDisk = fakeDisk
else:
if vifsFromConfig:
vm.vifs.extend(vm._getVifsFromConfig(vmPath))
else:
vm.vifs.extend(vm._getVifs(vmName))
safeSetAttr(vm, 'name', vmName)
disks = successToMap(xen_get_vdisks(vmPath))['vdisks'].split(',')
rootDisk = None
#BUG: there is no way to get type of disk, assume all are "w"
for d in disks:
if vmName in d:
rootDisk = OvmDisk()
safeSetAttr(rootDisk, 'path', d)
safeSetAttr(rootDisk, 'type', "w")
continue
disk = OvmDisk()
safeSetAttr(disk, 'path', d)
safeSetAttr(disk, 'type', "w")
vm.disks.append(disk)
if not rootDisk: raise Exception("Cannot find root disk for vm %s"%vmName)
safeSetAttr(vm, 'rootDisk', rootDisk)
vcpus = int(successToMap(xen_get_vcpus(vmPath))['vcpus'])
safeSetAttr(vm, 'cpuNum', vcpus)
memory = MtoBytes(int(successToMap(xen_get_memory(vmPath))['memory']))
safeSetAttr(vm, 'memory', memory)
vmStatus = db_get_vm(vmPath)
safeSetAttr(vm, 'powerState', vmStatus['status'])
vmType = successToMap(xen_get_vm_type(vmPath))['type'].replace('hvm', 'HVM').replace('para', 'PV')
safeSetAttr(vm, 'type', vmType)
rs = fromOvmVm(vm)
logger.info(OvmVm.getDetails, rs)
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmVm.getDetails, errmsg)
raise XmlRpcFault(toErrCode(OvmVm, OvmVm.getDetails), errmsg)
@staticmethod
def getVmStats(vmName):
def getVcpuNumAndUtils():
try:
session = session_login()
refs = session.xenapi.VM.get_by_name_label(vmName)
if len(refs) == 0:
raise Exception("No ref for %s found in xenapi VM objects"%vmName)
vm = XenAPIObject('VM', session, refs[0])
VM_metrics = XenAPIObject("VM_metrics", session, vm.get_metrics())
items = VM_metrics.get_VCPUs_utilisation().items()
nvCpus = len(items)
if nvCpus == 0:
raise Exception("vm %s has 0 vcpus !!!"%vmName)
xmInfo = successToMap(xen_get_xm_info())
nCpus = int(xmInfo['nr_cpus'])
totalUtils = 0.0
# CPU utlization of VM = (total cpu utilization of each vcpu) / number of physical cpu
for num, util in items:
totalUtils += float(util)
avgUtils = float(totalUtils/nCpus) * 100
return (nvCpus, avgUtils)
finally:
session_logout()
try:
try:
OvmHost()._getDomainIdByName(vmName)
vmPath = OvmHost()._vmNameToPath(vmName)
(nvcpus, avgUtils) = getVcpuNumAndUtils()
vifs = successToMap(xen_get_vifs(vmPath))
rxBytes = 0
txBytes = 0
vifs = OvmVm()._getVifs(vmName)
for vif in vifs:
rxp = join('/sys/class/net', vif.name, 'statistics/rx_bytes')
txp = join("/sys/class/net/", vif.name, "statistics/tx_bytes")
if not exists(rxp): raise Exception('can not find %s'%rxp)
if not exists(txp): raise Exception('can not find %s'%txp)
rxBytes += long(doCmd(['cat', rxp])) / 1000
txBytes += long(doCmd(['cat', txp])) / 1000
except NoVmFoundException, e:
vmPath = OvmHost()._getVmPathFromPrimaryStorage(vmName)
nvcpus = int(successToMap(xen_get_vcpus(vmPath))['vcpus'])
avgUtils = 0
rxBytes = 0
txBytes = 0
rs = toGson({"cpuNum":nvcpus, "cpuUtil":avgUtils, "rxBytes":rxBytes, "txBytes":txBytes})
logger.debug(OvmVm.getVmStats, rs)
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmVm.getVmStats, errmsg)
raise XmlRpcFault(toErrCode(OvmVm, OvmVm.getVmStats), errmsg)
@staticmethod
def migrate(vmName, targetHost):
try:
vmPath = OvmHost()._vmNameToPath(vmName)
raiseExceptionIfFail(xen_migrate_vm(vmPath, targetHost))
unregister_vm(vmPath)
return SUCC()
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmVm.migrate, errmsg)
raise XmlRpcFault(toErrCode(OvmVm, OvmVm.migrate), errmsg)
@staticmethod
def register(vmName):
try:
vmPath = OvmHost()._vmNameToPath(vmName)
raiseExceptionIfFail(register_vm(vmPath))
vncPort= successToMap(xen_get_vnc_port(vmName))['vnc_port']
rs = toGson({"vncPort":str(vncPort)})
logger.debug(OvmVm.register, rs)
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmVm.register, errmsg)
raise XmlRpcFault(toErrCode(OvmVm, OvmVm.register), errmsg)
@staticmethod
def getVncPort(vmName):
try:
vncPort= successToMap(xen_get_vnc_port(vmName))['vnc_port']
rs = toGson({"vncPort":vncPort})
logger.debug(OvmVm.getVncPort, rs)
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmVm.getVncPort, errmsg)
raise XmlRpcFault(toErrCode(OvmVm, OvmVm.getVncPort), errmsg)
@staticmethod
def detachOrAttachIso(vmName, iso, isAttach):
try:
if vmName in OvmHost.getAllVms():
scope = 'both'
vmPath = OvmHost()._vmNameToPath(vmName)
else:
scope = 'cfg'
vmPath = OvmHost()._getVmPathFromPrimaryStorage(vmName)
vmType = OvmVm()._getVmTypeFromConfigFile(vmPath)
if vmType != 'HVM':
raise Exception("Only HVM supports attaching/detaching ISO")
if not isAttach:
iso = ''
else:
isoName = basename(iso)
isoMountPoint = OvmVm()._getIsoMountPath(vmPath)
isoOnSecStorage = dirname(iso)
OvmStoragePool()._mount(isoOnSecStorage, isoMountPoint)
iso = join(isoMountPoint, isoName)
exceptionIfNoSuccess(xen_change_vm_cdrom(vmPath, iso, scope))
return SUCC()
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmVm.detachOrAttachIso, errmsg)
raise XmlRpcFault(toErrCode(OvmVm, OvmVm.detachOrAttachIso), errmsg)
if __name__ == "__main__":
import sys
print OvmVm.getDetails(sys.argv[1])
#print OvmVm.getVmStats(sys.argv[1])

View File

@ -0,0 +1,144 @@
'''
Created on June 2, 2011
@author: frank
'''
from OvmCommonModule import *
from OvmStoragePoolModule import OvmStoragePool
from OVSXUtility import xen_create_disk
from OvmHostModule import OvmHost
import os
logger = OvmLogger("OvmVolume")
class OvmVolumeDecoder(json.JSONDecoder):
def decode(self, jStr):
deDict = asciiLoads(jStr)
vol = OvmVolume()
setAttrFromDict(vol, 'uuid', deDict)
setAttrFromDict(vol, 'size', deDict, long)
setAttrFromDict(vol, 'poolUuid', deDict)
return vol
class OvmVolumeEncoder(json.JSONEncoder):
def default(self, obj):
if not isinstance(obj, OvmVolume): raise Exception("%s is not instance of OvmVolume"%type(obj))
dct = {}
safeDictSet(obj, dct, 'name')
safeDictSet(obj, dct, 'uuid')
safeDictSet(obj, dct, 'poolUuid')
safeDictSet(obj, dct, 'path')
safeDictSet(obj, dct, 'size')
return dct
def toOvmVolume(jStr):
return json.loads(jStr, cls=OvmVolumeDecoder)
def fromOvmVlolume(vol):
return normalizeToGson(json.dumps(vol, cls=OvmVolumeEncoder))
class OvmVolume(OvmObject):
name = ''
uuid = ''
poolUuid = ''
path = ''
size = 0
@staticmethod
def createDataDisk(poolUuid, size, isRoot):
try:
vol = OvmVolume()
vol.size = long(size)
vol.poolUuid = poolUuid
pool = OvmStoragePool()
sr = pool._getSrByNameLable(vol.poolUuid)
if isRoot:
path = join(sr.mountpoint, 'running_pool', get_uuid())
else:
path = join(sr.mountpoint, 'shareDisk')
if not exists(path): os.makedirs(path)
freeSpace = pool._getSpaceinfoOfDir(path)
if freeSpace < vol.size:
raise Exception("%s has not enough space (available:%s, required:%s"%(path, freeSpace, vol.size))
vol.uuid = get_uuid()
vol.name = vol.uuid + '.raw'
filePath = join(path, vol.name)
exceptionIfNoSuccess(xen_create_disk(filePath, BytesToM(vol.size)), "Create datadisk %s failed"%filePath)
vol.path = filePath
rs = fromOvmVlolume(vol)
logger.debug(OvmVolume.createDataDisk, rs)
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmVolume.createDataDisk, errmsg)
raise XmlRpcFault(toErrCode(OvmVolume, OvmVolume.createDataDisk, errmsg))
@staticmethod
def createFromTemplate(poolUuid, templateUrl):
try:
if not exists(templateUrl):
raise Exception("Cannot find template:%s"%templateUrl)
sr = OvmStoragePool()._getSrByNameLable(poolUuid)
volDirUuid = get_uuid()
volUuid = get_uuid()
priStorageMountPoint = sr.mountpoint
volDir = join(priStorageMountPoint, 'running_pool', volDirUuid)
if exists(volDir):
raise Exception("Volume dir %s alreay existed, can not override"%volDir)
os.makedirs(volDir)
OvmStoragePool()._checkDirSizeForImage(volDir, templateUrl)
volName = volUuid + '.raw'
tgt = join(volDir, volName)
cpVolCmd = ['cp', templateUrl, tgt]
doCmd(cpVolCmd)
volSize = os.path.getsize(tgt)
vol = OvmVolume()
vol.name = volName
vol.path = tgt
vol.size = volSize
vol.uuid = volUuid
vol.poolUuid = poolUuid
rs = fromOvmVlolume(vol)
logger.debug(OvmVolume.createFromTemplate, rs)
return rs
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmVolume.createFromTemplate, errmsg)
raise XmlRpcFault(toErrCode(OvmVolume, OvmVolume.createFromTemplate), errmsg)
@staticmethod
def destroy(poolUuid, path):
try:
OvmStoragePool()._getSrByNameLable(poolUuid)
if not exists(path): raise Exception("Cannot find %s"%path)
dir = dirname(path)
if exists(join(dir, 'vm.cfg')):
# delete root disk
vmNamePath = join(dir, 'vmName')
if exists(vmNamePath):
vmNameFd = open(vmNamePath, 'r')
vmName = vmNameFd.readline()
vmName = vmName.rstrip('\n')
link = join(dirname(dir), vmName)
doCmd(['rm', '-rf', link])
vmNameFd.close()
else:
logger.warning(OvmVolume.destroy, "Can not find vmName file in %s"%dir)
doCmd(['rm','-rf', dir])
else:
doCmd(['rm', path])
return SUCC()
except Exception, e:
errmsg = fmt_err_msg(e)
logger.error(OvmVolume.destroy, errmsg)
raise XmlRpcFault(toErrCode(OvmVolume, OvmVolume.destroy), errmsg)
if __name__ == "__main__":
print OvmVolume.detachOrAttachIso(sys.argv[1], '', False)

View File

@ -0,0 +1,112 @@
#!/bin/sh
errExit() {
echo $@
exit 1
}
stopHeartbeat() {
pidFile="/var/run/ovs-agent/heartbeat.pid"
if [ -f $pidFile ]; then
pid=`cat $pidFile`
ps -p $pid &>/dev/null
if [ $? -eq 0 ]; then
kill $pid &>/dev/null
fi
fi
}
openPortOnIptables() {
port="$1"
protocol="$2"
chkconfig --list iptables | grep "on"
if [ $? -eq 0 ]; then
iptables-save | grep "A INPUT -p $protocol -m $protocol --dport $port -j ACCEPT" >/dev/null
if [ $? -ne 0 ]; then
iptables -I INPUT 1 -p $protocol --dport $port -j ACCEPT
if [ $? -ne 0 ]; then
exit_with_error "iptables -I INPUT 1 -p $protocol --dport $port -j ACCEPT failed"
fi
echo "iptables:Open $protocol port $port for DHCP"
fi
fi
}
applyPatch() {
patchFile="$1"
level="$2"
[ ! -f $patchFile ] && errExit "Can not find $patchFile"
if [ $? -ne 0 ]; then
pushd /opt/ovs-agent-latest &>/dev/null
test=`patch -p$level --dry-run -N < $patchFile`
if [ $? -ne 0 ]; then
tmp=`mktemp`
echo $test > $tmp
grep "Reversed (or previously applied) patch detected" $tmp &>/dev/null
if [ $? -eq 0 ]; then
# The file has been patched
rm $tmp -f
popd &>/dev/null
return
else
rm $tmp -f
popd &>/dev/null
errExit "Can not apply $patchFile beacuse $test"
fi
fi
patch -p$level < $patchFile
[ $? -ne 0 ] && errExit "Patch to $target failed"
popd &>/dev/null
fi
}
postSetup() {
openPortOnIptables 7777 tcp
openPortOnIptables 7777 udp
applyPatch "/opt/ovs-agent-latest/OvmPatch.patch" 2
applyPatch "/opt/ovs-agent-latest/OvmDontTouchOCFS2ClusterWhenAgentStart.patch" 1
stopHeartbeat
/etc/init.d/ovs-agent restart --disable-nowayout
[ $? -ne 0 ] && errExit "Restart ovs agent failed"
exit 0
}
preSetup() {
agentConfig="/etc/ovs-agent/agent.ini"
agentInitScript="/etc/init.d/ovs-agent"
[ ! -f $agentConfig ] && errExit "Can not find $agentConfig"
[ ! -f $agentInitScript ] && errExit "Can not find $agentInitScript"
version=`grep "version=" $agentInitScript | cut -d "=" -f 2`
[ x"$version" != x"2.3" ] && errExit "The OVS agent version is $version, we only support 2.3 now"
# disable SSL
sed -i 's/ssl=enable/ssl=disable/g' $agentConfig
[ $? -ne 0 ] && errExit "configure ovs agent to non ssl failed"
if [ ! -L /opt/ovs-agent-latest ]; then
eval $agentInitScript status | grep 'down' && $agentInitScript start
[ $? -ne 0 ] && errExit "Start ovs agent failed"
[ ! -L /opt/ovs-agent-latest ] && errExit "No link at /opt/ovs-agent-latest"
fi
exit 0
}
[ $# -ne 1 ] && errExit "Usage: configureOvm.sh command"
case "$1" in
preSetup)
preSetup
;;
postSetup)
postSetup
;;
*)
errExit "Valid commands: preSetup postSetup"
esac

View File

@ -0,0 +1,166 @@
package com.cloud.ovm.hypervisor;
import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.xmlrpc.XmlRpcException;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.exception.DiscoveryException;
import com.cloud.host.HostInfo;
import com.cloud.host.HostVO;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.ovm.object.Connection;
import com.cloud.ovm.object.OvmHost;
import com.cloud.resource.Discoverer;
import com.cloud.resource.DiscovererBase;
import com.cloud.resource.ServerResource;
import com.cloud.utils.component.Inject;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.ssh.SSHCmdHelper;
@Local(value=Discoverer.class)
public class OvmDiscoverer extends DiscovererBase implements Discoverer {
private static final Logger s_logger = Logger.getLogger(OvmDiscoverer.class);
@Inject ClusterDao _clusterDao;
protected OvmDiscoverer() {
}
@Override
public Map<? extends ServerResource, Map<String, String>> find(long dcId,
Long podId, Long clusterId, URI url, String username,
String password, List<String> hostTags) throws DiscoveryException {
Connection conn = null;
if (!url.getScheme().equals("http")) {
String msg = "urlString is not http so we're not taking care of the discovery for this: " + url;
s_logger.debug(msg);
return null;
}
if (clusterId == null) {
String msg = "must specify cluster Id when add host";
s_logger.debug(msg);
throw new CloudRuntimeException(msg);
}
if (podId == null) {
String msg = "must specify pod Id when add host";
s_logger.debug(msg);
throw new CloudRuntimeException(msg);
}
ClusterVO cluster = _clusterDao.findById(clusterId);
if(cluster == null || (cluster.getHypervisorType() != HypervisorType.Ovm)) {
if(s_logger.isInfoEnabled())
s_logger.info("invalid cluster id or cluster is not for Ovm hypervisors");
return null;
}
String agentUsername = _params.get("agentusername");
if (agentUsername == null) {
throw new CloudRuntimeException("Agent user name must be specified");
}
String agentPassword = _params.get("agentpassword");
if (agentPassword == null) {
throw new CloudRuntimeException("Agent password must be specified");
}
try {
String hostname = url.getHost();
InetAddress ia = InetAddress.getByName(hostname);
String hostIp = ia.getHostAddress();
String guid = UUID.nameUUIDFromBytes(hostIp.getBytes()).toString();
ClusterVO clu = _clusterDao.findById(clusterId);
if (clu.getGuid() == null) {
clu.setGuid("/root");
_clusterDao.update(clusterId, clu);
}
com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(hostIp, 22);
sshConnection.connect(null, 60000, 60000);
sshConnection = SSHCmdHelper.acquireAuthorizedConnection(hostIp, username, password);
if (sshConnection == null) {
throw new DiscoveryException(
String.format("Cannot connect to ovm host(IP=%1$s, username=%2$s, password=%3$s, discover failed", hostIp, username, password));
}
if (!SSHCmdHelper.sshExecuteCmd(sshConnection, "[ -f '/etc/ovs-agent/agent.ini' ]")) {
throw new DiscoveryException("Can not find /etc/ovs-agent/agent.ini " + hostIp);
}
Map<String, String> details = new HashMap<String, String>();
OvmResourceBase ovmResource = new OvmResourceBase();
details.put("ip", hostIp);
details.put("username", username);
details.put("password", password);
details.put("zone", Long.toString(dcId));
details.put("guid", guid);
details.put("pod", Long.toString(podId));
details.put("cluster", Long.toString(clusterId));
details.put("agentusername", agentUsername);
details.put("agentpassword", agentPassword);
Map<String, Object> params = new HashMap<String, Object>();
params.putAll(details);
ovmResource.configure("Ovm Server", params);
ovmResource.start();
conn = new Connection(hostIp, "oracle", agentPassword);
/* After resource start, we are able to execute our agent api*/
OvmHost.Details d = OvmHost.getDetails(conn);
details.put("agentVersion", d.agentVersion);
details.put(HostInfo.HOST_OS_KERNEL_VERSION, d.dom0KernelVersion);
details.put(HostInfo.HYPERVISOR_VERSION, d.hypervisorVersion);
Map<OvmResourceBase, Map<String, String>> resources = new HashMap<OvmResourceBase, Map<String, String>>();
resources.put(ovmResource, details);
return resources;
} catch (XmlRpcException e) {
s_logger.debug("XmlRpc exception, Unable to discover OVM: " + url, e);
return null;
} catch (UnknownHostException e) {
s_logger.debug("Host name resolve failed exception, Unable to discover OVM: " + url, e);
return null;
} catch (ConfigurationException e) {
s_logger.debug("Configure resource failed, Unable to discover OVM: " + url, e);
return null;
} catch (Exception e) {
s_logger.debug("Unable to discover OVM: " + url, e);
return null;
}
}
@Override
public void postDiscovery(List<HostVO> hosts, long msId)
throws DiscoveryException {
// TODO Auto-generated method stub
}
@Override
public boolean matchHypervisor(String hypervisor) {
return HypervisorType.Ovm.toString().equalsIgnoreCase(hypervisor);
}
@Override
public HypervisorType getHypervisorType() {
return HypervisorType.Ovm;
}
}

View File

@ -0,0 +1,45 @@
package com.cloud.ovm.hypervisor;
import javax.ejb.Local;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.hypervisor.HypervisorGuru;
import com.cloud.hypervisor.HypervisorGuruBase;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.GuestOSVO;
import com.cloud.storage.dao.GuestOSDao;
import com.cloud.utils.component.Inject;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
@Local(value=HypervisorGuru.class)
public class OvmGuru extends HypervisorGuruBase implements HypervisorGuru {
@Inject GuestOSDao _guestOsDao;
protected OvmGuru() {
super();
}
@Override
public HypervisorType getHypervisorType() {
return HypervisorType.Ovm;
}
@Override
public <T extends VirtualMachine> VirtualMachineTO implement(
VirtualMachineProfile<T> vm) {
VirtualMachineTO to = toVirtualMachineTO(vm);
to.setBootloader(vm.getBootLoaderType());
// Determine the VM's OS description
GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId());
to.setOs(guestOS.getDisplayName());
return to;
}
@Override
public boolean trackVmHostChange() {
return true;
}
}

View File

@ -0,0 +1,42 @@
package com.cloud.ovm.hypervisor;
import java.util.HashMap;
public class OvmHelper {
private static final HashMap<String, String> _ovmMap = new HashMap<String, String>();
public static final String ORACLE_LINUX = "Oracle Linux";
public static final String WINDOWS = "Windows";
static {
_ovmMap.put("Oracle Enterprise Linux 6.0 (32-bit)", ORACLE_LINUX);
_ovmMap.put("Oracle Enterprise Linux 6.0 (64-bit)", ORACLE_LINUX);
_ovmMap.put("Oracle Enterprise Linux 5.0 (32-bit)", ORACLE_LINUX);
_ovmMap.put("Oracle Enterprise Linux 5.0 (64-bit)", ORACLE_LINUX);
_ovmMap.put("Oracle Enterprise Linux 5.1 (32-bit)", ORACLE_LINUX);
_ovmMap.put("Oracle Enterprise Linux 5.1 (64-bit)", ORACLE_LINUX);
_ovmMap.put("Oracle Enterprise Linux 5.2 (32-bit)", ORACLE_LINUX);
_ovmMap.put("Oracle Enterprise Linux 5.2 (64-bit)", ORACLE_LINUX);
_ovmMap.put("Oracle Enterprise Linux 5.3 (32-bit)", ORACLE_LINUX);
_ovmMap.put("Oracle Enterprise Linux 5.3 (64-bit)", ORACLE_LINUX);
_ovmMap.put("Oracle Enterprise Linux 5.4 (32-bit)", ORACLE_LINUX);
_ovmMap.put("Oracle Enterprise Linux 5.4 (64-bit)", ORACLE_LINUX);
_ovmMap.put("Oracle Enterprise Linux 5.5 (32-bit)", ORACLE_LINUX);
_ovmMap.put("Oracle Enterprise Linux 5.5 (64-bit)", ORACLE_LINUX);
_ovmMap.put("Windows 7 (32-bit)", WINDOWS);
_ovmMap.put("Windows 7 (64-bit)", WINDOWS);
_ovmMap.put("Windows Server 2003 (32-bit)", WINDOWS);
_ovmMap.put("Windows Server 2003 (64-bit)", WINDOWS);
_ovmMap.put("Windows Server 2008 (32-bit)", WINDOWS);
_ovmMap.put("Windows Server 2008 (64-bit)", WINDOWS);
_ovmMap.put("Windows Server 2008 R2 (64-bit)", WINDOWS);
_ovmMap.put("Windows 2000 SP4 (32-bit)", WINDOWS);
_ovmMap.put("Windows Vista (32-bit)", WINDOWS);
_ovmMap.put("Windows XP SP2 (32-bit)", WINDOWS);
_ovmMap.put("Windows XP SP3 (32-bit)", WINDOWS);
}
public static String getOvmGuestType(String stdType) {
return _ovmMap.get(stdType);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,69 @@
package com.cloud.ovm.object;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.cloud.ovm.object.OvmHost.Details;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
public class Coder {
private static Gson _gson;
private static Gson _mapGson;
public static Object[] EMPTY_PARAMS = new Object[0];
private static class MapDecoder implements JsonDeserializer<Map<String, String>> {
@Override
public Map<String, String> deserialize(JsonElement arg0, Type arg1,
JsonDeserializationContext arg2) throws JsonParseException {
if (!arg0.isJsonObject()) {
throw new JsonParseException(arg0.toString() + " is not Json Object, cannot convert to map");
}
JsonObject objs = arg0.getAsJsonObject();
Map<String, String> map = new HashMap<String ,String>();
for (Entry<String, JsonElement> e : objs.entrySet()) {
if (!e.getValue().isJsonPrimitive()) {
throw new JsonParseException(e.getValue().toString() + " is not a Json primitive," + arg0 + " can not convert to map");
}
map.put(e.getKey(), e.getValue().getAsString());
}
return map;
}
}
static {
GsonBuilder _builder = new GsonBuilder();
_builder.registerTypeAdapter(Map.class, new MapDecoder());
_mapGson = _builder.create();
_gson = new Gson();
}
public static String toJson(Object obj) {
return _gson.toJson(obj);
}
public static <T> T fromJson(String str, Class<T> clz) {
return (T)_gson.fromJson(str, clz);
}
@SuppressWarnings("unchecked")
public static Map<String, String> mapFromJson(String str) {
return _mapGson.fromJson(str, Map.class);
}
public static List<String> listFromJson(String str) {
Type listType = new TypeToken<List<String>>() {}.getType();
return _gson.fromJson(str, listType);
}
}

View File

@ -0,0 +1,108 @@
package com.cloud.ovm.object;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.TimeZone;
import org.apache.log4j.Logger;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.TimingOutCallback;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
import com.cloud.utils.exception.CloudRuntimeException;
public class Connection {
private static final Logger s_logger = Logger.getLogger(Connection.class);
private XmlRpcClientConfigImpl _config = new XmlRpcClientConfigImpl();
XmlRpcClient _client;
String _username;
String _password;
String _ip;
Integer _port = 8899;
Boolean _isSsl = false;
private XmlRpcClient getXmlClient() {
XmlRpcClient client = new XmlRpcClient();
URL url;
try {
url = new URL("http://" + _ip + ":" + _port.toString());
_config.setTimeZone(TimeZone.getTimeZone("UTC"));
_config.setServerURL(url);
_config.setReplyTimeout(0); // disable, we use asyncexecute to control timeout
_config.setConnectionTimeout(6000);
_config.setBasicUserName(_username);
_config.setBasicPassword(_password);
client.setConfig(_config);
} catch (MalformedURLException e) {
throw new CloudRuntimeException(e.getMessage());
}
return client;
}
public Connection(String ip, Integer port, String username, String password) {
_ip = ip;
_port = port;
_username = username;
_password = password;
_client = getXmlClient();
}
public Connection(String ip, String username, String password) {
_ip = ip;
_username = username;
_password = password;
_client = getXmlClient();
}
public Object call(String method, Object[] params) throws XmlRpcException {
/* default timeout is 10 mins */
return callTimeoutInSec(method, params, 600);
}
public Object callTimeoutInSec(String method, Object[] params, int timeout) throws XmlRpcException {
TimingOutCallback callback = new TimingOutCallback(timeout * 1000);
Object[] mParams = new Object[params.length + 1];
mParams[0] = method;
for (int i=0; i<params.length; i++) {
mParams[i+1] = params[i];
}
s_logger.debug("Call Ovm agent: " + Coder.toJson(mParams));
long startTime = System.currentTimeMillis();
_client.executeAsync("OvmDispatch", mParams, callback);
try {
return callback.waitForResponse();
} catch (TimingOutCallback.TimeoutException to) {
throw to;
} catch (Throwable e) {
throw new XmlRpcException(-2, e.getMessage());
} finally {
long endTime = System.currentTimeMillis();
float during = (endTime - startTime) / 1000; // in secs
s_logger.debug("Ovm call " + method + " finished in " + during + " secs");
}
}
public String getIp() {
return _ip;
}
public Integer getPort() {
return _port;
}
public String getUserName() {
return _username;
}
public String getPassword() {
return _password;
}
public Boolean getIsSsl() {
return _isSsl;
}
}

View File

@ -0,0 +1,54 @@
package com.cloud.ovm.object;
import java.util.List;
import org.apache.xmlrpc.XmlRpcException;
public class OvmBridge extends OvmObject {
public static class Details {
public String name;
public String attach;
public List<String> interfaces;
public String toJson() {
return Coder.toJson(this);
}
}
public static void create(Connection c, Details d) throws XmlRpcException {
Object[] params = {d.toJson()};
c.call("OvmNetwork.createBridge", params);
}
public static void delete(Connection c, String name) throws XmlRpcException {
Object[] params = {name};
c.call("OvmNetwork.deleteBridge", params);
}
public static List<String> getAllBridges(Connection c) throws XmlRpcException {
String res = (String) c.call("OvmNetwork.getAllBridges", Coder.EMPTY_PARAMS);
return Coder.listFromJson(res);
}
public static String getBridgeByIp(Connection c, String ip) throws XmlRpcException {
Object[] params = {ip};
String res = (String) c.call("OvmNetwork.getBridgeByIp", params);
return Coder.mapFromJson(res).get("bridge");
}
public static void createVlanBridge(Connection c, OvmBridge.Details bDetails, OvmVlan.Details vDetails) throws XmlRpcException {
Object[] params = {bDetails.toJson(), vDetails.toJson()};
c.call("OvmNetwork.createVlanBridge", params);
}
public static void deleteVlanBridge(Connection c, String name) throws XmlRpcException {
Object[] params = {name};
c.call("OvmNetwork.deleteVlanBridge", params);
}
public static Details getDetails(Connection c, String name) throws XmlRpcException {
Object[] params = {name};
String res = (String) c.call("OvmNetwork.getBridgeDetails", params);
return Coder.fromJson(res, Details.class);
}
}

View File

@ -0,0 +1,15 @@
package com.cloud.ovm.object;
public class OvmDisk extends OvmObject {
public static final String WRITE = "w";
public static final String READ = "r";
public static final String SHAREDWRITE = "w!";
public static final String SHAREDREAD = "r!";
public static class Details {
public String type;
public String path;
public Boolean isIso;
}
}

View File

@ -0,0 +1,77 @@
package com.cloud.ovm.object;
import java.util.List;
import java.util.Map;
import org.apache.xmlrpc.XmlRpcException;
public class OvmHost extends OvmObject {
public static final String SITE = "site";
public static final String UTILITY = "utility";
public static final String XEN = "xen";
public static class Details {
public String masterIp;
public Integer cpuNum;
public Integer cpuSpeed;
public Long totalMemory;
public Long freeMemory;
public Long dom0Memory;
public String agentVersion;
public String name;
public String dom0KernelVersion;
public String hypervisorVersion;
public String toJson() {
return Coder.toJson(this);
}
}
public static void registerAsMaster(Connection c) throws XmlRpcException {
Object[] params = {c.getIp(), c.getUserName(), c.getPassword(), c.getPort(), c.getIsSsl()};
c.call("OvmHost.registerAsMaster", params);
}
public static void registerAsVmServer(Connection c) throws XmlRpcException {
Object[] params = {c.getIp(), c.getUserName(), c.getPassword(), c.getPort(), c.getIsSsl()};
c.call("OvmHost.registerAsVmServer", params);
}
public static Details getDetails(Connection c) throws XmlRpcException {
String res = (String)c.call("OvmHost.getDetails", Coder.EMPTY_PARAMS);
return Coder.fromJson(res, OvmHost.Details.class);
}
public static void ping(Connection c) throws XmlRpcException {
Object[] params = {c.getIp()};
c.call("OvmHost.ping", params);
}
public static Map<String, String> getPerformanceStats(Connection c, String bridge) throws XmlRpcException {
Object[] params = {bridge};
String res = (String) c.call("OvmHost.getPerformanceStats", params);
return Coder.mapFromJson(res);
}
public static Map<String, String> getAllVms(Connection c) throws XmlRpcException {
String res = (String) c.call("OvmHost.getAllVms", Coder.EMPTY_PARAMS);
return Coder.mapFromJson(res);
}
public static void setupHeartBeat(Connection c, String poolUuid, String ip) throws XmlRpcException {
Object[] params = {poolUuid, ip};
c.call("OvmHost.setupHeartBeat", params);
}
public static Boolean fence(Connection c, String ip) throws XmlRpcException {
Object[] params = {ip};
String res = (String)c.call("OvmHost.fence", params);
Map<String, String> result = Coder.mapFromJson(res);
return Boolean.parseBoolean(result.get("isLive"));
}
public static void pingAnotherHost(Connection c, String ip) throws XmlRpcException {
Object[] params = {ip};
c.call("OvmHost.pingAnotherHost", params);
}
}

View File

@ -0,0 +1,4 @@
package com.cloud.ovm.object;
public class OvmObject {
}

View File

@ -0,0 +1,38 @@
package com.cloud.ovm.object;
import org.apache.xmlrpc.XmlRpcException;
public class OvmSecurityGroup extends OvmObject {
// canBridgeFirewall
// cleanupRules
// defaultNetworkRulesUserVm
// addNetworkRules
// deleteAllNetworkRulesForVm
public static boolean canBridgeFirewall(Connection c) throws XmlRpcException {
Object[] params = {};
return (Boolean) c.call("OvmSecurityGroup.can_bridge_firewall", params);
}
public static boolean cleanupNetworkRules(Connection c) throws XmlRpcException {
Object[] params = {};
return (Boolean) c.call("OvmSecurityGroup.cleanup_rules", params);
}
public static boolean defaultNetworkRulesForUserVm(Connection c, String vmName, String vmId, String ipAddress, String macAddress, String vifName, String bridgeName) throws XmlRpcException {
Object[] params = {vmName, vmId, ipAddress, macAddress, vifName, bridgeName};
return (Boolean) c.call("OvmSecurityGroup.default_network_rules_user_vm", params);
}
public static boolean addNetworkRules(Connection c, String vmName, String vmId, String guestIp, String signature, String seqno, String vifMacAddress, String newRules, String vifDeviceName, String bridgeName) throws XmlRpcException {
Object[] params = {vmName, vmId, guestIp, signature, seqno, vifMacAddress, newRules, vifDeviceName, bridgeName};
return (Boolean) c.call("OvmSecurityGroup.add_network_rules", params);
}
public static boolean deleteAllNetworkRulesForVm(Connection c, String vmName, String vif) throws XmlRpcException {
Object[] params = {vmName, vif};
return (Boolean) c.call("OvmSecurityGroup.delete_all_network_rules_for_vm", params);
}
}

View File

@ -0,0 +1,70 @@
package com.cloud.ovm.object;
import java.util.Map;
import org.apache.xmlrpc.XmlRpcException;
import com.cloud.utils.Pair;
public class OvmStoragePool extends OvmObject {
public static final String NFS = "OVSSPNFS";
public static final String OCFS2 = "OVSSPOCFS2";
public static final String PARTITION = "OVSSPPartition";
public static class Details {
public String uuid;
public String type;
public String path;
public String mountPoint;
public Long totalSpace;
public Long freeSpace;
public Long usedSpace;
public String toJson() {
return Coder.toJson(this);
}
}
/**
* @param c: connection
* @param d: includes three fields {uuid, type, path}
* @throws XmlRpcException
*/
public static void create(Connection c, Details d) throws XmlRpcException {
Object[] params = {d.toJson()};
c.callTimeoutInSec("OvmStoragePool.create", params, 3600);
}
/**
*
* @param c: connection
* @param uuid: uuid of primary storage
* @return: Details with full fields
* @throws XmlRpcException
*/
public static Details getDetailsByUuid(Connection c, String uuid) throws XmlRpcException {
Object[] params = {uuid};
String res = (String)c.call("OvmStoragePool.getDetailsByUuid", params);
return Coder.fromJson(res, Details.class);
}
/**
*
* @param c: Connection
* @param uuid: Pool uuid
* @param from: secondary storage download path
* @return: <destenation path, size of template>
* @throws XmlRpcException
*/
public static Pair<String, Long> downloadTemplate(Connection c, String uuid, String from) throws XmlRpcException {
Object[] params = {uuid, from};
String res = (String) c.callTimeoutInSec("OvmStoragePool.downloadTemplate", params, 3600);
Map pair = Coder.mapFromJson(res);
return new Pair<String, Long>((String)pair.get("installPath"), Long.parseLong((String)pair.get("templateSize")));
}
public static void prepareOCFS2Nodes(Connection c, String clusterName, String nodes) throws XmlRpcException {
Object[] params = {clusterName, nodes};
c.call("OvmStoragePool.prepareOCFS2Nodes", params);
}
}

View File

@ -0,0 +1,14 @@
package com.cloud.ovm.object;
public class OvmVif extends OvmObject {
public static final String NETFRONT = "netfront";
public static final String IOEMU = "ioemu";
public static class Details {
public String name;
public String mac;
public String bridge;
public String type;
}
}

View File

@ -0,0 +1,27 @@
package com.cloud.ovm.object;
import org.apache.xmlrpc.XmlRpcException;
public class OvmVlan extends OvmObject {
public static class Details {
public String name;
public int vid;
public String pif;
public String toJson() {
return Coder.toJson(this);
}
}
public static String create(Connection c, Details d) throws XmlRpcException {
Object[] params = {d.toJson()};
String res = (String)c.call("OvmNetwork.createVlan", params);
Details ret = Coder.fromJson(res, Details.class);
return ret.name;
}
public static void delete(Connection c, String name) throws XmlRpcException {
Object[] params = {name};
c.call("OvmNetwork.deleteVlan", params);
}
}

View File

@ -0,0 +1,96 @@
package com.cloud.ovm.object;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.xmlrpc.XmlRpcException;
import com.cloud.ovm.object.OvmHost.Details;
public class OvmVm extends OvmObject {
public static final String CD = "CD";
public static final String HDD = "HDD";
public static final String HVM = "HVM";
public static final String PV = "PV";
public static final String FROMCONFIGFILE = "FROMCONFIGFILE";
public static class Details {
public int cpuNum;
public long memory;
public OvmDisk.Details rootDisk;
public List<OvmDisk.Details> disks;
public List<OvmVif.Details> vifs;
public String name;
public String uuid;
public String powerState;
public String bootDev;
public String type;
public Details() {
disks = new ArrayList<OvmDisk.Details>();
vifs = new ArrayList<OvmVif.Details>();
}
public String toJson() {
return Coder.toJson(this);
}
}
public OvmVm() {
}
/*********** XML RPC Call **************/
public static void create(Connection c, Details d) throws XmlRpcException {
Object[] params = {d.toJson()};
c.call("OvmVm.create", params);
}
public static Map<String, String> reboot(Connection c, String vmName) throws XmlRpcException {
Object[] params = {vmName};
String res = (String) c.call("OvmVm.reboot", params);
return Coder.mapFromJson(res);
}
public static void stop(Connection c, String vmName) throws XmlRpcException {
Object[] params = {vmName};
/* Agent will destroy vm if vm shutdowns failed due to timout after 10 mins, so we set timeout to 20 mins here*/
c.callTimeoutInSec("OvmVm.stop", params, 1200);
}
public static Details getDetails(Connection c, String vmName) throws XmlRpcException {
Object[] params = {vmName};
String res = (String)c.call("OvmVm.getDetails", params);
return Coder.fromJson(res, OvmVm.Details.class);
}
public static Map<String, String> getVmStats(Connection c, String vmName) throws XmlRpcException {
Object[] params = {vmName};
String res = (String)c.call("OvmVm.getVmStats", params);
return Coder.mapFromJson(res);
}
public static void migrate(Connection c, String vmName, String dest) throws XmlRpcException {
Object[] params = {vmName, dest};
c.call("OvmVm.migrate", params);
}
public static Map<String, String> register(Connection c, String vmName) throws XmlRpcException {
Object[] params = {vmName};
String res = (String) c.call("OvmVm.register", params);
return Coder.mapFromJson(res);
}
public static Integer getVncPort(Connection c, String vmName) throws XmlRpcException {
Object[] params = {vmName};
String res = (String) c.call("OvmVm.getVncPort", params);
Map<String, String> result = Coder.mapFromJson(res);
return Integer.parseInt(result.get("vncPort"));
}
public static void detachOrAttachIso(Connection c, String vmName, String iso, Boolean isAttach) throws XmlRpcException {
Object[] params = {vmName, iso, isAttach};
c.call("OvmVm.detachOrAttachIso", params);
}
}

View File

@ -0,0 +1,37 @@
package com.cloud.ovm.object;
import org.apache.xmlrpc.XmlRpcException;
public class OvmVolume extends OvmObject {
public static class Details {
public String name;
public String uuid;
public String poolUuid;
public Long size;
public String path;
public String toJson() {
return Coder.toJson(this);
}
}
public static Details createDataDsik(Connection c, String poolUuid, String size, Boolean isRoot) throws XmlRpcException {
Object[] params = {poolUuid, size, isRoot};
String res = (String) c.call("OvmVolume.createDataDisk", params);
Details result = Coder.fromJson(res, Details.class);
return result;
}
public static Details createFromTemplate(Connection c, String poolUuid, String templateUrl) throws XmlRpcException {
Object[] params = {poolUuid, templateUrl};
String res = (String) c.callTimeoutInSec("OvmVolume.createFromTemplate", params, 3600*3);
Details result = Coder.fromJson(res, Details.class);
return result;
}
public static void destroy(Connection c, String poolUuid, String path) throws XmlRpcException {
Object[] params = {poolUuid, path};
c.call("OvmVolume.destroy", params);
}
}

View File

@ -0,0 +1,167 @@
package com.cloud.ovm.object;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.cloud.utils.Pair;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class Test {
public static void main(String[] args) {
try {
/*Connection c = new Connection("192.168.105.155", "oracle", "password");
Utils util = new UtilsImpl(c);
Storage storage = new StorageImpl(c);
String[] res = util.listDir("/etc", 1);
for (String s : res) {
System.out.println(s);
}
Pool pool = new PoolImpl(c);
//pool.registerServer("192.168.105.155", Pool.ServerType.SITE);
//pool.registerServer("192.168.105.155", Pool.ServerType.UTILITY);
//pool.registerServer("192.168.105.155", Pool.ServerType.XEN);
System.out.println("Is:" + pool.isServerRegistered());
//String ip = pool.getMasterIp();
//System.out.println("IP:" + ip);
System.out.println(pool.getServerConfig());
System.out.println(pool.getServerXmInfo());
System.out.println(pool.getHostInfo());
System.out.println(pool.getAgentVersion());
String[] srs = storage.listSr();
for (int i=0; i<srs.length; i++) {
System.out.println(srs[i]);
}
String spuuid = storage.createSp(StorageType.OVSSPNFS, "192.168.110.232:/export/frank/nfs");
System.out.println(spuuid);
String sruuid = storage.createSr(spuuid, "hi");
System.out.println(sruuid);
storage.initSr();
Pair<Long, Long> spaceInfo = storage.getSrSpaceInfo("192.168.110.232:/export/frank/nfs");
System.out.println("Total:" + spaceInfo.first());
System.out.println("Free:" + spaceInfo.second());*/
OvmVm.Details vm = new OvmVm.Details();
vm.cpuNum = 1;
vm.memory = 512;
vm.name = "Test";
vm.uuid = "This-is-a-test";
OvmDisk.Details rootDisk = new OvmDisk.Details();
rootDisk.path = "/root/root.raw";
rootDisk.type = OvmDisk.WRITE;
vm.rootDisk = rootDisk;
OvmDisk.Details dataDisk = new OvmDisk.Details();
dataDisk.path = "/tmp/data.raw";
dataDisk.type = OvmDisk.SHAREDWRITE;
vm.disks.add(dataDisk);
vm.disks.add(dataDisk);
vm.disks.add(dataDisk);
vm.disks.add(dataDisk);
vm.disks.add(dataDisk);
OvmVif.Details vif = new OvmVif.Details();
vif.mac = "00:ff:ff:ff:ff:ee";
vif.bridge = "xenbr0";
vif.type = OvmVif.NETFRONT;
vm.vifs.add(vif);
vm.vifs.add(vif);
vm.vifs.add(vif);
vm.vifs.add(vif);
vm.vifs.add(vif);
//System.out.println(vm.toJson());
Connection c = new Connection("192.168.189.12", "oracle", "password");
//System.out.println(Coder.toJson(OvmHost.getDetails(c)));
String txt = "{\"MasterIp\": \"192.168.189.12\", \"dom0Memory\": 790626304, \"freeMemory\": 16378757120, \"totalMemory\": 17169383424, \"cpuNum\": 4, \"agentVersion\": \"2.3-38\", \"cpuSpeed\": 2261}";
//OvmHost.Details d = new GsonBuilder().create().fromJson(txt, OvmHost.Details.class);
//OvmHost.Details d = Coder.fromJson(txt, OvmHost.Details.class);
//OvmHost.Details d = OvmHost.getDetails(c);
//System.out.println(Coder.toJson(d));
// OvmStoragePool.Details pool = new OvmStoragePool.Details();
// pool.path = "192.168.110.232:/export/frank/ovs";
// pool.type = OvmStoragePool.NFS;
// pool.uuid = "123";
// System.out.println(pool.toJson());
String cmd = null;
System.out.println(args.length);
if (args.length >= 1) {
cmd = args[0];
OvmVm.Details d = new OvmVm.Details();
d.cpuNum = 1;
d.memory = 512 * 1024 * 1024;
d.name = "MyTest";
d.uuid = "1-2-3-4-5";
OvmDisk.Details r = new OvmDisk.Details();
r.path = "/var/ovs/mount/60D0985974CA425AAF5D01A1F161CC8B/running_pool/36_systemvm/System.img";
r.type = OvmDisk.WRITE;
d.rootDisk = r;
OvmVif.Details v = new OvmVif.Details();
v.mac = "00:16:3E:5C:B1:D1";
v.bridge = "xenbr0";
v.type = OvmVif.NETFRONT;
d.vifs.add(v);
System.out.println(d.toJson());
if (cmd.equalsIgnoreCase("create")) {
// String s =
// "{\"cpuNum\":1,\"memory\":512,\"rootDisk\":{\"type\":\"w\",\"path\":\"/var/ovs/mount/60D0985974CA425AAF5D01A1F161CC8B/running_pool/36_systemvm/System.img\"},\"disks\":[],\"vifs\":[{\"mac\":\"00:16:3E:5C:B1:D1\",\"bridge\":\"xenbr0\",\"type\":\"netfront\"}],\"name\":\"MyTest\",\"uuid\":\"1-2-3-4-5\"}";
OvmVm.create(c, d);
// c.call("OvmVm.echo", new Object[]{s});
} else if (cmd.equalsIgnoreCase("reboot")) {
Map<String, String> res = OvmVm.reboot(c, "MyTest");
System.out.println(res.get("vncPort"));
//OvmVm.stop(c, "MyTest");
//OvmVm.create(c, d);
} else if (cmd.equalsIgnoreCase("stop")) {
OvmVm.stop(c, "MyTest");
} else if (cmd.equalsIgnoreCase("details")) {
OvmVm.Details ddd = OvmVm.getDetails(c, "MyTest");
System.out.println(ddd.vifs.size());
System.out.println(ddd.rootDisk.path);
System.out.println(ddd.powerState);
} else if (cmd.equalsIgnoreCase("all")) {
System.out.println(OvmHost.getAllVms(c));
} else if (cmd.equalsIgnoreCase("createBridge")) {
OvmBridge.Details bd = new OvmBridge.Details();
bd.name = "xenbr10";
bd.attach = args[1];
OvmBridge.create(c, bd);
} else if (cmd.equalsIgnoreCase("createVlan")) {
OvmVlan.Details vd = new OvmVlan.Details();
vd.pif = "eth0";
vd.vid = 1000;
String vname = OvmVlan.create(c, vd);
System.out.println(vname);
} else if (cmd.equalsIgnoreCase("delVlan")) {
OvmVlan.delete(c, args[1]);
} else if (cmd.equalsIgnoreCase("delBr")) {
OvmBridge.delete(c, args[1]);
} else if (cmd.equalsIgnoreCase("getBrs")) {
List<String> brs = OvmBridge.getAllBridges(c);
System.out.println(brs);
} else if (cmd.equalsIgnoreCase("getBrDetails")) {
OvmBridge.Details brd = OvmBridge.getDetails(c, args[1]);
System.out.println(brd.interfaces);
}
}
List<String> l = new ArrayList<String>();
l.add("4b4d8951-f0b6-36c5-b4f3-a82ff2611c65");
System.out.println(Coder.toJson(l));
// Map<String, String> res = OvmHost.getPerformanceStats(c, "xenbr0");
// System.out.println(res.toString());
// String stxt = "{\"vifs\": [{\"bridge\": \"xenbr0\", \"mac\": \"00:16:3E:5C:B1:D1\", \"type\": \"netfront\"}], \"powerState\": \"RUNNING\", \"disks\": [], \"cpuNum\": 1, \"memory\": 536870912, \"rootDisk\": {\"path\": \"/var/ovs/mount/60D0985974CA425AAF5D01A1F161CC8B/running_pool/MyTest/System.img\", \"type\": \"w\"}}";
// OvmVm.Details ddd = Coder.fromJson(stxt, OvmVm.Details.class);
// System.out.println(ddd.vifs.size());
// System.out.println(ddd.rootDisk.path);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,20 @@
<rpc>
<load-configuration>
<configuration>
<access>
<profile>
<name>%access-profile-name%</name>
<client>
<name>%username%</name>
<firewall-user>
<password>%password%</password>
</firewall-user>
</client>
<address-assignment>
<pool>%address-pool-name%</pool>
</address-assignment>
</profile>
</access>
</configuration>
</load-configuration>
</rpc>

View File

@ -0,0 +1,10 @@
<rpc>
<get-configuration>
<configuration>
<access>
<profile>
</profile>
</access>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,11 @@
<rpc>
<get-configuration>
<configuration>
<access>
<profile %delete%>
<name>%access-profile-name%</name>
</profile>
</access>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,19 @@
<rpc>
<load-configuration>
<configuration>
<security>
<zones>
<security-zone>
<name>%zone%</name>
<address-book>
<address>
<name>%entry-name%</name>
<ip-prefix>%ip%</ip-prefix>
</address>
</address-book>
</security-zone>
</zones>
</security>
</configuration>
</load-configuration>
</rpc>

View File

@ -0,0 +1,15 @@
<rpc>
<get-configuration>
<configuration>
<security>
<zones>
<security-zone>
<name>%zone%</name>
<address-book>
</address-book>
</security-zone>
</zones>
</security>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,18 @@
<rpc>
<get-configuration>
<configuration>
<security>
<zones>
<security-zone>
<name>%zone%</name>
<address-book>
<address %delete%>
<name>%entry-name%</name>
</address>
</address-book>
</security-zone>
</zones>
</security>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,26 @@
<rpc>
<load-configuration>
<configuration>
<access>
<address-assignment>
<pool>
<name>%address-pool-name%</name>
<family>
<inet>
<network>%guest-network-cidr%</network>
<range>
<name>%address-range-name%</name>
<low>%low-address%</low>
<high>%high-address%</high>
</range>
<xauth-attributes>
<primary-dns>%primary-dns-address%</primary-dns>
</xauth-attributes>
</inet>
</family>
</pool>
</address-assignment>
</access>
</configuration>
</load-configuration>
</rpc>

View File

@ -0,0 +1,12 @@
<rpc>
<get-configuration>
<configuration>
<access>
<address-assignment>
<pool>
</pool>
</address-assignment>
</access>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,13 @@
<rpc>
<get-configuration>
<configuration>
<access>
<address-assignment>
<pool %delete%>
<name>%address-pool-name%</name>
</pool>
</address-assignment>
</access>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,13 @@
<rpc>
<load-configuration>
<configuration>
<applications>
<application>
<name>%name%</name>
<protocol>%protocol%</protocol>
<destination-port>%dest-port%</destination-port>
</application>
</applications>
</configuration>
</load-configuration>
</rpc>

View File

@ -0,0 +1,11 @@
<rpc>
<get-configuration>
<configuration>
<applications>
<application %delete%>
<name>%name%</name>
</application>
</applications>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,3 @@
<rpc>
<close-configuration/>
</rpc>

View File

@ -0,0 +1,4 @@
<rpc>
<commit-configuration>
</commit-configuration>
</rpc>

View File

@ -0,0 +1,19 @@
<rpc>
<load-configuration>
<configuration>
<security>
<nat>
<destination>
<pool>
<name>%pool-name%</name>
<address>
<ipaddr>%private-address%</ipaddr>
<port>%dest-port%</port>
</address>
</pool>
</destination>
</nat>
</security>
</configuration>
</load-configuration>
</rpc>

View File

@ -0,0 +1,12 @@
<rpc>
<get-configuration>
<configuration>
<security>
<nat>
<destination>
</destination>
</nat>
</security>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,15 @@
<rpc>
<get-configuration>
<configuration>
<security>
<nat>
<destination>
<pool %delete%>
<name>%pool-name%</name>
</pool>
</destination>
</nat>
</security>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,38 @@
<rpc>
<load-configuration>
<configuration>
<security>
<nat>
<destination>
<rule-set>
<name>%rule-set%</name>
<from><zone>%from-zone%</zone></from>
<rule>
<name>%rule-name%</name>
<dest-nat-rule-match>
<destination-address>
<dst-addr>%public-address%</dst-addr>
</destination-address>
<destination-port>
<dst-port>%src-port%</dst-port>
</destination-port>
</dest-nat-rule-match>
<then>
<destination-nat>
<pool>
<pool-name>%pool-name%</pool-name>
</pool>
</destination-nat>
</then>
</rule>
</rule-set>
</destination>
</nat>
</security>
</configuration>
</load-configuration>
</rpc>

View File

@ -0,0 +1,15 @@
<rpc>
<get-configuration>
<configuration>
<security>
<nat>
<destination>
<rule-set>
<name>%rule-set%</name>
</rule-set>
</destination>
</nat>
</security>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,20 @@
<rpc>
<get-configuration>
<configuration>
<security>
<nat>
<destination>
<rule-set>
<name>%from-zone%</name>
<rule %delete%>
<name>%rule-name%</name>
</rule>
</rule-set>
</destination>
</nat>
</security>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,29 @@
<rpc>
<load-configuration>
<configuration>
<security>
<dynamic-vpn>
<clients>
<name>%client-name%</name>
<remote-protected-resources>
<name>%guest-network-cidr%</name>
</remote-protected-resources>
<remote-exceptions>
<name>0.0.0.0/0</name>
</remote-exceptions>
<remote-exceptions>
<name>0.0.0.0/32</name>
</remote-exceptions>
<remote-exceptions>
<name>1.1.1.1/24</name>
</remote-exceptions>
<ipsec-vpn>%ipsec-vpn-name%</ipsec-vpn>
<user>
<name>%username%</name>
</user>
</clients>
</dynamic-vpn>
</security>
</configuration>
</load-configuration>
</rpc>

View File

@ -0,0 +1,12 @@
<rpc>
<get-configuration>
<configuration>
<security>
<dynamic-vpn>
<clients>
</clients>
</dynamic-vpn>
</security>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,13 @@
<rpc>
<get-configuration>
<configuration>
<security>
<dynamic-vpn>
<clients %delete%>
<name>%client-name%</name>
</clients>
</dynamic-vpn>
</security>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,11 @@
<rpc>
<get-configuration>
<configuration>
<firewall>
<filter %delete%>
<name>%filter-name%</name>
</filter>
</firewall>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,14 @@
<rpc>
<get-configuration>
<configuration>
<firewall>
<filter>
<name>%filter-name%</name>
<term %delete%>
<name>%term-name%</name>
</term>
</filter>
</firewall>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,5 @@
<rpc>
<get-firewall-information>
</get-firewall-information>
</rpc>

View File

@ -0,0 +1,18 @@
<rpc>
<load-configuration>
<configuration>
<firewall>
<filter>
<name>%filter-name%</name>
<term>
<name>%term-name%</name>
<then>
<count>%term-name%</count>
<accept/>
</then>
</term>
</filter>
</firewall>
</configuration>
</load-configuration>
</rpc>

View File

@ -0,0 +1,21 @@
<rpc>
<load-configuration>
<configuration>
<security>
<ike>
<gateway>
<name>%gateway-name%</name>
<ike-policy>%ike-policy-name%</ike-policy>
<dynamic>
<hostname>%ike-gateway-hostname%</hostname>
</dynamic>
<external-interface>%public-interface-name%</external-interface>
<xauth>
<access-profile>%access-profile-name%</access-profile>
</xauth>
</gateway>
</ike>
</security>
</configuration>
</load-configuration>
</rpc>

View File

@ -0,0 +1,12 @@
<rpc>
<get-configuration>
<configuration>
<security>
<ike>
<gateway>
</gateway>
</ike>
</security>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,13 @@
<rpc>
<get-configuration>
<configuration>
<security>
<ike>
<gateway %delete%>
<name>%gateway-name%</name>
</gateway>
</ike>
</security>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,18 @@
<rpc>
<load-configuration>
<configuration>
<security>
<ike>
<policy>
<name>%policy-name%</name>
<mode>aggressive</mode>
<proposals>%proposal-name%</proposals>
<pre-shared-key>
<ascii-text>%pre-shared-key%</ascii-text>
</pre-shared-key>
</policy>
</ike>
</security>
</configuration>
</load-configuration>
</rpc>

View File

@ -0,0 +1,12 @@
<rpc>
<get-configuration>
<configuration>
<security>
<ike>
<policy>
</policy>
</ike>
</security>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,13 @@
<rpc>
<get-configuration>
<configuration>
<security>
<ike>
<policy %delete%>
<name>%policy-name%</name>
</policy>
</ike>
</security>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,18 @@
<rpc>
<load-configuration>
<configuration>
<security>
<ipsec>
<vpn>
<name>%ipsec-vpn-name%</name>
<ike>
<gateway>%ike-gateway%</gateway>
<ipsec-policy>%ipsec-policy-name%</ipsec-policy>
</ike>
<establish-tunnels>on-traffic</establish-tunnels>
</vpn>
</ipsec>
</security>
</configuration>
</load-configuration>
</rpc>

View File

@ -0,0 +1,12 @@
<rpc>
<get-configuration>
<configuration>
<security>
<ipsec>
<vpn>
</vpn>
</ipsec>
</security>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,13 @@
<rpc>
<get-configuration>
<configuration>
<security>
<ipsec>
<vpn %delete%>
<name>%ipsec-vpn-name%</name>
</vpn>
</ipsec>
</security>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="us-ascii"?>
<junoscript version="1.0">
<rpc>
<request-login>
<username>
%username%
</username>
<challenge-response>
%password%
</challenge-response>
</request-login>
</rpc>
</junoscript>

View File

@ -0,0 +1,5 @@
<rpc>
<open-configuration>
<private/>
</open-configuration>
</rpc>

View File

@ -0,0 +1,23 @@
<rpc>
<load-configuration>
<configuration>
<interfaces>
<interface>
<name>%private-interface-name%</name>
<vlan-tagging/>
<unit>
<name>%vlan-id%</name>
<vlan-id>%vlan-id%</vlan-id>
<family>
<inet>
<address>
<name>%private-interface-ip%</name>
</address>
</inet>
</family>
</unit>
</interface>
</interfaces>
</configuration>
</load-configuration>
</rpc>

View File

@ -0,0 +1,11 @@
<rpc>
<get-configuration>
<configuration>
<interfaces>
<interface>
<name>%private-interface-name%</name>
</interface>
</interfaces>
</configuration>
</get-configuration>
</rpc>

View File

@ -0,0 +1,15 @@
<rpc>
<get-configuration>
<configuration>
<interfaces>
<interface>
<name>%private-interface-name%</name>
<vlan-tagging/>
<unit %delete%>
<name>%vlan-id%</name>
</unit>
</interface>
</interfaces>
</configuration>
</get-configuration>
</rpc>

Some files were not shown because too many files have changed in this diff Show More