blob: 27fbc46fd3876651471b6a98f86b4e652bafcf9e [file] [log] [blame]
/**
* 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.config;
import java.io.InputStream;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import javax.inject.Singleton;
import org.jclouds.byon.Node;
import org.jclouds.byon.functions.NodeToNodeMetadata;
import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.OsFamily;
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.location.suppliers.OnlyLocationOrFirstZone;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.ssh.SshClient;
import org.jclouds.virtualbox.Preconfiguration;
import org.jclouds.virtualbox.compute.VirtualBoxComputeServiceAdapter;
import org.jclouds.virtualbox.domain.ExecutionType;
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.admin.StartJettyIfNotAlreadyRunning;
import org.jclouds.virtualbox.functions.admin.StartVBoxIfNotAlreadyRunning;
import org.jclouds.virtualbox.predicates.SshResponds;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.LockType;
import org.virtualbox_4_1.MachineState;
import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
/**
* @author Mattias Holmqvist, Andrea Turli
*/
@SuppressWarnings("unchecked")
public class VirtualBoxComputeServiceContextModule extends
ComputeServiceAdapterContextModule<Supplier, Supplier, IMachine, IMachine, Image, Location> {
public VirtualBoxComputeServiceContextModule() {
super(Supplier.class, Supplier.class);
}
@SuppressWarnings( { "unchecked", "rawtypes" })
@Override
protected void configure() {
super.configure();
bind(new TypeLiteral<ComputeServiceAdapter<IMachine, IMachine, Image, Location>>() {
}).to(VirtualBoxComputeServiceAdapter.class);
bind(new TypeLiteral<Function<IMachine, NodeMetadata>>() {
}).to(IMachineToNodeMetadata.class);
bind(new TypeLiteral<Function<Location, Location>>() {
}).to((Class) IdentityFunction.class);
bind(new TypeLiteral<Function<Image, Image>>() {
}).to((Class) IdentityFunction.class);
bind(new TypeLiteral<Function<IMachine, Hardware>>() {
}).to(IMachineToHardware.class);
bind(new TypeLiteral<Function<IMachine, Image>>() {
}).to(IMachineToImage.class);
bind(new TypeLiteral<Supplier<Location>>() {
}).to(OnlyLocationOrFirstZone.class);
// for byon
bind(new TypeLiteral<Function<URI, InputStream>>() {
}).to(SupplyFromProviderURIOrNodesProperty.class);
bind(new TypeLiteral<Function<IMachine, SshClient>>() {
}).to(IMachineToSshClient.class);
bind(ExecutionType.class).toInstance(ExecutionType.GUI);
bind(LockType.class).toInstance(LockType.Write);
}
@Provides
@Singleton
@Preconfiguration
protected Supplier<URI> preconfiguration(javax.inject.Provider<StartJettyIfNotAlreadyRunning> lazyGet) {
return lazyGet.get();
}
@Provides
@Singleton
protected Function<Supplier<NodeMetadata>, VirtualBoxManager> provideVBox(Supplier<NodeMetadata> host) {
return new Function<Supplier<NodeMetadata>, VirtualBoxManager>(){
@Override
public VirtualBoxManager apply(Supplier<NodeMetadata> arg0) {
return VirtualBoxManager.createInstance(arg0.get().getId());
}
};
}
@Provides
@Singleton
protected Supplier defaultClient(Supplier<VirtualBoxManager> in) {
return in;
}
@Provides
@Singleton
protected Supplier<VirtualBoxManager> vbox(javax.inject.Provider<StartVBoxIfNotAlreadyRunning> lazyGet) {
return lazyGet.get();
}
@Provides
@Singleton
protected Predicate<SshClient> sshResponds(SshResponds sshResponds, Timeouts timeouts) {
return new RetryablePredicate<SshClient>(sshResponds, timeouts.nodeRunning);
}
@Override
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
return template.osFamily(OsFamily.UBUNTU).osVersionMatches("11.04");
}
@Provides
@Singleton
protected Supplier<NodeMetadata> host(Supplier<LoadingCache<String, Node>> nodes, NodeToNodeMetadata converter)
throws ExecutionException {
return Suppliers.compose(Functions.compose(converter, new Function<LoadingCache<String, Node>, Node>() {
@Override
public Node apply(LoadingCache<String, Node> arg0) {
return arg0.apply("host");
}
}), nodes);
}
@VisibleForTesting
public static final Map<MachineState, NodeState> machineToNodeState = ImmutableMap
.<MachineState, NodeState> builder().put(MachineState.Running, NodeState.RUNNING).put(
MachineState.PoweredOff, NodeState.SUSPENDED)
.put(MachineState.DeletingSnapshot, NodeState.PENDING).put(MachineState.DeletingSnapshotOnline,
NodeState.PENDING).put(MachineState.DeletingSnapshotPaused, NodeState.PENDING).put(
MachineState.FaultTolerantSyncing, NodeState.PENDING).put(MachineState.LiveSnapshotting,
NodeState.PENDING).put(MachineState.SettingUp, NodeState.PENDING).put(MachineState.Starting,
NodeState.PENDING).put(MachineState.Stopping, NodeState.PENDING).put(MachineState.Restoring,
NodeState.PENDING)
// TODO What to map these states to?
.put(MachineState.FirstOnline, NodeState.PENDING).put(MachineState.FirstTransient, NodeState.PENDING).put(
MachineState.LastOnline, NodeState.PENDING).put(MachineState.LastTransient, NodeState.PENDING)
.put(MachineState.Teleported, NodeState.PENDING).put(MachineState.TeleportingIn, NodeState.PENDING).put(
MachineState.TeleportingPausedVM, NodeState.PENDING)
.put(MachineState.Aborted, NodeState.ERROR).put(MachineState.Stuck, NodeState.ERROR)
.put(MachineState.Null, NodeState.UNRECOGNIZED).build();
}