Skip to content

Commit

Permalink
Command "clean": clean only enabled repos (RhBug:1330211)
Browse files Browse the repository at this point in the history
Added option "--enabled".
Command "clean" cleans temporary files for all repositories by default.
Only enabled repositories are cleaned by using option "--enabled".
Option "--enabled" is automaticaly activated if list of enabled repositories
is changed from commandline ("--repo". "--enablerepo", "--disablerepo").
  • Loading branch information
jrohel committed Oct 16, 2017
1 parent 48e4d1f commit 124e144
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 10 deletions.
34 changes: 29 additions & 5 deletions dnf/cli/commands/clean.py
Expand Up @@ -71,6 +71,13 @@ def _clean(dirpath, files):
return count


def _is_repo_cached(repo, files):
"""Return true if the repo have some cached metadata around."""
metapat = dnf.repo.repo_cache_files_pattern('metadata', repo)
matches = (re.match(metapat, f) for f in files)
return bool(matches)


def _cached_repos(files):
"""Return the repo IDs that have some cached metadata around."""
metapat = dnf.repo.CACHE_FILES['metadata']
Expand All @@ -88,11 +95,18 @@ class CleanCommand(commands.Command):

@staticmethod
def set_argparser(parser):
parser.add_argument('--enabled', action='store_true',
dest='enabled',
help=_('Clean only enabled repositories'))
parser.add_argument('type', nargs='+',
choices=_CACHE_TYPES.keys(),
help=_('Metadata type to clean'))
choices=_CACHE_TYPES.keys(),
help=_('Metadata type to clean'))

def run(self):
all_repos = not (self.opts.enabled or self.opts.repos_ed)
if not all_repos and not self.base.repos._any_enabled():
logger.info(_('There are no enabled repos. Nothing to do.'))
return
cachedir = self.base.conf.cachedir
md_lock = dnf.lock.build_metadata_lock(cachedir, True)
download_lock = dnf.lock.build_download_lock(cachedir, True)
Expand All @@ -105,12 +119,22 @@ def run(self):
logger.debug(_('Cleaning data: ' + ' '.join(types)))

if 'expire-cache' in types:
expired = _cached_repos(files)
self.base._repo_persistor.expired_to_add.update(expired)
if all_repos:
repos_expire = _cached_repos(files)
else:
repos_expire = set()
for repo in self.base.repos.iter_enabled():
if _is_repo_cached(repo, files):
repos_expire.add(repo.id)
self.base._repo_persistor.expired_to_add.update(repos_expire)
types.remove('expire-cache')
logger.info(_('Cache was expired'))

patterns = [dnf.repo.CACHE_FILES[t] for t in types]
if all_repos:
patterns = [dnf.repo.CACHE_FILES[t] for t in types]
else:
patterns = [dnf.repo.repo_cache_files_pattern(t, repo)
for t in types for repo in self.base.repos.iter_enabled()]
count = _clean(cachedir, _filter(files, patterns))
logger.info(P_('%d file removed', '%d files removed', count) % count)
return
Expand Down
24 changes: 20 additions & 4 deletions dnf/repo.py
Expand Up @@ -70,6 +70,19 @@
logger = logging.getLogger("dnf")


# Returns regex pattern matching any filename that is repo-specific cache data of a
# particular type for given repo. The filename is expected to not contain the base cachedir
# path components.
def repo_cache_files_pattern(type, repo):
if type == 'metadata':
return r'^%s\/.*(xml(\.gz|\.xz|\.bz2)?|asc|cachecookie|%s)$' % \
(repo._cachedir_name, dnf.repo._MIRRORLIST_FILENAME)
if type == 'packages':
return r'^%s\/%s\/.+rpm$' % (repo._cachedir_name, dnf.repo._PACKAGES_RELATIVE_DIR)
if type == 'dbcache':
return r'^%s(\.solv|(-filenames|-presto|-updateinfo)\.solvx)$' % repo.id


def repo_id_invalid(repo_id):
# :api
"""Return index of an invalid character in the repo ID (if present)."""
Expand Down Expand Up @@ -499,7 +512,7 @@ def end(self):

# use the local cache even if it's expired. download if there's no cache.
SYNC_LAZY = 1
# use the local cache, even if it's expired, never download.
# use the local cache, even if it's expired, never download.
SYNC_ONLY_CACHE = 2
# try the cache, if it is expired download new md.
SYNC_TRY_CACHE = 3
Expand Down Expand Up @@ -541,12 +554,15 @@ def repofile(self, value):
self._repofile = value

@property
def _cachedir(self):
def _cachedir_name(self):
s = self.metalink or self.mirrorlist or \
(self.baseurl and self.baseurl[0]) or self.id
digest = hashlib.sha256(s.encode('utf8')).hexdigest()[:16]
repodir = "%s-%s" % (self.id, digest)
return os.path.join(self.basecachedir, repodir)
return "%s-%s" % (self.id, digest)

@property
def _cachedir(self):
return os.path.join(self.basecachedir, self._cachedir_name)

@property
def _filelists_fn(self):
Expand Down
4 changes: 3 additions & 1 deletion doc/command_ref.rst
Expand Up @@ -411,7 +411,9 @@ Clean Command
-------------
Performs cleanup of temporary files kept for repositories. This includes any
such data left behind from disabled or removed repositories as well as for
different distribution release versions.
different distribution release versions by default.
However, command can be limited to enabled repositories using option ``--enabled``.
Option ``--enabled`` is automaticaly activated if list of enabled repositories is changed from commandline (``--repo``. ``--enablerepo``, ``--disablerepo``).

``dnf clean dbcache``
Removes cache files generated from the repository metadata. This forces DNF
Expand Down

0 comments on commit 124e144

Please sign in to comment.