[elbe-devel] [PATCH v2 5/7] Prevent double file access
Bastian Germann
bage at linutronix.de
Tue Dec 20 11:31:28 CET 2022
Windows locks an open file. Prevent files that are open from being
opened again on the client side.
To that end, eliminate the use of NamedTemporaryFile with .name
access.
Signed-off-by: Bastian Germann <bage at linutronix.de>
---
elbepack/initvmaction.py | 13 ++++++-------
elbepack/xmlpreprocess.py | 25 ++++++++++++++++---------
2 files changed, 22 insertions(+), 16 deletions(-)
diff --git a/elbepack/initvmaction.py b/elbepack/initvmaction.py
index af153de8fc..44df1b1674 100644
--- a/elbepack/initvmaction.py
+++ b/elbepack/initvmaction.py
@@ -13,8 +13,6 @@ import time
import os
import datetime
-from tempfile import NamedTemporaryFile
-
import elbepack
from elbepack.treeutils import etree
from elbepack.directories import elbe_exe
@@ -266,16 +264,17 @@ class AttachAction(InitVMAction):
def submit_with_repodir_and_dl_result(xmlfile, cdrom, opt):
+ fname = f'elbe-repodir-{time.time_ns()}.xml'
+ preprocess_xmlfile = os.path.join(os.path.dirname(xmlfile), fname)
try:
- with NamedTemporaryFile(suffix=".xml", prefix="elbe-repodir",
- dir=os.path.dirname(xmlfile)) as tmpfile:
- preprocess_xmlfile = tmpfile.name
- with Repodir(xmlfile, preprocess_xmlfile):
- submit_and_dl_result(preprocess_xmlfile, cdrom, opt)
+ with Repodir(xmlfile, preprocess_xmlfile):
+ submit_and_dl_result(preprocess_xmlfile, cdrom, opt)
except RepodirError as err:
print("elbe repodir failed", file=sys.stderr)
print(err, file=sys.stderr)
sys.exit(20)
+ finally:
+ os.remove(preprocess_xmlfile)
def submit_and_dl_result(xmlfile, cdrom, opt):
diff --git a/elbepack/xmlpreprocess.py b/elbepack/xmlpreprocess.py
index 86a913b309..8481abdd55 100644
--- a/elbepack/xmlpreprocess.py
+++ b/elbepack/xmlpreprocess.py
@@ -8,8 +8,9 @@
import os
import re
import sys
+import tempfile
+import time
-from tempfile import NamedTemporaryFile
from optparse import OptionGroup
from itertools import islice
from urllib.error import HTTPError,URLError
@@ -17,7 +18,7 @@ from urllib.request import urlopen
from passlib.hash import sha512_crypt
from lxml import etree
-from lxml.etree import XMLParser, parse, Element
+from lxml.etree import XMLParser, Element
from elbepack.archivedir import ArchivedirError, combinearchivedir
from elbepack.config import cfg
@@ -272,7 +273,12 @@ def preprocess_passwd(xml):
adduser.attrib['passwd_hashed'] = sha512_crypt.hash(passwd)
del adduser.attrib['passwd']
-def xmlpreprocess(fname, output, variants=None, proxy=None):
+def xmlpreprocess(xml_input_file, xml_output_file, variants=None, proxy=None):
+ """Preprocesses the input XML data to make sure the `output`
+ can be validated against the current schema.
+ `xml_input_file` is either a file-like object or a path (str) to the input file.
+ `xml_output_file` is either a file-like object or a path (str) to the output file.
+ """
# pylint: disable=too-many-locals
# pylint: disable=too-many-branches
@@ -289,7 +295,7 @@ def xmlpreprocess(fname, output, variants=None, proxy=None):
schema = etree.XMLSchema(schema_tree)
try:
- xml = parse(fname, parser=parser)
+ xml = etree.parse(xml_input_file, parser=parser)
xml.xinclude()
# Variant management
@@ -360,7 +366,7 @@ def xmlpreprocess(fname, output, variants=None, proxy=None):
if schema.validate(xml):
# if validation succedes write xml file
xml.write(
- output,
+ xml_output_file,
encoding="UTF-8",
pretty_print=True,
compression=9)
@@ -390,10 +396,11 @@ class PreprocessWrapper:
self.options += f' --variants "{opt.variant}"'
def __enter__(self):
- self.outxml = NamedTemporaryFile(prefix='elbe', suffix='xml')
+ fname = f'elbe-{time.time_ns()}.xml'
+ self.outxml = os.path.join(tempfile.gettempdir(), fname)
cmd = (f'{sys.executable} {elbe_exe} preprocess {self.options} '
- f'-o {self.outxml.name} {self.xmlfile}')
+ f'-o {self.outxml} {self.xmlfile}')
ret, _, err = command_out_stderr(cmd)
if ret != 0:
print("elbe preprocess failed.", file=sys.stderr)
@@ -403,7 +410,7 @@ class PreprocessWrapper:
return self
def __exit__(self, _typ, _value, _traceback):
- self.outxml = None
+ os.remove(self.outxml)
@staticmethod
def add_options(oparser):
@@ -420,4 +427,4 @@ class PreprocessWrapper:
@property
def preproc(self):
- return self.outxml.name
+ return self.outxml
--
2.30.2
More information about the elbe-devel
mailing list