You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltacloud.apache.org by lu...@redhat.com on 2011/08/23 06:53:57 UTC

[PATCH 2/2] mock driver: split into driver and client

From: David Lutterkort <lu...@redhat.com>

This rewrite takes care of a number of issues with the driver (e.g., newly
created blobs would not show up in the bucket), and cleans up the code so
that it hopefully becomes clearer what driver writers need to do.

The driver now also uses the objects stored in the file system verbatim,
instead of modifying loaded objects on read.

Signed-off-by: David Lutterkort <lu...@redhat.com>
---
 .../deltacloud/drivers/mock/data/blobs/blob1.yml   |   10 +
 .../deltacloud/drivers/mock/data/blobs/blob2.yml   |   10 +
 .../deltacloud/drivers/mock/data/blobs/blob3.yml   |    9 +
 .../deltacloud/drivers/mock/data/blobs/blob4.yml   |   10 +
 .../deltacloud/drivers/mock/data/blobs/blob5.yml   |    9 +
 .../drivers/mock/data/buckets/blobs/blob1.yml      |    8 -
 .../drivers/mock/data/buckets/blobs/blob2.yml      |    8 -
 .../drivers/mock/data/buckets/blobs/blob3.yml      |    7 -
 .../drivers/mock/data/buckets/blobs/blob4.yml      |    8 -
 .../drivers/mock/data/buckets/blobs/blob5.yml      |    7 -
 .../drivers/mock/data/buckets/bucket1.yml          |    8 +-
 .../drivers/mock/data/buckets/bucket2.yml          |    7 +-
 .../deltacloud/drivers/mock/data/images/img1.yml   |    8 +-
 .../deltacloud/drivers/mock/data/images/img2.yml   |    8 +-
 .../deltacloud/drivers/mock/data/images/img3.yml   |    8 +-
 .../drivers/mock/data/instances/inst0.yml          |   21 +-
 .../drivers/mock/data/instances/inst1.yml          |   21 ++-
 .../drivers/mock/data/instances/inst2.yml          |   21 ++-
 .../drivers/mock/data/storage_snapshots/snap1.yml  |    5 +-
 .../drivers/mock/data/storage_snapshots/snap2.yml  |    5 +-
 .../drivers/mock/data/storage_snapshots/snap3.yml  |    5 +-
 .../drivers/mock/data/storage_volumes/vol1.yml     |    7 +-
 .../drivers/mock/data/storage_volumes/vol2.yml     |    7 +-
 .../drivers/mock/data/storage_volumes/vol3.yml     |    7 +-
 server/lib/deltacloud/drivers/mock/mock_client.rb  |  101 ++++++++++
 server/lib/deltacloud/drivers/mock/mock_driver.rb  |  198 ++++++--------------
 26 files changed, 298 insertions(+), 225 deletions(-)
 create mode 100644 server/lib/deltacloud/drivers/mock/data/blobs/blob1.yml
 create mode 100644 server/lib/deltacloud/drivers/mock/data/blobs/blob2.yml
 create mode 100644 server/lib/deltacloud/drivers/mock/data/blobs/blob3.yml
 create mode 100644 server/lib/deltacloud/drivers/mock/data/blobs/blob4.yml
 create mode 100644 server/lib/deltacloud/drivers/mock/data/blobs/blob5.yml
 delete mode 100644 server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob1.yml
 delete mode 100644 server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob2.yml
 delete mode 100644 server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob3.yml
 delete mode 100644 server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob4.yml
 delete mode 100644 server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob5.yml
 create mode 100644 server/lib/deltacloud/drivers/mock/mock_client.rb

