Merge lp:~cjwatson/launchpad-buildd/translation-merge-states into lp:launchpad-buildd
- translation-merge-states
- Merge into trunk
Proposed by
Colin Watson
Status: | Merged |
---|---|
Merged at revision: | 293 |
Proposed branch: | lp:~cjwatson/launchpad-buildd/translation-merge-states |
Merge into: | lp:launchpad-buildd |
Prerequisite: | lp:~cjwatson/launchpad-buildd/translation-refactor-chdir |
Diff against target: |
266 lines (+62/-67) 4 files modified
bin/generate-translation-templates (+5/-2) debian/changelog (+2/-0) lpbuildd/tests/test_translationtemplatesbuildmanager.py (+31/-27) lpbuildd/translationtemplates.py (+24/-38) |
To merge this branch: | bzr merge lp:~cjwatson/launchpad-buildd/translation-merge-states |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
William Grant | code | Approve | |
Review via email: mp+330434@code.launchpad.net |
Commit message
Merge TranslationTemp
Description of the change
This will make it easier to turn generate-
To post a comment you must log in.
Revision history for this message
William Grant (wgrant) : | # |
review:
Approve
(code)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/generate-translation-templates' | |||
2 | --- bin/generate-translation-templates 2017-07-25 22:11:19 +0000 | |||
3 | +++ bin/generate-translation-templates 2017-09-08 14:41:25 +0000 | |||
4 | @@ -1,6 +1,6 @@ | |||
5 | 1 | #!/bin/sh | 1 | #!/bin/sh |
6 | 2 | # | 2 | # |
8 | 3 | # Copyright 2010,2011 Canonical Ltd. This software is licensed under the | 3 | # Copyright 2010-2017 Canonical Ltd. This software is licensed under the |
9 | 4 | # GNU Affero General Public License version 3 (see the file LICENSE). | 4 | # GNU Affero General Public License version 3 (see the file LICENSE). |
10 | 5 | 5 | ||
11 | 6 | # Buildd Slave tool to generate translation templates. Boiler plate code | 6 | # Buildd Slave tool to generate translation templates. Boiler plate code |
12 | @@ -53,6 +53,8 @@ | |||
13 | 53 | $1 || echo "Got error $? from '$1'." | 53 | $1 || echo "Got error $? from '$1'." |
14 | 54 | } | 54 | } |
15 | 55 | 55 | ||
16 | 56 | $SUDO $CHROOT $BUILD_CHROOT apt-get install -y bzr intltool || exit 200 | ||
17 | 57 | |||
18 | 56 | # Copy pottery files to chroot. | 58 | # Copy pottery files to chroot. |
19 | 57 | debug_exec "$SUDO $MKDIR -vp $BUILD_CHROOT$PYMODULES/$BUILDD_PACKAGE" | 59 | debug_exec "$SUDO $MKDIR -vp $BUILD_CHROOT$PYMODULES/$BUILDD_PACKAGE" |
20 | 58 | debug_exec "$SUDO $TOUCH $BUILD_CHROOT$PYMODULES/$BUILDD_PACKAGE/__init__.py" | 60 | debug_exec "$SUDO $TOUCH $BUILD_CHROOT$PYMODULES/$BUILDD_PACKAGE/__init__.py" |
21 | @@ -63,4 +65,5 @@ | |||
22 | 63 | # Enter chroot, switch back to unprivileged user, execute the generate script. | 65 | # Enter chroot, switch back to unprivileged user, execute the generate script. |
23 | 64 | $SUDO $CHROOT $BUILD_CHROOT \ | 66 | $SUDO $CHROOT $BUILD_CHROOT \ |
24 | 65 | $SU - $USER \ | 67 | $SU - $USER \ |
26 | 66 | -c "PYTHONPATH=$PYMODULES $GENERATE_SCRIPT $BRANCH_URL $RESULT_NAME" | 68 | -c "PYTHONPATH=$PYMODULES $GENERATE_SCRIPT $BRANCH_URL $RESULT_NAME" \ |
27 | 69 | || exit 201 | ||
28 | 67 | 70 | ||
29 | === modified file 'debian/changelog' | |||
30 | --- debian/changelog 2017-09-08 14:41:25 +0000 | |||
31 | +++ debian/changelog 2017-09-08 14:41:25 +0000 | |||
32 | @@ -1,6 +1,8 @@ | |||
33 | 1 | launchpad-buildd (152) UNRELEASED; urgency=medium | 1 | launchpad-buildd (152) UNRELEASED; urgency=medium |
34 | 2 | 2 | ||
35 | 3 | * Refactor lpbuildd.pottery.intltool to avoid calling chdir. | 3 | * Refactor lpbuildd.pottery.intltool to avoid calling chdir. |
36 | 4 | * Merge TranslationTemplatesBuildState.{INSTALL,GENERATE} into a single | ||
37 | 5 | state. | ||
38 | 4 | 6 | ||
39 | 5 | -- Colin Watson <cjwatson@ubuntu.com> Fri, 08 Sep 2017 13:42:17 +0100 | 7 | -- Colin Watson <cjwatson@ubuntu.com> Fri, 08 Sep 2017 13:42:17 +0100 |
40 | 6 | 8 | ||
41 | 7 | 9 | ||
42 | === modified file 'lpbuildd/tests/test_translationtemplatesbuildmanager.py' | |||
43 | --- lpbuildd/tests/test_translationtemplatesbuildmanager.py 2017-08-22 15:55:44 +0000 | |||
44 | +++ lpbuildd/tests/test_translationtemplatesbuildmanager.py 2017-09-08 14:41:25 +0000 | |||
45 | @@ -14,6 +14,8 @@ | |||
46 | 14 | from lpbuildd.tests.fakeslave import FakeSlave | 14 | from lpbuildd.tests.fakeslave import FakeSlave |
47 | 15 | from lpbuildd.tests.matchers import HasWaitingFiles | 15 | from lpbuildd.tests.matchers import HasWaitingFiles |
48 | 16 | from lpbuildd.translationtemplates import ( | 16 | from lpbuildd.translationtemplates import ( |
49 | 17 | RETCODE_FAILURE_BUILD, | ||
50 | 18 | RETCODE_FAILURE_INSTALL, | ||
51 | 17 | TranslationTemplatesBuildManager, | 19 | TranslationTemplatesBuildManager, |
52 | 18 | TranslationTemplatesBuildState, | 20 | TranslationTemplatesBuildState, |
53 | 19 | ) | 21 | ) |
54 | @@ -65,23 +67,9 @@ | |||
55 | 65 | self.buildmanager.backend_name = original_backend_name | 67 | self.buildmanager.backend_name = original_backend_name |
56 | 66 | 68 | ||
57 | 67 | # Skip states that are done in DebianBuildManager to the state | 69 | # Skip states that are done in DebianBuildManager to the state |
59 | 68 | # directly before INSTALL. | 70 | # directly before GENERATE. |
60 | 69 | self.buildmanager._state = TranslationTemplatesBuildState.UPDATE | 71 | self.buildmanager._state = TranslationTemplatesBuildState.UPDATE |
61 | 70 | 72 | ||
62 | 71 | # INSTALL: Install additional packages needed for this job into | ||
63 | 72 | # the chroot. | ||
64 | 73 | self.buildmanager.iterate(0) | ||
65 | 74 | self.assertEqual( | ||
66 | 75 | TranslationTemplatesBuildState.INSTALL, self.getState()) | ||
67 | 76 | expected_command = [ | ||
68 | 77 | '/usr/bin/sudo', | ||
69 | 78 | 'sudo', 'chroot', self.chrootdir, | ||
70 | 79 | 'apt-get', | ||
71 | 80 | ] | ||
72 | 81 | self.assertEqual(expected_command, self.buildmanager.commands[-1][:5]) | ||
73 | 82 | self.assertEqual( | ||
74 | 83 | self.buildmanager.iterate, self.buildmanager.iterators[-1]) | ||
75 | 84 | |||
76 | 85 | # GENERATE: Run the slave's payload, the script that generates | 73 | # GENERATE: Run the slave's payload, the script that generates |
77 | 86 | # templates. | 74 | # templates. |
78 | 87 | self.buildmanager.iterate(0) | 75 | self.buildmanager.iterate(0) |
79 | @@ -136,34 +124,50 @@ | |||
80 | 136 | self.buildmanager.iterate, self.buildmanager.iterators[-1]) | 124 | self.buildmanager.iterate, self.buildmanager.iterators[-1]) |
81 | 137 | self.assertFalse(self.slave.wasCalled('buildFail')) | 125 | self.assertFalse(self.slave.wasCalled('buildFail')) |
82 | 138 | 126 | ||
85 | 139 | def test_iterate_fail_INSTALL(self): | 127 | def test_iterate_fail_GENERATE_install(self): |
86 | 140 | # See that a failing INSTALL is handled properly. | 128 | # See that a GENERATE that fails at the install step is handled |
87 | 129 | # properly. | ||
88 | 141 | url = 'lp:~my/branch' | 130 | url = 'lp:~my/branch' |
89 | 142 | # The build manager's iterate() kicks off the consecutive states | 131 | # The build manager's iterate() kicks off the consecutive states |
90 | 143 | # after INIT. | 132 | # after INIT. |
91 | 144 | self.buildmanager.initiate( | 133 | self.buildmanager.initiate( |
92 | 145 | {}, 'chroot.tar.gz', {'series': 'xenial', 'branch_url': url}) | 134 | {}, 'chroot.tar.gz', {'series': 'xenial', 'branch_url': url}) |
93 | 146 | 135 | ||
96 | 147 | # Skip states to the INSTALL state. | 136 | # Skip states to the GENERATE state. |
97 | 148 | self.buildmanager._state = TranslationTemplatesBuildState.INSTALL | 137 | self.buildmanager._state = TranslationTemplatesBuildState.GENERATE |
98 | 149 | 138 | ||
101 | 150 | # The buildmanager fails and iterates to the UMOUNT state. | 139 | # The buildmanager fails and reaps processes. |
102 | 151 | self.buildmanager.iterate(-1) | 140 | self.buildmanager.iterate(RETCODE_FAILURE_INSTALL) |
103 | 152 | self.assertEqual( | 141 | self.assertEqual( |
105 | 153 | TranslationTemplatesBuildState.UMOUNT, self.getState()) | 142 | TranslationTemplatesBuildState.GENERATE, self.getState()) |
106 | 154 | expected_command = [ | 143 | expected_command = [ |
107 | 155 | 'sharepath/slavebin/in-target', 'in-target', | 144 | 'sharepath/slavebin/in-target', 'in-target', |
109 | 156 | 'umount-chroot', | 145 | 'scan-for-processes', |
110 | 157 | '--backend=chroot', '--series=xenial', '--arch=i386', | 146 | '--backend=chroot', '--series=xenial', '--arch=i386', |
111 | 158 | self.buildid, | 147 | self.buildid, |
112 | 159 | ] | 148 | ] |
113 | 160 | self.assertEqual(expected_command, self.buildmanager.commands[-1]) | 149 | self.assertEqual(expected_command, self.buildmanager.commands[-1]) |
115 | 161 | self.assertEqual( | 150 | self.assertNotEqual( |
116 | 162 | self.buildmanager.iterate, self.buildmanager.iterators[-1]) | 151 | self.buildmanager.iterate, self.buildmanager.iterators[-1]) |
117 | 163 | self.assertTrue(self.slave.wasCalled('chrootFail')) | 152 | self.assertTrue(self.slave.wasCalled('chrootFail')) |
118 | 164 | 153 | ||
121 | 165 | def test_iterate_fail_GENERATE(self): | 154 | # The buildmanager iterates to the UMOUNT state. |
122 | 166 | # See that a failing GENERATE is handled properly. | 155 | self.buildmanager.iterateReap(self.getState(), 0) |
123 | 156 | self.assertEqual( | ||
124 | 157 | TranslationTemplatesBuildState.UMOUNT, self.getState()) | ||
125 | 158 | expected_command = [ | ||
126 | 159 | 'sharepath/slavebin/in-target', 'in-target', | ||
127 | 160 | 'umount-chroot', | ||
128 | 161 | '--backend=chroot', '--series=xenial', '--arch=i386', | ||
129 | 162 | self.buildid, | ||
130 | 163 | ] | ||
131 | 164 | self.assertEqual(expected_command, self.buildmanager.commands[-1]) | ||
132 | 165 | self.assertEqual( | ||
133 | 166 | self.buildmanager.iterate, self.buildmanager.iterators[-1]) | ||
134 | 167 | |||
135 | 168 | def test_iterate_fail_GENERATE_build(self): | ||
136 | 169 | # See that a GENERATE that fails at the build step is handled | ||
137 | 170 | # properly. | ||
138 | 167 | url = 'lp:~my/branch' | 171 | url = 'lp:~my/branch' |
139 | 168 | # The build manager's iterate() kicks off the consecutive states | 172 | # The build manager's iterate() kicks off the consecutive states |
140 | 169 | # after INIT. | 173 | # after INIT. |
141 | @@ -174,7 +178,7 @@ | |||
142 | 174 | self.buildmanager._state = TranslationTemplatesBuildState.GENERATE | 178 | self.buildmanager._state = TranslationTemplatesBuildState.GENERATE |
143 | 175 | 179 | ||
144 | 176 | # The buildmanager fails and reaps processes. | 180 | # The buildmanager fails and reaps processes. |
146 | 177 | self.buildmanager.iterate(-1) | 181 | self.buildmanager.iterate(RETCODE_FAILURE_BUILD) |
147 | 178 | expected_command = [ | 182 | expected_command = [ |
148 | 179 | 'sharepath/slavebin/in-target', 'in-target', | 183 | 'sharepath/slavebin/in-target', 'in-target', |
149 | 180 | 'scan-for-processes', | 184 | 'scan-for-processes', |
150 | 181 | 185 | ||
151 | === modified file 'lpbuildd/translationtemplates.py' | |||
152 | --- lpbuildd/translationtemplates.py 2017-08-05 09:43:43 +0000 | |||
153 | +++ lpbuildd/translationtemplates.py 2017-09-08 14:41:25 +0000 | |||
154 | @@ -1,15 +1,21 @@ | |||
156 | 1 | # Copyright 2010 Canonical Ltd. This software is licensed under the | 1 | # Copyright 2010-2017 Canonical Ltd. This software is licensed under the |
157 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). |
158 | 3 | 3 | ||
159 | 4 | __metaclass__ = type | 4 | __metaclass__ = type |
160 | 5 | 5 | ||
161 | 6 | import os | 6 | import os |
162 | 7 | 7 | ||
164 | 8 | from lpbuildd.debian import DebianBuildManager, DebianBuildState | 8 | from lpbuildd.debian import ( |
165 | 9 | DebianBuildManager, | ||
166 | 10 | DebianBuildState, | ||
167 | 11 | ) | ||
168 | 12 | |||
169 | 13 | |||
170 | 14 | RETCODE_FAILURE_INSTALL = 200 | ||
171 | 15 | RETCODE_FAILURE_BUILD = 201 | ||
172 | 9 | 16 | ||
173 | 10 | 17 | ||
174 | 11 | class TranslationTemplatesBuildState(DebianBuildState): | 18 | class TranslationTemplatesBuildState(DebianBuildState): |
175 | 12 | INSTALL = "INSTALL" | ||
176 | 13 | GENERATE = "GENERATE" | 19 | GENERATE = "GENERATE" |
177 | 14 | 20 | ||
178 | 15 | 21 | ||
179 | @@ -21,7 +27,7 @@ | |||
180 | 21 | runs on the build slave. | 27 | runs on the build slave. |
181 | 22 | """ | 28 | """ |
182 | 23 | 29 | ||
184 | 24 | initial_build_state = TranslationTemplatesBuildState.INSTALL | 30 | initial_build_state = TranslationTemplatesBuildState.GENERATE |
185 | 25 | 31 | ||
186 | 26 | def __init__(self, slave, buildid): | 32 | def __init__(self, slave, buildid): |
187 | 27 | super(TranslationTemplatesBuildManager, self).__init__(slave, buildid) | 33 | super(TranslationTemplatesBuildManager, self).__init__(slave, buildid) |
188 | @@ -33,26 +39,10 @@ | |||
189 | 33 | def initiate(self, files, chroot, extra_args): | 39 | def initiate(self, files, chroot, extra_args): |
190 | 34 | """See `BuildManager`.""" | 40 | """See `BuildManager`.""" |
191 | 35 | self._branch_url = extra_args['branch_url'] | 41 | self._branch_url = extra_args['branch_url'] |
192 | 36 | self._chroot_path = os.path.join( | ||
193 | 37 | self.home, 'build-' + self._buildid, 'chroot-autobuild') | ||
194 | 38 | 42 | ||
195 | 39 | super(TranslationTemplatesBuildManager, self).initiate( | 43 | super(TranslationTemplatesBuildManager, self).initiate( |
196 | 40 | files, chroot, extra_args) | 44 | files, chroot, extra_args) |
197 | 41 | 45 | ||
198 | 42 | def doInstall(self): | ||
199 | 43 | """Install packages required.""" | ||
200 | 44 | required_packages = [ | ||
201 | 45 | 'bzr', | ||
202 | 46 | 'intltool', | ||
203 | 47 | ] | ||
204 | 48 | command = ['apt-get', 'install', '-y'] + required_packages | ||
205 | 49 | chroot = ['sudo', 'chroot', self._chroot_path] | ||
206 | 50 | self.runSubProcess('/usr/bin/sudo', chroot + command) | ||
207 | 51 | |||
208 | 52 | # To satisfy DebianPackageManagers needs without having a misleading | ||
209 | 53 | # method name here. | ||
210 | 54 | doRunBuild = doInstall | ||
211 | 55 | |||
212 | 56 | def doGenerate(self): | 46 | def doGenerate(self): |
213 | 57 | """Generate templates.""" | 47 | """Generate templates.""" |
214 | 58 | command = [ | 48 | command = [ |
215 | @@ -60,37 +50,33 @@ | |||
216 | 60 | self._buildid, self._branch_url, self._resultname] | 50 | self._buildid, self._branch_url, self._resultname] |
217 | 61 | self.runSubProcess(self._generatepath, command) | 51 | self.runSubProcess(self._generatepath, command) |
218 | 62 | 52 | ||
219 | 53 | # Satisfy DebianPackageManager's needs without having a misleading | ||
220 | 54 | # method name here. | ||
221 | 55 | doRunBuild = doGenerate | ||
222 | 56 | |||
223 | 63 | def gatherResults(self): | 57 | def gatherResults(self): |
224 | 64 | """Gather the results of the build and add them to the file cache.""" | 58 | """Gather the results of the build and add them to the file cache.""" |
226 | 65 | # The file is inside the chroot, in the home directory of the buildd | 59 | # The file is inside the target, in the home directory of the buildd |
227 | 66 | # user. Should be safe to assume the home dirs are named identically. | 60 | # user. Should be safe to assume the home dirs are named identically. |
228 | 67 | path = os.path.join(self.home, self._resultname) | 61 | path = os.path.join(self.home, self._resultname) |
229 | 68 | if self.backend.path_exists(path): | 62 | if self.backend.path_exists(path): |
230 | 69 | self.addWaitingFileFromBackend(path) | 63 | self.addWaitingFileFromBackend(path) |
231 | 70 | 64 | ||
245 | 71 | def iterate_INSTALL(self, success): | 65 | def iterate_GENERATE(self, retcode): |
233 | 72 | """Installation was done.""" | ||
234 | 73 | if success == 0: | ||
235 | 74 | self._state = TranslationTemplatesBuildState.GENERATE | ||
236 | 75 | self.doGenerate() | ||
237 | 76 | else: | ||
238 | 77 | if not self.alreadyfailed: | ||
239 | 78 | self._slave.chrootFail() | ||
240 | 79 | self.alreadyfailed = True | ||
241 | 80 | self._state = TranslationTemplatesBuildState.UMOUNT | ||
242 | 81 | self.doUnmounting() | ||
243 | 82 | |||
244 | 83 | def iterate_GENERATE(self, success): | ||
246 | 84 | """Template generation finished.""" | 66 | """Template generation finished.""" |
248 | 85 | if success == 0: | 67 | if retcode == 0: |
249 | 86 | # It worked! Now let's bring in the harvest. | 68 | # It worked! Now let's bring in the harvest. |
250 | 87 | self.gatherResults() | 69 | self.gatherResults() |
251 | 88 | self.doReapProcesses(self._state) | ||
252 | 89 | else: | 70 | else: |
253 | 90 | if not self.alreadyfailed: | 71 | if not self.alreadyfailed: |
255 | 91 | self._slave.buildFail() | 72 | if retcode == RETCODE_FAILURE_INSTALL: |
256 | 73 | self._slave.chrootFail() | ||
257 | 74 | elif retcode == RETCODE_FAILURE_BUILD: | ||
258 | 75 | self._slave.buildFail() | ||
259 | 76 | else: | ||
260 | 77 | self._slave.builderFail() | ||
261 | 92 | self.alreadyfailed = True | 78 | self.alreadyfailed = True |
263 | 93 | self.doReapProcesses(self._state) | 79 | self.doReapProcesses(self._state) |
264 | 94 | 80 | ||
265 | 95 | def iterateReap_GENERATE(self, success): | 81 | def iterateReap_GENERATE(self, success): |
266 | 96 | """Finished reaping after template generation.""" | 82 | """Finished reaping after template generation.""" |