Merge branch 'master' of ssh://git.cloud.com/var/lib/git/cloudstack-oss

This commit is contained in:
nit 2010-11-12 14:48:11 +05:30
commit b42458fa0d
189 changed files with 2665 additions and 25981 deletions

View File

@ -121,6 +121,8 @@ import com.cloud.agent.api.ReadyCommand;
import com.cloud.agent.api.RebootAnswer;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.RebootRouterCommand;
import com.cloud.agent.api.Start2Answer;
import com.cloud.agent.api.Start2Command;
import com.cloud.agent.api.StartAnswer;
import com.cloud.agent.api.StartCommand;
import com.cloud.agent.api.StartConsoleProxyAnswer;
@ -134,6 +136,8 @@ import com.cloud.agent.api.StartupRoutingCommand;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.VmStatsEntry;
import com.cloud.agent.api.check.CheckSshAnswer;
import com.cloud.agent.api.check.CheckSshCommand;
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
@ -145,28 +149,34 @@ import com.cloud.agent.api.storage.CreatePrivateTemplateCommand;
import com.cloud.agent.api.storage.DestroyCommand;
import com.cloud.agent.api.storage.DownloadAnswer;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.api.to.VolumeTO;
import com.cloud.agent.api.to.VirtualMachineTO.Monitor;
import com.cloud.agent.api.to.VirtualMachineTO.SshMonitor;
import com.cloud.agent.resource.computing.KVMHABase.NfsStoragePool;
import com.cloud.agent.resource.computing.KVMHABase.PoolType;
import com.cloud.agent.resource.computing.LibvirtStoragePoolDef.poolType;
import com.cloud.agent.resource.computing.LibvirtStorageVolumeDef.volFormat;
import com.cloud.agent.resource.computing.LibvirtVMDef.consoleDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.devicesDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.diskDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.featuresDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.graphicDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.guestDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.guestResourceDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.inputDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.interfaceDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.interfaceDef.hostNicType;
import com.cloud.agent.resource.computing.LibvirtVMDef.serialDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.termPolicy;
import com.cloud.agent.resource.computing.LibvirtVMDef.ConsoleDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.DevicesDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.DiskDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.FeaturesDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.GraphicDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.GuestDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.GuestResourceDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.InputDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.InterfaceDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.InterfaceDef.hostNicType;
import com.cloud.agent.resource.computing.LibvirtVMDef.SerialDef;
import com.cloud.agent.resource.computing.LibvirtVMDef.TermPolicy;
import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
import com.cloud.exception.InternalErrorException;
import com.cloud.host.Host.Type;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.Network.BroadcastDomainType;
import com.cloud.network.Network.TrafficType;
import com.cloud.network.NetworkEnums.RouterPrivateIpStrategy;
import com.cloud.resource.ServerResource;
import com.cloud.resource.ServerResourceBase;
@ -196,6 +206,7 @@ import com.cloud.vm.DiskProfile;
import com.cloud.vm.DomainRouter;
import com.cloud.vm.SecondaryStorageVmVO;
import com.cloud.vm.State;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineName;
@ -871,14 +882,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
protected synchronized String startDomainRouter(StartRouterCommand cmd) {
DomainRouter router = cmd.getRouter();
List<interfaceDef> nics = null;
List<InterfaceDef> nics = null;
try {
nics = createRouterVMNetworks(cmd);
List<diskDef> disks = createSystemVMDisk(cmd.getVolumes());
List<DiskDef> disks = createSystemVMDisk(cmd.getVolumes());
String dataDiskPath = null;
for (diskDef disk : disks) {
for (DiskDef disk : disks) {
if (disk.getDiskLabel().equalsIgnoreCase("vdb")) {
dataDiskPath = disk.getDiskPath();
}
@ -894,7 +905,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
startDomain(vmName, domXML);
for (interfaceDef nic : nics) {
for (InterfaceDef nic : nics) {
if (nic.getHostNetType() == hostNicType.VNET) {
disableBridgeForwardding(nic.getBrName());
}
@ -920,14 +931,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
protected synchronized String startConsoleProxy(StartConsoleProxyCommand cmd) {
ConsoleProxyVO console = cmd.getProxy();
List<interfaceDef> nics = null;
List<InterfaceDef> nics = null;
try {
nics = createSysVMNetworks(console.getGuestMacAddress(), console.getPrivateMacAddress(), console.getPublicMacAddress(), console.getVlanId());
List<diskDef> disks = createSystemVMDisk(cmd.getVolumes());
List<DiskDef> disks = createSystemVMDisk(cmd.getVolumes());
String dataDiskPath = null;
for (diskDef disk : disks) {
for (DiskDef disk : disks) {
if (disk.getDiskLabel().equalsIgnoreCase("vdb")) {
dataDiskPath = disk.getDiskPath();
}
@ -959,14 +970,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
protected String startSecStorageVM(StartSecStorageVmCommand cmd) {
SecondaryStorageVmVO secVm = cmd.getSecondaryStorageVmVO();
List<interfaceDef> nics = null;
List<InterfaceDef> nics = null;
try {
nics = createSysVMNetworks(secVm.getGuestMacAddress(), secVm.getPrivateMacAddress(), secVm.getPublicMacAddress(), secVm.getVlanId());
List<diskDef> disks = createSystemVMDisk(cmd.getVolumes());
List<DiskDef> disks = createSystemVMDisk(cmd.getVolumes());
String dataDiskPath = null;
for (diskDef disk : disks) {
for (DiskDef disk : disks) {
if (disk.getDiskLabel().equalsIgnoreCase("vdb")) {
dataDiskPath = disk.getDiskPath();
}
@ -995,61 +1006,61 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return null;
}
private String defineVMXML(String vmName, String uuid, int memSize, int cpus, String arch, List<interfaceDef> nics, List<diskDef> disks, String vncPaswd, String guestOSType) {
private String defineVMXML(String vmName, String uuid, int memSize, int cpus, String arch, List<InterfaceDef> nics, List<DiskDef> disks, String vncPaswd, String guestOSType) {
LibvirtVMDef vm = new LibvirtVMDef();
vm.setHvsType(_hypervisorType);
vm.setDomainName(vmName);
vm.setDomUUID(uuid);
vm.setDomDescription(KVMGuestOsMapper.getGuestOsName(guestOSType));
guestDef guest = new guestDef();
guest.setGuestType(guestDef.guestType.KVM);
GuestDef guest = new GuestDef();
guest.setGuestType(GuestDef.guestType.KVM);
guest.setGuestArch(arch);
guest.setMachineType("pc");
guest.setBootOrder(guestDef.bootOrder.CDROM);
guest.setBootOrder(guestDef.bootOrder.HARDISK);
guest.setBootOrder(GuestDef.bootOrder.CDROM);
guest.setBootOrder(GuestDef.bootOrder.HARDISK);
vm.addComp(guest);
guestResourceDef grd = new guestResourceDef();
GuestResourceDef grd = new GuestResourceDef();
grd.setMemorySize(memSize*1024);
grd.setVcpuNum(cpus);
vm.addComp(grd);
featuresDef features = new featuresDef();
FeaturesDef features = new FeaturesDef();
features.addFeatures("pae");
features.addFeatures("apic");
features.addFeatures("acpi");
vm.addComp(features);
termPolicy term = new termPolicy();
TermPolicy term = new TermPolicy();
term.setCrashPolicy("destroy");
term.setPowerOffPolicy("destroy");
term.setRebootPolicy("restart");
vm.addComp(term);
devicesDef devices = new devicesDef();
DevicesDef devices = new DevicesDef();
devices.setEmulatorPath(_hypervisorPath);
for (interfaceDef nic : nics) {
for (InterfaceDef nic : nics) {
devices.addDevice(nic);
}
for (diskDef disk : disks) {
for (DiskDef disk : disks) {
if (!disk.isAttachDeferred())
devices.addDevice(disk);
}
serialDef serial = new serialDef("pty", null, (short)0);
SerialDef serial = new SerialDef("pty", null, (short)0);
devices.addDevice(serial);
consoleDef console = new consoleDef("pty", null, null, (short)0);
ConsoleDef console = new ConsoleDef("pty", null, null, (short)0);
devices.addDevice(console);
graphicDef grap = new graphicDef("vnc", (short)0, true, null, null, null);
GraphicDef grap = new GraphicDef("vnc", (short)0, true, null, null, null);
devices.addDevice(grap);
inputDef input = new inputDef("tablet", "usb");
InputDef input = new InputDef("tablet", "usb");
devices.addDevice(input);
vm.addComp(devices);
@ -1234,8 +1245,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return execute((DeleteStoragePoolCommand) cmd);
} else if (cmd instanceof FenceCommand ) {
return execute((FenceCommand) cmd);
} else if (cmd instanceof Start2Command ) {
return execute((Start2Command) cmd);
} else if (cmd instanceof RoutingCommand) {
return _virtRouterResource.executeRequest(cmd);
} else if (cmd instanceof CheckSshCommand) {
return execute((CheckSshCommand) cmd);
} else {
s_logger.warn("Unsupported command ");
return Answer.createUnsupportedCommandAnswer(cmd);
@ -2553,14 +2568,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
protected synchronized String startVM(StartCommand cmd) {
List<interfaceDef> nics = null;
List<InterfaceDef> nics = null;
try {
String uuid = UUID.nameUUIDFromBytes(cmd.getVmName().getBytes()).toString();
nics = createUserVMNetworks(cmd);
List<diskDef> disks = createVMDisk(cmd.getVolumes(), cmd.getGuestOSDescription(), cmd.getISOPath());
List<DiskDef> disks = createVMDisk(cmd.getVolumes(), cmd.getGuestOSDescription(), cmd.getISOPath());
@ -2574,7 +2589,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
startDomain(cmd.getVmName(), vmDomainXML);
// Attach each data volume to the VM, if there is a deferred attached disk
for (diskDef disk : disks) {
for (DiskDef disk : disks) {
if (disk.isAttachDeferred()) {
attachOrDetachDisk(true, cmd.getVmName(), disk.getDiskPath());
}
@ -2602,6 +2617,282 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
}
private void handleVmStartFailure(String vmName, LibvirtVMDef vm) {
if (vm != null && vm.getDevices() != null)
cleanupVMNetworks(vm.getDevices().getInterfaces());
}
private LibvirtVMDef createVMFromSpec(VirtualMachineTO vmTO) {
LibvirtVMDef vm = new LibvirtVMDef();
vm.setHvsType(_hypervisorType);
vm.setDomainName(vmTO.getName());
vm.setDomUUID(UUID.nameUUIDFromBytes(vmTO.getName().getBytes()).toString());
vm.setDomDescription(KVMGuestOsMapper.getGuestOsName(vmTO.getOs()));
GuestDef guest = new GuestDef();
guest.setGuestType(GuestDef.guestType.KVM);
guest.setGuestArch(vmTO.getArch());
guest.setMachineType("pc");
guest.setBootOrder(GuestDef.bootOrder.CDROM);
guest.setBootOrder(GuestDef.bootOrder.HARDISK);
vm.addComp(guest);
GuestResourceDef grd = new GuestResourceDef();
grd.setMemorySize(vmTO.getMinRam()/1024);
grd.setVcpuNum(vmTO.getCpus());
vm.addComp(grd);
FeaturesDef features = new FeaturesDef();
features.addFeatures("pae");
features.addFeatures("apic");
features.addFeatures("acpi");
vm.addComp(features);
TermPolicy term = new TermPolicy();
term.setCrashPolicy("destroy");
term.setPowerOffPolicy("destroy");
term.setRebootPolicy("restart");
vm.addComp(term);
DevicesDef devices = new DevicesDef();
devices.setEmulatorPath(_hypervisorPath);
SerialDef serial = new SerialDef("pty", null, (short)0);
devices.addDevice(serial);
ConsoleDef console = new ConsoleDef("pty", null, null, (short)0);
devices.addDevice(console);
GraphicDef grap = new GraphicDef("vnc", (short)0, true, null, null, null);
devices.addDevice(grap);
InputDef input = new InputDef("tablet", "usb");
devices.addDevice(input);
vm.addComp(devices);
return vm;
}
private void createVifs(VirtualMachineTO vmSpec, LibvirtVMDef vm) throws InternalErrorException {
NicTO[] nics = vmSpec.getNics();
for (int i = 0; i < nics.length; i++) {
for (NicTO nic : vmSpec.getNics()) {
if (nic.getDeviceId() == i)
createVif(vm, nic);
}
}
}
protected Start2Answer execute(Start2Command cmd) {
VirtualMachineTO vmSpec = cmd.getVirtualMachine();
String vmName = vmSpec.getName();
LibvirtVMDef vm = null;
State state = State.Stopped;
try {
synchronized (_vms) {
_vms.put(vmName, State.Starting);
}
vm = createVMFromSpec(vmSpec);
createVbd(vmSpec, vmName, vm);
createVifs(vmSpec, vm);
s_logger.debug("starting " + vmName + ": " + vm.toString());
startDomain(vmName, vm.toString());
Monitor monitor = vmSpec.getMonitor();
if (monitor != null && monitor instanceof SshMonitor) {
SshMonitor sshMon = (SshMonitor)monitor;
String privateIp = sshMon.getIp();
int cmdPort = sshMon.getPort();
if (s_logger.isDebugEnabled()) {
s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort);
}
String result = _virtRouterResource.connect(privateIp, cmdPort);
if (result != null) {
throw new CloudRuntimeException("Can not ping System vm " + vmName + "due to:" + result);
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Ping command port succeeded for vm " + vmName);
}
}
// Attach each data volume to the VM, if there is a deferred attached disk
for (DiskDef disk : vm.getDevices().getDisks()) {
if (disk.isAttachDeferred()) {
attachOrDetachDisk(true, vmName, disk.getDiskPath());
}
}
state = State.Running;
return new Start2Answer(cmd);
} catch (Exception e) {
s_logger.warn("Exception ", e);
handleVmStartFailure(vmName, vm);
return new Start2Answer(cmd, e.getMessage());
} finally {
synchronized (_vms) {
if (state != State.Stopped) {
_vms.put(vmName, state);
} else {
_vms.remove(vmName);
}
}
}
}
private String getVolumePath(VolumeTO volume) throws LibvirtException, URISyntaxException {
if (volume.getType() == Volume.VolumeType.ISO) {
StorageVol vol = getVolume(_conn, volume.getPath());
return vol.getPath();
} else {
return volume.getPath();
}
}
private void createVbd(VirtualMachineTO vmSpec, String vmName, LibvirtVMDef vm) throws InternalErrorException, LibvirtException, URISyntaxException{
boolean foundISO = false;
for (VolumeTO volume : vmSpec.getDisks()) {
String volPath = getVolumePath(volume);
DiskDef.diskBus diskBusType = getGuestDiskModel(vmSpec.getOs());
DiskDef disk = new DiskDef();
if (volume.getType() == VolumeType.ISO) {
foundISO = true;
disk.defISODisk(volPath);
} else {
int devId = 0;
if (volume.getType() == VolumeType.ROOT) {
devId = 0;
} else {
devId = 1;
}
disk.defFileBasedDisk(volume.getPath(), devId, diskBusType, DiskDef.diskFmtType.QCOW2);
}
//Centos doesn't support scsi hotplug. For other host OSes, we attach the disk after the vm is running, so that we can hotplug it.
if (volume.getType() == VolumeType.DATADISK && diskBusType != DiskDef.diskBus.VIRTIO) {
disk.setAttachDeferred(true);
}
if (!disk.isAttachDeferred()) {
vm.getDevices().addDevice(disk);
}
}
if (vmSpec.getType() == VirtualMachine.Type.User) {
if (!foundISO) {
/*Add iso as placeholder*/
DiskDef iso = new DiskDef();
iso.defISODisk(null);
vm.getDevices().addDevice(iso);
}
} else {
DiskDef iso = new DiskDef();
iso.defISODisk(_sysvmISOPath);
vm.getDevices().addDevice(iso);
createPatchVbd(vmName, vm, vmSpec);
}
}
private void createPatchVbd(String vmName, LibvirtVMDef vm, VirtualMachineTO vmSpec) throws LibvirtException, InternalErrorException {
List<DiskDef> disks = vm.getDevices().getDisks();
DiskDef rootDisk = disks.get(0);
StorageVol tmplVol = createTmplDataDisk(rootDisk.getDiskPath(), 10L * 1024 * 1024);
String datadiskPath = tmplVol.getKey();
/*add patch disk*/
DiskDef patchDisk = new DiskDef();
patchDisk.defFileBasedDisk(rootDisk.getDiskPath(), 1, rootDisk.getBusType(), DiskDef.diskFmtType.RAW);
disks.add(patchDisk);
patchDisk.setDiskPath(datadiskPath);
String bootArgs = vmSpec.getBootArgs();
patchSystemVm(bootArgs, datadiskPath, vmName);
}
private String createVlanBr(String vlanId, String nic) throws InternalErrorException{
String brName = setVnetBrName(vlanId);
createVnet(vlanId, nic);
return brName;
}
private InterfaceDef createVif(LibvirtVMDef vm, NicTO nic) throws InternalErrorException {
InterfaceDef intf = new InterfaceDef();
String vlanId = null;
if (nic.getBroadcastType() == BroadcastDomainType.Vlan) {
URI broadcastUri = nic.getBroadcastUri();
vlanId = broadcastUri.getHost();
s_logger.debug("vlanId: " + vlanId);
}
if (nic.getType() == TrafficType.Guest) {
if (nic.getBroadcastType() == BroadcastDomainType.Vlan && !vlanId.equalsIgnoreCase("untagged")){
String brName = createVlanBr(vlanId, _pifs.first());
intf.defBridgeNet(brName, null, nic.getMac(), InterfaceDef.nicModel.VIRTIO);
} else {
intf.defBridgeNet(_privBridgeName, null, nic.getMac(), InterfaceDef.nicModel.VIRTIO);
}
} else if (nic.getType() == TrafficType.Control) {
intf.defPrivateNet(_privNwName, null, nic.getMac(), InterfaceDef.nicModel.VIRTIO);
} else if (nic.getType() == TrafficType.Public) {
if (nic.getBroadcastType() == BroadcastDomainType.Vlan && !vlanId.equalsIgnoreCase("untagged")) {
String brName = createVlanBr(vlanId, _pifs.second());
intf.defBridgeNet(brName, null, nic.getMac(), InterfaceDef.nicModel.VIRTIO);
} else {
intf.defBridgeNet(_publicBridgeName, null, nic.getMac(), InterfaceDef.nicModel.VIRTIO);
}
} else if (nic.getType() == TrafficType.Management) {
intf.defBridgeNet(_privBridgeName, null, nic.getMac(), InterfaceDef.nicModel.VIRTIO);
}
vm.getDevices().addDevice(intf);
return intf;
}
protected CheckSshAnswer execute(CheckSshCommand cmd) {
String vmName = cmd.getName();
String privateIp = cmd.getIp();
int cmdPort = cmd.getPort();
if (s_logger.isDebugEnabled()) {
s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort);
}
try {
String result = _virtRouterResource.connect(privateIp, cmdPort);
if (result != null) {
return new CheckSshAnswer(cmd, "Can not ping System vm " + vmName + "due to:" + result);
}
} catch (Exception e) {
return new CheckSshAnswer(cmd, e);
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Ping command port succeeded for vm " + vmName);
}
return new CheckSshAnswer(cmd);
}
protected synchronized String attachOrDetachISO(String vmName, String isoPath, boolean isAttach) throws LibvirtException, URISyntaxException {
String isoXml = null;
if (isoPath != null && isAttach) {
@ -2609,14 +2900,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
isoPath = isoVol.getPath();
diskDef iso = new diskDef();
iso.defFileBasedDisk(isoPath, "hdc", diskDef.diskBus.IDE, diskDef.diskFmtType.RAW);
iso.setDeviceType(diskDef.deviceType.CDROM);
DiskDef iso = new DiskDef();
iso.defFileBasedDisk(isoPath, "hdc", DiskDef.diskBus.IDE, DiskDef.diskFmtType.RAW);
iso.setDeviceType(DiskDef.deviceType.CDROM);
isoXml = iso.toString();
} else {
diskDef iso = new diskDef();
iso.defFileBasedDisk(null, "hdc", diskDef.diskBus.IDE, diskDef.diskFmtType.RAW);
iso.setDeviceType(diskDef.deviceType.CDROM);
DiskDef iso = new DiskDef();
iso.defFileBasedDisk(null, "hdc", DiskDef.diskBus.IDE, DiskDef.diskFmtType.RAW);
iso.setDeviceType(DiskDef.deviceType.CDROM);
isoXml = iso.toString();
}
@ -2664,12 +2955,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
s_logger.warn("Can't get disk dev");
return "Can't get disk dev";
}
diskDef disk = new diskDef();
DiskDef disk = new DiskDef();
String guestOSType = getGuestType(vmName);
if (isGuestPVEnabled(guestOSType)) {
disk.defFileBasedDisk(sourceFile, diskDev, diskDef.diskBus.VIRTIO, diskDef.diskFmtType.QCOW2);
disk.defFileBasedDisk(sourceFile, diskDev, DiskDef.diskBus.VIRTIO, DiskDef.diskFmtType.QCOW2);
} else {
disk.defFileBasedDisk(sourceFile, diskDev, diskDef.diskBus.SCSI, diskDef.diskFmtType.QCOW2);
disk.defFileBasedDisk(sourceFile, diskDev, DiskDef.diskBus.SCSI, DiskDef.diskFmtType.QCOW2);
}
String xml = disk.toString();
return attachOrDetachDevice(attach, vmName, xml);
@ -3320,19 +3611,19 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return dataVol;
}
private interfaceDef.nicModel getGuestNicModel(String guestOSType) {
private InterfaceDef.nicModel getGuestNicModel(String guestOSType) {
if (isGuestPVEnabled(guestOSType) && !isCentosHost()) {
return interfaceDef.nicModel.VIRTIO;
return InterfaceDef.nicModel.VIRTIO;
} else {
return interfaceDef.nicModel.E1000;
return InterfaceDef.nicModel.E1000;
}
}
private diskDef.diskBus getGuestDiskModel(String guestOSType) {
private DiskDef.diskBus getGuestDiskModel(String guestOSType) {
if (isGuestPVEnabled(guestOSType) && !isCentosHost()) {
return diskDef.diskBus.VIRTIO;
return DiskDef.diskBus.VIRTIO;
} else {
return diskDef.diskBus.IDE;
return DiskDef.diskBus.IDE;
}
}
@ -3342,12 +3633,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
private String getVnetIdFromBrName(String vnetBrName) {
return vnetBrName.replaceAll("cloudVirBr", "");
}
private List<interfaceDef> createUserVMNetworks(StartCommand cmd) throws InternalErrorException {
List<interfaceDef> nics = new ArrayList<interfaceDef>();
interfaceDef.nicModel nicModel = getGuestNicModel(cmd.getGuestOSDescription());
private List<InterfaceDef> createUserVMNetworks(StartCommand cmd) throws InternalErrorException {
List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
InterfaceDef.nicModel nicModel = getGuestNicModel(cmd.getGuestOSDescription());
String guestMac = cmd.getGuestMacAddress();
String brName;
interfaceDef pubNic = new interfaceDef();
InterfaceDef pubNic = new InterfaceDef();
if (cmd.getGuestIpAddress() == null) {
/*guest network is direct attached without external DHCP server*/
brName = _privBridgeName;
@ -3368,89 +3659,89 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return nics;
}
private List<interfaceDef> createRouterVMNetworks(StartRouterCommand cmd) throws InternalErrorException {
List<interfaceDef> nics = new ArrayList<interfaceDef>();
private List<InterfaceDef> createRouterVMNetworks(StartRouterCommand cmd) throws InternalErrorException {
List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
DomainRouter router = cmd.getRouter();
String guestMac = router.getGuestMacAddress();
String privateMac = router.getPrivateMacAddress();
String pubMac = router.getPublicMacAddress();
String brName;
interfaceDef pubNic = new interfaceDef();
interfaceDef privNic = new interfaceDef();
interfaceDef vnetNic = new interfaceDef();
InterfaceDef pubNic = new InterfaceDef();
InterfaceDef privNic = new InterfaceDef();
InterfaceDef vnetNic = new InterfaceDef();
/*nic 0, guest network*/
if ("untagged".equalsIgnoreCase(router.getVnet())){
vnetNic.defBridgeNet(_privBridgeName, null, guestMac, interfaceDef.nicModel.VIRTIO);
vnetNic.defBridgeNet(_privBridgeName, null, guestMac, InterfaceDef.nicModel.VIRTIO);
} else {
String vnetId = getVnetId(router.getVnet());
brName = setVnetBrName(vnetId);
String vnetDev = "vtap" + vnetId;
createVnet(vnetId, _pifs.first());
vnetNic.defBridgeNet(brName, null, guestMac, interfaceDef.nicModel.VIRTIO);
vnetNic.defBridgeNet(brName, null, guestMac, InterfaceDef.nicModel.VIRTIO);
}
nics.add(vnetNic);
/*nic 1: link local*/
privNic.defPrivateNet(_privNwName, null, privateMac, interfaceDef.nicModel.VIRTIO);
privNic.defPrivateNet(_privNwName, null, privateMac, InterfaceDef.nicModel.VIRTIO);
nics.add(privNic);
/*nic 2: public */
if ("untagged".equalsIgnoreCase(router.getVlanId())) {
pubNic.defBridgeNet(_publicBridgeName, null, pubMac, interfaceDef.nicModel.VIRTIO);
pubNic.defBridgeNet(_publicBridgeName, null, pubMac, InterfaceDef.nicModel.VIRTIO);
} else {
String vnetId = getVnetId(router.getVlanId());
brName = setVnetBrName(vnetId);
String vnetDev = "vtap" + vnetId;
createVnet(vnetId, _pifs.second());
pubNic.defBridgeNet(brName, null, pubMac, interfaceDef.nicModel.VIRTIO);
pubNic.defBridgeNet(brName, null, pubMac, InterfaceDef.nicModel.VIRTIO);
}
nics.add(pubNic);
return nics;
}
private List<interfaceDef> createSysVMNetworks(String guestMac, String privMac, String pubMac, String vlanId) throws InternalErrorException {
List<interfaceDef> nics = new ArrayList<interfaceDef>();
private List<InterfaceDef> createSysVMNetworks(String guestMac, String privMac, String pubMac, String vlanId) throws InternalErrorException {
List<InterfaceDef> nics = new ArrayList<InterfaceDef>();
String brName;
interfaceDef pubNic = new interfaceDef();
interfaceDef privNic = new interfaceDef();
interfaceDef vnetNic = new interfaceDef();
InterfaceDef pubNic = new InterfaceDef();
InterfaceDef privNic = new InterfaceDef();
InterfaceDef vnetNic = new InterfaceDef();
/*nic 0: link local*/
privNic.defPrivateNet(_privNwName, null, guestMac, interfaceDef.nicModel.VIRTIO);
privNic.defPrivateNet(_privNwName, null, guestMac, InterfaceDef.nicModel.VIRTIO);
nics.add(privNic);
/*nic 1, priv network*/
vnetNic.defBridgeNet(_privBridgeName, null, privMac, interfaceDef.nicModel.VIRTIO);
vnetNic.defBridgeNet(_privBridgeName, null, privMac, InterfaceDef.nicModel.VIRTIO);
nics.add(vnetNic);
/*nic 2: public */
if ("untagged".equalsIgnoreCase(vlanId)) {
pubNic.defBridgeNet(_publicBridgeName, null, pubMac, interfaceDef.nicModel.VIRTIO);
pubNic.defBridgeNet(_publicBridgeName, null, pubMac, InterfaceDef.nicModel.VIRTIO);
} else {
String vnetId = getVnetId(vlanId);
brName = setVnetBrName(vnetId);
String vnetDev = "vtap" + vnetId;
createVnet(vnetId, _pifs.second());
pubNic.defBridgeNet(brName, null, pubMac, interfaceDef.nicModel.VIRTIO);
pubNic.defBridgeNet(brName, null, pubMac, InterfaceDef.nicModel.VIRTIO);
}
nics.add(pubNic);
return nics;
}
private void cleanupVMNetworks(List<interfaceDef> nics) {
for (interfaceDef nic : nics) {
private void cleanupVMNetworks(List<InterfaceDef> nics) {
for (InterfaceDef nic : nics) {
if (nic.getHostNetType() == hostNicType.VNET) {
cleanupVnet(getVnetIdFromBrName(nic.getBrName()));
}
}
}
private List<diskDef> createSystemVMDisk(List<VolumeVO> vols) throws InternalErrorException, LibvirtException{
List<diskDef> disks = new ArrayList<diskDef>();
private List<DiskDef> createSystemVMDisk(List<VolumeVO> vols) throws InternalErrorException, LibvirtException{
List<DiskDef> disks = new ArrayList<DiskDef>();
// Get the root volume
List<VolumeVO> rootVolumes = findVolumes(vols, VolumeType.ROOT, true);
@ -3464,24 +3755,24 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
StorageVol tmplVol = createTmplDataDisk(rootkPath, 10L * 1024 * 1024);
String datadiskPath = tmplVol.getKey();
diskDef hda = new diskDef();
hda.defFileBasedDisk(rootkPath, "vda", diskDef.diskBus.VIRTIO, diskDef.diskFmtType.QCOW2);
DiskDef hda = new DiskDef();
hda.defFileBasedDisk(rootkPath, "vda", DiskDef.diskBus.VIRTIO, DiskDef.diskFmtType.QCOW2);
disks.add(hda);
diskDef hdb = new diskDef();
hdb.defFileBasedDisk(datadiskPath, "vdb", diskDef.diskBus.VIRTIO, diskDef.diskFmtType.RAW);
DiskDef hdb = new DiskDef();
hdb.defFileBasedDisk(datadiskPath, "vdb", DiskDef.diskBus.VIRTIO, DiskDef.diskFmtType.RAW);
disks.add(hdb);
diskDef hdc = new diskDef();
hdc.defFileBasedDisk(_sysvmISOPath, "hdc", diskDef.diskBus.IDE, diskDef.diskFmtType.RAW);
hdc.setDeviceType(diskDef.deviceType.CDROM);
DiskDef hdc = new DiskDef();
hdc.defFileBasedDisk(_sysvmISOPath, "hdc", DiskDef.diskBus.IDE, DiskDef.diskFmtType.RAW);
hdc.setDeviceType(DiskDef.deviceType.CDROM);
disks.add(hdc);
return disks;
}
private List<diskDef> createVMDisk(List<VolumeVO> vols, String guestOSType, String isoURI) throws InternalErrorException, LibvirtException, URISyntaxException{
List<diskDef> disks = new ArrayList<diskDef>();
private List<DiskDef> createVMDisk(List<VolumeVO> vols, String guestOSType, String isoURI) throws InternalErrorException, LibvirtException, URISyntaxException{
List<DiskDef> disks = new ArrayList<DiskDef>();
// Get the root volume
List<VolumeVO> rootVolumes = findVolumes(vols, VolumeType.ROOT, true);
@ -3505,17 +3796,17 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
if (dataVolumes.size() > 0)
dataVolume = dataVolumes.get(0);
diskDef.diskBus diskBusType = getGuestDiskModel(guestOSType);
DiskDef.diskBus diskBusType = getGuestDiskModel(guestOSType);
diskDef hda = new diskDef();
hda.defFileBasedDisk(rootVolume.getPath(), "vda", diskBusType, diskDef.diskFmtType.QCOW2);
DiskDef hda = new DiskDef();
hda.defFileBasedDisk(rootVolume.getPath(), "vda", diskBusType, DiskDef.diskFmtType.QCOW2);
disks.add(hda);
/*Centos doesn't support scsi hotplug. For other host OSes, we attach the disk after the vm is running, so that we can hotplug it.*/
if (dataVolume != null) {
diskDef hdb = new diskDef();
hdb.defFileBasedDisk(dataVolume.getPath(), "vdb", diskBusType, diskDef.diskFmtType.QCOW2);
DiskDef hdb = new DiskDef();
hdb.defFileBasedDisk(dataVolume.getPath(), "vdb", diskBusType, DiskDef.diskFmtType.QCOW2);
if (!isCentosHost()) {
hdb.setAttachDeferred(true);
}
@ -3523,9 +3814,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
/*Add a placeholder for iso, even if there is no iso attached*/
diskDef hdc = new diskDef();
hdc.defFileBasedDisk(isoPath, "hdc", diskDef.diskBus.IDE, diskDef.diskFmtType.RAW);
hdc.setDeviceType(diskDef.deviceType.CDROM);
DiskDef hdc = new DiskDef();
hdc.defFileBasedDisk(isoPath, "hdc", DiskDef.diskBus.IDE, DiskDef.diskFmtType.RAW);
hdc.setDeviceType(DiskDef.deviceType.CDROM);
disks.add(hdc);
return disks;

View File

@ -19,7 +19,10 @@
package com.cloud.agent.resource.computing;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class LibvirtVMDef {
@ -27,9 +30,9 @@ public class LibvirtVMDef {
private String _domName;
private String _domUUID;
private String _desc;
private final List<Object> components = new ArrayList<Object>();
private final Map<String, Object> components = new HashMap<String,Object>();
public static class guestDef {
public static class GuestDef {
enum guestType {
KVM,
XEN,
@ -104,12 +107,12 @@ public class LibvirtVMDef {
}
}
public static class guestResourceDef {
private int _mem;
public static class GuestResourceDef {
private long _mem;
private int _currentMem = -1;
private String _memBacking;
private int _vcpu = -1;
public void setMemorySize(int mem) {
public void setMemorySize(long mem) {
_mem = mem;
}
public void setCurrentMem(int currMem) {
@ -138,7 +141,7 @@ public class LibvirtVMDef {
}
}
public static class featuresDef {
public static class FeaturesDef {
private final List<String> _features = new ArrayList<String>();
public void addFeatures(String feature) {
_features.add(feature);
@ -154,11 +157,11 @@ public class LibvirtVMDef {
return feaBuilder.toString();
}
}
public static class termPolicy {
public static class TermPolicy {
private String _reboot;
private String _powerOff;
private String _crash;
public termPolicy() {
public TermPolicy() {
_reboot = _powerOff = _crash = "destroy";
}
public void setRebootPolicy(String rbPolicy) {
@ -180,11 +183,20 @@ public class LibvirtVMDef {
}
}
public static class devicesDef {
public static class DevicesDef {
private String _emulator;
private final List<Object> devices = new ArrayList<Object>();
private final Map<String, List<?>> devices = new HashMap<String, List<?>>();
public boolean addDevice(Object device) {
return devices.add(device);
Object dev = devices.get(device.getClass().toString());
if (dev == null) {
List<Object> devs = new ArrayList<Object>();
devs.add(device);
devices.put(device.getClass().toString(), devs);
} else {
List<Object> devs = (List<Object>)dev;
devs.add(device);
}
return true;
}
public void setEmulatorPath(String emulator) {
_emulator = emulator;
@ -196,15 +208,24 @@ public class LibvirtVMDef {
if (_emulator != null) {
devicesBuilder.append("<emulator>" + _emulator + "</emulator>\n");
}
for (Object o : devices) {
devicesBuilder.append(o.toString());
for (List<?> devs : devices.values()) {
for (Object dev : devs) {
devicesBuilder.append(dev.toString());
}
}
devicesBuilder.append("</devices>\n");
return devicesBuilder.toString();
}
public List<DiskDef> getDisks() {
return (List<DiskDef>)devices.get(DiskDef.class.toString());
}
public List<InterfaceDef> getInterfaces() {
return (List<InterfaceDef>)devices.get(InterfaceDef.class.toString());
}
}
public static class diskDef {
public static class DiskDef {
enum deviceType {
FLOOPY("floopy"),
DISK("disk"),
@ -282,6 +303,33 @@ public class LibvirtVMDef {
_bus = bus;
}
private String getDevLabel(int devId, diskBus bus) {
char suffix = (char)('a' + devId);
if (bus == diskBus.SCSI) {
return "sd" + suffix;
} else if (bus == diskBus.VIRTIO) {
return "vd" + suffix;
}
return "hd" + suffix;
}
public void defFileBasedDisk(String filePath, int devId, diskBus bus, diskFmtType diskFmtType) {
_diskType = diskType.FILE;
_deviceType = deviceType.DISK;
_sourcePath = filePath;
_diskLabel = getDevLabel(devId, bus);
_diskFmtType = diskFmtType;
_bus = bus;
}
public void defISODisk(String volPath) {
_diskType = diskType.FILE;
_deviceType = deviceType.CDROM;
_sourcePath = volPath;
_diskLabel = "hdc";
_diskFmtType = diskFmtType.RAW;
_bus = diskBus.IDE;
}
public void defBlockBasedDisk(String diskName, String diskLabel, diskBus bus) {
_diskType = diskType.BLOCK;
_deviceType = deviceType.DISK;
@ -307,6 +355,19 @@ public class LibvirtVMDef {
public String getDiskLabel() {
return _diskLabel;
}
public deviceType getDeviceType() {
return _deviceType;
}
public void setDiskPath(String volPath) {
this._sourcePath = volPath;
}
public diskBus getBusType() {
return _bus;
}
public int getDiskSeq() {
char suffix = this._diskLabel.charAt(this._diskLabel.length() - 1);
return suffix - 'a';
}
@Override
public String toString() {
StringBuilder diskBuilder = new StringBuilder();
@ -342,7 +403,7 @@ public class LibvirtVMDef {
}
}
public static class interfaceDef {
public static class InterfaceDef {
enum guestNetType {
BRIDGE("bridge"),
NETWORK("network"),
@ -415,6 +476,7 @@ public class LibvirtVMDef {
public guestNetType getNetType() {
return _netType;
}
@Override
public String toString() {
StringBuilder netBuilder = new StringBuilder();
@ -437,12 +499,12 @@ public class LibvirtVMDef {
return netBuilder.toString();
}
}
public static class consoleDef {
public static class ConsoleDef {
private final String _ttyPath;
private final String _type;
private final String _source;
private short _port = -1;
public consoleDef(String type, String path, String source, short port) {
public ConsoleDef(String type, String path, String source, short port) {
_type = type;
_ttyPath = path;
_source = source;
@ -467,11 +529,11 @@ public class LibvirtVMDef {
return consoleBuilder.toString();
}
}
public static class serialDef {
public static class SerialDef {
private final String _type;
private final String _source;
private short _port = -1;
public serialDef(String type, String source, short port) {
public SerialDef(String type, String source, short port) {
_type = type;
_source = source;
_port = port;
@ -490,14 +552,14 @@ public class LibvirtVMDef {
return serialBuidler.toString();
}
}
public static class graphicDef {
public static class GraphicDef {
private final String _type;
private short _port = -2;
private boolean _autoPort = false;
private final String _listenAddr;
private final String _passwd;
private final String _keyMap;
public graphicDef(String type, short port, boolean auotPort, String listenAddr, String passwd, String keyMap) {
public GraphicDef(String type, short port, boolean auotPort, String listenAddr, String passwd, String keyMap) {
_type = type;
_port = port;
_autoPort = auotPort;
@ -528,10 +590,10 @@ public class LibvirtVMDef {
return graphicBuilder.toString();
}
}
public static class inputDef {
public static class InputDef {
private final String _type; /*tablet, mouse*/
private final String _bus; /*ps2, usb, xen*/
public inputDef(String type, String bus) {
public InputDef(String type, String bus) {
_type = type;
_bus = bus;
}
@ -558,8 +620,18 @@ public class LibvirtVMDef {
public void setDomDescription(String desc) {
_desc = desc;
}
public boolean addComp(Object comp) {
return components.add(comp);
public String getGuestOSType() {
return _desc;
}
public void addComp(Object comp) {
components.put(comp.getClass().toString(), comp);
}
public DevicesDef getDevices() {
Object o = components.get(DevicesDef.class.toString());
if (o != null) {
return (DevicesDef)o;
}
return null;
}
@Override
public String toString() {
@ -572,7 +644,7 @@ public class LibvirtVMDef {
if (_desc != null ) {
vmBuilder.append("<description>" + _desc + "</description>\n");
}
for (Object o : components) {
for (Object o : components.values()) {
vmBuilder.append(o.toString());
}
vmBuilder.append("</domain>\n");
@ -586,63 +658,63 @@ public class LibvirtVMDef {
vm.setDomainName("testing");
vm.setDomUUID(UUID.randomUUID().toString());
guestDef guest = new guestDef();
guest.setGuestType(guestDef.guestType.KVM);
GuestDef guest = new GuestDef();
guest.setGuestType(GuestDef.guestType.KVM);
guest.setGuestArch("x86_64");
guest.setMachineType("pc-0.11");
guest.setBootOrder(guestDef.bootOrder.HARDISK);
guest.setBootOrder(GuestDef.bootOrder.HARDISK);
vm.addComp(guest);
guestResourceDef grd = new guestResourceDef();
GuestResourceDef grd = new GuestResourceDef();
grd.setMemorySize(512*1024);
grd.setVcpuNum(1);
vm.addComp(grd);
featuresDef features = new featuresDef();
FeaturesDef features = new FeaturesDef();
features.addFeatures("pae");
features.addFeatures("apic");
features.addFeatures("acpi");
vm.addComp(features);
termPolicy term = new termPolicy();
TermPolicy term = new TermPolicy();
term.setCrashPolicy("destroy");
term.setPowerOffPolicy("destroy");
term.setRebootPolicy("destroy");
vm.addComp(term);
devicesDef devices = new devicesDef();
DevicesDef devices = new DevicesDef();
devices.setEmulatorPath("/usr/bin/cloud-qemu-system-x86_64");
diskDef hda = new diskDef();
hda.defFileBasedDisk("/path/to/hda1", "hda", diskDef.diskBus.IDE, diskDef.diskFmtType.QCOW2);
DiskDef hda = new DiskDef();
hda.defFileBasedDisk("/path/to/hda1", 0, DiskDef.diskBus.VIRTIO, DiskDef.diskFmtType.QCOW2);
devices.addDevice(hda);
diskDef hdb = new diskDef();
hdb.defFileBasedDisk("/path/to/hda2", "hdb", diskDef.diskBus.IDE, diskDef.diskFmtType.QCOW2);
DiskDef hdb = new DiskDef();
hdb.defFileBasedDisk("/path/to/hda2", 1, DiskDef.diskBus.VIRTIO, DiskDef.diskFmtType.QCOW2);
devices.addDevice(hdb);
interfaceDef pubNic = new interfaceDef();
pubNic.defBridgeNet("cloudbr0", "vnet1", "00:16:3e:77:e2:a1", interfaceDef.nicModel.VIRTIO);
InterfaceDef pubNic = new InterfaceDef();
pubNic.defBridgeNet("cloudbr0", "vnet1", "00:16:3e:77:e2:a1", InterfaceDef.nicModel.VIRTIO);
devices.addDevice(pubNic);
interfaceDef privNic = new interfaceDef();
privNic.defPrivateNet("cloud-private", null, "00:16:3e:77:e2:a2", interfaceDef.nicModel.VIRTIO);
InterfaceDef privNic = new InterfaceDef();
privNic.defPrivateNet("cloud-private", null, "00:16:3e:77:e2:a2", InterfaceDef.nicModel.VIRTIO);
devices.addDevice(privNic);
interfaceDef vlanNic = new interfaceDef();
vlanNic.defBridgeNet("vnbr1000", "tap1", "00:16:3e:77:e2:a2", interfaceDef.nicModel.VIRTIO);
InterfaceDef vlanNic = new InterfaceDef();
vlanNic.defBridgeNet("vnbr1000", "tap1", "00:16:3e:77:e2:a2", InterfaceDef.nicModel.VIRTIO);
devices.addDevice(vlanNic);
serialDef serial = new serialDef("pty", null, (short)0);
SerialDef serial = new SerialDef("pty", null, (short)0);
devices.addDevice(serial);
consoleDef console = new consoleDef("pty", null, null, (short)0);
ConsoleDef console = new ConsoleDef("pty", null, null, (short)0);
devices.addDevice(console);
graphicDef grap = new graphicDef("vnc", (short)0, true, null, null, null);
GraphicDef grap = new GraphicDef("vnc", (short)0, true, null, null, null);
devices.addDevice(grap);
inputDef input = new inputDef("tablet", "usb");
InputDef input = new InputDef("tablet", "usb");
devices.addDevice(input);
vm.addComp(devices);

View File

@ -13,5 +13,6 @@ public interface DataCenter extends Grouping {
String getDns1();
String getDns2();
String getGuestNetworkCidr();
String getName();
Long getDomainId();
}

View File

@ -6,9 +6,15 @@ package com.cloud.deploy;
import java.util.HashSet;
import java.util.Set;
import com.cloud.dc.DataCenter;
import com.cloud.dc.Pod;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InsufficientServerCapacityException;
import com.cloud.host.Host;
import com.cloud.org.Cluster;
import com.cloud.storage.StoragePool;
import com.cloud.utils.component.Adapter;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
/**
@ -23,7 +29,7 @@ public interface DeploymentPlanner extends Adapter {
* @param avoid avoid these data centers, pods, clusters, or hosts.
* @return DeployDestination for that virtual machine.
*/
DeployDestination plan(VirtualMachineProfile vm, DeploymentPlan plan, ExcludeList avoid) throws InsufficientServerCapacityException;
DeployDestination plan(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan plan, ExcludeList avoid) throws InsufficientServerCapacityException;
/**
* check() is called right before the virtual machine starts to make sure
@ -35,15 +41,40 @@ public interface DeploymentPlanner extends Adapter {
* @param avoid what to avoid.
* @return true if it's okay to start; false if not. If false, the exclude list will include what should be excluded.
*/
boolean check(VirtualMachineProfile vm, DeploymentPlan plan, DeployDestination dest, ExcludeList exclude);
boolean check(VirtualMachineProfile<? extends VirtualMachine> vm, DeploymentPlan plan, DeployDestination dest, ExcludeList exclude);
public static class ExcludeList {
Set<Long> _dcIds;
Set<Long> _podIds;
Set<Long> _clusterIds;
Set<Long> _hostIds;
Set<Long> _poolIds;
public void adddDataCenter(long dataCenterId) {
public void add(InsufficientCapacityException e) {
Class<?> scope = e.getScope();
if (scope == null) {
return;
}
if (Host.class.isAssignableFrom(scope)) {
addHost(e.getId());
} else if (Pod.class.isAssignableFrom(scope)) {
addPod(e.getId());
} else if (DataCenter.class.isAssignableFrom(scope)) {
addDataCenter(e.getId());
} else if (Cluster.class.isAssignableFrom(scope)) {
addCluster(e.getId());
} else if (StoragePool.class.isAssignableFrom(scope)) {
addPool(e.getId());
}
}
public void addPool(long poolId) {
_poolIds.add(poolId);
}
public void addDataCenter(long dataCenterId) {
if (_dcIds == null) {
_dcIds = new HashSet<Long>();
}

View File

@ -27,8 +27,8 @@ public class InsufficientAddressCapacityException extends InsufficientNetworkCap
private static final long serialVersionUID = SerialVersionUID.InsufficientAddressCapacityException;
public InsufficientAddressCapacityException(String msg) {
super(msg);
public InsufficientAddressCapacityException(String msg, Class<?> scope, Long id) {
super(msg, scope, id);
}
protected InsufficientAddressCapacityException() {

View File

@ -26,10 +26,32 @@ import com.cloud.utils.SerialVersionUID;
public abstract class InsufficientCapacityException extends Exception {
private static final long serialVersionUID = SerialVersionUID.InsufficientCapacityException;
Long id;
Class<?> scope;
protected InsufficientCapacityException() {
super();
}
public InsufficientCapacityException(String msg) {
public InsufficientCapacityException(String msg, Class<?> type, Long id) {
super(msg);
}
/**
* @return scope where we are insufficient. The possible classes are
* Host, StoragePool, Cluster, Pod, DataCenter, NetworkConfiguration.
*/
public Class<?> getScope() {
return scope;
}
/**
* @return the id of the object that it is insufficient in. Note that this method is
* marked such that if the id is not set, then it will throw NullPointerException.
* This is intended as you should check to see if the Scope is present before
* accessing this method.
*/
public long getId() {
return id;
}
}

View File

@ -26,7 +26,7 @@ public class InsufficientNetworkCapacityException extends InsufficientCapacityEx
super();
}
public InsufficientNetworkCapacityException(String msg) {
super(msg);
public InsufficientNetworkCapacityException(String msg, Class<?> scope, Long id) {
super(msg, scope, id);
}
}

View File

@ -17,6 +17,7 @@
*/
package com.cloud.exception;
import com.cloud.org.Cluster;
import com.cloud.utils.SerialVersionUID;
/**
@ -28,7 +29,11 @@ public class InsufficientServerCapacityException extends InsufficientCapacityExc
private static final long serialVersionUID = SerialVersionUID.InsufficientServerCapacityException;
public InsufficientServerCapacityException(String msg) {
super(msg);
public InsufficientServerCapacityException(String msg, Long clusterId) {
this(msg, Cluster.class, clusterId);
}
public InsufficientServerCapacityException(String msg, Class<?> scope, Long id) {
super(msg, scope, id);
}
}

View File

@ -17,6 +17,7 @@
*/
package com.cloud.exception;
import com.cloud.storage.StoragePool;
import com.cloud.utils.SerialVersionUID;
/**
@ -27,7 +28,11 @@ public class InsufficientStorageCapacityException extends InsufficientCapacityEx
private static final long serialVersionUID = SerialVersionUID.InsufficientStorageCapacityException;
public InsufficientStorageCapacityException(String msg) {
super(msg);
public InsufficientStorageCapacityException(String msg, long id) {
this(msg, StoragePool.class, id);
}
public InsufficientStorageCapacityException(String msg, Class<?> scope, Long id) {
super(msg, scope, id);
}
}

View File

@ -17,12 +17,17 @@
*/
package com.cloud.exception;
import com.cloud.dc.Pod;
import com.cloud.utils.SerialVersionUID;
public class InsufficientVirtualNetworkCapcityException extends InsufficientNetworkCapacityException {
private static final long serialVersionUID = SerialVersionUID.InsufficientVirtualNetworkCapacityException;
public InsufficientVirtualNetworkCapcityException(String msg) {
super(msg);
public InsufficientVirtualNetworkCapcityException(String msg, Class<?> scope, Long id) {
super(msg, scope, id);
}
public InsufficientVirtualNetworkCapcityException(String msg, long id) {
this(msg, Pod.class, id);
}
}

View File

@ -92,9 +92,9 @@ public class Network {
Public,
Guest,
Storage,
Management,
Control,
Vpn,
Management
Vpn
};
public enum IsolationType {

View File

@ -18,7 +18,7 @@ import com.cloud.vm.VirtualMachineProfile;
/**
* NetworkGuru takes a network offering requested and figures
* out what is the correct network configuration that are needed to add
* out the correct network configuration needed to add
* to the account in order to support this network.
*
*/
@ -71,4 +71,13 @@ public interface NetworkGuru extends Adapter {
void deallocate(NetworkConfiguration config, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm);
void destroy(NetworkConfiguration config, NetworkOffering offering);
/**
* Throw away the design.
* @param config
* @param offering
* @param owner
* @return
*/
boolean trash(NetworkConfiguration config, NetworkOffering offering, Account owner);
}

View File

@ -37,8 +37,8 @@ public class DiskProfile {
private long diskOfferingId;
private Long templateId;
private long volumeId;
private Volume vol;
private DiskOffering offering;
private HypervisorType hyperType;
protected DiskProfile() {
@ -58,8 +58,6 @@ public class DiskProfile {
public DiskProfile(Volume vol, DiskOffering offering, HypervisorType hyperType) {
this(vol.getId(), vol.getVolumeType(), vol.getName(), offering.getId(), vol.getSize(), offering.getTagsArray(), offering.getUseLocalStorage(), offering.getUseLocalStorage(), vol.getSize());
this.vol = vol;
this.offering = offering;
this.hyperType = hyperType;
}

View File

@ -31,6 +31,10 @@ public interface Nic extends Resource {
String getMacAddress();
String getNetmask();
String getGateway();
/**
* @return network profile id that this
*/

View File

@ -103,9 +103,13 @@ listPublicIpAddresses=com.cloud.api.commands.ListPublicIpAddressesCmd;15
#### firewall commands
listPortForwardingRules=com.cloud.api.commands.ListPortForwardingRulesCmd;15
createPortForwardingRule=com.cloud.api.commands.CreateIPForwardingRuleCmd;15
deletePortForwardingRule=com.cloud.api.commands.DeleteIPForwardingRuleCmd;15
updatePortForwardingRule=com.cloud.api.commands.UpdateIPForwardingRuleCmd;15
createPortForwardingRule=com.cloud.api.commands.CreatePortForwardingRuleCmd;15
deletePortForwardingRule=com.cloud.api.commands.DeletePortForwardingRuleCmd;15
updatePortForwardingRule=com.cloud.api.commands.UpdatePortForwardingRuleCmd;15
#### NAT commands
createIpForwardingRule=com.cloud.api.commands.CreateIpForwardingRuleCmd;15
deleteIpForwardingRule=com.cloud.api.commands.DeleteIpForwardingRuleCmd;15
#### load balancer commands
createLoadBalancerRule=com.cloud.api.commands.CreateLoadBalancerRuleCmd;15

View File

@ -123,8 +123,8 @@
</adapters>
<adapters key="com.cloud.storage.allocator.StoragePoolAllocator">
<adapter name="LocalStorage" class="com.cloud.storage.allocator.LocalStoragePoolAllocator"/>
<!-- adapter name="Storage" class="com.cloud.storage.allocator.FirstFitStoragePoolAllocator"/ -->
<!--adapter name="Storage" class="com.cloud.storage.allocator.RandomStoragePoolAllocator"/-->
< adapter name="Storage" class="com.cloud.storage.allocator.FirstFitStoragePoolAllocator"/ >
<adapter name="Storage" class="com.cloud.storage.allocator.RandomStoragePoolAllocator"/>
<adapter name="GarbageCollecting" class="com.cloud.storage.allocator.GarbageCollectingStoragePoolAllocator"/>
</adapters>
<adapters key="com.cloud.agent.manager.allocator.PodAllocator">

View File

@ -74,19 +74,6 @@ Group: System Environment/Libraries
The Cloud.com server libraries provide a set of Java classes used
in the Cloud.com Stack.
%package vnet
Summary: Cloud.com-specific virtual network daemon
Requires: python
Requires: %{name}-daemonize = %{version}-%{release}
Requires: %{name}-python = %{version}-%{release}
Requires: net-tools
Requires: bridge-utils
Obsoletes: vmops-vnet < %{version}-%{release}
Group: System Environment/Daemons
%description vnet
The Cloud.com virtual network daemon manages virtual networks used in the
Cloud.com Stack.
%package agent-scripts
Summary: Cloud.com agent scripts
# FIXME nuke the archdependency
@ -217,7 +204,6 @@ Requires: java >= 1.6.0
Requires: %{name}-utils = %{version}-%{release}, %{name}-core = %{version}-%{release}, %{name}-deps = %{version}-%{release}
Requires: %{name}-agent-libs = %{version}-%{release}
Requires: %{name}-agent-scripts = %{version}-%{release}
Requires: %{name}-vnet = %{version}-%{release}
Requires: python
Requires: %{name}-python = %{version}-%{release}
Requires: commons-httpclient
@ -439,21 +425,6 @@ else
/sbin/service %{name}-console-proxy condrestart >/dev/null 2>&1 || true
fi
%preun vnet
if [ "$1" == "0" ] ; then
/sbin/chkconfig --del %{name}-vnetd > /dev/null 2>&1 || true
/sbin/service %{name}-vnetd stop > /dev/null 2>&1 || true
fi
%post vnet
if [ "$1" == "1" ] ; then
/sbin/chkconfig --add %{name}-vnetd > /dev/null 2>&1 || true
/sbin/chkconfig --level 345 %{name}-vnetd on > /dev/null 2>&1 || true
else
/sbin/service %{name}-vnetd condrestart >/dev/null 2>&1 || true
fi
%files utils
%defattr(0644,root,root,0755)
%{_javadir}/%{name}-utils.jar
@ -520,12 +491,6 @@ fi
%defattr(0644,root,root,0755)
%{_javadir}/%{name}-core.jar
%files vnet
%defattr(0644,root,root,0755)
%attr(0755,root,root) %{_sbindir}/%{name}-vnetd
%attr(0755,root,root) %{_sbindir}/%{name}-vn
%attr(0755,root,root) %{_initrddir}/%{name}-vnetd
%files python
%defattr(0644,root,root,0755)
%{_prefix}/lib*/python*/site-packages/%{name}*

View File

@ -25,6 +25,8 @@ public class SetFirewallRuleCommand extends RoutingCommand {
String routerIpAddress;
String oldPrivateIP = null;
String oldPrivatePort = null;
boolean nat = false;
boolean create = false;
protected SetFirewallRuleCommand() {
}
@ -37,10 +39,12 @@ public class SetFirewallRuleCommand extends RoutingCommand {
this.oldPrivatePort = oldPrivatePort;
}
public SetFirewallRuleCommand(String routerName, String routerIpAddress, FirewallRuleVO rule) {
public SetFirewallRuleCommand(String routerName, String routerIpAddress, boolean nat, FirewallRuleVO rule, boolean create) {
this.routerName = routerName;
this.routerIpAddress = routerIpAddress;
this.nat = nat;
this.rule = rule;
this.create = create;
}
@Override
@ -96,4 +100,12 @@ public class SetFirewallRuleCommand extends RoutingCommand {
return this.oldPrivatePort;
}
public boolean isNat(){
return this.nat;
}
public boolean isCreate() {
return create;
}
}

View File

@ -26,6 +26,7 @@ public interface DataCenterIpAddressDao extends GenericDao<DataCenterIpAddressVO
boolean mark(long dcId, long podId, String ip);
List<DataCenterIpAddressVO> listByPodIdDcIdIpAddress(long podId, long dcId, String ipAddress);
List<DataCenterIpAddressVO> listByPodIdDcId(long podId, long dcId);
int countIPs(long podId, long dcId, boolean onlyCountAllocated);
boolean deleteIpAddressByPod(long podId);

View File

@ -1115,32 +1115,44 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
protected Answer execute(final SetFirewallRuleCommand cmd) {
String args;
if (cmd.isEnable()) {
args = "-A";
} else {
args = "-D";
if(cmd.isNat()){
//1:1 NAT needs instanceip;publicip;domrip;op
if(cmd.isCreate())
args = "-A";
else
args = "-D";
args += " -l " + cmd.getPublicIpAddress();
args += " -i " + cmd.getRouterIpAddress();
args += " -r " + cmd.getPrivateIpAddress();
args += " -G " + cmd.getProtocol();
}else{
if (cmd.isEnable()) {
args = "-A";
} else {
args = "-D";
}
args += " -P " + cmd.getProtocol().toLowerCase();
args += " -l " + cmd.getPublicIpAddress();
args += " -p " + cmd.getPublicPort();
args += " -n " + cmd.getRouterName();
args += " -i " + cmd.getRouterIpAddress();
args += " -r " + cmd.getPrivateIpAddress();
args += " -d " + cmd.getPrivatePort();
args += " -N " + cmd.getVlanNetmask();
String oldPrivateIP = cmd.getOldPrivateIP();
String oldPrivatePort = cmd.getOldPrivatePort();
if (oldPrivateIP != null) {
args += " -w " + oldPrivateIP;
}
if (oldPrivatePort != null) {
args += " -x " + oldPrivatePort;
}
}
args += " -P " + cmd.getProtocol().toLowerCase();
args += " -l " + cmd.getPublicIpAddress();
args += " -p " + cmd.getPublicPort();
args += " -n " + cmd.getRouterName();
args += " -i " + cmd.getRouterIpAddress();
args += " -r " + cmd.getPrivateIpAddress();
args += " -d " + cmd.getPrivatePort();
args += " -N " + cmd.getVlanNetmask();
String oldPrivateIP = cmd.getOldPrivateIP();
String oldPrivatePort = cmd.getOldPrivatePort();
if (oldPrivateIP != null) {
args += " -w " + oldPrivateIP;
}
if (oldPrivatePort != null) {
args += " -x " + oldPrivatePort;
}
String result = callHostPlugin("vmops", "setFirewallRule", "args", args);
if (result == null || result.isEmpty()) {
@ -4680,7 +4692,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
vdir.type = Types.VdiType.USER;
if(cmd.getSize()!=0)
vdir.virtualSize = cmd.getSize();
vdir.virtualSize = (cmd.getSize()*1024*1024*1L);
else
vdir.virtualSize = dskch.getSize();
vdi = VDI.create(conn, vdir);

View File

@ -44,5 +44,6 @@ public interface FirewallRulesDao extends GenericDao<FirewallRuleVO, Long> {
public List<FirewallRuleVO> listBySecurityGroupId(long securityGroupId);
public List<FirewallRuleVO> listByLoadBalancerId(long loadBalancerId);
public List<FirewallRuleVO> listForwardingByPubAndPrivIp(boolean forwarding, String publicIPAddress, String privateIp);
public FirewallRuleVO findByGroupAndPrivateIp(long groupId, String privateIp, boolean forwarding);
public FirewallRuleVO findByGroupAndPrivateIp(long groupId, String privateIp, boolean forwarding);
List<FirewallRuleVO> findByPublicIpPrivateIpForNatRule(String publicIp,String privateIp);
}

View File

@ -55,7 +55,8 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
protected SearchBuilder<FirewallRuleVO> FWByPrivateIPSearch;
protected SearchBuilder<FirewallRuleVO> RulesExcludingPubIpPort;
protected SearchBuilder<FirewallRuleVO> FWByGroupId;
protected SearchBuilder<FirewallRuleVO> FWByGroupAndPrivateIp;
protected SearchBuilder<FirewallRuleVO> FWByGroupAndPrivateIp;
protected SearchBuilder<FirewallRuleVO> FWByPrivateIpPrivatePortPublicIpPublicPortSearch;
protected FirewallRulesDaoImpl() {
}
@ -124,6 +125,13 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
FWByGroupAndPrivateIp.and("forwarding", FWByGroupAndPrivateIp.entity().isForwarding(), SearchCriteria.Op.EQ);
FWByGroupAndPrivateIp.done();
FWByPrivateIpPrivatePortPublicIpPublicPortSearch = createSearchBuilder();
FWByPrivateIpPrivatePortPublicIpPublicPortSearch.and("publicIpAddress", FWByPrivateIpPrivatePortPublicIpPublicPortSearch.entity().getPublicIpAddress(), SearchCriteria.Op.EQ);
FWByPrivateIpPrivatePortPublicIpPublicPortSearch.and("privateIpAddress", FWByPrivateIpPrivatePortPublicIpPublicPortSearch.entity().getPrivateIpAddress(), SearchCriteria.Op.EQ);
FWByPrivateIpPrivatePortPublicIpPublicPortSearch.and("privatePort", FWByPrivateIpPrivatePortPublicIpPublicPortSearch.entity().getPrivatePort(), SearchCriteria.Op.NULL);
FWByPrivateIpPrivatePortPublicIpPublicPortSearch.and("publicPort", FWByPrivateIpPrivatePortPublicIpPublicPortSearch.entity().getPublicPort(), SearchCriteria.Op.NULL);
FWByPrivateIpPrivatePortPublicIpPublicPortSearch.done();
return true;
}
@ -306,5 +314,13 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
sc.setParameters("forwarding", forwarding);
return findOneBy(sc);
}
@Override
public List<FirewallRuleVO> findByPublicIpPrivateIpForNatRule(String publicIp, String privateIp){
SearchCriteria<FirewallRuleVO> sc = FWByPrivateIpPrivatePortPublicIpPublicPortSearch.create();
sc.setParameters("publicIpAddress", publicIp);
sc.setParameters("privateIpAddress", privateIp);
return listBy(sc);
}
}

View File

@ -238,7 +238,6 @@ public class VolumeVO implements Volume {
}
public boolean isRecreatable() {
return recreatable;
}

View File

@ -26,6 +26,8 @@ import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import com.cloud.vm.VirtualMachine.Type;
/**
* SecondaryStorageVmVO domain object
@ -86,7 +88,11 @@ public class SecondaryStorageVmVO extends VMInstanceVO implements SecondaryStora
@Temporal(TemporalType.TIMESTAMP)
@Column(name="last_update", updatable=true, nullable=true)
private Date lastUpdateTime;
public SecondaryStorageVmVO(long id, long serviceOfferingId, String name, long templateId, long guestOSId, long dataCenterId,
long domainId, long accountId) {
super(id, serviceOfferingId, name, name, Type.SecondaryStorageVm, templateId, guestOSId, domainId, accountId, true);
}
public SecondaryStorageVmVO(
long id,

View File

@ -1,3 +0,0 @@
/usr/sbin/cloud-vn
/usr/sbin/cloud-vnetd
/etc/init.d/cloud-vnetd

View File

@ -1,13 +0,0 @@
#!/bin/sh -e
case "$1" in
configure)
if [ "$2" = "" ] ; then # no recently configured version, this is a first install
/usr/sbin/update-rc.d cloud-vnet defaults || true
fi
;;
esac
#DEBHELPER#

12
debian/control vendored
View File

@ -49,16 +49,6 @@ Description: Cloud.com server library
The Cloud.com server libraries provide a set of Java classes used
in the Cloud.com Cloud Stack.
Package: cloud-vnet
Provides: vmops-vnet
Conflicts: vmops-vnet
Replaces: vmops-vnet
Architecture: any
Depends: cloud-daemonize (= ${source:Version}), cloud-python (= ${source:Version}), python, bridge-utils, net-tools
Description: Cloud.com-specific virtual network daemon
The Cloud.com virtual network daemon manages virtual networks used in the
Cloud.com Cloud Stack.
Package: cloud-agent-scripts
Provides: vmops-agent-scripts, vmops-console, cloud-console, vmops-console-proxy
Conflicts: vmops-agent-scripts, vmops-console, cloud-console, vmops-console-proxy
@ -151,7 +141,7 @@ Provides: vmops-agent
Conflicts: vmops-agent
Replaces: vmops-agent
Architecture: any
Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-deps (= ${source:Version}), python, cloud-python (= ${source:Version}), cloud-agent-libs (= ${source:Version}), cloud-agent-scripts (= ${source:Version}), cloud-vnet (= ${source:Version}), libcommons-httpclient-java, libcommons-collections-java, libcommons-dbcp-java, libcommons-pool-java, libcommons-logging-java, libvirt0, cloud-daemonize, sysvinit-utils, chkconfig, qemu-kvm, libvirt-bin, cgroup-bin, augeas-tools, uuid-runtime, rsync, grep, iproute
Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-deps (= ${source:Version}), python, cloud-python (= ${source:Version}), cloud-agent-libs (= ${source:Version}), cloud-agent-scripts (= ${source:Version}), libcommons-httpclient-java, libcommons-collections-java, libcommons-dbcp-java, libcommons-pool-java, libcommons-logging-java, libvirt0, cloud-daemonize, sysvinit-utils, chkconfig, qemu-kvm, libvirt-bin, cgroup-bin, augeas-tools, uuid-runtime, rsync, grep, iproute
Description: Cloud.com agent
The Cloud.com agent is in charge of managing shared computing resources in
a Cloud.com Cloud Stack-powered cloud. Install this package if this computer

View File

@ -9,7 +9,7 @@ usage() {
printf "Usage: %s: (-A|-D) -i <domR eth1 ip> -r <target-instance-ip> -P protocol (-p port_range | -t icmp_type_code) -l <public ip address> -d <target port> [-f <firewall ip> -u <firewall user> -y <firewall password> -z <firewall enable password> ] \n" $(basename $0) >&2
}
set -x
# set -x
get_dom0_ip () {
eval "$1=$(ifconfig eth0 | awk '/inet addr/ {split ($2,A,":"); print A[2]}')"
@ -71,6 +71,36 @@ icmp_entry() {
return $?
}
#Add 1:1 NAT entry
add_one_to_one_nat_entry() {
local guestIp=$1
local publicIp=$2
local dIp=$3
local op=$4
if [ "$op" == "-D" ]
then
iptables -t nat $op PREROUTING -i eth2 -d $publicIp -j DNAT --to-destination $guestIp
if [ $? -gt 0 ]
then
return 0
fi
else
iptables -t nat $op PREROUTING -i eth2 -d $publicIp -j DNAT --to-destination $guestIp
fi
iptables -t nat $op POSTROUTING -o eth2 -s $guestIp -j SNAT --to-source $publicIp
if [ "$op" == "-A" ]
then
iptables -P FORWARD DROP
else
iptables -P FORWARD ACCEPT
fi
iptables $op FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables $op FORWARD -i eth2 -o eth0 -d $guestIp -m state --state NEW -j ACCEPT
iptables $op FORWARD -i eth0 -o eth2 -s $guestIp -m state --state NEW -j ACCEPT
return $?
}
get_vif_list() {
local vif_list=""
for i in /sys/class/net/eth*; do
@ -107,11 +137,12 @@ wflag=
xflag=
nflag=
Nflag=
Gflag=
op=""
oldPrivateIP=""
oldPrivatePort=""
while getopts 'ADr:i:P:p:t:l:d:w:x:n:N:' OPTION
while getopts 'ADr:i:P:p:t:l:d:w:x:n:N:G:' OPTION
do
case $OPTION in
A) Aflag=1
@ -153,12 +184,23 @@ do
N) Nflag=1
netmask="$OPTARG"
;;
G) Gflag=1
nat="$OPTARG"
;;
?) usage
exit 2
;;
esac
done
#1:1 NAT
if [ "$Gflag" == "1" ]
then
add_one_to_one_nat_entry $instanceIp $publicIp $domRIp $op
fi
exit $?
fi
reverseOp=$(reverse_op $op)
VIF_LIST=$(get_vif_list)

View File

@ -33,11 +33,12 @@ wflag=
xflag=
nflag=
Nflag=
Gflag=
op=""
oldPrivateIP=""
oldPrivatePort=""
while getopts 'ADr:i:P:p:t:l:d:w:x:n:N:' OPTION
while getopts 'ADr:i:P:p:t:l:d:w:x:n:N:G:' OPTION
do
case $OPTION in
A) Aflag=1
@ -79,6 +80,9 @@ do
N) Nflag=1
netmask="$OPTARG"
;;
G) Gflag=1
nat="OPTARG"
;;
?) usage
exit 2
;;
@ -101,12 +105,6 @@ then
exit 2
fi
if [ "$rflag$iflag$Pflag$pflag$tflag$lflag" != "11111" ]
then
usage
exit 2
fi
#Require -d with -p
if [ "$pflag$dflag" != 11 -a "$pflag$dflag" != "" ]
then

View File

@ -231,4 +231,4 @@ case $protocol in
;;
esac
exit 0
exit 0

View File

@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/utils"/>
<classpathentry kind="lib" path="/thirdparty/log4j-1.2.15.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/core"/>
<classpathentry kind="lib" path="/thirdparty/cglib-nodep-2.2.jar"/>
<classpathentry kind="lib" path="/thirdparty/ehcache-1.5.0.jar"/>
<classpathentry kind="lib" path="/thirdparty/gson-1.3.jar"/>
<classpathentry kind="lib" path="/thirdparty/commons-httpclient-3.1.jar"/>
<classpathentry kind="lib" path="/thirdparty/httpcore-4.0.jar"/>
<classpathentry kind="lib" path="/thirdparty/email.jar"/>
<classpathentry kind="lib" path="/thirdparty/junit-4.8.1.jar"/>
<classpathentry kind="lib" path="/thirdparty/xenserver-5.5.0-1.jar"/>
<classpathentry kind="lib" path="/thirdparty/ws-commons-util-1.0.2.jar"/>
<classpathentry kind="lib" path="/thirdparty/xmlrpc-client-3.1.3.jar"/>
<classpathentry kind="lib" path="/thirdparty/xmlrpc-common-3.1.3.jar"/>
<classpathentry kind="lib" path="/thirdparty/commons-codec-1.4.jar"/>
<classpathentry kind="lib" path="/thirdparty/servlet-api.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/api"/>
<classpathentry kind="lib" path="/thirdparty/trilead-ssh2-build213.jar"/>
<classpathentry kind="lib" path="/thirdparty/xstream-1.3.1.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/utils"/>
<classpathentry kind="lib" path="/thirdparty/log4j-1.2.15.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/core"/>
<classpathentry kind="lib" path="/thirdparty/cglib-nodep-2.2.jar"/>
<classpathentry kind="lib" path="/thirdparty/ehcache-1.5.0.jar"/>
<classpathentry kind="lib" path="/thirdparty/gson-1.3.jar"/>
<classpathentry kind="lib" path="/thirdparty/commons-httpclient-3.1.jar"/>
<classpathentry kind="lib" path="/thirdparty/httpcore-4.0.jar"/>
<classpathentry kind="lib" path="/thirdparty/email.jar"/>
<classpathentry kind="lib" path="/thirdparty/junit-4.8.1.jar"/>
<classpathentry kind="lib" path="/thirdparty/xenserver-5.5.0-1.jar"/>
<classpathentry kind="lib" path="/thirdparty/ws-commons-util-1.0.2.jar"/>
<classpathentry kind="lib" path="/thirdparty/xmlrpc-client-3.1.3.jar"/>
<classpathentry kind="lib" path="/thirdparty/xmlrpc-common-3.1.3.jar"/>
<classpathentry kind="lib" path="/thirdparty/commons-codec-1.4.jar"/>
<classpathentry kind="lib" path="/thirdparty/servlet-api.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/api"/>
<classpathentry kind="lib" path="/thirdparty/trilead-ssh2-build213.jar"/>
<classpathentry kind="lib" path="/thirdparty/xstream-1.3.1.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -54,6 +54,7 @@ import com.cloud.configuration.ConfigurationVO;
import com.cloud.configuration.ResourceCount.ResourceType;
import com.cloud.configuration.ResourceLimit;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.Vlan.VlanType;
@ -67,6 +68,8 @@ import com.cloud.host.Status.Event;
import com.cloud.network.FirewallRuleVO;
import com.cloud.network.IPAddressVO;
import com.cloud.network.LoadBalancerVO;
import com.cloud.network.Network.TrafficType;
import com.cloud.network.NetworkConfiguration;
import com.cloud.offering.NetworkOffering.GuestIpType;
import com.cloud.offering.ServiceOffering;
import com.cloud.server.Criteria;
@ -91,6 +94,7 @@ import com.cloud.uservm.UserVm;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.DomainRouter;
import com.cloud.vm.InstanceGroupVO;
import com.cloud.vm.Nic;
import com.cloud.vm.SecondaryStorageVmVO;
import com.cloud.vm.State;
import com.cloud.vm.SystemVm;
@ -351,6 +355,9 @@ public class ApiResponseHelper {
}
public static UserVmResponse createUserVmResponse (UserVm userVm) {
if (userVm.getPrivateIpAddress() == null) {
return createUserVm2Response(userVm);
}
UserVmResponse userVmResponse = new UserVmResponse();
Account acct = ApiDBUtils.findAccountById(Long.valueOf(userVm.getAccountId()));
//FIXME - this check should be done in searchForUserVm method in ManagementServerImpl;
@ -377,7 +384,6 @@ public class ApiResponseHelper {
userVmResponse.setState(userVm.getState().toString());
}
userVmResponse.setHaEnable(userVm.isHaEnabled());
if (userVm.getDisplayName() != null) {
@ -473,6 +479,9 @@ public class ApiResponseHelper {
}
public static SystemVmResponse createSystemVmResponse (VMInstanceVO systemVM) {
if (systemVM.getPrivateIpAddress() == null) {
return createSystemVm2Response(systemVM);
}
SystemVmResponse vmResponse = new SystemVmResponse();
if (systemVM instanceof SystemVm) {
SystemVm vm = (SystemVm)systemVM;
@ -528,6 +537,9 @@ public class ApiResponseHelper {
public static DomainRouterResponse createDomainRouterResponse (DomainRouter router) {
if (router.getPrivateIpAddress() == null) {
return createDomainRouter2Response(router);
}
DomainRouterResponse routerResponse = new DomainRouterResponse();
routerResponse.setId(router.getId());
@ -985,4 +997,276 @@ public class ApiResponseHelper {
return response;
}
public static UserVmResponse createUserVm2Response (UserVm userVm) {
UserVmResponse userVmResponse = new UserVmResponse();
Account acct = ApiDBUtils.findAccountById(Long.valueOf(userVm.getAccountId()));
//FIXME - this check should be done in searchForUserVm method in ManagementServerImpl;
//otherwise the number of vms returned is not going to match pageSize request parameter
if ((acct != null) && (acct.getRemoved() == null)) {
userVmResponse.setAccountName(acct.getAccountName());
userVmResponse.setDomainId(acct.getDomainId());
userVmResponse.setDomainName(ApiDBUtils.findDomainById(acct.getDomainId()).getName());
} else {
return null; // the account has been deleted, skip this VM in the response
}
userVmResponse.setId(userVm.getId());
AsyncJobVO asyncJob = ApiDBUtils.findInstancePendingAsyncJob("vm_instance", userVm.getId());
if (asyncJob != null) {
userVmResponse.setJobId(asyncJob.getId());
userVmResponse.setJobStatus(asyncJob.getStatus());
}
userVmResponse.setName(userVm.getHostName());
userVmResponse.setCreated(userVm.getCreated());
if (userVm.getState() != null) {
userVmResponse.setState(userVm.getState().toString());
}
userVmResponse.setHaEnable(userVm.isHaEnabled());
if (userVm.getDisplayName() != null) {
userVmResponse.setDisplayName(userVm.getDisplayName());
} else {
userVmResponse.setDisplayName(userVm.getHostName());
}
InstanceGroupVO group = ApiDBUtils.findInstanceGroupForVM(userVm.getId());
if (group != null) {
userVmResponse.setGroup(group.getName());
userVmResponse.setGroupId(group.getId());
}
// Data Center Info
userVmResponse.setZoneId(userVm.getDataCenterId());
userVmResponse.setZoneName(ApiDBUtils.findZoneById(userVm.getDataCenterId()).getName());
Account account = UserContext.current().getAccount();
//if user is an admin, display host id
if (((account == null) || (account.getType() == Account.ACCOUNT_TYPE_ADMIN)) && (userVm.getHostId() != null)) {
userVmResponse.setHostId(userVm.getHostId());
userVmResponse.setHostName(ApiDBUtils.findHostById(userVm.getHostId()).getName());
}
// Template Info
VMTemplateVO template = ApiDBUtils.findTemplateById(userVm.getTemplateId());
if (template != null) {
userVmResponse.setTemplateId(userVm.getTemplateId());
userVmResponse.setTemplateName(template.getName());
userVmResponse.setTemplateDisplayText(template.getDisplayText());
userVmResponse.setPasswordEnabled(template.getEnablePassword());
} else {
userVmResponse.setTemplateId(-1L);
userVmResponse.setTemplateName("ISO Boot");
userVmResponse.setTemplateDisplayText("ISO Boot");
userVmResponse.setPasswordEnabled(false);
}
if (userVm.getPassword() != null) {
userVmResponse.setPassword(userVm.getPassword());
}
// ISO Info
if (userVm.getIsoId() != null) {
VMTemplateVO iso = ApiDBUtils.findTemplateById(userVm.getIsoId().longValue());
if (iso != null) {
userVmResponse.setIsoId(userVm.getIsoId());
userVmResponse.setIsoName(iso.getName());
}
}
// Service Offering Info
ServiceOffering offering = ApiDBUtils.findServiceOfferingById(userVm.getServiceOfferingId());
userVmResponse.setServiceOfferingId(userVm.getServiceOfferingId());
userVmResponse.setServiceOfferingName(offering.getName());
userVmResponse.setCpuNumber(offering.getCpu());
userVmResponse.setCpuSpeed(offering.getSpeed());
userVmResponse.setMemory(offering.getRamSize());
VolumeVO rootVolume = ApiDBUtils.findRootVolume(userVm.getId());
if (rootVolume != null) {
userVmResponse.setRootDeviceId(rootVolume.getDeviceId());
String rootDeviceType = "Not created";
if (rootVolume.getPoolId() != null){
StoragePoolVO storagePool = ApiDBUtils.findStoragePoolById(rootVolume.getPoolId());
rootDeviceType = storagePool.getPoolType().toString();
}
userVmResponse.setRootDeviceType(rootDeviceType);
}
//stats calculation
DecimalFormat decimalFormat = new DecimalFormat("#.##");
String cpuUsed = null;
VmStats vmStats = ApiDBUtils.getVmStatistics(userVm.getId());
if (vmStats != null) {
float cpuUtil = (float) vmStats.getCPUUtilization();
cpuUsed = decimalFormat.format(cpuUtil) + "%";
userVmResponse.setCpuUsed(cpuUsed);
long networkKbRead = (long)vmStats.getNetworkReadKBs();
userVmResponse.setNetworkKbsRead(networkKbRead);
long networkKbWrite = (long)vmStats.getNetworkWriteKBs();
userVmResponse.setNetworkKbsWrite(networkKbWrite);
}
userVmResponse.setGuestOsId(userVm.getGuestOSId());
//network groups
userVmResponse.setNetworkGroupList(ApiDBUtils.getNetworkGroupsNamesForVm(userVm.getId()));
List<? extends Nic> nics = BaseCmd._networkMgr.getNics(userVm);
for (Nic singleNic : nics) {
long configId = singleNic.getNetworkConfigurationId();
NetworkConfiguration networkConf = BaseCmd._networkMgr.getNetworkConfiguration(configId);
if (networkConf.getTrafficType() == TrafficType.Guest) {
userVmResponse.setIpAddress(singleNic.getIp4Address());
}
}
userVmResponse.setObjectName("virtualmachine");
return userVmResponse;
}
public static DomainRouterResponse createDomainRouter2Response (DomainRouter router) {
DomainRouterResponse routerResponse = new DomainRouterResponse();
routerResponse.setId(router.getId());
routerResponse.setZoneId(router.getDataCenterId());
routerResponse.setName(router.getHostName());
routerResponse.setPodId(router.getPodId());
routerResponse.setTemplateId(router.getTemplateId());
routerResponse.setCreated(router.getCreated());
routerResponse.setState(router.getState());
routerResponse.setNetworkDomain(router.getDomain());
if (router.getHostId() != null) {
routerResponse.setHostId(router.getHostId());
routerResponse.setHostName(ApiDBUtils.findHostById(router.getHostId()).getName());
}
Account accountTemp = ApiDBUtils.findAccountById(router.getAccountId());
if (accountTemp != null) {
routerResponse.setAccountName(accountTemp.getAccountName());
routerResponse.setDomainId(accountTemp.getDomainId());
routerResponse.setDomainName(ApiDBUtils.findDomainById(accountTemp.getDomainId()).getName());
}
AsyncJobVO asyncJob = ApiDBUtils.findInstancePendingAsyncJob("domain_router", router.getId());
if (asyncJob != null) {
routerResponse.setJobId(asyncJob.getId());
routerResponse.setJobStatus(asyncJob.getStatus());
}
List<? extends Nic> nics = BaseCmd._networkMgr.getNics(router);
for (Nic singleNic : nics) {
long configId = singleNic.getNetworkConfigurationId();
NetworkConfiguration networkConf = BaseCmd._networkMgr.getNetworkConfiguration(configId);
if (networkConf.getTrafficType() == TrafficType.Guest) {
routerResponse.setGuestIpAddress(singleNic.getIp4Address());
routerResponse.setGuestMacAddress(singleNic.getMacAddress());
routerResponse.setGuestNetmask(singleNic.getNetmask());
}
if (networkConf.getTrafficType() == TrafficType.Control) {
routerResponse.setPrivateIp(singleNic.getIp4Address());
routerResponse.setPrivateMacAddress(singleNic.getMacAddress());
routerResponse.setPrivateNetmask(singleNic.getNetmask());
}
if (networkConf.getTrafficType() == TrafficType.Public) {
routerResponse.setPublicIp(singleNic.getIp4Address());
routerResponse.setPublicMacAddress(singleNic.getMacAddress());
routerResponse.setPublicNetmask(singleNic.getNetmask());
routerResponse.setGateway(singleNic.getGateway());
}
DataCenter zone = ApiDBUtils.findZoneById(router.getDataCenterId());
if (zone != null) {
routerResponse.setZoneName(zone.getName());
routerResponse.setDns1(zone.getDns1());
routerResponse.setDns2(zone.getDns2());
}
}
routerResponse.setObjectName("domainrouter");
return routerResponse;
}
public static SystemVmResponse createSystemVm2Response (VMInstanceVO systemVM) {
SystemVmResponse vmResponse = new SystemVmResponse();
if (systemVM instanceof SystemVm) {
SystemVm vm = (SystemVm)systemVM;
vmResponse.setId(vm.getId());
vmResponse.setSystemVmType(vm.getType().toString().toLowerCase());
vmResponse.setZoneId(vm.getDataCenterId());
vmResponse.setNetworkDomain(vm.getDomain());
vmResponse.setName(vm.getHostName());
vmResponse.setPodId(vm.getPodId());
vmResponse.setTemplateId(vm.getTemplateId());
vmResponse.setCreated(vm.getCreated());
if (vm.getHostId() != null) {
vmResponse.setHostId(vm.getHostId());
vmResponse.setHostName(ApiDBUtils.findHostById(vm.getHostId()).getName());
}
if (vm.getState() != null) {
vmResponse.setState(vm.getState().toString());
}
String instanceType = "console_proxy";
if (systemVM instanceof SecondaryStorageVmVO) {
instanceType = "sec_storage_vm"; // FIXME: this should be a constant so that the async jobs get updated with the correct instance type, they are using
// different instance types at the moment
}
AsyncJobVO asyncJob = ApiDBUtils.findInstancePendingAsyncJob(instanceType, vm.getId());
if (asyncJob != null) {
vmResponse.setJobId(asyncJob.getId());
vmResponse.setJobStatus(asyncJob.getStatus());
}
// for console proxies, add the active sessions
if (systemVM instanceof ConsoleProxyVO) {
ConsoleProxyVO proxy = (ConsoleProxyVO)systemVM;
vmResponse.setActiveViewerSessions(proxy.getActiveSession());
}
DataCenter zone = ApiDBUtils.findZoneById(vm.getDataCenterId());
if (zone != null) {
vmResponse.setZoneName(zone.getName());
vmResponse.setDns1(zone.getDns1());
vmResponse.setDns2(zone.getDns2());
}
List<? extends Nic> nics = BaseCmd._networkMgr.getNics(systemVM);
for (Nic singleNic : nics) {
long configId = singleNic.getNetworkConfigurationId();
NetworkConfiguration networkConf = BaseCmd._networkMgr.getNetworkConfiguration(configId);
if (networkConf.getTrafficType() == TrafficType.Management) {
vmResponse.setPrivateIp(singleNic.getIp4Address());
vmResponse.setPrivateMacAddress(singleNic.getMacAddress());
vmResponse.setPrivateNetmask(singleNic.getNetmask());
}
if (networkConf.getTrafficType() == TrafficType.Public) {
vmResponse.setPublicIp(singleNic.getIp4Address());
vmResponse.setPublicMacAddress(singleNic.getMacAddress());
vmResponse.setPublicNetmask(singleNic.getNetmask());
vmResponse.setGateway(singleNic.getGateway());
}
}
}
vmResponse.setObjectName("systemvm");
return vmResponse;
}
}

View File

@ -90,6 +90,7 @@ import com.cloud.exception.CloudAuthenticationException;
import com.cloud.maid.StackMaid;
import com.cloud.server.ManagementServer;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.User;
import com.cloud.user.UserAccount;
import com.cloud.user.UserContext;
@ -113,6 +114,9 @@ public class ApiServer implements HttpRequestHandler {
//private AsyncJobManager _asyncMgr;
private ApiDispatcher _dispatcher;
private ManagementServer _ms = null;
private AccountManager _accountMgr = null;
private Account _systemAccount = null;
private User _systemUser = null;
private static int _workerCount = 0;
@ -187,6 +191,9 @@ public class ApiServer implements HttpRequestHandler {
_ms = (ManagementServer)ComponentLocator.getComponent(ManagementServer.Name);
ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name);
_accountMgr = locator.getManager(AccountManager.class);
_systemAccount = _accountMgr.getSystemAccount();
_systemUser = _accountMgr.getSystemUser();
//_asyncMgr = locator.getManager(AsyncJobManager.class);
_dispatcher = ApiDispatcher.getInstance();
@ -247,7 +254,7 @@ public class ApiServer implements HttpRequestHandler {
}
try {
// always trust commands from API port, user context will always be UID_SYSTEM/ACCOUNT_ID_SYSTEM
UserContext.registerContext(User.UID_SYSTEM, null, null, Account.ACCOUNT_ID_SYSTEM, null, null, true);
UserContext.registerContext(_systemUser.getId(), _systemAccount, _systemAccount.getAccountName(), _systemAccount.getId(), null, null, true);
sb.insert(0,"(userId="+User.UID_SYSTEM+ " accountId="+Account.ACCOUNT_ID_SYSTEM+ " sessionId="+null+ ") " );
String responseText = handleRequest(parameterMap, true, responseType, sb);
sb.append(" 200 " + ((responseText == null) ? 0 : responseText.length()));
@ -362,7 +369,7 @@ public class ApiServer implements HttpRequestHandler {
UserContext ctx = UserContext.current();
Long userId = ctx.getUserId();
Account account = (Account)ctx.getAccount();
Account account = ctx.getAccount();
if (userId != null) {
params.put("ctxUserId", userId.toString());
}

View File

@ -101,7 +101,9 @@ public class ApiServlet extends HttpServlet {
if (userId != null) {
_apiServer.logoutUser(userId);
}
session.invalidate();
try {
session.invalidate();
}catch (IllegalStateException ise) {}
}
auditTrailSb.append("command=logout");
auditTrailSb.append(" " +HttpServletResponse.SC_OK);
@ -110,7 +112,11 @@ public class ApiServlet extends HttpServlet {
} else if ("login".equalsIgnoreCase(command)) {
auditTrailSb.append("command=login");
// if this is a login, authenticate the user and return
if (session != null) session.invalidate();
if (session != null) {
try {
session.invalidate();
}catch (IllegalStateException ise) {}
}
session = req.getSession(true);
String[] username = (String[])params.get("username");
String[] password = (String[])params.get("password");
@ -160,7 +166,9 @@ public class ApiServlet extends HttpServlet {
return;
} catch (CloudAuthenticationException ex) {
// TODO: fall through to API key, or just fail here w/ auth error? (HTTP 401)
session.invalidate();
try {
session.invalidate();
}catch (IllegalStateException ise) {}
auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "failed to authenticated user, check username/password are correct");
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "failed to authenticated user, check username/password are correct");
return;
@ -185,7 +193,9 @@ public class ApiServlet extends HttpServlet {
String sessionKey = (String)session.getAttribute("sessionkey");
String[] sessionKeyParam = (String[])params.get("sessionkey");
if ((sessionKeyParam == null) || (sessionKey == null) || !sessionKey.equals(sessionKeyParam[0])) {
session.invalidate();
try {
session.invalidate();
}catch (IllegalStateException ise) {}
auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "unable to verify user credentials");
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials");
return;
@ -204,7 +214,9 @@ public class ApiServlet extends HttpServlet {
} else {
// Invalidate the session to ensure we won't allow a request across management server restarts if the userId was serialized to the
// stored session
session.invalidate();
try {
session.invalidate();
}catch (IllegalStateException ise) {}
auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "unable to verify user credentials");
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials");
return;
@ -242,7 +254,9 @@ public class ApiServlet extends HttpServlet {
}
} else {
if (session != null) {
session.invalidate();
try {
session.invalidate();
}catch (IllegalStateException ise) {}
}
auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "unable to verify user credentials and/or request signature");
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials and/or request signature");

View File

@ -6,6 +6,7 @@ import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;

View File

@ -0,0 +1,114 @@
/**
* Copyright (C) 2010 Cloud.com, 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.api.commands;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.ApiResponseHelper;
import com.cloud.api.BaseAsyncCreateCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.FirewallRuleResponse;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.FirewallRuleVO;
import com.cloud.user.Account;
@Implementation(description="Creates an ip forwarding rule")
public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd {
public static final Logger s_logger = Logger.getLogger(CreateIpForwardingRuleCmd.class.getName());
private static final String s_name = "createipforwardingruleresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, required=true, description="the public IP address of the forwarding rule, already associated via associateIp")
private String ipAddress;
@Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.LONG, required=true, description="the ID of the virtual machine for the forwarding rule")
private Long virtualMachineId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getIpAddress() {
return ipAddress;
}
public Long getVirtualMachineId() {
return virtualMachineId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getName() {
return s_name;
}
@Override
public void execute() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException{
FirewallRuleVO result = _networkMgr.createIpForwardingRuleOnDomr(this.getId());
if (result != null) {
FirewallRuleResponse fwResponse = ApiResponseHelper.createFirewallRuleResponse(result);
fwResponse.setResponseName(getName());
this.setResponseObject(fwResponse);
} else {
throw new ServerApiException(NET_CREATE_IPFW_RULE_ERROR, "Error in creating ip forwarding rule on the domr");
}
}
@Override
public void callCreate() throws ServerApiException,InvalidParameterValueException, PermissionDeniedException,InsufficientAddressCapacityException,InsufficientCapacityException, ResourceUnavailableException,ConcurrentOperationException, ResourceAllocationException{
FirewallRuleVO rule = _networkMgr.createIpForwardingRuleInDb(ipAddress,virtualMachineId);
this.setId(rule.getId());
}
@Override
public long getAccountId() {
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
}
@Override
public String getEventType() {
return EventTypes.EVENT_NET_RULE_ADD;
}
@Override
public String getEventDescription() {
return ("Creating an ipforwarding 1:1 NAT rule for "+ipAddress+" with virtual machine:"+virtualMachineId);
}
}

View File

@ -36,8 +36,8 @@ import com.cloud.exception.PermissionDeniedException;
import com.cloud.network.FirewallRuleVO;
@Implementation(description="Creates a port forwarding rule")
public class CreateIPForwardingRuleCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(CreateIPForwardingRuleCmd.class.getName());
public class CreatePortForwardingRuleCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(CreatePortForwardingRuleCmd.class.getName());
private static final String s_name = "createportforwardingruleresponse";

View File

@ -0,0 +1,99 @@
/**
* Copyright (C) 2010 Cloud.com, 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.api.commands;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.BaseAsyncCmd;
import com.cloud.api.BaseCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.SuccessResponse;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.user.Account;
@Implementation(description="Deletes an ip forwarding rule")
public class DeleteIpForwardingRuleCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(DeleteIpForwardingRuleCmd.class.getName());
private static final String s_name = "deleteipforwardingruleresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the id of the forwarding rule")
private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getName() {
return s_name;
}
@Override
public void execute() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException{
try {
boolean result = false;
result = _networkMgr.deleteIpForwardingRule(id);
if (result) {
SuccessResponse response = new SuccessResponse(getName());
this.setResponseObject(response);
} else {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete ip forwarding rule");
}
} catch (Exception ex) {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage());
}
}
@Override
public long getAccountId() {
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
}
@Override
public String getEventType() {
return EventTypes.EVENT_NET_RULE_ADD;
}
@Override
public String getEventDescription() {
return ("Deleting an ipforwarding 1:1 NAT rule id:"+id);
}
}

View File

@ -32,8 +32,8 @@ import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
@Implementation(description="Deletes a port forwarding rule")
public class DeleteIPForwardingRuleCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(DeleteIPForwardingRuleCmd.class.getName());
public class DeletePortForwardingRuleCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(DeletePortForwardingRuleCmd.class.getName());
private static final String s_name = "deleteportforwardingruleresponse";
/////////////////////////////////////////////////////
@ -63,7 +63,7 @@ public class DeleteIPForwardingRuleCmd extends BaseCmd {
@Override
public void execute() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException{
boolean result = _networkMgr.deleteIpForwardingRule(this);
boolean result = _networkMgr.deletePortForwardingRule(this);
if (result) {
SuccessResponse response = new SuccessResponse(getName());
this.setResponseObject(response);

View File

@ -24,8 +24,8 @@ import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.ApiResponseHelper;
import com.cloud.api.BaseAsyncCreateCmd;
import com.cloud.api.BaseCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
@ -36,15 +36,10 @@ import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.offering.ServiceOffering;
import com.cloud.storage.VMTemplateVO;
import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.user.UserContext;
import com.cloud.uservm.UserVm;
import com.cloud.vm.InstanceGroupVO;
@Implementation(description="Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.")
public class DeployVm2Cmd extends BaseAsyncCreateCmd {
@ -161,127 +156,19 @@ public class DeployVm2Cmd extends BaseAsyncCreateCmd {
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() {
try {
UserVm userVm = _userVmService.startVirtualMachine(this);
UserVmResponse response = new UserVmResponse();
response.setId(userVm.getId());
response.setName(userVm.getHostName());
response.setCreated(userVm.getCreated());
response.setZoneId(userVm.getDataCenterId());
response.setZoneName(ApiDBUtils.findZoneById(userVm.getDataCenterId()).getName());
response.setIpAddress(userVm.getPrivateIpAddress());
response.setServiceOfferingId(userVm.getServiceOfferingId());
response.setHaEnable(userVm.isHaEnabled());
InstanceGroupVO group = ApiDBUtils.findInstanceGroupForVM(userVm.getId());
if (group != null) {
response.setGroup(group.getName());
response.setGroupId(group.getId());
}
if (userVm.getDisplayName() == null || userVm.getDisplayName().length() == 0) {
response.setDisplayName(userVm.getHostName());
} else {
response.setDisplayName(userVm.getDisplayName());
}
if (userVm.getState() != null) {
response.setState(userVm.getState().toString());
}
VMTemplateVO template = ApiDBUtils.findTemplateById(userVm.getTemplateId());
Account acct = ApiDBUtils.findAccountById(Long.valueOf(userVm.getAccountId()));
if (acct != null) {
response.setAccountName(acct.getAccountName());
response.setDomainId(acct.getDomainId());
response.setDomainName(ApiDBUtils.findDomainById(acct.getDomainId()).getName());
}
Long userId = UserContext.current().getUserId();
if (userId == null) {
userId = User.UID_SYSTEM;
}
//this is for the case where the admin deploys a vm for a normal user
User userExecutingCmd = ApiDBUtils.findUserById(userId);
Account acctForUserExecutingCmd = ApiDBUtils.findAccountById(Long.valueOf(userExecutingCmd.getAccountId()));
if ((BaseCmd.isAdmin(acctForUserExecutingCmd.getType()) && (userVm.getHostId() != null)) || (BaseCmd.isAdmin(acct.getType()) && (userVm.getHostId() != null))) {
response.setHostName(ApiDBUtils.findHostById(userVm.getHostId()).getName());
response.setHostId(userVm.getHostId());
}
String templateName = "none";
boolean templatePasswordEnabled = false;
String templateDisplayText = null;
if (template != null) {
templateName = template.getName();
templatePasswordEnabled = template.getEnablePassword();
templateDisplayText = template.getDisplayText();
if (templateDisplayText == null) {
templateDisplayText = templateName;
}
}
if (templatePasswordEnabled) { // FIXME: where will the password come from in this case?
response.setPassword(getPassword());
}
// ISO Info
Long isoId = userVm.getIsoId();
if (isoId != null) {
VMTemplateVO iso = ApiDBUtils.findTemplateById(isoId.longValue());
if (iso != null) {
response.setIsoId(isoId.longValue());
response.setIsoName(iso.getName());
response.setTemplateId(isoId.longValue());
response.setTemplateName(iso.getName());
templateDisplayText = iso.getDisplayText();
if(templateDisplayText == null)
templateDisplayText = iso.getName();
response.setIsoDisplayText(templateDisplayText);
response.setTemplateDisplayText(templateDisplayText);
}
} else {
response.setTemplateId(userVm.getTemplateId());
response.setTemplateName(templateName);
response.setTemplateDisplayText(templateDisplayText);
response.setPasswordEnabled(templatePasswordEnabled);
}
ServiceOffering offering = ApiDBUtils.findServiceOfferingById(userVm.getServiceOfferingId());
response.setServiceOfferingId(userVm.getServiceOfferingId());
response.setServiceOfferingName(offering.getName());
response.setCpuNumber(offering.getCpu());
response.setCpuSpeed(offering.getSpeed());
response.setMemory(offering.getRamSize());
response.setNetworkGroupList(ApiDBUtils.getNetworkGroupsNamesForVm(userVm.getId()));
public void execute() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException{
UserVm result;
result = _userVmService.startVirtualMachine(this);
UserVmResponse response = ApiResponseHelper.createUserVm2Response(result);
response.setPassword(password);
response.setResponseName(getName());
response.setObjectName("virtualmachine");
this.setResponseObject(response);
} catch (Exception ex) {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to deploy virtual machine");
}
}
@Override
public void callCreate() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException{
try {
UserVm vm = _userVmService.createVirtualMachine(this);
if (vm != null) {
this.setId(vm.getId());
}
} catch (ResourceUnavailableException ex) {
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create a vm");
}
public void callCreate() throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
UserVm vm = _userVmService.createVirtualMachine(this);
this.setId(vm.getId());
}

View File

@ -0,0 +1,103 @@
/**
* Copyright (C) 2010 Cloud.com, 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.api.commands;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.ApiResponseHelper;
import com.cloud.api.BaseAsyncCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.SystemVmResponse;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.server.ManagementServer;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
@Implementation(method="startSystemVM", manager=ManagementServer.class, description="Starts a system virtual machine.")
public class StartSystemVm2Cmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(StartSystemVm2Cmd.class.getName());
private static final String s_name = "startsystemvmresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="The ID of the system virtual machine")
private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getName() {
return s_name;
}
public static String getResultObjectName() {
return "systemvm";
}
@Override
public long getAccountId() {
Account account = UserContext.current().getAccount();
if (account != null) {
return account.getId();
}
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
}
@Override
public String getEventType() {
return EventTypes.EVENT_SSVM_START;
}
@Override
public String getEventDescription() {
return "starting system vm: " + getId();
}
@Override
public void execute() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException{
VirtualMachine instance = _mgr.startSystemVm(this);
SystemVmResponse response = ApiResponseHelper.createSystemVmResponse((VMInstanceVO)instance);
response.setResponseName(getName());
this.setResponseObject(response);
}
}

View File

@ -0,0 +1,98 @@
/**
* Copyright (C) 2010 Cloud.com, 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.api.commands;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.ApiResponseHelper;
import com.cloud.api.BaseAsyncCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.SystemVmResponse;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.server.ManagementServer;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
@Implementation(method="stopSystemVM", manager=ManagementServer.class, description="Stops a system VM.")
public class StopSystemVm2Cmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(StopSystemVm2Cmd.class.getName());
private static final String s_name = "stopsystemvmresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="The ID of the system virtual machine")
private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getName() {
return s_name;
}
@Override
public long getAccountId() {
Account account = UserContext.current().getAccount();
if (account != null) {
return account.getId();
}
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
}
@Override
public String getEventType() {
return EventTypes.EVENT_SSVM_STOP;
}
@Override
public String getEventDescription() {
return "stopping system vm: " + getId();
}
@Override
public void execute() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException{
VirtualMachine instance = _mgr.stopSystemVm(this);
SystemVmResponse response = ApiResponseHelper.createSystemVmResponse((VMInstanceVO)instance);
response.setResponseName(getName());
}
}

View File

@ -19,10 +19,10 @@ import com.cloud.exception.PermissionDeniedException;
import com.cloud.network.FirewallRuleVO;
import com.cloud.network.IPAddressVO;
import com.cloud.user.Account;
@Implementation(description="Updates a port forwarding rule. Only the private port and the virtual machine can be updated.")
public class UpdateIPForwardingRuleCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(UpdateIPForwardingRuleCmd.class.getName());
public class UpdatePortForwardingRuleCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(UpdatePortForwardingRuleCmd.class.getName());
private static final String s_name = "updateportforwardingruleresponse";
/////////////////////////////////////////////////////
@ -38,7 +38,7 @@ public class UpdateIPForwardingRuleCmd extends BaseAsyncCmd {
@Parameter(name=ApiConstants.PROTOCOL, type=CommandType.STRING, required=true, description="the protocol for the port fowarding rule. Valid values are TCP or UDP.")
private String protocol;
@Parameter(name=ApiConstants.PUBLIC_IP, type=CommandType.STRING, required=true, description="the public IP address of the port forwarding rule")
@Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, required=true, description="the IP address of the port forwarding rule")
private String publicIp;
@Parameter(name=ApiConstants.PUBLIC_PORT, type=CommandType.STRING, required=true, description="the public port of the port forwarding rule")

View File

@ -48,7 +48,7 @@ public enum Config {
StorageOverprovisioningFactor("Storage", StoragePoolAllocator.class, String.class, "storage.overprovisioning.factor", "2", "Used for storage overprovisioning calculation; available storage will be (actualStorageSize * storage.overprovisioning.factor)", null),
StorageStatsInterval("Storage", ManagementServer.class, String.class, "storage.stats.interval", "60000", "The interval in milliseconds when storage stats (per host) are retrieved from agents.", null),
MaxVolumeSize("Storage", ManagementServer.class, Integer.class, "max.volume.size.gb", "2000", "The maximum size for a volume in gigabytes.", null),
MaxVolumeSize("Storage", ManagementServer.class, Integer.class, "max.volume.size.mb", "1024000", "The maximum size for a volume in megabytes.", null),
TotalRetries("Storage", AgentManager.class, Integer.class, "total.retries", "4", "The number of times each command sent to a host should be retried in case of failure.", null),
// Network

View File

@ -52,16 +52,18 @@ import com.cloud.configuration.ResourceCount.ResourceType;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.AccountVlanMapVO;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterIpAddressVO;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.Pod;
import com.cloud.dc.PodVlanMapVO;
import com.cloud.dc.Vlan;
import com.cloud.dc.VlanVO;
import com.cloud.dc.Vlan.VlanType;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.AccountVlanMapDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.DataCenterIpAddressDao;
import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDaoImpl;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.dc.dao.PodVlanMapDao;
import com.cloud.dc.dao.VlanDao;
@ -81,8 +83,8 @@ import com.cloud.network.NetworkManager;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.offering.DiskOffering;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.offering.NetworkOffering.GuestIpType;
import com.cloud.offering.ServiceOffering;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.DiskOfferingVO;
@ -97,6 +99,7 @@ import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.Adapters;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.component.Inject;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
@ -140,6 +143,9 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
@Inject NetworkManager _networkMgr;
@Inject(adapter=SecurityChecker.class)
Adapters<SecurityChecker> _secChecker;
//FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao?
protected static final DataCenterLinkLocalIpAddressDaoImpl _LinkLocalIpAllocDao = ComponentLocator.inject(DataCenterLinkLocalIpAddressDaoImpl.class);
private int _maxVolumeSizeInGb;
@ -437,14 +443,27 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
HostPodVO pod = _podDao.findById(podId);
DataCenterVO zone = _zoneDao.findById(pod.getDataCenterId());
//Delete private ip addresses for the pod if there are any
List<DataCenterIpAddressVO> privateIps = _privateIpAddressDao.listByPodIdDcId(Long.valueOf(podId), pod.getDataCenterId());
if (privateIps != null && privateIps.size() != 0) {
if (!(_privateIpAddressDao.deleteIpAddressByPod(podId))) {
throw new CloudRuntimeException("Failed to cleanup private ip addresses for pod " + podId);
}
}
//Delete link local ip addresses for the pod
if (!(_LinkLocalIpAllocDao.deleteIpAddressByPod(podId))) {
throw new CloudRuntimeException("Failed to cleanup private ip addresses for pod " + podId);
}
//Delete the pod and private IP addresses in the pod
if (_podDao.expunge(podId) && _privateIpAddressDao.deleteIpAddressByPod(podId)) {
saveConfigurationEvent(userId, null, EventTypes.EVENT_POD_DELETE, "Successfully deleted pod with name: " + pod.getName() + " in zone: " + zone.getName() + ".", "podId=" + podId, "dcId=" + zone.getId());
return true;
} else {
return false;
//Delete the pod
if (!(_podDao.expunge(podId))) {
throw new CloudRuntimeException("Failed to delete pod " + podId);
}
saveConfigurationEvent(userId, null, EventTypes.EVENT_POD_DELETE, "Successfully deleted pod with name: " + pod.getName() + " in zone: " + zone.getName() + ".", "podId=" + podId, "dcId=" + zone.getId());
return true;
}
@Override
@ -974,7 +993,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
@Override @DB
public DataCenterVO createZone(long userId, String zoneName, String dns1, String dns2, String internalDns1, String internalDns2, String vnetRange, String guestCidr, String domain, Long domainId) {
int vnetStart, vnetEnd;
int vnetStart = -1;
int vnetEnd = -1;
if (vnetRange != null) {
String[] tokens = vnetRange.split("-");
@ -993,9 +1013,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
if (networkType != null && networkType.equals("vnet")) {
vnetStart = 1000;
vnetEnd = 2000;
} else {
throw new InvalidParameterValueException("Please specify a vlan range.");
}
}
}
//checking the following params outside checkzoneparams method as we do not use these params for updatezone
@ -1011,8 +1029,9 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
zone = _zoneDao.persist(zone);
// Add vnet entries for the new zone
_zoneDao.addVnet(zone.getId(), vnetStart, vnetEnd);
if (vnetStart != -1 && vnetEnd != -1) {
_zoneDao.addVnet(zone.getId(), vnetStart, vnetEnd);
}
saveConfigurationEvent(userId, null, EventTypes.EVENT_ZONE_CREATE, "Successfully created new zone with name: " + zoneName + ".", "dcId=" + zone.getId(), "dns1=" + dns1, "dns2=" + dns2, "internalDns1=" + internalDns1, "internalDns2=" + internalDns2, "vnetRange=" + vnetRange, "guestCidr=" + guestCidr);
return zone;

View File

@ -0,0 +1,37 @@
package com.cloud.hypervisor;
import javax.ejb.Local;
import com.cloud.agent.api.to.VirtualMachineTO;
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 KVMGuru extends HypervisorGuruBase implements HypervisorGuru {
@Inject GuestOSDao _guestOsDao;
@Override
public HypervisorType getHypervisorType() {
return HypervisorType.KVM;
}
protected KVMGuru() {
super();
}
@Override
public <T extends VirtualMachine> VirtualMachineTO implement(
VirtualMachineProfile<T> vm) {
VirtualMachineTO to = toVirtualMachineTO(vm);
// Determine the VM's OS description
GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId());
to.setOs(guestOS.getDisplayName());
return to;
}
}

View File

@ -20,13 +20,16 @@ package com.cloud.network;
import java.util.List;
import java.util.Map;
import com.cloud.api.ServerApiException;
import com.cloud.api.commands.AddVpnUserCmd;
import com.cloud.api.commands.AssignToLoadBalancerRuleCmd;
import com.cloud.api.commands.AssociateIPAddrCmd;
import com.cloud.api.commands.CreateIPForwardingRuleCmd;
import com.cloud.api.commands.CreateIpForwardingRuleCmd;
import com.cloud.api.commands.CreatePortForwardingRuleCmd;
import com.cloud.api.commands.CreateLoadBalancerRuleCmd;
import com.cloud.api.commands.CreateRemoteAccessVpnCmd;
import com.cloud.api.commands.DeleteIPForwardingRuleCmd;
import com.cloud.api.commands.DeleteIpForwardingRuleCmd;
import com.cloud.api.commands.DeletePortForwardingRuleCmd;
import com.cloud.api.commands.DeleteLoadBalancerRuleCmd;
import com.cloud.api.commands.DeleteRemoteAccessVpnCmd;
import com.cloud.api.commands.DisassociateIPAddrCmd;
@ -61,11 +64,12 @@ import com.cloud.user.AccountVO;
import com.cloud.utils.Pair;
import com.cloud.vm.DomainRouter;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicVO;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
/**
@ -210,7 +214,7 @@ public interface NetworkManager {
* @param cmd the command specifying the ip address, public port, protocol, private port, and virtual machine id.
* @return the newly created FirewallRuleVO if successful, null otherwise.
*/
public FirewallRuleVO createPortForwardingRule(CreateIPForwardingRuleCmd cmd) throws NetworkRuleConflictException;
public FirewallRuleVO createPortForwardingRule(CreatePortForwardingRuleCmd cmd) throws NetworkRuleConflictException;
/**
* List port forwarding rules assigned to an ip address
@ -302,8 +306,6 @@ public interface NetworkManager {
List<IPAddressVO> listPublicIpAddressesInVirtualNetwork(long accountId, long dcId, Boolean sourceNat);
public boolean disassociateIpAddress(DisassociateIPAddrCmd cmd);
public boolean deleteIpForwardingRule(DeleteIPForwardingRuleCmd cmd);
List<NetworkConfigurationVO> setupNetworkConfiguration(Account owner, NetworkOfferingVO offering, DeploymentPlan plan);
List<NetworkConfigurationVO> setupNetworkConfiguration(Account owner, NetworkOfferingVO offering, NetworkConfiguration predefined, DeploymentPlan plan);
@ -316,7 +318,7 @@ public interface NetworkManager {
void release(VirtualMachineProfile<? extends VMInstanceVO> vmProfile);
DomainRouter upgradeRouter(UpgradeRouterCmd cmd);
List<NicVO> getNics(VMInstanceVO vm);
List<? extends Nic> getNics (VirtualMachine vm);
List<AccountVO> getAccountsUsingNetworkConfiguration(long configurationId);
AccountVO getNetworkConfigurationOwner(long configurationId);
@ -357,5 +359,14 @@ public interface NetworkManager {
boolean removeVpnUser(RemoveVpnUserCmd cmd) throws ConcurrentOperationException;
String getNextAvailableMacAddressInNetwork(long networkConfigurationId);
NetworkConfiguration getNetworkConfiguration(long id);
String getNextAvailableMacAddressInNetwork(long networkConfigurationId) throws InsufficientAddressCapacityException;
FirewallRuleVO createIpForwardingRuleInDb(String ipAddr, Long virtualMachineId) throws ServerApiException;
public boolean deletePortForwardingRule(DeletePortForwardingRuleCmd cmd);
FirewallRuleVO createIpForwardingRuleOnDomr(Long ruleId);
boolean deleteIpForwardingRule(Long id);
}

View File

@ -49,10 +49,12 @@ import com.cloud.api.ServerApiException;
import com.cloud.api.commands.AddVpnUserCmd;
import com.cloud.api.commands.AssignToLoadBalancerRuleCmd;
import com.cloud.api.commands.AssociateIPAddrCmd;
import com.cloud.api.commands.CreateIPForwardingRuleCmd;
import com.cloud.api.commands.CreateIpForwardingRuleCmd;
import com.cloud.api.commands.CreatePortForwardingRuleCmd;
import com.cloud.api.commands.CreateLoadBalancerRuleCmd;
import com.cloud.api.commands.CreateRemoteAccessVpnCmd;
import com.cloud.api.commands.DeleteIPForwardingRuleCmd;
import com.cloud.api.commands.DeleteIpForwardingRuleCmd;
import com.cloud.api.commands.DeletePortForwardingRuleCmd;
import com.cloud.api.commands.DeleteLoadBalancerRuleCmd;
import com.cloud.api.commands.DeleteRemoteAccessVpnCmd;
import com.cloud.api.commands.DisassociateIPAddrCmd;
@ -156,13 +158,16 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.DomainRouter;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicVO;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.State;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.UserVmDao;
@ -727,7 +732,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
Pair<String, VlanVO> ipAndVlan = _vlanDao.assignIpAddress(zoneId, accountId, domainId, VlanType.VirtualNetwork, false);
if (ipAndVlan == null) {
throw new InsufficientAddressCapacityException("Unable to find available public IP addresses");
throw new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zoneId);
} else {
ipAddress = ipAndVlan.first();
_accountMgr.incrementResourceCount(accountId, ResourceType.public_ip);
@ -892,7 +897,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
if (rule.isForwarding()) {
fwdRules.add(rule);
final SetFirewallRuleCommand cmd = new SetFirewallRuleCommand(routerName, routerIp, rule);
final SetFirewallRuleCommand cmd = new SetFirewallRuleCommand(routerName, routerIp, false, rule, false);
cmds.addCommand(cmd);
} else {
lbRules.add(rule);
@ -971,7 +976,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
rule.setVlanNetmask(vlanNetmask);
if (rule.isForwarding()) {
fwdRules.add(rule);
final SetFirewallRuleCommand cmd = new SetFirewallRuleCommand(router.getInstanceName(), router.getPrivateIpAddress(), rule);
final SetFirewallRuleCommand cmd = new SetFirewallRuleCommand(router.getInstanceName(), router.getPrivateIpAddress(), false, rule, false);
cmds.addCommand(cmd);
}
}
@ -999,7 +1004,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
@Override
public FirewallRuleVO createPortForwardingRule(CreateIPForwardingRuleCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, NetworkRuleConflictException {
public FirewallRuleVO createPortForwardingRule(CreatePortForwardingRuleCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, NetworkRuleConflictException {
// validate IP Address exists
IPAddressVO ipAddress = _ipAddressDao.findById(cmd.getIpAddress());
if (ipAddress == null) {
@ -1376,6 +1381,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
EventUtils.saveEvent(UserContext.current().getUserId(), loadBalancer.getAccountId(), level, type, description);
}
}
return true;
} else {
// Remove the instanceIds from the load balancer since there was a failure. Make sure to commit the
// transaction here, otherwise the act of throwing the internal error exception will cause this
@ -1391,7 +1397,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
_loadBalancerDao.releaseFromLockTable(loadBalancerId);
}
}
return true;
}
@Override @DB
@ -2086,7 +2091,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
@Override
public List<NicVO> getNics(VMInstanceVO vm) {
public List<? extends Nic> getNics(VirtualMachine vm) {
return _nicDao.listBy(vm.getId());
}
@ -2507,7 +2512,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
@Override @DB
public boolean deleteIpForwardingRule(DeleteIPForwardingRuleCmd cmd) {
public boolean deletePortForwardingRule(DeletePortForwardingRuleCmd cmd) {
Long ruleId = cmd.getId();
Long userId = UserContext.current().getUserId();
Account account = UserContext.current().getAccount();
@ -2921,7 +2926,247 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
@Override
public String getNextAvailableMacAddressInNetwork(long networkConfigurationId) {
return _networkConfigDao.getNextAvailableMacAddress(networkConfigurationId);
public String getNextAvailableMacAddressInNetwork(long networkConfigurationId) throws InsufficientAddressCapacityException {
String mac = _networkConfigDao.getNextAvailableMacAddress(networkConfigurationId);
if (mac == null) {
throw new InsufficientAddressCapacityException("Unable to create another mac address", NetworkConfiguration.class, networkConfigurationId);
}
return mac;
}
@Override
public NetworkConfiguration getNetworkConfiguration(long id) {
return _networkConfigDao.findById(id);
}
@Override
public FirewallRuleVO createIpForwardingRuleOnDomr(Long ruleId) throws ServerApiException{
boolean success = false;
//get the rule
FirewallRuleVO rule = _rulesDao.findById(ruleId);
if(rule == null){
throw new PermissionDeniedException("Cannot create ip forwarding rule in db");
}
//get ip address
IPAddressVO ipAddress = _ipAddressDao.findById(rule.getPublicIpAddress());
if (ipAddress == null) {
throw new InvalidParameterValueException("Unable to create ip forwarding rule on address " + ipAddress + ", invalid IP address specified.");
}
//get the domain router object
DomainRouterVO router = _routerMgr.getRouter(ipAddress.getAccountId(), ipAddress.getDataCenterId());
success = createOrDeleteIpForwardingRuleOnDomr(rule,router,rule.getPrivateIpAddress(),true); //true +> create
if(!success){
//corner case; delete record from db as domR rule creation failed
try {
_rulesDao.remove(ruleId);
throw new PermissionDeniedException("Cannot create ip forwarding rule on domr, hence deleting created record in db");
} catch (Exception e) {
throw new ServerApiException(BaseCmd.NET_CREATE_IPFW_RULE_ERROR, e.getMessage());
}
}
// Save and create the event
String description;
String ruleName = "ip forwarding";
String level = EventVO.LEVEL_INFO;
description = "created new " + ruleName + " rule [" + rule.getPublicIpAddress() + "]->["
+ rule.getPrivateIpAddress() + "]" + ":" + rule.getProtocol();
EventUtils.saveEvent(UserContext.current().getUserId(), ipAddress.getAccountId(), level, EventTypes.EVENT_NET_RULE_ADD, description);
return rule;
}
@Override @DB
public FirewallRuleVO createIpForwardingRuleInDb(String ipAddr, Long virtualMachineId) throws ServerApiException {
Transaction txn = Transaction.currentTxn();
txn.start();
UserVmVO userVM = null;
FirewallRuleVO newFwRule = null;
boolean locked = false;
try {
// validate IP Address exists
IPAddressVO ipAddress = _ipAddressDao.findById(ipAddr);
if (ipAddress == null) {
throw new InvalidParameterValueException("Unable to create ip forwarding rule on address " + ipAddress + ", invalid IP address specified.");
}
// validate user VM exists
userVM = _vmDao.findById(virtualMachineId);
if (userVM == null) {
throw new InvalidParameterValueException("Unable to create ip forwarding rule on address " + ipAddress + ", invalid virtual machine id specified (" + virtualMachineId + ").");
}
//sync point; cannot lock on rule ; hence sync on vm
userVM = _vmDao.acquireInLockTable(userVM.getId());
if(userVM == null){
s_logger.warn("Unable to acquire lock on user vm for creating 1-1 NAT rule");
return newFwRule;
}else{
locked = true;
}
// validate that IP address and userVM belong to the same account
if ((ipAddress.getAccountId() == null) || (ipAddress.getAccountId().longValue() != userVM.getAccountId())) {
throw new InvalidParameterValueException("Unable to create ip forwarding rule, IP address " + ipAddress + " owner is not the same as owner of virtual machine " + userVM.toString());
}
// validate that userVM is in the same availability zone as the IP address
if (ipAddress.getDataCenterId() != userVM.getDataCenterId()) {
throw new InvalidParameterValueException("Unable to create ip forwarding rule, IP address " + ipAddress + " is not in the same availability zone as virtual machine " + userVM.toString());
}
// if an admin account was passed in, or no account was passed in, make sure we honor the accountName/domainId parameters
Account account = UserContext.current().getAccount();
if (account != null) {
if ((account.getType() == Account.ACCOUNT_TYPE_ADMIN) || (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)) {
if (!_domainDao.isChildDomain(account.getDomainId(), userVM.getDomainId())) {
throw new PermissionDeniedException("Unable to create ip forwarding rule, IP address " + ipAddress + " to virtual machine " + virtualMachineId + ", permission denied.");
}
} else if (account.getId() != userVM.getAccountId()) {
throw new PermissionDeniedException("Unable to create ip forwarding rule, IP address " + ipAddress + " to virtual machine " + virtualMachineId + ", permission denied.");
}
}
// check for ip address/port conflicts by checking existing forwarding and load balancing rules
List<FirewallRuleVO> existingNatRules = _rulesDao.findByPublicIpPrivateIpForNatRule(ipAddr, userVM.getGuestIpAddress());
if(existingNatRules.size() > 0){
throw new NetworkRuleConflictException("The specified rule for public ip:"+ipAddr+" vm id:"+virtualMachineId+" already exists");
}
newFwRule = new FirewallRuleVO();
newFwRule.setEnabled(true);
newFwRule.setForwarding(true);
newFwRule.setPrivatePort(null);
newFwRule.setProtocol("NAT");//protocol cannot be null; adding this as a NAT
newFwRule.setPublicPort(null);
newFwRule.setPublicIpAddress(ipAddress.getAddress());
newFwRule.setPrivateIpAddress(userVM.getGuestIpAddress());
newFwRule.setGroupId(null);
_rulesDao.persist(newFwRule);
txn.commit();
} catch (Exception e) {
s_logger.warn("Unable to create new firewall rule for 1:1 NAT");
txn.rollback();
throw new ServerApiException(BaseCmd.IP_ALLOCATION_ERROR,"Unable to create new firewall rule for 1:1 NAT:"+e.getMessage());
}finally{
if(locked)
_vmDao.releaseFromLockTable(userVM.getId());
}
return newFwRule;
}
@Override @DB
public boolean deleteIpForwardingRule(Long id) {
Long ruleId = id;
Long userId = UserContext.current().getUserId();
Account account = UserContext.current().getAccount();
//verify input parameters here
FirewallRuleVO rule = _firewallRulesDao.findById(ruleId);
if (rule == null) {
throw new InvalidParameterValueException("Unable to find port forwarding rule " + ruleId);
}
String publicIp = rule.getPublicIpAddress();
IPAddressVO ipAddress = _ipAddressDao.findById(publicIp);
if (ipAddress == null) {
throw new InvalidParameterValueException("Unable to find IP address for ip forwarding rule " + ruleId);
}
// although we are not writing these values to the DB, we will check
// them out of an abundance
// of caution (may not be warranted)
Account ruleOwner = _accountDao.findById(ipAddress.getAccountId());
if (ruleOwner == null) {
throw new InvalidParameterValueException("Unable to find owning account for ip forwarding rule " + ruleId);
}
// if an admin account was passed in, or no account was passed in, make sure we honor the accountName/domainId parameters
if (account != null) {
if (isAdmin(account.getType())) {
if (!_domainDao.isChildDomain(account.getDomainId(), ruleOwner.getDomainId())) {
throw new PermissionDeniedException("Unable to delete ip forwarding rule " + ruleId + ", permission denied.");
}
} else if (account.getId() != ruleOwner.getId()) {
throw new PermissionDeniedException("Unable to delete ip forwarding rule " + ruleId + ", permission denied.");
}
}
Transaction txn = Transaction.currentTxn();
boolean locked = false;
boolean success = false;
try {
ipAddress = _ipAddressDao.acquireInLockTable(publicIp);
if (ipAddress == null) {
throw new PermissionDeniedException("Unable to obtain lock on record for deletion");
}
locked = true;
txn.start();
final DomainRouterVO router = _routerMgr.getRouter(ipAddress.getAccountId(), ipAddress.getDataCenterId());
success = createOrDeleteIpForwardingRuleOnDomr(rule, router, rule.getPrivateIpAddress(), false);
_firewallRulesDao.remove(ruleId);
String description;
String type = EventTypes.EVENT_NET_RULE_DELETE;
String level = EventVO.LEVEL_INFO;
String ruleName = rule.isForwarding() ? "ip forwarding" : "load balancer";
if (success) {
description = "deleted " + ruleName + " rule [" + publicIp +"]->[" + rule.getPrivateIpAddress() + "] " + rule.getProtocol();
} else {
level = EventVO.LEVEL_ERROR;
description = "Error while deleting " + ruleName + " rule [" + publicIp + "]->[" + rule.getPrivateIpAddress() +"] " + rule.getProtocol();
}
EventUtils.saveEvent(userId, ipAddress.getAccountId(), level, type, description);
txn.commit();
}catch (Exception ex) {
txn.rollback();
s_logger.error("Unexpected exception deleting port forwarding rule " + ruleId, ex);
return false;
}finally {
if (locked) {
_ipAddressDao.releaseFromLockTable(publicIp);
}
txn.close();
}
return success;
}
private boolean createOrDeleteIpForwardingRuleOnDomr(FirewallRuleVO fwRule, DomainRouterVO router, String guestIp, boolean create){
Commands cmds = new Commands(OnError.Continue);
final SetFirewallRuleCommand cmd = new SetFirewallRuleCommand(router.getInstanceName(), router.getPrivateIpAddress(), true, fwRule, create);
cmds.addCommand(cmd);
try {
_agentMgr.send(router.getHostId(), cmds);
} catch (final AgentUnavailableException e) {
s_logger.warn("agent unavailable", e);
} catch (final OperationTimedoutException e) {
s_logger.warn("Timed Out", e);
}
Answer[] answers = cmds.getAnswers();
if (answers == null || answers[0].getResult() == false ){
return false;
}else{
return true;
}
}
}

View File

@ -140,4 +140,9 @@ public class ControlNetworkGuru extends AdapterBase implements NetworkGuru {
return true;
}
@Override
public boolean trash(NetworkConfiguration config, NetworkOffering offering, Account owner) {
return true;
}
}

View File

@ -174,7 +174,7 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
if (nic.getMacAddress() == null) {
nic.setMacAddress(_networkMgr.getNextAvailableMacAddressInNetwork(config.getId()));
if (nic.getMacAddress() == null) {
throw new InsufficientAddressCapacityException("Unable to allocate more mac addresses");
throw new InsufficientAddressCapacityException("Unable to allocate more mac addresses", NetworkConfiguration.class, config.getId());
}
}
@ -225,4 +225,10 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
public void destroy(NetworkConfiguration config, NetworkOffering offering) {
config.getBroadcastUri();
}
@Override
public boolean trash(NetworkConfiguration config, NetworkOffering offering, Account owner) {
// TODO Auto-generated method stub
return true;
}
}

View File

@ -83,7 +83,7 @@ public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru {
String ip = _dcDao.allocatePrivateIpAddress(dest.getDataCenter().getId(), dest.getPod().getId(), nic.getId(), context.getReservationId());
if (ip == null) {
throw new InsufficientAddressCapacityException("Unable to get a management ip address");
throw new InsufficientAddressCapacityException("Unable to get a management ip address", Pod.class, pod.getId());
}
nic.setIp4Address(ip);
@ -108,4 +108,9 @@ public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru {
@Override
public void destroy(NetworkConfiguration config, NetworkOffering offering) {
}
@Override
public boolean trash(NetworkConfiguration config, NetworkOffering offering, Account owner) {
return true;
}
}

View File

@ -62,7 +62,7 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
if (nic.getIp4Address() == null) {
Pair<String, VlanVO> ipAndVlan = _vlanDao.assignIpAddress(dc.getId(), vm.getVirtualMachine().getAccountId(), vm.getVirtualMachine().getDomainId(), VlanType.VirtualNetwork, true);
if (ipAndVlan == null) {
throw new InsufficientVirtualNetworkCapcityException("Unable to get public ip address in " + dc.getId());
throw new InsufficientVirtualNetworkCapcityException("Unable to get public ip address in " + dc.getId(), DataCenter.class, dc.getId());
}
VlanVO vlan = ipAndVlan.second();
nic.setIp4Address(ipAndVlan.first());
@ -92,9 +92,6 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
}
String mac = _networkMgr.getNextAvailableMacAddressInNetwork(config.getId());
if (mac == null) {
throw new InsufficientAddressCapacityException("Not enough mac addresses");
}
nic.setMacAddress(mac);
DataCenter dc = _dcDao.findById(config.getDataCenterId());
@ -128,4 +125,9 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
@Override
public void destroy(NetworkConfiguration config, NetworkOffering offering) {
}
@Override
public boolean trash(NetworkConfiguration config, NetworkOffering offering, Account owner) {
return true;
}
}

View File

@ -2131,6 +2131,8 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute
public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile<DomainRouterVO> profile, DeployDestination dest, ReservationContext context) {
NicProfile controlNic = (NicProfile)profile.getParameter("control.nic");
cmds.addCommand("checkSsh", new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922, 5, 20));
return true;
}
@ -2371,7 +2373,11 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute
@Override
public DomainRouter stopRouter(StopRouter2Cmd cmd) throws ResourceUnavailableException, ConcurrentOperationException {
Long routerId = cmd.getId();
Account account = UserContext.current().getAccount();
UserContext context = UserContext.current();
Account account = context.getAccount();
long accountId = context.getAccountId();
long userId = context.getUserId();
// verify parameters
DomainRouterVO router = _routerDao.findById(routerId);
@ -2381,9 +2387,9 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute
_accountMgr.checkAccess(account, router);
long eventId = EventUtils.saveScheduledEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_ROUTER_STOP, "stopping Router with Id: "+routerId);
long eventId = EventUtils.saveScheduledEvent(userId, accountId, EventTypes.EVENT_ROUTER_STOP, "stopping Router with Id: "+routerId);
UserVO user = _userDao.findById(UserContext.current().getUserId());
UserVO user = _userDao.findById(context.getUserId());
try {
if (!_itMgr.stop(router, user, account)) {
@ -2397,4 +2403,73 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute
return router;
}
private boolean resendRouterState(NetworkConfiguration config, DomainRouterVO router, Commands cmds) {
if (router.getRole() == Role.DHCP_FIREWALL_LB_PASSWD_USERDATA) {
//source NAT address is stored in /proc/cmdline of the domR and gets
//reassigned upon powerup. Source NAT rule gets configured in StartRouter command
List<IPAddressVO> ipAddrs = _networkMgr.listPublicIpAddressesInVirtualNetwork(router.getAccountId(), router.getDataCenterId(), null);
List<String> ipAddrList = new ArrayList<String>();
for (final IPAddressVO ipVO : ipAddrs) {
ipAddrList.add(ipVO.getAddress());
}
if (!ipAddrList.isEmpty()) {
try {
final boolean success = _networkMgr.associateIP(router, ipAddrList, true, 0);
if (!success) {
return false;
}
} catch (ConcurrentOperationException e) {
s_logger.warn("unable to associate ip due to ", e);
return false;
}
}
final List<FirewallRuleVO> fwRules = new ArrayList<FirewallRuleVO>();
for (final IPAddressVO ipVO : ipAddrs) {
fwRules.addAll(_rulesDao.listIPForwarding(ipVO.getAddress()));
}
final List<FirewallRuleVO> result = _networkMgr.updateFirewallRules(router
.getPublicIpAddress(), fwRules, router);
if (result.size() != fwRules.size()) {
return false;
}
}
return resendDhcpEntries(router) && resendVpnServerData(router);
}
private boolean resendDhcpEntries(NetworkConfiguration config, DomainRouterVO router, Commands cmd){
final List<UserVmVO> vms = _vmDao.listBy(router.getId(), State.Creating, State.Starting, State.Running, State.Stopping, State.Stopped, State.Migrating);
Commands cmds = new Commands(OnError.Continue);
for (UserVmVO vm: vms) {
if (vm.getGuestIpAddress() == null || vm.getGuestMacAddress() == null || vm.getHostName() == null)
continue;
DhcpEntryCommand decmd = new DhcpEntryCommand(vm.getGuestMacAddress(), vm.getGuestIpAddress(), router.getPrivateIpAddress(), vm.getHostName());
cmds.addCommand(decmd);
}
if (cmds.size() > 0) {
try {
_agentMgr.send(router.getHostId(), cmds);
} catch (final AgentUnavailableException e) {
s_logger.warn("agent unavailable", e);
} catch (final OperationTimedoutException e) {
s_logger.warn("Timed Out", e);
}
Answer[] answers = cmds.getAnswers();
if (answers == null ){
return false;
}
int i=0;
while (i < cmds.size()) {
Answer ans = answers[i];
i++;
if ((ans != null) && (ans.getResult())) {
continue;
} else {
return false;
}
}
}
return true;
}
}

View File

@ -71,9 +71,11 @@ import com.cloud.api.commands.RebootSystemVmCmd;
import com.cloud.api.commands.RegisterCmd;
import com.cloud.api.commands.RegisterPreallocatedLunCmd;
import com.cloud.api.commands.StartSystemVMCmd;
import com.cloud.api.commands.StartSystemVm2Cmd;
import com.cloud.api.commands.StopSystemVm2Cmd;
import com.cloud.api.commands.StopSystemVmCmd;
import com.cloud.api.commands.UpdateDomainCmd;
import com.cloud.api.commands.UpdateIPForwardingRuleCmd;
import com.cloud.api.commands.UpdatePortForwardingRuleCmd;
import com.cloud.api.commands.UpdateIsoCmd;
import com.cloud.api.commands.UpdateIsoPermissionsCmd;
import com.cloud.api.commands.UpdateTemplateCmd;
@ -144,6 +146,7 @@ import com.cloud.vm.VirtualMachine;
*/
public interface ManagementServer {
static final String Name = "management-server";
List<ClusterVO> listClusterByPodId(long podId);
@ -549,10 +552,10 @@ public interface ManagementServer {
/**
* Update an existing port forwarding rule on the given public IP / public port for the given protocol
* @param cmd - the UpdateIPForwardingRuleCmd command that wraps publicIp, privateIp, publicPort, privatePort, protocol of the rule to update
* @param cmd - the UpdatePortForwardingRuleCmd command that wraps publicIp, privateIp, publicPort, privatePort, protocol of the rule to update
* @return the new firewall rule if updated, null if no rule on public IP / public port of that protocol could be found
*/
FirewallRuleVO updatePortForwardingRule(UpdateIPForwardingRuleCmd cmd);
FirewallRuleVO updatePortForwardingRule(UpdatePortForwardingRuleCmd cmd);
/**
* Find a firewall rule by rule id
@ -679,6 +682,9 @@ public interface ManagementServer {
VMInstanceVO stopSystemVM(StopSystemVmCmd cmd);
VMInstanceVO startSystemVM(StartSystemVMCmd cmd);
VMInstanceVO rebootSystemVM(RebootSystemVmCmd cmd);
VirtualMachine startSystemVm(StartSystemVm2Cmd cmd);
VirtualMachine stopSystemVm(StopSystemVm2Cmd cmd);
/**
* Returns a configuration value with the specified name

View File

@ -121,9 +121,11 @@ import com.cloud.api.commands.RebootSystemVmCmd;
import com.cloud.api.commands.RegisterCmd;
import com.cloud.api.commands.RegisterPreallocatedLunCmd;
import com.cloud.api.commands.StartSystemVMCmd;
import com.cloud.api.commands.StartSystemVm2Cmd;
import com.cloud.api.commands.StopSystemVm2Cmd;
import com.cloud.api.commands.StopSystemVmCmd;
import com.cloud.api.commands.UpdateDomainCmd;
import com.cloud.api.commands.UpdateIPForwardingRuleCmd;
import com.cloud.api.commands.UpdatePortForwardingRuleCmd;
import com.cloud.api.commands.UpdateIsoCmd;
import com.cloud.api.commands.UpdateIsoPermissionsCmd;
import com.cloud.api.commands.UpdateTemplateCmd;
@ -391,7 +393,7 @@ public class ManagementServerImpl implements ManagementServer {
private final int _routerRamSize;
private final int _proxyRamSize;
private final int _ssRamSize;
private int _maxVolumeSizeInGb;
private int _maxVolumeSizeInMb;
private final Map<String, Boolean> _availableIdsMap;
@ -510,9 +512,9 @@ public class ManagementServerImpl implements ManagementServer {
_networkGroupsEnabled = true;
}
String maxVolumeSizeInGbString = _configDao.getValue("max.volume.size.gb");
int maxVolumeSizeGb = NumbersUtil.parseInt(maxVolumeSizeInGbString, 2000);
_maxVolumeSizeInGb = maxVolumeSizeGb;
String maxVolumeSizeInMbString = _configDao.getValue("max.volume.size.gb");
int maxVolumeSizeMb = NumbersUtil.parseInt(maxVolumeSizeInMbString, (2000*1024));//2000 gb
_maxVolumeSizeInMb = maxVolumeSizeMb;
}
protected Map<String, String> getConfigs() {
@ -1214,8 +1216,8 @@ public class ManagementServerImpl implements ManagementServer {
throw new InvalidParameterValueException("Please specify a valid disk size for VM creation; custom disk offering has no size set");
}
if(diskOffering != null && diskOffering.isCustomized() && size > _maxVolumeSizeInGb){
throw new InvalidParameterValueException("Please specify a valid disk size for VM creation; custom disk offering max size is:"+_maxVolumeSizeInGb);
if(diskOffering != null && diskOffering.isCustomized() && size > _maxVolumeSizeInMb){
throw new InvalidParameterValueException("Please specify a valid disk size for VM creation; custom disk offering max size is:"+_maxVolumeSizeInMb);
}
// validate that the template is usable by the account
@ -1489,10 +1491,10 @@ public class ManagementServerImpl implements ManagementServer {
// default domainId to the admin's domain
domainId = ((account == null) ? DomainVO.ROOT_DOMAIN : account.getDomainId());
}
Filter searchFilter = new Filter(UserAccountVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
Object id = cmd.getId();
Long id = cmd.getId();
Object username = cmd.getUsername();
Object type = cmd.getAccountType();
Object accountName = cmd.getAccountName();
@ -1501,7 +1503,17 @@ public class ManagementServerImpl implements ManagementServer {
SearchBuilder<UserAccountVO> sb = _userAccountDao.createSearchBuilder();
sb.and("username", sb.entity().getUsername(), SearchCriteria.Op.LIKE);
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
if (id != null && id == 1) {
//system user should NOT be searchable
List<UserAccountVO> emptyList = new ArrayList<UserAccountVO>();
return emptyList;
} else if (id != null) {
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
} else {
//this condition is used to exclude system user from the search results
sb.and("id", sb.entity().getId(), SearchCriteria.Op.NEQ);
}
sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ);
sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
sb.and("accountName", sb.entity().getAccountName(), SearchCriteria.Op.LIKE);
@ -1534,6 +1546,9 @@ public class ManagementServerImpl implements ManagementServer {
if (id != null) {
sc.setParameters("id", id);
} else {
//Don't return system user, search builder with NEQ
sc.setParameters("id", 1);
}
if (type != null) {
@ -2565,7 +2580,7 @@ public class ManagementServerImpl implements ManagementServer {
}
@Override
public FirewallRuleVO updatePortForwardingRule(UpdateIPForwardingRuleCmd cmd) throws InvalidParameterValueException, PermissionDeniedException{
public FirewallRuleVO updatePortForwardingRule(UpdatePortForwardingRuleCmd cmd) throws InvalidParameterValueException, PermissionDeniedException{
String publicIp = cmd.getPublicIp();
String privateIp = cmd.getPrivateIp();
String privatePort = cmd.getPrivatePort();
@ -3462,7 +3477,13 @@ public class ManagementServerImpl implements ManagementServer {
Filter searchFilter = new Filter(DomainVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
Long domainId = cmd.getId();
String domainName = cmd.getDomainName();
Boolean isRecursive = cmd.isRecursive();
Object keyword = cmd.getKeyword();
List <DomainVO> domainList = null;
if (isRecursive == null) {
isRecursive = false;
}
Account account = UserContext.current().getAccount();
if (account != null) {
@ -3475,12 +3496,24 @@ public class ManagementServerImpl implements ManagementServer {
}
}
return searchForDomainChildren(searchFilter, domainId, domainName,
keyword);
domainList = searchForDomainChildren(searchFilter, domainId, domainName,
keyword, null);
if (isRecursive) {
List<DomainVO> childDomains = new ArrayList<DomainVO>();
for (DomainVO domain : domainList) {
String path = domain.getPath();
childDomains.addAll(searchForDomainChildren(searchFilter, null, null,
null, path));
}
return childDomains;
} else {
return domainList;
}
}
private List<DomainVO> searchForDomainChildren(Filter searchFilter,
Long domainId, String domainName, Object keyword) {
Long domainId, String domainName, Object keyword, String path) {
SearchCriteria<DomainVO> sc = _domainDao.createSearchCriteria();
if (keyword != null) {
@ -3497,6 +3530,10 @@ public class ManagementServerImpl implements ManagementServer {
if (domainName != null) {
sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + domainName + "%");
}
if (path != null) {
sc.addAnd("path", SearchCriteria.Op.LIKE, path + "%");
}
return _domainDao.search(sc, searchFilter);
}
@ -4796,6 +4833,76 @@ public class ManagementServerImpl implements ManagementServer {
}
}
@Override
public VirtualMachine startSystemVm(StartSystemVm2Cmd cmd) {
UserContext context = UserContext.current();
long callerId = context.getUserId();
long callerAccountId = context.getAccountId();
//verify input
Long id = cmd.getId();
VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(id, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm);
if (systemVm == null) {
throw new InvalidParameterValueException("unable to find a system vm with id " + id);
}
if (systemVm.getType() == VirtualMachine.Type.ConsoleProxy) {
long eventId = EventUtils.saveScheduledEvent(callerId, callerAccountId, EventTypes.EVENT_PROXY_START, "Starting console proxy with Id: "+id);
try {
checkIfStoragePoolAvailable(id);
} catch (StorageUnavailableException e) {
s_logger.warn(e.getMessage());
return null;
} catch (Exception e){
//unforseen exceptions
s_logger.warn(e.getMessage());
return null;
}
return startConsoleProxy(id, eventId);
} else if (systemVm.getType() == VirtualMachine.Type.SecondaryStorageVm) {
long eventId = EventUtils.saveScheduledEvent(callerId, callerAccountId, EventTypes.EVENT_SSVM_START, "Starting secondary storage Vm Id: "+id);
try {
checkIfStoragePoolAvailable(id);
} catch (StorageUnavailableException e) {
s_logger.warn(e.getMessage());
return null;
} catch (Exception e){
//unforseen exceptions
s_logger.warn(e.getMessage());
return null;
}
return startSecondaryStorageVm(id, eventId);
} else {
throw new InvalidParameterValueException("Unable to find a system vm: " + id);
}
}
@Override
public VirtualMachine stopSystemVm(StopSystemVm2Cmd cmd) {
UserContext context = UserContext.current();
long callerId = context.getUserId();
long callerAccountId = context.getAccountId();
Long id = cmd.getId();
// verify parameters
VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(id, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm);
if (systemVm == null) {
throw new ServerApiException (BaseCmd.PARAM_ERROR, "unable to find a system vm with id " + id);
}
// FIXME: We need to return the system VM from this method, so what do we do with the boolean response from stopConsoleProxy and stopSecondaryStorageVm?
if (systemVm.getType().equals(VirtualMachine.Type.ConsoleProxy)){
long eventId = EventUtils.saveScheduledEvent(callerId, callerAccountId, EventTypes.EVENT_PROXY_STOP, "stopping console proxy with Id: "+id);
return stopConsoleProxy(id, eventId);
} else {
long eventId = EventUtils.saveScheduledEvent(callerId, callerAccountId, EventTypes.EVENT_SSVM_STOP, "stopping secondary storage Vm Id: "+id);
return stopSecondaryStorageVm(id, eventId);
}
}
private void checkIfStoragePoolAvailable(Long id) throws StorageUnavailableException {
//check if the sp is up before starting
List<VolumeVO> rootVolList = _volumeDao.findByInstanceAndType(id, VolumeType.ROOT);

View File

@ -716,6 +716,9 @@ public class StorageManagerImpl implements StorageManager {
StoragePoolVO pool = null;
final HashSet<StoragePool> avoidPools = new HashSet<StoragePool>(avoids);
if(diskOffering != null && diskOffering.isCustomized()){
diskOffering.setDiskSize(size);
}
DiskProfile dskCh = null;
if (volume.getVolumeType() == VolumeType.ROOT && Storage.ImageFormat.ISO != template.getFormat()) {
dskCh = createDiskCharacteristics(volume, template, dc, offering);
@ -842,7 +845,7 @@ public class StorageManagerImpl implements StorageManager {
rootVol.setDeviceId(0l);
rootVol = _volsDao.persist(rootVol);
if (diskOffering != null && diskOffering.getDiskSizeInBytes() > 0) {
if ((diskOffering != null && diskOffering.getDiskSizeInBytes() > 0) || (diskOffering != null && diskOffering.isCustomized())) {
dataVol = new VolumeVO(VolumeType.DATADISK, vm.getId(), vm.getInstanceName() + "-DATA", dc.getId(), pod.getId(), account.getId(), account.getDomainId(), (size>0)? size : diskOffering.getDiskSizeInBytes());
createStartedEvent(account, dataVol);
@ -1458,10 +1461,12 @@ public class StorageManagerImpl implements StorageManager {
//verify parameters
StoragePoolVO sPool = _storagePoolDao.findById(id);
if (sPool == null) {
s_logger.warn("Unable to find pool:"+id);
throw new InvalidParameterValueException("Unable to find pool by id " + id);
}
if (sPool.getPoolType().equals(StoragePoolType.LVM)) {
s_logger.warn("Unable to delete local storage id:"+id);
throw new InvalidParameterValueException("Unable to delete local storage id: " + id);
}
@ -1481,6 +1486,7 @@ public class StorageManagerImpl implements StorageManager {
Pair<Long, Long> volumeRecords = _volsDao.getCountAndTotalByPool(id);
if (volumeRecords.first() > 0) {
s_logger.warn("Cannot delete pool "+sPool.getName()+" as there are associated vols for this pool");
return false; // cannot delete as there are associated vols
}
// 3. Else part, remove the SR associated with the Xenserver
@ -1490,7 +1496,8 @@ public class StorageManagerImpl implements StorageManager {
StoragePoolVO lock = _storagePoolDao.acquireInLockTable(sPool.getId());
try {
if (lock == null) {
s_logger.debug("Failed to acquire lock when deleting StoragePool with ID: " + sPool.getId());
if(s_logger.isDebugEnabled())
s_logger.debug("Failed to acquire lock when deleting StoragePool with ID: " + sPool.getId());
return false;
}

View File

@ -17,6 +17,7 @@
*/
package com.cloud.storage.secondary;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
@ -49,6 +50,9 @@ import com.cloud.agent.api.StartSecStorageVmCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.check.CheckSshAnswer;
import com.cloud.agent.api.check.CheckSshCommand;
import com.cloud.agent.manager.Commands;
import com.cloud.async.AsyncJobExecutor;
import com.cloud.async.AsyncJobManager;
import com.cloud.async.AsyncJobVO;
@ -64,6 +68,8 @@ import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.deploy.DataCenterDeployment;
import com.cloud.deploy.DeployDestination;
import com.cloud.domain.DomainVO;
import com.cloud.event.EventState;
import com.cloud.event.EventTypes;
@ -73,6 +79,7 @@ import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.ha.HighAvailabilityManager;
import com.cloud.ha.dao.HighAvailabilityDao;
@ -83,10 +90,13 @@ import com.cloud.info.RunningHostCountInfo;
import com.cloud.info.RunningHostInfoAgregator;
import com.cloud.info.RunningHostInfoAgregator.ZoneHostInfo;
import com.cloud.network.IpAddrAllocator;
import com.cloud.network.NetworkConfigurationVO;
import com.cloud.network.IpAddrAllocator.networkInfo;
import com.cloud.network.Network.TrafficType;
import com.cloud.network.NetworkManager;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.GuestOSVO;
@ -107,6 +117,7 @@ import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.User;
import com.cloud.user.UserVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.DateUtil;
import com.cloud.utils.NumbersUtil;
@ -122,9 +133,16 @@ import com.cloud.utils.events.SubscriptionMgr;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExecutionException;
import com.cloud.utils.net.NetUtils;
import com.cloud.utils.net.NfsUtils;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.NicProfile;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.SecondaryStorageVmVO;
import com.cloud.vm.State;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineGuru;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.VmManager;
import com.cloud.vm.VirtualMachine.Event;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.VirtualMachineName;
@ -151,7 +169,7 @@ import com.cloud.vm.dao.VMInstanceDao;
// because sooner or later, it will be driven into Running state
//
@Local(value={SecondaryStorageVmManager.class})
public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, VirtualMachineManager<SecondaryStorageVmVO> {
public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, VirtualMachineManager<SecondaryStorageVmVO>, VirtualMachineGuru<SecondaryStorageVmVO> {
private static final Logger s_logger = Logger.getLogger(SecondaryStorageManagerImpl.class);
private static final int DEFAULT_FIND_HOST_RETRY_COUNT = 2;
@ -208,6 +226,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
@Inject private ServiceOfferingDao _offeringDao;
@Inject private AccountManager _accountMgr;
@Inject GuestOSDao _guestOSDao = null;
@Inject private VmManager _itMgr;
private IpAddrAllocator _IpAllocator;
@ -227,6 +246,8 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
private String _instance;
private boolean _useLocalStorage;
private boolean _useSSlCopy;
private String _secHostUuid;
private String _nfsShare;
private String _allowedInternalSites;
@ -240,7 +261,9 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
@Override
public SecondaryStorageVmVO startSecStorageVm(long secStorageVmId, long startEventId) {
try {
return start(secStorageVmId, startEventId);
} catch (StorageUnavailableException e) {
s_logger.warn("Exception while trying to start secondary storage vm", e);
return null;
@ -250,8 +273,17 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
} catch (ConcurrentOperationException e) {
s_logger.warn("Exception while trying to start secondary storage vm", e);
return null;
} catch (ResourceUnavailableException e) {
return null;
}
}
public SecondaryStorageVmVO start2(long secStorageVmId, long startEventId) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException {
SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
AccountVO systemAcct = _accountMgr.getSystemAccount();
UserVO systemUser = _accountMgr.getSystemUser();
return _itMgr.start(secStorageVm, null, systemUser, systemAcct);
}
@Override @DB
public SecondaryStorageVmVO start(long secStorageVmId, long startEventId) throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException {
@ -666,6 +698,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
return null;
}
//SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
SecondaryStorageVmVO secStorageVm = allocSecStorageVmStorage(dataCenterId, secStorageVmId);
if (secStorageVm != null) {
SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
@ -688,6 +721,52 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
}
return null;
}
protected Map<String, Object> createSecStorageVmInstance2(long dataCenterId) {
long startEventId = saveStartedEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_SSVM_CREATE, "Creating secondary storage Vm in zone : "+dataCenterId, 0);
HostVO secHost = _hostDao.findSecondaryStorageHost(dataCenterId);
if (secHost == null) {
String msg = "No secondary storage available in zone " + dataCenterId + ", cannot create secondary storage vm";
s_logger.warn(msg);
saveFailedEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_SSVM_CREATE, msg, startEventId);
throw new CloudRuntimeException(msg);
}
_secHostUuid = secHost.getGuid();
_nfsShare = secHost.getStorageUrl();
long id = _secStorageVmDao.getNextInSequence(Long.class, "id");
String name = VirtualMachineName.getSystemVmName(id, _instance, "s").intern();
AccountVO systemAcct = _accountMgr.getSystemAccount();
DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
List<NetworkOfferingVO> defaultOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmPublicNetwork);
List<NetworkOfferingVO> offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmControlNetwork, NetworkOfferingVO.SystemVmManagementNetwork);
List<Pair<NetworkConfigurationVO, NicProfile>> networks = new ArrayList<Pair<NetworkConfigurationVO, NicProfile>>(offerings.size() + 1);
NicProfile defaultNic = new NicProfile();
defaultNic.setDefaultNic(true);
defaultNic.setDeviceId(2);
networks.add(new Pair<NetworkConfigurationVO, NicProfile>(_networkMgr.setupNetworkConfiguration(systemAcct, defaultOffering.get(0), plan).get(0), defaultNic));
for (NetworkOfferingVO offering : offerings) {
networks.add(new Pair<NetworkConfigurationVO, NicProfile>(_networkMgr.setupNetworkConfiguration(systemAcct, offering, plan).get(0), null));
}
SecondaryStorageVmVO secStorageVm = new SecondaryStorageVmVO(id, _serviceOffering.getId(), name, _template.getId(),
_template.getGuestOSId(), dataCenterId, systemAcct.getDomainId(), systemAcct.getId());
try {
secStorageVm = _itMgr.allocate(secStorageVm, _template, _serviceOffering, networks, plan, systemAcct);
} catch (InsufficientCapacityException e) {
s_logger.warn("InsufficientCapacity", e);
throw new CloudRuntimeException("Insufficient capacity exception", e);
} catch (StorageUnavailableException e) {
s_logger.warn("Unable to contact storage", e);
throw new CloudRuntimeException("Unable to contact storage", e);
}
Map<String, Object> context = new HashMap<String, Object>();
context.put("secStorageVmId", secStorageVm.getId());
return context;
}
@DB
protected Map<String, Object> createSecStorageVmInstance(long dataCenterId) {
@ -1379,12 +1458,15 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
haMgr.registerHandler(VirtualMachine.Type.SecondaryStorageVm, this);
}
_itMgr.registerGuru(VirtualMachine.Type.SecondaryStorageVm, this);
Adapters<IpAddrAllocator> ipAllocators = locator.getAdapters(IpAddrAllocator.class);
if (ipAllocators != null && ipAllocators.isSet()) {
Enumeration<IpAddrAllocator> it = ipAllocators.enumeration();
_IpAllocator = it.nextElement();
}
boolean useLocalStorage = Boolean.parseBoolean(configs.get(Config.SystemVMUseLocalStorage.key()));
String networkRateStr = _configDao.getValue("network.throttling.rate");
String multicastRateStr = _configDao.getValue("multicast.throttling.rate");
@ -1908,4 +1990,110 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
_eventDao.persist(event);
return;
}
@Override
public SecondaryStorageVmVO findByName(String name) {
if (!VirtualMachineName.isValidSecStorageVmName(name, null)) {
return null;
}
return findById(VirtualMachineName.getSystemVmId(name));
}
@Override
public SecondaryStorageVmVO findById(long id) {
return _secStorageVmDao.findById(id);
}
@Override
public SecondaryStorageVmVO persist(SecondaryStorageVmVO vm) {
return _secStorageVmDao.persist(vm);
}
@Override
public boolean finalizeVirtualMachineProfile(
VirtualMachineProfile<SecondaryStorageVmVO> profile,
DeployDestination dest, ReservationContext context) {
StringBuilder buf = profile.getBootArgsBuilder();
buf.append(" template=domP type=secstorage");
buf.append(" host=").append(_mgmt_host);
buf.append(" port=").append(_mgmt_port);
buf.append(" name=").append(profile.getVirtualMachine().getHostName());
buf.append(" zone=").append(dest.getDataCenter().getId());
buf.append(" pod=").append(dest.getPod().getId());
buf.append(" guid=").append(_secHostUuid);
buf.append(" mount.path=").append(_nfsShare);
buf.append(" resource=com.cloud.storage.resource.NfsSecondaryStorageResource");
buf.append(" instance=SecStorage");
buf.append(" sslcopy=").append(Boolean.toString(_useSSlCopy));
NicProfile controlNic = null;
for (NicProfile nic : profile.getNics()) {
int deviceId = nic.getDeviceId();
if (nic.getIp4Address() == null) {
/*External DHCP mode*/
buf.append(" eth").append(deviceId).append("ip=").append("0.0.0.0");
buf.append(" bootproto=dhcp");
} else {
buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address());
}
buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask());
if (nic.isDefaultNic()) {
buf.append(" gateway=").append(nic.getGateway());
buf.append(" dns1=").append(nic.getDns1());
if (nic.getDns2() != null) {
buf.append(" dns2=").append(nic.getDns2());
}
}
if (nic.getTrafficType() == TrafficType.Management) {
buf.append(" localgw=").append(dest.getPod().getGateway());
} else if (nic.getTrafficType() == TrafficType.Control) {
controlNic = nic;
}
}
String bootArgs = buf.toString();
if (s_logger.isDebugEnabled()) {
s_logger.debug("Boot Args for " + profile + ": " + bootArgs);
}
if (controlNic == null) {
throw new CloudRuntimeException("Didn't start a control port");
}
profile.setParameter("control.nic", controlNic);
return true;
}
@Override
public boolean finalizeDeployment(Commands cmds,
VirtualMachineProfile<SecondaryStorageVmVO> profile,
DeployDestination dest, ReservationContext context) {
NicProfile controlNic = (NicProfile)profile.getParameter("control.nic");
CheckSshCommand check = new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922, 5, 20);
cmds.addCommand("checkSsh", check);
return true;
}
@Override
public boolean finalizeStart(Commands cmds,
VirtualMachineProfile<SecondaryStorageVmVO> profile,
DeployDestination dest, ReservationContext context) {
CheckSshAnswer answer = (CheckSshAnswer)cmds.getAnswer("checkSsh");
if (!answer.getResult()) {
s_logger.warn("Unable to ssh to the VM: " + answer.getDetails());
return false;
}
return true;
}
@Override
public void finalizeStop(
VirtualMachineProfile<SecondaryStorageVmVO> profile, long hostId,
String reservationId) {
}
}

View File

@ -41,6 +41,7 @@ import com.cloud.cluster.ClusterManagerListener;
import com.cloud.cluster.ManagementServerHostVO;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenter;
import com.cloud.deploy.DataCenterDeployment;
import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlan;
@ -307,7 +308,7 @@ public class MauriceMoss implements VmManager, ClusterManagerListener {
}
if (dest == null) {
throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile);
throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId());
}
vm.setDataCenterId(dest.getDataCenter().getId());

View File

@ -740,17 +740,17 @@ CREATE TABLE `cloud`.`secondary_storage_vm` (
`dns1` varchar(15) COMMENT 'dns1',
`dns2` varchar(15) COMMENT 'dns2',
`domain` varchar(255) COMMENT 'domain',
`public_mac_address` varchar(17) NOT NULL unique COMMENT 'mac address of the public facing network card',
`public_mac_address` varchar(17) unique COMMENT 'mac address of the public facing network card',
`public_ip_address` varchar(15) UNIQUE COMMENT 'public ip address for the sec storage vm',
`public_netmask` varchar(15) COMMENT 'public netmask used for the sec storage vm',
`guest_mac_address` varchar(17) NOT NULL unique COMMENT 'mac address of the guest facing network card',
`guest_mac_address` varchar(17) unique COMMENT 'mac address of the guest facing network card',
`guest_ip_address` varchar(15) UNIQUE COMMENT 'guest ip address for the console proxy',
`guest_netmask` varchar(15) COMMENT 'guest netmask used for the console proxy',
`vlan_db_id` bigint unsigned COMMENT 'Foreign key into vlan id table',
`vlan_id` varchar(255) COMMENT 'optional VLAN ID for sec storage vm that can be used',
`ram_size` int(10) unsigned NOT NULL DEFAULT 512 COMMENT 'memory to use in mb',
`guid` varchar(255) NOT NULL COMMENT 'copied from guid of secondary storage host',
`nfs_share` varchar(255) NOT NULL COMMENT 'server and path exported by the nfs server ',
`guid` varchar(255) COMMENT 'copied from guid of secondary storage host',
`nfs_share` varchar(255) COMMENT 'server and path exported by the nfs server ',
`last_update` DATETIME NULL COMMENT 'Last session update time',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

View File

@ -22,108 +22,207 @@
<div class="tabbox" style="margin-top: 15px;">
<div class="content_tabs on" id="tab_details">
<%=t.t("details")%></div>
<div class="content_tabs off" id="tab_network">
<%=t.t("network")%></div>
</div>
<!-- Details tab (start)-->
<div id="tab_content_details">
<div class="rightpanel_mainloader_panel" style="display: none;">
<div id="tab_spinning_wheel" class="rightpanel_mainloader_panel" style="display: none;">
<div class="rightpanel_mainloaderbox">
<div class="rightpanel_mainloader_animatedicon">
</div>
<p>
Loading &hellip;</p>
</div>
</div>
<div class="grid_container">
<div class="grid_header">
<div id="grid_header_title" class="grid_header_title">
(title)</div>
<div class="grid_actionbox" id="action_link">
<div class="grid_actionsdropdown_box" id="action_menu" style="display: none;">
<ul class="actionsdropdown_boxlist" id="action_list">
<li>
<%=t.t("no.available.actions")%></li>
</ul>
</div>
</div>
<div class="gridheader_loaderbox" id="spinning_wheel" style="border: 1px solid #999;
display: none;">
<div class="gridheader_loader" id="icon">
</div>
<p id="description">
Waiting &hellip;</p>
</div>
</div>
<div class="grid_rows odd">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
<%=t.t("ID")%>:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="id">
</div>
</div>
</div>
<div class="grid_rows even">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
<%=t.t("name")%>:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="name">
</div>
<input class="text" id="name_edit" style="width: 200px; display: none;" type="text" />
<div id="name_edit_errormsg" style="display:none"></div>
</div>
</div>
<div class="grid_rows odd">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
<%=t.t("private.cidr")%>:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="cidr">
</div>
<input class="text" id="cidr_edit" style="width: 200px; display: none;" type="text" />
<div id="cidr_edit_errormsg" style="display:none"></div>
</div>
</div>
<div class="grid_rows even">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
<%=t.t("private.ip.range")%>:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="ipRange">
</div>
<input class="text" id="startIpRange_edit" style="width: 100px; display: none;" type="text" />
<div id="startIpRange_edit_errormsg" style="display:none"></div>
<input class="text" id="endIpRange_edit" style="width: 100px; display: none;" type="text" />
<div id="endIpRange_edit_errormsg" style="display:none"></div>
</div>
</div>
<div class="grid_rows odd">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
<%=t.t("gateway")%>:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="gateway">
</div>
<input class="text" id="gateway_edit" style="width: 200px; display: none;" type="text" />
<div id="gateway_edit_errormsg" style="display:none"></div>
</div>
</div>
</div>
<div class="grid_botactionpanel">
<div class="gridbot_buttons" id="save_button" style="display:none;">Save</div>
<div class="gridbot_buttons" id="cancel_button" style="display:none;">Cancel</div>
</div>
</div>
<div id="tab_container">
<div class="grid_container">
<div class="grid_header">
<div id="grid_header_title" class="grid_header_title">
(title)</div>
<div class="grid_actionbox" id="action_link">
<div class="grid_actionsdropdown_box" id="action_menu" style="display: none;">
<ul class="actionsdropdown_boxlist" id="action_list">
<li>
<%=t.t("no.available.actions")%></li>
</ul>
</div>
</div>
<div class="gridheader_loaderbox" id="spinning_wheel" style="border: 1px solid #999;
display: none;">
<div class="gridheader_loader" id="icon">
</div>
<p id="description">
Waiting &hellip;</p>
</div>
</div>
<div class="grid_rows odd">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
<%=t.t("ID")%>:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="id">
</div>
</div>
</div>
<div class="grid_rows even">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
<%=t.t("name")%>:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="name">
</div>
<input class="text" id="name_edit" style="width: 200px; display: none;" type="text" />
<div id="name_edit_errormsg" style="display:none"></div>
</div>
</div>
<div class="grid_rows odd">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
<%=t.t("private.cidr")%>:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="cidr">
</div>
<input class="text" id="cidr_edit" style="width: 200px; display: none;" type="text" />
<div id="cidr_edit_errormsg" style="display:none"></div>
</div>
</div>
<div class="grid_rows even">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
<%=t.t("private.ip.range")%>:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="ipRange">
</div>
<input class="text" id="startIpRange_edit" style="width: 100px; display: none;" type="text" />
<div id="startIpRange_edit_errormsg" style="display:none"></div>
<input class="text" id="endIpRange_edit" style="width: 100px; display: none;" type="text" />
<div id="endIpRange_edit_errormsg" style="display:none"></div>
</div>
</div>
<div class="grid_rows odd">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
<%=t.t("gateway")%>:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="gateway">
</div>
<input class="text" id="gateway_edit" style="width: 200px; display: none;" type="text" />
<div id="gateway_edit_errormsg" style="display:none"></div>
</div>
</div>
</div>
<div class="grid_botactionpanel">
<div class="gridbot_buttons" id="save_button" style="display:none;">Save</div>
<div class="gridbot_buttons" id="cancel_button" style="display:none;">Cancel</div>
</div>
</div>
</div>
<!-- Details tab (end)-->
<!-- Network tab (start)-->
<div style="display: none;" id="tab_content_network">
<div id="tab_spinning_wheel" class="rightpanel_mainloader_panel" style="display:none;">
<div class="rightpanel_mainloaderbox">
<div class="rightpanel_mainloader_animatedicon"></div>
<p>Loading &hellip;</p>
</div>
</div>
<div id="tab_container">
</div>
</div>
<!-- Network tab (end)-->
</div>
<!-- Network tab template (begin) -->
<div class="grid_container" id="network_tab_template" style="display: none">
<div class="grid_header">
<div class="grid_header_title" id="grid_header_title">
</div>
<div class="grid_actionbox" id="network_action_link" style="display: none;">
<div class="grid_actionsdropdown_box" id="network_action_menu" style="display: none;">
<ul class="actionsdropdown_boxlist" id="action_list">
</ul>
</div>
</div>
<div class="gridheader_loaderbox" id="spinning_wheel" style="display: none; height: 18px;">
<div class="gridheader_loader" id="icon">
</div>
<p id="description">
Waiting &hellip;
</p>
</div>
</div>
<div class="grid_rows" id="after_action_info_container" style="display:none">
<div class="grid_row_cell" style="width: 90%; border: none;">
<div class="row_celltitles">
<strong id="after_action_info">Message will appear here</strong></div>
</div>
</div>
<div class="grid_rows even">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
ID:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="id">
</div>
</div>
</div>
<div class="grid_rows odd">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
Guest IP Range:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="iprange">
</div>
</div>
</div>
<div class="grid_rows even">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
Guest Netmask:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="netmask">
</div>
</div>
</div>
<div class="grid_rows odd">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
Gateway:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="gateway">
</div>
</div>
</div>
<div class="grid_rows even">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
Pod:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="podname">
</div>
</div>
</div>
</div>
<!-- Network tab template (end) -->
<!-- ***** dialogs (begin) ***** -->
<!-- Add Host Dialog -->
<div id="dialog_add_host" title="Add Host" style="display: none">

View File

@ -193,39 +193,39 @@
<li>
<label>Name:</label>
<input class="text" type="text" name="add_zone_name" id="add_zone_name"/>
<div id="add_zone_name_errormsg" class="dialog_formcontent_errormsg" style="display:none;" ></div>
<div id="add_zone_name_errormsg" class="dialog_formcontent_errormsg" style="display:none; margin-left:0;" ></div>
</li>
<li>
<label>DNS 1:</label>
<input class="text" type="text" name="add_zone_dns1" id="add_zone_dns1"/>
<div id="add_zone_dns1_errormsg" class="dialog_formcontent_errormsg" style="display:none;" ></div>
<div id="add_zone_dns1_errormsg" class="dialog_formcontent_errormsg" style="display:none; margin-left:0;" ></div>
</li>
<li>
<label>DNS 2:</label>
<input class="text" type="text" name="add_zone_dns2" id="add_zone_dns2"/>
<div id="add_zone_dns2_errormsg" class="dialog_formcontent_errormsg" style="display:none;" ></div>
<div id="add_zone_dns2_errormsg" class="dialog_formcontent_errormsg" style="display:none; margin-left:0;" ></div>
</li>
<li>
<label>Internal DNS 1:</label>
<input class="text" type="text" id="add_zone_internaldns1"/>
<div id="add_zone_internaldns1_errormsg" class="dialog_formcontent_errormsg" style="display:none;" ></div>
<div id="add_zone_internaldns1_errormsg" class="dialog_formcontent_errormsg" style="display:none; margin-left:0;" ></div>
</li>
<li>
<label>Internal DNS 2:</label>
<input class="text" type="text" id="add_zone_internaldns2"/>
<div id="add_zone_internaldns2_errormsg" class="dialog_formcontent_errormsg" style="display:none;" ></div>
<div id="add_zone_internaldns2_errormsg" class="dialog_formcontent_errormsg" style="display:none; margin-left:0;" ></div>
</li>
<li id="add_zone_vlan_container">
<label>VLAN Range:</label>
<input class="text" style="width:92px" type="text" name="add_zone_startvlan" id="add_zone_startvlan"/><span>-</span>
<input class="text" style="width:92px" type="text" name="add_zone_endvlan" id="add_zone_endvlan"/>
<div id="add_zone_startvlan_errormsg" class="dialog_formcontent_errormsg" style="display:none;" ></div>
<div id="add_zone_endvlan_errormsg" class="dialog_formcontent_errormsg" style="display:none;" ></div>
<div id="add_zone_startvlan_errormsg" class="dialog_formcontent_errormsg" style="display:none; margin-left:0;" ></div>
<div id="add_zone_endvlan_errormsg" class="dialog_formcontent_errormsg" style="display:none; margin-left:0;" ></div>
</li>
<li>
<label for="add_zone_guestcidraddress">Guest CIDR:</label>
<input class="text" type="text" id="add_zone_guestcidraddress" value="10.1.1.0/24"/>
<div id="add_zone_guestcidraddress_errormsg" class="dialog_formcontent_errormsg" style="display:none;" ></div>
<div id="add_zone_guestcidraddress_errormsg" class="dialog_formcontent_errormsg" style="display:none; margin-left:0;" ></div>
</li>
<li>
<label>Public?:</label>
@ -292,21 +292,21 @@
<label for="user_name" style="width: 115px;">
Name:</label>
<input class="text" type="text" name="add_pod_name" id="add_pod_name" />
<div id="add_pod_name_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
<div id="add_pod_name_errormsg" class="dialog_formcontent_errormsg" style="display: none; margin-left:0;">
</div>
</li>
<li>
<label for="add_pod_gateway" style="width: 115px;">
Gateway:</label>
<input class="text" type="text" id="add_pod_gateway" />
<div id="add_pod_gateway_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
<div id="add_pod_gateway_errormsg" class="dialog_formcontent_errormsg" style="display: none; margin-left:0;">
</div>
</li>
<li>
<label for="user_name" style="width: 115px;">
CIDR:</label>
<input class="text" type="text" name="add_pod_cidr" id="add_pod_cidr" />
<div id="add_pod_cidr_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
<div id="add_pod_cidr_errormsg" class="dialog_formcontent_errormsg" style="display: none; margin-left:0;">
</div>
</li>
<li>
@ -314,9 +314,9 @@
Reserved System IP:</label>
<input class="text" style="width: 92px" type="text" name="add_pod_startip" id="add_pod_startip" /><span>-</span>
<input class="text" style="width: 92px" type="text" name="add_pod_endip" id="add_pod_endip" />
<div id="add_pod_startip_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
<div id="add_pod_startip_errormsg" class="dialog_formcontent_errormsg" style="display: none; margin-left:133px;">
</div>
<div id="add_pod_endip_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
<div id="add_pod_endip_errormsg" class="dialog_formcontent_errormsg" style="display: none; ">
</div>
</li>
<li id="guestip_container">
@ -324,7 +324,7 @@
Guest IP Range:</label>
<input class="text" style="width: 92px" type="text" id="startguestip" /><span>-</span>
<input class="text" style="width: 92px" type="text" id="endguestip" />
<div id="startguestip_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
<div id="startguestip_errormsg" class="dialog_formcontent_errormsg" style="display: none; margin-left:133px;">
</div>
<div id="endguestip_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
</div>
@ -333,7 +333,7 @@
<label style="width: 115px;">
Guest Netmask:</label>
<input class="text" type="text" id="guestnetmask" />
<div id="guestnetmask_errormsg" class="dialog_formcontent_errormsg" style="display: none;">
<div id="guestnetmask_errormsg" class="dialog_formcontent_errormsg" style="display: none; margin-left:0;">
</div>
</li>
</ol>
@ -362,9 +362,9 @@
Step 1</div>
<div class="vmpopup_steps" style="background: url(images/othersteps_bg.gif) no-repeat top left">
Step 2</div>
<div class="vmpopup_steps" style="color: #FFF; background: url(images/step2_selected.gif) no-repeat top left">
<div class="vmpopup_steps" style="background: url(images/othersteps_bg.gif) no-repeat top left">
Step 3</div>
<div class="vmpopup_steps" style="background: url(images/laststep_slectedbg.gif) no-repeat top left">
<div class="vmpopup_steps" style="background: url(images/laststep_bg.gif) no-repeat top left">
</div>
<div class="vmpopup_container_closebutton" id="close_button">
</div>

View File

@ -131,7 +131,7 @@
<div id="internaldns2_edit_errormsg" style="display:none"></div>
</div>
</div>
<div class="grid_rows odd">
<div class="grid_rows odd" id="vlan_container">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
<%=t.t("vlan")%>:</div>

View File

@ -152,14 +152,7 @@ $(document).ready(function() {
disableMultipleSelectionInMidMenu();
clearMiddleMenu();
$arrowIcon = $(this).find("#physical_resource_arrow");
if($arrowIcon.hasClass("expanded_close") == true) {
$arrowIcon.removeClass("expanded_close").addClass("expanded_open");
buildZoneTree();
} else {
$arrowIcon.removeClass("expanded_open").addClass("expanded_close");
$("#leftmenu_zone_tree").find("#tree_container").empty();
}
expandOrCollapseZoneTree();
resourceLoadPage("jsp/resource.jsp", null);
return false;

View File

@ -909,7 +909,7 @@ function portForwardingJsonToTemplate(jsonObj, $template) {
var virtualMachineId = $rowContainerEdit.find("#vm").val();
var array1 = [];
array1.push("&publicip="+ipAddress);
array1.push("&ipaddress="+ipAddress);
array1.push("&privateport="+privatePort);
array1.push("&publicport="+publicPort);
array1.push("&protocol="+protocol);

View File

@ -1051,6 +1051,17 @@ function drawBarChart($capacity, percentused) { //percentused == "0.01%" (having
else if (percentusedFloat > 0.8 )
$capacity.find("#bar_chart").removeClass().addClass("db_barbox high").css("width", percentused);
}
function expandOrCollapseZoneTree() {
$arrowIcon = $("#leftmenu_physical_resource").find("#physical_resource_arrow");
if($arrowIcon.hasClass("expanded_close") == true) {
$arrowIcon.removeClass("expanded_close").addClass("expanded_open");
buildZoneTree();
} else {
$arrowIcon.removeClass("expanded_open").addClass("expanded_close");
$("#leftmenu_zone_tree").find("#tree_container").empty();
}
}

View File

@ -16,7 +16,7 @@
*
*/
function afterLoadPodJSP($midmenuItem1) {
function afterLoadPodJSP($leftmenuItem1) {
hideMiddleMenu();
initAddHostButton($("#midmenu_add_link"), "pod_page");
@ -29,36 +29,76 @@
if (getHypervisorType() == 'kvm')
$("#dialog_add_pool").find("#add_pool_protocol").empty().html('<option value="nfs">NFS</option>');
bindEventHandlerToDialogAddPool();
podJsonToRightPanel($midmenuItem1);
//switch between different tabs
var tabArray = [$("#tab_details"), $("#tab_network")];
var tabContentArray = [$("#tab_content_details"), $("#tab_content_network")];
var afterSwitchFnArray = [podJsonToDetailsTab, podJsonToNetworkTab];
switchBetweenDifferentTabs(tabArray, tabContentArray, afterSwitchFnArray);
podJsonToRightPanel($leftmenuItem1);
}
function podJsonToRightPanel($leftmenuItem1) {
podJsonToDetailsTab($leftmenuItem1);
$("#right_panel_content").data("$leftmenuItem1", $leftmenuItem1);
$("#tab_details").click();
}
function podJsonToDetailsTab($leftmenuItem1) {
var jsonObj = $leftmenuItem1.data("jsonObj");
var $detailsTab = $("#tab_content_details");
$detailsTab.data("jsonObj", jsonObj);
$detailsTab.find("#id").text(fromdb(jsonObj.id));
$detailsTab.find("#grid_header_title").text(fromdb(jsonObj.name));
function podJsonToDetailsTab() {
var $thisTab = $("#right_panel_content #tab_content_details");
$thisTab.find("#tab_container").hide();
$thisTab.find("#tab_spinning_wheel").show();
$detailsTab.find("#name").text(fromdb(jsonObj.name));
$detailsTab.find("#name_edit").val(fromdb(jsonObj.name));
var $leftmenuItem1 = $("#right_panel_content").data("$leftmenuItem1");
var jsonObj = $leftmenuItem1.data("jsonObj");
$thisTab.data("jsonObj", jsonObj);
$thisTab.find("#id").text(fromdb(jsonObj.id));
$thisTab.find("#grid_header_title").text(fromdb(jsonObj.name));
$detailsTab.find("#cidr").text(fromdb(jsonObj.cidr));
$detailsTab.find("#cidr_edit").val(fromdb(jsonObj.cidr));
$thisTab.find("#name").text(fromdb(jsonObj.name));
$thisTab.find("#name_edit").val(fromdb(jsonObj.name));
$thisTab.find("#cidr").text(fromdb(jsonObj.cidr));
$thisTab.find("#cidr_edit").val(fromdb(jsonObj.cidr));
$detailsTab.find("#ipRange").text(getIpRange(jsonObj.startip, jsonObj.endip));
$detailsTab.find("#startIpRange_edit").val(fromdb(jsonObj.startip));
$detailsTab.find("#endIpRange_edit").val(fromdb(jsonObj.endip));
$thisTab.find("#ipRange").text(getIpRange(jsonObj.startip, jsonObj.endip));
$thisTab.find("#startIpRange_edit").val(fromdb(jsonObj.startip));
$thisTab.find("#endIpRange_edit").val(fromdb(jsonObj.endip));
$thisTab.find("#gateway").text(fromdb(jsonObj.gateway));
$thisTab.find("#gateway_edit").val(fromdb(jsonObj.gateway));
// hide network tab upon zone vlan
var zoneVlan;
$.ajax({
data: createURL("command=listZones&id="+jsonObj.zoneid),
dataType: "json",
async: false,
success: function(json) {
var items = json.listzonesresponse.zone;
if (items != null && items.length > 0) {
//zoneVlan = items[0].vlan; //comment this one out until bug 7162 is fixed ("listZones API should take in id parameter")
//temporary code before bug 7162 is fixed ********(begin)***********
for(var i=0; i<items.length; i++) {
if(items[i].name == jsonObj.zonename) {
zoneVlan = items[i].vlan;
}
}
//temporary code before bug 7162 is fixed ********(end)*************
}
}
});
if(zoneVlan == null) //basic network (VLAN in pod-level)
$("#tab_network").show();
else //advanced network (VLAN in zone-level)
$("#tab_network").hide();
$detailsTab.find("#gateway").text(fromdb(jsonObj.gateway));
$detailsTab.find("#gateway_edit").val(fromdb(jsonObj.gateway));
//actions ***
var $actionLink = $detailsTab.find("#action_link");
var $actionLink = $thisTab.find("#action_link");
$actionLink.bind("mouseover", function(event) {
$(this).find("#action_menu").show();
return false;
@ -67,32 +107,75 @@ function podJsonToDetailsTab($leftmenuItem1) {
$(this).find("#action_menu").hide();
return false;
});
var $actionMenu = $detailsTab.find("#action_link #action_menu");
var $actionMenu = $thisTab.find("#action_link #action_menu");
$actionMenu.find("#action_list").empty();
buildActionLinkForTab("Edit Pod", podActionMap, $actionMenu, $leftmenuItem1, $detailsTab);
buildActionLinkForTab("Delete Pod", podActionMap, $actionMenu, $leftmenuItem1, $detailsTab);
buildActionLinkForTab("Edit Pod", podActionMap, $actionMenu, $leftmenuItem1, $thisTab);
buildActionLinkForTab("Delete Pod", podActionMap, $actionMenu, $leftmenuItem1, $thisTab);
$thisTab.find("#tab_spinning_wheel").hide();
$thisTab.find("#tab_container").show();
}
function podJsonToNetworkTab() {
var $thisTab = $("#right_panel_content #tab_content_network");
$thisTab.find("#tab_container").hide();
$thisTab.find("#tab_spinning_wheel").show();
var $leftmenuItem1 = $("#right_panel_content").data("$leftmenuItem1");
var jsonObj = $leftmenuItem1.data("jsonObj");
$.ajax({
data: createURL("command=listVlanIpRanges&zoneid="+jsonObj.zoneid+"&podid="+jsonObj.id),
dataType: "json",
success: function(json) {
var items = json.listvlaniprangesresponse.vlaniprange;
var $container = $thisTab.find("#tab_container").empty();
var template = $("#network_tab_template");
if (items != null && items.length > 0) {
for (var i = 0; i < items.length; i++) {
var newTemplate = template.clone(true);
podVLANJSONToTemplate(items[i], newTemplate);
$container.append(newTemplate.show());
}
}
$thisTab.find("#tab_spinning_wheel").hide();
$thisTab.find("#tab_container").show();
}
});
}
function podVLANJSONToTemplate(jsonObj, template) {
template.data("jsonObj", jsonObj);
template.attr("id", "pod_VLAN_"+jsonObj.id).data("podVLANId", jsonObj.id);
template.find("#grid_header_title").text(fromdb(jsonObj.description));
template.find("#id").text(jsonObj.id);
template.find("#iprange").text(jsonObj.description);
template.find("#netmask").text(jsonObj.netmask);
template.find("#gateway").text(jsonObj.gateway);
template.find("#podname").text(jsonObj.podname);
}
function podJsonClearRightPanel(jsonObj) {
podJsonClearDetailsTab(jsonObj);
}
function podJsonClearDetailsTab(jsonObj) {
var $detailsTab = $("#tab_content_details");
$detailsTab.find("#id").text("");
var $thisTab = $("#right_panel_content #tab_content_details");
$thisTab.find("#id").text("");
$detailsTab.find("#name").text("");
$detailsTab.find("#name_edit").val("");
$thisTab.find("#name").text("");
$thisTab.find("#name_edit").val("");
$detailsTab.find("#cidr").text("");
$detailsTab.find("#cidr_edit").val("");
$thisTab.find("#cidr").text("");
$thisTab.find("#cidr_edit").val("");
$detailsTab.find("#ipRange").text("");
$detailsTab.find("#startIpRange_edit").val("");
$detailsTab.find("#endIpRange_edit").val("");
$thisTab.find("#ipRange").text("");
$thisTab.find("#startIpRange_edit").val("");
$thisTab.find("#endIpRange_edit").val("");
$detailsTab.find("#gateway").text("");
$detailsTab.find("#gateway_edit").val("");
$thisTab.find("#gateway").text("");
$thisTab.find("#gateway_edit").val("");
//if (getDirectAttachUntaggedEnabled() == "true")
// $("#submenu_content_zones #action_add_directip_vlan").data("type", "pod").data("id", obj.id).data("name", obj.name).data("zoneid", obj.zoneid).show();

View File

@ -39,7 +39,9 @@ function primarystorageToMidmenu(jsonObj, $midmenuItem1) {
$iconContainer.find("#icon").attr("src", "images/midmenuicon_primarystorage.png");
$midmenuItem1.find("#first_row").text(fromdb(jsonObj.name).substring(0,25));
$midmenuItem1.find("#second_row").text(jsonObj.ipaddress.substring(0,25));
$midmenuItem1.find("#second_row").text(jsonObj.ipaddress.substring(0,25));
updateHostStateInMidMenu(jsonObj, $midmenuItem1);
}
function primarystorageToRightPanel($midmenuItem1) {

View File

@ -347,13 +347,10 @@ function initAddZoneShortcut() {
}
});
$("#add_zone_shortcut").unbind("click").bind("click", function(event) {
/*
$("#add_zone_shortcut").unbind("click").bind("click", function(event) {
if($("#leftmenu_physical_resource").find("#physical_resource_arrow").hasClass("expanded_close") == true)
$("#leftmenu_physical_resource").click(); //if Physical Resource arrow shows closed (i.e. zonetree is hidden), expand and show zonetree.
*/
//$addZoneWizard.find("#info_container").hide();
expandOrCollapseZoneTree(); //if Physical Resource arrow shows closed (i.e. zonetree is hidden), expand and show zonetree.
openAddZoneWizard();
return false;
});
@ -483,9 +480,6 @@ function addZoneWizardSubmit($thisWizard) {
else
moreCriteria.push("&vlan=" + encodeURIComponent(vlanStart));
}
else {
moreCriteria.push("&vlan=30"); //temporary hacking before bug 7143 is fixed ("VLAN parameter in CreateZone shouldn't be required")
}
var guestcidraddress = trim($thisWizard.find("#add_zone_guestcidraddress").val());
moreCriteria.push("&guestcidraddress="+encodeURIComponent(guestcidraddress));
@ -502,9 +496,8 @@ function addZoneWizardSubmit($thisWizard) {
dataType: "json",
async: false,
success: function(json) {
afterActionMsg += "Zone was created successfully<br>";
$thisWizard.find("#spinning_wheel").hide();
afterActionMsg += "Zone was created successfully<br><br>";
$zoneNode = $("#leftmenu_zone_node_template").clone(true);
var $zoneTree = $("#leftmenu_zone_tree").find("#tree_container");
$zoneTree.prepend($zoneNode);
@ -517,8 +510,7 @@ function addZoneWizardSubmit($thisWizard) {
},
error: function(XMLHttpResponse) {
handleError(XMLHttpResponse, function() {
afterActionMsg += ("Failed to create zone. " + parseXMLHttpResponse(XMLHttpResponse) + "<br>");
$thisWizard.find("#spinning_wheel").hide();
afterActionMsg += ("Failed to create zone. " + parseXMLHttpResponse(XMLHttpResponse) + "<br><br>");
});
}
});
@ -544,8 +536,7 @@ function addZoneWizardSubmit($thisWizard) {
dataType: "json",
async: false,
success: function(json) {
afterActionMsg += "Pod was created successfully<br>";
$thisWizard.find("#spinning_wheel").hide();
afterActionMsg += "Pod was created successfully<br><br>";
var item = json.createpodresponse.pod;
podId = item.id;
@ -569,8 +560,7 @@ function addZoneWizardSubmit($thisWizard) {
},
error: function(XMLHttpResponse) {
handleError(XMLHttpResponse, function() {
afterActionMsg += ("Failed to create Pod. " + parseXMLHttpResponse(XMLHttpResponse) + "<br>");
$thisWizard.find("#spinning_wheel").hide();
afterActionMsg += ("Failed to create Pod. " + parseXMLHttpResponse(XMLHttpResponse) + "<br><br>");
});
}
});
@ -595,20 +585,21 @@ function addZoneWizardSubmit($thisWizard) {
$.ajax({
data: createURL("command=createVlanIpRange" + array1.join("")),
dataType: "json",
async: false,
success: function(json) {
afterActionMsg += "Guest IP range was created successfully<br>";
afterActionMsg += "Guest IP range was created successfully<br><br>";
var item = json.createvlaniprangeresponse.vlan;
vlanId = item.id;
},
error: function(XMLHttpResponse) {
handleError(XMLHttpResponse, function() {
afterActionMsg += ("Failed to create Guest IP range. " + parseXMLHttpResponse(XMLHttpResponse) + "<br>");
$thisWizard.find("#spinning_wheel").hide();
afterActionMsg += ("Failed to create Guest IP range. " + parseXMLHttpResponse(XMLHttpResponse) + "<br><br>");
});
}
});
}
$thisWizard.find("#spinning_wheel").hide();
$thisWizard.find("#after_action_message").html(afterActionMsg);
}

View File

@ -81,8 +81,9 @@ function zoneJsonToDetailsTab($leftmenuItem1) {
$detailsTab.find("#internaldns2_edit").val(fromdb(jsonObj.internaldns2));
$detailsTab.find("#vlan").text(fromdb(jsonObj.vlan));
var vlan = fromdb(jsonObj.vlan);
var vlan = jsonObj.vlan;
if(vlan != null) {
$("#midmenu_add2_link, #tab_network, #tab_content_details #vlan_container").show();
if(vlan.indexOf("-")!==-1) {
var startVlan = vlan.substring(0, vlan.indexOf("-"));
var endVlan = vlan.substring((vlan.indexOf("-")+1));
@ -93,6 +94,9 @@ function zoneJsonToDetailsTab($leftmenuItem1) {
$detailsTab.find("#startvlan_edit").val(vlan);
}
}
else {
$("#midmenu_add2_link, #tab_network, #tab_content_details #vlan_container").hide();
}
$detailsTab.find("#guestcidraddress").text(fromdb(jsonObj.guestcidraddress));
$detailsTab.find("#guestcidraddress_edit").val(fromdb(jsonObj.guestcidraddress));
@ -758,9 +762,9 @@ function doEditZone2($actionLink, $detailsTab, $midmenuItem1, $readonlyFields, $
isValid &= validateIp("DNS 2", $detailsTab.find("#dns2_edit"), $detailsTab.find("#dns2_edit_errormsg"), true); //optional
isValid &= validateIp("Internal DNS 1", $detailsTab.find("#internaldns1_edit"), $detailsTab.find("#internaldns1_edit_errormsg"), false); //required
isValid &= validateIp("Internal DNS 2", $detailsTab.find("#internaldns2_edit"), $detailsTab.find("#internaldns2_edit_errormsg"), true); //optional
if (getNetworkType() != "vnet") {
isValid &= validateString("Zone - Start VLAN Range", $detailsTab.find("#startvlan_edit"), $detailsTab.find("#startvlan_edit_errormsg"), false); //required
isValid &= validateString("Zone - End VLAN Range", $detailsTab.find("#endvlan_edit"), $detailsTab.find("#endvlan_edit_errormsg"), true); //optional
if ($("#tab_content_details #vlan_container").css("display") != "none") {
isValid &= validateString("Start VLAN Range", $detailsTab.find("#startvlan_edit"), $detailsTab.find("#startvlan_edit_errormsg"), false); //required
isValid &= validateString("End VLAN Range", $detailsTab.find("#endvlan_edit"), $detailsTab.find("#endvlan_edit_errormsg"), true); //optional
}
isValid &= validateCIDR("Guest CIDR", $detailsTab.find("#guestcidraddress_edit"), $detailsTab.find("#guestcidraddress_edit_errormsg"), false); //required
if (!isValid)
@ -790,7 +794,7 @@ function doEditZone2($actionLink, $detailsTab, $midmenuItem1, $readonlyFields, $
moreCriteria.push("&internaldns2="+encodeURIComponent(internaldns2));
var vlan;
if (getNetworkType() != "vnet") {
if ($("#tab_content_details #vlan_container").css("display") != "none") {
var vlanStart = trim($detailsTab.find("#startvlan_edit").val());
var vlanEnd = trim($detailsTab.find("#endvlan_edit").val());
if (vlanEnd != null && vlanEnd.length > 0)

View File

@ -1,85 +0,0 @@
#!/bin/bash
# chkconfig: 35 99 05
# description: CloudStack Virtual Network Daemon
# WARNING: if this script is changed, then all other initscripts MUST BE changed to match it as well
. /etc/rc.d/init.d/functions
whatami=cloud-vnetd
# set environment variables
SHORTNAME="$whatami"
PIDFILE=@PIDDIR@/"$whatami".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@LOCALSTATEDIR@/log/cloud/vnetd.log
PROGNAME="CloudStack Virtual Network Daemon"
unset OPTIONS
[ -r @SYSCONFDIR@/sysconfig/"$SHORTNAME" ] && source @SYSCONFDIR@/sysconfig/"$SHORTNAME"
DAEMONIZE=@BINDIR@/@PACKAGE@-daemonize
PROG=@SBINDIR@/$SHORTNAME
start() {
echo -n $"Starting $PROGNAME: "
daemon --check=$SHORTNAME --pidfile=${PIDFILE} "$DAEMONIZE" \
-n "$SHORTNAME" -p "$PIDFILE" -l "$LOGFILE" "$PROG" $OPTIONS
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch ${LOCKFILE}
return $RETVAL
}
stop() {
echo -n $"Stopping $PROGNAME: "
killproc -p ${PIDFILE} $SHORTNAME # -d 10 $SHORTNAME
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f ${LOCKFILE} ${PIDFILE}
}
recreate_vnets() {
for br in `ip link | grep vnbr | cut -d":" -f2| cut --complement -c1`;
do
vnetid=0000:0000:0000:0000:0000:0000:0000:`echo $br | cut -c5-`
vn vnet-create -b $br $vnetid &> /dev/null;
done
}
# See how we were called.
case "$1" in
start)
start
sleep 1
recreate_vnets
;;
stop)
stop
;;
status)
status -p ${PIDFILE} $SHORTNAME
RETVAL=$?
;;
restart)
stop
sleep 2
start
recreate_vnets
;;
condrestart)
if status -p ${PIDFILE} $SHORTNAME >&/dev/null; then
stop
sleep 2
start
recreate_vnets
fi
;;
*)
echo $"Usage: $whatami {start|stop|restart|condrestart|status|help}"
RETVAL=3
esac
exit $RETVAL

View File

@ -1,85 +0,0 @@
#!/bin/bash
# chkconfig: 35 99 05
# description: CloudStack Virtual Network Daemon
# WARNING: if this script is changed, then all other initscripts MUST BE changed to match it as well
. /etc/rc.d/init.d/functions
whatami=cloud-vnetd
# set environment variables
SHORTNAME="$whatami"
PIDFILE=@PIDDIR@/"$whatami".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@LOCALSTATEDIR@/log/cloud/vnetd.log
PROGNAME="CloudStack Virtual Network Daemon"
unset OPTIONS
[ -r @SYSCONFDIR@/sysconfig/"$SHORTNAME" ] && source @SYSCONFDIR@/sysconfig/"$SHORTNAME"
DAEMONIZE=@BINDIR@/@PACKAGE@-daemonize
PROG=@SBINDIR@/$SHORTNAME
start() {
echo -n $"Starting $PROGNAME: "
daemon --check=$SHORTNAME --pidfile=${PIDFILE} "$DAEMONIZE" \
-n "$SHORTNAME" -p "$PIDFILE" -l "$LOGFILE" "$PROG" $OPTIONS
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch ${LOCKFILE}
return $RETVAL
}
stop() {
echo -n $"Stopping $PROGNAME: "
killproc -p ${PIDFILE} $SHORTNAME # -d 10 $SHORTNAME
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f ${LOCKFILE} ${PIDFILE}
}
recreate_vnets() {
for br in `ip link | grep vnbr | cut -d":" -f2| cut --complement -c1`;
do
vnetid=0000:0000:0000:0000:0000:0000:0000:`echo $br | cut -c5-`
vn vnet-create -b $br $vnetid &> /dev/null;
done
}
# See how we were called.
case "$1" in
start)
start
sleep 1
recreate_vnets
;;
stop)
stop
;;
status)
status -p ${PIDFILE} $SHORTNAME
RETVAL=$?
;;
restart)
stop
sleep 2
start
recreate_vnets
;;
condrestart)
if status -p ${PIDFILE} $SHORTNAME >&/dev/null; then
stop
sleep 2
start
recreate_vnets
fi
;;
*)
echo $"Usage: $whatami {start|stop|restart|condrestart|status|help}"
RETVAL=3
esac
exit $RETVAL

View File

@ -1,104 +0,0 @@
#!/bin/bash
# chkconfig: 35 99 05
# description: CloudStack Virtual Network Daemon
# WARNING: if this script is changed, then all other initscripts MUST BE changed to match it as well
. /lib/lsb/init-functions
. /etc/default/rcS
whatami=cloud-vnetd
# set environment variables
SHORTNAME="$whatami"
PIDFILE=@PIDDIR@/"$whatami".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@LOCALSTATEDIR@/log/cloud/vnetd.log
PROGNAME="CloudStack Virtual Network Daemon"
unset OPTIONS
[ -r @SYSCONFDIR@/default/"$SHORTNAME" ] && source @SYSCONFDIR@/default/"$SHORTNAME"
DAEMONIZE=@BINDIR@/@PACKAGE@-daemonize
PROG=@SBINDIR@/$SHORTNAME
start() {
log_daemon_msg $"Starting $PROGNAME" "$SHORTNAME"
if [ -s "$PIDFILE" ] && kill -0 $(cat "$PIDFILE") >/dev/null 2>&1; then
log_progress_msg "apparently already running"
log_end_msg 0
exit 0
fi
if "$DAEMONIZE" -n "$SHORTNAME" -p "$PIDFILE" -l "$LOGFILE" "$PROG" $OPTIONS
RETVAL=$?
then
rc=0
sleep 1
if ! kill -0 $(cat "$PIDFILE") >/dev/null 2>&1; then
log_failure_msg "$PROG failed to start"
rc=1
fi
else
rc=1
fi
if [ $rc -eq 0 ]; then
log_end_msg 0
else
log_end_msg 1
rm -f "$PIDFILE"
fi
}
stop() {
echo -n $"Stopping $PROGNAME" "$SHORTNAME"
start-stop-daemon --stop --quiet --oknodo --pidfile "$PIDFILE"
log_end_msg $?
rm -f "$PIDFILE"
}
recreate_vnets() {
for br in `ip link | grep vnbr | cut -d":" -f2| cut --complement -c1`;
do
vnetid=0000:0000:0000:0000:0000:0000:0000:`echo $br | cut -c5-`
vn vnet-create -b $br $vnetid &> /dev/null;
done
}
# See how we were called.
case "$1" in
start)
start
sleep 1
recreate_vnets
;;
stop)
stop
;;
status)
status_of_proc -p "$PIDFILE" "$PROG" "$SHORTNAME"
RETVAL=$?
;;
restart)
stop
sleep 2
start
recreate_vnets
;;
condrestart)
if [ -f "$PIDFILE" ] ; then
stop
sleep 2
start
recreate_vnets
fi
;;
*)
echo $"Usage: $whatami {start|stop|restart|condrestart|status|help}"
RETVAL=3
esac
exit $RETVAL

View File

@ -1,904 +0,0 @@
#!/usr/bin/env python
# -*- mode: python; -*-
#============================================================================
# Copyright (C) 2005, 2006 Mike Wray <mike.wray@hp.com>
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This library 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Vnet (network virtualization) control utility.
import os
import os.path
import re
import socket
import sys
sys.path.insert(0,"@PYTHONDIR@")
from getopt import getopt, GetoptError
#from xen.xend import sxp
#from xen.xend.PrettyPrint import prettyprint
import cloud_sxp as sxp
from cloud_PrettyPrint import prettyprint
# Path of unix-domain socket to vnetd.
VNETD_PATH = "/tmp/vnetd"
def vnetd_running():
return os.path.exists(VNETD_PATH)
def vnetd_open():
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(VNETD_PATH)
fi = sock.makefile('r', 0)
fo = sock.makefile('w', 0)
return (fi, fo)
os.defpath += ':/sbin:/usr/sbin:/usr/local/sbin'
CMD_IFCONFIG = 'ifconfig'
CMD_BRCTL = 'brctl'
opts = None
class Opts:
def __init__(self, **kwds):
for (k, v) in kwds.items():
setattr(self, k, v)
opts = Opts(verbose=False, dryrun=False)
def set_opts(val):
global opts
opts = val
return opts
def cmd(prog, *args):
"""Execute command 'prog' with 'args', optionally printing the command.
"""
global opts
command = " ".join([ prog ] + map(str, args))
if opts.verbose:
print command
if not opts.dryrun:
os.system(command)
def vif_bridge_add(bridge, vif):
"""Add a network interface to a bridge.
"""
cmd(CMD_BRCTL, 'addif', bridge, vif)
def vif_bridge_rem(bridge, vif):
"""Remove a network interface from a bridge.
"""
cmd(CMD_BRCTL, 'delif', bridge, vif)
def bridge_create(bridge, **kwd):
"""Create a bridge.
Defaults hello time to 0, forward delay to 0 and stp off.
"""
cmd(CMD_BRCTL, 'addbr', bridge)
if kwd.get('hello', None) is None:
kwd['hello'] = 0
if kwd.get('fd', None) is None:
kwd['fd'] = 0
if kwd.get('stp', None) is None:
kwd['stp'] = 'off'
bridge_set(bridge, **kwd)
cmd(CMD_IFCONFIG, bridge, "up")
def bridge_set(bridge, hello=None, fd=None, stp=None):
"""Set bridge parameters.
"""
if hello is not None:
cmd(CMD_BRCTL, 'sethello', bridge, hello)
if fd is not None:
cmd(CMD_BRCTL, 'setfd', bridge, fd)
if stp is not None:
cmd(CMD_BRCTL, 'stp', bridge, stp)
def bridge_del(bridge):
"""Delete a bridge.
"""
cmd(CMD_IFCONFIG, bridge, 'down')
cmd(CMD_BRCTL, 'delbr', bridge)
class Bridge:
# Network interfaces are at /sys/class/net/*.
# A bridge interface has ./bridge dir, ./brif is dir of bridged interfaces
# (symlinks to the brport dirs).
# If an interface is bridged ./brport is bridged port info,
# brport/bridge is a symlink to the bridge.
INTERFACE_DIR = "/sys/class/net"
def isBridge(klass, dev):
"""Test if a network interface is a bridge.
"""
devdir = os.path.join(klass.INTERFACE_DIR, dev)
brdir = os.path.join(devdir, "bridge")
try:
os.stat(brdir)
return True
except:
return False
isBridge = classmethod(isBridge)
def getInterfaces(klass):
"""Get a list of the network interfaces.
"""
try:
v = os.listdir(klass.INTERFACE_DIR)
v.sort()
return v
except:
return []
getInterfaces = classmethod(getInterfaces)
def getInterfaceAddr(klass, intf):
intfdir = os.path.join(klass.INTERFACE_DIR, intf)
addrfile = os.path.join(intfdir, "address")
try:
f = file(addrfile, "rb")
except Exception, ex:
#print ex
return None
try:
return f.readline().strip()
finally:
f.close()
getInterfaceAddr = classmethod(getInterfaceAddr)
def getBridges(klass):
"""Get a list of the bridges.
"""
return [ dev for dev in klass.getInterfaces() if klass.isBridge(dev) ]
getBridges = classmethod(getBridges)
def getBridgeInterfaces(klass, dev):
"""Get a list of the interfaces attached to a bridge.
"""
devdir = os.path.join(klass.INTERFACE_DIR, dev)
intfdir = os.path.join(devdir, "brif")
try:
v = os.listdir(intfdir)
v.sort()
return v
except:
return []
getBridgeInterfaces = classmethod(getBridgeInterfaces)
def getBridge(klass, dev):
"""Get the bridge an interface is attached to (if any).
"""
devdir = os.path.join(klass.INTERFACE_DIR, dev)
brfile = os.path.join(devdir, "brport/bridge")
try:
brpath = os.readlink(brfile)
return os.path.basename(brpath)
except:
return None
getBridge = classmethod(getBridge)
def vnet_cmd(expr):
"""Send a command expression to the vnet implementation.
"""
if vnetd_running():
(fi, fo) = vnetd_open()
else:
fi = None
fo = file("/proc/vnet/policy", "wb")
try:
sxp.show(expr, fo)
fo.flush()
finally:
if fi: fi.close()
if fo: fo.close()
def varp_flush():
"""Flush the varp cache.
"""
expr = ['varp.flush']
return vnet_cmd(expr)
def vif_add(vnetid, vmac):
"""Tell the vnet implementation to add a vif to a vnet.
"""
expr = ['vif.add', ['vnet', vnetid], ['vmac', vmac]]
return vnet_cmd(expr)
def vif_del(vnetid, vmac):
"""Tell the vnet implementation to delete a vif from a vnet.
"""
expr = ['vif.del', ['vnet', vnetid], ['vmac', vmac]]
return vnet_cmd(expr)
def vnet_add(vnetid, vnetif=None, security=None):
"""Tell the vnet implementation to add a vnet.
"""
expr = ['vnet.add', ['id', vnetid]]
if vnetif:
expr.append(['vnetif', vnetif])
if security:
expr.append(['security', security])
return vnet_cmd(expr)
def peer_add(addr, port=None):
expr = ['peer.add', ['addr', addr]]
if port:
expr.append(['port', port])
return vnet_cmd(expr)
def peer_del(addr, port=None):
expr = ['peer.del', ['addr', addr]]
return vnet_cmd(expr)
def vnet_del(vnetid):
"""Tell the vnet implementation to delete a vnet.
"""
expr = ['vnet.del', ['id', vnetid]]
return vnet_cmd(expr)
def vnet_create(vnetid, vnetif=None, bridge=None, security=None):
"""Tell the vnet implementation to add a vnet.
If 'bridge' is non-null, create the bridge and add the vnet interface
to it.
"""
vnet_add(vnetid, vnetif=vnetif, security=security)
val = vnet_lookup(vnetid)
if not vnetif:
vnetif = sxp.child_value(val, "vnetif")
vmac = get_mac(vnetif)
emac = get_mac("eth0") or get_mac("eth1") or get_mac("eth2")
if emac and vmac != emac:
set_mac(vnetif, emac)
cmd(CMD_IFCONFIG, vnetif, 'up')
if bridge:
bridge_create(bridge)
vif_bridge_add(bridge, vnetif)
return val
def vnet_delete(vnet, delbridge=False):
"""Tell the vnet implementation to delete a vnet.
If the vnet interface is attached to a bridge,
remove it from the bridge, and if delbridge is true
delete the bridge.
"""
v = vnet_lookup(vnet)
if not v:
raise GetoptError("vnet not found: %s" % vnet)
vnetid = sxp.child_value(v, "id")
vnetif = sxp.child_value(v, "vnetif")
bridge = Bridge.getBridge(vnetif)
if bridge:
vif_bridge_rem(bridge, vnetif)
if delbridge:
bridge_del(bridge)
return vnet_del(vnetid)
def get_mac(intf):
"""Get the mac address of an interface.
"""
try:
return Bridge.getInterfaceAddr(intf)
except:
pass
hwre = re.compile(".*\s+HWaddr\s+(?P<mac>\S*)\s+.*")
fin = os.popen("%s %s" % (CMD_IFCONFIG, intf), 'r')
try:
for x in fin:
m = hwre.match(x)
if not m:
continue
info = m.groupdict()
return info['mac']
return None
finally:
fin.close()
def set_mac(intf, mac):
cmd(CMD_IFCONFIG, intf, 'down')
cmd(CMD_IFCONFIG, intf, 'hw', 'ether', mac)
cmd(CMD_IFCONFIG, intf, 'up')
def get_addr(host):
return socket.gethostbyname(host)
def get_port(srv):
return srv
def vnetidof(v):
"""Normalise a vnet id. Adds leading 0 fields to make up 8 if
there aren't enough. Pads all fields to 4 hex digits.
"""
try:
l = v.split(":")
l = [ int(x or 0, 16) for x in l ]
l = [ 0 ] * (8 - len(l)) + l
return ":".join([ "%04x" % x for x in l ])
except:
return None
def vnet_lookup(vnet, vnets=None):
"""Find the vnet with the given vnet id or vnet interface.
@param vnet id or interface
@param vnets list of vnet info to use (get from implementation if None)
@return vnet info or None if not found
"""
vnetid = vnetidof(vnet)
if vnets is None:
vnets = vnet_list()
for v in vnets:
vid = sxp.child_value(v, "id")
if vid == vnet or vid == vnetid:
return v
if sxp.child_value(v, "vnetif") == vnet:
return v
return None
def get_vnetid(vnet):
"""Get the normalised vnet id of the given vnet id or vnet interface.
Raises an error if the vnet cannot be found.
"""
v = vnet_lookup(vnet)
if not v:
raise GetoptError("vnet not found: %s" % vnet)
vnetid = sxp.child_value(v, "id")
return vnetid
def vif_list():
"""Get the list of vif info from the vnet implementation.
"""
if vnetd_running():
(fi, fo) = vnetd_open()
sxp.show(['vif.list'], fo)
fo.flush()
else:
fi = file("/proc/vnet/vifs")
fo = None
try:
return sxp.parse(fi) or []
finally:
if fi: fi.close()
if fo: fo.close()
def vnets_filter(vnetlist, vnets):
"""Filter a list of vnet info by a list of vnet ids or interfaces.
"""
if vnets is None:
val = vnetlist
else:
val = []
for x in vnets:
v = vnet_lookup(x, vnets=vnetlist)
if not v:
continue
val.append(v)
return val
def vnet_list(vnets=None):
"""Get the list of vnet info from the vnet implementation,
sorted by vnet id.
@param vnets list of vnet ids or interfaces to filter the results by
"""
if vnetd_running():
(fi, fo) = vnetd_open()
sxp.show(['vnet.list'], fo)
fo.flush()
else:
fi = file("/proc/vnet/vnets")
fo = None
try:
val = vnets_filter(sxp.parse(fi) or [], vnets)
val.sort(lambda x, y:
cmp(sxp.child_value(x, "id"),
sxp.child_value(y, "id")))
return val
finally:
if fi: fi.close()
if fo: fo.close()
def vnif_list(vnets=None):
"""Get the list of vnet interface names from the vnet implementation.
@param vnets list of vnet ids or interfaces to filter the results by
"""
vnifs = []
for v in vnet_list(vnets=vnets):
vnetif = sxp.child_value(v, "vnetif")
if vnetif:
vnifs.append(vnetif)
return vnifs
def varp_list():
"""Get the list of varp info from the vnet implementation.
"""
if vnetd_running():
(fi, fo) = vnetd_open()
sxp.show(['varp.list'], fo)
fo.flush()
else:
fi = file("/proc/vnet/varp")
fo = None
try:
return sxp.parse(fi) or []
finally:
if fi: fi.close()
if fo: fo.close()
def peer_list():
if vnetd_running():
(fi, fo) = vnetd_open()
sxp.show(['peer.list'], fo)
fo.flush()
else:
fi = file("/proc/vnet/peers")
fo = None
try:
return sxp.parse(fi) or []
finally:
if fi: fi.close()
if fo: fo.close()
class Opt:
"""Declares command-line options for a command.
"""
def getopt(klass, argv, opts, args):
"""Get options and args from argv.
The value opts in the return value has an attribute for
eacho option or arg. The value args in the return value
is the remaining arguments.
@param argv arguments
@param opts option specifiers (list of Opt objects)
@param args arg specififiers (list of Arg objects)
@return (opts, args)
"""
shortopts = "".join([ x.optShort() for x in opts ])
longopts = [ x.optLong() for x in opts ]
(ovals, oargs) = getopt(argv[1:], shortopts, longopts)
odir = Opts()
for x in opts:
x.setDefault(odir)
for (k, v) in ovals:
for x in opts:
x.setOpt(k, v, odir)
argc = len(oargs)
if len(oargs) < len(args):
raise GetoptError("insufficient arguments for %s" % argv[0])
for (x, v) in zip(args, oargs):
x.setArg(v, odir)
return (odir, oargs[len(args): ])
getopt = classmethod(getopt)
def gethelp(klass, opts, args):
l = []
for x in opts:
l.append(x.help())
for x in args:
l.append(x.help())
return " ".join(l)
gethelp = classmethod(gethelp)
"""A command=-line option.
@param name option name (this attribute is set to value in opts)
@param short short option flag (single-character string)
@param long long option name (defaults to option name, pass "" to suppress)
@param arg argument name (option has no arg if not specified)
"""
def __init__(self, name, short=None, long=None, arg=False):
self.name = name
self.short = short
if long is None:
long = name
elif not long:
long = None
self.long = long
self.arg = arg
def help(self):
s = self.keyShort()
l = self.keyLong()
if s and l:
return "[%s | %s]" % (s, l)
else:
return s or l
def keyShort(self):
if self.short:
return "-%s" % self.short
else:
return None
def keyLong(self):
if self.long:
return "--%s" % self.long
else:
return None
def optLong(self):
if not self.long:
return None
if self.arg:
return "%s=" % self.long
else:
return self.long
def optShort(self):
if not self.short:
return None
if self.arg:
return "%s:" % self.short
else:
return self.short
def setDefault(self, vals):
if self.arg:
setattr(vals, self.name, None)
else:
setattr(vals, self.name, False)
def setOpt(self, k, v, vals):
if k in [ self.keyShort(), self.keyLong() ]:
if self.arg:
setattr(vals, self.name, v)
else:
if v not in [ None, '' ]:
raise GetoptError("option %s does not take an argument" % k)
setattr(vals, self.name, True)
class Arg:
"""A command-line parameter. Args get their values from arguments
left over after option processing and are assigned in order.
The value is accessible as the attribute called 'name' in opts.
@param name argument name
"""
def __init__(self, name):
self.name = name
def setArg(self, v, vals):
setattr(vals, self.name, v)
def help(self):
return "<%s>" % self.name
class VnMain:
"""Methods beginning with this prefix are commands.
They must all have arguments like this:
op_foo(self, argv, args, opts)
argv: original command-line arguments
args: arguments left after option processing
opts: option and arg values (accessible as attributes)
Method options are specified by setting attribute
.opts on the method to a list of Option objects.
For args set .args to a list of Arg objects.
Use .use for short usage string, .help for long help.
Each option or arg defines an attribute in opts. For example
an option with name 'foo' is accessible as 'opts.foo'.
"""
opPrefix = "op_"
def __init__(self, argv):
if argv:
self.name = argv[0]
else:
self.name = "vn"
self.argv = argv
self.argc = len(argv)
def error(self, v):
print >>sys.stderr, "%s: %s" % (self.name, v)
sys.exit(1)
def getFunction(self, opname):
key = self.opPrefix + opname.replace("-", "_")
fn = getattr(self, key, None)
if not fn:
raise ValueError("unknown command: %s" % opname)
return fn
def main(self):
if self.argc < 2:
args = ["help"]
else:
args = self.argv[1:]
try:
fn = self.getFunction(args[0])
except ValueError, ex:
self.error(ex)
try:
fnopts = self.getOpts(fn)
fnargs = self.getArgs(fn)
(opts, parms) = Opt.getopt(args, fnopts, fnargs)
return fn(args, parms, opts)
except GetoptError, ex:
self.error(ex)
except ValueError, ex:
self.error(ex)
except Exception, ex:
import traceback; traceback.print_exc()
self.error(ex)
def getOpts(self, meth):
return getattr(meth, "opts", [])
def getArgs(self, meth):
return getattr(meth, "args", [])
def getUse(self, meth):
return getattr(meth, "use", "")
def getHelp(self, meth):
return getattr(meth, "help", "") or self.getUse(meth)
def fnHelp(self, meth):
return Opt.gethelp(self.getOpts(meth), self.getArgs(meth))
def printHelp(self, fn, opt_long):
meth = getattr(self, fn)
opname = fn[len(self.opPrefix):].replace("_", "-")
if opt_long:
help = self.getHelp(meth)
print "\n %s" % opname
if help:
print "%s" % help
else:
use = self.getUse(meth)
print " %s %s" % (opname, self.fnHelp(meth))
if use:
print "\t\t%s" % use
def show_vnif(self, dev):
cmd(CMD_IFCONFIG, dev)
bridge = Bridge.getBridge(dev)
if bridge:
print " Bridge:", bridge
interfaces = Bridge.getBridgeInterfaces(bridge)
if dev in interfaces:
interfaces.remove(dev)
if interfaces:
print " Interfaces:", ", ".join(interfaces)
print
def op_help(self, argv, args, opts):
if opts.long:
print '%s <command> <options>' % self.name
print self.long_help
else:
print '%s:' % self.name
l = dir(self)
l.sort()
for fn in l:
if fn.startswith(self.opPrefix):
self.printHelp(fn, opts.long)
print
op_help.opts = [ Opt('long', short='l') ]
def op_vnets(self, argv, args, opts):
vnets = vnet_list(vnets=args or None)
for v in vnets:
prettyprint(v, width=50)
print
if not opts.long:
continue
vnif = sxp.child_value(v, "vnetif")
if not vnif:
continue
self.show_vnif(vnif)
if opts.all:
vnetids = {}
for v in vnets:
vnetids[sxp.child_value(v, "id")] = v
for v in vif_list():
vnet = sxp.child_value(v, "vnet")
if vnet not in vnetids:
continue
prettyprint(v)
print
for v in varp_list():
prettyprint(v)
print
op_vnets.opts = [ Opt('all', short='a'), Opt('long', short='l') ]
def op_vnifs(self, argv, args, opts):
vnifs = vnif_list(vnets=args or None)
for vnif in vnifs:
self.show_vnif(vnif)
def op_vifs(self, argv, args, opts):
for v in vif_list():
prettyprint(v)
print
def op_varp(self, argv, args, opts):
for v in varp_list():
prettyprint(v)
print
def op_varp_flush(self, argv, args, opts):
varp_flush()
def op_vnet_create(self, argv, args, opts):
return vnet_create(opts.vnet,
vnetif=opts.vnetif,
bridge=opts.bridge,
security=opts.security)
op_vnet_create.args = [ Arg('vnet') ]
op_vnet_create.opts = [ Opt('security', short='s', arg="SECURITY"),
Opt('bridge', short='b', arg="BRIDGE"),
Opt('vnetif', short='v', arg="VNETIF") ]
def op_vnet_delete(self, argv, args, opts):
vnetid = get_vnetid(opts.vnet)
return vnet_delete(vnetid, delbridge=opts.bridge)
op_vnet_delete.args = [ Arg('vnet') ]
op_vnet_delete.opts = [ Opt('bridge', short='b') ]
def op_vif_add(self, argv, args, opts):
vnetid = get_vnetid(opts.vnet)
if opts.interface:
vmac = get_mac(opts.vmac)
if not vmac:
raise ValueError("interface not found: %s" % opts.vmac)
else:
vmac = opts.vmac
return vif_add(vnetid, vmac)
op_vif_add.args = [ Arg('vnet'), Arg('vmac') ]
op_vif_add.opts = [ Opt('interface', short='i') ]
def op_vif_delete(self, argv, args, opts):
vnetid = get_vnetid(opts.vnet)
if opts.interface:
vmac = get_mac(opts.vmac)
else:
vmac = opts.vmac
return vif_del(vnetid, vmac)
op_vif_delete.args = [ Arg('vnet'), Arg('vmac') ]
op_vif_delete.opts = [ Opt('interface', short='i') ]
def op_peer_add(self, argv, args, opts):
addr = get_addr(opts.addr)
if(opts.port):
port = get_port(opts.port)
else:
port = None
return peer_add(addr, port)
op_peer_add.args = [ Arg('addr') ]
op_peer_add.opts = [ Opt('port', short='p') ]
def op_peer_delete(self, argv, args, opts):
addr = get_addr(opts.addr)
return peer_del(addr)
op_peer_delete.args = [ Arg('addr') ]
def op_peers(self, argv, args, opts):
for v in peer_list():
prettyprint(v)
print
def op_bridges(self, argv, args, opts):
if opts.long:
for bridge in Bridge.getBridges():
cmd(CMD_IFCONFIG, bridge)
interfaces = Bridge.getBridgeInterfaces(bridge)
if interfaces:
print " Interfaces:", ", ".join(interfaces)
print
else:
for bridge in Bridge.getBridges():
print bridge,
interfaces = Bridge.getBridgeInterfaces(bridge)
if interfaces:
print ":", ", ".join(interfaces)
else:
print
op_bridges.opts = [ Opt('long', short='l') ]
def op_insmod(self, argv, args, opts):
"""Insert the vnet kernel module."""
"""cmd("/etc/xen/scripts/vnet-insert", *args)"""
long_help = """Control utility for vnets (virtual networking).
Report bugs to Mike Wray <mike.wray@hp.com>.
"""
op_help.use = "Print help."
op_help.help = "Print help, long help if the option -l or --long is given."
op_vnets.use = """Print vnets."""
op_vnets.help = """Print vnet information, where options are:
-a, -all Print vnets, vifs and varp info.
-l, --long Print ifconfigs for vnet interfaces."""
op_vifs.use = "Print vifs."
op_vnifs.use = "Print ifconfigs for vnet network interfaces."
op_varp.use = "Print varp info and entries in the varp cache."
op_varp_flush.use = "Flush the varp cache."
op_vnet_create.use = "Create a vnet."
op_vnet_delete.use = "Delete a vnet."
op_vnet_delete.help = """Delete a vnet.
-b, --bridge Delete the bridge the vnet interface is attached to.
"""
op_vif_add.use = "Add a vif to a vnet."
op_vif_add.help = """Add a vif to a vnet. Not usually needed as vifs
are added automatically.
-i, --interface The vmac is the name of an interface to get the mac from."""
op_vif_delete.use = "Delete a vif from a vnet."
op_vif_delete.help = """Delete a vif from a vnet. Not usually needed as vifs
are removed periodically.
-i, --interface The vmac is the name of an interface to get the mac from."""
op_peer_add.use = "Add a peer."
op_peer_add.help = """Add a peer: <addr> <port>
Vnets use multicast to discover interfaces, but networks are often configured
not to forward multicast. Vnets forward multicasts to peers using UDP.
Only add peers if multicasts are not working, check with
ping -b 224.10.0.1
Only add peers at one machine in a subnet, otherwise you may cause forwarding
loops.
"""
op_peer_delete.use = "Delete a peer."
op_peer_delete.help= "Delete a peer: <addr>"
op_peers.use = "List peers."
op_peers.help = "List peers."
op_bridges.use = "Print bridges."
op_insmod.use = "Insert the vnet kernel module, optionally with parameters."
if __name__ == "__main__":
vn = VnMain(sys.argv)
vn.main()

View File

@ -1,55 +0,0 @@
This directory contains the implementation of vnets:
virtual private networks for virtual machines.
make
- compile in local dirs. The module is in vnet-module/vnet_module.ko.
make dist
- compile and install into $(XEN_ROOT)/dist/install,
- where XEN_ROOT is the root of the xen tree.
make install
- compile and install into system.
By default the makefiles expect this code to have been installed
in tools/vnet in a xen source tree. If compiling outside the xen
source tree, set XEN_ROOT to the location of the xen source.
You can do this in the environment or in a Make.local file
in the current directory (see Make.env for details).
The xen0 kernel must have been compiled before building the vnet module.
The vnet module installs to
/lib/modules/<kernel version>-xen0/kernel/xen/vnet_module.ko
The vnet module should be loaded before starting xend, or
xend will fail to create any persistent vnets it has in its configuration.
The script network-vnet is a modified version of the xen network script
that loads the module if it's not already loaded.
The module uses kernel crypto functions, and these need to be
enabled in the xen0 kernel config. They should be on by default -
if they're not you will get compile or insmod errors (see below).
Kernel config options:
1) You will need to have your xen0 kernel compiled with HMAC_SUPPORT
2.6.x = (MAIN MENU: Cryptographic Options -> HMAC Support)
BEFORE running "make install".
2) You will want at least some of the other algorithms listed under
"Cryptographic Options" for the kernel compiled as modules.
3) You will want the networking IPsec/VLAN options compiled in as modules
2.6.x = (MAIN MENU: Device Drivers -> Networking Support ->
Networking Options ->
IP: AH transformation
IP: ESP transformation
IP: IPComp transformation
IP: tunnel transformation
IPsec user configuration interface
802.1Q VLAN Support
Please refer to the additional documentation found in tools/vnet/doc for
proper syntax and config file parameters.

View File

@ -1,15 +0,0 @@
This directory contains the implementation of vnets:
virtual private networks for virtual machines.
See 00INSTALL for build instructions, doc/ for more information
and examples/ for example configurations.
The vnet implementation can be run using a kernel module
or a user-space daemon. The kernel module is in vnet-module/ and the
user-space daemon (varpd) is in vnetd/. The user-space daemon
needs the tun/tap kernel module. Vnets use multicast to find
virtual interfaces and support broadcast. Either implementation can
tunnel multicast packets to other implementations if wide-area
multicast routing is not available.
Mike Wray <mike.wray@hp.com>

View File

@ -1,28 +0,0 @@
# -*- mode: Makefile; -*-
# Include any local overrides.
-include $(VNET_ROOT)/Make.local
# If building vnets outside the xen source tree, set XEN_ROOT to the
# absolute path of the root of the xen source tree. Edit this file
# or set XEN_ROOT in Make.local, the make command line or
# the environment. For example put this in Make.local:
# export XEN_ROOT = $(shell cd ~/xen-unstable.hg && pwd)
export XEN_ROOT ?= $(shell cd $(VNET_ROOT)/../.. && pwd)
export LINUX_SERIES ?= 2.6
DISTDIR ?= $(XEN_ROOT)/dist
export DESTDIR ?= $(DISTDIR)/install
export VNET_MODULE_DIR = $(VNET_ROOT)/vnet-module
export VNETD_DIR = $(VNET_ROOT)/vnetd
export LIBXUTIL_DIR = $(VNET_ROOT)/libxutil
export GC_DIR = $(VNET_ROOT)/build/gc
export GC_INCLUDE = $(GC_DIR)/include
export GC_LIB_DIR = $(GC_DIR)/lib
export GC_LIB_A = $(GC_LIB_DIR)/libgc.a
export GC_LIB_SO = $(GC_LIB_DIR)/libgc.so

View File

@ -1,89 +0,0 @@
# -*- mode: Makefile; -*-
ifndef VNET_ROOT
export VNET_ROOT = $(shell pwd)
include $(VNET_ROOT)/Make.env
endif
SUBDIRS:=
SUBDIRS+= examples
SUBDIRS+= scripts
#SUBDIRS+= gc
SUBDIRS+= libxutil
SUBDIRS+= vnetd
SUBDIRS+= vnet-module
.PHONY: all
all: compile
gc.tar.gz:
wget http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/$@
.PHONY: gc
gc: gc.tar.gz
tar xfz gc.tar.gz
ln -sf gc?.? gc
$(GC_LIB_A): gc
(cd gc && ./configure --prefix=$(GC_DIR) )
make -C gc
DESTDIR="" make -C gc install
.PHONY: gc-all
gc-all: $(GC_LIB_A)
.PHONY: gc-install
gc-install:
.PHONY: gc-clean
gc-clean:
-@$(RM) -r gc?.? gc
submak = $(MAKE) -C $(patsubst %-$(1),%,$(@)) $(1)
subtgt = $(patsubst %,%-$(1),$(SUBDIRS))
%-all:
$(call submak,all)
%-clean:
-$(call submak,clean)
%-install:
$(call submak,install)
.PHONY: compile
compile: $(call subtgt,all)
.PHONY: install
install: DESTDIR=
install: dist
.PHONY: dist
dist: compile $(call subtgt,install)
.PHONY: clean
clean: $(call subtgt,clean)
-@$(RM) -r build
.PHONY: pristine
pristine: clean
-@$(RM) gc.tar.gz
.PHONY: help
help:
@echo 'Cleaning targets:'
@echo ' clean - clean subdirs and remove the build dir'
@echo ' pristine - clean, then remove the gc tarball'
@echo ''
@echo 'Installation targets:'
@echo ' install - build and install relative to /'
@echo ' dist - build and install relative to DESTDIR (default XEN_ROOT/dist/install)'
@echo ''
@echo 'Compilation targets:'
@echo ' all - same as compile'
@echo ' compile - build everything'
@echo ''
@echo 'To build everything locally use "make" or "make all"'.
@echo 'To build and install into XEN_ROOT/dist/install use "make dist".'
@echo 'To build and install into the system use "make dist".'
@echo 'See ./00README and ./00INSTALL for more information.'

View File

@ -1,51 +0,0 @@
#!/usr/bin/make -f
# -*- mode: Makefile; -*-
XEN_ROOT = ../../..
include $(XEN_ROOT)/tools/Rules.mk
VERSION = 1.0
HEADER = Vnet
PS2PDF := ps2pdf
DVIPS := dvips
LATEX := latex
LATEX2HTML := latex2html
DOXYGEN := doxygen
POD2MAN := pod2man
DOC_MAN5SRC := $(wildcard man/*.pod.5)
DOC_MAN1SRC := $(wildcard man/*.pod.1)
DOC_MAN1 := $(patsubst man/%.pod.1,man1/%.1,$(DOC_MAN1SRC))
DOC_MAN5 := $(patsubst man/%.pod.5,man5/%.5,$(DOC_MAN5SRC))
.PHONY: all man clean install
.PHONY: all
all: man
.PHONY: man
man:
@if which $(POD2MAN) 1>/dev/null 2>/dev/null; then \
$(MAKE) $(DOC_MAN1) $(DOC_MAN5); fi
man1/%.1: man/%.pod.1 Makefile
$(INSTALL_DIR) $(@D)
$(POD2MAN) --release=$(VERSION) --name=`echo $@ | sed 's/^man1.//'| \
sed 's/.1//'` -s 1 -c $(HEADER) $< $@
man5/%.5: man/%.pod.5 Makefile
$(INSTALL_DIR) $(@D)
$(POD2MAN) --release=$(VERSION) --name=`echo $@ | sed 's/^man5.//'| \
sed 's/.5//'` -s 5 -c $(HEADER) $< $@
.PHONY: clean
clean:
@$(RM) -rf man5
@$(RM) -rf man1
.PHONY: install
install: all
$(INSTALL_DIR) $(DESTDIR)$(MANDIR)
$(CP) -dR man1 $(DESTDIR)$(MANDIR)
$(CP) -dR man5 $(DESTDIR)$(MANDIR)

View File

@ -1,176 +0,0 @@
=head1 NAME
vn - Vnet (virtual networking) management utility.
=head1 SYNOPSIS
vn <command> [args]
=head1 DESCRIPTION
The B<vn> utility manages vnets, virtual networks for virtual machines.
Before using vnets, the vnet kernel module must be installed or
the user-space daemon vnetd must be running. Using the kernel module is recommended,
see the B<insmod> command below.
A vnet is a virtual network that behaves like a private LAN, transporting
Ethernet frames. Each vnet is identified by a 128-bit vnet id and
has a network device that interfaces to it. Ethernet packets written
to the device are encapsulated and sent to the network.
Received vnet packets are decapsulated and delivered from the device
corresponding to their vnet id. The default encapsulation uses UDP on port 1798.
Usually each vnet device is enslaved to a corresponding bridge, and virtual
machine interfaces are attached to vnets by enslaving them to the bridge.
Each vnet behaves like a private LAN: traffic on one vnet is not visible
on other vnets, and interfaces on a vnet cannot see traffic on the
physical network.
Vnets can be connected together into larger networks
by direct bridging or packet forwarding, or by using multihomed vms
with interfaces on several vnets, or vnets and the physical network.
As vnet interfaces are discovered dynamically, vnet connectivity is maintained
if a vm using a vnet is migrated from one physical machine to another.
In the commands vnet ids can be given in two forms. Long form, as 8 4-digit hex fields
separated by colons, for example 0000:0000:0000:0000:0000:0000:0000:0004, and
short form as a hex field, for example 0004 or 4. The short form is the same as the
long form with the first 7 fields zero. Vnet id 0000:0000:0000:0000:0000:0000:0000:0001
is reserved for the physical network and has no vnet device.
Vnets use multicast to discover the location of virtual interfaces, by default
using multicast group 224.10.0.1. If all the machines hosting vnets are on
the same subnet, or reachable by multicast, vnets will span all the machines
automatically. If some machines are not reachable by multicast you can configure
vnets to perform multicast forwarding using UDP.
The vnet devices are fully-functional network devices, so you can add IP addresses
to them and test connectivity without any vms running.
For example, using vnif0004 on machines A and B:
A> ifconfig vnif0004 192.0.2.11
B> ifconfig vnif0004 192.0.2.12
B> ping 192.0.2.11
If the vnet device is enslaved to a bridge you will have to add the IP address
to the bridge instead. Use C<brctl show> or C<vn vnets> to see if a vnet
device is on a bridge.
=over 4
=item B<insmod> I<[varp_mcaddr=ADDR]>
Insert the vnet kernel module, optionally supplying the multicast
address to use, default 224.10.0.1.
=item B<varp>
Print varp infrormation and varp cache.
=item B<vnets> [options]
Print the list of vnets (virtual networks). If a vnet device is on a bridge,
also shows the bridge and its bridged interfaces.
=over 4
=item B<-a | --all>
Also print the vifs on each vnet and varp information.
=item B<-l | --long>
Also print the ifconfig for the vnet devices.
=back
=item B<vnet-create> I<[options]> I<vnetid>
Create a vnet with the given id. The options are:
=over 4
=item B<-s | --security> I<level>
Security level, which can be one of I<none> for no security,
I<auth> for message authentication, and I<conf> for message
authentication and confidentiality. The default is no security.
Security is provided using IPSEC, but uses hard-wired keys.
=item B<-b | --bridge> I<bridgename>
Create a bridge for the vnet called I<bridgename> and enslave
the vnet device to it.
=item B<-v | --vnetif> I<vnetifname>
Use I<vnetifname> as the name for the vnet device. If this option
is not specified the default is to name the device vnifN where N
is the last field of the vnet id as 4 hex characters.
For example vnif0004. Network device names can be at
most 14 characters.
=back
=item B<vnet-delete> I<[options]> I<vnetid>
Delete the vnet with the given id. The vnet device goes away too.
=over 4
=item B<-b | --bridge>
If this option is specified, delete the bridge associated with the vnet.
=back
=item B<vifs>
Print the list of vifs (virtual interfaces).
=item B<vif-add> I<[-i|-interface]> I<vnet> I<vmac>
Add a vif to a vnet. Here I<vnet> is the vnet id and I<vmac>
is the vif's MAC address. Alternatively, I<vmac> can be the name of
a network device if the I<-i> or -I<--interface> flag is given.
It is not usually necessary to use B<vif-add> as vnets automatically
add vifs for the MAC addresses they see.
=item B<vif-delete> I<[-i|-interface]> I<vnet> I<vmac>
Delete a vif from a vnet. Here I<vnet> is the vnet id and I<vmac>
is the vif's MAC address. Alternatively, I<vmac> can be the name of
a network device if the I<-i> of -I<--interface> flag is given.
It is not usually necessary to use B<vif-delete> as vnets periodically
delete unused vifs.
=item B<peers>
Print the list of peer vnet machines to forward multicasts to, and accept
forwarded multicasts from.
=item B<peer-add> I<addr>
Add the peer with the given IP address or hostname.
=item B<peer-delete> I<addr>
Delete the peer with the given IP address or hostname.
=back
=head1 AUTHOR
The author of vn and vnets is Mike Wray of HP Labs. Please send problems, bugs,
enhancements requests etc. to mike.wray@hp.com.
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2006 Mike Wray <mike.wray@hp.com>.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

View File

@ -1,72 +0,0 @@
Vnet Low-level Command Interface
Mike Wray <mike.wray@hp.com>
2006/10/12
The vnet kernel module and user-space daemon vnetd support a low-level
command interface to control vnets. The kernel module creates /proc/vnet/policy,
which is used by writing commands into it. Vnetd listens on the unix-domain
socket /tmp/vnetd.
The vn utility in ../scripts provides a higher-level interface to
the vnet commands (using the kernel module or vnetd).
The commands are:
(vnet.add (id <id>) [(vnetif <ifname>)] [(security { none | auth | conf } )] )
Create the vnet with id <id> and the given security level (default none).
Vnet ids are 128-bit and can be specified as 8 fields of 1 to 4 hex digits
separated by colons. A vnet id with no colons is treated as one with the first
7 fields zero. Examples:
1500 - equivalent to 0:0:0:0:0:0:0:1500
aaff:0:0:0:0:0:77:88
Security levels:
- none: no security
- auth: message authentication (IPSEC hmac)
- conf: message confidentiality (IPSEC hmac and encryption)
The <ifname> is the name of the network device created for the vnet.
If not given it defaults to vnif<N>, where <N> is the hex for the
8-th field in the id. Note that network device names can have a
maximum of 14 characters.
(vnet.del (id <id>))
Delete the vnet with id <id>.
(vif.add (vnet <vnetid>) (vmac <macaddr>))
Add the vif with MAC address <macaddr> to the vnet with id <vnetid>.
This makes the vnet module respond to VARP requests for <macaddr>
on vnet <vnetid>. The vnet implementation learns MAC addresses
so doing this should not be necessary.
(vif.del (vnet <vnetid>) (vmac <macaddr>))
Remove the vif with MAC address <macaddr> from the vnet with id <vnetid>.
The vnet module will stop responding to VARP for the vif.
(peer.add (addr <addr>))
Add a peer at IP address <addr> to forward multicasts to,
and accept forwarded multicasts from.
(peer.del (addr <addr>))
Delete a peer.
(vif.list) - get list of vifs.
(vnet.list) - get list of vnets.
(varp.list) - get vnet/varp info.
(peer.list) - get list of peers.
The kernel module produces output on the console, and vnetd
returns output on the unix socket. The kernel module also provides
the following files which can be read to get information:
/proc/vnet/vifs - get list of vifs.
/proc/vnet/vnets - get list of vnets.
/proc/vnet/varp - get vnet/varp info.
/proc/vnet/peers - get list of peers.

View File

@ -1,167 +0,0 @@
Vnets: Virtual Networks for Virtual Machines
Mike Wray <mike.wray@hp.com>
2005/12/13
0) Introduction
---------------
Vnets provide virtual private LANs for virtual machines.
This is done using bridging and multipoint tunneling. A virtual interface
on a vnet can only see other interfaces on the same vnet - it cannot
see the real network, and the real network cannot see it either.
Virtual interfaces on the same vnet can be on the same machine
or on different machines, they can still talk. The hosting machines
can even be on different subnets if you configure vnet forwarding,
or have multicast routing enabled.
1) Installing vnet support
--------------------------
Assuming the code has been installed (make install in the parent directory),
configure xend to use 'network-vnet' instead of the default 'network' to
start up networking. This just loads the vnet module when networking starts.
In /etc/xend/xend-config.sxp:
Configure the network script:
(network-script network-vnet)
Restart xend.
Alternatively insert the vnet module using 'vn insmod',
preferably before xend starts.
2) Creating vnets
-----------------
Xend already implements commands to add/remove vnets and
bridge to them. To add a vnet use
xm vnet-create <vnet config file>
For example, if vnet97.sxp contains:
(vnet (id 97) (bridge vnet97) (vnetif vnif97) (security none))
do
xm vnet-create vnet97.sxp
This will define a vnet with id 97 and no security. The bridge for the
vnet is called vnet97 and the virtual interface for it is vnif97.
To add an interface on a vm to this vnet simply set its bridge to vnet97
in its configuration.
In Python:
vif="bridge=vnet97"
In sxp:
(dev (vif (mac aa:00:00:01:02:03) (bridge vnet97)))
By default vnets use udp encapsulation, but if you use etherip encapsulation
you will also have to reduce the MTU of the corresponding
device in the domain (because of the tunneling). Reducing the MTU may improve
performance for udp encapsulation, but is not necessary.
For example, for eth0 (in the domain, not dom0) use
ifconfig eth0 mtu 1400
or, better, put
MTU=1400
in /etc/sysconfig/network-scripts/ifcfg-eth0. You may also have to change or remove
cached config files for eth0 under /etc/sysconfig/networking.
Once configured, vnets are persistent in the xend database.
To remove a vnet use
xm vnet-delete <vnet id>
To list vnets use
xm vnet-list
To get information on one or more vnet ids use
xm vnet-list <vnet id>...
You can also manage vnets using the vn utility which talks
directly to the vnet implementation. The source is in ../scripts/vn
and is installed in /usr/sbin/vn.
3) Troubleshooting
------------------
The vnet module should appear in 'lsmod'.
If a vnet has been configured it should appear in the output of 'xm vnet-list'.
Its bridge and interface should appear in 'ifconfig'.
It should also show in 'brctl show', with its attached interfaces.
You can 'see into' a vnet from dom0 if you put an IP address on the bridge.
For example, if you have vnet97 and a vm with ip addr 192.0.2.12 connected to it,
then
ifconfig vnet97 192.0.2.20 up
should let you ping 192.0.2.12 via the vnet97 bridge.
4) Examples
-----------
These assume a vnet with a bridge 'vnet97' has been created.
Here's the full config for a vm on vnet 97, using ip addr 192.0.2.12:
(vm
(name dom12)
(memory '64')
(cpu '1')
(console '8502')
(image
(linux
(kernel /boot/vmlinuz-2.6-xenU)
(ip 192.0.2.12:192.0.2.4::::eth0:off)
(root /dev/sda1)
(args 'rw fastboot 4')
)
)
(device (vbd (uname phy:hda2) (dev sda1) (mode w)))
(device (vif (mac aa:00:00:11:00:12) (bridge vnet97)))
)
If you run another vm on the same vnet:
(vm
(name dom11)
(memory '64')
(cpu '1')
(console '8501')
(image
(linux
(kernel /boot/vmlinuz-2.6-xenU)
(ip 192.0.2.11:192.0.2.4::::eth0:off)
(root /dev/sda1)
(args 'rw fastboot 4')
)
)
(device (vbd (uname phy:hda3) (dev sda1) (mode w)))
(device (vif (mac aa:00:00:11:00:11) (bridge vnet97)))
)
the vms should be able to talk over the vnet. Check with ping.
If they are both on the same machine the connection will simply
be the vnet97 bridge, if they are on separate machines their
packets will be tunneled in udp (or etherip). They should be able to
see each other, but not the real network.

View File

@ -1,18 +0,0 @@
# -*- mode: Makefile; -*-
#============================================================================
XEN_ROOT = ../../..
include $(XEN_ROOT)/tools/Rules.mk
XEN_SCRIPT_DIR = $(DESTDIR)/etc/xen/scripts
.PHONY: all
all:
.PHONY: install
install:
$(INSTALL_DIR) $(XEN_SCRIPT_DIR)
$(INSTALL_PROG) network-vnet $(XEN_SCRIPT_DIR)
$(INSTALL_PROG) vnet-insert $(XEN_SCRIPT_DIR)
.PHONY: clean
clean:

View File

@ -1,10 +0,0 @@
#!/bin/sh
scriptdir=/etc/xen/scripts/
case ${1} in
start)
${scriptdir}/vnet-insert
;;
esac
${scriptdir}/network-bridge "$@"

View File

@ -1,28 +0,0 @@
#!/bin/bash
# Insert the vnet module if it can be found and
# it's not already there.
vnet_insert () {
local module="vnet_module"
local mod_dir=/lib/modules/$(uname -r)
local mod_obj=""
if lsmod | grep -q ${module} ; then
echo "VNET: ${module} loaded"
return
fi
local mods=$(find ${mod_dir} -name "${module}.*o")
if [[ ${mods} ]] ; then
for mod_obj in ${mods} ; do
break
done
fi
if [ -z "${mod_obj}" ] ; then
echo "VNET: ${module} not found"
exit 1
fi
echo "VNET: Loading ${module} from ${mod_obj}"
insmod ${mod_obj} "$@"
}
vnet_insert "$@"

View File

@ -1,2 +0,0 @@
# Vnet configuration for a vnet with id 97 and no security.
(vnet (id 97) (bridge vnet97) (vnetif vnif97) (security none))

View File

@ -1,2 +0,0 @@
# Vnet configuration for a vnet with id 98 and message authentication.
(vnet (id 98) (bridge vnet98) (vnetif vnif98) (security auth))

View File

@ -1,2 +0,0 @@
# Vnet configuration for a vnet with id 99 and message confidentiality.
(vnet (id 99) (bridge vnet99) (vnif vnetif99) (security conf))

View File

@ -1,86 +0,0 @@
ifndef VNET_ROOT
export VNET_ROOT = $(shell cd .. && pwd)
include $(VNET_ROOT)/Make.env
endif
include $(XEN_ROOT)/tools/Rules.mk
LIB_SRCS :=
LIB_SRCS += allocate.c
LIB_SRCS += enum.c
LIB_SRCS += file_stream.c
#LIB_SRCS += gzip_stream.c
LIB_SRCS += hash_table.c
LIB_SRCS += iostream.c
LIB_SRCS += lexis.c
LIB_SRCS += mem_stream.c
LIB_SRCS += string_stream.c
LIB_SRCS += sxpr.c
LIB_SRCS += sxpr_parser.c
LIB_SRCS += sys_net.c
LIB_SRCS += sys_string.c
LIB_SRCS += util.c
LIB_OBJS := $(LIB_SRCS:.c=.o)
PIC_OBJS := $(LIB_SRCS:.c=.opic)
CFLAGS += -Werror -fno-strict-aliasing $(call cc-option,$(CC),-fgnu89-inline,)
CFLAGS += -O3
#CFLAGS += -g
# Get gcc to generate the dependencies for us.
CFLAGS += -Wp,-MD,.$(@F).d
DEPS = .*.d
MAJOR := 3.0
MINOR := 0
LIB := libxutil.so
LIB += libxutil.so.$(MAJOR)
LIB += libxutil.so.$(MAJOR).$(MINOR)
LIB += libxutil.a
.PHONY: all
all: build
.PHONY: build
build: #check-for-zlib
$(MAKE) $(LIB)
gzip_stream.o: check-for-zlib
libxutil.so: libxutil.so.$(MAJOR)
ln -sf $^ $@
libxutil.so.$(MAJOR): libxutil.so.$(MAJOR).$(MINOR)
ln -sf $^ $@
libxutil.so.$(MAJOR).$(MINOR): $(PIC_OBJS)
$(CC) $(CFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxutil.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^
libxutil.a: $(LIB_OBJS)
$(AR) rc $@ $^
.PHONY: check-for-zlib
check-for-zlib:
@if [ ! -e /usr/include/zlib.h ]; then \
echo "***********************************************************"; \
echo "ERROR: install zlib header files (http://www.gzip.org/zlib)"; \
echo "***********************************************************"; \
false; \
fi
.PHONY: install
install: build
$(INSTALL_DIR) $(DESTDIR)$(LIBDIR)
$(INSTALL_PROG) libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)
$(INSTALL_DATA) libxutil.a $(DESTDIR)$(LIBDIR)
ln -sf libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libxutil.so.$(MAJOR)
ln -sf libxutil.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libxutil.so
.PHONY: clean
clean:
-@$(RM) *.a *.so* *.o *.opic *.rpm
-@$(RM) *~
-@$(RM) $(DEPS)
-include $(DEPS)

View File

@ -1,116 +0,0 @@
/*
* Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "allocate.h"
/** @file
* Support for allocating memory.
* Usable from user code or kernel code (with __KERNEL__ defined).
* In user code will use GC if USE_GC is defined.
*/
#ifdef __KERNEL__
/*----------------------------------------------------------------------------*/
# include <linux/config.h>
# include <linux/slab.h>
# include <linux/string.h>
# include <linux/types.h>
# define DEFAULT_TYPE 0
# define MALLOC(n, type) kmalloc(n, type)
# define FREE(ptr) kfree(ptr)
/*----------------------------------------------------------------------------*/
#else /* ! __KERNEL__ */
# include <stdlib.h>
# include <string.h>
# define DEFAULT_TYPE 0
#ifdef USE_GC
# include "gc.h"
# define MALLOC(n, typ) GC_malloc(n)
# define FREE(ptr) (ptr=NULL)
//typedef void *GC_PTR;
//GC_PTR (*GC_oom_fn)(size_t n);
#else
# define MALLOC(n, type) malloc(n)
# define FREE(ptr) free(ptr)
#endif
/*----------------------------------------------------------------------------*/
#endif
/** Function to call when memory cannot be allocated. */
AllocateFailedFn *allocate_failed_fn = NULL;
/** Allocate memory and zero it.
* The type is only relevant when calling from kernel code,
* from user code it is ignored.
* In kernel code the values accepted by kmalloc can be used:
* GFP_USER, GFP_ATOMIC, GFP_KERNEL.
*
* @param size number of bytes to allocate
* @param type memory type to allocate (kernel only)
* @return pointer to the allocated memory or zero
* if malloc failed
*/
void *allocate_type(int size, int type){
void *p = MALLOC(size, type);
if(p){
memzero(p, size);
} else if(allocate_failed_fn){
allocate_failed_fn(size, type);
}
return p;
}
/** Allocate memory and zero it.
*
* @param size number of bytes to allocate
* @return pointer to the allocated memory or zero
* if malloc failed
*/
void *allocate(int size){
return allocate_type(size, DEFAULT_TYPE);
}
/** Free memory allocated by allocate().
* No-op if 'p' is null.
*
* @param p memory to free
*/
void deallocate(void *p){
if(p){
FREE(p);
}
}
/** Set bytes to zero.
* No-op if 'p' is null.
*
* @param p memory to zero
* @param size number of bytes to zero
*/
void memzero(void *p, int size){
if(p){
memset(p, 0, (size_t)size);
}
}

View File

@ -1,45 +0,0 @@
/*
* Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _XUTIL_ALLOCATE_H_
#define _XUTIL_ALLOCATE_H_
/** Allocate memory for a given type, and cast. */
#define ALLOCATE(ctype) (ctype *)allocate(sizeof(ctype))
/** Allocate memory for a given type, and cast. */
#define ALLOCATE_TYPE(ctype, type) (ctype *)allocate(sizeof(ctype))
extern void *allocate_type(int size, int type);
extern void *allocate(int size);
extern void deallocate(void *);
extern void memzero(void *p, int size);
typedef void AllocateFailedFn(int size, int type);
extern AllocateFailedFn *allocate_failed_fn;
#endif /* _XUTIL_ALLOCATE_H_ */

View File

@ -1,72 +0,0 @@
/*
* Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _XUTIL_DEBUG_H_
#define _XUTIL_DEBUG_H_
#ifndef MODULE_NAME
#define MODULE_NAME ""
#endif
#ifdef __KERNEL__
#include <linux/config.h>
#include <linux/kernel.h>
#ifdef DEBUG
#define dprintf(fmt, args...) printk(KERN_DEBUG "[DBG] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
#define iprintf(fmt, args...) printk(KERN_INFO "[INF] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
#define eprintf(fmt, args...) printk(KERN_ERR "[ERR] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
#else
#define dprintf(fmt, args...) do {} while(0)
#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME fmt, ##args)
#define iprintf(fmt, args...) printk(KERN_INFO "[INF] " MODULE_NAME fmt, ##args)
#define eprintf(fmt, args...) printk(KERN_ERR "[ERR] " MODULE_NAME fmt, ##args)
#endif
#else
#include <stdio.h>
#ifdef DEBUG
#define dprintf(fmt, args...) fprintf(stdout, "%d [DBG] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args)
#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args)
#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args)
#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args)
#else
#define dprintf(fmt, args...) do {} while(0)
#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME fmt, getpid(), ##args)
#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME fmt, getpid(), ##args)
#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME fmt, getpid(), ##args)
#endif
#endif
/** Print format for an IP address.
* See NIPQUAD(), HIPQUAD()
*/
#define IPFMT "%u.%u.%u.%u"
#endif /* ! _XUTIL_DEBUG_H_ */

View File

@ -1,61 +0,0 @@
/*
* Copyright (C) 2002, 2004 Mike Wray <mike.wray@hp.com>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version. This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef __KERNEL__
#include <linux/errno.h>
#else
#include <errno.h>
#endif
#include "sys_string.h"
#include "enum.h"
/** Map an enum name to its value using a table.
*
* @param name enum name
* @param defs enum definitions
* @return enum value or -1 if not known
*/
int enum_name_to_val(char *name, EnumDef *defs){
int val = -1;
for(; defs->name; defs++){
if(!strcmp(defs->name, name)){
val = defs->val;
break;
}
}
return val;
}
/** Map an enum value to its name using a table.
*
* @param val enum value
* @param defs enum definitions
* @param defs_n number of definitions
* @return enum name or NULL if not known
*/
char *enum_val_to_name(int val, EnumDef *defs){
char *name = NULL;
for(; defs->name; defs++){
if(val == defs->val){
name = defs->name;
break;
}
}
return name;
}

View File

@ -1,30 +0,0 @@
/*
* Copyright (C) 2002, 2004 Mike Wray <mike.wray@hp.com>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version. This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _XUTIL_ENUM_H_
#define _XUTIL_ENUM_H_
/** Mapping of an enum value to a name. */
typedef struct EnumDef {
int val;
char *name;
} EnumDef;
extern int enum_name_to_val(char *name, EnumDef *defs);
extern char *enum_val_to_name(int val, EnumDef *defs);
#endif /* _XUTIL_ENUM_H_ */

View File

@ -1,184 +0,0 @@
/*
* Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/** @file
* An IOStream implementation using fds.
*/
#ifndef __KERNEL__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "allocate.h"
#include "fd_stream.h"
#define MODULE_NAME "fd_stream"
#define DEBUG 1
//#undef DEBUG
#include "debug.h"
static int fd_read(IOStream *s, void *buf, size_t n);
static int fd_write(IOStream *s, const void *buf, size_t n);
static int fd_error(IOStream *s);
static int fd_close(IOStream *s);
static void fd_free(IOStream *s);
static int fd_flush(IOStream *s);
/** Methods used by a fd IOStream. */
static const IOMethods fd_methods = {
read: fd_read,
write: fd_write,
error: fd_error,
close: fd_close,
free: fd_free,
flush: fd_flush,
};
/** Get the fd data.
*
* @param io fd stream
* @return data
*/
static inline FDData * fd_data(IOStream *io){
return (FDData *)io->data;
}
/** Test if a stream is a fd stream.
*
* @param io stream
* @return 0 if a fd stream, -EINVAL if not
*/
int fd_stream_check(IOStream *io){
return (io && io->methods == &fd_methods ? 0 : -EINVAL);
}
/** Get the data for a fd stream.
*
* @param io stream
* @param data return value for the data
* @return 0 if a fd stream, -EINVAL if not
*/
int fd_stream_data(IOStream *io, FDData **data){
int err = fd_stream_check(io);
if(err){
*data = NULL;
} else {
*data = fd_data(io);
}
return err;
}
/** Write to the underlying fd.
*
* @param stream input
* @param buf where to put input
* @param n number of bytes to write
* @return number of bytes written
*/
static int fd_write(IOStream *s, const void *buf, size_t n){
FDData *data = fd_data(s);
int k;
k = write(data->fd, buf, n);
return k;
}
/** Read from the underlying stream;
*
* @param stream input
* @param buf where to put input
* @param n number of bytes to read
* @return number of bytes read
*/
static int fd_read(IOStream *s, void *buf, size_t n){
FDData *data = fd_data(s);
int k;
k = read(data->fd, buf, n);
//printf("> fd_read> buf=%p n=%d --> k=%d\n", buf, n, k);
return k;
}
/** Flush the fd (no-op).
*
* @param s fd stream
* @return 0 on success, error code otherwise
*/
static int fd_flush(IOStream *s){
return 0;
}
/** Check if a fd stream has an error (no-op).
*
* @param s fd stream
* @return 1 if has an error, 0 otherwise
*/
static int fd_error(IOStream *s){
return 0;
}
/** Close a fd stream.
*
* @param s fd stream to close
* @return result of the close
*/
static int fd_close(IOStream *s){
FDData *data = fd_data(s);
return close(data->fd);
}
/** Free a fd stream.
*
* @param s fd stream
*/
static void fd_free(IOStream *s){
FDData *data = fd_data(s);
deallocate(data);
}
/** Create an IOStream for a fd.
*
* @param fd fd to wtap
* @return new IOStream using fd for i/o
*/
IOStream *fd_stream_new(int fd){
int err = -ENOMEM;
IOStream *io = NULL;
FDData *data = NULL;
io = ALLOCATE(IOStream);
if(!io) goto exit;
io->methods = &fd_methods;
data = ALLOCATE(FDData);
if(!data) goto exit;
io->data = data;
data->fd = fd;
err = 0;
exit:
if(err){
if(io){
if(data) deallocate(data);
deallocate(io);
io = NULL;
}
}
return io;
}
#endif

View File

@ -1,36 +0,0 @@
/*
* Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _XMC_FD_STREAM_H_
#define _XMC_FD_STREAM_H_
#ifndef __KERNEL__
#include "iostream.h"
/** Data associated with a fd stream. */
typedef struct FDData {
/** The socket file descriptor. */
int fd;
} FDData;
extern IOStream *fd_stream_new(int fd);
extern int fd_stream_data(IOStream *io, FDData **data);
extern int fd_stream_check(IOStream *io);
#endif
#endif /* !_XMC_FD_STREAM_H_ */

View File

@ -1,234 +0,0 @@
/*
* Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/** @file
* An IOStream implementation using FILE*.
*/
#ifndef __KERNEL__
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "allocate.h"
#include "file_stream.h"
static int file_read(IOStream *s, void *buf, size_t n);
static int file_write(IOStream *s, const void *buf, size_t n);
static int file_error(IOStream *s);
static int file_close(IOStream *s);
static void file_free(IOStream *s);
static int file_flush(IOStream *s);
/** Methods used by a FILE* IOStream. */
static const IOMethods file_methods = {
read: file_read,
write: file_write,
error: file_error,
close: file_close,
free: file_free,
flush: file_flush,
};
/** IOStream for stdin. */
static IOStream _iostdin = {
methods: &file_methods,
data: (void*)1,
nofree: 1,
};
/** IOStream for stdout. */
static IOStream _iostdout = {
methods: &file_methods,
data: (void*)2,
nofree: 1,
};
/** IOStream for stderr. */
static IOStream _iostderr = {
methods: &file_methods,
data: (void*)3,
nofree: 1,
};
/** IOStream for stdin. */
IOStream *iostdin = &_iostdin;
/** IOStream for stdout. */
IOStream *iostdout = &_iostdout;
/** IOStream for stderr. */
IOStream *iostderr = &_iostderr;
/* Get the underlying FILE*.
*
* @param s file stream
* @return the stream s wraps
*/
static inline FILE *get_file(IOStream *s){
FILE *data = NULL;
switch((long)s->data){
case 1:
data = stdin;
break;
case 2:
data = stdout;
break;
case 3:
data = stderr;
break;
default:
data = (FILE*)s->data;
break;
}
return data;
}
/** Control buffering on the underlying stream, like setvbuf().
*
* @param io file stream
* @param buf buffer
* @param mode buffering mode (see man setvbuf())
* @param size buffer size
* @return 0 on success, non-zero otherwise
*/
int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size){
return setvbuf(get_file(io), buf, mode, size);
}
/** Write to the underlying stream using fwrite();
*
* @param stream input
* @param buf where to put input
* @param n number of bytes to write
* @return number of bytes written
*/
static int file_write(IOStream *s, const void *buf, size_t n){
int cnt = 0;
unsigned char *ptr = (unsigned char*)buf;
while (n) {
if ((cnt = fwrite((const void *)(ptr), sizeof(unsigned char), n, get_file(s))) < 0) {
if (errno == EINTR)
continue;
else
return -1;
}
n -= cnt;
ptr += cnt;
}
return n;
}
/** Read from the underlying stream using fread();
*
* @param stream input
* @param buf where to put input
* @param n number of bytes to read
* @return number of bytes read
*/
static int file_read(IOStream *s, void *buf, size_t n){
return fread(buf, 1, n, get_file(s));
}
/** Fush the underlying stream using fflush().
*
* @param s file stream
* @return 0 on success, error code otherwise
*/
static int file_flush(IOStream *s){
return fflush(get_file(s));
}
/** Check if a stream has an error.
*
* @param s file stream
* @return 1 if has an error, 0 otherwise
*/
static int file_error(IOStream *s){
return ferror(get_file(s));
}
/** Close a file stream.
*
* @param s file stream to close
* @return result of the close
*/
static int file_close(IOStream *s){
int result = 0;
result = fclose(get_file(s));
return result;
}
/** Free a file stream.
*
* @param s file stream
*/
static void file_free(IOStream *s){
// Nothing extra to do - close did it all.
}
/** Create an IOStream for a stream.
*
* @param f stream to wrap
* @return new IOStream using f for i/o
*/
IOStream *file_stream_new(FILE *f){
IOStream *io = ALLOCATE(IOStream);
if(io){
io->methods = &file_methods;
io->data = (void*)f;
}
return io;
}
/** IOStream version of fopen().
*
* @param file name of the file to open
* @param flags giving the mode to open in (as for fopen())
* @return new stream for the open file, or 0 if failed
*/
IOStream *file_stream_fopen(const char *file, const char *flags){
IOStream *io = 0;
FILE *fin = fopen(file, flags);
if(fin){
io = file_stream_new(fin);
if(!io){
fclose(fin);
}
}
return io;
}
/** IOStream version of fdopen().
*
* @param fd file descriptor
* @param flags giving the mode to open in (as for fdopen())
* @return new stream for the open file, or 0 if failed. Always takes
* ownership of fd.
*/
IOStream *file_stream_fdopen(int fd, const char *flags){
IOStream *io = 0;
FILE *fin = fdopen(fd, flags);
if(fin){
io = file_stream_new(fin);
if(!io){
fclose(fin);
}
}
return io;
}
#endif

View File

@ -1,35 +0,0 @@
/*
* Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _XUTIL_FILE_STREAM_H_
#define _XUTIL_FILE_STREAM_H_
#ifndef __KERNEL__
#include "iostream.h"
#include <stdio.h>
extern IOStream *file_stream_new(FILE *f);
extern IOStream *file_stream_fopen(const char *file, const char *flags);
extern IOStream *file_stream_fdopen(int fd, const char *flags);
extern IOStream get_stream_stdout(void);
extern IOStream get_stream_stderr(void);
extern IOStream get_stream_stdin(void);
extern int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size);
#endif
#endif /* !_XUTIL_FILE_STREAM_H_ */

View File

@ -1,174 +0,0 @@
/*
* Copyright (C) 2003 Hewlett-Packard Company.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/** @file
* An IOStream implementation using zlib gzFile to provide
* compression and decompression.
*/
#ifndef __KERNEL__
#include <stdio.h>
#include <stdlib.h>
#include "zlib.h"
#include "allocate.h"
#include "gzip_stream.h"
static int gzip_read(IOStream *s, void *buf, size_t n);
static int gzip_write(IOStream *s, const void *buf, size_t n);
static int gzip_error(IOStream *s);
static int gzip_close(IOStream *s);
static void gzip_free(IOStream *s);
static int gzip_flush(IOStream *s);
/** Methods used by a gzFile* IOStream. */
static const IOMethods gzip_methods = {
read: gzip_read,
write: gzip_write,
error: gzip_error,
close: gzip_close,
free: gzip_free,
flush: gzip_flush,
};
/** Get the underlying gzFile*.
*
* @param s gzip stream
* @return the stream s wraps
*/
static inline gzFile get_gzfile(IOStream *s){
return (gzFile)s->data;
}
/** Write to the underlying stream.
*
* @param stream destination
* @param buf data
* @param n number of bytes to write
* @return number of bytes written
*/
static int gzip_write(IOStream *s, const void *buf, size_t n){
return gzwrite(get_gzfile(s), (void*)buf, n);
}
/** Read from the underlying stream.
*
* @param stream input
* @param buf where to put input
* @param n number of bytes to read
* @return number of bytes read
*/
static int gzip_read(IOStream *s, void *buf, size_t n){
return gzread(get_gzfile(s), buf, n);
}
/** Flush the underlying stream.
*
* @param s gzip stream
* @return 0 on success, error code otherwise
*/
static int gzip_flush(IOStream *s){
//return gzflush(get_gzfile(s), Z_NO_FLUSH);
return gzflush(get_gzfile(s), Z_SYNC_FLUSH);
//return gzflush(get_gzfile(s), Z_FULL_FLUSH);
}
/** Check if a stream has an error.
*
* @param s gzip stream
* @return 1 if has an error, 0 otherwise
*/
static int gzip_error(IOStream *s){
int err;
gzFile *gz = get_gzfile(s);
gzerror(gz, &err);
return (err == Z_ERRNO ? 1 /* ferror(gzfile(gz)) */ : err);
}
/** Close a gzip stream.
*
* @param s gzip stream to close
* @return result of the close
*/
static int gzip_close(IOStream *s){
int result = 0;
result = gzclose(get_gzfile(s));
return result;
}
/** Free a gzip stream.
*
* @param s gzip stream
*/
static void gzip_free(IOStream *s){
// Nothing to do - close did it all.
}
/** Create an IOStream for a gzip stream.
*
* @param f stream to wrap
* @return new IOStream using f for i/o
*/
IOStream *gzip_stream_new(gzFile *f){
IOStream *io = ALLOCATE(IOStream);
if(io){
io->methods = &gzip_methods;
io->data = (void*)f;
}
return io;
}
/** IOStream version of fopen().
*
* @param file name of the file to open
* @param flags giving the mode to open in (as for fopen())
* @return new stream for the open file, or NULL if failed
*/
IOStream *gzip_stream_fopen(const char *file, const char *flags){
IOStream *io = NULL;
gzFile *fgz;
fgz = gzopen(file, flags);
if(fgz){
io = gzip_stream_new(fgz);
if(!io){
gzclose(fgz);
}
}
return io;
}
/** IOStream version of fdopen().
*
* @param fd file descriptor
* @param flags giving the mode to open in (as for fdopen())
* @return new stream for the open file, or NULL if failed. Always takes
* ownership of fd.
*/
IOStream *gzip_stream_fdopen(int fd, const char *flags){
IOStream *io = NULL;
gzFile *fgz;
fgz = gzdopen(fd, flags);
if(fgz){
io = gzip_stream_new(fgz);
if(!io)
gzclose(fgz);
}
return io;
}
#endif

View File

@ -1,30 +0,0 @@
/*
* Copyright (C) 2003 Hewlett-Packard Company.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _XUTIL_GZIP_STREAM_H_
#define _XUTIL_GZIP_STREAM_H_
#ifndef __KERNEL__
#include "iostream.h"
#include "zlib.h"
extern IOStream *gzip_stream_new(gzFile *f);
extern IOStream *gzip_stream_fopen(const char *file, const char *flags);
extern IOStream *gzip_stream_fdopen(int fd, const char *flags);
#endif
#endif /* !_XUTIL_GZIP_STREAM_H_ */

View File

@ -1,658 +0,0 @@
/*
* Copyright (C) 2001 - 2005 Mike Wray <mike.wray@hp.com>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef __KERNEL__
# include <linux/config.h>
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/errno.h>
#else
# include <errno.h>
# include <stddef.h>
#endif
#include "allocate.h"
#include "hash_table.h"
/** @file
* Base support for hashtables.
*
* Hash codes are reduced modulo the number of buckets to index tables,
* so there is no need for hash functions to limit the range of hashcodes.
* In fact it is assumed that hashcodes do not change when the number of
* buckets in the table changes.
*/
/*============================================================================*/
/*
--------------------------------------------------------------------
lookup2.c, by Bob Jenkins, December 1996, Public Domain.
You can use this free for any purpose. It has no warranty.
--------------------------------------------------------------------
*/
#define hashsize(n) ((ub4)1<<(n))
#define hashmask(n) (hashsize(n)-1)
/*
--------------------------------------------------------------------
mix -- mix 3 32-bit values reversibly.
For every delta with one or two bit set, and the deltas of all three
high bits or all three low bits, whether the original value of a,b,c
is almost all zero or is uniformly distributed,
* If mix() is run forward or backward, at least 32 bits in a,b,c
have at least 1/4 probability of changing.
* If mix() is run forward, every bit of c will change between 1/3 and
2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.)
mix() was built out of 36 single-cycle latency instructions in a
structure that could supported 2x parallelism, like so:
a -= b;
a -= c; x = (c>>13);
b -= c; a ^= x;
b -= a; x = (a<<8);
c -= a; b ^= x;
c -= b; x = (b>>13);
...
Unfortunately, superscalar Pentiums and Sparcs can't take advantage
of that parallelism. They've also turned some of those single-cycle
latency instructions into multi-cycle latency instructions. Still,
this is the fastest good hash I could find. There were about 2^^68
to choose from. I only looked at a billion or so.
--------------------------------------------------------------------
*/
#define mix(a,b,c) \
{ \
a -= b; a -= c; a ^= (c>>13); \
b -= c; b -= a; b ^= (a<<8); \
c -= a; c -= b; c ^= (b>>13); \
a -= b; a -= c; a ^= (c>>12); \
b -= c; b -= a; b ^= (a<<16); \
c -= a; c -= b; c ^= (b>>5); \
a -= b; a -= c; a ^= (c>>3); \
b -= c; b -= a; b ^= (a<<10); \
c -= a; c -= b; c ^= (b>>15); \
}
/*
--------------------------------------------------------------------
hash() -- hash a variable-length key into a 32-bit value
k : the key (the unaligned variable-length array of bytes)
len : the length of the key, counting by bytes
level : can be any 4-byte value
Returns a 32-bit value. Every bit of the key affects every bit of
the return value. Every 1-bit and 2-bit delta achieves avalanche.
About 36+6len instructions.
The best hash table sizes are powers of 2. There is no need to do
mod a prime (mod is sooo slow!). If you need less than 32 bits,
use a bitmask. For example, if you need only 10 bits, do
h = (h & hashmask(10));
In which case, the hash table should have hashsize(10) elements.
If you are hashing n strings (ub1 **)k, do it like this:
for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this
code any way you wish, private, educational, or commercial. It's free.
See http://burlteburtle.net/bob/hash/evahash.html
Use for hash table lookup, or anything where one collision in 2^32 is
acceptable. Do NOT use for cryptographic purposes.
--------------------------------------------------------------------
*/
static inline ub4 _hash(const ub1 *k, ub4 length, ub4 initval)
//register ub1 *k; /* the key */
//register ub4 length; /* the length of the key */
//register ub4 initval; /* the previous hash, or an arbitrary value */
{
/*register*/ ub4 a,b,c,len;
/* Set up the internal state */
len = length;
a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
c = initval; /* the previous hash value */
/*---------------------------------------- handle most of the key */
while (len >= 12)
{
a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
mix(a,b,c);
k += 12; len -= 12;
}
/*------------------------------------- handle the last 11 bytes */
c += length;
switch(len) /* all the case statements fall through */
{
case 11: c+=((ub4)k[10]<<24);
case 10: c+=((ub4)k[9]<<16);
case 9 : c+=((ub4)k[8]<<8);
/* the first byte of c is reserved for the length */
case 8 : b+=((ub4)k[7]<<24);
case 7 : b+=((ub4)k[6]<<16);
case 6 : b+=((ub4)k[5]<<8);
case 5 : b+=k[4];
case 4 : a+=((ub4)k[3]<<24);
case 3 : a+=((ub4)k[2]<<16);
case 2 : a+=((ub4)k[1]<<8);
case 1 : a+=k[0];
/* case 0: nothing left to add */
}
mix(a,b,c);
/*-------------------------------------------- report the result */
return c;
}
ub4 hash(const ub1 *k, ub4 length, ub4 initval){
return _hash(k, length, initval);
}
/*============================================================================*/
/** Get the bucket for a hashcode in a hash table.
*
* @param table to get bucket from
* @param hashcode to get bucket for
* @return bucket
*/
inline HTBucket * get_bucket(HashTable *table, Hashcode hashcode){
return table->buckets + (hashcode % table->buckets_n);
}
/** Initialize a hash table.
*
* @param table to initialize
*/
static void HashTable_init(HashTable *table){
int i;
for(i = 0; i < table->buckets_n; i++){
HTBucket *bucket = get_bucket(table, i);
bucket->head = NULL;
bucket->count = 0;
}
table->entry_count = 0;
}
/** Allocate a new hashtable.
* If the number of buckets is not positive the default is used.
*
* @param buckets_n number of buckets
* @return new hashtable or null
*/
HashTable *HashTable_new(int buckets_n){
HashTable *z = ALLOCATE(HashTable);
if(!z) goto exit;
if(buckets_n <= 0){
buckets_n = HT_BUCKETS_N;
}
z->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket));
if(!z->buckets){
deallocate(z);
z = NULL;
goto exit;
}
z->buckets_n = buckets_n;
HashTable_init(z);
exit:
return z;
}
/** Free a hashtable.
* Any entries are removed and freed.
*
* @param h hashtable (ignored if null)
*/
void HashTable_free(HashTable *h){
if(h){
HashTable_clear(h);
deallocate(h->buckets);
deallocate(h);
}
}
/** Push an entry on the list in the bucket for a given hashcode.
*
* @param table to add entry to
* @param hashcode for the entry
* @param entry to add
*/
static inline void push_on_bucket(HashTable *table, Hashcode hashcode,
HTEntry *entry){
HTBucket *bucket;
HTEntry *old_head;
bucket = get_bucket(table, hashcode);
old_head = bucket->head;
bucket->count++;
bucket->head = entry;
entry->next = old_head;
}
/** Change the number of buckets in a hashtable.
* No-op if the number of buckets is not positive.
* Existing entries are reallocated to buckets based on their hashcodes.
* The table is unmodified if the number of buckets cannot be changed.
*
* @param table hashtable
* @param buckets_n new number of buckets
* @return 0 on success, error code otherwise
*/
int HashTable_set_buckets_n(HashTable *table, int buckets_n){
int err = 0;
HTBucket *old_buckets = table->buckets;
int old_buckets_n = table->buckets_n;
int i;
if(buckets_n <= 0){
err = -EINVAL;
goto exit;
}
table->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket));
if(!table->buckets){
err = -ENOMEM;
table->buckets = old_buckets;
goto exit;
}
table->buckets_n = buckets_n;
for(i=0; i < old_buckets_n; i++){
HTBucket *bucket = old_buckets + i;
HTEntry *entry, *next;
for(entry = bucket->head; entry; entry = next){
next = entry->next;
push_on_bucket(table, entry->hashcode, entry);
}
}
deallocate(old_buckets);
exit:
return err;
}
/** Adjust the number of buckets so the table is neither too full nor too empty.
* The table is unmodified if adjusting fails.
*
* @param table hash table
* @param buckets_min minimum number of buckets (use default if 0 or negative)
* @return 0 on success, error code otherwise
*/
int HashTable_adjust(HashTable *table, int buckets_min){
int buckets_n = 0;
int err = 0;
if(buckets_min <= 0) buckets_min = HT_BUCKETS_N;
if(table->entry_count >= table->buckets_n){
// The table is dense - expand it.
buckets_n = 2 * table->buckets_n;
} else if((table->buckets_n > buckets_min) &&
(4 * table->entry_count < table->buckets_n)){
// The table is more than minimum size and sparse - shrink it.
buckets_n = 2 * table->entry_count;
if(buckets_n < buckets_min) buckets_n = buckets_min;
}
if(buckets_n){
err = HashTable_set_buckets_n(table, buckets_n);
}
return err;
}
/** Allocate a new entry for a given value.
*
* @param value to put in the entry
* @return entry, or 0 on failure
*/
HTEntry * HTEntry_new(Hashcode hashcode, void *key, void *value){
HTEntry *z = ALLOCATE(HTEntry);
if(z){
z->hashcode = hashcode;
z->key = key;
z->value = value;
}
return z;
}
/** Free an entry.
*
* @param z entry to free
*/
inline void HTEntry_free(HTEntry *z){
if(z){
deallocate(z);
}
}
/** Free an entry in a hashtable.
* The table's entry_free_fn is used is defined, otherwise
* the HTEntry itself is freed.
*
* @param table hashtable
* @param entry to free
*/
inline void HashTable_free_entry(HashTable *table, HTEntry *entry){
if(!entry) return;
if(table && table->entry_free_fn){
table->entry_free_fn(table, entry);
} else {
HTEntry_free(entry);
}
}
/** Get the first entry satisfying a test from the bucket for the
* given hashcode.
*
* @param table to look in
* @param hashcode indicates the bucket
* @param test_fn test to apply to elements
* @param arg first argument to calls to test_fn
* @return entry found, or 0
*/
inline HTEntry * HashTable_find_entry(HashTable *table, Hashcode hashcode,
TableTestFn *test_fn, TableArg arg){
HTBucket *bucket;
HTEntry *entry = NULL;
HTEntry *next;
bucket = get_bucket(table, hashcode);
for(entry = bucket->head; entry; entry = next){
next = entry->next;
if(test_fn(arg, table, entry)){
break;
}
}
return entry;
}
/** Test hashtable keys for equality.
* Uses the table's key_equal_fn if defined, otherwise pointer equality.
*
* @param key1 key to compare
* @param key2 key to compare
* @return 1 if equal, 0 otherwise
*/
inline int HashTable_key_equal(HashTable *table, void *key1, void *key2){
if(table->key_size){
return memcmp(key1, key2, table->key_size) == 0;
}
return (table->key_equal_fn ? table->key_equal_fn(key1, key2) : key1 == key2);
}
/** Compute the hashcode of a hashtable key.
* The table's key_hash_fn is used if defined, otherwise the address of
* the key is hashed.
*
* @param table hashtable
* @param key to hash
* @return hashcode
*/
inline Hashcode HashTable_key_hash(HashTable *table, void *key){
if(table->key_size){
return _hash(key, table->key_size, 0);
}
return (table->key_hash_fn
? table->key_hash_fn(key)
: hash_hvoid(0, &key, sizeof(key)));
}
/** Test if an entry has a given key.
*
* @param arg containing key to test for
* @param table the entry is in
* @param entry to test
* @return 1 if the entry has the key, 0 otherwise
*/
static inline int has_key(TableArg arg, HashTable *table, HTEntry *entry){
return HashTable_key_equal(table, arg.ptr, entry->key);
}
/** Get an entry with a given key.
*
* @param table to search
* @param key to look for
* @return entry if found, null otherwise
*/
inline HTEntry * HashTable_get_entry(HashTable *table, void *key){
Hashcode hashcode;
HTBucket *bucket;
HTEntry *entry = NULL;
HTEntry *next;
hashcode = HashTable_key_hash(table, key);
bucket = get_bucket(table, hashcode);
for(entry = bucket->head; entry; entry = next){
next = entry->next;
if(HashTable_key_equal(table, key, entry->key)){
break;
}
}
return entry;
}
/** Get the value of an entry with a given key.
*
* @param table to search
* @param key to look for
* @return value if an entry was found, null otherwise
*/
inline void * HashTable_get(HashTable *table, void *key){
HTEntry *entry = HashTable_get_entry(table, key);
return (entry ? entry->value : 0);
}
/** Print the buckets in a table.
*
* @param table to print
*/
void show_buckets(HashTable *table, IOStream *io){
int i,j ;
IOStream_print(io, "entry_count=%d buckets_n=%d\n", table->entry_count, table->buckets_n);
for(i=0; i < table->buckets_n; i++){
if(0 || table->buckets[i].count>0){
IOStream_print(io, "bucket %3d %3d %10p ", i,
table->buckets[i].count,
table->buckets[i].head);
for(j = table->buckets[i].count; j>0; j--){
IOStream_print(io, "+");
}
IOStream_print(io, "\n");
}
}
HashTable_print(table, io);
}
/** Print an entry in a table.
*
* @param entry to print
* @param arg a pointer to an IOStream to print to
* @return 0
*/
static int print_entry(TableArg arg, HashTable *table, HTEntry *entry){
IOStream *io = (IOStream*)arg.ptr;
IOStream_print(io, " b=%4lx h=%08lx |-> e=%8p k=%8p v=%8p\n",
entry->hashcode % table->buckets_n,
entry->hashcode,
entry, entry->key, entry->value);
return 0;
}
/** Print a hash table.
*
* @param table to print
*/
void HashTable_print(HashTable *table, IOStream *io){
IOStream_print(io, "{\n");
HashTable_map(table, print_entry, (TableArg){ ptr: io });
IOStream_print(io, "}\n");
}
/*==========================================================================*/
/** Add an entry to the bucket for the
* given hashcode.
*
* @param table to insert in
* @param hashcode indicates the bucket
* @param key to add an entry for
* @param value to add an entry for
* @return entry on success, 0 on failure
*/
inline HTEntry * HashTable_add_entry(HashTable *table, Hashcode hashcode, void *key, void *value){
HTEntry *entry = HTEntry_new(hashcode, key, value);
if(entry){
push_on_bucket(table, hashcode, entry);
table->entry_count++;
}
return entry;
}
/** Move the front entry for a bucket to the correct point in the bucket order as
* defined by the order function. If this is called every time a new entry is added
* the bucket will be maintained in sorted order.
*
* @param table to modify
* @param hashcode indicates the bucket
* @param order entry comparison function
* @return 0 if an entry was moved, 1 if not
*/
int HashTable_order_bucket(HashTable *table, Hashcode hashcode, TableOrderFn *order){
HTEntry *new_entry = NULL, *prev = NULL, *entry = NULL;
HTBucket *bucket;
int err = 1;
bucket = get_bucket(table, hashcode);
new_entry = bucket->head;
if(!new_entry || !new_entry->next) goto exit;
for(entry = new_entry->next; entry; prev = entry, entry = entry->next){
if(order(new_entry, entry) <= 0) break;
}
if(prev){
err = 0;
bucket->head = new_entry->next;
new_entry->next = entry;
prev->next = new_entry;
}
exit:
return err;
}
/** Add an entry to a hashtable.
* The entry is added to the bucket for its key's hashcode.
*
* @param table to insert in
* @param key to add an entry for
* @param value to add an entry for
* @return entry on success, 0 on failure
*/
inline HTEntry * HashTable_add(HashTable *table, void *key, void *value){
return HashTable_add_entry(table, HashTable_key_hash(table, key), key, value);
}
/** Remove entries satisfying a test from the bucket for the
* given hashcode.
*
* @param table to remove from
* @param hashcode indicates the bucket
* @param test_fn test to apply to elements
* @param arg first argument to calls to test_fn
* @return number of entries removed
*/
inline int HashTable_remove_entry(HashTable *table, Hashcode hashcode,
TableTestFn *test_fn, TableArg arg){
HTBucket *bucket;
HTEntry *entry, *prev = NULL, *next;
int removed_count = 0;
bucket = get_bucket(table, hashcode);
for(entry = bucket->head; entry; entry = next){
next = entry->next;
if(test_fn(arg, table, entry)){
if(prev){
prev->next = next;
} else {
bucket->head = next;
}
bucket->count--;
table->entry_count--;
removed_count++;
HashTable_free_entry(table, entry);
entry = NULL;
}
prev = entry;
}
return removed_count;
}
/** Remove entries with a given key.
*
* @param table to remove from
* @param key of entries to remove
* @return number of entries removed
*/
inline int HashTable_remove(HashTable *table, void *key){
Hashcode hashcode;
HTBucket *bucket;
HTEntry *entry, *prev = NULL, *next;
int removed_count = 0;
hashcode = HashTable_key_hash(table, key);
bucket = get_bucket(table, hashcode);
for(entry = bucket->head; entry; entry = next){
next = entry->next;
if(HashTable_key_equal(table, key, entry->key)){
if(prev){
prev->next = next;
} else {
bucket->head = next;
}
bucket->count--;
table->entry_count--;
removed_count++;
HashTable_free_entry(table, entry);
entry = NULL;
}
prev = entry;
}
return removed_count;
}
/** Remove (and free) all the entries in a bucket.
*
* @param bucket to clear
*/
static inline void bucket_clear(HashTable *table, HTBucket *bucket){
HTEntry *entry, *next;
for(entry = bucket->head; entry; entry = next){
next = entry->next;
HashTable_free_entry(table, entry);
}
bucket->head = NULL;
table->entry_count -= bucket->count;
bucket->count = 0;
}
/** Remove (and free) all the entries in a table.
*
* @param table to clear
*/
void HashTable_clear(HashTable *table){
int i, n = table->buckets_n;
for(i = 0; i < n; i++){
bucket_clear(table, table->buckets + i);
}
}

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