[OpenStack-Infra] [zuul] Change publication interface to be directories on node, not executor

Paul Belanger pabelanger at redhat.com
Thu Aug 2 17:06:42 UTC 2018


On Tue, Oct 10, 2017 at 05:42:12PM -0500, Monty Taylor wrote:
> Hey everybody!
> 
> I'd like to make a proposal for changing how we do logs/artifacts/docs
> collection based on the last few weeks/months of writing things- and of
> having to explain to people how to structure build and publish jobs over the
> last couple of weeks.
> 
> tl;dr - I'd like to change the publication interface to be directories on
> the remote node, not directories on the executor
> 
> Rationale
> =========
> 
> If jobs have to copy files back to the executor as part of the publication
> interface, then the zuul admins can't change the mechanism of how artifacts,
> logs or docs are published without touching a ton of potentially in-tree job
> content.
> 
> Doing so should also allow us to stop having a second copy of build logic in
> the artifact release jobs.
> 
> Implementation
> ==============
> 
> Define a root 'output' dir on the remote nodes. Different types of output
> can be collected by putting them into subdirectories of that dir on the
> remote nodes and expecting that base jobs will take care of them.
> 
> People using jobs defined in zuul-jobs should define a variable
> "zuul_output_dir", either in site-variables or in their base job. Jobs in
> zuul-jobs can and will depend on that variable existing - it will be
> considered part of the base job interface zuul-jobs expects.
> 
> Jobs in zuul-jobs will recognize three specific types of job output:
> * logs
> * artifacts
> * docs
> 
> Jobs in zuul-jobs will put job outputs into "{{ zuul_output_dir }}/logs",
> "{{ zuul_ouptut_dir }}/artifacts" and "{{ zuul_output_dir }}/docs" as
> appropriate.
> 
> A role will be added to zuul-jobs that can be used in base jobs that will
> ensure those directories all exist.
> 
> Compression
> -----------
> 
> Deployers may choose to have their base job compress items in {{
> zuul_output_dir }} as part of processing them, or may prefer not to
> depending on whether CPU or network is more precious. Jobs in zuul-jobs
> should just move/copy things into {{ zuul_output_dir }} on the node and
> leave compression, transfer and publication as a base-job operation.
> 
> Easy Output Copying
> -------------------
> 
> A role will also be added to zuul-jobs to facilitate easy/declarative output
> copying.
> 
> It will take as input a dictionary of files/folders named
> 'zuul_copy_output'. The role will copy contents into {{ zuul_output_dir }}
> on the remote node and is intended to be used before output fetching in a
> base job's post-playook.
> 
> The input will be a dictionary so that zuul variable merging can be used for
> accumulating.
> 
> Keys of the dictionary will be things to copy. Valid values will be the type
> of output to copy:
> 
> * logs
> * artifacts
> * docs
> * null   # ansible null, not the string null
> 
> null will be used for 'a parent job said to copy this, but this job wants to
> not do so'
> 
> The simple content copying role will not be flexible or powerful. People
> wanting more expressive output copying have all of the normal tools for
> moving files around at their disposal. It will obey the following rules:
> 
> * All files/folders will be copied if they exist, or ignored if they don't
> * Items will be copied as-if 'cp -a' had been used.
> * Order of files is undefined
> * Conflicts between declared files are an error.
> 
> Jobs defined in zuul-jobs should not depend on the {{ zuul_copy_output }}
> variable for content they need copied in place on a remote node. Jobs
> defined in zuul-jobs should instead copy their output to {{ zuul_output_dir
> }} This prevents zuul deployers from being required to put the easy output
> copying role into their base jobs. Jobs defined in zuul-jobs may use the
> role behind the scenes.
> 
> Filter Plugin
> -------------
> 
> Since the pattern of using a dictionary in job variables to take advantage
> of variable merging is bound to come up more than once, we'll define a
> filter plugin in zuul called 'zuul_list_from_value' (or some better name)
> that will return the list of keys that match a given value. So that given
> the following in a job defintion:
> 
> vars:
>   zuul_copy_output:
>     foo/bar.html: logs
>     other/logs/here.html: logs
>     foo/bar.tgz: artifacts
> 
> Corresponding Ansible could do:
> 
> - copy:
>     src: {{ item }}
>     dest: {{ zuul_log_dir }}
>   with_items: {{ zuul_copy_output | zuul_list_from_value(logs) }}
> 
> For OpenStack Today
> ===================
> 
> We will define zuul_output_dir to be "{{ ansible_user_dir }}/zuul-output" in
> our site-variables.yaml file.
> 
> Implement the following in OpenStack's base job:
> 
> We will have the base job will include the simple copying role.
> 
> Logs
> ----
> 
> Base job post playbook will always grab {{ zuul_output_dir }}/logs from
> nodes, same as today:
> * If there are more than one node, grab it into {{ zuul.executor.log_dir
> }}/{{ inventory_hostname }}.
> * If only one node, grab into  {{ zuul.executor.log_dir }} directly
> 
> This will mean moving things like 'fetch-tox-output' logic into the 'tox'
> role itself, so after it's run the appropriate tox logs will be copied to {{
> zuul_output_dir }}/logs
> 
> Artifacts and docs
> ------------------
> 
> Base job will always ...
> 
> * Grab {{ zuul_output_dir }}/artifacts and {{ zuul_output_dir }}/docs to {{
> zuul.executor.work_dir }}/artifacts and {{ zuul.executor.work_dir }}/docs
> * Publish docs content to logs.openstack.org/{{ zuul_log_path }}/docs -
> allows for easy setting of success-url to 'docs/html" in base jobs
> regardless of the subdir the job puts docs in to (see docs vs. releasenotes)
> * rsync docs content to logs.o.o/{{ zuul_log_path }}/docs after contents of
> {{ zuul_output_dir }}/logs so that explicit docs win if there is overlap
> * Sign each artifact
> * Copy each artifact to {{ zuul.project.short_name }}.{{ zuul.tag }}.{{
> suffix }} OR {{ zuul.project.short_name }}.{{ zuul.branch }}.{{ suffix }}
> depending on if {{ zuul.tag exists }} or not
> * If {{ zuul.change }} is set, upload artifacts to {{ zuul_log_path
> }}/artifacts - to allow people to iterate on artifact upload jobs in check
> and verify that they work
> * If {{ zuul.change }} is not set, upload artifacts to
> tarballs.openstack.org/{{ zuul.project.short_name }, same as today.
> Communicate artifact and docs upload paths to child jobs using:
> https://review.openstack.org/#/c/504808/
> 
++

I've made one small change your current logic, by creating new
fetch-zuul-log[2] and fetch-zuul-docs[3] roles. Only because I think it is much
easier to read then adding everything into a single fetch-output role.

We'd do the same for artifacts, and any new folder a zuul user would create.
This also allows an operator the ability to choose which role to also include
for their base jobs.

[2] https://review.openstack.org/583346/
[3] https://review.openstack.org/583350/

> Artifact Release jobs
> =====================
> 
> The release jobs become similar to v2 release jobs, but can be much more
> generalized and reusable. They can also mostly be nodeless jobs (javascript
> npm publication is a notable exception - it will need a node)
> 
> Artifacts
> ---------
> 
> * Fetch artifacts and signatures from tarballs.openstack.org/{{
> zuul.project.short_name }} - based on values set by parent job
> Verify fetched signature is correct
> * Upload artifact to appropriate destination(s) (pypi, npm, maven, etc)
> 
> Docs
> ----
> 
> * Rsync docs from logs.openstack.org/{{ zuul_log_path }}/docs - based on
> values set by parent job
> * Publish to release-job-specific destination as the current jobs do
> 
> This should allow us to make job/project/content specific publication jobs
> without needing those jobs to duplicate content in the build jobs.
> 
> It means we can ALSO put jobs like 'publish-to-pypi' in zuul-jobs without
> needing a second copy in openstack-zuul-jobs because openstack happens to
> builds tarballs differently. The pypi publication step is the same no matter
> how the tarball is produced.
> 
>     - jobs:
>         - build-openstack-sphinx-docs
>         - publish-sphinx-docs-to-afs:
>             dependencies:
>                 - build-openstack-sphinx-docs
> 
> Rollout
> =======
> 
> The steps should be fairly straightforward (and are fine to do post rollout)
> 
> * Add variable to site-variables
> * Add support to base job for creating directories and then copying content
> back
> * Add easy copy helper role
> * Start transitioning jobs in zuul-jobs and openstack-zuul-jobs to using the
> new interface - can be done one at a time
> * Update usage
> 
> If people are ok with the direction generally, we should be able to get the
> enablement pieces in pretty quickly.
> 
> Monty
> 
I'd like to first land our base-minimal[3] (trusted) / base (untrusted) changes
then this. But I've already done some testing of new log publishing[4] and works
as expected.

- Paul

[3] https://review.openstack.org/#/q/topic:base-minimal-jobs
[4] https://review.openstack.org/584614/



More information about the OpenStack-Infra mailing list