diff --git a/server/lib/deltacloud/drivers/mock/data/blobs/blob1.yml b/server/lib/deltacloud/drivers/mock/data/blobs/blob1.yml
new file mode 100644
index 0000000..6ff9cfb
--- /dev/null
+++ b/server/lib/deltacloud/drivers/mock/data/blobs/blob1.yml
@@ -0,0 +1,10 @@
+---
+:content_length: 17
+:content_type: text/plain
+:last_modified: 2010-09-23 16:44:54 +0100
+:content: content of blob 1
+:name: blob1
+:user_metadata:
+  SOMENEWKEY: NEWVALUE
+:bucket: bucket1
+:id: blob1
diff --git a/server/lib/deltacloud/drivers/mock/data/blobs/blob2.yml b/server/lib/deltacloud/drivers/mock/data/blobs/blob2.yml
new file mode 100644
index 0000000..18aba74
--- /dev/null
+++ b/server/lib/deltacloud/drivers/mock/data/blobs/blob2.yml
@@ -0,0 +1,10 @@
+---
+:content_length: 56
+:content_type: text/html
+:last_modified: 2010-09-23 16:55:05 +0100
+:content: <html><head></head><body>content of blob 2</body></html>
+:name: blob2
+:user_metadata:
+  VERSION: "1.2"
+:bucket: bucket1
+:id: blob2
diff --git a/server/lib/deltacloud/drivers/mock/data/blobs/blob3.yml b/server/lib/deltacloud/drivers/mock/data/blobs/blob3.yml
new file mode 100644
index 0000000..e2a4e65
--- /dev/null
+++ b/server/lib/deltacloud/drivers/mock/data/blobs/blob3.yml
@@ -0,0 +1,9 @@
+---
+:content_length: 17
+:content_type: text/plain
+:last_modified: 2010-08-14 02:14:31 +0100
+:content: content of blob 3
+:name: blob3
+:user_metadata: ""
+:bucket: bucket1
+:id: blob3
diff --git a/server/lib/deltacloud/drivers/mock/data/blobs/blob4.yml b/server/lib/deltacloud/drivers/mock/data/blobs/blob4.yml
new file mode 100644
index 0000000..f9f2c34
--- /dev/null
+++ b/server/lib/deltacloud/drivers/mock/data/blobs/blob4.yml
@@ -0,0 +1,10 @@
+---
+:content_length: 17
+:content_type: application/octet-stream
+:last_modified: 2010-09-21 06:17:24 +0100
+:content: content of blob 4
+:name: blob4
+:user_metadata:
+  some: value
+:bucket: bucket2
+:id: blob4
diff --git a/server/lib/deltacloud/drivers/mock/data/blobs/blob5.yml b/server/lib/deltacloud/drivers/mock/data/blobs/blob5.yml
new file mode 100644
index 0000000..f2b144a
--- /dev/null
+++ b/server/lib/deltacloud/drivers/mock/data/blobs/blob5.yml
@@ -0,0 +1,9 @@
+---
+:content_length: 17
+:content_type: application/pdf
+:last_modified: 2009-07-21 11:12:13 +0100
+:content: content of blob 5
+:name: blob5
+:user_metadata: ""
+:id: blob5
+:bucket: bucket2
diff --git a/server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob1.yml b/server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob1.yml
deleted file mode 100644
index cf119bc..0000000
--- a/server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob1.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-:content_type: text/plain
-:content_length: 17
-:bucket: bucket1
-:user_metadata:
-  SOMENEWKEY: NEWVALUE
-:last_modified: 2010-09-23 16:44:54 +0100
-:content: content of blob 1
diff --git a/server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob2.yml b/server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob2.yml
deleted file mode 100644
index 431ad69..0000000
--- a/server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob2.yml
+++ /dev/null
@@ -1,8 +0,0 @@
---- 
-:user_metadata: 
-  VERSION: "1.2"
-:content_type: text/html
-:content_length: 56
-:bucket: bucket1
-:last_modified: 2010-09-23 16:55:05 +0100
-:content: <html><head></head><body>content of blob 2</body></html>
diff --git a/server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob3.yml b/server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob3.yml
deleted file mode 100644
index f0a4d12..0000000
--- a/server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob3.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-:bucket: bucket1
-:content_length: 17
-:content_type: text/plain
-:last_modified: 2010-08-14 02:14:31 +0100
-:content:
-    content of blob 3
-:user_metadata: ''
\ No newline at end of file
diff --git a/server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob4.yml b/server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob4.yml
deleted file mode 100644
index 0dbeef1..0000000
--- a/server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob4.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-:bucket: bucket2
-:content_length: 17
-:content_type: application/octet-stream
-:last_modified: 2010-09-21 06:17:24 +0100
-:content:
-    content of blob 4
-:user_metadata:
-    some: "value"
\ No newline at end of file
diff --git a/server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob5.yml b/server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob5.yml
deleted file mode 100644
index fac8fce..0000000
--- a/server/lib/deltacloud/drivers/mock/data/buckets/blobs/blob5.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-:bucket: bucket2
-:content_length: 17
-:content_type: application/pdf
-:last_modified: 2009-07-21 11:12:13 +0100
-:content:
-    content of blob 5
-:user_metadata: ''
\ No newline at end of file
diff --git a/server/lib/deltacloud/drivers/mock/data/buckets/bucket1.yml b/server/lib/deltacloud/drivers/mock/data/buckets/bucket1.yml
index d97f2c0..5d2c694 100644
--- a/server/lib/deltacloud/drivers/mock/data/buckets/bucket1.yml
+++ b/server/lib/deltacloud/drivers/mock/data/buckets/bucket1.yml
@@ -1,2 +1,8 @@
-:blob_list: [blob1, blob2, blob3]
+---
+:blob_list:
+- blob1
+- blob2
+- blob3
 :size: 3
