def test_without_project_path_default_exists_abort(runner, fake_git_remote): assert get_project_path() is None assert not os.system('mkdir {}'.format(default_project_path())) with mock.patch('deploy.settings.PROJECT_REMOTE', new=fake_git_remote): result = runner.invoke(dummy, input='1\nn\n') assert result.exit_code == exit_codes.ABORT assert get_project_path() is None
def test_without_project_path_default_exists_file(runner, fake_git_remote): assert get_project_path() is None assert not os.system('touch {}'.format(default_project_path())) with mock.patch('deploy.settings.PROJECT_REMOTE', new=fake_git_remote): result = runner.invoke(dummy, input='1\n\n') assert result.exit_code == exit_codes.SUCCESS assert get_project_path() == path_utils.canonical_path(default_project_path())
def test_without_project_path_default_normal(runner, fake_git_remote): assert get_project_path() is None with mock.patch('deploy.settings.PROJECT_REMOTE', new=fake_git_remote): result = runner.invoke(dummy, input='1\n') assert result.exit_code == exit_codes.SUCCESS assert get_project_path() == path_utils.canonical_path( default_project_path())
def test_without_project_path_default_exists_file(runner, fake_git_remote): assert get_project_path() is None assert not os.system('touch {}'.format(default_project_path())) with mock.patch('deploy.settings.PROJECT_REMOTE', new=fake_git_remote): result = runner.invoke(dummy, input='1\n\n') assert result.exit_code == exit_codes.SUCCESS assert get_project_path() == path_utils.canonical_path( default_project_path())
def update(name): """Update the main TigerHost server. This also updates the documentation. """ echo_heading('Retrieving server config.', marker='-', marker_color='magenta') project_path = get_project_path() database = store.get('main__database_url') secret = store.get('main__django_secret') addon_name = store.get('main__addon_name') if database is None or secret is None or addon_name is None: raise click.exceptions.ClickException( 'Server config not found. Was a TigerHost server created with `{} main create`?' .format(settings.APP_NAME)) click.echo('Done.') echo_heading('Making sure addon machine exists.', marker='-', marker_color='magenta') addon_docker_host = docker_machine.get_url(addon_name) click.echo('Done.') echo_heading('Copying addon machine credentials.', marker='-', marker_color='magenta') target_path = os.path.join(project_path, 'web/credentials') if not os.path.exists(target_path): os.mkdir(target_path) docker_machine.retrieve_credentials(addon_name, target_path) click.echo('Done.') echo_heading('Generating docker-compose file.', marker='-', marker_color='magenta') _generate_compose_file(project_path, database, addon_docker_host, secret) click.echo('Done.') echo_heading('Initializing TigerHost containers.', marker='-', marker_color='magenta') env_text = docker_machine.check_output(['env', name]) env = os.environ.copy() env.update(parse_shell_for_exports(env_text)) subprocess.check_call([ 'docker-compose', '-f', os.path.join(get_project_path(), 'docker-compose.prod.yml'), '-p', settings.MAIN_COMPOSE_PROJECT_NAME, 'build' ], env=env) subprocess.check_call([ 'docker-compose', '-f', os.path.join(get_project_path(), 'docker-compose.prod.yml'), '-p', settings.MAIN_COMPOSE_PROJECT_NAME, 'up', '-d' ], env=env)
def create(name, instance_type, database, addon_name, secret, elastic_ip_id): """Create a new machine for the main TigerHost server. The addon servers machine must already be created. """ project_path = get_project_path() # get url, ensures addon machine exists echo_heading('Making sure addon machine exists.', marker='-', marker_color='magenta') addon_docker_host = docker_machine.get_url(addon_name) click.echo('Done.') echo_heading('Copying addon machine credentials.', marker='-', marker_color='magenta') target_path = os.path.join(project_path, 'web/credentials') if not os.path.exists(target_path): os.mkdir(target_path) docker_machine.retrieve_credentials(addon_name, target_path) click.echo('Done.') echo_heading('Creating machine {name} with type {type}.'.format( name=name, type=instance_type), marker='-', marker_color='magenta') if settings.DEBUG: docker_machine.check_call(['create', '--driver', 'virtualbox', name]) else: docker_machine.check_call(['create', '--driver', 'amazonec2', '--amazonec2-instance-type', instance_type, name]) set_aws_security_group_ingress_rule( 'docker-machine', 0, 65535, '0.0.0.0/0') echo_heading( 'Associating Elastic IP.'.format(name), marker='-', marker_color='magenta') click.echo('Done.') new_ip = _associate_elastic_ip(name, elastic_ip_id) echo_heading( 'Saving IP {} to docker-machine.'.format(new_ip), marker='-', marker_color='magenta') _update_docker_machine_ip(name, new_ip) echo_heading('Generating docker-compose file.', marker='-', marker_color='magenta') _generate_compose_file(project_path, database, addon_docker_host, secret) click.echo('Done.') echo_heading('Initializing TigerHost containers.', marker='-', marker_color='magenta') env_text = docker_machine.check_output(['env', name]) env = os.environ.copy() env.update(parse_shell_for_exports(env_text)) subprocess.check_call(['docker-compose', '-f', os.path.join( get_project_path(), 'docker-compose.prod.yml'), '-p', settings.MAIN_COMPOSE_PROJECT_NAME, 'up', '-d'], env=env) store.set('main__database_url', database) store.set('main__django_secret', secret) store.set('main__addon_name', addon_name) store.set('main__elastic_ip_id', elastic_ip_id)
def create(stack): """Create a new Deis cluster. """ deisctl = path_utils.executable_path('deisctl') subprocess.check_call(['ssh-add', path_utils.ssh_path('deis')]) with contextmanagers.chdir(os.path.join(get_project_path(), 'deis')): subprocess.check_call(['make', 'discovery-url']) click.echo('Provisioning machines.') with contextmanagers.chdir('contrib/aws'): subprocess.check_call(['./provision-aws-cluster.sh', stack]) ec2 = boto3.resource('ec2') instances = ec2.instances.filter(Filters=[ { 'Name': 'instance-state-name', 'Values': ['running'], }, { 'Name': 'tag:aws:cloudformation:stack-name', 'Values': [stack], }, ]).limit(1) ip = None for i in instances: ip = i.public_ip_address assert ip is not None click.echo('Machines provisioned. An IP address is {}.'.format(ip)) env = {'DEISCTL_TUNNEL': ip} env.update(os.environ) click.echo('Installing Deis.') subprocess.check_call([ deisctl, 'config', 'platform', 'set', 'sshPrivateKey=' + path_utils.ssh_path('deis') ], env=env) subprocess.check_call([ deisctl, 'config', 'platform', 'set', 'domain=' + settings.DOMAIN_NAME ], env=env) subprocess.check_call([deisctl, 'refresh-units'], env=env) subprocess.check_call([deisctl, 'install', 'platform'], env=env) subprocess.check_call([deisctl, 'start', 'platform'], env=env)
def create(ctx, name, instance_type, database): """Create machine for the addon server. """ # TODO verify that database is [a-zA-Z0-9_] echo_heading('Creating machine {name} with type {type}.'.format( name=name, type=instance_type), marker='-', marker_color='magenta') if settings.DEBUG: docker_machine.check_call(['create', '--driver', 'virtualbox', name]) else: docker_machine.check_call([ 'create', '--driver', 'amazonec2', '--amazonec2-instance-type', instance_type, name ]) utils.set_aws_security_group_ingress_rule('docker-machine', 0, 65535, '0.0.0.0/0') project_path = get_project_path() echo_heading('Generating docker-compose file.', marker='-', marker_color='magenta') _generate_compose_file(project_path, database) echo_heading('Instantiating addons proxy.', marker='-', marker_color='magenta') env_text = docker_machine.check_output(['env', name]) env = os.environ.copy() env.update(utils.parse_shell_for_exports(env_text)) subprocess.check_call([ 'docker-compose', '-f', os.path.join(project_path, 'proxy/docker-compose.prod.yml'), '-p', settings.ADDONS_COMPOSE_PROJECT_NAME, 'up', '-d' ], env=env) store.set('addon__database_container_name', database)
def new_func(ctx, *args, **kwargs): """ :param click.Context ctx: """ if get_project_path() is None: click.echo('Config project_path not set.') click.echo('You can do one of the following:') choice = click_utils.prompt_choices([ 'Clone the repository to {}.'.format(default_project_path()), 'Specify the path to an existing repo.' ]) if choice == 0: path = default_project_path() if os.path.exists(path): click.confirm( 'Path {} already exists. Continuing will remove this path.' .format(path), default=True, abort=True) if os.path.isdir(path): shutil.rmtree(path) else: os.remove(path) click.echo('Cloning to {}...'.format(path), nl=False) clone_project() click.secho('Done', fg='black', bg='green') save_project_path(path) else: value = click.prompt('Please enter the path to your project', type=str) value = path_utils.canonical_path(value) if not os.path.exists(value) or not os.path.isdir(value): click.echo('This directory does not exist.') ctx.exit(code=exit_codes.OTHER_FAILURE) click.confirm('Is your project at {}?'.format(value), default=True, abort=True) save_project_path(value) return ctx.invoke(f, *args, **kwargs)
def update(name): """Update the addon server. """ echo_heading('Retrieving addons config.', marker='-', marker_color='magenta') database = store.get('addon__database_container_name', default=False) if database is False: raise click.exceptions.ClickException('Addons config not found. Was an addon server created with `{} addons create`?'.format(settings.APP_NAME)) click.echo('Done.') project_path = get_project_path() echo_heading('Generating docker-compose file.', marker='-', marker_color='magenta') _generate_compose_file(project_path, database) click.echo('Done.') echo_heading('Updating addons proxy.', marker='-', marker_color='magenta') env_text = docker_machine.check_output(['env', name]) env = os.environ.copy() env.update(utils.parse_shell_for_exports(env_text)) subprocess.check_call(['docker-compose', '-f', os.path.join( project_path, 'proxy/docker-compose.prod.yml'), '-p', settings.ADDONS_COMPOSE_PROJECT_NAME, 'build'], env=env) subprocess.check_call(['docker-compose', '-f', os.path.join( project_path, 'proxy/docker-compose.prod.yml'), '-p', settings.ADDONS_COMPOSE_PROJECT_NAME, 'up', '-d'], env=env)
def update(name): """Update the addon server. """ echo_heading('Retrieving addons config.', marker='-', marker_color='magenta') database = store.get('addon__database_container_name', default=False) if database is False: raise click.exceptions.ClickException( 'Addons config not found. Was an addon server created with `{} addons create`?' .format(settings.APP_NAME)) click.echo('Done.') project_path = get_project_path() echo_heading('Generating docker-compose file.', marker='-', marker_color='magenta') _generate_compose_file(project_path, database) click.echo('Done.') echo_heading('Updating addons proxy.', marker='-', marker_color='magenta') env_text = docker_machine.check_output(['env', name]) env = os.environ.copy() env.update(utils.parse_shell_for_exports(env_text)) subprocess.check_call([ 'docker-compose', '-f', os.path.join(project_path, 'proxy/docker-compose.prod.yml'), '-p', settings.ADDONS_COMPOSE_PROJECT_NAME, 'build' ], env=env) subprocess.check_call([ 'docker-compose', '-f', os.path.join(project_path, 'proxy/docker-compose.prod.yml'), '-p', settings.ADDONS_COMPOSE_PROJECT_NAME, 'up', '-d' ], env=env)
def test_without_project_path_default_normal(runner, fake_git_remote): assert get_project_path() is None with mock.patch('deploy.settings.PROJECT_REMOTE', new=fake_git_remote): result = runner.invoke(dummy, input='1\n') assert result.exit_code == exit_codes.SUCCESS assert get_project_path() == path_utils.canonical_path(default_project_path())
def test_without_project_path_normal(runner): assert get_project_path() is None result = runner.invoke(dummy, input='2\n.\n\n') assert result.exit_code == exit_codes.SUCCESS assert get_project_path() == path_utils.canonical_path('.')
def create(name, instance_type, database, addon_name, secret, elastic_ip_id): """Create a new machine for the main TigerHost server. The addon servers machine must already be created. """ project_path = get_project_path() # get url, ensures addon machine exists echo_heading('Making sure addon machine exists.', marker='-', marker_color='magenta') addon_docker_host = docker_machine.get_url(addon_name) click.echo('Done.') echo_heading('Copying addon machine credentials.', marker='-', marker_color='magenta') target_path = os.path.join(project_path, 'web/credentials') if not os.path.exists(target_path): os.mkdir(target_path) docker_machine.retrieve_credentials(addon_name, target_path) click.echo('Done.') echo_heading('Creating machine {name} with type {type}.'.format( name=name, type=instance_type), marker='-', marker_color='magenta') if settings.DEBUG: docker_machine.check_call(['create', '--driver', 'virtualbox', name]) else: docker_machine.check_call([ 'create', '--driver', 'amazonec2', '--amazonec2-instance-type', instance_type, name ]) set_aws_security_group_ingress_rule('docker-machine', 0, 65535, '0.0.0.0/0') echo_heading('Associating Elastic IP.'.format(name), marker='-', marker_color='magenta') click.echo('Done.') new_ip = _associate_elastic_ip(name, elastic_ip_id) echo_heading('Saving IP {} to docker-machine.'.format(new_ip), marker='-', marker_color='magenta') _update_docker_machine_ip(name, new_ip) echo_heading('Generating docker-compose file.', marker='-', marker_color='magenta') _generate_compose_file(project_path, database, addon_docker_host, secret) click.echo('Done.') echo_heading('Initializing TigerHost containers.', marker='-', marker_color='magenta') env_text = docker_machine.check_output(['env', name]) env = os.environ.copy() env.update(parse_shell_for_exports(env_text)) subprocess.check_call([ 'docker-compose', '-f', os.path.join(get_project_path(), 'docker-compose.prod.yml'), '-p', settings.MAIN_COMPOSE_PROJECT_NAME, 'up', '-d' ], env=env) store.set('main__database_url', database) store.set('main__django_secret', secret) store.set('main__addon_name', addon_name) store.set('main__elastic_ip_id', elastic_ip_id)
def test_project_path(): assert get_project_path() is None save_project_path('/test/../') assert get_project_path() == '/'
def test_path_already_exists(runner): assert get_project_path() is None save_project_path('.') result = runner.invoke(dummy) assert result.exit_code == exit_codes.SUCCESS assert get_project_path() == path_utils.canonical_path('.')
def test_without_project_path_not_confirmed(runner): assert get_project_path() is None result = runner.invoke(dummy, input='2\n.\nn\n') assert result.exit_code == exit_codes.ABORT assert get_project_path() is None
def test_without_project_path_nonexist(runner): assert get_project_path() is None result = runner.invoke(dummy, input='2\n/doesnotexist\n\n') assert result.exit_code == exit_codes.OTHER_FAILURE assert get_project_path() is None