issue 384: bridged support

This commit is contained in:
Andrea Turli 2012-03-12 18:57:23 +00:00
parent 67d70fae62
commit d10f45ad46
15 changed files with 796 additions and 285 deletions

View File

@ -0,0 +1,203 @@
/**
* 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.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Objects;
/**
* Name: en1: Wi-Fi (AirPort) GUID: 00316e65-0000-4000-8000-28cfdaf2917a Dhcp:
* Disabled IPAddress: 192.168.57.1 NetworkMask: 255.255.255.0 IPV6Address:
* IPV6NetworkMaskPrefixLength: 0 HardwareAddress: 28:cf:da:f2:91:7a MediumType:
* Ethernet Status: Up VBoxNetworkName: HostInterfaceNetworking-en1: Wi-Fi
* (AirPort)
*
* @author Andrea Turli
*
*/
public class BridgedIf {
private final String name;
private final String guid;
private final String dhcp;
private final String ipAddress;
private final String networkMask;
private final String ipv6Address;
private final String ipv6NetworkMask;
private final String mediumType;
private final String status;
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String name;
private String guid;
private String dhcp;
private String ipAddress;
private String networkMask;
private String ipv6Address;
private String iv6NetworkMask;
private String mediumType;
private String status;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder guid(String guid) {
this.guid = guid;
return this;
}
public Builder dhcp(String dhcp) {
this.dhcp = dhcp;
return this;
}
public Builder ip(String ipAddress) {
this.ipAddress = ipAddress;
return this;
}
public Builder networkMask(String networkMask) {
this.networkMask = networkMask;
return this;
}
public Builder ipv6(String ipv6Address) {
this.ipv6Address = ipv6Address;
return this;
}
public Builder ipv6networkMask(String iv6NetworkMask) {
this.iv6NetworkMask = iv6NetworkMask;
return this;
}
public Builder mediumType(String mediumType) {
this.mediumType = mediumType;
return this;
}
public Builder status(String status) {
this.status = status;
return this;
}
public BridgedIf build() {
return new BridgedIf(name, guid, dhcp, ipAddress, networkMask,
ipv6Address, iv6NetworkMask, mediumType, status);
}
}
public BridgedIf(String name, String guid, String dhcp, String ipAddress,
String networkMask, String ipv6Address, String iv6NetworkMask,
String mediumType, String status) {
this.name = checkNotNull(name, "bridgedIf name");
this.guid = guid;
this.dhcp = dhcp;
this.ipAddress = checkNotNull(ipAddress, "bridgedIf ipAddress");
this.networkMask = networkMask;
this.ipv6Address = ipv6Address;
this.ipv6NetworkMask = iv6NetworkMask;
this.mediumType = mediumType;
this.status = checkNotNull(status, "bridgedIf status");
}
public String getName() {
return name;
}
public String getGuid() {
return guid;
}
public String getDhcp() {
return dhcp;
}
public String getIpAddress() {
return ipAddress;
}
public String getNetworkMask() {
return networkMask;
}
public String getIpv6Address() {
return ipv6Address;
}
public String getIpv6NetworkMask() {
return ipv6NetworkMask;
}
public String getMediumType() {
return mediumType;
}
public String getStatus() {
return status;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o instanceof VmSpec) {
BridgedIf other = (BridgedIf) o;
return Objects.equal(name, other.name)
&& Objects.equal(guid, other.guid)
&& Objects.equal(dhcp, other.dhcp)
&& Objects.equal(ipAddress, other.ipAddress)
&& Objects.equal(networkMask, other.networkMask)
&& Objects.equal(ipv6Address, other.ipv6Address)
&& Objects.equal(ipv6NetworkMask, other.ipv6NetworkMask)
&& Objects.equal(mediumType, other.mediumType)
&& Objects.equal(status, other.status);
}
return false;
}
@Override
public int hashCode() {
return Objects.hashCode(name, guid, dhcp, ipAddress, networkMask, ipv6Address, ipv6NetworkMask, mediumType, status);
}
@Override
public String toString() {
return "BridgedIf{" +
"name=" + name +
", dhcp=" + dhcp +
", ipAddress=" + ipAddress +
", networkMask=" + networkMask +
", ipv6Address=" + ipv6Address +
", ipv6NetworkMask=" + ipv6NetworkMask +
", mediumType=" + mediumType +
", status=" + status +
'}';
}
}

View File

@ -117,6 +117,6 @@ public class CloneSpec {
@Override
public String toString() {
return "IMachineSpec{" + "vmSpec= " + vmSpec + ", networkSpec= " + networkSpec + '}';
return "CloneSpec{" + "vmSpec= " + vmSpec + ", networkSpec= " + networkSpec + '}';
}
}

View File

