From 46a54e6178fa5e9c9258c17c478af0388f60951e Mon Sep 17 00:00:00 2001
From: caoyuan <cao.yuan@99cloud.net>
Date: Fri, 17 Feb 2017 12:36:28 +0800
Subject: [PATCH] Optimize the reconfiguration for 'common' container

Change-Id: I57e3b310c65aabeea9f298db78762e9d535e8703
Partially-implements: blueprint better-reconfigure
---
 ansible/roles/common/defaults/main.yml     | 36 ++++++++++++
 ansible/roles/common/handlers/main.yml     | 67 ++++++++++++++++++++++
 ansible/roles/common/tasks/config.yml      | 46 +++++++++++++--
 ansible/roles/common/tasks/deploy.yml      |  3 +-
 ansible/roles/common/tasks/pull.yml        | 17 +-----
 ansible/roles/common/tasks/reconfigure.yml | 42 +-------------
 ansible/roles/common/tasks/start.yml       | 46 ---------------
 ansible/roles/common/tasks/upgrade.yml     |  3 +-
 8 files changed, 151 insertions(+), 109 deletions(-)
 create mode 100644 ansible/roles/common/handlers/main.yml
 delete mode 100644 ansible/roles/common/tasks/start.yml

diff --git a/ansible/roles/common/defaults/main.yml b/ansible/roles/common/defaults/main.yml
index 11db34b922..d33420e177 100644
--- a/ansible/roles/common/defaults/main.yml
+++ b/ansible/roles/common/defaults/main.yml
@@ -3,6 +3,42 @@
 # this role has already run. We can track what has run with host facts.
 common_run: False
 
+common_services:
+  fluentd:
+    container_name: fluentd
+    image: "{{ fluentd_image_full }}"
+    environment:
+      KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
+      SKIP_LOG_SETUP: "true"
+    volumes:
+      - "{{ node_config_directory }}/fluentd/:{{ container_config_directory }}/:ro"
+      - "/etc/localtime:/etc/localtime:ro"
+      - "kolla_logs:/var/log/kolla/"
+  kolla-toolbox:
+    container_name: kolla_toolbox
+    image: "{{ kolla_toolbox_image_full }}"
+    environment:
+      ANSIBLE_NOCOLOR: "1"
+      ANSIBLE_LIBRARY: "/usr/share/ansible"
+    privileged: True
+    volumes:
+      - "{{ node_config_directory }}/kolla-toolbox/:{{ container_config_directory }}/:ro"
+      - "/etc/localtime:/etc/localtime:ro"
+      - "/dev/:/dev/"
+      - "/run/:/run/:shared"
+      - "kolla_logs:/var/log/kolla/"
+# DUMMY_ENVIRONMENT is needed because empty environment is not supported
+  cron:
+    container_name: cron
+    image: "{{ cron_image_full }}"
+    environment:
+      DUMMY_ENVIRONMENT:
+    volumes:
+      - "{{ node_config_directory }}/cron/:{{ container_config_directory }}/:ro"
+      - "/etc/localtime:/etc/localtime:ro"
+      - "kolla_logs:/var/log/kolla/"
+
+
 ####################
 # Docker
 ####################
