opendevstack / ods-core

The core of OpenDevStack - infrastructure setup based on Atlassian tools, Jenkins, Nexus, SonarQube and shared images
Apache License 2.0
47 stars 34 forks source link

Webhook Proxy #38

Closed michaelsauter closed 5 years ago

michaelsauter commented 5 years ago

Currently, every component creates two Jenkins pipelines, dev and test, as OCP resources. In addition, every repo has two webhooks (actually four, but two of them are pointless), which trigger both pipelines for every commit. Inside the pipeline, Jenkins checks whether the pipeline is responsible for the commit (test=master,dev=*) and then continues.

This has several drawbacks:

To improve this situation, we have build a "webhook proxy" internally. This proxy provides one endpoint accepting webhooks from BitBucket and forwards them to the corresponding Jenkins pipeline (which is determined based on the branch name). If there is no corresponding pipeline yet, it will be created on the fly. Once a branch is deleted or a pull request declined/merged, the corresponding Jenkins pipeline is deleted automatically. The webhook proxy is a Go application - a single, no-dependency binary, produced from one file using just the standard library.

This works very reliable so far (tested in two initiatives for about a month) and solves all the pain points mentioned above.

To include it in OpenDevStack, the following has to be changed:

FYI @tjaeschke @rattermeyer @clemensutschig @stitakis @gerardcl

rattermeyer commented 5 years ago

Actually, I like the idea of the webhook proxy. I would also vote for deploying the proxy into the foo-cd project, rather than the general cd project. Would it also be an option to use a s2i build in this case?

michaelsauter commented 5 years ago

Cool, thanks for feedback. I can look into whether s2i is an option. Also I have to check if the new OCP version allows multi-stage builds, which would also be handy in this case.

In addition to my proposal above, I realised that the webhook proxy could allow users to use a monorepo without loosing the capability to do individual pipelines/deployments. The basic idea would be to add a query param to the end of the webhook proxy url, e.g. ?dirs=frontend,backend and then the proxy would create/manage one pipeline per specified directory, pointing to the Jenkinsfile in them ... but yea, that would be something for later :)

michaelsauter commented 5 years ago

So s2i might be an option. However, the "official" golang s2i does not support Golang 1.11 on RHEL yet. So I opted for the simplest option, which is to just build the binary in the Docker image (which is now based on golang:1.11-alpineinsteas of alpine).

I'm now at a stage where the proxy image can be built in the cd namespace. In addition, we have a project-specific proxy running that is built that way and it works well. The next steps are:

  1. ods-project-quickstarters: Add DC,SVC,Route definitions in the cd-jenkins-persistent.yml template.
  2. ods-provisioning-app: Change the created webhooks to point to the proxy. Right now we create 4 webhooks in total. 2 for CI, and 2 for RShiny. I have no idea why we need the latter ones. Anyone ideas?
  3. ods-project-quickstarters: Remove the pipelines (dev, test) from the component template (as pipelines are auto-created now).
  4. ods-jenkins-shared-library: Remove the (buggy) code that tries to checkout the correct Git commit.

All in all, not too much work left :)

michaelsauter commented 5 years ago

Done!