@ -0,0 +1,100 @@
/**
* 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 javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.virtualbox.domain.BridgedIf;
import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
@Singleton
public class BridgedIfStringToBridgedIf implements Function<String, BridgedIf> {
private static final String BRIDGED_IF_STATUS = "Status";
private static final String BRIDGED_IF_MEDIUM_TYPE = "MediumType";
private static final String BRIDGED_IF_NETWORK_MASK = "NetworkMask";
private static final String BRIDGED_IF_IP_ADDRESS = "IPAddress";
private static final String BRIDGED_IF_GUID = "GUID";
private static final String BRIDGED_IF_NAME = "Name";
@Inject
public BridgedIfStringToBridgedIf() {
}
@Override
public BridgedIf apply(String rawBridgedIf) {
checkNotNull(rawBridgedIf, "rawBridgedIf");
String transformedBridgedIf = transformRawBridgedIf(rawBridgedIf);
Map<String, String> bridegedIfMap = Splitter.on("\n")
.omitEmptyStrings().withKeyValueSeparator("=")
.split(transformedBridgedIf);
return BridgedIf
.builder()
.name(getValueFromMap(bridegedIfMap, BRIDGED_IF_NAME))
.guid(getValueFromMap(bridegedIfMap, BRIDGED_IF_GUID))
.ip(getValueFromMap(bridegedIfMap, BRIDGED_IF_IP_ADDRESS))
.networkMask(getValueFromMap(bridegedIfMap, BRIDGED_IF_NETWORK_MASK))
.mediumType(getValueFromMap(bridegedIfMap, BRIDGED_IF_MEDIUM_TYPE))
.status(getValueFromMap(bridegedIfMap, BRIDGED_IF_STATUS))
.build();
}
private String getValueFromMap(Map<String, String> map, String key) {
return map.get(key).trim();
}
/**
* This is an helper to simplify the split step of the raw bridgedIf
* Substitute first ':' with '='
*
* @param rawBridgedIf
* @return
*/
private String transformRawBridgedIf(String rawBridgedIf) {
Iterable<String> transformedLines = Iterables.transform(
Splitter.on("\n").split(rawBridgedIf),
new Function<String, String>() {
@Override
public String apply(String line) {
return line.replaceFirst(":", "=");
}
});
StringBuilder stringBuilder = new StringBuilder();
for (String line : transformedLines) {
stringBuilder.append(line + "\n");
}
return stringBuilder.toString();
}
}

View File

