def test_get_default_interactive_config_reads_from_tty(): with contextlib.nested( mock.patch('paasta_tools.adhoc_tools.prompt_pick_one', autospec=True), mock.patch('paasta_tools.adhoc_tools.load_adhoc_job_config', autospec=True), mock.patch('paasta_tools.adhoc_tools.load_v2_deployments_json', autospec=True), ) as ( mock_prompt_pick_one, mock_load_adhoc_job_config, mock_load_deployments_json, ): mock_prompt_pick_one.return_value = 'fake_deploygroup' mock_load_adhoc_job_config.side_effect = NoConfigurationForServiceError mock_load_deployments_json.return_value = DeploymentsJson({ 'deployments': { 'fake_deploygroup': { 'docker_image': mock.sentinel.docker_image, }, }, }) result = adhoc_tools.get_default_interactive_config( 'fake_serivce', 'fake_cluster', '/fake/soa/dir', load_deployments=True, ) assert result.get_deploy_group() == 'fake_deploygroup' assert result.get_docker_image() == mock.sentinel.docker_image
def test_get_default_interactive_config(): with contextlib.nested( mock.patch('paasta_tools.adhoc_tools.load_adhoc_job_config', autospec=True), ) as (mock_load_adhoc_job_config, ): mock_load_adhoc_job_config.return_value = adhoc_tools.AdhocJobConfig( service='fake_service', instance='interactive', cluster='fake_cluster', config_dict={}, branch_dict={'deploy_group': 'fake_deploy_group'}, ) result = adhoc_tools.get_default_interactive_config( 'fake_serivce', 'fake_cluster', '/fake/soa/dir', load_deployments=False, ) assert result.get_cpus() == 4 assert result.get_mem() == 10240 assert result.get_disk() == 1024
def test_get_default_interactive_config(): with contextlib.nested( mock.patch('paasta_tools.adhoc_tools.load_adhoc_job_config', autospec=True), ) as ( mock_load_adhoc_job_config, ): mock_load_adhoc_job_config.return_value = adhoc_tools.AdhocJobConfig( service='fake_service', instance='interactive', cluster='fake_cluster', config_dict={}, branch_dict={'deploy_group': 'fake_deploy_group'}, ) result = adhoc_tools.get_default_interactive_config( 'fake_serivce', 'fake_cluster', '/fake/soa/dir', load_deployments=False, ) assert result.get_cpus() == 4 assert result.get_mem() == 10240 assert result.get_disk() == 1024
def configure_and_run_docker_container( docker_client, docker_hash, service, instance, cluster, system_paasta_config, args, pull_image=False, dry_run=False ): """ Run Docker container by image hash with args set in command line. Function prints the output of run command in stdout. """ if instance is None and args.healthcheck_only: paasta_print( "With --healthcheck-only, --instance MUST be provided!", file=sys.stderr, ) return 1 if instance is None and not sys.stdin.isatty(): paasta_print( "--instance and --cluster must be specified when using paasta local-run without a tty!", file=sys.stderr, ) return 1 soa_dir = args.yelpsoa_config_root volumes = list() load_deployments = docker_hash is None or pull_image interactive = args.interactive try: if instance is None: instance_type = 'adhoc' instance = 'interactive' instance_config = get_default_interactive_config( service=service, cluster=cluster, soa_dir=soa_dir, load_deployments=load_deployments, ) interactive = True else: instance_type = validate_service_instance(service, instance, cluster, soa_dir) instance_config = get_instance_config( service=service, instance=instance, cluster=cluster, load_deployments=load_deployments, soa_dir=soa_dir, ) except NoConfigurationForServiceError as e: paasta_print(str(e), file=sys.stderr) return 1 except NoDeploymentsAvailable: paasta_print( PaastaColors.red( "Error: No deployments.json found in %(soa_dir)s/%(service)s." "You can generate this by running:" "generate_deployments_for_service -d %(soa_dir)s -s %(service)s" % { 'soa_dir': soa_dir, 'service': service, } ), sep='\n', file=sys.stderr, ) return 1 if docker_hash is None: try: docker_url = instance_config.get_docker_url() except NoDockerImageError: paasta_print(PaastaColors.red( "Error: No sha has been marked for deployment for the %s deploy group.\n" "Please ensure this service has either run through a jenkins pipeline " "or paasta mark-for-deployment has been run for %s\n" % (instance_config.get_deploy_group(), service)), sep='', file=sys.stderr, ) return 1 docker_hash = docker_url if pull_image: docker_pull_image(docker_url) # if only one volume specified, extra_volumes should be converted to a list extra_volumes = instance_config.get_extra_volumes() if type(extra_volumes) == dict: extra_volumes = [extra_volumes] for volume in system_paasta_config.get_volumes() + extra_volumes: volumes.append('%s:%s:%s' % (volume['hostPath'], volume['containerPath'], volume['mode'].lower())) if interactive is True and args.cmd is None: command = 'bash' elif args.cmd: command = args.cmd else: command_from_config = instance_config.get_cmd() if command_from_config: command_modifier = command_function_for_framework(instance_type) command = command_modifier(command_from_config) else: command = instance_config.get_args() return run_docker_container( docker_client=docker_client, service=service, instance=instance, docker_hash=docker_hash, volumes=volumes, interactive=interactive, command=command, healthcheck=args.healthcheck, healthcheck_only=args.healthcheck_only, user_port=args.user_port, instance_config=instance_config, soa_dir=args.yelpsoa_config_root, dry_run=dry_run, json_dict=args.dry_run_json_dict, framework=instance_type, )
def configure_and_run_docker_container( docker_client, docker_url, docker_sha, service, instance, cluster, system_paasta_config, args, pull_image=False, dry_run=False, ): """ Run Docker container by image hash with args set in command line. Function prints the output of run command in stdout. """ if instance is None and args.healthcheck_only: paasta_print( "With --healthcheck-only, --instance MUST be provided!", file=sys.stderr ) return 1 if instance is None and not sys.stdin.isatty(): paasta_print( "--instance and --cluster must be specified when using paasta local-run without a tty!", file=sys.stderr, ) return 1 soa_dir = args.yelpsoa_config_root volumes = list() load_deployments = (docker_url is None or pull_image) and not docker_sha interactive = args.interactive try: if instance is None: instance_type = "adhoc" instance = "interactive" instance_config = get_default_interactive_config( service=service, cluster=cluster, soa_dir=soa_dir, load_deployments=load_deployments, ) interactive = True else: instance_type = validate_service_instance( service, instance, cluster, soa_dir ) instance_config = get_instance_config( service=service, instance=instance, cluster=cluster, load_deployments=load_deployments, soa_dir=soa_dir, ) except NoConfigurationForServiceError as e: paasta_print(str(e), file=sys.stderr) return 1 except NoDeploymentsAvailable: paasta_print( PaastaColors.red( "Error: No deployments.json found in %(soa_dir)s/%(service)s. " "You can generate this by running: " "generate_deployments_for_service -d %(soa_dir)s -s %(service)s" % {"soa_dir": soa_dir, "service": service} ), sep="\n", file=sys.stderr, ) return 1 if docker_sha is not None: instance_config.branch_dict = { "git_sha": docker_sha, "docker_image": build_docker_image_name(service=service, sha=docker_sha), "desired_state": "start", "force_bounce": None, } if docker_url is None: try: docker_url = instance_config.get_docker_url() except NoDockerImageError: if instance_config.get_deploy_group() is None: paasta_print( PaastaColors.red( f"Error: {service}.{instance} has no 'deploy_group' set. Please set one so " "the proper image can be used to run for this service." ), sep="", file=sys.stderr, ) else: paasta_print( PaastaColors.red( "Error: No sha has been marked for deployment for the %s deploy group.\n" "Please ensure this service has either run through a jenkins pipeline " "or paasta mark-for-deployment has been run for %s\n" % (instance_config.get_deploy_group(), service) ), sep="", file=sys.stderr, ) return 1 if pull_image: docker_pull_image(docker_url) for volume in instance_config.get_volumes(system_paasta_config.get_volumes()): if os.path.exists(volume["hostPath"]): volumes.append( "{}:{}:{}".format( volume["hostPath"], volume["containerPath"], volume["mode"].lower() ) ) else: paasta_print( PaastaColors.yellow( "Warning: Path %s does not exist on this host. Skipping this binding." % volume["hostPath"] ), file=sys.stderr, ) if interactive is True and args.cmd is None: command = "bash" elif args.cmd: command = args.cmd else: command_from_config = instance_config.get_cmd() if command_from_config: command = format_command_for_type( command=command_from_config, instance_type=instance_type, date=args.date ) else: command = instance_config.get_args() secret_provider_kwargs = { "vault_cluster_config": system_paasta_config.get_vault_cluster_config(), "vault_auth_method": args.vault_auth_method, "vault_token_file": args.vault_token_file, } return run_docker_container( docker_client=docker_client, service=service, instance=instance, docker_url=docker_url, volumes=volumes, interactive=interactive, command=command, healthcheck=args.healthcheck, healthcheck_only=args.healthcheck_only, user_port=args.user_port, instance_config=instance_config, soa_dir=args.yelpsoa_config_root, dry_run=dry_run, json_dict=args.dry_run_json_dict, framework=instance_type, secret_provider_name=system_paasta_config.get_secret_provider_name(), secret_provider_kwargs=secret_provider_kwargs, skip_secrets=args.skip_secrets, )
def configure_and_run_docker_container(docker_client, docker_hash, service, instance, cluster, system_paasta_config, args, pull_image=False, dry_run=False): """ Run Docker container by image hash with args set in command line. Function prints the output of run command in stdout. """ soa_dir = args.yelpsoa_config_root volumes = list() load_deployments = docker_hash is None or pull_image interactive = args.interactive try: if instance is None: instance_type = 'adhoc' instance = 'interactive' instance_config = get_default_interactive_config(service=service, cluster=cluster, soa_dir=soa_dir) interactive = True else: instance_type = validate_service_instance(service, instance, cluster, soa_dir) instance_config = get_instance_config( service=service, instance=instance, cluster=cluster, load_deployments=load_deployments, soa_dir=soa_dir, ) except NoConfigurationForServiceError as e: sys.stderr.write(str(e) + '\n') return except NoDeploymentsAvailable: sys.stderr.write( PaastaColors.red( "Error: No deployments.json found in %(soa_dir)s/%(service)s.\n" "You can generate this by running:\n" "generate_deployments_for_service -d %(soa_dir)s -s %(service)s\n" % { 'soa_dir': soa_dir, 'service': service })) return if docker_hash is None: try: docker_url = get_docker_url( system_paasta_config.get_docker_registry(), instance_config.get_docker_image()) except NoDockerImageError: sys.stderr.write( PaastaColors.red( "Error: No sha has been marked for deployment for the %s deploy group.\n" "Please ensure this service has either run through a jenkins pipeline " "or paasta mark-for-deployment has been run for %s\n" % (instance_config.get_deploy_group(), service))) return docker_hash = docker_url if pull_image: docker_pull_image(docker_url) # if only one volume specified, extra_volumes should be converted to a list extra_volumes = instance_config.get_extra_volumes() if type(extra_volumes) == dict: extra_volumes = [extra_volumes] for volume in system_paasta_config.get_volumes() + extra_volumes: volumes.append('%s:%s:%s' % (volume['hostPath'], volume['containerPath'], volume['mode'].lower())) if interactive is True and args.cmd is None: command = ['bash'] elif args.cmd: command = shlex.split(args.cmd, posix=False) else: command_from_config = instance_config.get_cmd() if command_from_config: command_modifier = command_function_for_framework(instance_type) command = shlex.split(command_modifier(command_from_config), posix=False) else: command = instance_config.get_args() hostname = socket.getfqdn() run_docker_container( docker_client=docker_client, service=service, instance=instance, docker_hash=docker_hash, volumes=volumes, interactive=interactive, command=command, hostname=hostname, healthcheck=args.healthcheck, healthcheck_only=args.healthcheck_only, instance_config=instance_config, soa_dir=args.yelpsoa_config_root, dry_run=dry_run, json_dict=args.dry_run_json_dict, )
def configure_and_run_docker_container( docker_client, docker_hash, service, instance, cluster, system_paasta_config, args, pull_image=False, dry_run=False ): """ Run Docker container by image hash with args set in command line. Function prints the output of run command in stdout. """ soa_dir = args.yelpsoa_config_root volumes = list() load_deployments = docker_hash is None or pull_image interactive = args.interactive try: if instance is None and args.healthcheck: sys.stderr.write("With --healthcheck, --instance must be provided!\n") sys.exit(1) if instance is None: instance_type = 'adhoc' instance = 'interactive' instance_config = get_default_interactive_config( service=service, cluster=cluster, soa_dir=soa_dir, load_deployments=load_deployments, ) interactive = True else: instance_type = validate_service_instance(service, instance, cluster, soa_dir) instance_config = get_instance_config( service=service, instance=instance, cluster=cluster, load_deployments=load_deployments, soa_dir=soa_dir, ) except NoConfigurationForServiceError as e: sys.stderr.write(str(e) + '\n') return except NoDeploymentsAvailable: sys.stderr.write(PaastaColors.red( "Error: No deployments.json found in %(soa_dir)s/%(service)s.\n" "You can generate this by running:\n" "generate_deployments_for_service -d %(soa_dir)s -s %(service)s\n" % { 'soa_dir': soa_dir, 'service': service})) return if docker_hash is None: try: docker_url = get_docker_url( system_paasta_config.get_docker_registry(), instance_config.get_docker_image()) except NoDockerImageError: sys.stderr.write(PaastaColors.red( "Error: No sha has been marked for deployment for the %s deploy group.\n" "Please ensure this service has either run through a jenkins pipeline " "or paasta mark-for-deployment has been run for %s\n" % (instance_config.get_deploy_group(), service))) return docker_hash = docker_url if pull_image: docker_pull_image(docker_url) # if only one volume specified, extra_volumes should be converted to a list extra_volumes = instance_config.get_extra_volumes() if type(extra_volumes) == dict: extra_volumes = [extra_volumes] for volume in system_paasta_config.get_volumes() + extra_volumes: volumes.append('%s:%s:%s' % (volume['hostPath'], volume['containerPath'], volume['mode'].lower())) if interactive is True and args.cmd is None: command = ['bash'] elif args.cmd: command = shlex.split(args.cmd, posix=False) else: command_from_config = instance_config.get_cmd() if command_from_config: command_modifier = command_function_for_framework(instance_type) command = shlex.split(command_modifier(command_from_config), posix=False) else: command = instance_config.get_args() hostname = socket.getfqdn() run_docker_container( docker_client=docker_client, service=service, instance=instance, docker_hash=docker_hash, volumes=volumes, interactive=interactive, command=command, hostname=hostname, healthcheck=args.healthcheck, healthcheck_only=args.healthcheck_only, instance_config=instance_config, soa_dir=args.yelpsoa_config_root, dry_run=dry_run, json_dict=args.dry_run_json_dict, )