issue 384: Refactoring of listImages to support yaml idea

This commit is contained in:
andreaturli 2011-10-19 00:12:02 +01:00
parent 32667703ae
commit c5d0543da8
11 changed files with 548 additions and 31 deletions

View File

@ -22,25 +22,21 @@
package org.jclouds.virtualbox.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.filter;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Map;
import javax.annotation.Nullable;
import javax.inject.Inject;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.Template;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.location.suppliers.JustProvider;
import org.jclouds.virtualbox.config.VirtualBoxConstants;
import org.jclouds.virtualbox.functions.IMachineToImage;
import org.jclouds.virtualbox.functions.admin.ImageFromYamlStream;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IProgress;
@ -58,7 +54,7 @@ import com.google.inject.Singleton;
* @author Mattias Holmqvist, Andrea Turli
*/
@Singleton
public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IMachine, IMachine, IMachine, Location> {
public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IMachine, IMachine, Image, Location> {
private final VirtualBoxManager manager;
private final JustProvider justProvider;
@ -85,20 +81,10 @@ public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IM
}
@Override
public Iterable<IMachine> listImages() {
final Predicate<? super IMachine> imagePredicate = new Predicate<IMachine>() {
@Override
public boolean apply(@Nullable IMachine iMachine) {
return iMachine.getName().startsWith(VIRTUALBOX_IMAGE_PREFIX);
}
};
IMachineToImage fn = new IMachineToImage(manager);
for (IMachine imachine : filter(manager.getVBox().getMachines(), imagePredicate)) {
Image image = fn.apply(imachine);
System.out.println(image.getVersion());
}
return filter(manager.getVBox().getMachines(), imagePredicate);
public Iterable<Image> listImages() {
InputStream is = getClass().getResourceAsStream("/testImages.yaml");
ImageFromYamlStream parser = new ImageFromYamlStream();
return parser.apply(is).asMap().values();
}
@SuppressWarnings("unchecked")

View File

@ -59,7 +59,7 @@ import com.google.inject.TypeLiteral;
/**
* @author Mattias Holmqvist, Andrea Turli
*/
public class VirtualBoxComputeServiceContextModule extends ComputeServiceAdapterContextModule<VirtualBoxManager, VirtualBoxManager, IMachine, IMachine, IMachine, Location> {
public class VirtualBoxComputeServiceContextModule extends ComputeServiceAdapterContextModule<VirtualBoxManager, VirtualBoxManager, IMachine, IMachine, Image, Location> {
public VirtualBoxComputeServiceContextModule() {
super(VirtualBoxManager.class, VirtualBoxManager.class);
@ -79,7 +79,7 @@ public class VirtualBoxComputeServiceContextModule extends ComputeServiceAdapter
@Override
protected void configure() {
super.configure();
bind(new TypeLiteral<ComputeServiceAdapter<IMachine, IMachine, IMachine, Location>>() {
bind(new TypeLiteral<ComputeServiceAdapter<IMachine, IMachine, Image, Location>>() {
}).to(VirtualBoxComputeServiceAdapter.class);
bind(new TypeLiteral<Function<IMachine, NodeMetadata>>() {
}).to(IMachineToNodeMetadata.class);
@ -87,8 +87,12 @@ public class VirtualBoxComputeServiceContextModule extends ComputeServiceAdapter
}).to((Class) IdentityFunction.class);
bind(new TypeLiteral<Function<IMachine, Hardware>>() {
}).to(IMachineToHardware.class);
bind(new TypeLiteral<Function<Image, Image>>() {
}).to((Class) IdentityFunction.class);
/*
bind(new TypeLiteral<Function<IMachine, Image>>() {
}).to(IMachineToImage.class);
*/
bind(new TypeLiteral<Supplier<Location>>() {
}).to(OnlyLocationOrFirstZone.class);
}

View File

@ -0,0 +1,160 @@
/**
*
* 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.
*
*
* @author Andrea Turli
*/
package org.jclouds.virtualbox.domain;
import static org.jclouds.virtualbox.functions.IMachineToImage.osFamily;
import java.util.List;
import java.util.Map;
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 com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
* Serializes to the following
*
* <pre>
id: myTestId
name: ubuntu-11.04-server-i386
description: ubuntu 11.04 server (i386)
os_arch: x86
os_family: linux
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
* </pre>
*
* @author Kelvin Kakugawa
* @author Adrian Cole
*/
public class YamlImage {
public String id;
public String name;
public String description;
public String hostname;
public String location_id;
public String os_arch;
public String os_family;
public String os_description;
public String os_version;
public String iso;
public String keystroke_sequence;
public String preseed_cfg;
public int login_port = 22;
public boolean os_64bit;
public String group;
public List<String> tags = Lists.newArrayList();
public Map<String, String> metadata = Maps.newLinkedHashMap();
public String username;
public String credential;
public String credential_url;
public String sudo_password;
public static Function<YamlImage, Image> toImage = new Function<YamlImage, Image>() {
@Override
public Image apply(YamlImage arg0) {
if (arg0 == null)
return null;
OsFamily family = osFamily().apply(arg0.os_family);
OperatingSystem operatingSystem = OperatingSystem.builder()
.description(arg0.os_description)
.family(family)
.version(arg0.os_version)
.is64Bit(arg0.os_64bit)
.build();
return new ImageBuilder().id(arg0.id).name(arg0.name).description(arg0.description).operatingSystem(operatingSystem).build();
}
};
public Image toImage() {
return toImage.apply(this);
}
}

View File

@ -75,7 +75,7 @@ public class IMachineToImage implements Function<IMachine, Image> {
return new Function<String, OsFamily>() {
@Override
public OsFamily apply(String osDescription) {
if (osDescription.startsWith(UBUNTU)) return OsFamily.UBUNTU;
if (osDescription.startsWith("linux")) return OsFamily.LINUX;
return OsFamily.UNRECOGNIZED;
}
};

View File

@ -0,0 +1,95 @@
package org.jclouds.virtualbox.functions.admin;
import static com.google.common.base.Preconditions.checkState;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import javax.inject.Singleton;
import org.jclouds.byon.Node;
import org.jclouds.byon.domain.YamlNode;
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.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
/**
*
* 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.
*
*
* @author Andrea Turli
*/
@Singleton
public class ImageFromYamlStream implements Function<InputStream, Cache<String, Image>> {
/**
* Type-safe config class for YAML
*
*/
public static class Config {
public List<YamlImage> images;
}
private Object construct(String data) {
Yaml yaml = new Yaml();
return yaml.load(data);
}
@Override
public Cache<String, Image> apply(InputStream source) {
Constructor constructor = new Constructor(Config.class);
TypeDescription imageDesc = new TypeDescription(YamlImage.class);
imageDesc.putListPropertyType("images", String.class);
constructor.addTypeDescription(imageDesc);
Yaml yaml = new Yaml(new Loader(constructor));
Config config = (Config) yaml.load(source);
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();
}
});
Cache<String, Image> cache = CacheBuilder.newBuilder().build(CacheLoader.from(Functions.forMap(backingMap)));
for (String node : backingMap.keySet())
cache.getUnchecked(node);
return cache;
}
}

View File

@ -108,11 +108,8 @@ public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClien
}
@Test
public void testListImages() {
IMachineToImage iMachineToImage = new IMachineToImage(getManager());
Iterable<IMachine> iMachineIterable = adapter.listImages();
for (IMachine iMachine : iMachineIterable) {
Image image = iMachineToImage.apply(iMachine);
Iterable<Image> iMageIterable = adapter.listImages();
for (Image image : iMageIterable) {
System.out.println(image);
}
// check state;

View File

@ -0,0 +1,69 @@
package org.jclouds.virtualbox.compute;
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
import static org.testng.Assert.assertEquals;
import java.util.Set;
import org.jclouds.compute.BaseTemplateBuilderLiveTest;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.OsFamilyVersion64Bit;
import org.jclouds.compute.domain.Template;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableSet;
/**
*
* @author Andrea Turli
*/
@Test(groups = "live")
public class VirtualBoxTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
public VirtualBoxTemplateBuilderLiveTest() {
provider = "virtualbox";
}
@Override
protected Predicate<OsFamilyVersion64Bit> defineUnsupportedOperatingSystems() {
return Predicates.not(new Predicate<OsFamilyVersion64Bit>() {
@Override
public boolean apply(OsFamilyVersion64Bit input) {
switch (input.family) {
case UBUNTU:
return !(input.version.startsWith("11") || input.version.equals("8.04")) && input.is64Bit;
case DEBIAN:
return !(input.version.equals("6.0")) && input.is64Bit;
case CENTOS:
return !(input.version.matches("5.[023]") || input.version.equals("8.04")) && input.is64Bit;
case WINDOWS:
return input.version.equals("2008 SP2") || input.version.equals("")
|| (input.version.equals("2008 R2") && input.is64Bit);
default:
return false;
}
}
});
}
@Test
public void testTemplateBuilder() {
Template defaultTemplate = this.context.getComputeService().templateBuilder().build();
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04");
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
}
@Override
protected Set<String> getIso3166Codes() {
return ImmutableSet.<String> of();
}
}

View File

@ -0,0 +1,84 @@
/**
* 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.experiment;
import java.util.Map;
import org.jclouds.scriptbuilder.statements.login.AdminAccess.Configuration;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
/**
*
* @author Adrian Cole
*
*/
public enum TestConfiguration implements Configuration {
INSTANCE;
int pwCount = 0;
public TestConfiguration reset() {
pwCount = 0;
return this;
}
private final Supplier<String> defaultAdminUsername = Suppliers.ofInstance("defaultAdminUsername");
private final Supplier<Map<String, String>> defaultAdminSshKeys = Suppliers
.<Map<String, String>> ofInstance(ImmutableMap.of("public", "publicKey", "private", "privateKey"));
private final Supplier<String> passwordGenerator = new Supplier<String>() {
@Override
public String get() {
return pwCount++ + "";
}
};
private final Function<String, String> cryptFunction = new Function<String, String>() {
@Override
public String apply(String input) {
return String.format("crypt(%s)", input);
}
};
@Override
public Supplier<String> defaultAdminUsername() {
return defaultAdminUsername;
}
@Override
public Supplier<Map<String, String>> defaultAdminSshKeys() {
return defaultAdminSshKeys;
}
@Override
public Supplier<String> passwordGenerator() {
return passwordGenerator;
}
@Override
public Function<String, String> cryptFunction() {
return cryptFunction;
}
}

View File

@ -0,0 +1,60 @@
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.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
/**
*
* 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.
*
*
* @author Andrea Turli
*/
public class ImageFromYamlStreamTest extends BaseVirtualBoxClientLiveTest {
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.LINUX)
.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();
}
}

View File

@ -0,0 +1,57 @@
/*
* *
* * 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;
/**
* @author Andrea Turli
*/
import static org.testng.Assert.assertEquals;
import org.eclipse.jetty.server.Server;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.testng.annotations.Test;
@Test(groups = "live", singleThreaded = true, testName = "StartJettyIfNotAlreadyRunningLiveTest")
public class StartJettyIfNotAlreadyRunningLiveTest extends BaseVirtualBoxClientLiveTest {
private String basebaseResource = ".";
private String port = "8080";
@Test
public void testLaunchJettyServer() throws Exception {
Server server = new StartJettyIfNotAlreadyRunning(port).apply(basebaseResource);
server.stop();
assertEquals(server.getState(), server.STOPPED);
}
@Test
public void testLaunchingSameJettyServer() throws Exception {
Server server = new StartJettyIfNotAlreadyRunning(port).apply(basebaseResource);
assertEquals(server.getState(), server.STARTED);
Server sameServer = new StartJettyIfNotAlreadyRunning(port).apply(basebaseResource);
sameServer.stop();
}
}

View File

@ -1,6 +1,11 @@
images:
- name: ubuntu-11.04-server-i386
- id: myTestId
name: ubuntu-11.04-server-i386
description: ubuntu 11.04 server (i386)
os_arch: x86
os_family: linux
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>