buildbot

No grid/console views in buildbot, build view always empty, despite successful build


I have installed buildbot -- one docker image with a master, and another with a worker. Inter-container networking is allowed, and they share the same network; I have also a gitea instance, and installed the buildbot_gitea plugin.

So far I got a small project to run make on the worker after a push, and buildbot correctly reports success back to gitea (I can tell form the logs, and gitea also shows the green check image on the repo).

However,

The only things that look strange on the master logs are periodic timeout messages, some connection drop messages:

2020-03-21 12:11:26+0000 [-] Timing out client: IPv4Address(type='TCP', host='172.27.0.1', port=56388)
2020-03-21 12:11:26+0000 [-] Timing out client: IPv4Address(type='TCP', host='172.27.0.1', port=56380)
2020-03-21 12:11:26+0000 [-] Timing out client: IPv4Address(type='TCP', host='172.27.0.1', port=56392)

2020-03-21 12:19:40+0000 [-] dropping connection to peer tcp4:172.27.0.1:56598 with abort=False: None

and this:

2020-03-21 12:10:49+0000 [-] Unhandled error in Deferred:
2020-03-21 12:10:49+0000 [-] Unhandled Error
    Traceback (most recent call last):
      File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
        self.run()
      File "/usr/lib/python3.8/threading.py", line 870, in run
        self._target(*self._args, **self._kwargs)
      File "/bbot/sandbox/lib/python3.8/site-packages/twisted/_threads/_threadworker.py", line 46, in work
        task()
      File "/bbot/sandbox/lib/python3.8/site-packages/twisted/_threads/_team.py", line 190, in doWork
        task()
    --- <exception caught here> ---
      File "/bbot/sandbox/lib/python3.8/site-packages/twisted/python/threadpool.py", line 250, in inContext
        result = inContext.theWork()
      File "/bbot/sandbox/lib/python3.8/site-packages/twisted/python/threadpool.py", line 266, in <lambda>
        inContext.theWork = lambda: context.call(ctx, func, *args, **kw)
      File "/bbot/sandbox/lib/python3.8/site-packages/twisted/python/context.py", line 122, in callWithContext
        return self.currentContext().callWithContext(ctx, func, *args, **kw)
      File "/bbot/sandbox/lib/python3.8/site-packages/twisted/python/context.py", line 85, in callWithContext
        return func(*args,**kw)
      File "/bbot/sandbox/lib/python3.8/site-packages/buildbot/buildbot_net_usage_data.py", line 204, in _sendBuildbotNetUsageData
        res = _sendWithRequests(PHONE_HOME_URL, data)
      File "/bbot/sandbox/lib/python3.8/site-packages/buildbot/buildbot_net_usage_data.py", line 197, in _sendWithRequests
        r = requests.post(url, json=data)
      File "/bbot/sandbox/lib/python3.8/site-packages/requests/api.py", line 119, in post
        return request('post', url, data=data, json=json, **kwargs)
      File "/bbot/sandbox/lib/python3.8/site-packages/requests/api.py", line 61, in request
        return session.request(method=method, url=url, **kwargs)
      File "/bbot/sandbox/lib/python3.8/site-packages/requests/sessions.py", line 530, in request
        resp = self.send(prep, **send_kwargs)
      File "/bbot/sandbox/lib/python3.8/site-packages/requests/sessions.py", line 643, in send
        r = adapter.send(request, **kwargs)
      File "/bbot/sandbox/lib/python3.8/site-packages/requests/adapters.py", line 516, in send
        raise ConnectionError(e, request=request)
    requests.exceptions.ConnectionError: HTTPSConnectionPool(host='events.buildbot.net', port=443): Max retries exceeded with url: /events/phone_home (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7ff7297704f0>: Failed to establish a new connection: [Errno 110] Operation timed out'))

which seems to happen only once (why is buildbot trying to phone home anyway? there is no mention of events.buildbot.net in any of my config files.

The docker containers have full network access, ipv6, routing and DNS are all fine (tested with the buildbot-master image).

This is my master.cfg:

import os

from twisted.application import service
from buildbot.master import BuildMaster

from buildbot.plugins import *
from buildbot_gitea.auth import GiteaAuth
from buildbot_gitea import *

basedir = '/bbot/bbot-master'
rotateLength = 10000000
maxRotatedFiles = 10
configfile = 'master.cfg'

umask = None

if basedir == '.':
    basedir = os.path.abspath(os.path.dirname(__file__))
application = service.Application('buildmaster')
from twisted.python.logfile import LogFile
from twisted.python.log import ILogObserver, FileLogObserver
logfile = LogFile.fromFullPath(os.path.join(basedir, "twistd.log"), rotateLength=rotateLength,
                                maxRotatedFiles=maxRotatedFiles)
application.setComponent(ILogObserver, FileLogObserver(logfile).emit)

m = BuildMaster(basedir, configfile, umask)
m.setServiceParent(application)
m.log_rotation.rotateLength = rotateLength
m.log_rotation.maxRotatedFiles = maxRotatedFiles# -*- python -*-                                                                                                                                                                                                                                                       
# ex: set filetype=python:                                                                                                                                                                                                                                                                                             

from buildbot.plugins import *


c = BuildmasterConfig = {}
####### WORKERS                                                                                                                                                                                                                                                                                                        

c['workers'] = [worker.Worker("bbot-worker", "BUILDBOT_PASSWORD")]

c['protocols'] = {'pb': {'port': 9989}}

####### CHANGESOURCES                                                                                                                                                                                                                                                                                                  

c['change_source'] = []
c['change_source'].append(changes.PBChangeSource())

####### SCHEDULERS                                                                                                                                                                                                                                                                                                     

c['schedulers'] = []


c['schedulers'].append(schedulers.SingleBranchScheduler(
                            name="all",
                            change_filter=util.ChangeFilter(branch='master'),
                            treeStableTimer=None,
                            builderNames=["runtests"]))
c['schedulers'].append(schedulers.ForceScheduler(
                            name="force",
                            builderNames=["runtests"]))

####### BUILDERS                                                                                                                                                                                                                                                                                                       

factory = util.BuildFactory()
factory.addStep(steps.Gitea(repourl='gitea@gitea.mydomain:myself/repo.git',
    mode='incremental',
        workdir="build",
        branch="master",
        progress=True,
        logEnviron=False,
))

factory.addStep(steps.ShellCommand(command=["make"]))

c['builders'] = []

c['builders'].append(
    util.BuilderConfig(name="runtests",
      workernames=["bbot-worker"],
      factory=factory))

####### BUILDBOT SERVICES                                                                                                                                                                                                                                                                                              

c['services'] = [
    reporters.GiteaStatusPush(
    baseURL="https://gitea.mydomain/",
        token="GITEA_API_ACCESS_TOKEN",
        verbose=True)
]


####### PROJECT IDENTITY                                                                                                                                                                                                                                                                                               

c['title'] = "My Domain!"
c['titleURL'] = "https://buildbot.mydomain"


c['buildbotURL'] = "https://buildbot.mydomain/"

c['www'] = dict(port=8010,
                plugins=dict(waterfall_view={}, console_view={}, grid_view={}))

c['www']['authz'] = util.Authz(
        allowRules = [
            util.AnyEndpointMatcher(role="admins")
        ],
        roleMatchers = [
            util.RolesFromUsername(roles=['admins'], usernames=['myself'])
        ]
)

c['www']['auth'] = GiteaAuth(
    endpoint="https://gitea.mydomain/",
    client_id="MY_CLIENT_ID_FROM_GITEA",
    client_secret='MY_CLIENT_SECRET_FROM_GITEA')

c['www']['change_hook_dialects'] = {
                                  'gitea': {
                                  'secret': 'THE_GITEA_WEBHOOK_SECRET',
                                  'onlyIncludePushCommit': True
                                  }
}

####### DB URL                                                                                                                                                                                                                                                                                                         

c['db'] = {
    'db_url' : "postgresql://buildbot:MY_SECRET_DB_PASSWORD@172.25.0.2/buildbot",
}

The Dockerfile for the master is

FROM alpine:3.11.3
EXPOSE 9989

RUN apk update
RUN apk add python3 bash    busybox-extras w3m gcc python3-dev libffi-dev openssl-dev musl-dev postgresql-dev
RUN mkdir /bbot
COPY entrypoint.sh /root/
RUN chmod a+x /root/entrypoint.sh
RUN mkdir /root/.ssh && chmod og-rwx /root/.ssh/
COPY bbot-gitea bbot-gitea.pub /root/.ssh/
RUN chmod og-w /root/.ssh/bbot-gitea*


RUN cd /bbot && \
    python3 -m venv sandbox && \
    source sandbox/bin/activate && \
    pip3 install 'buildbot[bundle]' && \
    pip3 install 'requests[security]' && \
    pip3 -v install buildbot_gitea && \
    pip3 install treq && \
    pip3 install psycopg2
RUN apk del gcc python3-dev libffi-dev openssl-dev musl-dev

RUN ls -la /root
RUN cat /root/entrypoint.sh

ENTRYPOINT [ "/root/entrypoint.sh" ]

and the entrypoint does nothing special -- it is this,

#!/bin/bash                                                                                                                                                                                                                                                                                                            

cd /bbot

echo " BBOT MASTER ENTRYPOINT"

source sandbox/bin/activate
buildbot upgrade-master bbot-master

# debug: check everything that was pip-installed:
echo "\n\n=====\n"
pip3 list
echo "=====\n\n"

if [ ! -f bbot-master/buildbot.tac ]; then
        buildbot create-master bbot-master
fi

buildbot start bbot-master
tail -f /bbot/bbot-master/twistd.log

and the pip3 list line, which runs on startup for debugging, shows that I have

buildbot                2.7.0     
buildbot-console-view   2.7.0     
buildbot-gitea          1.2.0     
buildbot-grid-view      2.7.0     
buildbot-waterfall-view 2.7.0     
buildbot-worker         2.7.0     
buildbot-www            2.7.0     

edit: checked the JS console in Firefox, and there seems to be a problem connecting to the server via websockets:

Firefox can’t establish a connection to the server at wss://buildbot.mydomain/ws.

From Chrome, this is what I see:

WebSocket connection to 'wss://buildbot.aleph0.info/ws' failed: Error during WebSocket handshake: Unexpected response code: 200

(200? why 200?)

I can't see why it wouldn't work. Apache is configured to do reverse proxying, like this:

RewriteEngine On
RewriteCond ${HTTP:Upgrade} websocket [NC]
RewriteCond ${HTTP:Connection} upgrade [NC]
RewriteRule .* "wss:/localhost:8010/$1" [P,L]
ProxyPass        / http://localhost:8010/
ProxyPassReverse / http://localhost:8010/

So... What else can I do to continue debugging this?

(By the way, it does look like the buildbot mailing list is not very active -- after posting this question there I checked the archives, and there is svery low activity. Where do users of Buildbot go these days in order to get and share advice?)


Solution

  • I found the problem!

    It was the reverse proxy that wasn't properly configured for websockets.

    I used this in my apache virtualhost config,

        <Location /ws>
                  ProxyPass ws://127.0.0.1:8010/ws
                  ProxyPassReverse ws://127.0.0.1:8010/ws
        </Location>
    
        ProxyPass /ws !
        ProxyPass        / http://localhost:8010/
        ProxyPassReverse / http://localhost:8010/
    

    and it works now!

    ( after searching a lot, I found the solution here: https://docs.buildbot.net/0.9.2/manual/cfg-www.html )

    There it is, in case anyone else needs it.