Browse Source

Combine artifact URLs with log_url if relative

The plan for the idea of a "promote" pipeline is to fetch
previously uploaded artifacts from the build log server
and move them to the final publication location.  However,
jobs which store data (such as documentation builds,
tarballs, or container images) on the log server should not
need to know the configuration of the log server in order
to return the artifact URL to zuul.  To support this, if
the job returns a relative URL for an artifact, assume it
is relative to the log URL for the build and combine the
two when storing the artifact info.

Change-Id: I4bce2401c9e59fd469e3b3da2973514c07faecf2
tags/3.5.0
James E. Blair 5 months ago
parent
commit
b7c68c2f76

+ 4
- 1
doc/source/user/jobs.rst View File

@@ -755,7 +755,10 @@ under the **zuul.artifacts** dictionary.  For example:
755 755
               - name: tarball
756 756
                 url: http://example.com/path/to/package.tar.gz
757 757
               - name: docs
758
-                url: http://example.com/path/to/docs
758
+                url: build/docs/
759
+
760
+If the value of **url** is a relative URL, it will be combined with
761
+the **zuul.log_url** value if set to create an absolute URL.
759 762
 
760 763
 Skipping child jobs
761 764
 ~~~~~~~~~~~~~~~~~~~

+ 4
- 0
tests/fixtures/config/sql-driver/git/common-config/playbooks/project-test1.yaml View File

@@ -4,8 +4,12 @@
4 4
       zuul_return:
5 5
         data:
6 6
           zuul:
7
+            log_url: http://logs.example.com/build
8
+            foo: bar
7 9
             artifacts:
8 10
               - name: tarball
9 11
                 url: http://example.com/tarball
10 12
               - name: docs
11 13
                 url: http://example.com/docs
14
+              - name: relative
15
+                url: relative/docs

+ 3
- 1
tests/unit/test_web.py View File

@@ -701,10 +701,12 @@ class TestArtifacts(ZuulDBTestCase, BaseTestWeb, AnsibleZuulTestCase):
701 701
                                    "project=org/project&"
702 702
                                    "job_name=project-test1").json()
703 703
         self.assertEqual(len(build_query), 1)
704
-        self.assertEqual(len(build_query[0]['artifacts']), 2)
704
+        self.assertEqual(len(build_query[0]['artifacts']), 3)
705 705
         self.assertEqual(build_query[0]['artifacts'], [
706 706
             {'url': 'http://example.com/tarball',
707 707
              'name': 'tarball'},
708 708
             {'url': 'http://example.com/docs',
709 709
              'name': 'docs'},
710
+            {'url': 'http://logs.example.com/build/relative/docs',
711
+             'name': 'relative'},
710 712
         ])

+ 23
- 2
zuul/driver/sql/sqlreporter.py View File

@@ -16,6 +16,7 @@ import datetime
16 16
 import logging
17 17
 import time
18 18
 import voluptuous as v
19
+import urllib.parse
19 20
 
20 21
 from zuul.reporter import BaseReporter
21 22
 
@@ -32,7 +33,9 @@ class SQLReporter(BaseReporter):
32 33
     }
33 34
     zuul_data = {
34 35
         'zuul': {
35
-            'artifacts': [artifact]
36
+            'log_url': str,
37
+            'artifacts': [artifact],
38
+            v.Extra: object,
36 39
         }
37 40
     }
38 41
     artifact_schema = v.Schema(zuul_data)
@@ -103,11 +106,29 @@ class SQLReporter(BaseReporter):
103 106
                 if self.validateArtifactSchema(build.result_data):
104 107
                     artifacts = build.result_data.get('zuul', {}).get(
105 108
                         'artifacts', [])
109
+                    default_url = build.result_data.get('zuul', {}).get(
110
+                        'log_url')
111
+                    if default_url:
112
+                        if default_url[-1] != '/':
113
+                            default_url += '/'
106 114
                     for artifact in artifacts:
115
+                        url = artifact['url']
116
+                        if default_url:
117
+                            # If the artifact url is relative, it will
118
+                            # be combined with the log_url; if it is
119
+                            # absolute, it will replace it.
120
+                            try:
121
+                                url = urllib.parse.urljoin(default_url, url)
122
+                            except Exception:
123
+                                self.log.debug("Error parsing URL:",
124
+                                               exc_info=1)
107 125
                         db_build.createArtifact(
108 126
                             name=artifact['name'],
109
-                            url=artifact['url'],
127
+                            url=url,
110 128
                         )
129
+                else:
130
+                    self.log.debug("Result data did not pass artifact schema "
131
+                                   "validation: %s", build.result_data)
111 132
 
112 133
 
113 134
 def getSchema():

Loading…
Cancel
Save