@@ -128,6 +128,8 @@ def job_name(self, project_name, config_suffix):
128128 'address' , ['afl' , 'engine_asan' ],
129129 minimize_job_override = LIBFUZZER_ASAN_JOB )
130130NO_ENGINE_ASAN_JOB = JobInfo ('asan_' , 'none' , 'address' , [])
131+ NO_ENGINE_HWASAN_JOB = JobInfo ('noengine_hwasan_' , 'none' , 'hardware' , [])
132+ NO_ENGINE_NONE_JOB = JobInfo ('noengine_nosanitizer_' , 'none' , 'none' , [])
131133
132134HONGGFUZZ_ASAN_JOB = JobInfo (
133135 'honggfuzz_asan_' ,
@@ -191,6 +193,11 @@ def job_name(self, project_name, config_suffix):
191193 'x86_64' : {
192194 'address' : NO_ENGINE_ASAN_JOB ,
193195 },
196+ 'arm' : {
197+ 'address' : NO_ENGINE_ASAN_JOB ,
198+ 'hardware' : NO_ENGINE_HWASAN_JOB ,
199+ 'none' : NO_ENGINE_NONE_JOB ,
200+ },
194201 },
195202 'centipede' : {
196203 'x86_64' : {
@@ -473,34 +480,40 @@ def _get_ccs(field_name, allow_list=True):
473480 return [utils .normalize_email (cc ) for cc in ccs ]
474481
475482
476- def update_fuzzer_jobs (fuzzer_entities , job_names ):
483+ def update_fuzzer_jobs (job_names ):
477484 """Update fuzzer job mappings."""
478485 to_delete = {}
479486
480- for fuzzer_entity_key in fuzzer_entities :
481- fuzzer_entity = fuzzer_entity_key .get ()
487+ # First, find all jobs that need to be deleted
488+ for job in data_types .Job .query ():
489+ if not job .environment_string :
490+ continue
482491
483- for job in data_types . Job . query ():
484- if not job . environment_string :
485- continue
492+ job_environment = job . get_environment ()
493+ if not utils . string_is_true ( job_environment . get ( 'MANAGED' , 'False' )) :
494+ continue
486495
487- job_environment = job .get_environment ()
488- if not utils .string_is_true (job_environment .get ('MANAGED' , 'False' )):
489- continue
496+ if job .name in job_names :
497+ continue
490498
491- if job .name in job_names :
492- continue
499+ logs .info (f'Deleting job { job .name } ' )
493500
494- logs . info (f'Deleting job { job .name } ' )
495- to_delete [job .name ] = job .key
501+ print (f'Deleting job { job .name } ' )
502+ to_delete [job .name ] = job .key
496503
504+ # Clean up job references from all fuzzer entities
505+ for fuzzer in data_types .Fuzzer .query ():
506+ # modified = False
507+ for job_name in to_delete :
497508 try :
498- fuzzer_entity .jobs .remove (job .name )
509+ fuzzer .jobs .remove (job_name )
510+ # modified = True
499511 except ValueError :
500512 pass
501513
502- fuzzer_entity .put ()
503- fuzzer_selection .update_mappings_for_fuzzer (fuzzer_entity )
514+ # if modified:
515+ fuzzer .put ()
516+ fuzzer_selection .update_mappings_for_fuzzer (fuzzer )
504517
505518 if to_delete :
506519 ndb_utils .delete_multi (to_delete .values ())
@@ -759,12 +772,19 @@ def _sync_job(self, project, info, corpus_bucket_name, quarantine_bucket_name,
759772
760773 for template in get_jobs_for_project (project , info ):
761774 if template .engine == 'none' :
762- # Engine-less jobs are not automatically managed.
763- continue
764-
765- fuzzer_entity = self ._fuzzer_entities .get (template .engine ).get ()
766- if not fuzzer_entity :
767- raise ProjectSetupError ('Invalid fuzzing engine ' + template .engine )
775+ if not info .get ('managed_engineless' , False ):
776+ # Engine-less jobs are not automatically managed unless explicitly
777+ # enabled
778+ continue
779+ # For engineless jobs, we don't need a fuzzer entity
780+ fuzzer_entity = None
781+ # Get fuzzers specified for this project
782+ fuzzers = info .get ('fuzzers' , [])
783+ else :
784+ fuzzer_entity = self ._fuzzer_entities .get (template .engine ).get ()
785+ if not fuzzer_entity :
786+ raise ProjectSetupError ('Invalid fuzzing engine ' + template .engine )
787+ fuzzers = []
768788
769789 job_name = template .job_name (project , self ._config_suffix )
770790 job = data_types .Job .query (data_types .Job .name == job_name ).get ()
@@ -786,10 +806,21 @@ def _sync_job(self, project, info, corpus_bucket_name, quarantine_bucket_name,
786806
787807 if not info .get ('disabled' , False ):
788808 job_names .append (job_name )
789- if job_name not in fuzzer_entity .jobs and not job .is_external ():
809+ if (fuzzer_entity and job_name not in fuzzer_entity .jobs and
810+ not job .is_external ()):
790811 # Enable new job.
791812 fuzzer_entity .jobs .append (job_name )
792813 fuzzer_entity .put ()
814+ # For engineless jobs, update the fuzzer-job mappings
815+ for fuzzer_name in fuzzers :
816+ fuzzer = data_types .Fuzzer .query (
817+ data_types .Fuzzer .name == fuzzer_name ).get ()
818+ if not fuzzer :
819+ raise ProjectSetupError (
820+ f'Invalid fuzzer { fuzzer_name } specified for engineless job' )
821+ if job_name not in fuzzer .jobs :
822+ fuzzer .jobs .append (job_name )
823+ fuzzer .put ()
793824
794825 job .name = job_name
795826 if self ._segregate_projects :
@@ -803,6 +834,7 @@ def _sync_job(self, project, info, corpus_bucket_name, quarantine_bucket_name,
803834 if template .engine == 'centipede' :
804835 build_bucket_path = self ._get_build_bucket_path (
805836 project , info , template .engine , 'none' , template .architecture )
837+ print (template , build_bucket_path )
806838 else :
807839 build_bucket_path = self ._get_build_bucket_path (
808840 project , info , template .engine , template .memory_tool ,
@@ -914,8 +946,16 @@ def _sync_job(self, project, info, corpus_bucket_name, quarantine_bucket_name,
914946 f'{ key } = { str (value ).encode ("unicode-escape" ).decode ("utf-8" )} \n '
915947 )
916948
917- job .put ()
949+ if info .get ('additional_vars' ):
950+ additional_vars = {}
951+ additional_vars .update (info .get ('additional_vars' , {}))
952+ for key , value in sorted (additional_vars .items ()):
953+ job .environment_string += (
954+ f'{ key } = { str (value ).encode ("unicode-escape" ).decode ("utf-8" )} \n '
955+ )
918956
957+ job .put ()
958+ print (project , job_names )
919959 return job_names
920960
921961 def sync_user_permissions (self , project , info ):
@@ -996,10 +1036,9 @@ def set_up(self, projects):
9961036 return SetupResult (enabled_projects , job_names )
9971037
9981038
999- def cleanup_stale_projects (fuzzer_entities , project_names , job_names ,
1000- segregate_projects ):
1039+ def cleanup_stale_projects (project_names , job_names , segregate_projects ):
10011040 """Clean up stale projects."""
1002- update_fuzzer_jobs (fuzzer_entities , job_names )
1041+ update_fuzzer_jobs (job_names )
10031042 cleanup_old_projects_settings (project_names )
10041043
10051044 if segregate_projects :
@@ -1095,9 +1134,7 @@ def main():
10951134 project_names .update (result .project_names )
10961135 job_names .update (result .job_names )
10971136
1098- cleanup_stale_projects (
1099- list (fuzzer_entities .values ()), project_names , job_names ,
1100- segregate_projects )
1137+ cleanup_stale_projects (project_names , job_names , segregate_projects )
11011138
11021139 logs .info ('Project setup succeeded.' )
11031140 return True
0 commit comments