Merge ~the-meulengracht/snappy-hwe-snaps/+git/jenkins-jobs:master into ~snappy-hwe-team/snappy-hwe-snaps/+git/jenkins-jobs:master
- Git
- lp:~the-meulengracht/snappy-hwe-snaps/+git/jenkins-jobs
- master
- Merge into master
Status: | Merged |
---|---|
Approved by: | Alfonso Sanchez-Beato |
Approved revision: | d20dc2f3493ffbf7c1e1bbaf516dfe1689cfbf64 |
Merged at revision: | 016fa6aca8bf2a9774f1fb3b629ece831ca2c6e1 |
Proposed branch: | ~the-meulengracht/snappy-hwe-snaps/+git/jenkins-jobs:master |
Merge into: | ~snappy-hwe-team/snappy-hwe-snaps/+git/jenkins-jobs:master |
Diff against target: |
491 lines (+71/-69) 11 files modified
3rdparty/repo (+1/-1) jobs/infrastructure/credentials-1-launchpad.py (+2/-1) jobs/infrastructure/prepare-0-install.sh (+31/-29) tools/automerge-mps.py (+1/-1) tools/delete-ci-repo.py (+1/-3) tools/se_utils/__init__.py (+17/-9) tools/shyaml (+1/-1) tools/trigger-ci.py (+1/-1) tools/unstage-from-manifest.py (+1/-2) tools/update-merge-proposal.py (+2/-10) tools/vote-on-merge-proposal.py (+13/-11) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alfonso Sanchez-Beato | Approve | ||
System Enablement Bot | continuous-integration | Approve | |
Review via email: mp+422731@code.launchpad.net |
Commit message
Description of the change
This MP contains the following:
- Support for focal
- Migration to python3
System Enablement Bot (system-enablement-ci-bot) wrote : | # |
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote : | # |
Thanks for this! I've a couple of comments.
Also, I have run flake8 on the python scripts, that should help to find issues in the migration to python3. See https:/
./tools/
Anyway, it is a good opportunity to clean-up these warnings, although maybe you can ignore the "line too long" ones.
System Enablement Bot (system-enablement-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:d20dc2f3493
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote : | # |
LGTM, thanks for the changes!
Preview Diff
1 | diff --git a/3rdparty/repo b/3rdparty/repo | |||
2 | index f9eb9e8..c069798 100644 | |||
3 | --- a/3rdparty/repo | |||
4 | +++ b/3rdparty/repo | |||
5 | @@ -1,4 +1,4 @@ | |||
7 | 1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python3 |
8 | 2 | 2 | ||
9 | 3 | # repo default configuration | 3 | # repo default configuration |
10 | 4 | # | 4 | # |
11 | diff --git a/jobs/infrastructure/credentials-1-launchpad.py b/jobs/infrastructure/credentials-1-launchpad.py | |||
12 | index 59dd706..61e36de 100644 | |||
13 | --- a/jobs/infrastructure/credentials-1-launchpad.py | |||
14 | +++ b/jobs/infrastructure/credentials-1-launchpad.py | |||
15 | @@ -1,4 +1,4 @@ | |||
17 | 1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python3 |
18 | 2 | # | 2 | # |
19 | 3 | # Copyright (C) 2016 Canonical Ltd | 3 | # Copyright (C) 2016 Canonical Ltd |
20 | 4 | # | 4 | # |
21 | @@ -82,5 +82,6 @@ def get_launchpad(cred_path, launchpadlib_dir=None): | |||
22 | 82 | authorization_engine=authorization_engine, | 82 | authorization_engine=authorization_engine, |
23 | 83 | launchpadlib_dir=launchpadlib_dir) | 83 | launchpadlib_dir=launchpadlib_dir) |
24 | 84 | 84 | ||
25 | 85 | |||
26 | 85 | if __name__ == '__main__': | 86 | if __name__ == '__main__': |
27 | 86 | get_launchpad("{credentials_path}") | 87 | get_launchpad("{credentials_path}") |
28 | diff --git a/jobs/infrastructure/prepare-0-install.sh b/jobs/infrastructure/prepare-0-install.sh | |||
29 | index d50e5a9..afffe90 100644 | |||
30 | --- a/jobs/infrastructure/prepare-0-install.sh | |||
31 | +++ b/jobs/infrastructure/prepare-0-install.sh | |||
32 | @@ -16,6 +16,9 @@ | |||
33 | 16 | 16 | ||
34 | 17 | set -ex | 17 | set -ex |
35 | 18 | 18 | ||
36 | 19 | JENKINS_JOBS_GIT_REPO="{jobs-git-repo}" | ||
37 | 20 | JENKINS_JOBS_GIT_REPO_BRANCH="{jobs-git-repo-branch}" | ||
38 | 21 | |||
39 | 19 | # Use correct home and preserve environment variables when calling `sudo ...` | 22 | # Use correct home and preserve environment variables when calling `sudo ...` |
40 | 20 | SUDO="sudo -E -H" | 23 | SUDO="sudo -E -H" |
41 | 21 | 24 | ||
42 | @@ -26,24 +29,27 @@ $SUDO apt-get install --yes software-properties-common | |||
43 | 26 | # build tools as used in Launchpad | 29 | # build tools as used in Launchpad |
44 | 27 | $SUDO add-apt-repository --yes ppa:launchpad/buildd-staging | 30 | $SUDO add-apt-repository --yes ppa:launchpad/buildd-staging |
45 | 28 | $SUDO add-apt-repository --yes ppa:jenkaas-hackers/tools | 31 | $SUDO add-apt-repository --yes ppa:jenkaas-hackers/tools |
47 | 29 | $SUDO add-apt-repository --yes ppa:snappy-hwe-team/ci-tools | 32 | |
48 | 33 | version=$(lsb_release -sc) | ||
49 | 34 | if [ "$version" = "xenial" ]; then | ||
50 | 35 | $SUDO add-apt-repository --yes ppa:snappy-hwe-team/ci-tools | ||
51 | 36 | fi | ||
52 | 30 | 37 | ||
53 | 31 | $SUDO apt-get update | 38 | $SUDO apt-get update |
54 | 32 | 39 | ||
55 | 33 | echo "postfix postfix/mailname string $(hostname)" | $SUDO debconf-set-selections | 40 | echo "postfix postfix/mailname string $(hostname)" | $SUDO debconf-set-selections |
56 | 34 | echo "postfix postfix/main_mailer_type string 'Internet Site'" | $SUDO debconf-set-selections | 41 | echo "postfix postfix/main_mailer_type string 'Internet Site'" | $SUDO debconf-set-selections |
57 | 35 | 42 | ||
58 | 43 | # install shared packages | ||
59 | 36 | $SUDO apt-get install --yes \ | 44 | $SUDO apt-get install --yes \ |
60 | 37 | git \ | 45 | git \ |
70 | 38 | python \ | 46 | python3 \ |
71 | 39 | python-launchpadlib \ | 47 | python3-launchpadlib \ |
72 | 40 | python-bzrlib \ | 48 | python3-lockfile \ |
73 | 41 | python-lockfile \ | 49 | python3-yaml \ |
74 | 42 | python-yaml \ | 50 | python3-jenkins \ |
75 | 43 | python-jenkins \ | 51 | python3-requests \ |
76 | 44 | python-requests \ | 52 | python3-git \ |
68 | 45 | python-git \ | ||
69 | 46 | python-pip \ | ||
77 | 47 | python3-debian \ | 53 | python3-debian \ |
78 | 48 | python3-pip \ | 54 | python3-pip \ |
79 | 49 | tarmac \ | 55 | tarmac \ |
80 | @@ -58,7 +64,6 @@ $SUDO apt-get install --yes \ | |||
81 | 58 | jq \ | 64 | jq \ |
82 | 59 | postfix \ | 65 | postfix \ |
83 | 60 | abootimg \ | 66 | abootimg \ |
84 | 61 | android-tools-fsutils \ | ||
85 | 62 | golang-go \ | 67 | golang-go \ |
86 | 63 | dpkg-dev \ | 68 | dpkg-dev \ |
87 | 64 | devscripts \ | 69 | devscripts \ |
88 | @@ -66,31 +71,28 @@ $SUDO apt-get install --yes \ | |||
89 | 66 | bzr \ | 71 | bzr \ |
90 | 67 | dh-systemd \ | 72 | dh-systemd \ |
91 | 68 | expect \ | 73 | expect \ |
94 | 69 | tcl \ | 74 | tcl {install_packages} |
95 | 70 | {install_packages} | 75 | |
96 | 76 | # install additional packages based on distro | ||
97 | 77 | if [ "$version" != "xenial" ]; then | ||
98 | 78 | $SUDO apt-get install --yes \ | ||
99 | 79 | android-sdk-libsparse-utils \ | ||
100 | 80 | android-sdk-ext4-utils | ||
101 | 81 | else | ||
102 | 82 | $SUDO apt-get install --yes \ | ||
103 | 83 | android-tools-fsutils | ||
104 | 84 | fi | ||
105 | 71 | 85 | ||
106 | 72 | # Install snaps | 86 | # Install snaps |
107 | 73 | $SUDO snap install snapcraft | 87 | $SUDO snap install snapcraft |
108 | 74 | $SUDO snap install yq | 88 | $SUDO snap install yq |
109 | 75 | 89 | ||
113 | 76 | # Install additional sofware from the python package database | 90 | export http_proxy="{http_proxy}" |
114 | 77 | $SUDO pip2 install --upgrade pip | 91 | export https_proxy="{https_proxy}" |
112 | 78 | $SUDO pip2 install jenkins-job-builder pid | ||
115 | 79 | 92 | ||
116 | 80 | # documentation-builder is normally available as a snap but we can't | 93 | # documentation-builder is normally available as a snap but we can't |
117 | 81 | # use snaps yet on our agents. | 94 | # use snaps yet on our agents. |
118 | 82 | $SUDO pip3 install --upgrade pip | 95 | $SUDO pip3 install --upgrade pip |
119 | 96 | $SUDO pip3 install --ignore-installed PyYAML | ||
120 | 97 | $SUDO pip3 install jenkins-job-builder pid | ||
121 | 83 | $SUDO pip3 install ubuntudesign.documentation-builder | 98 | $SUDO pip3 install ubuntudesign.documentation-builder |
122 | 84 | |||
123 | 85 | # Now http & https proxy is not needed, it will in fact interfere with curl | ||
124 | 86 | # below | ||
125 | 87 | |||
126 | 88 | unset http_proxy | ||
127 | 89 | unset https_proxy | ||
128 | 90 | |||
129 | 91 | # Fetch and install latest repo; we still can't use snaps reliably on our | ||
130 | 92 | # agents so we go with the upstream release. | ||
131 | 93 | $SUDO mkdir -p /usr/local/bin | ||
132 | 94 | curl $JENKINS_JOBS_GIT_REPO/plain/3rdparty/repo?h=$JENKINS_JOBS_GIT_REPO_BRANCH | $SUDO tee /usr/local/bin/repo | ||
133 | 95 | $SUDO mv $HOME/repo /usr/local/bin/repo | ||
134 | 96 | $SUDO chmod +x /usr/local/bin/repo | ||
135 | diff --git a/tools/automerge-mps.py b/tools/automerge-mps.py | |||
136 | index 2e1e0b6..150da07 100755 | |||
137 | --- a/tools/automerge-mps.py | |||
138 | +++ b/tools/automerge-mps.py | |||
139 | @@ -1,4 +1,4 @@ | |||
141 | 1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python3 |
142 | 2 | # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- | 2 | # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- |
143 | 3 | # | 3 | # |
144 | 4 | # Copyright (C) 2016 Canonical Ltd | 4 | # Copyright (C) 2016 Canonical Ltd |
145 | diff --git a/tools/delete-ci-repo.py b/tools/delete-ci-repo.py | |||
146 | index 35c762d..3a04613 100755 | |||
147 | --- a/tools/delete-ci-repo.py | |||
148 | +++ b/tools/delete-ci-repo.py | |||
149 | @@ -1,4 +1,4 @@ | |||
151 | 1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python3 |
152 | 2 | # | 2 | # |
153 | 3 | # Copyright (C) 2017 Canonical Ltd | 3 | # Copyright (C) 2017 Canonical Ltd |
154 | 4 | # | 4 | # |
155 | @@ -14,8 +14,6 @@ | |||
156 | 14 | # You should have received a copy of the GNU General Public License | 14 | # You should have received a copy of the GNU General Public License |
157 | 15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
158 | 16 | 16 | ||
159 | 17 | from launchpadlib.launchpad import Launchpad | ||
160 | 18 | |||
161 | 19 | from argparse import ArgumentParser | 17 | from argparse import ArgumentParser |
162 | 20 | 18 | ||
163 | 21 | import se_utils | 19 | import se_utils |
164 | diff --git a/tools/se_utils/__init__.py b/tools/se_utils/__init__.py | |||
165 | index 64cc0cc..e78eb6b 100644 | |||
166 | --- a/tools/se_utils/__init__.py | |||
167 | +++ b/tools/se_utils/__init__.py | |||
168 | @@ -1,4 +1,4 @@ | |||
170 | 1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python3 |
171 | 2 | # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- | 2 | # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- |
172 | 3 | # | 3 | # |
173 | 4 | # Copyright (C) 2016 Canonical Ltd | 4 | # Copyright (C) 2016 Canonical Ltd |
174 | @@ -18,7 +18,6 @@ | |||
175 | 18 | import atexit | 18 | import atexit |
176 | 19 | import sys | 19 | import sys |
177 | 20 | import time | 20 | import time |
178 | 21 | import logging | ||
179 | 22 | import os | 21 | import os |
180 | 23 | import re | 22 | import re |
181 | 24 | import yaml | 23 | import yaml |
182 | @@ -28,11 +27,13 @@ from lazr.restfulclient.errors import HTTPError | |||
183 | 28 | from launchpadlib.launchpad import Launchpad | 27 | from launchpadlib.launchpad import Launchpad |
184 | 29 | from launchpadlib.credentials import UnencryptedFileCredentialStore | 28 | from launchpadlib.credentials import UnencryptedFileCredentialStore |
185 | 30 | 29 | ||
186 | 30 | |||
187 | 31 | class LaunchpadVote(): | 31 | class LaunchpadVote(): |
188 | 32 | APPROVE = 'Approve' | 32 | APPROVE = 'Approve' |
189 | 33 | DISAPPROVE = 'Disapprove' | 33 | DISAPPROVE = 'Disapprove' |
190 | 34 | NEEDS_FIXING = 'Needs Fixing' | 34 | NEEDS_FIXING = 'Needs Fixing' |
191 | 35 | 35 | ||
192 | 36 | |||
193 | 36 | ACCESS_TOKEN_POLL_TIME = 10 | 37 | ACCESS_TOKEN_POLL_TIME = 10 |
194 | 37 | WAITING_FOR_USER = """Open this link: | 38 | WAITING_FOR_USER = """Open this link: |
195 | 38 | {} | 39 | {} |
196 | @@ -58,7 +59,7 @@ class AuthorizeRequestTokenWithConsole(RequestTokenAuthorizationEngine): | |||
197 | 58 | 59 | ||
198 | 59 | """ | 60 | """ |
199 | 60 | authorization_url = self.authorization_url(request_token) | 61 | authorization_url = self.authorization_url(request_token) |
201 | 61 | print WAITING_FOR_USER.format(authorization_url) | 62 | print(WAITING_FOR_USER.format(authorization_url)) |
202 | 62 | # if we don't flush we may not see the message | 63 | # if we don't flush we may not see the message |
203 | 63 | sys.stdout.flush() | 64 | sys.stdout.flush() |
204 | 64 | while credentials.access_token is None: | 65 | while credentials.access_token is None: |
205 | @@ -67,7 +68,7 @@ class AuthorizeRequestTokenWithConsole(RequestTokenAuthorizationEngine): | |||
206 | 67 | credentials.exchange_request_token_for_access_token( | 68 | credentials.exchange_request_token_for_access_token( |
207 | 68 | self.web_root) | 69 | self.web_root) |
208 | 69 | break | 70 | break |
210 | 70 | except HTTPError, e: | 71 | except HTTPError as e: |
211 | 71 | if e.response.status == 403: | 72 | if e.response.status == 403: |
212 | 72 | # The user decided not to authorize this | 73 | # The user decided not to authorize this |
213 | 73 | # application. | 74 | # application. |
214 | @@ -79,6 +80,7 @@ class AuthorizeRequestTokenWithConsole(RequestTokenAuthorizationEngine): | |||
215 | 79 | # There was an error accessing the server. | 80 | # There was an error accessing the server. |
216 | 80 | raise e | 81 | raise e |
217 | 81 | 82 | ||
218 | 83 | |||
219 | 82 | # launchpadlib is not thread/process safe so we are creating launchpadlib | 84 | # launchpadlib is not thread/process safe so we are creating launchpadlib |
220 | 83 | # cache in /tmp per process which gets cleaned up at the end | 85 | # cache in /tmp per process which gets cleaned up at the end |
221 | 84 | # see also lp:459418 and lp:1025153 | 86 | # see also lp:459418 and lp:1025153 |
222 | @@ -97,8 +99,8 @@ def get_launchpad(launchpadlib_dir=None, credential_store_path=None, lp_app=None | |||
223 | 97 | the default """ | 99 | the default """ |
224 | 98 | store = UnencryptedFileCredentialStore(credential_store_path) | 100 | store = UnencryptedFileCredentialStore(credential_store_path) |
225 | 99 | authorization_engine = AuthorizeRequestTokenWithConsole(lp_env, lp_app) | 101 | authorization_engine = AuthorizeRequestTokenWithConsole(lp_env, lp_app) |
228 | 100 | lib_dir=launchpad_cachedir | 102 | lib_dir = launchpad_cachedir |
229 | 101 | if launchpadlib_dir != None: | 103 | if launchpadlib_dir is not None: |
230 | 102 | lib_dir = launchpadlib_dir | 104 | lib_dir = launchpadlib_dir |
231 | 103 | return Launchpad.login_with(lp_app, lp_env, | 105 | return Launchpad.login_with(lp_app, lp_env, |
232 | 104 | credential_store=store, | 106 | credential_store=store, |
233 | @@ -106,6 +108,7 @@ def get_launchpad(launchpadlib_dir=None, credential_store_path=None, lp_app=None | |||
234 | 106 | launchpadlib_dir=lib_dir, | 108 | launchpadlib_dir=lib_dir, |
235 | 107 | version='devel') | 109 | version='devel') |
236 | 108 | 110 | ||
237 | 111 | |||
238 | 109 | # Load configuration for the current agent we're running on. All agents were | 112 | # Load configuration for the current agent we're running on. All agents were |
239 | 110 | # provisioned when they were setup with a proper configuration. See | 113 | # provisioned when they were setup with a proper configuration. See |
240 | 111 | # https://wiki.canonical.com/InformationInfrastructure/Jenkaas/UserDocs for | 114 | # https://wiki.canonical.com/InformationInfrastructure/Jenkaas/UserDocs for |
241 | @@ -121,12 +124,14 @@ def load_config(): | |||
242 | 121 | print("ERROR: No config file found") | 124 | print("ERROR: No config file found") |
243 | 122 | sys.exit(1) | 125 | sys.exit(1) |
244 | 123 | 126 | ||
245 | 127 | |||
246 | 124 | # Return a configuration option from the agent configuration specified by the | 128 | # Return a configuration option from the agent configuration specified by the |
247 | 125 | # name argument. | 129 | # name argument. |
248 | 126 | def get_config_option(name): | 130 | def get_config_option(name): |
249 | 127 | config = load_config() | 131 | config = load_config() |
250 | 128 | return config[name] | 132 | return config[name] |
251 | 129 | 133 | ||
252 | 134 | |||
253 | 130 | def get_branch_handle_from_url(lp_handle, url): | 135 | def get_branch_handle_from_url(lp_handle, url): |
254 | 131 | """ Return a branch/repo handle for the given url. | 136 | """ Return a branch/repo handle for the given url. |
255 | 132 | Returns a launchpad branch or git repository handle for the given url. | 137 | Returns a launchpad branch or git repository handle for the given url. |
256 | @@ -147,6 +152,7 @@ def get_branch_handle_from_url(lp_handle, url): | |||
257 | 147 | print('fetching branch: ' + name) | 152 | print('fetching branch: ' + name) |
258 | 148 | return lp_handle.branches.getByUrl(url=name) | 153 | return lp_handle.branches.getByUrl(url=name) |
259 | 149 | 154 | ||
260 | 155 | |||
261 | 150 | def get_branch_from_mp(merge_proposal): | 156 | def get_branch_from_mp(merge_proposal): |
262 | 151 | """Return a link to branch given a link to a merge proposal. | 157 | """Return a link to branch given a link to a merge proposal. |
263 | 152 | 158 | ||
264 | @@ -157,11 +163,12 @@ def get_branch_from_mp(merge_proposal): | |||
265 | 157 | 163 | ||
266 | 158 | :param merge_proposal: url of a launchpad merge proposal | 164 | :param merge_proposal: url of a launchpad merge proposal |
267 | 159 | """ | 165 | """ |
269 | 160 | m = re.search('(.*)\+merge/[0-9]+$', merge_proposal) | 166 | m = re.search(r'(.*)\+merge/[0-9]+$', merge_proposal) |
270 | 161 | if m: | 167 | if m: |
271 | 162 | return m.group(1) | 168 | return m.group(1) |
272 | 163 | return None | 169 | return None |
273 | 164 | 170 | ||
274 | 171 | |||
275 | 165 | def get_mp_handle_from_url(lp_handle, merge_proposal_link): | 172 | def get_mp_handle_from_url(lp_handle, merge_proposal_link): |
276 | 166 | """ Get launchpad handle for merge proposal given a merge proposal URL. | 173 | """ Get launchpad handle for merge proposal given a merge proposal URL. |
277 | 167 | 174 | ||
278 | @@ -173,7 +180,7 @@ def get_mp_handle_from_url(lp_handle, merge_proposal_link): | |||
279 | 173 | print('Unable to get branch link from merge proposal link.') | 180 | print('Unable to get branch link from merge proposal link.') |
280 | 174 | return None | 181 | return None |
281 | 175 | 182 | ||
283 | 176 | branch = get_branch_handle_from_url(lp_handle, branch_link) | 183 | branch = get_branch_handle_from_url(lp_handle, branch_link) |
284 | 177 | if not branch: | 184 | if not branch: |
285 | 178 | print('Branch {} does not exist'.format(branch_link)) | 185 | print('Branch {} does not exist'.format(branch_link)) |
286 | 179 | return None | 186 | return None |
287 | @@ -187,6 +194,7 @@ def get_mp_handle_from_url(lp_handle, merge_proposal_link): | |||
288 | 187 | 194 | ||
289 | 188 | return None | 195 | return None |
290 | 189 | 196 | ||
291 | 197 | |||
292 | 190 | def get_vote_subject(mp): | 198 | def get_vote_subject(mp): |
293 | 191 | """Given a mp handle return a subject for the vote message | 199 | """Given a mp handle return a subject for the vote message |
294 | 192 | 200 | ||
295 | @@ -209,4 +217,4 @@ def get_vote_subject(mp): | |||
296 | 209 | else: | 217 | else: |
297 | 210 | return 'Re: [Merge] {} into {}'.format( | 218 | return 'Re: [Merge] {} into {}'.format( |
298 | 211 | mp.source_branch.display_name, | 219 | mp.source_branch.display_name, |
299 | 212 | mp.target_branch.display_name) | ||
300 | 213 | \ No newline at end of file | 220 | \ No newline at end of file |
301 | 221 | mp.target_branch.display_name) | ||
302 | diff --git a/tools/shyaml b/tools/shyaml | |||
303 | index e4618ec..ea3db4f 100755 | |||
304 | --- a/tools/shyaml | |||
305 | +++ b/tools/shyaml | |||
306 | @@ -1,4 +1,4 @@ | |||
308 | 1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python3 |
309 | 2 | 2 | ||
310 | 3 | # Taken from upstream git repository https://github.com/0k/shyaml | 3 | # Taken from upstream git repository https://github.com/0k/shyaml |
311 | 4 | # at revision d77e30599a0971c51896ef97d21883550e7e9979 | 4 | # at revision d77e30599a0971c51896ef97d21883550e7e9979 |
312 | diff --git a/tools/trigger-ci.py b/tools/trigger-ci.py | |||
313 | index 65f3b3e..9267a16 100755 | |||
314 | --- a/tools/trigger-ci.py | |||
315 | +++ b/tools/trigger-ci.py | |||
316 | @@ -1,4 +1,4 @@ | |||
318 | 1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python3 |
319 | 2 | # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- | 2 | # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- |
320 | 3 | # | 3 | # |
321 | 4 | # Copyright (C) 2016 Canonical Ltd | 4 | # Copyright (C) 2016 Canonical Ltd |
322 | diff --git a/tools/unstage-from-manifest.py b/tools/unstage-from-manifest.py | |||
323 | index e189492..e3f79ec 100755 | |||
324 | --- a/tools/unstage-from-manifest.py | |||
325 | +++ b/tools/unstage-from-manifest.py | |||
326 | @@ -22,7 +22,6 @@ | |||
327 | 22 | # store. | 22 | # store. |
328 | 23 | 23 | ||
329 | 24 | import sys | 24 | import sys |
330 | 25 | import yaml | ||
331 | 26 | from tools import yaml_utils | 25 | from tools import yaml_utils |
332 | 27 | 26 | ||
333 | 28 | 27 | ||
334 | @@ -34,7 +33,7 @@ def remove_from_staged(pkg_list_path, manifest_path, out_manifest_path): | |||
335 | 34 | try: | 33 | try: |
336 | 35 | with open(pkg_list_path) as pkg_list_f: | 34 | with open(pkg_list_path) as pkg_list_f: |
337 | 36 | pkg_list = pkg_list_f.read().splitlines() | 35 | pkg_list = pkg_list_f.read().splitlines() |
339 | 37 | except FileNotFoundError as e: | 36 | except FileNotFoundError: |
340 | 38 | print(pkg_list_path, 'not found, just copying manifest') | 37 | print(pkg_list_path, 'not found, just copying manifest') |
341 | 39 | pkg_list = [] | 38 | pkg_list = [] |
342 | 40 | 39 | ||
343 | diff --git a/tools/update-merge-proposal.py b/tools/update-merge-proposal.py | |||
344 | index 0054659..261fa6d 100755 | |||
345 | --- a/tools/update-merge-proposal.py | |||
346 | +++ b/tools/update-merge-proposal.py | |||
347 | @@ -1,4 +1,4 @@ | |||
349 | 1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python3 |
350 | 2 | # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- | 2 | # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- |
351 | 3 | # | 3 | # |
352 | 4 | # Copyright (C) 2017 Canonical Ltd | 4 | # Copyright (C) 2017 Canonical Ltd |
353 | @@ -15,14 +15,6 @@ | |||
354 | 15 | # You should have received a copy of the GNU General Public License | 15 | # You should have received a copy of the GNU General Public License |
355 | 16 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
356 | 17 | 17 | ||
357 | 18 | import atexit | ||
358 | 19 | import sys | ||
359 | 20 | import time | ||
360 | 21 | import logging | ||
361 | 22 | import os | ||
362 | 23 | import yaml | ||
363 | 24 | import re | ||
364 | 25 | from shutil import rmtree | ||
365 | 26 | from argparse import ArgumentParser | 18 | from argparse import ArgumentParser |
366 | 27 | 19 | ||
367 | 28 | import se_utils | 20 | import se_utils |
368 | @@ -54,7 +46,7 @@ content = content.decode('string_escape') | |||
369 | 54 | if not args['approve'] and not args['disapprove']: | 46 | if not args['approve'] and not args['disapprove']: |
370 | 55 | parser.error('neither approved or disapproved the MP') | 47 | parser.error('neither approved or disapproved the MP') |
371 | 56 | 48 | ||
373 | 57 | vote="" | 49 | vote = "" |
374 | 58 | if args["approve"]: | 50 | if args["approve"]: |
375 | 59 | vote = se_utils.LaunchpadVote.APPROVE | 51 | vote = se_utils.LaunchpadVote.APPROVE |
376 | 60 | elif args["disapprove"]: | 52 | elif args["disapprove"]: |
377 | diff --git a/tools/vote-on-merge-proposal.py b/tools/vote-on-merge-proposal.py | |||
378 | index bec6da5..96838a7 100755 | |||
379 | --- a/tools/vote-on-merge-proposal.py | |||
380 | +++ b/tools/vote-on-merge-proposal.py | |||
381 | @@ -1,4 +1,4 @@ | |||
383 | 1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python3 |
384 | 2 | # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- | 2 | # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- |
385 | 3 | # | 3 | # |
386 | 4 | # Copyright (C) 2016 Canonical Ltd | 4 | # Copyright (C) 2016 Canonical Ltd |
387 | @@ -20,7 +20,6 @@ import sys | |||
388 | 20 | import time | 20 | import time |
389 | 21 | import logging | 21 | import logging |
390 | 22 | import os | 22 | import os |
391 | 23 | import yaml | ||
392 | 24 | import re | 23 | import re |
393 | 25 | from shutil import rmtree | 24 | from shutil import rmtree |
394 | 26 | from argparse import ArgumentParser | 25 | from argparse import ArgumentParser |
395 | @@ -29,7 +28,7 @@ from lazr.restfulclient.errors import HTTPError | |||
396 | 29 | from launchpadlib.launchpad import Launchpad | 28 | from launchpadlib.launchpad import Launchpad |
397 | 30 | from launchpadlib.credentials import UnencryptedFileCredentialStore | 29 | from launchpadlib.credentials import UnencryptedFileCredentialStore |
398 | 31 | from jlp import get_config_option | 30 | from jlp import get_config_option |
400 | 32 | from jlp import launchpadutils, jenkinsutils, logger | 31 | from jlp import jenkinsutils |
401 | 33 | 32 | ||
402 | 34 | logger = logging.getLogger('jenkins-launchpad-plugin') | 33 | logger = logging.getLogger('jenkins-launchpad-plugin') |
403 | 35 | stdout_handler = logging.StreamHandler(stream=sys.stdout) | 34 | stdout_handler = logging.StreamHandler(stream=sys.stdout) |
404 | @@ -73,7 +72,7 @@ class AuthorizeRequestTokenWithConsole(RequestTokenAuthorizationEngine): | |||
405 | 73 | 72 | ||
406 | 74 | """ | 73 | """ |
407 | 75 | authorization_url = self.authorization_url(request_token) | 74 | authorization_url = self.authorization_url(request_token) |
409 | 76 | print WAITING_FOR_USER.format(authorization_url) | 75 | print(WAITING_FOR_USER.format(authorization_url)) |
410 | 77 | # if we don't flush we may not see the message | 76 | # if we don't flush we may not see the message |
411 | 78 | sys.stdout.flush() | 77 | sys.stdout.flush() |
412 | 79 | while credentials.access_token is None: | 78 | while credentials.access_token is None: |
413 | @@ -82,7 +81,7 @@ class AuthorizeRequestTokenWithConsole(RequestTokenAuthorizationEngine): | |||
414 | 82 | credentials.exchange_request_token_for_access_token( | 81 | credentials.exchange_request_token_for_access_token( |
415 | 83 | self.web_root) | 82 | self.web_root) |
416 | 84 | break | 83 | break |
418 | 85 | except HTTPError, e: | 84 | except HTTPError as e: |
419 | 86 | if e.response.status == 403: | 85 | if e.response.status == 403: |
420 | 87 | # The user decided not to authorize this | 86 | # The user decided not to authorize this |
421 | 88 | # application. | 87 | # application. |
422 | @@ -110,6 +109,7 @@ def get_launchpad(launchpadlib_dir=None): | |||
423 | 110 | launchpadlib_dir=launchpadlib_dir, | 109 | launchpadlib_dir=launchpadlib_dir, |
424 | 111 | version='devel') | 110 | version='devel') |
425 | 112 | 111 | ||
426 | 112 | |||
427 | 113 | def get_branch_handle_from_url(lp_handle, url): | 113 | def get_branch_handle_from_url(lp_handle, url): |
428 | 114 | """ Return a branch/repo handle for the given url. | 114 | """ Return a branch/repo handle for the given url. |
429 | 115 | Returns a launchpad branch or git repository handle for the given url. | 115 | Returns a launchpad branch or git repository handle for the given url. |
430 | @@ -130,6 +130,7 @@ def get_branch_handle_from_url(lp_handle, url): | |||
431 | 130 | logger.debug('fetching branch: ' + name) | 130 | logger.debug('fetching branch: ' + name) |
432 | 131 | return lp_handle.branches.getByUrl(url=name) | 131 | return lp_handle.branches.getByUrl(url=name) |
433 | 132 | 132 | ||
434 | 133 | |||
435 | 133 | def get_branch_from_mp(merge_proposal): | 134 | def get_branch_from_mp(merge_proposal): |
436 | 134 | """Return a link to branch given a link to a merge proposal. | 135 | """Return a link to branch given a link to a merge proposal. |
437 | 135 | 136 | ||
438 | @@ -140,11 +141,12 @@ def get_branch_from_mp(merge_proposal): | |||
439 | 140 | 141 | ||
440 | 141 | :param merge_proposal: url of a launchpad merge proposal | 142 | :param merge_proposal: url of a launchpad merge proposal |
441 | 142 | """ | 143 | """ |
443 | 143 | m = re.search('(.*)\+merge/[0-9]+$', merge_proposal) | 144 | m = re.search(r'(.*)\+merge/[0-9]+$', merge_proposal) |
444 | 144 | if m: | 145 | if m: |
445 | 145 | return m.group(1) | 146 | return m.group(1) |
446 | 146 | return None | 147 | return None |
447 | 147 | 148 | ||
448 | 149 | |||
449 | 148 | def get_mp_handle_from_url(lp_handle, merge_proposal_link): | 150 | def get_mp_handle_from_url(lp_handle, merge_proposal_link): |
450 | 149 | """ Get launchpad handle for merge proposal given a merge proposal URL. | 151 | """ Get launchpad handle for merge proposal given a merge proposal URL. |
451 | 150 | 152 | ||
452 | @@ -156,7 +158,7 @@ def get_mp_handle_from_url(lp_handle, merge_proposal_link): | |||
453 | 156 | logger.error('Unable to get branch link from merge proposal link.') | 158 | logger.error('Unable to get branch link from merge proposal link.') |
454 | 157 | return None | 159 | return None |
455 | 158 | 160 | ||
457 | 159 | branch = get_branch_handle_from_url(lp_handle, branch_link) | 161 | branch = get_branch_handle_from_url(lp_handle, branch_link) |
458 | 160 | if not branch: | 162 | if not branch: |
459 | 161 | logger.debug('Branch {} does not exist'.format(branch_link)) | 163 | logger.debug('Branch {} does not exist'.format(branch_link)) |
460 | 162 | return None | 164 | return None |
461 | @@ -170,11 +172,13 @@ def get_mp_handle_from_url(lp_handle, merge_proposal_link): | |||
462 | 170 | 172 | ||
463 | 171 | return None | 173 | return None |
464 | 172 | 174 | ||
465 | 175 | |||
466 | 173 | class LaunchpadVote(): | 176 | class LaunchpadVote(): |
467 | 174 | APPROVE = 'Approve' | 177 | APPROVE = 'Approve' |
468 | 175 | DISAPPROVE = 'Disapprove' | 178 | DISAPPROVE = 'Disapprove' |
469 | 176 | NEEDS_FIXING = 'Needs Fixing' | 179 | NEEDS_FIXING = 'Needs Fixing' |
470 | 177 | 180 | ||
471 | 181 | |||
472 | 178 | def get_vote_subject(mp): | 182 | def get_vote_subject(mp): |
473 | 179 | """Given a mp handle return a subject for the vote message | 183 | """Given a mp handle return a subject for the vote message |
474 | 180 | 184 | ||
475 | @@ -241,6 +245,7 @@ def disapprove_mp(mp, revision, build_url, reason=None): | |||
476 | 241 | subject=get_vote_subject(mp), | 245 | subject=get_vote_subject(mp), |
477 | 242 | content=content) | 246 | content=content) |
478 | 243 | 247 | ||
479 | 248 | |||
480 | 244 | # launchpadlib is not thread/process safe so we are creating launchpadlib | 249 | # launchpadlib is not thread/process safe so we are creating launchpadlib |
481 | 245 | # cache in /tmp per process which gets cleaned up at the end | 250 | # cache in /tmp per process which gets cleaned up at the end |
482 | 246 | # see also lp:459418 and lp:1025153 | 251 | # see also lp:459418 and lp:1025153 |
483 | @@ -265,7 +270,4 @@ reason = '' | |||
484 | 265 | if overal_status == 'PASSED': | 270 | if overal_status == 'PASSED': |
485 | 266 | approve_mp(mp, args['revision'], args['build_url']) | 271 | approve_mp(mp, args['revision'], args['build_url']) |
486 | 267 | else: # status == False corresponds to NOT 'PASSED' | 272 | else: # status == False corresponds to NOT 'PASSED' |
491 | 268 | disapprove_mp(mp, | 273 | disapprove_mp(mp, args['revision'], args['build_url'], reason) |
488 | 269 | args['revision'], | ||
489 | 270 | args['build_url'], | ||
490 | 271 | reason) |
PASSED: Continuous integration, rev:663e605c99a 54e7065b741d5db 521abcd7ae7718 /jenkins. canonical. com/system- enablement/ job/snappy- hwe-snaps- snap-build- prepare/ 719/ /jenkins. canonical. com/system- enablement/ job/snappy- hwe-snaps- snap-build/ ARCHITECTURE= amd64/742 /jenkins. canonical. com/system- enablement/ job/snappy- hwe-snaps- snap-build/ ARCHITECTURE= arm64/742 /jenkins. canonical. com/system- enablement/ job/snappy- hwe-snaps- snap-build/ ARCHITECTURE= armhf/742 /jenkins. canonical. com/system- enablement/ job/snappy- hwe-snaps- snap-build/ ARCHITECTURE= i386/742 /jenkins. canonical. com/system- enablement/ job/snappy- hwe-snaps- snap-docs/ 1523 /jenkins. canonical. com/system- enablement/ job/snappy- hwe-snaps- snap-cleanup/ 1265 /jenkins. canonical. com/system- enablement/ job/snappy- hwe-snaps- snap-update- mp/1332/ console
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
Click here to trigger a rebuild: /jenkins. canonical. com/system- enablement/ job/snappy- hwe-snaps- snap-build- prepare/ 719/rebuild
https:/