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)
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)
def setUp(self): self.repo = Repo('/root')
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)
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)
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)
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)
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)
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)