Merge ~pieq/oem-qa-autosummary:fix-1945724-image-url into oem-qa-autosummary:master

Proposed by Pierre Equoy
Status: Merged
Approved by: Pierre Equoy
Approved revision: 81acbf987a25a4bc243f829afc1be65b7fb77aec
Merged at revision: 1339810a70127fd5baa8db7bd4387da1bba39f06
Proposed branch: ~pieq/oem-qa-autosummary:fix-1945724-image-url
Merge into: oem-qa-autosummary:master
Diff against target: 172 lines (+35/-28)
4 files modified
autosummary/summary.py (+28/-21)
webapp/__init__.py (+3/-3)
webapp/static/style.css (+1/-1)
webapp/templates/image_info.html (+3/-3)
Reviewer Review Type Date Requested Status
Nara Huang (community) Approve
StanleyHuang Approve
Review via email: mp+414387@code.launchpad.net

Description of the change

See issue lp:1945724 for more context.

With this MR, if auto-summary cannot find the mail.content file that contains the image name and the image sha256, it will ask user to manually enter the full URL to that image, and use it to compute the WebDAV URI to download the associated sha256 file that contains the image sha256 value.

This is a bit more flexible than the current situation where user can only input the image name, and not the URL.

To see it in action, check the following screen recording:

https://drive.google.com/file/d/1-ufHaCMXlMpfABC-i4gkpq957l6wVOrd/view?usp=sharing

1. The carlsbad project is selected, with the x03 milestone.
2. The mail.content file cannot be found, so user manually inputs full URL to the image name
3. The webapp computes the WebDAV URI to point to the file containing the sha256 value and use it in the generated summary.

NOTE: In the above video, I use the x03 milestone, but then paste the URL to a x02 milestone image. This is for demonstration purpose only, because the x03 milestone for that project is actually not out yet.

To post a comment you must log in.
Revision history for this message
StanleyHuang (stanley31) wrote :

LGTM +1

review: Approve
Revision history for this message
Nara Huang (narahuang) wrote :

