Compare commits
12 Commits
nilmdb-1.9
...
nilmdb-1.9
Author | SHA1 | Date | |
---|---|---|---|
7d7b89b52f | |||
8d249273c6 | |||
abe431c663 | |||
ccf1f695af | |||
06f7390c9e | |||
6de77a08f1 | |||
8db9771c20 | |||
04f815a24b | |||
6868f5f126 | |||
ca0943ec19 | |||
68addb4e4a | |||
68c33b1f14 |
6
Makefile
6
Makefile
@@ -1,5 +1,5 @@
|
|||||||
# By default, run the tests.
|
# By default, run the tests.
|
||||||
all: fscktest
|
all: test
|
||||||
|
|
||||||
version:
|
version:
|
||||||
python setup.py version
|
python setup.py version
|
||||||
@@ -23,10 +23,6 @@ docs:
|
|||||||
lint:
|
lint:
|
||||||
pylint --rcfile=.pylintrc nilmdb
|
pylint --rcfile=.pylintrc nilmdb
|
||||||
|
|
||||||
fscktest:
|
|
||||||
python -c "import nilmdb.fsck; nilmdb.fsck.Fsck('/home/jim/wsgi/db').check()"
|
|
||||||
# python -c "import nilmdb.fsck; nilmdb.fsck.Fsck('/home/jim/mnt/bucket/mnt/sharon/data/db', True).check()"
|
|
||||||
|
|
||||||
test:
|
test:
|
||||||
ifeq ($(INSIDE_EMACS), t)
|
ifeq ($(INSIDE_EMACS), t)
|
||||||
# Use the slightly more flexible script
|
# Use the slightly more flexible script
|
||||||
|
@@ -9,7 +9,7 @@ import requests
|
|||||||
|
|
||||||
class HTTPClient(object):
|
class HTTPClient(object):
|
||||||
"""Class to manage and perform HTTP requests from the client"""
|
"""Class to manage and perform HTTP requests from the client"""
|
||||||
def __init__(self, baseurl = "", post_json = False):
|
def __init__(self, baseurl = "", post_json = False, verify_ssl = True):
|
||||||
"""If baseurl is supplied, all other functions that take
|
"""If baseurl is supplied, all other functions that take
|
||||||
a URL can be given a relative URL instead."""
|
a URL can be given a relative URL instead."""
|
||||||
# Verify / clean up URL
|
# Verify / clean up URL
|
||||||
@@ -19,6 +19,7 @@ class HTTPClient(object):
|
|||||||
self.baseurl = reparsed.rstrip('/') + '/'
|
self.baseurl = reparsed.rstrip('/') + '/'
|
||||||
|
|
||||||
# Build Requests session object, enable SSL verification
|
# Build Requests session object, enable SSL verification
|
||||||
|
self.verify_ssl = verify_ssl
|
||||||
self.session = requests.Session()
|
self.session = requests.Session()
|
||||||
self.session.verify = True
|
self.session.verify = True
|
||||||
|
|
||||||
@@ -67,7 +68,8 @@ class HTTPClient(object):
|
|||||||
params = query_data,
|
params = query_data,
|
||||||
data = body_data,
|
data = body_data,
|
||||||
stream = stream,
|
stream = stream,
|
||||||
headers = headers)
|
headers = headers,
|
||||||
|
verify = self.verify_ssl)
|
||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
raise ServerError(status = "502 Error", url = url,
|
raise ServerError(status = "502 Error", url = url,
|
||||||
message = str(e.message))
|
message = str(e.message))
|
||||||
|
@@ -19,9 +19,8 @@ except ImportError: # pragma: no cover
|
|||||||
|
|
||||||
# Valid subcommands. Defined in separate files just to break
|
# Valid subcommands. Defined in separate files just to break
|
||||||
# things up -- they're still called with Cmdline as self.
|
# things up -- they're still called with Cmdline as self.
|
||||||
subcommands = [ "help", "info", "create", "list", "metadata",
|
subcommands = [ "help", "info", "create", "rename", "list", "intervals",
|
||||||
"insert", "extract", "remove", "destroy",
|
"metadata", "insert", "extract", "remove", "destroy" ]
|
||||||
"intervals", "rename" ]
|
|
||||||
|
|
||||||
# Import the subcommand modules
|
# Import the subcommand modules
|
||||||
subcmd_mods = {}
|
subcmd_mods = {}
|
||||||
@@ -122,7 +121,7 @@ class Cmdline(object):
|
|||||||
group = self.parser.add_argument_group("General options")
|
group = self.parser.add_argument_group("General options")
|
||||||
group.add_argument("-h", "--help", action='help',
|
group.add_argument("-h", "--help", action='help',
|
||||||
help='show this help message and exit')
|
help='show this help message and exit')
|
||||||
group.add_argument("-V", "--version", action="version",
|
group.add_argument("-v", "--version", action="version",
|
||||||
version = nilmdb.__version__)
|
version = nilmdb.__version__)
|
||||||
|
|
||||||
group = self.parser.add_argument_group("Server")
|
group = self.parser.add_argument_group("Server")
|
||||||
|
@@ -45,6 +45,8 @@ def setup(self, sub):
|
|||||||
help="Show raw timestamps when printing times")
|
help="Show raw timestamps when printing times")
|
||||||
group.add_argument("-l", "--layout", action="store_true",
|
group.add_argument("-l", "--layout", action="store_true",
|
||||||
help="Show layout type next to path name")
|
help="Show layout type next to path name")
|
||||||
|
group.add_argument("-n", "--no-decim", action="store_true",
|
||||||
|
help="Skip paths containing \"~decim-\"")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
@@ -71,6 +73,8 @@ def cmd_list(self):
|
|||||||
(path, layout, int_min, int_max, rows, time) = stream[:6]
|
(path, layout, int_min, int_max, rows, time) = stream[:6]
|
||||||
if not fnmatch.fnmatch(path, argpath):
|
if not fnmatch.fnmatch(path, argpath):
|
||||||
continue
|
continue
|
||||||
|
if self.args.no_decim and "~decim-" in path:
|
||||||
|
continue
|
||||||
|
|
||||||
if self.args.layout:
|
if self.args.layout:
|
||||||
printf("%s %s\n", path, layout)
|
printf("%s %s\n", path, layout)
|
||||||
|
@@ -44,15 +44,16 @@ def err(format, *args):
|
|||||||
fprintf(sys.stderr, format, *args)
|
fprintf(sys.stderr, format, *args)
|
||||||
|
|
||||||
# Decorator that retries a function if it returns a specific value
|
# Decorator that retries a function if it returns a specific value
|
||||||
def retry_if_raised(exc, message = None):
|
def retry_if_raised(exc, message = None, max_retries = 100):
|
||||||
def f1(func):
|
def f1(func):
|
||||||
def f2(*args, **kwargs):
|
def f2(*args, **kwargs):
|
||||||
while True:
|
for n in range(max_retries):
|
||||||
try:
|
try:
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
except exc as e:
|
except exc as e:
|
||||||
if message:
|
if message:
|
||||||
log("%s\n\n", message)
|
log("%s\n\n", message)
|
||||||
|
raise Exception("Max number of retries (%d) exceeded; giving up")
|
||||||
return f2
|
return f2
|
||||||
return f1
|
return f1
|
||||||
|
|
||||||
@@ -89,7 +90,7 @@ class Fsck(object):
|
|||||||
### Main checks
|
### Main checks
|
||||||
|
|
||||||
@retry_if_raised(RetryFsck, "Something was fixed: restarting fsck")
|
@retry_if_raised(RetryFsck, "Something was fixed: restarting fsck")
|
||||||
def check(self):
|
def check(self, skip_data = False):
|
||||||
self.bulk = None
|
self.bulk = None
|
||||||
self.sql = None
|
self.sql = None
|
||||||
try:
|
try:
|
||||||
@@ -97,7 +98,10 @@ class Fsck(object):
|
|||||||
self.check_sql()
|
self.check_sql()
|
||||||
self.check_streams()
|
self.check_streams()
|
||||||
self.check_intervals()
|
self.check_intervals()
|
||||||
self.check_data()
|
if skip_data:
|
||||||
|
log("skipped data check\n")
|
||||||
|
else:
|
||||||
|
self.check_data()
|
||||||
finally:
|
finally:
|
||||||
if self.bulk:
|
if self.bulk:
|
||||||
self.bulk.close()
|
self.bulk.close()
|
||||||
@@ -118,7 +122,11 @@ class Fsck(object):
|
|||||||
raise FsckError("Bulk data directory missing (%s)", self.bulkpath)
|
raise FsckError("Bulk data directory missing (%s)", self.bulkpath)
|
||||||
with open(self.bulklock, "w") as lockfile:
|
with open(self.bulklock, "w") as lockfile:
|
||||||
if not nilmdb.utils.lock.exclusive_lock(lockfile):
|
if not nilmdb.utils.lock.exclusive_lock(lockfile):
|
||||||
raise FsckError('database already locked by another process')
|
raise FsckError('Database already locked by another process\n'
|
||||||
|
'Make sure all other processes that might be '
|
||||||
|
'using the database are stopped.\n'
|
||||||
|
'Restarting apache will cause it to unlock '
|
||||||
|
'the db until a request is received.')
|
||||||
# unlocked immediately
|
# unlocked immediately
|
||||||
self.bulk = nilmdb.server.bulkdata.BulkData(self.basepath)
|
self.bulk = nilmdb.server.bulkdata.BulkData(self.basepath)
|
||||||
|
|
||||||
@@ -170,7 +178,7 @@ class Fsck(object):
|
|||||||
|
|
||||||
def check_streams(self):
|
def check_streams(self):
|
||||||
ids = self.stream_path.keys()
|
ids = self.stream_path.keys()
|
||||||
log("checking %d streams\n", len(ids))
|
log("checking %s streams\n", "{:,d}".format(len(ids)))
|
||||||
with Progress(len(ids)) as pbar:
|
with Progress(len(ids)) as pbar:
|
||||||
for i, sid in enumerate(ids):
|
for i, sid in enumerate(ids):
|
||||||
pbar.update(i)
|
pbar.update(i)
|
||||||
@@ -306,7 +314,7 @@ class Fsck(object):
|
|||||||
|
|
||||||
def check_intervals(self):
|
def check_intervals(self):
|
||||||
total_ints = sum(len(x) for x in self.stream_interval.values())
|
total_ints = sum(len(x) for x in self.stream_interval.values())
|
||||||
log("checking %d intervals\n", total_ints)
|
log("checking %s intervals\n", "{:,d}".format(total_ints))
|
||||||
done = 0
|
done = 0
|
||||||
with Progress(total_ints) as pbar:
|
with Progress(total_ints) as pbar:
|
||||||
for sid in self.stream_interval:
|
for sid in self.stream_interval:
|
||||||
@@ -389,7 +397,7 @@ class Fsck(object):
|
|||||||
def check_data(self):
|
def check_data(self):
|
||||||
total_rows = sum(sum((y[3] - y[2]) for y in x)
|
total_rows = sum(sum((y[3] - y[2]) for y in x)
|
||||||
for x in self.stream_interval.values())
|
for x in self.stream_interval.values())
|
||||||
log("checking %d rows of data\n", total_rows)
|
log("checking %s rows of data\n", "{:,d}".format(total_rows))
|
||||||
done = 0
|
done = 0
|
||||||
with Progress(total_rows) as pbar:
|
with Progress(total_rows) as pbar:
|
||||||
for sid in self.stream_interval:
|
for sid in self.stream_interval:
|
||||||
|
@@ -10,16 +10,17 @@ def main():
|
|||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description = 'Check database consistency',
|
description = 'Check database consistency',
|
||||||
formatter_class = argparse.ArgumentDefaultsHelpFormatter)
|
formatter_class = argparse.ArgumentDefaultsHelpFormatter,
|
||||||
parser.add_argument("-V", "--version", action="version",
|
version = nilmdb.__version__)
|
||||||
version = nilmdb.__version__)
|
|
||||||
parser.add_argument("-f", "--fix", action="store_true",
|
parser.add_argument("-f", "--fix", action="store_true",
|
||||||
default=False, help = 'Fix errors when possible '
|
default=False, help = 'Fix errors when possible '
|
||||||
'(which may involve removing data)')
|
'(which may involve removing data)')
|
||||||
|
parser.add_argument("-n", "--no-data", action="store_true",
|
||||||
|
default=False, help = 'Skip the slow full-data check')
|
||||||
parser.add_argument('database', help = 'Database directory')
|
parser.add_argument('database', help = 'Database directory')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
nilmdb.fsck.Fsck(args.database, args.fix).check()
|
nilmdb.fsck.Fsck(args.database, args.fix).check(skip_data = args.no_data)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@@ -10,10 +10,8 @@ def main():
|
|||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description = 'Run the NilmDB server',
|
description = 'Run the NilmDB server',
|
||||||
formatter_class = argparse.ArgumentDefaultsHelpFormatter)
|
formatter_class = argparse.ArgumentDefaultsHelpFormatter,
|
||||||
|
version = nilmdb.__version__)
|
||||||
parser.add_argument("-V", "--version", action="version",
|
|
||||||
version = nilmdb.__version__)
|
|
||||||
|
|
||||||
group = parser.add_argument_group("Standard options")
|
group = parser.add_argument_group("Standard options")
|
||||||
group.add_argument('-a', '--address',
|
group.add_argument('-a', '--address',
|
||||||
|
@@ -74,8 +74,8 @@ class Root(NilmApp):
|
|||||||
dbsize = nilmdb.utils.du(path)
|
dbsize = nilmdb.utils.du(path)
|
||||||
return { "path": path,
|
return { "path": path,
|
||||||
"size": dbsize,
|
"size": dbsize,
|
||||||
"other": usage.used - dbsize,
|
"other": max(usage.used - dbsize, 0),
|
||||||
"reserved": usage.total - usage.used - usage.free,
|
"reserved": max(usage.total - usage.used - usage.free, 0),
|
||||||
"free": usage.free }
|
"free": usage.free }
|
||||||
|
|
||||||
class Stream(NilmApp):
|
class Stream(NilmApp):
|
||||||
|
@@ -21,7 +21,8 @@ def du(path):
|
|||||||
errors that might occur if we encounter broken symlinks or
|
errors that might occur if we encounter broken symlinks or
|
||||||
files in the process of being removed."""
|
files in the process of being removed."""
|
||||||
try:
|
try:
|
||||||
size = os.path.getsize(path)
|
st = os.stat(path)
|
||||||
|
size = st.st_blocks * 512
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path):
|
||||||
for thisfile in os.listdir(path):
|
for thisfile in os.listdir(path):
|
||||||
filepath = os.path.join(path, thisfile)
|
filepath = os.path.join(path, thisfile)
|
||||||
|
Reference in New Issue
Block a user