From a1aadbf8224d8382233dd341983e6a48fff3addc Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Mon, 14 May 2012 16:38:20 -0400 Subject: [PATCH] Make a couple of the fake directory handling options configurable and added docs. --- doc/streams-tutorial.md | 22 +++++++++ .../Storage/ObjectStorage/StreamWrapperFS.php | 45 +++++++++++++++++-- test/Tests/StreamWrapperFSTest.php | 1 - 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/doc/streams-tutorial.md b/doc/streams-tutorial.md index 09b21a3..80d1235 100644 --- a/doc/streams-tutorial.md +++ b/doc/streams-tutorial.md @@ -220,6 +220,28 @@ The main difference is the creation of `$cxt` using PHP's take a look at the [PHP documentation](http://us3.php.net/manual/en/book.stream.php) for streams. +## Stream Wrapper As A File System +As it was noted earlier in this tutorial, swift does not support directories. +Instead the names of a file can be path like with a separator. For example, +`swiftfs://Example/path/to/my_file.txt` has a name of `path/to/my_file.txt`. + +To enable applications to use swift in a more directlry like manner there is a +second stream wrapper with a prefix `swiftfs://`. swiftfs stands for swift file +system. It works in a similar manner to to the standard stream wrappers with a +few key differences: + +- mkdir will return TRUE is no objects start with the directory you are trying + to crate. Otherwise it will return FALSE. +- rmdir will return FALSE if any objects start with the directory prefix you are + trying to remove. rmdir does not allow you to remove directories with files + in them. +- Running stat on a directory that is a prefix for some objects (e.g., + `swiftfs://Example/path/to/`) will see this is a prefix for a file and treat + it as if it were a directory. + +To use this stream wrapper instead of the standard swift one simple replace the +usage of `swift://` with `swiftfs://`. + ## Summary This tutorial is focused on using stream wrappers to interact with your diff --git a/src/HPCloud/Storage/ObjectStorage/StreamWrapperFS.php b/src/HPCloud/Storage/ObjectStorage/StreamWrapperFS.php index a046256..a9ec5f7 100644 --- a/src/HPCloud/Storage/ObjectStorage/StreamWrapperFS.php +++ b/src/HPCloud/Storage/ObjectStorage/StreamWrapperFS.php @@ -23,8 +23,45 @@ SOFTWARE. * @file * Contains the stream wrapper for `swiftfs://` URLs. * + * Note, this stream wrapper is in early testing. + * * The stream wrapper implemented in HPCloud\Storage\ObjectStorage\StreamWrapper - * only supports the elements of a stream + * only supports the elements of a stream that are implemented by object + * storage. This is how the PHP documentation states a stream wrapper should be + * created. Because some features do not exist, attempting to treat a stream + * wrapper as if it were a file system will not entirely work. For example, + * while there are not directories objects have pathy names (with / separators). + * Directory calls to object storage with the default stream wrappers will not + * operate how they would for a file system. + * + * StreamWrapperFS is an attempt to make a filesystem like stream wrapper. + * Hence the protocol is swiftfs standing for swift file system. + * + * To understand how this stream wrapper works start by first reading the + * documentation on the HPCloud::Storage::ObjectStorage::StreamWrapper. + * + * DIRECTORIES + * + * Because OpenStack Swift does not support directories the swift:// stream + * wrapper does not support them. This stream wrapper attempts to fake them by + * faking directory stats, mkdir, and rmdir. By default (see the options below + * for how to change these) directories have permissions of 777, timestamps + * close to that of the request, and the user and group called by php. We mock + * these on the fly though information is stored in the PHP stat cache. + * + * In addition to the parameters supported by StreamWrapper, the following + * parameters may be set either in the stream context or through + * HPCloud::Bootstrap::setConfiguration(): + * - swiftfs_fake_stat_mode: Directories don't exist in swift. When stat() is + * is called on a directory we mock the stat information so functions like + * is_dir will work. The default file permissions is 0777. Though this + * parameter you can pass is a different set of file permissions to use + * for these mock stats. + * - swiftfs_fake_isdir_true: Directory functions like mkdir and is_dir (stat) + * check to see if there are objects with the the passed in directory as a + * prefix to see if it already exists. If you want is_dir to always return + * true even if it is not an existing prefix set this to TRUE. Defaults to + * FALSE. */ namespace HPCloud\Storage\ObjectStorage; @@ -55,7 +92,7 @@ class StreamWrapperFS extends StreamWrapper { */ public function mkdir($uri, $mode, $options) { - return !($this->testDirectoryExists($uri)); + return ($this->cxt('swiftfs_fake_isdir_true', FALSE) || !($this->testDirectoryExists($uri))); } @@ -85,7 +122,7 @@ class StreamWrapperFS extends StreamWrapper { // When FALSE is returned there is no file to stat. So, we attempt to handle // it like a directory. else { - if ($this->testDirectoryExists($path)) { + if ($this->cxt('swiftfs_fake_isdir_true', FALSE) || $this->testDirectoryExists($path)) { // The directory prefix exists. Fake the directory file permissions. return $this->fakeStat(TRUE); } @@ -159,7 +196,7 @@ class StreamWrapperFS extends StreamWrapper { // Set inode type to directory or file. $type = $dir ? 040000 : 0100000; // Fake world-readible - $mode = $type + 0777; + $mode = $type + $this->cxt('swiftfs_fake_stat_mode', 0777); $values = array( 'dev' => 0, diff --git a/test/Tests/StreamWrapperFSTest.php b/test/Tests/StreamWrapperFSTest.php index b239d04..3639e14 100644 --- a/test/Tests/StreamWrapperFSTest.php +++ b/test/Tests/StreamWrapperFSTest.php @@ -647,5 +647,4 @@ class StreamWrapperFSTest extends \HPCloud\Tests\TestCase { $this->assertFalse(rmdir($url, $this->basicSwiftContext())); } - }