diff options
Diffstat (limited to 'utils')
| -rw-r--r-- | utils/setup.py | 2 | ||||
| -rw-r--r-- | utils/src/ooinstall/cli_installer.py | 142 | ||||
| -rw-r--r-- | utils/src/ooinstall/openshift_ansible.py (renamed from utils/src/ooinstall/install_transactions.py) | 12 | ||||
| -rw-r--r-- | utils/test/cli_installer_tests.py | 70 | 
4 files changed, 147 insertions, 79 deletions
| diff --git a/utils/setup.py b/utils/setup.py index 6e2fdd9c0..eac1b4b2e 100644 --- a/utils/setup.py +++ b/utils/setup.py @@ -79,7 +79,7 @@ setup(      # pip to create the appropriate form of executable for the target platform.      entry_points={          'console_scripts': [ -            'oo-install=ooinstall.cli_installer:main', +            'oo-install=ooinstall.cli_installer:cli',          ],      },  ) diff --git a/utils/src/ooinstall/cli_installer.py b/utils/src/ooinstall/cli_installer.py index c2ae00bd1..bfaaea6aa 100644 --- a/utils/src/ooinstall/cli_installer.py +++ b/utils/src/ooinstall/cli_installer.py @@ -6,12 +6,13 @@ import click  import os  import re  import sys -from ooinstall import install_transactions +from ooinstall import openshift_ansible  from ooinstall import OOConfig  from ooinstall.oo_config import Host  from ooinstall.variants import find_variant, get_variant_version_combos  DEFAULT_ANSIBLE_CONFIG = '/usr/share/atomic-openshift-util/ansible.cfg' +DEFAULT_PLAYBOOK_DIR = '/usr/share/ansible/openshift-ansible/'  def validate_ansible_dir(path):      if not path: @@ -356,8 +357,8 @@ def get_hosts_to_run_on(oo_cfg, callback_facts, unattended, force):                  hosts_to_run_on.extend(new_nodes)                  oo_cfg.hosts.extend(new_nodes) -                install_transactions.set_config(oo_cfg) -                callback_facts, error = install_transactions.default_facts(oo_cfg.hosts) +                openshift_ansible.set_config(oo_cfg) +                callback_facts, error = openshift_ansible.default_facts(oo_cfg.hosts)                  if error:                      click.echo("There was a problem fetching the required information. " \                                 "See {} for details.".format(oo_cfg.settings['ansible_log_path'])) @@ -367,71 +368,117 @@ def get_hosts_to_run_on(oo_cfg, callback_facts, unattended, force):      return hosts_to_run_on, callback_facts -@click.command() + +@click.group() +@click.pass_context +@click.option('--unattended', '-u', is_flag=True, default=False)  @click.option('--configuration', '-c', -              type=click.Path(file_okay=True, -                              dir_okay=False, -                              writable=True, -                              readable=True), -              default=None) +    type=click.Path(file_okay=True, +        dir_okay=False, +        writable=True, +        readable=True), +    default=None)  @click.option('--ansible-playbook-directory', -              '-a', -              type=click.Path(exists=True, -                              file_okay=False, -                              dir_okay=True, -                              writable=True, -                              readable=True), -              # callback=validate_ansible_dir, -              envvar='OO_ANSIBLE_PLAYBOOK_DIRECTORY') +    '-a', +    type=click.Path(exists=True, +        file_okay=False, +        dir_okay=True, +        writable=False, +        readable=True), +    # callback=validate_ansible_dir, +    envvar='OO_ANSIBLE_PLAYBOOK_DIRECTORY')  @click.option('--ansible-config', -              type=click.Path(file_okay=True, -                              dir_okay=False, -                              writable=True, -                              readable=True), -              default=None) +    type=click.Path(file_okay=True, +        dir_okay=False, +        writable=True, +        readable=True), +    default=None)  @click.option('--ansible-log-path', -              type=click.Path(file_okay=True, -                              dir_okay=False, -                              writable=True, -                              readable=True), -              default="/tmp/ansible.log") -@click.option('--unattended', '-u', is_flag=True, default=False) -@click.option('--force', '-f', is_flag=True, default=False) +    type=click.Path(file_okay=True, +        dir_okay=False, +        writable=True, +        readable=True), +    default="/tmp/ansible.log")  #pylint: disable=too-many-arguments  # Main CLI entrypoint, not much we can do about too many arguments. -def main(configuration, ansible_playbook_directory, ansible_config, ansible_log_path, unattended, force): -    oo_cfg = OOConfig(configuration) +def cli(ctx, unattended, configuration, ansible_playbook_directory, ansible_config, ansible_log_path): +    """ +    The main click CLI module. Responsible for handling most common CLI options, +    assigning any defaults and adding to the context for the sub-commands. +    """ +    ctx.obj = {} +    ctx.obj['unattended'] = unattended +    ctx.obj['configuration'] = configuration +    ctx.obj['ansible_config'] = ansible_config +    ctx.obj['ansible_log_path'] = ansible_log_path +    oo_cfg = OOConfig(ctx.obj['configuration']) + +    # If no playbook dir on the CLI, check the config:      if not ansible_playbook_directory:          ansible_playbook_directory = oo_cfg.settings.get('ansible_playbook_directory', '') +    # If still no playbook dir, check for the default location: +    if not ansible_playbook_directory and os.path.exists(DEFAULT_PLAYBOOK_DIR): +        ansible_playbook_directory = DEFAULT_PLAYBOOK_DIR +    validate_ansible_dir(ansible_playbook_directory) +    oo_cfg.settings['ansible_playbook_directory'] = ansible_playbook_directory +    oo_cfg.ansible_playbook_directory = ansible_playbook_directory +    ctx.obj['ansible_playbook_directory'] = ansible_playbook_directory -    if ansible_config: -        oo_cfg.settings['ansible_config'] = ansible_config +    if ctx.obj['ansible_config']: +        oo_cfg.settings['ansible_config'] = ctx.obj['ansible_config']      elif os.path.exists(DEFAULT_ANSIBLE_CONFIG):          # If we're installed by RPM this file should exist and we can use it as our default:          oo_cfg.settings['ansible_config'] = DEFAULT_ANSIBLE_CONFIG -    validate_ansible_dir(ansible_playbook_directory) -    oo_cfg.settings['ansible_playbook_directory'] = ansible_playbook_directory -    oo_cfg.ansible_playbook_directory = ansible_playbook_directory +    oo_cfg.settings['ansible_log_path'] = ctx.obj['ansible_log_path'] -    oo_cfg.settings['ansible_log_path'] = ansible_log_path -    install_transactions.set_config(oo_cfg) +    ctx.obj['oo_cfg'] = oo_cfg +    openshift_ansible.set_config(oo_cfg) -    if unattended: + +@click.command() +@click.pass_context +def uninstall(ctx): +    oo_cfg = ctx.obj['oo_cfg'] + +    if len(oo_cfg.hosts) == 0: +        click.echo("No hosts defined in: %s" % oo_cfg['configuration']) +        sys.exit(1) + +    click.echo("OpenShift will be uninstalled from the following hosts:\n") +    if not ctx.obj['unattended']: +        # Prompt interactively to confirm: +        for host in oo_cfg.hosts: +            click.echo("  * %s" % host.name) +        proceed = click.confirm("\nDo you wish to proceed?") +        if not proceed: +            click.echo("Uninstall cancelled.") +            sys.exit(0) + +    openshift_ansible.run_uninstall_playbook() + + + +@click.command() +@click.option('--force', '-f', is_flag=True, default=False) +@click.pass_context +def install(ctx, force): +    oo_cfg = ctx.obj['oo_cfg'] + +    if ctx.obj['unattended']:          error_if_missing_info(oo_cfg)      else:          oo_cfg = get_missing_info_from_user(oo_cfg)      click.echo('Gathering information from hosts...') -    callback_facts, error = install_transactions.default_facts(oo_cfg.hosts) +    callback_facts, error = openshift_ansible.default_facts(oo_cfg.hosts)      if error:          click.echo("There was a problem fetching the required information. " \                     "Please see {} for details.".format(oo_cfg.settings['ansible_log_path']))          sys.exit(1) -    hosts_to_run_on, callback_facts = get_hosts_to_run_on(oo_cfg, callback_facts, unattended, force) - +    hosts_to_run_on, callback_facts = get_hosts_to_run_on(oo_cfg, callback_facts, ctx.obj['unattended'], force)      click.echo('Writing config to: %s' % oo_cfg.config_path) @@ -449,10 +496,10 @@ def main(configuration, ansible_playbook_directory, ansible_config, ansible_log_      message = """  If changes are needed to the values recorded by the installer please update {}.  """.format(oo_cfg.config_path) -    if not unattended: +    if not ctx.obj['unattended']:          confirm_continue(message) -    error = install_transactions.run_main_playbook(oo_cfg.hosts, +    error = openshift_ansible.run_main_playbook(oo_cfg.hosts,                                                     hosts_to_run_on)      if error:          # The bootstrap script will print out the log location. @@ -475,5 +522,10 @@ http://docs.openshift.com/enterprise/latest/admin_guide/overview.html          click.echo(message)          click.pause() +cli.add_command(install) +cli.add_command(uninstall) +  if __name__ == '__main__': -    main() +    # This is expected behaviour for context passing with click library: +    # pylint: disable=unexpected-keyword-arg +    cli(obj={}) diff --git a/utils/src/ooinstall/install_transactions.py b/utils/src/ooinstall/openshift_ansible.py index cef6662d7..3306271c8 100644 --- a/utils/src/ooinstall/install_transactions.py +++ b/utils/src/ooinstall/openshift_ansible.py @@ -126,8 +126,20 @@ def run_main_playbook(hosts, hosts_to_run_on):          facts_env['ANSIBLE_CONFIG'] = CFG.settings['ansible_config']      return run_ansible(main_playbook_path, inventory_file, facts_env) +  def run_ansible(playbook, inventory, env_vars):      return subprocess.call(['ansible-playbook',                               '--inventory-file={}'.format(inventory),                               playbook],                               env=env_vars) + +def run_uninstall_playbook(): +    playbook = os.path.join(CFG.settings['ansible_playbook_directory'], +        'playbooks/adhoc/uninstall.yml') +    inventory_file = generate_inventory(CFG.hosts) +    facts_env = os.environ.copy() +    if 'ansible_log_path' in CFG.settings: +        facts_env['ANSIBLE_LOG_PATH'] = CFG.settings['ansible_log_path'] +    if 'ansible_config' in CFG.settings: +        facts_env['ANSIBLE_CONFIG'] = CFG.settings['ansible_config'] +    return run_ansible(playbook, inventory_file, facts_env) diff --git a/utils/test/cli_installer_tests.py b/utils/test/cli_installer_tests.py index 076fe5dc9..b183f0acb 100644 --- a/utils/test/cli_installer_tests.py +++ b/utils/test/cli_installer_tests.py @@ -76,7 +76,7 @@ class OOCliFixture(OOInstallFixture):          self.cli_args = ["-a", self.work_dir]      def run_cli(self): -        return self.runner.invoke(cli.main, self.cli_args) +        return self.runner.invoke(cli.cli, self.cli_args)      def assert_result(self, result, exit_code):          if result.exception is not None or result.exit_code != exit_code: @@ -102,8 +102,8 @@ class UnattendedCliTests(OOCliFixture):          OOCliFixture.setUp(self)          self.cli_args.append("-u") -    @patch('ooinstall.install_transactions.run_main_playbook') -    @patch('ooinstall.install_transactions.load_system_facts') +    @patch('ooinstall.openshift_ansible.run_main_playbook') +    @patch('ooinstall.openshift_ansible.load_system_facts')      def test_cfg_full_run(self, load_facts_mock, run_playbook_mock):          load_facts_mock.return_value = (MOCK_FACTS, 0)          run_playbook_mock.return_value = 0 @@ -111,8 +111,8 @@ class UnattendedCliTests(OOCliFixture):          config_file = self.write_config(os.path.join(self.work_dir,              'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise') -        self.cli_args.extend(["-c", config_file]) -        result = self.runner.invoke(cli.main, self.cli_args) +        self.cli_args.extend(["-c", config_file, "install"]) +        result = self.runner.invoke(cli.cli, self.cli_args)          self.assert_result(result, 0)          load_facts_args = load_facts_mock.call_args[0] @@ -133,8 +133,8 @@ class UnattendedCliTests(OOCliFixture):          self.assertEquals(3, len(hosts))          self.assertEquals(3, len(hosts_to_run_on)) -    @patch('ooinstall.install_transactions.run_main_playbook') -    @patch('ooinstall.install_transactions.load_system_facts') +    @patch('ooinstall.openshift_ansible.run_main_playbook') +    @patch('ooinstall.openshift_ansible.load_system_facts')      def test_inventory_write(self, load_facts_mock, run_playbook_mock):          # Add an ssh user so we can verify it makes it to the inventory file: @@ -146,8 +146,8 @@ class UnattendedCliTests(OOCliFixture):          config_file = self.write_config(os.path.join(self.work_dir,              'ooinstall.conf'), merged_config) -        self.cli_args.extend(["-c", config_file]) -        result = self.runner.invoke(cli.main, self.cli_args) +        self.cli_args.extend(["-c", config_file, "install"]) +        result = self.runner.invoke(cli.cli, self.cli_args)          self.assert_result(result, 0)          # Check the inventory file looks as we would expect: @@ -172,8 +172,8 @@ class UnattendedCliTests(OOCliFixture):              self.assertTrue('openshift_hostname' in master_line)              self.assertTrue('openshift_public_hostname' in master_line) -    @patch('ooinstall.install_transactions.run_main_playbook') -    @patch('ooinstall.install_transactions.load_system_facts') +    @patch('ooinstall.openshift_ansible.run_main_playbook') +    @patch('ooinstall.openshift_ansible.load_system_facts')      def test_variant_version_latest_assumed(self, load_facts_mock,          run_playbook_mock):          load_facts_mock.return_value = (MOCK_FACTS, 0) @@ -182,8 +182,8 @@ class UnattendedCliTests(OOCliFixture):          config_file = self.write_config(os.path.join(self.work_dir,              'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise') -        self.cli_args.extend(["-c", config_file]) -        result = self.runner.invoke(cli.main, self.cli_args) +        self.cli_args.extend(["-c", config_file, "install"]) +        result = self.runner.invoke(cli.cli, self.cli_args)          self.assert_result(result, 0)          written_config = self._read_yaml(config_file) @@ -199,8 +199,8 @@ class UnattendedCliTests(OOCliFixture):          self.assertEquals('openshift-enterprise',              inventory.get('OSEv3:vars', 'deployment_type')) -    @patch('ooinstall.install_transactions.run_main_playbook') -    @patch('ooinstall.install_transactions.load_system_facts') +    @patch('ooinstall.openshift_ansible.run_main_playbook') +    @patch('ooinstall.openshift_ansible.load_system_facts')      def test_variant_version_preserved(self, load_facts_mock,          run_playbook_mock):          load_facts_mock.return_value = (MOCK_FACTS, 0) @@ -211,8 +211,8 @@ class UnattendedCliTests(OOCliFixture):          config_file = self.write_config(os.path.join(self.work_dir,              'ooinstall.conf'), config) -        self.cli_args.extend(["-c", config_file]) -        result = self.runner.invoke(cli.main, self.cli_args) +        self.cli_args.extend(["-c", config_file, "install"]) +        result = self.runner.invoke(cli.cli, self.cli_args)          self.assert_result(result, 0)          written_config = self._read_yaml(config_file) @@ -227,8 +227,8 @@ class UnattendedCliTests(OOCliFixture):          self.assertEquals('enterprise',              inventory.get('OSEv3:vars', 'deployment_type')) -    @patch('ooinstall.install_transactions.run_ansible') -    @patch('ooinstall.install_transactions.load_system_facts') +    @patch('ooinstall.openshift_ansible.run_ansible') +    @patch('ooinstall.openshift_ansible.load_system_facts')      def test_no_ansible_config_specified(self, load_facts_mock, run_ansible_mock):          load_facts_mock.return_value = (MOCK_FACTS, 0)          run_ansible_mock.return_value = 0 @@ -238,8 +238,8 @@ class UnattendedCliTests(OOCliFixture):          self._ansible_config_test(load_facts_mock, run_ansible_mock,              config, None, None) -    @patch('ooinstall.install_transactions.run_ansible') -    @patch('ooinstall.install_transactions.load_system_facts') +    @patch('ooinstall.openshift_ansible.run_ansible') +    @patch('ooinstall.openshift_ansible.load_system_facts')      def test_ansible_config_specified_cli(self, load_facts_mock, run_ansible_mock):          load_facts_mock.return_value = (MOCK_FACTS, 0)          run_ansible_mock.return_value = 0 @@ -250,8 +250,8 @@ class UnattendedCliTests(OOCliFixture):          self._ansible_config_test(load_facts_mock, run_ansible_mock,              config, ansible_config, ansible_config) -    @patch('ooinstall.install_transactions.run_ansible') -    @patch('ooinstall.install_transactions.load_system_facts') +    @patch('ooinstall.openshift_ansible.run_ansible') +    @patch('ooinstall.openshift_ansible.load_system_facts')      def test_ansible_config_specified_in_installer_config(self,          load_facts_mock, run_ansible_mock): @@ -282,7 +282,8 @@ class UnattendedCliTests(OOCliFixture):          self.cli_args.extend(["-c", config_file])          if ansible_config_cli:              self.cli_args.extend(["--ansible-config", ansible_config_cli]) -        result = self.runner.invoke(cli.main, self.cli_args) +        self.cli_args.append("install") +        result = self.runner.invoke(cli.cli, self.cli_args)          self.assert_result(result, 0)          # Test the env vars for facts playbook: @@ -388,8 +389,8 @@ class AttendedCliTests(OOCliFixture):              self.assertTrue('public_ip' in h)              self.assertTrue('public_hostname' in h) -    @patch('ooinstall.install_transactions.run_main_playbook') -    @patch('ooinstall.install_transactions.load_system_facts') +    @patch('ooinstall.openshift_ansible.run_main_playbook') +    @patch('ooinstall.openshift_ansible.load_system_facts')      def test_full_run(self, load_facts_mock, run_playbook_mock):          load_facts_mock.return_value = (MOCK_FACTS, 0)          run_playbook_mock.return_value = 0 @@ -401,7 +402,8 @@ class AttendedCliTests(OOCliFixture):                                        ssh_user='root',                                        variant_num=1,                                        confirm_facts='y') -        result = self.runner.invoke(cli.main, self.cli_args, +        self.cli_args.append("install") +        result = self.runner.invoke(cli.cli, self.cli_args,              input=cli_input)          self.assert_result(result, 0) @@ -411,8 +413,8 @@ class AttendedCliTests(OOCliFixture):          written_config = self._read_yaml(self.config_file)          self._verify_config_hosts(written_config, 3) -    @patch('ooinstall.install_transactions.run_main_playbook') -    @patch('ooinstall.install_transactions.load_system_facts') +    @patch('ooinstall.openshift_ansible.run_main_playbook') +    @patch('ooinstall.openshift_ansible.load_system_facts')      def test_add_nodes(self, load_facts_mock, run_playbook_mock):          # Modify the mock facts to return a version indicating OpenShift @@ -432,7 +434,8 @@ class AttendedCliTests(OOCliFixture):                                        ssh_user='root',                                        variant_num=1,                                        confirm_facts='y') -        result = self.runner.invoke(cli.main, +        self.cli_args.append("install") +        result = self.runner.invoke(cli.cli,                                      self.cli_args,                                      input=cli_input)          self.assert_result(result, 0) @@ -443,8 +446,8 @@ class AttendedCliTests(OOCliFixture):          written_config = self._read_yaml(self.config_file)          self._verify_config_hosts(written_config, 3) -    @patch('ooinstall.install_transactions.run_main_playbook') -    @patch('ooinstall.install_transactions.load_system_facts') +    @patch('ooinstall.openshift_ansible.run_main_playbook') +    @patch('ooinstall.openshift_ansible.load_system_facts')      def test_fresh_install_with_config(self, load_facts_mock, run_playbook_mock):          load_facts_mock.return_value = (MOCK_FACTS, 0)          run_playbook_mock.return_value = 0 @@ -454,7 +457,8 @@ class AttendedCliTests(OOCliFixture):                                          SAMPLE_CONFIG % 'openshift-enterprise')          cli_input = self._build_input(confirm_facts='y')          self.cli_args.extend(["-c", config_file]) -        result = self.runner.invoke(cli.main, +        self.cli_args.append("install") +        result = self.runner.invoke(cli.cli,                                      self.cli_args,                                      input=cli_input)          self.assert_result(result, 0) | 
