From e9680cc1020f9c54221993b3ae816b046d92bafc Mon Sep 17 00:00:00 2001
From: Jason DeTiberus <jdetiber@redhat.com>
Date: Thu, 5 Nov 2015 15:42:30 -0500
Subject: Additional upgrade enhancements

- rework the version checking
- provide better safety if the apiLevel attributes are missing
- ensure a list of api levels are present
- remove a list of api levels
- pylint fixes
---
 playbooks/adhoc/upgrades/files/versions.sh         |  8 ++
 .../upgrades/library/openshift_upgrade_config.py   | 92 ++++++++++++++++------
 playbooks/adhoc/upgrades/upgrade.yml               | 73 ++++++-----------
 3 files changed, 101 insertions(+), 72 deletions(-)
 create mode 100644 playbooks/adhoc/upgrades/files/versions.sh

(limited to 'playbooks/adhoc/upgrades')

diff --git a/playbooks/adhoc/upgrades/files/versions.sh b/playbooks/adhoc/upgrades/files/versions.sh
new file mode 100644
index 000000000..01ea1d91a
--- /dev/null
+++ b/playbooks/adhoc/upgrades/files/versions.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+yum_installed=$(yum list installed "$@" | tail -n +2 | grep -v 'Installed Packages' | grep -v 'Red Hat Subscription Management' | awk '{ print $2 }' | tr '\n' ' ')
+yum_available=$(yum list available "$@" | tail -n +2 | grep -v 'Available Packages' | grep -v 'Red Hat Subscription Management' | grep -v 'el7ose' | awk '{ print $2 }' | tr '\n' ' ')
+
+echo "---"
+echo "curr_version: ${yum_installed}" 
+echo "avail_version: ${yum_available}"
diff --git a/playbooks/adhoc/upgrades/library/openshift_upgrade_config.py b/playbooks/adhoc/upgrades/library/openshift_upgrade_config.py
index 0894efa52..33eb40d7d 100755
--- a/playbooks/adhoc/upgrades/library/openshift_upgrade_config.py
+++ b/playbooks/adhoc/upgrades/library/openshift_upgrade_config.py
@@ -17,8 +17,40 @@ requirements: [ ]
 EXAMPLES = '''
 '''
 
+def modify_api_levels(level_list, remove, ensure, msg_prepend='',
+                      msg_append=''):
+    """ modify_api_levels """
+    changed = False
+    changes = []
+
+    if not isinstance(remove, list):
+        remove = []
+
+    if not isinstance(ensure, list):
+        ensure = []
+
+    if not isinstance(level_list, list):
+        new_list = []
+        changed = True
+        changes.append("%s created missing %s" % (msg_prepend, msg_append))
+    else:
+        new_list = level_list
+        for level in remove:
+            if level in new_list:
+                new_list.remove(level)
+                changed = True
+                changes.append("%s removed %s %s" % (msg_prepend, level, msg_append))
+
+    for level in ensure:
+        if level not in new_list:
+            new_list.append(level)
+            changed = True
+            changes.append("%s added %s %s" % (msg_prepend, level, msg_append))
 
-def upgrade_master_3_0_to_3_1(module, config_base, backup):
+    return {'new_list': new_list, 'changed': changed, 'changes': changes}
+
+
+def upgrade_master_3_0_to_3_1(ansible_module, config_base, backup):
     """Main upgrade method for 3.0 to 3.1."""
     changes = []
 
@@ -30,30 +62,38 @@ def upgrade_master_3_0_to_3_1(module, config_base, backup):
     config = yaml.safe_load(master_cfg_file.read())
     master_cfg_file.close()
 
-    # Remove v1beta3 from apiLevels:
-    if 'apiLevels' in config and \
-        'v1beta3' in config['apiLevels']:
-        config['apiLevels'].remove('v1beta3')
-        changed = True
-        changes.append("master-config.yaml: removed v1beta3 from apiLevels")
-    if 'apiLevels' in config['kubernetesMasterConfig'] and \
-        'v1beta3' in config['kubernetesMasterConfig']['apiLevels']:
-        config['kubernetesMasterConfig']['apiLevels'].remove('v1beta3')
-        changed = True
 
-    # Add the new master proxy client certs:
-    # TODO: re-enable this once these certs are generated during upgrade:
-#    if 'proxyClientInfo' not in config['kubernetesMasterConfig']:
-#        config['kubernetesMasterConfig']['proxyClientInfo'] = {
-#            'certFile': 'master.proxy-client.crt',
-#            'keyFile': 'master.proxy-client.key'
-#       }
-#        changes.append("master-config.yaml: added proxyClientInfo")
+    # Remove unsupported api versions and ensure supported api versions from
+    # master config
+    unsupported_levels = ['v1beta1', 'v1beta2', 'v1beta3']
+    supported_levels = ['v1']
+
+    result = modify_api_levels(config.get('apiLevels'), unsupported_levels,
+                               supported_levels, 'master-config.yaml:', 'from apiLevels')
+    if result['changed']:
+        config['apiLevels'] = result['new_list']
+        changes.append(result['changes'])
+
+    if 'kubernetesMasterConfig' in config:
+        result = modify_api_levels(config['kubernetesMasterConfig'].get('apiLevels'),
+                                   unsupported_levels, supported_levels, 'master-config.yaml:',
+                                   'from apiLevels')
+        if result['changed']:
+            config['kubernetesMasterConfig']['apiLevels'] = result['new_list']
+            changes.append(result['changes'])
+
+    # Add proxyClientInfo to master-config
+    if 'proxyClientInfo' not in config['kubernetesMasterConfig']:
+        config['kubernetesMasterConfig']['proxyClientInfo'] = {
+            'certFile': 'master.proxy-client.crt',
+            'keyFile': 'master.proxy-client.key'
+        }
+        changes.append("master-config.yaml: added proxyClientInfo")
 
     if len(changes) > 0:
         if backup:
             # TODO: Check success:
-            module.backup_local(master_config)
+            ansible_module.backup_local(master_config)
 
         # Write the modified config:
         out_file = open(master_config, 'w')
@@ -63,18 +103,19 @@ def upgrade_master_3_0_to_3_1(module, config_base, backup):
     return changes
 
 
-def upgrade_master(module, config_base, from_version, to_version, backup):
+def upgrade_master(ansible_module, config_base, from_version, to_version, backup):
     """Upgrade entry point."""
     if from_version == '3.0':
         if to_version == '3.1':
-            return upgrade_master_3_0_to_3_1(module, config_base, backup)
+            return upgrade_master_3_0_to_3_1(ansible_module, config_base, backup)
 
 
 def main():
     """ main """
     # disabling pylint errors for global-variable-undefined and invalid-name
     # for 'global module' usage, since it is required to use ansible_facts
-    # pylint: disable=global-variable-undefined, invalid-name
+    # pylint: disable=global-variable-undefined, invalid-name,
+    # redefined-outer-name
     global module
 
     module = AnsibleModule(
@@ -98,10 +139,13 @@ def main():
         changes = []
         if role == 'master':
             changes = upgrade_master(module, config_base, from_version,
-                to_version, backup)
+                                     to_version, backup)
 
         changed = len(changes) > 0
         return module.exit_json(changed=changed, changes=changes)
+
+    # ignore broad-except error to avoid stack trace to ansible user
+    # pylint: disable=broad-except
     except Exception, e:
         return module.fail_json(msg=str(e))
 
diff --git a/playbooks/adhoc/upgrades/upgrade.yml b/playbooks/adhoc/upgrades/upgrade.yml
index d9abff040..3b3609dca 100644
--- a/playbooks/adhoc/upgrades/upgrade.yml
+++ b/playbooks/adhoc/upgrades/upgrade.yml
@@ -87,50 +87,29 @@
       local_facts:
         deployment_type: "{{ deployment_type }}"
 
-- name: Upgrade base package on masters
-  hosts: masters
-  roles:
-  - openshift_facts
-  vars:
-    openshift_version: "{{ openshift_pkg_version | default('') }}"
-  tasks:
-    - name: Upgrade base package
-      yum:
-        pkg: "{{ openshift.common.service_type }}{{ openshift_version  }}"
-        state: latest
-
-# TODO: ideally we would check the new version, without installing it. (some
-# kind of yum repoquery? would need to handle openshift -> atomic-openshift
-# package rename)
 
 - name: Perform upgrade version checking
   hosts: masters[0]
   tasks:
