Browse Source

[tripleo_transfer] Do transfers directly from src to dst

When running fetch with become, the slurp module will also
be used to fetch the contents of the file for determining
the remote checksum. This effectively doubles the transfer
size [0] and shows up as a MemoryError when the file size
is large enough.

In TripleO this is problematic in large & old deployments
when transferring the /var/lib/mysql folder.

This patch switches to using rsync directly between the src
and dst hosts to transfer the data. This is advantageous not
only for solving the above-mentioned bug, but is also faster.

A simpler implementation using synchronize was attempted [1],
but there were issues with the mistral container which
prevented that approach from being successful.

[0] https://docs.ansible.com/ansible/latest/collections/ansible/builtin/fetch_module.html#notes
[1] https://review.opendev.org/c/openstack/tripleo-ansible/+/776565/11

Closes-Bug: #1908425
Closes-Bug: rhbz#1904681
Closes-Bug: rhbz#1916162
Depends-On: https://review.opendev.org/778650

Change-Id: Ifc03f9eb1cb4ca3faec194569f4cb2dace93323f
(cherry picked from commit d7730980c9)
changes/65/778665/2
Jose Luis Franco Arza 3 months ago
committed by Jesse Pretorius (odyssey4me)
parent
commit
eb70943c2d
5 changed files with 100 additions and 98 deletions
  1. +6
    -4
      tripleo_ansible/roles/tripleo-transfer/defaults/main.yml
  2. +8
    -1
      tripleo_ansible/roles/tripleo-transfer/molecule/default/playbook.yml
  3. +0
    -7
      tripleo_ansible/roles/tripleo-transfer/tasks/flag.yml
  4. +78
    -80
      tripleo_ansible/roles/tripleo-transfer/tasks/main.yml
  5. +8
    -6
      tripleo_ansible/roles/tripleo-transfer/vars/main.yml

+ 6
- 4
tripleo_ansible/roles/tripleo-transfer/defaults/main.yml View File

@ -23,10 +23,12 @@
# * `tripleo_transfer_src_dir` -- directory on the source host to transfer from
# * `tripleo_transfer_dest_host` -- the inventory name of the destination host
# * `tripleo_transfer_dest_dir` -- directory on the destination host to transfer to
tripleo_transfer_storage_root_dir: /var/lib/mistral/tripleo-transfer
tripleo_transfer_storage_root_become: false
tripleo_transfer_src_become: true
tripleo_transfer_dest_become: true
tripleo_transfer_dest_wipe: true
tripleo_transfer_flag_file: ~
# tripleo_transfer_key_location: location of the private key used to connect
# from src host to dest host.
tripleo_transfer_key_location: "~/transfer_key"
# tripleo_transfer_cleanup_keys: clean up the keypair from the source host
# and remove public key from destination host when true.
tripleo_transfer_cleanup_keys: true

+ 8
- 1
tripleo_ansible/roles/tripleo-transfer/molecule/default/playbook.yml View File

@ -14,6 +14,14 @@
# License for the specific language governing permissions and limitations
# under the License.
- name: Collect facts
hosts: all
gather_facts: false
any_errors_fatal: true
tasks:
- name: Gather a minimal set of facts
setup:
gather_subset: '!all,min'
- name: Converge
hosts: localhost
@ -25,4 +33,3 @@
tripleo_transfer_src_dir: /etc
tripleo_transfer_dest_host: controller1
tripleo_transfer_dest_dir: /opt/etc-target
tripleo_transfer_storage_root_dir: /tmp/transfer-staging

+ 0
- 7
tripleo_ansible/roles/tripleo-transfer/tasks/flag.yml View File

