diff options
31 files changed, 657 insertions, 115 deletions
diff --git a/.tito/packages/openshift-ansible b/.tito/packages/openshift-ansible index 271e86d20..d397467cb 100644 --- a/.tito/packages/openshift-ansible +++ b/.tito/packages/openshift-ansible @@ -1 +1 @@ -3.0.28-1 ./ +3.0.34-1 ./ diff --git a/README_AWS.md b/README_AWS.md index f8ecaec49..c605de43d 100644 --- a/README_AWS.md +++ b/README_AWS.md @@ -51,7 +51,7 @@ to setup a private key file to allow ansible to connect to the created hosts. To do so, add the the following entry to your $HOME/.ssh/config file and make it point to the private key file which allows you to login on AWS. ``` Host *.compute-1.amazonaws.com - PrivateKey $HOME/.ssh/my_private_key.pem + IdentityFile $HOME/.ssh/my_private_key.pem ``` Alternatively, you can configure your ssh-agent to hold the credentials to connect to your AWS instances. @@ -16,6 +16,7 @@ Options: -c CLUSTER, --cluster CLUSTER which cluster to use -e ENV, --env ENV which environment to use + --v3 When working with v3 environments. v2 by default -t HOST_TYPE, --host-type HOST_TYPE which host type to use --list-host-types list all of the host types @@ -72,6 +72,8 @@ class Ossh(object): parser.add_argument('-o', '--ssh_opts', action='store', help='options to pass to SSH.\n \ "-oForwardX11=yes,TCPKeepAlive=yes"') + parser.add_argument('-A', default=False, action="store_true", + help='Forward authentication agent') parser.add_argument('host', nargs='?', default='') self.args = parser.parse_args() @@ -177,6 +179,9 @@ class Ossh(object): if self.user: ssh_args.append('-l%s' % self.user) + if self.args.A: + ssh_args.append('-A') + if self.args.verbose: ssh_args.append('-vvv') diff --git a/docs/best_practices_guide.adoc b/docs/best_practices_guide.adoc index 6b744333c..267aa850d 100644 --- a/docs/best_practices_guide.adoc +++ b/docs/best_practices_guide.adoc @@ -13,9 +13,12 @@ This guide complies with https://www.ietf.org/rfc/rfc2119.txt[RFC2119]. == Pull Requests + + +[[All-pull-requests-MUST-pass-the-build-bot-before-they-are-merged]] [cols="2v,v"] |=== -| **Rule** +| <<All-pull-requests-MUST-pass-the-build-bot-before-they-are-merged, Rule>> | All pull requests MUST pass the build bot *before* they are merged. |=== @@ -30,9 +33,10 @@ The tooling is flexible enough that exceptions can be made so that the tool the === Python Source Files ''' +[[Python-source-files-MUST-contain-the-following-vim-mode-line]] [cols="2v,v"] |=== -| **Rule** +| <<Python-source-files-MUST-contain-the-following-vim-mode-line, Rule>> | Python source files MUST contain the following vim mode line. |=== @@ -48,9 +52,10 @@ If mode lines for other editors are needed, please open a GitHub issue. === Method Signatures ''' +[[When-adding-a-new-paramemter-to-an-existing-method-a-default-value-SHOULD-be-used]] [cols="2v,v"] |=== -| **Rule** +| <<When-adding-a-new-paramemter-to-an-existing-method-a-default-value-SHOULD-be-used, Rule>> | When adding a new paramemter to an existing method, a default value SHOULD be used |=== The purpose of this rule is to make it so that method signatures are backwards compatible. @@ -74,18 +79,20 @@ def add_person(first_name, last_name, age=None): http://www.pylint.org/[PyLint] is used in an attempt to keep the python code as clean and as managable as possible. The build bot runs each pull request through PyLint and any warnings or errors cause the build bot to fail the pull request. ''' +[[PyLint-rules-MUST-NOT-be-disabled-on-a-whole-file]] [cols="2v,v"] |=== -| **Rule** +| <<PyLint-rules-MUST-NOT-be-disabled-on-a-whole-file, Rule>> | PyLint rules MUST NOT be disabled on a whole file. |=== Instead, http://docs.pylint.org/faq.html#is-it-possible-to-locally-disable-a-particular-message[disable the PyLint check on the line where PyLint is complaining]. ''' +[[PyLint-rules-MUST-NOT-be-disabled-unless-they-meet-one-of-the-following-exceptions]] [cols="2v,v"] |=== -| **Rule** +| <<PyLint-rules-MUST-NOT-be-disabled-unless-they-meet-one-of-the-following-exceptions, Rule>> | PyLint rules MUST NOT be disabled unless they meet one of the following exceptions |=== @@ -95,9 +102,10 @@ Instead, http://docs.pylint.org/faq.html#is-it-possible-to-locally-disable-a-par 1. When PyLint fails, but the code makes more sense the way it is formatted (stylistic exception). For this exception, the description of the PyLint disable MUST state why the code is more clear, AND the person reviewing the PR will decide if they agree or not. The reviewer may reject the PR if they disagree with the reason for the disable. ''' +[[All-PyLint-rule-disables-MUST-be-documented-in-the-code]] [cols="2v,v"] |=== -| **Rule** +| <<All-PyLint-rule-disables-MUST-be-documented-in-the-code, Rule>> | All PyLint rule disables MUST be documented in the code. |=== @@ -124,9 +132,10 @@ metadata[line] = results.pop() === Yaml Files (Playbooks, Roles, Vars, etc) ''' +[[Ansible-files-SHOULD-NOT-use-JSON-use-pure-YAML-instead]] [cols="2v,v"] |=== -| **Rule** +| <<Ansible-files-SHOULD-NOT-use-JSON-use-pure-YAML-instead, Rule>> | Ansible files SHOULD NOT use JSON (use pure YAML instead). |=== @@ -144,9 +153,10 @@ Every effort should be made to keep our Ansible YAML files in pure YAML. === Modules ''' +[[Custom-Ansible-modules-SHOULD-be-embedded-in-a-role]] [cols="2v,v"] |=== -| **Rule** +| <<Custom-Ansible-modules-SHOULD-be-embedded-in-a-role, Rule>> | Custom Ansible modules SHOULD be embedded in a role. |=== @@ -177,9 +187,10 @@ The purpose of this rule is to make it easy to include custom modules in our pla ''' +[[Parameters-to-Ansible-modules-SHOULD-use-the-Yaml-dictionary-format-when-3-or-more-parameters-are-being-passed]] [cols="2v,v"] |=== -| **Rule** +| <<Parameters-to-Ansible-modules-SHOULD-use-the-Yaml-dictionary-format-when-3-or-more-parameters-are-being-passed, Rule>> | Parameters to Ansible modules SHOULD use the Yaml dictionary format when 3 or more parameters are being passed |=== @@ -204,9 +215,10 @@ When a module has several parameters that are being passed in, it's hard to see ''' +[[Parameters-to-Ansible-modules-SHOULD-use-the-Yaml-dictionary-format-when-the-line-length-exceeds-120-characters]] [cols="2v,v"] |=== -| **Rule** +| <<Parameters-to-Ansible-modules-SHOULD-use-the-Yaml-dictionary-format-when-the-line-length-exceeds-120-characters, Rule>> | Parameters to Ansible modules SHOULD use the Yaml dictionary format when the line length exceeds 120 characters |=== @@ -228,9 +240,10 @@ Lines that are long quickly become a wall of text that isn't easily parsable. It ---- ''' +[[The-Ansible-command-module-SHOULD-be-used-instead-of-the-Ansible-shell-module]] [cols="2v,v"] |=== -| **Rule** +| <<The-Ansible-command-module-SHOULD-be-used-instead-of-the-Ansible-shell-module, Rule>> | The Ansible `command` module SHOULD be used instead of the Ansible `shell` module. |=== .Context @@ -251,9 +264,10 @@ The Ansible `shell` module can run most commands that can be run from a bash CLI ---- ''' +[[The-Ansible-quote-filter-MUST-be-used-with-any-variable-passed-into-the-shell-module]] [cols="2v,v"] |=== -| **Rule** +| <<The-Ansible-quote-filter-MUST-be-used-with-any-variable-passed-into-the-shell-module, Rule>> | The Ansible `quote` filter MUST be used with any variable passed into the shell module. |=== .Context @@ -279,9 +293,10 @@ It is recommended not to use the `shell` module. However, if it absolutely must * http://docs.ansible.com/fail_module.html[Ansible Fail Module] ''' +[[Ansible-playbooks-MUST-begin-with-checks-for-any-variables-that-they-require]] [cols="2v,v"] |=== -| **Rule** +| <<Ansible-playbooks-MUST-begin-with-checks-for-any-variables-that-they-require, Rule>> | Ansible playbooks MUST begin with checks for any variables that they require. |=== @@ -299,9 +314,10 @@ If an Ansible playbook requires certain variables to be set, it's best to check ---- ''' +[[Ansible-roles-tasks-main-yml-file-MUST-begin-with-checks-for-any-variables-that-they-require]] [cols="2v,v"] |=== -| **Rule** +| <<Ansible-roles-tasks-main-yml-file-MUST-begin-with-checks-for-any-variables-that-they-require, Rule>> | Ansible roles tasks/main.yml file MUST begin with checks for any variables that they require. |=== @@ -318,9 +334,10 @@ If an Ansible role requires certain variables to be set, it's best to check for === Tasks ''' +[[Ansible-tasks-SHOULD-NOT-be-used-in-ansible-playbooks-Instead-use-pre_tasks-and-post_tasks]] [cols="2v,v"] |=== -| **Rule** +| <<Ansible-tasks-SHOULD-NOT-be-used-in-ansible-playbooks-Instead-use-pre_tasks-and-post_tasks, Rule>> | Ansible tasks SHOULD NOT be used in ansible playbooks. Instead, use pre_tasks and post_tasks. |=== An Ansible play is defined as a Yaml dictionary. Because of that, ansible doesn't know if the play's tasks list or roles list was specified first. Therefore Ansible always runs tasks after roles. @@ -370,9 +387,10 @@ Therefore, we SHOULD use pre_tasks and post_tasks to make it more clear when the === Roles ''' +[[All-tasks-in-a-role-SHOULD-be-tagged-with-the-role-name]] [cols="2v,v"] |=== -| **Rule** +| <<All-tasks-in-a-role-SHOULD-be-tagged-with-the-role-name, Rule>> | All tasks in a role SHOULD be tagged with the role name. |=== @@ -395,9 +413,10 @@ This is very useful when developing and debugging new tasks. It can also signifi ''' +[[The-Ansible-roles-directory-MUST-maintain-a-flat-structure]] [cols="2v,v"] |=== -| **Rule** +| <<The-Ansible-roles-directory-MUST-maintain-a-flat-structure, Rule>> | The Ansible roles directory MUST maintain a flat structure. |=== @@ -410,9 +429,10 @@ This is very useful when developing and debugging new tasks. It can also signifi * Make it compatible with Ansible Galaxy ''' +[[Ansible-Roles-SHOULD-be-named-like-technology_component_subcomponent]] [cols="2v,v"] |=== -| **Rule** +| [[Ansible-Roles-SHOULD-be-named-like-technology_component_subcomponent, Rule]] | Ansible Roles SHOULD be named like technology_component[_subcomponent]. |=== @@ -430,9 +450,10 @@ Many times the `technology` portion of the pattern will line up with a package n * http://jinja.pocoo.org/docs/dev/templates/#builtin-filters[Jinja2 Builtin Filters] ''' +[[The-default-filter-SHOULD-replace-empty-strings-lists-etc]] [cols="2v,v"] |=== -| **Rule** +| <<The-default-filter-SHOULD-replace-empty-strings-lists-etc, Rule>> | The `default` filter SHOULD replace empty strings, lists, etc. |=== @@ -469,15 +490,17 @@ This is almost always more desirable than an empty list, string, etc. === Yum and DNF ''' +[[Package-installation-MUST-use-ansible-action-module-to-abstract-away-dnf-yum]] [cols="2v,v"] |=== -| **Rule** +| <<Package-installation-MUST-use-ansible-action-module-to-abstract-away-dnf-yum, Rule>> | Package installation MUST use ansible action module to abstract away dnf/yum. -| Package installation MUST use name= and state=present rather than pkg= and state=installed respectively. |=== + +[[Package-installation-MUST-use-name-and-state-present-rather-than-pkg-and-state-installed-respectively]] [cols="2v,v"] |=== -| **Rule** +| <<Package-installation-MUST-use-name-and-state-present-rather-than-pkg-and-state-installed-respectively, Rule>> | Package installation MUST use name= and state=present rather than pkg= and state=installed respectively. |=== diff --git a/docs/style_guide.adoc b/docs/style_guide.adoc index 09d4839c7..72eaedcf9 100644 --- a/docs/style_guide.adoc +++ b/docs/style_guide.adoc @@ -19,9 +19,10 @@ This style guide complies with https://www.ietf.org/rfc/rfc2119.txt[RFC2119]. * https://www.python.org/dev/peps/pep-0008/#maximum-line-length[Python Pep8 Line Length] ''' +[[All-lines-SHOULD-be-no-longer-than-80-characters]] [cols="2v,v"] |=== -| **Rule** +| <<All-lines-SHOULD-be-no-longer-than-80-characters, Rule>> | All lines SHOULD be no longer than 80 characters. |=== @@ -31,9 +32,10 @@ Code readability is subjective, therefore pull-requests SHOULD still be merged, ''' +[[All-lines-MUST-be-no-longer-than-120-characters]] [cols="2v,v"] |=== -| **Rule** +| <<All-lines-MUST-be-no-longer-than-120-characters, Rule>> | All lines MUST be no longer than 120 characters. |=== @@ -46,9 +48,10 @@ This is a hard limit and is enforced by the build bot. This check MUST NOT be di === Ansible Yaml file extension ''' +[[All-Ansible-Yaml-files-MUST-have-a-yml-extension-and-NOT-YML-yaml-etc]] [cols="2v,v"] |=== -| **Rule** +| <<All-Ansible-Yaml-files-MUST-have-a-yml-extension-and-NOT-YML-yaml-etc, Rule>> | All Ansible Yaml files MUST have a .yml extension (and NOT .YML, .yaml etc). |=== @@ -59,9 +62,10 @@ Example: `tasks.yml` === Ansible CLI Variables ''' +[[Variables-meant-to-be-passed-in-from-the-ansible-CLI-MUST-have-a-prefix-of-cli]] [cols="2v,v"] |=== -| **Rule** +| <<Variables-meant-to-be-passed-in-from-the-ansible-CLI-MUST-have-a-prefix-of-cli, Rule>> | Variables meant to be passed in from the ansible CLI MUST have a prefix of cli_ |=== @@ -76,9 +80,10 @@ ansible-playbook -e cli_foo=bar someplays.yml === Ansible Global Variables ''' +[[Global-variables-MUST-have-a-prefix-of-g]] [cols="2v,v"] |=== -| **Rule** +| <<Global-variables-MUST-have-a-prefix-of-g, Rule>> | Global variables MUST have a prefix of g_ |=== Ansible global variables are defined as any variables outside of ansible roles. Examples include playbook variables, variables passed in on the cli, etc. @@ -94,9 +99,10 @@ g_environment: someval Ansible role variables are defined as variables contained in (or passed into) a role. ''' +[[Role-variables-MUST-have-a-prefix-of-atleast-3-characters-See.below.for.specific.naming.rules]] [cols="2v,v"] |=== -| **Rule** +| <<Role-variables-MUST-have-a-prefix-of-atleast-3-characters-See.below.for.specific.naming.rules, Rule>> | Role variables MUST have a prefix of atleast 3 characters. See below for specific naming rules. |=== diff --git a/inventory/aws/hosts/ec2.ini b/inventory/aws/hosts/ec2.ini index 1f503b8cf..aa0f9090f 100644 --- a/inventory/aws/hosts/ec2.ini +++ b/inventory/aws/hosts/ec2.ini @@ -45,10 +45,10 @@ vpc_destination_variable = ip_address route53 = False # To exclude RDS instances from the inventory, uncomment and set to False. -#rds = False +rds = False # To exclude ElastiCache instances from the inventory, uncomment and set to False. -#elasticache = False +elasticache = False # Additionally, you can specify the list of zones to exclude looking up in # 'route53_excluded_zones' as a comma-separated list. diff --git a/openshift-ansible.spec b/openshift-ansible.spec index 70938e8d2..37117feac 100644 --- a/openshift-ansible.spec +++ b/openshift-ansible.spec @@ -5,7 +5,7 @@ } Name: openshift-ansible -Version: 3.0.28 +Version: 3.0.34 Release: 1%{?dist} Summary: Openshift and Atomic Enterprise Ansible License: ASL 2.0 @@ -259,6 +259,71 @@ Atomic OpenShift Utilities includes %changelog +* Mon Jan 18 2016 Brenton Leanhardt <bleanhar@redhat.com> 3.0.34-1 +- clean up too-many-branches / logic (jdiaz@redhat.com) +- atomic-openshift-installer: add containerized to inventory + (smunilla@redhat.com) +- Add 'unknown' to possible output for the is-active check. + (abutcher@redhat.com) +- Fix cluster_method conditional in master restart playbook. + (abutcher@redhat.com) +- Use IdentityFile instead of PrivateKey (donovan.muller@gmail.com) +- atomic-openshift-installer: Remove containerized install for 3.0 + (smunilla@redhat.com) +- Host group should be OSEv3 not OSv3 (donovan.muller@gmail.com) +- Remove pause after haproxy start (abutcher@redhat.com) +- Ensure nfs-utils installed for non-atomic hosts. (abutcher@redhat.com) + +* Fri Jan 15 2016 Brenton Leanhardt <bleanhar@redhat.com> 3.0.33-1 +- Configure nodes which are also masters prior to nodes in containerized + install. (abutcher@redhat.com) +- Call attention to openshift_master_rolling_restart_mode variable in restart + prompt. (abutcher@redhat.com) +- Added anchors for rules in style_guide.adoc in order to make it easier to + reference specific rules in PRs. (twiest@redhat.com) +- Update ec2.ini (jdetiber@redhat.com) + +* Thu Jan 14 2016 Brenton Leanhardt <bleanhar@redhat.com> 3.0.32-1 +- Uninstall remove containerized wrapper and symlinks (abutcher@redhat.com) + +* Thu Jan 14 2016 Brenton Leanhardt <bleanhar@redhat.com> 3.0.31-1 +- Check api prior to starting node. (abutcher@redhat.com) +- added anchors (twiest@redhat.com) + +* Wed Jan 13 2016 Joel Diaz <jdiaz@redhat.com> 3.0.30-1 +- Add -A and detail --v3 flags + +* Wed Jan 13 2016 Brenton Leanhardt <bleanhar@redhat.com> 3.0.29-1 +- 3.1.1 upgrade playbook (bleanhar@redhat.com) +- Updated help menu for v3 flag (kwoodson@redhat.com) +- Add wait in between api and controllers start for native ha. + (abutcher@redhat.com) +- atomic-openshift-installer: Error handling for unicode hostnames + (smunilla@redhat.com) +- Update api verification. (abutcher@redhat.com) +- Add a Verify API Server handler that waits for the API server to become + available (sdodson@redhat.com) +- Add -A parameter to forward ssh agent (jdiaz@redhat.com) +- Validate pacemaker cluster members. (abutcher@redhat.com) +- Removed atomic host check (kwoodson@redhat.com) +- Add is_containerized inputs to nosetests. (abutcher@redhat.com) +- Add wait for API before starting controllers w/ native ha install. + (abutcher@redhat.com) +- Fix for to_padded_yaml filter (jdetiber@redhat.com) +- - sqashed to one commit (llange@redhat.com) +- Switch to using hostnamectl as it works on atomic and rhel7 + (sdodson@redhat.com) +- Update rolling restart playbook for pacemaker support. Replace fail with a + warn and prompt if running ansible from a host that will be rebooted. Re- + organize playbooks. (abutcher@redhat.com) +- Implement simple master rolling restarts. (dgoodwin@redhat.com) +- re-enable containerize installs (sdodson@redhat.com) +- Set portal net in master playbook (jdetiber@redhat.com) +- Set the cli image to match osm_image in openshift_cli role + (sdodson@redhat.com) +- atomic-openshift-installer: Populate new_nodes group (smunilla@redhat.com) +- Always pull docker images (sdodson@redhat.com) + * Mon Jan 11 2016 Kenny Woodson <kwoodson@redhat.com> 3.0.28-1 - added the rhe7-host-monitoring service file (mwoodson@redhat.com) - Fixing tab completion for latest metadata changes (kwoodson@redhat.com) diff --git a/playbooks/adhoc/bootstrap-fedora.yml b/playbooks/adhoc/bootstrap-fedora.yml index de9f36c8a..0df77e309 100644 --- a/playbooks/adhoc/bootstrap-fedora.yml +++ b/playbooks/adhoc/bootstrap-fedora.yml @@ -1,4 +1,4 @@ -- hosts: OSv3 +- hosts: OSEv3 gather_facts: false tasks: - name: install python and deps for ansible modules diff --git a/playbooks/adhoc/uninstall.yml b/playbooks/adhoc/uninstall.yml index ac20f5f9b..36d686c8b 100644 --- a/playbooks/adhoc/uninstall.yml +++ b/playbooks/adhoc/uninstall.yml @@ -202,6 +202,10 @@ - /usr/lib/systemd/system/atomic-openshift-master-controllers.service - /usr/lib/systemd/system/origin-master-api.service - /usr/lib/systemd/system/origin-master-controllers.service + - /usr/local/bin/openshift + - /usr/local/bin/oadm + - /usr/local/bin/oc + - /usr/local/bin/kubectl # Since we are potentially removing the systemd unit files for separated # master-api and master-controllers services, so we need to reload the diff --git a/playbooks/byo/openshift-cluster/upgrades/v3_1_minor/README.md b/playbooks/byo/openshift-cluster/upgrades/v3_1_minor/README.md new file mode 100644 index 000000000..b230835c3 --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/v3_1_minor/README.md @@ -0,0 +1,17 @@ +# v3.1 minor upgrade playbook +This upgrade will preserve all locally made configuration modifications to the +Masters and Nodes. + +## Overview +This playbook is available as a technical preview. It currently performs the +following steps. + + * Upgrade and restart master services + * Upgrade and restart node services + * Applies the latest cluster policies + * Updates the default router if one exists + * Updates the default registry if one exists + * Updates image streams and quickstarts + +## Usage +ansible-playbook -i ~/ansible-inventory openshift-ansible/playbooks/byo/openshift-cluster/upgrades/v3_1_minor/upgrade.yml diff --git a/playbooks/byo/openshift-cluster/upgrades/v3_1_minor/upgrade.yml b/playbooks/byo/openshift-cluster/upgrades/v3_1_minor/upgrade.yml new file mode 100644 index 000000000..20fa9b10f --- /dev/null +++ b/playbooks/byo/openshift-cluster/upgrades/v3_1_minor/upgrade.yml @@ -0,0 +1,14 @@ +--- +- include: ../../../../common/openshift-cluster/evaluate_groups.yml + vars: + g_etcd_hosts: "{{ groups.etcd | default([]) }}" + g_master_hosts: "{{ groups.masters | default([]) }}" + g_nfs_hosts: "{{ groups.nfs | default([]) }}" + g_node_hosts: "{{ groups.nodes | default([]) }}" + g_lb_hosts: "{{ groups.lb | default([]) }}" + openshift_cluster_id: "{{ cluster_id | default('default') }}" + openshift_deployment_type: "{{ deployment_type }}" +- include: ../../../../common/openshift-cluster/upgrades/v3_1_minor/pre.yml +- include: ../../../../common/openshift-cluster/upgrades/v3_1_minor/upgrade.yml +- include: ../../../openshift-master/restart.yml +- include: ../../../../common/openshift-cluster/upgrades/v3_1_minor/post.yml diff --git a/playbooks/common/openshift-cluster/upgrades/v3_1_minor/filter_plugins b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/filter_plugins new file mode 120000 index 000000000..27ddaa18b --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/filter_plugins @@ -0,0 +1 @@ +../../../../../filter_plugins
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/v3_1_minor/library b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/library new file mode 120000 index 000000000..53bed9684 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/library @@ -0,0 +1 @@ +../library
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/v3_1_minor/lookup_plugins b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/lookup_plugins new file mode 120000 index 000000000..cf407f69b --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/lookup_plugins @@ -0,0 +1 @@ +../../../../../lookup_plugins
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/v3_1_minor/post.yml b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/post.yml new file mode 100644 index 000000000..d8336fcae --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/post.yml @@ -0,0 +1,50 @@ +--- +############################################################################### +# Post upgrade - Upgrade default router, default registry and examples +############################################################################### +- name: Upgrade default router and default registry + hosts: oo_first_master + vars: + openshift_deployment_type: "{{ deployment_type }}" + 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" + roles: + # Create the new templates shipped in 3.1.z, existing templates are left + # unmodified. This prevents the subsequent role definition for + # openshift_examples from failing when trying to replace templates that do + # not already exist. We could have potentially done a replace --force to + # create and update in one step. + - openshift_examples + # Update the existing templates + - role: openshift_examples + openshift_examples_import_command: replace + pre_tasks: + - name: Check for default router + command: > + {{ oc_cmd }} get -n default dc/router + register: _default_router + failed_when: false + changed_when: false + + - name: Check for default registry + command: > + {{ oc_cmd }} get -n default dc/docker-registry + register: _default_registry + failed_when: false + changed_when: false + + - name: Update router image to current version + when: _default_router.rc == 0 + command: > + {{ oc_cmd }} patch dc/router -p + '{"spec":{"template":{"spec":{"containers":[{"name":"router","image":"{{ router_image }}"}]}}}}' + --api-version=v1 + + - name: Update registry image to current version + when: _default_registry.rc == 0 + command: > + {{ oc_cmd }} patch dc/docker-registry -p + '{"spec":{"template":{"spec":{"containers":[{"name":"registry","image":"{{ registry_image }}"}]}}}}' + --api-version=v1 + diff --git a/playbooks/common/openshift-cluster/upgrades/v3_1_minor/pre.yml b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/pre.yml new file mode 100644 index 000000000..91780de09 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/pre.yml @@ -0,0 +1,87 @@ +--- +############################################################################### +# Evaluate host groups and gather facts +############################################################################### +- name: Load openshift_facts + hosts: oo_masters_to_config:oo_nodes_to_config:oo_etcd_to_config:oo_lb_to_config + roles: + - openshift_facts + +############################################################################### +# Pre-upgrade checks +############################################################################### +- name: Verify upgrade can proceed + hosts: oo_first_master + vars: + openshift_master_ha: "{{ groups.oo_masters_to_config | length > 1 }}" + target_version: "{{ '1.1.1' if deployment_type == 'origin' else '3.1.1' }}" + gather_facts: no + tasks: + - fail: + msg: > + This upgrade is only supported for origin, openshift-enterprise, and online + deployment types + when: deployment_type not in ['origin','openshift-enterprise', 'online'] + + - fail: + msg: > + openshift_pkg_version is {{ openshift_pkg_version }} which is not a + valid version for a {{ target_version }} upgrade + when: openshift_pkg_version is defined and openshift_pkg_version.split('-',1).1 | version_compare(target_version ,'<') + +- name: Verify upgrade can proceed + hosts: oo_masters_to_config:oo_nodes_to_config + vars: + target_version: "{{ '1.1.1' if deployment_type == 'origin' else '3.1.1' }}" + tasks: + - name: Clean package cache + command: "{{ ansible_pkg_mgr }} clean all" + + - set_fact: + g_new_service_name: "{{ 'origin' if deployment_type =='origin' else 'atomic-openshift' }}" + + - name: Determine available versions + script: ../files/versions.sh {{ g_new_service_name }} 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: + msg: This playbook requires Origin 1.1 or later + when: deployment_type == 'origin' and g_aos_versions.curr_version | version_compare('1.1','<') + + - fail: + msg: This playbook requires Atomic Enterprise Platform/OpenShift Enterprise 3.1 or later + when: deployment_type == 'atomic-openshift' and g_aos_versions.curr_version | version_compare('3.1','<') + + - fail: + msg: Upgrade packages not found + when: (g_aos_versions.avail_version | default(g_aos_versions.curr_version, true) | version_compare(target_version, '<')) + + - set_fact: + pre_upgrade_complete: True + + +############################################################################## +# Gate on pre-upgrade checks +############################################################################## +- name: Gate on pre-upgrade checks + hosts: localhost + connection: local + become: no + vars: + pre_upgrade_hosts: "{{ groups.oo_masters_to_config | union(groups.oo_nodes_to_config) }}" + tasks: + - set_fact: + pre_upgrade_completed: "{{ hostvars + | oo_select_keys(pre_upgrade_hosts) + | oo_collect('inventory_hostname', {'pre_upgrade_complete': true}) }}" + - set_fact: + pre_upgrade_failed: "{{ pre_upgrade_hosts | difference(pre_upgrade_completed) }}" + - fail: + msg: "Upgrade cannot continue. The following hosts did not complete pre-upgrade checks: {{ pre_upgrade_failed | join(',') }}" + when: pre_upgrade_failed | length > 0 diff --git a/playbooks/common/openshift-cluster/upgrades/v3_1_minor/roles b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/roles new file mode 120000 index 000000000..6bc1a7aef --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/roles @@ -0,0 +1 @@ +../../../../../roles
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/v3_1_minor/upgrade.yml b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/upgrade.yml new file mode 100644 index 000000000..81dbba1e3 --- /dev/null +++ b/playbooks/common/openshift-cluster/upgrades/v3_1_minor/upgrade.yml @@ -0,0 +1,137 @@ +--- +############################################################################### +# The restart playbook should be run after this playbook completes. +############################################################################### + +############################################################################### +# Upgrade Masters +############################################################################### +- name: Upgrade master packages and configuration + hosts: oo_masters_to_config + vars: + openshift_version: "{{ openshift_pkg_version | default('') }}" + tasks: + - name: Upgrade master packages + command: "{{ ansible_pkg_mgr}} update -y {{ openshift.common.service_type }}-master{{ openshift_version }}" + + - name: Ensure python-yaml present for config upgrade + action: "{{ ansible_pkg_mgr }} name=PyYAML state=present" + when: not openshift.common.is_atomic | bool + +# Currently 3.1.1 does not have any new configuration settings +# +# - name: Upgrade master configuration +# openshift_upgrade_config: +# from_version: '3.0' +# to_version: '3.1' +# role: master +# config_base: "{{ hostvars[inventory_hostname].openshift.common.config_base }}" + +- name: Set master update status to complete + hosts: oo_masters_to_config + tasks: + - set_fact: + master_update_complete: True + +############################################################################## +# Gate on master update complete +############################################################################## +- name: Gate on master update + hosts: localhost + connection: local + become: no + tasks: + - set_fact: + master_update_completed: "{{ hostvars + | oo_select_keys(groups.oo_masters_to_config) + | oo_collect('inventory_hostname', {'master_update_complete': true}) }}" + - set_fact: + master_update_failed: "{{ groups.oo_masters_to_config | difference(master_update_completed) }}" + - fail: + msg: "Upgrade cannot continue. The following masters did not finish updating: {{ master_update_failed | join(',') }}" + when: master_update_failed | length > 0 + +############################################################################### +# Upgrade Nodes +############################################################################### +- name: Upgrade nodes + hosts: oo_nodes_to_config + vars: + openshift_version: "{{ openshift_pkg_version | default('') }}" + roles: + - openshift_facts + tasks: + - name: Upgrade node packages + command: "{{ ansible_pkg_mgr }} update -y {{ openshift.common.service_type }}-node{{ openshift_version }}" + + - name: Restart node service + service: name="{{ openshift.common.service_type }}-node" state=restarted + + - set_fact: + node_update_complete: True + +############################################################################## +# Gate on nodes update +############################################################################## +- name: Gate on nodes update + hosts: localhost + connection: local + become: no + tasks: + - set_fact: + node_update_completed: "{{ hostvars + | oo_select_keys(groups.oo_nodes_to_config) + | oo_collect('inventory_hostname', {'node_update_complete': true}) }}" + - set_fact: + node_update_failed: "{{ groups.oo_nodes_to_config | difference(node_update_completed) }}" + - fail: + msg: "Upgrade cannot continue. The following nodes did not finish updating: {{ node_update_failed | join(',') }}" + when: node_update_failed | length > 0 + +############################################################################### +# Reconcile Cluster Roles and Cluster Role Bindings +############################################################################### +- name: Reconcile Cluster Roles and Cluster Role Bindings + hosts: oo_masters_to_config + vars: + origin_reconcile_bindings: "{{ deployment_type == 'origin' and g_new_version | version_compare('1.0.6', '>') }}" + ent_reconcile_bindings: true + openshift_master_ha: "{{ groups.oo_masters_to_config | length > 1 }}" + tasks: + - name: Reconcile Cluster Roles + command: > + {{ openshift.common.admin_binary}} --config={{ openshift.common.config_base }}/master/admin.kubeconfig + policy reconcile-cluster-roles --confirm + run_once: true + + - name: Reconcile Cluster Role Bindings + command: > + {{ openshift.common.admin_binary}} --config={{ openshift.common.config_base }}/master/admin.kubeconfig + policy reconcile-cluster-role-bindings + --exclude-groups=system:authenticated + --exclude-groups=system:unauthenticated + --exclude-users=system:anonymous + --additive-only=true --confirm + when: origin_reconcile_bindings | bool or ent_reconcile_bindings | bool + run_once: true + + - set_fact: + reconcile_complete: True + +############################################################################## +# Gate on reconcile +############################################################################## +- name: Gate on reconcile + hosts: localhost + connection: local + become: no + tasks: + - set_fact: + reconcile_completed: "{{ hostvars + | oo_select_keys(groups.oo_masters_to_config) + | oo_collect('inventory_hostname', {'reconcile_complete': true}) }}" + - set_fact: + reconcile_failed: "{{ groups.oo_masters_to_config | difference(reconcile_completed) }}" + - fail: + msg: "Upgrade cannot continue. The following masters did not finish reconciling: {{ reconcile_failed | join(',') }}" + when: reconcile_failed | length > 0 diff --git a/playbooks/common/openshift-master/config.yml b/playbooks/common/openshift-master/config.yml index 4ecdf2a0c..0df03f194 100644 --- a/playbooks/common/openshift-master/config.yml +++ b/playbooks/common/openshift-master/config.yml @@ -313,6 +313,7 @@ - name: Configure master instances hosts: oo_masters_to_config + any_errors_fatal: true serial: 1 vars: sync_tmpdir: "{{ hostvars.localhost.g_master_mktemp.stdout }}" diff --git a/playbooks/common/openshift-master/restart.yml b/playbooks/common/openshift-master/restart.yml index fa13a64cb..d9d857b1a 100644 --- a/playbooks/common/openshift-master/restart.yml +++ b/playbooks/common/openshift-master/restart.yml @@ -57,8 +57,10 @@ Warning: Running playbook from a host that will be restarted! Press CTRL+C and A to abort playbook execution. You may continue by pressing ENTER but the playbook will stop - executing once this system restarts and services must be - manually verified. + executing after this system has been restarted and services + must be verified manually. To only restart services, set + openshift_master_rolling_restart_mode=services in host + inventory and relaunch the playbook. when: exists.stat.exists and openshift.common.rolling_restart_mode == 'system' - set_fact: current_host: "{{ exists.stat.exists }}" @@ -71,12 +73,12 @@ command: > systemctl is-active {{ openshift.common.service_type }}-master register: active_check_output - when: openshift.master.cluster_method == 'pacemaker' - failed_when: active_check_output.stdout not in ['active', 'inactive'] + when: openshift.master.cluster_method | default(None) == 'pacemaker' + failed_when: active_check_output.stdout not in ['active', 'inactive', 'unknown'] changed_when: false - set_fact: is_active: "{{ active_check_output.stdout == 'active' }}" - when: openshift.master.cluster_method == 'pacemaker' + when: openshift.master.cluster_method | default(None) == 'pacemaker' - name: Evaluate master groups hosts: localhost diff --git a/playbooks/common/openshift-node/config.yml b/playbooks/common/openshift-node/config.yml index 483a7768c..1d31657ed 100644 --- a/playbooks/common/openshift-node/config.yml +++ b/playbooks/common/openshift-node/config.yml @@ -154,21 +154,15 @@ validate_checksum: yes with_items: nodes_needing_certs -- name: Configure node instances +- name: Deploy node certificates hosts: oo_nodes_to_config vars: sync_tmpdir: "{{ hostvars.localhost.mktemp.stdout }}" - openshift_node_master_api_url: "{{ hostvars[groups.oo_first_master.0].openshift.master.api_url }}" - # TODO: Prefix flannel role variables. - etcd_urls: "{{ hostvars[groups.oo_first_master.0].openshift.master.etcd_urls }}" - embedded_etcd: "{{ hostvars[groups.oo_first_master.0].openshift.master.embedded_etcd }}" - openshift_node_first_master_ip: "{{ hostvars[groups.oo_first_master.0].openshift.common.ip }}" - pre_tasks: + tasks: - name: Ensure certificate directory exists file: path: "{{ node_cert_dir }}" state: directory - # TODO: notify restart node # possibly test service started time against certificate/config file # timestamps in node to trigger notify @@ -177,8 +171,44 @@ src: "{{ sync_tmpdir }}/{{ node_subdir }}.tgz" dest: "{{ node_cert_dir }}" when: certs_missing + +- name: Evaluate node groups + hosts: localhost + become: no + tasks: + - name: Evaluate oo_containerized_master_nodes + add_host: + name: "{{ item }}" + groups: oo_containerized_master_nodes + ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" + ansible_sudo: "{{ g_sudo | default(omit) }}" + with_items: "{{ groups.oo_nodes_to_config | default([]) }}" + when: hostvars[item].openshift.common.is_containerized | bool and (item in groups.oo_nodes_to_config and item in groups.oo_masters_to_config) + +- name: Configure node instances + hosts: oo_containerized_master_nodes + serial: 1 + vars: + openshift_node_master_api_url: "{{ hostvars[groups.oo_first_master.0].openshift.master.api_url }}" + openshift_node_first_master_ip: "{{ hostvars[groups.oo_first_master.0].openshift.common.ip }}" roles: - openshift_node + +- name: Configure node instances + hosts: oo_nodes_to_config:!oo_containerized_master_nodes + vars: + openshift_node_master_api_url: "{{ hostvars[groups.oo_first_master.0].openshift.master.api_url }}" + openshift_node_first_master_ip: "{{ hostvars[groups.oo_first_master.0].openshift.common.ip }}" + roles: + - openshift_node + +- name: Additional node config + hosts: oo_nodes_to_config + vars: + # TODO: Prefix flannel role variables. + etcd_urls: "{{ hostvars[groups.oo_first_master.0].openshift.master.etcd_urls }}" + embedded_etcd: "{{ hostvars[groups.oo_first_master.0].openshift.master.embedded_etcd }}" + roles: - role: flannel when: openshift.common.use_flannel | bool - role: nickhammond.logrotate @@ -215,6 +245,19 @@ | oo_collect('openshift.common.hostname') }}" openshift_node_vars: "{{ hostvars | oo_select_keys(groups['oo_nodes_to_config']) }}" pre_tasks: - + # Necessary because when you're on a node that's also a master the master will be + # restarted after the node restarts docker and it will take up to 60 seconds for + # systemd to start the master again + - name: Wait for master API to become available before proceeding + # Using curl here since the uri module requires python-httplib2 and + # wait_for port doesn't provide health information. + command: > + curl -k --head --silent {{ openshift.master.api_url }} + register: api_available_output + until: api_available_output.stdout.find("200 OK") != -1 + retries: 120 + delay: 1 + changed_when: false + when: openshift.common.is_containerized | bool roles: - openshift_manage_node diff --git a/roles/haproxy/handlers/main.yml b/roles/haproxy/handlers/main.yml index ee60adcab..5b8691b26 100644 --- a/roles/haproxy/handlers/main.yml +++ b/roles/haproxy/handlers/main.yml @@ -3,3 +3,4 @@ service: name: haproxy state: restarted + when: not (haproxy_start_result_changed | default(false) | bool) diff --git a/roles/haproxy/tasks/main.yml b/roles/haproxy/tasks/main.yml index 97f870829..0b8370ce2 100644 --- a/roles/haproxy/tasks/main.yml +++ b/roles/haproxy/tasks/main.yml @@ -19,6 +19,5 @@ enabled: yes register: start_result -- name: Pause 30 seconds if haproxy was just started - pause: seconds=30 - when: start_result | changed +- set_fact: + haproxy_start_result_changed: "{{ start_result | changed }}" diff --git a/roles/lib_zabbix/library/zbx_action.py b/roles/lib_zabbix/library/zbx_action.py index c08bef4f7..2f9524556 100644 --- a/roles/lib_zabbix/library/zbx_action.py +++ b/roles/lib_zabbix/library/zbx_action.py @@ -81,6 +81,61 @@ def filter_differences(zabbix_filters, user_filters): return rval +def opconditions_diff(zab_val, user_val): + ''' Report whether there are differences between opconditions on + zabbix and opconditions supplied by user ''' + + if len(zab_val) != len(user_val): + return True + + for z_cond, u_cond in zip(zab_val, user_val): + if not all([str(u_cond[op_key]) == z_cond[op_key] for op_key in \ + ['conditiontype', 'operator', 'value']]): + return True + + return False + +def opmessage_diff(zab_val, user_val): + ''' Report whether there are differences between opmessage on + zabbix and opmessage supplied by user ''' + + for op_msg_key, op_msg_val in user_val.items(): + if zab_val[op_msg_key] != str(op_msg_val): + return True + + return False + +def opmessage_grp_diff(zab_val, user_val): + ''' Report whether there are differences between opmessage_grp + on zabbix and opmessage_grp supplied by user ''' + + zab_grp_ids = set([ugrp['usrgrpid'] for ugrp in zab_val]) + usr_grp_ids = set([ugrp['usrgrpid'] for ugrp in user_val]) + if usr_grp_ids != zab_grp_ids: + return True + + return False + +def opmessage_usr_diff(zab_val, user_val): + ''' Report whether there are differences between opmessage_usr + on zabbix and opmessage_usr supplied by user ''' + + zab_usr_ids = set([usr['usrid'] for usr in zab_val]) + usr_ids = set([usr['usrid'] for usr in user_val]) + if usr_ids != zab_usr_ids: + return True + + return False + +def opcommand_diff(zab_op_cmd, usr_op_cmd): + ''' Check whether user-provided opcommand matches what's already + stored in Zabbix ''' + + for usr_op_cmd_key, usr_op_cmd_val in usr_op_cmd.items(): + if zab_op_cmd[usr_op_cmd_key] != str(usr_op_cmd_val): + return True + return False + def host_in_zabbix(zab_hosts, usr_host): ''' Check whether a particular user host is already in the Zabbix list of hosts ''' @@ -106,23 +161,11 @@ def hostlist_in_zabbix(zab_hosts, usr_hosts): return True -def opcommand_diff(zab_op_cmd, usr_op_cmd): - ''' Check whether user-provided opcommand matches what's already - stored in Zabbix ''' - - for usr_op_cmd_key, usr_op_cmd_val in usr_op_cmd.items(): - if zab_op_cmd[usr_op_cmd_key] != str(usr_op_cmd_val): - return True - return False - -# This logic is quite complex. We are comparing two lists of dictionaries. -# The outer for-loops allow us to descend down into both lists at the same time -# and then walk over the key,val pairs of the incoming user dict's changes -# or updates. The if-statements are looking at different sub-object types and -# comparing them. The other suggestion on how to write this is to write a recursive -# compare function but for the time constraints and for complexity I decided to go -# this route. -# pylint: disable=too-many-branches +# We are comparing two lists of dictionaries (the one stored on zabbix and the +# one the user is providing). For each type of operation, determine whether there +# is a difference between what is stored on zabbix and what the user is providing. +# If there is a difference, we take the user-provided data for what needs to +# be stored/updated into zabbix. def operation_differences(zabbix_ops, user_ops): '''Determine the differences from user and zabbix for operations''' @@ -132,49 +175,41 @@ def operation_differences(zabbix_ops, user_ops): rval = {} for zab, user in zip(zabbix_ops, user_ops): - for key, val in user.items(): - if key == 'opconditions': - if len(zab[key]) != len(val): - rval[key] = val - break - for z_cond, u_cond in zip(zab[key], user[key]): - if not all([str(u_cond[op_key]) == z_cond[op_key] for op_key in \ - ['conditiontype', 'operator', 'value']]): - rval[key] = val - break - elif key == 'opmessage': - # Verify each passed param matches - for op_msg_key, op_msg_val in val.items(): - if zab[key][op_msg_key] != str(op_msg_val): - rval[key] = val - break - - elif key == 'opmessage_grp': - zab_grp_ids = set([ugrp['usrgrpid'] for ugrp in zab[key]]) - usr_grp_ids = set([ugrp['usrgrpid'] for ugrp in val]) - if usr_grp_ids != zab_grp_ids: - rval[key] = val - - elif key == 'opmessage_usr': - zab_usr_ids = set([usr['userid'] for usr in zab[key]]) - usr_ids = set([usr['userid'] for usr in val]) - if usr_ids != zab_usr_ids: - rval[key] = val - - elif key == 'opcommand': - if opcommand_diff(zab[key], val): - rval[key] = val - break + for oper in user.keys(): + if oper == 'opconditions' and opconditions_diff(zab[oper], \ + user[oper]): + rval[oper] = user[oper] + + elif oper == 'opmessage' and opmessage_diff(zab[oper], \ + user[oper]): + rval[oper] = user[oper] + + elif oper == 'opmessage_grp' and opmessage_grp_diff(zab[oper], \ + user[oper]): + rval[oper] = user[oper] + + elif oper == 'opmessage_usr' and opmessage_usr_diff(zab[oper], \ + user[oper]): + rval[oper] = user[oper] + + elif oper == 'opcommand' and opcommand_diff(zab[oper], \ + user[oper]): + rval[oper] = user[oper] # opcommand_grp can be treated just like opcommand_hst # as opcommand_grp[] is just a list of groups - elif key == 'opcommand_hst' or key == 'opcommand_grp': - if not hostlist_in_zabbix(zab[key], val): - rval[key] = val - break + elif oper == 'opcommand_hst' or oper == 'opcommand_grp': + if not hostlist_in_zabbix(zab[oper], user[oper]): + rval[oper] = user[oper] + + # if it's any other type of operation than the ones tested above + # just do a direct compare + elif oper not in ['opconditions', 'opmessage', 'opmessage_grp', + 'opmessage_usr', 'opcommand', 'opcommand_hst', + 'opcommand_grp'] \ + and str(zab[oper]) != str(user[oper]): + rval[oper] = user[oper] - elif zab[key] != str(val): - rval[key] = val return rval def get_users(zapi, users): diff --git a/roles/openshift_master/handlers/main.yml b/roles/openshift_master/handlers/main.yml index e1b95eda4..6b9992eea 100644 --- a/roles/openshift_master/handlers/main.yml +++ b/roles/openshift_master/handlers/main.yml @@ -2,11 +2,24 @@ - name: restart master service: name={{ openshift.common.service_type }}-master state=restarted when: (not openshift_master_ha | bool) and (not (master_service_status_changed | default(false) | bool)) + notify: Verify API Server - name: restart master api service: name={{ openshift.common.service_type }}-master-api state=restarted when: (openshift_master_ha | bool) and (not (master_api_service_status_changed | default(false) | bool)) and openshift.master.cluster_method == 'native' + notify: Verify API Server - name: restart master controllers service: name={{ openshift.common.service_type }}-master-controllers state=restarted when: (openshift_master_ha | bool) and (not (master_controllers_service_status_changed | default(false) | bool)) and openshift.master.cluster_method == 'native' + +- name: Verify API Server + # Using curl here since the uri module requires python-httplib2 and + # wait_for port doesn't provide health information. + command: > + curl -k --head --silent {{ openshift.master.api_url }} + register: api_available_output + until: api_available_output.stdout.find("200 OK") != -1 + retries: 120 + delay: 1 + changed_when: false diff --git a/roles/openshift_master/tasks/main.yml b/roles/openshift_master/tasks/main.yml index 3b46a0df4..150b76fc8 100644 --- a/roles/openshift_master/tasks/main.yml +++ b/roles/openshift_master/tasks/main.yml @@ -269,6 +269,7 @@ service: name={{ openshift.common.service_type }}-master enabled=yes state=started when: not openshift_master_ha | bool register: start_result + notify: Verify API Server - name: Stop and disable non HA master when running HA service: name={{ openshift.common.service_type }}-master enabled=no state=stopped @@ -287,6 +288,20 @@ master_api_service_status_changed: "{{ start_result | changed }}" when: openshift_master_ha | bool and openshift.master.cluster_method == 'native' +# A separate wait is required here for native HA since notifies will +# be resolved after all tasks in the role. +- name: Wait for API to become available + # Using curl here since the uri module requires python-httplib2 and + # wait_for port doesn't provide health information. + command: > + curl -k --head --silent {{ openshift.master.api_url }} + register: api_available_output + until: api_available_output.stdout.find("200 OK") != -1 + retries: 120 + delay: 1 + changed_when: false + when: openshift_master_ha | bool and openshift.master.cluster_method == 'native' and master_api_service_status_changed | bool + - name: Start and enable master controller service: name={{ openshift.common.service_type }}-master-controllers enabled=yes state=started when: openshift_master_ha | bool and openshift.master.cluster_method == 'native' diff --git a/roles/openshift_node/tasks/main.yml b/roles/openshift_node/tasks/main.yml index 0828d8e2c..9035248f9 100644 --- a/roles/openshift_node/tasks/main.yml +++ b/roles/openshift_node/tasks/main.yml @@ -103,6 +103,21 @@ - name: Additional storage plugin configuration include: storage_plugins/main.yml +# Necessary because when you're on a node that's also a master the master will be +# restarted after the node restarts docker and it will take up to 60 seconds for +# systemd to start the master again +- name: Wait for master API to become available before proceeding + # Using curl here since the uri module requires python-httplib2 and + # wait_for port doesn't provide health information. + command: > + curl -k --head --silent {{ openshift_node_master_api_url }} + register: api_available_output + until: api_available_output.stdout.find("200 OK") != -1 + retries: 120 + delay: 1 + changed_when: false + when: openshift.common.is_containerized | bool + - name: Start and enable node service: name={{ openshift.common.service_type }}-node enabled=yes state=started register: start_result diff --git a/roles/openshift_node/tasks/storage_plugins/nfs.yml b/roles/openshift_node/tasks/storage_plugins/nfs.yml index 1edf21d9b..14a613786 100644 --- a/roles/openshift_node/tasks/storage_plugins/nfs.yml +++ b/roles/openshift_node/tasks/storage_plugins/nfs.yml @@ -1,4 +1,8 @@ --- +- name: Install NFS storage plugin dependencies + action: "{{ ansible_pkg_mgr }} name=nfs-utils state=present" + when: not openshift.common.is_atomic | bool + - name: Set seboolean to allow nfs storage plugin access from containers seboolean: name: virt_use_nfs diff --git a/utils/src/ooinstall/cli_installer.py b/utils/src/ooinstall/cli_installer.py index 4e30929da..1aacf3a4b 100644 --- a/utils/src/ooinstall/cli_installer.py +++ b/utils/src/ooinstall/cli_installer.py @@ -127,14 +127,13 @@ http://docs.openshift.com/enterprise/latest/architecture/infrastructure_componen masters_set = True host_props['node'] = True - #TODO: Reenable this option once container installs are out of tech preview - rpm_or_container = click.prompt('Will this host be RPM or Container based (rpm/container)?', - type=click.Choice(['rpm', 'container']), - default='rpm') - if rpm_or_container == 'container': - host_props['containerized'] = True - else: - host_props['containerized'] = False + host_props['containerized'] = False + if oo_cfg.settings['variant_version'] != '3.0': + rpm_or_container = click.prompt('Will this host be RPM or Container based (rpm/container)?', + type=click.Choice(['rpm', 'container']), + default='rpm') + if rpm_or_container == 'container': + host_props['containerized'] = True if existing_env: host_props['new_host'] = True diff --git a/utils/src/ooinstall/openshift_ansible.py b/utils/src/ooinstall/openshift_ansible.py index 20401f812..c0d115fdc 100644 --- a/utils/src/ooinstall/openshift_ansible.py +++ b/utils/src/ooinstall/openshift_ansible.py @@ -128,6 +128,8 @@ def write_host(host, inventory, schedulable=None): facts += ' openshift_hostname={}'.format(host.hostname) if host.public_hostname: facts += ' openshift_public_hostname={}'.format(host.public_hostname) + if host.containerized: + facts += ' containerized={}'.format(host.containerized) # TODO: For not write_host is handles both master and nodes. # Technically only nodes will ever need this. |