// TODO: reduce duplication with above public GetBladeStatusResult getVMStatus(string nodeIp, string requestorIp) { using (lockableVMSpec blade = getVMByIP(nodeIp, bladeLockType.lockOwnership, bladeLockType.lockNone)) { switch (blade.spec.state) { case bladeStatus.unused: return(GetBladeStatusResult.unused); case bladeStatus.releaseRequested: return(GetBladeStatusResult.releasePending); case bladeStatus.inUse: if (blade.spec.currentOwner == requestorIp) { return(GetBladeStatusResult.yours); } return(GetBladeStatusResult.notYours); case bladeStatus.inUseByDirector: return(GetBladeStatusResult.notYours); default: throw new ArgumentOutOfRangeException(); } } }
public void testDBObjectCanDoDelayedDisposalWhileUpgraded() { using (hostDB db = new hostDB()) { bladeDirectorWCF.vmSpec toDB = new bladeDirectorWCF.vmSpec(db.conn, "1.1.1.3", bladeLockType.lockAll, bladeLockType.lockAll); db.addNode(toDB); using (lockableVMSpec refA = db.getVMByIP("1.1.1.3", bladeLockType.lockNone, bladeLockType.lockNone)) { using (new tempLockElevation(refA, bladeLockType.lockVirtualHW, bladeLockType.lockOwnership)) { Assert.AreEqual(bladeLockType.lockIPAddresses | bladeLockType.lockVirtualHW | bladeLockType.lockOwnership, refA.spec.permittedAccessRead); Assert.AreEqual(bladeLockType.lockOwnership, refA.spec.permittedAccessWrite); refA.Dispose(); refA.inhibitNextDisposal(); } } // As a final check, make sure we can re-acquire the locks. This will make sure we didn't 'leak' any. using (lockableVMSpec refA = db.getVMByIP("1.1.1.3", bladeLockType.lockAll, bladeLockType.lockAll)) { // .. } } }
public void testDBObjectIsUpdatedFromDBOnPermissionUpgrade() { using (hostDB db = new hostDB()) { bladeDirectorWCF.vmSpec toDB = new bladeDirectorWCF.vmSpec(db.conn, "1.1.1.2", bladeLockType.lockAll, bladeLockType.lockAll); db.addNode(toDB); using (lockableVMSpec refB = db.getVMByIP("1.1.1.2", bladeLockType.lockNone, bladeLockType.lockNone)) { Thread innerThread = new Thread(() => { using (lockableVMSpec refA = db.getVMByIP("1.1.1.2", bladeLockType.lockNone, bladeLockType.lockVirtualHW | bladeLockType.lockOwnership)) { refA.spec.friendlyName = "test data"; refA.spec.currentOwner = "Dave_Lister"; } }); innerThread.Start(); innerThread.Join(); refB.upgradeLocks(bladeLockType.lockVirtualHW | bladeLockType.lockOwnership, bladeLockType.lockNone); Assert.AreEqual("test data", refB.spec.friendlyName); Assert.AreEqual("Dave_Lister", refB.spec.currentOwner); } } }
public void testDBObjectThrowsAfterDowngradeToReadOnlyAccess() { using (hostDB db = new hostDB()) { bladeDirectorWCF.vmSpec toDB = new bladeDirectorWCF.vmSpec(db.conn, "1.1.1.4", bladeLockType.lockAll, bladeLockType.lockAll); db.addNode(toDB); // Lock with write access to a field, and then downgrade to read-only access. Then, try to write to the field we // originally locked, and expect an exception to be thrown. using (lockableVMSpec refA = db.getVMByIP("1.1.1.4", bladeLockType.lockNone, bladeLockType.lockVirtualHW | bladeLockType.lockOwnership)) { refA.downgradeLocks( bladeLockType.lockNone | bladeLockType.lockNone, bladeLockType.lockVirtualHW | bladeLockType.lockOwnership); // We have released the write lock, so we should be holding the read lock only. Assert.AreEqual(bladeLockType.lockIPAddresses | bladeLockType.lockOwnership | bladeLockType.lockVirtualHW, refA.spec.permittedAccessRead); Assert.AreEqual(bladeLockType.lockNone, refA.spec.permittedAccessWrite); // We should not be permitted to write fields failIfNoThrow(() => { refA.spec.friendlyName = "test data"; }); failIfNoThrow(() => { refA.spec.currentOwner = "Dave_Lister"; }); // but should be permitted to read them. failIfThrow(() => { Debug.WriteLine(refA.spec.currentOwner); }); failIfThrow(() => { Debug.WriteLine(refA.spec.friendlyName); }); } } }
public override hypervisor makeHypervisorForVM(lockableVMSpec vm, lockableBladeSpec parentBladeSpec) { hypSpec_vmware spec = new hypSpec_vmware(vm.spec.friendlyName, parentBladeSpec.spec.bladeIP, Settings.Default.esxiUsername, Settings.Default.esxiPassword, Settings.Default.vmUsername, Settings.Default.vmPassword, null, null, vm.spec.kernelDebugPort, vm.spec.kernelDebugKey, vm.spec.VMIP); return(new hypervisor_vmware(spec, clientExecutionMethod.smbWithWMI)); }
public void testDBObjectFlushesToDBOnLockDowngrade() { using (hostDB db = new hostDB()) { bladeDirectorWCF.vmSpec toDB = new bladeDirectorWCF.vmSpec(db.conn, "1.1.1.7", bladeLockType.lockAll, bladeLockType.lockAll); db.addNode(toDB); ManualResetEvent canCheckRefB = new ManualResetEvent(false); ManualResetEvent testEnded = new ManualResetEvent(false); Thread innerThread = new Thread(() => { using (lockableVMSpec refA = db.getVMByIP("1.1.1.7", bladeLockType.lockNone, bladeLockType.lockVirtualHW | bladeLockType.lockOwnership)) { // Set some data, and then downgrade to a read-only lock. // The data should be flushed to the DB at that point, so we set a ManualResetEvent and the main thread // will check that the data has indeed been flushed, by reading from the DB. refA.spec.friendlyName = "test data"; refA.spec.currentOwner = "Dave_Lister"; refA.downgradeLocks( bladeLockType.lockNone | bladeLockType.lockNone, bladeLockType.lockVirtualHW | bladeLockType.lockOwnership); Assert.AreEqual(bladeLockType.lockIPAddresses | bladeLockType.lockOwnership | bladeLockType.lockVirtualHW, refA.spec.permittedAccessRead); Assert.AreEqual(bladeLockType.lockNone, refA.spec.permittedAccessWrite); canCheckRefB.Set(); testEnded.WaitOne(); } }); innerThread.Start(); canCheckRefB.WaitOne(); try { using (lockableVMSpec refB = db.getVMByIP("1.1.1.7", bladeLockType.lockVirtualHW | bladeLockType.lockOwnership, bladeLockType.lockNone)) { Assert.AreEqual("Dave_Lister", refB.spec.currentOwner); Assert.AreEqual("test data", refB.spec.friendlyName); } } finally { testEnded.Set(); innerThread.Join(); } } }
public lockableVMSpec createChildVM(SQLiteConnection conn, hostDB db, VMHardwareSpec reqhw, VMSoftwareSpec reqsw, string newOwner) { if ((permittedAccessRead & bladeLockType.lockVMCreation) == bladeLockType.lockNone) { throw new Exception("lockVMCreation is needed when calling .createChildVM"); } vmserverTotals totals = db.getVMServerTotals(this); int indexOnServer = totals.VMs + 1; string newBladeName = xdlClusterNaming.makeVMName(bladeIP, indexOnServer); // If we set the debugger port automatically, make sure we reset it to zero before we return. bool needToResetReqSWDebugPort = false; if (reqsw.debuggerPort == 0) { reqsw.debuggerPort = xdlClusterNaming.makeVMKernelDebugPort(bladeIP, indexOnServer); needToResetReqSWDebugPort = true; } vmSpec newVM = new vmSpec(conn, newBladeName, reqsw, bladeLockType.lockAll, bladeLockType.lockAll); newVM.parentBladeIP = bladeIP; newVM.state = bladeStatus.inUseByDirector; newVM.currentOwner = "vmserver"; // We own the blade until we are done setting it up newVM.nextOwner = newOwner; newVM.parentBladeID = bladeID.Value; newVM.memoryMB = reqhw.memoryMB; newVM.cpuCount = reqhw.cpuCount; newVM.indexOnServer = indexOnServer; newVM.VMIP = xdlClusterNaming.makeVMIP(bladeIP, newVM); newVM.iscsiIP = xdlClusterNaming.makeiSCSIIP(bladeIP, newVM); newVM.eth0MAC = xdlClusterNaming.makeEth0MAC(bladeIP, newVM); newVM.eth1MAC = xdlClusterNaming.makeEth1MAC(bladeIP, newVM); // VMs always have this implicit snapshot. newVM.currentSnapshot = "vm"; if (needToResetReqSWDebugPort) { reqsw.debuggerPort = 0; } lockableVMSpec toRet = new lockableVMSpec(newVM.VMIP, bladeLockType.lockAll, bladeLockType.lockAll); toRet.setSpec(newVM); return(toRet); }
public disposingList <lockableVMSpec> getAllVMInfo(Func <vmSpec, bool> filter, bladeLockType lockTypeRead, bladeLockType lockTypeWrite) { disposingList <lockableVMSpec> toRet = new disposingList <lockableVMSpec>(); foreach (string bladeIP in getAllVMIP()) { lockableVMSpec VM = getVMByIP(bladeIP, lockTypeRead, lockTypeWrite); if (filter(VM.spec)) { toRet.Add(VM); } else { VM.Dispose(); } } return(toRet); }
public void testDBObjectThrowsAfterUpgradeToWriteAccess() { using (hostDB db = new hostDB()) { bladeDirectorWCF.vmSpec toDB = new bladeDirectorWCF.vmSpec(db.conn, "1.1.1.6", bladeLockType.lockAll, bladeLockType.lockAll); db.addNode(toDB); using (lockableVMSpec refA = db.getVMByIP("1.1.1.6", bladeLockType.lockNone, bladeLockType.lockNone)) { refA.upgradeLocks( bladeLockType.lockVirtualHW | bladeLockType.lockOwnership, bladeLockType.lockVirtualHW | bladeLockType.lockOwnership); Assert.AreEqual(bladeLockType.lockIPAddresses | bladeLockType.lockOwnership | bladeLockType.lockVirtualHW, refA.spec.permittedAccessRead); Assert.AreEqual(bladeLockType.lockOwnership | bladeLockType.lockVirtualHW, refA.spec.permittedAccessWrite); failIfThrow(() => { refA.spec.friendlyName = "test data"; }); failIfThrow(() => { refA.spec.currentOwner = "Dave_Lister"; }); failIfThrow(() => { Debug.WriteLine(refA.spec.friendlyName); }); failIfThrow(() => { Debug.WriteLine(refA.spec.currentOwner); }); } } }
public lockableVMSpec getVMByIP(string bladeName, bladeLockType readLock, bladeLockType writeLock) { // We need to lock IP addressess, since we're searching by them. readLock = readLock | bladeLockType.lockIPAddresses; lockableVMSpec toRet = new lockableVMSpec(bladeName, readLock, writeLock); try { string sqlCommand = "select * from bladeOwnership " + "join VMConfiguration on ownershipKey = VMConfiguration.ownershipID " + "where VMConfiguration.VMIP = $VMIP"; using (SQLiteCommand cmd = new SQLiteCommand(sqlCommand, conn)) { cmd.Parameters.AddWithValue("$VMIP", bladeName); using (SQLiteDataReader reader = cmd.ExecuteReader()) { if (reader.Read()) { toRet.setSpec(new vmSpec(conn, reader, readLock, writeLock)); return(toRet); } // No records returned. toRet.Dispose(); return(null); } } } catch (Exception) { toRet.Dispose(); throw; } }
public void testDBObjectThrowsAfterDowngradeToNoAccess() { using (hostDB db = new hostDB()) { bladeDirectorWCF.vmSpec toDB = new bladeDirectorWCF.vmSpec(db.conn, "1.1.1.3", bladeLockType.lockAll, bladeLockType.lockAll); db.addNode(toDB); // Lock with write access to a field, and then downgrade to no access. Then, access the field we originally // locked, and expect an exception to be thrown. using (lockableVMSpec refA = db.getVMByIP("1.1.1.3", bladeLockType.lockNone, bladeLockType.lockVirtualHW | bladeLockType.lockOwnership)) { refA.downgradeLocks( bladeLockType.lockVirtualHW | bladeLockType.lockOwnership, bladeLockType.lockVirtualHW | bladeLockType.lockOwnership); Assert.AreEqual(bladeLockType.lockIPAddresses, refA.spec.permittedAccessRead); Assert.AreEqual(bladeLockType.lockNone, refA.spec.permittedAccessWrite); failIfNoThrow(() => { refA.spec.friendlyName = "test data"; }); failIfNoThrow(() => { refA.spec.currentOwner = "Dave_Lister"; }); } } }
public disposingList <lockableVMSpec> getVMByVMServerIP(lockableBladeSpec blade, bladeLockType readLock, bladeLockType writeLock) { disposingList <lockableVMSpec> toRet = new disposingList <lockableVMSpec>(); if ((blade.getCurrentLocks().read & bladeLockType.lockVMCreation) == 0) { throw new Exception("lockVMCreation required on vmserver passed to getVMByVMServerIP"); } // We need to lock IP addressess on the VMs, since we lock by them. readLock = readLock | bladeLockType.lockIPAddresses; // Since we hold lockVMCreation, we can assume no new VMs will be added or removed to/from this blade. We assume that // VM IP addresses will never change, except during initialization, when they go from null - we just drop any with a // NULL IP address. Dictionary <string, lockableVMSpec> VMNames = new Dictionary <string, lockableVMSpec>(); string sqlCommand = "select VMIP from vmConfiguration " + "join bladeConfiguration on parentbladeID = bladeConfigKey " + "where bladeIP = $vmServerIP"; using (SQLiteCommand cmd = new SQLiteCommand(sqlCommand, conn)) { cmd.Parameters.AddWithValue("$vmServerIP", blade.spec.bladeIP); using (SQLiteDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { string VMName = reader[0].ToString(); if (!String.IsNullOrEmpty(VMName)) { VMNames.Add(VMName, new lockableVMSpec(VMName, readLock, writeLock)); } } } } try { // Now read each from the DB, now that we hold the lock for each. foreach (KeyValuePair <string, lockableVMSpec> kvp in VMNames) { string vmName = kvp.Key; lockableVMSpec vmSpec = kvp.Value; string sql_getVM = "select bladeOwnership.*, vmConfiguration.* from vmConfiguration " + " join bladeOwnership on bladeOwnership.ownershipKey = vmConfiguration.ownershipID " + " join bladeConfiguration on parentbladeID = bladeConfigKey " + " where VMIP = $vmIP"; using (SQLiteCommand cmd = new SQLiteCommand(sql_getVM, conn)) { cmd.Parameters.AddWithValue("$vmIP", vmName); using (SQLiteDataReader reader = cmd.ExecuteReader()) { if (!reader.Read()) { throw new Exception("VM disappeared, even though we hold lockVMCreation on the parent!"); } vmSpec.setSpec(new vmSpec(conn, reader, readLock, writeLock)); toRet.Add(vmSpec); } } } } catch (Exception) { foreach (KeyValuePair <string, lockableVMSpec> kvp in VMNames) { kvp.Value.Dispose(); } throw; } return(toRet); }
public override hypervisor makeHypervisorForVM(lockableVMSpec VM, lockableBladeSpec parentBladeSpec) { return(new hypervisor_mocked_vmware(VM.spec, parentBladeSpec.spec, callMockedExecutionHandler)); }