Skip to content

Commit

Permalink
Refreshing documentation.
Browse files Browse the repository at this point in the history
addressing comments for lines #3, #11, and #30.

removed references to pluginclient

other updates
  • Loading branch information
gnarled-cipher committed Aug 22, 2019
1 parent 9e713be commit 6d9c907
Showing 1 changed file with 25 additions and 12 deletions.
37 changes: 25 additions & 12 deletions prow/life_of_a_prow_job.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,36 @@
# Life of a Prow Job

I comment `/test all` on a PR. GitHub creates a JSON object representing that action and sends a webhook to prow. [Here](https://github.com/kubernetes/test-infra/tree/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/cmd/phony/examples) are some examples of webhook payloads.
I comment `/test all` on a Pull Request (PR). In response, GitHub posts my comment to Prow, via [a webhook](https://developer.github.com/webhooks/). See examples for webhook payloads [here](https://github.com/kubernetes/test-infra/tree/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/cmd/phony/examples).

The webhook finds its way into the cluster with the help of an [Ingress](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/cluster/ingress.yaml) object. This object has a rule stating that `/hook` goes to the [hook service](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/cluster/hook_service.yaml) which is backed by the [hook deployment](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/cluster/hook_deployment.yaml) and finally into the [hook program](https://github.com/kubernetes/test-infra/tree/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/cmd/hook) itself. The hook program deserializes the payload into the appropriate go struct, and then passes it along to each plugin.
Prow's Kubernetes cluster uses an [ingress resource](https://kubernetes.io/docs/concepts/services-networking/ingress/) for terminating TLS, and routing traffic to the hook [service resource](https://kubernetes.io/docs/concepts/services-networking/service/). [This document](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/cluster/ingress.yaml) describes the configuration for the ingress resource. The ingress resource sends traffic to the "hook" service. [This document](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/cluster/hook_service.yaml) describes the configuration for the "hook" service.

To each plugin, hook passes two objects: a [plugin client](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/plugins/plugins.go#L64-L70) and the deserialized GitHub event. In this case, the event is an [IssueCommentEvent](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/github/types.go#L116-L121). The plugin client has a Kubernetes client, a GitHub client, and the prow config:
The "hook" service routes traffic to the "hook" application. [This deployment resource](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/cluster/hook_deployment.yaml) defines the pods that "hook" is comprised of.

The pods for "hook" run [the "Hook" executable](https://github.com/kubernetes/test-infra/blob/42d4af367a2312d8facbb92f9669f7356d8b13f4/prow/cmd/hook/main.go#L95). "hook" listens for incoming http requests and translates them to "GitHub event objects". Afterwards, "hook" broadcasts these events to Prow Plugins. In the case of my `/test all` comment, "hook" builds an ["Issue Comment Event"](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/github/types.go#L116-L121).

Prow plugins receive 2 objects: 1) a GitHub event object, and 2) a ["client agent object"](https://github.com/kubernetes/test-infra/blob/42d4af367a2312d8facbb92f9669f7356d8b13f4/prow/plugins/plugins.go#L199). The Client agent object contains 7 clients: Github, Prow jobs, Kubernetes, Git, Slack, Owners, and Bugzilla. These 7 clients are initialized by "hook", during start-up. This is what "client agent objects" look like:

```go
type PluginClient struct {
GitHubClient github.Client
KubeClient *kube.Client
Config *config.Config
Logger *logrus.Entry
type ClientAgent struct {
GitHubClient github.Client
ProwJobClient prowv1.ProwJobInterface
KubernetesClient kubernetes.Interface
GitClient *git.Client
SlackClient *slack.Client
OwnersClient *repoowners.Client
BugzillaClient bugzilla.Client
}
```

The [trigger](https://github.com/kubernetes/test-infra/tree/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/plugins/trigger) plugin has a function called [`handleIC`](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/plugins/trigger/ic.go#L31) that it [registered at init-time](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/plugins/trigger/trigger.go#L35). This function checks the issue comment for any test requests by comparing the issue comment body to the list of jobs supplied in the `Config` object in the `PluginClient`. I requested that some tests run, so the trigger plugin talks to the Kubernetes API server and creates a [ProwJob Custom Resource](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/kube/prowjob.go#L50-L83) with the information from the issue comment. At this point, `cmd/hook`'s role is done. It goes on and handles the next webhooks.
"hook" [multiplexes events](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/cmd/hook/server.go#L40) by looking at "X-GitHub-Event", a custom http header. Afterwards, a [PluginAgent object](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/plugins/plugins.go#L86), initialized [during Hook's startup](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/cmd/hook/main.go#L128), selects plugins to handle events. See [events.go](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/cmd/hook/events.go#L17) for more details, and check [plugins.yaml](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/plugins.yaml) for a list of plugins per repo.

"hook" delivers an event that represents my `/test all` comment to the [Trigger plugin](https://github.com/kubernetes/test-infra/tree/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/plugins/trigger). The Trigger plugin validates the PR before running tests. One such validation is, for instance, that the author is a member of the organization or that the PR is labeled `ok-to-test`. The function called [`handleGenericCommentEvent` (implementec by `handleGenericComment`)](https://github.com/kubernetes/test-infra/blob/99b91b56b097e39d70cb1ae82c0b1cb57d98ac48/prow/plugins/trigger/generic-comment.go#L32) describes Trigger's logic.

Finally, `handleGenericComment` determines *presubmit* jobs to run. The list of jobs supplied by the `Config` object, in the `PluginClient` object, will be used to find suitable jobs.

Next, the trigger plugin talks to the Kubernetes API server and creates a [ProwJob Custom Resource](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/kube/prowjob.go#L50-L83) with the information from the issue comment.

The ProwJob that it creates looks a little like this, although I elided some of the pod details:
Pod details aside, the resulting Prow job looks like this:

```yaml
apiVersion: prow.k8s.io/v1
Expand Down Expand Up @@ -45,8 +58,8 @@ status:
state: triggered
```
Every thirty seconds, `cmd/plank` runs a [`Sync`](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/plank/controller.go#L71) function that lists ProwJobs and Kubernetes pods in the cluster. For each ProwJob, it runs [`syncKubernetesJob`](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/plank/controller.go#L233-L296). This function notices that the above ProwJob does not have a corresponding Kubernetes pod, so it creates one in the [`test-pods`](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/cluster/test_pod_namespace.yaml) namespace using the pod spec in the ProwJob. It also injects environment variables into the container such as `PULL_NUMBER` and `JOB_NAME`. It also updates the status line on the PR with a link to Gubernator, which will provide real-time logs and results.
Every thirty seconds, `cmd/plank` runs [`Sync`](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/plank/controller.go#L71). `Sync` runs [`syncKubernetesJob`](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/plank/controller.go#L233-L296) for each Prow job and pod. Because the above Prow job lacks a corresponding Kubernetes pod, `Sync` creates one in the [`test-pods`](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/cluster/test_pod_namespace.yaml) namespace. Finally, `Sync` updates the status line on the PR with a link to Gubernator. Gubernator handles real-time logs and results.

Several minutes later, the `syncKubernetesJob` method notices that the Kubernetes pod in that ProwJob has finished and succeeded. It sets the ProwJob status to success and sets the status line on GitHub to success. A green check-mark shows up on the PR.
When the Prow job ends, the `syncKubernetesJob` method updates the ProwJob status to success and sets the status line on GitHub to success. The status update makes a green check-mark show up on the PR.

A day later, [`cmd/sinker`](https://github.com/kubernetes/test-infra/blob/c8829eef589a044126289cb5b4dc8e85db3ea22f/prow/cmd/sinker/main.go#L58-L92) notices that the job and pod are a day old and deletes them from the Kubernetes API server.

0 comments on commit 6d9c907

Please sign in to comment.