amprolla

devuan's apt repo merger
git clone https://git.parazyd.org/amprolla
Log | Files | Refs | README | LICENSE

release.py (4908B)


      1 # See LICENSE file for copyright and license details.
      2 
      3 """
      4 Release file functions and helpers
      5 """
      6 
      7 from datetime import datetime  # , timedelta
      8 from gzip import decompress as gzip_decomp
      9 from lzma import compress as lzma_comp
     10 from os.path import getsize, isfile
     11 from subprocess import Popen
     12 
     13 import lib.globalvars as globalvars
     14 from lib.config import (checksums, distrolabel, gpgdir, release_aliases,
     15                         release_keys, signingkey, signrelease, arches)
     16 from lib.log import info
     17 from lib.parse import parse_release_head, parse_release
     18 
     19 
     20 def rewrite_release_head(headers):
     21     """
     22     Rewrites the necessary headers in a Release file
     23     Used to override needed values defined in config.release_aliases
     24     """
     25     if headers['Suite'] in release_aliases:
     26         headers['Label'] = distrolabel
     27         suitename = headers['Suite']
     28         for var in release_aliases[suitename]:
     29             headers[var] = release_aliases[suitename][var]
     30 
     31     return headers
     32 
     33 
     34 def write_release(oldrel, newrel, filelist, rmstr, rewrite=True):
     35     """
     36     Generates a valid Release file
     37     if sign=False: do not use gnupg to sign the file
     38     if rewrite=True: rewrite the Release headers as defined in the config
     39 
     40     Arguments taken: oldrel, newrel, filelist, rmstr
     41         * location of the old Release file (used to take metadata)
     42         * location where to write the new Release file
     43         * list of files to make checksums
     44         * string to remove from the path of the hashed file
     45     """
     46     time1 = datetime.utcnow()
     47     # time2 = datetime.utcnow() + timedelta(days=7)
     48 
     49     prettyt1 = time1.strftime('%a, %d %b %Y %H:%M:%S UTC')
     50     # prettyt2 = time2.strftime('%a, %d %b %Y %H:%M:%S UTC')
     51 
     52     # this holds our local data in case we don't want to rehash files
     53     if isfile(newrel):
     54         local_rel = open(newrel).read()
     55         local_rel = parse_release(local_rel)
     56 
     57     old = open(oldrel).read()
     58     new = open(newrel, 'w')
     59 
     60     rel_cont = parse_release_head(old)
     61 
     62     rel_cont['Date'] = prettyt1
     63     # rel_cont['Valid-Until'] = prettyt2
     64 
     65     _archlist = ''
     66     for i in arches:
     67         if i == 'source':
     68             continue
     69         if i == 'binary-all':
     70             continue
     71         i = i.replace('binary-', ' ')
     72         _archlist += i
     73     rel_cont['Architectures'] = _archlist
     74 
     75     if rewrite:
     76         rel_cont = rewrite_release_head(rel_cont)
     77 
     78     for k in release_keys:
     79         if k in rel_cont:
     80             new.write('%s: %s\n' % (k, rel_cont[k]))
     81 
     82     if globalvars.rehash:
     83         rehash_release(filelist, new, rmstr)
     84     else:
     85         info('Reusing old checksums')
     86         for csum in checksums:
     87             new.write('%s:\n' % csum['name'])
     88             for i, j in local_rel.items():
     89                 new.write(' %s %8s %s\n' % (j[0], j[1], i))
     90 
     91     new.close()
     92 
     93     if signrelease:
     94         sign_release(newrel)
     95 
     96 
     97 def rehash_release(_filelist, fdesc, rmstr):
     98     """
     99     Calculates checksums of a given filelist and writes them to the given
    100     file descriptor. Takes rmstr as the third argument, which is a string to
    101     remove from the path of the hashed file when writing it to a file.
    102     """
    103     info('Hashing checksums')
    104     for csum in checksums:
    105         fdesc.write('%s:\n' % csum['name'])
    106         for i in _filelist:
    107             if isfile(i):
    108                 cont = open(i, 'rb').read()
    109                 fdesc.write(' %s %8s %s\n' % (csum['f'](cont).hexdigest(),
    110                                               getsize(i),
    111                                               i.replace(rmstr+'/', '')))
    112             elif i.endswith('.xz') and isfile(i.replace('.xz', '.gz')):
    113                 xzstr = lzma_comp(open(i.replace('.xz', '.gz'), 'rb').read())
    114                 fdesc.write(' %s %8s %s\n' % (csum['f'](xzstr).hexdigest(),
    115                                               len(xzstr),
    116                                               i.replace(rmstr+'/', '')))
    117             elif not i.endswith('.gz') and isfile(i+'.gz'):
    118                 uncomp = gzip_decomp(open(i+'.gz', 'rb').read())
    119                 fdesc.write(' %s %8s %s\n' % (csum['f'](uncomp).hexdigest(),
    120                                               len(uncomp),
    121                                               i.replace(rmstr+'/', '')))
    122     return
    123 
    124 
    125 def sign_release(infile):
    126     """
    127     Signs both the clearsign and the detached signature of a Release file.
    128 
    129     Takes a valid path to a release file as an argument.
    130     """
    131     args = ['gpg', '-q', '--default-key', signingkey, '--batch', '--yes',
    132             '--homedir', gpgdir]
    133 
    134     clearargs = args + ['--clearsign', '-a', '-o',
    135                         infile.replace('Release', 'InRelease'), infile]
    136     detachargs = args + ['-sb', '-o', infile+'.gpg', infile]
    137 
    138     info('Signing Release (clearsign)')
    139     cleargpg = Popen(clearargs)
    140     cleargpg.wait(timeout=5)
    141 
    142     info('Signing Release (detached sign)')
    143     detachgpg = Popen(detachargs)
    144     detachgpg.wait(timeout=5)