diff options
-rw-r--r-- | HOOKS.md | 70 | ||||
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | playbooks/common/openshift-cluster/config.yml | 3 | ||||
-rw-r--r-- | playbooks/common/openshift-cluster/upgrades/upgrade_nodes.yml | 13 | ||||
-rw-r--r-- | roles/docker/tasks/main.yml | 2 | ||||
-rw-r--r-- | roles/openshift_builddefaults/vars/main.yml | 1 | ||||
-rw-r--r-- | roles/openshift_buildoverrides/tasks/main.yml | 9 | ||||
-rw-r--r-- | roles/openshift_buildoverrides/vars/main.yml | 3 | ||||
-rw-r--r-- | roles/openshift_docker_facts/tasks/main.yml | 2 | ||||
-rwxr-xr-x | roles/openshift_facts/library/openshift_facts.py | 29 | ||||
-rw-r--r-- | roles/openshift_metrics/tasks/main.yaml | 7 | ||||
-rwxr-xr-x | roles/os_firewall/library/os_firewall_manage_iptables.py | 4 | ||||
-rw-r--r-- | roles/os_firewall/tasks/firewall/firewalld.yml | 5 |
13 files changed, 133 insertions, 21 deletions
diff --git a/HOOKS.md b/HOOKS.md new file mode 100644 index 000000000..9c5f80054 --- /dev/null +++ b/HOOKS.md @@ -0,0 +1,70 @@ +# Hooks + +The ansible installer allows for operators to execute custom tasks during +specific operations through a system called hooks. Hooks allow operators to +provide files defining tasks to execute before and/or after specific areas +during installations and upgrades. This can be very helpful to validate +or modify custom infrastructure when installing/upgrading OpenShift. + +It is important to remember that when a hook fails the operation fails. This +means a good hook can run multiple times and provide the same results. A great +hook is idempotent. + +**Note**: There is currently not a standard interface for hooks. In the future +a standard interface will be defined and any hooks that existed previously will +need to be updated to meet the new standard. + +## Using Hooks + +Hooks are defined in the ``hosts`` inventory file under the ``OSEv3:vars`` +section. + +Each hook should point to a yaml file which defines Ansible tasks. This file +will be used as an include meaning that the file can not be a playbook but +a set of tasks. Best practice suggests using absolute paths to the hook file to avoid any ambiguity. + +### Example +```ini +[OSEv3:vars] +# <snip> +openshift_master_upgrade_pre_hook=/usr/share/custom/pre_master.yml +openshift_master_upgrade_hook=/usr/share/custom/master.yml +openshift_master_upgrade_post_hook=/usr/share/custom/post_master.yml +# <snip> +``` + +Hook files must be a yaml formatted file that defines a set of Ansible tasks. +The file may **not** be a playbook. + +### Example +```yaml +--- +# Trivial example forcing an operator to ack the start of an upgrade +# file=/usr/share/custom/pre_master.yml + +- name: note the start of a master upgrade + debug: + msg: "Master upgrade of {{ inventory_hostname }} is about to start" + +- name: require an operator agree to start an upgrade + pause: + prompt: "Hit enter to start the master upgrade" +``` + +## Upgrade Hooks + +### openshift_master_upgrade_pre_hook +- Runs **before** each master is upgraded. +- This hook runs against **each master** in serial. +- If a task needs to run against a different host, said task will need to use [``delegate_to`` or ``local_action``](http://docs.ansible.com/ansible/playbooks_delegation.html#delegation). + +### openshift_master_upgrade_hook +- Runs **after** each master is upgraded but **before** it's service/system restart. +- This hook runs against **each master** in serial. +- If a task needs to run against a different host, said task will need to use [``delegate_to`` or ``local_action``](http://docs.ansible.com/ansible/playbooks_delegation.html#delegation). + + +### openshift_master_upgrade_post_hook +- Runs **after** each master is upgraded and has had it's service/system restart. +- This hook runs against **each master** in serial. +- If a task needs to run against a different host, said task will need to use [``delegate_to`` or ``local_action``](http://docs.ansible.com/ansible/playbooks_delegation.html#delegation). @@ -74,6 +74,12 @@ you are not running a stable release. - [OpenShift Enterprise](https://docs.openshift.com/enterprise/latest/install_config/install/advanced_install.html) - [OpenShift Origin](https://docs.openshift.org/latest/install_config/install/advanced_install.html) + +## Installer Hooks + +See the [hooks documentation](HOOKS.md). + + ## Contributing See the [contribution guide](CONTRIBUTING.md). diff --git a/playbooks/common/openshift-cluster/config.yml b/playbooks/common/openshift-cluster/config.yml index 0f226f5f9..a95cb68b7 100644 --- a/playbooks/common/openshift-cluster/config.yml +++ b/playbooks/common/openshift-cluster/config.yml @@ -38,6 +38,9 @@ - set_fact: openshift_docker_log_options: "{{ lookup('oo_option', 'docker_log_options') }}" when: openshift_docker_log_options is not defined + - set_fact: + openshift_docker_selinux_enabled: "{{ lookup('oo_option', 'docker_selinux_enabled') }}" + when: openshift_docker_selinux_enabled is not defined - include: ../openshift-etcd/config.yml tags: diff --git a/playbooks/common/openshift-cluster/upgrades/upgrade_nodes.yml b/playbooks/common/openshift-cluster/upgrades/upgrade_nodes.yml index 86b344d7a..2bb460815 100644 --- a/playbooks/common/openshift-cluster/upgrades/upgrade_nodes.yml +++ b/playbooks/common/openshift-cluster/upgrades/upgrade_nodes.yml @@ -87,6 +87,19 @@ - name: Restart rpm node service service: name="{{ openshift.common.service_type }}-node" state=restarted when: inventory_hostname in groups.oo_nodes_to_upgrade and not openshift.common.is_containerized | bool + + - name: Wait for node to be ready + command: > + {{ hostvars[groups.oo_first_master.0].openshift.common.client_binary }} get node {{ openshift.common.hostname | lower }} --no-headers + register: node_output + delegate_to: "{{ groups.oo_first_master.0 }}" + when: inventory_hostname in groups.oo_nodes_to_upgrade + until: "{{ node_output.stdout.split()[1].startswith('Ready')}}" + # Give the node two minutes to come back online. Note that we pre-pull images now + # so containerized services should restart quickly as well. + retries: 24 + delay: 5 + - name: Set node schedulability command: > {{ hostvars[groups.oo_first_master.0].openshift.common.client_binary }} adm manage-node {{ openshift.node.nodename | lower }} --schedulable=true diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml index a8935370a..66c9cfa0f 100644 --- a/roles/docker/tasks/main.yml +++ b/roles/docker/tasks/main.yml @@ -96,7 +96,7 @@ dest: /etc/sysconfig/docker regexp: '^OPTIONS=.*$' line: "OPTIONS='\ - {% if ansible_selinux and ansible_selinux.status == '''enabled''' %} --selinux-enabled{% endif %}\ + {% if ansible_selinux.status | default(None) == '''enabled''' and docker_selinux_enabled | default(true) %} --selinux-enabled {% endif %}\ {% if docker_log_driver is defined %} --log-driver {{ docker_log_driver }}{% endif %}\ {% if docker_log_options is defined %} {{ docker_log_options | oo_split() | oo_prepend_strings_in_list('--log-opt ') | join(' ')}}{% endif %}\ {% if docker_options is defined %} {{ docker_options }}{% endif %}\ diff --git a/roles/openshift_builddefaults/vars/main.yml b/roles/openshift_builddefaults/vars/main.yml index c9ec3b82f..fe6069ea9 100644 --- a/roles/openshift_builddefaults/vars/main.yml +++ b/roles/openshift_builddefaults/vars/main.yml @@ -23,7 +23,6 @@ builddefaults_yaml: imageLabels: "{{ openshift_builddefaults_image_labels | default(None) }}" nodeSelector: "{{ openshift_builddefaults_nodeselectors | default(None) }}" annotations: "{{ openshift_builddefaults_annotations | default(None) }}" - #resources: "{{ openshift.builddefaults.resources | default(None) }}" resources: requests: cpu: "{{ openshift_builddefaults_resources_requests_cpu | default(None) }}" diff --git a/roles/openshift_buildoverrides/tasks/main.yml b/roles/openshift_buildoverrides/tasks/main.yml index 82fce1c5b..87d0e6f21 100644 --- a/roles/openshift_buildoverrides/tasks/main.yml +++ b/roles/openshift_buildoverrides/tasks/main.yml @@ -1,13 +1,4 @@ --- -#- name: Set buildoverrides -# openshift_facts: -# role: buildoverrides -# local_facts: -# force_pull: "{{ openshift_buildoverrides_force_pull | default(None) }}" -# image_labels: "{{ openshift_buildoverrides_image_labels | default(None) }}" -# nodeselectors: "{{ openshift_buildoverrides_nodeselectors | default(None) }}" -# annotations: "{{ openshift_buildoverrides_annotations | default(None) }}" - - name: Set buildoverrides config structure openshift_facts: role: buildoverrides diff --git a/roles/openshift_buildoverrides/vars/main.yml b/roles/openshift_buildoverrides/vars/main.yml index f0f9c255b..cf49a6ebf 100644 --- a/roles/openshift_buildoverrides/vars/main.yml +++ b/roles/openshift_buildoverrides/vars/main.yml @@ -1,10 +1,11 @@ --- +force_pull: "{{ openshift_buildoverrides_force_pull | default('') }}" buildoverrides_yaml: BuildOverrides: configuration: apiVersion: v1 kind: BuildOverridesConfig - forcePull: "{{ openshift_buildoverrides_force_pull | default('', true) }}" + forcePull: "{{ '' if force_pull == '' else force_pull | bool }}" imageLabels: "{{ openshift_buildoverrides_image_labels | default(None) }}" nodeSelector: "{{ openshift_buildoverrides_nodeselectors | default(None) }}" annotations: "{{ openshift_buildoverrides_annotations | default(None) }}" diff --git a/roles/openshift_docker_facts/tasks/main.yml b/roles/openshift_docker_facts/tasks/main.yml index 613c237a3..049ceffe0 100644 --- a/roles/openshift_docker_facts/tasks/main.yml +++ b/roles/openshift_docker_facts/tasks/main.yml @@ -9,6 +9,7 @@ additional_registries: "{{ openshift_docker_additional_registries | default(None) }}" blocked_registries: "{{ openshift_docker_blocked_registries | default(None) }}" insecure_registries: "{{ openshift_docker_insecure_registries | default(None) }}" + selinux_enabled: "{{ openshift_docker_selinux_enabled | default(None) }}" log_driver: "{{ openshift_docker_log_driver | default(None) }}" log_options: "{{ openshift_docker_log_options | default(None) }}" options: "{{ openshift_docker_options | default(None) }}" @@ -23,6 +24,7 @@ | default(omit) }}" docker_insecure_registries: "{{ openshift.docker.insecure_registries | default(omit) }}" + docker_selinux_enabled: "{{ openshift.docker.selinux_enabled | default(omit) }}" docker_log_driver: "{{ openshift.docker.log_driver | default(omit) }}" docker_log_options: "{{ openshift.docker.log_options | default(omit) }}" docker_push_dockerhub: "{{ openshift.docker.disable_push_dockerhub diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py index 10121f82a..c99452062 100755 --- a/roles/openshift_facts/library/openshift_facts.py +++ b/roles/openshift_facts/library/openshift_facts.py @@ -1690,9 +1690,38 @@ def set_builddefaults_facts(facts): if 'admission_plugin_config' not in facts['master']: facts['master']['admission_plugin_config'] = dict() facts['master']['admission_plugin_config'].update(builddefaults['config']) + # if the user didn't actually provide proxy values, delete the proxy env variable defaults. + delete_empty_keys(facts['master']['admission_plugin_config']['BuildDefaults']['configuration']['env']) + return facts +def delete_empty_keys(keylist): + """ Delete dictionary elements from keylist where "value" is empty. + + Args: + keylist(list): A list of builddefault configuration envs. + + Returns: + none + + Example: + keylist = [{'name': 'HTTP_PROXY', 'value': 'http://file.rdu.redhat.com:3128'}, + {'name': 'HTTPS_PROXY', 'value': 'http://file.rdu.redhat.com:3128'}, + {'name': 'NO_PROXY', 'value': ''}] + + After calling delete_empty_keys the provided list is modified to become: + + [{'name': 'HTTP_PROXY', 'value': 'http://file.rdu.redhat.com:3128'}, + {'name': 'HTTPS_PROXY', 'value': 'http://file.rdu.redhat.com:3128'}] + """ + count = 0 + for i in range(0, len(keylist)): + if len(keylist[i - count]['value']) == 0: + del keylist[i - count] + count += 1 + + def set_buildoverrides_facts(facts): """ Set build overrides diff --git a/roles/openshift_metrics/tasks/main.yaml b/roles/openshift_metrics/tasks/main.yaml index c42440130..1808db5d5 100644 --- a/roles/openshift_metrics/tasks/main.yaml +++ b/roles/openshift_metrics/tasks/main.yaml @@ -7,6 +7,7 @@ - name: Create temp directory for all our templates file: path={{mktemp.stdout}}/templates state=directory mode=0755 changed_when: False + when: "{{ openshift_metrics_install_metrics | bool }}" - name: Copy the admin client config(s) command: > @@ -15,8 +16,4 @@ check_mode: no tags: metrics_init -- include: install_metrics.yaml - when: openshift_metrics_install_metrics | default(false) | bool - -- include: uninstall_metrics.yaml - when: not openshift_metrics_install_metrics | default(false) | bool +- include: "{{ (openshift_metrics_install_metrics | bool) | ternary('install_metrics.yaml','uninstall_metrics.yaml') }}" diff --git a/roles/os_firewall/library/os_firewall_manage_iptables.py b/roles/os_firewall/library/os_firewall_manage_iptables.py index 4ba38b721..8d4878fa7 100755 --- a/roles/os_firewall/library/os_firewall_manage_iptables.py +++ b/roles/os_firewall/library/os_firewall_manage_iptables.py @@ -224,8 +224,8 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes def gen_cmd(self): cmd = 'iptables' if self.ip_version == 'ipv4' else 'ip6tables' # Include -w (wait for xtables lock) in default arguments. - default_args = '-w' - return ["/usr/sbin/%s %s" % (cmd, default_args)] + default_args = ['-w'] + return ["/usr/sbin/%s" % cmd] + default_args def gen_save_cmd(self): # pylint: disable=no-self-use return ['/usr/libexec/iptables/iptables.init', 'save'] diff --git a/roles/os_firewall/tasks/firewall/firewalld.yml b/roles/os_firewall/tasks/firewall/firewalld.yml index 1101870be..c4db197ca 100644 --- a/roles/os_firewall/tasks/firewall/firewalld.yml +++ b/roles/os_firewall/tasks/firewall/firewalld.yml @@ -1,7 +1,8 @@ --- - name: Install firewalld packages - package: name=firewalld state=present - when: not openshift.common.is_containerized | bool + package: + name: firewalld + state: present - name: Ensure iptables services are not enabled systemd: |