Browse Source

Merge branch 'upgrade' into config-upgrade

Devan Goodwin 9 years ago
parent
commit
d608d84361

+ 2 - 0
openshift-ansible.spec

@@ -230,6 +230,8 @@ BuildArch:     noarch
 %package -n atomic-openshift-utils
 Summary:       Atomic OpenShift Utilities
 BuildRequires: python-setuptools
+Requires:      openshift-ansible-playbooks
+Requires:      openshift-ansible-roles
 Requires:      ansible
 Requires:      python-click
 Requires:      python-setuptools

+ 43 - 0
playbooks/adhoc/upgrades/upgrade.yml

@@ -1,4 +1,45 @@
 ---
+- name: Verify upgrade can proceed
+  hosts: masters
+  tasks:
+  # Checking the global deployment type rather than host facts, this is about
+  # what the user is requesting.
+    - fail: msg="Deployment type enterprise not supported for upgrade"
+      when: deployment_type == "enterprise"
+
+- name: Backup etcd
+  hosts: masters
+  vars:
+    embedded_etcd: "{{ openshift.master.embedded_etcd }}"
+    timestamp: "{{ lookup('pipe', 'date +%Y%m%d%H%M%S') }}"
+  roles:
+  - openshift_facts
+  tasks:
+  - stat: path=/var/lib/openshift
+    register: var_lib_openshift
+  - name: Create origin symlink if necessary
+    file: src=/var/lib/openshift/ dest=/var/lib/origin state=link
+    when: var_lib_openshift.stat.exists == True
+  - name: Check available disk space for etcd backup
+    # We assume to be using the data dir for all backups.
+    shell: >
+      df --output=avail -k {{ openshift.common.data_dir }} | tail -n 1
+    register: avail_disk
+
+  - name: Check current embedded etcd disk usage
+    shell: >
+      du -k {{ openshift.master.etcd_data_dir }} | tail -n 1 | cut -f1
+    register: etcd_disk_usage
+    when: embedded_etcd | bool
+
+  - name: Abort if insufficient disk space for etcd backup
+    fail: msg="{{ etcd_disk_usage.stdout }} Kb disk space required for etcd backup, {{ avail_disk.stdout }} Kb available."
+    when: (embedded_etcd | bool) and (etcd_disk_usage.stdout|int > avail_disk.stdout|int)
+  - name: Install etcd (for etcdctl)
+    yum: pkg=etcd state=latest
+  - name: Generate etcd backup
+    command: etcdctl backup --data-dir={{ openshift.master.etcd_data_dir }} --backup-dir={{ openshift.common.data_dir }}/etcd-backup-{{ timestamp }}
+
 - name: Upgrade base package on masters
   hosts: masters
   roles:
@@ -23,6 +64,8 @@
   vars:
     openshift_version: "{{ openshift_pkg_version | default('') }}"
   tasks:
+    - name: Upgrade to latest available kernel
+      yum: pkg=kernel state=latest
     - name: Upgrade master packages
       yum: pkg={{ openshift.common.service_type }}-master{{ openshift_version }} state=latest
     - name: Restart master services

+ 6 - 0
roles/openshift_facts/library/openshift_facts.py

@@ -493,6 +493,12 @@ def set_aggregate_facts(facts):
             if 'cluster_public_hostname' in facts['master']:
                 all_hostnames.add(facts['master']['cluster_public_hostname'])
 
+            if facts['master']['embedded_etcd']:
+                facts['master']['etcd_data_dir'] = os.path.join(
+                    facts['common']['data_dir'], 'openshift.local.etcd')
+            else:
+                facts['master']['etcd_data_dir'] = '/var/lib/etcd'
+
         facts['common']['all_hostnames'] = list(all_hostnames)
 
     return facts

+ 5 - 0
utils/docs/config.md

@@ -7,6 +7,7 @@ The default location this config file will be written to ~/.config/openshift/ins
 ## Example
 
 ```
+version: v1
 variant: openshift-enterprise
 variant_version: 3.0
 ansible_ssh_user: root
@@ -32,6 +33,10 @@ hosts:
 
 ## Primary Settings
 
+### version
+
+Indicates the version of configuration this file was written with. Current implementation is v1.
+
 ### variant
 
 The OpenShift variant to install. Currently valid options are:

+ 1 - 1
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',
         ],
     },
 )

+ 130 - 40
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:
@@ -190,7 +191,7 @@ Notes:
     facts_confirmed = click.confirm("Do the above facts look correct?")
     if not facts_confirmed:
         message = """
-Edit %s with the desired values and rerun oo-install with --unattended .
+Edit %s with the desired values and re-run with --unattended .
 """ % oo_cfg.config_path
         click.echo(message)
         # Make sure we actually write out the config file.
@@ -367,58 +368,142 @@ 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
+    ctx.obj['oo_cfg'] = oo_cfg
     install_transactions.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)
+
+    install_transactions.run_uninstall_playbook()
+
+
+@click.command()
+@click.pass_context
+def upgrade(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)
+
+    # Update config to reflect the version we're targetting, we'll write
+    # to disk once ansible completes successfully, not before.
+    old_variant = oo_cfg.settings['variant']
+    old_version = oo_cfg.settings['variant_version']
+    if oo_cfg.settings['variant'] == 'enterprise':
+        oo_cfg.settings['variant'] = 'openshift-enterprise'
+    version = find_variant(oo_cfg.settings['variant'])[0]
+    oo_cfg.settings['variant_version'] = version.name
+    click.echo("Openshift will be upgraded from %s %s to %s %s on the following hosts:\n" % (
+        old_variant, old_version, oo_cfg.settings['variant'],
+        oo_cfg.settings['variant_version']))
+    for host in oo_cfg.hosts:
+        click.echo("  * %s" % host.name)
+
+    if not ctx.obj['unattended']:
+        # Prompt interactively to confirm:
+        proceed = click.confirm("\nDo you wish to proceed?")
+        if not proceed:
+            click.echo("Upgrade cancelled.")
+            sys.exit(0)
+
+    retcode = install_transactions.run_upgrade_playbook()
+    if retcode > 0:
+        click.echo("Errors encountered during upgrade, please check %s." %
+            oo_cfg.settings['ansible_log_path'])
+    else:
+        click.echo("Upgrade completed! Rebooting all hosts is recommended.")
+
+
+@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)
@@ -430,8 +515,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 +533,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 +559,11 @@ http://docs.openshift.com/enterprise/latest/admin_guide/overview.html
         click.echo(message)
         click.pause()
 
+cli.add_command(install)
+cli.add_command(upgrade)
+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={})

+ 26 - 1
utils/src/ooinstall/install_transactions.py

@@ -14,7 +14,6 @@ def set_config(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')
@@ -126,8 +125,34 @@ 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)
+
+
+def run_upgrade_playbook():
+    playbook = os.path.join(CFG.settings['ansible_playbook_directory'],
+        'playbooks/adhoc/upgrades/upgrade.yml')
+    # TODO: Upgrade inventory for upgrade?
+    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)
+

+ 34 - 10
utils/src/ooinstall/oo_config.py

@@ -12,6 +12,7 @@ PERSIST_SETTINGS = [
     'ansible_log_path',
     'variant',
     'variant_version',
+    'version',
     ]
 REQUIRED_FACTS = ['ip', 'public_ip', 'hostname', 'public_hostname']
 
@@ -73,7 +74,6 @@ class Host(object):
 
 
 class OOConfig(object):
-    new_config = True
     default_dir = os.path.normpath(
         os.environ.get('XDG_CONFIG_HOME',
                        os.environ['HOME'] + '/.config/') + '/openshift/')
@@ -86,19 +86,22 @@ class OOConfig(object):
             self.config_path = os.path.normpath(self.default_dir +
                                                 self.default_file)
         self.settings = {}
-        self.read_config()
-        self.set_defaults()
+        self._read_config()
+        self._set_defaults()
 
-    def read_config(self, is_new=False):
+    def _read_config(self):
         self.hosts = []
         try:
-            new_settings = None
             if os.path.exists(self.config_path):
                 cfgfile = open(self.config_path, 'r')
-                new_settings = yaml.safe_load(cfgfile.read())
+                self.settings = yaml.safe_load(cfgfile.read())
                 cfgfile.close()
-            if new_settings:
-                self.settings = new_settings
+
+                # Use the presence of a Description as an indicator this is
+                # a legacy config file:
+                if 'Description' in self.settings:
+                    self._upgrade_legacy_config()
+
                 # Parse the hosts into DTO objects:
                 if 'hosts' in self.settings:
                     for host in self.settings['hosts']:
@@ -114,9 +117,28 @@ class OOConfig(object):
                                                                               ferr.strerror))
         except yaml.scanner.ScannerError:
             raise OOConfigFileError('Config file "{}" is not a valid YAML document'.format(self.config_path))
-        self.new_config = is_new
 
-    def set_defaults(self):
+    def _upgrade_legacy_config(self):
+        new_hosts = []
+        if 'validated_facts' in self.settings:
+            for key, value in self.settings['validated_facts'].iteritems():
+                if 'masters' in self.settings and key in self.settings['masters']:
+                    value['master'] = True
+                if 'nodes' in self.settings and key in self.settings['nodes']:
+                    value['node'] = True
+                new_hosts.append(value)
+        self.settings['hosts'] = new_hosts
+
+        remove_settings = ['validated_facts', 'Description', 'Name',
+            'Subscription', 'Vendor', 'Version', 'masters', 'nodes']
+        for s in remove_settings:
+            del self.settings[s]
+
+        # A legacy config implies openshift-enterprise 3.0:
+        self.settings['variant'] = 'openshift-enterprise'
+        self.settings['variant_version'] = '3.0'
+
+    def _set_defaults(self):
 
         if 'ansible_inventory_directory' not in self.settings:
             self.settings['ansible_inventory_directory'] = \
@@ -125,6 +147,8 @@ class OOConfig(object):
             os.makedirs(self.settings['ansible_inventory_directory'])
         if 'ansible_plugins_directory' not in self.settings:
             self.settings['ansible_plugins_directory'] = resource_filename(__name__, 'ansible_plugins')
+        if 'version' not in self.settings:
+            self.settings['version'] = 'v1'
 
         if 'ansible_callback_facts_yaml' not in self.settings:
             self.settings['ansible_callback_facts_yaml'] = '%s/callback_facts.yaml' % \

+ 4 - 1
utils/src/ooinstall/variants.py

@@ -29,6 +29,9 @@ class Variant(object):
 
         self.versions = versions
 
+    def latest_version(self):
+        return self.versions[-1]
+
 
 # WARNING: Keep the versions ordered, most recent last:
 OSE = Variant('openshift-enterprise', 'OpenShift Enterprise',
@@ -58,7 +61,7 @@ def find_variant(name, version=None):
     for prod in SUPPORTED_VARIANTS:
         if prod.name == name:
             if version is None:
-                return (prod, prod.versions[-1])
+                return (prod, prod.latest_version())
             for v in prod.versions:
                 if v.name == version:
                     return (prod, v)

+ 17 - 13
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)

+ 64 - 0
utils/test/oo_config_tests.py

@@ -32,6 +32,26 @@ hosts:
     node: true
 """
 
+# Used to test automatic upgrading of config:
+LEGACY_CONFIG = """
+Description: This is the configuration file for the OpenShift Ansible-Based Installer.
+Name: OpenShift Ansible-Based Installer Configuration
+Subscription: {type: none}
+Vendor: OpenShift Community
+Version: 0.0.1
+ansible_config: /tmp/notreal/ansible.cfg
+ansible_inventory_directory: /tmp/notreal/.config/openshift/.ansible
+ansible_log_path: /tmp/ansible.log
+ansible_plugins_directory: /tmp/notreal/.python-eggs/ooinstall-3.0.0-py2.7.egg-tmp/ooinstall/ansible_plugins
+masters: [10.0.0.1]
+nodes: [10.0.0.2, 10.0.0.3]
+validated_facts:
+  10.0.0.1: {hostname: master-private.example.com, ip: 10.0.0.1, public_hostname: master.example.com, public_ip: 24.222.0.1}
+  10.0.0.2: {hostname: node1-private.example.com, ip: 10.0.0.2, public_hostname: node1.example.com, public_ip: 24.222.0.2}
+  10.0.0.3: {hostname: node2-private.example.com, ip: 10.0.0.3, public_hostname: node2.example.com, public_ip: 24.222.0.3}
+"""
+
+
 CONFIG_INCOMPLETE_FACTS = """
 hosts:
   - ip: 10.0.0.1
@@ -74,6 +94,48 @@ class OOInstallFixture(unittest.TestCase):
         return path
 
 
+class LegacyOOConfigTests(OOInstallFixture):
+
+    def setUp(self):
+        OOInstallFixture.setUp(self)
+        self.cfg_path = self.write_config(os.path.join(self.work_dir,
+            'ooinstall.conf'), LEGACY_CONFIG)
+        self.cfg = OOConfig(self.cfg_path)
+
+    def test_load_config_memory(self):
+        self.assertEquals('openshift-enterprise', self.cfg.settings['variant'])
+        self.assertEquals('3.0', self.cfg.settings['variant_version'])
+        self.assertEquals('v1', self.cfg.settings['version'])
+
+        self.assertEquals(3, len(self.cfg.hosts))
+        h1 = self.cfg.get_host('10.0.0.1')
+        self.assertEquals('10.0.0.1', h1.ip)
+        self.assertEquals('24.222.0.1', h1.public_ip)
+        self.assertEquals('master-private.example.com', h1.hostname)
+        self.assertEquals('master.example.com', h1.public_hostname)
+
+        h2 = self.cfg.get_host('10.0.0.2')
+        self.assertEquals('10.0.0.2', h2.ip)
+        self.assertEquals('24.222.0.2', h2.public_ip)
+        self.assertEquals('node1-private.example.com', h2.hostname)
+        self.assertEquals('node1.example.com', h2.public_hostname)
+
+        h3 = self.cfg.get_host('10.0.0.3')
+        self.assertEquals('10.0.0.3', h3.ip)
+        self.assertEquals('24.222.0.3', h3.public_ip)
+        self.assertEquals('node2-private.example.com', h3.hostname)
+        self.assertEquals('node2.example.com', h3.public_hostname)
+
+        self.assertFalse('masters' in self.cfg.settings)
+        self.assertFalse('nodes' in self.cfg.settings)
+        self.assertFalse('Description' in self.cfg.settings)
+        self.assertFalse('Name' in self.cfg.settings)
+        self.assertFalse('Subscription' in self.cfg.settings)
+        self.assertFalse('Vendor' in self.cfg.settings)
+        self.assertFalse('Version' in self.cfg.settings)
+        self.assertFalse('validates_facts' in self.cfg.settings)
+
+
 class OOConfigTests(OOInstallFixture):
 
     def test_load_config(self):
@@ -91,6 +153,7 @@ class OOConfigTests(OOInstallFixture):
                           [host['ip'] for host in ooconfig.settings['hosts']])
 
         self.assertEquals('openshift-enterprise', ooconfig.settings['variant'])
+        self.assertEquals('v1', ooconfig.settings['version'])
 
     def test_load_complete_facts(self):
         cfg_path = self.write_config(os.path.join(self.work_dir,
@@ -128,6 +191,7 @@ class OOConfigTests(OOInstallFixture):
 
         self.assertTrue('ansible_ssh_user' in written_config)
         self.assertTrue('variant' in written_config)
+        self.assertEquals('v1', written_config['version'])
 
         # Some advanced settings should not get written out if they
         # were not specified by the user: