From dbd669caf8ea89ef811ff24fe97004de04178842 Mon Sep 17 00:00:00 2001 From: Andrea Turli Date: Thu, 1 Mar 2012 16:55:38 +0000 Subject: [PATCH] issue 384: network support refactored --- .gitignore | 1 + .../jclouds/virtualbox/domain/CloneSpec.java | 98 ++++++ .../virtualbox/domain/NetworkAdapter.java | 161 ++++++++++ .../virtualbox/domain/NetworkSpec.java | 56 ++-- .../AttachBridgedAdapterToMachine.java | 26 +- ...NATAdapterToMachineIfNotAlreadyExists.java | 22 +- ...MachineFromIMachineIfNotAlreadyExists.java | 135 +++++---- .../functions/CreateAndInstallVm.java | 13 +- ...isterMachineFromIsoIfNotAlreadyExists.java | 51 ++-- .../AttachBridgedAdapterToMachineTest.java | 74 ++--- ...dapterToMachineIfNotAlreadyExistsTest.java | 137 +++++---- ...hineFromIsoIfNotAlreadyExistsLiveTest.java | 169 ++++++----- .../functions/CreateAndInstallVmLiveTest.java | 280 ++++++++++-------- ...hineFromIsoIfNotAlreadyExistsLiveTest.java | 159 +++++----- .../GuestAdditionsInstallerLiveTest.java | 174 ++++++----- .../IMachinePredicatesLiveTest.java | 117 +++++--- 16 files changed, 1049 insertions(+), 624 deletions(-) create mode 100644 labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/CloneSpec.java create mode 100644 labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/NetworkAdapter.java diff --git a/.gitignore b/.gitignore index e1c23c8b9a..1ce93e0405 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ bin/ *.iws *.DS_STORE TAGS +.metadata/ diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/CloneSpec.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/CloneSpec.java new file mode 100644 index 0000000000..2260b22213 --- /dev/null +++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/CloneSpec.java @@ -0,0 +1,98 @@ +/* + * 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 com.google.common.base.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A complete specification of a "clone" node with networking setup + * and the physical machine specification. + */ +public class CloneSpec { + + private VmSpec vmSpec; + private NetworkSpec networkSpec; + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private VmSpec vmSpec; + private NetworkSpec networkSpec; + + public Builder vm(VmSpec vmSpec) { + this.vmSpec = vmSpec; + return this; + } + + public Builder network(NetworkSpec networkSpec) { + this.networkSpec = networkSpec; + return this; + } + + public CloneSpec build() { + return new CloneSpec(vmSpec, networkSpec); + } + + } + + public CloneSpec(VmSpec vmSpec, NetworkSpec networkSpec) { + checkNotNull(vmSpec, "vmSpec"); + checkNotNull(networkSpec, "networkSpec"); + this.vmSpec = vmSpec; + this.networkSpec = networkSpec; + } + + public VmSpec getVmSpec() { + return vmSpec; + } + + public NetworkSpec getNetworkSpec() { + return networkSpec; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o instanceof VmSpec) { + CloneSpec other = (CloneSpec) o; + return Objects.equal(vmSpec, other.vmSpec) && + Objects.equal(networkSpec, other.networkSpec); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hashCode(vmSpec,networkSpec); + } + + @Override + public String toString() { + return "IMachineSpec{" + + "vmSpec= " + vmSpec + + ", networkSpec= " + networkSpec + + '}'; + } +} diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/NetworkAdapter.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/NetworkAdapter.java new file mode 100644 index 0000000000..4a8f62de91 --- /dev/null +++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/NetworkAdapter.java @@ -0,0 +1,161 @@ +/** + * 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 org.virtualbox_4_1.NetworkAttachmentType; + +import com.google.common.base.Objects; +import com.google.common.collect.Sets; +import org.virtualbox_4_1.NATProtocol; + +import java.util.Collections; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Represents a network adapter in VirtualBox. + *

+ * redirectRules are the redirect rules that are applied to the network adapter. + */ +public class NetworkAdapter { + + private final NetworkAttachmentType networkAttachmentType; + private final String macAddress; + private final Set redirectRules = Sets.newLinkedHashSet(); + + public NetworkAdapter(NetworkAttachmentType networkAttachmentType, + String macAddress, Set redirectRules) { + this.networkAttachmentType = checkNotNull(networkAttachmentType, + "networkAttachmentType"); + this.macAddress = macAddress; + this.redirectRules.addAll(redirectRules); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private NetworkAttachmentType networkAttachmentType; + private String macAddress; + private Set redirectRules = Sets.newLinkedHashSet(); + + /** + * + * @param networkAttachmentType + * @return + */ + public Builder networkAttachmentType( + NetworkAttachmentType networkAttachmentType) { + this.networkAttachmentType = networkAttachmentType; + return this; + } + + /** + * + * @param macAddress + * @return + */ + public Builder macAddress(String macAddress) { + this.macAddress = macAddress; + return this; + } + + /** + * @param host + * incoming address + * @param hostPort + * @param guest + * guest address or empty string for all addresses + * @param guestPort + * @return + */ + public Builder tcpRedirectRule(String host, int hostPort, String guest, + int guestPort) { + redirectRules.add(new RedirectRule(NATProtocol.TCP, host, hostPort, + guest, guestPort)); + return this; + } + + /** + * @param host + * incoming address + * @param hostPort + * @param guest + * guest address or empty string for all addresses + * @param guestPort + * @return + */ + public Builder udpRedirectRule(String host, int hostPort, String guest, + int guestPort) { + redirectRules.add(new RedirectRule(NATProtocol.UDP, host, hostPort, + guest, guestPort)); + return this; + } + + public NetworkAdapter build() { + return new NetworkAdapter(networkAttachmentType, macAddress, + redirectRules); + } + + } + + public NetworkAttachmentType getNetworkAttachmentType() { + return networkAttachmentType; + } + + public Set getRedirectRules() { + return Collections.unmodifiableSet(redirectRules); + } + + public String getMacAddress() { + return macAddress; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o instanceof NetworkAdapter) { + NetworkAdapter other = (NetworkAdapter) o; + return Objects.equal(networkAttachmentType, + other.networkAttachmentType) && + Objects.equal(macAddress, other.macAddress) && + Objects.equal(redirectRules, other.redirectRules); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hashCode(networkAttachmentType, macAddress, redirectRules); + } + + @Override + public String toString() { + return "NetworkAdapter{" + "networkAttachmentType= "+ + networkAttachmentType + + "macAddress= " + macAddress + + "redirectRules= " + redirectRules + + '}'; + } +} diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/NetworkSpec.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/NetworkSpec.java index 54869e47c0..87acaf14a2 100644 --- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/NetworkSpec.java +++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/domain/NetworkSpec.java @@ -16,26 +16,24 @@ * specific language governing permissions and limitations * under the License. */ - package org.jclouds.virtualbox.domain; -import com.google.common.base.Objects; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - import static com.google.common.base.Preconditions.checkNotNull; +import java.util.ArrayList; +import java.util.List; + +import com.google.common.base.Objects; + /** * Describes the network configuration for a VirtualBox machine. */ public class NetworkSpec { - private final Map natNetworkAdapters; + private final List networkInterfaceCards; - public NetworkSpec(final Map natNetworkAdapters) { - this.natNetworkAdapters = checkNotNull(natNetworkAdapters, "natNetworkAdapters"); + public NetworkSpec(final List networkInterfaceCards) { + this.networkInterfaceCards = checkNotNull(networkInterfaceCards, "networkInterfaceCards"); } public static Builder builder() { @@ -44,21 +42,40 @@ public class NetworkSpec { public static class Builder { - private Map natNetworkAdapters = new HashMap(); + private List networkInterfaceCards = new ArrayList(); - public Builder natNetworkAdapter(int slot, NatAdapter adapter) { - this.natNetworkAdapters.put((long) slot, adapter); + public Builder addNIC1(NetworkInterfaceCard networkInterfaceCard) { + NetworkInterfaceCard nic = NetworkInterfaceCard.builder().slot(0L).addNetworkAdapter(networkInterfaceCard.getNetworkAdapter()).build(); + this.networkInterfaceCards.add(nic); return this; } + + public Builder addNIC2(NetworkInterfaceCard networkInterfaceCard) { + NetworkInterfaceCard nic = NetworkInterfaceCard.builder().slot(1L).addNetworkAdapter(networkInterfaceCard.getNetworkAdapter()).build(); + this.networkInterfaceCards.add(nic); + return this; + } + + public Builder addNIC3(NetworkInterfaceCard networkInterfaceCard) { + NetworkInterfaceCard nic = NetworkInterfaceCard.builder().slot(2L).addNetworkAdapter(networkInterfaceCard.getNetworkAdapter()).build(); + this.networkInterfaceCards.add(nic); + return this; + } + + public Builder addNIC4(NetworkInterfaceCard networkInterfaceCard) { + NetworkInterfaceCard nic = NetworkInterfaceCard.builder().slot(3L).addNetworkAdapter(networkInterfaceCard.getNetworkAdapter()).build(); + this.networkInterfaceCards.add(nic); + return this; + } public NetworkSpec build() { - return new NetworkSpec(natNetworkAdapters); + return new NetworkSpec(networkInterfaceCards); } } - public Map getNatNetworkAdapters() { - return Collections.unmodifiableMap(natNetworkAdapters); + public List getNetworkInterfaceCards() { + return networkInterfaceCards; } @Override @@ -66,21 +83,20 @@ public class NetworkSpec { if (this == o) return true; if (o instanceof VmSpec) { NetworkSpec other = (NetworkSpec) o; - return Objects.equal(natNetworkAdapters, other.natNetworkAdapters); + return Objects.equal(networkInterfaceCards, other.networkInterfaceCards); } return false; } @Override public int hashCode() { - return Objects.hashCode(natNetworkAdapters); + return Objects.hashCode(networkInterfaceCards); } - @Override public String toString() { return "NetworkSpec{" + - "natNetworkAdapters=" + natNetworkAdapters + + "networkInterfaceCards= " + networkInterfaceCards + '}'; } } diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachine.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachine.java index aa7026518e..6e0fbcda9a 100644 --- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachine.java +++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachine.java @@ -23,6 +23,7 @@ import static org.virtualbox_4_1.NetworkAttachmentType.Bridged; import javax.annotation.Nullable; +import org.jclouds.virtualbox.domain.NetworkInterfaceCard; import org.virtualbox_4_1.IMachine; import org.virtualbox_4_1.INetworkAdapter; @@ -33,25 +34,20 @@ import com.google.common.base.Function; */ public class AttachBridgedAdapterToMachine implements Function { - private long adapterIndex; - private String macAddress; - private String hostInterface; + private NetworkInterfaceCard networkInterfaceCard; - public AttachBridgedAdapterToMachine(long adapterSlot, String macAddress, - String hostInterface) { - this.adapterIndex = adapterSlot; - this.macAddress = macAddress; - this.hostInterface = hostInterface; - } + public AttachBridgedAdapterToMachine(NetworkInterfaceCard networkInterfaceCard) { + this.networkInterfaceCard = networkInterfaceCard; + } @Override public Void apply(@Nullable IMachine machine) { - INetworkAdapter networkAdapter = machine.getNetworkAdapter(adapterIndex); - networkAdapter.setAttachmentType(Bridged); - networkAdapter.setAdapterType(Am79C973); - networkAdapter.setMACAddress(macAddress); - networkAdapter.setBridgedInterface(hostInterface); - networkAdapter.setEnabled(true); + INetworkAdapter iNetworkAdapter = machine.getNetworkAdapter(networkInterfaceCard.getSlot()); + iNetworkAdapter.setAttachmentType(Bridged); + iNetworkAdapter.setAdapterType(Am79C973); + iNetworkAdapter.setMACAddress(networkInterfaceCard.getNetworkAdapter().getMacAddress()); + iNetworkAdapter.setBridgedInterface(networkInterfaceCard.getNetworkInterfaceName()); + iNetworkAdapter.setEnabled(true); machine.saveSettings(); return null; } diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineIfNotAlreadyExists.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineIfNotAlreadyExists.java index 10d8f0b208..511b0af538 100644 --- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineIfNotAlreadyExists.java +++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineIfNotAlreadyExists.java @@ -23,7 +23,7 @@ import static org.virtualbox_4_1.NetworkAttachmentType.NAT; import javax.annotation.Nullable; -import org.jclouds.virtualbox.domain.NatAdapter; +import org.jclouds.virtualbox.domain.NetworkInterfaceCard; import org.jclouds.virtualbox.domain.RedirectRule; import org.virtualbox_4_1.IMachine; import org.virtualbox_4_1.INetworkAdapter; @@ -32,34 +32,32 @@ import org.virtualbox_4_1.VBoxException; import com.google.common.base.Function; /** - * @author Mattias Holmqvist + * @author Mattias Holmqvist, Andrea Turli */ public class AttachNATAdapterToMachineIfNotAlreadyExists implements Function { - private long adapterSlot; - private NatAdapter natAdapter; + private NetworkInterfaceCard networkInterfaceCard; - public AttachNATAdapterToMachineIfNotAlreadyExists(long adapterSlot, NatAdapter natAdapter) { - this.adapterSlot = adapterSlot; - this.natAdapter = natAdapter; + public AttachNATAdapterToMachineIfNotAlreadyExists(NetworkInterfaceCard networkInterfaceCard) { + this.networkInterfaceCard = networkInterfaceCard; } @Override public Void apply(@Nullable IMachine machine) { - INetworkAdapter networkAdapter = machine.getNetworkAdapter(adapterSlot); - networkAdapter.setAttachmentType(NAT); - for (RedirectRule rule : natAdapter.getRedirectRules()) { + INetworkAdapter iNetworkAdapter = machine.getNetworkAdapter(networkInterfaceCard.getSlot()); + iNetworkAdapter.setAttachmentType(NAT); + for (RedirectRule rule : networkInterfaceCard.getNetworkAdapter().getRedirectRules()) { try { String ruleName = String.format("%s@%s:%s->%s:%s",rule.getProtocol(), rule.getHost(), rule.getHostPort(), rule.getGuest(), rule.getGuestPort()); - networkAdapter.getNatDriver().addRedirect(ruleName, rule.getProtocol(), rule.getHost(), rule.getHostPort(), + iNetworkAdapter.getNatDriver().addRedirect(ruleName, rule.getProtocol(), rule.getHost(), rule.getHostPort(), rule.getGuest(), rule.getGuestPort()); } catch (VBoxException e) { if (!e.getMessage().contains("already exists")) throw e; } } - networkAdapter.setEnabled(true); + iNetworkAdapter.setEnabled(true); machine.saveSettings(); return null; } diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.java index b912a74bab..4f4d6fb11a 100644 --- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.java +++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.java @@ -29,7 +29,10 @@ import javax.inject.Named; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.logging.Logger; import org.jclouds.virtualbox.config.VirtualBoxConstants; +import org.jclouds.virtualbox.domain.CloneSpec; +import org.jclouds.virtualbox.domain.NetworkInterfaceCard; import org.jclouds.virtualbox.domain.VmSpec; +import org.jclouds.virtualbox.util.MachineUtils; import org.virtualbox_4_1.CloneMode; import org.virtualbox_4_1.CloneOptions; import org.virtualbox_4_1.IMachine; @@ -43,70 +46,98 @@ import com.google.common.base.Supplier; import com.google.inject.Inject; /** - * CloneAndRegisterMachineFromIMachineIfNotAlreadyExists will take care of the followings: - cloning - * the master - register the clone machine - + * CloneAndRegisterMachineFromIMachineIfNotAlreadyExists will take care of the + * followings: - cloning the master - register the clone machine - * * @author Andrea Turli */ -public class CloneAndRegisterMachineFromIMachineIfNotAlreadyExists implements Function { +public class CloneAndRegisterMachineFromIMachineIfNotAlreadyExists implements + Function { - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + protected Logger logger = Logger.NULL; - private final Supplier manager; - private final String workingDir; - private final VmSpec vmSpec; - private final boolean isLinkedClone; + private final Supplier manager; + private final String workingDir; + private final CloneSpec cloneSpec; + private final boolean isLinkedClone; + private final MachineUtils machineUtils; + + @Inject + public CloneAndRegisterMachineFromIMachineIfNotAlreadyExists( + Supplier manager, + @Named(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR) String workingDir, + CloneSpec cloneSpec, boolean isLinkedClone, MachineUtils machineUtils) { + this.manager = manager; + this.workingDir = workingDir; + this.cloneSpec = cloneSpec; + this.isLinkedClone = isLinkedClone; + this.machineUtils = machineUtils; + } - @Inject - public CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(Supplier manager, - @Named(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR) String workingDir, VmSpec vmSpec, boolean isLinkedClone) { - this.manager = manager; - this.workingDir = workingDir; - this.vmSpec = vmSpec; - this.isLinkedClone = isLinkedClone; - } + @Override + public IMachine apply(@Nullable IMachine master) { + VmSpec vmSpec = cloneSpec.getVmSpec(); + try { + manager.get().getVBox().findMachine(vmSpec.getVmName()); + throw new IllegalStateException("Machine " + vmSpec.getVmName() + + " is already registered."); + } catch (VBoxException e) { + if (machineNotFoundException(e)) + return cloneMachine(vmSpec, master); + else + throw e; + } + } - @Override - public IMachine apply(@Nullable IMachine master) { - try { - manager.get().getVBox().findMachine(vmSpec.getVmName()); - throw new IllegalStateException("Machine " + vmSpec.getVmName() + " is already registered."); - } catch (VBoxException e) { - if (machineNotFoundException(e)) - return cloneMachine(vmSpec, master); - else - throw e; - } - } + private boolean machineNotFoundException(VBoxException e) { + return e.getMessage().contains( + "VirtualBox error: Could not find a registered machine named ") + || e.getMessage().contains( + "Could not find a registered machine with UUID {"); + } - private boolean machineNotFoundException(VBoxException e) { - return e.getMessage().contains("VirtualBox error: Could not find a registered machine named ") || - e.getMessage().contains("Could not find a registered machine with UUID {"); - } + private IMachine cloneMachine(VmSpec vmSpec, IMachine master) { + String settingsFile = manager.get().getVBox() + .composeMachineFilename(vmSpec.getVmName(), workingDir); + IMachine clonedMachine = manager + .get() + .getVBox() + .createMachine(settingsFile, vmSpec.getVmName(), + vmSpec.getOsTypeId(), vmSpec.getVmId(), + vmSpec.isForceOverwrite()); + List options = new ArrayList(); + if (isLinkedClone) + options.add(CloneOptions.Link); - private IMachine cloneMachine(VmSpec vmSpec, IMachine master) { - String settingsFile = manager.get().getVBox().composeMachineFilename(vmSpec.getVmName(), workingDir); - IMachine clonedMachine = manager.get().getVBox().createMachine(settingsFile, vmSpec.getVmName(), vmSpec.getOsTypeId(), - vmSpec.getVmId(), vmSpec.isForceOverwrite()); - List options = new ArrayList(); - if (isLinkedClone) - options.add(CloneOptions.Link); + // TODO snapshot name + ISnapshot currentSnapshot = new TakeSnapshotIfNotAlreadyAttached( + manager, "snapshotName", "snapshotDesc").apply(master); - // TODO snapshot name - ISnapshot currentSnapshot = new TakeSnapshotIfNotAlreadyAttached(manager, "snapshotName", "snapshotDesc") - .apply(master); + // clone + IProgress progress = currentSnapshot.getMachine().cloneTo( + clonedMachine, CloneMode.MachineState, options); - // clone - IProgress progress = currentSnapshot.getMachine().cloneTo(clonedMachine, CloneMode.MachineState, options); + if (progress.getCompleted()) + logger.debug("clone done"); - if (progress.getCompleted()) - logger.debug("clone done"); - // registering - manager.get().getVBox().registerMachine(clonedMachine); - return clonedMachine; - } + // registering + manager.get().getVBox().registerMachine(clonedMachine); + // Bridged + for (NetworkInterfaceCard networkInterfaceCard : cloneSpec.getNetworkSpec().getNetworkInterfaceCards()) { + ensureBridgedNetworkingIsAppliedToMachine(clonedMachine.getName(), networkInterfaceCard); + } + + return clonedMachine; + } + + private void ensureBridgedNetworkingIsAppliedToMachine(String vmName, + NetworkInterfaceCard nic) { + + machineUtils.writeLockMachineAndApply(vmName, + new AttachBridgedAdapterToMachine(nic)); + } } diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndInstallVm.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndInstallVm.java index ffc64e450c..2aa844d818 100644 --- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndInstallVm.java +++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndInstallVm.java @@ -47,11 +47,13 @@ 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; import com.google.common.base.Splitter; import com.google.common.base.Supplier; +import com.google.common.base.Throwables; import com.google.common.cache.LoadingCache; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; @@ -91,7 +93,7 @@ public class CreateAndInstallVm implements Function { this.machineUtils = machineUtils; this.preConfiguration = preConfiguration; } - + @Override public IMachine apply(MasterSpec masterSpec) { @@ -138,7 +140,8 @@ public class CreateAndInstallVm implements Function { } private void ensureMachineHasPowerDown(String vmName) { - machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function() { + while(manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.RUNNING)) { + machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function() { @Override public Void apply(ISession session) { IProgress powerDownProgress = session.getConsole().powerDown(); @@ -146,6 +149,12 @@ public class CreateAndInstallVm implements Function { return null; } }); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Throwables.propagate(e); + } + } } private void ensureMachineIsLaunched(String vmName) { diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExists.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExists.java index 9f62e1a905..aef24b199b 100644 --- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExists.java +++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExists.java @@ -19,25 +19,39 @@ package org.jclouds.virtualbox.functions; -import com.google.common.base.Function; -import com.google.common.base.Supplier; -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.logging.Logger; -import org.jclouds.virtualbox.config.VirtualBoxConstants; -import org.jclouds.virtualbox.domain.*; -import org.jclouds.virtualbox.util.MachineUtils; -import org.virtualbox_4_1.*; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.File; +import java.util.Set; import javax.annotation.Nullable; import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; -import java.io.File; -import java.util.Map; -import java.util.Set; -import static com.google.common.base.Preconditions.checkNotNull; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.logging.Logger; +import org.jclouds.virtualbox.config.VirtualBoxConstants; +import org.jclouds.virtualbox.domain.DeviceDetails; +import org.jclouds.virtualbox.domain.HardDisk; +import org.jclouds.virtualbox.domain.IsoImage; +import org.jclouds.virtualbox.domain.MasterSpec; +import org.jclouds.virtualbox.domain.NetworkInterfaceCard; +import org.jclouds.virtualbox.domain.NetworkSpec; +import org.jclouds.virtualbox.domain.StorageController; +import org.jclouds.virtualbox.domain.VmSpec; +import org.jclouds.virtualbox.util.MachineUtils; +import org.virtualbox_4_1.AccessMode; +import org.virtualbox_4_1.DeviceType; +import org.virtualbox_4_1.IMachine; +import org.virtualbox_4_1.IMedium; +import org.virtualbox_4_1.IVirtualBox; +import org.virtualbox_4_1.VBoxException; +import org.virtualbox_4_1.VirtualBoxManager; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; /** * @author Mattias Holmqvist @@ -112,12 +126,9 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Functi setupHardDisksForController(vmName, controller); setupDvdsForController(vmSpec, vmName, controller); - // NAT - Map natNetworkAdapters = networkSpec.getNatNetworkAdapters(); - for (Map.Entry natAdapterAndSlot : natNetworkAdapters.entrySet()) { - long slotId = natAdapterAndSlot.getKey(); - NatAdapter natAdapter = natAdapterAndSlot.getValue(); - ensureNATNetworkingIsAppliedToMachine(vmName, slotId, natAdapter); + // Networking + for (NetworkInterfaceCard networkInterfaceCard : networkSpec.getNetworkInterfaceCards()) { + new AttachNicToMachine(vmName, machineUtils).apply(networkInterfaceCard); } } @@ -163,10 +174,6 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Functi machineUtils.writeLockMachineAndApply(vmName, new ApplyMemoryToMachine(memorySize)); } - private void ensureNATNetworkingIsAppliedToMachine(String vmName, long slotId, NatAdapter natAdapter) { - machineUtils.writeLockMachineAndApply(vmName, new AttachNATAdapterToMachineIfNotAlreadyExists(slotId, natAdapter)); - } - public void ensureMachineHasStorageControllerNamed(String vmName, StorageController storageController) { machineUtils.writeLockMachineAndApply(vmName, new AddIDEControllerIfNotExists(checkNotNull( storageController, "storageController"))); diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachineTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachineTest.java index a85789c10f..bd4cfa6c91 100644 --- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachineTest.java +++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachineTest.java @@ -18,18 +18,19 @@ */ package org.jclouds.virtualbox.functions; +import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; -import static org.easymock.classextension.EasyMock.createMock; -import static org.easymock.classextension.EasyMock.createNiceMock; -import static org.easymock.classextension.EasyMock.replay; -import static org.easymock.classextension.EasyMock.verify; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; import static org.virtualbox_4_1.NetworkAdapterType.Am79C973; import static org.virtualbox_4_1.NetworkAttachmentType.Bridged; +import org.jclouds.virtualbox.domain.NetworkAdapter; +import org.jclouds.virtualbox.domain.NetworkInterfaceCard; import org.testng.annotations.Test; import org.virtualbox_4_1.IMachine; import org.virtualbox_4_1.INetworkAdapter; -import org.virtualbox_4_1.VBoxException; +import org.virtualbox_4_1.NetworkAttachmentType; /** * @author Andrea Turli @@ -37,51 +38,32 @@ import org.virtualbox_4_1.VBoxException; @Test(groups = "unit", testName = "AttachBridgedAdapterToMachineTest") public class AttachBridgedAdapterToMachineTest { - private String macAddress; - private String hostInterface; + private String macAddress; + private String hostInterface; - @Test - public void testApplyNetworkingToNonExistingAdapter() throws Exception { - Long adapterId = 0l; - IMachine machine = createMock(IMachine.class); - INetworkAdapter networkAdapter = createMock(INetworkAdapter.class); + @Test + public void testApplyNetworkingToNonExistingAdapter() throws Exception { + Long adapterId = 0l; + IMachine machine = createMock(IMachine.class); + INetworkAdapter iNetworkAdapter = createMock(INetworkAdapter.class); - expect(machine.getNetworkAdapter(adapterId)).andReturn(networkAdapter); - networkAdapter.setAttachmentType(Bridged); - networkAdapter.setAdapterType(Am79C973); - networkAdapter.setMACAddress(macAddress); - networkAdapter.setBridgedInterface(hostInterface); - networkAdapter.setEnabled(true); - machine.saveSettings(); + expect(machine.getNetworkAdapter(adapterId)).andReturn(iNetworkAdapter); + iNetworkAdapter.setAttachmentType(Bridged); + iNetworkAdapter.setAdapterType(Am79C973); + iNetworkAdapter.setMACAddress(macAddress); + iNetworkAdapter.setBridgedInterface(hostInterface); + iNetworkAdapter.setEnabled(true); + machine.saveSettings(); - replay(machine, networkAdapter); + replay(machine, iNetworkAdapter); + NetworkAdapter networkAdapter = NetworkAdapter.builder() + .networkAttachmentType(NetworkAttachmentType.Bridged).build(); + NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard + .builder().addNetworkAdapter(networkAdapter).build(); - new AttachBridgedAdapterToMachine(adapterId, macAddress, hostInterface) - .apply(machine); + new AttachBridgedAdapterToMachine(networkInterfaceCard).apply(machine); - verify(machine, networkAdapter); - } - - @Test(expectedExceptions = VBoxException.class) - public void testRethrowInvalidAdapterSlotException() throws Exception { - Long adapterId = 30l; - IMachine machine = createMock(IMachine.class); - INetworkAdapter networkAdapter = createMock(INetworkAdapter.class); - - String error = "VirtualBox error: Argument slot is invalid " - + "(must be slot < RT_ELEMENTS(mNetworkAdapters)) (0x80070057)"; - - VBoxException invalidSlotException = new VBoxException( - createNiceMock(Throwable.class), error); - expect(machine.getNetworkAdapter(adapterId)).andThrow( - invalidSlotException); - - replay(machine, networkAdapter); - - new AttachBridgedAdapterToMachine(adapterId, macAddress, hostInterface) - .apply(machine); - - verify(machine, networkAdapter); - } + verify(machine, iNetworkAdapter); + } } diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineIfNotAlreadyExistsTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineIfNotAlreadyExistsTest.java index c0b030ca64..916b85107b 100644 --- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineIfNotAlreadyExistsTest.java +++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineIfNotAlreadyExistsTest.java @@ -28,85 +28,108 @@ import static org.easymock.EasyMock.verify; import static org.virtualbox_4_1.NATProtocol.TCP; import static org.virtualbox_4_1.NetworkAttachmentType.NAT; -import org.jclouds.virtualbox.domain.NatAdapter; +import org.jclouds.virtualbox.domain.NetworkAdapter; +import org.jclouds.virtualbox.domain.NetworkInterfaceCard; import org.testng.annotations.Test; import org.virtualbox_4_1.IMachine; import org.virtualbox_4_1.INATEngine; import org.virtualbox_4_1.INetworkAdapter; +import org.virtualbox_4_1.NetworkAttachmentType; import org.virtualbox_4_1.VBoxException; /** - * @author Mattias Holmqvist + * @author Mattias Holmqvist, Andrea Turli */ @Test(groups = "unit", testName = "AttachNATAdapterToMachineIfNotAlreadyExistsTest") public class AttachNATAdapterToMachineIfNotAlreadyExistsTest { - @Test - public void testApplyNetworkingToNonExistingAdapter() throws Exception { - Long slotId = 0l; - IMachine machine = createMock(IMachine.class); - INetworkAdapter networkAdapter = createMock(INetworkAdapter.class); - INATEngine natEngine = createMock(INATEngine.class); + @Test + public void testApplyNetworkingToNonExistingAdapter() throws Exception { + Long slotId = 0l; + IMachine machine = createMock(IMachine.class); + INetworkAdapter iNetworkAdapter = createMock(INetworkAdapter.class); + INATEngine natEngine = createMock(INATEngine.class); - expect(machine.getNetworkAdapter(slotId)).andReturn(networkAdapter); - networkAdapter.setAttachmentType(NAT); - expect(networkAdapter.getNatDriver()).andReturn(natEngine); - - natEngine.addRedirect("TCP@127.0.0.1:2222->:22", TCP, "127.0.0.1", 2222, "", 22); - networkAdapter.setEnabled(true); - machine.saveSettings(); + expect(machine.getNetworkAdapter(slotId)).andReturn(iNetworkAdapter); + iNetworkAdapter.setAttachmentType(NAT); + expect(iNetworkAdapter.getNatDriver()).andReturn(natEngine); - replay(machine, networkAdapter, natEngine); - NatAdapter natAdapter = NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build(); - new AttachNATAdapterToMachineIfNotAlreadyExists(slotId, natAdapter).apply(machine); + natEngine.addRedirect("TCP@127.0.0.1:2222->:22", TCP, "127.0.0.1", + 2222, "", 22); + iNetworkAdapter.setEnabled(true); + machine.saveSettings(); - verify(machine, networkAdapter, natEngine); - } + replay(machine, iNetworkAdapter, natEngine); + NetworkAdapter networkAdapter = NetworkAdapter.builder() + .networkAttachmentType(NetworkAttachmentType.NAT) + .tcpRedirectRule("127.0.0.1", 2222, "", 22).build(); + NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard + .builder().addNetworkAdapter(networkAdapter).build(); - @Test - public void testApplySkipsWhenAlreadyExists() throws Exception { - Long slotId = 0l; - IMachine machine = createMock(IMachine.class); - INetworkAdapter networkAdapter = createMock(INetworkAdapter.class); - INATEngine natEngine = createMock(INATEngine.class); + new AttachNATAdapterToMachineIfNotAlreadyExists(networkInterfaceCard) + .apply(machine); - expect(machine.getNetworkAdapter(slotId)).andReturn(networkAdapter); - networkAdapter.setAttachmentType(NAT); - expect(networkAdapter.getNatDriver()).andReturn(natEngine); - - natEngine.addRedirect("TCP@127.0.0.1:2222->:22", TCP, "127.0.0.1", 2222, "", 22); - expectLastCall().andThrow( - new VBoxException(null, "VirtualBox error: A NAT rule of this name already exists (0x80070057)")); - - networkAdapter.setEnabled(true); - machine.saveSettings(); + verify(machine, iNetworkAdapter, natEngine); + } - replay(machine, networkAdapter, natEngine); - NatAdapter natAdapter = NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build(); - new AttachNATAdapterToMachineIfNotAlreadyExists(slotId, natAdapter).apply(machine); + @Test + public void testApplySkipsWhenAlreadyExists() throws Exception { + Long slotId = 0l; + IMachine machine = createMock(IMachine.class); + INetworkAdapter iNetworkAdapter = createMock(INetworkAdapter.class); + INATEngine natEngine = createMock(INATEngine.class); - verify(machine, networkAdapter, natEngine); - } - - @Test(expectedExceptions = VBoxException.class) - public void testRethrowInvalidAdapterSlotException() throws Exception { - Long slotId = 30l; - IMachine machine = createMock(IMachine.class); - INetworkAdapter networkAdapter = createMock(INetworkAdapter.class); - INATEngine natEngine = createMock(INATEngine.class); + expect(machine.getNetworkAdapter(slotId)).andReturn(iNetworkAdapter); + iNetworkAdapter.setAttachmentType(NAT); + expect(iNetworkAdapter.getNatDriver()).andReturn(natEngine); - String error = "VirtualBox error: Argument slot is invalid " - + "(must be slot < RT_ELEMENTS(mNetworkAdapters)) (0x80070057)"; + natEngine.addRedirect("TCP@127.0.0.1:2222->:22", TCP, "127.0.0.1", + 2222, "", 22); + expectLastCall() + .andThrow( + new VBoxException(null, + "VirtualBox error: A NAT rule of this name already exists (0x80070057)")); - VBoxException invalidSlotException = new VBoxException(createNiceMock(Throwable.class), error); - expect(machine.getNetworkAdapter(slotId)).andThrow(invalidSlotException); + iNetworkAdapter.setEnabled(true); + machine.saveSettings(); - replay(machine, networkAdapter, natEngine); + replay(machine, iNetworkAdapter, natEngine); + NetworkAdapter networkAdapter = NetworkAdapter.builder() + .networkAttachmentType(NetworkAttachmentType.NAT) + .tcpRedirectRule("127.0.0.1", 2222, "", 22).build(); + NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard + .builder().addNetworkAdapter(networkAdapter).build(); + new AttachNATAdapterToMachineIfNotAlreadyExists(networkInterfaceCard) + .apply(machine); - NatAdapter natAdapter = NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build(); - new AttachNATAdapterToMachineIfNotAlreadyExists(slotId, natAdapter).apply(machine); + verify(machine, iNetworkAdapter, natEngine); + } - verify(machine, networkAdapter, natEngine); - } + @Test(enabled=false, expectedExceptions = VBoxException.class) + public void testRethrowInvalidAdapterSlotException() throws Exception { + Long slotId = 30l; + IMachine machine = createMock(IMachine.class); + INetworkAdapter iNetworkAdapter = createMock(INetworkAdapter.class); + INATEngine natEngine = createMock(INATEngine.class); + + String error = "VirtualBox error: Argument slot is invalid " + + "(must be slot < RT_ELEMENTS(mNetworkAdapters)) (0x80070057)"; + + VBoxException invalidSlotException = new VBoxException( + createNiceMock(Throwable.class), error); + expect(machine.getNetworkAdapter(slotId)) + .andThrow(invalidSlotException); + + replay(machine, iNetworkAdapter, natEngine); + NetworkAdapter networkAdapter = NetworkAdapter.builder() + .networkAttachmentType(NetworkAttachmentType.NAT) + .tcpRedirectRule("127.0.0.1", 2222, "", 22).build(); + NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard + .builder().addNetworkAdapter(networkAdapter).build(); + new AttachNATAdapterToMachineIfNotAlreadyExists(networkInterfaceCard) + .apply(machine); + + verify(machine, iNetworkAdapter, natEngine); + } } diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java index 182a5da936..56f2ddd10f 100644 --- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java +++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java @@ -25,20 +25,21 @@ import static org.testng.Assert.assertEquals; import org.jclouds.config.ValueOfConfigurationKeyOrNull; import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest; +import org.jclouds.virtualbox.domain.CloneSpec; import org.jclouds.virtualbox.domain.HardDisk; import org.jclouds.virtualbox.domain.IsoSpec; import org.jclouds.virtualbox.domain.MasterSpec; +import org.jclouds.virtualbox.domain.NetworkAdapter; +import org.jclouds.virtualbox.domain.NetworkInterfaceCard; import org.jclouds.virtualbox.domain.NetworkSpec; import org.jclouds.virtualbox.domain.StorageController; import org.jclouds.virtualbox.domain.VmSpec; -import org.jclouds.virtualbox.functions.CloneAndRegisterMachineFromIMachineIfNotAlreadyExists; -import org.jclouds.virtualbox.functions.CreateAndRegisterMachineFromIsoIfNotAlreadyExists; -import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import org.virtualbox_4_1.CleanupMode; import org.virtualbox_4_1.IMachine; import org.virtualbox_4_1.ISession; +import org.virtualbox_4_1.NetworkAttachmentType; import org.virtualbox_4_1.StorageBus; import com.google.common.base.CaseFormat; @@ -51,93 +52,107 @@ import com.google.inject.Injector; */ @Test(groups = "live", singleThreaded = true, testName = "CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest") public class CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends - BaseVirtualBoxClientLiveTest { + BaseVirtualBoxClientLiveTest { - private static final boolean IS_LINKED_CLONE = true; + private static final boolean IS_LINKED_CLONE = true; - private VmSpec clonedVmSpec; - private MasterSpec sourceMachineSpec; + private CloneSpec cloneSpec; + private MasterSpec sourceMachineSpec; - private CleanupMode mode = CleanupMode.Full; + private CleanupMode mode = CleanupMode.Full; - @Override - @BeforeClass(groups = "live") - public void setupClient() { - super.setupClient(); - String sourceName = VIRTUALBOX_IMAGE_PREFIX - + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass() - .getSimpleName()); - String cloneName = VIRTUALBOX_IMAGE_PREFIX - + "Clone#" - + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass() - .getSimpleName()); + @Override + @BeforeClass(groups = "live") + public void setupClient() { + super.setupClient(); + String sourceName = VIRTUALBOX_IMAGE_PREFIX + + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass() + .getSimpleName()); + String cloneName = VIRTUALBOX_IMAGE_PREFIX + + "Clone#" + + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass() + .getSimpleName()); - StorageController ideController = StorageController - .builder() - .name("IDE Controller") - .bus(StorageBus.IDE) - .attachISO(0, 0, operatingSystemIso) - .attachHardDisk( - HardDisk.builder().diskpath(adminDisk).controllerPort(0) - .deviceSlot(1).autoDelete(true).build()) - .attachISO(1, 1, guestAdditionsIso).build(); + StorageController ideController = StorageController + .builder() + .name("IDE Controller") + .bus(StorageBus.IDE) + .attachISO(0, 0, operatingSystemIso) + .attachHardDisk( + HardDisk.builder().diskpath(adminDisk) + .controllerPort(0).deviceSlot(1) + .autoDelete(true).build()) + .attachISO(1, 1, guestAdditionsIso).build(); - VmSpec sourceVmSpec = VmSpec.builder().id(sourceName).name(sourceName) - .osTypeId("").memoryMB(512).cleanUpMode(CleanupMode.Full) - .controller(ideController).forceOverwrite(true).build(); + VmSpec sourceVmSpec = VmSpec.builder().id(sourceName).name(sourceName) + .osTypeId("").memoryMB(512).cleanUpMode(CleanupMode.Full) + .controller(ideController).forceOverwrite(true).build(); - Injector injector = context.utils().injector(); - Function configProperties = injector - .getInstance(ValueOfConfigurationKeyOrNull.class); - IsoSpec isoSpec = IsoSpec - .builder() - .sourcePath(operatingSystemIso) - .installationScript( - configProperties.apply(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE) - .replace("HOSTNAME", sourceVmSpec.getVmName())).build(); + Injector injector = context.utils().injector(); + Function configProperties = injector + .getInstance(ValueOfConfigurationKeyOrNull.class); + IsoSpec isoSpec = IsoSpec + .builder() + .sourcePath(operatingSystemIso) + .installationScript( + configProperties.apply( + VIRTUALBOX_INSTALLATION_KEY_SEQUENCE).replace( + "HOSTNAME", sourceVmSpec.getVmName())).build(); + + NetworkAdapter networkAdapter = NetworkAdapter.builder() + .networkAttachmentType(NetworkAttachmentType.Bridged).build(); + NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard + .builder().addNetworkAdapter(networkAdapter).build(); - NetworkSpec networkSpec = NetworkSpec.builder().build(); - sourceMachineSpec = MasterSpec.builder().iso(isoSpec).vm(sourceVmSpec).network(networkSpec).build(); + NetworkSpec networkSpec = NetworkSpec.builder() + .addNIC1(networkInterfaceCard).build(); - clonedVmSpec = VmSpec.builder().id(cloneName).name(cloneName) - .memoryMB(512).cleanUpMode(mode).forceOverwrite(true).build(); - } + VmSpec clonedVmSpec = VmSpec.builder().id(cloneName).name(cloneName) + .memoryMB(512).cleanUpMode(mode).forceOverwrite(true).build(); - @Test - public void testCloneMachineFromAnotherMachine() throws Exception { - try { - IMachine source = getSourceNode(); + cloneSpec = CloneSpec.builder().vm(clonedVmSpec).network(networkSpec) + .build(); - if (source.getCurrentSnapshot() != null) { - ISession session = manager.get().openMachineSession(source); - session.getConsole().deleteSnapshot( - source.getCurrentSnapshot().getId()); - session.unlockMachine(); - } + sourceMachineSpec = MasterSpec.builder().iso(isoSpec).vm(sourceVmSpec) + .network(networkSpec).build(); + + } - IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists( - manager, workingDir, clonedVmSpec, IS_LINKED_CLONE) - .apply(source); - assertEquals(clone.getName(), clonedVmSpec.getVmName()); - } finally { - for (VmSpec spec : ImmutableSet.of(clonedVmSpec, - sourceMachineSpec.getVmSpec())) - undoVm(spec); - } + @Test + public void testCloneMachineFromAnotherMachine() throws Exception { + try { + IMachine source = getSourceNode(); - } + if (source.getCurrentSnapshot() != null) { + ISession session = manager.get().openMachineSession(source); + session.getConsole().deleteSnapshot( + source.getCurrentSnapshot().getId()); + session.unlockMachine(); + } - private IMachine getSourceNode() { - try { - Injector injector = context.utils().injector(); - return injector.getInstance( - CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class).apply( - sourceMachineSpec); - } catch (IllegalStateException e) { - // already created - return manager.get().getVBox() - .findMachine(sourceMachineSpec.getVmSpec().getVmId()); - } - } + IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists( + manager, workingDir, cloneSpec, IS_LINKED_CLONE, + machineUtils).apply(source); + assertEquals(clone.getName(), cloneSpec.getVmSpec().getVmName()); + } finally { + for (VmSpec spec : ImmutableSet.of(cloneSpec.getVmSpec(), + sourceMachineSpec.getVmSpec())) + undoVm(spec); + } + + } + + private IMachine getSourceNode() { + try { + Injector injector = context.utils().injector(); + return injector.getInstance( + CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class) + .apply(sourceMachineSpec); + } catch (IllegalStateException e) { + // already created + return manager.get().getVBox() + .findMachine(sourceMachineSpec.getVmSpec().getVmId()); + } + } } \ No newline at end of file diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java index a52b0ab05d..93e96d24a0 100644 --- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java +++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java @@ -45,7 +45,8 @@ import org.jclouds.virtualbox.domain.ExecutionType; import org.jclouds.virtualbox.domain.HardDisk; import org.jclouds.virtualbox.domain.IsoSpec; import org.jclouds.virtualbox.domain.MasterSpec; -import org.jclouds.virtualbox.domain.NatAdapter; +import org.jclouds.virtualbox.domain.NetworkAdapter; +import org.jclouds.virtualbox.domain.NetworkInterfaceCard; import org.jclouds.virtualbox.domain.NetworkSpec; import org.jclouds.virtualbox.domain.StorageController; import org.jclouds.virtualbox.domain.VmSpec; @@ -58,12 +59,15 @@ 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; import org.virtualbox_4_1.StorageBus; +import org.virtualbox_4_1.jaxws.MachineState; import com.google.common.base.CaseFormat; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Splitter; +import com.google.common.base.Throwables; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.inject.Guice; @@ -75,134 +79,166 @@ import com.google.inject.Injector; @Test(groups = "live", singleThreaded = true, testName = "CreateAndInstallVmLiveTest") public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest { - Map> map = new BaseComputeServiceContextModule() { - }.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice - .createInjector(new GsonModule()).getInstance(Json.class)); + Map> map = new BaseComputeServiceContextModule() { + }.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice + .createInjector(new GsonModule()).getInstance(Json.class)); - private VmSpec vmSpecification; - private MasterSpec masterSpec; - private Injector injector; - private Function sshClientForIMachine; - private Predicate sshResponds; + private VmSpec vmSpecification; + private MasterSpec masterSpec; + private Injector injector; + private Function sshClientForIMachine; + private Predicate sshResponds; - - @Override - @BeforeClass(groups = "live") - public void setupClient() { - super.setupClient(); - String vmName = VIRTUALBOX_IMAGE_PREFIX - + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass() - .getSimpleName()); + @Override + @BeforeClass(groups = "live") + public void setupClient() { + super.setupClient(); + String vmName = VIRTUALBOX_IMAGE_PREFIX + + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass() + .getSimpleName()); - HardDisk hardDisk = HardDisk.builder().diskpath(adminDisk).autoDelete(true) - .controllerPort(0).deviceSlot(1).build(); - StorageController ideController = StorageController.builder().name("IDE Controller").bus(StorageBus.IDE) - .attachISO(0, 0, operatingSystemIso) - .attachHardDisk(hardDisk) - .attachISO(1, 1, guestAdditionsIso).build(); - vmSpecification = VmSpec.builder().id(vmName).name(vmName).memoryMB(512).osTypeId("") - .controller(ideController) - .forceOverwrite(true) - .cleanUpMode(CleanupMode.Full).build(); - - injector = context.utils().injector(); - Function configProperties = injector - .getInstance(ValueOfConfigurationKeyOrNull.class); + HardDisk hardDisk = HardDisk.builder().diskpath(adminDisk) + .autoDelete(true).controllerPort(0).deviceSlot(1).build(); + StorageController ideController = StorageController.builder() + .name("IDE Controller").bus(StorageBus.IDE) + .attachISO(0, 0, operatingSystemIso).attachHardDisk(hardDisk) + .attachISO(1, 1, guestAdditionsIso).build(); + vmSpecification = VmSpec.builder().id(vmName).name(vmName) + .memoryMB(512).osTypeId("").controller(ideController) + .forceOverwrite(true).cleanUpMode(CleanupMode.Full).build(); - masterSpec = MasterSpec.builder().vm(vmSpecification) - .iso(IsoSpec.builder() - .sourcePath(operatingSystemIso) - .installationScript(configProperties - .apply(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE) - .replace("HOSTNAME", vmSpecification.getVmName())) - .build()) - .network(NetworkSpec.builder() - .natNetworkAdapter(0, NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build()) - .build()).build(); - - undoVm(vmSpecification); - } + injector = context.utils().injector(); + Function configProperties = injector + .getInstance(ValueOfConfigurationKeyOrNull.class); - public void testCreateImageMachineFromIso() throws Exception { - IMachine imageMachine = getVmWithGuestAdditionsInstalled(); + NetworkAdapter networkAdapter = NetworkAdapter.builder() + .networkAttachmentType(NetworkAttachmentType.NAT) + .tcpRedirectRule("127.0.0.1", 2222, "", 22).build(); + NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard + .builder().addNetworkAdapter(networkAdapter).build(); - IMachineToImage iMachineToImage = new IMachineToImage(manager, map); - Image newImage = iMachineToImage.apply(imageMachine); - // TODO add the description to the cache of the images or serialize to - // YAML the image desc - Set images = context.getComputeService().listImages(); - Iterable imageIds = transform(images, extractId()); - assertTrue(any(imageIds, equalTo(newImage.getId()))); - } - - @Test - public void testGuestAdditionsAreInstalled() throws Exception { - try { - IMachine machine = getVmWithGuestAdditionsInstalled(); - - machineUtils.applyForMachine(machine.getName(), new LaunchMachineIfNotAlreadyRunning(manager.get(), ExecutionType.GUI, "")); - sshClientForIMachine = injector.getInstance(IMachineToSshClient.class); - SshClient client = sshClientForIMachine.apply(machine); - - sshResponds = injector.getInstance(SshResponds.class); - checkState(sshResponds.apply(client), "timed out waiting for guest %s to be accessible via ssh", machine.getName()); - - assertTrue(machineUtils.lockSessionOnMachineAndApply(machine.getName(), LockType.Shared, new Function() { - @Override - public Boolean apply(ISession session) { - String vboxVersion = Iterables.get(Splitter.on('r').split(context.getProviderSpecificContext().getBuildVersion()), 0); - return session.getMachine().getGuestPropertyValue("/VirtualBox/GuestAdd/Version").equals(vboxVersion); - } - })); - } finally { - for (VmSpec spec : ImmutableSet.of( - vmSpecification)) { - ensureMachineHasPowerDown(spec.getVmName()); - } - } - } + NetworkSpec networkSpec = NetworkSpec.builder() + .addNIC1(networkInterfaceCard).build(); - private Function extractId() { - return new Function() { + masterSpec = MasterSpec + .builder() + .vm(vmSpecification) + .iso(IsoSpec + .builder() + .sourcePath(operatingSystemIso) + .installationScript( + configProperties.apply( + VIRTUALBOX_INSTALLATION_KEY_SEQUENCE) + .replace("HOSTNAME", + vmSpecification.getVmName())) + .build()).network(networkSpec).build(); - @Override - public String apply(@Nullable Image input) { - return input.getId(); - } - }; - } + undoVm(vmSpecification); + } - private IMachine getVmWithGuestAdditionsInstalled() { - try { - Injector injector = context.utils().injector(); - return injector.getInstance( - CreateAndInstallVm.class).apply( - masterSpec); - } catch (IllegalStateException e) { - // already created - return manager.get().getVBox() - .findMachine(masterSpec.getVmSpec().getVmId()); - } - } - - private void ensureMachineHasPowerDown(String vmName) { - machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function() { - @Override - public Void apply(ISession session) { - IProgress powerDownProgress = session.getConsole().powerDown(); - powerDownProgress.waitForCompletion(-1); - return null; - } - }); - } - - @Override - @AfterClass(groups = "live") - protected void tearDown() throws Exception { - for (VmSpec spec : ImmutableSet.of( - vmSpecification)) { - undoVm(spec); - } - super.tearDown(); - } + public void testCreateImageMachineFromIso() throws Exception { + IMachine imageMachine = getVmWithGuestAdditionsInstalled(); + + IMachineToImage iMachineToImage = new IMachineToImage(manager, map); + Image newImage = iMachineToImage.apply(imageMachine); + // TODO add the description to the cache of the images or serialize to + // YAML the image desc + Set images = context.getComputeService().listImages(); + Iterable imageIds = transform(images, extractId()); + assertTrue(any(imageIds, equalTo(newImage.getId()))); + } + + @Test + public void testGuestAdditionsAreInstalled() throws Exception { + try { + IMachine machine = getVmWithGuestAdditionsInstalled(); + + machineUtils.applyForMachine(machine.getName(), + new LaunchMachineIfNotAlreadyRunning(manager.get(), + ExecutionType.GUI, "")); + sshClientForIMachine = injector + .getInstance(IMachineToSshClient.class); + SshClient client = sshClientForIMachine.apply(machine); + + sshResponds = injector.getInstance(SshResponds.class); + checkState(sshResponds.apply(client), + "timed out waiting for guest %s to be accessible via ssh", + machine.getName()); + + assertTrue(machineUtils.lockSessionOnMachineAndApply( + machine.getName(), LockType.Shared, + new Function() { + @Override + public Boolean apply(ISession session) { + String vboxVersion = Iterables + .get(Splitter + .on('r') + .split(context + .getProviderSpecificContext() + .getBuildVersion()), 0); + return session + .getMachine() + .getGuestPropertyValue( + "/VirtualBox/GuestAdd/Version") + .equals(vboxVersion); + } + })); + } finally { + for (VmSpec spec : ImmutableSet.of(vmSpecification)) { + ensureMachineHasPowerDown(spec.getVmName()); + } + } + } + + private Function extractId() { + return new Function() { + + @Override + public String apply(@Nullable Image input) { + return input.getId(); + } + }; + } + + private IMachine getVmWithGuestAdditionsInstalled() { + try { + Injector injector = context.utils().injector(); + return injector.getInstance(CreateAndInstallVm.class).apply( + masterSpec); + } catch (IllegalStateException e) { + // already created + return manager.get().getVBox() + .findMachine(masterSpec.getVmSpec().getVmId()); + } + } + + private void ensureMachineHasPowerDown(String vmName) { + while (manager.get().getVBox().findMachine(vmName).getState() + .equals(MachineState.RUNNING)) { + machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, + new Function() { + @Override + public Void apply(ISession session) { + IProgress powerDownProgress = session.getConsole() + .powerDown(); + powerDownProgress.waitForCompletion(-1); + return null; + } + }); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Throwables.propagate(e); + } + } + } + + @Override + @AfterClass(groups = "live") + protected void tearDown() throws Exception { + for (VmSpec spec : ImmutableSet.of(vmSpecification)) { + undoVm(spec); + } + super.tearDown(); + } } diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java index 00ebafc6be..698016f1e2 100644 --- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java +++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java @@ -29,6 +29,7 @@ import org.jclouds.virtualbox.domain.*; import org.testng.annotations.Test; import org.virtualbox_4_1.CleanupMode; import org.virtualbox_4_1.IMachine; +import org.virtualbox_4_1.NetworkAttachmentType; import org.virtualbox_4_1.StorageBus; import org.virtualbox_4_1.VBoxException; @@ -36,87 +37,95 @@ import org.virtualbox_4_1.VBoxException; * @author Mattias Holmqvist */ @Test(groups = "live", singleThreaded = true, testName = "CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest") -public class CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends BaseVirtualBoxClientLiveTest { +public class CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends + BaseVirtualBoxClientLiveTest { - private String ideControllerName; - private CleanupMode mode; - private StorageController ideController; + private String ideControllerName; + private CleanupMode mode; + private StorageController ideController; - @Override - public void setupClient() { - super.setupClient(); - ideControllerName = "IDE Controller"; - mode = CleanupMode.Full; - ideController = StorageController.builder().name(ideControllerName).bus(StorageBus.IDE) - .attachISO(0, 0, operatingSystemIso) - .attachHardDisk(HardDisk.builder().diskpath(adminDisk).controllerPort(0).deviceSlot(1).build()).attachISO(1, 1, - guestAdditionsIso).build(); - } + @Override + public void setupClient() { + super.setupClient(); + ideControllerName = "IDE Controller"; + mode = CleanupMode.Full; + ideController = StorageController + .builder() + .name(ideControllerName) + .bus(StorageBus.IDE) + .attachISO(0, 0, operatingSystemIso) + .attachHardDisk( + HardDisk.builder().diskpath(adminDisk) + .controllerPort(0).deviceSlot(1).build()) + .attachISO(1, 1, guestAdditionsIso).build(); + } - @Test - public void testCreateNewMachine() throws Exception { - String vmName = "jclouds-test-create-1-node"; - String vmId = UUID.randomUUID().toString(); + @Test + public void testCreateNewMachine() throws Exception { + String vmName = "jclouds-test-create-1-node"; + String vmId = UUID.randomUUID().toString(); - VmSpec vmSpec = VmSpec.builder() - .id(vmId) - .name(vmName) - .memoryMB(512) - .controller(ideController) - .cleanUpMode(mode) - .osTypeId("Debian") - .forceOverwrite(true).build(); - MasterSpec machineSpec = MasterSpec.builder() - .iso(IsoSpec.builder() - .sourcePath(operatingSystemIso) - .installationScript("") - .build()) - .vm(vmSpec) - .network(NetworkSpec.builder().build()).build(); - undoVm(vmSpec); - try { - IMachine debianNode = context.utils().injector().getInstance( - CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class).apply(machineSpec); - IMachine machine = manager.get().getVBox().findMachine(vmName); - assertEquals(debianNode.getName(), machine.getName()); - } finally { - undoVm(vmSpec); - } - } + VmSpec vmSpec = VmSpec.builder().id(vmId).name(vmName).memoryMB(512) + .controller(ideController).cleanUpMode(mode).osTypeId("Debian") + .forceOverwrite(true).build(); - @Test - public void testCreateNewMachineWithBadOsType() throws Exception { - String vmName = "jclouds-test-create-2-node"; - String vmId = UUID.randomUUID().toString(); + NetworkAdapter networkAdapter = NetworkAdapter.builder() + .networkAttachmentType(NetworkAttachmentType.NAT) + .tcpRedirectRule("127.0.0.1", 2222, "", 22).build(); + NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard + .builder().addNetworkAdapter(networkAdapter).build(); - VmSpec vmSpec = VmSpec.builder() - .id(vmId) - .name(vmName).memoryMB(512).controller(ideController) - .cleanUpMode(mode).osTypeId("SomeWeirdUnknownOs").forceOverwrite(true).build(); - IsoSpec isoSpec = IsoSpec.builder() - .sourcePath(operatingSystemIso) - .installationScript("") - .build(); - NetworkSpec networkSpec = NetworkSpec.builder().build(); - MasterSpec machineSpec = MasterSpec.builder() - .iso(isoSpec) - .vm(vmSpec) - .network(networkSpec).build(); - undoVm(vmSpec); - try { - Injector injector = context.utils().injector(); - injector.getInstance(CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class) - .apply(machineSpec); - fail(); - } catch (VBoxException e) { - ErrorCode errorCode = ErrorCode.valueOf(e); - // According to the documentation VBOX_E_OBJECT_NOT_FOUND - // if osTypeId is not found. - assertEquals(errorCode, ErrorCode.VBOX_E_OBJECT_NOT_FOUND); - } finally { - undoVm(vmSpec); - } + NetworkSpec networkSpec = NetworkSpec.builder() + .addNIC1(networkInterfaceCard).build(); - } + MasterSpec machineSpec = MasterSpec + .builder() + .iso(IsoSpec.builder().sourcePath(operatingSystemIso) + .installationScript("").build()).vm(vmSpec) + .network(networkSpec).build(); + undoVm(vmSpec); + try { + IMachine debianNode = context.utils() + .injector() + .getInstance( + CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class) + .apply(machineSpec); + IMachine machine = manager.get().getVBox().findMachine(vmName); + assertEquals(debianNode.getName(), machine.getName()); + } finally { + undoVm(vmSpec); + } + } + + @Test + public void testCreateNewMachineWithBadOsType() throws Exception { + String vmName = "jclouds-test-create-2-node"; + String vmId = UUID.randomUUID().toString(); + + VmSpec vmSpec = VmSpec.builder().id(vmId).name(vmName).memoryMB(512) + .controller(ideController).cleanUpMode(mode) + .osTypeId("SomeWeirdUnknownOs").forceOverwrite(true).build(); + IsoSpec isoSpec = IsoSpec.builder().sourcePath(operatingSystemIso) + .installationScript("").build(); + NetworkSpec networkSpec = NetworkSpec.builder().build(); + MasterSpec machineSpec = MasterSpec.builder().iso(isoSpec).vm(vmSpec) + .network(networkSpec).build(); + undoVm(vmSpec); + try { + Injector injector = context.utils().injector(); + injector.getInstance( + CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class) + .apply(machineSpec); + fail(); + } catch (VBoxException e) { + ErrorCode errorCode = ErrorCode.valueOf(e); + // According to the documentation VBOX_E_OBJECT_NOT_FOUND + // if osTypeId is not found. + assertEquals(errorCode, ErrorCode.VBOX_E_OBJECT_NOT_FOUND); + } finally { + undoVm(vmSpec); + } + + } } diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/GuestAdditionsInstallerLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/GuestAdditionsInstallerLiveTest.java index 4abc0fea20..e9c74e3780 100644 --- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/GuestAdditionsInstallerLiveTest.java +++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/GuestAdditionsInstallerLiveTest.java @@ -25,14 +25,17 @@ import static org.testng.Assert.assertTrue; import org.jclouds.config.ValueOfConfigurationKeyOrNull; import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest; +import org.jclouds.virtualbox.domain.ExecutionType; import org.jclouds.virtualbox.domain.HardDisk; import org.jclouds.virtualbox.domain.IsoSpec; import org.jclouds.virtualbox.domain.MasterSpec; -import org.jclouds.virtualbox.domain.NatAdapter; +import org.jclouds.virtualbox.domain.NetworkAdapter; +import org.jclouds.virtualbox.domain.NetworkInterfaceCard; import org.jclouds.virtualbox.domain.NetworkSpec; import org.jclouds.virtualbox.domain.StorageController; import org.jclouds.virtualbox.domain.VmSpec; import org.jclouds.virtualbox.functions.CreateAndInstallVm; +import org.jclouds.virtualbox.functions.LaunchMachineIfNotAlreadyRunning; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import org.virtualbox_4_1.CleanupMode; @@ -40,11 +43,11 @@ 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; import org.virtualbox_4_1.StorageBus; import com.google.common.base.CaseFormat; import com.google.common.base.Function; -import com.google.common.base.Splitter; import com.google.common.collect.ImmutableSet; import com.google.inject.Injector; @@ -53,91 +56,104 @@ import com.google.inject.Injector; */ @Test(groups = "live", singleThreaded = true, testName = "GuestAdditionsInstallerLiveTest") public class GuestAdditionsInstallerLiveTest extends - BaseVirtualBoxClientLiveTest { + BaseVirtualBoxClientLiveTest { - private MasterSpec sourceMachineSpec; + private MasterSpec sourceMachineSpec; - @Override - @BeforeClass(groups = "live") - public void setupClient() { - super.setupClient(); - String sourceName = VIRTUALBOX_IMAGE_PREFIX - + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass() - .getSimpleName()); + @Override + @BeforeClass(groups = "live") + public void setupClient() { + super.setupClient(); + String sourceName = VIRTUALBOX_IMAGE_PREFIX + + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass() + .getSimpleName()); - StorageController ideController = StorageController - .builder() - .name("IDE Controller") - .bus(StorageBus.IDE) - .attachISO(0, 0, operatingSystemIso) - .attachHardDisk( - HardDisk.builder().diskpath(adminDisk).controllerPort(0) - .deviceSlot(1).autoDelete(true).build()) - .attachISO(1, 1, guestAdditionsIso).build(); + StorageController ideController = StorageController + .builder() + .name("IDE Controller") + .bus(StorageBus.IDE) + .attachISO(0, 0, operatingSystemIso) + .attachHardDisk( + HardDisk.builder().diskpath(adminDisk) + .controllerPort(0).deviceSlot(1) + .autoDelete(true).build()) + .attachISO(1, 1, guestAdditionsIso).build(); - VmSpec sourceVmSpec = VmSpec.builder().id(sourceName).name(sourceName) - .osTypeId("").memoryMB(512).cleanUpMode(CleanupMode.Full) - .controller(ideController).forceOverwrite(true).build(); + VmSpec sourceVmSpec = VmSpec.builder().id(sourceName).name(sourceName) + .osTypeId("").memoryMB(512).cleanUpMode(CleanupMode.Full) + .controller(ideController).forceOverwrite(true).build(); - Injector injector = context.utils().injector(); - Function configProperties = injector - .getInstance(ValueOfConfigurationKeyOrNull.class); - IsoSpec isoSpec = IsoSpec - .builder() - .sourcePath(operatingSystemIso) - .installationScript( - configProperties.apply(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE) - .replace("HOSTNAME", sourceVmSpec.getVmName())).build(); + Injector injector = context.utils().injector(); + Function configProperties = injector + .getInstance(ValueOfConfigurationKeyOrNull.class); + IsoSpec isoSpec = IsoSpec + .builder() + .sourcePath(operatingSystemIso) + .installationScript( + configProperties.apply( + VIRTUALBOX_INSTALLATION_KEY_SEQUENCE).replace( + "HOSTNAME", sourceVmSpec.getVmName())).build(); + + NetworkAdapter networkAdapter = NetworkAdapter.builder() + .networkAttachmentType(NetworkAttachmentType.NAT) + .tcpRedirectRule("127.0.0.1", 2222, "", 22).build(); + NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard + .builder().addNetworkAdapter(networkAdapter).build(); - NetworkSpec networkSpec = //NetworkSpec.builder().build(); - NetworkSpec.builder() - .natNetworkAdapter(0, NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build()) - .build(); - sourceMachineSpec = MasterSpec.builder().iso(isoSpec).vm(sourceVmSpec).network(networkSpec).build(); + NetworkSpec networkSpec = NetworkSpec.builder() + .addNIC1(networkInterfaceCard).build(); + sourceMachineSpec = MasterSpec.builder().iso(isoSpec).vm(sourceVmSpec) + .network(networkSpec).build(); - } + } - @Test - public void testGuestAdditionsAreInstalled() throws Exception { - try { - IMachine machine = getVmWithGuestAdditionsInstalled(); - assertTrue(machineUtils.lockSessionOnMachineAndApply(machine.getName(), LockType.Shared, new Function() { - @Override - public Boolean apply(ISession session) { - return session.getMachine().getGuestPropertyValue("/VirtualBox/GuestAdd/Version") != null; - } - })); - } finally { - for (VmSpec spec : ImmutableSet.of( - sourceMachineSpec.getVmSpec())) { - ensureMachineHasPowerDown(spec.getVmName()); - undoVm(spec); - } - } + @Test + public void testGuestAdditionsAreInstalled() throws Exception { + try { + IMachine machine = getVmWithGuestAdditionsInstalled(); + machineUtils.applyForMachine(machine.getName(), + new LaunchMachineIfNotAlreadyRunning(manager.get(), + ExecutionType.GUI, "")); + assertTrue(machineUtils.lockSessionOnMachineAndApply( + machine.getName(), LockType.Shared, + new Function() { + @Override + public Boolean apply(ISession session) { + return session.getMachine().getGuestPropertyValue( + "/VirtualBox/GuestAdd/Version") != null; + } + })); + } finally { + for (VmSpec spec : ImmutableSet.of(sourceMachineSpec.getVmSpec())) { + ensureMachineHasPowerDown(spec.getVmName()); + undoVm(spec); + } + } - } + } - private IMachine getVmWithGuestAdditionsInstalled() { - try { - Injector injector = context.utils().injector(); - return injector.getInstance( - CreateAndInstallVm.class).apply( - sourceMachineSpec); - } catch (IllegalStateException e) { - // already created - return manager.get().getVBox() - .findMachine(sourceMachineSpec.getVmSpec().getVmId()); - } - } - - private void ensureMachineHasPowerDown(String vmName) { - machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function() { - @Override - public Void apply(ISession session) { - IProgress powerDownProgress = session.getConsole().powerDown(); - powerDownProgress.waitForCompletion(-1); - return null; - } - }); - } + private IMachine getVmWithGuestAdditionsInstalled() { + try { + Injector injector = context.utils().injector(); + return injector.getInstance(CreateAndInstallVm.class).apply( + sourceMachineSpec); + } catch (IllegalStateException e) { + // already created + return manager.get().getVBox() + .findMachine(sourceMachineSpec.getVmSpec().getVmId()); + } + } + + private void ensureMachineHasPowerDown(String vmName) { + machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, + new Function() { + @Override + public Void apply(ISession session) { + IProgress powerDownProgress = session.getConsole() + .powerDown(); + powerDownProgress.waitForCompletion(-1); + return null; + } + }); + } } \ No newline at end of file diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/IMachinePredicatesLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/IMachinePredicatesLiveTest.java index 00d2196579..7013989d2c 100644 --- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/IMachinePredicatesLiveTest.java +++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/IMachinePredicatesLiveTest.java @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ + package org.jclouds.virtualbox.predicates; import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX; @@ -23,9 +24,12 @@ import static org.jclouds.virtualbox.predicates.IMachinePredicates.isLinkedClone import static org.testng.Assert.assertTrue; import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest; +import org.jclouds.virtualbox.domain.CloneSpec; import org.jclouds.virtualbox.domain.HardDisk; import org.jclouds.virtualbox.domain.IsoSpec; import org.jclouds.virtualbox.domain.MasterSpec; +import org.jclouds.virtualbox.domain.NetworkAdapter; +import org.jclouds.virtualbox.domain.NetworkInterfaceCard; import org.jclouds.virtualbox.domain.NetworkSpec; import org.jclouds.virtualbox.domain.StorageController; import org.jclouds.virtualbox.domain.VmSpec; @@ -37,6 +41,7 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import org.virtualbox_4_1.CleanupMode; import org.virtualbox_4_1.IMachine; +import org.virtualbox_4_1.NetworkAttachmentType; import org.virtualbox_4_1.StorageBus; import com.google.common.base.CaseFormat; @@ -50,56 +55,78 @@ import com.google.inject.Injector; @Test(groups = "live", singleThreaded = true, testName = "IMachinePredicatesLiveTest") public class IMachinePredicatesLiveTest extends BaseVirtualBoxClientLiveTest { - private String osTypeId = ""; - private String ideControllerName = "IDE Controller"; - private String cloneName; - private String vmName; - private StorageController masterStorageController; - private MasterSpec masterMachineSpec; - private VmSpec cloneSpec; + private String osTypeId = ""; + private String ideControllerName = "IDE Controller"; + private String cloneName; + private String vmName; + private StorageController masterStorageController; + private MasterSpec masterMachineSpec; + private CloneSpec cloneSpec; - @Override - @BeforeClass(groups = "live") - public void setupClient() { - super.setupClient(); - vmName = VIRTUALBOX_IMAGE_PREFIX + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass().getSimpleName()); + @Override + @BeforeClass(groups = "live") + public void setupClient() { + super.setupClient(); + vmName = VIRTUALBOX_IMAGE_PREFIX + + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass() + .getSimpleName()); - cloneName = VIRTUALBOX_IMAGE_PREFIX + "Clone#" - + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass().getSimpleName()); + cloneName = VIRTUALBOX_IMAGE_PREFIX + + "Clone#" + + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass() + .getSimpleName()); - HardDisk hardDisk = HardDisk.builder().diskpath(adminDisk).autoDelete(true).controllerPort(0).deviceSlot(1) - .build(); - masterStorageController = StorageController.builder().name(ideControllerName).bus(StorageBus.IDE).attachISO(0, 0, - operatingSystemIso).attachHardDisk(hardDisk).attachISO(1, 1, guestAdditionsIso).build(); - VmSpec masterSpec = VmSpec.builder().id(vmName).name(vmName).memoryMB(512).osTypeId(osTypeId).controller( - masterStorageController).forceOverwrite(true).cleanUpMode(CleanupMode.Full).build(); - masterMachineSpec = MasterSpec.builder() - .iso(IsoSpec.builder() - .sourcePath(operatingSystemIso) - .installationScript("").build()) - .vm(masterSpec) - .network(NetworkSpec.builder().build()).build(); - - cloneSpec = VmSpec.builder().id(cloneName).name(cloneName).memoryMB(512).cleanUpMode(CleanupMode.Full) - .forceOverwrite(true).build(); - } + HardDisk hardDisk = HardDisk.builder().diskpath(adminDisk) + .autoDelete(true).controllerPort(0).deviceSlot(1).build(); + masterStorageController = StorageController.builder() + .name(ideControllerName).bus(StorageBus.IDE) + .attachISO(0, 0, operatingSystemIso).attachHardDisk(hardDisk) + .attachISO(1, 1, guestAdditionsIso).build(); + VmSpec masterSpec = VmSpec.builder().id(vmName).name(vmName) + .memoryMB(512).osTypeId(osTypeId) + .controller(masterStorageController).forceOverwrite(true) + .cleanUpMode(CleanupMode.Full).build(); + masterMachineSpec = MasterSpec + .builder() + .iso(IsoSpec.builder().sourcePath(operatingSystemIso) + .installationScript("").build()).vm(masterSpec) + .network(NetworkSpec.builder().build()).build(); - @Test - public void testLinkedClone() { + NetworkAdapter networkAdapter = NetworkAdapter.builder() + .networkAttachmentType(NetworkAttachmentType.Bridged).build(); + NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard + .builder().addNetworkAdapter(networkAdapter).build(); - Injector injector = context.utils().injector(); - IMachine master = injector.getInstance(CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class).apply( - masterMachineSpec); - IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(manager, workingDir, cloneSpec, true) - .apply(master); + NetworkSpec networkSpec = NetworkSpec.builder() + .addNIC1(networkInterfaceCard).build(); - assertTrue(isLinkedClone().apply(clone)); - } + VmSpec clonedVmSpec = VmSpec.builder().id(cloneName).name(cloneName) + .memoryMB(512).cleanUpMode(CleanupMode.Full) + .forceOverwrite(true).build(); - @BeforeMethod - @AfterMethod - void cleanUpVms() { - for (VmSpec spec : ImmutableSet.of(cloneSpec, masterMachineSpec.getVmSpec())) - this.undoVm(spec); - } + cloneSpec = CloneSpec.builder().vm(clonedVmSpec).network(networkSpec) + .build(); + } + + @Test + public void testLinkedClone() { + + Injector injector = context.utils().injector(); + IMachine master = injector.getInstance( + CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class).apply( + masterMachineSpec); + IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists( + manager, workingDir, cloneSpec, true, machineUtils) + .apply(master); + + assertTrue(isLinkedClone().apply(clone)); + } + + @BeforeMethod + @AfterMethod + void cleanUpVms() { + for (VmSpec spec : ImmutableSet.of(cloneSpec.getVmSpec(), + masterMachineSpec.getVmSpec())) + this.undoVm(spec); + } }