LGTM +1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/autosummary/summary.py b/autosummary/summary.py
2index 9a08276..6117361 100644
3--- a/autosummary/summary.py
4+++ b/autosummary/summary.py
5@@ -12,23 +12,19 @@ WEBDAV_CREDENTIALS = os.environ.get("WEBDAV_CREDENTIALS")
6
7 class MailContentNotFoundError(FileNotFoundError):
8 """Raised when the mail.content file is not found on the WebDAV server"""
9- logging.error("the mail.content file is not found on the WebDAV server")
10- pass
11
12
13 class Sha256FileNotFoundError(FileNotFoundError):
14 """Raised when the sha256sum file for a given image is not found on the WebDAV server"""
15- logging.error(
16- "sha256sum file for a given image is not found on the WebDAV server")
17- pass
18
19
20 class Summary:
21- def __init__(self, launchpad, project_name, milestone_name, image_name=""):
22+ def __init__(self, launchpad, project_name, milestone_name, image_url=""):
23 logging.info("Initailizing Summary object")
24 self.project_name = project_name
25 self.milestone_name = milestone_name
26 self.launchpad = launchpad
27+ self.image_url = image_url
28
29 logging.info((f"Preparing launchpad API for {self.project_name} "
30 f"- {self.milestone_name}"))
31@@ -45,11 +41,14 @@ class Summary:
32 logging.info(f"Preparing WebDAV API as user {user}")
33 self.webdav_client = Client(webdav_options)
34
35- if not image_name:
36- self.image_name, self.image_sha256 = self.get_image_info_from_mail_content()
37- else:
38- self.image_name = image_name
39+ if self.image_url:
40+ # Image name is the last element of the URL, e.g.:
41+ # https://oem-share.canonical.com/partners/project/share/uc20/uc20-alpha/iot-blabla-x01-20201228-9.img.xz
42+ # -> iot-blabla-x01-20201228-9.img.xz
43+ self.image_name = self.image_url.split("/")[-1]
44 self.image_sha256 = self.get_image_sha256()
45+ else:
46+ self.image_name, self.image_sha256 = self.get_image_info_from_mail_content()
47 self.image_date = get_date_from_image_name(self.image_name)
48 self.new_bugs = self.get_new_bugs()
49 self.milestone_bugs = self.lp_milestone.searchTasks()
50@@ -136,7 +135,7 @@ class Summary:
51
52 image_name = image_path.strip().split("/")[-1]
53 except Exception:
54- raise MailContentNotFoundError()
55+ raise MailContentNotFoundError("the mail.content file is not found on the WebDAV server")
56
57 logging.info(f"Image: {image_name}, SHA256: {image_sha256}")
58 return image_name, image_sha256
59@@ -144,7 +143,7 @@ class Summary:
60 def get_image_sha256(self):
61 """
62 If the image information cannot be automatically parsed from mail.content,
63- user can manually input the image name, and this function will try to parse
64+ user can manually input the image URL, and this function will try to parse
65 the corresponding sha256sum file to retrieve the sha256 value.
66 """
67 buff = io.BytesIO()
68@@ -156,20 +155,28 @@ class Summary:
69 content = buff.read()
70 sha256 = content.decode().split()[0]
71 except Exception:
72- raise Sha256FileNotFoundError()
73+ raise Sha256FileNotFoundError("sha256sum file for a given image is not found on the WebDAV server")
74
75 return sha256
76
77 def get_milestone_uri(self):
78- # For projects not using series (i.e. using the default "trunk"
79- # series), the default is to put the releases in a `releases` directory
80- # on WebDAV.
81- if self.series_name == "trunk":
82- uri = f"/share/{self.project_name}/releases/{self.milestone_name}/"
83+ """Generate WebDAV URI for the selected milestone"""
84+ # If the image URL is manually provided by user, we recreate the WebDAV URI from it, e.g.:
85+ # https://oem-share.canonical.com/partners/project/share/uc-20/uc20-x01/iot-blabla-x01-20201228-9.img.xz
86+ # -> /share/project/uc20/uc20-x01
87+ if self.image_url:
88+ url_list = self.image_url.split("/")
89+ uri = f"/share/{self.project_name}/{url_list[-3]}/{url_list[-2]}/"
90 else:
91- uri = (
92- f"/share/{self.project_name}/{self.series_name}/{self.milestone_name}/"
93- )
94+ # For projects not using series (i.e. using the default "trunk"
95+ # series), the default is to put the releases in a `releases` directory
96+ # on WebDAV.
97+ if self.series_name == "trunk":
98+ uri = f"/share/{self.project_name}/releases/{self.milestone_name}/"
99+ else:
100+ uri = (
101+ f"/share/{self.project_name}/{self.series_name}/{self.milestone_name}/"
102+ )
103 return uri
104
105
106diff --git a/webapp/__init__.py b/webapp/__init__.py
107index befaea5..755a829 100644
108--- a/webapp/__init__.py
109+++ b/webapp/__init__.py
110@@ -119,7 +119,7 @@ def generate_summary():
111 logging.info("Route to summary page")
112 project = request.form.get("project")
113 milestone = request.form.get("milestone")
114- image_name = request.form.get("image_name")
115+ image_url = request.form.get("image_url")
116 hardware = request.form.get("hardware")
117 stress_test_reports = request.form.get("stress_test_reports")
118 full_test_reports = request.form.get("full_test_reports")
119@@ -130,7 +130,7 @@ def generate_summary():
120 return redirect(url_for("index"))
121
122 try:
123- report = summary.Summary(launchpad, project, milestone, image_name=image_name)
124+ report = summary.Summary(launchpad, project, milestone, image_url=image_url)
125 critical_new_bugs = [b for b in report.new_bugs if b.importance == "Critical"]
126 high_new_bugs = [b for b in report.new_bugs if b.importance == "High"]
127 critical_reopened_bugs = [
128@@ -156,7 +156,7 @@ def generate_summary():
129 )
130 except summary.Sha256FileNotFoundError:
131 error = (
132- f"Could not find sha256 for image named {image_name}. "
133+ f"Could not find sha256 for image at {image_url}. "
134 f"Please make sure this image is available on oem-share."
135 )
136 logging.error(error)
137diff --git a/webapp/static/style.css b/webapp/static/style.css
138index 3ef3f96..b45b806 100644
139--- a/webapp/static/style.css
140+++ b/webapp/static/style.css
141@@ -11,7 +11,7 @@ main {
142 input, textarea, select {
143 line-height: 1.5em;
144 font-size: 1em;
145- width: 40em;
146+ width: 50em;
147 padding: 0.5em;
148 }
149
150diff --git a/webapp/templates/image_info.html b/webapp/templates/image_info.html
151index 6828be6..eb76be1 100644
152--- a/webapp/templates/image_info.html
153+++ b/webapp/templates/image_info.html
154@@ -17,15 +17,15 @@
155 <p class="warning"><strong>Error:</strong> {{ error }}</p>
156 {% endif %}
157 <p>Auto-Summary relies on the release e-mail (stored on oem-share as a <code>mail.content</code> file) to retrieve the image name and its SHA256 value.</p>
158- <p>If you want, you can manually specify the image name, and Auto-Summary will try to figure out the rest.</p>
159+ <p>If you want, you can manually specify the image URL, and Auto-Summary will try to figure out the rest.</p>
160 <p>Note: In the normal process, a release e-mail should always be sent, and the <code>mail.content</code> file should always be available in the project's oem-share. If it is not the case, please contact the Software Engineering team to review the process.</p>
161
162 <hr>
163 <form action="{{ url_for('generate_summary') }}" method="post">
164 <ul>
165 <li>
166- <label for="html_report">Image name:</label>
167- <input type="text" id="image_name" name="image_name" placeholder="e.g. iot-fisterra-nitrogen6x-classic-server-2004-x01-20201228-9.img.xz">
168+ <label for="html_report">Image URL:</label>
169+ <input type="text" id="image_url" name="image_url" placeholder="e.g. https://oem-share.canonical.com/partners/project/share/uc20/uc20-x01/iot-project-uc20-x01-20201228-9.img.xz">
170 </li>
171 <li class="button">
172 <button type="submit">Generate Summary</button>

Subscribers

People subscribed via source and target branches

to all changes: