Added support for changing the IP of a VBox Node at runtime. Added use of CacheLoader for the VBox ComputeService.

This commit is contained in:
Mattias Holmqvist 2011-09-24 02:04:44 +02:00
parent c46c0b4c47
commit fc5d172523
21 changed files with 621 additions and 234 deletions

View File

@ -21,5 +21,17 @@
package org.jclouds.virtualbox; package org.jclouds.virtualbox;
import org.virtualbox_4_1.VirtualBoxManager;
public class VirtualBox { public class VirtualBox {
private VirtualBoxManager manager;
public VirtualBox() {
this.manager = VirtualBoxManager.createInstance("");
}
public VirtualBoxManager manager() {
return manager;
}
} }

View File

@ -24,6 +24,7 @@ package org.jclouds.virtualbox;
import org.jclouds.PropertiesBuilder; import org.jclouds.PropertiesBuilder;
import org.jclouds.virtualbox.config.VirtualBoxConstants; import org.jclouds.virtualbox.config.VirtualBoxConstants;
import java.io.File;
import java.util.Properties; import java.util.Properties;
import static org.jclouds.Constants.*; import static org.jclouds.Constants.*;
@ -51,6 +52,22 @@ public class VirtualBoxPropertiesBuilder extends PropertiesBuilder {
properties.put(PROPERTY_ENDPOINT, "http://localhost:18083/"); properties.put(PROPERTY_ENDPOINT, "http://localhost:18083/");
properties.put(VirtualBoxConstants.VIRTUALBOX_PRESEED_URL, "http://dl.dropbox.com/u/693111/preseed.cfg"); properties.put(VirtualBoxConstants.VIRTUALBOX_PRESEED_URL, "http://dl.dropbox.com/u/693111/preseed.cfg");
properties.put(VirtualBoxConstants.VIRTUALBOX_SNAPSHOT_DESCRIPTION, "jclouds-virtualbox-snaphot"); properties.put(VirtualBoxConstants.VIRTUALBOX_SNAPSHOT_DESCRIPTION, "jclouds-virtualbox-snaphot");
properties.put(VirtualBoxConstants.VIRTUALBOX_HOSTNAME, "jclouds-virtualbox-kickstart-admin");
properties.put(VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE, "<Esc><Esc><Enter> "
+ "/install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg "
+ "debian-installer=en_US auto locale=en_US kbd-chooser/method=us "
+ "hostname="
+ properties.get(VirtualBoxConstants.VIRTUALBOX_HOSTNAME)
+ " "
+ "fb=false debconf/frontend=noninteractive "
+ "keyboard-configuration/layout=USA keyboard-configuration/variant=USA console-setup/ask_detect=false "
+ "initrd=/install/initrd.gz -- <Enter>");
properties.put(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR, System.getProperty("user.home")
+ File.separator
+ System.getProperty("test.virtualbox.workingDir",
"jclouds-virtualbox-test"));
// TODO: Add more properties and use the wired properties from test code. // TODO: Add more properties and use the wired properties from test code.
return properties; return properties;
} }

View File