+:name: bucket1
+:id: bucket1
diff --git a/server/lib/deltacloud/drivers/mock/data/buckets/bucket2.yml b/server/lib/deltacloud/drivers/mock/data/buckets/bucket2.yml
index 2e9abe9..26ec204 100644
--- a/server/lib/deltacloud/drivers/mock/data/buckets/bucket2.yml
+++ b/server/lib/deltacloud/drivers/mock/data/buckets/bucket2.yml
@@ -1,2 +1,7 @@
-:blob_list: [blob4, blob5]
+---
+:blob_list:
+- blob4
+- blob5
 :size: 2
+:name: bucket2
+:id: bucket2
diff --git a/server/lib/deltacloud/drivers/mock/data/images/img1.yml b/server/lib/deltacloud/drivers/mock/data/images/img1.yml
index 9e56d25..1b641b4 100644
--- a/server/lib/deltacloud/drivers/mock/data/images/img1.yml
+++ b/server/lib/deltacloud/drivers/mock/data/images/img1.yml
@@ -1,3 +1,7 @@
-:description: Fedora 10
-:owner_id: fedoraproject
+---
 :architecture: x86_64
+:owner_id: fedoraproject
+:state: AVAILABLE
+:id: img1
+:name: img1
+:description: Fedora 10
diff --git a/server/lib/deltacloud/drivers/mock/data/images/img2.yml b/server/lib/deltacloud/drivers/mock/data/images/img2.yml
index df8ffa6..1aa77cc 100644
--- a/server/lib/deltacloud/drivers/mock/data/images/img2.yml
+++ b/server/lib/deltacloud/drivers/mock/data/images/img2.yml
@@ -1,3 +1,7 @@
-:description: Fedora 10
-:owner_id: fedoraproject
+---
 :architecture: i386
+:owner_id: fedoraproject
+:state: AVAILABLE
+:id: img2
+:name: img2
+:description: Fedora 10
diff --git a/server/lib/deltacloud/drivers/mock/data/images/img3.yml b/server/lib/deltacloud/drivers/mock/data/images/img3.yml
index a6b82a6..3afb116 100644
--- a/server/lib/deltacloud/drivers/mock/data/images/img3.yml
+++ b/server/lib/deltacloud/drivers/mock/data/images/img3.yml
@@ -1,3 +1,7 @@
-:description: JBoss
-:owner_id: mockuser
+---
 :architecture: i386
+:owner_id: mockuser
+:state: AVAILABLE
+:id: img3
+:name: img3
+:description: JBoss
diff --git a/server/lib/deltacloud/drivers/mock/data/instances/inst0.yml b/server/lib/deltacloud/drivers/mock/data/instances/inst0.yml
index d5f9fae..447a99c 100644
--- a/server/lib/deltacloud/drivers/mock/data/instances/inst0.yml
+++ b/server/lib/deltacloud/drivers/mock/data/instances/inst0.yml
@@ -1,17 +1,18 @@
 ---
-:realm_id: us
-:public_addresses:
-- img1.inst0.public.com
-:state: RUNNING
-:name: "Mock Instance With Profile Change"
-:private_addresses:
-- img1.inst0.private.com
-:image_id: img1
 :instance_profile: !ruby/object:InstanceProfile
-  id: m1-large
   memory: "12288"
-:owner_id: mockuser
+  id: m1-large
+:realm_id: us
 :actions:
 - :reboot
 - :stop
+:owner_id: mockuser
+:public_addresses:
+- img1.inst0.public.com
+:private_addresses:
+- img1.inst0.private.com
 :create_image: true
+:image_id: img1
+:name: Mock Instance With Profile Change
+:id: inst0
+:state: RUNNING
diff --git a/server/lib/deltacloud/drivers/mock/data/instances/inst1.yml b/server/lib/deltacloud/drivers/mock/data/instances/inst1.yml
index 746daa2..f0bed5c 100644
--- a/server/lib/deltacloud/drivers/mock/data/instances/inst1.yml
+++ b/server/lib/deltacloud/drivers/mock/data/instances/inst1.yml
@@ -1,10 +1,17 @@
-:name: MockUserInstance
-:state: RUNNING
-:image_id: img3
-:owner_id: mockuser
-:public_addresses: [ img3.inst1.public.com ]
-:private_addresses: [ img3.inst1.private.com ]
-:realm_id: us
+---
 :instance_profile: !ruby/object:InstanceProfile
   id: m1-small
+:realm_id: us
+:owner_id: mockuser
+:public_addresses:
+- img3.inst1.public.com
+:private_addresses:
+- img3.inst1.private.com
 :create_image: true
