mirror of https://github.com/apache/jclouds.git
Merge pull request #428 from andreaturli/dev
issue 384: bridged support
This commit is contained in:
commit
538c2129a8
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -117,6 +117,6 @@ public class CloneSpec {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "IMachineSpec{" + "vmSpec= " + vmSpec + ", networkSpec= " + networkSpec + '}';
|
return "CloneSpec{" + "vmSpec= " + vmSpec + ", networkSpec= " + networkSpec + '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -36,18 +36,15 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
import org.jclouds.virtualbox.Preconfiguration;
|
import org.jclouds.virtualbox.Preconfiguration;
|
||||||
import org.jclouds.virtualbox.domain.ExecutionType;
|
|
||||||
import org.jclouds.virtualbox.domain.IsoSpec;
|
import org.jclouds.virtualbox.domain.IsoSpec;
|
||||||
import org.jclouds.virtualbox.domain.MasterSpec;
|
import org.jclouds.virtualbox.domain.MasterSpec;
|
||||||
import org.jclouds.virtualbox.domain.VmSpec;
|
import org.jclouds.virtualbox.domain.VmSpec;
|
||||||
import org.jclouds.virtualbox.predicates.GuestAdditionsInstaller;
|
import org.jclouds.virtualbox.predicates.GuestAdditionsInstaller;
|
||||||
|
import org.jclouds.virtualbox.util.MachineController;
|
||||||
import org.jclouds.virtualbox.util.MachineUtils;
|
import org.jclouds.virtualbox.util.MachineUtils;
|
||||||
import org.virtualbox_4_1.IMachine;
|
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.LockType;
|
||||||
import org.virtualbox_4_1.VirtualBoxManager;
|
import org.virtualbox_4_1.VirtualBoxManager;
|
||||||
import org.virtualbox_4_1.jaxws.MachineState;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
@ -61,124 +58,99 @@ import com.google.inject.Inject;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
|
public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
private final Supplier<VirtualBoxManager> manager;
|
private final Supplier<VirtualBoxManager> manager;
|
||||||
private final CreateAndRegisterMachineFromIsoIfNotAlreadyExists createAndRegisterMachineFromIsoIfNotAlreadyExists;
|
private final CreateAndRegisterMachineFromIsoIfNotAlreadyExists createAndRegisterMachineFromIsoIfNotAlreadyExists;
|
||||||
private final GuestAdditionsInstaller guestAdditionsInstaller;
|
private final GuestAdditionsInstaller guestAdditionsInstaller;
|
||||||
private final Predicate<SshClient> sshResponds;
|
private final Predicate<SshClient> sshResponds;
|
||||||
private final ExecutionType executionType;
|
private LoadingCache<IsoSpec, URI> preConfiguration;
|
||||||
private LoadingCache<IsoSpec, URI> preConfiguration;
|
private final Function<IMachine, SshClient> sshClientForIMachine;
|
||||||
private final Function<IMachine, SshClient> sshClientForIMachine;
|
private final MachineUtils machineUtils;
|
||||||
private final MachineUtils machineUtils;
|
private final IMachineToNodeMetadata imachineToNodeMetadata;
|
||||||
private final IMachineToNodeMetadata imachineToNodeMetadata;
|
private final MachineController machineController;
|
||||||
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CreateAndInstallVm(Supplier<VirtualBoxManager> manager,
|
public CreateAndInstallVm(
|
||||||
CreateAndRegisterMachineFromIsoIfNotAlreadyExists CreateAndRegisterMachineFromIsoIfNotAlreadyExists,
|
Supplier<VirtualBoxManager> manager,
|
||||||
GuestAdditionsInstaller guestAdditionsInstaller, IMachineToNodeMetadata imachineToNodeMetadata,
|
CreateAndRegisterMachineFromIsoIfNotAlreadyExists CreateAndRegisterMachineFromIsoIfNotAlreadyExists,
|
||||||
Predicate<SshClient> sshResponds, Function<IMachine, SshClient> sshClientForIMachine,
|
GuestAdditionsInstaller guestAdditionsInstaller,
|
||||||
ExecutionType executionType, MachineUtils machineUtils,
|
IMachineToNodeMetadata imachineToNodeMetadata,
|
||||||
@Preconfiguration LoadingCache<IsoSpec, URI> preConfiguration) {
|
Predicate<SshClient> sshResponds,
|
||||||
this.manager = manager;
|
Function<IMachine, SshClient> sshClientForIMachine,
|
||||||
this.createAndRegisterMachineFromIsoIfNotAlreadyExists = CreateAndRegisterMachineFromIsoIfNotAlreadyExists;
|
MachineUtils machineUtils,
|
||||||
this.sshResponds = sshResponds;
|
@Preconfiguration LoadingCache<IsoSpec, URI> preConfiguration, MachineController machineController) {
|
||||||
this.sshClientForIMachine = sshClientForIMachine;
|
this.manager = manager;
|
||||||
this.executionType = executionType;
|
this.createAndRegisterMachineFromIsoIfNotAlreadyExists = CreateAndRegisterMachineFromIsoIfNotAlreadyExists;
|
||||||
this.machineUtils = machineUtils;
|
this.sshResponds = sshResponds;
|
||||||
this.preConfiguration = preConfiguration;
|
this.sshClientForIMachine = sshClientForIMachine;
|
||||||
this.guestAdditionsInstaller = guestAdditionsInstaller;
|
this.machineUtils = machineUtils;
|
||||||
this.imachineToNodeMetadata = imachineToNodeMetadata;
|
this.preConfiguration = preConfiguration;
|
||||||
}
|
this.guestAdditionsInstaller = guestAdditionsInstaller;
|
||||||
|
this.imachineToNodeMetadata = imachineToNodeMetadata;
|
||||||
|
this.machineController = machineController;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IMachine apply(MasterSpec masterSpec) {
|
public IMachine apply(MasterSpec masterSpec) {
|
||||||
|
|
||||||
VmSpec vmSpec = masterSpec.getVmSpec();
|
VmSpec vmSpec = masterSpec.getVmSpec();
|
||||||
IsoSpec isoSpec = masterSpec.getIsoSpec();
|
IsoSpec isoSpec = masterSpec.getIsoSpec();
|
||||||
String vmName = vmSpec.getVmName();
|
String vmName = vmSpec.getVmName();
|
||||||
|
|
||||||
IMachine vm = createAndRegisterMachineFromIsoIfNotAlreadyExists.apply(masterSpec);
|
IMachine vm = createAndRegisterMachineFromIsoIfNotAlreadyExists
|
||||||
|
.apply(masterSpec);
|
||||||
|
|
||||||
// Launch machine and wait for it to come online
|
// Launch machine and wait for it to come online
|
||||||
ensureMachineIsLaunched(vmName);
|
machineController.ensureMachineIsLaunched(vmName);
|
||||||
|
|
||||||
URI uri = preConfiguration.getUnchecked(isoSpec);
|
URI uri = preConfiguration.getUnchecked(isoSpec);
|
||||||
String installationKeySequence = isoSpec.getInstallationKeySequence().replace("PRECONFIGURATION_URL",
|
String installationKeySequence = isoSpec.getInstallationKeySequence()
|
||||||
uri.toASCIIString());
|
.replace("PRECONFIGURATION_URL", uri.toASCIIString());
|
||||||
|
|
||||||
configureOsInstallationWithKeyboardSequence(vmName, installationKeySequence);
|
configureOsInstallationWithKeyboardSequence(vmName,
|
||||||
SshClient client = sshClientForIMachine.apply(vm);
|
installationKeySequence);
|
||||||
|
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);
|
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);
|
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);
|
|
||||||
|
|
||||||
logger.debug("<< installation of image complete. Powering down node(%s)", vmName);
|
ListenableFuture<ExecResponse> execFuture =
|
||||||
|
machineUtils.runScriptOnNode(vmMetadata, call("cleanupUdevIfNeeded"), RunScriptOptions.NONE);
|
||||||
|
|
||||||
ensureMachineHasPowerDown(vmName);
|
ExecResponse execResponse = Futures.getUnchecked(execFuture);
|
||||||
return vm;
|
checkState(execResponse.getExitStatus() == 0);
|
||||||
}
|
|
||||||
|
|
||||||
private void configureOsInstallationWithKeyboardSequence(String vmName, String installationKeySequence) {
|
logger.debug(
|
||||||
Iterable<List<Integer>> scancodelist = transform(Splitter.on(" ").split(installationKeySequence),
|
"<< installation of image complete. Powering down node(%s)",
|
||||||
new StringToKeyCode());
|
vmName);
|
||||||
|
|
||||||
for (List<Integer> scancodes : scancodelist) {
|
machineController.ensureMachineHasPowerDown(vmName);
|
||||||
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new SendScancodes(scancodes));
|
return vm;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
private void configureOsInstallationWithKeyboardSequence(String vmName,
|
||||||
* ensureMachineHasPowerDown needs to have this delay just to ensure that the machine is
|
String installationKeySequence) {
|
||||||
* completely powered off
|
Iterable<List<Integer>> scancodelist = transform(Splitter.on(" ")
|
||||||
*
|
.split(installationKeySequence), new StringToKeyCode());
|
||||||
* @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 ensureMachineIsLaunched(String vmName) {
|
for (List<Integer> scancodes : scancodelist) {
|
||||||
machineUtils.applyForMachine(vmName, new LaunchMachineIfNotAlreadyRunning(manager.get(), executionType, ""));
|
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared,
|
||||||
}
|
new SendScancodes(scancodes));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,58 +19,123 @@
|
||||||
package org.jclouds.virtualbox.functions;
|
package org.jclouds.virtualbox.functions;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
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.annotation.Resource;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
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.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.domain.LoginCredentials;
|
import org.jclouds.domain.LoginCredentials;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.net.IPSocket;
|
import org.jclouds.net.IPSocket;
|
||||||
import org.jclouds.ssh.SshClient;
|
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.IMachine;
|
||||||
import org.virtualbox_4_1.INetworkAdapter;
|
import org.virtualbox_4_1.INetworkAdapter;
|
||||||
|
import org.virtualbox_4_1.NetworkAttachmentType;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class IMachineToSshClient implements Function<IMachine, SshClient> {
|
public class IMachineToSshClient implements Function<IMachine, SshClient> {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected Logger logger = Logger.NULL;
|
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
|
@Inject
|
||||||
public IMachineToSshClient(SshClient.Factory sshClientFactory) {
|
public IMachineToSshClient(SshClient.Factory sshClientFactory,
|
||||||
this.sshClientFactory = sshClientFactory;
|
RunScriptOnNode.Factory scriptRunnerFactory,
|
||||||
}
|
Supplier<NodeMetadata> hostSupplier) {
|
||||||
|
this.sshClientFactory = sshClientFactory;
|
||||||
|
this.scriptRunnerFactory = scriptRunnerFactory;
|
||||||
|
this.hostSupplier = hostSupplier;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SshClient apply(final IMachine vm) {
|
public SshClient apply(final IMachine vm) {
|
||||||
INetworkAdapter networkAdapter = vm.getNetworkAdapter(0L);
|
INetworkAdapter networkAdapter = vm.getNetworkAdapter(0L);
|
||||||
|
|
||||||
SshClient client = null;
|
SshClient client = null;
|
||||||
checkNotNull(networkAdapter);
|
checkNotNull(networkAdapter);
|
||||||
for (String nameProtocolnumberAddressInboudportGuestTargetport : networkAdapter.getNatDriver().getRedirects()) {
|
|
||||||
Iterable<String> stuff = Splitter.on(',').split(nameProtocolnumberAddressInboudportGuestTargetport);
|
String clientIpAddress = null;
|
||||||
String protocolNumber = Iterables.get(stuff, 1);
|
String sshPort = "22";
|
||||||
String hostAddress = Iterables.get(stuff, 2);
|
|
||||||
String inboundPort = Iterables.get(stuff, 3);
|
// TODO: we need a way to align the default login credentials
|
||||||
String targetPort = Iterables.get(stuff, 5);
|
// from the iso with the vmspec -> IMachineToNodeMetadata using YamlImage ?
|
||||||
// TODO: we need a way to align the default login credentials from the iso with the
|
LoginCredentials loginCredentials = LoginCredentials.builder()
|
||||||
// vmspec
|
.user("toor").password("password").authenticateSudo(true)
|
||||||
if ("1".equals(protocolNumber) && "22".equals(targetPort)) {
|
.build();
|
||||||
client = sshClientFactory.create(new IPSocket(hostAddress, Integer.parseInt(inboundPort)), LoginCredentials
|
|
||||||
.builder().user("toor").password("password").authenticateSudo(true).build());
|
if (networkAdapter.getAttachmentType()
|
||||||
}
|
.equals(NetworkAttachmentType.NAT)) {
|
||||||
}
|
for (String nameProtocolnumberAddressInboudportGuestTargetport : networkAdapter
|
||||||
checkNotNull(client);
|
.getNatDriver().getRedirects()) {
|
||||||
return client;
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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_IMAGE_PREFIX;
|
||||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_NODE_PREFIX;
|
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_NODE_PREFIX;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
|
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
|
||||||
|
import org.jclouds.compute.callables.RunScriptOnNode;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.options.RunScriptOptions;
|
import org.jclouds.compute.options.RunScriptOptions;
|
||||||
import org.jclouds.domain.LoginCredentials;
|
import org.jclouds.domain.LoginCredentials;
|
||||||
|
import org.jclouds.virtualbox.domain.BridgedIf;
|
||||||
import org.jclouds.virtualbox.domain.CloneSpec;
|
import org.jclouds.virtualbox.domain.CloneSpec;
|
||||||
import org.jclouds.virtualbox.domain.ExecutionType;
|
import org.jclouds.virtualbox.domain.ExecutionType;
|
||||||
import org.jclouds.virtualbox.domain.Master;
|
import org.jclouds.virtualbox.domain.Master;
|
||||||
|
@ -52,95 +55,148 @@ import com.google.common.base.Function;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class NodeCreator implements Function<NodeSpec, NodeAndInitialCredentials<IMachine>> {
|
public class NodeCreator implements
|
||||||
|
Function<NodeSpec, NodeAndInitialCredentials<IMachine>> {
|
||||||
|
|
||||||
// TODO parameterize
|
// TODO parameterize
|
||||||
public static final int NODE_PORT_INIT = 3000;
|
public static final int NODE_PORT_INIT = 3000;
|
||||||
|
|
||||||
// TODO parameterize
|
// TODO parameterize
|
||||||
public static final String VMS_NETWORK = "33.33.33.";
|
public static final String VMS_NETWORK = "33.33.33.";
|
||||||
|
|
||||||
// TODO parameterize
|
// TODO parameterize
|
||||||
public static final String HOST_ONLY_IFACE_NAME = "vboxnet0";
|
public static final String HOST_ONLY_IFACE_NAME = "vboxnet0";
|
||||||
|
|
||||||
// TODO parameterize
|
// TODO parameterize
|
||||||
public static final boolean USE_LINKED = true;
|
public static final boolean USE_LINKED = true;
|
||||||
|
|
||||||
private final Supplier<VirtualBoxManager> manager;
|
private final Supplier<VirtualBoxManager> manager;
|
||||||
private final Function<CloneSpec, IMachine> cloner;
|
private final Function<CloneSpec, IMachine> cloner;
|
||||||
private final AtomicInteger nodes;
|
private final AtomicInteger nodePorts;
|
||||||
private MachineUtils machineUtils;
|
private final AtomicInteger nodeIps;
|
||||||
private Function<IMachine, NodeMetadata> imachineToNodeMetadata;
|
private MachineUtils machineUtils;
|
||||||
|
private Function<IMachine, NodeMetadata> imachineToNodeMetadata;
|
||||||
|
|
||||||
@Inject
|
private final RunScriptOnNode.Factory scriptRunnerFactory;
|
||||||
public NodeCreator(Supplier<VirtualBoxManager> manager, Function<CloneSpec, IMachine> cloner,
|
private final Supplier<NodeMetadata> hostSupplier;
|
||||||
MachineUtils machineUtils, Function<IMachine, NodeMetadata> imachineToNodeMetadata) {
|
|
||||||
this.manager = manager;
|
|
||||||
this.cloner = cloner;
|
|
||||||
this.nodes = new AtomicInteger(0);
|
|
||||||
this.machineUtils = machineUtils;
|
|
||||||
this.imachineToNodeMetadata = imachineToNodeMetadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
@Inject
|
||||||
* Creates a clone based on the {@link NodeSpec}. It is synchronized because it needs sole access
|
public NodeCreator(Supplier<VirtualBoxManager> manager,
|
||||||
* to the master. Could be improved by locking on a master basis (would allow concurrent cloning
|
Function<CloneSpec, IMachine> cloner, MachineUtils machineUtils,
|
||||||
* as long as form different masters."
|
Function<IMachine, NodeMetadata> imachineToNodeMetadata,
|
||||||
*/
|
RunScriptOnNode.Factory scriptRunnerFactory,
|
||||||
@Override
|
Supplier<NodeMetadata> hostSupplier) {
|
||||||
public synchronized NodeAndInitialCredentials<IMachine> apply(NodeSpec nodeSpec) {
|
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();
|
@Override
|
||||||
checkNotNull(master, "Master");
|
public NodeAndInitialCredentials<IMachine> apply(NodeSpec nodeSpec) {
|
||||||
|
|
||||||
if (master.getMachine().getCurrentSnapshot() != null) {
|
checkNotNull(nodeSpec, "NodeSpec");
|
||||||
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, "");
|
Master master = nodeSpec.getMaster();
|
||||||
|
checkNotNull(master, "Master");
|
||||||
|
|
||||||
String cloneName = VIRTUALBOX_NODE_PREFIX + masterNameWithoutPrefix + "-" + nodeSpec.getTag() + "-"
|
if (master.getMachine().getCurrentSnapshot() != null) {
|
||||||
+ nodeSpec.getName();
|
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)
|
String cloneName = VIRTUALBOX_NODE_PREFIX + masterNameWithoutPrefix
|
||||||
.forceOverwrite(true).build();
|
+ "-" + nodeSpec.getTag() + "-" + nodeSpec.getName();
|
||||||
|
|
||||||
NetworkAdapter natAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.NAT)
|
VmSpec cloneVmSpec = VmSpec.builder().id(cloneName).name(cloneName)
|
||||||
.tcpRedirectRule("127.0.0.1", NODE_PORT_INIT + this.nodes.getAndIncrement(), "", 22).build();
|
.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)
|
NetworkAdapter hostOnlyAdapter = NetworkAdapter.builder()
|
||||||
.staticIp(VMS_NETWORK + this.nodes.getAndIncrement()).build();
|
.networkAttachmentType(NetworkAttachmentType.HostOnly)
|
||||||
|
.staticIp(VMS_NETWORK + this.nodeIps.getAndIncrement()).build();
|
||||||
|
|
||||||
NetworkInterfaceCard hostOnlyIfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(hostOnlyAdapter)
|
NetworkInterfaceCard hostOnlyIfaceCard = NetworkInterfaceCard.builder()
|
||||||
.addHostInterfaceName(HOST_ONLY_IFACE_NAME).slot(1L).build();
|
.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)
|
IMachine cloned = cloner.apply(cloneSpec);
|
||||||
.vm(cloneVmSpec).build();
|
|
||||||
|
|
||||||
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),
|
// TODO get credentials from somewhere else (they are also HC in
|
||||||
RunScriptOptions.NONE);
|
// 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)
|
return nodeAndInitialCredentials;
|
||||||
NodeAndInitialCredentials<IMachine> nodeAndInitialCredentials = new NodeAndInitialCredentials<IMachine>(cloned,
|
}
|
||||||
cloneName, LoginCredentials.builder().user("toor").password("password").authenticateSudo(true).build());
|
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
import org.jclouds.scriptbuilder.domain.Statements;
|
import org.jclouds.scriptbuilder.domain.Statements;
|
||||||
|
import org.jclouds.virtualbox.domain.BridgedIf;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
@ -50,67 +51,56 @@ import com.google.inject.name.Named;
|
||||||
/**
|
/**
|
||||||
* @author Andrea Turli
|
* @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)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
private final Factory runScriptOnNodeFactory;
|
private final Factory runScriptOnNodeFactory;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RetrieveActiveBridgedInterfaces(Factory runScriptOnNodeFactory) {
|
public RetrieveActiveBridgedInterfaces(Factory runScriptOnNodeFactory) {
|
||||||
this.runScriptOnNodeFactory = checkNotNull(runScriptOnNodeFactory, "runScriptOnNodeFactory");
|
this.runScriptOnNodeFactory = checkNotNull(runScriptOnNodeFactory, "runScriptOnNodeFactory");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> apply(NodeMetadata host) {
|
public List<BridgedIf> apply(NodeMetadata host) {
|
||||||
// Bridged Network
|
// Bridged Network
|
||||||
Statement command = Statements.exec("VBoxManage list bridgedifs");
|
Statement command = Statements.exec("VBoxManage list bridgedifs");
|
||||||
String bridgedIfBlocks = runScriptOnNodeFactory.create(host, command, runAsRoot(false).wrapInInitScript(false))
|
String bridgedIfBlocks = runScriptOnNodeFactory.create(host, command, runAsRoot(false).wrapInInitScript(false))
|
||||||
.init().call().getOutput();
|
.init().call().getOutput();
|
||||||
|
|
||||||
List<String> bridgedInterfaces = retrieveBridgedInterfaceNames(bridgedIfBlocks);
|
List<BridgedIf> bridgedInterfaces = retrieveBridgedInterfaceNames(bridgedIfBlocks);
|
||||||
checkNotNull(bridgedInterfaces);
|
checkNotNull(bridgedInterfaces);
|
||||||
|
|
||||||
// union of bridgedNetwork with inet up and !loopback
|
// union of bridgedNetwork with inet up and !loopback
|
||||||
List<String> activeNetworkInterfaceNames = Lists.newArrayList();
|
List<BridgedIf> activeNetworkInterfaces = Lists.newArrayList();
|
||||||
try {
|
try {
|
||||||
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
|
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
|
||||||
for (NetworkInterface inet : Collections.list(nets)) {
|
for (NetworkInterface inet : Collections.list(nets)) {
|
||||||
Iterable<String> filteredBridgedInterface = filter(bridgedInterfaces, new IsActiveBridgedInterface(inet));
|
Iterable<BridgedIf> filteredBridgedInterface = filter(bridgedInterfaces, new IsActiveBridgedInterface(inet));
|
||||||
Iterables.addAll(activeNetworkInterfaceNames, filteredBridgedInterface);
|
Iterables.addAll(activeNetworkInterfaces, filteredBridgedInterface);
|
||||||
}
|
}
|
||||||
} catch (SocketException e) {
|
} catch (SocketException e) {
|
||||||
logger.error(e, "Problem in listing network interfaces.");
|
logger.error(e, "Problem in listing network interfaces.");
|
||||||
Throwables.propagate(e);
|
Throwables.propagate(e);
|
||||||
assert false;
|
assert false;
|
||||||
}
|
}
|
||||||
return activeNetworkInterfaceNames;
|
return activeNetworkInterfaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static List<String> retrieveBridgedInterfaceNames(String bridgedIfBlocks) {
|
protected static List<BridgedIf> retrieveBridgedInterfaceNames(String bridgedIfBlocks) {
|
||||||
List<String> bridgedInterfaceNames = Lists.newArrayList();
|
List<BridgedIf> bridgedInterfaces = Lists.newArrayList();
|
||||||
// separate the different bridge block
|
// separate the different bridge block
|
||||||
for (String bridgedIfBlock : Splitter.on(Pattern.compile("(?m)^[ \t]*\r?\n")).split(bridgedIfBlocks)) {
|
for (String bridgedIfBlock : Splitter.on(Pattern.compile("(?m)^[ \t]*\r?\n")).split(bridgedIfBlocks)) {
|
||||||
|
if(!bridgedIfBlock.isEmpty())
|
||||||
Iterable<String> bridgedIfName = filter(Splitter.on("\n").split(bridgedIfBlock), new Predicate<String>() {
|
bridgedInterfaces.add(new BridgedIfStringToBridgedIf().apply(bridgedIfBlock));
|
||||||
@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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return bridgedInterfaceNames;
|
return bridgedInterfaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class IsActiveBridgedInterface implements Predicate<String> {
|
private class IsActiveBridgedInterface implements Predicate<BridgedIf> {
|
||||||
|
|
||||||
private NetworkInterface networkInterface;
|
private NetworkInterface networkInterface;
|
||||||
|
|
||||||
|
@ -119,10 +109,12 @@ public class RetrieveActiveBridgedInterfaces implements Function<NodeMetadata, L
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(String bridgedInterfaceName) {
|
public boolean apply(BridgedIf bridgedInterface) {
|
||||||
try {
|
try {
|
||||||
return (bridgedInterfaceName.startsWith(networkInterface.getDisplayName()) && networkInterface.isUp() && !networkInterface
|
return (bridgedInterface.getName().startsWith(networkInterface.getDisplayName()) &&
|
||||||
.isLoopback());
|
bridgedInterface.getStatus().equals("Up") &&
|
||||||
|
networkInterface.isUp() &&
|
||||||
|
!networkInterface.isLoopback());
|
||||||
} catch (SocketException e) {
|
} catch (SocketException e) {
|
||||||
logger.error(e, "Problem in listing network interfaces.");
|
logger.error(e, "Problem in listing network interfaces.");
|
||||||
Throwables.propagate(e);
|
Throwables.propagate(e);
|
||||||
|
|
|
@ -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;
|
package org.jclouds.virtualbox.predicates;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
function cleanupUdevIfNeeded {
|
function cleanupUdevIfNeeded {
|
||||||
unset OSNAME;
|
# unset OSNAME;
|
||||||
local OSNAME=`lsb_release -d -s | cut -d ' ' -f 1`; shift
|
# local OSNAME=`lsb_release -d -s | cut -d ' ' -f 1`; shift
|
||||||
if [ $OSNAME = 'Ubuntu' ]
|
# if [ $OSNAME = 'Ubuntu' ]
|
||||||
|
if [ -f '/etc/udev/rules.d/70-persistent-net.rules']
|
||||||
then
|
then
|
||||||
echo "OS is Ubuntu"
|
|
||||||
rm /etc/udev/rules.d/70-persistent-net.rules;
|
rm /etc/udev/rules.d/70-persistent-net.rules;
|
||||||
mkdir /etc/udev/rules.d/70-persistent-net.rules;
|
mkdir /etc/udev/rules.d/70-persistent-net.rules;
|
||||||
rm -rf /dev/.udev/;
|
rm -rf /dev/.udev/;
|
||||||
|
|
|
@ -30,14 +30,11 @@ import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.byon.Node;
|
|
||||||
import org.jclouds.byon.config.CacheNodeStoreModule;
|
|
||||||
import org.jclouds.compute.BaseVersionedServiceLiveTest;
|
import org.jclouds.compute.BaseVersionedServiceLiveTest;
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
|
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
|
||||||
import org.jclouds.concurrent.MoreExecutors;
|
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.Master;
|
||||||
import org.jclouds.virtualbox.domain.VmSpec;
|
import org.jclouds.virtualbox.domain.VmSpec;
|
||||||
import org.jclouds.virtualbox.functions.admin.UnregisterMachineIfExistsAndDeleteItsMedia;
|
import org.jclouds.virtualbox.functions.admin.UnregisterMachineIfExistsAndDeleteItsMedia;
|
||||||
|
import org.jclouds.virtualbox.util.MachineController;
|
||||||
import org.jclouds.virtualbox.util.MachineUtils;
|
import org.jclouds.virtualbox.util.MachineUtils;
|
||||||
import org.testng.annotations.AfterClass;
|
import org.testng.annotations.AfterClass;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
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.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.Splitter;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
@ -80,6 +72,9 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ComputeServiceContext context;
|
protected ComputeServiceContext context;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected MachineController machineController;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected Supplier<VirtualBoxManager> manager;
|
protected Supplier<VirtualBoxManager> manager;
|
||||||
|
@ -160,30 +155,7 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
|
||||||
new UnregisterMachineIfExistsAndDeleteItsMedia(vmSpecification));
|
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) {
|
public String adminDisk(String vmName) {
|
||||||
return workingDir + File.separator + vmName + ".vdi";
|
return workingDir + File.separator + vmName + ".vdi";
|
||||||
|
|
|
@ -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)");
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,8 +26,6 @@ import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTA
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
@ -153,21 +151,11 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest {
|
||||||
}));
|
}));
|
||||||
} finally {
|
} finally {
|
||||||
for (VmSpec spec : ImmutableSet.of(vmSpecification)) {
|
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() {
|
private IMachine getVmWithGuestAdditionsInstalled() {
|
||||||
try {
|
try {
|
||||||
Injector injector = context.utils().injector();
|
Injector injector = context.utils().injector();
|
||||||
|
|
|
@ -25,6 +25,7 @@ import static org.testng.Assert.assertFalse;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
|
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
|
||||||
|
import org.jclouds.virtualbox.domain.BridgedIf;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
@ -51,13 +52,13 @@ public class RetrieveActiveBridgedInterfacesLiveTest extends BaseVirtualBoxClien
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void retrieveBridgedInterfaceNamesTest() {
|
public void retrieveBridgedInterfaceNamesTest() {
|
||||||
List<String> activeBridgedInterfaceNames = retrieveBridgedInterfaceNames(TEST1);
|
List<BridgedIf> activeBridgedInterfaces = retrieveBridgedInterfaceNames(TEST1);
|
||||||
assertEquals(activeBridgedInterfaceNames, expectedBridgedInterfaces);
|
assertEquals(activeBridgedInterfaces, expectedBridgedInterfaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void retrieveAvailableBridgedInterfaceInfoTest() {
|
public void retrieveAvailableBridgedInterfaceInfoTest() {
|
||||||
List<String> bridgedInterface = context.utils().injector().getInstance(RetrieveActiveBridgedInterfaces.class)
|
List<BridgedIf> bridgedInterface = context.utils().injector().getInstance(RetrieveActiveBridgedInterfaces.class)
|
||||||
.apply(host.get());
|
.apply(host.get());
|
||||||
assertFalse(bridgedInterface.isEmpty());
|
assertFalse(bridgedInterface.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@ import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
import org.virtualbox_4_1.CleanupMode;
|
import org.virtualbox_4_1.CleanupMode;
|
||||||
import org.virtualbox_4_1.IMachine;
|
import org.virtualbox_4_1.IMachine;
|
||||||
import org.virtualbox_4_1.IProgress;
|
|
||||||
import org.virtualbox_4_1.ISession;
|
import org.virtualbox_4_1.ISession;
|
||||||
import org.virtualbox_4_1.LockType;
|
import org.virtualbox_4_1.LockType;
|
||||||
import org.virtualbox_4_1.NetworkAttachmentType;
|
import org.virtualbox_4_1.NetworkAttachmentType;
|
||||||
|
@ -123,7 +122,7 @@ public class GuestAdditionsInstallerLiveTest extends
|
||||||
}));
|
}));
|
||||||
} finally {
|
} finally {
|
||||||
for (VmSpec spec : ImmutableSet.of(sourceMachineSpec.getVmSpec())) {
|
for (VmSpec spec : ImmutableSet.of(sourceMachineSpec.getVmSpec())) {
|
||||||
ensureMachineHasPowerDown(spec.getVmName());
|
machineController.ensureMachineHasPowerDown(spec.getVmName());
|
||||||
undoVm(spec);
|
undoVm(spec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue