Projet

Général

Profil

Révision 17f78427

ID17f784270ae966ee9a13e9f5104a5b8f925b639e
Parent ef851f0c
Enfant d4320aea, 5b2396a9

Ajouté par Lars Kruse il y a plus de 7 ans

Whitespace cleanup

  • remove trailing whitespace
  • remove empty lines at the end of files

Voir les différences:

plugins/apt/deb_packages/deb_packages.py
1 1
#!/usr/bin/python
2 2
# -*- coding: utf-8 -*-
3 3

  
4
""" 
4
"""
5 5
A munin plugin that prints archive and their upgradable packets
6 6

  
7 7
TODO: make it usable and readable as commandline tool
......
13 13
   sorting a packet to the newest archive
14 14
   (WONTFIX unless someone asks for)
15 15

  
16
TODO: 
16
TODO:
17 17
 • addinge alternative names for archives "stable -> squeeze"
18
TODO: add gray as 
18
TODO: add gray as
19 19
      foo.colour 000000
20 20
      to 'now', '', '', '', '', 'Debian dpkg status file'
21 21
TODO: update only if system was updated (aptitutde update has been run)
22 22
      • check modification date of /var/cache/apt/pkgcache.bin
23 23
      • cache file must not be older than mod_date of pkgcache.bin + X
24
TODO: shorten ext_info with getShortestConfigOfOptions 
25
TODO: check whether cachefile matches the config 
24
TODO: shorten ext_info with getShortestConfigOfOptions
25
TODO: check whether cachefile matches the config
26 26
      • i have no clever idea to do this without 100 lines of code
27
BUG: If a package will be upgraded, and brings in new dependencies, 
27
BUG: If a package will be upgraded, and brings in new dependencies,
28 28
     these new deps will not be counted. WONTFIX
29 29
"""
30 30
import sys
......
32 32
import apt_pkg
33 33
from apt.progress.base import OpProgress
34 34
from time import time, strftime
35
import os 
35
import os
36 36
import StringIO
37 37
import string
38 38
import re
......
41 41

  
42 42
class EnvironmentConfigBroken(Exception): pass
43 43

  
44
# print environmental things 
44
# print environmental things
45 45
# for k,v in os.environ.iteritems(): print >> sys.stderr, "%r : %r" % (k,v)
46 46

  
47 47
def getEnv(name, default=None, cast=None):
......
68 68

  
69 69
STATE_DIR = getEnv('MUNIN_PLUGSTATE', default='.')
70 70
CACHE_FILE = os.path.join(STATE_DIR, "deb_packages.state")
71
""" 
71
"""
72 72
   There is no need to execute this script every 5 minutes.
73 73
   The Results are put to this file, next munin-run can read from it
74 74
   CACHE_FILE is usually /var/lib/munin/plugin-state/debian_packages.state
75 75
"""
76 76

  
77 77
CACHE_FILE_MAX_AGE = getEnv('CACHE_FILE_MAX_AGE', default=3540, cast=int)
78
""" 
78
"""
79 79
   Age in seconds an $CACHE_FILE can be. If it is older, the script updates
80 80
"""
81 81

  
......
103 103
        doc = "apt_pkg.Cache instance, lazy instantiated"
104 104
        def fget(self):
105 105
            class NullProgress(OpProgress):
106
                """ used for do not giving any progress info, 
107
                    while doing apt things used, cause documented 
108
                    use of None as OpProgress did not worked in 
106
                """ used for do not giving any progress info,
107
                    while doing apt things used, cause documented
108
                    use of None as OpProgress did not worked in
109 109
                    python-apt 0.7
110 110
                """
111 111
                def __init__(self):
......
119 119
                def update(*args,**kwords):
120 120
                    pass
121 121

  
122
            if self._cache is None: 
123
                self._cache = apt_pkg.Cache(NullProgress()) 
122
            if self._cache is None:
123
                self._cache = apt_pkg.Cache(NullProgress())
124 124
            return self._cache
125 125
        return locals()
126 126

  
......
129 129
        doc = "apt_pkg.DepCache object"
130 130

  
131 131
        def fget(self):
