Index: /trunk/Nebulous/Changes
===================================================================
--- /trunk/Nebulous/Changes	(revision 24439)
+++ /trunk/Nebulous/Changes	(revision 24440)
@@ -4,4 +4,5 @@
     - add chmod() API
     - change neb-ls to always output in --long format
+    - add neb-rm --force flag
 
 0.10
Index: /trunk/Nebulous/bin/neb-rm
===================================================================
--- /trunk/Nebulous/bin/neb-rm	(revision 24439)
+++ /trunk/Nebulous/bin/neb-rm	(revision 24440)
@@ -16,11 +16,16 @@
 use Pod::Usage qw( pod2usage );
 
-my ($server, $move);
+my (
+    $force,
+    $move,
+    $server,
+);
 
 $server = $ENV{'NEB_SERVER'} unless $server;
 
 GetOptions(
+    'force|f'       => \$force,
+    'move|m'        => \$move,
     'server|s=s'    => \$server,
-    'move|m'        => \$move,
 ) || pod2usage( 2 );
 
@@ -63,4 +68,11 @@
 
 =over 4
+
+=item * --force|-f
+
+When set, C<<key>> will be removed from the nebulous database even if the on
+disk file(s) are missing.
+
+Optional.
 
 =item * --move|-m
Index: /trunk/Nebulous/lib/Nebulous/Client.pm
===================================================================
--- /trunk/Nebulous/lib/Nebulous/Client.pm	(revision 24439)
+++ /trunk/Nebulous/lib/Nebulous/Client.pm	(revision 24440)
@@ -16,5 +16,5 @@
 use Nebulous::Client::Log;
 use Nebulous::Util qw( :standard );
-use Params::Validate qw( validate validate_pos SCALAR UNDEF );
+use Params::Validate qw( validate validate_pos SCALAR UNDEF BOOLEAN );
 #use SOAP::Lite +trace => [qw( debug )];
 use SOAP::Lite;
@@ -329,4 +329,11 @@
     my $uri = $self->delete_instance($key, @$locations[0]);
 
+    eval {
+        _nuke_file(_get_file_path(@$locations[0]));
+    };
+    if ($@) {
+        $log->logdie($@);
+    }
+
     $log->debug("leaving");
 
@@ -803,7 +810,17 @@
     my $self = shift;
 
-    my ( $key ) = validate_pos( @_,
-        {
-            type => SCALAR,
+    my ($key, $force) = validate_pos( @_,
+        {
+            type        => SCALAR,
+        },
+        {
+            type        => BOOLEAN,
+            optional    => 1,
+            default     => undef,
+            callbacks   => {
+                'is boolean' => sub {
+                    $_[0] == 0 or $_[0] == 1 or $_[0] == undef;
+                },
+            },
         },
     );
@@ -817,5 +834,32 @@
     # a lock is implicitly removed when the last storage object is deleted
     foreach my $uri ( @$locations ) {
+        # it is being assumed here that it is better to have files on disk and
+        # not in the database then the inverse.
+        my $path;
+        eval {
+            $path = _get_file_path( $uri );
+        };
+        if ($@) {
+            if ($force) {
+                $log->warn($@);
+                $log->warn("exception ignored because force is in effect");
+            } else {
+                $log->logdie($@);
+            }
+        }
+
         $self->delete_instance($key, $uri) or return undef;
+
+        eval {
+            _nuke_file( $path );
+        };
+        if ($@) {
+            if ($force) {
+                $log->warn($@);
+                $log->warn("exception ignored because force is in effect");
+            } else {
+                $log->logdie($@);
+            }
+        }
     }
 
@@ -959,13 +1003,4 @@
     $log->debug( "entered - @_" );
 
-    # it is being assumed here that it is better to have files on disk and not in
-    # the database then the inverse.
-
-    my $path;
-    eval {
-        $path = _get_file_path( $uri );
-    };
-    $log->logdie( $@ ) if $@;
-
     my $response = $self->{ 'server' }->delete_instance($key, $uri);
     if ( $response->fault ) {
@@ -981,9 +1016,4 @@
 
     $log->debug( "server deleted instance" );
-
-    eval {
-        _nuke_file( $path );
-    };
-    $log->logdie( $@ ) if $@;
 
     $log->debug( "leaving" );
Index: /trunk/Nebulous/t/59_client_delete.t
===================================================================
--- /trunk/Nebulous/t/59_client_delete.t	(revision 24439)
+++ /trunk/Nebulous/t/59_client_delete.t	(revision 24440)
@@ -10,5 +10,5 @@
 use Apache::Test qw( -withtestmore );
 
-plan tests => 9;
+plan tests => 13;
 
 use lib qw( ./t ./lib );
@@ -26,7 +26,9 @@
         proxy => "http://$hostport/nebulous",
     );
-    $neb->create( "foo" );
+    my $uri = $neb->create( "foo" );
 
     ok( $neb->delete( "foo" ), "delete object" );
+
+    ok( ! -e _get_file_path($uri), "deleted file" );
 
     my $locations = $neb->find_instances( "foo" );
@@ -76,4 +78,27 @@
 }
 
+# force flag
+Test::Nebulous->setup;
+
+{
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+    $neb->create( "foo" );
+
+    is( $neb->delete("foo", undef), 1, "force flag false" );
+}
+
+Test::Nebulous->setup;
+
+{
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+    $neb->create( "foo" );
+
+    is( $neb->delete("foo", 1), 1, "force flag false" );
+}
+
 Test::Nebulous->setup;
 
@@ -84,5 +109,5 @@
     $neb->delete();
 };
-like( $@, qr/1 was expected/, "no params" );
+like( $@, qr/1 - 2 were expected/, "no params" );
 
 Test::Nebulous->setup;
@@ -92,7 +117,17 @@
         proxy => "http://$hostport/nebulous",
     );
-    $neb->delete( "foo", 2 );
+    $neb->delete( "foo", 3);
 };
-like( $@, qr/1 was expected/, "too many params" );
+like( $@, qr/is boolean/, "force flag not boolean" );
+
+Test::Nebulous->setup;
+
+eval {
+    my $neb = Nebulous::Client->new(
+        proxy => "http://$hostport/nebulous",
+    );
+    $neb->delete( "foo", 0, 2 );
+};
+like( $@, qr/1 - 2 were expected/, "too many params" );
 
 Test::Nebulous->cleanup;
Index: /trunk/Nebulous/t/62_client_delete_instance.t
===================================================================
--- /trunk/Nebulous/t/62_client_delete_instance.t	(revision 24439)
+++ /trunk/Nebulous/t/62_client_delete_instance.t	(revision 24440)
@@ -10,5 +10,5 @@
 use Apache::Test qw( -withtestmore );
 
-plan tests => 11;
+plan tests => 10;
 
 use lib qw( ./t ./lib );
@@ -35,6 +35,4 @@
 
     is( $uri, @$locations[0], "delete instance" );
-
-    ok( ! -e _get_file_path( @$locations[0] ), "deleted file" );
 }
 
