def _pick_node(instance_list, node): instance_list = sorted(instance_list, key=lambda n: tags2dict(n.tags)['Name']) info = [n for n in instance_list] # def helpfn(pick): node = pick - 1 return "%s (%s, %s)" % (tags2dict(info[node].tags)['Name'], info[node].id, info[node].public_ip_address) num_instances = len(instance_list) if num_instances > 1: if not node: node = utils._pick('node', list(range(1, num_instances + 1)), helpfn=helpfn) node = int(node) - 1 instance = instance_list[int(node)] else: ensure( node == 1 or node is None, "You can't specify a node different from 1 for a single-instance stack" ) instance = instance_list[0] ensure( instance.public_ip_address, "Selected instance does not have a public ip address, are you sure it's running?" ) return instance
def fuzzy_find_and_play(self, video_filter): start = time.time() movies, tvshows = self._get_video_library() if 'mediaType' in video_filter and video_filter[ 'mediaType'] and video_filter['mediaType'] != 'movie': movie, movie_score = None, 0 else: movie, movie_score = get_best_match(video_filter, movies) logger.debug('Found Movie {} with score {}'.format( str(movie), movie_score)) if 'mediaType' in video_filter and video_filter[ 'mediaType'] and video_filter['mediaType'] != 'tv show': tvshow, tvshow_score = None, 0 else: tvshow, tvshow_score = get_best_match(video_filter, tvshows) logger.debug('Found TvShow {} with score {}'.format( str(tvshow), tvshow_score)) logger.debug('Find and play took {} ms'.format( int((time.time() - start) * 1000))) if movie and movie_score >= tvshow_score: async_play_movie(movie) elif tvshow: season, episode = _pick(video_filter, 'season', 'episode') async_play_tvshow(tvshow, season, episode) else: return False return True
def _check_want_to_be_running(stackname, autostart=False): try: context = context_handler.load_context(stackname) if 'ec2' in context: # early check can only be made if the instance actually declares # ec2 True/False in its context # otherwise, don't make assumptions and go ahead if not context['ec2']: return False except context_handler.MissingContextFile as e: LOG.warn(e) instance_list = core.find_ec2_instances(stackname, allow_empty=True) num_instances = len(instance_list) if num_instances >= 1: return instance_list if not autostart: should_start = utils._pick( 'should_start', [True, False], message='Stack not running. Should it be started?') if not should_start: return False core_lifecycle.start(stackname) # to get the ip addresses that are assigned to the now-running instances # and that weren't there before return core.find_ec2_instances(stackname)
def requires_aws_project_stack(*plist): if not plist: plist = [ utils._pick("project", project.project_list(), default_file=deffile('.project')) ] def wrap1(func): @wraps(func) def _wrapper(stackname=None, *args, **kwargs): region = aws.find_region(stackname) asl = core.active_stack_names(region) if not asl: print '\nno AWS stacks exist, cannot continue.' return def pname_startswith(stack): for pname in plist: if stack.startswith(pname): return stack asl = filter(pname_startswith, asl) if not stackname or stackname not in asl: stackname = utils._pick("stack", asl) return func(stackname, *args, **kwargs) return _wrapper return wrap1
def _check_want_to_be_running(stackname, autostart=False): try: context = context_handler.load_context(stackname) if not _are_there_existing_servers(context): return False except context_handler.MissingContextFile as e: LOG.warn(e) instance_list = core.find_ec2_instances(stackname, allow_empty=True) num_instances = len(instance_list) if num_instances >= 1: return instance_list if not autostart: should_start = utils._pick( 'should_start', [True, False], message='Stack not running. Should it be started?') if not should_start: return False core_lifecycle.start(stackname) # another call to get the ip addresses that are assigned to the now-running # instances and that weren't there before return core.find_ec2_instances(stackname)
def generate_stack_from_input(pname, instance_id=None): """creates a new CloudFormation file for the given project.""" if not instance_id: default_instance_id = core_utils.ymd() instance_id = utils.uin("instance id", default_instance_id) stackname = core.mk_stackname(pname, instance_id) more_context = {'stackname': stackname} # prompt user for alternate configurations pdata = project.project_data(pname) if 'aws-alt' in pdata: def helpfn(altkey): try: return pdata['aws-alt'][altkey]['description'] except KeyError: return None default = 'skip this step' alt_config = [default] + pdata['aws-alt'].keys() alt_config = utils._pick('alternative config', alt_config, helpfn=helpfn) if alt_config != default: more_context['alt-config'] = alt_config cfngen.generate_stack(pname, **more_context) return stackname
def wrap2(_pname=None, *args, **kwargs): pname = os.environ.get('PROJECT', _pname) project_list = project.filtered_projects(filterfn) if not pname or not pname.strip() or pname not in project_list: pname = utils._pick("project", sorted(project_list), default_file=deffile('.project')) return func(pname, *args, **kwargs)
def find_region(stackname=None): """tries to find the region, but falls back to user input if there are multiple regions available. Uses stackname, if provided, to filter the available regions""" try: return core.find_region(stackname) except MultipleRegionsError as e: print "many possible regions found!" return utils._pick('region', e.regions())
def wrap2(_pname=None, *args, **kwargs): pname = os.environ.get('PROJECT', _pname) # used by Vagrant ...? project_list = project.filtered_projects(filterfn) if not pname or not pname.strip() or pname not in project_list: # TODO: # if config.BUILDER_NON_INTERACTIVE: # print('project name not found or not provided and input is disabled, cannot continue.') # return pname = utils._pick("project", sorted(project_list), default_file=deffile('.project')) return func(pname, *args, **kwargs)
def call(*args, **kwargs): ss = core.steady_aws_stacks(utils.find_region()) keys = lmap(first, ss) idx = dict(zip(keys, ss)) helpfn = lambda pick: idx[pick][1] if not keys: print('\nno AWS stacks *in a steady state* exist, cannot continue.') return stackname = first(args) or os.environ.get('INSTANCE') if not stackname or stackname not in keys: stackname = utils._pick("stack", sorted(keys), helpfn=helpfn, default_file=deffile('.active-stack')) return func(stackname, *args[1:], **kwargs)
def call(*args, **kwargs): stackname = first(args) or os.environ.get('INSTANCE') region = aws.find_region(stackname) asl = core.active_stack_names(region) if not asl: raise RuntimeError( '\nno AWS stacks *in an active state* exist, cannot continue.') if not stackname or stackname not in asl: stackname = utils._pick("stack", asl, default_file=deffile('.active-stack')) args = args[1:] return func(stackname, *args, **kwargs)
def call(*args, **kwargs): stackname = first(args) or os.environ.get('INSTANCE') region = utils.find_region(stackname) if stackname: args = args[1:] return func(stackname, *args, **kwargs) asl = core.active_stack_names(region) if not asl: raise RuntimeError('\nno AWS stacks *in an active state* exist, cannot continue.') if not stackname or stackname not in asl: stackname = utils._pick("stack", asl, default_file=deffile('.active-stack')) args = args[1:] return func(stackname, *args, **kwargs)
def previous_item(self): if not self.current_item: return False if 'tvshowid' in self.current_item: tvshow_id, season, episode = _pick(self.current_item, 'tvshowid', 'season', 'episode') if tvshow_id and season and episode: previous_episode_id = get_previous_episode_id(tvshow_id, season, episode) if previous_episode_id: kodi_rpc.play_episodeid(previous_episode_id) return True return False
def _pick_node(instance_list, node): num_instances = len(instance_list) if num_instances > 1: if not node: node = utils._pick('node', range(1, num_instances + 1)) node = int(node) - 1 instance = instance_list[int(node)] else: instance = instance_list[0] core_utils.ensure( instance.ip_address is not None, "Selected instance does not have a public ip address, are you sure it's running?" ) return instance
def trgm_find_and_play(self, video_filter): entity = self.library_index.find_best_by_filter(video_filter) if not entity: return False if 'movieid' in entity: async_play_movie(movie) elif 'tvshowid' in entity: season, episode = _pick(video_filter, 'season', 'episode') async_play_tvshow(entity, season, episode) else: return False return True
def next_item(self): print('NEXT ITEM:', self.current_item) if not self.current_item: return False if 'tvshowid' in self.current_item: tvshow_id, season, episode = _pick(self.current_item, 'tvshowid', 'season', 'episode') if tvshow_id and season and episode: next_episode_id = get_next_episode_id(tvshow_id, season, episode) if next_episode_id: kodi_rpc.play_episodeid(next_episode_id) return True return False
def _wrapper(stackname=None, *args, **kwargs): region = utils.find_region(stackname) asl = core.active_stack_names(region) if not asl: print('\nno AWS stacks exist, cannot continue.') return def pname_startswith(stack): for pname in plist: if stack.startswith(pname): return stack asl = lfilter(pname_startswith, asl) if not stackname or stackname not in asl: stackname = utils._pick("stack", asl) return func(stackname, *args, **kwargs)
def call(*args, **kwargs): ss = core.steady_aws_stacks(aws.find_region()) keys = map(first, ss) idx = dict(zip(keys, ss)) helpfn = lambda pick: idx[pick][1] if not keys: print '\nno AWS stacks *in a steady state* exist, cannot continue.' return stackname = first(args) or os.environ.get('INSTANCE') if not stackname or stackname not in keys: stackname = utils._pick("stack", keys, helpfn=helpfn, default_file=deffile('.active-stack')) return func(stackname, *args[1:], **kwargs)
def _wrapper(stackname=None, *args, **kwargs): region = aws.find_region(stackname) asl = core.active_stack_names(region) if not asl: print '\nno AWS stacks exist, cannot continue.' return def pname_startswith(stack): for pname in plist: if stack.startswith(pname): return stack asl = filter(pname_startswith, asl) if not stackname or stackname not in asl: stackname = utils._pick("stack", asl) return func(stackname, *args, **kwargs)
def _check_want_to_be_running(stackname): instance_list = core.find_ec2_instances(stackname) num_instances = len(instance_list) if num_instances >= 1: return instance_list should_start = utils._pick( 'should_start', [True, False], message='Stack not running. Should it be started?') if not should_start: return False core_lifecycle.start(stackname) # to get the ip addresses that are assigned to the now-running instances # and that weren't there before return core.find_ec2_instances(stackname)
def generate_stack_from_input(pname, instance_id=None, alt_config=None): """creates a new CloudFormation file for the given project.""" instance_id = instance_id or utils.uin("instance id", core_utils.ymd()) stackname = core.mk_stackname(pname, instance_id) checks.ensure_stack_does_not_exist(stackname) more_context = {'stackname': stackname} pdata = project.project_data(pname) if alt_config: ensure( 'aws-alt' in pdata, "alternative configuration name given, but project has no alternate configurations" ) # prompt user for alternate configurations if pdata['aws-alt']: default = 'skip' def helpfn(altkey): if altkey == default: return 'uses the default configuration' try: return pdata['aws-alt'][altkey]['description'] except KeyError: return None if instance_id in pdata['aws-alt'].keys(): LOG.info( "instance-id found in known alternative configurations. using configuration %r", instance_id) more_context['alt-config'] = instance_id else: alt_config_choices = [default] + list(pdata['aws-alt'].keys()) if not alt_config: alt_config = utils._pick('alternative config', alt_config_choices, helpfn=helpfn) if alt_config != default: more_context['alt-config'] = alt_config # TODO: return the templates used here, so that they can be passed down to # bootstrap.create_stack() without relying on them implicitly existing # on the filesystem cfngen.generate_stack(pname, **more_context) return stackname
def next_item(self): logger.debug('Next item, current_item: {}'.format( str(self.current_item))) if not self.current_item: return False if 'tvshowid' in self.current_item: tvshow_id, season, episode = _pick(self.current_item, 'tvshowid', 'season', 'episode') if tvshow_id and season and episode: next_episode_id = get_next_episode_id(tvshow_id, season, episode) if next_episode_id: kodi_rpc.play_episodeid(next_episode_id) return True return False
def _pick_node(instance_list, node): instance_list = sorted(instance_list, key=lambda n: tags2dict(n.tags)['Name']) info = [n for n in instance_list] # def helpfn(pick): node = pick - 1 return "%s (%s, %s)" % (tags2dict(info[node].tags)['Name'], info[node].id, info[node].public_ip_address) num_instances = len(instance_list) if num_instances > 1: if not node: node = utils._pick('node', list(range(1, num_instances + 1)), helpfn=helpfn) node = int(node) - 1 instance = instance_list[int(node)] else: ensure(node == 1 or node is None, "You can't specify a node different from 1 for a single-instance stack") instance = instance_list[0] ensure(instance.public_ip_address, "Selected instance does not have a public ip address, are you sure it's running?") return instance
def deploy(pname, instance_id=None, branch='master', part_filter=None): pdata = project.project_data(pname) if not branch: branch_list = utils.git_remote_branches(pdata['repo']) branch_list = impose_ordering(branch_list) branch = utils._pick('branch', branch_list, deffile('.branch')) stackname = cfn.generate_stack_from_input(pname, instance_id) region = pdata['aws']['region'] active_stacks = core.active_stack_names(region) if stackname in active_stacks: LOG.info("stack %r exists, skipping creation", stackname) else: LOG.info("stack %r doesn't exist, creating", stackname) more_context = cfngen.choose_config(stackname) more_context['branch'] = branch cfngen.generate_stack(pname, **more_context) bootstrap.create_update(stackname, part_filter) setdefault('.active-stack', stackname)
def trgm_find_and_play(self, video_filter): entity = self.library_index.find_best_by_filter(video_filter) if not entity: return False if 'movieid' in entity: play_movie(entity) elif 'tvshowid' in entity: # season = video_filter.get('season') # if season: # season = int(season) # episode = video_filter.get('episode') # if episode: # episode = int(episode) season, episode = _pick(video_filter, 'season', 'episode') play_tvshow(entity, season, episode) else: return False return True
def create_stack(pname): """creates a new CloudFormation template for the given project.""" default_instance_id = core_utils.ymd() inst_id = utils.uin("instance id", default_instance_id) stackname = core.mk_stackname(pname, inst_id) more_context = {'instance_id': stackname} # prompt user for alternate configurations pdata = project.project_data(pname) if pdata.has_key('aws-alt'): def helpfn(altkey): try: return pdata['aws-alt'][altkey]['description'] except KeyError: return None default = 'skip this step' alt_config = [default] + pdata['aws-alt'].keys() alt_config = utils._pick('alternative config', alt_config, helpfn=helpfn) if alt_config != default: more_context['alt-config'] = alt_config cfngen.generate_stack(pname, **more_context) return stackname
def requires_aws_project_stack(*plist): if not plist: plist = [utils._pick("project", project.project_list(), default_file=deffile('.project'))] def wrap1(func): @wraps(func) def _wrapper(stackname=None, *args, **kwargs): region = utils.find_region(stackname) asl = core.active_stack_names(region) if not asl: print('\nno AWS stacks exist, cannot continue.') return def pname_startswith(stack): for pname in plist: if stack.startswith(pname): return stack asl = lfilter(pname_startswith, asl) if not stackname or stackname not in asl: stackname = utils._pick("stack", asl) return func(stackname, *args, **kwargs) return _wrapper return wrap1
def _check_want_to_be_running(stackname, autostart=False): try: context = context_handler.load_context(stackname) if not _are_there_existing_servers(context): return False except context_handler.MissingContextFile as e: LOG.warn(e) instance_list = core.find_ec2_instances(stackname, allow_empty=True) num_instances = len(instance_list) if num_instances >= 1: return instance_list if not autostart: should_start = utils._pick('should_start', [True, False], message='Stack not running. Should it be started?') if not should_start: return False core_lifecycle.start(stackname) # another call to get the ip addresses that are assigned to the now-running # instances and that weren't there before return core.find_ec2_instances(stackname)
def generate_stack_from_input(pname, instance_id=None, alt_config=None): """creates a new CloudFormation file for the given project.""" instance_id = instance_id or utils.uin("instance id", core_utils.ymd()) stackname = core.mk_stackname(pname, instance_id) checks.ensure_stack_does_not_exist(stackname) more_context = {'stackname': stackname} pdata = project.project_data(pname) if alt_config: ensure('aws-alt' in pdata, "alternative configuration name given, but project has no alternate configurations") # prompt user for alternate configurations if pdata['aws-alt']: default = 'skip' def helpfn(altkey): if altkey == default: return 'uses the default configuration' try: return pdata['aws-alt'][altkey]['description'] except KeyError: return None if instance_id in pdata['aws-alt'].keys(): LOG.info("instance-id found in known alternative configurations. using configuration %r", instance_id) more_context['alt-config'] = instance_id else: alt_config_choices = [default] + list(pdata['aws-alt'].keys()) if not alt_config: alt_config = utils._pick('alternative config', alt_config_choices, helpfn=helpfn) if alt_config != default: more_context['alt-config'] = alt_config # TODO: return the templates used here, so that they can be passed down to # bootstrap.create_stack() without relying on them implicitly existing # on the filesystem cfngen.generate_stack(pname, **more_context) return stackname
def _pick_node(instance_list, node): info = [n for n in instance_list] def helpfn(pick): node = pick - 1 return info[node] num_instances = len(instance_list) if num_instances > 1: if not node: # TODO print some more info: ip address, instance id node = utils._pick('node', range(1, num_instances + 1), helpfn=helpfn) node = int(node) - 1 instance = instance_list[int(node)] else: assert node == 1 or node is None, "You can't specify a node different from 1 for a single-instance stack" instance = instance_list[0] core_utils.ensure( instance.ip_address is not None, "Selected instance does not have a public ip address, are you sure it's running?" ) return instance
def fetch_cert(stackname): try: # replicates some logic in builder core pname = core.project_name_from_stackname(stackname) project_data = project.project_data(pname) assert project_data.has_key('subdomain'), "project subdomain not found. quitting" instance_id = stackname[len(pname + "-"):] is_prod = instance_id in ['master', 'production'] # we still have some instances that are the production/master # instances but don't adhere to the naming yet. old_prods = [ 'elife-ci-2015-11-04', 'elife-jira-2015-06-02' ] if not is_prod and stackname in old_prods: is_prod = True hostname_data = core.hostname_struct(stackname) domain_names = [hostname_data['full_hostname']] if is_prod: project_hostname = hostname_data['project_hostname'] if acme_enabled(project_hostname): domain_names.append(project_hostname) else: print '* project hostname (%s) doesnt appear to have letsencrypt enabled, ignore' % project_hostname print '\nthese hosts will be targeted:' print '* ' + '\n* '.join(domain_names) #pillar_data = cfngen.salt_pillar_data(config.PILLAR_DIR) #server = { # 'staging': pillar_data['sys']['webserver']['acme_staging_server'], # 'live': pillar_data['sys']['webserver']['acme_server'], #} server = { 'staging': "https://acme-staging.api.letsencrypt.org/directory", 'live': "https://acme-v01.api.letsencrypt.org/directory", } certtype = utils._pick("certificate type", ['staging', 'live']) cmds = [ "cd /opt/letsencrypt/", "./fetch-ssl-certs.sh -d %s --server %s" % (" -d ".join(domain_names), server[certtype]), "sudo service nginx reload", ] print print 'the following commands will be run:' print ' * ' + '\n * '.join(cmds) print if raw_input('enter to continue, ctrl-c to quit') == '': with stack_conn(stackname): return run(" && ".join(cmds)) except AssertionError, ex: print print "* " + str(ex) print exit(1)
def test_pick(self, get_input): value = utils._pick('project', ['lax', 'bot'], '/tmp/cache') self.assertEqual('lax', value)
def check_user_input(pname, instance_id=None, alt_config=None): "marshals user input and checks it for correctness" instance_id = instance_id or utils.uin("instance id", core_utils.ymd()) stackname = core.mk_stackname(pname, instance_id) pdata = project.project_data(pname) # alt-config given, die if it doesn't exist if alt_config: ensure( 'aws-alt' in pdata, "alt-config %r given, but project has no alternate configurations" % alt_config) # if the requested instance-id matches a known alt-config, we'll use that alt-config. warn user. if instance_id in pdata['aws-alt'].keys(): LOG.warn("instance-id %r found in alt-config list, using that.", instance_id) alt_config = instance_id # no alt-config given but alt-config options exist, prompt user if not alt_config and pdata['aws-alt']: default_choice = 'skip' def helpfn(altkey): if altkey == default_choice: return 'uses the default configuration' try: return pdata['aws-alt'][altkey]['description'] except KeyError: return None alt_config_choice_list = [default_choice] + list( pdata['aws-alt'].keys()) alt_config_choice = utils._pick('alternative config', alt_config_choice_list, helpfn=helpfn) if alt_config_choice != default_choice: alt_config = alt_config_choice # check the alt-config isn't unique and if it *is* unique, that an instance using it doesn't exist yet. # note: it is *technically* possible that an instance is using a unique configuration but # that its instance-id *is not* the name of the alt-config passed in. # For example, if `journal--prod` didn't exist, I could create `journal--foo` using the `prod` config. if alt_config and alt_config in pdata['aws-alt'] and pdata['aws-alt'][ alt_config]['unique']: dealbreaker = core.mk_stackname(pname, alt_config) # "project 'journal' config 'prod' is marked as unique!" # "checking for any instance named 'journal--prod' ..." print("project %r config %r is marked as unique!" % (pname, alt_config)) print("checking for any instance named %r ..." % (dealbreaker, )) try: checks.ensure_stack_does_not_exist(dealbreaker) except checks.StackAlreadyExistsProblem: # "stack 'journal--prod' exists, cannot re-use unique configuration 'prod'" msg = "stack %r exists, cannot re-use unique configuration %r." % ( dealbreaker, alt_config) raise TaskExit(msg) # check that the instance we want to create doesn't exist try: print("checking %r doesn't exist." % stackname) checks.ensure_stack_does_not_exist(stackname) except checks.StackAlreadyExistsProblem as e: msg = 'stack %r already exists.' % e.stackname raise TaskExit(msg) more_context = {'stackname': stackname} if alt_config: more_context['alt-config'] = alt_config return more_context
def fetch_cert(stackname): # NOTE: this was ported from the old builder and won't work with new instances # this isn't a problem because new instances shouldn't be using letsencrypt if # they can avoid it. try: # replicates some logic in builder core pname = core.project_name_from_stackname(stackname) project_data = project.project_data(pname) assert 'subdomain' in project_data, "project subdomain not found. quitting" instance_id = stackname[len(pname + "-"):] is_prod = instance_id in ['master', 'production'] # we still have some instances that are the production/master # instances but don't adhere to the naming yet. old_prods = [ 'elife-ci-2015-11-04', ] if not is_prod and stackname in old_prods: is_prod = True hostname_data = core.hostname_struct(stackname) domain_names = [hostname_data['full_hostname']] if is_prod: project_hostname = hostname_data['project_hostname'] if acme_enabled(project_hostname): domain_names.append(project_hostname) else: print '* project hostname (%s) doesnt appear to have letsencrypt enabled, ignore' % project_hostname print '\nthese hosts will be targeted:' print '* ' + '\n* '.join(domain_names) #pillar_data = cfngen.salt_pillar_data(config.PILLAR_DIR) # server = { # 'staging': pillar_data['sys']['webserver']['acme_staging_server'], # 'live': pillar_data['sys']['webserver']['acme_server'], #} server = { 'staging': "https://acme-staging.api.letsencrypt.org/directory", 'live': "https://acme-v01.api.letsencrypt.org/directory", } certtype = utils._pick("certificate type", ['staging', 'live']) cmds = [ "cd /opt/letsencrypt/", "./fetch-ssl-certs.sh -d %s --server %s" % (" -d ".join(domain_names), server[certtype]), "sudo service nginx reload", ] print print 'the following commands will be run:' print ' * ' + '\n * '.join(cmds) print if raw_input('enter to continue, ctrl-c to quit') == '': with stack_conn(stackname): return run(" && ".join(cmds)) except AssertionError as ex: print print "* " + str(ex) print exit(1)