Example #1
0
def accept_source_changes(session, changes, user):
    group = changes.get('X-Lucy-Group', "default")
    suite = changes['Distribution']

    try:
        group_suite = session.query(GroupSuite).filter(
            Group.name==group,
            Suite.name==suite,
        ).one()
    except MultipleResultsFound:
        return reject_changes(session, changes, "internal-error")
    except NoResultFound:
        return reject_changes(session, changes, "invalid-suite-for-group")

    dsc = changes.get_dsc_obj()
    if dsc['Source'] != changes['Source']:
        return reject_changes(session, changes, "dsc-does-not-march-changes")
    if dsc['Version'] != changes['Version']:
        return reject_changes(session, changes, "dsc-does-not-march-changes")

    try:
        source = session.query(Source).filter(
            Source.name==dsc['Source'],
            Source.version==dsc['Version'],
            GroupSuite.group==group_suite.group,
        ).one()
        return reject_changes(session, changes, "source-already-in-group")
    except MultipleResultsFound:
        return reject_changes(session, changes, "internal-error")
    except NoResultFound:
        pass

    component = session.query(Component).filter_by(name="main").one()

    if 'Build-Architecture-Indep' in dsc:
        valid_affinities = dsc['Build-Architecture-Indep']
    elif 'X-Build-Architecture-Indep' in dsc:
        valid_affinities = dsc['X-Build-Architecture-Indep']
    elif 'X-Arch-Indep-Build-Arch' in dsc:
        valid_affinities = dsc['X-Arch-Indep-Build-Arch']
    else:
        valid_affinities = "any"

    source = create_source(dsc, group_suite, component, user)
    create_jobs(source, valid_affinities)

    session.add(source)  # OK. Populated entry. Let's insert.
    session.commit()  # Neato.

    # OK. We have a changes in order. Let's roll.
    repo = Repo(group_suite.group.repo_path)
    repo.add_changes(changes)

    emit('accept', 'source', source.debilize())

    # OK. It's safely in the database and repo. Let's cleanup.
    for fp in [changes.get_filename()] + changes.get_files():
        os.unlink(fp)
Example #2
0
def accept_binary_changes(session, changes, builder):
    # OK. We'll relate this back to a build job.
    job = changes.get('X-Debile-Job', None)
    if job is None:
        return reject_changes(session, changes, "no-job")
    job = session.query(Job).get(job)
    source = job.source

    if changes.get('Source') != source.name:
        return reject_changes(session, changes, "binary-source-name-mismatch")

    if changes.get("Version") != source.version:
        return reject_changes(session, changes, "binary-source-version-mismatch")

    if changes.get('X-Lucy-Group', "default") != source.group_suite.group.name:
        return reject_changes(session, changes, "binary-source-group-mismatch")

    if changes.get('Distribution') != source.group_suite.suite.name:
        return reject_changes(session, changes, "binary-source-suite-mismatch")

    if changes.get("Architecture") != job.arch.name:
        return reject_changes(session, changes, "wrong-architecture")

    if builder != job.builder:
        return reject_changes(session, changes, "wrong-builder")

    binary = Binary.from_job(job)

    ## OK. Let's make sure we can add this.
    try:
        repo = Repo(job.source.group_suite.group.repo_path)
        repo.add_changes(changes)
    except RepoSourceAlreadyRegistered:
        return reject_changes(session, changes, 'stupid-source-thing')

    job.changes_uploaded(session, binary)
    session.add(binary)
    session.commit()

    emit('accept', 'binary', binary.debilize())

    # OK. It's safely in the database and repo. Let's cleanup.
    for fp in [changes.get_filename()] + changes.get_files():
        os.unlink(fp)
Example #3
0
 def setUp(self):
     self.repo = Repo('/root')
Example #4
0
class ReprepoTestCase(unittest.TestCase):
    def setUp(self):
        self.repo = Repo('/root')


    def test_repo_constructor(self):
        self.assertEquals(self.repo.root, '/root')


    @mock.patch('debile.utils.deb822.Changes',
            return_value={'distribution':'unstable'})
    @mock.patch('debile.master.reprepro.Repo.include')
    @mock.patch('debile.master.changes.Changes.get_changes_file',
            return_value='mock.dsc')
    def test_add_changes(self, mock_changes, mock_reprepro, mock):
        changes = Changes(string='Some change')
        self.repo.add_changes(changes)

        args,_ = mock_reprepro.call_args
        
        self.assertEquals(args, ('unstable', 'mock.dsc'))


    @mock.patch('debile.master.reprepro.run_command', return_value=(0,0,0))
    def test_exec_with_successful_command(self, mock):
        self.repo._exec('include', 'unstable', 'test.changes')
        self.assertTrue(mock.called)

        args,_ = mock.call_args

        self.assertEquals(args, (['reprepro', '-Vb', '/root', 'include',
            'unstable', 'test.changes'],))


    @mock.patch('debile.master.reprepro.run_command', return_value=(0,0,-1))
    def test_exec_with_failure_command(self, mock):
        self.assertRaises(RepoException, self.repo._exec)


    @mock.patch('debile.master.reprepro.run_command', return_value=(0,0,0))
    def test_include(self, mock):
        (out, stderr, ret) = self.repo.include('unstable', 'test.changes')

        self.assertTrue(mock.called)
        self.assertEquals((out, stderr, ret), (0,0,0))


    @mock.patch('debile.master.reprepro.RepoException.message', return_value=1)
    @mock.patch('debile.master.reprepro.run_command', return_value=(0,0,-1))
    def test_include_raise_repoexception(self, mock, mock_exception):
        self.assertRaises(RepoException, self.repo.include, 'unstable',
                'test.changes')


    @mock.patch('debile.master.reprepro.RepoException.message', return_value=254)
    @mock.patch('debile.master.reprepro.run_command', return_value=(0,0,-1))
    def test_include_raise_repo_source_already_registered(self, mock,
            mock_exception):
        self.assertRaises(RepoException, self.repo.include, 'unstable',
                'test.changes')


    def test_includedeb_not_implemented(self):
        self.assertRaises(NotImplementedError, self.repo.includedeb, 'unstable',
                'test.deb')


    def test_includeudeb_not_implemented(self):
        self.assertRaises(NotImplementedError, self.repo.includeudeb, 'unstable',
                'test.udeb')


    def test_includedsc_not_implemented(self):
        self.assertRaises(NotImplementedError, self.repo.includedsc, 'unstable',
                'test.dsc')


    def test_list_not_implemented(self):
        self.assertRaises(NotImplementedError, self.repo.list, 'unstable', 
                'test')


    def test_clearvanished_not_implemented(self):
        self.assertRaises(NotImplementedError, self.repo.clearvanished)
Example #5
0
def accept_source_changes(default_group, config, session, changes, user):
    group = changes.get('X-Debile-Group', default_group)
    suite = changes['Distribution']

    try:
        group_suite = session.query(GroupSuite).join(GroupSuite.group).join(GroupSuite.suite).filter(
            Group.name == group,
            Suite.name == suite,
        ).one()
    except MultipleResultsFound:
        return reject_changes(session, changes, "internal-error")
    except NoResultFound:
        return reject_changes(session, changes, "invalid-suite-for-group")

    dsc = changes.get_dsc_obj()
    if dsc['Source'] != changes['Source']:
        return reject_changes(session, changes, "dsc-does-not-march-changes")
    if dsc['Version'] != changes['Version']:
        return reject_changes(session, changes, "dsc-does-not-march-changes")

    try:
        source = session.query(Source).filter(
            Source.name == dsc['Source'],
            Source.version == dsc['Version'],
            GroupSuite.group == group_suite.group,
        ).one()
        return reject_changes(session, changes, "source-already-in-group")
    except MultipleResultsFound:
        return reject_changes(session, changes, "internal-error")
    except NoResultFound:
        pass

    oldsources = session.query(Source).filter(
        Source.group_suite == group_suite,
        Source.name == dsc['Source'],
    )
    for oldsource in oldsources:
        if version_compare(oldsource.version, dsc['Version']) > 0:
            return reject_changes(session, changes, "newer-source-already-in-suite")

    # Drop any old jobs that are still pending.
    for oldsource in oldsources:
        for job in oldsource.jobs:
            if (not any(job.results) and not any(job.built_binaries)):
                session.delete(job)
            elif job.failed is None:
                job.failed = True
        if not any(oldsource.jobs):
            session.delete(oldsource)

    component = session.query(Component).filter_by(name="main").one()

    if 'Build-Architecture-Indep' in dsc:
        valid_affinities = dsc['Build-Architecture-Indep']
    elif 'X-Build-Architecture-Indep' in dsc:
        valid_affinities = dsc['X-Build-Architecture-Indep']
    elif 'X-Arch-Indep-Build-Arch' in dsc:
        valid_affinities = dsc['X-Arch-Indep-Build-Arch']
    else:
        valid_affinities = "any"

    with session.no_autoflush:
        source = create_source(dsc, group_suite, component, user,
                               config["affinity_preference"], valid_affinities)
        create_jobs(source)
        session.add(source)

        # We have a changes in order. Let's roll.
        repo = Repo(group_suite.group.repo_path)
        repo.add_changes(changes)
        (source.directory, source.dsc_filename) = repo.find_dsc(source)

    emit('accept', 'source', source.debilize())

    # OK. It's safely in the database and repo. Let's cleanup.
    for fp in [changes.get_changes_file()] + changes.get_files():
        os.unlink(fp)
Example #6
0
def accept_binary_changes(default_group, config, session, changes, builder):
    # OK. We'll relate this back to a build job.
    job = changes.get('X-Debile-Job', None)
    if job is None:
        return reject_changes(session, changes, "no-job")
    job = session.query(Job).get(job)
    source = job.source

    if changes.get('Source') != source.name:
        return reject_changes(session, changes, "binary-source-name-mismatch")

    if changes.get("Version") != source.version:
        return reject_changes(
            session, changes, "binary-source-version-mismatch")

    if changes.get('X-Debile-Group', default_group) != source.group.name:
        return reject_changes(session, changes, "binary-source-group-mismatch")

    if changes.get('Distribution') != source.suite.name:
        return reject_changes(session, changes, "binary-source-suite-mismatch")

    if builder != job.builder:
        return reject_changes(session, changes, "wrong-builder")

    anames = changes.get("Architecture").split(None)
    arches = session.query(Arch).filter(Arch.name.in_(anames)).all()

    binaries = {}
    for arch in arches:
        if arch.name not in [job.arch.name, "all"]:
            return reject_changes(session, changes, "wrong-architecture")
        binaries[arch.name] = job.new_binary(arch)

    if not binaries:
        return reject_changes(session, changes, "no-architecture")

    session.add_all(binaries.values())

    PATH = re.compile("^/pool/.*/")
    ARCH = re.compile(".+_(?P<arch>[^_]+)\.u?deb$")
    for entry in changes.get('Files'):
        directory = source.directory
        if '/' in entry['section']:
            component, section = entry['section'].split('/', 1)
            directory = PATH.sub("/pool/%s/" % component, directory)
        arch = ARCH.match(entry['name']).groupdict().get('arch')
        if arch not in binaries:
            return reject_changes(session, changes, "bad-architecture-of-file")
        deb = Deb(binary=binaries[arch], directory=directory, filename=entry['name'])
        session.add(deb)

    ## OK. Let's make sure we can add this.
    try:
        repo = Repo(job.group.repo_path)
        repo.add_changes(changes)
    except RepoSourceAlreadyRegistered:
        return reject_changes(session, changes, 'stupid-source-thing')

    for binary in binaries.values():
        emit('accept', 'binary', binary.debilize())

    # OK. It's safely in the database and repo. Let's cleanup.
    for fp in [changes.get_changes_file()] + changes.get_files():
        os.unlink(fp)
Example #7
0
 def setUp(self):
     self.repo = Repo('/root')
Example #8
0
class ReprepoTestCase(unittest.TestCase):
    def setUp(self):
        self.repo = Repo('/root')

    def test_repo_constructor(self):
        self.assertEquals(self.repo.root, '/root')

    @mock.patch('debile.utils.deb822.Changes',
                return_value={'distribution': 'unstable'})
    @mock.patch('debile.master.reprepro.Repo.include')
    @mock.patch('debile.master.changes.Changes.get_changes_file',
                return_value='mock.dsc')
    def test_add_changes(self, mock_changes, mock_reprepro, mock):
        changes = Changes(string='Some change')
        self.repo.add_changes(changes)

        args, _ = mock_reprepro.call_args

        self.assertEquals(args, ('unstable', 'mock.dsc'))

    @mock.patch('debile.master.reprepro.run_command', return_value=(0, 0, 0))
    def test_exec_with_successful_command(self, mock):
        self.repo._exec('include', 'unstable', 'test.changes')
        self.assertTrue(mock.called)

        args, _ = mock.call_args

        self.assertEquals(args, ([
            'reprepro', '-Vb', '/root', 'include', 'unstable', 'test.changes'
        ], ))

    @mock.patch('debile.master.reprepro.run_command', return_value=(0, 0, -1))
    def test_exec_with_failure_command(self, mock):
        self.assertRaises(RepoException, self.repo._exec)

    @mock.patch('debile.master.reprepro.run_command', return_value=(0, 0, 0))
    def test_include(self, mock):
        (out, stderr, ret) = self.repo.include('unstable', 'test.changes')

        self.assertTrue(mock.called)
        self.assertEquals((out, stderr, ret), (0, 0, 0))

    @mock.patch('debile.master.reprepro.RepoException.message', return_value=1)
    @mock.patch('debile.master.reprepro.run_command', return_value=(0, 0, -1))
    def test_include_raise_repoexception(self, mock, mock_exception):
        self.assertRaises(RepoException, self.repo.include, 'unstable',
                          'test.changes')

    @mock.patch('debile.master.reprepro.RepoException.message',
                return_value=254)
    @mock.patch('debile.master.reprepro.run_command', return_value=(0, 0, -1))
    def test_include_raise_repo_source_already_registered(
            self, mock, mock_exception):
        self.assertRaises(RepoException, self.repo.include, 'unstable',
                          'test.changes')

    def test_includedeb_not_implemented(self):
        self.assertRaises(NotImplementedError, self.repo.includedeb,
                          'unstable', 'test.deb')

    def test_includeudeb_not_implemented(self):
        self.assertRaises(NotImplementedError, self.repo.includeudeb,
                          'unstable', 'test.udeb')

    def test_includedsc_not_implemented(self):
        self.assertRaises(NotImplementedError, self.repo.includedsc,
                          'unstable', 'test.dsc')

    def test_list_not_implemented(self):
        self.assertRaises(NotImplementedError, self.repo.list, 'unstable',
                          'test')

    def test_clearvanished_not_implemented(self):
        self.assertRaises(NotImplementedError, self.repo.clearvanished)
Example #9
0
def accept_binary_changes(default_group, config, session, changes, builder):
    # OK. We'll relate this back to a build job.
    job = changes.get('X-Debile-Job', None)
    if job is None:
        return reject_changes(session, changes, "no-job")
    job = session.query(Job).get(job)
    source = job.source

    if changes.get('Source') != source.name:
        return reject_changes(session, changes, "binary-source-name-mismatch")

    if changes.get("Version") != source.version:
        return reject_changes(session, changes,
                              "binary-source-version-mismatch")

    if changes.get('X-Debile-Group', default_group) != source.group.name:
        return reject_changes(session, changes, "binary-source-group-mismatch")

    if changes.get('Distribution') != source.suite.name:
        return reject_changes(session, changes, "binary-source-suite-mismatch")

    if builder != job.builder:
        return reject_changes(session, changes, "wrong-builder")

    anames = changes.get("Architecture").split(None)
    arches = session.query(Arch).filter(Arch.name.in_(anames)).all()

    binaries = {}
    for arch in arches:
        if arch.name not in [job.arch.name, "all"]:
            return reject_changes(session, changes, "wrong-architecture")
        binaries[arch.name] = job.new_binary(arch)

    if not binaries:
        return reject_changes(session, changes, "no-architecture")

    session.add_all(binaries.values())

    PATH = re.compile("^/pool/.*/")
    ARCH = re.compile(".+_(?P<arch>[^_]+)\.u?deb$")
    for entry in changes.get('Files'):
        directory = source.directory
        if '/' in entry['section']:
            component, section = entry['section'].split('/', 1)
            directory = PATH.sub("/pool/%s/" % component, directory)
        arch = ARCH.match(entry['name']).groupdict().get('arch')
        if arch not in binaries:
            return reject_changes(session, changes, "bad-architecture-of-file")
        deb = Deb(binary=binaries[arch],
                  directory=directory,
                  filename=entry['name'])
        session.add(deb)

    # OK. Let's make sure we can add this.
    try:
        repo = Repo(job.group.repo_path)
        repo.add_changes(changes)
    except RepoSourceAlreadyRegistered:
        return reject_changes(session, changes, 'stupid-source-thing')

    for binary in binaries.values():
        emit('accept', 'binary', binary.debilize())

    # OK. It's safely in the database and repo. Let's cleanup.
    for fp in [changes.get_changes_file()] + changes.get_files():
        os.unlink(fp)
Example #10
0
def accept_source_changes(default_group, config, session, changes, user):
    group = changes.get('X-Debile-Group', default_group)
    suite = changes['Distribution']

    try:
        group_suite = session.query(GroupSuite).join(GroupSuite.group).join(
            GroupSuite.suite).filter(
                Group.name == group,
                Suite.name == suite,
            ).one()
    except MultipleResultsFound:
        return reject_changes(session, changes, "internal-error")
    except NoResultFound:
        return reject_changes(session, changes, "invalid-suite-for-group")

    dsc = changes.get_dsc_obj()
    if dsc['Source'] != changes['Source']:
        return reject_changes(session, changes, "dsc-does-not-march-changes")
    if dsc['Version'] != changes['Version']:
        return reject_changes(session, changes, "dsc-does-not-march-changes")

    try:
        source = session.query(Source).filter(
            Source.name == dsc['Source'],
            Source.version == dsc['Version'],
            GroupSuite.group == group_suite.group,
        ).one()
        return reject_changes(session, changes, "source-already-in-group")
    except MultipleResultsFound:
        return reject_changes(session, changes, "internal-error")
    except NoResultFound:
        pass

    oldsources = session.query(Source).filter(
        Source.group_suite == group_suite,
        Source.name == dsc['Source'],
    )
    for oldsource in oldsources:
        if version_compare(oldsource.version, dsc['Version']) > 0:
            return reject_changes(session, changes,
                                  "newer-source-already-in-suite")

    # Drop any old jobs that are still pending.
    for oldsource in oldsources:
        for job in oldsource.jobs:
            if (not any(job.results) and not any(job.built_binaries)):
                session.delete(job)
            elif job.failed is None:
                job.failed = True
        if not any(oldsource.jobs):
            session.delete(oldsource)

    component = session.query(Component).filter_by(name="main").one()

    if 'Build-Architecture-Indep' in dsc:
        valid_affinities = dsc['Build-Architecture-Indep']
    elif 'X-Build-Architecture-Indep' in dsc:
        valid_affinities = dsc['X-Build-Architecture-Indep']
    elif 'X-Arch-Indep-Build-Arch' in dsc:
        valid_affinities = dsc['X-Arch-Indep-Build-Arch']
    else:
        valid_affinities = "any"

    with session.no_autoflush:
        source = create_source(dsc, group_suite, component, user,
                               config["affinity_preference"], valid_affinities)
        create_jobs(source)
        session.add(source)

        # We have a changes in order. Let's roll.
        repo = Repo(group_suite.group.repo_path)
        repo.add_changes(changes)
        try:
            (source.directory, source.dsc_filename) = repo.find_dsc(source)
        except RepoPackageNotFound:
            return reject_changes(session, changes,
                                  "reprepo-package-not-found")

    emit('accept', 'source', source.debilize())

    # OK. It's safely in the database and repo. Let's cleanup.
    for fp in [changes.get_changes_file()] + changes.get_files():
        os.unlink(fp)