Re-factored resources upload into role
Whole functionality of resource files upload is
implemented in resource-data role instead of
playbook level tasks.
This will make roles easier to test
and make it easier to implement other OS support later.
Issue-ID: OOM-1654
Change-Id: I3d3da9381b0e804f511ee854c41554b924d18883
Signed-off-by: Samuli Silvius <s.silvius@partner.samsung.com>
diff --git a/ansible/roles/resource-data/defaults/main.yml b/ansible/roles/resource-data/defaults/main.yml
new file mode 100644
index 0000000..8a1adfa
--- /dev/null
+++ b/ansible/roles/resource-data/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+resources_on_nfs: no
diff --git a/ansible/roles/resource-data/tasks/main.yml b/ansible/roles/resource-data/tasks/main.yml
index 5112722..bcdc7dd 100644
--- a/ansible/roles/resource-data/tasks/main.yml
+++ b/ansible/roles/resource-data/tasks/main.yml
@@ -1,2 +1,31 @@
---
-- include_tasks: "{{ transport }}-upload.yml"
+- name: Collect source resources
+ block:
+ - name: Check if source dir and files are present
+ stat:
+ path: "{{ item.source }}"
+ loop:
+ - { source: "{{ resources_dir }}/{{ resources_filename | default('thisdoesnotexists', true) }}",
+ target: "{{ app_data_path }}/{{ resources_filename | default('thisdoesnotexists', true) }}" }
+ - { source: "{{ resources_dir }}/{{ aux_resources_filename | default('thisdoesnotexists', true) }}",
+ target: "{{ aux_data_path }}/{{ aux_resources_filename | default('thisdoesnotexists', true) }}" }
+ register: source_path
+
+ - name: Create initial resources list of dicts
+ set_fact:
+ to_be_uploaded_resources_list: "{{
+ to_be_uploaded_resources_list | default([]) + [
+ {'file': item.item.target | basename,
+ 'destination_dir': item.item.target | dirname } ] }}"
+ loop: "{{ source_path.results }}"
+ when: item.stat.exists
+ when: inventory_hostname in groups.resources
+
+- name: "Upload resource files {{ hostvars[groups.resources.0].to_be_uploaded_resources_list }} to infrastructure"
+ include_tasks: upload_resources.yml
+ vars:
+ resources_source_host: "{{ hostvars[groups.resources.0].ansible_host | default(hostvars[groups.resources.0].inventory_hostname) }}"
+ resources_list_of_dicts: "{{ hostvars[groups.resources.0].to_be_uploaded_resources_list }}"
+ when:
+ - inventory_hostname in groups.infrastructure
+ - hostvars[groups.resources.0].to_be_uploaded_resources_list is defined
diff --git a/ansible/roles/resource-data/tasks/nfs-upload.yml b/ansible/roles/resource-data/tasks/nfs-upload.yml
deleted file mode 100644
index 4b5c18d..0000000
--- a/ansible/roles/resource-data/tasks/nfs-upload.yml
+++ /dev/null
@@ -1,53 +0,0 @@
----
-- name: Upload resources to infrastructure servers over nfs
- block:
- - name: Mount resources
- mount:
- path: /tmp/resource_data
- src: "{{ hostvars[groups.resources.0].ansible_host }}:{{ hostvars[groups.resources.0].resources_dir }}"
- fstype: nfs
- state: mounted
-
- - name: Unarchive resources
- unarchive:
- src: "/tmp/resource_data/{{ hostvars[groups.resources.0].resources_filename }}"
- remote_src: yes
- dest: "{{ app_data_path }}"
- when: not resources_data_check.stat.exists
-
- - name: Unarchive auxiliary resources
- unarchive:
- src: "/tmp/resource_data/{{ hostvars[groups.resources.0].aux_resources_filename }}"
- remote_src: yes
- dest: "{{ aux_data_path }}"
- when: >
- hostvars[groups.resources.0].aux_resources_filename is defined
- and hostvars[groups.resources.0].aux_resources_filename is not none
- and aux_data_path is defined and aux_data_path is not none
- and hostvars[groups.resources.0].aux_file_presence.stat.exists
- and not aux_resources_data_check.stat.exists
-
- rescue:
- - name: Removing the resources data due to an error - so the next run can try again
- command: /bin/false
- register: upload_failed
-
- always:
- - name: unmount resource dir
- mount:
- path: /tmp/resource_data
- src: "{{ hostvars[groups.resources.0].ansible_host }}:{{hostvars[groups.resources.0].resources_dir }}"
- fstype: nfs
- state: absent
-
- - name: Remove the resource data on error
- file:
- path: "{{ app_data_path }}"
- state: absent
- when: upload_failed is defined
-
- - name: Remove the auxilliary resource data on error
- file:
- path: "{{ aux_data_path }}"
- state: absent
- when: upload_failed is defined
diff --git a/ansible/roles/resource-data/tasks/ssh-upload.yml b/ansible/roles/resource-data/tasks/ssh-upload.yml
deleted file mode 100644
index bc7df37..0000000
--- a/ansible/roles/resource-data/tasks/ssh-upload.yml
+++ /dev/null
@@ -1,60 +0,0 @@
----
-- name: Upload resources to infrastructure servers over ssh
- block:
- - name: Upload ssh private key
- copy:
- src: "{{ ansible_ssh_private_key_file }}"
- dest: /root/.ssh/infra_to_resource.privkey
- mode: 0600
- owner: root
- group: root
- remote_src: no
-
- - name: Unarchive resources
- shell: >
- ssh -o StrictHostKeyChecking=no -o BatchMode=yes
- -i /root/.ssh/infra_to_resource.privkey
- {{ hostvars[groups.resources.0].ansible_host }}
- 'cat "{{ hostvars[groups.resources.0].resources_dir }}/{{ hostvars[groups.resources.0].resources_filename }}"'
- | tar -C "{{ app_data_path }}" -xf -
- args:
- warn: False
- when: not resources_data_check.stat.exists
-
- - name: Unarchive auxiliary resources
- shell: >
- ssh -i /root/.ssh/infra_to_resource.privkey
- {{ hostvars[groups.resources.0].ansible_host }}
- 'cat "{{ hostvars[groups.resources.0].resources_dir }}/{{ hostvars[groups.resources.0].aux_resources_filename }}"'
- | tar -C "{{ aux_data_path }}" -xf -
- when: >
- hostvars[groups.resources.0].aux_resources_filename is defined
- and hostvars[groups.resources.0].aux_resources_filename is not none
- and aux_data_path is defined and aux_data_path is not none
- and hostvars[groups.resources.0].aux_file_presence.stat.exists
- and not aux_resources_data_check.stat.exists
- args:
- warn: False
-
- rescue:
- - name: Removing the resources data due to an error - so the next run can try again
- command: /bin/false
- register: upload_failed
-
- always:
- - name: Remove the ssh private key
- file:
- path: /root/.ssh/infra_to_resource.privkey
- state: absent
-
- - name: Remove the resource data on error
- file:
- path: "{{ app_data_path }}"
- state: absent
- when: upload_failed is defined
-
- - name: Remove the auxilliary resource data on error
- file:
- path: "{{ aux_data_path }}"
- state: absent
- when: upload_failed is defined
diff --git a/ansible/roles/resource-data/tasks/unarchive-nfs-resource.yml b/ansible/roles/resource-data/tasks/unarchive-nfs-resource.yml
new file mode 100644
index 0000000..9baca2f
--- /dev/null
+++ b/ansible/roles/resource-data/tasks/unarchive-nfs-resource.yml
@@ -0,0 +1,34 @@
+---
+#
+# Expected variables
+# resources_source_host
+# resources_dir
+# resource_source_filename
+# resource_destination_directory
+# Output is upload_failed true/false
+#
+- name: "Upload resource {{ resources_dir }}/{{ resource_source_filename }} to infrastructure servers over nfs"
+ block:
+ - name: Mount resource dir
+ mount:
+ path: /tmp/resource_data
+ src: "{{ resources_source_host }}:{{ resources_dir }}"
+ fstype: nfs
+ state: mounted
+
+ - name: "Unarchive resource {{ resources_dir }}/{{ resource_source_filename }} to {{ resource_destination_directory }} dir on infrastructure servers over nfs"
+ unarchive:
+ src: "/tmp/resource_data/{{ resource_source_filename }}"
+ dest: "{{ resource_destination_directory }}"
+ remote_src: yes
+ rescue:
+ - name: Upload failed
+ set_fact:
+ upload_failed: true
+ always:
+ - name: Unmount resource dir
+ mount:
+ path: /tmp/resource_data
+ src: "{{ resources_source_host }}:{{ resources_dir }}"
+ fstype: nfs
+ state: absent
diff --git a/ansible/roles/resource-data/tasks/unarchive-resource.yml b/ansible/roles/resource-data/tasks/unarchive-resource.yml
new file mode 100644
index 0000000..9eafc22
--- /dev/null
+++ b/ansible/roles/resource-data/tasks/unarchive-resource.yml
@@ -0,0 +1,36 @@
+---
+#
+# Wrapper to pass through following variables
+# resources_source_host
+# resources_dir
+# resource_source_filename
+# resource_destination_directory
+# And handling target directory creation and possible removal on failure.
+# Idempotence is also handled here as nothing is done if resource_destination_directory
+# was already created.
+#
+# Logically also tranport method selection belongs to here but left it to caller
+# as this is called in a loop causing "package_facts" called many times
+# (not sure if it would matter).
+#
+- name: "Create {{ resource_destination_directory }} directory"
+ file:
+ path: "{{ resource_destination_directory }}"
+ state: directory
+ register: create_destination_dir
+
+- name: "Handle transport of one archive file"
+ block:
+ - name: Re-set upload_failed
+ set_fact:
+ upload_failed: false
+
+ - name: "Unarchive resource {{ resource_source_filename }} from host {{ resources_source_host }}, transport is {{ transport }}"
+ include_tasks: "unarchive-{{ transport }}-resource.yml"
+
+ - name: "Remove the destination directory {{ resource_destination_directory }} on error"
+ file:
+ path: "{{ resource_destination_directory }}"
+ state: absent
+ when: upload_failed
+ when: create_destination_dir.changed
diff --git a/ansible/roles/resource-data/tasks/unarchive-ssh-resource.yml b/ansible/roles/resource-data/tasks/unarchive-ssh-resource.yml
new file mode 100644
index 0000000..4b1b7d7
--- /dev/null
+++ b/ansible/roles/resource-data/tasks/unarchive-ssh-resource.yml
@@ -0,0 +1,51 @@
+---
+#
+# Expected variables
+# resources_source_host
+# resources_dir
+# resource_source_filename
+# resource_destination_directory
+# Output is upload_failed true/false
+#
+- name: "Upload resource {{ resources_dir }}/{{ resource_source_filename }} to infrastructure servers over ssh"
+ block:
+ - name: Upload ssh private key
+ copy:
+ src: "{{ ansible_ssh_private_key_file }}"
+ dest: /root/.ssh/infra_to_resource.privkey
+ mode: 0600
+ owner: root
+ group: root
+ remote_src: no
+
+ - name: Detect if archive is compressed
+ shell: >
+ ssh -o StrictHostKeyChecking=no
+ -i /root/.ssh/infra_to_resource.privkey
+ {{ resources_source_host }}
+ 'file "{{ resources_dir }}/{{ resource_source_filename }}"'
+ | grep "compressed"
+ register: compressed
+
+ - name: Set tar extract options
+ set_fact:
+ tar_extract_options: "{{ '-xzf' if compressed.rc == 0 else '-xf' }}"
+
+ - name: "Unarchive resource {{ resources_dir }}/{{ resource_source_filename }} to {{ resource_destination_directory }} dir on infrastructure servers over ssh"
+ shell: >
+ ssh -o StrictHostKeyChecking=no -o BatchMode=yes
+ -i /root/.ssh/infra_to_resource.privkey
+ {{ resources_source_host }}
+ 'cat "{{ resources_dir }}/{{ resource_source_filename }}"'
+ | tar -C "{{ resource_destination_directory }}" "{{ tar_extract_options }}" -
+ args:
+ warn: false
+ rescue:
+ - name: Upload failed
+ set_fact:
+ upload_failed: true
+ always:
+ - name: Remove the ssh private key
+ file:
+ path: /root/.ssh/infra_to_resource.privkey
+ state: absent
diff --git a/ansible/roles/resource-data/tasks/upload_resources.yml b/ansible/roles/resource-data/tasks/upload_resources.yml
new file mode 100644
index 0000000..571bc7d
--- /dev/null
+++ b/ansible/roles/resource-data/tasks/upload_resources.yml
@@ -0,0 +1,15 @@
+---
+- name: Query package facts to check nfs-utils existence
+ package_facts:
+ manager: auto
+
+- name: Set transport fact to nfs or ssh
+ set_fact:
+ transport: "{{ 'nfs' if resources_on_nfs and 'nfs-utils' in ansible_facts.packages else 'ssh' }}"
+
+- name: "Upload resources to infrastructure servers over {{ transport }}"
+ include_tasks: unarchive-resource.yml
+ vars:
+ resource_source_filename: "{{ item.file }}"
+ resource_destination_directory: "{{ item.destination_dir }}"
+ loop: "{{ resources_list_of_dicts }}"