diff --git a/ansible/roles/common/handlers/main.yml b/ansible/roles/common/handlers/main.yml
new file mode 100644
index 0000000000..8c4965b78b
--- /dev/null
+++ b/ansible/roles/common/handlers/main.yml
@@ -0,0 +1,67 @@
+---
+- name: Restart fluentd container
+  vars:
+    service_name: "fluentd"
+    service: "{{ common_services[service_name] }}"
+    config_json: "{{ common_config_jsons.results|selectattr('item.key', 'equalto', service_name)|first }}"
+    fluentd_container: "{{ check_common_containers.results|selectattr('item.key', 'equalto', service_name)|first }}"
+  kolla_docker:
+    action: "recreate_or_restart_container"
+    common_options: "{{ docker_common_options }}"
+    name: "{{ service.container_name }}"
+    image: "{{ service.image }}"
+    volumes: "{{ service.volumes }}"
+    environment: "{{ service.environment }}"
+  when:
+    - action != "config"
+    - config_json.changed | bool
+      or fluentd_input.changed | bool
+      or fluentd_output.changed | bool
+      or fluentd_format.changed | bool
+      or fluentd_filter.changed | bool
+      or fluentd_td_agent.changed | bool
+      or fluentd_container.changed | bool
+
+- name: Restart kolla-toolbox container
+  vars:
+    service_name: "kolla-toolbox"
+    service: "{{ common_services[service_name] }}"
+    config_json: "{{ common_config_jsons.results|selectattr('item.key', 'equalto', service_name)|first }}"
+    kolla_toolbox_container: "{{ check_common_containers.results|selectattr('item.key', 'equalto', service_name)|first }}"
+  kolla_docker:
+    action: "recreate_or_restart_container"
+    common_options: "{{ docker_common_options }}"
+    name: "{{ service.container_name }}"
+    image: "{{ service.image }}"
+    privileged: "{{ service.privileged | default(False) }}"
+    volumes: "{{ service.volumes }}"
+    environment: "{{ service.environment }}"
+  when:
+    - action != "config"
+    - config_json.changed | bool
+      or kolla_toolbox_container.changed | bool
+  notify:
+    - Initializing toolbox container using normal user
+
+- name: Initializing toolbox container using normal user
+  command: docker exec -t kolla_toolbox /usr/bin/ansible --version
+  changed_when: false
+
+- name: Restart cron container
+  vars:
+    service_name: "cron"
+    service: "{{ common_services[service_name] }}"
+    config_json: "{{ common_config_jsons.results|selectattr('item.key', 'equalto', service_name)|first }}"
+    cron_container: "{{ check_common_containers.results|selectattr('item.key', 'equalto', service_name)|first }}"
+  kolla_docker:
+    action: "recreate_or_restart_container"
+    common_options: "{{ docker_common_options }}"
+    name: "{{ service.container_name }}"
+    image: "{{ service.image }}"
+    volumes: "{{ service.volumes }}"
+    environment: "{{ service.environment }}"
+  when:
+    - action != "config"
+    - config_json.changed | bool
+      or cron_confs.changed | bool
+      or check_common_containers.changed | bool
diff --git a/ansible/roles/common/tasks/config.yml b/ansible/roles/common/tasks/config.yml
index 46a27b8910..732ee05c9b 100644
--- a/ansible/roles/common/tasks/config.yml
+++ b/ansible/roles/common/tasks/config.yml
@@ -16,27 +16,31 @@
 
 - name: Copying over config.json files for services
   template:
-    src: "{{ item }}.json.j2"
-    dest: "{{ node_config_directory }}/{{ item }}/config.json"
-  with_items:
-    - "fluentd"
-    - "kolla-toolbox"
-    - "cron"
+    src: "{{ item.key }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item.key }}/config.json"
+  register: common_config_jsons
+  with_dict: "{{ common_services }}"
+  notify:
+    - "Restart {{ item.key }} container"
 
 - name: Copying over fluentd input config files
   template:
     src: "conf/input/{{ item }}.conf.j2"
     dest: "{{ node_config_directory }}/fluentd/input/{{ item }}.conf"
+  register: fluentd_input
   with_items:
     - "00-global"
     - "01-syslog"
     - "02-mariadb"
     - "03-rabbitmq"
+  notify:
+    - Restart fluentd container
 
 - name: Copying over fluentd output config files
   template:
     src: "conf/output/{{ item.name }}.conf.j2"
     dest: "{{ node_config_directory }}/fluentd/output/{{ item.name }}.conf"
+  register: fluentd_output
   when: item.enabled | bool
   with_items:
     - name: "00-local"
@@ -44,35 +48,47 @@
     - name: "01-es"
       enabled: "{{ enable_elasticsearch | bool or
                 ( elasticsearch_address != kolla_internal_vip_address ) | bool }}"