@ -19,8 +19,6 @@
stat:
path: "{{ tripleo_transfer_flag_file }}"
register: tripleo_transfer_flag_stat
become: "{{ tripleo_transfer_dest_become }}"
delegate_to: "{{ tripleo_transfer_dest_host }}"
- name: fail if flag file exists
fail:
@ -32,18 +30,13 @@
and re-run the data transfer.
when:
- tripleo_transfer_flag_stat.stat.exists
delegate_to: "{{ tripleo_transfer_dest_host }}"
- name: ensure directory for flag file exists
file:
path: "{{ tripleo_transfer_flag_file|dirname }}"
state: directory
become: "{{ tripleo_transfer_dest_become }}"
delegate_to: "{{ tripleo_transfer_dest_host }}"
- name: create the flag file
file:
path: "{{ tripleo_transfer_flag_file }}"
state: touch
become: "{{ tripleo_transfer_dest_become }}"
delegate_to: "{{ tripleo_transfer_dest_host }}"

+ 78
- 80
tripleo_ansible/roles/tripleo-transfer/tasks/main.yml View File

@ -15,89 +15,87 @@
# under the License.
- name: make sure we don't have a trailing forward slash in the src
set_fact:
tripleo_transfer_src_dir_safe: "{{ tripleo_transfer_src_dir | regex_replace('\\/$', '') }}"
cacheable: false
# Note:
# This role is used in a playbook that typically targets the undercloud
# and may target other hosts, so to ensure that it executes against the
# right src and dest it uses delegation throughout.
- name: make sure we don't have a trailing forward slash in the dst
set_fact:
tripleo_transfer_dest_dir_safe: "{{ tripleo_transfer_dest_dir | regex_replace('\\/$', '') }}"
cacheable: false
- name: tripleo_transfer tasks
run_once: true
block:
- name: install requirements in src and dest hosts
become: true
package:
name:
- rsync
- openssh-clients
state: present
delegate_to: "{{ item }}"
loop:
- "{{ tripleo_transfer_src_host }}"
- "{{ tripleo_transfer_dest_host }}"
- name: ensure local storage directory exists and has correct permissions
file:
path: "{{ tripleo_transfer_storage_root_dir }}"
# Attempting to set an owner fails with "chown failed: failed to
# look up user" so we at least ensure the permissions.
mode: 0700
state: directory
delegate_to: localhost
become: "{{ tripleo_transfer_storage_root_become }}"
- name: generate ssh key-pair in source host
openssh_keypair:
path: "{{ tripleo_transfer_key_location }}"
delegate_to: "{{ tripleo_transfer_src_host }}"
become: "{{ tripleo_transfer_src_become }}"
register: keypair_gen
- name: create tempfile for the archive
tempfile:
prefix: ansible.tripleo-transfer.
register: tripleo_transfer_tempfile
become: "{{ tripleo_transfer_src_become }}"
delegate_to: "{{ tripleo_transfer_src_host }}"
- name: set authorized-keys in destination host
authorized_key:
comment: "Added by tripleo-transfer"
user: "{{ ansible_user|default(ansible_ssh_user|default(hostvars[tripleo_transfer_dest_host].ansible_user_id)) }}"
state: present
key: "{{ keypair_gen.public_key }}"
delegate_to: "{{ tripleo_transfer_dest_host }}"
when: keypair_gen is succeeded
# Using the "archive" module lists lists all tarred files in module
# output, if there's too many files, it can crash ansible even with
# "no_log: true".
- name: create the archive
shell: |-
set -euo pipefail
tar --transform "s|^{{ tripleo_transfer_src_dir_safe | basename }}|{{ tripleo_transfer_dest_dir_safe | basename }}|" \
-czf "{{ tripleo_transfer_tempfile.path }}" \
-C "{{ tripleo_transfer_src_dir_safe | dirname }}" \
"{{ tripleo_transfer_src_dir_safe | basename }}"
become: "{{ tripleo_transfer_src_become }}"
delegate_to: "{{ tripleo_transfer_src_host }}"
- import_tasks: flag.yml
when:
- tripleo_transfer_flag_file != None
- tripleo_transfer_flag_file|length > 0
become: "{{ tripleo_transfer_dest_become }}"
delegate_to: "{{ tripleo_transfer_dest_host }}"
- name: fetch the archive
fetch:
src: "{{ tripleo_transfer_tempfile.path }}"
dest: "{{ tripleo_transfer_storage_root_dir }}/{{ tripleo_transfer_dest_host }}{{ tripleo_transfer_dest_dir_safe }}.tar.gz"
flat: true
become: "{{ tripleo_transfer_src_become }}"
delegate_to: "{{ tripleo_transfer_src_host }}"
- name: synchronize both directories
vars:
hostvars_dest_host_ip: >-
{{ hostvars[tripleo_transfer_dest_host].ansible_host |
default(hostvars[tripleo_transfer_dest_host].inventory_hostname) }}
tripleo_transfer_dest_user: >-
{{ hostvars[tripleo_transfer_dest_host].ansible_user |
default(hostvars[tripleo_transfer_dest_host].ansible_ssh_user |
default(hostvars[tripleo_transfer_dest_host].ansible_user_id)) }}
shell: >-
/usr/bin/rsync
-v
--delay-updates
-F
--compress
--archive
--delete
--rsync-path='sudo rsync'
--rsh='ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i {{ tripleo_transfer_key_location }}'
{{ tripleo_transfer_src_dir_safe }}
{{ tripleo_transfer_dest_user }}@{{ hostvars_dest_host_ip }}:{{ tripleo_transfer_dest_dir_safe }}
become: "{{ tripleo_transfer_src_become }}"
delegate_to: "{{ tripleo_transfer_src_host }}"
always:
- name: clean up keys in source host
file:
path: "{{ item }}"
state: absent
delegate_to: "{{ tripleo_transfer_src_host }}"
become: "{{ tripleo_transfer_src_become }}"
loop:
- "{{ tripleo_transfer_key_location }}"
- "{{ tripleo_transfer_key_location }}.pub"
- name: remove tempfile
file:
name: "{{ tripleo_transfer_tempfile.path }}"
state: absent
become: "{{ tripleo_transfer_src_become }}"
delegate_to: "{{ tripleo_transfer_src_host }}"
- include_tasks: flag.yml
when:
- tripleo_transfer_flag_file != None
- tripleo_transfer_flag_file|length > 0
- name: wipe the destination directory
file:
path: "{{ tripleo_transfer_dest_dir_safe }}"
state: absent
become: "{{ tripleo_transfer_dest_become }}"
delegate_to: "{{ tripleo_transfer_dest_host }}"
when: tripleo_transfer_dest_wipe|bool
- name: make sure the destination parent directory is present
file:
path: "{{ tripleo_transfer_dest_dir_safe|dirname }}"
state: directory
become: "{{ tripleo_transfer_dest_become }}"
delegate_to: "{{ tripleo_transfer_dest_host }}"
- name: push and extract the archive
unarchive:
src: "{{ tripleo_transfer_storage_root_dir }}/{{ tripleo_transfer_dest_host }}{{ tripleo_transfer_dest_dir_safe }}.tar.gz"
dest: "{{ tripleo_transfer_dest_dir_safe|dirname }}"
become: "{{ tripleo_transfer_dest_become }}"
delegate_to: "{{ tripleo_transfer_dest_host }}"
- name: remove the local archive
file:
path: "{{ tripleo_transfer_storage_root_dir }}/{{ tripleo_transfer_dest_host }}{{ tripleo_transfer_dest_dir_safe }}.tar.gz"
state: absent
- name: remove public key from authorized keys in destination host
lineinfile:
path: "~/.ssh/authorized_keys"
state: absent
regexp: '.*Added by tripleo-transfer.*$'
delegate_to: "{{ tripleo_transfer_dest_host }}"
when: tripleo_transfer_cleanup_keys | bool

tripleo_ansible/roles/tripleo-transfer/tasks/cleanup.yml → tripleo_ansible/roles/tripleo-transfer/vars/main.yml View File


Loading…
Cancel
Save