def create_chronos_job_config_object_from_configs(context, service, instance, job_name): job_config = chronos_tools.create_complete_config(service=service, job_name=instance, soa_dir=context.soa_dir) # s_c_l caches reads from the fs and doesn't offer a way to ignore the cache, so doesn't return # the most recent version on the file. I *hate* this, but need to move on. chronos_tools.service_configuration_lib._yaml_cache = {} context.jobs[job_name] = job_config
def create_chronos_job_config_object_from_configs(context, service, instance, job_name): job_config = chronos_tools.create_complete_config( service=service, job_name=instance, soa_dir=context.soa_dir, ) # s_c_l caches reads from the fs and doesn't offer a way to ignore the cache, so doesn't return # the most recent version on the file. I *hate* this, but need to move on. chronos_tools.service_configuration_lib._yaml_cache = {} context.jobs[job_name] = job_config
def test_setup_job_with_previously_enabled_job(self): fake_existing_job = { 'name': 'fake_job', 'disabled': False, } with mock.patch( 'paasta_tools.setup_chronos_job.bounce_chronos_job', autospec=True, return_value=(0, 'ok'), ) as mock_bounce_chronos_job, mock.patch( 'paasta_tools.chronos_tools.lookup_chronos_jobs', autospec=True, ) as mock_lookup_chronos_jobs, mock.patch( 'paasta_tools.chronos_tools.sort_jobs', autospec=True, return_value=[fake_existing_job], ), mock.patch( 'paasta_tools.utils.load_system_paasta_config', autospec=True, ), mock.patch( 'paasta_tools.chronos_tools.load_system_paasta_config', autospec=True, ) as load_system_paasta_config_patch, mock.patch( 'paasta_tools.chronos_tools.load_chronos_job_config', autospec=True, return_value=self.fake_chronos_job_config, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = self.fake_cluster load_system_paasta_config_patch.return_value.get_volumes.return_value = [] load_system_paasta_config_patch.return_value.get_deploy_whitelist.return_value = None load_system_paasta_config_patch.return_value.get_dockercfg_location.return_value = \ "file:///root/.dockercfg" complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir, ) actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, job_to_update=complete_config, client=self.fake_client, ) assert mock_lookup_chronos_jobs.called assert actual == mock_bounce_chronos_job.return_value
def test_setup_job_does_nothing_with_only_existing_app(self): fake_existing_job = self.fake_config_dict with contextlib.nested( mock.patch('setup_chronos_job.bounce_chronos_job', autospec=True, return_value=(0, 'ok')), mock.patch('paasta_tools.chronos_tools.lookup_chronos_jobs', autospec=True), mock.patch('paasta_tools.chronos_tools.sort_jobs', autospec=True, return_value=[fake_existing_job]), mock.patch( 'paasta_tools.chronos_tools.load_system_paasta_config', autospec=True), mock.patch( 'paasta_tools.chronos_tools.load_chronos_job_config', autospec=True, return_value=self.fake_chronos_job_config), ) as ( mock_bounce_chronos_job, mock_lookup_chronos_jobs, mock_sort_jobs, load_system_paasta_config_patch, load_chronos_job_config_patch, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = self.fake_cluster complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir) # Force the complete_config's name to match the return value of # lookup_chronos_jobs to simulate that they have the same name complete_config["name"] = fake_existing_job["name"] actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, chronos_job_config=self.fake_chronos_job_config, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, jobs_to_delete=[], jobs_to_disable=[], job_to_create=None, client=self.fake_client, ) assert mock_lookup_chronos_jobs.called assert actual == mock_bounce_chronos_job.return_value
def test_setup_job_with_previously_enabled_job(self): fake_existing_job = { 'name': 'fake_job', 'disabled': False, } with contextlib.nested( mock.patch('setup_chronos_job.bounce_chronos_job', autospec=True, return_value=(0, 'ok')), mock.patch('paasta_tools.chronos_tools.lookup_chronos_jobs', autospec=True), mock.patch('paasta_tools.chronos_tools.sort_jobs', autospec=True, return_value=[fake_existing_job]), mock.patch( 'paasta_tools.chronos_tools.load_system_paasta_config', autospec=True), mock.patch( 'paasta_tools.chronos_tools.load_chronos_job_config', autospec=True, return_value=self.fake_chronos_job_config), ) as ( mock_bounce_chronos_job, mock_lookup_chronos_jobs, mock_sort_jobs, load_system_paasta_config_patch, load_chronos_job_config_patch, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = self.fake_cluster complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir) actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, chronos_job_config=self.fake_chronos_job_config, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, jobs_to_delete=[], jobs_to_disable=[fake_existing_job], job_to_create=complete_config, client=self.fake_client, ) assert mock_lookup_chronos_jobs.called assert actual == mock_bounce_chronos_job.return_value
def test_setup_job_new_app_with_no_previous_jobs(self): fake_existing_jobs = [] with mock.patch( "paasta_tools.setup_chronos_job.bounce_chronos_job", autospec=True, return_value=(0, "ok"), ) as mock_bounce_chronos_job, mock.patch( "paasta_tools.chronos_tools.lookup_chronos_jobs", autospec=True), mock.patch( "paasta_tools.chronos_tools.sort_jobs", autospec=True, return_value=fake_existing_jobs, ), mock.patch( "paasta_tools.utils.load_system_paasta_config", autospec=True), mock.patch( "paasta_tools.chronos_tools.load_system_paasta_config", autospec=True ) as load_system_paasta_config_patch, mock.patch( "paasta_tools.chronos_tools.load_chronos_job_config", autospec=True, return_value=self.fake_chronos_job_config, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = ( self.fake_cluster) load_system_paasta_config_patch.return_value.get_volumes.return_value = [] load_system_paasta_config_patch.return_value.get_deploy_whitelist.return_value = ( None) load_system_paasta_config_patch.return_value.get_dockercfg_location.return_value = ( "file:///root/.dockercfg") complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir, ) actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, job_to_update=complete_config, client=self.fake_client, ) assert actual == mock_bounce_chronos_job.return_value
def main(): args = parse_args() cluster = load_system_paasta_config().get_cluster() service, instance = chronos_tools.decompose_job_id(args.service_instance) config = chronos_tools.load_chronos_config() client = chronos_tools.get_chronos_client(config) system_paasta_config = load_system_paasta_config() chronos_job_config = chronos_tools.load_chronos_job_config( service, instance, system_paasta_config.get_cluster(), soa_dir=args.soa_dir) try: complete_job_config = chronos_tools.create_complete_config( service=service, job_name=instance, soa_dir=args.soa_dir, ) except (NoDeploymentsAvailable, NoDockerImageError) as e: error_msg = "No deployment found for %s in cluster %s. Has Jenkins run for it?" % ( args.service_instance, cluster) print error_msg raise e except chronos_tools.UnknownChronosJobError as e: error_msg = ( "Could not read chronos configuration file for %s in cluster %s\n" % (args.service_instance, cluster) + "Error was: %s" % str(e)) print error_msg raise e except chronos_tools.InvalidParentError as e: raise e # complete_job_config is a formatted version # of the job, so the command is fornatted in the context # of 'now' # replace it with the 'original' cmd so it can be # re rendered original_command = chronos_job_config.get_cmd() complete_job_config['command'] = original_command clone = clone_job( complete_job_config, datetime.datetime.strptime(args.execution_date, "%Y-%m-%dT%H:%M:%S")) client.add(clone)
def test_setup_job_new_app_with_no_previous_jobs(self): fake_existing_jobs = [] with contextlib.nested( mock.patch('paasta_tools.setup_chronos_job.bounce_chronos_job', autospec=True, return_value=(0, 'ok')), mock.patch('paasta_tools.chronos_tools.lookup_chronos_jobs', autospec=True), mock.patch('paasta_tools.chronos_tools.sort_jobs', autospec=True, return_value=fake_existing_jobs), mock.patch( 'paasta_tools.chronos_tools.load_system_paasta_config', autospec=True), mock.patch( 'paasta_tools.chronos_tools.load_chronos_job_config', autospec=True, return_value=self.fake_chronos_job_config), ) as ( mock_bounce_chronos_job, lookup_chronos_jobs_patch, sort_jobs_patch, load_system_paasta_config_patch, load_chronos_job_config_patch, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = self.fake_cluster load_system_paasta_config_patch.return_value.get_volumes.return_value = [] load_system_paasta_config_patch.return_value.get_dockerfile_location.return_value = \ 'file:///root/.dockercfg' complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir, ) actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, job_to_update=complete_config, client=self.fake_client, ) assert actual == mock_bounce_chronos_job.return_value
def test_setup_job_does_nothing_with_only_existing_app(self): fake_existing_job = self.fake_config_dict with contextlib.nested( mock.patch('setup_chronos_job.bounce_chronos_job', autospec=True, return_value=(0, 'ok')), mock.patch('paasta_tools.chronos_tools.lookup_chronos_jobs', autospec=True), mock.patch('paasta_tools.chronos_tools.sort_jobs', autospec=True, return_value=[fake_existing_job]), mock.patch('paasta_tools.chronos_tools.load_system_paasta_config', autospec=True), mock.patch('paasta_tools.chronos_tools.load_chronos_job_config', autospec=True, return_value=self.fake_chronos_job_config), ) as ( mock_bounce_chronos_job, mock_lookup_chronos_jobs, mock_sort_jobs, load_system_paasta_config_patch, load_chronos_job_config_patch, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = self.fake_cluster complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir ) # Force the complete_config's name to match the return value of # lookup_chronos_jobs to simulate that they have the same name complete_config["name"] = fake_existing_job["name"] actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, chronos_job_config=self.fake_chronos_job_config, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, jobs_to_delete=[], jobs_to_disable=[], job_to_create=None, client=self.fake_client, ) assert mock_lookup_chronos_jobs.called assert actual == mock_bounce_chronos_job.return_value
def test_setup_job_with_previously_enabled_job(self): fake_existing_job = { 'name': 'fake_job', 'disabled': False, } with contextlib.nested( mock.patch('paasta_tools.setup_chronos_job.bounce_chronos_job', autospec=True, return_value=(0, 'ok')), mock.patch('paasta_tools.chronos_tools.lookup_chronos_jobs', autospec=True), mock.patch('paasta_tools.chronos_tools.sort_jobs', autospec=True, return_value=[fake_existing_job]), mock.patch('paasta_tools.chronos_tools.load_system_paasta_config', autospec=True), mock.patch('paasta_tools.chronos_tools.load_chronos_job_config', autospec=True, return_value=self.fake_chronos_job_config), ) as ( mock_bounce_chronos_job, mock_lookup_chronos_jobs, mock_sort_jobs, load_system_paasta_config_patch, load_chronos_job_config_patch, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = self.fake_cluster load_system_paasta_config_patch.return_value.get_volumes.return_value = [] load_system_paasta_config_patch.return_value.get_dockercfg_location.return_value = \ "file:///root/.dockercfg" complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir ) actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, job_to_update=complete_config, client=self.fake_client, ) assert mock_lookup_chronos_jobs.called assert actual == mock_bounce_chronos_job.return_value
def test_setup_job_new_app_with_no_previous_jobs(self): fake_existing_jobs = [] with contextlib.nested( mock.patch('setup_chronos_job.bounce_chronos_job', autospec=True, return_value=(0, 'ok')), mock.patch('paasta_tools.chronos_tools.lookup_chronos_jobs', autospec=True), mock.patch('paasta_tools.chronos_tools.sort_jobs', autospec=True, return_value=fake_existing_jobs), mock.patch('paasta_tools.chronos_tools.load_system_paasta_config', autospec=True), mock.patch('paasta_tools.chronos_tools.load_chronos_job_config', autospec=True, return_value=self.fake_chronos_job_config), ) as ( mock_bounce_chronos_job, lookup_chronos_jobs_patch, sort_jobs_patch, load_system_paasta_config_patch, load_chronos_job_config_patch, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = self.fake_cluster complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir ) actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, chronos_job_config=self.fake_chronos_job_config, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, jobs_to_delete=[], jobs_to_disable=[], job_to_create=complete_config, client=self.fake_client, ) assert actual == mock_bounce_chronos_job.return_value
def main(): args = parse_args() cluster = load_system_paasta_config().get_cluster() service, instance = chronos_tools.decompose_job_id(args.service_instance) config = chronos_tools.load_chronos_config() client = chronos_tools.get_chronos_client(config) system_paasta_config = load_system_paasta_config() chronos_job_config = chronos_tools.load_chronos_job_config( service, instance, system_paasta_config.get_cluster(), soa_dir=args.soa_dir) try: complete_job_config = chronos_tools.create_complete_config( service=service, job_name=instance, soa_dir=args.soa_dir, ) except (NoDeploymentsAvailable, NoDockerImageError) as e: error_msg = "No deployment found for %s in cluster %s. Has Jenkins run for it?" % ( args.service_instance, cluster) print error_msg raise e except chronos_tools.UnknownChronosJobError as e: error_msg = ( "Could not read chronos configuration file for %s in cluster %s\n" % (args.service_instance, cluster) + "Error was: %s" % str(e)) print error_msg raise e except chronos_tools.InvalidParentError as e: raise e # complete_job_config is a formatted version # of the job, so the command is fornatted in the context # of 'now' # replace it with the 'original' cmd so it can be # re rendered original_command = chronos_job_config.get_cmd() complete_job_config['command'] = original_command clone = clone_job(complete_job_config, datetime.datetime.strptime(args.execution_date, "%Y-%m-%dT%H:%M:%S")) client.add(clone)
def test_setup_job_with_previously_enabled_job(self): fake_existing_job = {"name": "fake_job", "disabled": False} with contextlib.nested( mock.patch("setup_chronos_job.bounce_chronos_job", autospec=True, return_value=(0, "ok")), mock.patch("paasta_tools.chronos_tools.lookup_chronos_jobs", autospec=True), mock.patch("paasta_tools.chronos_tools.sort_jobs", autospec=True, return_value=[fake_existing_job]), mock.patch("paasta_tools.chronos_tools.load_system_paasta_config", autospec=True), mock.patch( "paasta_tools.chronos_tools.load_chronos_job_config", autospec=True, return_value=self.fake_chronos_job_config, ), ) as ( mock_bounce_chronos_job, mock_lookup_chronos_jobs, mock_sort_jobs, load_system_paasta_config_patch, load_chronos_job_config_patch, ): load_system_paasta_config_patch.return_value.get_cluster.return_value = self.fake_cluster complete_config = chronos_tools.create_complete_config( service=self.fake_service, job_name=self.fake_instance, soa_dir=self.fake_args.soa_dir ) actual = setup_chronos_job.setup_job( service=self.fake_service, instance=self.fake_instance, complete_job_config=complete_config, client=self.fake_client, cluster=self.fake_cluster, ) mock_bounce_chronos_job.assert_called_once_with( service=self.fake_service, instance=self.fake_instance, cluster=self.fake_cluster, jobs_to_delete=[], jobs_to_disable=[fake_existing_job], job_to_create=complete_config, client=self.fake_client, ) assert mock_lookup_chronos_jobs.called assert actual == mock_bounce_chronos_job.return_value
def main(): configure_log() args = parse_args() soa_dir = args.soa_dir if args.verbose: log.setLevel(logging.DEBUG) else: log.setLevel(logging.WARNING) try: service, instance, _, __ = decompose_job_id(args.service_instance, spacer=chronos_tools.INTERNAL_SPACER) print 'service, instance' print service, instance except InvalidJobNameError: log.error("Invalid service instance '%s' specified. Format is service%sinstance." % (args.service_instance, SPACER)) sys.exit(1) client = chronos_tools.get_chronos_client(chronos_tools.load_chronos_config()) cluster = load_system_paasta_config().get_cluster() try: complete_job_config = chronos_tools.create_complete_config( service=service, job_name=instance, soa_dir=soa_dir, ) except (NoDeploymentsAvailable, NoDockerImageError): error_msg = "No deployment found for %s in cluster %s. Has Jenkins run for it?" % ( args.service_instance, cluster) send_event( service=service, instance=None, soa_dir=soa_dir, status=pysensu_yelp.Status.CRITICAL, output=error_msg, ) log.error(error_msg) sys.exit(0) except chronos_tools.UnknownChronosJobError as e: error_msg = ( "Could not read chronos configuration file for %s in cluster %s\n" % (args.service_instance, cluster) + "Error was: %s" % str(e)) send_event( service=service, instance=instance, soa_dir=soa_dir, status=pysensu_yelp.Status.CRITICAL, output=error_msg, ) log.error(error_msg) sys.exit(0) except chronos_tools.InvalidParentError: log.warn("Skipping %s.%s: Parent job could not be found" % (service, instance)) sys.exit(0) status, output = setup_job( service=service, instance=instance, cluster=cluster, complete_job_config=complete_job_config, client=client, ) sensu_status = pysensu_yelp.Status.CRITICAL if status else pysensu_yelp.Status.OK send_event( service=service, instance=instance, soa_dir=soa_dir, status=sensu_status, output=output, ) # We exit 0 because the script finished ok and the event was sent to the right team. sys.exit(0)
def main(): args = parse_args() soa_dir = args.soa_dir if args.verbose: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.WARNING) try: service, instance, _, __ = decompose_job_id( args.service_instance, spacer=chronos_tools.INTERNAL_SPACER) except InvalidJobNameError: log.error( "Invalid service instance '%s' specified. Format is service%sinstance." % (args.service_instance, SPACER)) sys.exit(1) client = chronos_tools.get_chronos_client( chronos_tools.load_chronos_config()) cluster = load_system_paasta_config().get_cluster() try: complete_job_config = chronos_tools.create_complete_config( service=service, job_name=instance, soa_dir=soa_dir, ) except (NoDeploymentsAvailable, NoDockerImageError): error_msg = "No deployment found for {} in cluster {}. Has Jenkins run for it?".format( args.service_instance, cluster, ) send_event( service=service, instance=instance, soa_dir=soa_dir, status=pysensu_yelp.Status.CRITICAL, output=error_msg, ) log.error(error_msg) sys.exit(0) except NoConfigurationForServiceError as e: error_msg = ( f"Could not read chronos configuration file for {args.service_instance} in cluster {cluster}\n" + "Error was: %s" % str(e)) send_event( service=service, instance=instance, soa_dir=soa_dir, status=pysensu_yelp.Status.CRITICAL, output=error_msg, ) log.error(error_msg) sys.exit(0) except NoSlavesAvailableError as e: error_msg = ( f"There are no PaaSTA slaves that can run {args.service_instance} in cluster {cluster}\n" + "Double check the cluster and the configured constraints/pool/whitelist.\n" "Error was: %s" % str(e)) send_event( service=service, instance=instance, soa_dir=soa_dir, status=pysensu_yelp.Status.CRITICAL, output=error_msg, ) log.error(error_msg) sys.exit(0) except chronos_tools.InvalidParentError: log.warn( f"Skipping {service}.{instance}: Parent job could not be found") sys.exit(0) modified_config = config_with_historical_stats( chronos_client=client, service=service, instance=instance, job_config=complete_job_config, ) status, output = setup_job( service=service, instance=instance, cluster=cluster, complete_job_config=modified_config, client=client, ) sensu_status = pysensu_yelp.Status.CRITICAL if status else pysensu_yelp.Status.OK send_event( service=service, instance=instance, soa_dir=soa_dir, status=sensu_status, output=output, ) # We exit 0 because the script finished ok and the event was sent to the right team. sys.exit(0)
def create_chronos_job_from_configs(context, instance, service): chronos_job_config = chronos_tools.create_complete_config(service, instance, context.soa_dir) context.chronos_job_config = chronos_job_config context.chronos_job_name = chronos_job_config['name']
def main(): configure_log() args = parse_args() soa_dir = args.soa_dir if args.verbose: log.setLevel(logging.DEBUG) else: log.setLevel(logging.WARNING) try: service, instance, _, __ = decompose_job_id(args.service_instance, spacer=chronos_tools.INTERNAL_SPACER) print 'service, instance' print service, instance except InvalidJobNameError: log.error("Invalid service instance '%s' specified. Format is service%sinstance." % (args.service_instance, SPACER)) sys.exit(1) client = chronos_tools.get_chronos_client(chronos_tools.load_chronos_config()) cluster = load_system_paasta_config().get_cluster() try: complete_job_config = chronos_tools.create_complete_config( service=service, job_name=instance, soa_dir=soa_dir, ) except (NoDeploymentsAvailable, NoDockerImageError): error_msg = "No deployment found for %s in cluster %s. Has Jenkins run for it?" % ( args.service_instance, cluster) send_event( service=service, instance=instance, soa_dir=soa_dir, status=pysensu_yelp.Status.CRITICAL, output=error_msg, ) log.error(error_msg) sys.exit(0) except chronos_tools.UnknownChronosJobError as e: error_msg = ( "Could not read chronos configuration file for %s in cluster %s\n" % (args.service_instance, cluster) + "Error was: %s" % str(e)) send_event( service=service, instance=instance, soa_dir=soa_dir, status=pysensu_yelp.Status.CRITICAL, output=error_msg, ) log.error(error_msg) sys.exit(0) except chronos_tools.InvalidParentError: log.warn("Skipping %s.%s: Parent job could not be found" % (service, instance)) sys.exit(0) status, output = setup_job( service=service, instance=instance, cluster=cluster, complete_job_config=complete_job_config, client=client, ) sensu_status = pysensu_yelp.Status.CRITICAL if status else pysensu_yelp.Status.OK send_event( service=service, instance=instance, soa_dir=soa_dir, status=sensu_status, output=output, ) # We exit 0 because the script finished ok and the event was sent to the right team. sys.exit(0)
def main(): args = parse_args() system_paasta_config = load_system_paasta_config() cluster = system_paasta_config.get_cluster() service, instance = chronos_tools.decompose_job_id(args.service_instance) config = chronos_tools.load_chronos_config() client = chronos_tools.get_chronos_client(config) related_jobs = chronos_tools.get_related_jobs_configs(cluster, service, instance, soa_dir=args.soa_dir) if not related_jobs: error_msg = "No deployment found for {} in cluster {}. Has Jenkins run for it?".format( args.service_instance, cluster, ) paasta_print(error_msg) raise NoDeploymentsAvailable if not args.run_all_related_jobs: # Strip all the configuration for the related services # those information will not be used by the rest of the flow related_jobs = { (service, instance): related_jobs[(service, instance)], } complete_job_configs = {} for (srv, inst) in related_jobs: try: complete_job_configs.update( { (srv, inst): chronos_tools.create_complete_config( service=srv, job_name=inst, soa_dir=args.soa_dir, ), }, ) except (NoDeploymentsAvailable, NoDockerImageError) as e: error_msg = "No deployment found for {} in cluster {}. Has Jenkins run for it?".format( chronos_tools.compose_job_id(srv, inst), cluster, ) paasta_print(error_msg) raise e except NoConfigurationForServiceError as e: error_msg = ( "Could not read chronos configuration file for {} in cluster {}\nError was: {}" .format( chronos_tools.compose_job_id(srv, inst), cluster, str(e), )) paasta_print(error_msg) raise e except chronos_tools.InvalidParentError as e: raise e if not args.run_all_related_jobs: sorted_jobs = [(service, instance)] else: sorted_jobs = chronos_tools.topological_sort_related_jobs( cluster, service, instance, soa_dir=args.soa_dir) timestamp = datetime.datetime.utcnow().isoformat() chronos_to_add = [] for (service, instance) in sorted_jobs: # complete_job_config is a formatted version of the job, # so the command is formatted in the context of 'now' # replace it with the 'original' cmd so it can be re rendered chronos_job_config = chronos_tools.load_chronos_job_config( service=service, instance=instance, cluster=cluster, soa_dir=args.soa_dir, ) original_command = chronos_job_config.get_cmd() complete_job_config = complete_job_configs[(service, instance)] complete_job_config['command'] = original_command clone = clone_job( chronos_job=complete_job_config, timestamp=timestamp, force_disabled=args.force_disabled, ) # modify the command to run commands for a given date clone = modify_command_for_date( chronos_job=clone, date=datetime.datetime.strptime(args.execution_date, "%Y-%m-%dT%H:%M:%S"), verbose=args.verbose, ) if not args.run_all_related_jobs and chronos_tools.get_job_type( clone) == chronos_tools.JobType.Dependent: # If the job is a dependent job and we want to re-run only the specific instance # remove the parents and update the schedule to start the job as soon as possible clone = set_default_schedule(remove_parents(clone)) chronos_to_add.append(clone) for job_to_add in chronos_to_add: client.add(job_to_add)
def perform_command(command, service, instance, cluster, verbose, soa_dir): """Performs a start/stop/restart/status on an instance :param command: String of start, stop, restart, status or scale :param service: service name :param instance: instance name, like "main" or "canary" :param cluster: cluster name :param verbose: int verbosity level :returns: A unix-style return code """ chronos_config = chronos_tools.load_chronos_config() client = chronos_tools.get_chronos_client(chronos_config) job_config = chronos_tools.load_chronos_job_config( service=service, instance=instance, cluster=cluster, soa_dir=soa_dir, ) complete_job_config = chronos_tools.create_complete_config(service, instance, soa_dir=soa_dir) job_id = complete_job_config["name"] if command == "start": start_chronos_job( service=service, instance=instance, job_id=job_id, client=client, cluster=cluster, job_config=job_config, complete_job_config=complete_job_config, emergency=True, ) elif command == "stop": matching_jobs = chronos_tools.lookup_chronos_jobs( service=service, instance=instance, client=client, include_disabled=True, include_temporary=True) stop_chronos_job(service, instance, client, cluster, matching_jobs, emergency=True) elif command == "restart": matching_jobs = chronos_tools.lookup_chronos_jobs( service=service, instance=instance, client=client, include_disabled=True, ) restart_chronos_job( service=service, instance=instance, job_id=job_id, client=client, cluster=cluster, matching_jobs=matching_jobs, job_config=job_config, complete_job_config=complete_job_config, emergency=True, ) elif command == "status": # Verbose mode shows previous versions. matching_jobs = chronos_tools.lookup_chronos_jobs( service=service, instance=instance, client=client, include_disabled=True, ) sorted_matching_jobs = chronos_tools.sort_jobs(matching_jobs) job_config = chronos_tools.load_chronos_job_config( service=service, instance=instance, cluster=cluster, soa_dir=soa_dir, ) paasta_print( status_chronos_jobs(client, sorted_matching_jobs, job_config, verbose)) else: # The command parser shouldn't have let us get this far... raise NotImplementedError("Command %s is not implemented!" % command) return 0
def perform_command(command, service, instance, cluster, verbose, soa_dir): """Performs a start/stop/restart/status on an instance :param command: String of start, stop, restart, status or scale :param service: service name :param instance: instance name, like "main" or "canary" :param cluster: cluster name :param verbose: int verbosity level :returns: A unix-style return code """ chronos_config = chronos_tools.load_chronos_config() client = chronos_tools.get_chronos_client(chronos_config) job_config = chronos_tools.load_chronos_job_config( service=service, instance=instance, cluster=cluster, soa_dir=soa_dir, ) complete_job_config = chronos_tools.create_complete_config(service, instance, soa_dir=soa_dir) job_id = complete_job_config["name"] if command == "start": start_chronos_job( service=service, instance=instance, job_id=job_id, client=client, cluster=cluster, job_config=job_config, complete_job_config=complete_job_config, emergency=True, ) elif command == "stop": matching_jobs = chronos_tools.lookup_chronos_jobs( service=service, instance=instance, client=client, include_disabled=True, include_temporary=True ) stop_chronos_job(service, instance, client, cluster, matching_jobs, emergency=True) elif command == "restart": matching_jobs = chronos_tools.lookup_chronos_jobs( service=service, instance=instance, client=client, include_disabled=True, ) restart_chronos_job( service=service, instance=instance, job_id=job_id, client=client, cluster=cluster, matching_jobs=matching_jobs, job_config=job_config, complete_job_config=complete_job_config, emergency=True, ) elif command == "status": # Verbose mode shows previous versions. matching_jobs = chronos_tools.lookup_chronos_jobs( service=service, instance=instance, client=client, include_disabled=True, ) sorted_matching_jobs = chronos_tools.sort_jobs(matching_jobs) job_config = chronos_tools.load_chronos_job_config( service=service, instance=instance, cluster=cluster, soa_dir=soa_dir, ) paasta_print(status_chronos_jobs(client, sorted_matching_jobs, job_config, verbose)) else: # The command parser shouldn't have let us get this far... raise NotImplementedError("Command %s is not implemented!" % command) return 0
def main(): configure_log() args = parse_args() soa_dir = args.soa_dir if args.verbose: log.setLevel(logging.DEBUG) else: log.setLevel(logging.WARNING) try: service, instance, _, __ = decompose_job_id(args.service_instance) except InvalidJobNameError: log.error("Invalid service instance '%s' specified. Format is service%sinstance." % (args.service_instance, SPACER)) sys.exit(1) client = chronos_tools.get_chronos_client(chronos_tools.load_chronos_config()) cluster = load_system_paasta_config().get_cluster() try: chronos_job_config = chronos_tools.load_chronos_job_config( service=service, instance=instance, cluster=cluster, soa_dir=soa_dir, ) except NoDeploymentsAvailable: error_msg = "No deployments found for %s in cluster %s" % (args.service_instance, cluster) send_event( service=service, instance=None, soa_dir=soa_dir, status=pysensu_yelp.Status.CRITICAL, output=error_msg, ) log.error(error_msg) # exit 0 because the event was sent to the right team and this is not an issue with Paasta itself sys.exit(0) except chronos_tools.InvalidChronosConfigError as e: error_msg = ( "Could not read chronos configuration file for %s in cluster %s\n" % (args.service_instance, cluster) + "Error was: %s" % str(e)) log.error(error_msg) send_event( service=service, instance=instance, soa_dir=soa_dir, status=pysensu_yelp.Status.CRITICAL, output=error_msg, ) # exit 0 because the event was sent to the right team and this is not an issue with Paasta itself sys.exit(0) complete_job_config = chronos_tools.create_complete_config( service=service, job_name=instance, soa_dir=soa_dir, ) status, output = setup_job( service=service, instance=instance, cluster=cluster, chronos_job_config=chronos_job_config, complete_job_config=complete_job_config, client=client, ) sensu_status = pysensu_yelp.Status.CRITICAL if status else pysensu_yelp.Status.OK send_event( service=service, instance=instance, soa_dir=soa_dir, status=sensu_status, output=output, ) # We exit 0 because the script finished ok and the event was sent to the right team. sys.exit(0)