Last active
March 21, 2019 19:07
-
-
Save krzysztof-magosa/d9d96c8864a20dc3b47fd1eee1cfcc4f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# | |
# (c) Krzysztof Magosa | |
# License: MIT | |
# Use at your own risk. | |
# | |
# https://gist.github.com/krzysztof-magosa/d9d96c8864a20dc3b47fd1eee1cfcc4f | |
# | |
import argparse | |
import os | |
import heapq | |
parser = argparse.ArgumentParser() | |
parser.add_argument("--thresh", type=int, default=80, help="Maximum used space in %%") | |
parser.add_argument("--offenders", type=int, default=4096, help="Find N offenders at a time") | |
parser.add_argument("--hysteresis", type=int, default=5, help="Remove N more %%") | |
parser.add_argument("path", nargs=1, help="Path to scan") | |
args = parser.parse_args() | |
# Return % of disk used | |
def get_disk_percents(path): | |
vfs = os.statvfs(path) | |
return 100.0 * float((vfs.f_blocks - vfs.f_bfree) / float(vfs.f_blocks - vfs.f_bfree + vfs.f_bavail)) | |
# Return files from path (recursively) as tuple of mtime+filename | |
def get_files(path): | |
for root, dirs, files in os.walk(path): | |
for name in files: | |
filename = os.path.join(root, name) | |
try: | |
# Only regular files | |
if os.path.isfile(filename): | |
mtime = os.path.getmtime(filename) | |
yield (mtime, filename) | |
except: | |
pass | |
# Get offenders from path | |
# Priority Queue is sorted by first element from tuple (mtime). | |
# Therefore files having oldest mtime are returned. | |
def get_offenders(path, limit): | |
offenders = [] | |
for entry in get_files(path): | |
heapq.heappush(offenders, entry) | |
if len(offenders) > limit: | |
del offenders[-1] | |
return offenders | |
if __name__ == "__main__": | |
# Initial check whether we should do anything. | |
if get_disk_percents(args.path[0]) > args.thresh: | |
offenders = [] | |
while True: | |
# Remove to reach thresh + hysteresis. | |
if get_disk_percents(args.path[0]) <= (args.thresh - args.hysteresis): | |
break | |
# We have no offenders available, find them. | |
if not offenders: | |
offenders = get_offenders(args.path[0], args.offenders) | |
# No offenders available, nothing we can do. | |
if not offenders: | |
break | |
# Remove oldest offender ignoring possible permission denied problems. | |
mtime, filename = heapq.heappop(offenders) | |
try: | |
print("Removing {}".format(filename)) | |
os.unlink(filename) | |
except OSError: | |
pass | |
else: | |
print("Usage below threshold. Exiting...") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment