mirror of https://github.com/apache/jclouds.git
Merge pull request #713 from magnayn/master
Initial implementation of SmartOS-SSH
This commit is contained in:
commit
6264dee999
|
@ -55,5 +55,6 @@
|
||||||
<module>nodepool</module>
|
<module>nodepool</module>
|
||||||
<module>rds</module>
|
<module>rds</module>
|
||||||
<module>aws-rds</module>
|
<module>aws-rds</module>
|
||||||
|
<module>smartos-ssh</module>
|
||||||
</modules>
|
</modules>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
This is designed for interacting with a Joyent SmartOS host, in order to be able to leverage
|
||||||
|
the lightweight VM support (nee Solaris Zones).
|
||||||
|
|
||||||
|
It is planned to support KVM VMs in the future.
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
|
#Setup
|
||||||
|
|
||||||
|
Have a SmartOS installation, that you know either the root password for, or a secondary account with sufficient
|
||||||
|
permissions to be able to run the vm tools (vmadm, dsadm).
|
||||||
|
|
||||||
|
That's it!
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
|
#Notes:
|
||||||
|
|
||||||
|
- This is a work in progress, so please report any bugs that you find.
|
|
@ -0,0 +1,121 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<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>
|
||||||
|
<artifactId>jclouds-project</artifactId>
|
||||||
|
<version>1.5.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../../project/pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<groupId>org.jclouds.labs</groupId>
|
||||||
|
<artifactId>smartos-ssh</artifactId>
|
||||||
|
<name>smartos ssh api</name>
|
||||||
|
<description>jclouds components to access SmartOS over SSH</description>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<test.smartos-ssh.endpoint>https://api.joyentcloud.com</test.smartos-ssh.endpoint>
|
||||||
|
<test.smartos-ssh.api-version>~6.5</test.smartos-ssh.api-version>
|
||||||
|
<test.smartos-ssh.build-version></test.smartos-ssh.build-version>
|
||||||
|
<test.smartos-ssh.identity>FIXME_IDENTITY</test.smartos-ssh.identity>
|
||||||
|
<test.smartos-ssh.credential>FIXME_CREDENTIALS</test.smartos-ssh.credential>
|
||||||
|
<jclouds.osgi.export>org.jclouds.joyent.cloudapi.v6_5*;version="${project.version}"</jclouds.osgi.export>
|
||||||
|
<jclouds.osgi.import>
|
||||||
|
org.jclouds.rest.internal;version="${project.version}",
|
||||||
|
org.jclouds*;version="${project.version}",
|
||||||
|
*
|
||||||
|
</jclouds.osgi.import>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jclouds</groupId>
|
||||||
|
<artifactId>jclouds-compute</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jclouds</groupId>
|
||||||
|
<artifactId>jclouds-compute</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>test-jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jclouds</groupId>
|
||||||
|
<artifactId>jclouds-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>test-jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jclouds.driver</groupId>
|
||||||
|
<artifactId>jclouds-slf4j</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jclouds.driver</groupId>
|
||||||
|
<artifactId>jclouds-sshj</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>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>live</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>integration</id>
|
||||||
|
<phase>integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<test.smartos-ssh.endpoint>${test.smartos-ssh.endpoint}</test.smartos-ssh.endpoint>
|
||||||
|
<test.smartos-ssh.api-version>${test.smartos-ssh.api-version}</test.smartos-ssh.api-version>
|
||||||
|
<test.smartos-ssh.build-version>${test.smartos-ssh.build-version}</test.smartos-ssh.build-version>
|
||||||
|
<test.smartos-ssh.identity>${test.smartos-ssh.identity}</test.smartos-ssh.identity>
|
||||||
|
<test.smartos-ssh.credential>${test.smartos-ssh.credential}</test.smartos-ssh.credential>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,57 @@
|
||||||
|
package org.jclouds.smartos;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.jclouds.apis.ApiMetadata;
|
||||||
|
import org.jclouds.apis.internal.BaseApiMetadata;
|
||||||
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
import org.jclouds.smartos.compute.config.SmartOSComputeServiceContextModule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link ApiMetadata} for SmartOS
|
||||||
|
*
|
||||||
|
* @author Nigel Magnay
|
||||||
|
*/
|
||||||
|
public class SmartOSApiMetadata extends BaseApiMetadata {
|
||||||
|
|
||||||
|
/** The serialVersionUID */
|
||||||
|
private static final long serialVersionUID = 3606170564482119304L;
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return Builder.class.cast(builder().fromApiMetadata(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public SmartOSApiMetadata() {
|
||||||
|
super(builder());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SmartOSApiMetadata(Builder builder) {
|
||||||
|
super(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder extends BaseApiMetadata.Builder {
|
||||||
|
|
||||||
|
protected Builder(){
|
||||||
|
id("smartos-ssh")
|
||||||
|
.name("SmartOS SSH API")
|
||||||
|
.identityName("Username")
|
||||||
|
.defaultIdentity("root")
|
||||||
|
.defaultCredential("smartos")
|
||||||
|
.defaultEndpoint("http://localhost")
|
||||||
|
.documentation(URI.create("http://http://wiki.smartos.org/display/DOC/How+to+create+a+Virtual+Machine+in+SmartOS"))
|
||||||
|
.view(ComputeServiceContext.class)
|
||||||
|
.defaultModule(SmartOSComputeServiceContextModule.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SmartOSApiMetadata build() {
|
||||||
|
return new SmartOSApiMetadata(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* 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.smartos.compute.config;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
import org.jclouds.smartos.compute.domain.DataSet;
|
||||||
|
import org.jclouds.smartos.compute.domain.SmartOSHost;
|
||||||
|
import org.jclouds.smartos.compute.domain.VM;
|
||||||
|
import org.jclouds.smartos.compute.domain.VmSpecification;
|
||||||
|
import org.jclouds.compute.ComputeServiceAdapter;
|
||||||
|
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.domain.Location;
|
||||||
|
|
||||||
|
import org.jclouds.smartos.compute.functions.DataSetToImage;
|
||||||
|
import org.jclouds.smartos.compute.functions.DatacenterToLocation;
|
||||||
|
import org.jclouds.smartos.compute.functions.VMToNodeMetadata;
|
||||||
|
import org.jclouds.smartos.compute.functions.VmSpecificationToHardware;
|
||||||
|
import org.jclouds.smartos.compute.strategy.SmartOSComputeServiceAdapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Nigel Magnay
|
||||||
|
*/
|
||||||
|
public class SmartOSComputeServiceContextModule extends
|
||||||
|
ComputeServiceAdapterContextModule<VM, VmSpecification, DataSet, SmartOSHost> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
super.configure();
|
||||||
|
bind(new TypeLiteral<ComputeServiceAdapter<VM, VmSpecification, DataSet, SmartOSHost>>() {
|
||||||
|
}).to(SmartOSComputeServiceAdapter.class);
|
||||||
|
bind(new TypeLiteral<Function<VM, NodeMetadata>>() {
|
||||||
|
}).to(VMToNodeMetadata.class);
|
||||||
|
bind(new TypeLiteral<Function<DataSet, org.jclouds.compute.domain.Image>>() {
|
||||||
|
}).to(DataSetToImage.class);
|
||||||
|
bind(new TypeLiteral<Function<VmSpecification, org.jclouds.compute.domain.Hardware>>() {
|
||||||
|
}).to(VmSpecificationToHardware.class);
|
||||||
|
bind(new TypeLiteral<Function<SmartOSHost, Location>>() {
|
||||||
|
}).to(DatacenterToLocation.class);
|
||||||
|
// to have the compute service adapter override default locations
|
||||||
|
//install(new LocationsFromComputeServiceAdapterModule<VM, VmSpecification, DataSet, SmartOSHost>(){});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
package org.jclouds.smartos.compute.domain;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dataset is a pre-built image ready to be cloned.
|
||||||
|
*/
|
||||||
|
public class DataSet {
|
||||||
|
private final UUID uuid;
|
||||||
|
private final String os;
|
||||||
|
private final String published;
|
||||||
|
private final String urn;
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return builder().fromDataSet(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
public UUID uuid;
|
||||||
|
public String os;
|
||||||
|
public String published;
|
||||||
|
public String urn;
|
||||||
|
|
||||||
|
public Builder uuid(UUID uuid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder uuid(String uuid) {
|
||||||
|
this.uuid = UUID.fromString(uuid);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder os(String os) {
|
||||||
|
this.os = os;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder published(String published) {
|
||||||
|
this.published = published;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder urn(String urn) {
|
||||||
|
this.urn = urn;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder fromDsadmString(String string) {
|
||||||
|
String [] sections = string.split(" ");
|
||||||
|
|
||||||
|
uuid ( sections[0] );
|
||||||
|
os ( sections[1] );
|
||||||
|
published ( sections[2] );
|
||||||
|
urn ( sections[3] );
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public DataSet build() {
|
||||||
|
return new DataSet(uuid, os, published, urn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder fromDataSet(DataSet in) {
|
||||||
|
return uuid(in.getUuid())
|
||||||
|
.os(in.getOs())
|
||||||
|
.published(in.getPublished())
|
||||||
|
.urn(in.getUrn());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected DataSet(UUID uuid, String os, String published, String urn) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.os = os;
|
||||||
|
this.published = published;
|
||||||
|
this.urn = urn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getUuid() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOs() {
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPublished() {
|
||||||
|
return published;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrn() {
|
||||||
|
return urn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
// UUID is primary key
|
||||||
|
return uuid.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
return uuid.equals(((DataSet)obj).uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Objects.toStringHelper(this).omitNullValues()
|
||||||
|
.add("uuid", uuid)
|
||||||
|
.add("os", os)
|
||||||
|
.add("published", published)
|
||||||
|
.add("urn", urn).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,296 @@
|
||||||
|
package org.jclouds.smartos.compute.domain;
|
||||||
|
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.net.HostAndPort;
|
||||||
|
import org.jclouds.domain.LoginCredentials;
|
||||||
|
import org.jclouds.location.Provider;
|
||||||
|
import org.jclouds.rest.annotations.Credential;
|
||||||
|
import org.jclouds.rest.annotations.Identity;
|
||||||
|
import org.jclouds.ssh.SshClient;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A host machine that runs smartOS
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class SmartOSHost {
|
||||||
|
protected final String hostname;
|
||||||
|
protected final String username;
|
||||||
|
protected final String password;
|
||||||
|
|
||||||
|
protected SshClient.Factory sshClientFactory;
|
||||||
|
|
||||||
|
private SshClient _connection;
|
||||||
|
|
||||||
|
public static class HostException extends RuntimeException {
|
||||||
|
public HostException(String s, Throwable throwable) {
|
||||||
|
super(s, throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HostException(String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class NoResponseException extends Exception {
|
||||||
|
public NoResponseException() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return builder().fromSmartOSHost(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
protected String hostname;
|
||||||
|
protected String username;
|
||||||
|
protected String password;
|
||||||
|
protected SshClient.Factory sshFactory;
|
||||||
|
|
||||||
|
public Builder hostname(String hostname) {
|
||||||
|
this.hostname = hostname;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder username(String username) {
|
||||||
|
this.username = username;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder password(String password) {
|
||||||
|
this.password = password;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder sshFactory(SshClient.Factory sshFactory) {
|
||||||
|
this.sshFactory = sshFactory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SmartOSHost build() {
|
||||||
|
return new SmartOSHost(hostname, username, password, sshFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder fromSmartOSHost(SmartOSHost in) {
|
||||||
|
return this.hostname ( in.getHostname() )
|
||||||
|
.username ( in.getHostname() )
|
||||||
|
.password ( in.getPassword() )
|
||||||
|
.sshFactory( in.getSshClientFactory() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected SmartOSHost(@Provider Supplier<URI> provider,
|
||||||
|
@Nullable @Identity String identity,
|
||||||
|
@Nullable @Credential String credential,
|
||||||
|
SshClient.Factory sshFactory) {
|
||||||
|
|
||||||
|
this.hostname = provider.get().getHost();
|
||||||
|
this.username = identity;
|
||||||
|
this.password = credential;
|
||||||
|
this.sshClientFactory = sshFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SmartOSHost(String hostname, String username, String password, SshClient.Factory sshClientFactory) {
|
||||||
|
this.hostname = hostname;
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
|
this.sshClientFactory = sshClientFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return "SmartOS@" + hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHostname() {
|
||||||
|
return hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SshClient.Factory getSshClientFactory() {
|
||||||
|
return sshClientFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SshClient getConnection() {
|
||||||
|
if (_connection == null) {
|
||||||
|
|
||||||
|
LoginCredentials credentials = new LoginCredentials.Builder()
|
||||||
|
.user(username)
|
||||||
|
.password(password)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
_connection = getSshClientFactory().create(
|
||||||
|
HostAndPort.fromParts(hostname, 22),
|
||||||
|
credentials
|
||||||
|
);
|
||||||
|
|
||||||
|
_connection.connect();
|
||||||
|
|
||||||
|
}
|
||||||
|
return _connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String exec(String cmd) {
|
||||||
|
return getConnection().exec(cmd).getOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String vmList() {
|
||||||
|
return exec("vmadm list -p");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Map<String, String> getVMIpAddresses(UUID vmId)
|
||||||
|
{
|
||||||
|
ImmutableMap.Builder<String, String> netMapBuilder = ImmutableMap.builder();
|
||||||
|
|
||||||
|
String response = getConnection().exec("zlogin " + vmId.toString() + " ifconfig -a4").getOutput();
|
||||||
|
|
||||||
|
if( response.length() == 0)
|
||||||
|
return ImmutableMap.of();
|
||||||
|
|
||||||
|
Iterable<String> strings = Splitter.on("\n").split(response);
|
||||||
|
Pattern inetMatcher = Pattern.compile("inet [0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}");
|
||||||
|
|
||||||
|
String iface = "";
|
||||||
|
for(String line : strings )
|
||||||
|
{
|
||||||
|
if( line.length() > 0 && Character.isLetterOrDigit(line.charAt(0)) )
|
||||||
|
{
|
||||||
|
iface = line.substring(0, line.indexOf(":") );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Matcher matcher = inetMatcher.matcher(line);
|
||||||
|
if( matcher.find() )
|
||||||
|
netMapBuilder.put(iface, matcher.group().substring(5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return netMapBuilder.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* What remotely available images are there in the cloud?
|
||||||
|
*
|
||||||
|
* @return Collection of datasets
|
||||||
|
*/
|
||||||
|
public Iterable<DataSet> getAvailableImages() {
|
||||||
|
return toSpecList(exec("dsadm avail"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterable<DataSet> getLocalDatasets() {
|
||||||
|
return toSpecList(exec("dsadm list"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterable<VM> getVMs() {
|
||||||
|
return toVMList(exec("vmadm list -p"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public VM createVM(VmSpecification specification) {
|
||||||
|
|
||||||
|
String response = getConnection().exec("(cat <<END\n" +
|
||||||
|
specification.toJSONSpecification() + "\nEND\n) | vmadm create").getOutput();
|
||||||
|
|
||||||
|
Pattern uuidPattern = Pattern.compile("[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}");
|
||||||
|
Matcher matcher = uuidPattern.matcher(response);
|
||||||
|
if (matcher.find()) {
|
||||||
|
String uuid = matcher.group();
|
||||||
|
return getVM( UUID.fromString(uuid) );
|
||||||
|
} else {
|
||||||
|
throw new HostException("Error creating Host: response = " + response + "\n source = " + specification.toJSONSpecification());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Iterable<DataSet> toSpecList(String string) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
BufferedReader r = new BufferedReader(new StringReader(string));
|
||||||
|
r.readLine(); // Skip
|
||||||
|
String line;
|
||||||
|
ImmutableList.Builder resultBuilder = ImmutableList.builder();
|
||||||
|
while ((line = r.readLine()) != null) {
|
||||||
|
DataSet dataset = DataSet.builder().fromDsadmString(line).build();
|
||||||
|
|
||||||
|
resultBuilder.add(dataset);
|
||||||
|
}
|
||||||
|
return resultBuilder.build();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new HostException("Error parsing response when building spec list", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Iterable<VM> toVMList(String string) {
|
||||||
|
try {
|
||||||
|
BufferedReader r = new BufferedReader(new StringReader(string));
|
||||||
|
String line;
|
||||||
|
ImmutableList.Builder resultBuilder = ImmutableList.builder();
|
||||||
|
while ((line = r.readLine()) != null) {
|
||||||
|
VM vm = VM.builder().host(this).fromVmadmString(line).build();
|
||||||
|
|
||||||
|
resultBuilder.add(vm);
|
||||||
|
}
|
||||||
|
return resultBuilder.build();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new HostException("Error parsing response when building VM list", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public VM getVM(UUID serverId) {
|
||||||
|
for (VM vm : getVMs())
|
||||||
|
if (vm.uuid.equals(serverId))
|
||||||
|
return vm;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataSet getDataSet(UUID imageId) {
|
||||||
|
for (DataSet ds : getLocalDatasets()) {
|
||||||
|
if (ds.getUuid().equals(imageId))
|
||||||
|
return ds;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroyHost(UUID uuid) {
|
||||||
|
exec("vmadm delete " + uuid.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rebootHost(UUID uuid) {
|
||||||
|
exec("vmadm reboot " + uuid.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopHost(UUID uuid) {
|
||||||
|
exec("vmadm stop -p");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startHost(UUID uuid) {
|
||||||
|
exec("vmadm start " + uuid.toString());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,222 @@
|
||||||
|
package org.jclouds.smartos.compute.domain;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Representing a Virtual Machine (Zone / KVM )
|
||||||
|
**/
|
||||||
|
public class VM {
|
||||||
|
|
||||||
|
public enum State
|
||||||
|
{
|
||||||
|
RUNNING,
|
||||||
|
STOPPED,
|
||||||
|
INCOMPLETE
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return builder().fromVM(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
protected SmartOSHost host;
|
||||||
|
protected UUID uuid;
|
||||||
|
protected String type;
|
||||||
|
protected String ram;
|
||||||
|
protected State state = State.STOPPED;
|
||||||
|
protected String alias;
|
||||||
|
|
||||||
|
public Builder uuid(UUID uuid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder uuid(String uuid) {
|
||||||
|
this.uuid = UUID.fromString(uuid);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder host(SmartOSHost host) {
|
||||||
|
this.host = host;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder type(String type) {
|
||||||
|
this.type = type;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder ram(String ram) {
|
||||||
|
this.ram = ram;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder state(String state) {
|
||||||
|
this.state = State.valueOf(state.toUpperCase());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder state(State state) {
|
||||||
|
this.state = state;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder alias(String alias) {
|
||||||
|
this.alias = alias;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder fromVmadmString(String string) {
|
||||||
|
String[] sections = string.split(":");
|
||||||
|
|
||||||
|
uuid(sections[0]);
|
||||||
|
|
||||||
|
type(sections[1]);
|
||||||
|
ram(sections[2]);
|
||||||
|
state(sections[3]);
|
||||||
|
|
||||||
|
if (sections.length > 4)
|
||||||
|
alias(sections[4]);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public VM build() {
|
||||||
|
return new VM(host,uuid,type,ram,state,alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder fromVM(VM in) {
|
||||||
|
return host(in.getHost())
|
||||||
|
.uuid(in.getUuid())
|
||||||
|
.type(in.getType())
|
||||||
|
.ram(in.getRam())
|
||||||
|
.state(in.getState())
|
||||||
|
.alias(in.getAlias());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected SmartOSHost host;
|
||||||
|
protected final UUID uuid;
|
||||||
|
protected String type;
|
||||||
|
protected String ram;
|
||||||
|
protected State state;
|
||||||
|
protected String alias;
|
||||||
|
|
||||||
|
|
||||||
|
public VM(SmartOSHost host, UUID uuid, String type, String ram, State state, String alias) {
|
||||||
|
this.host = host;
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.type = type;
|
||||||
|
this.ram = ram;
|
||||||
|
this.state = state;
|
||||||
|
this.alias = alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public State getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
host.destroyHost(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reboot() {
|
||||||
|
host.rebootHost(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
host.stopHost(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
host.startHost(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<String> getPublicAddress() throws InterruptedException {
|
||||||
|
Map<String, String> ipAddresses;
|
||||||
|
|
||||||
|
for( int i=0; i<30; i++ )
|
||||||
|
{
|
||||||
|
ipAddresses = host.getVMIpAddresses(uuid);
|
||||||
|
if( ipAddresses.isEmpty() )
|
||||||
|
{
|
||||||
|
// Got some
|
||||||
|
String ip = ipAddresses.get("net0");
|
||||||
|
if( ip != null && !ip.equals("0.0.0.0"))
|
||||||
|
return Optional.of(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.sleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.absent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SmartOSHost getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getUuid() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRam() {
|
||||||
|
return ram;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlias() {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
// UUID is primary key
|
||||||
|
return uuid.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
return uuid.equals(((DataSet)obj).getUuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Objects.toStringHelper(this).omitNullValues()
|
||||||
|
.add("uuid", uuid)
|
||||||
|
.add("type", type)
|
||||||
|
.add("ram", ram)
|
||||||
|
.add("alias", alias).toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
package org.jclouds.smartos.compute.domain;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specification of a network card.
|
||||||
|
*/
|
||||||
|
public class VmNIC {
|
||||||
|
|
||||||
|
@SerializedName("nic_tag")
|
||||||
|
protected final String tag;
|
||||||
|
protected final String ip;
|
||||||
|
protected final String netmask;
|
||||||
|
protected final String gateway;
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return builder().fromVmNIC(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
public String tag = "admin";
|
||||||
|
public String ip;
|
||||||
|
public String netmask;
|
||||||
|
public String gateway;
|
||||||
|
|
||||||
|
|
||||||
|
public Builder simpleDCHPNic() {
|
||||||
|
tag = "admin";
|
||||||
|
ip = "dhcp";
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder tag(String tag) {
|
||||||
|
this.tag = tag;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder ip(String ip) {
|
||||||
|
this.ip = ip;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder netmask(String netmask) {
|
||||||
|
this.netmask = netmask;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder gateway(String gateway) {
|
||||||
|
this.gateway = gateway;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VmNIC build() {
|
||||||
|
return new VmNIC(tag,ip,netmask,gateway);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder fromVmNIC(VmNIC in) {
|
||||||
|
return tag ( in.getTag())
|
||||||
|
.ip ( in.getIp() )
|
||||||
|
.netmask( in.getNetmask() )
|
||||||
|
.gateway( in.getGateway() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public VmNIC(String tag, String ip, String netmask, String gateway) {
|
||||||
|
this.tag = tag;
|
||||||
|
this.ip = ip;
|
||||||
|
this.netmask = netmask;
|
||||||
|
this.gateway = gateway;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIp() {
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNetmask() {
|
||||||
|
return netmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGateway() {
|
||||||
|
return gateway;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Objects.toStringHelper(this).omitNullValues()
|
||||||
|
.add("tag", tag)
|
||||||
|
.add("ip", ip)
|
||||||
|
.add("netmask", netmask)
|
||||||
|
.add("gateway", gateway).toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
package org.jclouds.smartos.compute.domain;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.gson.*;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specification of a VM to build, based on a dataset.
|
||||||
|
*/
|
||||||
|
public class VmSpecification {
|
||||||
|
protected final String alias;
|
||||||
|
protected final String brand;
|
||||||
|
|
||||||
|
@SerializedName("dataset_uuid")
|
||||||
|
protected final DataSet dataset;
|
||||||
|
protected final String dnsDomain;
|
||||||
|
protected final String quota;
|
||||||
|
|
||||||
|
protected final List<VmNIC> nics;
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return builder().fromVmSpecification(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
protected String alias;
|
||||||
|
protected String brand = "joyent";
|
||||||
|
protected DataSet dataset;
|
||||||
|
protected String dnsDomain = "local";
|
||||||
|
protected String quota = "10";
|
||||||
|
|
||||||
|
protected List<VmNIC> nics = new ArrayList<VmNIC>();
|
||||||
|
|
||||||
|
public Builder alias(String alias) {
|
||||||
|
this.alias = alias;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder brand(String brand) {
|
||||||
|
this.brand = brand;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder dataset(DataSet dataset) {
|
||||||
|
this.dataset = dataset;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder dnsDomain(String dnsDomain) {
|
||||||
|
this.dnsDomain = dnsDomain;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder quota(String quota) {
|
||||||
|
this.quota = quota;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder nics(Collection<VmNIC> nic) {
|
||||||
|
this.nics.addAll(nics);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder nic(VmNIC nic) {
|
||||||
|
this.nics.add(nic);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VmSpecification build() {
|
||||||
|
return new VmSpecification(alias, brand, dataset, dnsDomain, quota, nics);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder fromVmSpecification(VmSpecification in) {
|
||||||
|
return alias (in.getAlias())
|
||||||
|
.brand (in.getBrand())
|
||||||
|
.dataset (in.getDataset())
|
||||||
|
.dnsDomain(in.getDnsDomain())
|
||||||
|
.quota (in.getQuota())
|
||||||
|
.nics(in.getNics());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected VmSpecification(String alias, String brand, DataSet dataset, String dnsDomain, String quota, List<VmNIC> nics) {
|
||||||
|
this.alias = alias;
|
||||||
|
this.brand = brand;
|
||||||
|
this.dataset = dataset;
|
||||||
|
this.dnsDomain = dnsDomain;
|
||||||
|
this.quota = quota;
|
||||||
|
this.nics = nics;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlias() {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBrand() {
|
||||||
|
return brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataSet getDataset() {
|
||||||
|
return dataset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDnsDomain() {
|
||||||
|
return dnsDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQuota() {
|
||||||
|
return quota;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<VmNIC> getNics() {
|
||||||
|
return ImmutableList.copyOf(nics);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toJSONSpecification() {
|
||||||
|
GsonBuilder gson = new GsonBuilder();
|
||||||
|
gson.registerTypeAdapter(DataSet.class, new FlattenDataset() );
|
||||||
|
Gson g = gson.create();
|
||||||
|
|
||||||
|
return g.toJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FlattenDataset implements JsonSerializer<DataSet>
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(DataSet vmSpecification, Type type, JsonSerializationContext jsonSerializationContext) {
|
||||||
|
return new JsonPrimitive(dataset.getUuid().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* 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.smartos.compute.functions;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.smartos.compute.domain.DataSet;
|
||||||
|
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.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nigel Magnay
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class DataSetToImage implements Function<DataSet, Image> {
|
||||||
|
@Resource
|
||||||
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Image apply(DataSet from) {
|
||||||
|
|
||||||
|
ImageBuilder builder = new ImageBuilder();
|
||||||
|
builder.ids(from.getUuid() + "");
|
||||||
|
builder.name(from.getUrn());
|
||||||
|
builder.description(from.getUrn());
|
||||||
|
builder.status(Image.Status.AVAILABLE);
|
||||||
|
|
||||||
|
OsFamily family;
|
||||||
|
try {
|
||||||
|
family = OsFamily.SOLARIS;
|
||||||
|
builder.operatingSystem(new OperatingSystem.Builder().name(from.getUrn()).description(from.getUrn()).family(family).build());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
logger.debug("<< didn't match os(%s)", from);
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/**
|
||||||
|
* 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.smartos.compute.functions;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import org.jclouds.smartos.compute.domain.SmartOSHost;
|
||||||
|
import org.jclouds.domain.Location;
|
||||||
|
import org.jclouds.domain.LocationBuilder;
|
||||||
|
import org.jclouds.domain.LocationScope;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Provider;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nigel Magnay
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class DatacenterToLocation implements Function<SmartOSHost, Location> {
|
||||||
|
private final Provider<Supplier<Location>> provider;
|
||||||
|
|
||||||
|
// allow us to lazy discover the provider of a resource
|
||||||
|
@Inject
|
||||||
|
public DatacenterToLocation(Provider<Supplier<Location>> provider) {
|
||||||
|
this.provider = checkNotNull(provider, "provider");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Location apply(SmartOSHost from) {
|
||||||
|
return new LocationBuilder().scope(LocationScope.ZONE).id(from.getHostname() + "").description(from.getDescription()).parent(
|
||||||
|
provider.get().get()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
/**
|
||||||
|
* 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.smartos.compute.functions;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.sun.corba.se.spi.activation.Server;
|
||||||
|
import org.jclouds.smartos.compute.domain.VM;
|
||||||
|
import org.jclouds.collect.FindResourceInSet;
|
||||||
|
import org.jclouds.collect.Memoized;
|
||||||
|
import org.jclouds.compute.domain.*;
|
||||||
|
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||||
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.domain.Location;
|
||||||
|
import org.jclouds.domain.LoginCredentials;
|
||||||
|
import org.omg.PortableInterceptor.ACTIVE;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nigel Magnay
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class VMToNodeMetadata implements Function<VM, NodeMetadata> {
|
||||||
|
|
||||||
|
public static final Map<VM.State, NodeMetadata.Status> serverStatusToNodeStatus = ImmutableMap
|
||||||
|
.<VM.State, NodeMetadata.Status> builder()
|
||||||
|
.put(VM.State.RUNNING, NodeMetadata.Status.RUNNING)//
|
||||||
|
.put(VM.State.STOPPED, NodeMetadata.Status.SUSPENDED)//
|
||||||
|
.put(VM.State.INCOMPLETE, NodeMetadata.Status.PENDING)//
|
||||||
|
.build();
|
||||||
|
|
||||||
|
private final FindHardwareForServer findHardwareForServer;
|
||||||
|
private final FindLocationForServer findLocationForServer;
|
||||||
|
private final FindImageForServer findImageForServer;
|
||||||
|
private final Map<String, Credentials> credentialStore;
|
||||||
|
private final GroupNamingConvention nodeNamingConvention;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
VMToNodeMetadata(Map<String, Credentials> credentialStore, FindHardwareForServer findHardwareForServer,
|
||||||
|
FindLocationForServer findLocationForServer, FindImageForServer findImageForServer,
|
||||||
|
GroupNamingConvention.Factory namingConvention) {
|
||||||
|
this.nodeNamingConvention = checkNotNull(namingConvention, "namingConvention").createWithoutPrefix();
|
||||||
|
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
||||||
|
this.findHardwareForServer = checkNotNull(findHardwareForServer, "findHardwareForServer");
|
||||||
|
this.findLocationForServer = checkNotNull(findLocationForServer, "findLocationForServer");
|
||||||
|
this.findImageForServer = checkNotNull(findImageForServer, "findImageForServer");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeMetadata apply(VM from) {
|
||||||
|
// convert the result object to a jclouds NodeMetadata
|
||||||
|
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
||||||
|
builder.ids(from.getUuid() + "");
|
||||||
|
builder.name(from.getAlias());
|
||||||
|
builder.location(findLocationForServer.apply(from));
|
||||||
|
builder.group(nodeNamingConvention.groupInUniqueNameOrNull(from.getType()));
|
||||||
|
builder.imageId(from.getType() + "");
|
||||||
|
Image image = findImageForServer.apply(from);
|
||||||
|
if (image != null)
|
||||||
|
builder.operatingSystem(image.getOperatingSystem());
|
||||||
|
builder.hardware(findHardwareForServer.apply(from));
|
||||||
|
builder.status(serverStatusToNodeStatus.get(from.getState()));
|
||||||
|
try {
|
||||||
|
if( from.getState() == VM.State.RUNNING )
|
||||||
|
{
|
||||||
|
Optional<String> ip = from.getPublicAddress();
|
||||||
|
if( ip.isPresent() ) {
|
||||||
|
builder.publicAddresses(ImmutableSet.<String> of(ip.get()));
|
||||||
|
builder.privateAddresses(ImmutableSet.<String> of(ip.get()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
// None?
|
||||||
|
}
|
||||||
|
//builder.privateAddresses(ImmutableSet.<String> of(from.privateAddress));
|
||||||
|
builder.credentials(LoginCredentials.fromCredentials(credentialStore.get(from.getUuid() + "")));
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class FindHardwareForServer extends FindResourceInSet<VM, Hardware> {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public FindHardwareForServer(@Memoized Supplier<Set<? extends Hardware>> hardware) {
|
||||||
|
super(hardware);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(VM from, Hardware input) {
|
||||||
|
return input.getProviderId().equals(from.getUuid() + "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class FindImageForServer extends FindResourceInSet<VM, Image> {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public FindImageForServer(@Memoized Supplier<Set<? extends Image>> hardware) {
|
||||||
|
super(hardware);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(VM from, Image input) {
|
||||||
|
return input.getProviderId().equals(from.getUuid() + "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class FindLocationForServer extends FindResourceInSet<VM, Location> {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public FindLocationForServer(@Memoized Supplier<Set<? extends Location>> hardware) {
|
||||||
|
super(hardware);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(VM from, Location input) {
|
||||||
|
return input.getId().equals(from.getUuid() + "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
* 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.smartos.compute.functions;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.smartos.compute.domain.VmSpecification;
|
||||||
|
import org.jclouds.compute.domain.Hardware;
|
||||||
|
import org.jclouds.compute.domain.HardwareBuilder;
|
||||||
|
import org.jclouds.compute.domain.Processor;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nigel Magnay
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class VmSpecificationToHardware implements Function<VmSpecification, Hardware> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Hardware apply(VmSpecification from) {
|
||||||
|
HardwareBuilder builder = new HardwareBuilder();
|
||||||
|
builder.ids("AnID");
|
||||||
|
builder.name(from.getAlias());
|
||||||
|
builder.processors(ImmutableList.of(new Processor(1, 1.0)));
|
||||||
|
builder.ram(256);
|
||||||
|
//builder.volumes(ImmutableList.<Volume> of(new VolumeImpl(from.disk, true, false)));
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
/**
|
||||||
|
* 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.smartos.compute.strategy;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.smartos.compute.domain.*;
|
||||||
|
import org.jclouds.compute.ComputeService;
|
||||||
|
import org.jclouds.compute.ComputeServiceAdapter;
|
||||||
|
import org.jclouds.compute.domain.Template;
|
||||||
|
import org.jclouds.domain.LoginCredentials;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* defines the connection between the {@link org.jclouds.smartos.compute.domain.SmartOSHost} implementation and the jclouds
|
||||||
|
* {@link ComputeService}
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class SmartOSComputeServiceAdapter implements ComputeServiceAdapter<VM, VmSpecification, DataSet, SmartOSHost> {
|
||||||
|
private final SmartOSHost host;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SmartOSComputeServiceAdapter(SmartOSHost host) {
|
||||||
|
this.host = checkNotNull(host, "host");
|
||||||
|
}
|
||||||
|
|
||||||
|
private SmartOSHost getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeAndInitialCredentials<VM> createNodeWithGroupEncodedIntoName(String tag, String name, Template template) {
|
||||||
|
VmSpecification specification = VmSpecification.builder()
|
||||||
|
.alias(name)
|
||||||
|
.dataset(getHost().getDataSet(UUID.fromString(template.getImage().getProviderId())))
|
||||||
|
.nic(VmNIC.builder().simpleDCHPNic().build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
VM from = getHost().createVM(specification);
|
||||||
|
|
||||||
|
return new NodeAndInitialCredentials<VM>(from, from.getUuid() + "", LoginCredentials.builder().user("smartos")
|
||||||
|
.password("smartos").build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<VmSpecification> listHardwareProfiles() {
|
||||||
|
List<VmSpecification> specificationList = new ArrayList<VmSpecification>();
|
||||||
|
|
||||||
|
VmSpecification vs = VmSpecification.builder()
|
||||||
|
.alias("Standard Joyent VM")
|
||||||
|
.nic(VmNIC.builder().simpleDCHPNic().build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
specificationList.add(vs);
|
||||||
|
|
||||||
|
return specificationList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<DataSet> listImages() {
|
||||||
|
return getHost().getLocalDatasets();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSet getImage(String id) {
|
||||||
|
return getHost().getDataSet(UUID.fromString(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<VM> listNodes() {
|
||||||
|
return getHost().getVMs();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<SmartOSHost> listLocations() {
|
||||||
|
return ImmutableSet.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VM getNode(String id) {
|
||||||
|
return getHost().getVM(UUID.fromString(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroyNode(String id) {
|
||||||
|
getHost().getVM(UUID.fromString(id)).destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void rebootNode(String id) {
|
||||||
|
getHost().getVM(UUID.fromString(id)).reboot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resumeNode(String id) {
|
||||||
|
getHost().getVM(UUID.fromString(id)).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void suspendNode(String id) {
|
||||||
|
getHost().getVM(UUID.fromString(id)).stop();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
org.jclouds.smartos.SmartOSApiMetadata
|
|
@ -0,0 +1,88 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.smartos.compute;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
import org.jclouds.ContextBuilder;
|
||||||
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
import org.jclouds.internal.ContextImpl;
|
||||||
|
import org.jclouds.rest.internal.BaseRestClientTest;
|
||||||
|
import org.jclouds.smartos.SmartOSApiMetadata;
|
||||||
|
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "ServerManagerContextBuilderTest")
|
||||||
|
public class SmartOSManagerComputeServiceContextBuilderTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCanBuildWithApiMetadata() {
|
||||||
|
ComputeServiceContext context = ContextBuilder.newBuilder(
|
||||||
|
new SmartOSApiMetadata())
|
||||||
|
.modules(ImmutableSet.<Module>of(getSshModule()))
|
||||||
|
.build(ComputeServiceContext.class);
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCanBuildById() {
|
||||||
|
ComputeServiceContext context = ContextBuilder.newBuilder("smartos-ssh")
|
||||||
|
.modules(ImmutableSet.<Module>of(getSshModule()))
|
||||||
|
.build(ComputeServiceContext.class);
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCanBuildWithOverridingProperties() {
|
||||||
|
Properties overrides = new Properties();
|
||||||
|
overrides.setProperty("smartos-ssh.endpoint", "http://host");
|
||||||
|
overrides.setProperty("smartos-ssh.api-version", "1");
|
||||||
|
|
||||||
|
ComputeServiceContext context = ContextBuilder.newBuilder("smartos-ssh")
|
||||||
|
.modules(ImmutableSet.<Module>of(getSshModule()))
|
||||||
|
.overrides(overrides).build(ComputeServiceContext.class);
|
||||||
|
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUnwrapIsCorrectType() {
|
||||||
|
ComputeServiceContext context = ContextBuilder.newBuilder("smartos-ssh")
|
||||||
|
.modules(ImmutableSet.<Module>of(getSshModule()))
|
||||||
|
.build(ComputeServiceContext.class);
|
||||||
|
|
||||||
|
assertEquals(context.unwrap().getClass(), ContextImpl.class);
|
||||||
|
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Module getSshModule() {
|
||||||
|
return new SshjSshClientModule();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/**
|
||||||
|
* 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.smartos.compute;
|
||||||
|
|
||||||
|
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.compute.domain.Template;
|
||||||
|
import org.jclouds.compute.internal.BaseComputeServiceLiveTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", enabled = true, singleThreaded = true)
|
||||||
|
public class SmartOSManagerComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
|
|
||||||
|
public SmartOSManagerComputeServiceLiveTest() {
|
||||||
|
provider = "smartos-ssh";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTemplateBuilder() {
|
||||||
|
Template defaultTemplate = client.templateBuilder().build();
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "5.3");
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS);
|
||||||
|
assertEquals(defaultTemplate.getLocation().getId(), "1");
|
||||||
|
assertEquals(getCores(defaultTemplate.getHardware()), 0.5d);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// smartos-ssh does not support metadata
|
||||||
|
@Override
|
||||||
|
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||||
|
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
|
||||||
|
"node userMetadata did not match %s %s", userMetadata, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package org.jclouds.smartos.compute.domain;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Test(groups = "unit", testName = "DataSetTest")
|
||||||
|
public class DataSetTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParse() throws IOException {
|
||||||
|
// Response from console from a 'dsadm list'
|
||||||
|
InputStream is = getClass().getResourceAsStream("dsadm-list-response.txt");
|
||||||
|
|
||||||
|
BufferedReader r = new BufferedReader(new InputStreamReader(is));
|
||||||
|
String line = r.readLine(); // skip line
|
||||||
|
ImmutableList.Builder resultBuilder = ImmutableList.builder();
|
||||||
|
while ((line = r.readLine()) != null) {
|
||||||
|
DataSet ds = DataSet.builder().fromDsadmString(line).build();
|
||||||
|
|
||||||
|
resultBuilder.add(ds);
|
||||||
|
}
|
||||||
|
List<DataSet> dataSetList = resultBuilder.build();
|
||||||
|
|
||||||
|
Assert.assertEquals(10, dataSetList.size());
|
||||||
|
|
||||||
|
Assert.assertEquals(UUID.fromString("c0ffee88-883e-47cf-80d1-ad71cc872180"), dataSetList.get(0).getUuid());
|
||||||
|
Assert.assertEquals("nrm:nrm:realtime-jenkins:1.7", dataSetList.get(0).getUrn());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package org.jclouds.smartos.compute.domain;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Test(groups = "unit", testName = "VMTest")
|
||||||
|
public class VMTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParse() throws IOException {
|
||||||
|
// Response from console from a 'vmadm list -p'
|
||||||
|
InputStream is = getClass().getResourceAsStream("vmadm-list-response.txt");
|
||||||
|
|
||||||
|
BufferedReader r = new BufferedReader(new InputStreamReader(is));
|
||||||
|
String line = null;
|
||||||
|
ImmutableList.Builder resultBuilder = ImmutableList.builder();
|
||||||
|
while ((line = r.readLine()) != null) {
|
||||||
|
VM vm = VM.builder().fromVmadmString(line).build();
|
||||||
|
|
||||||
|
resultBuilder.add(vm);
|
||||||
|
}
|
||||||
|
List<VM> vmList = resultBuilder.build();
|
||||||
|
|
||||||
|
Assert.assertEquals(2, vmList.size());
|
||||||
|
|
||||||
|
Assert.assertEquals(UUID.fromString("60bd2ae5-4e4d-4952-88f9-1b850259d914"), vmList.get(0).getUuid());
|
||||||
|
Assert.assertEquals(VM.State.STOPPED, vmList.get(0).getState());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,190 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
For more configuration infromation and examples see the Apache
|
||||||
|
Log4j website: http://logging.apache.org/log4j/
|
||||||
|
-->
|
||||||
|
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
|
||||||
|
debug="false">
|
||||||
|
|
||||||
|
|
||||||
|
<appender name="S" class="org.apache.log4j.ConsoleAppender">
|
||||||
|
|
||||||
|
<param name="Append" value="true"/>
|
||||||
|
|
||||||
|
<!-- Rollover at midnight each day -->
|
||||||
|
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
|
||||||
|
|
||||||
|
<param name="Threshold" value="TRACE"/>
|
||||||
|
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||||
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The full pattern: Date MS Priority [Category]
|
||||||
|
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||||
|
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||||
|
-->
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- A time/date based rolling appender -->
|
||||||
|
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||||
|
<param name="File" value="target/test-data/jclouds-wire.log"/>
|
||||||
|
<param name="Append" value="true"/>
|
||||||
|
|
||||||
|
<!-- Rollover at midnight each day -->
|
||||||
|
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
|
||||||
|
|
||||||
|
<param name="Threshold" value="TRACE"/>
|
||||||
|
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||||
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The full pattern: Date MS Priority [Category]
|
||||||
|
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||||
|
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||||
|
-->
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- A time/date based rolling appender -->
|
||||||
|
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||||
|
<param name="File" value="target/test-data/jclouds.log"/>
|
||||||
|
<param name="Append" value="true"/>
|
||||||
|
|
||||||
|
<!-- Rollover at midnight each day -->
|
||||||
|
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
|
||||||
|
|
||||||
|
<param name="Threshold" value="TRACE"/>
|
||||||
|
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||||
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The full pattern: Date MS Priority [Category]
|
||||||
|
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||||
|
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||||
|
-->
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
<!-- A time/date based rolling appender -->
|
||||||
|
<appender name="BLOBSTOREFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||||
|
<param name="File" value="target/test-data/jclouds-blobstore.log"/>
|
||||||
|
<param name="Append" value="true"/>
|
||||||
|
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
|
||||||
|
<param name="Threshold" value="TRACE"/>
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- A time/date based rolling appender -->
|
||||||
|
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||||
|
<param name="File" value="target/test-data/jclouds-compute.log"/>
|
||||||
|
<param name="Append" value="true"/>
|
||||||
|
|
||||||
|
<!-- Rollover at midnight each day -->
|
||||||
|
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
|
||||||
|
|
||||||
|
<param name="Threshold" value="TRACE"/>
|
||||||
|
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||||
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The full pattern: Date MS Priority [Category]
|
||||||
|
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||||
|
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||||
|
-->
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- A time/date based rolling appender -->
|
||||||
|
<appender name="SSHFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||||
|
<param name="File" value="target/test-data/jclouds-ssh.log"/>
|
||||||
|
<param name="Append" value="true"/>
|
||||||
|
|
||||||
|
<!-- Rollover at midnight each day -->
|
||||||
|
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
|
||||||
|
|
||||||
|
<param name="Threshold" value="TRACE"/>
|
||||||
|
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||||
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The full pattern: Date MS Priority [Category]
|
||||||
|
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||||
|
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||||
|
-->
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
|
||||||
|
<appender-ref ref="COMPUTEFILE"/>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="ASYNCSSH" class="org.apache.log4j.AsyncAppender">
|
||||||
|
<appender-ref ref="SSHFILE"/>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
|
||||||
|
<appender-ref ref="FILE"/>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
|
||||||
|
<appender-ref ref="WIREFILE"/>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="ASYNCBLOBSTORE" class="org.apache.log4j.AsyncAppender">
|
||||||
|
<appender-ref ref="BLOBSTOREFILE"/>
|
||||||
|
</appender>
|
||||||
|
<!-- ================ -->
|
||||||
|
<!-- Limit categories -->
|
||||||
|
<!-- ================ -->
|
||||||
|
|
||||||
|
<category name="org.jclouds">
|
||||||
|
<priority value="DEBUG"/>
|
||||||
|
<appender-ref ref="ASYNC"/>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category name="jclouds.headers">
|
||||||
|
<priority value="DEBUG"/>
|
||||||
|
<appender-ref ref="ASYNCWIRE"/>
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category name="jclouds.ssh">
|
||||||
|
<priority value="DEBUG"/>
|
||||||
|
<appender-ref ref="ASYNCSSH"/>
|
||||||
|
</category>
|
||||||
|
<category name="jclouds.wire">
|
||||||
|
<priority value="DEBUG"/>
|
||||||
|
<appender-ref ref="ASYNCWIRE"/>
|
||||||
|
</category>
|
||||||
|
<category name="jclouds.blobstore">
|
||||||
|
<priority value="DEBUG"/>
|
||||||
|
<appender-ref ref="ASYNCBLOBSTORE"/>
|
||||||
|
</category>
|
||||||
|
<category name="jclouds.compute">
|
||||||
|
<priority value="TRACE"/>
|
||||||
|
<appender-ref ref="ASYNCCOMPUTE"/>
|
||||||
|
</category>
|
||||||
|
<!-- ======================= -->
|
||||||
|
<!-- Setup the Root category -->
|
||||||
|
<!-- ======================= -->
|
||||||
|
|
||||||
|
<root>
|
||||||
|
<priority value="TRACE"/>
|
||||||
|
<appender-ref ref="S"/>
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</log4j:configuration>
|
|
@ -0,0 +1,11 @@
|
||||||
|
UUID OS PUBLISHED URN
|
||||||
|
c0ffee88-883e-47cf-80d1-ad71cc872180 smartos 2012-05-02 nrm:nrm:realtime-jenkins:1.7
|
||||||
|
c0ffee99-883e-47cf-80d1-ad71cc872180 smartos 2012-05-02 nrm:nrm:realtime-jenkins:1.7
|
||||||
|
bb5aa3d2-cc19-11e1-99e7-a752418da63a smartos 2012-05-02 nrm:nrm:jenkins-slave:1.0
|
||||||
|
c0ffee32-883e-47cf-80d1-ad71cc872180 smartos 2012-05-02 nrm:nrm:realtime-jenkins:1.6.3
|
||||||
|
467ca742-4873-11e1-80ea-37290b38d2eb smartos 2012-02-14 sdc:sdc:smartos64:1.5.3
|
||||||
|
56108678-1183-11e1-83c3-ff3185a5b47f linux 2011-11-18 sdc:sdc:ubuntu10.04:0.1.0
|
||||||
|
f9e4be48-9466-11e1-bc41-9f993f5dff36 smartos 2012-05-02 sdc:sdc:smartos64:1.6.3
|
||||||
|
c0ffee64-883e-47cf-80d1-ad71cc872180 smartos 2012-05-02 nrm:nrm:realtime-jenkins:1.6
|
||||||
|
a9380908-ea0e-11e0-aeee-4ba794c83c33 smartos 2011-09-28 sdc:sdc:percona:1.0.7
|
||||||
|
c0ffee00-883e-47cf-80d1-ad71cc872180 smartos 2012-05-02 sdc:sdc:realtime-jenkins:1.6.3
|
|
@ -0,0 +1,2 @@
|
||||||
|
60bd2ae5-4e4d-4952-88f9-1b850259d914:OS:256:stopped:
|
||||||
|
a8799014-7680-481f-b7de-76b501dbd803:OS:256:running:instance1-3b5
|
Loading…
Reference in New Issue