275
275
job_id = BUILD_REVISION
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
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.')
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})
792
797
"""Main control logic."""
794
799
def __init__(self, jenkins, state_file=None, branches=None, mailer=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:
800
805
self.branches = branches
806
if ignore_branches is None:
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
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)
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.
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,
826
director = cls.from_config(config, state_file, branches)
834
director = cls.from_config(config, state_file, branches,
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,
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,
957
966
version, job, status, info['timestamp'], info['duration'])
960
def build_revision(branches):
969
def build_revision(branches, ignore_branches):
961
970
"""Top-level logic for building jobs.
963
972
For a supplied list of branches, it
965
974
- Runs jobs using CIDirector.
966
975
- Saves the updated state.
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)
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=[])
1033
1045
logger = logging.getLogger('cidirector')
1034
1046
with log_exceptions(logger) as result:
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.')