mirror of
https://github.com/trapexit/mergerfs.git
synced 2024-11-25 09:41:43 +08:00
remove tooling from repo. closes #198
This commit is contained in:
parent
02c1ce5181
commit
de776b7cf0
7
Makefile
7
Makefile
|
@ -111,8 +111,6 @@ $(TARGET): src/version.hpp obj/obj-stamp $(OBJ)
|
|||
clone: $(TARGET)
|
||||
$(LN) -fs "$<" "$@"
|
||||
|
||||
fsck.mergerfs: tools/fsck.mergerfs
|
||||
|
||||
mount.mergerfs: $(TARGET)
|
||||
$(LN) -fs "$<" "$@"
|
||||
|
||||
|
@ -145,7 +143,7 @@ clean: rpm-clean
|
|||
distclean: clean
|
||||
$(GIT) clean -fd
|
||||
|
||||
install: install-base install-clone install-mount.mergerfs install-tools install-man
|
||||
install: install-base install-clone install-mount.mergerfs install-man
|
||||
|
||||
install-base: $(TARGET)
|
||||
$(INSTALL) -v -m 0755 -D "$(TARGET)" "$(INSTALLBINDIR)/$(TARGET)"
|
||||
|
@ -158,9 +156,6 @@ install-mount.mergerfs: mount.mergerfs
|
|||
$(MKDIR) -p "$(INSTALLBINDIR)"
|
||||
$(CP) -a "$<" "$(INSTALLBINDIR)/$<"
|
||||
|
||||
install-tools: fsck.mergerfs
|
||||
$(INSTALL) -v -m 0755 -D "tools/$<" "$(INSTALLSBINDIR)/$<"
|
||||
|
||||
install-man: $(MANPAGE)
|
||||
$(INSTALL) -v -m 0644 -D "$(MANPAGE)" "$(INSTALLMAN1DIR)/$(MANPAGE)"
|
||||
|
||||
|
|
|
@ -304,7 +304,9 @@ A B C
|
|||
|
||||
# TOOLING
|
||||
|
||||
* /usr/sbin/fsck.mergerfs: Provides permissions and ownership auditing and the ability to fix them.
|
||||
Find extra tooling to help with managing `mergerfs` at: https://github.com/trapexit/mergerfs-tools
|
||||
|
||||
* fsck.mergerfs: Provides permissions and ownership auditing and the ability to fix them
|
||||
|
||||
# TIPS / NOTES
|
||||
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
|
||||
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import xattr
|
||||
import errno
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='audit a mergerfs mount for inconsistencies')
|
||||
parser.add_argument('device',type=str,help='device')
|
||||
parser.add_argument('-v','--verbose',action='store_true',help='print details of audit item')
|
||||
parser.add_argument('-f','--fix',choices=['manual','newest'],help='fix policy')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.fix:
|
||||
args.verbose = True
|
||||
|
||||
if args.fix == 'manual':
|
||||
fix = manual_fix
|
||||
elif args.fix == 'newest':
|
||||
fix = newest_fix
|
||||
else:
|
||||
fix = noop_fix
|
||||
|
||||
try:
|
||||
controlfile = os.path.join(args.device,".mergerfs")
|
||||
version = xattr.getxattr(controlfile,"user.mergerfs.version")
|
||||
|
||||
for (dirname,dirnames,filenames) in os.walk(args.device):
|
||||
fulldirpath = os.path.join(args.device,dirname)
|
||||
check_consistancy(fulldirpath,args.verbose,fix)
|
||||
for filename in filenames:
|
||||
fullpath = os.path.join(fulldirpath,filename)
|
||||
check_consistancy(fullpath,args.verbose,fix)
|
||||
|
||||
except IOError as e:
|
||||
if e.errno == errno.ENOENT:
|
||||
print("%s is not a mergerfs device" % args.device)
|
||||
else:
|
||||
print("IOError: %s" % e.strerror)
|
||||
|
||||
|
||||
def check_consistancy(fullpath,verbose,fix):
|
||||
paths = xattr.getxattr(fullpath,"user.mergerfs.allpaths").split('\0')
|
||||
if len(paths) > 1:
|
||||
stats = [os.stat(path) for path in paths]
|
||||
if stats_different(stats):
|
||||
print("mismatch: %s" % fullpath)
|
||||
if verbose:
|
||||
print_stats(paths,stats)
|
||||
fix(paths,stats)
|
||||
|
||||
|
||||
def noop_fix(paths,stats):
|
||||
pass
|
||||
|
||||
|
||||
def manual_fix(paths,stats):
|
||||
done = False
|
||||
while not done:
|
||||
try:
|
||||
value = input('Which is correct?: ')
|
||||
setstat(stats[value % len(paths)],paths)
|
||||
done = True
|
||||
except NameError:
|
||||
print("Input error: enter a value between 0 and %d" % (len(paths)-1))
|
||||
except Exception as e:
|
||||
print("%s" % e)
|
||||
done = True
|
||||
|
||||
|
||||
def newest_fix(paths,stats):
|
||||
stats.sort(key=lambda stat: stat.st_mtime)
|
||||
try:
|
||||
setstat(stats[-1],paths)
|
||||
except Exception as e:
|
||||
print("%s" % e)
|
||||
|
||||
|
||||
def setstat(stat,paths):
|
||||
for path in paths:
|
||||
try:
|
||||
os.chmod(path,stat.st_mode)
|
||||
os.chown(path,stat.st_uid,stat.st_gid);
|
||||
print("setting %s > uid: %d gid: %d mode: %o" %
|
||||
(path,stat.st_uid,stat.st_gid,stat.st_mode))
|
||||
except Exception as e:
|
||||
print("%s" % e)
|
||||
|
||||
|
||||
def stats_different(stats):
|
||||
base = stats[0]
|
||||
for stat in stats:
|
||||
if ((stat.st_mode == base.st_mode) and
|
||||
(stat.st_uid == base.st_uid) and
|
||||
(stat.st_gid == base.st_gid)):
|
||||
continue
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def print_stats(Files,Stats):
|
||||
for i in xrange(0,len(Files)):
|
||||
print("- %i: %s > uid: %s; gid: %s; mode: %o" %
|
||||
(i,Files[i],Stats[i].st_uid,Stats[i].st_gid,Stats[i].st_mode))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue
Block a user