~launchpad-pqm/launchpad/devel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/python2.4
# Copyright 2004-2005 Canonical Ltd.  All rights reserved.
# pylint: disable-msg=C0103,W0403

"""Librarian garbage collector.

This script is run on the Librarian server to merge duplicate files,
remove expired files from the file system and clean up unreachable
rows in the database.
"""

__metaclass__ = type

import _pythonpath
import logging

from canonical.librarian import librariangc
from canonical.database.sqlbase import AUTOCOMMIT_ISOLATION
from canonical.config import config
from canonical.launchpad.scripts.base import LaunchpadCronScript


class LibrarianGC(LaunchpadCronScript):
    def add_my_options(self):
        self.parser.add_option(
                '', "--skip-duplicates", action="store_true", default=False,
                dest="skip_duplicates",
                help="Skip duplicate LibraryFileContent merging"
                )
        self.parser.add_option(
                '', "--skip-aliases", action="store_true", default=False,
                dest="skip_aliases",
                help="Skip unreferenced LibraryFileAlias removal"
                )
        self.parser.add_option(
                '', "--skip-content", action="store_true", default=False,
                dest="skip_content",
                help="Skip unreferenced LibraryFileContent removal"
                )
        self.parser.add_option(
                '', "--skip-blobs", action="store_true", default=False,
                dest="skip_blobs",
                help="Skip removing expired TemporaryBlobStorage rows"
                )
        self.parser.add_option(
                '', "--skip-files", action="store_true", default=False,
                dest="skip_files",
                help="Skip removing files on disk with no database references"
                )

    def main(self):
        librariangc.log = self.logger

        if self.options.loglevel <= logging.DEBUG:
            librariangc.debug = True

        self.txn.set_isolation_level(AUTOCOMMIT_ISOLATION)
        conn = self.txn.conn()

        # Refuse to run if we have significant clock skew between the
        # librarian and the database.
        librariangc.confirm_no_clock_skew(conn)

        # Note that each of these next steps will issue commit commands
        # as appropriate to make this script transaction friendly
        if not self.options.skip_content:
            librariangc.delete_unreferenced_content(conn) # first sweep
        if not self.options.skip_blobs:
            librariangc.delete_expired_blobs(conn)
        if not self.options.skip_duplicates:
            librariangc.merge_duplicates(conn)
        if not self.options.skip_aliases:
            librariangc.delete_unreferenced_aliases(conn)
        if not self.options.skip_content:
            librariangc.delete_unreferenced_content(conn) # second sweep
        if not self.options.skip_files:
            librariangc.delete_unwanted_files(conn)


if __name__ == '__main__':
    script = LibrarianGC('librarian-gc',
                         dbuser=config.librarian.gc.dbuser)
    script.lock_and_run()