Add a generic stage-output role

This role does roughly what save_dir and save_file do in d-g
functions, only it can be used for a list of files and/or
folders. Jobs can use this role to rename artifacts and place
them in a staging folder which is then used for mass sync to
the executor.

This is typically used in post - the zuul user won't necessarily
have write access to the folders with the artifacts - so it's
easier to stage everything to a folder owned by the zuul user.

Change-Id: Id45a50821539985710da7172a9185fd91e803603
This commit is contained in:
Andrea Frittoli (andreaf) 2017-10-03 17:07:35 +01:00 committed by Andrea Frittoli
parent e617405939
commit 786c48f051
3 changed files with 98 additions and 0 deletions

View File

@ -0,0 +1,49 @@
Stage job output on the remote node
Takes as input a dictionary of files/folders named 'zuul_copy_output'.
Copies contents into {{ zuul_output_dir }} on the remote node and is
intended to be used before output fetching in a base job's post-playbook.
**Role Variables**
.. zuul:rolevar:: zuul_copy_output
:default: None
Dictionary of files and folders to be staged.
The input is a dictionary so that it can accumulated via zuul variable
merging. Keys of the dictionary will be things to copy. Valid values
describe the type of output to copy:
* logs
* artifacts
* docs
* null # ansible null, not the string null
null overrides the will of a parent job to copy something instructing
not to copy.
.. zuul:rolevar:: stage_dir
:default: {{ ansible_user_dir }}
The stage directory on the remote node.
.. zuul:rolevar:: extensions_to_txt
:default: null
A list of file extensions to be replaced with .txt when staging.
This can be useful to ensure that text files with an extension not
registered in the web server may be viewed via browser when uploaded
to a file server.
Note that this is only used for files listed directly in
`zuul_copy_output` and it won't be applied to files contained in
folders listed in `zuul_copy_output`.
Example:
extensions_to_txt:
- conf
- log
zuul.conf --(staged as)--> zuul_conf.txt

View File

@ -0,0 +1,2 @@
stage_dir: "{{ ansible_user_dir }}"
extensions_to_txt:

View File

@ -0,0 +1,47 @@
- name: Register sources
stat:
path: "{{ item.key }}"
with_dict: "{{ zuul_copy_output }}"
register: sources
- name: Build the replace regex
set_fact:
extensions_regex: "{{ extensions_to_txt | join('|') | default('__do_not_replace__') }}"
- debug:
var: extensions_regex
# TODO(andreaf) We might want to enforce that item.value is a valid value
# in docs, artifacts, logs. Null case already handled.
# We don't check if the item is a file before renaming, but it is not likely
# to have directories with log, yaml or conf extension.
- name: Set source and destination for files and folders
set_fact:
source: "{{ item.stat.path }}"
dest: "{{ item.item.value }}/{{ item.stat.path|basename|regex_replace('\\.(' + extensions_regex + ')$', '_\\1.txt') }}"
with_items: "{{ sources.results }}"
when:
- item.stat.exists
- item.item.value
register: results
- name: Build a list of source, dest dictionaries for text files
set_fact:
all_sources: "{{ results.results | selectattr('ansible_facts', 'defined') | map(attribute='ansible_facts') | list }}"
- name: ensure target folders exist
become: true
file:
path: "{{ stage_dir }}/{{ item }}"
state: directory
owner: "{{ ansible_user }}"
with_items:
- docs
- artifacts
- logs
- name: Copy text files to staging folder
# remote_src copy does not work recursively, synchronise is restricted by
# zuul, using command
command: cp -pR {{ item.source}} {{ stage_dir }}/{{ item.dest }}
with_items: "{{ all_sources }}"