File: master-worker.rst

package info (click to toggle)
buildbot 4.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 21,080 kB
  • sloc: python: 174,183; sh: 1,204; makefile: 332; javascript: 119; xml: 16
file content (532 lines) | stat: -rw-r--r-- 16,604 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
Master-Worker API
=================

This section describes the master-worker interface.
It covers the communication protocol of the "classic" remote Worker.
Notice there are other types of workers which behave a bit differently, such as :ref:`Local Worker <Local-Workers>` and :ref:`Latent Worker <Latent-Workers>`.

Connection
----------

The interface is based on Twisted's Perspective Broker, which operates over TCP connections.

The worker connects to the master, using the parameters supplied to :command:`buildbot-worker create-worker`.
It uses a reconnecting process with an exponential backoff, and will automatically reconnect on disconnection.

Once connected, the worker authenticates with the Twisted Cred (newcred) mechanism, using the username and password supplied to :command:`buildbot-worker create-worker`.
The *mind* behind the worker is the worker bot instance (class :class:`buildbot_worker.pb.BotPb`).

On the master side, the realm is implemented by :class:`buildbot.pbmanager.Dispatcher`, which examines the username of incoming avatar requests.
There are special cases for ``change`` and ``debug``, which are not discussed here.
For all other usernames, the botmaster is consulted, and if a worker with that name is configured, its :class:`buildbot.worker.Worker` instance is returned as the perspective.

Workers
-------

At this point, the master-side Worker object has a pointer to the remote
worker-side Bot object in its ``self.worker``, and the worker-side Bot object has
a reference to the master-side Worker object in its ``self.perspective``.

Bot methods
~~~~~~~~~~~

The worker-side Bot object has the following remote methods:

:meth:`~buildbot_worker.pb.BotPb.remote_getCommands`
    Returns a dictionary for all commands the worker recognizes: the key of the dictionary is the command name and the command version is the value.

:meth:`~buildbot_worker.pb.BotPb.remote_setBuilderList`
    Given a list of builders and their build directories, ensures that
    those builders, and only those builders, are running.  This can be
    called after the initial connection is established, with a new
    list, to add or remove builders.

    This method returns a dictionary of :class:`WorkerForBuilder` objects - see below.

:meth:`~buildbot_worker.pb.BotPb.remote_print`
    Adds a message to the worker logfile.

