uploader: do not delete files after uploading (#1253)
* cffi xattr function wrapper * xattr wrapper error handling * xattr tests * use xattr for tracking files uploaded * uploader xattr exception handling * update uploader tests * remove unused import * update release build * xattrs.py -> xattr.pypull/1254/head
parent
6f7320a046
commit
f21d0f325e
5 changed files with 133 additions and 37 deletions
@ -0,0 +1,46 @@ |
|||||||
|
import os |
||||||
|
import tempfile |
||||||
|
import shutil |
||||||
|
import unittest |
||||||
|
|
||||||
|
from common.xattr import getxattr, setxattr, listxattr, removexattr |
||||||
|
|
||||||
|
class TestParams(unittest.TestCase): |
||||||
|
def setUp(self): |
||||||
|
self.tmpdir = tempfile.mkdtemp() |
||||||
|
self.tmpfn = os.path.join(self.tmpdir, 'test.txt') |
||||||
|
open(self.tmpfn, 'w').close() |
||||||
|
#print("using", self.tmpfn) |
||||||
|
|
||||||
|
def tearDown(self): |
||||||
|
shutil.rmtree(self.tmpdir) |
||||||
|
|
||||||
|
def test_getxattr_none(self): |
||||||
|
a = getxattr(self.tmpfn, 'user.test') |
||||||
|
assert a is None |
||||||
|
|
||||||
|
def test_listxattr_none(self): |
||||||
|
l = listxattr(self.tmpfn) |
||||||
|
assert l == [] |
||||||
|
|
||||||
|
def test_setxattr(self): |
||||||
|
setxattr(self.tmpfn, 'user.test', b'123') |
||||||
|
a = getxattr(self.tmpfn, 'user.test') |
||||||
|
assert a == b'123' |
||||||
|
|
||||||
|
def test_listxattr(self): |
||||||
|
setxattr(self.tmpfn, 'user.test1', b'123') |
||||||
|
setxattr(self.tmpfn, 'user.test2', b'123') |
||||||
|
l = listxattr(self.tmpfn) |
||||||
|
assert l == ['user.test1', 'user.test2'] |
||||||
|
|
||||||
|
def test_removexattr(self): |
||||||
|
setxattr(self.tmpfn, 'user.test', b'123') |
||||||
|
a = getxattr(self.tmpfn, 'user.test') |
||||||
|
assert a == b'123' |
||||||
|
removexattr(self.tmpfn, 'user.test') |
||||||
|
a = getxattr(self.tmpfn, 'user.test') |
||||||
|
assert a is None |
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
unittest.main() |
@ -0,0 +1,45 @@ |
|||||||
|
import os |
||||||
|
from cffi import FFI |
||||||
|
|
||||||
|
# Workaround for the EON/termux build of Python having os.*xattr removed. |
||||||
|
ffi = FFI() |
||||||
|
ffi.cdef(""" |
||||||
|
int setxattr(const char *path, const char *name, const void *value, size_t size, int flags); |
||||||
|
ssize_t getxattr(const char *path, const char *name, void *value, size_t size); |
||||||
|
ssize_t listxattr(const char *path, char *list, size_t size); |
||||||
|
int removexattr(const char *path, const char *name); |
||||||
|
""") |
||||||
|
libc = ffi.dlopen(None) |
||||||
|
|
||||||
|
def setxattr(path, name, value, flags=0): |
||||||
|
path = path.encode() |
||||||
|
name = name.encode() |
||||||
|
if libc.setxattr(path, name, value, len(value), flags) == -1: |
||||||
|
raise OSError(ffi.errno, f"{os.strerror(ffi.errno)}: setxattr({path}, {name}, {value}, {flags})") |
||||||
|
|
||||||
|
def getxattr(path, name, size=128): |
||||||
|
path = path.encode() |
||||||
|
name = name.encode() |
||||||
|
value = ffi.new(f"char[{size}]") |
||||||
|
l = libc.getxattr(path, name, value, size) |
||||||
|
if l == -1: |
||||||
|
# errno 61 means attribute hasn't been set |
||||||
|
if ffi.errno == 61: |
||||||
|
return None |
||||||
|
raise OSError(ffi.errno, f"{os.strerror(ffi.errno)}: getxattr({path}, {name}, {size})") |
||||||
|
return ffi.buffer(value)[:l] |
||||||
|
|
||||||
|
def listxattr(path, size=128): |
||||||
|
path = path.encode() |
||||||
|
attrs = ffi.new(f"char[{size}]") |
||||||
|
l = libc.listxattr(path, attrs, size) |
||||||
|
if l == -1: |
||||||
|
raise OSError(ffi.errno, f"{os.strerror(ffi.errno)}: listxattr({path}, {size})") |
||||||
|
# attrs is b'\0' delimited values (so chop off trailing empty item) |
||||||
|
return [a.decode() for a in ffi.buffer(attrs)[:l].split(b"\0")[0:-1]] |
||||||
|
|
||||||
|
def removexattr(path, name): |
||||||
|
path = path.encode() |
||||||
|
name = name.encode() |
||||||
|
if libc.removexattr(path, name) == -1: |
||||||
|
raise OSError(ffi.errno, f"{os.strerror(ffi.errno)}: removexattr({path}, {name})") |
Loading…
Reference in new issue