Also added code to keep track of tempfiles and cleanup on exit.
Fixes bug #8096 --- src/bin/secstate | 49 +++++++++++++++++++++++++++++++------------------ src/secstate/main.py | 9 +++++---- src/secstate/util.py | 1 - 3 files changed, 36 insertions(+), 23 deletions(-)
diff --git a/src/bin/secstate b/src/bin/secstate index ebaf9c8..c560510 100644 --- a/src/bin/secstate +++ b/src/bin/secstate @@ -24,6 +24,7 @@ import sys import ConfigParser import os +import shutil from optparse import OptionParser
import openscap_api as oscap @@ -57,67 +58,79 @@ def main(): subcommand = sys.argv[1] except IndexError, e: usage() - return -1 + return_code = -1
arg_num = 2 if (subcommand == '-c') or (subcommand == '--config'): if not sec_instance.setConfigFile(sys.argv[arg_num]): usage() - return -1 + return_code = -1 arg_num += 2 try: subcommand = sys.argv[arg_num - 1] except IndexError: usage() - return -1 + return_code = -1
if subcommand == 'help': - return help(sys.argv[arg_num:]) + return_code = help(sys.argv[arg_num:])
elif subcommand == 'export': - return export(sys.argv[arg_num:]) + return_code = export(sys.argv[arg_num:])
elif subcommand == 'search': - return search(sys.argv[arg_num:]) + return_code = search(sys.argv[arg_num:])
elif subcommand == 'list': - return list_content(sys.argv[arg_num:]) + return_code = list_content(sys.argv[arg_num:])
elif subcommand == 'show': - return show(sys.argv[arg_num:]) + return_code = show(sys.argv[arg_num:])
elif os.geteuid() != 0: sys.stderr.write("secstate must be run as root!\n") - return -1 + return_code = -1
elif subcommand == 'import': - return import_content(sys.argv[arg_num:]) + return_code = import_content(sys.argv[arg_num:])
elif subcommand == 'remove': - return remove_content(sys.argv[arg_num:]) + return_code = remove_content(sys.argv[arg_num:])
elif subcommand == 'select': - return select(sys.argv[arg_num:], True) + return_code = select(sys.argv[arg_num:], True)
elif subcommand == 'deselect': - return select(sys.argv[arg_num:], False) + return_code = select(sys.argv[arg_num:], False)
elif subcommand == 'audit': - return audit(sys.argv[arg_num:]) + return_code = audit(sys.argv[arg_num:])
elif subcommand == 'remediate': - return remediate(sys.argv[arg_num:]) + return_code = remediate(sys.argv[arg_num:])
elif subcommand == 'mitigate': - return mitigate(sys.argv[arg_num:]) + return_code = mitigate(sys.argv[arg_num:])
elif subcommand == 'save': - return save_profile(sys.argv[arg_num:]) + return_code = save_profile(sys.argv[arg_num:])
else: sys.stderr.write("Uknown subcommand: %(command)s" % {'command':subcommand}) usage() - return -1 + return_code = -1 + + try: + for dir in sec_instance.tempfiles['dirs']: + shutil.rmtree(dir) + + for tmpfile in sec_instance.tempfiles['files']: + os.remove(tmpfile) + except IOError,e: + sec_instance.log.error("Error cleaning up temporary files: %(err)s" % {'err':e}) + return_code = -1 + + return return_code
def help(arg): if arg == []: diff --git a/src/secstate/main.py b/src/secstate/main.py index f2025cd..60bb864 100644 --- a/src/secstate/main.py +++ b/src/secstate/main.py @@ -54,6 +54,7 @@ class Secstate: self.load_content() self.log = self.getLogger() self.benchmark_dir = self.config.get('secstate', 'benchmark_dir') + self.tempfiles = {'dirs':[], 'files':[]}
def setConfigFile(self, conf): config = ConfigParser.ConfigParser() @@ -349,6 +350,7 @@ class Secstate: Output: Success of failure of the import """ extract_path = tempfile.mkdtemp() + self.tempfiles['dirs'].append(extract_path)
if type[0] == "application/x-tar": tar_file = None @@ -407,11 +409,8 @@ class Secstate: if benchmark == None: return None
- # Delete temporary directory now that we are done with it - shutil.rmtree(extract_path) return benchmark
- def import_content(self, content, changes=True, save=False, active_profile=NONE_PROFILE): """ Function: Validates XCCDF/OVAL content and optionally saves it to the data store @@ -474,6 +473,7 @@ class Secstate: benchmark_file = self.content[benchmark_id] else: benchmark_file = tempfile.mktemp() + self.tempfiles['files'].append(benchmark_file) benchmark = self.import_content(benchmark_id) if benchmark.export(benchmark_file) == None: self.log.error("Error exporting benchmark to %(file)s" % {'file':new_file}) @@ -1049,6 +1049,7 @@ class Secstate: site_pp = self.config.get('secstate', 'site_pp') else: (site_pp_buf, site_pp) = tempfile.mkstemp() + self.tempfiles['files'].append(site_pp) for puppet in benchmark.puppet: os.write(site_pp_buf, 'import "%(file)s"\n' % {'file':puppet}) os.close(site_pp_buf) @@ -1073,6 +1074,7 @@ class Secstate:
else: handle, fname = tempfile.mkstemp(suffix='.yaml') + self.tempfiles['files'].append(fname) os.write(handle, template % dict_to_external(puppet_content)) os.close(handle) puppet_args = ['/usr/bin/puppet', '--external_node', '/usr/libexec/secstate/secstate_external_node %s' % fname, '--node_terminus', 'exec', site_pp] @@ -1083,7 +1085,6 @@ class Secstate: if verbose: puppet_args.append('--verbose') subprocess.call(puppet_args) - os.unlink(fname)
return True
diff --git a/src/secstate/util.py b/src/secstate/util.py index d30a169..1b208cd 100644 --- a/src/secstate/util.py +++ b/src/secstate/util.py @@ -27,7 +27,6 @@ import time import re import ConfigParser import json -import tempfile import zipfile import libxml2 import libxslt
On Tue, 2010-09-14 at 10:44 -0400, Josh Adams wrote:
Also added code to keep track of tempfiles and cleanup on exit.
Fixes bug #8096
src/bin/secstate | 49 +++++++++++++++++++++++++++++++------------------ src/secstate/main.py | 9 +++++---- src/secstate/util.py | 1 - 3 files changed, 36 insertions(+), 23 deletions(-)
diff --git a/src/bin/secstate b/src/bin/secstate index ebaf9c8..c560510 100644 --- a/src/bin/secstate +++ b/src/bin/secstate @@ -24,6 +24,7 @@ import sys import ConfigParser import os +import shutil from optparse import OptionParser
import openscap_api as oscap @@ -57,67 +58,79 @@ def main(): subcommand = sys.argv[1] except IndexError, e: usage()
return -1
return_code = -1
arg_num = 2 if (subcommand == '-c') or (subcommand == '--config'): if not sec_instance.setConfigFile(sys.argv[arg_num]): usage()
return -1
return_code = -1 arg_num += 2 try: subcommand = sys.argv[arg_num - 1] except IndexError: usage()
return -1
return_code = -1
if subcommand == 'help':
return help(sys.argv[arg_num:])
return_code = help(sys.argv[arg_num:])
elif subcommand == 'export':
return export(sys.argv[arg_num:])
return_code = export(sys.argv[arg_num:])
elif subcommand == 'search':
return search(sys.argv[arg_num:])
return_code = search(sys.argv[arg_num:])
elif subcommand == 'list':
return list_content(sys.argv[arg_num:])
return_code = list_content(sys.argv[arg_num:])
elif subcommand == 'show':
return show(sys.argv[arg_num:])
return_code = show(sys.argv[arg_num:])
elif os.geteuid() != 0: sys.stderr.write("secstate must be run as root!\n")
return -1
return_code = -1
elif subcommand == 'import':
return import_content(sys.argv[arg_num:])
return_code = import_content(sys.argv[arg_num:])
elif subcommand == 'remove':
return remove_content(sys.argv[arg_num:])
return_code = remove_content(sys.argv[arg_num:])
elif subcommand == 'select':
return select(sys.argv[arg_num:], True)
return_code = select(sys.argv[arg_num:], True)
elif subcommand == 'deselect':
return select(sys.argv[arg_num:], False)
return_code = select(sys.argv[arg_num:], False)
elif subcommand == 'audit':
return audit(sys.argv[arg_num:])
return_code = audit(sys.argv[arg_num:])
elif subcommand == 'remediate':
return remediate(sys.argv[arg_num:])
return_code = remediate(sys.argv[arg_num:])
elif subcommand == 'mitigate':
return mitigate(sys.argv[arg_num:])
return_code = mitigate(sys.argv[arg_num:])
elif subcommand == 'save':
return save_profile(sys.argv[arg_num:])
return_code = save_profile(sys.argv[arg_num:])
else: sys.stderr.write("Uknown subcommand: %(command)s" % {'command':subcommand}) usage()
return -1
return_code = -1
- try:
for dir in sec_instance.tempfiles['dirs']:
shutil.rmtree(dir)
for tmpfile in sec_instance.tempfiles['files']:
os.remove(tmpfile)
- except IOError,e:
sec_instance.log.error("Error cleaning up temporary files: %(err)s" % {'err':e})
return_code = -1
This code should be moved into a cleanup method in the SecState class. Since the SecState class is responsible for creating these files and directories, it should also be responsible for cleaning them up. We might be able to have the __del__ method call the cleanup function so there isn't a need to call it explicitly.
Marshall
- return return_code
def help(arg): if arg == []: diff --git a/src/secstate/main.py b/src/secstate/main.py index f2025cd..60bb864 100644 --- a/src/secstate/main.py +++ b/src/secstate/main.py @@ -54,6 +54,7 @@ class Secstate: self.load_content() self.log = self.getLogger() self.benchmark_dir = self.config.get('secstate', 'benchmark_dir')
self.tempfiles = {'dirs':[], 'files':[]}
def setConfigFile(self, conf): config = ConfigParser.ConfigParser()
@@ -349,6 +350,7 @@ class Secstate: Output: Success of failure of the import """ extract_path = tempfile.mkdtemp()
self.tempfiles['dirs'].append(extract_path) if type[0] == "application/x-tar": tar_file = None
@@ -407,11 +409,8 @@ class Secstate: if benchmark == None: return None
# Delete temporary directory now that we are done with it
shutil.rmtree(extract_path) return benchmark
def import_content(self, content, changes=True, save=False, active_profile=NONE_PROFILE): """ Function: Validates XCCDF/OVAL content and optionally saves it to the data store
@@ -474,6 +473,7 @@ class Secstate: benchmark_file = self.content[benchmark_id] else: benchmark_file = tempfile.mktemp()
self.tempfiles['files'].append(benchmark_file) benchmark = self.import_content(benchmark_id) if benchmark.export(benchmark_file) == None: self.log.error("Error exporting benchmark to %(file)s" % {'file':new_file})
@@ -1049,6 +1049,7 @@ class Secstate: site_pp = self.config.get('secstate', 'site_pp') else: (site_pp_buf, site_pp) = tempfile.mkstemp()
self.tempfiles['files'].append(site_pp) for puppet in benchmark.puppet: os.write(site_pp_buf, 'import "%(file)s"\n' % {'file':puppet}) os.close(site_pp_buf)
@@ -1073,6 +1074,7 @@ class Secstate:
else: handle, fname = tempfile.mkstemp(suffix='.yaml')
self.tempfiles['files'].append(fname) os.write(handle, template % dict_to_external(puppet_content)) os.close(handle) puppet_args = ['/usr/bin/puppet', '--external_node', '/usr/libexec/secstate/secstate_external_node %s' % fname, '--node_terminus', 'exec', site_pp]
@@ -1083,7 +1085,6 @@ class Secstate: if verbose: puppet_args.append('--verbose') subprocess.call(puppet_args)
os.unlink(fname) return True
diff --git a/src/secstate/util.py b/src/secstate/util.py index d30a169..1b208cd 100644 --- a/src/secstate/util.py +++ b/src/secstate/util.py @@ -27,7 +27,6 @@ import time import re import ConfigParser import json -import tempfile import zipfile import libxml2 import libxslt
secstate-devel@lists.fedorahosted.org