132
            if self._depcache is None: 
132
            if self._depcache is None:
133 133
                self._depcache = apt_pkg.DepCache(self.cache)
134 134
            return self._depcache
135 135

  
......
180 180
        apt.installedPackages
181 181
        apt.upgradablePackages
182 182

  
183
    initialisation is lazy 
183
    initialisation is lazy
184 184
"""
185 185

  
186 186
def weightOfPackageFile(detail_tuple, option_tuple):
......
214 214

  
215 215
class TreeTwig(defaultdict):
216 216
    def __init__(self, defaultFactory):
217
        super(TreeTwig, self).__init__(defaultFactory) 
217
        super(TreeTwig, self).__init__(defaultFactory)
218 218

  
219 219
    def printAsTree(self, indent=0):
220 220
        for k, tree in self.iteritems():
......
245 245

  
246 246

  
247 247
def getShortestConfigOfOptions(optionList = ['label', 'archive', 'site']):
248
    """ 
248
    """
249 249
        tries to find the order to print a tree of the optionList
250
        with the local repositories with the shortest line 
250
        with the local repositories with the shortest line
251 251
        possible options are:
252 252
          'component'
253 253
          'label'
254 254
          'site'
255 255
          'archive'
256
          'origin' 
257
          'architecture' 
256
          'origin'
257
          'architecture'
258 258
        Architecture values are usually the same and can be ignored.
259 259

  
260 260
        tells you which representation of a tree as line is shortest.
......
262 262
        to write the shortest readable output.
263 263
    """
264 264
    l = optionList # just because l is much shorter
265
    
265

  
266 266
    # creating possible iterations
267 267
    fieldCount = len(optionList)
268 268
    if fieldCount == 1:
269 269
        selection = l
270 270
    elif fieldCount == 2:
271
        selection = [(x,y) 
272
                     for x in l 
271
        selection = [(x,y)
272
                     for x in l
273 273
                     for y in l if x!=y ]
274 274
    elif fieldCount == 3:
275
        selection = [(x,y,z) 
276
                     for x in l 
277
                     for y in l if x!=y 
275
        selection = [(x,y,z)
276
                     for x in l
277
                     for y in l if x!=y
278 278
                     for z in l if z!=y and z!=x]
279 279
    else:
280 280
        raise Exception("NotImplemented for size %s" % fieldCount)
......
289 289
    r = min( d.items(), key=lambda x: x[1] )
290 290

  
291 291
    return list(r[0]), r[1]
292
    
292

  
293 293
def getOptionsTree(cache, keys=None):
294 294
    """
295 295
    t = getOptionsTree(cache, ['archive', 'site', 'label'])
......
322 322
    """
323 323
    if type(key) in StringTypes:
324 324
        return file.__getattribute__(key)
325
    elif type(key) in (TupleType, ListType): 
325
    elif type(key) in (TupleType, ListType):
326 326
        nKey = tuple()
327 327
        for pKey in key:
328 328
            nKey = nKey.__add__((file.__getattribute__(pKey),))
329 329
        return nKey
330 330
    else:
331
        raise Exception("Not implemented for keytype %s" % type(key)) 
331
        raise Exception("Not implemented for keytype %s" % type(key))
332 332

  
333 333
def getOptionsTree2(cache, primary=None, secondary=None):
334
    """ 
334
    """
335 335
    primary muss ein iterable oder StringType sein
336 336
    secondary muss iterable oder StringType sein
337 337
    t1 = getOptionsTree2(apt.cache, 'origin', ['site', 'archive'])
......
369 369
                dKey = file.__getattribute__(sKey)
370 370
                d = d[dKey]
371 371
    return t
372
    
372

  
373 373
#def getAttributeSet(iterable, attribute):
374 374
#    return set(f.__getattribute__(attribute) for f in iterable)
375 375
#
376 376
#def getOrigins(cache):
377
#    return getAttributeSet(cache.file_list, 'origin') 
377
#    return getAttributeSet(cache.file_list, 'origin')
378 378
#
379 379
#def getArchives(cache):
380
#    return getAttributeSet(cache.file_list, 'archive') 
380
#    return getAttributeSet(cache.file_list, 'archive')
381 381
#
382 382
#def getComponents(cache):
383
#    return getAttributeSet(cache.file_list, 'component') 
383
#    return getAttributeSet(cache.file_list, 'component')
384 384
#
385 385
#def getLabels(cache):
386
#    return getAttributeSet(cache.file_list, 'label') 
386
#    return getAttributeSet(cache.file_list, 'label')
387 387
#
388 388
#def getSites(cache):
389
#    return getAttributeSet(cache.file_list, 'site') 
389
#    return getAttributeSet(cache.file_list, 'site')
390 390
#
391 391

  
392 392
class PackageStat(defaultdict):
......
397 397
        with some abilities to print output munin likes
398 398
    """
399 399

  
400
    sortDict = { 'label': defaultdict(   lambda :  20, 
401
                                       {'Debian':  90, 
400
    sortDict = { 'label': defaultdict(   lambda :  20,
401
                                       {'Debian':  90,
402 402
                                        ''      :  1,
403 403
                                        'Debian Security' : 90,
404 404
                                        'Debian Backports': 90}),
405 405
                 'archive': defaultdict( lambda :  5,
406
                                { 'now':                0, 
406
                                { 'now':                0,
407 407
                                  'experimental':      10,
408
                                  'unstable':          50, 
409
                                  'sid':               50, 
408
                                  'unstable':          50,
409
                                  'sid':               50,
410 410
                                  'testing':           70,
411 411
                                  'wheezy':            70,
412 412
                                  'squeeze-backports': 80,
......
426 426
    }
427 427
    """
428 428
        Values to sort options (label, archive, origin ...)
429
        (0..99) is allowed. 
429
        (0..99) is allowed.
430 430
        (this is needed for other graphs to calc aggregated weights)
431
        higher is more older and more official or better 
431
        higher is more older and more official or better
432 432
    """
433 433

  
434 434
    dpkgStatusValue = { 'site': '', 'origin': '', 'label': '', 'component': '', 'archive': 'now' }
......
443 443
                       'component' : 10**2,
444 444
    }
445 445
    """
446
        Dict that stores multipliers 
446
        Dict that stores multipliers
447 447
        to compile a sorting value for each archivefile
448 448
    """
449 449

  
......
483 483
    def addPackage(self, sourceFile, package):
484 484
        if self.packetHandler.decider(package):
485 485
            self.packetHandler.adder(package, self)
486
            
486

  
487 487
    @classmethod
488 488
    def configD(cls, key, value):
489 489
        i = { 'rrdName': cls.generate_rrd_name_from(key),
......
514 514
            print "{rrdName}.draw AREASTACK".format(**i)
515 515

  
516 516
    def optionIsDpkgStatus(self, details, options=None):
517
        """ 
518
            give it details and options and it tells you whether the datails looks like they come from 
517
        """
518
            give it details and options and it tells you whether the datails looks like they come from
519 519
            a 'Debian dpkg status file'.
520 520
        """
521 521
        # setting defaults
......
530 530
        return isNow
531 531

  
532 532
    def printValues(self):
533
        print "\nmultigraph packages_{option}_{type}".format(option=self.generate_rrd_name_from(self.option), 
533
        print "\nmultigraph packages_{option}_{type}".format(option=self.generate_rrd_name_from(self.option),
534 534
                                                             type=self.packetHandler.type)
535 535
        for options, item in self.options_sorted:
536 536
            if not self.packetHandler.includeNow and self.optionIsDpkgStatus(details=options):
......
555 555

  
556 556
class PacketHandler(object):
557 557
    """
558
    Baseclass, that represents the Interface which is used 
558
    Baseclass, that represents the Interface which is used
559 559
    """
560 560

  
561 561
    type = None
......
591 591
        return weightOfPackageFile(details, options)
592 592

  
593 593
class PacketHandlerUpgradable(PacketHandler):
594
    
594

  
595 595
    type='upgradable'
596 596
    includeNow = False
597 597
    extInfoItemString = "  {i[0].name} <{i[1]} -> {i[2]}>"
......
628 628
        # this item (as i) is used for input in extInfoItemString
629 629
        item = package
630 630
        packageStat[keys].append(item)
631
        
631

  
632 632
# registering PackageHandler for Usage
633 633
packetHandlerD[PacketHandlerInstalled.type] = PacketHandlerInstalled
634 634

  
......
637 637
    def __init__(self, commandLineArgs=None):
638 638
        self.commandLineArgs = commandLineArgs
639 639
        self.argParser = self._argParser()
640
        self.executionMatrix = { 
640
        self.executionMatrix = {
641 641
            'config': self.config,
642 642
            'run'   : self.run,
643 643
            'autoconf' : self.autoconf,
......
685 685
        else:
686 686
            raise Exception('DPKG-statusfile %r not found, really strange!!!'%dpkgStatusFile)
687 687
        newestFileTimestamp = max(timeL)
688
        age = newestFileTimestamp - cacheMTime 
688
        age = newestFileTimestamp - cacheMTime
689 689
        if age > 0:
690 690
            return True
691 691
        else:
......
709 709
        #         cacheNeedUpdate = True
710 710

  
711 711
        if self._cacheIsOutdated() or self.args.nocache:
712
            # save stdout 
712
            # save stdout
713 713
            stdoutDef = sys.stdout
714 714
            try:
715 715
                out =  StringIO.StringIO()
......
765 765
    def _argParser(self):
766 766
        parser = argparse.ArgumentParser(description="Show some statistics "\
767 767
                            "about debian packages installed on system by archive",
768
                           ) 
768
                           )
769 769
        parser.set_defaults(command='run', debug=True, nocache=True)
770 770

  
771 771
        parser.add_argument('--nocache', '-n', default=False, action='store_true',
......
775 775
            run ........ munin run (writes values)
776 776
            autoconf ... writes 'yes'
777 777
        """
778
        parser.add_argument('command', nargs='?', 
778
        parser.add_argument('command', nargs='?',
779 779
                            choices=['config', 'run', 'autoconf', 'drun'],
780 780
                            help='mode munin wants to use. "run" is default' + helpCommand)
781 781
        return parser
......
783 783
    def _envParser(self):
784 784
        """
785 785
            reads environVars from [deb_packages] and generate
786
            a list of dicts, each dict holds a set of settings made in 
786
            a list of dicts, each dict holds a set of settings made in
787 787
            munin config.
788
            [ 
789
              { 'type' = 'installed', 
788
            [
789
              { 'type' = 'installed',
790 790
                'sort_by' = ['label', 'archive'],
791 791
                'show_ext' = ['origin', 'site'],
792 792
              },
......
816 816
                configPart['show_ext'][m.group('optNumber')] = os.getenv(var)
817 817
            else:
818 818
                print >> sys.stderr, "configuration option %r was ignored" % (var)
819
        # we have now dicts for 'sort_by' and 'show_ext' keys 
819
        # we have now dicts for 'sort_by' and 'show_ext' keys
820 820
        # changing them to lists
821 821
        for graphConfig in config.itervalues():
822 822
            graphConfig['sort_by'] = [val for key, val in sorted(graphConfig['sort_by'].items())]
......
839 839
                      "Graph must be sorted by anything"
840 840
                raise EnvironmentConfigBroken("Environment Config broken")
841 841
            # check for valid options for sort_by
842
            unusableOptions = set(graph['sort_by']) - PackageStat.viewSet 
843
            if unusableOptions: 
842
            unusableOptions = set(graph['sort_by']) - PackageStat.viewSet
843
            if unusableOptions:
844 844
                print >> sys.stderr, \
845 845
                      "%r are not valid options for 'sort_by'" % (unusableOptions)
846 846
                raise EnvironmentConfigBroken("Environment Config broken")
847 847
            # check for valid options for sort_by
848
            unusableOptions = set(graph['show_ext']) - PackageStat.viewSet 
848
            unusableOptions = set(graph['show_ext']) - PackageStat.viewSet
849 849
            if unusableOptions:
850 850
                print >> sys.stderr, \
851 851
                      "%r are not valid options for 'show_ext'" % (x)

Formats disponibles : Unified diff