Blame dnf/persistor.py

Packit 6f3914
# persistor.py
Packit 6f3914
# Persistence data container.
Packit 6f3914
#
Packit 6f3914
# Copyright (C) 2013-2016 Red Hat, Inc.
Packit 6f3914
#
Packit 6f3914
# This copyrighted material is made available to anyone wishing to use,
Packit 6f3914
# modify, copy, or redistribute it subject to the terms and conditions of
Packit 6f3914
# the GNU General Public License v.2, or (at your option) any later version.
Packit 6f3914
# This program is distributed in the hope that it will be useful, but WITHOUT
Packit 6f3914
# ANY WARRANTY expressed or implied, including the implied warranties of
Packit 6f3914
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit 6f3914
# Public License for more details.  You should have received a copy of the
Packit 6f3914
# GNU General Public License along with this program; if not, write to the
Packit 6f3914
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit 6f3914
# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
Packit 6f3914
# source code or documentation are not subject to the GNU General Public
Packit 6f3914
# License and may only be used or replicated with the express permission of
Packit 6f3914
# Red Hat, Inc.
Packit 6f3914
#
Packit 6f3914
Packit 6f3914
# The current implementation is storing to files in persistdir. Do not depend on
Packit 6f3914
# specific files existing, instead use the persistor API. The underlying
Packit 6f3914
# implementation can change, e.g. for one general file with a serialized dict of
Packit 6f3914
# data etc.
Packit 6f3914
Packit 6f3914
from __future__ import absolute_import
Packit 6f3914
from __future__ import unicode_literals
Packit 6f3914
from dnf.i18n import _
Packit 6f3914
import distutils.version
Packit 6f3914
import dnf.util
Packit 6f3914
import errno
Packit 6f3914
import fnmatch
Packit 6f3914
import json
Packit 6f3914
import logging
Packit 6f3914
import os
Packit 6f3914
import re
Packit 6f3914
Packit 6f3914
logger = logging.getLogger("dnf")
Packit 6f3914
Packit 6f3914
Packit 6f3914
class JSONDB(object):
Packit 6f3914
Packit 6f3914
    def _check_json_db(self, json_path):
Packit 6f3914
        if not os.path.isfile(json_path):
Packit 6f3914
            # initialize new db
Packit 6f3914
            dnf.util.ensure_dir(os.path.dirname(json_path))
Packit 6f3914
            self._write_json_db(json_path, [])
Packit 6f3914
Packit 6f3914
    def _get_json_db(self, json_path, default=[]):
Packit 6f3914
        with open(json_path, 'r') as f:
Packit 6f3914
            content = f.read()
Packit 6f3914
        if content == "":
Packit 6f3914
            # empty file is invalid json format
Packit 6f3914
            logger.warning(_("%s is empty file"), json_path)
Packit 6f3914
            self._write_json_db(json_path, default)
Packit 6f3914
        else:
Packit 6f3914
            try:
Packit 6f3914
                default = json.loads(content)
Packit 6f3914
            except ValueError as e:
Packit 6f3914
                logger.warning(e)
Packit 6f3914
        return default
Packit 6f3914
Packit 6f3914
    @staticmethod
Packit 6f3914
    def _write_json_db(json_path, content):
Packit 6f3914
        with open(json_path, 'w') as f:
Packit 6f3914
            json.dump(content, f)
Packit 6f3914
Packit 6f3914
Packit 6f3914
class RepoPersistor(JSONDB):
Packit 6f3914
    """Persistent data kept for repositories.
Packit 6f3914
Packit 6f3914
    Is arch/releasever specific and stores to cachedir.
Packit 6f3914
Packit 6f3914
    """
Packit 6f3914
Packit 6f3914
    def __init__(self, cachedir):
Packit 6f3914
        self.cachedir = cachedir
Packit 6f3914
        self.db_path = os.path.join(self.cachedir, "expired_repos.json")
Packit 6f3914
        self.expired_to_add = set()
Packit 6f3914
        self.reset_last_makecache = False
Packit 6f3914
Packit 6f3914
    @property
Packit 6f3914
    def _last_makecache_path(self):
Packit 6f3914
        return os.path.join(self.cachedir, "last_makecache")
Packit 6f3914
Packit 6f3914
    def get_expired_repos(self):
Packit 6f3914
        self._check_json_db(self.db_path)
Packit 6f3914
        return set(self._get_json_db(self.db_path))
Packit 6f3914
Packit 6f3914
    def save(self):
Packit 6f3914
        self._check_json_db(self.db_path)
Packit 6f3914
        self._write_json_db(self.db_path, list(self.expired_to_add))
Packit 6f3914
        if self.reset_last_makecache:
Packit 6f3914
            try:
Packit 6f3914
                dnf.util.touch(self._last_makecache_path)
Packit 6f3914
                return True
Packit 6f3914
            except IOError:
Packit 6f3914
                logger.info(_("Failed storing last makecache time."))
Packit 6f3914
                return False
Packit 6f3914
Packit 6f3914
    def since_last_makecache(self):
Packit 6f3914
        try:
Packit 6f3914
            return int(dnf.util.file_age(self._last_makecache_path))
Packit 6f3914
        except OSError:
Packit 6f3914
            logger.info(_("Failed determining last makecache time."))
Packit 6f3914
            return None
Packit 6f3914
Packit 6f3914
Packit 6f3914
class TempfilePersistor(JSONDB):
Packit 6f3914
Packit 6f3914
    def __init__(self, cachedir):
Packit 6f3914
        self.db_path = os.path.join(cachedir, "tempfiles.json")
Packit 6f3914
        self.tempfiles_to_add = set()
Packit 6f3914
        self._empty = False
Packit 6f3914
Packit 6f3914
    def get_saved_tempfiles(self):
Packit 6f3914
        self._check_json_db(self.db_path)
Packit 6f3914
        return self._get_json_db(self.db_path)
Packit 6f3914
Packit 6f3914
    def save(self):
Packit 6f3914
        if not self._empty and not self.tempfiles_to_add:
Packit 6f3914
            return
Packit 6f3914
        self._check_json_db(self.db_path)
Packit 6f3914
        if self._empty:
Packit 6f3914
            self._write_json_db(self.db_path, [])
Packit 6f3914
            return
Packit 6f3914
        if self.tempfiles_to_add:
Packit 6f3914
            data = set(self._get_json_db(self.db_path))
Packit 6f3914
            data.update(self.tempfiles_to_add)
Packit 6f3914
            self._write_json_db(self.db_path, list(data))
Packit 6f3914
Packit 6f3914
    def empty(self):
Packit 6f3914
        self._empty = True