-    - name: Determine available version
-      shell: >
-        yum list available {{ openshift.common.service_type }} | tail -n 1 | cut -f 2 -d " " | cut -f 1 -d "-"
-      register: _new_version
-    - debug: var=_new_version
-    # The above check will return nothing if the package is already installed,
-    # and we may be re-running upgrade due to a failure.
-    - name: Determine installed version
-      command: >
-        rpm -q --queryformat '%{version}' {{ openshift.common.service_type }}
-      register: _new_version
-      when: _new_version.stdout == ""
-    # Fail if we still don't know:
-    - debug: var=_new_version
-    - name: Verify upgrade version
-      fail: Unable to determine upgrade version for {{ openshift.common.service_type }}
-      when: _new_version.stdout == ""
-
-  - fail:
-      msg: This playbook requires Atomic OpenShift 3.0.2 or later
-    when: deployment_type in ['openshift_enterprise', 'atomic-enterprise'] and g_new_version.stdout | version_compare('3.0','>=') and g_new_version.stdout | version_compare('3.0.2','<')
-
-  - fail:
-      msg: This playbook requires Origin 1.0.6 or later
-    when: deployment_type == 'origin'
+  - name: Clean yum cache
+    command: yum clean all
+
+  - name: Determine available versions
+    script: files/versions.sh {{ openshift.common.service_type }} openshift
+    register: g_versions_result
+
+  - set_fact:
+      g_aos_versions: "{{ g_versions_result.stdout | from_yaml }}"
+
+  - set_fact:
+      g_new_version: "{{ g_aos_versions.curr_version.split('-', 1).0 if g_aos_versions.avail_version is none else g_aos_versions.avail_version.split('-', 1).0 }}"
+
+  - fail: This playbook requires Origin 1.0.6 or later
+    when: deployment_type == 'origin' and g_aos_versions.curr_version | version_compare('1.0.6','<')
+
+  - fail: This playbook requires Atomic OpenShift 3.0.2 or later
+    when: deployment_type in ['openshift-enterprise', 'atomic-openshift'] and g_aos_versions.curr_version | version_compare('3.0.2','<')
+
 
 - name: Upgrade masters
   hosts: masters
@@ -142,10 +121,6 @@
         pkg: kernel
         state: latest
 
-    - name: display just the deployment_type variable for the current host
-      debug:
-        var: hostvars[inventory_hostname].openshift.common.deployment_type
-
     - name: Upgrade master packages
       command: yum update -y {{ openshift.common.service_type }}-master{{ openshift_version }}
 
@@ -154,6 +129,8 @@
         pkg: python-yaml
         state: installed
 
+    - debug: var=hostvars[inventory_hostname].openshift.common.config_base
+
     - name: Upgrade master configuration
       openshift_upgrade_config:
         from_version: '3.0'
@@ -253,8 +230,8 @@
 - name: Update cluster policy and policy bindings
   hosts: masters[0]
   vars:
-    origin_reconcile_bindings: "{{ deployment_type == 'origin' and gg_new_version.stdout | version_compare('1.0.6', '>') }}"
-    ent_reconcile_bindings: "{{ deployment_type in ['openshift-enterprise', 'atomic-enterprise'] and gg_new_version.stdout | version_compare('3.0.2','>') }}"
+    origin_reconcile_bindings: "{{ deployment_type == 'origin' and g_new_version | version_compare('1.0.6', '>') }}"
+    ent_reconcile_bindings: "{{ deployment_type in ['openshift-enterprise', 'atomic-enterprise'] and g_new_version | version_compare('3.0.2','>') }}"
   tasks:
     - name: oadm policy reconcile-cluster-roles --confirm
       command: >
@@ -282,8 +259,8 @@
 - name: Upgrade default router and registry
   hosts: masters[0]
   vars:
-    - registry_image: "{{  openshift.master.registry_url | replace( '${component}', 'docker-registry' )  | replace ( '${version}', 'v' + g_new_version.stdout  ) }}"
-    - router_image: "{{ openshift.master.registry_url | replace( '${component}', 'haproxy-router' ) | replace ( '${version}', 'v' + g_new_version.stdout ) }}"
+    - registry_image: "{{  openshift.master.registry_url | replace( '${component}', 'docker-registry' )  | replace ( '${version}', 'v' + g_new_version  ) }}"
+    - router_image: "{{ openshift.master.registry_url | replace( '${component}', 'haproxy-router' ) | replace ( '${version}', 'v' + g_new_version ) }}"
     - oc_cmd: "{{ openshift.common.client_binary }} --config={{ openshift.common.config_base }}/master/admin.kubeconfig"
   tasks:
     - name: Check for default router
-- 
cgit v1.2.3