:meth:`~buildbot_worker.pb.BotPb.remote_getWorkerInfo`
    Returns a dictionary with the contents of the worker's :file:`info/` directory (i.e. file name is used as key and file contents as the value).
    This dictionary also contains the following keys:

    ``environ``

        copy of the workers environment

    ``system``

        OS the worker is running (extracted from Python's ``os.name``)

    ``basedir``

        base directory where the worker is running

    ``numcpus``

        number of CPUs on the worker, either as configured or as detected (since ``buildbot-worker`` version 0.9.0)

    ``version``

        worker's version (same as the result of :meth:`~buildbot_worker.pb.BotPb.remote_getVersion` call)

    ``worker_commands``

        worker supported commands (same as the result of :meth:`~buildbot_worker.pb.BotPb.remote_getCommands` call)

:meth:`~buildbot_worker.pb.BotPb.remote_getVersion`
    Returns the worker's version.

:meth:`~buildbot_worker.pb.BotPb.remote_shutdown`
    Shuts down the worker cleanly.

Worker methods
~~~~~~~~~~~~~~

The master-side object has the following method:

:meth:`~buildbot.protocols.pb.Connection.perspective_keepalive`
    Does nothing - used to keep traffic flowing over the TCP connection

Setup
-----

After the initial connection and trading of a mind (:class:`buildbot_worker.pb.BotPb`) for an avatar
(Worker), the master calls the Bot's :meth:`setBuilderList` method to set
up the proper builders on the worker side.  This method returns a
reference to each of the new worker-side :class:`~buildbot_worker.pb.WorkerForBuilderPb`
objects, described below.  Each of these is handed to the corresponding
master-side :class:`~buildbot.process.workerforbuilder.WorkerForBuilder` object.

This immediately calls the remote :meth:`setMaster` method, and then the :meth:`print` method.

Pinging
-------

To ping a remote Worker, the master calls its :meth:`print` method.

Building
--------

When a build starts, the master calls the worker's :meth:`startBuild` method.
Each BuildStep instance will subsequently call the :meth:`startCommand` method,
passing a reference to itself as the ``stepRef`` parameter.  The
:meth:`startCommand` method returns immediately, and the end of the command is
signalled with a call to a method on the master-side BuildStep object.

.. _worker-for-builders:

Worker For Builders
-------------------

Each worker has a set of builders which can run on it.  These are
represented by distinct classes on the master and worker, just like the
Worker and Bot objects described above.

On the worker side, builders are represented as instances of the
:class:`buildbot_worker.pb.WorkerForBuilderPb` class.  On the master side, they are
represented by the :class:`buildbot.process.workerforbuilder.WorkerForBuilder` class.
The identical names are a source of confusion.  The following will refer to
these as the worker-side and master-side Worker For Builder classes.  Each object
keeps a reference to its opposite in ``self.remote``.

Worker-Side :class:`~buildbot_worker.pb.WorkerForBuilderPb` Methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:meth:`~buildbot_worker.pb.WorkerForBuilderPb.remote_setMaster`
    Provides a reference to the master-side Worker For Builder

:meth:`~buildbot_worker.pb.WorkerForBuilderPb.remote_print`
    Adds a message to the worker logfile; used to check round-trip connectivity

:meth:`~buildbot_worker.pb.WorkerForBuilderPb.remote_startBuild`
    Indicates that a build is about to start, and that any subsequent
    commands are part of that build

:meth:`~buildbot_worker.pb.WorkerForBuilderPb.remote_startCommand`
    Invokes a command on the worker side

:meth:`~buildbot_worker.pb.WorkerForBuilderPb.remote_interruptCommand`
    Interrupts the currently-running command

Master-side :class:`~buildbot.process.workerforbuilder.WorkerForBuilder` Methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The master side does not have any remotely-callable methods.

Commands
--------

The actual work done by the worker is represented on the master side by a
:class:`buildbot.process.remotecommand.RemoteCommand` instance.

The command instance keeps a reference to the worker-side
:class:`buildbot_worker.pb.WorkerForBuilderPb`, and calls methods like
:meth:`~buildbot_worker.pb.WorkerForBuilderPb.remote_startCommand` to start new commands.
Once that method is called, the :class:`~buildbot_worker.pb.WorkerForBuilderPb` instance
keeps a reference to the command, and calls the following methods on it:

Master-Side RemoteCommand Methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:meth:`~buildbot.process.remotecommand.RemoteCommand.remote_update`
    Update information about the running command.  See below for the format.

:meth:`~buildbot.process.remotecommand.RemoteCommand.remote_complete`
    Signal that the command is complete, either successfully or with a Twisted failure.

.. _master-worker-updates:

Updates
-------

Updates from the worker, sent via
:meth:`~buildbot.process.remotecommand.RemoteCommand.remote_update`, are a list of
individual update elements.  Each update element is, in turn, a list of the
form ``[data, 0]``, where the 0 is present for historical reasons.  The data is
a dictionary, with keys describing the contents.  The updates are handled by
:meth:`~buildbot.process.remotecommand.RemoteCommand.remote_update`.

Updates with different keys can be combined into a single dictionary or
delivered sequentially as list elements, at the worker's option.

To summarize, an ``updates`` parameter to
:meth:`~buildbot.process.remotecommand.RemoteCommand.remote_update` might look like
this::

    [
        [ { 'header' : 'running command..' }, 0 ],
        [ { 'stdout' : 'abcd', 'stderr' : 'local modifications' }, 0 ],
        [ { 'log' : ( 'cmd.log', 'cmd invoked at 12:33 pm\n' ) }, 0 ],
        [ { 'rc' : 0 }, 0 ],
    ]

Defined Commands
~~~~~~~~~~~~~~~~

The following commands are defined on the workers.

.. _shell-command-args:

shell
.....

Runs a shell command on the worker.  This command takes the following arguments:

``command``

    The command to run.  If this is a string, it will be passed to the system
    shell as a string.  Otherwise, it must be a list, which will be
    executed directly.

``workdir``

    The directory in which to run the command, relative to the builder dir.

``env``

    A dictionary of environment variables to augment or replace the
    existing environment on the worker.  In this dictionary, ``PYTHONPATH``
    is treated specially: it should be a list of path components, rather
    than a string, and will be prepended to the existing Python path.

``initial_stdin``

    A string which will be written to the command's standard input before
    it is closed.

``want_stdout``

    If false, then no updates will be sent for stdout.

``want_stderr``

    If false, then no updates will be sent for stderr.

``usePTY``

    If true, the command should be run with a PTY (POSIX only).  This
    defaults to False.

``not_really``

    If true, skip execution and return an update with rc=0.

``timeout``

    Maximum time without output before the command is killed.

``maxTime``

    Maximum overall time from the start before the command is killed.

``max_lines``

    Maximum overall produced lines by the command, then it is killed.

``logfiles``

    A dictionary specifying logfiles other than stdio.  Keys are the logfile
    names, and values give the workdir-relative filename of the logfile.  Alternately,
    a value can be a dictionary; in this case, the dictionary must have a ``filename``
    key specifying the filename, and can also have the following keys:

    ``follow``

        Only follow the file from its current end-of-file, rather that starting
        from the beginning.

``logEnviron``

    If false, the command's environment will not be logged.

The ``shell`` command sends the following updates:

``stdout``

    The data is a bytestring which represents a continuation of the stdout
    stream.  Note that the bytestring boundaries are not necessarily aligned
    with newlines.

``stderr``

    Similar to ``stdout``, but for the error stream.

``header``

    Similar to ``stdout``, but containing data for a stream of
    Buildbot-specific metadata.

``rc``

    The exit status of the command, where -- in keeping with UNIX tradition --
    0 indicates success and any nonzero value is considered a failure.  No
    further updates should be sent after an ``rc``.

``failure_reason``

    Value is a string and describes additional scenarios when a process failed.
    The value of the ``failure_reason`` key can be one of the following:

     - ``timeout`` if the command timed out due to time specified by the ``maxTime`` parameter being exceeded.
     - ``timeout_without_output`` if the command timed out due to time specified by the ``timeout`` parameter being exceeded.
     - ``max_lines_failure`` if the command is killed due to the number of lines specified by the ``max_lines`` parameter being exceeded.

``log``

    This update contains data for a logfile other than stdio.  The data
    associated with the update is a tuple of the log name and the data for that
    log.  Note that non-stdio logs do not distinguish output, error, and header
    streams.

uploadFile
..........

Upload a file from the worker to the master.  The arguments are

``workdir``

    Base directory for the filename, relative to the builder's basedir.

``workersrc``

    Name of the filename to read from, relative to the workdir.

``writer``

    A remote reference to a writer object, described below.

``maxsize``

    Maximum size, in bytes, of the file to write.  The operation will fail if
    the file exceeds this size.

``blocksize``

    The block size with which to transfer the file.

``keepstamp``

    If true, preserve the file modified and accessed times.

The worker calls a few remote methods on the writer object.  First, the
``write`` method is called with a bytestring containing data, until all of the
data has been transmitted.  Then, the worker calls the writer's ``close``,
followed (if ``keepstamp`` is true) by a call to ``upload(atime, mtime)``.

This command sends ``rc`` and ``stderr`` updates, as defined for the ``shell``
command.

uploadDirectory
...............

Similar to ``uploadFile``, this command will upload an entire directory to the
master, in the form of a tarball.  It takes the following arguments:

``workdir``
``workersrc``
``writer``
``maxsize``
``blocksize``

    See ``uploadFile`` for these arguments.

``compress``

    Compression algorithm to use -- one of ``None``, ``'bz2'``, or ``'gz'``.

The writer object is treated similarly to the ``uploadFile`` command, but after
the file is closed, the worker calls the master's ``unpack`` method with no
arguments to extract the tarball.

This command sends ``rc`` and ``stderr`` updates, as defined for the ``shell``
command.

downloadFile
............

This command will download a file from the master to the worker.  It takes the
following arguments:

``workdir``

    Base directory for the destination filename, relative to the builder basedir.

``workerdest``

    Filename to write to, relative to the workdir.

``reader``

    A remote reference to a reader object, described below.

``maxsize``

    Maximum size of the file.

``blocksize``

    The block size with which to transfer the file.

``mode``

    Access mode for the new file.

The reader object's ``read(maxsize)`` method will be called with a maximum
size, which will return no more than that number of bytes as a bytestring.  At
EOF, it will return an empty string.  Once EOF is received, the worker will call
the remote ``close`` method.

This command sends ``rc`` and ``stderr`` updates, as defined for the ``shell``
command.

mkdir
.....

This command will create a directory on the worker.  It will also create any
intervening directories required.  It takes the following argument:

``dir``

    Directory to create.

The ``mkdir`` command produces the same updates as ``shell``.

rmdir
.....

This command will remove a directory or file on the worker.  It takes the following arguments:

``dir``

    Directory to remove.

``timeout``
``maxTime``

    See ``shell`` above.

The ``rmdir`` command produces the same updates as ``shell``.

cpdir
.....

This command will copy a directory from one place to another place on the worker.  It takes the following
arguments:

``fromdir``

    Source directory for the copy operation, relative to the builder's basedir.

``todir``

    Destination directory for the copy operation, relative to the builder's basedir.

``timeout``
``maxTime``

    See ``shell`` above.

The ``cpdir`` command produces the same updates as ``shell``.

stat
....

This command returns status information about a file or directory.  It takes a
single parameter, ``file``, specifying the filename relative to the builder's
basedir.

It produces two status updates:

``stat``

    The return value from Python's ``os.stat``.

``rc``

    0 if the file is found, otherwise 1.

glob
....

This command finds all pathnames matching a specified pattern that uses shell-style wildcards.
It takes a single parameter, ``path``, specifying the pattern to pass to Python's
``glob.glob`` function.

It produces two status updates:

``files``

    The list of matching files returned from ``glob.glob``

``rc``

    0 if the ``glob.glob`` does not raise exception, otherwise 1.

listdir
.......

This command reads the directory and returns the list with directory contents. It
takes a single parameter, ``dir``, specifying the directory relative to the builder's basedir.

It produces two status updates:

``files``

    The list of files in the directory returned from ``os.listdir``

``rc``

    0 if the ``os.listdir`` does not raise exception, otherwise 1.

rmfile
......

This command removes the file in the worker base directory.
It takes a single parameter, ``path``, specifying the file path relative to the builder's basedir.

It produces one status update:

``rc``

    0 if the ``os.remove`` does not raise exception, otherwise the corresponding errno.