mirror of https://github.com/apache/jclouds.git
fixed locking transient bug
This commit is contained in:
parent
28bd62edfc
commit
1f31e96a9f
|
@ -158,7 +158,7 @@ public class VirtualBoxComputeServiceContextModule extends
|
|||
bind(new TypeLiteral<Function<IMachine, SshClient>>() {
|
||||
}).to(IMachineToSshClient.class);
|
||||
|
||||
bind(ExecutionType.class).toInstance(ExecutionType.GUI);
|
||||
bind(ExecutionType.class).toInstance(ExecutionType.HEADLESS);
|
||||
bind(LockType.class).toInstance(LockType.Write);
|
||||
}
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
|
|||
.split(installationKeySequence), new StringToKeyCode());
|
||||
|
||||
for (List<Integer> scancodes : scancodelist) {
|
||||
machineUtils.readLockMachineAndApplyToSession(vmName,new SendScancodes(scancodes));
|
||||
machineUtils.sharedLockMachineAndApplyToSession(vmName,new SendScancodes(scancodes));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.jclouds.virtualbox.domain.NodeSpec;
|
|||
import org.jclouds.virtualbox.domain.VmSpec;
|
||||
import org.jclouds.virtualbox.statements.DeleteGShadowLock;
|
||||
import org.jclouds.virtualbox.statements.SetIpAddress;
|
||||
import org.jclouds.virtualbox.util.MachineController;
|
||||
import org.jclouds.virtualbox.util.MachineUtils;
|
||||
import org.virtualbox_4_1.CleanupMode;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
|
@ -83,23 +84,22 @@ public class NodeCreator implements Function<NodeSpec, NodeAndInitialCredentials
|
|||
// TODO parameterize
|
||||
public static final boolean USE_LINKED = true;
|
||||
|
||||
// TODO parameterize
|
||||
public static final ExecutionType EXECUTION_TYPE = ExecutionType.HEADLESS;
|
||||
|
||||
private final Supplier<VirtualBoxManager> manager;
|
||||
private final Function<CloneSpec, IMachine> cloner;
|
||||
private final AtomicInteger nodePorts;
|
||||
private final AtomicInteger nodeIps;
|
||||
private MachineUtils machineUtils;
|
||||
private final MachineUtils machineUtils;
|
||||
private final MachineController machineController;
|
||||
|
||||
@Inject
|
||||
public NodeCreator(Supplier<VirtualBoxManager> manager, Function<CloneSpec, IMachine> cloner,
|
||||
MachineUtils machineUtils, RunScriptOnNode.Factory scriptRunnerFactory) {
|
||||
MachineUtils machineUtils, RunScriptOnNode.Factory scriptRunnerFactory, MachineController machineController) {
|
||||
this.manager = manager;
|
||||
this.cloner = cloner;
|
||||
this.nodePorts = new AtomicInteger(NODE_PORT_INIT);
|
||||
this.nodeIps = new AtomicInteger(2);
|
||||
this.machineUtils = machineUtils;
|
||||
this.machineController = machineController;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -147,7 +147,7 @@ public class NodeCreator implements Function<NodeSpec, NodeAndInitialCredentials
|
|||
|
||||
IMachine cloned = cloner.apply(cloneSpec);
|
||||
|
||||
new LaunchMachineIfNotAlreadyRunning(manager.get(), EXECUTION_TYPE, "").apply(cloned);
|
||||
machineController.ensureMachineIsLaunched(cloneVmSpec.getVmName());
|
||||
|
||||
// IMachineToNodeMetadata produces the final ip's but these need to be set before so we build a
|
||||
// NodeMetadata just for the sake of running the gshadow and setip scripts
|
||||
|
|
|
@ -67,7 +67,7 @@ public class MachineController {
|
|||
public void ensureMachineHasPowerDown(String vmName) {
|
||||
while (!manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.POWERED_OFF)) {
|
||||
try {
|
||||
machineUtils.writeLockMachineAndApplyToSession(vmName, new Function<ISession, Void>() {
|
||||
machineUtils.sharedLockMachineAndApplyToSession(vmName, new Function<ISession, Void>() {
|
||||
@Override
|
||||
public Void apply(ISession session) {
|
||||
IProgress powerDownProgress = session.getConsole().powerDown();
|
||||
|
|
|
@ -57,15 +57,12 @@ public class MachineUtils {
|
|||
|
||||
private final Supplier<VirtualBoxManager> manager;
|
||||
private final Factory scriptRunner;
|
||||
private final Supplier<NodeMetadata> host;
|
||||
|
||||
@Inject
|
||||
public MachineUtils(Supplier<VirtualBoxManager> manager, RunScriptOnNode.Factory scriptRunner,
|
||||
Supplier<NodeMetadata> host) {
|
||||
public MachineUtils(Supplier<VirtualBoxManager> manager, RunScriptOnNode.Factory scriptRunner) {
|
||||
super();
|
||||
this.manager = manager;
|
||||
this.scriptRunner = scriptRunner;
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public ListenableFuture<ExecResponse> runScriptOnNode(NodeMetadata metadata, Statement statement,
|
||||
|
@ -102,8 +99,9 @@ public class MachineUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Locks the machine and executes the given function using the machine matching the given id.
|
||||
* The machine is write locked and modifications to the session that reflect on the machine can be done safely.
|
||||
* Locks the machine and executes the given function using the machine matching the given id. The
|
||||
* machine is write locked and modifications to the session that reflect on the machine can be
|
||||
* done safely.
|
||||
* <p/>
|
||||
* Unlocks the machine before returning.
|
||||
*
|
||||
|
@ -118,8 +116,9 @@ public class MachineUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Locks the machine and executes the given function using the machine matching the given id.
|
||||
* The machine is read locked, which means that settings can be read safely (but not changed) by function.
|
||||
* Locks the machine and executes the given function using the machine matching the given id. The
|
||||
* machine is read locked, which means that settings can be read safely (but not changed) by
|
||||
* function.
|
||||
* <p/>
|
||||
* Unlocks the machine before returning.
|
||||
*
|
||||
|
@ -129,7 +128,7 @@ public class MachineUtils {
|
|||
* the function to execute
|
||||
* @return the result from applying the function to the machine.
|
||||
*/
|
||||
public <T> T readLockMachineAndApply(final String machineId, final Function<IMachine, T> function) {
|
||||
public <T> T sharedLockMachineAndApply(final String machineId, final Function<IMachine, T> function) {
|
||||
return lockSessionOnMachineAndApply(machineId, LockType.Shared, new Function<ISession, T>() {
|
||||
|
||||
@Override
|
||||
|
@ -146,8 +145,9 @@ public class MachineUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Locks the machine and executes the given function to the session using the machine matching the given id.
|
||||
* The machine is read locked, which means that settings can be read safely (but not changed) by function.
|
||||
* Locks the machine and executes the given function to the session using the machine matching
|
||||
* the given id. The machine is read locked, which means that settings can be read safely (but
|
||||
* not changed) by function.
|
||||
* <p/>
|
||||
* Unlocks the machine before returning.
|
||||
*
|
||||
|
@ -157,11 +157,10 @@ public class MachineUtils {
|
|||
* the function to execute
|
||||
* @return the result from applying the function to the machine.
|
||||
*/
|
||||
public <T> T readLockMachineAndApplyToSession(final String machineId, final Function<ISession, T> function) {
|
||||
public <T> T sharedLockMachineAndApplyToSession(final String machineId, final Function<ISession, T> function) {
|
||||
return lockSessionOnMachineAndApply(machineId, LockType.Shared, function);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Locks the machine and executes the given function using the current session. Since the machine
|
||||
* is locked it is possible to perform some modifications to the IMachine.
|
||||
|
@ -183,11 +182,14 @@ public class MachineUtils {
|
|||
int retries = 5;
|
||||
int count = 0;
|
||||
ISession session;
|
||||
long time = System.currentTimeMillis();
|
||||
while (true) {
|
||||
try {
|
||||
session = manager.get().getSessionObject();
|
||||
IMachine immutableMachine = manager.get().getVBox().findMachine(machineId);
|
||||
session = manager.get().getSessionObject();
|
||||
immutableMachine.lockMachine(session, type);
|
||||
System.err.println("ACQUIRED LOCK ["+time+"]");
|
||||
print();
|
||||
break;
|
||||
} catch (VBoxException e) {
|
||||
VBoxException vbex = Throwables2.getFirstThrowableOfType(e, VBoxException.class);
|
||||
|
@ -195,7 +197,7 @@ public class MachineUtils {
|
|||
return null;
|
||||
}
|
||||
count++;
|
||||
logger.warn("Could not lock machine (try %i of %i). Error: %s", retries, count, e.getMessage());
|
||||
logger.warn(e, "Could not lock machine (try %d of %d). Error: %s", count, retries, e.getMessage());
|
||||
if (count == retries) {
|
||||
throw new RuntimeException(String.format("error locking %s with %s lock: %s", machineId, type,
|
||||
e.getMessage()), e);
|
||||
|
@ -213,6 +215,14 @@ public class MachineUtils {
|
|||
type, e.getMessage()), e);
|
||||
} finally {
|
||||
session.unlockMachine();
|
||||
System.err.println("RELEASED LOCK ["+time+"]");
|
||||
print();
|
||||
}
|
||||
}
|
||||
|
||||
void print() {
|
||||
for (StackTraceElement element : Thread.currentThread().getStackTrace()){
|
||||
System.err.println(element.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest {
|
|||
|
||||
String vboxVersion = Iterables.get(
|
||||
Splitter.on('r').split(context.getProviderSpecificContext().getBuildVersion()), 0);
|
||||
assertEquals(vboxVersion, machineUtils.readLockMachineAndApplyToSession(machine.getName(),
|
||||
assertEquals(vboxVersion, machineUtils.sharedLockMachineAndApplyToSession(machine.getName(),
|
||||
new Function<ISession, String>() {
|
||||
@Override
|
||||
public String apply(ISession session) {
|
||||
|
|
|
@ -110,7 +110,7 @@ public class GuestAdditionsInstallerLiveTest extends
|
|||
machineUtils.applyForMachine(machine.getName(),
|
||||
new LaunchMachineIfNotAlreadyRunning(manager.get(),
|
||||
ExecutionType.GUI, ""));
|
||||
assertTrue(machineUtils.readLockMachineAndApplyToSession(
|
||||
assertTrue(machineUtils.sharedLockMachineAndApplyToSession(
|
||||
machine.getName(),
|
||||
new Function<ISession, Boolean>() {
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue