summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xblackboxtest7
-rw-r--r--obnamlib/plugins/restore_plugin.py22
-rw-r--r--obnamlib/plugins/sftp_plugin.py6
-rw-r--r--obnamlib/plugins/show_plugin.py1
-rw-r--r--obnamlib/vfs.py4
-rw-r--r--obnamlib/vfs_local.py3
-rwxr-xr-xtest-sftpfs3
7 files changed, 44 insertions, 2 deletions
diff --git a/blackboxtest b/blackboxtest
index b4122ddd..3f5ad7e4 100755
--- a/blackboxtest
+++ b/blackboxtest
@@ -374,6 +374,13 @@ class RestoreTests(ObnamTestCase):
restored2 = os.path.join(self.restored, './' + self.data)
self.assert_same_contents('sparse', self.data, restored2)
+ def test_restores_pipe(self):
+ pathname = os.path.join(self.data, 'pipe')
+ os.mknod(pathname, 0600 | stat.S_IFIFO)
+ self.backup()
+ self.restore()
+ self.assert_restored_correctly()
+
class BackupTests(ObnamTestCase):
diff --git a/obnamlib/plugins/restore_plugin.py b/obnamlib/plugins/restore_plugin.py
index cc72f07d..cbfd405a 100644
--- a/obnamlib/plugins/restore_plugin.py
+++ b/obnamlib/plugins/restore_plugin.py
@@ -16,6 +16,7 @@
import logging
import os
+import stat
import obnamlib
@@ -122,9 +123,9 @@ class RestorePlugin(obnamlib.ObnamPlugin):
self.restore_hardlink(to_dir, filename, link, metadata)
else:
self.hardlinks.add(filename, metadata)
- self.restore_regular_file(gen, to_dir, filename, metadata)
+ self.restore_first_link(gen, to_dir, filename, metadata)
else:
- self.restore_regular_file(gen, to_dir, filename, metadata)
+ self.restore_first_link(gen, to_dir, filename, metadata)
def restore_hardlink(self, to_dir, filename, link, metadata):
logging.debug('restoring hardlink %s to %s' % (filename, link))
@@ -139,6 +140,17 @@ class RestorePlugin(obnamlib.ObnamPlugin):
logging.debug('restoring symlink %s' % filename)
to_filename = os.path.join(to_dir, './' + filename)
obnamlib.set_metadata(self.fs, to_filename, metadata)
+
+ def restore_first_link(self, gen, to_dir, filename, metadata):
+ if stat.S_ISREG(metadata.st_mode):
+ self.restore_regular_file(gen, to_dir, filename, metadata)
+ elif stat.S_ISFIFO(metadata.st_mode):
+ self.restore_fifo(gen, to_dir, filename, metadata)
+ else:
+ msg = ('Unknown file type: %s (%o)' %
+ (filename, metadata.st_mode))
+ logging.error(msg)
+ self.app.hooks.call('error-message', msg)
def restore_regular_file(self, gen, to_dir, filename, metadata):
logging.debug('restoring regular %s' % filename)
@@ -170,3 +182,9 @@ class RestorePlugin(obnamlib.ObnamPlugin):
f.seek(-1, 1)
f.write('\0')
+ def restore_fifo(self, gen, to_dir, filename, metadata):
+ logging.debug('restoring fifo %s' % filename)
+ to_filename = os.path.join(to_dir, './' + filename)
+ self.fs.mknod(to_filename, metadata.st_mode)
+ obnamlib.set_metadata(self.fs, to_filename, metadata)
+
diff --git a/obnamlib/plugins/sftp_plugin.py b/obnamlib/plugins/sftp_plugin.py
index ff8abd5d..95623d7c 100644
--- a/obnamlib/plugins/sftp_plugin.py
+++ b/obnamlib/plugins/sftp_plugin.py
@@ -250,6 +250,12 @@ class SftpFS(obnamlib.VirtualFileSystem):
else:
return stat.S_ISDIR(st.st_mode)
+ def mknod(self, pathname, mode):
+ # SFTP does not provide an mknod, so we can't do this. We
+ # raise an exception, so upper layers can handle this (we _could_
+ # just fail silently, but that would be silly.)
+ raise NotImplementedError('mknod on SFTP: %s' % pathname)
+
@ioerror_to_oserror
def mkdir(self, pathname):
self.sftp.mkdir(pathname)
diff --git a/obnamlib/plugins/show_plugin.py b/obnamlib/plugins/show_plugin.py
index 387001de..47542a77 100644
--- a/obnamlib/plugins/show_plugin.py
+++ b/obnamlib/plugins/show_plugin.py
@@ -105,6 +105,7 @@ class ShowPlugin(obnamlib.ObnamPlugin):
(stat.S_IFREG, 0, '-'),
(stat.S_IFDIR, 0, 'd'),
(stat.S_IFLNK, 0, 'l'),
+ (stat.S_IFIFO, 0, 'p'),
(stat.S_IRUSR, 1, 'r'),
(stat.S_IWUSR, 2, 'w'),
(stat.S_IXUSR, 3, 'x'),
diff --git a/obnamlib/vfs.py b/obnamlib/vfs.py
index 41ac3230..20957b93 100644
--- a/obnamlib/vfs.py
+++ b/obnamlib/vfs.py
@@ -364,6 +364,10 @@ class VfsTests(object): # pragma: no cover
def test_listdir_raises_oserror_if_directory_does_not_exist(self):
self.assertRaises(OSError, self.fs.listdir, 'foo')
+ def test_mknod_creates_fifo(self):
+ self.fs.mknod('foo', 0600 | stat.S_IFIFO)
+ self.assertEqual(self.fs.lstat('foo').st_mode, 0600 | stat.S_IFIFO)
+
def test_mkdir_raises_oserror_if_directory_exists(self):
self.assertRaises(OSError, self.fs.mkdir, '.')
diff --git a/obnamlib/vfs_local.py b/obnamlib/vfs_local.py
index d35fcf58..e00b14bc 100644
--- a/obnamlib/vfs_local.py
+++ b/obnamlib/vfs_local.py
@@ -124,6 +124,9 @@ class LocalFS(obnamlib.VirtualFileSystem):
def isdir(self, pathname):
return os.path.isdir(self.join(pathname))
+ def mknod(self, pathname, mode):
+ os.mknod(self.join(pathname), mode)
+
def mkdir(self, pathname):
os.mkdir(self.join(pathname))
diff --git a/test-sftpfs b/test-sftpfs
index becf1f4f..c8632ad3 100755
--- a/test-sftpfs
+++ b/test-sftpfs
@@ -56,6 +56,9 @@ class SftpTests(unittest.TestCase, obnamlib.VfsTests):
def test_link_creates_hard_link(self):
pass # sftp does not support hardlinking, so not testing it
+ def test_mknod_creates_fifo(self):
+ self.assertRaises(NotImplementedError, self.fs.mknod, 'foo', 0)
+
if __name__ == '__main__':
unittest.main()