+:image_id: img3
+:name: MockUserInstance
+:id: inst1
+:state: RUNNING
+:actions:
+- :reboot
+- :stop
diff --git a/server/lib/deltacloud/drivers/mock/data/instances/inst2.yml b/server/lib/deltacloud/drivers/mock/data/instances/inst2.yml
index 662bbb9..a6fcd43 100644
--- a/server/lib/deltacloud/drivers/mock/data/instances/inst2.yml
+++ b/server/lib/deltacloud/drivers/mock/data/instances/inst2.yml
@@ -1,10 +1,17 @@
-:name: AnotherInstance
-:state: RUNNING
-:image_id: img1
-:owner_id: anotheruser
-:public_addresses: [ img1.inst2.public.com ]
-:private_addresses: [ img1.inst2.private.com ]
-:realm_id: us
+---
 :instance_profile: !ruby/object:InstanceProfile
   id: m1-large
+:realm_id: us
+:owner_id: anotheruser
+:public_addresses:
+- img1.inst2.public.com
+:private_addresses:
+- img1.inst2.private.com
 :create_image: true
+:image_id: img1
+:name: AnotherInstance
+:id: inst2
+:state: RUNNING
+:actions:
+- :reboot
+- :stop
diff --git a/server/lib/deltacloud/drivers/mock/data/storage_snapshots/snap1.yml b/server/lib/deltacloud/drivers/mock/data/storage_snapshots/snap1.yml
index 180a2c7..c7fa9b1 100644
--- a/server/lib/deltacloud/drivers/mock/data/storage_snapshots/snap1.yml
+++ b/server/lib/deltacloud/drivers/mock/data/storage_snapshots/snap1.yml
@@ -1,4 +1,5 @@
-:owner_id: fedoraproject
+---
 :created: Wed Jul 29 18:15:24 UTC 2009
-:state: COMPLETED
 :storage_volume_id: vol1
+:id: snap1
+:state: COMPLETED
diff --git a/server/lib/deltacloud/drivers/mock/data/storage_snapshots/snap2.yml b/server/lib/deltacloud/drivers/mock/data/storage_snapshots/snap2.yml
index f68c8ce..d164dac 100644
--- a/server/lib/deltacloud/drivers/mock/data/storage_snapshots/snap2.yml
+++ b/server/lib/deltacloud/drivers/mock/data/storage_snapshots/snap2.yml
@@ -1,4 +1,5 @@
-:owner_id: mockuser
+---
 :created: Wed Jul 29 18:15:24 UTC 2009
-:state: COMPLETED
 :storage_volume_id: vol2
+:id: snap2
+:state: COMPLETED
diff --git a/server/lib/deltacloud/drivers/mock/data/storage_snapshots/snap3.yml b/server/lib/deltacloud/drivers/mock/data/storage_snapshots/snap3.yml
index f68c8ce..5f308de 100644
--- a/server/lib/deltacloud/drivers/mock/data/storage_snapshots/snap3.yml
+++ b/server/lib/deltacloud/drivers/mock/data/storage_snapshots/snap3.yml
@@ -1,4 +1,5 @@
-:owner_id: mockuser
+---
 :created: Wed Jul 29 18:15:24 UTC 2009
-:state: COMPLETED
 :storage_volume_id: vol2
+:id: snap3
+:state: COMPLETED
diff --git a/server/lib/deltacloud/drivers/mock/data/storage_volumes/vol1.yml b/server/lib/deltacloud/drivers/mock/data/storage_volumes/vol1.yml
index a577b65..b582dcb 100644
--- a/server/lib/deltacloud/drivers/mock/data/storage_volumes/vol1.yml
+++ b/server/lib/deltacloud/drivers/mock/data/storage_volumes/vol1.yml
@@ -1,7 +1,8 @@
-:owner_id: fedoraproject
+---
 :realm_id: us
-:created: Thu Jul 30 14:35:11 UTC 2009
-:state: AVAILABLE
 :capacity: 1
 :device:
+:created: Thu Jul 30 14:35:11 UTC 2009
 :instance_id:
+:id: vol1
+:state: AVAILABLE
diff --git a/server/lib/deltacloud/drivers/mock/data/storage_volumes/vol2.yml b/server/lib/deltacloud/drivers/mock/data/storage_volumes/vol2.yml
index 697a48e..eb60b99 100644
--- a/server/lib/deltacloud/drivers/mock/data/storage_volumes/vol2.yml
+++ b/server/lib/deltacloud/drivers/mock/data/storage_volumes/vol2.yml
@@ -1,7 +1,8 @@
-:owner_id: mockuser
+---
 :realm_id: us
-:created: Thu Jul 30 14:35:11 UTC 2009
-:state: AVAILABLE
 :capacity: 1
 :device:
+:created: Thu Jul 30 14:35:11 UTC 2009
 :instance_id:
+:id: vol2
+:state: AVAILABLE
diff --git a/server/lib/deltacloud/drivers/mock/data/storage_volumes/vol3.yml b/server/lib/deltacloud/drivers/mock/data/storage_volumes/vol3.yml
index c8f0de8..b5bc8c2 100644
--- a/server/lib/deltacloud/drivers/mock/data/storage_volumes/vol3.yml
+++ b/server/lib/deltacloud/drivers/mock/data/storage_volumes/vol3.yml
@@ -1,7 +1,8 @@
-:owner_id: mockuser
+---
 :realm_id: us
