-
Notifications
You must be signed in to change notification settings - Fork 798
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update docs for connecting to Kubeflow Pipelines from the same cluster in multi-user mode #2905
Update docs for connecting to Kubeflow Pipelines from the same cluster in multi-user mode #2905
Conversation
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed (or fixed any issues), please reply here with What to do if you already signed the CLAIndividual signers
Corporate signers
ℹ️ Googlers: Go here for more info. |
Hi @bartgras. Thanks for your PR. I'm waiting for a kubeflow member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bartgras please sign CLA
@googlebot I signed it! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for updating this @bartgras, it's very useful!
@zijianjoy @Bobgy @RFMVasconcelos Please take a look.
Co-authored-by: Andrey Velichkevich <andrey.velichkevich@gmail.com>
Thank you for the contribution! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If token is found, `kfp.Client` puts it in the `Authorization: Bearer <token>` header where Kubeflow Pipelines API can read it. No additional setup is required to refresh tokens. | ||
|
||
Setup is similar for other cases like e.g. **cron tasks or in-cluster CI/CD**: Configure your Pod with token in either `KF_PIPELINES_SA_TOKEN_PATH` or `/var/run/secrets/kubeflow/pipelines/token` and `kfp.Client` will gain access to Kubeflow Pipelines. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bartgras I think there is an important piece of information missing, namely how to allow cross-namespaces access to the pipelines API.
For example, giving Notebook Pods in namespace-1
access to namespace-2
Pipelines can be done by giving, namespace-1:ServiceAccount/default-editor
the ClusterRole/kubeflow-edit
in namespace-2
.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubeflow-edit-namespace-1
namespace: namespace-2
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubeflow-edit
subjects:
- kind: ServiceAccount
name: default-editor
namespace: namespace-1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was under assumption that users would use "Manage Contributors" to achieve the same result without additional RBAC settings.
Specifically, both namespace-1
and namespace-2
would require PodDefault
s and then namespace-2
would add namespace-2
through contributors. I admit I didn't test if that's enough to get the access.If not, I can extend docs with your comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both options should work, it's useful to introduce rbac when users want to configure on their own, probably with different granularity.
- serviceAccountToken: | ||
path: token | ||
expirationSeconds: 7200 | ||
audience: pipelines.kubeflow.org |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's important to explain how this works, as most users will have never seen this feature of Kubernetes.
Also, we should clarify that this serviceAccountToken
method respects the Pipelines RBAC, and does not allow access beyond what the ServiceAcount
running the notebook Pod has.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't want to overflow users with details some of them might not find important if their goal is just to have in-cluster access to pipelines working.
Would adding something like this be enough, or you want to provide more info:
"More details about PodDefault can be found here".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for the detailed info, because they need the details to understand how to access KFP API from any pod.
I think your argument about focusing on the minimum they need to know is also valid. What about adding a section at the end of the page to introduce the details.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"More details about PodDefault can be found here".
It should be good enough for me
After the manifest is deployed, newly created Jupyter notebook contains additional option (`Allow access to Kubeflow Pipelines`) in section **configurations**. | ||
Read more about **configurations** on [Jupyter notebook server](/docs/components/notebooks/setup/#create-a-jupyter-notebook-server-and-add-a-notebook). | ||
|
||
Note, Kubeflow `kfp.Client` expects token either in `KF_PIPELINES_SA_TOKEN_PATH` environment variable or mounted to `/var/run/secrets/kubeflow/pipelines/token`. Do not change these values in the manifest. Similarly, `audience` should not be modified as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be put first in this section, explaining that KF_PIPELINES_SA_TOKEN_PATH
is what the kfp.Client()
is looking for, and then how serviceAccountToken
actually works. (From an auth-flow perspective)
|
||
Setup is similar for other cases like e.g. **cron tasks or in-cluster CI/CD**: Configure your Pod with token in either `KF_PIPELINES_SA_TOKEN_PATH` or `/var/run/secrets/kubeflow/pipelines/token` and `kfp.Client` will gain access to Kubeflow Pipelines. | ||
|
||
#### Generic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we have a concept of "generic" @Bobgy what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. I wasn't sure what would be the right wording in this case. Could not find any other name in docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can start with non-multi-user mode?
|
||
There is work-in-progress to support this use-case, refer to [github issue #5138](https://github.com/kubeflow/pipelines/issues/5138). | ||
Alternatively, in-cluster workloads like Jupyter notebooks or cron tasks can be also accessed through public endpoint. This option is platform specific and explained in | ||
[Connect to Kubeflow Pipelines from outside your cluster](/docs/components/pipelines/sdk/connect-api/#connect-to-kubeflow-pipelines-from-outside-your-cluster) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it's not 100% related to this PR, but we should expand how to connect to the Pipelines endpoint from outside the cluster. Right now, (when using Dex) we don't document how people can access their https://kubeflow.example.com/pipelines
endpoint from outside the cluster.
NOTE: The default manifests use "dex + oidc-authservice" with a very web-UI-focused authentication-flow.
Therefore, we should document how to use a "kubeflow service account" + "kubeflow token" to access the Kubeflow Pipelines REST API, with a fully configured Dex (that might use LDAP/OAUTH for normal users).
@Bobgy what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
notebooks or cron tasks, current suggested workaround is to connect through | ||
public endpoint and follow platform specific documentation to authenticate | ||
programmatically using user credentials. For Google Cloud, you can refer to | ||
[Connecting to Kubeflow Pipelines in a full Kubeflow deployment on Google Cloud](/docs/gke/pipelines/authentication-sdk/#connecting-to-kubeflow-pipelines-in-a-full-kubeflow-deployment). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this is a GKE-specific doc, we might want to explain this generically rather than remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The link I added explains it for GKE and other platforms.
|
||
Clients can only access the Kubeflow Pipelines API from the public endpoint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably want to keep some preamble like this (possibly reworded), about how the Istio auth is setup in Kubeflow.
For example, most users may not realize that the istio-ingressgateway
is how Kubeflow APIs are exposed external to the clsuter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I searched the term "ingress gateway" on kubeflow.org and found that it's often mentioned in distribution-specific installation steps.
Istio ingress gateway is not being used exclusively by Kubeflow Pipelines. If we want to give more details about access etc. then something like Traffic Flow section could serve as a starting point and would probably fit better on Overview page. If you agree, I could create separate issue+PR for that.
/ok-to-test |
[Connecting to Kubeflow Pipelines in a full Kubeflow deployment on Google Cloud](/docs/gke/pipelines/authentication-sdk/#connecting-to-kubeflow-pipelines-in-a-full-kubeflow-deployment). | ||
|
||
There is work-in-progress to support this use-case, refer to [github issue #5138](https://github.com/kubeflow/pipelines/issues/5138). | ||
Alternatively, in-cluster workloads like Jupyter notebooks or cron tasks can be also accessed through public endpoint. This option is platform specific and explained in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can also access Kubeflow Pipelines API through the public endpoint.
Authentication uses ServiceAccountToken | ||
[projection](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#service-account-token-volume-projection) where token with limited lifetime, that can be verified by Kubeflow Pipelines API, is being injected into (e.g. Jupyter notebook's) Pod. | ||
|
||
In order to **access Kubeflow Pipeline from Jupyter notebook**, additional per namespace (profile) manifest is required: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Kubeflow Pipelines
value: /var/run/secrets/kubeflow/pipelines/token | ||
``` | ||
|
||
After the manifest is deployed, newly created Jupyter notebook contains additional option (`Allow access to Kubeflow Pipelines`) in section **configurations**. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
contains an additional option
|
||
Note, Kubeflow `kfp.Client` expects token either in `KF_PIPELINES_SA_TOKEN_PATH` environment variable or mounted to `/var/run/secrets/kubeflow/pipelines/token`. Do not change these values in the manifest. Similarly, `audience` should not be modified as well. | ||
|
||
If token is found, `kfp.Client` puts it in the `Authorization: Bearer <token>` header where Kubeflow Pipelines API can read it. No additional setup is required to refresh tokens. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do users need to know these?
|
||
Setup is similar for other cases like e.g. **cron tasks or in-cluster CI/CD**: Configure your Pod with token in either `KF_PIPELINES_SA_TOKEN_PATH` or `/var/run/secrets/kubeflow/pipelines/token` and `kfp.Client` will gain access to Kubeflow Pipelines. | ||
|
||
#### Generic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can start with non-multi-user mode?
@thesuperzapper @Bobgy Thanks for suggestions. Would these changes be enough? |
/lgtm Are we ready to merge this PR ? |
@zijianjoy what do you think about this PR ? |
@bartgras @andreyvelich there are still some unresolved comments, if we resolve them, I think we are happy to merge. |
@thesuperzapper I thought I addressed them all in my last push. |
|
||
##### Managing cross-namespaces access to Kubeflow Pipelines API | ||
|
||
The setup can be extended to allow other namespaces to access Kubeflow Pipelines API through your namespace's Juputer notebook server. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: Jupyter instead of Juputer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I misunderstood sth, I think the setting below allows default-editor
service account in namespace-1 to call KFP API and create pipelines/runs in namespace-2. (it also allows access to notebooks, but we won't use a service account to access notebooks, the goal here is to grant namespaced pipeline creation permission to a notebook in a separate namespace)
@thesuperzapper is this what you wanted to convey?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
Thank you for the PR! It looks good to me, pending @Bobgy for approval.
/lgtm |
I've just noticed this comment from @juliusvonkohout . |
Sorry for the delay, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you again for the great documentation contribution!
I love the new content you are adding.
Some general comments:
- regarding content, I'd argue that the main documentation should be written without dependency on PodDefault. I agree PodDefault is a nice to have, but I don't want people to treat it as a hard dependency of KFP.
- also, can we also introduce how a general Pod can be configured to access KFP API, besides the documentation for accessing KFP API from Kubeflow notebooks?
- I feel like the overall tech writing quality needs some improvement. Are there anyone who want to help polish the doc here?
What do you all think?
@andreyvelich @thesuperzapper @bartgras @zijianjoy @capri-xiyue
|
||
It is important to understand that `serviceAccountToken` method respects the Kubeflow Pipelines RBAC, and does not allow access beyond what the ServiceAcount running the notebook Pod has. | ||
|
||
#### Non-multi-user mode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: do you think moving this section before "multi-user" mode help users absorb the knowledge gradually?
Per my imagination, first reading some simple general introduction for how to connect,
and then dive into the complex configuration for how to authenticate in multi-user mode sounds like a better learning experience.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, it is helpful to start with simple approach. If user cannot resolve their need with simple approach, then they will keep reading for more guidance, which naturally leads to the change in new section.
In this scenario, both `namespace-1` and `namespace-2` require `PodDefault` to be properly configured. Access is granted by `namespace-2` adding `namespace-1` as a | ||
[contributor](https://www.kubeflow.org/docs/components/multi-tenancy/getting-started/#managing-contributors-through-the-kubeflow-ui). | ||
|
||
##### How in-cluster authentication works |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
##### How in-cluster authentication works | |
##### How Multi-User mode in-cluster authentication works |
|
||
* **By sharing access to the other profile.** | ||
|
||
In this scenario, both `namespace-1` and `namespace-2` require `PodDefault` to be properly configured. Access is granted by `namespace-2` adding `namespace-1` as a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: what text should we enter in the contributor UI textbox when adding namespace-1 default-editor
service account?
|
||
More details about PodDefault can be found [here](https://github.com/kubeflow/kubeflow/blob/master/components/admission-webhook/README.md). | ||
|
||
It is important to understand that `serviceAccountToken` method respects the Kubeflow Pipelines RBAC, and does not allow access beyond what the ServiceAcount running the notebook Pod has. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it's helpful emphasizing on the two steps: authenticate and then authorize?
- service account token projection allows you to authenticate as the service account (default-editor in your namespace)
- KFP API will verify whether your authenticated identity has the right permissions to do certain actions (RBAC)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that projected token is separate from the Pod's (e.g. default-editor) service account.
I've modified this paragraph to:
"Authentication uses ServiceAccountToken projection. Simply put, the token is first being injected into a Pod (e.g. Jupyter notebook's). Then Kubeflow Pipelines SDK uses this token to authorize against Kubeflow Pipelines API."
Please @Bobgy @elikatsis @andreyvelich @thesuperzapper correct me if I'm wrong.
|
||
##### Managing cross-namespaces access to Kubeflow Pipelines API | ||
|
||
The setup can be extended to allow other namespaces to access Kubeflow Pipelines API through your namespace's Juputer notebook server. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I misunderstood sth, I think the setting below allows default-editor
service account in namespace-1 to call KFP API and create pipelines/runs in namespace-2. (it also allows access to notebooks, but we won't use a service account to access notebooks, the goal here is to grant namespaced pipeline creation permission to a notebook in a separate namespace)
@thesuperzapper is this what you wanted to convey?
I think it's good to have instructions for
That is a good point. @bartgras What do you think about it ? @Bobgy Since this doc PR is very important for using KFP from the Kubeflow Notebook, should we try to merge the initial doc changes before the Kubeflow 1.4 will be released ? What do you think ? |
I propose to organize the doc structure as followed: Remove the following section heading but keep the text content within it, because the whole page is about using SDK client, so we don't need to have a duplicate heading.
How do you think? |
|
||
There is work-in-progress to support this use-case, refer to [github issue #5138](https://github.com/kubeflow/pipelines/issues/5138). | ||
Alternatively, in-cluster workloads like Jupyter notebooks or cron tasks can also access Kubeflow Pipelines API through the public endpoint. This option is platform specific and explained in | ||
[Connect to Kubeflow Pipelines from outside your cluster](/docs/components/pipelines/sdk/connect-api/#connect-to-kubeflow-pipelines-from-outside-your-cluster) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add period at end
Note, this is not supported right now for multi-user Kubeflow Pipelines, refer to [Multi-User Isolation for Pipelines -- Current Limitations](/docs/components/pipelines/multi-user/#current-limitations). | ||
#### Multi-User mode | ||
|
||
In order to **access Kubeflow Pipelines from Jupyter notebook**, additional per namespace (profile) manifest is required: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"additional per namespace (profile) manifest is required" -> "an additional per-namespace (profile) manifest is required"
Note, technical details were put in the [How in-cluster authentication works](#how-in-cluster-authentication-works) section below. | ||
|
||
After the manifest is applied, newly created Jupyter notebook contains an additional option in section **configurations**. | ||
Read more about **configurations** on [Jupyter notebook server](/docs/components/notebooks/setup/#create-a-jupyter-notebook-server-and-add-a-notebook). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jupyter notebook server link not working for me (but maybe I'm missing something)
|
||
Note, technical details were put in the [How in-cluster authentication works](#how-in-cluster-authentication-works) section below. | ||
|
||
After the manifest is applied, newly created Jupyter notebook contains an additional option in section **configurations**. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"newly created Jupyter notebook contains an additional option in section configurations" -> "the newly created Jupyter notebook contains an additional option in the configurations section"
Note, technical details were put in the [How in-cluster authentication works](#how-in-cluster-authentication-works) section below. | ||
|
||
After the manifest is applied, newly created Jupyter notebook contains an additional option in section **configurations**. | ||
Read more about **configurations** on [Jupyter notebook server](/docs/components/notebooks/setup/#create-a-jupyter-notebook-server-and-add-a-notebook). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"configurations on" -> "configurations in the"
|
||
##### Managing cross-namespaces access to Kubeflow Pipelines API | ||
|
||
The setup can be extended to allow other namespaces to access Kubeflow Pipelines API through your namespace's Juputer notebook server. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jupyter
|
||
The setup can be extended to allow other namespaces to access Kubeflow Pipelines API through your namespace's Juputer notebook server. | ||
|
||
Note, examples below assume that `namespace-1` is a namespace (profile) that will be granted access to Kubeflow Pipelines API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Note, examples below assume that namespace-1
is a namespace (profile) that will be granted access to Kubeflow Pipelines API through namespace-2
Jupyter notebook server. namespace-2
is already configured to access Kubeflow Pipelines API."
->
"Note, the examples below assume that namespace-1
is a namespace (profile) that will be granted access to Kubeflow Pipelines API
through the namespace-2
Jupyter notebook server. The namespace-2
server should already be configured to access Kubeflow Pipelines API."
|
||
Setup is similar for other cases like e.g. **cron tasks or in-cluster CI/CD**: Configure your Pod with token in either `KF_PIPELINES_SA_TOKEN_PATH` or `/var/run/secrets/kubeflow/pipelines/token` and `kfp.Client` will gain access to Kubeflow Pipelines. | ||
|
||
##### Managing cross-namespaces access to Kubeflow Pipelines API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless this wording is used elsewhere preference for something clearer like:
Managing access to Kubeflow Pipelines API across namespaces
Note, examples below assume that `namespace-1` is a namespace (profile) that will be granted access to Kubeflow Pipelines API | ||
through `namespace-2` Jupyter notebook server. `namespace-2` is already configured to access Kubeflow Pipelines API. | ||
|
||
The access can be achieved in two ways: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cross-namespace access can be achieved in two ways:
|
||
##### How in-cluster authentication works | ||
|
||
Authentication uses ServiceAccountToken |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
confusing-- consider breaking this up for clarity. Something like:
"Authentication uses ServiceAccountToken projection. This is where a verifiable (by Kubeflow Pipelines API) token with a limited lifetime is being injected into a Pod (e.g. Jupyter notebook's)."
Thank you @Bobgy @zijianjoy @shuesc1 @andreyvelich for detailed feedback. Summary of the changes:
Previous version already mentioned general Pod case but it was only briefly mentioned at the end of "Access Kubeflow Pipelines from Jupyter notebook" section. Now it's split into 2 sections, one that addresses notebooks and the other that addresses Pods in general. |
/lgtm @bartgras Thank you so much for your contributions to this doc PR! Since most comments have been addressed, let's merge this PR first and follow up for any remaining items in a separate PR. |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: bartgras, zijianjoy The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Changes requested in issue, comment .