Blame dnf/persistor.py

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