mirror of https://github.com/apache/jclouds.git
Merge branch 'jclouds-vbox' of https://github.com/dralves/jclouds
* 'jclouds-vbox' of https://github.com/dralves/jclouds: (24 commits) updated readme corrected IMachinePredicatesLiveTests that were failing and added workaround for transient function execution failure minor error wrt to test group got the clone to get networking solved a problem running most live tests where the admin disk was the same corrected formatting and small bug in CloneAndRegisterMachineFromIMachineIfNotAlreadyExistsLiveTest formatted most changed classes to comply with jclouds formatting guildelines removed dangling file clones are now booting, but without networking clone is created and boots sucessfully. still no network on the clone though stuck on adapter problems added the possiblity for master machines to survive the jvm. first run creates and installs the master vm subsequent calls fetch the already created master from vm adapter creates the master image. cloning next sshclien to the master is now workign added dependencies added a computeservicecontext provider for the vbox host (byon) circular dependencies problem with CreateAndInstallVm still failing matching the default image to the yaml images refactored image from yaml creation refactored image from yaml creation ...
This commit is contained in:
commit
d069b0b745
|
@ -1,3 +1,86 @@
|
|||
|
||||
#Enviroment setup
|
||||
|
||||
Note: These steps will be automated in the future:
|
||||
- create a ~/.jclouds-vbox/ directory
|
||||
- create a ~/.jclouds-vbox/isos directory
|
||||
- download an ubuntu 11.04 server i386 ISO into "~/.jclouds-vbox/isos" from http://releases.ubuntu.com/11.04/ubuntu-11.04-server-i386.iso
|
||||
- download VirtualBox Guest Additions ISO into "~/.jclouds-vbox/isos" from http://download.virtualbox.org/virtualbox/4.1.8/VBoxGuestAdditions_4.1.8.iso
|
||||
- copy the following into an images.yaml file to place in"~/.jclouds-vbox/" :
|
||||
"images:
|
||||
- id: myTestId
|
||||
name: ubuntu-11.04-server-i386
|
||||
description: ubuntu 11.04 server (i386)
|
||||
os_arch: x86
|
||||
os_family: ubuntu
|
||||
os_description: ubuntu
|
||||
os_version: 11.04
|
||||
iso: http://releases.ubuntu.com/11.04/ubuntu-11.04-server-i386.iso
|
||||
keystroke_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=vmName
|
||||
fb=false debconf/frontend=noninteractive
|
||||
keyboard-configuration/layout=USA keyboard-configuration/variant=USA console-setup/ask_detect=false
|
||||
initrd=/install/initrd.gz -- <Enter>
|
||||
preseed_cfg: |
|
||||
## Options to set on the command line
|
||||
d-i debian-installer/locale string en_US.utf8
|
||||
d-i console-setup/ask_detect boolean false
|
||||
d-i console-setup/layout string USA
|
||||
d-i netcfg/get_hostname string unassigned-hostname
|
||||
d-i netcfg/get_domain string unassigned-domain
|
||||
# Continue without a default route
|
||||
# Not working , specify a dummy in the DHCP
|
||||
d-i time/zone string UTC
|
||||
d-i clock-setup/utc-auto boolean true
|
||||
d-i clock-setup/utc boolean true
|
||||
d-i kbd-chooser/method select American English
|
||||
d-i netcfg/wireless_wep string
|
||||
d-i base-installer/kernel/override-image string linux-server
|
||||
# Choices: Dialog, Readline, Gnome, Kde, Editor, Noninteractive
|
||||
d-i debconf debconf/frontend select Noninteractive
|
||||
d-i pkgsel/install-language-support boolean false
|
||||
tasksel tasksel/first multiselect standard, ubuntu-server
|
||||
d-i partman-auto/method string lvm
|
||||
d-i partman-lvm/confirm boolean true
|
||||
d-i partman-lvm/device_remove_lvm boolean true
|
||||
d-i partman-auto/choose_recipe select atomic
|
||||
d-i partman/confirm_write_new_label boolean true
|
||||
d-i partman/confirm_nooverwrite boolean true
|
||||
d-i partman/choose_partition select finish
|
||||
d-i partman/confirm boolean true
|
||||
# Write the changes to disks and configure LVM?
|
||||
d-i partman-lvm/confirm boolean true
|
||||
d-i partman-lvm/confirm_nooverwrite boolean true
|
||||
d-i partman-auto-lvm/guided_size string max
|
||||
## Default user, we can get away with a recipe to change this
|
||||
d-i passwd/user-fullname string toor
|
||||
d-i passwd/username string toor
|
||||
d-i passwd/user-password password password
|
||||
d-i passwd/user-password-again password password
|
||||
d-i user-setup/encrypt-home boolean false
|
||||
d-i user-setup/allow-password-weak boolean true
|
||||
# Individual additional packages to install
|
||||
d-i pkgsel/include string openssh-server ntp
|
||||
# Whether to upgrade packages after debootstrap.
|
||||
# Allowed values: none, safe-upgrade, full-upgrade
|
||||
d-i pkgsel/upgrade select full-upgrade
|
||||
d-i grub-installer/only_debian boolean true
|
||||
d-i grub-installer/with_other_os boolean true
|
||||
d-i finish-install/reboot_in_progress note
|
||||
#For the update
|
||||
d-i pkgsel/update-policy select none
|
||||
# debconf-get-selections --install
|
||||
#Use mirror
|
||||
choose-mirror-bin mirror/http/proxy string"
|
||||
|
||||
** NOTE! **
|
||||
Make sure you change your VirtualBox preferences to not auto-capture keyboard, and also set host key to none. Otherwise you may accidentally screw-up automated installs.
|
||||
|
||||
- Old Notes -
|
||||
|
||||
# Administation viewpoint
|
||||
|
||||
These steps are usually in charge of cloud provider, in this case it's up to you
|
||||
|
@ -37,7 +120,3 @@ and choose the numberOfVirtualMachine you need using -Dtest.virtualbox.numberOfV
|
|||
These VMs will be cloned starting from the golden template VM created before
|
||||
|
||||
It will create a "numberOfVirtualMachine" in a vbox default machine folder with 'VMName_i' name, by cloning the golden template in linked mode with a bridged NIC.
|
||||
|
||||
|
||||
** NOTE! **
|
||||
Make sure you change your VirtualBox preferences to not auto-capture keyboard, and also set host key to none. Otherwise you may accidentally screw-up automated installs.
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
under the License.
|
||||
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.jclouds</groupId>
|
||||
|
@ -42,6 +43,8 @@
|
|||
<test.virtualbox.image-id>ubuntu-11.04-server-i386</test.virtualbox.image-id>
|
||||
<test.virtualbox.image.login-user>toor:password</test.virtualbox.image.login-user>
|
||||
<test.virtualbox.image.authenticate-sudo>true</test.virtualbox.image.authenticate-sudo>
|
||||
<test.virtualbox.image.authenticate-sudo>true</test.virtualbox.image.authenticate-sudo>
|
||||
<test.virtualbox.image.descriptor.yaml>target/test-classes/testImages.yaml</test.virtualbox.image.descriptor.yaml>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
@ -70,6 +73,21 @@
|
|||
<artifactId>jetty-server</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.driver</groupId>
|
||||
<artifactId>jclouds-sshj</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.driver</groupId>
|
||||
<artifactId>jclouds-slf4j</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<artifactId>jclouds-core</artifactId>
|
||||
|
@ -84,26 +102,25 @@
|
|||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.driver</groupId>
|
||||
<artifactId>jclouds-sshj</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.driver</groupId>
|
||||
<artifactId>jclouds-slf4j</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<version>6.3.1</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<groupId>org.yaml</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>live</id>
|
||||
|
@ -130,6 +147,7 @@
|
|||
<test.virtualbox.image-id>${test.virtualbox.image-id}</test.virtualbox.image-id>
|
||||
<test.virtualbox.image.login-user>${test.virtualbox.image.login-user}</test.virtualbox.image.login-user>
|
||||
<test.virtualbox.image.authenticate-sudo>${test.virtualbox.image.authenticate-sudo}</test.virtualbox.image.authenticate-sudo>
|
||||
<test.virtualbox.image.descriptor.yaml>${test.virtualbox.image.descriptor.yaml}</test.virtualbox.image.descriptor.yaml>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
@ -142,7 +160,7 @@
|
|||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<configuration>
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* 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;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
/**
|
||||
* Signals the annotated target pertains to the vbox host and not to one of the nodes.
|
||||
*
|
||||
* @author dralves
|
||||
*
|
||||
*/
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
||||
@Qualifier
|
||||
public @interface Host {
|
||||
|
||||
}
|
|
@ -19,18 +19,23 @@
|
|||
|
||||
package org.jclouds.virtualbox;
|
||||
|
||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||
import static org.jclouds.Constants.*;
|
||||
import static org.jclouds.Constants.PROPERTY_BUILD_VERSION;
|
||||
import static org.jclouds.Constants.PROPERTY_CREDENTIAL;
|
||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||
import static org.jclouds.Constants.PROPERTY_IDENTITY;
|
||||
import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_IMAGE_AUTHENTICATE_SUDO;
|
||||
import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_IMAGE_LOGIN_USER;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_DIR;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGES_DESCRIPTOR;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_PRECONFIGURATION_URL;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.PropertiesBuilder;
|
||||
import static org.jclouds.compute.reference.ComputeServiceConstants.*;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.*;
|
||||
|
||||
/**
|
||||
* Builds properties for VirtualBox integration.
|
||||
|
@ -53,32 +58,36 @@ public class VirtualBoxPropertiesBuilder extends PropertiesBuilder {
|
|||
properties.put(PROPERTY_ENDPOINT, "http://localhost:18083/");
|
||||
// later version not in maven, yet
|
||||
properties.put(PROPERTY_API_VERSION, "4.1.4");
|
||||
|
||||
properties.put(PROPERTY_BUILD_VERSION, "4.1.8r75467");
|
||||
properties.put(PROPERTY_IDENTITY, "administrator");
|
||||
properties.put(PROPERTY_CREDENTIAL, "12345");
|
||||
|
||||
properties.put(PROPERTY_IMAGE_ID, "ubuntu-11.04-server-i386");
|
||||
properties.put(PROPERTY_IMAGE_LOGIN_USER, "toor:password");
|
||||
properties.put(PROPERTY_IMAGE_AUTHENTICATE_SUDO, "true");
|
||||
|
||||
properties.put(VIRTUALBOX_ISO_URL, "http://releases.ubuntu.com/11.04/ubuntu-11.04-server-i386.iso");
|
||||
properties.put(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE, "<Esc><Esc><Enter> "
|
||||
+ "/install/vmlinuz noapic preseed/url=PRECONFIGURATION_URL "
|
||||
+ "debian-installer=en_US auto locale=en_US kbd-chooser/method=us "
|
||||
+ "hostname=" + "HOSTNAME "
|
||||
+ "debian-installer=en_US auto locale=en_US kbd-chooser/method=us " + "hostname=" + "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(VIRTUALBOX_WORKINGDIR, System.getProperty("user.home") + File.separator
|
||||
+ System.getProperty("test.virtualbox.workingDir", "jclouds-virtualbox-test"));
|
||||
|
||||
properties.put(
|
||||
VIRTUALBOX_WORKINGDIR,
|
||||
System.getProperty("user.home") + File.separator
|
||||
+ System.getProperty("test.virtualbox.workingDir", ".jclouds-vbox"));
|
||||
|
||||
// allow to set the descriptor as a sysprop but default to just setting a default file path.
|
||||
// The configured supplier
|
||||
// must be able to handle the chosen option.
|
||||
properties.put(
|
||||
VIRTUALBOX_IMAGES_DESCRIPTOR,
|
||||
System.getProperty("test.virtualbox.image.descriptor.yaml", VIRTUALBOX_DEFAULT_DIR + File.separator
|
||||
+ "images.yaml"));
|
||||
|
||||
properties.put(VIRTUALBOX_PRECONFIGURATION_URL, "http://10.0.2.2:8080/src/test/resources/preseed.cfg");
|
||||
|
||||
|
||||
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,8 +21,10 @@ package org.jclouds.virtualbox.compute;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_NODE_PREFIX;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
@ -31,6 +33,9 @@ import org.jclouds.compute.domain.Image;
|
|||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.virtualbox.domain.Master;
|
||||
import org.jclouds.virtualbox.domain.NodeSpec;
|
||||
import org.jclouds.virtualbox.domain.YamlImage;
|
||||
import org.virtualbox_4_1.CleanupMode;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.IProgress;
|
||||
|
@ -42,14 +47,14 @@ import com.google.common.base.Function;
|
|||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
/**
|
||||
* Defines the connection between the
|
||||
* {@link org.virtualbox_4_1.VirtualBoxManager} implementation and the jclouds
|
||||
* {@link org.jclouds.compute.ComputeService}
|
||||
* Defines the connection between the {@link org.virtualbox_4_1.VirtualBoxManager} implementation
|
||||
* and the jclouds {@link org.jclouds.compute.ComputeService}
|
||||
*
|
||||
* @author Mattias Holmqvist, Andrea Turli
|
||||
*/
|
||||
|
@ -57,30 +62,39 @@ import com.google.inject.Singleton;
|
|||
public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IMachine, IMachine, Image, Location> {
|
||||
|
||||
private final Supplier<VirtualBoxManager> manager;
|
||||
private final Function<IMachine, Image> iMachineToImage;
|
||||
private final Map<Image, YamlImage> images;
|
||||
private final LoadingCache<Image, Master> mastersLoader;
|
||||
private final Function<NodeSpec, NodeAndInitialCredentials<IMachine>> cloneCreator;
|
||||
|
||||
@Inject
|
||||
public VirtualBoxComputeServiceAdapter(Supplier<VirtualBoxManager> manager,
|
||||
Function<IMachine, Image> iMachineToImage) {
|
||||
this.iMachineToImage = iMachineToImage;
|
||||
Supplier<Map<Image, YamlImage>> imagesMapper, LoadingCache<Image, Master> mastersLoader,
|
||||
Function<NodeSpec, NodeAndInitialCredentials<IMachine>> cloneCreator) {
|
||||
this.manager = checkNotNull(manager, "manager");
|
||||
this.images = imagesMapper.get();
|
||||
this.mastersLoader = mastersLoader;
|
||||
this.cloneCreator = cloneCreator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeAndInitialCredentials<IMachine> createNodeWithGroupEncodedIntoName(String tag, String name,
|
||||
Template template) {
|
||||
return null;
|
||||
Template template) {
|
||||
try {
|
||||
Master master = mastersLoader.get(template.getImage());
|
||||
NodeSpec nodeSpec = NodeSpec.builder().master(master).name(name).tag(tag).template(template).build();
|
||||
return cloneCreator.apply(nodeSpec);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IMachine> listNodes() {
|
||||
return Iterables.filter(manager.get().getVBox().getMachines(), new Predicate<IMachine>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(IMachine arg0) {
|
||||
return !arg0.getName().startsWith(VIRTUALBOX_IMAGE_PREFIX);
|
||||
return !arg0.getName().startsWith(VIRTUALBOX_NODE_PREFIX);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -91,7 +105,7 @@ public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IM
|
|||
|
||||
@Override
|
||||
public Iterable<Image> listImages() {
|
||||
return transform(imageMachines(), iMachineToImage);
|
||||
return images.keySet();
|
||||
}
|
||||
|
||||
private Iterable<IMachine> imageMachines() {
|
||||
|
@ -108,7 +122,7 @@ public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IM
|
|||
@Override
|
||||
public Iterable<Location> listLocations() {
|
||||
// Not using the adapter to determine locations
|
||||
return ImmutableSet.<Location>of();
|
||||
return ImmutableSet.<Location> of();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -181,4 +195,5 @@ public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IM
|
|||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_PRECO
|
|||
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
|
@ -31,11 +32,16 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.jclouds.byon.Node;
|
||||
import org.jclouds.byon.config.CacheNodeStoreModule;
|
||||
import org.jclouds.byon.functions.NodeToNodeMetadata;
|
||||
import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.HardwareBuilder;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
|
@ -44,16 +50,30 @@ import org.jclouds.compute.domain.TemplateBuilder;
|
|||
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.functions.IdentityFunction;
|
||||
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.jclouds.virtualbox.Host;
|
||||
import org.jclouds.virtualbox.Preconfiguration;
|
||||
import org.jclouds.virtualbox.compute.VirtualBoxComputeServiceAdapter;
|
||||
import org.jclouds.virtualbox.domain.CloneSpec;
|
||||
import org.jclouds.virtualbox.domain.ExecutionType;
|
||||
import org.jclouds.virtualbox.domain.IsoSpec;
|
||||
import org.jclouds.virtualbox.domain.Master;
|
||||
import org.jclouds.virtualbox.domain.MasterSpec;
|
||||
import org.jclouds.virtualbox.domain.NodeSpec;
|
||||
import org.jclouds.virtualbox.domain.YamlImage;
|
||||
import org.jclouds.virtualbox.functions.CloneAndRegisterMachineFromIMachineIfNotAlreadyExists;
|
||||
import org.jclouds.virtualbox.functions.CreateAndInstallVm;
|
||||
import org.jclouds.virtualbox.functions.IMachineToHardware;
|
||||
import org.jclouds.virtualbox.functions.IMachineToImage;
|
||||
import org.jclouds.virtualbox.functions.IMachineToNodeMetadata;
|
||||
import org.jclouds.virtualbox.functions.IMachineToSshClient;
|
||||
import org.jclouds.virtualbox.functions.MastersCache;
|
||||
import org.jclouds.virtualbox.functions.NodeCreator;
|
||||
import org.jclouds.virtualbox.functions.YamlImagesFromFileConfig;
|
||||
import org.jclouds.virtualbox.functions.admin.ImagesToYamlImagesFromYamlDescriptor;
|
||||
import org.jclouds.virtualbox.functions.admin.StartJettyIfNotAlreadyRunning;
|
||||
import org.jclouds.virtualbox.functions.admin.StartVBoxIfNotAlreadyRunning;
|
||||
import org.jclouds.virtualbox.predicates.SshResponds;
|
||||
|
@ -72,7 +92,9 @@ import com.google.common.cache.CacheBuilder;
|
|||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
|
@ -81,7 +103,7 @@ import com.google.inject.TypeLiteral;
|
|||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public class VirtualBoxComputeServiceContextModule extends
|
||||
ComputeServiceAdapterContextModule<Supplier, Supplier, IMachine, IMachine, Image, Location> {
|
||||
ComputeServiceAdapterContextModule<Supplier, Supplier, IMachine, IMachine, Image, Location> {
|
||||
|
||||
public VirtualBoxComputeServiceContextModule() {
|
||||
super(Supplier.class, Supplier.class);
|
||||
|
@ -106,6 +128,24 @@ public class VirtualBoxComputeServiceContextModule extends
|
|||
}).to((Class) StartJettyIfNotAlreadyRunning.class);
|
||||
bind(new TypeLiteral<Supplier<VirtualBoxManager>>() {
|
||||
}).to((Class) StartVBoxIfNotAlreadyRunning.class);
|
||||
// the yaml config to image mapper
|
||||
bind(new TypeLiteral<Supplier<Map<Image, YamlImage>>>() {
|
||||
}).to((Class) ImagesToYamlImagesFromYamlDescriptor.class);
|
||||
// the yaml config provider
|
||||
bind(new TypeLiteral<Supplier<String>>() {
|
||||
}).to((Class) YamlImagesFromFileConfig.class);
|
||||
// the master machines cache
|
||||
bind(new TypeLiteral<LoadingCache<Image, Master>>() {
|
||||
}).to((Class) MastersCache.class);
|
||||
// the master creating function
|
||||
bind(new TypeLiteral<Function<MasterSpec, IMachine>>() {
|
||||
}).to((Class) CreateAndInstallVm.class);
|
||||
// the machine cloning function
|
||||
bind(new TypeLiteral<Function<NodeSpec, NodeAndInitialCredentials<IMachine>>>() {
|
||||
}).to((Class) NodeCreator.class);
|
||||
bind(new TypeLiteral<Function<CloneSpec, IMachine>>() {
|
||||
}).to((Class) CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.class);
|
||||
|
||||
// for byon
|
||||
bind(new TypeLiteral<Function<URI, InputStream>>() {
|
||||
}).to(SupplyFromProviderURIOrNodesProperty.class);
|
||||
|
@ -115,9 +155,8 @@ public class VirtualBoxComputeServiceContextModule extends
|
|||
|
||||
bind(ExecutionType.class).toInstance(ExecutionType.GUI);
|
||||
bind(LockType.class).toInstance(LockType.Write);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Preconfiguration
|
||||
|
@ -125,6 +164,25 @@ public class VirtualBoxComputeServiceContextModule extends
|
|||
return CacheBuilder.newBuilder().build(cacheLoader);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Host
|
||||
@Singleton
|
||||
protected ComputeServiceContext provideHostController() {
|
||||
String provider = "byon";
|
||||
String identity = "";
|
||||
String credential = "";
|
||||
CacheNodeStoreModule hostModule = new CacheNodeStoreModule(ImmutableMap.of(
|
||||
"host",
|
||||
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(URI.create("file://" + System.getProperty("user.home") + "/.ssh/id_rsa"))
|
||||
.build()));
|
||||
return new ComputeServiceContextFactory().createContext(provider, identity, credential,
|
||||
ImmutableSet.<Module> of(new SLF4JLoggingModule(), new SshjSshClientModule(), hostModule));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Server providesJettyServer(@Named(VIRTUALBOX_PRECONFIGURATION_URL) String preconfigurationUrl) {
|
||||
|
@ -141,7 +199,6 @@ public class VirtualBoxComputeServiceContextModule extends
|
|||
return VirtualBoxManager.createInstance(nodeSupplier.get().getId());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "createInstanceByNodeId()";
|
||||
|
@ -162,6 +219,12 @@ public class VirtualBoxComputeServiceContextModule extends
|
|||
return new RetryablePredicate<SshClient>(sshResponds, timeouts.nodeRunning);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier provideHardware(ComputeServiceAdapter<IMachine, IMachine, Image, Location> adapter,
|
||||
Function<IMachine, Hardware> transformer) {
|
||||
return Suppliers.ofInstance(Collections.singleton(new HardwareBuilder().id("").build()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
||||
return template.osFamily(OsFamily.UBUNTU).osVersionMatches("11.04");
|
||||
|
@ -170,7 +233,7 @@ public class VirtualBoxComputeServiceContextModule extends
|
|||
@Provides
|
||||
@Singleton
|
||||
protected Supplier<NodeMetadata> host(Supplier<LoadingCache<String, Node>> nodes, NodeToNodeMetadata converter)
|
||||
throws ExecutionException {
|
||||
throws ExecutionException {
|
||||
return Suppliers.compose(Functions.compose(converter, new Function<LoadingCache<String, Node>, Node>() {
|
||||
|
||||
@Override
|
||||
|
@ -182,22 +245,24 @@ public class VirtualBoxComputeServiceContextModule extends
|
|||
|
||||
@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)
|
||||
.<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.Aborted, NodeState.ERROR).put(MachineState.Stuck, NodeState.ERROR)
|
||||
|
||||
.put(MachineState.Null, NodeState.UNRECOGNIZED).build();
|
||||
.put(MachineState.Null, NodeState.UNRECOGNIZED).build();
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
package org.jclouds.virtualbox.config;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Configuration properties used for interacting with VirtualBox instances.
|
||||
*
|
||||
|
@ -29,13 +31,15 @@ public interface VirtualBoxConstants {
|
|||
|
||||
public static final String VIRTUALBOX_IMAGE_PREFIX = "jclouds-image-";
|
||||
|
||||
public static final String VIRTUALBOX_NODE_PREFIX = "jclouds-node-";
|
||||
|
||||
public static final String VIRTUALBOX_PRECONFIGURATION_URL = "jclouds.virtualbox.preconfigurationurl";
|
||||
|
||||
public static final String VIRTUALBOX_INSTALLATION_KEY_SEQUENCE = "jclouds.virtualbox.installationkeysequence";
|
||||
|
||||
public static final String VIRTUALBOX_WORKINGDIR = "jclouds.virtualbox.workingdir";
|
||||
|
||||
public static final String VIRTUALBOX_ISO_URL = "jclouds.virtualbox.isourl";
|
||||
public static final String VIRTUALBOX_IMAGES_DESCRIPTOR = "jclouds.virtualbox.image.descriptor.yaml";
|
||||
|
||||
public static final String VIRTUALBOX_MACHINE_GROUP = "jclouds.virtualbox.machinegroup";
|
||||
|
||||
|
@ -51,4 +55,9 @@ public interface VirtualBoxConstants {
|
|||
|
||||
public static final String VIRTUALBOX_WEBSERVER_CREDENTIAL = "jclouds.virtualbox.webserver.credential";
|
||||
|
||||
public static final String VIRTUALBOX_DEFAULT_DIR = System.getProperty("user.home") + File.separator
|
||||
+ ".jclouds-vbox";
|
||||
|
||||
public static final String VIRTUALBOX_PROVIDER = "virtualbox";
|
||||
|
||||
}
|
||||
|
|
|
@ -19,18 +19,22 @@
|
|||
|
||||
package org.jclouds.virtualbox.domain;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* A complete specification of a "clone" node with networking setup
|
||||
* and the physical machine specification.
|
||||
* A complete specification of a "clone" node with networking setup and the physical machine
|
||||
* specification.
|
||||
*/
|
||||
public class CloneSpec {
|
||||
|
||||
private final VmSpec vmSpec;
|
||||
private final NetworkSpec networkSpec;
|
||||
private final IMachine master;
|
||||
private final boolean isLinked;
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
|
@ -40,6 +44,8 @@ public class CloneSpec {
|
|||
|
||||
private VmSpec vmSpec;
|
||||
private NetworkSpec networkSpec;
|
||||
private IMachine master;
|
||||
private boolean isLinked;
|
||||
|
||||
public Builder vm(VmSpec vmSpec) {
|
||||
this.vmSpec = vmSpec;
|
||||
|
@ -51,17 +57,30 @@ public class CloneSpec {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder master(IMachine master) {
|
||||
this.master = master;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder linked(boolean isLinked) {
|
||||
this.isLinked = isLinked;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CloneSpec build() {
|
||||
return new CloneSpec(vmSpec, networkSpec);
|
||||
return new CloneSpec(vmSpec, networkSpec, master, isLinked);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public CloneSpec(VmSpec vmSpec, NetworkSpec networkSpec) {
|
||||
public CloneSpec(VmSpec vmSpec, NetworkSpec networkSpec, IMachine master, boolean isLinked) {
|
||||
checkNotNull(vmSpec, "vmSpec");
|
||||
checkNotNull(networkSpec, "networkSpec");
|
||||
checkNotNull(master, "master");
|
||||
this.vmSpec = vmSpec;
|
||||
this.networkSpec = networkSpec;
|
||||
this.master = master;
|
||||
this.isLinked = isLinked;
|
||||
}
|
||||
|
||||
public VmSpec getVmSpec() {
|
||||
|
@ -72,27 +91,32 @@ public class CloneSpec {
|
|||
return networkSpec;
|
||||
}
|
||||
|
||||
public IMachine getMaster() {
|
||||
return master;
|
||||
}
|
||||
|
||||
public boolean isLinked() {
|
||||
return isLinked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
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 Objects.equal(vmSpec, other.vmSpec) && Objects.equal(networkSpec, other.networkSpec);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(vmSpec,networkSpec);
|
||||
return Objects.hashCode(vmSpec, networkSpec);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IMachineSpec{" +
|
||||
"vmSpec= " + vmSpec +
|
||||
", networkSpec= " + networkSpec +
|
||||
'}';
|
||||
return "IMachineSpec{" + "vmSpec= " + vmSpec + ", networkSpec= " + networkSpec + '}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,10 +19,11 @@
|
|||
|
||||
package org.jclouds.virtualbox.domain;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.virtualbox_4_1.DeviceType;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Represents a specification for a device attachment.
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
*/
|
||||
package org.jclouds.virtualbox.domain;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Represents an optical medium (DVD) in a VirtualBox VM.
|
||||
* <p/>
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* 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.IMachine;
|
||||
|
||||
public class Master {
|
||||
|
||||
private final IMachine machine;
|
||||
private final MasterSpec spec;
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private IMachine machine;
|
||||
private MasterSpec spec;
|
||||
|
||||
public Builder machine(IMachine machine) {
|
||||
this.machine = machine;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder spec(MasterSpec spec) {
|
||||
this.spec = spec;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Master build() {
|
||||
return new Master(machine, spec);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Master(IMachine machine, MasterSpec spec) {
|
||||
super();
|
||||
this.machine = machine;
|
||||
this.spec = spec;
|
||||
}
|
||||
|
||||
public IMachine getMachine() {
|
||||
return machine;
|
||||
}
|
||||
|
||||
public MasterSpec getSpec() {
|
||||
return spec;
|
||||
}
|
||||
|
||||
}
|
|
@ -19,13 +19,13 @@
|
|||
|
||||
package org.jclouds.virtualbox.domain;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* A complete specification of a "master" node, including the ISO, networking setup
|
||||
* and the physical machine specification.
|
||||
* A complete specification of a "master" node, including the ISO, networking setup and the physical
|
||||
* machine specification.
|
||||
*/
|
||||
public class MasterSpec {
|
||||
|
||||
|
@ -64,7 +64,7 @@ public class MasterSpec {
|
|||
|
||||
}
|
||||
|
||||
public MasterSpec(VmSpec vmSpec, IsoSpec isoSpec, NetworkSpec networkSpec) {
|
||||
private MasterSpec(VmSpec vmSpec, IsoSpec isoSpec, NetworkSpec networkSpec) {
|
||||
checkNotNull(vmSpec, "vmSpec");
|
||||
checkNotNull(isoSpec, "isoSpec");
|
||||
checkNotNull(networkSpec, "networkSpec");
|
||||
|
@ -87,27 +87,23 @@ public class MasterSpec {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o instanceof VmSpec) {
|
||||
MasterSpec other = (MasterSpec) o;
|
||||
return Objects.equal(vmSpec, other.vmSpec) &&
|
||||
Objects.equal(isoSpec, other.isoSpec) &&
|
||||
Objects.equal(networkSpec, other.networkSpec);
|
||||
return Objects.equal(vmSpec, other.vmSpec) && Objects.equal(isoSpec, other.isoSpec)
|
||||
&& Objects.equal(networkSpec, other.networkSpec);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(vmSpec,isoSpec,networkSpec);
|
||||
return Objects.hashCode(vmSpec, isoSpec, networkSpec);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IMachineSpec{" +
|
||||
"vmSpec=" + vmSpec +
|
||||
", isoSpec=" + isoSpec +
|
||||
", networkSpec=" + networkSpec +
|
||||
'}';
|
||||
return "IMachineSpec{" + "vmSpec=" + vmSpec + ", isoSpec=" + isoSpec + ", networkSpec=" + networkSpec + '}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,14 +19,15 @@
|
|||
|
||||
package org.jclouds.virtualbox.domain;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.virtualbox_4_1.NATProtocol;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import org.virtualbox_4_1.NATProtocol;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Represents a NAT network adapter in VirtualBox.
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.util.List;
|
|||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
|
||||
/**
|
||||
* Describes the network configuration for a VirtualBox machine.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.virtualbox.domain;
|
||||
|
||||
import org.jclouds.compute.domain.Template;
|
||||
|
||||
public class NodeSpec {
|
||||
|
||||
private final Master master;
|
||||
private final String name;
|
||||
private final String tag;
|
||||
private final Template template;
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private Master master;
|
||||
private String name;
|
||||
private String tag;
|
||||
private Template template;
|
||||
|
||||
public Builder master(Master master) {
|
||||
this.master = master;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder tag(String tag) {
|
||||
this.tag = tag;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder template(Template template) {
|
||||
this.template = template;
|
||||
return this;
|
||||
}
|
||||
|
||||
public NodeSpec build() {
|
||||
return new NodeSpec(master, name, tag, template);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private NodeSpec(Master master, String name, String tag, Template template) {
|
||||
super();
|
||||
this.master = master;
|
||||
this.name = name;
|
||||
this.tag = tag;
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
public Master getMaster() {
|
||||
return master;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public Template getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
}
|
|
@ -18,10 +18,11 @@
|
|||
*/
|
||||
package org.jclouds.virtualbox.domain;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.virtualbox_4_1.NATProtocol;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* @author Mattias Holmqvist
|
||||
|
|
|
@ -18,14 +18,17 @@
|
|||
*/
|
||||
package org.jclouds.virtualbox.domain;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import org.virtualbox_4_1.CleanupMode;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.virtualbox_4_1.CleanupMode;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* A description of a Virtual Machine in VirtualBox.
|
||||
*/
|
||||
|
@ -39,7 +42,8 @@ public class VmSpec {
|
|||
private final Set<StorageController> controllers;
|
||||
private final CleanupMode cleanupMode;
|
||||
|
||||
public VmSpec(String vmId, String vmName, String osTypeId, long memory, boolean forceOverwrite, Set<StorageController> controllers, CleanupMode cleanupMode) {
|
||||
public VmSpec(String vmId, String vmName, String osTypeId, long memory, boolean forceOverwrite,
|
||||
Set<StorageController> controllers, CleanupMode cleanupMode) {
|
||||
this.vmId = checkNotNull(vmId, "vmId");
|
||||
this.vmName = checkNotNull(vmName, "vmName");
|
||||
this.osTypeId = checkNotNull(osTypeId, "osTypeId");
|
||||
|
@ -61,7 +65,7 @@ public class VmSpec {
|
|||
private String name;
|
||||
private String id;
|
||||
private String osTypeId = "";
|
||||
private boolean forceOverwrite;
|
||||
private boolean forceOverwrite = true;
|
||||
private long memory;
|
||||
private CleanupMode cleanUpMode;
|
||||
|
||||
|
@ -138,16 +142,14 @@ public class VmSpec {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o instanceof VmSpec) {
|
||||
VmSpec other = (VmSpec) o;
|
||||
return Objects.equal(vmId, other.vmId) &&
|
||||
Objects.equal(vmName, other.vmName) &&
|
||||
Objects.equal(osTypeId, other.osTypeId) &&
|
||||
Objects.equal(memory, other.memory) &&
|
||||
Objects.equal(forceOverwrite, other.forceOverwrite) &&
|
||||
Objects.equal(controllers, other.controllers) &&
|
||||
Objects.equal(cleanupMode, other.cleanupMode);
|
||||
return Objects.equal(vmId, other.vmId) && Objects.equal(vmName, other.vmName)
|
||||
&& Objects.equal(osTypeId, other.osTypeId) && Objects.equal(memory, other.memory)
|
||||
&& Objects.equal(forceOverwrite, other.forceOverwrite)
|
||||
&& Objects.equal(controllers, other.controllers) && Objects.equal(cleanupMode, other.cleanupMode);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -159,14 +161,8 @@ public class VmSpec {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VmSpecification{" +
|
||||
"vmName='" + vmName + '\'' +
|
||||
", osTypeId='" + osTypeId + '\'' +
|
||||
", memory='" + memory + '\'' +
|
||||
", vmId='" + vmId + '\'' +
|
||||
", forceOverwrite=" + forceOverwrite +
|
||||
", controllers=" + controllers +
|
||||
", cleanupMode=" + cleanupMode +
|
||||
'}';
|
||||
return "VmSpecification{" + "vmName='" + vmName + '\'' + ", osTypeId='" + osTypeId + '\'' + ", memory='" + memory
|
||||
+ '\'' + ", vmId='" + vmId + '\'' + ", forceOverwrite=" + forceOverwrite + ", controllers="
|
||||
+ controllers + ", cleanupMode=" + cleanupMode + '}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,10 +139,10 @@ public class YamlImage {
|
|||
OsFamily family = parseOsFamilyOrUnrecognized(arg0.os_family);
|
||||
|
||||
OperatingSystem operatingSystem = OperatingSystem.builder().description(arg0.os_description).family(family)
|
||||
.version(arg0.os_version).is64Bit(arg0.os_64bit).build();
|
||||
.version(arg0.os_version).is64Bit(arg0.os_64bit).build();
|
||||
|
||||
return new ImageBuilder().id(arg0.id).name(arg0.name).description(arg0.description)
|
||||
.operatingSystem(operatingSystem).build();
|
||||
.operatingSystem(operatingSystem).build();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -61,5 +61,5 @@ public class AttachNicToMachine implements Function<NetworkInterfaceCard, Void>
|
|||
private boolean hasBridgedAdapter(NetworkInterfaceCard nic) {
|
||||
return nic.getNetworkAdapter().getNetworkAttachmentType()
|
||||
.equals(NetworkAttachmentType.Bridged);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ package org.jclouds.virtualbox.functions;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
|
||||
|
@ -31,6 +30,7 @@ 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.NetworkSpec;
|
||||
import org.jclouds.virtualbox.domain.VmSpec;
|
||||
import org.jclouds.virtualbox.util.MachineUtils;
|
||||
import org.virtualbox_4_1.CloneMode;
|
||||
|
@ -46,98 +46,81 @@ 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<IMachine, IMachine> {
|
||||
public class CloneAndRegisterMachineFromIMachineIfNotAlreadyExists implements Function<CloneSpec, IMachine> {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final Supplier<VirtualBoxManager> manager;
|
||||
private final String workingDir;
|
||||
private final CloneSpec cloneSpec;
|
||||
private final boolean isLinkedClone;
|
||||
private final MachineUtils machineUtils;
|
||||
|
||||
@Inject
|
||||
public CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(
|
||||
Supplier<VirtualBoxManager> 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;
|
||||
}
|
||||
private final Supplier<VirtualBoxManager> manager;
|
||||
private final String workingDir;
|
||||
private final MachineUtils machineUtils;
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
@Inject
|
||||
public CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(Supplier<VirtualBoxManager> manager,
|
||||
@Named(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR) String workingDir, MachineUtils machineUtils) {
|
||||
this.manager = manager;
|
||||
this.workingDir = workingDir;
|
||||
this.machineUtils = machineUtils;
|
||||
}
|
||||
|
||||
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 {");
|
||||
}
|
||||
@Override
|
||||
public IMachine apply(CloneSpec cloneSpec) {
|
||||
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(cloneSpec);
|
||||
else
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
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<CloneOptions> options = new ArrayList<CloneOptions>();
|
||||
if (isLinkedClone)
|
||||
options.add(CloneOptions.Link);
|
||||
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 {");
|
||||
}
|
||||
|
||||
// TODO snapshot name
|
||||
ISnapshot currentSnapshot = new TakeSnapshotIfNotAlreadyAttached(
|
||||
manager, "snapshotName", "snapshotDesc").apply(master);
|
||||
private IMachine cloneMachine(CloneSpec cloneSpec) {
|
||||
VmSpec vmSpec = cloneSpec.getVmSpec();
|
||||
NetworkSpec networkSpec = cloneSpec.getNetworkSpec();
|
||||
boolean isLinkedClone = cloneSpec.isLinked();
|
||||
IMachine master = cloneSpec.getMaster();
|
||||
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<CloneOptions> options = new ArrayList<CloneOptions>();
|
||||
if (isLinkedClone)
|
||||
options.add(CloneOptions.Link);
|
||||
|
||||
// clone
|
||||
IProgress progress = currentSnapshot.getMachine().cloneTo(
|
||||
clonedMachine, CloneMode.MachineState, options);
|
||||
// TODO snapshot name
|
||||
ISnapshot currentSnapshot = new TakeSnapshotIfNotAlreadyAttached(manager, "snapshotName", "snapshotDesc")
|
||||
.apply(master);
|
||||
|
||||
if (progress.getCompleted())
|
||||
logger.debug("clone done");
|
||||
// clone
|
||||
IProgress progress = currentSnapshot.getMachine().cloneTo(clonedMachine, CloneMode.MachineState, options);
|
||||
|
||||
progress.waitForCompletion(-1);
|
||||
logger.debug("clone done");
|
||||
|
||||
// registering
|
||||
manager.get().getVBox().registerMachine(clonedMachine);
|
||||
// registering
|
||||
manager.get().getVBox().registerMachine(clonedMachine);
|
||||
|
||||
// Bridged#
|
||||
for (NetworkInterfaceCard nic : cloneSpec.getNetworkSpec().getNetworkInterfaceCards()){
|
||||
ensureBridgedNetworkingIsAppliedToMachine(clonedMachine.getName(), nic);
|
||||
}
|
||||
|
||||
return clonedMachine;
|
||||
}
|
||||
// Networking
|
||||
for (NetworkInterfaceCard networkInterfaceCard : networkSpec.getNetworkInterfaceCards()) {
|
||||
new AttachNicToMachine(vmSpec.getVmName(), machineUtils).apply(networkInterfaceCard);
|
||||
}
|
||||
|
||||
private void ensureBridgedNetworkingIsAppliedToMachine(String vmName,
|
||||
NetworkInterfaceCard nic) {
|
||||
|
||||
machineUtils.writeLockMachineAndApply(vmName,
|
||||
new AttachBridgedAdapterToMachine(nic));
|
||||
}
|
||||
return clonedMachine;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ import javax.annotation.Resource;
|
|||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.options.RunScriptOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
@ -53,7 +53,6 @@ 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;
|
||||
|
@ -65,26 +64,24 @@ public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
|
|||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final ComputeServiceContext context;
|
||||
|
||||
private final Supplier<VirtualBoxManager> manager;
|
||||
private final CreateAndRegisterMachineFromIsoIfNotAlreadyExists createAndRegisterMachineFromIsoIfNotAlreadyExists;
|
||||
|
||||
private final GuestAdditionsInstaller guestAdditionsInstaller;
|
||||
private final Predicate<SshClient> sshResponds;
|
||||
private final ExecutionType executionType;
|
||||
|
||||
private LoadingCache<IsoSpec, URI> preConfiguration;
|
||||
|
||||
private final Function<IMachine, SshClient> sshClientForIMachine;
|
||||
|
||||
private final MachineUtils machineUtils;
|
||||
private final IMachineToNodeMetadata imachineToNodeMetadata;
|
||||
|
||||
@Inject
|
||||
public CreateAndInstallVm(ComputeServiceContext context, Supplier<VirtualBoxManager> manager,
|
||||
CreateAndRegisterMachineFromIsoIfNotAlreadyExists CreateAndRegisterMachineFromIsoIfNotAlreadyExists,
|
||||
Predicate<SshClient> sshResponds, Function<IMachine, SshClient> sshClientForIMachine,
|
||||
ExecutionType executionType, MachineUtils machineUtils, @Preconfiguration LoadingCache<IsoSpec, URI> preConfiguration) {
|
||||
this.context = context;
|
||||
public CreateAndInstallVm(Supplier<VirtualBoxManager> manager,
|
||||
CreateAndRegisterMachineFromIsoIfNotAlreadyExists CreateAndRegisterMachineFromIsoIfNotAlreadyExists,
|
||||
GuestAdditionsInstaller guestAdditionsInstaller, IMachineToNodeMetadata imachineToNodeMetadata,
|
||||
Predicate<SshClient> sshResponds, Function<IMachine, SshClient> sshClientForIMachine,
|
||||
ExecutionType executionType, MachineUtils machineUtils,
|
||||
@Preconfiguration LoadingCache<IsoSpec, URI> preConfiguration) {
|
||||
this.manager = manager;
|
||||
this.createAndRegisterMachineFromIsoIfNotAlreadyExists = CreateAndRegisterMachineFromIsoIfNotAlreadyExists;
|
||||
this.sshResponds = sshResponds;
|
||||
|
@ -92,47 +89,57 @@ public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
|
|||
this.executionType = executionType;
|
||||
this.machineUtils = machineUtils;
|
||||
this.preConfiguration = preConfiguration;
|
||||
this.guestAdditionsInstaller = guestAdditionsInstaller;
|
||||
this.imachineToNodeMetadata = imachineToNodeMetadata;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IMachine apply(MasterSpec masterSpec) {
|
||||
|
||||
VmSpec vmSpec = masterSpec.getVmSpec();
|
||||
IsoSpec isoSpec = masterSpec.getIsoSpec();
|
||||
String vmName = vmSpec.getVmName();
|
||||
|
||||
final IMachine vm = createAndRegisterMachineFromIsoIfNotAlreadyExists.apply(masterSpec);
|
||||
|
||||
IMachine vm = createAndRegisterMachineFromIsoIfNotAlreadyExists.apply(masterSpec);
|
||||
|
||||
// Launch machine and wait for it to come online
|
||||
ensureMachineIsLaunched(vmName);
|
||||
|
||||
|
||||
URI uri = preConfiguration.getUnchecked(isoSpec);
|
||||
String installationKeySequence = isoSpec.getInstallationKeySequence().replace("PRECONFIGURATION_URL",
|
||||
uri.toASCIIString());
|
||||
uri.toASCIIString());
|
||||
|
||||
configureOsInstallationWithKeyboardSequence(vmName, installationKeySequence);
|
||||
SshClient client = sshClientForIMachine.apply(vm);
|
||||
|
||||
logger.debug(">> awaiting installation to finish node(%s)", vmName);
|
||||
|
||||
checkState(sshResponds.apply(client), "timed out waiting for guest %s to be accessible via ssh", vmName);
|
||||
|
||||
|
||||
logger.debug(">> awaiting installation of guest additions on vm: %s", vmName);
|
||||
checkState(new GuestAdditionsInstaller(context).apply(vmName));
|
||||
|
||||
|
||||
checkState(guestAdditionsInstaller.apply(vm));
|
||||
|
||||
logger.debug(">> awaiting post-installation actions on vm: %s", vmName);
|
||||
ListenableFuture<ExecResponse> execFuture = context.getComputeService().submitScriptOnNode(vmName,
|
||||
call("cleanupUdevIfNeeded"), RunScriptOptions.NONE);
|
||||
ExecResponse execResponse = Futures.getUnchecked(execFuture);
|
||||
checkState(execResponse.getExitCode() == 0);
|
||||
|
||||
NodeMetadata vmMetadata = imachineToNodeMetadata.apply(vm);
|
||||
|
||||
// TODO for now this is executed on installModuleAssistantIfNeeded as a workaround to some transient execution issue.
|
||||
// ListenableFuture<ExecResponse> execFuture = machineUtils.runScriptOnNode(vmMetadata, call("cleanupUdevIfNeeded"),
|
||||
// RunScriptOptions.NONE);
|
||||
|
||||
// ExecResponse execResponse = Futures.getUnchecked(execFuture);
|
||||
// checkState(execResponse.getExitCode() == 0);
|
||||
|
||||
logger.debug("<< installation of image complete. Powering down node(%s)", vmName);
|
||||
|
||||
ensureMachineHasPowerDown(vmName);
|
||||
return vm;
|
||||
}
|
||||
|
||||
private void configureOsInstallationWithKeyboardSequence(String vmName, String installationKeySequence) {
|
||||
Iterable<List<Integer>> scancodelist =
|
||||
transform(Splitter.on(" ").split(installationKeySequence), new StringToKeyCode());
|
||||
Iterable<List<Integer>> scancodelist = transform(Splitter.on(" ").split(installationKeySequence),
|
||||
new StringToKeyCode());
|
||||
|
||||
for (List<Integer> scancodes : scancodelist) {
|
||||
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new SendScancodes(scancodes));
|
||||
|
@ -140,26 +147,34 @@ public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
|
|||
}
|
||||
|
||||
/**
|
||||
* ensureMachineHasPowerDown needs to have this delay just to ensure that the machine is completely powered off
|
||||
* ensureMachineHasPowerDown needs to have this delay just to ensure that the machine is
|
||||
* completely powered off
|
||||
*
|
||||
* @param vmName
|
||||
*/
|
||||
private void ensureMachineHasPowerDown(String vmName) {
|
||||
while(!manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.POWERED_OFF)) {
|
||||
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function<ISession, Void>() {
|
||||
@Override
|
||||
public Void apply(ISession session) {
|
||||
IProgress powerDownProgress = session.getConsole().powerDown();
|
||||
powerDownProgress.waitForCompletion(-1);
|
||||
return null;
|
||||
while (!manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.POWERED_OFF)) {
|
||||
try {
|
||||
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function<ISession, Void>() {
|
||||
@Override
|
||||
public Void apply(ISession session) {
|
||||
IProgress powerDownProgress = session.getConsole().powerDown();
|
||||
powerDownProgress.waitForCompletion(-1);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (RuntimeException e) {
|
||||
// sometimes the machine might be powered of between the while test and the call to
|
||||
// lockSessionOnMachineAndApply
|
||||
if (e.getMessage().contains("Invalid machine state: PoweredOff")) {
|
||||
return;
|
||||
} else if (e.getMessage().contains("VirtualBox error: The object is not ready")) {
|
||||
continue;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureMachineIsLaunched(String vmName) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.virtualbox.util.MachineUtils.machineNotFoundException;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
|
@ -69,8 +70,8 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Functi
|
|||
private final String workingDir;
|
||||
|
||||
@Inject
|
||||
public CreateAndRegisterMachineFromIsoIfNotAlreadyExists(Supplier<VirtualBoxManager> manager, MachineUtils machineUtils,
|
||||
@Named(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR) String workingDir) {
|
||||
public CreateAndRegisterMachineFromIsoIfNotAlreadyExists(Supplier<VirtualBoxManager> manager,
|
||||
MachineUtils machineUtils, @Named(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR) String workingDir) {
|
||||
this.manager = manager;
|
||||
this.machineUtils = machineUtils;
|
||||
this.workingDir = workingDir;
|
||||
|
@ -93,11 +94,6 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Functi
|
|||
}
|
||||
}
|
||||
|
||||
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 createMachine(IVirtualBox vBox, MasterSpec machineSpec) {
|
||||
VmSpec vmSpec = machineSpec.getVmSpec();
|
||||
String settingsFile = vBox.composeMachineFilename(vmSpec.getVmName(), workingDir);
|
||||
|
@ -128,7 +124,7 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Functi
|
|||
|
||||
// Networking
|
||||
for (NetworkInterfaceCard networkInterfaceCard : networkSpec.getNetworkInterfaceCards()) {
|
||||
new AttachNicToMachine(vmName, machineUtils).apply(networkInterfaceCard);
|
||||
new AttachNicToMachine(vmName, machineUtils).apply(networkInterfaceCard);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,22 +132,21 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Functi
|
|||
Set<IsoImage> dvds = controller.getIsoImages();
|
||||
for (IsoImage dvd : dvds) {
|
||||
String dvdSource = dvd.getSourcePath();
|
||||
final IMedium dvdMedium = manager.get().getVBox().openMedium(dvdSource, DeviceType.DVD, AccessMode.ReadOnly,
|
||||
vmSpecification.isForceOverwrite());
|
||||
final IMedium dvdMedium = manager.get().getVBox()
|
||||
.openMedium(dvdSource, DeviceType.DVD, AccessMode.ReadOnly, vmSpecification.isForceOverwrite());
|
||||
ensureMachineDevicesAttached(vmName, dvdMedium, dvd.getDeviceDetails(), controller.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureMachineDevicesAttached(String vmName, IMedium medium, DeviceDetails deviceDetails,
|
||||
String controllerName) {
|
||||
machineUtils.writeLockMachineAndApply(vmName, new AttachMediumToMachineIfNotAlreadyAttached(deviceDetails, medium,
|
||||
controllerName));
|
||||
machineUtils.writeLockMachineAndApply(vmName, new AttachMediumToMachineIfNotAlreadyAttached(deviceDetails,
|
||||
medium, controllerName));
|
||||
}
|
||||
|
||||
private String missingIDEControllersMessage(VmSpec vmSpecification) {
|
||||
return String
|
||||
.format(
|
||||
"First controller is not an IDE controller. Please verify that the VM spec is a correct master node: %s",
|
||||
.format("First controller is not an IDE controller. Please verify that the VM spec is a correct master node: %s",
|
||||
vmSpecification);
|
||||
}
|
||||
|
||||
|
@ -175,7 +170,7 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Functi
|
|||
}
|
||||
|
||||
public void ensureMachineHasStorageControllerNamed(String vmName, StorageController storageController) {
|
||||
machineUtils.writeLockMachineAndApply(vmName, new AddIDEControllerIfNotExists(checkNotNull(
|
||||
storageController, "storageController")));
|
||||
machineUtils.writeLockMachineAndApply(vmName,
|
||||
new AddIDEControllerIfNotExists(checkNotNull(storageController, "storageController")));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,9 +61,10 @@ public class IMachineToImage implements Function<IMachine, Image> {
|
|||
OsFamily family = parseOsFamilyOrUnrecognized(guestOSType.getDescription());
|
||||
String version = parseVersionOrReturnEmptyString(family, guestOSType.getDescription(), osVersionMap);
|
||||
OperatingSystem os = OperatingSystem.builder().description(guestOSType.getDescription()).family(family)
|
||||
.version(version).is64Bit(guestOSType.getIs64Bit()).build();
|
||||
.version(version).is64Bit(guestOSType.getIs64Bit()).build();
|
||||
|
||||
return new ImageBuilder().id("" + from.getId()).description(from.getDescription()).operatingSystem(os).build();
|
||||
return new ImageBuilder().id("" + from.getId()).name(from.getName()).description(from.getDescription())
|
||||
.operatingSystem(os).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,11 +18,15 @@
|
|||
*/
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
|
@ -35,6 +39,11 @@ import com.google.inject.Inject;
|
|||
|
||||
@Singleton
|
||||
public class IMachineToSshClient implements Function<IMachine, SshClient> {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final SshClient.Factory sshClientFactory;
|
||||
|
||||
@Inject
|
||||
|
@ -44,9 +53,10 @@ public class IMachineToSshClient implements Function<IMachine, SshClient> {
|
|||
|
||||
@Override
|
||||
public SshClient apply(final IMachine vm) {
|
||||
INetworkAdapter networkAdapter = vm.getNetworkAdapter(0l);
|
||||
INetworkAdapter networkAdapter = vm.getNetworkAdapter(0L);
|
||||
|
||||
SshClient client = null;
|
||||
checkState(networkAdapter != null);
|
||||
checkNotNull(networkAdapter);
|
||||
for (String nameProtocolnumberAddressInboudportGuestTargetport : networkAdapter.getNatDriver().getRedirects()) {
|
||||
Iterable<String> stuff = Splitter.on(',').split(nameProtocolnumberAddressInboudportGuestTargetport);
|
||||
String protocolNumber = Iterables.get(stuff, 1);
|
||||
|
@ -56,10 +66,11 @@ public class IMachineToSshClient implements Function<IMachine, SshClient> {
|
|||
// TODO: we need a way to align the default login credentials from the iso with the
|
||||
// vmspec
|
||||
if ("1".equals(protocolNumber) && "22".equals(targetPort)) {
|
||||
client = sshClientFactory.create(new IPSocket(hostAddress, Integer.parseInt(inboundPort)),
|
||||
LoginCredentials.builder().user("toor").password("password").authenticateSudo(true).build());
|
||||
client = sshClientFactory.create(new IPSocket(hostAddress, Integer.parseInt(inboundPort)), LoginCredentials
|
||||
.builder().user("toor").password("password").authenticateSudo(true).build());
|
||||
}
|
||||
}
|
||||
checkNotNull(client);
|
||||
return client;
|
||||
}
|
||||
}
|
|
@ -58,13 +58,10 @@ public class IMachineToVmSpec implements Function<IMachine, VmSpec> {
|
|||
|
||||
// TODO some parameters are predefined cause the IMachine doesn't have the
|
||||
// concept i.e.: cleanUpMode
|
||||
org.jclouds.virtualbox.domain.VmSpec.Builder vmSpecBuilder = VmSpec
|
||||
.builder();
|
||||
org.jclouds.virtualbox.domain.VmSpec.Builder vmSpecBuilder = VmSpec.builder();
|
||||
|
||||
vmSpecBuilder.id(machine.getId()).name(machine.getName())
|
||||
.memoryMB(machine.getMemorySize().intValue())
|
||||
.osTypeId(machine.getOSTypeId()).forceOverwrite(true)
|
||||
.cleanUpMode(CleanupMode.Full);
|
||||
vmSpecBuilder.id(machine.getId()).name(machine.getName()).memoryMB(machine.getMemorySize().intValue())
|
||||
.osTypeId(machine.getOSTypeId()).forceOverwrite(true).cleanUpMode(CleanupMode.Full);
|
||||
|
||||
for (StorageController storageController : controllers) {
|
||||
vmSpecBuilder.controller(storageController);
|
||||
|
@ -76,28 +73,23 @@ public class IMachineToVmSpec implements Function<IMachine, VmSpec> {
|
|||
private List<StorageController> buildControllers(IMachine machine) {
|
||||
|
||||
List<StorageController> controllers = Lists.newArrayList();
|
||||
for (IStorageController iStorageController : machine
|
||||
.getStorageControllers()) {
|
||||
for (IStorageController iStorageController : machine.getStorageControllers()) {
|
||||
|
||||
Builder storageControlleBuiler = StorageController.builder();
|
||||
for (IMediumAttachment iMediumAttachment : machine
|
||||
.getMediumAttachmentsOfController(iStorageController.getName())) {
|
||||
for (IMediumAttachment iMediumAttachment : machine.getMediumAttachmentsOfController(iStorageController
|
||||
.getName())) {
|
||||
IMedium iMedium = iMediumAttachment.getMedium();
|
||||
if (iMedium.getDeviceType().equals(DeviceType.HardDisk)) {
|
||||
storageControlleBuiler.attachHardDisk(HardDisk.builder()
|
||||
.diskpath(iMedium.getLocation()).autoDelete(true)
|
||||
.controllerPort(iMediumAttachment.getPort())
|
||||
.deviceSlot(iMediumAttachment.getDevice().intValue())
|
||||
.build());
|
||||
storageControlleBuiler.attachHardDisk(HardDisk.builder().diskpath(iMedium.getLocation())
|
||||
.autoDelete(true).controllerPort(iMediumAttachment.getPort())
|
||||
.deviceSlot(iMediumAttachment.getDevice().intValue()).build());
|
||||
} else if (iMedium.getDeviceType().equals(DeviceType.DVD)) {
|
||||
storageControlleBuiler.attachISO(iMediumAttachment.getPort(),
|
||||
iMediumAttachment.getDevice().intValue(),
|
||||
iMedium.getLocation());
|
||||
storageControlleBuiler.attachISO(iMediumAttachment.getPort(), iMediumAttachment.getDevice().intValue(),
|
||||
iMedium.getLocation());
|
||||
}
|
||||
}
|
||||
controllers.add(storageControlleBuiler
|
||||
.name(iStorageController.getName())
|
||||
.bus(iStorageController.getBus()).build());
|
||||
controllers.add(storageControlleBuiler.name(iStorageController.getName()).bus(iStorageController.getBus())
|
||||
.build());
|
||||
}
|
||||
return controllers;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,11 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
|
|||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.virtualbox.domain.ErrorCode;
|
||||
import org.jclouds.virtualbox.domain.ExecutionType;
|
||||
import org.virtualbox_4_1.*;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.IProgress;
|
||||
import org.virtualbox_4_1.SessionState;
|
||||
import org.virtualbox_4_1.VBoxException;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_DIR;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_WORKINGDIR;
|
||||
import static org.jclouds.virtualbox.util.MachineUtils.machineNotFoundException;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.virtualbox.domain.HardDisk;
|
||||
import org.jclouds.virtualbox.domain.IsoSpec;
|
||||
import org.jclouds.virtualbox.domain.Master;
|
||||
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.domain.YamlImage;
|
||||
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;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.AbstractLoadingCache;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Does most of the work wrt to creating the master image.
|
||||
*
|
||||
* @author dralves
|
||||
*
|
||||
*/
|
||||
public class MastersCache extends AbstractLoadingCache<Image, Master> {
|
||||
|
||||
private final Map<String, Master> masters = Maps.newHashMap();
|
||||
private final Function<MasterSpec, IMachine> masterCreatorAndInstaller;
|
||||
private final Map<String, YamlImage> imageMapping;
|
||||
private final String workingDir;
|
||||
private final String guestAdditionsIso;
|
||||
private final String installationKeySequence;
|
||||
private final String isosDir;
|
||||
private Supplier<VirtualBoxManager> manager;
|
||||
|
||||
@Inject
|
||||
public MastersCache(@Named(Constants.PROPERTY_BUILD_VERSION) String version,
|
||||
@Named(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE) String installationKeySequence,
|
||||
@Named(VIRTUALBOX_WORKINGDIR) String workingDir, Function<MasterSpec, IMachine> masterLoader,
|
||||
Supplier<Map<Image, YamlImage>> yamlMapper, Supplier<VirtualBoxManager> manager) {
|
||||
checkNotNull(version, "version");
|
||||
checkNotNull(installationKeySequence, "installationKeySequence");
|
||||
checkNotNull(manager, "vboxmanager");
|
||||
this.manager = manager;
|
||||
this.masterCreatorAndInstaller = masterLoader;
|
||||
this.installationKeySequence = installationKeySequence;
|
||||
this.workingDir = workingDir == null ? VIRTUALBOX_DEFAULT_DIR : workingDir;
|
||||
File wdFile = new File(this.workingDir);
|
||||
if (!wdFile.exists()) {
|
||||
wdFile.mkdirs();
|
||||
}
|
||||
this.isosDir = wdFile.getAbsolutePath() + File.separator + "isos";
|
||||
this.imageMapping = Maps.newLinkedHashMap();
|
||||
for (Entry<Image, YamlImage> entry : yamlMapper.get().entrySet()) {
|
||||
this.imageMapping.put(entry.getKey().getId(), entry.getValue());
|
||||
}
|
||||
this.guestAdditionsIso = String.format("%s/VBoxGuestAdditions_%s.iso", isosDir,
|
||||
Iterables.get(Splitter.on('r').split(version), 0));
|
||||
checkState(new File(guestAdditionsIso).exists(), "guest additions iso does not exist at: " + guestAdditionsIso);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Master get(Image key) throws ExecutionException {
|
||||
// check if we have loaded this machine before
|
||||
if (masters.containsKey(key.getId())) {
|
||||
return masters.get(key);
|
||||
}
|
||||
|
||||
// the yaml image
|
||||
YamlImage yamlImage = imageMapping.get(key.getId());
|
||||
|
||||
checkNotNull(yamlImage, "could not find yaml image for image: " + key);
|
||||
|
||||
// check if the iso is here, download if not
|
||||
String localIsoUrl = getFilePathOrDownload(yamlImage.iso);
|
||||
|
||||
String vmName = VIRTUALBOX_IMAGE_PREFIX + yamlImage.id;
|
||||
|
||||
String adminDisk = workingDir + File.separator + vmName + ".vdi";
|
||||
|
||||
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, localIsoUrl).attachHardDisk(hardDisk).attachISO(1, 1, guestAdditionsIso).build();
|
||||
|
||||
VmSpec vmSpecification = VmSpec.builder().id(yamlImage.id).name(vmName).memoryMB(512).osTypeId("")
|
||||
.controller(ideController).forceOverwrite(true).cleanUpMode(CleanupMode.Full).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().addNIC(0L, networkInterfaceCard).build();
|
||||
|
||||
MasterSpec masterSpec = MasterSpec
|
||||
.builder()
|
||||
.vm(vmSpecification)
|
||||
.iso(IsoSpec.builder().sourcePath(localIsoUrl)
|
||||
.installationScript(installationKeySequence.replace("HOSTNAME", vmSpecification.getVmName()))
|
||||
.build()).network(networkSpec).build();
|
||||
|
||||
IMachine masterMachine;
|
||||
|
||||
// try and find a master machine in vbox
|
||||
try {
|
||||
masterMachine = manager.get().getVBox().findMachine(vmName);
|
||||
} catch (VBoxException e) {
|
||||
if (machineNotFoundException(e)) {
|
||||
// create the master machine if it can't be found
|
||||
masterMachine = masterCreatorAndInstaller.apply(masterSpec);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
Master master = Master.builder().machine(masterMachine).spec(masterSpec).build();
|
||||
|
||||
masters.put(key.getId(), master);
|
||||
|
||||
return master;
|
||||
}
|
||||
|
||||
private String getFilePathOrDownload(String httpUrl) throws ExecutionException {
|
||||
// TODO validation
|
||||
String fileName = httpUrl.substring(httpUrl.lastIndexOf('/') + 1, httpUrl.length());
|
||||
File localFile = new File(isosDir, fileName);
|
||||
// TODO download. for now just expect the file to be there
|
||||
checkState(localFile.exists(), "iso file has not been downloaded: " + fileName);
|
||||
return localFile.getAbsolutePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Master getIfPresent(Image key) {
|
||||
if (masters.containsKey(key.getId())) {
|
||||
return masters.get(key.getId());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
mh * Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_NODE_PREFIX;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.virtualbox.domain.CloneSpec;
|
||||
import org.jclouds.virtualbox.domain.ExecutionType;
|
||||
import org.jclouds.virtualbox.domain.Master;
|
||||
import org.jclouds.virtualbox.domain.NetworkAdapter;
|
||||
import org.jclouds.virtualbox.domain.NetworkInterfaceCard;
|
||||
import org.jclouds.virtualbox.domain.NetworkSpec;
|
||||
import org.jclouds.virtualbox.domain.NodeSpec;
|
||||
import org.jclouds.virtualbox.domain.VmSpec;
|
||||
import org.jclouds.virtualbox.util.MachineUtils;
|
||||
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.VirtualBoxManager;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
@Singleton
|
||||
public class NodeCreator implements Function<NodeSpec, NodeAndInitialCredentials<IMachine>> {
|
||||
|
||||
private final Supplier<VirtualBoxManager> manager;
|
||||
private final Function<CloneSpec, IMachine> cloner;
|
||||
|
||||
@Inject
|
||||
public NodeCreator(Supplier<VirtualBoxManager> manager, Function<CloneSpec, IMachine> cloner,
|
||||
MachineUtils machineUtils) {
|
||||
this.manager = manager;
|
||||
this.cloner = cloner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeAndInitialCredentials<IMachine> apply(NodeSpec nodeSpec) {
|
||||
|
||||
Master master = nodeSpec.getMaster();
|
||||
|
||||
if (master.getMachine().getCurrentSnapshot() != null) {
|
||||
ISession session;
|
||||
try {
|
||||
session = manager.get().openMachineSession(master.getMachine());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("error opening vbox machine session: " + e.getMessage(), e);
|
||||
}
|
||||
session.getConsole().deleteSnapshot(master.getMachine().getCurrentSnapshot().getId());
|
||||
session.unlockMachine();
|
||||
}
|
||||
String masterNameWithoutPrefix = master.getSpec().getVmSpec().getVmName().replace(VIRTUALBOX_IMAGE_PREFIX, "");
|
||||
|
||||
String cloneName = VIRTUALBOX_NODE_PREFIX + masterNameWithoutPrefix + "-" + nodeSpec.getTag() + "-"
|
||||
+ nodeSpec.getName();
|
||||
|
||||
VmSpec cloneVmSpec = VmSpec.builder().id(cloneName).name(cloneName).memoryMB(512).cleanUpMode(CleanupMode.Full)
|
||||
.forceOverwrite(true).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().addNIC(0L, networkInterfaceCard).build();
|
||||
|
||||
CloneSpec cloneSpec = CloneSpec.builder().linked(false).master(master.getMachine()).network(networkSpec)
|
||||
.vm(cloneVmSpec).build();
|
||||
|
||||
IMachine cloned = cloner.apply(cloneSpec);
|
||||
|
||||
new LaunchMachineIfNotAlreadyRunning(manager.get(), ExecutionType.GUI, "").apply(cloned);
|
||||
|
||||
// TODO get credentials from somewhere else (they are also HC in IMachineToSshClient)
|
||||
NodeAndInitialCredentials<IMachine> nodeAndInitialCredentials = new NodeAndInitialCredentials<IMachine>(cloned,
|
||||
cloneName, LoginCredentials.builder().user("toor").password("password").authenticateSudo(true).build());
|
||||
|
||||
return nodeAndInitialCredentials;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jclouds.virtualbox.config.VirtualBoxConstants;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
/**
|
||||
* A supplier for vbox yaml config that reads a yaml whose path is stored under
|
||||
* VirtualBoxConstants.VIRTUALBOX_IMAGES_DESCRIPTOR.
|
||||
*
|
||||
* @author dralves
|
||||
*
|
||||
*/
|
||||
public class YamlImagesFromFileConfig implements Supplier<String> {
|
||||
|
||||
private String yamlFilePath;
|
||||
|
||||
@Inject
|
||||
public YamlImagesFromFileConfig(@Named(VirtualBoxConstants.VIRTUALBOX_IMAGES_DESCRIPTOR) String yamlFilePath) {
|
||||
this.yamlFilePath = yamlFilePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get() {
|
||||
checkNotNull(yamlFilePath, "yaml file path");
|
||||
File yamlFile = new File(yamlFilePath);
|
||||
checkState(yamlFile.exists(), "yaml file does not exist at: " + yamlFilePath);
|
||||
try {
|
||||
return IOUtils.toString(new FileInputStream(yamlFile));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("error reading yaml file");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,35 +19,38 @@
|
|||
|
||||
package org.jclouds.virtualbox.functions.admin;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.virtualbox.domain.YamlImage;
|
||||
import org.yaml.snakeyaml.Loader;
|
||||
import org.yaml.snakeyaml.TypeDescription;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.Constructor;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Andrea Turli
|
||||
*/
|
||||
@Singleton
|
||||
public class ImageFromYamlStream implements Function<InputStream, LoadingCache<String, Image>> {
|
||||
public class ImagesToYamlImagesFromYamlDescriptor implements Supplier<Map<Image, YamlImage>> {
|
||||
|
||||
private String yamlDescriptor;
|
||||
|
||||
@Inject
|
||||
public ImagesToYamlImagesFromYamlDescriptor(Supplier<String> yamlDescriptorSupplier) {
|
||||
this.yamlDescriptor = yamlDescriptorSupplier.get();
|
||||
checkNotNull(yamlDescriptor, "yaml descriptor");
|
||||
checkState(!yamlDescriptor.equals(""), "yaml descriptor is empty");
|
||||
}
|
||||
|
||||
/**
|
||||
* Type-safe config class for YAML
|
||||
|
@ -57,13 +60,8 @@ public class ImageFromYamlStream implements Function<InputStream, LoadingCache<S
|
|||
public List<YamlImage> images;
|
||||
}
|
||||
|
||||
private Object construct(String data) {
|
||||
Yaml yaml = new Yaml();
|
||||
return yaml.load(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoadingCache<String, Image> apply(InputStream source) {
|
||||
public Map<Image, YamlImage> get() {
|
||||
|
||||
Constructor constructor = new Constructor(Config.class);
|
||||
|
||||
|
@ -71,21 +69,16 @@ public class ImageFromYamlStream implements Function<InputStream, LoadingCache<S
|
|||
imageDesc.putListPropertyType("images", String.class);
|
||||
constructor.addTypeDescription(imageDesc);
|
||||
|
||||
Yaml yaml = new Yaml(new Loader(constructor));
|
||||
Config config = (Config) yaml.load(source);
|
||||
Yaml yaml = new Yaml(constructor);
|
||||
Config config = (Config) yaml.load(yamlDescriptor);
|
||||
checkState(config != null, "missing config: class");
|
||||
checkState(config.images != null, "missing images: collection");
|
||||
|
||||
Map<String, Image> backingMap = Maps.uniqueIndex(Iterables.transform(config.images, YamlImage.toImage),
|
||||
new Function<Image, String>() {
|
||||
public String apply(Image image) {
|
||||
return image.getId();
|
||||
}
|
||||
});
|
||||
LoadingCache<String, Image> cache = CacheBuilder.newBuilder().build(CacheLoader.from(Functions.forMap(backingMap)));
|
||||
for (String node : backingMap.keySet())
|
||||
cache.getUnchecked(node);
|
||||
return cache;
|
||||
Map<Image, YamlImage> backingMap = Maps.newLinkedHashMap();
|
||||
for (YamlImage yamlImage : config.images) {
|
||||
backingMap.put(YamlImage.toImage.apply(yamlImage), yamlImage);
|
||||
}
|
||||
return backingMap;
|
||||
}
|
||||
|
||||
}
|
|
@ -4,42 +4,50 @@ import javax.annotation.Resource;
|
|||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
import org.jclouds.compute.options.RunScriptOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.virtualbox.functions.IMachineToNodeMetadata;
|
||||
import org.jclouds.virtualbox.statements.InstallGuestAdditions;
|
||||
import org.jclouds.virtualbox.util.MachineUtils;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
@Singleton
|
||||
public class GuestAdditionsInstaller implements Predicate<String> {
|
||||
public class GuestAdditionsInstaller implements Predicate<IMachine> {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final ComputeServiceContext context;
|
||||
private String vboxVersion;
|
||||
private final IMachineToNodeMetadata imachineToNodeMetadata;
|
||||
private final MachineUtils machineUtils;
|
||||
private final Supplier<VirtualBoxManager> manager;
|
||||
|
||||
@Inject
|
||||
public GuestAdditionsInstaller(ComputeServiceContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
@Inject
|
||||
public GuestAdditionsInstaller(Supplier<VirtualBoxManager> manager, MachineUtils machineUtils,
|
||||
IMachineToNodeMetadata imachineToNodeMetadata) {
|
||||
this.machineUtils = machineUtils;
|
||||
this.imachineToNodeMetadata = imachineToNodeMetadata;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(String vmName) {
|
||||
vboxVersion = Iterables.get(Splitter.on('r').split(context.getProviderSpecificContext().getBuildVersion()), 0);
|
||||
ListenableFuture<ExecResponse> execFuture = context.getComputeService().submitScriptOnNode(vmName,
|
||||
new InstallGuestAdditions(vboxVersion), RunScriptOptions.NONE);
|
||||
ExecResponse execResponse = Futures.getUnchecked(execFuture);
|
||||
return execResponse == null ? false : execResponse.getExitStatus() == 0;
|
||||
}
|
||||
@Override
|
||||
public boolean apply(IMachine machine) {
|
||||
String vboxVersion = Iterables.get(Splitter.on('r').split(manager.get().getVBox().getVersion()), 0);
|
||||
ListenableFuture<ExecResponse> execFuture = machineUtils.runScriptOnNode(imachineToNodeMetadata.apply(machine),
|
||||
new InstallGuestAdditions(vboxVersion), RunScriptOptions.NONE);
|
||||
ExecResponse execResponse = Futures.getUnchecked(execFuture);
|
||||
return execResponse == null ? false : execResponse.getExitStatus() == 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -45,7 +45,9 @@ public class SshResponds implements Predicate<SshClient> {
|
|||
} catch (SshException e) {
|
||||
logger.trace("No response from ssh daemon connecting to %s: %s", client, e.getMessage());
|
||||
} finally {
|
||||
if (client != null) {
|
||||
client.disconnect();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -18,29 +18,41 @@
|
|||
*/
|
||||
package org.jclouds.virtualbox.util;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.inject.Inject;
|
||||
import org.jclouds.compute.callables.RunScriptOnNode;
|
||||
import org.jclouds.compute.callables.RunScriptOnNode.Factory;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.jclouds.util.Throwables2;
|
||||
import org.jclouds.virtualbox.functions.MutableMachine;
|
||||
import org.virtualbox_4_1.*;
|
||||
import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.call;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.findPid;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.kill;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.newStatementList;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.*;
|
||||
import org.jclouds.compute.callables.RunScriptOnNode;
|
||||
import org.jclouds.compute.callables.RunScriptOnNode.Factory;
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.options.RunScriptOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.jclouds.util.Throwables2;
|
||||
import org.jclouds.virtualbox.functions.MutableMachine;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.ISession;
|
||||
import org.virtualbox_4_1.LockType;
|
||||
import org.virtualbox_4_1.SessionState;
|
||||
import org.virtualbox_4_1.VBoxException;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* Utilities for executing functions on a VirtualBox machine.
|
||||
*
|
||||
*
|
||||
* @author Adrian Cole, Mattias Holmqvist, Andrea Turli
|
||||
*/
|
||||
|
||||
|
@ -56,51 +68,59 @@ public class MachineUtils {
|
|||
private final Supplier<NodeMetadata> host;
|
||||
|
||||
@Inject
|
||||
public MachineUtils(Supplier<VirtualBoxManager> manager, RunScriptOnNode.Factory scriptRunner, Supplier<NodeMetadata> host) {
|
||||
public MachineUtils(Supplier<VirtualBoxManager> manager, RunScriptOnNode.Factory scriptRunner,
|
||||
Supplier<NodeMetadata> host) {
|
||||
super();
|
||||
this.manager = manager;
|
||||
this.scriptRunner = scriptRunner;
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks the machine and executes the given function using the machine
|
||||
* matching the given id. Since the machine is locked it is possible to
|
||||
* perform some modifications to the IMachine.
|
||||
* <p/>
|
||||
* Unlocks the machine before returning.
|
||||
*
|
||||
* @param machineId the id of the machine
|
||||
* @param function the function to execute
|
||||
* @return the result from applying the function to the machine.
|
||||
*/
|
||||
public <T> T writeLockMachineAndApply(final String machineId, final Function<IMachine, T> function) {
|
||||
return lockSessionOnMachineAndApply(machineId, LockType.Write,
|
||||
new Function<ISession, T>() {
|
||||
|
||||
@Override
|
||||
public T apply(ISession session) {
|
||||
return function.apply(session.getMachine());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return function.toString();
|
||||
}
|
||||
|
||||
});
|
||||
public ListenableFuture<ExecResponse> runScriptOnNode(NodeMetadata metadata, Statement statement,
|
||||
RunScriptOptions options) {
|
||||
return scriptRunner.submit(metadata, statement, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks the machine and executes the given function using the current
|
||||
* session. Since the machine is locked it is possible to perform some
|
||||
* modifications to the IMachine.
|
||||
* Locks the machine and executes the given function using the machine matching the given id.
|
||||
* Since the machine is locked it is possible to perform some modifications to the IMachine.
|
||||
* <p/>
|
||||
* Unlocks the machine before returning.
|
||||
*
|
||||
* @param type the kind of lock to use when initially locking the machine.
|
||||
* @param machineId the id of the machine
|
||||
* @param function the function to execute
|
||||
*
|
||||
* @param machineId
|
||||
* the id of the machine
|
||||
* @param function
|
||||
* the function to execute
|
||||
* @return the result from applying the function to the machine.
|
||||
*/
|
||||
public <T> T writeLockMachineAndApply(final String machineId, final Function<IMachine, T> function) {
|
||||
return lockSessionOnMachineAndApply(machineId, LockType.Write, new Function<ISession, T>() {
|
||||
|
||||
@Override
|
||||
public T apply(ISession session) {
|
||||
return function.apply(session.getMachine());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return function.toString();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks the machine and executes the given function using the current session. Since the machine
|
||||
* is locked it is possible to perform some modifications to the IMachine.
|
||||
* <p/>
|
||||
* Unlocks the machine before returning.
|
||||
*
|
||||
* @param type
|
||||
* the kind of lock to use when initially locking the machine.
|
||||
* @param machineId
|
||||
* the id of the machine
|
||||
* @param function
|
||||
* the function to execute
|
||||
* @return the result from applying the function to the session.
|
||||
*/
|
||||
public <T> T lockSessionOnMachineAndApply(String machineId, LockType type, Function<ISession, T> function) {
|
||||
|
@ -112,9 +132,8 @@ public class MachineUtils {
|
|||
session.unlockMachine();
|
||||
}
|
||||
} catch (VBoxException e) {
|
||||
throw new RuntimeException(String.format(
|
||||
"error applying %s to %s with %s lock: %s", function, machineId,
|
||||
type, e.getMessage()), e);
|
||||
throw new RuntimeException(String.format("error applying %s to %s with %s lock: %s", function, machineId,
|
||||
type, e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,25 +144,24 @@ public class MachineUtils {
|
|||
private void unlockMachine(final String machineId) {
|
||||
IMachine immutableMachine = manager.get().getVBox().findMachine(machineId);
|
||||
if (immutableMachine.getSessionState().equals(SessionState.Locked)) {
|
||||
Statement kill = newStatementList(call("default"),
|
||||
findPid(immutableMachine.getSessionPid().toString()), kill());
|
||||
scriptRunner
|
||||
.create(host.get(), kill,
|
||||
runAsRoot(false).wrapInInitScript(false)).init().call();
|
||||
Statement kill = newStatementList(call("default"), findPid(immutableMachine.getSessionPid().toString()),
|
||||
kill());
|
||||
scriptRunner.create(host.get(), kill, runAsRoot(false).wrapInInitScript(false)).init().call();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks the machine and executes the given function using the machine
|
||||
* matching the given id. Since the machine is unlocked it is possible to
|
||||
* delete the IMachine.
|
||||
* Unlocks the machine and executes the given function using the machine matching the given id.
|
||||
* Since the machine is unlocked it is possible to delete the IMachine.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* <h3>Note!</h3> Currently, this can only unlock the machine, if the lock
|
||||
* was created in the current session.
|
||||
*
|
||||
* @param machineId the id of the machine
|
||||
* @param function the function to execute
|
||||
* <h3>Note!</h3> Currently, this can only unlock the machine, if the lock was created in the
|
||||
* current session.
|
||||
*
|
||||
* @param machineId
|
||||
* the id of the machine
|
||||
* @param function
|
||||
* the function to execute
|
||||
* @return the result from applying the function to the machine.
|
||||
*/
|
||||
public <T> T unlockMachineAndApply(final String machineId, final Function<IMachine, T> function) {
|
||||
|
@ -154,31 +172,28 @@ public class MachineUtils {
|
|||
return function.apply(immutableMachine);
|
||||
|
||||
} catch (VBoxException e) {
|
||||
throw new RuntimeException(String.format(
|
||||
"error applying %s to %s: %s", function, machineId,
|
||||
e.getMessage()), e);
|
||||
throw new RuntimeException(String.format("error applying %s to %s: %s", function, machineId, e.getMessage()),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks the machine and executes the given function, if the machine is
|
||||
* registered. Since the machine is unlocked it is possible to delete the
|
||||
* machine.
|
||||
* Unlocks the machine and executes the given function, if the machine is registered. Since the
|
||||
* machine is unlocked it is possible to delete the machine.
|
||||
* <p/>
|
||||
*
|
||||
* @param machineId the id of the machine
|
||||
* @param function the function to execute
|
||||
*
|
||||
* @param machineId
|
||||
* the id of the machine
|
||||
* @param function
|
||||
* the function to execute
|
||||
* @return the result from applying the function to the session.
|
||||
*/
|
||||
public <T> T unlockMachineAndApplyOrReturnNullIfNotRegistered(String machineId,
|
||||
Function<IMachine, T> function) {
|
||||
public <T> T unlockMachineAndApplyOrReturnNullIfNotRegistered(String machineId, Function<IMachine, T> function) {
|
||||
try {
|
||||
return unlockMachineAndApply(machineId, function);
|
||||
} catch (RuntimeException e) {
|
||||
VBoxException vbex = Throwables2.getFirstThrowableOfType(e,
|
||||
VBoxException.class);
|
||||
if (vbex != null
|
||||
&& vbex.getMessage().indexOf("not find a registered") == -1)
|
||||
VBoxException vbex = Throwables2.getFirstThrowableOfType(e, VBoxException.class);
|
||||
if (vbex != null && vbex.getMessage().indexOf("not find a registered") == -1)
|
||||
throw e;
|
||||
return null;
|
||||
}
|
||||
|
@ -204,4 +219,8 @@ public class MachineUtils {
|
|||
}.apply(immutableMachine);
|
||||
}
|
||||
|
||||
public static 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 {");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,5 +6,9 @@ function installModuleAssistantIfNeeded {
|
|||
echo "OS is Ubuntu"
|
||||
apt-get -f -y -qq --force-yes install build-essential module-assistant;
|
||||
m-a prepare -i
|
||||
rm /etc/udev/rules.d/70-persistent-net.rules;
|
||||
mkdir /etc/udev/rules.d/70-persistent-net.rules;
|
||||
rm -rf /dev/.udev/;
|
||||
rm /lib/udev/rules.d/75-persistent-net-generator.rules
|
||||
fi
|
||||
}
|
|
@ -19,16 +19,10 @@
|
|||
|
||||
package org.jclouds.virtualbox;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.byon.Node;
|
||||
import org.jclouds.byon.config.CacheNodeStoreModule;
|
||||
|
@ -37,7 +31,8 @@ import org.jclouds.compute.ComputeServiceContext;
|
|||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials;
|
||||
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
|
||||
import org.jclouds.config.ValueOfConfigurationKeyOrNull;
|
||||
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
|
@ -49,14 +44,26 @@ import org.jclouds.virtualbox.util.MachineUtils;
|
|||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.IProgress;
|
||||
import org.virtualbox_4_1.ISession;
|
||||
import org.virtualbox_4_1.LockType;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
import org.virtualbox_4_1.jaxws.MachineState;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code VirtualBoxClient}
|
||||
*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", singleThreaded = true, testName = "BaseVirtualBoxClientLiveTest")
|
||||
|
@ -72,9 +79,11 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
|
|||
protected String hostVersion;
|
||||
protected String operatingSystemIso;
|
||||
protected String guestAdditionsIso;
|
||||
protected String adminDisk;
|
||||
protected String workingDir;
|
||||
protected String isosDir;
|
||||
protected Supplier<NodeMetadata> host;
|
||||
protected static final PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate = new PrioritizeCredentialsFromTemplate(
|
||||
new DefaultCredentialsFromImageOrOverridingCredentials());
|
||||
|
||||
@Override
|
||||
protected void setupCredentials() {
|
||||
|
@ -86,52 +95,44 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
|
|||
}
|
||||
|
||||
protected void ensureIdentityPropertyIsSpecifiedOrTakeFromDefaults() {
|
||||
Properties defaultVBoxProperties = new VirtualBoxPropertiesBuilder()
|
||||
.build();
|
||||
Properties defaultVBoxProperties = new VirtualBoxPropertiesBuilder().build();
|
||||
if (!System.getProperties().containsKey("test." + provider + ".identity"))
|
||||
System.setProperty("test." + provider + ".identity",
|
||||
defaultVBoxProperties.getProperty(Constants.PROPERTY_IDENTITY));
|
||||
defaultVBoxProperties.getProperty(Constants.PROPERTY_IDENTITY));
|
||||
}
|
||||
|
||||
@BeforeClass(groups = "live")
|
||||
public void setupClient() {
|
||||
setupCredentials();
|
||||
Properties overrides = setupProperties();
|
||||
Properties overrides = new VirtualBoxPropertiesBuilder(setupProperties()).build();
|
||||
|
||||
CacheNodeStoreModule hostModule = new CacheNodeStoreModule(
|
||||
ImmutableMap.of(
|
||||
"host",
|
||||
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(
|
||||
URI.create("file://"
|
||||
+ System.getProperty("user.home")
|
||||
+ "/.ssh/id_rsa")).build()));
|
||||
CacheNodeStoreModule hostModule = new CacheNodeStoreModule(ImmutableMap.of(
|
||||
"host",
|
||||
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(URI.create("file://" + System.getProperty("user.home") + "/.ssh/id_rsa"))
|
||||
.build()));
|
||||
|
||||
context = new ComputeServiceContextFactory().createContext(provider,
|
||||
identity, credential, ImmutableSet.<Module>of(
|
||||
new SLF4JLoggingModule(), new SshjSshClientModule(),
|
||||
hostModule), overrides);
|
||||
context = new ComputeServiceContextFactory().createContext(provider, identity, credential,
|
||||
ImmutableSet.<Module> of(new SLF4JLoggingModule(), new SshjSshClientModule(), hostModule), overrides);
|
||||
Function<String, String> configProperties = context.utils().injector()
|
||||
.getInstance(ValueOfConfigurationKeyOrNull.class);
|
||||
imageId = configProperties
|
||||
.apply(ComputeServiceConstants.PROPERTY_IMAGE_ID);
|
||||
workingDir = configProperties
|
||||
.apply(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR);
|
||||
host = context.utils().injector()
|
||||
.getInstance(Key.get(new TypeLiteral<Supplier<NodeMetadata>>() {
|
||||
}));
|
||||
.getInstance(ValueOfConfigurationKeyOrNull.class);
|
||||
imageId = "ubuntu-11.04-server-i386";
|
||||
workingDir = configProperties.apply(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR);
|
||||
isosDir = workingDir + File.separator + "isos";
|
||||
File isosDirFile = new File(isosDir);
|
||||
if (!isosDirFile.exists()) {
|
||||
isosDirFile.mkdirs();
|
||||
}
|
||||
host = context.utils().injector().getInstance(Key.get(new TypeLiteral<Supplier<NodeMetadata>>() {
|
||||
}));
|
||||
|
||||
// this will eagerly startup Jetty, note the impl will shut itself down
|
||||
preconfigurationUri = context.utils().injector().getInstance(Key.get(new TypeLiteral<LoadingCache<IsoSpec, URI>>() {
|
||||
}, Preconfiguration.class));
|
||||
preconfigurationUri = context.utils().injector()
|
||||
.getInstance(Key.get(new TypeLiteral<LoadingCache<IsoSpec, URI>>() {
|
||||
}, Preconfiguration.class));
|
||||
// this will eagerly startup Jetty, note the impl will shut itself down
|
||||
|
||||
manager = context.utils().injector().getInstance(Key.get(new TypeLiteral<Supplier<VirtualBoxManager>>() {
|
||||
|
@ -141,19 +142,43 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
|
|||
|
||||
machineUtils = context.utils().injector().getInstance(MachineUtils.class);
|
||||
|
||||
hostVersion = Iterables.get(
|
||||
Splitter.on('r').split(
|
||||
context.getProviderSpecificContext().getBuildVersion()), 0);
|
||||
adminDisk = workingDir + "/testadmin.vdi";
|
||||
operatingSystemIso = String.format("%s/%s.iso", workingDir, imageId);
|
||||
guestAdditionsIso = String.format("%s/VBoxGuestAdditions_%s.iso",
|
||||
workingDir, hostVersion);
|
||||
hostVersion = Iterables.get(Splitter.on('r').split(context.getProviderSpecificContext().getBuildVersion()), 0);
|
||||
operatingSystemIso = String.format("%s/%s.iso", isosDir, imageId);
|
||||
guestAdditionsIso = String.format("%s/VBoxGuestAdditions_%s.iso", isosDir, hostVersion);
|
||||
}
|
||||
|
||||
protected void undoVm(VmSpec vmSpecification) {
|
||||
machineUtils.unlockMachineAndApplyOrReturnNullIfNotRegistered(
|
||||
vmSpecification.getVmId(),
|
||||
new UnregisterMachineIfExistsAndDeleteItsMedia(vmSpecification));
|
||||
machineUtils.unlockMachineAndApplyOrReturnNullIfNotRegistered(vmSpecification.getVmId(),
|
||||
new UnregisterMachineIfExistsAndDeleteItsMedia(vmSpecification));
|
||||
}
|
||||
|
||||
protected void ensureMachineHasPowerDown(String vmName) {
|
||||
while (!manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.POWERED_OFF)) {
|
||||
try {
|
||||
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function<ISession, Void>() {
|
||||
@Override
|
||||
public Void apply(ISession session) {
|
||||
IProgress powerDownProgress = session.getConsole().powerDown();
|
||||
powerDownProgress.waitForCompletion(-1);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (RuntimeException e) {
|
||||
// sometimes the machine might be powered of between the while test and the call to
|
||||
// lockSessionOnMachineAndApply
|
||||
if (e.getMessage().contains("Invalid machine state: PoweredOff")) {
|
||||
return;
|
||||
} else if (e.getMessage().contains("VirtualBox error: The object is not ready")) {
|
||||
continue;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String adminDisk(String vmName) {
|
||||
return workingDir + File.separator + vmName + ".vdi";
|
||||
}
|
||||
|
||||
@AfterClass(groups = "live")
|
||||
|
|
|
@ -19,20 +19,17 @@
|
|||
|
||||
package org.jclouds.virtualbox.compute;
|
||||
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_NODE_PREFIX;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials;
|
||||
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
|
||||
import org.jclouds.virtualbox.functions.IMachineToSshClient;
|
||||
import org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
|
||||
|
@ -50,17 +47,17 @@ public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClien
|
|||
adapter = context.utils().injector().getInstance(VirtualBoxComputeServiceAdapter.class);
|
||||
}
|
||||
|
||||
private static final PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate = new PrioritizeCredentialsFromTemplate(
|
||||
new DefaultCredentialsFromImageOrOverridingCredentials());
|
||||
|
||||
@Test
|
||||
public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentials() {
|
||||
String group = "foo";
|
||||
String name = "foo-ef4";
|
||||
Template template = context.getComputeService().templateBuilder().build();
|
||||
String machineName = VIRTUALBOX_NODE_PREFIX + "myTestId-" + group + "-" + name;
|
||||
// get the image from
|
||||
Image image = Iterables.get(adapter.listImages(), 0);
|
||||
System.out.println(context.getComputeService().templateBuilder());
|
||||
Template template = context.getComputeService().templateBuilder().fromImage(image).build();
|
||||
machine = adapter.createNodeWithGroupEncodedIntoName(group, name, template);
|
||||
assertEquals(machine.getNode().getName(), name);
|
||||
assertEquals(machine.getNodeId(), machine.getNode().getId());
|
||||
assertEquals(machine.getNode().getName(), machineName);
|
||||
// is there a place for group?
|
||||
// check other things, like cpu correct, mem correct, image/os is correct
|
||||
// (as possible)
|
||||
|
@ -69,11 +66,10 @@ public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClien
|
|||
// InetAddresses.isInetAddress(machine.getPrimaryBackendIpAddress()) :
|
||||
// machine;
|
||||
doConnectViaSsh(machine.getNode(), prioritizeCredentialsFromTemplate.apply(template, machine.getCredentials()));
|
||||
|
||||
}
|
||||
|
||||
protected void doConnectViaSsh(IMachine machine, LoginCredentials creds) {
|
||||
SshClient ssh = context.utils().sshFactory().create(new IPSocket("//TODO", 22), creds);
|
||||
SshClient ssh = context.utils().injector().getInstance(IMachineToSshClient.class).apply(machine);
|
||||
try {
|
||||
ssh.connect();
|
||||
ExecResponse hello = ssh.exec("echo hello");
|
||||
|
@ -90,8 +86,7 @@ public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClien
|
|||
@Test
|
||||
public void testListHardwareProfiles() {
|
||||
Iterable<IMachine> profiles = adapter.listHardwareProfiles();
|
||||
assertTrue(Iterables.isEmpty(profiles));
|
||||
// check state;
|
||||
assertEquals(1, Iterables.size(profiles));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -102,7 +97,7 @@ public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClien
|
|||
}
|
||||
// check state;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
if (machine != null)
|
||||
|
|
|
@ -23,10 +23,8 @@ import static org.easymock.EasyMock.createNiceMock;
|
|||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -46,7 +44,6 @@ import org.virtualbox_4_1.VirtualBoxManager;
|
|||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.inject.Guice;
|
||||
|
||||
@Test(groups = "unit")
|
||||
|
@ -83,11 +80,25 @@ public class VirtualBoxComputeServiceAdapterTest {
|
|||
replay(manager, vBox, clonedMachine, imageMachine, osType);
|
||||
|
||||
Function<IMachine, Image> iMachineToImage = new IMachineToImage(Suppliers.ofInstance(manager), osMap);
|
||||
VirtualBoxComputeServiceAdapter adapter = new VirtualBoxComputeServiceAdapter(Suppliers.ofInstance(manager), iMachineToImage);
|
||||
|
||||
Iterator<Image> iterator = adapter.listImages().iterator();
|
||||
Image image = Iterators.getOnlyElement(iterator);
|
||||
assertEquals(image.getDescription(), VIRTUALBOX_IMAGE_PREFIX + "ubuntu-10.04");
|
||||
// VirtualBoxComputeServiceAdapter adapter = new VirtualBoxComputeServiceAdapter(Suppliers.ofInstance(manager), iMachineToImage, new ImageFromYamlString(), new Supplier<String>() {
|
||||
//
|
||||
// @Override
|
||||
// public String get() {
|
||||
// return "images:\n" +
|
||||
// " - id: myTestId\n" +
|
||||
// " name: ubuntu-11.04-server-i386\n" +
|
||||
// " description: ubuntu 11.04 server (i386)\n" +
|
||||
// " os_arch: x86\n" +
|
||||
// " os_family: ubuntu\n" +
|
||||
// " os_description: ubuntu\n" +
|
||||
// " os_version: 11.04\n" +
|
||||
// " iso: http://releases.ubuntu.com/11.04/ubuntu-11.04-server-i386.iso";
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// Iterator<Image> iterator = adapter.listImages().iterator();
|
||||
// Image image = Iterators.getOnlyElement(iterator);
|
||||
// assertEquals(image.getDescription(), "ubuntu 11.04 server (i386)");
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ import com.google.common.io.Resources;
|
|||
|
||||
@Test(groups = "unit")
|
||||
public class InstallGuestAdditionsTest {
|
||||
@Test
|
||||
@Test(enabled = false)
|
||||
public void testUnixByItself() throws IOException {
|
||||
InstallGuestAdditions statement = new InstallGuestAdditions("4.1.6");
|
||||
assertEquals(statement.render(OsFamily.UNIX),
|
||||
|
@ -44,7 +44,7 @@ public class InstallGuestAdditionsTest {
|
|||
Charsets.UTF_8)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(enabled = false)
|
||||
public void testUnixInInitScript() throws IOException {
|
||||
Statement statement = InitScript.builder().name("install_guest_additions")
|
||||
.run(new InstallGuestAdditions("4.1.6")).build();
|
||||
|
|
|
@ -19,6 +19,12 @@
|
|||
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.createNiceMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
|
||||
import org.jclouds.virtualbox.domain.StorageController;
|
||||
import org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
|
@ -26,9 +32,6 @@ import org.virtualbox_4_1.IStorageController;
|
|||
import org.virtualbox_4_1.StorageBus;
|
||||
import org.virtualbox_4_1.VBoxException;
|
||||
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.*;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.createNiceMock;
|
||||
import static org.easymock.EasyMock.expectLastCall;
|
||||
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 org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
|
|
|
@ -21,12 +21,12 @@ package org.jclouds.virtualbox.functions;
|
|||
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static org.easymock.EasyMock.anyLong;
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.createNiceMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.expectLastCall;
|
||||
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 org.jclouds.virtualbox.domain.DeviceDetails;
|
||||
import org.jclouds.virtualbox.domain.HardDisk;
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.config.ValueOfConfigurationKeyOrNull;
|
||||
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
|
||||
import org.jclouds.virtualbox.domain.CloneSpec;
|
||||
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.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.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;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* @author Andrea Turli
|
||||
*/
|
||||
@Test(groups = "live", singleThreaded = true, testName = "CloneAndRegisterMachineFromIMachineIfNotAlreadyExistsLiveTest")
|
||||
public class CloneAndRegisterMachineFromIMachineIfNotAlreadyExistsLiveTest extends BaseVirtualBoxClientLiveTest {
|
||||
|
||||
private static final boolean IS_LINKED_CLONE = true;
|
||||
|
||||
private MasterSpec sourceMachineSpec;
|
||||
private CleanupMode mode = CleanupMode.Full;
|
||||
private VmSpec clonedVmSpec;
|
||||
private NetworkSpec cloneNetworkSpec;
|
||||
|
||||
@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(sourceName)).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();
|
||||
|
||||
Injector injector = context.utils().injector();
|
||||
Function<String, String> 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();
|
||||
|
||||
this.cloneNetworkSpec = NetworkSpec.builder().addNIC(0L, networkInterfaceCard).build();
|
||||
|
||||
sourceMachineSpec = MasterSpec.builder().iso(isoSpec).vm(sourceVmSpec).network(cloneNetworkSpec).build();
|
||||
|
||||
this.clonedVmSpec = VmSpec.builder().id(cloneName).name(cloneName).memoryMB(512).cleanUpMode(mode)
|
||||
.forceOverwrite(true).build();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloneMachineFromAnotherMachine() throws Exception {
|
||||
CloneSpec cloneSpec = null;
|
||||
try {
|
||||
|
||||
IMachine source = getSourceNode();
|
||||
|
||||
cloneSpec = CloneSpec.builder().vm(clonedVmSpec).network(cloneNetworkSpec).master(source)
|
||||
.linked(IS_LINKED_CLONE).build();
|
||||
|
||||
if (source.getCurrentSnapshot() != null) {
|
||||
ISession session = manager.get().openMachineSession(source);
|
||||
session.getConsole().deleteSnapshot(source.getCurrentSnapshot().getId());
|
||||
session.unlockMachine();
|
||||
}
|
||||
|
||||
IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(manager, workingDir, machineUtils)
|
||||
.apply(cloneSpec);
|
||||
assertEquals(clone.getName(), cloneSpec.getVmSpec().getVmName());
|
||||
|
||||
new LaunchMachineIfNotAlreadyRunning(manager.get(), ExecutionType.GUI, "").apply(clone);
|
||||
|
||||
// TODO ssh into the node
|
||||
|
||||
} finally {
|
||||
Set<VmSpec> specs = cloneSpec == null ? ImmutableSet.of(sourceMachineSpec.getVmSpec()) : ImmutableSet.of(
|
||||
cloneSpec.getVmSpec(), sourceMachineSpec.getVmSpec());
|
||||
for (VmSpec spec : specs) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,156 +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.functions;
|
||||
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
|
||||
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.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;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* @author Andrea Turli
|
||||
*/
|
||||
@Test(groups = "live", singleThreaded = true, testName = "CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest")
|
||||
public class CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends
|
||||
BaseVirtualBoxClientLiveTest {
|
||||
|
||||
private static final boolean IS_LINKED_CLONE = true;
|
||||
|
||||
private CloneSpec cloneSpec;
|
||||
private MasterSpec sourceMachineSpec;
|
||||
|
||||
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());
|
||||
|
||||
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();
|
||||
|
||||
Injector injector = context.utils().injector();
|
||||
Function<String, String> 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()
|
||||
.addNIC(0L, networkInterfaceCard).build();
|
||||
sourceMachineSpec = MasterSpec.builder().iso(isoSpec).vm(sourceVmSpec)
|
||||
.network(networkSpec).build();
|
||||
|
||||
VmSpec clonedVmSpec = VmSpec.builder().id(cloneName).name(cloneName)
|
||||
.memoryMB(512).cleanUpMode(mode).forceOverwrite(true).build();
|
||||
|
||||
cloneSpec = CloneSpec.builder().vm(clonedVmSpec).network(networkSpec)
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -20,15 +20,11 @@
|
|||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.base.Predicates.equalTo;
|
||||
import static com.google.common.collect.Iterables.any;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
@ -56,18 +52,15 @@ import org.testng.annotations.BeforeClass;
|
|||
import org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.CleanupMode;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.IProgress;
|
||||
import org.virtualbox_4_1.ISession;
|
||||
import org.virtualbox_4_1.LockType;
|
||||
import org.virtualbox_4_1.NetworkAttachmentType;
|
||||
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;
|
||||
|
@ -79,166 +72,118 @@ import com.google.inject.Injector;
|
|||
@Test(groups = "live", singleThreaded = true, testName = "CreateAndInstallVmLiveTest")
|
||||
public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest {
|
||||
|
||||
Map<OsFamily, Map<String, String>> map = new BaseComputeServiceContextModule() {
|
||||
}.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice
|
||||
.createInjector(new GsonModule()).getInstance(Json.class));
|
||||
Map<OsFamily, Map<String, String>> 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<IMachine, SshClient> sshClientForIMachine;
|
||||
private Predicate<SshClient> sshResponds;
|
||||
private VmSpec vmSpecification;
|
||||
private MasterSpec masterSpec;
|
||||
private Injector injector;
|
||||
private Function<IMachine, SshClient> sshClientForIMachine;
|
||||
private Predicate<SshClient> sshResponds;
|
||||
private String vmName;
|
||||
|
||||
@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();
|
||||
this.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();
|
||||
HardDisk hardDisk = HardDisk.builder().diskpath(adminDisk(vmName)).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<String, String> configProperties = injector
|
||||
.getInstance(ValueOfConfigurationKeyOrNull.class);
|
||||
injector = context.utils().injector();
|
||||
Function<String, String> configProperties = injector.getInstance(ValueOfConfigurationKeyOrNull.class);
|
||||
|
||||
NetworkAdapter networkAdapter = NetworkAdapter.builder()
|
||||
.networkAttachmentType(NetworkAttachmentType.NAT)
|
||||
.tcpRedirectRule("127.0.0.1", 2222, "", 22).build();
|
||||
NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard
|
||||
.builder().addNetworkAdapter(networkAdapter).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()
|
||||
.addNIC(0L, networkInterfaceCard).build();
|
||||
NetworkSpec networkSpec = NetworkSpec.builder().addNIC(0L, networkInterfaceCard).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).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).build();
|
||||
|
||||
undoVm(vmSpecification);
|
||||
}
|
||||
undoVm(vmSpecification);
|
||||
}
|
||||
|
||||
public void testCreateImageMachineFromIso() throws Exception {
|
||||
IMachine imageMachine = getVmWithGuestAdditionsInstalled();
|
||||
@Test
|
||||
public void testCreateImageMachineFromIso() throws Exception {
|
||||
IMachine imageMachine = getVmWithGuestAdditionsInstalled();
|
||||
IMachineToImage iMachineToImage = new IMachineToImage(manager, map);
|
||||
Image newImage = iMachineToImage.apply(imageMachine);
|
||||
assertEquals(vmName, newImage.getName());
|
||||
}
|
||||
|
||||
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<? extends Image> images = context.getComputeService().listImages();
|
||||
Iterable<String> imageIds = transform(images, extractId());
|
||||
assertTrue(any(imageIds, equalTo(newImage.getId())));
|
||||
}
|
||||
@Test
|
||||
public void testGuestAdditionsAreInstalled() throws Exception {
|
||||
try {
|
||||
IMachine machine = getVmWithGuestAdditionsInstalled();
|
||||
|
||||
@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);
|
||||
|
||||
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());
|
||||
|
||||
sshResponds = injector.getInstance(SshResponds.class);
|
||||
checkState(sshResponds.apply(client),
|
||||
"timed out waiting for guest %s to be accessible via ssh",
|
||||
machine.getName());
|
||||
String vboxVersion = Iterables.get(
|
||||
Splitter.on('r').split(context.getProviderSpecificContext().getBuildVersion()), 0);
|
||||
assertEquals(vboxVersion, machineUtils.lockSessionOnMachineAndApply(machine.getName(), LockType.Shared,
|
||||
new Function<ISession, String>() {
|
||||
@Override
|
||||
public String apply(ISession session) {
|
||||
return session.getMachine().getGuestPropertyValue("/VirtualBox/GuestAdd/Version");
|
||||
}
|
||||
}));
|
||||
} finally {
|
||||
for (VmSpec spec : ImmutableSet.of(vmSpecification)) {
|
||||
ensureMachineHasPowerDown(spec.getVmName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(machineUtils.lockSessionOnMachineAndApply(
|
||||
machine.getName(), LockType.Shared,
|
||||
new Function<ISession, Boolean>() {
|
||||
@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<Image, String> extractId() {
|
||||
return new Function<Image, String>() {
|
||||
|
||||
private Function<Image, String> extractId() {
|
||||
return new Function<Image, String>() {
|
||||
@Override
|
||||
public String apply(@Nullable Image input) {
|
||||
return input.getId();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@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 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.POWERED_OFF)) {
|
||||
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared,
|
||||
new Function<ISession, Void>() {
|
||||
@Override
|
||||
public Void apply(ISession session) {
|
||||
IProgress powerDownProgress = session.getConsole()
|
||||
.powerDown();
|
||||
powerDownProgress.waitForCompletion(-1);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
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();
|
||||
}
|
||||
@Override
|
||||
@AfterClass(groups = "live")
|
||||
protected void tearDown() throws Exception {
|
||||
for (VmSpec spec : ImmutableSet.of(vmSpecification)) {
|
||||
undoVm(spec);
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,9 +23,16 @@ import static org.testng.Assert.fail;
|
|||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
|
||||
import org.jclouds.virtualbox.domain.*;
|
||||
import org.jclouds.virtualbox.domain.ErrorCode;
|
||||
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.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.CleanupMode;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
|
@ -33,6 +40,8 @@ import org.virtualbox_4_1.NetworkAttachmentType;
|
|||
import org.virtualbox_4_1.StorageBus;
|
||||
import org.virtualbox_4_1.VBoxException;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* @author Mattias Holmqvist
|
||||
*/
|
||||
|
@ -42,28 +51,23 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends
|
|||
|
||||
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();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateNewMachine() throws Exception {
|
||||
String vmName = "jclouds-test-create-1-node";
|
||||
String vmId = UUID.randomUUID().toString();
|
||||
|
||||
StorageController ideController = StorageController.builder().name(ideControllerName).bus(StorageBus.IDE)
|
||||
.attachISO(0, 0, operatingSystemIso)
|
||||
.attachHardDisk(HardDisk.builder().diskpath(adminDisk(vmName)).controllerPort(0).deviceSlot(1).build())
|
||||
.attachISO(1, 1, guestAdditionsIso).build();
|
||||
|
||||
VmSpec vmSpec = VmSpec.builder().id(vmId).name(vmName).memoryMB(512)
|
||||
.controller(ideController).cleanUpMode(mode).osTypeId("Debian")
|
||||
|
@ -101,6 +105,11 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends
|
|||
public void testCreateNewMachineWithBadOsType() throws Exception {
|
||||
String vmName = "jclouds-test-create-2-node";
|
||||
String vmId = UUID.randomUUID().toString();
|
||||
|
||||
StorageController ideController = StorageController.builder().name(ideControllerName).bus(StorageBus.IDE)
|
||||
.attachISO(0, 0, operatingSystemIso)
|
||||
.attachHardDisk(HardDisk.builder().diskpath(adminDisk(vmName)).controllerPort(0).deviceSlot(1).build())
|
||||
.attachISO(1, 1, guestAdditionsIso).build();
|
||||
|
||||
VmSpec vmSpec = VmSpec.builder().id(vmId).name(vmName).memoryMB(512)
|
||||
.controller(ideController).cleanUpMode(mode)
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
*/
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.createNiceMock;
|
||||
import static org.easymock.EasyMock.expectLastCall;
|
||||
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 org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static org.easymock.EasyMock.createNiceMock;
|
||||
import static org.easymock.EasyMock.eq;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static org.easymock.EasyMock.createNiceMock;
|
||||
import static org.easymock.EasyMock.eq;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.AssertJUnit.assertTrue;
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static org.easymock.EasyMock.createNiceMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.virtualbox.domain.HardDisk;
|
||||
|
|
|
@ -18,14 +18,18 @@
|
|||
*/
|
||||
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.replay;
|
||||
import static org.easymock.classextension.EasyMock.verify;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
|
||||
import org.jclouds.virtualbox.domain.ExecutionType;
|
||||
import org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.*;
|
||||
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;
|
||||
|
||||
@Test(groups = "unit", testName = "LaunchMachineIfNotAlreadyRunningTest")
|
||||
public class LaunchMachineIfNotAlreadyRunningTest {
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
*/
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.createNiceMock;
|
||||
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 org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.IConsole;
|
||||
|
|
|
@ -1,56 +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.functions.admin;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.ImageBuilder;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
* @author Andrea Turli
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ImageFromYamlStreamTest {
|
||||
|
||||
public static final Image TEST1 = new ImageBuilder()
|
||||
.id("myTestId")
|
||||
.name("ubuntu-11.04-server-i386")
|
||||
.description("ubuntu 11.04 server (i386)")
|
||||
.operatingSystem(
|
||||
OperatingSystem.builder().description("ubuntu").family(OsFamily.UBUNTU).version("11.04").build())
|
||||
.build();
|
||||
|
||||
@Test
|
||||
public void testNodesParse() throws Exception {
|
||||
InputStream is = getClass().getResourceAsStream("/testImages.yaml");
|
||||
ImageFromYamlStream parser = new ImageFromYamlStream();
|
||||
assertEquals(parser.apply(is).asMap(), ImmutableMap.of(TEST1.getId(), TEST1));
|
||||
is.close();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* 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 static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.ImageBuilder;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* @author Andrea Turli
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ImageFromYamlStringTest {
|
||||
|
||||
public static final Image TEST1 = new ImageBuilder()
|
||||
.id("myTestId")
|
||||
.name("ubuntu-11.04-server-i386")
|
||||
.description("ubuntu 11.04 server (i386)")
|
||||
.operatingSystem(
|
||||
OperatingSystem.builder().description("ubuntu").family(OsFamily.UBUNTU)
|
||||
.version("11.04").build()).build();
|
||||
|
||||
@Test
|
||||
public void testNodesParse() throws Exception {
|
||||
|
||||
final StringBuilder yamlFileLines = new StringBuilder();
|
||||
for (Object line : IOUtils.readLines(new InputStreamReader(getClass().getResourceAsStream("/testImages.yaml")))) {
|
||||
yamlFileLines.append(line).append("\n");
|
||||
}
|
||||
|
||||
ImagesToYamlImagesFromYamlDescriptor parser = new ImagesToYamlImagesFromYamlDescriptor(new Supplier<String>() {
|
||||
|
||||
@Override
|
||||
public String get() {
|
||||
return yamlFileLines.toString();
|
||||
}
|
||||
});
|
||||
assertEquals(Iterables.getFirst(parser.get().keySet(), null), TEST1);
|
||||
}
|
||||
}
|
|
@ -19,15 +19,17 @@
|
|||
|
||||
package org.jclouds.virtualbox.functions.admin;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.jclouds.virtualbox.domain.IsoSpec;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.*;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.jclouds.virtualbox.domain.IsoSpec;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Andrea Turli, Adrian Cole
|
||||
|
|
|
@ -18,17 +18,19 @@
|
|||
*/
|
||||
package org.jclouds.virtualbox.functions.admin;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.createNiceMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.expectLastCall;
|
||||
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.EasyMock.replay;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.virtualbox.domain.*;
|
||||
import org.jclouds.virtualbox.domain.HardDisk;
|
||||
import org.jclouds.virtualbox.domain.StorageController;
|
||||
import org.jclouds.virtualbox.domain.VmSpec;
|
||||
import org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.CleanupMode;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
|
|
|
@ -68,16 +68,14 @@ public class GuestAdditionsInstallerLiveTest extends
|
|||
+ 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(sourceName)).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)
|
||||
|
@ -144,16 +142,4 @@ public class GuestAdditionsInstallerLiveTest extends
|
|||
}
|
||||
}
|
||||
|
||||
private void ensureMachineHasPowerDown(String vmName) {
|
||||
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared,
|
||||
new Function<ISession, Void>() {
|
||||
@Override
|
||||
public Void apply(ISession session) {
|
||||
IProgress powerDownProgress = session.getConsole()
|
||||
.powerDown();
|
||||
powerDownProgress.waitForCompletion(-1);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -23,6 +23,8 @@ import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE
|
|||
import static org.jclouds.virtualbox.predicates.IMachinePredicates.isLinkedClone;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
|
||||
import org.jclouds.virtualbox.domain.CloneSpec;
|
||||
import org.jclouds.virtualbox.domain.HardDisk;
|
||||
|
@ -55,78 +57,67 @@ 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 CloneSpec cloneSpec;
|
||||
private String osTypeId = "";
|
||||
private String ideControllerName = "IDE Controller";
|
||||
private String cloneName;
|
||||
private String vmName;
|
||||
private StorageController masterStorageController;
|
||||
private MasterSpec masterMachineSpec;
|
||||
private NetworkSpec networkSpec;
|
||||
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();
|
||||
HardDisk hardDisk = HardDisk.builder().diskpath(adminDisk(vmName)).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();
|
||||
|
||||
NetworkAdapter networkAdapter = NetworkAdapter.builder()
|
||||
.networkAttachmentType(NetworkAttachmentType.Bridged).build();
|
||||
NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard
|
||||
.builder().addNetworkAdapter(networkAdapter).build();
|
||||
NetworkAdapter networkAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.Bridged)
|
||||
.build();
|
||||
NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(networkAdapter)
|
||||
.build();
|
||||
|
||||
NetworkSpec networkSpec = NetworkSpec.builder()
|
||||
.addNIC(0L, networkInterfaceCard).build();
|
||||
this.networkSpec = NetworkSpec.builder().addNIC(0L, networkInterfaceCard).build();
|
||||
|
||||
VmSpec clonedVmSpec = VmSpec.builder().id(cloneName).name(cloneName)
|
||||
.memoryMB(512).cleanUpMode(CleanupMode.Full)
|
||||
.forceOverwrite(true).build();
|
||||
}
|
||||
|
||||
cloneSpec = CloneSpec.builder().vm(clonedVmSpec).network(networkSpec)
|
||||
.build();
|
||||
}
|
||||
@Test
|
||||
public void testLinkedClone() {
|
||||
|
||||
@Test
|
||||
public void testLinkedClone() {
|
||||
Injector injector = context.utils().injector();
|
||||
IMachine master = injector.getInstance(CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class).apply(
|
||||
masterMachineSpec);
|
||||
|
||||
Injector injector = context.utils().injector();
|
||||
IMachine master = injector.getInstance(
|
||||
CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class).apply(
|
||||
masterMachineSpec);
|
||||
IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(
|
||||
manager, workingDir, cloneSpec, true, machineUtils)
|
||||
.apply(master);
|
||||
VmSpec clonedVmSpec = VmSpec.builder().id(cloneName).name(cloneName).memoryMB(512).cleanUpMode(CleanupMode.Full)
|
||||
.forceOverwrite(true).build();
|
||||
|
||||
assertTrue(isLinkedClone().apply(clone));
|
||||
}
|
||||
this.cloneSpec = CloneSpec.builder().vm(clonedVmSpec).network(networkSpec).master(master).linked(true).build();
|
||||
|
||||
@BeforeMethod
|
||||
@AfterMethod
|
||||
void cleanUpVms() {
|
||||
for (VmSpec spec : ImmutableSet.of(cloneSpec.getVmSpec(),
|
||||
masterMachineSpec.getVmSpec()))
|
||||
this.undoVm(spec);
|
||||
}
|
||||
IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(manager, workingDir, machineUtils)
|
||||
.apply(cloneSpec);
|
||||
|
||||
assertTrue(isLinkedClone().apply(clone));
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
@AfterMethod
|
||||
void cleanUpVms() {
|
||||
Set<VmSpec> specs = cloneSpec != null ? ImmutableSet.of(cloneSpec.getVmSpec(), masterMachineSpec.getVmSpec())
|
||||
: ImmutableSet.of(masterMachineSpec.getVmSpec());
|
||||
for (VmSpec spec : specs)
|
||||
this.undoVm(spec);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,13 +19,14 @@
|
|||
|
||||
package org.jclouds.virtualbox.statements;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.inject.Injector;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
|
||||
|
||||
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* @author Andrea Turli
|
||||
|
|
|
@ -31,9 +31,16 @@
|
|||
<Pattern>%d %-5p [%c] (%t) %m%n</Pattern>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<Pattern>%-4r [%thread] %-5level - %msg%n</Pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root>
|
||||
<level value="warn" />
|
||||
<level value="debug" />
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</root>
|
||||
|
||||
<logger name="org.jclouds">
|
||||
|
|
Loading…
Reference in New Issue