@ -36,18 +36,15 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.ssh.SshClient;
import org.jclouds.virtualbox.Preconfiguration;
import org.jclouds.virtualbox.domain.ExecutionType;
import org.jclouds.virtualbox.domain.IsoSpec;
import org.jclouds.virtualbox.domain.MasterSpec;
import org.jclouds.virtualbox.domain.VmSpec;
import org.jclouds.virtualbox.predicates.GuestAdditionsInstaller;
import org.jclouds.virtualbox.util.MachineController;
import org.jclouds.virtualbox.util.MachineUtils;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IProgress;
import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.LockType;
import org.virtualbox_4_1.VirtualBoxManager;
import org.virtualbox_4_1.jaxws.MachineState;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
@ -61,124 +58,99 @@ import com.google.inject.Inject;
@Singleton
public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final Supplier<VirtualBoxManager> manager;
private final CreateAndRegisterMachineFromIsoIfNotAlreadyExists createAndRegisterMachineFromIsoIfNotAlreadyExists;
private final GuestAdditionsInstaller guestAdditionsInstaller;
private final Predicate<SshClient> sshResponds;
private final ExecutionType executionType;
private LoadingCache<IsoSpec, URI> preConfiguration;
private final Function<IMachine, SshClient> sshClientForIMachine;
private final MachineUtils machineUtils;
private final IMachineToNodeMetadata imachineToNodeMetadata;
private final Supplier<VirtualBoxManager> manager;
private final CreateAndRegisterMachineFromIsoIfNotAlreadyExists createAndRegisterMachineFromIsoIfNotAlreadyExists;
private final GuestAdditionsInstaller guestAdditionsInstaller;
private final Predicate<SshClient> sshResponds;
private LoadingCache<IsoSpec, URI> preConfiguration;
private final Function<IMachine, SshClient> sshClientForIMachine;
private final MachineUtils machineUtils;
private final IMachineToNodeMetadata imachineToNodeMetadata;
private final MachineController machineController;
@Inject
public CreateAndInstallVm(Supplier<VirtualBoxManager> manager,
CreateAndRegisterMachineFromIsoIfNotAlreadyExists CreateAndRegisterMachineFromIsoIfNotAlreadyExists,
GuestAdditionsInstaller guestAdditionsInstaller, IMachineToNodeMetadata imachineToNodeMetadata,
Predicate<SshClient> sshResponds, Function<IMachine, SshClient> sshClientForIMachine,
ExecutionType executionType, MachineUtils machineUtils,
@Preconfiguration LoadingCache<IsoSpec, URI> preConfiguration) {
this.manager = manager;
this.createAndRegisterMachineFromIsoIfNotAlreadyExists = CreateAndRegisterMachineFromIsoIfNotAlreadyExists;
this.sshResponds = sshResponds;
this.sshClientForIMachine = sshClientForIMachine;
this.executionType = executionType;
this.machineUtils = machineUtils;
this.preConfiguration = preConfiguration;
this.guestAdditionsInstaller = guestAdditionsInstaller;
this.imachineToNodeMetadata = imachineToNodeMetadata;
}
@Inject
public CreateAndInstallVm(
Supplier<VirtualBoxManager> manager,
CreateAndRegisterMachineFromIsoIfNotAlreadyExists CreateAndRegisterMachineFromIsoIfNotAlreadyExists,
GuestAdditionsInstaller guestAdditionsInstaller,
IMachineToNodeMetadata imachineToNodeMetadata,
Predicate<SshClient> sshResponds,
Function<IMachine, SshClient> sshClientForIMachine,
MachineUtils machineUtils,
@Preconfiguration LoadingCache<IsoSpec, URI> preConfiguration, MachineController machineController) {
this.manager = manager;
this.createAndRegisterMachineFromIsoIfNotAlreadyExists = CreateAndRegisterMachineFromIsoIfNotAlreadyExists;
this.sshResponds = sshResponds;
this.sshClientForIMachine = sshClientForIMachine;
this.machineUtils = machineUtils;
this.preConfiguration = preConfiguration;
this.guestAdditionsInstaller = guestAdditionsInstaller;
this.imachineToNodeMetadata = imachineToNodeMetadata;
this.machineController = machineController;
}
@Override
public IMachine apply(MasterSpec masterSpec) {
@Override
public IMachine apply(MasterSpec masterSpec) {
VmSpec vmSpec = masterSpec.getVmSpec();
IsoSpec isoSpec = masterSpec.getIsoSpec();
String vmName = vmSpec.getVmName();
VmSpec vmSpec = masterSpec.getVmSpec();
IsoSpec isoSpec = masterSpec.getIsoSpec();
String vmName = vmSpec.getVmName();
IMachine vm = createAndRegisterMachineFromIsoIfNotAlreadyExists.apply(masterSpec);
IMachine vm = createAndRegisterMachineFromIsoIfNotAlreadyExists
.apply(masterSpec);
// Launch machine and wait for it to come online
ensureMachineIsLaunched(vmName);
// Launch machine and wait for it to come online
machineController.ensureMachineIsLaunched(vmName);
URI uri = preConfiguration.getUnchecked(isoSpec);
String installationKeySequence = isoSpec.getInstallationKeySequence().replace("PRECONFIGURATION_URL",
uri.toASCIIString());
URI uri = preConfiguration.getUnchecked(isoSpec);
String installationKeySequence = isoSpec.getInstallationKeySequence()
.replace("PRECONFIGURATION_URL", uri.toASCIIString());
configureOsInstallationWithKeyboardSequence(vmName, installationKeySequence);
SshClient client = sshClientForIMachine.apply(vm);
logger.debug(">> awaiting installation to finish node(%s)", vmName);
configureOsInstallationWithKeyboardSequence(vmName,
installationKeySequence);
SshClient client = sshClientForIMachine.apply(vm);
checkState(sshResponds.apply(client), "timed out waiting for guest %s to be accessible via ssh", vmName);
logger.debug(">> awaiting installation to finish node(%s)", vmName);
logger.debug(">> awaiting installation of guest additions on vm: %s", vmName);
checkState(sshResponds.apply(client),
"timed out waiting for guest %s to be accessible via ssh",
vmName);
checkState(guestAdditionsInstaller.apply(vm));
//logger.debug(">> awaiting installation of guest additions on vm: %s", vmName);
//checkState(guestAdditionsInstaller.apply(vm));
logger.debug(">> awaiting post-installation actions on vm: %s", vmName);
logger.debug(">> awaiting post-installation actions on vm: %s", vmName);
NodeMetadata vmMetadata = imachineToNodeMetadata.apply(vm);
// TODO for now this is executed on installModuleAssistantIfNeeded as a workaround to some transient execution issue.
// ListenableFuture<ExecResponse> execFuture = machineUtils.runScriptOnNode(vmMetadata, call("cleanupUdevIfNeeded"),
// RunScriptOptions.NONE);
// ExecResponse execResponse = Futures.getUnchecked(execFuture);
// checkState(execResponse.getExitCode() == 0);
NodeMetadata vmMetadata = imachineToNodeMetadata.apply(vm);
logger.debug("<< installation of image complete. Powering down node(%s)", vmName);
ListenableFuture<ExecResponse> execFuture =
machineUtils.runScriptOnNode(vmMetadata, call("cleanupUdevIfNeeded"), RunScriptOptions.NONE);
ensureMachineHasPowerDown(vmName);
return vm;
}
ExecResponse execResponse = Futures.getUnchecked(execFuture);
checkState(execResponse.getExitStatus() == 0);
private void configureOsInstallationWithKeyboardSequence(String vmName, String installationKeySequence) {
Iterable<List<Integer>> scancodelist = transform(Splitter.on(" ").split(installationKeySequence),
new StringToKeyCode());
logger.debug(
"<< installation of image complete. Powering down node(%s)",
vmName);
for (List<Integer> scancodes : scancodelist) {
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new SendScancodes(scancodes));
}
}
machineController.ensureMachineHasPowerDown(vmName);
return vm;
}
/**
* ensureMachineHasPowerDown needs to have this delay just to ensure that the machine is
* completely powered off
*
* @param vmName
*/
private void ensureMachineHasPowerDown(String vmName) {
while (!manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.POWERED_OFF)) {
try {
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function<ISession, Void>() {
@Override
public Void apply(ISession session) {
IProgress powerDownProgress = session.getConsole().powerDown();
powerDownProgress.waitForCompletion(-1);
return null;
}
});
} catch (RuntimeException e) {
// sometimes the machine might be powered of between the while test and the call to
// lockSessionOnMachineAndApply
if (e.getMessage().contains("Invalid machine state: PoweredOff")) {
return;
} else if (e.getMessage().contains("VirtualBox error: The object is not ready")) {
continue;
} else {
throw e;
}
}
}
}
private void configureOsInstallationWithKeyboardSequence(String vmName,
String installationKeySequence) {
Iterable<List<Integer>> scancodelist = transform(Splitter.on(" ")
.split(installationKeySequence), new StringToKeyCode());
private void ensureMachineIsLaunched(String vmName) {
machineUtils.applyForMachine(vmName, new LaunchMachineIfNotAlreadyRunning(manager.get(), executionType, ""));
}
for (List<Integer> scancodes : scancodelist) {
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared,
new SendScancodes(scancodes));
}
}
}

View File

