1 |
commit: f43ba834fa9a6ef83d81f6e5512078ac741a6ac6 |
2 |
Author: Magnus Granberg <zorry <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon Dec 28 16:03:12 2020 +0000 |
4 |
Commit: Magnus Granberg <zorry <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon Dec 28 16:15:59 2020 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/tinderbox-cluster.git/commit/?id=f43ba834 |
7 |
|
8 |
Make upgrade_master work |
9 |
|
10 |
Signed-off-by: Magnus Granberg <zorry <AT> gentoo.org> |
11 |
|
12 |
README.txt | 8 + |
13 |
buildbot_gentoo_ci/__init__.py | 0 |
14 |
buildbot_gentoo_ci/config/__init__.py | 0 |
15 |
buildbot_gentoo_ci/config/builders.py | 9 + |
16 |
buildbot_gentoo_ci/config/buildfactory.py | 8 + |
17 |
buildbot_gentoo_ci/config/config.py | 135 ++++++++ |
18 |
buildbot_gentoo_ci/config/schedulers.py | 56 ++++ |
19 |
buildbot_gentoo_ci/config/workers.py | 8 + |
20 |
buildbot_gentoo_ci/db/__init__.py | 0 |
21 |
buildbot_gentoo_ci/db/connector.py | 98 ++++++ |
22 |
buildbot_gentoo_ci/db/migrate/README | 4 + |
23 |
buildbot_gentoo_ci/db/migrate/migrate.cfg | 20 ++ |
24 |
buildbot_gentoo_ci/db/migrate/versions/__init__.py | 0 |
25 |
buildbot_gentoo_ci/db/model.py | 352 +++++++++++++++++++++ |
26 |
buildbot_gentoo_ci/scripts/update_db.py | 110 +++++++ |
27 |
gentooci.cfg | 17 + |
28 |
licenses/GPL-2 | 339 ++++++++++++++++++++ |
29 |
master.cfg | 80 +++++ |
30 |
18 files changed, 1244 insertions(+) |
31 |
|
32 |
diff --git a/README.txt b/README.txt |
33 |
new file mode 100644 |
34 |
index 0000000..1e08eb1 |
35 |
--- /dev/null |
36 |
+++ b/README.txt |
37 |
@@ -0,0 +1,8 @@ |
38 |
+============================= |
39 |
+Gentoo Ci Build System |
40 |
+============================= |
41 |
+ |
42 |
+This is a POC |
43 |
+We use Buildbot to build and test packages |
44 |
+ |
45 |
+https://wiki.gentoo.org/wiki/Project:Tinderbox-cluster |
46 |
|
47 |
diff --git a/buildbot_gentoo_ci/__init__.py b/buildbot_gentoo_ci/__init__.py |
48 |
new file mode 100644 |
49 |
index 0000000..e69de29 |
50 |
|
51 |
diff --git a/buildbot_gentoo_ci/config/__init__.py b/buildbot_gentoo_ci/config/__init__.py |
52 |
new file mode 100644 |
53 |
index 0000000..e69de29 |
54 |
|
55 |
diff --git a/buildbot_gentoo_ci/config/builders.py b/buildbot_gentoo_ci/config/builders.py |
56 |
new file mode 100644 |
57 |
index 0000000..b663fba |
58 |
--- /dev/null |
59 |
+++ b/buildbot_gentoo_ci/config/builders.py |
60 |
@@ -0,0 +1,9 @@ |
61 |
+# Copyright 2020 Gentoo Authors |
62 |
+# Distributed under the terms of the GNU General Public License v2 |
63 |
+ |
64 |
+from buildbot.plugins import util |
65 |
+from buildbot_gentoo_ci.config import buildfactory |
66 |
+ |
67 |
+def gentoo_builders(b=[]): |
68 |
+ b.append(util.BuilderConfig(name='update_db_packages', workername='updatedb_1', factory=buildfactory.f_update_db_packages())) |
69 |
+ return b |
70 |
|
71 |
diff --git a/buildbot_gentoo_ci/config/buildfactory.py b/buildbot_gentoo_ci/config/buildfactory.py |
72 |
new file mode 100644 |
73 |
index 0000000..0943031 |
74 |
--- /dev/null |
75 |
+++ b/buildbot_gentoo_ci/config/buildfactory.py |
76 |
@@ -0,0 +1,8 @@ |
77 |
+# Copyright 2020 Gentoo Authors |
78 |
+# Distributed under the terms of the GNU General Public License v2 |
79 |
+ |
80 |
+from buildbot.plugins import util |
81 |
+ |
82 |
+def f_update_db_packages(): |
83 |
+ f = util.BuildFactory() |
84 |
+ return f |
85 |
|
86 |
diff --git a/buildbot_gentoo_ci/config/config.py b/buildbot_gentoo_ci/config/config.py |
87 |
new file mode 100644 |
88 |
index 0000000..3ad8595 |
89 |
--- /dev/null |
90 |
+++ b/buildbot_gentoo_ci/config/config.py |
91 |
@@ -0,0 +1,135 @@ |
92 |
+# This file has parts from Buildbot and is modifyed by Gentoo Authors. |
93 |
+# Buildbot is free software: you can redistribute it and/or modify it |
94 |
+# under the terms of the GNU General Public License as published by the |
95 |
+# Free Software Foundation, version 2. |
96 |
+# |
97 |
+# This program is distributed in the hope that it will be useful, but WITHOUT |
98 |
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
99 |
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
100 |
+# details. |
101 |
+# |
102 |
+# You should have received a copy of the GNU General Public License along with |
103 |
+# this program; if not, write to the Free Software Foundation, Inc., 51 |
104 |
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
105 |
+# |
106 |
+# Copyright Buildbot Team Members |
107 |
+# Origins: buildbot.config.py |
108 |
+# Modifyed by Gentoo Authors. |
109 |
+# Copyright 2020 Gentoo Authors |
110 |
+ |
111 |
+import datetime |
112 |
+import inspect |
113 |
+import os |
114 |
+import re |
115 |
+import sys |
116 |
+import traceback |
117 |
+import warnings |
118 |
+from types import MethodType |
119 |
+ |
120 |
+from twisted.python import failure |
121 |
+from twisted.python import log |
122 |
+from twisted.python.compat import execfile |
123 |
+from zope.interface import implementer |
124 |
+ |
125 |
+from buildbot import interfaces |
126 |
+from buildbot import locks |
127 |
+from buildbot import util |
128 |
+from buildbot.interfaces import IRenderable |
129 |
+from buildbot.revlinks import default_revlink_matcher |
130 |
+from buildbot.util import ComparableMixin |
131 |
+from buildbot.util import bytes2unicode |
132 |
+from buildbot.util import config as util_config |
133 |
+from buildbot.util import identifiers as util_identifiers |
134 |
+from buildbot.util import safeTranslate |
135 |
+from buildbot.util import service as util_service |
136 |
+from buildbot.warnings import ConfigWarning |
137 |
+from buildbot.warnings import warn_deprecated |
138 |
+from buildbot.config import ConfigErrors, error, loadConfigDict |
139 |
+ |
140 |
+_errors = None |
141 |
+ |
142 |
+DEFAULT_DB_URL = 'sqlite:///gentoo.sqlite' |
143 |
+ |
144 |
+#Use GentooCiConfig.loadFromDict |
145 |
+@implementer(interfaces.IConfigLoader) |
146 |
+class FileLoader(ComparableMixin): |
147 |
+ compare_attrs = ['basedir', 'configFileName'] |
148 |
+ |
149 |
+ def __init__(self, basedir, configFileName): |
150 |
+ self.basedir = basedir |
151 |
+ self.configFileName = configFileName |
152 |
+ |
153 |
+ def loadConfig(self): |
154 |
+ # from here on out we can batch errors together for the user's |
155 |
+ # convenience |
156 |
+ global _errors |
157 |
+ _errors = errors = ConfigErrors() |
158 |
+ |
159 |
+ try: |
160 |
+ filename, config_dict = loadConfigDict( |
161 |
+ self.basedir, self.configFileName) |
162 |
+ config = GentooCiConfig.loadFromDict(config_dict, filename) |
163 |
+ except ConfigErrors as e: |
164 |
+ errors.merge(e) |
165 |
+ finally: |
166 |
+ _errors = None |
167 |
+ |
168 |
+ if errors: |
169 |
+ raise errors |
170 |
+ |
171 |
+ return config |
172 |
+ |
173 |
+# Modifyed for Gentoo Ci settings |
174 |
+class GentooCiConfig(util.ComparableMixin): |
175 |
+ |
176 |
+ def __init__(self): |
177 |
+ self.db = dict( |
178 |
+ db_url=DEFAULT_DB_URL, |
179 |
+ ) |
180 |
+ |
181 |
+ _known_config_keys = set([ |
182 |
+ "db_url", |
183 |
+ ]) |
184 |
+ |
185 |
+ compare_attrs = list(_known_config_keys) |
186 |
+ |
187 |
+ @classmethod |
188 |
+ def loadFromDict(cls, config_dict, filename): |
189 |
+ # warning, all of this is loaded from a thread |
190 |
+ global _errors |
191 |
+ _errors = errors = ConfigErrors() |
192 |
+ |
193 |
+ # check for unknown keys |
194 |
+ unknown_keys = set(config_dict.keys()) - cls._known_config_keys |
195 |
+ if unknown_keys: |
196 |
+ if len(unknown_keys) == 1: |
197 |
+ error('Unknown BuildmasterConfig key {}'.format(unknown_keys.pop())) |
198 |
+ else: |
199 |
+ error('Unknown BuildmasterConfig keys {}'.format(', '.join(sorted(unknown_keys)))) |
200 |
+ |
201 |
+ # instantiate a new config object, which will apply defaults |
202 |
+ # automatically |
203 |
+ config = cls() |
204 |
+ # and defer the rest to sub-functions, for code clarity |
205 |
+ try: |
206 |
+ config.load_db(config_dict) |
207 |
+ finally: |
208 |
+ _errors = None |
209 |
+ |
210 |
+ if errors: |
211 |
+ raise errors |
212 |
+ |
213 |
+ return config |
214 |
+ |
215 |
+ @staticmethod |
216 |
+ def getDbUrlFromConfig(config_dict, throwErrors=True): |
217 |
+ |
218 |
+ # we don't attempt to parse db URLs here - the engine strategy will do |
219 |
+ # so. |
220 |
+ if 'db_url' in config_dict: |
221 |
+ return config_dict['db_url'] |
222 |
+ |
223 |
+ return DEFAULT_DB_URL |
224 |
+ |
225 |
+ def load_db(self, config_dict): |
226 |
+ self.db = dict(db_url=self.getDbUrlFromConfig(config_dict)) |
227 |
|
228 |
diff --git a/buildbot_gentoo_ci/config/schedulers.py b/buildbot_gentoo_ci/config/schedulers.py |
229 |
new file mode 100644 |
230 |
index 0000000..f5b19da |
231 |
--- /dev/null |
232 |
+++ b/buildbot_gentoo_ci/config/schedulers.py |
233 |
@@ -0,0 +1,56 @@ |
234 |
+# Copyright 2020 Gentoo Authors |
235 |
+# Distributed under the terms of the GNU General Public License v2 |
236 |
+ |
237 |
+from buildbot.plugins import schedulers, util |
238 |
+ |
239 |
+@××××.renderer |
240 |
+def builderUpdateDbNames(self, props): |
241 |
+ builders = set() |
242 |
+ for f in props.files: |
243 |
+ if f.endswith('.ebuild'): |
244 |
+ builders.add('update_db_packages') |
245 |
+ return list(builders) |
246 |
+ |
247 |
+@××××.renderer |
248 |
+def cpvUpdateDb(props): |
249 |
+ cpv_changes = [] |
250 |
+ for f in props.files: |
251 |
+ if f.endswith('.ebuild'): |
252 |
+ cppv = f.split('.eb', 0) |
253 |
+ cpv = cppv.split('/', 0) + '/' + cppv.split('/', 2) |
254 |
+ if not cpv in cpv_changes: |
255 |
+ cpv_changes.append(cpv) |
256 |
+ return cpv_changes |
257 |
+ |
258 |
+def gentoo_schedulers(): |
259 |
+ scheduler_update_db = schedulers.SingleBranchScheduler( |
260 |
+ name='scheduler_update_db', |
261 |
+ treeStableTimer=60, |
262 |
+ properties = { |
263 |
+ 'cpv_changes' : cpvUpdateDb, |
264 |
+ }, |
265 |
+ builderNames = builderUpdateDbNames, |
266 |
+ change_filter=util.ChangeFilter(branch='master'), |
267 |
+ ) |
268 |
+ test_updatedb = schedulers.ForceScheduler( |
269 |
+ name="force", |
270 |
+ buttonName="pushMe!", |
271 |
+ label="My nice Force form", |
272 |
+ builderNames=['update_db_packages'], |
273 |
+ # A completely customized property list. The name of the |
274 |
+ # property is the name of the parameter |
275 |
+ properties=[ |
276 |
+ util.NestedParameter(name="options", label="Build Options", |
277 |
+ layout="vertical", fields=[ |
278 |
+ util.StringParameter(name="cpv_changes", |
279 |
+ label="Package to check", |
280 |
+ default="dev-lang/python-3.8", size=80), |
281 |
+ util.StringParameter(name="repository", |
282 |
+ label="repo", |
283 |
+ default="gentoo", size=80), |
284 |
+ ]) |
285 |
+ ]) |
286 |
+ s = [] |
287 |
+ s.append(test_updatedb) |
288 |
+ #s.append(scheduler_update_db) |
289 |
+ return s |
290 |
|
291 |
diff --git a/buildbot_gentoo_ci/config/workers.py b/buildbot_gentoo_ci/config/workers.py |
292 |
new file mode 100644 |
293 |
index 0000000..50a4751 |
294 |
--- /dev/null |
295 |
+++ b/buildbot_gentoo_ci/config/workers.py |
296 |
@@ -0,0 +1,8 @@ |
297 |
+# Copyright 2020 Gentoo Authors |
298 |
+# Distributed under the terms of the GNU General Public License v2 |
299 |
+ |
300 |
+from buildbot.plugins import worker |
301 |
+ |
302 |
+def gentoo_workers(w=[]): |
303 |
+ w.append(worker.LocalWorker('updatedb_1')) |
304 |
+ return w |
305 |
|
306 |
diff --git a/buildbot_gentoo_ci/db/__init__.py b/buildbot_gentoo_ci/db/__init__.py |
307 |
new file mode 100644 |
308 |
index 0000000..e69de29 |
309 |
|
310 |
diff --git a/buildbot_gentoo_ci/db/connector.py b/buildbot_gentoo_ci/db/connector.py |
311 |
new file mode 100644 |
312 |
index 0000000..682e72a |
313 |
--- /dev/null |
314 |
+++ b/buildbot_gentoo_ci/db/connector.py |
315 |
@@ -0,0 +1,98 @@ |
316 |
+# This file has parts from Buildbot and is modifyed by Gentoo Authors. |
317 |
+# Buildbot is free software: you can redistribute it and/or modify it |
318 |
+# under the terms of the GNU General Public License as published by the |
319 |
+# Free Software Foundation, version 2. |
320 |
+# |
321 |
+# This program is distributed in the hope that it will be useful, but WITHOUT |
322 |
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
323 |
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
324 |
+# details. |
325 |
+# |
326 |
+# You should have received a copy of the GNU General Public License along with |
327 |
+# this program; if not, write to the Free Software Foundation, Inc., 51 |
328 |
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
329 |
+# |
330 |
+# Copyright Buildbot Team Members |
331 |
+# Origins: buildbot.db.connector.py |
332 |
+# Modifyed by Gentoo Authors. |
333 |
+# Copyright 2020 Gentoo Authors |
334 |
+ |
335 |
+ |
336 |
+import textwrap |
337 |
+ |
338 |
+from twisted.application import internet |
339 |
+from twisted.internet import defer |
340 |
+from twisted.python import log |
341 |
+ |
342 |
+from buildbot import util |
343 |
+from buildbot.db import enginestrategy |
344 |
+from buildbot.db import exceptions |
345 |
+from buildbot.db import pool |
346 |
+from buildbot.util import service |
347 |
+ |
348 |
+from buildbot_gentoo_ci.db import model |
349 |
+ |
350 |
+upgrade_message = textwrap.dedent("""\ |
351 |
+ |
352 |
+ The Buildmaster database needs to be upgraded before this version of |
353 |
+ buildbot can run. Use the following command-line |
354 |
+ |
355 |
+ buildbot upgrade-master {basedir} |
356 |
+ |
357 |
+ to upgrade the database, and try starting the buildmaster again. You may |
358 |
+ want to make a backup of your buildmaster before doing so. |
359 |
+ """).strip() |
360 |
+ |
361 |
+# Gentoo Ci tables and ConnectorComponent |
362 |
+class DBConnector(service.ReconfigurableServiceMixin, |
363 |
+ service.AsyncMultiService): |
364 |
+ # The connection between Buildbot and its backend database. This is |
365 |
+ # generally accessible as master.db, but is also used during upgrades. |
366 |
+ # |
367 |
+ # Most of the interesting operations available via the connector are |
368 |
+ # implemented in connector components, available as attributes of this |
369 |
+ # object, and listed below. |
370 |
+ |
371 |
+ # Period, in seconds, of the cleanup task. This master will perform |
372 |
+ # periodic cleanup actions on this schedule. |
373 |
+ CLEANUP_PERIOD = 3600 |
374 |
+ |
375 |
+ def __init__(self, basedir): |
376 |
+ super().__init__() |
377 |
+ self.setName('db') |
378 |
+ self.basedir = basedir |
379 |
+ |
380 |
+ # set up components |
381 |
+ self._engine = None # set up in reconfigService |
382 |
+ self.pool = None # set up in reconfigService |
383 |
+ |
384 |
+ @defer.inlineCallbacks |
385 |
+ def setServiceParent(self, p): |
386 |
+ yield super().setServiceParent(p) |
387 |
+ self.model = model.Model(self) |
388 |
+ |
389 |
+ @defer.inlineCallbacks |
390 |
+ def setup(self, config, check_version=True, verbose=True): |
391 |
+ db_url = config.db['db_url'] |
392 |
+ |
393 |
+ log.msg("Setting up database with URL %r" |
394 |
+ % util.stripUrlPassword(db_url)) |
395 |
+ |
396 |
+ # set up the engine and pool |
397 |
+ self._engine = enginestrategy.create_engine(db_url, |
398 |
+ basedir=self.basedir) |
399 |
+ self.pool = pool.DBThreadPool( |
400 |
+ self._engine, reactor=self.master.reactor, verbose=verbose) |
401 |
+ |
402 |
+ # make sure the db is up to date, unless specifically asked not to |
403 |
+ if check_version: |
404 |
+ if db_url == 'sqlite://': |
405 |
+ # Using in-memory database. Since it is reset after each process |
406 |
+ # restart, `buildbot upgrade-master` cannot be used (data is not |
407 |
+ # persistent). Upgrade model here to allow startup to continue. |
408 |
+ self.model.upgrade() |
409 |
+ current = yield self.model.is_current() |
410 |
+ if not current: |
411 |
+ for l in upgrade_message.format(basedir=self.basedir).split('\n'): |
412 |
+ log.msg(l) |
413 |
+ raise exceptions.DatabaseNotReadyError() |
414 |
|
415 |
diff --git a/buildbot_gentoo_ci/db/migrate/README b/buildbot_gentoo_ci/db/migrate/README |
416 |
new file mode 100644 |
417 |
index 0000000..c5f51f2 |
418 |
--- /dev/null |
419 |
+++ b/buildbot_gentoo_ci/db/migrate/README |
420 |
@@ -0,0 +1,4 @@ |
421 |
+This is a database migration repository. |
422 |
+ |
423 |
+More information at |
424 |
+https://sqlalchemy-migrate.readthedocs.io/en/latest/ |
425 |
|
426 |
diff --git a/buildbot_gentoo_ci/db/migrate/migrate.cfg b/buildbot_gentoo_ci/db/migrate/migrate.cfg |
427 |
new file mode 100644 |
428 |
index 0000000..8be171d |
429 |
--- /dev/null |
430 |
+++ b/buildbot_gentoo_ci/db/migrate/migrate.cfg |
431 |
@@ -0,0 +1,20 @@ |
432 |
+[db_settings] |
433 |
+# Used to identify which repository this database is versioned under. |
434 |
+# You can use the name of your project. |
435 |
+repository_id=GentooCi |
436 |
+ |
437 |
+# The name of the database table used to track the schema version. |
438 |
+# This name shouldn't already be used by your project. |
439 |
+# If this is changed once a database is under version control, you'll need to |
440 |
+# change the table name in each database too. |
441 |
+version_table=migrate_version |
442 |
+ |
443 |
+# When committing a change script, Migrate will attempt to generate the |
444 |
+# sql for all supported databases; normally, if one of them fails - probably |
445 |
+# because you don't have that database installed - it is ignored and the |
446 |
+# commit continues, perhaps ending successfully. |
447 |
+# Databases in this list MUST compile successfully during a commit, or the |
448 |
+# entire commit will fail. List the databases your application will actually |
449 |
+# be using to ensure your updates to that database work properly. |
450 |
+# This must be a list; example: ['postgres','sqlite'] |
451 |
+required_dbs=[] |
452 |
|
453 |
diff --git a/buildbot_gentoo_ci/db/migrate/versions/__init__.py b/buildbot_gentoo_ci/db/migrate/versions/__init__.py |
454 |
new file mode 100644 |
455 |
index 0000000..e69de29 |
456 |
|
457 |
diff --git a/buildbot_gentoo_ci/db/model.py b/buildbot_gentoo_ci/db/model.py |
458 |
new file mode 100644 |
459 |
index 0000000..8865517 |
460 |
--- /dev/null |
461 |
+++ b/buildbot_gentoo_ci/db/model.py |
462 |
@@ -0,0 +1,352 @@ |
463 |
+# This file has parts from Buildbot and is modifyed by Gentoo Authors. |
464 |
+# Buildbot is free software: you can redistribute it and/or modify it |
465 |
+# under the terms of the GNU General Public License as published by the |
466 |
+# Free Software Foundation, version 2. |
467 |
+# |
468 |
+# This program is distributed in the hope that it will be useful, but WITHOUT |
469 |
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
470 |
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
471 |
+# details. |
472 |
+# |
473 |
+# You should have received a copy of the GNU General Public License along with |
474 |
+# this program; if not, write to the Free Software Foundation, Inc., 51 |
475 |
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
476 |
+# |
477 |
+# Copyright Buildbot Team Members |
478 |
+# Origins: buildbot.db.model.py |
479 |
+# Modifyed by Gentoo Authors. |
480 |
+# Copyright 2020 Gentoo Authors |
481 |
+ |
482 |
+import uuid |
483 |
+import migrate |
484 |
+import migrate.versioning.repository |
485 |
+import sqlalchemy as sa |
486 |
+from migrate import exceptions # pylint: disable=ungrouped-imports |
487 |
+ |
488 |
+from twisted.internet import defer |
489 |
+from twisted.python import log |
490 |
+from twisted.python import util |
491 |
+ |
492 |
+from buildbot.db import base |
493 |
+from buildbot.db.migrate_utils import test_unicode |
494 |
+from buildbot.util import sautils |
495 |
+ |
496 |
+try: |
497 |
+ from migrate.versioning.schema import ControlledSchema # pylint: disable=ungrouped-imports |
498 |
+except ImportError: |
499 |
+ ControlledSchema = None |
500 |
+ |
501 |
+ |
502 |
+class Model(base.DBConnectorComponent): |
503 |
+ # |
504 |
+ # schema |
505 |
+ # |
506 |
+ |
507 |
+ metadata = sa.MetaData() |
508 |
+ |
509 |
+ # NOTES |
510 |
+ |
511 |
+ # * server_defaults here are included to match those added by the migration |
512 |
+ # scripts, but they should not be depended on - all code accessing these |
513 |
+ # tables should supply default values as necessary. The defaults are |
514 |
+ # required during migration when adding non-nullable columns to existing |
515 |
+ # tables. |
516 |
+ # |
517 |
+ # * dates are stored as unix timestamps (UTC-ish epoch time) |
518 |
+ # |
519 |
+ # * sqlalchemy does not handle sa.Boolean very well on MySQL or Postgres; |
520 |
+ # use sa.SmallInteger instead |
521 |
+ |
522 |
+ # Tables related to gentoo-ci-cloud |
523 |
+ # ------------------------- |
524 |
+ |
525 |
+ repositorys = sautils.Table( |
526 |
+ "repositorys", metadata, |
527 |
+ # unique id per repository |
528 |
+ sa.Column('uuid', sa.String(36), primary_key=True, |
529 |
+ default=lambda: str(uuid.uuid4()), |
530 |
+ ), |
531 |
+ # repository's name |
532 |
+ sa.Column('name', sa.String(255), nullable=False), |
533 |
+ # description of the repository |
534 |
+ sa.Column('description', sa.Text, nullable=True), |
535 |
+ sa.Column('mirror_url', sa.String(255), nullable=True), |
536 |
+ sa.Column('auto', sa.Boolean, default=False), |
537 |
+ sa.Column('enabled', sa.Boolean, default=False), |
538 |
+ sa.Column('ebuild', sa.Boolean, default=False), |
539 |
+ ) |
540 |
+ |
541 |
+ # Use by GitPoller |
542 |
+ repository_gitpuller = sautils.Table( |
543 |
+ "repository_gitpuller", metadata, |
544 |
+ # unique id per repository |
545 |
+ sa.Column('id', sa.Integer, primary_key=True), |
546 |
+ sa.Column('repository_uuid', sa.String(36), |
547 |
+ sa.ForeignKey('repositorys.uuid', ondelete='CASCADE'), |
548 |
+ nullable=False), |
549 |
+ sa.Column('project', sa.String(255), nullable=False, default='gentoo'), |
550 |
+ sa.Column('url', sa.String(255), nullable=False), |
551 |
+ sa.Column('branche', sa.String(255), nullable=False, default='master'), |
552 |
+ ) |
553 |
+ |
554 |
+ projects = sautils.Table( |
555 |
+ "projects", metadata, |
556 |
+ # unique id per project |
557 |
+ sa.Column('uuid', sa.String(36), primary_key=True, |
558 |
+ default=lambda: str(uuid.uuid4()), |
559 |
+ ), |
560 |
+ # project's name |
561 |
+ sa.Column('name', sa.String(255), nullable=False), |
562 |
+ # description of the project |
563 |
+ sa.Column('description', sa.Text, nullable=True), |
564 |
+ sa.Column('profile', sa.String(255), nullable=False), |
565 |
+ sa.Column('portage_repository_uuid', sa.Integer, |
566 |
+ sa.ForeignKey('repositorys.uuid', ondelete='CASCADE'), |
567 |
+ nullable=False), |
568 |
+ sa.Column('keyword_id', sa.Integer, |
569 |
+ sa.ForeignKey('keywords.id', ondelete='CASCADE'), |
570 |
+ nullable=False), |
571 |
+ sa.Column('unstable', sa.Boolean, default=False), |
572 |
+ sa.Column('auto', sa.Boolean, default=False), |
573 |
+ sa.Column('enabled', sa.Boolean, default=False), |
574 |
+ sa.Column('created_by', sa.Integer, |
575 |
+ sa.ForeignKey('users.uid', ondelete='CASCADE'), |
576 |
+ nullable=False), |
577 |
+ ) |
578 |
+ |
579 |
+ # What repository's use by projects |
580 |
+ projects_repositorys = sautils.Table( |
581 |
+ "projects_repositorys", metadata, |
582 |
+ sa.Column('id', sa.Integer, primary_key=True), |
583 |
+ sa.Column('projects_uuid', sa.String(36), |
584 |
+ sa.ForeignKey('projects.uuid', ondelete='CASCADE'), |
585 |
+ nullable=False), |
586 |
+ sa.Column('repository_uuid', sa.String(36), |
587 |
+ sa.ForeignKey('repositorys.uuid', ondelete='CASCADE'), |
588 |
+ nullable=False), |
589 |
+ ) |
590 |
+ keywords = sautils.Table( |
591 |
+ "keywords", metadata, |
592 |
+ # unique id per project |
593 |
+ sa.Column('id', sa.Integer, primary_key=True), |
594 |
+ # project's name |
595 |
+ sa.Column('keyword', sa.String(255), nullable=False), |
596 |
+ ) |
597 |
+ |
598 |
+ categorys = sautils.Table( |
599 |
+ "categories", metadata, |
600 |
+ sa.Column('uuid', sa.String(36), primary_key=True, |
601 |
+ default=lambda: str(uuid.uuid4()) |
602 |
+ ), |
603 |
+ sa.Column('name', sa.String(255), nullable=False), |
604 |
+ ) |
605 |
+ |
606 |
+ packages = sautils.Table( |
607 |
+ "packages", metadata, |
608 |
+ sa.Column('uuid', sa.String(36), primary_key=True, |
609 |
+ default=lambda: str(uuid.uuid4()), |
610 |
+ ), |
611 |
+ sa.Column('name', sa.String(255), nullable=False), |
612 |
+ sa.Column('category_uuid', sa.String(36), |
613 |
+ sa.ForeignKey('categories.uuid', ondelete='CASCADE'), |
614 |
+ nullable=False), |
615 |
+ sa.Column('repository_uuid', sa.String(36), |
616 |
+ sa.ForeignKey('repositorys.uuid', ondelete='CASCADE'), |
617 |
+ nullable=False), |
618 |
+ sa.Column('deleted', sa.Boolean, default=False), |
619 |
+ sa.Column('deleted_at', sa.Integer, nullable=True), |
620 |
+ ) |
621 |
+ |
622 |
+ ebuilds = sautils.Table( |
623 |
+ "ebuilds", metadata, |
624 |
+ sa.Column('uuid', sa.String(36), primary_key=True, |
625 |
+ default=lambda: str(uuid.uuid4()), |
626 |
+ ), |
627 |
+ sa.Column('name', sa.String(255), nullable=False), |
628 |
+ sa.Column('package_uuid', sa.String(36), |
629 |
+ sa.ForeignKey('packages.uuid', ondelete='CASCADE'), |
630 |
+ nullable=False), |
631 |
+ sa.Column('ebuild_hash', sa.String(255), nullable=False), |
632 |
+ sa.Column('deleted', sa.Boolean, default=False), |
633 |
+ sa.Column('deleted_at', sa.Integer, nullable=True), |
634 |
+ ) |
635 |
+ |
636 |
+ ebuildkeywords = sautils.Table( |
637 |
+ "ebuildkeywords", metadata, |
638 |
+ # unique id per project |
639 |
+ sa.Column('id', sa.Integer, primary_key=True), |
640 |
+ # project's name |
641 |
+ sa.Column('keyword_id', sa.Integer, |
642 |
+ sa.ForeignKey('keywords.id', ondelete='CASCADE')), |
643 |
+ sa.Column('ebuild_uuid', sa.String(36), |
644 |
+ sa.ForeignKey('ebuilds.uuid', ondelete='CASCADE')), |
645 |
+ sa.Column('status', sa.String(255), nullable=False), |
646 |
+ ) |
647 |
+ |
648 |
+ # Tables related to users |
649 |
+ # ----------------------- |
650 |
+ |
651 |
+ # This table identifies individual users, and contains buildbot-specific |
652 |
+ # information about those users. |
653 |
+ users = sautils.Table( |
654 |
+ "users", metadata, |
655 |
+ # unique user id number |
656 |
+ sa.Column("uid", sa.Integer, primary_key=True), |
657 |
+ |
658 |
+ # identifier (nickname) for this user; used for display |
659 |
+ sa.Column("identifier", sa.String(255), nullable=False), |
660 |
+ |
661 |
+ # username portion of user credentials for authentication |
662 |
+ sa.Column("bb_username", sa.String(128)), |
663 |
+ |
664 |
+ # password portion of user credentials for authentication |
665 |
+ sa.Column("bb_password", sa.String(128)), |
666 |
+ ) |
667 |
+ |
668 |
+ # Indexes |
669 |
+ # ------- |
670 |
+ |
671 |
+ |
672 |
+ |
673 |
+ # MySQL creates indexes for foreign keys, and these appear in the |
674 |
+ # reflection. This is a list of (table, index) names that should be |
675 |
+ # expected on this platform |
676 |
+ |
677 |
+ implied_indexes = [ |
678 |
+ ] |
679 |
+ |
680 |
+ # Migration support |
681 |
+ # ----------------- |
682 |
+ |
683 |
+ # this is a bit more complicated than might be expected because the first |
684 |
+ # seven database versions were once implemented using a homespun migration |
685 |
+ # system, and we need to support upgrading masters from that system. The |
686 |
+ # old system used a 'version' table, where SQLAlchemy-Migrate uses |
687 |
+ # 'migrate_version' |
688 |
+ |
689 |
+ repo_path = util.sibpath(__file__, "migrate") |
690 |
+ |
691 |
+ @defer.inlineCallbacks |
692 |
+ def is_current(self): |
693 |
+ if ControlledSchema is None: |
694 |
+ # this should have been caught earlier by enginestrategy.py with a |
695 |
+ # nicer error message |
696 |
+ raise ImportError("SQLAlchemy/SQLAlchemy-Migrate version conflict") |
697 |
+ |
698 |
+ def thd(engine): |
699 |
+ # we don't even have to look at the old version table - if there's |
700 |
+ # no migrate_version, then we're not up to date. |
701 |
+ repo = migrate.versioning.repository.Repository(self.repo_path) |
702 |
+ repo_version = repo.latest |
703 |
+ try: |
704 |
+ # migrate.api doesn't let us hand in an engine |
705 |
+ schema = ControlledSchema(engine, self.repo_path) |
706 |
+ db_version = schema.version |
707 |
+ except exceptions.DatabaseNotControlledError: |
708 |
+ return False |
709 |
+ |
710 |
+ return db_version == repo_version |
711 |
+ ret = yield self.db.pool.do_with_engine(thd) |
712 |
+ return ret |
713 |
+ |
714 |
+ # returns a Deferred that returns None |
715 |
+ def create(self): |
716 |
+ # this is nice and simple, but used only for tests |
717 |
+ def thd(engine): |
718 |
+ self.metadata.create_all(bind=engine) |
719 |
+ return self.db.pool.do_with_engine(thd) |
720 |
+ |
721 |
+ @defer.inlineCallbacks |
722 |
+ def upgrade(self): |
723 |
+ |
724 |
+ # here, things are a little tricky. If we have a 'version' table, then |
725 |
+ # we need to version_control the database with the proper version |
726 |
+ # number, drop 'version', and then upgrade. If we have no 'version' |
727 |
+ # table and no 'migrate_version' table, then we need to version_control |
728 |
+ # the database. Otherwise, we just need to upgrade it. |
729 |
+ |
730 |
+ def table_exists(engine, tbl): |
731 |
+ try: |
732 |
+ r = engine.execute("select * from {} limit 1".format(tbl)) |
733 |
+ r.close() |
734 |
+ return True |
735 |
+ except Exception: |
736 |
+ return False |
737 |
+ |
738 |
+ # http://code.google.com/p/sqlalchemy-migrate/issues/detail?id=100 |
739 |
+ # means we cannot use the migrate.versioning.api module. So these |
740 |
+ # methods perform similar wrapping functions to what is done by the API |
741 |
+ # functions, but without disposing of the engine. |
742 |
+ def upgrade(engine): |
743 |
+ schema = ControlledSchema(engine, self.repo_path) |
744 |
+ changeset = schema.changeset(None) |
745 |
+ with sautils.withoutSqliteForeignKeys(engine): |
746 |
+ for version, change in changeset: |
747 |
+ log.msg('migrating schema version {} -> {}'.format(version, version + 1)) |
748 |
+ schema.runchange(version, change, 1) |
749 |
+ |
750 |
+ def check_sqlalchemy_migrate_version(): |
751 |
+ # sqlalchemy-migrate started including a version number in 0.7; we |
752 |
+ # support back to 0.6.1, but not 0.6. We'll use some discovered |
753 |
+ # differences between 0.6.1 and 0.6 to get that resolution. |
754 |
+ version = getattr(migrate, '__version__', 'old') |
755 |
+ if version == 'old': |
756 |
+ try: |
757 |
+ from migrate.versioning import schemadiff |
758 |
+ if hasattr(schemadiff, 'ColDiff'): |
759 |
+ version = "0.6.1" |
760 |
+ else: |
761 |
+ version = "0.6" |
762 |
+ except Exception: |
763 |
+ version = "0.0" |
764 |
+ version_tup = tuple(map(int, version.split('-', 1)[0].split('.'))) |
765 |
+ log.msg("using SQLAlchemy-Migrate version {}".format(version)) |
766 |
+ if version_tup < (0, 6, 1): |
767 |
+ raise RuntimeError(("You are using SQLAlchemy-Migrate {}. " |
768 |
+ "The minimum version is 0.6.1.").format(version)) |
769 |
+ |
770 |
+ def version_control(engine, version=None): |
771 |
+ ControlledSchema.create(engine, self.repo_path, version) |
772 |
+ |
773 |
+ # the upgrade process must run in a db thread |
774 |
+ def thd(engine): |
775 |
+ # if the migrate_version table exists, we can just let migrate |
776 |
+ # take care of this process. |
777 |
+ if table_exists(engine, 'migrate_version'): |
778 |
+ r = engine.execute( |
779 |
+ "select version from migrate_version limit 1") |
780 |
+ old_version = r.scalar() |
781 |
+ if old_version < 40: |
782 |
+ raise EightUpgradeError() |
783 |
+ try: |
784 |
+ upgrade(engine) |
785 |
+ except sa.exc.NoSuchTableError as e: # pragma: no cover |
786 |
+ if 'migration_tmp' in str(e): |
787 |
+ log.err('A serious error has been encountered during the upgrade. The ' |
788 |
+ 'previous upgrade has been likely interrupted. The database has ' |
789 |
+ 'been damaged and automatic recovery is impossible.') |
790 |
+ log.err('If you believe this is an error, please submit a bug to the ' |
791 |
+ 'Buildbot project.') |
792 |
+ raise |
793 |
+ |
794 |
+ # if the version table exists, then we can version_control things |
795 |
+ # at that version, drop the version table, and let migrate take |
796 |
+ # care of the rest. |
797 |
+ elif table_exists(engine, 'version'): |
798 |
+ raise EightUpgradeError() |
799 |
+ |
800 |
+ # otherwise, this db is new, so we don't bother using the migration engine |
801 |
+ # and just create the tables, and put the version directly to |
802 |
+ # latest |
803 |
+ else: |
804 |
+ # do some tests before getting started |
805 |
+ test_unicode(engine) |
806 |
+ |
807 |
+ log.msg("Initializing empty database") |
808 |
+ Model.metadata.create_all(engine) |
809 |
+ repo = migrate.versioning.repository.Repository(self.repo_path) |
810 |
+ |
811 |
+ version_control(engine, repo.latest) |
812 |
+ |
813 |
+ check_sqlalchemy_migrate_version() |
814 |
+ yield self.db.pool.do_with_engine(thd) |
815 |
|
816 |
diff --git a/buildbot_gentoo_ci/scripts/update_db.py b/buildbot_gentoo_ci/scripts/update_db.py |
817 |
new file mode 100644 |
818 |
index 0000000..29e9072 |
819 |
--- /dev/null |
820 |
+++ b/buildbot_gentoo_ci/scripts/update_db.py |
821 |
@@ -0,0 +1,110 @@ |
822 |
+# This file has parts from Buildbot and is modifyed by Gentoo Authors. |
823 |
+# Buildbot is free software: you can redistribute it and/or modify it |
824 |
+# under the terms of the GNU General Public License as published by the |
825 |
+# Free Software Foundation, version 2. |
826 |
+# |
827 |
+# This program is distributed in the hope that it will be useful, but WITHOUT |
828 |
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
829 |
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
830 |
+# details. |
831 |
+# |
832 |
+# You should have received a copy of the GNU General Public License along with |
833 |
+# this program; if not, write to the Free Software Foundation, Inc., 51 |
834 |
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
835 |
+# |
836 |
+# Copyright Buildbot Team Members |
837 |
+# Origins: buildbot.scripts.base.py |
838 |
+# buildbot.scripts.upgrade_master.py |
839 |
+# Modifyed by Gentoo Authors. |
840 |
+# Copyright 2020 Gentoo Authors |
841 |
+ |
842 |
+import os |
843 |
+import signal |
844 |
+import sys |
845 |
+import traceback |
846 |
+ |
847 |
+from twisted.internet import defer |
848 |
+from buildbot.master import BuildMaster |
849 |
+from buildbot.util import stripUrlPassword |
850 |
+from buildbot.config import ConfigErrors |
851 |
+ |
852 |
+from buildbot_gentoo_ci.db import connector |
853 |
+from buildbot_gentoo_ci.config.config import FileLoader |
854 |
+ |
855 |
+# Use FileLoader from Gentoo Ci |
856 |
+def loadConfig(config, configFileName='master.cfg'): |
857 |
+ if not config['quiet']: |
858 |
+ print("checking {}".format(configFileName)) |
859 |
+ |
860 |
+ try: |
861 |
+ master_cfg = FileLoader( |
862 |
+ config['basedir'], configFileName).loadConfig() |
863 |
+ except ConfigErrors as e: |
864 |
+ print("Errors loading configuration:") |
865 |
+ |
866 |
+ for msg in e.errors: |
867 |
+ print(" " + msg) |
868 |
+ return None |
869 |
+ except Exception: |
870 |
+ print("Errors loading configuration:") |
871 |
+ traceback.print_exc(file=sys.stdout) |
872 |
+ return None |
873 |
+ |
874 |
+ return master_cfg |
875 |
+ |
876 |
+#Use the db from Gentoo Ci |
877 |
+@×××××.inlineCallbacks |
878 |
+def upgradeDatabase(config, master_cfg): |
879 |
+ if not config['quiet']: |
880 |
+ print("upgrading database ({})".format(stripUrlPassword(master_cfg.db['db_url']))) |
881 |
+ print("Warning: Stopping this process might cause data loss") |
882 |
+ |
883 |
+ def sighandler(signum, frame): |
884 |
+ msg = " ".join(""" |
885 |
+ WARNING: ignoring signal {}. |
886 |
+ This process should not be interrupted to avoid database corruption. |
887 |
+ If you really need to terminate it, use SIGKILL. |
888 |
+ """.split()) |
889 |
+ print(msg.format(signum)) |
890 |
+ |
891 |
+ prev_handlers = {} |
892 |
+ try: |
893 |
+ for signame in ("SIGTERM", "SIGINT", "SIGQUIT", "SIGHUP", |
894 |
+ "SIGUSR1", "SIGUSR2", "SIGBREAK"): |
895 |
+ if hasattr(signal, signame): |
896 |
+ signum = getattr(signal, signame) |
897 |
+ prev_handlers[signum] = signal.signal(signum, sighandler) |
898 |
+ |
899 |
+ master = BuildMaster(config['basedir']) |
900 |
+ master.config = master_cfg |
901 |
+ master.db.disownServiceParent() |
902 |
+ db = connector.DBConnector(basedir=config['basedir']) |
903 |
+ yield db.setServiceParent(master) |
904 |
+ yield db.setup(master_cfg, check_version=False, verbose=not config['quiet']) |
905 |
+ yield db.model.upgrade() |
906 |
+ yield db.masters.setAllMastersActiveLongTimeAgo() |
907 |
+ |
908 |
+ finally: |
909 |
+ # restore previous signal handlers |
910 |
+ for signum, handler in prev_handlers.items(): |
911 |
+ signal.signal(signum, handler) |
912 |
+ |
913 |
+# Use gentooci.cfg for config |
914 |
+def upgradeGentooCi(config): |
915 |
+ master_cfg = loadConfig(config, 'gentooci.cfg') |
916 |
+ if not master_cfg: |
917 |
+ return defer.succeed(1) |
918 |
+ return _upgradeMaster(config, master_cfg) |
919 |
+ |
920 |
+# No changes |
921 |
+def _upgradeMaster(config, master_cfg): |
922 |
+ try: |
923 |
+ upgradeDatabase(config, master_cfg) |
924 |
+ except Exception: |
925 |
+ e = traceback.format_exc() |
926 |
+ print("problem while upgrading!:\n" + e, file=sys.stderr) |
927 |
+ return 1 |
928 |
+ else: |
929 |
+ if not config['quiet']: |
930 |
+ print("upgrade complete") |
931 |
+ return 0 |
932 |
|
933 |
diff --git a/gentooci.cfg b/gentooci.cfg |
934 |
new file mode 100644 |
935 |
index 0000000..5036ae9 |
936 |
--- /dev/null |
937 |
+++ b/gentooci.cfg |
938 |
@@ -0,0 +1,17 @@ |
939 |
+# -*- python -*- |
940 |
+# ex: set filetype=python: |
941 |
+ |
942 |
+# This is a sample gentoo ci buildmaster config file. It must be installed as |
943 |
+# 'gentooci.cfg' in your buildmaster's base directory. |
944 |
+ |
945 |
+# This is the dictionary that the buildmaster pays attention to. We also use |
946 |
+# a shorter alias to save typing. |
947 |
+c = BuildmasterConfig = {} |
948 |
+ |
949 |
+####### DB URL |
950 |
+####### DB URL |
951 |
+# This specifies what database buildbot uses to store its state. |
952 |
+# It's easy to start with sqlite, but it's recommended to switch to a dedicated |
953 |
+# database, such as PostgreSQL or MySQL, for use in production environments. |
954 |
+# http://docs.buildbot.net/current/manual/configuration/global.html#database-specification |
955 |
+c['db_url'] = "mysql://buildbot:xxxx@192.168.1.x/gentooci?max_idle=300" |
956 |
|
957 |
diff --git a/licenses/GPL-2 b/licenses/GPL-2 |
958 |
new file mode 100644 |
959 |
index 0000000..0e845b5 |
960 |
--- /dev/null |
961 |
+++ b/licenses/GPL-2 |
962 |
@@ -0,0 +1,339 @@ |
963 |
+ GNU GENERAL PUBLIC LICENSE |
964 |
+ Version 2, June 1991 |
965 |
+ |
966 |
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc., |
967 |
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
968 |
+ Everyone is permitted to copy and distribute verbatim copies |
969 |
+ of this license document, but changing it is not allowed. |
970 |
+ |
971 |
+ Preamble |
972 |
+ |
973 |
+ The licenses for most software are designed to take away your |
974 |
+freedom to share and change it. By contrast, the GNU General Public |
975 |
+License is intended to guarantee your freedom to share and change free |
976 |
+software--to make sure the software is free for all its users. This |
977 |
+General Public License applies to most of the Free Software |
978 |
+Foundation's software and to any other program whose authors commit to |
979 |
+using it. (Some other Free Software Foundation software is covered by |
980 |
+the GNU Lesser General Public License instead.) You can apply it to |
981 |
+your programs, too. |
982 |
+ |
983 |
+ When we speak of free software, we are referring to freedom, not |
984 |
+price. Our General Public Licenses are designed to make sure that you |
985 |
+have the freedom to distribute copies of free software (and charge for |
986 |
+this service if you wish), that you receive source code or can get it |
987 |
+if you want it, that you can change the software or use pieces of it |
988 |
+in new free programs; and that you know you can do these things. |
989 |
+ |
990 |
+ To protect your rights, we need to make restrictions that forbid |
991 |
+anyone to deny you these rights or to ask you to surrender the rights. |
992 |
+These restrictions translate to certain responsibilities for you if you |
993 |
+distribute copies of the software, or if you modify it. |
994 |
+ |
995 |
+ For example, if you distribute copies of such a program, whether |
996 |
+gratis or for a fee, you must give the recipients all the rights that |
997 |
+you have. You must make sure that they, too, receive or can get the |
998 |
+source code. And you must show them these terms so they know their |
999 |
+rights. |
1000 |
+ |
1001 |
+ We protect your rights with two steps: (1) copyright the software, and |
1002 |
+(2) offer you this license which gives you legal permission to copy, |
1003 |
+distribute and/or modify the software. |
1004 |
+ |
1005 |
+ Also, for each author's protection and ours, we want to make certain |
1006 |
+that everyone understands that there is no warranty for this free |
1007 |
+software. If the software is modified by someone else and passed on, we |
1008 |
+want its recipients to know that what they have is not the original, so |
1009 |
+that any problems introduced by others will not reflect on the original |
1010 |
+authors' reputations. |
1011 |
+ |
1012 |
+ Finally, any free program is threatened constantly by software |
1013 |
+patents. We wish to avoid the danger that redistributors of a free |
1014 |
+program will individually obtain patent licenses, in effect making the |
1015 |
+program proprietary. To prevent this, we have made it clear that any |
1016 |
+patent must be licensed for everyone's free use or not licensed at all. |
1017 |
+ |
1018 |
+ The precise terms and conditions for copying, distribution and |
1019 |
+modification follow. |
1020 |
+ |
1021 |
+ GNU GENERAL PUBLIC LICENSE |
1022 |
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
1023 |
+ |
1024 |
+ 0. This License applies to any program or other work which contains |
1025 |
+a notice placed by the copyright holder saying it may be distributed |
1026 |
+under the terms of this General Public License. The "Program", below, |
1027 |
+refers to any such program or work, and a "work based on the Program" |
1028 |
+means either the Program or any derivative work under copyright law: |
1029 |
+that is to say, a work containing the Program or a portion of it, |
1030 |
+either verbatim or with modifications and/or translated into another |
1031 |
+language. (Hereinafter, translation is included without limitation in |
1032 |
+the term "modification".) Each licensee is addressed as "you". |
1033 |
+ |
1034 |
+Activities other than copying, distribution and modification are not |
1035 |
+covered by this License; they are outside its scope. The act of |
1036 |
+running the Program is not restricted, and the output from the Program |
1037 |
+is covered only if its contents constitute a work based on the |
1038 |
+Program (independent of having been made by running the Program). |
1039 |
+Whether that is true depends on what the Program does. |
1040 |
+ |
1041 |
+ 1. You may copy and distribute verbatim copies of the Program's |
1042 |
+source code as you receive it, in any medium, provided that you |
1043 |
+conspicuously and appropriately publish on each copy an appropriate |
1044 |
+copyright notice and disclaimer of warranty; keep intact all the |
1045 |
+notices that refer to this License and to the absence of any warranty; |
1046 |
+and give any other recipients of the Program a copy of this License |
1047 |
+along with the Program. |
1048 |
+ |
1049 |
+You may charge a fee for the physical act of transferring a copy, and |
1050 |
+you may at your option offer warranty protection in exchange for a fee. |
1051 |
+ |
1052 |
+ 2. You may modify your copy or copies of the Program or any portion |
1053 |
+of it, thus forming a work based on the Program, and copy and |
1054 |
+distribute such modifications or work under the terms of Section 1 |
1055 |
+above, provided that you also meet all of these conditions: |
1056 |
+ |
1057 |
+ a) You must cause the modified files to carry prominent notices |
1058 |
+ stating that you changed the files and the date of any change. |
1059 |
+ |
1060 |
+ b) You must cause any work that you distribute or publish, that in |
1061 |
+ whole or in part contains or is derived from the Program or any |
1062 |
+ part thereof, to be licensed as a whole at no charge to all third |
1063 |
+ parties under the terms of this License. |
1064 |
+ |
1065 |
+ c) If the modified program normally reads commands interactively |
1066 |
+ when run, you must cause it, when started running for such |
1067 |
+ interactive use in the most ordinary way, to print or display an |
1068 |
+ announcement including an appropriate copyright notice and a |
1069 |
+ notice that there is no warranty (or else, saying that you provide |
1070 |
+ a warranty) and that users may redistribute the program under |
1071 |
+ these conditions, and telling the user how to view a copy of this |
1072 |
+ License. (Exception: if the Program itself is interactive but |
1073 |
+ does not normally print such an announcement, your work based on |
1074 |
+ the Program is not required to print an announcement.) |
1075 |
+ |
1076 |
+These requirements apply to the modified work as a whole. If |
1077 |
+identifiable sections of that work are not derived from the Program, |
1078 |
+and can be reasonably considered independent and separate works in |
1079 |
+themselves, then this License, and its terms, do not apply to those |
1080 |
+sections when you distribute them as separate works. But when you |
1081 |
+distribute the same sections as part of a whole which is a work based |
1082 |
+on the Program, the distribution of the whole must be on the terms of |
1083 |
+this License, whose permissions for other licensees extend to the |
1084 |
+entire whole, and thus to each and every part regardless of who wrote it. |
1085 |
+ |
1086 |
+Thus, it is not the intent of this section to claim rights or contest |
1087 |
+your rights to work written entirely by you; rather, the intent is to |
1088 |
+exercise the right to control the distribution of derivative or |
1089 |
+collective works based on the Program. |
1090 |
+ |
1091 |
+In addition, mere aggregation of another work not based on the Program |
1092 |
+with the Program (or with a work based on the Program) on a volume of |
1093 |
+a storage or distribution medium does not bring the other work under |
1094 |
+the scope of this License. |
1095 |
+ |
1096 |
+ 3. You may copy and distribute the Program (or a work based on it, |
1097 |
+under Section 2) in object code or executable form under the terms of |
1098 |
+Sections 1 and 2 above provided that you also do one of the following: |
1099 |
+ |
1100 |
+ a) Accompany it with the complete corresponding machine-readable |
1101 |
+ source code, which must be distributed under the terms of Sections |
1102 |
+ 1 and 2 above on a medium customarily used for software interchange; or, |
1103 |
+ |
1104 |
+ b) Accompany it with a written offer, valid for at least three |
1105 |
+ years, to give any third party, for a charge no more than your |
1106 |
+ cost of physically performing source distribution, a complete |
1107 |
+ machine-readable copy of the corresponding source code, to be |
1108 |
+ distributed under the terms of Sections 1 and 2 above on a medium |
1109 |
+ customarily used for software interchange; or, |
1110 |
+ |
1111 |
+ c) Accompany it with the information you received as to the offer |
1112 |
+ to distribute corresponding source code. (This alternative is |
1113 |
+ allowed only for noncommercial distribution and only if you |
1114 |
+ received the program in object code or executable form with such |
1115 |
+ an offer, in accord with Subsection b above.) |
1116 |
+ |
1117 |
+The source code for a work means the preferred form of the work for |
1118 |
+making modifications to it. For an executable work, complete source |
1119 |
+code means all the source code for all modules it contains, plus any |
1120 |
+associated interface definition files, plus the scripts used to |
1121 |
+control compilation and installation of the executable. However, as a |
1122 |
+special exception, the source code distributed need not include |
1123 |
+anything that is normally distributed (in either source or binary |
1124 |
+form) with the major components (compiler, kernel, and so on) of the |
1125 |
+operating system on which the executable runs, unless that component |
1126 |
+itself accompanies the executable. |
1127 |
+ |
1128 |
+If distribution of executable or object code is made by offering |
1129 |
+access to copy from a designated place, then offering equivalent |
1130 |
+access to copy the source code from the same place counts as |
1131 |
+distribution of the source code, even though third parties are not |
1132 |
+compelled to copy the source along with the object code. |
1133 |
+ |
1134 |
+ 4. You may not copy, modify, sublicense, or distribute the Program |
1135 |
+except as expressly provided under this License. Any attempt |
1136 |
+otherwise to copy, modify, sublicense or distribute the Program is |
1137 |
+void, and will automatically terminate your rights under this License. |
1138 |
+However, parties who have received copies, or rights, from you under |
1139 |
+this License will not have their licenses terminated so long as such |
1140 |
+parties remain in full compliance. |
1141 |
+ |
1142 |
+ 5. You are not required to accept this License, since you have not |
1143 |
+signed it. However, nothing else grants you permission to modify or |
1144 |
+distribute the Program or its derivative works. These actions are |
1145 |
+prohibited by law if you do not accept this License. Therefore, by |
1146 |
+modifying or distributing the Program (or any work based on the |
1147 |
+Program), you indicate your acceptance of this License to do so, and |
1148 |
+all its terms and conditions for copying, distributing or modifying |
1149 |
+the Program or works based on it. |
1150 |
+ |
1151 |
+ 6. Each time you redistribute the Program (or any work based on the |
1152 |
+Program), the recipient automatically receives a license from the |
1153 |
+original licensor to copy, distribute or modify the Program subject to |
1154 |
+these terms and conditions. You may not impose any further |
1155 |
+restrictions on the recipients' exercise of the rights granted herein. |
1156 |
+You are not responsible for enforcing compliance by third parties to |
1157 |
+this License. |
1158 |
+ |
1159 |
+ 7. If, as a consequence of a court judgment or allegation of patent |
1160 |
+infringement or for any other reason (not limited to patent issues), |
1161 |
+conditions are imposed on you (whether by court order, agreement or |
1162 |
+otherwise) that contradict the conditions of this License, they do not |
1163 |
+excuse you from the conditions of this License. If you cannot |
1164 |
+distribute so as to satisfy simultaneously your obligations under this |
1165 |
+License and any other pertinent obligations, then as a consequence you |
1166 |
+may not distribute the Program at all. For example, if a patent |
1167 |
+license would not permit royalty-free redistribution of the Program by |
1168 |
+all those who receive copies directly or indirectly through you, then |
1169 |
+the only way you could satisfy both it and this License would be to |
1170 |
+refrain entirely from distribution of the Program. |
1171 |
+ |
1172 |
+If any portion of this section is held invalid or unenforceable under |
1173 |
+any particular circumstance, the balance of the section is intended to |
1174 |
+apply and the section as a whole is intended to apply in other |
1175 |
+circumstances. |
1176 |
+ |
1177 |
+It is not the purpose of this section to induce you to infringe any |
1178 |
+patents or other property right claims or to contest validity of any |
1179 |
+such claims; this section has the sole purpose of protecting the |
1180 |
+integrity of the free software distribution system, which is |
1181 |
+implemented by public license practices. Many people have made |
1182 |
+generous contributions to the wide range of software distributed |
1183 |
+through that system in reliance on consistent application of that |
1184 |
+system; it is up to the author/donor to decide if he or she is willing |
1185 |
+to distribute software through any other system and a licensee cannot |
1186 |
+impose that choice. |
1187 |
+ |
1188 |
+This section is intended to make thoroughly clear what is believed to |
1189 |
+be a consequence of the rest of this License. |
1190 |
+ |
1191 |
+ 8. If the distribution and/or use of the Program is restricted in |
1192 |
+certain countries either by patents or by copyrighted interfaces, the |
1193 |
+original copyright holder who places the Program under this License |
1194 |
+may add an explicit geographical distribution limitation excluding |
1195 |
+those countries, so that distribution is permitted only in or among |
1196 |
+countries not thus excluded. In such case, this License incorporates |
1197 |
+the limitation as if written in the body of this License. |
1198 |
+ |
1199 |
+ 9. The Free Software Foundation may publish revised and/or new versions |
1200 |
+of the General Public License from time to time. Such new versions will |
1201 |
+be similar in spirit to the present version, but may differ in detail to |
1202 |
+address new problems or concerns. |
1203 |
+ |
1204 |
+Each version is given a distinguishing version number. If the Program |
1205 |
+specifies a version number of this License which applies to it and "any |
1206 |
+later version", you have the option of following the terms and conditions |
1207 |
+either of that version or of any later version published by the Free |
1208 |
+Software Foundation. If the Program does not specify a version number of |
1209 |
+this License, you may choose any version ever published by the Free Software |
1210 |
+Foundation. |
1211 |
+ |
1212 |
+ 10. If you wish to incorporate parts of the Program into other free |
1213 |
+programs whose distribution conditions are different, write to the author |
1214 |
+to ask for permission. For software which is copyrighted by the Free |
1215 |
+Software Foundation, write to the Free Software Foundation; we sometimes |
1216 |
+make exceptions for this. Our decision will be guided by the two goals |
1217 |
+of preserving the free status of all derivatives of our free software and |
1218 |
+of promoting the sharing and reuse of software generally. |
1219 |
+ |
1220 |
+ NO WARRANTY |
1221 |
+ |
1222 |
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
1223 |
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
1224 |
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
1225 |
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
1226 |
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
1227 |
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
1228 |
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
1229 |
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
1230 |
+REPAIR OR CORRECTION. |
1231 |
+ |
1232 |
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
1233 |
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
1234 |
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
1235 |
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
1236 |
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
1237 |
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
1238 |
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
1239 |
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
1240 |
+POSSIBILITY OF SUCH DAMAGES. |
1241 |
+ |
1242 |
+ END OF TERMS AND CONDITIONS |
1243 |
+ |
1244 |
+ How to Apply These Terms to Your New Programs |
1245 |
+ |
1246 |
+ If you develop a new program, and you want it to be of the greatest |
1247 |
+possible use to the public, the best way to achieve this is to make it |
1248 |
+free software which everyone can redistribute and change under these terms. |
1249 |
+ |
1250 |
+ To do so, attach the following notices to the program. It is safest |
1251 |
+to attach them to the start of each source file to most effectively |
1252 |
+convey the exclusion of warranty; and each file should have at least |
1253 |
+the "copyright" line and a pointer to where the full notice is found. |
1254 |
+ |
1255 |
+ <one line to give the program's name and a brief idea of what it does.> |
1256 |
+ Copyright (C) <year> <name of author> |
1257 |
+ |
1258 |
+ This program is free software; you can redistribute it and/or modify |
1259 |
+ it under the terms of the GNU General Public License as published by |
1260 |
+ the Free Software Foundation; either version 2 of the License, or |
1261 |
+ (at your option) any later version. |
1262 |
+ |
1263 |
+ This program is distributed in the hope that it will be useful, |
1264 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
1265 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1266 |
+ GNU General Public License for more details. |
1267 |
+ |
1268 |
+ You should have received a copy of the GNU General Public License along |
1269 |
+ with this program; if not, write to the Free Software Foundation, Inc., |
1270 |
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
1271 |
+ |
1272 |
+Also add information on how to contact you by electronic and paper mail. |
1273 |
+ |
1274 |
+If the program is interactive, make it output a short notice like this |
1275 |
+when it starts in an interactive mode: |
1276 |
+ |
1277 |
+ Gnomovision version 69, Copyright (C) year name of author |
1278 |
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
1279 |
+ This is free software, and you are welcome to redistribute it |
1280 |
+ under certain conditions; type `show c' for details. |
1281 |
+ |
1282 |
+The hypothetical commands `show w' and `show c' should show the appropriate |
1283 |
+parts of the General Public License. Of course, the commands you use may |
1284 |
+be called something other than `show w' and `show c'; they could even be |
1285 |
+mouse-clicks or menu items--whatever suits your program. |
1286 |
+ |
1287 |
+You should also get your employer (if you work as a programmer) or your |
1288 |
+school, if any, to sign a "copyright disclaimer" for the program, if |
1289 |
+necessary. Here is a sample; alter the names: |
1290 |
+ |
1291 |
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
1292 |
+ `Gnomovision' (which makes passes at compilers) written by James Hacker. |
1293 |
+ |
1294 |
+ <signature of Ty Coon>, 1 April 1989 |
1295 |
+ Ty Coon, President of Vice |
1296 |
+ |
1297 |
+This General Public License does not permit incorporating your program into |
1298 |
+proprietary programs. If your program is a subroutine library, you may |
1299 |
+consider it more useful to permit linking proprietary applications with the |
1300 |
+library. If this is what you want to do, use the GNU Lesser General |
1301 |
+Public License instead of this License. |
1302 |
|
1303 |
diff --git a/master.cfg b/master.cfg |
1304 |
new file mode 100644 |
1305 |
index 0000000..996f917 |
1306 |
--- /dev/null |
1307 |
+++ b/master.cfg |
1308 |
@@ -0,0 +1,80 @@ |
1309 |
+# -*- python -*- |
1310 |
+# ex: set filetype=python: |
1311 |
+from buildbot_gentoo_ci.config import schedulers, workers, builders |
1312 |
+ |
1313 |
+# This is a sample buildmaster config file. It must be installed as |
1314 |
+# 'master.cfg' in your buildmaster's base directory. |
1315 |
+ |
1316 |
+# This is the dictionary that the buildmaster pays attention to. We also use |
1317 |
+# a shorter alias to save typing. |
1318 |
+c = BuildmasterConfig = {} |
1319 |
+ |
1320 |
+####### WORKERS |
1321 |
+ |
1322 |
+# The 'workers' list defines the set of recognized workers. Each element is |
1323 |
+# a Worker object, specifying a unique worker name and password. The same |
1324 |
+# worker name and password must be configured on the worker. |
1325 |
+c['workers'] = workers.gentoo_workers() |
1326 |
+ |
1327 |
+# 'protocols' contains information about protocols which master will use for |
1328 |
+# communicating with workers. You must define at least 'port' option that workers |
1329 |
+# could connect to your master with this protocol. |
1330 |
+# 'port' must match the value configured into the workers (with their |
1331 |
+# --master option) |
1332 |
+c['protocols'] = {'pb': {'port': 9989}} |
1333 |
+ |
1334 |
+####### CHANGESOURCES |
1335 |
+ |
1336 |
+# the 'change_source' setting tells the buildmaster how it should find out |
1337 |
+# about source code changes. Here we point to the buildbot version of a python hello-world project. |
1338 |
+ |
1339 |
+# c['change_source'] = [] |
1340 |
+ |
1341 |
+####### SCHEDULERS |
1342 |
+ |
1343 |
+# Configure the Schedulers, which decide how to react to incoming changes. In this |
1344 |
+# case, just kick off a 'runtests' build |
1345 |
+ |
1346 |
+c['schedulers'] = schedulers.gentoo_schedulers() |
1347 |
+ |
1348 |
+####### BUILDERS |
1349 |
+ |
1350 |
+# The 'builders' list defines the Builders, which tell Buildbot how to perform a build: |
1351 |
+# what steps, and which workers can execute them. Note that any particular build will |
1352 |
+# only take place on one worker. |
1353 |
+ |
1354 |
+c['builders'] = builders.gentoo_builders() |
1355 |
+ |
1356 |
+####### BUILDBOT SERVICES |
1357 |
+ |
1358 |
+# 'services' is a list of BuildbotService items like reporter targets. The |
1359 |
+# status of each build will be pushed to these targets. buildbot/reporters/*.py |
1360 |
+# has a variety to choose from, like IRC bots. |
1361 |
+ |
1362 |
+#c['services'] = [] |
1363 |
+ |
1364 |
+####### PROJECT IDENTITY |
1365 |
+ |
1366 |
+# the 'title' string will appear at the top of this buildbot installation's |
1367 |
+# home pages (linked to the 'titleURL'). |
1368 |
+ |
1369 |
+c['title'] = "Gentoo CI" |
1370 |
+c['titleURL'] = "https://gentoo-ci.gentoo.org" |
1371 |
+ |
1372 |
+# the 'buildbotURL' string should point to the location where the buildbot's |
1373 |
+# internal web server is visible. This typically uses the port number set in |
1374 |
+# the 'www' entry below, but with an externally-visible host name which the |
1375 |
+# buildbot cannot figure out without some help. |
1376 |
+ |
1377 |
+c['buildbotURL'] = "http://localhost:8010/" |
1378 |
+ |
1379 |
+# minimalistic config to activate new web UI |
1380 |
+c['www'] = dict(port=8010, |
1381 |
+ plugins=dict(waterfall_view={}, console_view={}, grid_view={})) |
1382 |
+ |
1383 |
+####### DB URL |
1384 |
+# This specifies what database buildbot uses to store its state. |
1385 |
+# It's easy to start with sqlite, but it's recommended to switch to a dedicated |
1386 |
+# database, such as PostgreSQL or MySQL, for use in production environments. |
1387 |
+# http://docs.buildbot.net/current/manual/configuration/global.html#database-specification |
1388 |
+c['db_url'] = "mysql://buildbot:xxx@192.168.1.x/buildbot?max_idle=300" |