|
| 1 | +from django.db import transaction |
| 2 | + |
| 3 | +from datetime import date |
| 4 | + |
| 5 | +from pgweb.core.models import Version, TESTING_SHORTSTRING |
| 6 | +from pgweb.news.models import NewsArticle, PinnedNewsArticle |
| 7 | +from pgweb.security.models import SecurityPatch |
| 8 | +from pgweb.util.moderation import ModerationState |
| 9 | +from pgweb.util.versions import ParsedVersion |
| 10 | + |
| 11 | +from pgweb.release.util import CurrentRelease |
| 12 | + |
| 13 | + |
| 14 | +@transaction.atomic |
| 15 | +def do_migrate(): |
| 16 | + # Runs after migrations. Process the current release into being an actual release, if we can. |
| 17 | + release = CurrentRelease.get() |
| 18 | + |
| 19 | + if release.get('noprocess', False): |
| 20 | + print("Noprocess flag set on release, not processing") |
| 21 | + return |
| 22 | + |
| 23 | + if not isinstance(release['date'], date): |
| 24 | + raise Exception("Incorrect format of date {}".format(release['date'])) |
| 25 | + |
| 26 | + if release['type'] in ('major', 'override') and not release.get('announcetext', None): |
| 27 | + raise Exception("Release type {} must specify an announcetext".format(release['type'])) |
| 28 | + |
| 29 | + newsid = release.get('news', {}).get('id', None) |
| 30 | + if not newsid: |
| 31 | + print("No news specified for release, cannot approve news or connect CVEs") |
| 32 | + news = None |
| 33 | + else: |
| 34 | + try: |
| 35 | + news = NewsArticle.objects.get(pk=newsid) |
| 36 | + except NewsArticle.DoesNotExist: |
| 37 | + print("Could not find news article with id {}, cannot approve news or connect CVEs".format(release['news']['id'])) |
| 38 | + news = None |
| 39 | + |
| 40 | + # Update latest available version |
| 41 | + for ver in release['versions']: |
| 42 | + try: |
| 43 | + v = Version.objects.only('tree', 'latestminor', 'reldate', 'testing').get(tree=ver.major) |
| 44 | + uf = [] |
| 45 | + if v.latestminor != ver.minor: |
| 46 | + v.latestminor = ver.minor |
| 47 | + uf.append('latestminor') |
| 48 | + print("Set latestminor={} for version {}".format(v.latestminor, v.numtree)) |
| 49 | + if v.reldate != release['date']: |
| 50 | + v.reldate = release['date'] |
| 51 | + uf.append('reldate') |
| 52 | + print("Set reldate={} for version {}".format(v.reldate, v.numtree)) |
| 53 | + |
| 54 | + if ver.testing and v.testing != ver.testing: |
| 55 | + v.testing = ver.testing |
| 56 | + v.current = False |
| 57 | + v.supported = False |
| 58 | + uf.extend(['testing', 'current', 'supported']) |
| 59 | + print("Set testing={}, current=False, supported=False for version {}".format(ver.type, v.numtree)) |
| 60 | + |
| 61 | + # If we are transitioning beta -> release, set testing and supported flags. |
| 62 | + if v.testing != 0 and ver.type == 'major': |
| 63 | + v.testing = 0 |
| 64 | + v.supported = True |
| 65 | + v.current = True |
| 66 | + uf.extend(['testing', 'supported', 'current']) |
| 67 | + print("Set testing=Release, supported=True and current=True for major version {}".format(v.numtree)) |
| 68 | + |
| 69 | + if uf: |
| 70 | + v.save(update_fields=list(set(uf))) |
| 71 | + except Version.DoesNotExist: |
| 72 | + print("Could not find version tree {}, cannot update latest minor".format(ver.major)) |
| 73 | + |
| 74 | + # If there are any CVEs attached to this release, add the news article to them if there is one |
| 75 | + if news: |
| 76 | + for cve in release.get('cve', []): |
| 77 | + try: |
| 78 | + patch = SecurityPatch.objects.get(cve=cve) |
| 79 | + patch.newspost = news |
| 80 | + patch.public = True |
| 81 | + patch.save(update_fields=['newspost', 'public']) |
| 82 | + print("Attached news article {} to CVE-{}".format(news.id, cve)) |
| 83 | + except SecurityPatch.DoesNotExist: |
| 84 | + print("Could not find CVE {}, cannot connect to announcement") |
| 85 | + |
| 86 | + # If the news article isn't approved yet, bypass approval and do it! |
| 87 | + if news: |
| 88 | + if news.modstate != ModerationState.APPROVED: |
| 89 | + print("Approving news item {}".format(news.id)) |
| 90 | + news.modstate = ModerationState.APPROVED |
| 91 | + news.date = release['date'] |
| 92 | + news.save(update_fields=['modstate', 'date']) |
| 93 | + print("Sending announcement email for news item") |
| 94 | + news.on_approval(None) |
| 95 | + |
| 96 | + pa = PinnedNewsArticle.objects.all()[0] |
| 97 | + if pa.pinnedarticle != news: |
| 98 | + print("Pinning news item {}".format(news.id)) |
| 99 | + pa.pinnedarticle = news |
| 100 | + pa.save(update_fields=['pinnedarticle']) |
0 commit comments