← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~stevenk/launchpad/destroy-manage-chroot into lp:launchpad

 

Steve Kowalik has proposed merging lp:~stevenk/launchpad/destroy-manage-chroot into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~stevenk/launchpad/destroy-manage-chroot/+merge/171210

Now that we have two methods exported over the API, IDistroArchSeries.{set,remove}Chroot(), this horrible script that requires shell access to a privileged machine can die horribly. Good riddance.
-- 
https://code.launchpad.net/~stevenk/launchpad/destroy-manage-chroot/+merge/171210
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~stevenk/launchpad/destroy-manage-chroot into lp:launchpad.
=== removed file 'lib/lp/soyuz/scripts/chrootmanager.py'
--- lib/lp/soyuz/scripts/chrootmanager.py	2012-06-29 08:40:05 +0000
+++ lib/lp/soyuz/scripts/chrootmanager.py	1970-01-01 00:00:00 +0000
@@ -1,230 +0,0 @@
-# Copyright 2009-2012 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Chroot management utilities."""
-
-__metaclass__ = type
-
-__all__ = [
-    'ChrootManager',
-    'ChrootManagerError',
-    'ManageChrootScript',
-    ]
-
-import os
-
-from zope.component import getUtility
-
-from lp.app.errors import NotFoundError
-from lp.services.helpers import filenameToContentType
-from lp.services.librarian.interfaces import ILibraryFileAliasSet
-from lp.services.librarian.interfaces.client import (
-    ILibrarianClient,
-    UploadFailed,
-    )
-from lp.services.librarian.utils import copy_and_close
-from lp.soyuz.scripts.ftpmasterbase import (
-    SoyuzScript,
-    SoyuzScriptError,
-    )
-
-
-class ChrootManagerError(Exception):
-    """Any error generated during the ChrootManager procedures."""
-
-
-class ChrootManager:
-    """Chroot actions wrapper.
-
-    The 'distroarchseries' argument is mandatory and 'filepath' is
-    optional.
-
-    'filepath' is required by some allowed actions as source or destination,
-
-    ChrootManagerError will be raised if anything wrong occurred in this
-    class, things like missing parameter or infrastructure pieces not in
-    place.
-    """
-
-    allowed_actions = ['add', 'update', 'remove', 'get']
-
-    def __init__(self, distroarchseries, filepath=None):
-        self.distroarchseries = distroarchseries
-        self.filepath = filepath
-        self._messages = []
-
-    def _upload(self):
-        """Upload the self.filepath contents to Librarian.
-
-        Return the respective ILibraryFileAlias instance.
-        Raises ChrootManagerError if it could not be found.
-        """
-        try:
-            fd = open(self.filepath)
-        except IOError:
-            raise ChrootManagerError('Could not open: %s' % self.filepath)
-
-        flen = os.stat(self.filepath).st_size
-        filename = os.path.basename(self.filepath)
-        ftype = filenameToContentType(filename)
-
-        try:
-            alias_id = getUtility(ILibrarianClient).addFile(
-                filename, flen, fd, contentType=ftype)
-        except UploadFailed as info:
-            raise ChrootManagerError("Librarian upload failed: %s" % info)
-
-        lfa = getUtility(ILibraryFileAliasSet)[alias_id]
-
-        self._messages.append(
-            "LibraryFileAlias: %d, %s bytes, %s"
-            % (lfa.id, lfa.content.filesize, lfa.content.md5))
-
-        return lfa
-
-    def _getPocketChroot(self):
-        """Retrive PocketChroot record.
-
-        Return the respective IPocketChroot instance.
-        Raises ChrootManagerError if it could not be found.
-        """
-        pocket_chroot = self.distroarchseries.getPocketChroot()
-        if pocket_chroot is None:
-            raise ChrootManagerError(
-                'Could not find chroot for %s'
-                % (self.distroarchseries.title))
-
-        self._messages.append(
-            "PocketChroot for '%s' (%d) retrieved."
-            % (pocket_chroot.distroarchseries.title, pocket_chroot.id))
-
-        return pocket_chroot
-
-    def _update(self):
-        """Base method for add and update action."""
-        if self.filepath is None:
-            raise ChrootManagerError('Missing local chroot file path.')
-        alias = self._upload()
-        return self.distroarchseries.addOrUpdateChroot(alias)
-
-    def add(self):
-        """Create a new PocketChroot record.
-
-        Raises ChrootManagerError if self.filepath isn't set.
-        Update of pre-existing PocketChroot record will be automatically
-        handled.
-        It's a bind to the self.update method.
-        """
-        pocket_chroot = self._update()
-        self._messages.append(
-            "PocketChroot for '%s' (%d) added."
-            % (pocket_chroot.distroarchseries.title, pocket_chroot.id))
-
-    def update(self):
-        """Update a PocketChroot record.
-
-        Raises ChrootManagerError if filepath isn't set
-        Creation of non-existing PocketChroot records will be automatically
-        handled.
-        """
-        pocket_chroot = self._update()
-        self._messages.append(
-            "PocketChroot for '%s' (%d) updated."
-            % (pocket_chroot.distroarchseries.title, pocket_chroot.id))
-
-    def remove(self):
-        """Overwrite existing PocketChroot file to none.
-
-        Raises ChrootManagerError if the chroot record isn't found.
-        """
-        pocket_chroot = self._getPocketChroot()
-        self.distroarchseries.addOrUpdateChroot(None)
-        self._messages.append(
-            "PocketChroot for '%s' (%d) removed."
-            % (pocket_chroot.distroarchseries.title, pocket_chroot.id))
-
-    def get(self):
-        """Download chroot file from Librarian and store."""
-        pocket_chroot = self._getPocketChroot()
-
-        if self.filepath is None:
-            abs_filepath = os.path.abspath(pocket_chroot.chroot.filename)
-            if os.path.exists(abs_filepath):
-                raise ChrootManagerError(
-                    'cannot overwrite %s' % abs_filepath)
-            self._messages.append(
-                "Writing to '%s'." % abs_filepath)
-            local_file = open(pocket_chroot.chroot.filename, "w")
-        else:
-            abs_filepath = os.path.abspath(self.filepath)
-            if os.path.exists(abs_filepath):
-                raise ChrootManagerError(
-                    'cannot overwrite %s' % abs_filepath)
-            self._messages.append(
-                "Writing to '%s'." % abs_filepath)
-            local_file = open(abs_filepath, "w")
-
-        if pocket_chroot.chroot is None:
-            raise ChrootManagerError('Chroot was deleted.')
-
-        pocket_chroot.chroot.open()
-        copy_and_close(pocket_chroot.chroot, local_file)
-
-
-class ManageChrootScript(SoyuzScript):
-    """`SoyuzScript` that manages chroot files."""
-
-    usage = "%prog -d <distribution> -s <suite> -a <architecture> -f file"
-    description = "Manage the chroot files used by the builders."
-    success_message = "Success."
-
-    def add_my_options(self):
-        """Add script options."""
-        SoyuzScript.add_distro_options(self)
-        SoyuzScript.add_transaction_options(self)
-        self.parser.add_option(
-            '-a', '--architecture', dest='architecture', default=None,
-            help='Architecture tag')
-        self.parser.add_option(
-            '-f', '--filepath', dest='filepath', default=None,
-            help='Chroot file path')
-
-    def mainTask(self):
-        """Set up a ChrootManager object and invoke it."""
-        if len(self.args) != 1:
-            raise SoyuzScriptError(
-                "manage-chroot.py <add|update|remove|get>")
-
-        [action] = self.args
-
-        series = self.location.distroseries
-
-        try:
-            distroarchseries = series[self.options.architecture]
-        except NotFoundError as info:
-            raise SoyuzScriptError("Architecture not found: %s" % info)
-
-        # We don't want to have to force the user to confirm transactions
-        # for manage-chroot.py, so disable that feature of SoyuzScript.
-        self.options.confirm_all = True
-
-        self.logger.debug(
-            "Initializing ChrootManager for '%s'" % (distroarchseries.title))
-        chroot_manager = ChrootManager(
-            distroarchseries, filepath=self.options.filepath)
-
-        if action in chroot_manager.allowed_actions:
-            chroot_action = getattr(chroot_manager, action)
-        else:
-            self.logger.error(
-                "Allowed actions: %s" % chroot_manager.allowed_actions)
-            raise SoyuzScriptError("Unknown action: %s" % action)
-
-        try:
-            chroot_action()
-        except ChrootManagerError as info:
-            raise SoyuzScriptError(info)
-        else:
-            # Collect extra debug messages from chroot_manager.
-            for debug_message in chroot_manager._messages:
-                self.logger.debug(debug_message)

