~ubuntu-branches/ubuntu/wily/simplestreams/wily-proposed

« back to all changes in this revision

Viewing changes to simplestreams/util.py

  • Committer: Package Import Robot
  • Author(s): Scott Moser
  • Date: 2015-09-24 21:53:46 UTC
  • mfrom: (1.1.16)
  • Revision ID: package-import@ubuntu.com-20150924215346-ijw9jcrq49fchix8
Tags: 0.1.0~bzr400-0ubuntu1
* New upstream snapshot.
  - sstream-mirror, sstream-query, sstream-sync: add --no-verify
    flag (LP: #1249018)
  - pep8/flake8 cleanups
  - several closing of filehandle fixes (LP: #1461181)
  - GlanceMirror fix stack trace if no matching entries (LP: #1353724)
  - tools: upstream development tools fixes (not shipped in ubuntu)
  - GlanceMirror: change known Ubuntu arches into appropriate glance
    arch values (LP: #1483159)
  - Ensure all users of 'sync' get checksumming of content by default.
    insert_item now provides a content source that does checksumming
    during reads and raises exception on error (LP: #1487004)
* debian/README.source: add file, doc how to take upstream snapshot
* debian/rules: export SS_REQUIRE_DISTRO_INFO so that test
  runs without a dependency on distro-info

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
#   along with Simplestreams.  If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
18
import errno
19
 
import hashlib
20
19
import os
21
20
import re
22
21
import subprocess
25
24
import json
26
25
 
27
26
import simplestreams.contentsource as cs
 
27
import simplestreams.checksum_util as checksum_util
28
28
from simplestreams.log import LOG
29
29
 
30
 
try:
31
 
    ALGORITHMS = list(getattr(hashlib, 'algorithms'))
32
 
except AttributeError:
33
 
    ALGORITHMS = list(hashlib.algorithms_available)
34
 
 
35
30
ALIASNAME = "_aliases"
36
31
 
37
32
PGP_SIGNED_MESSAGE_HEADER = "-----BEGIN PGP SIGNED MESSAGE-----"
39
34
PGP_SIGNATURE_FOOTER = "-----END PGP SIGNATURE-----"
40
35
 
41
36
_UNSET = object()
42
 
CHECKSUMS = ("md5", "sha256", "sha512")
43
37
 
44
38
READ_SIZE = (1024 * 10)
45
39
 
127
121
        del cur[pedigree[-1]]
128
122
 
129
123
 
130
 
def products_prune(tree):
 
124
def products_prune(tree, preserve_empty_products=False):
131
125
    for prodname in list(tree.get('products', {}).keys()):
132
126
        keys = list(tree['products'][prodname].get('versions', {}).keys())
133
127
        for vername in keys:
143
137
                not tree['products'][prodname]['versions']):
144
138
            del tree['products'][prodname]
145
139
 
146
 
    if 'products' in tree and not tree['products']:
 
140
    if (not preserve_empty_products and 'products' in tree and
 
141
            not tree['products']):
147
142
        del tree['products']
148
143
 
149
144
 
254
249
    return read_signed(content=content, keyring=keyring)
255
250
 
256
251
 
257
 
def read_signed(content, keyring=None):
 
252
def read_signed(content, keyring=None, checked=True):
258
253
    # ensure that content is signed by a key in keyring.
259
254
    # if no keyring given use default.
260
255
    if content.startswith(PGP_SIGNED_MESSAGE_HEADER):
261
 
        # http://rfc-ref.org/RFC-TEXTS/2440/chapter7.html
262
 
        cmd = ["gpg", "--batch", "--verify"]
263
 
        if keyring:
264
 
            cmd.append("--keyring=%s" % keyring)
265
 
        cmd.append("-")
266
 
        try:
267
 
            subp(cmd, data=content)
268
 
        except subprocess.CalledProcessError as e:
269
 
            LOG.debug("failed: %s\n out=%s\n err=%s" %
270
 
                      (' '.join(cmd), e.output[0], e.output[1]))
271
 
            raise e
 
256
        if checked:
 
257
            # http://rfc-ref.org/RFC-TEXTS/2440/chapter7.html
 
258
            cmd = ["gpg", "--batch", "--verify"]
 
259
            if keyring:
 
260
                cmd.append("--keyring=%s" % keyring)
 
261
            cmd.append("-")
 
262
            try:
 
263
                subp(cmd, data=content)
 
264
            except subprocess.CalledProcessError as e:
 
265
                LOG.debug("failed: %s\n out=%s\n err=%s" %
 
266
                          (' '.join(cmd), e.output[0], e.output[1]))
 
267
                raise e
272
268
 
273
269
        ret = {'body': '', 'signature': '', 'garbage': ''}
274
270
        lines = content.splitlines()
313
309
    return time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime(ts))
314
310
 
315
311
 
316
 
def item_checksums(item):
317
 
    return {k: item[k] for k in CHECKSUMS if k in item}
318
 
 
319
 
 
320
 
class checksummer(object):
321
 
    _hasher = None
322
 
    algorithm = None
323
 
    expected = None
324
 
 
325
 
    def __init__(self, checksums):
326
 
        # expects a dict of hashname/value
327
 
        if not checksums:
328
 
            self._hasher = None
329
 
            return
330
 
        for meth in CHECKSUMS:
331
 
            if meth in checksums and meth in ALGORITHMS:
332
 
                self._hasher = hashlib.new(meth)
333
 
                self.algorithm = meth
334
 
 
335
 
        self.expected = checksums.get(self.algorithm, None)
336
 
 
337
 
        if not self._hasher:
338
 
            raise TypeError("Unable to find suitable hash algorithm")
339
 
 
340
 
    def update(self, data):
341
 
        if self._hasher is None:
342
 
            return
343
 
        self._hasher.update(data)
344
 
 
345
 
    def hexdigest(self):
346
 
        if self._hasher is None:
347
 
            return None
348
 
        return self._hasher.hexdigest()
349
 
 
350
 
    def check(self):
351
 
        return (self.expected is None or self.expected == self.hexdigest())
352
 
 
353
 
 
354
312
def move_dups(src, target, sticky=None):
355
313
    # given src = {e1: {a:a, b:c}, e2: {a:a, b:d, e:f}}
356
314
    # update target with {a:a}, and delete 'a' from entries in dict1
602
560
    def emit(self, progress):
603
561
        raise NotImplementedError()
604
562
 
 
563
 
 
564
# these are legacy
 
565
CHECKSUMS = checksum_util.CHECKSUMS
 
566
item_checksums = checksum_util.item_checksums
 
567
ALGORITHMS = checksum_util.ALGORITHMS
 
568
 
 
569
 
605
570
# vi: ts=4 expandtab