@ -19,58 +19,123 @@
package org.jclouds.virtualbox.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.util.List;
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.options.RunScriptOptions;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.logging.Logger;
import org.jclouds.net.IPSocket;
import org.jclouds.ssh.SshClient;
import org.jclouds.virtualbox.domain.BridgedIf;
import org.jclouds.virtualbox.statements.GetIPAddressFromMAC;
import org.jclouds.virtualbox.statements.ScanNetworkWithPing;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.INetworkAdapter;
import org.virtualbox_4_1.NetworkAttachmentType;
import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.common.base.Supplier;
import com.google.common.collect.Iterables;
import com.google.inject.Inject;
@Singleton
public class IMachineToSshClient implements Function<IMachine, SshClient> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final SshClient.Factory sshClientFactory;
private final SshClient.Factory sshClientFactory;
private final RunScriptOnNode.Factory scriptRunnerFactory;
private final Supplier<NodeMetadata> hostSupplier;
@Inject
public IMachineToSshClient(SshClient.Factory sshClientFactory) {
this.sshClientFactory = sshClientFactory;
}
@Inject
public IMachineToSshClient(SshClient.Factory sshClientFactory,
RunScriptOnNode.Factory scriptRunnerFactory,
Supplier<NodeMetadata> hostSupplier) {
this.sshClientFactory = sshClientFactory;
this.scriptRunnerFactory = scriptRunnerFactory;
this.hostSupplier = hostSupplier;
}
@Override
public SshClient apply(final IMachine vm) {
INetworkAdapter networkAdapter = vm.getNetworkAdapter(0L);
@Override
public SshClient apply(final IMachine vm) {
INetworkAdapter networkAdapter = vm.getNetworkAdapter(0L);
SshClient client = null;
checkNotNull(networkAdapter);
for (String nameProtocolnumberAddressInboudportGuestTargetport : networkAdapter.getNatDriver().getRedirects()) {
Iterable<String> stuff = Splitter.on(',').split(nameProtocolnumberAddressInboudportGuestTargetport);
String protocolNumber = Iterables.get(stuff, 1);
String hostAddress = Iterables.get(stuff, 2);
String inboundPort = Iterables.get(stuff, 3);
String targetPort = Iterables.get(stuff, 5);
// TODO: we need a way to align the default login credentials from the iso with the
// vmspec
if ("1".equals(protocolNumber) && "22".equals(targetPort)) {
client = sshClientFactory.create(new IPSocket(hostAddress, Integer.parseInt(inboundPort)), LoginCredentials
.builder().user("toor").password("password").authenticateSudo(true).build());
}
}
checkNotNull(client);
return client;
}
SshClient client = null;
checkNotNull(networkAdapter);
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 ?
LoginCredentials loginCredentials = LoginCredentials.builder()
.user("toor").password("password").authenticateSudo(true)
.build();
if (networkAdapter.getAttachmentType()
.equals(NetworkAttachmentType.NAT)) {
for (String nameProtocolnumberAddressInboudportGuestTargetport : networkAdapter
.getNatDriver().getRedirects()) {
Iterable<String> stuff = Splitter.on(',').split(
nameProtocolnumberAddressInboudportGuestTargetport);
String protocolNumber = Iterables.get(stuff, 1);
String hostAddress = Iterables.get(stuff, 2);
String inboundPort = Iterables.get(stuff, 3);
String targetPort = Iterables.get(stuff, 5);
if ("1".equals(protocolNumber) && "22".equals(targetPort)) {
clientIpAddress = hostAddress;
sshPort = inboundPort;
}
}
} else if (networkAdapter.getAttachmentType().equals(
NetworkAttachmentType.Bridged)) {
String network = "1.1.1.1";
clientIpAddress = getIpAddressFromBridgedNIC(networkAdapter, network);
}
checkNotNull(clientIpAddress, "clientIpAddress");
client = sshClientFactory.create(
new IPSocket(clientIpAddress, Integer.parseInt(sshPort)),
loginCredentials);
checkNotNull(client);
return client;
}
private String getIpAddressFromBridgedNIC(INetworkAdapter networkAdapter,
String network) {
// RetrieveActiveBridgedInterfaces
List<BridgedIf> activeBridgedInterfaces = new RetrieveActiveBridgedInterfaces(scriptRunnerFactory).apply(hostSupplier.get());
BridgedIf activeBrigedIf = checkNotNull(Iterables.get(activeBridgedInterfaces, 0), "activeBridgrdIf");
network = activeBrigedIf.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");
}
}

View File

@ -23,15 +23,18 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_NODE_PREFIX;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
import org.jclouds.compute.callables.RunScriptOnNode;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.virtualbox.domain.BridgedIf;
import org.jclouds.virtualbox.domain.CloneSpec;
import org.jclouds.virtualbox.domain.ExecutionType;
import org.jclouds.virtualbox.domain.Master;
@ -52,95 +55,148 @@ import com.google.common.base.Function;
import com.google.common.base.Supplier;
@Singleton
public class NodeCreator implements Function<NodeSpec, NodeAndInitialCredentials<IMachine>> {
public class NodeCreator implements
Function<NodeSpec, NodeAndInitialCredentials<IMachine>> {
// TODO parameterize
public static final int NODE_PORT_INIT = 3000;
// TODO parameterize
public static final int NODE_PORT_INIT = 3000;
// TODO parameterize
public static final String VMS_NETWORK = "33.33.33.";
// TODO parameterize
public static final String VMS_NETWORK = "33.33.33.";
// TODO parameterize
public static final String HOST_ONLY_IFACE_NAME = "vboxnet0";
// TODO parameterize
public static final String HOST_ONLY_IFACE_NAME = "vboxnet0";
// TODO parameterize
public static final boolean USE_LINKED = true;
// TODO parameterize
public static final boolean USE_LINKED = true;
private final Supplier<VirtualBoxManager> manager;
private final Function<CloneSpec, IMachine> cloner;
private final AtomicInteger nodes;
private MachineUtils machineUtils;
private Function<IMachine, NodeMetadata> imachineToNodeMetadata;
private final Supplier<VirtualBoxManager> manager;
private final Function<CloneSpec, IMachine> cloner;
private final AtomicInteger nodePorts;
private final AtomicInteger nodeIps;
private MachineUtils machineUtils;
private Function<IMachine, NodeMetadata> imachineToNodeMetadata;
@Inject
public NodeCreator(Supplier<VirtualBoxManager> manager, Function<CloneSpec, IMachine> cloner,
MachineUtils machineUtils, Function<IMachine, NodeMetadata> imachineToNodeMetadata) {
this.manager = manager;
this.cloner = cloner;
this.nodes = new AtomicInteger(0);
this.machineUtils = machineUtils;
this.imachineToNodeMetadata = imachineToNodeMetadata;
}
private final RunScriptOnNode.Factory scriptRunnerFactory;
private final Supplier<NodeMetadata> hostSupplier;
/**
* Creates a clone based on the {@link NodeSpec}. It is synchronized because it needs sole access
* to the master. Could be improved by locking on a master basis (would allow concurrent cloning
* as long as form different masters."
*/
@Override
public synchronized NodeAndInitialCredentials<IMachine> apply(NodeSpec nodeSpec) {
@Inject
public NodeCreator(Supplier<VirtualBoxManager> manager,
Function<CloneSpec, IMachine> cloner, MachineUtils machineUtils,
Function<IMachine, NodeMetadata> imachineToNodeMetadata,
RunScriptOnNode.Factory scriptRunnerFactory,
Supplier<NodeMetadata> hostSupplier) {
this.manager = manager;
this.cloner = cloner;
this.nodePorts = new AtomicInteger(NODE_PORT_INIT);
this.nodeIps = new AtomicInteger(1);
this.machineUtils = machineUtils;
this.imachineToNodeMetadata = imachineToNodeMetadata;
this.scriptRunnerFactory = scriptRunnerFactory;
this.hostSupplier = hostSupplier;
checkNotNull(nodeSpec, "NodeSpec");
}
Master master = nodeSpec.getMaster();
checkNotNull(master, "Master");
@Override
public NodeAndInitialCredentials<IMachine> apply(NodeSpec nodeSpec) {
if (master.getMachine().getCurrentSnapshot() != null) {
ISession session;
try {
session = manager.get().openMachineSession(master.getMachine());
} catch (Exception e) {
throw new RuntimeException("error opening vbox machine session: " + e.getMessage(), e);
}
session.getConsole().deleteSnapshot(master.getMachine().getCurrentSnapshot().getId());
session.unlockMachine();
}
checkNotNull(nodeSpec, "NodeSpec");
String masterNameWithoutPrefix = master.getSpec().getVmSpec().getVmName().replace(VIRTUALBOX_IMAGE_PREFIX, "");
Master master = nodeSpec.getMaster();
checkNotNull(master, "Master");
String cloneName = VIRTUALBOX_NODE_PREFIX + masterNameWithoutPrefix + "-" + nodeSpec.getTag() + "-"
+ nodeSpec.getName();
if (master.getMachine().getCurrentSnapshot() != null) {
ISession session;
try {
session = manager.get().openMachineSession(master.getMachine());
} catch (Exception e) {
throw new RuntimeException(
"error opening vbox machine session: " + e.getMessage(),
e);
}
session.getConsole().deleteSnapshot(
master.getMachine().getCurrentSnapshot().getId());
session.unlockMachine();
}
String masterNameWithoutPrefix = master.getSpec().getVmSpec()
.getVmName().replace(VIRTUALBOX_IMAGE_PREFIX, "");
VmSpec cloneVmSpec = VmSpec.builder().id(cloneName).name(cloneName).memoryMB(512).cleanUpMode(CleanupMode.Full)
.forceOverwrite(true).build();
String cloneName = VIRTUALBOX_NODE_PREFIX + masterNameWithoutPrefix
+ "-" + nodeSpec.getTag() + "-" + nodeSpec.getName();
NetworkAdapter natAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.NAT)
.tcpRedirectRule("127.0.0.1", NODE_PORT_INIT + this.nodes.getAndIncrement(), "", 22).build();
VmSpec cloneVmSpec = VmSpec.builder().id(cloneName).name(cloneName)
.memoryMB(512).cleanUpMode(CleanupMode.Full)
.forceOverwrite(true).build();
NetworkInterfaceCard natIfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(natAdapter).slot(0L).build();
// CASE NAT + HOST-ONLY
NetworkAdapter natAdapter = NetworkAdapter
.builder()
.networkAttachmentType(NetworkAttachmentType.NAT)
.tcpRedirectRule("127.0.0.1", this.nodePorts.getAndIncrement(),
"", 22).build();
NetworkInterfaceCard natIfaceCard = NetworkInterfaceCard.builder()
.addNetworkAdapter(natAdapter).slot(0L).build();
NetworkAdapter hostOnlyAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.HostOnly)
.staticIp(VMS_NETWORK + this.nodes.getAndIncrement()).build();
NetworkAdapter hostOnlyAdapter = NetworkAdapter.builder()
.networkAttachmentType(NetworkAttachmentType.HostOnly)
.staticIp(VMS_NETWORK + this.nodeIps.getAndIncrement()).build();
NetworkInterfaceCard hostOnlyIfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(hostOnlyAdapter)
.addHostInterfaceName(HOST_ONLY_IFACE_NAME).slot(1L).build();
NetworkInterfaceCard hostOnlyIfaceCard = NetworkInterfaceCard.builder()
.addNetworkAdapter(hostOnlyAdapter)
.addHostInterfaceName(HOST_ONLY_IFACE_NAME).slot(1L).build();
NetworkSpec networkSpec = createNetworkSpecForHostOnlyNATNICs(natIfaceCard, hostOnlyIfaceCard);
////
// CASE BRIDGED
//NetworkSpec networkSpec = createNetworkSpecForBridgedNIC();
NetworkSpec networkSpec = NetworkSpec.builder().addNIC(natIfaceCard).addNIC(hostOnlyIfaceCard).build();
CloneSpec cloneSpec = CloneSpec.builder().linked(USE_LINKED)
.master(master.getMachine()).network(networkSpec)
.vm(cloneVmSpec).build();
CloneSpec cloneSpec = CloneSpec.builder().linked(USE_LINKED).master(master.getMachine()).network(networkSpec)
.vm(cloneVmSpec).build();
IMachine cloned = cloner.apply(cloneSpec);
IMachine cloned = cloner.apply(cloneSpec);
new LaunchMachineIfNotAlreadyRunning(manager.get(), ExecutionType.GUI,
"").apply(cloned);
new LaunchMachineIfNotAlreadyRunning(manager.get(), ExecutionType.GUI, "").apply(cloned);
// CASE NAT + HOST-ONLY
machineUtils.runScriptOnNode(imachineToNodeMetadata.apply(cloned),
new SetIpAddress(hostOnlyIfaceCard), RunScriptOptions.NONE);
////
machineUtils.runScriptOnNode(imachineToNodeMetadata.apply(cloned), new SetIpAddress(hostOnlyIfaceCard),
RunScriptOptions.NONE);
// TODO get credentials from somewhere else (they are also HC in
// IMachineToSshClient)
NodeAndInitialCredentials<IMachine> nodeAndInitialCredentials = new NodeAndInitialCredentials<IMachine>(
cloned, cloneName, LoginCredentials.builder().user("toor")
.password("password").authenticateSudo(true).build());
// TODO get credentials from somewhere else (they are also HC in IMachineToSshClient)
NodeAndInitialCredentials<IMachine> nodeAndInitialCredentials = new NodeAndInitialCredentials<IMachine>(cloned,
cloneName, LoginCredentials.builder().user("toor").password("password").authenticateSudo(true).build());
return nodeAndInitialCredentials;
}
return nodeAndInitialCredentials;
}
private NetworkSpec createNetworkSpecForHostOnlyNATNICs(NetworkInterfaceCard natIfaceCard, NetworkInterfaceCard hostOnlyIfaceCard) {
return NetworkSpec.builder().addNIC(natIfaceCard)
.addNIC(hostOnlyIfaceCard).build();
}
private NetworkSpec createNetworkSpecForBridgedNIC() {
List<BridgedIf> activeBridgedInterfaces = new RetrieveActiveBridgedInterfaces(
scriptRunnerFactory).apply(hostSupplier.get());
BridgedIf bridgedActiveInterface = checkNotNull(
activeBridgedInterfaces.get(0), "activeBridgedIf");
NetworkAdapter bridgedAdapter = NetworkAdapter.builder()
.networkAttachmentType(NetworkAttachmentType.Bridged).build();
NetworkInterfaceCard bridgedNIC = NetworkInterfaceCard.builder()
.addNetworkAdapter(bridgedAdapter)
.addHostInterfaceName(bridgedActiveInterface.getName())
.slot(0L).build();
NetworkSpec networkSpec = NetworkSpec.builder().addNIC(bridgedNIC)
.build();
return networkSpec;
}
}