=== removed file 'lib/lp/soyuz/scripts/tests/test_chrootmanager.py'
--- lib/lp/soyuz/scripts/tests/test_chrootmanager.py	2012-03-27 13:38:04 +0000
+++ lib/lp/soyuz/scripts/tests/test_chrootmanager.py	1970-01-01 00:00:00 +0000
@@ -1,161 +0,0 @@
-# Copyright 2009-2012 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""ChrootManager facilities tests."""
-
-__metaclass__ = type
-
-import os
-import re
-import tempfile
-from unittest import TestCase
-
-import transaction
-from zope.component import getUtility
-
-from lp.registry.interfaces.distribution import IDistributionSet
-from lp.services.config import config
-from lp.soyuz.scripts.chrootmanager import (
-    ChrootManager,
-    ChrootManagerError,
-    )
-from lp.testing.layers import LaunchpadZopelessLayer
-
-
-class TestChrootManager(TestCase):
-    layer = LaunchpadZopelessLayer
-    dbuser = config.archivepublisher.dbuser
-
-    def setUp(self):
-        """Setup the test environment and retrieve useful instances."""
-        self.files_to_delete = []
-        self.distribution = getUtility(IDistributionSet)['ubuntu']
-        self.distroarchseries = self.distribution.currentseries['i386']
-
-    def tearDown(self):
-        """Clean up test environment and remove the test archive."""
-        self._remove_files()
-
-    def _create_file(self, filename, content=None):
-        """Create a file in the system temporary directory.
-
-        Annotate the path for posterior removal (see _remove_files)
-        """
-        filepath = os.path.join(tempfile.gettempdir(), filename)
-        if content is not None:
-            fd = open(filepath, "w")
-            fd.write(content)
-            fd.close()
-
-        self.files_to_delete.append(filepath)
-        return filepath
-
-    def _remove_files(self):
-        """Remove files during this test."""
-        for filepath in self.files_to_delete:
-            os.remove(filepath)
-
-        self.files_to_delete = []
-
-    def test_initialize(self):
-        """Chroot Manager initialization"""
-        chroot_manager = ChrootManager(self.distroarchseries)
-
-        self.assertEqual(self.distroarchseries,
-                         chroot_manager.distroarchseries)
-        self.assertEqual([], chroot_manager._messages)
-
-    def test_add_and_get(self):
-        """Adding new chroot and then retrieve it."""
-        chrootfilepath = self._create_file('chroot.test', content="UHMMM")
-        chrootfilename = os.path.basename(chrootfilepath)
-
-        chroot_manager = ChrootManager(
-            self.distroarchseries, filepath=chrootfilepath)
-
-        chroot_manager.add()
-        match = re.match(
-            ("LibraryFileAlias: \d+, 5 bytes, "
-             "5088e6471ab02d4268002f529a02621c"),
-            chroot_manager._messages[0])
-        self.assert_(match is not None,
-                     "chroot_manager message mismatch: %s" %
-                     chroot_manager._messages[0])
-        self.assertEqual(
-            ["PocketChroot for 'The Hoary Hedgehog Release for i386 (x86)' "
-             "(1) added."], chroot_manager._messages[1:])
-
-        pocket_chroot = self.distroarchseries.getPocketChroot()
-        self.assertEqual(chrootfilename, pocket_chroot.chroot.filename)
-
-        # required to turn librarian results visible.
-        transaction.commit()
-
-        dest = self._create_file('chroot.gotten')
-
-        chroot_manager = ChrootManager(
-            self.distroarchseries, filepath=dest)
-
-        chroot_manager.get()
-        self.assertEqual(
-            ["PocketChroot for 'The Hoary Hedgehog Release for i386 (x86)' "
-             "(1) retrieved.",
-             "Writing to '/tmp/chroot.gotten'."], chroot_manager._messages)
-
-        self.assertEqual(True, os.path.exists(dest))
-
-    def test_update_and_remove(self):
-        """Update existing chroot then remove it."""
-        chrootfilepath = self._create_file('chroot.update', content="DUHHHH")
-        chrootfilename = os.path.basename(chrootfilepath)
-
-        chroot_manager = ChrootManager(
-            self.distroarchseries, filepath=chrootfilepath)
-
-        chroot_manager.update()
-        match = re.match(
-            ("LibraryFileAlias: \d+, 6 bytes, "
-             "a4cd43e083161afcdf26f4324024d8ef"), chroot_manager._messages[0])
-        self.assert_(match is not None,
-                     "chroot_manager message mismatch: %s" %
-                     chroot_manager._messages[0])
-        self.assertEqual(
-            ["PocketChroot for 'The Hoary Hedgehog Release for i386 (x86)' "
-             "(1) updated."], chroot_manager._messages[1:])
-
-        pocket_chroot = self.distroarchseries.getPocketChroot()
-        self.assertEqual(chrootfilename, pocket_chroot.chroot.filename)
-
-        # required to turn librarian results visible.
-        transaction.commit()
-
-        chroot_manager = ChrootManager(self.distroarchseries)
-
-        chroot_manager.remove()
-        self.assertEqual(
-            ["PocketChroot for 'The Hoary Hedgehog Release for i386 (x86)' "
-             "(1) retrieved.",
-             "PocketChroot for 'The Hoary Hedgehog Release for i386 (x86)' "
-             "(1) removed."], chroot_manager._messages)
-
-        pocket_chroot = self.distroarchseries.getPocketChroot()
-        self.assertEqual(None, pocket_chroot.chroot)
-
-    def test_remove_fail(self):
-        """Attempt to remove non-existent chroot will fail."""
-        # Use a different distroarchseries in the sample data; this one
-        # has no chroot.
-        distroarchseries = self.distribution['warty']['hppa']
-        chroot_manager = ChrootManager(distroarchseries)
-
-        self.assertRaises(
-            ChrootManagerError, chroot_manager.remove)
-
-    def test_add_fail(self):
-        """Attempt to add non-existent local chroot will fail."""
-        chroot_manager = ChrootManager(
-            self.distroarchseries,
-            filepath='foo-bar')
-
-        self.assertRaises(
-            ChrootManagerError, chroot_manager.add)

=== removed file 'scripts/ftpmaster-tools/manage-chroot.py'
--- scripts/ftpmaster-tools/manage-chroot.py	2013-01-07 03:21:35 +0000
+++ scripts/ftpmaster-tools/manage-chroot.py	1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
-#!/usr/bin/python -S
-#
-# Copyright 2009-2012 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Tool for adding, removing and replacing buildd chroots."""
-
-import _pythonpath
-
-from lp.soyuz.scripts.chrootmanager import ManageChrootScript
-
-
-if __name__ == '__main__':
-    script = ManageChrootScript('manage-chroot', dbuser="fiera")
-    script.lock_and_run()