+  notify:
+    - Restart fluentd container
 
 - name: Copying over fluentd format config files
   template:
     src: "conf/format/{{ item }}.conf.j2"
     dest: "{{ node_config_directory }}/fluentd/format/{{ item }}.conf"
+  register: fluentd_format
   with_items:
     - "apache_access"
     - "wsgi_access"
     - "wsgi_python"
+  notify:
+    - Restart fluentd container
 
 - name: Copying over fluentd filter config files
   template:
     src: "conf/filter/{{ item }}.conf.j2"
     dest: "{{ node_config_directory }}/fluentd/filter/{{ item }}.conf"
+  register: fluentd_filter
   with_items:
     - "00-record_transformer"
     - "01-rewrite"
+  notify:
+    - Restart fluentd container
 
 - name: Copying over td-agent.conf
   template:
     src: "td-agent.conf.j2"
     dest: "{{ node_config_directory }}/{{ item }}/td-agent.conf"
+  register: fluentd_td_agent
   with_items:
     - "fluentd"
+  notify:
+    - Restart fluentd container
 
 - name: Copying over cron logrotate config files
   template:
     src: "cron-logrotate-{{ item.name }}.conf.j2"
     dest: "{{ node_config_directory }}/cron/logrotate/{{ item.name }}.conf"
+  register: cron_confs
   when: item.enabled | bool
   with_items:
     - { name: "ansible", enabled: "yes" }
@@ -125,3 +141,21 @@
     - { name: "trove", enabled: "{{ enable_trove }}" }
     - { name: "watcher", enabled: "{{ enable_watcher }}" }
     - { name: "zun", enabled: "{{ enable_zun }}" }
+  notify:
+    - Restart cron container
+
+- name: Check common containers
+  kolla_docker:
+    action: "compare_container"
+    common_options: "{{ docker_common_options }}"
+    name: "{{ item.value.container_name }}"
+    image: "{{ item.value.image }}"
+    volumes: "{{ item.value.volumes }}"
+    privileged: "{{ item.value.privileged | default(False) }}"
+    environment: "{{ item.value.environment }}"
+  register: check_common_containers
+  when:
+    - action != "config"
+  with_dict: "{{ common_services }}"
+  notify:
+    - "Restart {{ item.key }} container"
diff --git a/ansible/roles/common/tasks/deploy.yml b/ansible/roles/common/tasks/deploy.yml
index 98daa4021c..9eca42dec5 100644
--- a/ansible/roles/common/tasks/deploy.yml
+++ b/ansible/roles/common/tasks/deploy.yml
@@ -3,4 +3,5 @@
 
 - include: bootstrap.yml
 
-- include: start.yml
+- name: Flush handlers
+  meta: flush_handlers
diff --git a/ansible/roles/common/tasks/pull.yml b/ansible/roles/common/tasks/pull.yml
index 3cf41e2357..ac648a0f2d 100644
--- a/ansible/roles/common/tasks/pull.yml
+++ b/ansible/roles/common/tasks/pull.yml
@@ -1,18 +1,7 @@
 ---
-- name: Pulling kolla-toolbox image
+- name: Pulling common images
   kolla_docker:
     action: "pull_image"
     common_options: "{{ docker_common_options }}"
-    image: "{{ kolla_toolbox_image_full }}"
-
-- name: Pulling fluentd image
-  kolla_docker:
-    action: "pull_image"
-    common_options: "{{ docker_common_options }}"
-    image: "{{ fluentd_image_full }}"
-
-- name: Pulling cron image
-  kolla_docker:
-    action: "pull_image"
-    common_options: "{{ docker_common_options }}"
-    image: "{{ cron_image_full }}"
+    image: "{{ item.value.image }}"
+  with_dict: "{{ common_services }}"
diff --git a/ansible/roles/common/tasks/reconfigure.yml b/ansible/roles/common/tasks/reconfigure.yml
index 84e5c86c2b..e078ef1318 100644
--- a/ansible/roles/common/tasks/reconfigure.yml
+++ b/ansible/roles/common/tasks/reconfigure.yml
@@ -1,42 +1,2 @@
 ---
