diff --git a/labs/virtualbox/README.md b/labs/virtualbox/README.md
index 9b7e26d86a..b618fa9d92 100644
--- a/labs/virtualbox/README.md
+++ b/labs/virtualbox/README.md
@@ -1,11 +1,19 @@
#Setup
-Have virtualbox 4.1.8 installed.
+Have virtualbox 4.1.20r80170 installed.
Have an ssh daemon with passwordless login to localhost (i.e. "ssh [me]@localhost" must work without password).
+To achieve that, be sure you have your ssh public key (at System.getProperty("user.home") + "/.ssh/id_rsa") in your '.ssh/authorized_keys'.
+Please look at [this example]http://www.linuxproblem.org/art_9.html for more details.
-That's it!
+You can have also specify '-Dvirtualbox.identity' and '-Dvirtualbox.credential' if you want to use a username and password of your local machine.
+
+In order to make available a preseed file, jclouds-vbox will start a PreseedServer at `http://localhost:23232` that will serve a preseed.cfg file.
+Make sure your firewall rules are not blocking this port.
+If you need to override this default you can use -Djclouds.virtualbox.preconfigurationurl=http://localhost:PORT/preseed.cfg, with a different PORT.
+
+That's it!
--------------
@@ -17,7 +25,7 @@ Enjoy local cloud goodness by running:
> (use 'org.jclouds.compute2)
> (import 'org.jclouds.scriptbuilder.statements.login.AdminAccess)
-> (def compute (compute-service "virtualbox" "admin" "12345" :sshj :slf4j))
+> (def compute (compute-service "virtualbox" "user" "password" :sshj :slf4j))
> (create-nodes compute "local-cluster" 2 (build-template compute { :run-script (AdminAccess/standard) } ))
--------------
@@ -39,8 +47,8 @@ It *should* behave as any other provider, if not please report.
- jclouds-vbox is still at alpha stage please report any issues you find.
- jclouds-vbox has been mostly tested on Mac OSX, it might work on Linux iff vbox is running and correctly set up, but it won't work on windows for the moment.
-- cached isos, vm's and most configs are kept at ~/.jclouds-vbox/ by default.
-- jclouds-vbox assumes vbox has the default host-only network vboxnet0, that the network is in 192.168.86.0/255.255.255.0 and that the host has address 1 in this network.
+- cached isos, vm's and most configs are kept at ~/.jclouds-vbox/ by default, you can override -Dtest.virtualbox.workingDir=/path/to/your/workingDir.
+- jclouds-vbox assumes vbox has the default host-only network vboxnet0, that the network is in 192.168.86.0/255.255.255.0 and that the host has address 1 in this network.
--------------
diff --git a/labs/virtualbox/pom.xml b/labs/virtualbox/pom.xml
index 820018decf..27c6c93b52 100644
--- a/labs/virtualbox/pom.xml
+++ b/labs/virtualbox/pom.xml
@@ -37,10 +37,10 @@
http://localhost:18083/
4.1.4
- 4.1.8r75467
+ 4.1.20r80170
administrator
- 12345
- imageId=test-ubuntu-11.10-i386,loginUser=toor:password,authenticateSudo=true
+ CHANGE_ME
+ osFamily=UBUNTU,osVersionMatches=12.04.1,os64Bit=true,osArchMatches=amd64,loginUser=toor:password,authenticateSudo=true
org.jclouds.virtualbox*;version="${project.version}"
org.jclouds*;version="${project.version}",*
@@ -136,6 +136,7 @@
1
+ false
${test.virtualbox.endpoint}
${test.virtualbox.api-version}
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxApiMetadata.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxApiMetadata.java
index f7c1b7fef9..6fd60045c8 100644
--- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxApiMetadata.java
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxApiMetadata.java
@@ -20,6 +20,8 @@ package org.jclouds.virtualbox;
import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_DIR;
+import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_GUEST_CREDENTIAL;
+import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_GUEST_IDENTITY;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGES_DESCRIPTOR;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_PRECONFIGURATION_URL;
@@ -81,7 +83,13 @@ public class VirtualBoxApiMetadata extends BaseApiMetadata {
properties.put(VIRTUALBOX_IMAGES_DESCRIPTOR, yamlDescriptor);
properties.put(VIRTUALBOX_PRECONFIGURATION_URL, "http://10.0.2.2:23232/preseed.cfg");
- properties.setProperty(TEMPLATE, "osFamily=UBUNTU,osVersionMatches=11.10,os64Bit=true,osArchMatches=x86,loginUser=toor:password,authenticateSudo=true");
+
+ properties.put(VIRTUALBOX_GUEST_IDENTITY, "toor");
+ properties.put(VIRTUALBOX_GUEST_CREDENTIAL, "password");
+ properties.setProperty(TEMPLATE,
+ String.format("osFamily=UBUNTU,osVersionMatches=12.04.1,os64Bit=true,osArchMatches=amd64,loginUser=%s:%s,authenticateSudo=true",
+ properties.getProperty(VIRTUALBOX_GUEST_IDENTITY),
+ properties.getProperty(VIRTUALBOX_GUEST_CREDENTIAL)));
return properties;
}
@@ -93,8 +101,8 @@ public class VirtualBoxApiMetadata extends BaseApiMetadata {
.identityName("User")
.credentialName("Password")
.documentation(URI.create("https://www.virtualbox.org/sdkref/index.html"))
- .defaultIdentity("administrator")
- .defaultCredential("12345")
+ .defaultIdentity(System.getProperty("user.name"))
+ .defaultCredential("CHANGE_ME")
.defaultEndpoint("http://localhost:18083/")
.documentation(URI.create("https://github.com/jclouds/jclouds/tree/master/apis/byon"))
// later version not in maven, yet
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/HardcodeLocalhostAsNodeMetadataSupplier.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/HardcodeLocalhostAsNodeMetadataSupplier.java
index 814a6c9c1f..ce598d4037 100644
--- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/HardcodeLocalhostAsNodeMetadataSupplier.java
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/HardcodeLocalhostAsNodeMetadataSupplier.java
@@ -35,6 +35,7 @@ import org.jclouds.domain.LocationScope;
import org.jclouds.domain.LoginCredentials;
import com.google.common.base.Charsets;
+import com.google.common.base.Strings;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.io.Files;
@@ -79,7 +80,7 @@ import com.google.inject.Provides;
public class HardcodeLocalhostAsNodeMetadataSupplier extends AbstractModule {
public static final String HOST_ID = "host";
- public static final String HOSTNAME = System.getenv("HOSTNAME");
+ public static final String HOSTNAME = Strings.nullToEmpty(System.getenv("HOSTNAME"));
/**
* Lazy so that we don't hang up the injector reading a file
@@ -91,9 +92,7 @@ public class HardcodeLocalhostAsNodeMetadataSupplier extends AbstractModule {
@Override
public NodeMetadata get() {
-
String privateKey = readRsaIdentity();
-
return new NodeMetadataBuilder()
.id(HOST_ID)
.name("host installing virtualbox")
@@ -110,9 +109,9 @@ public class HardcodeLocalhostAsNodeMetadataSupplier extends AbstractModule {
.description(HOSTNAME)
.build())
.credentials(LoginCredentials.builder()
- .user(System.getProperty("user.name"))
- .privateKey(privateKey)
- .build())
+ .user(System.getProperty("user.name"))
+ .privateKey(privateKey)
+ .build())
.build();
}
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java
index 7fe2b90c26..d65bd8584b 100644
--- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java
@@ -150,7 +150,10 @@ public class VirtualBoxComputeServiceContextModule extends
@Override
public VirtualBoxManager apply(Supplier nodeSupplier) {
- return VirtualBoxManager.createInstance(nodeSupplier.get().getId());
+ if(nodeSupplier.get().getId() != null)
+ return VirtualBoxManager.createInstance(nodeSupplier.get().getId());
+
+ return VirtualBoxManager.createInstance("");
}
@Override
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxConstants.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxConstants.java
index 46a6e67ac5..e0c8442435 100644
--- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxConstants.java
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxConstants.java
@@ -61,5 +61,8 @@ public interface VirtualBoxConstants {
+ ".jclouds-vbox";
public static final String VIRTUALBOX_PROVIDER = "virtualbox";
+
+ public static final String VIRTUALBOX_GUEST_IDENTITY = "jclouds.virtualbox.guest.identity";
+ public static final String VIRTUALBOX_GUEST_CREDENTIAL = "jclouds.virtualbox.guest.credential";
}
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/YamlImage.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/YamlImage.java
index bff48a2632..8a45140ffa 100644
--- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/YamlImage.java
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/YamlImage.java
@@ -118,6 +118,7 @@ public class YamlImage {
public String os_family;
public String os_description;
public String os_version;
+ public String iso_md5;
public String iso;
public String keystroke_sequence;
public String preseed_cfg;
@@ -154,7 +155,7 @@ public class YamlImage {
public String toString() {
return "YamlImage [id=" + id + ", name=" + name + ", description=" + description + ", hostname=" + hostname
+ ", location_id=" + location_id + ", os_arch=" + os_arch + ", os_family=" + os_family
- + ", os_description=" + os_description + ", os_version=" + os_version + ", iso=" + iso
+ + ", os_description=" + os_description + ", os_version=" + os_version + ", iso=" + iso
+ ", keystroke_sequence=" + keystroke_sequence + ", preseed_cfg=" + preseed_cfg + ", login_port="
+ login_port + ", os_64bit=" + os_64bit + ", group=" + group + ", tags=" + tags + ", metadata="
+ metadata + ", username=" + username + ", credential=" + credential + ", credential_url="
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.java
index 46521df88a..0985deb519 100644
--- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.java
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.java
@@ -21,6 +21,7 @@ package org.jclouds.virtualbox.functions;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.locks.ReentrantLock;
import javax.annotation.Resource;
import javax.inject.Named;
@@ -60,6 +61,8 @@ public class CloneAndRegisterMachineFromIMachineIfNotAlreadyExists implements Fu
private final Supplier manager;
private final String workingDir;
private final MachineUtils machineUtils;
+
+ private final ReentrantLock lock = new ReentrantLock();
@Inject
public CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(Supplier manager,
@@ -104,15 +107,13 @@ public class CloneAndRegisterMachineFromIMachineIfNotAlreadyExists implements Fu
if (isLinkedClone)
options.add(CloneOptions.Link);
- // TODO snapshot name
- ISnapshot currentSnapshot = new TakeSnapshotIfNotAlreadyAttached(manager, "snapshotName", "snapshotDesc", logger)
- .apply(master);
-
- // clone
- IProgress progress = currentSnapshot.getMachine().cloneTo(clonedMachine, CloneMode.MachineState, options);
-
+ ISnapshot currentSnapshot = new TakeSnapshotIfNotAlreadyAttached(manager,
+ "snapshotName", "snapshotDesc", logger).apply(master);
+ IProgress progress = currentSnapshot.getMachine().cloneTo(clonedMachine,
+ CloneMode.MachineState, options);
progress.waitForCompletion(-1);
- logger.debug(String.format("Machine %s is cloned correctly", clonedMachine.getName()));
+ logger.debug(String.format("Machine %s is cloned correctly",
+ clonedMachine.getName()));
// memory may not be the same as the master vm
clonedMachine.setMemorySize(cloneSpec.getVmSpec().getMemory());
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndInstallVm.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndInstallVm.java
index b359cd47ff..ff013ede56 100644
--- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndInstallVm.java
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndInstallVm.java
@@ -42,7 +42,9 @@ import org.jclouds.virtualbox.domain.VmSpec;
import org.jclouds.virtualbox.statements.InstallGuestAdditions;
import org.jclouds.virtualbox.util.MachineController;
import org.jclouds.virtualbox.util.MachineUtils;
+import org.virtualbox_4_1.DeviceType;
import org.virtualbox_4_1.IMachine;
+import org.virtualbox_4_1.IMediumAttachment;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
@@ -88,19 +90,14 @@ public class CreateAndInstallVm implements Function {
@Override
public IMachine apply(MasterSpec masterSpec) {
-
VmSpec vmSpec = masterSpec.getVmSpec();
IsoSpec isoSpec = masterSpec.getIsoSpec();
String vmName = vmSpec.getVmName();
-
IMachine vm = createAndRegisterMachineFromIsoIfNotAlreadyExists.apply(masterSpec);
-
// Launch machine and wait for it to come online
machineController.ensureMachineIsLaunched(vmName);
-
String installationKeySequence = isoSpec.getInstallationKeySequence().replace("PRECONFIGURATION_URL",
preconfigurationUrl);
-
configureOsInstallationWithKeyboardSequence(vmName, installationKeySequence);
// the OS installation is a long process: let's delay the check for ssh of 30 sec
@@ -111,11 +108,8 @@ public class CreateAndInstallVm implements Function {
}
SshClient client = sshClientForIMachine.apply(vm);
-
logger.debug(">> awaiting installation to finish node(%s)", vmName);
-
checkState(sshResponds.apply(client), "timed out waiting for guest %s to be accessible via ssh", vmName);
-
NodeMetadata nodeMetadata = imachineToNodeMetadata.apply(vm);
logger.debug(">> awaiting post-installation actions on vm: %s", vmName);
@@ -129,9 +123,17 @@ public class CreateAndInstallVm implements Function {
new InstallGuestAdditions(vmSpec, version), RunScriptOptions.NONE);
ExecResponse gaInstallationResponse = Futures.getUnchecked(execInstallGA);
checkState(gaInstallationResponse.getExitStatus() == 0);
-
machineController.ensureMachineIsShutdown(vmName);
-
+ Iterable mediumAttachments = Iterables.filter(vm.getMediumAttachmentsOfController("IDE Controller"),
+ new Predicate() {
+ public boolean apply(IMediumAttachment in) {
+ return in.getMedium() != null && in.getMedium().getDeviceType().equals(DeviceType.DVD);
+ }
+ });
+ for (IMediumAttachment iMediumAttachment : mediumAttachments) {
+ machineUtils.writeLockMachineAndApply(vm.getName(), new DetachDistroMediumFromMachine(
+ iMediumAttachment.getController(), iMediumAttachment.getPort(), iMediumAttachment.getDevice()));
+ }
return vm;
}
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/HardcodedHostToHostNodeMetadata.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/HardcodedHostToHostNodeMetadata.java
new file mode 100644
index 0000000000..8f09c67d22
--- /dev/null
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/HardcodedHostToHostNodeMetadata.java
@@ -0,0 +1,83 @@
+/**
+ * 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.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.net.URI;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.Provider;
+import org.jclouds.logging.Logger;
+import org.jclouds.rest.annotations.Credential;
+import org.jclouds.rest.annotations.Identity;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+@Singleton
+public class HardcodedHostToHostNodeMetadata implements
+ Function {
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ private final Supplier providerSupplier;
+ private final String username;
+ private final String password;
+
+ @Inject
+ public HardcodedHostToHostNodeMetadata(
+ @Provider Supplier providerSupplier,
+ @Nullable @Identity String identity,
+ @Nullable @Credential String credential) {
+ this.providerSupplier = checkNotNull(providerSupplier,
+ "endpoint to virtualbox websrvd is needed");
+ this.username = identity;
+ this.password = credential.equals("CHANGE_ME") ? "" : credential;
+ }
+
+ @Override
+ public NodeMetadata apply(NodeMetadata host) {
+
+ LoginCredentials.Builder credentialsBuilder = LoginCredentials.builder(
+ host.getCredentials()).user(username);
+ if (!password.isEmpty())
+ credentialsBuilder.password(password);
+
+ return NodeMetadataBuilder
+ .fromNodeMetadata(host)
+ .credentials(credentialsBuilder.build())
+ .publicAddresses(ImmutableList.of(providerSupplier.get().getHost()))
+ .build();
+ }
+
+}
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadata.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadata.java
index d985d050cd..499fca7da1 100644
--- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadata.java
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadata.java
@@ -46,7 +46,6 @@ import org.virtualbox_4_1.NetworkAttachmentType;
import com.google.common.base.Function;
import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -82,7 +81,6 @@ public class IMachineToNodeMetadata implements Function
NodeMetadataBuilder nodeMetadataBuilder = new NodeMetadataBuilder();
nodeMetadataBuilder.name(name).ids(vm.getName()).group(group);
-
// TODO Set up location properly
LocationBuilder locationBuilder = new LocationBuilder();
locationBuilder.description("");
@@ -96,41 +94,8 @@ public class IMachineToNodeMetadata implements Function
if (nodeState == null)
nodeState = Status.UNRECOGNIZED;
nodeMetadataBuilder.status(nodeState);
-
- /*
- // nat adapter
- INetworkAdapter natAdapter = vm.getNetworkAdapter(0l);
- checkNotNull(natAdapter, "slot 0 networkadapter");
- checkState(natAdapter.getAttachmentType() == NetworkAttachmentType.NAT,
- "expecting slot 0 to be a NAT attachment type (was: " + natAdapter.getAttachmentType() + ")");
-
- int ipTermination = 0;
- int inPort = 0;
- String hostAddress = "";
-
- nodeMetadataBuilder.publicAddresses(ImmutableSet.of(natAdapter.getNatDriver().getHostIP()));
- for (String nameProtocolnumberAddressInboudportGuestTargetport : natAdapter.getNatDriver().getRedirects()) {
- Iterable stuff = Splitter.on(',').split(nameProtocolnumberAddressInboudportGuestTargetport);
- String protocolNumber = Iterables.get(stuff, 1);
- hostAddress = Iterables.get(stuff, 2);
- String inboundPort = Iterables.get(stuff, 3);
- String targetPort = Iterables.get(stuff, 5);
- if ("1".equals(protocolNumber) && "22".equals(targetPort)) {
- inPort = Integer.parseInt(inboundPort);
- ipTermination = inPort % NodeCreator.NODE_PORT_INIT + 2;
- }
- }
-
- // only masters use 2222 port
- if (inPort == MastersLoadingCache.MASTER_PORT) {
- nodeMetadataBuilder.publicAddresses(ImmutableSet.of(hostAddress)).loginPort(inPort);
- } else {
- nodeMetadataBuilder.privateAddresses(ImmutableSet.of((NodeCreator.VMS_NETWORK + ipTermination) + ""));
- nodeMetadataBuilder.publicAddresses(ImmutableSet.of((NodeCreator.VMS_NETWORK + ipTermination) + ""));
- }
- */
-
nodeMetadataBuilder = getIpAddresses(vm, nodeMetadataBuilder);
+
LoginCredentials loginCredentials = new LoginCredentials("toor", "password", null, true);
nodeMetadataBuilder.credentials(loginCredentials);
@@ -144,7 +109,9 @@ public class IMachineToNodeMetadata implements Function
INetworkAdapter adapter = vm.getNetworkAdapter(slot);
if(adapter != null) {
if (adapter.getAttachmentType() == NetworkAttachmentType.NAT) {
- publicIpAddresses.add(adapter.getNatDriver().getHostIP());
+ String hostIP = adapter.getNatDriver().getHostIP();
+ if(!hostIP.isEmpty())
+ publicIpAddresses.add(hostIP);
for (String nameProtocolnumberAddressInboudportGuestTargetport : adapter.getNatDriver().getRedirects()) {
Iterable stuff = Splitter.on(',').split(nameProtocolnumberAddressInboudportGuestTargetport);
String protocolNumber = Iterables.get(stuff, 1);
@@ -153,26 +120,25 @@ public class IMachineToNodeMetadata implements Function
String targetPort = Iterables.get(stuff, 5);
if ("1".equals(protocolNumber) && "22".equals(targetPort)) {
int inPort = Integer.parseInt(inboundPort);
- nodeMetadataBuilder.publicAddresses(ImmutableSet.of(hostAddress)).loginPort(inPort);
+ publicIpAddresses.add(hostAddress);
+ nodeMetadataBuilder.loginPort(inPort);
}
//privateIpAddresses.add((NodeCreator.VMS_NETWORK + ipTermination) + "");
}
// TODO this could be a public and private address
} else if (adapter.getAttachmentType() == NetworkAttachmentType.Bridged) {
- String clientIpAddress = machineUtils.getIpAddressFromBridgedNIC(vm.getName());
+ String clientIpAddress = machineUtils.getIpAddressFromFirstNIC(vm.getName());
//privateIpAddresses.add(clientIpAddress);
publicIpAddresses.add(clientIpAddress);
} else if (adapter.getAttachmentType() == NetworkAttachmentType.HostOnly) {
- String clientIpAddress = machineUtils.getIpAddressFromHostOnlyNIC(vm.getName());
+ String clientIpAddress = machineUtils.getIpAddressFromFirstNIC(vm.getName());
publicIpAddresses.add(clientIpAddress);
-
}
}
}
nodeMetadataBuilder.publicAddresses(publicIpAddresses);
nodeMetadataBuilder.privateAddresses(publicIpAddresses);
-
return nodeMetadataBuilder;
}
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToSshClient.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToSshClient.java
index 3c684152b6..adb15aa207 100644
--- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToSshClient.java
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToSshClient.java
@@ -20,6 +20,8 @@ package org.jclouds.virtualbox.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
+import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_GUEST_CREDENTIAL;
+import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_GUEST_IDENTITY;
import java.util.List;
@@ -35,6 +37,7 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.logging.Logger;
import org.jclouds.ssh.SshClient;
+import org.jclouds.virtualbox.VirtualBoxApiMetadata;
import org.jclouds.virtualbox.domain.BridgedIf;
import org.jclouds.virtualbox.statements.GetIPAddressFromMAC;
import org.jclouds.virtualbox.statements.ScanNetworkWithPing;
@@ -82,10 +85,11 @@ public class IMachineToSshClient implements Function {
String clientIpAddress = null;
String sshPort = "22";
- // TODO: we need a way to align the default login credentials
- // from the iso with the vmspec -> IMachineToNodeMetadata using YamlImage ?
+ String guestIdentity = VirtualBoxApiMetadata.defaultProperties().getProperty(VIRTUALBOX_GUEST_IDENTITY);
+ String guestCredential = VirtualBoxApiMetadata.defaultProperties().getProperty(VIRTUALBOX_GUEST_CREDENTIAL);
LoginCredentials loginCredentials = LoginCredentials.builder()
- .user("toor").password("password").authenticateSudo(true)
+ .user(guestIdentity)
+ .password(guestCredential).authenticateSudo(true)
.build();
if (networkAdapter.getAttachmentType()
@@ -109,7 +113,7 @@ public class IMachineToSshClient implements Function {
clientIpAddress = getIpAddressFromBridgedNIC(networkAdapter, network);
} else if (networkAdapter.getAttachmentType().equals(
NetworkAttachmentType.HostOnly)) {
- clientIpAddress = machineUtils.getIpAddressFromHostOnlyNIC(vm.getName());
+ clientIpAddress = machineUtils.getIpAddressFromFirstNIC(vm.getName());
}
checkNotNull(clientIpAddress, "clientIpAddress");
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IpAddressesLoadingCache.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IpAddressesLoadingCache.java
new file mode 100644
index 0000000000..c45112a6b7
--- /dev/null
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IpAddressesLoadingCache.java
@@ -0,0 +1,95 @@
+/**
+ * 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.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.jclouds.virtualbox.util.MachineUtils;
+import org.virtualbox_4_1.VirtualBoxManager;
+
+import com.google.common.base.Supplier;
+import com.google.common.cache.AbstractLoadingCache;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.Maps;
+
+/**
+ * A {@link LoadingCache} for ip addresses. If the requested ip address has been
+ * previously extracted this returns it, if not it calls vbox api.
+ *
+ * @author andrea turli
+ *
+ */
+@Singleton
+public class IpAddressesLoadingCache extends
+ AbstractLoadingCache {
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ private final Map masters = Maps.newHashMap();
+ private final Supplier manager;
+
+ @Inject
+ public IpAddressesLoadingCache(Supplier manager) {
+ this.manager = checkNotNull(manager, "vboxmanager");
+ }
+
+ @Override
+ public synchronized String get(String idOrName) throws ExecutionException {
+ if (masters.containsKey(idOrName)) {
+ return masters.get(idOrName);
+ }
+
+ String currentIp = "", previousIp = "";
+ int count = 0;
+ while (count < 3) {
+ currentIp = "";
+ while (!MachineUtils.isIpv4(currentIp)) {
+ currentIp = manager.get().getVBox().findMachine(idOrName)
+ .getGuestPropertyValue("/VirtualBox/GuestInfo/Net/0/V4/IP");
+ }
+
+ if (previousIp.equals(currentIp)) {
+ count++;
+ }
+ previousIp = currentIp;
+ }
+
+ masters.put(idOrName, currentIp);
+ return currentIp;
+ }
+
+ @Override
+ public String getIfPresent(Object key) {
+ return masters.get((String) key);
+ }
+
+}
diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/MastersLoadingCache.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/MastersLoadingCache.java
index 42f95069d0..04f6f4d702 100644
--- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/MastersLoadingCache.java
+++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/MastersLoadingCache.java
@@ -22,6 +22,7 @@ package org.jclouds.virtualbox.functions;
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 static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_DIR;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
@@ -32,6 +33,8 @@ import static org.jclouds.virtualbox.util.MachineUtils.machineNotFoundException;
import java.io.File;
import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
@@ -42,10 +45,17 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
+import org.jclouds.compute.callables.RunScriptOnNode.Factory;
+import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.location.Provider;
import org.jclouds.logging.Logger;
import org.jclouds.rest.annotations.BuildVersion;
+import org.jclouds.scriptbuilder.domain.Statement;
+import org.jclouds.scriptbuilder.domain.StatementList;
+import org.jclouds.scriptbuilder.domain.Statements;
import org.jclouds.virtualbox.domain.HardDisk;
import org.jclouds.virtualbox.domain.IsoSpec;
import org.jclouds.virtualbox.domain.Master;
@@ -57,6 +67,8 @@ import org.jclouds.virtualbox.domain.StorageController;
import org.jclouds.virtualbox.domain.VmSpec;
import org.jclouds.virtualbox.domain.YamlImage;
import org.jclouds.virtualbox.functions.admin.PreseedCfgServer;
+import org.jclouds.virtualbox.predicates.RetryIfSocketNotYetOpen;
+import org.testng.collections.Lists;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.NetworkAttachmentType;
@@ -71,178 +83,236 @@ import com.google.common.cache.AbstractLoadingCache;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
+import com.google.common.net.HostAndPort;
/**
- * A {@link LoadingCache} for masters. If the requested master has been previously created this
- * returns it, if not it coordinates its creation including downloading isos and creating
- * cache/config directories. This also implements {@link Supplier} in order to provide jetty with
- * the current image (only one master can be created at a time).
+ * A {@link LoadingCache} for masters. If the requested master has been
+ * previously created this returns it, if not it coordinates its creation
+ * including downloading isos and creating cache/config directories. This also
+ * implements {@link Supplier} in order to provide jetty with the current image
+ * (only one master can be created at a time).
*
- * @author dralves
+ * @author dralves, andrea turli
*
*/
@Singleton
public class MastersLoadingCache extends AbstractLoadingCache {
- // TODO parameterize
- public static final int MASTER_PORT = 2222;
- public static final String HOST_ONLY_IFACE_NAME = "vboxnet0";
+ // TODO parameterize
+ public static final int MASTER_PORT = 2222;
- @Resource
- @Named(ComputeServiceConstants.COMPUTE_LOGGER)
- protected Logger logger = Logger.NULL;
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
- private final Map masters = Maps.newHashMap();
- private final Function masterCreatorAndInstaller;
- private final Map imageMapping;
- private final String workingDir;
- private final String installationKeySequence;
- private final String isosDir;
- private final Supplier manager;
- private final Function isoDownloader;
- private final String version;
- private final String preconfigurationUrl;
+ private final Map masters = Maps.newHashMap();
+ private final Function masterCreatorAndInstaller;
+ private final Map imageMapping;
+ private final String workingDir;
+ private final String installationKeySequence;
+ private final String isosDir;
+ private final Supplier manager;
+ private final String version;
+ private final String preconfigurationUrl;
- @Inject
- public MastersLoadingCache(@BuildVersion String version,
- @Named(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE) String installationKeySequence,
- @Named(VIRTUALBOX_PRECONFIGURATION_URL) String preconfigurationUrl,
- @Named(VIRTUALBOX_WORKINGDIR) String workingDir, Function masterLoader,
- Supplier