From 4c58fc9fbe8b43ab08f9e2b0a7d260c0fa66948c Mon Sep 17 00:00:00 2001 From: Fabio Erculiani Date: Fri, 29 Mar 2013 11:41:05 +0000 Subject: [PATCH] [entropy*] create const_mkdtemp() as tempfile.mkdtemp() wrapper. using /tmp as TMPDIR is a no go, since on modern systems, /tmp is on tmpfs with a very limited amount of fs size assigned. Use /var/tmp/entropy (or /var/tmp as fallback) instead. --- lib/entropy/cache.py | 11 +- lib/entropy/client/interfaces/db.py | 6 +- lib/entropy/client/interfaces/methods.py | 4 +- lib/entropy/const.py | 29 +++++ lib/entropy/qa.py | 4 +- lib/entropy/security.py | 7 +- lib/entropy/server/interfaces/db.py | 7 +- lib/entropy/server/interfaces/main.py | 6 +- lib/entropy/server/interfaces/mirrors.py | 6 +- .../interfaces/portage_plugin/__init__.py | 114 +++++++++--------- .../interfaces/portage_plugin/xpaktools.py | 4 +- .../plugins/interfaces/ssh_plugin.py | 4 +- 12 files changed, 120 insertions(+), 82 deletions(-) diff --git a/lib/entropy/cache.py b/lib/entropy/cache.py index 0b4ddbb40..f25041ff4 100644 --- a/lib/entropy/cache.py +++ b/lib/entropy/cache.py @@ -21,7 +21,8 @@ import sys import tempfile from entropy.const import etpConst, const_debug_write, \ - const_debug_enabled, const_pid_exists, const_setup_perms + const_debug_enabled, const_pid_exists, const_setup_perms, \ + const_mkdtemp from entropy.core import Singleton from entropy.misc import TimeScheduled, ParallelTask, Lifo import time @@ -491,9 +492,13 @@ class MtimePingus(object): try: if not os.path.isdir(MtimePingus.PINGUS_DIR): os.makedirs(MtimePingus.PINGUS_DIR, 0o775) - const_setup_perms(MtimePingus.PINGUS_DIR, etpConst['entropygid']) + const_setup_perms( + MtimePingus.PINGUS_DIR, + etpConst['entropygid']) + except (OSError, IOError,): - MtimePingus.PINGUS_DIR = tempfile.mkdtemp() # what else can I do? + MtimePingus.PINGUS_DIR = const_mkdtemp( + prefix="pingus_dir") def _hash_key(self, key): """ diff --git a/lib/entropy/client/interfaces/db.py b/lib/entropy/client/interfaces/db.py index b3d185820..5f3a8c3ff 100644 --- a/lib/entropy/client/interfaces/db.py +++ b/lib/entropy/client/interfaces/db.py @@ -21,7 +21,7 @@ import time from entropy.const import const_debug_write, const_setup_perms, etpConst, \ const_set_nice_level, const_setup_file, const_convert_to_unicode, \ - const_debug_enabled + const_debug_enabled, const_mkdtemp from entropy.output import blue, darkred, red, darkgreen, purple, teal, brown, \ bold, TextInterface from entropy.dump import dumpobj, loadobj @@ -1147,7 +1147,7 @@ class AvailablePackagesRepositoryUpdater(object): if not (os.path.isfile(mypath) and os.access(mypath, os.R_OK)): continue - tmpdir = tempfile.mkdtemp() + tmpdir = const_mkdtemp(prefix="_standard_items_download") repo_dir = repo_data['dbpath'] enc = etpConst['conf_encoding'] try: @@ -1344,7 +1344,7 @@ class AvailablePackagesRepositoryUpdater(object): if pk_avail: - tmp_dir = tempfile.mkdtemp() + tmp_dir = const_mkdtemp(prefix="_install_gpg_key") repo_tmp_sec = self._entropy.RepositorySecurity( keystore_dir = tmp_dir) # try to install and get fingerprint diff --git a/lib/entropy/client/interfaces/methods.py b/lib/entropy/client/interfaces/methods.py index aa9da737f..05a558afb 100644 --- a/lib/entropy/client/interfaces/methods.py +++ b/lib/entropy/client/interfaces/methods.py @@ -28,7 +28,7 @@ from entropy.i18n import _ from entropy.const import etpConst, const_debug_write, etpSys, \ const_setup_file, initconfig_entropy_constants, const_pid_exists, \ const_setup_perms, const_isstring, const_convert_to_unicode, \ - const_isnumber, const_convert_to_rawstring + const_isnumber, const_convert_to_rawstring, const_mkdtemp from entropy.exceptions import RepositoryError, SystemDatabaseError, \ RepositoryPluginError, SecurityError, EntropyPackageException from entropy.db.skel import EntropyRepositoryBase @@ -894,7 +894,7 @@ class RepositoryMixin: doesn't contain a valid package repository. """ basefile = os.path.basename(package_file_path) - db_dir = tempfile.mkdtemp() + db_dir = const_mkdtemp(prefix="add_package_repository") dbfile = os.path.join(db_dir, etpConst['etpdatabasefile']) dump_rc = entropy.tools.dump_entropy_metadata(package_file_path, dbfile) if not dump_rc: diff --git a/lib/entropy/const.py b/lib/entropy/const.py index 4d0018558..8cfb40f9b 100644 --- a/lib/entropy/const.py +++ b/lib/entropy/const.py @@ -41,6 +41,7 @@ import gzip import bz2 import grp import pwd +import tempfile import traceback import threading try: @@ -1010,6 +1011,34 @@ def const_setup_directory(dirpath): const_setup_perms(dirpath, etpConst['entropygid'], recursion=False) +def const_mkdtemp(dir=None, prefix=None, suffix=None): + """ + mkdtemp() wrapper that creates a temporary directory inside + etpConst['entropyunpackdir'] if dir is None. + + @keyword dir: TMPDIR + @type dir: string + @keyword prefix: the mkdtemp prefix argument + @type prefix: string + @keyword suffix: the mkdtemp suffix argument + @type suffix: string + @rtype: string + @return: the temporary directory path + """ + if dir is None: + dir = etpConst['entropyunpackdir'] + try: + os.makedirs(dir) + except OSError as err: + if err.errno != errno.EEXIST: + dir = os.getenv("TMPDIR", "/var/tmp") + + if prefix is None: + prefix = "" + if suffix is None: + suffix = "" + return tempfile.mkdtemp(dir=dir, prefix=prefix, suffix=suffix) + def const_get_chmod(myfile): """ This function get the current permissions of the specified diff --git a/lib/entropy/qa.py b/lib/entropy/qa.py index 37075b663..8f950324d 100644 --- a/lib/entropy/qa.py +++ b/lib/entropy/qa.py @@ -27,7 +27,7 @@ import codecs from entropy.output import TextInterface from entropy.misc import Lifo -from entropy.const import etpConst, etpSys, const_debug_write, \ +from entropy.const import etpConst, etpSys, const_debug_write, const_mkdtemp, \ const_debug_write, const_convert_to_rawstring, const_is_python3 from entropy.output import blue, darkgreen, red, darkred, bold, purple, brown, \ teal @@ -682,7 +682,7 @@ class QAInterface(TextInterface, EntropyPluginStore): files_list_path = None if dump_results_to_file: - tmp_dir = tempfile.mkdtemp() + tmp_dir = const_mkdtemp(prefix="qa.libtest") syms_list_path = os.path.join(tmp_dir, "libtest_syms.txt") files_list_path = os.path.join(tmp_dir, "libtest_files.txt") diff --git a/lib/entropy/security.py b/lib/entropy/security.py index bef3dcf5b..ec786ee52 100644 --- a/lib/entropy/security.py +++ b/lib/entropy/security.py @@ -17,12 +17,11 @@ import errno import shutil import subprocess import datetime -import tempfile import time import codecs from entropy.exceptions import EntropyException -from entropy.const import etpConst, const_setup_perms, \ +from entropy.const import etpConst, const_setup_perms, const_mkdtemp, \ const_debug_write, const_setup_file, const_convert_to_unicode, \ const_convert_to_rawstring, const_is_python3, const_debug_enabled from entropy.i18n import _ @@ -303,7 +302,7 @@ class System: if pk_avail: - tmp_dir = tempfile.mkdtemp() + tmp_dir = const_mkdtemp() repo_tmp_sec = self._entropy.RepositorySecurity( keystore_dir = tmp_dir) # try to install and get fingerprint @@ -1881,7 +1880,7 @@ class Repository: """ tmp_dir = None try: - tmp_dir = tempfile.mkdtemp(prefix=".entropy.security.get_fp") + tmp_dir = const_mkdtemp(prefix=".entropy.security.get_fp") args = self.__default_gpg_args(preserve_perms = False, homedir = tmp_dir) args += ["--import", key_path] diff --git a/lib/entropy/server/interfaces/db.py b/lib/entropy/server/interfaces/db.py index d9f635c2e..82a744584 100644 --- a/lib/entropy/server/interfaces/db.py +++ b/lib/entropy/server/interfaces/db.py @@ -26,7 +26,8 @@ import bz2 import codecs import threading -from entropy.const import etpConst, const_setup_file, const_convert_to_unicode +from entropy.const import etpConst, const_setup_file, const_mkdtemp, \ + const_convert_to_unicode from entropy.core import Singleton from entropy.db import EntropyRepository from entropy.transceivers import EntropyTransceiver @@ -666,7 +667,7 @@ class ServerPackagesRepositoryUpdater(object): enc = etpConst['conf_encoding'] for symname, symfile in spm_syms.items(): - mytmpdir = tempfile.mkdtemp(dir = etpConst['entropyunpackdir']) + mytmpdir = const_mkdtemp(prefix="entropy.server._get_files_to_sync") tmp_dirs.append(mytmpdir) mytmpfile = os.path.join(mytmpdir, os.path.basename(symfile)) mylink = os.readlink(symfile) @@ -709,7 +710,7 @@ class ServerPackagesRepositoryUpdater(object): try: - mytmpdir = tempfile.mkdtemp(prefix = "entropy.server") + mytmpdir = const_mkdtemp(prefix="entropy.server._download") self._entropy.output( "[repo:%s|%s|%s] %s" % ( diff --git a/lib/entropy/server/interfaces/main.py b/lib/entropy/server/interfaces/main.py index 2621354d6..7b4dd9aaf 100644 --- a/lib/entropy/server/interfaces/main.py +++ b/lib/entropy/server/interfaces/main.py @@ -27,7 +27,7 @@ from entropy.exceptions import OnlineMirrorError, PermissionDenied, \ from entropy.const import etpConst, etpSys, const_setup_perms, \ const_create_working_dirs, const_convert_to_unicode, \ const_setup_file, const_get_stringtype, const_debug_write, \ - const_debug_enabled, const_convert_to_rawstring + const_debug_enabled, const_convert_to_rawstring, const_mkdtemp from entropy.output import purple, red, darkgreen, \ bold, brown, blue, darkred, teal from entropy.cache import EntropyCacher @@ -2377,7 +2377,7 @@ class Server(Client): all_fine = True - tmp_down_dir = tempfile.mkdtemp(prefix = "entropy.server") + tmp_down_dir = const_mkdtemp(prefix="entropy.server") download_queue = {} dbconn = self.open_server_repository(repository_id, read_only = False, @@ -4591,7 +4591,7 @@ class Server(Client): """ pkg_list_path = None if dump_results_to_file: - tmp_dir = tempfile.mkdtemp(prefix = "entropy.server") + tmp_dir = const_mkdtemp(prefix="entropy.server") pkg_list_path = os.path.join(tmp_dir, "libtest_broken.txt") dmp_data = [ (_("Broken and matched packages list"), pkg_list_path,), diff --git a/lib/entropy/server/interfaces/mirrors.py b/lib/entropy/server/interfaces/mirrors.py index b1f1351b2..378e60150 100644 --- a/lib/entropy/server/interfaces/mirrors.py +++ b/lib/entropy/server/interfaces/mirrors.py @@ -22,7 +22,7 @@ import codecs from entropy.exceptions import EntropyPackageException from entropy.output import red, darkgreen, bold, brown, blue, darkred, \ darkblue, purple, teal -from entropy.const import etpConst, const_get_int, const_get_cpus +from entropy.const import etpConst, const_get_int, const_get_cpus, const_mkdtemp from entropy.cache import EntropyCacher from entropy.i18n import _ from entropy.misc import RSS, ParallelTask @@ -145,7 +145,7 @@ class Server(object): # nothing to do, not a file continue - tmp_dir = tempfile.mkdtemp(prefix = "entropy.server") + tmp_dir = const_mkdtemp(prefix = "entropy.server") down_path = os.path.join(tmp_dir, os.path.basename(filename)) tries = 4 @@ -2527,7 +2527,7 @@ class Server(object): mirrors = self._entropy.remote_repository_mirrors(repository_id) rss_path = self._entropy._get_local_repository_notice_board_file( repository_id) - mytmpdir = tempfile.mkdtemp(prefix = "entropy.server") + mytmpdir = const_mkdtemp(prefix = "entropy.server") self._entropy.output( "[%s] %s %s" % ( diff --git a/lib/entropy/spm/plugins/interfaces/portage_plugin/__init__.py b/lib/entropy/spm/plugins/interfaces/portage_plugin/__init__.py index c1aed3127..99dbb6e5f 100644 --- a/lib/entropy/spm/plugins/interfaces/portage_plugin/__init__.py +++ b/lib/entropy/spm/plugins/interfaces/portage_plugin/__init__.py @@ -28,7 +28,7 @@ import warnings from entropy.const import etpConst, const_get_stringtype, \ const_convert_to_unicode, const_convert_to_rawstring, \ const_setup_perms, const_setup_file, const_is_python3, \ - const_debug_enabled + const_debug_enabled, const_mkdtemp from entropy.exceptions import FileNotFound, InvalidDependString, \ InvalidAtom, EntropyException from entropy.output import darkred, darkgreen, brown, darkblue, teal, \ @@ -1308,8 +1308,7 @@ class PortagePlugin(SpmPlugin): data['datecreation'] = str(os.path.getmtime(package_file)) data['size'] = str(entropy.tools.get_file_size(package_file)) - tmp_dir = tempfile.mkdtemp(prefix="entropy.spm._extract", - dir=etpConst['entropyunpackdir']) + tmp_dir = const_mkdtemp(prefix="entropy.spm._extract") meta_dir = os.path.join(tmp_dir, "portage") pkg_dir = os.path.join(tmp_dir, "pkg") os.mkdir(meta_dir) @@ -2067,8 +2066,7 @@ class PortagePlugin(SpmPlugin): if portage_tmpdir is None: # /tmp might be mounted using tmpfs, noexec, etc - portage_tmpdir = tempfile.mkdtemp( - dir=etpConst['entropyunpackdir']) + portage_tmpdir = const_mkdtemp(prefix="tmpdir_doebuild") portage_tmpdir_created = True elif not os.path.isdir(portage_tmpdir): os.makedirs(portage_tmpdir, 0o744) @@ -3100,8 +3098,8 @@ class PortagePlugin(SpmPlugin): # lock vdb before making changes with self._PortageVdbLocker(self, root = root): - tmp_dir = tempfile.mkdtemp(dir=cat_dir, - prefix="-MERGING-") + tmp_dir = const_mkdtemp( + dir=cat_dir, prefix="-MERGING-") vdb_failed = False try: @@ -3416,60 +3414,66 @@ class PortagePlugin(SpmPlugin): @staticmethod def _test_environment_bz2(package_path): - tmp_path = tempfile.mkdtemp() - xpaktools.extract_xpak(package_path, tmpdir = tmp_path) - if not os.listdir(tmp_path): - shutil.rmtree(tmp_path) - return 1, "unable to extract xpak metadata" - - # make sure we have the environment.bz2 file to check - env_file = os.path.join(tmp_path, PortagePlugin.ENV_FILE_COMP) - if not (os.path.isfile(env_file) and os.access(env_file, os.R_OK)): - shutil.rmtree(tmp_path) - return 2, "unable to locate %s file" % ( - PortagePlugin.ENV_FILE_COMP,) - - # check if we have an alternate setting for LC* - sys_settings = SystemSettings() - srv_plug_id = etpConst['system_settings_plugins_ids']['server_plugin'] + tmp_path = None try: - qa_langs = sys_settings[srv_plug_id]['server']['qa_langs'] - except KeyError: - qa_langs = ["en_US", "C"] + tmp_path = const_mkdtemp(prefix="_test_environment_bz2") - qa_rlangs = [const_convert_to_rawstring("LC_ALL="+x) for x in qa_langs] + xpaktools.extract_xpak(package_path, tmpdir = tmp_path) + if not os.listdir(tmp_path): + return 1, "unable to extract xpak metadata" - valid_lc_all = False - lc_found = False - msg = None - lc_all_str = const_convert_to_rawstring("LC_ALL") - found_lang = None - bz_f = None - try: + # make sure we have the environment.bz2 file to check + env_file = os.path.join(tmp_path, PortagePlugin.ENV_FILE_COMP) + if not (os.path.isfile(env_file) and os.access(env_file, os.R_OK)): + return 2, "unable to locate %s file" % ( + PortagePlugin.ENV_FILE_COMP,) - # read env file - bz_f = bz2.BZ2File(env_file, "r") + # check if we have an alternate setting for LC* + sys_settings = SystemSettings() + plug_id = etpConst['system_settings_plugins_ids']['server_plugin'] + try: + qa_langs = sys_settings[plug_id]['server']['qa_langs'] + except KeyError: + qa_langs = ["en_US", "C"] + + qa_rlangs = [const_convert_to_rawstring( + "LC_ALL="+x) for x in qa_langs] + + valid_lc_all = False + lc_found = False + msg = None + lc_all_str = const_convert_to_rawstring("LC_ALL") + found_lang = None + bz_f = None + try: + + # read env file + bz_f = bz2.BZ2File(env_file, "r") + + for line in bz_f.readlines(): + if not line.startswith(lc_all_str): + continue + lc_found = True + found_lang = line.strip() + for lang in qa_rlangs: + if line.startswith(lang): + valid_lc_all = True + break + finally: + if bz_f is not None: + bz_f.close() + + env_rc = 0 + if lc_found and (not valid_lc_all): + msg = "LC_ALL not set to => %s (but: %s)" % ( + qa_langs, found_lang,) + env_rc = 1 + + return env_rc, msg - for line in bz_f.readlines(): - if not line.startswith(lc_all_str): - continue - lc_found = True - found_lang = line.strip() - for lang in qa_rlangs: - if line.startswith(lang): - valid_lc_all = True - break finally: - if bz_f is not None: - bz_f.close() - - env_rc = 0 - if lc_found and (not valid_lc_all): - msg = "LC_ALL not set to => %s (but: %s)" % (qa_langs, found_lang,) - env_rc = 1 - shutil.rmtree(tmp_path) - - return env_rc, msg + if tmp_path is not None: + shutil.rmtree(tmp_path) @staticmethod def _config_updates_make_conf(entropy_client, repo): diff --git a/lib/entropy/spm/plugins/interfaces/portage_plugin/xpaktools.py b/lib/entropy/spm/plugins/interfaces/portage_plugin/xpaktools.py index f1633d9aa..6d2245f2e 100644 --- a/lib/entropy/spm/plugins/interfaces/portage_plugin/xpaktools.py +++ b/lib/entropy/spm/plugins/interfaces/portage_plugin/xpaktools.py @@ -14,7 +14,7 @@ import tempfile import os import errno import shutil -from entropy.const import const_is_python3 +from entropy.const import etpConst, const_is_python3, const_mkdtemp from entropy.output import TextInterface from entropy.spm.plugins.factory import get_default_instance from entropy.spm.plugins.interfaces.portage_plugin import xpak @@ -81,7 +81,7 @@ def unpack_xpak(xpakfile, tmpdir = None): @rtype: """ if tmpdir is None: - tmpdir = tempfile.mkdtemp() + tmpdir = const_mkdtemp(prefix="unpack_xpak") elif not os.path.isdir(tmpdir): raise AttributeError("tmpdir %s does not exist" % (tmpdir,)) try: diff --git a/lib/entropy/transceivers/uri_handlers/plugins/interfaces/ssh_plugin.py b/lib/entropy/transceivers/uri_handlers/plugins/interfaces/ssh_plugin.py index ff1ecf96d..1d436ed98 100644 --- a/lib/entropy/transceivers/uri_handlers/plugins/interfaces/ssh_plugin.py +++ b/lib/entropy/transceivers/uri_handlers/plugins/interfaces/ssh_plugin.py @@ -18,7 +18,7 @@ import shutil import codecs from entropy.const import const_isnumber, const_debug_write, \ - etpConst + const_mkdtemp, etpConst from entropy.output import brown, darkgreen, teal from entropy.i18n import _ from entropy.transceivers.exceptions import TransceiverConnectionError @@ -251,7 +251,7 @@ class EntropySshUriHandler(EntropyUriHandler): except (shutil.Error, OSError, IOError,): pass - tmp_dir = tempfile.mkdtemp() + tmp_dir = const_mkdtemp(prefix="ssh_plugin.download_many") args = [EntropySshUriHandler._TXC_CMD] c_args, remote_str = self._setup_common_args(remote_paths.pop())