Skip to content
This repository has been archived by the owner on Jun 19, 2024. It is now read-only.

ApplyService#applyProjectRequest should be (truly) idempotent #1715

Closed
erikgb opened this issue Oct 1, 2019 · 4 comments · Fixed by #1717
Closed

ApplyService#applyProjectRequest should be (truly) idempotent #1715

erikgb opened this issue Oct 1, 2019 · 4 comments · Fixed by #1717
Assignees

Comments

@erikgb
Copy link
Contributor

erikgb commented Oct 1, 2019

Description

It seems like the method ApplyService#applyProjectRequest isn't truly idempotent - and I think the method name applies that it should be. It is close, but no cigar. If the method is invoked when a POST ProjectRequest is already in process by Openshift, but before the Project/Namespace actually exists, it will fail - because Openshift returns HTTP 409 when trying to POST ProjectRequest.

Somehow this bug is only noticeable when you are creating RoleBinding and BuildConfig resources. Why this happens becomes apparent if you look at the callers to the method:

ApplyService.applyProject(Project)  (io.fabric8.maven.core.service)
    ApplyMojo.executeInternal()  (io.fabric8.maven.plugin.mojo.build)
ApplyService.applyNamespace(String, Map<String, String>)  (io.fabric8.maven.core.service)
    ApplyService.applyNamespace(String)  (io.fabric8.maven.core.service)
        ApplyMojo.executeInternal()  (io.fabric8.maven.plugin.mojo.build)
        ApplyService.getNamespace(HasMetadata)  (io.fabric8.maven.core.service)
        ApplyService.applyRoleBinding(RoleBinding, String)  (io.fabric8.maven.core.service)
        ApplyService.applyBuildConfig(BuildConfig, String)  (io.fabric8.maven.core.service)

Info

  • f-m-p version : 4.2.0 (and same behavior with HEAD of master; 4.3-SNAPSHOT)
  • Maven version (mvn -v) : 3.5.3 and also 3.6.1 (but I think it is irrelevant)
  • Kubernetes / OpenShift setup and version : Openshift 3.11

How to reproduce

  • Prerequisite: Openshift mode
  1. Create a simple Maven project with a single RoleBinding resource
  2. Run mvn fabric8:resource-apply
@rohanKanojia
Copy link
Member

I could not reproduce this. I added this fragment in my src/main/fabric8 directory:

apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read pods in the "default" namespace.
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: jane # Name is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role #this must be Role or ClusterRole
  name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
  apiGroup: rbac.authorization.k8s.io

@erikgb
Copy link
Contributor Author

erikgb commented Oct 1, 2019

@rohanKanojia : I forgot to add a minor detail; you must let f-m-p create the project/namespace (i.e. playing around with the fabric8.namespace property/parameter). It is actually a race condition between f-m-p and Openshift processing the ProjectRequest. And since ApplyService#applyProjectRequest isn't idempotent this may fail.

I add the fragment in my src/main/fabric8 directory (viewers-rolebinding):

roleRef:
  kind: ClusterRole
  name: view
subjects:
  - kind: User
    name: jane

This results in the following error when running 'mvn clean fabric8:resource-apply' (masking some corporate details):

[INFO] --- fabric8-maven-plugin:4.2.0:resource-apply (default-cli) @ deploy-test ---
[INFO] F8: Using OpenShift at https://xxx.yyy.zzz:443/ in namespace egb-test with manifest (...)/target/classes/META-INF/fabric8/openshift.yml 
[INFO] OpenShift platform detected
[INFO] F8: Using project: egb-test
[INFO] F8: Created ProjectRequest: target/fabric8/applyJson/egb-test/projectrequest-egb-test.json
[INFO] F8: Using project: egb-test
[ERROR] F8: Failed to create ProjectRequest: egb-test due Failure executing: POST at: https://xxx.yyy.zzz/oapi/v1/projectrequests. Message: project.project.openshift.io "egb-test" already exists. Received status: Status(apiVersion=v1, code=409, details=StatusDetails(causes=[], group=project.openshift.io, kind=project, name=egb-test, retryAfterSeconds=null, uid=null, additionalProperties={}), kind=Status, message=project.project.openshift.io "egb-test" already exists, metadata=ListMeta(_continue=null, resourceVersion=null, selfLink=null, additionalProperties={}), reason=AlreadyExists, status=Failure, additionalProperties={}).: io.fabric8.kubernetes.client.KubernetesClientException: Failure executing: POST at: https://xxx.yyy.zzz/oapi/v1/projectrequests. Message: project.project.openshift.io "egb-test" already exists. Received status: Status(apiVersion=v1, code=409, details=StatusDetails(causes=[], group=project.openshift.io, kind=project, name=egb-test, retryAfterSeconds=null, uid=null, additionalProperties={}), kind=Status, message=project.project.openshift.io "egb-test" already exists, metadata=ListMeta(_continue=null, resourceVersion=null, selfLink=null, additionalProperties={}), reason=AlreadyExists, status=Failure, additionalProperties={}).
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.286 s
[INFO] Finished at: 2019-10-01T16:49:19+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal io.fabric8:fabric8-maven-plugin:4.2.0:resource-apply (default-cli) on project deploy-test: Failed to create ProjectRequest: egb-test due Failure executing: POST at: https://xxx.yyy.zzz/oapi/v1/projectrequests. Message: project.project.openshift.io "egb-test" already exists. Received status: Status(apiVersion=v1, code=409, details=StatusDetails(causes=[], group=project.openshift.io, kind=project, name=egb-test, retryAfterSeconds=null, uid=null, additionalProperties={}), kind=Status, message=project.project.openshift.io "egb-test" already exists, metadata=ListMeta(_continue=null, resourceVersion=null, selfLink=null, additionalProperties={}), reason=AlreadyExists, status=Failure, additionalProperties={}). -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

@erikgb
Copy link
Contributor Author

erikgb commented Oct 1, 2019

@rohanKanojia : I created a repository to show you my exact setup. Hope this helps. Please let me know if I am doing anything the wrong way. ;-)

@rohanKanojia
Copy link
Member

No, seems like there is a bug in our code.

rohanKanojia added a commit to rohanKanojia/fabric8-maven-plugin that referenced this issue Oct 3, 2019
rohanKanojia added a commit to rohanKanojia/fabric8-maven-plugin that referenced this issue Oct 3, 2019
@rohanKanojia rohanKanojia self-assigned this Oct 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
2 participants