-- name: Ensuring the fluentd container is up
-  kolla_docker:
-    name: "fluentd"
-    action: "get_container_state"
-  register: container_state
-  failed_when: container_state.Running == false
-
-- include: config.yml
-
-- name: Checking the fluentd config
-  command: docker exec fluentd /usr/local/bin/kolla_set_configs --check
-  changed_when: false
-  failed_when: false
-  register: check_result
-
-- name: Getting the fluentd container config strategy
-  kolla_docker:
-    name: "fluentd"
-    action: "get_container_env"
-  register: container_env
-
-- name: Removing the fluentd container
-  kolla_docker:
-    name: "fluentd"
-    action: "remove_container"
-  register: remove_container
-  when:
-    - config_strategy == "COPY_ONCE" or container_env["KOLLA_CONFIG_STRATEGY"] == "COPY_ONCE"
-    - check_result.rc == 1
-
-- include: start.yml
-  when: remove_container.changed
-
-- name: Restarting the fluentd container
-  kolla_docker:
-    name: "fluentd"
-    action: "restart_container"
-  when:
-    - config_strategy == "COPY_ALWAYS"
-    - container_env["KOLLA_CONFIG_STRATEGY"] == "COPY_ALWAYS"
-    - check_result.rc == 1
+- include: deploy.yml
diff --git a/ansible/roles/common/tasks/start.yml b/ansible/roles/common/tasks/start.yml
deleted file mode 100644
index cfba855032..0000000000
--- a/ansible/roles/common/tasks/start.yml
+++ /dev/null
@@ -1,46 +0,0 @@
----
-- name: Starting fluentd container
-  kolla_docker:
-    action: "start_container"
-    common_options: "{{ docker_common_options }}"
-    environment:
-      KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
-      SKIP_LOG_SETUP: "true"
-    image: "{{ fluentd_image_full }}"
-    name: "fluentd"
-    volumes:
-      - "{{ node_config_directory }}/fluentd/:{{ container_config_directory }}/:ro"
-      - "/etc/localtime:/etc/localtime:ro"
-      - "kolla_logs:/var/log/kolla/"
-
-- name: Starting kolla-toolbox container
-  kolla_docker:
-    action: "start_container"
-    common_options: "{{ docker_common_options }}"
-    environment:
-      ANSIBLE_NOCOLOR: "1"
-      ANSIBLE_LIBRARY: "/usr/share/ansible"
-    image: "{{ kolla_toolbox_image_full }}"
-    name: "kolla_toolbox"
-    privileged: True
-    volumes:
-      - "{{ node_config_directory }}/kolla-toolbox/:{{ container_config_directory }}/:ro"
-      - "/etc/localtime:/etc/localtime:ro"
-      - "/dev/:/dev/"
-      - "/run/:/run/:shared"
-      - "kolla_logs:/var/log/kolla/"
-
-- name: Initializing toolbox container using normal user
-  command: docker exec -t kolla_toolbox /usr/bin/ansible --version
-  changed_when: false
-
-- name: Starting cron container
-  kolla_docker:
-    action: "start_container"
-    common_options: "{{ docker_common_options }}"
-    image: "{{ cron_image_full }}"
-    name: "cron"
-    volumes:
-      - "{{ node_config_directory }}/cron/:{{ container_config_directory }}/:ro"
-      - "/etc/localtime:/etc/localtime:ro"
-      - "kolla_logs:/var/log/kolla/"
diff --git a/ansible/roles/common/tasks/upgrade.yml b/ansible/roles/common/tasks/upgrade.yml
index 1f16915ad9..dd26ecc34d 100644
--- a/ansible/roles/common/tasks/upgrade.yml
+++ b/ansible/roles/common/tasks/upgrade.yml
@@ -1,4 +1,5 @@
 ---
 - include: config.yml
 
-- include: start.yml
+- name: Flush handlers
+  meta: flush_handlers