diff --git a/CHANGELOG.md b/CHANGELOG.md index 009c484..50b6582 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [Version 0.7.20](https://github.com/beebeeep/cacus/tree/v0.7.20) (2017-09-18) + * Decrement used quota upon package purging + ## [Version 0.7.19](https://github.com/beebeeep/cacus/tree/v0.7.19) (2017-09-14) * Added compatibility with Azure CosmosDB (mongodb API) * Added support of locks in Consul diff --git a/cacus/repo_daemon.py b/cacus/repo_daemon.py index 0114d15..5be6136 100644 --- a/cacus/repo_daemon.py +++ b/cacus/repo_daemon.py @@ -347,15 +347,39 @@ def get(self, distro): components = [x['component'] for x in (yield c)] pkg_count = yield self.settings['db'].packages[d['distro']].count({}) if 'imported' in d: - result.append({'distro': d['distro'], 'description': d['description'], 'lastupdated': d['lastupdated'].isoformat(), 'packages': pkg_count, - 'type': 'mirror', 'source': d['imported']['from'], 'components': components}) + result.append({ + 'distro': d['distro'], + 'description': d['description'], + 'lastupdated': d['lastupdated'].isoformat(), + 'packages': pkg_count, + 'type': 'mirror', + 'source': d['imported']['from'], + 'components': components + }) elif 'snapshot' in d: - result.append({'distro': d['distro'], 'description': d['description'], 'lastupdated': d['lastupdated'].isoformat(), 'packages': pkg_count, - 'type': 'snapshot', 'origin': d['snapshot']['origin'], 'components': components}) + result.append({ + 'distro': d['distro'], + 'description': d['description'], + 'lastupdated': d['lastupdated'].isoformat(), + 'packages': pkg_count, + 'type': 'snapshot', + 'origin': d['snapshot']['origin'], + 'components': components + }) else: - result.append({'distro': d['distro'], 'description': d['description'], 'lastupdated': d['lastupdated'].isoformat(), 'packages': pkg_count, - 'type': 'general', 'simple': d.get('simple', True), 'strict': d.get('strict', True), - 'gpg_key': d.get('gpg_key', None) or self.settings['config']['gpg']['sign_key'], 'components': components}) + result.append({ + 'distro': d['distro'], + 'description': d['description'], + 'lastupdated': d['lastupdated'].isoformat(), + 'packages': pkg_count, + 'quota': d['quota'] if d['quota'] is not None else -1, + 'quota_used': d['quota_used'], + 'type': 'general', + 'simple': d.get('simple', True), + 'strict': d.get('strict', True), + 'gpg_key': d.get('gpg_key', None) or self.settings['config']['gpg']['sign_key'], + 'components': components + }) self.write({'success': True, 'result': result}) diff --git a/cacus/repo_manage.py b/cacus/repo_manage.py index 1e84849..9b5935b 100644 --- a/cacus/repo_manage.py +++ b/cacus/repo_manage.py @@ -2,7 +2,6 @@ # -*- coding: utf-8 -*- import os -import stat import hashlib import StringIO from debian import debfile, deb822 @@ -157,7 +156,7 @@ def _process_deb_file(self, file): hashes = self.get_hashes(file=f) doc = { - 'size': os.stat(file)[stat.ST_SIZE], + 'size': os.stat(file).st_size, 'sha512': binary.Binary(hashes['sha512'].digest()), 'sha256': binary.Binary(hashes['sha256'].digest()), 'sha1': binary.Binary(hashes['sha1'].digest()), @@ -182,7 +181,7 @@ def _process_source_file(self, file): doc = { 'name': filename, - 'size': os.stat(file)[stat.ST_SIZE], + 'size': os.stat(file).st_size, 'sha512': binary.Binary(hashes['sha512'].digest()), 'sha256': binary.Binary(hashes['sha256'].digest()), 'sha1': binary.Binary(hashes['sha1'].digest()), @@ -596,11 +595,13 @@ def purge_package(self, pkg=None, ver=None, arch=None, distro=None, skipUpdateM affected_comps = set() try: with self.lock(distro, comps=None, already_locked=locked): + freed = 0 result = self.db.sources[distro].find_one_and_delete({'Package': pkg, 'Version': ver}) if result: # found source package matching query, remove this package, its non-deb files and all debs it consists of for f in result['files']: self.storage.delete(f['storage_key']) + freed += f['size'] source = result['_id'] while True: result = self.db.packages[distro].find_one_and_delete({'source': source}) @@ -608,6 +609,7 @@ def purge_package(self, pkg=None, ver=None, arch=None, distro=None, skipUpdateM affected_arches.add(result['Architecture']) affected_comps.update(result['components']) self.storage.delete(result['storage_key']) + freed += result['meta']['size'] else: break else: @@ -621,9 +623,12 @@ def purge_package(self, pkg=None, ver=None, arch=None, distro=None, skipUpdateM affected_arches.update(result['Architecture']) affected_comps.update(result['components']) self.storage.delete(result['storage_key']) + freed += result['meta']['size'] else: raise common.NotFound("Package not found") + self.db.cacus.distros.update_one({'distro': distro}, {'$inc': {'quota_used': -freed}}) + self.log.info("Purged %s_%s from distro %s, %s bytes freed", pkg, ver, distro, freed) if not skipUpdateMeta: if 'all' in affected_arches: affected_arches = None # update all arches in case we have 'all' arch in scope diff --git a/debian/changelog b/debian/changelog index dd1b965..1ca8922 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cacus (0.7.20) unstable; urgency=medium + + * Decrement used quota upon package purging + + -- Cacus maintainer entity Mon, 18 Sep 2017 12:13:16 +0000 + cacus (0.7.19) unstable; urgency=medium * Added compatibility with Azure CosmosDB (mongodb API) diff --git a/setup.py b/setup.py index 9853a24..ac4103f 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ setup( name="cacus", - version="0.7.19", + version="0.7.20", author="Danila Migalin", author_email="me@miga.me.uk", url="https://github.com/beebeeep/cacus", diff --git a/tests/test_repo_manage.py b/tests/test_repo_manage.py index 5ac6698..549756f 100644 --- a/tests/test_repo_manage.py +++ b/tests/test_repo_manage.py @@ -141,9 +141,14 @@ def test_distro_quotas(distro_gen, repo_manager, package): assert package_is_in_repo(repo_manager, pkg1, distro['distro'], comp) distro_settings = repo_manager.db.cacus.distros.find_one({'distro': distro['distro']}) assert distro_settings['quota_used'] == deb1['debsize'] + with pytest.raises(repo_manager.common.FatalError): repo_manager.upload_package(distro['distro'], comp, [deb2['debfile']], changes=None) + repo_manager.purge_package(pkg=pkg1['Package'], ver=pkg1['Version'], distro = distro['distro']) + distro_settings = repo_manager.db.cacus.distros.find_one({'distro': distro['distro']}) + assert distro_settings['quota_used'] == 0 + def test_delete_snapshot(distro, repo_manager): n = repo_manager._get_snapshot_name(distro['distro'], 'testsnap')