@ -0,0 +1,107 @@
/*
* *
* * 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.compute;
import com.google.common.base.Function;
import com.google.common.cache.CacheLoader;
import org.jclouds.byon.Node;
import org.jclouds.compute.domain.OsFamily;
import org.virtualbox_4_1.IGuestOSType;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.VirtualBoxManager;
import javax.inject.Inject;
import java.net.URI;
import java.net.URISyntaxException;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.*;
/**
* Loads a node from a VirtualBox IMachine
*
* @author Mattias Holmqvist
*/
public class LoadMachineFromVirtualBox extends CacheLoader<String, Node> {
private VirtualBoxManager manager;
private Function<IMachine, String> iMachineToIpAddress;
@Inject
public LoadMachineFromVirtualBox(VirtualBoxManager manager, Function<IMachine, String> iMachineToIpAddress) {
this.manager = manager;
this.iMachineToIpAddress = iMachineToIpAddress;
}
@Override
public Node load(final String id) throws Exception {
if (id.equals("host")) {
final Node hostNode = Node.builder().id("host")
.name("host installing virtualbox")
.hostname("localhost")
.osFamily(OsFamily.LINUX.toString())
.osDescription(System.getProperty("os.name"))
.osVersion(System.getProperty("os.version"))
.group("ssh")
.username(System.getProperty("user.name"))
.credentialUrl(privateKeyFile())
.build();
return hostNode;
}
final IMachine machine = manager.getVBox().findMachine(id);
final String ipAddress = iMachineToIpAddress.apply(machine);
final String osTypeId = machine.getOSTypeId();
final IGuestOSType guestOSType = manager.getVBox().getGuestOSType(osTypeId);
final Node node = Node.builder()
.id(machine.getId())
.name(machine.getName())
.description(machine.getDescription())
.loginPort(22)
.group(System.getProperty(VIRTUALBOX_MACHINE_GROUP))
.username(System.getProperty(VIRTUALBOX_MACHINE_USERNAME))
.credential(System.getProperty(VIRTUALBOX_MACHINE_CREDENTIAL))
.sudoPassword(System.getProperty(VIRTUALBOX_MACHINE_CREDENTIAL))
.locationId(System.getProperty(VIRTUALBOX_MACHINE_LOCATION))
.os64Bit(guestOSType.getIs64Bit())
.osArch(guestOSType.getDescription())
.osFamily(guestOSType.getFamilyDescription())
.osVersion(guestOSType.getId())
.osDescription(guestOSType.getDescription())
.hostname(ipAddress)
.build();
return node;
}
private static URI privateKeyFile() {
try {
return new URI("file://" + System.getProperty("user.home") + "/.ssh/id_rsa");
} catch (URISyntaxException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -21,28 +21,19 @@
package org.jclouds.virtualbox.compute; package org.jclouds.virtualbox.compute;
import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.Throwables;
import com.google.inject.Singleton;
import java.util.Collections;
import java.util.Map;
import javax.inject.Inject;
import org.jclouds.compute.ComputeServiceAdapter; import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.virtualbox.domain.Host; import org.jclouds.virtualbox.domain.Host;
import org.jclouds.virtualbox.domain.Image; import org.virtualbox_4_1.*;
import org.jclouds.virtualbox.domain.VMSpec;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IProgress;
import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.SessionState;
import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Throwables; import javax.inject.Inject;
import com.google.inject.Singleton; import java.util.Collections;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* Defines the connection between the {@link org.virtualbox_4_1.VirtualBoxManager} implementation and the jclouds * Defines the connection between the {@link org.virtualbox_4_1.VirtualBoxManager} implementation and the jclouds
@ -51,7 +42,7 @@ import com.google.inject.Singleton;
* @author Mattias Holmqvist, Andrea Turli * @author Mattias Holmqvist, Andrea Turli
*/ */
@Singleton @Singleton
public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IMachine, VMSpec, Image, Host> { public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IMachine, IMachine, IMachine, Host> {
private final VirtualBoxManager manager; private final VirtualBoxManager manager;
@ -71,12 +62,12 @@ public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IM
} }
@Override @Override
public Iterable<VMSpec> listHardwareProfiles() { public Iterable<IMachine> listHardwareProfiles() {
return Collections.emptyList(); return Collections.emptyList();
} }
@Override @Override
public Iterable<Image> listImages() { public Iterable<IMachine> listImages() {
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@ -21,41 +21,39 @@
package org.jclouds.virtualbox.config; package org.jclouds.virtualbox.config;
import java.net.URI; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import javax.inject.Named; import com.google.common.base.Supplier;
import javax.inject.Singleton; import com.google.common.collect.ImmutableMap;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.compute.ComputeServiceAdapter; import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.ComputeServiceAdapterContextModule; import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.*;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.location.Provider; import org.jclouds.location.Provider;
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone; import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
import org.jclouds.virtualbox.compute.VirtualBoxComputeServiceAdapter; import org.jclouds.virtualbox.compute.VirtualBoxComputeServiceAdapter;
import org.jclouds.virtualbox.domain.Host; import org.jclouds.virtualbox.domain.Host;
import org.jclouds.virtualbox.domain.Image;
import org.jclouds.virtualbox.domain.VMSpec;
import org.jclouds.virtualbox.functions.HostToLocation; import org.jclouds.virtualbox.functions.HostToLocation;
import org.jclouds.virtualbox.functions.IMachineToHardware;
import org.jclouds.virtualbox.functions.IMachineToImage;
import org.jclouds.virtualbox.functions.IMachineToNodeMetadata; import org.jclouds.virtualbox.functions.IMachineToNodeMetadata;
import org.jclouds.virtualbox.functions.ImageToImage;
import org.jclouds.virtualbox.functions.VMSpecToHardware;
import org.virtualbox_4_1.IMachine; import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.MachineState;
import org.virtualbox_4_1.VirtualBoxManager; import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Function; import javax.inject.Named;
import com.google.common.base.Supplier; import javax.inject.Singleton;
import com.google.inject.Injector; import java.net.URI;
import com.google.inject.Provides; import java.util.Map;
import com.google.inject.TypeLiteral;
/** /**
* @author Mattias Holmqvist, Andrea Turli * @author Mattias Holmqvist, Andrea Turli
*/ */
public class VirtualBoxComputeServiceContextModule extends ComputeServiceAdapterContextModule<VirtualBoxManager, VirtualBoxManager, IMachine, VMSpec, Image, Host> { public class VirtualBoxComputeServiceContextModule extends ComputeServiceAdapterContextModule<VirtualBoxManager, VirtualBoxManager, IMachine, IMachine, IMachine, Host> {
public VirtualBoxComputeServiceContextModule() { public VirtualBoxComputeServiceContextModule() {
super(VirtualBoxManager.class, VirtualBoxManager.class); super(VirtualBoxManager.class, VirtualBoxManager.class);
@ -73,16 +71,16 @@ public class VirtualBoxComputeServiceContextModule extends ComputeServiceAdapter
@Override @Override
protected void configure() { protected void configure() {
super.configure(); super.configure();
bind(new TypeLiteral<ComputeServiceAdapter<IMachine, VMSpec, Image, Host>>() { bind(new TypeLiteral<ComputeServiceAdapter<IMachine, IMachine, IMachine, Host>>() {
}).to(VirtualBoxComputeServiceAdapter.class); }).to(VirtualBoxComputeServiceAdapter.class);
bind(new TypeLiteral<Function<IMachine, NodeMetadata>>() { bind(new TypeLiteral<Function<IMachine, NodeMetadata>>() {
}).to(IMachineToNodeMetadata.class); }).to(IMachineToNodeMetadata.class);
bind(new TypeLiteral<Function<Host, Location>>() { bind(new TypeLiteral<Function<Host, Location>>() {
}).to(HostToLocation.class); }).to(HostToLocation.class);
bind(new TypeLiteral<Function<VMSpec, org.jclouds.compute.domain.Hardware>>() { bind(new TypeLiteral<Function<IMachine, Hardware>>() {
}).to(VMSpecToHardware.class); }).to(IMachineToHardware.class);
bind(new TypeLiteral<Function<Image, org.jclouds.compute.domain.Image>>() { bind(new TypeLiteral<Function<IMachine, Image>>() {
}).to(ImageToImage.class); }).to(IMachineToImage.class);
bind(new TypeLiteral<Supplier<Location>>() { bind(new TypeLiteral<Supplier<Location>>() {
}).to(OnlyLocationOrFirstZone.class); }).to(OnlyLocationOrFirstZone.class);
} }
@ -91,4 +89,34 @@ public class VirtualBoxComputeServiceContextModule extends ComputeServiceAdapter
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) { protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
return template.osFamily(OsFamily.UBUNTU).os64Bit(false).osVersionMatches("11.04-server"); return template.osFamily(OsFamily.UBUNTU).os64Bit(false).osVersionMatches("11.04-server");
} }
@VisibleForTesting
public static final Map<MachineState, NodeState> machineToNodeState = ImmutableMap
.<MachineState, NodeState>builder()
.put(MachineState.Running, NodeState.RUNNING)
.put(MachineState.PoweredOff, NodeState.SUSPENDED)
.put(MachineState.DeletingSnapshot, NodeState.PENDING)
.put(MachineState.DeletingSnapshotOnline, NodeState.PENDING)
.put(MachineState.DeletingSnapshotPaused, NodeState.PENDING)
.put(MachineState.FaultTolerantSyncing, NodeState.PENDING)
.put(MachineState.LiveSnapshotting, NodeState.PENDING)
.put(MachineState.SettingUp, NodeState.PENDING)
.put(MachineState.Starting, NodeState.PENDING)
.put(MachineState.Stopping, NodeState.PENDING)
.put(MachineState.Restoring, NodeState.PENDING)
// TODO What to map these states to?
.put(MachineState.FirstOnline, NodeState.PENDING)
.put(MachineState.FirstTransient, NodeState.PENDING)
.put(MachineState.LastOnline, NodeState.PENDING)
.put(MachineState.LastTransient, NodeState.PENDING)
.put(MachineState.Teleported, NodeState.PENDING)
.put(MachineState.TeleportingIn, NodeState.PENDING)
.put(MachineState.TeleportingPausedVM, NodeState.PENDING)
.put(MachineState.Aborted, NodeState.ERROR)
.put(MachineState.Stuck, NodeState.ERROR)
.put(MachineState.Null, NodeState.UNRECOGNIZED).build();
} }

View File

@ -33,5 +33,21 @@ public interface VirtualBoxConstants {
public static final String VIRTUALBOX_SNAPSHOT_DESCRIPTION = "jclouds.virtualbox.snapshotDescription"; public static final String VIRTUALBOX_SNAPSHOT_DESCRIPTION = "jclouds.virtualbox.snapshotDescription";
public static final String VIRTUALBOX_INSTALLATION_KEY_SEQUENCE = "jclouds.virtualbox.installationkeysequence";
public static final String VIRTUALBOX_HOSTNAME = "jclouds.virtualbox.hostname";
public static final String VIRTUALBOX_WORKINGDIR = "jclouds.virtualbox.workingdir";
public static final String VIRTUALBOX_ISOFILE = "jclouds.virtualbox.isofile";
public static final String VIRTUALBOX_MACHINE_GROUP = "jclouds.virtualbox.machinegroup";
public static final String VIRTUALBOX_MACHINE_USERNAME = "jclouds.virtualbox.username";
public static final String VIRTUALBOX_MACHINE_CREDENTIAL = "jclouds.virtualbox.credential";
public static final String VIRTUALBOX_MACHINE_LOCATION = "jclouds.virtualbox.location";
public static final String VIRTUALBOX_HOST_ID = "jclouds.virtualbox.hostid";
} }

View File

@ -1,26 +0,0 @@
/*
* *
* * 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;
public class Image {
}

View File

@ -1,25 +0,0 @@
/*
* *
* * 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;
public class Snapshot {
}

View File

@ -1,25 +0,0 @@
/*
* *
* * 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;
public class VMSpec {
}

View File

@ -22,15 +22,35 @@
package org.jclouds.virtualbox.functions; package org.jclouds.virtualbox.functions;
import com.google.common.base.Function; import com.google.common.base.Function;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.HardwareBuilder; import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.virtualbox.domain.VMSpec; import org.jclouds.virtualbox.VirtualBox;
import org.virtualbox_4_1.IGuestOSType;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.VirtualBoxManager;
public class VMSpecToHardware implements Function<VMSpec, org.jclouds.compute.domain.Hardware> { import javax.inject.Inject;
public class IMachineToHardware implements Function<IMachine, Hardware> {
private VirtualBox vbox;
@Inject
public IMachineToHardware(VirtualBox vbox) {
this.vbox = vbox;
}
@Override @Override
public org.jclouds.compute.domain.Hardware apply(@Nullable VMSpec input) { public Hardware apply(@Nullable IMachine vm) {
String osTypeId = vm.getOSTypeId();
IGuestOSType guestOSType = vbox.manager().getVBox().getGuestOSType(osTypeId);
Boolean is64Bit = guestOSType.getIs64Bit();
HardwareBuilder hardwareBuilder = new HardwareBuilder(); HardwareBuilder hardwareBuilder = new HardwareBuilder();
return hardwareBuilder.build(); hardwareBuilder.ids(vm.getId());
vm.getSessionPid();
hardwareBuilder.is64Bit(is64Bit);
return null;
} }
} }

View File

@ -22,14 +22,18 @@
package org.jclouds.virtualbox.functions; package org.jclouds.virtualbox.functions;
import com.google.common.base.Function; import com.google.common.base.Function;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder; import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.virtualbox.domain.Image; import org.virtualbox_4_1.IMachine;
public class IMachineToImage implements Function<IMachine, Image> {
public class ImageToImage implements Function<Image, org.jclouds.compute.domain.Image> {
@Override @Override
public org.jclouds.compute.domain.Image apply(@Nullable Image from) { public Image apply(@Nullable IMachine vm) {
ImageBuilder imageBuilder = new ImageBuilder(); ImageBuilder imageBuilder = new ImageBuilder();
return imageBuilder.build(); imageBuilder.ids(vm.getId());
return null;
} }
} }

View File

@ -0,0 +1,91 @@
/*
* *
* * 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 com.google.common.base.Function;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.virtualbox.config.VirtualBoxConstants;
import org.virtualbox_4_1.IGuestOSType;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.VirtualBoxManager;
import javax.annotation.Nullable;
import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
public class IMachineToIpAddress implements Function<IMachine, String> {
private VirtualBoxManager manager;
private ComputeService computeService;
public IMachineToIpAddress(VirtualBoxManager manager, ComputeService computeService) {
this.manager = manager;
this.computeService = computeService;
}
@Override
public String apply(@Nullable IMachine machine) {
String macAddress = machine.getNetworkAdapter(0l).getMACAddress();
int offset = 0, step = 2;
for (int j = 1; j <= 5; j++) {
macAddress = new StringBuffer(macAddress).insert(j * step + offset, ":").toString().toLowerCase();
offset++;
}
String simplifiedMacAddressOfClonedVM = macAddress;
final String hostId = System.getProperty(VirtualBoxConstants.VIRTUALBOX_HOST_ID);
IMachine hostMachine = manager.getVBox().findMachine(hostId);
if (isOSX(hostMachine)) {
if (simplifiedMacAddressOfClonedVM.contains("00"))
simplifiedMacAddressOfClonedVM = new StringBuffer(simplifiedMacAddressOfClonedVM).delete(simplifiedMacAddressOfClonedVM.indexOf("00"), simplifiedMacAddressOfClonedVM.indexOf("00") + 1).toString();
if (simplifiedMacAddressOfClonedVM.contains("0"))
if (simplifiedMacAddressOfClonedVM.indexOf("0") + 1 != ':' && simplifiedMacAddressOfClonedVM.indexOf("0") - 1 != ':')
simplifiedMacAddressOfClonedVM = new StringBuffer(simplifiedMacAddressOfClonedVM).delete(simplifiedMacAddressOfClonedVM.indexOf("0"), simplifiedMacAddressOfClonedVM.indexOf("0") + 1).toString();
}
ExecResponse execResponse = runScriptOnNode(hostId, "for i in {1..254} ; do ping -c 1 -t 1 192.168.2.$i & done", runAsRoot(false).wrapInInitScript(false));
System.out.println(execResponse);
String arpLine = runScriptOnNode(hostId, "arp -an | grep " + simplifiedMacAddressOfClonedVM, runAsRoot(false).wrapInInitScript(false)).getOutput();
String ipAddress = arpLine.substring(arpLine.indexOf("(") + 1, arpLine.indexOf(")"));
System.out.println("IP address " + ipAddress);
return ipAddress;
}
private ExecResponse runScriptOnNode(String nodeId, String command, RunScriptOptions options) {
return computeService.runScriptOnNode(nodeId, command, options);
}
protected boolean isOSX(IMachine machine) {
String osTypeId = machine.getOSTypeId();
IGuestOSType guestOSType = manager.getVBox().getGuestOSType(osTypeId);
String familyDescription = guestOSType.getFamilyDescription();
return true;
}
}

View File

@ -19,36 +19,24 @@
package org.jclouds.virtualbox.functions; package org.jclouds.virtualbox.functions;
import java.util.HashMap; import com.google.common.base.Function;
import java.util.HashSet; import org.jclouds.compute.domain.*;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Named;
import org.eclipse.jetty.server.Server;
import org.jclouds.collect.FindResourceInSet;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope; import org.jclouds.domain.LocationScope;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.virtualbox_4_1.IMachine; import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.INetworkAdapter;
import org.virtualbox_4_1.MachineState; import org.virtualbox_4_1.MachineState;
import com.google.common.base.Function; import javax.annotation.Resource;
import com.google.common.base.Supplier; import javax.inject.Named;
import com.google.inject.Inject; import java.util.HashSet;
import com.google.inject.Singleton; import java.util.Set;
import static org.jclouds.virtualbox.config.VirtualBoxComputeServiceContextModule.machineToNodeState;
public class IMachineToNodeMetadata implements Function<IMachine, NodeMetadata> { public class IMachineToNodeMetadata implements Function<IMachine, NodeMetadata> {
@ -87,43 +75,21 @@ public class IMachineToNodeMetadata implements Function<IMachine, NodeMetadata>
nodeMetadataBuilder.hostname(vm.getName()); nodeMetadataBuilder.hostname(vm.getName());
nodeMetadataBuilder.loginPort(18083); nodeMetadataBuilder.loginPort(18083);
Map<MachineState, NodeState> nodeStateMap = new HashMap<MachineState, NodeState>();
nodeStateMap.put(MachineState.Running, NodeState.RUNNING);
nodeStateMap.put(MachineState.PoweredOff, NodeState.SUSPENDED);
nodeStateMap.put(MachineState.DeletingSnapshot, NodeState.PENDING);
nodeStateMap.put(MachineState.DeletingSnapshotOnline, NodeState.PENDING);
nodeStateMap.put(MachineState.DeletingSnapshotPaused, NodeState.PENDING);
nodeStateMap.put(MachineState.FaultTolerantSyncing, NodeState.PENDING);
nodeStateMap.put(MachineState.LiveSnapshotting, NodeState.PENDING);
nodeStateMap.put(MachineState.SettingUp, NodeState.PENDING);
nodeStateMap.put(MachineState.Starting, NodeState.PENDING);
nodeStateMap.put(MachineState.Stopping, NodeState.PENDING);
nodeStateMap.put(MachineState.Restoring, NodeState.PENDING);
// TODO What to map these states to?
nodeStateMap.put(MachineState.FirstOnline, NodeState.PENDING);
nodeStateMap.put(MachineState.FirstTransient, NodeState.PENDING);
nodeStateMap.put(MachineState.LastOnline, NodeState.PENDING);
nodeStateMap.put(MachineState.LastTransient, NodeState.PENDING);
nodeStateMap.put(MachineState.Teleported, NodeState.PENDING);
nodeStateMap.put(MachineState.TeleportingIn, NodeState.PENDING);
nodeStateMap.put(MachineState.TeleportingPausedVM, NodeState.PENDING);
nodeStateMap.put(MachineState.Aborted, NodeState.ERROR);
nodeStateMap.put(MachineState.Stuck, NodeState.ERROR);
nodeStateMap.put(MachineState.Null, NodeState.UNRECOGNIZED);
MachineState vmState = vm.getState(); MachineState vmState = vm.getState();
NodeState nodeState = nodeStateMap.get(vmState); NodeState nodeState = machineToNodeState.get(vmState);
if(nodeState == null) if (nodeState == null)
nodeState = NodeState.UNRECOGNIZED; nodeState = NodeState.UNRECOGNIZED;
nodeMetadataBuilder.state(nodeState); nodeMetadataBuilder.state(nodeState);
logger.debug("Setting virtualbox node to: " + nodeState + " from machine state: " + vmState); logger.debug("Setting virtualbox node to: " + nodeState + " from machine state: " + vmState);
INetworkAdapter networkAdapter = vm.getNetworkAdapter(0l);
if (networkAdapter != null) {
String bridgedInterface = networkAdapter.getBridgedInterface();
System.out.println("Interface: " + bridgedInterface);
}
// nodeMetadataBuilder.imageId(""); // nodeMetadataBuilder.imageId("");
// nodeMetadataBuilder.group(""); // nodeMetadataBuilder.group("");

View File

@ -0,0 +1,88 @@
/*
* *
* * 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.admin;
import com.google.common.base.Function;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.logging.Logger;
import org.jclouds.virtualbox.config.VirtualBoxConstants;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.*;
import java.net.URI;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.io.ByteStreams.copy;
import static com.google.common.io.Closeables.closeQuietly;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_WORKINGDIR;
/**
* @author Mattias Holmqvist
*/
public class FileDownloadFromURI implements Function<URI, File> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final ComputeServiceContext context;
private final String workingDir;
private final String isoFile;
@Inject
public FileDownloadFromURI(final ComputeServiceContext context,
@Named(VIRTUALBOX_WORKINGDIR) final String workingDir,
@Named(VirtualBoxConstants.VIRTUALBOX_ISOFILE) final String isoFile) {
this.context = context;
this.workingDir = workingDir;
this.isoFile = isoFile;
}
@Override
public File apply(@Nullable URI input) {
final File file = new File(workingDir, isoFile);
if (!file.exists()) {
final InputStream inputStream = context.utils().http().get(input);
checkNotNull(inputStream, "%s not found", input);
try {
copy(inputStream, new FileOutputStream(file));
return file;
} catch (FileNotFoundException e) {
logger.error(e, "File %s could not be found", file);
} catch (IOException e) {
logger.error(e, "Error when downloading file %s", input);
} finally {
closeQuietly(inputStream);
}
return null;
} else {
logger.debug("File %s already exists. Skipping download", file);
return file;
}
}
}

View File

@ -30,12 +30,11 @@ import org.jclouds.compute.StandaloneComputeServiceContextSpec;
import org.jclouds.sshj.config.SshjSshClientModule; import org.jclouds.sshj.config.SshjSshClientModule;
import org.jclouds.virtualbox.VirtualBox; import org.jclouds.virtualbox.VirtualBox;
import org.jclouds.virtualbox.VirtualBoxContextBuilder; import org.jclouds.virtualbox.VirtualBoxContextBuilder;
import org.jclouds.virtualbox.domain.VMSpec;
import org.jclouds.virtualbox.domain.Host; import org.jclouds.virtualbox.domain.Host;
import org.jclouds.virtualbox.domain.Image;
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.IMachine; import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.VirtualBoxManager;
import java.util.Properties; import java.util.Properties;
@ -75,8 +74,8 @@ public class VirtualBoxComputeServiceLiveTest extends BaseComputeServiceLiveTest
ComputeServiceContext context = null; ComputeServiceContext context = null;
try { try {
context = new ComputeServiceContextFactory() context = new ComputeServiceContextFactory()
.createContext(new StandaloneComputeServiceContextSpec<VirtualBox, IMachine, VMSpec, Image, Host>( .createContext(new StandaloneComputeServiceContextSpec<VirtualBoxManager, IMachine, IMachine, IMachine, Host>(
"virtualbox", endpoint, apiversion, "", identity, credential, VirtualBox.class, "virtualbox", endpoint, apiversion, "", identity, credential, VirtualBoxManager.class,
VirtualBoxContextBuilder.class, ImmutableSet.<Module>of())); VirtualBoxContextBuilder.class, ImmutableSet.<Module>of()));
context.getComputeService().listNodes(); context.getComputeService().listNodes();

View File

@ -177,8 +177,10 @@ public class KickstartTest2 {
context = TestUtils.computeServiceForLocalhost(); context = TestUtils.computeServiceForLocalhost();
socketTester = new RetryablePredicate<IPSocket>( socketTester = new RetryablePredicate<IPSocket>(
new InetSocketAddressConnect(), 130, 10, TimeUnit.SECONDS); new InetSocketAddressConnect(), 130, 10, TimeUnit.SECONDS);
setupCredentials(); setupCredentials();
setupConfigurationProperties(); setupConfigurationProperties();
downloadFileUnlessPresent(distroIsoUrl, workingDir, distroIsoName); downloadFileUnlessPresent(distroIsoUrl, workingDir, distroIsoName);
downloadFileUnlessPresent(gaIsoUrl, workingDir, gaIsoName); downloadFileUnlessPresent(gaIsoUrl, workingDir, gaIsoName);
@ -189,7 +191,7 @@ public class KickstartTest2 {
manager.connect(endpoint.toASCIIString(), identity, credential); manager.connect(endpoint.toASCIIString(), identity, credential);
// Create machine // Create machine
IMachine newVM = manager.getVBox().createMachine(settingsFile, vmName, osTypeId, vmId, forceOverwrite); IMachine newVM = manager.getVBox().createMachine(settingsFile, vmName, osTypeId, "host", forceOverwrite);
manager.getVBox().registerMachine(newVM); manager.getVBox().registerMachine(newVM);
// Change RAM // Change RAM
@ -301,13 +303,11 @@ public class KickstartTest2 {
// Configure guest additions // Configure guest additions
// TODO generalize // TODO generalize
if (isUbuntu(guestId)) { if (isUbuntu(guestId)) {
runScriptOnNode(guestId, "m-a prepare -i", wrapInInitScript(true)); runScriptOnNode(guestId, "rm /etc/udev/rules.d/70-persistent-net.rules");
runScriptOnNode(guestId, "mount -o loop /dev/dvd /media/cdrom"); runScriptOnNode(guestId, "mkdir /etc/udev/rules.d/70-persistent-net.rules");
runScriptOnNode(guestId, "sh /media/cdrom/VBoxLinuxAdditions.run"); runScriptOnNode(guestId, "rm -rf /dev/.udev/");
runScriptOnNode(guestId, "rm /etc/udev/rules.d/70-persistent-net.rules"); runScriptOnNode(guestId, "rm /lib/udev/rules.d/75-persistent-net-generator.rules");
runScriptOnNode(guestId, "mkdir /etc/udev/rules.d/70-persistent-net.rules"); runScriptOnNode(guestId, "echo 0 | tee /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts");
runScriptOnNode(guestId, "rm -rf /dev/.udev/");
runScriptOnNode(guestId, "rm /lib/udev/rules.d/75-persistent-net-generator.rules");
} }
logMachineStatus(machine); logMachineStatus(machine);
@ -336,6 +336,7 @@ public class KickstartTest2 {
logMachineStatus(machine); logMachineStatus(machine);
logger().debug("Changing to bridged networking..."); logger().debug("Changing to bridged networking...");
session = manager.getSessionObject(); session = manager.getSessionObject();
IMachine adminNode = manager.getVBox().findMachine(vmName); IMachine adminNode = manager.getVBox().findMachine(vmName);
adminNode.lockMachine(session, LockType.Write); adminNode.lockMachine(session, LockType.Write);

View File

@ -31,16 +31,37 @@ import org.jclouds.compute.domain.OsFamily;
import org.jclouds.encryption.bouncycastle.config.BouncyCastleCryptoModule; import org.jclouds.encryption.bouncycastle.config.BouncyCastleCryptoModule;
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule; import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
import org.jclouds.sshj.config.SshjSshClientModule; import org.jclouds.sshj.config.SshjSshClientModule;
import org.jclouds.virtualbox.compute.LoadMachineFromVirtualBox;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.inject.Module; import com.google.inject.Module;
import org.jclouds.virtualbox.config.VirtualBoxConstants;
public class TestUtils { public class TestUtils {
public static ComputeServiceContext computeServiceForLocalhost() throws IOException { public static ComputeServiceContext computeServiceForLocalhost() throws IOException {
String hostId = System.getProperty(VirtualBoxConstants.VIRTUALBOX_HOST_ID);
Node host = Node.builder().id(hostId)
.name(System.getProperty(VirtualBoxConstants.VIRTUALBOX_HOST_ID))
.hostname(System.getProperty(VirtualBoxConstants.VIRTUALBOX_HOSTNAME))
.osFamily(OsFamily.LINUX.toString())
.osDescription(System.getProperty("os.name"))
.osVersion(System.getProperty("os.version"))
.group("ssh")
.username(System.getProperty("user.name"))
.credentialUrl(privateKeyFile())
.build();
final Map<String, Node> nodeMap = ImmutableMap.<String, Node>builder().put(hostId, host).build();
return new ComputeServiceContextFactory().createContext("byon", "foo", "bar", ImmutableSet.<Module>of(
new SshjSshClientModule(), new SLF4JLoggingModule(), new BouncyCastleCryptoModule(), new CacheNodeStoreModule(nodeMap)));
}
public static ComputeServiceContext computeServiceForLocalhostAndGuest() throws IOException {
Node host = Node.builder().id("host") Node host = Node.builder().id("host")
.name("host installing virtualbox") .name("host installing virtualbox")
.hostname("localhost") .hostname("localhost")
@ -77,4 +98,9 @@ public class TestUtils {
} }
return null; return null;
} }
public static ComputeServiceContext computeServiceForVirtualBox(Cache<String, Node> cache) {
return new ComputeServiceContextFactory().createContext("byon", "foo", "bar", ImmutableSet.<Module>of(
new SshjSshClientModule(), new SLF4JLoggingModule(), new BouncyCastleCryptoModule(), new CacheNodeStoreModule(cache)));
}
} }

View File

@ -22,12 +22,16 @@
package org.jclouds.virtualbox.experiment; package org.jclouds.virtualbox.experiment;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Module; import com.google.inject.Module;
import org.jclouds.byon.Node;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.ExecResponse; import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
@ -37,17 +41,25 @@ import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory;
import org.jclouds.ssh.SshClient; import org.jclouds.ssh.SshClient;
import org.jclouds.sshj.config.SshjSshClientModule; import org.jclouds.sshj.config.SshjSshClientModule;
import org.jclouds.virtualbox.compute.LoadMachineFromVirtualBox;
import org.jclouds.virtualbox.functions.IMachineToIpAddress;
import org.jclouds.virtualbox.functions.IMachineToNodeMetadata; import org.jclouds.virtualbox.functions.IMachineToNodeMetadata;
import org.virtualbox_4_1.*; import org.virtualbox_4_1.*;
import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhost;
import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForVirtualBox;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
public class VirtualBoxLiveTest2 { public class VirtualBoxLiveTest2 {
@ -58,6 +70,8 @@ public class VirtualBoxLiveTest2 {
protected String credential; protected String credential;
protected URI endpoint; protected URI endpoint;
protected String vmName; protected String vmName;
private String hostId = "host";
private String guestId = "guest";
VirtualBoxManager manager = VirtualBoxManager.createInstance(""); VirtualBoxManager manager = VirtualBoxManager.createInstance("");
@ -78,13 +92,15 @@ public class VirtualBoxLiveTest2 {
protected int numberOfVirtualMachine; protected int numberOfVirtualMachine;
protected String originalDisk; protected String originalDisk;
private String clonedDisk; private String clonedDisk;
private ComputeServiceContext context; private ComputeServiceContext virtualBoxComputeService;
private String adminNodeName; private String adminNodeName;
private Injector injector; private Injector injector;
private Cache<String, Node> cache;
private ComputeServiceContext localhostComputeService;
protected Logger logger() { protected Logger logger() {
return context.utils().loggerFactory().getLogger("jclouds.compute"); return virtualBoxComputeService.utils().loggerFactory().getLogger("jclouds.compute");
} }
protected void setupCredentials() { protected void setupCredentials() {
@ -122,7 +138,7 @@ public class VirtualBoxLiveTest2 {
numberOfVirtualMachine = Integer.parseInt(checkNotNull(System.getProperty("test." + provider numberOfVirtualMachine = Integer.parseInt(checkNotNull(System.getProperty("test." + provider
+ ".numberOfVirtualMachine", "3"))); + ".numberOfVirtualMachine", "3")));
injector = new RestContextFactory().createContextBuilder(provider, injector = new RestContextFactory().createContextBuilder(provider,
ImmutableSet.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule())).buildInjector(); ImmutableSet.<Module>of(new Log4JLoggingModule(), new SshjSshClientModule())).buildInjector();
sshFactory = injector.getInstance(SshClient.Factory.class); sshFactory = injector.getInstance(SshClient.Factory.class);
} }
@ -139,7 +155,11 @@ public class VirtualBoxLiveTest2 {
} }
private void runAll() throws IOException, InterruptedException { private void runAll() throws IOException, InterruptedException {
context = TestUtils.computeServiceForLocalhost(); localhostComputeService = computeServiceForLocalhost();
IMachineToIpAddress iMachineToIpAddress = new IMachineToIpAddress(manager, localhostComputeService.getComputeService());
LoadMachineFromVirtualBox cacheLoader = new LoadMachineFromVirtualBox(manager, iMachineToIpAddress);
cache = CacheBuilder.newBuilder().build(cacheLoader);
virtualBoxComputeService = computeServiceForVirtualBox(cache);
socketTester = new RetryablePredicate<IPSocket>( socketTester = new RetryablePredicate<IPSocket>(
new InetSocketAddressConnect(), 130, 10, TimeUnit.SECONDS); new InetSocketAddressConnect(), 130, 10, TimeUnit.SECONDS);
setupCredentials(); setupCredentials();
@ -147,32 +167,29 @@ public class VirtualBoxLiveTest2 {
manager.connect(endpoint.toASCIIString(), identity, credential); manager.connect(endpoint.toASCIIString(), identity, credential);
for (int i = 1; i < numberOfVirtualMachine + 1; i++) { createAndLaunchVirtualMachine(1);
createAndLaunchVirtualMachine(i);
String instanceName = vmName + "_1";
IMachine machine = manager.getVBox().findMachine(instanceName);
logMachineStatus(machine);
try {
ISession machineSession = manager.openMachineSession(machine);
IProgress progress = machineSession.getConsole().powerDown();
progress.waitForCompletion(-1);
machineSession.unlockMachine();
while (!machine.getSessionState().equals(SessionState.Unlocked)) {
try {
logger().debug("Waiting for unlocking session - session state: " + machine.getSessionState());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
logMachineStatus(machine);
} catch (Exception e) {
e.printStackTrace();
} }
for (int i = 1; i < numberOfVirtualMachine + 1; i++) {
String instanceName = vmName + "_" + i;
IMachine machine = manager.getVBox().findMachine(instanceName);
logMachineStatus(machine);
try {
ISession machineSession = manager.openMachineSession(machine);
IProgress progress = machineSession.getConsole().powerDown();
progress.waitForCompletion(-1);
machineSession.unlockMachine();
while (!machine.getSessionState().equals(SessionState.Unlocked)) {
try {
logger().debug("Waiting for unlocking session - session state: " + machine.getSessionState());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
logMachineStatus(machine);
} catch (Exception e) {
e.printStackTrace();
}
}
} }
@ -184,30 +201,87 @@ public class VirtualBoxLiveTest2 {
List<CloneOptions> options = new ArrayList<CloneOptions>(); List<CloneOptions> options = new ArrayList<CloneOptions>();
options.add(CloneOptions.Link); options.add(CloneOptions.Link);
IProgress progress = adminNode.getCurrentSnapshot().getMachine().cloneTo(clonedVM, CloneMode.MachineState, options); IProgress progress = adminNode.getCurrentSnapshot().getMachine().cloneTo(clonedVM, CloneMode.MachineState, options);
if (progress.getCompleted()) if (progress.getCompleted())
logger().debug("clone done"); logger().debug("clone done");
manager.getVBox().registerMachine(clonedVM); manager.getVBox().registerMachine(clonedVM);
ISession session = manager.getSessionObject();
clonedVM.lockMachine(session, LockType.Write);
IMachine mutable = session.getMachine();
// network
String hostInterface = null;
String command = "vboxmanage list bridgedifs";
try {
Process child = Runtime.getRuntime().exec(command);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(child.getInputStream()));
String line = "";
boolean found = false;
while ((line = bufferedReader.readLine()) != null && !found) {
System.out.println("line: " + line);
if (line.split(":")[0].contains("Name")) {
hostInterface = line.substring(line.indexOf(":") + 1);
}
if (line.split(":")[0].contains("Status") && line.split(":")[1].contains("Up")) {
System.out.println("bridge: " + hostInterface.trim());
found = true;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mutable.getNetworkAdapter(new Long(0)).setAttachmentType(NetworkAttachmentType.Bridged);
mutable.getNetworkAdapter(new Long(0)).setAdapterType(NetworkAdapterType.Am79C973);
mutable.getNetworkAdapter(new Long(0)).setMACAddress("0800279DA478");
mutable.getNetworkAdapter(new Long(0)).setBridgedInterface(hostInterface.trim());
mutable.getNetworkAdapter(new Long(0)).setEnabled(true);
mutable.saveSettings();
session.unlockMachine();
System.out.println("\nLaunching VM named " + clonedVM.getName() + " ..."); System.out.println("\nLaunching VM named " + clonedVM.getName() + " ...");
launchVMProcess(clonedVM, manager.getSessionObject()); launchVMProcess(clonedVM, manager.getSessionObject());
String ipAddress = null;
while (ipAddress == null || ipAddress.equals("")) { clonedVM = manager.getVBox().findMachine(instanceName);
try {
ipAddress = clonedVM.getGuestPropertyValue("/VirtualBox/GuestInfo/Net/0/V4/IP");
Thread.sleep(1000);
} catch (InterruptedException e) { try {
e.printStackTrace(); boolean gotIp = false;
while (!gotIp) {
Node node = cache.get(instanceName);
if (node.getHostname() != null) {
gotIp = true;
}
else {
cache.invalidate(node);
Thread.sleep(1000);
System.out.println("waiting for IP: got IP");
}
} }
} catch (ExecutionException e) {
} }
logger().debug(ipAddress + " is the IP address of " + clonedVM.getName());
// TODO: This does not work yet. logger().debug("Trying echo...");
// IPSocket socket = new IPSocket(ipAddress, 22); runScriptOnNode(instanceName, "echo ciao");
// checkSSH(socket);
} }
protected ExecResponse runScriptOnNode(String nodeId, String command) {
return runScriptOnNode(nodeId, command, wrapInInitScript(false));
}
protected ExecResponse runScriptOnNode(String nodeId, String command,
RunScriptOptions options) {
ExecResponse toReturn = virtualBoxComputeService.getComputeService().runScriptOnNode(nodeId, command, options);
assert toReturn.getExitCode() == 0 : toReturn;
return toReturn;
}
private void checkSSH(IPSocket socket) { private void checkSSH(IPSocket socket) {
socketTester.apply(socket); socketTester.apply(socket);
SshClient client = sshFactory.create(socket, new Credentials(osUsername, osPassword)); SshClient client = sshFactory.create(socket, new Credentials(osUsername, osPassword));

View File

@ -209,7 +209,7 @@ public class VirtualboxAdministrationKickstartLiveTest {
@BeforeGroups(groups = "live") @BeforeGroups(groups = "live")
protected void setupClient() throws Exception { protected void setupClient() throws Exception {
context = TestUtils.computeServiceForLocalhost(); context = TestUtils.computeServiceForLocalhostAndGuest();
socketTester = new RetryablePredicate<IPSocket>( socketTester = new RetryablePredicate<IPSocket>(
new InetSocketAddressConnect(), 130, 10, TimeUnit.SECONDS); new InetSocketAddressConnect(), 130, 10, TimeUnit.SECONDS);
setupCredentials(); setupCredentials();

View File

@ -168,7 +168,7 @@ public class VirtualboxLiveTest {
@BeforeGroups(groups = "live") @BeforeGroups(groups = "live")
protected void setupClient() throws Exception { protected void setupClient() throws Exception {
context = TestUtils.computeServiceForLocalhost(); context = TestUtils.computeServiceForLocalhostAndGuest();
socketTester = new RetryablePredicate<IPSocket>( socketTester = new RetryablePredicate<IPSocket>(
new InetSocketAddressConnect(), 130, 10, TimeUnit.SECONDS); new InetSocketAddressConnect(), 130, 10, TimeUnit.SECONDS);
setupCredentials(); setupCredentials();

View File

@ -19,14 +19,37 @@
package org.jclouds.virtualbox.functions; package org.jclouds.virtualbox.functions;
import com.google.common.collect.ImmutableSet;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.domain.Credentials;
import org.jclouds.virtualbox.VirtualBox;
import org.jclouds.virtualbox.config.VirtualBoxComputeServiceContextModule;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import org.virtualbox_4_1.IMachine; import org.virtualbox_4_1.MachineState;
import org.virtualbox_4_1.VirtualBoxManager; import org.virtualbox_4_1.VirtualBoxManager;
import java.util.Map;
import java.util.Set;
//@Test(groups = "live")
public class IMachineToNodeMetadataTest { public class IMachineToNodeMetadataTest {
@Test @Test
public void testCreate() throws Exception { public void testCreate() throws Exception {
Credentials creds = new Credentials("admin", "123456");
VirtualBoxManager manager = VirtualBoxManager.createInstance("");
Map<MachineState, NodeState> machineToNodeState = VirtualBoxComputeServiceContextModule.machineToNodeState;
Set<Image> images = ImmutableSet.of();
Set<org.jclouds.compute.domain.Hardware> hardwares = ImmutableSet.of();
VirtualBox virtualBox = new VirtualBox();
IMachineToNodeMetadata parser = new IMachineToNodeMetadata();
IMachineToHardware hwParser = new IMachineToHardware(virtualBox);
// hwParser.apply()
} }
} }