View File

@ -37,6 +37,7 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.scriptbuilder.domain.Statement;
import org.jclouds.scriptbuilder.domain.Statements;
import org.jclouds.virtualbox.domain.BridgedIf;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
@ -50,67 +51,56 @@ import com.google.inject.name.Named;
/**
* @author Andrea Turli
*/
public class RetrieveActiveBridgedInterfaces implements Function<NodeMetadata, List<String>> {
public class RetrieveActiveBridgedInterfaces implements Function<NodeMetadata, List<BridgedIf>> {
@Resource
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final Factory runScriptOnNodeFactory;
@Inject
public RetrieveActiveBridgedInterfaces(Factory runScriptOnNodeFactory) {
public RetrieveActiveBridgedInterfaces(Factory runScriptOnNodeFactory) {
this.runScriptOnNodeFactory = checkNotNull(runScriptOnNodeFactory, "runScriptOnNodeFactory");
}
@Override
public List<String> apply(NodeMetadata host) {
public List<BridgedIf> apply(NodeMetadata host) {
// Bridged Network
Statement command = Statements.exec("VBoxManage list bridgedifs");
String bridgedIfBlocks = runScriptOnNodeFactory.create(host, command, runAsRoot(false).wrapInInitScript(false))
.init().call().getOutput();
List<String> bridgedInterfaces = retrieveBridgedInterfaceNames(bridgedIfBlocks);
List<BridgedIf> bridgedInterfaces = retrieveBridgedInterfaceNames(bridgedIfBlocks);
checkNotNull(bridgedInterfaces);
// union of bridgedNetwork with inet up and !loopback
List<String> activeNetworkInterfaceNames = Lists.newArrayList();
List<BridgedIf> activeNetworkInterfaces = Lists.newArrayList();
try {
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
for (NetworkInterface inet : Collections.list(nets)) {
Iterable<String> filteredBridgedInterface = filter(bridgedInterfaces, new IsActiveBridgedInterface(inet));
Iterables.addAll(activeNetworkInterfaceNames, filteredBridgedInterface);
Iterable<BridgedIf> filteredBridgedInterface = filter(bridgedInterfaces, new IsActiveBridgedInterface(inet));
Iterables.addAll(activeNetworkInterfaces, filteredBridgedInterface);
}
} catch (SocketException e) {
logger.error(e, "Problem in listing network interfaces.");
Throwables.propagate(e);
assert false;
}
return activeNetworkInterfaceNames;
return activeNetworkInterfaces;
}
protected static List<String> retrieveBridgedInterfaceNames(String bridgedIfBlocks) {
List<String> bridgedInterfaceNames = Lists.newArrayList();
protected static List<BridgedIf> retrieveBridgedInterfaceNames(String bridgedIfBlocks) {
List<BridgedIf> bridgedInterfaces = Lists.newArrayList();
// separate the different bridge block
for (String bridgedIfBlock : Splitter.on(Pattern.compile("(?m)^[ \t]*\r?\n")).split(bridgedIfBlocks)) {
Iterable<String> bridgedIfName = filter(Splitter.on("\n").split(bridgedIfBlock), new Predicate<String>() {
@Override
public boolean apply(String arg0) {
return arg0.startsWith("Name:");
}
});
for (String bridgedInterfaceName : bridgedIfName) {
for (String string : Splitter.on("Name:").split(bridgedInterfaceName)) {
if (!string.isEmpty())
bridgedInterfaceNames.add(string.trim());
}
}
if(!bridgedIfBlock.isEmpty())
bridgedInterfaces.add(new BridgedIfStringToBridgedIf().apply(bridgedIfBlock));
}
return bridgedInterfaceNames;
return bridgedInterfaces;
}
private class IsActiveBridgedInterface implements Predicate<String> {
private class IsActiveBridgedInterface implements Predicate<BridgedIf> {
private NetworkInterface networkInterface;
@ -119,10 +109,12 @@ public class RetrieveActiveBridgedInterfaces implements Function<NodeMetadata, L
}
@Override
public boolean apply(String bridgedInterfaceName) {
public boolean apply(BridgedIf bridgedInterface) {
try {
return (bridgedInterfaceName.startsWith(networkInterface.getDisplayName()) && networkInterface.isUp() && !networkInterface
.isLoopback());
return (bridgedInterface.getName().startsWith(networkInterface.getDisplayName()) &&
bridgedInterface.getStatus().equals("Up") &&
networkInterface.isUp() &&
!networkInterface.isLoopback());
} catch (SocketException e) {
logger.error(e, "Problem in listing network interfaces.");
Throwables.propagate(e);

View File

@ -1,3 +1,22 @@
/**
* 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.predicates;
import javax.annotation.Resource;

View File

@ -0,0 +1,92 @@
/**
* 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 javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.virtualbox.domain.ExecutionType;
import org.jclouds.virtualbox.functions.LaunchMachineIfNotAlreadyRunning;
import org.virtualbox_4_1.IProgress;
import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.LockType;
import org.virtualbox_4_1.VirtualBoxManager;
import org.virtualbox_4_1.jaxws.MachineState;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.inject.Inject;
/**
* Utilities to manage VirtualBox machine life cycle.
*
* @author Adrian Cole, Mattias Holmqvist, Andrea Turli
*/
@Singleton
public class MachineController {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final Supplier<VirtualBoxManager> manager;
private final MachineUtils machineUtils;
private final ExecutionType executionType;
@Inject
public MachineController(Supplier<VirtualBoxManager> manager, MachineUtils machineUtils, ExecutionType executionType) {
this.manager = manager;
this.machineUtils = machineUtils;
this.executionType = executionType;
}
public void ensureMachineIsLaunched(String vmName) {
machineUtils.applyForMachine(vmName, new LaunchMachineIfNotAlreadyRunning(manager.get(), executionType, ""));
}
public void ensureMachineHasPowerDown(String vmName) {
while (!manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.POWERED_OFF)) {
try {
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function<ISession, Void>() {
@Override
public Void apply(ISession session) {
IProgress powerDownProgress = session.getConsole().powerDown();
powerDownProgress.waitForCompletion(-1);
return null;
}
});
} catch (RuntimeException e) {
// sometimes the machine might be powered of between the while test and the call to
// lockSessionOnMachineAndApply
if (e.getMessage().contains("Invalid machine state: PoweredOff")) {
return;
} else if (e.getMessage().contains("VirtualBox error: The object is not ready")) {
continue;
} else {
throw e;
}
}
}
}
}

View File

@ -1,9 +1,9 @@
function cleanupUdevIfNeeded {
unset OSNAME;
local OSNAME=`lsb_release -d -s | cut -d ' ' -f 1`; shift
if [ $OSNAME = 'Ubuntu' ]
# unset OSNAME;
# local OSNAME=`lsb_release -d -s | cut -d ' ' -f 1`; shift
# if [ $OSNAME = 'Ubuntu' ]
if [ -f '/etc/udev/rules.d/70-persistent-net.rules']
then
echo "OS is Ubuntu"
rm /etc/udev/rules.d/70-persistent-net.rules;
mkdir /etc/udev/rules.d/70-persistent-net.rules;
rm -rf /dev/.udev/;

View File

@ -30,14 +30,11 @@ import javax.inject.Inject;
import javax.inject.Named;
import org.jclouds.Constants;
import org.jclouds.byon.Node;
import org.jclouds.byon.config.CacheNodeStoreModule;
import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
import org.jclouds.concurrent.MoreExecutors;
@ -49,21 +46,16 @@ import org.jclouds.virtualbox.domain.IsoSpec;
import org.jclouds.virtualbox.domain.Master;
import org.jclouds.virtualbox.domain.VmSpec;
import org.jclouds.virtualbox.functions.admin.UnregisterMachineIfExistsAndDeleteItsMedia;
import org.jclouds.virtualbox.util.MachineController;
import org.jclouds.virtualbox.util.MachineUtils;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.virtualbox_4_1.IProgress;
import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.LockType;
import org.virtualbox_4_1.VirtualBoxManager;
import org.virtualbox_4_1.jaxws.MachineState;
import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.common.base.Supplier;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.inject.Module;
@ -80,6 +72,9 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
}
protected ComputeServiceContext context;
@Inject
protected MachineController machineController;
@Inject
protected Supplier<VirtualBoxManager> manager;
@ -160,30 +155,7 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
new UnregisterMachineIfExistsAndDeleteItsMedia(vmSpecification));
}
protected void ensureMachineHasPowerDown(String vmName) {
while (!manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.POWERED_OFF)) {
try {
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function<ISession, Void>() {
@Override
public Void apply(ISession session) {
IProgress powerDownProgress = session.getConsole().powerDown();
powerDownProgress.waitForCompletion(-1);
return null;
}
});
} catch (RuntimeException e) {
// sometimes the machine might be powered of between the while test and the call to
// lockSessionOnMachineAndApply
if (e.getMessage().contains("Invalid machine state: PoweredOff")) {
return;
} else if (e.getMessage().contains("VirtualBox error: The object is not ready")) {
continue;
} else {
throw e;
}
}
}
}
public String adminDisk(String vmName) {
return workingDir + File.separator + vmName + ".vdi";

View File

@ -0,0 +1,52 @@
package org.jclouds.virtualbox.functions;
import static org.testng.Assert.assertEquals;
import org.jclouds.virtualbox.domain.BridgedIf;
import org.testng.annotations.Test;
@Test(groups = "live", singleThreaded = true, testName = "BridgedIfStringToBridgedIfTest")
public class BridgedIfStringToBridgedIfTest {
private static final String en0 = "Name: en0: Ethernet\n" +
"GUID: 00306e65-0000-4000-8000-3c0754205d2f\n" +
"Dhcp: Disabled\n" +
"IPAddress: 192.168.56.1\n" +
"NetworkMask: 255.255.255.0\n" +
"IPV6Address: \n" +
"IPV6NetworkMaskPrefixLength: 0\n" +
"HardwareAddress: 3c:07:54:20:5d:2f\n" +
"MediumType: Ethernet\n" +
"Status: Up\n" +
"VBoxNetworkName: HostInterfaceNetworking-en0: Ethernet\n";
private static final String en1 = "Name: en1: Wi-Fi (AirPort)\n" +
"GUID: 00316e65-0000-4000-8000-28cfdaf2917a\n" +
"Dhcp: Disabled\n" +
"IPAddress: 192.168.57.1\n" +
"NetworkMask: 255.255.255.0\n" +
"IPV6Address: \n" +
"IPV6NetworkMaskPrefixLength: 0\n" +
"HardwareAddress: 28:cf:da:f2:91:7a\n" +
"MediumType: Ethernet\n" +
"Status: Up\n" +
"VBoxNetworkName: HostInterfaceNetworking-en1: Wi-Fi (AirPort)\n";
private static final String p2p0 = "Name: p2p0\n" +
"GUID: 30703270-0000-4000-8000-0acfdaf2917a\n" +
"Dhcp: Disabled\n" +
"IPAddress: 192.168.58.1\n" +
"NetworkMask: 255.255.255.0\n" +
"IPV6Address: \n" +
"IPV6NetworkMaskPrefixLength: 0\n" +
"HardwareAddress: 0a:cf:da:f2:91:7a\n" +
"MediumType: Ethernet\n" +
"Status: Down\n" +
"VBoxNetworkName: HostInterfaceNetworking-p2p0\n";
@Test
public void transformRawBridgedifToBridgedIf() {
BridgedIf bridgedIfEn1 = new BridgedIfStringToBridgedIf().apply(en1);
assertEquals(bridgedIfEn1.getName(), "en1: Wi-Fi (AirPort)");
}
}

View File

@ -26,8 +26,6 @@ import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTA
import java.util.Map;
import javax.annotation.Nullable;
import org.jclouds.compute.config.BaseComputeServiceContextModule;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OsFamily;
@ -153,21 +151,11 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest {
}));
} finally {
for (VmSpec spec : ImmutableSet.of(vmSpecification)) {
ensureMachineHasPowerDown(spec.getVmName());
machineController.ensureMachineHasPowerDown(spec.getVmName());
}
}
}
private Function<Image, String> extractId() {
return new Function<Image, String>() {
@Override
public String apply(@Nullable Image input) {
return input.getId();
}
};
}
private IMachine getVmWithGuestAdditionsInstalled() {
try {
Injector injector = context.utils().injector();

View File

@ -25,6 +25,7 @@ import static org.testng.Assert.assertFalse;
import java.util.List;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.jclouds.virtualbox.domain.BridgedIf;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
@ -51,13 +52,13 @@ public class RetrieveActiveBridgedInterfacesLiveTest extends BaseVirtualBoxClien
@Test
public void retrieveBridgedInterfaceNamesTest() {
List<String> activeBridgedInterfaceNames = retrieveBridgedInterfaceNames(TEST1);
assertEquals(activeBridgedInterfaceNames, expectedBridgedInterfaces);
List<BridgedIf> activeBridgedInterfaces = retrieveBridgedInterfaceNames(TEST1);
assertEquals(activeBridgedInterfaces, expectedBridgedInterfaces);
}
@Test
public void retrieveAvailableBridgedInterfaceInfoTest() {
List<String> bridgedInterface = context.utils().injector().getInstance(RetrieveActiveBridgedInterfaces.class)
List<BridgedIf> bridgedInterface = context.utils().injector().getInstance(RetrieveActiveBridgedInterfaces.class)
.apply(host.get());
assertFalse(bridgedInterface.isEmpty());
}

View File

@ -40,7 +40,6 @@ 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.IProgress;
import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.LockType;
import org.virtualbox_4_1.NetworkAttachmentType;
@ -123,7 +122,7 @@ public class GuestAdditionsInstallerLiveTest extends
}));
} finally {
for (VmSpec spec : ImmutableSet.of(sourceMachineSpec.getVmSpec())) {
ensureMachineHasPowerDown(spec.getVmName());
machineController.ensureMachineHasPowerDown(spec.getVmName());
undoVm(spec);
}
}