mirror of https://github.com/borgbackup/borg.git
Implemented, mode, owner and ctime/mtime support
This commit is contained in:
parent
7e288c0b5c
commit
0839e6bed3
|
@ -11,7 +11,8 @@ import msgpack
|
|||
from .chunkifier import chunkify
|
||||
from .cache import Cache, NS_ARCHIVES, NS_CHUNKS
|
||||
from .bandstore import BandStore
|
||||
from .helpers import location_validator, pretty_size, LevelFilter
|
||||
from .helpers import location_validator, pretty_size, LevelFilter, \
|
||||
uid2user, user2uid, gid2group, group2gid
|
||||
|
||||
CHUNK_SIZE = 55001
|
||||
|
||||
|
@ -110,6 +111,14 @@ class Archive(object):
|
|||
raise Exception('Invalid chunk checksum')
|
||||
data = zlib.decompress(data)
|
||||
fd.write(data)
|
||||
os.chmod(path, item['mode'])
|
||||
uid = user2uid(item['user']) or item['uid']
|
||||
gid = group2gid(item['group']) or item['gid']
|
||||
try:
|
||||
os.chown(path, uid, gid)
|
||||
except OSError:
|
||||
pass
|
||||
os.utime(path, (item['ctime'], item['mtime']))
|
||||
|
||||
def verify(self):
|
||||
for item in self.items:
|
||||
|
@ -189,7 +198,13 @@ class Archive(object):
|
|||
for chunk in chunkify(fd, CHUNK_SIZE, 30):
|
||||
size += len(chunk)
|
||||
chunks.append(self.add_chunk(*self.cache.add_chunk(chunk)))
|
||||
self.items.append({'type': 'FILE', 'path': path, 'chunks': chunks, 'size': size})
|
||||
self.items.append({
|
||||
'type': 'FILE', 'path': path, 'chunks': chunks, 'size': size,
|
||||
'mode': st.st_mode,
|
||||
'uid': st.st_uid, 'user': uid2user(st.st_uid),
|
||||
'gid': st.st_gid, 'group': gid2group(st.st_gid),
|
||||
'ctime': st.st_ctime, 'mtime': st.st_mtime,
|
||||
})
|
||||
|
||||
|
||||
class Archiver(object):
|
||||
|
|
|
@ -1,10 +1,51 @@
|
|||
import logging
|
||||
import argparse
|
||||
import re
|
||||
import grp
|
||||
import pwd
|
||||
|
||||
def memoize(function):
|
||||
cache = {}
|
||||
def decorated_function(*args):
|
||||
try:
|
||||
return cache[args]
|
||||
except KeyError:
|
||||
val = function(*args)
|
||||
cache[args] = val
|
||||
return val
|
||||
return decorated_function
|
||||
|
||||
@memoize
|
||||
def uid2user(uid):
|
||||
try:
|
||||
return pwd.getpwuid(uid).pw_name
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
@memoize
|
||||
def user2uid(user):
|
||||
try:
|
||||
return pwd.getpwnam(user).pw_uid
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
@memoize
|
||||
def gid2group(gid):
|
||||
try:
|
||||
return grp.getgrgid(gid).gr_name
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
@memoize
|
||||
def group2gid(group):
|
||||
try:
|
||||
return grp.getgrnam(group).gr_gid
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
class LevelFilter(logging.Filter):
|
||||
|
||||
"""Filter that counts record levels
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
logging.Filter.__init__(self, *args, **kwargs)
|
||||
self.count = {}
|
||||
|
@ -15,7 +56,6 @@ class LevelFilter(logging.Filter):
|
|||
return record
|
||||
|
||||
|
||||
|
||||
class Location(object):
|
||||
|
||||
loc_re = re.compile(r'^((?:(?P<user>[^@]+)@)?(?P<host>[^:]+):)?'
|
||||
|
|
Loading…
Reference in New Issue