() {
+ @Override
+ public boolean apply(IAdditionsFacility additionsFacility) {
+ return additionsFacility.getType().equals(AdditionsFacilityType.VBoxService);
+ };
+ });
+ }
+
+ while(!vboxServiceFacility.get().getStatus().equals(AdditionsFacilityStatus.Active)) {
+ Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
+ }
+ Uninterruptibles.sleepUninterruptibly(3, TimeUnit.SECONDS);
+ return null;
+ }
+ });
}
}
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/util/MachineNameOrIdAndNicSlot.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/util/MachineNameOrIdAndNicSlot.java
new file mode 100644
index 0000000000..360f08350b
--- /dev/null
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/util/MachineNameOrIdAndNicSlot.java
@@ -0,0 +1,132 @@
+package org.jclouds.virtualbox.util;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.io.Serializable;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
+
+
+/**
+ * An immutable representation of a MachineNameOrId and NIC port.
+ *
+ * Example usage:
+ *
+ * MachineNameOrIdAndNicSlot mp = MachineNameOrIdAndNicSlot.fromString("myMachine:1");
+ * hp.getMachineNameOrId(); // returns "myMachine"
+ * hp.getSlot(); // returns 1
+ * hp.toString(); // returns "myMachine:1"
+ *
+ *
+ * @author Andrea Turli
+ */
+public final class MachineNameOrIdAndNicSlot implements Serializable {
+
+ private static final String SEPARATOR = ":";
+
+/** IMachine name or id*/
+ private final String machineNameOrId;
+
+ /** Validated NIC slot number in the range [0..3] */
+ private final long slot;
+
+ private MachineNameOrIdAndNicSlot(String machineNameOrId, long slot) {
+ this.machineNameOrId = machineNameOrId;
+ this.slot = slot;
+ }
+
+ public String getMachineNameOrId() {
+ return machineNameOrId;
+ }
+
+ public boolean hasSlot() {
+ return slot >= 0;
+ }
+
+ public long getSlot() {
+ checkState(hasSlot());
+ return slot;
+ }
+
+ public String getSlotText() {
+ checkState(hasSlot());
+ return String.valueOf(slot);
+ }
+
+ public static MachineNameOrIdAndNicSlot fromParts(String machineNameOrId, long slot) {
+ checkArgument(isValidSlot(slot));
+ return new MachineNameOrIdAndNicSlot(checkNotNull(machineNameOrId, "machineNameOrId"), slot);
+ }
+
+ public static MachineNameOrIdAndNicSlot fromString(
+ String machineNameOrIdAndNicSlotString) {
+ checkNotNull(machineNameOrIdAndNicSlotString);
+ String machineNameOrId = null;
+ String nicSlotString = null;
+
+ Iterable splittedString = Splitter.on(SEPARATOR).split(
+ machineNameOrIdAndNicSlotString);
+ checkState(Iterables.size(splittedString) == 2);
+ machineNameOrId = Iterables.get(splittedString, 0);
+ nicSlotString = Iterables.get(splittedString, 1);
+
+ long slot = -1;
+ if (nicSlotString != null) {
+ checkArgument(!nicSlotString.startsWith("+"),
+ "Unparseable slot number: %s", nicSlotString);
+ try {
+ slot = Long.parseLong(nicSlotString);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Unparseable slot number: "
+ + nicSlotString);
+ }
+ checkArgument(isValidSlot(slot), "Slot number out of range: %s",
+ nicSlotString);
+ }
+ return new MachineNameOrIdAndNicSlot(machineNameOrId, slot);
+ }
+
+ public MachineNameOrIdAndNicSlot withDefaultSlot(int defaultSlot) {
+ checkArgument(isValidSlot(defaultSlot));
+ if (hasSlot() || slot == defaultSlot) {
+ return this;
+ }
+ return new MachineNameOrIdAndNicSlot(machineNameOrId, defaultSlot);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (other instanceof MachineNameOrIdAndNicSlot) {
+ MachineNameOrIdAndNicSlot that = (MachineNameOrIdAndNicSlot) other;
+ return Objects.equal(this.machineNameOrId, that.machineNameOrId)
+ && this.slot == that.slot;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(machineNameOrId, slot);
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this)
+ .add("machineNameOrId", machineNameOrId)
+ .add("nicSlot", slot)
+ .toString();
+ }
+
+ private static boolean isValidSlot(long slot) {
+ return slot >= 0l && slot <= 3l;
+ }
+
+ private static final long serialVersionUID = 0;
+}
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/util/MachineUtils.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/util/MachineUtils.java
index c0d23708c7..768ff7e501 100644
--- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/util/MachineUtils.java
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/util/MachineUtils.java
@@ -21,9 +21,7 @@ package org.jclouds.virtualbox.util;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
-import java.util.concurrent.ExecutionException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import javax.inject.Named;
@@ -48,8 +46,8 @@ import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
-import com.google.common.base.Throwables;
import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.Uninterruptibles;
import com.google.inject.Inject;
/**
@@ -61,6 +59,8 @@ import com.google.inject.Inject;
@Singleton
public class MachineUtils {
+
+
public final String IP_V4_ADDRESS_PATTERN = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
+ "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
+ "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
@@ -71,14 +71,13 @@ public class MachineUtils {
private final Supplier manager;
private final Factory scriptRunner;
- private final IpAddressesLoadingCache ipAddressesLoadingCache;
+
@Inject
public MachineUtils(Supplier manager, RunScriptOnNode.Factory scriptRunner,
IpAddressesLoadingCache ipAddressesLoadingCache) {
this.manager = manager;
this.scriptRunner = scriptRunner;
- this.ipAddressesLoadingCache = ipAddressesLoadingCache;
}
public ListenableFuture runScriptOnNode(NodeMetadata metadata, Statement statement,
@@ -183,7 +182,7 @@ public class MachineUtils {
*
* Unlocks the machine before returning.
*
- * Tries to obtain a lock 5 times before giving up waiting 1 sec between tries. When no machine
+ * Tries to obtain a lock 15 times before giving up waiting 1 sec between tries. When no machine
* is found null is returned.
*
* @param type
@@ -196,30 +195,27 @@ public class MachineUtils {
*/
protected T lockSessionOnMachineAndApply(String machineId, LockType type, Function function) {
int retries = 15;
- ISession session = lockSession(machineId, type, retries);
+ ISession session = checkNotNull(lockSession(machineId, type, retries), "session");
try {
return function.apply(session);
} catch (VBoxException e) {
throw new RuntimeException(String.format("error applying %s to %s with %s lock: %s", function, machineId,
type, e.getMessage()), e);
} finally {
- if (session != null && session.getState().equals(SessionState.Locked))
- session.unlockMachine();
+ if (session.getState().equals(SessionState.Locked)) {
+ session.unlockMachine();
+ while (!session.getState().equals(SessionState.Unlocked)) {
+ logger.debug("Session not unlocked - wait ...");
+ Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
+ }
+ }
}
}
private ISession lockSession(String machineId, LockType type, int retries) {
int count = 0;
- ISession session;
IMachine immutableMachine = manager.get().getVBox().findMachine(machineId);
-
- try {
- session = manager.get().openMachineSession(immutableMachine);
- if (session.getState().equals(SessionState.Locked))
- return checkNotNull(session, "session");
- } catch (Exception e) {
- logger.debug("machine %s is not locked). Error: %s", immutableMachine.getName(), e.getMessage());
- }
+ ISession session = null;
while (true) {
try {
@@ -237,10 +233,7 @@ public class MachineUtils {
throw new RuntimeException(String.format("error locking %s with %s lock: %s", machineId, type,
e.getMessage()), e);
}
- try {
- Thread.sleep(count * 1000L);
- } catch (InterruptedException e1) {
- }
+ Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
}
}
checkState(session.getState().equals(SessionState.Locked));
@@ -278,24 +271,4 @@ public class MachineUtils {
|| e.getMessage().contains("Could not find a registered machine with UUID {");
}
- public String getIpAddressFromFirstNIC(String machineName) {
- try {
- return ipAddressesLoadingCache.get(machineName);
- } catch (ExecutionException e) {
- logger.error("Problem in using the ipAddressCache", e.getCause());
- throw Throwables.propagate(e);
- }
- }
-
-
- public static boolean isIpv4(String s) {
- String IP_V4_ADDRESS_PATTERN = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
- + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
- + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
- Pattern pattern = Pattern.compile(IP_V4_ADDRESS_PATTERN);
- Matcher matcher = pattern.matcher(s);
- return matcher.matches();
- }
-
-
}
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/util/NetworkUtils.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/util/NetworkUtils.java
new file mode 100644
index 0000000000..73ddb4e247
--- /dev/null
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/util/NetworkUtils.java
@@ -0,0 +1,339 @@
+/**
+ * Licensed to jclouds, Inc. (jclouds) under one or more
+ * contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. jclouds licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jclouds.virtualbox.util;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
+
+import java.net.URI;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.callables.RunScriptOnNode;
+import org.jclouds.compute.domain.ExecResponse;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+import org.jclouds.compute.options.RunScriptOptions;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.location.Provider;
+import org.jclouds.logging.Logger;
+import org.jclouds.scriptbuilder.domain.Statements;
+import org.jclouds.virtualbox.domain.BridgedIf;
+import org.jclouds.virtualbox.domain.NetworkAdapter;
+import org.jclouds.virtualbox.domain.NetworkInterfaceCard;
+import org.jclouds.virtualbox.domain.NetworkSpec;
+import org.jclouds.virtualbox.functions.IpAddressesLoadingCache;
+import org.jclouds.virtualbox.functions.RetrieveActiveBridgedInterfaces;
+import org.jclouds.virtualbox.statements.EnableNetworkInterface;
+import org.jclouds.virtualbox.statements.GetIPAddressFromMAC;
+import org.jclouds.virtualbox.statements.ScanNetworkWithPing;
+import org.virtualbox_4_1.HostNetworkInterfaceType;
+import org.virtualbox_4_1.IDHCPServer;
+import org.virtualbox_4_1.IHostNetworkInterface;
+import org.virtualbox_4_1.IMachine;
+import org.virtualbox_4_1.INetworkAdapter;
+import org.virtualbox_4_1.ISession;
+import org.virtualbox_4_1.LockType;
+import org.virtualbox_4_1.NetworkAttachmentType;
+import org.virtualbox_4_1.VirtualBoxManager;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.util.concurrent.Uninterruptibles;
+import com.google.inject.Inject;
+
+/**
+ * Utilities to manage VirtualBox networks on guests
+ *
+ * @author Andrea Turli
+ */
+
+@Singleton
+public class NetworkUtils {
+
+ // TODO parameterize
+ public static final int MASTER_PORT = 2222;
+ private static final String VIRTUALBOX_HOST_GATEWAY = "10.0.2.15";
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ private final Supplier manager;
+ private final MachineUtils machineUtils;
+ private final Supplier host;
+ private final Supplier providerSupplier;
+ private final IpAddressesLoadingCache ipAddressesLoadingCache;
+ private final RunScriptOnNode.Factory scriptRunnerFactory;
+ private final Supplier hostSupplier;
+
+ @Inject
+ public NetworkUtils(Supplier manager, MachineUtils machineUtils,
+ MachineController machineController,
+ Supplier host,
+ @Provider Supplier providerSupplier,
+ IpAddressesLoadingCache ipAddressesLoadingCache,
+ Supplier hostSupplier,
+ RunScriptOnNode.Factory scriptRunnerFactory) {
+ this.manager = manager;
+ this.machineUtils = machineUtils;
+ this.host = checkNotNull(host, "host");
+ this.providerSupplier = checkNotNull(providerSupplier,
+ "endpoint to virtualbox websrvd is needed");
+ this.ipAddressesLoadingCache = ipAddressesLoadingCache;
+ this.scriptRunnerFactory = scriptRunnerFactory;
+ this.hostSupplier = hostSupplier;
+ }
+
+ public NetworkSpec createNetworkSpecWhenVboxIsLocalhost() {
+ NetworkAdapter natAdapter = NetworkAdapter.builder()
+ .networkAttachmentType(NetworkAttachmentType.NAT)
+ .build();
+
+ NetworkInterfaceCard natIfaceCard = NetworkInterfaceCard.builder()
+ .addNetworkAdapter(natAdapter)
+ .slot(1L)
+ .build();
+ NetworkAdapter hostOnlyAdapter = NetworkAdapter.builder()
+ .networkAttachmentType(NetworkAttachmentType.HostOnly)
+ .build();
+ // create new hostOnly interface if needed, otherwise use the one already there with dhcp enabled ...
+ String hostOnlyIfName = getHostOnlyIfOrCreate();
+ NetworkInterfaceCard hostOnlyIfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(hostOnlyAdapter)
+ .addHostInterfaceName(hostOnlyIfName).slot(0L).build();
+ return createNetworkSpecForHostOnlyNATNICs(natIfaceCard, hostOnlyIfaceCard);
+ }
+
+ public boolean enableNetworkInterface(NodeMetadata nodeMetadata, NetworkInterfaceCard networkInterfaceCard) {
+ ExecResponse execResponse = null;
+ try {
+ execResponse = machineUtils.runScriptOnNode(nodeMetadata,
+ new EnableNetworkInterface(networkInterfaceCard), RunScriptOptions.NONE).get();
+ } catch (InterruptedException e) {
+ logger.error(e.getMessage());
+ } catch (ExecutionException e) {
+ logger.error(e.getMessage());
+ }
+ if(execResponse == null)
+ return false;
+ return execResponse.getExitStatus() == 0;
+ }
+
+ private NetworkSpec createNetworkSpecForHostOnlyNATNICs(NetworkInterfaceCard natIfaceCard,
+ NetworkInterfaceCard hostOnlyIfaceCard) {
+ return NetworkSpec.builder()
+ .addNIC(hostOnlyIfaceCard)
+ .addNIC(natIfaceCard)
+ .build();
+ }
+
+ public String getHostOnlyIfOrCreate() {
+ IHostNetworkInterface availableHostInterfaceIf = returnExistingHostNetworkInterfaceWithDHCPenabledOrNull(manager
+ .get().getVBox().getHost().getNetworkInterfaces());
+ if (availableHostInterfaceIf==null) {
+ final String hostOnlyIfName = createHostOnlyIf();
+ assignDHCPtoHostOnlyInterface(hostOnlyIfName);
+ return hostOnlyIfName;
+ } else {
+ return availableHostInterfaceIf.getName();
+ }
+ }
+
+ private void assignDHCPtoHostOnlyInterface(final String hostOnlyIfName) {
+ List availableNetworkInterfaces = manager.get().getVBox().getHost()
+ .getNetworkInterfaces();
+
+ IHostNetworkInterface iHostNetworkInterfaceWithHostOnlyIfName = Iterables.getOnlyElement(Iterables.filter(availableNetworkInterfaces, new Predicate() {
+
+ @Override
+ public boolean apply(IHostNetworkInterface iHostNetworkInterface) {
+ return iHostNetworkInterface.getName().equals(hostOnlyIfName);
+ }
+ }));
+
+ String hostOnlyIfIpAddress = iHostNetworkInterfaceWithHostOnlyIfName.getIPAddress();
+ String dhcpIpAddress = hostOnlyIfIpAddress.substring(0, hostOnlyIfIpAddress.lastIndexOf(".")) + ".254";
+ String dhcpNetmask = "255.255.255.0";
+ String dhcpLowerIp = hostOnlyIfIpAddress.substring(0, hostOnlyIfIpAddress.lastIndexOf(".")) + ".2";
+ String dhcpUpperIp = hostOnlyIfIpAddress.substring(0, hostOnlyIfIpAddress.lastIndexOf(".")) + ".253";
+ NodeMetadata hostNodeMetadata = getHostNodeMetadata();
+
+ ExecResponse response = scriptRunnerFactory
+ .create(hostNodeMetadata,
+ Statements.exec(String
+ .format("VBoxManage dhcpserver add --ifname %s --ip %s --netmask %s --lowerip %s --upperip %s --enable",
+ hostOnlyIfName, dhcpIpAddress, dhcpNetmask, dhcpLowerIp, dhcpUpperIp)), runAsRoot(false).wrapInInitScript(false)).init().call();
+ checkState(response.getExitStatus()==0);
+ }
+
+ private String createHostOnlyIf() {
+ final String hostOnlyIfName;
+ NodeMetadata hostNodeMetadata = getHostNodeMetadata();
+ ExecResponse createHostOnlyResponse = scriptRunnerFactory
+ .create(hostNodeMetadata, Statements.exec("VBoxManage hostonlyif create"),
+ runAsRoot(false).wrapInInitScript(false)).init().call();
+ String output = createHostOnlyResponse.getOutput();
+ checkState(createHostOnlyResponse.getExitStatus()==0);
+ checkState(output.contains("'"), "cannot create hostonlyif");
+ hostOnlyIfName = output.substring(output.indexOf("'") + 1, output.lastIndexOf("'"));
+ return hostOnlyIfName;
+ }
+
+ private NodeMetadata getHostNodeMetadata() {
+ NodeMetadata hostNodeMetadata = NodeMetadataBuilder
+ .fromNodeMetadata(host.get())
+ .publicAddresses(
+ ImmutableList.of(providerSupplier.get().getHost()))
+ .build();
+ return hostNodeMetadata;
+ }
+
+ private IHostNetworkInterface returnExistingHostNetworkInterfaceWithDHCPenabledOrNull(Iterable availableNetworkInterfaces) {
+ checkNotNull(availableNetworkInterfaces);
+ return Iterables.getFirst(filterAvailableNetworkInterfaceByHostOnlyAndDHCPenabled(availableNetworkInterfaces), null);
+ }
+
+ /**
+ * @param availableNetworkInterfaces
+ * @param hostOnlyIfIpAddress
+ * @return
+ */
+ private Iterable filterAvailableNetworkInterfaceByHostOnlyAndDHCPenabled(Iterable availableNetworkInterfaces) {
+ Iterable filteredNetworkInterfaces = Iterables.filter(availableNetworkInterfaces, new Predicate() {
+ @Override
+ public boolean apply(IHostNetworkInterface iHostNetworkInterface) {
+ // this is an horrible workaround cause iHostNetworkInterface.getDhcpEnabled is working only for windows host
+ boolean match = false;
+ List availableDHCPservers = manager.get().getVBox().getDHCPServers();
+ for (IDHCPServer idhcpServer : availableDHCPservers) {
+ if(idhcpServer.getEnabled() && idhcpServer.getNetworkName().equals(iHostNetworkInterface.getNetworkName()))
+ match = true;
+ }
+ return iHostNetworkInterface.getInterfaceType().equals(HostNetworkInterfaceType.HostOnly) &&
+ match;
+ }
+ });
+ return filteredNetworkInterfaces;
+ }
+
+
+ public String getIpAddressFromNicSlot(String machineNameOrId, long nicSlot) {
+ MachineNameOrIdAndNicSlot machineNameOrIdAndNicSlot =
+ MachineNameOrIdAndNicSlot.fromParts(machineNameOrId, nicSlot);
+ logger.debug("Looking for an available IP address for %s at slot %s ...",
+ machineNameOrIdAndNicSlot.getMachineNameOrId(),
+ machineNameOrIdAndNicSlot.getSlotText());
+ try {
+ String ipAddress = ipAddressesLoadingCache.get(machineNameOrIdAndNicSlot);
+ while(!isValidIpForHostOnly(machineNameOrIdAndNicSlot, ipAddress)) {
+ ipAddressesLoadingCache.invalidate(machineNameOrIdAndNicSlot);
+ ipAddress = ipAddressesLoadingCache.get(machineNameOrIdAndNicSlot);
+ }
+ logger.debug("Found an available IP address %s for guest: %s at slot: %s",
+ ipAddress,
+ machineNameOrIdAndNicSlot.getMachineNameOrId(),
+ machineNameOrIdAndNicSlot.getSlotText());
+ return ipAddress;
+ } catch (ExecutionException e) {
+ logger.error("Problem in using the ipAddressCache", e.getCause());
+ throw Throwables.propagate(e);
+ }
+ }
+
+ public static boolean isIpv4(String s) {
+ String IP_V4_ADDRESS_PATTERN = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
+ + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
+ + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
+ Pattern pattern = Pattern.compile(IP_V4_ADDRESS_PATTERN);
+ Matcher matcher = pattern.matcher(s);
+ return matcher.matches();
+ }
+
+ public boolean isValidIpForHostOnly(MachineNameOrIdAndNicSlot machineNameOrIdAndNicSlot, String ip) {
+ final String vmNameOrId = machineNameOrIdAndNicSlot.getMachineNameOrId();
+ IMachine machine = manager.get().getVBox().findMachine(vmNameOrId);
+ long slot = machineNameOrIdAndNicSlot.getSlot();
+
+ if(ip.equals(VIRTUALBOX_HOST_GATEWAY) || !isValidHostOnlyIpAddress(ip, slot, machine)) {
+ // restart vm
+ logger.debug("reset node (%s) to refresh guest properties.", vmNameOrId);
+ machineUtils.lockSessionOnMachineAndApply(vmNameOrId, LockType.Shared,
+ new Function() {
+ @Override
+ public Void apply(ISession session) {
+ session.getConsole().reset();
+ long time = 15;
+ logger.debug("Waiting %s secs for the reset of (%s) ...", time, vmNameOrId);
+ Uninterruptibles.sleepUninterruptibly(time, TimeUnit.SECONDS);
+ return null;
+ }
+ });
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean isValidHostOnlyIpAddress(String ip, long slot,
+ IMachine machine) {
+ boolean result = isIpv4(ip) && machine.getNetworkAdapter(slot).getAttachmentType().equals(NetworkAttachmentType.HostOnly)
+ && !ipBelongsToNatRange(ip);
+ return result;
+ }
+
+ private static boolean ipBelongsToNatRange(String ip) {
+ return ip.startsWith("10.0.3");
+ }
+
+ protected String getIpAddressFromBridgedNIC(INetworkAdapter networkAdapter,
+ String network) {
+ // RetrieveActiveBridgedInterfaces
+ List activeBridgedInterfaces = new RetrieveActiveBridgedInterfaces(scriptRunnerFactory).apply(hostSupplier.get());
+ BridgedIf activeBridgedIf = checkNotNull(Iterables.get(activeBridgedInterfaces, 0), "activeBridgedInterfaces");
+ network = activeBridgedIf.getIpAddress();
+
+ // scan ip
+ RunScriptOnNode ipScanRunScript = scriptRunnerFactory.create(
+ hostSupplier.get(), new ScanNetworkWithPing(network),
+ RunScriptOptions.NONE);
+ ExecResponse execResponse = ipScanRunScript.init().call();
+ checkState(execResponse.getExitStatus() == 0);
+
+ // retrieve ip from mac
+ RunScriptOnNode getIpFromMACAddressRunScript = scriptRunnerFactory
+ .create(hostSupplier.get(), new GetIPAddressFromMAC(
+ networkAdapter.getMACAddress()),
+ RunScriptOptions.NONE);
+ ExecResponse ipExecResponse = getIpFromMACAddressRunScript.init()
+ .call();
+ checkState(ipExecResponse.getExitStatus() == 0);
+ return checkNotNull(ipExecResponse.getOutput(), "ipAddress");
+ }
+}
diff --git a/labs/virtualbox/src/main/resources/default-images.yaml b/labs/virtualbox/src/main/resources/default-images.yaml
index c9ed61fe71..fe4c0c82d3 100644
--- a/labs/virtualbox/src/main/resources/default-images.yaml
+++ b/labs/virtualbox/src/main/resources/default-images.yaml
@@ -1,4 +1,139 @@
images:
+ - id: ubuntu-10.04.4-server-i386
+ name: ubuntu-10.04-server-i386
+ description: ubuntu 10.04.4 server (i386)
+ os_arch: x86
+ os_family: ubuntu
+ os_description: ubuntu
+ os_version: 10.04.4
+ iso: http://releases.ubuntu.com/10.04.4/ubuntu-10.04.4-server-i386.iso
+ iso_md5: fc08a01e78348e3918180ea91a6883bb
+ username: toor
+ credential: password
+ keystroke_sequence: |
+
+ /install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg
+ debian-installer=en_US auto locale=en_US kbd-chooser/method=us
+ hostname=vmName
+ fb=false debconf/frontend=noninteractive
+ console-setup/ask_detect=false console-setup/modelcode=pc105 console-setup/layoutcode=us
+ initrd=/install/initrd.gz --
+ preseed_cfg: |
+ ## Options to set on the command line
+ d-i debian-installer/locale string en_US
+ d-i console-setup/ask_detect boolean false
+ d-i console-setup/layoutcode string us
+ d-i netcfg/get_hostname string unassigned-hostname
+ d-i netcfg/get_domain string unassigned-domain
+ d-i time/zone string UTC
+ d-i clock-setup/utc-auto boolean true
+ d-i clock-setup/utc boolean true
+ d-i kbd-chooser/method select American English
+ d-i netcfg/wireless_wep string
+ d-i base-installer/kernel/override-image string linux-server
+ d-i debconf debconf/frontend select Noninteractive
+ d-i pkgsel/install-language-support boolean false
+ tasksel tasksel/first multiselect standard, ubuntu-server
+ d-i partman-auto/method string lvm
+ #d-i partman-auto/purge_lvm_from_device boolean true
+ d-i partman-lvm/confirm boolean true
+ d-i partman-lvm/device_remove_lvm boolean true
+ d-i partman-auto/choose_recipe select atomic
+ d-i partman/confirm_write_new_label boolean true
+ d-i partman/confirm_nooverwrite boolean true
+ d-i partman/choose_partition select finish
+ d-i partman/confirm boolean true
+ # Write the changes to disks and configure LVM?
+ d-i partman-lvm/confirm boolean true
+ d-i partman-lvm/confirm_nooverwrite boolean true
+ d-i partman-auto-lvm/guided_size string max
+ ## Default user, we can get away with a recipe to change this
+ d-i passwd/user-fullname string toor
+ d-i passwd/username string toor
+ d-i passwd/user-password password password
+ d-i passwd/user-password-again password password
+ d-i user-setup/encrypt-home boolean false
+ d-i user-setup/allow-password-weak boolean true
+ d-i pkgsel/include string openssh-server ntp
+ # Whether to upgrade packages after debootstrap.
+ # Allowed values: none, safe-upgrade, full-upgrade
+ d-i pkgsel/upgrade select full-upgrade
+ d-i grub-installer/only_debian boolean true
+ d-i grub-installer/with_other_os boolean true
+ d-i finish-install/reboot_in_progress note
+ #For the update
+ d-i pkgsel/update-policy select none
+ # debconf-get-selections --install
+ #Use mirror
+ choose-mirror-bin mirror/http/proxy string
+ - id: ubuntu-10.04.4-server-amd64
+ name: ubuntu-10.04-server-amd64
+ description: ubuntu 10.04.4 server (amd64)
+ os_arch: amd64
+ os_family: ubuntu
+ os_description: ubuntu
+ os_version: 10.04.4
+ os_64bit: true
+ iso: http://releases.ubuntu.com/10.04.4/ubuntu-10.04.4-server-amd64.iso
+ iso_md5: 9b218654cdcdf9722171648c52f8a088
+ username: toor
+ credential: password
+ keystroke_sequence: |
+
+ /install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg
+ debian-installer=en_US auto locale=en_US kbd-chooser/method=us
+ hostname=vmName
+ fb=false debconf/frontend=noninteractive
+ console-setup/ask_detect=false console-setup/modelcode=pc105 console-setup/layoutcode=us
+ initrd=/install/initrd.gz --
+ preseed_cfg: |
+ ## Options to set on the command line
+ d-i debian-installer/locale string en_US
+ d-i console-setup/ask_detect boolean false
+ d-i console-setup/layoutcode string us
+ d-i netcfg/get_hostname string unassigned-hostname
+ d-i netcfg/get_domain string unassigned-domain
+ d-i time/zone string UTC
+ d-i clock-setup/utc-auto boolean true
+ d-i clock-setup/utc boolean true
+ d-i kbd-chooser/method select American English
+ d-i netcfg/wireless_wep string
+ d-i base-installer/kernel/override-image string linux-server
+ d-i debconf debconf/frontend select Noninteractive
+ d-i pkgsel/install-language-support boolean false
+ tasksel tasksel/first multiselect standard, ubuntu-server
+ d-i partman-auto/method string lvm
+ #d-i partman-auto/purge_lvm_from_device boolean true
+ d-i partman-lvm/confirm boolean true
+ d-i partman-lvm/device_remove_lvm boolean true
+ d-i partman-auto/choose_recipe select atomic
+ d-i partman/confirm_write_new_label boolean true
+ d-i partman/confirm_nooverwrite boolean true
+ d-i partman/choose_partition select finish
+ d-i partman/confirm boolean true
+ # Write the changes to disks and configure LVM?
+ d-i partman-lvm/confirm boolean true
+ d-i partman-lvm/confirm_nooverwrite boolean true
+ d-i partman-auto-lvm/guided_size string max
+ ## Default user, we can get away with a recipe to change this
+ d-i passwd/user-fullname string toor
+ d-i passwd/username string toor
+ d-i passwd/user-password password password
+ d-i passwd/user-password-again password password
+ d-i user-setup/encrypt-home boolean false
+ d-i user-setup/allow-password-weak boolean true
+ d-i pkgsel/include string openssh-server ntp
+ # Whether to upgrade packages after debootstrap.
+ # Allowed values: none, safe-upgrade, full-upgrade
+ d-i pkgsel/upgrade select full-upgrade
+ d-i grub-installer/only_debian boolean true
+ d-i grub-installer/with_other_os boolean true
+ d-i finish-install/reboot_in_progress note
+ #For the update
+ d-i pkgsel/update-policy select none
+ # debconf-get-selections --install
+ #Use mirror
+ choose-mirror-bin mirror/http/proxy string
- id: ubuntu-11.04-i386
name: ubuntu-11.04-server-i386
description: ubuntu 11.04 server (i386)
@@ -27,7 +162,7 @@ images:
d-i time/zone string UTC
d-i clock-setup/utc-auto boolean true
d-i clock-setup/utc boolean true
- d-i kbd-chooser/method select American English
+ d-i kbd-chooser/method select American English
d-i netcfg/wireless_wep string
d-i base-installer/kernel/override-image string linux-server
# Choices: Dialog, Readline, Gnome, Kde, Editor, Noninteractive
@@ -142,8 +277,9 @@ images:
os_version: 12.04.1
os_64bit: true
iso: http://releases.ubuntu.com/12.04/ubuntu-12.04.1-server-amd64.iso
+ iso_md5: a8c667e871f48f3a662f3fbf1c3ddb17
username: toor
- credential: $user
+ credential: password
keystroke_sequence: |
/install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/BaseVirtualBoxClientLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/BaseVirtualBoxClientLiveTest.java
index 4dbe57877d..9ab564dfc2 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/BaseVirtualBoxClientLiveTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/BaseVirtualBoxClientLiveTest.java
@@ -25,6 +25,7 @@ import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTA
import java.io.File;
import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Named;
@@ -53,6 +54,7 @@ import org.jclouds.virtualbox.functions.IMachineToVmSpec;
import org.jclouds.virtualbox.functions.admin.UnregisterMachineIfExistsAndDeleteItsMedia;
import org.jclouds.virtualbox.util.MachineController;
import org.jclouds.virtualbox.util.MachineUtils;
+import org.jclouds.virtualbox.util.NetworkUtils;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeClass;
@@ -71,6 +73,7 @@ import com.google.common.base.Supplier;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
+import com.google.common.util.concurrent.Uninterruptibles;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
@@ -103,6 +106,9 @@ public class BaseVirtualBoxClientLiveTest extends BaseComputeServiceContextLiveT
@Inject
protected MachineUtils machineUtils;
+
+ @Inject
+ protected NetworkUtils networkUtils;
protected String hostVersion;
protected String operatingSystemIso;
@@ -155,10 +161,7 @@ public class BaseVirtualBoxClientLiveTest extends BaseComputeServiceContextLiveT
int attempts = 0;
while (attempts < 10 && !vm.getSessionState().equals(SessionState.Unlocked)) {
attempts++;
- try {
- Thread.sleep(200l);
- } catch (InterruptedException e) {
- }
+ Uninterruptibles.sleepUninterruptibly(200, TimeUnit.MILLISECONDS);
}
machineUtils.applyForMachine(vmNameOrId, new UnregisterMachineIfExistsAndDeleteItsMedia(vmSpec));
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxExperimentLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxExperimentLiveTest.java
index fa5e67a83f..8a06eee51c 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxExperimentLiveTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxExperimentLiveTest.java
@@ -36,6 +36,7 @@ import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
+import org.jclouds.scriptbuilder.statements.login.AdminAccess;
import org.jclouds.ssh.SshClient;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
@@ -50,7 +51,7 @@ import com.google.inject.Module;
*
* @author Adrian Cole
*/
-@Test(groups = "live", singleThreaded = true, testName = "VirtualBoxExperimentLiveTest")
+@Test(groups = "live", testName = "VirtualBoxExperimentLiveTest")
public class VirtualBoxExperimentLiveTest extends BaseVirtualBoxClientLiveTest {
@Resource
@@ -71,7 +72,7 @@ public class VirtualBoxExperimentLiveTest extends BaseVirtualBoxClientLiveTest {
int numNodes = 3;
final String clusterName = "test-launch-cluster";
Set extends NodeMetadata> nodes = context.getComputeService().createNodesInGroup(clusterName, numNodes,
- TemplateOptions.Builder.overrideLoginUser("toor")); //TODO runScript(AdminAccess.standard()));
+ TemplateOptions.Builder.overrideLoginUser("toor").runScript(AdminAccess.standard()));
assertEquals(numNodes, nodes.size(), "wrong number of nodes");
for (NodeMetadata node : nodes) {
assertTrue(node.getGroup().equals("test-launch-cluster"));
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadataTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadataTest.java
index 5a0167a14a..274c28c45c 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadataTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadataTest.java
@@ -30,7 +30,7 @@ import static org.testng.Assert.assertEquals;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.virtualbox.config.VirtualBoxComputeServiceContextModule;
-import org.jclouds.virtualbox.util.MachineUtils;
+import org.jclouds.virtualbox.util.NetworkUtils;
import org.testng.annotations.Test;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.INATEngine;
@@ -64,18 +64,18 @@ public class IMachineToNodeMetadataTest {
expect(natEng.getRedirects()).andReturn(ImmutableList.of("0,1,127.0.0.1,2222,,22"));
INetworkAdapter hostOnly = createNiceMock(INetworkAdapter.class);
- MachineUtils machineUtils = createNiceMock(MachineUtils.class);
+ NetworkUtils networkUtils = createNiceMock(NetworkUtils.class);
- replay(vm, nat, natEng, hostOnly, machineUtils);
+ replay(vm, nat, natEng, hostOnly, networkUtils);
NodeMetadata node = new IMachineToNodeMetadata(VirtualBoxComputeServiceContextModule.toPortableNodeStatus,
- machineUtils).apply(vm);
+ networkUtils).apply(vm);
assertEquals(MASTER_NAME, node.getName());
assertEquals(1, node.getPrivateAddresses().size());
assertEquals(1, node.getPublicAddresses().size());
assertEquals("127.0.0.1", Iterables.get(node.getPublicAddresses(), 0));
- assertEquals(MastersLoadingCache.MASTER_PORT, node.getLoginPort());
+ assertEquals(NetworkUtils.MASTER_PORT, node.getLoginPort());
assertEquals("", node.getGroup());
}
@@ -103,12 +103,12 @@ public class IMachineToNodeMetadataTest {
expect(nat.getNatDriver()).andReturn(natEng).anyTimes();
expect(natEng.getHostIP()).andReturn("127.0.0.1").once();
expect(natEng.getRedirects()).andReturn(ImmutableList.of("0,1,127.0.0.1,3000,,22"));
- MachineUtils machineUtils = createNiceMock(MachineUtils.class);
+ NetworkUtils networkUtils = createNiceMock(NetworkUtils.class);
- replay(vm, nat, natEng, hostOnly, machineUtils);
+ replay(vm, nat, natEng, hostOnly, networkUtils);
NodeMetadata node = new IMachineToNodeMetadata(VirtualBoxComputeServiceContextModule.toPortableNodeStatus,
- machineUtils).apply(vm);
+ networkUtils).apply(vm);
assertEquals(name, node.getName());
assertEquals(group, node.getGroup());
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/ImageFromYamlStringTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/ImageFromYamlStringTest.java
index 843071ad80..0e4b3ef2f8 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/ImageFromYamlStringTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/ImageFromYamlStringTest.java
@@ -41,11 +41,11 @@ import com.google.common.collect.Iterables;
public class ImageFromYamlStringTest {
public static final Image TEST1 = new ImageBuilder()
- .id("ubuntu-11.04-i386")
- .name("ubuntu-11.04-server-i386")
- .description("ubuntu 11.04 server (i386)")
+ .id("ubuntu-10.04.4-server-i386")
+ .name("ubuntu-10.04-server-i386")
+ .description("ubuntu")
.operatingSystem(
- OperatingSystem.builder().description("ubuntu").family(OsFamily.UBUNTU).version("11.04")
+ OperatingSystem.builder().description("ubuntu").family(OsFamily.UBUNTU).version("10.04.4")
.arch("x86").build())
.status(Image.Status.AVAILABLE).build();
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/GuestAdditionsInstallerLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/GuestAdditionsInstallerLiveTest.java
index b21ce39586..13514c8af3 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/GuestAdditionsInstallerLiveTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/GuestAdditionsInstallerLiveTest.java
@@ -39,8 +39,7 @@ import org.jclouds.virtualbox.domain.VmSpec;
import org.jclouds.virtualbox.functions.CloneAndRegisterMachineFromIMachineIfNotAlreadyExists;
import org.jclouds.virtualbox.functions.CreateAndInstallVm;
import org.jclouds.virtualbox.functions.IMachineToSshClient;
-import org.jclouds.virtualbox.functions.IpAddressesLoadingCache;
-import org.jclouds.virtualbox.util.MachineUtils;
+import org.jclouds.virtualbox.util.NetworkUtils;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.virtualbox_4_1.CleanupMode;
@@ -57,7 +56,7 @@ import com.google.inject.Injector;
/**
* @author Andrea Turli
*/
-@Test(groups = "live", singleThreaded = true, testName = "GuestAdditionsInstallerLiveTest")
+@Test(groups = "live", singleThreaded = true, testName = "GuestAdditionsInstallerLiveTest", enabled=false)
public class GuestAdditionsInstallerLiveTest extends BaseVirtualBoxClientLiveTest {
private Injector injector;
@@ -65,7 +64,6 @@ public class GuestAdditionsInstallerLiveTest extends BaseVirtualBoxClientLiveTes
private Predicate sshResponds;
private MasterSpec machineSpec;
- private IpAddressesLoadingCache ipAddressesLoadingCache;
@Override
@BeforeClass(groups = "live")
@@ -117,9 +115,8 @@ public class GuestAdditionsInstallerLiveTest extends BaseVirtualBoxClientLiveTes
sshResponds = injector.getInstance(SshResponds.class);
checkState(sshResponds.apply(client), "timed out waiting for guest %s to be accessible via ssh",
machine.getName());
- ipAddressesLoadingCache = injector.getInstance(IpAddressesLoadingCache.class);
- assertTrue(MachineUtils.isIpv4(ipAddressesLoadingCache.apply(machine.getName())));
+ assertTrue(NetworkUtils.isIpv4(networkUtils.getIpAddressFromNicSlot(machine.getName(), 0l)));
} finally {
for (String vmNameOrId : ImmutableSet.of(machine.getName())) {
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/statements/InstallGuestAdditionsLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/statements/InstallGuestAdditionsLiveTest.java
index dff4c41464..e9993057a0 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/statements/InstallGuestAdditionsLiveTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/statements/InstallGuestAdditionsLiveTest.java
@@ -45,13 +45,7 @@ public class InstallGuestAdditionsLiveTest extends BaseVirtualBoxClientLiveTest
InstallGuestAdditions installer = new InstallGuestAdditions(vmSpecification, "4.1.8");
String scripts = installer.render(OsFamily.UNIX);
assertEquals("installModuleAssistantIfNeeded || return 1\n" + "mount -t iso9660 /dev/sr1 /mnt\n"
- + "/mnt/VBoxLinuxAdditions.run\n"
- + "service vboxadd setup\n"
- + "VBoxService\n"
- + "echo VBoxService > /etc/rc.local\n"
- + "echo exit 0 >> /etc/rc.local\n"
- + "umount /mnt\n"
- , scripts);
+ + "/mnt/VBoxLinuxAdditions.run --nox11\n", scripts);
}
public void testIsoNotPresent() {
@@ -67,12 +61,7 @@ public class InstallGuestAdditionsLiveTest extends BaseVirtualBoxClientLiveTest
+ "setupPublicCurl || return 1\n"
+ "(mkdir -p /tmp/ && cd /tmp/ && [ ! -f VBoxGuestAdditions_4.1.8.iso ] && curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -C - -X GET http://download.virtualbox.org/virtualbox/4.1.8/VBoxGuestAdditions_4.1.8.iso >VBoxGuestAdditions_4.1.8.iso)\n"
+ "mount -o loop /tmp/VBoxGuestAdditions_4.1.8.iso /mnt\n"
- + "/mnt/VBoxLinuxAdditions.run\n"
- + "service vboxadd setup\n"
- + "VBoxService\n"
- + "echo VBoxService > /etc/rc.local\n"
- + "echo exit 0 >> /etc/rc.local\n"
- + "umount /mnt\n", scripts);
+ + "/mnt/VBoxLinuxAdditions.run --nox11\n", scripts);
}
}
\ No newline at end of file
diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/util/MachineUtilsLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/util/MachineUtilsLiveTest.java
index 39bac6d52f..af69bc2732 100644
--- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/util/MachineUtilsLiveTest.java
+++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/util/MachineUtilsLiveTest.java
@@ -18,9 +18,11 @@
*/
package org.jclouds.virtualbox.util;
+
import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
+import static org.testng.AssertJUnit.assertTrue;
import org.jclouds.config.ValueOfConfigurationKeyOrNull;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
@@ -35,20 +37,17 @@ import org.jclouds.virtualbox.domain.StorageController;
import org.jclouds.virtualbox.domain.VmSpec;
import org.jclouds.virtualbox.functions.CloneAndRegisterMachineFromIMachineIfNotAlreadyExists;
import org.jclouds.virtualbox.functions.CreateAndInstallVm;
-import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.ISession;
-import org.virtualbox_4_1.LockType;
import org.virtualbox_4_1.NetworkAttachmentType;
import org.virtualbox_4_1.SessionState;
import org.virtualbox_4_1.StorageBus;
import com.google.common.base.CaseFormat;
import com.google.common.base.Function;
-import com.google.common.collect.ImmutableSet;
import com.google.inject.Injector;
@Test(groups = "live", testName = "MachineControllerLiveTest")
@@ -62,62 +61,134 @@ public class MachineUtilsLiveTest extends BaseVirtualBoxClientLiveTest {
public void setupContext() {
super.setupContext();
instanceName = VIRTUALBOX_IMAGE_PREFIX
- + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass().getSimpleName());
+ + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass().getSimpleName());
StorageController ideController = StorageController
- .builder()
- .name("IDE Controller")
- .bus(StorageBus.IDE)
- .attachISO(0, 0, operatingSystemIso)
- .attachHardDisk(
- HardDisk.builder().diskpath(adminDisk(instanceName)).controllerPort(0).deviceSlot(1)
- .autoDelete(true).build()).attachISO(1, 1, guestAdditionsIso).build();
+ .builder()
+ .name("IDE Controller")
+ .bus(StorageBus.IDE)
+ .attachISO(0, 0, operatingSystemIso)
+ .attachHardDisk(
+ HardDisk.builder().diskpath(adminDisk(instanceName)).controllerPort(0).deviceSlot(1).autoDelete(true)
+ .build()).attachISO(1, 1, guestAdditionsIso).build();
VmSpec instanceVmSpec = VmSpec.builder().id(instanceName).name(instanceName).osTypeId("").memoryMB(512)
- .cleanUpMode(CleanupMode.Full).controller(ideController).forceOverwrite(true).build();
+ .cleanUpMode(CleanupMode.Full).controller(ideController).forceOverwrite(true).build();
Injector injector = view.utils().injector();
Function configProperties = injector.getInstance(ValueOfConfigurationKeyOrNull.class);
IsoSpec isoSpec = IsoSpec
- .builder()
- .sourcePath(operatingSystemIso)
- .installationScript(
- configProperties.apply(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE).replace("HOSTNAME",
- instanceVmSpec.getVmName())).build();
+ .builder()
+ .sourcePath(operatingSystemIso)
+ .installationScript(
+ configProperties.apply(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE).replace("HOSTNAME",
+ instanceVmSpec.getVmName())).build();
NetworkAdapter networkAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.NAT)
- .tcpRedirectRule("127.0.0.1", 2222, "", 22).build();
+ .tcpRedirectRule("127.0.0.1", 2222, "", 22).build();
NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(networkAdapter)
- .build();
+ .build();
NetworkSpec networkSpec = NetworkSpec.builder().addNIC(networkInterfaceCard).build();
machineSpec = MasterSpec.builder().iso(isoSpec).vm(instanceVmSpec).network(networkSpec).build();
}
- @Test
- public void lockSessionOnMachine() {
- IMachine machine = cloneFromMaster();
- ISession session = machineUtils.lockSessionOnMachineAndApply(instanceName, LockType.Shared,
- new Function() {
+ @Test(description = "write lock is acquired and released correctly")
+ public void writeLockSessionOnMachine() {
+ final IMachine clone = cloneFromMaster();
+ ISession session = machineUtils.writeLockMachineAndApplyToSession(clone.getName(),
+ new Function() {
+ @Override
+ public ISession apply(ISession session) {
+ assertTrue(session.getMachine().getName().equals(clone.getName()));
+ return session;
+ }
+ });
+ checkState(session.getState().equals(SessionState.Unlocked));
+ undoVm(clone.getName());
+ }
+ @Test(dependsOnMethods="writeLockSessionOnMachine", description = "shared lock is acquired and released correctly")
+ public void sharedLockSessionOnMachine() {
+ final IMachine clone = cloneFromMaster();
+ ISession session = machineUtils.sharedLockMachineAndApplyToSession(clone.getName(),
+ new Function() {
+ @Override
+ public ISession apply(ISession session) {
+ assertTrue(session.getMachine().getName().equals(clone.getName()));
+ return session;
+ }
+ });
+ checkState(session.getState().equals(SessionState.Unlocked));
+ undoVm(clone.getName());
+ }
+
+ @Test(dependsOnMethods="sharedLockSessionOnMachine", description = "shared lock can be acquired after a write lock")
+ public void sharedLockCanBeAcquiredAfterWriteLockSessionOnMachine() {
+ final IMachine clone = cloneFromMaster();
+ try {
+ ISession writeSession = machineUtils.writeLockMachineAndApplyToSession(clone.getName(),
+ new Function() {
@Override
- public ISession apply(ISession session) {
- return session;
+ public ISession apply(ISession writeSession) {
+ checkState(writeSession.getState().equals(SessionState.Locked));
+ //ISession sharedSession = sharedSession(clone);
+ return writeSession;
}
});
- checkState(session.getState().equals(SessionState.Unlocked));
- machine = manager.get().getVBox().findMachine(instanceName);
- undoVm(instanceName);
-
+ checkState(writeSession.getState().equals(SessionState.Unlocked));
+ } finally {
+ undoVm(clone.getName());
+ }
+ }
+
+ private ISession sharedSession(final IMachine clone) {
+ ISession sharedSession = machineUtils.sharedLockMachineAndApplyToSession(clone.getName(),
+ new Function() {
+ @Override
+ public ISession apply(ISession sharedSession) {
+ checkState(sharedSession.getState().equals(SessionState.Locked));
+ assertTrue(sharedSession.getMachine().getName().equals(clone.getName()));
+ return sharedSession;
+ }
+ });
+ return sharedSession;
+ }
+
+ @Test(dependsOnMethods="sharedLockCanBeAcquiredAfterWriteLockSessionOnMachine", description = "write lock cannot be acquired after a shared lock")
+ public void writeLockCannotBeAcquiredAfterSharedLockSessionOnMachine() {
+ final IMachine clone = cloneFromMaster();
+ try {
+ ISession sharedSession = machineUtils.sharedLockMachineAndApplyToSession(clone.getName(),
+ new Function() {
+ @Override
+ public ISession apply(ISession sharedSession) {
+ checkState(sharedSession.getState().equals(SessionState.Locked));
+ return sharedSession;
+ }
+ });
+ checkState(sharedSession.getState().equals(SessionState.Unlocked));
+ ISession writeSession = machineUtils.writeLockMachineAndApplyToSession(clone.getName(),
+ new Function() {
+ @Override
+ public ISession apply(ISession writeSession) {
+ checkState(writeSession.getState().equals(SessionState.Locked));
+ assertTrue(writeSession.getMachine().getName().equals(clone.getName()));
+ return writeSession;
+ }
+ });
+ checkState(writeSession.getState().equals(SessionState.Unlocked));
+ } finally {
+ undoVm(clone.getName());
+ }
}
-
private IMachine cloneFromMaster() {
IMachine source = getVmWithGuestAdditionsInstalled();
CloneSpec cloneSpec = CloneSpec.builder().vm(machineSpec.getVmSpec()).network(machineSpec.getNetworkSpec())
- .master(source).linked(true).build();
+ .master(source).linked(true).build();
return new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(manager, workingDir, machineUtils)
- .apply(cloneSpec);
+ .apply(cloneSpec);
}
private IMachine getVmWithGuestAdditionsInstalled() {
@@ -130,13 +201,4 @@ public class MachineUtilsLiveTest extends BaseVirtualBoxClientLiveTest {
return manager.get().getVBox().findMachine(masterSpecForTest.getVmSpec().getVmId());
}
}
-
- @Override
- @AfterClass(groups = "live")
- protected void tearDown() throws Exception {
- for (String vmName : ImmutableSet.of(instanceName)) {
- undoVm(vmName);
- }
- super.tearDown();
- }
}
diff --git a/labs/virtualbox/src/test/resources/default-images.yaml b/labs/virtualbox/src/test/resources/default-images.yaml
index fddcff3c4a..fe4c0c82d3 100644
--- a/labs/virtualbox/src/test/resources/default-images.yaml
+++ b/labs/virtualbox/src/test/resources/default-images.yaml
@@ -1,4 +1,139 @@
images:
+ - id: ubuntu-10.04.4-server-i386
+ name: ubuntu-10.04-server-i386
+ description: ubuntu 10.04.4 server (i386)
+ os_arch: x86
+ os_family: ubuntu
+ os_description: ubuntu
+ os_version: 10.04.4
+ iso: http://releases.ubuntu.com/10.04.4/ubuntu-10.04.4-server-i386.iso
+ iso_md5: fc08a01e78348e3918180ea91a6883bb
+ username: toor
+ credential: password
+ keystroke_sequence: |
+
+ /install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg
+ debian-installer=en_US auto locale=en_US kbd-chooser/method=us
+ hostname=vmName
+ fb=false debconf/frontend=noninteractive
+ console-setup/ask_detect=false console-setup/modelcode=pc105 console-setup/layoutcode=us
+ initrd=/install/initrd.gz --
+ preseed_cfg: |
+ ## Options to set on the command line
+ d-i debian-installer/locale string en_US
+ d-i console-setup/ask_detect boolean false
+ d-i console-setup/layoutcode string us
+ d-i netcfg/get_hostname string unassigned-hostname
+ d-i netcfg/get_domain string unassigned-domain
+ d-i time/zone string UTC
+ d-i clock-setup/utc-auto boolean true
+ d-i clock-setup/utc boolean true
+ d-i kbd-chooser/method select American English
+ d-i netcfg/wireless_wep string
+ d-i base-installer/kernel/override-image string linux-server
+ d-i debconf debconf/frontend select Noninteractive
+ d-i pkgsel/install-language-support boolean false
+ tasksel tasksel/first multiselect standard, ubuntu-server
+ d-i partman-auto/method string lvm
+ #d-i partman-auto/purge_lvm_from_device boolean true
+ d-i partman-lvm/confirm boolean true
+ d-i partman-lvm/device_remove_lvm boolean true
+ d-i partman-auto/choose_recipe select atomic
+ d-i partman/confirm_write_new_label boolean true
+ d-i partman/confirm_nooverwrite boolean true
+ d-i partman/choose_partition select finish
+ d-i partman/confirm boolean true
+ # Write the changes to disks and configure LVM?
+ d-i partman-lvm/confirm boolean true
+ d-i partman-lvm/confirm_nooverwrite boolean true
+ d-i partman-auto-lvm/guided_size string max
+ ## Default user, we can get away with a recipe to change this
+ d-i passwd/user-fullname string toor
+ d-i passwd/username string toor
+ d-i passwd/user-password password password
+ d-i passwd/user-password-again password password
+ d-i user-setup/encrypt-home boolean false
+ d-i user-setup/allow-password-weak boolean true
+ d-i pkgsel/include string openssh-server ntp
+ # Whether to upgrade packages after debootstrap.
+ # Allowed values: none, safe-upgrade, full-upgrade
+ d-i pkgsel/upgrade select full-upgrade
+ d-i grub-installer/only_debian boolean true
+ d-i grub-installer/with_other_os boolean true
+ d-i finish-install/reboot_in_progress note
+ #For the update
+ d-i pkgsel/update-policy select none
+ # debconf-get-selections --install
+ #Use mirror
+ choose-mirror-bin mirror/http/proxy string
+ - id: ubuntu-10.04.4-server-amd64
+ name: ubuntu-10.04-server-amd64
+ description: ubuntu 10.04.4 server (amd64)
+ os_arch: amd64
+ os_family: ubuntu
+ os_description: ubuntu
+ os_version: 10.04.4
+ os_64bit: true
+ iso: http://releases.ubuntu.com/10.04.4/ubuntu-10.04.4-server-amd64.iso
+ iso_md5: 9b218654cdcdf9722171648c52f8a088
+ username: toor
+ credential: password
+ keystroke_sequence: |
+
+ /install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg
+ debian-installer=en_US auto locale=en_US kbd-chooser/method=us
+ hostname=vmName
+ fb=false debconf/frontend=noninteractive
+ console-setup/ask_detect=false console-setup/modelcode=pc105 console-setup/layoutcode=us
+ initrd=/install/initrd.gz --
+ preseed_cfg: |
+ ## Options to set on the command line
+ d-i debian-installer/locale string en_US
+ d-i console-setup/ask_detect boolean false
+ d-i console-setup/layoutcode string us
+ d-i netcfg/get_hostname string unassigned-hostname
+ d-i netcfg/get_domain string unassigned-domain
+ d-i time/zone string UTC
+ d-i clock-setup/utc-auto boolean true
+ d-i clock-setup/utc boolean true
+ d-i kbd-chooser/method select American English
+ d-i netcfg/wireless_wep string
+ d-i base-installer/kernel/override-image string linux-server
+ d-i debconf debconf/frontend select Noninteractive
+ d-i pkgsel/install-language-support boolean false
+ tasksel tasksel/first multiselect standard, ubuntu-server
+ d-i partman-auto/method string lvm
+ #d-i partman-auto/purge_lvm_from_device boolean true
+ d-i partman-lvm/confirm boolean true
+ d-i partman-lvm/device_remove_lvm boolean true
+ d-i partman-auto/choose_recipe select atomic
+ d-i partman/confirm_write_new_label boolean true
+ d-i partman/confirm_nooverwrite boolean true
+ d-i partman/choose_partition select finish
+ d-i partman/confirm boolean true
+ # Write the changes to disks and configure LVM?
+ d-i partman-lvm/confirm boolean true
+ d-i partman-lvm/confirm_nooverwrite boolean true
+ d-i partman-auto-lvm/guided_size string max
+ ## Default user, we can get away with a recipe to change this
+ d-i passwd/user-fullname string toor
+ d-i passwd/username string toor
+ d-i passwd/user-password password password
+ d-i passwd/user-password-again password password
+ d-i user-setup/encrypt-home boolean false
+ d-i user-setup/allow-password-weak boolean true
+ d-i pkgsel/include string openssh-server ntp
+ # Whether to upgrade packages after debootstrap.
+ # Allowed values: none, safe-upgrade, full-upgrade
+ d-i pkgsel/upgrade select full-upgrade
+ d-i grub-installer/only_debian boolean true
+ d-i grub-installer/with_other_os boolean true
+ d-i finish-install/reboot_in_progress note
+ #For the update
+ d-i pkgsel/update-policy select none
+ # debconf-get-selections --install
+ #Use mirror
+ choose-mirror-bin mirror/http/proxy string
- id: ubuntu-11.04-i386
name: ubuntu-11.04-server-i386
description: ubuntu 11.04 server (i386)
@@ -27,7 +162,7 @@ images:
d-i time/zone string UTC
d-i clock-setup/utc-auto boolean true
d-i clock-setup/utc boolean true
- d-i kbd-chooser/method select American English
+ d-i kbd-chooser/method select American English
d-i netcfg/wireless_wep string
d-i base-installer/kernel/override-image string linux-server
# Choices: Dialog, Readline, Gnome, Kde, Editor, Noninteractive
@@ -143,6 +278,8 @@ images:
os_64bit: true
iso: http://releases.ubuntu.com/12.04/ubuntu-12.04.1-server-amd64.iso
iso_md5: a8c667e871f48f3a662f3fbf1c3ddb17
+ username: toor
+ credential: password
keystroke_sequence: |
/install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg
diff --git a/labs/virtualbox/src/test/resources/logback.xml b/labs/virtualbox/src/test/resources/logback.xml
index 3a5a73c80d..26f517de96 100644
--- a/labs/virtualbox/src/test/resources/logback.xml
+++ b/labs/virtualbox/src/test/resources/logback.xml
@@ -42,6 +42,11 @@
+
+
+
+
+