mirror of https://github.com/apache/jclouds.git
Merge pull request #273 from alasdairhodge/CloudSigma-SSD-support
CloudSigma support for drive tags and SSD affinity
This commit is contained in:
commit
cd9b140ad0
|
@ -219,6 +219,7 @@ public interface CloudSigmaClient {
|
||||||
* options to control size
|
* options to control size
|
||||||
* @return new drive
|
* @return new drive
|
||||||
*/
|
*/
|
||||||
|
@Timeout(duration = 300, timeUnit = TimeUnit.SECONDS)
|
||||||
DriveInfo cloneDrive(String sourceUuid, String newName, CloneDriveOptions... options);
|
DriveInfo cloneDrive(String sourceUuid, String newName, CloneDriveOptions... options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
* 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.cloudsigma.domain;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option for the cloneDrive operation.
|
||||||
|
* 'HDD' to specifies a regular "spinning oxide" disk; 'SSD' specifies a solid-state drive.
|
||||||
|
*
|
||||||
|
* @author Alasdair Hodge
|
||||||
|
*/
|
||||||
|
public enum AffinityType {
|
||||||
|
HDD,
|
||||||
|
SSD,
|
||||||
|
UNRECOGNIZED;
|
||||||
|
|
||||||
|
public String value() {
|
||||||
|
return name().toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AffinityType fromValue(String affinity) {
|
||||||
|
try {
|
||||||
|
return valueOf(checkNotNull(affinity, "affinity").toUpperCase());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return UNRECOGNIZED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -64,6 +64,14 @@ public class CreateDriveRequest extends Drive {
|
||||||
return Builder.class.cast(super.name(name));
|
return Builder.class.cast(super.name(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder tags(Iterable<String> tags) {
|
||||||
|
return Builder.class.cast(super.tags(tags));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -89,7 +97,7 @@ public class CreateDriveRequest extends Drive {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreateDriveRequest build() {
|
public CreateDriveRequest build() {
|
||||||
return new CreateDriveRequest(name, size, claimType, readers, use, encryptionCipher, avoid);
|
return new CreateDriveRequest(name, size, claimType, tags, readers, use, encryptionCipher, avoid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,9 +105,9 @@ public class CreateDriveRequest extends Drive {
|
||||||
@Nullable
|
@Nullable
|
||||||
private final String encryptionCipher;
|
private final String encryptionCipher;
|
||||||
|
|
||||||
public CreateDriveRequest(String name, long size, @Nullable ClaimType claimType, Iterable<String> readers,
|
public CreateDriveRequest(String name, long size, @Nullable ClaimType claimType, Iterable<String> tags,
|
||||||
Iterable<String> use, @Nullable String encryptionCipher, Iterable<String> avoid) {
|
Iterable<String> readers, Iterable<String> use, @Nullable String encryptionCipher, Iterable<String> avoid) {
|
||||||
super(null, name, size, claimType, readers, use);
|
super(null, name, size, claimType, tags, readers, use);
|
||||||
this.encryptionCipher = encryptionCipher;
|
this.encryptionCipher = encryptionCipher;
|
||||||
this.avoid = ImmutableSet.copyOf(checkNotNull(avoid, "avoid"));
|
this.avoid = ImmutableSet.copyOf(checkNotNull(avoid, "avoid"));
|
||||||
}
|
}
|
||||||
|
@ -155,7 +163,8 @@ public class CreateDriveRequest extends Drive {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[name=" + name + ", size=" + size + ", claimType=" + claimType + ", readers=" + readers + ", use=" + use
|
return "[name=" + name + ", size=" + size + ", claimType=" + claimType + ", tags=" + tags
|
||||||
+ ", avoid=" + avoid + ", encryptionCipher=" + encryptionCipher + "]";
|
+ ", readers=" + readers + ", use=" + use + ", avoid=" + avoid
|
||||||
|
+ ", encryptionCipher=" + encryptionCipher + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -24,6 +24,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,6 +35,7 @@ public class Drive extends Item {
|
||||||
public static class Builder extends Item.Builder {
|
public static class Builder extends Item.Builder {
|
||||||
protected long size;
|
protected long size;
|
||||||
protected ClaimType claimType = ClaimType.EXCLUSIVE;
|
protected ClaimType claimType = ClaimType.EXCLUSIVE;
|
||||||
|
protected Set<String> tags = ImmutableSet.of();
|
||||||
protected Set<String> readers = ImmutableSet.of();
|
protected Set<String> readers = ImmutableSet.of();
|
||||||
|
|
||||||
public Builder claimType(ClaimType claimType) {
|
public Builder claimType(ClaimType claimType) {
|
||||||
|
@ -41,6 +43,11 @@ public class Drive extends Item {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder tags(Iterable<String> tags) {
|
||||||
|
this.tags = ImmutableSet.copyOf(checkNotNull(tags, "tags"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder readers(Iterable<String> readers) {
|
public Builder readers(Iterable<String> readers) {
|
||||||
this.readers = ImmutableSet.copyOf(checkNotNull(readers, "readers"));
|
this.readers = ImmutableSet.copyOf(checkNotNull(readers, "readers"));
|
||||||
return this;
|
return this;
|
||||||
|
@ -76,7 +83,7 @@ public class Drive extends Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Drive build() {
|
public Drive build() {
|
||||||
return new Drive(uuid, name, size, claimType, readers, use);
|
return new Drive(uuid, name, size, claimType, tags, readers, use);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -84,6 +91,7 @@ public class Drive extends Item {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = super.hashCode();
|
int result = super.hashCode();
|
||||||
result = prime * result + ((claimType == null) ? 0 : claimType.hashCode());
|
result = prime * result + ((claimType == null) ? 0 : claimType.hashCode());
|
||||||
|
result = prime * result + ((tags == null) ? 0 : tags.hashCode());
|
||||||
result = prime * result + ((readers == null) ? 0 : readers.hashCode());
|
result = prime * result + ((readers == null) ? 0 : readers.hashCode());
|
||||||
result = prime * result + (int) (size ^ (size >>> 32));
|
result = prime * result + (int) (size ^ (size >>> 32));
|
||||||
return result;
|
return result;
|
||||||
|
@ -100,11 +108,10 @@ public class Drive extends Item {
|
||||||
Builder other = (Builder) obj;
|
Builder other = (Builder) obj;
|
||||||
if (claimType != other.claimType)
|
if (claimType != other.claimType)
|
||||||
return false;
|
return false;
|
||||||
if (readers == null) {
|
if (!Objects.equal(tags, other.tags))
|
||||||
if (other.readers != null)
|
return false;
|
||||||
return false;
|
if (!Objects.equal(readers, other.readers))
|
||||||
} else if (!readers.equals(other.readers))
|
return false;
|
||||||
return false;
|
|
||||||
if (size != other.size)
|
if (size != other.size)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -113,13 +120,15 @@ public class Drive extends Item {
|
||||||
|
|
||||||
protected final long size;
|
protected final long size;
|
||||||
protected final ClaimType claimType;
|
protected final ClaimType claimType;
|
||||||
|
protected final Set<String> tags;
|
||||||
protected final Set<String> readers;
|
protected final Set<String> readers;
|
||||||
|
|
||||||
public Drive(@Nullable String uuid, String name, long size, @Nullable ClaimType claimType, Iterable<String> readers,
|
public Drive(@Nullable String uuid, String name, long size, @Nullable ClaimType claimType,
|
||||||
Iterable<String> use) {
|
Iterable<String> tags, Iterable<String> readers, Iterable<String> use) {
|
||||||
super(uuid, name, use);
|
super(uuid, name, use);
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.claimType = checkNotNull(claimType, "set claimType to exclusive, not null");
|
this.claimType = checkNotNull(claimType, "set claimType to exclusive, not null");
|
||||||
|
this.tags = ImmutableSet.copyOf(checkNotNull(tags, "tags"));
|
||||||
this.readers = ImmutableSet.copyOf(checkNotNull(readers, "readers"));
|
this.readers = ImmutableSet.copyOf(checkNotNull(readers, "readers"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +142,13 @@ public class Drive extends Item {
|
||||||
return claimType;
|
return claimType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return all tags associated with this drive, both user-specified and "system" tags (e.g. "affinity:ssd")
|
||||||
|
*/
|
||||||
|
public Set<String> getTags() {
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return list of users allowed to read from a drive or 'ffffffff-ffff-ffff-ffff-ffffffffffff'
|
* @return list of users allowed to read from a drive or 'ffffffff-ffff-ffff-ffff-ffffffffffff'
|
||||||
|
@ -155,6 +171,7 @@ public class Drive extends Item {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = prime * result + ((claimType == null) ? 0 : claimType.hashCode());
|
result = prime * result + ((claimType == null) ? 0 : claimType.hashCode());
|
||||||
|
result = prime * result + ((tags == null) ? 0 : tags.hashCode());
|
||||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
result = prime * result + ((readers == null) ? 0 : readers.hashCode());
|
result = prime * result + ((readers == null) ? 0 : readers.hashCode());
|
||||||
result = prime * result + (int) (size ^ (size >>> 32));
|
result = prime * result + (int) (size ^ (size >>> 32));
|
||||||
|
@ -173,16 +190,12 @@ public class Drive extends Item {
|
||||||
Drive other = (Drive) obj;
|
Drive other = (Drive) obj;
|
||||||
if (claimType != other.claimType)
|
if (claimType != other.claimType)
|
||||||
return false;
|
return false;
|
||||||
if (name == null) {
|
if (!Objects.equal(tags, other.tags))
|
||||||
if (other.name != null)
|
return false;
|
||||||
return false;
|
if (!Objects.equal(name, other.name))
|
||||||
} else if (!name.equals(other.name))
|
return false;
|
||||||
return false;
|
if (!Objects.equal(readers, other.readers))
|
||||||
if (readers == null) {
|
return false;
|
||||||
if (other.readers != null)
|
|
||||||
return false;
|
|
||||||
} else if (!readers.equals(other.readers))
|
|
||||||
return false;
|
|
||||||
if (size != other.size)
|
if (size != other.size)
|
||||||
return false;
|
return false;
|
||||||
if (use == null) {
|
if (use == null) {
|
||||||
|
@ -196,7 +209,7 @@ public class Drive extends Item {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[uuid=" + uuid + ", name=" + name + ", use=" + use + ", size=" + size + ", claimType=" + claimType
|
return "[uuid=" + uuid + ", name=" + name + ", use=" + use + ", size=" + size + ", claimType=" + claimType
|
||||||
+ ", readers=" + readers + "]";
|
+ ", tags=" + tags + ", readers=" + readers + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -43,6 +43,14 @@ public class DriveData extends Drive {
|
||||||
return Builder.class.cast(super.name(name));
|
return Builder.class.cast(super.name(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder tags(Iterable<String> tags) {
|
||||||
|
return Builder.class.cast(super.tags(tags));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -68,12 +76,12 @@ public class DriveData extends Drive {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DriveData build() {
|
public DriveData build() {
|
||||||
return new DriveData(uuid, name, size, claimType, readers, use);
|
return new DriveData(uuid, name, size, claimType, tags, readers, use);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DriveData(@Nullable String uuid, String name, long size, @Nullable ClaimType claimType,
|
public DriveData(@Nullable String uuid, String name, long size, @Nullable ClaimType claimType,
|
||||||
Iterable<String> readers, Iterable<String> use) {
|
Iterable<String> tags, Iterable<String> readers, Iterable<String> use) {
|
||||||
super(uuid, name, size, claimType, readers, use);
|
super(uuid, name, size, claimType, tags, readers, use);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -141,6 +141,14 @@ public class DriveInfo extends Drive {
|
||||||
return Builder.class.cast(super.claimType(claimType));
|
return Builder.class.cast(super.claimType(claimType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder tags(Iterable<String> tags) {
|
||||||
|
return Builder.class.cast(super.tags(tags));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -195,7 +203,7 @@ public class DriveInfo extends Drive {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public DriveInfo build() {
|
public DriveInfo build() {
|
||||||
return new DriveInfo(uuid, name, size, claimType, readers, use, status, user, claimed, encryptionCipher,
|
return new DriveInfo(uuid, name, size, claimType, tags, readers, use, status, user, claimed, encryptionCipher,
|
||||||
imaging, metrics, autoexpanding, bits, description, driveType, encryptionKey, free, installNotes, os,
|
imaging, metrics, autoexpanding, bits, description, driveType, encryptionKey, free, installNotes, os,
|
||||||
type, url);
|
type, url);
|
||||||
}
|
}
|
||||||
|
@ -221,12 +229,12 @@ public class DriveInfo extends Drive {
|
||||||
private final DriveType type;
|
private final DriveType type;
|
||||||
private final URI url;
|
private final URI url;
|
||||||
|
|
||||||
public DriveInfo(String uuid, String name, long size, ClaimType claimType, Iterable<String> readers,
|
public DriveInfo(String uuid, String name, long size, ClaimType claimType, Iterable<String> tags, Iterable<String> readers,
|
||||||
Iterable<String> use, DriveStatus status, String user, Set<String> claimed, String encryptionCipher,
|
Iterable<String> use, DriveStatus status, String user, Set<String> claimed, String encryptionCipher,
|
||||||
String imaging, DriveMetrics metrics, Boolean autoexpanding, Integer bits, String description,
|
String imaging, DriveMetrics metrics, Boolean autoexpanding, Integer bits, String description,
|
||||||
Iterable<String> driveType, String encryptionKey, Boolean free, String installNotes, String os,
|
Iterable<String> driveType, String encryptionKey, Boolean free, String installNotes, String os,
|
||||||
DriveType type, URI url) {
|
DriveType type, URI url) {
|
||||||
super(uuid, name, size, claimType, readers, use);
|
super(uuid, name, size, claimType, tags, readers, use);
|
||||||
this.status = status;
|
this.status = status;
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.claimed = ImmutableSet.copyOf(checkNotNull(claimed, "claimed"));
|
this.claimed = ImmutableSet.copyOf(checkNotNull(claimed, "claimed"));
|
||||||
|
@ -455,9 +463,10 @@ public class DriveInfo extends Drive {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[size=" + size + ", claimType=" + claimType + ", readers=" + readers + ", uuid=" + uuid + ", name="
|
return "[size=" + size + ", claimType=" + claimType + ", tags=" + tags + ", readers=" + readers
|
||||||
+ name + ", use=" + use + ", status=" + status + ", user=" + user + ", claimed=" + claimed
|
+ ", uuid=" + uuid + ", name=" + name + ", use=" + use + ", status=" + status
|
||||||
+ ", encryptionCipher=" + encryptionCipher + ", imaging=" + imaging + ", metrics=" + metrics + "]";
|
+ ", user=" + user + ", claimed=" + claimed + ", encryptionCipher=" + encryptionCipher
|
||||||
|
+ ", imaging=" + imaging + ", metrics=" + metrics + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -45,6 +45,8 @@ public class BaseDriveToMap implements Function<Drive, Map<String, String>> {
|
||||||
builder.put("size", from.getSize() + "");
|
builder.put("size", from.getSize() + "");
|
||||||
if (from.getClaimType() != ClaimType.EXCLUSIVE)
|
if (from.getClaimType() != ClaimType.EXCLUSIVE)
|
||||||
builder.put("claim:type", from.getClaimType().toString());
|
builder.put("claim:type", from.getClaimType().toString());
|
||||||
|
if (from.getTags().size() != 0)
|
||||||
|
builder.put("tags", Joiner.on(' ').join(from.getTags()));
|
||||||
if (from.getReaders().size() != 0)
|
if (from.getReaders().size() != 0)
|
||||||
builder.put("readers", Joiner.on(' ').join(from.getReaders()));
|
builder.put("readers", Joiner.on(' ').join(from.getReaders()));
|
||||||
if (from.getUse().size() != 0)
|
if (from.getUse().size() != 0)
|
||||||
|
|
|
@ -48,8 +48,6 @@ public class MapToDriveInfo implements Function<Map<String, String>, DriveInfo>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DriveInfo apply(Map<String, String> from) {
|
public DriveInfo apply(Map<String, String> from) {
|
||||||
if (from.size() == 0)
|
|
||||||
return null;
|
|
||||||
if (from.size() == 0)
|
if (from.size() == 0)
|
||||||
return null;
|
return null;
|
||||||
DriveInfo.Builder builder = new DriveInfo.Builder();
|
DriveInfo.Builder builder = new DriveInfo.Builder();
|
||||||
|
@ -66,6 +64,8 @@ public class MapToDriveInfo implements Function<Map<String, String>, DriveInfo>
|
||||||
builder.claimType(ClaimType.fromValue(from.get("claim:type")));
|
builder.claimType(ClaimType.fromValue(from.get("claim:type")));
|
||||||
if (from.containsKey("claimed"))
|
if (from.containsKey("claimed"))
|
||||||
builder.claimed(Splitter.on(' ').split(from.get("claimed")));
|
builder.claimed(Splitter.on(' ').split(from.get("claimed")));
|
||||||
|
if (from.containsKey("tags"))
|
||||||
|
builder.tags(Splitter.on(' ').split(from.get("tags")));
|
||||||
if (from.containsKey("readers"))
|
if (from.containsKey("readers"))
|
||||||
builder.readers(Splitter.on(' ').split(from.get("readers")));
|
builder.readers(Splitter.on(' ').split(from.get("readers")));
|
||||||
if (from.containsKey("size"))
|
if (from.containsKey("size"))
|
||||||
|
|
|
@ -20,10 +20,18 @@ package org.jclouds.cloudsigma.options;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.cloudsigma.domain.AffinityType;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains options supported for clone drive operations. <h2>
|
* Contains options supported for clone drive operations. <h2>
|
||||||
|
@ -42,6 +50,7 @@ import com.google.common.collect.Maps;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CloneDriveOptions {
|
public class CloneDriveOptions {
|
||||||
|
private final String SSD_AFFINITY_TAG = "affinity:ssd";
|
||||||
private final Map<String, String> options = Maps.newLinkedHashMap();
|
private final Map<String, String> options = Maps.newLinkedHashMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,6 +62,51 @@ public class CloneDriveOptions {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CloneDriveOptions tags(String... tags) {
|
||||||
|
// Affinity is conveyed using regular tags; make sure to preserve any already-set affinity tag.
|
||||||
|
String currentTagsString = options.remove("tags");
|
||||||
|
Set<String> currentTags = (currentTagsString == null) ? new HashSet<String>() :
|
||||||
|
Sets.newLinkedHashSet(Splitter.on(' ').split(currentTagsString));
|
||||||
|
|
||||||
|
Set<String> newTags = new LinkedHashSet<String>();
|
||||||
|
for (String tag : tags)
|
||||||
|
newTags.add(tag);
|
||||||
|
|
||||||
|
if (currentTags.contains(SSD_AFFINITY_TAG))
|
||||||
|
newTags.add(SSD_AFFINITY_TAG);
|
||||||
|
|
||||||
|
options.put("tags", Joiner.on(' ').join(newTags));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether the new drive has 'HDD' affinity (the default) or 'SSD' (for solid-state drives).
|
||||||
|
* Affinity is conveyed via a special value among the drive's tags.
|
||||||
|
*/
|
||||||
|
public CloneDriveOptions affinity(AffinityType affinity) {
|
||||||
|
// Affinity is conveyed using regular tags; make sure to avoid multiple affinity tags in the options.
|
||||||
|
String currentTagsString = options.remove("tags");
|
||||||
|
Set<String> tags = (currentTagsString == null) ? new LinkedHashSet<String>() :
|
||||||
|
Sets.newLinkedHashSet(Splitter.on(' ').split(currentTagsString));
|
||||||
|
|
||||||
|
switch (affinity) {
|
||||||
|
// SSD affinity is conveyed as a special tag: "affinity:ssd".
|
||||||
|
case SSD:
|
||||||
|
tags.add(SSD_AFFINITY_TAG);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// HDD affinity (the default) is conveyed by the *absence* of the "affinity:ssd" tag.
|
||||||
|
case HDD:
|
||||||
|
tags.remove(SSD_AFFINITY_TAG);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tags.isEmpty())
|
||||||
|
options.put("tags", Joiner.on(' ').join(tags));
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,6 +117,22 @@ public class CloneDriveOptions {
|
||||||
return options.size(size);
|
return options.size(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CloneDriveOptions#tags
|
||||||
|
*/
|
||||||
|
public static CloneDriveOptions tags(String... tags) {
|
||||||
|
CloneDriveOptions options = new CloneDriveOptions();
|
||||||
|
return options.tags(tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CloneDriveOptions#affinity
|
||||||
|
*/
|
||||||
|
public static CloneDriveOptions affinity(AffinityType affinity) {
|
||||||
|
CloneDriveOptions options = new CloneDriveOptions();
|
||||||
|
return options.affinity(affinity);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getOptions() {
|
public Map<String, String> getOptions() {
|
||||||
|
|
|
@ -460,9 +460,16 @@ public class CloudSigmaClientLiveTest {
|
||||||
protected void prepareDrive() {
|
protected void prepareDrive() {
|
||||||
client.destroyDrive(drive.getUuid());
|
client.destroyDrive(drive.getUuid());
|
||||||
drive = client.cloneDrive(bootDrive, drive.getName(),
|
drive = client.cloneDrive(bootDrive, drive.getName(),
|
||||||
new CloneDriveOptions().size(driveSize));
|
new CloneDriveOptions()
|
||||||
|
.size(driveSize)
|
||||||
|
.tags("cat:mouse", "monkey:banana")
|
||||||
|
);
|
||||||
|
// Block until the async clone operation has completed.
|
||||||
assert driveNotClaimed.apply(drive) : client.getDriveInfo(drive.getUuid());
|
assert driveNotClaimed.apply(drive) : client.getDriveInfo(drive.getUuid());
|
||||||
System.err.println("after prepare" + client.getDriveInfo(drive.getUuid()));
|
|
||||||
|
DriveInfo clonedDrive = client.getDriveInfo(drive.getUuid());
|
||||||
|
System.err.println("after prepare" + clonedDrive);
|
||||||
|
assertEquals(clonedDrive.getTags(), ImmutableSet.of("cat:mouse", "monkey:banana"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ public class BindDriveDataToPlainTextStringTest {
|
||||||
//
|
//
|
||||||
.size(8589934592l)//
|
.size(8589934592l)//
|
||||||
.claimType(ClaimType.SHARED)//
|
.claimType(ClaimType.SHARED)//
|
||||||
|
.tags(ImmutableSet.of("foo", "bar", "baz"))//
|
||||||
.readers(ImmutableSet.of("ffffffff-ffff-ffff-ffff-ffffffffffff"))//
|
.readers(ImmutableSet.of("ffffffff-ffff-ffff-ffff-ffffffffffff"))//
|
||||||
.use(ImmutableSet.of("tag1", "tag2"))//
|
.use(ImmutableSet.of("tag1", "tag2"))//
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -48,13 +48,16 @@ public class BaseDriveToMapTest {
|
||||||
//
|
//
|
||||||
.size(8589934592l)//
|
.size(8589934592l)//
|
||||||
.claimType(ClaimType.SHARED)//
|
.claimType(ClaimType.SHARED)//
|
||||||
|
.tags(ImmutableSet.of("foo", "bar", "baz"))//
|
||||||
.readers(ImmutableSet.of("ffffffff-ffff-ffff-ffff-ffffffffffff"))//
|
.readers(ImmutableSet.of("ffffffff-ffff-ffff-ffff-ffffffffffff"))//
|
||||||
.use(ImmutableSet.of("tag1", "tag2"))//
|
.use(ImmutableSet.of("tag1", "tag2"))//
|
||||||
.build();
|
.build();
|
||||||
assertEquals(
|
assertEquals(
|
||||||
BASEDRIVE_TO_MAP.apply(one),
|
BASEDRIVE_TO_MAP.apply(one),
|
||||||
ImmutableMap.builder().put("name", "Ubuntu 10.10 Server Edition Linux 64bit Preinstalled System")
|
ImmutableMap.builder().put("name", "Ubuntu 10.10 Server Edition Linux 64bit Preinstalled System")
|
||||||
.put("size", "8589934592").put("claim:type", "shared")
|
.put("size", "8589934592")
|
||||||
|
.put("claim:type", "shared")
|
||||||
|
.put("tags", "foo bar baz")
|
||||||
.put("readers", "ffffffff-ffff-ffff-ffff-ffffffffffff").put("use", "tag1 tag2").build()
|
.put("readers", "ffffffff-ffff-ffff-ffff-ffffffffffff").put("use", "tag1 tag2").build()
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
|
@ -49,14 +49,19 @@ public class DriveDataToMapTest {
|
||||||
//
|
//
|
||||||
.size(8589934592l)//
|
.size(8589934592l)//
|
||||||
.claimType(ClaimType.SHARED)//
|
.claimType(ClaimType.SHARED)//
|
||||||
|
.tags(ImmutableSet.of("foo", "bar", "baz"))//
|
||||||
.readers(ImmutableSet.of("ffffffff-ffff-ffff-ffff-ffffffffffff"))//
|
.readers(ImmutableSet.of("ffffffff-ffff-ffff-ffff-ffffffffffff"))//
|
||||||
.use(ImmutableSet.of("tag1", "tag2"))//
|
.use(ImmutableSet.of("tag1", "tag2"))//
|
||||||
.build();
|
.build();
|
||||||
assertEquals(
|
assertEquals(
|
||||||
BASEDRIVE_TO_MAP.apply(one),
|
BASEDRIVE_TO_MAP.apply(one),
|
||||||
ImmutableMap.builder().put("name", "Ubuntu 10.10 Server Edition Linux 64bit Preinstalled System")
|
ImmutableMap.builder()
|
||||||
.put("size", "8589934592").put("claim:type", "shared")
|
.put("name", "Ubuntu 10.10 Server Edition Linux 64bit Preinstalled System")
|
||||||
.put("readers", "ffffffff-ffff-ffff-ffff-ffffffffffff").put("use", "tag1 tag2").build()
|
.put("size", "8589934592")
|
||||||
|
.put("claim:type", "shared")
|
||||||
|
.put("tags", "foo bar baz")
|
||||||
|
.put("readers", "ffffffff-ffff-ffff-ffff-ffffffffffff")
|
||||||
|
.put("use", "tag1 tag2").build()
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ public class MapToDriveInfoTest {
|
||||||
.encryptionCipher("aes-xts-plain")
|
.encryptionCipher("aes-xts-plain")
|
||||||
.encryptionKey("ba6c2a4897072e9f25920ed73bd522e9c10d89f30a215158cccf8d0f654ac643")
|
.encryptionKey("ba6c2a4897072e9f25920ed73bd522e9c10d89f30a215158cccf8d0f654ac643")
|
||||||
.description("The Ubuntu Linux distribution brings the spirit of Ubuntu to the software world.")
|
.description("The Ubuntu Linux distribution brings the spirit of Ubuntu to the software world.")
|
||||||
|
.tags(ImmutableSet.of("foo", "bar", "baz"))
|
||||||
.uuid("b8171d28-755a-4271-b891-7998871a160e")
|
.uuid("b8171d28-755a-4271-b891-7998871a160e")
|
||||||
.installNotes("first line\n\n")
|
.installNotes("first line\n\n")
|
||||||
.os("linux")
|
.os("linux")
|
||||||
|
|
|
@ -19,9 +19,12 @@
|
||||||
package org.jclouds.cloudsigma.options;
|
package org.jclouds.cloudsigma.options;
|
||||||
|
|
||||||
import static org.jclouds.cloudsigma.options.CloneDriveOptions.Builder.size;
|
import static org.jclouds.cloudsigma.options.CloneDriveOptions.Builder.size;
|
||||||
|
import static org.jclouds.cloudsigma.options.CloneDriveOptions.Builder.tags;
|
||||||
|
import static org.jclouds.cloudsigma.options.CloneDriveOptions.Builder.affinity;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertNull;
|
import static org.testng.Assert.assertNull;
|
||||||
|
|
||||||
|
import org.jclouds.cloudsigma.domain.AffinityType;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,4 +58,74 @@ public class CloneDriveOptionsTest {
|
||||||
size(-1);
|
size(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullTags() {
|
||||||
|
CloneDriveOptions options = new CloneDriveOptions();
|
||||||
|
assertNull(options.getOptions().get("tags"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTags() {
|
||||||
|
CloneDriveOptions options = new CloneDriveOptions().tags("foo", "bar", "baz");
|
||||||
|
assertEquals(options.getOptions().get("tags"), "foo bar baz");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTagsStatic() {
|
||||||
|
CloneDriveOptions options = tags("foo", "bar", "baz");
|
||||||
|
assertEquals(options.getOptions().get("tags"), "foo bar baz");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHddAffinity() {
|
||||||
|
CloneDriveOptions options = new CloneDriveOptions().affinity(AffinityType.HDD);
|
||||||
|
assertNull(options.getOptions().get("tags"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHddAffinityStatic() {
|
||||||
|
CloneDriveOptions options = affinity(AffinityType.HDD);
|
||||||
|
assertNull(options.getOptions().get("tags"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSsdAffinity() {
|
||||||
|
CloneDriveOptions options = new CloneDriveOptions().affinity(AffinityType.SSD);
|
||||||
|
assertEquals(options.getOptions().get("tags"), "affinity:ssd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSsdAffinityStatic() {
|
||||||
|
CloneDriveOptions options = affinity(AffinityType.SSD);
|
||||||
|
assertEquals(options.getOptions().get("tags"), "affinity:ssd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHddAffinityBeforeTags() {
|
||||||
|
CloneDriveOptions options = new CloneDriveOptions().affinity(AffinityType.HDD);
|
||||||
|
options.tags("foo", "bar", "baz");
|
||||||
|
assertEquals(options.getOptions().get("tags"), "foo bar baz");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSsdAffinityBeforeTags() {
|
||||||
|
CloneDriveOptions options = new CloneDriveOptions().affinity(AffinityType.SSD);
|
||||||
|
options.tags("foo", "bar", "baz");
|
||||||
|
assertEquals(options.getOptions().get("tags"), "foo bar baz affinity:ssd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHddAffinityAfterTags() {
|
||||||
|
CloneDriveOptions options = new CloneDriveOptions().tags("foo", "bar", "baz");
|
||||||
|
options.affinity(AffinityType.HDD);
|
||||||
|
assertEquals(options.getOptions().get("tags"), "foo bar baz");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSsdAffinityAfterTags() {
|
||||||
|
CloneDriveOptions options = new CloneDriveOptions().tags("foo", "bar", "baz");
|
||||||
|
options.affinity(AffinityType.SSD);
|
||||||
|
assertEquals(options.getOptions().get("tags"), "foo bar baz affinity:ssd");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ claim:type shared
|
||||||
claimed 00109617-2c6b-424b-9cfa-5b572c17bafe:guest:692cd1c7-a863-4a22-8170-fc6e6feb68af:ide:0:0 00031836-a624-4b22-bc7d-41ff8977087b:guest:a1414360-7c24-4730-8c97-180bf7775a71:ide:0:0 0002c6df-a1d2-4d1d-96f0-f95405a28183:guest:386f1cc7-affc-49c1-82a5-2f8e412170e4:ide:0:0 00031836-a624-4b22-bc7d-41ff8977087b:guest:17b076be-430d-4a76-9df3-b9896fec82a5:ide:0:0 000663ee-9fb6-4461-90f6-01327a4aff07:guest:f83b519f-feab-42cf-859c-f61495681ada:ide:0:1
|
claimed 00109617-2c6b-424b-9cfa-5b572c17bafe:guest:692cd1c7-a863-4a22-8170-fc6e6feb68af:ide:0:0 00031836-a624-4b22-bc7d-41ff8977087b:guest:a1414360-7c24-4730-8c97-180bf7775a71:ide:0:0 0002c6df-a1d2-4d1d-96f0-f95405a28183:guest:386f1cc7-affc-49c1-82a5-2f8e412170e4:ide:0:0 00031836-a624-4b22-bc7d-41ff8977087b:guest:17b076be-430d-4a76-9df3-b9896fec82a5:ide:0:0 000663ee-9fb6-4461-90f6-01327a4aff07:guest:f83b519f-feab-42cf-859c-f61495681ada:ide:0:1
|
||||||
drive_type installcd,livecd
|
drive_type installcd,livecd
|
||||||
autoexpanding false
|
autoexpanding false
|
||||||
|
tags foo bar baz
|
||||||
readers ffffffff-ffff-ffff-ffff-ffffffffffff
|
readers ffffffff-ffff-ffff-ffff-ffffffffffff
|
||||||
read:requests 1
|
read:requests 1
|
||||||
free true
|
free true
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
name Ubuntu 10.10 Server Edition Linux 64bit Preinstalled System
|
name Ubuntu 10.10 Server Edition Linux 64bit Preinstalled System
|
||||||
size 8589934592
|
size 8589934592
|
||||||
claim:type shared
|
claim:type shared
|
||||||
|
tags foo bar baz
|
||||||
readers ffffffff-ffff-ffff-ffff-ffffffffffff
|
readers ffffffff-ffff-ffff-ffff-ffffffffffff
|
||||||
use tag1 tag2
|
use tag1 tag2
|
Loading…
Reference in New Issue