~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/archivepublisher/scripts/generate_contents_files.py

  • Committer: Launchpad Patch Queue Manager
  • Date: 2011-07-25 15:34:28 UTC
  • mfrom: (13506.1.1 bug-815725)
  • Revision ID: launchpad@pqm.canonical.com-20110725153428-145o1ulcqloo1w39
[r=henninge, lifeless][bug=815725] Fix long-running transaction in
        generate-contents-files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
 
11
11
from optparse import OptionValueError
12
12
import os
 
13
 
13
14
from zope.component import getUtility
14
15
 
15
16
from canonical.config import config
 
17
from canonical.launchpad.webapp.dbpolicy import (
 
18
    DatabaseBlockedPolicy,
 
19
    SlaveOnlyDatabasePolicy,
 
20
    )
16
21
from lp.archivepublisher.config import getPubConfig
17
22
from lp.registry.interfaces.distribution import IDistributionSet
18
23
from lp.registry.interfaces.pocket import pocketsuffix
218
223
                        self.logger.debug("Creating %s.", path)
219
224
                        os.makedirs(path)
220
225
 
221
 
    def copyOverrides(self):
222
 
        """Copy overrides into the content archive."""
223
 
        if file_exists(self.config.overrideroot):
 
226
    def copyOverrides(self, override_root):
 
227
        """Copy overrides into the content archive.
 
228
 
 
229
        This method won't access the database.
 
230
        """
 
231
        if file_exists(override_root):
224
232
            execute(self.logger, "cp", [
225
233
                "-a",
226
 
                self.config.overrideroot,
 
234
                override_root,
227
235
                "%s/" % self.content_archive,
228
236
                ])
229
237
        else:
230
238
            self.logger.debug("Did not find overrides; not copying.")
231
239
 
232
 
    def writeContentsTop(self):
233
 
        """Write Contents.top file."""
 
240
    def writeContentsTop(self, distro_name, distro_title):
 
241
        """Write Contents.top file.
 
242
 
 
243
        This method won't access the database.
 
244
        """
234
245
        output_filename = os.path.join(
235
 
            self.content_archive, '%s-misc' % self.distribution.name,
236
 
            "Contents.top")
 
246
            self.content_archive, '%s-misc' % distro_name, "Contents.top")
237
247
        parameters = {
238
 
            'distrotitle': self.distribution.title,
 
248
            'distrotitle': distro_title,
239
249
        }
240
250
        output_file = file(output_filename, 'w')
241
251
        text = file(get_template("Contents.top")).read() % parameters
242
252
        output_file.write(text)
243
253
        output_file.close()
244
254
 
245
 
    def runAptFTPArchive(self):
246
 
        """Run apt-ftparchive to produce the Contents files."""
 
255
    def runAptFTPArchive(self, distro_name):
 
256
        """Run apt-ftparchive to produce the Contents files.
 
257
 
 
258
        This method may take a long time to run.
 
259
        This method won't access the database.
 
260
        """
247
261
        execute(self.logger, "apt-ftparchive", [
248
262
            "generate",
249
263
            os.path.join(
250
 
                self.content_archive, "%s-misc" % self.distribution.name,
 
264
                self.content_archive, "%s-misc" % distro_name,
251
265
                "apt-contents.conf"),
252
266
            ])
253
267
 
254
 
    def generateContentsFiles(self):
255
 
        """Generate Contents files."""
 
268
    def generateContentsFiles(self, override_root, distro_name, distro_title):
 
269
        """Generate Contents files.
 
270
 
 
271
        This method may take a long time to run.
 
272
        This method won't access the database.
 
273
 
 
274
        :param override_root: Copy of `self.config.overrideroot` that can be
 
275
            evaluated without accessing the database.
 
276
        :param distro_name: Copy of `self.distribution.name` that can be
 
277
            evaluated without accessing the database.
 
278
        :param distro_title: Copy of `self.distribution.title` that can be
 
279
            evaluated without accessing the database.
 
280
        """
256
281
        self.logger.debug(
257
282
            "Running apt in private tree to generate new contents.")
258
 
        self.copyOverrides()
259
 
        self.writeContentsTop()
260
 
        self.runAptFTPArchive()
 
283
        self.copyOverrides(override_root)
 
284
        self.writeContentsTop(distro_name, distro_title)
 
285
        self.runAptFTPArchive(distro_name)
261
286
 
262
287
    def updateContentsFile(self, suite, arch):
263
288
        """Update Contents file, if it has changed."""
340
365
        self.updateLegacyContentArchiveRoot()
341
366
        self.setUpContentArchive()
342
367
 
343
 
    def main(self):
344
 
        """See `LaunchpadScript`."""
 
368
    def process(self):
 
369
        """Do the bulk of the work."""
345
370
        self.setUp()
346
371
        suites = self.getPockets()
347
372
        archs = self.getArchs()
348
373
        self.writeAptContentsConf(suites, archs)
349
374
        self.createComponentDirs(suites, archs)
350
 
        self.generateContentsFiles()
 
375
 
 
376
        overrideroot = self.config.overrideroot
 
377
        distro_name = self.distribution.name
 
378
        distro_title = self.distribution.title
 
379
 
 
380
        # This takes a while.  Ensure that we do it without keeping a
 
381
        # database transaction open.
 
382
        self.txn.commit()
 
383
        with DatabaseBlockedPolicy():
 
384
            self.generateContentsFiles(
 
385
                overrideroot, distro_name, distro_title)
 
386
 
351
387
        self.updateContentsFiles(suites, archs)
 
388
 
 
389
    def main(self):
 
390
        """See `LaunchpadScript`."""
 
391
        # This code has no need to alter the database.
 
392
        with SlaveOnlyDatabasePolicy():
 
393
            self.process()