mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 20:02:29 +01:00
Merge branch 'master' of ssh://git.cloud.com/var/lib/git/cloudstack-oss
This commit is contained in:
commit
b42458fa0d
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -13,5 +13,6 @@ public interface DataCenter extends Grouping {
|
||||
String getDns1();
|
||||
String getDns2();
|
||||
String getGuestNetworkCidr();
|
||||
String getName();
|
||||
Long getDomainId();
|
||||
}
|
||||
|
||||
@ -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>();
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,9 +92,9 @@ public class Network {
|
||||
Public,
|
||||
Guest,
|
||||
Storage,
|
||||
Management,
|
||||
Control,
|
||||
Vpn,
|
||||
Management
|
||||
Vpn
|
||||
};
|
||||
|
||||
public enum IsolationType {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -31,6 +31,10 @@ public interface Nic extends Resource {
|
||||
|
||||
String getMacAddress();
|
||||
|
||||
String getNetmask();
|
||||
|
||||
String getGateway();
|
||||
|
||||
/**
|
||||
* @return network profile id that this
|
||||
*/
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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">
|
||||
|
||||
35
cloud.spec
35
cloud.spec
@ -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}*
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,7 +238,6 @@ public class VolumeVO implements Volume {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isRecreatable() {
|
||||
return recreatable;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
3
debian/cloud-vnet.install
vendored
3
debian/cloud-vnet.install
vendored
@ -1,3 +0,0 @@
|
||||
/usr/sbin/cloud-vn
|
||||
/usr/sbin/cloud-vnetd
|
||||
/etc/init.d/cloud-vnetd
|
||||
13
debian/cloud-vnet.postinst
vendored
13
debian/cloud-vnet.postinst
vendored
@ -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
12
debian/control
vendored
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -231,4 +231,4 @@ case $protocol in
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
exit 0
|
||||
@ -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>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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;
|
||||
|
||||
114
server/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java
Normal file
114
server/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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";
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
103
server/src/com/cloud/api/commands/StartSystemVm2Cmd.java
Normal file
103
server/src/com/cloud/api/commands/StartSystemVm2Cmd.java
Normal 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);
|
||||
}
|
||||
}
|
||||
98
server/src/com/cloud/api/commands/StopSystemVm2Cmd.java
Normal file
98
server/src/com/cloud/api/commands/StopSystemVm2Cmd.java
Normal 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());
|
||||
}
|
||||
}
|
||||
@ -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")
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
37
server/src/com/cloud/hypervisor/KVMGuru.java
Normal file
37
server/src/com/cloud/hypervisor/KVMGuru.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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;
|
||||
|
||||
277
ui/jsp/pod.jsp
277
ui/jsp/pod.jsp
@ -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 …</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 …</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 …</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 …</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 …
|
||||
</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">
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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.
|
||||
@ -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>
|
||||
@ -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
|
||||
@ -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.'
|
||||
@ -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)
|
||||
|
||||
@ -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.
|
||||
@ -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.
|
||||
@ -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.
|
||||
|
||||
|
||||
@ -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:
|
||||
@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
scriptdir=/etc/xen/scripts/
|
||||
|
||||
case ${1} in
|
||||
start)
|
||||
${scriptdir}/vnet-insert
|
||||
;;
|
||||
esac
|
||||
|
||||
${scriptdir}/network-bridge "$@"
|
||||
@ -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 "$@"
|
||||
@ -1,2 +0,0 @@
|
||||
# Vnet configuration for a vnet with id 97 and no security.
|
||||
(vnet (id 97) (bridge vnet97) (vnetif vnif97) (security none))
|
||||
@ -1,2 +0,0 @@
|
||||
# Vnet configuration for a vnet with id 98 and message authentication.
|
||||
(vnet (id 98) (bridge vnet98) (vnetif vnif98) (security auth))
|
||||
@ -1,2 +0,0 @@
|
||||
# Vnet configuration for a vnet with id 99 and message confidentiality.
|
||||
(vnet (id 99) (bridge vnet99) (vnif vnetif99) (security conf))
|
||||
@ -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)
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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_ */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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_ */
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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_ */
|
||||
@ -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
|
||||
@ -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_ */
|
||||
@ -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
|
||||
@ -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_ */
|
||||
@ -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
|
||||
@ -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_ */
|
||||
@ -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
Loading…
x
Reference in New Issue
Block a user