~veebers/ci-director/ignore-multibranch-jobs

« back to all changes in this revision

Viewing changes to cidirector/cidirector.py

  • Committer: Aaron Bentley
  • Date: 2016-08-31 17:36:58 UTC
  • mfrom: (185.1.5 ignore-specified)
  • Revision ID: aaron.bentley@canonical.com-20160831173658-1hoixkd85fyf091t
Add --ignore to ignore branches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
274
274
 
275
275
    job_id = BUILD_REVISION
276
276
 
277
 
    def __init__(self, repo_path, branches, logger, state_file, jenkins):
 
277
    def __init__(self, repo_path, branches, ignore_branches, logger,
 
278
                 state_file, jenkins):
278
279
        super(BuildRevisionJob, self).__init__(logger, state_file, jenkins)
279
280
        self.repo_path = repo_path
280
281
        self.branches = branches
 
282
        self.ignore_branches = ignore_branches
281
283
 
282
284
    def conflicting_jobs(self, active_jobs):
283
285
        if test_jobs_are_running(self.jenkins, active_jobs):
302
304
            self.logger.info('No revision ready to build.')
303
305
            return False
304
306
        branch = 'gitbranch:{}:{}'.format(branch, self.repo_path)
 
307
        logging.info('Selected {} ({})'.format(branch, revision_id))
305
308
        self.build({'branch': branch, 'revision': revision_id})
306
309
        return True
307
310
 
333
336
        branch_order = priority_branches
334
337
        branch_order.extend(sorted(set(tips).difference(branch_order)))
335
338
        for branch in branch_order:
 
339
            if branch in self.ignore_branches:
 
340
                continue
336
341
            try:
337
342
                commit = tips[branch]
338
343
            except KeyError:
792
797
    """Main control logic."""
793
798
 
794
799
    def __init__(self, jenkins, state_file=None, branches=None, mailer=None,
795
 
                 repo_path=None):
 
800
                 repo_path=None, ignore_branches=None):
796
801
        self.jenkins = jenkins
797
802
        self.state_file = state_file
798
803
        if branches is None:
799
804
            branches = []
800
805
        self.branches = branches
 
806
        if ignore_branches is None:
 
807
            ignore_branches = []
 
808
        self.ignore_branches = ignore_branches
801
809
        self.logger = logging.getLogger('cidirector')
802
810
        self.mailer = mailer
803
811
        self.repo_path = repo_path
804
812
 
805
813
    @classmethod
806
 
    def from_config(cls, config, state_file, branches):
 
814
    def from_config(cls, config, state_file, branches, ignore_branches):
807
815
        """Create an instace from a config, StateFile and list of branches."""
808
816
        mailer = Mailer.from_config(config)
809
817
        return CIDirector(
810
818
            make_jenkins(config),
811
 
            state_file, branches, mailer, config['repo_path'])
 
819
            state_file, branches, mailer, config['repo_path'], ignore_branches)
812
820
 
813
821
    @classmethod
814
822
    @contextmanager
815
 
    def stateful(cls, branches, save=True):
 
823
    def stateful(cls, branches, ignore_branches, save=True):
816
824
        """Provide a CIDirector whose state will be saved to disk.
817
825
 
818
826
        :param branches: The branches that the CIDirector should check for new
823
831
        config = ConfigReader.read_config()
824
832
        with StateFile.acquire(S3Storage.from_config(config)) as (state_file,
825
833
                                                                  fileobj):
826
 
            director = cls.from_config(config, state_file, branches)
 
834
            director = cls.from_config(config, state_file, branches,
 
835
                                       ignore_branches)
827
836
            try:
828
837
                yield director
829
838
            finally:
889
898
        for r_job in resourcefuljobs:
890
899
                candidate_jobs.append(r_job)
891
900
        candidate_jobs.append(BuildRevisionJob(
892
 
            self.repo_path, self.branches, self.logger, self.state_file,
893
 
            self.jenkins))
 
901
            self.repo_path, self.branches, self.ignore_branches, self.logger,
 
902
            self.state_file, self.jenkins))
894
903
        for job in candidate_jobs:
895
904
            if job.maybe_build(active_jobs):
896
905
                # We create a new set so that tests that access the parameters
903
912
    def adopt_builds(self, server_info):
904
913
        """Adopt any builds for the build-revision not already recorded."""
905
914
        # We happen to know that branch will not be used here.
906
 
        job_instances = [BuildRevisionJob(self.repo_path, None, self.logger,
907
 
                         self.state_file, self.jenkins)]
 
915
        job_instances = [BuildRevisionJob(self.repo_path, None, None,
 
916
                         self.logger, self.state_file, self.jenkins)]
908
917
        job_instances.extend(
909
918
            Job.make_subclass(si_job['name'], self.logger, self.state_file,
910
919
                              self.jenkins)
957
966
                version, job, status, info['timestamp'], info['duration'])
958
967
 
959
968
 
960
 
def build_revision(branches):
 
969
def build_revision(branches, ignore_branches):
961
970
    """Top-level logic for building jobs.
962
971
 
963
972
    For a supplied list of branches, it
965
974
    - Runs jobs using CIDirector.
966
975
    - Saves the updated state.
967
976
    """
968
 
    with CIDirector.stateful(branches) as director:
 
977
    with CIDirector.stateful(branches, ignore_branches) as director:
969
978
        server_info = ServerInfo(director.jenkins.get_info())
970
979
        director.schedule_builds(server_info)
971
980
 
1007
1016
                        default='ci-director.log')
1008
1017
    parser.add_argument('--log-count', help='The number of backups to keep.',
1009
1018
                        default=2, type=int)
 
1019
    parser.add_argument(
 
1020
        '--ignore', help='Ignore this branch when triggering revision builds',
 
1021
        action='append', default=[])
1010
1022
    return parser
1011
1023
 
1012
1024
 
1033
1045
    logger = logging.getLogger('cidirector')
1034
1046
    with log_exceptions(logger) as result:
1035
1047
        try:
1036
 
            build_revision(args.branch)
 
1048
            build_revision(args.branch, args.ignore)
1037
1049
        except StateFileInUse:
1038
1050
            logger.warning('State file already in use.')
1039
1051
            return 1