-:created: Thu Jul 30 14:35:11 UTC 2009
-:state: IN-USE
 :capacity: 1
 :device: /dev/sda1
+:created: Thu Jul 30 14:35:11 UTC 2009
 :instance_id: inst1
+:id: vol3
+:state: IN-USE
diff --git a/server/lib/deltacloud/drivers/mock/mock_client.rb b/server/lib/deltacloud/drivers/mock/mock_client.rb
new file mode 100644
index 0000000..96157cd
--- /dev/null
+++ b/server/lib/deltacloud/drivers/mock/mock_client.rb
@@ -0,0 +1,101 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF 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.
+
+# The mock client does a bunch of filesystem judo. It's mostly there to
+# keep the driver from looking too ugly with all the File I/O
+
+module Deltacloud::Drivers::Mock
+
+  class Client
+    def initialize(storage_root)
+      @storage_root = storage_root
+      @collections = []
+
+      if ! File::directory?(@storage_root)
+        FileUtils::rm_rf(@storage_root)
+        FileUtils::mkdir_p(@storage_root)
+        data = Dir[File::join(File::dirname(__FILE__), "data", "*")]
+        FileUtils::cp_r(data, @storage_root)
+      end
+    end
+
+    def dir(collection)
+      result = File::join(@storage_root, collection.to_s)
+      unless @collections.include?(collection)
+        FileUtils::mkdir_p(result) unless File::directory?(result)
+        @collections << collection
+      end
+      result
+    end
+
+    def file(collection, id)
+      File::join(dir(collection), "#{id}.yml")
+    end
+
+    def files(collection)
+      Dir[File::join(dir(collection), "*.yml")]
+    end
+
+    # Return the ID's of all members of +collection+
+    def members(collection)
+      files(collection).map { |f| File::basename(f, ".yml") }
+    end
+
+    def load(collection, id)
+      fname = file(collection, id)
+      begin
+        YAML.load(File.read(fname))
+      rescue Errno::ENOENT
+        nil
+      end
+    end
+
+    def store(collection, obj)
+      raise "Why no obj[:id] ?" unless obj[:id]
+      File::open(file(collection, obj[:id]), "w") { |f| YAML.dump(obj, f) }
+    end
+
+    # Return the object with id +id+ of class +klass+ from the collection
+    # derived from the classes name
+    def build(klass, id)
+      klass.new(load(collection_name(klass), id))
+    end
+
+    # Return an array of hashes of all the resources in the collection
+    def load_all(collection)
+      members(collection).map { |id| load(collection, id) }
+    end
+
+    # Return an array of model objects of the resources in the collection
+    # corresponding to class. The name of the collection is derived from
+    # the name of the class
+    def build_all(klass)
+      load_all(collection_name(klass)).map { |hash| klass.new(hash) }
+    end
+
+    def destroy(collection, id)
+      fname = file(collection, id)
+      FileUtils.rm(fname) if File::exists?(fname)
+    end
+
+    private
+
+    def collection_name(klass)
+      klass.name.underscore.pluralize
+    end
+  end
+
+end
diff --git a/server/lib/deltacloud/drivers/mock/mock_driver.rb b/server/lib/deltacloud/drivers/mock/mock_driver.rb
index d328ffb..47e8d98 100644
--- a/server/lib/deltacloud/drivers/mock/mock_driver.rb
+++ b/server/lib/deltacloud/drivers/mock/mock_driver.rb
@@ -17,6 +17,7 @@
 
 require 'deltacloud/base_driver'
 require 'yaml'
+require 'deltacloud/drivers/mock/mock_client'
 
 module Deltacloud::Drivers::Mock
 
@@ -87,18 +88,13 @@ module Deltacloud::Drivers::Mock
 
     def initialize
       if ENV["DELTACLOUD_MOCK_STORAGE"]
-        @storage_root = ENV["DELTACLOUD_MOCK_STORAGE"]
+        storage_root = ENV["DELTACLOUD_MOCK_STORAGE"]
       elsif ENV["USER"]
-        @storage_root = File::join("/var/tmp", "deltacloud-mock-#{ENV["USER"]}")
+        storage_root = File::join("/var/tmp", "deltacloud-mock-#{ENV["USER"]}")
       else
         raise "Please set either the DELTACLOUD_MOCK_STORAGE or USER environment variable"
       end
-      if ! File::directory?(@storage_root)
-        FileUtils::rm_rf(@storage_root)
-        FileUtils::mkdir_p(@storage_root)
-        data = Dir::glob(File::join(File::dirname(__FILE__), "data", "*"))
-        FileUtils::cp_r(data, @storage_root)
-      end
+      @client = Client.new(storage_root)
     end
 
     def realms(credentials, opts=nil)
@@ -114,13 +110,7 @@ module Deltacloud::Drivers::Mock
     def images(credentials, opts=nil )
       check_credentials( credentials )
       images = []
-      Dir[ "#{@storage_root}/images/*.yml" ].each do |image_file|
-        image = YAML.load( File.read( image_file ) )
-        image[:id] = File.basename( image_file, ".yml" )
-        image[:name] = image[:description]
-        image[:state] = "AVAILABLE"
-        images << Image.new( image )
-      end
+      images = @client.build_all(Image)
       images = filter_on( images, :id, opts )
       images = filter_on( images, :architecture, opts )
       if ( opts && opts[:owner_id] == 'self' )
@@ -138,22 +128,20 @@ module Deltacloud::Drivers::Mock
         raise 'CreateImageNotSupported' unless instance and instance.can_create_image?
         image = {
           :id => opts[:name],
-	      :name => opts[:name],
-	      :owner_id => 'root',
+          :name => opts[:name],
+          :owner_id => 'root',
+          :state => "AVAILABLE",
           :description => opts[:description],
-          :architecture => 'i386',
-          :state => 'UP'
+          :architecture => 'i386'
         }
-        File.open( "#{@storage_root}/images/#{opts[:name]}.yml", 'w' ) do |f|
-          YAML.dump( image, f )
-        end
+        @client.store(:images, image)
         Image.new(image)
       end
     end
 
     def destroy_image(credentials, id)
       check_credentials( credentials )
-      FileUtils.rm( "#{@storage_root}/images/#{id}.yml" )
+      @client.destroy(:images, id)
     end
 
     #
@@ -162,25 +150,15 @@ module Deltacloud::Drivers::Mock
 
     def instance(credentials, opts={})
       check_credentials( credentials )
-      instance_filename = File.join(@storage_root, 'instances', "#{opts[:id]}.yml")
-      return nil unless File.exists?(instance_filename)
-      instance = YAML::load_file(instance_filename)
-      instance[:actions] = instance_actions_for( instance[:state] )
-      instance[:id] = File::basename(instance_filename, ".yml")
-      Instance.new(instance)
+      if instance = @client.load(:instances, opts[:id])
+        Instance.new(instance)
+      end
     end
 
     def instances(credentials, opts=nil)
       check_credentials( credentials )
-      instances = []
-      Dir[ "#{@storage_root}/instances/*.yml" ].each do |instance_file|
-        instance = YAML::load_file(instance_file)
-        if ( instance[:owner_id] == credentials.user )
-          instance[:id] = File.basename( instance_file, ".yml" )
-          instance[:actions] = instance_actions_for( instance[:state] )
-          instances << Instance.new( instance )
-        end
-      end
+      instances = @client.build_all(Instance)
+      instances = filter_on( instances, :owner_id, :owner_id => credentials.user )
       instances = filter_on( instances, :id, opts )
       instances = filter_on( instances, :state, opts )
       instances
@@ -188,7 +166,7 @@ module Deltacloud::Drivers::Mock
 
     def create_instance(credentials, image_id, opts)
       check_credentials( credentials )
-      ids = Dir[ "#{@storage_root}/instances/*.yml" ].collect{|e| File.basename( e, ".yml" )}
+      ids = @client.members(:instances)
 
       count = 0
       while true
@@ -210,6 +188,7 @@ module Deltacloud::Drivers::Mock
       name = opts[:name] || "i-#{Time.now.to_i}"
 
       instance = {
+        :id => next_id,
         :name=>name,
         :state=>'RUNNING',
         :keyname => opts[:keyname],
@@ -223,23 +202,16 @@ module Deltacloud::Drivers::Mock
         :actions=>instance_actions_for( 'RUNNING' ),
         :user_data => opts[:user_data]
       }
-      File.open( "#{@storage_root}/instances/#{next_id}.yml", 'w' ) {|f|
-        YAML.dump( instance, f )
-      }
-      instance[:id] = next_id
+      @client.store(:instances, instance)
       Instance.new( instance )
     end
 
     def update_instance_state(credentials, id, state)
-      instance_file = "#{@storage_root}/instances/#{id}.yml"
-      instance_yml  = YAML.load( File.read( instance_file ) )
-      instance_yml[:id] = id
-      instance_yml[:state] = state
-      instance_yml[:actions] = instance_actions_for( instance_yml[:state] )
-      File.open( instance_file, 'w' ) do |f|
-        f << YAML.dump( instance_yml )
-      end
-      Instance.new( instance_yml )
+      instance  = @client.load(:instances, id)
+      instance[:state] = state
+      instance[:actions] = instance_actions_for( instance[:state] )
+      @client.store(:instances, instance)
+      Instance.new( instance )
     end
 
     def start_instance(credentials, id)
@@ -257,7 +229,7 @@ module Deltacloud::Drivers::Mock
 
     def destroy_instance(credentials, id)
       check_credentials( credentials )
-      FileUtils.rm( "#{@storage_root}/instances/#{id}.yml" )
+      @client.destroy(:instances, id)
     end
 
     #
@@ -266,14 +238,7 @@ module Deltacloud::Drivers::Mock
 
     def storage_volumes(credentials, opts=nil)
       check_credentials( credentials )
-      volumes = []
-      Dir[ "#{@storage_root}/storage_volumes/*.yml" ].each do |storage_volume_file|
-        storage_volume = YAML.load( File.read( storage_volume_file ) )
-        if ( storage_volume[:owner_id] == credentials.user )
-          storage_volume[:id] = File.basename( storage_volume_file, ".yml" )
-          volumes << StorageVolume.new( storage_volume )
-        end
-      end
+      volumes = @client.build_all(StorageVolume)
       volumes = filter_on( volumes, :id, opts )
       volumes
     end
@@ -284,25 +249,14 @@ module Deltacloud::Drivers::Mock
 
     def storage_snapshots(credentials, opts=nil)
       check_credentials( credentials )
-      snapshots = []
-      Dir[ "#{@storage_root}/storage_snapshots/*.yml" ].each do |storage_snapshot_file|
-        storage_snapshot = YAML.load( File.read( storage_snapshot_file ) )
-        if ( storage_snapshot[:owner_id] == credentials.user )
-          storage_snapshot[:id] = File.basename( storage_snapshot_file, ".yml" )
-          snapshots << StorageSnapshot.new( storage_snapshot )
-        end
-      end
-      snapshots = filter_on( snapshots, :id, opts )
+      snapshots = @client.build_all(StorageSnapshot)
+      snapshots = filter_on(snapshots, :id, opts )
       snapshots
     end
 
     def keys(credentials, opts={})
       check_credentials(credentials)
-      result = []
-      key_dir = File.join(@storage_root, 'keys')
-      Dir[key_dir + '/*.yml'].each do |key_file|
-        result << Key.new(YAML::load(File.read(key_file)))
-      end
+      result = @client.build_all(Key)
       result = filter_on( result, :id, opts )
       result
     end
@@ -319,23 +273,15 @@ module Deltacloud::Drivers::Mock
         :fingerprint => Key::generate_mock_fingerprint,
         :pem_rsa_key => Key::generate_mock_pem
       }
-      key_dir = File.join(@storage_root, 'keys')
-      if File.exists?(key_dir + "/#{key_hash[:id]}.yml")
-        raise "KeyExist"
-      end
-      FileUtils.mkdir_p(key_dir) unless File.directory?(key_dir)
-      File.open(key_dir + "/#{key_hash[:id]}.yml", 'w') do |f|
-        f.puts(YAML::dump(key_hash))
-      end
+
+      raise "KeyExist" if @client.load(:keys, key_hash[:id])
+      @client.store(:keys, key_hash)
       return Key.new(key_hash)
     end
 
     def destroy_key(credentials, opts={})
       key = key(credentials, opts)
-      safely do
-        key_dir = File.join(@storage_root, 'keys')
-        File.delete(key_dir + "/#{key.id}.yml")
-      end
+      @client.destroy(:keys, key.id)
     end
 
     #--
@@ -343,22 +289,14 @@ module Deltacloud::Drivers::Mock
     #--
     def buckets(credentials, opts={})
       check_credentials(credentials)
-      buckets=[]
-      safely do
-        unless (opts[:id].nil?)
-          bucket_file = File::join(@storage_root, 'buckets', "#{opts[:id]}.yml")
-          bucket = YAML.load_file(bucket_file)
-          bucket[:id] = opts[:id]
-          bucket[:name] = bucket[:id]
-          buckets << Bucket.new( bucket )
-        else
-          Dir[ File::join(@storage_root, 'buckets', '*.yml')].each do |bucket_file|
-            bucket_id = File.basename( bucket_file, ".yml" )
-            buckets << Bucket.new( {:id => bucket_id, :name => bucket_id } )
-          end
-        end
+      buckets = @client.build_all(Bucket)
+      blob_map = @client.load_all(:blobs).inject({}) do |map, blob|
+        map[blob[:bucket]] ||= []
+        map[blob[:bucket]] << blob[:id]
+        map
       end
-      buckets = filter_on( buckets, :id, opts )
+      buckets.each { |bucket| bucket.blob_list = blob_map[bucket.id] }
+      filter_on( buckets, :id, opts )
     end
 
     #--
@@ -372,7 +310,7 @@ module Deltacloud::Drivers::Mock
         :size=>'0',
         :blob_list=>[]
       }
-      File.open( File::join(@storage_root, 'buckets', "#{name}.yml"), 'w') {|b| YAML.dump( bucket, b )}
+      @client.store(:buckets, bucket)
       Bucket.new(bucket)
     end
 
