mirror of https://github.com/apache/jclouds.git
First cut at a clojure wrapper of EBS interface
This commit is contained in:
parent
1bdf5eda18
commit
bc7a92fae1
|
@ -0,0 +1,165 @@
|
|||
(ns org.jclouds.aws.ebs
|
||||
"A clojure binding to the jclouds EBS service interface."
|
||||
(:require (org.jclouds [compute :as compute])
|
||||
(clojure.contrib [logging :as log]))
|
||||
(:use (clojure.contrib def core))
|
||||
(:import org.jclouds.aws.domain.Region
|
||||
org.jclouds.aws.ec2.domain.AvailabilityZone
|
||||
(org.jclouds.aws.ec2.options DescribeSnapshotsOptions DetachVolumeOptions)))
|
||||
|
||||
(defn #^org.jclouds.aws.ec2.services.ElasticBlockStoreClient
|
||||
ebs-services
|
||||
"Returns the synchronous ElasticBlockStoreClient associated with
|
||||
the specified compute service, or compute/*compute* as bound by with-compute-service."
|
||||
[& [compute]]
|
||||
(-> (or compute compute/*compute*)
|
||||
.getContext .getProviderSpecificContext .getApi .getElasticBlockStoreServices))
|
||||
|
||||
(defn as-region
|
||||
"Returns the first argument as the corresponding Region if it is a
|
||||
keyword or already a Region instance. An optional second argument
|
||||
is returned if the first cannot be coerced into a Region.
|
||||
Returns nil otherwise."
|
||||
[v & [default-region]]
|
||||
(cond
|
||||
(keyword? v) (Region/fromValue (name v))
|
||||
(instance? Region v) v
|
||||
:else default-region))
|
||||
|
||||
(defn describe-volumes
|
||||
"Returns a set of org.jclouds.aws.ec2.domain.Volume instances corresponding to the
|
||||
volumes in the specified region (defaulting to your account's default region).
|
||||
|
||||
e.g. (with-compute-service [compute] (describe-volumes))
|
||||
(with-compute-service [compute] (describe-volumes :us-east-1 \"vol-6b218805\" ...))"
|
||||
[& [region & volume-ids]]
|
||||
(set
|
||||
(.describeVolumesInRegion (ebs-services)
|
||||
(as-region region Region/DEFAULT)
|
||||
(into-array String (if (as-region region)
|
||||
volume-ids
|
||||
(cons region volume-ids))))))
|
||||
|
||||
(defvar- snapshot-options-ops
|
||||
{:ids #(.snapshotIds % (into-array %2))
|
||||
:owners #(.ownedBy % (into-array %2))
|
||||
:restorable-by #(.restorableBy % (into-array %2))})
|
||||
|
||||
(defn- snapshot-options
|
||||
[options-seq]
|
||||
(let [optmap (apply hash-map options-seq)
|
||||
string-array #(let [v (% optmap)]
|
||||
(into-array String (if (string? v) [v] v)))]
|
||||
(-> (DescribeSnapshotsOptions.)
|
||||
(.ownedBy (string-array :owner))
|
||||
(.snapshotIds (string-array :ids))
|
||||
(.restorableBy (string-array :restorable-by)))))
|
||||
|
||||
(defn describe-snapshots
|
||||
"Returns a set of org.jclouds.aws.ec2.domain.Snapshot instances corresponding to the
|
||||
snapshots in the specified region (defaulting to your account's default region)
|
||||
limited according to the further options provided.
|
||||
|
||||
This returns all of the snapshots you own (you can also provide \"amazon\" or an AWS
|
||||
account ID here):
|
||||
(with-compute-service [compute]
|
||||
(describe-snapshots [:owner \"self\"]))
|
||||
|
||||
This returns metadata on the two specified snapshots in us-west-1 (assuming you have access to them):
|
||||
(with-compute-service [compute]
|
||||
(describe-snapshots :us-west-1 [:ids [\"snap-44b3ab2d\" \"snap-9e8821f7\"]]))
|
||||
|
||||
There is also a :restorable-by option. Option values can be provided as strings, or
|
||||
collections of strings."
|
||||
[& [region & option-keyvals]]
|
||||
(let [options (apply snapshot-options
|
||||
(if (as-region region)
|
||||
option-keyvals
|
||||
(cons region option-keyvals)))]
|
||||
(set
|
||||
(.describeSnapshotsInRegion (ebs-services)
|
||||
(as-region region Region/DEFAULT)
|
||||
(into-array DescribeSnapshotsOptions [options])))))
|
||||
|
||||
(defn- as-string
|
||||
[v]
|
||||
(cond
|
||||
(string? v) v
|
||||
(keyword? v) (name v)
|
||||
:else v))
|
||||
(defn- get-string
|
||||
[map key]
|
||||
(as-string (get map key)))
|
||||
(defn- as-int
|
||||
[v]
|
||||
(cond
|
||||
(number? v) (int v)
|
||||
(string? v) (Integer/parseInt v)
|
||||
:else (throw (IllegalArgumentException.
|
||||
(str "Don't know how to convert object of type " (class v) " to a string")))))
|
||||
|
||||
(defn create-volume
|
||||
"Creates a new volume given a set of options. :zone is required, one
|
||||
or both of :size and :snapshot may also be provided; all values can be strings or keywords,
|
||||
:size may be a number, and :zone may be a org.jclouds.aws.ec2.domain.AvailabilityZone.
|
||||
Returns the created org.jclouds.aws.ec2.domain.Volume.
|
||||
|
||||
e.g. (with-compute-service [compute]
|
||||
(create-volume :zone :us-east-1a :size 250)
|
||||
(create-volume :zone :eu-west-1b :snapshot \"snap-252310af\")
|
||||
(create-volume :zone :eu-west-1b :snapshot \"snap-252310af\" :size :1024))"
|
||||
[& options]
|
||||
(when (-> options count odd?)
|
||||
(throw (IllegalArgumentException. "Must provide key-value pairs, e.g. :zone :us-east-1d :size 200")))
|
||||
(let [options (apply hash-map options)
|
||||
snapshot (get-string options :snapshot)
|
||||
size (-?> (get-string options :size) as-int)
|
||||
zone (get-string options :zone)
|
||||
zone (if zone
|
||||
(if (instance? AvailabilityZone zone)
|
||||
zone
|
||||
(AvailabilityZone/fromValue zone))
|
||||
(throw (IllegalArgumentException. "Must supply a :zone option.")))
|
||||
ebs (ebs-services)]
|
||||
(cond
|
||||
(and snapshot size) (.createVolumeFromSnapshotInAvailabilityZone ebs zone size snapshot)
|
||||
snapshot (.createVolumeFromSnapshotInAvailabilityZone ebs zone snapshot)
|
||||
size (.createVolumeInAvailabilityZone ebs zone size)
|
||||
:else (throw (IllegalArgumentException. "Must supply :size and/or :snapshot options.")))))
|
||||
|
||||
(defn delete-volume
|
||||
"Deletes a volume in the specified region.
|
||||
|
||||
e.g. (with-compute-service [compute]
|
||||
(delete-volume :us-east-1 :vol-45228a6d)
|
||||
(delete-volume :us-east-1 \"vol-052b846c\"))"
|
||||
[region volume-id]
|
||||
(.deleteVolumeInRegion (ebs-services)
|
||||
(as-region region)
|
||||
(as-string volume-id)))
|
||||
|
||||
(defn attach-volume
|
||||
"Attaches a volume to an instance, returning the resulting org.jclouds.aws.ec2.domain.Attachment.
|
||||
The region must be a keyword or Region instance; the remaining parameters may be
|
||||
strings or keywords.
|
||||
|
||||
e.g. (with-compute-service [compute]
|
||||
(attach-volume :us-east-1 :vol-45228a6d \"i-a92358c1\" \"/dev/sdh\"))"
|
||||
[region & [volume-id instance-id device :as options]]
|
||||
(apply #(.attachVolumeInRegion (ebs-services)
|
||||
(as-region region) % %2 %3)
|
||||
(map as-string options)))
|
||||
|
||||
(defn detach-volume
|
||||
"Detatches a volume from the instance to which it is currently attached.
|
||||
The optional force? parameter, if logically true, will cause the volume to be forcibly
|
||||
detached, regardless of whether it is in-use (mounted) or not.
|
||||
|
||||
(It appears that issuing a detatch-volume command while the volume in question is mounted
|
||||
will cause the volume to be detatched immediately upon the volume beign unmounted."
|
||||
[region volume-id & [force?]]
|
||||
(.detachVolumeInRegion (ebs-services)
|
||||
(as-region region)
|
||||
(as-string volume-id)
|
||||
(boolean force?)
|
||||
(into-array DetachVolumeOptions [])))
|
Loading…
Reference in New Issue