diff options
| author | Kenny Woodson <kwoodson@redhat.com> | 2015-10-29 11:14:51 -0400 | 
|---|---|---|
| committer | Kenny Woodson <kwoodson@redhat.com> | 2015-10-29 11:14:51 -0400 | 
| commit | 9bbaa824da5e1a049cdec1a6523c3841d713386c (patch) | |
| tree | 93e80f1577ad0f2f5f8931b493c50cd9aa657c77 /bin | |
| parent | 15df494fb781dd1509854eeb366e981930b52c22 (diff) | |
| parent | 16d1bce0be2f8c3942489630adcb7030aecadc55 (diff) | |
| download | openshift-9bbaa824da5e1a049cdec1a6523c3841d713386c.tar.gz openshift-9bbaa824da5e1a049cdec1a6523c3841d713386c.tar.bz2 openshift-9bbaa824da5e1a049cdec1a6523c3841d713386c.tar.xz openshift-9bbaa824da5e1a049cdec1a6523c3841d713386c.zip | |
Merge pull request #763 from openshift/master
Merge master into prod.
Diffstat (limited to 'bin')
| -rwxr-xr-x | bin/cluster | 97 | ||||
| -rwxr-xr-x | bin/ohi | 2 | ||||
| -rw-r--r-- | bin/openshift-ansible-bin.spec | 104 | ||||
| l--------- | bin/openshift_ansible/aws | 1 | ||||
| -rwxr-xr-x | bin/oscp | 6 | ||||
| -rwxr-xr-x | bin/ossh | 6 | ||||
| -rwxr-xr-x | bin/ossh_bash_completion | 21 | ||||
| -rw-r--r-- | bin/ossh_zsh_completion | 13 | 
8 files changed, 109 insertions, 141 deletions
| diff --git a/bin/cluster b/bin/cluster index 2ea389523..59a6755d3 100755 --- a/bin/cluster +++ b/bin/cluster @@ -3,8 +3,10 @@  import argparse  import ConfigParser -import sys  import os +import sys +import subprocess +import traceback  class Cluster(object): @@ -22,6 +24,16 @@ class Cluster(object):                  '-o ControlMaster=auto '                  '-o ControlPersist=600s '              ) +            # Because of `UserKnownHostsFile=/dev/null` +            # our `.ssh/known_hosts` file most probably misses the ssh host public keys +            # of our servers. +            # In that case, ansible serializes the execution of ansible modules +            # because we might be interactively prompted to accept the ssh host public keys. +            # Because of `StrictHostKeyChecking=no` we know that we won't be prompted +            # So, we don't want our modules execution to be serialized. +            os.environ['ANSIBLE_HOST_KEY_CHECKING'] = 'False' +            # TODO: A more secure way to proceed would consist in dynamically +            # retrieving the ssh host public keys from the IaaS interface      def get_deployment_type(self, args):          """ @@ -37,11 +49,11 @@ class Cluster(object):              deployment_type = os.environ['OS_DEPLOYMENT_TYPE']          return deployment_type +      def create(self, args):          """          Create an OpenShift cluster for given provider          :param args: command line arguments provided by user -        :return: exit status from run command          """          env = {'cluster_id': args.cluster_id,                 'deployment_type': self.get_deployment_type(args)} @@ -50,66 +62,63 @@ class Cluster(object):          env['num_masters'] = args.masters          env['num_nodes'] = args.nodes +        env['num_infra'] = args.infra +        env['num_etcd'] = args.etcd -        return self.action(args, inventory, env, playbook) +        self.action(args, inventory, env, playbook)      def terminate(self, args):          """          Destroy OpenShift cluster          :param args: command line arguments provided by user -        :return: exit status from run command          """          env = {'cluster_id': args.cluster_id,                 'deployment_type': self.get_deployment_type(args)}          playbook = "playbooks/{}/openshift-cluster/terminate.yml".format(args.provider)          inventory = self.setup_provider(args.provider) -        return self.action(args, inventory, env, playbook) +        self.action(args, inventory, env, playbook)      def list(self, args):          """          List VMs in cluster          :param args: command line arguments provided by user -        :return: exit status from run command          """          env = {'cluster_id': args.cluster_id,                 'deployment_type': self.get_deployment_type(args)}          playbook = "playbooks/{}/openshift-cluster/list.yml".format(args.provider)          inventory = self.setup_provider(args.provider) -        return self.action(args, inventory, env, playbook) +        self.action(args, inventory, env, playbook)      def config(self, args):          """          Configure or reconfigure OpenShift across clustered VMs          :param args: command line arguments provided by user -        :return: exit status from run command          """          env = {'cluster_id': args.cluster_id,                 'deployment_type': self.get_deployment_type(args)}          playbook = "playbooks/{}/openshift-cluster/config.yml".format(args.provider)          inventory = self.setup_provider(args.provider) -        return self.action(args, inventory, env, playbook) +        self.action(args, inventory, env, playbook)      def update(self, args):          """          Update to latest OpenShift across clustered VMs          :param args: command line arguments provided by user -        :return: exit status from run command          """          env = {'cluster_id': args.cluster_id,                 'deployment_type': self.get_deployment_type(args)}          playbook = "playbooks/{}/openshift-cluster/update.yml".format(args.provider)          inventory = self.setup_provider(args.provider) -        return self.action(args, inventory, env, playbook) +        self.action(args, inventory, env, playbook)      def service(self, args):          """          Make the same service call across all nodes in the cluster          :param args: command line arguments provided by user -        :return: exit status from run command          """          env = {'cluster_id': args.cluster_id,                 'deployment_type': self.get_deployment_type(args), @@ -118,7 +127,7 @@ class Cluster(object):          playbook = "playbooks/{}/openshift-cluster/service.yml".format(args.provider)          inventory = self.setup_provider(args.provider) -        return self.action(args, inventory, env, playbook) +        self.action(args, inventory, env, playbook)      def setup_provider(self, provider):          """ @@ -128,10 +137,14 @@ class Cluster(object):          """          config = ConfigParser.ConfigParser()          if 'gce' == provider: -            config.readfp(open('inventory/gce/hosts/gce.ini')) +            gce_ini_default_path = os.path.join( +                'inventory/gce/hosts/gce.ini') +            gce_ini_path = os.environ.get('GCE_INI_PATH', gce_ini_default_path) +            if os.path.exists(gce_ini_path):  +                config.readfp(open(gce_ini_path)) -            for key in config.options('gce'): -                os.environ[key] = config.get('gce', key) +                for key in config.options('gce'): +                    os.environ[key] = config.get('gce', key)              inventory = '-i inventory/gce/hosts'          elif 'aws' == provider: @@ -141,6 +154,17 @@ class Cluster(object):                  os.environ[key] = config.get('ec2', key)              inventory = '-i inventory/aws/hosts' + +            key_vars = ['AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY'] +            key_missing = [key for key in key_vars if key not in os.environ] + +            boto_conf_files = ['~/.aws/credentials', '~/.boto'] +            conf_exists = lambda conf: os.path.isfile(os.path.expanduser(conf)) +            boto_configs = [conf for conf in boto_conf_files if conf_exists(conf)] + +            if len(key_missing) > 0 and len(boto_configs) == 0: +                raise ValueError("PROVIDER aws requires {} environment variable(s). See README_AWS.md".format(key_missing)) +          elif 'libvirt' == provider:              inventory = '-i inventory/libvirt/hosts'          elif 'openstack' == provider: @@ -158,7 +182,6 @@ class Cluster(object):          :param inventory: derived provider library          :param env: environment variables for kubernetes          :param playbook: ansible playbook to execute -        :return: exit status from ansible-playbook command          """          verbose = '' @@ -168,7 +191,7 @@ class Cluster(object):          if args.option:              for opt in args.option:                  k, v = opt.split('=', 1) -                env['opt_'+k] = v +                env['cli_' + k] = v          ansible_env = '-e \'{}\''.format(              ' '.join(['%s=%s' % (key, value) for (key, value) in env.items()]) @@ -178,6 +201,9 @@ class Cluster(object):              verbose, inventory, ansible_env, playbook          ) +        if args.profile: +            command = 'ANSIBLE_CALLBACK_PLUGINS=ansible-profile/callback_plugins ' + command +          if args.verbose > 1:              command = 'time {}'.format(command) @@ -185,7 +211,18 @@ class Cluster(object):              sys.stderr.write('RUN [{}]\n'.format(command))              sys.stderr.flush() -        return os.system(command) +        try: +            subprocess.check_call(command, shell=True) +        except subprocess.CalledProcessError as exc: +            raise ActionFailed("ACTION [{}] failed: {}" +                               .format(args.action, exc)) + + +class ActionFailed(Exception): +    """ +    Raised when action failed. +    """ +    pass  if __name__ == '__main__': @@ -231,9 +268,15 @@ if __name__ == '__main__':      meta_parser.add_argument('-t', '--deployment-type',                               choices=['origin', 'online', 'enterprise'],                               help='Deployment type. (default: origin)') +    meta_parser.add_argument('-T', '--product-type', +                             choices=['openshift', 'atomic-enterprise'], +                             help='Product type. (default: openshift)')      meta_parser.add_argument('-o', '--option', action='append',                               help='options') +    meta_parser.add_argument('-p', '--profile', action='store_true', +                             help='Enable playbook profiling') +      action_parser = parser.add_subparsers(dest='action', title='actions',                                            description='Choose from valid actions') @@ -243,6 +286,10 @@ if __name__ == '__main__':                                 help='number of masters to create in cluster')      create_parser.add_argument('-n', '--nodes', default=2, type=int,                                 help='number of nodes to create in cluster') +    create_parser.add_argument('-i', '--infra', default=1, type=int, +                               help='number of infra nodes to create in cluster') +    create_parser.add_argument('-e', '--etcd', default=0, type=int, +                               help='number of external etcd hosts to create in cluster')      create_parser.set_defaults(func=cluster.create)      config_parser = action_parser.add_parser('config', @@ -290,7 +337,11 @@ if __name__ == '__main__':              sys.stderr.write('\nACTION [update] aborted by user!\n')              exit(1) -    status = args.func(args) -    if status != 0: -        sys.stderr.write("ACTION [{}] failed with exit status {}\n".format(args.action, status)) -    exit(status) +    try: +        args.func(args) +    except Exception as exc: +        if args.verbose: +            traceback.print_exc(file=sys.stderr) +        else: +            print >>sys.stderr, exc +        exit(1) @@ -83,7 +83,7 @@ class Ohi(object):          """Setup the command line parser with the options we want          """ -        parser = argparse.ArgumentParser(description='Openshift Host Inventory') +        parser = argparse.ArgumentParser(description='OpenShift Host Inventory')          parser.add_argument('--list-host-types', default=False, action='store_true',                         help='List all of the host types') diff --git a/bin/openshift-ansible-bin.spec b/bin/openshift-ansible-bin.spec deleted file mode 100644 index fd2386c9a..000000000 --- a/bin/openshift-ansible-bin.spec +++ /dev/null @@ -1,104 +0,0 @@ -Summary:       OpenShift Ansible Scripts for working with metadata hosts -Name:          openshift-ansible-bin -Version:       0.0.18 -Release:       1%{?dist} -License:       ASL 2.0 -URL:           https://github.com/openshift/openshift-ansible -Source0:       %{name}-%{version}.tar.gz -Requires:      python2, openshift-ansible-inventory -BuildRequires: python2-devel -BuildArch:     noarch - -%description -Scripts to make it nicer when working with hosts that are defined only by metadata. - -%prep -%setup -q - -%build - -%install -mkdir -p %{buildroot}%{_bindir} -mkdir -p %{buildroot}%{python_sitelib}/openshift_ansible -mkdir -p %{buildroot}/etc/bash_completion.d -mkdir -p %{buildroot}/etc/openshift_ansible - -cp -p ossh oscp opssh opscp ohi %{buildroot}%{_bindir} -cp -pP openshift_ansible/* %{buildroot}%{python_sitelib}/openshift_ansible - -# Make it so we can load multi_ec2.py as a library. -rm %{buildroot}%{python_sitelib}/openshift_ansible/multi_ec2.py* -ln -sf /usr/share/ansible/inventory/multi_ec2.py %{buildroot}%{python_sitelib}/openshift_ansible/multi_ec2.py -ln -sf /usr/share/ansible/inventory/multi_ec2.pyc %{buildroot}%{python_sitelib}/openshift_ansible/multi_ec2.pyc - -cp -p ossh_bash_completion %{buildroot}/etc/bash_completion.d - -cp -p openshift_ansible.conf.example %{buildroot}/etc/openshift_ansible/openshift_ansible.conf - -%files -%{_bindir}/* -%{python_sitelib}/openshift_ansible/ -/etc/bash_completion.d/* -%config(noreplace) /etc/openshift_ansible/ - -%changelog -* Tue Jun 09 2015 Kenny Woodson <kwoodson@redhat.com> 0.0.18-1 -- Implement OpenStack provider (lhuard@amadeus.com) -- * Update defaults and examples to track core concepts guide -  (jhonce@redhat.com) -- Issue 119 - Add support for ~/.openshift-ansible (jhonce@redhat.com) -- Infrastructure - Add service action to bin/cluster (jhonce@redhat.com) - -* Fri May 15 2015 Thomas Wiest <twiest@redhat.com> 0.0.17-1 -- fixed the openshift-ansible-bin build (twiest@redhat.com) - -* Fri May 15 2015 Thomas Wiest <twiest@redhat.com> 0.0.14-1 -- Command line tools import multi_ec2 as lib (kwoodson@redhat.com) -- Adding cache location for multi ec2 (kwoodson@redhat.com) -* Thu May 07 2015 Thomas Wiest <twiest@redhat.com> 0.0.13-1 -- added '-e all' to ohi and fixed pylint errors. (twiest@redhat.com) - -* Tue May 05 2015 Thomas Wiest <twiest@redhat.com> 0.0.12-1 -- fixed opssh and opscp to allow just environment or just host-type. -  (twiest@redhat.com) - -* Mon May 04 2015 Thomas Wiest <twiest@redhat.com> 0.0.11-1 -- changed opssh to a bash script using ohi to make it easier to maintain, and -  to expose all of the pssh features directly. (twiest@redhat.com) -- Added --user option to ohi to pre-pend the username in the hostlist output. -  (twiest@redhat.com) -- Added utils.py that contains a normalize_dnsname function good for sorting -  dns names to a human readable list. (twiest@redhat.com) - -* Thu Apr 30 2015 Thomas Wiest <twiest@redhat.com> 0.0.10-1 -- added --list-host-types option to opscp (twiest@redhat.com) - -* Thu Apr 30 2015 Thomas Wiest <twiest@redhat.com> 0.0.9-1 -- added opscp (twiest@redhat.com) -* Mon Apr 13 2015 Thomas Wiest <twiest@redhat.com> 0.0.8-1 -- fixed bug in opssh where it wouldn't actually run pssh (twiest@redhat.com) - -* Mon Apr 13 2015 Thomas Wiest <twiest@redhat.com> 0.0.7-1 -- added the ability to run opssh and ohi on all hosts in an environment, as -  well as all hosts of the same host-type regardless of environment -  (twiest@redhat.com) -- added ohi (twiest@redhat.com) -* Thu Apr 09 2015 Thomas Wiest <twiest@redhat.com> 0.0.6-1 -- fixed bug where opssh would throw an exception if pssh returned a non-zero -  exit code (twiest@redhat.com) - -* Wed Apr 08 2015 Thomas Wiest <twiest@redhat.com> 0.0.5-1 -- fixed the opssh default output behavior to be consistent with pssh. Also -  fixed a bug in how directories are named for --outdir and --errdir. -  (twiest@redhat.com) -* Tue Mar 31 2015 Thomas Wiest <twiest@redhat.com> 0.0.4-1 -- Fixed when tag was missing and added opssh completion (kwoodson@redhat.com) - -* Mon Mar 30 2015 Thomas Wiest <twiest@redhat.com> 0.0.3-1 -- created a python package named openshift_ansible (twiest@redhat.com) - -* Mon Mar 30 2015 Thomas Wiest <twiest@redhat.com> 0.0.2-1 -- added config file support to opssh, ossh, and oscp (twiest@redhat.com) -* Tue Mar 24 2015 Thomas Wiest <twiest@redhat.com> 0.0.1-1 -- new package built with tito - diff --git a/bin/openshift_ansible/aws b/bin/openshift_ansible/aws new file mode 120000 index 000000000..eb0575b4d --- /dev/null +++ b/bin/openshift_ansible/aws @@ -0,0 +1 @@ +../../inventory/aws/
\ No newline at end of file @@ -55,7 +55,7 @@ class Oscp(object):              config.read(self.config_path)      def parse_cli_args(self): -        parser = argparse.ArgumentParser(description='Openshift Online SSH Tool.') +        parser = argparse.ArgumentParser(description='OpenShift Online SSH Tool.')          parser.add_argument('-e', '--env',                            action="store", help="Environment where this server exists.")          parser.add_argument('-d', '--debug', default=False, @@ -167,7 +167,7 @@ class Oscp(object):                      name = server_info['ec2_tag_Name']                      ec2_id = server_info['ec2_id']                      ip = server_info['ec2_ip_address'] -                    print '{ec2_tag_Name:<35} {ec2_tag_environment:<8} {ec2_id:<15} {ec2_ip_address}'.format(**server_info) +                    print '{ec2_tag_Name:<35} {ec2_tag_environment:<8} {ec2_id:<15} {ec2_ip_address:<18} {ec2_private_ip_address}'.format(**server_info)                  if limit:                      print @@ -180,7 +180,7 @@ class Oscp(object):                      name = server_info['ec2_tag_Name']                      ec2_id = server_info['ec2_id']                      ip = server_info['ec2_ip_address'] -                    print '{ec2_tag_Name:<35} {ec2_tag_environment:<5} {ec2_id:<15} {ec2_ip_address}'.format(**server_info) +                    print '{ec2_tag_Name:<35} {ec2_tag_environment:<8} {ec2_id:<15} {ec2_ip_address:<18} {ec2_private_ip_address}'.format(**server_info)      def scp(self):          '''scp files to or from a specified host @@ -53,7 +53,7 @@ class Ossh(object):              config.read(self.config_path)      def parse_cli_args(self): -        parser = argparse.ArgumentParser(description='Openshift Online SSH Tool.') +        parser = argparse.ArgumentParser(description='OpenShift Online SSH Tool.')          parser.add_argument('-e', '--env', action="store",                            help="Which environment to search for the host ")          parser.add_argument('-d', '--debug', default=False, @@ -156,7 +156,7 @@ class Ossh(object):                      name = server_info['ec2_tag_Name']                      ec2_id = server_info['ec2_id']                      ip = server_info['ec2_ip_address'] -                    print '{ec2_tag_Name:<35} {ec2_tag_environment:<8} {ec2_id:<15} {ec2_ip_address}'.format(**server_info) +                    print '{ec2_tag_Name:<35} {ec2_tag_environment:<8} {ec2_id:<15} {ec2_ip_address:<18} {ec2_private_ip_address}'.format(**server_info)                  if limit:                      print @@ -169,7 +169,7 @@ class Ossh(object):                      name = server_info['ec2_tag_Name']                      ec2_id = server_info['ec2_id']                      ip = server_info['ec2_ip_address'] -                    print '{ec2_tag_Name:<35} {ec2_tag_environment:<5} {ec2_id:<15} {ec2_ip_address}'.format(**server_info) +                    print '{ec2_tag_Name:<35} {ec2_tag_environment:<8} {ec2_id:<15} {ec2_ip_address:<18} {ec2_private_ip_address}'.format(**server_info)      def ssh(self):          '''SSH to a specified host diff --git a/bin/ossh_bash_completion b/bin/ossh_bash_completion index 1467de858..5072161f0 100755 --- a/bin/ossh_bash_completion +++ b/bin/ossh_bash_completion @@ -1,6 +1,12 @@  __ossh_known_hosts(){ -    if [[ -f ~/.ansible/tmp/multi_ec2_inventory.cache ]]; then -        /usr/bin/python -c 'import json,os; z = json.loads(open("%s"%os.path.expanduser("~/.ansible/tmp/multi_ec2_inventory.cache")).read()); print "\n".join(["%s.%s" % (host["ec2_tag_Name"],host["ec2_tag_environment"]) for dns, host in z["_meta"]["hostvars"].items() if all(k in host for k in ("ec2_tag_Name", "ec2_tag_environment"))])' +    if python -c 'import openshift_ansible' &>/dev/null; then +      /usr/bin/python -c 'from openshift_ansible import multi_ec2; m=multi_ec2.MultiEc2(); m.run(); z=m.result; print "\n".join(["%s.%s" % (host["ec2_tag_Name"],host["ec2_tag_environment"]) for dns, host in z["_meta"]["hostvars"].items() if all(k in host for k in ("ec2_tag_Name", "ec2_tag_environment"))])' + +    elif [[ -f /dev/shm/.ansible/tmp/multi_ec2_inventory.cache ]]; then +      /usr/bin/python -c 'import json; loc="/dev/shm/.ansible/tmp/multi_ec2_inventory.cache"; z=json.loads(open(loc).read()); print "\n".join(["%s.%s" % (host["ec2_tag_Name"],host["ec2_tag_environment"]) for dns, host in z["_meta"]["hostvars"].items() if all(k in host for k in ("ec2_tag_Name", "ec2_tag_environment"))])' + +    elif [[ -f ~/.ansible/tmp/multi_ec2_inventory.cache ]]; then +      /usr/bin/python -c 'import json,os; loc="%s" % os.path.expanduser("~/.ansible/tmp/multi_ec2_inventory.cache"); z=json.loads(open(loc).read()); print "\n".join(["%s.%s" % (host["ec2_tag_Name"],host["ec2_tag_environment"]) for dns, host in z["_meta"]["hostvars"].items() if all(k in host for k in ("ec2_tag_Name", "ec2_tag_environment"))])'      fi  } @@ -19,8 +25,15 @@ _ossh()  complete -F _ossh ossh oscp  __opssh_known_hosts(){ -    if [[ -f ~/.ansible/tmp/multi_ec2_inventory.cache ]]; then -                /usr/bin/python -c 'import json,os; z = json.loads(open("%s"%os.path.expanduser("~/.ansible/tmp/multi_ec2_inventory.cache")).read()); print "\n".join(["%s" % (host["ec2_tag_host-type"]) for dns, host in z["_meta"]["hostvars"].items() if "ec2_tag_host-type" in host])' +    if python -c 'import openshift_ansible' &>/dev/null; then +      /usr/bin/python -c 'from openshift_ansible.multi_ec2 import MultiEc2; m=MultiEc2(); m.run(); print "\n".join(["%s" % (host["ec2_tag_host-type"]) for dns, host in m.result["_meta"]["hostvars"].items() if "ec2_tag_host-type" in host])' + +    elif [[ -f /dev/shm/.ansible/tmp/multi_ec2_inventory.cache ]]; then +      /usr/bin/python -c 'import json; loc="/dev/shm/.ansible/tmp/multi_ec2_inventory.cache"; z=json.loads(open(loc).read()); print "\n".join(["%s" % (host["ec2_tag_host-type"]) for dns, host in z["_meta"]["hostvars"].items() if "ec2_tag_host-type" in host])' + +    elif [[ -f ~/.ansible/tmp/multi_ec2_inventory.cache ]]; then +      /usr/bin/python -c 'import json,os; loc="%s" % os.path.expanduser("/dev/shm/.ansible/tmp/multi_ec2_inventory.cache"); z=json.loads(open(loc).read()); print "\n".join(["%s" % (host["ec2_tag_host-type"]) for dns, host in z["_meta"]["hostvars"].items() if "ec2_tag_host-type" in host])' +      fi  } diff --git a/bin/ossh_zsh_completion b/bin/ossh_zsh_completion index 6ab930dc4..44500c618 100644 --- a/bin/ossh_zsh_completion +++ b/bin/ossh_zsh_completion @@ -1,9 +1,16 @@  #compdef ossh oscp  _ossh_known_hosts(){ -  if [[ -f ~/.ansible/tmp/multi_ec2_inventory.cache ]]; then -    print $(/usr/bin/python -c 'import json,os; z = json.loads(open("%s"%os.path.expanduser("~/.ansible/tmp/multi_ec2_inventory.cache")).read()); print "\n".join(["%s.%s" % (host["ec2_tag_Name"],host["ec2_tag_environment"]) for dns, host in z["_meta"]["hostvars"].items()])') -  fi +    if python -c 'import openshift_ansible' &>/dev/null; then +      print $(/usr/bin/python -c 'from openshift_ansible import multi_ec2; m=multi_ec2.MultiEc2(); m.run(); z=m.result; print "\n".join(["%s.%s" % (host["ec2_tag_Name"],host["ec2_tag_environment"]) for dns, host in z["_meta"]["hostvars"].items() if all(k in host for k in ("ec2_tag_Name", "ec2_tag_environment"))])') + +    elif [[ -f /dev/shm/.ansible/tmp/multi_ec2_inventory.cache ]]; then +      print $(/usr/bin/python -c 'import json; loc="/dev/shm/.ansible/tmp/multi_ec2_inventory.cache"; z=json.loads(open(loc).read()); print "\n".join(["%s.%s" % (host["ec2_tag_Name"],host["ec2_tag_environment"]) for dns, host in z["_meta"]["hostvars"].items() if all(k in host for k in ("ec2_tag_Name", "ec2_tag_environment"))])') + +    elif [[ -f ~/.ansible/tmp/multi_ec2_inventory.cache ]]; then +      print $(/usr/bin/python -c 'import json,os; loc="%s" % os.path.expanduser("~/.ansible/tmp/multi_ec2_inventory.cache"); z=json.loads(open(loc).read()); print "\n".join(["%s.%s" % (host["ec2_tag_Name"],host["ec2_tag_environment"]) for dns, host in z["_meta"]["hostvars"].items() if all(k in host for k in ("ec2_tag_Name", "ec2_tag_environment"))])') + +    fi  }  _ossh(){ | 