@@ -382,12 +320,8 @@ module Deltacloud::Drivers::Mock
     def delete_bucket(credentials, name, opts={})
       check_credentials(credentials)
       bucket = bucket(credentials, {:id => name})
-      unless (bucket.size == "0")
-        raise "BucketNotEmpty"
-      end
-      safely do
-        File.delete(File::join(@storage_root, 'buckets', "#{name}.yml"))
-      end
+      raise "BucketNotEmpty" unless (bucket.size == "0")
+      @client.destroy(:buckets, bucket.id)
     end
 
     #--
@@ -395,16 +329,9 @@ module Deltacloud::Drivers::Mock
     #--
     def blobs(credentials, opts = {})
       check_credentials(credentials)
-      blobs=[]
-      blobfile = File::join("#{@storage_root}", "buckets", "blobs", "#{opts[:id]}.yml")
-      safely do
-        blob = YAML.load_file(blobfile)
-        return [] unless blob[:bucket] == opts['bucket'] #can't return nil since base_driver invokes .first on return
-        blob[:id] = File.basename( blobfile, ".yml" )
-        blob[:name] = blob[:id]
-        blobs << Blob.new( blob )
-        blobs = filter_on( blobs, :id, opts )
-      end
+      blobs = @client.build_all(Blob)
+      filter_on( blobs, :bucket, :bucket => opts['bucket'] )
+      filter_on( blobs, :id, opts )
     end
 
     #--
@@ -412,12 +339,9 @@ module Deltacloud::Drivers::Mock
     #--
     def blob_data(credentials, bucket_id, blob_id, opts = {})
       check_credentials(credentials)
-      blob=nil
-      safely do
-        blobfile = File::join("#{@storage_root}", "buckets", "blobs", "#{opts['blob']}.yml")
-        blob = YAML.load_file(blobfile)
+      if blob = @client.load(:blobs, blob_id)
+        blob[:content].each {|part| yield part}
       end
-      blob[:content].each {|part| yield part}
     end
 
     #--
@@ -428,6 +352,7 @@ module Deltacloud::Drivers::Mock
       blob_meta = BlobHelper::extract_blob_metadata_hash(opts)
       blob = {
         :id => blob_id,
+        :name => blob_id,
         :bucket => bucket_id,
         :content_length => blob_data[:tempfile].length,
         :content_type => blob_data[:type],
@@ -435,7 +360,7 @@ module Deltacloud::Drivers::Mock
         :user_metadata => BlobHelper::rename_metadata_headers(blob_meta, ''),
         :content => blob_data[:tempfile].read
       }
-      File.open( File::join("#{@storage_root}", "buckets", "blobs", "#{blob_id}.yml"), 'w' ) {|b| YAML.dump( blob, b )}
+      @client.store(:blobs, blob)
       Blob.new(blob)
     end
 
@@ -444,12 +369,9 @@ module Deltacloud::Drivers::Mock
     #--
     def delete_blob(credentials, bucket_id, blob_id, opts={})
       check_credentials(credentials)
-      blobfile = File::join("#{@storage_root}", "buckets", "blobs", "#{blob_id}.yml")
       safely do
-        unless File.exists?(blobfile)
-          raise "NotExistentBlob"
-        end
-        File.delete(blobfile)
+        raise "NotExistentBlob" unless @client.load(:blobs, blob_id)
+        @client.destroy(:blobs, blob_id)
       end
     end
 
@@ -458,14 +380,11 @@ module Deltacloud::Drivers::Mock
     #--
     def blob_metadata(credentials, opts={})
       check_credentials(credentials)
-      blobfile = File::join("#{@storage_root}", "buckets", "blobs", "#{opts[:id]}.yml")
-      #safely do - mechanism not suitable here since head requests don't return a body response
-      begin
-        blob = YAML.load_file(blobfile)
-      rescue Errno::ENOENT
-        return nil #server.rb picks this up and gives 404
+      if blob = @client.load(:blobs, params[:id])
+        blob[:user_metadata]
+      else
+        nil
       end
-      blob[:user_metadata]
     end
 
     #--
@@ -473,12 +392,11 @@ module Deltacloud::Drivers::Mock
     #--
     def update_blob_metadata(credentials, opts={})
       check_credentials(credentials)
-      blobfile = File::join("#{@storage_root}", "buckets", "blobs", "#{opts[:id]}.yml")
       safely do
-        blob = YAML.load_file(blobfile)
+        blob = @client.load(:blobs, params[:id])
         return false unless blob
         blob[:user_metadata] = BlobHelper::rename_metadata_headers(opts['meta_hash'], '')
-        File.open(File::join("#{@storage_root}", "buckets", "blobs", "#{opts[:id]}.yml"), 'w' ) {|b| YAML.dump( blob, b )}
+        @client.store(:blobs, blob)
       end
     end
 
-- 
1.7.6