From efba9eb00b9bb8451cb73744c4a21f5c583e3d58 Mon Sep 17 00:00:00 2001 From: Devan Goodwin Date: Mon, 26 Oct 2015 14:55:43 -0300 Subject: Add subcommands to CLI. --- utils/setup.py | 2 +- utils/src/ooinstall/cli_installer.py | 108 ++++++++++++++++++---------- utils/src/ooinstall/install_transactions.py | 1 + utils/test/cli_installer_tests.py | 30 ++++---- 4 files changed, 91 insertions(+), 50 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..32b968794 100644 --- a/utils/src/ooinstall/cli_installer.py +++ b/utils/src/ooinstall/cli_installer.py @@ -367,46 +367,59 @@ 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=True, + 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_playbook_directory'] = ansible_playbook_directory + ctx.obj['ansible_config'] = ansible_config + ctx.obj['ansible_log_path'] = ansible_log_path + oo_cfg = OOConfig(ctx.obj['configuration']) + + ansible_playbook_directory = ctx.obj['ansible_playbook_directory'] if not ansible_playbook_directory: ansible_playbook_directory = oo_cfg.settings.get('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 @@ -415,10 +428,29 @@ def main(configuration, ansible_playbook_directory, ansible_config, ansible_log_ oo_cfg.settings['ansible_playbook_directory'] = ansible_playbook_directory oo_cfg.ansible_playbook_directory = ansible_playbook_directory - oo_cfg.settings['ansible_log_path'] = ansible_log_path + oo_cfg.settings['ansible_log_path'] = ctx.obj['ansible_log_path'] + + ctx.obj['oo_cfg'] = oo_cfg + + +@click.command() +@click.pass_context +def uninstall(ctx): + #oo_cfg = ctx.obj['oo_cfg'] + click.echo("Running uninstall command.") + if not ctx.obj['unattended']: + # Prompt interactively to confirm: + pass + + +@click.command() +@click.option('--force', '-f', is_flag=True, default=False) +@click.pass_context +def install(ctx, force): + oo_cfg = ctx.obj['oo_cfg'] install_transactions.set_config(oo_cfg) - if unattended: + if ctx.obj['unattended']: error_if_missing_info(oo_cfg) else: oo_cfg = get_missing_info_from_user(oo_cfg) @@ -430,8 +462,7 @@ def main(configuration, ansible_playbook_directory, ansible_config, ansible_log_ "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,7 +480,7 @@ 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, @@ -475,5 +506,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/install_transactions.py index cef6662d7..de53dc3c0 100644 --- a/utils/src/ooinstall/install_transactions.py +++ b/utils/src/ooinstall/install_transactions.py @@ -131,3 +131,4 @@ def run_ansible(playbook, inventory, env_vars): '--inventory-file={}'.format(inventory), playbook], env=env_vars) + diff --git a/utils/test/cli_installer_tests.py b/utils/test/cli_installer_tests.py index 076fe5dc9..1f74b5b15 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: @@ -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] @@ -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: @@ -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) @@ -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) @@ -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: @@ -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) @@ -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) @@ -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) -- cgit v1.2.3 From 201fd2f37d43419513b448cd99dd202a96bb8542 Mon Sep 17 00:00:00 2001 From: Devan Goodwin Date: Mon, 26 Oct 2015 15:37:30 -0300 Subject: Add uninstall subcommand. --- utils/src/ooinstall/cli_installer.py | 21 +++++++++++++++++---- utils/src/ooinstall/install_transactions.py | 11 +++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/utils/src/ooinstall/cli_installer.py b/utils/src/ooinstall/cli_installer.py index 32b968794..91d501952 100644 --- a/utils/src/ooinstall/cli_installer.py +++ b/utils/src/ooinstall/cli_installer.py @@ -431,16 +431,30 @@ def cli(ctx, unattended, configuration, ansible_playbook_directory, ansible_conf oo_cfg.settings['ansible_log_path'] = ctx.obj['ansible_log_path'] ctx.obj['oo_cfg'] = oo_cfg + install_transactions.set_config(oo_cfg) @click.command() @click.pass_context def uninstall(ctx): - #oo_cfg = ctx.obj['oo_cfg'] - click.echo("Running uninstall command.") + 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: - pass + 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) + + install_transactions.run_uninstall_playbook() + @click.command() @@ -448,7 +462,6 @@ def uninstall(ctx): @click.pass_context def install(ctx, force): oo_cfg = ctx.obj['oo_cfg'] - install_transactions.set_config(oo_cfg) if ctx.obj['unattended']: error_if_missing_info(oo_cfg) diff --git a/utils/src/ooinstall/install_transactions.py b/utils/src/ooinstall/install_transactions.py index de53dc3c0..3306271c8 100644 --- a/utils/src/ooinstall/install_transactions.py +++ b/utils/src/ooinstall/install_transactions.py @@ -126,9 +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) -- cgit v1.2.3 From 93b2a9bd2f4a3b93be3cb51ecf034000a652496e Mon Sep 17 00:00:00 2001 From: Devan Goodwin Date: Tue, 27 Oct 2015 13:26:57 -0300 Subject: Use default playbooks if available. Because we're now installing from an rpm, we have a good idea where to find the default playbooks and shouldn't require the user to tell us. --- openshift-ansible.spec | 1 + utils/src/ooinstall/cli_installer.py | 17 ++++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/openshift-ansible.spec b/openshift-ansible.spec index a24ca0c8a..3b69da825 100644 --- a/openshift-ansible.spec +++ b/openshift-ansible.spec @@ -208,6 +208,7 @@ BuildArch: noarch %package -n atomic-openshift-utils Summary: Atomic OpenShift Utilities BuildRequires: python-setuptools +Requires: openshift-ansible-playbooks Requires: ansible Requires: python-click Requires: python-setuptools diff --git a/utils/src/ooinstall/cli_installer.py b/utils/src/ooinstall/cli_installer.py index 91d501952..03f86a166 100644 --- a/utils/src/ooinstall/cli_installer.py +++ b/utils/src/ooinstall/cli_installer.py @@ -12,6 +12,7 @@ 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: @@ -382,7 +383,7 @@ def get_hosts_to_run_on(oo_cfg, callback_facts, unattended, force): type=click.Path(exists=True, file_okay=False, dir_okay=True, - writable=True, + writable=False, readable=True), # callback=validate_ansible_dir, envvar='OO_ANSIBLE_PLAYBOOK_DIRECTORY') @@ -408,15 +409,21 @@ def cli(ctx, unattended, configuration, ansible_playbook_directory, ansible_conf ctx.obj = {} ctx.obj['unattended'] = unattended ctx.obj['configuration'] = configuration - ctx.obj['ansible_playbook_directory'] = ansible_playbook_directory ctx.obj['ansible_config'] = ansible_config ctx.obj['ansible_log_path'] = ansible_log_path oo_cfg = OOConfig(ctx.obj['configuration']) - ansible_playbook_directory = ctx.obj['ansible_playbook_directory'] + # 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 ctx.obj['ansible_config']: oo_cfg.settings['ansible_config'] = ctx.obj['ansible_config'] @@ -424,10 +431,6 @@ def cli(ctx, unattended, configuration, ansible_playbook_directory, ansible_conf # 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'] ctx.obj['oo_cfg'] = oo_cfg -- cgit v1.2.3 From e2c30afd5af2fa952a3ef576f50c8dd304dfdd7d Mon Sep 17 00:00:00 2001 From: Devan Goodwin Date: Fri, 30 Oct 2015 10:51:40 -0300 Subject: Add utils subpackage missing dep on openshift-ansible-roles. --- openshift-ansible.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/openshift-ansible.spec b/openshift-ansible.spec index 3b69da825..d3be338a7 100644 --- a/openshift-ansible.spec +++ b/openshift-ansible.spec @@ -209,6 +209,7 @@ BuildArch: noarch Summary: Atomic OpenShift Utilities BuildRequires: python-setuptools Requires: openshift-ansible-playbooks +Requires: openshift-ansible-roles Requires: ansible Requires: python-click Requires: python-setuptools -- cgit v1.2.3 From 2855bc043f8970136b72774b15c5306dccdaa040 Mon Sep 17 00:00:00 2001 From: Devan Goodwin Date: Mon, 2 Nov 2015 12:06:34 -0400 Subject: Rename install_transactions module to openshift_ansible. --- utils/src/ooinstall/cli_installer.py | 14 +-- utils/src/ooinstall/install_transactions.py | 145 ---------------------------- utils/src/ooinstall/openshift_ansible.py | 145 ++++++++++++++++++++++++++++ utils/test/cli_installer_tests.py | 40 ++++---- 4 files changed, 172 insertions(+), 172 deletions(-) delete mode 100644 utils/src/ooinstall/install_transactions.py create mode 100644 utils/src/ooinstall/openshift_ansible.py diff --git a/utils/src/ooinstall/cli_installer.py b/utils/src/ooinstall/cli_installer.py index 03f86a166..bfaaea6aa 100644 --- a/utils/src/ooinstall/cli_installer.py +++ b/utils/src/ooinstall/cli_installer.py @@ -6,7 +6,7 @@ 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 @@ -357,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'])) @@ -434,7 +434,7 @@ def cli(ctx, unattended, configuration, ansible_playbook_directory, ansible_conf oo_cfg.settings['ansible_log_path'] = ctx.obj['ansible_log_path'] ctx.obj['oo_cfg'] = oo_cfg - install_transactions.set_config(oo_cfg) + openshift_ansible.set_config(oo_cfg) @click.command() @@ -456,7 +456,7 @@ def uninstall(ctx): click.echo("Uninstall cancelled.") sys.exit(0) - install_transactions.run_uninstall_playbook() + openshift_ansible.run_uninstall_playbook() @@ -472,7 +472,7 @@ def install(ctx, force): 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'])) @@ -499,7 +499,7 @@ If changes are needed to the values recorded by the installer please update {}. 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. diff --git a/utils/src/ooinstall/install_transactions.py b/utils/src/ooinstall/install_transactions.py deleted file mode 100644 index 3306271c8..000000000 --- a/utils/src/ooinstall/install_transactions.py +++ /dev/null @@ -1,145 +0,0 @@ -# TODO: Temporarily disabled due to importing old code into openshift-ansible -# repo. We will work on these over time. -# pylint: disable=bad-continuation,missing-docstring,no-self-use,invalid-name,global-statement,global-variable-not-assigned - -import subprocess -import os -import yaml -from ooinstall.variants import find_variant - -CFG = None - -def set_config(cfg): - global CFG - CFG = cfg - -def generate_inventory(hosts): - print hosts - global CFG - base_inventory_path = CFG.settings['ansible_inventory_path'] - base_inventory = open(base_inventory_path, 'w') - base_inventory.write('\n[OSEv3:children]\nmasters\nnodes\n') - base_inventory.write('\n[OSEv3:vars]\n') - base_inventory.write('ansible_ssh_user={}\n'.format(CFG.settings['ansible_ssh_user'])) - if CFG.settings['ansible_ssh_user'] != 'root': - base_inventory.write('ansible_sudo=true\n') - - # Find the correct deployment type for ansible: - ver = find_variant(CFG.settings['variant'], - version=CFG.settings.get('variant_version', None))[1] - base_inventory.write('deployment_type={}\n'.format(ver.ansible_key)) - - if 'OO_INSTALL_DEVEL_REGISTRY' in os.environ: - base_inventory.write('oreg_url=rcm-img-docker01.build.eng.bos.redhat.com:' - '5001/openshift3/ose-${component}:${version}\n') - if 'OO_INSTALL_PUDDLE_REPO_ENABLE' in os.environ: - base_inventory.write("openshift_additional_repos=[{'id': 'ose-devel', " - "'name': 'ose-devel', " - "'baseurl': 'http://buildvm-devops.usersys.redhat.com" - "/puddle/build/AtomicOpenShift/3.1/latest/RH7-RHAOS-3.1/$basearch/os', " - "'enabled': 1, 'gpgcheck': 0}]\n") - if 'OO_INSTALL_STAGE_REGISTRY' in os.environ: - base_inventory.write('oreg_url=registry.access.stage.redhat.com/openshift3/ose-${component}:${version}\n') - - base_inventory.write('\n[masters]\n') - masters = (host for host in hosts if host.master) - for master in masters: - write_host(master, base_inventory) - base_inventory.write('\n[nodes]\n') - nodes = (host for host in hosts if host.node) - for node in nodes: - # TODO: Until the Master can run the SDN itself we have to configure the Masters - # as Nodes too. - scheduleable = True - # If there's only one Node and it's also a Master we want it to be scheduleable: - if node in masters and len(masters) != 1: - scheduleable = False - write_host(node, base_inventory, scheduleable) - base_inventory.close() - return base_inventory_path - - -def write_host(host, inventory, scheduleable=True): - global CFG - facts = '' - if host.ip: - facts += ' openshift_ip={}'.format(host.ip) - if host.public_ip: - facts += ' openshift_public_ip={}'.format(host.public_ip) - if host.hostname: - facts += ' openshift_hostname={}'.format(host.hostname) - if host.public_hostname: - facts += ' openshift_public_hostname={}'.format(host.public_hostname) - # TODO: For not write_host is handles both master and nodes. - # Technically only nodes will ever need this. - if not scheduleable: - facts += ' openshift_scheduleable=False' - inventory.write('{} {}\n'.format(host, facts)) - - -def load_system_facts(inventory_file, os_facts_path, env_vars): - """ - Retrieves system facts from the remote systems. - """ - FNULL = open(os.devnull, 'w') - status = subprocess.call(['ansible-playbook', - '--inventory-file={}'.format(inventory_file), - os_facts_path], - env=env_vars, - stdout=FNULL) - if not status == 0: - return [], 1 - callback_facts_file = open(CFG.settings['ansible_callback_facts_yaml'], 'r') - callback_facts = yaml.load(callback_facts_file) - callback_facts_file.close() - return callback_facts, 0 - - -def default_facts(hosts): - global CFG - inventory_file = generate_inventory(hosts) - os_facts_path = '{}/playbooks/byo/openshift_facts.yml'.format(CFG.ansible_playbook_directory) - - facts_env = os.environ.copy() - facts_env["OO_INSTALL_CALLBACK_FACTS_YAML"] = CFG.settings['ansible_callback_facts_yaml'] - facts_env["ANSIBLE_CALLBACK_PLUGINS"] = CFG.settings['ansible_plugins_directory'] - 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 load_system_facts(inventory_file, os_facts_path, facts_env) - - -def run_main_playbook(hosts, hosts_to_run_on): - global CFG - inventory_file = generate_inventory(hosts) - if len(hosts_to_run_on) != len(hosts): - main_playbook_path = os.path.join(CFG.ansible_playbook_directory, - 'playbooks/common/openshift-cluster/scaleup.yml') - else: - main_playbook_path = os.path.join(CFG.ansible_playbook_directory, - 'playbooks/byo/config.yml') - 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(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/src/ooinstall/openshift_ansible.py b/utils/src/ooinstall/openshift_ansible.py new file mode 100644 index 000000000..3306271c8 --- /dev/null +++ b/utils/src/ooinstall/openshift_ansible.py @@ -0,0 +1,145 @@ +# TODO: Temporarily disabled due to importing old code into openshift-ansible +# repo. We will work on these over time. +# pylint: disable=bad-continuation,missing-docstring,no-self-use,invalid-name,global-statement,global-variable-not-assigned + +import subprocess +import os +import yaml +from ooinstall.variants import find_variant + +CFG = None + +def set_config(cfg): + global CFG + CFG = cfg + +def generate_inventory(hosts): + print hosts + global CFG + base_inventory_path = CFG.settings['ansible_inventory_path'] + base_inventory = open(base_inventory_path, 'w') + base_inventory.write('\n[OSEv3:children]\nmasters\nnodes\n') + base_inventory.write('\n[OSEv3:vars]\n') + base_inventory.write('ansible_ssh_user={}\n'.format(CFG.settings['ansible_ssh_user'])) + if CFG.settings['ansible_ssh_user'] != 'root': + base_inventory.write('ansible_sudo=true\n') + + # Find the correct deployment type for ansible: + ver = find_variant(CFG.settings['variant'], + version=CFG.settings.get('variant_version', None))[1] + base_inventory.write('deployment_type={}\n'.format(ver.ansible_key)) + + if 'OO_INSTALL_DEVEL_REGISTRY' in os.environ: + base_inventory.write('oreg_url=rcm-img-docker01.build.eng.bos.redhat.com:' + '5001/openshift3/ose-${component}:${version}\n') + if 'OO_INSTALL_PUDDLE_REPO_ENABLE' in os.environ: + base_inventory.write("openshift_additional_repos=[{'id': 'ose-devel', " + "'name': 'ose-devel', " + "'baseurl': 'http://buildvm-devops.usersys.redhat.com" + "/puddle/build/AtomicOpenShift/3.1/latest/RH7-RHAOS-3.1/$basearch/os', " + "'enabled': 1, 'gpgcheck': 0}]\n") + if 'OO_INSTALL_STAGE_REGISTRY' in os.environ: + base_inventory.write('oreg_url=registry.access.stage.redhat.com/openshift3/ose-${component}:${version}\n') + + base_inventory.write('\n[masters]\n') + masters = (host for host in hosts if host.master) + for master in masters: + write_host(master, base_inventory) + base_inventory.write('\n[nodes]\n') + nodes = (host for host in hosts if host.node) + for node in nodes: + # TODO: Until the Master can run the SDN itself we have to configure the Masters + # as Nodes too. + scheduleable = True + # If there's only one Node and it's also a Master we want it to be scheduleable: + if node in masters and len(masters) != 1: + scheduleable = False + write_host(node, base_inventory, scheduleable) + base_inventory.close() + return base_inventory_path + + +def write_host(host, inventory, scheduleable=True): + global CFG + facts = '' + if host.ip: + facts += ' openshift_ip={}'.format(host.ip) + if host.public_ip: + facts += ' openshift_public_ip={}'.format(host.public_ip) + if host.hostname: + facts += ' openshift_hostname={}'.format(host.hostname) + if host.public_hostname: + facts += ' openshift_public_hostname={}'.format(host.public_hostname) + # TODO: For not write_host is handles both master and nodes. + # Technically only nodes will ever need this. + if not scheduleable: + facts += ' openshift_scheduleable=False' + inventory.write('{} {}\n'.format(host, facts)) + + +def load_system_facts(inventory_file, os_facts_path, env_vars): + """ + Retrieves system facts from the remote systems. + """ + FNULL = open(os.devnull, 'w') + status = subprocess.call(['ansible-playbook', + '--inventory-file={}'.format(inventory_file), + os_facts_path], + env=env_vars, + stdout=FNULL) + if not status == 0: + return [], 1 + callback_facts_file = open(CFG.settings['ansible_callback_facts_yaml'], 'r') + callback_facts = yaml.load(callback_facts_file) + callback_facts_file.close() + return callback_facts, 0 + + +def default_facts(hosts): + global CFG + inventory_file = generate_inventory(hosts) + os_facts_path = '{}/playbooks/byo/openshift_facts.yml'.format(CFG.ansible_playbook_directory) + + facts_env = os.environ.copy() + facts_env["OO_INSTALL_CALLBACK_FACTS_YAML"] = CFG.settings['ansible_callback_facts_yaml'] + facts_env["ANSIBLE_CALLBACK_PLUGINS"] = CFG.settings['ansible_plugins_directory'] + 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 load_system_facts(inventory_file, os_facts_path, facts_env) + + +def run_main_playbook(hosts, hosts_to_run_on): + global CFG + inventory_file = generate_inventory(hosts) + if len(hosts_to_run_on) != len(hosts): + main_playbook_path = os.path.join(CFG.ansible_playbook_directory, + 'playbooks/common/openshift-cluster/scaleup.yml') + else: + main_playbook_path = os.path.join(CFG.ansible_playbook_directory, + 'playbooks/byo/config.yml') + 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(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 1f74b5b15..b183f0acb 100644 --- a/utils/test/cli_installer_tests.py +++ b/utils/test/cli_installer_tests.py @@ -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 @@ -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: @@ -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) @@ -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) @@ -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): @@ -389,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 @@ -413,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 @@ -446,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 -- cgit v1.2.3