Commit 63b7a49b authored by Enrico Zini's avatar Enrico Zini
Browse files

Ported to django_housekeeping

parent 1b7adab2
......@@ -5,17 +5,12 @@ Debian NM Front Desk web application
### Dependencies
apt-get install python-django python-ldap python-psycopg2 python-xapian \
python-debian python-django-south python-markdown
python-debian python-django-south python-markdown python-debiancontributors
# http://anonscm.debian.org/gitweb/?p=users/enrico/django_maintenance.git
git clone https://alioth.debian.org/anonscm/git/users/enrico/django_maintenance.git
# https://github.com/spanezz/django-housekeeping
git clone https://github.com/spanezz/django-housekeeping
(you can either build the package from it or symlink the module directory
into the nm.debian.org sources)
# http://anonscm.debian.org/gitweb/?p=nm/python-debiancontributors.git
git clone https://alioth.debian.org/anonscm/git/nm/python-debiancontributors.git
(you can either build the package from it or symlink the module directory
into the nm.debian.org sources)
into the contributors.debian.org sources)
# https://github.com/jsocol/django-ratelimit
git clone https://github.com/jsocol/django-ratelimit.git
......
# nm.debian.org website maintenance
# nm.debian.org website housekeeping
#
# Copyright (C) 2012--2014 Enrico Zini <enrico@debian.org>
#
......@@ -20,7 +20,7 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from django.conf import settings
from django_maintenance import MaintenanceTask
import django_housekeeping as hk
from django.db import connection, transaction
from django.contrib.sites.models import Site
from . import models as bmodels
......@@ -36,7 +36,9 @@ log = logging.getLogger(__name__)
BACKUP_DIR = getattr(settings, "BACKUP_DIR", None)
class MakeLink(MaintenanceTask):
STAGES = ["backup", "main", "stats"]
class MakeLink(hk.Task):
NAME = "link"
def __init__(self, *args, **kw):
......@@ -49,11 +51,11 @@ class MakeLink(MaintenanceTask):
else:
return "https://%s%s" % (self.site.domain, obj.get_absolute_url())
class BackupDB(MaintenanceTask):
class BackupDB(hk.Task):
"""
Backup of the whole database
"""
def run(self):
def run_backup(self, stage):
if BACKUP_DIR is None:
log.info("BACKUP_DIR is not set: skipping backups")
return
......@@ -69,7 +71,7 @@ class BackupDB(MaintenanceTask):
# Base filename for the backup
fname = os.path.join(BACKUP_DIR, datetime.datetime.utcnow().strftime("%Y%m%d-db-full.json.gz"))
log.info("%s: backing up to %s", self.IDENTIFIER, fname)
if self.maint.dry_run: return
if self.hk.dry_run: return
# Use a sequential number to avoid overwriting old backups when run manually
while os.path.exists(fname):
......@@ -83,7 +85,7 @@ class BackupDB(MaintenanceTask):
finally:
gzfd.close()
class Inconsistencies(MaintenanceTask):
class Inconsistencies(hk.Task):
"""
Keep track of inconsistencies
"""
......@@ -99,7 +101,7 @@ class Inconsistencies(MaintenanceTask):
except ImportError:
self.imodels = None
def run(self):
def run_main(self, stage):
"""
Reset the inconsistency log at the start of maintenance
"""
......@@ -132,12 +134,12 @@ class Inconsistencies(MaintenanceTask):
def log_person(self, maintproc, person, log, **kw):
if self.imodels:
self.imodels.InconsistentPerson.add_info(person, log=log, **kw)
self.log("%s: %s %s", maintproc.IDENTIFIER, self.maint.link(person), log)
self.log("%s: %s %s", maintproc.IDENTIFIER, self.hk.link(person), log)
def log_process(self, maintproc, process, log, **kw):
if self.imodels:
self.imodels.InconsistentProcess.add_info(process, log=log, **kw)
self.log("%s: %s %s", maintproc.IDENTIFIER, self.maint.link(process), log)
self.log("%s: %s %s", maintproc.IDENTIFIER, self.hk.link(process), log)
def log_fingerprint(self, maintproc, fpr, log, **kw):
fpr = fpr.replace(" ", "").upper()
......@@ -149,13 +151,13 @@ class Inconsistencies(MaintenanceTask):
# Delay execution until finalization phase, when all inconsistencies
# we want to annotate have been found and logged
self.ann_person.append((maintproc, person, log, kw))
self.logger.debug("%s: annotation for %s: %s", maintproc.IDENTIFIER, self.maint.link(person), log)
self.logger.debug("%s: annotation for %s: %s", maintproc.IDENTIFIER, self.hk.link(person), log)
def annotate_process(self, maintproc, process, log, **kw):
# Delay execution until finalization phase, when all inconsistencies
# we want to annotate have been found and logged
self.ann_process.append((maintproc, process, log, kw))
self.logger.debug("%s: annotation for %s: %s", maintproc.IDENTIFIER, self.maint.link(process), log)
self.logger.debug("%s: annotation for %s: %s", maintproc.IDENTIFIER, self.hk.link(process), log)
def annotate_fingerprint(self, maintproc, fpr, log, **kw):
# Delay execution until finalization phase, when all inconsistencies
......@@ -163,7 +165,7 @@ class Inconsistencies(MaintenanceTask):
self.ann_fpr.append((maintproc, fpr, log, kw))
self.logger.debug("%s: annotation for %s: %s", maintproc.IDENTIFIER, fpr, log)
def log_stats(self):
def run_stats(self, stage):
# FIXME: we're abusing this for post-maintenance finalization. Add a
# post-run pass to django_maintenance
maintproc = None
......@@ -181,26 +183,24 @@ class Inconsistencies(MaintenanceTask):
old = self.prev_person.get(i.person.lookup_key, frozenset())
for l in i.info_log:
if l not in old:
self.logger.warning("%s: new inconsistency for %s: %s", maintproc.IDENTIFIER, self.maint.link(person), l)
self.logger.warning("%s: new inconsistency for %s: %s", maintproc.IDENTIFIER, self.hk.link(person), l)
for i in self.imodels.InconsistentProcess.objects.all():
old = self.prev_process.get(i.process.lookup_key, frozenset())
for l in i.info_log:
if l not in old:
self.logger.warning("%s: new inconsistency for %s: %s", maintproc.IDENTIFIER, self.maint.link(process), l)
self.logger.warning("%s: new inconsistency for %s: %s", maintproc.IDENTIFIER, self.hk.link(process), l)
for i in self.imodels.InconsistentFingerprint.objects.all():
old = self.prev_fpr.get(i.fpr, frozenset())
for l in i.info_log:
if l not in old:
self.logger.warning("%s: new inconsistency for %s: %s", maintproc.IDENTIFIER, i.fpr, l)
class ComputeAMCTTE(MaintenanceTask):
class ComputeAMCTTE(hk.Task):
"""
Compute AM Committee membership
"""
DEPENDS = [BackupDB]
@transaction.commit_on_success
def run(self):
def run_main(self, stage):
# Set all to False
bmodels.AM.objects.update(is_am_ctte=False)
......@@ -223,14 +223,12 @@ class ComputeAMCTTE(MaintenanceTask):
transaction.commit_unless_managed()
log.info("%s: %d CTTE members", self.IDENTIFIER, bmodels.AM.objects.filter(is_am_ctte=True).count())
class ComputeProcessActiveFlag(MaintenanceTask):
class ComputeProcessActiveFlag(hk.Task):
"""
Compute Process.is_active from Process.progress
"""
DEPENDS = [BackupDB]
@transaction.commit_on_success
def run(self):
def run_main(self, stage):
cursor = connection.cursor()
cursor.execute("""
UPDATE process SET is_active=(progress NOT IN (%s, %s))
......@@ -241,14 +239,14 @@ class ComputeProcessActiveFlag(MaintenanceTask):
bmodels.Process.objects.filter(is_active=True).count(),
cursor.rowcount)
class PersonExpires(MaintenanceTask):
class PersonExpires(hk.Task):
"""
Expire old Person records
"""
DEPENDS = [BackupDB, MakeLink]
DEPENDS = [MakeLink]
@transaction.commit_on_success
def run(self):
def run_main(self, stage):
"""
Generate a sequence of Person objects that have expired
"""
......@@ -256,48 +254,49 @@ class PersonExpires(MaintenanceTask):
for p in bmodels.Person.objects.filter(expires__lt=today):
if p.status != const.STATUS_MM:
log.info("%s: removing expiration date for %s who has become %s",
self.IDENTIFIER, self.maint.link(p), p.status)
self.IDENTIFIER, self.hk.link(p), p.status)
p.expires = None
p.save()
elif p.processes.exists():
log.info("%s: removing expiration date for %s who now has process history",
self.IDENTIFIER, self.maint.link(p))
self.IDENTIFIER, self.hk.link(p))
p.expires = None
p.save()
else:
log.info("%s: deleting expired Person %s", self.IDENTIFIER, p)
p.delete()
class CheckOneProcessPerPerson(MaintenanceTask):
class CheckOneProcessPerPerson(hk.Task):
"""
Check that one does not have more than one open process at the current time
"""
DEPENDS = [Inconsistencies]
def run(self):
def run_main(self, stage):
from django.db.models import Count
for p in bmodels.Person.objects.filter(processes__is_active=True) \
.annotate(num_processes=Count("processes")) \
.filter(num_processes__gt=1):
self.maint.inconsistencies.log_person(self, p,
self.hk.inconsistencies.log_person(self, p,
"has {} open processes".format(p.num_processes),
processes=[pr.lookup_key for pr in p.processes.filter(is_active=True)])
class CheckAMMustHaveUID(MaintenanceTask):
class CheckAMMustHaveUID(hk.Task):
"""
Check that AMs have a Debian login
"""
def run(self):
def run_main(self, stage):
for am in bmodels.AM.objects.filter(person__uid=None):
log.warning("%s: AM %d (person %d %s) has no uid", self.IDENTIFIER, am.id, am.person.id, am.person.email)
class CheckStatusProgressMatch(MaintenanceTask):
class CheckStatusProgressMatch(hk.Task):
"""
Check that the last process with progress 'done' has the same
'applying_for' as the person status
"""
DEPENDS = [Inconsistencies]
def run(self):
def run_main(self, stage):
from django.db.models import Max
for p in bmodels.Person.objects.all():
try:
......@@ -305,58 +304,58 @@ class CheckStatusProgressMatch(MaintenanceTask):
except IndexError:
continue
if p.status != last_proc.applying_for:
self.maint.inconsistencies.log_person(self, p,
self.hk.inconsistencies.log_person(self, p,
"status {} but the last completed process was applying for {}".format(
p.status, last_proc.applying_for),
process_status=last_proc.applying_for)
class CheckLogProgressMatch(MaintenanceTask):
class CheckLogProgressMatch(hk.Task):
"""
Check that the last process with progress 'done' has the same
'applying_for' as the person status
"""
DEPENDS = [MakeLink]
def run(self):
def run_main(self, stage):
for p in bmodels.Process.objects.filter(is_active=True):
try:
last_log = p.log.order_by("-logdate")[0]
except IndexError:
log.warning("%s: %s (%s) has no log entries", self.IDENTIFIER, self.maint.link(p), repr(p))
log.warning("%s: %s (%s) has no log entries", self.IDENTIFIER, self.hk.link(p), repr(p))
continue
if p.progress != last_log.progress:
log.warning("%s: %s (%s) has progress %s but the last log entry has progress %s",
self.IDENTIFIER, self.maint.link(p), repr(p), p.progress, last_log.progress)
self.IDENTIFIER, self.hk.link(p), repr(p), p.progress, last_log.progress)
class CheckEnums(MaintenanceTask):
class CheckEnums(hk.Task):
"""
Consistency check of enum values
"""
DEPENDS = [MakeLink]
def run(self):
def run_main(self, stage):
statuses = [x.tag for x in const.ALL_STATUS]
progresses = [x.tag for x in const.ALL_PROGRESS]
for p in bmodels.Person.objects.exclude(status__in=statuses):
log.warning("%s: %s: invalid status %s", self.IDENTIFIER, self.maint.link(p), p.status)
log.warning("%s: %s: invalid status %s", self.IDENTIFIER, self.hk.link(p), p.status)
for p in bmodels.Process.objects.exclude(applying_for__in=statuses):
log.warning("%s: %s: invalid applying_for %s", self.IDENTIFIER, self.maint.link(p), p.applying_for)
log.warning("%s: %s: invalid applying_for %s", self.IDENTIFIER, self.hk.link(p), p.applying_for)
for p in bmodels.Process.objects.exclude(progress__in=progresses):
log.warning("%s: %s: invalid progress %s", self.IDENTIFIER, self.maint.link(p), p.progress)
log.warning("%s: %s: invalid progress %s", self.IDENTIFIER, self.hk.link(p), p.progress)
for l in bmodels.Log.objects.exclude(progress__in=progresses):
log.warning("%s: %s: log entry %d has invalid progress %s",
self.IDENTIFIER, self.maint.link(l.process), l.id, l.progress)
self.IDENTIFIER, self.hk.link(l.process), l.id, l.progress)
class CheckCornerCases(MaintenanceTask):
class CheckCornerCases(hk.Task):
"""
Check for known corner cases, to be fixed somehow eventually maybe in case
they give trouble
"""
def run(self):
def run_main(self, stage):
c = bmodels.Person.objects.filter(processes__isnull=True).count()
if c > 0:
log.info("%s: %d Great Ancients found who have no Process entry", self.IDENTIFIER, c)
......@@ -365,13 +364,13 @@ class CheckCornerCases(MaintenanceTask):
if c > 0:
log.warning("%s: %d entries still have a NULL status_changed date", self.IDENTIFIER, c)
class CheckDjangoPermissions(MaintenanceTask):
class CheckDjangoPermissions(hk.Task):
"""
Check consistency between Django permissions and flags in the AM model
"""
DEPENDS = [MakeLink]
def run(self):
def run_main(self, stage):
from django.contrib.auth.models import User
from django.db.models import Q
......@@ -385,7 +384,7 @@ class CheckDjangoPermissions(MaintenanceTask):
nm_power_users = set()
for a in bmodels.AM.objects.filter(Q(is_fd=True) | Q(is_dam=True)):
if a.person.user is None:
log.warning("%s: %s: no corresponding django user", self.IDENTIFIER, self.maint.link(a.person))
log.warning("%s: %s: no corresponding django user", self.IDENTIFIER, self.hk.link(a.person))
else:
nm_power_users.add(a.person.user.id)
......
# nm.debian.org website maintenance
# nm.debian.org website housekeeping
#
# Copyright (C) 2012 Enrico Zini <enrico@debian.org>
# Copyright (C) 2014 Enrico Zini <enrico@debian.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
......@@ -20,8 +20,8 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from django.conf import settings
from backend.maintenance import MakeLink
from django_maintenance import MaintenanceTask
from backend.housekeeping import MakeLink
import django_housekeeping as hk
import backend.models as bmodels
import debiancontributors as dc
import logging
......@@ -33,12 +33,15 @@ DC_SUBMIT_URL = getattr(settings, "DC_SUBMIT_URL", None)
DC_GIT_REPO_NM = getattr(settings, "DC_GIT_REPO_NM", "/srv/nm.debian.org/nm2/.git")
DC_GIT_REPO_DC = getattr(settings, "DC_GIT_REPO_DC", "/srv/contributors.debian.org/dc/.git")
class SubmitContributors(MaintenanceTask):
STAGES = ["main", "reports", "stats"]
class SubmitContributors(hk.Task):
"""
Compute contributions and submit them to contributors.debian.org
"""
DEPENDS = [MakeLink]
def run(self):
def run_reports(self, stage):
from django.db.models import Min, Max
if DC_AUTH_TOKEN is None:
......@@ -67,7 +70,7 @@ dirs: {git_repo_nm}
submission.add_contribution_data(
dc.Identifier(type="login", id=am.person.uid, desc=am.person.fullname),
type="am", begin=res["since"].date(), end=res["until"].date(),
url=self.maint.link(am))
url=self.hk.link(am))
for am in bmodels.AM.objects.filter(is_fd=True):
res = bmodels.Log.objects.filter(changed_by=am.person).exclude(process__manager=am).aggregate(
......@@ -78,7 +81,7 @@ dirs: {git_repo_nm}
submission.add_contribution_data(
dc.Identifier(type="login", id=am.person.uid, desc=am.person.fullname),
type="fd", begin=res["since"].date(), end=res["until"].date(),
url=self.maint.link(am))
url=self.hk.link(am))
submission.set_auth_token(DC_AUTH_TOKEN)
if DC_SUBMIT_URL:
......
# nm.debian.org website maintenance
# nm.debian.org website housekeeping
#
# Copyright (C) 2012--2014 Enrico Zini <enrico@debian.org>
#
......@@ -19,9 +19,9 @@ from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from django_maintenance import MaintenanceTask
import django_housekeeping as hk
from django.db import transaction
from backend.maintenance import MakeLink, BackupDB, Inconsistencies
from backend.housekeeping import MakeLink, Inconsistencies
from . import models as dmodels
from backend import const
import backend.models as bmodels
......@@ -29,14 +29,14 @@ import logging
log = logging.getLogger(__name__)
class ProgressFinalisationsOnAccountsCreated(MaintenanceTask):
class ProgressFinalisationsOnAccountsCreated(hk.Task):
"""
Update pending dm_ga processes after the account is created
"""
DEPENDS = [BackupDB, MakeLink]
DEPENDS = [MakeLink]
@transaction.commit_on_success
def run(self):
def run_main(self, stage):
# Get a lits of accounts from DSA
dm_ga_uids = set()
dd_uids = set()
......@@ -60,16 +60,16 @@ class ProgressFinalisationsOnAccountsCreated(MaintenanceTask):
old_status = proc.person.status
proc.finalize(finalised_msg)
log.info("%s: %s finalised: %s changes status %s->%s",
self.IDENTIFIER, self.maint.link(proc), proc.person.uid, old_status, proc.person.status)
self.IDENTIFIER, self.hk.link(proc), proc.person.uid, old_status, proc.person.status)
class NewGuestAccountsFromDSA(MaintenanceTask):
class NewGuestAccountsFromDSA(hk.Task):
"""
Create new Person entries for guest accounts created by DSA
"""
DEPENDS = [BackupDB, MakeLink, Inconsistencies]
DEPENDS = [MakeLink, Inconsistencies]
@transaction.commit_on_success
def run(self):
def run_main(self, stage):
for entry in dmodels.list_people():
# Skip DDs
if entry.single("gidNumber") == "800" and entry.single("keyFingerPrint") is not None: continue
......@@ -86,7 +86,7 @@ class NewGuestAccountsFromDSA(MaintenanceTask):
# Check for fingerprint duplicates
try:
p = bmodels.Person.objects.get(fpr=entry.single("keyFingerPrint"))
self.maint.inconsistencies.log_person(self, p,
self.hk.inconsistencies.log_person(self, p,
"has the same fingerprint as LDAP uid {}".format(entry.uid),
ldap_uid=entry.uid)
continue
......@@ -103,15 +103,15 @@ class NewGuestAccountsFromDSA(MaintenanceTask):
status=const.STATUS_MM_GA,
)
p.save()
log.info("%s (guest account only) imported from LDAP", self.maint.link(p))
log.info("%s (guest account only) imported from LDAP", self.hk.link(p))
class CheckLDAPConsistency(MaintenanceTask):
class CheckLDAPConsistency(hk.Task):
"""
Show entries that do not match between LDAP and our DB
"""
DEPENDS = [BackupDB, MakeLink, Inconsistencies]
DEPENDS = [MakeLink, Inconsistencies]
def run(self):
def run_main(self, stage):
# Prefetch people and index them by uid
people_by_uid = dict()
for p in bmodels.Person.objects.all():
......@@ -124,7 +124,7 @@ class CheckLDAPConsistency(MaintenanceTask):
except bmodels.Person.DoesNotExist:
fpr = entry.single("keyFingerPrint")
if fpr:
self.maint.inconsistencies.log_fingerprint(self, fpr,
self.hk.inconsistencies.log_fingerprint(self, fpr,
"is in LDAP as {} but not in our db".format(entry.uid),
ldap_uid=entry.uid)
else:
......@@ -133,7 +133,7 @@ class CheckLDAPConsistency(MaintenanceTask):
if entry.single("gidNumber") == "800" and entry.single("keyFingerPrint") is not None:
if person.status not in (const.STATUS_DD_U, const.STATUS_DD_NU):
self.maint.inconsistencies.log_person(self, person,
self.hk.inconsistencies.log_person(self, person,
"has gidNumber 800 and a key, but the db has state {}".format(person.status),
dsa_status="dd")
......@@ -141,7 +141,7 @@ class CheckLDAPConsistency(MaintenanceTask):
if email != person.email:
if email is not None:
log.info("%s: %s changing email from %s to %s (source: LDAP)",
self.IDENTIFIER, self.maint.link(person), person.email, email)
self.IDENTIFIER, self.hk.link(person), person.email, email)
person.email = email
person.save()
# It gives lots of errors when run outside of the debian.org
......@@ -150,4 +150,4 @@ class CheckLDAPConsistency(MaintenanceTask):
#
# else:
# log.info("%s: %s has email %s but emailForward is empty in LDAP",
# self.IDENTIFIER, self.maint.link(person), person.email)
# self.IDENTIFIER, self.hk.link(person), person.email)
# nm.debian.org website maintenance
# nm.debian.org website housekeeping
#
# Copyright (C) 2012 Enrico Zini <enrico@debian.org>
# Copyright (C) 2012--2014 Enrico Zini <enrico@debian.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
......@@ -19,9 +19,9 @@ from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from django_maintenance import MaintenanceTask
import django_housekeeping as hk
from django.conf import settings
from backend.maintenance import MakeLink, Inconsistencies
from backend.housekeeping import MakeLink, Inconsistencies
import backend.models as bmodels
from backend import const
from . import models as kmodels
......@@ -37,7 +37,7 @@ log = logging.getLogger(__name__)
KEYRINGS_TMPDIR = getattr(settings, "KEYRINGS_TMPDIR", "/srv/keyring.debian.org/data/tmp_keyrings")
class Keyrings(MaintenanceTask):
class Keyrings(hk.Task):
"""
Load keyrings
"""
......@@ -45,7 +45,7 @@ class Keyrings(MaintenanceTask):
KEYID_LEN = 16
def run(self):
def run_main(self, stage):
log.info("%s: Importing dm keyring...", self.IDENTIFIER)
self.dm = frozenset(kmodels.list_dm())
log.info("%s: Importing dd_u keyring...", self.IDENTIFIER)
......@@ -110,13 +110,13 @@ class Keyrings(MaintenanceTask):
return rec
class CheckKeyringConsistency(MaintenanceTask):
class CheckKeyringConsistency(hk.Task):
"""
Show entries that do not match between keyrings and our DB
"""
DEPENDS = [Keyrings, MakeLink, Inconsistencies]
def run(self):
def run_main(self, stage):
# Prefetch people and index them by fingerprint
people_by_fpr = dict()
for p in bmodels.Person.objects.all():
......@@ -125,12 +125,12 @@ class CheckKeyringConsistency(MaintenanceTask):
people_by_fpr[p.fpr] = p
keyring_by_status = {
const.STATUS_DM: self.maint.keyrings.dm,
const.STATUS_DM_GA: self.maint.keyrings.dm,
const.STATUS_DD_U: self.maint.keyrings.dd_u,
const.STATUS_DD_NU: self.maint.keyrings.dd_nu,
const.STATUS_EMERITUS_DD: self.maint.keyrings.emeritus_dd,
const.STATUS_REMOVED_DD: self.maint.keyrings.removed_dd,
const.STATUS_DM: self.hk.keyrings.dm,
const.STATUS_DM_GA: self.hk.keyrings.dm,
const.STATUS_DD_U: self.hk.keyrings.dd_u,
const.STATUS_DD_NU: self.hk.keyrings.dd_nu,
const.STATUS_EMERITUS_DD: self.hk.keyrings.emeritus_dd,
const.STATUS_REMOVED_DD: self.hk.keyrings.removed_dd,
}
self.count = 0
......@@ -146,14 +146,14 @@ class CheckKeyringConsistency(MaintenanceTask):
found = False
for status, keyring in keyring_by_status.iteritems():
if fpr in keyring:
self.maint.inconsistencies.log_person(self, p,
self.hk.inconsistencies.log_person(self, p,
"has status {} but is in {} keyring".format(p.status, status),
keyring_status=status)
self.count += 1
found = True
break
if not found and p.status != const.STATUS_REMOVED_DD:
self.maint.inconsistencies.log_person(self, p,
self.hk.inconsistencies.log_person(self, p,
"has status {} but is not in any keyring".format(p.status),
keyring_status=None)
self.count += 1
......@@ -165,7 +165,7 @@ class CheckKeyringConsistency(MaintenanceTask):
if status == const.STATUS_REMOVED_DD: continue
for fpr in keyring:
if fpr not in people_by_fpr:
self.maint.inconsistencies.log_fingerprint(self, fpr,
self.hk.inconsistencies.log_fingerprint(self, fpr,
"is in {} keyring but not in our db".format(status),
keyring_status=status)
self.count += 1
......@@ -216,11 +216,11 @@ class CheckKeyringConsistency(MaintenanceTask):
# if i["cur"] != cand:
# log.info("%s: %s %r != %r", keyring, fpr, i["cur"], cand)
class CleanUserKeyrings(MaintenanceTask):
class CleanUserKeyrings(hk.Task):
"""
Remove old user keyrings
"""
def run(self):
def run_main(self, stage):
if not os.path.isdir(KEYRINGS_TMPDIR):
return
# Delete everything older than three days ago
......@@ -242,7 +242,7 @@ def keyring_log_matcher(regexp, **kw):
return f
return decorator
class CheckKeyringLogs(MaintenanceTask):
class CheckKeyringLogs(hk.Task):
"""
Show entries that do not match between keyrings and our DB
"""
......@@ -259,25 +259,25 @@ class CheckKeyringLogs(MaintenanceTask):
def _ann_fpr(self, d, rt, fpr, log, **kw):
if rt is not None:
self.maint.inconsistencies.annotate_fingerprint(self, fpr,
self.hk.inconsistencies.annotate_fingerprint(self, fpr,
"{}, RT #{}".format(log, rt),
keyring_rt=rt,
keyring_log_date=d.strftime("%Y%m%d %H%M%S"),
**kw)
else:
self.maint.inconsistencies.annotate_fingerprint(self, fpr, log,
self.hk.inconsistencies.annotate_fingerprint(self, fpr, log,
keyring_log_date=d.strftime("%Y%m%d %H%M%S"),
**kw)
def _ann_person(self, d, rt, person, log, **kw):
if rt is not None:
self.maint.inconsistencies.annotate_person(self, person,
self.hk.inconsistencies.annotate_person(self, person,
"{}, RT #{}".format(log, rt),
keyring_rt=rt,
keyring_log_date=d.strftime("%Y%m%d %H%M%S"),
**kw)
else:
self.maint.inconsistencies.annotate_person(self, person, log,
self.hk.inconsistencies.annotate_person(self, person, log,
keyring_log_date=d.strftime("%Y%m%d %H%M%S"),
**kw)
......@@ -285,7 +285,7 @@ class CheckKeyringLogs(MaintenanceTask):
def do_new_dm(self, d, key, rt):
p = self.person_for_key_id(key)
if p is None:
fpr, ktype = self.maint.keyrings.resolve_keyid(key)
fpr, ktype = self.hk.keyrings.resolve_keyid(key)
if fpr is None:
log.info("%s: unknown key ID %s found in log for %s RT#%s", self.IDENTIFIER, key, d, rt)
else:
......@@ -310,7 +310,7 @@ class CheckKeyringLogs(MaintenanceTask):
def do_new_dd(self, d, key, rt):
p = self.person_for_key_id(key)
if p is None:
fpr, ktype = self.maint.keyrings.resolve_keyid(key)
fpr, ktype = self.hk.keyrings.resolve_keyid(key)
self._ann_fpr(d, rt, fpr, "keyring logs report a new DD, with no known record in our database", keyring_status=ktype)
#print("! New DD %s %s (no account before??)" % (key, self.rturl(rt)))
elif p.status == const.STATUS_DD_U:
......@@ -326,7 +326,7 @@ class CheckKeyringLogs(MaintenanceTask):
def do_new_em(self, d, key, rt):
p = self.person_for_key_id(key)
if p is None:
fpr, ktype = self.maint.keyrings.resolve_keyid(key)
fpr, ktype = self.hk.keyrings.resolve_keyid(key)
self._ann_fpr(d, rt, fpr, "keyring logs report a new emeritus DD, with no known record in our database", keyring_status=ktype)
#print("! New Emeritus DD %s %s (no account before??)" % (key, self.rturl(rt)))
elif p.status == const.STATUS_EMERITUS_DD:
......@@ -342,7 +342,7 @@ class CheckKeyringLogs(MaintenanceTask):
def do_new_rem(self, d, key, rt):
p = self.person_for_key_id(key)
if p is None:
fpr, ktype = self.maint.keyrings.resolve_keyid(key)
fpr, ktype = self.hk.keyrings.resolve_keyid(key)
self._ann_fpr(d, rt, fpr, "keyring logs report a new removed DD, with no known record in our database", keyring_status=ktype)
#print("! New removed key %s %s (no account before??)" % (key, self.rturl(rt)))
else:
......@@ -355,8 +355,8 @@ class CheckKeyringLogs(MaintenanceTask):
p2 = self.person_for_key_id(key2)
if p1 is None and p2 is None:
# No before or after match with our records
fpr1, ktype1 = self.maint.keyrings.resolve_keyid(key1)
fpr2, ktype2 = self.maint.keyrings.resolve_keyid(key2)
fpr1, ktype1 = self.hk.keyrings.resolve_keyid(key1)
fpr2, ktype2 = self.hk.keyrings.resolve_keyid(key2)
if fpr1 is not None:
if fpr2 is not None:
# Before and after keyrings known
......@@ -388,7 +388,7 @@ class CheckKeyringLogs(MaintenanceTask):
pass
# print("! Replaced %s with %s (none of which are in the database!) %s" % (key1, key2, self.rturl(rt)))
elif p1 is None and p2 is not None:
#self.maint.inconsistencies.annotate_person(self, p,
#self.hk.inconsistencies.annotate_person(self, p,
# "keyring logs report key change from {} to {}, RT#{}".format(key1, key2, rt),
# keyring_rt=rt,
# keyring_log_date=d,
......@@ -396,7 +396,7 @@ class CheckKeyringLogs(MaintenanceTask):
#print("# Replaced %s with %s (already done in the database) %s" % (key1, key2, self.rturl(rt)))
pass # Already known
elif p1 is not None and p2 is None:
fpr, ktype = self.maint.keyrings.resolve_keyid(key2)
fpr, ktype = self.hk.keyrings.resolve_keyid(key2)
if fpr is None:
self._ann_person(d, rt, p1, "key changed to unknown key {}".format(key2))
# print("! %s replaced key %s with %s but could not find %s in keyrings %s" % (p.lookup_key, key1, key2, key2, self.rturl(rt)))
......@@ -408,7 +408,7 @@ class CheckKeyringLogs(MaintenanceTask):
else:
# This is very weird, so we log instead of just annotating
for p in (p1, p2):
self.maint.inconsistencies.log_person(self, p,
self.hk.inconsistencies.log_person(self, p,
"keyring logs report key change from {} to {}, but the keys belong to two different people, {} and {}. RT #{}".format(key1, key2, p1.lookup_key, p2.lookup_key, rt),
keyring_rt=rt,
keyring_log_date=d.strftime("%Y%m%d %H%M%S"))
......@@ -430,7 +430,7 @@ class CheckKeyringLogs(MaintenanceTask):
self._ann_person(d, rt, p, "relevant but unparsed log entry: \"{}\"".format(line))
continue
fpr, ktype = self.maint.keyrings.resolve_keyid(key)
fpr, ktype = self.hk.keyrings.resolve_keyid(key)
if fpr is not None:
self._ann_fpr(d, rt, fpr, "relevant but unparsed log entry: \"{}\"".format(line))
......@@ -455,7 +455,7 @@ class CheckKeyringLogs(MaintenanceTask):
return True
return False
def run(self):
def run_main(self, stage):
"""
Parse changes from changelog entries after the given date (non inclusive).
"""
......
......@@ -131,8 +131,8 @@ INSTALLED_APPS = (
'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
'django.contrib.admindocs',
# http://git.debian.org/?p=users/enrico/django_maintenance.git
'django_maintenance',
# https://github.com/spanezz/django-housekeeping
'django_housekeeping',
'django_dacs',
'ratelimit',
'keyring',
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment