summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <lars.wirzenius@codethink.co.uk>2014-06-23 15:32:18 +0000
committerLars Wirzenius <lars.wirzenius@codethink.co.uk>2014-06-23 16:13:23 +0000
commita1d65e0b92845157228f58ffa1d2a9e21a4e399c (patch)
treee2518f54f44dc910c258498ee381dcb363a3099a
parent376c03c53bc86b88f14ef46c036795eb52186805 (diff)
downloadlorry-controller-liw/status-write-via-temp-file.tar.gz
Write static status HTML page via temporary fileliw/status-write-via-temp-file
This will avoid the file being truncated if the disk fills up.
-rw-r--r--lorrycontroller/status.py27
1 files changed, 26 insertions, 1 deletions
diff --git a/lorrycontroller/status.py b/lorrycontroller/status.py
index b0a3807..22bdb0b 100644
--- a/lorrycontroller/status.py
+++ b/lorrycontroller/status.py
@@ -16,6 +16,7 @@
import logging
import os
+import tempfile
import time
import bottle
@@ -49,13 +50,37 @@ class StatusRenderer(object):
modified_status = dict(status)
modified_status['links'] = False
html = self.render_status_as_html(template, modified_status)
+
+ # We write the file first to a temporary file and then
+ # renaming it into place. If there are any problems, such as
+ # the disk getting full, we won't truncate an existing file.
+
try:
- with open(filename, 'w') as f:
+ temp_filename = self.temp_filename_in_same_dir_as(filename)
+ with open(temp_filename, 'w') as f:
f.write(html)
+ os.rename(temp_filename, filename)
except (OSError, IOError) as e:
+ self.remove_temp_file(temp_filename)
status['warning_msg'] = (
'ERROR WRITING STATUS HTML TO DISK: %s' % str(e))
+ def temp_filename_in_same_dir_as(self, filename):
+ dirname = os.path.dirname(filename)
+ fd, temp_filename = tempfile.mkstemp(dir=dirname)
+ os.fchmod(fd, 0644)
+ os.close(fd)
+ return temp_filename
+
+ def remove_temp_file(self, temp_filename):
+ try:
+ os.remove(temp_filename)
+ except OSError:
+ # Ignore a problem with removing. Don't ignore all
+ # exceptions to avoid catching variable names being
+ # mistyped, etc.
+ pass
+
def get_free_disk_space(self, dirname):
result = os.statvfs(dirname)
free_bytes = result.f_bavail * result.f_bsize