From a1d65e0b92845157228f58ffa1d2a9e21a4e399c Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Mon, 23 Jun 2014 15:32:18 +0000 Subject: Write static status HTML page via temporary file This will avoid the file being truncated if the disk fills up. --- lorrycontroller/status.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) 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 -- cgit v1.2.1